GNU libmicrohttpd  0.9.59
digestauth.c File Reference

Implements HTTP digest authentication. More...

#include "platform.h"
#include "mhd_limits.h"
#include "internal.h"
#include "md5.h"
#include "mhd_mono_clock.h"
#include "mhd_str.h"
#include "mhd_compat.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 TIMESTAMP_BIN_SIZE   4
 
#define TIMESTAMP_HEX_LEN   (2 * TIMESTAMP_BIN_SIZE)
 
#define NONCE_STD_LEN   (HASH_MD5_HEX_LEN + TIMESTAMP_HEX_LEN)
 
#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[HASH_MD5_HEX_LEN+1])
 
static void digest_calc_response (const char ha1[HASH_MD5_HEX_LEN+1], const char *nonce, const char *noncecount, const char *cnonce, const char *qop, const char *method, const char *uri, const char *hentity, char response[HASH_MD5_HEX_LEN+1])
 
static size_t 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, uint64_t nc)
 
_MHD_EXTERN char * MHD_digest_auth_get_username (struct MHD_Connection *connection)
 
static void calculate_nonce (uint32_t nonce_time, const char *method, const char *rnd, size_t rnd_size, const char *uri, const char *realm, char nonce[NONCE_STD_LEN+1])
 
static int test_header (struct MHD_Connection *connection, const char *key, const char *value, enum MHD_ValueKind kind)
 
static int check_argument_match (struct MHD_Connection *connection, const char *args)
 
_MHD_EXTERN int MHD_digest_auth_check (struct MHD_Connection *connection, const char *realm, const char *username, const char *password, unsigned int nonce_timeout)
 
_MHD_EXTERN 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

◆ _BASE

#define _BASE   "Digest "

Beginning string for any valid Digest authentication header.

Definition at line 51 of file digestauth.c.

Referenced by MHD_digest_auth_check(), and MHD_digest_auth_get_username().

◆ HASH_MD5_HEX_LEN

#define HASH_MD5_HEX_LEN   (2 * MD5_DIGEST_SIZE)

Definition at line 40 of file digestauth.c.

Referenced by digest_calc_response(), and MHD_digest_auth_check().

◆ MAX_AUTH_RESPONSE_LENGTH

#define MAX_AUTH_RESPONSE_LENGTH   128

Maximum length of the response in digest authentication.

Definition at line 66 of file digestauth.c.

Referenced by MHD_digest_auth_check().

◆ MAX_REALM_LENGTH

#define MAX_REALM_LENGTH   256

Maximum length of a realm for digest authentication.

Definition at line 61 of file digestauth.c.

Referenced by MHD_digest_auth_check().

◆ MAX_USERNAME_LENGTH

#define MAX_USERNAME_LENGTH   128

Maximum length of a username for digest authentication.

Definition at line 56 of file digestauth.c.

Referenced by MHD_digest_auth_check(), and MHD_digest_auth_get_username().

◆ NONCE_STD_LEN

#define NONCE_STD_LEN   (HASH_MD5_HEX_LEN + TIMESTAMP_HEX_LEN)

Definition at line 46 of file digestauth.c.

Referenced by MHD_digest_auth_check(), and MHD_queue_auth_fail_response().

◆ TIMESTAMP_BIN_SIZE

#define TIMESTAMP_BIN_SIZE   4

Definition at line 42 of file digestauth.c.

Referenced by calculate_nonce().

◆ TIMESTAMP_HEX_LEN

#define TIMESTAMP_HEX_LEN   (2 * TIMESTAMP_BIN_SIZE)

Definition at line 43 of file digestauth.c.

Referenced by calculate_nonce(), and MHD_digest_auth_check().

Function Documentation

◆ calculate_nonce()

static void calculate_nonce ( uint32_t  nonce_time,
const char *  method,
const char *  rnd,
size_t  rnd_size,
const char *  uri,
const char *  realm,
char  nonce[NONCE_STD_LEN+1] 
)
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 rnd
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 508 of file digestauth.c.

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

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:

◆ check_argument_match()

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 619 of file digestauth.c.

References _, MHD_Connection::daemon, MHD_Connection::headers_received, MHD_HTTP_Header::kind, MHD_GET_ARGUMENT_KIND, MHD_NO, MHD_parse_arguments_(), MHD_YES, MHD_HTTP_Header::next, NULL, and test_header().

Referenced by MHD_digest_auth_check().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_nonce_nc()

static int check_nonce_nc ( struct MHD_Connection connection,
const char *  nonce,
uint64_t  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 379 of file digestauth.c.

References _, MHD_Connection::daemon, MAX_NONCE_LENGTH, MHD_mutex_lock_chk_, MHD_mutex_unlock_chk_, MHD_NO, MHD_YES, MHD_NonceNc::nc, MHD_NonceNc::nmask, and MHD_NonceNc::nonce.

Referenced by MHD_digest_auth_check(), and MHD_queue_auth_fail_response().

Here is the caller graph for this function:

◆ cvthex()

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 77 of file digestauth.c.

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

Here is the caller graph for this function:

◆ digest_calc_ha1()

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[HASH_MD5_HEX_LEN+1] 
)
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 108 of file digestauth.c.

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

Referenced by MHD_digest_auth_check().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ digest_calc_response()

static void digest_calc_response ( const char  ha1[HASH_MD5_HEX_LEN+1],
const char *  nonce,
const char *  noncecount,
const char *  cnonce,
const char *  qop,
const char *  method,
const char *  uri,
const char *  hentity,
char  response[HASH_MD5_HEX_LEN+1] 
)
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 179 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:

◆ lookup_sub_value()

static size_t 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 286 of file digestauth.c.

References data, MHD_str_equal_caseless_n_(), and NULL.

Referenced by MHD_digest_auth_check(), and MHD_digest_auth_get_username().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ test_header()

static int test_header ( struct MHD_Connection connection,
const char *  key,
const char *  value,
enum MHD_ValueKind  kind 
)
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
kindtype of the header
Returns
MHD_YES if the key-value pair is in the headers, MHD_NO if not

Definition at line 580 of file digestauth.c.

References MHD_HTTP_Header::header, MHD_Connection::headers_received, MHD_HTTP_Header::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: