how-lix-os-pkgs/lynx/2.8.9rel.1/patch

312 lines
9.9 KiB
Plaintext

patch retrieved from
https://lists.gnu.org/archive/html/lynx-dev/2019-09/txtdZJkhuP5_U.txt
context:
https://lists.gnu.org/archive/html/lynx-dev/2019-09/msg00030.html
summary: adds socks5 support to lynx through a "-socks5-proxy" flag.
this change has been upstreamed, but a stable release containing this change is
not yet available. without this, lynx cannot be used with tor under lix os.
(torsocks hooks into the dynamic library loading mechanism, which is not used at
all by statically-linked binaries.)
diff --git a/WWW/Library/Implementation/HTTCP.c b/WWW/Library/Implementation/HTTCP.c
index 4669efd4..75f3a161 100644
--- a/WWW/Library/Implementation/HTTCP.c
+++ b/WWW/Library/Implementation/HTTCP.c
@@ -1825,6 +1825,10 @@ int HTDoConnect(const char *url,
int default_port,
int *s)
{
+ /* On error goto jout */
+ char *socks5_host;
+ int socks5_host_len, socks5_port;
+ const char *socks5_orig_url;
int status = 0;
char *line = NULL;
char *p1 = NULL;
@@ -1836,7 +1840,45 @@ int HTDoConnect(const char *url,
#else
struct sockaddr_in sock_A;
struct sockaddr_in *soc_in = &sock_A;
+#endif
+
+ /* In case of a present SOCKS5 proxy, marshal */
+ if((socks5_orig_url = socks5_proxy) != NULL){
+ size_t i;
+ int xport;
+
+ xport = default_port;
+ socks5_orig_url = url;
+
+ /* Get node name and optional port number of wanted URL */
+ p1 = HTParse(url, "", PARSE_HOST);
+ socks5_host = NULL;
+ StrAllocCopy(socks5_host, p1);
+ strip_userid(socks5_host, FALSE);
+ FREE(p1);
+
+ if((i = strlen(socks5_host)) > 255){
+ HTAlert(gettext("SOCKS5: hostname too long."));
+ goto jout;
+ }
+ socks5_host_len = (int)i;
+
+ if(HTParsePort((char*)url, &socks5_port) == NULL)
+ socks5_port = xport;
+
+ /* And switch over to our SOCKS5 config; in order to embed that into
+ * lynx environment, prepend protocol prefix */
+ default_port = 1080; /* RFC 1928 */
+ HTSACat(&p1, "socks://");
+ HTSACat(&p1, socks5_proxy);
+ url = p1;
+ p1 = NULL;
+
+ protocol = HTSprintf0(NULL, gettext("(for %s at %s) SOCKS5"),
+ protocol, socks5_host);
+ }
+#ifndef INET6
/*
* Set up defaults.
*/
@@ -1859,11 +1901,10 @@ int HTDoConnect(const char *url,
/* HTParseInet() is useless! */
res0 = HTGetAddrInfo(host, default_port);
if (res0 == NULL) {
- HTSprintf0(&line, gettext("Unable to locate remote host %s."), host);
- _HTProgress(line);
- FREE(host);
- FREE(line);
- return HT_NO_DATA;
+ HTSprintf0(&line, gettext("Unable to locate remote host %s."), host);
+ _HTProgress(line);
+ status = HT_NO_DATA;
+ goto jout;
}
#else
status = HTParseInet(soc_in, host);
@@ -1882,16 +1923,12 @@ int HTDoConnect(const char *url,
}
status = HT_NO_DATA;
}
- FREE(host);
- FREE(line);
- return status;
+ goto jout;
}
#endif /* INET6 */
HTSprintf0(&line, gettext("Making %s connection to %s"), protocol, host);
_HTProgress(line);
- FREE(host);
- FREE(line);
/*
* Now, let's get a socket set up from the server for the data.
@@ -1900,7 +1937,8 @@ int HTDoConnect(const char *url,
*s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (*s == -1) {
HTAlert(gettext("socket failed."));
- return HT_NO_DATA;
+ status = HT_NO_DATA;
+ goto jout;
}
#else
for (res = res0; res; res = res->ai_next) {
@@ -1916,7 +1954,6 @@ int HTDoConnect(const char *url,
gettext("socket failed: family %d addr %s port %s."),
res->ai_family, hostbuf, portbuf);
_HTProgress(line);
- FREE(line);
continue;
}
#endif /* INET6 */
@@ -2005,13 +2042,13 @@ int HTDoConnect(const char *url,
if ((tries++ / TRIES_PER_SECOND) >= connect_timeout) {
HTAlert(gettext("Connection failed (too many retries)."));
#ifdef INET6
- FREE(line);
#ifndef NSL_FORK
if (res0)
freeaddrinfo(res0);
#endif
#endif /* INET6 */
- return HT_NO_DATA;
+ status = HT_NO_DATA;
+ goto jout;
}
set_timeout(&select_timeout);
FD_ZERO(&writefds);
@@ -2204,7 +2241,6 @@ int HTDoConnect(const char *url,
#endif /* !DOSPATH || __DJGPP__ */
#ifdef INET6
- FREE(line);
#ifdef NSL_FORK
FREE_NSL_FORK(res0);
#else
@@ -2212,6 +2248,109 @@ int HTDoConnect(const char *url,
freeaddrinfo(res0);
#endif
#endif /* INET6 */
+
+ /* Now if this was a SOCKS5 proxy connection, go for the real one */
+ if(status >= 0 && socks5_orig_url != NULL){
+ unsigned char pbuf[4 + 1 + 255 + 2];
+ size_t i;
+ char const *emsg;
+
+ /* RFC 1928: version identifier/method selection message */
+ pbuf[0] = 0x05; /* VER: protocol version: X'05' */
+ pbuf[1] = 0x01; /* NMETHODS: 1 */
+ pbuf[2] = 0x00; /* METHOD: X'00' NO AUTHENTICATION REQUIRED */
+ if(write(*s, pbuf, 3) != 3){
+jerrsocks:
+ HTAlert(LYStrerror(errno));
+jesocks:
+ NETCLOSE(*s);
+ status = HT_NO_CONNECTION;
+ goto jout;
+ }
+
+ /* Receive greeting */
+ if(HTDoRead(*s, pbuf, 2) != 2)
+ goto jerrsocks;
+ if(pbuf[0] != 0x05 || pbuf[1] != 0x00){
+jesocksreply:
+ emsg = N_("unexpected reply\n");
+jesocksreplymsg:
+ HTAlert(gettext(emsg));
+ goto jesocks;
+ }
+
+ /* RFC 1928: CONNECT request */
+ HTSprintf0(&line, gettext("SOCKS5: connecting to %s"), socks5_host);
+ _HTProgress(line);
+ pbuf[0] = 0x05; /* VER: protocol version: X'05' */
+ pbuf[1] = 0x01; /* CMD: CONNECT X'01' */
+ pbuf[2] = 0x00; /* RESERVED */
+ pbuf[3] = 0x03; /* ATYP: domain name */
+ pbuf[4] = (unsigned char)socks5_host_len;
+ memcpy(&pbuf[i = 5], socks5_host, socks5_host_len);
+ i += socks5_host_len;
+ /* C99 */{
+ unsigned short x; /* XXX 16-bit? */
+
+ x = htons(socks5_port);
+ memcpy(&pbuf[i], (unsigned char*)&x, sizeof x);
+ i += sizeof x;
+ }
+ if((size_t)write(*s, pbuf, i) != i)
+ goto jerrsocks;
+
+ /* Connect result */
+ if((i = HTDoRead(*s, pbuf, 4)) != 4)
+ goto jerrsocks;
+ /* Version 5, reserved must be 0 */
+ if(pbuf[0] != 0x05 || pbuf[2] != 0x00)
+ goto jesocksreply;
+ /* Result */
+ switch(pbuf[1]){
+ case 0x00: emsg = NULL; break;
+ case 0x01: emsg = N_("SOCKS server failure"); break;
+ case 0x02: emsg = N_("connection not allowed by ruleset"); break;
+ case 0x03: emsg = N_("network unreachable"); break;
+ case 0x04: emsg = N_("host unreachable"); break;
+ case 0x05: emsg = N_("connection refused"); break;
+ case 0x06: emsg = N_("TTL expired"); break;
+ case 0x07: emsg = N_("command not supported"); break;
+ case 0x08: emsg = N_("address type not supported"); break;
+ default: emsg = N_("unknown SOCKS error code"); break;
+ }
+ if(emsg != NULL)
+ goto jesocksreplymsg;
+
+ /* Address type variable; read the BND.PORT with it.
+ * This is actually false since RFC 1928 says that the BND.ADDR reply
+ * to CONNECT contains the IP address, so only 0x01 and 0x04 are
+ * allowed */
+ switch(pbuf[3]){
+ case 0x01: i = 4; break;
+ case 0x03: i = 1; break;
+ case 0x04: i = 16; break;
+ default: goto jesocksreply;
+ }
+ i += sizeof(unsigned short);
+ if((size_t)HTDoRead(*s, pbuf, i) != i)
+ goto jerrsocks;
+ if(i == 1 + sizeof(unsigned short)){
+ i = pbuf[0];
+ if((size_t)HTDoRead(*s, pbuf, i) != i)
+ goto jerrsocks;
+ }
+ }
+
+jout:
+ if(socks5_proxy != NULL){
+ FREE(url);
+ FREE(protocol);
+ FREE(socks5_host);
+ }
+ if(host != NULL);
+ FREE(host);
+ if(line != NULL)
+ FREE(line);
return status;
}
diff --git a/lynx.man b/lynx.man
index ff4eb1b8..5a43c71a 100644
--- a/lynx.man
+++ b/lynx.man
@@ -804,6 +804,11 @@ If enabled the transfer rate is shown in bytes/second.
If disabled, no transfer rate is shown.
Use lynx.cfg or the options menu to select KB/second and/or ETA.
.TP
+.B \-socks5-proxy=URL
+(Via which) SOCKS5 proxy to connect.
+This controls the builtin SOCKS5 support, and is therefore unrelated to
+the option \fB\-nosocks\fP.
+.TP
.B \-soft_dquotes
toggles emulation of the old Netscape and Mosaic bug which
treated \*(``>\*('' as a co-terminator for double-quotes and tags.
diff --git a/src/LYGlobalDefs.h b/src/LYGlobalDefs.h
index e1203c02..577a5948 100644
--- a/src/LYGlobalDefs.h
+++ b/src/LYGlobalDefs.h
@@ -441,6 +441,7 @@ extern "C" {
extern BOOLEAN debug_display_partial; /* show with MessageSecs delay */
extern BOOLEAN display_partial_flag; /* permanent flag, not mutable */
#endif
+ extern char *socks5_proxy;
extern char *form_post_data; /* User data for post form */
extern char *form_get_data; /* User data for get form */
extern char *http_error_file; /* Place HTTP status code in this file */
diff --git a/src/LYMain.c b/src/LYMain.c
index 36c22ed5..46b8cee8 100644
--- a/src/LYMain.c
+++ b/src/LYMain.c
@@ -635,6 +635,8 @@ BOOLEAN debug_display_partial = FALSE; /* Show with MessageSecs delay */
int partial_threshold = -1; /* # of lines to be d/l'ed until we repaint */
#endif
+char *socks5_proxy = NULL;
+
BOOLEAN LYNonRestartingSIGWINCH = FALSE;
BOOLEAN LYReuseTempfiles = FALSE;
BOOLEAN LYUseBuiltinSuffixes = TRUE;
@@ -3910,6 +3912,10 @@ saves session to that file on exit"
"toggles display of transfer rate"
),
#endif
+ PARSE_STR(
+ "socks5-proxy", 2|NEED_LYSTRING_ARG, socks5_proxy,
+ "=URL\n(via which) SOCKS5 proxy to connect (unrelated to -nosocks!)"
+ ),
PARSE_SET(
"soft_dquotes", 4|TOGGLE_ARG, soft_dquotes,
"toggles emulation of the old Netscape and Mosaic\n\