aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac1
-rw-r--r--src/daemon/Makefile.am3
-rw-r--r--src/daemon/daemon.c96
-rw-r--r--src/daemon/https/includes/gnutls.h26
-rw-r--r--src/daemon/internal.h10
-rw-r--r--src/examples/https_server_example.c45
-rw-r--r--src/include/microhttpd.h29
-rw-r--r--src/testcurl/Makefile.am7
-rw-r--r--src/testcurl/daemon_HTTPS_test_get.c276
9 files changed, 149 insertions, 344 deletions
diff --git a/configure.ac b/configure.ac
index 7601b742..b7c8fa7f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -257,6 +257,7 @@ src/daemon/https/minitasn1/Makefile
257src/daemon/https/includes/Makefile 257src/daemon/https/includes/Makefile
258src/examples/Makefile 258src/examples/Makefile
259src/testcurl/Makefile 259src/testcurl/Makefile
260src/testcurl/https/Makefile
260src/testzzuf/Makefile]) 261src/testzzuf/Makefile])
261AC_OUTPUT 262AC_OUTPUT
262 263
diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am
index 9d4fd650..ed1818a4 100644
--- a/src/daemon/Makefile.am
+++ b/src/daemon/Makefile.am
@@ -1,4 +1,5 @@
1AM_CPPFLAGS = -I$(top_srcdir)/src/include \ 1AM_CPPFLAGS = \
2-I$(top_srcdir)/src/include \
2-I$(top_srcdir)/src/daemon \ 3-I$(top_srcdir)/src/daemon \
3-I$(top_srcdir)/src/daemon/https/lgl \ 4-I$(top_srcdir)/src/daemon/https/lgl \
4-I$(top_srcdir)/src/daemon/https/x509 \ 5-I$(top_srcdir)/src/daemon/https/x509 \
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c
index 2831bd00..ecc70a02 100644
--- a/src/daemon/daemon.c
+++ b/src/daemon/daemon.c
@@ -220,7 +220,7 @@ MHDS_handle_connection (void *data)
220 con->daemon->x509_cret); 220 con->daemon->x509_cret);
221 221
222 /* avoid gnutls blocking recv / write calls */ 222 /* avoid gnutls blocking recv / write calls */
223 // gnutls_transport_set_pull_function(tls_session, &recv); 223 gnutls_transport_set_pull_function(tls_session, &recv);
224 // gnutls_transport_set_push_function(tls_session, &send); 224 // gnutls_transport_set_push_function(tls_session, &send);
225 225
226 gnutls_transport_set_ptr (tls_session, con->socket_fd); 226 gnutls_transport_set_ptr (tls_session, con->socket_fd);
@@ -786,14 +786,10 @@ MHD_start_daemon (unsigned int options,
786 retVal->pool_size = MHD_POOL_SIZE_DEFAULT; 786 retVal->pool_size = MHD_POOL_SIZE_DEFAULT;
787 retVal->connection_timeout = 0; /* no timeout */ 787 retVal->connection_timeout = 0; /* no timeout */
788 788
789 /* initialize ssl path parameters to the local path */
790 retVal->https_cert_path = "cert.pem";
791 retVal->https_key_path = "key.pem";
792
793 /* initializes the argument pointer variable */ 789 /* initializes the argument pointer variable */
794 va_start (ap, dh_cls); 790 va_start (ap, dh_cls);
795 /* 791 /*
796 * loop through daemon options 792 * loop through daemon options
797 */ 793 */
798 while (MHD_OPTION_END != (opt = va_arg (ap, enum MHD_OPTION))) 794 while (MHD_OPTION_END != (opt = va_arg (ap, enum MHD_OPTION)))
799 { 795 {
@@ -817,10 +813,16 @@ MHD_start_daemon (unsigned int options,
817 retVal->per_ip_connection_limit = va_arg (ap, unsigned int); 813 retVal->per_ip_connection_limit = va_arg (ap, unsigned int);
818 break; 814 break;
819 case MHD_OPTION_HTTPS_KEY_PATH: 815 case MHD_OPTION_HTTPS_KEY_PATH:
820 retVal->https_key_path = va_arg (ap, const char *); 816 retVal->https_key_path = va_arg (ap, const char *);
821 break; 817 break;
822 case MHD_OPTION_HTTPS_CERT_PATH: 818 case MHD_OPTION_HTTPS_CERT_PATH:
823 retVal->https_cert_path = va_arg (ap, const char* ); 819 retVal->https_cert_path = va_arg (ap, const char *);
820 break;
821 case MHD_OPTION_HTTPS_MEM_KEY:
822 retVal->https_mem_key = va_arg (ap, const char *);
823 break;
824 case MHD_OPTION_HTTPS_MEM_CERT:
825 retVal->https_mem_cert = va_arg (ap, const char *);
824 break; 826 break;
825 default: 827 default:
826#if HAVE_MESSAGES 828#if HAVE_MESSAGES
@@ -832,25 +834,13 @@ MHD_start_daemon (unsigned int options,
832 } 834 }
833#if HTTPS_SUPPORT 835#if HTTPS_SUPPORT
834 /* initialize HTTPS daemon certificate aspects & send / recv functions */ 836 /* initialize HTTPS daemon certificate aspects & send / recv functions */
835 if (options & MHD_USE_SSL) 837 if (options & MHD_USE_SSL && MHD_NO == MHDS_init (retVal))
836 { 838 {
837 /* test for private key & certificate file exsitance */
838 FILE *cert_file = fopen (retVal->https_cert_path, "r");
839 FILE *key_file = fopen (retVal->https_key_path, "r");
840 if (key_file == NULL || cert_file == NULL)
841 {
842 printf ("missing cert files");
843#if HAVE_MESSAGES 839#if HAVE_MESSAGES
844 MHD_DLOG (retVal, "Missing X.509 key or certificate file\n"); 840 MHD_DLOG (retVal, "Failed to initialize MHDS\n", STRERROR (errno));
845#endif 841#endif
846 free (retVal); 842 free (retVal);
847 CLOSE (socket_fd); 843 return NULL;
848 return NULL;
849 }
850
851 fclose (cert_file);
852 fclose (key_file);
853 MHDS_init (retVal);
854 } 844 }
855#endif 845#endif
856 va_end (ap); 846 va_end (ap);
@@ -923,13 +913,13 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
923 } 913 }
924 914
925 /* TLS clean up */ 915 /* TLS clean up */
926#if HTTPS_SUPPORT 916#if HTTPS_SUPPORT
927 if (daemon->options & MHD_USE_SSL) 917 if (daemon->options & MHD_USE_SSL)
928 { 918 {
929 gnutls_priority_deinit (daemon->priority_cache); 919 gnutls_priority_deinit (daemon->priority_cache);
930 gnutls_global_deinit (); 920 gnutls_global_deinit ();
931 } 921 }
932#endif 922#endif
933 923
934 free (daemon); 924 free (daemon);
935} 925}
@@ -952,13 +942,13 @@ MHDS_init (struct MHD_Daemon *daemon)
952 gnutls_global_init (); 942 gnutls_global_init ();
953 943
954 /* Generate Diffie Hellman parameters - for use with DHE kx algorithms. */ 944 /* Generate Diffie Hellman parameters - for use with DHE kx algorithms. */
955 // TODO should we be initializing RSA params or DH params ? 945 // TODO should we be initializing RSA params or DH params ?
956 gnutls_dh_params_init (&daemon->dh_params); 946 gnutls_dh_params_init (&daemon->dh_params);
957 gnutls_dh_params_generate2 (daemon->dh_params, DH_BITS); 947 gnutls_dh_params_generate2 (daemon->dh_params, DH_BITS);
958 948
949 // TODO rm NONE:+AES-256-CBC:+RSA:+SHA1:+COMP-NULL", NULL);
959 gnutls_priority_init (&daemon->priority_cache, 950 gnutls_priority_init (&daemon->priority_cache,
960 "NONE:+AES-256-CBC:+RSA:+SHA1:+COMP-NULL", 951 "NONE:+AES-256-CBC:+RSA:+SHA1:+COMP-NULL", NULL);
961 NULL);
962 952
963 /* setup server certificate */ 953 /* setup server certificate */
964 gnutls_certificate_allocate_credentials (&daemon->x509_cret); 954 gnutls_certificate_allocate_credentials (&daemon->x509_cret);
@@ -971,15 +961,53 @@ MHDS_init (struct MHD_Daemon *daemon)
971 //gnutls_certificate_set_x509_crl_file(x509_cret, CRLFILE, GNUTLS_X509_FMT_PEM); 961 //gnutls_certificate_set_x509_crl_file(x509_cret, CRLFILE, GNUTLS_X509_FMT_PEM);
972 962
973 /* sets a certificate private key pair */ 963 /* sets a certificate private key pair */
974 gnutls_certificate_set_x509_key_file (daemon->x509_cret, 964 if (daemon->https_cert_path && daemon->https_key_path )
975 daemon->https_cert_path, 965 {
976 daemon->https_key_path, 966 /* test for private key & certificate file exsitance */
977 GNUTLS_X509_FMT_PEM); 967 FILE *cert_file = fopen (daemon->https_cert_path, "r");
968 FILE *key_file = fopen (daemon->https_key_path, "r");
969 if (key_file == NULL || cert_file == NULL)
970 {
971 printf ("missing cert files");
972#if HAVE_MESSAGES
973 MHD_DLOG (daemon, "Missing X.509 key or certificate file\n");
974#endif
975 free (daemon);
976 CLOSE (daemon->socket_fd);
977 return NULL;
978 }
979 fclose (cert_file);
980 fclose (key_file);
981 gnutls_certificate_set_x509_key_file (daemon->x509_cret,
982 daemon->https_cert_path,
983 daemon->https_key_path,
984 GNUTLS_X509_FMT_PEM);
985 }
986 else if (daemon->https_mem_cert && daemon->https_mem_key )
987 {
988 // TODO free
989 gnutls_datum_t * key = ( gnutls_datum_t * ) malloc (sizeof(gnutls_datum_t));
990 gnutls_datum_t * cert = ( gnutls_datum_t * ) malloc (sizeof(gnutls_datum_t));
991
992 _gnutls_set_datum_m(key,daemon->https_mem_key,strlen (daemon->https_mem_key), &malloc);
993 _gnutls_set_datum_m(cert,daemon->https_mem_cert,strlen (daemon->https_mem_cert), &malloc);
994
995 gnutls_certificate_set_x509_key_mem (daemon->x509_cret, cert, key,
996 GNUTLS_X509_FMT_PEM);
997 printf("");
998 }
999 else
1000 {
1001#if HAVE_MESSAGES
1002 MHD_DLOG (daemon, "Failed to load certificate\n");
1003#endif
1004 return MHD_NO;
1005 }
978 1006
979 gnutls_certificate_set_dh_params (daemon->x509_cret, daemon->dh_params); 1007 gnutls_certificate_set_dh_params (daemon->x509_cret, daemon->dh_params);
980 1008
981 // TODO address error case return value 1009 // TODO address error case return value
982 return 0; 1010 return MHD_YES;
983} 1011}
984#endif 1012#endif
985 1013
diff --git a/src/daemon/https/includes/gnutls.h b/src/daemon/https/includes/gnutls.h
index b5d168f7..535e89ed 100644
--- a/src/daemon/https/includes/gnutls.h
+++ b/src/daemon/https/includes/gnutls.h
@@ -227,7 +227,7 @@ extern "C"
227 */ 227 */
228 228
229 /* Those are extra information about the verification 229 /* Those are extra information about the verification
230 * process. Will be set only if the certificate was 230 * process. Will be set only if the certificate was
231 * not verified. 231 * not verified.
232 */ 232 */
233 GNUTLS_CERT_SIGNER_NOT_FOUND = 64, 233 GNUTLS_CERT_SIGNER_NOT_FOUND = 64,
@@ -494,7 +494,7 @@ extern "C"
494 const char *gnutls_supplemental_get_name 494 const char *gnutls_supplemental_get_name
495 (gnutls_supplemental_data_format_type_t type); 495 (gnutls_supplemental_data_format_type_t type);
496 496
497/* functions to set priority of cipher suites 497/* functions to set priority of cipher suites
498 */ 498 */
499 int gnutls_cipher_set_priority (gnutls_session_t session, const int *list); 499 int gnutls_cipher_set_priority (gnutls_session_t session, const int *list);
500 int gnutls_mac_set_priority (gnutls_session_t session, const int *list); 500 int gnutls_mac_set_priority (gnutls_session_t session, const int *list);
@@ -510,7 +510,7 @@ extern "C"
510 */ 510 */
511 int gnutls_priority_init( gnutls_priority_t*, const char *priority, const char** err_pos); 511 int gnutls_priority_init( gnutls_priority_t*, const char *priority, const char** err_pos);
512 void gnutls_priority_deinit( gnutls_priority_t); 512 void gnutls_priority_deinit( gnutls_priority_t);
513 513
514 int gnutls_priority_set(gnutls_session_t session, gnutls_priority_t); 514 int gnutls_priority_set(gnutls_session_t session, gnutls_priority_t);
515 int gnutls_priority_set_direct(gnutls_session_t session, const char *priority, const char** err_pos); 515 int gnutls_priority_set_direct(gnutls_session_t session, const char *priority, const char** err_pos);
516 516
@@ -533,7 +533,7 @@ extern "C"
533 const char *gnutls_protocol_get_name (gnutls_protocol_t version); 533 const char *gnutls_protocol_get_name (gnutls_protocol_t version);
534 534
535 535
536/* get/set session 536/* get/set session
537 */ 537 */
538 int gnutls_session_set_data (gnutls_session_t session, 538 int gnutls_session_set_data (gnutls_session_t session,
539 const void *session_data, 539 const void *session_data,
@@ -548,7 +548,7 @@ extern "C"
548 int gnutls_session_get_id (gnutls_session_t session, void *session_id, 548 int gnutls_session_get_id (gnutls_session_t session, void *session_id,
549 size_t * session_id_size); 549 size_t * session_id_size);
550 550
551/* returns security values. 551/* returns security values.
552 * Do not use them unless you know what you're doing. 552 * Do not use them unless you know what you're doing.
553 */ 553 */
554#define TLS_MASTER_SIZE 48 554#define TLS_MASTER_SIZE 48
@@ -557,7 +557,7 @@ extern "C"
557 const void *gnutls_session_get_client_random (gnutls_session_t session); 557 const void *gnutls_session_get_client_random (gnutls_session_t session);
558 const void *gnutls_session_get_master_secret (gnutls_session_t session); 558 const void *gnutls_session_get_master_secret (gnutls_session_t session);
559 559
560/* checks if this session is a resumed one 560/* checks if this session is a resumed one
561 */ 561 */
562 int gnutls_session_is_resumed (gnutls_session_t session); 562 int gnutls_session_is_resumed (gnutls_session_t session);
563 563
@@ -583,7 +583,7 @@ extern "C"
583 typedef int (*gnutls_handshake_post_client_hello_func)(gnutls_session_t); 583 typedef int (*gnutls_handshake_post_client_hello_func)(gnutls_session_t);
584 void gnutls_handshake_set_post_client_hello_function(gnutls_session_t, 584 void gnutls_handshake_set_post_client_hello_function(gnutls_session_t,
585 gnutls_handshake_post_client_hello_func); 585 gnutls_handshake_post_client_hello_func);
586 586
587 void gnutls_handshake_set_max_packet_length (gnutls_session_t session, 587 void gnutls_handshake_set_max_packet_length (gnutls_session_t session,
588 size_t max); 588 size_t max);
589 589
@@ -684,7 +684,7 @@ extern "C"
684 684
685 void gnutls_certificate_send_x509_rdn_sequence (gnutls_session_t session, 685 void gnutls_certificate_send_x509_rdn_sequence (gnutls_session_t session,
686 int status); 686 int status);
687 687
688 688
689 extern int 689 extern int
690 gnutls_certificate_set_x509_simple_pkcs12_file 690 gnutls_certificate_set_x509_simple_pkcs12_file
@@ -769,7 +769,7 @@ extern "C"
769 int gnutls_dh_params_cpy (gnutls_dh_params_t dst, gnutls_dh_params_t src); 769 int gnutls_dh_params_cpy (gnutls_dh_params_t dst, gnutls_dh_params_t src);
770 770
771 771
772/* RSA params 772/* RSA params
773 */ 773 */
774 int gnutls_rsa_params_init (gnutls_rsa_params_t * rsa_params); 774 int gnutls_rsa_params_init (gnutls_rsa_params_t * rsa_params);
775 void gnutls_rsa_params_deinit (gnutls_rsa_params_t rsa_params); 775 void gnutls_rsa_params_deinit (gnutls_rsa_params_t rsa_params);
@@ -825,7 +825,7 @@ extern "C"
825 void gnutls_transport_set_errno (gnutls_session_t session, int err); 825 void gnutls_transport_set_errno (gnutls_session_t session, int err);
826 void gnutls_transport_set_global_errno (int err); 826 void gnutls_transport_set_global_errno (int err);
827 827
828/* session specific 828/* session specific
829 */ 829 */
830 void gnutls_session_set_ptr (gnutls_session_t session, void *ptr); 830 void gnutls_session_set_ptr (gnutls_session_t session, void *ptr);
831 void *gnutls_session_get_ptr (gnutls_session_t session); 831 void *gnutls_session_get_ptr (gnutls_session_t session);
@@ -833,7 +833,7 @@ extern "C"
833 void gnutls_openpgp_send_cert (gnutls_session_t session, 833 void gnutls_openpgp_send_cert (gnutls_session_t session,
834 gnutls_openpgp_crt_status_t status); 834 gnutls_openpgp_crt_status_t status);
835 835
836/* fingerprint 836/* fingerprint
837 * Actually this function returns the hash of the given data. 837 * Actually this function returns the hash of the given data.
838 */ 838 */
839 int gnutls_fingerprint (gnutls_digest_algorithm_t algo, 839 int gnutls_fingerprint (gnutls_digest_algorithm_t algo,
@@ -841,7 +841,7 @@ extern "C"
841 size_t * result_size); 841 size_t * result_size);
842 842
843 843
844/* SRP 844/* SRP
845 */ 845 */
846 846
847 typedef struct gnutls_srp_server_credentials_st 847 typedef struct gnutls_srp_server_credentials_st
@@ -1117,7 +1117,7 @@ extern "C"
1117 gnutls_datum_t * result); 1117 gnutls_datum_t * result);
1118 1118
1119 int gnutls_global_init (void); 1119 int gnutls_global_init (void);
1120 1120
1121 /* key_usage will be an OR of the following values: 1121 /* key_usage will be an OR of the following values:
1122 */ 1122 */
1123 1123
diff --git a/src/daemon/internal.h b/src/daemon/internal.h
index 0bb6dd1d..51177ede 100644
--- a/src/daemon/internal.h
+++ b/src/daemon/internal.h
@@ -308,7 +308,7 @@ enum MHDS_CONNECTION_STATE
308 308
309 /* while receiving an HTTP request through the encrypted channel */ 309 /* while receiving an HTTP request through the encrypted channel */
310 MHDS_REPLY_SENDING, 310 MHDS_REPLY_SENDING,
311 311
312 MHDS_REPLY_SENT, 312 MHDS_REPLY_SENT,
313 313
314 MHDS_CONNECTION_CLOSED 314 MHDS_CONNECTION_CLOSED
@@ -549,7 +549,7 @@ struct MHD_Connection
549 549
550 int (*idle_handler) (struct MHD_Connection * connection); 550 int (*idle_handler) (struct MHD_Connection * connection);
551 551
552 /* 552 /*
553 * function pointers to the appropriate send & receive funtions 553 * function pointers to the appropriate send & receive funtions
554 * according to whether this is a HTTPS / HTTP daemon 554 * according to whether this is a HTTPS / HTTP daemon
555 */ 555 */
@@ -586,7 +586,7 @@ struct MHD_Daemon
586 /** 586 /**
587 * Linked list of our current connections. 587 * Linked list of our current connections.
588 */ 588 */
589 // TODO switch to a dedicated tls connection struct 589 // TODO switch to a dedicated tls connection struct
590 struct MHD_Connection *tls_connections; 590 struct MHD_Connection *tls_connections;
591 591
592 MHD_AcceptPolicyCallback apc; 592 MHD_AcceptPolicyCallback apc;
@@ -657,6 +657,10 @@ struct MHD_Daemon
657 const char * https_key_path; 657 const char * https_key_path;
658 658
659 const char * https_cert_path; 659 const char * https_cert_path;
660
661 const char * https_mem_key;
662
663 const char * https_mem_cert;
660#endif 664#endif
661}; 665};
662 666
diff --git a/src/examples/https_server_example.c b/src/examples/https_server_example.c
index 342b3111..c731c7f6 100644
--- a/src/examples/https_server_example.c
+++ b/src/examples/https_server_example.c
@@ -50,16 +50,45 @@
50#define BUF_SIZE 1024 50#define BUF_SIZE 1024
51#define MAX_URL_LEN 255 51#define MAX_URL_LEN 255
52 52
53#define KEYFILE "key.pem"
54#define CERTFILE "cert.pem"
55
56
57// TODO remove if unused 53// TODO remove if unused
58#define CAFILE "ca.pem" 54#define CAFILE "ca.pem"
59#define CRLFILE "crl.pem" 55#define CRLFILE "crl.pem"
60 56
61#define PAGE_NOT_FOUND "<html><head><title>File not found</title></head><body>File not found</body></html>" 57#define PAGE_NOT_FOUND "<html><head><title>File not found</title></head><body>File not found</body></html>"
62 58
59/* Test Certificate */
60const char cert_pem[] =
61 "-----BEGIN CERTIFICATE-----\n"
62 "MIICHjCCAYmgAwIBAgIERiYdNzALBgkqhkiG9w0BAQUwGTEXMBUGA1UEAxMOR251\n"
63 "VExTIHRlc3QgQ0EwHhcNMDcwNDE4MTMyOTI3WhcNMDgwNDE3MTMyOTI3WjAdMRsw\n"
64 "GQYDVQQDExJHbnVUTFMgdGVzdCBjbGllbnQwgZwwCwYJKoZIhvcNAQEBA4GMADCB\n"
65 "iAKBgLtmQ/Xyxde2jMzF3/WIO7HJS2oOoa0gUEAIgKFPXKPQ+GzP5jz37AR2ExeL\n"
66 "ZIkiW8DdU3w77XwEu4C5KL6Om8aOoKUSy/VXHqLnu7czSZ/ju0quak1o/8kR4jKN\n"
67 "zj2AC41179gAgY8oBAOgIo1hBAf6tjd9IQdJ0glhaZiQo1ipAgMBAAGjdjB0MAwG\n"
68 "A1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDwYDVR0PAQH/BAUDAweg\n"
69 "ADAdBgNVHQ4EFgQUTLkKm/odNON+3svSBxX+odrLaJEwHwYDVR0jBBgwFoAU6Twc\n"
70 "+62SbuYGpFYsouHAUyfI8pUwCwYJKoZIhvcNAQEFA4GBALujmBJVZnvaTXr9cFRJ\n"
71 "jpfc/3X7sLUsMvumcDE01ls/cG5mIatmiyEU9qI3jbgUf82z23ON/acwJf875D3/\n"
72 "U7jyOsBJ44SEQITbin2yUeJMIm1tievvdNXBDfW95AM507ShzP12sfiJkJfjjdhy\n"
73 "dc8Siq5JojruiMizAf0pA7in\n" "-----END CERTIFICATE-----\n";
74
75const char key_pem[] =
76 "-----BEGIN RSA PRIVATE KEY-----\n"
77 "MIICXAIBAAKBgQC7ZkP18sXXtozMxd/1iDuxyUtqDqGtIFBACIChT1yj0Phsz+Y8\n"
78 "9+wEdhMXi2SJIlvA3VN8O+18BLuAuSi+jpvGjqClEsv1Vx6i57u3M0mf47tKrmpN\n"
79 "aP/JEeIyjc49gAuNde/YAIGPKAQDoCKNYQQH+rY3fSEHSdIJYWmYkKNYqQIDAQAB\n"
80 "AoGADpmARG5CQxS+AesNkGmpauepiCz1JBF/JwnyiX6vEzUh0Ypd39SZztwrDxvF\n"
81 "PJjQaKVljml1zkJpIDVsqvHdyVdse8M+Qn6hw4x2p5rogdvhhIL1mdWo7jWeVJTF\n"
82 "RKB7zLdMPs3ySdtcIQaF9nUAQ2KJEvldkO3m/bRJFEp54k0CQQDYy+RlTmwRD6hy\n"
83 "7UtMjR0H3CSZJeQ8svMCxHLmOluG9H1UKk55ZBYfRTsXniqUkJBZ5wuV1L+pR9EK\n"
84 "ca89a+1VAkEA3UmBelwEv2u9cAU1QjKjmwju1JgXbrjEohK+3B5y0ESEXPAwNQT9\n"
85 "TrDM1m9AyxYTWLxX93dI5QwNFJtmbtjeBQJARSCWXhsoaDRG8QZrCSjBxfzTCqZD\n"
86 "ZXtl807ymCipgJm60LiAt0JLr4LiucAsMZz6+j+quQbSakbFCACB8SLV1QJBAKZQ\n"
87 "YKf+EPNtnmta/rRKKvySsi3GQZZN+Dt3q0r094XgeTsAqrqujVNfPhTMeP4qEVBX\n"
88 "/iVX2cmMTSh3w3z8MaECQEp0XJWDVKOwcTW6Ajp9SowtmiZ3YDYo1LF9igb4iaLv\n"
89 "sWZGfbnU3ryjvkb6YuFjgtzbZDZHWQCo8/cOtOBmPdk=\n"
90 "-----END RSA PRIVATE KEY-----\n";
91
63static int 92static int
64file_reader (void *cls, size_t pos, char *buf, int max) 93file_reader (void *cls, size_t pos, char *buf, int max)
65{ 94{
@@ -93,7 +122,7 @@ http_ahc (void *cls,
93 return MHD_YES; 122 return MHD_YES;
94 } 123 }
95 *ptr = NULL; /* reset when done */ 124 *ptr = NULL; /* reset when done */
96 125
97 file = fopen (url, "r"); 126 file = fopen (url, "r");
98 if (file == NULL) 127 if (file == NULL)
99 { 128 {
@@ -105,7 +134,7 @@ http_ahc (void *cls,
105 } 134 }
106 else 135 else
107 { 136 {
108 stat (&url[1], &buf); 137 stat (url, &buf);
109 response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k PAGE_NOT_FOUND size */ 138 response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k PAGE_NOT_FOUND size */
110 &file_reader, file, 139 &file_reader, file,
111 (MHD_ContentReaderFreeCallback) 140 (MHD_ContentReaderFreeCallback)
@@ -115,12 +144,10 @@ http_ahc (void *cls,
115 } 144 }
116 return ret; 145 return ret;
117} 146}
118 147
119int 148int
120main (int argc, char *const *argv) 149main (int argc, char *const *argv)
121{ 150{
122 char keyfile[255] = KEYFILE;
123 char certfile[255] = CERTFILE;
124 struct MHD_Daemon *TLS_daemon; 151 struct MHD_Daemon *TLS_daemon;
125 152
126 /* look for HTTPS arguments */ 153 /* look for HTTPS arguments */
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 999ca590..08a3b5ae 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -307,7 +307,7 @@ enum MHD_OPTION
307 MHD_OPTION_CONNECTION_MEMORY_LIMIT = 1, 307 MHD_OPTION_CONNECTION_MEMORY_LIMIT = 1,
308 308
309 /** 309 /**
310 * Maximum number of concurrenct connections to 310 * Maximum number of concurrent connections to
311 * accept (followed by an unsigned int). 311 * accept (followed by an unsigned int).
312 */ 312 */
313 MHD_OPTION_CONNECTION_LIMIT = 2, 313 MHD_OPTION_CONNECTION_LIMIT = 2,
@@ -345,21 +345,40 @@ enum MHD_OPTION
345 */ 345 */
346 MHD_OPTION_PER_IP_CONNECTION_LIMIT = 5, 346 MHD_OPTION_PER_IP_CONNECTION_LIMIT = 5,
347 347
348 // TODO rename
348 /** 349 /**
349 * Filename for the private key (key.pem) to be used by the 350 * Filename for the private key (key.pem) to be used by the
350 * HTTPS daemon. This option should be followed by an 351 * HTTPS daemon. This option should be followed by an
351 * "const char*" argument. The memory of the filename must 352 * "const char*" argument. The memory of the filename must
352 * not be released until the application terminates. 353 * not be released until the application terminates.
354 * This should be used in conjunction with 'MHD_OPTION_HTTPS_CERT_PATH'.
353 */ 355 */
354 MHD_OPTION_HTTPS_KEY_PATH = 6, 356 MHD_OPTION_HTTPS_KEY_PATH = 6,
355 357
356 /** 358 /**
357 * Filename for the certificate (cert.pem) to be used by the 359 * Filename for the certificate (cert.pem) to be used by the
358 * HTTPS daemon. This option should be followed by an 360 * HTTPS daemon. This option should be followed by an
359 * "const char*" argument. The memory of the filename must 361 * "const char*" argument. The memory of the filename must
360 * not be released until the application terminates. 362 * not be released until the application terminates.
363 * This should be used in conjunction with 'MHD_OPTION_HTTPS_KEY_PATH'.
361 */ 364 */
362 MHD_OPTION_HTTPS_CERT_PATH = 7, 365 MHD_OPTION_HTTPS_CERT_PATH = 7,
366
367 /**
368 * Memory pointer for the private key (key.pem) to be used by the
369 * HTTPS daemon. This option should be followed by an
370 * "const char*" argument.
371 * This should be used in conjunction with 'MHD_OPTION_HTTPS_MEM_CERT'.
372 */
373 MHD_OPTION_HTTPS_MEM_KEY = 8,
374
375 /**
376 * Memory pointer for the certificate (cert.pem) to be used by the
377 * HTTPS daemon. This option should be followed by an
378 * "const char*" argument.
379 * This should be used in conjunction with 'MHD_OPTION_HTTPS_MEM_KEY'.
380 */
381 MHD_OPTION_HTTPS_MEM_CERT = 9,
363}; 382};
364 383
365/** 384/**
@@ -866,10 +885,10 @@ MHD_post_process (struct MHD_PostProcessor *pp,
866 885
867/** 886/**
868 * Release PostProcessor resources. 887 * Release PostProcessor resources.
869 * 888 *
870 * @return MHD_YES if processing completed nicely, 889 * @return MHD_YES if processing completed nicely,
871 * MHD_NO if there were spurious characters / formatting 890 * MHD_NO if there were spurious characters / formatting
872 * problems; it is common to ignore the return 891 * problems; it is common to ignore the return
873 * value of this function 892 * value of this function
874 */ 893 */
875int MHD_destroy_post_processor (struct MHD_PostProcessor *pp); 894int MHD_destroy_post_processor (struct MHD_PostProcessor *pp);
diff --git a/src/testcurl/Makefile.am b/src/testcurl/Makefile.am
index 608c004f..9a8d69b4 100644
--- a/src/testcurl/Makefile.am
+++ b/src/testcurl/Makefile.am
@@ -1,6 +1,8 @@
1SUBDIRS = . 1SUBDIRS = https .
2 2
3INCLUDES = -I$(top_srcdir)/src/include 3AM_CPPFLAGS = \
4-I$(top_srcdir)/src/daemon \
5-I$(top_srcdir)/src/include
4 6
5check_PROGRAMS = \ 7check_PROGRAMS = \
6 daemontest_get \ 8 daemontest_get \
@@ -93,7 +95,6 @@ daemontest_put11_LDADD = \
93 $(top_builddir)/src/daemon/libmicrohttpd.la \ 95 $(top_builddir)/src/daemon/libmicrohttpd.la \
94 @LIBCURL@ 96 @LIBCURL@
95 97
96
97daemontest_large_put_SOURCES = \ 98daemontest_large_put_SOURCES = \
98 daemontest_large_put.c 99 daemontest_large_put.c
99daemontest_large_put_LDADD = \ 100daemontest_large_put_LDADD = \
diff --git a/src/testcurl/daemon_HTTPS_test_get.c b/src/testcurl/daemon_HTTPS_test_get.c
deleted file mode 100644
index a4b957cc..00000000
--- a/src/testcurl/daemon_HTTPS_test_get.c
+++ /dev/null
@@ -1,276 +0,0 @@
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 daemon_HTTPS_test_get.c
23 * @brief Testcase for libmicrohttpd GET operations
24 * @author lv-426
25 */
26
27#include "config.h"
28#include "plibc.h"
29#include "microhttpd.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/types.h>
37#include <sys/stat.h>
38#include <unistd.h>
39
40#define BUF_SIZE 1024
41#define MAX_URL_LEN 255
42
43/* Test Certificate */
44const char cert_pem[] =
45 "-----BEGIN CERTIFICATE-----\n"
46 "MIIB5zCCAVKgAwIBAgIERiYdJzALBgkqhkiG9w0BAQUwGTEXMBUGA1UEAxMOR251\n"
47 "VExTIHRlc3QgQ0EwHhcNMDcwNDE4MTMyOTExWhcNMDgwNDE3MTMyOTExWjAZMRcw\n"
48 "FQYDVQQDEw5HbnVUTFMgdGVzdCBDQTCBnDALBgkqhkiG9w0BAQEDgYwAMIGIAoGA\n"
49 "vuyYeh1vfmslnuggeEKgZAVmQ5ltSdUY7H25WGSygKMUYZ0KT74v8C780qtcNt9T\n"
50 "7EPH/N6RvB4BprdssgcQLsthR3XKA84jbjjxNCcaGs33lvOz8A1nf8p3hD+cKfRi\n"
51 "kfYSW2JazLrtCC4yRCas/SPOUxu78of+3HiTfFm/oXUCAwEAAaNDMEEwDwYDVR0T\n"
52 "AQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwQAMB0GA1UdDgQWBBTpPBz7rZJu5gak\n"
53 "Viyi4cBTJ8jylTALBgkqhkiG9w0BAQUDgYEAiaIRqGfp1jPpNeVhABK60SU0KIAy\n"
54 "njuu7kHq5peUgYn8Jd9zNzExBOEp1VOipGsf6G66oQAhDFp2o8zkz7ZH71zR4HEW\n"
55 "KoX6n5Emn6DvcEH/9pAhnGxNHJAoS7czTKv/JDZJhkqHxyrE1fuLsg5Qv25DTw7+\n"
56 "PfqUpIhz5Bbm7J4=\n" "-----END CERTIFICATE-----\n";
57
58const char key_pem[] =
59 "-----BEGIN RSA PRIVATE KEY-----\n"
60 "MIICXAIBAAKBgQC7ZkP18sXXtozMxd/1iDuxyUtqDqGtIFBACIChT1yj0Phsz+Y8\n"
61 "9+wEdhMXi2SJIlvA3VN8O+18BLuAuSi+jpvGjqClEsv1Vx6i57u3M0mf47tKrmpN\n"
62 "aP/JEeIyjc49gAuNde/YAIGPKAQDoCKNYQQH+rY3fSEHSdIJYWmYkKNYqQIDAQAB\n"
63 "AoGADpmARG5CQxS+AesNkGmpauepiCz1JBF/JwnyiX6vEzUh0Ypd39SZztwrDxvF\n"
64 "PJjQaKVljml1zkJpIDVsqvHdyVdse8M+Qn6hw4x2p5rogdvhhIL1mdWo7jWeVJTF\n"
65 "RKB7zLdMPs3ySdtcIQaF9nUAQ2KJEvldkO3m/bRJFEp54k0CQQDYy+RlTmwRD6hy\n"
66 "7UtMjR0H3CSZJeQ8svMCxHLmOluG9H1UKk55ZBYfRTsXniqUkJBZ5wuV1L+pR9EK\n"
67 "ca89a+1VAkEA3UmBelwEv2u9cAU1QjKjmwju1JgXbrjEohK+3B5y0ESEXPAwNQT9\n"
68 "TrDM1m9AyxYTWLxX93dI5QwNFJtmbtjeBQJARSCWXhsoaDRG8QZrCSjBxfzTCqZD\n"
69 "ZXtl807ymCipgJm60LiAt0JLr4LiucAsMZz6+j+quQbSakbFCACB8SLV1QJBAKZQ\n"
70 "YKf+EPNtnmta/rRKKvySsi3GQZZN+Dt3q0r094XgeTsAqrqujVNfPhTMeP4qEVBX\n"
71 "/iVX2cmMTSh3w3z8MaECQEp0XJWDVKOwcTW6Ajp9SowtmiZ3YDYo1LF9igb4iaLv\n"
72 "sWZGfbnU3ryjvkb6YuFjgtzbZDZHWQCo8/cOtOBmPdk=\n"
73 "-----END RSA PRIVATE KEY-----\n";
74
75struct CBC
76{
77 char *buf;
78 size_t pos;
79 size_t size;
80};
81
82static size_t
83copyBuffer (void *ptr, size_t size, size_t nmemb, void *ctx)
84{
85 struct CBC *cbc = ctx;
86
87 if (cbc->pos + size * nmemb > cbc->size)
88 return 0; /* overflow */
89 memcpy (&cbc->buf[cbc->pos], ptr, size * nmemb);
90 cbc->pos += size * nmemb;
91 return size * nmemb;
92}
93
94static int
95file_reader (void *cls, size_t pos, char *buf, int max)
96{
97 FILE *file = cls;
98 fseek (file, pos, SEEK_SET);
99 return fread (buf, 1, max, file);
100}
101
102/* HTTP access handler call back */
103static int
104http_ahc (void *cls,
105 struct MHD_Connection *connection,
106 const char *url,
107 const char *method,
108 const char *upload_data,
109 const char *version, unsigned int *upload_data_size, void **ptr)
110{
111 static int aptr;
112 static char full_url[MAX_URL_LEN];
113 struct MHD_Response *response;
114 int ret;
115 FILE *file;
116 struct stat buf;
117
118 // TODO never respond on first call
119 if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
120 return MHD_NO; /* unexpected method */
121 if (&aptr != *ptr)
122 {
123 /* do never respond on first call */
124 *ptr = &aptr;
125 return MHD_YES;
126 }
127 *ptr = NULL; /* reset when done */
128
129 file = fopen (url, "r");
130 if (file == NULL)
131 {
132 return 1;
133 }
134 else
135 {
136 stat (&url[1], &buf);
137 response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k PAGE_NOT_FOUND size */
138 &file_reader, file,
139 (MHD_ContentReaderFreeCallback)
140 & fclose);
141 ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
142 MHD_destroy_response (response);
143 }
144 return ret;
145}
146
147static int
148test_HTTPS_Get ()
149{
150 struct MHD_Daemon *d;
151 CURL *c;
152 struct CBC cbc;
153 CURLcode errornum;
154 char *doc_path;
155 char *url;
156 /* currently use self as test file - consider better alternatives */
157 char *test_file_name = "daemon_HTTPS_test_get";
158 struct stat test_file_stat;
159 FILE *key_file, *cert_file, *test_file;
160
161 /* used to memcmp local copy & deamon supplied copy */
162 unsigned char *mem_test_file_local;
163 unsigned char *mem_test_file_recv;
164
165 /* setup test file path, url */
166 doc_path = get_current_dir_name ();
167
168 /* construct url - this might use doc_path */
169 url =
170 (char *) malloc (sizeof (char) *
171 (strlen (test_file_name) +
172 strlen ("https://127.0.0.1:42433/")));
173 strncat (url, "https://127.0.0.1:42433/", strlen ("https://127.0.0.1:42433/"));
174 strncat (url, test_file_name, strlen (test_file_name));
175
176 /* look for test file used for testing */
177 key_file = fopen ("key_file", "w");
178 cert_file = fopen ("cert_file", "w");
179 test_file = fopen (test_file_name, "r");
180 if ( key_file == NULL)
181 {
182 fprintf (stderr, "Error : failed to open key_file. errno:%d\n", errno);
183 return 1;
184 }
185 if (!cert_file)
186 {
187 fprintf (stderr, "Error : failed to open cert_file. errno:%d\n", errno);
188 return 1;
189 }
190 if (!test_file)
191 {
192 fprintf (stderr, "Error : failed to open test_file. errno:%d\n", errno);
193 return 1;
194 }
195 if (stat (test_file_name, &test_file_stat) == -1)
196 return 1;
197
198 /* create test cert & key */
199 fwrite (key_pem, 1, sizeof (key_pem), key_file);
200 fwrite (cert_pem, 1, sizeof (cert_pem), cert_file);
201 mem_test_file_local = malloc (test_file_stat.st_size);
202 mem_test_file_recv = malloc (test_file_stat.st_size);
203 fread (mem_test_file_local, 1, test_file_stat.st_size, test_file);
204
205 fclose (key_file);
206 fclose (cert_file);
207 fclose (test_file);
208
209 cbc.buf = mem_test_file_recv;
210 cbc.size = test_file_stat.st_size;
211 cbc.pos = 0;
212
213 /* setup test */
214 d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_USE_DEBUG,
215 42433, NULL, NULL, &http_ahc, NULL,
216 MHD_OPTION_DOC_ROOT, doc_path, MHD_OPTION_END);
217 if (d == NULL)
218 return 1;
219
220 c = curl_easy_init ();
221 curl_easy_setopt (c, CURLOPT_URL, url);
222 curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
223 curl_easy_setopt (c, CURLOPT_TIMEOUT, 150L);
224 curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
225 curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
226 curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
227 /* TLS options */
228 curl_easy_setopt (c, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
229 curl_easy_setopt (c, CURLOPT_SSL_CIPHER_LIST, "AES256-SHA");
230 /* currently skip peer authentication */
231 curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0);
232 // curl_easy_setopt (c, CURLOPT_FAILONERROR, 1);
233
234 // NOTE: use of CONNECTTIMEOUT without also
235 // setting NOSIGNAL results in really weird
236 // crashes on my system!
237 curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1);
238 if (CURLE_OK != (errornum = curl_easy_perform (c)))
239 {
240 fprintf (stderr,
241 "curl_easy_perform failed: `%s'\n",
242 curl_easy_strerror (errornum));
243 curl_easy_cleanup (c);
244 MHD_stop_daemon (d);
245 return 2;
246 }
247 curl_easy_cleanup (c);
248 MHD_stop_daemon (d);
249 if (remove ("key_file") != 0)
250 fprintf (stderr, "Error : failed to remove key_file.\n");
251 if (remove ("cert_file") != 0)
252 fprintf (stderr, "Error : failed to remove cert_file.\n");
253
254 fprintf (stderr, "file = %s.\n" , mem_test_file_recv );
255 if (memcmp (cbc.buf, mem_test_file_local, test_file_stat.st_size) == 0)
256 {
257 // TODO find proper error code
258 return 1;
259 }
260 return 0;
261}
262
263int
264main (int argc, char *const *argv)
265{
266
267 unsigned int errorCount = 0;
268
269 if (0 != curl_global_init (CURL_GLOBAL_WIN32))
270 return 2;
271 errorCount += test_HTTPS_Get ();
272 if (errorCount != 0)
273 fprintf (stderr, "Error (code: %u)\n", errorCount);
274 curl_global_cleanup ();
275 return errorCount == 0; /* 0 == pass */
276}