From: "Monte Mitzelfelt" <monte@gonefishing.org>
To: Ibrahim <ibam@baracuda.vision.net.id>
cc: nelson@qmail.org
Subject: Re: qmail with radius
Date: 22 Dec 1998 08:46:01 -0700
Date: Tue, 22 Dec 1998 08:46:01 -0700 (MST)


On Tue, 22 Dec 1998, Ibrahim wrote:

> I'll using radius to authenticate qmail. In www.qmail.org, you give a
> perl file, but I don't know How to include it in qmail and what
> arguments that needed your perl program.

It is a drop in replacement for the checkpassword function for
qmail-popup.  Just follow the manpage for qmail-popup and replace the
checkpassword program with the perl version that calls radius.  You'll
also need the Authen::Radius module from your local CPAN.  Go to
<URL:http://www.perl.com/CPAN> to find the one nearest you.  I'll append
the latest version, too.  It supports failover to multiple radius hosts.

#!/usr/local/bin/perl -T

use strict qw( vars ) ;
use Authen::Radius ;

$| = 1 ;

%ENV = () ;
exit( -1 ) unless ( @ARGV >= 2 && $ARGV[0] =~ m!^/! && -x $ARGV[0] ) ;

# get the radius shared secret
my( %secrets, ) ;
open SECRETS, "</path/to/clients"  # CHANGE this to correct path
  or exit( -2 ) ;
while (<SECRETS>) {
  s/\#.*$// ;
  s/^\s+// ;
  next if /^$/ ;
  my( $host, $sec, ) = split /\s+/ ;
  $secrets{ $host } = $sec ;
}
close SECRETS ;

# read from the 3rd filehandle qpopup sends user / pass to us that way.
my( $len, $buf, ) ;
open( USER, "<&=3" )
  or exit( -3 ) ;
$len = read( USER, $buf, 512 ) ;
close USER ;
exit(-3) if $len < 4 ;

# extract null-terminated user/pass pair from buf
my( $user, $pass ) = split /\x00/, $buf ;
$user = lc $user ;
$buf = "\x00" x $len ;
 
my $HOST ;

# CHANGE to local radius hostnames
HOST:
foreach $HOST ( qw/ radius1.domain.dom radius2.domain.dom / ) {
  # create a Radius query object
  my $r = new Authen::Radius( Host => $HOST,
                            Secret => $secrets{ $HOST } )
     or exit( -2 ) ;

  # check password
  if( $r->check_pwd( $user, $pass, ) ) {
    # print "You were verified via $HOST\n" ;
    @ENV{ 'USER', 'UID', 'GID', 'HOME', 'SHELL', }
      = (getpwnam( $user ))[ 0, 2, 3, 7, 8 ] ;
    exit(-4) unless $ENV{UID} ;
    $ENV{HOME} =~ m!((?:/\w[-_.\w]+)+)! ;
    $ENV{HOME} = $1 ;
    chdir $ENV{HOME} ;
    $> = $ENV{UID} ;
    $) = $ENV{GID} ;
    exec @ARGV ; # skip to program
  }
  undef $r ;
}

sleep( 10 ) ;
exit( -4 ) ;

