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_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 md5_context *ctx)
 Initialise HTTP Digest.
static void http_digest_update (struct md5_context *ctx, const char *string)
 Update HTTP Digest with new data.
static void http_digest_final (struct md5_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:181
#define EINFO_EACCES
Definition errno.h:300

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

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

Definition at line 58 of file httpdigest.c.

58#define HTTP_DIGEST_FIELD( _name ) { \
59 .name = #_name, \
60 .offset = offsetof ( struct http_transaction, \
61 response.auth.digest._name ), \
62 }

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

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

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

97 {
98 struct http_digest_field *field;
99 char *key;
100 char *value;
101 unsigned int i;
102
103 /* Process fields */
104 while ( ( key = http_token ( &line, &value ) ) ) {
105 for ( i = 0 ; i < ( sizeof ( http_digest_fields ) /
106 sizeof ( http_digest_fields[0] ) ) ; i++){
107 field = &http_digest_fields[i];
108 if ( strcasecmp ( key, field->name ) == 0 )
109 http_digest_field ( http, field, value );
110 }
111 }
112
113 /* Allow HTTP request to be retried if the request had not
114 * already tried authentication.
115 */
116 if ( ! http->request.auth.auth )
118
119 return 0;
120}
union @162305117151260234136356364136041353210355154177 key
Sense key.
Definition scsi.h:3
@ HTTP_RESPONSE_RETRY
Transaction may be retried on failure.
Definition http.h:361
char * http_token(char **line, char **value)
Get HTTP response token.
Definition httpcore.c:196
static struct http_digest_field http_digest_fields[]
HTTP Digest "WWW-Authenticate" fields.
Definition httpdigest.c:81
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:72
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:50
const char * name
Name.
Definition httpdigest.c:52
struct http_authentication * auth
Authentication scheme (if any)
Definition http.h:190
struct http_request_auth auth
Authentication descriptor.
Definition http.h:223
unsigned int flags
Flags.
Definition http.h:351
struct http_response response
Response.
Definition http.h:439
struct http_request request
Request.
Definition http.h:437

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 md5_context * ctx)
static

Initialise HTTP Digest.

Parameters
ctxDigest context
stringInitial string

Definition at line 128 of file httpdigest.c.

128 {
129
130 /* Initialise MD5 digest */
132}
struct golan_eq_context ctx
Definition CIB_PRM.h:0
static void digest_init(struct digest_algorithm *digest, void *ctx)
Definition crypto.h:219
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition md5.c:287

References ctx, digest_init(), and md5_algorithm.

Referenced by http_digest_authenticate().

◆ http_digest_update()

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

140 {
141 static const char colon = ':';
142
143 /* Add (possibly colon-separated) field to MD5 digest */
144 if ( ctx->len )
145 digest_update ( &md5_algorithm, ctx, &colon, sizeof ( colon ) );
146 digest_update ( &md5_algorithm, ctx, string, strlen ( string ) );
147}
static void digest_update(struct digest_algorithm *digest, void *ctx, const void *data, size_t len)
Definition crypto.h:224
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 md5_context * ctx,
char * out,
size_t len )
static

Finalise HTTP Digest.

Parameters
ctxDigest context
outBuffer for digest output
lenBuffer length

Definition at line 156 of file httpdigest.c.

157 {
158 uint8_t digest[MD5_DIGEST_SIZE];
159
160 /* Finalise and base16-encode MD5 digest */
161 digest_final ( &md5_algorithm, ctx, digest );
162 base16_encode ( digest, sizeof ( digest ), out, len );
163}
__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:230
#define MD5_DIGEST_SIZE
MD5 digest size.
Definition md5.h:73

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

171 {
172 struct http_request_auth_digest *req = &http->request.auth.digest;
174 char ha1[ base16_encoded_len ( MD5_DIGEST_SIZE ) + 1 /* NUL */ ];
175 char ha2[ base16_encoded_len ( MD5_DIGEST_SIZE ) + 1 /* NUL */ ];
176 static const char md5sess[] = "MD5-sess";
177 static const char md5[] = "MD5";
178 struct md5_context ctx;
179 const char *password;
180
181 /* Check for required response parameters */
182 if ( ! rsp->realm ) {
183 DBGC ( http, "HTTP %p has no realm for Digest authentication\n",
184 http );
185 return -EINVAL;
186 }
187 if ( ! rsp->nonce ) {
188 DBGC ( http, "HTTP %p has no nonce for Digest authentication\n",
189 http );
190 return -EINVAL;
191 }
192
193 /* Record username and password */
194 if ( ! http->uri->user ) {
195 DBGC ( http, "HTTP %p has no username for Digest "
196 "authentication\n", http );
197 return -EACCES_USERNAME;
198 }
199 req->username = http->uri->user;
200 password = ( http->uri->password ? http->uri->password : "" );
201
202 /* Handle quality of protection */
203 if ( rsp->qop ) {
204
205 /* Use "auth" in subsequent request */
206 req->qop = "auth";
207
208 /* Generate a client nonce */
209 snprintf ( req->cnonce, sizeof ( req->cnonce ),
210 "%08lx", random() );
211
212 /* Determine algorithm */
213 req->algorithm = md5;
214 if ( rsp->algorithm &&
215 ( strcasecmp ( rsp->algorithm, md5sess ) == 0 ) ) {
216 req->algorithm = md5sess;
217 }
218 }
219
220 /* Generate HA1 */
223 http_digest_update ( &ctx, rsp->realm );
225 http_digest_final ( &ctx, ha1, sizeof ( ha1 ) );
226 if ( req->algorithm == md5sess ) {
228 http_digest_update ( &ctx, ha1 );
229 http_digest_update ( &ctx, rsp->nonce );
230 http_digest_update ( &ctx, req->cnonce );
231 http_digest_final ( &ctx, ha1, sizeof ( ha1 ) );
232 }
233
234 /* Generate HA2 */
237 http_digest_update ( &ctx, http->request.uri );
238 http_digest_final ( &ctx, ha2, sizeof ( ha2 ) );
239
240 /* Generate response */
242 http_digest_update ( &ctx, ha1 );
243 http_digest_update ( &ctx, rsp->nonce );
244 if ( req->qop ) {
246 http_digest_update ( &ctx, req->cnonce );
247 http_digest_update ( &ctx, req->qop );
248 }
249 http_digest_update ( &ctx, ha2 );
250 http_digest_final ( &ctx, req->response, sizeof ( req->response ) );
251
252 return 0;
253}
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:505
#define EINVAL
Invalid argument.
Definition errno.h:429
#define HTTP_DIGEST_NC
HTTP Digest authentication client nonce count.
Definition http.h:120
#define EACCES_USERNAME
Definition httpbasic.c:41
static void http_digest_update(struct md5_context *ctx, const char *string)
Update HTTP Digest with new data.
Definition httpdigest.c:140
static void http_digest_init(struct md5_context *ctx)
Initialise HTTP Digest.
Definition httpdigest.c:128
static void http_digest_final(struct md5_context *ctx, char *out, size_t len)
Finalise HTTP Digest.
Definition httpdigest.c:156
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
const char * name
Method name (e.g.
Definition http.h:102
HTTP request Digest authentication descriptor.
Definition http.h:162
char cnonce[HTTP_DIGEST_CNONCE_LEN+1]
Client nonce.
Definition http.h:170
const char * qop
Quality of protection.
Definition http.h:166
char response[HTTP_DIGEST_RESPONSE_LEN+1]
Response.
Definition http.h:172
const char * algorithm
Algorithm.
Definition http.h:168
const char * username
Username.
Definition http.h:164
struct http_request_auth_digest digest
Digest authentication descriptor.
Definition http.h:196
struct http_method * method
Method.
Definition http.h:213
const char * uri
Request URI string.
Definition http.h:215
HTTP response Digest authorization descriptor.
Definition http.h:274
struct http_response_auth_digest digest
Digest authorization descriptor.
Definition http.h:304
struct http_response_auth auth
Authorization descriptor.
Definition http.h:347
struct uri * uri
Request URI.
Definition http.h:435
An MD5 context.
Definition md5.h:59
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(), 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 263 of file httpdigest.c.

264 {
265 struct http_request_auth_digest *req = &http->request.auth.digest;
267 size_t used = 0;
268
269 /* Sanity checks */
270 assert ( rsp->realm != NULL );
271 assert ( rsp->nonce != NULL );
272 assert ( req->username != NULL );
273 if ( req->qop ) {
274 assert ( req->algorithm != NULL );
275 assert ( req->cnonce[0] != '\0' );
276 }
277 assert ( req->response[0] != '\0' );
278
279 /* Construct response */
280 used += ssnprintf ( ( buf + used ), ( len - used ),
281 "realm=\"%s\", nonce=\"%s\", uri=\"%s\", "
282 "username=\"%s\"", rsp->realm, rsp->nonce,
283 http->request.uri, req->username );
284 if ( rsp->opaque ) {
285 used += ssnprintf ( ( buf + used ), ( len - used ),
286 ", opaque=\"%s\"", rsp->opaque );
287 }
288 if ( req->qop ) {
289 used += ssnprintf ( ( buf + used ), ( len - used ),
290 ", qop=%s, algorithm=%s, cnonce=\"%s\", "
291 "nc=" HTTP_DIGEST_NC, req->qop,
292 req->algorithm, req->cnonce );
293 }
294 used += ssnprintf ( ( buf + used ), ( len - used ),
295 ", response=\"%s\"", req->response );
296
297 return used;
298}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
int ssnprintf(char *buf, ssize_t ssize, const char *fmt,...)
Version of vsnprintf() that accepts a signed buffer size.
Definition vsprintf.c:421

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:58
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 81 of file httpdigest.c.

81 {
82 HTTP_DIGEST_FIELD ( realm ),
83 HTTP_DIGEST_FIELD ( qop ),
86 HTTP_DIGEST_FIELD ( opaque ),
87};

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:263
static int http_digest_authenticate(struct http_transaction *http)
Perform HTTP Digest authentication.
Definition httpdigest.c:171
static int http_parse_digest_auth(struct http_transaction *http, char *line)
Parse HTTP "WWW-Authenticate" header for Digest authentication.
Definition httpdigest.c:96

HTTP Digest authentication scheme.

Definition at line 301 of file httpdigest.c.

301 {
302 .name = "Digest",
303 .parse = http_parse_digest_auth,
304 .authenticate = http_digest_authenticate,
305 .format = http_format_digest_auth,
306};