milter-greylist で差出人アドレスのドメイン部だけを評価する。
id:JULY:20100109 で id:kshiono さんとのコメントのやり取りの中、その存在がバレてしまった(^^;、「差出人アドレスのドメインパートだけを評価するキーワード」のパッチを公開します。
Ver 4.2.5 から作ったパッチですが、4.2.6 でもそのまま適用出来ます。
このパッチを当てると、「fromdom」というキーワードが使えるようになります。
racl whitelist fromdom example.jp domain mx.example.jp
と書くと、
- 差出人のメールアドレスが example.jp で、
- かつ、相手の MTA が mx.example.jp だった場合
に許可することになります。
普通の from との違いは、from の場合はメールアドレス全体に対して部分文字列一致か、正規表現で指定するのに対し、fromdom の場合は、メールアドレスのドメインパート(「@」より後ろ)だけを対象として評価します。その時の評価方法は domain と同じで、大文字小文字を無視します。また、domainexact が指定されていれば、ドメインの境界を考慮するようになり、「example.jp」と指定されている場合、
- mail.example.jp はマッチする。
- mailexample.jp はマッチしない。
といった具合に、サブドメインがマッチするようになるのも domain と同じです*1。
このパッチでやっているのは、設定ファイルのキーワードとして fromdom を追加して、fromdom が来たら「@」の後ろの文字列を、domain キーワードを評価している関数に投げるようにしただけです。
きちんとテストした訳じゃないのですが、少なくとも手元では悪影響は出ていません。一応、お約束ですが、自己責任で(^^;。
diff -uNr milter-greylist-4.2.5/acl.c milter-greylist-4.2.5-j/acl.c --- milter-greylist-4.2.5/acl.c 2010-04-14 13:41:22.000000000 +0900 +++ milter-greylist-4.2.5-j/acl.c 2010-04-28 17:29:44.000000000 +0900 @@ -152,6 +152,10 @@ void acl_free_prop_regex(acl_data_t *); #endif + +static void retrive_domain_part(const char *, char *, size_t); + + struct acl_clause_rec acl_clause_rec[] = { /* Temporary types for lists */ { AC_LIST, MULTIPLE_OK, AS_NONE, "list", @@ -180,6 +184,18 @@ AT_LIST, AC_NONE, AC_NONE, EXF_ADDR, acl_print_list, acl_add_list, NULL, acl_list_filter }, + { AC_FROMDOM, UNIQUE, AS_ANY, "fromdom", + AT_STRING, AC_FROMDOM_LIST, AC_DOMAIN, EXF_FROM, + acl_print_string, acl_add_string, + acl_free_string, acl_fromdom_cmp }, + { AC_FROMDOM_RE, UNIQUE, AS_ANY, "fromdom_re", + AT_REGEX, AC_FROMDOM_LIST, AC_REGEX, EXF_FROM, + acl_print_regex, acl_add_regex, + acl_free_regex, acl_fromdom_regexec }, + { AC_FROMDOM_LIST, UNIQUE, AS_ANY, "fromdom_list", + AT_LIST, AC_NONE, AC_NONE, EXF_FROM, + acl_print_list, acl_add_list, + NULL, acl_list_filter }, { AC_DOMAIN, UNIQUE, AS_ANY, "domain", AT_STRING, AC_DOMAIN_LIST, AC_DOMAIN, EXF_DOMAIN, acl_print_string, acl_add_string, @@ -514,6 +530,47 @@ return (1); } +static +void +retrive_domain_part(address, buf, bufsize) + const char *address; + char *buf; + size_t bufsize; +{ + char *domain_part, *bracket; + + if (address == NULL || buf == NULL || bufsize < 1) return; + + domain_part = strchr(address, '@'); + + if (domain_part != NULL) { + domain_part++; + strncpy(buf, domain_part, bufsize); + buf[bufsize - 1] = '\0'; + + bracket = strchr(buf, '>'); + if (bracket != NULL) + *bracket = '\0'; + } else { + buf[0] = '\0'; + } +} + +int +acl_fromdom_cmp(ad, stage, ap, priv) + acl_data_t *ad; + acl_stage_t stage; + struct acl_param *ap; + struct mlfi_priv *priv; +{ + struct mlfi_priv copied_priv; + + copied_priv = *priv; + retrive_domain_part(priv->priv_from, copied_priv.priv_hostname, sizeof(copied_priv.priv_hostname)); + + return acl_domain_cmp(ad, stage, ap, &copied_priv); +} + int acl_header_strstr(ad, stage, ap, priv) acl_data_t *ad; @@ -744,6 +801,21 @@ } int +acl_fromdom_regexec(ad, stage, ap, priv) + acl_data_t *ad; + acl_stage_t stage; + struct acl_param *ap; + struct mlfi_priv *priv; +{ + struct mlfi_priv copied_priv; + + copied_priv = *priv; + retrive_domain_part(priv->priv_from, copied_priv.priv_hostname, sizeof(copied_priv.priv_hostname)); + + return acl_domain_regexec(ad, stage, ap, &copied_priv); +} + +int acl_header_regexec(ad, stage, ap, priv) acl_data_t *ad; acl_stage_t stage; diff -uNr milter-greylist-4.2.5/acl.h milter-greylist-4.2.5-j/acl.h --- milter-greylist-4.2.5/acl.h 2010-04-19 01:19:36.000000000 +0900 +++ milter-greylist-4.2.5-j/acl.h 2010-04-28 17:31:17.000000000 +0900 @@ -111,6 +111,9 @@ AC_SA, AC_SASCORE, AC_RATELIMIT, + AC_FROMDOM, + AC_FROMDOM_RE, + AC_FROMDOM_LIST, } acl_clause_t; struct acl_clause; @@ -302,6 +305,10 @@ struct acl_param *, struct mlfi_priv *); int acl_domain_regexec(acl_data_t *, acl_stage_t, struct acl_param *, struct mlfi_priv *); +int acl_fromdom_cmp(acl_data_t *, acl_stage_t, + struct acl_param *, struct mlfi_priv *); +int acl_fromdom_regexec(acl_data_t *, acl_stage_t, + struct acl_param *, struct mlfi_priv *); int acl_body_strstr(acl_data_t *, acl_stage_t, struct acl_param *, struct mlfi_priv *); int acl_header_strstr(acl_data_t *, acl_stage_t, diff -uNr milter-greylist-4.2.5/conf_lex.l milter-greylist-4.2.5-j/conf_lex.l --- milter-greylist-4.2.5/conf_lex.l 2010-04-15 16:52:16.000000000 +0900 +++ milter-greylist-4.2.5-j/conf_lex.l 2010-04-28 17:26:20.000000000 +0900 @@ -17,6 +17,7 @@ addr [Aa][Dd][Dd][Rr]:? helo [Hh][Ee][Ll][Oo] from [Ff][Rr][Oo][Mm]:? +fromdom [Ff][Rr][Oo][Mm][Dd][Oo][Mm]:? rcpt [Rr][Cc][Pp][Tt]:? peer [Pp][Ee][Ee][Rr]:? verbose [Vv][Ee][Rr][Bb][Oo][Ss][Ee] @@ -204,6 +205,7 @@ {addr} { return ADDR; } {helo} { BEGIN(S_REGEX); return HELO; } {from} { BEGIN(S_REGEX); return FROM; } +{fromdom} { BEGIN(S_REGEX); return FROMDOM; } {rcpt} { BEGIN(S_REGEX); return RCPT; } {peer} { return PEER; } {autowhite} { return AUTOWHITE; } diff -uNr milter-greylist-4.2.5/conf_yacc.y milter-greylist-4.2.5-j/conf_yacc.y --- milter-greylist-4.2.5/conf_yacc.y 2010-04-15 00:32:49.000000000 +0900 +++ milter-greylist-4.2.5-j/conf_yacc.y 2010-04-28 17:34:15.000000000 +0900 @@ -15,6 +15,7 @@ %token LOGFAC_LOCAL0 LOGFAC_LOCAL1 LOGFAC_LOCAL2 LOGFAC_LOCAL3 LOGFAC_LOCAL4 %token LOGFAC_LOCAL5 LOGFAC_LOCAL6 LOGFAC_LOCAL7 P0F P0FSOCK DKIMCHECK %token SPAMDSOCK SPAMDSOCKT SPAMD DOMAINEXACT ADDHEADER NOLOG RATELIMIT KEY +%token FROMDOM %{ #include "config.h" @@ -117,6 +118,8 @@ | lines rcptaddr '\n' | lines fromregex '\n' | lines rcptregex '\n' + | lines fromdomaddr '\n' + | lines fromdomregex '\n' | lines domainaddr '\n' | lines domainregex '\n' | lines peeraddr '\n' @@ -250,6 +253,16 @@ acl_register_entry_first(AS_RCPT, A_WHITELIST); } ; +fromdomaddr: FROMDOM DOMAINNAME { + acl_add_clause(AC_FROMDOM, $2); + acl_register_entry_first(AS_RCPT, A_WHITELIST); + } + ; +fromdomregex: FROMDOM REGEX { + acl_add_clause(AC_FROMDOM_RE, $2); + acl_register_entry_first(AS_RCPT, A_WHITELIST); + } + ; domainaddr: DOMAIN DOMAINNAME { acl_add_clause(AC_DOMAIN, $2); acl_register_entry_first(AS_RCPT, A_WHITELIST); @@ -799,6 +812,8 @@ | fromregex_clause | rcptaddr_clause | rcptregex_clause + | fromdomaddr_clause + | fromdomregex_clause | domainaddr_clause | domainregex_clause | netblock_clause @@ -984,6 +999,12 @@ rcptregex_clause: RCPT REGEX { acl_add_clause(AC_RCPT_RE, $2); } ; +fromdomaddr_clause: FROMDOM DOMAINNAME { acl_add_clause(AC_FROMDOM, $2); } + ; + +fromdomregex_clause: FROMDOM REGEX { acl_add_clause(AC_FROMDOM_RE, $2); } + ; + domainaddr_clause: DOMAIN DOMAINNAME { acl_add_clause(AC_DOMAIN, $2); } ; @@ -1496,6 +1517,8 @@ { all_list_settype(glist, AC_FROM_LIST); } | RCPT OPENLIST email_list CLOSELIST { all_list_settype(glist, AC_RCPT_LIST); } + | FROMDOM OPENLIST fromdom_list CLOSELIST + { all_list_settype(glist, AC_FROMDOM_LIST); } | DOMAIN OPENLIST domain_list CLOSELIST { all_list_settype(glist, AC_DOMAIN_LIST); } | DNSRBL OPENLIST qstring_list CLOSELIST @@ -1530,6 +1553,14 @@ | REGEX { list_add(glist, AC_REGEX, $1); } ; +fromdom_list: fromdom_item + | fromdom_list fromdom_item + ; + +fromdom_item: DOMAINNAME { list_add(glist, AC_FROMDOM, $1); } + | REGEX { list_add(glist, AC_FROMDOM_RE, $1); } + ; + domain_list: domain_item | domain_list domain_item ;
*1:domainexact が無いと mailexample.jp もマッチします