aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/daemon.c')
-rw-r--r--src/daemon/daemon.c202
1 files changed, 115 insertions, 87 deletions
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c
index 7911be33..34a94922 100644
--- a/src/daemon/daemon.c
+++ b/src/daemon/daemon.c
@@ -60,7 +60,65 @@
60#define DEBUG_CONNECT MHD_NO 60#define DEBUG_CONNECT MHD_NO
61 61
62#if HTTPS_SUPPORT 62#if HTTPS_SUPPORT
63/* TODO unite with code in gnutls_priority.c */ 63/**
64 * Note: code duplication with code in gnutls_priority.c
65 *
66 * @return 0
67 */
68static int
69_set_priority (mhd_gtls_priority_st * st, const int *list)
70{
71 int num = 0;
72
73 while ( (list[num] != 0) &&
74 (num < MAX_ALGOS) )
75 num++;
76 st->num_algorithms = num;
77 memcpy(st->priority, list, num * sizeof(int));
78 return 0;
79}
80
81
82/**
83 * Callback for receiving data from the socket.
84 *
85 * @param conn the MHD connection structure
86 * @param other where to write received data to
87 * @param i maximum size of other (in bytes)
88 * @return number of bytes actually received
89 */
90static ssize_t
91recv_tls_adapter (struct MHD_Connection* connection,
92 void *other,
93 size_t i)
94{
95 return MHD_gnutls_record_recv(connection->tls_session,
96 other, i);
97}
98
99/**
100 * Callback for writing data to the socket.
101 *
102 * @param conn the MHD connection structure
103 * @param other data to write
104 * @param i number of bytes to write
105 * @return actual number of bytes written
106 */
107static ssize_t
108send_tls_adapter (struct MHD_Connection* connection,
109 const void *other,
110 size_t i)
111{
112 return MHD_gnutls_record_send(connection->tls_session,
113 other, i);
114}
115
116
117/**
118 * Read and setup our certificate and key.
119 *
120 * @return 0 on success
121 */
64static int 122static int
65MHD_init_daemon_certificate (struct MHD_Daemon *daemon) 123MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
66{ 124{
@@ -132,27 +190,25 @@ MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
132} 190}
133 191
134/** 192/**
135 * initialize security aspects of the HTTPS daemon 193 * Initialize security aspects of the HTTPS daemon
194 *
195 * @return 0 on success
136 */ 196 */
137static int 197static int
138MHD_TLS_init (struct MHD_Daemon *daemon) 198MHD_TLS_init (struct MHD_Daemon *daemon)
139{ 199{
140 int ret;
141
142 switch (daemon->cred_type) 200 switch (daemon->cred_type)
143 { 201 {
144 case MHD_GNUTLS_CRD_ANON: 202 case MHD_GNUTLS_CRD_ANON:
145 ret = MHD_gnutls_anon_allocate_server_credentials (&daemon->anon_cred); 203 if ( (0 != MHD_gnutls_anon_allocate_server_credentials (&daemon->anon_cred)) ||
146 ret |= MHD_gnutls_dh_params_init (&daemon->dh_params); 204 (0 != MHD_gnutls_dh_params_init (&daemon->dh_params)) )
147 if (ret != 0)
148 return GNUTLS_E_MEMORY_ERROR; 205 return GNUTLS_E_MEMORY_ERROR;
149 MHD_gnutls_dh_params_generate2 (daemon->dh_params, 1024); 206 MHD_gnutls_dh_params_generate2 (daemon->dh_params, 1024);
150 MHD_gnutls_anon_set_server_dh_params (daemon->anon_cred, 207 MHD_gnutls_anon_set_server_dh_params (daemon->anon_cred,
151 daemon->dh_params); 208 daemon->dh_params);
152 return 0; 209 return 0;
153 case MHD_GNUTLS_CRD_CERTIFICATE: 210 case MHD_GNUTLS_CRD_CERTIFICATE:
154 ret = MHD_gnutls_certificate_allocate_credentials (&daemon->x509_cred); 211 if (0 != MHD_gnutls_certificate_allocate_credentials (&daemon->x509_cred))
155 if (ret != 0)
156 return GNUTLS_E_MEMORY_ERROR; 212 return GNUTLS_E_MEMORY_ERROR;
157 return MHD_init_daemon_certificate (daemon); 213 return MHD_init_daemon_certificate (daemon);
158 default: 214 default:
@@ -164,19 +220,6 @@ MHD_TLS_init (struct MHD_Daemon *daemon)
164 return -1; 220 return -1;
165 } 221 }
166} 222}
167
168static int
169_set_priority (mhd_gtls_priority_st * st, const int *list)
170{
171 int num = 0;
172
173 while ( (list[num] != 0) &&
174 (num < MAX_ALGOS) )
175 num++;
176 st->num_algorithms = num;
177 memcpy(st->priority, list, num * sizeof(int));
178 return 0;
179}
180#endif 223#endif
181 224
182/** 225/**
@@ -292,9 +335,8 @@ MHD_handle_connection (void *data)
292 return NULL; 335 return NULL;
293} 336}
294 337
295#if HTTPS_SUPPORT
296/** 338/**
297 * Callback for receiving data from the socket (for gnutls). 339 * Callback for receiving data from the socket.
298 * 340 *
299 * @param conn the MHD connection structure 341 * @param conn the MHD connection structure
300 * @param other where to write received data to 342 * @param other where to write received data to
@@ -302,19 +344,17 @@ MHD_handle_connection (void *data)
302 * @return number of bytes actually received 344 * @return number of bytes actually received
303 */ 345 */
304static ssize_t 346static ssize_t
305pull_param_adapter (gnutls_transport_ptr_t conn, 347recv_param_adapter (struct MHD_Connection * connection,
306 void *other, 348 void *other,
307 size_t i) 349 size_t i)
308{ 350{
309 struct MHD_Connection * connection = (struct MHD_Connection*) conn;
310
311 if (connection->socket_fd == -1) 351 if (connection->socket_fd == -1)
312 return -1; 352 return -1;
313 return RECV(connection->socket_fd, other, i, MSG_NOSIGNAL); 353 return RECV(connection->socket_fd, other, i, MSG_NOSIGNAL);
314} 354}
315 355
316/** 356/**
317 * Callback for writing data to the socket (for gnutls). 357 * Callback for writing data to the socket.
318 * 358 *
319 * @param conn the MHD connection structure 359 * @param conn the MHD connection structure
320 * @param other data to write 360 * @param other data to write
@@ -322,61 +362,16 @@ pull_param_adapter (gnutls_transport_ptr_t conn,
322 * @return actual number of bytes written 362 * @return actual number of bytes written
323 */ 363 */
324static ssize_t 364static ssize_t
325push_param_adapter (void *conn, 365send_param_adapter (struct MHD_Connection *connection,
326 const void *other, 366 const void *other,
327 size_t i) 367 size_t i)
328{ 368{
329 struct MHD_Connection * connection = (struct MHD_Connection*) conn;
330
331 if (connection->socket_fd == -1) 369 if (connection->socket_fd == -1)
332 return -1; 370 return -1;
333 return SEND(connection->socket_fd, other, i, MSG_NOSIGNAL); 371 return SEND(connection->socket_fd, other, i, MSG_NOSIGNAL);
334} 372}
335 373
336/** 374/**
337 * Handle an individual TLS connection (main function
338 * of the thread handling a TLS connection).
339 */
340static void *
341MHD_TLS_init_connection (void *data)
342{
343 struct MHD_Connection *con = data;
344
345 EXTRA_CHECK (con->state == MHD_CONNECTION_INIT);
346 con->state = MHD_TLS_CONNECTION_INIT;
347 MHD_gnutls_init (&con->tls_session, GNUTLS_SERVER);
348 MHD_gnutls_priority_set (con->tls_session, con->daemon->priority_cache);
349 switch (con->daemon->cred_type)
350 {
351 /* set needed credentials for certificate authentication. */
352 case MHD_GNUTLS_CRD_CERTIFICATE:
353 MHD_gnutls_credentials_set (con->tls_session,
354 MHD_GNUTLS_CRD_CERTIFICATE,
355 con->daemon->x509_cred);
356 break;
357 case MHD_GNUTLS_CRD_ANON:
358 /* set needed credentials for anonymous authentication. */
359 MHD_gnutls_credentials_set (con->tls_session, MHD_GNUTLS_CRD_ANON,
360 con->daemon->anon_cred);
361 MHD_gnutls_dh_set_prime_bits (con->tls_session, 1024);
362 break;
363 default:
364#if HAVE_MESSAGES
365 MHD_DLOG (con->daemon,
366 "Failed to setup TLS credentials: unknown credential type %d\n",
367 con->daemon->cred_type);
368#endif
369 abort();
370 }
371 MHD_gnutls_transport_set_ptr (con->tls_session,
372 (gnutls_transport_ptr_t) con);
373 MHD_gnutls_transport_set_pull_function(con->tls_session, &pull_param_adapter);
374 MHD_gnutls_transport_set_push_function(con->tls_session, &push_param_adapter);
375 return MHD_handle_connection (data);
376}
377#endif
378
379/**
380 * Accept an incoming connection and create the MHD_Connection object for 375 * Accept an incoming connection and create the MHD_Connection object for
381 * it. This function also enforces policy by way of checking with the 376 * it. This function also enforces policy by way of checking with the
382 * accept policy callback. 377 * accept policy callback.
@@ -519,19 +514,52 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
519 514
520 /* set default connection handlers */ 515 /* set default connection handlers */
521 MHD_set_http_calbacks (connection); 516 MHD_set_http_calbacks (connection);
517 connection->recv_cls = &recv_param_adapter;
518 connection->send_cls = &send_param_adapter;
522#if HTTPS_SUPPORT 519#if HTTPS_SUPPORT
523 if (0 != (daemon->options & MHD_USE_SSL)) 520 if (0 != (daemon->options & MHD_USE_SSL))
524 MHD_set_https_calbacks (connection); 521 {
522 connection->recv_cls = &recv_tls_adapter;
523 connection->send_cls = &send_tls_adapter;
524 connection->state = MHD_TLS_CONNECTION_INIT;
525 MHD_set_https_calbacks (connection);
526 MHD_gnutls_init (&connection->tls_session, GNUTLS_SERVER);
527 MHD_gnutls_priority_set (connection->tls_session, connection->daemon->priority_cache);
528 switch (connection->daemon->cred_type)
529 {
530 /* set needed credentials for certificate authentication. */
531 case MHD_GNUTLS_CRD_CERTIFICATE:
532 MHD_gnutls_credentials_set (connection->tls_session,
533 MHD_GNUTLS_CRD_CERTIFICATE,
534 connection->daemon->x509_cred);
535 break;
536 case MHD_GNUTLS_CRD_ANON:
537 /* set needed credentials for anonymous authentication. */
538 MHD_gnutls_credentials_set (connection->tls_session, MHD_GNUTLS_CRD_ANON,
539 connection->daemon->anon_cred);
540 MHD_gnutls_dh_set_prime_bits (connection->tls_session, 1024);
541 break;
542 default:
543#if HAVE_MESSAGES
544 MHD_DLOG (connection->daemon,
545 "Failed to setup TLS credentials: unknown credential type %d\n",
546 connection->daemon->cred_type);
547#endif
548 abort();
549 }
550 MHD_gnutls_transport_set_ptr (connection->tls_session,
551 (gnutls_transport_ptr_t) connection);
552 MHD_gnutls_transport_set_pull_function(connection->tls_session,
553 (mhd_gtls_pull_func) &recv_param_adapter);
554 MHD_gnutls_transport_set_push_function(connection->tls_session,
555 (mhd_gtls_push_func) &send_param_adapter);
556 }
525#endif 557#endif
526 558
527 /* attempt to create handler thread */ 559 /* attempt to create handler thread */
528 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) 560 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
529 { 561 {
530 res_thread_create = pthread_create (&connection->pid, NULL, 562 res_thread_create = pthread_create (&connection->pid, NULL,
531#if HTTPS_SUPPORT
532 (0 != (daemon->options & MHD_USE_SSL)) ?
533 &MHD_TLS_init_connection :
534#endif
535 &MHD_handle_connection, 563 &MHD_handle_connection,
536 connection); 564 connection);
537 if (res_thread_create != 0) 565 if (res_thread_create != 0)
@@ -855,7 +883,6 @@ MHD_start_daemon_va (unsigned int options,
855 retVal->max_connections = MHD_MAX_CONNECTIONS_DEFAULT; 883 retVal->max_connections = MHD_MAX_CONNECTIONS_DEFAULT;
856 retVal->pool_size = MHD_POOL_SIZE_DEFAULT; 884 retVal->pool_size = MHD_POOL_SIZE_DEFAULT;
857 retVal->connection_timeout = 0; /* no timeout */ 885 retVal->connection_timeout = 0; /* no timeout */
858
859#if HTTPS_SUPPORT 886#if HTTPS_SUPPORT
860 if (options & MHD_USE_SSL) 887 if (options & MHD_USE_SSL)
861 { 888 {
@@ -931,13 +958,13 @@ MHD_start_daemon_va (unsigned int options,
931 if ((opt >= MHD_OPTION_HTTPS_KEY_PATH) && 958 if ((opt >= MHD_OPTION_HTTPS_KEY_PATH) &&
932 (opt <= MHD_OPTION_TLS_COMP_ALGO)) 959 (opt <= MHD_OPTION_TLS_COMP_ALGO))
933 { 960 {
934 fprintf (stderr, 961 FPRINTF (stderr,
935 "MHD HTTPS option %d passed to MHD compiled without HTTPS support\n", 962 "MHD HTTPS option %d passed to MHD compiled without HTTPS support\n",
936 opt); 963 opt);
937 } 964 }
938 else 965 else
939 { 966 {
940 fprintf (stderr, 967 FPRINTF (stderr,
941 "Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n", 968 "Invalid option %d! (Did you terminate the list with MHD_OPTION_END?)\n",
942 opt); 969 opt);
943 } 970 }
@@ -954,7 +981,7 @@ MHD_start_daemon_va (unsigned int options,
954 { 981 {
955#if HAVE_MESSAGES 982#if HAVE_MESSAGES
956 if ((options & MHD_USE_DEBUG) != 0) 983 if ((options & MHD_USE_DEBUG) != 0)
957 fprintf (stderr, "Call to socket failed: %s\n", STRERROR (errno)); 984 FPRINTF (stderr, "Call to socket failed: %s\n", STRERROR (errno));
958#endif 985#endif
959 free (retVal); 986 free (retVal);
960 return NULL; 987 return NULL;
@@ -965,7 +992,7 @@ MHD_start_daemon_va (unsigned int options,
965 &on, sizeof (on)) < 0) && (options & MHD_USE_DEBUG) != 0) 992 &on, sizeof (on)) < 0) && (options & MHD_USE_DEBUG) != 0)
966 { 993 {
967#if HAVE_MESSAGES 994#if HAVE_MESSAGES
968 fprintf (stderr, "setsockopt failed: %s\n", STRERROR (errno)); 995 FPRINTF (stderr, "setsockopt failed: %s\n", STRERROR (errno));
969#endif 996#endif
970 } 997 }
971 998
@@ -996,7 +1023,7 @@ MHD_start_daemon_va (unsigned int options,
996 { 1023 {
997#if HAVE_MESSAGES 1024#if HAVE_MESSAGES
998 if ((options & MHD_USE_DEBUG) != 0) 1025 if ((options & MHD_USE_DEBUG) != 0)
999 fprintf (stderr, 1026 FPRINTF (stderr,
1000 "Failed to bind to port %u: %s\n", port, STRERROR (errno)); 1027 "Failed to bind to port %u: %s\n", port, STRERROR (errno));
1001#endif 1028#endif
1002 CLOSE (socket_fd); 1029 CLOSE (socket_fd);
@@ -1009,7 +1036,7 @@ MHD_start_daemon_va (unsigned int options,
1009 { 1036 {
1010#if HAVE_MESSAGES 1037#if HAVE_MESSAGES
1011 if ((options & MHD_USE_DEBUG) != 0) 1038 if ((options & MHD_USE_DEBUG) != 0)
1012 fprintf (stderr, 1039 FPRINTF (stderr,
1013 "Failed to listen for connections: %s\n", STRERROR (errno)); 1040 "Failed to listen for connections: %s\n", STRERROR (errno));
1014#endif 1041#endif
1015 CLOSE (socket_fd); 1042 CLOSE (socket_fd);
@@ -1019,7 +1046,8 @@ MHD_start_daemon_va (unsigned int options,
1019 1046
1020#if HTTPS_SUPPORT 1047#if HTTPS_SUPPORT
1021 /* initialize HTTPS daemon certificate aspects & send / recv functions */ 1048 /* initialize HTTPS daemon certificate aspects & send / recv functions */
1022 if ((options & MHD_USE_SSL) && MHD_TLS_init (retVal)) 1049 if ( (0 != (options & MHD_USE_SSL)) &&
1050 (0 != MHD_TLS_init (retVal)) )
1023 { 1051 {
1024#if HAVE_MESSAGES 1052#if HAVE_MESSAGES
1025 MHD_DLOG (retVal, "Failed to initialize TLS support\n"); 1053 MHD_DLOG (retVal, "Failed to initialize TLS support\n");