https_fileserver_example.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. This file is part of libmicrohttpd
  3. (C) 2007, 2008 Christian Grothoff (and other contributing authors)
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with this library; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  15. */
  16. /**
  17. * @file https_server_example.c
  18. * @brief a simple HTTPS file server using TLS.
  19. *
  20. * Usage :
  21. *
  22. * 'http_fileserver_example HTTP-PORT SECONDS-TO-RUN [CERTIFICATE PATH, KEY PATH]'
  23. *
  24. * The certificate & key are required by the server to operate, Omitting the
  25. * path arguments will cause the server to use the hard coded example certificate & key.
  26. *
  27. * 'certtool' may be used to generate these if required.
  28. *
  29. * @author Sagie Amir
  30. */
  31. #include "platform.h"
  32. #include <microhttpd.h>
  33. #include <sys/stat.h>
  34. #include "gnutls.h"
  35. #include <gcrypt.h>
  36. #define BUF_SIZE 1024
  37. #define MAX_URL_LEN 255
  38. // TODO remove if unused
  39. #define CAFILE "ca.pem"
  40. #define CRLFILE "crl.pem"
  41. #define EMPTY_PAGE "<html><head><title>File not found</title></head><body>File not found</body></html>"
  42. /* Test Certificate */
  43. const char cert_pem[] =
  44. "-----BEGIN CERTIFICATE-----\n"
  45. "MIICpjCCAZCgAwIBAgIESEPtjjALBgkqhkiG9w0BAQUwADAeFw0wODA2MDIxMjU0\n"
  46. "MzhaFw0wOTA2MDIxMjU0NDZaMAAwggEfMAsGCSqGSIb3DQEBAQOCAQ4AMIIBCQKC\n"
  47. "AQC03TyUvK5HmUAirRp067taIEO4bibh5nqolUoUdo/LeblMQV+qnrv/RNAMTx5X\n"
  48. "fNLZ45/kbM9geF8qY0vsPyQvP4jumzK0LOJYuIwmHaUm9vbXnYieILiwCuTgjaud\n"
  49. "3VkZDoQ9fteIo+6we9UTpVqZpxpbLulBMh/VsvX0cPJ1VFC7rT59o9hAUlFf9jX/\n"
  50. "GmKdYI79MtgVx0OPBjmmSD6kicBBfmfgkO7bIGwlRtsIyMznxbHu6VuoX/eVxrTv\n"
  51. "rmCwgEXLWRZ6ru8MQl5YfqeGXXRVwMeXU961KefbuvmEPccgCxm8FZ1C1cnDHFXh\n"
  52. "siSgAzMBjC/b6KVhNQ4KnUdZAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0O\n"
  53. "BBYEFJcUvpjvE5fF/yzUshkWDpdYiQh/MAsGCSqGSIb3DQEBBQOCAQEARP7eKSB2\n"
  54. "RNd6XjEjK0SrxtoTnxS3nw9sfcS7/qD1+XHdObtDFqGNSjGYFB3Gpx8fpQhCXdoN\n"
  55. "8QUs3/5ZVa5yjZMQewWBgz8kNbnbH40F2y81MHITxxCe1Y+qqHWwVaYLsiOTqj2/\n"
  56. "0S3QjEJ9tvklmg7JX09HC4m5QRYfWBeQLD1u8ZjA1Sf1xJriomFVyRLI2VPO2bNe\n"
  57. "JDMXWuP+8kMC7gEvUnJ7A92Y2yrhu3QI3bjPk8uSpHea19Q77tul1UVBJ5g+zpH3\n"
  58. "OsF5p0MyaVf09GTzcLds5nE/osTdXGUyHJapWReVmPm3Zn6gqYlnzD99z+DPIgIV\n"
  59. "RhZvQx74NQnS6g==\n" "-----END CERTIFICATE-----\n";
  60. const char key_pem[] =
  61. "-----BEGIN RSA PRIVATE KEY-----\n"
  62. "MIIEowIBAAKCAQEAtN08lLyuR5lAIq0adOu7WiBDuG4m4eZ6qJVKFHaPy3m5TEFf\n"
  63. "qp67/0TQDE8eV3zS2eOf5GzPYHhfKmNL7D8kLz+I7psytCziWLiMJh2lJvb2152I\n"
  64. "niC4sArk4I2rnd1ZGQ6EPX7XiKPusHvVE6VamacaWy7pQTIf1bL19HDydVRQu60+\n"
  65. "faPYQFJRX/Y1/xpinWCO/TLYFcdDjwY5pkg+pInAQX5n4JDu2yBsJUbbCMjM58Wx\n"
  66. "7ulbqF/3lca0765gsIBFy1kWeq7vDEJeWH6nhl10VcDHl1PetSnn27r5hD3HIAsZ\n"
  67. "vBWdQtXJwxxV4bIkoAMzAYwv2+ilYTUOCp1HWQIDAQABAoIBAArOQv3R7gmqDspj\n"
  68. "lDaTFOz0C4e70QfjGMX0sWnakYnDGn6DU19iv3GnX1S072ejtgc9kcJ4e8VUO79R\n"
  69. "EmqpdRR7k8dJr3RTUCyjzf/C+qiCzcmhCFYGN3KRHA6MeEnkvRuBogX4i5EG1k5l\n"
  70. "/5t+YBTZBnqXKWlzQLKoUAiMLPg0eRWh+6q7H4N7kdWWBmTpako7TEqpIwuEnPGx\n"
  71. "u3EPuTR+LN6lF55WBePbCHccUHUQaXuav18NuDkcJmCiMArK9SKb+h0RqLD6oMI/\n"
  72. "dKD6n8cZXeMBkK+C8U/K0sN2hFHACsu30b9XfdnljgP9v+BP8GhnB0nCB6tNBCPo\n"
  73. "32srOwECgYEAxWh3iBT4lWqL6bZavVbnhmvtif4nHv2t2/hOs/CAq8iLAw0oWGZc\n"
  74. "+JEZTUDMvFRlulr0kcaWra+4fN3OmJnjeuFXZq52lfMgXBIKBmoSaZpIh2aDY1Rd\n"
  75. "RbEse7nQl9hTEPmYspiXLGtnAXW7HuWqVfFFP3ya8rUS3t4d07Hig8ECgYEA6ou6\n"
  76. "OHiBRTbtDqLIv8NghARc/AqwNWgEc9PelCPe5bdCOLBEyFjqKiT2MttnSSUc2Zob\n"
  77. "XhYkHC6zN1Mlq30N0e3Q61YK9LxMdU1vsluXxNq2rfK1Scb1oOlOOtlbV3zA3VRF\n"
  78. "hV3t1nOA9tFmUrwZi0CUMWJE/zbPAyhwWotKyZkCgYEAh0kFicPdbABdrCglXVae\n"
  79. "SnfSjVwYkVuGd5Ze0WADvjYsVkYBHTvhgRNnRJMg+/vWz3Sf4Ps4rgUbqK8Vc20b\n"
  80. "AU5G6H6tlCvPRGm0ZxrwTWDHTcuKRVs+pJE8C/qWoklE/AAhjluWVoGwUMbPGuiH\n"
  81. "6Gf1bgHF6oj/Sq7rv/VLZ8ECgYBeq7ml05YyLuJutuwa4yzQ/MXfghzv4aVyb0F3\n"
  82. "QCdXR6o2IYgR6jnSewrZKlA9aPqFJrwHNR6sNXlnSmt5Fcf/RWO/qgJQGLUv3+rG\n"
  83. "7kuLTNDR05azSdiZc7J89ID3Bkb+z2YkV+6JUiPq/Ei1+nDBEXb/m+/HqALU/nyj\n"
  84. "P3gXeQKBgBusb8Rbd+KgxSA0hwY6aoRTPRt8LNvXdsB9vRcKKHUFQvxUWiUSS+L9\n"
  85. "/Qu1sJbrUquKOHqksV5wCnWnAKyJNJlhHuBToqQTgKXjuNmVdYSe631saiI7PHyC\n"
  86. "eRJ6DxULPxABytJrYCRrNqmXi5TCiqR2mtfalEMOPxz8rUU8dYyx\n"
  87. "-----END RSA PRIVATE KEY-----\n";
  88. static int
  89. file_reader (void *cls, size_t pos, char *buf, int max)
  90. {
  91. FILE *file = cls;
  92. fseek (file, pos, SEEK_SET);
  93. return fread (buf, 1, max, file);
  94. }
  95. /* HTTP access handler call back */
  96. static int
  97. http_ahc (void *cls,
  98. struct MHD_Connection *connection,
  99. const char *url,
  100. const char *method,
  101. const char *upload_data,
  102. const char *version, unsigned int *upload_data_size, void **ptr)
  103. {
  104. static int aptr;
  105. struct MHD_Response *response;
  106. int ret;
  107. FILE *file;
  108. struct stat buf;
  109. if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
  110. return MHD_NO; /* unexpected method */
  111. if (&aptr != *ptr)
  112. {
  113. /* do never respond on first call */
  114. *ptr = &aptr;
  115. return MHD_YES;
  116. }
  117. *ptr = NULL; /* reset when done */
  118. file = fopen (url, "r");
  119. if (file == NULL)
  120. {
  121. response = MHD_create_response_from_data (strlen (EMPTY_PAGE),
  122. (void *) EMPTY_PAGE,
  123. MHD_NO, MHD_NO);
  124. ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
  125. MHD_destroy_response (response);
  126. }
  127. else
  128. {
  129. stat (url, &buf);
  130. response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k PAGE_NOT_FOUND size */
  131. &file_reader, file,
  132. (MHD_ContentReaderFreeCallback)
  133. & fclose);
  134. ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
  135. MHD_destroy_response (response);
  136. }
  137. return ret;
  138. }
  139. int
  140. main (int argc, char *const *argv)
  141. {
  142. struct MHD_Daemon *TLS_daemon;
  143. if (argc == 3){
  144. /* TODO check if this is truly necessary - disallow usage of the blocking /dev/random */
  145. /* gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0); */
  146. TLS_daemon = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION | MHD_USE_DEBUG
  147. | MHD_USE_SSL, atoi (argv[1]),
  148. NULL,
  149. NULL, &http_ahc,
  150. NULL, MHD_OPTION_CONNECTION_TIMEOUT, 256,
  151. MHD_OPTION_HTTPS_MEM_KEY, key_pem,
  152. MHD_OPTION_HTTPS_MEM_CERT, cert_pem,
  153. MHD_OPTION_END);
  154. }
  155. else {
  156. printf
  157. ("Usage : %s HTTP-PORT SECONDS-TO-RUN\n", argv[0]);
  158. return 1;
  159. }
  160. if (TLS_daemon == NULL)
  161. {
  162. printf ("Error: failed to start TLS_daemon");
  163. return 1;
  164. }
  165. else {
  166. printf ("MHD daemon listening on port %d\n", atoi (argv[1]));
  167. }
  168. sleep (atoi (argv[2]));
  169. MHD_stop_daemon (TLS_daemon);
  170. return 0;
  171. }