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