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