2016-10-25 9 views
3

のCentOS-6.8のperlが含まれているユーザの入力によって設定された引数でIPC :: Run]を提供しない、v5.10.1(*)はx86_64-linuxのスレッドのマルチがどのように埋め込まれた空白に

のために構築されたこの質問はから下降しますこの1つWhere is the shell command called which invokes OpenSSL commands?。簡単に私は内部プライベートPKIを維持するために使用される非常に古いPerlスクリプトをハックして、デフォルトの署名ハッシュとキーサイズが現在のブラウザ要件を満たすようにしています。ユーザーが提供するパスワード引数の値は、必要に応じて、このコードが実行、その後に空白が含まれていない場合

. . .  
$args->{keypass} = $self->getPassword("Private key password",1) 
    unless $args->{keypass};  
$self->warn("# Password argument: $args->{keypass}\n") if $ENV{CSPDEBUG}; 
my $cmd = "-out $args->{keyfile} $args->{keysize}"; 
$cmd = "-des3 -passout pass:$args->{keypass} ".$cmd if defined($args->{keypass}); 
$self->{openssl}->cmd('genrsa',$cmd,$args); 
. . . 
$self->{openssl}->cmd('req',"-x509 $common_args -new -out $cacert",$args); 
. . . 
use IPC::Run qw(start pump finish timeout new_appender new_chunker); 
. . . 
sub cmd 
    { 
    my $self = shift; 
    my $cmd = shift; 
    my $cmdline = shift; 
    my $args = shift; 
    my $conf; 
    my $cfgcmd; 
. . . 
    $self->{_handle}->pump while length ${$self->{_in}}; 
. . . 

は、私はこれらのコードスニペットを持っています。埋め込み空白が含まれている場合、コードは自動的に失敗します。 keypassに渡された引数が開始シングルクォートと終了シングルクォートで連結されている場合、コードは同様にサイレントに失敗します。どちらの失敗の場合でも、スクリプトは成功を報告します。

なぜですか?

ユーザー入力にスペースが含まれているかどうかにかかわらず、このコードを変更するために必要な変更はありますか?

+0

私はちょうど正しい質問を得ることができます、それは動作するようにパスワードフィールドから空白を排除しようとしていますか?パスワードに空白があっても動作させるには?前の質問とここの説明の –

+0

@ user2082599には、パスワードに空白が含まれている可能性があります。そうであれば、プログラムは失敗します。これは、コマンドライン引数で空白が失われるためです。引用しても機能しません。 – simbabque

+0

@Jamesあなたは引数のどれがパスワードであるかを強調表示できますか?それは私には分かりません。 – simbabque

答えて

1

quote the IPC::Run manualてみましょう、あなたのリテラルの質問に答えるために:

run()start()、およびharness()は、すべての入力としてのハーネス仕様を取ることができますハーネスの仕様は、システムに渡される単一の文字列のいずれかです。 'shell […]または実行するコマンド、IO操作、および/またはタイマー/タイムアウトのリスト。

コマンド引数がシェルによって解析されないようにするには(引数に空白が含まれていると何かが壊れてしまう)、単一の文字列として渡すのではなく、単一の文字列として、個々の引数は、このような何か:

my @cmd = ("-out", $args->{keyfile}, $args->{keysize}); 
unshift @cmd, ("-des3", "-passout", "pass:$args->{keypass}") if defined $args->{keypass}; 
# ... 
my $h = start ["openssl", "genrsa", @cmd], \$in, \$out; # or something equivalent 

は(あなたが投稿したコードは、いくつかのカスタムインターフェース層を介してIPC :: Run]を使用しているように見える。あなたは私たちがまさにその示していないので、レイヤはIPC :: Run :: startの簡単な呼び出しで置き換えられました。


いずれの場合でも、コマンドラインでのパスワードの受け渡しは一般的に安全ではないと考えられます。信頼できないユーザーが(特権のないアカウントであっても)同じサーバー上でコードを実行できる場合は、ps axを実行するだけでパスワードを見ることができます。 openssl manualはこれに注意し、pass:passwordは "セキュリティは重要でない場合にのみ使用するべきです"と警告しています。

より安全な代替方法はsend the password over a separate file descriptorです。都合の良いことに、IPC :: Runはこれを簡単にします:

my @cmd = ("-out", $args->{keyfile}, $args->{keysize}); 
unshift @cmd, ("-des3", "-passout", "fd:3") if defined $args->{keypass}; 
# ... 
my $h = start ["openssl", "genrsa", @cmd], '<', \$in, '>', \$out, '3<', \$args->{keypass}; 

ここで、パスワードはファイル記述子番号3に渡されます。複数のパスワードを渡す必要がある場合は、ファイル記述子4,5などを使用できます。 (記述子0、1、2が標準入力され、stdoutとstderr)

免責事項:これは、明らかに、すべてのテストされていないコードです。私はIPC :: Runの専門家ではないので、いくつかばかげたコマンド構文エラーやその他の間違いを犯しているかもしれません。使用する前に十分にテストしてください!

+0

私が持っている難しさは、私には全く馴染みのないことです。私は非常に古い第三者のスクリプトをハッキングしていますが、その言語で書かれているのは私だけの知識しかありません。元の著者は移ってそれを放棄した。私は鍵サイズのデフォルト値を少し変更して動作させ、現在の期待に合うように署名ハッシュアルゴリズムを変更する必要がありました。私にとっては残念なことに、私はこの問題を偶然見つけて、適切な解決策を得たいと思っています。簡単な回避策は、単純にホワイトスペースでパスフレーズを使用しないことです。しかし、それは間違っているようです。 –

+0

@ JamesB.Byrne:残念ながら、あなたが修正する必要がある部分のいくつかは、あなたが 'に置き換えられたコードにあります。 。あなたの質問で。具体的には、IPC :: Run 'start()'コールがあるかもしれませんが、文字列ではなく配列参照を使用するように変更する必要があります。おそらくPerlには少なくとも基本的な知識が必要です。もしあなたがそれを持っていなければ、あなたの選択は基本的には1)良い入門Perlの本を手に入れて学ぶこと、2)Perlを知っている人を見つけること、3)あきらめること、 –

+0

最初に私は交換用のPKIを確立する必要があります。現時点では、私は遭遇した障害物を乗り越えたり避けたりしているように見えるので、これは問題ではないようです。プログラム全体を文字列から配列引数に切り替えるためのコードの書き換えは、時間が見つかるまで可能ではありません。リソースはわずかな量で提供されています。 opensslを使用してキーのパスフレーズを直接変更することができます。これは、スクリプトを再プログラムする必要がなくなり、他の疣贅を明らかにするプロセスです。 –

関連する問題