Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:42.3
lynx
lynx-CVE-2016-9179.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File lynx-CVE-2016-9179.patch of Package lynx
Index: lynx2-8-7/WWW/Library/Implementation/HTTP.c =================================================================== --- lynx2-8-7.orig/WWW/Library/Implementation/HTTP.c 2017-02-06 19:55:12.392985155 +0100 +++ lynx2-8-7/WWW/Library/Implementation/HTTP.c 2017-02-06 20:11:43.034365672 +0100 @@ -379,27 +379,151 @@ int ws_netread(int fd, char *buf, int le #endif /* _WINDOWS */ /* + * RFC-1738 says we can have user/password using these ASCII characters + * safe = "$" | "-" | "_" | "." | "+" + * extra = "!" | "*" | "'" | "(" | ")" | "," + * hex = digit | "A" | "B" | "C" | "D" | "E" | "F" | + * "a" | "b" | "c" | "d" | "e" | "f" + * escape = "%" hex hex + * unreserved = alpha | digit | safe | extra + * uchar = unreserved | escape + * user = *[ uchar | ";" | "?" | "&" | "=" ] + * password = *[ uchar | ";" | "?" | "&" | "=" ] + * and we cannot have a password without user, i.e., no leading ":" + * and ":", "@", "/" must be encoded, i.e., will not appear as such. + * + * However, in a URL + * //<user>:<password>@<host>:<port>/<url-path> + * valid characters in the host are different, not allowing most of those + * punctuation characters. + * + * RFC-3986 amends this, using + * userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) + * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" + * reserved = gen-delims / sub-delims + * gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" + * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" + * / "*" / "+" / "," / ";" / "=" + * and + * host = IP-literal / IPv4address / reg-name + * reg-name = *( unreserved / pct-encoded / sub-delims ) + */ +#define RFC_3986_UNRESERVED(c) (isalnum(UCH(c)) || strchr("-._~", UCH(c)) != 0) +#define RFC_3986_GEN_DELIMS(c) ((c) != 0 && strchr(":/?#[]@", UCH(c)) != 0) +#define RFC_3986_SUB_DELIMS(c) ((c) != 0 && strchr("!$&'()*+,;=", UCH(c)) != 0) + +static char *skip_user_passwd(char *host) +{ + char *result = 0; + char *s = host; + int pass = 0; + int ch; + int last = -1; + + while ((ch = UCH(*s)) != '\0') { + if (ch == '\0') { + break; + } else if (ch == ':') { + if (pass++) + break; + } else if (ch == '@') { + if (s != host && last != ':') + result = s; + break; + } else if (RFC_3986_GEN_DELIMS(ch)) { + if (!RFC_3986_GEN_DELIMS(s[1])) + break; + } else if (ch == '%') { + if (!(isxdigit(UCH(s[1])) && isxdigit(UCH(s[2])))) + break; + } else if (!(RFC_3986_UNRESERVED(ch) || + RFC_3986_SUB_DELIMS(ch))) { + break; + } + ++s; + last = ch; + } + return result; +} + +static char *fake_hostname(char *auth) +{ + char *result = NULL; + char *colon = NULL; + + StrAllocCopy(result, auth); + if ((colon = strchr(result, ':')) != 0) + *colon = '\0'; + if (strchr(result, '.') == 0) + FREE(result); + return result; +} + +/* * Strip any username from the given string so we retain only the host. */ -static void strip_userid(char *host) +void strip_userid(char *host, int parse_only) { char *p1 = host; - char *p2 = strchr(host, '@'); - char *fake; + char *p2 = skip_user_passwd(host); if (p2 != 0) { + char *msg = NULL; + char *auth = NULL; + char *save = NULL; + char *fake = NULL; + char *p3 = p2; + int gen_delims = 0; + int sub_delims = 0; + int my_delimit = UCH(*p2); + int do_trimming = (my_delimit == '@'); + *p2++ = '\0'; - if ((fake = HTParse(host, "", PARSE_HOST)) != NULL) { - char *msg = NULL; + StrAllocCopy(auth, host); - CTRACE((tfp, "parsed:%s\n", fake)); - HTSprintf0(&msg, gettext("Address contains a username: %s"), host); - HTAlert(msg); - FREE(msg); - } - while ((*p1++ = *p2++) != '\0') { - ; - } + /* + * Trailing "gen-delims" demonstrates that there is no user/password. + */ + while ((p3 != host) && RFC_3986_GEN_DELIMS(p3[-1])) { + ++gen_delims; + *(--p3) = '\0'; + } + /* + * While legal, punctuation-only user/password is questionable. + */ + while ((p3 != host) && RFC_3986_SUB_DELIMS(p3[-1])) { + ++sub_delims; + *(--p3) = '\0'; + } + CTRACE((tfp, "trimmed:%s\n", host)); + StrAllocCopy(save, host); + + if (gen_delims || strcmp(save, auth)) { + HTSprintf0(&msg, + gettext("User/password may appear to be a hostname: '%s' (e.g, '%s')"), + auth, save); + do_trimming = !gen_delims; + } else if (*host == '\0' && sub_delims) { + HTSprintf0(&msg, + gettext("User/password contains only punctuation: %s"), + auth); + } else if ((fake = fake_hostname(host)) != NULL) { + HTSprintf0(&msg, + gettext("User/password may be confused with hostname: '%s' (e.g, '%s')"), + auth, fake); + } + if (msg != 0 && !parse_only) + HTAlert(msg); + if (do_trimming) { + while ((*p1++ = *p2++) != '\0') { + ; + } + + } + FREE(fake); + FREE(save); + FREE(auth); + FREE(msg); } } @@ -1021,7 +1145,7 @@ static int HTLoadHTTP(const char *arg, char *host = NULL; if ((host = HTParse(anAnchor->address, "", PARSE_HOST)) != NULL) { - strip_userid(host); + strip_userid(host, TRUE); HTBprintf(&command, "Host: %s%c%c", host, CR, LF); FREE(host); } Index: lynx2-8-7/WWW/Library/Implementation/HTTCP.c =================================================================== --- lynx2-8-7.orig/WWW/Library/Implementation/HTTCP.c 2008-12-15 01:24:56.000000000 +0100 +++ lynx2-8-7/WWW/Library/Implementation/HTTCP.c 2017-02-06 19:57:44.899041404 +0100 @@ -1577,7 +1577,6 @@ int HTDoConnect(const char *url, int status = 0; char *line = NULL; char *p1 = NULL; - char *at_sign = NULL; char *host = NULL; #ifdef INET6 @@ -1599,14 +1598,8 @@ int HTDoConnect(const char *url, * Get node name and optional port number. */ p1 = HTParse(url, "", PARSE_HOST); - if ((at_sign = strchr(p1, '@')) != NULL) { - /* - * If there's an @ then use the stuff after it as a hostname. - */ - StrAllocCopy(host, (at_sign + 1)); - } else { - StrAllocCopy(host, p1); - } + StrAllocCopy(host, p1); + strip_userid(host, FALSE); FREE(p1); HTSprintf0(&line, "%s%s", WWW_FIND_MESSAGE, host); Index: lynx2-8-7/WWW/Library/Implementation/HTUtils.h =================================================================== --- lynx2-8-7.orig/WWW/Library/Implementation/HTUtils.h 2009-05-25 23:05:31.000000000 +0200 +++ lynx2-8-7/WWW/Library/Implementation/HTUtils.h 2017-02-06 19:55:12.404985318 +0100 @@ -747,6 +747,8 @@ extern "C" { extern FILE *TraceFP(void); + extern void strip_userid(char *host, int warn); + #ifdef USE_SSL extern SSL *HTGetSSLHandle(void); extern void HTSSLInitPRNG(void); Index: lynx2-8-7/src/LYUtils.c =================================================================== --- lynx2-8-7.orig/src/LYUtils.c 2009-05-26 02:10:12.000000000 +0200 +++ lynx2-8-7/src/LYUtils.c 2017-02-06 19:55:12.404985318 +0100 @@ -4604,6 +4604,7 @@ BOOLEAN LYExpandHostForURL(char **Alloca * Do a DNS test on the potential host field as presently trimmed. - FM */ StrAllocCopy(host, Str); + strip_userid(host, FALSE); HTUnEscape(host); if (LYCursesON) { StrAllocCopy(MsgStr, WWW_FIND_MESSAGE);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor