iPXE
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_context
 An HTTP Digest algorithm context. More...
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.

Functions

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

Variables

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

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 44 of file httpdigest.c.

◆ EINFO_EACCES_USERNAME

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

Definition at line 45 of file httpdigest.c.

45#define EINFO_EACCES_USERNAME \
46 __einfo_uniqify ( EINFO_EACCES, 0x01, \
47 "No username available for Digest authentication" )

◆ 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:25
An HTTP transaction.
Definition http.h:423

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

Definition at line 66 of file httpdigest.c.

66#define HTTP_DIGEST_FIELD( _name ) { \
67 .name = #_name, \
68 .offset = offsetof ( struct http_transaction, \
69 response.auth.digest._name ), \
70 }

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ http_digest_field()

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 80 of file httpdigest.c.

81 {
82 char **ptr;
83
84 ptr = ( ( ( void * ) http ) + field->offset );
85 *ptr = value;
86}
pseudo_bit_t value[0x00020]
Definition arbel.h:2
size_t offset
Offset.
Definition httpdigest.c:62

References http_digest_field::offset, and value.

Referenced by http_parse_digest_auth().

◆ http_parse_digest_auth()

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 104 of file httpdigest.c.

105 {
106 struct http_digest_field *field;
107 char *key;
108 char *value;
109 unsigned int i;
110
111 /* Process fields */
112 while ( ( key = http_token ( &line, &value ) ) ) {
113 for ( i = 0 ; i < ( sizeof ( http_digest_fields ) /
114 sizeof ( http_digest_fields[0] ) ) ; i++){
115 field = &http_digest_fields[i];
116 if ( strcasecmp ( key, field->name ) == 0 )
117 http_digest_field ( http, field, value );
118 }
119 }
120
121 /* Allow HTTP request to be retried if the request had not
122 * already tried authentication.
123 */
124 if ( ! http->request.auth.auth )
126
127 return 0;
128}
union @162305117151260234136356364136041353210355154177 key
@ HTTP_RESPONSE_RETRY
Transaction may be retried on failure.
Definition http.h:368
char * http_token(char **line, char **value)
Get HTTP response token.
Definition httpcore.c:219
static struct http_digest_field http_digest_fields[]
HTTP Digest "WWW-Authenticate" fields.
Definition httpdigest.c:89
static void http_digest_field(struct http_transaction *http, struct http_digest_field *field, char *value)
Set HTTP Digest "WWW-Authenticate" response field value.
Definition httpdigest.c:80
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
Definition string.c:209
An HTTP Digest "WWW-Authenticate" response field.
Definition httpdigest.c:58
const char * name
Name.
Definition httpdigest.c:60
struct http_authentication * auth
Authentication scheme (if any).
Definition http.h:197
struct http_request_auth auth
Authentication descriptor.
Definition http.h:230
unsigned int flags
Flags.
Definition http.h:358
struct http_response response
Response.
Definition http.h:446
struct http_request request
Request.
Definition http.h:444

References http_request::auth, http_request_auth::auth, http_response::flags, http_digest_field(), 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()

void http_digest_init ( struct http_digest_context * ctx)
static

Initialise HTTP Digest.

Parameters
ctxDigest context
stringInitial string

Definition at line 136 of file httpdigest.c.

136 {
137
138 /* Initialise MD5 digest */
139 digest_init ( &md5_algorithm, ctx->md5 );
140
141 /* Omit colon before first field */
142 ctx->colon_len = 0;
143}
struct golan_eq_context ctx
Definition CIB_PRM.h:0
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition crypto.h:294
struct digest_algorithm md5_algorithm

References ctx, digest_init(), and md5_algorithm.

Referenced by http_digest_authenticate().

◆ http_digest_update()

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

Update HTTP Digest with new data.

Parameters
ctxDigest context
stringString to append

Definition at line 151 of file httpdigest.c.

152 {
153 static const char colon = ':';
154
155 /* Add (possibly colon-separated) field to MD5 digest */
156 digest_update ( &md5_algorithm, ctx->md5, &colon, ctx->colon_len );
157 digest_update ( &md5_algorithm, ctx->md5, string, strlen ( string ) );
158
159 /* Include colon before any subsequent fields */
160 ctx->colon_len = sizeof ( colon );
161}
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition crypto.h:299
size_t strlen(const char *src)
Get length of string.
Definition string.c:244

References ctx, digest_update(), md5_algorithm, and strlen().

Referenced by http_digest_authenticate().

◆ http_digest_final()

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

Finalise HTTP Digest.

Parameters
ctxDigest context
outBuffer for digest output
lenBuffer length

Definition at line 170 of file httpdigest.c.

171 {
172 uint8_t digest[MD5_DIGEST_SIZE];
173
174 /* Finalise and base16-encode MD5 digest */
175 digest_final ( &md5_algorithm, ctx->md5, digest );
176 base16_encode ( digest, sizeof ( digest ), out, len );
177}
__be32 out[4]
Definition CIB_PRM.h:8
unsigned char uint8_t
Definition stdint.h:10
ring len
Length.
Definition dwmac.h:226
static void digest_final(struct digest_algorithm *digest, void *ctx, void *out)
Definition crypto.h:305
#define MD5_DIGEST_SIZE
MD5 digest size.
Definition md5.h:57

References ctx, digest_final(), len, md5_algorithm, MD5_DIGEST_SIZE, and out.

Referenced by http_digest_authenticate().

◆ http_digest_authenticate()

int http_digest_authenticate ( struct http_transaction * http)
static

Perform HTTP Digest authentication.

Parameters
httpHTTP transaction
Return values
rcReturn status code

Definition at line 185 of file httpdigest.c.

185 {
186 struct http_request_auth_digest *req = &http->request.auth.digest;
188 char ha1[ base16_encoded_len ( MD5_DIGEST_SIZE ) + 1 /* NUL */ ];
189 char ha2[ base16_encoded_len ( MD5_DIGEST_SIZE ) + 1 /* NUL */ ];
190 static const char md5sess[] = "MD5-sess";
191 static const char md5[] = "MD5";
193 const char *password;
194
195 /* Check for required response parameters */
196 if ( ! rsp->realm ) {
197 DBGC ( http, "HTTP %p has no realm for Digest authentication\n",
198 http );
199 return -EINVAL;
200 }
201 if ( ! rsp->nonce ) {
202 DBGC ( http, "HTTP %p has no nonce for Digest authentication\n",
203 http );
204 return -EINVAL;
205 }
206
207 /* Record username and password */
208 if ( ! http->uri->user ) {
209 DBGC ( http, "HTTP %p has no username for Digest "
210 "authentication\n", http );
211 return -EACCES_USERNAME;
212 }
213 req->username = http->uri->user;
214 password = ( http->uri->password ? http->uri->password : "" );
215
216 /* Handle quality of protection */
217 if ( rsp->qop ) {
218
219 /* Use "auth" in subsequent request */
220 req->qop = "auth";
221
222 /* Generate a client nonce */
223 snprintf ( req->cnonce, sizeof ( req->cnonce ),
224 "%08lx", random() );
225
226 /* Determine algorithm */
227 req->algorithm = md5;
228 if ( rsp->algorithm &&
229 ( strcasecmp ( rsp->algorithm, md5sess ) == 0 ) ) {
230 req->algorithm = md5sess;
231 }
232 }
233
234 /* Generate HA1 */
237 http_digest_update ( &ctx, rsp->realm );
239 http_digest_final ( &ctx, ha1, sizeof ( ha1 ) );
240 if ( req->algorithm == md5sess ) {
242 http_digest_update ( &ctx, ha1 );
243 http_digest_update ( &ctx, rsp->nonce );
244 http_digest_update ( &ctx, req->cnonce );
245 http_digest_final ( &ctx, ha1, sizeof ( ha1 ) );
246 }
247
248 /* Generate HA2 */
251 http_digest_update ( &ctx, http->request.uri );
252 http_digest_final ( &ctx, ha2, sizeof ( ha2 ) );
253
254 /* Generate response */
256 http_digest_update ( &ctx, ha1 );
257 http_digest_update ( &ctx, rsp->nonce );
258 if ( req->qop ) {
260 http_digest_update ( &ctx, req->cnonce );
261 http_digest_update ( &ctx, req->qop );
262 }
263 http_digest_update ( &ctx, ha2 );
264 http_digest_final ( &ctx, req->response, sizeof ( req->response ) );
265
266 return 0;
267}
static size_t base16_encoded_len(size_t raw_len)
Calculate length of base16-encoded data.
Definition base16.h:25
#define DBGC(...)
Definition compiler.h:530
#define EINVAL
Invalid argument.
Definition errno.h:472
#define HTTP_DIGEST_NC
HTTP Digest authentication client nonce count.
Definition http.h:127
#define EACCES_USERNAME
Definition httpbasic.c:41
static void http_digest_init(struct http_digest_context *ctx)
Initialise HTTP Digest.
Definition httpdigest.c:136
static void http_digest_update(struct http_digest_context *ctx, const char *string)
Update HTTP Digest with new data.
Definition httpdigest.c:151
static void http_digest_final(struct http_digest_context *ctx, char *out, size_t len)
Finalise HTTP Digest.
Definition httpdigest.c:170
uint64_t rsp
Definition librm.h:18
static struct dynamic_item password
Definition login_ui.c:37
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition random.c:32
An HTTP Digest algorithm context.
Definition httpdigest.c:50
uint8_t md5[MD5_CTX_SIZE]
MD5 context.
Definition httpdigest.c:52
const char * name
Method name (e.g.
Definition http.h:102
HTTP request Digest authentication descriptor.
Definition http.h:169
char cnonce[HTTP_DIGEST_CNONCE_LEN+1]
Client nonce.
Definition http.h:177
const char * qop
Quality of protection.
Definition http.h:173
char response[HTTP_DIGEST_RESPONSE_LEN+1]
Response.
Definition http.h:179
const char * algorithm
Algorithm.
Definition http.h:175
const char * username
Username.
Definition http.h:171
struct http_request_auth_digest digest
Digest authentication descriptor.
Definition http.h:203
struct http_method * method
Method.
Definition http.h:220
const char * uri
Request URI string.
Definition http.h:222
HTTP response Digest authorization descriptor.
Definition http.h:281
struct http_response_auth_digest digest
Digest authorization descriptor.
Definition http.h:311
struct http_response_auth auth
Authorization descriptor.
Definition http.h:354
struct uri * uri
Request URI.
Definition http.h:442
const char * user
User name.
Definition uri.h:73
const char * password
Password.
Definition uri.h:75
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383

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(), http_digest_context::md5, MD5_DIGEST_SIZE, http_request::method, http_method::name, password, 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()

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 277 of file httpdigest.c.

278 {
279 struct http_request_auth_digest *req = &http->request.auth.digest;
281 size_t used = 0;
282
283 /* Sanity checks */
284 assert ( rsp->realm != NULL );
285 assert ( rsp->nonce != NULL );
286 assert ( req->username != NULL );
287 if ( req->qop ) {
288 assert ( req->algorithm != NULL );
289 assert ( req->cnonce[0] != '\0' );
290 }
291 assert ( req->response[0] != '\0' );
292
293 /* Construct response */
294 used += ssnprintf ( ( buf + used ), ( len - used ),
295 "realm=\"%s\", nonce=\"%s\", uri=\"%s\", "
296 "username=\"%s\"", rsp->realm, rsp->nonce,
297 http->request.uri, req->username );
298 if ( rsp->opaque ) {
299 used += ssnprintf ( ( buf + used ), ( len - used ),
300 ", opaque=\"%s\"", rsp->opaque );
301 }
302 if ( req->qop ) {
303 used += ssnprintf ( ( buf + used ), ( len - used ),
304 ", qop=%s, algorithm=%s, cnonce=\"%s\", "
305 "nc=" HTTP_DIGEST_NC, req->qop,
306 req->algorithm, req->cnonce );
307 }
308 used += ssnprintf ( ( buf + used ), ( len - used ),
309 ", response=\"%s\"", req->response );
310
311 return used;
312}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
int ssnprintf(char *buf, ssize_t ssize, const char *fmt,...)
Version of snprintf() that accepts a signed buffer size.
Definition vsprintf.c:441

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:
= {
HTTP_DIGEST_FIELD ( realm ),
HTTP_DIGEST_FIELD ( opaque ),
}
#define HTTP_DIGEST_FIELD(_name)
Define an HTTP Digest "WWW-Authenticate" response field.
Definition httpdigest.c:66
u16 algorithm
Authentication algorithm (Open System or Shared Key).
Definition ieee80211.h:1
u8 nonce[32]
Nonce value.
Definition wpa.h:25

HTTP Digest "WWW-Authenticate" fields.

Definition at line 89 of file httpdigest.c.

89 {
90 HTTP_DIGEST_FIELD ( realm ),
91 HTTP_DIGEST_FIELD ( qop ),
94 HTTP_DIGEST_FIELD ( opaque ),
95};

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_format_digest_auth(struct http_transaction *http, char *buf, size_t len)
Construct HTTP "Authorization" header for Digest authentication.
Definition httpdigest.c:277
static int http_digest_authenticate(struct http_transaction *http)
Perform HTTP Digest authentication.
Definition httpdigest.c:185
static int http_parse_digest_auth(struct http_transaction *http, char *line)
Parse HTTP "WWW-Authenticate" header for Digest authentication.
Definition httpdigest.c:104

HTTP Digest authentication scheme.

Definition at line 315 of file httpdigest.c.

315 {
316 .name = "Digest",
317 .parse = http_parse_digest_auth,
318 .authenticate = http_digest_authenticate,
319 .format = http_format_digest_auth,
320};