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