2007-09-11
Plaggerのpassword:をMac OS XのKeyChain Accessから引っ張ってくるCryptモジュール書いた
何でそうするのかと言うと、plaggerのconfig.yamlのpassword:は現状では単なる難読化しかサポートしていないから。認証データは一元管理したい。
ソースは /lang/perl/plagger/lib/Plagger/Crypt/Keychain.pm ? CodeRepos::Share ? Trac に。
package Plagger::Crypt::Keychain; use strict; use Mac::AppleScript qw(RunAppleScript); use URI; sub id { 'keychain' } sub decrypt { my ($self, $text) = @_; my $u = URI->new($text); # my $protocol = $u->scheme; my $account_name = $u->userinfo; my $server_name = $u->host; # my $port = $u->port; my $path_to = $u->path; my $result = RunAppleScript(qq{tell application "Keychain Scripting"\nreturn password of last Internet key of current keychain whose server is "$server_name" and path is "$path_to"\nend tell}); if ($@) { Plagger->context->log(error => "AppleScript error: $@"); return; } return fixquote($result); } sub encrypt { my($self, $text) = @_; my $u = URI->new($text); my $protocol = $u->scheme; my ($account_name, $clr_password) = split /:/, $u->userinfo; my $server_name = $u->host; # my $port_num = $u->port; my $path_to = $u->path; RunAppleScript(qq/tell application "Keychain Scripting"\nmake new Internet key at current keychain with properties {account:"$account_name", password:"$clr_password", server:"$server_name", path:"$path_to", protocol:"$protocol"}\nend tell/); if ($@) { Plagger->context->log(error => "AppleScript error: $@"); return; } $u->userinfo($account_name); return $u->as_string; } sub fixquote { $_[0] =~ s/(?:\xC2\xA5|\\)"/"/mg; # delete YEN SIGN or BACKSLASH return substr $_[0], 1, length($_[0])-2; # strip quotation } 1; __END__ =head1 NAME Plagger::Crypy::Keychain - Plagger Crypt for Mac OS X Keychain Access =head1 SYNOPSIS - module: Plugin::Foobar config: host: example.com username: username password: keychain::http://username:password@example.com/pathto/ =head1 DESCRIPTION =head1 KNOWN BUGS dont work contains '@' at username.
(あと t/core/keychain.t と Makeperl.PL でdependどうするかがよく分からん)
(2008-10-24追記:Perlからキーチェーンのパスワードを引っ張ってくるのはTatsuhiko Miyagawa / LWP-UserAgent-Keychain-0.01 - search.cpan.orgの
use Mac::Glue ':all'; use base qw( LWP::UserAgent ); my $keychain = Mac::Glue->new("Keychain Scripting"); sub get_basic_credentials { my($self, $realm, $uri, $isproxy) = @_; for my $key ($keychain->obj(keys => keychain => "Login.keychain")->get) { if ($key->prop('class')->get eq 'cint' and $key->prop('server')->get eq $uri->host and $key->prop('protocol')->get eq $uri->scheme) { my $username = $key->prop('account')->get; my $password = $key->prop('password')->get; return ($username, $password); } } return (undef, undef); }
みたいにMac::Glue使うほうがスッキリ書けるので良いかも)
んで現状のplaggerはlib/Plagger/Plugin.pmを
sub decrypt_config { my($self, $data, $key) = @_; my $decrypted = Plagger::Crypt->decrypt($data->{$key}); if ($decrypted eq $data->{$key}) { # Plagger->context->add_rewrite_task($key, $decrypted, Plagger::Crypt->encrypt($decrypted, 'base64')); Plagger->context->add_rewrite_task($key, $decrypted, Plagger::Crypt->encrypt($decrypted, 'keychain')); } else { $data->{$key} = $decrypted; } }
という感じにbase64からkeychainに変えないとencryptでrewriteしてくれない。
このあたりはglobalのconfigを見るのが良いのかも?
--- lib/Plagger/Plugin.pm (revision 1873) +++ lib/Plagger/Plugin.pm (local) @@ -68,10 +68,10 @@ sub decrypt_config { my($self, $data, $key) = @_; - + my $context = Plagger->context; my $decrypted = Plagger::Crypt->decrypt($data->{$key}); if ($decrypted eq $data->{$key}) { - Plagger->context->add_rewrite_task($key, $decrypted, Plagger::Crypt->encrypt($decrypted, 'base64')); + $context->add_rewrite_task($key, $decrypted, Plagger::Crypt->encrypt($decrypted, $context->conf->{encrypt} || 'base64')); } else { $data->{$key} = $decrypted; }
global: encrypt: keychain
こんな感じで。
コメント
トラックバック - http://subtech.g.hatena.ne.jp/otsune/20070911
