#!/usr/bin/perl # chilli - ChilliSpot.org. A Wireless LAN Access Point Controller # Copyright (C) 2003, 2004 Mondru AB. # Copyright (C) 2006-2008 David Bird # # The contents of this file may be used under the terms of the GNU # General Public License Version 2, provided that the above copyright # notice and this permission notice is included in all copies or # substantial portions of the software. # Redirects from ChilliSpot daemon: # # Redirection when not yet or already authenticated # notyet: ChilliSpot daemon redirects to login page. # already: ChilliSpot daemon redirects to success status page. # # Response to login: # already: Attempt to login when already logged in. # failed: Login failed # success: Login succeded # # logoff: Response to a logout # Shared secret used to encrypt challenge with. Prevents dictionary attacks. # You should change this to your own shared secret. $uamsecret = "ht2eb8ej6s4et3rg1ulp"; # Uncomment the following line if you want to use ordinary user-password # for radius authentication. Must be used together with $uamsecret. #$userpassword=1; # This code is horrible -- it came that way, and remains that way. A # real open-source captive portal for coova-chilli should be built -- david $loginpath = "/cgi-bin/hotspotlogin.cgi"; use Digest::MD5 qw(md5 md5_hex md5_base64); # Make sure that the form parameters are clean $OK_CHARS='-a-zA-Z0-9_.@&=%!'; $_ = $input = ; s/[^$OK_CHARS]/_/go; $input = $_; # Make sure that the get query parameters are clean $OK_CHARS='-a-zA-Z0-9_.@&=%!'; $_ = $query=$ENV{QUERY_STRING}; s/[^$OK_CHARS]/_/go; $query = $_; # If she did not use https tell her that it was wrong. if (!($ENV{HTTPS} =~ /^on$/)) { print "Content-type: text/html\n\n ChilliSpot Login Failed

ChilliSpot Login Failed

Login must use encrypted connection.
"; exit(0); } #Read form parameters which we care about @array = split('&',$input); foreach $var ( @array ) { @array2 = split('=',$var); if ($array2[0] =~ /^username$/i) { $username = $array2[1]; } if ($array2[0] =~ /^password$/i) { $password = $array2[1]; } if ($array2[0] =~ /^challenge$/) { $challenge = $array2[1]; } if ($array2[0] =~ /^button$/) { $button = $array2[1]; } if ($array2[0] =~ /^logout$/) { $logout = $array2[1]; } if ($array2[0] =~ /^prelogin$/) { $prelogin = $array2[1]; } if ($array2[0] =~ /^res$/) { $res = $array2[1]; } if ($array2[0] =~ /^uamip$/) { $uamip = $array2[1]; } if ($array2[0] =~ /^uamport$/) { $uamport = $array2[1]; } if ($array2[0] =~ /^userurl$/) { $userurl = $array2[1]; } if ($array2[0] =~ /^timeleft$/) { $timeleft = $array2[1]; } if ($array2[0] =~ /^redirurl$/) { $redirurl = $array2[1]; } } #Read query parameters which we care about @array = split('&',$query); foreach $var ( @array ) { @array2 = split('=',$var); if ($array2[0] =~ /^username$/i) { $username = $array2[1]; } if ($array2[0] =~ /^password$/i) { $password = $array2[1]; } if ($array2[0] =~ /^res$/) { $res = $array2[1]; } if ($array2[0] =~ /^challenge$/) { $challenge = $array2[1]; } if ($array2[0] =~ /^uamip$/) { $uamip = $array2[1]; } if ($array2[0] =~ /^uamport$/) { $uamport = $array2[1]; } if ($array2[0] =~ /^reply$/) { $reply = $array2[1]; } if ($array2[0] =~ /^userurl$/) { $userurl = $array2[1]; } if ($array2[0] =~ /^timeleft$/) { $timeleft = $array2[1]; } if ($array2[0] =~ /^redirurl$/) { $redirurl = $array2[1]; } } $reply =~ s/\+/ /g; $reply =~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/seg; $userurldecode = $userurl; $userurldecode =~ s/\+/ /g; $userurldecode =~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/seg; $redirurldecode = $redirurl; $redirurldecode =~ s/\+/ /g; $redirurldecode =~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/seg; $password =~ s/\+/ /g; $password =~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/seg; # If attempt to login if ($button =~ /^Login$/) { $hexchal = pack "H32", $challenge; if (defined $uamsecret) { $newchal = md5($hexchal, $uamsecret); } else { $newchal = $hexchal; } $response = md5_hex("\0", $password, $newchal); $pappassword = unpack "H32", ($password ^ $newchal); #sleep 5; print "Content-type: text/html\n\n"; print " ChilliSpot Login "; if ((defined $uamsecret) && defined($userpassword)) { print " "; } else { print " "; } print " "; print "

Logging in to ChilliSpot

"; print "
Please wait......
"; exit(0); } # Default: It was not a form request $result = 0; # If login successful if ($res =~ /^success$/) { $result = 1; } # If login failed if ($res =~ /^failed$/) { $result = 2; } # If logout successful if ($res =~ /^logoff$/) { $result = 3; } # If tried to login while already logged in if ($res =~ /^already$/) { $result = 4; } # If not logged in yet if ($res =~ /^notyet$/) { $result = 5; } # If login from smart client if ($res =~ /^smartclient$/) { $result = 6; } # If requested a logging in pop up window if ($res =~ /^popup1$/) { $result = 11; } # If requested a success pop up window if ($res =~ /^popup2$/) { $result = 12; } # If requested a logout pop up window if ($res =~ /^popup3$/) { $result = 13; } # Otherwise it was not a form request # Send out an error message if ($result == 0) { print "Content-type: text/html\n\n ChilliSpot Login Failed

ChilliSpot Login Failed

Login must be performed through ChilliSpot daemon.
"; exit(0); } #Generate the output print "Content-type: text/html\n\n ChilliSpot Login "; # if (!window.opener) { # document.bgColor = '#c0d8f4'; # } #print "THE INPUT: $input"; #foreach $key (sort (keys %ENV)) { # print $key, ' = ', $ENV{$key}, "
\n"; #} if ($result == 2) { print "

ChilliSpot Login Failed

"; if ($reply) { print "
$reply

"; } } if ($result == 5) { print "

ChilliSpot Login

"; } if ($result == 2 || $result == 5) { print "
Username:
Password:
"; } if ($result == 1) { print "

Logged in to ChilliSpot

"; if ($reply) { print "
$reply

"; } print "
Logout
"; } if (($result == 4) || ($result == 12)) { print "

Logged in to ChilliSpot

Logout
"; } if ($result == 11) { print "

Logging in to ChilliSpot

"; print "
Please wait......
"; } if (($result == 3) || ($result == 13)) { print "

Logged out from ChilliSpot

Login
"; } exit(0);