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