Config::Pit、すごい便利だなーと思いつつも、でも平文なんだよな、パスワードとか保存するのイヤだなーと思ってて、ずっと躊躇していたんだけど、やっぱり使いたいので暗号化することにしました。
とりあえずRC4で。根本的な解決ではないけど、平文で保存するよりはずっと安心感あるかなと。
参考:Crypt::RC4を使ってみる - XXXannex
package Config::Pit::RC4; use strict; use warnings; use Crypt::RC4; use base qw(Config::Pit Exporter); our @EXPORT = qw/pit_get pit_set pit_switch/; our $passphrase = 'password'; our $set_done = 0; *pit_get = \&get; *pit_set = \&set; *pit_switch = \&switch; sub get { my ($name, %opts) = @_; my $config; # override Config::Pit::set and call original get { no warnings 'redefine'; my $org_method = Config::Pit->can('set'); *Config::Pit::set = sub {$set_done=1; &$org_method(@_)}; $config = Config::Pit::get($name, %opts); *Config::Pit::set = $org_method; } # non-crypted if($set_done){ my $profile = Config::Pit::_load(); $profile->{$name}->{$_} = encrypt($profile->{$name}->{$_}) foreach (keys %{$profile->{$name}}); YAML::Syck::DumpFile($Config::Pit::profile_file, $profile); } # crypted else{ $config->{$_} = decrypt($config->{$_}) foreach (keys %$config); } return $config; } sub set { my ($name, %opts) = @_; my $config = Config::Pit::set($name, %opts); my $profile = Config::Pit::_load(); $profile->{$name}->{$_} = encrypt($profile->{$name}->{$_}) foreach (keys %{$profile->{$name}}); YAML::Syck::DumpFile($Config::Pit::profile_file, $profile); return $config; } sub encrypt{ my $plaintext = shift; my $encrypted = RC4($passphrase, $plaintext); $encrypted =~ s/(.)/unpack('H2', $1)/eg; return $encrypted; } sub decrypt{ my $encrypted = shift; $encrypted =~ s/([0-9A-Fa-f]{2})/pack('H2', $1)/eg; my $decrypted = RC4($passphrase, $encrypted); return $decrypted; }
use strict; use warnings; use Config::Pit::RC4; my $config_g = pit_get("get_test", require => { username => "foobar", password => "barbaz", }); my $config_s = pit_set("set_test", data => { username => "foobar", password => "barbaz", }); ### $config_g ### $config_s
実行結果
### $config_g: { ### password => 'barbaz', ### username => 'foobar' ### } ### $config_s: { ### password => 'barbaz', ### username => 'foobar' ### }
$ cat ~/.pit/default.yaml --- get_test: password: 9d944a6c2d44 username: 999a576c2d4c set_test: password: 9d944a6c2d44 username: 999a576c2d4c
Config::Pitが継承に対応してくれていればもう少しきれいに書けるのかもしれないけど、とりあえず目的は果たされた。
基本的に、「まずはオリジナルを呼んで、その後暗号化/復号化する」というアレな実装です。getの中で、パスワードが未設定だとsetを呼んで設定する部分があるので、若干めんどくさい感じに。