r420@erker: lars | 2008-09-28 17:37:42 +0200

module Mail::Ezmlm::GpgEzmlm:
 * added new dependencies: File::Path and File::Copy
 * renamed configuration backup directory from 'gpg-ezmlm.bak' to '.gpg-ezmlm.backup'
 * only create empty keyring directory, if it does not exist, yet
 * implement revert of gpg-ezmlm conversion
This commit is contained in:
lars 2008-09-29 20:44:45 +00:00
parent 84bb54f428
commit 71edc021ff

View file

@ -29,6 +29,8 @@ use strict;
use warnings; use warnings;
use diagnostics; use diagnostics;
use vars qw($GPG_EZMLM_BASE $VERSION @ISA @EXPORT @EXPORT_OK); use vars qw($GPG_EZMLM_BASE $VERSION @ISA @EXPORT @EXPORT_OK);
use File::Copy;
use File::Path;
use Carp; use Carp;
use Mail::Ezmlm; use Mail::Ezmlm;
@ -158,7 +160,7 @@ sub convert_to_encrypted {
} }
# the backup directory will contain the old config file and the dotqmails # the backup directory will contain the old config file and the dotqmails
$backup_dir = $list_dir . '/gpg-ezmlm.bak'; $backup_dir = $list_dir . '/.gpg-ezmlm.backup';
if ((! -e $backup_dir) && (!mkdir($backup_dir))) { if ((! -e $backup_dir) && (!mkdir($backup_dir))) {
warn "failed to create gpg-ezmlm conversion backup dir: $backup_dir"; warn "failed to create gpg-ezmlm conversion backup dir: $backup_dir";
return undef; return undef;
@ -253,8 +255,8 @@ sub convert_to_encrypted {
} }
# create the (empty) gnupg keyring directory - this enables the keyring # create the (empty) gnupg keyring directory - this enables the keyring
# management interface # management interface. Don't create it, if it already exists.
unless (mkdir("$list_dir/.gnupg", 0700)) { if ((!-e "$list_dir/.gnupg") && (!mkdir("$list_dir/.gnupg", 0700))) {
warn "failed to create the gnupg keyring directory: $!"; warn "failed to create the gnupg keyring directory: $!";
return undef; return undef;
} }
@ -300,9 +302,20 @@ object of the plaintext mailing list is returned.
sub convert_to_plaintext { sub convert_to_plaintext {
my $self = shift; my $self = shift;
my ($dot_loc, $list_dir); my ($dot_loc, $list_dir, $dot_prefix, $backup_dir);
$list_dir = $self->thislist(); $list_dir = $self->thislist();
# untaint the input
$list_dir =~ m/^([\w\d\_\-\.\/\@]+)$/;
unless (defined($1)) {
# sanitize directory name (it must be safe to put the warn message)
$list_dir =~ s/\W/_/g;
warn "[GpgEzmlm] the list directory contains invalid characters: '"
. $list_dir . "' (special characters are escaped)";
return undef;
}
$list_dir = $1;
# check if a directory was given # check if a directory was given
unless (defined($list_dir)) { unless (defined($list_dir)) {
$self->_seterror(-1, 'must define directory in convert_to_plaintext()'); $self->_seterror(-1, 'must define directory in convert_to_plaintext()');
@ -313,8 +326,8 @@ sub convert_to_plaintext {
$self->_seterror(-1, 'directory does not exist: ' . $list_dir); $self->_seterror(-1, 'directory does not exist: ' . $list_dir);
return undef; return undef;
} }
# check if the current object is still encrypted by opening it again # check if the current object is still encrypted
if (Mail::Ezmlm::GpgEzmlm->new($list_dir)) { unless (_is_encrypted($list_dir)) {
$self->_seterror(-1, 'list is not encrypted: ' . $list_dir); $self->_seterror(-1, 'list is not encrypted: ' . $list_dir);
return undef; return undef;
} }
@ -322,20 +335,78 @@ sub convert_to_plaintext {
# retrieve location of dotqmail-files # retrieve location of dotqmail-files
$dot_loc = _get_dotqmail_location($list_dir); $dot_loc = _get_dotqmail_location($list_dir);
# untaint "dot_loc"
$dot_loc =~ m/^([\w\d\_\-\.\@ \/]+)$/;
if (defined($1)) {
$dot_loc = $1;
} else {
$dot_loc =~ s/\W/_/g;
warn "[GpgEzmlm] directory name of dotqmail files contains invalid "
. "characters: $dot_loc (special characters are escaped)";
return undef;
}
# the backup directory should contain the old config file (if it existed)
# and the original dotqmail files
$backup_dir = $list_dir . '/.gpg-ezmlm.backup';
unless (-r $backup_dir) {
warn "[GpgEzmlm] failed to revert conversion - the backup directory "
. "is missing: $backup_dir";
return undef;
}
# the "dot_prefix" is the basename of the main dotqmail file
# (e.g. '.qmail-list-foo')
$dot_loc =~ m/\/([^\/]+)$/;
if (defined($1)) {
$dot_prefix = $1;
} else {
warn 'invalid location of dotqmail file: ' . $dot_loc;
return undef;
}
# the "dotqmail" location must be valid # the "dotqmail" location must be valid
unless (defined($dot_loc) && ($dot_loc ne '') && (-e $dot_loc)) { unless (defined($dot_loc) && ($dot_loc ne '') && (-e $dot_loc)) {
$self->_seterror(-1, 'dotqmail files not found: ' . $dot_loc); $self->_seterror(-1, 'dotqmail files not found: ' . $dot_loc);
return undef; return undef;
} }
# TODO: implement the custom backward conversion # start reverting the gpg-ezmlm conversion:
if (system("$GPG_EZMLM_BASE/gpg-ezmlm-convert.pl", "--quiet", "--revert", $list_dir, $dot_loc) != 0) { # - restore old dotqmail files
$self->_seterror($?, "failed to undo list encryption: " . $list_dir); # - restore old config file (if it existed before)
# replace the config file with the original one (if it exists)
if (-e "$backup_dir/config") {
unless (File::Copy::copy("$backup_dir/config", "$list_dir/config")) {
warn "[GpgEzmlm] failed to restore the original config file '"
. "$backup_dir/config' to '$list_dir/config': $!";
return undef;
}
} else {
unless (unlink("$list_dir/config")) {
warn "[GpgEzmlm] failed to remove the gpg-ezmlm config file ('"
. "$list_dir/config'): $!";
return undef;
}
}
# replace the dotqmail files with the ones from the backup
unless ((File::Copy::copy("$backup_dir/$dot_prefix", "$dot_loc"))
&& (File::Copy::copy("$backup_dir/$dot_prefix-default",
"$dot_loc-default",))) {
warn "[GpgEzmlm] failed to restore dotqmail files: $!";
return undef; return undef;
} }
$self->_seterror(undef); # remove the original directory
$self = $self->SUPER->new($list_dir); unless (File::Path::rmtree($backup_dir)) {
warn "[GpgEzmlm] failed to remove configuration backup directory ('"
. $backup_dir . "'): $!";
# just warn - don't fail
}
$self = Mail::Ezmlm->new($list_dir);
return $self; return $self;
} }