client certs and basic auth support, unmodified patch from MS

This commit is contained in:
Christian Grothoff
2010-12-25 20:58:06 +00:00
parent 65c3125ced
commit fe4e71ecaa
11 changed files with 489 additions and 20 deletions
+1
View File
@@ -4,6 +4,7 @@ Nils Durner <durner@gnunet.org> (W32 port)
Sagie Amir (TLS/SSL support using GNUtls)
Richard Alimi <rich@velvetsea.net> (performance)
Amr Ali <amr.ali.cc@gmail.com> (digest authentication)
Matthieu Speder <mspeder@users.sourceforge.net> (basic authentication, client certificates)
Code contributions also came from:
Chris GauthierDickey <chrisg@cs.du.edu>
+3
View File
@@ -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).
+5 -5
View File
@@ -325,18 +325,18 @@ AC_MSG_RESULT($enable_https)
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 @@ AC_MSG_NOTICE([Configuration Summary:
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}
])
+123 -8
View File
@@ -117,7 +117,7 @@ GNU libmicrohttpd is a GNU package.
* 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 @@ alternative type and also define @code{MHD_LONG_LONG_PRINTF} to the
corresponding format string for printing such a data type (without
the percent sign).
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@@ -449,6 +448,20 @@ HTTPS daemon. This option should be followed by an
"const char*" argument.
This should be used in conjunction with 'MHD_OPTION_HTTPS_MEM_KEY'.
@item MHD_OPTION_HTTPS_MEM_TRUST
@cindex SSL
@cindex 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 finding out the TLS/SSL protocol used
Takes no extra arguments. Allows access to the underlying GNUtls session
(HTTPS connections only).
@item 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 @@ the @code{MHD_Response} object is released.
@c ------------------------------------------------------------
@node microhttpd-response create
@section Creating response objects
@section 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,7 +1476,68 @@ We should not modify the value, unless we know what we are doing.
@c ------------------------------------------------------------
@node microhttpd-dauth
@chapter Utilizing Digest Authentication
@chapter Utilizing Authentication
@noindent
@mhd{} 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).
@menu
* microhttpd-dauth basic:: Using Basic Authentication.
* microhttpd-dauth digest:: Using Digest Authentication.
* microhttpd-dauth cert:: Using Client Certificate Authentication.
@end menu
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@node microhttpd-dauth basic
@section Using Basic Authentication
@deftypefun {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.
@var{password} reference a buffer to store the password. It can be @mynull{}.
If returned value is not @mynull{}, the value must be free()'ed.
@end deftypefun
@deftypefun {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}.
@var{realm} must reference to a zero-terminated string representing the realm.
@var{response} a response structure to specify what shall be presented to the
client with a 401 HTTP status.
@end deftypefun
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@node microhttpd-dauth digest
@section 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.
@@ -1467,7 +1547,7 @@ If returned value is not @mynull{}, the value must be free()'ed.
@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,7 +1563,9 @@ Most of the time it is sound to specify 300 seconds as its values.
@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}.
@var{realm} 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
@@ -1494,8 +1576,8 @@ client with a 401 HTTP status.
@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.
@@ -1562,6 +1644,39 @@ ahc_echo (void *cls,
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@node microhttpd-dauth cert
@section Using Client Certificate Authentication
@deftypefun {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.
@end deftypefun
@deftypefun {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.
@end deftypefun
@deftypefun {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.
@var{nametype} The requested name type (of type 'enum gnutls_x509_subject_alt_name_t')
@var{index} The position of the alternative name if multiple names are matching the
requested type, 0 for the first matching name
@end deftypefun
@c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
@c ------------------------------------------------------------
@node microhttpd-post
@chapter Adding a @code{POST} processor
+5
View File
@@ -27,3 +27,8 @@ MHD_get_version
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
+2 -1
View File
@@ -37,7 +37,8 @@ endif
if ENABLE_DAUTH
libmicrohttpd_la_SOURCES += \
digestauth.c \
md5.c md5.h
md5.c md5.h \
base64.c base64.h
endif
if ENABLE_HTTPS
+4
View File
@@ -2316,6 +2316,10 @@ MHD_get_connection_info (struct MHD_Connection *connection,
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;
+32 -2
View File
@@ -439,6 +439,19 @@ MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
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 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
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 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
#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)
@@ -1472,6 +1491,16 @@ parse_options_va (struct MHD_Daemon *daemon,
FPRINTF (stderr,
"MHD HTTPS option %d passed to MHD but MHD_USE_SSL not set\n",
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:
@@ -1561,6 +1590,7 @@ parse_options_va (struct MHD_Daemon *daemon,
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 @@ parse_options_va (struct MHD_Daemon *daemon,
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",
+221 -1
View File
@@ -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)
@@ -34,6 +36,11 @@
*/
#define _BASE "Digest "
/**
* Beginning string for any valid Basic authentication header.
*/
#define _BASIC_BASE "Basic "
/**
* Maximum length of a username for digest authentication.
*/
@@ -636,5 +643,218 @@ MHD_queue_auth_fail_response(struct MHD_Connection *connection,
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 */
+16
View File
@@ -705,6 +705,17 @@ struct MHD_Connection
* 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 @@ struct MHD_Daemon
*/
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
+77 -3
View File
@@ -580,9 +580,14 @@ enum MHD_OPTION
* 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 @@ enum MHD_ConnectionInfoType
/**
* 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 @@ MHD_queue_auth_fail_response (struct MHD_Connection *connection,
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 ********************** */
/**
@@ -1453,6 +1522,11 @@ union MHD_ConnectionInfo
*/
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.
*/