gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r7753 - in libmicrohttpd/doc: . chapters examples


From: gnunet
Subject: [GNUnet-SVN] r7753 - in libmicrohttpd/doc: . chapters examples
Date: Sat, 11 Oct 2008 11:55:14 -0600 (MDT)

Author: sebdocwriter
Date: 2008-10-11 11:55:14 -0600 (Sat, 11 Oct 2008)
New Revision: 7753

Added:
   libmicrohttpd/doc/chapters/tlsauthentication.inc
   libmicrohttpd/doc/examples/tlsauthentication.c
Modified:
   libmicrohttpd/doc/tutorial.texi
Log:
Tutorial: New chapter for SSL/TLS


Added: libmicrohttpd/doc/chapters/tlsauthentication.inc
===================================================================
--- libmicrohttpd/doc/chapters/tlsauthentication.inc                            
(rev 0)
+++ libmicrohttpd/doc/chapters/tlsauthentication.inc    2008-10-11 17:55:14 UTC 
(rev 7753)
@@ -0,0 +1,130 @@
+We left the basic authentication chapter with the unsatisfactory conclusion 
that
+any traffic, including the credentials, could be intercepted by anyone between
+the browser client and the server. Protecting the data while it is sent over 
+unsecured lines will be the goal of this chapter.
+
+Since version 0.4, the @emph{MHD} library includes support for encrypting the
+traffic by employing SSL/TSL. If @emph{GNU libmicrohttpd} has been configured 
to
+support these, encryption and decryption can be applied transparently on the
+data being sent, with only minimal changes to the actual source code of the 
example.
+
+
address@hidden Preparation
+
+First, a private key for the server will be generated. With this key, the 
server
+will later be able to authenticate itself to the client---preventing anyone 
else
+from stealing the password by faking its identity. The @emph{OpenSSL} suite, 
which
+is available on many operating systems, can generate such a key. For the scope 
of
+this tutorial, we will be content with a 1024 bit key:
address@hidden
+> openssl genrsa -out server.key 1024
address@hidden verbatim
address@hidden
+
+In addition to the key, a certificate describing the server in human readable 
tokens
+is also needed. This certificate will be attested with our aforementioned key. 
In this way,
+we obtain a self-signed certificate, valid for one year. 
+
address@hidden
+> openssl req -days 365 -out server.pem -new -x509 -key server.key
address@hidden verbatim
address@hidden
+
+To avoid unnecessary error messages in the browser, the certificate needs to
+have a name that matches the @emph{URI}, for example, "localhost" or the 
domain.
+If you plan to have a publicly reachable server, you will need to ask a 
trusted third party,
+called @emph{Certificate Authority}, or @emph{CA}, to attest the certificate 
for you. This way,
+any visitor can make sure the server's identity is real.
+
+Whether the server's certificate is signed by us or a third party, once it has 
been accepted
+by the client, both sides will be communicating over encrypted channels. From 
this point on,
+it is the client's turn to authenticate itself. But this has already been 
implemented in the basic 
+authentication scheme.
+
+
address@hidden Changing the source code
+
+We merely have to extend the server program so that it loads the two files 
into memory,
+
address@hidden
+int
+main ()
+{
+  struct MHD_Daemon *daemon;
+  char *key_pem;
+  char *cert_pem;
+
+  key_pem = load_file (SERVERKEYFILE);
+  cert_pem = load_file (SERVERCERTFILE);
+
+  if ((key_pem == NULL) || (cert_pem == NULL))
+  {
+    printf ("The key/certificate files could not be read.\n");
+    return 1;
+  }
address@hidden verbatim
address@hidden
+
+and then we point the @emph{MHD} daemon to it upon initalization. 
address@hidden
+
+  daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY |  MHD_USE_SSL, PORT, 
NULL, NULL,
+                             &answer_to_connection, NULL, 
+                             MHD_OPTION_HTTPS_MEM_KEY, key_pem,
+                             MHD_OPTION_HTTPS_MEM_CERT, cert_pem,
+                             MHD_OPTION_END);
+
+  if (NULL == daemon)
+    {
+      printf ("%s\n", cert_pem);
+  
+      free (key_pem);
+      free (cert_pem);
+  
+      return 1;
+    }
address@hidden verbatim
address@hidden
+
+
+The rest consists of little new besides some additional memory cleanups.
address@hidden
+
+  getchar ();
+
+  MHD_stop_daemon (daemon);
+  free (key_pem);
+  free (cert_pem);
+  
+  return 0;
+}
address@hidden verbatim
address@hidden
+
+
+The rather unexciting file loader can be found in the complete example 
@code{tlsauthentication.c}.
+
address@hidden Remarks
address@hidden @bullet
address@hidden
+While the standard @emph{HTTP} port is 80, it is 443 for @emph{HTTPS}. The 
common internet browsers assume
+standard @emph{HTTP} if they are asked to access other ports than these. 
Therefore, you will have to type 
address@hidden://localhost:8888} explicitly when you test the example, or the 
browser will not know how to
+handle the answer properly.
+
address@hidden
+The remaining weak point is the question how the server will be trusted 
initially. Either a @emph{CA} signs the
+certificate or the client obtains the key over secure means. Anyway, the 
clients have to be aware (or configured) 
+that they should not accept certificates of unknown origin.
+
address@hidden
+The introduced method of certificates makes it mandatory to set an expiration 
date---making it less feasible to
+hardcode certificates in embedded devices. 
+
address@hidden
+The cryptographic facilities consume memory space and computing time. For this 
reason, websites usually consists
+both of uncritically @emph{HTTP} parts and secured @emph{HTTPS}.
+
address@hidden itemize
+
+

Added: libmicrohttpd/doc/examples/tlsauthentication.c
===================================================================
--- libmicrohttpd/doc/examples/tlsauthentication.c                              
(rev 0)
+++ libmicrohttpd/doc/examples/tlsauthentication.c      2008-10-11 17:55:14 UTC 
(rev 7753)
@@ -0,0 +1,253 @@
+#include <platform.h>
+#include <microhttpd.h>
+
+#define PORT 8888
+
+#define REALM     "\"Maintenance\""
+#define USER      "a legitimate user"
+#define PASSWORD  "and his password"
+
+#define SERVERKEYFILE "server.key"
+#define SERVERCERTFILE "server.pem"
+
+char *string_to_base64 (const char *message);
+
+long
+get_file_size (const char *filename)
+{
+  FILE *fp;
+
+  fp = fopen (filename, "rb");
+  if (fp)
+    {
+      long size;
+
+      if ((0 != fseek (fp, 0, SEEK_END)) || (-1 == (size = ftell (fp))))
+        size = 0;
+
+      fclose (fp);
+
+      return size;
+    }
+  else
+    return 0;
+}
+
+char* 
+load_file (const char* filename)
+{
+  FILE *fp;
+  char *buffer;
+  long size;
+
+  size = get_file_size (filename);
+  if (size == 0) return NULL;
+
+  fp = fopen (filename, "rb");
+  if (!fp) return NULL;
+
+  buffer = malloc (size);
+  if (!buffer) {fclose (fp); return NULL;}
+
+  if (size != fread (buffer, 1, size, fp))
+    {  
+      free (buffer);
+      buffer = NULL;
+    }
+
+  fclose (fp);
+  return buffer;
+}
+
+int
+ask_for_authentication (struct MHD_Connection *connection, const char *realm)
+{
+  int ret;
+  struct MHD_Response *response;
+  char *headervalue;
+  const char *strbase = "Basic realm=";
+
+  response = MHD_create_response_from_data (0, NULL, MHD_NO, MHD_NO);
+  if (!response)
+    return MHD_NO;
+
+  headervalue = malloc (strlen (strbase) + strlen (realm) + 1);
+  if (!headervalue)
+    return MHD_NO;
+
+  strcpy (headervalue, strbase);
+  strcat (headervalue, realm);
+
+  ret = MHD_add_response_header (response, "WWW-Authenticate", headervalue);
+  free (headervalue);
+  if (!ret)
+    {
+      MHD_destroy_response (response);
+      return MHD_NO;
+    }
+
+  ret = MHD_queue_response (connection, MHD_HTTP_UNAUTHORIZED, response);
+
+  MHD_destroy_response (response);
+
+  return ret;
+}
+
+int
+is_authenticated (struct MHD_Connection *connection,
+                  const char *username, const char *password)
+{
+  const char *headervalue;
+  char *expected_b64, *expected;
+  const char *strbase = "Basic ";
+  int authenticated;
+
+  headervalue =
+    MHD_lookup_connection_value (connection, MHD_HEADER_KIND,
+                                 "Authorization");
+  if (NULL == headervalue)
+    return 0;
+  if (0 != strncmp (headervalue, strbase, strlen (strbase)))
+    return 0;
+
+  expected = malloc (strlen (username) + 1 + strlen (password) + 1);
+  if (NULL == expected)
+    return 0;
+
+  strcpy (expected, username);
+  strcat (expected, ":");
+  strcat (expected, password);
+
+  expected_b64 = string_to_base64 (expected);
+  if (NULL == expected_b64)
+    return 0;
+
+  strcpy (expected, strbase);
+  authenticated =
+    (strcmp (headervalue + strlen (strbase), expected_b64) == 0);
+
+  free (expected_b64);
+
+  return authenticated;
+}
+
+
+int
+secret_page (struct MHD_Connection *connection)
+{
+  int ret;
+  struct MHD_Response *response;
+  const char *page = "<html><body>A secret.</body></html>";
+
+  response =
+    MHD_create_response_from_data (strlen (page), (void *) page, MHD_NO,
+                                   MHD_NO);
+  if (!response)
+    return MHD_NO;
+
+  ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+  MHD_destroy_response (response);
+
+  return ret;
+}
+
+
+int
+answer_to_connection (void *cls, struct MHD_Connection *connection,
+                      const char *url, const char *method,
+                      const char *version, const char *upload_data,
+                      unsigned int *upload_data_size, void **con_cls)
+{
+  if (0 != strcmp (method, "GET"))
+    return MHD_NO;
+  if (NULL == *con_cls)
+    {
+      *con_cls = connection;
+      return MHD_YES;
+    }
+
+  if (!is_authenticated (connection, USER, PASSWORD))
+    return ask_for_authentication (connection, REALM);
+
+  return secret_page (connection);
+}
+
+
+int
+main ()
+{
+  struct MHD_Daemon *daemon;
+  char *key_pem;
+  char *cert_pem;
+
+  key_pem = load_file (SERVERKEYFILE);
+  cert_pem = load_file (SERVERCERTFILE);
+
+  if ((key_pem == NULL) || (cert_pem == NULL))
+  {
+    printf ("The key/certificate files could not be read.\n");
+    return 1;
+  }
+
+  daemon = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY |  MHD_USE_SSL, PORT, 
NULL, NULL,
+                             &answer_to_connection, NULL, 
+                             MHD_OPTION_HTTPS_MEM_KEY, key_pem, 
MHD_OPTION_HTTPS_MEM_CERT, cert_pem,
+                             MHD_OPTION_END);
+  if (NULL == daemon)
+    {
+      printf ("%s\n", cert_pem);
+  
+      free (key_pem);
+      free (cert_pem);
+  
+      return 1;
+    }
+
+  getchar ();
+
+  MHD_stop_daemon (daemon);
+  free (key_pem);
+  free (cert_pem);
+  
+  return 0;
+}
+
+
+char *
+string_to_base64 (const char *message)
+{
+  const char *lookup =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+  unsigned long l;
+  int i;
+  char *tmp;
+  size_t length = strlen (message);
+
+  tmp = malloc (length * 2);
+  if (NULL == tmp)
+    return tmp;
+
+  tmp[0] = 0;
+
+  for (i = 0; i < length; i += 3)
+    {
+      l = (((unsigned long) message[i]) << 16)
+        | (((i + 1) < length) ? (((unsigned long) message[i + 1]) << 8) : 0)
+        | (((i + 2) < length) ? ((unsigned long) message[i + 2]) : 0);
+
+
+      strncat (tmp, &lookup[(l >> 18) & 0x3F], 1);
+      strncat (tmp, &lookup[(l >> 12) & 0x3F], 1);
+
+      if (i + 1 < length)
+        strncat (tmp, &lookup[(l >> 6) & 0x3F], 1);
+      if (i + 2 < length)
+        strncat (tmp, &lookup[l & 0x3F], 1);
+    }
+
+  if (length % 3)
+    strncat (tmp, "===", 3 - length % 3);
+
+  return tmp;
+}
+

Modified: libmicrohttpd/doc/tutorial.texi
===================================================================
--- libmicrohttpd/doc/tutorial.texi     2008-10-11 14:08:15 UTC (rev 7752)
+++ libmicrohttpd/doc/tutorial.texi     2008-10-11 17:55:14 UTC (rev 7753)
@@ -39,6 +39,7 @@
 * Supporting basic authentication::
 * Processing POST data::
 * Improved processing of POST data::
+* Adding a layer of security::
 * Bibliography::
 * License text::
 * Example programs::
@@ -72,6 +73,10 @@
 @chapter Improved processing of POST data 
 @include chapters/largerpost.inc
 
address@hidden Adding a layer of security
address@hidden Adding a layer of security
address@hidden chapters/tlsauthentication.inc
+
 @node Bibliography
 @appendix Bibliography
 @include chapters/bibliography.inc
@@ -89,6 +94,7 @@
 * basicauthentication.c::
 * simplepost.c::
 * largepost.c::
+* tlsauthentication.c::
 @end menu
 
 @node hellobrowser.c
@@ -127,5 +133,10 @@
 @verbatiminclude examples/largepost.c
 @end smalldisplay
 
address@hidden tlsauthentication.c
address@hidden tlsauthentication.c
address@hidden
address@hidden examples/tlsauthentication.c
address@hidden smalldisplay
 
 @bye





reply via email to

[Prev in Thread] Current Thread [Next in Thread]