aboutsummaryrefslogtreecommitdiff
path: root/src/testcurl/https/tls_daemon_options_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/testcurl/https/tls_daemon_options_test.c')
-rw-r--r--src/testcurl/https/tls_daemon_options_test.c370
1 files changed, 27 insertions, 343 deletions
diff --git a/src/testcurl/https/tls_daemon_options_test.c b/src/testcurl/https/tls_daemon_options_test.c
index b388f24d..7b56f334 100644
--- a/src/testcurl/https/tls_daemon_options_test.c
+++ b/src/testcurl/https/tls_daemon_options_test.c
@@ -26,360 +26,46 @@
26 26
27#include "platform.h" 27#include "platform.h"
28#include "microhttpd.h" 28#include "microhttpd.h"
29
30#include <sys/stat.h> 29#include <sys/stat.h>
31#include <limits.h> 30#include <limits.h>
32#include "gnutls.h" 31#include "gnutls.h"
33#include <curl/curl.h>
34
35#define DEBUG_CURL_VERBOSE 0
36#define PAGE_NOT_FOUND "<html><head><title>File not found</title></head><body>File not found</body></html>"
37 32
38#define MHD_E_MEM "Error: memory error\n" 33#include "tls_test_common.h"
39#define MHD_E_SERVER_INIT "Error: failed to start server\n"
40#define MHD_E_TEST_FILE_CREAT "Error: failed to setup test file\n"
41#define MHD_E_CERT_FILE_CREAT "Error: failed to setup test certificate\n"
42#define MHD_E_KEY_FILE_CREAT "Error: failed to setup test certificate\n"
43 34
44#include "tls_test_keys.h" 35extern const char srv_key_pem[];
45 36extern const char srv_self_signed_cert_pem[];
46const char *test_file_name = "https_test_file";
47const char test_file_data[] = "Hello World\n";
48 37
49int curl_check_version (const char *req_version, ...); 38int curl_check_version (const char *req_version, ...);
50 39
51struct CBC
52{
53 char *buf;
54 size_t pos;
55 size_t size;
56};
57
58struct https_test_data
59{
60 FILE *test_fd;
61 char *cipher_suite;
62 int proto_version;
63};
64
65struct CipherDef
66{
67 int options[2];
68 char *curlname;
69};
70
71static size_t
72copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
73{
74 struct CBC *cbc = ctx;
75
76 if (cbc->pos + size * nmemb > cbc->size)
77 return 0; /* overflow */
78 memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
79 cbc->pos += size * nmemb;
80 return size * nmemb;
81}
82
83static int
84file_reader (void *cls, size_t pos, char *buf, int max)
85{
86 FILE *file = cls;
87 fseek (file, pos, SEEK_SET);
88 return fread (buf, 1, max, file);
89}
90
91/* HTTP access handler call back */
92static int
93http_ahc (void *cls, struct MHD_Connection *connection,
94 const char *url, const char *method, const char *upload_data,
95 const char *version, unsigned int *upload_data_size, void **ptr)
96{
97 static int aptr;
98 struct MHD_Response *response;
99 int ret;
100 FILE *file;
101 struct stat buf;
102
103 if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
104 return MHD_NO; /* unexpected method */
105 if (&aptr != *ptr)
106 {
107 /* do never respond on first call */
108 *ptr = &aptr;
109 return MHD_YES;
110 }
111 *ptr = NULL; /* reset when done */
112
113 file = fopen (url, "r");
114 if (file == NULL)
115 {
116 response = MHD_create_response_from_data (strlen (PAGE_NOT_FOUND),
117 (void *) PAGE_NOT_FOUND,
118 MHD_NO, MHD_NO);
119 ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
120 MHD_destroy_response (response);
121 }
122 else
123 {
124 stat (url, &buf);
125 response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k PAGE_NOT_FOUND size */
126 &file_reader, file,
127 (MHD_ContentReaderFreeCallback)
128 & fclose);
129 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
130 MHD_destroy_response (response);
131 }
132 return ret;
133}
134
135
136
137/** 40/**
138 * test HTTPS transfer 41 * test server refuses to negotiate connections with unsupported protocol versions
139 * @param test_fd: file to attempt transfering 42 *
140 */ 43 */
44/* TODO rm test_fd */
141static int 45static int
142test_https_transfer (FILE * test_fd, char *cipher_suite, int proto_version) 46test_unmatching_ssl_version (FILE * test_fd, char *cipher_suite,
47 int curl_req_ssl_version)
143{ 48{
144 CURL *c;
145 CURLcode errornum;
146 struct CBC cbc; 49 struct CBC cbc;
147 char *doc_path; 50 if (NULL == (cbc.buf = malloc (sizeof (char) * 256)))
148 size_t doc_path_len;
149 char url[255];
150 struct stat statb;
151
152 stat (test_file_name, &statb);
153
154 int len = statb.st_size;
155
156 /* used to memcmp local copy & deamon supplied copy */
157 unsigned char *mem_test_file_local;
158
159 /* setup test file path, url */
160 doc_path_len = PATH_MAX > 4096 ? 4096 : PATH_MAX;
161 if (NULL == (doc_path = malloc (doc_path_len)))
162 {
163 fprintf (stderr, MHD_E_MEM);
164 return -1;
165 }
166 if (getcwd (doc_path, doc_path_len) == NULL)
167 {
168 fprintf (stderr, "Error: failed to get working directory. %s\n",
169 strerror (errno));
170 free (doc_path);
171 return -1;
172 }
173
174 if (NULL == (mem_test_file_local = malloc (len)))
175 {
176 fprintf (stderr, MHD_E_MEM);
177 free (doc_path);
178 return -1;
179 }
180
181 fseek (test_fd, 0, SEEK_SET);
182 if (fread (mem_test_file_local, sizeof (char), len, test_fd) != len)
183 { 51 {
184 fprintf (stderr, "Error: failed to read test file. %s\n", 52 fprintf (stderr, "Error: failed to read test file. %s\n",
185 strerror (errno)); 53 strerror (errno));
186 free (mem_test_file_local);
187 free (doc_path);
188 return -1;
189 }
190
191 if (NULL == (cbc.buf = malloc (sizeof (char) * len)))
192 {
193 fprintf (stderr, MHD_E_MEM);
194 free (mem_test_file_local);
195 free (doc_path);
196 return -1; 54 return -1;
197 } 55 }
198 cbc.size = len; 56 cbc.size = 256;
199 cbc.pos = 0; 57 cbc.pos = 0;
200 58
201 /* construct url - this might use doc_path */ 59 char url[255];
202 sprintf (url, "%s%s/%s", "https://localhost:42433", 60 if (gen_test_file_url (url, DEAMON_TEST_PORT))
203 doc_path, test_file_name);
204
205 c = curl_easy_init ();
206#if DEBUG_CURL_VERBOSE
207 curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
208#endif
209 curl_easy_setopt (c, CURLOPT_URL, url);
210 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
211 curl_easy_setopt (c, CURLOPT_TIMEOUT, 60L);
212 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 60L);
213 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
214 curl_easy_setopt (c, CURLOPT_FILE, &cbc);
215
216 /* TLS options */
217 curl_easy_setopt (c, CURLOPT_SSLVERSION, proto_version);
218 curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, cipher_suite);
219
220 /* currently skip any peer authentication */
221 curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
222 curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
223
224 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
225
226 /* NOTE: use of CONNECTTIMEOUT without also
227 setting NOSIGNAL results in really weird
228 crashes on my system! */
229 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
230 if (CURLE_OK != (errornum = curl_easy_perform (c)))
231 {
232 fprintf (stderr, "curl_easy_perform failed: `%s'\n",
233 curl_easy_strerror (errornum));
234 curl_easy_cleanup (c);
235 free (cbc.buf);
236 free (mem_test_file_local);
237 free (doc_path);
238 return errornum;
239 }
240
241 curl_easy_cleanup (c);
242
243 if (memcmp (cbc.buf, mem_test_file_local, len) != 0)
244 {
245 fprintf (stderr, "Error: local file & received file differ.\n");
246 free (cbc.buf);
247 free (mem_test_file_local);
248 free (doc_path);
249 return -1;
250 }
251
252 free (mem_test_file_local);
253 free (cbc.buf);
254 free (doc_path);
255 return 0;
256}
257
258static FILE *
259setupTestFile ()
260{
261 FILE *test_fd;
262
263 if (NULL == (test_fd = fopen (test_file_name, "w+")))
264 {
265 fprintf (stderr, "Error: failed to open `%s': %s\n",
266 test_file_name, strerror (errno));
267 return NULL;
268 }
269 if (fwrite (test_file_data, sizeof (char), strlen (test_file_data), test_fd)
270 != strlen (test_file_data))
271 {
272 fprintf (stderr, "Error: failed to write `%s. %s'\n",
273 test_file_name, strerror (errno));
274 fclose (test_fd);
275 return NULL;
276 }
277 if (fflush (test_fd))
278 {
279 fprintf (stderr, "Error: failed to flush test file stream. %s\n",
280 strerror (errno));
281 fclose (test_fd);
282 return NULL;
283 }
284
285 return test_fd;
286}
287
288static int
289setup (struct MHD_Daemon **d, int daemon_flags, va_list arg_list)
290{
291 *d = MHD_start_daemon_va (daemon_flags, 42433,
292 NULL, NULL, &http_ahc, NULL, arg_list);
293
294 if (*d == NULL)
295 {
296 fprintf (stderr, MHD_E_SERVER_INIT);
297 return -1;
298 }
299
300 return 0;
301}
302
303static void
304teardown (struct MHD_Daemon *d)
305{
306 MHD_stop_daemon (d);
307}
308
309/* TODO test_wrap: change sig to (setup_func, test, va_list test_arg) & move to test_util.c */
310static int
311test_wrap (char *test_name, int
312 (*test_function) (FILE * test_fd, char *cipher_suite,
313 int proto_version), FILE * test_fd,
314 int daemon_flags, char *cipher_suite, int proto_version, ...)
315{
316 int ret;
317 va_list arg_list;
318 struct MHD_Daemon *d;
319
320 va_start (arg_list, proto_version);
321 if (setup (&d, daemon_flags, arg_list) != 0)
322 { 61 {
323 va_end (arg_list);
324 return -1; 62 return -1;
325 } 63 }
326 64
327 fprintf (stdout, "running test: %s ", test_name); 65 /* assert daemon *rejected* request */
328 ret = test_function (test_fd, cipher_suite, proto_version); 66 if (CURLE_OK ==
329 67 send_curl_req (url, &cbc, cipher_suite, curl_req_ssl_version))
330 if (ret == 0)
331 {
332 fprintf (stdout, "[pass]\n");
333 }
334 else
335 { 68 {
336 fprintf (stdout, "[fail]\n");
337 }
338
339 teardown (d);
340 va_end (arg_list);
341 return ret;
342}
343
344/**
345 * test server refuses to negotiate connections with unsupported protocol versions
346 *
347 */
348static int
349test_protocol_version (FILE * test_fd, char *cipher_suite,
350 int curl_proto_version)
351{
352 CURL *c;
353 CURLcode errornum;
354
355 c = curl_easy_init ();
356#if DEBUG_CURL_VERBOSE
357 curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
358#endif
359 curl_easy_setopt (c, CURLOPT_URL, "https://localhost:42433/");
360 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
361 curl_easy_setopt (c, CURLOPT_TIMEOUT, 3L);
362 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 3L);
363
364 /* TLS options */
365 curl_easy_setopt (c, CURLOPT_SSLVERSION, curl_proto_version);
366 curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, cipher_suite);
367
368 curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
369 curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
370 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
371
372 /* NOTE: use of CONNECTTIMEOUT without also
373 setting NOSIGNAL results in really weird
374 crashes on my system! */
375 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
376
377 /* assert daemon rejected request */
378 if (CURLE_OK == (errornum = curl_easy_perform (c)))
379 {
380 fprintf (stderr, "curl_easy_perform failed: `%s'\n",
381 curl_easy_strerror (errornum));
382 curl_easy_cleanup (c);
383 return -1; 69 return -1;
384 } 70 }
385 71
@@ -403,7 +89,7 @@ main (int argc, char *const *argv)
403 return -1; 89 return -1;
404 } 90 }
405 91
406 if ((test_fd = setupTestFile ()) == NULL) 92 if ((test_fd = setup_test_file ()) == NULL)
407 { 93 {
408 fprintf (stderr, MHD_E_TEST_FILE_CREAT); 94 fprintf (stderr, MHD_E_TEST_FILE_CREAT);
409 return -1; 95 return -1;
@@ -411,8 +97,9 @@ main (int argc, char *const *argv)
411 97
412 if (0 != curl_global_init (CURL_GLOBAL_ALL)) 98 if (0 != curl_global_init (CURL_GLOBAL_ALL))
413 { 99 {
414 fprintf (stderr, "Error: %s\n", strerror (errno));
415 fclose (test_fd); 100 fclose (test_fd);
101 remove (TEST_FILE_NAME);
102 fprintf (stderr, "Error: %s\n", strerror (errno));
416 return -1; 103 return -1;
417 } 104 }
418 105
@@ -422,12 +109,12 @@ main (int argc, char *const *argv)
422 MHD_GNUTLS_PROTOCOL_TLS1_0, 0 109 MHD_GNUTLS_PROTOCOL_TLS1_0, 0
423 }; 110 };
424 111
425 struct CipherDef ciphers[] = 112 struct CipherDef ciphers[] = {
426 { {{MHD_GNUTLS_CIPHER_ARCFOUR_128, 0}, "RC4-SHA"}, 113 {{MHD_GNUTLS_CIPHER_AES_128_CBC, 0}, "AES128-SHA"},
427 {{MHD_GNUTLS_CIPHER_3DES_CBC, 0}, "3DES-SHA"}, 114 {{MHD_GNUTLS_CIPHER_ARCFOUR_128, 0}, "RC4-SHA"},
428 {{MHD_GNUTLS_CIPHER_AES_128_CBC, 0}, "AES128-SHA"}, 115 {{MHD_GNUTLS_CIPHER_3DES_CBC, 0}, "3DES-SHA"},
429 {{MHD_GNUTLS_CIPHER_AES_256_CBC, 0}, "AES256-SHA"}, 116 {{MHD_GNUTLS_CIPHER_AES_256_CBC, 0}, "AES256-SHA"},
430 {{0, 0}, NULL} 117 {{0, 0}, NULL}
431 }; 118 };
432 119
433 fprintf (stderr, "SHA/TLS tests:\n"); 120 fprintf (stderr, "SHA/TLS tests:\n");
@@ -466,18 +153,15 @@ main (int argc, char *const *argv)
466 } 153 }
467 154
468 errorCount += 155 errorCount +=
469 test_wrap ("protocol_version", &test_protocol_version, test_fd, 156 test_wrap ("unmatching SSL version", &test_unmatching_ssl_version,
470 daemon_flags, "AES256-SHA", CURL_SSLVERSION_TLSv1, 157 test_fd, daemon_flags, "AES256-SHA", CURL_SSLVERSION_TLSv1,
471 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem, 158 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
472 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, 159 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
473 MHD_OPTION_PROTOCOL_VERSION, p_ssl3, MHD_OPTION_END); 160 MHD_OPTION_PROTOCOL_VERSION, p_ssl3, MHD_OPTION_END);
474 if (errorCount != 0)
475 fprintf (stderr, "Failed test: %s.\n", argv[0]);
476 161
477 curl_global_cleanup (); 162 curl_global_cleanup ();
478 fclose (test_fd); 163 fclose (test_fd);
479 164 remove (TEST_FILE_NAME);
480 remove (test_file_name);
481 165
482 return errorCount != 0; 166 return errorCount != 0;
483} 167}