1package Netdot::Radius; 2 3use strict; 4use warnings; 5use Authen::Radius; 6use APR::SockAddr; 7use Netdot::AuthLocal; 8 9=head1 NAME 10 11Netdot::Radius - RADIUS module for Netdot 12 13=head1 SYNOPSIS 14 15In Apache configuration: 16 17=over 4 18 19 PerlSetVar SiteControlMethod Netdot::Radius 20 21 <Location /netdot/NetdotLogin> 22 PerlSetVar NetdotRadiusHost "localhost" 23 PerlSetVar NetdotRadiusSecret "testing123" 24 PerlSetVar NetdotRadiusHost2 "otherhost" 25 PerlSetVar NetdotRadiusSecret2 "testing123" 26 PerlSetVar NetdotRadiusTimeOut "5" 27 PerlSetVar NetdotRadiusFailToLocal "yes" 28 </Location> 29 30=back 31 32=head1 DESCRIPTION 33 34 Netdot::Radius uses Authen::Radius to issue authentication and authorization queries 35 for Netdot. It supports failover by querying one RADIUS server first, then the second. 36 It also returns any available Netdot-specific attributes for a given user. 37 38=cut 39 40#Be sure to return 1 411; 42 43 44############################################################################ 45 46=head2 check_credentials 47 48 Arguments: 49 Apache Request Object 50 Username 51 Password 52 Returns: 53 True or false 54 Examples: 55 if ( Netdot::Radius::check_credentials($r, $user, $pass) {...} 56 57=cut 58 59sub check_credentials { 60 my ($r, $username, $password) = @_; 61 unless ( $username && $password ){ 62 $r->log_error("Missing username and/or password"); 63 return 0; 64 } 65 66 my $fail_to_local = ($r->dir_config("NetdotRadiusFailToLocal") eq "yes")? 1 : 0; 67 68 my $radius; 69 unless ( $radius = Netdot::Radius::_connect($r) ){ 70 if ( $fail_to_local ){ 71 $r->log_error("Netdot::Radius::check_credentials: Trying local auth"); 72 return Netdot::AuthLocal::check_credentials($r, $username, $password); 73 }else{ 74 return 0; 75 } 76 } 77 78 # Get my IP address to pass as the Source IP and NAS IP Address 79 my $c = $r->connection; 80 my $sockaddr = $c->local_addr if defined($c); 81 my $nas_ip_address = $sockaddr->ip_get if defined($sockaddr); 82 83 84 if ( $radius->check_pwd($username, $password, $nas_ip_address) ) { 85 return 1; 86 }else{ 87 $r->log_error("Netdot::Radius::check_credentials: User $username failed RADIUS authentication: " 88 . $radius->strerror); 89 if ( $fail_to_local ){ 90 $r->log_error("Netdot::Radius::check_credentials: Trying local auth"); 91 return Netdot::AuthLocal::check_credentials($r, $username, $password); 92 } 93 } 94 return 0; 95} 96 97############################################################################ 98# _connect - Connect to an available RADIUS server 99# 100# Arguments: 101# Apache Request Object 102# Returns: 103# Authen::Radius object 104# Examples: 105# my $radius = Netdot::Radius::connect($r); 106# 107# 108sub _connect { 109 my ($r) = @_; 110 111 my $host = $r->dir_config("NetdotRadiusHost") || "localhost"; 112 my $host2 = $r->dir_config("NetdotRadiusHost2"); 113 my $secret = $r->dir_config("NetdotRadiusSecret") || "unknown"; 114 my $secret2 = $r->dir_config("NetdotRadiusSecret2") || "unknown"; 115 my $timeout = $r->dir_config("NetdotRadiusTimeOut") || "5"; 116 my $radius; 117 118 $r->log_error("WARNING: Shared secret is not set. Use RadiusSiteControlSecret in httpd.conf") 119 if $secret eq "unknown"; 120 121 $radius = new Authen::Radius(Host=>$host, Secret=>$secret, TimeOut=>$timeout); 122 if ( !$radius ) { 123 $r->log_error("Could not contact radius server: $host."); 124 if ( $host2 ){ 125 # Try second RADIUS server 126 $radius = new Authen::Radius(Host=>$host2, Secret => $secret2); 127 if ( !$radius ) { 128 $r->log_error("Could not contact radius server: $host2"); 129 return 0; 130 } 131 }else{ 132 return 0; 133 } 134 } 135 return $radius; 136} 137 138=head1 SEE ALSO 139 140Apache2::SiteControl 141 142=head1 AUTHORS 143 144Carlos Vicente, C<< <cvicente at ns.uoregon.edu> >> 145 146=head1 COPYRIGHT & LICENSE 147 148Copyright 2012 University of Oregon, all rights reserved. 149 150This program is free software; you can redistribute it and/or modify 151it under the terms of the GNU General Public License as published by 152the Free Software Foundation; either version 2 of the License, or 153(at your option) any later version. 154 155This program is distributed in the hope that it will be useful, but 156WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY 157or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 158License for more details. 159 160You should have received a copy of the GNU General Public License 161along with this program; if not, write to the Free Software Foundation, 162Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 163 164=cut 165 166 167 168