byrnejb has asked for the wisdom of the Perl Monks concerning the following question:

I am hacking at an old perl scrip that is used to generate and maintain a private CA. The script contains this code:

. . . 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; if ( (grep $_ eq $cmd,qw(req ca)) && !$args->{noconfig}) { $conf = $self->{csp}->writeConfig($cmd,$args); $self->{csp}->die("Unable to write configuration file") unless -f $c +onf; $cfgcmd = " -config $conf "; } elsif ($cmd eq 'x509' && !$args->{noconfig}) { $conf = $self->{csp}->writeConfig($cmd,$args); $self->{csp}->die("Unable to write configuration file") unless -f $c +onf; $cfgcmd = " -extfile $conf -extensions extensions "; } $cmd = '' if $cmd eq 'dummy'; ${$self->{_in}} = "$cmd $cfgcmd $cmdline"; if ($ENV{CSPDEBUG}) { $self->warn("Here I am"); $self->warn("# openssl $cmd $cfgcmd $cmdline\n"); } $self->{_handle}->pump while length ${$self->{_in}}; $self->{_handle}->finish; . . .
When I run this command
csp CA_HLL_ROOT_2016 init --verbose --type=root --keysize=4096 --days= +7317 --url=ca.harte-lyne.ca --email=certificates@harte-lyne.ca --dige +st=sha512 "CN=CA_HLL_ROOT_2016,OU=Networked Data Services,O=Harte & L +yne Limited,L=Hamilton,ST=Ontario,C=CA,DC=harte-lyne,DC=ca"
then I get this result:
[CSP][ ] Here I am [CSP][ ] # openssl genrsa -des3 -passout pass:'test me' -out / +home/byrnejb/Projects/Software/rcsp/ca_test_a/csp/CA_HLL_ROOT_2016/pr +ivate/ca.key 4096 [CSP][ ] Here I am [CSP][ ] # openssl req -config /home/byrnejb/Projects/Software +/rcsp/ca_test_a/csp/CA_HLL_ROOT_2016/tmp/csp-32489.conf -x509 -sha51 +2 -days 7317 -key /home/byrnejb/Projects/Software/rcsp/ca_test_a/csp +/CA_HLL_ROOT_2016/private/ca.key -passin pass:'test me' -new -out /ho +me/byrnejb/Projects/Software/rcsp/ca_test_a/csp/CA_HLL_ROOT_2016/ca.c +rt

There are no errors but the files specified in the command lines are not created. If I copy and paste the command lines that are output from the warn statements then the files are created without problem.

I have zero experience with Perl. Well, not quite zero any more but not much. Is there something obvious that I am missing here? The entire project is available on github at https://github.com/byrnejb/rcsp/tree/csp040 if more context is desired.

Replies are listed 'Best First'.
Re: IPC::Run command is correctly constructed but does not have effect
by byrnejb (Initiate) on Oct 25, 2016 at 18:31 UTC
    I have this pinned down to this line:
    422 $args->{keypass} = "'" . $self->getPassword("Private key passwor +d",1) . "'"

    If the "'" concatenations are removed and a pass phrase without spaces is entered then the openssl commands execute from the script. If spaces are used then the command fails. If the password input is escaped with ' ' then the command simply does not execute from the script but does from the command line.

    How do I allow private key pass-phrases to contain blanks and still get the script to operate?

      Whatever is building the command line is doing it wrong:

      -passin pass:'test me'

      ... should likely be

      -passin 'pass:test me'

      For example, the following line building some command line will also not deal well with spaces in your password:

      $cmd = "-des3 -passout pass:$args->{keypass} ".$cmd if defined($args-> +{keypass});

      Also, this line:

      my $common_args = "-$args->{digest} -days $args->{days} ". " -key $cakey -passin pass:$args->{keypass}";

      As a general rule, if it doesn't work on the command line/shell prompt, there is very little that IPC::Run can do to make it work either.