#!/usr/bin/perl # sessauth.pl: A non-graphical Session Authentication Agent for # FireWall-1 3.x # # Author: Dameon D. Welch (dwelch@phoneboy.com) # Version: 1.0 # Date: 12 August 1998 # # This program is designed to listen on port 261 for session authentication # requests from a FireWall-1 server. No access control of any kind is # performed on this connection, though I suppose you could easily # add it if you'd like. Because of the low port number used for the # agent, this program must regrettably run as root. # # The program is invoked as: # # sessauth.pl [ fwusername [ fwpassword ] ] # # If no arguments are specified in this program, the default is to prompt # for username and password when the Session Authentication Agent asks for # it. If the fwusername argument is specified, the password will be # prompted for (good for SecurID and S/Key). If both are specified (which # will only work for static password schemes), then it will run in a # non-interactive mode. # # Uses for this program: A (somewhat limited) session authentication agent # for people who run a non-supported OS for their client system (this # program was tested under Linux, but should run on anything that has # Perl) or who need the command-line capabilities. # # Version History: # # 1.0 Initial Release, which supports FireWall-1 Password and Unix Password. # I know I'm leaving out NT passwords, but I'll figure out how to support # that in the next release. # # License: # # GNU Copyleft (http://www.gnu.ai.mit.edu/copyleft/gpl.html) # The short version: Feel free to make changes and send them back to me # if you feel they are useful. But don't try and sell the program # or otherwise claim you wrote it. Because you didn't. I did. ;-) # # fnord. # # Parameters # # If you want to run this non-interactively and don't want to pass these # parameters on the command line, set fwuser and fwpass up. If you are # using a single-use password scheme like S/Key or SecurID, fwpass is # not used. These can be overridden #$fwuser = "skeyuser"; #$fwpass = "1234"; # If you want to see debugging output $DEBUG = 0; # Shouldn't have to change anything beyond this point. # If neither fwuser or fwpass is set, run in interactive mode. if ($fwuser eq "" && $fwpass eq "") { $INTER = 1; } if ( $ARGV[0] ne "" ) { $fwuser = $ARGV[0]; } # If the password is specified on the command line, then assume # non-interactive mode. if ( $ARGV[1] ne "" ) { $fwpass = $ARGV[1]; $INTER = 0; } # Sockets stuff $AF_INET = 2; $SOCK_STREAM = 1; $port = 261; $sockaddr = 'S n a4 x8'; ($name, $aliases, $proto) = getprotobyname('tcp'); if ( $port !~ /^\d+$/ ) { ($name, $aliases, $port) = getservbyport($port, 'tcp'); } $this = pack($sockaddr, $AF_INET, $port, "\0\0\0\0"); select(NS); $| = 1; select (STDOUT); socket(S, $AF_INET, $SOCK_STREAM, $proto) || die "socket: $!"; bind (S,$this) || die "bind: $!"; listen (S,5) || die "connect: $!"; select(S); $| = 1; select(STDOUT); while (1) { print "Listening for connection on port $port...\n" if $DEBUG; ($addr = accept(NS,S)) || die $!; if (($child = fork()) == 0) { print "Accepted connection\n" if $DEBUG; ($af, $port, $inetaddr) = unpack ($sockaddr,$addr); @inetaddr = unpack ('C4',$inetaddr); print "$af $port @inetaddr\n" if $DEBUG; $skeyno = 0; TOP: while () { print "recv: $_\n" if $DEBUG; /([0-9]{3}) (.+)/; $mno = $1; $mtext = $2; chop $mtext; print "mno = $mno ; mtext = $mtext\n" if $DEBUG; if ($mno eq "200") { print $mtext,"\n" if $INTER; next TOP; } if ($mno eq "331" && $mtext eq "User:" && $fwuser ne "") { print NS $fwuser,"\n"; print "send: $fwuser\n" if $DEBUG; next TOP; } if ($mno eq "331" && $mtext eq "User:" && $fwuser eq "") { print "Enter Username: "; while () { $user = $_; last; } print NS $user,"\n"; print "send: $user\n" if $DEBUG; next TOP; } if ($mno eq "331" && $mtext eq "*FireWall-1 password:") { print NS $fwpass,"\n"; print "send: $fwpass\n" if $DEBUG; next TOP; } if ($mno eq "331" && $mtext eq "*Unix password:") { print NS $fwpass,"\n"; print "send: $fwpass\n" if $DEBUG; next TOP; } if ($mno eq "331" && $mtext eq "*OS password:") { print NS $fwpass,"\n"; print "send: $fwpass\n" if $DEBUG; next TOP; } if ($mno eq "331" && $INTER) { print "Enter password: "; while () { $pass = $_; last; } print NS $pass,"\n"; print "send: $pass\n" if $DEBUG; next TOP; } elsif ($mno eq "331" && !$INTER) { die "Unrecognized authentication scheme"; } if ($mno eq "230") { last; } if ($mno eq "431" || $mno eq "530") { print "Exiting: $_" if $DEBUG; last; } } close(NS); exit; } close(NS); }