mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-25 04:09:31 +03:00
186 lines
6.3 KiB
C
186 lines
6.3 KiB
C
/*
|
|
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 https_server_example.c
|
|
* @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
|
|
*/
|
|
|
|
#include "config.h"
|
|
#include <microhttpd.h>
|
|
#include <sys/stat.h>
|
|
|
|
#include <stdlib.h>
|
|
#ifndef MINGW
|
|
#include <unistd.h>
|
|
#endif
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include "gnutls.h"
|
|
#include <gcrypt.h>
|
|
|
|
#define BUF_SIZE 1024
|
|
#define MAX_URL_LEN 255
|
|
|
|
// 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)
|
|
{
|
|
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;
|
|
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 */
|
|
|
|
file = fopen (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, &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 *TLS_daemon;
|
|
|
|
/* look for HTTPS arguments */
|
|
if (argc < 5)
|
|
{
|
|
printf
|
|
("Usage : %s HTTP-PORT SECONDS-TO-RUN HTTPS-PORT KEY-FILE CERT-FILE\n",
|
|
argv[0]);
|
|
return 1;
|
|
}
|
|
|
|
// TODO check if this is truly necessary - disallow usage of the blocking /dev/random */
|
|
// gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0);
|
|
|
|
TLS_daemon = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG
|
|
| MHD_USE_SSL, atoi (argv[3]),
|
|
NULL,
|
|
NULL, &http_ahc,
|
|
NULL, MHD_OPTION_CONNECTION_TIMEOUT, 256,
|
|
MHD_OPTION_HTTPS_KEY_PATH, argv[4],
|
|
MHD_OPTION_HTTPS_CERT_PATH, argv[5],
|
|
MHD_OPTION_END);
|
|
|
|
if (TLS_daemon == NULL)
|
|
{
|
|
printf ("Error: failed to start TLS_daemon");
|
|
return 1;
|
|
}
|
|
|
|
sleep (atoi (argv[2]));
|
|
|
|
MHD_stop_daemon (TLS_daemon);
|
|
|
|
return 0;
|
|
}
|