Hello.
Steffen Nurpmeso wrote in <20190916201722.43jo6%[email protected]>:
|Steffen Nurpmeso wrote in <20190916181305._pau3%[email protected]>:
||Thomas Dickey wrote in <20190916003351.7x3j6ubnoerj7ysh@prl-debianold-64\
||.jexium-island.net>:
|||On Sun, Sep 15, 2019 at 12:31:17AM +0200, Steffen Nurpmeso wrote:
|||> Steffen Nurpmeso wrote in <20190914220418.j7nb7%[email protected]>:
|||>|Steffen Nurpmeso wrote in <20190911141510.7s2dr%[email protected]>:
|||>||please excuse the late reply.
|||> ...
|||>|Right. So here is a working patch, porting over my own SOCKS5
|||>
|||> Yep, but it should set status to an error code if the hostname
|||> length check in the upper conditional fails. Sorry.
|||
|||well... I'll have to set up something for testing, but here's something
|||more like the style of lynx
|
|I see we would also have crashed if the hostname length would have
|been excessed. Ah, it also was the last night of the proms, i am
|sorry. But i wanted to post it on Saturday, after having said
|i will do it Wednesday or Thursday. Other than that i hope it is
|fine.
Now here stylified the way you did, with your jumps copied over
(but placed at end of function to pessimize errors), Thorsten's
htons() replacement, and style adjusted to what seems appropriate
for lynx. I did not initialize all locals due to the reordering
of the first conditional (i would in fact rather use a struct to
collect all that, and do the SOCKS5 address lookup only once, as
the address is fixed in lynx; anyway). Works here from a short
test. I also added the word "to" to manual and help string.
--steffen
|
|Der Kragenbaer, The moon bear,
|der holt sich munter he cheerfully and one by one
|einen nach dem anderen runter wa.ks himself off
|(By Robert Gernhardt)
diff -Napru -u lynx2.8.9rel.1.orig/lynx.man lynx2.8.9rel.1/lynx.man
--- lynx2.8.9rel.1.orig/lynx.man 2018-07-08 12:54:20.000000000 +0200
+++ lynx2.8.9rel.1/lynx.man 2019-09-16 22:27:31.540865464 +0200
@@ -804,6 +804,11 @@ If enabled the transfer rate is shown in
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 to.
+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 -Napru -u lynx2.8.9rel.1.orig/src/LYGlobalDefs.h lynx2.8.9rel.1/src/LYGlobalDefs.h
--- lynx2.8.9rel.1.orig/src/LYGlobalDefs.h 2018-03-28 01:05:13.000000000 +0200
+++ lynx2.8.9rel.1/src/LYGlobalDefs.h 2019-09-16 22:19:08.160874980 +0200
@@ -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 -Napru -u lynx2.8.9rel.1.orig/src/LYMain.c lynx2.8.9rel.1/src/LYMain.c
--- lynx2.8.9rel.1.orig/src/LYMain.c 2018-07-08 17:22:44.000000000 +0200
+++ lynx2.8.9rel.1/src/LYMain.c 2019-09-16 22:27:23.827532277 +0200
@@ -635,6 +635,8 @@ BOOLEAN debug_display_partial = FALSE; /
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 to (unrelated to -nosocks!)"
+ ),
PARSE_SET(
"soft_dquotes", 4|TOGGLE_ARG, soft_dquotes,
"toggles emulation of the old Netscape and Mosaic\n\
diff -Napru -u lynx2.8.9rel.1.orig/WWW/Library/Implementation/HTTCP.c lynx2.8.9rel.1/WWW/Library/Implementation/HTTCP.c
--- lynx2.8.9rel.1.orig/WWW/Library/Implementation/HTTCP.c 2018-05-16 21:48:49.000000000 +0200
+++ lynx2.8.9rel.1/WWW/Library/Implementation/HTTCP.c 2019-09-16 22:53:29.772696773 +0200
@@ -1825,10 +1825,16 @@ int HTDoConnect(const char *url,
int default_port,
int *s)
{
- int status = 0;
+ /* On error goto cleanup */
+ char *socks5_host;
+ unsigned socks5_host_len;
+ int socks5_port;
+ const char *socks5_orig_url;
+ int status = HT_OK;
char *line = NULL;
char *p1 = NULL;
char *host = NULL;
+ char const *emsg;
#ifdef INET6
LYNX_ADDRINFO *res = 0, *res0 = 0;
@@ -1836,7 +1842,48 @@ int HTDoConnect(const char *url,
#else
struct sockaddr_in sock_A;
struct sockaddr_in *soc_in = &sock_A;
+#endif
+
+ *s = -1; /* nothing is open yet */
+
+ /* 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 (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);
+
+ if ((i = strlen(socks5_host)) > 255) {
+ HTAlert(gettext("SOCKS5: hostname too long."));
+ status = HT_ERROR;
+ goto cleanup;
+ }
+ socks5_host_len = (int) i;
+ }
+#ifndef INET6
/*
* Set up defaults.
*/
@@ -1859,11 +1906,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 cleanup;
}
#else
status = HTParseInet(soc_in, host);
@@ -1882,16 +1928,12 @@ int HTDoConnect(const char *url,
}
status = HT_NO_DATA;
}
- FREE(host);
- FREE(line);
- return status;
+ goto cleanup;
}
#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 +1942,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 cleanup;
}
#else
for (res = res0; res; res = res->ai_next) {
@@ -1916,7 +1959,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 +2047,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 cleanup;
}
set_timeout(&select_timeout);
FD_ZERO(&writefds);
@@ -2204,7 +2246,6 @@ int HTDoConnect(const char *url,
#endif /* !DOSPATH || __DJGPP__ */
#ifdef INET6
- FREE(line);
#ifdef NSL_FORK
FREE_NSL_FORK(res0);
#else
@@ -2212,7 +2253,143 @@ 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];
+ unsigned i;
+
+ /* 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)
+ goto report_system_err;
+
+ /* Receive greeting */
+ if (HTDoRead(*s, pbuf, 2) != 2)
+ goto report_system_err;
+
+ if (pbuf[0] != 0x05 || pbuf[1] != 0x00)
+ goto report_unexpected_reply;
+
+ /* 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;
+ pbuf[i++] = ((unsigned)socks5_port >> 8) & 0xFF;
+ pbuf[i++] = (unsigned)socks5_port & 0xFF;
+ if ((size_t) write(*s, pbuf, i) != i)
+ goto report_system_err;
+
+ /* Connect result */
+ if (HTDoRead(*s, pbuf, 4) != 4)
+ goto report_system_err;
+
+ /* Version 5, reserved must be 0 */
+ if (pbuf[0] != 0x05 || pbuf[2] != 0x00)
+ goto report_unexpected_reply;
+ 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) {
+ emsg = gettext(emsg);
+ goto report_no_connection;
+ }
+
+ /* 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 report_unexpected_reply;
+ }
+ i += 2;
+ if ((unsigned) HTDoRead(*s, pbuf, i) != i)
+ goto report_system_err;
+ if (i == 1 + 2) {
+ i = pbuf[0];
+ if ((unsigned) HTDoRead(*s, pbuf, i) != i)
+ goto report_system_err;
+ }
+ }
+
+ cleanup:
+ if (socks5_proxy != NULL) {
+ FREE(url);
+ FREE(protocol);
+ FREE(socks5_host);
+ }
+ if (host != NULL);
+ FREE(host);
+ if (line != NULL)
+ FREE(line);
return status;
+
+ report_system_err:
+ emsg = LYStrerror(errno);
+ goto report_no_connection;
+
+ report_unexpected_reply:
+ emsg = gettext("unexpected reply");
+ /* FALLTHRU */
+
+ report_no_connection:
+ status = HT_NO_CONNECTION;
+ /* FALLTHRU */
+
+ report_error:
+ HTAlert(emsg);
+ if (*s != -1)
+ NETCLOSE(*s);
+
+ goto cleanup;
}
/*
_______________________________________________
Lynx-dev mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/lynx-dev