Mercurial > dovecot > original-hg > dovecot-2.2
changeset 16761:ec9eab188dd8
lib-http: Added (non-default) support for parsing user:pasword from HTTP URL.
author | Stephan Bosch <stephan@rename-it.nl> |
---|---|
date | Tue, 17 Sep 2013 21:57:48 +0300 |
parents | 6be5d8d8af2d |
children | 393c389b1540 |
files | src/lib-http/http-url.c src/lib-http/http-url.h src/lib-http/test-http-url.c |
diffstat | 3 files changed, 71 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-http/http-url.c Tue Sep 17 21:57:14 2013 +0300 +++ b/src/lib-http/http-url.c Tue Sep 17 21:57:48 2013 +0300 @@ -32,25 +32,41 @@ struct uri_parser *parser = &url_parser->parser; struct http_url *url = url_parser->url; struct uri_authority auth; + const char *user = NULL, *password = NULL; int ret; if ((ret = uri_parse_authority(parser, &auth)) < 0) return FALSE; if (ret > 0) { if (auth.enc_userinfo != NULL) { - /* http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-20 + const char *p; - Section 2.8.1: + if ((url_parser->flags & HTTP_URL_ALLOW_USERINFO_PART) == 0) { + /* http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-20 + + Section 2.8.1: - {...} Senders MUST NOT include a userinfo subcomponent (and its "@" - delimiter) when transmitting an "http" URI in a message. Recipients - of HTTP messages that contain a URI reference SHOULD parse for the - existence of userinfo and treat its presence as an error, likely - indicating that the deprecated subcomponent is being used to - obscure the authority for the sake of phishing attacks. - */ - parser->error = "HTTP URL does not allow `userinfo@' part"; - return FALSE; + {...} Senders MUST NOT include a userinfo subcomponent (and its "@" + delimiter) when transmitting an "http" URI in a message. Recipients + of HTTP messages that contain a URI reference SHOULD parse for the + existence of userinfo and treat its presence as an error, likely + indicating that the deprecated subcomponent is being used to + obscure the authority for the sake of phishing attacks. + */ + parser->error = "HTTP URL does not allow `userinfo@' part"; + return FALSE; + } + + p = strchr(auth.enc_userinfo, ':'); + if (p == NULL) { + if (!uri_data_decode(parser, auth.enc_userinfo, NULL, &user)) + return FALSE; + } else { + if (!uri_data_decode(parser, auth.enc_userinfo, p, &user)) + return FALSE; + if (!uri_data_decode(parser, p+1, NULL, &password)) + return FALSE; + } } } if (url != NULL) { @@ -59,6 +75,8 @@ url->have_host_ip = auth.have_host_ip; url->port = auth.port; url->have_port = auth.have_port; + url->user = p_strdup(parser->pool, user); + url->password = p_strdup(parser->pool, password); } return TRUE; } @@ -210,12 +228,14 @@ parser->error = "Relative HTTP URL not allowed"; return FALSE; } else if (!have_authority && url != NULL) { - url->host_name = p_strdup(parser->pool, base->host_name); + url->host_name = p_strdup_empty(parser->pool, base->host_name); url->host_ip = base->host_ip; url->have_host_ip = base->have_host_ip; url->port = base->port; url->have_port = base->have_port; url->have_ssl = base->have_ssl; + url->user = p_strdup_empty(parser->pool, base->user); + url->password = p_strdup_empty(parser->pool, base->password); } url_parser->relative = TRUE;
--- a/src/lib-http/http-url.h Tue Sep 17 21:57:14 2013 +0300 +++ b/src/lib-http/http-url.h Tue Sep 17 21:57:48 2013 +0300 @@ -11,6 +11,10 @@ struct ip_addr host_ip; in_port_t port; + /* userinfo (not parsed by default) */ + const char *user; + const char *password; + /* path */ const char *path; @@ -33,8 +37,10 @@ /* Scheme part 'http:' is already parsed externally. This implies that this is an absolute HTTP URL. */ HTTP_URL_PARSE_SCHEME_EXTERNAL = 0x01, - /* Allow '#fragment' part in URL */ - HTTP_URL_ALLOW_FRAGMENT_PART = 0x02 + /* Allow '#fragment' part in HTTP URL */ + HTTP_URL_ALLOW_FRAGMENT_PART = 0x02, + /* Allow 'user:password@' part in HTTP URL */ + HTTP_URL_ALLOW_USERINFO_PART = 0x04 }; int http_url_parse(const char *url, struct http_url *base,
--- a/src/lib-http/test-http-url.c Tue Sep 17 21:57:14 2013 +0300 +++ b/src/lib-http/test-http-url.c Tue Sep 17 21:57:48 2013 +0300 @@ -48,6 +48,23 @@ .port = 8080, .have_port = TRUE } #endif },{ + .url = "http://user@api.dovecot.org", + .flags = HTTP_URL_ALLOW_USERINFO_PART, + .url_parsed = { + .host_name = "api.dovecot.org", .user = "user" } + },{ + .url = "http://userid:secret@api.dovecot.org", + .flags = HTTP_URL_ALLOW_USERINFO_PART, + .url_parsed = { + .host_name = "api.dovecot.org", + .user = "userid", .password = "secret" } + },{ + .url = "http://su%3auserid:secret@api.dovecot.org", + .flags = HTTP_URL_ALLOW_USERINFO_PART, + .url_parsed = { + .host_name = "api.dovecot.org", + .user = "su:userid", .password = "secret" } + },{ .url = "http://www.example.com/" "?question=What%20are%20you%20doing%3f&answer=Nothing.", .url_parsed = { @@ -296,6 +313,20 @@ test_out("url->host_ip = (valid)", urlp->have_host_ip == urlt->have_host_ip); } + if (urlp->user == NULL || urlt->user == NULL) { + test_out(t_strdup_printf("url->user = %s", urlp->user), + urlp->user == urlt->user); + } else { + test_out(t_strdup_printf("url->user = %s", urlp->user), + strcmp(urlp->user, urlt->user) == 0); + } + if (urlp->password == NULL || urlt->password == NULL) { + test_out(t_strdup_printf("url->password = %s", urlp->password), + urlp->password == urlt->password); + } else { + test_out(t_strdup_printf("url->password = %s", urlp->password), + strcmp(urlp->password, urlt->password) == 0); + } if (urlp->path == NULL || urlt->path == NULL) { test_out(t_strdup_printf("url->path = %s", urlp->path), urlp->path == urlt->path);