aboutsummaryrefslogtreecommitdiff
path: root/doc/examples/basicauthentication.c
diff options
context:
space:
mode:
Diffstat (limited to 'doc/examples/basicauthentication.c')
-rw-r--r--doc/examples/basicauthentication.c179
1 files changed, 36 insertions, 143 deletions
diff --git a/doc/examples/basicauthentication.c b/doc/examples/basicauthentication.c
index 389242da..0b5ce62c 100644
--- a/doc/examples/basicauthentication.c
+++ b/doc/examples/basicauthentication.c
@@ -3,108 +3,12 @@
3#include <sys/socket.h> 3#include <sys/socket.h>
4#include <microhttpd.h> 4#include <microhttpd.h>
5#include <time.h> 5#include <time.h>
6#include <string.h>
7#include <stdlib.h>
8#include <stdio.h>
6 9
7#define PORT 8888 10#define PORT 8888
8 11
9#define REALM "\"Maintenance\""
10#define USER "a legitimate user"
11#define PASSWORD "and his password"
12
13
14char *string_to_base64 (const char *message);
15
16
17static int
18ask_for_authentication (struct MHD_Connection *connection, const char *realm)
19{
20 int ret;
21 struct MHD_Response *response;
22 char *headervalue;
23 const char *strbase = "Basic realm=";
24
25 response = MHD_create_response_from_data (0, NULL, MHD_NO, MHD_NO);
26 if (!response)
27 return MHD_NO;
28
29 headervalue = malloc (strlen (strbase) + strlen (realm) + 1);
30 if (!headervalue)
31 return MHD_NO;
32
33 strcpy (headervalue, strbase);
34 strcat (headervalue, realm);
35
36 ret = MHD_add_response_header (response, "WWW-Authenticate", headervalue);
37 free (headervalue);
38 if (!ret)
39 {
40 MHD_destroy_response (response);
41 return MHD_NO;
42 }
43
44 ret = MHD_queue_response (connection, MHD_HTTP_UNAUTHORIZED, response);
45
46 MHD_destroy_response (response);
47
48 return ret;
49}
50
51static int
52is_authenticated (struct MHD_Connection *connection,
53 const char *username, const char *password)
54{
55 const char *headervalue;
56 char *expected_b64, *expected;
57 const char *strbase = "Basic ";
58 int authenticated;
59
60 headervalue =
61 MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
62 "Authorization");
63 if (NULL == headervalue)
64 return 0;
65 if (0 != strncmp (headervalue, strbase, strlen (strbase)))
66 return 0;
67
68 expected = malloc (strlen (username) + 1 + strlen (password) + 1);
69 if (NULL == expected)
70 return 0;
71
72 strcpy (expected, username);
73 strcat (expected, ":");
74 strcat (expected, password);
75
76 expected_b64 = string_to_base64 (expected);
77 free (expected);
78 if (NULL == expected_b64)
79 return 0;
80
81 authenticated =
82 (strcmp (headervalue + strlen (strbase), expected_b64) == 0);
83
84 free (expected_b64);
85 return authenticated;
86}
87
88
89static int
90secret_page (struct MHD_Connection *connection)
91{
92 int ret;
93 struct MHD_Response *response;
94 const char *page = "<html><body>A secret.</body></html>";
95
96 response =
97 MHD_create_response_from_data (strlen (page), (void *) page, MHD_NO,
98 MHD_NO);
99 if (!response)
100 return MHD_NO;
101
102 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
103 MHD_destroy_response (response);
104
105 return ret;
106}
107
108 12
109static int 13static int
110answer_to_connection (void *cls, struct MHD_Connection *connection, 14answer_to_connection (void *cls, struct MHD_Connection *connection,
@@ -112,6 +16,12 @@ answer_to_connection (void *cls, struct MHD_Connection *connection,
112 const char *version, const char *upload_data, 16 const char *version, const char *upload_data,
113 size_t *upload_data_size, void **con_cls) 17 size_t *upload_data_size, void **con_cls)
114{ 18{
19 char *user;
20 char *pass;
21 int fail;
22 int ret;
23 struct MHD_Response *response;
24
115 if (0 != strcmp (method, "GET")) 25 if (0 != strcmp (method, "GET"))
116 return MHD_NO; 26 return MHD_NO;
117 if (NULL == *con_cls) 27 if (NULL == *con_cls)
@@ -119,11 +29,33 @@ answer_to_connection (void *cls, struct MHD_Connection *connection,
119 *con_cls = connection; 29 *con_cls = connection;
120 return MHD_YES; 30 return MHD_YES;
121 } 31 }
122 32 pass = NULL;
123 if (!is_authenticated (connection, USER, PASSWORD)) 33 user = MHD_basic_auth_get_username_password (connection, &pass);
124 return ask_for_authentication (connection, REALM); 34 fail = ( (user == NULL) ||
125 35 (0 != strcmp (user, "root")) ||
126 return secret_page (connection); 36 (0 != strcmp (pass, "pa$$w0rd") ) );
37 if (user != NULL) free (user);
38 if (pass != NULL) free (pass);
39 if (fail)
40 {
41 const char *page = "<html><body>Go away.</body></html>";
42 response =
43 MHD_create_response_from_data (strlen (page), (void *) page, MHD_NO,
44 MHD_NO);
45 ret = MHD_queue_basic_auth_fail_response (connection,
46 "my realm",
47 response);
48 }
49 else
50 {
51 const char *page = "<html><body>A secret.</body></html>";
52 response =
53 MHD_create_response_from_data (strlen (page), (void *) page, MHD_NO,
54 MHD_NO);
55 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
56 }
57 MHD_destroy_response (response);
58 return ret;
127} 59}
128 60
129 61
@@ -142,42 +74,3 @@ main ()
142 MHD_stop_daemon (daemon); 74 MHD_stop_daemon (daemon);
143 return 0; 75 return 0;
144} 76}
145
146
147char *
148string_to_base64 (const char *message)
149{
150 const char *lookup =
151 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
152 unsigned long l;
153 int i;
154 char *tmp;
155 size_t length = strlen (message);
156
157 tmp = malloc (length * 2);
158 if (NULL == tmp)
159 return tmp;
160
161 tmp[0] = 0;
162
163 for (i = 0; i < length; i += 3)
164 {
165 l = (((unsigned long) message[i]) << 16)
166 | (((i + 1) < length) ? (((unsigned long) message[i + 1]) << 8) : 0)
167 | (((i + 2) < length) ? ((unsigned long) message[i + 2]) : 0);
168
169
170 strncat (tmp, &lookup[(l >> 18) & 0x3F], 1);
171 strncat (tmp, &lookup[(l >> 12) & 0x3F], 1);
172
173 if (i + 1 < length)
174 strncat (tmp, &lookup[(l >> 6) & 0x3F], 1);
175 if (i + 2 < length)
176 strncat (tmp, &lookup[l & 0x3F], 1);
177 }
178
179 if (length % 3)
180 strncat (tmp, "===", 3 - length % 3);
181
182 return tmp;
183}