Hello community,

here is the log from the commit of package lynx for openSUSE:Factory checked in 
at 2017-02-11 01:31:30
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/lynx (Old)
 and      /work/SRC/openSUSE:Factory/.lynx.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "lynx"

Changes:
--------
--- /work/SRC/openSUSE:Factory/lynx/lynx.changes        2014-12-03 
22:52:17.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.lynx.new/lynx.changes   2017-02-11 
01:31:31.830741195 +0100
@@ -1,0 +2,7 @@
+Mon Feb  6 16:27:18 UTC 2017 - [email protected]
+
+- security update:
+  * CVE-2016-9179 [bsc#1008642]
+    + lynx-CVE-2016-9179.patch
+
+-------------------------------------------------------------------

New:
----
  lynx-CVE-2016-9179.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ lynx.spec ++++++
--- /var/tmp/diff_new_pack.3htS23/_old  2017-02-11 01:31:33.266538556 +0100
+++ /var/tmp/diff_new_pack.3htS23/_new  2017-02-11 01:31:33.270537991 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package lynx
 #
-# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -38,6 +38,7 @@
 Patch102:       lynx-2.8.7-enable_xli.patch
 Patch103:       lynx-no-build-date.patch
 Patch104:       lynx-2.8.8-expired-cookie-crash.patch
+Patch105:       lynx-CVE-2016-9179.patch
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 Provides:       lynxssl = %version
 Obsoletes:      lynxssl < %version
@@ -56,6 +57,7 @@
 %patch102 -p1
 %patch103
 %patch104
+%patch105 -p1
 # containing a few test msg's only:
 # rm -f po/{es,fr,it,ko,no,pl,pt}.po
 

++++++ lynx-CVE-2016-9179.patch ++++++
Index: lynx2-8-8/WWW/Library/Implementation/HTTP.c
===================================================================
--- lynx2-8-8.orig/WWW/Library/Implementation/HTTP.c    2017-02-06 
18:52:54.585749847 +0100
+++ lynx2-8-8/WWW/Library/Implementation/HTTP.c 2017-02-06 19:17:22.161941448 
+0100
@@ -417,27 +417,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)
 {
     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);
+        /*
+         * Trailing "gen-delims" demonstrates that there is no user/password.
+         */
+        while ((p3 != host) && RFC_3986_GEN_DELIMS(p3[-1])) {
+            ++gen_delims;
+            *(--p3) = '\0';
        }
-       while ((*p1++ = *p2++) != '\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)
+            HTAlert(msg);
+        if (do_trimming) {
+            while ((*p1++ = *p2++) != '\0') {
+                ;
+            }
+
        }
+        FREE(fake);
+        FREE(save);
+        FREE(auth);
+        FREE(msg);
     }
 }
 
Index: lynx2-8-8/WWW/Library/Implementation/HTTCP.c
===================================================================
--- lynx2-8-8.orig/WWW/Library/Implementation/HTTCP.c   2013-12-18 
02:56:13.000000000 +0100
+++ lynx2-8-8/WWW/Library/Implementation/HTTCP.c        2017-02-06 
19:21:15.081092383 +0100
@@ -1792,7 +1792,6 @@ int HTDoConnect(const char *url,
     int status = 0;
     char *line = NULL;
     char *p1 = NULL;
-    char *at_sign = NULL;
     char *host = NULL;
 
 #ifdef INET6
@@ -1814,14 +1813,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-8/WWW/Library/Implementation/HTTP.c
===================================================================
--- lynx2-8-8.orig/WWW/Library/Implementation/HTTP.c    2017-02-06 
19:19:32.719706928 +0100
+++ lynx2-8-8/WWW/Library/Implementation/HTTP.c 2017-02-06 19:23:34.346979724 
+0100
@@ -500,7 +500,7 @@ static char *fake_hostname(char *auth)
 /*
  * 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 = skip_user_passwd(host);
@@ -550,7 +550,7 @@ static void strip_userid(char *host)
                        gettext("User/password may be confused with hostname: 
'%s' (e.g, '%s')"),
                        auth, fake);
         }
-        if (msg != 0)
+        if (msg != 0 && !parse_only)
             HTAlert(msg);
         if (do_trimming) {
             while ((*p1++ = *p2++) != '\0') {
@@ -1198,7 +1198,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-8/WWW/Library/Implementation/HTUtils.h
===================================================================
--- lynx2-8-8.orig/WWW/Library/Implementation/HTUtils.h 2014-02-05 
01:50:18.000000000 +0100
+++ lynx2-8-8/WWW/Library/Implementation/HTUtils.h      2017-02-06 
19:19:32.727707036 +0100
@@ -801,6 +801,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-8/src/LYUtils.c
===================================================================
--- lynx2-8-8.orig/src/LYUtils.c        2014-03-09 22:43:10.000000000 +0100
+++ lynx2-8-8/src/LYUtils.c     2017-02-06 19:19:32.727707036 +0100
@@ -4693,6 +4693,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);

Reply via email to