GNU libmicrohttpd  0.9.5
digestauth.c File Reference

Implements HTTP digest authentication. More...

#include "platform.h"
#include <limits.h>
#include "internal.h"
#include "md5.h"
Include dependency graph for digestauth.c:

Go to the source code of this file.

Macros

#define HASH_MD5_HEX_LEN   (2 * MD5_DIGEST_SIZE)
#define _BASE   "Digest "
#define MAX_USERNAME_LENGTH   128
#define MAX_REALM_LENGTH   256
#define MAX_AUTH_RESPONSE_LENGTH   128

Functions

static void cvthex (const unsigned char *bin, size_t len, char *hex)
static void digest_calc_ha1 (const char *alg, const char *username, const char *realm, const char *password, const char *nonce, const char *cnonce, char *sessionkey)
static void digest_calc_response (const char *ha1, const char *nonce, const char *noncecount, const char *cnonce, const char *qop, const char *method, const char *uri, const char *hentity, char *response)
static int lookup_sub_value (char *dest, size_t size, const char *data, const char *key)
static int check_nonce_nc (struct MHD_Connection *connection, const char *nonce, unsigned long int nc)
char * MHD_digest_auth_get_username (struct MHD_Connection *connection)
static void calculate_nonce (uint32_t nonce_time, const char *method, const char *rnd, unsigned int rnd_size, const char *uri, const char *realm, char *nonce)
static int test_header (struct MHD_Connection *connection, const char *key, const char *value)
static int check_argument_match (struct MHD_Connection *connection, const char *args)
int MHD_digest_auth_check (struct MHD_Connection *connection, const char *realm, const char *username, const char *password, unsigned int nonce_timeout)
int MHD_queue_auth_fail_response (struct MHD_Connection *connection, const char *realm, const char *opaque, struct MHD_Response *response, int signal_stale)

Detailed Description

Implements HTTP digest authentication.

Author:
Amr Ali
Matthieu Speder

Definition in file digestauth.c.


Macro Definition Documentation

#define _BASE   "Digest "

Beginning string for any valid Digest authentication header.

Definition at line 35 of file digestauth.c.

Referenced by MHD_digest_auth_check(), and MHD_digest_auth_get_username().

#define HASH_MD5_HEX_LEN   (2 * MD5_DIGEST_SIZE)
#define MAX_AUTH_RESPONSE_LENGTH   128

Maximum length of the response in digest authentication.

Definition at line 50 of file digestauth.c.

Referenced by MHD_digest_auth_check().

#define MAX_REALM_LENGTH   256

Maximum length of a realm for digest authentication.

Definition at line 45 of file digestauth.c.

Referenced by MHD_digest_auth_check().

#define MAX_USERNAME_LENGTH   128

Maximum length of a username for digest authentication.

Definition at line 40 of file digestauth.c.

Referenced by MHD_digest_auth_check(), and MHD_digest_auth_get_username().


Function Documentation

static void calculate_nonce ( uint32_t  nonce_time,
const char *  method,
const char *  rnd,
unsigned int  rnd_size,
const char *  uri,
const char *  realm,
char *  nonce 
)
static

Calculate the server nonce so that it mitigates replay attacks The current format of the nonce is ... H(timestamp ":" method ":" random ":" uri ":" realm) + Hex(timestamp)

Parameters:
nonce_timeThe amount of time in seconds for a nonce to be invalid
methodHTTP method
rndA pointer to a character array for the random seed
rnd_sizeThe size of the random seed array
uriHTTP URI (in MHD, without the arguments ("?k=v")
realmA string of characters that describes the realm of auth.
nonceA pointer to a character array for the nonce to put in

Definition at line 389 of file digestauth.c.

References cvthex(), MD5_DIGEST_SIZE, MD5Final(), MD5Init(), and MD5Update().

Referenced by MHD_digest_auth_check(), and MHD_queue_auth_fail_response().

Here is the call graph for this function:

Here is the caller graph for this function:

static int check_argument_match ( struct MHD_Connection connection,
const char *  args 
)
static

Check that the arguments given by the client as part of the authentication header match the arguments we got as part of the HTTP request URI.

Parameters:
connectionconnections with headers to compare against
argsargument URI string (after "?" in URI)
Returns:
MHD_YES if the arguments match, MHD_NO if not

Definition at line 471 of file digestauth.c.

References MHD_Connection::daemon, MHD_Connection::headers_received, MHD_HTTP_Header::kind, MHD_GET_ARGUMENT_KIND, MHD_NO, MHD_YES, MHD_HTTP_Header::next, NULL, test_header(), MHD_Daemon::unescape_callback, and MHD_Daemon::unescape_callback_cls.

Referenced by MHD_digest_auth_check().

Here is the call graph for this function:

Here is the caller graph for this function:

static int check_nonce_nc ( struct MHD_Connection connection,
const char *  nonce,
unsigned long int  nc 
)
static

Check nonce-nc map array with either new nonce counter or a whole new nonce.

Parameters:
connectionThe MHD connection structure
nonceA pointer that referenced a zero-terminated array of nonce
ncThe nonce counter, zero to add the nonce to the array
Returns:
MHD_YES if successful, MHD_NO if invalid (or we have no NC array)

Definition at line 294 of file digestauth.c.

References MHD_Connection::daemon, MHD_NO, and MHD_YES.

Referenced by MHD_digest_auth_check(), and MHD_queue_auth_fail_response().

Here is the caller graph for this function:

static void cvthex ( const unsigned char *  bin,
size_t  len,
char *  hex 
)
static

convert bin to hex

Parameters:
binbinary data
lennumber of bytes in bin
hexpointer to len*2+1 bytes

Definition at line 61 of file digestauth.c.

Referenced by calculate_nonce(), digest_calc_ha1(), and digest_calc_response().

Here is the caller graph for this function:

static void digest_calc_ha1 ( const char *  alg,
const char *  username,
const char *  realm,
const char *  password,
const char *  nonce,
const char *  cnonce,
char *  sessionkey 
)
static

calculate H(A1) as per RFC2617 spec and store the result in 'sessionkey'.

Parameters:
algThe hash algorithm used, can be "md5" or "md5-sess"
usernameA `char *' pointer to the username value
realmA `char *' pointer to the realm value
passwordA `char *' pointer to the password value
nonceA `char *' pointer to the nonce value
cnonceA `char *' pointer to the cnonce value
sessionkeypointer to buffer of HASH_MD5_HEX_LEN+1 bytes

Definition at line 92 of file digestauth.c.

References cvthex(), MD5_DIGEST_SIZE, MD5Final(), MD5Init(), and MD5Update().

Referenced by MHD_digest_auth_check().

Here is the call graph for this function:

Here is the caller graph for this function:

static void digest_calc_response ( const char *  ha1,
const char *  nonce,
const char *  noncecount,
const char *  cnonce,
const char *  qop,
const char *  method,
const char *  uri,
const char *  hentity,
char *  response 
)
static

Calculate request-digest/response-digest as per RFC2617 spec

Parameters:
ha1H(A1)
noncenonce from server
noncecount8 hex digits
cnonceclient nonce
qopqop-value: "", "auth" or "auth-int"
methodmethod from request
urirequested URL
hentityH(entity body) if qop="auth-int"
responserequest-digest or response-digest

Definition at line 138 of file digestauth.c.

References cvthex(), HASH_MD5_HEX_LEN, MD5_DIGEST_SIZE, MD5Final(), MD5Init(), MD5Update(), and NULL.

Referenced by MHD_digest_auth_check().

Here is the call graph for this function:

Here is the caller graph for this function:

static int lookup_sub_value ( char *  dest,
size_t  size,
const char *  data,
const char *  key 
)
static

Lookup subvalue off of the HTTP Authorization header.

A description of the input format for 'data' is at http://en.wikipedia.org/wiki/Digest_access_authentication

Parameters:
destwhere to store the result (possibly truncated if the buffer is not big enough).
sizesize of dest
datapointer to the Authorization header
keykey to look up in data
Returns:
size of the located value, 0 if otherwise

Definition at line 205 of file digestauth.c.

References NULL.

Referenced by MHD_digest_auth_check(), and MHD_digest_auth_get_username().

Here is the caller graph for this function:

int MHD_digest_auth_check ( struct MHD_Connection connection,
const char *  realm,
const char *  username,
const char *  password,
unsigned int  nonce_timeout 
)

Authenticates the authorization header sent by the client

Parameters:
connectionThe MHD connection structure
realmThe realm presented to the client
usernameThe username needs to be authenticated
passwordThe password used in the authentication
nonce_timeoutThe amount of time for a nonce to be invalid in seconds
Returns:
MHD_YES if authenticated, MHD_NO if not, MHD_INVALID_NONCE if nonce is invalid

Definition at line 546 of file digestauth.c.

References _BASE, calculate_nonce(), check_argument_match(), check_nonce_nc(), MHD_Connection::daemon, digest_calc_ha1(), digest_calc_response(), HASH_MD5_HEX_LEN, MHD_HTTP_Header::header, lookup_sub_value(), MAX_AUTH_RESPONSE_LENGTH, MAX_NONCE_LENGTH, MAX_REALM_LENGTH, MAX_USERNAME_LENGTH, MHD_Connection::method, MHD_HEADER_KIND, MHD_HTTP_HEADER_AUTHORIZATION, MHD_INVALID_NONCE, MHD_lookup_connection_value(), MHD_monotonic_time(), MHD_NO, MHD_YES, NULL, and MHD_Connection::url.

Here is the call graph for this function:

char* MHD_digest_auth_get_username ( struct MHD_Connection connection)

Get the username from the authorization header sent by the client

Parameters:
connectionThe MHD connection structure
Returns:
NULL if no username could be found, a pointer to the username if found

Definition at line 353 of file digestauth.c.

References _BASE, lookup_sub_value(), MAX_USERNAME_LENGTH, MHD_HEADER_KIND, MHD_HTTP_HEADER_AUTHORIZATION, MHD_lookup_connection_value(), and NULL.

Here is the call graph for this function:

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

Parameters:
connectionThe MHD connection structure
realmthe realm presented to the client
opaquestring to user for opaque value
signal_staleMHD_YES if the nonce is invalid to add 'stale=true' to the authentication header
Returns:
MHD_YES on success, MHD_NO otherwise

Definition at line 744 of file digestauth.c.

References calculate_nonce(), check_nonce_nc(), MHD_Connection::daemon, HASH_MD5_HEX_LEN, MHD_HTTP_Header::header, MHD_Connection::method, MHD_add_response_header(), MHD_HTTP_HEADER_WWW_AUTHENTICATE, MHD_HTTP_UNAUTHORIZED, MHD_monotonic_time(), MHD_NO, MHD_queue_response(), MHD_YES, NULL, and MHD_Connection::url.

Here is the call graph for this function:

static int test_header ( struct MHD_Connection connection,
const char *  key,
const char *  value 
)
static

Test if the given key-value pair is in the headers for the given connection.

Parameters:
connectionthe connection
keythe key
valuethe value, can be NULL
Returns:
MHD_YES if the key-value pair is in the headers, MHD_NO if not

Definition at line 435 of file digestauth.c.

References MHD_HTTP_Header::header, MHD_Connection::headers_received, MHD_HTTP_Header::kind, MHD_GET_ARGUMENT_KIND, MHD_NO, MHD_YES, MHD_HTTP_Header::next, NULL, and MHD_HTTP_Header::value.

Referenced by check_argument_match().

Here is the caller graph for this function: