2003年05月22日

moblogシステム概要


2005-07-17 機能を整理して新版を作成しました。→こちら。

重要! 2005-06-16 更新 2004-04-13以前の版には、セキュリティホールがあります。内容と対策はこちら

このweblogに携帯メールから書き込めるようにしているシステムの概要とセットアップ方法
環境:
Mac OS X 10.2 (10.3以降はSendmailからPostfixに変更されているので、後半のSMTPの設定方法が異なる)

概要:
1.メールサーバでメールを受ける
2.題名、本文、添付ファイルをとりだす
3.weblogに書き込む
という動作をするスクリプトを使用。XMLRPCを使用しているので、メールサーバとMovable Typeが動いているWebサーバは別のマシンでも良い。

更新履歴

  • 2005-06-13: セキュリティ対策(投稿内容のサニタイズ)
  • 2004-04-13: A5501TのExifタグに対応。(GPSタグの度が1/100000、分・秒共に0)
  • 2004-02-13:
    • [Movable Type 2.661 + 日本語化パッチ]に対応。
    • GPS情報の抽出をexiflistからImage::Infoに変更。
    • mencoderによるamcファイルの変換を廃止。(QuickTime6.5によりamc再生環境が整ったため不要と判断)
  • 2003-07-24: Extendedが生成されないバグを修正。
  • 2003-07-20: Altitudeタグがない場合に対応。

この手の動作をするpythonのスクリプトとしてmail2entryというものがすでにあるが、これがOS X10.2に含まれるバージョンのpythonではうまく動かなかったので、perlで書いてしまった。車輪の再発明かも。
Download file
GNU General Public License version 2日本語) に従ったフリーウェアです。

位置付写真を添付したメールでMovable Typeに書き込むための基本的な機能しか実装してません。

  • 想定している測地系は、WGS-84。
  • 地図へのリンクは、@NAVI。
  • カテゴリーは扱いません。
  • ffmpegをインストールしておけば、auムービーメールのサムネールを作って同時にアップロード。
  • ムービーに埋め込んだ位置情報には対応していません

測地系の変換をして日本測地系のMapionを使う、自動的にカテゴリーを設定する、などの拡張をするには、nob sekiさんのSync A World You Want To Explore: GPSは正確だが、地図情報は?が参考になります。

メールから書き込む機能はいらない、画像に地図リンクだけ付け足したい、という場合は、AddMapsプラグインをどうぞ。

スクリプトの設定:

my $url = 'http://www.your-site.com/movabletype/mt-xmlrpc.cgi';
Movable Type のmt.cgiをmt-xmlrpc.cgiに置き換えたもの。

my $blog_id = 2;
書き込みたいweblogのid。Entry編集画面のURLにblog_id=で表示されているもの。

my $username = 'Melody';
my $password = 'Nelson';
書き込むユーザ名とパスワード。メール書き込み用に新しくユーザを追加したほうがいいかも。

my $code = utf8; # utf8, euc, jis, sjis
書き込む漢字コード
(2.661+日本語化パッチではXML-RPCがutf8に統一されているようなので、この設定は削除)

my $MT_DIR = '/Library/WebServer/Documents/mt/';
同じマシンにMovable Type をインストールしているならば、そのディレクトリ。文字列の最後は/で。

my $parse_path = '/Users/Shared/post2blog';
テンポラリファイルを作るディレクトリを用意する。OS Xの場合、Finder上から確認しやすい/Users/Shared/に作るのが良いかも。

モジュールのインストール:

OS XでMovable Typeが動いている環境の標準以外で必要なperlモジュール
http://search.cpan.org/author/ERYQ/IO-stringy-2.108/
http://search.cpan.org/author/GAAS/MIME-Base64-2.20/
http://search.cpan.org/author/MARKOV/MailTools-1.58/
http://search.cpan.org/author/ERYQ/MIME-tools-5.411a/
http://search.cpan.org/author/DANKOGAI/Jcode-0.83/
http://search.cpan.org/~gaas/Image-Info-1.16/

MIME-toolsをインストールする前に、その上の3つをインストール。

それぞれを展開したディレクトリの中で
% perl Makefile.PL
% make
% sudo make install
でインストールできる。

OS Xの標準に含まれていないものとしては、SOAP::Liteも必要だが、Movable Typeが動いている環境ならば、すでにインストールされている。Movable Typeを動かしているマシンとは別のマシンでこのスクリプトを動かす場合は、SOAP::Liteもインストールする。SOAP::Liteは依存するモジュールが多くてややこしいので、CPANモジュールを使ったほうがいいかもしれない
まずはCPANモジュール自身のアップデート。途中でいろいろ聞いてくるが、基本的にはすべてデフォルトでよい。つまりひたすらリターンキー。
% perl -MCPAN -e shell
cpan> install Bundle::CPAN
ただしlibwww-perlのインストール中に
Do you want to install the HEAD alias? [y]
と聞いてくるので、これだけはnと答えないと、大文字小文字を区別しないHFS+ボリュームの場合/usr/bin/headコマンドを潰してしまう。

cpan> reload cpan

CPANモジュールを使っていると、途中でperl5.8.0とかのインストールが始まってしまうことがある。そんなときはダウンロード中にすかさずCtrl+Cで中断。

cpan> install SOAP::Lite

sendmailの設定:
まずはサーバとして動くようにする。
[参考ページ]
http://pisa.csrs.is.uec.ac.jp/TechInfo/Macintosh/SendmailOnJaguar/UptheSendmailOnJaguar.html

[参考ページ]に書いてないこと:
DNSで引けるマシン名がなくてIPアドレスだけの場合
/etc/mail/local-host-names
に、生IPアドレスを[]で囲んだものを記入。仮にアドレスを192.168.0.1とすると
192.168.0.1
[192.168.0.1]
これは、SMTPサーバによってはTo: user@192.168.0.1では送信ができず、To: user@[192.168.0.1]とする必要があるため。.macはこのパターン。ezwebは[]なしで送信可。

次に、サーバに届いたメールをスクリプトに渡すようにする。
スクリプトを/usr/adm/sm.bin内に置く。
% sudo mkdir -p /usr/adm/sm.bin
% sudo cp post2blog /usr/adm/sm.bin
% sudo chmod 555 /usr/adm/sm.bin/post2blog

NetInfoマネージャで[参考ページ]の通りにaliasesを追加。ただし、"members"にはアドレスのかわりにスクリプトへのパイプをフルパスで記入。
| /usr/adm/sm.bin/post2blog

再起動。

これで、
alias名@IPアドレス
にメールを送信すれば書き込まれる。


重要:
2004-04-13以前の版には以下のセキュリティホールがあります。最新のものをダウンロードしなおして使用するか、以下の対策を取ってください。

内容1:
添付ファイル名のサニタイズを行っていないため、投稿先メールアドレスが漏洩すると、最悪の場合、メールを受信するサーバ上で任意のコードの実行が可能です。

この脆弱性情報は坂井まどかさんによるものです。ありがとうございました。

対策1:
オリジナルの添付ファイル名を使用しないようにしてください。

例) $parser->output_under($parse_path); の次行に $parser->filer->ignore_filename(1); を追加。

内容2:
同じく投稿先メールアドレスが漏洩した場合、題名、本文などを利用したXSSが可能になります。
対策2:
投稿内容のサニタイズを行ってください。

例) スクリプト冒頭に BEGIN { my $MT_DIR = '/Library/WebServer/Documents/mt/'; unshift @INC, $MT_DIR . 'extlib'; unshift @INC, $MT_DIR . 'lib'; } use MT::Sanitize; を追加。 my $sub = $head->get('Subject'); の次行に $sub = MT::Sanitize->sanitize($sub); を追加。 $cont = $j->set($cont)->utf8; の前行に $cont = MT::Sanitize->sanitize($cont); を追加。

以上二つの変更を行ったものと旧バージョンとのdiffは以下。

% diff -c post2blog.old post2blog *** post2blog.old Thu Jun 16 17:55:58 2005 --- post2blog Thu Jun 16 17:58:40 2005 *************** *** 10,15 **** --- 10,20 ---- # You can redistribute it and/or modify it under the terms of # the GNU General Public License version 2. # + BEGIN { + my $MT_DIR = '/Library/WebServer/Documents/mt/'; + unshift @INC, $MT_DIR . 'extlib'; + unshift @INC, $MT_DIR . 'lib'; + } use strict; *************** *** 17,35 **** my $blog_id = 2; my $username = 'Melody'; my $password = 'Nelson'; - my $MT_DIR = '/Library/WebServer/Documents/mt/'; my $parse_path = '/Users/Shared/post2blog'; my ($maxx, $maxy) = (320, 320); - unshift @INC, $MT_DIR . 'extlib'; - use MIME::Parser; #use Data::Dumper; use File::Basename; use Jcode; use XMLRPC::Lite; use Image::Info qw(image_info dim); my $j = new Jcode; --- 22,38 ---- my $blog_id = 2; my $username = 'Melody'; my $password = 'Nelson'; my $parse_path = '/Users/Shared/post2blog'; my ($maxx, $maxy) = (320, 320); use MIME::Parser; #use Data::Dumper; use File::Basename; use Jcode; use XMLRPC::Lite; use Image::Info qw(image_info dim); + use MT::Sanitize; my $j = new Jcode; *************** *** 43,51 **** --- 46,56 ---- my $parser = new MIME::Parser; $parser->output_under($parse_path); + $parser->filer->ignore_filename(1); my $entity = $parser->parse_data($str); my $head = $entity->head; my $sub = $head->get('Subject'); + $sub = MT::Sanitize->sanitize($sub); my $message_id = $head->get('Message-ID'); my $cnttype = $entity->mime_type; $sub = $j->set($sub)->mime_decode->utf8; *************** *** 85,90 **** --- 90,96 ---- } close(CONT); } + $cont = MT::Sanitize->sanitize($cont); $cont = $j->set($cont)->utf8; my @conts = split(/?n?n?n/, $cont);