diff options
Diffstat (limited to '')
-rw-r--r-- | WWW/Library/Implementation/HTTelnet.c | 553 |
1 files changed, 553 insertions, 0 deletions
diff --git a/WWW/Library/Implementation/HTTelnet.c b/WWW/Library/Implementation/HTTelnet.c new file mode 100644 index 0000000..fb0098a --- /dev/null +++ b/WWW/Library/Implementation/HTTelnet.c @@ -0,0 +1,553 @@ +/* + * $LynxId: HTTelnet.c,v 1.41 2013/11/28 11:15:19 tom Exp $ + * + * Telnet Access, Rlogin, etc HTTelnet.c + * ========================== + * + * Authors + * TBL Tim Berners-Lee timbl@info.cern.ch + * JFG Jean-Francois Groff jgh@next.com + * DD Denis DeLaRoca (310) 825-4580 <CSP1DWD@mvs.oac.ucla.edu> + * History + * 8 Jun 92 Telnet hopping prohibited as telnet is not secure (TBL) + * 26 Jun 92 When over DECnet, suppressed FTP, Gopher and News. (JFG) + * 6 Oct 92 Moved HTClientHost and logfile into here. (TBL) + * 17 Dec 92 Tn3270 added, bug fix. (DD) + * 2 Feb 93 Split from HTAccess.c. Registration.(TBL) + */ + +#include <HTUtils.h> +#include <LYUtils.h> + +/* Implements: +*/ +#include <HTTelnet.h> + +#include <HTParse.h> +#include <HTAnchor.h> +#include <HTTP.h> +#include <HTFile.h> + +#include <HTTCP.h> +#include <HText.h> + +#include <HTAccess.h> +#include <HTAlert.h> + +#include <LYStrings.h> +#include <LYClean.h> +#include <LYLeaks.h> + +#ifdef __GNUC__ +static void do_system(char *) GCC_UNUSED; +#endif + +static void do_system(char *command) +{ + if (non_empty(command)) { + CTRACE((tfp, "HTTelnet: Command is: %s\n\n", command)); + LYSystem(command); + } + FREE(command); +} + +/* Telnet or "rlogin" access + * ------------------------- + */ +static int remote_session(char *acc_method, char *host) +{ + const char *program; + char *user = host; + char *password = NULL; + char *cp; + char *hostname; + char *port; + char *command = NULL; + enum _login_protocol { + telnet, + rlogin, + tn3270 + } login_protocol = + strcmp(acc_method, "rlogin") == 0 ? rlogin : + strcmp(acc_method, "tn3270") == 0 ? tn3270 : telnet; + + /* + * Modified to allow for odd chars in a username only if exists. + * 05-28-94 Lynx 2-3-1 Garrett Arch Blythe + */ + /* prevent telnet://hostname;rm -rf * URL's (VERY BAD) + * *cp=0; // terminate at any ;,<,>,`,|,",' or space or return + * or tab to prevent security hole + */ + for (cp = (StrChr(host, '@') ? StrChr(host, '@') : host); *cp != '\0'; + cp++) { + if (!isalnum(UCH(*cp)) && *cp != '_' && *cp != '-' && + *cp != ':' && *cp != '.' && *cp != '@') { + *cp = '\0'; + break; + } + } + + hostname = StrChr(host, '@'); + + if (hostname) { + *hostname++ = '\0'; /* Split */ + } else { + hostname = host; + user = NULL; /* No user specified */ + } + + port = StrChr(hostname, ':'); + if (port) + *port++ = '\0'; /* Split */ + + if (*hostname == '\0') { + CTRACE((tfp, "HTTelnet: No host specified!\n")); + return HT_NO_DATA; + } else if (!valid_hostname(hostname)) { + char *prefix = NULL; + char *line = NULL; + + CTRACE((tfp, "HTTelnet: Invalid hostname %s!\n", host)); + HTSprintf0(&prefix, + gettext("remote %s session:"), acc_method); + HTSprintf0(&line, + gettext("Invalid hostname %s"), host); + HTAlwaysAlert(prefix, line); + FREE(prefix); + FREE(line); + return HT_NO_DATA; + } + + if (user) { + password = StrChr(user, ':'); + if (password) { + *password++ = '\0'; + } + } + + /* If the person is already telnetting etc, forbid hopping */ + /* This is a security precaution, for us and remote site */ + + if (HTSecure) { + +#ifdef TELNETHOPPER_MAIL + HTSprintf0(&command, + "finger @%s | mail -s \"**telnethopper %s\" tbl@dxcern.cern.ch", + HTClientHost, HTClientHost); + do_system(command); +#endif + printf("\n\nSorry, but the service you have selected is one\n"); + printf("to which you have to log in. If you were running www\n"); + printf("on your own computer, you would be automatically connected.\n"); + printf("For security reasons, this is not allowed when\n"); + printf("you log in to this information service remotely.\n\n"); + + printf("You can manually connect to this service using %s\n", + acc_method); + printf("to host %s", hostname); + if (user) + printf(", user name %s", user); + if (password) + printf(", password %s", password); + if (port) + printf(", port %s", port); + printf(".\n\n"); + return HT_NO_DATA; + } + + /* Not all telnet servers get it even if user name is specified so we + * always tell the guy what to log in as. + */ + if (user && login_protocol != rlogin) + printf("When you are connected, log in as: %s\n", user); + if (password && login_protocol != rlogin) + printf(" The password is: %s\n", password); + fflush(stdout); + +/* + * NeXTSTEP is the implied version of the NeXT operating system. + * You may need to define this yourself. + */ +#if !defined(TELNET_DONE) && (defined(NeXT) && defined(NeXTSTEP) && NeXTSTEP<=20100) +#define FMT_TELNET "%s%s%s %s %s" + + if ((program = HTGetProgramPath(ppTELNET)) != NULL) { + HTAddParam(&command, FMT_TELNET, 1, program); + HTOptParam(&command, FMT_TELNET, 2, user ? " -l " : ""); + HTAddParam(&command, FMT_TELNET, 3, user); + HTAddParam(&command, FMT_TELNET, 4, hostname); + HTAddParam(&command, FMT_TELNET, 5, port); + HTEndParam(&command, FMT_TELNET, 5); + } + do_system(command); +#define TELNET_DONE +#endif + +/* Most unix machines support username only with rlogin */ +#if !defined(TELNET_DONE) && (defined(UNIX) || defined(DOSPATH) || defined(__CYGWIN__)) + +#define FMT_RLOGIN "%s %s%s%s" +#define FMT_TN3270 "%s %s %s" +#define FMT_TELNET "%s %s %s" + + switch (login_protocol) { + case rlogin: + if ((program = HTGetProgramPath(ppRLOGIN)) != NULL) { + HTAddParam(&command, FMT_RLOGIN, 1, program); + HTAddParam(&command, FMT_RLOGIN, 2, hostname); + HTOptParam(&command, FMT_RLOGIN, 3, user ? " -l " : ""); + HTAddParam(&command, FMT_RLOGIN, 4, user); + HTEndParam(&command, FMT_RLOGIN, 4); + } + break; + + case tn3270: + if ((program = HTGetProgramPath(ppTN3270)) != NULL) { + HTAddParam(&command, FMT_TN3270, 1, program); + HTAddParam(&command, FMT_TN3270, 2, hostname); + HTAddParam(&command, FMT_TN3270, 3, port); + HTEndParam(&command, FMT_TN3270, 3); + } + break; + + case telnet: + if ((program = HTGetProgramPath(ppTELNET)) != NULL) { + HTAddParam(&command, FMT_TELNET, 1, program); + HTAddParam(&command, FMT_TELNET, 2, hostname); + HTAddParam(&command, FMT_TELNET, 3, port); + HTEndParam(&command, FMT_TELNET, 3); + } + break; + } + + LYSystem(command); +#define TELNET_DONE +#endif /* unix */ + +/* VMS varieties */ +#if !defined(TELNET_DONE) && (defined(MULTINET)) + if (login_protocol == rlogin) { + HTSprintf0(&command, "RLOGIN%s%s%s%s%s %s", /*lm 930713 */ + user ? "/USERNAME=\"" : "", + NonNull(user), + user ? "\"" : "", + port ? "/PORT=" : "", + NonNull(port), + hostname); + + } else if (login_protocol == tn3270) { + HTSprintf0(&command, "TELNET/TN3270 %s%s %s", + port ? "/PORT=" : "", + NonNull(port), + hostname); + + } else { /* TELNET */ + HTSprintf0(&command, "TELNET %s%s %s", + port ? "/PORT=" : "", + NonNull(port), + hostname); + } + + do_system(command); +#define TELNET_DONE +#endif /* MULTINET */ + +#if !defined(TELNET_DONE) && defined(WIN_TCP) + if ((cp = getenv("WINTCP_COMMAND_STYLE")) != NULL && + 0 == strncasecomp(cp, "VMS", 3)) { /* VMS command syntax */ + if (login_protocol == rlogin) { + HTSprintf0(&command, "RLOGIN%s%s%s%s%s %s", /*lm 930713 */ + user ? "/USERNAME=\"" : "", + NonNull(user), + user ? "\"" : "", + port ? "/PORT=" : "", + NonNull(port), + hostname); + + } else if (login_protocol == tn3270) { + HTSprintf0(&command, "TELNET/TN3270 %s%s %s", + port ? "/PORT=" : "", + NonNull(port), + hostname); + + } else { /* TELNET */ + HTSprintf0(&command, "TELNET %s%s %s", + port ? "/PORT=" : "", + NonNull(port), + hostname); + } + + } else { /* UNIX command syntax */ + if (login_protocol == rlogin) { + HTSprintf0(&command, "RLOGIN %s%s%s%s%s", + hostname, + user ? " -l " : "", + user ? "\"" : "", + NonNull(user), + user ? "\"" : ""); + + } else if (login_protocol == tn3270) { + HTSprintf0(&command, "TN3270 %s %s", + hostname, + NonNull(port)); + + } else { /* TELNET */ + HTSprintf0(&command, "TELNET %s %s", + hostname, + NonNull(port)); + } + } + + do_system(command); +#define TELNET_DONE +#endif /* WIN_TCP */ + +#if !defined(TELNET_DONE) && defined(UCX) + if (login_protocol == rlogin) { + HTSprintf0(&command, "RLOGIN%s%s%s %s %s", + user ? "/USERNAME=\"" : "", + NonNull(user), + user ? "\"" : "", + hostname, + NonNull(port)); + + } else if (login_protocol == tn3270) { + HTSprintf0(&command, "TN3270 %s %s", + hostname, + NonNull(port)); + + } else { /* TELNET */ + HTSprintf0(&command, "TELNET %s %s", + hostname, + NonNull(port)); + } + + do_system(command); +#define TELNET_DONE +#endif /* UCX */ + +#if !defined(TELNET_DONE) && defined(CMU_TCP) + if (login_protocol == telnet) { + HTSprintf0(&command, "TELNET %s%s %s", + port ? "/PORT=" : "", + NonNull(port), + hostname); + do_system(command); + } else { + printf("\nSorry, this browser was compiled without the %s access option.\n", + acc_method); + printf("\nPress <return> to return to Lynx."); + LYgetch(); + HadVMSInterrupt = FALSE; + } +#define TELNET_DONE +#endif /* CMU_TCP */ + +#if !defined(TELNET_DONE) && defined(SOCKETSHR_TCP) + if (getenv("MULTINET_SOCKET_LIBRARY") != NULL) { + if (login_protocol == rlogin) { + HTSprintf0(&command, "MULTINET RLOGIN%s%s%s%s %s", /*lm 930713 */ + user ? "/USERNAME=" : "", + NonNull(user), + port ? "/PORT=" : "", + NonNull(port), + hostname); + + } else if (login_protocol == tn3270) { + HTSprintf0(&command, "MULTINET TELNET/TN3270 %s%s %s", + port ? "/PORT=" : "", + NonNull(port), + hostname); + + } else { /* TELNET */ + HTSprintf0(&command, "MULTINET TELNET %s%s %s", + port ? "/PORT=" : "", + NonNull(port), + hostname); + } + + do_system(command); + return HT_NO_DATA; /* Ok - it was done but no data */ + } else if ((cp = getenv("WINTCP_COMMAND_STYLE")) != NULL) { + if (0 == strncasecomp(cp, "VMS", 3)) { /* VMS command syntax */ + if (login_protocol == rlogin) { + HTSprintf0(&command, "RLOGIN%s%s%s%s %s", /*lm 930713 */ + user ? "/USERNAME=" : "", + NonNull(user), + port ? "/PORT=" : "", + NonNull(port), + hostname); + } else if (login_protocol == tn3270) { + HTSprintf0(&command, "TELNET/TN3270 %s%s %s", + port ? "/PORT=" : "", + NonNull(port), + hostname); + } else { /* TELNET */ + HTSprintf0(&command, "TELNET %s%s %s", + port ? "/PORT=" : "", + NonNull(port), + hostname); + } + } else { /* UNIX command syntax */ + if (login_protocol == rlogin) { + HTSprintf0(&command, "RLOGIN %s%s%s", + hostname, + user ? " -l " : "", + NonNull(user)); + } else if (login_protocol == tn3270) { + HTSprintf0(&command, "TN3270 %s %s", + hostname, + NonNull(port)); + } else { /* TELNET */ + HTSprintf0(&command, "TELNET %s %s", + hostname, + NonNull(port)); + } + } + + do_system(command); + return HT_NO_DATA; /* Ok - it was done but no data */ + } else if (getenv("UCX$DEVICE") != NULL + || getenv("TCPIP$DEVICE") != NULL) { + if (login_protocol == rlogin) { + HTSprintf0(&command, "RLOGIN%s%s %s %s", + user ? "/USERNAME=" : "", + NonNull(user), + hostname, + NonNull(port)); + + } else if (login_protocol == tn3270) { + HTSprintf0(&command, "TN3270 %s %s", + hostname, + NonNull(port)); + + } else { /* TELNET */ + HTSprintf0(&command, "TELNET %s %s", + hostname, + NonNull(port)); + } + + do_system(command); + return HT_NO_DATA; /* Ok - it was done but no data */ + } else if (getenv("CMUTEK_ROOT") != NULL) { + if (login_protocol == telnet) { + HTSprintf0(&command, "TELNET %s%s %s", + port ? "/PORT=" : "", + NonNull(port), + hostname); + do_system(command); + } else { + printf("\nSorry, this browser was compiled without the %s access option.\n", + acc_method); + printf("\nPress <return> to return to Lynx."); + LYgetch(); + HadVMSInterrupt = FALSE; + } + } else { + if (login_protocol == telnet) { + HTSprintf0(&command, "TELNET %s%s %s", + port ? "/PORT=" : "", + NonNull(port), + hostname); + do_system(command); + } else { + printf("\nSorry, this browser was compiled without the %s access option.\n", + acc_method); + printf("\nPress <return> to return to Lynx."); + LYgetch(); + HadVMSInterrupt = FALSE; + } + } +#define TELNET_DONE +#endif /* SOCKETSHR_TCP */ + +#if !defined(TELNET_DONE) && (defined(SIMPLE_TELNET) || defined(VM)) + if (login_protocol == telnet) { /* telnet only */ + HTSprintf0(&command, "TELNET %s", /* @@ Bug: port ignored */ + hostname); + do_system(command); + return HT_NO_DATA; /* Ok - it was done but no data */ + } +#define TELNET_DONE +#endif + +#ifndef TELNET_DONE + printf("\nSorry, this browser was compiled without the %s access option.\n", + acc_method); + printf("\nTo access the information you must %s to %s", acc_method, hostname); + if (port) + printf(" (port %s)", port); + if (user) + printf("\nlogging in with username %s", user); + printf(".\n"); + { + printf("\nPress <return> to return to Lynx."); + fflush(stdout); + LYgetch(); +#ifdef VMS + HadVMSInterrupt = FALSE; +#endif /* VMS */ + } +#endif /* !TELNET_DONE */ + return HT_NO_DATA; +} + +/* "Load a document" -- establishes a session + * ------------------------------------------ + * + * On entry, + * addr must point to the fully qualified hypertext reference. + * + * On exit, + * returns <0 Error has occurred. + * >=0 Value of file descriptor or socket to be used + * to read data. + * *pFormat Set to the format of the file, if known. + * (See WWW.h) + * + */ +static int HTLoadTelnet(const char *addr, + HTParentAnchor *anchor GCC_UNUSED, + HTFormat format_out GCC_UNUSED, + HTStream *sink) /* Ignored */ +{ + char *acc_method; + char *host; + int status; + + if (sink) { + CTRACE((tfp, + "HTTelnet: Can't output a live session -- must be interactive!\n")); + return HT_NO_DATA; + } + acc_method = HTParse(addr, STR_FILE_URL, PARSE_ACCESS); + + host = HTParse(addr, "", PARSE_HOST); + if (!host || *host == '\0') { + status = HT_NO_DATA; + CTRACE((tfp, "HTTelnet: No host specified!\n")); + } else { + status = remote_session(acc_method, host); + } + + FREE(host); + FREE(acc_method); + return status; +} + +#ifdef GLOBALDEF_IS_MACRO +#define _HTTELNET_C_1_INIT { "telnet", HTLoadTelnet, NULL } +#define _HTTELNET_C_2_INIT { "rlogin", HTLoadTelnet, NULL } +#define _HTTELNET_C_3_INIT { "tn3270", HTLoadTelnet, NULL } +GLOBALDEF(HTProtocol, HTTelnet, _HTTELNET_C_1_INIT); +GLOBALDEF(HTProtocol, HTRlogin, _HTTELNET_C_2_INIT); +GLOBALDEF(HTProtocol, HTTn3270, _HTTELNET_C_3_INIT); +#else +GLOBALDEF HTProtocol HTTelnet = +{"telnet", HTLoadTelnet, NULL}; +GLOBALDEF HTProtocol HTRlogin = +{"rlogin", HTLoadTelnet, NULL}; +GLOBALDEF HTProtocol HTTn3270 = +{"tn3270", HTLoadTelnet, NULL}; +#endif /* GLOBALDEF_IS_MACRO */ |