Apache-AuthenRadius
view release on metacpan or search on metacpan
AuthenRadius.pm view on Meta::CPAN
# Get the user name.
my ($user) = ($auth =~ /username="([^"]*)"/);
# REVISIT: check that the uri is correct
unless ($r->proxyreq()) {
my ($uri) = ($auth =~ /uri="([^"]*)"/);
return DECLINED() unless $r->uri() eq $uri;
}
# check the nonce is not stale
my $nonce_lifetime = $r->dir_config('Auth_Radius_nonce_lifetime') || 300;
my ($nonce) = ($auth =~ /nonce="([^"]*)"/);
if ($nonce < time() - $nonce_lifetime) {
# Its stale. Send back another challenge
$nonce = time();
# XXXX
$r->err_header_out($r->proxyreq() ?
'Proxy-Authenticate' : 'WWW-Authenticate',
"Digest algorithm=\"$algorithm\", nonce=\"$nonce\", realm=\"$realm\", stale=\"true\""
);
return AUTH_REQUIRED();
}
# Send the entire Authorization header as the password
# let the radius server figure it out
my $pass = $auth;
# Sanity for usernames and passwords.
if (length $user > 64) {
$r->log_error("Apache::AuthenRadius username too long or contains illegal characters", $r->uri());
return AUTH_REQUIRED();
}
if (length $pass > 256) {
$r->log_error("Apache::AuthenRadius password too long", $r->uri());
return AUTH_REQUIRED();
}
return _authen_radius($r, $user, $pass);
}
sub _authen_radius {
my ($r, $user, $pass) = @_;
# Radius Server and port.
my $host = $r->dir_config("Auth_Radius_host") or return DECLINED();
my $port = $r->dir_config("Auth_Radius_port") || 1647;
my $ident = $r->dir_config("Auth_Radius_ident") || 'apache';
my $ip = inet_ntoa(gethost($r->hostname)->addr);
# Shared secret for the host we are running on.
my $secret = $r->dir_config("Auth_Radius_secret") or return DECLINED();
# Timeout to wait for a response from the radius server.
my $timeout = $r->dir_config("Auth_Radius_timeout") || 5;
# Create the radius connection.
my $radius = Authen::Radius->new(
'Host' => "$host:$port",
'Secret' => $secret,
'TimeOut' => $timeout,
);
# Error if we can't connect.
if (!$radius) {
$r->log_error("Apache::AuthenRadius failed to connect to $host: $port",$r->uri());
return SERVER_ERROR();
}
# Possibly append somthing to the users name, so we can
# flag to the radius server where this request came from
# Clever radius servers like Radiator can then discriminate
# between web users and dialup users
$user .= $r->dir_config("Auth_Radius_appendToUsername");
# Do the actual check by talking to the radius server
if ($radius->check_pwd($user,$pass)) {
return OK();
} else {
$r->log_error("Apache::AuthenRadius rejected user $user", $r->uri());
return AUTH_REQUIRED();
}
}
1;
__END__
=head1 LIST OF TOKENS
=over 4
=item * Auth_Radius_host
The Radius server host: either its name or its dotted quad IP number.
The parameter is passed as the PeerHost option to IO::Socket::INET->new.
=item * Auth_Radius_port
The port on which the Radius server is listening: either its service name or
its actual port number. This parameter defaults to "1647" which is the
official service name for Radius servers. The parameter is passed as the
PeerPort option to IO::Socket::INET->new.
=item * Auth_Radius_secret
The shared secret for connection to the Radius server.
=item * Auth_Radius_timeout
The timeout in seconds to wait for a response from the Radius server.
( run in 1.746 second using v1.01-cache-2.11-cpan-140bd7fdf52 )