Annotation of libwww/Library/src/HTTelnet.c, revision 2.37
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 ! frystyk 6: ** @(#) $Id: HTTelnet.c,v 2.36 1996/04/12 17:49:28 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 */
1.1 timbl 28:
2.12 frystyk 29: /* ------------------------------------------------------------------------- */
1.1 timbl 30:
2.11 luotonen 31: /* make a string secure for passage to the
32: ** system() command. Make it contain only alphanumneric
33: ** characters, or the characters '.', '-', '_', '+'.
34: ** Also remove leading '-' or '+'.
35: ** -----------------------------------------------------
36: ** Function taken from Mosaic's HTTelnet.c.
37: */
2.28 frystyk 38: PRIVATE void make_system_secure (char * str)
2.11 luotonen 39: {
2.21 frystyk 40: char *ptr1, *ptr2;
41: if ((str == NULL)||(*str == '\0'))
42: return;
2.11 luotonen 43:
2.21 frystyk 44: /*
45: * remove leading '-' or '+' by making it into whitespace that
46: * will be stripped later.
47: */
48: if (*str=='-' || *str=='+')
49: *str = ' ';
50: ptr1 = ptr2 = str;
51: while (*ptr1) {
52: if ((!isalpha((int)*ptr1))&&(!isdigit((int)*ptr1))&&
53: (*ptr1 != '.')&&(*ptr1 != '_')&&
54: (*ptr1 != '+')&&(*ptr1 != '-')) {
55: ptr1++;
56: } else {
57: *ptr2 = *ptr1;
58: ptr2++;
59: ptr1++;
2.11 luotonen 60: }
2.21 frystyk 61: }
62: *ptr2 = *ptr1;
2.11 luotonen 63: }
64:
1.1 timbl 65: /* Telnet or "rlogin" access
66: ** -------------------------
2.27 frystyk 67: ** Returns HT_NO_DATA OK
68: ** HT_ERROR Error
1.1 timbl 69: */
2.28 frystyk 70: PRIVATE int remote_session (HTRequest * request, char * url)
1.1 timbl 71: {
2.21 frystyk 72: int status = HT_NO_DATA;
2.32 frystyk 73: HTChunk *cmd = HTChunk_new(64);
2.21 frystyk 74: char *access = HTParse(url, "", PARSE_ACCESS);
75: char *host = HTParse(url, "", PARSE_HOST);
76: char *hostname = strchr(host, '@');
77: char *user = NULL;
78: char *passwd = NULL;
79: char *port = NULL;
80:
2.27 frystyk 81: /* We must be in interactive mode */
2.31 frystyk 82: if (!HTAlert_interactive()) {
2.34 eric 83: if (PROT_TRACE) HTTrace("Telnet...... Not interactive\n");
2.33 frystyk 84: HT_FREE(access);
85: HT_FREE(host);
2.32 frystyk 86: HTChunk_delete(cmd);
2.27 frystyk 87: return HT_ERROR;
88: }
89:
2.21 frystyk 90: /* Look for user name, password, and port number */
91: if (hostname) {
92: *hostname++ = '\0';
93: user = host;
94: if ((passwd = strchr(host, ':')) != NULL) {
95: *passwd++ = '\0';
96: HTUnEscape(passwd);
97: }
98: HTUnEscape(user); /* Might have a funny userid */
99: } else {
100: hostname = host;
101: }
102: if ((port = strchr(hostname, ':')) != NULL)
103: *port++ = '\0';
104:
105: /* If the person is already telnetting etc, forbid hopping */
2.30 frystyk 106: if (HTLib_secure()) {
2.31 frystyk 107: HTRequest_addError(request, ERR_FATAL, NO,
108: HTERR_ACCESS, NULL, 0, "HTLoadTelnet");
2.33 frystyk 109: HT_FREE(access);
110: HT_FREE(host);
2.32 frystyk 111: HTChunk_delete(cmd);
2.21 frystyk 112: return HT_NO_DATA;
113: }
114:
115: /*
116: ** Make user and hostname secure by removing leading '-' or '+'.
117: ** and allowing only alphanumeric, '.', '_', '+', and '-'.
118: */
119: make_system_secure(user);
120: make_system_secure(passwd);
121: make_system_secure(hostname);
122: make_system_secure(port);
123:
2.27 frystyk 124: if (!strcasecomp(access, "telnet")) {
2.21 frystyk 125: #ifdef SIMPLE_TELNET
2.32 frystyk 126: HTChunk_puts(cmd, "TELNET ");
127: HTChunk_puts(cmd, hostname); /* Port is ignored */
2.21 frystyk 128: #else
2.26 frystyk 129: #ifdef FULL_TELNET /* User and port */
2.32 frystyk 130: HTChunk_puts(cmd, "telnet ");
131: HTChunk_puts(cmd, hostname);
2.26 frystyk 132: if (user) {
2.32 frystyk 133: HTChunk_puts(cmd, " -l ");
134: HTChunk_puts(cmd, user);
2.26 frystyk 135: }
136: if (port) {
2.32 frystyk 137: HTChunk_putc(cmd, ' ');
138: HTChunk_puts(cmd, port);
2.26 frystyk 139: }
140: #else
2.21 frystyk 141: #ifdef MULTINET
2.32 frystyk 142: HTChunk_puts(cmd, "TELNET ");
2.21 frystyk 143: if (port) {
2.32 frystyk 144: HTChunk_puts(cmd, "/PORT=");
145: HTChunk_puts(cmd, port);
146: HTChunk_putc(cmd, ' ');
2.21 frystyk 147: }
2.32 frystyk 148: HTChunk_puts(cmd, hostname);
2.26 frystyk 149: #else /* User is ignored */
2.32 frystyk 150: HTChunk_puts(cmd, "telnet ");
151: HTChunk_puts(cmd, hostname);
2.21 frystyk 152: if (port) {
2.32 frystyk 153: HTChunk_putc(cmd, ' ');
154: HTChunk_puts(cmd, port);
2.21 frystyk 155: }
156: #endif /* MULTINET */
2.26 frystyk 157: #endif /* FULL_TELNET */
2.21 frystyk 158: #endif /* SIMPLE_TELNET */
159:
2.27 frystyk 160: } else if (!strcasecomp(access, "rlogin")) {
2.21 frystyk 161: #ifdef MULTINET
2.32 frystyk 162: HTChunk_puts(cmd, "RLOGIN ");
2.21 frystyk 163: if (user) {
2.32 frystyk 164: HTChunk_puts(cmd, "/USERNAME=");
165: HTChunk_puts(cmd, user);
166: HTChunk_putc(cmd, ' ');
2.21 frystyk 167: }
168: if (port) {
2.32 frystyk 169: HTChunk_puts(cmd, "/PORT=");
170: HTChunk_puts(cmd, port);
171: HTChunk_putc(cmd, ' ');
2.21 frystyk 172: }
2.32 frystyk 173: HTChunk_puts(cmd, hostname);
2.21 frystyk 174: #else
175: #ifdef RLOGIN_USER /* format: "hostname -l user" */
2.32 frystyk 176: HTChunk_puts(cmd, "rlogin ");
177: HTChunk_puts(cmd, hostname);
2.21 frystyk 178: if (user) {
2.32 frystyk 179: HTChunk_puts(cmd, " -l ");
180: HTChunk_puts(cmd, user);
2.21 frystyk 181: }
182: #else /* format: "-l user hostname" */
2.32 frystyk 183: HTChunk_puts(cmd, "rlogin ");
2.21 frystyk 184: if (user) {
2.32 frystyk 185: HTChunk_puts(cmd, "-l ");
186: HTChunk_puts(cmd, user);
187: HTChunk_putc(cmd, ' ');
2.21 frystyk 188: }
2.32 frystyk 189: HTChunk_puts(cmd, hostname);
2.21 frystyk 190: #endif /* RLOGIN_AFTER */
191: #endif /* MULTINET */
192:
2.27 frystyk 193: } else if (!strcasecomp(access, "tn3270")) {
2.21 frystyk 194: #ifdef MULTINET
2.32 frystyk 195: HTChunk_puts(cmd, "TELNET/TN3270 ");
2.21 frystyk 196: if (port) {
2.32 frystyk 197: HTChunk_puts(cmd, "/PORT=");
198: HTChunk_puts(cmd, port);
199: HTChunk_putc(cmd, ' ');
1.1 timbl 200: }
2.32 frystyk 201: HTChunk_puts(cmd, hostname);
2.21 frystyk 202: #else
2.32 frystyk 203: HTChunk_puts(cmd, "tn3270 ");
204: HTChunk_puts(cmd, hostname); /* Port is ignored */
2.21 frystyk 205: #endif /* MULTINET */
206:
207: } else {
208: if (PROT_TRACE)
2.34 eric 209: HTTrace("Telnet...... Unknown access method: `%s\'\n",
2.21 frystyk 210: access);
211: status = HT_ERROR;
212: }
1.1 timbl 213:
2.21 frystyk 214: /* Now we are ready to execute the command */
215: if (PROT_TRACE)
2.34 eric 216: HTTrace("Telnet...... Command is `%s\'\n", cmd->data);
2.21 frystyk 217: if (user) {
2.32 frystyk 218: HTChunk *msg = HTChunk_new(128);
2.27 frystyk 219: if (strcasecomp(access, "rlogin")) {
2.32 frystyk 220: HTChunk_puts(msg, "user <");
221: HTChunk_puts(msg, user);
222: HTChunk_putc(msg, '>');
2.21 frystyk 223: }
224: if (passwd) {
2.32 frystyk 225: HTChunk_puts(msg, " and password <");
226: HTChunk_puts(msg, passwd);
227: HTChunk_putc(msg, '>');
1.1 timbl 228: }
2.31 frystyk 229: HTRequest_addError(request, ERR_INFO, NO,
2.32 frystyk 230: HTERR_LOGIN, HTChunk_data(msg), HTChunk_size(msg),
2.31 frystyk 231: "HTLoadTelnet");
2.32 frystyk 232: HTChunk_delete(msg);
2.21 frystyk 233: }
2.35 frystyk 234: #ifdef HAVE_SYSTEM
2.21 frystyk 235: system(cmd->data);
2.29 frystyk 236: #endif
2.33 frystyk 237: HT_FREE(access);
238: HT_FREE(host);
2.32 frystyk 239: HTChunk_delete(cmd);
2.21 frystyk 240: return status;
1.1 timbl 241:
242: }
243:
244: /* "Load a document" -- establishes a session
2.21 frystyk 245: ** ==========================================
1.1 timbl 246: **
247: ** On entry,
2.21 frystyk 248: ** request This is the request structure
1.1 timbl 249: ** On exit,
2.21 frystyk 250: ** returns HT_ERROR Error has occured or interrupted
251: ** HT_NO_DATA if return status 204 No Response
1.1 timbl 252: */
2.28 frystyk 253: PUBLIC int HTLoadTelnet (SOCKET soc, HTRequest * request, SockOps ops)
1.1 timbl 254: {
2.37 ! frystyk 255: HTNet * net = HTRequest_net(request);
! 256: HTParentAnchor * anchor = HTRequest_anchor(request);
! 257: char * url = HTAnchor_physical(anchor);
2.10 luotonen 258:
2.27 frystyk 259: /* This is a trick as we don't have any socket! */
260: if (ops == FD_NONE) {
2.34 eric 261: if (PROT_TRACE) HTTrace("Telnet...... Looking for `%s\'\n",url);
2.27 frystyk 262: HTCleanTelnetString(url);
263: {
264: int status = remote_session(request, url);
2.37 ! frystyk 265: HTNet_delete(net, status);
2.27 frystyk 266: }
267: } else if (ops == FD_CLOSE) /* Interrupted */
2.37 ! frystyk 268: HTNet_delete(net, HT_INTERRUPTED);
2.27 frystyk 269: else
2.37 ! frystyk 270: HTNet_delete(net, HT_ERROR);
2.27 frystyk 271: return HT_OK;
1.1 timbl 272: }
273:
274:
Webmaster