Annotation of libwww/Library/src/HTTelnet.c, revision 2.19
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
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:
2.16 frystyk 21: /* Library include files */
22: #include "tcp.h"
23: #include "HTUtils.h"
1.1 timbl 24: #include "HTParse.h"
25: #include "HTAnchor.h"
26: #include "HTAccess.h"
1.3 timbl 27: #include "HTAlert.h"
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: printf("\n\nSorry, but the service you have selected is one\n");
112: printf("to which you have to log in. If you were running www\n");
113: printf("on your own computer, you would be automatically connected.\n");
114: printf("For security reasons, this is not allowed when\n");
115: printf("you log in to this information service remotely.\n\n");
116:
117: printf("You can manually connect to this service using %s\n",
118: access);
119: printf("to host %s", hostname);
120: if (user) printf(", user name %s", user);
121: if (port) printf(", port %s", port);
122: printf(".\n\n");
123: return HT_NO_DATA;
124: }
125:
126: /* Not all telnet servers get it even if user name is specified
127: ** so we always tell the guy what to log in as
128: */
129: if (user) printf("When you are connected, log in as %s\n", user);
2.16 frystyk 130:
131: #ifdef NeXT
132: #define TELNET_MINUS_L
133: #endif
134: #ifdef ultrix
135: #define TELNET_MINUS_L
136: #endif
2.15 roeber 137:
2.16 frystyk 138: #ifdef TELNET_MINUS_L
139: sprintf(command, "%s%s%s %s %s", access,
140: user ? " -l " : "",
141: user ? user : "",
142: hostname,
143: port ? port : "");
144:
145: if (TRACE) fprintf(TDEST, "HTaccess: Command is: %s\n", command);
146: system(command);
147: return HT_NO_DATA; /* Ok - it was done but no data */
148: #define TELNET_DONE
1.1 timbl 149: #endif
2.15 roeber 150:
2.16 frystyk 151: /* Most unix machines suppport username only with rlogin */
152: #ifdef unix
153: #ifndef TELNET_DONE
154: if (login_protocol != rlogin) {
155: sprintf(command, "%s %s %s", access,
156: hostname,
157: port ? port : "");
158: } else {
159: sprintf(command, "%s%s%s %s %s", access,
160: user ? " -l " : "",
161: user ? user : "",
162: hostname,
163: port ? port : "");
164: }
165: if (TRACE) fprintf(TDEST, "HTaccess: Command is: %s\n", command);
166: system(command);
167: return HT_NO_DATA; /* Ok - it was done but no data */
168: #define TELNET_DONE
169: #endif
1.1 timbl 170: #endif
171:
2.16 frystyk 172: #ifdef MULTINET /* VMS varieties */
173: if (login_protocol == telnet) {
174: sprintf(command, "TELNET %s%s %s",
175: port ? "/PORT=" : "",
176: port ? port : "",
177: hostname);
178: } else if (login_protocol == tn3270) {
179: sprintf(command, "TELNET/TN3270 %s%s %s",
180: port ? "/PORT=" : "",
181: port ? port : "",
182: hostname);
183: } else {
184: sprintf(command, "RLOGIN%s%s%s%s %s", /*lm 930713 */
185: user ? "/USERNAME=" : "",
186: user ? user : "",
187: port ? "/PORT=" : "",
188: port ? port : "",
189: hostname);
190: }
191: if (TRACE) fprintf(TDEST, "HTaccess: Command is: %s\n", command);
192: system(command);
193: return HT_NO_DATA; /* Ok - it was done but no data */
194: #define TELNET_DONE
1.2 timbl 195: #endif
1.1 timbl 196:
2.16 frystyk 197: #ifdef UCX
198: #define SIMPLE_TELNET
199: #endif
200: #ifdef VM
201: #define SIMPLE_TELNET
202: #endif
203: #ifdef SIMPLE_TELNET
204: if (login_protocol == telnet) { /* telnet only */
205: sprintf(command, "TELNET %s", /* @@ Bug: port ignored */
206: hostname);
207: if (TRACE) fprintf(TDEST, "HTaccess: Command is: %s\n", command);
208: system(command);
209: return HT_NO_DATA; /* Ok - it was done but no data */
1.1 timbl 210: }
2.16 frystyk 211: #endif
1.1 timbl 212:
2.16 frystyk 213: #ifndef TELNET_DONE
214: fprintf(TDEST,
215: "Sorry, this browser was compiled without the %s access option.\n",
216: access);
217: fprintf(TDEST,
218: "\nTo access the information you must %s to %s", access, hostname);
219: if (port) fprintf(TDEST," (port %s)", port);
220: if (user) fprintf(TDEST," logging in with username %s", user);
221: fprintf(TDEST, ".\n");
222: return -1;
223: #endif
1.1 timbl 224: }
225:
226: /* "Load a document" -- establishes a session
227: ** ------------------------------------------
228: **
229: ** On entry,
230: ** addr must point to the fully qualified hypertext reference.
231: **
232: ** On exit,
233: ** returns <0 Error has occured.
234: ** >=0 Value of file descriptor or socket to be used
235: ** to read data.
236: ** *pFormat Set to the format of the file, if known.
237: ** (See WWW.h)
238: **
239: */
2.9 timbl 240: PRIVATE int HTLoadTelnet ARGS1(HTRequest *, request)
1.1 timbl 241: {
1.2 timbl 242: char * access;
2.9 timbl 243: CONST char * addr = HTAnchor_physical(request->anchor);
1.2 timbl 244: char * host;
245: int status;
2.10 luotonen 246:
2.9 timbl 247: if (request->output_stream) {
1.2 timbl 248: HTAlert("Can't output a live session -- it has to be interactive");
249: return HT_NO_ACCESS;
250: }
251: access = HTParse(addr, "file:", PARSE_ACCESS);
1.1 timbl 252:
1.2 timbl 253: host = HTParse(addr, "", PARSE_HOST);
2.10 luotonen 254:
255: /*
256: * Fix a security hole with telnet: URLs that contain semicolon
257: * after the machine name. This would cause system commands to
258: * be executed after the telnet session is finished, e.g.
259: *
260: * telnet://some.host; rm some_important_file
261: *
262: * or even more destructive:
263: *
264: * telnet://some.host; rm -fr * (don't try this!!)
265: */
266: {
267: char * semi = strchr(host,';');
268: if (semi) *semi = 0;
269: }
270:
1.2 timbl 271: status = remote_session(access, host);
1.1 timbl 272:
273: free(host);
274: free(access);
275: return status;
276: }
277:
278:
2.13 frystyk 279: GLOBALDEF PUBLIC HTProtocol HTTelnet = {
280: "telnet", SOC_BLOCK, HTLoadTelnet, NULL, NULL
281: };
282:
283: GLOBALDEF PUBLIC HTProtocol HTRlogin = {
284: "rlogin", SOC_BLOCK, HTLoadTelnet, NULL, NULL
285: };
286:
287: GLOBALDEF PUBLIC HTProtocol HTTn3270 = {
288: "tn3270", SOC_BLOCK, HTLoadTelnet, NULL, NULL
289: };
1.1 timbl 290:
291:
Webmaster