#!/usr/bin/perl -w
#
# authRADIUS.pl
#
# An external authentication script against an external RADIUS server
#
#
# This script requires Authen::Radius module which in turn requires the following modules:
# * Digest::MD5 2.20 or higher
# * IO 1.12 or higher
# * Data::HexDump 0.02 or higher
# All of them can be found in <http://search.cpan.org>
#
# Originator page: <http://communigatepro.ru/CGAUTH/>
#
# Please send your comments to <support@communigatepro.ru>
#


my $RADIUSserver='127.0.0.1:1813';  # You need to redefine these values
my $RADIUSsecret='';


use strict;
use IO::Socket;
use Authen::Radius;
use Text::ParseWords;

die "You should configure the script before you launch it!\n" unless($RADIUSsecret);

$| = 1;
print "* authRADIUS script v1.0 started\n";
while (<STDIN>) {
  chomp;
  my ( $prefix, $command, @eargs ) = parse_line('\s+', 0, $_);

  if ( $command eq 'NEW' ) {
    print "$prefix ERROR \"This script doesn't create accounts\"\n";
  }
  elsif ( $command eq 'VRFY' ) {
    my ($account,$password,$address);
    if($eargs[0] =~ /^\(.*\)$/) {
      shift(@eargs);
    }
    $account=$eargs[0]; $password=$eargs[1];
    if($eargs[2] && $eargs[2] =~ /\[(.*)\]/) {
      $address=$1;
    }
    processVRFY($prefix,$account,$password,$address); 
 
  }
  elsif ( $command eq 'INTF' ) {
    if($eargs[0] < 3) {
      print "* This script requires CGPro version 4.1b7 or newer\n";
      exit;
    }
    print "$prefix INTF 3\n";
  }
  elsif ( $command eq 'QUIT' ) {
    print "$prefix OK\n";
    last;
  }
  else {
    print "$prefix ERROR \"Only VRFY,INTF and QUIT commands supported\"\n";
  }
}
print "* authRADIUS script ended\n";
exit;

sub processVRFY {
  my ($prefix,$account,$password,$address)=@_;

  my ($name,$domain); 
  if($account =~ /(.+)\@(.+)/) {  
    $name=$1;$domain=$2;
  } else {
    print "$prefix ERROR Full account name with \@ and domain part expected\n";
    return;
  }
  
  my $r = new Authen::Radius(Host => $RADIUSserver, Secret => $RADIUSsecret);
  #unless( $r ) {
  if(Authen::Radius::get_error) {
    print "$prefix ERROR \"login: ".Authen::Radius::strerror. "---".Authen::Radius::get_error."\"\n";
    return;
  }
   
  if( $r->check_pwd($account,$password,$address) ) {
    print "$prefix OK\n";
  } else {
    my $errCode=Authen::Radius::get_error();
    if($errCode) {    
      print "$prefix ERROR \"".Authen::Radius::strerror($errCode)."\"\n";
    } else {
      print "$prefix ERROR \"authentication failed\"\n";
    }
  }
}

__END__; 
