- 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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+: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: //
--- /dev/null
+[^< @]+?@(dovecot\.)?heureux-cyclage\.org>->MyEmailAddress
+[^< @]+?@(dovecot\.)?cyclocoop\.org>->MyEmailAddress
+ateliers\.heureux-cyclage\.org>->MyLocalMailRouter
+91\.216\.110\.42>->MyLocalMailRouterIP
--- /dev/null
+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)
--- /dev/null
+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)
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
}
}
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 {
--- /dev/null
+require
+ [ "imap4flags"
+ ];
+
+if header :contains "X-Spam-Level" "***" {
+ addflag "Junk";
+ }
require ["include"];
include :personal "roundcube";
+include :global "spam";
include :global "list";
include :global "extension";
-Subproject commit 5a6ef35f70571437f95c1e8be4ce46db1b3a3f72
+Subproject commit 2aa41322b16c1c1c1445726d6d6a6cc7affac1c2
<h2>Forge logicielle privée de l'Heureux Cyclage</h2>
<p>Pour récupérer un dépôt privé :</p>
-<pre>git clone git@git.heureux-cyclage.org/<projet></pre>
+<pre>git clone git@git.heureux-cyclage.org/<dépôt></pre>
# (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
-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
// 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";
}
'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',
);
// ----------------------------------
// 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
$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;
--- /dev/null
+"$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
--- /dev/null
+#!/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
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 \
--- /dev/null
+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 <C-S-tab> :tabprevious<CR>
+nnoremap <C-tab> :tabnext<CR>
+nnoremap <C-t> :tabnew<CR>
+inoremap <C-S-tab> <Esc>:tabprevious<CR>i
+inoremap <C-tab> <Esc>:tabnext<CR>i
+inoremap <C-t> <Esc>:tabnew<CR>
+
+nnoremap th :tabfirst<CR>
+nnoremap tj :tabprev<CR>
+nnoremap tk :tabnext<CR>
+nnoremap tl :tablast<CR>
+nnoremap tt :tabedit<Space>
+nnoremap tn :tabnew<Space>
+nnoremap tm :tabm<Space>
+nnoremap td :tabclose<CR>
+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
+
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
+++ /dev/null
-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