aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/daemon/Makefile.am10
-rw-r--r--src/daemon/daemon.c97
-rw-r--r--src/daemon/internal.h20
-rw-r--r--src/examples/Makefile.am13
-rw-r--r--src/examples/https_server_example.c261
-rw-r--r--src/include/microhttpd.h8
6 files changed, 339 insertions, 70 deletions
diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am
index 718dd023..365c1cf1 100644
--- a/src/daemon/Makefile.am
+++ b/src/daemon/Makefile.am
@@ -11,8 +11,6 @@ EXTRA_DIST = SYMBOLS
11lib_LTLIBRARIES = \ 11lib_LTLIBRARIES = \
12 libmicrohttpd.la 12 libmicrohttpd.la
13 13
14libmicrohttpd_la_LDFLAGS = \
15 -export-dynamic -version-info 4:3:0 $(retaincommand)
16libmicrohttpd_la_SOURCES = \ 14libmicrohttpd_la_SOURCES = \
17 connection.c connection.h \ 15 connection.c connection.h \
18 reason_phrase.c reason_phrase.h \ 16 reason_phrase.c reason_phrase.h \
@@ -21,7 +19,13 @@ libmicrohttpd_la_SOURCES = \
21 memorypool.c memorypool.h \ 19 memorypool.c memorypool.h \
22 plibc.h \ 20 plibc.h \
23 postprocessor.c \ 21 postprocessor.c \
24 response.c response.h 22 response.c response.h
23libmicrohttpd_la_LDFLAGS = \
24 -export-dynamic -version-info 4:3:0 $(retaincommand) \
25 -L$(GNUTLS_LIB_PATH) \
26 -lgnutls
27libmicrohttpd_la_CPPFLAGS = \
28 $(GNUTLS_CPPFLAGS)
25 29
26check_PROGRAMS = \ 30check_PROGRAMS = \
27 postprocessor_test \ 31 postprocessor_test \
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c
index 3578823a..cb70e9a9 100644
--- a/src/daemon/daemon.c
+++ b/src/daemon/daemon.c
@@ -29,6 +29,7 @@
29#include "response.h" 29#include "response.h"
30#include "connection.h" 30#include "connection.h"
31#include "memorypool.h" 31#include "memorypool.h"
32#include <gnutls/gnutls.h>
32 33
33/** 34/**
34 * Default connection limit. 35 * Default connection limit.
@@ -52,6 +53,12 @@
52 */ 53 */
53#define DEBUG_CONNECT MHD_NO 54#define DEBUG_CONNECT MHD_NO
54 55
56// TODO rm
57/* HTTPS file path limit, leaving room for file name */
58#define MHD_PATH_LEN 240
59
60int MHDS_init (struct MHD_Daemon *daemon);
61
55/** 62/**
56 * Obtain the select sets for this daemon. 63 * Obtain the select sets for this daemon.
57 * 64 *
@@ -174,6 +181,8 @@ MHDS_handle_connection (void *data)
174 if (con == NULL) 181 if (con == NULL)
175 abort (); 182 abort ();
176 183
184 // TODO add connection time out code
185
177 /* forward call to handler */ 186 /* forward call to handler */
178 con->daemon->default_handler (NULL, con, NULL, NULL, NULL, NULL, NULL, 187 con->daemon->default_handler (NULL, con, NULL, NULL, NULL, NULL, NULL,
179 NULL); 188 NULL);
@@ -690,6 +699,13 @@ MHD_start_daemon (unsigned int options,
690 retVal->pool_size = MHD_POOL_SIZE_DEFAULT; 699 retVal->pool_size = MHD_POOL_SIZE_DEFAULT;
691 retVal->connection_timeout = 0; /* no timeout */ 700 retVal->connection_timeout = 0; /* no timeout */
692 701
702 /* set server default document root path */
703 getcwd (retVal->doc_root, MHD_PATH_LEN);
704
705 /* initialize ssl path parameters to the local path */
706 strcpy (retVal->https_cert_path, "cert.pem");
707 strcpy (retVal->https_key_path, "key.pem");
708
693 /* initializes the argument pointer variable */ 709 /* initializes the argument pointer variable */
694 va_start (ap, dh_cls); 710 va_start (ap, dh_cls);
695 711
@@ -717,6 +733,22 @@ MHD_start_daemon (unsigned int options,
717 case MHD_OPTION_PER_IP_CONNECTION_LIMIT: 733 case MHD_OPTION_PER_IP_CONNECTION_LIMIT:
718 retVal->per_ip_connection_limit = va_arg (ap, unsigned int); 734 retVal->per_ip_connection_limit = va_arg (ap, unsigned int);
719 break; 735 break;
736 case MHD_OPTION_DOC_ROOT:
737 strncpy (retVal->doc_root, va_arg (ap, char *), MHD_PATH_LEN);
738 break;
739 case MHD_OPTION_HTTPS_KEY_PATH:
740 strncpy (retVal->https_key_path, va_arg (ap, char *), MHD_PATH_LEN);
741 strcat (retVal->https_key_path, DIR_SEPARATOR_STR);
742 strcat (retVal->https_key_path, "key.pem");
743 break;
744 case MHD_OPTION_HTTPS_CERT_PATH:
745
746 strncpy (retVal->https_cert_path,
747 va_arg (ap, char *), MHD_PATH_LEN);
748 strcat (retVal->https_cert_path, DIR_SEPARATOR_STR);
749 strcat (retVal->https_cert_path, "cert.pem");
750 break;
751
720 default: 752 default:
721#if HAVE_MESSAGES 753#if HAVE_MESSAGES
722 fprintf (stderr, 754 fprintf (stderr,
@@ -725,6 +757,29 @@ MHD_start_daemon (unsigned int options,
725 abort (); 757 abort ();
726 } 758 }
727 } 759 }
760
761 /* initialize HTTPS daemon certificate aspects */
762 if (options & MHD_USE_SSL)
763 {
764 /* test for private key & certificate file exsitance */
765 FILE *cert_file = fopen (retVal->https_cert_path, "r");
766 FILE *key_file = fopen (retVal->https_key_path, "r");
767 if (key_file == NULL || cert_file == NULL)
768 {
769 printf ("missing cert files");
770#if HAVE_MESSAGES
771 MHD_DLOG (retVal, "Missing X.509 key or certificate file\n");
772#endif
773 free (retVal);
774 CLOSE (socket_fd);
775 return NULL;
776 }
777
778 fclose (cert_file);
779 fclose (key_file);
780 MHDS_init (retVal);
781 }
782
728 va_end (ap); 783 va_end (ap);
729 if (((0 != (options & MHD_USE_THREAD_PER_CONNECTION)) || (0 != (options 784 if (((0 != (options & MHD_USE_THREAD_PER_CONNECTION)) || (0 != (options
730 & 785 &
@@ -793,9 +848,51 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
793 } 848 }
794 MHD_cleanup_connections (daemon); 849 MHD_cleanup_connections (daemon);
795 } 850 }
851
852 /* TLS clean up */
853 if (daemon->options & MHD_USE_SSL)
854 {
855 gnutls_priority_deinit (daemon->priority_cache);
856 gnutls_global_deinit ();
857 }
858
796 free (daemon); 859 free (daemon);
797} 860}
798 861
862int
863MHDS_init (struct MHD_Daemon *daemon)
864{
865 gnutls_global_init ();
866 /* Generate Diffie Hellman parameters - for use with DHE kx algorithms. */
867 gnutls_dh_params_init (&daemon->dh_params);
868 gnutls_dh_params_generate2 (daemon->dh_params, DH_BITS);
869
870 // TODO make room for cipher settings adjustment
871 gnutls_priority_init (&daemon->priority_cache,
872 "NORMAL:+AES-256-CBC:+RSA:+SHA1:+COMP-NULL", NULL);
873
874 /* setup server certificate */
875 gnutls_certificate_allocate_credentials (&daemon->x509_cret);
876
877 // TODO remove if unused
878 /* add trusted CAs to certificate */
879 // gnutls_certificate_set_x509_trust_file(x509_cret, CAFILE,GNUTLS_X509_FMT_PEM);
880
881 /* add Certificate revocation list to certificate */
882 //gnutls_certificate_set_x509_crl_file(x509_cret, CRLFILE, GNUTLS_X509_FMT_PEM);
883
884 /* sets a certificate private key pair */
885 gnutls_certificate_set_x509_key_file (daemon->x509_cret,
886 daemon->https_cert_path,
887 daemon->https_key_path,
888 GNUTLS_X509_FMT_PEM);
889
890 gnutls_certificate_set_dh_params (daemon->x509_cret, daemon->dh_params);
891
892 // TODO address error case return value
893 return 0;
894}
895
799#ifndef WINDOWS 896#ifndef WINDOWS
800 897
801static struct sigaction sig; 898static struct sigaction sig;
diff --git a/src/daemon/internal.h b/src/daemon/internal.h
index 37075bc0..1084de08 100644
--- a/src/daemon/internal.h
+++ b/src/daemon/internal.h
@@ -35,6 +35,7 @@
35#include <errno.h> 35#include <errno.h>
36#include <fcntl.h> 36#include <fcntl.h>
37#include <signal.h> 37#include <signal.h>
38#include <gnutls/gnutls.h>
38 39
39#include "config.h" 40#include "config.h"
40#include "plibc.h" 41#include "plibc.h"
@@ -58,6 +59,9 @@
58 */ 59 */
59#define MHD_BUF_INC_SIZE 2048 60#define MHD_BUF_INC_SIZE 2048
60 61
62/* TLS Diffie-Hellman parameter */
63#define DH_BITS 1024
64
61#if HAVE_MESSAGES 65#if HAVE_MESSAGES
62/** 66/**
63 * fprintf-like helper function for logging debug 67 * fprintf-like helper function for logging debug
@@ -606,6 +610,22 @@ struct MHD_Daemon
606 */ 610 */
607 unsigned short port; 611 unsigned short port;
608 612
613 /* server credintials */
614 gnutls_certificate_credentials_t x509_cret;
615
616 /* cipher priority cache */
617 gnutls_priority_t priority_cache;
618
619 /* Diffie-Hellman parameters */
620 gnutls_dh_params_t dh_params;
621
622 // TODO consider switching to variadic length paths
623 /* server root path used while serving http pages */
624 char doc_root[255];
625
626 char https_key_path[255];
627
628 char https_cert_path[255];
609}; 629};
610 630
611#endif 631#endif
diff --git a/src/examples/Makefile.am b/src/examples/Makefile.am
index 189284e2..c42672ab 100644
--- a/src/examples/Makefile.am
+++ b/src/examples/Makefile.am
@@ -6,6 +6,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/include
6 6
7noinst_PROGRAMS = \ 7noinst_PROGRAMS = \
8https_server_example \ 8https_server_example \
9https_echo_server_example \
9https_echo_client_example \ 10https_echo_client_example \
10minimal_example \ 11minimal_example \
11querystring_example \ 12querystring_example \
@@ -43,6 +44,18 @@ https_server_example_LDADD = \
43https_server_example_LDFLAGS = \ 44https_server_example_LDFLAGS = \
44 -L$(GNUTLS_LIB_PATH) \ 45 -L$(GNUTLS_LIB_PATH) \
45 -lgnutls 46 -lgnutls
47
48https_echo_server_example_CPPFLAGS = \
49 $(GNUTLS_CPPFLAGS) \
50 -I$(top_srcdir)/src/daemon \
51 -I$(top_srcdir)/src/include
52https_echo_server_example_SOURCES = \
53 https_echo_server_example.c
54https_echo_server_example_LDADD = \
55 $(top_builddir)/src/daemon/libmicrohttpd.la
56https_echo_server_example_LDFLAGS = \
57 -L$(GNUTLS_LIB_PATH) \
58 -lgnutls
46 59
47https_echo_client_example_CPPFLAGS = \ 60https_echo_client_example_CPPFLAGS = \
48 $(GNUTLS_CPPFLAGS) \ 61 $(GNUTLS_CPPFLAGS) \
diff --git a/src/examples/https_server_example.c b/src/examples/https_server_example.c
index 78f7176b..459b4aa2 100644
--- a/src/examples/https_server_example.c
+++ b/src/examples/https_server_example.c
@@ -20,7 +20,17 @@
20 20
21/** 21/**
22 * @file https_server_example.c 22 * @file https_server_example.c
23 * @brief a simple echo server using TLS. echo input from client until 'exit' message is received. 23 * @brief a simple https file server using TLS.
24 *
25 * This example assumes the existence of a private key file named "key.pem"
26 * and a server certificate file named "cert.pem". File path for these should be
27 * provided as command-line arguments. 'certtool' may be used to generate these if
28 * missing.
29 *
30 * Access server with your browser of choice or with curl :
31 *
32 * curl --insecure --tlsv1 --ciphers AES256-SHA <url>
33 *
24 * @author LV-426 34 * @author LV-426
25 */ 35 */
26 36
@@ -35,64 +45,76 @@
35#include <string.h> 45#include <string.h>
36#include <stdio.h> 46#include <stdio.h>
37#include <gnutls/gnutls.h> 47#include <gnutls/gnutls.h>
48#include <gcrypt.h>
38 49
39#define DH_BITS 1024 50#define BUF_SIZE 1024
40#define MAX_BUF 1024 51#define MAX_URL_LEN 255
41/* server credintials */
42gnutls_anon_server_credentials_t anoncred;
43 52
44/* server Diffie-Hellman parameters */ 53#define KEYFILE "key.pem"
45static gnutls_dh_params_t dh_params; 54#define CERTFILE "cert.pem"
46 55
56// TODO remove if unused
57#define CAFILE "ca.pem"
58#define CRLFILE "crl.pem"
47 59
48/* Generate Diffie Hellman parameters - for use with DHE kx algorithms. */ 60#define PAGE_NOT_FOUND "<html><head><title>File not found</title></head><body>File not found</body></html>"
49static int
50generate_dh_params (void)
51{
52
53 gnutls_dh_params_init (&dh_params);
54 gnutls_dh_params_generate2 (dh_params, DH_BITS);
55 return 0;
56}
57 61
58gnutls_session_t 62gnutls_session_t
59initialize_tls_session (void) 63initialize_tls_session (struct MHD_Connection *connection)
60{ 64{
61 gnutls_session_t session; 65 gnutls_session_t session;
62 66
63 gnutls_init (&session, GNUTLS_SERVER); 67 gnutls_init (&session, GNUTLS_SERVER);
64 68
65 gnutls_priority_set_direct (session, "NORMAL:+ANON-DH", NULL); 69 /* sets cipher priorities */
70 gnutls_priority_set (session, connection->daemon->priority_cache);
66 71
67 gnutls_credentials_set (session, GNUTLS_CRD_ANON, anoncred); 72 /* set needed credentials for certificate authentication. */
68 73 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE,
69 gnutls_dh_set_prime_bits (session, DH_BITS); 74 connection->daemon->x509_cret);
70 75
71 return session; 76 return session;
72} 77}
73 78
74/* Accept Policy Callback */
75static int 79static int
76TLS_echo (void *cls, 80file_reader (void *cls, size_t pos, char *buf, int max)
77 struct MHD_Connection *connection,
78 const char *url,
79 const char *method,
80 const char *upload_data,
81 const char *version, unsigned int *upload_data_size, void **ptr)
82{ 81{
82 FILE *file = cls;
83
84 fseek (file, pos, SEEK_SET);
85 return fread (buf, 1, max, file);
86}
87
88/* HTTPS access handler call back */
89static int
90https_ahc (void *cls,
91 struct MHD_Connection *connection,
92 const char *url,
93 const char *method,
94 const char *upload_data,
95 const char *version, unsigned int *upload_data_size, void **ptr)
96{
97 /* loopback HTTP socket */
98 int loopback_sd, err;
99 ssize_t ret;
100 struct sockaddr_in servaddr4;
101 const struct sockaddr *servaddr;
102 struct sockaddr_in loopback_sa;
103 socklen_t addrlen;
104
83 gnutls_session_t session; 105 gnutls_session_t session;
84 static int aptr; 106 static int aptr;
85 struct MHD_Response *response; 107 struct MHD_Response *response;
86 char buffer[MAX_BUF + 1]; 108 char buffer[BUF_SIZE];
87 int ret;
88 109
89 printf ("accepted connection from %d\n", connection->addr->sin_addr); 110 printf ("accepted connection from %d\n", connection->addr->sin_addr);
90 111
91 session = initialize_tls_session (); 112 session = initialize_tls_session (connection);
92 113
93 gnutls_transport_set_ptr (session, connection->socket_fd); 114 gnutls_transport_set_ptr (session, connection->socket_fd);
94 115
95 ret = gnutls_handshake (session); 116 ret = gnutls_handshake (session);
117
96 if (ret < 0) 118 if (ret < 0)
97 { 119 {
98 /* set connection as closed */ 120 /* set connection as closed */
@@ -106,77 +128,182 @@ TLS_echo (void *cls,
106 printf ("TLS Handshake completed\n"); 128 printf ("TLS Handshake completed\n");
107 connection->state = MHDS_HANDSHAKE_COMPLETE; 129 connection->state = MHDS_HANDSHAKE_COMPLETE;
108 130
109 /* simple echo loop. message encryption/decryption is acheived through 'gnutls_record_send' 131 /* initialize loopback socket */
110 * & gnutls_record_recv calls. */ 132 loopback_sd = socket (AF_INET, SOCK_STREAM, 0);
133 memset (&loopback_sa, '\0', sizeof (loopback_sa));
134 loopback_sa.sin_family = AF_INET;
135
136 // TODO solve magic number issue - the http's daemons port must be shared with the https daemon - rosolve data sharing point
137 loopback_sa.sin_port = htons (50000);
138 inet_pton (AF_INET, "127.0.0.1", &loopback_sa.sin_addr);
139
140 /* connect loopback socket */
141 err = connect (loopback_sd, (struct sockaddr *) &loopback_sa,
142 sizeof (loopback_sa));
143 if (err < 0)
144 {
145 // TODO err handle
146 fprintf (stderr, "Error : failed to create TLS loopback socket\n");
147 exit (1);
148 }
149
150 /*
151 * This loop pipes data received through the TLS tunnel into the loopback connection.
152 * message encryption/decryption is acheived via 'gnutls_record_send' & gnutls_record_recv calls.
153 */
154 memset (buffer, 0, BUF_SIZE);
155 if (gnutls_record_recv (session, buffer, BUF_SIZE) < 0)
156 {
157 fprintf (stderr, "\n*** Received corrupted "
158 "data(%d). Closing the connection.\n\n", ret);
159 connection->socket_fd = -1;
160 gnutls_deinit (session);
161 return MHD_NO;
162 }
163
164 if (write (loopback_sd, buffer, BUF_SIZE) < 0)
165 {
166 printf ("failed to write to TLS loopback socket\n");
167 connection->socket_fd = -1;
168 gnutls_deinit (session);
169 return MHD_NO;
170 }
171
111 for (;;) 172 for (;;)
112 { 173 {
113 memset (buffer, 0, MAX_BUF + 1); 174 memset (buffer, 0, BUF_SIZE);
114 ret = gnutls_record_recv (session, buffer, MAX_BUF); 175
176 ret = read (loopback_sd, buffer, BUF_SIZE);
115 177
116 if (ret < 0) 178 if (ret < 0)
117 { 179 {
118 fprintf (stderr, "\n*** Received corrupted " 180 printf ("failed to read from TLS loopback socket\n");
119 "data(%d). Closing the connection.\n\n", ret);
120 break; 181 break;
121 } 182 }
122 else if (ret >= 0) 183
184 if (ret == 0)
123 { 185 {
124 if (strcmp (buffer, "exit") == 0) 186 break;
125 {
126 printf ("\n- Peer has closed the GNUTLS connection\n");
127 break;
128 }
129 else
130 {
131 /* echo data back to the client */
132 gnutls_record_send (session, buffer, strlen (buffer));
133 }
134 } 187 }
135 }
136 printf ("\n");
137 188
189 /* echo data back to the client */
190 ret = gnutls_record_send (session, buffer, ret);
191 if (ret < 0)
192 {
193 printf ("failed to write to TLS socket\n");
194 break;
195 }
196 }
138 /* mark connection as closed */ 197 /* mark connection as closed */
139 connection->socket_fd = -1; 198 connection->socket_fd = -1;
140
141 gnutls_deinit (session); 199 gnutls_deinit (session);
142 200
201 return MHD_YES;
202}
203
204/* HTTP access handler call back */
205static int
206http_ahc (void *cls,
207 struct MHD_Connection *connection,
208 const char *url,
209 const char *method,
210 const char *upload_data,
211 const char *version, unsigned int *upload_data_size, void **ptr)
212{
213 static int aptr;
214 static char full_url[MAX_URL_LEN];
215 struct MHD_Response *response;
216 int ret;
217 FILE *file;
218 struct stat buf;
219
220 if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
221 return MHD_NO; /* unexpected method */
222 if (&aptr != *ptr)
223 {
224 /* do never respond on first call */
225 *ptr = &aptr;
226 return MHD_YES;
227 }
228 *ptr = NULL; /* reset when done */
229
230 /* assemble full url */
231 strcpy (full_url, connection->daemon->doc_root);
232 strncat (full_url, url,
233 MAX_URL_LEN - strlen (connection->daemon->doc_root) - 1);
234
235 file = fopen (full_url, "r");
236 if (file == NULL)
237 {
238 response = MHD_create_response_from_data (strlen (PAGE_NOT_FOUND),
239 (void *) PAGE_NOT_FOUND,
240 MHD_NO, MHD_NO);
241 ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
242 MHD_destroy_response (response);
243 }
244 else
245 {
246 stat (&url[1], &buf);
247 response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k PAGE_NOT_FOUND size */
248 &file_reader, file,
249 (MHD_ContentReaderFreeCallback)
250 & fclose);
251 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
252 MHD_destroy_response (response);
253 }
143 return ret; 254 return ret;
144} 255}
145 256
146int 257int
147main (int argc, char *const *argv) 258main (int argc, char *const *argv)
148{ 259{
149 struct MHD_Daemon *daemon; 260 char keyfile[255] = KEYFILE;
261 char certfile[255] = CERTFILE;
262 struct MHD_Daemon *HTTP_daemon;
150 struct MHD_Daemon *TLS_daemon; 263 struct MHD_Daemon *TLS_daemon;
151 264
152 /* look for HTTPS port argument */ 265 /* look for HTTPS arguments */
153 if (argc < 4) 266 if (argc < 5)
154 { 267 {
155 printf ("Usage : %s HTTP-PORT SECONDS-TO-RUN HTTPS-PORT\n", argv[0]); 268 printf
269 ("Usage : %s HTTP-PORT SECONDS-TO-RUN HTTPS-PORT X.509_FILE_PATH\n",
270 argv[0]);
156 return 1; 271 return 1;
157 } 272 }
158 273
159 gnutls_global_init (); 274 // TODO check if this is truly necessary - disallow usage of the blocking /dev/random */
160 275 // gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0);
161 gnutls_anon_allocate_server_credentials (&anoncred);
162 276
163 generate_dh_params (); 277 HTTP_daemon =
278 MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
279 atoi (argv[1]), NULL, NULL, &http_ahc, MHD_OPTION_END);
164 280
165 gnutls_anon_set_server_dh_params (anoncred, dh_params); 281 if (HTTP_daemon == NULL)
282 {
283 printf ("Error: failed to start HTTP_daemon");
284 return 1;
285 }
166 286
167 TLS_daemon = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION 287 TLS_daemon = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG
168 | MHD_USE_DEBUG | MHD_USE_SSL, 288 | MHD_USE_SSL, atoi (argv[3]),
169 atoi (argv[3]), NULL, NULL, &TLS_echo, NULL, 289 NULL,
290 NULL, &https_ahc,
291 NULL, MHD_OPTION_CONNECTION_TIMEOUT, 256,
292 MHD_OPTION_HTTPS_KEY_PATH, argv[4],
293 MHD_OPTION_HTTPS_CERT_PATH, argv[4],
170 MHD_OPTION_END); 294 MHD_OPTION_END);
171 295
172 if (TLS_daemon == NULL) 296 if (TLS_daemon == NULL)
173 return 1; 297 {
298 printf ("Error: failed to start TLS_daemon");
299 return 1;
300 }
301
174 sleep (atoi (argv[2])); 302 sleep (atoi (argv[2]));
175 303
176 MHD_stop_daemon (daemon); 304 MHD_stop_daemon (HTTP_daemon);
177 305
178 gnutls_anon_free_server_credentials (anoncred); 306 MHD_stop_daemon (TLS_daemon);
179 307
180 gnutls_global_deinit ();
181 return 0; 308 return 0;
182} 309}
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 0fd8600a..682b7651 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -345,6 +345,14 @@ enum MHD_OPTION
345 */ 345 */
346 MHD_OPTION_PER_IP_CONNECTION_LIMIT = 5, 346 MHD_OPTION_PER_IP_CONNECTION_LIMIT = 5,
347 347
348 /* server root path used while serving http pages */
349 MHD_OPTION_DOC_ROOT = 6,
350
351 /* private key path used by the HTTPS daemon */
352 MHD_OPTION_HTTPS_KEY_PATH = 7,
353
354 /* certificate path used by the HTTPS daemon */
355 MHD_OPTION_HTTPS_CERT_PATH = 8,
348}; 356};
349 357
350/** 358/**