]>
git.proxmox.com Git - pmg-api.git/blob - PMG/Config.pm
1 package PMG
:: Config
:: Base
;
8 use PVE
:: JSONSchema
qw(get_standard_option) ;
9 use PVE
:: SectionConfig
;
11 use base
qw(PVE::SectionConfig) ;
15 type
=> { description
=> "Section type." },
17 description
=> "Secion ID." ,
18 type
=> 'string' , format
=> 'pve-configid' ,
27 sub format_section_header
{
28 my ( $class, $type, $sectionId ) = @_ ;
30 if ( $type eq 'ldap' ) {
31 $sectionId =~ s/^ldap_// ;
32 return " $type : $sectionId\n " ;
34 return "section: $type\n " ;
39 sub parse_section_header
{
40 my ( $class, $line ) = @_ ;
42 if ( $line =~ m/^(ldap|section):\s*(\S+)\s*$/ ) {
43 my ( $raw_type, $raw_id ) = ( lc ( $1 ), $2 );
44 my $type = $raw_type eq 'section' ?
$raw_id : $raw_type ;
45 my $section_id = "${raw_type}_${raw_id}" ;
46 my $errmsg = undef ; # set if you want to skip whole section
47 eval { PVE
:: JSONSchema
:: pve_verify_configid
( $raw_id ); };
49 my $config = {}; # to return additional attributes
50 return ( $type, $section_id, $errmsg, $config );
55 package PMG
:: Config
:: Admin
;
60 use base
qw(PMG::Config::Base) ;
69 description
=> "Send daily reports." ,
74 description
=> "Demo mode - do not start SMTP filter." ,
79 description
=> "Administrator E-Mail address." ,
80 type
=> 'string' , format
=> 'email' ,
81 default => 'admin @domain .tld' ,
84 description
=> "HTTP proxy port." ,
90 description
=> "HTTP proxy server address." ,
94 description
=> "HTTP proxy user name." ,
98 description
=> "HTTP proxy password." ,
106 dailyreport
=> { optional
=> 1 },
107 demo
=> { optional
=> 1 },
108 proxyport
=> { optional
=> 1 },
109 proxyserver
=> { optional
=> 1 },
110 proxyuser
=> { optional
=> 1 },
111 proxypassword
=> { optional
=> 1 },
115 package PMG
:: Config
:: Spam
;
120 use base
qw(PMG::Config::Base) ;
129 description
=> "This option is used to specify which languages are considered OK for incoming mail." ,
131 pattern
=> '(all|([a-z][a-z])+( ([a-z][a-z])+)*)' ,
135 description
=> "Whether to use the naive-Bayesian-style classifier." ,
140 description
=> "Use the Auto-Whitelist plugin." ,
145 description
=> "Whether to use Razor2, if it is available." ,
150 description
=> "Enable OCR to scan pictures." ,
154 wl_bounce_relays
=> {
155 description
=> "Whitelist legitimate bounce relays." ,
159 description
=> "Additional score for bounce mails." ,
166 description
=> "Enable real time blacklists (RBL) checks." ,
171 description
=> "Maximum size of spam messages in bytes." ,
181 use_awl
=> { optional
=> 1 },
182 use_razor
=> { optional
=> 1 },
183 use_ocr
=> { optional
=> 1 },
184 wl_bounce_relays
=> { optional
=> 1 },
185 languages
=> { optional
=> 1 },
186 use_bayes
=> { optional
=> 1 },
187 bounce_score
=> { optional
=> 1 },
188 rbl_checks
=> { optional
=> 1 },
189 maxspamsize
=> { optional
=> 1 },
193 package PMG
:: Config
:: ClamAV
;
198 use base
qw(PMG::Config::Base) ;
207 description
=> "ClamAV database mirror server." ,
209 default => 'database.clamav.net' ,
211 archiveblockencrypted
=> {
212 description
=> "Wether to block encrypted archives. Mark encrypted archives as viruses." ,
217 description
=> "Nested archives are scanned recursively, e.g. if a ZIP archive contains a TAR file, all files within it will also be scanned. This options specifies how deeply the process should be continued. Warning: setting this limit too high may result in severe damage to the system." ,
222 description
=> "Number of files to be scanned within an archive, a document, or any other kind of container. Warning: disabling this limit or setting it too high may result in severe damage to the system." ,
228 description
=> "Files larger than this limit won't be scanned." ,
234 description
=> "Sets the maximum amount of data to be scanned for each input file." ,
237 default => 100000000 ,
240 description
=> "This option sets the lowest number of Credit Card or Social Security numbers found in a file to generate a detect." ,
250 archiveblockencrypted
=> { optional
=> 1 },
251 archivemaxrec
=> { optional
=> 1 },
252 archivemaxfiles
=> { optional
=> 1 },
253 archivemaxsize
=> { optional
=> 1 },
254 maxscansize
=> { optional
=> 1 },
255 dbmirror
=> { optional
=> 1 },
256 maxcccount
=> { optional
=> 1 },
260 package PMG
:: Config
:: LDAP
;
265 use base
qw(PMG::Config::Base) ;
274 description
=> "LDAP protocol mode ('ldap' or 'ldaps')." ,
276 enum
=> [ 'ldap' , 'ldaps' ],
284 mode
=> { optional
=> 1 },
288 package PMG
:: Config
:: Mail
;
293 use PVE
:: ProcFSTools
;
295 use base
qw(PMG::Config::Base) ;
302 sub physical_memory
{
304 return $physicalmem if $physicalmem ;
306 my $info = PVE
:: ProcFSTools
:: read_meminfo
();
307 my $total = int ( $info ->{ memtotal
} / ( 1024 * 1024 ));
312 sub get_max_filters
{
313 # estimate optimal number of filter servers
317 my $memory = physical_memory
();
318 my $add_servers = int (( $memory - 512 )/ $servermem );
319 $max_servers += $add_servers if $add_servers > 0 ;
320 $max_servers = 40 if $max_servers > 40 ;
322 return $max_servers - 2 ;
328 description
=> "ESMTP banner." ,
331 default => 'ESMTP Proxmox' ,
334 description
=> "Maximum number of filter processes." ,
338 default => get_max_filters
(),
341 description
=> "Hide received header in outgoing mails." ,
346 description
=> "Maximum email size. Larger mails are rejected." ,
349 default => 1024 * 1024 * 10 ,
356 max_size
=> { optional
=> 1 },
357 banner
=> { optional
=> 1 },
358 max_filters
=> { optional
=> 1 },
359 hide_received
=> { optional
=> 1 },
376 PMG
:: Config
:: Admin-
> register ();
377 PMG
:: Config
:: Mail-
> register ();
378 PMG
:: Config
:: Spam-
> register ();
379 PMG
:: Config
:: LDAP-
> register ();
380 PMG
:: Config
:: ClamAV-
> register ();
382 # initialize all plugins
383 PMG
:: Config
:: Base-
> init ();
389 my $class = ref ( $type ) || $type ;
391 my $cfg = PVE
:: INotify
:: read_file
( "pmg.conf" );
393 return bless $cfg, $class ;
397 # this does not work for ldap entries
399 my ( $self, $section, $key, $value ) = @_ ;
401 my $pdata = PMG
:: Config
:: Base-
> private ();
403 die "internal error" if $section eq 'ldap' ;
405 my $plugin = $pdata ->{ plugins
}->{ $section };
406 die "no such section ' $section '" if ! $plugin ;
408 my $configid = "section_ $section " ;
409 if ( defined ( $value )) {
410 my $tmp = PMG
:: Config
:: Base-
> check_value ( $section, $key, $value, $section, 0 );
411 print Dumper
( $self ->{ ids
});
412 $self ->{ ids
}->{ $configid } = { type
=> $section } if ! defined ( $self ->{ ids
}->{ $configid });
413 $self ->{ ids
}->{ $configid }->{ $key } = PMG
:: Config
:: Base-
> decode_value ( $section, $key, $tmp );
415 if ( defined ( $self ->{ ids
}->{ $configid })) {
416 delete $self ->{ ids
}->{ $configid }->{ $key };
423 # get section value or default
424 # this does not work for ldap entries
426 my ( $self, $section, $key ) = @_ ;
428 my $pdata = PMG
:: Config
:: Base-
> private ();
429 return undef if ! defined ( $pdata ->{ options
}->{ $section });
430 return undef if ! defined ( $pdata ->{ options
}->{ $section }->{ $key });
431 my $pdesc = $pdata ->{ propertyList
}->{ $key };
432 return undef if ! defined ( $pdesc );
434 my $configid = "section_ $section " ;
435 if ( defined ( $self ->{ ids
}->{ $configid }) &&
436 defined ( my $value = $self ->{ ids
}->{ $configid }->{ $key })) {
440 return $pdesc ->{ default };
443 # get a whole section with default value
444 # this does not work for ldap entries
446 my ( $self, $section ) = @_ ;
448 my $pdata = PMG
:: Config
:: Base-
> private ();
449 return undef if ! defined ( $pdata ->{ options
}->{ $section });
453 foreach my $key ( keys %{ $pdata ->{ options
}->{ $section }}) {
455 my $pdesc = $pdata ->{ propertyList
}->{ $key };
457 my $configid = "section_ $section " ;
458 if ( defined ( $self ->{ ids
}->{ $configid }) &&
459 defined ( my $value = $self ->{ ids
}->{ $configid }->{ $key })) {
460 $res ->{ $key } = $value ;
463 $res ->{ $key } = $pdesc ->{ default };
469 # get a whole config with default values
470 # this does not work for ldap entries
474 my $pdata = PMG
:: Config
:: Base-
> private ();
478 foreach my $type ( keys %{ $pdata ->{ plugins
}}) {
479 next if $type eq 'ldap' ;
480 my $plugin = $pdata ->{ plugins
}->{ $type };
481 $res ->{ $type } = $self -> get_section ( $type );
488 my ( $filename, $fh ) = @_ ;
490 local $/ = undef ; # slurp mode
494 return PMG
:: Config
:: Base-
> parse_config ( $filename, $raw );
498 my ( $filename, $fh, $cfg ) = @_ ;
500 my $raw = PMG
:: Config
:: Base-
> write_config ( $filename, $cfg );
502 PVE
:: Tools
:: safe_print
( $filename, $fh, $raw );
505 PVE
:: INotify
:: register_file
( 'pmg.conf' , "/etc/proxmox/pmg.conf" ,
510 # config file generation using templates
512 sub rewrite_config_file
{
513 my ( $self, $tmplname, $dstfn ) = @_ ;
515 my $demo = $self -> get ( 'admin' , 'demo' );
517 my $srcfn = ( $tmplname =~ m
|^. ?
/|) ?
518 $tmplname : "/var/lib/pmg/templates/ $tmplname " ;
521 my $demosrc = " $srcfn .demo" ;
522 $srcfn = $demosrc if - f
$demosrc ;
525 my $srcfd = IO
:: File-
> new ( $srcfn, "r" )
526 || die "cant read template ' $srcfn ' - $! : ERROR" ;
527 my $dstfd = PMG
:: AtomicFile-
> open ( $dstfn, "w" )
528 || die "cant open config file ' $dstfn ' - $! : ERROR" ;
530 if ( $dstfn eq '/etc/fetchmailrc' ) {
531 my ( $login, $pass, $uid, $gid ) = getpwnam ( 'fetchmail' );
533 chown ( $uid, $gid, ${* $dstfd }{ 'io_atomicfile_temp' });
535 chmod ( 0600 , ${* $dstfd }{ 'io_atomicfile_temp' });
536 } elsif ( $dstfn eq '/etc/clamav/freshclam.conf' ) {
537 # needed if file contains a HTTPProxyPasswort
539 my $uid = getpwnam ( 'clamav' );
540 my $gid = getgrnam ( 'adm' );
543 chown ( $uid, $gid, ${* $dstfd }{ 'io_atomicfile_temp' });
545 chmod ( 0600 , ${* $dstfd }{ 'io_atomicfile_temp' });
548 my $template = Template-
> new ({});
550 my $vars = { pmg
=> $self -> get_config () };
552 $template -> process ( $srcfd, $vars, $dstfd ) ||
553 die $template -> error ();
559 sub rewrite_config_script
{
560 my ( $self, $tmplname, $dstfn ) = @_ ;
562 $self -> rewrite_config_file ( $tmplname, $dstfn );
563 system ( "chmod +x $dstfn " );
566 # rewrite spam configuration
567 sub rewrite_config_spam
{
570 my $use_awl = $self -> get ( 'spam' , 'use_awl' );
571 my $use_bayes = $self -> get ( 'spam' , 'use_bayes' );
572 my $use_razor = $self -> get ( 'spam' , 'use_razor' );
574 # delete AW and bayes databases if those features are disabled
575 unlink '/root/.spamassassin/auto-whitelist' if ! $use_awl ;
577 unlink '/root/.spamassassin/bayes_journal' ;
578 unlink '/root/.spamassassin/bayes_seen' ;
579 unlink '/root/.spamassassin/bayes_toks' ;
582 # make sure we have a custom.cf file (else cluster sync fails)
583 IO
:: File-
> new ( '/etc/mail/spamassassin/custom.cf' , 'a' , 0644 );
585 $self -> rewrite_config_file ( 'local.cf.in' , '/etc/mail/spamassassin/local.cf' );
586 $self -> rewrite_config_file ( 'init.pre.in' , '/etc/mail/spamassassin/init.pre' );
587 $self -> rewrite_config_file ( 'v310.pre.in' , '/etc/mail/spamassassin/v310.pre' );
588 $self -> rewrite_config_file ( 'v320.pre.in' , '/etc/mail/spamassassin/v320.pre' );
591 mkdir "/root/.razor" ;
592 $self -> rewrite_config_file ( 'razor-agent.conf.in' , '/root/.razor/razor-agent.conf' );
593 if (! - e
'/root/.razor/identity' ) {
596 PVE
:: Tools
:: run_command
([ 'razor-admin' , '-discover' ], timeout
=> $timeout );
597 PVE
:: Tools
:: run_command
([ 'razor-admin' , '-register' ], timeout
=> $timeout );
600 syslog
( 'info' , msgquote
( "registering razor failed: $err " )) if $err ;
605 # rewrite ClamAV configuration
606 sub rewrite_config_clam
{
609 $self -> rewrite_config_file ( 'clamd.conf.in' , '/etc/clamav/clamd.conf' );
610 $self -> rewrite_config_file ( 'freshclam.conf.in' , '/etc/clamav/freshclam.conf' );
613 sub rewrite_config_postgres
{
616 my $pgconfdir = "/etc/postgresql/9.6/main" ;
618 $self -> rewrite_config_file ( 'pg_hba.conf.in' , " $pgconfdir/pg_hba .conf" );
619 $self -> rewrite_config_file ( 'postgresql.conf.in' , " $pgconfdir/postgresql .conf" );
622 # rewrite /root/.forward
623 sub rewrite_dot_forward
{
626 my $fname = '/root/.forward' ;
628 my $email = $self -> get ( 'administration' , 'email' );
629 open ( TMP
, "> $fname " );
630 if ( $email && $email =~ m/\s*(\S+)\s*/ ) {
633 # empty .forward does not forward mails (see man local)
641 $self -> rewrite_dot_forward ();
642 $self -> rewrite_config_postgres ();
643 $self -> rewrite_config_spam ();
644 $self -> rewrite_config_clam ();