aboutsummaryrefslogtreecommitdiff
path: root/src/testcurl/test_digestauth_with_arguments.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/testcurl/test_digestauth_with_arguments.c')
-rw-r--r--src/testcurl/test_digestauth_with_arguments.c236
1 files changed, 236 insertions, 0 deletions
diff --git a/src/testcurl/test_digestauth_with_arguments.c b/src/testcurl/test_digestauth_with_arguments.c
new file mode 100644
index 00000000..04227823
--- /dev/null
+++ b/src/testcurl/test_digestauth_with_arguments.c
@@ -0,0 +1,236 @@
1/*
2 This file is part of libmicrohttpd
3 (C) 2010, 2012 Christian Grothoff
4
5 libmicrohttpd is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 libmicrohttpd is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with libmicrohttpd; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file daemontest_digestauth_with_arguments.c
23 * @brief Testcase for libmicrohttpd Digest Auth with arguments
24 * @author Amr Ali
25 */
26
27#include "MHD_config.h"
28#include "platform.h"
29#include <curl/curl.h>
30#include <microhttpd.h>
31#include <stdlib.h>
32#include <string.h>
33#include <time.h>
34
35#ifndef WINDOWS
36#include <sys/socket.h>
37#include <unistd.h>
38#else
39#include <wincrypt.h>
40#endif
41
42#define PAGE "<html><head><title>libmicrohttpd demo</title></head><body>Access granted</body></html>"
43
44#define DENIED "<html><head><title>libmicrohttpd demo</title></head><body>Access denied</body></html>"
45
46#define OPAQUE "11733b200778ce33060f31c9af70a870ba96ddd4"
47
48struct CBC
49{
50 char *buf;
51 size_t pos;
52 size_t size;
53};
54
55static size_t
56copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
57{
58 struct CBC *cbc = ctx;
59
60 if (cbc->pos + size * nmemb > cbc->size)
61 return 0; /* overflow */
62 memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
63 cbc->pos += size * nmemb;
64 return size * nmemb;
65}
66
67static int
68ahc_echo (void *cls,
69 struct MHD_Connection *connection,
70 const char *url,
71 const char *method,
72 const char *version,
73 const char *upload_data, size_t *upload_data_size,
74 void **unused)
75{
76 struct MHD_Response *response;
77 char *username;
78 const char *password = "testpass";
79 const char *realm = "test@example.com";
80 int ret;
81
82 username = MHD_digest_auth_get_username(connection);
83 if ( (username == NULL) ||
84 (0 != strcmp (username, "testuser")) )
85 {
86 response = MHD_create_response_from_buffer(strlen (DENIED),
87 DENIED,
88 MHD_RESPMEM_PERSISTENT);
89 ret = MHD_queue_auth_fail_response(connection, realm,
90 OPAQUE,
91 response,
92 MHD_NO);
93 MHD_destroy_response(response);
94 return ret;
95 }
96 ret = MHD_digest_auth_check(connection, realm,
97 username,
98 password,
99 300);
100 free(username);
101 if ( (ret == MHD_INVALID_NONCE) ||
102 (ret == MHD_NO) )
103 {
104 response = MHD_create_response_from_buffer(strlen (DENIED),
105 DENIED,
106 MHD_RESPMEM_PERSISTENT);
107 if (NULL == response)
108 return MHD_NO;
109 ret = MHD_queue_auth_fail_response(connection, realm,
110 OPAQUE,
111 response,
112 (ret == MHD_INVALID_NONCE) ? MHD_YES : MHD_NO);
113 MHD_destroy_response(response);
114 return ret;
115 }
116 response = MHD_create_response_from_buffer(strlen(PAGE), PAGE,
117 MHD_RESPMEM_PERSISTENT);
118 ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
119 MHD_destroy_response(response);
120 return ret;
121}
122
123
124static int
125testDigestAuth ()
126{
127 int fd;
128 CURL *c;
129 CURLcode errornum;
130 struct MHD_Daemon *d;
131 struct CBC cbc;
132 size_t len;
133 size_t off = 0;
134 char buf[2048];
135 char rnd[8];
136
137 cbc.buf = buf;
138 cbc.size = 2048;
139 cbc.pos = 0;
140#ifndef WINDOWS
141 fd = open("/dev/urandom", O_RDONLY);
142 if (-1 == fd)
143 {
144 fprintf(stderr, "Failed to open `%s': %s\n",
145 "/dev/urandom",
146 strerror(errno));
147 return 1;
148 }
149 while (off < 8)
150 {
151 len = read(fd, rnd, 8);
152 if (len == -1)
153 {
154 fprintf(stderr, "Failed to read `%s': %s\n",
155 "/dev/urandom",
156 strerror(errno));
157 (void) close(fd);
158 return 1;
159 }
160 off += len;
161 }
162 (void) close(fd);
163#else
164 {
165 HCRYPTPROV cc;
166 BOOL b;
167 b = CryptAcquireContext (&cc, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
168 if (b == 0)
169 {
170 fprintf (stderr, "Failed to acquire crypto provider context: %lu\n",
171 GetLastError ());
172 return 1;
173 }
174 b = CryptGenRandom (cc, 8, rnd);
175 if (b == 0)
176 {
177 fprintf (stderr, "Failed to generate 8 random bytes: %lu\n",
178 GetLastError ());
179 }
180 CryptReleaseContext (cc, 0);
181 if (b == 0)
182 return 1;
183 }
184#endif
185 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
186 1337, NULL, NULL, &ahc_echo, PAGE,
187 MHD_OPTION_DIGEST_AUTH_RANDOM, sizeof (rnd), rnd,
188 MHD_OPTION_NONCE_NC_SIZE, 300,
189 MHD_OPTION_END);
190 if (d == NULL)
191 return 1;
192 c = curl_easy_init ();
193 curl_easy_setopt (c, CURLOPT_URL, "http://127.0.0.1:1337/foo?key=value");
194 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
195 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
196 curl_easy_setopt (c, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
197 curl_easy_setopt (c, CURLOPT_USERPWD, "testuser:testpass");
198 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
199 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
200 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 150L);
201 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
202 /* NOTE: use of CONNECTTIMEOUT without also
203 setting NOSIGNAL results in really weird
204 crashes on my system!*/
205 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
206 if (CURLE_OK != (errornum = curl_easy_perform (c)))
207 {
208 fprintf (stderr,
209 "curl_easy_perform failed: `%s'\n",
210 curl_easy_strerror (errornum));
211 curl_easy_cleanup (c);
212 MHD_stop_daemon (d);
213 return 2;
214 }
215 curl_easy_cleanup (c);
216 MHD_stop_daemon (d);
217 if (cbc.pos != strlen (PAGE))
218 return 4;
219 if (0 != strncmp (PAGE, cbc.buf, strlen (PAGE)))
220 return 8;
221 return 0;
222}
223
224int
225main (int argc, char *const *argv)
226{
227 unsigned int errorCount = 0;
228
229 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
230 return 2;
231 errorCount += testDigestAuth ();
232 if (errorCount != 0)
233 fprintf (stderr, "Error (code: %u)\n", errorCount);
234 curl_global_cleanup ();
235 return errorCount != 0; /* 0 == pass */
236}