| 678 | } |
| 679 | |
| 680 | static apr_status_t update_directory(const md_http_response_t *res, void *data) |
| 681 | { |
| 682 | md_http_request_t *req = res->req; |
| 683 | md_acme_t *acme = ((update_dir_ctx *)data)->acme; |
| 684 | md_result_t *result = ((update_dir_ctx *)data)->result; |
| 685 | apr_status_t rv; |
| 686 | md_json_t *json; |
| 687 | const char *s; |
| 688 | |
| 689 | md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, req->pool, "directory lookup response: %d", res->status); |
| 690 | if (res->status == 503) { |
| 691 | md_result_printf(result, APR_EAGAIN, |
| 692 | "The ACME server at <%s> reports that Service is Unavailable (503). This " |
| 693 | "may happen during maintenance for short periods of time.", acme->url); |
| 694 | md_result_log(result, MD_LOG_INFO); |
| 695 | rv = result->status; |
| 696 | goto leave; |
| 697 | } |
| 698 | else if (res->status < 200 || res->status >= 300) { |
| 699 | md_result_printf(result, APR_EAGAIN, |
| 700 | "The ACME server at <%s> responded with HTTP status %d. This " |
| 701 | "is unusual. Please verify that the URL is correct and that you can indeed " |
| 702 | "make request from the server to it by other means, e.g. invoking curl/wget.", |
| 703 | acme->url, res->status); |
| 704 | rv = result->status; |
| 705 | goto leave; |
| 706 | } |
| 707 | |
| 708 | rv = md_json_read_http(&json, req->pool, res); |
| 709 | if (APR_SUCCESS != rv) { |
| 710 | md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, req->pool, "reading JSON body"); |
| 711 | goto leave; |
| 712 | } |
| 713 | |
| 714 | if (md_log_is_level(acme->p, MD_LOG_TRACE2)) { |
| 715 | s = md_json_writep(json, req->pool, MD_JSON_FMT_INDENT); |
| 716 | md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, rv, req->pool, |
| 717 | "response: %s", s ? s : "<failed to serialize!>"); |
| 718 | } |
| 719 | |
| 720 | /* What have we got? */ |
| 721 | if ((s = md_json_dups(acme->p, json, "newAccount", NULL))) { |
| 722 | acme->api.v2.new_account = s; |
| 723 | acme->api.v2.new_order = md_json_dups(acme->p, json, "newOrder", NULL); |
| 724 | acme->api.v2.revoke_cert = md_json_dups(acme->p, json, "revokeCert", NULL); |
| 725 | acme->api.v2.key_change = md_json_dups(acme->p, json, "keyChange", NULL); |
| 726 | acme->api.v2.new_nonce = md_json_dups(acme->p, json, "newNonce", NULL); |
| 727 | acme->api.v2.renewal_info = md_json_dups(acme->p, json, "renewalInfo", NULL); |
| 728 | /* RFC 8555 only requires "directory" and "newNonce" resources. |
| 729 | * mod_md uses "newAccount" and "newOrder" so check for them. |
| 730 | * But mod_md does not use the "revokeCert" or "keyChange" |
| 731 | * resources, so tolerate the absence of those keys. In the |
| 732 | * future if mod_md implements revocation or key rollover then |
| 733 | * the use of those features should be predicated on the |
| 734 | * server's advertised capabilities. */ |
| 735 | if (acme->api.v2.new_account |
| 736 | && acme->api.v2.new_order |
| 737 | && acme->api.v2.new_nonce) { |
nothing calls this directly
no test coverage detected