File Coverage

blib/lib/App/SilverSplash.pm
Criterion Covered Total %
statement 22 24 91.6
branch n/a
condition 1 2 50.0
subroutine 8 8 100.0
pod n/a
total 31 34 91.1


line stmt bran cond sub pod time code
1             package App::SilverSplash;
2              
3 1     1   23397 use strict;
  1         2  
  1         40  
4 1     1   6 use warnings;
  1         2  
  1         53  
5              
6             =head1 NAME
7              
8             App::SilverSplash - A network captive portal for Linux platforms.
9              
10             =head1 ABSTRACT
11              
12             See http://groups.google.com/group/silversplash for information. This
13             module is currently beta status and being polished.
14              
15             =head1 DESCRIPTION
16              
17             Silver Splash is a captive portal for Linux platforms.
18              
19             Setup is still rough - see the Google Group for discussion of setup.
20              
21             But there are a few notes being added here.
22              
23             You will need to add the apache user to /etc/sudoers and give it
24             permission to run iptables. Here's the entry I'm using:
25              
26             apache ALL=NOPASSWD:/sbin/iptables
27              
28             Adding apache to iptables worked quite well, however I also had to
29             comment out
30             # Defaults requiretty
31              
32             =cut
33              
34 1   50 1   6 use constant DEBUG => $ENV{SL_DEBUG} || 0;
  1         6  
  1         114  
35              
36             our $VERSION = 0.02;
37              
38 1     1   1087 use Data::Dumper qw(Dumper);
  1         10180  
  1         64  
39              
40 1     1   814 use Config::SL ();
  1         90768  
  1         29  
41 1     1   749 use App::SilverSplash::IPTables (); # ugh
  1         22  
  1         73  
42 1     1   19 use URI::Escape ();
  1         2  
  1         19  
43 1     1   697 use DB_File;
  0            
  0            
44             use Fcntl qw(O_CREAT);
45              
46              
47             our ( $Config, $Lease_file, $Auth_url, $Max_rate, %Db,
48             $Min_count, $Wan_if, $Lan_if, $Lan_ip, $Wan_mac );
49              
50             BEGIN {
51             $Config = Config::SL->new;
52             $Lease_file = $Config->sl_dhcp_lease_file || die 'oops';
53             $Wan_if = $Config->sl_wan_if || die 'oops';
54             $Lan_if = $Config->sl_lan_if || die 'oops';
55             ($Lan_ip) = `/sbin/ifconfig $Lan_if` =~ m/inet addr:(\S+)/;
56             ($Wan_mac) = `/sbin/ifconfig $Wan_if` =~ m/HWaddr\s(\S+)/;
57             }
58              
59             sub tie_db {
60             my $class = shift;
61             my $fn = $Config->sl_dbfile;
62             tie %Db, 'DB_File', $fn, O_CREAT, 0777, $DB_BTREE
63             or die "Can't tie $fn: $!";
64             }
65              
66              
67             sub lan_ip {
68             my $self = shift;
69             return $Lan_ip;
70             }
71              
72             sub wan_mac {
73             my $self = shift;
74             return $Wan_mac;
75             }
76            
77             sub get {
78             my ($class, $key) = @_;
79              
80             $class->tie_db;
81             my $val = $Db{uc($key)};
82             untie %Db;
83             return $val if $val;
84             return;
85             }
86              
87             sub set {
88             my ($class, $key, $val) = @_;
89              
90             $class->tie_db;
91             $Db{uc($key)} = $val;
92             untie %Db;
93             return 1;
94             }
95              
96             # returns true if the mac address may pass
97              
98             sub check_auth {
99             my ($class, $mac, $ip) = @_;
100              
101             my $chain = $class->not_timed_out($mac, $ip);
102              
103             return unless $chain;
104              
105             # fixup the firewall rules based on the chain type
106             my $fixup = App::SilverSplash::IPTables->fixup_access($mac, $ip, $chain);
107              
108             return unless $fixup;
109              
110             return $fixup;
111             }
112              
113              
114             sub make_post_url {
115             my ( $class, $splash_url, $dest_url ) = @_;
116              
117             $dest_url = URI::Escape::uri_escape($dest_url);
118             my $separator = ($splash_url =~ m/\?/) ? '&' : '?';
119              
120             my $location = $splash_url . $separator . "url=$dest_url";
121              
122             return $location;
123             }
124              
125              
126             sub mac_from_ip {
127             my ($class, $ip) = @_;
128              
129             my $fh;
130             open($fh, '<', $Lease_file) or die "couldn't open lease $Lease_file";
131             my $client_mac;
132             while (my $line = <$fh>) {
133              
134             my ($time, $mac, $hostip, $hostname, $othermac) = split(/\s/, $line);
135             if ($ip eq $hostip) {
136              
137             $client_mac = $mac;
138             last;
139             }
140             }
141             close($fh) or die $!;
142              
143             return unless $client_mac;
144              
145             warn("$$ found mac $client_mac for ip $ip") if DEBUG;
146              
147             return $client_mac;
148             }
149              
150              
151             sub ip_from_mac {
152             my ($class, $client_mac) = @_;
153              
154             my $fh;
155             open($fh, '<', $Lease_file) or die "couldn't open lease $Lease_file";
156             my $client_ip;
157             while (my $line = <$fh>) {
158              
159             my ($time, $mac, $hostip, $hostname, $othermac) = split(/\s/, $line);
160             if ($client_mac eq $mac) {
161              
162             $client_ip = $hostip;
163             last;
164             }
165             }
166             close($fh) or die $!;
167              
168             return unless $client_ip;
169              
170             warn("$$ found ip $client_ip for mac $client_mac") if DEBUG;
171              
172             return $client_ip;
173             }
174              
175             # returns the auth chain if the user is not timed out
176              
177             sub not_timed_out {
178             my ($class, $mac, $ip) = @_;
179              
180             my $exp = $class->get($mac);
181              
182             return unless $exp;
183              
184             my ($exp_time, $chain) = split(/\|/, $exp);
185              
186             return if time() > $exp_time;
187              
188             return $chain; # paid, ads
189             }
190              
191             =head1 COPYRIGHT AND LICENSE
192              
193             Copyright 2010 Silver Lining Networks. All rights reserved.
194              
195             This program is licensed under the Apache 2.0 software license.
196              
197             A copy of this license is included in the module distribution.
198              
199             =cut
200              
201             1;
202