]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - html/cgi-bin/captive.cgi
BUG11139: Captive voucher table too wide
[people/pmueller/ipfire-2.x.git] / html / cgi-bin / captive.cgi
1 #!/usr/bin/perl
2 ###############################################################################
3 # #
4 # IPFire.org - A linux based firewall #
5 # Copyright (C) 2016 IPFire Team <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 HTML::Entities();
24 use File::Basename;
25
26 # enable only the following on debugging purpose
27 #use warnings;
28 #use CGI::Carp 'fatalsToBrowser';
29
30 require '/var/ipfire/general-functions.pl';
31 require "${General::swroot}/lang.pl";
32 require "${General::swroot}/header.pl";
33
34 my %settings=();
35 my %mainsettings;
36 my %color;
37 my %cgiparams=();
38 my %netsettings=();
39 my %checked=();
40 my $errormessage='';
41 my $voucherout="${General::swroot}/captive/voucher_out";
42 my $clients="${General::swroot}/captive/clients";
43 my %voucherhash=();
44 my %clientshash=();
45 my $settingsfile="${General::swroot}/captive/settings";
46 my $logopath = "/srv/web/ipfire/html/captive/logo";
47 unless (-e $settingsfile) { system("touch $settingsfile"); }
48 unless (-e $voucherout) { system("touch $voucherout"); }
49
50 &Header::getcgihash(\%cgiparams);
51
52 &General::readhash("${General::swroot}/main/settings", \%mainsettings);
53 &General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color);
54 &General::readhash("$settingsfile", \%settings) if(-f $settingsfile);
55 &General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
56
57 &Header::showhttpheaders();
58
59 #actions
60 if ($cgiparams{'ACTION'} eq "$Lang::tr{'save'}"){
61 #Check Expiretime
62 if($cgiparams{'EXP_HOUR'}+$cgiparams{'EXP_DAY'}+$cgiparams{'EXP_WEEK'}+$cgiparams{'EXP_MONTH'} == 0 && $cgiparams{'UNLIMITED'} == ''){
63 $errormessage=$Lang::tr{'Captive noexpiretime'};
64 }
65
66 my $file = $cgiparams{'uploaded_file'};
67 if ($file){
68 #Check if extension is png
69 chomp $file;
70 my ($name, $path, $ext) = fileparse($file, qr/\.[^.]*$/);
71 if ($ext ne ".png"){
72 $errormessage=$Lang::tr{'Captive wrong ext'};
73 }
74 }
75 if (!$errormessage){
76 #Check if we need to upload a new logo
77 if($file){
78 #Save File
79 my ($filehandle) = CGI::upload('uploaded_file');
80 open (UPLOADFILE, ">$logopath/logo.png");
81 binmode $filehandle;
82 while ( <$filehandle> ) {
83 print UPLOADFILE;
84 }
85 close (UPLOADFILE);
86
87 #Open file to check if dimensions are within rang
88 open (PNG , "<$logopath/logo.png");
89 local $/;
90 my $PNG1=<PNG>;
91 close(PNG);
92 my ($width,$height)=&pngsize($PNG1);
93 if($width > 1920 || $height > 800 || $width < 1280 || $height < 400){
94 $errormessage.="$Lang::tr{'Captive invalid logosize'} <br>Filedimensions width: $width height: $height ";
95 unlink("$logopath/logo.png");
96 }
97 }
98
99 #saves the Captiveportal settings to disk
100 if ($cgiparams{'UNLIMITED'} eq 'on'){
101 $cgiparams{'EXP_HOUR'} = '0';
102 $cgiparams{'EXP_DAY'} = '0';
103 $cgiparams{'EXP_WEEK'} = '0';
104 $cgiparams{'EXP_MONTH'} = '0';
105 }
106
107 $settings{'ENABLE_GREEN'} = $cgiparams{'ENABLE_GREEN'};
108 $settings{'ENABLE_BLUE'} = $cgiparams{'ENABLE_BLUE'};
109 $settings{'AUTH'} = $cgiparams{'AUTH'};
110 $settings{'EXPIRE'} = $cgiparams{'EXP_HOUR'}+$cgiparams{'EXP_DAY'}+$cgiparams{'EXP_WEEK'}+$cgiparams{'EXP_MONTH'};
111 $settings{'EXP_HOUR'} = $cgiparams{'EXP_HOUR'};
112 $settings{'EXP_DAY'} = $cgiparams{'EXP_DAY'};
113 $settings{'EXP_WEEK'} = $cgiparams{'EXP_WEEK'};
114 $settings{'EXP_MONTH'} = $cgiparams{'EXP_MONTH'};
115 $settings{'TITLE'} = $cgiparams{'TITLE'};
116 $settings{'UNLIMITED'} = $cgiparams{'UNLIMITED'};
117 &General::writehash("$settingsfile", \%settings);
118
119 #write Licensetext if defined
120 if ($cgiparams{'AGB'}){
121 $cgiparams{'AGB'} = &Header::escape($cgiparams{'AGB'});
122 open( FH, ">:utf8", "/var/ipfire/captive/agb.txt" ) or die("$!");
123 print FH $cgiparams{'AGB'};
124 close( FH );
125 $cgiparams{'AGB'}="";
126 }
127 #execute binary to reload firewall rules
128 system("/usr/local/bin/captivectrl");
129
130 if ($cgiparams{'ENABLE_BLUE'} eq 'on'){
131 system("/usr/local/bin/wirelessctrl");
132 }
133 }
134 }
135
136 if ($cgiparams{'ACTION'} eq "$Lang::tr{'Captive voucherout'}"){
137 #generates a voucher and writes it to /var/ipfire/voucher_out
138
139 #check if we already have a voucher with same code
140 &General::readhasharray("$voucherout", \%voucherhash);
141 foreach my $key (keys %voucherhash) {
142 if($voucherhash{$key}[1] eq $cgiparams{'CODE'}){
143 $errormessage=$Lang::tr{'Captive err doublevoucher'};
144 last;
145 }
146 }
147
148 #check valid remark
149 if ($cgiparams{'REMARK'} ne '' && !&validremark($cgiparams{'REMARK'})){
150 $errormessage=$Lang::tr{'fwhost err remark'};
151 }
152
153 #if no error detected, write to disk
154 if (!$errormessage){
155 my $date=time(); #seconds in utc
156
157 #first get new key from hash
158 my $key=&General::findhasharraykey (\%voucherhash);
159 #initialize all fields with ''
160 foreach my $i (0 .. 3) { $voucherhash{$key}[$i] = "";}
161 #define fields
162 $voucherhash{$key}[0] = $date;
163 $voucherhash{$key}[1] = $cgiparams{'CODE'};
164 $voucherhash{$key}[2] = $settings{'EXPIRE'};
165 $voucherhash{$key}[3] = $cgiparams{'REMARK'};
166 #write values to disk
167 &General::writehasharray("$voucherout", \%voucherhash);
168
169 #now prepare log entry, get expiring date for voucher and decode remark for logfile
170 my $expdate=localtime(time()+$voucherhash{$key}[3]);
171 my $rem=HTML::Entities::decode_entities($voucherhash{$key}[4]);
172
173 #write logfile entry
174 &General::log("Captive", "Generated new voucher $voucherhash{$key}[1] $voucherhash{$key}[2] hours valid expires on $expdate remark $rem");
175 }
176 }
177
178 if ($cgiparams{'ACTION'} eq 'delvoucherout'){
179 #deletes an already generated but unused voucher
180
181 #read all generated vouchers
182 &General::readhasharray("$voucherout", \%voucherhash);
183 foreach my $key (keys %voucherhash) {
184 if($cgiparams{'key'} eq $voucherhash{$key}[0]){
185 #write logenty with decoded remark
186 my $rem=HTML::Entities::decode_entities($voucherhash{$key}[4]);
187 &General::log("Captive", "Delete unused voucher $voucherhash{$key}[1] $voucherhash{$key}[2] hours valid expires on $voucherhash{$key}[3] remark $rem");
188 #delete line from hash
189 delete $voucherhash{$key};
190 last;
191 }
192 }
193 #write back hash
194 &General::writehasharray("$voucherout", \%voucherhash);
195 }
196
197 if ($cgiparams{'ACTION'} eq 'delvoucherinuse'){
198 #delete voucher and connection in use
199
200 #read all active clients
201 &General::readhasharray("$clients", \%clientshash);
202 foreach my $key (keys %clientshash) {
203 if($cgiparams{'key'} eq $clientshash{$key}[0]){
204 #prepare log entry with decoded remark
205 my $rem=HTML::Entities::decode_entities($clientshash{$key}[7]);
206 #write logentry
207 &General::log("Captive", "Delete voucher in use $clientshash{$key}[1] $clientshash{$key}[2] hours valid expires on $clientshash{$key}[3] remark $rem - Connection will be terminated");
208 #delete line from hash
209 delete $clientshash{$key};
210 last;
211 }
212 }
213 #write back hash
214 &General::writehasharray("$clients", \%clientshash);
215 #reload firewallrules to kill connection of client
216 system("/usr/local/bin/captivectrl");
217 }
218
219 #open webpage, print header and open box
220 &Header::openpage($Lang::tr{'Captive menu'}, 1, '');
221 &Header::openbigbox();
222
223 #call error() to see if we have to print an errormessage on website
224 &error();
225
226 #call config() to display the configuration box
227 &config();
228
229 sub getagb(){
230 #open textfile from /var/ipfire/captive/agb.txt
231 open( my $handle, "<:utf8", "/var/ipfire/captive/agb.txt" ) or die("$!");
232 while(<$handle>){
233 #read line by line and print on screen
234 $cgiparams{'AGB'}.= HTML::Entities::decode_entities($_);
235 }
236 close( $handle );
237 }
238
239 sub config(){
240 #prints the config box on the website
241 &Header::openbox('100%', 'left', $Lang::tr{'Captive config'});
242 print <<END
243 <form method='post' action='$ENV{'SCRIPT_NAME'}' enctype="multipart/form-data">\n
244 <table width='100%' border="0">
245 <tr>
246 END
247 ;
248 #check which parameters have to be enabled (from settings file)
249 $checked{'ENABLE_GREEN'}{'off'} = '';
250 $checked{'ENABLE_GREEN'}{'on'} = '';
251 $checked{'ENABLE_GREEN'}{$settings{'ENABLE_GREEN'}} = "checked='checked'";
252
253 $checked{'ENABLE_BLUE'}{'off'} = '';
254 $checked{'ENABLE_BLUE'}{'on'} = '';
255 $checked{'ENABLE_BLUE'}{$settings{'ENABLE_BLUE'}} = "checked='checked'";
256
257 $checked{'UNLIMITED'}{'off'} = '';
258 $checked{'UNLIMITED'}{'on'} = '';
259 $checked{'UNLIMITED'}{$settings{'UNLIMITED'}} = "checked='checked'";
260
261 if ($netsettings{'GREEN_DEV'}){
262 print "<td width='30%'>$Lang::tr{'Captive active on'} <font color='$Header::colourgreen'>Green</font></td><td><input type='checkbox' name='ENABLE_GREEN' $checked{'ENABLE_GREEN'}{'on'} /></td></tr>";
263 }
264 if ($netsettings{'BLUE_DEV'}){
265 print "<td width='30%'>$Lang::tr{'Captive active on'} <font color='$Header::colourblue'>Blue</font></td><td><input type='checkbox' name='ENABLE_BLUE' $checked{'ENABLE_BLUE'}{'on'} /></td></tr>";
266 }
267
268 print<<END
269 </tr>
270 <tr>
271 <td><br>
272 $Lang::tr{'Captive title'}
273 </td>
274 <td><br>
275 <input type='text' name='TITLE' value="$settings{'TITLE'}" size='40'>
276 </td>
277 </tr>
278 END
279 ;
280
281 print<<END
282 <tr>
283 <td>
284 $Lang::tr{'Captive authentication'}
285 </td>
286 <td>
287 <select name='AUTH' style='width:8em;'>
288 END
289 ;
290 print "<option value='LICENSE' ";
291 print " selected='selected'" if ($settings{'AUTH'} eq 'LICENSE');
292 print ">$Lang::tr{'Captive auth_lic'}</option>";
293
294 print "<option value='VOUCHER' ";
295 print " selected='selected'" if ($settings{'AUTH'} eq 'VOUCHER');
296 print ">$Lang::tr{'Captive auth_vou'}</option>";
297
298 print<<END
299 </select>
300 </td>
301 </tr>
302 END
303 ;
304
305 &agbbox();
306
307 #Logo Upload
308 print "<tr><td>$Lang::tr{'Captive logo_upload'}</td><td><INPUT TYPE='file' NAME='uploaded_file' SIZE=30 MAXLENGTH=80></td></tr><tr>";
309 #Show Logo in webinterface with 1/2 size if set
310 if (-f "$logopath/logo.png"){
311 print"<td>$Lang::tr{'Captive logo_set'}</td>";
312 print"<td><img src='/captive/logo/logo.png' alt='$logopath/logo.png' width='25%' height='25%' /></td></tr>";
313 }else{
314 print"<td>$Lang::tr{'Captive logo_set'}</td>";
315 print"<td><br>$Lang::tr{'no'}</td></tr>";
316 }
317 print"<tr><td>$Lang::tr{'Captive vouchervalid'}</td><td>";
318 print "<br><table border='0' with=100%>";
319 print "<th>$Lang::tr{'hours'}</th><th>$Lang::tr{'days'}</th><th>$Lang::tr{'weeks'}</th><th>$Lang::tr{'months'}</th>";
320
321 #print hour-dropdownbox
322 my $hrs=3600;
323 print "<tr><td><select name='EXP_HOUR' style='width:8em;'>";
324 print "<option value='0' ";
325 print " selected='selected'" if ($settings{'EXP_HOUR'} eq '0');
326 print ">--</option>";
327 for (my $i = 1; $i<25; $i++){
328 my $exp_sec = $i * $hrs;
329 print "<option value='$exp_sec' ";
330 print " selected='selected'" if ($settings{'EXP_HOUR'} eq $exp_sec);
331 print ">$i</option>";
332 }
333 print "</td><td>";
334
335 #print day-dropdownbox
336 my $days=3600*24;
337 print "<select name='EXP_DAY' style='width:8em;'>";
338 print "<option value='0' ";
339 print " selected='selected'" if ($settings{'EXP_DAY'} eq '0');
340 print ">--</option>";
341 for (my $i = 1; $i<8; $i++){
342 my $exp_sec = $i * $days;
343 print "<option value='$exp_sec' ";
344 print " selected='selected'" if ($settings{'EXP_DAY'} eq $exp_sec);
345 print ">$i</option>";
346 }
347 print "</td><td>";
348
349 #print week-dropdownbox
350 my $week=3600*24*7;
351 print "<select name='EXP_WEEK' style='width:8em;'>";
352 print "<option value='0' ";
353 print " selected='selected'" if ($settings{'EXP_WEEK'} eq '0');
354 print ">--</option>";
355 for (my $i = 1; $i<5; $i++){
356 my $exp_sec = $i * $week;
357 print "<option value='$exp_sec' ";
358 print " selected='selected'" if ($settings{'EXP_WEEK'} eq $exp_sec);
359 print ">$i</option>";
360 }
361 print "</td><td>";
362
363 #print month-dropdownbox
364 my $month=3600*24*30;
365 print "<select name='EXP_MONTH' style='width:8em;'>";
366 print "<option value='0' ";
367 print " selected='selected'" if ($settings{'EXP_MONTH'} eq '0');
368 print ">--</option>";
369 for (my $i = 1; $i<13; $i++){
370 my $exp_sec = $i * $month;
371 print "<option value='$exp_sec' ";
372 print " selected='selected'" if ($settings{'EXP_MONTH'} eq $exp_sec);
373 print ">$i</option>";
374 }
375 print "</td>";
376
377 print "<td>&nbsp;&nbsp;&nbsp;<input type='checkbox' name='UNLIMITED' $checked{'UNLIMITED'}{'on'} /></td><td>&nbsp;<b>$Lang::tr{'Captive nolimit'}</b></td>";
378
379 print "</tr></table>";
380
381 print<<END
382 <tr>
383 <td>
384 </td>
385 <td align='right'>
386 <input type='submit' name='ACTION' value="$Lang::tr{'save'}"/>
387 </td>
388 </tr>
389 </table>
390 <br><br>
391 END
392 ;
393 print "</form>";
394
395 &Header::closebox();
396
397 #if settings is set to use vouchers, the voucher part has to be displayed
398 if ($settings{'AUTH'} eq 'VOUCHER'){
399 &voucher();
400 }else{
401 #otherwise we show the licensepart
402 &show_license_connections();
403 }
404 }
405
406 sub agbbox(){
407 &getagb();
408 print<<END
409 <tr>
410 <td>
411 License agreement
412 </td>
413 <td>
414 <br>
415 <textarea cols="50" rows="10" name="AGB">$cgiparams{'AGB'}</textarea>
416 </td>
417 </tr>
418 END
419 ;
420 }
421
422 sub gencode(){
423 #generate a random code only letters from A-Z except 'O' and 0-9
424 my @chars = ("A".."N", "P".."Z", "0".."9");
425 my $randomstring;
426 $randomstring .= $chars[rand @chars] for 1..8;
427 return $randomstring;
428 }
429
430 sub voucher(){
431 #show voucher part
432 #calculate expiredate
433 my $expire;
434 if ($settings{'UNLIMITED'} eq 'on'){
435 $expire = $Lang::tr{'Captive nolimit'};
436 }else{
437 $expire = sub{sprintf '%02d.%02d.%04d %02d:%02d', $_[3], $_[4]+1, $_[5]+1900, $_[2], $_[1] }->(localtime(time()+$settings{'EXPIRE'}));
438 }
439
440 &Header::openbox('100%', 'left', $Lang::tr{'Captive voucher'});
441 print<<END
442 <form method='post' action='$ENV{'SCRIPT_NAME'}'>
443 <table class='tbl' width='100%'>
444 <tr>
445 <th align='center' width='20%'>$Lang::tr{'Captive voucher'}</th><th align='center' width='15%'>$Lang::tr{'Captive expire'}</th><th align='center' width='65%'>$Lang::tr{'remark'}</th></tr>
446 END
447 ;
448
449 $cgiparams{'CODE'} = &gencode();
450 print "<tr><td><center><b><font size='5'>$cgiparams{'CODE'}</font></b></center></td><td><center><font size='2'>$expire</font></center></td><td><input type='text' style='width: 96%;' name='REMARK' align='left'></td></tr>";
451 print "</table><br>";
452 print "<center><input type='submit' name='ACTION' value='$Lang::tr{'Captive voucherout'}'><input type='hidden' name='CODE' value='$cgiparams{'CODE'}'</center></form>";
453 &Header::closebox();
454 if (! -z $voucherout) { &show_voucher_out();}
455 if (! -z $clients) { &show_voucher_in_use();}
456 }
457
458 sub show_license_connections(){
459 #if there are active clients, show the box with active connections
460 return if ( -z $clients || ! -f $clients );
461 my $count=0;
462 my $col;
463 &Header::openbox('100%', 'left', $Lang::tr{'Captive voactive'});
464 print<<END
465 <center><table class='tbl'>
466 <tr>
467 <th align='center' width='15%'>$Lang::tr{'Captive voucher'}</th><th th align='center' width='15%'>$Lang::tr{'Captive activated'}</th><th th align='center' width='15%'>$Lang::tr{'Captive expire'}</th><th align='center' width='50%'><font size='1'>$Lang::tr{'Captive mac'}</th><th th align='center' width='5%'>$Lang::tr{'delete'}</th></tr>
468 END
469 ;
470 #read all clients from hash and show table
471 &General::readhasharray("$clients", \%clientshash);
472 foreach my $key (keys %clientshash){
473 my $starttime = sub{sprintf '%02d.%02d.%04d %02d:%02d', $_[3], $_[4]+1, $_[5]+1900, $_[2], $_[1] }->(localtime($clientshash{$key}[2]));
474 my $endtime;
475 if ($clientshash{$key}[3] eq '0'){
476 $endtime=$Lang::tr{'Captive nolimit'};
477 }else{
478 $endtime=sub{sprintf '%02d.%02d.%04d %02d:%02d', $_[3], $_[4]+1, $_[5]+1900, $_[2], $_[1] }->(localtime($clientshash{$key}[2]+$clientshash{$key}[3]));
479 }
480
481 if ($count % 2){
482 print" <tr>";
483 $col="bgcolor='$color{'color20'}'";
484 }else{
485 $col="bgcolor='$color{'color22'}'";
486 print" <tr>";
487 }
488 print "<td $col><center>$clientshash{$key}[4]</td><td $col><center>$starttime ";
489 print "</center></td><td $col><center>$endtime ";
490 print "</td><td $col><center>$clientshash{$key}[0]</td><td $col><form method='post'><center><input type='image' src='/images/delete.gif' align='middle' alt='$Lang::tr{'delete'}' title='$Lang::tr{'delete'}' /><form method='post'><input type='hidden' name='ACTION' value='delvoucherinuse' /><input type='hidden' name='key' value='$clientshash{$key}[0]' /></form></tr>";
491 $count++;
492 }
493
494 print "</table>";
495 &Header::closebox();
496 }
497
498 sub show_voucher_out(){
499 #if there are already generated but unsused vouchers, print a table
500 return if ( -z $voucherout);
501 my $count=0;
502 my $col;
503 &Header::openbox('100%', 'left', $Lang::tr{'Captive vout'});
504 print<<END
505 <center><table class='tbl' border='0'>
506 <tr>
507 <th align='center' width='15%'>$Lang::tr{'Captive voucher'}</th><th align='center' width='15%'>$Lang::tr{'date'}</th><th th align='center' width='15%'>$Lang::tr{'Captive expire'}</th><th align='center' width='60%'>$Lang::tr{'remark'}</th><th align='center' width='5%'>$Lang::tr{'delete'}</th></tr>
508 END
509 ;
510 &General::readhasharray("$voucherout", \%voucherhash);
511 foreach my $key (keys %voucherhash)
512 {
513 my $starttime = sub{sprintf '%02d.%02d.%04d %02d:%02d', $_[3], $_[4]+1, $_[5]+1900, $_[2], $_[1] }->(localtime($voucherhash{$key}[0]));
514 my $endtime;
515 if ($voucherhash{$key}[2] eq '0'){
516 $endtime=$Lang::tr{'Captive nolimit'};
517 }else{
518 $endtime=sub{sprintf '%02d.%02d.%04d %02d:%02d', $_[3], $_[4]+1, $_[5]+1900, $_[2], $_[1] }->(localtime(time()+$voucherhash{$key}[2]));
519 }
520
521 if ($count % 2){
522 print" <tr>";
523 $col="bgcolor='$color{'color20'}'";
524 }else{
525 $col="bgcolor='$color{'color22'}'";
526 print" <tr>";
527 }
528
529 print "<td $col><center><b>$voucherhash{$key}[1]</b></td>";
530 print "<td $col><center>$starttime</td>";
531 print "<td $col><center>$endtime</td>";
532 print "<td $col align='center'>$voucherhash{$key}[3]</td>";
533 print "<td $col><form method='post'><center><input type='image' src='/images/delete.gif' align='middle' alt='$Lang::tr{'delete'}' title='$Lang::tr{'delete'}' /><form method='post'><input type='hidden' name='ACTION' value='delvoucherout' /><input type='hidden' name='key' value='$voucherhash{$key}[0]' /></form></tr>";
534 $count++;
535 }
536
537 print "</table>";
538 &Header::closebox();
539 }
540
541 sub show_voucher_in_use(){
542 #if there are active clients which use vouchers show table
543 return if ( -z $clients || ! -f $clients );
544 my $count=0;
545 my $col;
546 &Header::openbox('100%', 'left', $Lang::tr{'Captive voactive'});
547 print<<END
548 <center><table class='tbl' width='100%'>
549 <tr>
550 <th align='center' width='15%'>$Lang::tr{'Captive voucher'}</th><th th align='center' width='15%'>$Lang::tr{'Captive activated'}</th><th align='center' width='15%'>$Lang::tr{'Captive expire'}</th><th align='center' width='10%'>$Lang::tr{'Captive mac'}</th><th align='center' width='43%'>$Lang::tr{'remark'}</th><th th align='center' width='5%'>$Lang::tr{'delete'}</th></tr>
551 END
552 ;
553 &General::readhasharray("$clients", \%clientshash);
554 foreach my $key (keys %clientshash)
555 {
556 #calculate time from clientshash (starttime)
557 my $starttime = sub{sprintf '%02d.%02d.%04d %02d:%02d', $_[3], $_[4]+1, $_[5]+1900, $_[2], $_[1] }->(localtime($clientshash{$key}[2]));
558 #calculate endtime from clientshash
559 my $endtime;
560 if ($clientshash{$key}[3] eq '0'){
561 $endtime=$Lang::tr{'Captive nolimit'};
562 }else{
563 $endtime = sub{sprintf '%02d.%02d.%04d %02d:%02d', $_[3], $_[4]+1, $_[5]+1900, $_[2], $_[1] }->(localtime($clientshash{$key}[2]+$clientshash{$key}[3]));
564 }
565
566 if ($count % 2){
567 print" <tr>";
568 $col="bgcolor='$color{'color20'}'";
569 }else{
570 $col="bgcolor='$color{'color22'}'";
571 print" <tr>";
572 }
573
574 print "<td $col><center><b>$clientshash{$key}[4]</b></td><td $col><center>$starttime ";
575 print "</center></td><td $col><center>$endtime</center></td><td $col><center>$clientshash{$key}[0]</td><td $col><center>$clientshash{$key}[5]</center>";
576 print "</td><td $col><form method='post'><center><input type='image' src='/images/delete.gif' align='middle' alt='$Lang::tr{'delete'}' title='$Lang::tr{'delete'}' /><form method='post'><input type='hidden' name='ACTION' value='delvoucherinuse' /><input type='hidden' name='key' value='$clientshash{$key}[0]' /></form></tr>";
577 $count++;
578 }
579
580 print "</table>";
581 &Header::closebox();
582 }
583
584 sub validremark
585 {
586 # Checks a hostname against RFC1035
587 my $remark = $_[0];
588 # Each part should be at least two characters in length
589 # but no more than 63 characters
590 if (length ($remark) < 1 || length ($remark) > 255) {
591 return 0;}
592 # Only valid characters are a-z, A-Z, 0-9 and -
593 if ($remark !~ /^[a-zäöüA-ZÖÄÜ0-9-.:;\|_()\/\s]*$/) {
594 return 0;}
595 # First character can only be a letter or a digit
596 if (substr ($remark, 0, 1) !~ /^[a-zäöüA-ZÖÄÜ0-9]*$/) {
597 return 0;}
598 # Last character can only be a letter or a digit
599 if (substr ($remark, -1, 1) !~ /^[a-zöäüA-ZÖÄÜ0-9.:;_)]*$/) {
600 return 0;}
601 return 1;
602 }
603
604 sub pngsize {
605 my $Buffer = shift;
606 my ($width,$height) = ( undef, undef );
607
608 if ($Buffer =~ /IHDR(.{8})/) {
609 my $PNG = $1;
610 ($width,$height) = unpack( "NN", $PNG );
611 } else {
612 $width="invalid";
613 $height= "invalid";
614 };
615 return ($width,$height);
616 }
617
618 sub error{
619 #if an errormessage exits, show a box with errormessage
620 if ($errormessage) {
621 &Header::openbox('100%', 'left', $Lang::tr{'error messages'});
622 print "<class name='base'>$errormessage\n";
623 print "&nbsp;</class>\n";
624 &Header::closebox();
625 }
626 }
627
628 &Header::closebigbox();
629 &Header::closepage();