iPXE
Data Structures | Macros | Functions | Variables
httpdigest.c File Reference

Hyper Text Transfer Protocol (HTTP) Digest authentication. More...

#include <stdio.h>
#include <errno.h>
#include <strings.h>
#include <ipxe/uri.h>
#include <ipxe/md5.h>
#include <ipxe/base16.h>
#include <ipxe/vsprintf.h>
#include <ipxe/http.h>

Go to the source code of this file.

Data Structures

struct  http_digest_field
 An HTTP Digest "WWW-Authenticate" response field. More...
 

Macros

#define EACCES_USERNAME   __einfo_error ( EINFO_EACCES_USERNAME )
 
#define EINFO_EACCES_USERNAME
 
#define HTTP_DIGEST_FIELD(_name)
 Define an HTTP Digest "WWW-Authenticate" response field. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static void http_digest_field (struct http_transaction *http, struct http_digest_field *field, char *value)
 Set HTTP Digest "WWW-Authenticate" response field value. More...
 
static int http_parse_digest_auth (struct http_transaction *http, char *line)
 Parse HTTP "WWW-Authenticate" header for Digest authentication. More...
 
static void http_digest_init (struct md5_context *ctx)
 Initialise HTTP Digest. More...
 
static void http_digest_update (struct md5_context *ctx, const char *string)
 Update HTTP Digest with new data. More...
 
static void http_digest_final (struct md5_context *ctx, char *out, size_t len)
 Finalise HTTP Digest. More...
 
static int http_digest_authenticate (struct http_transaction *http)
 Perform HTTP Digest authentication. More...
 
static int http_format_digest_auth (struct http_transaction *http, char *buf, size_t len)
 Construct HTTP "Authorization" header for Digest authentication. More...
 
 REQUIRING_SYMBOL (http_digest_auth)
 
 REQUIRE_OBJECT (httpauth)
 

Variables

static struct http_digest_field http_digest_fields []
 HTTP Digest "WWW-Authenticate" fields. More...
 
struct http_authentication http_digest_auth __http_authentication
 HTTP Digest authentication scheme. More...
 

Detailed Description

Hyper Text Transfer Protocol (HTTP) Digest authentication.

Definition in file httpdigest.c.

Macro Definition Documentation

◆ EACCES_USERNAME

#define EACCES_USERNAME   __einfo_error ( EINFO_EACCES_USERNAME )

Definition at line 43 of file httpdigest.c.

◆ EINFO_EACCES_USERNAME

#define EINFO_EACCES_USERNAME
Value:
"No username available for Digest authentication" )
#define EINFO_EACCES
Definition: errno.h:299
#define __einfo_uniqify(einfo_base, uniq, desc)
Declare disambiguated error.
Definition: errno.h:180

Definition at line 44 of file httpdigest.c.

◆ HTTP_DIGEST_FIELD

#define HTTP_DIGEST_FIELD (   _name)
Value:
{ \
.name = #_name, \
.offset = offsetof ( struct http_transaction, \
response.auth.digest._name ), \
}
#define offsetof(type, field)
Get offset of a field within a structure.
Definition: stddef.h:24
An HTTP transaction.
Definition: http.h:415

Define an HTTP Digest "WWW-Authenticate" response field.

Definition at line 57 of file httpdigest.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ http_digest_field()

static void http_digest_field ( struct http_transaction http,
struct http_digest_field field,
char *  value 
)
inlinestatic

Set HTTP Digest "WWW-Authenticate" response field value.

Parameters
httpHTTP transaction
fieldResponse field
valueField value

Definition at line 71 of file httpdigest.c.

72  {
73  char **ptr;
74 
75  ptr = ( ( ( void * ) http ) + field->offset );
76  *ptr = value;
77 }
size_t offset
Offset.
Definition: httpdigest.c:53
pseudo_bit_t value[0x00020]
Definition: arbel.h:13

References http_digest_field::offset, and value.

◆ http_parse_digest_auth()

static int http_parse_digest_auth ( struct http_transaction http,
char *  line 
)
static

Parse HTTP "WWW-Authenticate" header for Digest authentication.

Parameters
httpHTTP transaction
lineRemaining header line
Return values
rcReturn status code

Definition at line 95 of file httpdigest.c.

96  {
97  struct http_digest_field *field;
98  char *key;
99  char *value;
100  unsigned int i;
101 
102  /* Process fields */
103  while ( ( key = http_token ( &line, &value ) ) ) {
104  for ( i = 0 ; i < ( sizeof ( http_digest_fields ) /
105  sizeof ( http_digest_fields[0] ) ) ; i++){
106  field = &http_digest_fields[i];
107  if ( strcasecmp ( key, field->name ) == 0 )
108  http_digest_field ( http, field, value );
109  }
110  }
111 
112  /* Allow HTTP request to be retried if the request had not
113  * already tried authentication.
114  */
115  if ( ! http->request.auth.auth )
117 
118  return 0;
119 }
const char * name
Name.
Definition: httpdigest.c:51
An HTTP Digest "WWW-Authenticate" response field.
Definition: httpdigest.c:49
unsigned int flags
Flags.
Definition: http.h:350
static struct http_digest_field http_digest_fields[]
HTTP Digest "WWW-Authenticate" fields.
Definition: httpdigest.c:80
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
Definition: string.c:208
struct http_request request
Request.
Definition: http.h:434
struct http_response response
Response.
Definition: http.h:436
struct http_request_auth auth
Authentication descriptor.
Definition: http.h:222
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
struct http_authentication * auth
Authentication scheme (if any)
Definition: http.h:189
char * http_token(char **line, char **value)
Get HTTP response token.
Definition: httpcore.c:192
Transaction may be retried on failure.
Definition: http.h:360
union @382 key
Sense key.
Definition: crypto.h:284

References http_request_auth::auth, http_request::auth, http_response::flags, http_digest_fields, HTTP_RESPONSE_RETRY, http_token(), key, http_digest_field::name, http_transaction::request, http_transaction::response, strcasecmp(), and value.

◆ http_digest_init()

static void http_digest_init ( struct md5_context ctx)
static

Initialise HTTP Digest.

Parameters
ctxDigest context
stringInitial string

Definition at line 127 of file httpdigest.c.

127  {
128 
129  /* Initialise MD5 digest */
130  digest_init ( &md5_algorithm, ctx );
131 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:286

References ctx, and md5_algorithm.

Referenced by http_digest_authenticate().

◆ http_digest_update()

static void http_digest_update ( struct md5_context ctx,
const char *  string 
)
static

Update HTTP Digest with new data.

Parameters
ctxDigest context
stringString to append

Definition at line 139 of file httpdigest.c.

139  {
140  static const char colon = ':';
141 
142  /* Add (possibly colon-separated) field to MD5 digest */
143  if ( ctx->len )
144  digest_update ( &md5_algorithm, ctx, &colon, sizeof ( colon ) );
145  digest_update ( &md5_algorithm, ctx, string, strlen ( string ) );
146 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:286

References ctx, md5_algorithm, and strlen().

Referenced by http_digest_authenticate().

◆ http_digest_final()

static void http_digest_final ( struct md5_context ctx,
char *  out,
size_t  len 
)
static

Finalise HTTP Digest.

Parameters
ctxDigest context
outBuffer for digest output
lenBuffer length

Definition at line 155 of file httpdigest.c.

156  {
158 
159  /* Finalise and base16-encode MD5 digest */
160  digest_final ( &md5_algorithm, ctx, digest );
161  base16_encode ( digest, sizeof ( digest ), out, len );
162 }
__be32 out[4]
Definition: CIB_PRM.h:36
static void struct digest_algorithm * digest
HMAC-MD5 digest.
Definition: crypto.h:308
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
unsigned char uint8_t
Definition: stdint.h:10
uint32_t len
Length.
Definition: ena.h:14
#define MD5_DIGEST_SIZE
MD5 digest size.
Definition: md5.h:72
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:286

References ctx, digest, len, md5_algorithm, MD5_DIGEST_SIZE, and out.

Referenced by http_digest_authenticate().

◆ http_digest_authenticate()

static int http_digest_authenticate ( struct http_transaction http)
static

Perform HTTP Digest authentication.

Parameters
httpHTTP transaction
Return values
rcReturn status code

Definition at line 170 of file httpdigest.c.

170  {
171  struct http_request_auth_digest *req = &http->request.auth.digest;
173  char ha1[ base16_encoded_len ( MD5_DIGEST_SIZE ) + 1 /* NUL */ ];
174  char ha2[ base16_encoded_len ( MD5_DIGEST_SIZE ) + 1 /* NUL */ ];
175  static const char md5sess[] = "MD5-sess";
176  static const char md5[] = "MD5";
177  struct md5_context ctx;
178  const char *password;
179 
180  /* Check for required response parameters */
181  if ( ! rsp->realm ) {
182  DBGC ( http, "HTTP %p has no realm for Digest authentication\n",
183  http );
184  return -EINVAL;
185  }
186  if ( ! rsp->nonce ) {
187  DBGC ( http, "HTTP %p has no nonce for Digest authentication\n",
188  http );
189  return -EINVAL;
190  }
191 
192  /* Record username and password */
193  if ( ! http->uri->user ) {
194  DBGC ( http, "HTTP %p has no username for Digest "
195  "authentication\n", http );
196  return -EACCES_USERNAME;
197  }
198  req->username = http->uri->user;
199  password = ( http->uri->password ? http->uri->password : "" );
200 
201  /* Handle quality of protection */
202  if ( rsp->qop ) {
203 
204  /* Use "auth" in subsequent request */
205  req->qop = "auth";
206 
207  /* Generate a client nonce */
208  snprintf ( req->cnonce, sizeof ( req->cnonce ),
209  "%08lx", random() );
210 
211  /* Determine algorithm */
212  req->algorithm = md5;
213  if ( rsp->algorithm &&
214  ( strcasecmp ( rsp->algorithm, md5sess ) == 0 ) ) {
215  req->algorithm = md5sess;
216  }
217  }
218 
219  /* Generate HA1 */
220  http_digest_init ( &ctx );
221  http_digest_update ( &ctx, req->username );
222  http_digest_update ( &ctx, rsp->realm );
223  http_digest_update ( &ctx, password );
224  http_digest_final ( &ctx, ha1, sizeof ( ha1 ) );
225  if ( req->algorithm == md5sess ) {
226  http_digest_init ( &ctx );
227  http_digest_update ( &ctx, ha1 );
228  http_digest_update ( &ctx, rsp->nonce );
229  http_digest_update ( &ctx, req->cnonce );
230  http_digest_final ( &ctx, ha1, sizeof ( ha1 ) );
231  }
232 
233  /* Generate HA2 */
234  http_digest_init ( &ctx );
236  http_digest_update ( &ctx, http->request.uri );
237  http_digest_final ( &ctx, ha2, sizeof ( ha2 ) );
238 
239  /* Generate response */
240  http_digest_init ( &ctx );
241  http_digest_update ( &ctx, ha1 );
242  http_digest_update ( &ctx, rsp->nonce );
243  if ( req->qop ) {
245  http_digest_update ( &ctx, req->cnonce );
246  http_digest_update ( &ctx, req->qop );
247  }
248  http_digest_update ( &ctx, ha2 );
249  http_digest_final ( &ctx, req->response, sizeof ( req->response ) );
250 
251  return 0;
252 }
const char * qop
Quality of protection.
Definition: http.h:165
#define EINVAL
Invalid argument.
Definition: errno.h:428
const char * username
Username.
Definition: http.h:163
struct http_response_auth_digest digest
Digest authorization descriptor.
Definition: http.h:303
static void http_digest_final(struct md5_context *ctx, char *out, size_t len)
Finalise HTTP Digest.
Definition: httpdigest.c:155
#define DBGC(...)
Definition: compiler.h:505
struct uri * uri
Request URI.
Definition: http.h:432
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
Definition: string.c:208
struct http_response_auth auth
Authorization descriptor.
Definition: http.h:346
struct http_request request
Request.
Definition: http.h:434
static size_t base16_encoded_len(size_t raw_len)
Calculate length of base16-encoded data.
Definition: base16.h:24
struct http_response response
Response.
Definition: http.h:436
const char * uri
Request URI string.
Definition: http.h:214
const char * algorithm
Algorithm.
Definition: http.h:167
struct http_request_auth auth
Authentication descriptor.
Definition: http.h:222
HTTP request Digest authentication descriptor.
Definition: http.h:161
const char * name
Method name (e.g.
Definition: http.h:101
uint64_t rsp
Definition: librm.h:267
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:31
An MD5 context.
Definition: md5.h:58
struct http_method * method
Method.
Definition: http.h:212
HTTP response Digest authorization descriptor.
Definition: http.h:273
const char * password
Password.
Definition: uri.h:74
char cnonce[HTTP_DIGEST_CNONCE_LEN+1]
Client nonce.
Definition: http.h:169
#define MD5_DIGEST_SIZE
MD5 digest size.
Definition: md5.h:72
const char * user
User name.
Definition: uri.h:72
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
static void http_digest_update(struct md5_context *ctx, const char *string)
Update HTTP Digest with new data.
Definition: httpdigest.c:139
static void http_digest_init(struct md5_context *ctx)
Initialise HTTP Digest.
Definition: httpdigest.c:127
#define EACCES_USERNAME
Definition: httpdigest.c:43
char response[HTTP_DIGEST_RESPONSE_LEN+1]
Response.
Definition: http.h:171
#define HTTP_DIGEST_NC
HTTP Digest authentication client nonce count.
Definition: http.h:119
struct http_request_auth_digest digest
Digest authentication descriptor.
Definition: http.h:195

References http_request_auth_digest::algorithm, http_request::auth, http_response::auth, base16_encoded_len(), http_request_auth_digest::cnonce, ctx, DBGC, http_request_auth::digest, http_response_auth::digest, EACCES_USERNAME, EINVAL, http_digest_final(), http_digest_init(), HTTP_DIGEST_NC, http_digest_update(), MD5_DIGEST_SIZE, http_request::method, http_method::name, uri::password, http_request_auth_digest::qop, random(), http_transaction::request, http_request_auth_digest::response, http_transaction::response, rsp, snprintf(), strcasecmp(), http_request::uri, http_transaction::uri, uri::user, and http_request_auth_digest::username.

◆ http_format_digest_auth()

static int http_format_digest_auth ( struct http_transaction http,
char *  buf,
size_t  len 
)
static

Construct HTTP "Authorization" header for Digest authentication.

Parameters
httpHTTP transaction
bufBuffer
lenLength of buffer
Return values
lenLength of header value, or negative error

Definition at line 262 of file httpdigest.c.

263  {
264  struct http_request_auth_digest *req = &http->request.auth.digest;
266  size_t used = 0;
267 
268  /* Sanity checks */
269  assert ( rsp->realm != NULL );
270  assert ( rsp->nonce != NULL );
271  assert ( req->username != NULL );
272  if ( req->qop ) {
273  assert ( req->algorithm != NULL );
274  assert ( req->cnonce[0] != '\0' );
275  }
276  assert ( req->response[0] != '\0' );
277 
278  /* Construct response */
279  used += ssnprintf ( ( buf + used ), ( len - used ),
280  "realm=\"%s\", nonce=\"%s\", uri=\"%s\", "
281  "username=\"%s\"", rsp->realm, rsp->nonce,
282  http->request.uri, req->username );
283  if ( rsp->opaque ) {
284  used += ssnprintf ( ( buf + used ), ( len - used ),
285  ", opaque=\"%s\"", rsp->opaque );
286  }
287  if ( req->qop ) {
288  used += ssnprintf ( ( buf + used ), ( len - used ),
289  ", qop=%s, algorithm=%s, cnonce=\"%s\", "
290  "nc=" HTTP_DIGEST_NC, req->qop,
291  req->algorithm, req->cnonce );
292  }
293  used += ssnprintf ( ( buf + used ), ( len - used ),
294  ", response=\"%s\"", req->response );
295 
296  return used;
297 }
const char * qop
Quality of protection.
Definition: http.h:165
const char * username
Username.
Definition: http.h:163
struct http_response_auth_digest digest
Digest authorization descriptor.
Definition: http.h:303
struct http_response_auth auth
Authorization descriptor.
Definition: http.h:346
struct http_request request
Request.
Definition: http.h:434
int ssnprintf(char *buf, ssize_t ssize, const char *fmt,...)
Version of vsnprintf() that accepts a signed buffer size.
Definition: vsprintf.c:420
struct http_response response
Response.
Definition: http.h:436
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
const char * uri
Request URI string.
Definition: http.h:214
const char * algorithm
Algorithm.
Definition: http.h:167
struct http_request_auth auth
Authentication descriptor.
Definition: http.h:222
HTTP request Digest authentication descriptor.
Definition: http.h:161
uint64_t rsp
Definition: librm.h:267
uint32_t len
Length.
Definition: ena.h:14
HTTP response Digest authorization descriptor.
Definition: http.h:273
char cnonce[HTTP_DIGEST_CNONCE_LEN+1]
Client nonce.
Definition: http.h:169
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
char response[HTTP_DIGEST_RESPONSE_LEN+1]
Response.
Definition: http.h:171
#define HTTP_DIGEST_NC
HTTP Digest authentication client nonce count.
Definition: http.h:119
struct http_request_auth_digest digest
Digest authentication descriptor.
Definition: http.h:195

References http_request_auth_digest::algorithm, assert(), http_request::auth, http_response::auth, http_request_auth_digest::cnonce, http_request_auth::digest, http_response_auth::digest, HTTP_DIGEST_NC, len, NULL, http_request_auth_digest::qop, http_transaction::request, http_request_auth_digest::response, http_transaction::response, rsp, ssnprintf(), http_request::uri, and http_request_auth_digest::username.

◆ REQUIRING_SYMBOL()

REQUIRING_SYMBOL ( http_digest_auth  )

◆ REQUIRE_OBJECT()

REQUIRE_OBJECT ( httpauth  )

Variable Documentation

◆ http_digest_fields

struct http_digest_field http_digest_fields[]
static
Initial value:
= {
}
const char * realm
Realm.
Definition: http.h:275
u16 algorithm
Authentication algorithm (Open System or Shared Key)
Definition: ieee80211.h:1030
struct ntlm_nonce nonce
Server nonce.
Definition: ntlm.h:18
const char * opaque
Opaque.
Definition: http.h:283
#define HTTP_DIGEST_FIELD(_name)
Define an HTTP Digest "WWW-Authenticate" response field.
Definition: httpdigest.c:57
const char * qop
Quality of protection.
Definition: http.h:277

HTTP Digest "WWW-Authenticate" fields.

Definition at line 80 of file httpdigest.c.

Referenced by http_parse_digest_auth().

◆ __http_authentication

struct http_authentication http_digest_auth __http_authentication
Initial value:
= {
.name = "Digest",
.authenticate = http_digest_authenticate,
}
static int http_digest_authenticate(struct http_transaction *http)
Perform HTTP Digest authentication.
Definition: httpdigest.c:170
static int http_format_digest_auth(struct http_transaction *http, char *buf, size_t len)
Construct HTTP "Authorization" header for Digest authentication.
Definition: httpdigest.c:262
static int http_parse_digest_auth(struct http_transaction *http, char *line)
Parse HTTP "WWW-Authenticate" header for Digest authentication.
Definition: httpdigest.c:95

HTTP Digest authentication scheme.

Definition at line 300 of file httpdigest.c.