]>
git.proxmox.com Git - pmg-api.git/blob - src/PMG/API2/Quarantine.pm
1 package PMG
:: API2
:: Quarantine
;
13 use Mail
:: SpamAssassin
;
16 use PVE
:: Exception
qw(raise_param_exc raise_perm_exc) ;
17 use PVE
:: Tools
qw(extract_param) ;
18 use PVE
:: JSONSchema
qw(get_standard_option) ;
21 use PVE
:: APIServer
:: Formatter
;
24 use PMG
:: AccessControl
;
32 use base
qw(PVE::RESTHandler) ;
36 my $extract_pmail = sub {
37 my ( $authuser, $role ) = @_ ;
39 if ( $authuser =~ m/^(.+)\@quarantine$/ ) {
42 raise_param_exc
({ pmail
=> "got unexpected authuser ' $authuser ' with role ' $role '" });
45 my $verify_optional_pmail = sub {
46 my ( $authuser, $role, $pmail_param ) = @_ ;
49 if ( $role eq 'quser' ) {
50 $pmail = $extract_pmail ->( $authuser, $role );
51 raise_param_exc
({ pmail
=> "parameter not allwed with role ' $role '" })
52 if defined ( $pmail_param ) && ( $pmail ne $pmail_param );
54 raise_param_exc
({ pmail
=> "parameter required with role ' $role '" })
55 if ! defined ( $pmail_param );
56 $pmail = $pmail_param ;
65 return $res if ! defined ( $info );
67 my $saversion = Mail
:: SpamAssassin-
> VERSION ;
69 my $salocaldir = "/var/lib/spamassassin/ $saversion/updates_spamassassin_org " ;
71 $spamdesc = PMG
:: Utils
:: load_sa_descriptions
([ $salocaldir ]) if ! $spamdesc ;
73 foreach my $test ( split ( ',' , $info )) {
74 my ( $name, $score ) = split ( ':' , $test );
76 my $info = { name
=> $name, score
=> $score + 0 , desc
=> '-' };
77 if ( my $si = $spamdesc ->{ $name }) {
78 $info ->{ desc
} = $si ->{ desc
};
79 $info ->{ url
} = $si ->{ url
} if defined ( $si ->{ url
});
87 my $extract_email = sub {
90 return $data if ! $data ;
92 if ( $data =~ m/^.*\s(\S+)\s*$/ ) {
96 if ( $data =~ m/^<([^<>\s]+)>$/ ) {
100 if ( $data !~ m/[\s><]/ && $data =~ m/^(.+\@[^\.]+\..*[^\.]+)$/ ) {
109 my $get_real_sender = sub {
112 my @lines = split ( ' \n ' , $ref ->{ header
});
113 my $head = Mail
:: Header-
> new ( \
@lines );
115 my @fromarray = split ( '\s*,\s*' , $head -> get ( 'from' ) || $ref ->{ sender
});
116 my $from = $extract_email ->( $fromarray [ 0 ]) || $ref ->{ sender
};;
117 my $sender = $extract_email ->( $head -> get ( 'sender' ));
119 return $sender if $sender ;
124 my $parse_header_info = sub {
127 my $res = { subject
=> '' , from
=> '' };
129 my @lines = split ( ' \n ' , $ref ->{ header
});
130 my $head = Mail
:: Header-
> new ( \
@lines );
132 $res ->{ subject
} = PMG
:: Utils
:: decode_rfc1522
( PVE
:: Tools
:: trim
( $head -> get ( 'subject' ))) // '' ;
134 my @fromarray = split ( '\s*,\s*' , $head -> get ( 'from' ) || $ref ->{ sender
});
136 $res ->{ from
} = PMG
:: Utils
:: decode_rfc1522
( PVE
:: Tools
:: trim
( $fromarray [ 0 ])) // '' ;
138 my $sender = PMG
:: Utils
:: decode_rfc1522
( PVE
:: Tools
:: trim
( $head -> get ( 'sender' )));
139 $res ->{ sender
} = $sender if $sender && ( $sender ne $res ->{ from
});
141 $res ->{ envelope_sender
} = $ref ->{ sender
};
142 $res ->{ receiver
} = $ref ->{ receiver
} // $ref ->{ pmail
};
143 $res ->{ id
} = 'C' . $ref ->{ cid
} . 'R' . $ref ->{ rid
} . 'T' . $ref ->{ ticketid
};
144 $res ->{ time } = $ref ->{ time };
145 $res ->{ bytes
} = $ref ->{ bytes
};
147 my $qtype = $ref ->{ qtype
};
150 $res ->{ virusname
} = $ref ->{ info
};
151 $res ->{ spamlevel
} = 0 ;
152 } elsif ( $qtype eq 'S' ) {
153 $res ->{ spamlevel
} = $ref ->{ spamlevel
} // 0 ;
159 my $pmail_param_type = get_standard_option
( 'pmg-email-address' , {
160 description
=> "List entries for the user with this primary email address. Quarantine users cannot speficy this parameter, but it is required for all other roles." ,
164 __PACKAGE__-
> register_method ({
168 permissions
=> { user
=> 'all' },
169 description
=> "Directory index." ,
171 additionalProperties
=> 0 ,
180 links
=> [ { rel
=> 'child' , href
=> "{name}" } ],
186 { name
=> 'whitelist' },
187 { name
=> 'blacklist' },
188 { name
=> 'content' },
190 { name
=> 'spamusers' },
191 { name
=> 'spamstatus' },
193 { name
=> 'virusstatus' },
194 { name
=> 'quarusers' },
195 { name
=> 'attachment' },
196 { name
=> 'listattachments' },
197 { name
=> 'download' },
204 my $read_or_modify_user_bw_list = sub {
205 my ( $listname, $param, $addrs, $delete ) = @_ ;
207 my $rpcenv = PMG
:: RESTEnvironment-
> get ();
208 my $authuser = $rpcenv -> get_user ();
209 my $role = $rpcenv -> get_role ();
211 my $pmail = $verify_optional_pmail ->( $authuser, $role, $param ->{ pmail
});
213 my $dbh = PMG
:: DBTools
:: open_ruledb
();
215 my $list = PMG
:: Quarantine
:: add_to_blackwhite
(
216 $dbh, $pmail, $listname, $addrs, $delete );
219 foreach my $a ( @$list ) { push @$res, { address
=> $a }; }
223 __PACKAGE__-
> register_method ({
227 permissions
=> { check
=> [ 'admin' , 'qmanager' , 'audit' , 'quser' ] },
228 description
=> "Show user whitelist." ,
230 additionalProperties
=> 0 ,
232 pmail
=> $pmail_param_type,
249 return $read_or_modify_user_bw_list ->( 'WL' , $param );
252 __PACKAGE__-
> register_method ({
253 name
=> 'whitelist_add' ,
256 description
=> "Add user whitelist entries." ,
257 permissions
=> { check
=> [ 'admin' , 'qmanager' , 'audit' , 'quser' ] },
260 additionalProperties
=> 0 ,
262 pmail
=> $pmail_param_type,
263 address
=> get_standard_option
( 'pmg-whiteblacklist-entry-list' , {
264 description
=> "The address you want to add." ,
268 returns
=> { type
=> 'null' },
272 my $addresses = [ split ( ',' , $param ->{ address
})];
273 $read_or_modify_user_bw_list ->( 'WL' , $param, $addresses );
278 __PACKAGE__-
> register_method ({
279 name
=> 'whitelist_delete_base' ,
282 description
=> "Delete user whitelist entries." ,
283 permissions
=> { check
=> [ 'admin' , 'qmanager' , 'audit' , 'quser' ] },
286 additionalProperties
=> 0 ,
288 pmail
=> $pmail_param_type,
289 address
=> get_standard_option
( 'pmg-whiteblacklist-entry-list' , {
291 description
=> "The address, or comma-separated list of addresses, you want to remove." ,
295 returns
=> { type
=> 'null' },
299 my $addresses = [ split ( ',' , $param ->{ address
})];
300 $read_or_modify_user_bw_list ->( 'WL' , $param, $addresses, 1 );
305 # FIXME: remove for PMG 7.0 - addresses can contain stuff like '/' which breaks
306 # API path resolution, thus we replaced it by above "un-templated" call
307 __PACKAGE__-
> register_method ({
308 name
=> 'whitelist_delete' ,
309 path
=> 'whitelist/{address}' ,
311 description
=> "Delete user whitelist entries." ,
312 permissions
=> { check
=> [ 'admin' , 'qmanager' , 'audit' , 'quser' ] },
315 additionalProperties
=> 0 ,
317 pmail
=> $pmail_param_type,
318 address
=> get_standard_option
( 'pmg-whiteblacklist-entry-list' , {
319 description
=> "The address you want to remove." ,
323 returns
=> { type
=> 'null' },
327 my $addresses = [ split ( ',' , $param ->{ address
})];
328 $read_or_modify_user_bw_list ->( 'WL' , $param, $addresses, 1 );
333 __PACKAGE__-
> register_method ({
337 permissions
=> { check
=> [ 'admin' , 'qmanager' , 'audit' , 'quser' ] },
338 description
=> "Show user blacklist." ,
340 additionalProperties
=> 0 ,
342 pmail
=> $pmail_param_type,
359 return $read_or_modify_user_bw_list ->( 'BL' , $param );
362 __PACKAGE__-
> register_method ({
363 name
=> 'blacklist_add' ,
366 description
=> "Add user blacklist entries." ,
367 permissions
=> { check
=> [ 'admin' , 'qmanager' , 'audit' , 'quser' ] },
370 additionalProperties
=> 0 ,
372 pmail
=> $pmail_param_type,
373 address
=> get_standard_option
( 'pmg-whiteblacklist-entry-list' , {
374 description
=> "The address you want to add." ,
378 returns
=> { type
=> 'null' },
382 my $addresses = [ split ( ',' , $param ->{ address
})];
383 $read_or_modify_user_bw_list ->( 'BL' , $param, $addresses );
388 __PACKAGE__-
> register_method ({
389 name
=> 'blacklist_delete_base' ,
392 description
=> "Delete user blacklist entries." ,
393 permissions
=> { check
=> [ 'admin' , 'qmanager' , 'audit' , 'quser' ] },
396 additionalProperties
=> 0 ,
398 pmail
=> $pmail_param_type,
399 address
=> get_standard_option
( 'pmg-whiteblacklist-entry-list' , {
401 description
=> "The address, or comma-separated list of addresses, you want to remove." ,
405 returns
=> { type
=> 'null' },
409 my $addresses = [ split ( ',' , $param ->{ address
})];
410 $read_or_modify_user_bw_list ->( 'BL' , $param, $addresses, 1 );
415 # FIXME: remove for PMG 7.0 - addresses can contain stuff like '/' which breaks
416 # API path resolution, thus we replaced it by above "un-templated" call
417 __PACKAGE__-
> register_method ({
418 name
=> 'blacklist_delete' ,
419 path
=> 'blacklist/{address}' ,
421 description
=> "Delete user blacklist entries." ,
422 permissions
=> { check
=> [ 'admin' , 'qmanager' , 'audit' , 'quser' ] },
425 additionalProperties
=> 0 ,
427 pmail
=> $pmail_param_type,
428 address
=> get_standard_option
( 'pmg-whiteblacklist-entry-list' , {
429 description
=> "The address you want to remove." ,
433 returns
=> { type
=> 'null' },
437 my $addresses = [ split ( ',' , $param ->{ address
})];
438 $read_or_modify_user_bw_list ->( 'BL' , $param, $addresses, 1 );
443 __PACKAGE__-
> register_method ({
447 permissions
=> { check
=> [ 'admin' , 'qmanager' , 'audit' ] },
448 description
=> "Get a list of receivers of spam in the given timespan (Default the last 24 hours)." ,
450 additionalProperties
=> 0 ,
452 starttime
=> get_standard_option
( 'pmg-starttime' ),
453 endtime
=> get_standard_option
( 'pmg-endtime' ),
462 description
=> 'the receiving email' ,
471 my $rpcenv = PMG
:: RESTEnvironment-
> get ();
472 my $authuser = $rpcenv -> get_user ();
476 my $dbh = PMG
:: DBTools
:: open_ruledb
();
478 my $start = $param ->{ starttime
} // ( time - 86400 );
479 my $end = $param ->{ endtime
} // ( $start + 86400 );
481 my $sth = $dbh -> prepare (
482 "SELECT DISTINCT pmail " .
483 "FROM CMailStore, CMSReceivers WHERE " .
484 "time >= $start AND time < $end AND " .
485 "QType = 'S' AND CID = CMailStore_CID AND RID = CMailStore_RID " .
486 "AND Status = 'N' ORDER BY pmail" );
490 while ( my $ref = $sth -> fetchrow_hashref ()) {
491 push @$res, { mail
=> $ref ->{ pmail
} };
497 __PACKAGE__-
> register_method ({
498 name
=> 'spamstatus' ,
499 path
=> 'spamstatus' ,
501 permissions
=> { check
=> [ 'admin' , 'qmanager' , 'audit' ] },
502 description
=> "Get Spam Quarantine Status" ,
504 additionalProperties
=> 0 ,
511 description
=> 'Number of stored mails.' ,
515 description
=> "Estimated disk space usage in MByte." ,
519 description
=> "Average size of stored mails in bytes." ,
523 description
=> "Average spam level." ,
531 my $dbh = PMG
:: DBTools
:: open_ruledb
();
532 my $ref = PMG
:: DBTools
:: get_quarantine_count
( $dbh, 'S' );
537 __PACKAGE__-
> register_method ({
541 permissions
=> { check
=> [ 'admin' , 'qmanager' , 'audit' ] },
542 description
=> "Get a list of users with whitelist/blacklist setttings." ,
544 additionalProperties
=> 0 ,
548 description
=> 'If set, limits the result to the given list.' ,
549 enum
=> [ 'BL' , 'WL' ],
560 description
=> 'the receiving email' ,
569 my $rpcenv = PMG
:: RESTEnvironment-
> get ();
570 my $authuser = $rpcenv -> get_user ();
574 my $dbh = PMG
:: DBTools
:: open_ruledb
();
577 if ( $param ->{ list
}) {
578 $sth = $dbh -> prepare ( "SELECT DISTINCT pmail FROM UserPrefs WHERE name = ? ORDER BY pmail" );
579 $sth -> execute ( $param ->{ list
});
581 $sth = $dbh -> prepare ( "SELECT DISTINCT pmail FROM UserPrefs ORDER BY pmail" );
585 while ( my $ref = $sth -> fetchrow_hashref ()) {
586 push @$res, { mail
=> $ref ->{ pmail
} };
592 my $quarantine_api = sub {
593 my ( $param, $quartype, $check_pmail ) = @_ ;
595 my $rpcenv = PMG
:: RESTEnvironment-
> get ();
596 my $authuser = $rpcenv -> get_user ();
598 my $start = $param ->{ starttime
} // ( time - 86400 );
599 my $end = $param ->{ endtime
} // ( $start + 86400 );
604 my $role = $rpcenv -> get_role ();
605 $pmail = $verify_optional_pmail ->( $authuser, $role, $param ->{ pmail
});
606 $select = "SELECT * " .
607 "FROM CMailStore, CMSReceivers WHERE " .
608 "pmail = ? AND time >= $start AND time < $end AND " .
609 "QType = ' $quartype ' AND CID = CMailStore_CID AND RID = CMailStore_RID " .
610 "AND Status = 'N' ORDER BY pmail, time, receiver" ;
612 $select = "SELECT * " .
613 "FROM CMailStore, CMSReceivers WHERE " .
614 "time >= $start AND time < $end AND " .
615 "QType = ' $quartype ' AND CID = CMailStore_CID AND RID = CMailStore_RID " .
616 "AND Status = 'N' ORDER BY time, receiver" ;
621 my $dbh = PMG
:: DBTools
:: open_ruledb
();
623 my $sth = $dbh -> prepare ( $select );
626 $sth -> execute ( $pmail );
631 while ( my $ref = $sth -> fetchrow_hashref ()) {
632 my $data = $parse_header_info ->( $ref );
639 __PACKAGE__-
> register_method ({
643 permissions
=> { check
=> [ 'admin' , 'qmanager' , 'audit' , 'quser' ] },
644 description
=> "Get a list of quarantined spam mails in the given timeframe (default the last 24 hours) for the given user." ,
646 additionalProperties
=> 0 ,
648 starttime
=> get_standard_option
( 'pmg-starttime' ),
649 endtime
=> get_standard_option
( 'pmg-endtime' ),
650 pmail
=> $pmail_param_type,
659 description
=> 'Unique ID' ,
663 description
=> "Size of raw email." ,
667 description
=> "SMTP envelope sender." ,
671 description
=> "Header 'From' field." ,
675 description
=> "Header 'Sender' field." ,
680 description
=> "Receiver email address" ,
684 description
=> "Header 'Subject' field." ,
688 description
=> "Receive time stamp" ,
692 description
=> "Spam score." ,
700 return $quarantine_api ->( $param, 'S' , 1 );
703 __PACKAGE__-
> register_method ({
707 permissions
=> { check
=> [ 'admin' , 'qmanager' , 'audit' ] },
708 description
=> "Get a list of quarantined virus mails in the given timeframe (default the last 24 hours)." ,
710 additionalProperties
=> 0 ,
712 starttime
=> get_standard_option
( 'pmg-starttime' ),
713 endtime
=> get_standard_option
( 'pmg-endtime' ),
722 description
=> 'Unique ID' ,
726 description
=> "Size of raw email." ,
730 description
=> "SMTP envelope sender." ,
734 description
=> "Header 'From' field." ,
738 description
=> "Header 'Sender' field." ,
743 description
=> "Receiver email address" ,
747 description
=> "Header 'Subject' field." ,
751 description
=> "Receive time stamp" ,
755 description
=> "Virus name." ,
763 return $quarantine_api ->( $param, 'V' );
766 __PACKAGE__-
> register_method ({
767 name
=> 'attachment' ,
768 path
=> 'attachment' ,
770 permissions
=> { check
=> [ 'admin' , 'qmanager' , 'audit' ] },
771 description
=> "Get a list of quarantined attachment mails in the given timeframe (default the last 24 hours)." ,
773 additionalProperties
=> 0 ,
775 starttime
=> get_standard_option
( 'pmg-starttime' ),
776 endtime
=> get_standard_option
( 'pmg-endtime' ),
785 description
=> 'Unique ID' ,
789 description
=> "Size of raw email." ,
793 description
=> "SMTP envelope sender." ,
797 description
=> "Header 'From' field." ,
801 description
=> "Header 'Sender' field." ,
806 description
=> "Receiver email address" ,
810 description
=> "Header 'Subject' field." ,
814 description
=> "Receive time stamp" ,
822 return $quarantine_api ->( $param, 'A' );
825 __PACKAGE__-
> register_method ({
826 name
=> 'virusstatus' ,
827 path
=> 'virusstatus' ,
829 permissions
=> { check
=> [ 'admin' , 'qmanager' , 'audit' ] },
830 description
=> "Get Virus Quarantine Status" ,
832 additionalProperties
=> 0 ,
839 description
=> 'Number of stored mails.' ,
843 description
=> "Estimated disk space usage in MByte." ,
847 description
=> "Average size of stored mails in bytes." ,
855 my $dbh = PMG
:: DBTools
:: open_ruledb
();
856 my $ref = PMG
:: DBTools
:: get_quarantine_count
( $dbh, 'V' );
858 delete $ref ->{ avgspam
};
863 my $get_and_check_mail = sub {
864 my ( $id, $rpcenv, $dbh ) = @_ ;
866 my ( $cid, $rid, $tid ) = $id =~ m/^C(\d+)R(\d+)T(\d+)$/ ;
872 $dbh = PMG
:: DBTools
:: open_ruledb
();
875 my $ref = PMG
:: DBTools
:: load_mail_data
( $dbh, $cid, $rid, $tid );
877 my $authuser = $rpcenv -> get_user ();
878 my $role = $rpcenv -> get_role ();
880 if ( $role eq 'quser' ) {
881 my $quar_username = $ref ->{ pmail
} . ' @quarantine ' ;
882 raise_perm_exc
( "mail does not belong to user ' $authuser ' ( $ref ->{pmail})" )
883 if $authuser ne $quar_username ;
889 __PACKAGE__-
> register_method ({
893 permissions
=> { check
=> [ 'admin' , 'qmanager' , 'audit' , 'quser' ] },
894 description
=> "Get email data. There is a special formatter called 'htmlmail' to get sanitized html view of the mail content (use the '/api2/htmlmail/quarantine/content' url)." ,
896 additionalProperties
=> 0 ,
899 description
=> 'Unique ID' ,
901 pattern
=> 'C\d+R\d+T\d+' ,
905 description
=> "Display 'raw' eml data. Deactivates size limit." ,
916 description
=> 'Unique ID' ,
920 description
=> "Size of raw email." ,
924 description
=> "SMTP envelope sender." ,
928 description
=> "Header 'From' field." ,
932 description
=> "Header 'Sender' field." ,
937 description
=> "Receiver email address" ,
941 description
=> "Header 'Subject' field." ,
945 description
=> "Receive time stamp" ,
949 description
=> "Spam score." ,
953 description
=> "Information about matched spam tests (name, score, desc, url)." ,
957 description
=> "Raw email header data." ,
961 description
=> "Raw email data (first 4096 bytes). Useful for preview. NOTE: The 'htmlmail' formatter displays the whole email." ,
969 my $rpcenv = PMG
:: RESTEnvironment-
> get ();
970 my $format = $rpcenv -> get_format ();
972 my $raw = $param ->{ raw
} // 0 ;
974 my $ref = $get_and_check_mail ->( $param ->{ id
}, $rpcenv );
976 my $res = $parse_header_info ->( $ref );
978 my $filename = $ref ->{ file
};
979 my $spooldir = $PMG :: MailQueue
:: spooldir
;
981 my $path = " $spooldir/$filename " ;
983 if ( $format eq 'htmlmail' ) {
985 my $cfg = PMG
:: Config-
> new ();
986 my $viewimages = $cfg -> get ( 'spamquar' , 'viewimages' );
987 my $allowhref = $cfg -> get ( 'spamquar' , 'allowhrefs' );
989 $res ->{ content
} = PMG
:: HTMLMail
:: email_to_html
( $path, $raw, $viewimages, $allowhref ) // 'unable to parse mail' ;
991 # to make result verification happy
994 $res ->{ spamlevel
} = 0 ;
995 $res ->{ spaminfo
} = [];
997 # include additional details
999 # we want to get the whole email in raw mode
1000 my $maxbytes = (! $raw ) ?
4096 : undef ;
1002 my ( $header, $content ) = PMG
:: HTMLMail
:: read_raw_email
( $path, $maxbytes );
1004 $res ->{ file
} = $ref ->{ file
};
1005 $res ->{ spaminfo
} = decode_spaminfo
( $ref ->{ info
});
1006 $res ->{ header
} = $header ;
1007 $res ->{ content
} = $content ;
1014 my $get_attachments = sub {
1015 my ( $mailid, $dumpdir, $with_path ) = @_ ;
1017 my $rpcenv = PMG
:: RESTEnvironment-
> get ();
1019 my $ref = $get_and_check_mail ->( $mailid, $rpcenv );
1021 my $filename = $ref ->{ file
};
1022 my $spooldir = $PMG :: MailQueue
:: spooldir
;
1024 my $parser = PMG
:: MIMEUtils
:: new_mime_parser
({
1027 extract_uuencode
=> 0 ,
1028 dumpdir
=> $dumpdir,
1031 my $entity = $parser -> parse_open ( " $spooldir/$filename " );
1032 PMG
:: MIMEUtils
:: fixup_multipart
( $entity );
1033 PMG
:: MailQueue
:: decode_entities
( $parser, 'attachmentquarantine' , $entity );
1038 PMG
:: MIMEUtils
:: traverse_mime_parts
( $entity, sub {
1040 my $name = PMG
:: Utils
:: extract_filename
( $part -> head ) || "part- $id " ;
1041 my $attachment_path = $part ->{ PMX_decoded_path
};
1042 return if ! $attachment_path || ! - f
$attachment_path ;
1043 my $size = - s
$attachment_path // 0 ;
1048 'content-type' => $part -> head -> mime_attr ( 'content-type' ),
1050 $entry ->{ path
} = $attachment_path if $with_path ;
1058 __PACKAGE__-
> register_method ({
1059 name
=> 'listattachments' ,
1060 path
=> 'listattachments' ,
1062 permissions
=> { check
=> [ 'admin' , 'qmanager' , 'audit' ] },
1063 description
=> "Get Attachments for E-Mail in Quarantine." ,
1065 additionalProperties
=> 0 ,
1068 description
=> 'Unique ID' ,
1070 pattern
=> 'C\d+R\d+T\d+' ,
1081 description
=> 'Attachment ID' ,
1085 description
=> "Size of raw attachment in bytes." ,
1089 description
=> "Raw email header data." ,
1093 description
=> "Raw email header data." ,
1102 my $dumpdir = "/run/pmgproxy/pmg- $param ->{id}- $$ " ;
1103 my $res = $get_attachments ->( $param ->{ id
}, $dumpdir );
1110 __PACKAGE__-
> register_method ({
1114 permissions
=> { check
=> [ 'admin' , 'qmanager' , 'audit' , 'quser' ] },
1115 description
=> "Download E-Mail or Attachment from Quarantine." ,
1118 additionalProperties
=> 0 ,
1121 description
=> 'Unique ID' ,
1123 pattern
=> 'C\d+R\d+T\d+' ,
1127 description
=> "The Attachment ID for the mail." ,
1139 my $mailid = $param ->{ mailid
};
1140 my $attachmentid = $param ->{ attachmentid
};
1142 my $dumpdir = "/run/pmgproxy/pmg- $mailid - $$/ " ;
1145 if ( $attachmentid ) {
1146 my $attachments = $get_attachments ->( $mailid, $dumpdir, 1 );
1147 $res = $attachments ->[ $attachmentid ];
1149 raise_param_exc
({ attachmentid
=> "Invalid Attachment ID for Mail." });
1152 my $rpcenv = PMG
:: RESTEnvironment-
> get ();
1153 my $ref = $get_and_check_mail ->( $mailid, $rpcenv );
1154 my $spooldir = $PMG :: MailQueue
:: spooldir
;
1157 'content-type' => 'message/rfc822' ,
1158 path
=> " $spooldir/$ref ->{file}" ,
1162 $res ->{ fh
} = IO
:: File-
> new ( $res ->{ path
}, '<' ) ||
1163 die "unable to open file ' $res ->{path}' - $!\n " ;
1165 rmtree
$dumpdir if - e
$dumpdir ;
1171 PVE
:: APIServer
:: Formatter
:: register_page_formatter
(
1172 'format' => 'htmlmail' ,
1174 path
=> '/quarantine/content' ,
1176 my ( $res, $data, $param, $path, $auth, $config ) = @_ ;
1178 if (! HTTP
:: Status
:: is_success
( $res ->{ status
})) {
1179 return ( "Error $res ->{status}: $res ->{message}" , "text/plain" );
1182 my $ct = "text/html;charset=UTF-8" ;
1184 my $raw = $data ->{ content
};
1186 return ( encode
( 'UTF-8' , $raw ), $ct, 1 );
1189 __PACKAGE__-
> register_method ({
1193 description
=> "Execute quarantine actions." ,
1194 permissions
=> { check
=> [ 'admin' , 'qmanager' , 'quser' ] },
1197 additionalProperties
=> 0 ,
1200 description
=> 'Unique IDs, seperate with ;' ,
1202 pattern
=> 'C\d+R\d+T\d+(;C\d+R\d+T\d+)*' ,
1205 description
=> 'Action - specify what you want to do with the mail.' ,
1207 enum
=> [ 'whitelist' , 'blacklist' , 'deliver' , 'delete' ],
1211 returns
=> { type
=> "null" },
1215 my $rpcenv = PMG
:: RESTEnvironment-
> get ();
1216 my $action = $param ->{ action
};
1217 my @idlist = split ( ';' , $param ->{ id
});
1219 my $dbh = PMG
:: DBTools
:: open_ruledb
();
1221 for my $id ( @idlist ) {
1223 my $ref = $get_and_check_mail ->( $id, $rpcenv, $dbh );
1224 my $sender = $get_real_sender ->( $ref );
1226 if ( $action eq 'whitelist' ) {
1227 PMG
:: Quarantine
:: add_to_blackwhite
( $dbh, $ref ->{ pmail
}, 'WL' , [ $sender ]);
1228 } elsif ( $action eq 'blacklist' ) {
1229 PMG
:: Quarantine
:: add_to_blackwhite
( $dbh, $ref ->{ pmail
}, 'BL' , [ $sender ]);
1230 } elsif ( $action eq 'deliver' ) {
1231 PMG
:: Quarantine
:: deliver_quarantined_mail
( $dbh, $ref, $ref ->{ receiver
} // $ref ->{ pmail
});
1232 } elsif ( $action eq 'delete' ) {
1233 PMG
:: Quarantine
:: delete_quarantined_mail
( $dbh, $ref );
1235 die "internal error" ; # should not be reached