aboutsummaryrefslogtreecommitdiff
path: root/src/testcurl/https/tls_daemon_options_test.c
diff options
context:
space:
mode:
authorlv-426 <oxcafebaby@yahoo.com>2008-08-02 22:17:12 +0000
committerlv-426 <oxcafebaby@yahoo.com>2008-08-02 22:17:12 +0000
commitae588bb3c84708b17d75d3ab2ccaf5e972c28fde (patch)
treeabcddff8a5f883291bf2fee10c9ceb21b9e8e345 /src/testcurl/https/tls_daemon_options_test.c
parenta0026eb09eb0b6687ca55a6bf6a019b54f55d330 (diff)
downloadlibmicrohttpd-ae588bb3c84708b17d75d3ab2ccaf5e972c28fde.tar.gz
libmicrohttpd-ae588bb3c84708b17d75d3ab2ccaf5e972c28fde.zip
added MHD_daemon_start_va
better daemon option testing through tls_option_test other misc fixes
Diffstat (limited to 'src/testcurl/https/tls_daemon_options_test.c')
-rw-r--r--src/testcurl/https/tls_daemon_options_test.c461
1 files changed, 461 insertions, 0 deletions
diff --git a/src/testcurl/https/tls_daemon_options_test.c b/src/testcurl/https/tls_daemon_options_test.c
new file mode 100644
index 00000000..95accebb
--- /dev/null
+++ b/src/testcurl/https/tls_daemon_options_test.c
@@ -0,0 +1,461 @@
1/*
2 This file is part of libmicrohttpd
3 (C) 2007 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 mhds_get_test.c
23 * @brief Testcase for libmicrohttpd HTTPS GET operations
24 * @author Sagie Amir
25 */
26
27#include "platform.h"
28#include "microhttpd.h"
29
30#include <sys/stat.h>
31
32#include "gnutls.h"
33#include <curl/curl.h>
34
35#define PAGE_NOT_FOUND "<html><head><title>File not found</title></head><body>File not found</body></html>"
36
37#define MHD_E_MEM "Error: memory error\n"
38#define MHD_E_SERVER_INIT "Error: failed to start server\n"
39#define MHD_E_TEST_FILE_CREAT "Error: failed to setup test file\n"
40#define MHD_E_CERT_FILE_CREAT "Error: failed to setup test certificate\n"
41#define MHD_E_KEY_FILE_CREAT "Error: failed to setup test certificate\n"
42
43#include "tls_test_keys.h"
44
45const char *test_file_name = "https_test_file";
46const char test_file_data[] = "Hello World\n";
47
48int curl_check_version (const char *req_version, ...);
49
50struct CBC
51{
52 char *buf;
53 size_t pos;
54 size_t size;
55};
56
57static size_t
58copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
59{
60 struct CBC *cbc = ctx;
61
62 if (cbc->pos + size * nmemb > cbc->size)
63 return 0; /* overflow */
64 memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
65 cbc->pos += size * nmemb;
66 return size * nmemb;
67}
68
69static int
70file_reader (void *cls, size_t pos, char *buf, int max)
71{
72 FILE *file = cls;
73 fseek (file, pos, SEEK_SET);
74 return fread (buf, 1, max, file);
75}
76
77/* HTTP access handler call back */
78static int
79http_ahc (void *cls, struct MHD_Connection *connection,
80 const char *url, const char *method, const char *upload_data,
81 const char *version, unsigned int *upload_data_size, void **ptr)
82{
83 static int aptr;
84 struct MHD_Response *response;
85 int ret;
86 FILE *file;
87 struct stat buf;
88
89 if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
90 return MHD_NO; /* unexpected method */
91 if (&aptr != *ptr)
92 {
93 /* do never respond on first call */
94 *ptr = &aptr;
95 return MHD_YES;
96 }
97 *ptr = NULL; /* reset when done */
98
99 file = fopen (url, "r");
100 if (file == NULL)
101 {
102 response = MHD_create_response_from_data (strlen (PAGE_NOT_FOUND),
103 (void *) PAGE_NOT_FOUND,
104 MHD_NO, MHD_NO);
105 ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
106 MHD_destroy_response (response);
107 }
108 else
109 {
110 stat (url, &buf);
111 response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k PAGE_NOT_FOUND size */
112 &file_reader, file,
113 (MHD_ContentReaderFreeCallback)
114 & fclose);
115 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
116 MHD_destroy_response (response);
117 }
118 return ret;
119}
120
121/*
122 * test HTTPS transfer
123 * @param test_fd: file to attempt transfering
124 */
125static int
126test_https_transfer (FILE * test_fd, char * cipher_suite, int proto_version)
127{
128 CURL *c;
129 CURLcode errornum;
130 struct CBC cbc;
131 char *doc_path;
132 char url[255];
133 struct stat statb;
134
135 stat (test_file_name, &statb);
136
137 int len = statb.st_size;
138
139 /* used to memcmp local copy & deamon supplied copy */
140 unsigned char *mem_test_file_local;
141
142 /* setup test file path, url */
143 doc_path = get_current_dir_name ();
144
145 if (NULL == (mem_test_file_local = malloc (len)))
146 {
147 fclose (test_fd);
148 fprintf (stderr, MHD_E_MEM);
149 return -1;
150 }
151
152 fseek (test_fd, 0, SEEK_SET);
153 if (fread (mem_test_file_local, sizeof (char), len, test_fd) != len)
154 {
155 fclose (test_fd);
156 fprintf (stderr, "Error: failed to read test file. %s\n",
157 strerror (errno));
158 return -1;
159 }
160
161 if (NULL == (cbc.buf = malloc (sizeof (char) * len)))
162 {
163 fclose (test_fd);
164 fprintf (stderr, MHD_E_MEM);
165 return -1;
166 }
167 cbc.size = len;
168 cbc.pos = 0;
169
170 /* construct url - this might use doc_path */
171 sprintf (url, "%s%s/%s", "https://localhost:42433",
172 doc_path, test_file_name);
173
174 c = curl_easy_init ();
175#ifdef DEBUG
176 curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
177#endif
178 curl_easy_setopt (c, CURLOPT_URL, url);
179 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
180 curl_easy_setopt (c, CURLOPT_TIMEOUT, 5L);
181 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 5L);
182 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
183 curl_easy_setopt (c, CURLOPT_FILE, &cbc);
184
185 /* TLS options */
186 curl_easy_setopt (c, CURLOPT_SSLVERSION, proto_version);
187 curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, cipher_suite);
188
189 /* currently skip any peer authentication */
190 curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
191 curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
192
193 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
194
195 /* NOTE: use of CONNECTTIMEOUT without also
196 setting NOSIGNAL results in really weird
197 crashes on my system! */
198 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
199 if (CURLE_OK != (errornum = curl_easy_perform (c)))
200 {
201 fprintf (stderr, "curl_easy_perform failed: `%s'\n",
202 curl_easy_strerror (errornum));
203 curl_easy_cleanup (c);
204 return errornum;
205 }
206
207 curl_easy_cleanup (c);
208
209 if (memcmp (cbc.buf, mem_test_file_local, len) != 0)
210 {
211 fprintf (stderr, "Error: local file & received file differ.\n");
212 free (cbc.buf);
213 free (mem_test_file_local);
214 return -1;
215 }
216
217 free (mem_test_file_local);
218 free (cbc.buf);
219 free (doc_path);
220 return 0;
221}
222
223FILE *
224setupTestFile ()
225{
226 FILE *test_fd;
227
228 if (NULL == (test_fd = fopen (test_file_name, "w+")))
229 {
230 fprintf (stderr, "Error: failed to open `%s': %s\n",
231 test_file_name, strerror (errno));
232 return NULL;
233 }
234 if (fwrite (test_file_data, sizeof (char), strlen (test_file_data), test_fd)
235 != strlen (test_file_data))
236 {
237 fprintf (stderr, "Error: failed to write `%s. %s'\n",
238 test_file_name, strerror (errno));
239 return NULL;
240 }
241 if (fflush (test_fd))
242 {
243 fprintf (stderr, "Error: failed to flush test file stream. %s\n",
244 strerror (errno));
245 return NULL;
246 }
247
248 return test_fd;
249}
250
251static int
252setup (struct MHD_Daemon **d, enum MHD_OPTION option, void * value )
253{
254 *d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
255 MHD_USE_DEBUG, 42433,
256 NULL, NULL, &http_ahc, NULL,
257 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
258 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
259 option, value, MHD_OPTION_END);
260
261 if (*d == NULL)
262 {
263 fprintf (stderr, MHD_E_SERVER_INIT);
264 return -1;
265 }
266
267 return 0;
268}
269
270static void
271teardown (struct MHD_Daemon *d)
272{
273 MHD_stop_daemon (d);
274}
275
276int
277test_wrap (int
278 (*test) (FILE * test_fd, char *cipher_suite, int proto_version),
279 FILE * test_fd, char *cipher_suite, int proto_version,
280 enum MHD_OPTION option, void * value)
281{
282 int ret;
283 struct MHD_Daemon *d;
284
285 if (setup (&d, option, value) != 0)
286 return -1;
287 ret = test (test_fd, cipher_suite, proto_version);
288 teardown (d);
289 return ret;
290}
291
292/* perform a HTTP GET request via SSL/TLS */
293
294/* test loading of key & certificate files */
295int
296test_file_certificates (FILE * test_fd, char *cipher_suite, int proto_version)
297{
298 int ret;
299 struct MHD_Daemon *d;
300 FILE *cert_fd, *key_fd;
301 char cert_path[255], key_path[255], *cur_dir;
302
303 cur_dir = get_current_dir_name ();
304
305 sprintf (cert_path, "%s/%s", cur_dir, "cert.pem");
306 sprintf (key_path, "%s/%s", cur_dir, "key.pem");
307
308 if (NULL == (key_fd = fopen (key_path, "w+")))
309 {
310 fprintf (stderr, MHD_E_KEY_FILE_CREAT);
311 return -1;
312 }
313 if (NULL == (cert_fd = fopen (cert_path, "w+")))
314 {
315 fprintf (stderr, MHD_E_CERT_FILE_CREAT);
316 return -1;
317 }
318
319 fwrite (srv_key_pem, strlen (srv_key_pem), sizeof (char), key_fd);
320 fwrite (srv_self_signed_cert_pem, strlen (srv_self_signed_cert_pem),
321 sizeof (char), cert_fd);
322 fclose (key_fd);
323 fclose (cert_fd);
324
325 if (d == NULL)
326 {
327 fprintf (stderr, MHD_E_SERVER_INIT);
328 return -1;
329 }
330
331 ret = test_https_transfer (test_fd, cipher_suite, proto_version);
332
333 free (cur_dir);
334 remove (cert_path);
335 remove (key_path);
336 return ret;
337}
338
339int
340test_protocol_version (FILE * test_fd, char *cipher_suite,
341 int curl_proto_version)
342{
343 CURL *c;
344 CURLcode errornum;
345
346 c = curl_easy_init ();
347#ifdef DEBUG
348 curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
349#endif
350 curl_easy_setopt (c, CURLOPT_URL, "https://localhost:42433/");
351 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
352 curl_easy_setopt (c, CURLOPT_TIMEOUT, 5L);
353 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 5L);
354
355 /* TLS options */
356 curl_easy_setopt (c, CURLOPT_SSLVERSION, curl_proto_version);
357 curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, cipher_suite);
358
359 curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
360 curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
361 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
362
363 /* NOTE: use of CONNECTTIMEOUT without also
364 setting NOSIGNAL results in really weird
365 crashes on my system! */
366 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
367
368 /* assert daemon rejected request */
369 if (CURLE_OK == (errornum = curl_easy_perform (c)))
370 {
371 fprintf (stderr, "curl_easy_perform failed: `%s'\n",
372 curl_easy_strerror (errornum));
373 curl_easy_cleanup (c);
374 return -1;
375 }
376
377 return 0;
378}
379
380/* setup a temporary transfer test file */
381int
382main (int argc, char *const *argv)
383{
384 FILE *test_fd;
385 unsigned int errorCount = 0;
386
387 gnutls_global_set_log_level(11);
388
389 if (curl_check_version (MHD_REQ_CURL_VERSION))
390 {
391 return -1;
392 }
393
394 if ((test_fd = setupTestFile ()) == NULL)
395 {
396 fprintf (stderr, MHD_E_TEST_FILE_CREAT);
397 return -1;
398 }
399
400 if (0 != curl_global_init (CURL_GLOBAL_ALL))
401 {
402 fprintf (stderr, "Error: %s\n", strerror (errno));
403 return -1;
404 }
405
406 int mac[] = {MHD_GNUTLS_MAC_SHA1, 0};
407 int p [] = {MHD_GNUTLS_SSL3, 0};
408 int cipher[] = { MHD_GNUTLS_CIPHER_3DES_CBC, 0 };
409 int kx[] = { MHD_GNUTLS_KX_DHE_RSA, 0 };
410
411
412// errorCount +=
413// test_wrap (&test_https_transfer, test_fd, "AES256-SHA",
414// CURL_SSLVERSION_TLSv1, MHD_OPTION_END, 0);
415// errorCount +=
416// test_wrap (&test_file_certificates, test_fd, "AES256-SHA",
417// CURL_SSLVERSION_TLSv1, MHD_OPTION_END, 0);
418//
419// errorCount +=
420// test_wrap (&test_protocol_version, test_fd, "AES256-SHA",
421// CURL_SSLVERSION_TLSv1, MHD_OPTION_PROTOCOL_VERSION, p);
422//
423// errorCount +=
424// test_wrap (&test_https_transfer, test_fd, "DES-CBC3-SHA",
425// CURL_SSLVERSION_TLSv1, MHD_OPTION_CIPHER_ALGORITHM, cipher);
426
427 errorCount +=
428 test_wrap (&test_https_transfer, test_fd, "AES256-SHA",
429 CURL_SSLVERSION_TLSv1, MHD_OPTION_MAC_ALGO, mac);
430
431 // errorCount +=
432 // test_wrap (&test_https_transfer, test_fd, "EDH-RSA-DES-CBC3-SHA",
433 // CURL_SSLVERSION_TLSv1, MHD_OPTION_KX_PRIORITY, kx);
434
435 /*gnutls_mac_algorithm_t mac[] = {
436 {MHD_GNUTLS_MAC_MD5, 0}, 0};
437 gnutls_mac_algorithm_t * cur_mac;
438
439 for ( cur_mac = &mac[0]; (*cur_mac) != 0; cur_mac++ ){
440 option[0] = MHD_GNUTLS_MAC_SHA1;
441 errorCount +=
442 test_wrap (&test_https_transfer, test_fd, "AES256-SHA",
443 CURL_SSLVERSION_TLSv1, MHD_OPTION_MAC_ALGO, option);
444 }*/
445
446
447
448 if (errorCount != 0)
449 fprintf (stderr, "Failed test: %s.\n", argv[0]);
450 else
451 {
452 fprintf (stderr, "ok\n");
453 }
454
455 curl_global_cleanup ();
456 fclose (test_fd);
457
458 remove (test_file_name);
459
460 return errorCount != 0;
461}