Perl: 2013年5月アーカイブ

昨日、Perl で作成した GCM メッセージ送信サーバの話。

どうも、昨日、CPAN で WWW::Google::Cloud::Messaging をインストールしてからだと思うのだが(結局、この Perl モジュールは使ってないけど(^^;)、LWP モジュールを呼ぶと、

# ./gcm_message_send.pl
*******************************************************************
 Using the default of SSL_verify_mode of SSL_VERIFY_NONE for client
 is depreciated! Please set SSL_verify_mode to SSL_VERIFY_PEER
 together with SSL_ca_file|SSL_ca_path for verification.
 If you really don't want to verify the certificate and keep the
 connection open to Man-In-The-Middle attacks please set
 SSL_verify_mode explicitly to SSL_VERIFY_NONE in your application.
*******************************************************************
  at /usr/lib/perl5/site_perl/5.8.8/LWP/Protocol/http.pm line 31
id=0:13685930XXXXXXXX%XXXX249ace0038c9

という感じで、エラーが出るようになった。
一応、メッセージ自体は送られているからエラーじゃないな。ワーニングだな。

どうも、WWW::Google::Cloud::Messaging のインストール時に、関連モジュールとして IO::Socket::SSL 関係もバージョンアップされちゃった臭いな(^^;

IO::Socket::SSL のバージョンが上がってセキュリティ関係に厳しくなって、「Man-In-The-Middle アタック の可能性があるので、サーバーとクライアントの間でホスト同士の証明書を交換するか、情報漏洩の可能性を承知で使うために、SSL_VERIFY_NONE を明示的に設定しましょう」ということのようであります。

取り敢えず、証明書交換はせず、SSL_VERIFY_NONE の設定で行きたいので、LWP::UserAgent のコンストラクタで、

my $ua = LWP::UserAgent->new(
ssl_opts => {
verify_hostname => 0,
SSL_verify_mode => SSL_VERIFY_NONE,
}
);

という具合に SSL_verify_mode オプションに定数 SSL_VERIFY_NONE をセットしてみたり、直接 0 をセットしてみたりしても状況変わらず。
む~ん(^^;

結局、LWP::UserAgent は SSL 接続のバックエンドとして Net::SSL も使えるってことだったので、環境変数 'PERL_NET_HTTPS_SSL_SOCKET_CLASS' に Net::SSL を指定し、IO::Socket::SSL を使わないようにしたらワーニングは出なくなった。

こんな感じ。

#!/usr/bin/perl
#
# gcm_message_send.pl
#

use LWP;

$ENV{'PERL_NET_HTTPS_SSL_SOCKET_CLASS'} = "Net::SSL";
$ENV{'PERL_LWP_SSL_VERIFY_HOSTNAME'} = 0;

my $ua = LWP::UserAgent->new;
my $res = $ua->post(
"https://android.googleapis.com/gcm/send",
{
'registration_id' => "APA91bHi1fbAcCk1qwCMu6jO4IlJuAtXXXXXXXX_hhyK7atS6i6G_GuhtprPGroMnZkNQvKTWuAPxXXXXXXXXTLv-mKpIi_Ek9CpDPWvJQ79IZjmyXXXXXXXXttIgKOcf-GTcHRC8VmND3UpXXXXXXXXvfC4bw5hJw",
'collapse_key' => 'update',
'data.message' => "これはテストメッセージです",
},
"User-Agent"    => "NAF Perl Program/0.1",
"Authorization" => "key=AIzaSyDsXXXXXXXX9Lyazw0NYRVrXXXXXXXXHk",
"Content-Type"  => "application/x-www-form-urlencoded;charset=UTF-8"
);

print $res->content . "\n";

ま、これでいいか。(結局、環境変数のセット処理を 2行追加しただけだし(笑))

それに、現実的に、中間者攻撃で我が社の GCM メッセージが改ざんされる可能性は果てしなくゼロに近いからな(笑)
Android 端末へのメッセージのプッシュをする場合のプログラムね。

GCM サービスを使うための API キーの入手の手順とかは、
を参照。(日本語訳です)

で、Google が用意しているサンプルプログラムをクライアントで動かして、メッセージを実際に端末に向けてプッシュするところまでテストしてみたんだけど、ざっとググってみたところ、サーバ側のプログラムを Perl で書いてる例が無かったので、簡単なものを作ってみた。

まず、クライアント(Android 端末上のアプリ)から regID を取得するプログラム。
(クライアントで、SERVER_URL にセットしている URL)

・・・っても、POSTで送られてくるデータをファイルに書き出してるだけだけどな。

#!/usr/bin/perl
#
# gcm_demo.cgi
#

read (STDIN, $postdata, $ENV{'CONTENT_LENGTH'});

open OUT, ">>/tmp/gcm_test.txt";
print OUT "POST $postdata\n";
close(OUT);

print "Content-type: text/html;charset=UTF-8\n\n";
print "DEMO";

exit();

これで、Android 側でクライアントを実行すると、

# cat /tmp/gcm_test.txt
POST regId=APA91bHi1fbAcCk1qwCMu6jO4IlJuAtXXXXXXXX_hhyK7atS6i6G_GuhtprPGroMnZkNQvKTWuAPxXXXXXXXXTLv-mKpIi_Ek9CpDPWvJQ79IZjmyXXXXXXXXttIgKOcf-GTcHRC8VmND3UpXXXXXXXXvfC4bw5hJw

という具合に regID(端末識別番号みたいなもん)が取得出来る。

regID が取得出来たらメッセージ送信プログラムにセット。

#!/usr/bin/perl
#
# gcm_message_send.pl
#
use LWP;

$ua = LWP::UserAgent->new;
$res = $ua->post(
"https://android.googleapis.com/gcm/send",
{
'registration_id' => "APA91bHi1fbAcCk1qwCMu6jO4IlJuAtXXXXXXXX_hhyK7atS6i6G_GuhtprPGroMnZkNQvKTWuAPxXXXXXXXXTLv-mKpIi_Ek9CpDPWvJQ79IZjmyXXXXXXXXttIgKOcf-GTcHRC8VmND3UpXXXXXXXXvfC4bw5hJw",
'collapse_key' => 'update',
'data.message' => "これはサーバからのテストメッセージです",
},
"User-Agent"    => "NAF Perl Program/0.1",
"Authorization" => "key=AIzaSyDsXXXXXXXX9Lyazw0NYRVrXXXXXXXXHk",
"Content-Type"  => "application/x-www-form-urlencoded;charset=UTF-8"
);

print $res->content;

これを実行したら、

$ ./gcm_message_send.pl
id=0:13685xxxxxxxx632%921cxxxxxxxx38c9

という具合に、https://android.googleapis.com/gcm/send がちゃんとメッセージ ID を返してくるので、ばっちりだろう。

必要最小限の一番シンプルな例ってことで(笑)

Perl 使いの皆様へ。参考まで。

このアーカイブについて

このページには、2013年5月以降に書かれたブログ記事のうちPerlカテゴリに属しているものが含まれています。

前のアーカイブはPerl: 2013年3月です。

次のアーカイブはPerl: 2013年6月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。


月別 アーカイブ

電気ウナギ的○○ mobile ver.

携帯版「電気ウナギ的○○」はこちら