Skip Menu |

This queue is for tickets about the Authen-Radius CPAN distribution.

Report information
The Basics
Id: 39351
Status: resolved
Priority: 0/
Queue: Authen-Radius

People
Owner: PORTAONE [...] cpan.org
Requestors: matteo.valsasna [...] uninsubria.it
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: (no value)
Fixed in: 0.24



Subject: error code persistent across queries because not reset by set_error
# $Id: Radius.pm,v 1.17 2007/02/20 06:15:04 andrew Exp $ This is perl, v5.8.8 built for x86_64-linux-gnu-thread-multi Linux skunk 2.6.18-5-amd64 #1 SMP Sat Dec 22 20:43:59 UTC 2007 x86_64 GNU/Linux problem: after one Authen::Radius objects encounters an error, it maintains its error state forever even if new queries are performed. I think that the error state should be cleared when a new radius query is started (e.g. using check_pwd), but the set_error function sets error to ENONE **only if not defined**. context: I'm using Authen::Radius in a perl script (attached) as an authentication helper for squid. Squid authentication helpers run forever, reading unsername and password on each line and printing ERR or OK, thus I'm re-using a single radius object for multiple queries. As I want to be able to query 2 radius servers, I check the error status after running check_pwd on the first server, and query the second server unless its ENONE. But I found out that, after one error was encountered, the same error code was still there for subsequent queries. I worked this around by re-creating the radius object if get_error returns something different not ENONE. after looking at the source, I see that there is an undocumented set_error function, which I could have used to explicitly set ENONE after reading the error status, but if this was the way it should at least have been documented in http://search.cpan.org/~manowar/RadiusPerl-0.09/Radius.pm.
Subject: radius_auth.pl
#!/usr/bin/perl #----------------------------------------------------------------------------------- # Author: Edmar Lourenco Borges; # Authenticator Squid/Radius; # Use perl modules perl RadiusPerl-0.05/MD5-1.7/IO-1.20 # Theses modules can be found in http://core.ring.gr.jp/archives/lang/perl/CPAN/modules #----------------------------------------------------------------------------------- # modified by MAtteo HCE Valsasna (matteo.valsasna@uninsubria.it) # * support for 2 radius server with basic failover # * timestamped logging # * radius object re-creation on error # * logging of error condition of errored object before query # last modification 20080917 use Radius; $|=1; BEGIN {;} END {print "ERR" unless $GLOBAL{loaded};} #------------------------------------------------------------------------------ #Definition of globals variables: #Radius Server: $Global{server1} = "" or "ip address[:port]" #Simetric Key: $Global{key} = "string" #------------------------------------------------------------------------------ $GLOBAL{loaded} = 0; $GLOBAL{server1} = "rad-02:1812"; $GLOBAL{server2} = "rad-01:1812"; $GLOBAL{key} = "***"; $GLOBAL{timeout} = 100; $GLOBAL{error}; $GLOBAL{radius1}; $GLOBAL{radius2}; $GLOBAL{errcount1}=0; $GLOBAL{errcount2}=0; $GLOBAL{err_thereshold}=0; sub debug { # strip newlines from comment string s/\\n//; # timestamp logs my $now = localtime time; # Uncomment this to enable debugging print STDERR "radius_auth[$$]: $now @_\n"; } main(); sub main { # init radius objects $GLOBAL{radius1} = new Authen::Radius(Host => $GLOBAL{server1}, Secret => $GLOBAL{key}, $GLOBAL{timeout}, Debug => 4); if (! $GLOBAL{radius1} ){ &debug ("1st radius creation failed"); } $GLOBAL{radius2} = new Authen::Radius(Host => $GLOBAL{server2}, Secret => $GLOBAL{key}, $GLOBAL{timeout}, Debug => 4); if (! $GLOBAL{radius2} ){ &debug ("2nd radius creation failed"); } &debug ("initialization completed. servers are $GLOBAL{server1} and $GLOBAL{server2}"); authentication(); } # end of main sub authentication { local(@info,$radius); # use Authen::Radius; #use Radius; $GLOBAL{loaded} = 1; while (<STDIN>) { # check for error status before query $error = $GLOBAL{radius1}->get_error; if ($error ne 'ENONE') { &debug ("WTF! error $error already set before query on $GLOBAL{server1}\n"); $GLOBAL{errcount1} ++; if ($GLOBAL{errcount1}=0 > $GLOBAL{err_thereshold}){ &debug ("giving UP\n"); exit (1); } } chop($_); @info = split(/ / , $_); # @info[0] =~ s/ateneo\\//; $res = $GLOBAL{radius1}->check_pwd(@info[0], @info[1]) ? "OK\n" : "ERR\n"; $error = $GLOBAL{radius1}->get_error; &debug ("checking @info[0] on $GLOBAL{server1}: ERRNO $error, RESULT $res"); if ($error ne 'ENONE') { # reset radius1 $GLOBAL{radius1} = new Authen::Radius(Host => $GLOBAL{server1}, Secret => $GLOBAL{key}, $GLOBAL{timeout}, Debug => 4); if (! $GLOBAL{radius1} ){ &debug ("1st radius RE-creation failed"); } else { &debug ("1st radius RE-creation success"); } # check for error status before query $error = $GLOBAL{radius2}->get_error; if ($error ne 'ENONE') { &debug ("WTF! error $error already set before query on $GLOBAL{server2}\n"); $GLOBAL{errcount2} ++; if ($GLOBAL{errcount2}=0 > $GLOBAL{err_thereshold}){ &debug ("giving UP\n"); exit (1); } } $res = $GLOBAL{radius2}->check_pwd(@info[0], @info[1]) ? "OK\n" : "ERR\n"; $error = $GLOBAL{radius2}->get_error; &debug ("checking again @info[0] on $GLOBAL{server2}: ERRNO $error, RESULT $res"); # reset radius2 if ($error ne 'ENONE') { $GLOBAL{radius2} = new Authen::Radius(Host => $GLOBAL{server2}, Secret => $GLOBAL{key}, $GLOBAL{timeout}, Debug => 4); if (! $GLOBAL{radius2} ){ &debug ("1st radius RE-creation failed"); } else { &debug ("1st radius RE-creation success"); } } } print $res; } } # end authentication
Issue is not reproduced in v0.24, error is cleared at the beginning of check_pwd().