Merge branch 'captive-portal' into next

This commit is contained in:
Michael Tremer
2017-10-04 16:10:07 +01:00
48 changed files with 2658 additions and 13 deletions

View File

@@ -41,3 +41,4 @@
/root/.bash_history
/var/ipfire/ethernet/aliases
/var/ipfire/ethernet/wireless
/var/ipfire/captive/*

View File

@@ -235,7 +235,13 @@ sub writehashpart
sub age {
my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
$atime, $mtime, $ctime, $blksize, $blocks) = stat $_[0];
my $totalsecs = time() - $mtime;
my $t = time() - $mtime;
return &format_time($t);
}
sub format_time($) {
my $totalsecs = shift;
my @s = ();
my $secs = $totalsecs % 60;

View File

@@ -179,4 +179,18 @@ sub FindWebLanguage() {
return undef;
}
sub DetectBrowserLanguages() {
my $langs = $ENV{"HTTP_ACCEPT_LANGUAGE"};
my @results = ();
foreach my $lang (split /[,;]/, $langs) {
# Drop all q= arguments
next if ($lang =~ m/^q=/);
push(@results, $lang);
}
return @results;
}
1;

View File

@@ -374,6 +374,26 @@ sub wifi_get_signal_level($) {
return $signal_level;
}
sub get_hardware_address($) {
my $ip_address = shift;
my $ret;
open(FILE, "/proc/net/arp") or die("Could not read ARP table");
while (<FILE>) {
my ($ip_addr, $hwtype, $flags, $hwaddr, $mask, $device) = split(/\s+/, $_);
if ($ip_addr eq $ip_address) {
$ret = $hwaddr;
last;
}
}
close(FILE);
return $ret;
}
1;
# Remove the next line to enable the testsuite

View File

@@ -65,6 +65,12 @@ HOME=/
# Retry sending spooled mails regularly
%hourly * /usr/sbin/dma -q
# Cleanup captive clients
%hourly * /usr/bin/captive-cleanup
# Reload captive firewall rules
%nightly * 23-1 /usr/local/bin/captivectrl >/dev/null
# Cleanup the mail spool directory
%weekly * * /usr/sbin/dma-cleanup-spool

View File

@@ -0,0 +1,30 @@
Listen 1013
<VirtualHost *:1013>
DocumentRoot /srv/web/ipfire/html/captive
# Close all connections as soon as a reply has been sent.
# Most browsers open loads of connections which then causes
# the access page being loaded again after a correct coupon
# code was entered.
KeepAlive Off
ScriptAlias /cgi-bin/ /srv/web/ipfire/cgi-bin/captive/
Alias /assets/ /srv/web/ipfire/html/captive/assets/
Alias /favicon.ico /srv/web/ipfire/html/captive/assets/favicon.ico
# All unknown URIs will be redirected to the first
# redirector script.
ScriptAliasMatch .* /srv/web/ipfire/cgi-bin/captive/redirect.cgi
<Directory /srv/web/ipfire/cgi-bin/captive>
Options ExecCGI
Require all granted
</Directory>
<Directory /srv/web/ipfire/html/captive>
Options +FollowSymlinks
Require all granted
</Directory>
</VirtualHost>

View File

@@ -23,6 +23,11 @@
'title' => "$Lang::tr{'dhcp server'}",
'enabled' => 1,
};
$subnetwork->{'32.captive'} = {'caption' => $Lang::tr{'Captive menu'},
'uri' => '/cgi-bin/captive.cgi',
'title' => $Lang::tr{'Captive menu'},
'enabled' => 1,
};
$subnetwork->{'40.scheduler'} = {
'caption' => $Lang::tr{'connscheduler'},
'uri' => '/cgi-bin/connscheduler.cgi',

View File

@@ -43,6 +43,7 @@ etc/httpd/conf/server-tuning.conf
etc/httpd/conf/ssl-global.conf
etc/httpd/conf/uid.conf
#etc/httpd/conf/vhosts.d
etc/httpd/conf/vhosts.d/captive.conf
etc/httpd/conf/vhosts.d/ipfire-interface-ssl.conf
etc/httpd/conf/vhosts.d/ipfire-interface.conf
#etc/httpd/conf/vhosts.d/nagios.conf
@@ -91,6 +92,8 @@ etc/httpd/conf/vhosts.d/ipfire-interface.conf
#srv/web/ipfire/error/include/top.html
#srv/web/ipfire/htdocs
#srv/web/ipfire/htdocs/index.html
#srv/web/ipfire/html
srv/web/ipfire/html/captive
#srv/web/ipfire/icons
#srv/web/ipfire/icons/README
#srv/web/ipfire/icons/README.html
@@ -1662,3 +1665,4 @@ usr/sbin/httpd
#usr/share/man/man8/rotatelogs.8
#usr/share/man/man8/suexec.8
var/log/httpd
var/log/httpd/captive

View File

@@ -0,0 +1,17 @@
#usr/share/bootstrap
#usr/share/bootstrap/css
usr/share/bootstrap/css/bootstrap.css
usr/share/bootstrap/css/bootstrap.css.map
usr/share/bootstrap/css/bootstrap-grid.css
usr/share/bootstrap/css/bootstrap-grid.css.map
usr/share/bootstrap/css/bootstrap-grid.min.css
usr/share/bootstrap/css/bootstrap-grid.min.css.map
usr/share/bootstrap/css/bootstrap.min.css
usr/share/bootstrap/css/bootstrap.min.css.map
usr/share/bootstrap/css/bootstrap-reboot.css
usr/share/bootstrap/css/bootstrap-reboot.css.map
usr/share/bootstrap/css/bootstrap-reboot.min.css
usr/share/bootstrap/css/bootstrap-reboot.min.css.map
#usr/share/bootstrap/js
usr/share/bootstrap/js/bootstrap.js
usr/share/bootstrap/js/bootstrap.min.js

View File

@@ -11,6 +11,11 @@ var/ipfire/auth
var/ipfire/backup/exclude.user
var/ipfire/backup/include.user
var/ipfire/ca
var/ipfire/captive
var/ipfire/captive/agb.txt
var/ipfire/captive/clients
var/ipfire/captive/settings
var/ipfire/captive/voucher_out
var/ipfire/certs
#var/ipfire/certs/index.txt
#var/ipfire/certs/serial
@@ -51,16 +56,14 @@ var/ipfire/extrahd
#var/ipfire/extrahd/settings
var/ipfire/firewall
#var/ipfire/firewall/config
#var/ipfire/firewall/dmz
#var/ipfire/firewall/geoipblock
#var/ipfire/firewall/input
#var/ipfire/firewall/nat
#var/ipfire/firewall/outgoing
#var/ipfire/firewall/p2protocols
#var/ipfire/firewall/settings
var/ipfire/fwhosts
#var/ipfire/fwhosts/customgroups
#var/ipfire/fwhosts/customgeoipgrp
#var/ipfire/fwhosts/customgroups
#var/ipfire/fwhosts/customhosts
#var/ipfire/fwhosts/customnetworks
#var/ipfire/fwhosts/customservicegrp
@@ -116,6 +119,7 @@ var/ipfire/menu.d/70-log.menu
#var/ipfire/menu.d/EX-tor.menu
#var/ipfire/menu.d/EX-wlanap.menu
var/ipfire/modem
var/ipfire/modem-lib.pl
#var/ipfire/modem/defaults
#var/ipfire/modem/settings
var/ipfire/modem-lib.pl

View File

@@ -1,6 +1,7 @@
usr/local/bin/addonctrl
#usr/local/bin/applejuicectrl
usr/local/bin/backupctrl
usr/local/bin/captivectrl
#usr/local/bin/clamavctrl
usr/local/bin/collectdctrl
usr/local/bin/ddnsctrl

View File

@@ -69,6 +69,7 @@ run
#sbin
#srv
#usr/bin
usr/bin/captive-cleanup
#usr/bin/perl
#usr/include
#usr/lib

View File

@@ -0,0 +1,13 @@
usr/share/fonts/Ubuntu-B.ttf
usr/share/fonts/Ubuntu-BI.ttf
usr/share/fonts/Ubuntu-C.ttf
usr/share/fonts/Ubuntu-L.ttf
usr/share/fonts/Ubuntu-LI.ttf
usr/share/fonts/Ubuntu-M.ttf
usr/share/fonts/Ubuntu-MI.ttf
usr/share/fonts/Ubuntu-R.ttf
usr/share/fonts/Ubuntu-RI.ttf
usr/share/fonts/UbuntuMono-B.ttf
usr/share/fonts/UbuntuMono-BI.ttf
usr/share/fonts/UbuntuMono-R.ttf
usr/share/fonts/UbuntuMono-RI.ttf

View File

@@ -8,6 +8,11 @@ srv/web/ipfire/cgi-bin/aliases.cgi
srv/web/ipfire/cgi-bin/atm-status.cgi
srv/web/ipfire/cgi-bin/backup.cgi
srv/web/ipfire/cgi-bin/bluetooth.cgi
#srv/web/ipfire/cgi-bin/captive
srv/web/ipfire/cgi-bin/captive.cgi
srv/web/ipfire/cgi-bin/captive/index.cgi
srv/web/ipfire/cgi-bin/captive/logo.cgi
srv/web/ipfire/cgi-bin/captive/redirect.cgi
srv/web/ipfire/cgi-bin/chpasswd.cgi
srv/web/ipfire/cgi-bin/connections.cgi
srv/web/ipfire/cgi-bin/connscheduler.cgi
@@ -23,8 +28,8 @@ srv/web/ipfire/cgi-bin/fireinfo.cgi
srv/web/ipfire/cgi-bin/firewall.cgi
srv/web/ipfire/cgi-bin/fwhosts.cgi
srv/web/ipfire/cgi-bin/geoip-block.cgi
#srv/web/ipfire/cgi-bin/guardian.cgi
srv/web/ipfire/cgi-bin/gpl.cgi
#srv/web/ipfire/cgi-bin/guardian.cgi
srv/web/ipfire/cgi-bin/gui.cgi
srv/web/ipfire/cgi-bin/hardwaregraphs.cgi
srv/web/ipfire/cgi-bin/hosts.cgi
@@ -89,6 +94,19 @@ srv/web/ipfire/cgi-bin/wirelessclient.cgi
srv/web/ipfire/cgi-bin/wlanap.cgi
#srv/web/ipfire/html
srv/web/ipfire/html/blob.gif
#srv/web/ipfire/html/captive
#srv/web/ipfire/html/captive/assets
srv/web/ipfire/html/captive/assets/Ubuntu-L.ttf
srv/web/ipfire/html/captive/assets/Ubuntu-M.ttf
srv/web/ipfire/html/captive/assets/Ubuntu-R.ttf
srv/web/ipfire/html/captive/assets/bootstrap-grid.min.css
srv/web/ipfire/html/captive/assets/bootstrap-grid.min.css.map
srv/web/ipfire/html/captive/assets/bootstrap-reboot.min.css
srv/web/ipfire/html/captive/assets/bootstrap-reboot.min.css.map
srv/web/ipfire/html/captive/assets/captive.css
srv/web/ipfire/html/captive/assets/favicon.ico
srv/web/ipfire/html/captive/assets/ipfire.png
srv/web/ipfire/html/captive/template.html
srv/web/ipfire/html/clwarn.cgi
srv/web/ipfire/html/dial.cgi
srv/web/ipfire/html/favicon.ico

View File

@@ -70,6 +70,7 @@ run
#sbin
#srv
#usr/bin
usr/bin/captive-cleanup
#usr/bin/perl
#usr/include
#usr/lib

View File

@@ -1,4 +1,24 @@
WARNING: translation string unused: Async logging enabled
WARNING: translation string unused: Captive 1day
WARNING: translation string unused: Captive 1month
WARNING: translation string unused: Captive 1week
WARNING: translation string unused: Captive activate
WARNING: translation string unused: Captive auth_lic
WARNING: translation string unused: Captive auth_vou
WARNING: translation string unused: Captive err doublevoucher
WARNING: translation string unused: Captive expire
WARNING: translation string unused: Captive genvoucher
WARNING: translation string unused: Captive invalid logosize
WARNING: translation string unused: Captive invalid_voucher
WARNING: translation string unused: Captive ip
WARNING: translation string unused: Captive logo_set
WARNING: translation string unused: Captive logo_upload
WARNING: translation string unused: Captive logo_upload1
WARNING: translation string unused: Captive nr
WARNING: translation string unused: Captive time
WARNING: translation string unused: Captive voactive
WARNING: translation string unused: Captive voucher
WARNING: translation string unused: Captive vout
WARNING: translation string unused: ConnSched scheduler
WARNING: translation string unused: ConnSched select profile
WARNING: translation string unused: HDD temperature
@@ -665,9 +685,11 @@ WARNING: translation string unused: xtaccess all error
WARNING: translation string unused: xtaccess bad transfert
WARNING: translation string unused: year-graph
WARNING: translation string unused: yearly firewallhits
WARNING: untranslated string: 24 hours
WARNING: untranslated string: Scan for Songs
WARNING: untranslated string: addons
WARNING: untranslated string: bytes
WARNING: untranslated string: captive
WARNING: untranslated string: community rules
WARNING: untranslated string: dead peer detection
WARNING: untranslated string: emerging rules
@@ -714,11 +736,15 @@ WARNING: untranslated string: ike lifetime should be between 1 and 8 hours
WARNING: untranslated string: info messages
WARNING: untranslated string: no data
WARNING: untranslated string: none
WARNING: untranslated string: one hour
WARNING: untranslated string: one month
WARNING: untranslated string: one week
WARNING: untranslated string: qos add subclass
WARNING: untranslated string: route config changed
WARNING: untranslated string: routing config added
WARNING: untranslated string: routing config changed
WARNING: untranslated string: routing table
WARNING: untranslated string: show tls-auth key
WARNING: untranslated string: unlimited
WARNING: untranslated string: vpn force mobike
WARNING: untranslated string: vpn statistics n2n

View File

@@ -1,4 +1,25 @@
WARNING: translation string unused: Async logging enabled
WARNING: translation string unused: Captive 1day
WARNING: translation string unused: Captive 1month
WARNING: translation string unused: Captive 1week
WARNING: translation string unused: Captive activate
WARNING: translation string unused: Captive auth_lic
WARNING: translation string unused: Captive auth_vou
WARNING: translation string unused: Captive err doublevoucher
WARNING: translation string unused: Captive expire
WARNING: translation string unused: Captive heading terms
WARNING: translation string unused: Captive heading voucher
WARNING: translation string unused: Captive invalid coupon
WARNING: translation string unused: Captive invalid logosize
WARNING: translation string unused: Captive invalid_voucher
WARNING: translation string unused: Captive ip
WARNING: translation string unused: Captive logo_set
WARNING: translation string unused: Captive nr
WARNING: translation string unused: Captive please enter a coupon code
WARNING: translation string unused: Captive time
WARNING: translation string unused: Captive voactive
WARNING: translation string unused: Captive voucher
WARNING: translation string unused: Captive vout
WARNING: translation string unused: ConnSched scheduler
WARNING: translation string unused: ConnSched select profile
WARNING: translation string unused: HDD temperature
@@ -701,8 +722,10 @@ WARNING: translation string unused: xtaccess all error
WARNING: translation string unused: xtaccess bad transfert
WARNING: translation string unused: year-graph
WARNING: translation string unused: yearly firewallhits
WARNING: untranslated string: Captive clients
WARNING: untranslated string: Scan for Songs
WARNING: untranslated string: bytes
WARNING: untranslated string: captive
WARNING: untranslated string: fwhost cust geoipgrp
WARNING: untranslated string: fwhost err hostip
WARNING: untranslated string: guardian block a host

View File

@@ -618,6 +618,35 @@ WARNING: translation string unused: xtaccess all error
WARNING: translation string unused: xtaccess bad transfert
WARNING: translation string unused: year-graph
WARNING: translation string unused: yearly firewallhits
WARNING: untranslated string: 24 hours
WARNING: untranslated string: Captive ACTIVATE
WARNING: untranslated string: Captive GAIN ACCESS
WARNING: untranslated string: Captive activated
WARNING: untranslated string: Captive active on
WARNING: untranslated string: Captive agree tac
WARNING: untranslated string: Captive authentication
WARNING: untranslated string: Captive brand color
WARNING: untranslated string: Captive branding
WARNING: untranslated string: Captive client session expiry time
WARNING: untranslated string: Captive clients
WARNING: untranslated string: Captive config
WARNING: untranslated string: Captive coupon
WARNING: untranslated string: Captive expiry time
WARNING: untranslated string: Captive generate coupon
WARNING: untranslated string: Captive issued coupons
WARNING: untranslated string: Captive logo uploaded
WARNING: untranslated string: Captive mac
WARNING: untranslated string: Captive menu
WARNING: untranslated string: Captive noexpiretime
WARNING: untranslated string: Captive nolimit
WARNING: untranslated string: Captive please accept the terms and conditions
WARNING: untranslated string: Captive terms
WARNING: untranslated string: Captive terms short
WARNING: untranslated string: Captive title
WARNING: untranslated string: Captive upload logo
WARNING: untranslated string: Captive upload logo recommendations
WARNING: untranslated string: Captive vouchervalid
WARNING: untranslated string: Captive wrong ext
WARNING: untranslated string: ConnSched dial
WARNING: untranslated string: ConnSched hangup
WARNING: untranslated string: ConnSched reboot
@@ -649,6 +678,7 @@ WARNING: untranslated string: bit
WARNING: untranslated string: block
WARNING: untranslated string: bytes
WARNING: untranslated string: capabilities
WARNING: untranslated string: captive
WARNING: untranslated string: ccd add
WARNING: untranslated string: ccd choose net
WARNING: untranslated string: ccd client options
@@ -729,6 +759,7 @@ WARNING: untranslated string: drop action1
WARNING: untranslated string: drop action2
WARNING: untranslated string: drop forward
WARNING: untranslated string: drop outgoing
WARNING: untranslated string: eight hours
WARNING: untranslated string: email config
WARNING: untranslated string: email empty field
WARNING: untranslated string: email invalid
@@ -1019,6 +1050,9 @@ WARNING: untranslated string: no hardware random number generator
WARNING: untranslated string: none
WARNING: untranslated string: not a valid dh key
WARNING: untranslated string: notice
WARNING: untranslated string: one hour
WARNING: untranslated string: one month
WARNING: untranslated string: one week
WARNING: untranslated string: openvpn default
WARNING: untranslated string: openvpn destination port used
WARNING: untranslated string: openvpn fragment allowed with udp
@@ -1143,6 +1177,7 @@ WARNING: untranslated string: tor use exit nodes
WARNING: untranslated string: unblock
WARNING: untranslated string: unblock all
WARNING: untranslated string: uncheck all
WARNING: untranslated string: unlimited
WARNING: untranslated string: uplink
WARNING: untranslated string: uplink bit rate
WARNING: untranslated string: upload dh key

View File

@@ -628,6 +628,35 @@ WARNING: translation string unused: xtaccess all error
WARNING: translation string unused: xtaccess bad transfert
WARNING: translation string unused: year-graph
WARNING: translation string unused: yearly firewallhits
WARNING: untranslated string: 24 hours
WARNING: untranslated string: Captive ACTIVATE
WARNING: untranslated string: Captive GAIN ACCESS
WARNING: untranslated string: Captive activated
WARNING: untranslated string: Captive active on
WARNING: untranslated string: Captive agree tac
WARNING: untranslated string: Captive authentication
WARNING: untranslated string: Captive brand color
WARNING: untranslated string: Captive branding
WARNING: untranslated string: Captive client session expiry time
WARNING: untranslated string: Captive clients
WARNING: untranslated string: Captive config
WARNING: untranslated string: Captive coupon
WARNING: untranslated string: Captive expiry time
WARNING: untranslated string: Captive generate coupon
WARNING: untranslated string: Captive issued coupons
WARNING: untranslated string: Captive logo uploaded
WARNING: untranslated string: Captive mac
WARNING: untranslated string: Captive menu
WARNING: untranslated string: Captive noexpiretime
WARNING: untranslated string: Captive nolimit
WARNING: untranslated string: Captive please accept the terms and conditions
WARNING: untranslated string: Captive terms
WARNING: untranslated string: Captive terms short
WARNING: untranslated string: Captive title
WARNING: untranslated string: Captive upload logo
WARNING: untranslated string: Captive upload logo recommendations
WARNING: untranslated string: Captive vouchervalid
WARNING: untranslated string: Captive wrong ext
WARNING: untranslated string: ConnSched dial
WARNING: untranslated string: ConnSched hangup
WARNING: untranslated string: ConnSched reboot
@@ -658,6 +687,7 @@ WARNING: untranslated string: bit
WARNING: untranslated string: block
WARNING: untranslated string: bytes
WARNING: untranslated string: capabilities
WARNING: untranslated string: captive
WARNING: untranslated string: ccd add
WARNING: untranslated string: ccd choose net
WARNING: untranslated string: ccd client options
@@ -739,6 +769,7 @@ WARNING: untranslated string: drop action1
WARNING: untranslated string: drop action2
WARNING: untranslated string: drop forward
WARNING: untranslated string: drop outgoing
WARNING: untranslated string: eight hours
WARNING: untranslated string: email config
WARNING: untranslated string: email empty field
WARNING: untranslated string: email invalid
@@ -1038,6 +1069,9 @@ WARNING: untranslated string: not a valid dh key
WARNING: untranslated string: notice
WARNING: untranslated string: ntp common settings
WARNING: untranslated string: ntp sync
WARNING: untranslated string: one hour
WARNING: untranslated string: one month
WARNING: untranslated string: one week
WARNING: untranslated string: openvpn default
WARNING: untranslated string: openvpn destination port used
WARNING: untranslated string: openvpn fragment allowed with udp
@@ -1157,6 +1191,7 @@ WARNING: untranslated string: tor use exit nodes
WARNING: untranslated string: unblock
WARNING: untranslated string: unblock all
WARNING: untranslated string: uncheck all
WARNING: untranslated string: unlimited
WARNING: untranslated string: uplink
WARNING: untranslated string: uplink bit rate
WARNING: untranslated string: upload dh key

View File

@@ -695,6 +695,35 @@ WARNING: translation string unused: xtaccess all error
WARNING: translation string unused: xtaccess bad transfert
WARNING: translation string unused: year-graph
WARNING: translation string unused: yearly firewallhits
WARNING: untranslated string: 24 hours
WARNING: untranslated string: Captive ACTIVATE
WARNING: untranslated string: Captive GAIN ACCESS
WARNING: untranslated string: Captive activated
WARNING: untranslated string: Captive active on
WARNING: untranslated string: Captive agree tac
WARNING: untranslated string: Captive authentication
WARNING: untranslated string: Captive brand color
WARNING: untranslated string: Captive branding
WARNING: untranslated string: Captive client session expiry time
WARNING: untranslated string: Captive clients
WARNING: untranslated string: Captive config
WARNING: untranslated string: Captive coupon
WARNING: untranslated string: Captive expiry time
WARNING: untranslated string: Captive generate coupon
WARNING: untranslated string: Captive issued coupons
WARNING: untranslated string: Captive logo uploaded
WARNING: untranslated string: Captive mac
WARNING: untranslated string: Captive menu
WARNING: untranslated string: Captive noexpiretime
WARNING: untranslated string: Captive nolimit
WARNING: untranslated string: Captive please accept the terms and conditions
WARNING: untranslated string: Captive terms
WARNING: untranslated string: Captive terms short
WARNING: untranslated string: Captive title
WARNING: untranslated string: Captive upload logo
WARNING: untranslated string: Captive upload logo recommendations
WARNING: untranslated string: Captive vouchervalid
WARNING: untranslated string: Captive wrong ext
WARNING: untranslated string: MTU settings
WARNING: untranslated string: Number of Countries for the pie chart
WARNING: untranslated string: Scan for Songs
@@ -707,6 +736,7 @@ WARNING: untranslated string: advproxy group required
WARNING: untranslated string: application layer gateways
WARNING: untranslated string: block
WARNING: untranslated string: bytes
WARNING: untranslated string: captive
WARNING: untranslated string: check all
WARNING: untranslated string: dhcp dns enable update
WARNING: untranslated string: dhcp dns key name
@@ -715,6 +745,7 @@ WARNING: untranslated string: dhcp dns update algo
WARNING: untranslated string: dhcp dns update secret
WARNING: untranslated string: dl client arch insecure
WARNING: untranslated string: dnssec disabled warning
WARNING: untranslated string: eight hours
WARNING: untranslated string: email config
WARNING: untranslated string: email empty field
WARNING: untranslated string: email invalid
@@ -808,6 +839,9 @@ WARNING: untranslated string: masquerading enabled
WARNING: untranslated string: messages
WARNING: untranslated string: no data
WARNING: untranslated string: none
WARNING: untranslated string: one hour
WARNING: untranslated string: one month
WARNING: untranslated string: one week
WARNING: untranslated string: outgoing compression in bytes per second
WARNING: untranslated string: outgoing overhead in bytes per second
WARNING: untranslated string: ovpn add conf
@@ -825,6 +859,7 @@ WARNING: untranslated string: search
WARNING: untranslated string: unblock
WARNING: untranslated string: unblock all
WARNING: untranslated string: uncheck all
WARNING: untranslated string: unlimited
WARNING: untranslated string: uplink bit rate
WARNING: untranslated string: vpn broken
WARNING: untranslated string: vpn connecting

View File

@@ -691,6 +691,35 @@ WARNING: translation string unused: xtaccess all error
WARNING: translation string unused: xtaccess bad transfert
WARNING: translation string unused: year-graph
WARNING: translation string unused: yearly firewallhits
WARNING: untranslated string: 24 hours
WARNING: untranslated string: Captive ACTIVATE
WARNING: untranslated string: Captive GAIN ACCESS
WARNING: untranslated string: Captive activated
WARNING: untranslated string: Captive active on
WARNING: untranslated string: Captive agree tac
WARNING: untranslated string: Captive authentication
WARNING: untranslated string: Captive brand color
WARNING: untranslated string: Captive branding
WARNING: untranslated string: Captive client session expiry time
WARNING: untranslated string: Captive clients
WARNING: untranslated string: Captive config
WARNING: untranslated string: Captive coupon
WARNING: untranslated string: Captive expiry time
WARNING: untranslated string: Captive generate coupon
WARNING: untranslated string: Captive issued coupons
WARNING: untranslated string: Captive logo uploaded
WARNING: untranslated string: Captive mac
WARNING: untranslated string: Captive menu
WARNING: untranslated string: Captive noexpiretime
WARNING: untranslated string: Captive nolimit
WARNING: untranslated string: Captive please accept the terms and conditions
WARNING: untranslated string: Captive terms
WARNING: untranslated string: Captive terms short
WARNING: untranslated string: Captive title
WARNING: untranslated string: Captive upload logo
WARNING: untranslated string: Captive upload logo recommendations
WARNING: untranslated string: Captive vouchervalid
WARNING: untranslated string: Captive wrong ext
WARNING: untranslated string: MTU settings
WARNING: untranslated string: Number of Countries for the pie chart
WARNING: untranslated string: Scan for Songs
@@ -706,6 +735,7 @@ WARNING: untranslated string: atm device
WARNING: untranslated string: block
WARNING: untranslated string: bytes
WARNING: untranslated string: capabilities
WARNING: untranslated string: captive
WARNING: untranslated string: check all
WARNING: untranslated string: default
WARNING: untranslated string: dh
@@ -727,6 +757,7 @@ WARNING: untranslated string: dnssec not supported
WARNING: untranslated string: dnssec validating
WARNING: untranslated string: download tls-auth key
WARNING: untranslated string: drop outgoing
WARNING: untranslated string: eight hours
WARNING: untranslated string: email config
WARNING: untranslated string: email empty field
WARNING: untranslated string: email invalid
@@ -840,6 +871,9 @@ WARNING: untranslated string: nameserver
WARNING: untranslated string: no data
WARNING: untranslated string: none
WARNING: untranslated string: not a valid dh key
WARNING: untranslated string: one hour
WARNING: untranslated string: one month
WARNING: untranslated string: one week
WARNING: untranslated string: outgoing compression in bytes per second
WARNING: untranslated string: outgoing overhead in bytes per second
WARNING: untranslated string: ovpn add conf
@@ -871,6 +905,7 @@ WARNING: untranslated string: ta key
WARNING: untranslated string: unblock
WARNING: untranslated string: unblock all
WARNING: untranslated string: uncheck all
WARNING: untranslated string: unlimited
WARNING: untranslated string: uplink bit rate
WARNING: untranslated string: upload dh key
WARNING: untranslated string: vendor

View File

@@ -618,6 +618,35 @@ WARNING: translation string unused: xtaccess all error
WARNING: translation string unused: xtaccess bad transfert
WARNING: translation string unused: year-graph
WARNING: translation string unused: yearly firewallhits
WARNING: untranslated string: 24 hours
WARNING: untranslated string: Captive ACTIVATE
WARNING: untranslated string: Captive GAIN ACCESS
WARNING: untranslated string: Captive activated
WARNING: untranslated string: Captive active on
WARNING: untranslated string: Captive agree tac
WARNING: untranslated string: Captive authentication
WARNING: untranslated string: Captive brand color
WARNING: untranslated string: Captive branding
WARNING: untranslated string: Captive client session expiry time
WARNING: untranslated string: Captive clients
WARNING: untranslated string: Captive config
WARNING: untranslated string: Captive coupon
WARNING: untranslated string: Captive expiry time
WARNING: untranslated string: Captive generate coupon
WARNING: untranslated string: Captive issued coupons
WARNING: untranslated string: Captive logo uploaded
WARNING: untranslated string: Captive mac
WARNING: untranslated string: Captive menu
WARNING: untranslated string: Captive noexpiretime
WARNING: untranslated string: Captive nolimit
WARNING: untranslated string: Captive please accept the terms and conditions
WARNING: untranslated string: Captive terms
WARNING: untranslated string: Captive terms short
WARNING: untranslated string: Captive title
WARNING: untranslated string: Captive upload logo
WARNING: untranslated string: Captive upload logo recommendations
WARNING: untranslated string: Captive vouchervalid
WARNING: untranslated string: Captive wrong ext
WARNING: untranslated string: ConnSched dial
WARNING: untranslated string: ConnSched hangup
WARNING: untranslated string: ConnSched reboot
@@ -649,6 +678,7 @@ WARNING: untranslated string: bit
WARNING: untranslated string: block
WARNING: untranslated string: bytes
WARNING: untranslated string: capabilities
WARNING: untranslated string: captive
WARNING: untranslated string: ccd add
WARNING: untranslated string: ccd choose net
WARNING: untranslated string: ccd client options
@@ -729,6 +759,7 @@ WARNING: untranslated string: drop action1
WARNING: untranslated string: drop action2
WARNING: untranslated string: drop forward
WARNING: untranslated string: drop outgoing
WARNING: untranslated string: eight hours
WARNING: untranslated string: email config
WARNING: untranslated string: email empty field
WARNING: untranslated string: email invalid
@@ -1019,6 +1050,9 @@ WARNING: untranslated string: no hardware random number generator
WARNING: untranslated string: none
WARNING: untranslated string: not a valid dh key
WARNING: untranslated string: notice
WARNING: untranslated string: one hour
WARNING: untranslated string: one month
WARNING: untranslated string: one week
WARNING: untranslated string: openvpn default
WARNING: untranslated string: openvpn destination port used
WARNING: untranslated string: openvpn fragment allowed with udp
@@ -1143,6 +1177,7 @@ WARNING: untranslated string: tor use exit nodes
WARNING: untranslated string: unblock
WARNING: untranslated string: unblock all
WARNING: untranslated string: uncheck all
WARNING: untranslated string: unlimited
WARNING: untranslated string: uplink
WARNING: untranslated string: uplink bit rate
WARNING: untranslated string: upload dh key

View File

@@ -619,7 +619,36 @@ WARNING: translation string unused: wlanap wlan services
WARNING: translation string unused: xtaccess all error
WARNING: translation string unused: xtaccess bad transfert
WARNING: translation string unused: yearly firewallhits
WARNING: untranslated string: 24 hours
WARNING: untranslated string: Add a route
WARNING: untranslated string: Captive ACTIVATE
WARNING: untranslated string: Captive GAIN ACCESS
WARNING: untranslated string: Captive activated
WARNING: untranslated string: Captive active on
WARNING: untranslated string: Captive agree tac
WARNING: untranslated string: Captive authentication
WARNING: untranslated string: Captive brand color
WARNING: untranslated string: Captive branding
WARNING: untranslated string: Captive client session expiry time
WARNING: untranslated string: Captive clients
WARNING: untranslated string: Captive config
WARNING: untranslated string: Captive coupon
WARNING: untranslated string: Captive expiry time
WARNING: untranslated string: Captive generate coupon
WARNING: untranslated string: Captive issued coupons
WARNING: untranslated string: Captive logo uploaded
WARNING: untranslated string: Captive mac
WARNING: untranslated string: Captive menu
WARNING: untranslated string: Captive noexpiretime
WARNING: untranslated string: Captive nolimit
WARNING: untranslated string: Captive please accept the terms and conditions
WARNING: untranslated string: Captive terms
WARNING: untranslated string: Captive terms short
WARNING: untranslated string: Captive title
WARNING: untranslated string: Captive upload logo
WARNING: untranslated string: Captive upload logo recommendations
WARNING: untranslated string: Captive vouchervalid
WARNING: untranslated string: Captive wrong ext
WARNING: untranslated string: ConnSched dial
WARNING: untranslated string: ConnSched hangup
WARNING: untranslated string: ConnSched reboot
@@ -651,6 +680,7 @@ WARNING: untranslated string: bit
WARNING: untranslated string: block
WARNING: untranslated string: bytes
WARNING: untranslated string: capabilities
WARNING: untranslated string: captive
WARNING: untranslated string: ccd add
WARNING: untranslated string: ccd choose net
WARNING: untranslated string: ccd client options
@@ -733,6 +763,7 @@ WARNING: untranslated string: drop action1
WARNING: untranslated string: drop action2
WARNING: untranslated string: drop forward
WARNING: untranslated string: drop outgoing
WARNING: untranslated string: eight hours
WARNING: untranslated string: email config
WARNING: untranslated string: email empty field
WARNING: untranslated string: email invalid
@@ -1021,6 +1052,9 @@ WARNING: untranslated string: no hardware random number generator
WARNING: untranslated string: none
WARNING: untranslated string: not a valid dh key
WARNING: untranslated string: notice
WARNING: untranslated string: one hour
WARNING: untranslated string: one month
WARNING: untranslated string: one week
WARNING: untranslated string: openvpn default
WARNING: untranslated string: openvpn destination port used
WARNING: untranslated string: openvpn fragment allowed with udp
@@ -1138,6 +1172,7 @@ WARNING: untranslated string: tor use exit nodes
WARNING: untranslated string: unblock
WARNING: untranslated string: unblock all
WARNING: untranslated string: uncheck all
WARNING: untranslated string: unlimited
WARNING: untranslated string: uplink
WARNING: untranslated string: uplink bit rate
WARNING: untranslated string: upload dh key

View File

@@ -703,10 +703,41 @@ WARNING: translation string unused: xtaccess all error
WARNING: translation string unused: xtaccess bad transfert
WARNING: translation string unused: year-graph
WARNING: translation string unused: yearly firewallhits
WARNING: untranslated string: 24 hours
WARNING: untranslated string: Captive ACTIVATE
WARNING: untranslated string: Captive GAIN ACCESS
WARNING: untranslated string: Captive activated
WARNING: untranslated string: Captive active on
WARNING: untranslated string: Captive agree tac
WARNING: untranslated string: Captive authentication
WARNING: untranslated string: Captive brand color
WARNING: untranslated string: Captive branding
WARNING: untranslated string: Captive client session expiry time
WARNING: untranslated string: Captive clients
WARNING: untranslated string: Captive config
WARNING: untranslated string: Captive coupon
WARNING: untranslated string: Captive expiry time
WARNING: untranslated string: Captive generate coupon
WARNING: untranslated string: Captive issued coupons
WARNING: untranslated string: Captive logo uploaded
WARNING: untranslated string: Captive mac
WARNING: untranslated string: Captive menu
WARNING: untranslated string: Captive noexpiretime
WARNING: untranslated string: Captive nolimit
WARNING: untranslated string: Captive please accept the terms and conditions
WARNING: untranslated string: Captive terms
WARNING: untranslated string: Captive terms short
WARNING: untranslated string: Captive title
WARNING: untranslated string: Captive upload logo
WARNING: untranslated string: Captive upload logo recommendations
WARNING: untranslated string: Captive vouchervalid
WARNING: untranslated string: Captive wrong ext
WARNING: untranslated string: Scan for Songs
WARNING: untranslated string: application layer gateways
WARNING: untranslated string: bytes
WARNING: untranslated string: captive
WARNING: untranslated string: dnssec disabled warning
WARNING: untranslated string: eight hours
WARNING: untranslated string: firewall graph country
WARNING: untranslated string: firewall graph ip
WARNING: untranslated string: firewall graph port
@@ -755,10 +786,14 @@ WARNING: untranslated string: guardian watch snort alertfile
WARNING: untranslated string: ike lifetime should be between 1 and 8 hours
WARNING: untranslated string: info messages
WARNING: untranslated string: no data
WARNING: untranslated string: one hour
WARNING: untranslated string: one month
WARNING: untranslated string: one week
WARNING: untranslated string: route config changed
WARNING: untranslated string: routing config added
WARNING: untranslated string: routing config changed
WARNING: untranslated string: routing table
WARNING: untranslated string: unlimited
WARNING: untranslated string: uplink bit rate
WARNING: untranslated string: vpn broken
WARNING: untranslated string: vpn connecting

View File

@@ -2,6 +2,10 @@
# Checking cgi-bin translations for language: en #
############################################################################
< addon
< Captive clients
< Captive genvoucher
< Captive logo_upload
< Captive logo_upload1
< ccd maxclients
< ovpn_fragment
############################################################################
@@ -32,6 +36,54 @@
< bit
< block
< capabilities
< Captive 1day
< Captive 1month
< Captive 1week
< Captive activate
< Captive ACTIVATE
< Captive activated
< Captive active on
< Captive agree tac
< Captive authentication
< Captive auth_lic
< Captive auth_vou
< Captive brand color
< Captive branding
< Captive clients
< Captive client session expiry time
< Captive config
< Captive coupon
< Captive err doublevoucher
< Captive expire
< Captive expiry time
< Captive GAIN ACCESS
< Captive generate coupon
< Captive genvoucher
< Captive invalid logosize
< Captive invalid_voucher
< Captive ip
< Captive issued coupons
< Captive logo_set
< Captive logo_upload
< Captive logo_upload1
< Captive logo uploaded
< Captive mac
< Captive menu
< Captive noexpiretime
< Captive nolimit
< Captive nr
< Captive please accept the terms and conditions
< Captive terms
< Captive terms short
< Captive time
< Captive title
< Captive upload logo
< Captive upload logo recommendations
< Captive voactive
< Captive voucher
< Captive vouchervalid
< Captive vout
< Captive wrong ext
< ccd add
< ccd choose net
< ccd clientip
@@ -121,6 +173,7 @@
< drop action2
< drop forward
< drop outgoing
< eight hours
< email config
< email empty field
< email error
@@ -674,6 +727,54 @@
< bit
< block
< capabilities
< Captive 1day
< Captive 1month
< Captive 1week
< Captive activate
< Captive ACTIVATE
< Captive activated
< Captive active on
< Captive agree tac
< Captive authentication
< Captive auth_lic
< Captive auth_vou
< Captive brand color
< Captive branding
< Captive clients
< Captive client session expiry time
< Captive config
< Captive coupon
< Captive err doublevoucher
< Captive expire
< Captive expiry time
< Captive GAIN ACCESS
< Captive generate coupon
< Captive genvoucher
< Captive invalid logosize
< Captive invalid_voucher
< Captive ip
< Captive issued coupons
< Captive logo_set
< Captive logo_upload
< Captive logo_upload1
< Captive logo uploaded
< Captive mac
< Captive menu
< Captive noexpiretime
< Captive nolimit
< Captive nr
< Captive please accept the terms and conditions
< Captive terms
< Captive terms short
< Captive time
< Captive title
< Captive upload logo
< Captive upload logo recommendations
< Captive voactive
< Captive voucher
< Captive vouchervalid
< Captive vout
< Captive wrong ext
< ccd add
< ccd choose net
< ccd clientip
@@ -762,6 +863,7 @@
< drop action2
< drop forward
< drop outgoing
< eight hours
< email config
< email empty field
< email error
@@ -1297,6 +1399,54 @@
< bit
< block
< capabilities
< Captive 1day
< Captive 1month
< Captive 1week
< Captive activate
< Captive ACTIVATE
< Captive activated
< Captive active on
< Captive agree tac
< Captive authentication
< Captive auth_lic
< Captive auth_vou
< Captive brand color
< Captive branding
< Captive clients
< Captive client session expiry time
< Captive config
< Captive coupon
< Captive err doublevoucher
< Captive expire
< Captive expiry time
< Captive GAIN ACCESS
< Captive generate coupon
< Captive genvoucher
< Captive invalid logosize
< Captive invalid_voucher
< Captive ip
< Captive issued coupons
< Captive logo_set
< Captive logo_upload
< Captive logo_upload1
< Captive logo uploaded
< Captive mac
< Captive menu
< Captive noexpiretime
< Captive nolimit
< Captive nr
< Captive please accept the terms and conditions
< Captive terms
< Captive terms short
< Captive time
< Captive title
< Captive upload logo
< Captive upload logo recommendations
< Captive voactive
< Captive voucher
< Captive vouchervalid
< Captive vout
< Captive wrong ext
< ccd add
< ccd choose net
< ccd clientip
@@ -1385,6 +1535,7 @@
< drop action2
< drop forward
< drop outgoing
< eight hours
< email config
< email empty field
< email error
@@ -1907,6 +2058,54 @@
< bit
< block
< capabilities
< Captive 1day
< Captive 1month
< Captive 1week
< Captive activate
< Captive ACTIVATE
< Captive activated
< Captive active on
< Captive agree tac
< Captive authentication
< Captive auth_lic
< Captive auth_vou
< Captive brand color
< Captive branding
< Captive clients
< Captive client session expiry time
< Captive config
< Captive coupon
< Captive err doublevoucher
< Captive expire
< Captive expiry time
< Captive GAIN ACCESS
< Captive generate coupon
< Captive genvoucher
< Captive invalid logosize
< Captive invalid_voucher
< Captive ip
< Captive issued coupons
< Captive logo_set
< Captive logo_upload
< Captive logo_upload1
< Captive logo uploaded
< Captive mac
< Captive menu
< Captive noexpiretime
< Captive nolimit
< Captive nr
< Captive please accept the terms and conditions
< Captive terms
< Captive terms short
< Captive time
< Captive title
< Captive upload logo
< Captive upload logo recommendations
< Captive voactive
< Captive voucher
< Captive vouchervalid
< Captive vout
< Captive wrong ext
< ccd add
< ccd choose net
< ccd clientip
@@ -1998,6 +2197,7 @@
< drop forward
< drop outgoing
< Edit an existing route
< eight hours
< email config
< email empty field
< email error

666
html/cgi-bin/captive.cgi Executable file
View File

@@ -0,0 +1,666 @@
#!/usr/bin/perl
###############################################################################
# #
# IPFire.org - A linux based firewall #
# Copyright (C) 2016 IPFire Team <alexander.marx@ipfire.org> #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
###############################################################################
#use strict;
use HTML::Entities();
use File::Basename;
# enable only the following on debugging purpose
#use warnings;
#use CGI::Carp 'fatalsToBrowser';
require '/var/ipfire/general-functions.pl';
require "${General::swroot}/lang.pl";
require "${General::swroot}/header.pl";
my %selected = ();
my $coupons = "${General::swroot}/captive/coupons";
my %couponhash = ();
my $logo = "${General::swroot}/captive/logo.dat";
my %settings=();
my %mainsettings;
my %color;
my %cgiparams=();
my %netsettings=();
my %checked=();
my $errormessage='';
my $clients="${General::swroot}/captive/clients";
my %clientshash=();
my $settingsfile="${General::swroot}/captive/settings";
unless (-e $settingsfile) { system("touch $settingsfile"); }
&Header::getcgihash(\%cgiparams);
&General::readhash("${General::swroot}/main/settings", \%mainsettings);
&General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color);
&General::readhash("$settingsfile", \%settings) if(-f $settingsfile);
&General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
&Header::showhttpheaders();
if ($cgiparams{'ACTION'} eq $Lang::tr{'save'}) {
my $file = $cgiparams{'logo'};
if ($file) {
# Check if the file extension is PNG/JPEG
chomp $file;
my ($name, $path, $ext) = fileparse($file, qr/\.[^.]*$/);
if ($ext ne ".png" && $ext ne ".jpg" && $ext ne ".jpeg") {
$errormessage = $Lang::tr{'Captive wrong ext'};
}
}
$settings{'ENABLE_GREEN'} = $cgiparams{'ENABLE_GREEN'};
$settings{'ENABLE_BLUE'} = $cgiparams{'ENABLE_BLUE'};
$settings{'AUTH'} = $cgiparams{'AUTH'};
$settings{'TITLE'} = $cgiparams{'TITLE'};
$settings{'COLOR'} = $cgiparams{'COLOR'};
$settings{'SESSION_TIME'} = $cgiparams{'SESSION_TIME'};
if (!$errormessage){
#Check if we need to upload a new logo
if ($file) {
# Save logo
my ($filehandle) = CGI::upload("logo");
# XXX check filesize
open(FILE, ">$logo");
binmode $filehandle;
while (<$filehandle>) {
print FILE;
}
close(FILE);
}
&General::writehash("$settingsfile", \%settings);
# Save terms
if ($cgiparams{'TERMS'}){
$cgiparams{'TERMS'} = &Header::escape($cgiparams{'TERMS'});
open(FH, ">:utf8", "/var/ipfire/captive/terms.txt") or die("$!");
print FH $cgiparams{'TERMS'};
close(FH);
$cgiparams{'TERMS'} = "";
}
#execute binary to reload firewall rules
system("/usr/local/bin/captivectrl");
if ($cgiparams{'ENABLE_BLUE'} eq 'on'){
system("/usr/local/bin/wirelessctrl");
}
}
}
if ($cgiparams{'ACTION'} eq "$Lang::tr{'Captive generate coupon'}") {
# Check expiry time
if ($cgiparams{'EXP_HOUR'} + $cgiparams{'EXP_DAY'} + $cgiparams{'EXP_WEEK'} + $cgiparams{'EXP_MONTH'} == 0 && $cgiparams{'UNLIMITED'} == '') {
$errormessage = $Lang::tr{'Captive noexpiretime'};
}
#check valid remark
if ($cgiparams{'REMARK'} ne '' && !&validremark($cgiparams{'REMARK'})){
$errormessage=$Lang::tr{'fwhost err remark'};
}
if (!$errormessage) {
# Remember selected values
foreach my $val (("UNLIMITED", "EXP_HOUR", "EXP_DAY", "EXP_WEEK", "EXP_MONTH")) {
$settings{$val} = $cgiparams{$val};
}
&General::writehash($settingsfile, \%settings);
&General::readhasharray($coupons, \%couponhash) if (-e $coupons);
my $now = time();
# Calculate expiry time in seconds
my $expires = 0;
if ($settings{'UNLIMITED'} ne 'on') {
$expires += $settings{'EXP_HOUR'};
$expires += $settings{'EXP_DAY'};
$expires += $settings{'EXP_WEEK'};
$expires += $settings{'EXP_MONTH'};
}
my $count = $cgiparams{'COUNT'} || 1;
while($count-- > 0) {
# Generate a new code
my $code = &gencode();
# Check if the coupon code already exists
foreach my $key (keys %couponhash) {
if($couponhash{$key}[1] eq $code) {
# Code already exists, so try again
$code = "";
$count++;
last;
}
}
next if ($code eq "");
# Get a new key from hash
my $key = &General::findhasharraykey(\%couponhash);
# Initialize all fields
foreach my $i (0 .. 3) { $couponhash{$key}[$i] = ""; }
$couponhash{$key}[0] = $now;
$couponhash{$key}[1] = $code;
$couponhash{$key}[2] = $expires;
$couponhash{$key}[3] = $cgiparams{'REMARK'};
}
# Save everything to disk
&General::writehasharray($coupons, \%couponhash);
}
}
if ($cgiparams{'ACTION'} eq 'delete-coupon') {
#deletes an already generated but unused voucher
#read all generated vouchers
&General::readhasharray($coupons, \%couponhash) if (-e $coupons);
foreach my $key (keys %couponhash) {
if($cgiparams{'key'} eq $couponhash{$key}[0]){
#write logenty with decoded remark
my $rem=HTML::Entities::decode_entities($couponhash{$key}[4]);
&General::log("Captive", "Delete unused coupon $couponhash{$key}[1] $couponhash{$key}[2] hours valid expires on $couponhash{$key}[3] remark $rem");
#delete line from hash
delete $couponhash{$key};
last;
}
}
#write back hash
&General::writehasharray($coupons, \%couponhash);
}
if ($cgiparams{'ACTION'} eq 'delete-client') {
#delete voucher and connection in use
#read all active clients
&General::readhasharray($clients, \%clientshash) if (-e $clients);
foreach my $key (keys %clientshash) {
if($cgiparams{'key'} eq $clientshash{$key}[0]){
#prepare log entry with decoded remark
my $rem=HTML::Entities::decode_entities($clientshash{$key}[7]);
#write logentry
&General::log("Captive", "Deleted client in use $clientshash{$key}[1] $clientshash{$key}[2] hours valid expires on $clientshash{$key}[3] remark $rem - Connection will be terminated");
#delete line from hash
delete $clientshash{$key};
last;
}
}
#write back hash
&General::writehasharray("$clients", \%clientshash);
#reload firewallrules to kill connection of client
system("/usr/local/bin/captivectrl");
}
#open webpage, print header and open box
&Header::openpage($Lang::tr{'Captive menu'}, 1, '');
&Header::openbigbox();
# If an error message exists, show a box with the error message
if ($errormessage) {
&Header::openbox('100%', 'left', $Lang::tr{'error messages'});
print $errormessage;
&Header::closebox();
}
# Prints the config box on the website
&Header::openbox('100%', 'left', $Lang::tr{'Captive config'});
print <<END
<form method='post' action='$ENV{'SCRIPT_NAME'}' enctype="multipart/form-data">\n
<table width='100%' border="0">
<tr>
END
;
#check which parameters have to be enabled (from settings file)
$checked{'ENABLE_GREEN'}{'off'} = '';
$checked{'ENABLE_GREEN'}{'on'} = '';
$checked{'ENABLE_GREEN'}{$settings{'ENABLE_GREEN'}} = "checked='checked'";
$checked{'ENABLE_BLUE'}{'off'} = '';
$checked{'ENABLE_BLUE'}{'on'} = '';
$checked{'ENABLE_BLUE'}{$settings{'ENABLE_BLUE'}} = "checked='checked'";
$checked{'UNLIMITED'}{'off'} = '';
$checked{'UNLIMITED'}{'on'} = '';
$checked{'UNLIMITED'}{$settings{'UNLIMITED'}} = "checked='checked'";
$selected{'AUTH'} = ();
$selected{'AUTH'}{'COUPON'} = "";
$selected{'AUTH'}{'TERMS'} = "";
$selected{'AUTH'}{$settings{'AUTH'}} = "selected";
if ($netsettings{'GREEN_DEV'}){
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>";
}
if ($netsettings{'BLUE_DEV'}){
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>";
}
print<<END
</tr>
<tr>
<td>
$Lang::tr{'Captive authentication'}
</td>
<td>
<select name='AUTH'>
<option value="TERMS" $selected{'AUTH'}{'TERMS'} >$Lang::tr{'Captive terms'}</option>
<option value="COUPON" $selected{'AUTH'}{'COUPON'}>$Lang::tr{'Captive coupon'}</option>
</select>
</td>
</tr>
END
;
if ($settings{'AUTH'} eq 'TERMS') {
$selected{'SESSION_TIME'} = ();
$selected{'SESSION_TIME'}{'0'} = "";
$selected{'SESSION_TIME'}{'3600'} = "";
$selected{'SESSION_TIME'}{'86400'} = "";
$selected{'SESSION_TIME'}{'604800'} = "";
$selected{'SESSION_TIME'}{'18144000'} = "";
$selected{'SESSION_TIME'}{$settings{'SESSION_TIME'}} = "selected";
my $terms = &getterms();
print <<END;
<tr>
<td></td>
<td>
<textarea cols="50" rows="10" name="TERMS">$terms</textarea>
</td>
</tr>
<tr>
<td>$Lang::tr{'Captive client session expiry time'}</td>
<td>
<select name="SESSION_TIME">
<option value="0" $selected{'SESSION_TIME'}{'0'}>- $Lang::tr{'unlimited'} -</option>
<option value="3600" $selected{'SESSION_TIME'}{'3600'}>$Lang::tr{'one hour'}</option>
<option value="28800" $selected{'SESSION_TIME'}{'28800'}>$Lang::tr{'eight hours'}</option>
<option value="86400" $selected{'SESSION_TIME'}{'86400'}>$Lang::tr{'24 hours'}</option>
<option value="604800" $selected{'SESSION_TIME'}{'604800'}>$Lang::tr{'one week'}</option>
<option value="18144000" $selected{'SESSION_TIME'}{'18144000'}>$Lang::tr{'one month'}</option>
</select>
</td>
</tr>
END
}
print<<END;
<tr>
<td colspan="2">
<br>
<strong>$Lang::tr{'Captive branding'}</strong>
</td>
</tr>
<tr>
<td>
$Lang::tr{'Captive title'}
</td>
<td>
<input type='text' name='TITLE' value="$settings{'TITLE'}" size='40'>
</td>
</tr>
<tr>
<td>$Lang::tr{'Captive brand color'}</td>
<td>
<input type="color" name="COLOR" value="$settings{'COLOR'}">
</td>
</tr>
<tr>
<td>
$Lang::tr{'Captive upload logo'}
</td>
<td>
<input type="file" name="logo">
<br>$Lang::tr{'Captive upload logo recommendations'}
</td>
</tr>
END
if (-e $logo) {
print <<END;
<tr>
<td>$Lang::tr{'Captive logo uploaded'}</td>
<td>$Lang::tr{'yes'}</td>
</tr>
END
}
print <<END;
<tr>
<td></td>
<td align='right'>
<input type='submit' name='ACTION' value="$Lang::tr{'save'}"/>
</td>
</tr>
</table></form>
END
&Header::closebox();
#if settings is set to use coupons, the coupon part has to be displayed
if ($settings{'AUTH'} eq 'COUPON') {
&coupons();
}
# Show active clients
&show_clients();
sub getterms() {
my @ret;
open(FILE, "<:utf8", "/var/ipfire/captive/terms.txt");
while(<FILE>) {
push(@ret, HTML::Entities::decode_entities($_));
}
close(FILE);
return join(/\n/, @ret);
}
sub gencode(){
#generate a random code only letters from A-Z except 'O' and 0-9
my @chars = ("A".."N", "P".."Z", "0".."9");
my $randomstring;
$randomstring .= $chars[rand @chars] for 1..8;
return $randomstring;
}
sub coupons() {
&Header::openbox('100%', 'left', $Lang::tr{'Captive generate coupon'});
print <<END;
<form method='post' action='$ENV{'SCRIPT_NAME'}'>
<table border='0' width='100%'>
<tr>
<td width='30%'>
$Lang::tr{'Captive vouchervalid'}
</td>
<td width='70%'>
<table class='tbl' border='0' width='100%'>
<tr>
<th>$Lang::tr{'hours'}</th>
<th>$Lang::tr{'days'}</th>
<th>$Lang::tr{'weeks'}</th>
<th>$Lang::tr{'months'}</th>
<th></th>
</tr>
END
#print hour-dropdownbox
my $hrs=3600;
print "<tr height='40px'><td><select name='EXP_HOUR' style='width:8em;'>";
print "<option value='0' ";
print " selected='selected'" if ($settings{'EXP_HOUR'} eq '0');
print ">--</option>";
for (my $i = 1; $i<25; $i++){
my $exp_sec = $i * $hrs;
print "<option value='$exp_sec' ";
print " selected='selected'" if ($settings{'EXP_HOUR'} eq $exp_sec);
print ">$i</option>";
}
print "</td><td>";
#print day-dropdownbox
my $days=3600*24;
print "<select name='EXP_DAY' style='width:8em;'>";
print "<option value='0' ";
print " selected='selected'" if ($settings{'EXP_DAY'} eq '0');
print ">--</option>";
for (my $i = 1; $i<8; $i++){
my $exp_sec = $i * $days;
print "<option value='$exp_sec' ";
print " selected='selected'" if ($settings{'EXP_DAY'} eq $exp_sec);
print ">$i</option>";
}
print "</td><td>";
#print week-dropdownbox
my $week=3600*24*7;
print "<select name='EXP_WEEK' style='width:8em;'>";
print "<option value='0' ";
print " selected='selected'" if ($settings{'EXP_WEEK'} eq '0');
print ">--</option>";
for (my $i = 1; $i<5; $i++){
my $exp_sec = $i * $week;
print "<option value='$exp_sec' ";
print " selected='selected'" if ($settings{'EXP_WEEK'} eq $exp_sec);
print ">$i</option>";
}
print "</td><td>";
#print month-dropdownbox
my $month=3600*24*30;
print "<select name='EXP_MONTH' style='width:8em;'>";
print "<option value='0' ";
print " selected='selected'" if ($settings{'EXP_MONTH'} eq '0');
print ">--</option>";
for (my $i = 1; $i<13; $i++){
my $exp_sec = $i * $month;
print "<option value='$exp_sec' ";
print " selected='selected'" if ($settings{'EXP_MONTH'} eq $exp_sec);
print ">$i</option>";
}
print <<END;
</td>
<td>
<label>
<input type='checkbox' name='UNLIMITED' $checked{'UNLIMITED'}{'on'} />
$Lang::tr{'Captive nolimit'}
</label>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>$Lang::tr{'remark'}</td>
<td>
<input type='text' style='width: 98%;' name='REMARK' align='left'>
</td>
</tr>
</table>
<div align="right">
<select name="COUNT">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
<option value="20">20</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
<input type="submit" name="ACTION" value="$Lang::tr{'Captive generate coupon'}">
</div>
</form>
END
&Header::closebox();
# Show all coupons if exist
if (! -z $coupons) {
&show_coupons();
}
}
sub show_coupons() {
&General::readhasharray($coupons, \%couponhash) if (-e $coupons);
#if there are already generated but unsused coupons, print a table
&Header::openbox('100%', 'left', $Lang::tr{'Captive issued coupons'});
print <<END;
<table class='tbl' border='0'>
<tr>
<th align='center' width='15%'>
$Lang::tr{'Captive coupon'}
</th>
<th align='center' width='15%'>$Lang::tr{'Captive expiry time'}</th>
<th align='center' width='65%'>$Lang::tr{'remark'}</th>
<th align='center' width='5%'>$Lang::tr{'delete'}</th>
</tr>
END
foreach my $key (keys %couponhash) {
my $expirytime = $Lang::tr{'Captive nolimit'};
if ($couponhash{$key}[2] > 0) {
$expirytime = &General::format_time($couponhash{$key}[2]);
}
if ($count++ % 2) {
$col="bgcolor='$color{'color20'}'";
} else {
$col="bgcolor='$color{'color22'}'";
}
print <<END;
<tr>
<td $col align="center">
<b>$couponhash{$key}[1]</b>
</td>
<td $col align="center">
$expirytime
</td>
<td $col align="center">
$couponhash{$key}[3]
</td>
<td $col align="center">
<form method='post'>
<input type='image' src='/images/delete.gif' align='middle' alt='$Lang::tr{'delete'}' title='$Lang::tr{'delete'}' />
<input type='hidden' name='ACTION' value='delete-coupon' />
<input type='hidden' name='key' value='$couponhash{$key}[0]' />
</form>
</td>
</tr>
END
}
print "</table>";
&Header::closebox();
}
sub show_clients() {
# if there are active clients which use coupons show table
return if ( -z $clients || ! -f $clients );
my $count=0;
my $col;
&Header::openbox('100%', 'left', $Lang::tr{'Captive clients'});
print <<END;
<table class='tbl' width='100%'>
<tr>
<th align='center' width='15%'>$Lang::tr{'Captive coupon'}</th>
<th align='center' width='15%'>$Lang::tr{'Captive activated'}</th>
<th align='center' width='15%'>$Lang::tr{'Captive expiry time'}</th>
<th align='center' width='10%'>$Lang::tr{'Captive mac'}</th>
<th align='center' width='43%'>$Lang::tr{'remark'}</th>
<th align='center' width='5%'>$Lang::tr{'delete'}</th>
</tr>
END
&General::readhasharray($clients, \%clientshash) if (-e $clients);
foreach my $key (keys %clientshash) {
#calculate time from clientshash (starttime)
my $starttime = sub{sprintf '%02d.%02d.%04d %02d:%02d', $_[3], $_[4]+1, $_[5]+1900, $_[2], $_[1] }->(localtime($clientshash{$key}[2]));
#calculate endtime from clientshash
my $endtime;
if ($clientshash{$key}[3] eq '0'){
$endtime=$Lang::tr{'Captive nolimit'};
} else {
$endtime = sub{sprintf '%02d.%02d.%04d %02d:%02d', $_[3], $_[4]+1, $_[5]+1900, $_[2], $_[1] }->(localtime($clientshash{$key}[2]+$clientshash{$key}[3]));
}
if ($count++ % 2) {
$col="bgcolor='$color{'color20'}'";
} else {
$col="bgcolor='$color{'color22'}'";
}
my $coupon = ($clientshash{$key}[4] eq "LICENSE") ? $Lang::tr{'Captive terms short'} : $clientshash{$key}[4];
print <<END;
<tr>
<td $col align="center"><b>$coupon</b></td>
<td $col align="center">$starttime</td>
<td $col align="center">$endtime</td>
<td $col align="center">$clientshash{$key}[0]</td>
<td $col align="center">$clientshash{$key}[5]</td>
<td $col align="center">
<form method='post'>
<input type='image' src='/images/delete.gif' align='middle' alt='$Lang::tr{'delete'}' title='$Lang::tr{'delete'}' />
<input type='hidden' name='ACTION' value='delete-client' />
<input type='hidden' name='key' value='$clientshash{$key}[0]' />
</form>
</td>
</tr>
END
}
print "</table>";
&Header::closebox();
}
sub validremark
{
# Checks a hostname against RFC1035
my $remark = $_[0];
# Each part should be at least two characters in length
# but no more than 63 characters
if (length ($remark) < 1 || length ($remark) > 255) {
return 0;}
# Only valid characters are a-z, A-Z, 0-9 and -
if ($remark !~ /^[a-zäöüA-ZÖÄÜ0-9-.:;\|_()\/\s]*$/) {
return 0;}
# First character can only be a letter or a digit
if (substr ($remark, 0, 1) !~ /^[a-zäöüA-ZÖÄÜ0-9]*$/) {
return 0;}
# Last character can only be a letter or a digit
if (substr ($remark, -1, 1) !~ /^[a-zöäüA-ZÖÄÜ0-9.:;_)]*$/) {
return 0;}
return 1;
}
&Header::closebigbox();
&Header::closepage();

238
html/cgi-bin/captive/index.cgi Executable file
View File

@@ -0,0 +1,238 @@
#!/usr/bin/perl
###############################################################################
# #
# IPFire.org - A linux based firewall #
# Copyright (C) 2016 Alexander Marx alexander.marx@ipfire.org #
# #
# This program is free software you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
###############################################################################
use strict;
use CGI ':standard';
use URI::Escape;
use HTML::Entities();
use HTML::Template;
# enable only the following on debugging purpose
#use warnings;
#use CGI::Carp 'fatalsToBrowser';
require '/var/ipfire/general-functions.pl';
require "${General::swroot}/lang.pl";
# Load the most appropriate language from the browser configuration
my @langs = &Lang::DetectBrowserLanguages();
&Lang::reload(@langs);
my $coupons = "${General::swroot}/captive/coupons";
my %couponhash = ();
my %clientshash=();
my %cgiparams=();
my %settings=();
my $clients="${General::swroot}/captive/clients";
my $settingsfile="${General::swroot}/captive/settings";
my $errormessage;
my $url=param('redirect');
#Create /var/ipfire/captive/clients if not exist
unless (-f $clients){ system("touch $clients"); }
#Get GUI variables
&getcgihash(\%cgiparams);
#Read settings
&General::readhash("$settingsfile", \%settings) if(-f $settingsfile);
# Actions
if ($cgiparams{'ACTION'} eq "SUBMIT") {
# Get client IP address
my $ip_address = $ENV{X_FORWARDED_FOR} || $ENV{REMOTE_ADDR};
# Retrieve the MAC address from the ARP table
my $mac_address = &Network::get_hardware_address($ip_address);
&General::readhasharray("$clients", \%clientshash);
my $key = &General::findhasharraykey(\%clientshash);
# Create a new client line
foreach my $i (0 .. 5) { $clientshash{$key}[$i] = ""; }
# MAC address of the client
$clientshash{$key}[0] = $mac_address;
# IP address of the client
$clientshash{$key}[1] = $ip_address;
# Current time
$clientshash{$key}[2] = time();
if ($settings{"AUTH"} eq "COUPON") {
&General::readhasharray($coupons, \%couponhash);
if ($cgiparams{'COUPON'}) {
# Convert coupon input to uppercase
$cgiparams{'COUPON'} = uc $cgiparams{'COUPON'};
# Walk through all valid coupons and find the right one
my $found = 0;
foreach my $coupon (keys %couponhash) {
if ($couponhash{$coupon}[1] eq $cgiparams{'COUPON'}) {
$found = 1;
# Copy expiry time
$clientshash{$key}[3] = $couponhash{$coupon}[2];
# Save coupon code
$clientshash{$key}[4] = $cgiparams{'COUPON'};
# Copy coupon remark
$clientshash{$key}[5] = $couponhash{$coupon}[3];
# Delete used coupon
delete $couponhash{$coupon};
&General::writehasharray($coupons, \%couponhash);
last;
}
}
if ($found == 1) {
&General::log("Captive", "Internet access granted via coupon ($clientshash{$key}[4]) for $ip_address until $clientshash{$key}[3]");
} else {
$errormessage = $Lang::tr{"Captive invalid coupon"};
}
# No coupon given
} else {
$errormessage = $Lang::tr{"Captive please enter a coupon code"};
}
# Terms
} else {
# Make sure that they have been accepted
if ($cgiparams{'TERMS'} eq "on") {
# Copy session expiry time
$clientshash{$key}[3] = $settings{'SESSION_TIME'} || "0";
# No coupon code
$clientshash{$key}[4] = "TERMS";
&General::log("Captive", "Internet access granted via license agreement for $ip_address until $clientshash{$key}[3]");
# The terms have not been accepted
} else {
$errormessage = $Lang::tr{'Captive please accept the terms and conditions'};
}
}
# If no errors were found, save configruation and reload
if (!$errormessage) {
&General::writehasharray("$clients", \%clientshash);
system("/usr/local/bin/captivectrl");
# Redirect client to the original URL
print "Status: 302 Moved Temporarily\n";
print "Location: $url\n";
print "Connection: close\n\n";
exit 0;
}
}
my $tmpl = HTML::Template->new(
filename => "/srv/web/ipfire/html/captive/template.html",
die_on_bad_params => 0
);
$tmpl->param(REDIRECT => $url);
# Coupon
if ($settings{'AUTH'} eq "COUPON") {
$tmpl->param(COUPON => 1);
$tmpl->param(L_HEADING => $Lang::tr{'Captive coupon'});
} else {
$tmpl->param(L_HEADING => $Lang::tr{'Captive terms'});
}
$tmpl->param(TITLE => $settings{'TITLE'});
$tmpl->param(COLOR => $settings{'COLOR'});
$tmpl->param(ERROR => $errormessage);
$tmpl->param(TERMS => &getterms());
# Some translated strings
$tmpl->param(L_ACTIVATE => $Lang::tr{'Captive ACTIVATE'});
$tmpl->param(L_GAIN_ACCESS => $Lang::tr{'Captive GAIN ACCESS'});
$tmpl->param(L_AGREE_TERMS => $Lang::tr{'Captive agree tac'});
# Print header
print "Pragma: no-cache\n";
print "Cache-control: no-cache\n";
print "Connection: close\n";
print "Content-type: text/html\n\n";
# Print rendered template
print $tmpl->output();
sub getcgihash {
my ($hash, $params) = @_;
my $cgi = CGI->new ();
$hash->{'__CGI__'} = $cgi;
return if ($ENV{'REQUEST_METHOD'} ne 'POST');
if (!$params->{'wantfile'}) {
$CGI::DISABLE_UPLOADS = 1;
$CGI::POST_MAX = 1024 * 1024;
} else {
$CGI::POST_MAX = 10 * 1024 * 1024;
}
$cgi->referer() =~ m/^http?\:\/\/([^\/]+)/;
my $referer = $1;
$cgi->url() =~ m/^http?\:\/\/([^\/]+)/;
my $servername = $1;
return if ($referer ne $servername);
### Modified for getting multi-vars, split by |
my %temp = $cgi->Vars();
foreach my $key (keys %temp) {
$hash->{$key} = $temp{$key};
$hash->{$key} =~ s/\0/|/g;
$hash->{$key} =~ s/^\s*(.*?)\s*$/$1/;
}
if (($params->{'wantfile'})&&($params->{'filevar'})) {
$hash->{$params->{'filevar'}} = $cgi->upload
($params->{'filevar'});
}
return;
}
sub getterms() {
my @terms = ();
open(my $handle, "<:utf8", "/var/ipfire/captive/terms.txt");
while(<$handle>) {
$_ = HTML::Entities::decode_entities($_);
push(@terms, $_);
}
close($handle);
my $terms = join("\n", @terms);
# Format paragraphs
$terms =~ s/\n\n/<\/p>\n<p>/g;
return $terms;
}

View File

@@ -0,0 +1,44 @@
#!/usr/bin/perl
###############################################################################
# #
# IPFire.org - A linux based firewall #
# Copyright (C) 2016 Alexander Marx alexander.marx@ipfire.org #
# #
# This program is free software you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
###############################################################################
use strict;
use CGI;
use File::Copy;
# enable only the following on debugging purpose
#use warnings;
#use CGI::Carp 'fatalsToBrowser';
require '/var/ipfire/general-functions.pl';
my $logo = "${General::swroot}/captive/logo.dat";
# Send 404 if logo was not uploaded and exit
if (!-e $logo) {
print CGI::header(status => 404);
exit(0);
}
print "Content-Type: application/octet-stream\n\n";
# Send image data
File::Copy::copy $logo, \*STDOUT;
exit(0);

View File

@@ -0,0 +1,58 @@
#!/usr/bin/perl
###############################################################################
# #
# IPFire.org - A linux based firewall #
# Copyright (C) 2016 Alexander Marx alexander.marx@ipfire.org #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
###############################################################################
use strict;
use URI::Escape;
use CGI::Carp qw(fatalsToBrowser);
require '/var/ipfire/general-functions.pl';
my $url = "http://$ENV{'SERVER_NAME'}$ENV{'REQUEST_URI'}";
my $safe_url = uri_escape($url);
my %settingshash = ();
my %ethernethash = ();
my $target;
# Read settings
&General::readhash("${General::swroot}/captive/settings", \%settingshash);
&General::readhash("${General::swroot}/ethernet/settings", \%ethernethash);
# Get the client's IP address
my $client_address = $ENV{X_FORWARDED_FOR} || $ENV{REMOTE_ADDR} || "";
if ($settingshash{'ENABLE_GREEN'} eq "on" && $ethernethash{'GREEN_ADDRESS'} ne '') {
if (&General::IpInSubnet($client_address, $ethernethash{'GREEN_ADDRESS'}, $ethernethash{'GREEN_NETMASK'})) {
$target = $ethernethash{'GREEN_ADDRESS'};
}
} elsif($settingshash{'ENABLE_BLUE'} eq "on" && $ethernethash{'BLUE_ADDRESS'} ne '') {
if (&General::IpInSubnet($client_address, $ethernethash{'BLUE_ADDRESS'}, $ethernethash{'BLUE_NETMASK'})) {
$target = $ethernethash{'BLUE_ADDRESS'};
}
} else {
exit 0;
}
print "Status: 302 Moved Temporarily\n";
print "Location: http://$target:1013/cgi-bin/index.cgi?redirect=$safe_url\n";
print "Connection: close\n\n";

View File

@@ -51,6 +51,7 @@ $cgiparams{'SECTION'} = 'ipfire';
my %sections = (
'auth' => '(\w+\(pam_unix\)\[.*\]: )',
'wio' => '(wio|wio\[.*\])',
'captive' => '(Captive:)',
'clamav' => '(clamd\[.*\]: |freshclam\[.*\]: )',
'collectd' => '(collectd\[.*\]: )',
'cron' => '(fcron\[.*\]: )',
@@ -77,6 +78,7 @@ my %sections = (
my %trsections = (
'auth' => "$Lang::tr{'loginlogout'}",
'wio' => 'Who Is Online?',
'captive' => $Lang::tr{'captive'},
'clamav' => 'ClamAV',
'collectd' => 'Collectd',
'cron' => 'Cron',

View File

@@ -0,0 +1,194 @@
@font-face {
font-family: "Ubuntu";
font-weight: 300;
src: local("Ubuntu Light"), local("Ubuntu-Light"), url("Ubuntu-L.ttf") format("truetype");
}
@font-face {
font-family: "Ubuntu";
font-weight: 400;
src: local("Ubuntu Regular"), local("Ubuntu-Regular"), url("Ubuntu-R.ttf") format("truetype");
}
@font-face {
font-family: "Ubuntu";
font-weight: 500;
src: local("Ubuntu Medium"), local("Ubuntu-Medium"), url("Ubuntu-M.ttf") format("truetype");
}
body {
background-image: url("../cgi-bin/logo.cgi");
background-size: 100%;
background-repeat: no-repeat;
background-color: #eceff1;
color: #263238;
display: flex;
min-height: 100vh;
flex-direction: column;
}
body, input {
font-family: "Ubuntu", sans-serif;
font-size: 14px;
}
.content {
flex: 1;
}
.box {
margin: 272px 0 48px 0;
padding: 0 30px 48px 30px;
position: relative;
display: flex;
flex-direction: column;
background-color: white;
border: none;
border-radius: 4px;
box-shadow:
0 19px 38px 0 rgba(0, 0, 0, 0.3),
0 15px 12px 0 rgba(0, 0, 0, 0.22);
}
.box-header {
display: flex;
align-items: center;
justify-content: center;
min-height: 128px;
}
.box-header h1 {
font-size: 40px;
}
@media (min-width: 1200px) {
.box-header {
min-height: none;
}
.box-header h1 {
margin-top: 24px;
margin-bottom: 20px;
}
}
.box-block {
padding: 24px 16px 24px 16px;
margin: 0 -8px 40px -8px;
text-align: center;
background-color: #b71c1c;
color: white;
border-radius: 4px;
}
@media (min-width: 1200px) {
.box-block {
padding: 18px 16px 18px 16px;
margin: 0 0 48px 0;
}
}
.box-block h4 {
font-size: 20px;
}
footer {
height: 64px;
background-color: rgba(84, 110, 122, 0.06); /* #546e7a */
}
.footer {
display: flex;
align-items: center;
}
.footer .logo {
width: 64px;
height: 64px;
padding: 8px;
}
.form-text {
display: inline-block;
height: 36px;
color: #263238;
background-color: rgba(38, 49, 56, 0,08);
border: 0;
border-radius: 2px;
box-shadow: inset 0 -2px 0 0 #546e7a;
}
.form-error {
box-shadow: inset 0 -2px 0 0 #ff3d00;
}
.form-submit {
display: inline-block;
font-weight: 500;
text-transform: uppercase;
height: 36px;
padding: 0 16px 0 16px;
margin: 0 8px 0 8px;
color: #263238;
background-color: white;
border: none;
border-radius: 2px;
box-shadow:
0 2px 4px 0 rgba(0, 0, 0, 0.16),
0 1px 2px 0 rgba(0, 0, 0, 0.23);
}
.form-submit:hover {
box-shadow:
0 3px 6px 0 rgba(0, 0, 0, 0.16),
0 3px 6px 0 rgba(0, 0, 0, 0.23);
}
.form-submit:active {
background-color: black;
opacity: 0.16;
box-shadow: none;
}
.checkbox {
position: relative;
display: block;
margin-top: 20px;
}
.checkbox .form-checkbox {
position: absolute;
margin-top: 1px;
margin-left: -24px;
width: 20px;
height: 20px;
background-color: rgba(38, 49, 56, 0.08);
border: 2px solid #546e7a;
border-radius: 2px;
}
.text-error {
position: block;
margin-top: 6px;
min-height: 23px;
color: white;
background-color: #ff3d00;
border-radius: 2px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -0,0 +1,79 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title><TMPL_VAR NAME="TITLE"></title>
<link rel="stylesheet" href="../assets/bootstrap-reboot.min.css">
<link rel="stylesheet" href="../assets/bootstrap-grid.min.css">
<link rel="stylesheet" href="../assets/captive.css">
<TMPL_IF NAME="COLOR">
<style>
.box-block {
background-color: <TMPL_VAR NAME="COLOR">;
}
</style>
</TMPL_IF>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
</head>
<body>
<div class="container content">
<div class="row">
<div class="col-12 col-lg-10 offset-lg-1 col-xl-8 offset-xl-2">
<div class="box">
<div class="box-header">
<h1><TMPL_VAR NAME="TITLE"></h1>
</div>
<div class="box-block">
<h4><TMPL_VAR NAME="L_HEADING"></h4>
<form action="" method="POST">
<input type="hidden" name="ACTION" value="SUBMIT">
<input type="hidden" name="redirect" value="<TMPL_VAR NAME="REDIRECT">">
<TMPL_IF NAME="COUPON">
<input class="form-text <TMPL_IF NAME="ERROR">form-error</TMPL_IF>" type="text" name="COUPON">
<input class="form-submit" type="submit"
value="<TMPL_VAR NAME="L_ACTIVATE">">
<TMPL_ELSE>
<div class="checkbox">
<label>
<input class="form-checkbox <TMPL_IF NAME="ERROR">error</TMPL_IF>" type="checkbox" name="TERMS">
<TMPL_VAR NAME="L_AGREE_TERMS">
</label>
</div>
<input class="form-submit" type="submit"
value="<TMPL_VAR NAME="L_GAIN_ACCESS">">
</TMPL_IF>
<TMPL_IF NAME="ERROR">
<div class="text-error">
<TMPL_VAR NAME="ERROR">
</div>
</TMPL_IF>
</form>
</div>
<TMPL_IF NAME="TERMS">
<TMPL_VAR NAME="TERMS">
</TMPL_IF>
</div>
</div>
</div>
</div>
<footer>
<div class="container">
<div class="footer">
<img class="logo" src="../assets/ipfire.png" alt="IPFire Logo">
Powered by IPFire
</div>
</div>
</footer>
</body>
</html>

View File

@@ -7,6 +7,54 @@
'Add Rule' => 'Regel hinzufügen',
'Add a route' => 'Eine Route hinzufügen',
'Async logging enabled' => 'Aktiviere asynchrones Schreiben des Syslogs',
'Captive 1day' => '1 Tag',
'Captive 1month' => '1 Monat',
'Captive 1week' => '1 Woche',
'Captive ACTIVATE' => 'AKTIVIEREN',
'Captive GAIN ACCESS' => 'ZUGANG',
'Captive activate' => 'Aktivieren',
'Captive activated' => 'Aktiviert',
'Captive active on' => 'Aktiviert auf',
'Captive agree tac' => 'Bedingungen akzeptieren',
'Captive auth_lic' => 'Lizenz',
'Captive auth_vou' => 'Gutschein',
'Captive authentication' => 'Art der Anmeldung',
'Captive brand color' => 'Highlight-Farbe',
'Captive branding' => 'Branding',
'Captive client session expiry time' => 'Ablaufzeit',
'Captive clients' => 'Clients',
'Captive config' => 'Konfiguration',
'Captive coupon' => 'Coupon',
'Captive err doublevoucher' => 'Ein Gutschein mit diesem Code ist bereits im Umlauf',
'Captive expire' => 'Ablauf',
'Captive expiry time' => 'Ablaufzeit',
'Captive generate coupon' => 'Coupon generieren',
'Captive genvoucher' => 'Gutschein generieren',
'Captive invalid logosize' => 'Die hochgeladene Datei entspricht nicht der vorgegeben Auflösung von mindestens 1280x400 und maximal 1920x800 Pixeln',
'Captive invalid_voucher' => 'Dieser Code ist ungültig. Bitte versuchen Sie es erneut',
'Captive ip' => 'IP-Addresse',
'Captive issued coupons' => 'Ausgestellte Coupons',
'Captive logo uploaded' => 'Logo hochgeladen',
'Captive logo_set' => 'Aktuelles Logo',
'Captive logo_upload' => 'Logo hochladen',
'Captive logo_upload1' => '(PNG, min. 1280x400, max. 1920x800)',
'Captive mac' => 'MAC-Adresse',
'Captive menu' => 'Captive-Portal',
'Captive noexpiretime' => 'Es wurde kein gültiger Verbindungszeitraum angegeben',
'Captive nolimit' => 'Unbegrenzt',
'Captive nr' => 'Nummer',
'Captive please accept the terms and conditions' => 'Bitte akzeptieren Sie die Bedingungen',
'Captive terms' => 'Bedingungen',
'Captive terms short' => 'Bedingungen',
'Captive time' => 'Erlaubter Nutzungszeitraum nach Aktivierung (Stunden)',
'Captive title' => 'Titel der Anmeldeseite',
'Captive upload logo' => 'Logo hochladen',
'Captive upload logo recommendations' => '(PNG oder JPEG, 1280x720 Pixel empfohlen)',
'Captive voactive' => 'Aktive Gutscheine',
'Captive voucher' => 'Gutschein',
'Captive vouchervalid' => 'Erlaubter Zeitraum für Gutschein',
'Captive vout' => 'Ausgegebene Gutscheine',
'Captive wrong ext' => 'Die hochgeladene Datei hat den falschen Dateityp',
'Choose Rule' => 'Wählen Sie <u>eine</u> der untenstehenden Regeln aus.',
'Class' => 'Klasse',
'Class was deleted' => 'wurde mit eventuell vorhandenen Unterklassen gelöscht',
@@ -841,6 +889,7 @@
'edit share' => 'Freigabe bearbeiten',
'editor' => 'Editor',
'eg' => 'z.B.:',
'eight hours' => '8 Stunden',
'email config' => 'Konfiguration',
'email empty field' => 'Leeres Feld',
'email error' => 'FEHLER: Test-E-Mail konnte nicht versendet werden',

View File

@@ -1,12 +1,61 @@
%tr = (
%tr,
'24 hours' => '24 Hours',
'Act as' => 'Act as:',
'Add Level7 rule' => 'Add Level7 rule',
'Add Port Rule' => 'Add port rule',
'Add Rule' => 'Add rule',
'Add a route' => 'Add a route',
'Async logging enabled' => 'Enable asynchronous writing of the syslog file',
'Captive 1day' => '1 day',
'Captive 1month' => '1 month',
'Captive 1week' => '1 week',
'Captive ACTIVATE' => 'ACTIVATE',
'Captive GAIN ACCESS' => 'GAIN ACCESS',
'Captive activate' => 'Activate',
'Captive activated' => 'Activated',
'Captive active on' => 'Activated on',
'Captive agree tac' => 'I agree with the terms & conditions below.',
'Captive auth_lic' => 'License',
'Captive auth_vou' => 'Voucher',
'Captive authentication' => 'Type of Access',
'Captive brand color' => 'Brand Color',
'Captive branding' => 'Branding',
'Captive client session expiry time' => 'Session Expiry Time',
'Captive config' => 'Settings',
'Captive coupon' => 'Coupon',
'Captive err doublevoucher' => 'A voucher with this code already exists',
'Captive expire' => 'Expire',
'Captive expiry time' => 'Expiry Time',
'Captive generate coupon' => 'Generate Coupon',
'Captive heading terms' => 'Terms &amp; Conditions',
'Captive heading voucher' => 'Voucher or Access Code',
'Captive invalid coupon' => 'You entered an invalid coupon code. Please try again.',
'Captive invalid logosize' => 'The uploaded image file does not meet the required resolution of at least 1280x400 but not larger than 1920x800 pixels',
'Captive invalid_voucher' => 'Invalid code. Please try again',
'Captive ip' => 'IP Address',
'Captive issued coupons' => 'Issued Coupons',
'Captive logo uploaded' => 'Logo uploaded',
'Captive logo_set' => 'Current Logo',
'Captive mac' => 'MAC Address',
'Captive menu' => 'Captive Portal',
'Captive noexpiretime' => 'No valid connection time range given',
'Captive nolimit' => 'unlimited',
'Captive nr' => 'Number',
'Captive please accept the terms and conditions' => 'Please accept the terms &amp; conditions',
'Captive please enter a coupon code' => 'Please enter a coupon code',
'Captive terms' => 'Terms &amp; Conditions',
'Captive terms short' => 'T&Cs',
'Captive time' => 'Access time post activation (hours)',
'Captive title' => 'Title of Login Page',
'Captive upload logo' => 'Upload Logo',
'Captive upload logo recommendations' => '(PNG or JPEG, recommended 1280x720 pixels)',
'Captive voactive' => 'Active Vouchers',
'Captive voucher' => 'Voucher',
'Captive vouchervalid' => 'Allowed time for this voucher',
'Captive vout' => 'Issued Vouchers',
'Captive wrong ext' => 'Uploaded file has wrong filetype',
'Choose Rule' => 'Choose <u>one</u> of the following rules.',
'Class' => 'Class',
'Class was deleted' => 'with potential subclasses was deleted',
@@ -650,7 +699,7 @@
'day after' => 'Day after',
'day before' => 'Day before',
'day-graph' => 'Day',
'days' => 'days.',
'days' => 'Days',
'dbfile' => 'Dbfile',
'ddns help dnsmadeeasy' => 'In the field for hostname enter your ID (or a list of IDs seperated by;)',
'ddns help freedns' => 'In the fied username enter your connect string',
@@ -867,6 +916,7 @@
'edit share' => 'Edit share',
'editor' => 'Editor',
'eg' => 'e.g.:',
'eight hours' => '8 Hours',
'email config' => 'Configuration',
'email empty field' => 'Empty field',
'email error' => 'ERROR: Test mail could not be sent',
@@ -1282,7 +1332,7 @@
'hosts config changed' => 'Hosts config changed',
'hour' => 'Hour',
'hour-graph' => 'Hour',
'hours' => 'hours',
'hours' => 'Hours',
'hours2' => 'Hours',
'ibod for dual isdn only' => 'iBOD can only be used with Dual ISDN.',
'icmp selected but no type' => 'ICMP selected for protocol, but no ICMP type specified.',
@@ -1606,7 +1656,7 @@
'monthly volume' => 'Monthly volume',
'monthly volume start day' => 'First day of monthly period',
'monthly volume start day short' => 'First day',
'months' => 'months',
'months' => 'Months',
'more' => 'more',
'most preferred' => 'most preferred',
'mount' => 'Mount',
@@ -1701,6 +1751,9 @@
'ok' => 'OK',
'older' => 'Older',
'on' => 'on',
'one hour' => 'One Hour',
'one month' => 'One Month',
'one week' => 'One Week',
'online help en' => 'Online help (in english)',
'only digits allowed in holdoff field' => 'Only digits allowed in holdoff field',
'only digits allowed in max retries field' => 'Only digits allowed in max retries field.',
@@ -2314,6 +2367,7 @@
'unix password sync' => 'Unix Password Sync',
'unix shell' => 'UNIX Shell',
'unknown' => 'UNKNOWN',
'unlimited' => 'Unlimited',
'unnamed' => 'Unnamed',
'update' => 'Update',
'update accelerator' => 'Update Accelerator',
@@ -2694,7 +2748,7 @@
'week' => 'Week',
'week-graph' => 'Week',
'weekly firewallhits' => 'weekly firewallhits',
'weeks' => 'weeks',
'weeks' => 'Weeks',
'wildcards' => 'Wildcards',
'wins server' => 'Wins Server',
'wins support' => 'Wins Support',

View File

@@ -117,5 +117,8 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
cp -rf $(DIR_CONF)/httpd/* /etc/httpd/conf
ln -sf $(CONFIG_ROOT)/main/hostname.conf /etc/httpd/conf/
# Create captive logging directory
-mkdir -pv /var/log/httpd/captive
@rm -rf $(DIR_APP)
@$(POSTBUILD)

79
lfs/bootstrap Normal file
View File

@@ -0,0 +1,79 @@
###############################################################################
# #
# IPFire.org - A linux based firewall #
# Copyright (C) 2007-2016 IPFire Team <info@ipfire.org> #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
###############################################################################
###############################################################################
# Definitions
###############################################################################
include Config
VER = 4.0.0-alpha.6
THISAPP = bootstrap-$(VER)
DL_FILE = $(THISAPP)-dist.zip
DL_FROM = $(URL_IPFIRE)
DIR_APP = $(DIR_SRC)/$(THISAPP)-dist
TARGET = $(DIR_INFO)/$(THISAPP)
###############################################################################
# Top-level Rules
###############################################################################
objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
$(DL_FILE)_MD5 = 7fed4691d4d7ca19820009dad86e1aef
install : $(TARGET)
check : $(patsubst %,$(DIR_CHK)/%,$(objects))
download :$(patsubst %,$(DIR_DL)/%,$(objects))
md5 : $(subst %,%_MD5,$(objects))
###############################################################################
# Downloading, checking, md5sum
###############################################################################
$(patsubst %,$(DIR_CHK)/%,$(objects)) :
@$(CHECK)
$(patsubst %,$(DIR_DL)/%,$(objects)) :
@$(LOAD)
$(subst %,%_MD5,$(objects)) :
@$(MD5)
###############################################################################
# Installation Details
###############################################################################
$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
@$(PREBUILD)
@rm -rf $(DIR_APP) && cd $(DIR_SRC) && unzip $(DIR_DL)/$(DL_FILE)
-mkdir -pv /usr/share/bootstrap/{css,js}
cd $(DIR_APP) && cp -vf css/* /usr/share/bootstrap/css
cd $(DIR_APP) && cp -vf js/* /usr/share/bootstrap/js
@rm -rf $(DIR_APP)
@$(POSTBUILD)

View File

@@ -50,7 +50,7 @@ $(TARGET) :
@$(PREBUILD)
# Create all directories
for i in addon-lang auth backup ca certs connscheduler crls ddns dhcp dhcpc dns dnsforward \
for i in addon-lang auth backup ca captive certs connscheduler crls ddns dhcp dhcpc dns dnsforward \
ethernet extrahd/bin fwlogs fwhosts firewall isdn key langs logging mac main \
menu.d modem nfs optionsfw \
ovpn patches pakfire portfw ppp private proxy/advanced/cre \
@@ -62,7 +62,7 @@ $(TARGET) :
# Touch empty files
for i in auth/users backup/include.user backup/exclude.user \
certs/index.txt ddns/config ddns/noipsettings ddns/settings ddns/ipcache dhcp/settings \
captive/settings captive/agb.txt captive/clients captive/voucher_out certs/index.txt ddns/config ddns/noipsettings ddns/settings ddns/ipcache dhcp/settings \
dhcp/fixleases dhcp/advoptions dhcp/dhcpd.conf.local dns/settings dnsforward/config ethernet/aliases ethernet/settings ethernet/known_nics ethernet/scanned_nics \
ethernet/wireless extrahd/scan extrahd/devices extrahd/partitions extrahd/settings firewall/settings firewall/config firewall/geoipblock firewall/input firewall/outgoing \
fwhosts/customnetworks fwhosts/customhosts fwhosts/customgroups fwhosts/customservicegrp fwhosts/customgeoipgrp fwlogs/ipsettings fwlogs/portsettings \

View File

@@ -107,6 +107,7 @@ endif
# Move script to correct place.
mv -vf /usr/local/bin/ovpn-ccd-convert /usr/sbin/
mv -vf /usr/local/bin/ovpn-collectd-convert /usr/sbin/
mv -vf /usr/local/bin/captive-cleanup /usr/bin/
# Install firewall scripts.
mkdir -pv /usr/lib/firewall

78
lfs/ubuntu-font-family Normal file
View File

@@ -0,0 +1,78 @@
###############################################################################
# #
# IPFire.org - A linux based firewall #
# Copyright (C) 2007-2017 IPFire Team <info@ipfire.org> #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
###############################################################################
###############################################################################
# Definitions
###############################################################################
include Config
VER = 0.83
THISAPP = ubuntu-font-family-$(VER)
DL_FILE = $(THISAPP).zip
DL_FROM = $(URL_IPFIRE)
DIR_APP = $(DIR_SRC)/$(THISAPP)
TARGET = $(DIR_INFO)/$(THISAPP)
###############################################################################
# Top-level Rules
###############################################################################
objects = $(DL_FILE)
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
$(DL_FILE)_MD5 = a24b8136b8f3bb93f166baf97d9328de
install : $(TARGET)
check : $(patsubst %,$(DIR_CHK)/%,$(objects))
download :$(patsubst %,$(DIR_DL)/%,$(objects))
md5 : $(subst %,%_MD5,$(objects))
###############################################################################
# Downloading, checking, md5sum
###############################################################################
$(patsubst %,$(DIR_CHK)/%,$(objects)) :
@$(CHECK)
$(patsubst %,$(DIR_DL)/%,$(objects)) :
@$(LOAD)
$(subst %,%_MD5,$(objects)) :
@$(MD5)
###############################################################################
# Installation Details
###############################################################################
$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
@$(PREBUILD)
@rm -rf $(DIR_APP) && cd $(DIR_SRC) && unzip $(DIR_DL)/$(DL_FILE)
-mkdir -pv /usr/share/fonts
cd $(DIR_APP) && cp -vf *.ttf /usr/share/fonts/
@rm -rf $(DIR_APP)
@$(POSTBUILD)

View File

@@ -68,5 +68,24 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
ln -svf ipfire /srv/web/ipfire/html/themes/ipfire-rounded
# Reset permissions of redirect templates and theme directories
find /srv/web/ipfire/html/{redirect-templates,themes} -type d | xargs chmod -v 755
find /srv/web/ipfire/html/{captive,redirect-templates,themes} -type d | xargs chmod -v 755
# Captive Portal CSS
ln -svf --relative /usr/share/bootstrap/css/bootstrap-grid.min.css \
/srv/web/ipfire/html/captive/assets/bootstrap-grid.min.css
ln -svf --relative /usr/share/bootstrap/css/bootstrap-grid.min.css.map \
/srv/web/ipfire/html/captive/assets/bootstrap-grid.min.css.map
ln -svf --relative /usr/share/bootstrap/css/bootstrap-reboot.min.css \
/srv/web/ipfire/html/captive/assets/bootstrap-reboot.min.css
ln -svf --relative /usr/share/bootstrap/css/bootstrap-reboot.min.css.map \
/srv/web/ipfire/html/captive/assets/bootstrap-reboot.min.css.map
# Captive Portal Fonts
ln -svf --relative /usr/share/fonts/Ubuntu-L.ttf \
/srv/web/ipfire/html/captive/assets/Ubuntu-L.ttf
ln -svf --relative /usr/share/fonts/Ubuntu-M.ttf \
/srv/web/ipfire/html/captive/assets/Ubuntu-M.ttf
ln -svf --relative /usr/share/fonts/Ubuntu-R.ttf \
/srv/web/ipfire/html/captive/assets/Ubuntu-R.ttf
@$(POSTBUILD)

View File

@@ -548,6 +548,7 @@ buildipfire() {
lfsmake2 web-user-interface
lfsmake2 flag-icons
lfsmake2 jquery
lfsmake2 bootstrap
lfsmake2 arping
lfsmake2 beep
lfsmake2 dvdrtools
@@ -626,6 +627,7 @@ buildipfire() {
lfsmake2 openssh
lfsmake2 fontconfig
lfsmake2 dejavu-fonts-ttf
lfsmake2 ubuntu-font-family
lfsmake2 freefont
lfsmake2 pixman
lfsmake2 cairo

View File

@@ -224,6 +224,13 @@ iptables_init() {
iptables -A ${i} -j LOOPBACK
done
# Captive portal
iptables -N CAPTIVE_PORTAL
iptables -N CAPTIVE_PORTAL_CLIENTS
for i in INPUT FORWARD; do
iptables -A ${i} -j CAPTIVE_PORTAL
done
# Accept everything connected
for i in INPUT FORWARD OUTPUT; do
iptables -A ${i} -j CONNTRACK
@@ -337,6 +344,10 @@ iptables_init() {
iptables -N UPNPFW
iptables -A FORWARD -m conntrack --ctstate NEW -j UPNPFW
# Captive Portal
iptables -t nat -N CAPTIVE_PORTAL
iptables -t nat -A PREROUTING -j CAPTIVE_PORTAL
# RED chain, used for the red interface
iptables -N REDINPUT
iptables -A INPUT -j REDINPUT

View File

@@ -31,7 +31,8 @@ SUID_PROGS = squidctrl sshctrl ipfirereboot \
redctrl syslogdctrl extrahdctrl sambactrl upnpctrl \
smartctrl clamavctrl addonctrl pakfire mpfirectrl wlanapctrl \
setaliases urlfilterctrl updxlratorctrl fireinfoctrl rebuildroutes \
getconntracktable wirelessclient torctrl ddnsctrl unboundctrl
getconntracktable wirelessclient torctrl ddnsctrl unboundctrl \
captivectrl
SUID_UPDX = updxsetperms
OBJS = $(patsubst %,%.o,$(PROGS) $(SUID_PROGS))

View File

@@ -0,0 +1,369 @@
/* This file is part of the IPFire Firewall.
*
* This program is distributed under the terms of the GNU General Public
* Licence. See the file COPYING for details. */
#define _BSD_SOURCE
#define _XOPEN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "libsmooth.h"
#include "setuid.h"
#define CAPTIVE_PORTAL_SETTINGS CONFIG_ROOT "/captive/settings"
#define ETHERNET_SETTINGS CONFIG_ROOT "/ethernet/settings"
#define CLIENTS CONFIG_ROOT "/captive/clients"
#define IPTABLES "/sbin/iptables --wait"
#define HTTP_PORT 80
#define REDIRECT_PORT 1013
typedef struct client {
char etheraddr[STRING_SIZE];
char ipaddr[STRING_SIZE];
time_t time_start;
int expires;
struct client* next;
} client_t;
static time_t parse_time(const char* s) {
int t = 0;
if (sscanf(s, "%d", &t) == 1) {
return (time_t)t;
}
return -1;
}
static char* format_time(const time_t* t) {
char buffer[STRING_SIZE];
struct tm* tm = gmtime(t);
if (tm == NULL)
return NULL;
strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M", tm);
return strdup(buffer);
}
static client_t* read_clients(char* filename) {
FILE* f = NULL;
if (!(f = fopen(filename, "r"))) {
fprintf(stderr, "Could not open configuration file: %s\n", filename);
return NULL;;
}
char line[STRING_SIZE];
client_t* client_first = NULL;
client_t* client_last = NULL;
client_t* client_curr;
while ((fgets(line, STRING_SIZE, f) != NULL)) {
if (line[strlen(line) - 1] == '\n')
line[strlen(line) - 1] = '\0';
// Skip all commented lines
if (*line == '#')
continue;
client_curr = (client_t*)malloc(sizeof(client_t));
memset(client_curr, 0, sizeof(client_t));
if (client_first == NULL)
client_first = client_curr;
else
client_last->next = client_curr;
client_last = client_curr;
unsigned int count = 0;
char* lineptr = line;
while (1) {
if (!*lineptr)
break;
char* word = lineptr;
while (*lineptr != '\0') {
if (*lineptr == ',') {
*lineptr = '\0';
lineptr++;
break;
}
lineptr++;
}
switch (count++) {
// Ethernet address
case 1:
strcpy(client_curr->etheraddr, word);
break;
// IP address
case 2:
strcpy(client_curr->ipaddr, word);
break;
// Start time
case 3:
client_curr->time_start = parse_time(word);
break;
// Expire duration
case 4:
client_curr->expires = atoi(word);
break;
default:
break;
}
}
}
if (f)
fclose(f);
return client_first;
}
static void flush_chains() {
// filter
safe_system(IPTABLES " -F CAPTIVE_PORTAL");
safe_system(IPTABLES " -F CAPTIVE_PORTAL_CLIENTS");
// nat
safe_system(IPTABLES " -t nat -F CAPTIVE_PORTAL");
}
static int setup_dns_filters() {
const char* protos[] = { "udp", "tcp", NULL };
// Limits the number of DNS requests to 3 kByte/s
// A burst of 1MB is permitted at the start
const char* limiter = "-m hashlimit --hashlimit-name dns-filter"
" --hashlimit-mode srcip --hashlimit-upto 3kb/sec --hashlimit-burst 1024kb";
char command[STRING_SIZE];
const char** proto = protos;
while (*proto) {
snprintf(command, sizeof(command), IPTABLES " -A CAPTIVE_PORTAL_CLIENTS -p %s"
" --dport 53 %s -j RETURN", *proto, limiter);
int r = safe_system(command);
if (r)
return r;
proto++;
}
return 0;
}
static int add_client_rules(const client_t* clients) {
char command[STRING_SIZE];
char match[STRING_SIZE];
while (clients) {
size_t len = 0;
if (*clients->ipaddr && clients->expires > 0) {
len += snprintf(match + len, sizeof(match) - len,
"-s %s", clients->ipaddr);
}
len += snprintf(match + len, sizeof(match) - len,
" -m mac --mac-source %s", clients->etheraddr);
if (clients->expires > 0) {
time_t expires = clients->time_start + clients->expires;
char* time_start = format_time(&clients->time_start);
char* time_end = format_time(&expires);
len += snprintf(match + len, sizeof(match) - len,
" -m time --datestart %s --datestop %s",
time_start, time_end);
free(time_start);
free(time_end);
}
// filter
snprintf(command, sizeof(command), IPTABLES " -A CAPTIVE_PORTAL_CLIENTS"
" %s -j RETURN", match);
safe_system(command);
// nat
snprintf(command, sizeof(command), IPTABLES " -t nat -A CAPTIVE_PORTAL"
" %s -j RETURN", match);
safe_system(command);
// Move on to the next client
clients = clients->next;
}
return 0;
}
static char* get_key(struct keyvalue* settings, char* key) {
char value[STRING_SIZE];
if (!findkey(settings, key, value))
return NULL;
return strdup(value);
}
static int add_interface_rule(const char* intf, int allow_webif_access) {
int r;
char command[STRING_SIZE];
if ((intf == NULL) || (strlen(intf) == 0)) {
fprintf(stderr, "Empty interface given\n");
return -1;
}
snprintf(command, sizeof(command), IPTABLES " -A CAPTIVE_PORTAL -i %s"
" -j CAPTIVE_PORTAL_CLIENTS", intf);
r = safe_system(command);
if (r)
return r;
#if 0
snprintf(command, sizeof(command), IPTABLES " -A CAPTIVE_PORTAL -o %s"
" -j CAPTIVE_PORTAL_CLIENTS", intf);
r = safe_system(command);
if (r)
return r;
#endif
if (allow_webif_access) {
snprintf(command, sizeof(command), IPTABLES " -A CAPTIVE_PORTAL_CLIENTS"
" -i %s -p tcp --dport 444 -j RETURN", intf);
r = safe_system(command);
if (r)
return r;
}
// Redirect all unauthenticated clients
snprintf(command, sizeof(command), IPTABLES " -t nat -A CAPTIVE_PORTAL -i %s"
" -p tcp --dport %d -j REDIRECT --to-ports %d", intf, HTTP_PORT, REDIRECT_PORT);
r = safe_system(command);
if (r)
return r;
// Allow access to captive portal site
snprintf(command, sizeof(command), IPTABLES " -A CAPTIVE_PORTAL_CLIENTS"
" -i %s -p tcp --dport %d -j RETURN", intf, REDIRECT_PORT);
r = safe_system(command);
if (r)
return r;
return 0;
}
static int add_interface_rules(struct keyvalue* captive_portal_settings, struct keyvalue* ethernet_settings) {
const char* intf;
char* setting;
int r = 0;
setting = get_key(captive_portal_settings, "ENABLE_GREEN");
if (setting && (strcmp(setting, "on") == 0)) {
free(setting);
intf = get_key(ethernet_settings, "GREEN_DEV");
r = add_interface_rule(intf, /* allow webif access from green */ 1);
if (r)
return r;
}
setting = get_key(captive_portal_settings, "ENABLE_BLUE");
if (setting && (strcmp(setting, "on") == 0)) {
free(setting);
intf = get_key(ethernet_settings, "BLUE_DEV");
r = add_interface_rule(intf, /* do not allow webif access */ 0);
if (r)
return r;
}
// Always pass DNS packets through all firewall rules
r = setup_dns_filters();
if (r)
return r;
// Add the last rule
r = safe_system(IPTABLES " -A CAPTIVE_PORTAL_CLIENTS -j DROP");
if (r)
return r;
return r;
}
int main(int argc, char** argv) {
int r = 0;
char* intf = NULL;
client_t* clients = NULL;
struct keyvalue* captive_portal_settings = NULL;
struct keyvalue* ethernet_settings = NULL;
if (!(initsetuid()))
exit(2);
ethernet_settings = initkeyvalues();
if (!readkeyvalues(ethernet_settings, ETHERNET_SETTINGS)) {
fprintf(stderr, "Could not read %s\n", ETHERNET_SETTINGS);
r = 1;
goto END;
}
captive_portal_settings = initkeyvalues();
if (!readkeyvalues(captive_portal_settings, CAPTIVE_PORTAL_SETTINGS)) {
fprintf(stderr, "Could not read %s\n", CAPTIVE_PORTAL_SETTINGS);
r = 1;
goto END;
}
clients = read_clients(CLIENTS);
// Clean up all old rules
flush_chains();
// Add all client rules
r = add_client_rules(clients);
if (r)
goto END;
// Add all interface rules
r = add_interface_rules(captive_portal_settings, ethernet_settings);
if (r)
goto END;
END:
while (clients) {
client_t* head = clients;
clients = clients->next;
free(head);
}
if (ethernet_settings)
freekeyvalues(ethernet_settings);
if (captive_portal_settings)
freekeyvalues(captive_portal_settings);
if (intf)
free(intf);
return r;
}

View File

@@ -42,6 +42,7 @@ int main(void) {
char buffer[STRING_SIZE];
char *index, *ipaddress, *macaddress, *enabled;
struct keyvalue *kv = NULL;
struct keyvalue* captive_settings = NULL;
if (!(initsetuid()))
exit(1);
@@ -67,6 +68,13 @@ int main(void) {
exit(1);
}
// Read captive portal settings
captive_settings = initkeyvalues();
if (!readkeyvalues(captive_settings, CONFIG_ROOT "/captive/settings")) {
fprintf(stderr, "Could not read captive portal settings\n");
exit(1);
}
/* Get the BLUE interface details */
if (findkey(kv, "BLUE_DEV", blue_dev) > 0) {
if ((strlen(blue_dev) > 0) && !VALID_DEVICE(blue_dev)) {
@@ -79,6 +87,15 @@ int main(void) {
exit(0);
}
// Check if the captive portal is enabled on blue. If so, we will
// just keep the chains flushed and do not add any rules.
char captive_enabled[STRING_SIZE];
if (findkey(captive_settings, "ENABLE_BLUE", captive_enabled) > 0) {
if (strcmp(captive_enabled, "on") == 0) {
return 0;
}
}
if ((fd = fopen(CONFIG_ROOT "/wireless/nodrop", "r")))
return 0;

46
src/scripts/captive-cleanup Executable file
View File

@@ -0,0 +1,46 @@
#!/usr/bin/perl
###############################################################################
# #
# IPFire.org - A linux based firewall #
# Copyright (C) 2016 IPFire Team <alexander.marx@ipfire.org> #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
###############################################################################
use strict;
require '/var/ipfire/general-functions.pl';
my %settings=();
my %clientshash=();
my $settingsfile="${General::swroot}/captive/settings";
my $clients="${General::swroot}/captive/clients";
my $time;
my $expiretime;
if (-f $settingsfile && -f $clients && ! -z $clients){
&General::readhash("$settingsfile", \%settings) if(-f $settingsfile);
&General::readhasharray("$clients", \%clientshash);
$time = time();
foreach my $key (keys %clientshash) {
$expiretime=($clientshash{$key}[2])+$clientshash{$key}[3];
if ($expiretime < $time){
delete $clientshash{$key};
my $exp = gmtime($expiretime);
&General::log("Captive", "Delete expired voucher $clientshash{$key}[4] expired on $exp. Remark: $clientshash{$key}[5]");
}
}
&General::writehasharray("$clients", \%clientshash);
}