Handle hostnames with upper-case letters
[webmin.git] / telnet / index.cgi
1 #!/usr/local/bin/perl
2 # index.cgi
3 # Display the telnet applet
4
5 BEGIN { push(@INC, ".."); };
6 use WebminCore;
7 use Socket;
8
9 &init_config();
10 $theme_no_table = 1 if ($config{'sizemode'} == 1);
11 &ui_print_header(undef, $text{'index_title'}, "", undef, 1, 1);
12
13 if ($ENV{'HTTPS'} eq 'ON' && !$config{'mode'}) {
14         print "<center><font color=#ff0000>$text{'index_warn'}",
15               "</font></center><br>\n";
16         }
17
18 # Work out real host and port
19 $addr = $config{'host'} || $ENV{'SERVER_NAME'} ||
20         &to_ipaddress(&get_system_hostname());
21 $port = $config{'port'} ? $config{'port'} :
22         $config{'mode'} ? 22 : 23;
23
24 if ($config{'no_test'}) {
25         # Just assume that the telnet server is running
26         $rv = 1;
27         }
28 else {
29         # Check if the telnet server is running
30         $ip = &to_ipaddress($addr) || &to_ip6address($addr);
31         if ($ip) {
32                 $SIG{ALRM} = "connect_timeout";
33                 alarm(10);
34                 &open_socket($ip, $port, STEST, \$err);
35                 close(STEST);
36                 $rv = !$err;
37                 }
38         }
39 if (!$rv) {
40         # Not running! Show an error
41         if ($ip) {
42                 print "<p>",&text(
43                         $config{'mode'} ? 'index_esocket2' : 'index_esocket',
44                         $addr, $port),"<p>\n";
45                 }
46         else {
47                 print "<p>",&text('index_elookup', $addr),"<p>\n";
48                 }
49         }
50 else {
51         # If the host is not local, start up a proxy sub-process
52         if ($config{'proxy'}) {
53                 # Allocate a free port
54                 &get_miniserv_config(\%miniserv);
55                 $proxyport = $miniserv{'port'} + 1;
56                 $err = &allocate_socket(MAIN, \$proxyport);
57                 &error($err) if ($err);
58
59                 # Connect to the destination
60                 &open_socket($addr, $port, CONN);
61
62                 # Forward traffic in sub-process
63                 if (!($pid = fork())) {
64                         # Accept the connection (for up to 60 secs)
65                         $rmask = undef;
66                         vec($rmask, fileno(MAIN), 1) = 1;
67                         $sel = select($rmask, undef, undef, 60);
68                         $sel >= 0 || die "no connection after 60 seconds";
69                         $acptaddr = accept(SOCK, MAIN);
70                         $acptaddr || die "accept failed?!";
71                         close(MAIN);
72
73                         untie(*STDIN);
74                         untie(*STDOUT);
75                         #untie(*STDERR);
76                         close(STDIN);
77                         close(STDOUT);
78                         #close(STDERR);
79
80                         # Forward traffic in and out
81                         select(CONN); $| = 1;
82                         select(SOCK); $| = 1;
83                         while(1) {
84                                 $rmask = undef;
85                                 vec($rmask, fileno(SOCK), 1) = 1;
86                                 vec($rmask, fileno(CONN), 1) = 1;
87                                 $sel = select($rmask, undef, undef, undef);
88
89                                 if (vec($rmask, fileno(SOCK), 1)) {
90                                         # Read from applet, send to server
91                                         $got = sysread(SOCK, $buf, 1024);
92                                         $got > 0 || last;
93                                         syswrite(CONN, $buf, $got);
94                                         }
95
96                                 if (vec($rmask, fileno(CONN), 1)) {
97                                         # Read from applet, send to server
98                                         $got = sysread(CONN, $buf, 1024);
99                                         $got > 0 || last;
100                                         syswrite(SOCK, $buf, $got);
101                                         }
102                                 }
103                         print STDERR "exited read loop\n";
104                         exit(0);
105                         }
106
107                 $SIG{'CHLD'} = \&child_reaper;
108                 close(CONN);
109                 close(MAIN);
110
111                 # Force applet to connect to proxy
112                 $config{'port'} = $proxyport;
113                 delete($config{'host'});
114                 }
115
116         # Output the applet
117         print "<center>\n";
118         if ($config{'detach'}) {
119                 $w = 100; $h = 50;
120                 }
121         elsif ($config{'sizemode'} == 2 &&
122             $config{'size'} =~ /^(\d+)\s*x\s*(\d+)$/) {
123                 $w = $1; $h = $2;
124                 }
125         elsif ($config{'sizemode'} == 1) {
126                 $w = "100%"; $h = "80%";
127                 }
128         else {
129                 $w = 590; $h = 360;
130                 }
131         $jar = "jta26.jar";
132         print "<applet archive=\"$jar\" code=de.mud.jta.Applet ",
133               "width=$w height=$h>\n";
134         printf "<param name=config value=%s>\n",
135                 $config{'mode'} ? "ssh.conf" : "telnet.conf";
136         if ($config{'port'}) {
137                 print "<param name=Socket.port value=$config{'port'}>\n";
138                 }
139         if ($config{'host'}) {
140                 print "<param name=Socket.host value=$config{'host'}>\n";
141                 }
142         else {
143                 print "<param name=Socket.host value=$ENV{'SERVER_NAME'}>\n";
144                 }
145         if ($config{'script'}) {
146                 print "<param name=Script.script value='$config{'script'}'>\n";
147                 }
148         if ($config{'sizemode'}) {
149                 print "<param name=Terminal.resize value='screen'>\n";
150                 }
151         if ($config{'fontsize'}) {
152                 print "<param name=Terminal.fontSize value='$config{'fontsize'}'>\n";
153                 }
154         if ($config{'detach'}) {
155                 print "<param name=Applet.detach value='true'>\n";
156                 print "<param name=Applet.detach.stopText value='Disconnect'>\n";
157                 }
158         print "$text{'index_nojava'} <p>\n";
159         print "</applet><br>\n";
160
161         print &text('index_credits',
162                     "http://www.mud.de/se/jta/"),"<br>\n";
163         if ($config{'mode'}) {
164                 print &text('index_sshcredits',
165                             "http://www.systemics.com/docs/cryptix/"),"<br>\n";
166                 }
167         print "</center>\n";
168         }
169
170 &ui_print_footer("/", $text{'index'});
171
172 sub connect_timeout
173 {
174 }
175
176 # allocate_socket(handle, &port)
177 sub allocate_socket
178 {
179 local ($fh, $port) = @_;
180 local $proto = getprotobyname('tcp');
181 if (!socket($fh, PF_INET, SOCK_STREAM, $proto)) {
182         return "socket failed : $!";
183         }
184 setsockopt($fh, SOL_SOCKET, SO_REUSEADDR, pack("l", 1));
185 while(1) {
186         $$port++;
187         last if (bind($fh, sockaddr_in($$port, INADDR_ANY)));
188         }
189 listen($fh, SOMAXCONN);
190 return undef;
191 }
192
193 sub child_reaper
194 {
195 local $xp;
196 do {
197         $xp = waitpid(-1, WNOHANG);
198         } while($xp > 0);
199 }
200
201