aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlv-426 <oxcafebaby@yahoo.com>2009-02-02 22:22:56 +0000
committerlv-426 <oxcafebaby@yahoo.com>2009-02-02 22:22:56 +0000
commitf577769d8e2aaadae58a37f7f7206ed24e265bf9 (patch)
treeab5a067652f705721c28caeeb2c62b5b3b733d11
parentb9ec40f2e8aab686380d8bf22dc1e80b8b463741 (diff)
downloadlibmicrohttpd-f577769d8e2aaadae58a37f7f7206ed24e265bf9.tar.gz
libmicrohttpd-f577769d8e2aaadae58a37f7f7206ed24e265bf9.zip
merged common test code into tls_test_common.h & tls_test_common.c
-rw-r--r--src/testcurl/https/Makefile.am46
-rw-r--r--src/testcurl/https/mhds_get_test.c252
-rw-r--r--src/testcurl/https/mhds_multi_daemon_test.c178
-rw-r--r--src/testcurl/https/mhds_session_info_test.c38
-rw-r--r--src/testcurl/https/tls_alert_test.c98
-rw-r--r--src/testcurl/https/tls_authentication_test.c179
-rw-r--r--src/testcurl/https/tls_cipher_change_test.c65
-rw-r--r--src/testcurl/https/tls_daemon_options_test.c370
-rw-r--r--src/testcurl/https/tls_multi_thread_mode_test.c330
-rw-r--r--src/testcurl/https/tls_session_time_out_test.c52
-rw-r--r--src/testcurl/https/tls_test_common.c414
-rw-r--r--src/testcurl/https/tls_test_common.h118
-rw-r--r--src/testcurl/https/tls_thread_mode_test.c326
13 files changed, 720 insertions, 1746 deletions
diff --git a/src/testcurl/https/Makefile.am b/src/testcurl/https/Makefile.am
index eeede99a..074a987b 100644
--- a/src/testcurl/https/Makefile.am
+++ b/src/testcurl/https/Makefile.am
@@ -33,70 +33,82 @@ EXTRA_DIST = cert.pem key.pem tls_test_keys.h
33 33
34TESTS = $(check_PROGRAMS) 34TESTS = $(check_PROGRAMS)
35 35
36# cURL independent tests 36# cURL dependent tests
37tls_session_time_out_test_SOURCES = \ 37tls_session_time_out_test_SOURCES = \
38 tls_session_time_out_test.c 38 tls_session_time_out_test.c \
39 tls_test_common.c
39tls_session_time_out_test_LDADD = \ 40tls_session_time_out_test_LDADD = \
40 $(top_builddir)/src/testcurl/libcurl_version_check.a \ 41 $(top_builddir)/src/testcurl/libcurl_version_check.a \
41 $(top_builddir)/src/daemon/libmicrohttpd.la 42 $(top_builddir)/src/daemon/libmicrohttpd.la \
42 43 @LIBCURL@
44
43tls_cipher_change_test_SOURCES = \ 45tls_cipher_change_test_SOURCES = \
44 tls_cipher_change_test.c 46 tls_cipher_change_test.c \
47 tls_test_common.c
45tls_cipher_change_test_LDADD = \ 48tls_cipher_change_test_LDADD = \
46 $(top_builddir)/src/testcurl/libcurl_version_check.a \ 49 $(top_builddir)/src/testcurl/libcurl_version_check.a \
47 $(top_builddir)/src/daemon/libmicrohttpd.la 50 $(top_builddir)/src/daemon/libmicrohttpd.la \
48 51 @LIBCURL@
52
49tls_alert_test_SOURCES = \ 53tls_alert_test_SOURCES = \
50 tls_alert_test.c 54 tls_alert_test.c \
55 tls_test_common.c
51tls_alert_test_LDADD = \ 56tls_alert_test_LDADD = \
52 $(top_builddir)/src/testcurl/libcurl_version_check.a \ 57 $(top_builddir)/src/testcurl/libcurl_version_check.a \
53 $(top_builddir)/src/daemon/libmicrohttpd.la 58 $(top_builddir)/src/daemon/libmicrohttpd.la \
59 @LIBCURL@
54 60
55# cURL dependent tests
56tls_daemon_options_test_SOURCES = \ 61tls_daemon_options_test_SOURCES = \
57 tls_daemon_options_test.c 62 tls_daemon_options_test.c \
63 tls_test_common.c
58tls_daemon_options_test_LDADD = \ 64tls_daemon_options_test_LDADD = \
59 $(top_builddir)/src/testcurl/libcurl_version_check.a \ 65 $(top_builddir)/src/testcurl/libcurl_version_check.a \
60 $(top_builddir)/src/daemon/libmicrohttpd.la \ 66 $(top_builddir)/src/daemon/libmicrohttpd.la \
61 @LIBCURL@ 67 @LIBCURL@
62 68
63tls_thread_mode_test_SOURCES = \ 69tls_thread_mode_test_SOURCES = \
64 tls_thread_mode_test.c 70 tls_thread_mode_test.c \
71 tls_test_common.c
65tls_thread_mode_test_LDADD = \ 72tls_thread_mode_test_LDADD = \
66 $(top_builddir)/src/testcurl/libcurl_version_check.a \ 73 $(top_builddir)/src/testcurl/libcurl_version_check.a \
67 $(top_builddir)/src/daemon/libmicrohttpd.la \ 74 $(top_builddir)/src/daemon/libmicrohttpd.la \
68 @LIBCURL@ 75 @LIBCURL@
69 76
70tls_multi_thread_mode_test_SOURCES = \ 77tls_multi_thread_mode_test_SOURCES = \
71 tls_multi_thread_mode_test.c 78 tls_multi_thread_mode_test.c \
79 tls_test_common.c
72tls_multi_thread_mode_test_LDADD = \ 80tls_multi_thread_mode_test_LDADD = \
73 $(top_builddir)/src/testcurl/libcurl_version_check.a \ 81 $(top_builddir)/src/testcurl/libcurl_version_check.a \
74 $(top_builddir)/src/daemon/libmicrohttpd.la \ 82 $(top_builddir)/src/daemon/libmicrohttpd.la \
75 @LIBCURL@ 83 @LIBCURL@
76 84
77tls_authentication_test_SOURCES = \ 85tls_authentication_test_SOURCES = \
78 tls_authentication_test.c 86 tls_authentication_test.c \
87 tls_test_common.c
79tls_authentication_test_LDADD = \ 88tls_authentication_test_LDADD = \
80 $(top_builddir)/src/testcurl/libcurl_version_check.a \ 89 $(top_builddir)/src/testcurl/libcurl_version_check.a \
81 $(top_builddir)/src/daemon/libmicrohttpd.la \ 90 $(top_builddir)/src/daemon/libmicrohttpd.la \
82 @LIBCURL@ 91 @LIBCURL@
83 92
84mhds_session_info_test_SOURCES = \ 93mhds_session_info_test_SOURCES = \
85 mhds_session_info_test.c 94 mhds_session_info_test.c \
95 tls_test_common.c
86mhds_session_info_test_LDADD = \ 96mhds_session_info_test_LDADD = \
87 $(top_builddir)/src/testcurl/libcurl_version_check.a \ 97 $(top_builddir)/src/testcurl/libcurl_version_check.a \
88 $(top_builddir)/src/daemon/libmicrohttpd.la \ 98 $(top_builddir)/src/daemon/libmicrohttpd.la \
89 @LIBCURL@ 99 @LIBCURL@
90 100
91mhds_multi_daemon_test_SOURCES = \ 101mhds_multi_daemon_test_SOURCES = \
92 mhds_multi_daemon_test.c 102 mhds_multi_daemon_test.c \
103 tls_test_common.c
93mhds_multi_daemon_test_LDADD = \ 104mhds_multi_daemon_test_LDADD = \
94 $(top_builddir)/src/testcurl/libcurl_version_check.a \ 105 $(top_builddir)/src/testcurl/libcurl_version_check.a \
95 $(top_builddir)/src/daemon/libmicrohttpd.la \ 106 $(top_builddir)/src/daemon/libmicrohttpd.la \
96 @LIBCURL@ 107 @LIBCURL@
97 108
98mhds_get_test_SOURCES = \ 109mhds_get_test_SOURCES = \
99 mhds_get_test.c 110 mhds_get_test.c \
111 tls_test_common.c
100mhds_get_test_LDADD = \ 112mhds_get_test_LDADD = \
101 $(top_builddir)/src/testcurl/libcurl_version_check.a \ 113 $(top_builddir)/src/testcurl/libcurl_version_check.a \
102 $(top_builddir)/src/daemon/libmicrohttpd.la \ 114 $(top_builddir)/src/daemon/libmicrohttpd.la \
diff --git a/src/testcurl/https/mhds_get_test.c b/src/testcurl/https/mhds_get_test.c
index 7ba1cd5a..ce0fcbda 100644
--- a/src/testcurl/https/mhds_get_test.c
+++ b/src/testcurl/https/mhds_get_test.c
@@ -33,214 +33,13 @@
33#include "gnutls.h" 33#include "gnutls.h"
34#include <curl/curl.h> 34#include <curl/curl.h>
35 35
36#define DEBUG 0 36#include "tls_test_common.h"
37
38#define PAGE_NOT_FOUND "<html><head><title>File not found</title></head><body>File not found</body></html>"
39
40#define MHD_E_MEM "Error: memory error\n"
41#define MHD_E_SERVER_INIT "Error: failed to start server\n"
42#define MHD_E_TEST_FILE_CREAT "Error: failed to setup test file\n"
43#define MHD_E_CERT_FILE_CREAT "Error: failed to setup test certificate\n"
44#define MHD_E_KEY_FILE_CREAT "Error: failed to setup test certificate\n"
45
46#include "tls_test_keys.h"
47
48const char *test_file_name = "https_test_file";
49const char test_file_data[] = "Hello World\n";
50 37
51int curl_check_version (const char *req_version, ...); 38int curl_check_version (const char *req_version, ...);
52 39extern const char srv_key_pem[];
53struct CBC 40extern const char srv_self_signed_cert_pem[];
54{ 41extern const char srv_signed_cert_pem[];
55 char *buf; 42extern const char srv_signed_key_pem[];
56 size_t pos;
57 size_t size;
58};
59
60static size_t
61copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
62{
63 struct CBC *cbc = ctx;
64
65 if (cbc->pos + size * nmemb > cbc->size)
66 return 0; /* overflow */
67 memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
68 cbc->pos += size * nmemb;
69 return size * nmemb;
70}
71
72static int
73file_reader (void *cls, size_t pos, char *buf, int max)
74{
75 FILE *file = cls;
76 fseek (file, pos, SEEK_SET);
77 return fread (buf, 1, max, file);
78}
79
80/* HTTP access handler call back */
81static int
82http_ahc (void *cls, struct MHD_Connection *connection,
83 const char *url, const char *method, const char *upload_data,
84 const char *version, unsigned int *upload_data_size, void **ptr)
85{
86 static int aptr;
87 struct MHD_Response *response;
88 int ret;
89 FILE *file;
90 struct stat buf;
91
92 if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
93 return MHD_NO; /* unexpected method */
94 if (&aptr != *ptr)
95 {
96 /* do never respond on first call */
97 *ptr = &aptr;
98 return MHD_YES;
99 }
100 *ptr = NULL; /* reset when done */
101
102 file = fopen (url, "r");
103 if (file == NULL)
104 {
105 response = MHD_create_response_from_data (strlen (PAGE_NOT_FOUND),
106 (void *) PAGE_NOT_FOUND,
107 MHD_NO, MHD_NO);
108 ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
109 MHD_destroy_response (response);
110 }
111 else
112 {
113 stat (url, &buf);
114 response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k PAGE_NOT_FOUND size */
115 &file_reader, file,
116 (MHD_ContentReaderFreeCallback)
117 & fclose);
118 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
119 MHD_destroy_response (response);
120 }
121 return ret;
122}
123
124/*
125 * test HTTPS transfer
126 * @param test_fd: file to attempt transfering
127 */
128static int
129test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version)
130{
131 CURL *c;
132 struct CBC cbc;
133 CURLcode errornum;
134 char *doc_path;
135 size_t doc_path_len;
136 char url[255];
137 struct stat statb;
138
139 stat (test_file_name, &statb);
140
141 int len = statb.st_size;
142
143 /* used to memcmp local copy & deamon supplied copy */
144 unsigned char *mem_test_file_local;
145
146 /* setup test file path, url */
147 doc_path_len = PATH_MAX > 4096 ? 4096 : PATH_MAX;
148 if (NULL == (doc_path = malloc (doc_path_len)))
149 {
150 fprintf (stderr, MHD_E_MEM);
151 return -1;
152 }
153 if (getcwd (doc_path, doc_path_len) == NULL)
154 {
155 fprintf (stderr, "Error: failed to get working directory. %s\n",
156 strerror (errno));
157 free (doc_path);
158 return -1;
159 }
160
161 if (NULL == (mem_test_file_local = malloc (len)))
162 {
163 fprintf (stderr, MHD_E_MEM);
164 free (doc_path);
165 return -1;
166 }
167
168 fseek (test_fd, 0, SEEK_SET);
169 if (fread (mem_test_file_local, sizeof (char), len, test_fd) != len)
170 {
171 free (mem_test_file_local);
172 free (doc_path);
173 fprintf (stderr, "Error: failed to read test file. %s\n",
174 strerror (errno));
175 return -1;
176 }
177
178 if (NULL == (cbc.buf = malloc (len)))
179 {
180 free (mem_test_file_local);
181 free (doc_path);
182 fprintf (stderr, MHD_E_MEM);
183 return -1;
184 }
185 cbc.size = len;
186 cbc.pos = 0;
187
188 /* construct url - this might use doc_path */
189 sprintf (url, "%s%s/%s", "https://localhost:42433",
190 doc_path, test_file_name);
191
192 c = curl_easy_init ();
193#if DEBUG
194 curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
195#endif
196 curl_easy_setopt (c, CURLOPT_URL, url);
197 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
198 curl_easy_setopt (c, CURLOPT_TIMEOUT, 2L);
199 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 2L);
200 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
201 curl_easy_setopt (c, CURLOPT_FILE, &cbc);
202
203 /* TLS options */
204 curl_easy_setopt (c, CURLOPT_SSLVERSION, proto_version);
205 curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, cipher_suite);
206
207 /* currently skip any peer authentication */
208 curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
209 curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
210
211 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
212
213 /* NOTE: use of CONNECTTIMEOUT without also
214 setting NOSIGNAL results in really weird
215 crashes on my system! */
216 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
217 if (CURLE_OK != (errornum = curl_easy_perform (c)))
218 {
219 fprintf (stderr, "curl_easy_perform failed: `%s'\n",
220 curl_easy_strerror (errornum));
221 curl_easy_cleanup (c);
222 free (mem_test_file_local);
223 free (doc_path);
224 free (cbc.buf);
225 return errornum;
226 }
227
228 curl_easy_cleanup (c);
229
230 if (memcmp (cbc.buf, mem_test_file_local, len) != 0)
231 {
232 fprintf (stderr, "Error: local file & received file differ.\n");
233 free (cbc.buf);
234 free (mem_test_file_local);
235 free (doc_path);
236 return -1;
237 }
238
239 free (mem_test_file_local);
240 free (cbc.buf);
241 free (doc_path);
242 return 0;
243}
244 43
245static int 44static int
246test_cipher_option (FILE * test_fd, char *cipher_suite, int proto_version) 45test_cipher_option (FILE * test_fd, char *cipher_suite, int proto_version)
@@ -262,43 +61,12 @@ test_cipher_option (FILE * test_fd, char *cipher_suite, int proto_version)
262 return -1; 61 return -1;
263 } 62 }
264 63
265 ret = test_daemon_get (test_fd, cipher_suite, proto_version); 64 ret = test_https_transfer (test_fd, cipher_suite, proto_version);
266 65
267 MHD_stop_daemon (d); 66 MHD_stop_daemon (d);
268 return ret; 67 return ret;
269} 68}
270 69
271/* setup a temporary transfer test file */
272static FILE *
273setupTestFile ()
274{
275 FILE *test_fd;
276
277 if (NULL == (test_fd = fopen (test_file_name, "w+")))
278 {
279 fprintf (stderr, "Error: failed to open `%s': %s\n",
280 test_file_name, strerror (errno));
281 return NULL;
282 }
283 if (fwrite (test_file_data, sizeof (char), strlen (test_file_data), test_fd)
284 != strlen (test_file_data))
285 {
286 fprintf (stderr, "Error: failed to write `%s. %s'\n",
287 test_file_name, strerror (errno));
288 fclose (test_fd);
289 return NULL;
290 }
291 if (fflush (test_fd))
292 {
293 fprintf (stderr, "Error: failed to flush test file stream. %s\n",
294 strerror (errno));
295 fclose (test_fd);
296 return NULL;
297 }
298
299 return test_fd;
300}
301
302/* perform a HTTP GET request via SSL/TLS */ 70/* perform a HTTP GET request via SSL/TLS */
303int 71int
304test_secure_get (FILE * test_fd, char *cipher_suite, int proto_version) 72test_secure_get (FILE * test_fd, char *cipher_suite, int proto_version)
@@ -319,7 +87,7 @@ test_secure_get (FILE * test_fd, char *cipher_suite, int proto_version)
319 return -1; 87 return -1;
320 } 88 }
321 89
322 ret = test_daemon_get (test_fd, cipher_suite, proto_version); 90 ret = test_https_transfer (test_fd, cipher_suite, proto_version);
323 91
324 MHD_stop_daemon (d); 92 MHD_stop_daemon (d);
325 return ret; 93 return ret;
@@ -338,7 +106,7 @@ main (int argc, char *const *argv)
338 return -1; 106 return -1;
339 } 107 }
340 108
341 if ((test_fd = setupTestFile ()) == NULL) 109 if ((test_fd = setup_test_file ()) == NULL)
342 { 110 {
343 fprintf (stderr, MHD_E_TEST_FILE_CREAT); 111 fprintf (stderr, MHD_E_TEST_FILE_CREAT);
344 return -1; 112 return -1;
@@ -358,11 +126,11 @@ main (int argc, char *const *argv)
358 errorCount += 126 errorCount +=
359 test_cipher_option (test_fd, "DES-CBC3-SHA", CURL_SSLVERSION_TLSv1); 127 test_cipher_option (test_fd, "DES-CBC3-SHA", CURL_SSLVERSION_TLSv1);
360 128
129 print_test_result (errorCount, argv[0]);
361 130
362 curl_global_cleanup (); 131 curl_global_cleanup ();
363 fclose (test_fd); 132 fclose (test_fd);
364 133 remove (TEST_FILE_NAME);
365 remove (test_file_name);
366 134
367 return errorCount != 0; 135 return errorCount != 0;
368} 136}
diff --git a/src/testcurl/https/mhds_multi_daemon_test.c b/src/testcurl/https/mhds_multi_daemon_test.c
index d663902c..910989ab 100644
--- a/src/testcurl/https/mhds_multi_daemon_test.c
+++ b/src/testcurl/https/mhds_multi_daemon_test.c
@@ -30,93 +30,14 @@
30#include <limits.h> 30#include <limits.h>
31#include <sys/stat.h> 31#include <sys/stat.h>
32 32
33#define DEBUG_CURL_VERBOSE 0 33#include "tls_test_common.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
41#include "tls_test_keys.h"
42
43const char *test_file_name = "https_test_file";
44const char test_file_data[] = "Hello World\n";
45 34
46extern int curl_check_version (const char *req_version, ...); 35extern int curl_check_version (const char *req_version, ...);
36extern const char srv_key_pem[];
37extern const char srv_self_signed_cert_pem[];
47 38
48struct CBC 39/* TODO mv to common */
49{ 40/**
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
68file_reader (void *cls, size_t pos, char *buf, int max)
69{
70 FILE *file = cls;
71 fseek (file, pos, SEEK_SET);
72 return fread (buf, 1, max, file);
73}
74
75/* HTTP access handler call back */
76static int
77http_ahc (void *cls, struct MHD_Connection *connection,
78 const char *url, const char *method, const char *upload_data,
79 const char *version, unsigned int *upload_data_size, void **ptr)
80{
81 static int aptr;
82 struct MHD_Response *response;
83 int ret;
84 FILE *file;
85 struct stat buf;
86
87 if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
88 return MHD_NO; /* unexpected method */
89 if (&aptr != *ptr)
90 {
91 /* do never respond on first call */
92 *ptr = &aptr;
93 return MHD_YES;
94 }
95 *ptr = NULL; /* reset when done */
96
97 file = fopen (url, "r");
98 if (file == NULL)
99 {
100 response = MHD_create_response_from_data (strlen (PAGE_NOT_FOUND),
101 (void *) PAGE_NOT_FOUND,
102 MHD_NO, MHD_NO);
103 ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
104 MHD_destroy_response (response);
105 }
106 else
107 {
108 stat (url, &buf);
109 response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k PAGE_NOT_FOUND size */
110 &file_reader, file,
111 (MHD_ContentReaderFreeCallback)
112 & fclose);
113 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
114 MHD_destroy_response (response);
115 }
116 return ret;
117}
118
119/*
120 * perform cURL request for file 41 * perform cURL request for file
121 * @param test_fd: file to attempt transferring 42 * @param test_fd: file to attempt transferring
122 */ 43 */
@@ -127,33 +48,16 @@ test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version,
127 CURL *c; 48 CURL *c;
128 struct CBC cbc; 49 struct CBC cbc;
129 CURLcode errornum; 50 CURLcode errornum;
130 char *doc_path;
131 size_t doc_path_len;
132 char url[255]; 51 char url[255];
133 size_t len; 52 size_t len;
134 struct stat file_stat; 53 struct stat file_stat;
135 54
136 stat (test_file_name, &file_stat); 55 stat (TEST_FILE_NAME, &file_stat);
137 len = file_stat.st_size; 56 len = file_stat.st_size;
138 57
139 /* used to memcmp local copy & deamon supplied copy */ 58 /* used to memcmp local copy & deamon supplied copy */
140 unsigned char *mem_test_file_local; 59 unsigned char *mem_test_file_local;
141 60
142 /* setup test file path, url */
143 doc_path_len = PATH_MAX > 4096 ? 4096 : PATH_MAX;
144 if (NULL == (doc_path = malloc (doc_path_len)))
145 {
146 fprintf (stderr, MHD_E_MEM);
147 return -1;
148 }
149 if (getcwd (doc_path, doc_path_len) == NULL)
150 {
151 free (doc_path);
152 fprintf (stderr, "Error: failed to get working directory. %s\n",
153 strerror (errno));
154 return -1;
155 }
156
157 mem_test_file_local = malloc (len); 61 mem_test_file_local = malloc (len);
158 fseek (test_fd, 0, SEEK_SET); 62 fseek (test_fd, 0, SEEK_SET);
159 if (fread (mem_test_file_local, sizeof (char), len, test_fd) != len) 63 if (fread (mem_test_file_local, sizeof (char), len, test_fd) != len)
@@ -161,7 +65,6 @@ test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version,
161 fprintf (stderr, "Error: failed to read test file. %s\n", 65 fprintf (stderr, "Error: failed to read test file. %s\n",
162 strerror (errno)); 66 strerror (errno));
163 free (mem_test_file_local); 67 free (mem_test_file_local);
164 free (doc_path);
165 return -1; 68 return -1;
166 } 69 }
167 70
@@ -169,19 +72,18 @@ test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version,
169 { 72 {
170 fprintf (stderr, "Error: failed to read test file. %s\n", 73 fprintf (stderr, "Error: failed to read test file. %s\n",
171 strerror (errno)); 74 strerror (errno));
172 free (mem_test_file_local);
173 free (doc_path);
174 return -1; 75 return -1;
175 } 76 }
176 cbc.size = len; 77 cbc.size = len;
177 cbc.pos = 0; 78 cbc.pos = 0;
178 79
179 /* construct url */ 80 if (gen_test_file_url (url, port))
180 sprintf (url, "%s:%d%s/%s", "https://localhost", port, doc_path, 81 {
181 test_file_name); 82 return -1;
83 }
182 84
183 c = curl_easy_init (); 85 c = curl_easy_init ();
184#if DEBUG_CURL_VERBOSE 86#if DEBUG_HTTPS_TEST
185 curl_easy_setopt (c, CURLOPT_VERBOSE, 1); 87 curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
186#endif 88#endif
187 curl_easy_setopt (c, CURLOPT_URL, url); 89 curl_easy_setopt (c, CURLOPT_URL, url);
@@ -210,9 +112,6 @@ test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version,
210 fprintf (stderr, "curl_easy_perform failed: `%s'\n", 112 fprintf (stderr, "curl_easy_perform failed: `%s'\n",
211 curl_easy_strerror (errornum)); 113 curl_easy_strerror (errornum));
212 curl_easy_cleanup (c); 114 curl_easy_cleanup (c);
213 free (mem_test_file_local);
214 free (doc_path);
215 free (cbc.buf);
216 return errornum; 115 return errornum;
217 } 116 }
218 117
@@ -224,13 +123,11 @@ test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version,
224 fprintf (stderr, "Error: local file & received file differ.\n"); 123 fprintf (stderr, "Error: local file & received file differ.\n");
225 free (mem_test_file_local); 124 free (mem_test_file_local);
226 free (cbc.buf); 125 free (cbc.buf);
227 free (doc_path);
228 return -1; 126 return -1;
229 } 127 }
230 128
231 free (mem_test_file_local); 129 free (mem_test_file_local);
232 free (cbc.buf); 130 free (cbc.buf);
233 free (doc_path);
234 return 0; 131 return 0;
235} 132}
236 133
@@ -247,7 +144,7 @@ test_concurent_daemon_pair (FILE * test_fd, char *cipher_suite,
247 struct MHD_Daemon *d1; 144 struct MHD_Daemon *d1;
248 struct MHD_Daemon *d2; 145 struct MHD_Daemon *d2;
249 d1 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL | 146 d1 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
250 MHD_USE_DEBUG, 42433, 147 MHD_USE_DEBUG, DEAMON_TEST_PORT,
251 NULL, NULL, &http_ahc, NULL, 148 NULL, NULL, &http_ahc, NULL,
252 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem, 149 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
253 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, 150 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
@@ -260,7 +157,7 @@ test_concurent_daemon_pair (FILE * test_fd, char *cipher_suite,
260 } 157 }
261 158
262 d2 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL | 159 d2 = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
263 MHD_USE_DEBUG, 42434, 160 MHD_USE_DEBUG, DEAMON_TEST_PORT + 1,
264 NULL, NULL, &http_ahc, NULL, 161 NULL, NULL, &http_ahc, NULL,
265 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem, 162 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
266 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, 163 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
@@ -268,50 +165,24 @@ test_concurent_daemon_pair (FILE * test_fd, char *cipher_suite,
268 165
269 if (d2 == NULL) 166 if (d2 == NULL)
270 { 167 {
271 MHD_stop_daemon(d1); 168 MHD_stop_daemon (d1);
272 fprintf (stderr, MHD_E_SERVER_INIT); 169 fprintf (stderr, MHD_E_SERVER_INIT);
273 return -1; 170 return -1;
274 } 171 }
275 172
276 ret = test_daemon_get (test_fd, cipher_suite, proto_version, 42433); 173 ret =
277 ret += test_daemon_get (test_fd, cipher_suite, proto_version, 42434); 174 test_daemon_get (test_fd, cipher_suite, proto_version, DEAMON_TEST_PORT);
175 ret +=
176 test_daemon_get (test_fd, cipher_suite, proto_version,
177 DEAMON_TEST_PORT + 1);
278 178
279 MHD_stop_daemon (d2); 179 MHD_stop_daemon (d2);
280 ret += test_daemon_get (test_fd, cipher_suite, proto_version, 42433); 180 ret +=
181 test_daemon_get (test_fd, cipher_suite, proto_version, DEAMON_TEST_PORT);
281 MHD_stop_daemon (d1); 182 MHD_stop_daemon (d1);
282 return ret; 183 return ret;
283} 184}
284 185
285FILE *
286setupTestFile ()
287{
288 FILE *test_fd;
289
290 if (NULL == (test_fd = fopen (test_file_name, "w+")))
291 {
292 fprintf (stderr, "Error: failed to open `%s': %s\n",
293 test_file_name, strerror (errno));
294 return NULL;
295 }
296 if (fwrite (test_file_data, sizeof (char), strlen (test_file_data), test_fd)
297 != strlen (test_file_data))
298 {
299 fprintf (stderr, "Error: failed to write `%s. %s'\n",
300 test_file_name, strerror (errno));
301 fclose (test_fd);
302 return NULL;
303 }
304 if (fflush (test_fd))
305 {
306 fprintf (stderr, "Error: failed to flush test file stream. %s\n",
307 strerror (errno));
308 fclose (test_fd);
309 return NULL;
310 }
311
312 return test_fd;
313}
314
315int 186int
316main (int argc, char *const *argv) 187main (int argc, char *const *argv)
317{ 188{
@@ -323,7 +194,7 @@ main (int argc, char *const *argv)
323 return -1; 194 return -1;
324 } 195 }
325 196
326 if ((test_fd = setupTestFile ()) == NULL) 197 if ((test_fd = setup_test_file ()) == NULL)
327 { 198 {
328 fprintf (stderr, MHD_E_TEST_FILE_CREAT); 199 fprintf (stderr, MHD_E_TEST_FILE_CREAT);
329 return -1; 200 return -1;
@@ -340,12 +211,11 @@ main (int argc, char *const *argv)
340 errorCount += 211 errorCount +=
341 test_concurent_daemon_pair (test_fd, "AES256-SHA", CURL_SSLVERSION_SSLv3); 212 test_concurent_daemon_pair (test_fd, "AES256-SHA", CURL_SSLVERSION_SSLv3);
342 213
343 if (errorCount != 0) 214 print_test_result (errorCount, "concurent_daemon_pair");
344 fprintf (stderr, "Failed test: %s.\n", __FILE__);
345 215
346 curl_global_cleanup (); 216 curl_global_cleanup ();
347 fclose (test_fd); 217 fclose (test_fd);
348 218
349 remove (test_file_name); 219 remove (TEST_FILE_NAME);
350 return errorCount != 0; 220 return errorCount != 0;
351} 221}
diff --git a/src/testcurl/https/mhds_session_info_test.c b/src/testcurl/https/mhds_session_info_test.c
index 7bd797af..45675765 100644
--- a/src/testcurl/https/mhds_session_info_test.c
+++ b/src/testcurl/https/mhds_session_info_test.c
@@ -28,34 +28,14 @@
28#include "microhttpd.h" 28#include "microhttpd.h"
29#include <curl/curl.h> 29#include <curl/curl.h>
30 30
31#define DEBUG_CURL_VERBOSE 0 31#include "tls_test_common.h"
32#define EMPTY_PAGE "<html><head><title>Empty page</title></head><body>Empty page</body></html>"
33
34#include "tls_test_keys.h"
35 32
36extern int curl_check_version (const char *req_version, ...); 33extern int curl_check_version (const char *req_version, ...);
34extern const char srv_key_pem[];
35extern const char srv_self_signed_cert_pem[];
37 36
38struct MHD_Daemon *d; 37struct MHD_Daemon *d;
39 38
40struct CBC
41{
42 char *buf;
43 size_t pos;
44 size_t size;
45};
46
47static size_t
48copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
49{
50 struct CBC *cbc = ctx;
51
52 if (cbc->pos + size * nmemb > cbc->size)
53 return 0; /* overflow */
54 memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
55 cbc->pos += size * nmemb;
56 return size * nmemb;
57}
58
59/* 39/*
60 * HTTP access handler call back 40 * HTTP access handler call back
61 * used to query negotiated security parameters 41 * used to query negotiated security parameters
@@ -103,20 +83,21 @@ query_session_ahc (void *cls, struct MHD_Connection *connection,
103static int 83static int
104test_query_session () 84test_query_session ()
105{ 85{
106
107 CURL *c; 86 CURL *c;
108 struct CBC cbc; 87 struct CBC cbc;
109 CURLcode errornum; 88 CURLcode errornum;
110 char url[] = "https://localhost:42433/"; 89 char url[256];
111 90
112 if (NULL == (cbc.buf = malloc (sizeof (char) * 255))) 91 if (NULL == (cbc.buf = malloc (sizeof (char) * 255)))
113 return 16; 92 return 16;
114 cbc.size = 255; 93 cbc.size = 255;
115 cbc.pos = 0; 94 cbc.pos = 0;
116 95
96 gen_test_file_url (url, DEAMON_TEST_PORT);
97
117 /* setup test */ 98 /* setup test */
118 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL | 99 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
119 MHD_USE_DEBUG, 42433, 100 MHD_USE_DEBUG, DEAMON_TEST_PORT,
120 NULL, NULL, &query_session_ahc, NULL, 101 NULL, NULL, &query_session_ahc, NULL,
121 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem, 102 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
122 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, 103 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
@@ -126,7 +107,7 @@ test_query_session ()
126 return 2; 107 return 2;
127 108
128 c = curl_easy_init (); 109 c = curl_easy_init ();
129#if DEBUG_CURL_VERBOSE 110#if DEBUG_HTTPS_TEST
130 curl_easy_setopt (c, CURLOPT_VERBOSE, 1); 111 curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
131#endif 112#endif
132 curl_easy_setopt (c, CURLOPT_URL, url); 113 curl_easy_setopt (c, CURLOPT_URL, url);
@@ -183,8 +164,7 @@ main (int argc, char *const *argv)
183 164
184 errorCount += test_query_session (); 165 errorCount += test_query_session ();
185 166
186 if (errorCount != 0) 167 print_test_result (errorCount, argv[0]);
187 fprintf (stderr, "Failed test: %s.\n", argv[0]);
188 168
189 curl_global_cleanup (); 169 curl_global_cleanup ();
190 170
diff --git a/src/testcurl/https/tls_alert_test.c b/src/testcurl/https/tls_alert_test.c
index cbb2cf20..75444bc2 100644
--- a/src/testcurl/https/tls_alert_test.c
+++ b/src/testcurl/https/tls_alert_test.c
@@ -30,74 +30,10 @@
30#include "gnutls_int.h" 30#include "gnutls_int.h"
31#include "gnutls_datum.h" 31#include "gnutls_datum.h"
32#include "gnutls_record.h" 32#include "gnutls_record.h"
33#include "tls_test_keys.h"
34 33
35#define MHD_E_MEM "Error: memory error\n" 34#include "tls_test_common.h"
36#define MHD_E_SERVER_INIT "Error: failed to start server\n" 35extern const char srv_key_pem[];
37#define MHD_E_FAILED_TO_CONNECT "Error: server connection could not be established\n" 36extern const char srv_self_signed_cert_pem[];
38
39const char *ca_cert_file_name = "ca_cert_pem";
40const char *test_file_name = "https_test_file";
41const char test_file_data[] = "Hello World\n";
42
43struct CBC
44{
45 char *buf;
46 size_t pos;
47 size_t size;
48};
49
50/* HTTP access handler call back */
51static int
52http_ahc (void *cls, struct MHD_Connection *connection,
53 const char *url, const char *method, const char *upload_data,
54 const char *version, unsigned int *upload_data_size, void **ptr)
55{
56 return 0;
57}
58
59static int
60setup (MHD_gtls_session_t * session,
61 MHD_gnutls_datum_t * key,
62 MHD_gnutls_datum_t * cert, MHD_gtls_cert_credentials_t * xcred)
63{
64 int ret;
65 const char *err_pos;
66
67 MHD__gnutls_certificate_allocate_credentials (xcred);
68
69 MHD_gtls_set_datum_m (key, srv_key_pem, strlen (srv_key_pem), &malloc);
70 MHD_gtls_set_datum_m (cert, srv_self_signed_cert_pem,
71 strlen (srv_self_signed_cert_pem), &malloc);
72
73 MHD__gnutls_certificate_set_x509_key_mem (*xcred, cert, key,
74 GNUTLS_X509_FMT_PEM);
75
76 MHD__gnutls_init (session, GNUTLS_CLIENT);
77 ret = MHD__gnutls_priority_set_direct (*session, "NORMAL", &err_pos);
78 if (ret < 0)
79 {
80 return -1;
81 }
82
83 MHD__gnutls_credentials_set (*session, MHD_GNUTLS_CRD_CERTIFICATE, xcred);
84 return 0;
85}
86
87static int
88teardown (MHD_gtls_session_t session,
89 MHD_gnutls_datum_t * key,
90 MHD_gnutls_datum_t * cert, MHD_gtls_cert_credentials_t xcred)
91{
92
93 MHD_gtls_free_datum_m (key, free);
94 MHD_gtls_free_datum_m (cert, free);
95
96 MHD__gnutls_deinit (session);
97
98 MHD__gnutls_certificate_free_credentials (xcred);
99 return 0;
100}
101 37
102/* 38/*
103 * assert server closes connection upon receiving a 39 * assert server closes connection upon receiving a
@@ -114,14 +50,13 @@ test_alert_close_notify (MHD_gtls_session_t session)
114 sd = socket (AF_INET, SOCK_STREAM, 0); 50 sd = socket (AF_INET, SOCK_STREAM, 0);
115 if (sd == -1) 51 if (sd == -1)
116 { 52 {
117 fprintf(stderr, 53 fprintf (stderr, "Failed to create socket: %s\n", strerror (errno));
118 "Failed to create socket: %s\n",
119 strerror(errno));
120 return -1; 54 return -1;
121 } 55 }
56
122 memset (&sa, '\0', sizeof (struct sockaddr_in)); 57 memset (&sa, '\0', sizeof (struct sockaddr_in));
123 sa.sin_family = AF_INET; 58 sa.sin_family = AF_INET;
124 sa.sin_port = htons (42433); 59 sa.sin_port = htons (DEAMON_TEST_PORT);
125 inet_pton (AF_INET, "127.0.0.1", &sa.sin_addr); 60 inet_pton (AF_INET, "127.0.0.1", &sa.sin_addr);
126 61
127 MHD__gnutls_transport_set_ptr (session, (MHD_gnutls_transport_ptr_t) sd); 62 MHD__gnutls_transport_set_ptr (session, (MHD_gnutls_transport_ptr_t) sd);
@@ -170,14 +105,12 @@ test_alert_unexpected_message (MHD_gtls_session_t session)
170 sd = socket (AF_INET, SOCK_STREAM, 0); 105 sd = socket (AF_INET, SOCK_STREAM, 0);
171 if (sd == -1) 106 if (sd == -1)
172 { 107 {
173 fprintf(stderr, 108 fprintf (stderr, "Failed to create socket: %s\n", strerror (errno));
174 "Failed to create socket: %s\n",
175 strerror(errno));
176 return -1; 109 return -1;
177 } 110 }
178 memset (&sa, '\0', sizeof (struct sockaddr_in)); 111 memset (&sa, '\0', sizeof (struct sockaddr_in));
179 sa.sin_family = AF_INET; 112 sa.sin_family = AF_INET;
180 sa.sin_port = htons (42433); 113 sa.sin_port = htons (DEAMON_TEST_PORT);
181 inet_pton (AF_INET, "127.0.0.1", &sa.sin_addr); 114 inet_pton (AF_INET, "127.0.0.1", &sa.sin_addr);
182 115
183 MHD__gnutls_transport_set_ptr (session, 116 MHD__gnutls_transport_set_ptr (session,
@@ -225,8 +158,8 @@ main (int argc, char *const *argv)
225 MHD_gtls_global_set_log_level (11); 158 MHD_gtls_global_set_log_level (11);
226 159
227 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL | 160 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
228 MHD_USE_DEBUG, 42433, 161 MHD_USE_DEBUG, DEAMON_TEST_PORT,
229 NULL, NULL, &http_ahc, NULL, 162 NULL, NULL, &http_dummy_ahc, NULL,
230 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem, 163 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
231 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, 164 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
232 MHD_OPTION_END); 165 MHD_OPTION_END);
@@ -237,16 +170,15 @@ main (int argc, char *const *argv)
237 return -1; 170 return -1;
238 } 171 }
239 172
240 setup (&session, &key, &cert, &xcred); 173 setup_session (&session, &key, &cert, &xcred);
241 errorCount += test_alert_close_notify (session); 174 errorCount += test_alert_close_notify (session);
242 teardown (session, &key, &cert, xcred); 175 teardown_session (session, &key, &cert, xcred);
243 176
244 setup (&session, &key, &cert, &xcred); 177 setup_session (&session, &key, &cert, &xcred);
245 errorCount += test_alert_unexpected_message (session); 178 errorCount += test_alert_unexpected_message (session);
246 teardown (session, &key, &cert, xcred); 179 teardown_session (session, &key, &cert, xcred);
247 180
248 if (errorCount != 0) 181 print_test_result (errorCount, argv[0]);
249 fprintf (stderr, "Failed test: %s.\n", argv[0]);
250 182
251 MHD_stop_daemon (d); 183 MHD_stop_daemon (d);
252 MHD__gnutls_global_deinit (); 184 MHD__gnutls_global_deinit ();
diff --git a/src/testcurl/https/tls_authentication_test.c b/src/testcurl/https/tls_authentication_test.c
index 6e8cf0af..c5e2ea7c 100644
--- a/src/testcurl/https/tls_authentication_test.c
+++ b/src/testcurl/https/tls_authentication_test.c
@@ -30,93 +30,17 @@
30#include <limits.h> 30#include <limits.h>
31#include <sys/stat.h> 31#include <sys/stat.h>
32 32
33#define DEBUG_CURL_VERBOSE 0 33#include "tls_test_common.h"
34#define PAGE_NOT_FOUND "<html><head><title>File not found</title></head><body>File not found</body></html>"
35
36#define MHD_E_MEM "Error: memory error\n"
37#define MHD_E_SERVER_INIT "Error: failed to start server\n"
38#define MHD_E_TEST_FILE_CREAT "Error: failed to setup test file\n"
39
40#include "tls_test_keys.h"
41 34
42extern int curl_check_version (const char *req_version, ...); 35extern int curl_check_version (const char *req_version, ...);
36extern const char test_file_data[];
43 37
44const int DEBUG_GNUTLS_LOG_LEVEL = 6; 38extern const char ca_key_pem[];
45const char *ca_cert_file_name = "ca_cert_pem"; 39extern const char ca_cert_pem[];
46const char *test_file_name = "https_test_file"; 40extern const char srv_signed_cert_pem[];
47const char test_file_data[] = "Hello World\n"; 41extern const char srv_signed_key_pem[];
48
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 42
77/* HTTP access handler call back */ 43const char *ca_cert_file_name = "ca_cert_pem";
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 44
121/* 45/*
122 * test HTTPS transfer 46 * test HTTPS transfer
@@ -128,37 +52,19 @@ test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version)
128 CURL *c; 52 CURL *c;
129 struct CBC cbc; 53 struct CBC cbc;
130 CURLcode errornum; 54 CURLcode errornum;
131 char *doc_path;
132 size_t doc_path_len;
133 char url[255]; 55 char url[255];
134 struct stat statb; 56 struct stat statb;
135 57
136 stat (test_file_name, &statb); 58 stat (TEST_FILE_NAME, &statb);
137 59
138 int len = statb.st_size; 60 int len = statb.st_size;
139 61
140 /* used to memcmp local copy & deamon supplied copy */ 62 /* used to memcmp local copy & deamon supplied copy */
141 unsigned char *mem_test_file_local; 63 unsigned char *mem_test_file_local;
142 64
143 /* setup test file path, url */
144 doc_path_len = PATH_MAX > 4096 ? 4096 : PATH_MAX;
145 if (NULL == (doc_path = malloc (doc_path_len)))
146 {
147 fprintf (stderr, MHD_E_MEM);
148 return -1;
149 }
150 if (getcwd (doc_path, doc_path_len) == NULL)
151 {
152 fprintf (stderr, "Error: failed to get working directory. %s\n",
153 strerror (errno));
154 free (doc_path);
155 return -1;
156 }
157
158 if (NULL == (mem_test_file_local = malloc (len))) 65 if (NULL == (mem_test_file_local = malloc (len)))
159 { 66 {
160 fprintf (stderr, MHD_E_MEM); 67 fprintf (stderr, MHD_E_MEM);
161 free (doc_path);
162 return -1; 68 return -1;
163 } 69 }
164 70
@@ -167,7 +73,6 @@ test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version)
167 { 73 {
168 fprintf (stderr, "Error: failed to read test file. %s\n", 74 fprintf (stderr, "Error: failed to read test file. %s\n",
169 strerror (errno)); 75 strerror (errno));
170 free (doc_path);
171 free (mem_test_file_local); 76 free (mem_test_file_local);
172 return -1; 77 return -1;
173 } 78 }
@@ -175,7 +80,6 @@ test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version)
175 if (NULL == (cbc.buf = malloc (sizeof (char) * len))) 80 if (NULL == (cbc.buf = malloc (sizeof (char) * len)))
176 { 81 {
177 fprintf (stderr, MHD_E_MEM); 82 fprintf (stderr, MHD_E_MEM);
178 free (doc_path);
179 free (mem_test_file_local); 83 free (mem_test_file_local);
180 return -1; 84 return -1;
181 } 85 }
@@ -183,11 +87,10 @@ test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version)
183 cbc.pos = 0; 87 cbc.pos = 0;
184 88
185 /* construct url - this might use doc_path */ 89 /* construct url - this might use doc_path */
186 sprintf (url, "%s%s/%s", "https://localhost:42433", 90 gen_test_file_url (url, DEAMON_TEST_PORT);
187 doc_path, test_file_name);
188 91
189 c = curl_easy_init (); 92 c = curl_easy_init ();
190#if DEBUG_CURL_VERBOSE 93#if DEBUG_HTTPS_TEST
191 curl_easy_setopt (c, CURLOPT_VERBOSE, 1); 94 curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
192#endif 95#endif
193 curl_easy_setopt (c, CURLOPT_URL, url); 96 curl_easy_setopt (c, CURLOPT_URL, url);
@@ -202,6 +105,7 @@ test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version)
202 curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, cipher_suite); 105 curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, cipher_suite);
203 106
204 /* perform peer authentication */ 107 /* perform peer authentication */
108 /* TODO merge into send_curl_req */
205 curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 1); 109 curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 1);
206 curl_easy_setopt (c, CURLOPT_CAINFO, ca_cert_file_name); 110 curl_easy_setopt (c, CURLOPT_CAINFO, ca_cert_file_name);
207 111
@@ -218,9 +122,8 @@ test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version)
218 fprintf (stderr, "curl_easy_perform failed: `%s'\n", 122 fprintf (stderr, "curl_easy_perform failed: `%s'\n",
219 curl_easy_strerror (errornum)); 123 curl_easy_strerror (errornum));
220 curl_easy_cleanup (c); 124 curl_easy_cleanup (c);
221 free (cbc.buf);
222 free (doc_path);
223 free (mem_test_file_local); 125 free (mem_test_file_local);
126 free (cbc.buf);
224 return errornum; 127 return errornum;
225 } 128 }
226 129
@@ -231,13 +134,11 @@ test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version)
231 fprintf (stderr, "Error: local file & received file differ.\n"); 134 fprintf (stderr, "Error: local file & received file differ.\n");
232 free (cbc.buf); 135 free (cbc.buf);
233 free (mem_test_file_local); 136 free (mem_test_file_local);
234 free (doc_path);
235 return -1; 137 return -1;
236 } 138 }
237 139
238 free (mem_test_file_local); 140 free (mem_test_file_local);
239 free (cbc.buf); 141 free (cbc.buf);
240 free (doc_path);
241 return 0; 142 return 0;
242} 143}
243 144
@@ -249,7 +150,7 @@ test_secure_get (FILE * test_fd, char *cipher_suite, int proto_version)
249 struct MHD_Daemon *d; 150 struct MHD_Daemon *d;
250 151
251 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL | 152 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
252 MHD_USE_DEBUG, 42433, 153 MHD_USE_DEBUG, DEAMON_TEST_PORT,
253 NULL, NULL, &http_ahc, NULL, 154 NULL, NULL, &http_ahc, NULL,
254 MHD_OPTION_HTTPS_MEM_KEY, srv_signed_key_pem, 155 MHD_OPTION_HTTPS_MEM_KEY, srv_signed_key_pem,
255 MHD_OPTION_HTTPS_MEM_CERT, srv_signed_cert_pem, 156 MHD_OPTION_HTTPS_MEM_CERT, srv_signed_cert_pem,
@@ -267,65 +168,34 @@ test_secure_get (FILE * test_fd, char *cipher_suite, int proto_version)
267 return ret; 168 return ret;
268} 169}
269 170
270/* setup a temporary transfer test file */
271static FILE *
272setupTestFile ()
273{
274 FILE *test_fd;
275
276 if (NULL == (test_fd = fopen (test_file_name, "w+")))
277 {
278 fprintf (stderr, "Error: failed to open `%s': %s\n",
279 test_file_name, strerror (errno));
280 return NULL;
281 }
282 if (fwrite (test_file_data, sizeof (char), strlen (test_file_data), test_fd)
283 != strlen (test_file_data))
284 {
285 fprintf (stderr, "Error: failed to write `%s. %s'\n",
286 test_file_name, strerror (errno));
287 fclose (test_fd);
288 return NULL;
289 }
290 if (fflush (test_fd))
291 {
292 fprintf (stderr, "Error: failed to flush test file stream. %s\n",
293 strerror (errno));
294 fclose (test_fd);
295 return NULL;
296 }
297
298 return test_fd;
299}
300
301static FILE * 171static FILE *
302setup_ca_cert () 172setup_ca_cert ()
303{ 173{
304 FILE *fd; 174 FILE *cert_fd;
305 175
306 if (NULL == (fd = fopen (ca_cert_file_name, "w+"))) 176 if (NULL == (cert_fd = fopen (ca_cert_file_name, "w+")))
307 { 177 {
308 fprintf (stderr, "Error: failed to open `%s': %s\n", 178 fprintf (stderr, "Error: failed to open `%s': %s\n",
309 ca_cert_file_name, strerror (errno)); 179 ca_cert_file_name, strerror (errno));
310 return NULL; 180 return NULL;
311 } 181 }
312 if (fwrite (ca_cert_pem, sizeof (char), strlen (ca_cert_pem), fd) 182 if (fwrite (ca_cert_pem, sizeof (char), strlen (ca_cert_pem), cert_fd)
313 != strlen (ca_cert_pem)) 183 != strlen (ca_cert_pem))
314 { 184 {
315 fprintf (stderr, "Error: failed to write `%s. %s'\n", 185 fprintf (stderr, "Error: failed to write `%s. %s'\n",
316 ca_cert_file_name, strerror (errno)); 186 ca_cert_file_name, strerror (errno));
317 fclose (fd); 187 fclose (cert_fd);
318 return NULL; 188 return NULL;
319 } 189 }
320 if (fflush (fd)) 190 if (fflush (cert_fd))
321 { 191 {
322 fprintf (stderr, "Error: failed to flush ca cert file stream. %s\n", 192 fprintf (stderr, "Error: failed to flush ca cert file stream. %s\n",
323 strerror (errno)); 193 strerror (errno));
324 fclose (fd); 194 fclose (cert_fd);
325 return NULL; 195 return NULL;
326 } 196 }
327 197
328 return fd; 198 return cert_fd;
329} 199}
330 200
331int 201int
@@ -339,14 +209,12 @@ main (int argc, char *const *argv)
339 return -1; 209 return -1;
340 } 210 }
341 211
342 if ((test_fd = setupTestFile ()) == NULL) 212 if ((test_fd = setup_test_file ()) == NULL || setup_ca_cert () == NULL)
343 { 213 {
344 fprintf (stderr, MHD_E_TEST_FILE_CREAT); 214 fprintf (stderr, MHD_E_TEST_FILE_CREAT);
345 return -1; 215 return -1;
346 } 216 }
347 217
348 setup_ca_cert ();
349
350 if (0 != curl_global_init (CURL_GLOBAL_ALL)) 218 if (0 != curl_global_init (CURL_GLOBAL_ALL))
351 { 219 {
352 fprintf (stderr, "Error (code: %u)\n", errorCount); 220 fprintf (stderr, "Error (code: %u)\n", errorCount);
@@ -357,13 +225,12 @@ main (int argc, char *const *argv)
357 errorCount += 225 errorCount +=
358 test_secure_get (test_fd, "AES256-SHA", CURL_SSLVERSION_TLSv1); 226 test_secure_get (test_fd, "AES256-SHA", CURL_SSLVERSION_TLSv1);
359 227
360 if (errorCount != 0) 228 print_test_result (errorCount, argv[0]);
361 fprintf (stderr, "Failed test: %s.\n", argv[0]);
362 229
363 curl_global_cleanup (); 230 curl_global_cleanup ();
364 fclose (test_fd); 231 fclose (test_fd);
365 232
366 remove (test_file_name); 233 remove (TEST_FILE_NAME);
367 remove (ca_cert_file_name); 234 remove (ca_cert_file_name);
368 return errorCount != 0; 235 return errorCount != 0;
369} 236}
diff --git a/src/testcurl/https/tls_cipher_change_test.c b/src/testcurl/https/tls_cipher_change_test.c
index cb5b74c6..6890537c 100644
--- a/src/testcurl/https/tls_cipher_change_test.c
+++ b/src/testcurl/https/tls_cipher_change_test.c
@@ -31,10 +31,10 @@
31#include "gnutls_int.h" 31#include "gnutls_int.h"
32#include "gnutls_datum.h" 32#include "gnutls_datum.h"
33#include "gnutls_record.h" 33#include "gnutls_record.h"
34#include "tls_test_keys.h"
35 34
36#define MHD_E_SERVER_INIT "Error: failed to start server\n" 35#include "tls_test_common.h"
37#define MHD_E_FAILED_TO_CONNECT "Error: server connection could not be established\n" 36extern const char srv_key_pem[];
37extern const char srv_self_signed_cert_pem[];
38 38
39char *http_get_req = "GET / HTTP/1.1\r\n\r\n"; 39char *http_get_req = "GET / HTTP/1.1\r\n\r\n";
40 40
@@ -58,49 +58,6 @@ rehandshake_ahc (void *cls, struct MHD_Connection *connection,
58 return 0; 58 return 0;
59} 59}
60 60
61static int
62setup (MHD_gtls_session_t * session,
63 MHD_gnutls_datum_t * key,
64 MHD_gnutls_datum_t * cert, MHD_gtls_cert_credentials_t * xcred)
65{
66 int ret;
67 const char *err_pos;
68
69 MHD__gnutls_certificate_allocate_credentials (xcred);
70
71 MHD_gtls_set_datum_m (key, srv_key_pem, strlen (srv_key_pem), &malloc);
72 MHD_gtls_set_datum_m (cert, srv_self_signed_cert_pem,
73 strlen (srv_self_signed_cert_pem), &malloc);
74
75 MHD__gnutls_certificate_set_x509_key_mem (*xcred, cert, key,
76 GNUTLS_X509_FMT_PEM);
77
78 MHD__gnutls_init (session, GNUTLS_CLIENT);
79 ret = MHD__gnutls_priority_set_direct (*session, "NORMAL", &err_pos);
80 if (ret < 0)
81 {
82 return -1;
83 }
84
85 MHD__gnutls_credentials_set (*session, MHD_GNUTLS_CRD_CERTIFICATE, xcred);
86 return 0;
87}
88
89static int
90teardown (MHD_gtls_session_t session,
91 MHD_gnutls_datum_t * key,
92 MHD_gnutls_datum_t * cert, MHD_gtls_cert_credentials_t xcred)
93{
94
95 MHD_gtls_free_datum_m (key, free);
96 MHD_gtls_free_datum_m (cert, free);
97
98 MHD__gnutls_deinit (session);
99
100 MHD__gnutls_certificate_free_credentials (xcred);
101 return 0;
102}
103
104/* 61/*
105 * Cipher change message should only occur while negotiating 62 * Cipher change message should only occur while negotiating
106 * the SSL/TLS handshake. 63 * the SSL/TLS handshake.
@@ -118,14 +75,13 @@ test_out_of_context_cipher_change (MHD_gtls_session_t session)
118 sd = socket (AF_INET, SOCK_STREAM, 0); 75 sd = socket (AF_INET, SOCK_STREAM, 0);
119 if (sd == -1) 76 if (sd == -1)
120 { 77 {
121 fprintf(stderr, 78 fprintf (stderr, "Failed to create socket: %s\n", strerror (errno));
122 "Failed to create socket: %s\n",
123 strerror(errno));
124 return -1; 79 return -1;
125 } 80 }
81
126 memset (&sa, '\0', sizeof (struct sockaddr_in)); 82 memset (&sa, '\0', sizeof (struct sockaddr_in));
127 sa.sin_family = AF_INET; 83 sa.sin_family = AF_INET;
128 sa.sin_port = htons (42433); 84 sa.sin_port = htons (DEAMON_TEST_PORT);
129 inet_pton (AF_INET, "127.0.0.1", &sa.sin_addr); 85 inet_pton (AF_INET, "127.0.0.1", &sa.sin_addr);
130 86
131 MHD__gnutls_transport_set_ptr (session, (MHD_gnutls_transport_ptr_t) sd); 87 MHD__gnutls_transport_set_ptr (session, (MHD_gnutls_transport_ptr_t) sd);
@@ -173,7 +129,7 @@ main (int argc, char *const *argv)
173 MHD_gtls_global_set_log_level (11); 129 MHD_gtls_global_set_log_level (11);
174 130
175 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL | 131 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
176 MHD_USE_DEBUG, 42433, 132 MHD_USE_DEBUG, DEAMON_TEST_PORT,
177 NULL, NULL, &rehandshake_ahc, NULL, 133 NULL, NULL, &rehandshake_ahc, NULL,
178 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem, 134 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
179 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, 135 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
@@ -185,12 +141,11 @@ main (int argc, char *const *argv)
185 return -1; 141 return -1;
186 } 142 }
187 143
188 setup (&session, &key, &cert, &xcred); 144 setup_session (&session, &key, &cert, &xcred);
189 errorCount += test_out_of_context_cipher_change (session); 145 errorCount += test_out_of_context_cipher_change (session);
190 teardown (session, &key, &cert, xcred); 146 teardown_session (session, &key, &cert, xcred);
191 147
192 if (errorCount != 0) 148 print_test_result (errorCount, argv[0]);
193 fprintf (stderr, "Failed test: %s.\n", argv[0]);
194 149
195 MHD_stop_daemon (d); 150 MHD_stop_daemon (d);
196 MHD__gnutls_global_deinit (); 151 MHD__gnutls_global_deinit ();
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}
diff --git a/src/testcurl/https/tls_multi_thread_mode_test.c b/src/testcurl/https/tls_multi_thread_mode_test.c
index eeb5e8a0..602a7175 100644
--- a/src/testcurl/https/tls_multi_thread_mode_test.c
+++ b/src/testcurl/https/tls_multi_thread_mode_test.c
@@ -35,229 +35,12 @@
35#include "gnutls.h" 35#include "gnutls.h"
36#include <curl/curl.h> 36#include <curl/curl.h>
37 37
38#define DEBUG_CURL_VERBOSE 0 38#include "tls_test_common.h"
39#define PAGE_NOT_FOUND "<html><head><title>File not found</title></head><body>File not found</body></html>" 39extern const char srv_key_pem[];
40 40extern const char srv_self_signed_cert_pem[];
41#define MHD_E_MEM "Error: memory error\n"
42#define MHD_E_SERVER_INIT "Error: failed to start server\n"
43#define MHD_E_TEST_FILE_CREAT "Error: failed to setup test file\n"
44#define MHD_E_CERT_FILE_CREAT "Error: failed to setup test certificate\n"
45#define MHD_E_KEY_FILE_CREAT "Error: failed to setup test certificate\n"
46
47#include "tls_test_keys.h"
48
49const char *test_file_name = "https_test_file";
50const char test_file_data[] = "Hello World\n";
51 41
52int curl_check_version (const char *req_version, ...); 42int curl_check_version (const char *req_version, ...);
53 43
54struct CBC
55{
56 char *buf;
57 size_t pos;
58 size_t size;
59};
60
61struct https_test_data
62{
63 FILE *test_fd;
64 char *cipher_suite;
65 int proto_version;
66};
67
68struct CipherDef
69{
70 int options[2];
71 char *curlname;
72};
73
74static size_t
75copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
76{
77 struct CBC *cbc = ctx;
78
79 if (cbc->pos + size * nmemb > cbc->size)
80 return 0; /* overflow */
81 memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
82 cbc->pos += size * nmemb;
83 return size * nmemb;
84}
85
86static int
87file_reader (void *cls, size_t pos, char *buf, int max)
88{
89 FILE *file = cls;
90 fseek (file, pos, SEEK_SET);
91 return fread (buf, 1, max, file);
92}
93
94/* HTTP access handler call back */
95static int
96http_ahc (void *cls, struct MHD_Connection *connection,
97 const char *url, const char *method, const char *upload_data,
98 const char *version, unsigned int *upload_data_size, void **ptr)
99{
100 static int aptr;
101 struct MHD_Response *response;
102 int ret;
103 FILE *file;
104 struct stat buf;
105
106 if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
107 return MHD_NO; /* unexpected method */
108 if (&aptr != *ptr)
109 {
110 /* do never respond on first call */
111 *ptr = &aptr;
112 return MHD_YES;
113 }
114 *ptr = NULL; /* reset when done */
115
116 file = fopen (url, "r");
117 if (file == NULL)
118 {
119 response = MHD_create_response_from_data (strlen (PAGE_NOT_FOUND),
120 (void *) PAGE_NOT_FOUND,
121 MHD_NO, MHD_NO);
122 ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
123 MHD_destroy_response (response);
124 }
125 else
126 {
127 stat (url, &buf);
128 response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k PAGE_NOT_FOUND size */
129 &file_reader, file,
130 (MHD_ContentReaderFreeCallback)
131 & fclose);
132 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
133 MHD_destroy_response (response);
134 }
135 return ret;
136}
137
138
139
140/**
141 * test HTTPS transfer
142 * @param test_fd: file to attempt transfering
143 */
144static int
145test_https_transfer (FILE * test_fd, char *cipher_suite, int proto_version)
146{
147 CURL *c;
148 CURLcode errornum;
149 struct CBC cbc;
150 char *doc_path;
151 size_t doc_path_len;
152 char url[255];
153 struct stat statb;
154
155 stat (test_file_name, &statb);
156
157 int len = statb.st_size;
158
159 /* used to memcmp local copy & deamon supplied copy */
160 unsigned char *mem_test_file_local;
161
162 /* setup test file path, url */
163 doc_path_len = PATH_MAX > 4096 ? 4096 : PATH_MAX;
164 if (NULL == (doc_path = malloc (doc_path_len)))
165 {
166 fprintf (stderr, MHD_E_MEM);
167 return -1;
168 }
169 if (getcwd (doc_path, doc_path_len) == NULL)
170 {
171 fprintf (stderr, "Error: failed to get working directory. %s\n",
172 strerror (errno));
173 free (doc_path);
174 return -1;
175 }
176
177 if (NULL == (mem_test_file_local = malloc (len)))
178 {
179 fprintf (stderr, MHD_E_MEM);
180 free (doc_path);
181 return -1;
182 }
183
184 fseek (test_fd, 0, SEEK_SET);
185 if (fread (mem_test_file_local, sizeof (char), len, test_fd) != len)
186 {
187 fprintf (stderr, "Error: failed to read test file. %s\n",
188 strerror (errno));
189 free (doc_path);
190 free (mem_test_file_local);
191 return -1;
192 }
193
194 if (NULL == (cbc.buf = malloc (len)))
195 {
196 fprintf (stderr, MHD_E_MEM);
197 free (doc_path);
198 free (mem_test_file_local);
199 return -1;
200 }
201 cbc.size = len;
202 cbc.pos = 0;
203
204 /* construct url - this might use doc_path */
205 sprintf (url, "%s%s/%s", "https://localhost:42433",
206 doc_path, test_file_name);
207
208 c = curl_easy_init ();
209#if DEBUG_CURL_VERBOSE
210 curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
211#endif
212 curl_easy_setopt (c, CURLOPT_URL, url);
213 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
214 curl_easy_setopt (c, CURLOPT_TIMEOUT, 15L);
215 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
216 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
217 curl_easy_setopt (c, CURLOPT_FILE, &cbc);
218
219 /* TLS options */
220 curl_easy_setopt (c, CURLOPT_SSLVERSION, proto_version);
221 curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, cipher_suite);
222
223 /* currently skip any peer authentication */
224 curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
225 curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
226
227 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
228
229 /* NOTE: use of CONNECTTIMEOUT without also
230 setting NOSIGNAL results in really weird
231 crashes on my system! */
232 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
233 if (CURLE_OK != (errornum = curl_easy_perform (c)))
234 {
235 fprintf (stderr, "curl_easy_perform failed: `%s'\n",
236 curl_easy_strerror (errornum));
237 curl_easy_cleanup (c);
238 free (cbc.buf);
239 free (mem_test_file_local);
240 free (doc_path);
241 return errornum;
242 }
243
244 curl_easy_cleanup (c);
245
246 if (memcmp (cbc.buf, mem_test_file_local, len) != 0)
247 {
248 fprintf (stderr, "Error: local file & received file differ.\n");
249 free (cbc.buf);
250 free (mem_test_file_local);
251 free (doc_path);
252 return -1;
253 }
254
255 free (mem_test_file_local);
256 free (cbc.buf);
257 free (doc_path);
258 return 0;
259}
260
261/** 44/**
262 * used when spawning multiple threads executing curl server requests 45 * used when spawning multiple threads executing curl server requests
263 * 46 *
@@ -278,92 +61,6 @@ https_transfer_thread_adapter (void *args)
278 return &nonnull; 61 return &nonnull;
279} 62}
280 63
281static FILE *
282setupTestFile ()
283{
284 FILE *test_fd;
285
286 if (NULL == (test_fd = fopen (test_file_name, "w+")))
287 {
288 fprintf (stderr, "Error: failed to open `%s': %s\n",
289 test_file_name, strerror (errno));
290 return NULL;
291 }
292 if (fwrite (test_file_data, sizeof (char), strlen (test_file_data), test_fd)
293 != strlen (test_file_data))
294 {
295 fprintf (stderr, "Error: failed to write `%s. %s'\n",
296 test_file_name, strerror (errno));
297 fclose (test_fd);
298 return NULL;
299 }
300 if (fflush (test_fd))
301 {
302 fprintf (stderr, "Error: failed to flush test file stream. %s\n",
303 strerror (errno));
304 fclose (test_fd);
305 return NULL;
306 }
307
308 return test_fd;
309}
310
311static int
312setup (struct MHD_Daemon **d, int daemon_flags, va_list arg_list)
313{
314 *d = MHD_start_daemon_va (daemon_flags, 42433,
315 NULL, NULL, &http_ahc, NULL, arg_list);
316
317 if (*d == NULL)
318 {
319 fprintf (stderr, MHD_E_SERVER_INIT);
320 return -1;
321 }
322
323 return 0;
324}
325
326static void
327teardown (struct MHD_Daemon *d)
328{
329 MHD_stop_daemon (d);
330}
331
332/* TODO test_wrap: change sig to (setup_func, test, va_list test_arg) & move to test_util.c */
333static int
334test_wrap (char *test_name, int
335 (*test_function) (FILE * test_fd, char *cipher_suite,
336 int proto_version), FILE * test_fd,
337 int daemon_flags, char *cipher_suite, int proto_version, ...)
338{
339 int ret;
340 va_list arg_list;
341 struct MHD_Daemon *d;
342
343 va_start (arg_list, proto_version);
344 if (setup (&d, daemon_flags, arg_list) != 0)
345 {
346 va_end (arg_list);
347 return -1;
348 }
349
350 fprintf (stdout, "running test: %s ", test_name);
351 ret = test_function (test_fd, cipher_suite, proto_version);
352
353 if (ret == 0)
354 {
355 fprintf (stdout, "[pass]\n");
356 }
357 else
358 {
359 fprintf (stdout, "[fail]\n");
360 }
361
362 teardown (d);
363 va_end (arg_list);
364 return ret;
365}
366
367/** 64/**
368 * Test non-parallel requests. 65 * Test non-parallel requests.
369 * 66 *
@@ -407,11 +104,10 @@ test_parallel_clients (FILE * test_fd, char *cipher_suite,
407 for (i = 0; i < client_count; ++i) 104 for (i = 0; i < client_count; ++i)
408 { 105 {
409 if (pthread_create (&client_arr[i], NULL, 106 if (pthread_create (&client_arr[i], NULL,
410 &https_transfer_thread_adapter, 107 &https_transfer_thread_adapter, &client_args) != 0)
411 &client_args) != 0)
412 { 108 {
413 fprintf (stderr, "Error: failed to spawn test client threads.\n"); 109 fprintf (stderr, "Error: failed to spawn test client threads.\n");
414 110
415 return -1; 111 return -1;
416 } 112 }
417 } 113 }
@@ -441,7 +137,7 @@ main (int argc, char *const *argv)
441 if (curl_check_version (MHD_REQ_CURL_VERSION)) 137 if (curl_check_version (MHD_REQ_CURL_VERSION))
442 return -1; 138 return -1;
443 139
444 if ((test_fd = setupTestFile ()) == NULL) 140 if ((test_fd = setup_test_file ()) == NULL)
445 { 141 {
446 fprintf (stderr, MHD_E_TEST_FILE_CREAT); 142 fprintf (stderr, MHD_E_TEST_FILE_CREAT);
447 return -1; 143 return -1;
@@ -456,14 +152,16 @@ main (int argc, char *const *argv)
456 152
457 errorCount += 153 errorCount +=
458 test_wrap ("multi threaded daemon, single client", &test_single_client, 154 test_wrap ("multi threaded daemon, single client", &test_single_client,
459 test_fd, MHD_USE_SSL | MHD_USE_DEBUG | MHD_USE_THREAD_PER_CONNECTION, "AES256-SHA", 155 test_fd,
460 CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem, 156 MHD_USE_SSL | MHD_USE_DEBUG | MHD_USE_THREAD_PER_CONNECTION,
461 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, 157 "AES256-SHA", CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY,
462 MHD_OPTION_END); 158 srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
159 srv_self_signed_cert_pem, MHD_OPTION_END);
463 160
464 errorCount += 161 errorCount +=
465 test_wrap ("multi threaded daemon, parallel client", 162 test_wrap ("multi threaded daemon, parallel client",
466 &test_parallel_clients, test_fd, MHD_USE_SSL | MHD_USE_DEBUG | MHD_USE_THREAD_PER_CONNECTION, 163 &test_parallel_clients, test_fd,
164 MHD_USE_SSL | MHD_USE_DEBUG | MHD_USE_THREAD_PER_CONNECTION,
467 "AES256-SHA", CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY, 165 "AES256-SHA", CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY,
468 srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT, 166 srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
469 srv_self_signed_cert_pem, MHD_OPTION_END); 167 srv_self_signed_cert_pem, MHD_OPTION_END);
@@ -474,7 +172,7 @@ main (int argc, char *const *argv)
474 curl_global_cleanup (); 172 curl_global_cleanup ();
475 fclose (test_fd); 173 fclose (test_fd);
476 174
477 remove (test_file_name); 175 remove (TEST_FILE_NAME);
478 176
479 return errorCount != 0; 177 return errorCount != 0;
480} 178}
diff --git a/src/testcurl/https/tls_session_time_out_test.c b/src/testcurl/https/tls_session_time_out_test.c
index 97c7b74f..0f50ce39 100644
--- a/src/testcurl/https/tls_session_time_out_test.c
+++ b/src/testcurl/https/tls_session_time_out_test.c
@@ -31,33 +31,20 @@
31#include "gnutls_int.h" 31#include "gnutls_int.h"
32#include "gnutls_datum.h" 32#include "gnutls_datum.h"
33#include "gnutls_record.h" 33#include "gnutls_record.h"
34#include "tls_test_keys.h"
35 34
36#define MHD_E_MEM "Error: memory error\n" 35#include "tls_test_common.h"
37#define MHD_E_SERVER_INIT "Error: failed to start server\n" 36extern const char srv_key_pem[];
38#define MHD_E_FAILED_TO_CONNECT "Error: server connection could not be established\n" 37extern const char srv_self_signed_cert_pem[];
39
40const char *ca_cert_file_name = "ca_cert_pem";
41const char *test_file_name = "https_test_file";
42const char test_file_data[] = "Hello World\n";
43 38
44static const int TIME_OUT = 3; 39static const int TIME_OUT = 3;
45 40
46char *http_get_req = "GET / HTTP/1.1\r\n\r\n"; 41char *http_get_req = "GET / HTTP/1.1\r\n\r\n";
47 42
48/* HTTP access handler call back */
49static int 43static int
50http_ahc (void *cls, struct MHD_Connection *connection, 44setup_timeout_test (MHD_gtls_session_t * session,
51 const char *url, const char *method, const char *upload_data, 45 MHD_gnutls_datum_t * key,
52 const char *version, unsigned int *upload_data_size, void **ptr) 46 MHD_gnutls_datum_t * cert,
53{ 47 MHD_gtls_cert_credentials_t * xcred)
54 return 0;
55}
56
57static int
58setup (MHD_gtls_session_t * session,
59 MHD_gnutls_datum_t * key,
60 MHD_gnutls_datum_t * cert, MHD_gtls_cert_credentials_t * xcred)
61{ 48{
62 int ret; 49 int ret;
63 50
@@ -82,9 +69,10 @@ setup (MHD_gtls_session_t * session,
82} 69}
83 70
84static int 71static int
85teardown (MHD_gtls_session_t session, 72teardown_timeout_test (MHD_gtls_session_t session,
86 MHD_gnutls_datum_t * key, 73 MHD_gnutls_datum_t * key,
87 MHD_gnutls_datum_t * cert, MHD_gtls_cert_credentials_t xcred) 74 MHD_gnutls_datum_t * cert,
75 MHD_gtls_cert_credentials_t xcred)
88{ 76{
89 77
90 MHD_gtls_free_datum_m (key, free); 78 MHD_gtls_free_datum_m (key, free);
@@ -105,14 +93,13 @@ test_tls_session_time_out (MHD_gtls_session_t session)
105 sd = socket (AF_INET, SOCK_STREAM, 0); 93 sd = socket (AF_INET, SOCK_STREAM, 0);
106 if (sd == -1) 94 if (sd == -1)
107 { 95 {
108 fprintf(stderr, 96 fprintf (stderr, "Failed to create socket: %s\n", strerror (errno));
109 "Failed to create socket: %s\n",
110 strerror(errno));
111 return -1; 97 return -1;
112 } 98 }
99
113 memset (&sa, '\0', sizeof (struct sockaddr_in)); 100 memset (&sa, '\0', sizeof (struct sockaddr_in));
114 sa.sin_family = AF_INET; 101 sa.sin_family = AF_INET;
115 sa.sin_port = htons (42433); 102 sa.sin_port = htons (DEAMON_TEST_PORT);
116 inet_pton (AF_INET, "127.0.0.1", &sa.sin_addr); 103 inet_pton (AF_INET, "127.0.0.1", &sa.sin_addr);
117 104
118 MHD__gnutls_transport_set_ptr (session, (MHD_gnutls_transport_ptr_t) sd); 105 MHD__gnutls_transport_set_ptr (session, (MHD_gnutls_transport_ptr_t) sd);
@@ -158,8 +145,8 @@ main (int argc, char *const *argv)
158 MHD_gtls_global_set_log_level (11); 145 MHD_gtls_global_set_log_level (11);
159 146
160 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL | 147 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
161 MHD_USE_DEBUG, 42433, 148 MHD_USE_DEBUG, DEAMON_TEST_PORT,
162 NULL, NULL, &http_ahc, NULL, 149 NULL, NULL, &http_dummy_ahc, NULL,
163 MHD_OPTION_CONNECTION_TIMEOUT, TIME_OUT, 150 MHD_OPTION_CONNECTION_TIMEOUT, TIME_OUT,
164 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem, 151 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
165 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, 152 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
@@ -171,12 +158,11 @@ main (int argc, char *const *argv)
171 return -1; 158 return -1;
172 } 159 }
173 160
174 setup (&session, &key, &cert, &xcred); 161 setup_timeout_test (&session, &key, &cert, &xcred);
175 errorCount += test_tls_session_time_out (session); 162 errorCount += test_tls_session_time_out (session);
176 teardown (session, &key, &cert, xcred); 163 teardown_timeout_test (session, &key, &cert, xcred);
177 164
178 if (errorCount != 0) 165 print_test_result (errorCount, argv[0]);
179 fprintf (stderr, "Failed test: %s.\n", argv[0]);
180 166
181 MHD_stop_daemon (d); 167 MHD_stop_daemon (d);
182 MHD__gnutls_global_deinit (); 168 MHD__gnutls_global_deinit ();
diff --git a/src/testcurl/https/tls_test_common.c b/src/testcurl/https/tls_test_common.c
new file mode 100644
index 00000000..e9367462
--- /dev/null
+++ b/src/testcurl/https/tls_test_common.c
@@ -0,0 +1,414 @@
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 tls_daemon_options_test.c
23 * @brief Common tls test functions
24 * @author Sagie Amir
25 */
26
27#include "tls_test_common.h"
28#include "tls_test_keys.h"
29
30const char test_file_data[] = "Hello World\n";
31
32int curl_check_version (const char *req_version, ...);
33
34void
35print_test_result (int test_outcome, char *test_name)
36{
37 if (test_outcome != 0)
38 fprintf (stderr, "running test: %s [fail]\n", test_name);
39 else
40 fprintf (stdout, "running test: %s [pass]\n", test_name);
41}
42
43size_t
44copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
45{
46 struct CBC *cbc = ctx;
47
48 if (cbc->pos + size * nmemb > cbc->size)
49 return 0; /* overflow */
50 memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
51 cbc->pos += size * nmemb;
52 return size * nmemb;
53}
54
55static int
56file_reader (void *cls, size_t pos, char *buf, int max)
57{
58 FILE *file = cls;
59 fseek (file, pos, SEEK_SET);
60 return fread (buf, 1, max, file);
61}
62
63/**
64 * HTTP access handler call back
65 */
66int
67http_ahc (void *cls, struct MHD_Connection *connection,
68 const char *url, const char *method, const char *upload_data,
69 const char *version, unsigned int *upload_data_size, void **ptr)
70{
71 static int aptr;
72 struct MHD_Response *response;
73 int ret;
74 FILE *file;
75 struct stat buf;
76
77 if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
78 return MHD_NO; /* unexpected method */
79 if (&aptr != *ptr)
80 {
81 /* do never respond on first call */
82 *ptr = &aptr;
83 return MHD_YES;
84 }
85 *ptr = NULL; /* reset when done */
86
87 file = fopen (url, "r");
88 if (file == NULL)
89 {
90 response = MHD_create_response_from_data (strlen (PAGE_NOT_FOUND),
91 (void *) PAGE_NOT_FOUND,
92 MHD_NO, MHD_NO);
93 ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
94 MHD_destroy_response (response);
95 }
96 else
97 {
98 stat (url, &buf);
99 response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k PAGE_NOT_FOUND size */
100 &file_reader, file,
101 (MHD_ContentReaderFreeCallback)
102 & fclose);
103 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
104 MHD_destroy_response (response);
105 }
106 return ret;
107}
108
109/* HTTP access handler call back */
110int
111http_dummy_ahc (void *cls, struct MHD_Connection *connection,
112 const char *url, const char *method, const char *upload_data,
113 const char *version, unsigned int *upload_data_size,
114 void **ptr)
115{
116 return 0;
117}
118
119/**
120 * send a test http request to the daemon
121 * @param url
122 * @param cbc - may be null
123 * @param cipher_suite
124 * @param proto_version
125 * @return
126 */
127/* TODO have test wrap consider a NULL cbc */
128send_curl_req (char *url, struct CBC * cbc, char *cipher_suite,
129 int proto_version)
130{
131 CURL *c;
132 CURLcode errornum;
133 c = curl_easy_init ();
134#if DEBUG_HTTPS_TEST
135 curl_easy_setopt (c, CURLOPT_VERBOSE, CURL_VERBOS_LEVEL);
136#endif
137 curl_easy_setopt (c, CURLOPT_URL, url);
138 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
139 curl_easy_setopt (c, CURLOPT_TIMEOUT, 60L);
140 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 60L);
141
142 if (cbc != NULL)
143 {
144 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
145 curl_easy_setopt (c, CURLOPT_FILE, cbc);
146 }
147
148 /* TLS options */
149 curl_easy_setopt (c, CURLOPT_SSLVERSION, proto_version);
150 curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, cipher_suite);
151
152 /* currently skip any peer authentication */
153 curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
154 curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
155
156 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
157
158 /* NOTE: use of CONNECTTIMEOUT without also
159 setting NOSIGNAL results in really weird
160 crashes on my system! */
161 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
162 if (CURLE_OK != (errornum = curl_easy_perform (c)))
163 {
164 fprintf (stderr, "curl_easy_perform failed: `%s'\n",
165 curl_easy_strerror (errornum));
166 curl_easy_cleanup (c);
167 return errornum;
168 }
169
170 curl_easy_cleanup (c);
171
172 return CURLE_OK;
173}
174
175/**
176 * compile test file url pointing to the current running directory path
177 * @param url - char buffer into which the url is compiled
178 * @return
179 */
180int
181gen_test_file_url (char *url, int port)
182{
183 int ret = 0;
184 char *doc_path;
185 size_t doc_path_len;
186 /* setup test file path, url */
187 doc_path_len = PATH_MAX > 4096 ? 4096 : PATH_MAX;
188 if (NULL == (doc_path = malloc (doc_path_len)))
189 {
190 fprintf (stderr, MHD_E_MEM);
191 ret = -1;
192 }
193 if (getcwd (doc_path, doc_path_len) == NULL)
194 {
195 fprintf (stderr, "Error: failed to get working directory. %s\n",
196 strerror (errno));
197 ret = -1;
198 }
199 /* construct url - this might use doc_path */
200 if (sprintf (url, "%s:%d%s/%s", "https://localhost", port,
201 doc_path, TEST_FILE_NAME) < 0)
202 ret = -1;
203
204 free (doc_path);
205 return ret;
206}
207
208/**
209 * test HTTPS file transfer
210 * @param test_fd: file to attempt transferring
211 */
212int
213test_https_transfer (FILE * test_fd, char *cipher_suite, int proto_version)
214{
215 int len, ret = 0;
216 struct CBC cbc;
217 char url[255];
218 struct stat statb;
219 /* used to memcmp local copy & deamon supplied copy */
220 unsigned char *mem_test_file_local;
221
222 stat (TEST_FILE_NAME, &statb);
223 len = statb.st_size;
224
225 if (NULL == (mem_test_file_local = malloc (len)))
226 {
227 fprintf (stderr, MHD_E_MEM);
228 ret = -1;
229 goto cleanup;
230 }
231
232 fseek (test_fd, 0, SEEK_SET);
233 if (fread (mem_test_file_local, sizeof (char), len, test_fd) != len)
234 {
235 fprintf (stderr, "Error: failed to read test file. %s\n",
236 strerror (errno));
237 ret = -1;
238 goto cleanup;
239 }
240
241 if (NULL == (cbc.buf = malloc (sizeof (char) * len)))
242 {
243 fprintf (stderr, MHD_E_MEM);
244 ret = -1;
245 goto cleanup;
246 }
247 cbc.size = len;
248 cbc.pos = 0;
249
250 if (gen_test_file_url (url, DEAMON_TEST_PORT))
251 {
252 ret = -1;
253 goto cleanup;
254 }
255
256 if (CURLE_OK != send_curl_req (url, &cbc, cipher_suite, proto_version))
257 {
258 ret = -1;
259 goto cleanup;
260 }
261
262 /* compare test file & daemon responce */
263 if (memcmp (cbc.buf, mem_test_file_local, len) != 0)
264 {
265 fprintf (stderr, "Error: local file & received file differ.\n");
266 ret = -1;
267 }
268
269cleanup:
270 free (mem_test_file_local);
271 free (cbc.buf);
272 return ret;
273}
274
275/**
276 * setup a mock test file which is requested from the running daemon
277 * @return open file descriptor to the test file
278 */
279FILE *
280setup_test_file ()
281{
282 FILE *test_fd;
283
284 if (NULL == (test_fd = fopen (TEST_FILE_NAME, "w+")))
285 {
286 fprintf (stderr, "Error: failed to open `%s': %s\n",
287 TEST_FILE_NAME, strerror (errno));
288 return NULL;
289 }
290 if (fwrite (test_file_data, sizeof (char), strlen (test_file_data), test_fd)
291 != strlen (test_file_data))
292 {
293 fprintf (stderr, "Error: failed to write `%s. %s'\n",
294 TEST_FILE_NAME, strerror (errno));
295 fclose (test_fd);
296 return NULL;
297 }
298 if (fflush (test_fd))
299 {
300 fprintf (stderr, "Error: failed to flush test file stream. %s\n",
301 strerror (errno));
302 fclose (test_fd);
303 return NULL;
304 }
305 return test_fd;
306}
307
308/**
309 * setup test case
310 *
311 * @param d
312 * @param daemon_flags
313 * @param arg_list
314 * @return
315 */
316int
317setup_testcase (struct MHD_Daemon **d, int daemon_flags, va_list arg_list)
318{
319 *d = MHD_start_daemon_va (daemon_flags, DEAMON_TEST_PORT,
320 NULL, NULL, &http_ahc, NULL, arg_list);
321
322 if (*d == NULL)
323 {
324 fprintf (stderr, MHD_E_SERVER_INIT);
325 return -1;
326 }
327
328 return 0;
329}
330
331void
332teardown_testcase (struct MHD_Daemon *d)
333{
334 MHD_stop_daemon (d);
335}
336
337int
338setup_session (MHD_gtls_session_t * session,
339 MHD_gnutls_datum_t * key,
340 MHD_gnutls_datum_t * cert, MHD_gtls_cert_credentials_t * xcred)
341{
342 int ret;
343 const char **err_pos;
344
345 MHD__gnutls_certificate_allocate_credentials (xcred);
346
347 MHD_gtls_set_datum_m (key, srv_key_pem, strlen (srv_key_pem), &malloc);
348 MHD_gtls_set_datum_m (cert, srv_self_signed_cert_pem,
349 strlen (srv_self_signed_cert_pem), &malloc);
350
351 MHD__gnutls_certificate_set_x509_key_mem (*xcred, cert, key,
352 GNUTLS_X509_FMT_PEM);
353
354 MHD__gnutls_init (session, GNUTLS_CLIENT);
355 ret = MHD__gnutls_priority_set_direct (*session, "NORMAL", err_pos);
356 if (ret < 0)
357 {
358 return -1;
359 }
360
361 MHD__gnutls_credentials_set (*session, MHD_GNUTLS_CRD_CERTIFICATE, xcred);
362 return 0;
363}
364
365int
366teardown_session (MHD_gtls_session_t session,
367 MHD_gnutls_datum_t * key,
368 MHD_gnutls_datum_t * cert,
369 MHD_gtls_cert_credentials_t xcred)
370{
371
372 MHD_gtls_free_datum_m (key, free);
373 MHD_gtls_free_datum_m (cert, free);
374
375 MHD__gnutls_deinit (session);
376
377 MHD__gnutls_certificate_free_credentials (xcred);
378 return 0;
379}
380
381/* TODO test_wrap: change sig to (setup_func, test, va_list test_arg) */
382int
383test_wrap (char *test_name, int
384 (*test_function) (FILE * test_fd, char *cipher_suite,
385 int proto_version), FILE * test_fd,
386 int daemon_flags, char *cipher_suite, int proto_version, ...)
387{
388 int ret;
389 va_list arg_list;
390 struct MHD_Daemon *d;
391
392 va_start (arg_list, proto_version);
393 if (setup_testcase (&d, daemon_flags, arg_list) != 0)
394 {
395 va_end (arg_list);
396 return -1;
397 }
398
399 fprintf (stdout, "running test: %s ", test_name);
400 ret = test_function (test_fd, cipher_suite, proto_version);
401
402 if (ret == 0)
403 {
404 fprintf (stdout, "[pass]\n");
405 }
406 else
407 {
408 fprintf (stdout, "[fail]\n");
409 }
410
411 teardown_testcase (d);
412 va_end (arg_list);
413 return ret;
414}
diff --git a/src/testcurl/https/tls_test_common.h b/src/testcurl/https/tls_test_common.h
new file mode 100644
index 00000000..75c4361d
--- /dev/null
+++ b/src/testcurl/https/tls_test_common.h
@@ -0,0 +1,118 @@
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#ifndef TLS_TEST_COMMON_H_
22#define TLS_TEST_COMMON_H_
23
24#include "platform.h"
25#include "microhttpd.h"
26#include <curl/curl.h>
27#include <sys/stat.h>
28#include <limits.h>
29#include "gnutls.h"
30
31/* this enables verbos CURL version checking */
32#define DEBUG_HTTPS_TEST 1
33#define CURL_VERBOS_LEVEL 1
34
35#define DEAMON_TEST_PORT 42433
36
37#define TEST_FILE_NAME "https_test_file"
38
39#define EMPTY_PAGE "<html><head><title>Empty page</title></head><body>Empty page</body></html>"
40#define PAGE_NOT_FOUND "<html><head><title>File not found</title></head><body>File not found</body></html>"
41
42#define MHD_E_MEM "Error: memory error\n"
43#define MHD_E_SERVER_INIT "Error: failed to start server\n"
44#define MHD_E_TEST_FILE_CREAT "Error: failed to setup test file\n"
45#define MHD_E_CERT_FILE_CREAT "Error: failed to setup test certificate\n"
46#define MHD_E_KEY_FILE_CREAT "Error: failed to setup test certificate\n"
47#define MHD_E_FAILED_TO_CONNECT "Error: server connection could not be established\n"
48
49/* TODO rm if unused */
50struct https_test_data
51{
52 FILE *test_fd;
53 char *cipher_suite;
54 int proto_version;
55};
56
57struct CBC
58{
59 char *buf;
60 size_t pos;
61 size_t size;
62};
63
64struct CipherDef
65{
66 int options[2];
67 char *curlname;
68};
69
70void print_test_result (int test_outcome, char *test_name);
71
72size_t copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx);
73
74int
75http_ahc (void *cls, struct MHD_Connection *connection,
76 const char *url, const char *method, const char *upload_data,
77 const char *version, unsigned int *upload_data_size, void **ptr);
78
79int
80http_dummy_ahc (void *cls, struct MHD_Connection *connection,
81 const char *url, const char *method, const char *upload_data,
82 const char *version, unsigned int *upload_data_size,
83 void **ptr);
84
85int gen_test_file_url (char *url, int port);
86
87int
88send_curl_req (char *url, struct CBC *cbc, char *cipher_suite,
89 int proto_version);
90
91int
92test_https_transfer (FILE * test_fd, char *cipher_suite, int proto_version);
93
94FILE *setup_test_file ();
95
96int
97setup_testcase (struct MHD_Daemon **d, int daemon_flags, va_list arg_list);
98
99void teardown_testcase (struct MHD_Daemon *d);
100
101int
102setup_session (MHD_gtls_session_t * session,
103 MHD_gnutls_datum_t * key,
104 MHD_gnutls_datum_t * cert,
105 MHD_gtls_cert_credentials_t * xcred);
106
107int
108teardown_session (MHD_gtls_session_t session,
109 MHD_gnutls_datum_t * key,
110 MHD_gnutls_datum_t * cert,
111 MHD_gtls_cert_credentials_t xcred);
112
113int
114test_wrap (char *test_name, int
115 (*test_function) (FILE * test_fd, char *cipher_suite,
116 int proto_version), FILE * test_fd,
117 int daemon_flags, char *cipher_suite, int proto_version, ...);
118#endif /* TLS_TEST_COMMON_H_ */
diff --git a/src/testcurl/https/tls_thread_mode_test.c b/src/testcurl/https/tls_thread_mode_test.c
index 24882d95..cf92a26d 100644
--- a/src/testcurl/https/tls_thread_mode_test.c
+++ b/src/testcurl/https/tls_thread_mode_test.c
@@ -35,230 +35,12 @@
35#include "gnutls.h" 35#include "gnutls.h"
36#include <curl/curl.h> 36#include <curl/curl.h>
37 37
38#define DEBUG_CURL_VERBOSE 0 38#include "tls_test_common.h"
39#define PAGE_NOT_FOUND "<html><head><title>File not found</title></head><body>File not found</body></html>" 39extern const char srv_key_pem[];
40 40extern const char srv_self_signed_cert_pem[];
41#define MHD_E_MEM "Error: memory error\n"
42#define MHD_E_SERVER_INIT "Error: failed to start server\n"
43#define MHD_E_TEST_FILE_CREAT "Error: failed to setup test file\n"
44#define MHD_E_CERT_FILE_CREAT "Error: failed to setup test certificate\n"
45#define MHD_E_KEY_FILE_CREAT "Error: failed to setup test certificate\n"
46
47#include "tls_test_keys.h"
48
49const char *test_file_name = "https_test_file";
50const char test_file_data[] = "Hello World\n";
51 41
52int curl_check_version (const char *req_version, ...); 42int curl_check_version (const char *req_version, ...);
53 43
54struct CBC
55{
56 char *buf;
57 size_t pos;
58 size_t size;
59};
60
61struct https_test_data
62{
63 FILE *test_fd;
64 char *cipher_suite;
65 int proto_version;
66};
67
68struct CipherDef
69{
70 int options[2];
71 char *curlname;
72};
73
74static size_t
75copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
76{
77 struct CBC *cbc = ctx;
78
79 if (cbc->pos + size * nmemb > cbc->size)
80 return 0; /* overflow */
81 memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
82 cbc->pos += size * nmemb;
83 return size * nmemb;
84}
85
86static int
87file_reader (void *cls, size_t pos, char *buf, int max)
88{
89 FILE *file = cls;
90 fseek (file, pos, SEEK_SET);
91 return fread (buf, 1, max, file);
92}
93
94/* HTTP access handler call back */
95static int
96http_ahc (void *cls, struct MHD_Connection *connection,
97 const char *url, const char *method, const char *upload_data,
98 const char *version, unsigned int *upload_data_size, void **ptr)
99{
100 static int aptr;
101 struct MHD_Response *response;
102 int ret;
103 FILE *file;
104 struct stat buf;
105
106 if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
107 return MHD_NO; /* unexpected method */
108 if (&aptr != *ptr)
109 {
110 /* do never respond on first call */
111 *ptr = &aptr;
112 return MHD_YES;
113 }
114 *ptr = NULL; /* reset when done */
115
116 file = fopen (url, "r");
117 if (file == NULL)
118 {
119 response = MHD_create_response_from_data (strlen (PAGE_NOT_FOUND),
120 (void *) PAGE_NOT_FOUND,
121 MHD_NO, MHD_NO);
122 ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
123 MHD_destroy_response (response);
124 }
125 else
126 {
127 stat (url, &buf);
128 response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k PAGE_NOT_FOUND size */
129 &file_reader, file,
130 (MHD_ContentReaderFreeCallback)
131 & fclose);
132 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
133 MHD_destroy_response (response);
134 }
135 return ret;
136}
137
138
139
140/**
141 * test HTTPS transfer
142 * @param test_fd: file to attempt transfering
143 */
144static int
145test_https_transfer (FILE * test_fd, char *cipher_suite, int proto_version)
146{
147 CURL *c;
148 CURLcode errornum;
149 struct CBC cbc;
150 char *doc_path;
151 size_t doc_path_len;
152 char url[255];
153 struct stat statb;
154
155 stat (test_file_name, &statb);
156
157 int len = statb.st_size;
158
159 /* used to memcmp local copy & deamon supplied copy */
160 unsigned char *mem_test_file_local;
161
162 /* setup test file path, url */
163 doc_path_len = PATH_MAX > 4096 ? 4096 : PATH_MAX;
164 if (NULL == (doc_path = malloc (doc_path_len)))
165 {
166 fprintf (stderr, MHD_E_MEM);
167 return -1;
168 }
169 if (getcwd (doc_path, doc_path_len) == NULL)
170 {
171 fprintf (stderr, "Error: failed to get working directory. %s\n",
172 strerror (errno));
173 free (doc_path);
174 return -1;
175 }
176
177 if (NULL == (mem_test_file_local = malloc (len)))
178 {
179 fprintf (stderr, MHD_E_MEM);
180 free (doc_path);
181 return -1;
182 }
183
184 fseek (test_fd, 0, SEEK_SET);
185 if (fread (mem_test_file_local, sizeof (char), len, test_fd) != len)
186 {
187 fprintf (stderr, "Error: failed to read test file. %s\n",
188 strerror (errno));
189 fclose (test_fd);
190 free (doc_path);
191 free (mem_test_file_local);
192 return -1;
193 }
194
195 if (NULL == (cbc.buf = malloc (len)))
196 {
197 free (doc_path);
198 free (mem_test_file_local);
199 fprintf (stderr, MHD_E_MEM);
200 return -1;
201 }
202 cbc.size = len;
203 cbc.pos = 0;
204
205 /* construct url - this might use doc_path */
206 sprintf (url, "%s%s/%s", "https://localhost:42433",
207 doc_path, test_file_name);
208
209 c = curl_easy_init ();
210#if DEBUG_CURL_VERBOSE
211 curl_easy_setopt (c, CURLOPT_VERBOSE, 1);
212#endif
213 curl_easy_setopt (c, CURLOPT_URL, url);
214 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
215 curl_easy_setopt (c, CURLOPT_TIMEOUT, 60L);
216 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 60L);
217 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
218 curl_easy_setopt (c, CURLOPT_FILE, &cbc);
219
220 /* TLS options */
221 curl_easy_setopt (c, CURLOPT_SSLVERSION, proto_version);
222 curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, cipher_suite);
223
224 /* currently skip any peer authentication */
225 curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
226 curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0);
227
228 curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
229
230 /* NOTE: use of CONNECTTIMEOUT without also
231 setting NOSIGNAL results in really weird
232 crashes on my system! */
233 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
234 if (CURLE_OK != (errornum = curl_easy_perform (c)))
235 {
236 fprintf (stderr, "curl_easy_perform failed: `%s'\n",
237 curl_easy_strerror (errornum));
238 curl_easy_cleanup (c);
239 free (cbc.buf);
240 free (mem_test_file_local);
241 free (doc_path);
242 return errornum;
243 }
244
245 curl_easy_cleanup (c);
246
247 if (memcmp (cbc.buf, mem_test_file_local, len) != 0)
248 {
249 fprintf (stderr, "Error: local file & received file differ.\n");
250 free (cbc.buf);
251 free (mem_test_file_local);
252 free (doc_path);
253 return -1;
254 }
255
256 free (mem_test_file_local);
257 free (cbc.buf);
258 free (doc_path);
259 return 0;
260}
261
262/** 44/**
263 * used when spawning multiple threads executing curl server requests 45 * used when spawning multiple threads executing curl server requests
264 * 46 *
@@ -279,92 +61,6 @@ https_transfer_thread_adapter (void *args)
279 return &nonnull; 61 return &nonnull;
280} 62}
281 63
282static FILE *
283setupTestFile ()
284{
285 FILE *test_fd;
286
287 if (NULL == (test_fd = fopen (test_file_name, "w+")))
288 {
289 fprintf (stderr, "Error: failed to open `%s': %s\n",
290 test_file_name, strerror (errno));
291 return NULL;
292 }
293 if (fwrite (test_file_data, sizeof (char), strlen (test_file_data), test_fd)
294 != strlen (test_file_data))
295 {
296 fprintf (stderr, "Error: failed to write `%s. %s'\n",
297 test_file_name, strerror (errno));
298 fclose (test_fd);
299 return NULL;
300 }
301 if (fflush (test_fd))
302 {
303 fprintf (stderr, "Error: failed to flush test file stream. %s\n",
304 strerror (errno));
305 fclose (test_fd);
306 return NULL;
307 }
308
309 return test_fd;
310}
311
312static int
313setup (struct MHD_Daemon **d, int daemon_flags, va_list arg_list)
314{
315 *d = MHD_start_daemon_va (daemon_flags, 42433,
316 NULL, NULL, &http_ahc, NULL, arg_list);
317
318 if (*d == NULL)
319 {
320 fprintf (stderr, MHD_E_SERVER_INIT);
321 return -1;
322 }
323
324 return 0;
325}
326
327static void
328teardown (struct MHD_Daemon *d)
329{
330 MHD_stop_daemon (d);
331}
332
333/* TODO test_wrap: change sig to (setup_func, test, va_list test_arg) & move to test_util.c */
334static int
335test_wrap (char *test_name, int
336 (*test_function) (FILE * test_fd, char *cipher_suite,
337 int proto_version), FILE * test_fd,
338 int daemon_flags, char *cipher_suite, int proto_version, ...)
339{
340 int ret;
341 va_list arg_list;
342 struct MHD_Daemon *d;
343
344 va_start (arg_list, proto_version);
345 if (setup (&d, daemon_flags, arg_list) != 0)
346 {
347 va_end (arg_list);
348 return -1;
349 }
350
351 fprintf (stdout, "running test: %s ", test_name);
352 ret = test_function (test_fd, cipher_suite, proto_version);
353
354 if (ret == 0)
355 {
356 fprintf (stdout, "[pass]\n");
357 }
358 else
359 {
360 fprintf (stdout, "[fail]\n");
361 }
362
363 teardown (d);
364 va_end (arg_list);
365 return ret;
366}
367
368/** 64/**
369 * Test non-parallel requests. 65 * Test non-parallel requests.
370 * 66 *
@@ -386,7 +82,6 @@ test_single_client (FILE * test_fd, char *cipher_suite,
386 return 0; 82 return 0;
387} 83}
388 84
389
390/** 85/**
391 * Test parallel request handling. 86 * Test parallel request handling.
392 * 87 *
@@ -408,11 +103,9 @@ test_parallel_clients (FILE * test_fd, char *cipher_suite,
408 for (i = 0; i < client_count; ++i) 103 for (i = 0; i < client_count; ++i)
409 { 104 {
410 if (pthread_create (&client_arr[i], NULL, 105 if (pthread_create (&client_arr[i], NULL,
411 &https_transfer_thread_adapter, 106 &https_transfer_thread_adapter, &client_args) != 0)
412 &client_args) != 0)
413 { 107 {
414 fprintf (stderr, "Error: failed to spawn test client threads.\n"); 108 fprintf (stderr, "Error: failed to spawn test client threads.\n");
415
416 return -1; 109 return -1;
417 } 110 }
418 } 111 }
@@ -428,7 +121,6 @@ test_parallel_clients (FILE * test_fd, char *cipher_suite,
428 return 0; 121 return 0;
429} 122}
430 123
431
432int 124int
433main (int argc, char *const *argv) 125main (int argc, char *const *argv)
434{ 126{
@@ -442,7 +134,7 @@ main (int argc, char *const *argv)
442 if (curl_check_version (MHD_REQ_CURL_VERSION)) 134 if (curl_check_version (MHD_REQ_CURL_VERSION))
443 return -1; 135 return -1;
444 136
445 if ((test_fd = setupTestFile ()) == NULL) 137 if ((test_fd = setup_test_file ()) == NULL)
446 { 138 {
447 fprintf (stderr, MHD_E_TEST_FILE_CREAT); 139 fprintf (stderr, MHD_E_TEST_FILE_CREAT);
448 return -1; 140 return -1;
@@ -452,6 +144,7 @@ main (int argc, char *const *argv)
452 { 144 {
453 fprintf (stderr, "Error: %s\n", strerror (errno)); 145 fprintf (stderr, "Error: %s\n", strerror (errno));
454 fclose (test_fd); 146 fclose (test_fd);
147 remove (TEST_FILE_NAME);
455 return -1; 148 return -1;
456 } 149 }
457 150
@@ -462,6 +155,7 @@ main (int argc, char *const *argv)
462 "AES256-SHA", CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY, 155 "AES256-SHA", CURL_SSLVERSION_TLSv1, MHD_OPTION_HTTPS_MEM_KEY,
463 srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT, 156 srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
464 srv_self_signed_cert_pem, MHD_OPTION_END); 157 srv_self_signed_cert_pem, MHD_OPTION_END);
158
465 errorCount += 159 errorCount +=
466 test_wrap ("single threaded daemon, parallel clients", 160 test_wrap ("single threaded daemon, parallel clients",
467 &test_parallel_clients, test_fd, 161 &test_parallel_clients, test_fd,
@@ -470,13 +164,9 @@ main (int argc, char *const *argv)
470 srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT, 164 srv_key_pem, MHD_OPTION_HTTPS_MEM_CERT,
471 srv_self_signed_cert_pem, MHD_OPTION_END); 165 srv_self_signed_cert_pem, MHD_OPTION_END);
472 166
473 if (errorCount != 0)
474 fprintf (stderr, "Failed test: %s.\n", argv[0]);
475
476 curl_global_cleanup (); 167 curl_global_cleanup ();
477 fclose (test_fd); 168 fclose (test_fd);
478 169 remove (TEST_FILE_NAME);
479 remove (test_file_name);
480 170
481 return errorCount != 0; 171 return errorCount != 0;
482} 172}