[pmg-devel] [PATCH pmg-api v2 08/11] add DKIM API paths

Dominik Csapak d.csapak at proxmox.com
Wed Oct 16 15:31:54 CEST 2019


one comment inline

On 10/15/19 9:46 PM, Stoiko Ivanov wrote:
> A new path is added at /config/dkim with 2 subpaths:
> * /config/dkim/domains gives access to the dkimdomains
> * /config/dkim/selector gives access to the private key for the configured
>    selector
> 
> Signed-off-by: Stoiko Ivanov <s.ivanov at proxmox.com>
> ---
>   src/Makefile             |   1 +
>   src/PMG/API2/Config.pm   |   7 +++
>   src/PMG/API2/DKIMSign.pm | 126 +++++++++++++++++++++++++++++++++++++++
>   3 files changed, 134 insertions(+)
>   create mode 100644 src/PMG/API2/DKIMSign.pm
> 
> diff --git a/src/Makefile b/src/Makefile
> index 5cf9d27..a640d8a 100644
> --- a/src/Makefile
> +++ b/src/Makefile
> @@ -119,6 +119,7 @@ LIBSOURCES =				\
>   	PMG/API2/DestinationTLSPolicy.pm\
>   	PMG/API2/Domains.pm		\
>   	PMG/API2/DKIMSignDomains.pm	\
> +	PMG/API2/DKIMSign.pm		\
>   	PMG/API2/Fetchmail.pm		\
>   	PMG/API2/Users.pm		\
>   	PMG/API2/Transport.pm		\
> diff --git a/src/PMG/API2/Config.pm b/src/PMG/API2/Config.pm
> index 3b688fa..43653e4 100644
> --- a/src/PMG/API2/Config.pm
> +++ b/src/PMG/API2/Config.pm
> @@ -23,6 +23,7 @@ use PMG::API2::SMTPWhitelist;
>   use PMG::API2::MimeTypes;
>   use PMG::API2::Fetchmail;
>   use PMG::API2::DestinationTLSPolicy;
> +use PMG::API2::DKIMSign;
>   
>   use base qw(PVE::RESTHandler);
>   
> @@ -81,6 +82,11 @@ __PACKAGE__->register_method ({
>       path => 'tlspolicy',
>   });
>   
> +__PACKAGE__->register_method({
> +    subclass => "PMG::API2::DKIMSign",
> +    path => 'dkim',
> +});
> +
>   __PACKAGE__->register_method ({
>       name => 'index',
>       path => '',
> @@ -118,6 +124,7 @@ __PACKAGE__->register_method ({
>   	push @$res, { section => 'whitelist' };
>   	push @$res, { section => 'regextest' };
>   	push @$res, { section => 'tlspolicy' };
> +	push @$res, { section => 'dkim' };
>   
>   	return $res;
>       }});
> diff --git a/src/PMG/API2/DKIMSign.pm b/src/PMG/API2/DKIMSign.pm
> new file mode 100644
> index 0000000..c6a74c3
> --- /dev/null
> +++ b/src/PMG/API2/DKIMSign.pm
> @@ -0,0 +1,126 @@
> +package PMG::API2::DKIMSign;
> +
> +use strict;
> +use warnings;
> +
> +use PVE::Tools qw(extract_param);
> +use PVE::JSONSchema qw(get_standard_option);
> +use PVE::Exception qw(raise_param_exc);
> +use PVE::RESTHandler;
> +
> +use PMG::Config;
> +use PMG::DKIMSign;
> +
> +use PMG::API2::DKIMSignDomains;
> +
> +use base qw(PVE::RESTHandler);
> +
> +__PACKAGE__->register_method({
> +    subclass => "PMG::API2::DKIMSignDomains",
> +    path => 'domains',
> +});
> +
> +__PACKAGE__->register_method({
> +    name => 'index',
> +    path => '',
> +    method => 'GET',
> +    description => "Directory index.",
> +    parameters => {
> +	additionalProperties => 0,
> +	properties => {},
> +    },
> +    returns => {
> +	type => 'array',
> +	items => {
> +	    type => "object",
> +	    properties => { section => { type => 'string'} },
> +	},
> +	links => [ { rel => 'child', href => "{section}" } ],
> +    },
> +    code => sub {
> +	my ($param) = @_;
> +
> +	return [
> +	    { section => 'domains'},
> +	    { section => 'selector'}
> +	];
> +    }});
> +
> +__PACKAGE__->register_method({
> +    name => 'set_selector',
> +    path => 'selector',
> +    method => 'POST',
> +    description => "Generate a new private key for selector. All future mail will be signed with the new key!",
> +    protected => 1,
> +    permissions => { check => [ 'admin' ] },
> +    proxyto => 'master',
> +    parameters => {
> +	additionalProperties => 0,
> +	properties => {
> +	    selector => {
> +		description => "DKIM Selector",
> +		type => 'string', format => 'dns-name',
> +	    },
> +	    keysize => {
> +		description => "Number of bits for the RSA-Key",
> +		type => 'integer', minimum => 1024
> +	    },
> +	},
> +    },
> +    returns => { type => 'null' },
> +    code => sub {
> +	my ($param) = @_;
> +	my $selector = extract_param($param, 'selector');
> +	my $keysize = extract_param($param, 'keysize');
> +
> +	eval { PMG::DKIMSign::set_selector($selector, $keysize); };
> +
> +	raise_param_exc({ selector => "could not generate private key: $@" }) if $@;

i would omit this raise_param_exc too, since the parameter conditions
checked in set_selector are already checked by the api here
and all other errors should not mark 'selector' as a faulty parameter

> +
> +	return undef;
> +    }});
> +
> +sub pmg_verify_dkim_pubkey_record {
> +    my ($rec, $noerr) = @_;
> +
> +    if ($rec !~ /\._domainkey\tIN\tTXT\t\( "v=DKIM1; h=sha256; k=rsa; ".+ \)  ; ----- DKIM key/ms ) {
> +	return undef if $noerr;
> +	die "value does not look like a valid DKIM TXT record\n";
> +    }
> +
> +    return $rec
> +}
> +
> +PVE::JSONSchema::register_format(
> +    'pmg-dkim-record', \&pmg_verify_dkim_pubkey_record);
> +
> +__PACKAGE__->register_method({
> +    name => 'get_selector_info',
> +    path => 'selector',
> +    method => 'GET',
> +    description => "Get the public key for the configured selector, prepared as DKIM TXT record",
> +    protected => 1,
> +    permissions => { check => [ 'admin' ] },
> +    proxyto => 'master',
> +    parameters => {
> +	additionalProperties => 0,
> +	properties => { },
> +    },
> +    returns => {
> +	type => 'object',
> +	properties => {
> +	    selector => { type => 'string', format => 'dns-name' },
> +	    keysize => { type => 'integer', minimum => 1024 },
> +	    record => { type => 'string', format => 'pmg-dkim-record'},
> +	},
> +    },
> +    code => sub {
> +	my $cfg = PMG::Config->new();
> +	my $selector = $cfg->get('admin', 'dkim_selector');
> +
> +	my ($record, $size);
> +	($record, $size) = PMG::DKIMSign::get_selector_info($selector);
> +
> +	return { selector => $selector, keysize => $size, record => $record };
> +    }});
> +1;
> 




More information about the pmg-devel mailing list