]> git.ipfire.org Git - ipfire-2.x.git/blob - html/cgi-bin/captive/index.cgi
captive: Fix passing redirection URL
[ipfire-2.x.git] / html / cgi-bin / captive / index.cgi
1 #!/usr/bin/perl
2 ###############################################################################
3 # #
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2016 Alexander Marx alexander.marx@ipfire.org #
6 # #
7 # This program is free software you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
11 # #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
16 # #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
19 # #
20 ###############################################################################
21
22 use strict;
23 use CGI ':standard';
24 use URI::Escape;
25 use HTML::Entities();
26 use HTML::Template;
27
28 # enable only the following on debugging purpose
29 #use warnings;
30 #use CGI::Carp 'fatalsToBrowser';
31
32 require '/var/ipfire/general-functions.pl';
33 require "${General::swroot}/lang.pl";
34
35 my $coupons = "${General::swroot}/captive/coupons";
36 my %couponhash = ();
37
38 my %clientshash=();
39 my %cgiparams=();
40 my %settings=();
41 my $clients="${General::swroot}/captive/clients";
42 my $settingsfile="${General::swroot}/captive/settings";
43 my $errormessage;
44 my $url=param('redirect');
45
46 #Create /var/ipfire/captive/clients if not exist
47 unless (-f $clients){ system("touch $clients"); }
48
49 #Get GUI variables
50 &getcgihash(\%cgiparams);
51
52 #Read settings
53 &General::readhash("$settingsfile", \%settings) if(-f $settingsfile);
54
55 # Actions
56 if ($cgiparams{'ACTION'} eq "SUBMIT") {
57 # Get client IP address
58 my $ip_address = $ENV{X_FORWARDED_FOR} || $ENV{REMOTE_ADDR};
59
60 # Retrieve the MAC address from the ARP table
61 my $mac_address = &Network::get_hardware_address($ip_address);
62
63 &General::readhasharray("$clients", \%clientshash);
64 my $key = &General::findhasharraykey(\%clientshash);
65
66 # Create a new client line
67 foreach my $i (0 .. 5) { $clientshash{$key}[$i] = ""; }
68
69 # MAC address of the client
70 $clientshash{$key}[0] = $mac_address;
71
72 # IP address of the client
73 $clientshash{$key}[1] = $ip_address;
74
75 # Current time
76 $clientshash{$key}[2] = time();
77
78 if ($settings{"AUTH"} eq "COUPON") {
79 &General::readhasharray($coupons, \%couponhash);
80
81 if ($cgiparams{'COUPON'}) {
82 # Convert coupon input to uppercase
83 $cgiparams{'COUPON'} = uc $cgiparams{'COUPON'};
84
85 # Walk through all valid coupons and find the right one
86 my $found = 0;
87 foreach my $coupon (keys %couponhash) {
88 if ($couponhash{$coupon}[1] eq $cgiparams{'COUPON'}) {
89 $found = 1;
90
91 # Copy expiry time
92 $clientshash{$key}[3] = $couponhash{$coupon}[2];
93
94 # Save coupon code
95 $clientshash{$key}[4] = $cgiparams{'COUPON'};
96
97 # Copy coupon remark
98 $clientshash{$key}[5] = $couponhash{$coupon}[3];
99
100 # Delete used coupon
101 delete $couponhash{$coupon};
102 &General::writehasharray($coupons, \%couponhash);
103
104 last;
105 }
106 }
107
108 if ($found == 1) {
109 &General::log("Captive", "Internet access granted via coupon ($clientshash{$key}[4]) for $ip_address until $clientshash{$key}[3]");
110 } else {
111 $errormessage = $Lang::tr{"Captive invalid coupon"};
112 }
113
114 # No coupon given
115 } else {
116 $errormessage = $Lang::tr{"Captive please enter a coupon code"};
117 }
118
119 # Terms
120 } else {
121 # Make sure that they have been accepted
122 if ($cgiparams{'TERMS'} eq "on") {
123 # Copy session expiry time
124 $clientshash{$key}[3] = $settings{'SESSION_TIME'} || "0";
125
126 # No coupon code
127 $clientshash{$key}[4] = "TERMS";
128
129 &General::log("Captive", "Internet access granted via license agreement for $ip_address until $clientshash{$key}[3]");
130
131 # The terms have not been accepted
132 } else {
133 $errormessage = $Lang::tr{'Captive please accept the terms and conditions'};
134 }
135 }
136
137 # If no errors were found, save configruation and reload
138 if (!$errormessage) {
139 &General::writehasharray("$clients", \%clientshash);
140
141 system("/usr/local/bin/captivectrl");
142
143 # Redirect client to the original URL
144 print "Status: 302 Moved Temporarily\n";
145 print "Location: $url\n";
146 print "Connection: close\n\n";
147 exit 0;
148 }
149 }
150
151 my $tmpl = HTML::Template->new(
152 filename => "/srv/web/ipfire/html/captive/template.html",
153 die_on_bad_params => 0
154 );
155
156 $tmpl->param(REDIRECT => $url);
157
158 # Coupon
159 if ($settings{'AUTH'} eq "COUPON") {
160 $tmpl->param(COUPON => 1);
161 $tmpl->param(L_HEADING => $Lang::tr{'Captive coupon'});
162 } else {
163 $tmpl->param(L_HEADING => $Lang::tr{'Captive terms'});
164 }
165
166 $tmpl->param(TITLE => $settings{'TITLE'});
167 $tmpl->param(COLOR => $settings{'COLOR'});
168 $tmpl->param(ERROR => $errormessage);
169
170 $tmpl->param(TERMS => &getterms());
171
172 # Some translated strings
173 $tmpl->param(L_ACTIVATE => $Lang::tr{'Captive ACTIVATE'});
174 $tmpl->param(L_GAIN_ACCESS => $Lang::tr{'Captive GAIN ACCESS'});
175 $tmpl->param(L_AGREE_TERMS => $Lang::tr{'Captive agree tac'});
176
177 # Print header
178 print "Pragma: no-cache\n";
179 print "Cache-control: no-cache\n";
180 print "Connection: close\n";
181 print "Content-type: text/html\n\n";
182
183 # Print rendered template
184 print $tmpl->output();
185
186 sub getcgihash {
187 my ($hash, $params) = @_;
188 my $cgi = CGI->new ();
189 $hash->{'__CGI__'} = $cgi;
190 return if ($ENV{'REQUEST_METHOD'} ne 'POST');
191 if (!$params->{'wantfile'}) {
192 $CGI::DISABLE_UPLOADS = 1;
193 $CGI::POST_MAX = 1024 * 1024;
194 } else {
195 $CGI::POST_MAX = 10 * 1024 * 1024;
196 }
197 $cgi->referer() =~ m/^http?\:\/\/([^\/]+)/;
198 my $referer = $1;
199 $cgi->url() =~ m/^http?\:\/\/([^\/]+)/;
200 my $servername = $1;
201 return if ($referer ne $servername);
202
203 ### Modified for getting multi-vars, split by |
204 my %temp = $cgi->Vars();
205 foreach my $key (keys %temp) {
206 $hash->{$key} = $temp{$key};
207 $hash->{$key} =~ s/\0/|/g;
208 $hash->{$key} =~ s/^\s*(.*?)\s*$/$1/;
209 }
210
211 if (($params->{'wantfile'})&&($params->{'filevar'})) {
212 $hash->{$params->{'filevar'}} = $cgi->upload
213 ($params->{'filevar'});
214 }
215 return;
216 }
217
218 sub getterms() {
219 my @terms = ();
220
221 open(my $handle, "<:utf8", "/var/ipfire/captive/terms.txt");
222 while(<$handle>) {
223 $_ = HTML::Entities::decode_entities($_);
224 push(@terms, $_);
225 }
226 close($handle);
227
228 my $terms = join("\n", @terms);
229
230 # Format paragraphs
231 $terms =~ s/\n\n/<\/p>\n<p>/g;
232
233 return $terms;
234 }