3 # Forward the URL from path_info on to another webmin server
5 if ($ENV{'PATH_INFO'} =~ /^\/(\d+)\/([a-zA-Z0-9\-\/]+)\.(jar|class|gif|png)$/) {
6 # Allow fetches of Java classes and images without a referer header,
7 # as Java sometimes doesn't provide these
8 $trust_unknown_referers = 1;
12 require './servers-lib.pl';
13 our (%text, %gconfig, %access, $module_name, %tconfig);
14 $ENV{'PATH_INFO'} =~ /^\/(\d+)(.*)$/ ||
15 &error("Bad PATH_INFO : $ENV{'PATH_INFO'}");
17 my $path = $2 ? &urlize("$2") : '/';
19 if ($ENV{'QUERY_STRING'}) {
20 $path .= '?'.$ENV{'QUERY_STRING'};
23 $path .= '?'.join('+', @ARGV);
25 my $s = &get_server($id);
26 &can_use_server($s) || &error($text{'link_ecannot'});
27 $access{'links'} || &error($text{'link_ecannot'});
28 my $url = "$gconfig{'webprefix'}/$module_name/link.cgi/$s->{'id'}";
30 my $meth = $ENV{'REQUEST_METHOD'};
32 &get_miniserv_config(\%miniserv);
35 if ($s->{'autouser'}) {
36 # Login is variable .. check if we have it yet
37 if ($ENV{'HTTP_COOKIE'} =~ /$id=(\S+)/) {
38 # Yes - set the login and password to use
39 ($user, $pass) = split(/:/, &decode_base64("$1"));
42 # No - need to display a login form
43 &ui_print_header(undef, $text{'login_title'}, "");
45 print &text('login_desc', "<tt>$s->{'host'}</tt>"),"<p>\n";
48 "$gconfig{'webprefix'}/$module_name/login.cgi", "post");
49 print &ui_hidden("id", $id);
51 print &ui_table_start($text{'login_header'}, undef, 2);
52 print &ui_table_row($text{'login_user'},
53 &ui_textbox("user", undef, 20));
54 print &ui_table_row($text{'login_pass'},
55 &ui_password("pass", undef, 20));
56 print &ui_table_end();
58 print &ui_form_end([ [ undef, $text{'login_login'} ] ]);
60 &ui_print_footer("", $text{'index_return'});
64 elsif ($s->{'sameuser'}) {
65 # Login comes from this server
66 $user = $main::remote_user;
67 defined($main::remote_pass) || &error($text{'login_esame'});
68 $pass = $main::remote_pass;
76 # Connect to the server
77 my $con = &make_http_connection($s->{'ip'} || $s->{'host'}, $s->{'port'},
78 $s->{'ssl'}, $meth, $path);
79 &error($con) if (!ref($con));
81 # Send request headers
82 &write_http_connection($con, "Host: $s->{'host'}\r\n");
83 &write_http_connection($con, "User-agent: Webmin\r\n");
84 my $auth = &encode_base64("$user:$pass");
86 &write_http_connection($con, "Authorization: basic $auth\r\n");
87 my ($http_host, $http_port);
88 if ($ENV{'HTTP_HOST'} =~ /^(\S+):(\d+)$/) {
89 # Browser supplies port
93 elsif ($ENV{'HTTP_HOST'}) {
94 # Browser only supplies host
95 $http_host = $ENV{'HTTP_HOST'};
96 $http_port = $ENV{'SERVER_PORT'} || $miniserv{'port'} || 80;
99 # Web server supplies host and port
100 $http_host = $ENV{'SERVER_NAME'};
101 $http_port = $ENV{'SERVER_PORT'};
103 &write_http_connection($con, sprintf(
104 "Webmin-servers: %s://%s:%d/%s\n",
105 $ENV{'HTTPS'} eq "ON" ? "https" : "http",
106 $http_host, $http_port,
107 $tconfig{'inframe'} ? "" : "$module_name/"));
108 my $cl = $ENV{'CONTENT_LENGTH'};
109 &write_http_connection($con, "Content-length: $cl\r\n") if ($cl);
110 &write_http_connection($con, "Content-type: $ENV{'CONTENT_TYPE'}\r\n")
111 if ($ENV{'CONTENT_TYPE'});
112 &write_http_connection($con, "\r\n");
115 &read_fully(\*STDIN, \$post, $cl);
116 &write_http_connection($con, $post);
119 # read back the headers
120 my $dummy = &read_http_connection($con);
121 my (%header, $headers);
124 ($headline = &read_http_connection($con)) =~ s/\r|\n//g;
125 last if (!$headline);
126 $headline =~ /^(\S+):\s+(.*)$/ || &error("Bad header");
127 $header{lc($1)} = $2;
128 $headers .= $headline."\n";
131 my $defport = $s->{'ssl'} ? 443 : 80;
132 if ($header{'location'} &&
133 ($header{'location'} =~ /^(http|https):\/\/$s->{'host'}:$s->{'port'}(.*)$/||
134 $header{'location'} =~ /^(http|https):\/\/$s->{'host'}(.*)/ &&
135 $s->{'port'} == $defport)) {
140 elsif ($header{'www-authenticate'}) {
142 if ($s->{'autouser'}) {
143 print "Set-Cookie: $id=; path=/\n";
144 &error(&text('link_eautologin', $s->{'host'},
145 "$gconfig{'webprefix'}/$module_name/link.cgi/$id/"));
148 &error(&text('link_elogin', $s->{'host'}, $user));
152 # just output the headers
156 # read back the rest of the page
157 if ($header{'content-type'} =~ /text\/html/ && !$header{'x-no-links'}) {
159 while($_ = &read_http_connection($con)) {
160 s/src='(\/[^']*)'/src='$url$1'/gi;
161 s/src="(\/[^"]*)"/src="$url$1"/gi;
162 s/src=(\/[^ "'>]*)/src=$url$1/gi;
163 s/href='(\/[^']*)'/href='$url$1'/gi;
164 s/href="(\/[^"]*)"/href="$url$1"/gi;
165 s/href=(\/[^ >"']*)/href=$url$1/gi;
166 s/action='(\/[^']*)'/action='$url$1'/gi;
167 s/action="(\/[^"]*)"/action="$url$1"/gi;
168 s/action=(\/[^ "'>]*)/action=$url$1/gi;
169 s/\.location\s*=\s*'(\/[^']*)'/.location='$url$1'/gi;
170 s/\.location\s*=\s*"(\/[^']*)"/.location="$url$1"/gi;
171 s/window.open\("(\/[^"]*)"/window.open\("$url$1"/gi;
172 s/name=return\s+value="(\/[^"]*)"/name=return value="$url$1"/gi;
173 s/param\s+name=config\s+value='(\/[^']*)'/param name=config value='$url$1'/gi;
174 s/param\s+name=config\s+value="(\/[^']*)"/param name=config value="$url$1"/gi;
175 s/param\s+name=config\s+value=(\/[^']*)/param name=config value=$url$1/gi;
179 elsif ($header{'content-type'} =~ /text\/css/ && !$header{'x-no-links'}) {
181 while($_ = &read_http_connection($con)) {
182 s/url\("(\/[^"]*)"\)/url\("$url$1"\)/gi;
188 while(my $buf = &read_http_connection($con, 1024)) {
192 &close_http_connection($con);