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