libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 8a60f9f2fa63377eb8f1b9aac491b610eb78dba4
parent 79afda018af6d860548eda29241ac8cbe43a3b58
Author: lv-426 <oxcafebaby@yahoo.com>
Date:   Wed,  9 Jul 2008 18:33:16 +0000

added KX_PRIORITY option test
added CIPHER_ALGORITHM option test

Diffstat:
MAUTHORS | 1+
Msrc/daemon/connection.c | 4++--
Msrc/daemon/connection_https.c | 18++++++++++++------
Msrc/daemon/daemon.c | 96++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Msrc/daemon/https/openpgp/gnutls_openpgp.c | 17+++++------------
Msrc/daemon/https/tls/gnutls_int.h | 2+-
Msrc/daemon/https/tls/gnutls_state.c | 6+++---
Msrc/daemon/https/tls/pkix_asn1_tab.c | 2+-
Msrc/daemon/internal.c | 2++
Msrc/daemon/internal.h | 1-
Msrc/examples/https_server_example.c | 4++--
Msrc/testcurl/https/mhds_get_test.c | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
Msrc/testcurl/https/mhds_multi_daemon_test.c | 6++++--
Msrc/testcurl/https/mhds_session_info_test.c | 5+++--
14 files changed, 154 insertions(+), 81 deletions(-)

diff --git a/AUTHORS b/AUTHORS @@ -9,6 +9,7 @@ John Popplewell <john@johnnypops.demon.co.uk> Nils Durner <durner@gnunet.org> Heikki Lindholm <holindho@cs.helsinki.fi> Alex Sadovsky <alexeysad@gmail.com> +Sagie Amir Documentation contributions also came from: Marco Maggi <marco.maggi-ipsu@poste.it> diff --git a/src/daemon/connection.c b/src/daemon/connection.c @@ -31,7 +31,7 @@ #include "response.h" #include "reason_phrase.h" -// get opaque type +/* get opaque type */ #include "gnutls_int.h" #ifndef LINUX @@ -1593,7 +1593,7 @@ MHD_connection_handle_write (struct MHD_Connection *connection) connection->state = MHD_CONNECTION_NORMAL_BODY_UNREADY; break; } - // TODO clean - missing MSG_NOSIGNAL on gnutls record send call + /* TODO clean - missing MSG_NOSIGNAL on gnutls record send call */ if (connection->daemon->options & MHD_USE_SSL) { ret = gnutls_record_send (connection->tls_session, diff --git a/src/daemon/connection_https.c b/src/daemon/connection_https.c @@ -36,12 +36,15 @@ /* get opaque type */ #include "gnutls_int.h" +/* TODO rm */ +#include "gnutls_errors.h" + /* forward declarations used when setting secure connection callbacks */ int MHD_connection_handle_read (struct MHD_Connection *connection); int MHD_connection_handle_write (struct MHD_Connection *connection); int MHD_connection_handle_idle (struct MHD_Connection *connection); -// TODO rm - appears in a switch default clause +/* TODO rm - appears in a switch default clause */ static void connection_close_error (struct MHD_Connection *connection) { @@ -106,6 +109,8 @@ int MHDS_connection_handle_idle (struct MHD_Connection *connection) { unsigned int timeout; + + /* TODO rm gnutls_assert (); */ while (1) { #if HAVE_MESSAGES @@ -213,7 +218,7 @@ MHDS_connection_handle_read (struct MHD_Connection *connection) { #if HAVE_MESSAGES MHD_DLOG (connection->daemon, - "Received unrecognized alert: %s\n", + "Received unrecognized alert: %d\n", connection->tls_session->internals.last_alert); #endif return MHD_NO; @@ -236,14 +241,13 @@ MHDS_connection_handle_read (struct MHD_Connection *connection) { #if HAVE_MESSAGES MHD_DLOG (connection->daemon, - "Error: Handshake has failed (%s)\n", ret); + "Error: Handshake has failed (%d)\n", ret); #endif connection->s_state = MHDS_HANDSHAKE_FAILED; gnutls_bye (connection->tls_session, GNUTLS_SHUT_WR); gnutls_deinit (connection->tls_session); - connection->socket_fd = -1; + connection_close_error(connection); return MHD_NO; - } break; case GNUTLS_INNER_APPLICATION: @@ -257,6 +261,8 @@ int MHDS_connection_handle_write (struct MHD_Connection *connection) { connection->last_activity = time (NULL); + /* TODO rm */ + gnutls_assert (); while (1) { #if HAVE_MESSAGES @@ -269,7 +275,7 @@ MHDS_connection_handle_write (struct MHD_Connection *connection) /* these cases shouldn't occur */ case MHDS_HANDSHAKE_COMPLETE: case MHDS_CONNECTION_INIT: - // TODO do we have to write back a responce ? + /* TODO do we have to write back a responce ? */ case MHDS_HANDSHAKE_FAILED: /* we should first exit MHDS_REPLY_SENDING */ diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c @@ -59,24 +59,18 @@ /* initialize security aspects of the HTTPS daemon */ static int MHDS_init (struct MHD_Daemon *daemon){ + + int i; + priority_st st; + gnutls_global_set_log_function (MHD_tls_log_func); - /* TODO let user access log level */ /* setup server certificate */ gnutls_certificate_allocate_credentials (&daemon->x509_cret); - /* Generate Diffie Hellman parameters - for use with DHE kx algorithms. */ - // TODO should we be initializing RSA params or DH params ? - - gnutls_dh_params_init (&daemon->dh_params); - gnutls_dh_params_generate2 (daemon->dh_params, 1024); - - // TODO remove if unused - /* add trusted CAs to certificate */ - // gnutls_certificate_set_x509_trust_file(x509_cret, CAFILE,GNUTLS_X509_FMT_PEM); - - /* add Certificate revocation list to certificate */ - //gnutls_certificate_set_x509_crl_file(x509_cret, CRLFILE, GNUTLS_X509_FMT_PEM); + /* TODO remove if unused + gnutls_certificate_set_x509_trust_file(x509_cret, CAFILE,GNUTLS_X509_FMT_PEM); + gnutls_certificate_set_x509_crl_file(x509_cret, CRLFILE, GNUTLS_X509_FMT_PEM); */ /* sets a certificate private key pair */ if (daemon->https_cert_path && daemon->https_key_path) @@ -129,11 +123,46 @@ MHDS_init (struct MHD_Daemon *daemon){ return MHD_NO; } + /* generate DH parameters if necessary */ + st = daemon->priority_cache->kx; + for (i = 0; i < st.algorithms; i++) + { + /* initialize Diffie Hellman parameters if necessary */ + /* TODO add other cipher suits */ + if (st.priority[i] == GNUTLS_KX_DHE_RSA ){ + gnutls_dh_params_init (&daemon->dh_params); + gnutls_dh_params_generate2 (daemon->dh_params, 1024); + break; + } + } + gnutls_certificate_set_dh_params (daemon->x509_cret, daemon->dh_params); - // TODO address error case return value + /* TODO address error case return value */ return MHD_YES; } + +/* TODO unite with code in gnutls_priority.c */ +/* this is used to set HTTPS related daemon priorities */ +inline static int +_set_priority (priority_st * st, const int *list) +{ + int num = 0, i; + + while (list[num] != 0) + num++; + if (num > MAX_ALGOS) + num = MAX_ALGOS; + st->algorithms = num; + + for (i = 0; i < num; i++) + { + st->priority[i] = list[i]; + } + + return 0; +} + #endif /** @@ -297,9 +326,10 @@ MHDS_handle_connection (void *data) gnutls_credentials_set (tls_session, GNUTLS_CRD_CERTIFICATE, con->daemon->x509_cret); - /* avoid gnutls blocking recv / write calls */ - // gnutls_transport_set_pull_function(tls_session, &recv); - // gnutls_transport_set_push_function(tls_session, &send); + /* TODO avoid gnutls blocking recv / write calls + gnutls_transport_set_pull_function(tls_session, &recv); + gnutls_transport_set_push_function(tls_session, &send); + */ gnutls_transport_set_ptr (tls_session, con->socket_fd); @@ -524,7 +554,7 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon) free (pos->addr); free (pos); daemon->max_connections++; - // TODO add tls con cleanup + /* TODO add tls con cleanup */ if (prev == NULL) pos = daemon->connections; else @@ -722,27 +752,6 @@ MHD_select_thread (void *cls) return NULL; } -/* TODO unite with code in gnutls_priority.c */ -/* this is used to set HTTPS related daemon priorities */ -inline static int -_set_priority (priority_st * st, const int *list) -{ - int num = 0, i; - - while (list[num] != 0) - num++; - if (num > MAX_ALGOS) - num = MAX_ALGOS; - st->algorithms = num; - - for (i = 0; i < num; i++) - { - st->priority[i] = list[i]; - } - - return 0; -} - /** * Start a webserver on the given port. * @@ -861,6 +870,7 @@ MHD_start_daemon (unsigned int options, pthread_mutex_lock (&gnutls_init_mutex); gnutls_global_init (); pthread_mutex_unlock (&gnutls_init_mutex); + /* set default priorities */ gnutls_priority_init (&retVal->priority_cache, "NONE:+AES-256-CBC:+RSA:+SHA1:+COMP-NULL", NULL); } @@ -891,6 +901,7 @@ MHD_start_daemon (unsigned int options, case MHD_OPTION_PER_IP_CONNECTION_LIMIT: retVal->per_ip_connection_limit = va_arg (ap, unsigned int); break; +#if HTTPS_SUPPORT case MHD_OPTION_HTTPS_KEY_PATH: retVal->https_key_path = va_arg (ap, const char *); break; @@ -904,13 +915,12 @@ MHD_start_daemon (unsigned int options, retVal->https_mem_cert = va_arg (ap, const char *); break; case MHDS_KX_PRIORITY: - _set_priority (&retVal->priority_cache->kx, - va_arg (ap, const int *)); + _set_priority (&retVal->priority_cache->cipher, va_arg (ap, const int *)); break; case MHDS_CIPHER_ALGORITHM: - _set_priority (&retVal->priority_cache->cipher, - va_arg (ap, const int *)); + _set_priority (&retVal->priority_cache->cipher, va_arg (ap, const int *)); break; +#endif default: #if HAVE_MESSAGES if (opt > MHD_HTTPS_OPTION_START && opt < MHD_HTTPS_OPTION_END) { diff --git a/src/daemon/https/openpgp/gnutls_openpgp.c b/src/daemon/https/openpgp/gnutls_openpgp.c @@ -9,12 +9,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * GNUTLS-EXTRA is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -38,8 +38,6 @@ #define datum_append(x, y, z) _gnutls_datum_append_m (x, y, z, gnutls_realloc) - - static void release_mpi_array (mpi_t * arr, size_t n) { @@ -256,7 +254,6 @@ leave: return rc; } - /*- * _gnutls_openpgp_raw_key_to_gcert - Converts raw OpenPGP data to GnuTLS certs * @cert: the certificate to store the data. @@ -306,7 +303,7 @@ _gnutls_openpgp_raw_key_to_gcert (gnutls_cert * cert, * @key: contains an openpgp public key * @pkey: is an openpgp private key * - * This function sets a certificate/private key pair in the + * This function sets a certificate/private key pair in the * gnutls_certificate_credentials_t structure. This function may be called * more than once (in case multiple keys/certificates exist for the * server). @@ -486,7 +483,7 @@ stream_to_datum (cdk_stream_t inp, gnutls_datum_t * raw) * @cert: the datum that contains the public key. * @key: the datum that contains the secret key. * - * This funtion is used to load OpenPGP keys into the GnuTLS credential + * This funtion is used to load OpenPGP keys into the GnuTLS credential * structure. * It doesn't matter whether the keys are armored or not, but the files * should only contain one key which should not be encrypted. @@ -734,12 +731,8 @@ gnutls_certificate_set_openpgp_keyring_mem (gnutls_certificate_credentials_t gnutls_openpgp_keyring_deinit (c->keyring); return rc; } - - return 0; #else - c->keyring_format = format; - c->keyring.data = gnutls_malloc (dlen + 1); if (c->keyring.data == NULL) { @@ -749,8 +742,8 @@ gnutls_certificate_set_openpgp_keyring_mem (gnutls_certificate_credentials_t memcpy (c->keyring.data, data, dlen); c->keyring.data[dlen] = 0; c->keyring.size = dlen; - #endif + return 0; } /*- diff --git a/src/daemon/https/tls/gnutls_int.h b/src/daemon/https/tls/gnutls_int.h @@ -99,7 +99,7 @@ #define HASH2MAC(x) ((gnutls_mac_algorithm_t)x) -// TODO rm +/* TODO rm */ /* Additional cast to bring void* to a type castable to int. */ #define GNUTLS_POINTER_TO_INT_CAST (long) diff --git a/src/daemon/https/tls/gnutls_state.c b/src/daemon/https/tls/gnutls_state.c @@ -233,7 +233,7 @@ _gnutls_handshake_internal_state_clear (gnutls_session_t session) * Returns: %GNUTLS_E_SUCCESS on success, or an error code. **/ -// TODO rm redundent pointer ref +/* TODO rm redundent pointer ref */ int gnutls_init (gnutls_session_t * session, gnutls_connection_end_t con_end) { @@ -290,7 +290,7 @@ gnutls_init (gnutls_session_t * session, gnutls_connection_end_t con_end) gnutls_handshake_set_max_packet_length ((*session), MAX_HANDSHAKE_PACKET_SIZE); - /* Allocate a minimum size for recv_data + /* Allocate a minimum size for recv_data * This is allocated in order to avoid small messages, making * the receive procedure slow. */ @@ -796,7 +796,7 @@ _gnutls_xor (opaque * o1, opaque * o2, int length) #define MAX_PRF_BYTES 200 -/* The PRF function expands a given secret +/* The PRF function expands a given secret * needed by the TLS specification. ret must have a least total_bytes * available. */ diff --git a/src/daemon/https/tls/pkix_asn1_tab.c b/src/daemon/https/tls/pkix_asn1_tab.c @@ -4,7 +4,7 @@ #include <libtasn1.h> -extern const ASN1_ARRAY_TYPE pkix_asn1_tab[] = { +const ASN1_ARRAY_TYPE pkix_asn1_tab[] = { {"PKIX1", 536875024, 0}, {0, 1073741836, 0}, {"id-ce", 1879048204, 0}, diff --git a/src/daemon/internal.c b/src/daemon/internal.c @@ -46,7 +46,9 @@ MHD_DLOG (const struct MHD_Daemon *daemon, const char *format, ...) void MHD_tls_log_func (int level, const char *str) { +#ifdef DEBUG fprintf (stdout, "|<%d>| %s", level, str); +#endif } diff --git a/src/daemon/internal.h b/src/daemon/internal.h @@ -49,7 +49,6 @@ #include <pthread.h> -// TODO unify with other dec #define MHD_MAX(a,b) ((a)<(b)) ? (b) : (a) #define MHD_MIN(a,b) ((a)<(b)) ? (a) : (b) diff --git a/src/examples/https_server_example.c b/src/examples/https_server_example.c @@ -172,8 +172,8 @@ main (int argc, char *const *argv) return 1; } - // TODO check if this is truly necessary - disallow usage of the blocking /dev/random */ - // gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0); + /* TODO check if this is truly necessary - disallow usage of the blocking /dev/random */ + /* gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0); */ TLS_daemon = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG | MHD_USE_SSL, atoi (argv[3]), diff --git a/src/testcurl/https/mhds_get_test.c b/src/testcurl/https/mhds_get_test.c @@ -26,7 +26,7 @@ #include "config.h" #include "plibc.h" -#include "microhttpd.h" +#include "microhttpsd.h" #include <errno.h> #include <curl/curl.h> @@ -218,7 +218,9 @@ test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version) doc_path, test_file_name); c = curl_easy_init (); - /* curl_easy_setopt (c, CURLOPT_VERBOSE, 1); */ +#ifdef DEBUG + curl_easy_setopt (c, CURLOPT_VERBOSE, 1); +#endif curl_easy_setopt (c, CURLOPT_URL, url); curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); curl_easy_setopt (c, CURLOPT_TIMEOUT, 10L); @@ -228,9 +230,9 @@ test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version) /* TLS options */ curl_easy_setopt (c, CURLOPT_SSLVERSION, proto_version); - curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, cipher_suite); + //curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, cipher_suite); - // TODO rm : currently skip any peer authentication */ + /* currently skip any peer authentication */ curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0); @@ -332,6 +334,59 @@ test_file_certificates (FILE * test_fd, char *cipher_suite, int proto_version) return ret; } +int +test_cipher_option (FILE * test_fd, char *cipher_suite, int proto_version) +{ + + int ret; + int ciper[] = { GNUTLS_CIPHER_3DES_CBC, 0 }; + struct MHD_Daemon *d; + d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL | + MHD_USE_DEBUG, 42433, + NULL, NULL, &http_ahc, NULL, + MHD_OPTION_HTTPS_MEM_KEY, key_pem, + MHD_OPTION_HTTPS_MEM_CERT, cert_pem, + MHDS_CIPHER_ALGORITHM, ciper, MHD_OPTION_END); + + if (d == NULL) + { + fprintf (stderr, MHD_E_SERVER_INIT); + return -1; + } + + ret = test_daemon_get (test_fd, cipher_suite, proto_version); + + MHD_stop_daemon (d); + return ret; +} + +int +test_kx_option (FILE * test_fd, char *cipher_suite, int proto_version) +{ + + int ret; + int kx[] = { GNUTLS_KX_DHE_RSA, 0 }; + struct MHD_Daemon *d; + + d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL | + MHD_USE_DEBUG, 42433, + NULL, NULL, &http_ahc, NULL, + MHD_OPTION_HTTPS_MEM_KEY, key_pem, + MHD_OPTION_HTTPS_MEM_CERT, cert_pem, + MHDS_KX_PRIORITY, kx, MHD_OPTION_END); + + if (d == NULL) + { + fprintf (stderr, MHD_E_SERVER_INIT); + return -1; + } + + ret = test_daemon_get (test_fd, cipher_suite, proto_version); + + MHD_stop_daemon (d); + return ret; +} + /* setup a temporary transfer test file */ FILE * setupTestFile () @@ -367,8 +422,6 @@ main (int argc, char *const *argv) FILE *test_fd; unsigned int errorCount = 0; - gnutls_global_set_log_level (0); - if ((test_fd = setupTestFile ()) == NULL) { fprintf (stderr, MHD_E_TEST_FILE_CREAT); @@ -388,6 +441,12 @@ main (int argc, char *const *argv) errorCount += test_file_certificates (test_fd, "AES256-SHA", CURL_SSLVERSION_TLSv1); + /* TODO resolve cipher setting issue when compiling against GNU TLS */ + errorCount += + test_cipher_option (test_fd, "DES-CBC3-SHA", CURL_SSLVERSION_SSLv3); + errorCount += + test_kx_option (test_fd, "EDH-RSA-DES-CBC3-SHA", CURL_SSLVERSION_SSLv3); + if (errorCount != 0) fprintf (stderr, "Error (code: %u)\n", errorCount); diff --git a/src/testcurl/https/mhds_multi_daemon_test.c b/src/testcurl/https/mhds_multi_daemon_test.c @@ -216,7 +216,9 @@ test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version, test_file_name); c = curl_easy_init (); - /* curl_easy_setopt (c, CURLOPT_VERBOSE, 1); */ +#ifdef DEBUG + curl_easy_setopt (c, CURLOPT_VERBOSE, 1); +#endif curl_easy_setopt (c, CURLOPT_URL, url); curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); curl_easy_setopt (c, CURLOPT_TIMEOUT, 10L); @@ -228,7 +230,7 @@ test_daemon_get (FILE * test_fd, char *cipher_suite, int proto_version, curl_easy_setopt (c, CURLOPT_SSLVERSION, proto_version); curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, cipher_suite); - // TODO rm : currently skip any peer authentication */ + /* currently skip any peer authentication */ curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 0); diff --git a/src/testcurl/https/mhds_session_info_test.c b/src/testcurl/https/mhds_session_info_test.c @@ -128,7 +128,6 @@ query_session_ahc (void *cls, struct MHD_Connection *connection, return -1; } - // TODO should these be hard coded into the server ? if (MHDS_get_session_mac (connection) != GNUTLS_MAC_SHA1) { fprintf (stderr, "Error: requested mac algorithm mismatch. %s\n", @@ -184,7 +183,9 @@ test_query_session () return 2; c = curl_easy_init (); - //curl_easy_setopt (c, CURLOPT_VERBOSE, 1); +#ifdef DEBUG + curl_easy_setopt (c, CURLOPT_VERBOSE, 1); +#endif curl_easy_setopt (c, CURLOPT_URL, url); curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_easy_setopt (c, CURLOPT_TIMEOUT, 10L);