- switched to hard coded certificates

This commit is contained in:
lv-426
2008-07-02 00:51:22 +00:00
parent 7012df14ef
commit fc861fda8e
9 changed files with 149 additions and 344 deletions
+1
View File
@@ -257,6 +257,7 @@ src/daemon/https/minitasn1/Makefile
src/daemon/https/includes/Makefile
src/examples/Makefile
src/testcurl/Makefile
src/testcurl/https/Makefile
src/testzzuf/Makefile])
AC_OUTPUT
+2 -1
View File
@@ -1,4 +1,5 @@
AM_CPPFLAGS = -I$(top_srcdir)/src/include \
AM_CPPFLAGS = \
-I$(top_srcdir)/src/include \
-I$(top_srcdir)/src/daemon \
-I$(top_srcdir)/src/daemon/https/lgl \
-I$(top_srcdir)/src/daemon/https/x509 \
+62 -34
View File
@@ -220,7 +220,7 @@ MHDS_handle_connection (void *data)
con->daemon->x509_cret);
/* avoid gnutls blocking recv / write calls */
// gnutls_transport_set_pull_function(tls_session, &recv);
gnutls_transport_set_pull_function(tls_session, &recv);
// gnutls_transport_set_push_function(tls_session, &send);
gnutls_transport_set_ptr (tls_session, con->socket_fd);
@@ -786,14 +786,10 @@ MHD_start_daemon (unsigned int options,
retVal->pool_size = MHD_POOL_SIZE_DEFAULT;
retVal->connection_timeout = 0; /* no timeout */
/* initialize ssl path parameters to the local path */
retVal->https_cert_path = "cert.pem";
retVal->https_key_path = "key.pem";
/* initializes the argument pointer variable */
va_start (ap, dh_cls);
/*
* loop through daemon options
* loop through daemon options
*/
while (MHD_OPTION_END != (opt = va_arg (ap, enum MHD_OPTION)))
{
@@ -817,10 +813,16 @@ MHD_start_daemon (unsigned int options,
retVal->per_ip_connection_limit = va_arg (ap, unsigned int);
break;
case MHD_OPTION_HTTPS_KEY_PATH:
retVal->https_key_path = va_arg (ap, const char *);
retVal->https_key_path = va_arg (ap, const char *);
break;
case MHD_OPTION_HTTPS_CERT_PATH:
retVal->https_cert_path = va_arg (ap, const char* );
retVal->https_cert_path = va_arg (ap, const char *);
break;
case MHD_OPTION_HTTPS_MEM_KEY:
retVal->https_mem_key = va_arg (ap, const char *);
break;
case MHD_OPTION_HTTPS_MEM_CERT:
retVal->https_mem_cert = va_arg (ap, const char *);
break;
default:
#if HAVE_MESSAGES
@@ -832,25 +834,13 @@ MHD_start_daemon (unsigned int options,
}
#if HTTPS_SUPPORT
/* initialize HTTPS daemon certificate aspects & send / recv functions */
if (options & MHD_USE_SSL)
if (options & MHD_USE_SSL && MHD_NO == MHDS_init (retVal))
{
/* 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");
MHD_DLOG (retVal, "Failed to initialize MHDS\n", STRERROR (errno));
#endif
free (retVal);
CLOSE (socket_fd);
return NULL;
}
fclose (cert_file);
fclose (key_file);
MHDS_init (retVal);
free (retVal);
return NULL;
}
#endif
va_end (ap);
@@ -923,13 +913,13 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
}
/* TLS clean up */
#if HTTPS_SUPPORT
#if HTTPS_SUPPORT
if (daemon->options & MHD_USE_SSL)
{
gnutls_priority_deinit (daemon->priority_cache);
gnutls_global_deinit ();
}
#endif
#endif
free (daemon);
}
@@ -952,13 +942,13 @@ MHDS_init (struct MHD_Daemon *daemon)
gnutls_global_init ();
/* Generate Diffie Hellman parameters - for use with DHE kx algorithms. */
// TODO should we be initializing RSA params or DH params ?
// TODO should we be initializing RSA params or DH params ?
gnutls_dh_params_init (&daemon->dh_params);
gnutls_dh_params_generate2 (daemon->dh_params, DH_BITS);
// TODO rm NONE:+AES-256-CBC:+RSA:+SHA1:+COMP-NULL", NULL);
gnutls_priority_init (&daemon->priority_cache,
"NONE:+AES-256-CBC:+RSA:+SHA1:+COMP-NULL",
NULL);
"NONE:+AES-256-CBC:+RSA:+SHA1:+COMP-NULL", NULL);
/* setup server certificate */
gnutls_certificate_allocate_credentials (&daemon->x509_cret);
@@ -971,15 +961,53 @@ MHDS_init (struct MHD_Daemon *daemon)
//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);
if (daemon->https_cert_path && daemon->https_key_path )
{
/* test for private key & certificate file exsitance */
FILE *cert_file = fopen (daemon->https_cert_path, "r");
FILE *key_file = fopen (daemon->https_key_path, "r");
if (key_file == NULL || cert_file == NULL)
{
printf ("missing cert files");
#if HAVE_MESSAGES
MHD_DLOG (daemon, "Missing X.509 key or certificate file\n");
#endif
free (daemon);
CLOSE (daemon->socket_fd);
return NULL;
}
fclose (cert_file);
fclose (key_file);
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 )
{
// TODO free
gnutls_datum_t * key = ( gnutls_datum_t * ) malloc (sizeof(gnutls_datum_t));
gnutls_datum_t * cert = ( gnutls_datum_t * ) malloc (sizeof(gnutls_datum_t));
_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);
printf("");
}
else
{
#if HAVE_MESSAGES
MHD_DLOG (daemon, "Failed to load certificate\n");
#endif
return MHD_NO;
}
gnutls_certificate_set_dh_params (daemon->x509_cret, daemon->dh_params);
// TODO address error case return value
return 0;
return MHD_YES;
}
#endif
+13 -13
View File
@@ -227,7 +227,7 @@ extern "C"
*/
/* Those are extra information about the verification
* process. Will be set only if the certificate was
* process. Will be set only if the certificate was
* not verified.
*/
GNUTLS_CERT_SIGNER_NOT_FOUND = 64,
@@ -494,7 +494,7 @@ extern "C"
const char *gnutls_supplemental_get_name
(gnutls_supplemental_data_format_type_t type);
/* functions to set priority of cipher suites
/* functions to set priority of cipher suites
*/
int gnutls_cipher_set_priority (gnutls_session_t session, const int *list);
int gnutls_mac_set_priority (gnutls_session_t session, const int *list);
@@ -510,7 +510,7 @@ extern "C"
*/
int gnutls_priority_init( gnutls_priority_t*, const char *priority, const char** err_pos);
void gnutls_priority_deinit( gnutls_priority_t);
int gnutls_priority_set(gnutls_session_t session, gnutls_priority_t);
int gnutls_priority_set_direct(gnutls_session_t session, const char *priority, const char** err_pos);
@@ -533,7 +533,7 @@ extern "C"
const char *gnutls_protocol_get_name (gnutls_protocol_t version);
/* get/set session
/* get/set session
*/
int gnutls_session_set_data (gnutls_session_t session,
const void *session_data,
@@ -548,7 +548,7 @@ extern "C"
int gnutls_session_get_id (gnutls_session_t session, void *session_id,
size_t * session_id_size);
/* returns security values.
/* returns security values.
* Do not use them unless you know what you're doing.
*/
#define TLS_MASTER_SIZE 48
@@ -557,7 +557,7 @@ extern "C"
const void *gnutls_session_get_client_random (gnutls_session_t session);
const void *gnutls_session_get_master_secret (gnutls_session_t session);
/* checks if this session is a resumed one
/* checks if this session is a resumed one
*/
int gnutls_session_is_resumed (gnutls_session_t session);
@@ -583,7 +583,7 @@ extern "C"
typedef int (*gnutls_handshake_post_client_hello_func)(gnutls_session_t);
void gnutls_handshake_set_post_client_hello_function(gnutls_session_t,
gnutls_handshake_post_client_hello_func);
void gnutls_handshake_set_max_packet_length (gnutls_session_t session,
size_t max);
@@ -684,7 +684,7 @@ extern "C"
void gnutls_certificate_send_x509_rdn_sequence (gnutls_session_t session,
int status);
extern int
gnutls_certificate_set_x509_simple_pkcs12_file
@@ -769,7 +769,7 @@ extern "C"
int gnutls_dh_params_cpy (gnutls_dh_params_t dst, gnutls_dh_params_t src);
/* RSA params
/* RSA params
*/
int gnutls_rsa_params_init (gnutls_rsa_params_t * rsa_params);
void gnutls_rsa_params_deinit (gnutls_rsa_params_t rsa_params);
@@ -825,7 +825,7 @@ extern "C"
void gnutls_transport_set_errno (gnutls_session_t session, int err);
void gnutls_transport_set_global_errno (int err);
/* session specific
/* session specific
*/
void gnutls_session_set_ptr (gnutls_session_t session, void *ptr);
void *gnutls_session_get_ptr (gnutls_session_t session);
@@ -833,7 +833,7 @@ extern "C"
void gnutls_openpgp_send_cert (gnutls_session_t session,
gnutls_openpgp_crt_status_t status);
/* fingerprint
/* fingerprint
* Actually this function returns the hash of the given data.
*/
int gnutls_fingerprint (gnutls_digest_algorithm_t algo,
@@ -841,7 +841,7 @@ extern "C"
size_t * result_size);
/* SRP
/* SRP
*/
typedef struct gnutls_srp_server_credentials_st
@@ -1117,7 +1117,7 @@ extern "C"
gnutls_datum_t * result);
int gnutls_global_init (void);
/* key_usage will be an OR of the following values:
*/
+7 -3
View File
@@ -308,7 +308,7 @@ enum MHDS_CONNECTION_STATE
/* while receiving an HTTP request through the encrypted channel */
MHDS_REPLY_SENDING,
MHDS_REPLY_SENT,
MHDS_CONNECTION_CLOSED
@@ -549,7 +549,7 @@ struct MHD_Connection
int (*idle_handler) (struct MHD_Connection * connection);
/*
/*
* function pointers to the appropriate send & receive funtions
* according to whether this is a HTTPS / HTTP daemon
*/
@@ -586,7 +586,7 @@ struct MHD_Daemon
/**
* Linked list of our current connections.
*/
// TODO switch to a dedicated tls connection struct
// TODO switch to a dedicated tls connection struct
struct MHD_Connection *tls_connections;
MHD_AcceptPolicyCallback apc;
@@ -657,6 +657,10 @@ struct MHD_Daemon
const char * https_key_path;
const char * https_cert_path;
const char * https_mem_key;
const char * https_mem_cert;
#endif
};
+36 -9
View File
@@ -50,16 +50,45 @@
#define BUF_SIZE 1024
#define MAX_URL_LEN 255
#define KEYFILE "key.pem"
#define CERTFILE "cert.pem"
// TODO remove if unused
#define CAFILE "ca.pem"
#define CRLFILE "crl.pem"
#define PAGE_NOT_FOUND "<html><head><title>File not found</title></head><body>File not found</body></html>"
/* Test Certificate */
const char cert_pem[] =
"-----BEGIN CERTIFICATE-----\n"
"MIICHjCCAYmgAwIBAgIERiYdNzALBgkqhkiG9w0BAQUwGTEXMBUGA1UEAxMOR251\n"
"VExTIHRlc3QgQ0EwHhcNMDcwNDE4MTMyOTI3WhcNMDgwNDE3MTMyOTI3WjAdMRsw\n"
"GQYDVQQDExJHbnVUTFMgdGVzdCBjbGllbnQwgZwwCwYJKoZIhvcNAQEBA4GMADCB\n"
"iAKBgLtmQ/Xyxde2jMzF3/WIO7HJS2oOoa0gUEAIgKFPXKPQ+GzP5jz37AR2ExeL\n"
"ZIkiW8DdU3w77XwEu4C5KL6Om8aOoKUSy/VXHqLnu7czSZ/ju0quak1o/8kR4jKN\n"
"zj2AC41179gAgY8oBAOgIo1hBAf6tjd9IQdJ0glhaZiQo1ipAgMBAAGjdjB0MAwG\n"
"A1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDwYDVR0PAQH/BAUDAweg\n"
"ADAdBgNVHQ4EFgQUTLkKm/odNON+3svSBxX+odrLaJEwHwYDVR0jBBgwFoAU6Twc\n"
"+62SbuYGpFYsouHAUyfI8pUwCwYJKoZIhvcNAQEFA4GBALujmBJVZnvaTXr9cFRJ\n"
"jpfc/3X7sLUsMvumcDE01ls/cG5mIatmiyEU9qI3jbgUf82z23ON/acwJf875D3/\n"
"U7jyOsBJ44SEQITbin2yUeJMIm1tievvdNXBDfW95AM507ShzP12sfiJkJfjjdhy\n"
"dc8Siq5JojruiMizAf0pA7in\n" "-----END CERTIFICATE-----\n";
const char key_pem[] =
"-----BEGIN RSA PRIVATE KEY-----\n"
"MIICXAIBAAKBgQC7ZkP18sXXtozMxd/1iDuxyUtqDqGtIFBACIChT1yj0Phsz+Y8\n"
"9+wEdhMXi2SJIlvA3VN8O+18BLuAuSi+jpvGjqClEsv1Vx6i57u3M0mf47tKrmpN\n"
"aP/JEeIyjc49gAuNde/YAIGPKAQDoCKNYQQH+rY3fSEHSdIJYWmYkKNYqQIDAQAB\n"
"AoGADpmARG5CQxS+AesNkGmpauepiCz1JBF/JwnyiX6vEzUh0Ypd39SZztwrDxvF\n"
"PJjQaKVljml1zkJpIDVsqvHdyVdse8M+Qn6hw4x2p5rogdvhhIL1mdWo7jWeVJTF\n"
"RKB7zLdMPs3ySdtcIQaF9nUAQ2KJEvldkO3m/bRJFEp54k0CQQDYy+RlTmwRD6hy\n"
"7UtMjR0H3CSZJeQ8svMCxHLmOluG9H1UKk55ZBYfRTsXniqUkJBZ5wuV1L+pR9EK\n"
"ca89a+1VAkEA3UmBelwEv2u9cAU1QjKjmwju1JgXbrjEohK+3B5y0ESEXPAwNQT9\n"
"TrDM1m9AyxYTWLxX93dI5QwNFJtmbtjeBQJARSCWXhsoaDRG8QZrCSjBxfzTCqZD\n"
"ZXtl807ymCipgJm60LiAt0JLr4LiucAsMZz6+j+quQbSakbFCACB8SLV1QJBAKZQ\n"
"YKf+EPNtnmta/rRKKvySsi3GQZZN+Dt3q0r094XgeTsAqrqujVNfPhTMeP4qEVBX\n"
"/iVX2cmMTSh3w3z8MaECQEp0XJWDVKOwcTW6Ajp9SowtmiZ3YDYo1LF9igb4iaLv\n"
"sWZGfbnU3ryjvkb6YuFjgtzbZDZHWQCo8/cOtOBmPdk=\n"
"-----END RSA PRIVATE KEY-----\n";
static int
file_reader (void *cls, size_t pos, char *buf, int max)
{
@@ -93,7 +122,7 @@ http_ahc (void *cls,
return MHD_YES;
}
*ptr = NULL; /* reset when done */
file = fopen (url, "r");
if (file == NULL)
{
@@ -105,7 +134,7 @@ http_ahc (void *cls,
}
else
{
stat (&url[1], &buf);
stat (url, &buf);
response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k PAGE_NOT_FOUND size */
&file_reader, file,
(MHD_ContentReaderFreeCallback)
@@ -115,12 +144,10 @@ http_ahc (void *cls,
}
return ret;
}
int
main (int argc, char *const *argv)
{
char keyfile[255] = KEYFILE;
char certfile[255] = CERTFILE;
struct MHD_Daemon *TLS_daemon;
/* look for HTTPS arguments */
+24 -5
View File
@@ -307,7 +307,7 @@ enum MHD_OPTION
MHD_OPTION_CONNECTION_MEMORY_LIMIT = 1,
/**
* Maximum number of concurrenct connections to
* Maximum number of concurrent connections to
* accept (followed by an unsigned int).
*/
MHD_OPTION_CONNECTION_LIMIT = 2,
@@ -345,21 +345,40 @@ enum MHD_OPTION
*/
MHD_OPTION_PER_IP_CONNECTION_LIMIT = 5,
// TODO rename
/**
* Filename for the private key (key.pem) to be used by the
* Filename for the private key (key.pem) to be used by the
* HTTPS daemon. This option should be followed by an
* "const char*" argument. The memory of the filename must
* not be released until the application terminates.
* This should be used in conjunction with 'MHD_OPTION_HTTPS_CERT_PATH'.
*/
MHD_OPTION_HTTPS_KEY_PATH = 6,
/**
* Filename for the certificate (cert.pem) to be used by the
* Filename for the certificate (cert.pem) to be used by the
* HTTPS daemon. This option should be followed by an
* "const char*" argument. The memory of the filename must
* not be released until the application terminates.
* This should be used in conjunction with 'MHD_OPTION_HTTPS_KEY_PATH'.
*/
MHD_OPTION_HTTPS_CERT_PATH = 7,
/**
* Memory pointer for the private key (key.pem) to be used by the
* HTTPS daemon. This option should be followed by an
* "const char*" argument.
* This should be used in conjunction with 'MHD_OPTION_HTTPS_MEM_CERT'.
*/
MHD_OPTION_HTTPS_MEM_KEY = 8,
/**
* Memory pointer for the certificate (cert.pem) to be used by the
* HTTPS daemon. This option should be followed by an
* "const char*" argument.
* This should be used in conjunction with 'MHD_OPTION_HTTPS_MEM_KEY'.
*/
MHD_OPTION_HTTPS_MEM_CERT = 9,
};
/**
@@ -866,10 +885,10 @@ MHD_post_process (struct MHD_PostProcessor *pp,
/**
* Release PostProcessor resources.
*
*
* @return MHD_YES if processing completed nicely,
* MHD_NO if there were spurious characters / formatting
* problems; it is common to ignore the return
* problems; it is common to ignore the return
* value of this function
*/
int MHD_destroy_post_processor (struct MHD_PostProcessor *pp);
+4 -3
View File
@@ -1,6 +1,8 @@
SUBDIRS = .
SUBDIRS = https .
INCLUDES = -I$(top_srcdir)/src/include
AM_CPPFLAGS = \
-I$(top_srcdir)/src/daemon \
-I$(top_srcdir)/src/include
check_PROGRAMS = \
daemontest_get \
@@ -93,7 +95,6 @@ daemontest_put11_LDADD = \
$(top_builddir)/src/daemon/libmicrohttpd.la \
@LIBCURL@
daemontest_large_put_SOURCES = \
daemontest_large_put.c
daemontest_large_put_LDADD = \
-276
View File
@@ -1,276 +0,0 @@
/*
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 daemon_HTTPS_test_get.c
* @brief Testcase for libmicrohttpd GET operations
* @author lv-426
*/
#include "config.h"
#include "plibc.h"
#include "microhttpd.h"
#include <errno.h>
#include <curl/curl.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#define BUF_SIZE 1024
#define MAX_URL_LEN 255
/* Test Certificate */
const char cert_pem[] =
"-----BEGIN CERTIFICATE-----\n"
"MIIB5zCCAVKgAwIBAgIERiYdJzALBgkqhkiG9w0BAQUwGTEXMBUGA1UEAxMOR251\n"
"VExTIHRlc3QgQ0EwHhcNMDcwNDE4MTMyOTExWhcNMDgwNDE3MTMyOTExWjAZMRcw\n"
"FQYDVQQDEw5HbnVUTFMgdGVzdCBDQTCBnDALBgkqhkiG9w0BAQEDgYwAMIGIAoGA\n"
"vuyYeh1vfmslnuggeEKgZAVmQ5ltSdUY7H25WGSygKMUYZ0KT74v8C780qtcNt9T\n"
"7EPH/N6RvB4BprdssgcQLsthR3XKA84jbjjxNCcaGs33lvOz8A1nf8p3hD+cKfRi\n"
"kfYSW2JazLrtCC4yRCas/SPOUxu78of+3HiTfFm/oXUCAwEAAaNDMEEwDwYDVR0T\n"
"AQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwQAMB0GA1UdDgQWBBTpPBz7rZJu5gak\n"
"Viyi4cBTJ8jylTALBgkqhkiG9w0BAQUDgYEAiaIRqGfp1jPpNeVhABK60SU0KIAy\n"
"njuu7kHq5peUgYn8Jd9zNzExBOEp1VOipGsf6G66oQAhDFp2o8zkz7ZH71zR4HEW\n"
"KoX6n5Emn6DvcEH/9pAhnGxNHJAoS7czTKv/JDZJhkqHxyrE1fuLsg5Qv25DTw7+\n"
"PfqUpIhz5Bbm7J4=\n" "-----END CERTIFICATE-----\n";
const char key_pem[] =
"-----BEGIN RSA PRIVATE KEY-----\n"
"MIICXAIBAAKBgQC7ZkP18sXXtozMxd/1iDuxyUtqDqGtIFBACIChT1yj0Phsz+Y8\n"
"9+wEdhMXi2SJIlvA3VN8O+18BLuAuSi+jpvGjqClEsv1Vx6i57u3M0mf47tKrmpN\n"
"aP/JEeIyjc49gAuNde/YAIGPKAQDoCKNYQQH+rY3fSEHSdIJYWmYkKNYqQIDAQAB\n"
"AoGADpmARG5CQxS+AesNkGmpauepiCz1JBF/JwnyiX6vEzUh0Ypd39SZztwrDxvF\n"
"PJjQaKVljml1zkJpIDVsqvHdyVdse8M+Qn6hw4x2p5rogdvhhIL1mdWo7jWeVJTF\n"
"RKB7zLdMPs3ySdtcIQaF9nUAQ2KJEvldkO3m/bRJFEp54k0CQQDYy+RlTmwRD6hy\n"
"7UtMjR0H3CSZJeQ8svMCxHLmOluG9H1UKk55ZBYfRTsXniqUkJBZ5wuV1L+pR9EK\n"
"ca89a+1VAkEA3UmBelwEv2u9cAU1QjKjmwju1JgXbrjEohK+3B5y0ESEXPAwNQT9\n"
"TrDM1m9AyxYTWLxX93dI5QwNFJtmbtjeBQJARSCWXhsoaDRG8QZrCSjBxfzTCqZD\n"
"ZXtl807ymCipgJm60LiAt0JLr4LiucAsMZz6+j+quQbSakbFCACB8SLV1QJBAKZQ\n"
"YKf+EPNtnmta/rRKKvySsi3GQZZN+Dt3q0r094XgeTsAqrqujVNfPhTMeP4qEVBX\n"
"/iVX2cmMTSh3w3z8MaECQEp0XJWDVKOwcTW6Ajp9SowtmiZ3YDYo1LF9igb4iaLv\n"
"sWZGfbnU3ryjvkb6YuFjgtzbZDZHWQCo8/cOtOBmPdk=\n"
"-----END RSA PRIVATE KEY-----\n";
struct CBC
{
char *buf;
size_t pos;
size_t size;
};
static size_t
copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
{
struct CBC *cbc = ctx;
if (cbc->pos + size * nmemb > cbc->size)
return 0; /* overflow */
memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
cbc->pos += size * nmemb;
return size * nmemb;
}
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)
{
static int aptr;
static char full_url[MAX_URL_LEN];
struct MHD_Response *response;
int ret;
FILE *file;
struct stat buf;
// TODO never respond on first call
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 */
file = fopen (url, "r");
if (file == NULL)
{
return 1;
}
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;
}
static int
test_HTTPS_Get ()
{
struct MHD_Daemon *d;
CURL *c;
struct CBC cbc;
CURLcode errornum;
char *doc_path;
char *url;
/* currently use self as test file - consider better alternatives */
char *test_file_name = "daemon_HTTPS_test_get";
struct stat test_file_stat;
FILE *key_file, *cert_file, *test_file;
/* used to memcmp local copy & deamon supplied copy */
unsigned char *mem_test_file_local;
unsigned char *mem_test_file_recv;
/* setup test file path, url */
doc_path = get_current_dir_name ();
/* construct url - this might use doc_path */
url =
(char *) malloc (sizeof (char) *
(strlen (test_file_name) +
strlen ("https://127.0.0.1:42433/")));
strncat (url, "https://127.0.0.1:42433/", strlen ("https://127.0.0.1:42433/"));
strncat (url, test_file_name, strlen (test_file_name));
/* look for test file used for testing */
key_file = fopen ("key_file", "w");
cert_file = fopen ("cert_file", "w");
test_file = fopen (test_file_name, "r");
if ( key_file == NULL)
{
fprintf (stderr, "Error : failed to open key_file. errno:%d\n", errno);
return 1;
}
if (!cert_file)
{
fprintf (stderr, "Error : failed to open cert_file. errno:%d\n", errno);
return 1;
}
if (!test_file)
{
fprintf (stderr, "Error : failed to open test_file. errno:%d\n", errno);
return 1;
}
if (stat (test_file_name, &test_file_stat) == -1)
return 1;
/* create test cert & key */
fwrite (key_pem, 1, sizeof (key_pem), key_file);
fwrite (cert_pem, 1, sizeof (cert_pem), cert_file);
mem_test_file_local = malloc (test_file_stat.st_size);
mem_test_file_recv = malloc (test_file_stat.st_size);
fread (mem_test_file_local, 1, test_file_stat.st_size, test_file);
fclose (key_file);
fclose (cert_file);
fclose (test_file);
cbc.buf = mem_test_file_recv;
cbc.size = test_file_stat.st_size;
cbc.pos = 0;
/* setup test */
d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
42433, NULL, NULL, &http_ahc, NULL,
MHD_OPTION_DOC_ROOT, doc_path, MHD_OPTION_END);
if (d == NULL)
return 1;
c = curl_easy_init ();
curl_easy_setopt (c, CURLOPT_URL, url);
curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
/* TLS options */
curl_easy_setopt (c, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, "AES256-SHA");
/* currently skip peer authentication */
curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
// curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
// NOTE: use of CONNECTTIMEOUT without also
// setting NOSIGNAL results in really weird
// crashes on my system!
curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
if (CURLE_OK != (errornum = curl_easy_perform (c)))
{
fprintf (stderr,
"curl_easy_perform failed: `%s'\n",
curl_easy_strerror (errornum));
curl_easy_cleanup (c);
MHD_stop_daemon (d);
return 2;
}
curl_easy_cleanup (c);
MHD_stop_daemon (d);
if (remove ("key_file") != 0)
fprintf (stderr, "Error : failed to remove key_file.\n");
if (remove ("cert_file") != 0)
fprintf (stderr, "Error : failed to remove cert_file.\n");
fprintf (stderr, "file = %s.\n" , mem_test_file_recv );
if (memcmp (cbc.buf, mem_test_file_local, test_file_stat.st_size) == 0)
{
// TODO find proper error code
return 1;
}
return 0;
}
int
main (int argc, char *const *argv)
{
unsigned int errorCount = 0;
if (0 != curl_global_init (CURL_GLOBAL_WIN32))
return 2;
errorCount += test_HTTPS_Get ();
if (errorCount != 0)
fprintf (stderr, "Error (code: %u)\n", errorCount);
curl_global_cleanup ();
return errorCount == 0; /* 0 == pass */
}