commit 04c37e5bd7a82f60127b64338cf37c470ca93e12 parent 1cd7c174797f65098c6c3048564634cbe6c3bb9f Author: lv-426 <oxcafebaby@yahoo.com> Date: Fri, 18 Jul 2008 03:53:27 +0000 fixed some memory leaks removed includes dir Diffstat:
23 files changed, 415 insertions(+), 936 deletions(-)
diff --git a/configure.ac b/configure.ac @@ -277,7 +277,6 @@ src/daemon/https/lgl/Makefile src/daemon/https/openpgp/Makefile src/daemon/https/opencdk/Makefile src/daemon/https/minitasn1/Makefile -src/daemon/https/includes/Makefile src/examples/Makefile src/testcurl/Makefile src/testcurl/https/Makefile diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am @@ -6,7 +6,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/daemon/https/openpgp \ -I$(top_srcdir)/src/daemon/https/opencdk \ -I$(top_srcdir)/src/daemon/https/tls \ --I$(top_srcdir)/src/daemon/https/includes \ +-I$(top_srcdir)/src/daemon/https \ -I$(top_srcdir)/src/daemon/https/cfg \ -I$(GCRYPT_CPPFLAGS) diff --git a/src/daemon/connection_https.c b/src/daemon/connection_https.c @@ -71,24 +71,37 @@ MHD_tls_connection_close_err (struct MHD_Connection *connection) } union MHD_SessionInfo -MHD_get_session_info (struct MHD_Connection *con, enum MHD_InfoType infoType) +MHD_get_tls_session_info (struct MHD_Connection *con, + enum MHD_InfoType infoType) { + /* return NULL if this isn't a SSL/TLS type connection */ + if (con->tls_session == NULL) + { + /* TODO clean */ + return (union MHD_SessionInfo) 0; + } switch (infoType) { case MHS_INFO_CIPHER_ALGO: - return (union MHD_SessionInfo) con->tls_session->security_parameters.read_bulk_cipher_algorithm; + return (union MHD_SessionInfo) con->tls_session->security_parameters. + read_bulk_cipher_algorithm; case MHD_INFO_KX_ALGO: - return (union MHD_SessionInfo) con->tls_session->security_parameters.kx_algorithm; + return (union MHD_SessionInfo) con->tls_session->security_parameters. + kx_algorithm; case MHD_INFO_CREDENTIALS_TYPE: return (union MHD_SessionInfo) con->tls_session->key->cred->algorithm; case MHD_INFO_MAC_ALGO: - return (union MHD_SessionInfo) con->tls_session->security_parameters.read_mac_algorithm; + return (union MHD_SessionInfo) con->tls_session->security_parameters. + read_mac_algorithm; case MHD_INFO_COMPRESSION_METHOD: - return (union MHD_SessionInfo) con->tls_session->security_parameters.read_compression_algorithm; + return (union MHD_SessionInfo) con->tls_session->security_parameters. + read_compression_algorithm; case MHD_INFO_PROTOCOL: - return (union MHD_SessionInfo) con->tls_session->security_parameters.version; + return (union MHD_SessionInfo) con->tls_session->security_parameters. + version; case MHD_INFO_CERT_TYPE: - return (union MHD_SessionInfo) con->tls_session->security_parameters.cert_type; + return (union MHD_SessionInfo) con->tls_session->security_parameters. + cert_type; }; } @@ -280,24 +293,21 @@ MHD_tls_connection_handle_write (struct MHD_Connection *connection) { connection->last_activity = time (NULL); - while (1) - { #if HAVE_MESSAGES - MHD_DLOG (connection->daemon, "MHD write: %d. f: %s, l: %d\n", - connection->state, __FUNCTION__, __LINE__); + MHD_DLOG (connection->daemon, "MHD write: %d. f: %s, l: %d\n", + connection->state, __FUNCTION__, __LINE__); #endif - switch (connection->state) - { - case MHD_CONNECTION_CLOSED: - MHD_tls_connection_close (connection); - return MHD_NO; - case MHD_TLS_HANDSHAKE_FAILED: - MHD_tls_connection_close (connection); - return MHD_NO; - /* some HTTP state */ - default: - return MHD_connection_handle_write (connection); - } + switch (connection->state) + { + case MHD_CONNECTION_CLOSED: + MHD_tls_connection_close (connection); + return MHD_NO; + case MHD_TLS_HANDSHAKE_FAILED: + MHD_tls_connection_close (connection); + return MHD_NO; + /* some HTTP state */ + default: + return MHD_connection_handle_write (connection); } } diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c @@ -29,10 +29,11 @@ #include "connection.h" #include "memorypool.h" +#if HTTPS_SUPPORT #include "gnutls.h" #include "gnutls_int.h" -#include "gnutls_datum.h" #include "gnutls_global.h" +#endif /** * Default connection limit. @@ -59,86 +60,86 @@ #if HTTPS_SUPPORT /* 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); - - /* setup server certificate */ - gnutls_certificate_allocate_credentials (&daemon->x509_cret); - - /* 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) - { - /* test for private key & certificate file exsitance */ - if (access (daemon->https_cert_path, R_OK)) - { - #if HAVE_MESSAGES - MHD_DLOG (daemon, "Missing X.509 certificate file\n"); - #endif - free (daemon); - CLOSE (daemon->socket_fd); - return -1; - } - - if (access (daemon->https_key_path, R_OK)) - { - #if HAVE_MESSAGES - MHD_DLOG (daemon, "Missing X.509 key file\n"); - #endif - free (daemon); - CLOSE (daemon->socket_fd); - return -1; - } - gnutls_certificate_set_x509_key_file (daemon->x509_cret, - daemon->https_cert_path, - daemon->https_key_path, - GNUTLS_X509_FMT_PEM); - } - else if (daemon->https_mem_cert && daemon->https_mem_key) - { - gnutls_datum_t key ; - gnutls_datum_t cert ; - - _gnutls_set_datum_m (&key, daemon->https_mem_key, - strlen (daemon->https_mem_key), &malloc); - _gnutls_set_datum_m (&cert, daemon->https_mem_cert, - strlen (daemon->https_mem_cert), &malloc); - - gnutls_certificate_set_x509_key_mem (daemon->x509_cret, &cert, &key, - GNUTLS_X509_FMT_PEM); - } - else - { - #if HAVE_MESSAGES - MHD_DLOG (daemon, "Failed to load certificate\n"); - #endif - return MHD_NO; - } +MHDS_init (struct MHD_Daemon *daemon) +{ + int i; + priority_st st; + gnutls_datum_t key; + gnutls_datum_t cert; + + gnutls_global_set_log_function (MHD_tls_log_func); + + /* setup server certificate */ + gnutls_certificate_allocate_credentials (&daemon->x509_cret); - /* generate DH parameters if necessary */ - st = daemon->priority_cache->kx; - for (i = 0; i < st.algorithms; i++) + /* 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) + { + /* test for private key & certificate file exsitance */ + if (access (daemon->https_cert_path, R_OK)) { - /* 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; - } +#if HAVE_MESSAGES + MHD_DLOG (daemon, "Missing X.509 certificate file\n"); +#endif + free (daemon); + CLOSE (daemon->socket_fd); + return -1; } - gnutls_certificate_set_dh_params (daemon->x509_cret, daemon->dh_params); + if (access (daemon->https_key_path, R_OK)) + { +#if HAVE_MESSAGES + MHD_DLOG (daemon, "Missing X.509 key file\n"); +#endif + free (daemon); + CLOSE (daemon->socket_fd); + return -1; + } + gnutls_certificate_set_x509_key_file (daemon->x509_cret, + daemon->https_cert_path, + daemon->https_key_path, + GNUTLS_X509_FMT_PEM); + } + else if (daemon->https_mem_cert && daemon->https_mem_key) + { + key.data = daemon->https_mem_key; + key.size = strlen (daemon->https_mem_key); + cert.data = daemon->https_mem_cert; + cert.size = strlen (daemon->https_mem_cert); - /* TODO address error case return value */ - return MHD_YES; + gnutls_certificate_set_x509_key_mem (daemon->x509_cret, &cert, &key, + GNUTLS_X509_FMT_PEM); + } + else + { +#if HAVE_MESSAGES + MHD_DLOG (daemon, "Failed to load certificate\n"); +#endif + 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 */ + return MHD_YES; } /* TODO unite with code in gnutls_priority.c */ @@ -322,9 +323,9 @@ MHDS_handle_connection (void *data) con->daemon->x509_cret); /* 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_pull_function(tls_session, &recv); + gnutls_transport_set_push_function(tls_session, &send); + */ gnutls_transport_set_ptr (con->tls_session, con->socket_fd); @@ -546,14 +547,15 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon) } MHD_destroy_response (pos->response); MHD_pool_destroy (pos->pool); +#if HTTPS_SUPPORT + if (pos->tls_session != 0) + { + gnutls_deinit (pos->tls_session); + } +#endif free (pos->addr); free (pos); daemon->max_connections++; -#if HTTPS_SUPPORT - if(pos->tls_session != 0){ - gnutls_deinit (pos->tls_session); - } -#endif if (prev == NULL) pos = daemon->connections; else @@ -770,7 +772,7 @@ MHD_start_daemon (unsigned int options, MHD_AccessHandlerCallback dh, void *dh_cls, ...) { const int on = 1; - struct MHD_Daemon * retVal; + struct MHD_Daemon *retVal; /* listeningss sockets used by the daemon */ int socket_fd; @@ -915,22 +917,26 @@ MHD_start_daemon (unsigned int options, retVal->https_mem_cert = va_arg (ap, const char *); break; case MHD_OPTION_KX_PRIORITY: - _set_priority (&retVal->priority_cache->cipher, va_arg (ap, const int *)); + _set_priority (&retVal->priority_cache->cipher, + va_arg (ap, const int *)); break; case MHD_OPTION_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) { - fprintf (stderr, - "Error: HTTPS option given while compiling without HTTPS support\n"); - } - else { - fprintf (stderr, - "Invalid MHD_OPTION argument! (Did you terminate the list with MHD_OPTION_END?)\n"); - } + if (opt > MHD_HTTPS_OPTION_START && opt < MHD_HTTPS_OPTION_END) + { + fprintf (stderr, + "Error: HTTPS option given while compiling without HTTPS support\n"); + } + else + { + fprintf (stderr, + "Invalid MHD_OPTION argument! (Did you terminate the list with MHD_OPTION_END?)\n"); + } #endif abort (); } @@ -1021,6 +1027,8 @@ MHD_stop_daemon (struct MHD_Daemon *daemon) { gnutls_priority_deinit (daemon->priority_cache); + gnutls_certificate_free_credentials (daemon->x509_cret); + /* lock gnutls_global mutex since it uses reference counting */ pthread_mutex_lock (&gnutls_init_mutex); gnutls_global_deinit (); diff --git a/src/daemon/https/includes/compat.h b/src/daemon/https/compat.h diff --git a/src/daemon/https/includes/extra.h b/src/daemon/https/extra.h diff --git a/src/daemon/https/includes/gnutls.h b/src/daemon/https/gnutls.h diff --git a/src/daemon/https/https_common.c b/src/daemon/https/https_common.c @@ -1,702 +0,0 @@ -/* - * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation - * Author: Nikos Mavrogiannopoulos - * - * This file is part of GNUTLS. - * - * GNUTLS is free software: you can redistribute it and/or modify - * 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 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/>. - */ - -#include <config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <gnutls.h> -#include <extra.h> -#include <time.h> -#include "https_common.h" - -#define TEST_STRING -#define SU(x) (x!=NULL?x:"Unknown") - -// TODO clean - originaly from tls_test extern int verbose; -int print_cert; -int verbose = 0; - -static char buffer[5 * 1024]; - -#define PRINTX(x,y) if (y[0]!=0) printf(" # %s %s\n", x, y) -#define PRINT_PGP_NAME(X) PRINTX( "NAME:", name) - -const char str_unknown[] = "(unknown)"; - -/* Hex encodes the given data. - */ -const char * -raw_to_string (const unsigned char *raw, size_t raw_size) -{ - static char buf[1024]; - size_t i; - if (raw_size == 0) - return NULL; - - if (raw_size * 3 + 1 >= sizeof (buf)) - return NULL; - - for (i = 0; i < raw_size; i++) - { - sprintf (&(buf[i * 3]), "%02X%s", raw[i], (i == raw_size - 1) ? "" - : ":"); - } - buf[sizeof (buf) - 1] = '\0'; - - return buf; -} - -static const char * -my_ctime (const time_t * tv) -{ - static char buf[256]; - struct tm *tp; - - if (((tp = localtime (tv)) == NULL) || (!strftime (buf, sizeof buf, - "%a %b %e %H:%M:%S %Z %Y\n", - tp))) - strcpy (buf, str_unknown); /* make sure buf text isn't garbage */ - - return buf; - -} - -void -print_x509_info (gnutls_session_t session, const char *hostname) -{ - gnutls_x509_crt_t crt; - const gnutls_datum_t *cert_list; - unsigned int cert_list_size = 0; - int ret; - char digest[20]; - char serial[40]; - char dn[256]; - size_t dn_size; - size_t digest_size = sizeof (digest); - unsigned int j; - size_t serial_size = sizeof (serial); - const char *print; - const char *cstr; - unsigned int bits, algo; - time_t expiret, activet; - - cert_list = gnutls_certificate_get_peers (session, &cert_list_size); - - if (cert_list_size == 0) - { - fprintf (stderr, "No certificates found!\n"); - return; - } - - printf (" - Got a certificate list of %d certificates.\n\n", - cert_list_size); - - for (j = 0; j < (unsigned int) cert_list_size; j++) - { - - gnutls_x509_crt_init (&crt); - ret = gnutls_x509_crt_import (crt, &cert_list[j], GNUTLS_X509_FMT_DER); - if (ret < 0) - { - fprintf (stderr, "Decoding error: %s\n", gnutls_strerror (ret)); - return; - } - - printf (" - Certificate[%d] info:\n", j); - - if (print_cert) - { - size_t size; - - size = sizeof (buffer); - - ret = - gnutls_x509_crt_export (crt, GNUTLS_X509_FMT_PEM, buffer, &size); - if (ret < 0) - { - fprintf (stderr, "Encoding error: %s\n", gnutls_strerror (ret)); - return; - } - fputs ("\n", stdout); - fputs (buffer, stdout); - fputs ("\n", stdout); - } - - if (j == 0 && hostname != NULL) - { /* Check the hostname of the first certificate - * if it matches the name of the host we - * connected to. - */ - if (gnutls_x509_crt_check_hostname (crt, hostname) == 0) - { - printf - (" # The hostname in the certificate does NOT match '%s'.\n", - hostname); - } - else - { - printf (" # The hostname in the certificate matches '%s'.\n", - hostname); - } - } - - expiret = gnutls_x509_crt_get_expiration_time (crt); - activet = gnutls_x509_crt_get_activation_time (crt); - - printf (" # valid since: %s", my_ctime (&activet)); - printf (" # expires at: %s", my_ctime (&expiret)); - - /* Print the serial number of the certificate. - */ - if (verbose - && gnutls_x509_crt_get_serial (crt, serial, &serial_size) >= 0) - { - print = raw_to_string (serial, serial_size); - if (print != NULL) - printf (" # serial number: %s\n", print); - } - - /* Print the fingerprint of the certificate - */ - digest_size = sizeof (digest); - if ((ret = gnutls_x509_crt_get_fingerprint (crt, GNUTLS_DIG_MD5, digest, - &digest_size)) < 0) - { - fprintf (stderr, - "Error in fingerprint calculation: %s\n", - gnutls_strerror (ret)); - } - else - { - print = raw_to_string (digest, digest_size); - if (print != NULL) - printf (" # fingerprint: %s\n", print); - } - - /* Print the version of the X.509 - * certificate. - */ - if (verbose) - { - printf (" # version: #%d\n", gnutls_x509_crt_get_version (crt)); - - bits = 0; - algo = gnutls_x509_crt_get_pk_algorithm (crt, &bits); - printf (" # public key algorithm: "); - - cstr = SU (gnutls_pk_algorithm_get_name (algo)); - printf ("%s (%d bits)\n", cstr, bits); - -#ifdef ENABLE_PKI - if (algo == GNUTLS_PK_RSA) - { - gnutls_datum_t e, m; - - ret = gnutls_x509_crt_get_pk_rsa_raw (crt, &m, &e); - if (ret >= 0) - { - print = SU (raw_to_string (e.data, e.size)); - printf (" # e [%d bits]: %s\n", e.size * 8, print); - - print = SU (raw_to_string (m.data, m.size)); - printf (" # m [%d bits]: %s\n", m.size * 8, print); - - gnutls_free (e.data); - gnutls_free (m.data); - } - } -#endif - } - - dn_size = sizeof (dn); - ret = gnutls_x509_crt_get_dn (crt, dn, &dn_size); - if (ret >= 0) - printf (" # Subject's DN: %s\n", dn); - - dn_size = sizeof (dn); - ret = gnutls_x509_crt_get_issuer_dn (crt, dn, &dn_size); - if (ret >= 0) - printf (" # Issuer's DN: %s\n", dn); - - gnutls_x509_crt_deinit (crt); - - printf ("\n"); - - } - -} - -#if ENABLE_OPENPGP -void -print_openpgp_info (gnutls_session_t session, const char *hostname) -{ - - char digest[20]; - size_t digest_size = sizeof (digest); - int ret; - const char *print; - const char *cstr; - char name[256]; - size_t name_len = sizeof (name); - gnutls_openpgp_crt_t crt; - const gnutls_datum_t *cert_list; - int cert_list_size = 0; - time_t expiret; - time_t activet; - - cert_list = gnutls_certificate_get_peers (session, &cert_list_size); - - if (cert_list_size > 0) - { - unsigned int algo, bits; - - gnutls_openpgp_crt_init (&crt); - ret = gnutls_openpgp_crt_import (crt, &cert_list[0], - GNUTLS_OPENPGP_FMT_RAW); - if (ret < 0) - { - fprintf (stderr, "Decoding error: %s\n", gnutls_strerror (ret)); - return; - } - - if (print_cert) - { - size_t size; - - size = sizeof (buffer); - - ret = gnutls_openpgp_crt_export (crt, GNUTLS_OPENPGP_FMT_BASE64, - buffer, &size); - if (ret < 0) - { - fprintf (stderr, "Encoding error: %s\n", gnutls_strerror (ret)); - return; - } - fputs ("\n", stdout); - fputs (buffer, stdout); - fputs ("\n", stdout); - } - - if (hostname != NULL) - { /* Check the hostname of the first certificate - * if it matches the name of the host we - * connected to. - */ - if (gnutls_openpgp_crt_check_hostname (crt, hostname) == 0) - { - printf (" # The hostname in the key does NOT match '%s'.\n", - hostname); - } - else - { - printf (" # The hostname in the key matches '%s'.\n", hostname); - } - } - - activet = gnutls_openpgp_crt_get_creation_time (crt); - expiret = gnutls_openpgp_crt_get_expiration_time (crt); - - printf (" # Key was created at: %s", my_ctime (&activet)); - printf (" # Key expires: "); - if (expiret != 0) - printf ("%s", my_ctime (&expiret)); - else - printf ("Never\n"); - - if (gnutls_openpgp_crt_get_fingerprint (crt, digest, &digest_size) >= 0) - { - print = raw_to_string (digest, digest_size); - - printf (" # PGP Key version: %d\n", - gnutls_openpgp_crt_get_version (crt)); - - bits = 0; - algo = gnutls_openpgp_crt_get_pk_algorithm (crt, &bits); - - printf (" # PGP Key public key algorithm: "); - cstr = SU (gnutls_pk_algorithm_get_name (algo)); - printf ("%s (%d bits)\n", cstr, bits); - - if (print != NULL) - printf (" # PGP Key fingerprint: %s\n", print); - - name_len = sizeof (name); - if (gnutls_openpgp_crt_get_name (crt, 0, name, &name_len) < 0) - { - fprintf (stderr, "Could not extract name\n"); - } - else - { - PRINT_PGP_NAME (name); - } - - } - - gnutls_openpgp_crt_deinit (crt); - - } -} -#endif - -void -print_cert_vrfy (gnutls_session_t session) -{ - int rc; - unsigned int status; - - rc = gnutls_certificate_verify_peers2 (session, &status); - printf ("\n"); - - if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND) - { - printf ("- Peer did not send any certificate.\n"); - return; - } - - if (rc < 0) - { - printf ("- Could not verify certificate (err: %s)\n", - gnutls_strerror (rc)); - return; - } - - if (gnutls_certificate_type_get (session) == GNUTLS_CRT_X509) - { - if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) - printf ("- Peer's certificate issuer is unknown\n"); - if (status & GNUTLS_CERT_INVALID) - printf ("- Peer's certificate is NOT trusted\n"); - else - printf ("- Peer's certificate is trusted\n"); - } - else - { - if (status & GNUTLS_CERT_INVALID) - printf ("- Peer's key is invalid\n"); - else - printf ("- Peer's key is valid\n"); - if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) - printf ("- Could not find a signer of the peer's key\n"); - } -} - -int -print_info (gnutls_session_t session, const char *hostname) -{ - const char *tmp; - gnutls_credentials_type_t cred; - gnutls_kx_algorithm_t kx; - - /* print the key exchange's algorithm name - */ - kx = gnutls_kx_get (session); - - cred = gnutls_auth_get_type (session); - switch (cred) - { -#ifdef ENABLE_ANON - case GNUTLS_CRD_ANON: - printf ("- Anonymous DH using prime of %d bits, secret key " - "of %d bits, and peer's public key is %d bits.\n", - gnutls_dh_get_prime_bits (session), - gnutls_dh_get_secret_bits (session), - gnutls_dh_get_peers_public_bits (session)); - break; -#endif -#ifdef ENABLE_SRP - case GNUTLS_CRD_SRP: - /* This should be only called in server - * side. - */ - if (gnutls_srp_server_get_username (session) != NULL) - printf ("- SRP authentication. Connected as '%s'\n", - gnutls_srp_server_get_username (session)); - break; -#endif -#ifdef ENABLE_PSK - case GNUTLS_CRD_PSK: - /* This should be only called in server - * side. - */ - if (gnutls_psk_server_get_username (session) != NULL) - printf ("- PSK authentication. Connected as '%s'\n", - gnutls_psk_server_get_username (session)); - if (kx == GNUTLS_KX_DHE_PSK) - { - printf ("- DH using prime of %d bits, secret key " - "of %d bits, and peer's public key is %d bits.\n", - gnutls_dh_get_prime_bits (session), - gnutls_dh_get_secret_bits (session), - gnutls_dh_get_peers_public_bits (session)); - } - break; -#endif - case GNUTLS_CRD_IA: - printf ("- TLS/IA authentication\n"); - break; - case GNUTLS_CRD_CERTIFICATE: - { - char dns[256]; - size_t dns_size = sizeof (dns); - unsigned int type; - - /* This fails in client side */ - if (gnutls_server_name_get (session, dns, &dns_size, &type, 0) == 0) - { - printf ("- Given server name[%d]: %s\n", type, dns); - } - } - - if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) - { - printf ("- Ephemeral DH using prime of %d bits, secret key " - "of %d bits, and peer's public key is %d bits.\n", - gnutls_dh_get_prime_bits (session), - gnutls_dh_get_secret_bits (session), - gnutls_dh_get_peers_public_bits (session)); - } - - print_cert_info (session, hostname); - - print_cert_vrfy (session); - - } - - tmp = SU (gnutls_protocol_get_name (gnutls_protocol_get_version (session))); - printf ("- Version: %s\n", tmp); - - tmp = SU (gnutls_kx_get_name (kx)); - printf ("- Key Exchange: %s\n", tmp); - - tmp = SU (gnutls_cipher_get_name (gnutls_cipher_get (session))); - printf ("- Cipher: %s\n", tmp); - - tmp = SU (gnutls_mac_get_name (gnutls_mac_get (session))); - printf ("- MAC: %s\n", tmp); - - tmp = SU (gnutls_compression_get_name (gnutls_compression_get (session))); - printf ("- Compression: %s\n", tmp); - - if (verbose) - { - char id[32]; - size_t id_size = sizeof (id); - gnutls_session_get_id (session, id, &id_size); - printf ("- Session ID: %s\n", raw_to_string (id, id_size)); - } - - fflush (stdout); - - return 0; -} - -void -print_cert_info (gnutls_session_t session, const char *hostname) -{ - - if (gnutls_certificate_client_get_request_status (session) != 0) - printf ("- Server has requested a certificate.\n"); - - printf ("- Certificate type: "); - switch (gnutls_certificate_type_get (session)) - { - case GNUTLS_CRT_X509: - printf ("X.509\n"); - print_x509_info (session, hostname); - break; -#if ENABLE_OPENPGP - case GNUTLS_CRT_OPENPGP: - printf ("OpenPGP\n"); - print_openpgp_info (session, hostname); - break; -#endif - } -} - -void -print_list (int verbose) -{ - { - size_t i; - const char *name; - char id[2]; - gnutls_kx_algorithm_t kx; - gnutls_cipher_algorithm_t cipher; - gnutls_mac_algorithm_t mac; - gnutls_protocol_t version; - - printf ("Cipher suites:\n"); - for (i = 0; (name = gnutls_cipher_suite_info (i, id, &kx, &cipher, &mac, - &version)); i++) - { - printf ("%-50s\t0x%02x, 0x%02x\t%s\n", name, (unsigned char) id[0], - (unsigned char) id[1], gnutls_protocol_get_name (version)); - if (verbose) - printf ("\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n", - gnutls_kx_get_name (kx), gnutls_cipher_get_name (cipher), - gnutls_mac_get_name (mac)); - } - } - - { - const gnutls_certificate_type_t *p = gnutls_certificate_type_list (); - - printf ("Certificate types: "); - for (; *p; p++) - { - printf ("%s", gnutls_certificate_type_get_name (*p)); - if (*(p + 1)) - printf (", "); - else - printf ("\n"); - } - } - - { - const gnutls_protocol_t *p = gnutls_protocol_list (); - - printf ("Protocols: "); - for (; *p; p++) - { - printf ("%s", gnutls_protocol_get_name (*p)); - if (*(p + 1)) - printf (", "); - else - printf ("\n"); - } - } - - { - const gnutls_cipher_algorithm_t *p = gnutls_cipher_list (); - - printf ("Ciphers: "); - for (; *p; p++) - { - printf ("%s", gnutls_cipher_get_name (*p)); - if (*(p + 1)) - printf (", "); - else - printf ("\n"); - } - } - - { - const gnutls_mac_algorithm_t *p = gnutls_mac_list (); - - printf ("MACs: "); - for (; *p; p++) - { - printf ("%s", gnutls_mac_get_name (*p)); - if (*(p + 1)) - printf (", "); - else - printf ("\n"); - } - } - - { - const gnutls_kx_algorithm_t *p = gnutls_kx_list (); - - printf ("Key exchange algorithms: "); - for (; *p; p++) - { - printf ("%s", gnutls_kx_get_name (*p)); - if (*(p + 1)) - printf (", "); - else - printf ("\n"); - } - } - - { - const gnutls_compression_method_t *p = gnutls_compression_list (); - - printf ("Compression: "); - for (; *p; p++) - { - printf ("%s", gnutls_compression_get_name (*p)); - if (*(p + 1)) - printf (", "); - else - printf ("\n"); - } - } -} - -void -print_license (void) -{ - fputs ("\nCopyright (C) 2004,2005,2006,2007 Free Software Foundation\n" - "This program is free software; you can redistribute it and/or modify \n" - "it under the terms of the GNU General Public License as published by \n" - "the Free Software Foundation; either version 3 of the License, or \n" - "(at your option) any later version. \n" "\n" - "This program is distributed in the hope that it will be useful, \n" - "but WITHOUT ANY WARRANTY; without even the implied warranty of \n" - "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the \n" - "GNU General Public License for more details. \n" "\n" - "You should have received a copy of the GNU General Public License \n" - "along with this program; if not, write to the Free Software \n" - "Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n", - stdout); -} - -void -sockets_init (void) -{ -#ifdef _WIN32 - WORD wVersionRequested; - WSADATA wsaData; - - wVersionRequested = MAKEWORD (1, 1); - if (WSAStartup (wVersionRequested, &wsaData) != 0) - { - perror ("WSA_STARTUP_ERROR"); - } -#endif -} - -/* converts a service name or a port (in string) to a - * port number. The protocol is assumed to be TCP. - * - * returns -1 on error; - */ -int -service_to_port (const char *service) -{ - int port; - struct servent *server_port; - - port = atoi (service); - if (port != 0) - return port; - - server_port = getservbyname (service, "tcp"); - if (server_port == NULL) - { - perror ("getservbyname()"); - return (-1); - } - - return ntohs (server_port->s_port); - -} diff --git a/src/daemon/https/https_common.h b/src/daemon/https/https_common.h @@ -1,40 +0,0 @@ -#define PORT 5556 -#define SERVER "127.0.0.1" - -#include <config.h> -#include <gnutls.h> - -#include <sys/socket.h> -#include <arpa/inet.h> -#ifdef _WIN32 -# include <io.h> -# include <winbase.h> -# define close closesocket -#else -# include <netinet/in.h> -# include <unistd.h> -# include <netdb.h> -# include <signal.h> -#endif - -/* the number of elements in the priority structures. - */ -#define PRI_MAX 16 - -extern const char str_unknown[]; - -int print_info (gnutls_session_t state, const char *hostname); -void print_cert_info (gnutls_session_t state, const char *hostname); -void print_list (int verbose); - -void parse_comp (char **comp, int ncomp, int *comp_priority); -void parse_kx (char **kx, int nkx, int *kx_priority); -void parse_ctypes (char **ctype, int nctype, int *cert_type_priority); -void parse_macs (char **macs, int nmacs, int *mac_priority); -void parse_ciphers (char **ciphers, int nciphers, int *cipher_priority); -void parse_protocols (char **protocols, int protocols_size, - int *protocol_priority); -const char *raw_to_string (const unsigned char *raw, size_t raw_size); -int service_to_port (const char *service); - -void sockets_init (void); diff --git a/src/daemon/https/includes/Makefile.am b/src/daemon/https/includes/Makefile.am @@ -1,3 +0,0 @@ -AM_CPPFLAGS = -I$(top_srcdir)/src/https/includes - -lib_LTLIBRARIES = libmicrohttpd.la diff --git a/src/daemon/https/openpgp/Makefile.am b/src/daemon/https/openpgp/Makefile.am @@ -2,7 +2,7 @@ SUBDIRS = . AM_CPPFLAGS = \ -I$(top_srcdir)/src/include \ --I$(top_srcdir)/src/daemon/https/includes \ +-I$(top_srcdir)/src/daemon/https \ -I$(top_srcdir)/src/daemon/https/lgl \ -I$(top_srcdir)/src/daemon/https/x509 \ -I$(top_srcdir)/src/daemon/https/tls \ diff --git a/src/daemon/https/tls/Makefile.am b/src/daemon/https/tls/Makefile.am @@ -3,12 +3,12 @@ SUBDIRS = . AM_CPPFLAGS = \ -I$(top_srcdir)/src/include \ -I$(top_srcdir)/src/daemon/ \ +-I$(top_srcdir)/src/daemon/https \ -I$(top_srcdir)/src/daemon/https/tls \ -I$(top_srcdir)/src/daemon/https/lgl \ -I$(top_srcdir)/src/daemon/https/x509 \ -I$(top_srcdir)/src/daemon/https/openpgp \ -I$(top_srcdir)/src/daemon/https/opencdk \ --I$(top_srcdir)/src/daemon/https/includes \ -I$(GCRYPT_CPPFLAGS) noinst_LTLIBRARIES = libtls.la diff --git a/src/daemon/https/x509/Makefile.am b/src/daemon/https/x509/Makefile.am @@ -1,7 +1,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/src/include \ --I$(top_srcdir)/src/daemon/https/includes \ +-I$(top_srcdir)/src/daemon/https \ -I$(top_srcdir)/src/daemon/https/minitasn1 \ -I$(top_srcdir)/src/daemon/https/lgl \ -I$(top_srcdir)/src/daemon/https/x509 \ diff --git a/src/examples/Makefile.am b/src/examples/Makefile.am @@ -2,7 +2,7 @@ SUBDIRS = . AM_CPPFLAGS = \ -I$(top_srcdir)/src/include \ --I$(top_srcdir)/src/daemon/https/includes +-I$(top_srcdir)/src/daemon/https # example programs noinst_PROGRAMS = \ @@ -43,9 +43,5 @@ fileserver_example_external_select_LDADD = \ https_server_example_SOURCES = \ https_server_example.c -https_server_example_CPPFLAGS = \ - -I$(top_srcdir)/src/daemon/https/includes \ - -I$(top_srcdir)/src/daemon \ - -I$(top_srcdir)/src/include https_server_example_LDADD = \ $(top_builddir)/src/daemon/libmicrohttpd.la diff --git a/src/examples/authorization_example.c b/src/examples/authorization_example.c @@ -51,7 +51,7 @@ ahc_echo (void *cls, struct MHD_Response *response; int ret; int code; - const char * auth; + const char *auth; if (0 != strcmp (method, "GET")) return MHD_NO; /* unexpected method */ @@ -62,25 +62,24 @@ ahc_echo (void *cls, return MHD_YES; } *ptr = NULL; /* reset when done */ - auth = MHD_lookup_connection_value(connection, - MHD_HEADER_KIND, - MHD_HTTP_HEADER_AUTHORIZATION); - if ( (auth == NULL) || - (0 != strcmp(auth, - "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==") ) ) + auth = MHD_lookup_connection_value (connection, + MHD_HEADER_KIND, + MHD_HTTP_HEADER_AUTHORIZATION); + if ((auth == NULL) || + (0 != strcmp (auth, "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="))) { /* require: "Aladdin" with password "open sesame" */ response = MHD_create_response_from_data (strlen (DENIED), - (void *) DENIED, MHD_NO, MHD_NO); - MHD_add_response_header(response, - MHD_HTTP_HEADER_WWW_AUTHENTICATE, - "Basic realm=\"TestRealm\""); + (void *) DENIED, MHD_NO, + MHD_NO); + MHD_add_response_header (response, MHD_HTTP_HEADER_WWW_AUTHENTICATE, + "Basic realm=\"TestRealm\""); code = MHD_HTTP_UNAUTHORIZED; } else { response = MHD_create_response_from_data (strlen (me), - (void *) me, MHD_NO, MHD_NO); + (void *) me, MHD_NO, MHD_NO); code = MHD_HTTP_OK; } ret = MHD_queue_response (connection, code, response); diff --git a/src/examples/https_server_example.c b/src/examples/https_server_example.c @@ -18,12 +18,14 @@ */ /** * @file https_server_example.c - * @brief a simple https file server using TLS. + * @brief a simple HTTPS file server using TLS. * - * This example assumes the existence of a private key file named "key.pem" - * and a server certificate file named "cert.pem". File path for these should be - * provided as command-line arguments. 'certtool' may be used to generate these if - * missing. + * Server may be supplied either with included hard coded certificates or using + * external ones, which are to be supplied through command line arguments. + * A private key file named "key.pem" and a server certificate file named "cert.pem". + * are necessary to run the server in this way. + * + * 'certtool' may be used to generate these if required. * * Access server with your browser of choice or with curl : * @@ -33,7 +35,7 @@ */ #include "config.h" -#include <microhttpd.h> +#include <microhttpsd.h> #include <sys/stat.h> #include <stdlib.h> @@ -167,8 +169,7 @@ main (int argc, char *const *argv) if (argc < 5) { printf - ("Usage : %s HTTP-PORT SECONDS-TO-RUN HTTPS-PORT KEY-FILE CERT-FILE\n", - argv[0]); + ("Usage : %s HTTP-PORT SECONDS-TO-RUN KEY-FILE CERT-FILE\n", argv[0]); return 1; } diff --git a/src/include/microhttpsd.h b/src/include/microhttpsd.h @@ -133,6 +133,7 @@ union MHD_SessionInfo gnutls_protocol_t protocol; gnutls_certificate_type_t certificate_type; gnutls_pk_algorithm_t pk_algorithm; + int null_info; }; enum MHD_InfoType @@ -146,7 +147,7 @@ enum MHD_InfoType MHD_INFO_CERT_TYPE, }; -union MHD_SessionInfo MHD_get_session_info (struct MHD_Connection *con, +union MHD_SessionInfo MHD_get_tls_session_info (struct MHD_Connection *con, enum MHD_InfoType infoType); //TODO impl diff --git a/src/testcurl/Makefile.am b/src/testcurl/Makefile.am @@ -5,7 +5,7 @@ SUBDIRS += https endif AM_CPPFLAGS = \ --I$(top_srcdir)/src/daemon/https/includes \ +-I$(top_srcdir)/src/daemon/https \ -I$(top_srcdir)/src/daemon \ -I$(top_srcdir)/src/include diff --git a/src/testcurl/https/Makefile.am b/src/testcurl/https/Makefile.am @@ -2,18 +2,27 @@ SUBDIRS = . AM_CPPFLAGS = \ -I$(top_srcdir)/src/include \ --I$(top_srcdir)/src/daemon/https/includes \ +-I$(top_srcdir)/src/daemon/https \ +-I$(top_srcdir)/src/daemon/https/tls \ +-I$(top_srcdir)/src/daemon/https/lgl \ +-I$(top_srcdir)/src/daemon/https/x509 \ -I$(top_srcdir)/src/daemon check_PROGRAMS = \ - tls_authentication_test \ mhds_get_test \ - mhds_session_info_test \ - mhds_multi_daemon_test - + tls_authentication_test \ + mhds_multi_daemon_test \ + mhds_session_info_test + TESTS = $(check_PROGRAMS) +tls_alert_test_SOURCES = \ + tls_alert_test.c +tls_alert_test_LDADD = \ + $(top_builddir)/src/daemon/libmicrohttpd.la \ + @LIBCURL@ + tls_authentication_test_SOURCES = \ tls_authentication_test.c tls_authentication_test_LDADD = \ diff --git a/src/testcurl/https/mhds_get_test.c b/src/testcurl/https/mhds_get_test.c @@ -235,7 +235,8 @@ test_secure_get (FILE * test_fd, char *cipher_suite, int proto_version) MHD_USE_DEBUG, 42433, NULL, NULL, &http_ahc, NULL, MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem, - MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, MHD_OPTION_END); + MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, + MHD_OPTION_END); if (d == NULL) { @@ -255,10 +256,13 @@ test_file_certificates (FILE * test_fd, char *cipher_suite, int proto_version) int ret; struct MHD_Daemon *d; FILE *cert_fd, *key_fd; - char cert_path[255], key_path[255]; + char cert_path[255], key_path[255], *cur_dir; + + cur_dir = get_current_dir_name (); + + sprintf (cert_path, "%s/%s", cur_dir, "cert.pem"); + sprintf (key_path, "%s/%s", cur_dir, "key.pem"); - sprintf (cert_path, "%s/%s", get_current_dir_name (), "cert.pem"); - sprintf (key_path, "%s/%s", get_current_dir_name (), "key.pem"); if (NULL == (key_fd = fopen (key_path, "w+"))) { @@ -272,7 +276,8 @@ test_file_certificates (FILE * test_fd, char *cipher_suite, int proto_version) } fwrite (srv_key_pem, strlen (srv_key_pem), sizeof (char), key_fd); - fwrite (srv_self_signed_cert_pem, strlen (srv_self_signed_cert_pem), sizeof (char), cert_fd); + fwrite (srv_self_signed_cert_pem, strlen (srv_self_signed_cert_pem), + sizeof (char), cert_fd); fclose (key_fd); fclose (cert_fd); @@ -292,6 +297,7 @@ test_file_certificates (FILE * test_fd, char *cipher_suite, int proto_version) ret = test_daemon_get (test_fd, cipher_suite, proto_version); MHD_stop_daemon (d); + free (cur_dir); remove (cert_path); remove (key_path); return ret; @@ -412,6 +418,8 @@ main (int argc, char *const *argv) FILE *test_fd; unsigned int errorCount = 0; + // gnutls_global_set_log_level(11); + if ((test_fd = setupTestFile ()) == NULL) { fprintf (stderr, MHD_E_TEST_FILE_CREAT); @@ -420,18 +428,16 @@ main (int argc, char *const *argv) if (0 != curl_global_init (CURL_GLOBAL_ALL)) { - fprintf (stderr, "Error (code: %u)\n", errorCount); + fprintf (stderr, "Error: %s\n", strerror (errno)); return -1; } errorCount += test_secure_get (test_fd, "AES256-SHA", CURL_SSLVERSION_TLSv1); - errorCount += test_secure_get (test_fd, "AES256-SHA", CURL_SSLVERSION_SSLv3); 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); @@ -439,9 +445,6 @@ main (int argc, char *const *argv) test_kx_option (test_fd, "EDH-RSA-DES-CBC3-SHA", CURL_SSLVERSION_SSLv3); - if (errorCount != 0) - fprintf (stderr, "Error (code: %u)\n", errorCount); - curl_global_cleanup (); fclose (test_fd); diff --git a/src/testcurl/https/mhds_multi_daemon_test.c b/src/testcurl/https/mhds_multi_daemon_test.c @@ -236,7 +236,8 @@ test_concurent_daemon_pair (FILE * test_fd, char *cipher_suite, MHD_USE_DEBUG, 42433, NULL, NULL, &http_ahc, NULL, MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem, - MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, MHD_OPTION_END); + MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, + MHD_OPTION_END); if (d1 == NULL) { @@ -248,7 +249,8 @@ test_concurent_daemon_pair (FILE * test_fd, char *cipher_suite, MHD_USE_DEBUG, 42434, NULL, NULL, &http_ahc, NULL, MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem, - MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, MHD_OPTION_END); + MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, + MHD_OPTION_END); if (d2 == NULL) { diff --git a/src/testcurl/https/mhds_session_info_test.c b/src/testcurl/https/mhds_session_info_test.c @@ -75,54 +75,61 @@ query_session_ahc (void *cls, struct MHD_Connection *connection, int ret; /* assert actual connection cipher is the one negotiated */ - if (MHD_get_session_info (connection,MHS_INFO_CIPHER_ALGO).cipher_algorithm != GNUTLS_CIPHER_AES_256_CBC) + if (MHD_get_tls_session_info (connection, MHS_INFO_CIPHER_ALGO). + cipher_algorithm != GNUTLS_CIPHER_AES_256_CBC) { fprintf (stderr, "Error: requested cipher mismatch. %s\n", strerror (errno)); return -1; } - if (MHD_get_session_info (connection,MHD_INFO_KX_ALGO).kx_algorithm != GNUTLS_KX_RSA) - { - fprintf (stderr, "Error: requested key exchange mismatch. %s\n", - strerror (errno)); - return -1; - } + if (MHD_get_tls_session_info (connection, MHD_INFO_KX_ALGO).kx_algorithm != + GNUTLS_KX_RSA) + { + fprintf (stderr, "Error: requested key exchange mismatch. %s\n", + strerror (errno)); + return -1; + } - if (MHD_get_session_info (connection,MHD_INFO_MAC_ALGO).mac_algorithm != GNUTLS_MAC_SHA1) + if (MHD_get_tls_session_info (connection, MHD_INFO_MAC_ALGO). + mac_algorithm != GNUTLS_MAC_SHA1) { fprintf (stderr, "Error: requested mac algorithm mismatch. %s\n", strerror (errno)); return -1; } - if (MHD_get_session_info (connection,MHD_INFO_COMPRESSION_METHOD).compression_method != GNUTLS_COMP_NULL) + if (MHD_get_tls_session_info (connection, MHD_INFO_COMPRESSION_METHOD). + compression_method != GNUTLS_COMP_NULL) { fprintf (stderr, "Error: requested compression mismatch. %s\n", strerror (errno)); return -1; } - if (MHD_get_session_info (connection,MHD_INFO_PROTOCOL).protocol != GNUTLS_SSL3) - { - fprintf (stderr, "Error: requested compression mismatch. %s\n", - strerror (errno)); - return -1; - } + if (MHD_get_tls_session_info (connection, MHD_INFO_PROTOCOL).protocol != + GNUTLS_SSL3) + { + fprintf (stderr, "Error: requested compression mismatch. %s\n", + strerror (errno)); + return -1; + } - if (MHD_get_session_info (connection,MHD_INFO_CERT_TYPE).certificate_type != GNUTLS_CRT_X509) + if (MHD_get_tls_session_info (connection, MHD_INFO_CERT_TYPE). + certificate_type != GNUTLS_CRT_X509) { fprintf (stderr, "Error: requested certificate mismatch. %s\n", strerror (errno)); return -1; } - if (MHD_get_session_info (connection,MHD_INFO_CREDENTIALS_TYPE).credentials_type != GNUTLS_CRD_CERTIFICATE) - { - fprintf (stderr, "Error: requested certificate mismatch. %s\n", - strerror (errno)); - return -1; - } + if (MHD_get_tls_session_info (connection, MHD_INFO_CREDENTIALS_TYPE). + credentials_type != GNUTLS_CRD_CERTIFICATE) + { + fprintf (stderr, "Error: requested certificate mismatch. %s\n", + strerror (errno)); + return -1; + } response = MHD_create_response_from_data (strlen (EMPTY_PAGE), (void *) EMPTY_PAGE, @@ -154,7 +161,8 @@ test_query_session () MHD_USE_DEBUG, 42433, NULL, NULL, &query_session_ahc, NULL, MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem, - MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, MHD_OPTION_END); + MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, + MHD_OPTION_END); if (d == NULL) return 2; diff --git a/src/testcurl/https/tls_alert_test.c b/src/testcurl/https/tls_alert_test.c @@ -0,0 +1,188 @@ +/* + This file is part of libmicrohttpd + (C) 2007 Christian Grothoff + + libmicrohttpd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + libmicrohttpd 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 libmicrohttpd; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file mhds_get_test.c + * @brief Testcase for libmicrohttpd HTTPS GET operations + * @author Sagie Amir + */ + +#include "config.h" +#include "plibc.h" +#include "microhttpsd.h" +#include <errno.h> + +#include <curl/curl.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <fcntl.h> +#include <unistd.h> + + +#define MHD_E_MEM "Error: memory error\n" +#define MHD_E_SERVER_INIT "Error: failed to start server\n" + +#include "gnutls_int.h" +#include "gnutls_datum.h" +#include "tls_test_keys.h" + +const char *ca_cert_file_name = "ca_cert_pem"; +const char *test_file_name = "https_test_file"; +const char test_file_data[] = "Hello World\n"; + +struct CBC +{ + char *buf; + size_t pos; + size_t size; +}; + +static int +file_reader (void *cls, size_t pos, char *buf, int max) +{ + FILE *file = cls; + fseek (file, pos, SEEK_SET); + return fread (buf, 1, max, file); +} + +/* HTTP access handler call back */ +static int +http_ahc (void *cls, struct MHD_Connection *connection, + const char *url, const char *method, const char *upload_data, + const char *version, unsigned int *upload_data_size, void **ptr) +{ + return 0; +} + +static int +test_alert_response () +{ + + + int sd, ret; + char *err_pos; + struct sockaddr_in sa; + gnutls_priority_t priority_cache; + gnutls_session_t session; + gnutls_certificate_credentials_t xcred; + + + gnutls_global_init (); + + gnutls_datum_t key; + gnutls_datum_t cert; + + + gnutls_certificate_allocate_credentials (&xcred); + + _gnutls_set_datum_m (&key, srv_key_pem, strlen (srv_key_pem), &malloc); + _gnutls_set_datum_m (&cert, srv_self_signed_cert_pem, + strlen (srv_self_signed_cert_pem), &malloc); + + gnutls_certificate_set_x509_key_mem (xcred, &cert, &key, + GNUTLS_X509_FMT_PEM); + + ret = gnutls_priority_init (&priority_cache, + "NONE:+VERS-TLS1.0:+AES-256-CBC:+RSA:+SHA1:+COMP-NULL", + &err_pos); + if (ret < 0) + { + // ... + } + + gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + + sd = socket (AF_INET, SOCK_STREAM, 0); + memset (&sa, '\0', sizeof (struct sockaddr_in)); + sa.sin_family = AF_INET; + sa.sin_port = htons (42433); + inet_pton (AF_INET, "127.0.0.1", &sa.sin_addr); + + ret = connect (sd, &sa, sizeof (struct sockaddr_in)); + + if (ret < 0) + { + // ... + } + + ret = gnutls_handshake (session); + + if (ret < 0) + { + // ... + } + + gnutls_alert_send (session, GNUTLS_AL_FATAL, GNUTLS_A_CLOSE_NOTIFY); + + /* check server responds with a 'close-notify' */ + _gnutls_recv_int (session, GNUTLS_ALERT, GNUTLS_HANDSHAKE_FINISHED, 0, 0); + + /* CLOSE_NOTIFY */ + if (session->internals.last_alert != GNUTLS_A_CLOSE_NOTIFY) + { + return -1; + } + + close (sd); + + gnutls_deinit (session); + + gnutls_certificate_free_credentials (xcred); + + gnutls_global_deinit (); + + return 0; + +} + + + +int +main (int argc, char *const *argv) +{ + int ret, errorCount = 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, srv_key_pem, + MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, + MHD_OPTION_END); + + if (d == NULL) + { + fprintf (stderr, MHD_E_SERVER_INIT); + return -1; + } + + errorCount += test_alert_response (); + + if (errorCount != 0) + fprintf (stderr, "Error (code: %u)\n", errorCount); + + MHD_stop_daemon (d); + return errorCount != 0; +}