fml(メーリングリスト)の動作がおかしい?

メーリングリストサーバとして代表的なものは、Mailmanやfml、sympa等があります。
その中のfmlで動作がおかしい部分を発見したので、忘れないようにメモメモ〆(.. )

正直、クリティカルなものかそうでないかと言えば、微妙なところなのですがf(^^;)
所謂、”仕様”なのかもしれませんが( ̄Д ̄;)
おかしい気がするので。。。

fmlは、一度送信したメールのmessage-IDを記録しておき、以前送ったことがあるメールかどうかをmessage-IDを比較してチェックします。message-IDが同じメールを送ろうとすると、以前送ったメールであると判断してエラーとなり、「Loop Alert:」というログが出力されます。

message-IDはメール1通1通の識別子であり、同じになることはまずありえないのです。ですが、やたらと「Loop Alert:」となったので、何かがおかしい。で、メールログと、fmlのキャッシュを比べると似たようなmessage-IDがありました。

キャッシュファイル内: JA8AAAAABIH8CgABYQABNARwAfxU@example.com
メールログ内        : JA8AAAAABIH8cgABYQABNARwAfxU@example.com
                                  ^

 

ん?Cの大文字と小文字が違うだけ?怪しい・・・分からないので、実際にmessage-IDを比較しているところをfmlのソースから確認してみました。perlなので普通に分かりました。

◇ /usr/local/fml/fml.pl

~
local($status, $mid);

# no check -> "return not looped"
$CHECK_MESSAGE_ID || return 0;

local($mid) = $Envelope{'h:Message-Id:'};
$mid =~ s/[\<\>]//g;
$mid =~ s/^\s+//;

&Debug("DupMessageIdP::($mid, $LOG_MESSAGE_ID)") if $debug;

$status = &SearchDupKey($mid, $LOG_MESSAGE_ID);
          ^^^^^^^^^^^^^

if ($status) {
    &Debug("\tDupMessageIdP::(DUPLICATED == LOOPED)") if $debug;
    local($s) = "Duplicated Message-ID";
    &Log("Loop Alert: $s");
    &WarnE("Loop Alert: $s $ML_FN", "$s in <$MAIL_LIST>.\n\n");
    1;
}
~

 

SearchDupKeyの関数を見ればいいんだね!

~
sub SearchDupKey
{
    local($key, $file) = @_;
    local($status, $i);

    # 1. scan current and
    if (-f $file) {
        $status = &Lookup($key, $file);
                  ^^^^^^^
    }
    return $status if $status;

    # 2. scan all available caches
    for $i (0 .. $NEWSYSLOG_MAX) {
        if ($status) {
            last; # end if non null $status is returned.
        }
        elsif (-f "$file.$i") {
            $status = &Lookup($key, "$file.$i");
                      ^^^^^^^
        }
    }
    $status;
}
~

 

Lookupの関数を見ればいいんだね!

~
sub Lookup
{
    local($address, $file) = @_;
    local($addr, $has_special_char, $auto_registrable);
~
        # for high performance(Firstly special character check)
        if (! $has_special_char) { next getline unless /^$addr/i;}

        # This searching algorithm must require about N/2, not tuned,
        if (1 == &AddressMatch($_, $address)) {
                 ^^^^^^^^^^^^^
            close(LOOKUP_TABLE);
            return 1;
        }
    }# end of while loop;

    close(LOOKUP_TABLE);
    return 0;
}
~

 

AddressMatchの関数を見ればいいんだね!

~
sub AddressMatch
{
    local($addr1, $addr2) = @_;

    &Debug("   AddressMatch($addr1, $addr2)".
           " [\$ADDR_CHECK_MAX=$ADDR_CHECK_MAX]\n") if $debug_addrmatch;

    # canonicalize to lower case
    $addr1 =~ y/A-Z/a-z/;                         ☆ビンゴ
    $addr2 =~ y/A-Z/a-z/;
~
}
~

 

ビンゴ!!大文字を小文字に変えてるΣ( ̄Д ̄;)
つまり、大文字小文字区別なしでメールのIDを比較をしているジャマイカ。
RFCでは「メールのIDは大文字小文字の区別を行う」事が規定ですので、fmlがRFCに準拠していない。。。すごく似たmessage-IDを付けるメーラーもメーラーですが、これはいけないですよね・・・。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です