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