前回に引き続き、枯れたソフトでサーバ構築。

Courier-IMAP+vpopmail+APOPな環境。前回触ったのはいつか思い出せないので、ググって思い出してみる。あぁ、こいつもパッチか。とりあえず、ちょっと対象バージョンが古いみたいだけど当ててみる。やっぱ一筋縄じゃ行かないな。ということで、パッチとにらめっこしながら、適応できなかったところを手で編集。まあ、これはそんなにボリュームがないからいいや。
authlibのほうから、いつものように(prefixは好みで)

./configure --prefix=/usr/local/courier/authlib --with-mailuser=vpopmail --with-mailgroup=vchkpw
make
make install
make install-configure

でインストール。それから、imapの方もいつものように。だけどヘッダやらライブラリがない、と怒られるので、おまじない付きで。

COURIERAUTHCONFIG=/usr/local/courier/authlib/bin/courierauthconfig \
CPPFLAGS=-I/usr/local/courier/authlib/include \
./configure --prefix=/usr/local/courier/imap --with-redhat
make
make install-strip
make install-configure

インストールがうまくいったら、早速動作確認。証明書関係は最初は気にしないので、デフォルトのスクリプトで生成。

cd /usr/local/courier/imap/share
./mkimapdcert

勝手に証明書ができるので、中身を確認。キーと証明書が一体のヤツだ。しかも、DHPARAMファイルも一緒。確認したら、普通に動かしてみる。

/usr/local/courier/authlib/sbin/authdaemond start
/usr/local/courier/imap/libexec/imapd.rc start
/usr/local/courier/imap/libexec/imapd-ssl.rc start
/usr/local/courier/imap/libexec/pop3d.rc start
/usr/local/courier/imap/libexec/pop3d-ssl.rc start

分かれてるのはいいけど、dovecotみたいにさくっと全部動かせりゃいいのに。で、動作確認。普通にIMAP(ノーマル・CRAM-MD5)・IMAPS(ノーマル・CRAM-MD5)・POP3(ノーマル・APOP)・POP3S(ノーマル・APOP)のはずが、APOPは動かない。パッチを当てたのに〜何で?と思いつつ、デバッグフラグ2(パスワードも記録)で動かしてみる。どうやら、パスワードが一致しないと言われている。このままじゃ原因が分からないので、ソースを追っかけてみる。よく分からないけど、ファイルの中にauthvchkpw.cなんてのがあるから、ここから追いかけると、パスワードのチェックをしてるのは、checkpasswordmd5.cらしいことが分かる。で、encrypted_passwordの先頭が{APOP}から始まってると、APOPとしてチェックする、という形だ。でも、ここに渡されてるのは、至って普通の$1$〜ていうのだから、APOPで渡したパスワードとは一致しないわけだ。対策をどうしようかと考えるけど、パスワードの認証ルーチンでは、encryptedパスワードと入力された値しか持ってないから、APOPを確認するのが難しい、ということで追いかけると、その前の段階でクリアパスワードも持ってる事が発覚。preauthvchkpw.cのファイルで、パスワードをチェックルーチンに渡すときに変換してやる事にする。

元ファイル:

        /* save the user's passwd fields into the appropriate 
         * courier structure 
         */
        /*auth.sysusername      = userid;*/
        auth.sysuserid          = &uid;
        auth.sysgroupid         = gid;
        auth.homedir            = vpw->pw_dir;
        auth.address            = userid;
        auth.fullname           = vpw->pw_gecos;
        auth.passwd             = vpw->pw_passwd;
        auth.clearpasswd        = vpw->pw_clear_passwd;
        auth.options            = options;
        courier_authdebug_authinfo("DEBUG: authvchkpw: ", &auth, 0, vpw->pw_passwd);

        return ((*callback)(&auth, arg));

書き換え後:

        char *apoppass;
        if((apoppass = malloc(strlen(vpw->pw_clear_passwd)+6)) == 0)
        {
                perror("malloc");
                exit(1);
        }
        strcpy(apoppass, "{APOP}");
        strcat(apoppass, vpw->pw_clear_passwd);

        /* save the user's passwd fields into the appropriate 
         * courier structure 
         */
        /*auth.sysusername      = userid;*/
        auth.sysuserid          = &uid;
        auth.sysgroupid         = gid;
        auth.homedir            = vpw->pw_dir;
        auth.address            = userid;
        auth.fullname           = vpw->pw_gecos;
        auth.passwd             = (strcmp("apop", service)==0) ? apoppass : vpw->pw_passwd;
        auth.clearpasswd        = vpw->pw_clear_passwd;
        auth.options            = options;
        courier_authdebug_authinfo("DEBUG: authvchkpw: ", &auth, 0, vpw->pw_passwd);

        int retval;
        retval = (*callback)(&auth, arg);

        free(apoppass);

        return (retval);

ああ、Cなんてひっさびさに触るから忘れてるなぁ。で、いろいろ調べつつ、ちょこっと変更して、make & make installで、サービスをリスタートしてチェック。うむ。APOPも通るようになった。というわけで、メールサーバの下地作りは一件落着。不安なのは、自分で書き足したAPOPの部分だな。メモリリークとかやだな。今更APOPなんて、全く需要ないし、使うヤツがいるか分からないけど、まとめてパッチにしておきたい、と思う今日この頃。そういえば、dovecotと比較すると、確かに反応速度はかなり速い。(いや、自分のdovecot設定が悪いだけなのかも知れないけど)dovecotはもっさり、て感じで動くけど、courierはサクサク。軽さを求めるならこっちなのかなぁ。

最後に、正規の証明書をキーファイル、証明書、中間証明書、ルート証明書、DHPARAMファイルと含めて、全部1個のファイルを作って、こいつをサービスの証明書として指定する。よし、とりあえずうまく動いたぞ、と。

この2日間での日記になってるけど、実際にはここまでで倍はかかったわけで。結構大変ですなあ。


※追記1
APOPの認証は、telnet localhost 110とやって、

$ telnet localhost 110
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
+OK Hello there. <3035.1185645556@localhost.localdomain>

<3035.1185645556@localhost.localdomain>を使って、

$ echo -n '<3035.1185645556@localhost.localdomain>password' | md5sum
977169249fb6b7d9db240e5ca9b36c24  -

とやれば生成可能。この結果を、

APOP id:tkkochan 977169249fb6b7d9db240e5ca9b36c24

と渡してやればOK

追記:なぜかglibc 〜うんたらかんたら〜 memory corruption なるエラーが出る場合があって、採用を中止・・・