On Sun, Sep 15, 2019 at 12:31:17AM +0200, Steffen Nurpmeso wrote: > Huhu. > > 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'll have to think about the ifdef's, but testing the proposed changes would be next, before applying to trunk) -- Thomas E. Dickey <[email protected]> https://invisible-island.net ftp://ftp.invisible-island.net
# patch by Thomas E. Dickey <[email protected]> # created Mon Sep 16 00:29:40 UTC 2019 # ------------------------------------------------------------------------------ # WWW/Library/Implementation/HTTCP.c | 215 ++++++++++++++++++++++++++++++++--- # lynx.man | 7 - # src/LYGlobalDefs.h | 3 # src/LYMain.c | 8 + # 4 files changed, 213 insertions(+), 20 deletions(-) # ------------------------------------------------------------------------------ Index: WWW/Library/Implementation/HTTCP.c --- lynx2.9.0dev.4c+/WWW/Library/Implementation/HTTCP.c 2018-12-26 13:16:59.000000000 +0000 +++ lynx2.9.0dev.4d/WWW/Library/Implementation/HTTCP.c 2019-09-16 00:27:19.000000000 +0000 @@ -1,5 +1,5 @@ /* - * $LynxId: HTTCP.c,v 1.151 2018/12/26 13:16:59 tom Exp $ + * $LynxId: HTTCP.c,v 1.151.1.13 2019/09/16 00:27:19 tom Exp tom $ * * Generic Communication Code HTTCP.c * ========================== @@ -1825,10 +1825,17 @@ int default_port, int *s) { - int status = 0; + char *socks5_host; + unsigned socks5_host_len = 0; + int socks5_port; + const char *socks5_orig_url; + char *socks5_new_url = NULL; + char *socks5_protocol = NULL; + 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 +1843,49 @@ #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) { + int xport; + + xport = default_port; + socks5_orig_url = url; + StrAllocCopy(socks5_new_url, url); + + /* Get node name and optional port number of wanted URL */ + p1 = HTParse(socks5_new_url, "", PARSE_HOST); + socks5_host = NULL; + StrAllocCopy(socks5_host, p1); + strip_userid(socks5_host, FALSE); + FREE(p1); + + if (strlen(socks5_host) > 255) { + emsg = gettext("SOCKS5: hostname too long."); + status = HT_ERROR; + goto report_error; + } + socks5_host_len = (unsigned) strlen(socks5_host); + + if (HTParsePort(socks5_new_url, &socks5_port) == NULL) + socks5_port = xport; + FREE(socks5_new_url); + + /* And switch over to our SOCKS5 config; in order to embed that into + * lynx environment, prepend protocol prefix */ + default_port = 1080; /* RFC 1928 */ + HTSACat(&socks5_new_url, "socks://"); + HTSACat(&socks5_new_url, socks5_proxy); + url = socks5_new_url; + + socks5_protocol = HTSprintf0(NULL, + gettext("(for %s at %s) SOCKS5"), + protocol, socks5_host); + protocol = socks5_protocol; + } +#ifndef INET6 /* * Set up defaults. */ @@ -1861,9 +1910,8 @@ if (res0 == NULL) { HTSprintf0(&line, gettext("Unable to locate remote host %s."), host); _HTProgress(line); - FREE(host); - FREE(line); - return HT_NO_DATA; + status = HT_NO_DATA; + goto cleanup; } #else status = HTParseInet(soc_in, host); @@ -1882,16 +1930,12 @@ } 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. @@ -1899,8 +1943,9 @@ #ifndef INET6 *s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (*s == -1) { - HTAlert(gettext("socket failed.")); - return HT_NO_DATA; + status = HT_NO_DATA; + emsg = gettext("socket failed."); + goto report_error; } #else for (res = res0; res; res = res->ai_next) { @@ -1916,7 +1961,6 @@ gettext("socket failed: family %d addr %s port %s."), res->ai_family, hostbuf, portbuf); _HTProgress(line); - FREE(line); continue; } #endif /* INET6 */ @@ -2005,13 +2049,13 @@ 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 +2248,6 @@ #endif /* !DOSPATH || __DJGPP__ */ #ifdef INET6 - FREE(line); #ifdef NSL_FORK FREE_NSL_FORK(res0); #else @@ -2212,11 +2255,149 @@ 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; + } else if (HTDoRead(*s, pbuf, 2) != 2) { + goto report_system_err; + } else 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; + /* C99 */ { + unsigned short x; /* XXX 16-bit? */ + + x = htons(socks5_port); + memcpy(&pbuf[i], (unsigned char *) &x, sizeof x); + i += (unsigned) sizeof(x); + } + if ((size_t) write(*s, pbuf, i) != i) { + goto report_system_err; + } else if ((i = (unsigned) HTDoRead(*s, pbuf, 4)) != 4) { + goto report_system_err; + } + /* Version 5, reserved must be 0 */ + if (pbuf[0] == 0x05 && pbuf[2] == 0x00) { + /* Result */ + switch (pbuf[1]) { + case 0x00: + emsg = NULL; + break; + case 0x01: + emsg = gettext("SOCKS server failure"); + break; + case 0x02: + emsg = gettext("connection not allowed by ruleset"); + break; + case 0x03: + emsg = gettext("network unreachable"); + break; + case 0x04: + emsg = gettext("host unreachable"); + break; + case 0x05: + emsg = gettext("connection refused"); + break; + case 0x06: + emsg = gettext("TTL expired"); + break; + case 0x07: + emsg = gettext("command not supported"); + break; + case 0x08: + emsg = gettext("address type not supported"); + break; + default: + emsg = gettext("unknown SOCKS error code"); + break; + } + if (emsg != NULL) { + goto report_no_connection; + } + } else { + goto report_unexpected_reply; + } + + /* 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 += (unsigned) sizeof(unsigned short); + + if ((size_t) HTDoRead(*s, pbuf, i) != i) { + goto report_system_err; + } else if (i == 1 + sizeof(unsigned short)) { + i = pbuf[0]; + if ((size_t) HTDoRead(*s, pbuf, i) != i) { + goto report_system_err; + } + } + } + goto cleanup; + + report_system_err: + emsg = LYStrerror(errno); + goto report_no_connection; + + report_unexpected_reply: + emsg = gettext("unexpected reply\n"); + /* FALLTHRU */ + + report_no_connection: + status = HT_NO_CONNECTION; + /* FALLTHRU */ + + report_error: + HTAlert(emsg); + if (*s != -1) { + NETCLOSE(*s); + } + + cleanup: + if (socks5_proxy != NULL) { + FREE(socks5_new_url); + FREE(socks5_protocol); + FREE(socks5_host); + } + FREE(host); + FREE(line); return status; } /* - * This is so interruptible reads can be implemented cleanly. + * This is interruptible so reads can be implemented cleanly. */ int HTDoRead(int fildes, void *buf, Index: lynx.man --- lynx2.9.0dev.4c+/lynx.man 2019-08-17 01:07:24.000000000 +0000 +++ lynx2.9.0dev.4d/lynx.man 2019-09-15 22:20:44.000000000 +0000 @@ -1,4 +1,4 @@ -.\" $LynxId: lynx.man,v 1.124 2019/08/17 01:07:24 tom Exp $ +.\" $LynxId: lynx.man,v 1.124.1.1 2019/09/15 22:20:44 Steffen.Nurpmeso Exp tom $ .\" ************************************************************************** .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds AQ \(aq @@ -804,6 +804,11 @@ 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. Index: src/LYGlobalDefs.h --- lynx2.9.0dev.4c+/src/LYGlobalDefs.h 2019-01-25 02:00:58.000000000 +0000 +++ lynx2.9.0dev.4d/src/LYGlobalDefs.h 2019-09-15 22:20:44.000000000 +0000 @@ -1,5 +1,5 @@ /* - * $LynxId: LYGlobalDefs.h,v 1.150 2019/01/25 02:00:58 tom Exp $ + * $LynxId: LYGlobalDefs.h,v 1.150.1.1 2019/09/15 22:20:44 Steffen.Nurpmeso Exp tom $ * * global variable definitions */ @@ -441,6 +441,7 @@ 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 */ Index: src/LYMain.c --- lynx2.9.0dev.4c+/src/LYMain.c 2019-01-25 00:06:42.000000000 +0000 +++ lynx2.9.0dev.4d/src/LYMain.c 2019-09-15 22:20:44.000000000 +0000 @@ -1,5 +1,5 @@ /* - * $LynxId: LYMain.c,v 1.285 2019/01/25 00:06:42 tom Exp $ + * $LynxId: LYMain.c,v 1.285.1.1 2019/09/15 22:20:44 Steffen.Nurpmeso Exp tom $ */ #include <HTUtils.h> #include <HTTP.h> @@ -636,6 +636,8 @@ 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; @@ -3907,6 +3909,10 @@ "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\
signature.asc
Description: PGP signature
_______________________________________________ Lynx-dev mailing list [email protected] https://lists.nongnu.org/mailman/listinfo/lynx-dev
