Annotation of libwww/Library/src/HTTelnet.c, revision 2.14
2.14 ! frystyk 1: /* HTTelnet.c
! 2: ** TELNET ACCESS, ROLIGIN, etc.
! 3: **
! 4: ** (c) COPYRIGHT CERN 1994.
! 5: ** Please first read the full copyright statement in the file COPYRIGH.
1.1 timbl 6: **
7: ** Authors
8: ** TBL Tim Berners-Lee timbl@info.cern.ch
9: ** JFG Jean-Francois Groff jgh@next.com
10: ** DD Denis DeLaRoca (310) 825-4580 <CSP1DWD@mvs.oac.ucla.edu>
11: ** History
12: ** 8 Jun 92 Telnet hopping prohibited as telnet is not secure (TBL)
13: ** 26 Jun 92 When over DECnet, suppressed FTP, Gopher and News. (JFG)
14: ** 6 Oct 92 Moved HTClientHost and logfile into here. (TBL)
15: ** 17 Dec 92 Tn3270 added, bug fix. (DD)
16: ** 2 Feb 93 Split from HTAccess.c. Registration.(TBL)
2.11 luotonen 17: ** 2 May 94 Fixed security hole with illegal characters in host
18: ** and user names (code from Mosaic/Eric Bina).
1.1 timbl 19: */
20:
21: #include "HTParse.h"
22: #include "HTUtils.h"
23: #include "HTAnchor.h"
24: #include "HTFile.h"
25: #include "HTAccess.h"
1.3 timbl 26: #include "HTAlert.h"
1.1 timbl 27:
2.12 frystyk 28: #include "HTTelnet.h" /* Implemented here */
1.1 timbl 29:
2.12 frystyk 30: /* ------------------------------------------------------------------------- */
1.1 timbl 31:
2.11 luotonen 32: /* make a string secure for passage to the
33: ** system() command. Make it contain only alphanumneric
34: ** characters, or the characters '.', '-', '_', '+'.
35: ** Also remove leading '-' or '+'.
36: ** -----------------------------------------------------
37: ** Function taken from Mosaic's HTTelnet.c.
38: */
39: PRIVATE void make_system_secure ARGS1(char *, str)
40: {
41: char *ptr1, *ptr2;
42:
43: if ((str == NULL)||(*str == '\0'))
44: {
45: return;
46: }
47:
48: /*
49: * remove leading '-' or '+' by making it into whitespace that
50: * will be stripped later.
51: */
52: if ((*str == '-')||(*str == '+'))
53: {
54: *str = ' ';
55: }
56:
57: ptr1 = ptr2 = str;
58:
59: while (*ptr1 != '\0')
60: {
61: if ((!isalpha((int)*ptr1))&&(!isdigit((int)*ptr1))&&
62: (*ptr1 != '.')&&(*ptr1 != '_')&&
63: (*ptr1 != '+')&&(*ptr1 != '-'))
64: {
65: ptr1++;
66: }
67: else
68: {
69: *ptr2 = *ptr1;
70: ptr2++;
71: ptr1++;
72: }
73: }
74: *ptr2 = *ptr1;
75: }
76:
77:
78:
1.1 timbl 79: /* Telnet or "rlogin" access
80: ** -------------------------
81: */
82: PRIVATE int remote_session ARGS2(char *, access, char *, host)
83: {
84: char * user = host;
85: char * hostname = strchr(host, '@');
86: char * port = strchr(host, ':');
87: char command[256];
88: enum _login_protocol { telnet, rlogin, tn3270 } login_protocol =
89: strcmp(access, "rlogin") == 0 ? rlogin :
90: strcmp(access, "tn3270") == 0 ? tn3270 : telnet;
91:
92: if (hostname) {
93: *hostname++ = 0; /* Split */
94: } else {
95: hostname = host;
96: user = 0; /* No user specified */
97: }
98: if (port) *port++ = 0; /* Split */
99:
2.11 luotonen 100: /*
101: * Make user and hostname secure by removing leading '-' or '+'.
102: * and allowing only alphanumeric, '.', '_', '+', and '-'.
103: */
104: make_system_secure(user);
105: make_system_secure(hostname);
1.1 timbl 106:
107: /* If the person is already telnetting etc, forbid hopping */
108: /* This is a security precaution, for us and remote site */
109:
2.6 timbl 110: if (HTSecure) {
1.1 timbl 111:
112: #ifdef TELNETHOPPER_MAIL
113: sprintf(command,
114: "finger @%s | mail -s \"**telnethopper %s\" tbl@dxcern.cern.ch",
115: HTClientHost, HTClientHost);
116: system(command);
117: #endif
118: printf("\n\nSorry, but the service you have selected is one\n");
119: printf("to which you have to log in. If you were running www\n");
120: printf("on your own computer, you would be automatically connected.\n");
121: printf("For security reasons, this is not allowed when\n");
122: printf("you log in to this information service remotely.\n\n");
123:
124: printf("You can manually connect to this service using %s\n",
125: access);
126: printf("to host %s", hostname);
127: if (user) printf(", user name %s", user);
128: if (port) printf(", port %s", port);
129: printf(".\n\n");
130: return HT_NO_DATA;
131: }
132:
133: /* Not all telnet servers get it even if user name is specified
134: ** so we always tell the guy what to log in as
135: */
136: if (user) printf("When you are connected, log in as %s\n", user);
137:
138: #ifdef NeXT
139: #define TELNET_MINUS_L
140: #endif
141: #ifdef ultrix
142: #define TELNET_MINUS_L
143: #endif
144:
145: #ifdef TELNET_MINUS_L
146: sprintf(command, "%s%s%s %s %s", access,
147: user ? " -l " : "",
148: user ? user : "",
149: hostname,
150: port ? port : "");
151:
152: if (TRACE) fprintf(stderr, "HTaccess: Command is: %s\n", command);
153: system(command);
154: return HT_NO_DATA; /* Ok - it was done but no data */
155: #define TELNET_DONE
1.2 timbl 156: #endif
1.1 timbl 157:
158: /* Most unix machines suppport username only with rlogin */
159: #ifdef unix
160: #ifndef TELNET_DONE
161: if (login_protocol != rlogin) {
162: sprintf(command, "%s %s %s", access,
163: hostname,
164: port ? port : "");
165: } else {
166: sprintf(command, "%s%s%s %s %s", access,
167: user ? " -l " : "",
168: user ? user : "",
169: hostname,
170: port ? port : "");
171: }
172: if (TRACE) fprintf(stderr, "HTaccess: Command is: %s\n", command);
173: system(command);
174: return HT_NO_DATA; /* Ok - it was done but no data */
175: #define TELNET_DONE
176: #endif
177: #endif
178:
179: #ifdef MULTINET /* VMS varieties */
180: if (login_protocol == telnet) {
181: sprintf(command, "TELNET %s%s %s",
182: port ? "/PORT=" : "",
183: port ? port : "",
184: hostname);
185: } else if (login_protocol == tn3270) {
2.8 duns 186: sprintf(command, "TELNET/TN3270 %s%s %s",
1.1 timbl 187: port ? "/PORT=" : "",
188: port ? port : "",
189: hostname);
190: } else {
2.7 timbl 191: sprintf(command, "RLOGIN%s%s%s%s %s", /*lm 930713 */
1.1 timbl 192: user ? "/USERNAME=" : "",
193: user ? user : "",
194: port ? "/PORT=" : "",
195: port ? port : "",
196: hostname);
197: }
198: if (TRACE) fprintf(stderr, "HTaccess: Command is: %s\n", command);
199: system(command);
200: return HT_NO_DATA; /* Ok - it was done but no data */
201: #define TELNET_DONE
202: #endif
203:
204: #ifdef UCX
205: #define SIMPLE_TELNET
206: #endif
207: #ifdef VM
208: #define SIMPLE_TELNET
209: #endif
210: #ifdef SIMPLE_TELNET
211: if (login_protocol == telnet) { /* telnet only */
212: sprintf(command, "TELNET %s", /* @@ Bug: port ignored */
213: hostname);
214: if (TRACE) fprintf(stderr, "HTaccess: Command is: %s\n", command);
215: system(command);
216: return HT_NO_DATA; /* Ok - it was done but no data */
217: }
218: #endif
219:
220: #ifndef TELNET_DONE
221: fprintf(stderr,
222: "Sorry, this browser was compiled without the %s access option.\n",
223: access);
224: fprintf(stderr,
225: "\nTo access the information you must %s to %s", access, hostname);
226: if (port) fprintf(stderr," (port %s)", port);
227: if (user) fprintf(stderr," logging in with username %s", user);
228: fprintf(stderr, ".\n");
229: return -1;
230: #endif
231: }
232:
233: /* "Load a document" -- establishes a session
234: ** ------------------------------------------
235: **
236: ** On entry,
237: ** addr must point to the fully qualified hypertext reference.
238: **
239: ** On exit,
240: ** returns <0 Error has occured.
241: ** >=0 Value of file descriptor or socket to be used
242: ** to read data.
243: ** *pFormat Set to the format of the file, if known.
244: ** (See WWW.h)
245: **
246: */
2.9 timbl 247: PRIVATE int HTLoadTelnet ARGS1(HTRequest *, request)
1.1 timbl 248: {
1.2 timbl 249: char * access;
2.9 timbl 250: CONST char * addr = HTAnchor_physical(request->anchor);
1.2 timbl 251: char * host;
252: int status;
2.10 luotonen 253:
2.9 timbl 254: if (request->output_stream) {
1.2 timbl 255: HTAlert("Can't output a live session -- it has to be interactive");
256: return HT_NO_ACCESS;
257: }
258: access = HTParse(addr, "file:", PARSE_ACCESS);
1.1 timbl 259:
1.2 timbl 260: host = HTParse(addr, "", PARSE_HOST);
2.10 luotonen 261:
262: /*
263: * Fix a security hole with telnet: URLs that contain semicolon
264: * after the machine name. This would cause system commands to
265: * be executed after the telnet session is finished, e.g.
266: *
267: * telnet://some.host; rm some_important_file
268: *
269: * or even more destructive:
270: *
271: * telnet://some.host; rm -fr * (don't try this!!)
272: */
273: {
274: char * semi = strchr(host,';');
275: if (semi) *semi = 0;
276: }
277:
1.2 timbl 278: status = remote_session(access, host);
1.1 timbl 279:
280: free(host);
281: free(access);
282: return status;
283: }
284:
285:
2.13 frystyk 286: GLOBALDEF PUBLIC HTProtocol HTTelnet = {
287: "telnet", SOC_BLOCK, HTLoadTelnet, NULL, NULL
288: };
289:
290: GLOBALDEF PUBLIC HTProtocol HTRlogin = {
291: "rlogin", SOC_BLOCK, HTLoadTelnet, NULL, NULL
292: };
293:
294: GLOBALDEF PUBLIC HTProtocol HTTn3270 = {
295: "tn3270", SOC_BLOCK, HTLoadTelnet, NULL, NULL
296: };
1.1 timbl 297:
298:
Webmaster