(RADIATOR) Patch against 3.13 to support per-client TACACS+ keys

Mike McCauley mikem at open.com.au
Sat Oct 8 02:20:42 CDT 2005


Hello James,

This looks useful and interesting (and backwards compatible!)
I think the only thing I would suggest is that the client-specific tacacs key 
be kept in a different parameter than Secret, say in TacacsKey. Otherwise you 
could not have a Tacacs and Radius client on the same box unless they had the 
same secret/key. What do you think?

Cheers.

On Saturday 08 October 2005 01:22, James FitzGibbon wrote:
> In Radiator v3.13, ServerTACACSPLUS uses a global key to decrypt the
> packets.  I'm trying to replace a Cisco TACACS+ server by enabling TACACS+
> in Radiator, but each of our devices uses a different key.
>
> The following patch against Radius/ServerTACACSPLUS.pm allows for the
> "secret" defined in the <Client> block for each device to be used as the
> TACACS+ key.  If there is no secret defined for the client, the global key
> is still used (so this shouldn't break anything for people currently using
> the global key configuration).
>
> I've tested this using Perl's Authen::TACACS module and with Radiator's
> tacacsplustest and it works properly.  What I haven't been able to test due
> to the way both of those tools work is an unencrypted TACACS+ request.
> Neither tool can set up an unencrypted request such that
> $Radius::ServerTACACSPLUS::TAC_PLUS_UNENCRYPTED_FLAG is set.  If you don't
> provide a key to tacacsplustest, it uses the default secret of 'mysecret'.
>
> I've yet to update documentation, but I would like to get some feedback as
> to usefulness before I polish this off to submit to OSC for possible
> inclusion in an upcoming release.
>
> Thanks
>
> Index: Radius/ServerTACACSPLUS.pm
> ===================================================================
> --- Radius/ServerTACACSPLUS.pm  (.../vendor/Radiator-3.13)      (revision
> 173)
> +++ Radius/ServerTACACSPLUS.pm  (.../trunk)     (revision 173)
> @@ -17,6 +17,7 @@
>
>  package Radius::ServerTACACSPLUS;
>  @ISA = qw(Radius::Configurable);
> +use Radius::Client;
>  use Radius::Configurable;
>  use Radius::Context;
>  use Digest::MD5;
> @@ -150,8 +151,6 @@
>
>      my $self = $class->SUPER::new($file, @args);
>
> -    $self->log($main::LOG_WARNING, "No Key defined for $class at
> '$main::config_file' line $.")
> -       if !defined $self->{Key};
>
>      # Create a TCP socket to listen on each BindAddress, register it with
> select
>      # Set up the TCP listener
> @@ -234,10 +233,30 @@
>         return;
>      }
>
> +    # Try to find a key to decrypt the payload (per-client, falling back
> to server global)
> +    my $key;
> +    my $peer = getpeername($newsocket);
> +    my(undef, $peeraddr) = Socket::unpack_sockaddr_in($peer);
> +    if( my $client = &Radius::Client::find($peeraddr) ) {
> +        if( defined $client->{Secret} ) {
> +            $key = $client->{Secret};
> +            $self->log($main::LOG_EXTRA_DEBUG, "Found per-client TACACS+
> key");
> +        }
> +    }
> +    if( !defined $key ) {
> +        if( defined $self->{Key} ) {
> +            $key = $self->{Key};
> +            $self->log($main::LOG_EXTRA_DEBUG, "Using Global TACACS+
> Key"); +        }
> +        else {
> +            $self->log($main::LOG_WARNING, "No Global TACACS+ Key
> defined");
> +        }
> +    }
> +
>      Radius::TacacsplusConnection->new
>         ($self, $newsocket,
>          MaxBufferSize             => $self->{MaxBufferSize},
> -        Key                       => $self->{Key},
> +        Key                       => $key,
>          AuthorizationTimeout      => $self->{AuthorizationTimeout},
>          AddToRequest              => $self->{AddToRequest},
>          GroupCacheFile            => $self->{GroupCacheFile},
> @@ -362,8 +381,14 @@
>      $self->{session_id} = $session_id;
>
>      # Maybe decrypt the payload
> -    $body = &crypt($session_id, $self->{Key}, $version, $seq_no, $body) if
> defined($self->{Key});
> -    $self->{parent}->log($main::LOG_EXTRA_DEBUG, "TacacsPlus request
> decrypted body: " . unpack('H*', $body));
> +    if( defined($self->{Key}) ) {
> +        $self->{parent}->log($main::LOG_EXTRA_DEBUG, "Decrypting
> TacacsPlus request");
> +        $body = &crypt($session_id, $self->{Key}, $version, $seq_no,
> $body);
> +        $self->{parent}->log($main::LOG_EXTRA_DEBUG, "TacacsPlus request
> decrypted body: " . unpack('H*', $body));
> +    }
> +    else {
> +        $self->{parent}->log($main::LOG_EXTRA_DEBUG, "TacacsPlus request
> body: " . unpack('H*', $body));
> +    }
>
>      if ($type == $Radius::ServerTACACSPLUS::TAC_PLUS_AUTHEN && $seq_no ==
> 1)
>      {
>
> --
> j.
>
> James FitzGibbon
> Systems Developer, Primus Telecommunications Canada Inc.
> 416.644.6111
>
> --
> No virus found in this outgoing message.
> Checked by AVG Anti-Virus.
> Version: 7.0.344 / Virus Database: 267.11.9/116 - Release Date: 9/30/2005

-- 
Mike McCauley                               mikem at open.com.au
Open System Consultants Pty. Ltd            Unix, Perl, Motif, C++, WWW
9 Bulbul Place Currumbin Waters QLD 4223 Australia   http://www.open.com.au
Phone +61 7 5598-7474                       Fax   +61 7 5598-7070

Radiator: the most portable, flexible and configurable RADIUS server 
anywhere. SQL, proxy, DBM, files, LDAP, NIS+, password, NT, Emerald, 
Platypus, Freeside, TACACS+, PAM, external, Active Directory, EAP, TLS, 
TTLS, PEAP etc on Unix, Windows, MacOS etc.

--
Archive at http://www.open.com.au/archives/radiator/
Announcements on radiator-announce at open.com.au
To unsubscribe, email 'majordomo at open.com.au' with
'unsubscribe radiator' in the body of the message.


More information about the radiator mailing list