Skip to content

Commit

Permalink
qmail-remote: solve issue #1
Browse files Browse the repository at this point in the history
  • Loading branch information
pflanze committed Jun 19, 2020
1 parent 7e6a49b commit b0b2b44
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 70 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ Then run like:

opendkim-genkey # for options see `man opendkim-genkey`
mv default.private /var/qmail/control/dkim/global.key
# ^ or replace 'global' with whatever selector you want


### Test suite
Expand Down
121 changes: 61 additions & 60 deletions lib/MySignerPolicy.pm
Original file line number Diff line number Diff line change
Expand Up @@ -59,70 +59,71 @@ sub apply {
(undef, $domain) = split(/\./, $domain, 2);
}

my $conf = $self->config->{'global'};
return 0
if (!defined($conf->{'types'}) || defined($conf->{'types'}->{'none'}));

# set key file
$signer->key_file($conf->{'keyfile'});

# parse (signature) domain
if (substr($conf->{'domain'}, 0, 1) eq '/') {
open(FH, '<', $conf->{'domain'})
or croak('Unable to open domain-file: '.$!);
my $newdom = (split(/ /, <FH>))[0];
close(FH);
croak("Unable to read domain-file. Maybe empty file.")
if (!$newdom);
chomp($newdom);
$conf->{'domain'} = $newdom;
}

# generate signatures
my $sigdone = 0;
for my $type (keys(%{$conf->{'types'}})) {
my $sigconf = $conf->{'types'}->{$type};

my $get= sub {
my ($key)=@_;
my $fallback= exists $conf->{$key} ? $conf->{$key} : undef;
exists $sigconf->{$key} ? ($sigconf->{$key} || $fallback) : $fallback
};
my $getm= sub {
my ($key)=@_;
&$get($key) || $signer->$key
};

if ($type eq 'dkim') {
$signer->add_signature(
new Mail::DKIM::Signature(
Algorithm => &$getm('algorithm'),
Method => &$getm('method'),
Headers => &$getm('headers'),
Domain => &$getm('domain'),
Selector => &$getm('selector'),
Query => &$get('query'),
Identity => &$get('identity'),
Expiration => &$get('expiration'),
)
);
$sigdone = 1;
for my $selector (sort keys %{$self->config}) {
my $conf = $self->config->{$selector};
next # XX or report an error?
if (!defined($conf->{'types'}) || defined($conf->{'types'}->{'none'}));

# set key file
$signer->key_file($conf->{'keyfile'});

# parse (signature) domain
if (substr($conf->{'domain'}, 0, 1) eq '/') {
open(FH, '<', $conf->{'domain'})
or croak('Unable to open domain-file: '.$!);
my $newdom = (split(/ /, <FH>))[0];
close(FH);
croak("Unable to read domain-file. Maybe empty file.")
if (!$newdom);
chomp($newdom);
$conf->{'domain'} = $newdom;
}
elsif ($type eq 'domainkey') {
$signer->add_signature(
new Mail::DKIM::DkSignature(
Algorithm => 'rsa-sha1', # only rsa-sha1 supported
Method => &$getm('method'),
Headers => &$getm('selector'),
Domain => &$getm('domain'),
Selector => &$getm('selector'),
Query => &$get('query')
)
);
$sigdone = 1;

# generate signatures
for my $type (keys(%{$conf->{'types'}})) {
my $sigconf = $conf->{'types'}->{$type};

my $get= sub {
my ($key)=@_;
my $fallback= exists $conf->{$key} ? $conf->{$key} : undef;
exists $sigconf->{$key} ? ($sigconf->{$key} || $fallback) : $fallback
};
my $getm= sub {
my ($key)=@_;
&$get($key) || $signer->$key
};

if ($type eq 'dkim') {
$signer->add_signature(
new Mail::DKIM::Signature(
Algorithm => &$getm('algorithm'),
Method => &$getm('method'),
Headers => &$getm('headers'),
Domain => &$getm('domain'),
Selector => &$getm('selector'),
Query => &$get('query'),
Identity => &$get('identity'),
Expiration => &$get('expiration'),
)
);
$sigdone = 1;
}
elsif ($type eq 'domainkey') {
$signer->add_signature(
new Mail::DKIM::DkSignature(
Algorithm => 'rsa-sha1', # only rsa-sha1 supported
Method => &$getm('method'),
Headers => &$getm('selector'),
Domain => &$getm('domain'),
Selector => &$getm('selector'),
Query => &$get('query')
)
);
$sigdone = 1;
}
}
}

return $sigdone;
}

Expand Down
28 changes: 18 additions & 10 deletions qmail-remote
Original file line number Diff line number Diff line change
Expand Up @@ -103,16 +103,24 @@ our $config;
sub set_config_domain {
my ($domain)=@_;
my $keydir= $ENV{BETTER_QMAIL_REMOTE__KEYDIR} || '/var/qmail/control/dkim';
my $cfg= +{
types => { dkim => {} },
keyfile => "$keydir/global.key",
algorithm => 'rsa-sha256',
method => 'simple',
selector => 'global',
domain => $domain
};
lock_hash %$cfg;
$config->{'global'} = $cfg;
# Loop through all available .key files, add as corresponding
# selector, implementing
# https://github.com/pflanze/better-qmail-remote/issues/1 :
for my $keyfile (sort glob "$keydir/*.key") {
my ($selector)= $keyfile=~ m{([^/]+)\.key$}s
or die "BUG: can't extract selector from file '$keyfile'";
# $selector would e.g. be 'global'.
my $cfg = +{
types => { dkim => {} },
keyfile => $keyfile,
algorithm => 'rsa-sha256',
method => 'simple',
selector => $selector,
domain => $domain
};
lock_hash %$cfg;
$config->{$selector} = $cfg;
}
}

set_config_domain ( $sender=~ m{[^@]+\@([^/]+)}s ? $1
Expand Down

0 comments on commit b0b2b44

Please sign in to comment.