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} |