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