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:417

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:352
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:207
struct http_request request
Request.
Definition: http.h:436
struct http_response response
Response.
Definition: http.h:438
struct http_request_auth auth
Authentication descriptor.
Definition: http.h:224
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
struct http_authentication * auth
Authentication scheme (if any)
Definition: http.h:191
char * http_token(char **line, char **value)
Get HTTP response token.
Definition: httpcore.c:190
Transaction may be retried on failure.
Definition: http.h:362
union @376 key
Sense key.
Definition: scsi.h:18

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 */
131 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition: crypto.h:172
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:286

References ctx, digest_init(), 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 }
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition: crypto.h:177
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
size_t strlen(const char *src)
Get length of string.
Definition: string.c:228
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:286

References ctx, digest_update(), 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 */
161  base16_encode ( digest, sizeof ( digest ), out, len );
162 }
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition: crypto.h:182
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct md4_digest digest
Digest of data already processed.
Definition: md4.h:12
__be32 out[4]
Definition: CIB_PRM.h:36
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:69
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:286

References ctx, digest, digest_final(), 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:167
#define EINVAL
Invalid argument.
Definition: errno.h:428
const char * username
Username.
Definition: http.h:165
struct http_response_auth_digest digest
Digest authorization descriptor.
Definition: http.h:305
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:434
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
Definition: string.c:207
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
struct http_response_auth auth
Authorization descriptor.
Definition: http.h:348
struct http_request request
Request.
Definition: http.h:436
static size_t base16_encoded_len(size_t raw_len)
Calculate length of base16-encoded data.
Definition: base16.h:21
struct http_response response
Response.
Definition: http.h:438
const char * uri
Request URI string.
Definition: http.h:216
const char * algorithm
Algorithm.
Definition: http.h:169
struct http_request_auth auth
Authentication descriptor.
Definition: http.h:224
HTTP request Digest authentication descriptor.
Definition: http.h:163
const char * name
Method name (e.g.
Definition: http.h:103
uint64_t rsp
Definition: librm.h:267
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:30
An MD5 context.
Definition: md5.h:58
struct http_method * method
Method.
Definition: http.h:214
HTTP response Digest authorization descriptor.
Definition: http.h:275
const char * password
Password.
Definition: uri.h:60
char cnonce[HTTP_DIGEST_CNONCE_LEN+1]
Client nonce.
Definition: http.h:171
#define MD5_DIGEST_SIZE
MD5 digest size.
Definition: md5.h:69
const char * user
User name.
Definition: uri.h:58
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:173
#define HTTP_DIGEST_NC
HTTP Digest authentication client nonce count.
Definition: http.h:121
struct http_request_auth_digest digest
Digest authentication descriptor.
Definition: http.h:197

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:167
const char * username
Username.
Definition: http.h:165
struct http_response_auth_digest digest
Digest authorization descriptor.
Definition: http.h:305
struct http_response_auth auth
Authorization descriptor.
Definition: http.h:348
struct http_request request
Request.
Definition: http.h:436
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:438
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
const char * uri
Request URI string.
Definition: http.h:216
const char * algorithm
Algorithm.
Definition: http.h:169
struct http_request_auth auth
Authentication descriptor.
Definition: http.h:224
HTTP request Digest authentication descriptor.
Definition: http.h:163
uint64_t rsp
Definition: librm.h:267
uint32_t len
Length.
Definition: ena.h:14
HTTP response Digest authorization descriptor.
Definition: http.h:275
char cnonce[HTTP_DIGEST_CNONCE_LEN+1]
Client nonce.
Definition: http.h:171
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
char response[HTTP_DIGEST_RESPONSE_LEN+1]
Response.
Definition: http.h:173
#define HTTP_DIGEST_NC
HTTP Digest authentication client nonce count.
Definition: http.h:121
struct http_request_auth_digest digest
Digest authentication descriptor.
Definition: http.h:197

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:277
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:285
#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:279

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.