Annotation of libwww/Library/src/HTTelnet.c, revision 2.37.2.1
2.14 frystyk 1: /* HTTelnet.c
2: ** TELNET ACCESS, ROLIGIN, etc.
3: **
2.17 frystyk 4: ** (c) COPYRIGHT MIT 1995.
2.14 frystyk 5: ** Please first read the full copyright statement in the file COPYRIGH.
2.37.2.1! eric 6: ** @(#) $Id: HTTelnet.c,v 2.37 1996/06/02 00:35:03 frystyk Exp $
1.1 timbl 7: **
8: ** Authors
2.20 frystyk 9: ** TBL Tim Berners-Lee timbl@w3.org
1.1 timbl 10: ** JFG Jean-Francois Groff jgh@next.com
11: ** DD Denis DeLaRoca (310) 825-4580 <CSP1DWD@mvs.oac.ucla.edu>
2.21 frystyk 12: ** HFN Henrik Frystyk
1.1 timbl 13: ** History
14: ** 8 Jun 92 Telnet hopping prohibited as telnet is not secure (TBL)
15: ** 26 Jun 92 When over DECnet, suppressed FTP, Gopher and News. (JFG)
16: ** 6 Oct 92 Moved HTClientHost and logfile into here. (TBL)
17: ** 17 Dec 92 Tn3270 added, bug fix. (DD)
18: ** 2 Feb 93 Split from HTAccess.c. Registration.(TBL)
2.11 luotonen 19: ** 2 May 94 Fixed security hole with illegal characters in host
20: ** and user names (code from Mosaic/Eric Bina).
1.1 timbl 21: */
22:
2.16 frystyk 23: /* Library include files */
2.35 frystyk 24: #include "sysdep.h"
2.37 frystyk 25: #include "WWWUtil.h"
26: #include "WWWCore.h"
2.12 frystyk 27: #include "HTTelnet.h" /* Implemented here */
2.37.2.1! eric 28: #include "HTNetMan.h"
1.1 timbl 29:
2.12 frystyk 30: /* ------------------------------------------------------------------------- */
1.1 timbl 31:
2.11 luotonen 32: /* make a string secure for passage to the
33: ** system() command. Make it contain only alphanumneric
34: ** characters, or the characters '.', '-', '_', '+'.
35: ** Also remove leading '-' or '+'.
36: ** -----------------------------------------------------
37: ** Function taken from Mosaic's HTTelnet.c.
38: */
2.28 frystyk 39: PRIVATE void make_system_secure (char * str)
2.11 luotonen 40: {
2.21 frystyk 41: char *ptr1, *ptr2;
42: if ((str == NULL)||(*str == '\0'))
43: return;
2.11 luotonen 44:
2.21 frystyk 45: /*
46: * remove leading '-' or '+' by making it into whitespace that
47: * will be stripped later.
48: */
49: if (*str=='-' || *str=='+')
50: *str = ' ';
51: ptr1 = ptr2 = str;
52: while (*ptr1) {
53: if ((!isalpha((int)*ptr1))&&(!isdigit((int)*ptr1))&&
54: (*ptr1 != '.')&&(*ptr1 != '_')&&
55: (*ptr1 != '+')&&(*ptr1 != '-')) {
56: ptr1++;
57: } else {
58: *ptr2 = *ptr1;
59: ptr2++;
60: ptr1++;
2.11 luotonen 61: }
2.21 frystyk 62: }
63: *ptr2 = *ptr1;
2.11 luotonen 64: }
65:
1.1 timbl 66: /* Telnet or "rlogin" access
67: ** -------------------------
2.27 frystyk 68: ** Returns HT_NO_DATA OK
69: ** HT_ERROR Error
1.1 timbl 70: */
2.28 frystyk 71: PRIVATE int remote_session (HTRequest * request, char * url)
1.1 timbl 72: {
2.21 frystyk 73: int status = HT_NO_DATA;
2.32 frystyk 74: HTChunk *cmd = HTChunk_new(64);
2.21 frystyk 75: char *access = HTParse(url, "", PARSE_ACCESS);
76: char *host = HTParse(url, "", PARSE_HOST);
77: char *hostname = strchr(host, '@');
78: char *user = NULL;
79: char *passwd = NULL;
80: char *port = NULL;
81:
2.27 frystyk 82: /* We must be in interactive mode */
2.31 frystyk 83: if (!HTAlert_interactive()) {
2.34 eric 84: if (PROT_TRACE) HTTrace("Telnet...... Not interactive\n");
2.33 frystyk 85: HT_FREE(access);
86: HT_FREE(host);
2.32 frystyk 87: HTChunk_delete(cmd);
2.27 frystyk 88: return HT_ERROR;
89: }
90:
2.21 frystyk 91: /* Look for user name, password, and port number */
92: if (hostname) {
93: *hostname++ = '\0';
94: user = host;
95: if ((passwd = strchr(host, ':')) != NULL) {
96: *passwd++ = '\0';
97: HTUnEscape(passwd);
98: }
99: HTUnEscape(user); /* Might have a funny userid */
100: } else {
101: hostname = host;
102: }
103: if ((port = strchr(hostname, ':')) != NULL)
104: *port++ = '\0';
105:
106: /* If the person is already telnetting etc, forbid hopping */
2.30 frystyk 107: if (HTLib_secure()) {
2.31 frystyk 108: HTRequest_addError(request, ERR_FATAL, NO,
109: HTERR_ACCESS, NULL, 0, "HTLoadTelnet");
2.33 frystyk 110: HT_FREE(access);
111: HT_FREE(host);
2.32 frystyk 112: HTChunk_delete(cmd);
2.21 frystyk 113: return HT_NO_DATA;
114: }
115:
116: /*
117: ** Make user and hostname secure by removing leading '-' or '+'.
118: ** and allowing only alphanumeric, '.', '_', '+', and '-'.
119: */
120: make_system_secure(user);
121: make_system_secure(passwd);
122: make_system_secure(hostname);
123: make_system_secure(port);
124:
2.27 frystyk 125: if (!strcasecomp(access, "telnet")) {
2.21 frystyk 126: #ifdef SIMPLE_TELNET
2.32 frystyk 127: HTChunk_puts(cmd, "TELNET ");
128: HTChunk_puts(cmd, hostname); /* Port is ignored */
2.21 frystyk 129: #else
2.26 frystyk 130: #ifdef FULL_TELNET /* User and port */
2.32 frystyk 131: HTChunk_puts(cmd, "telnet ");
132: HTChunk_puts(cmd, hostname);
2.26 frystyk 133: if (user) {
2.32 frystyk 134: HTChunk_puts(cmd, " -l ");
135: HTChunk_puts(cmd, user);
2.26 frystyk 136: }
137: if (port) {
2.32 frystyk 138: HTChunk_putc(cmd, ' ');
139: HTChunk_puts(cmd, port);
2.26 frystyk 140: }
141: #else
2.21 frystyk 142: #ifdef MULTINET
2.32 frystyk 143: HTChunk_puts(cmd, "TELNET ");
2.21 frystyk 144: if (port) {
2.32 frystyk 145: HTChunk_puts(cmd, "/PORT=");
146: HTChunk_puts(cmd, port);
147: HTChunk_putc(cmd, ' ');
2.21 frystyk 148: }
2.32 frystyk 149: HTChunk_puts(cmd, hostname);
2.26 frystyk 150: #else /* User is ignored */
2.32 frystyk 151: HTChunk_puts(cmd, "telnet ");
152: HTChunk_puts(cmd, hostname);
2.21 frystyk 153: if (port) {
2.32 frystyk 154: HTChunk_putc(cmd, ' ');
155: HTChunk_puts(cmd, port);
2.21 frystyk 156: }
157: #endif /* MULTINET */
2.26 frystyk 158: #endif /* FULL_TELNET */
2.21 frystyk 159: #endif /* SIMPLE_TELNET */
160:
2.27 frystyk 161: } else if (!strcasecomp(access, "rlogin")) {
2.21 frystyk 162: #ifdef MULTINET
2.32 frystyk 163: HTChunk_puts(cmd, "RLOGIN ");
2.21 frystyk 164: if (user) {
2.32 frystyk 165: HTChunk_puts(cmd, "/USERNAME=");
166: HTChunk_puts(cmd, user);
167: HTChunk_putc(cmd, ' ');
2.21 frystyk 168: }
169: if (port) {
2.32 frystyk 170: HTChunk_puts(cmd, "/PORT=");
171: HTChunk_puts(cmd, port);
172: HTChunk_putc(cmd, ' ');
2.21 frystyk 173: }
2.32 frystyk 174: HTChunk_puts(cmd, hostname);
2.21 frystyk 175: #else
176: #ifdef RLOGIN_USER /* format: "hostname -l user" */
2.32 frystyk 177: HTChunk_puts(cmd, "rlogin ");
178: HTChunk_puts(cmd, hostname);
2.21 frystyk 179: if (user) {
2.32 frystyk 180: HTChunk_puts(cmd, " -l ");
181: HTChunk_puts(cmd, user);
2.21 frystyk 182: }
183: #else /* format: "-l user hostname" */
2.32 frystyk 184: HTChunk_puts(cmd, "rlogin ");
2.21 frystyk 185: if (user) {
2.32 frystyk 186: HTChunk_puts(cmd, "-l ");
187: HTChunk_puts(cmd, user);
188: HTChunk_putc(cmd, ' ');
2.21 frystyk 189: }
2.32 frystyk 190: HTChunk_puts(cmd, hostname);
2.21 frystyk 191: #endif /* RLOGIN_AFTER */
192: #endif /* MULTINET */
193:
2.27 frystyk 194: } else if (!strcasecomp(access, "tn3270")) {
2.21 frystyk 195: #ifdef MULTINET
2.32 frystyk 196: HTChunk_puts(cmd, "TELNET/TN3270 ");
2.21 frystyk 197: if (port) {
2.32 frystyk 198: HTChunk_puts(cmd, "/PORT=");
199: HTChunk_puts(cmd, port);
200: HTChunk_putc(cmd, ' ');
1.1 timbl 201: }
2.32 frystyk 202: HTChunk_puts(cmd, hostname);
2.21 frystyk 203: #else
2.32 frystyk 204: HTChunk_puts(cmd, "tn3270 ");
205: HTChunk_puts(cmd, hostname); /* Port is ignored */
2.21 frystyk 206: #endif /* MULTINET */
207:
208: } else {
209: if (PROT_TRACE)
2.34 eric 210: HTTrace("Telnet...... Unknown access method: `%s\'\n",
2.21 frystyk 211: access);
212: status = HT_ERROR;
213: }
1.1 timbl 214:
2.21 frystyk 215: /* Now we are ready to execute the command */
216: if (PROT_TRACE)
2.34 eric 217: HTTrace("Telnet...... Command is `%s\'\n", cmd->data);
2.21 frystyk 218: if (user) {
2.32 frystyk 219: HTChunk *msg = HTChunk_new(128);
2.27 frystyk 220: if (strcasecomp(access, "rlogin")) {
2.32 frystyk 221: HTChunk_puts(msg, "user <");
222: HTChunk_puts(msg, user);
223: HTChunk_putc(msg, '>');
2.21 frystyk 224: }
225: if (passwd) {
2.32 frystyk 226: HTChunk_puts(msg, " and password <");
227: HTChunk_puts(msg, passwd);
228: HTChunk_putc(msg, '>');
1.1 timbl 229: }
2.31 frystyk 230: HTRequest_addError(request, ERR_INFO, NO,
2.32 frystyk 231: HTERR_LOGIN, HTChunk_data(msg), HTChunk_size(msg),
2.31 frystyk 232: "HTLoadTelnet");
2.32 frystyk 233: HTChunk_delete(msg);
2.21 frystyk 234: }
2.35 frystyk 235: #ifdef HAVE_SYSTEM
2.21 frystyk 236: system(cmd->data);
2.29 frystyk 237: #endif
2.33 frystyk 238: HT_FREE(access);
239: HT_FREE(host);
2.32 frystyk 240: HTChunk_delete(cmd);
2.21 frystyk 241: return status;
1.1 timbl 242:
243: }
244:
245: /* "Load a document" -- establishes a session
2.21 frystyk 246: ** ==========================================
1.1 timbl 247: **
248: ** On entry,
2.21 frystyk 249: ** request This is the request structure
1.1 timbl 250: ** On exit,
2.21 frystyk 251: ** returns HT_ERROR Error has occured or interrupted
252: ** HT_NO_DATA if return status 204 No Response
1.1 timbl 253: */
2.37.2.1! eric 254: PRIVATE int TelnetEvent (SOCKET soc, void * pVoid, HTEvent_type type);
! 255:
! 256: PUBLIC int HTLoadTelnet (SOCKET soc, HTRequest * request)
1.1 timbl 257: {
2.37 frystyk 258: HTNet * net = HTRequest_net(request);
259: HTParentAnchor * anchor = HTRequest_anchor(request);
260: char * url = HTAnchor_physical(anchor);
2.10 luotonen 261:
2.37.2.1! eric 262: if (PROT_TRACE) HTTrace("Telnet...... Looking for `%s\'\n",url);
! 263: HTNet_setEventCallback(net, TelnetEvent);
! 264: HTNet_setEventParam(net, net); /* callbacks get http* */
! 265:
! 266: HTCleanTelnetString(url);
! 267: {
! 268: int status = remote_session(request, url);
! 269: HTNet_delete(net, status);
! 270: }
! 271: return HT_OK;
! 272: }
! 273:
! 274: PRIVATE int TelnetEvent (SOCKET soc, void * pVoid, HTEvent_type type)
! 275: {
! 276: HTNet * net = (HTNet *)pVoid;
! 277:
2.27 frystyk 278: /* This is a trick as we don't have any socket! */
2.37.2.1! eric 279: if (type == HTEvent_CLOSE) /* Interrupted */
2.37 frystyk 280: HTNet_delete(net, HT_INTERRUPTED);
2.27 frystyk 281: else
2.37 frystyk 282: HTNet_delete(net, HT_ERROR);
2.27 frystyk 283: return HT_OK;
1.1 timbl 284: }
285:
286:
Webmaster