public inbox for pmg-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pmg-devel] [PATCH pmg-api/gui] add quarantine self service button
@ 2020-11-17  8:05 Dominik Csapak
  2020-11-17  8:05 ` [pmg-devel] [PATCH pmg-api 1/3] refactor domain_regex to Utils Dominik Csapak
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Dominik Csapak @ 2020-11-17  8:05 UTC (permalink / raw)
  To: pmg-devel

adds an option/api call to request an quarantine link for an
email whose domain is in the relay domains

for now, we do not expose that option to the ui, but this can easily be
added if wanted

NOTES on security:

this adds a world reachable api call, that can potentially send e-mails
to users that belong to a relay domain

this is ok, since anybody can already send e-mails to the users
via normal smtp, and since the content of the e-mail cannot be
controlled, the only thing a potential attacker can do is a dos attack
(which can always be done via resource exhaustion, e.g. send a lot of mail)

we could add more checks to make it more secure, but not so convenient:
* add an option for a admin-settable shared secret that users must enter
  (makes it harder for the user to self-service, since the user has to
  know the secret)
* only allow it from 'trusted networks' (this makes probably no sense)
* add an option to allow it from a specific subnet (similar to above,
  but seperate from mail flow, which could make sense, but is also
  not as convenient)

for now all text is hardcoded, templates could be used later on
(if users want that)

also i am open for alternate wordings for all texts, i basically chose
what came to mind first...

pmg-api:

Dominik Csapak (3):
  refactor domain_regex to Utils
  add 'quarantinelink' to admin config
  api2/quarantine: add global sendlink api call

 src/PMG/API2/Quarantine.pm  | 87 +++++++++++++++++++++++++++++++++++++
 src/PMG/CLI/pmgqm.pm        | 29 +------------
 src/PMG/Config.pm           |  6 +++
 src/PMG/HTTPServer.pm       |  1 +
 src/PMG/Service/pmgproxy.pm |  4 ++
 src/PMG/Utils.pm            | 26 +++++++++++
 6 files changed, 126 insertions(+), 27 deletions(-)

pmg-gui:

Dominik Csapak (1):
  add 'Request Quarantine Link' Button to LoginView

 js/LoginView.js   | 33 +++++++++++++++++++++++++++++++++
 pmg-index.html.tt |  3 ++-
 2 files changed, 35 insertions(+), 1 deletion(-)

-- 
2.20.1





^ permalink raw reply	[flat|nested] 9+ messages in thread

* [pmg-devel] [PATCH pmg-api 1/3] refactor domain_regex to Utils
  2020-11-17  8:05 [pmg-devel] [PATCH pmg-api/gui] add quarantine self service button Dominik Csapak
@ 2020-11-17  8:05 ` Dominik Csapak
  2020-11-17 13:18   ` Stoiko Ivanov
  2020-11-17  8:05 ` [pmg-devel] [PATCH pmg-api 2/3] add 'quarantinelink' to admin config Dominik Csapak
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Dominik Csapak @ 2020-11-17  8:05 UTC (permalink / raw)
  To: pmg-devel

we will need this somewhere else later

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 src/PMG/CLI/pmgqm.pm | 29 ++---------------------------
 src/PMG/Utils.pm     | 26 ++++++++++++++++++++++++++
 2 files changed, 28 insertions(+), 27 deletions(-)

diff --git a/src/PMG/CLI/pmgqm.pm b/src/PMG/CLI/pmgqm.pm
index 937269f..39253db 100755
--- a/src/PMG/CLI/pmgqm.pm
+++ b/src/PMG/CLI/pmgqm.pm
@@ -33,31 +33,6 @@ sub setup_environment {
     PMG::RESTEnvironment->setup_default_cli_env();
 }
 
-sub domain_regex {
-    my ($domains) = @_;
-
-    my @ra;
-    foreach my $d (@$domains) {
-	# skip domains with non-DNS name characters
-	next if $d =~ m/[^A-Za-z0-9\-\.]/;
-	if ($d =~ m/^\.(.*)$/) {
-	    my $dom = $1;
-	    $dom =~ s/\./\\\./g;
-	    push @ra, $dom;
-	    push @ra, "\.\*\\.$dom";
-	} else {
-	    $d =~ s/\./\\\./g;
-	    push @ra, $d;
-	}
-    }
-
-    my $re = join ('|', @ra);
-
-    my $regex = qr/\@($re)$/i;
-
-    return $regex;
-}
-
 sub get_item_data {
     my ($data, $ref) = @_;
 
@@ -145,7 +120,7 @@ __PACKAGE__->register_method ({
 	my $dbh = PMG::DBTools::open_ruledb();
 
 	my $domains = PVE::INotify::read_file('domains');
-	my $domainregex = domain_regex([keys %$domains]);
+	my $domainregex = PMG::Utils::domain_regex([keys %$domains]);
 
 	my $sth = $dbh->prepare(
 	    "SELECT pmail, AVG(spamlevel) as spamlevel, count(*)  FROM CMailStore, CMSReceivers " .
@@ -278,7 +253,7 @@ __PACKAGE__->register_method ({
 	}
 
 	my $domains = PVE::INotify::read_file('domains');
-	my $domainregex = domain_regex([keys %$domains]);
+	my $domainregex = PMG::Utils::domain_regex([keys %$domains]);
 
 	my $template = "spamreport-${reportstyle}.tt";
 	my $found = 0;
diff --git a/src/PMG/Utils.pm b/src/PMG/Utils.pm
index d0654e1..a04d41b 100644
--- a/src/PMG/Utils.pm
+++ b/src/PMG/Utils.pm
@@ -1417,4 +1417,30 @@ sub reload_smtp_filter {
     return kill (10, $pid); # send SIGUSR1
 }
 
+sub domain_regex {
+    my ($domains) = @_;
+
+    my @ra;
+    foreach my $d (@$domains) {
+	# skip domains with non-DNS name characters
+	next if $d =~ m/[^A-Za-z0-9\-\.]/;
+	if ($d =~ m/^\.(.*)$/) {
+	    my $dom = $1;
+	    $dom =~ s/\./\\\./g;
+	    push @ra, $dom;
+	    push @ra, "\.\*\\.$dom";
+	} else {
+	    $d =~ s/\./\\\./g;
+	    push @ra, $d;
+	}
+    }
+
+    my $re = join ('|', @ra);
+
+    my $regex = qr/\@($re)$/i;
+
+    return $regex;
+}
+
+
 1;
-- 
2.20.1





^ permalink raw reply	[flat|nested] 9+ messages in thread

* [pmg-devel] [PATCH pmg-api 2/3] add 'quarantinelink' to admin config
  2020-11-17  8:05 [pmg-devel] [PATCH pmg-api/gui] add quarantine self service button Dominik Csapak
  2020-11-17  8:05 ` [pmg-devel] [PATCH pmg-api 1/3] refactor domain_regex to Utils Dominik Csapak
@ 2020-11-17  8:05 ` Dominik Csapak
  2020-11-17 13:20   ` Stoiko Ivanov
  2020-11-17  8:05 ` [pmg-devel] [PATCH pmg-api 3/3] api2/quarantine: add global sendlink api call Dominik Csapak
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Dominik Csapak @ 2020-11-17  8:05 UTC (permalink / raw)
  To: pmg-devel

to enable the 'Request Quarantine Link' button and api call

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 src/PMG/Config.pm           | 6 ++++++
 src/PMG/Service/pmgproxy.pm | 4 ++++
 2 files changed, 10 insertions(+)

diff --git a/src/PMG/Config.pm b/src/PMG/Config.pm
index cd69c9c..c7e2aca 100755
--- a/src/PMG/Config.pm
+++ b/src/PMG/Config.pm
@@ -126,6 +126,11 @@ sub properties {
 	    description => "Default DKIM selector",
 	    type => 'string', format => 'dns-name', #see RFC6376 3.1
 	},
+	quarantinelink => {
+	    description => "Enables user self-service for Quarantine Links. Caution: this is accessible without authentication",
+	    type => 'boolean',
+	    default => 0,
+	},
     };
 }
 
@@ -144,6 +149,7 @@ sub options {
 	dkim_sign => { optional => 1 },
 	dkim_sign_all_mail => { optional => 1 },
 	dkim_selector => { optional => 1 },
+	quarantinelink => { optional => 1 },
     };
 }
 
diff --git a/src/PMG/Service/pmgproxy.pm b/src/PMG/Service/pmgproxy.pm
index ea58b50..6d51048 100755
--- a/src/PMG/Service/pmgproxy.pm
+++ b/src/PMG/Service/pmgproxy.pm
@@ -21,6 +21,7 @@ use PVE::APIServer::Utils;
 
 use PMG::HTTPServer;
 use PMG::API2;
+use PMG::Config;
 
 use Template;
 
@@ -227,6 +228,8 @@ sub get_index {
 	$version = $1;
     };
 
+    my $cfg = PMG::Config->new();
+    my $quarantinelink = $cfg->get('admin', 'quarantinelink');
 
     $username = '' if !$username;
 
@@ -242,6 +245,7 @@ sub get_index {
 	debug => $args->{debug} || $server->{debug},
 	version => $version,
 	wtversion => $wtversion,
+	quarantinelink => $quarantinelink,
     };
 
     my $template_name;
-- 
2.20.1





^ permalink raw reply	[flat|nested] 9+ messages in thread

* [pmg-devel] [PATCH pmg-api 3/3] api2/quarantine: add global sendlink api call
  2020-11-17  8:05 [pmg-devel] [PATCH pmg-api/gui] add quarantine self service button Dominik Csapak
  2020-11-17  8:05 ` [pmg-devel] [PATCH pmg-api 1/3] refactor domain_regex to Utils Dominik Csapak
  2020-11-17  8:05 ` [pmg-devel] [PATCH pmg-api 2/3] add 'quarantinelink' to admin config Dominik Csapak
@ 2020-11-17  8:05 ` Dominik Csapak
  2020-11-17  8:05 ` [pmg-devel] [PATCH pmg-gui 1/1] add 'Request Quarantine Link' Button to LoginView Dominik Csapak
  2020-11-17 13:16 ` [pmg-devel] [PATCH pmg-api/gui] add quarantine self service button Stoiko Ivanov
  4 siblings, 0 replies; 9+ messages in thread
From: Dominik Csapak @ 2020-11-17  8:05 UTC (permalink / raw)
  To: pmg-devel

this api call takes an email, checks it against the relay domains,
and prepares a custom quarantinelink for that email  and sends it there

this has to happen unauthenticated, since the idea is that the user
want to access the quarantine but has no current ticket (and no
old spam report with a ticket)

to prevent abuse, we let the api call take 3 seconds, even if
it would fail due to an invalid e-mail address, so that an
potential attacker cannot probe for e-mails/relay domains.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 src/PMG/API2/Quarantine.pm | 87 ++++++++++++++++++++++++++++++++++++++
 src/PMG/HTTPServer.pm      |  1 +
 2 files changed, 88 insertions(+)

diff --git a/src/PMG/API2/Quarantine.pm b/src/PMG/API2/Quarantine.pm
index 73fb0ec..2b18b0c 100644
--- a/src/PMG/API2/Quarantine.pm
+++ b/src/PMG/API2/Quarantine.pm
@@ -8,6 +8,9 @@ use Data::Dumper;
 use Encode;
 use File::Path;
 use IO::File;
+use MIME::Entity;
+use URI::Escape;
+use Time::HiRes qw(usleep gettimeofday tv_interval);
 
 use Mail::Header;
 use Mail::SpamAssassin;
@@ -195,6 +198,7 @@ __PACKAGE__->register_method ({
 	    { name => 'attachment' },
 	    { name => 'listattachments' },
 	    { name => 'download' },
+	    { name => 'sendlink' },
 	];
 
 	return $result;
@@ -1239,4 +1243,87 @@ __PACKAGE__->register_method ({
 	return undef;
     }});
 
+__PACKAGE__->register_method ({
+    name =>'sendlink',
+    path => 'sendlink',
+    method => 'POST',
+    description => "Send Quarantine link to given e-mail.",
+    permissions => { user => 'world' },
+    protected => 1,
+    parameters => {
+	additionalProperties => 0,
+	properties => {
+	    mail => get_standard_option('pmg-email-address'),
+	},
+    },
+    returns => { type => "null" },
+    code => sub {
+	my ($param) = @_;
+
+	my $cfg = PMG::Config->new();
+
+	my $hostname = PVE::INotify::nodename();
+
+	my $is_enabled = $cfg->get('admin', 'quarantinelink');
+	if (!$is_enabled) {
+	    die "This feature is not enabled\n";
+	}
+
+	my $fqdn = $cfg->get('spamquar', 'hostname') //
+	    PVE::Tools::get_fqdn($hostname);
+
+	my $port = $cfg->get('spamquar', 'port') // 8006;
+
+	my $protocol = $cfg->get('spamquar', 'protocol') // 'https';
+
+	my $protocol_fqdn_port = "$protocol://$fqdn";
+	if (($protocol eq 'https' && $port != 443) ||
+	    ($protocol eq 'http' && $port != 80)) {
+	    $protocol_fqdn_port .= ":$port";
+	}
+
+	my $mailfrom = $cfg->get ('spamquar', 'mailfrom') //
+	    "Proxmox Mail Gateway <postmaster>";
+
+	my $domains = PVE::INotify::read_file('domains');
+	my $domainregex = PMG::Utils::domain_regex([keys %$domains]);
+
+	my $receiver = $param->{mail};
+
+	my $starttime = [gettimeofday];
+	my $delay = 0;
+
+	if ($receiver !~ $domainregex) {
+	    # make all calls to this take the same duration
+	    $delay = 3 - tv_interval($starttime);
+	    $delay = 0 if $delay < 0;
+	    sleep $delay;
+	    return undef; # silently ignore invalid mails
+	}
+
+	my $ticket = PMG::Ticket::assemble_quarantine_ticket($receiver);
+	my $esc_ticket = uri_escape($ticket);
+	my $link = "$protocol_fqdn_port/quarantine?ticket=${esc_ticket}";
+
+	my $text = "Here is your Link for the Spam Quarantine on $fqdn:\n\n$link\n";
+
+	my $top = MIME::Entity->build(
+	    Type    => "text/plain",
+	    To      => $receiver,
+	    From    => $mailfrom,
+	    Subject => "Proxmox Mail Gateway - Quarantine Link",
+	    Data    => $text,
+	);
+
+	# we use an empty envelope sender (we dont want to receive NDRs)
+	PMG::Utils::reinject_mail ($top, '', [$receiver], undef, $fqdn);
+
+	# make all calls to this take the same duration
+	$delay = 3 - tv_interval($starttime);
+	$delay = 0 if $delay < 0;
+	sleep $delay;
+
+	return undef;
+    }});
+
 1;
diff --git a/src/PMG/HTTPServer.pm b/src/PMG/HTTPServer.pm
index eb48b5f..3dc9655 100755
--- a/src/PMG/HTTPServer.pm
+++ b/src/PMG/HTTPServer.pm
@@ -58,6 +58,7 @@ sub auth_handler {
 
     # explicitly allow some calls without auth
     if (($rel_uri eq '/access/domains' && $method eq 'GET') ||
+	($rel_uri eq '/quarantine/sendlink' && ($method eq 'GET' || $method eq 'POST')) ||
 	($rel_uri eq '/access/ticket' && ($method eq 'GET' || $method eq 'POST'))) {
 	$require_auth = 0;
     }
-- 
2.20.1





^ permalink raw reply	[flat|nested] 9+ messages in thread

* [pmg-devel] [PATCH pmg-gui 1/1] add 'Request Quarantine Link' Button to LoginView
  2020-11-17  8:05 [pmg-devel] [PATCH pmg-api/gui] add quarantine self service button Dominik Csapak
                   ` (2 preceding siblings ...)
  2020-11-17  8:05 ` [pmg-devel] [PATCH pmg-api 3/3] api2/quarantine: add global sendlink api call Dominik Csapak
@ 2020-11-17  8:05 ` Dominik Csapak
  2020-11-17 13:27   ` Stoiko Ivanov
  2020-11-17 13:16 ` [pmg-devel] [PATCH pmg-api/gui] add quarantine self service button Stoiko Ivanov
  4 siblings, 1 reply; 9+ messages in thread
From: Dominik Csapak @ 2020-11-17  8:05 UTC (permalink / raw)
  To: pmg-devel

if the template has 'quarantinelink' enabled, we
show a button 'Request Quarantine Link' on the quarantine login ui

there a user can enter their e-mail and request a link to the quarantine

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
 js/LoginView.js   | 33 +++++++++++++++++++++++++++++++++
 pmg-index.html.tt |  3 ++-
 2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/js/LoginView.js b/js/LoginView.js
index 8e610aa..5546517 100644
--- a/js/LoginView.js
+++ b/js/LoginView.js
@@ -10,6 +10,10 @@ Ext.define('PMG.LoginView', {
 
 	    let realmfield = me.lookup('realmfield');
 
+	    let enableQuarantineLink = view.targetview === 'quarantineview' && !!Proxmox.QuarantineLink;
+
+	    me.lookup('quarantineButton').setVisible(enableQuarantineLink);
+
 	    if (view.targetview !== 'quarantineview') {
 		return;
 	    }
@@ -65,6 +69,28 @@ Ext.define('PMG.LoginView', {
 	    }
 	},
 
+	openQuarantineLinkWindow: function() {
+	    let me = this;
+	    me.lookup('loginwindow').setVisible(false);
+	    Ext.create('Proxmox.window.Edit', {
+		title: gettext('Request Quarantine Link'),
+		url: '/quarantine/sendlink',
+		method: 'POST',
+		items: [
+		    {
+			xtype: 'proxmoxtextfield',
+			name: 'mail',
+			fieldLabel: gettext('Your E-Mail'),
+		    },
+		],
+		listeners: {
+		    destroy: function() {
+			me.lookup('loginwindow').show(true);
+		    },
+		},
+	    }).show();
+	},
+
 	control: {
 	    'field[name=lang]': {
 		change: function(f, value) {
@@ -76,6 +102,9 @@ Ext.define('PMG.LoginView', {
 		    window.location.reload();
 		},
 	    },
+	    'button[reference=quarantineButton]': {
+		click: 'openQuarantineLinkWindow',
+	    },
 	    'button[reference=loginButton]': {
 		click: 'submitForm',
 	    },
@@ -172,6 +201,10 @@ Ext.define('PMG.LoginView', {
                         },
 		    ],
 		    buttons: [
+			{
+			    text: gettext('Request Quarantine Link'),
+			    reference: 'quarantineButton',
+			},
 			{
 			    text: gettext('Login'),
 			    reference: 'loginButton',
diff --git a/pmg-index.html.tt b/pmg-index.html.tt
index 4faf0cf..4a29ba2 100644
--- a/pmg-index.html.tt
+++ b/pmg-index.html.tt
@@ -30,7 +30,8 @@
         Setup: { auth_cookie_name: 'PMGAuthCookie' },
         NodeName: '[% nodename %]',
         UserName: '[% username %]',
-        CSRFPreventionToken: '[% token %]'
+        CSRFPreventionToken: '[% token %]',
+        QuarantineLink: [% IF quarantinelink %] true [% ELSE %] false [% END %],
       };
     </script>
     <script type="text/javascript" src="/proxmoxlib.js?ver=[% wtversion %]"></script>
-- 
2.20.1





^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [pmg-devel] [PATCH pmg-api/gui] add quarantine self service button
  2020-11-17  8:05 [pmg-devel] [PATCH pmg-api/gui] add quarantine self service button Dominik Csapak
                   ` (3 preceding siblings ...)
  2020-11-17  8:05 ` [pmg-devel] [PATCH pmg-gui 1/1] add 'Request Quarantine Link' Button to LoginView Dominik Csapak
@ 2020-11-17 13:16 ` Stoiko Ivanov
  4 siblings, 0 replies; 9+ messages in thread
From: Stoiko Ivanov @ 2020-11-17 13:16 UTC (permalink / raw)
  To: Dominik Csapak; +Cc: pmg-devel

Thanks for implementing this - many of our community will be happy!

Regarding the complete series:
applied the patch and tested it on my setup - works as advertised:
Reviewed-By: Stoiko Ivanov <s.ivanov@proxmox.com>
Tested-By: Stoiko Ivanov <s.ivanov@proxmox.com>

Have a few small nits/suggestions (will comment on the individual patches)
but those can be addressed later.



On Tue, 17 Nov 2020 09:05:09 +0100
Dominik Csapak <d.csapak@proxmox.com> wrote:

> adds an option/api call to request an quarantine link for an
> email whose domain is in the relay domains
> 
> for now, we do not expose that option to the ui, but this can easily be
> added if wanted
> 
> NOTES on security:
> 
> this adds a world reachable api call, that can potentially send e-mails
> to users that belong to a relay domain
> 
> this is ok, since anybody can already send e-mails to the users
> via normal smtp, and since the content of the e-mail cannot be
> controlled, the only thing a potential attacker can do is a dos attack
> (which can always be done via resource exhaustion, e.g. send a lot of mail)
> 
> we could add more checks to make it more secure, but not so convenient:
> * add an option for a admin-settable shared secret that users must enter
>   (makes it harder for the user to self-service, since the user has to
>   know the secret)
> * only allow it from 'trusted networks' (this makes probably no sense)
> * add an option to allow it from a specific subnet (similar to above,
>   but seperate from mail flow, which could make sense, but is also
>   not as convenient)
> 
> for now all text is hardcoded, templates could be used later on
> (if users want that)
> 
> also i am open for alternate wordings for all texts, i basically chose
> what came to mind first...
> 
> pmg-api:
> 
> Dominik Csapak (3):
>   refactor domain_regex to Utils
>   add 'quarantinelink' to admin config
>   api2/quarantine: add global sendlink api call
> 
>  src/PMG/API2/Quarantine.pm  | 87 +++++++++++++++++++++++++++++++++++++
>  src/PMG/CLI/pmgqm.pm        | 29 +------------
>  src/PMG/Config.pm           |  6 +++
>  src/PMG/HTTPServer.pm       |  1 +
>  src/PMG/Service/pmgproxy.pm |  4 ++
>  src/PMG/Utils.pm            | 26 +++++++++++
>  6 files changed, 126 insertions(+), 27 deletions(-)
> 
> pmg-gui:
> 
> Dominik Csapak (1):
>   add 'Request Quarantine Link' Button to LoginView
> 
>  js/LoginView.js   | 33 +++++++++++++++++++++++++++++++++
>  pmg-index.html.tt |  3 ++-
>  2 files changed, 35 insertions(+), 1 deletion(-)
> 





^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [pmg-devel] [PATCH pmg-api 1/3] refactor domain_regex to Utils
  2020-11-17  8:05 ` [pmg-devel] [PATCH pmg-api 1/3] refactor domain_regex to Utils Dominik Csapak
@ 2020-11-17 13:18   ` Stoiko Ivanov
  0 siblings, 0 replies; 9+ messages in thread
From: Stoiko Ivanov @ 2020-11-17 13:18 UTC (permalink / raw)
  To: Dominik Csapak; +Cc: pmg-devel

On Tue, 17 Nov 2020 09:05:10 +0100
Dominik Csapak <d.csapak@proxmox.com> wrote:

> we will need this somewhere else later
> 
> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
>  src/PMG/CLI/pmgqm.pm | 29 ++---------------------------
>  src/PMG/Utils.pm     | 26 ++++++++++++++++++++++++++
>  2 files changed, 28 insertions(+), 27 deletions(-)
> 
> diff --git a/src/PMG/CLI/pmgqm.pm b/src/PMG/CLI/pmgqm.pm
> index 937269f..39253db 100755
> --- a/src/PMG/CLI/pmgqm.pm
> +++ b/src/PMG/CLI/pmgqm.pm
> @@ -33,31 +33,6 @@ sub setup_environment {
>      PMG::RESTEnvironment->setup_default_cli_env();
>  }
>  
> -sub domain_regex {
> -    my ($domains) = @_;
> -
> -    my @ra;
> -    foreach my $d (@$domains) {
> -	# skip domains with non-DNS name characters
> -	next if $d =~ m/[^A-Za-z0-9\-\.]/;
> -	if ($d =~ m/^\.(.*)$/) {
> -	    my $dom = $1;
> -	    $dom =~ s/\./\\\./g;
> -	    push @ra, $dom;
> -	    push @ra, "\.\*\\.$dom";
> -	} else {
> -	    $d =~ s/\./\\\./g;
> -	    push @ra, $d;
> -	}
> -    }
> -
> -    my $re = join ('|', @ra);
> -
> -    my $regex = qr/\@($re)$/i;
> -
> -    return $regex;
> -}
> -
>  sub get_item_data {
>      my ($data, $ref) = @_;
>  
> @@ -145,7 +120,7 @@ __PACKAGE__->register_method ({
>  	my $dbh = PMG::DBTools::open_ruledb();
>  
>  	my $domains = PVE::INotify::read_file('domains');
> -	my $domainregex = domain_regex([keys %$domains]);
> +	my $domainregex = PMG::Utils::domain_regex([keys %$domains]);
>  
>  	my $sth = $dbh->prepare(
>  	    "SELECT pmail, AVG(spamlevel) as spamlevel, count(*)  FROM CMailStore, CMSReceivers " .
> @@ -278,7 +253,7 @@ __PACKAGE__->register_method ({
>  	}
>  
>  	my $domains = PVE::INotify::read_file('domains');
> -	my $domainregex = domain_regex([keys %$domains]);
> +	my $domainregex = PMG::Utils::domain_regex([keys %$domains]);
>  
>  	my $template = "spamreport-${reportstyle}.tt";
>  	my $found = 0;
> diff --git a/src/PMG/Utils.pm b/src/PMG/Utils.pm
> index d0654e1..a04d41b 100644
> --- a/src/PMG/Utils.pm
> +++ b/src/PMG/Utils.pm
> @@ -1417,4 +1417,30 @@ sub reload_smtp_filter {
>      return kill (10, $pid); # send SIGUSR1
>  }
>  
> +sub domain_regex {
> +    my ($domains) = @_;
> +
> +    my @ra;
> +    foreach my $d (@$domains) {
> +	# skip domains with non-DNS name characters
> +	next if $d =~ m/[^A-Za-z0-9\-\.]/;
> +	if ($d =~ m/^\.(.*)$/) {
> +	    my $dom = $1;
> +	    $dom =~ s/\./\\\./g;
> +	    push @ra, $dom;
> +	    push @ra, "\.\*\\.$dom";
> +	} else {
> +	    $d =~ s/\./\\\./g;
> +	    push @ra, $d;
> +	}
> +    }
> +
> +    my $re = join ('|', @ra);
> +
> +    my $regex = qr/\@($re)$/i;
> +
> +    return $regex;
> +}
> +
> +
nit: since pmgqm has a use statement for PMG::API2::Quarantine, we could
also move it there - but since all of it is in the same repository I don't
think it makes such a difference.
also: one extra newline

>  1;





^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [pmg-devel] [PATCH pmg-api 2/3] add 'quarantinelink' to admin config
  2020-11-17  8:05 ` [pmg-devel] [PATCH pmg-api 2/3] add 'quarantinelink' to admin config Dominik Csapak
@ 2020-11-17 13:20   ` Stoiko Ivanov
  0 siblings, 0 replies; 9+ messages in thread
From: Stoiko Ivanov @ 2020-11-17 13:20 UTC (permalink / raw)
  To: Dominik Csapak; +Cc: pmg-devel

On Tue, 17 Nov 2020 09:05:11 +0100
Dominik Csapak <d.csapak@proxmox.com> wrote:

> to enable the 'Request Quarantine Link' button and api call
> 
> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
>  src/PMG/Config.pm           | 6 ++++++
>  src/PMG/Service/pmgproxy.pm | 4 ++++
>  2 files changed, 10 insertions(+)
> 
> diff --git a/src/PMG/Config.pm b/src/PMG/Config.pm
> index cd69c9c..c7e2aca 100755
> --- a/src/PMG/Config.pm
> +++ b/src/PMG/Config.pm
> @@ -126,6 +126,11 @@ sub properties {
>  	    description => "Default DKIM selector",
>  	    type => 'string', format => 'dns-name', #see RFC6376 3.1
>  	},
> +	quarantinelink => {
> +	    description => "Enables user self-service for Quarantine Links. Caution: this is accessible without authentication",
> +	    type => 'boolean',
> +	    default => 0,
> +	},
>      };
>  }
>  
> @@ -144,6 +149,7 @@ sub options {
>  	dkim_sign => { optional => 1 },
>  	dkim_sign_all_mail => { optional => 1 },
>  	dkim_selector => { optional => 1 },
> +	quarantinelink => { optional => 1 },
>      };
>  }
>  
> diff --git a/src/PMG/Service/pmgproxy.pm b/src/PMG/Service/pmgproxy.pm
> index ea58b50..6d51048 100755
> --- a/src/PMG/Service/pmgproxy.pm
> +++ b/src/PMG/Service/pmgproxy.pm
> @@ -21,6 +21,7 @@ use PVE::APIServer::Utils;
>  
>  use PMG::HTTPServer;
>  use PMG::API2;
> +use PMG::Config;
>  
>  use Template;
>  
> @@ -227,6 +228,8 @@ sub get_index {
>  	$version = $1;
>      };
>  
> +    my $cfg = PMG::Config->new();
> +    my $quarantinelink = $cfg->get('admin', 'quarantinelink');
>  
>      $username = '' if !$username;
>  
> @@ -242,6 +245,7 @@ sub get_index {
>  	debug => $args->{debug} || $server->{debug},
>  	version => $version,
>  	wtversion => $wtversion,
> +	quarantinelink => $quarantinelink,
>      };
>  
>      my $template_name;
nit: I would probably put the change to pmgproxy in the next patch (where
it actually  gets used in the index.html.tt template




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [pmg-devel] [PATCH pmg-gui 1/1] add 'Request Quarantine Link' Button to LoginView
  2020-11-17  8:05 ` [pmg-devel] [PATCH pmg-gui 1/1] add 'Request Quarantine Link' Button to LoginView Dominik Csapak
@ 2020-11-17 13:27   ` Stoiko Ivanov
  0 siblings, 0 replies; 9+ messages in thread
From: Stoiko Ivanov @ 2020-11-17 13:27 UTC (permalink / raw)
  To: Dominik Csapak; +Cc: pmg-devel

On Tue, 17 Nov 2020 09:05:13 +0100
Dominik Csapak <d.csapak@proxmox.com> wrote:

> if the template has 'quarantinelink' enabled, we
> show a button 'Request Quarantine Link' on the quarantine login ui
> 
> there a user can enter their e-mail and request a link to the quarantine
> 
> Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
> ---
>  js/LoginView.js   | 33 +++++++++++++++++++++++++++++++++
>  pmg-index.html.tt |  3 ++-
>  2 files changed, 35 insertions(+), 1 deletion(-)
> 
> diff --git a/js/LoginView.js b/js/LoginView.js
> index 8e610aa..5546517 100644
> --- a/js/LoginView.js
> +++ b/js/LoginView.js
> @@ -10,6 +10,10 @@ Ext.define('PMG.LoginView', {
>  
>  	    let realmfield = me.lookup('realmfield');
>  
> +	    let enableQuarantineLink = view.targetview === 'quarantineview' && !!Proxmox.QuarantineLink;
as talked off-list - for me it was confusing to have the button only
available on the quarantine view. - No hard feelings on the topic
though... 


> +
> +	    me.lookup('quarantineButton').setVisible(enableQuarantineLink);
> +
>  	    if (view.targetview !== 'quarantineview') {
>  		return;
>  	    }
> @@ -65,6 +69,28 @@ Ext.define('PMG.LoginView', {
>  	    }
>  	},
>  
> +	openQuarantineLinkWindow: function() {
> +	    let me = this;
> +	    me.lookup('loginwindow').setVisible(false);
> +	    Ext.create('Proxmox.window.Edit', {
> +		title: gettext('Request Quarantine Link'),
> +		url: '/quarantine/sendlink',
> +		method: 'POST',
> +		items: [
> +		    {
> +			xtype: 'proxmoxtextfield',
> +			name: 'mail',
> +			fieldLabel: gettext('Your E-Mail'),
> +		    },
> +		],
> +		listeners: {
> +		    destroy: function() {
> +			me.lookup('loginwindow').show(true);
> +		    },
> +		},
> +	    }).show();
> +	},
> +
>  	control: {
>  	    'field[name=lang]': {
>  		change: function(f, value) {
> @@ -76,6 +102,9 @@ Ext.define('PMG.LoginView', {
>  		    window.location.reload();
>  		},
>  	    },
> +	    'button[reference=quarantineButton]': {
> +		click: 'openQuarantineLinkWindow',
> +	    },
>  	    'button[reference=loginButton]': {
>  		click: 'submitForm',
>  	    },
> @@ -172,6 +201,10 @@ Ext.define('PMG.LoginView', {
>                          },
>  		    ],
>  		    buttons: [
> +			{
> +			    text: gettext('Request Quarantine Link'),
> +			    reference: 'quarantineButton',
> +			},
>  			{
>  			    text: gettext('Login'),
>  			    reference: 'loginButton',
> diff --git a/pmg-index.html.tt b/pmg-index.html.tt
> index 4faf0cf..4a29ba2 100644
> --- a/pmg-index.html.tt
> +++ b/pmg-index.html.tt
> @@ -30,7 +30,8 @@
>          Setup: { auth_cookie_name: 'PMGAuthCookie' },
>          NodeName: '[% nodename %]',
>          UserName: '[% username %]',
> -        CSRFPreventionToken: '[% token %]'
> +        CSRFPreventionToken: '[% token %]',
> +        QuarantineLink: [% IF quarantinelink %] true [% ELSE %] false [% END %],
>        };
>      </script>
>      <script type="text/javascript" src="/proxmoxlib.js?ver=[% wtversion %]"></script>





^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-11-17 13:27 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-17  8:05 [pmg-devel] [PATCH pmg-api/gui] add quarantine self service button Dominik Csapak
2020-11-17  8:05 ` [pmg-devel] [PATCH pmg-api 1/3] refactor domain_regex to Utils Dominik Csapak
2020-11-17 13:18   ` Stoiko Ivanov
2020-11-17  8:05 ` [pmg-devel] [PATCH pmg-api 2/3] add 'quarantinelink' to admin config Dominik Csapak
2020-11-17 13:20   ` Stoiko Ivanov
2020-11-17  8:05 ` [pmg-devel] [PATCH pmg-api 3/3] api2/quarantine: add global sendlink api call Dominik Csapak
2020-11-17  8:05 ` [pmg-devel] [PATCH pmg-gui 1/1] add 'Request Quarantine Link' Button to LoginView Dominik Csapak
2020-11-17 13:27   ` Stoiko Ivanov
2020-11-17 13:16 ` [pmg-devel] [PATCH pmg-api/gui] add quarantine self service button Stoiko Ivanov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal