This repository has been archived on 2024-01-04. You can view files and clone it, but cannot push or open issues or pull requests.
ncsa-mosaic/libwww2/HTTelnet.c

314 lines
6.3 KiB
C

/* Telnet Acees, Roligin, etc HTAccess.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 "../config.h"
/* Implements:
*/
#include "HTTelnet.h"
#include "HTParse.h"
#include "HTUtils.h"
#include "HTAnchor.h"
#include "HTTP.h"
#include "HTFile.h"
#include <errno.h>
#include <stdio.h>
#include "tcp.h"
#include "HText.h"
#include "HTAccess.h"
#include "HTAlert.h"
extern void application_user_feedback (char *);
#ifndef DISABLE_TRACE
extern int www2Trace;
#endif
/* make a string secure for passage to the
** system() command. Make it contain only alphanumneric
** characters, or the characters '.', '-', '_', '+'.
** Also remove leading '-' or '+'.
** -----------------------------------------------------
*/
PRIVATE void make_system_secure ARGS1(char *, str)
{
char *ptr1, *ptr2;
if ((str == NULL)||(*str == '\0'))
{
return;
}
/*
* remove leading '-' or '+' by making it into whitespace that
* will be stripped later.
*/
if ((*str == '-')||(*str == '+'))
{
*str = ' ';
}
ptr1 = ptr2 = str;
while (*ptr1 != '\0')
{
if ((!isalpha((int)*ptr1))&&(!isdigit((int)*ptr1))&&
(*ptr1 != '.')&&(*ptr1 != '_')&&
(*ptr1 != '+')&&(*ptr1 != '-'))
{
ptr1++;
}
else
{
*ptr2 = *ptr1;
ptr2++;
ptr1++;
}
}
*ptr2 = *ptr1;
}
PRIVATE void run_a_command ARGS1(char *, command)
{
char **argv;
int argc;
char *str;
int alen;
alen = 10;
argv = (char **)malloc(10 * sizeof(char *));
if (argv == NULL)
{
return;
}
argc = 0;
str = strtok(command, " \t\n");
while (str != NULL)
{
argv[argc] = strdup(str);
argc++;
if (argc >= alen)
{
int i;
char **tmp_av;
tmp_av = (char **)malloc((alen + 10) * sizeof(char *));
if (tmp_av == NULL)
{
return;
}
for (i=0; i<alen; i++)
{
tmp_av[i] = argv[i];
}
alen += 10;
free((char *)argv);
argv = tmp_av;
}
str = strtok(NULL, " \t\n");
}
argv[argc] = NULL;
if (fork() == 0)
{
execvp(argv[0], argv);
}
else
{
int i;
/*
* The signal handler in main.c will clean this child
* up when it exits.
*/
for (i=0; i<argc; i++)
{
if (argv[i] != NULL)
{
free(argv[i]);
}
}
free((char *)argv);
}
}
/* Telnet or "rlogin" access
** -------------------------
*/
PRIVATE int remote_session ARGS2(char *, access, char *, host)
{
char *user, *hostname, *port;
int portnum;
char command[256];
char *xterm_str;
enum _login_protocol { telnet, rlogin, tn3270 } login_protocol;
extern char *global_xterm_str;
if (!access || !host)
{
application_user_feedback
("Cannot open remote session, because\nURL is malformed.\0");
return HT_NO_DATA;
}
login_protocol =
strcmp(access, "rlogin") == 0 ? rlogin :
strcmp(access, "tn3270") == 0 ? tn3270 :
telnet;
/* Make sure we won't overrun the size of command with a huge host string */
if (strlen(host) > 200)
{
host[200] = '\0';
}
user = host;
hostname = strchr(host, '@');
port = strchr(host, ':');
if (hostname)
{
*hostname++ = 0; /* Split */
}
else
{
hostname = host;
user = 0; /* No user specified */
}
if (port)
{
*port++ = 0; /* Split */
portnum = atoi(port);
}
/*
* Make user and hostname secure by removing leading '-' or '+'.
* and allowing only alphanumeric, '.', '_', '+', and '-'.
*/
make_system_secure(user);
make_system_secure(hostname);
xterm_str = global_xterm_str;
if (login_protocol == rlogin)
{
/* For rlogin, we should use -l user. */
if ((port)&&(portnum > 0)&&(portnum < 63336))
{
sprintf(command, "%s -e %s %s %d %s %s", xterm_str, access,
hostname,
portnum,
user ? "-l" : "",
user ? user : "");
}
else
{
sprintf(command, "%s -e %s %s %s %s", xterm_str, access,
hostname,
user ? "-l" : "",
user ? user : "");
}
}
else
{
/* For telnet, -l isn't safe to use at all -- most platforms
don't understand it. */
if ((port)&&(portnum > 0)&&(portnum < 63336))
{
sprintf(command, "%s -e %s %s %d", xterm_str, access,
hostname, portnum);
}
else
{
sprintf(command, "%s -e %s %s", xterm_str, access,
hostname);
}
}
#ifndef DISABLE_TRACE
if (www2Trace) fprintf(stderr, "HTaccess: Command is: %s\n", command);
#endif
run_a_command(command);
/* No need for application feedback if we're rlogging directly
in... */
if (user && login_protocol != rlogin)
{
char str[200];
/* Sleep to let the xterm get up first.
Otherwise, the popup will get buried. */
sleep (2);
sprintf (str, "When you are connected, log in as '%s'.", user);
application_user_feedback (str);
}
return HT_NO_DATA; /* Ok - it was done but 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 occured.
** >=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)
**
*/
PRIVATE int HTLoadTelnet
ARGS4
(
WWW_CONST char *, addr,
HTParentAnchor *, anchor,
HTFormat, format_out,
HTStream *, sink /* Ignored */
)
{
char * access;
char * host;
int status;
if (sink)
{
HTAlert("Can't output a live session -- it has to be interactive");
return HT_NO_ACCESS;
}
access = HTParse(addr, "file:", PARSE_ACCESS);
host = HTParse(addr, "", PARSE_HOST);
status = remote_session(access, host);
free(host);
free(access);
return status;
}
PUBLIC HTProtocol HTTelnet = { "telnet", HTLoadTelnet, NULL };
PUBLIC HTProtocol HTRlogin = { "rlogin", HTLoadTelnet, NULL };
PUBLIC HTProtocol HTTn3270 = { "tn3270", HTLoadTelnet, NULL };