Postfixをハックする(header_checksにコマンドを追加しよう)の巻

| | Comments (0) | TrackBacks (0)
HDEラボの桜井です。
今年はまともに梅雨入りしてますね。
最近は年のせいか、蛍光灯がちらついて液晶ディスプレイが見にくいです、ってどうでもいいですね。

では、今日はPostfixをハックして、header_checksにコマンドを追加する方法を解説しましょう。
まず、簡単な仕様は次のとおりです。

  • メールを指定したディレクトリに保存する機能(いわゆるアーカイブ)を追加する
  • header_checksに、「ARCHIVE」というコマンドを追加する
  • 「ARCHIVE」コマンドの引数には、メールを保存するディレクトリをフルパスで指定する

まずはソースを持ってきて展開します。
バージョンは最新でいいでしょう。

手を加えるプログラムは下記の4つです。
  • postfix-*.*.*/src/cleanup.h
  • postfix-*.*.*/src/cleanup_message.c
  • postfix-*.*.*/src/cleanup_out.c
  • postfix-*.*.*/src/cleanup_state.c

では、解説行ってみようと思います。

1. "cleanup.h" へ、"ARCHIVE" コマンドのフラグを追加
CLEANUP_STATE構造体へ、下記のフラグを追加します。
char *archive;  /* from header/body patterns */


2. "cleanup_state.c" へ、"ARCHIVE" フラグの状態の初期化/終了処理を追加
cleanup_state_alloc関数で、CLEANUPO_STATE構造体の初期化を行っています。
ここでフラグの初期化を追加します。
  state->archive = 0;


また、cleanup_state_free関数で、CLEANUP_STATE構造体の終了処理を行っています。
ここでフラグの終了処理を追加します。
  if (state->archive)
    myfree(state->archive);


3. "cleanup_message.c" へ、"ARCHIVE" コマンドと引数取得箇所を追加
cleanup_act関数で、既存コマンドの実行(FILTER、IGNOREなど)を行います。
ここへ "ARCHIVE" の処理を追加します。
    if (STREQUAL(value, "ARCHIVE", command_len)) {
        if (*optional_text == 0) {
            msg_warn("ARCHIVE action without text in %s map", map_class);
            return (buf);
        } else {
            if (state->archive) {
                myfree(state->archive);
            }
            char archive_filename[1024] = "";
            strcat(archive_filename, mystrdup(optional_text));
            strcat(archive_filename, mystrdup(state->queue_id));
            state->archive = mystrdup(archive_filename);
            msg_warn("ARCHIVE debug : file=%s, size=%d", archive_filename, sizeof(archive_filename));
            msg_warn("ARCHIVE debug : cleanup_path=%s, sender=%s, recip=%s, archive=%s", mystrdup(VSTREAM_PATH(state->dst)), mystrdup(state->sender), mystrdup(state->recip), state->archive);
            cleanup_act_log(state, "archive", context, buf, optional_text);
            return (buf);
        }
    }


4. "cleanup_out.c" へ、ファイルへのメール書き出し処理を追加
cleanup_out関数内で、cleanupコマンドからqueueへのアウトプット処理が行われます。
この中で、メールのファイルへの書き出し処理を追加します(最初の方へ記述します)。
    if (state->archive != 0) {
      msg_warn("DEBUG message : %s : %s", state->archive, string);
      int archive_fd = open(state->archive, O_WRONLY | O_CREAT | O_APPEND, 0666);
      write(archive_fd, string, strlen(string));
      write(archive_fd, "\n", 1);
      close(archive_fd);
    }


あとはコンパイルして動作させるのみです。
ちなみに、header_checksのファイルへの設定内容は下記のように行います。
(例)example.comから来たメールをすべてアーカイブする場合
/^From: .*example.com/    ARCHIVE  /etc/postfix/archive/


一応、2.3.3用に適当にパッチ作ったので(おそらく他のバージョンでも大丈夫な気がする)、 ここからどうぞ。

0 TrackBacks

Listed below are links to blogs that reference this entry: Postfixをハックする(header_checksにコマンドを追加しよう)の巻.

TrackBack URL for this entry: http://lab.hde.co.jp/blog/mt-tb.cgi/41

Leave a comment

About this Entry

This page contains a single entry by Takeshi SAKURAI published on June 12, 2008 10:40 AM.

CentOS + iSCSIを構築してみる。(検証編) was the previous entry in this blog.

開発チームを盛り上げるふたつの方法 is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.