| 1423 | } |
| 1424 | |
| 1425 | static int check_nonce(request_rec *r, digest_header_rec *resp, |
| 1426 | const digest_config_rec *conf) |
| 1427 | { |
| 1428 | apr_time_t dt; |
| 1429 | time_rec nonce_time; |
| 1430 | char tmp, hash[NONCE_HASH_LEN+1]; |
| 1431 | |
| 1432 | tmp = resp->nonce[NONCE_TIME_LEN]; |
| 1433 | resp->nonce[NONCE_TIME_LEN] = '\0'; |
| 1434 | apr_base64_decode_binary(nonce_time.arr, resp->nonce); |
| 1435 | gen_nonce_hash(hash, resp->nonce, resp->opaque, r->server, conf); |
| 1436 | resp->nonce[NONCE_TIME_LEN] = tmp; |
| 1437 | resp->nonce_time = nonce_time.time; |
| 1438 | |
| 1439 | if (!ap_memeq_timingsafe(hash, resp->nonce+NONCE_TIME_LEN, NONCE_HASH_LEN)) { |
| 1440 | ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01776) |
| 1441 | "invalid nonce %s received - hash is not %s", |
| 1442 | resp->nonce, hash); |
| 1443 | note_digest_auth_failure(r, conf, resp, 1); |
| 1444 | return HTTP_UNAUTHORIZED; |
| 1445 | } |
| 1446 | |
| 1447 | dt = r->request_time - nonce_time.time; |
| 1448 | if (conf->nonce_lifetime > 0 && dt < 0) { |
| 1449 | ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01777) |
| 1450 | "invalid nonce %s received - user attempted " |
| 1451 | "time travel", resp->nonce); |
| 1452 | note_digest_auth_failure(r, conf, resp, 1); |
| 1453 | return HTTP_UNAUTHORIZED; |
| 1454 | } |
| 1455 | |
| 1456 | if (conf->nonce_lifetime > 0) { |
| 1457 | if (dt > conf->nonce_lifetime) { |
| 1458 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0,r, APLOGNO(01778) |
| 1459 | "user %s: nonce expired (%.2f seconds old " |
| 1460 | "- max lifetime %.2f) - sending new nonce", |
| 1461 | r->user, (double)apr_time_sec(dt), |
| 1462 | (double)apr_time_sec(conf->nonce_lifetime)); |
| 1463 | note_digest_auth_failure(r, conf, resp, 1); |
| 1464 | return HTTP_UNAUTHORIZED; |
| 1465 | } |
| 1466 | } |
| 1467 | else if (conf->nonce_lifetime == 0 && resp->client) { |
| 1468 | if (memcmp(resp->client->last_nonce, resp->nonce, NONCE_LEN)) { |
| 1469 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(01779) |
| 1470 | "user %s: one-time-nonce mismatch - sending " |
| 1471 | "new nonce", r->user); |
| 1472 | note_digest_auth_failure(r, conf, resp, 1); |
| 1473 | return HTTP_UNAUTHORIZED; |
| 1474 | } |
| 1475 | } |
| 1476 | /* else (lifetime < 0) => never expires */ |
| 1477 | |
| 1478 | return OK; |
| 1479 | } |
| 1480 | |
| 1481 | /* The actual MD5 code... whee */ |
| 1482 |
no test coverage detected