summaryrefslogtreecommitdiffstats
path: root/crypto/http
diff options
context:
space:
mode:
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>2021-02-17 17:24:19 +0100
committerDr. David von Oheimb <dev@ddvo.net>2021-03-01 10:30:43 +0100
commitd546e8e267bfddc1ca310dfa8b9a72ab4f9aac7c (patch)
tree1688ff89cb61a15fee808af244d528e68ce45c4a /crypto/http
parentOSSL_HTTP_parse_url(): Handle any userinfo, query, and fragment components (diff)
downloadopenssl-d546e8e267bfddc1ca310dfa8b9a72ab4f9aac7c.tar.xz
openssl-d546e8e267bfddc1ca310dfa8b9a72ab4f9aac7c.zip
Generalize schmeme parsing of OSSL_HTTP_parse_url() to OSSL_parse_url()
Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/14009)
Diffstat (limited to 'crypto/http')
-rw-r--r--crypto/http/http_err.c4
-rw-r--r--crypto/http/http_lib.c93
2 files changed, 77 insertions, 20 deletions
diff --git a/crypto/http/http_err.c b/crypto/http/http_err.c
index 20235ba0f8..2bb6d97290 100644
--- a/crypto/http/http_err.c
+++ b/crypto/http/http_err.c
@@ -32,8 +32,8 @@ static const ERR_STRING_DATA HTTP_str_reasons[] = {
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INVALID_PORT_NUMBER),
"invalid port number"},
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INVALID_URL_PATH), "invalid url path"},
- {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INVALID_URL_PREFIX),
- "invalid url prefix"},
+ {ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INVALID_URL_SCHEME),
+ "invalid url scheme"},
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MAX_RESP_LEN_EXCEEDED),
"max resp len exceeded"},
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MISSING_ASN1_ENCODING),
diff --git a/crypto/http/http_lib.c b/crypto/http/http_lib.c
index 3c894d8629..6b8c15471e 100644
--- a/crypto/http/http_lib.c
+++ b/crypto/http/http_lib.c
@@ -36,21 +36,21 @@ static void free_pstring(char **pstr)
}
}
-int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost,
- char **pport, int *pport_num,
- char **ppath, char **pquery, char **pfrag)
+int OSSL_parse_url(const char *url, char **pscheme, char **puser, char **phost,
+ char **pport, int *pport_num,
+ char **ppath, char **pquery, char **pfrag)
{
const char *p, *tmp;
+ const char *scheme, *scheme_end;
const char *user, *user_end;
const char *host, *host_end;
- const char *port = OSSL_HTTP_PORT, *port_end;
+ const char *port, *port_end;
unsigned int portnum;
const char *path, *path_end;
const char *query, *query_end;
const char *frag, *frag_end;
- if (pssl != NULL)
- *pssl = 0;
+ init_pstring(pscheme);
init_pstring(puser);
init_pstring(phost);
init_pstring(pport);
@@ -63,19 +63,15 @@ int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost,
return 0;
}
- /* check for optional prefix "http[s]://" */
+ /* check for optional prefix "<scheme>://" */
+ scheme = scheme_end = url;
p = strstr(url, "://");
if (p == NULL) {
p = url;
- } else { /* p points to end of scheme name */
- if (strncmp(url, OSSL_HTTPS_NAME, strlen(OSSL_HTTPS_NAME)) == 0) {
- if (pssl != NULL)
- *pssl = 1;
- port = OSSL_HTTPS_PORT;
- } else if (strncmp(url, OSSL_HTTP_NAME, strlen(OSSL_HTTP_NAME)) != 0) {
- ERR_raise(ERR_LIB_HTTP, HTTP_R_INVALID_URL_PREFIX);
- goto err;
- }
+ } else {
+ scheme_end = p;
+ if (scheme_end == scheme)
+ goto parse_err;
p += strlen("://");
}
@@ -110,11 +106,12 @@ int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost,
}
/* parse optional port specification starting with ':' */
+ port = "0"; /* default */
if (*p == ':')
port = ++p;
/* remaining port spec handling is also done for the default values */
/* make sure a decimal port number is given */
- if (!sscanf(port, "%u", &portnum) || portnum < 1 || portnum > 65535) {
+ if (!sscanf(port, "%u", &portnum) || portnum > 65535) {
ERR_raise(ERR_LIB_HTTP, HTTP_R_INVALID_PORT_NUMBER);
goto err;
}
@@ -150,7 +147,8 @@ int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost,
frag = tmp + 1;
}
- if (!copy_substring(phost, host, host_end)
+ if (!copy_substring(pscheme, scheme, scheme_end)
+ || !copy_substring(phost, host, host_end)
|| !copy_substring(pport, port, port_end)
|| !copy_substring(puser, user, user_end)
|| !copy_substring(pquery, query, query_end)
@@ -174,6 +172,8 @@ int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost,
ERR_raise(ERR_LIB_HTTP, HTTP_R_ERROR_PARSING_URL);
err:
+ free_pstring(pscheme);
+ free_pstring(puser);
free_pstring(phost);
free_pstring(pport);
free_pstring(ppath);
@@ -182,6 +182,63 @@ int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost,
return 0;
}
+int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost,
+ char **pport, int *pport_num,
+ char **ppath, char **pquery, char **pfrag)
+{
+ char *scheme, *port;
+ int ssl = 0, portnum;
+
+ init_pstring(pport);
+ if (pssl != NULL)
+ *pssl = 0;
+ if (!OSSL_parse_url(url, &scheme, puser, phost, &port, pport_num,
+ ppath, pquery, pfrag))
+ return 0;
+
+ /* check for optional HTTP scheme "http[s]" */
+ if (strcmp(scheme, OSSL_HTTPS_NAME) == 0) {
+ ssl = 1;
+ if (pssl != NULL)
+ *pssl = ssl;
+ } else if (*scheme != '\0' && strcmp(scheme, OSSL_HTTP_NAME) != 0) {
+ ERR_raise(ERR_LIB_HTTP, HTTP_R_INVALID_URL_SCHEME);
+ OPENSSL_free(scheme);
+ OPENSSL_free(port);
+ goto err;
+ }
+ OPENSSL_free(scheme);
+
+ if (strcmp(port, "0") == 0) {
+ /* set default port */
+ OPENSSL_free(port);
+ port = ssl ? OSSL_HTTPS_PORT : OSSL_HTTP_PORT;
+ if (!ossl_assert(sscanf(port, "%d", &portnum) == 1))
+ goto err;
+ if (pport_num != NULL)
+ *pport_num = portnum;
+ if (pport != NULL) {
+ *pport = OPENSSL_strdup(port);
+ if (*pport == NULL)
+ goto err;
+ }
+ } else {
+ if (pport != NULL)
+ *pport = port;
+ else
+ OPENSSL_free(port);
+ }
+ return 1;
+
+ err:
+ free_pstring(puser);
+ free_pstring(phost);
+ free_pstring(ppath);
+ free_pstring(pquery);
+ free_pstring(pfrag);
+ return 0;
+}
+
int http_use_proxy(const char *no_proxy, const char *server)
{
size_t sl;