aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlv-426 <oxcafebaby@yahoo.com>2008-07-18 03:53:27 +0000
committerlv-426 <oxcafebaby@yahoo.com>2008-07-18 03:53:27 +0000
commit04c37e5bd7a82f60127b64338cf37c470ca93e12 (patch)
treee602f345000a692993ac38a7109d1ffaa67ce3b7 /src
parent1cd7c174797f65098c6c3048564634cbe6c3bb9f (diff)
downloadlibmicrohttpd-04c37e5bd7a82f60127b64338cf37c470ca93e12.tar.gz
libmicrohttpd-04c37e5bd7a82f60127b64338cf37c470ca93e12.zip
fixed some memory leaks
removed includes dir
Diffstat (limited to 'src')
-rw-r--r--src/daemon/Makefile.am2
-rw-r--r--src/daemon/connection_https.c56
-rw-r--r--src/daemon/daemon.c198
-rw-r--r--src/daemon/https/compat.h (renamed from src/daemon/https/includes/compat.h)0
-rw-r--r--src/daemon/https/extra.h (renamed from src/daemon/https/includes/extra.h)0
-rw-r--r--src/daemon/https/gnutls.h (renamed from src/daemon/https/includes/gnutls.h)0
-rw-r--r--src/daemon/https/https_common.c702
-rw-r--r--src/daemon/https/https_common.h40
-rw-r--r--src/daemon/https/includes/Makefile.am3
-rw-r--r--src/daemon/https/openpgp/Makefile.am2
-rw-r--r--src/daemon/https/tls/Makefile.am2
-rw-r--r--src/daemon/https/x509/Makefile.am2
-rw-r--r--src/examples/Makefile.am6
-rw-r--r--src/examples/authorization_example.c23
-rw-r--r--src/examples/https_server_example.c17
-rw-r--r--src/include/microhttpsd.h3
-rw-r--r--src/testcurl/Makefile.am2
-rw-r--r--src/testcurl/https/Makefile.am19
-rw-r--r--src/testcurl/https/mhds_get_test.c25
-rw-r--r--src/testcurl/https/mhds_multi_daemon_test.c6
-rw-r--r--src/testcurl/https/mhds_session_info_test.c54
-rw-r--r--src/testcurl/https/tls_alert_test.c188
22 files changed, 415 insertions, 935 deletions
diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am
index d17d6072..3a3580a7 100644
--- a/src/daemon/Makefile.am
+++ b/src/daemon/Makefile.am
@@ -6,7 +6,7 @@ AM_CPPFLAGS = \
6-I$(top_srcdir)/src/daemon/https/openpgp \ 6-I$(top_srcdir)/src/daemon/https/openpgp \
7-I$(top_srcdir)/src/daemon/https/opencdk \ 7-I$(top_srcdir)/src/daemon/https/opencdk \
8-I$(top_srcdir)/src/daemon/https/tls \ 8-I$(top_srcdir)/src/daemon/https/tls \
9-I$(top_srcdir)/src/daemon/https/includes \ 9-I$(top_srcdir)/src/daemon/https \
10-I$(top_srcdir)/src/daemon/https/cfg \ 10-I$(top_srcdir)/src/daemon/https/cfg \
11-I$(GCRYPT_CPPFLAGS) 11-I$(GCRYPT_CPPFLAGS)
12 12
diff --git a/src/daemon/connection_https.c b/src/daemon/connection_https.c
index 92292b10..4f6af3e4 100644
--- 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)
71} 71}
72 72
73union MHD_SessionInfo 73union MHD_SessionInfo
74MHD_get_session_info (struct MHD_Connection *con, enum MHD_InfoType infoType) 74MHD_get_tls_session_info (struct MHD_Connection *con,
75 enum MHD_InfoType infoType)
75{ 76{
77 /* return NULL if this isn't a SSL/TLS type connection */
78 if (con->tls_session == NULL)
79 {
80 /* TODO clean */
81 return (union MHD_SessionInfo) 0;
82 }
76 switch (infoType) 83 switch (infoType)
77 { 84 {
78 case MHS_INFO_CIPHER_ALGO: 85 case MHS_INFO_CIPHER_ALGO:
79 return (union MHD_SessionInfo) con->tls_session->security_parameters.read_bulk_cipher_algorithm; 86 return (union MHD_SessionInfo) con->tls_session->security_parameters.
87 read_bulk_cipher_algorithm;
80 case MHD_INFO_KX_ALGO: 88 case MHD_INFO_KX_ALGO:
81 return (union MHD_SessionInfo) con->tls_session->security_parameters.kx_algorithm; 89 return (union MHD_SessionInfo) con->tls_session->security_parameters.
90 kx_algorithm;
82 case MHD_INFO_CREDENTIALS_TYPE: 91 case MHD_INFO_CREDENTIALS_TYPE:
83 return (union MHD_SessionInfo) con->tls_session->key->cred->algorithm; 92 return (union MHD_SessionInfo) con->tls_session->key->cred->algorithm;
84 case MHD_INFO_MAC_ALGO: 93 case MHD_INFO_MAC_ALGO:
85 return (union MHD_SessionInfo) con->tls_session->security_parameters.read_mac_algorithm; 94 return (union MHD_SessionInfo) con->tls_session->security_parameters.
95 read_mac_algorithm;
86 case MHD_INFO_COMPRESSION_METHOD: 96 case MHD_INFO_COMPRESSION_METHOD:
87 return (union MHD_SessionInfo) con->tls_session->security_parameters.read_compression_algorithm; 97 return (union MHD_SessionInfo) con->tls_session->security_parameters.
98 read_compression_algorithm;
88 case MHD_INFO_PROTOCOL: 99 case MHD_INFO_PROTOCOL:
89 return (union MHD_SessionInfo) con->tls_session->security_parameters.version; 100 return (union MHD_SessionInfo) con->tls_session->security_parameters.
101 version;
90 case MHD_INFO_CERT_TYPE: 102 case MHD_INFO_CERT_TYPE:
91 return (union MHD_SessionInfo) con->tls_session->security_parameters.cert_type; 103 return (union MHD_SessionInfo) con->tls_session->security_parameters.
104 cert_type;
92 }; 105 };
93} 106}
94 107
@@ -280,24 +293,21 @@ MHD_tls_connection_handle_write (struct MHD_Connection *connection)
280{ 293{
281 connection->last_activity = time (NULL); 294 connection->last_activity = time (NULL);
282 295
283 while (1)
284 {
285#if HAVE_MESSAGES 296#if HAVE_MESSAGES
286 MHD_DLOG (connection->daemon, "MHD write: %d. f: %s, l: %d\n", 297 MHD_DLOG (connection->daemon, "MHD write: %d. f: %s, l: %d\n",
287 connection->state, __FUNCTION__, __LINE__); 298 connection->state, __FUNCTION__, __LINE__);
288#endif 299#endif
289 switch (connection->state) 300 switch (connection->state)
290 { 301 {
291 case MHD_CONNECTION_CLOSED: 302 case MHD_CONNECTION_CLOSED:
292 MHD_tls_connection_close (connection); 303 MHD_tls_connection_close (connection);
293 return MHD_NO; 304 return MHD_NO;
294 case MHD_TLS_HANDSHAKE_FAILED: 305 case MHD_TLS_HANDSHAKE_FAILED:
295 MHD_tls_connection_close (connection); 306 MHD_tls_connection_close (connection);
296 return MHD_NO; 307 return MHD_NO;
297 /* some HTTP state */ 308 /* some HTTP state */
298 default: 309 default:
299 return MHD_connection_handle_write (connection); 310 return MHD_connection_handle_write (connection);
300 }
301 } 311 }
302} 312}
303 313
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c
index 399715db..d6f3bc9c 100644
--- a/src/daemon/daemon.c
+++ b/src/daemon/daemon.c
@@ -29,10 +29,11 @@
29#include "connection.h" 29#include "connection.h"
30#include "memorypool.h" 30#include "memorypool.h"
31 31
32#if HTTPS_SUPPORT
32#include "gnutls.h" 33#include "gnutls.h"
33#include "gnutls_int.h" 34#include "gnutls_int.h"
34#include "gnutls_datum.h"
35#include "gnutls_global.h" 35#include "gnutls_global.h"
36#endif
36 37
37/** 38/**
38 * Default connection limit. 39 * Default connection limit.
@@ -59,86 +60,86 @@
59#if HTTPS_SUPPORT 60#if HTTPS_SUPPORT
60/* initialize security aspects of the HTTPS daemon */ 61/* initialize security aspects of the HTTPS daemon */
61static int 62static int
62MHDS_init (struct MHD_Daemon *daemon){ 63MHDS_init (struct MHD_Daemon *daemon)
63 64{
64 int i; 65 int i;
65 priority_st st; 66 priority_st st;
66 67 gnutls_datum_t key;
67 gnutls_global_set_log_function (MHD_tls_log_func); 68 gnutls_datum_t cert;
68 69
69 /* setup server certificate */ 70 gnutls_global_set_log_function (MHD_tls_log_func);
70 gnutls_certificate_allocate_credentials (&daemon->x509_cret); 71
71 72 /* setup server certificate */
72 /* TODO remove if unused 73 gnutls_certificate_allocate_credentials (&daemon->x509_cret);
73 gnutls_certificate_set_x509_trust_file(x509_cret, CAFILE,GNUTLS_X509_FMT_PEM);
74 gnutls_certificate_set_x509_crl_file(x509_cret, CRLFILE, GNUTLS_X509_FMT_PEM); */
75
76 /* sets a certificate private key pair */
77 if (daemon->https_cert_path && daemon->https_key_path)
78 {
79 /* test for private key & certificate file exsitance */
80 if (access (daemon->https_cert_path, R_OK))
81 {
82 #if HAVE_MESSAGES
83 MHD_DLOG (daemon, "Missing X.509 certificate file\n");
84 #endif
85 free (daemon);
86 CLOSE (daemon->socket_fd);
87 return -1;
88 }
89
90 if (access (daemon->https_key_path, R_OK))
91 {
92 #if HAVE_MESSAGES
93 MHD_DLOG (daemon, "Missing X.509 key file\n");
94 #endif
95 free (daemon);
96 CLOSE (daemon->socket_fd);
97 return -1;
98 }
99 gnutls_certificate_set_x509_key_file (daemon->x509_cret,
100 daemon->https_cert_path,
101 daemon->https_key_path,
102 GNUTLS_X509_FMT_PEM);
103 }
104 else if (daemon->https_mem_cert && daemon->https_mem_key)
105 {
106 gnutls_datum_t key ;
107 gnutls_datum_t cert ;
108
109 _gnutls_set_datum_m (&key, daemon->https_mem_key,
110 strlen (daemon->https_mem_key), &malloc);
111 _gnutls_set_datum_m (&cert, daemon->https_mem_cert,
112 strlen (daemon->https_mem_cert), &malloc);
113
114 gnutls_certificate_set_x509_key_mem (daemon->x509_cret, &cert, &key,
115 GNUTLS_X509_FMT_PEM);
116 }
117 else
118 {
119 #if HAVE_MESSAGES
120 MHD_DLOG (daemon, "Failed to load certificate\n");
121 #endif
122 return MHD_NO;
123 }
124 74
125 /* generate DH parameters if necessary */ 75 /* TODO remove if unused
126 st = daemon->priority_cache->kx; 76 gnutls_certificate_set_x509_trust_file(x509_cret, CAFILE,GNUTLS_X509_FMT_PEM);
127 for (i = 0; i < st.algorithms; i++) 77 gnutls_certificate_set_x509_crl_file(x509_cret, CRLFILE, GNUTLS_X509_FMT_PEM); */
78
79 /* sets a certificate private key pair */
80 if (daemon->https_cert_path && daemon->https_key_path)
81 {
82 /* test for private key & certificate file exsitance */
83 if (access (daemon->https_cert_path, R_OK))
128 { 84 {
129 /* initialize Diffie Hellman parameters if necessary */ 85#if HAVE_MESSAGES
130 /* TODO add other cipher suits */ 86 MHD_DLOG (daemon, "Missing X.509 certificate file\n");
131 if (st.priority[i] == GNUTLS_KX_DHE_RSA ){ 87#endif
132 gnutls_dh_params_init (&daemon->dh_params); 88 free (daemon);
133 gnutls_dh_params_generate2 (daemon->dh_params, 1024); 89 CLOSE (daemon->socket_fd);
134 break; 90 return -1;
135 }
136 } 91 }
137 92
138 gnutls_certificate_set_dh_params (daemon->x509_cret, daemon->dh_params); 93 if (access (daemon->https_key_path, R_OK))
94 {
95#if HAVE_MESSAGES
96 MHD_DLOG (daemon, "Missing X.509 key file\n");
97#endif
98 free (daemon);
99 CLOSE (daemon->socket_fd);
100 return -1;
101 }
102 gnutls_certificate_set_x509_key_file (daemon->x509_cret,
103 daemon->https_cert_path,
104 daemon->https_key_path,
105 GNUTLS_X509_FMT_PEM);
106 }
107 else if (daemon->https_mem_cert && daemon->https_mem_key)
108 {
109 key.data = daemon->https_mem_key;
110 key.size = strlen (daemon->https_mem_key);
111 cert.data = daemon->https_mem_cert;
112 cert.size = strlen (daemon->https_mem_cert);
139 113
140 /* TODO address error case return value */ 114 gnutls_certificate_set_x509_key_mem (daemon->x509_cret, &cert, &key,
141 return MHD_YES; 115 GNUTLS_X509_FMT_PEM);
116 }
117 else
118 {
119#if HAVE_MESSAGES
120 MHD_DLOG (daemon, "Failed to load certificate\n");
121#endif
122 return MHD_NO;
123 }
124
125 /* generate DH parameters if necessary */
126 st = daemon->priority_cache->kx;
127 for (i = 0; i < st.algorithms; i++)
128 {
129 /* initialize Diffie Hellman parameters if necessary */
130 /* TODO add other cipher suits */
131 if (st.priority[i] == GNUTLS_KX_DHE_RSA)
132 {
133 gnutls_dh_params_init (&daemon->dh_params);
134 gnutls_dh_params_generate2 (daemon->dh_params, 1024);
135 break;
136 }
137 }
138
139 gnutls_certificate_set_dh_params (daemon->x509_cret, daemon->dh_params);
140
141 /* TODO address error case return value */
142 return MHD_YES;
142} 143}
143 144
144/* TODO unite with code in gnutls_priority.c */ 145/* TODO unite with code in gnutls_priority.c */
@@ -322,9 +323,9 @@ MHDS_handle_connection (void *data)
322 con->daemon->x509_cret); 323 con->daemon->x509_cret);
323 324
324 /* TODO avoid gnutls blocking recv / write calls 325 /* TODO avoid gnutls blocking recv / write calls
325 gnutls_transport_set_pull_function(tls_session, &recv); 326 gnutls_transport_set_pull_function(tls_session, &recv);
326 gnutls_transport_set_push_function(tls_session, &send); 327 gnutls_transport_set_push_function(tls_session, &send);
327 */ 328 */
328 329
329 gnutls_transport_set_ptr (con->tls_session, con->socket_fd); 330 gnutls_transport_set_ptr (con->tls_session, con->socket_fd);
330 331
@@ -546,14 +547,15 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
546 } 547 }
547 MHD_destroy_response (pos->response); 548 MHD_destroy_response (pos->response);
548 MHD_pool_destroy (pos->pool); 549 MHD_pool_destroy (pos->pool);
550#if HTTPS_SUPPORT
551 if (pos->tls_session != 0)
552 {
553 gnutls_deinit (pos->tls_session);
554 }
555#endif
549 free (pos->addr); 556 free (pos->addr);
550 free (pos); 557 free (pos);
551 daemon->max_connections++; 558 daemon->max_connections++;
552#if HTTPS_SUPPORT
553 if(pos->tls_session != 0){
554 gnutls_deinit (pos->tls_session);
555 }
556#endif
557 if (prev == NULL) 559 if (prev == NULL)
558 pos = daemon->connections; 560 pos = daemon->connections;
559 else 561 else
@@ -770,7 +772,7 @@ MHD_start_daemon (unsigned int options,
770 MHD_AccessHandlerCallback dh, void *dh_cls, ...) 772 MHD_AccessHandlerCallback dh, void *dh_cls, ...)
771{ 773{
772 const int on = 1; 774 const int on = 1;
773 struct MHD_Daemon * retVal; 775 struct MHD_Daemon *retVal;
774 776
775 /* listeningss sockets used by the daemon */ 777 /* listeningss sockets used by the daemon */
776 int socket_fd; 778 int socket_fd;
@@ -915,22 +917,26 @@ MHD_start_daemon (unsigned int options,
915 retVal->https_mem_cert = va_arg (ap, const char *); 917 retVal->https_mem_cert = va_arg (ap, const char *);
916 break; 918 break;
917 case MHD_OPTION_KX_PRIORITY: 919 case MHD_OPTION_KX_PRIORITY:
918 _set_priority (&retVal->priority_cache->cipher, va_arg (ap, const int *)); 920 _set_priority (&retVal->priority_cache->cipher,
921 va_arg (ap, const int *));
919 break; 922 break;
920 case MHD_OPTION_CIPHER_ALGORITHM: 923 case MHD_OPTION_CIPHER_ALGORITHM:
921 _set_priority (&retVal->priority_cache->cipher, va_arg (ap, const int *)); 924 _set_priority (&retVal->priority_cache->cipher,
925 va_arg (ap, const int *));
922 break; 926 break;
923#endif 927#endif
924 default: 928 default:
925#if HAVE_MESSAGES 929#if HAVE_MESSAGES
926 if (opt > MHD_HTTPS_OPTION_START && opt < MHD_HTTPS_OPTION_END) { 930 if (opt > MHD_HTTPS_OPTION_START && opt < MHD_HTTPS_OPTION_END)
927 fprintf (stderr, 931 {
928 "Error: HTTPS option given while compiling without HTTPS support\n"); 932 fprintf (stderr,
929 } 933 "Error: HTTPS option given while compiling without HTTPS support\n");
930 else { 934 }
931 fprintf (stderr, 935 else
932 "Invalid MHD_OPTION argument! (Did you terminate the list with MHD_OPTION_END?)\n"); 936 {
933 } 937 fprintf (stderr,
938 "Invalid MHD_OPTION argument! (Did you terminate the list with MHD_OPTION_END?)\n");
939 }
934#endif 940#endif
935 abort (); 941 abort ();
936 } 942 }
@@ -1021,6 +1027,8 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
1021 { 1027 {
1022 gnutls_priority_deinit (daemon->priority_cache); 1028 gnutls_priority_deinit (daemon->priority_cache);
1023 1029
1030 gnutls_certificate_free_credentials (daemon->x509_cret);
1031
1024 /* lock gnutls_global mutex since it uses reference counting */ 1032 /* lock gnutls_global mutex since it uses reference counting */
1025 pthread_mutex_lock (&gnutls_init_mutex); 1033 pthread_mutex_lock (&gnutls_init_mutex);
1026 gnutls_global_deinit (); 1034 gnutls_global_deinit ();
diff --git a/src/daemon/https/includes/compat.h b/src/daemon/https/compat.h
index 32f5d2bd..32f5d2bd 100644
--- 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
index 0c363259..0c363259 100644
--- 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
index df34e72c..df34e72c 100644
--- 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
deleted file mode 100644
index de978219..00000000
--- a/src/daemon/https/https_common.c
+++ /dev/null
@@ -1,702 +0,0 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 * Author: Nikos Mavrogiannopoulos
4 *
5 * This file is part of GNUTLS.
6 *
7 * GNUTLS is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * GNUTLS is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <config.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25
26#include <gnutls.h>
27#include <extra.h>
28#include <time.h>
29#include "https_common.h"
30
31#define TEST_STRING
32#define SU(x) (x!=NULL?x:"Unknown")
33
34// TODO clean - originaly from tls_test extern int verbose;
35int print_cert;
36int verbose = 0;
37
38static char buffer[5 * 1024];
39
40#define PRINTX(x,y) if (y[0]!=0) printf(" # %s %s\n", x, y)
41#define PRINT_PGP_NAME(X) PRINTX( "NAME:", name)
42
43const char str_unknown[] = "(unknown)";
44
45/* Hex encodes the given data.
46 */
47const char *
48raw_to_string (const unsigned char *raw, size_t raw_size)
49{
50 static char buf[1024];
51 size_t i;
52 if (raw_size == 0)
53 return NULL;
54
55 if (raw_size * 3 + 1 >= sizeof (buf))
56 return NULL;
57
58 for (i = 0; i < raw_size; i++)
59 {
60 sprintf (&(buf[i * 3]), "%02X%s", raw[i], (i == raw_size - 1) ? ""
61 : ":");
62 }
63 buf[sizeof (buf) - 1] = '\0';
64
65 return buf;
66}
67
68static const char *
69my_ctime (const time_t * tv)
70{
71 static char buf[256];
72 struct tm *tp;
73
74 if (((tp = localtime (tv)) == NULL) || (!strftime (buf, sizeof buf,
75 "%a %b %e %H:%M:%S %Z %Y\n",
76 tp)))
77 strcpy (buf, str_unknown); /* make sure buf text isn't garbage */
78
79 return buf;
80
81}
82
83void
84print_x509_info (gnutls_session_t session, const char *hostname)
85{
86 gnutls_x509_crt_t crt;
87 const gnutls_datum_t *cert_list;
88 unsigned int cert_list_size = 0;
89 int ret;
90 char digest[20];
91 char serial[40];
92 char dn[256];
93 size_t dn_size;
94 size_t digest_size = sizeof (digest);
95 unsigned int j;
96 size_t serial_size = sizeof (serial);
97 const char *print;
98 const char *cstr;
99 unsigned int bits, algo;
100 time_t expiret, activet;
101
102 cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
103
104 if (cert_list_size == 0)
105 {
106 fprintf (stderr, "No certificates found!\n");
107 return;
108 }
109
110 printf (" - Got a certificate list of %d certificates.\n\n",
111 cert_list_size);
112
113 for (j = 0; j < (unsigned int) cert_list_size; j++)
114 {
115
116 gnutls_x509_crt_init (&crt);
117 ret = gnutls_x509_crt_import (crt, &cert_list[j], GNUTLS_X509_FMT_DER);
118 if (ret < 0)
119 {
120 fprintf (stderr, "Decoding error: %s\n", gnutls_strerror (ret));
121 return;
122 }
123
124 printf (" - Certificate[%d] info:\n", j);
125
126 if (print_cert)
127 {
128 size_t size;
129
130 size = sizeof (buffer);
131
132 ret =
133 gnutls_x509_crt_export (crt, GNUTLS_X509_FMT_PEM, buffer, &size);
134 if (ret < 0)
135 {
136 fprintf (stderr, "Encoding error: %s\n", gnutls_strerror (ret));
137 return;
138 }
139 fputs ("\n", stdout);
140 fputs (buffer, stdout);
141 fputs ("\n", stdout);
142 }
143
144 if (j == 0 && hostname != NULL)
145 { /* Check the hostname of the first certificate
146 * if it matches the name of the host we
147 * connected to.
148 */
149 if (gnutls_x509_crt_check_hostname (crt, hostname) == 0)
150 {
151 printf
152 (" # The hostname in the certificate does NOT match '%s'.\n",
153 hostname);
154 }
155 else
156 {
157 printf (" # The hostname in the certificate matches '%s'.\n",
158 hostname);
159 }
160 }
161
162 expiret = gnutls_x509_crt_get_expiration_time (crt);
163 activet = gnutls_x509_crt_get_activation_time (crt);
164
165 printf (" # valid since: %s", my_ctime (&activet));
166 printf (" # expires at: %s", my_ctime (&expiret));
167
168 /* Print the serial number of the certificate.
169 */
170 if (verbose
171 && gnutls_x509_crt_get_serial (crt, serial, &serial_size) >= 0)
172 {
173 print = raw_to_string (serial, serial_size);
174 if (print != NULL)
175 printf (" # serial number: %s\n", print);
176 }
177
178 /* Print the fingerprint of the certificate
179 */
180 digest_size = sizeof (digest);
181 if ((ret = gnutls_x509_crt_get_fingerprint (crt, GNUTLS_DIG_MD5, digest,
182 &digest_size)) < 0)
183 {
184 fprintf (stderr,
185 "Error in fingerprint calculation: %s\n",
186 gnutls_strerror (ret));
187 }
188 else
189 {
190 print = raw_to_string (digest, digest_size);
191 if (print != NULL)
192 printf (" # fingerprint: %s\n", print);
193 }
194
195 /* Print the version of the X.509
196 * certificate.
197 */
198 if (verbose)
199 {
200 printf (" # version: #%d\n", gnutls_x509_crt_get_version (crt));
201
202 bits = 0;
203 algo = gnutls_x509_crt_get_pk_algorithm (crt, &bits);
204 printf (" # public key algorithm: ");
205
206 cstr = SU (gnutls_pk_algorithm_get_name (algo));
207 printf ("%s (%d bits)\n", cstr, bits);
208
209#ifdef ENABLE_PKI
210 if (algo == GNUTLS_PK_RSA)
211 {
212 gnutls_datum_t e, m;
213
214 ret = gnutls_x509_crt_get_pk_rsa_raw (crt, &m, &e);
215 if (ret >= 0)
216 {
217 print = SU (raw_to_string (e.data, e.size));
218 printf (" # e [%d bits]: %s\n", e.size * 8, print);
219
220 print = SU (raw_to_string (m.data, m.size));
221 printf (" # m [%d bits]: %s\n", m.size * 8, print);
222
223 gnutls_free (e.data);
224 gnutls_free (m.data);
225 }
226 }
227#endif
228 }
229
230 dn_size = sizeof (dn);
231 ret = gnutls_x509_crt_get_dn (crt, dn, &dn_size);
232 if (ret >= 0)
233 printf (" # Subject's DN: %s\n", dn);
234
235 dn_size = sizeof (dn);
236 ret = gnutls_x509_crt_get_issuer_dn (crt, dn, &dn_size);
237 if (ret >= 0)
238 printf (" # Issuer's DN: %s\n", dn);
239
240 gnutls_x509_crt_deinit (crt);
241
242 printf ("\n");
243
244 }
245
246}
247
248#if ENABLE_OPENPGP
249void
250print_openpgp_info (gnutls_session_t session, const char *hostname)
251{
252
253 char digest[20];
254 size_t digest_size = sizeof (digest);
255 int ret;
256 const char *print;
257 const char *cstr;
258 char name[256];
259 size_t name_len = sizeof (name);
260 gnutls_openpgp_crt_t crt;
261 const gnutls_datum_t *cert_list;
262 int cert_list_size = 0;
263 time_t expiret;
264 time_t activet;
265
266 cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
267
268 if (cert_list_size > 0)
269 {
270 unsigned int algo, bits;
271
272 gnutls_openpgp_crt_init (&crt);
273 ret = gnutls_openpgp_crt_import (crt, &cert_list[0],
274 GNUTLS_OPENPGP_FMT_RAW);
275 if (ret < 0)
276 {
277 fprintf (stderr, "Decoding error: %s\n", gnutls_strerror (ret));
278 return;
279 }
280
281 if (print_cert)
282 {
283 size_t size;
284
285 size = sizeof (buffer);
286
287 ret = gnutls_openpgp_crt_export (crt, GNUTLS_OPENPGP_FMT_BASE64,
288 buffer, &size);
289 if (ret < 0)
290 {
291 fprintf (stderr, "Encoding error: %s\n", gnutls_strerror (ret));
292 return;
293 }
294 fputs ("\n", stdout);
295 fputs (buffer, stdout);
296 fputs ("\n", stdout);
297 }
298
299 if (hostname != NULL)
300 { /* Check the hostname of the first certificate
301 * if it matches the name of the host we
302 * connected to.
303 */
304 if (gnutls_openpgp_crt_check_hostname (crt, hostname) == 0)
305 {
306 printf (" # The hostname in the key does NOT match '%s'.\n",
307 hostname);
308 }
309 else
310 {
311 printf (" # The hostname in the key matches '%s'.\n", hostname);
312 }
313 }
314
315 activet = gnutls_openpgp_crt_get_creation_time (crt);
316 expiret = gnutls_openpgp_crt_get_expiration_time (crt);
317
318 printf (" # Key was created at: %s", my_ctime (&activet));
319 printf (" # Key expires: ");
320 if (expiret != 0)
321 printf ("%s", my_ctime (&expiret));
322 else
323 printf ("Never\n");
324
325 if (gnutls_openpgp_crt_get_fingerprint (crt, digest, &digest_size) >= 0)
326 {
327 print = raw_to_string (digest, digest_size);
328
329 printf (" # PGP Key version: %d\n",
330 gnutls_openpgp_crt_get_version (crt));
331
332 bits = 0;
333 algo = gnutls_openpgp_crt_get_pk_algorithm (crt, &bits);
334
335 printf (" # PGP Key public key algorithm: ");
336 cstr = SU (gnutls_pk_algorithm_get_name (algo));
337 printf ("%s (%d bits)\n", cstr, bits);
338
339 if (print != NULL)
340 printf (" # PGP Key fingerprint: %s\n", print);
341
342 name_len = sizeof (name);
343 if (gnutls_openpgp_crt_get_name (crt, 0, name, &name_len) < 0)
344 {
345 fprintf (stderr, "Could not extract name\n");
346 }
347 else
348 {
349 PRINT_PGP_NAME (name);
350 }
351
352 }
353
354 gnutls_openpgp_crt_deinit (crt);
355
356 }
357}
358#endif
359
360void
361print_cert_vrfy (gnutls_session_t session)
362{
363 int rc;
364 unsigned int status;
365
366 rc = gnutls_certificate_verify_peers2 (session, &status);
367 printf ("\n");
368
369 if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND)
370 {
371 printf ("- Peer did not send any certificate.\n");
372 return;
373 }
374
375 if (rc < 0)
376 {
377 printf ("- Could not verify certificate (err: %s)\n",
378 gnutls_strerror (rc));
379 return;
380 }
381
382 if (gnutls_certificate_type_get (session) == GNUTLS_CRT_X509)
383 {
384 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
385 printf ("- Peer's certificate issuer is unknown\n");
386 if (status & GNUTLS_CERT_INVALID)
387 printf ("- Peer's certificate is NOT trusted\n");
388 else
389 printf ("- Peer's certificate is trusted\n");
390 }
391 else
392 {
393 if (status & GNUTLS_CERT_INVALID)
394 printf ("- Peer's key is invalid\n");
395 else
396 printf ("- Peer's key is valid\n");
397 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
398 printf ("- Could not find a signer of the peer's key\n");
399 }
400}
401
402int
403print_info (gnutls_session_t session, const char *hostname)
404{
405 const char *tmp;
406 gnutls_credentials_type_t cred;
407 gnutls_kx_algorithm_t kx;
408
409 /* print the key exchange's algorithm name
410 */
411 kx = gnutls_kx_get (session);
412
413 cred = gnutls_auth_get_type (session);
414 switch (cred)
415 {
416#ifdef ENABLE_ANON
417 case GNUTLS_CRD_ANON:
418 printf ("- Anonymous DH using prime of %d bits, secret key "
419 "of %d bits, and peer's public key is %d bits.\n",
420 gnutls_dh_get_prime_bits (session),
421 gnutls_dh_get_secret_bits (session),
422 gnutls_dh_get_peers_public_bits (session));
423 break;
424#endif
425#ifdef ENABLE_SRP
426 case GNUTLS_CRD_SRP:
427 /* This should be only called in server
428 * side.
429 */
430 if (gnutls_srp_server_get_username (session) != NULL)
431 printf ("- SRP authentication. Connected as '%s'\n",
432 gnutls_srp_server_get_username (session));
433 break;
434#endif
435#ifdef ENABLE_PSK
436 case GNUTLS_CRD_PSK:
437 /* This should be only called in server
438 * side.
439 */
440 if (gnutls_psk_server_get_username (session) != NULL)
441 printf ("- PSK authentication. Connected as '%s'\n",
442 gnutls_psk_server_get_username (session));
443 if (kx == GNUTLS_KX_DHE_PSK)
444 {
445 printf ("- DH using prime of %d bits, secret key "
446 "of %d bits, and peer's public key is %d bits.\n",
447 gnutls_dh_get_prime_bits (session),
448 gnutls_dh_get_secret_bits (session),
449 gnutls_dh_get_peers_public_bits (session));
450 }
451 break;
452#endif
453 case GNUTLS_CRD_IA:
454 printf ("- TLS/IA authentication\n");
455 break;
456 case GNUTLS_CRD_CERTIFICATE:
457 {
458 char dns[256];
459 size_t dns_size = sizeof (dns);
460 unsigned int type;
461
462 /* This fails in client side */
463 if (gnutls_server_name_get (session, dns, &dns_size, &type, 0) == 0)
464 {
465 printf ("- Given server name[%d]: %s\n", type, dns);
466 }
467 }
468
469 if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS)
470 {
471 printf ("- Ephemeral DH using prime of %d bits, secret key "
472 "of %d bits, and peer's public key is %d bits.\n",
473 gnutls_dh_get_prime_bits (session),
474 gnutls_dh_get_secret_bits (session),
475 gnutls_dh_get_peers_public_bits (session));
476 }
477
478 print_cert_info (session, hostname);
479
480 print_cert_vrfy (session);
481
482 }
483
484 tmp = SU (gnutls_protocol_get_name (gnutls_protocol_get_version (session)));
485 printf ("- Version: %s\n", tmp);
486
487 tmp = SU (gnutls_kx_get_name (kx));
488 printf ("- Key Exchange: %s\n", tmp);
489
490 tmp = SU (gnutls_cipher_get_name (gnutls_cipher_get (session)));
491 printf ("- Cipher: %s\n", tmp);
492
493 tmp = SU (gnutls_mac_get_name (gnutls_mac_get (session)));
494 printf ("- MAC: %s\n", tmp);
495
496 tmp = SU (gnutls_compression_get_name (gnutls_compression_get (session)));
497 printf ("- Compression: %s\n", tmp);
498
499 if (verbose)
500 {
501 char id[32];
502 size_t id_size = sizeof (id);
503 gnutls_session_get_id (session, id, &id_size);
504 printf ("- Session ID: %s\n", raw_to_string (id, id_size));
505 }
506
507 fflush (stdout);
508
509 return 0;
510}
511
512void
513print_cert_info (gnutls_session_t session, const char *hostname)
514{
515
516 if (gnutls_certificate_client_get_request_status (session) != 0)
517 printf ("- Server has requested a certificate.\n");
518
519 printf ("- Certificate type: ");
520 switch (gnutls_certificate_type_get (session))
521 {
522 case GNUTLS_CRT_X509:
523 printf ("X.509\n");
524 print_x509_info (session, hostname);
525 break;
526#if ENABLE_OPENPGP
527 case GNUTLS_CRT_OPENPGP:
528 printf ("OpenPGP\n");
529 print_openpgp_info (session, hostname);
530 break;
531#endif
532 }
533}
534
535void
536print_list (int verbose)
537{
538 {
539 size_t i;
540 const char *name;
541 char id[2];
542 gnutls_kx_algorithm_t kx;
543 gnutls_cipher_algorithm_t cipher;
544 gnutls_mac_algorithm_t mac;
545 gnutls_protocol_t version;
546
547 printf ("Cipher suites:\n");
548 for (i = 0; (name = gnutls_cipher_suite_info (i, id, &kx, &cipher, &mac,
549 &version)); i++)
550 {
551 printf ("%-50s\t0x%02x, 0x%02x\t%s\n", name, (unsigned char) id[0],
552 (unsigned char) id[1], gnutls_protocol_get_name (version));
553 if (verbose)
554 printf ("\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n",
555 gnutls_kx_get_name (kx), gnutls_cipher_get_name (cipher),
556 gnutls_mac_get_name (mac));
557 }
558 }
559
560 {
561 const gnutls_certificate_type_t *p = gnutls_certificate_type_list ();
562
563 printf ("Certificate types: ");
564 for (; *p; p++)
565 {
566 printf ("%s", gnutls_certificate_type_get_name (*p));
567 if (*(p + 1))
568 printf (", ");
569 else
570 printf ("\n");
571 }
572 }
573
574 {
575 const gnutls_protocol_t *p = gnutls_protocol_list ();
576
577 printf ("Protocols: ");
578 for (; *p; p++)
579 {
580 printf ("%s", gnutls_protocol_get_name (*p));
581 if (*(p + 1))
582 printf (", ");
583 else
584 printf ("\n");
585 }
586 }
587
588 {
589 const gnutls_cipher_algorithm_t *p = gnutls_cipher_list ();
590
591 printf ("Ciphers: ");
592 for (; *p; p++)
593 {
594 printf ("%s", gnutls_cipher_get_name (*p));
595 if (*(p + 1))
596 printf (", ");
597 else
598 printf ("\n");
599 }
600 }
601
602 {
603 const gnutls_mac_algorithm_t *p = gnutls_mac_list ();
604
605 printf ("MACs: ");
606 for (; *p; p++)
607 {
608 printf ("%s", gnutls_mac_get_name (*p));
609 if (*(p + 1))
610 printf (", ");
611 else
612 printf ("\n");
613 }
614 }
615
616 {
617 const gnutls_kx_algorithm_t *p = gnutls_kx_list ();
618
619 printf ("Key exchange algorithms: ");
620 for (; *p; p++)
621 {
622 printf ("%s", gnutls_kx_get_name (*p));
623 if (*(p + 1))
624 printf (", ");
625 else
626 printf ("\n");
627 }
628 }
629
630 {
631 const gnutls_compression_method_t *p = gnutls_compression_list ();
632
633 printf ("Compression: ");
634 for (; *p; p++)
635 {
636 printf ("%s", gnutls_compression_get_name (*p));
637 if (*(p + 1))
638 printf (", ");
639 else
640 printf ("\n");
641 }
642 }
643}
644
645void
646print_license (void)
647{
648 fputs ("\nCopyright (C) 2004,2005,2006,2007 Free Software Foundation\n"
649 "This program is free software; you can redistribute it and/or modify \n"
650 "it under the terms of the GNU General Public License as published by \n"
651 "the Free Software Foundation; either version 3 of the License, or \n"
652 "(at your option) any later version. \n" "\n"
653 "This program is distributed in the hope that it will be useful, \n"
654 "but WITHOUT ANY WARRANTY; without even the implied warranty of \n"
655 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the \n"
656 "GNU General Public License for more details. \n" "\n"
657 "You should have received a copy of the GNU General Public License \n"
658 "along with this program; if not, write to the Free Software \n"
659 "Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n",
660 stdout);
661}
662
663void
664sockets_init (void)
665{
666#ifdef _WIN32
667 WORD wVersionRequested;
668 WSADATA wsaData;
669
670 wVersionRequested = MAKEWORD (1, 1);
671 if (WSAStartup (wVersionRequested, &wsaData) != 0)
672 {
673 perror ("WSA_STARTUP_ERROR");
674 }
675#endif
676}
677
678/* converts a service name or a port (in string) to a
679 * port number. The protocol is assumed to be TCP.
680 *
681 * returns -1 on error;
682 */
683int
684service_to_port (const char *service)
685{
686 int port;
687 struct servent *server_port;
688
689 port = atoi (service);
690 if (port != 0)
691 return port;
692
693 server_port = getservbyname (service, "tcp");
694 if (server_port == NULL)
695 {
696 perror ("getservbyname()");
697 return (-1);
698 }
699
700 return ntohs (server_port->s_port);
701
702}
diff --git a/src/daemon/https/https_common.h b/src/daemon/https/https_common.h
deleted file mode 100644
index 3ccd2cb1..00000000
--- a/src/daemon/https/https_common.h
+++ /dev/null
@@ -1,40 +0,0 @@
1#define PORT 5556
2#define SERVER "127.0.0.1"
3
4#include <config.h>
5#include <gnutls.h>
6
7#include <sys/socket.h>
8#include <arpa/inet.h>
9#ifdef _WIN32
10# include <io.h>
11# include <winbase.h>
12# define close closesocket
13#else
14# include <netinet/in.h>
15# include <unistd.h>
16# include <netdb.h>
17# include <signal.h>
18#endif
19
20/* the number of elements in the priority structures.
21 */
22#define PRI_MAX 16
23
24extern const char str_unknown[];
25
26int print_info (gnutls_session_t state, const char *hostname);
27void print_cert_info (gnutls_session_t state, const char *hostname);
28void print_list (int verbose);
29
30void parse_comp (char **comp, int ncomp, int *comp_priority);
31void parse_kx (char **kx, int nkx, int *kx_priority);
32void parse_ctypes (char **ctype, int nctype, int *cert_type_priority);
33void parse_macs (char **macs, int nmacs, int *mac_priority);
34void parse_ciphers (char **ciphers, int nciphers, int *cipher_priority);
35void parse_protocols (char **protocols, int protocols_size,
36 int *protocol_priority);
37const char *raw_to_string (const unsigned char *raw, size_t raw_size);
38int service_to_port (const char *service);
39
40void sockets_init (void);
diff --git a/src/daemon/https/includes/Makefile.am b/src/daemon/https/includes/Makefile.am
deleted file mode 100644
index b0c6ada1..00000000
--- a/src/daemon/https/includes/Makefile.am
+++ /dev/null
@@ -1,3 +0,0 @@
1AM_CPPFLAGS = -I$(top_srcdir)/src/https/includes
2
3lib_LTLIBRARIES = libmicrohttpd.la
diff --git a/src/daemon/https/openpgp/Makefile.am b/src/daemon/https/openpgp/Makefile.am
index 66380444..50f03c24 100644
--- a/src/daemon/https/openpgp/Makefile.am
+++ b/src/daemon/https/openpgp/Makefile.am
@@ -2,7 +2,7 @@ SUBDIRS = .
2 2
3AM_CPPFLAGS = \ 3AM_CPPFLAGS = \
4-I$(top_srcdir)/src/include \ 4-I$(top_srcdir)/src/include \
5-I$(top_srcdir)/src/daemon/https/includes \ 5-I$(top_srcdir)/src/daemon/https \
6-I$(top_srcdir)/src/daemon/https/lgl \ 6-I$(top_srcdir)/src/daemon/https/lgl \
7-I$(top_srcdir)/src/daemon/https/x509 \ 7-I$(top_srcdir)/src/daemon/https/x509 \
8-I$(top_srcdir)/src/daemon/https/tls \ 8-I$(top_srcdir)/src/daemon/https/tls \
diff --git a/src/daemon/https/tls/Makefile.am b/src/daemon/https/tls/Makefile.am
index 63cbaabe..11e70592 100644
--- a/src/daemon/https/tls/Makefile.am
+++ b/src/daemon/https/tls/Makefile.am
@@ -3,12 +3,12 @@ SUBDIRS = .
3AM_CPPFLAGS = \ 3AM_CPPFLAGS = \
4-I$(top_srcdir)/src/include \ 4-I$(top_srcdir)/src/include \
5-I$(top_srcdir)/src/daemon/ \ 5-I$(top_srcdir)/src/daemon/ \
6-I$(top_srcdir)/src/daemon/https \
6-I$(top_srcdir)/src/daemon/https/tls \ 7-I$(top_srcdir)/src/daemon/https/tls \
7-I$(top_srcdir)/src/daemon/https/lgl \ 8-I$(top_srcdir)/src/daemon/https/lgl \
8-I$(top_srcdir)/src/daemon/https/x509 \ 9-I$(top_srcdir)/src/daemon/https/x509 \
9-I$(top_srcdir)/src/daemon/https/openpgp \ 10-I$(top_srcdir)/src/daemon/https/openpgp \
10-I$(top_srcdir)/src/daemon/https/opencdk \ 11-I$(top_srcdir)/src/daemon/https/opencdk \
11-I$(top_srcdir)/src/daemon/https/includes \
12-I$(GCRYPT_CPPFLAGS) 12-I$(GCRYPT_CPPFLAGS)
13 13
14noinst_LTLIBRARIES = libtls.la 14noinst_LTLIBRARIES = libtls.la
diff --git a/src/daemon/https/x509/Makefile.am b/src/daemon/https/x509/Makefile.am
index 6121dd51..2bdb5799 100644
--- a/src/daemon/https/x509/Makefile.am
+++ b/src/daemon/https/x509/Makefile.am
@@ -1,7 +1,7 @@
1 1
2AM_CPPFLAGS = \ 2AM_CPPFLAGS = \
3-I$(top_srcdir)/src/include \ 3-I$(top_srcdir)/src/include \
4-I$(top_srcdir)/src/daemon/https/includes \ 4-I$(top_srcdir)/src/daemon/https \
5-I$(top_srcdir)/src/daemon/https/minitasn1 \ 5-I$(top_srcdir)/src/daemon/https/minitasn1 \
6-I$(top_srcdir)/src/daemon/https/lgl \ 6-I$(top_srcdir)/src/daemon/https/lgl \
7-I$(top_srcdir)/src/daemon/https/x509 \ 7-I$(top_srcdir)/src/daemon/https/x509 \
diff --git a/src/examples/Makefile.am b/src/examples/Makefile.am
index 802ba509..aed468b7 100644
--- a/src/examples/Makefile.am
+++ b/src/examples/Makefile.am
@@ -2,7 +2,7 @@ SUBDIRS = .
2 2
3AM_CPPFLAGS = \ 3AM_CPPFLAGS = \
4-I$(top_srcdir)/src/include \ 4-I$(top_srcdir)/src/include \
5-I$(top_srcdir)/src/daemon/https/includes 5-I$(top_srcdir)/src/daemon/https
6 6
7# example programs 7# example programs
8noinst_PROGRAMS = \ 8noinst_PROGRAMS = \
@@ -43,9 +43,5 @@ fileserver_example_external_select_LDADD = \
43 43
44https_server_example_SOURCES = \ 44https_server_example_SOURCES = \
45https_server_example.c 45https_server_example.c
46https_server_example_CPPFLAGS = \
47 -I$(top_srcdir)/src/daemon/https/includes \
48 -I$(top_srcdir)/src/daemon \
49 -I$(top_srcdir)/src/include
50https_server_example_LDADD = \ 46https_server_example_LDADD = \
51 $(top_builddir)/src/daemon/libmicrohttpd.la 47 $(top_builddir)/src/daemon/libmicrohttpd.la
diff --git a/src/examples/authorization_example.c b/src/examples/authorization_example.c
index 1e428148..9c7185e5 100644
--- a/src/examples/authorization_example.c
+++ b/src/examples/authorization_example.c
@@ -51,7 +51,7 @@ ahc_echo (void *cls,
51 struct MHD_Response *response; 51 struct MHD_Response *response;
52 int ret; 52 int ret;
53 int code; 53 int code;
54 const char * auth; 54 const char *auth;
55 55
56 if (0 != strcmp (method, "GET")) 56 if (0 != strcmp (method, "GET"))
57 return MHD_NO; /* unexpected method */ 57 return MHD_NO; /* unexpected method */
@@ -62,25 +62,24 @@ ahc_echo (void *cls,
62 return MHD_YES; 62 return MHD_YES;
63 } 63 }
64 *ptr = NULL; /* reset when done */ 64 *ptr = NULL; /* reset when done */
65 auth = MHD_lookup_connection_value(connection, 65 auth = MHD_lookup_connection_value (connection,
66 MHD_HEADER_KIND, 66 MHD_HEADER_KIND,
67 MHD_HTTP_HEADER_AUTHORIZATION); 67 MHD_HTTP_HEADER_AUTHORIZATION);
68 if ( (auth == NULL) || 68 if ((auth == NULL) ||
69 (0 != strcmp(auth, 69 (0 != strcmp (auth, "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==")))
70 "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==") ) )
71 { 70 {
72 /* require: "Aladdin" with password "open sesame" */ 71 /* require: "Aladdin" with password "open sesame" */
73 response = MHD_create_response_from_data (strlen (DENIED), 72 response = MHD_create_response_from_data (strlen (DENIED),
74 (void *) DENIED, MHD_NO, MHD_NO); 73 (void *) DENIED, MHD_NO,
75 MHD_add_response_header(response, 74 MHD_NO);
76 MHD_HTTP_HEADER_WWW_AUTHENTICATE, 75 MHD_add_response_header (response, MHD_HTTP_HEADER_WWW_AUTHENTICATE,
77 "Basic realm=\"TestRealm\""); 76 "Basic realm=\"TestRealm\"");
78 code = MHD_HTTP_UNAUTHORIZED; 77 code = MHD_HTTP_UNAUTHORIZED;
79 } 78 }
80 else 79 else
81 { 80 {
82 response = MHD_create_response_from_data (strlen (me), 81 response = MHD_create_response_from_data (strlen (me),
83 (void *) me, MHD_NO, MHD_NO); 82 (void *) me, MHD_NO, MHD_NO);
84 code = MHD_HTTP_OK; 83 code = MHD_HTTP_OK;
85 } 84 }
86 ret = MHD_queue_response (connection, code, response); 85 ret = MHD_queue_response (connection, code, response);
diff --git a/src/examples/https_server_example.c b/src/examples/https_server_example.c
index ce9ff9d7..0763f36d 100644
--- a/src/examples/https_server_example.c
+++ b/src/examples/https_server_example.c
@@ -18,12 +18,14 @@
18*/ 18*/
19/** 19/**
20 * @file https_server_example.c 20 * @file https_server_example.c
21 * @brief a simple https file server using TLS. 21 * @brief a simple HTTPS file server using TLS.
22 * 22 *
23 * This example assumes the existence of a private key file named "key.pem" 23 * Server may be supplied either with included hard coded certificates or using
24 * and a server certificate file named "cert.pem". File path for these should be 24 * external ones, which are to be supplied through command line arguments.
25 * provided as command-line arguments. 'certtool' may be used to generate these if 25 * A private key file named "key.pem" and a server certificate file named "cert.pem".
26 * missing. 26 * are necessary to run the server in this way.
27 *
28 * 'certtool' may be used to generate these if required.
27 * 29 *
28 * Access server with your browser of choice or with curl : 30 * Access server with your browser of choice or with curl :
29 * 31 *
@@ -33,7 +35,7 @@
33 */ 35 */
34 36
35#include "config.h" 37#include "config.h"
36#include <microhttpd.h> 38#include <microhttpsd.h>
37#include <sys/stat.h> 39#include <sys/stat.h>
38 40
39#include <stdlib.h> 41#include <stdlib.h>
@@ -167,8 +169,7 @@ main (int argc, char *const *argv)
167 if (argc < 5) 169 if (argc < 5)
168 { 170 {
169 printf 171 printf
170 ("Usage : %s HTTP-PORT SECONDS-TO-RUN HTTPS-PORT KEY-FILE CERT-FILE\n", 172 ("Usage : %s HTTP-PORT SECONDS-TO-RUN KEY-FILE CERT-FILE\n", argv[0]);
171 argv[0]);
172 return 1; 173 return 1;
173 } 174 }
174 175
diff --git a/src/include/microhttpsd.h b/src/include/microhttpsd.h
index 6620330d..cf85d3c6 100644
--- a/src/include/microhttpsd.h
+++ b/src/include/microhttpsd.h
@@ -133,6 +133,7 @@ union MHD_SessionInfo
133 gnutls_protocol_t protocol; 133 gnutls_protocol_t protocol;
134 gnutls_certificate_type_t certificate_type; 134 gnutls_certificate_type_t certificate_type;
135 gnutls_pk_algorithm_t pk_algorithm; 135 gnutls_pk_algorithm_t pk_algorithm;
136 int null_info;
136}; 137};
137 138
138enum MHD_InfoType 139enum MHD_InfoType
@@ -146,7 +147,7 @@ enum MHD_InfoType
146 MHD_INFO_CERT_TYPE, 147 MHD_INFO_CERT_TYPE,
147}; 148};
148 149
149union MHD_SessionInfo MHD_get_session_info (struct MHD_Connection *con, 150union MHD_SessionInfo MHD_get_tls_session_info (struct MHD_Connection *con,
150 enum MHD_InfoType infoType); 151 enum MHD_InfoType infoType);
151 152
152//TODO impl 153//TODO impl
diff --git a/src/testcurl/Makefile.am b/src/testcurl/Makefile.am
index 81d24c67..a95723dd 100644
--- a/src/testcurl/Makefile.am
+++ b/src/testcurl/Makefile.am
@@ -5,7 +5,7 @@ SUBDIRS += https
5endif 5endif
6 6
7AM_CPPFLAGS = \ 7AM_CPPFLAGS = \
8-I$(top_srcdir)/src/daemon/https/includes \ 8-I$(top_srcdir)/src/daemon/https \
9-I$(top_srcdir)/src/daemon \ 9-I$(top_srcdir)/src/daemon \
10-I$(top_srcdir)/src/include 10-I$(top_srcdir)/src/include
11 11
diff --git a/src/testcurl/https/Makefile.am b/src/testcurl/https/Makefile.am
index f9d3f80a..81b439fa 100644
--- a/src/testcurl/https/Makefile.am
+++ b/src/testcurl/https/Makefile.am
@@ -2,18 +2,27 @@ SUBDIRS = .
2 2
3AM_CPPFLAGS = \ 3AM_CPPFLAGS = \
4-I$(top_srcdir)/src/include \ 4-I$(top_srcdir)/src/include \
5-I$(top_srcdir)/src/daemon/https/includes \ 5-I$(top_srcdir)/src/daemon/https \
6-I$(top_srcdir)/src/daemon/https/tls \
7-I$(top_srcdir)/src/daemon/https/lgl \
8-I$(top_srcdir)/src/daemon/https/x509 \
6-I$(top_srcdir)/src/daemon 9-I$(top_srcdir)/src/daemon
7 10
8 11
9check_PROGRAMS = \ 12check_PROGRAMS = \
10 tls_authentication_test \
11 mhds_get_test \ 13 mhds_get_test \
12 mhds_session_info_test \ 14 tls_authentication_test \
13 mhds_multi_daemon_test 15 mhds_multi_daemon_test \
14 16 mhds_session_info_test
17
15TESTS = $(check_PROGRAMS) 18TESTS = $(check_PROGRAMS)
16 19
20tls_alert_test_SOURCES = \
21 tls_alert_test.c
22tls_alert_test_LDADD = \
23 $(top_builddir)/src/daemon/libmicrohttpd.la \
24 @LIBCURL@
25
17tls_authentication_test_SOURCES = \ 26tls_authentication_test_SOURCES = \
18 tls_authentication_test.c 27 tls_authentication_test.c
19tls_authentication_test_LDADD = \ 28tls_authentication_test_LDADD = \
diff --git a/src/testcurl/https/mhds_get_test.c b/src/testcurl/https/mhds_get_test.c
index fcbb8706..e92bf82c 100644
--- 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)
235 MHD_USE_DEBUG, 42433, 235 MHD_USE_DEBUG, 42433,
236 NULL, NULL, &http_ahc, NULL, 236 NULL, NULL, &http_ahc, NULL,
237 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem, 237 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
238 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, MHD_OPTION_END); 238 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
239 MHD_OPTION_END);
239 240
240 if (d == NULL) 241 if (d == NULL)
241 { 242 {
@@ -255,10 +256,13 @@ test_file_certificates (FILE * test_fd, char *cipher_suite, int proto_version)
255 int ret; 256 int ret;
256 struct MHD_Daemon *d; 257 struct MHD_Daemon *d;
257 FILE *cert_fd, *key_fd; 258 FILE *cert_fd, *key_fd;
258 char cert_path[255], key_path[255]; 259 char cert_path[255], key_path[255], *cur_dir;
260
261 cur_dir = get_current_dir_name ();
262
263 sprintf (cert_path, "%s/%s", cur_dir, "cert.pem");
264 sprintf (key_path, "%s/%s", cur_dir, "key.pem");
259 265
260 sprintf (cert_path, "%s/%s", get_current_dir_name (), "cert.pem");
261 sprintf (key_path, "%s/%s", get_current_dir_name (), "key.pem");
262 266
263 if (NULL == (key_fd = fopen (key_path, "w+"))) 267 if (NULL == (key_fd = fopen (key_path, "w+")))
264 { 268 {
@@ -272,7 +276,8 @@ test_file_certificates (FILE * test_fd, char *cipher_suite, int proto_version)
272 } 276 }
273 277
274 fwrite (srv_key_pem, strlen (srv_key_pem), sizeof (char), key_fd); 278 fwrite (srv_key_pem, strlen (srv_key_pem), sizeof (char), key_fd);
275 fwrite (srv_self_signed_cert_pem, strlen (srv_self_signed_cert_pem), sizeof (char), cert_fd); 279 fwrite (srv_self_signed_cert_pem, strlen (srv_self_signed_cert_pem),
280 sizeof (char), cert_fd);
276 fclose (key_fd); 281 fclose (key_fd);
277 fclose (cert_fd); 282 fclose (cert_fd);
278 283
@@ -292,6 +297,7 @@ test_file_certificates (FILE * test_fd, char *cipher_suite, int proto_version)
292 ret = test_daemon_get (test_fd, cipher_suite, proto_version); 297 ret = test_daemon_get (test_fd, cipher_suite, proto_version);
293 MHD_stop_daemon (d); 298 MHD_stop_daemon (d);
294 299
300 free (cur_dir);
295 remove (cert_path); 301 remove (cert_path);
296 remove (key_path); 302 remove (key_path);
297 return ret; 303 return ret;
@@ -412,6 +418,8 @@ main (int argc, char *const *argv)
412 FILE *test_fd; 418 FILE *test_fd;
413 unsigned int errorCount = 0; 419 unsigned int errorCount = 0;
414 420
421 // gnutls_global_set_log_level(11);
422
415 if ((test_fd = setupTestFile ()) == NULL) 423 if ((test_fd = setupTestFile ()) == NULL)
416 { 424 {
417 fprintf (stderr, MHD_E_TEST_FILE_CREAT); 425 fprintf (stderr, MHD_E_TEST_FILE_CREAT);
@@ -420,18 +428,16 @@ main (int argc, char *const *argv)
420 428
421 if (0 != curl_global_init (CURL_GLOBAL_ALL)) 429 if (0 != curl_global_init (CURL_GLOBAL_ALL))
422 { 430 {
423 fprintf (stderr, "Error (code: %u)\n", errorCount); 431 fprintf (stderr, "Error: %s\n", strerror (errno));
424 return -1; 432 return -1;
425 } 433 }
426 434
427 errorCount += 435 errorCount +=
428 test_secure_get (test_fd, "AES256-SHA", CURL_SSLVERSION_TLSv1); 436 test_secure_get (test_fd, "AES256-SHA", CURL_SSLVERSION_TLSv1);
429
430 errorCount += 437 errorCount +=
431 test_secure_get (test_fd, "AES256-SHA", CURL_SSLVERSION_SSLv3); 438 test_secure_get (test_fd, "AES256-SHA", CURL_SSLVERSION_SSLv3);
432 errorCount += 439 errorCount +=
433 test_file_certificates (test_fd, "AES256-SHA", CURL_SSLVERSION_TLSv1); 440 test_file_certificates (test_fd, "AES256-SHA", CURL_SSLVERSION_TLSv1);
434
435 /* TODO resolve cipher setting issue when compiling against GNU TLS */ 441 /* TODO resolve cipher setting issue when compiling against GNU TLS */
436 errorCount += 442 errorCount +=
437 test_cipher_option (test_fd, "DES-CBC3-SHA", CURL_SSLVERSION_SSLv3); 443 test_cipher_option (test_fd, "DES-CBC3-SHA", CURL_SSLVERSION_SSLv3);
@@ -439,9 +445,6 @@ main (int argc, char *const *argv)
439 test_kx_option (test_fd, "EDH-RSA-DES-CBC3-SHA", CURL_SSLVERSION_SSLv3); 445 test_kx_option (test_fd, "EDH-RSA-DES-CBC3-SHA", CURL_SSLVERSION_SSLv3);
440 446
441 447
442 if (errorCount != 0)
443 fprintf (stderr, "Error (code: %u)\n", errorCount);
444
445 curl_global_cleanup (); 448 curl_global_cleanup ();
446 fclose (test_fd); 449 fclose (test_fd);
447 450
diff --git a/src/testcurl/https/mhds_multi_daemon_test.c b/src/testcurl/https/mhds_multi_daemon_test.c
index c808405c..5d490d41 100644
--- 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,
236 MHD_USE_DEBUG, 42433, 236 MHD_USE_DEBUG, 42433,
237 NULL, NULL, &http_ahc, NULL, 237 NULL, NULL, &http_ahc, NULL,
238 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem, 238 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
239 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, MHD_OPTION_END); 239 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
240 MHD_OPTION_END);
240 241
241 if (d1 == NULL) 242 if (d1 == NULL)
242 { 243 {
@@ -248,7 +249,8 @@ test_concurent_daemon_pair (FILE * test_fd, char *cipher_suite,
248 MHD_USE_DEBUG, 42434, 249 MHD_USE_DEBUG, 42434,
249 NULL, NULL, &http_ahc, NULL, 250 NULL, NULL, &http_ahc, NULL,
250 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem, 251 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
251 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, MHD_OPTION_END); 252 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
253 MHD_OPTION_END);
252 254
253 if (d2 == NULL) 255 if (d2 == NULL)
254 { 256 {
diff --git a/src/testcurl/https/mhds_session_info_test.c b/src/testcurl/https/mhds_session_info_test.c
index 43315c0f..3b869913 100644
--- 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,
75 int ret; 75 int ret;
76 76
77 /* assert actual connection cipher is the one negotiated */ 77 /* assert actual connection cipher is the one negotiated */
78 if (MHD_get_session_info (connection,MHS_INFO_CIPHER_ALGO).cipher_algorithm != GNUTLS_CIPHER_AES_256_CBC) 78 if (MHD_get_tls_session_info (connection, MHS_INFO_CIPHER_ALGO).
79 cipher_algorithm != GNUTLS_CIPHER_AES_256_CBC)
79 { 80 {
80 fprintf (stderr, "Error: requested cipher mismatch. %s\n", 81 fprintf (stderr, "Error: requested cipher mismatch. %s\n",
81 strerror (errno)); 82 strerror (errno));
82 return -1; 83 return -1;
83 } 84 }
84 85
85 if (MHD_get_session_info (connection,MHD_INFO_KX_ALGO).kx_algorithm != GNUTLS_KX_RSA) 86 if (MHD_get_tls_session_info (connection, MHD_INFO_KX_ALGO).kx_algorithm !=
86 { 87 GNUTLS_KX_RSA)
87 fprintf (stderr, "Error: requested key exchange mismatch. %s\n", 88 {
88 strerror (errno)); 89 fprintf (stderr, "Error: requested key exchange mismatch. %s\n",
89 return -1; 90 strerror (errno));
90 } 91 return -1;
92 }
91 93
92 if (MHD_get_session_info (connection,MHD_INFO_MAC_ALGO).mac_algorithm != GNUTLS_MAC_SHA1) 94 if (MHD_get_tls_session_info (connection, MHD_INFO_MAC_ALGO).
95 mac_algorithm != GNUTLS_MAC_SHA1)
93 { 96 {
94 fprintf (stderr, "Error: requested mac algorithm mismatch. %s\n", 97 fprintf (stderr, "Error: requested mac algorithm mismatch. %s\n",
95 strerror (errno)); 98 strerror (errno));
96 return -1; 99 return -1;
97 } 100 }
98 101
99 if (MHD_get_session_info (connection,MHD_INFO_COMPRESSION_METHOD).compression_method != GNUTLS_COMP_NULL) 102 if (MHD_get_tls_session_info (connection, MHD_INFO_COMPRESSION_METHOD).
103 compression_method != GNUTLS_COMP_NULL)
100 { 104 {
101 fprintf (stderr, "Error: requested compression mismatch. %s\n", 105 fprintf (stderr, "Error: requested compression mismatch. %s\n",
102 strerror (errno)); 106 strerror (errno));
103 return -1; 107 return -1;
104 } 108 }
105 109
106 if (MHD_get_session_info (connection,MHD_INFO_PROTOCOL).protocol != GNUTLS_SSL3) 110 if (MHD_get_tls_session_info (connection, MHD_INFO_PROTOCOL).protocol !=
107 { 111 GNUTLS_SSL3)
108 fprintf (stderr, "Error: requested compression mismatch. %s\n", 112 {
109 strerror (errno)); 113 fprintf (stderr, "Error: requested compression mismatch. %s\n",
110 return -1; 114 strerror (errno));
111 } 115 return -1;
116 }
112 117
113 if (MHD_get_session_info (connection,MHD_INFO_CERT_TYPE).certificate_type != GNUTLS_CRT_X509) 118 if (MHD_get_tls_session_info (connection, MHD_INFO_CERT_TYPE).
119 certificate_type != GNUTLS_CRT_X509)
114 { 120 {
115 fprintf (stderr, "Error: requested certificate mismatch. %s\n", 121 fprintf (stderr, "Error: requested certificate mismatch. %s\n",
116 strerror (errno)); 122 strerror (errno));
117 return -1; 123 return -1;
118 } 124 }
119 125
120 if (MHD_get_session_info (connection,MHD_INFO_CREDENTIALS_TYPE).credentials_type != GNUTLS_CRD_CERTIFICATE) 126 if (MHD_get_tls_session_info (connection, MHD_INFO_CREDENTIALS_TYPE).
121 { 127 credentials_type != GNUTLS_CRD_CERTIFICATE)
122 fprintf (stderr, "Error: requested certificate mismatch. %s\n", 128 {
123 strerror (errno)); 129 fprintf (stderr, "Error: requested certificate mismatch. %s\n",
124 return -1; 130 strerror (errno));
125 } 131 return -1;
132 }
126 133
127 response = MHD_create_response_from_data (strlen (EMPTY_PAGE), 134 response = MHD_create_response_from_data (strlen (EMPTY_PAGE),
128 (void *) EMPTY_PAGE, 135 (void *) EMPTY_PAGE,
@@ -154,7 +161,8 @@ test_query_session ()
154 MHD_USE_DEBUG, 42433, 161 MHD_USE_DEBUG, 42433,
155 NULL, NULL, &query_session_ahc, NULL, 162 NULL, NULL, &query_session_ahc, NULL,
156 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem, 163 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
157 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem, MHD_OPTION_END); 164 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
165 MHD_OPTION_END);
158 166
159 if (d == NULL) 167 if (d == NULL)
160 return 2; 168 return 2;
diff --git a/src/testcurl/https/tls_alert_test.c b/src/testcurl/https/tls_alert_test.c
new file mode 100644
index 00000000..29d5559c
--- /dev/null
+++ b/src/testcurl/https/tls_alert_test.c
@@ -0,0 +1,188 @@
1/*
2 This file is part of libmicrohttpd
3 (C) 2007 Christian Grothoff
4
5 libmicrohttpd is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 libmicrohttpd is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with libmicrohttpd; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21/**
22 * @file mhds_get_test.c
23 * @brief Testcase for libmicrohttpd HTTPS GET operations
24 * @author Sagie Amir
25 */
26
27#include "config.h"
28#include "plibc.h"
29#include "microhttpsd.h"
30#include <errno.h>
31
32#include <curl/curl.h>
33#include <stdlib.h>
34#include <string.h>
35#include <time.h>
36#include <sys/stat.h>
37#include <sys/types.h>
38#include <sys/socket.h>
39#include <netinet/in.h>
40#include <fcntl.h>
41#include <unistd.h>
42
43
44#define MHD_E_MEM "Error: memory error\n"
45#define MHD_E_SERVER_INIT "Error: failed to start server\n"
46
47#include "gnutls_int.h"
48#include "gnutls_datum.h"
49#include "tls_test_keys.h"
50
51const char *ca_cert_file_name = "ca_cert_pem";
52const char *test_file_name = "https_test_file";
53const char test_file_data[] = "Hello World\n";
54
55struct CBC
56{
57 char *buf;
58 size_t pos;
59 size_t size;
60};
61
62static int
63file_reader (void *cls, size_t pos, char *buf, int max)
64{
65 FILE *file = cls;
66 fseek (file, pos, SEEK_SET);
67 return fread (buf, 1, max, file);
68}
69
70/* HTTP access handler call back */
71static int
72http_ahc (void *cls, struct MHD_Connection *connection,
73 const char *url, const char *method, const char *upload_data,
74 const char *version, unsigned int *upload_data_size, void **ptr)
75{
76 return 0;
77}
78
79static int
80test_alert_response ()
81{
82
83
84 int sd, ret;
85 char *err_pos;
86 struct sockaddr_in sa;
87 gnutls_priority_t priority_cache;
88 gnutls_session_t session;
89 gnutls_certificate_credentials_t xcred;
90
91
92 gnutls_global_init ();
93
94 gnutls_datum_t key;
95 gnutls_datum_t cert;
96
97
98 gnutls_certificate_allocate_credentials (&xcred);
99
100 _gnutls_set_datum_m (&key, srv_key_pem, strlen (srv_key_pem), &malloc);
101 _gnutls_set_datum_m (&cert, srv_self_signed_cert_pem,
102 strlen (srv_self_signed_cert_pem), &malloc);
103
104 gnutls_certificate_set_x509_key_mem (xcred, &cert, &key,
105 GNUTLS_X509_FMT_PEM);
106
107 ret = gnutls_priority_init (&priority_cache,
108 "NONE:+VERS-TLS1.0:+AES-256-CBC:+RSA:+SHA1:+COMP-NULL",
109 &err_pos);
110 if (ret < 0)
111 {
112 // ...
113 }
114
115 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
116
117 sd = socket (AF_INET, SOCK_STREAM, 0);
118 memset (&sa, '\0', sizeof (struct sockaddr_in));
119 sa.sin_family = AF_INET;
120 sa.sin_port = htons (42433);
121 inet_pton (AF_INET, "127.0.0.1", &sa.sin_addr);
122
123 ret = connect (sd, &sa, sizeof (struct sockaddr_in));
124
125 if (ret < 0)
126 {
127 // ...
128 }
129
130 ret = gnutls_handshake (session);
131
132 if (ret < 0)
133 {
134 // ...
135 }
136
137 gnutls_alert_send (session, GNUTLS_AL_FATAL, GNUTLS_A_CLOSE_NOTIFY);
138
139 /* check server responds with a 'close-notify' */
140 _gnutls_recv_int (session, GNUTLS_ALERT, GNUTLS_HANDSHAKE_FINISHED, 0, 0);
141
142 /* CLOSE_NOTIFY */
143 if (session->internals.last_alert != GNUTLS_A_CLOSE_NOTIFY)
144 {
145 return -1;
146 }
147
148 close (sd);
149
150 gnutls_deinit (session);
151
152 gnutls_certificate_free_credentials (xcred);
153
154 gnutls_global_deinit ();
155
156 return 0;
157
158}
159
160
161
162int
163main (int argc, char *const *argv)
164{
165 int ret, errorCount = 0;;
166 struct MHD_Daemon *d;
167
168 d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_SSL |
169 MHD_USE_DEBUG, 42433,
170 NULL, NULL, &http_ahc, NULL,
171 MHD_OPTION_HTTPS_MEM_KEY, srv_key_pem,
172 MHD_OPTION_HTTPS_MEM_CERT, srv_self_signed_cert_pem,
173 MHD_OPTION_END);
174
175 if (d == NULL)
176 {
177 fprintf (stderr, MHD_E_SERVER_INIT);
178 return -1;
179 }
180
181 errorCount += test_alert_response ();
182
183 if (errorCount != 0)
184 fprintf (stderr, "Error (code: %u)\n", errorCount);
185
186 MHD_stop_daemon (d);
187 return errorCount != 0;
188}