]>
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 | # Load the most appropriate language from the browser configuration | |
36 | my @langs = &Lang::DetectBrowserLanguages(); | |
37 | &Lang::reload(@langs); | |
38 | ||
39 | my $coupons = "${General::swroot}/captive/coupons"; | |
40 | my %couponhash = (); | |
41 | ||
42 | my %clientshash=(); | |
43 | my %cgiparams=(); | |
44 | my %settings=(); | |
45 | my $clients="${General::swroot}/captive/clients"; | |
46 | my $settingsfile="${General::swroot}/captive/settings"; | |
47 | my $errormessage; | |
48 | my $url=param('redirect'); | |
49 | ||
50 | #Create /var/ipfire/captive/clients if not exist | |
51 | unless (-f $clients){ system("touch $clients"); } | |
52 | ||
53 | #Get GUI variables | |
54 | &getcgihash(\%cgiparams); | |
55 | ||
56 | #Read settings | |
57 | &General::readhash("$settingsfile", \%settings) if(-f $settingsfile); | |
58 | ||
59 | # Actions | |
60 | if ($cgiparams{'ACTION'} eq "SUBMIT") { | |
61 | # Get client IP address | |
62 | my $ip_address = $ENV{X_FORWARDED_FOR} || $ENV{REMOTE_ADDR}; | |
63 | ||
64 | # Retrieve the MAC address from the ARP table | |
65 | my $mac_address = &Network::get_hardware_address($ip_address); | |
66 | ||
67 | &General::readhasharray("$clients", \%clientshash); | |
68 | my $key = &General::findhasharraykey(\%clientshash); | |
69 | ||
70 | # Create a new client line | |
71 | foreach my $i (0 .. 5) { $clientshash{$key}[$i] = ""; } | |
72 | ||
73 | # MAC address of the client | |
74 | $clientshash{$key}[0] = $mac_address; | |
75 | ||
76 | # IP address of the client | |
77 | $clientshash{$key}[1] = $ip_address; | |
78 | ||
79 | # Current time | |
80 | $clientshash{$key}[2] = time(); | |
81 | ||
82 | if ($settings{"AUTH"} eq "COUPON") { | |
83 | &General::readhasharray($coupons, \%couponhash); | |
84 | ||
85 | if ($cgiparams{'COUPON'}) { | |
86 | # Convert coupon input to uppercase | |
87 | $cgiparams{'COUPON'} = uc $cgiparams{'COUPON'}; | |
88 | ||
89 | # Walk through all valid coupons and find the right one | |
90 | my $found = 0; | |
91 | foreach my $coupon (keys %couponhash) { | |
92 | if ($couponhash{$coupon}[1] eq $cgiparams{'COUPON'}) { | |
93 | $found = 1; | |
94 | ||
95 | # Copy expiry time | |
96 | $clientshash{$key}[3] = $couponhash{$coupon}[2]; | |
97 | ||
98 | # Save coupon code | |
99 | $clientshash{$key}[4] = $cgiparams{'COUPON'}; | |
100 | ||
101 | # Copy coupon remark | |
102 | $clientshash{$key}[5] = $couponhash{$coupon}[3]; | |
103 | ||
104 | # Delete used coupon | |
105 | delete $couponhash{$coupon}; | |
106 | &General::writehasharray($coupons, \%couponhash); | |
107 | ||
108 | last; | |
109 | } | |
110 | } | |
111 | ||
112 | if ($found == 1) { | |
113 | &General::log("Captive", "Internet access granted via coupon ($clientshash{$key}[4]) for $ip_address until $clientshash{$key}[3]"); | |
114 | } else { | |
115 | $errormessage = $Lang::tr{"Captive invalid coupon"}; | |
116 | } | |
117 | ||
118 | # No coupon given | |
119 | } else { | |
120 | $errormessage = $Lang::tr{"Captive please enter a coupon code"}; | |
121 | } | |
122 | ||
123 | # Terms | |
124 | } else { | |
125 | # Make sure that they have been accepted | |
126 | if ($cgiparams{'TERMS'} eq "on") { | |
127 | # Copy session expiry time | |
128 | $clientshash{$key}[3] = $settings{'SESSION_TIME'} || "0"; | |
129 | ||
130 | # No coupon code | |
131 | $clientshash{$key}[4] = "TERMS"; | |
132 | ||
133 | &General::log("Captive", "Internet access granted via license agreement for $ip_address until $clientshash{$key}[3]"); | |
134 | ||
135 | # The terms have not been accepted | |
136 | } else { | |
137 | $errormessage = $Lang::tr{'Captive please accept the terms and conditions'}; | |
138 | } | |
139 | } | |
140 | ||
141 | # If no errors were found, save configruation and reload | |
142 | if (!$errormessage) { | |
143 | &General::writehasharray("$clients", \%clientshash); | |
144 | ||
145 | system("/usr/local/bin/captivectrl"); | |
146 | ||
147 | # Redirect client to the original URL | |
148 | print "Status: 302 Moved Temporarily\n"; | |
149 | print "Location: $url\n"; | |
150 | print "Connection: close\n\n"; | |
151 | exit 0; | |
152 | } | |
153 | } | |
154 | ||
155 | my $tmpl = HTML::Template->new( | |
156 | filename => "/srv/web/ipfire/html/captive/template.html", | |
157 | die_on_bad_params => 0 | |
158 | ); | |
159 | ||
160 | $tmpl->param(REDIRECT => $url); | |
161 | ||
162 | # Coupon | |
163 | if ($settings{'AUTH'} eq "COUPON") { | |
164 | $tmpl->param(COUPON => 1); | |
165 | $tmpl->param(L_HEADING => $Lang::tr{'Captive coupon'}); | |
166 | } else { | |
167 | $tmpl->param(L_HEADING => $Lang::tr{'Captive terms'}); | |
168 | } | |
169 | ||
170 | $tmpl->param(TITLE => $settings{'TITLE'}); | |
171 | $tmpl->param(COLOR => $settings{'COLOR'}); | |
172 | $tmpl->param(ERROR => $errormessage); | |
173 | ||
174 | $tmpl->param(TERMS => &getterms()); | |
175 | ||
176 | # Some translated strings | |
177 | $tmpl->param(L_ACTIVATE => $Lang::tr{'Captive ACTIVATE'}); | |
178 | $tmpl->param(L_GAIN_ACCESS => $Lang::tr{'Captive GAIN ACCESS'}); | |
179 | $tmpl->param(L_AGREE_TERMS => $Lang::tr{'Captive agree tac'}); | |
180 | ||
181 | # Print header | |
182 | print "Pragma: no-cache\n"; | |
183 | print "Cache-control: no-cache\n"; | |
184 | print "Connection: close\n"; | |
185 | print "Content-type: text/html\n\n"; | |
186 | ||
187 | # Print rendered template | |
188 | print $tmpl->output(); | |
189 | ||
190 | sub getcgihash { | |
191 | my ($hash, $params) = @_; | |
192 | my $cgi = CGI->new (); | |
193 | $hash->{'__CGI__'} = $cgi; | |
194 | return if ($ENV{'REQUEST_METHOD'} ne 'POST'); | |
195 | if (!$params->{'wantfile'}) { | |
196 | $CGI::DISABLE_UPLOADS = 1; | |
197 | $CGI::POST_MAX = 1024 * 1024; | |
198 | } else { | |
199 | $CGI::POST_MAX = 10 * 1024 * 1024; | |
200 | } | |
201 | $cgi->referer() =~ m/^http?\:\/\/([^\/]+)/; | |
202 | my $referer = $1; | |
203 | $cgi->url() =~ m/^http?\:\/\/([^\/]+)/; | |
204 | my $servername = $1; | |
205 | return if ($referer ne $servername); | |
206 | ||
207 | ### Modified for getting multi-vars, split by | | |
208 | my %temp = $cgi->Vars(); | |
209 | foreach my $key (keys %temp) { | |
210 | $hash->{$key} = $temp{$key}; | |
211 | $hash->{$key} =~ s/\0/|/g; | |
212 | $hash->{$key} =~ s/^\s*(.*?)\s*$/$1/; | |
213 | } | |
214 | ||
215 | if (($params->{'wantfile'})&&($params->{'filevar'})) { | |
216 | $hash->{$params->{'filevar'}} = $cgi->upload | |
217 | ($params->{'filevar'}); | |
218 | } | |
219 | return; | |
220 | } | |
221 | ||
222 | sub getterms() { | |
223 | my @terms = (); | |
224 | ||
225 | open(my $handle, "<:utf8", "/var/ipfire/captive/terms.txt"); | |
226 | while(<$handle>) { | |
227 | $_ = HTML::Entities::decode_entities($_); | |
228 | push(@terms, $_); | |
229 | } | |
230 | close($handle); | |
231 | ||
232 | my $terms = join("\n", @terms); | |
233 | ||
234 | # Format paragraphs | |
235 | $terms =~ s/\n\n/<\/p>\n<p>/g; | |
236 | ||
237 | return $terms; | |
238 | } |