From: Julien Moutinho Date: Tue, 6 Aug 2013 04:52:38 +0000 (+0200) Subject: Ajout : dovecot-antispam + amavis + crm114. X-Git-Url: https://git.cyclocoop.org/?p=lhc%2Fateliers.git;a=commitdiff_plain;h=b0da1a3b6963f3f6d7611770c8798f8dd7cac7d4 Ajout : dovecot-antispam + amavis + crm114. --- diff --git a/TODO b/TODO index 023a7f8..a2307b8 100644 --- a/TODO +++ b/TODO @@ -4,9 +4,10 @@ - quota : configurer - sftp : configurer - fail2ban : configurer -- agendav/caldavzap + davical - gitolite : rationalisation des adresses de notification dans hooks.mailinglist - ansible ? - varnish ? - munin, monit, check_mk - duplicity/backupninja ? +- mediawiki +- etherpad diff --git a/etc/amavis/15-content_filter_mode b/etc/amavis/15-content_filter_mode new file mode 100644 index 0000000..1d5ffab --- /dev/null +++ b/etc/amavis/15-content_filter_mode @@ -0,0 +1,27 @@ +use strict; + +# You can modify this file to re-enable SPAM checking through spamassassin +# and to re-enable antivirus checking. + +# +# Default antivirus checking mode +# Please note, that anti-virus checking is DISABLED by +# default. +# If You wish to enable it, please uncomment the following lines: + + +#@bypass_virus_checks_maps = ( +# \%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re); + + +# +# Default SPAM checking mode +# Please note, that anti-spam checking is DISABLED by +# default. +# If You wish to enable it, please uncomment the following lines: + + +@bypass_spam_checks_maps = ( + \%bypass_spam_checks, \@bypass_spam_checks_acl, \$bypass_spam_checks_re); + +1; # ensure a defined return diff --git a/etc/amavis/15-spam_scanners b/etc/amavis/15-spam_scanners new file mode 100644 index 0000000..38ebabe --- /dev/null +++ b/etc/amavis/15-spam_scanners @@ -0,0 +1,11 @@ +use strict; + +@spam_scanners = ( + #['SpamAssassin', 'Amavis::SpamControl::SpamAssassin' ], + ['CRM114', 'Amavis::SpamControl::ExtProg', 'crm', + [ qw(-u /home/mail/crm114 /usr/share/crm114/mailfilter.crm --stats_only) ], + mail_body_size_limit => 64000, score_factor => -0.20, + ], + ); + +1; # ensure a defined return diff --git a/etc/amavis/50-user b/etc/amavis/50-user new file mode 100644 index 0000000..dda0048 --- /dev/null +++ b/etc/amavis/50-user @@ -0,0 +1,51 @@ +use strict; + +## GENERAL +@local_domains_acl = + ( ".heureux-cyclage.org" + , ".cyclocoop.org" + ); +$max_servers = 2; + +## LOGGING AND DEBUGGING +$log_level = 1; +# $logfile = undef; +$do_syslog = 1; +$syslog_ident = 'amavis'; +$syslog_facility = 'mail'; +# $logline_maxlen = 980; + +# $log_short_templ ... built-in default at the end of file amavisd +# $log_verbose_templ ... built-in default at the end of file amavisd +# $log_recip_templ = ... built-in default at the end of file amavisd +# $log_templ = $log_short_templ; + +## MTA INTERFACE - INPUT +$protocol = 'LMTP'; +@inet_acl = qw( 127.0.0.1 ); +$inet_socket_port = 10024; + +## MTA INTERFACE - OUTPUT +$notify_method = 'smtp:[127.0.0.1]:10025'; +$forward_method = 'smtp:[127.0.0.1]:10025'; + +## MODIFICATIONS TO PASSED MAIL +#$prefer_our_added_header_fields{lc('X-CRM114-CacheID')} = 0; +#$allowed_added_header_fields{lc('X-CRM114-CacheID')} = 1; + +## ANTI-Spam CONTROLS +$sa_mail_body_size_limit = 400*1024; +$sa_local_tests_only = 1; +# $sa_spawned = 0; +# $dspam = undef; +# $sa_timeout = 30; + +$sa_tag_level_deflt = -999; # add spam info headers if at, or above that level +$sa_tag2_level_deflt = 6.2; # add 'spam detected' headers at that level +#$sa_tag3_level_deflt = undef; +$sa_kill_level_deflt = 6.9; # triggers spam evasive actions (e.g. blocks mail) +$sa_dsn_cutoff_level = 10; # spam level beyond which a DSN is not sent +# $sa_quarantine_cutoff_level = 25; # spam level beyond which quarantine is off + +#------------ Do not modify anything below this line ------------- +1; # ensure a defined return diff --git a/etc/crm114/blacklist.mfp b/etc/crm114/blacklist.mfp new file mode 100644 index 0000000..e69de29 diff --git a/etc/crm114/mailfilter.cf b/etc/crm114/mailfilter.cf new file mode 100644 index 0000000..43f4c86 --- /dev/null +++ b/etc/crm114/mailfilter.cf @@ -0,0 +1,39 @@ +:accepted_mail_exit_code: /0/ +:add_extra_stuff: /no/ +:add_headers: /yes/ +:add_mailtrainer_report: /yes/ +:add_verbose_stats: /yes/ +:automatic_training: /no/ +:cache_dupe_command: /\/bin\/ln/ +:clf: /osb unique microgroom/ +:confirm_flag_subject_string: /TCF:/ +:decision_length: /16000/ +:do_base64: /yes/ +:expand_urls: /no/ +:general_fails_to: // +:good_flag_subject_string: // +:good_threshold: /8.0/ +:inoculations_enabled: /no/ +:lcr: /[[:graph:]]+/ +:log_all_mail_to_file: // +:log_rejections: /no/ +:log_rejections_to_file: // +:log_to_allmail.txt: /no/ +:mail_separator: /\n-=-=-=-=-=-=- cut here -=-=-=-=-=-=-\n/ +:mime_decoder: /base64 -d/ +:program_fault_exit_code: /1/ +:rejected_mail_exit_code: /0/ +:rewrites_enabled: /yes/ +:spam_flag_subject_string: /*** SPAM ***/ +:spam_threshold: /-8.0/ +:spw: /DEFAULT_PASSWORD/ +:text_cache: // +:thick_threshold: /8.0/ +:trainer_invoke_command: /\/usr\/share\/crm114\/mailtrainer.crm/ +:trainer_randomizer_command: /\/usr\/share\/crm114\/shuffle.crm/ +:undo_interruptus: /no/ +:unsure_flag_subject_string: /*** UNSURE ***/ +:unsure_mail_exit_code: /0/ +:url_fetch_cmd: /wget -T 30 -O - / +:url_trim_cmd: / head -c 16000 / +:verbose_startup: // diff --git a/etc/crm114/priolist.mfp b/etc/crm114/priolist.mfp new file mode 100644 index 0000000..e69de29 diff --git a/etc/crm114/rewrites.mfp b/etc/crm114/rewrites.mfp new file mode 100644 index 0000000..ba27334 --- /dev/null +++ b/etc/crm114/rewrites.mfp @@ -0,0 +1,4 @@ +[^< @]+?@(dovecot\.)?heureux-cyclage\.org>->MyEmailAddress +[^< @]+?@(dovecot\.)?cyclocoop\.org>->MyEmailAddress +ateliers\.heureux-cyclage\.org>->MyLocalMailRouter +91\.216\.110\.42>->MyLocalMailRouterIP diff --git a/etc/crm114/whitelist.mfp b/etc/crm114/whitelist.mfp new file mode 100644 index 0000000..e69de29 diff --git a/etc/dovecot/dovecot-antispam-call-backend-pipe-unlearn.patch b/etc/dovecot/dovecot-antispam-call-backend-pipe-unlearn.patch new file mode 100644 index 0000000..6ffdcd2 --- /dev/null +++ b/etc/dovecot/dovecot-antispam-call-backend-pipe-unlearn.patch @@ -0,0 +1,186 @@ +diff -u b/dovecot-antispam-2.0+20120225/antispam-plugin.h c/dovecot-antispam-2.0+20120225/antispam-plugin.h +--- b/dovecot-antispam-2.0+20120225/antispam-plugin.h 2013-07-30 05:22:21.248730740 +0200 ++++ c/dovecot-antispam-2.0+20120225/antispam-plugin.h 2013-08-05 05:50:13.430597556 +0200 +@@ -30,6 +30,8 @@ + CLASS_UNSURE, + CLASS_NOTSPAM, + CLASS_SPAM, ++ CLASS_UNSPAM, ++ CLASS_UNNOTSPAM, + }; + + enum antispam_debug_target { +@@ -104,6 +106,10 @@ + int spam_args_num; + char **ham_args; + int ham_args_num; ++ char **unlearn_spam_args; ++ int unlearn_spam_args_num; ++ char **unlearn_ham_args; ++ int unlearn_ham_args_num; + const char *pipe_binary;// = "/usr/sbin/sendmail"; + const char *tmpdir;// = "/tmp"; + char **extra_args; +diff -u b/dovecot-antispam-2.0+20120225/antispam-storage-2.0.c c/dovecot-antispam-2.0+20120225/antispam-storage-2.0.c +--- b/dovecot-antispam-2.0+20120225/antispam-storage-2.0.c 2013-07-31 14:52:43.277922438 +0200 ++++ c/dovecot-antispam-2.0+20120225/antispam-storage-2.0.c 2013-08-05 07:51:45.235555750 +0200 +@@ -327,7 +327,11 @@ + } + } + +- debug(&amail->cfg->dbgcfg, "keyword list:\n"); ++ debug(&amail->cfg->dbgcfg, "keyword list: modify_type=%s\n" ++ , modify_type == MODIFY_ADD ? "MODIFY_ADD" ++ : modify_type == MODIFY_REPLACE ? "MODIFY_REPLACE" ++ : modify_type == MODIFY_REMOVE ? "MODIFY_REMOVE" ++ : "ERROR"); + + for (i = 0; i < keywords->count; i++) { + unsigned int idx = keywords->idx[i]; +@@ -346,28 +350,34 @@ + break; + case MODIFY_REMOVE: + if (keyword_is_spam(amail->cfg, keyword_names[idx])) +- spam_class = CLASS_NOTSPAM; ++ spam_class = previous_spam_keyword ? CLASS_UNSPAM : CLASS_UNSURE; + if (keyword_is_ham(amail->cfg, keyword_names[idx])) +- spam_class = CLASS_SPAM; ++ spam_class = previous_ham_keyword ? CLASS_UNNOTSPAM : CLASS_UNSURE; + break; + default: + i_assert(0); + } + } + +- debug(&amail->cfg->dbgcfg, "spam_class=%d previous_spam_keyword=%d previous_ham_keyword=%d\n", +- spam_class, previous_spam_keyword, previous_ham_keyword); ++ debug(&amail->cfg->dbgcfg, "spam_class=%s previous_spam_keyword=%d previous_ham_keyword=%d\n" ++ , spam_class == CLASS_UNSURE ? "CLASS_UNSURE" ++ : spam_class == CLASS_SPAM ? "CLASS_SPAM" ++ : spam_class == CLASS_NOTSPAM ? "CLASS_NOTSPAM" ++ : spam_class == CLASS_UNSPAM ? "CLASS_UNSPAM" ++ : spam_class == CLASS_UNNOTSPAM ? "CLASS_UNNOTSPAM" ++ : "ERROR" ++ , previous_spam_keyword, previous_ham_keyword); + + amail->module_ctx.super.update_keywords(mail, modify_type, keywords); + +- if (previous_spam_keyword && previous_ham_keyword) { +- /* NOTE: avoid to call the backend two times for the same change +- * once when adding one spam or ham keyword +- * and once when removing the other. +- */ +- debug(&amail->cfg->dbgcfg, "does not run backend a second time\n"); +- return; +- } ++ //if (previous_spam_keyword && previous_ham_keyword) { ++ // /* NOTE: avoid to call the backend two times for the same change ++ // * once when adding one spam or ham keyword ++ // * and once when removing the other. ++ // */ ++ // debug(&amail->cfg->dbgcfg, "does not run backend a second time\n"); ++ // return; ++ // } + + if (spam_class != CLASS_UNSURE) { + /* NOTE: on error, backend uses mail_storage_set_error() +Les sous-répertoires b/dovecot-antispam-2.0+20120225/debian et c/dovecot-antispam-2.0+20120225/debian sont identiques +Les sous-répertoires b/dovecot-antispam-2.0+20120225/.pc et c/dovecot-antispam-2.0+20120225/.pc sont identiques +diff -u b/dovecot-antispam-2.0+20120225/pipe.c c/dovecot-antispam-2.0+20120225/pipe.c +--- b/dovecot-antispam-2.0+20120225/pipe.c 2013-07-31 14:16:12.164255967 +0200 ++++ c/dovecot-antispam-2.0+20120225/pipe.c 2013-08-05 06:12:36.137800536 +0200 +@@ -46,7 +46,15 @@ + break; + case CLASS_NOTSPAM: + dest = cfg->pipe.ham_args; +- dest_num = cfg->pipe.spam_args_num; ++ dest_num = cfg->pipe.ham_args_num; ++ break; ++ case CLASS_UNSPAM: ++ dest = cfg->pipe.unlearn_spam_args; ++ dest_num = cfg->pipe.unlearn_spam_args_num; ++ break; ++ case CLASS_UNNOTSPAM: ++ dest = cfg->pipe.unlearn_ham_args; ++ dest_num = cfg->pipe.unlearn_ham_args_num; + break; + default: + i_assert(0); +@@ -55,13 +63,13 @@ + if (!dest) + return -1; + ++ debug(&cfg->dbgcfg, "running mailtrain backend program %s", cfg->pipe.pipe_binary); ++ + pid = fork(); + + if (pid == -1) + return -1; + +- debug(&cfg->dbgcfg, "running mailtrain backend program %s", cfg->pipe.pipe_binary); +- + if (pid) { + if (waitpid(pid, &status, 0) == -1) + return -1; +@@ -238,7 +246,7 @@ + return -1; + } + +- if (!cfg->pipe.ham_args || !cfg->pipe.spam_args) { ++ if (!cfg->pipe.ham_args || !cfg->pipe.spam_args || !cfg->pipe.unlearn_ham_args || !cfg->pipe.unlearn_spam_args) { + mail_storage_set_error(t->box->storage, + ME(NOTPOSSIBLE) + "antispam plugin not configured"); +@@ -371,6 +379,52 @@ + tmp = NULL; + } + } ++ ++ tmp = getenv("PIPE_PROGRAM_UNLEARN_SPAM_ARGS", getenv_data); ++ if (tmp) { ++ cfg->pipe.unlearn_spam_args = p_strsplit(cfg->mem_pool, tmp, ";"); ++ cfg->pipe.unlearn_spam_args_num = str_array_length( ++ (const char *const *)cfg->pipe.unlearn_spam_args); ++ for (i = 0; i < cfg->pipe.unlearn_spam_args_num; i++) ++ debug(&cfg->dbgcfg, "pipe backend unlearn spam arg[%d] = %s\n", ++ i, cfg->pipe.unlearn_spam_args[i]); ++ } else { ++ tmp = getenv("PIPE_PROGRAM_UNLEARN_SPAM_ARG", getenv_data); ++ if (!tmp) ++ tmp = getenv("MAIL_UNLEARN_SPAM", getenv_data); ++ if (tmp) { ++ /* bit of a hack */ ++ cfg->pipe.unlearn_spam_args = ++ p_strsplit(cfg->mem_pool, tmp, "\x01"); ++ cfg->pipe.unlearn_spam_args_num = 1; ++ debug(&cfg->dbgcfg, ++ "pipe backend unlearn spam argument = %s\n", tmp); ++ tmp = NULL; ++ } ++ } ++ ++ tmp = getenv("PIPE_PROGRAM_UNLEARN_NOTSPAM_ARGS", getenv_data); ++ if (tmp) { ++ cfg->pipe.unlearn_ham_args = p_strsplit(cfg->mem_pool, tmp, ";"); ++ cfg->pipe.unlearn_ham_args_num = str_array_length( ++ (const char *const *)cfg->pipe.unlearn_ham_args); ++ for (i = 0; i < cfg->pipe.unlearn_ham_args_num; i++) ++ debug(&cfg->dbgcfg, "pipe backend unlearn not-spam arg[%d] = %s\n", ++ i, cfg->pipe.unlearn_ham_args[i]); ++ } else { ++ tmp = getenv("PIPE_PROGRAM_UNLEARN_NOTSPAM_ARG", getenv_data); ++ if (!tmp) ++ tmp = getenv("MAIL_UNLEARN_NOTSPAM", getenv_data); ++ if (tmp) { ++ /* bit of a hack */ ++ cfg->pipe.unlearn_ham_args = ++ p_strsplit(cfg->mem_pool, tmp, "\x01"); ++ cfg->pipe.unlearn_ham_args_num = 1; ++ debug(&cfg->dbgcfg, ++ "pipe backend unlearn not-spam argument = %s\n", tmp); ++ tmp = NULL; ++ } ++ } + + tmp = getenv("PIPE_PROGRAM", getenv_data); + if (!tmp) diff --git a/etc/dovecot/dovecot-antispam-call-backend-with-imap-keywords.patch b/etc/dovecot/dovecot-antispam-call-backend-with-imap-keywords.patch new file mode 100644 index 0000000..11a7bce --- /dev/null +++ b/etc/dovecot/dovecot-antispam-call-backend-with-imap-keywords.patch @@ -0,0 +1,215 @@ +diff -ru a/dovecot-antispam-2.0+20120225/antispam-plugin.c b/dovecot-antispam-2.0+20120225/antispam-plugin.c +--- a/dovecot-antispam-2.0+20120225/antispam-plugin.c 2012-02-24 20:22:48.000000000 +0100 ++++ b/dovecot-antispam-2.0+20120225/antispam-plugin.c 2013-07-29 07:14:51.962245023 +0200 +@@ -246,6 +246,21 @@ + + return FALSE; + } ++bool keyword_is_ham(const struct antispam_config *cfg, const char *keyword) ++{ ++ char **k = cfg->ham_keywords; ++ ++ if (!cfg->ham_keywords) ++ return FALSE; ++ ++ while (*k) { ++ if (strcmp(*k, keyword) == 0) ++ return TRUE; ++ k++; ++ } ++ ++ return FALSE; ++} + + static int parse_folder_setting(const struct antispam_config *cfg, + const char *setting, char ***strings, +@@ -335,6 +350,17 @@ + iter++; + } + } ++ tmp = getenv("HAM_KEYWORDS", getenv_data); ++ if (tmp) ++ cfg->ham_keywords = p_strsplit(cfg->mem_pool, tmp, ";"); ++ ++ if (cfg->ham_keywords) { ++ iter = cfg->ham_keywords; ++ while (*iter) { ++ debug(&cfg->dbgcfg, "\"%s\" is ham keyword\n", *iter); ++ iter++; ++ } ++ } + + tmp = getenv("BACKEND", getenv_data); + if (tmp) { +diff -ru a/dovecot-antispam-2.0+20120225/antispam-plugin.h b/dovecot-antispam-2.0+20120225/antispam-plugin.h +--- a/dovecot-antispam-2.0+20120225/antispam-plugin.h 2013-07-31 12:45:33.000000000 +0200 ++++ b/dovecot-antispam-2.0+20120225/antispam-plugin.h 2013-07-30 05:22:21.248730740 +0200 +@@ -27,6 +27,7 @@ + struct antispam_transaction_context; + + enum classification { ++ CLASS_UNSURE, + CLASS_NOTSPAM, + CLASS_SPAM, + }; +@@ -72,6 +73,7 @@ + char **unsure_folders[3]; // = { NULL, NULL, NULL }; + + char **spam_keywords; ++ char **ham_keywords; + + const char *signature_hdr; + +@@ -178,6 +180,7 @@ + bool mailbox_is_trash(const struct antispam_config *cfg, struct mailbox *box); + bool mailbox_is_unsure(const struct antispam_config *cfg, struct mailbox *box); + bool keyword_is_spam(const struct antispam_config *cfg, const char *keyword); ++bool keyword_is_ham(const struct antispam_config *cfg, const char *keyword); + + struct antispam_config * + antispam_setup_config(const char *(getenv)(const char *env, void *data), +diff -ru a/dovecot-antispam-2.0+20120225/antispam-storage-2.0.c b/dovecot-antispam-2.0+20120225/antispam-storage-2.0.c +--- a/dovecot-antispam-2.0+20120225/antispam-storage-2.0.c 2012-02-24 20:22:48.000000000 +0100 ++++ b/dovecot-antispam-2.0+20120225/antispam-storage-2.0.c 2013-07-31 14:52:43.277922438 +0200 +@@ -310,21 +310,9 @@ + const ARRAY_TYPE(keywords) *idxkwd = mail_index_get_keywords(keywords->index); + const char *const *keyword_names = array_get(idxkwd, &numkwds); + const char *const *orig_keywords; +- bool previous_spam_keyword, now_spam_keyword; +- +- switch (modify_type) { +- case MODIFY_ADD: +- debug(&amail->cfg->dbgcfg, "adding keyword(s)\n"); +- break; +- case MODIFY_REMOVE: +- debug(&amail->cfg->dbgcfg, "removing keyword(s)\n"); +- break; +- case MODIFY_REPLACE: +- debug(&amail->cfg->dbgcfg, "replacing keyword(s)\n"); +- break; +- default: +- i_assert(0); +- } ++ bool previous_spam_keyword = FALSE, previous_ham_keyword = FALSE; ++ enum classification spam_class = CLASS_UNSURE; ++ struct antispam_transaction_context *ast; + + orig_keywords = pmail->v.get_keywords(mail); + if (orig_keywords) { +@@ -333,6 +321,8 @@ + debug(&amail->cfg->dbgcfg, " * %s\n", *orig_keywords); + if (keyword_is_spam(amail->cfg, *orig_keywords)) + previous_spam_keyword = TRUE; ++ if (keyword_is_ham(amail->cfg, *orig_keywords)) ++ previous_ham_keyword = TRUE; + orig_keywords++; + } + } +@@ -350,29 +340,47 @@ + case MODIFY_ADD: + case MODIFY_REPLACE: + if (keyword_is_spam(amail->cfg, keyword_names[idx])) +- now_spam_keyword = TRUE; ++ spam_class = CLASS_SPAM; ++ if (keyword_is_ham(amail->cfg, keyword_names[idx])) ++ spam_class = CLASS_NOTSPAM; + break; + case MODIFY_REMOVE: + if (keyword_is_spam(amail->cfg, keyword_names[idx])) +- now_spam_keyword = FALSE; ++ spam_class = CLASS_NOTSPAM; ++ if (keyword_is_ham(amail->cfg, keyword_names[idx])) ++ spam_class = CLASS_SPAM; + break; + default: + i_assert(0); + } + } +- ++ ++ debug(&amail->cfg->dbgcfg, "spam_class=%d previous_spam_keyword=%d previous_ham_keyword=%d\n", ++ spam_class, previous_spam_keyword, previous_ham_keyword); ++ + amail->module_ctx.super.update_keywords(mail, modify_type, keywords); +- +- debug(&amail->cfg->dbgcfg, "previous-spam, now-spam: %d, %d\n", +- previous_spam_keyword, now_spam_keyword); +- +- if (previous_spam_keyword != now_spam_keyword) { +- /* +- * Call backend here. +- * +- * TODO: It is not clear how to roll back the +- * keyword change if the backend fails. ++ ++ if (previous_spam_keyword && previous_ham_keyword) { ++ /* NOTE: avoid to call the backend two times for the same change ++ * once when adding one spam or ham keyword ++ * and once when removing the other. ++ */ ++ debug(&amail->cfg->dbgcfg, "does not run backend a second time\n"); ++ return; ++ } ++ ++ if (spam_class != CLASS_UNSURE) { ++ /* NOTE: on error, backend uses mail_storage_set_error() ++ * which is checked in commit() where a rollback() can be done. + */ ++ debug(&amail->cfg->dbgcfg, "call backend->start()\n"); ++ ast = amail->cfg->backend->start(amail->cfg, mail->transaction->box); ++ i_assert(ast != NULL); ++ debug(&amail->cfg->dbgcfg, "call backend->handle_mail()\n"); ++ if (!amail->cfg->backend->handle_mail(amail->cfg, mail->transaction, ast, mail, spam_class)) { ++ debug(&amail->cfg->dbgcfg, "call backend->commit()\n"); ++ amail->cfg->backend->commit(amail->cfg, mail->transaction, ast); ++ } + } + } + +@@ -401,7 +409,9 @@ + struct antispam_mailbox *asbox = ANTISPAM_CONTEXT(ctx->box); + struct antispam_internal_context *ast = ANTISPAM_CONTEXT(ctx); + +- if (antispam_transaction_commit(asbox->cfg, ctx, &ast->backendctx) < 0) { ++ if ((ctx->box->storage->error != MAIL_ERROR_NONE) ++ || antispam_transaction_commit(asbox->cfg, ctx, &ast->backendctx) < 0) { ++ debug(&asbox->cfg->dbgcfg, "transaction rollback\n"); + if (ast->mail) + mail_free(&ast->mail); + +diff -ru a/dovecot-antispam-2.0+20120225/crm114-exec.c b/dovecot-antispam-2.0+20120225/crm114-exec.c +--- a/dovecot-antispam-2.0+20120225/crm114-exec.c 2012-02-24 20:22:48.000000000 +0100 ++++ b/dovecot-antispam-2.0+20120225/crm114-exec.c 2013-07-30 06:00:16.266596502 +0200 +@@ -43,6 +43,8 @@ + case CLASS_SPAM: + class_arg = "--spam"; + break; ++ default: ++ i_assert(0); + } + + /* +diff -ru a/dovecot-antispam-2.0+20120225/dspam-exec.c b/dovecot-antispam-2.0+20120225/dspam-exec.c +--- a/dovecot-antispam-2.0+20120225/dspam-exec.c 2012-02-24 20:22:48.000000000 +0100 ++++ b/dovecot-antispam-2.0+20120225/dspam-exec.c 2013-07-31 13:28:39.217464532 +0200 +@@ -45,6 +45,8 @@ + case CLASS_SPAM: + class_arg = t_strconcat("--class=", "spam", NULL); + break; ++ default: ++ i_assert(0); + } + + /* +diff -ru a/dovecot-antispam-2.0+20120225/pipe.c b/dovecot-antispam-2.0+20120225/pipe.c +--- a/dovecot-antispam-2.0+20120225/pipe.c 2012-02-24 20:22:48.000000000 +0100 ++++ b/dovecot-antispam-2.0+20120225/pipe.c 2013-07-31 14:16:12.164255967 +0200 +@@ -48,6 +48,8 @@ + dest = cfg->pipe.ham_args; + dest_num = cfg->pipe.spam_args_num; + break; ++ default: ++ i_assert(0); + } + + if (!dest) diff --git a/etc/dovecot/dovecot.conf.m4 b/etc/dovecot/dovecot.conf.m4 index 0ecacf5..63604fa 100644 --- a/etc/dovecot/dovecot.conf.m4 +++ b/etc/dovecot/dovecot.conf.m4 @@ -44,14 +44,14 @@ namespace inbox { special_use = \Trash } prefix = - separator = . + separator = + } namespace { #list = children list = yes location = maildir:/home/mail/data/%%d/%%n/Maildir:INDEX=/var/lib/dovecot-index/%d/%n/Shared/%%n:CONTROL=/var/lib/dovecot-control/%d/%n/Shared/%%n - prefix = Shared.%%n. - separator = . + prefix = Partages+%%n+ + separator = + subscriptions = yes type = shared } @@ -64,21 +64,49 @@ passdb { } plugin { acl = vfile:/etc/dovecot/acl/global.d + acl_anyone = allow acl_shared_dict = file:/home/mail/acl/%d/shared.db + #antispam_allow_append_to_spam = yes + # NOTE: pour offlineimap + antispam_backend = pipe + #antispam_crm_args = -u;/home/mail/data/%d/.crm114;/usr/share/crm114/mailfilter.crm + antispam_crm_args = -u;/home/mail/crm114;/usr/share/crm114/mailfilter.crm + antispam_crm_binary = /usr/bin/crm + antispam_debug_target = syslog + #antispam_crm_env = HOME=%h;USER=%u + antispam_ham_keywords = NonJunk + antispam_pipe_program = /usr/bin/crm + antispam_pipe_program_args = -u;/home/mail/crm114;/usr/share/crm114/mailfilter.crm;--stats_only;--force + antispam_pipe_program_notspam_arg = --learnnonspam + antispam_pipe_program_spam_arg = --learnspam + antispam_pipe_program_unlearn_spam_args = --unlearn;--learnspam + antispam_pipe_program_unlearn_notspam_args = --unlearn;--learnnonspam + antispam_pipe_tmpdir = /home/mail/crm114/tmp + antispam_signature = X-CRM114-CacheID + antispam_signature_missing = move + antispam_spam = Junk + antispam_spam_keywords = Junk + antispam_trash = Trash + antispam_unsure = Unsure + antispam_verbose_debug = 0 quota = fs:user recipient_delimiter = + sieve = /home/mail/data/%d/%n/sieve sieve_after = /etc/dovecot/sieve/after.d/ sieve_before = /etc/dovecot/sieve/before.d/ sieve_dir = /home/mail/data/%d/%n/sieve.d/ + #sieve_extensions = +spamtest +spamtestplus sieve_global_dir = /etc/dovecot/sieve/global.d/ sieve_max_script_size = 1M sieve_quota_max_scripts = 0 sieve_quota_max_storage = 10M + sieve_spamtest_max_value = 10 + sieve_spamtest_status_header = X-Spam-Score + sieve_spamtest_status_type = strlen sieve_user_log = /home/mail/log/%d/sieve.%n.log } protocol imap { - mail_plugins = $mail_plugins imap_acl imap_quota + mail_plugins = $mail_plugins antispam imap_acl imap_quota } service imap-login { inet_listener imap { diff --git a/etc/dovecot/sieve/global.d/spam.sieve b/etc/dovecot/sieve/global.d/spam.sieve new file mode 100644 index 0000000..85f8120 --- /dev/null +++ b/etc/dovecot/sieve/global.d/spam.sieve @@ -0,0 +1,7 @@ +require + [ "imap4flags" + ]; + +if header :contains "X-Spam-Level" "***" { + addflag "Junk"; + } diff --git a/etc/dovecot/sieve/user.sieve b/etc/dovecot/sieve/user.sieve index 87f46ae..7079a2e 100644 --- a/etc/dovecot/sieve/user.sieve +++ b/etc/dovecot/sieve/user.sieve @@ -1,5 +1,6 @@ require ["include"]; include :personal "roundcube"; +include :global "spam"; include :global "list"; include :global "extension"; diff --git a/etc/gitolite b/etc/gitolite index 5a6ef35..2aa4132 160000 --- a/etc/gitolite +++ b/etc/gitolite @@ -1 +1 @@ -Subproject commit 5a6ef35f70571437f95c1e8be4ce46db1b3a3f72 +Subproject commit 2aa41322b16c1c1c1445726d6d6a6cc7affac1c2 diff --git a/etc/gitweb/lhc.home_text.html b/etc/gitweb/lhc.home_text.html index b0ed03f..58634c4 100644 --- a/etc/gitweb/lhc.home_text.html +++ b/etc/gitweb/lhc.home_text.html @@ -1,3 +1,3 @@

Forge logicielle privée de l'Heureux Cyclage

Pour récupérer un dépôt privé :

-
git clone git@git.heureux-cyclage.org/<projet>
+
git clone git@git.heureux-cyclage.org/<dépôt>
diff --git a/etc/postfix/master.cf b/etc/postfix/master.cf index 604f9fe..f004633 100644 --- a/etc/postfix/master.cf +++ b/etc/postfix/master.cf @@ -6,9 +6,42 @@ # (yes) (yes) (yes) (never) (100) # ========================================================================== smtp inet n - - - - smtpd + -o cleanup_service_name=pre-cleanup + -o content_filter=amavis:[127.0.0.1]:10024 + -o smtpd_sender_restrictions=reject_unauth_pipelining,reject_non_fqdn_sender,permit + -o receive_override_options=no_address_mappings +amavis unix - - n - 2 lmtp + -o lmtp_data_done_timeout=1200 + -o lmtp_send_xforward_command=yes + -o lmtp_tls_note_starttls_offer=no +127.0.0.1:10025 inet n - n - - smtpd + -o content_filter= + -o local_header_rewrite_clients= + -o local_recipient_maps= + -o mynetworks=127.0.0.0/8 + -o receive_override_options=no_header_body_checks,no_milters,no_unknown_recipient_checks + -o relay_recipient_maps= + -o smtpd_client_connection_count_limit=0 + -o smtpd_client_connection_rate_limit=0 + -o smtpd_client_restrictions=permit_mynetworks,reject + -o smtpd_data_restrictions=reject_unauth_pipelining + -o smtpd_delay_reject=no + -o smtpd_end_of_data_restrictions= + -o smtpd_error_sleep_time=0 + -o smtpd_hard_error_limit=1000 + -o smtpd_helo_restrictions= + -o smtpd_milters= + -o smtpd_recipient_restrictions=permit_mynetworks,reject + -o smtpd_restriction_classes= + -o smtpd_sender_restrictions= + -o smtpd_soft_error_limit=1001 + -o strict_rfc821_envelopes=yes submission inet n - - - - smtpd + -o cleanup_service_name=pre-cleanup + -o content_filter=amavis:[127.0.0.1]:10024 -o milter_macro_daemon_name=ORIGINATING - -o smtpd_sasl_auth_enable=yes + -o receive_override_options=no_address_mappings + -o smtpd_sender_restrictions=permit_tls_clientcerts,reject -o smtpd_tls_ask_ccert=yes -o smtpd_tls_auth_only=yes -o smtpd_tls_ccert_verifydepth=2 @@ -28,7 +61,14 @@ smtps inet n - - - - smtpd -o smtpd_tls_wrappermode=yes #628 inet n - - - - qmqpd pickup fifo n - - 60 1 pickup + #-o cleanup_service_name=pre-cleanup +pre-cleanup unix n - - - 0 cleanup + -o virtual_alias_maps= cleanup unix n - - - 0 cleanup + -o mime_header_checks= + -o nested_header_checks= + -o body_checks= + -o header_checks= qmgr fifo n - n 300 1 qmgr #qmgr fifo n - - 300 1 oqmgr tlsmgr unix - - - 1000? 1 tlsmgr diff --git a/etc/roundcube/main.inc.php b/etc/roundcube/main.inc.php index aa38b8f..f71f883 100644 --- a/etc/roundcube/main.inc.php +++ b/etc/roundcube/main.inc.php @@ -215,10 +215,6 @@ $rcmail_config['auto_create_user'] = true; // replace Roundcube logo with this image // specify an URL relative to the document root of this Roundcube installation -$http_host=$_SERVER['HTTP_HOST']; -if (substr($http_host, 0, strlen("roundcube.")) == "roundcube.") { - $http_host = substr($http_host, strlen("roundcube.")); - } if (file_exists("/home/www/pub/roundcube/images/logo-$http_host.png")) { $rcmail_config['skin_logo'] = "./images/logo-$http_host.png"; } @@ -380,10 +376,17 @@ $rcmail_config['plugins'] = array( 'password', 'userinfo', #'hide_blockquote', - 'markasjunk', + #'markasjunk2', 'managesieve', + 'chbox', + #'markasjunk', + 'junk_keyword', + #'message_label', + #'all_folder_search', 'show_additional_headers', #'subscriptions_option', + 'threading_as_default', + 'thunderbird_labels', ); // ---------------------------------- @@ -552,7 +555,7 @@ $rcmail_config['message_sort_order'] = 'DESC'; // These cols are shown in the message list. Available cols are: // subject, from, to, cc, replyto, date, size, status, flag, attachment, 'priority' -$rcmail_config['list_cols'] = array('subject', 'status', 'from', 'date', 'size', 'flag', 'attachment'); +$rcmail_config['list_cols'] = array('subject', 'status', 'junk_keyword', 'from', 'date', 'size', 'flag', 'attachment'); // the default locale setting (leave empty for auto-detection) // RFC1766 formatted language name like en_US, de_DE, de_CH, fr_FR, pt_BR @@ -857,23 +860,23 @@ $rcmail_config['timezone'] = 'auto'; $rcmail_config['dst_active'] = null; // prefer displaying HTML messages -$rcmail_config['prefer_html'] = true; +$rcmail_config['prefer_html'] = false; // display remote inline images // 0 - Never, always ask // 1 - Ask if sender is not in address book // 2 - Always show inline images -$rcmail_config['show_images'] = 0; +$rcmail_config['show_images'] = 1; // compose html formatted messages by default // 0 - never, 1 - always, 2 - on reply to HTML message only -$rcmail_config['htmleditor'] = 2; +$rcmail_config['htmleditor'] = 0; // show pretty dates as standard $rcmail_config['prettydate'] = true; // save compose message every 300 seconds (5min) -$rcmail_config['draft_autosave'] = 300; +$rcmail_config['draft_autosave'] = 60; // default setting if preview pane is enabled $rcmail_config['preview_pane'] = true; diff --git a/etc/sv/amavis/local.sh b/etc/sv/amavis/local.sh new file mode 100644 index 0000000..5bef19e --- /dev/null +++ b/etc/sv/amavis/local.sh @@ -0,0 +1,27 @@ +"$tool"/local/apt-get-install amavisd-new crm114 +"$tool"/local/insserv-remove amavis + +sudo find "$tool"/etc/amavis -maxdepth 1 -type f -exec \ + install -t /etc/amavis/conf.d -o root -g root -m 664 {} + + +sudo install -d -o root -g root -m 755 \ + /etc/crm114 +sudo find "$tool"/etc/crm114 -maxdepth 1 -type f -exec \ + install -t /etc/crm114 -o root -g root -m 664 {} + + +sudo install -d -o amavis -g amavis -m 2771 \ + ~mail/crm114 +sudo install -d -o amavis -g amavis -m 1777 \ + ~mail/crm114/tmp + +for css in spam notspam + do + sudo -u amavis cssutil -b -r ~mail/crm114/"$css".css + sudo chmod 660 ~mail/crm114/"$css".css + done + +sudo find /etc/crm114 -maxdepth 1 -type f -exec \ + ln -fns -t ~mail/crm114 -o root -g root -m 664 {} + + +sudo ln -fns /dev/null ~mail/crm114/spamtext.txt +sudo ln -fns /dev/null ~mail/crm114/nonspamtext.txt diff --git a/etc/sv/amavis/run b/etc/sv/amavis/run new file mode 100755 index 0000000..2f274c1 --- /dev/null +++ b/etc/sv/amavis/run @@ -0,0 +1,17 @@ +#!/bin/sh -eux +exec 2>&1 +sv=${PWD#/etc/sv/} + +for dir in \ + /var/lib/amavis \ + /var/lib/amavis/tmp + do + if test -d "$dir" + then find "$dir" -maxdepth 1 -name 'amavis-*' -type d -exec rm -rf {} + + fi + done + +exec /usr/bin/chpst \ + -u "$sv":"$sv" \ + /usr/sbin/amavisd-new \ + foreground diff --git a/etc/sv/postfix/run b/etc/sv/postfix/run index cfc8966..ad5590f 100755 --- a/etc/sv/postfix/run +++ b/etc/sv/postfix/run @@ -2,6 +2,7 @@ exec 2>&1 sv=${PWD#/etc/sv/} /usr/bin/sv -w 3 start postgrey +/usr/bin/sv -w 3 start amavis command_directory=/usr/sbin \ config_directory=/etc/postfix \ diff --git a/etc/vim/vimrc b/etc/vim/vimrc new file mode 100644 index 0000000..7bff4c8 --- /dev/null +++ b/etc/vim/vimrc @@ -0,0 +1,72 @@ +set nocompatible +set nowrap +set nowrapscan + +syntax on + +set list +set listchars=tab:\|·,trail:· +hi SpecialKey ctermfg=black cterm=bold + +set hlsearch +hi Search ctermbg=yellow + +set number +hi LineNr ctermfg=black cterm=bold + +set autochdir + +" tab navigation like firefox +nnoremap :tabprevious +nnoremap :tabnext +nnoremap :tabnew +inoremap :tabpreviousi +inoremap :tabnexti +inoremap :tabnew + +nnoremap th :tabfirst +nnoremap tj :tabprev +nnoremap tk :tabnext +nnoremap tl :tablast +nnoremap tt :tabedit +nnoremap tn :tabnew +nnoremap tm :tabm +nnoremap td :tabclose +hi TabLine term=bold,reverse cterm=none ctermfg=white ctermbg=4 gui=bold guifg=blue guibg=white +hi TabLineSel term=reverse cterm=bold ctermfg=white ctermbg=black gui=bold guifg=white guibg=blue +hi TabLineFill term=bold,reverse cterm=none ctermfg=4 ctermbg=4 gui=bold guifg=blue guibg=white + +set tabstop=2 +set smartindent +set shiftwidth=2 +set ruler + +set showcmd +set ch=1 +set laststatus=2 +set statusline=%F%=\ %m%R\ %l:%c\ x%02B\ %Y\ %{&encoding} +set wildmenu +set wildignore=*.a,*.d,*.o,*.so,*~,*.cmo,*.cmi,*.cmx,*.cmxs,*.cma,*.cmxa,*.byte,*.native +hi StatusLine term=bold,reverse cterm=NONE ctermfg=7 ctermbg=4 gui=bold guifg=white guibg=darkred +hi StatusLineNC term=reverse cterm=underline ctermfg=4 ctermbg=0 guifg=grey45 guibg=black + +function! GetFoldExprFromIndent() + " Calcule l'indentation en fonction des tabulations + " et espaces au début des lignes + let lin = getline(v:lnum) + let ind = strlen(matchstr(lin,"^\t*")) + let spa = strlen(matchstr(lin,"^[ \t]*")) - ind + let retval = ind + ((spa + 3) / 4) + return retval +endfunction + +set foldenable +set foldexpr=GetFoldExprFromIndent() +set foldtext=substitute(getline(v\:foldstart),'\\t','⎢·','g').'\ \ ('.(v\:foldend-v\:foldstart+1).')\ ' +set foldmethod=expr +set foldcolumn=0 +set foldminlines=0 +set fillchars=fold:· +hi Folded ctermfg=black ctermbg=black cterm=bold +hi FoldColumn ctermfg=black ctermbg=black cterm=bold + diff --git a/local/dovecot-user-add b/local/dovecot-user-add index 017faaf..5e9c35f 100755 --- a/local/dovecot-user-add +++ b/local/dovecot-user-add @@ -152,7 +152,7 @@ shift extra_fields="${extra_fields:+$extra_fields }userdb_uid=$uid" extra_fields="${extra_fields:+$extra_fields }userdb_gid=$gid" extra_fields="${extra_fields:+$extra_fields }userdb_home=$home" - extra_fields="${extra_fields:+$extra_fields }userdb_mail_access_groups=${mail_access_groups-$domain_group}" + extra_fields="${extra_fields:+$extra_fields }userdb_mail_access_groups=${mail_access_groups-$domain_group,amavis}" cat >&3 <<-EOF $user:$password:$uid:$gid:$gecos:$home:$shell:$extra_fields EOF diff --git a/pdo.diff b/pdo.diff deleted file mode 100644 index 5470599..0000000 --- a/pdo.diff +++ /dev/null @@ -1,48 +0,0 @@ -diff --git a/php5/fpm/php.ini b/php5/fpm/php.ini -index 51b7ad3..301675f 100644 ---- a/php5/fpm/php.ini -+++ b/php5/fpm/php.ini -@@ -131,7 +131,6 @@ expose_php = On - extension = apc.so - extension = gd.so - extension = pdo.so --extension = pdo_mysql.so - ;extension_dir = - file_uploads = On - html_errors = On -diff --git a/php5/fpm/pool.d/davical/php-fpm.conf b/php5/fpm/pool.d/davical/php-fpm.conf -index 4767b2f..6c04701 100644 ---- a/php5/fpm/pool.d/davical/php-fpm.conf -+++ b/php5/fpm/pool.d/davical/php-fpm.conf -@@ -31,7 +31,6 @@ user = php5_davical - php_admin_value[default_charset] = "UTF-8" - php_admin_value[error_reporting] = "E_ALL & ~E_NOTICE" - php_admin_value[extension] = curl.so --php_admin_value[extension] = pdo.so - php_admin_value[extension] = pdo_pgsql.so - php_admin_value[extension] = pgsql.so - php_admin_value[include_path] = "/usr/share/davical/inc:/usr/share/awl/inc" -diff --git a/php5/fpm/pool.d/lhc_quest/php-fpm.conf b/php5/fpm/pool.d/lhc_quest/php-fpm.conf -index 713394f..9e286b2 100644 ---- a/php5/fpm/pool.d/lhc_quest/php-fpm.conf -+++ b/php5/fpm/pool.d/lhc_quest/php-fpm.conf -@@ -28,7 +28,6 @@ rlimit_core = unlimited - rlimit_files = 131072 - slowlog = /home/www/log/php5/fpm/lhc_quest/slow.log - user = php5_lhc_quest --php_admin_value[extension] = pdo.so - php_admin_value[extension] = pdo_mysql.so - pm.max_children = 15 - pm.max_requests = 200 -diff --git a/php5/fpm/pool.d/lhc_stats/php-fpm.conf b/php5/fpm/pool.d/lhc_stats/php-fpm.conf -index b901d8e..62eba8d 100644 ---- a/php5/fpm/pool.d/lhc_stats/php-fpm.conf -+++ b/php5/fpm/pool.d/lhc_stats/php-fpm.conf -@@ -28,7 +28,6 @@ rlimit_core = unlimited - rlimit_files = 131072 - slowlog = /home/www/log/php5/fpm/lhc_stats/slow.log - user = php5_lhc_stats --php_admin_value[extension] = pdo.so - php_admin_value[extension] = pdo_mysql.so - pm.max_children = 15 - pm.max_requests = 200