Deleted Added
full compact
auth_digest.c (253895) auth_digest.c (262324)
1/* Copyright 2009 Justin Erenkrantz and Greg Stein
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *

--- 82 unchanged lines hidden (view full) ---

91 char *buf = apr_palloc(pool, APR_UUID_FORMATTED_LENGTH + 1);
92
93 apr_uuid_get(&uuid);
94 apr_uuid_format(buf, &uuid);
95
96 return hex_encode((unsigned char*)buf, pool);
97}
98
1/* Copyright 2009 Justin Erenkrantz and Greg Stein
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *

--- 82 unchanged lines hidden (view full) ---

91 char *buf = apr_palloc(pool, APR_UUID_FORMATTED_LENGTH + 1);
92
93 apr_uuid_get(&uuid);
94 apr_uuid_format(buf, &uuid);
95
96 return hex_encode((unsigned char*)buf, pool);
97}
98
99static const char *
100build_digest_ha1(const char *username,
99static apr_status_t
100build_digest_ha1(const char **out_ha1,
101 const char *username,
101 const char *password,
102 const char *realm_name,
103 apr_pool_t *pool)
104{
105 const char *tmp;
106 unsigned char ha1[APR_MD5_DIGESTSIZE];
107 apr_status_t status;
108
109 /* calculate ha1:
110 MD5 hash of the combined user name, authentication realm and password */
111 tmp = apr_psprintf(pool, "%s:%s:%s",
112 username,
113 realm_name,
114 password);
115 status = apr_md5(ha1, tmp, strlen(tmp));
102 const char *password,
103 const char *realm_name,
104 apr_pool_t *pool)
105{
106 const char *tmp;
107 unsigned char ha1[APR_MD5_DIGESTSIZE];
108 apr_status_t status;
109
110 /* calculate ha1:
111 MD5 hash of the combined user name, authentication realm and password */
112 tmp = apr_psprintf(pool, "%s:%s:%s",
113 username,
114 realm_name,
115 password);
116 status = apr_md5(ha1, tmp, strlen(tmp));
117 if (status)
118 return status;
116
119
117 return hex_encode(ha1, pool);
120 *out_ha1 = hex_encode(ha1, pool);
121
122 return APR_SUCCESS;
118}
119
123}
124
120static const char *
121build_digest_ha2(const char *uri,
125static apr_status_t
126build_digest_ha2(const char **out_ha2,
127 const char *uri,
122 const char *method,
123 const char *qop,
124 apr_pool_t *pool)
125{
126 if (!qop || strcmp(qop, "auth") == 0) {
127 const char *tmp;
128 unsigned char ha2[APR_MD5_DIGESTSIZE];
129 apr_status_t status;
130
131 /* calculate ha2:
132 MD5 hash of the combined method and URI */
133 tmp = apr_psprintf(pool, "%s:%s",
134 method,
135 uri);
136 status = apr_md5(ha2, tmp, strlen(tmp));
128 const char *method,
129 const char *qop,
130 apr_pool_t *pool)
131{
132 if (!qop || strcmp(qop, "auth") == 0) {
133 const char *tmp;
134 unsigned char ha2[APR_MD5_DIGESTSIZE];
135 apr_status_t status;
136
137 /* calculate ha2:
138 MD5 hash of the combined method and URI */
139 tmp = apr_psprintf(pool, "%s:%s",
140 method,
141 uri);
142 status = apr_md5(ha2, tmp, strlen(tmp));
143 if (status)
144 return status;
137
145
138 return hex_encode(ha2, pool);
146 *out_ha2 = hex_encode(ha2, pool);
147
148 return APR_SUCCESS;
139 } else {
140 /* TODO: auth-int isn't supported! */
149 } else {
150 /* TODO: auth-int isn't supported! */
151 return APR_ENOTIMPL;
141 }
152 }
142
143 return NULL;
144}
145
153}
154
146static const char *
147build_auth_header(digest_authn_info_t *digest_info,
155static apr_status_t
156build_auth_header(const char **out_header,
157 digest_authn_info_t *digest_info,
148 const char *path,
149 const char *method,
150 apr_pool_t *pool)
151{
152 char *hdr;
153 const char *ha2;
154 const char *response;
155 unsigned char response_hdr[APR_MD5_DIGESTSIZE];
156 const char *response_hdr_hex;
157 apr_status_t status;
158
158 const char *path,
159 const char *method,
160 apr_pool_t *pool)
161{
162 char *hdr;
163 const char *ha2;
164 const char *response;
165 unsigned char response_hdr[APR_MD5_DIGESTSIZE];
166 const char *response_hdr_hex;
167 apr_status_t status;
168
159 ha2 = build_digest_ha2(path, method, digest_info->qop, pool);
169 status = build_digest_ha2(&ha2, path, method, digest_info->qop, pool);
170 if (status)
171 return status;
160
161 hdr = apr_psprintf(pool,
162 "Digest realm=\"%s\","
163 " username=\"%s\","
164 " nonce=\"%s\","
165 " uri=\"%s\"",
166 digest_info->realm, digest_info->username,
167 digest_info->nonce,

--- 21 unchanged lines hidden (view full) ---

189 /* Build the response header:
190 MD5 hash of the combined HA1 result, server nonce (nonce)
191 and HA2 result. */
192 response = apr_psprintf(pool, "%s:%s:%s",
193 digest_info->ha1, digest_info->nonce, ha2);
194 }
195
196 status = apr_md5(response_hdr, response, strlen(response));
172
173 hdr = apr_psprintf(pool,
174 "Digest realm=\"%s\","
175 " username=\"%s\","
176 " nonce=\"%s\","
177 " uri=\"%s\"",
178 digest_info->realm, digest_info->username,
179 digest_info->nonce,

--- 21 unchanged lines hidden (view full) ---

201 /* Build the response header:
202 MD5 hash of the combined HA1 result, server nonce (nonce)
203 and HA2 result. */
204 response = apr_psprintf(pool, "%s:%s:%s",
205 digest_info->ha1, digest_info->nonce, ha2);
206 }
207
208 status = apr_md5(response_hdr, response, strlen(response));
209 if (status)
210 return status;
211
197 response_hdr_hex = hex_encode(response_hdr, pool);
198
199 hdr = apr_psprintf(pool, "%s, response=\"%s\"", hdr, response_hdr_hex);
200
201 if (digest_info->opaque) {
202 hdr = apr_psprintf(pool, "%s, opaque=\"%s\"", hdr,
203 digest_info->opaque);
204 }
205 if (digest_info->algorithm) {
206 hdr = apr_psprintf(pool, "%s, algorithm=\"%s\"", hdr,
207 digest_info->algorithm);
208 }
209
212 response_hdr_hex = hex_encode(response_hdr, pool);
213
214 hdr = apr_psprintf(pool, "%s, response=\"%s\"", hdr, response_hdr_hex);
215
216 if (digest_info->opaque) {
217 hdr = apr_psprintf(pool, "%s, opaque=\"%s\"", hdr,
218 digest_info->opaque);
219 }
220 if (digest_info->algorithm) {
221 hdr = apr_psprintf(pool, "%s, algorithm=\"%s\"", hdr,
222 digest_info->algorithm);
223 }
224
210 return hdr;
225 *out_header = hdr;
226
227 return APR_SUCCESS;
211}
212
213apr_status_t
214serf__handle_digest_auth(int code,
215 serf_request_t *request,
216 serf_bucket_t *response,
217 const char *auth_hdr,
218 const char *auth_attr,

--- 106 unchanged lines hidden (view full) ---

325 digest_info->nonce = apr_pstrdup(digest_info->pool, nonce);
326 digest_info->cnonce = NULL;
327 digest_info->opaque = apr_pstrdup(digest_info->pool, opaque);
328 digest_info->algorithm = apr_pstrdup(digest_info->pool, algorithm);
329 digest_info->realm = apr_pstrdup(digest_info->pool, realm_name);
330 digest_info->username = apr_pstrdup(digest_info->pool, username);
331 digest_info->digest_nc++;
332
228}
229
230apr_status_t
231serf__handle_digest_auth(int code,
232 serf_request_t *request,
233 serf_bucket_t *response,
234 const char *auth_hdr,
235 const char *auth_attr,

--- 106 unchanged lines hidden (view full) ---

342 digest_info->nonce = apr_pstrdup(digest_info->pool, nonce);
343 digest_info->cnonce = NULL;
344 digest_info->opaque = apr_pstrdup(digest_info->pool, opaque);
345 digest_info->algorithm = apr_pstrdup(digest_info->pool, algorithm);
346 digest_info->realm = apr_pstrdup(digest_info->pool, realm_name);
347 digest_info->username = apr_pstrdup(digest_info->pool, username);
348 digest_info->digest_nc++;
349
333 digest_info->ha1 = build_digest_ha1(username, password, digest_info->realm,
334 digest_info->pool);
350 status = build_digest_ha1(&digest_info->ha1, username, password,
351 digest_info->realm, digest_info->pool);
335
336 apr_pool_destroy(cred_pool);
337
338 /* If the handshake is finished tell serf it can send as much requests as it
339 likes. */
340 serf_connection_set_max_outstanding_requests(conn, 0);
341
352
353 apr_pool_destroy(cred_pool);
354
355 /* If the handshake is finished tell serf it can send as much requests as it
356 likes. */
357 serf_connection_set_max_outstanding_requests(conn, 0);
358
342 return APR_SUCCESS;
359 return status;
343}
344
345apr_status_t
346serf__init_digest(int code,
347 serf_context_t *ctx,
348 apr_pool_t *pool)
349{
350 return APR_SUCCESS;

--- 31 unchanged lines hidden (view full) ---

382 serf_request_t *request,
383 const char *method,
384 const char *uri,
385 serf_bucket_t *hdrs_bkt)
386{
387 serf_context_t *ctx = conn->ctx;
388 serf__authn_info_t *authn_info;
389 digest_authn_info_t *digest_info;
360}
361
362apr_status_t
363serf__init_digest(int code,
364 serf_context_t *ctx,
365 apr_pool_t *pool)
366{
367 return APR_SUCCESS;

--- 31 unchanged lines hidden (view full) ---

399 serf_request_t *request,
400 const char *method,
401 const char *uri,
402 serf_bucket_t *hdrs_bkt)
403{
404 serf_context_t *ctx = conn->ctx;
405 serf__authn_info_t *authn_info;
406 digest_authn_info_t *digest_info;
390 apr_status_t status = APR_SUCCESS;
407 apr_status_t status;
391
392 if (peer == HOST) {
393 authn_info = serf__get_authn_info_for_server(conn);
394 } else {
395 authn_info = &ctx->proxy_authn_info;
396 }
397 digest_info = authn_info->baton;
398

--- 17 unchanged lines hidden (view full) ---

416 return status;
417
418 path = parsed_uri.path;
419 }
420
421 /* Build a new Authorization header. */
422 digest_info->header = (peer == HOST) ? "Authorization" :
423 "Proxy-Authorization";
408
409 if (peer == HOST) {
410 authn_info = serf__get_authn_info_for_server(conn);
411 } else {
412 authn_info = &ctx->proxy_authn_info;
413 }
414 digest_info = authn_info->baton;
415

--- 17 unchanged lines hidden (view full) ---

433 return status;
434
435 path = parsed_uri.path;
436 }
437
438 /* Build a new Authorization header. */
439 digest_info->header = (peer == HOST) ? "Authorization" :
440 "Proxy-Authorization";
424 value = build_auth_header(digest_info, path, method,
425 conn->pool);
441 status = build_auth_header(&value, digest_info, path, method,
442 conn->pool);
443 if (status)
444 return status;
426
427 serf_bucket_headers_setn(hdrs_bkt, digest_info->header,
428 value);
429 digest_info->digest_nc++;
430
431 /* Store the uri of this request on the serf_request_t object, to make
432 it available when validating the Authentication-Info header of the
433 matching response. */
445
446 serf_bucket_headers_setn(hdrs_bkt, digest_info->header,
447 value);
448 digest_info->digest_nc++;
449
450 /* Store the uri of this request on the serf_request_t object, to make
451 it available when validating the Authentication-Info header of the
452 matching response. */
434 request->auth_baton = path;
453 request->auth_baton = (void *)path;
435 }
436
454 }
455
437 return status;
456 return APR_SUCCESS;
438}
439
440apr_status_t
457}
458
459apr_status_t
441serf__validate_response_digest_auth(peer_t peer,
460serf__validate_response_digest_auth(const serf__authn_scheme_t *scheme,
461 peer_t peer,
442 int code,
443 serf_connection_t *conn,
444 serf_request_t *request,
445 serf_bucket_t *response,
446 apr_pool_t *pool)
447{
448 const char *key;
449 char *auth_attr;
450 char *nextkv;
451 const char *rspauth = NULL;
452 const char *qop = NULL;
453 const char *nc_str = NULL;
454 serf_bucket_t *hdrs;
455 serf_context_t *ctx = conn->ctx;
462 int code,
463 serf_connection_t *conn,
464 serf_request_t *request,
465 serf_bucket_t *response,
466 apr_pool_t *pool)
467{
468 const char *key;
469 char *auth_attr;
470 char *nextkv;
471 const char *rspauth = NULL;
472 const char *qop = NULL;
473 const char *nc_str = NULL;
474 serf_bucket_t *hdrs;
475 serf_context_t *ctx = conn->ctx;
476 apr_status_t status;
456
457 hdrs = serf_bucket_response_get_headers(response);
458
459 /* Need a copy cuz we're going to write NUL characters into the string. */
460 if (peer == HOST)
461 auth_attr = apr_pstrdup(pool,
462 serf_bucket_headers_get(hdrs, "Authentication-Info"));
463 else

--- 47 unchanged lines hidden (view full) ---

511
512 if (peer == HOST) {
513 authn_info = serf__get_authn_info_for_server(conn);
514 } else {
515 authn_info = &ctx->proxy_authn_info;
516 }
517 digest_info = authn_info->baton;
518
477
478 hdrs = serf_bucket_response_get_headers(response);
479
480 /* Need a copy cuz we're going to write NUL characters into the string. */
481 if (peer == HOST)
482 auth_attr = apr_pstrdup(pool,
483 serf_bucket_headers_get(hdrs, "Authentication-Info"));
484 else

--- 47 unchanged lines hidden (view full) ---

532
533 if (peer == HOST) {
534 authn_info = serf__get_authn_info_for_server(conn);
535 } else {
536 authn_info = &ctx->proxy_authn_info;
537 }
538 digest_info = authn_info->baton;
539
519 ha2 = build_digest_ha2(req_uri, "", qop, pool);
540 status = build_digest_ha2(&ha2, req_uri, "", qop, pool);
541 if (status)
542 return status;
543
520 tmp = apr_psprintf(pool, "%s:%s:%s:%s:%s:%s",
521 digest_info->ha1, digest_info->nonce, nc_str,
522 digest_info->cnonce, digest_info->qop, ha2);
523 apr_md5(resp_hdr, tmp, strlen(tmp));
524 resp_hdr_hex = hex_encode(resp_hdr, pool);
525
526 /* Incorrect response-digest in Authentication-Info header. */
527 if (strcmp(rspauth, resp_hdr_hex) != 0) {
528 return SERF_ERROR_AUTHN_FAILED;
529 }
530 }
531
532 return APR_SUCCESS;
533}
544 tmp = apr_psprintf(pool, "%s:%s:%s:%s:%s:%s",
545 digest_info->ha1, digest_info->nonce, nc_str,
546 digest_info->cnonce, digest_info->qop, ha2);
547 apr_md5(resp_hdr, tmp, strlen(tmp));
548 resp_hdr_hex = hex_encode(resp_hdr, pool);
549
550 /* Incorrect response-digest in Authentication-Info header. */
551 if (strcmp(rspauth, resp_hdr_hex) != 0) {
552 return SERF_ERROR_AUTHN_FAILED;
553 }
554 }
555
556 return APR_SUCCESS;
557}