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