diff options
Diffstat (limited to 'libpamc/test/agents')
-rwxr-xr-x | libpamc/test/agents/secret@here | 308 |
1 files changed, 0 insertions, 308 deletions
diff --git a/libpamc/test/agents/secret@here b/libpamc/test/agents/secret@here deleted file mode 100755 index afdcbaa8..00000000 --- a/libpamc/test/agents/secret@here +++ /dev/null @@ -1,308 +0,0 @@ -#!/usr/bin/perl -# -# This is a simple example PAM authentication agent, it implements a -# simple shared secret authentication scheme. The PAM module pam_secret.so -# is its counter part. Both the agent and the remote server are able to -# authenticate one another, but the server is given the opportunity to -# ignore a failed authentication. -# - -$^W = 1; -use strict; -use IPC::Open2; -$| = 1; - -# display extra information to STDERR -my $debug = 0; -if (scalar @ARGV) { - $debug = 1; -} - -# Globals - -my %state; -my $default_key; - -my $next_key = $$; - -# loop over binary prompts -for (;;) { - my ($control, $data) = ReadBinaryPrompt(); - my ($reply_control, $reply_data); - - if ($control == 0) { - if ($debug) { - print STDERR "agent: no packet to read\n"; - } - last; - } elsif ($control == 0x02) { - ($reply_control, $reply_data) = HandleAgentSelection($data); - } elsif ($control == 0x01) { - ($reply_control, $reply_data) = HandleContinuation($data); - } else { - if ($debug) { - print STDERR - "agent: unrecognized packet $control {$data} to read\n"; - } - ($reply_control, $reply_data) = (0x04, ""); - } - - WriteBinaryPrompt($reply_control, $reply_data); -} - -# Only willing to exit well if we've completed our authentication exchange - -if (scalar keys %state) { - if ($debug) { - print STDERR "The following sessions are still active:\n "; - print STDERR join ', ', keys %state; - print STDERR "\n"; - } - exit 1; -} else { - exit 0; -} - -sub HandleAgentSelection ($) { - my ($data) = @_; - - unless ( $data =~ /^([a-zA-Z0-9_]+\@?[a-zA-Z0-9_.]*)\/(.*)$/ ) { - return (0x04, ""); - } - - my ($agent_name, $payload) = ($1, $2); - if ($debug) { - print STDERR "agent: ". "agent=$agent_name, payload=$payload\n"; - } - - # this agent has a defined name - if ($agent_name ne "secret\@here") { - if ($debug) { - print STDERR "bad agent name: [$agent_name]\n"; - } - return (0x04, ""); - } - - # the selection request is acompanied with a hexadecimal cookie - my @tokens = split '\|', $payload; - - unless ((scalar @tokens) == 2) { - if ($debug) { - print STDERR "bad payload\n"; - } - return (0x04, ""); - } - - unless ($tokens[1] =~ /^[a-z0-9]+$/) { - if ($debug) { - print STDERR "bad server cookie\n"; - } - return (0x04, ""); - } - - my $shared_secret = IdentifyLocalSecret($tokens[0]); - - unless (defined $shared_secret) { - # make a secret up - if ($debug) { - print STDERR "agent: cannot authenticate user\n"; - } - $shared_secret = GetRandom(); - } - - my $local_cookie = GetRandom(); - $default_key = $next_key++; - - $state{$default_key} = $local_cookie ."|". $tokens[1] ."|". $shared_secret; - - if ($debug) { - print STDERR "agent: \$state{$default_key} = $state{$default_key}\n"; - } - - return (0x01, $default_key ."|". $local_cookie); -} - -sub HandleContinuation ($) { - my ($data) = @_; - - my ($key, $server_digest) = split '\|', $data; - - unless (defined $state{$key}) { - # retries and out of sequence prompts are not permitted - return (0x04, ""); - } - - my $expected_digest = CreateDigest($state{$key}); - my ($local_cookie, $remote_cookie, $shared_secret) - = split '\|', $state{$key}; - delete $state{$key}; - - unless ($expected_digest eq $server_digest) { - if ($debug) { - print STDERR "agent: don't trust server - faking reply\n"; - print STDERR "agent: got ($server_digest)\n"; - print STDERR "agent: expected ($expected_digest)\n"; - } - - ## FIXME: Agent should exchange a prompt with the client warning - ## that the server is faking us out. - - return (0x03, CreateDigest($expected_digest . $data . GetRandom())); - } - - if ($debug) { - print STDERR "agent: server appears to know the secret\n"; - } - - my $session_authenticated_ticket = - CreateDigest($remote_cookie."|".$shared_secret."|".$local_cookie); - - # FIXME: Agent should set a derived session key environment - # variable (available for the client (and its children) to sign - # future data exchanges. - - if ($debug) { - print STDERR "agent: should putenv(" - ."\"AUTH_SESSION_TICKET=$session_authenticated_ticket\")\n"; - } - - # return agent's authenticating digest - return (0x03, CreateDigest($shared_secret."|".$remote_cookie - ."|".$local_cookie)); -} - -sub ReadBinaryPrompt { - my $buffer = " "; - my $count = read(STDIN, $buffer, 5); - if ($count == 0) { - # no more packets to read - return (0, ""); - } - - if ($count != 5) { - # broken packet header - return (-1, ""); - } - - my ($length, $control) = unpack("N C", $buffer); - if ($length < 5) { - # broken packet length - return (-1, ""); - } - - my $data = ""; - $length -= 5; - while ($count = read(STDIN, $buffer, $length)) { - $data .= $buffer; - if ($count != $length) { - $length -= $count; - next; - } - - if ($debug) { - print STDERR "agent: ". "data is [$data]\n"; - } - - return ($control, $data); - } - - # broken packet data - return (-1, ""); -} - -sub WriteBinaryPrompt ($$) { - my ($control, $data) = @_; - - my $length = 5 + length($data); - if ($debug) { - printf STDERR "agent: ". "{%d|0x%.2x|%s}\n", $length, $control, $data; - } - my $bp = pack("N C a*", $length, $control, $data); - print STDOUT $bp; - if ($debug) { - printf STDERR "agent: ". "agent has replied\n"; - } -} - -## -## Here is where we parse the simple secret file -## The format of this file is a list of lines of the following form: -## -## user@client0.host.name secret_string1 -## user@client1.host.name secret_string2 -## user@client2.host.name secret_string3 -## - -sub IdentifyLocalSecret ($) { - my ($identifier) = @_; - my $secret; - - if (open SECRETS, "< ". (getpwuid($<))[7] ."/.secret\@here") { - my $line; - while (defined ($line = <SECRETS>)) { - my ($id, $sec) = split /[\s]+/, $line; - if ((defined $id) && ($id eq $identifier)) { - $secret = $sec; - last; - } - } - close SECRETS; - } - - return $secret; -} - -## Here is where we generate a message digest - -sub CreateDigest ($) { - my ($data) = @_; - - my $pid = open2(\*MD5out, \*MD5in, "/usr/bin/md5sum -") - or die "you'll need /usr/bin/md5sum installed"; - - my $oldfd = select MD5in; $|=1; select $oldfd; - if ($debug) { - print STDERR "agent: ". "telling md5: <$data>\n"; - } - print MD5in "$data"; - close MD5in; - my $reply = <MD5out>; - ($reply) = split /\s/, $reply; - if ($debug) { - print STDERR "agent: ". "md5 said: <$reply>\n"; - } - close MD5out; - - return $reply; -} - -## get a random number - -sub GetRandom { - - if ( -r "/dev/urandom" ) { - open RANDOM, "< /dev/urandom" or die "crazy"; - - my $i; - my $reply = ""; - - for ($i=0; $i<4; ++$i) { - my $buffer = " "; - while (read(RANDOM, $buffer, 4) != 4) { - ; - } - $reply .= sprintf "%.8x", unpack("N", $buffer); - if ($debug) { - print STDERR "growing reply: [$reply]\n"; - } - } - close RANDOM; - - return $reply; - } else { - print STDERR "agent: ". "[got linux?]\n"; - return "%.8x%.8x%.8x%.8x", time, time, time, time; - } - -} - |