[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r6988 - in libmicrohttpd/src: daemon examples include
From: |
gnunet |
Subject: |
[GNUnet-SVN] r6988 - in libmicrohttpd/src: daemon examples include |
Date: |
Sun, 1 Jun 2008 20:11:54 -0600 (MDT) |
Author: lv-426
Date: 2008-06-01 20:11:51 -0600 (Sun, 01 Jun 2008)
New Revision: 6988
Modified:
libmicrohttpd/src/daemon/Makefile.am
libmicrohttpd/src/daemon/daemon.c
libmicrohttpd/src/daemon/internal.h
libmicrohttpd/src/examples/Makefile.am
libmicrohttpd/src/examples/https_server_example.c
libmicrohttpd/src/include/microhttpd.h
Log:
added X.509 parameters to the daemon struct
added https daemon creation functionality
https file server example [overriding existing echo server]
Modified: libmicrohttpd/src/daemon/Makefile.am
===================================================================
--- libmicrohttpd/src/daemon/Makefile.am 2008-06-02 02:03:03 UTC (rev
6987)
+++ libmicrohttpd/src/daemon/Makefile.am 2008-06-02 02:11:51 UTC (rev
6988)
@@ -11,8 +11,6 @@
lib_LTLIBRARIES = \
libmicrohttpd.la
-libmicrohttpd_la_LDFLAGS = \
- -export-dynamic -version-info 4:3:0 $(retaincommand)
libmicrohttpd_la_SOURCES = \
connection.c connection.h \
reason_phrase.c reason_phrase.h \
@@ -21,7 +19,13 @@
memorypool.c memorypool.h \
plibc.h \
postprocessor.c \
- response.c response.h
+ response.c response.h
+libmicrohttpd_la_LDFLAGS = \
+ -export-dynamic -version-info 4:3:0 $(retaincommand) \
+ -L$(GNUTLS_LIB_PATH) \
+ -lgnutls
+libmicrohttpd_la_CPPFLAGS = \
+ $(GNUTLS_CPPFLAGS)
check_PROGRAMS = \
postprocessor_test \
Modified: libmicrohttpd/src/daemon/daemon.c
===================================================================
--- libmicrohttpd/src/daemon/daemon.c 2008-06-02 02:03:03 UTC (rev 6987)
+++ libmicrohttpd/src/daemon/daemon.c 2008-06-02 02:11:51 UTC (rev 6988)
@@ -29,6 +29,7 @@
#include "response.h"
#include "connection.h"
#include "memorypool.h"
+#include <gnutls/gnutls.h>
/**
* Default connection limit.
@@ -52,6 +53,12 @@
*/
#define DEBUG_CONNECT MHD_NO
+// TODO rm
+/* HTTPS file path limit, leaving room for file name */
+#define MHD_PATH_LEN 240
+
+int MHDS_init (struct MHD_Daemon *daemon);
+
/**
* Obtain the select sets for this daemon.
*
@@ -174,6 +181,8 @@
if (con == NULL)
abort ();
+ // TODO add connection time out code
+
/* forward call to handler */
con->daemon->default_handler (NULL, con, NULL, NULL, NULL, NULL, NULL,
NULL);
@@ -690,6 +699,13 @@
retVal->pool_size = MHD_POOL_SIZE_DEFAULT;
retVal->connection_timeout = 0; /* no timeout */
+ /* set server default document root path */
+ getcwd (retVal->doc_root, MHD_PATH_LEN);
+
+ /* initialize ssl path parameters to the local path */
+ strcpy (retVal->https_cert_path, "cert.pem");
+ strcpy (retVal->https_key_path, "key.pem");
+
/* initializes the argument pointer variable */
va_start (ap, dh_cls);
@@ -717,6 +733,22 @@
case MHD_OPTION_PER_IP_CONNECTION_LIMIT:
retVal->per_ip_connection_limit = va_arg (ap, unsigned int);
break;
+ case MHD_OPTION_DOC_ROOT:
+ strncpy (retVal->doc_root, va_arg (ap, char *), MHD_PATH_LEN);
+ break;
+ case MHD_OPTION_HTTPS_KEY_PATH:
+ strncpy (retVal->https_key_path, va_arg (ap, char *), MHD_PATH_LEN);
+ strcat (retVal->https_key_path, DIR_SEPARATOR_STR);
+ strcat (retVal->https_key_path, "key.pem");
+ break;
+ case MHD_OPTION_HTTPS_CERT_PATH:
+
+ strncpy (retVal->https_cert_path,
+ va_arg (ap, char *), MHD_PATH_LEN);
+ strcat (retVal->https_cert_path, DIR_SEPARATOR_STR);
+ strcat (retVal->https_cert_path, "cert.pem");
+ break;
+
default:
#if HAVE_MESSAGES
fprintf (stderr,
@@ -725,6 +757,29 @@
abort ();
}
}
+
+ /* initialize HTTPS daemon certificate aspects */
+ if (options & MHD_USE_SSL)
+ {
+ /* test for private key & certificate file exsitance */
+ FILE *cert_file = fopen (retVal->https_cert_path, "r");
+ FILE *key_file = fopen (retVal->https_key_path, "r");
+ if (key_file == NULL || cert_file == NULL)
+ {
+ printf ("missing cert files");
+#if HAVE_MESSAGES
+ MHD_DLOG (retVal, "Missing X.509 key or certificate file\n");
+#endif
+ free (retVal);
+ CLOSE (socket_fd);
+ return NULL;
+ }
+
+ fclose (cert_file);
+ fclose (key_file);
+ MHDS_init (retVal);
+ }
+
va_end (ap);
if (((0 != (options & MHD_USE_THREAD_PER_CONNECTION)) || (0 != (options
&
@@ -793,9 +848,51 @@
}
MHD_cleanup_connections (daemon);
}
+
+ /* TLS clean up */
+ if (daemon->options & MHD_USE_SSL)
+ {
+ gnutls_priority_deinit (daemon->priority_cache);
+ gnutls_global_deinit ();
+ }
+
free (daemon);
}
+int
+MHDS_init (struct MHD_Daemon *daemon)
+{
+ gnutls_global_init ();
+ /* Generate Diffie Hellman parameters - for use with DHE kx algorithms. */
+ gnutls_dh_params_init (&daemon->dh_params);
+ gnutls_dh_params_generate2 (daemon->dh_params, DH_BITS);
+
+ // TODO make room for cipher settings adjustment
+ gnutls_priority_init (&daemon->priority_cache,
+ "NORMAL:+AES-256-CBC:+RSA:+SHA1:+COMP-NULL", NULL);
+
+ /* setup server certificate */
+ gnutls_certificate_allocate_credentials (&daemon->x509_cret);
+
+ // TODO remove if unused
+ /* add trusted CAs to certificate */
+ // gnutls_certificate_set_x509_trust_file(x509_cret,
CAFILE,GNUTLS_X509_FMT_PEM);
+
+ /* add Certificate revocation list to certificate */
+ //gnutls_certificate_set_x509_crl_file(x509_cret, CRLFILE,
GNUTLS_X509_FMT_PEM);
+
+ /* sets a certificate private key pair */
+ gnutls_certificate_set_x509_key_file (daemon->x509_cret,
+ daemon->https_cert_path,
+ daemon->https_key_path,
+ GNUTLS_X509_FMT_PEM);
+
+ gnutls_certificate_set_dh_params (daemon->x509_cret, daemon->dh_params);
+
+ // TODO address error case return value
+ return 0;
+}
+
#ifndef WINDOWS
static struct sigaction sig;
Modified: libmicrohttpd/src/daemon/internal.h
===================================================================
--- libmicrohttpd/src/daemon/internal.h 2008-06-02 02:03:03 UTC (rev 6987)
+++ libmicrohttpd/src/daemon/internal.h 2008-06-02 02:11:51 UTC (rev 6988)
@@ -35,6 +35,7 @@
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
+#include <gnutls/gnutls.h>
#include "config.h"
#include "plibc.h"
@@ -58,6 +59,9 @@
*/
#define MHD_BUF_INC_SIZE 2048
+/* TLS Diffie-Hellman parameter */
+#define DH_BITS 1024
+
#if HAVE_MESSAGES
/**
* fprintf-like helper function for logging debug
@@ -606,6 +610,22 @@
*/
unsigned short port;
+ /* server credintials */
+ gnutls_certificate_credentials_t x509_cret;
+
+ /* cipher priority cache */
+ gnutls_priority_t priority_cache;
+
+ /* Diffie-Hellman parameters */
+ gnutls_dh_params_t dh_params;
+
+ // TODO consider switching to variadic length paths
+ /* server root path used while serving http pages */
+ char doc_root[255];
+
+ char https_key_path[255];
+
+ char https_cert_path[255];
};
#endif
Modified: libmicrohttpd/src/examples/Makefile.am
===================================================================
--- libmicrohttpd/src/examples/Makefile.am 2008-06-02 02:03:03 UTC (rev
6987)
+++ libmicrohttpd/src/examples/Makefile.am 2008-06-02 02:11:51 UTC (rev
6988)
@@ -6,6 +6,7 @@
noinst_PROGRAMS = \
https_server_example \
+https_echo_server_example \
https_echo_client_example \
minimal_example \
querystring_example \
@@ -43,6 +44,18 @@
https_server_example_LDFLAGS = \
-L$(GNUTLS_LIB_PATH) \
-lgnutls
+
+https_echo_server_example_CPPFLAGS = \
+ $(GNUTLS_CPPFLAGS) \
+ -I$(top_srcdir)/src/daemon \
+ -I$(top_srcdir)/src/include
+https_echo_server_example_SOURCES = \
+ https_echo_server_example.c
+https_echo_server_example_LDADD = \
+ $(top_builddir)/src/daemon/libmicrohttpd.la
+https_echo_server_example_LDFLAGS = \
+ -L$(GNUTLS_LIB_PATH) \
+ -lgnutls
https_echo_client_example_CPPFLAGS = \
$(GNUTLS_CPPFLAGS) \
Modified: libmicrohttpd/src/examples/https_server_example.c
===================================================================
--- libmicrohttpd/src/examples/https_server_example.c 2008-06-02 02:03:03 UTC
(rev 6987)
+++ libmicrohttpd/src/examples/https_server_example.c 2008-06-02 02:11:51 UTC
(rev 6988)
@@ -20,7 +20,17 @@
/**
* @file https_server_example.c
- * @brief a simple echo server using TLS. echo input from client until 'exit'
message is received.
+ * @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.
+ *
+ * Access server with your browser of choice or with curl :
+ *
+ * curl --insecure --tlsv1 --ciphers AES256-SHA <url>
+ *
* @author LV-426
*/
@@ -35,64 +45,76 @@
#include <string.h>
#include <stdio.h>
#include <gnutls/gnutls.h>
+#include <gcrypt.h>
-#define DH_BITS 1024
-#define MAX_BUF 1024
-/* server credintials */
-gnutls_anon_server_credentials_t anoncred;
+#define BUF_SIZE 1024
+#define MAX_URL_LEN 255
-/* server Diffie-Hellman parameters */
-static gnutls_dh_params_t dh_params;
+#define KEYFILE "key.pem"
+#define CERTFILE "cert.pem"
+// TODO remove if unused
+#define CAFILE "ca.pem"
+#define CRLFILE "crl.pem"
-/* Generate Diffie Hellman parameters - for use with DHE kx algorithms. */
-static int
-generate_dh_params (void)
-{
+#define PAGE_NOT_FOUND "<html><head><title>File not
found</title></head><body>File not found</body></html>"
- gnutls_dh_params_init (&dh_params);
- gnutls_dh_params_generate2 (dh_params, DH_BITS);
- return 0;
-}
-
gnutls_session_t
-initialize_tls_session (void)
+initialize_tls_session (struct MHD_Connection *connection)
{
gnutls_session_t session;
gnutls_init (&session, GNUTLS_SERVER);
- gnutls_priority_set_direct (session, "NORMAL:+ANON-DH", NULL);
+ /* sets cipher priorities */
+ gnutls_priority_set (session, connection->daemon->priority_cache);
- gnutls_credentials_set (session, GNUTLS_CRD_ANON, anoncred);
+ /* set needed credentials for certificate authentication. */
+ gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE,
+ connection->daemon->x509_cret);
- gnutls_dh_set_prime_bits (session, DH_BITS);
-
return session;
}
-/* Accept Policy Callback */
static int
-TLS_echo (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)
+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);
+}
+
+/* HTTPS access handler call back */
+static int
+https_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)
+{
+ /* loopback HTTP socket */
+ int loopback_sd, err;
+ ssize_t ret;
+ struct sockaddr_in servaddr4;
+ const struct sockaddr *servaddr;
+ struct sockaddr_in loopback_sa;
+ socklen_t addrlen;
+
gnutls_session_t session;
static int aptr;
struct MHD_Response *response;
- char buffer[MAX_BUF + 1];
- int ret;
+ char buffer[BUF_SIZE];
printf ("accepted connection from %d\n", connection->addr->sin_addr);
- session = initialize_tls_session ();
+ session = initialize_tls_session (connection);
gnutls_transport_set_ptr (session, connection->socket_fd);
ret = gnutls_handshake (session);
+
if (ret < 0)
{
/* set connection as closed */
@@ -106,77 +128,182 @@
printf ("TLS Handshake completed\n");
connection->state = MHDS_HANDSHAKE_COMPLETE;
- /* simple echo loop. message encryption/decryption is acheived through
'gnutls_record_send'
- * & gnutls_record_recv calls. */
+ /* initialize loopback socket */
+ loopback_sd = socket (AF_INET, SOCK_STREAM, 0);
+ memset (&loopback_sa, '\0', sizeof (loopback_sa));
+ loopback_sa.sin_family = AF_INET;
+
+ // TODO solve magic number issue - the http's daemons port must be shared
with the https daemon - rosolve data sharing point
+ loopback_sa.sin_port = htons (50000);
+ inet_pton (AF_INET, "127.0.0.1", &loopback_sa.sin_addr);
+
+ /* connect loopback socket */
+ err = connect (loopback_sd, (struct sockaddr *) &loopback_sa,
+ sizeof (loopback_sa));
+ if (err < 0)
+ {
+ // TODO err handle
+ fprintf (stderr, "Error : failed to create TLS loopback socket\n");
+ exit (1);
+ }
+
+ /*
+ * This loop pipes data received through the TLS tunnel into the loopback
connection.
+ * message encryption/decryption is acheived via 'gnutls_record_send' &
gnutls_record_recv calls.
+ */
+ memset (buffer, 0, BUF_SIZE);
+ if (gnutls_record_recv (session, buffer, BUF_SIZE) < 0)
+ {
+ fprintf (stderr, "\n*** Received corrupted "
+ "data(%d). Closing the connection.\n\n", ret);
+ connection->socket_fd = -1;
+ gnutls_deinit (session);
+ return MHD_NO;
+ }
+
+ if (write (loopback_sd, buffer, BUF_SIZE) < 0)
+ {
+ printf ("failed to write to TLS loopback socket\n");
+ connection->socket_fd = -1;
+ gnutls_deinit (session);
+ return MHD_NO;
+ }
+
for (;;)
{
- memset (buffer, 0, MAX_BUF + 1);
- ret = gnutls_record_recv (session, buffer, MAX_BUF);
+ memset (buffer, 0, BUF_SIZE);
+ ret = read (loopback_sd, buffer, BUF_SIZE);
+
if (ret < 0)
{
- fprintf (stderr, "\n*** Received corrupted "
- "data(%d). Closing the connection.\n\n", ret);
+ printf ("failed to read from TLS loopback socket\n");
break;
}
- else if (ret >= 0)
+
+ if (ret == 0)
{
- if (strcmp (buffer, "exit") == 0)
- {
- printf ("\n- Peer has closed the GNUTLS connection\n");
- break;
- }
- else
- {
- /* echo data back to the client */
- gnutls_record_send (session, buffer, strlen (buffer));
- }
+ break;
}
+
+ /* echo data back to the client */
+ ret = gnutls_record_send (session, buffer, ret);
+ if (ret < 0)
+ {
+ printf ("failed to write to TLS socket\n");
+ break;
+ }
}
- printf ("\n");
-
/* mark connection as closed */
connection->socket_fd = -1;
-
gnutls_deinit (session);
+ return MHD_YES;
+}
+
+/* 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)
+{
+ static int aptr;
+ static char full_url[MAX_URL_LEN];
+ struct MHD_Response *response;
+ int ret;
+ FILE *file;
+ struct stat buf;
+
+ if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
+ return MHD_NO; /* unexpected method */
+ if (&aptr != *ptr)
+ {
+ /* do never respond on first call */
+ *ptr = &aptr;
+ return MHD_YES;
+ }
+ *ptr = NULL; /* reset when done */
+
+ /* assemble full url */
+ strcpy (full_url, connection->daemon->doc_root);
+ strncat (full_url, url,
+ MAX_URL_LEN - strlen (connection->daemon->doc_root) - 1);
+
+ file = fopen (full_url, "r");
+ if (file == NULL)
+ {
+ response = MHD_create_response_from_data (strlen (PAGE_NOT_FOUND),
+ (void *) PAGE_NOT_FOUND,
+ MHD_NO, MHD_NO);
+ ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
+ MHD_destroy_response (response);
+ }
+ else
+ {
+ stat (&url[1], &buf);
+ response = MHD_create_response_from_callback (buf.st_size, 32 * 1024,
/* 32k PAGE_NOT_FOUND size */
+ &file_reader, file,
+
(MHD_ContentReaderFreeCallback)
+ & fclose);
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ MHD_destroy_response (response);
+ }
return ret;
}
int
main (int argc, char *const *argv)
{
- struct MHD_Daemon *daemon;
+ char keyfile[255] = KEYFILE;
+ char certfile[255] = CERTFILE;
+ struct MHD_Daemon *HTTP_daemon;
struct MHD_Daemon *TLS_daemon;
- /* look for HTTPS port argument */
- if (argc < 4)
+ /* look for HTTPS arguments */
+ if (argc < 5)
{
- printf ("Usage : %s HTTP-PORT SECONDS-TO-RUN HTTPS-PORT\n", argv[0]);
+ printf
+ ("Usage : %s HTTP-PORT SECONDS-TO-RUN HTTPS-PORT X.509_FILE_PATH\n",
+ argv[0]);
return 1;
}
- gnutls_global_init ();
+ // TODO check if this is truly necessary - disallow usage of the blocking
/dev/random */
+ // gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0);
- gnutls_anon_allocate_server_credentials (&anoncred);
+ HTTP_daemon =
+ MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG,
+ atoi (argv[1]), NULL, NULL, &http_ahc, MHD_OPTION_END);
- generate_dh_params ();
+ if (HTTP_daemon == NULL)
+ {
+ printf ("Error: failed to start HTTP_daemon");
+ return 1;
+ }
- gnutls_anon_set_server_dh_params (anoncred, dh_params);
-
- TLS_daemon = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
- | MHD_USE_DEBUG | MHD_USE_SSL,
- atoi (argv[3]), NULL, NULL, &TLS_echo, NULL,
+ TLS_daemon = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG
+ | MHD_USE_SSL, atoi (argv[3]),
+ NULL,
+ NULL, &https_ahc,
+ NULL, MHD_OPTION_CONNECTION_TIMEOUT, 256,
+ MHD_OPTION_HTTPS_KEY_PATH, argv[4],
+ MHD_OPTION_HTTPS_CERT_PATH, argv[4],
MHD_OPTION_END);
if (TLS_daemon == NULL)
- return 1;
+ {
+ printf ("Error: failed to start TLS_daemon");
+ return 1;
+ }
+
sleep (atoi (argv[2]));
- MHD_stop_daemon (daemon);
+ MHD_stop_daemon (HTTP_daemon);
- gnutls_anon_free_server_credentials (anoncred);
+ MHD_stop_daemon (TLS_daemon);
- gnutls_global_deinit ();
return 0;
}
Modified: libmicrohttpd/src/include/microhttpd.h
===================================================================
--- libmicrohttpd/src/include/microhttpd.h 2008-06-02 02:03:03 UTC (rev
6987)
+++ libmicrohttpd/src/include/microhttpd.h 2008-06-02 02:11:51 UTC (rev
6988)
@@ -345,6 +345,14 @@
*/
MHD_OPTION_PER_IP_CONNECTION_LIMIT = 5,
+ /* server root path used while serving http pages */
+ MHD_OPTION_DOC_ROOT = 6,
+
+ /* private key path used by the HTTPS daemon */
+ MHD_OPTION_HTTPS_KEY_PATH = 7,
+
+ /* certificate path used by the HTTPS daemon */
+ MHD_OPTION_HTTPS_CERT_PATH = 8,
};
/**
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r6988 - in libmicrohttpd/src: daemon examples include,
gnunet <=