#!/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 = ; 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= ( '' => '/usr/local/rshb/fo/in/0901/', 'Gorky pgp gate ' => '/usr/local/rshb/fo/in/0907/', 'Poltava gate ' => '/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;