245 lines
6.5 KiB
Perl
245 lines
6.5 KiB
Perl
#!/usr/bin/perl
|
|
#
|
|
# Sample login-Script for use with radlogin
|
|
#
|
|
# Copyright (c) 1998 S.u.S.E. GmbH Fuerth, Germany.
|
|
#
|
|
# please send bugfixes or comments to feedback@suse.de.
|
|
#
|
|
# derived partly from login.radius/migs/login.radius
|
|
# currently does not do anything useful - for testing purposes only
|
|
# It only sets up Accounting for a simple Rlogin-User
|
|
#
|
|
# You can install this is /usr/sbin/login.radius for testing with
|
|
# radlogin
|
|
|
|
use strict;
|
|
|
|
# Programs and files.
|
|
my $prog_radacct = "/usr/bin/radacct";
|
|
my $prog_rlogin = "/usr/bin/rlogin";
|
|
my $prog_telnet = "/usr/bin/telnet";
|
|
my $prog_tcpclear = "/usr/bin/telnet -e ''";
|
|
my $prog_tty = "/usr/bin/tty";
|
|
my $prog_who = "/usr/bin/who";
|
|
|
|
my $debug = 1;
|
|
|
|
my $path_radiusclient_map = "/etc/radclient/port-id-map";
|
|
|
|
my $login_host = "0.0.0.0";
|
|
|
|
#############################################################################
|
|
|
|
# Main program.
|
|
|
|
print "Starting.\n" if ($debug);
|
|
|
|
# Run 'who am i' to determine the current port.
|
|
my $port = `$prog_tty`;
|
|
chomp ($port);
|
|
|
|
# Translate port numbers to numbers for RADIUS.
|
|
# This translation is done again by radacct, but it may be useful here.
|
|
# Remove if CPU time is a problem.
|
|
|
|
my ($portid, $line);
|
|
open (H, $path_radiusclient_map);
|
|
while (($line = <H>) && (!$portid))
|
|
{
|
|
my @info = split (/\s+/, $line);
|
|
$portid = $info[1] if ($info[0] eq $port);
|
|
}
|
|
close (H);
|
|
|
|
if ($debug)
|
|
{
|
|
# Print out all the RADIUS variables.
|
|
my @el = grep (/^RADIUS/, keys (%ENV));
|
|
my $e;
|
|
foreach $e (@el)
|
|
{
|
|
print "$e = " . $ENV{$e} . "\n";
|
|
}
|
|
}
|
|
|
|
# If the service type is Framed, then give them PPP.
|
|
# SLIP is not implemented (and will probably never be).
|
|
my $username = $ENV{"RADIUS_USER_NAME"};
|
|
|
|
# Generate a "unique" string for the session ID.
|
|
my $sessionid = "$$" . time ();
|
|
|
|
if ($ENV{"RADIUS_SERVICE_TYPE"} =~ /Login/)
|
|
{
|
|
# Warning: This code has not been tested as well as the PPP version,
|
|
# as of now (19961107).
|
|
|
|
# Determine what host to connect to.
|
|
if (($ENV{"RADIUS_LOGIN_IP_HOST"} eq "0.0.0.0") ||
|
|
!defined ($ENV{"RADIUS_LOGIN_IP_HOST"}))
|
|
{
|
|
die ("login_host not defined");
|
|
}
|
|
elsif ($ENV{"RADIUS_LOGIN_IP_HOST"} eq "255.255.255.255")
|
|
{
|
|
# The user should be able to choose. Prompt the user.
|
|
print "Host to connect to? ";
|
|
$login_host = <STDIN>;
|
|
chomp ($login_host);
|
|
}
|
|
else
|
|
{
|
|
# Use what's specified by the RADIUS server.
|
|
$login_host = $ENV{"RADIUS_LOGIN_IP_HOST"};
|
|
}
|
|
|
|
# Log into a host. Default to telnet. Do the accounting
|
|
# now, since the target of the login wouldn't know how to
|
|
# account for it.
|
|
|
|
# Time.
|
|
my $timestart = time ();
|
|
my $login_service = $ENV{"RADIUS_LOGIN_SERVICE"};
|
|
|
|
# What protocol are we running?
|
|
my ($prog_run, $login_port);
|
|
|
|
if ($login_service eq "Rlogin")
|
|
{
|
|
$prog_run = $prog_rlogin;
|
|
}
|
|
elsif ($login_service eq "Telnet")
|
|
{
|
|
$prog_run = $prog_telnet;
|
|
$login_port = $ENV{"RADIUS_LOGIN_PORT"};
|
|
}
|
|
elsif ($login_service eq "TCP-Clear")
|
|
{
|
|
$prog_run = $prog_tcpclear;
|
|
$login_port = $ENV{"RADIUS_LOGIN_PORT"};
|
|
} else {
|
|
die "unkown login_service $login_service\n";
|
|
}
|
|
|
|
# Start accounting. Send the record.
|
|
open (H, "| $prog_radacct") || die ("Cannot run $prog_radacct");
|
|
|
|
my $cmd =
|
|
"Acct-Session-ID = \"$sessionid\"\n" .
|
|
"User-Name = \"$username\"\n" .
|
|
"Acct-Status-Type = Start\n" .
|
|
"Acct-Authentic = RADIUS\n" .
|
|
"Service-Type = Login-User\n" .
|
|
"Login-Service = " . $login_service . "\n" .
|
|
"Login-IP-Host = $login_host\n";
|
|
print H $cmd;
|
|
close (H);
|
|
|
|
# Store the user information into portinfo. We need to
|
|
# manually fork, since we have to know the PID of the program.
|
|
|
|
my $pid = fork ();
|
|
if ($pid == 0)
|
|
{
|
|
# Child. Run the program.
|
|
# print "Connecting to $login_host:\n";
|
|
my $cmd = "$prog_run $login_host $login_port";
|
|
print "Running $cmd\n" if ($debug);
|
|
exec ("$cmd");
|
|
}
|
|
else
|
|
{
|
|
# Parent.
|
|
$login_host = $ENV{"RADIUS_LOGIN_IP_HOST"};
|
|
}
|
|
|
|
# Log into a host. Default to telnet. Do the accounting
|
|
# now, since the target of the login wouldn't know how to
|
|
# account for it.
|
|
|
|
# Time.
|
|
my $timestart = time ();
|
|
my $login_service = $ENV{"RADIUS_LOGIN_SERVICE"};
|
|
|
|
# What protocol are we running?
|
|
my ($prog_run, $login_port);
|
|
|
|
if ($login_service eq "Rlogin")
|
|
{
|
|
$prog_run = $prog_rlogin;
|
|
}
|
|
elsif ($login_service eq "Telnet")
|
|
{
|
|
$prog_run = $prog_telnet;
|
|
$login_port = $ENV{"RADIUS_LOGIN_PORT"};
|
|
}
|
|
elsif ($login_service eq "TCP-Clear")
|
|
{
|
|
$prog_run = $prog_tcpclear;
|
|
$login_port = $ENV{"RADIUS_LOGIN_PORT"};
|
|
} else {
|
|
die "unkown login_service $login_service\n";
|
|
}
|
|
|
|
# Start accounting. Send the record.
|
|
open (H, "| $prog_radacct") || die ("Cannot run $prog_radacct");
|
|
|
|
my $cmd =
|
|
"Acct-Session-ID = \"$sessionid\"\n" .
|
|
"User-Name = \"$username\"\n" .
|
|
"Acct-Status-Type = Start\n" .
|
|
"Acct-Authentic = RADIUS\n" .
|
|
"Service-Type = Login-User\n" .
|
|
"Login-Service = " . $login_service . "\n" .
|
|
"Login-IP-Host = $login_host\n";
|
|
print H $cmd;
|
|
close (H);
|
|
|
|
# Store the user information into portinfo. We need to
|
|
# manually fork, since we have to know the PID of the program.
|
|
|
|
my $pid = fork ();
|
|
if ($pid == 0)
|
|
{
|
|
# Child. Run the program.
|
|
# print "Connecting to $login_host:\n";
|
|
my $cmd = "$prog_run $login_host $login_port";
|
|
print "Running $cmd\n" if ($debug);
|
|
exec ("$cmd");
|
|
}
|
|
else
|
|
{
|
|
# Parent.
|
|
# Create the portinfo record, which needs the pid of the program
|
|
# to kill.
|
|
# The IP address is all zero, as it is not applicable here.
|
|
# Store the time now, and the Session-Timeout.
|
|
|
|
# Wait for the session to finish.
|
|
waitpid ($pid, 0);
|
|
}
|
|
# Stop. Send the record.
|
|
open (H, "| $prog_radacct") || die ("Cannot run $prog_radacct");
|
|
|
|
my $timespent = time () - $timestart;
|
|
|
|
my $cmd =
|
|
"Acct-Session-ID = \"$sessionid\"\n" .
|
|
"User-Name = \"$username\"\n" .
|
|
"Acct-Status-Type = Stop\n" .
|
|
"Acct-Authentic = RADIUS\n" .
|
|
"Service-Type = Login-User\n" .
|
|
"Login-Service = " . $login_service . "\n" .
|
|
"Login-IP-Host = $login_host\n" .
|
|
"Acct-Session-Time = $timespent\n";
|
|
|
|
print H $cmd;
|
|
close (H);
|
|
} else {
|
|
my $r = $ENV{"RADIUS_SERVICE_TYP"};
|
|
print "Unhandled Service-Type $r\n";
|
|
}
|
|
|
|
### END ####
|