2016-10-25 5 views
3

CentOS-6.8 Perl, v5.10.1 (*), построенный для x86_64-Linux-нить-мультиКак один обеспечить IPC :: Run с аргументом установленного пользовательского ввода, который содержит встроенный пробельные

Этот вопрос спускается этот Where is the shell command called which invokes OpenSSL commands?. Вкратце, я взламываю очень старый скрипт Perl, используемый для поддержки внутренней частной PKI, так что хэши подписи и размеры ключей по умолчанию соответствуют текущим требованиям браузера.

У меня есть эти фрагменты кода:

. . .  
$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 [& hellip;] или список команд, операций 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 стандартные ввод, стандартный вывод и стандартный поток ошибок.)

Отказ от ответственности: Это, очевидно, все непроверенный кода. Я не эксперт в IPC :: Run, поэтому я, возможно, сделал некоторые глупые синтаксические ошибки команды или другие ошибки. Перед использованием тщательно проконсультируйтесь!

+0

Сложность, которую я испытываю, это все, что мне очень не знакомо. Я взламываю очень старый сторонний скрипт, написанный на языке, на котором я имею только беглые знания; и чей первоначальный автор перешел и отказался от него. Мне нужно было заставить это работать с небольшими изменениями значений по умолчанию для размеров ключей и изменять алгоритмы хеша-подписи для удовлетворения текущих ожиданий. К сожалению, для меня я случайно наткнулся на эту проблему, и я хотел бы получить правильное решение. Легкая обходная процедура просто не использует пропущенную фразу с белым пространством. Но это кажется неправильным. –

+0

@ James.B.Byrne: К сожалению, некоторые части, которые вам нужно изменить, находятся в коде, который вы заменили на '. , .' в вашем вопросе. В частности, существует предположительно вызов IPC :: Run 'start()' где-то там, который вам нужно изменить, чтобы взять ссылку на массив вместо строки. Для этого, вероятно, потребуется, по крайней мере, базовое знакомство с Perl. Если у вас этого нет, ваши выборы в основном 1) возьмите хорошую вводную книгу Perl и узнайте, 2) найдите кого-нибудь, кто знает больше Perl, чем вы, или 3) сдадитесь, документируйте ошибку и перейдите. –

+0

Сначала мне нужно установить нашу замену PKI. На данный момент кажется, что это не будет проблемой, поскольку я, кажется, преодолел или уклонился от контрольно-пропускных пунктов, с которыми я столкнулся. Переписать код для переключения всей программы из аргументов из строки в массив невозможно до тех пор, пока я не найду время, ресурс которого находится в минимальном порядке. Я могу изменить парольную фразу на ключе напрямую, используя openssl, который дает желаемый результат и не позволяет перепрограммировать скрипт - процесс, который, несомненно, откроет другие бородавки. –