]>
Commit | Line | Data |
---|---|---|
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 => $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 | } |