gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r14080 - in libmicrohttpd: . doc src/daemon src/include


From: gnunet
Subject: [GNUnet-SVN] r14080 - in libmicrohttpd: . doc src/daemon src/include
Date: Sat, 25 Dec 2010 21:58:06 +0100

Author: grothoff
Date: 2010-12-25 21:58:06 +0100 (Sat, 25 Dec 2010)
New Revision: 14080

Modified:
   libmicrohttpd/AUTHORS
   libmicrohttpd/ChangeLog
   libmicrohttpd/configure.ac
   libmicrohttpd/doc/microhttpd.texi
   libmicrohttpd/src/daemon/EXPORT.sym
   libmicrohttpd/src/daemon/Makefile.am
   libmicrohttpd/src/daemon/connection.c
   libmicrohttpd/src/daemon/daemon.c
   libmicrohttpd/src/daemon/digestauth.c
   libmicrohttpd/src/daemon/internal.h
   libmicrohttpd/src/include/microhttpd.h
Log:
client certs and basic auth support, unmodified patch from MS

Modified: libmicrohttpd/AUTHORS
===================================================================
--- libmicrohttpd/AUTHORS       2010-12-24 10:21:15 UTC (rev 14079)
+++ libmicrohttpd/AUTHORS       2010-12-25 20:58:06 UTC (rev 14080)
@@ -4,6 +4,7 @@
 Sagie Amir (TLS/SSL support using GNUtls)
 Richard Alimi <address@hidden> (performance)
 Amr Ali <address@hidden> (digest authentication)
+Matthieu Speder <address@hidden> (basic authentication, client certificates)
 
 Code contributions also came from:
 Chris GauthierDickey <address@hidden>

Modified: libmicrohttpd/ChangeLog
===================================================================
--- libmicrohttpd/ChangeLog     2010-12-24 10:21:15 UTC (rev 14079)
+++ libmicrohttpd/ChangeLog     2010-12-25 20:58:06 UTC (rev 14080)
@@ -1,3 +1,6 @@
+Sat Dec 25 21:57:14 CET 2010
+       Adding support for basic authentication and client SSL certificates. -MS
+       
 Thu Dec 23 15:40:36 CET 2010
        Increasing nonce length to 128 to support digest authentication
        with Opera (see #1633).

Modified: libmicrohttpd/configure.ac
===================================================================
--- libmicrohttpd/configure.ac  2010-12-24 10:21:15 UTC (rev 14079)
+++ libmicrohttpd/configure.ac  2010-12-25 20:58:06 UTC (rev 14080)
@@ -325,18 +325,18 @@
 AM_CONDITIONAL(ENABLE_HTTPS, test "$enable_https" = "yes")
 
 # optional: HTTP Digest Auth support. Enabled by default
-AC_MSG_CHECKING(whether to support HTTP Digest authentication)
+AC_MSG_CHECKING(whether to support HTTP basic and digest authentication)
 AC_ARG_ENABLE([dauth],
                AS_HELP_STRING([--disable-dauth],
-                       [disable HTTP Digest Auth support]),
+                       [disable HTTP basic and digest Auth support]),
                [enable_dauth=${enableval}],
                [enable_dauth=no])
 
 if test "$enable_dauth" = "yes"
 then
- AC_DEFINE([DAUTH_SUPPORT],[1],[include Digest Auth support])
+ AC_DEFINE([DAUTH_SUPPORT],[1],[include basic and digest Auth support])
 else
- AC_DEFINE([DAUTH_SUPPORT],[0],[disable Digest Auth support])
+ AC_DEFINE([DAUTH_SUPPORT],[0],[disable basic and digest Auth support])
 fi
 AC_MSG_RESULT($enable_dauth)
 
@@ -416,7 +416,7 @@
   libcurl (testing): ${MSG_CURL}
   Target directory:  ${prefix}
   Messages:          ${enable_messages}
-  HTTP Digest Auth:  ${enable_dauth}
+  HTTP Authentic.:   ${enable_dauth}
   Postproc:          ${enable_postprocessor}
   HTTPS support:     ${enable_https}
 ])

Modified: libmicrohttpd/doc/microhttpd.texi
===================================================================
--- libmicrohttpd/doc/microhttpd.texi   2010-12-24 10:21:15 UTC (rev 14079)
+++ libmicrohttpd/doc/microhttpd.texi   2010-12-25 20:58:06 UTC (rev 14080)
@@ -117,7 +117,7 @@
 * microhttpd-inspect::          Implementing external @code{select}.
 * microhttpd-requests::         Handling requests.
 * microhttpd-responses::        Building responses to requests.
-* microhttpd-dauth::                   Utilizing Digest Authentication.
+* microhttpd-dauth::            Utilizing Authentication.
 * microhttpd-post::             Adding a @code{POST} processor.
 * microhttpd-info::             Obtaining status information.
 
@@ -259,7 +259,6 @@
 corresponding format string for printing such a data type (without
 the percent sign).
 
-
 @c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 @c ------------------------------------------------------------
@@ -449,6 +448,20 @@
 "const char*" argument.
 This should be used in conjunction with 'MHD_OPTION_HTTPS_MEM_KEY'.
    
address@hidden MHD_OPTION_HTTPS_MEM_TRUST
address@hidden SSL
address@hidden TLS
+Memory pointer to the CA certificate to be used by the
+HTTPS daemon to authenticate and trust clients certificates.
+This option should be followed by an "const char*" argument.
+The presence of this option activates the request of certificate
+to the client. The request to the client is marked optional, and
+it is the responsability of the server to check the presence
+of the certificate if needed.
+Note that most browsers will only present a client certificate
+only if they have one matching the specified CA, not sending
+any certificate otherwise.
+   
 @item MHD_OPTION_HTTPS_CRED_TYPE
 @cindex SSL
 @cindex TLS
@@ -680,6 +693,12 @@
 Takes no extra arguments.  Allows access to the underlying GNUtls session 
 (HTTPS connections only).
 
address@hidden MHD_CONNECTION_INFO_GNUTLS_CLIENT_CERT
+Allows access to the underlying GNUtls client certificate.
+Equivalent to calling directly MHD_cert_auth_get_certificate.
+Takes no extra arguments.
+(HTTPS connections only).
+
 @end table
 @end deftp
 
@@ -1263,7 +1282,7 @@
 
 @c ------------------------------------------------------------
 @node microhttpd-response create
address@hidden Creating response objects
address@hidden Creating a response object
 
 
 @deftypefun {struct MHD_Response *} MHD_create_response_from_callback 
(uint64_t size, size_t block_size, MHD_ContentReaderCallback crc, void 
*crc_cls, MHD_ContentReaderFreeCallback crfc)
@@ -1457,8 +1476,69 @@
 
 @c ------------------------------------------------------------
 @node microhttpd-dauth
address@hidden Utilizing Digest Authentication
address@hidden Utilizing Authentication
 
address@hidden
address@hidden support three types of client authentication.
+
+Basic authentication uses a simple authentication method based
+on BASE64 algorithm. Username and password are exchanged in clear
+between the client and the server, so this method must only be used
+for non-sensitive content or when the session is protected with https.
+When using basic authentication @mhd{} will have access to the clear
+password, possibily allowing to create a chained authentication
+toward an external authentication server.
+
+Digest authentication uses a one-way authentication method based
+on MD5 hash algorithm. Only the hash will transit over the network,
+hence protecting the user password. The nonce will prevent replay
+attacks. This method is appropriate for general use, especially
+when https is not used to encrypt the session.
+
+Client certificate authentication uses a X.509 certificate from
+the client. This is the strongest authentication mechanism but it
+requires the use of https. Client certificate authentication can
+be used simultaneously with Basic or Digest Authentication in order
+to provide a two levels authentication (like for instance separate
+machine and user authentication).
+
address@hidden
+* microhttpd-dauth basic:: Using Basic Authentication.
+* microhttpd-dauth digest:: Using Digest Authentication.
+* microhttpd-dauth cert:: Using Client Certificate Authentication.
address@hidden menu
+
address@hidden ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
address@hidden ------------------------------------------------------------
address@hidden microhttpd-dauth basic
address@hidden Using Basic Authentication
+
address@hidden {char *} MHD_basic_auth_get_username_password (struct 
MHD_Connection *connection, char** password)
+Get the username and password from the basic authorization header sent by the 
client.
+Return @mynull{} if no username could be found, a pointer to the username if 
found.
+If returned value is not @mynull{}, the value must be free()'ed.
+
address@hidden reference a buffer to store the password. It can be @mynull{}.
+If returned value is not @mynull{}, the value must be free()'ed.
address@hidden deftypefun
+
address@hidden {int} MHD_queue_basic_auth_fail_response (struct MHD_Connection 
*connection, const char *realm, struct MHD_Response *response)
+Queues a response to request basic authentication from the client.
+Return @code{MHD_YES} if successful, otherwise @code{MHD_NO}.
+
address@hidden must reference to a zero-terminated string representing the 
realm.
+
address@hidden a response structure to specify what shall be presented to the
+client with a 401 HTTP status.
address@hidden deftypefun
+
address@hidden ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
address@hidden ------------------------------------------------------------
address@hidden microhttpd-dauth digest
address@hidden Using Digest Authentication
+
 @deftypefun {char *} MHD_digest_auth_get_username (struct MHD_Connection 
*connection)
 Find and return a pointer to the username value from the request header.
 Return @mynull{} if the value is not found or header does not exist.
@@ -1467,7 +1547,7 @@
 
 @deftypefun int MHD_digest_auth_check (struct MHD_Connection *connection, 
const char *realm, const char *username, const char *password, unsigned int 
nonce_timeout)
 Checks if the provided values in the WWW-Authenticate header are valid
-and sound according to RFC2716. If valid return MHD_YES, otherwise return 
MHD_NO.
+and sound according to RFC2716. If valid return @code{MHD_YES}, otherwise 
return @code{MHD_NO}.
 
 @var{realm} must reference to a zero-terminated string representing the realm.
 
@@ -1483,8 +1563,10 @@
 
 @deftypefun int MHD_queue_auth_fail_response (struct MHD_Connection 
*connection, const char *realm, const char *opaque, struct MHD_Response 
*response, int signal_stale)
 Queues a response to request authentication from the client,
-return MHD_YES if successful, otherwise MHD_NO.
+return @code{MHD_YES} if successful, otherwise @code{MHD_NO}.
 
address@hidden must reference to a zero-terminated string representing the 
realm.
+
 @var{opaque} must reference to a zero-terminated string representing a value
 that gets passed to the client and expected to be passed again to the server
 as-is. This value can be a hexadecimal or base64 string.
@@ -1494,8 +1576,8 @@
 
 @var{signal_stale} a value that signals "stale=true" in the response header to
 indicate the invalidity of the nonce and no need to ask for authentication
-parameters and only a new nonce gets generated. MHD_YES to generate a new
-nonce, MHD_NO to ask for authentication parameters.
+parameters and only a new nonce gets generated. @code{MHD_YES} to generate a 
new
+nonce, @code{MHD_NO} to ask for authentication parameters.
 @end deftypefun
 
 Example: handling digest authentication requests and responses.
@@ -1563,6 +1645,39 @@
 @c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
 @c ------------------------------------------------------------
address@hidden microhttpd-dauth cert
address@hidden Using Client Certificate Authentication
+
address@hidden {void *} MHD_cert_auth_get_certificate (struct MHD_Connection 
*connection)
+Get the client's X.509 certificate.
+Return @mynull{} if no valid client certificate was found, a pointer to the 
certificate
+(which can be casted to gnutls_x509_crt_t) if found.
+The certificate is cached between calls for a same https session and must not 
but
+manually modified or free()'ed.
address@hidden deftypefun
+
address@hidden {char *} MHD_cert_auth_get_dn (struct MHD_Connection *connection)
+Get the distinguished name from the client's certificate.
+Return @mynull{} if the certificate doesn't contain a dn or if no valid 
certificate was
+found, a pointer to the dn if found. If returned value is not @mynull{}, the 
value must
+be free()'ed.
address@hidden deftypefun
+
address@hidden {char *} MHD_cert_auth_get_alt_name (struct MHD_Connection 
*connection, int nametype, unsigned int index)
+Get the alternative name of specified type from the client's certificate.
+Return @mynull{} if the certificate doesn't contain a matching alternative 
name or if no
+valid certificate was found, a pointer to the alternative name if found. If 
returned
+value is not @mynull{}, the value must be free()'ed.
+
address@hidden The requested name type (of type 'enum 
gnutls_x509_subject_alt_name_t')
+
address@hidden The position of the alternative name if multiple names are 
matching the
+requested type, 0 for the first matching name
address@hidden deftypefun
+
address@hidden ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
address@hidden ------------------------------------------------------------
 @node microhttpd-post
 @chapter Adding a @code{POST} processor
 @cindex POST method

Modified: libmicrohttpd/src/daemon/EXPORT.sym
===================================================================
--- libmicrohttpd/src/daemon/EXPORT.sym 2010-12-24 10:21:15 UTC (rev 14079)
+++ libmicrohttpd/src/daemon/EXPORT.sym 2010-12-25 20:58:06 UTC (rev 14080)
@@ -27,3 +27,8 @@
 MHD_digest_auth_get_username
 MHD_digest_auth_check
 MHD_queue_auth_fail_response
+MHD_basic_auth_get_username_password
+MHD_queue_basic_auth_fail_response
+MHD_cert_auth_get_certificate
+MHD_cert_auth_get_dn
+MHD_cert_auth_get_alt_name

Modified: libmicrohttpd/src/daemon/Makefile.am
===================================================================
--- libmicrohttpd/src/daemon/Makefile.am        2010-12-24 10:21:15 UTC (rev 
14079)
+++ libmicrohttpd/src/daemon/Makefile.am        2010-12-25 20:58:06 UTC (rev 
14080)
@@ -37,7 +37,8 @@
 if ENABLE_DAUTH
 libmicrohttpd_la_SOURCES += \
   digestauth.c \
-  md5.c md5.h 
+  md5.c md5.h \
+  base64.c base64.h
 endif
 
 if ENABLE_HTTPS

Modified: libmicrohttpd/src/daemon/connection.c
===================================================================
--- libmicrohttpd/src/daemon/connection.c       2010-12-24 10:21:15 UTC (rev 
14079)
+++ libmicrohttpd/src/daemon/connection.c       2010-12-25 20:58:06 UTC (rev 
14080)
@@ -2316,7 +2316,11 @@
       if (connection->tls_session == NULL)
        return NULL;
       return (const union MHD_ConnectionInfo *) &connection->tls_session;
+#if DAUTH_SUPPORT
+    case MHD_CONNECTION_INFO_GNUTLS_CLIENT_CERT:
+      return (const union MHD_ConnectionInfo *) 
MHD_cert_auth_get_certificate(connection);
 #endif
+#endif
     case MHD_CONNECTION_INFO_CLIENT_ADDRESS:
       return (const union MHD_ConnectionInfo *) &connection->addr;
     default:

Modified: libmicrohttpd/src/daemon/daemon.c
===================================================================
--- libmicrohttpd/src/daemon/daemon.c   2010-12-24 10:21:15 UTC (rev 14079)
+++ libmicrohttpd/src/daemon/daemon.c   2010-12-25 20:58:06 UTC (rev 14080)
@@ -439,6 +439,19 @@
   gnutls_datum_t key;
   gnutls_datum_t cert;
 
+  if (daemon->https_mem_trust) {
+               cert.data = (unsigned char *) daemon->https_mem_trust;
+               cert.size = strlen(daemon->https_mem_trust);
+               if (gnutls_certificate_set_x509_trust_mem(daemon->x509_cred, 
&cert,
+                               GNUTLS_X509_FMT_PEM) < 0) {
+#if HAVE_MESSAGES
+                       MHD_DLOG(daemon,
+                                       "Bad trust certificate format\n");
+#endif
+                       return -1;
+               }
+       }
+
   /* certificate & key loaded from memory */
   if (daemon->https_mem_cert && daemon->https_mem_key)
     {
@@ -987,6 +1000,10 @@
       gnutls_transport_set_push_function (connection->tls_session,
                                          (gnutls_push_func) &
                                                send_param_adapter);
+
+      if (daemon->https_mem_trust){
+      gnutls_certificate_server_set_request(connection->tls_session, 
GNUTLS_CERT_REQUEST);
+      }
     }
 #endif
 
@@ -1058,6 +1075,8 @@
 #if HTTPS_SUPPORT
           if (pos->tls_session != NULL)
             gnutls_deinit (pos->tls_session);
+          if (pos->client_cert != NULL)
+            gnutls_x509_crt_deinit (pos->client_cert);
 #endif
           MHD_ip_limit_del (daemon, (struct sockaddr*)pos->addr, 
pos->addr_len);
          if (pos->response != NULL)
@@ -1474,6 +1493,16 @@
                     opt);        
 #endif
           break;
+        case MHD_OPTION_HTTPS_MEM_TRUST:
+         if (0 != (daemon->options & MHD_USE_SSL))
+           daemon->https_mem_trust = va_arg (ap, const char *);
+#if HAVE_MESSAGES
+         else
+           FPRINTF (stderr,
+                    "MHD HTTPS option %d passed to MHD but MHD_USE_SSL not 
set\n",
+                    opt);
+#endif
+          break;
        case MHD_OPTION_HTTPS_CRED_TYPE:
          daemon->cred_type = va_arg (ap, gnutls_credentials_type_t);
          break;
@@ -1561,6 +1590,7 @@
                case MHD_OPTION_SOCK_ADDR:
                case MHD_OPTION_HTTPS_MEM_KEY:
                case MHD_OPTION_HTTPS_MEM_CERT:
+               case MHD_OPTION_HTTPS_MEM_TRUST:
                case MHD_OPTION_HTTPS_PRIORITIES:
                case MHD_OPTION_ARRAY:
                  if (MHD_YES != parse_options (daemon,
@@ -1606,8 +1636,8 @@
           break;
         default:
 #if HAVE_MESSAGES
-          if ((opt >= MHD_OPTION_HTTPS_MEM_KEY) &&
-              (opt <= MHD_OPTION_HTTPS_PRIORITIES))
+          if (((opt >= MHD_OPTION_HTTPS_MEM_KEY) &&
+              (opt <= MHD_OPTION_HTTPS_PRIORITIES)) || (opt == 
MHD_OPTION_HTTPS_MEM_TRUST))
             {
               FPRINTF (stderr,
                        "MHD HTTPS option %d passed to MHD compiled without 
HTTPS support\n",

Modified: libmicrohttpd/src/daemon/digestauth.c
===================================================================
--- libmicrohttpd/src/daemon/digestauth.c       2010-12-24 10:21:15 UTC (rev 
14079)
+++ libmicrohttpd/src/daemon/digestauth.c       2010-12-25 20:58:06 UTC (rev 
14080)
@@ -19,13 +19,15 @@
 
 /**
  * @file digestauth.c
- * @brief Implements HTTP/1.1 Digest Auth according to RFC2617
+ * @brief Implements various HTTP authentication methods
  * @author Amr Ali
+ * @author Matthieu Speder
  */
 
 #include "platform.h"
 #include "internal.h"
 #include "md5.h"
+#include "base64.h"
 
 #define HASH_MD5_HEX_LEN (2 * MD5_DIGEST_SIZE)
 
@@ -35,6 +37,11 @@
 #define _BASE          "Digest "
 
 /**
+ * Beginning string for any valid Basic authentication header.
+ */
+#define _BASIC_BASE            "Basic "
+
+/**
  * Maximum length of a username for digest authentication.
  */
 #define MAX_USERNAME_LENGTH 128
@@ -636,5 +643,218 @@
   return ret;
 }
 
+/**
+ * Get the username and password from the basic authorization header sent by 
the client
+ *
+ * @param connection The MHD connection structure
+ * @param password a pointer for the password
+ * @return NULL if no username could be found, a pointer
+ *                     to the username if found
+ */
+char *
+MHD_basic_auth_get_username_password(struct MHD_Connection *connection,
+               char** password) {
+       size_t len;
+       const char *header;
+       char *decode;
+       const char *separator;
+       char *user;
 
+       header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND,
+                       MHD_HTTP_HEADER_AUTHORIZATION);
+       if (header == NULL)
+               return NULL;
+       if (strncmp(header, _BASIC_BASE, strlen(_BASIC_BASE)) != 0)
+               return NULL;
+       header += strlen(_BASIC_BASE);
+       decode = BASE64Decode(header);
+       if (decode == NULL) {
+#if HAVE_MESSAGES
+               MHD_DLOG(connection->daemon, "Error decoding basic 
authentication\n");
+#endif
+               return NULL;
+       }
+       /* Find user:password pattern */
+       separator = strstr(decode, ":");
+       if (separator == NULL) {
+#if HAVE_MESSAGES
+               MHD_DLOG(connection->daemon,
+                               "Basic authentication doesn't contain ':' 
separator\n");
+#endif
+               free(decode);
+               return NULL;
+       }
+       user = strndup(decode, separator - decode);
+       if (password != NULL) {
+               *password = strdup(separator + 1);
+       }
+       free(decode);
+       return user;
+}
+
+/**
+ * Queues a response to request basic authentication from the client
+ *
+ * @param connection The MHD connection structure
+ * @param realm the realm presented to the client
+ * @return MHD_YES on success, MHD_NO otherwise
+ */
+int MHD_queue_basic_auth_fail_response(struct MHD_Connection *connection,
+               const char *realm, struct MHD_Response *response) {
+       int ret;
+       size_t hlen = strlen(realm) + sizeof("Basic realm=\"\"");
+       char header[hlen];
+       snprintf(header, sizeof(header), "Basic realm=\"%s\"", realm);
+       ret = MHD_add_response_header(response, 
MHD_HTTP_HEADER_WWW_AUTHENTICATE,
+                       header);
+       if (MHD_YES == ret)
+               ret = MHD_queue_response(connection, MHD_HTTP_UNAUTHORIZED, 
response);
+       return ret;
+}
+
+#if HTTPS_SUPPORT
+
+/**
+ * Get the client's certificate
+ *
+ * @param connection The MHD connection structure
+ * @return NULL if no valid client certificate could be found, a pointer
+ *                     to the certificate if found
+ */
+void*
+MHD_cert_auth_get_certificate(struct MHD_Connection *connection) {
+
+       if (connection->client_cert == NULL && connection->client_cert_status 
== 0) {
+               if (connection->tls_session == NULL) {
+                       connection->client_cert_status = GNUTLS_CERT_INVALID;
+                       return NULL;
+               }
+
+               if (gnutls_certificate_verify_peers2(connection->tls_session,
+                               &connection->client_cert_status)) {
+                       connection->client_cert_status = GNUTLS_CERT_INVALID;
+                       return NULL;
+               }
+
+               unsigned int listsize;
+               const gnutls_datum_t * pcert = gnutls_certificate_get_peers(
+                               connection->tls_session, &listsize);
+               if (pcert == NULL || listsize == 0) {
+#if HAVE_MESSAGES
+                       MHD_DLOG(connection->daemon,
+                                       "Failed to retrieve client certificate 
chain\n");
+#endif
+                       connection->client_cert_status = GNUTLS_CERT_INVALID;
+                       return NULL;
+               }
+
+               if (gnutls_x509_crt_init(&connection->client_cert)) {
+#if HAVE_MESSAGES
+                       MHD_DLOG(connection->daemon,
+                                       "Failed to initialize client 
certificate\n");
+#endif
+                       connection->client_cert = NULL;
+                       connection->client_cert_status = GNUTLS_CERT_INVALID;
+                       return NULL;
+               }
+               if (gnutls_x509_crt_import(connection->client_cert, &pcert[0],
+                               GNUTLS_X509_FMT_DER)) {
+#if HAVE_MESSAGES
+                       MHD_DLOG(connection->daemon,
+                                       "Failed to import client 
certificate\n");
+#endif
+                       gnutls_x509_crt_deinit(connection->client_cert);
+                       connection->client_cert = NULL;
+                       connection->client_cert_status = GNUTLS_CERT_INVALID;
+                       return NULL;
+               }
+       }
+
+       return connection->client_cert;
+}
+
+/**
+ * Get the distinguished name from the client's certificate
+ *
+ * @param connection The MHD connection structure
+ * @return NULL if no dn or certificate could be found, a pointer
+ *                     to the dn if found
+ */
+char *
+MHD_cert_auth_get_dn(struct MHD_Connection *connection) {
+
+       char* buf;
+       size_t lbuf = 0;
+
+       gnutls_x509_crt_t cert = MHD_cert_auth_get_certificate(connection);
+       if (cert == NULL)
+               return NULL;
+
+       gnutls_x509_crt_get_dn(cert, NULL, &lbuf);
+       buf = malloc(lbuf);
+       if (buf == NULL) {
+#if HAVE_MESSAGES
+               MHD_DLOG(connection->daemon,
+                               "Failed to allocate memory for certificate 
dn\n");
+#endif
+               return NULL;
+       }
+       gnutls_x509_crt_get_dn(cert, buf, &lbuf);
+       return buf;
+
+}
+
+/**
+ * Get the alternative name of specified type from the client's certificate
+ *
+ * @param connection The MHD connection structure
+ * @param nametype The requested name type
+ * @param index The position of the alternative name if multiple names are
+ *                     matching the requested type, 0 for the first matching 
name
+ * @return NULL if no matching alternative name could be found, a pointer
+ *                     to the alternative name if found
+ */
+char *
+MHD_cert_auth_get_alt_name(struct MHD_Connection *connection, int nametype, 
unsigned int index) {
+
+       char* buf;
+       size_t lbuf;
+       unsigned int seq = 0;
+       unsigned int subseq = 0;
+       int result;
+       unsigned int type;
+
+       gnutls_x509_crt_t cert = MHD_cert_auth_get_certificate(connection);
+       if (cert == NULL)
+               return NULL;
+
+       for (;; seq++) {
+               lbuf = 0;
+               result = gnutls_x509_crt_get_subject_alt_name2(cert, seq, NULL, 
&lbuf,
+                               &type, NULL);
+               if (result == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+                       return NULL;
+               if (type != nametype)
+                       continue;
+               if (subseq != index) {
+                       subseq++;
+                       continue;
+               }
+               buf = malloc(lbuf);
+               if (buf == NULL) {
+#if HAVE_MESSAGES
+                       MHD_DLOG(connection->daemon,
+                                       "Failed to allocate memory for 
certificate alt name\n");
+#endif
+                       return NULL;
+               }
+               gnutls_x509_crt_get_subject_alt_name2(cert, seq, buf, &lbuf, 
NULL, NULL);
+               return buf;
+
+       }
+
+}
+
+#endif /* HTTPS */
+
 /* end of digestauth.c */

Modified: libmicrohttpd/src/daemon/internal.h
===================================================================
--- libmicrohttpd/src/daemon/internal.h 2010-12-24 10:21:15 UTC (rev 14079)
+++ libmicrohttpd/src/daemon/internal.h 2010-12-25 20:58:06 UTC (rev 14080)
@@ -705,6 +705,17 @@
    * Memory location to return for protocol session info.
    */
   int cipher;
+
+  /**
+   * Validation status of client's certificate.
+   */
+  gnutls_certificate_status_t client_cert_status;
+
+  /**
+   * Client's certificate.
+   */
+  gnutls_x509_crt_t client_cert;
+
 #endif
 };
 
@@ -920,6 +931,11 @@
    */
   const char *https_mem_cert;
 
+  /**
+   * Pointer to our SSL/TLS certificate authority (in ASCII) in memory.
+   */
+  const char *https_mem_trust;
+
 #endif
 
 #ifdef DAUTH_SUPPORT

Modified: libmicrohttpd/src/include/microhttpd.h
===================================================================
--- libmicrohttpd/src/include/microhttpd.h      2010-12-24 10:21:15 UTC (rev 
14079)
+++ libmicrohttpd/src/include/microhttpd.h      2010-12-25 20:58:06 UTC (rev 
14080)
@@ -580,9 +580,14 @@
    * Desired size of the stack for threads created by MHD. Followed
    * by an argument of type 'size_t'.  Use 0 for system 'default'.
    */
-  MHD_OPTION_THREAD_STACK_SIZE = 19
+  MHD_OPTION_THREAD_STACK_SIZE = 19,
 
-
+  /**
+   * Memory pointer for the certificate (ca.pem) to be used by the
+   * HTTPS daemon for client authentification.
+   * This option should be followed by a "const char*" argument.
+   */
+  MHD_OPTION_HTTPS_MEM_TRUST =20
 };
 
 
@@ -719,7 +724,12 @@
   /**
    * Get the GNUTLS session handle.
    */
-  MHD_CONNECTION_INFO_GNUTLS_SESSION
+  MHD_CONNECTION_INFO_GNUTLS_SESSION,
+
+  /**
+   * Get the GNUTLS client certificate handle.
+   */
+  MHD_CONNECTION_INFO_GNUTLS_CLIENT_CERT
 };
 
 /**
@@ -1430,6 +1440,65 @@
                              int signal_stale);
 
 
+/**
+ * Get the username and password from the basic authorization header sent by 
the client
+ *
+ * @param connection The MHD connection structure
+ * @param password a pointer for the password
+ * @return NULL if no username could be found, a pointer
+ *                     to the username if found
+ */
+char *
+MHD_basic_auth_get_username_password(struct MHD_Connection *connection,
+                            char** password);
+
+/**
+ * Queues a response to request basic authentication from the client
+ *
+ * @param connection The MHD connection structure
+ * @param realm the realm presented to the client
+ * @return MHD_YES on success, MHD_NO otherwise
+ */
+int
+MHD_queue_basic_auth_fail_response(struct MHD_Connection *connection,
+                            const char *realm,
+                            struct MHD_Response *response);
+
+/**
+ * Get the client's certificate
+ *
+ * @param connection The MHD connection structure
+ * @return NULL if no valid client certificate could be found, a pointer
+ *                     to the certificate if found
+ */
+void*
+MHD_cert_auth_get_certificate(struct MHD_Connection *connection);
+
+/**
+ * Get the distinguished name from the client's certificate
+ *
+ * @param connection The MHD connection structure
+ * @return NULL if no dn or certificate could be found, a pointer
+ *                     to the dn if found
+ */
+char *
+MHD_cert_auth_get_dn(struct MHD_Connection *connection);
+
+/**
+ * Get the alternative name of specified type from the client's certificate
+ *
+ * @param connection The MHD connection structure
+ * @param nametype The requested name type
+ * @param index The position of the alternative name if multiple names are
+ *                     matching the requested type, 0 for the first matching 
name
+ * @return NULL if no matching alternative name could be found, a pointer
+ *                     to the alternative name if found
+ */
+char *
+MHD_cert_auth_get_alt_name(struct MHD_Connection *connection,
+                            int nametype,
+                            unsigned int index);
+
 /* ********************** generic query functions ********************** */
 
 /**
@@ -1454,6 +1523,11 @@
   void * /* gnutls_session_t */ tls_session;
 
   /**
+   * GNUtls client certificate handle, of type "gnutls_x509_crt_t".
+   */
+  void * /* gnutls_x509_crt_t */ client_cert;
+
+  /**
    * Address information for the client.
    */
   struct sockaddr_in * client_addr;




reply via email to

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