GNU libmicrohttpd 1.0.0
Loading...
Searching...
No Matches
basicauth.c
Go to the documentation of this file.
1/*
2 This file is part of libmicrohttpd
3 Copyright (C) 2010, 2011, 2012 Daniel Pittman and Christian Grothoff
4 Copyright (C) 2014-2023 Evgeny Grin (Karlson2k)
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19*/
27#include "basicauth.h"
28#include "gen_auth.h"
29#include "platform.h"
30#include "mhd_limits.h"
31#include "internal.h"
32#include "mhd_compat.h"
33#include "mhd_str.h"
34
35
50{
51 const struct MHD_RqBAuth *params;
52 size_t decoded_max_len;
53 struct MHD_BasicAuthInfo *ret;
54
55 params = MHD_get_rq_bauth_params_ (connection);
56
57 if (NULL == params)
58 return NULL;
59
60 if ((NULL == params->token68.str) || (0 == params->token68.len))
61 return NULL;
62
63 decoded_max_len = MHD_base64_max_dec_size_ (params->token68.len);
64 ret = (struct MHD_BasicAuthInfo *) malloc (sizeof(struct MHD_BasicAuthInfo)
65 + decoded_max_len + 1);
66 if (NULL != ret)
67 {
68 size_t decoded_len;
69 char *decoded;
70
71 decoded = (char *) (ret + 1);
72 decoded_len = MHD_base64_to_bin_n (params->token68.str, params->token68.len,
73 decoded, decoded_max_len);
74 mhd_assert (decoded_max_len >= decoded_len);
75 if (0 != decoded_len)
76 {
77 size_t username_len;
78 char *colon;
79
80 colon = memchr (decoded, ':', decoded_len);
81 if (NULL != colon)
82 {
83 size_t password_pos;
84 size_t password_len;
85
86 username_len = (size_t) (colon - decoded);
87 password_pos = username_len + 1;
88 password_len = decoded_len - password_pos;
89 ret->password = decoded + password_pos;
90 ret->password[password_len] = 0; /* Zero-terminate the string */
92 }
93 else
94 {
95 username_len = decoded_len;
96 ret->password = NULL;
97 ret->password_len = 0;
98 }
99 ret->username = decoded;
100 ret->username[username_len] = 0; /* Zero-terminate the string */
102
103 return ret; /* Success exit point */
104 }
105#ifdef HAVE_MESSAGES
106 else
107 MHD_DLOG (connection->daemon,
108 _ ("Error decoding Basic Authorization authentication.\n"));
109#endif /* HAVE_MESSAGES */
110
111 free (ret);
112 }
113#ifdef HAVE_MESSAGES
114 else
115 {
116 MHD_DLOG (connection->daemon,
117 _ ("Failed to allocate memory to process " \
118 "Basic Authorization authentication.\n"));
119 }
120#endif /* HAVE_MESSAGES */
121
122 return NULL; /* Failure exit point */
123}
124
125
136_MHD_EXTERN char *
138 char **password)
139{
140 struct MHD_BasicAuthInfo *info;
141
142 info = MHD_basic_auth_get_username_password3 (connection);
143 if (NULL == info)
144 return NULL;
145
146 /* For backward compatibility this function must return NULL if
147 * no password is provided */
148 if (NULL != info->password)
149 {
150 char *username;
151
152 username = malloc (info->username_len + 1);
153 if (NULL != username)
154 {
155 memcpy (username, info->username, info->username_len + 1);
156 mhd_assert (0 == username[info->username_len]);
157 if (NULL != password)
158 {
159 *password = malloc (info->password_len + 1);
160 if (NULL != *password)
161 {
162 memcpy (*password, info->password, info->password_len + 1);
163 mhd_assert (0 == (*password)[info->password_len]);
164
165 free (info);
166 return username; /* Success exit point */
167 }
168#ifdef HAVE_MESSAGES
169 else
170 MHD_DLOG (connection->daemon,
171 _ ("Failed to allocate memory.\n"));
172#endif /* HAVE_MESSAGES */
173 }
174 else
175 {
176 free (info);
177 return username; /* Success exit point */
178 }
179
180 free (username);
181 }
182#ifdef HAVE_MESSAGES
183 else
184 MHD_DLOG (connection->daemon,
185 _ ("Failed to allocate memory.\n"));
186#endif /* HAVE_MESSAGES */
187
188 }
189 free (info);
190 if (NULL != password)
191 *password = NULL;
192 return NULL; /* Failure exit point */
193}
194
195
224 const char *realm,
225 int prefer_utf8,
226 struct MHD_Response *response)
227{
228 static const char prefix[] = "Basic realm=\"";
229 static const char suff_charset[] = "\", charset=\"UTF-8\"";
230 static const size_t prefix_len = MHD_STATICSTR_LEN_ (prefix);
231 static const size_t suff_simple_len = MHD_STATICSTR_LEN_ ("\"");
232 static const size_t suff_charset_len =
233 MHD_STATICSTR_LEN_ (suff_charset);
234 enum MHD_Result ret;
235 char *h_str;
236 size_t h_maxlen;
237 size_t suffix_len;
238 size_t realm_len;
239 size_t realm_quoted_len;
240 size_t pos;
241
242 if (NULL == response)
243 return MHD_NO;
244
245 suffix_len = (0 == prefer_utf8) ? suff_simple_len : suff_charset_len;
246 realm_len = strlen (realm);
247 h_maxlen = prefix_len + realm_len * 2 + suffix_len;
248
249 h_str = (char *) malloc (h_maxlen + 1);
250 if (NULL == h_str)
251 {
252#ifdef HAVE_MESSAGES
253 MHD_DLOG (connection->daemon,
254 "Failed to allocate memory for Basic Authentication header.\n");
255#endif /* HAVE_MESSAGES */
256 return MHD_NO;
257 }
258 memcpy (h_str, prefix, prefix_len);
259 pos = prefix_len;
260 realm_quoted_len = MHD_str_quote (realm, realm_len, h_str + pos,
261 h_maxlen - prefix_len - suffix_len);
262 pos += realm_quoted_len;
263 mhd_assert (pos + suffix_len <= h_maxlen);
264 if (0 == prefer_utf8)
265 {
266 h_str[pos++] = '\"';
267 h_str[pos++] = 0; /* Zero terminate the result */
268 mhd_assert (pos <= h_maxlen + 1);
269 }
270 else
271 {
272 /* Copy with the final zero-termination */
273 mhd_assert (pos + suff_charset_len <= h_maxlen);
274 memcpy (h_str + pos, suff_charset, suff_charset_len + 1);
275 mhd_assert (0 == h_str[pos + suff_charset_len]);
276 }
277
278 ret = MHD_add_response_header (response,
280 h_str);
281 free (h_str);
282 if (MHD_NO != ret)
283 {
284 ret = MHD_queue_response (connection,
286 response);
287 }
288 else
289 {
290#ifdef HAVE_MESSAGES
291 MHD_DLOG (connection->daemon,
292 _ ("Failed to add Basic Authentication header.\n"));
293#endif /* HAVE_MESSAGES */
294 }
295 return ret;
296}
297
298
314 const char *realm,
315 struct MHD_Response *response)
316{
317 return MHD_queue_basic_auth_required_response3 (connection, realm, MHD_NO,
318 response);
319}
320
321
322/* end of basicauth.c */
Declarations for HTTP authorisation general functions.
_MHD_EXTERN enum MHD_Result MHD_queue_basic_auth_fail_response(struct MHD_Connection *connection, const char *realm, struct MHD_Response *response)
Definition: basicauth.c:313
_MHD_EXTERN enum MHD_Result MHD_queue_basic_auth_required_response3(struct MHD_Connection *connection, const char *realm, int prefer_utf8, struct MHD_Response *response)
Definition: basicauth.c:223
_MHD_EXTERN char * MHD_basic_auth_get_username_password(struct MHD_Connection *connection, char **password)
Definition: basicauth.c:137
_MHD_EXTERN struct MHD_BasicAuthInfo * MHD_basic_auth_get_username_password3(struct MHD_Connection *connection)
Definition: basicauth.c:49
#define MHD_HTTP_HEADER_WWW_AUTHENTICATE
Definition: microhttpd.h:658
#define MHD_HTTP_UNAUTHORIZED
Definition: microhttpd.h:387
_MHD_EXTERN enum MHD_Result MHD_queue_response(struct MHD_Connection *connection, unsigned int status_code, struct MHD_Response *response)
Definition: connection.c:7844
_MHD_EXTERN enum MHD_Result MHD_add_response_header(struct MHD_Response *response, const char *header, const char *content)
Definition: response.c:620
#define mhd_assert(CHK)
Definition: mhd_assert.h:39
#define MHD_STATICSTR_LEN_(macro)
Definition: mhd_str.h:45
#define NULL
Definition: reason_phrase.c:30
#define _(String)
Definition: mhd_options.h:42
#define _MHD_EXTERN
Definition: mhd_options.h:53
MHD internal shared structures.
Header for platform missing functions.
limits values definitions
Header for string manipulating helpers.
MHD_Result
Definition: microhttpd.h:158
@ MHD_NO
Definition: microhttpd.h:162
platform-specific includes for libmicrohttpd
struct MHD_Daemon * daemon
Definition: internal.h:675
struct _MHD_str_w_len token68
Definition: basicauth.h:40
const char * str
Definition: mhd_str_types.h:50