#!/usr/bin/perl -w -I/home/chris/software/tpop3d/scripts
#
# dotapopfile:
# Allow Unix users to authenticate themselves using a .apop file in their home
# directories. Works with tpop3d's auth-perl or auth-other.
#
# Copyright (c) 2001 Chris Lightfoot. All rights reserved.
#
my $rcsid = '$Id: dotapopfile,v 1.7 2002/02/02 16:07:04 chris Exp $';
package DotApopFile;
use TPOP3D::AuthDriver;
use File::stat;
use User::pwent;
use MD5;
@ISA = qw(TPOP3D::AuthDriver);
# Override generic APOP implementation.
sub apop ($$) {
my ($self, $req) = @_;
my $res = { 'result' => 'NO', 'logmsg' => "no such user $req->{user}" };
# See if the user exists.
$pw = getpwnam($req->{user});
if ($pw) {
# User exists
$file = $pw->dir() . "/.apop";
$sb = stat($file);
if ($sb) {
# ~/.apop file exists
if (($sb->mode & 077) == 0) {
# ~/.apop file has sane permissions
# retrieve password from .apop file
if (open(DOTAPOP, "<$file")) {
my $pass = <DOTAPOP>;
close(DOTAPOP);
if (defined($pass)) {
chomp($pass);
$pw =~ s/^\s+//;
$pw =~ s/\s+$//;
if (length($pass) > 0 && TPOP3D::AuthDriver::apopauth($req->{digest}, $req->{timestamp}, $pass) != 0) {
$res->{uid} = $pw->uid();
$res->{gid} = $pw->gid(); # or the mail group.
$res->{result} = 'YES';
$res->{logmsg} = "client $req->{user} connected from $req->{clienthost}";
} else {
$res->{logmsg} = "authentication failure for $req->{user}";
}
$pw = ' ' x 80; # clear password
}
} else {
$res->{logmsg} = "$file: $!";
}
} else {
$res->{logmsg} = "$file: mode " . sprintf("0%03o", $sb->mode & 0777) . " is too permissive";
}
} else {
$res->{logmsg} = "$req->{user} has no ~/.apop file";
}
}
return $res;
}
package main;
my $auth = new DotApopFile();
# Subroutine for auth-perl compatibility.
sub apopauth ($) {
return $auth->apop($_[0]);
}
# if running under auth_other, start main loop.
if (defined($ENV{TPOP3D_CONTEXT}) and $ENV{TPOP3D_CONTEXT} eq 'auth_other') {
$auth->run();
exit 0;
}
1;
syntax highlighted by Code2HTML, v. 0.9.1