2fedd
public text v1 · immutable#!/usr/local/bin/perl -w
# $Id: tele2 53 2006-06-22 02:28:05Z vnaum $
# $URL: file:///usr/home/vnaum/work/svn-reps/work/trunk/rshb-ns/sm.bin/tele2 $
# $Author: vnaum $
# $Date: 2006-06-22 09:28:05 +0700 (Thu, 22 Jun 2006) $
=pod
Этот скрипт вызывается из aliases
tele2_pgp: "| /usr/libexec/sm.bin/tele2"
На stdin ему передаётся письмо.
Он из письма выковыривает аттач, расшифровывает
аттач pgp и кидает его в
\\mail-server\t2archive
\\mail-server\t2send
=cut
use File::Copy;
use POSIX qw(strftime);
use Sys::Syslog qw(:DEFAULT setlogsock);
# ======= subs =======
sub parse_addr
{
local($line)=@_;
return $1 if ($line=~/^[^<]*<(\S+@\S+)>/o);
return $1 if ($line=~/^(\S+@\S+)/o);
}
sub parse_header
{
undef $REPLYTO;
undef $USERADDR;
undef $SUBJECT;
while(<>)
{
last if (/^\s*$/o);
next unless (($headline,$value)=/([^:]+):\s*(.*)\s*$/o);
$SUBJECT=$value if ($headline=~/^Subject$/io);
$USERADDR = parse_addr($value) if ($headline=~/^From$/io);
$REPLYTO = parse_addr($value) if ($headline=~/^Reply-To$/io);
}
return 0 unless (defined($USERADDR) && defined($SUBJECT));
# ($USERNAME,$USERHOST)=split("@",$USERADDR);
return 1;
}
sub safe_die {
my $reason = shift;
syslog LOG_INFO, "!!! %s", $reason;
closelog;
die $reason
}
=pod
Эта функция считывает пароль из указанного файла.
Таким образом нет нужды указвать пароли в десяти местах.
=cut
sub get_pw_from_file($)
{
my ($pwf) = @_;
open F, '<', $pwf or die "Cannot open password file '$pwf':$!\n";
my $pw = <F>;
chomp $pw;
close F;
# Checking permissions:
my $mode = (stat($pwf))[2];
my $mode_o = $mode % 8; # (last octal number, "others")
# printf "mode == %o\n", $mode;
die "password file '$pwf' must not have any permissions for others!\n"
if ($mode_o);
return $pw;
}
# ======= subs =======
# === main ===
# Из этого кейринга будут браться ключи для расшифровки
$ENV{GNUPGHOME}='/usr/local/rshb/.gnupg/';
# Хэш с ключами, чьи подписи будут считаться подходящими.
# Каталоги не используются, всё валится в один.
# Главное, чтобы ключ был посчитан.
my %keyIDhomes=
(
'<pgp-fo@lyubino.rshb.com.ru>' => '/usr/local/rshb/fo/in/0901/',
'Gorky pgp gate <pgp-fo@gorky.rshb.com.ru>' => '/usr/local/rshb/fo/in/0907/',
'Poltava gate <pgp-fo@poltava.rshb.com.ru>' => '/usr/local/rshb/fo/in/0905/',
'pgp-fo@bolsher.rshb.com.ru' => '/usr/local/rshb/fo/in/0906/',
'pgp-fo@moskal.rshb.com.ru' => '/usr/local/rshb/fo/in/0903/',
'pgp-fo@murom.rshb.com.ru' => '/usr/local/rshb/fo/other/',
'pgp-fo@nv.rshb.com.ru' => '/usr/local/rshb/fo/in/0902/',
'pgp-fo@odesskoe.rshb.com.ru' => '/usr/local/rshb/fo/in/0909/',
'pgp-fo@krutinka.rshb.com.ru' => '/usr/local/rshb/fo/in/0910/',
'pgp-fo@scherbakul.rshb.com.ru' => '/usr/local/rshb/fo/in/0911/',
'pgp-fo@kalachinsk.rshb.com.ru' => '/usr/local/rshb/fo/in/0912/',
'pgp-fo@no.rshb.com.ru' => '/usr/local/rshb/fo/in/0914/',
'pgp-fo@kormilovka.rshb.com.ru' => '/usr/local/rshb/fo/in/0915/',
'pgp-fo@irkutskaya.rshb.com.ru' => '/usr/local/rshb/fo/in/0913/',
'pgp-fo@isilkul.rshb.com.ru' => '/usr/local/rshb/fo/in/0916/',
'pgp-fo@pavlogradka.rshb.com.ru' => '/usr/local/rshb/fo/in/0917/',
'pgp-fo@sargatka.rshb.com.ru' => '/usr/local/rshb/fo/in/0918/',
'pgp-fo@okoneshnikovo.rshb.com.ru' => '/usr/local/rshb/fo/in/0919/',
'pgp-fo@tavricheskoe.rshb.com.ru' => '/usr/local/rshb/fo/in/0920/',
'pgp-fo@naz.rshb.com.ru' => '/usr/local/rshb/fo/in/0921/',
'pgp-fo@@rusp.rshb.com.ru' => '/usr/local/rshb/fo/in/0922/',
);
setlogsock 'unix';
openlog 'tele2', 'ndelay,pid,nowait', 'local3';
syslog('debug', "Начало работы (euid == $>, egid == $))");
# Пароль секретного ключа
#my $pgp_pass = get_pw_from_file ('/usr/local/rshb/.pgp/pass');
parse_header() || return 0;
$filename = $SUBJECT;
$cryptedfile = "$SUBJECT.pgp";
syslog('debug', "Получен файл от $USERADDR - $filename");
chdir '/usr/local/rshb/fo/temp'
or safe_die("Не могу перейти в каталог /usr/local/rshb/fo/temp");
open TEMPFILE, '>', $cryptedfile
or safe_die("Не могу открыть файл $cryptedfile для записи вложения в него. Ошибка: $!");
print TEMPFILE <>;
close TEMPFILE;
syslog('debug', "Приступаю к расшифровке файла $cryptedfile");
# Запускаем pgp для расшифровки:
#$pgpres=`/usr/local/bin/pgp +batchmode -z "$pgp_pass" "$cryptedfile" -o "$filename"`;
#$pgpres=`/usr/local/bin/pgp +batchmode -z "Charlie" "$cryptedfile" -o "$filename"`;
#$pgpres=`/usr/local/bin/gpg "$cryptedfile"`;
$pgpres=`/usr/local/bin/gpg --output "$filename" --decrypt "$cryptedfile"`;
if ( $? == 0 )
{
syslog('debug', "'$cryptedfile' расшифрован удачно");
unlink $cryptedfile;
if ( $pgpres =~ /Good\ signature\ from \"(.*)\"/m ) {
$keyID=$1;
syslog('debug', "Найден ключ $keyID");
if ( exists $keyIDhomes{$keyID} ) {
my $putres=0;
if (system(
"/bin/echo put " . $filename
." | /usr/local/bin/smbclient \\\\\\\\mail-server\\\\t2send "
."tele2 -U tele2 >/dev/null 2>/dev/null"
))
{
$putres=1;
}
if (system(
"/bin/echo put " . $filename
." | /usr/local/bin/smbclient \\\\\\\\mail-server\\\\t2archive "
."tele2 -U tele2 >/dev/null 2>/dev/null"
))
{
$putres=1;
}
if ($putres)
{
safe_die("Расшифрованный файл tele2 не удалось поместить на сервер!");
}
else {
unlink $filename;
}
}
else {
safe_die("Для ключа $keyID не определён каталог")
}
}
else {
safe_die("Странная ситуация: PGP завершила работу удачно, "
."но KeyID найти не удалось - "
."возможно шифрование сторонним ключом\n$pgpres\n")
}
}
else
{
syslog('debug', "%s %d", "!!! Не расшифровывается $cryptedfile", length($cryptedfile));
syslog('debug', $pgpres);
}
syslog('debug', "Работа закончена");
closelog;