#!/usr/bin/perl
##
## $Id: generate.pl,v 1.2 1999/09/04 05:26:39 morgan Exp morgan $
##
## Andrew Morgan <morgan@linux.kernel.org>
##
## this is a test script for regressing changes to the PAM client
## library and PAM module. By replacing the PAM agent with this script
## you can transmit a known good (use generate.pl) raw fingerprint
## as if it were one that has just been entered.
##
## Note, this is precisely why fingerprint devices should be able to
## generate a trusted path to the remote server. With this
## module/agent pair, there is no protection against man in the
## middle-replay attacks.

# replace this with the full path of your sample fingerprint file
my $path_to_raw_fingerprint = "/home/morgan/finger/prints/test1";

$^W = 1;
use strict;
use IPC::Open2;

$| = 1;

open FILE, "< $path_to_raw_fingerprint";
my $data;
my $line;
while (defined ($line = <FILE>)) {
    $data .= $line;
}

print STDERR "len=" . length($data) . "\n";

WriteBinaryPrompt(\*STDOUT, 0x03, $data . "morgan");

exit 0;

sub ReadBinaryPrompt ($) {
    my ($fd) = @_;

    my $buffer = "     ";
    my $count = read($fd, $buffer, 5);
    if ($count == 0) {
	# no more packets to read
	return (0, "");
    }

    if ($count != 5) {
	print STDERR "broken packet header ($count)\n";
	return (-1, "");
    }
    
    my ($length, $control) = unpack("N C", $buffer);
    if ($length < 5) {
	print STDERR "broken packet header ($length)\n";
	return (-1, "");
    }

    my $data = "";
    $length -= 5;
    while ($length && ($count = read($fd, $buffer, $length))) {
	$data .= $buffer;
	$length -= $count;
    }

    print STDERR "server: ". "data is ". length($data) ." long\n";
    if ($length) {
	# broken packet data
	return (-1, "");
    } else {
	return ($control, $data);
    }
}

sub WriteBinaryPrompt ($$$) {
    my ($fd, $control, $data) = @_;

    my $length = 5 + length($data);
#    printf STDERR "server: ". "{%d|0x%.2x|%s}\n", $length, $control, $data;
    my $bp = pack("N C a*", $length, $control, $data);
    print $fd $bp;

    print STDERR "server: ". "control passed to agent\n";
}

