diff --git a/changes-entries/cern-meta-header-injection.txt b/changes-entries/cern-meta-header-injection.txt new file mode 100644 index 00000000000..2aef1eec926 --- /dev/null +++ b/changes-entries/cern-meta-header-injection.txt @@ -0,0 +1,2 @@ + *) mod_cern_meta: Reject HTTP framing headers in metadata files to prevent + response splitting. [Joe Orton] diff --git a/changes-entries/ldap-url-cache-uaf.txt b/changes-entries/ldap-url-cache-uaf.txt new file mode 100644 index 00000000000..669b188c25d --- /dev/null +++ b/changes-entries/ldap-url-cache-uaf.txt @@ -0,0 +1,2 @@ + *) mod_ldap: Fix intermittent worker crashes under concurrent + LDAP-authenticated requests. [Joe Orton] diff --git a/changes-entries/remoteip-proxy-v2-local.txt b/changes-entries/remoteip-proxy-v2-local.txt new file mode 100644 index 00000000000..c2b240b7e3c --- /dev/null +++ b/changes-entries/remoteip-proxy-v2-local.txt @@ -0,0 +1,2 @@ + *) mod_remoteip: Fix crash with PROXY v2 LOCAL command and + RemoteIPProxyProtocol enabled. [Joe Orton] diff --git a/changes-entries/substitute-maxlinelength-overflow.txt b/changes-entries/substitute-maxlinelength-overflow.txt new file mode 100644 index 00000000000..7ad53978121 --- /dev/null +++ b/changes-entries/substitute-maxlinelength-overflow.txt @@ -0,0 +1,2 @@ + *) mod_substitute: Fix SubstituteMaxLineLength to reject values too + large for the K/M/G suffix. [Joe Orton] diff --git a/changes-entries/substitute-pattern-oob-read.txt b/changes-entries/substitute-pattern-oob-read.txt new file mode 100644 index 00000000000..55eea6f041b --- /dev/null +++ b/changes-entries/substitute-pattern-oob-read.txt @@ -0,0 +1,2 @@ + *) mod_substitute: Fix crash or misbehaviour when loading a Substitute + directive with a missing closing delimiter. [Joe Orton] diff --git a/modules/filters/mod_substitute.c b/modules/filters/mod_substitute.c index 65ca5f95d01..2533d7dcd04 100644 --- a/modules/filters/mod_substitute.c +++ b/modules/filters/mod_substitute.c @@ -679,7 +679,7 @@ static const char *set_pattern(cmd_parms *cmd, void *cfg, const char *line) if (delim) from = ++ourline; if (from) { - if (*ourline != delim) { + if (*ourline && *ourline != delim) { while (*++ourline && *ourline != delim); } if (*ourline) { @@ -688,7 +688,7 @@ static const char *set_pattern(cmd_parms *cmd, void *cfg, const char *line) } } if (to) { - if (*ourline != delim) { + if (*ourline && *ourline != delim) { while (*++ourline && *ourline != delim); } if (*ourline) { @@ -777,12 +777,18 @@ static const char *set_max_line_length(cmd_parms *cmd, void *cfg, const char *ar rv = apr_strtoff(&max, arg, &end, 10); if (rv == APR_SUCCESS) { if ((*end == 'K' || *end == 'k') && !end[1]) { + if (max > APR_INT64_MAX / KBYTE) + return "SubstituteMaxLineLength value too large"; max *= KBYTE; } else if ((*end == 'M' || *end == 'm') && !end[1]) { + if (max > APR_INT64_MAX / MBYTE) + return "SubstituteMaxLineLength value too large"; max *= MBYTE; } else if ((*end == 'G' || *end == 'g') && !end[1]) { + if (max > APR_INT64_MAX / GBYTE) + return "SubstituteMaxLineLength value too large"; max *= GBYTE; } else if (*end && /* neither empty nor [Bb] */ diff --git a/modules/ldap/util_ldap.c b/modules/ldap/util_ldap.c index 00f9f91361a..8c3ed68fe2a 100644 --- a/modules/ldap/util_ldap.c +++ b/modules/ldap/util_ldap.c @@ -1013,11 +1013,10 @@ static int uldap_cache_comparedn(request_rec *r, util_ldap_connection_t *ldc, if (curl == NULL) { curl = util_ald_create_caches(st, url); } - ldap_cache_unlock(st, r); /* a simple compare? */ if (!compare_dn_on_server) { - /* unlock this read lock */ + ldap_cache_unlock(st, r); if (strcmp(dn, reqdn)) { ldc->reason = "DN Comparison FALSE (direct strcmp())"; return LDAP_COMPARE_FALSE; @@ -1030,22 +1029,18 @@ static int uldap_cache_comparedn(request_rec *r, util_ldap_connection_t *ldc, if (curl) { /* no - it's a server side compare */ - ldap_cache_lock(st, r); /* is it in the compare cache? */ newnode.reqdn = (char *)reqdn; node = util_ald_cache_fetch(curl->dn_compare_cache, &newnode); if (node != NULL) { /* If it's in the cache, it's good */ - /* unlock this read lock */ ldap_cache_unlock(st, r); ldc->reason = "DN Comparison TRUE (cached)"; return LDAP_COMPARE_TRUE; } - - /* unlock this read lock */ - ldap_cache_unlock(st, r); } + ldap_cache_unlock(st, r); start_over: if (failures > st->retries) { @@ -1104,18 +1099,21 @@ static int uldap_cache_comparedn(request_rec *r, util_ldap_connection_t *ldc, result = LDAP_COMPARE_FALSE; } else { - if (curl) { + { /* compare successful - add to the compare cache */ ldap_cache_lock(st, r); - newnode.reqdn = (char *)reqdn; - newnode.dn = (char *)dn; - - node = util_ald_cache_fetch(curl->dn_compare_cache, &newnode); - if ( (node == NULL) - || (strcmp(reqdn, node->reqdn) != 0) - || (strcmp(dn, node->dn) != 0)) - { - util_ald_cache_insert(curl->dn_compare_cache, &newnode); + curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode); + if (curl) { + newnode.reqdn = (char *)reqdn; + newnode.dn = (char *)dn; + + node = util_ald_cache_fetch(curl->dn_compare_cache, &newnode); + if ( (node == NULL) + || (strcmp(reqdn, node->reqdn) != 0) + || (strcmp(dn, node->dn) != 0)) + { + util_ald_cache_insert(curl->dn_compare_cache, &newnode); + } } ldap_cache_unlock(st, r); } @@ -1158,11 +1156,9 @@ static int uldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc, if (curl == NULL) { curl = util_ald_create_caches(st, url); } - ldap_cache_unlock(st, r); if (curl) { /* make a comparison to the cache */ - ldap_cache_lock(st, r); curtime = apr_time_now(); the_compare_node.dn = (char *)dn; @@ -1193,8 +1189,8 @@ static int uldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc, ldc->reason = "Comparison no such attribute (cached)"; } else { - ldc->reason = apr_psprintf(r->pool, - "Comparison undefined: (%d): %s (adding to cache)", + ldc->reason = apr_psprintf(r->pool, + "Comparison undefined: (%d): %s (adding to cache)", result, ldap_err2string(result)); } @@ -1203,15 +1199,15 @@ static int uldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc, /* and unlock this read lock */ ldap_cache_unlock(st, r); - ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, - "ldap_compare_s(%pp, %s, %s, %s) = %s (cached)", + ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, + "ldap_compare_s(%pp, %s, %s, %s) = %s (cached)", ldc->ldap, dn, attrib, value, ldap_err2string(result)); return result; } } - /* unlock this read lock */ - ldap_cache_unlock(st, r); } + /* unlock this read lock */ + ldap_cache_unlock(st, r); start_over: if (failures > st->retries) { @@ -1256,36 +1252,39 @@ static int uldap_cache_compare(request_rec *r, util_ldap_connection_t *ldc, if ((LDAP_COMPARE_TRUE == result) || (LDAP_COMPARE_FALSE == result) || (LDAP_NO_SUCH_ATTRIBUTE == result)) { - if (curl) { + { /* compare completed; caching result */ ldap_cache_lock(st, r); - the_compare_node.lastcompare = curtime; - the_compare_node.result = result; - the_compare_node.sgl_processed = 0; - the_compare_node.subgroupList = NULL; - - /* If the node doesn't exist then insert it, otherwise just update - * it with the last results - */ - compare_nodep = util_ald_cache_fetch(curl->compare_cache, + curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode); + if (curl) { + the_compare_node.lastcompare = curtime; + the_compare_node.result = result; + the_compare_node.sgl_processed = 0; + the_compare_node.subgroupList = NULL; + + /* If the node doesn't exist then insert it, otherwise just update + * it with the last results + */ + compare_nodep = util_ald_cache_fetch(curl->compare_cache, + &the_compare_node); + if ( (compare_nodep == NULL) + || (strcmp(the_compare_node.dn, compare_nodep->dn) != 0) + || (strcmp(the_compare_node.attrib,compare_nodep->attrib) != 0) + || (strcmp(the_compare_node.value, compare_nodep->value) != 0)) + { + void *junk; + + junk = util_ald_cache_insert(curl->compare_cache, &the_compare_node); - if ( (compare_nodep == NULL) - || (strcmp(the_compare_node.dn, compare_nodep->dn) != 0) - || (strcmp(the_compare_node.attrib,compare_nodep->attrib) != 0) - || (strcmp(the_compare_node.value, compare_nodep->value) != 0)) - { - void *junk; - - junk = util_ald_cache_insert(curl->compare_cache, - &the_compare_node); - if (junk == NULL) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01287) - "cache_compare: Cache insertion failure."); + if (junk == NULL) { + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01287) + "cache_compare: Cache insertion failure."); + } + } + else { + compare_nodep->lastcompare = curtime; + compare_nodep->result = result; } - } - else { - compare_nodep->lastcompare = curtime; - compare_nodep->result = result; } ldap_cache_unlock(st, r); } @@ -1555,11 +1554,9 @@ static int uldap_cache_check_subgroups(request_rec *r, ldap_cache_lock(st, r); curnode.url = url; curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode); - ldap_cache_unlock(st, r); if (curl && curl->compare_cache) { /* make a comparison to the cache */ - ldap_cache_lock(st, r); the_compare_node.dn = (char *)dn; the_compare_node.attrib = (char *)"objectClass"; @@ -1601,8 +1598,8 @@ static int uldap_cache_check_subgroups(request_rec *r, } } } - ldap_cache_unlock(st, r); } + ldap_cache_unlock(st, r); if (!tmp_local_sgl && !sgl_cached_empty) { /* No Cached SGL, retrieve from LDAP */ @@ -1616,72 +1613,74 @@ static int uldap_cache_check_subgroups(request_rec *r, dn); } - if (curl && curl->compare_cache) { + { /* * Find the generic group cache entry and add the sgl we just retrieved. */ ldap_cache_lock(st, r); + curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode); + if (curl && curl->compare_cache) { + the_compare_node.dn = (char *)dn; + the_compare_node.attrib = (char *)"objectClass"; + the_compare_node.value = (char *)sgc_ents[base_sgcIndex].name; + the_compare_node.result = 0; + the_compare_node.sgl_processed = 0; + the_compare_node.subgroupList = NULL; - the_compare_node.dn = (char *)dn; - the_compare_node.attrib = (char *)"objectClass"; - the_compare_node.value = (char *)sgc_ents[base_sgcIndex].name; - the_compare_node.result = 0; - the_compare_node.sgl_processed = 0; - the_compare_node.subgroupList = NULL; - - compare_nodep = util_ald_cache_fetch(curl->compare_cache, - &the_compare_node); - - if (compare_nodep == NULL) { - /* - * The group entry we want to attach our SGL to doesn't exist. - * We only got here if we verified this DN was actually a group - * based on the objectClass, but we can't call the compare function - * while we already hold the cache lock -- only the insert. - */ - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01291) - "Cache entry for %s doesn't exist", dn); - the_compare_node.result = LDAP_COMPARE_TRUE; - util_ald_cache_insert(curl->compare_cache, &the_compare_node); compare_nodep = util_ald_cache_fetch(curl->compare_cache, &the_compare_node); - if (compare_nodep == NULL) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01292) - "util_ldap: Couldn't retrieve group entry " - "for %s from cache", - dn); - } - } - /* - * We have a valid cache entry and a locally generated SGL. - * Attach the SGL to the cache entry - */ - if (compare_nodep && !compare_nodep->sgl_processed) { - if (!tmp_local_sgl) { - /* We looked up an SGL for a group and found it to be empty */ - if (compare_nodep->subgroupList == NULL) { - compare_nodep->sgl_processed = 1; + if (compare_nodep == NULL) { + /* + * The group entry we want to attach our SGL to doesn't exist. + * We only got here if we verified this DN was actually a group + * based on the objectClass, but we can't call the compare function + * while we already hold the cache lock -- only the insert. + */ + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01291) + "Cache entry for %s doesn't exist", dn); + the_compare_node.result = LDAP_COMPARE_TRUE; + util_ald_cache_insert(curl->compare_cache, &the_compare_node); + compare_nodep = util_ald_cache_fetch(curl->compare_cache, + &the_compare_node); + if (compare_nodep == NULL) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01292) + "util_ldap: Couldn't retrieve group entry " + "for %s from cache", + dn); } } - else { - util_compare_subgroup_t *sgl_copy = - util_ald_sgl_dup(curl->compare_cache, tmp_local_sgl); - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01293) - "Copying local SGL of len %d for group %s into cache", - tmp_local_sgl->len, dn); - if (sgl_copy) { - if (compare_nodep->subgroupList) { - util_ald_sgl_free(curl->compare_cache, - &(compare_nodep->subgroupList)); + + /* + * We have a valid cache entry and a locally generated SGL. + * Attach the SGL to the cache entry + */ + if (compare_nodep && !compare_nodep->sgl_processed) { + if (!tmp_local_sgl) { + /* We looked up an SGL for a group and found it to be empty */ + if (compare_nodep->subgroupList == NULL) { + compare_nodep->sgl_processed = 1; } - compare_nodep->subgroupList = sgl_copy; - compare_nodep->sgl_processed = 1; } else { - ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, APLOGNO(01294) - "Copy of SGL failed to obtain shared memory, " - "couldn't update cache"); + util_compare_subgroup_t *sgl_copy = + util_ald_sgl_dup(curl->compare_cache, tmp_local_sgl); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01293) + "Copying local SGL of len %d for group %s into cache", + tmp_local_sgl->len, dn); + if (sgl_copy) { + if (compare_nodep->subgroupList) { + util_ald_sgl_free(curl->compare_cache, + &(compare_nodep->subgroupList)); + } + compare_nodep->subgroupList = sgl_copy; + compare_nodep->sgl_processed = 1; + } + else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, APLOGNO(01294) + "Copy of SGL failed to obtain shared memory, " + "couldn't update cache"); + } } } } @@ -1770,10 +1769,8 @@ static int uldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc, if (curl == NULL) { curl = util_ald_create_caches(st, url); } - ldap_cache_unlock(st, r); if (curl) { - ldap_cache_lock(st, r); the_search_node.username = filter; search_nodep = util_ald_cache_fetch(curl->search_cache, &the_search_node); @@ -1810,9 +1807,9 @@ static int uldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc, return LDAP_SUCCESS; } } - /* unlock this read lock */ - ldap_cache_unlock(st, r); } + /* unlock this read lock */ + ldap_cache_unlock(st, r); /* * At this point, there is no valid cached search, so lets do the search. @@ -1969,37 +1966,40 @@ static int uldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc, /* * Add the new username to the search cache. */ - if (curl) { + { ldap_cache_lock(st, r); - the_search_node.username = filter; - the_search_node.dn = *binddn; - the_search_node.bindpw = bindpw; - the_search_node.lastbind = apr_time_now(); - the_search_node.vals = vals; - the_search_node.numvals = numvals; - - /* Search again to make sure that another thread didn't ready insert - * this node into the cache before we got here. If it does exist then - * update the lastbind - */ - search_nodep = util_ald_cache_fetch(curl->search_cache, - &the_search_node); - if ((search_nodep == NULL) || - (strcmp(*binddn, search_nodep->dn) != 0)) { + curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode); + if (curl) { + the_search_node.username = filter; + the_search_node.dn = *binddn; + the_search_node.bindpw = bindpw; + the_search_node.lastbind = apr_time_now(); + the_search_node.vals = vals; + the_search_node.numvals = numvals; + + /* Search again to make sure that another thread didn't ready insert + * this node into the cache before we got here. If it does exist then + * update the lastbind + */ + search_nodep = util_ald_cache_fetch(curl->search_cache, + &the_search_node); + if ((search_nodep == NULL) || + (strcmp(*binddn, search_nodep->dn) != 0)) { - /* Nothing in cache, insert new entry */ - util_ald_cache_insert(curl->search_cache, &the_search_node); - } - else if ((!search_nodep->bindpw) || - (strcmp(bindpw, search_nodep->bindpw) != 0)) { + /* Nothing in cache, insert new entry */ + util_ald_cache_insert(curl->search_cache, &the_search_node); + } + else if ((!search_nodep->bindpw) || + (strcmp(bindpw, search_nodep->bindpw) != 0)) { - /* Entry in cache is invalid, remove it and insert new one */ - util_ald_cache_remove(curl->search_cache, search_nodep); - util_ald_cache_insert(curl->search_cache, &the_search_node); - } - else { - /* Cache entry is valid, update lastbind */ - search_nodep->lastbind = the_search_node.lastbind; + /* Entry in cache is invalid, remove it and insert new one */ + util_ald_cache_remove(curl->search_cache, search_nodep); + util_ald_cache_insert(curl->search_cache, &the_search_node); + } + else { + /* Cache entry is valid, update lastbind */ + search_nodep->lastbind = the_search_node.lastbind; + } } ldap_cache_unlock(st, r); } @@ -2046,10 +2046,8 @@ static int uldap_cache_getuserdn(request_rec *r, util_ldap_connection_t *ldc, if (curl == NULL) { curl = util_ald_create_caches(st, url); } - ldap_cache_unlock(st, r); if (curl) { - ldap_cache_lock(st, r); the_search_node.username = filter; search_nodep = util_ald_cache_fetch(curl->search_cache, &the_search_node); @@ -2080,9 +2078,9 @@ static int uldap_cache_getuserdn(request_rec *r, util_ldap_connection_t *ldc, return LDAP_SUCCESS; } } - /* unlock this read lock */ - ldap_cache_unlock(st, r); } + /* unlock this read lock */ + ldap_cache_unlock(st, r); /* * At this point, there is no valid cached search, so lets do the search. @@ -2178,35 +2176,38 @@ static int uldap_cache_getuserdn(request_rec *r, util_ldap_connection_t *ldc, /* * Add the new username to the search cache. */ - if (curl) { + { ldap_cache_lock(st, r); - the_search_node.username = filter; - the_search_node.dn = *binddn; - the_search_node.bindpw = NULL; - the_search_node.lastbind = apr_time_now(); - the_search_node.vals = vals; - the_search_node.numvals = numvals; - - /* Search again to make sure that another thread didn't ready insert - * this node into the cache before we got here. If it does exist then - * update the lastbind - */ - search_nodep = util_ald_cache_fetch(curl->search_cache, - &the_search_node); - if ((search_nodep == NULL) || - (strcmp(*binddn, search_nodep->dn) != 0)) { + curl = util_ald_cache_fetch(st->util_ldap_cache, &curnode); + if (curl) { + the_search_node.username = filter; + the_search_node.dn = *binddn; + the_search_node.bindpw = NULL; + the_search_node.lastbind = apr_time_now(); + the_search_node.vals = vals; + the_search_node.numvals = numvals; + + /* Search again to make sure that another thread didn't ready insert + * this node into the cache before we got here. If it does exist then + * update the lastbind + */ + search_nodep = util_ald_cache_fetch(curl->search_cache, + &the_search_node); + if ((search_nodep == NULL) || + (strcmp(*binddn, search_nodep->dn) != 0)) { - /* Nothing in cache, insert new entry */ - util_ald_cache_insert(curl->search_cache, &the_search_node); - } - /* - * Don't update lastbind on entries with bindpw because - * we haven't verified that password. It's OK to update - * the entry if there is no password in it. - */ - else if (!search_nodep->bindpw) { - /* Cache entry is valid, update lastbind */ - search_nodep->lastbind = the_search_node.lastbind; + /* Nothing in cache, insert new entry */ + util_ald_cache_insert(curl->search_cache, &the_search_node); + } + /* + * Don't update lastbind on entries with bindpw because + * we haven't verified that password. It's OK to update + * the entry if there is no password in it. + */ + else if (!search_nodep->bindpw) { + /* Cache entry is valid, update lastbind */ + search_nodep->lastbind = the_search_node.lastbind; + } } ldap_cache_unlock(st, r); } diff --git a/modules/metadata/mod_cern_meta.c b/modules/metadata/mod_cern_meta.c index 3f36b2dba8a..a150b3c9fa1 100644 --- a/modules/metadata/mod_cern_meta.c +++ b/modules/metadata/mod_cern_meta.c @@ -256,6 +256,18 @@ static int scan_meta_file(request_rec *r, apr_file_t *f) sscanf(l, "%d", &r->status); r->status_line = apr_pstrdup(r->pool, l); } + else if (!ap_cstr_casecmp(w, "Transfer-Encoding") + || !ap_cstr_casecmp(w, "Content-Length") + || !ap_cstr_casecmp(w, "Connection") + || !ap_cstr_casecmp(w, "Trailer") + || !ap_cstr_casecmp(w, "Upgrade") + || !ap_cstr_casecmp(w, "Keep-Alive") + || !ap_cstr_casecmp(w, "TE")) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10596) + "forbidden HTTP framing header '%s' in meta file: %s", + w, r->filename); + return HTTP_INTERNAL_SERVER_ERROR; + } else { apr_table_set(tmp_headers, w, l); } diff --git a/modules/metadata/mod_remoteip.c b/modules/metadata/mod_remoteip.c index 27a42d3cd37..eaa2d7c7926 100644 --- a/modules/metadata/mod_remoteip.c +++ b/modules/metadata/mod_remoteip.c @@ -950,6 +950,8 @@ static remoteip_parse_status_t remoteip_process_v2_header(conn_rec *c, switch (hdr->v2.ver_cmd & 0xF) { case 0x00: /* LOCAL command */ /* keep local connection address for LOCAL */ + conn_conf->client_addr = c->client_addr; + conn_conf->client_ip = c->client_ip; return HDR_DONE; case 0x01: /* PROXY command */ switch (hdr->v2.fam) { diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c index 9ee25ec52ca..3e96f9efdac 100644 --- a/modules/ssl/ssl_engine_kernel.c +++ b/modules/ssl/ssl_engine_kernel.c @@ -2238,7 +2238,7 @@ static apr_status_t set_challenge_creds(conn_rec *c, const char *servername, cleanup: if (our_data && cert) X509_free(cert); if (our_data && key) EVP_PKEY_free(key); - return APR_SUCCESS; + return rv; } /* diff --git a/modules/ssl/ssl_engine_ocsp.c b/modules/ssl/ssl_engine_ocsp.c index 539ed103eae..6a03fb41744 100644 --- a/modules/ssl/ssl_engine_ocsp.c +++ b/modules/ssl/ssl_engine_ocsp.c @@ -80,7 +80,7 @@ static apr_uri_t *determine_responder_uri(SSLSrvConfigRec *sc, X509 *cert, } rv = apr_uri_parse(p, s, u); - if (rv || !u->hostname) { + if (rv || !u->hostname || !u->scheme) { ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c, APLOGNO(01919) "failed to parse OCSP responder URI '%s'", s); return NULL;