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