Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

using a pipe

by drock (Beadle)
on Dec 29, 2005 at 20:18 UTC ( #519861=perlquestion: print w/replies, xml ) Need Help??

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

I am using gpg encryption to cat "file" to a pipe which has my passphrase in it to allow decryption to occur. I want to use Perl to do this below :
cat file |gpg --option newfile oldfile
Here is a snippet:
open (PASS, "+<$pass") or warn "was unable to open FH $!"; for (;<PASS>;) { $gpgpass = $_; }
thank you!

Replies are listed 'Best First'.
Re: using a pipe
by Celada (Monk) on Dec 29, 2005 at 20:47 UTC

    I don't quite understand what you are trying to do. In the first code fragment you are doing something with gpg (don't know what it is, it depends on the --option) and in the second fragment you are reading the contents of a file.

    Can you reword this?

    • Where is your passphrase coming from? (your Perl script, a file, or is gpg supposed to prompt for it?)
    • What is supposed to be in the file called file? (the stuff to be decrypted? the passphrase?)
    • Where should the output go? (standard output? your Perl script should collect it?

    That said, you might be interested in gpg's --passphrase-fd option. It allows you to supply the passphrase to gpg over a pipe, and without disturbing any of the stdio channels. It is the most secure option for passing a passphrase to gpg other than letting gpg prompt for it by itself.

      the passphrase is coming from a file on my unix box. gpg needs it as stdin like so: cat file |gpg. the password is in the file being opened or cat'ed. the stdout goes as stdin to the gpg decryption process. I am using the --passphrase-fd 0 option, but you still need to cat the file first.

        OK, so if I understand correctly,

        • The passphrase comes from file
        • The input (ciphertext) is in a file and gpg is given this file on its command line, and
        • The output goes into another file, again directed by a command line option.

        The first thing to notice is that the cat might be unnecesary. In other words,

        cat file | gpg
        should have the same effect as
        gpg <file

        but the second is simpler and eliminates an unnecesary pipeline stage. In either case the contents of file becomes the standard input for gpg. The only reason it would matter is if for some reason gpg really insisted that the passphrase-fd be a pipe.

        If that will do, then you may be able to reduce the whole thing down to something as simple as this:

        # Open the file open(FILE, "<file") || die; # Run gpg # Notice that we are not going to bother to try to # make the file become stdin to gpg. We're just going # to tell gpg which file descriptor it's already # accessible as. system("gpg", "--passphrase-fd=" . fileno(FILE), "--decrypt", "--output", "cleartext-filename", "ciphertext-filename"); close FILE;

        That's the true intent of gpg's passphrase-fd option: to give it a file descriptor for some other file besides the three stdio ones.

Re: using a pipe
by wazzuteke (Hermit) on Dec 29, 2005 at 21:14 UTC
    Sounds like what you are trying to do is take the file contents, returned from the cat bash command, pipe it to gpg to create an un-encrypted password in a new file. At least, that's what the *nix syntax looks like.

    If this is the case, I believe you can do this pretty simply by reading in the file using a standard open() and pipe it to gpg similarly to how you are doing it through your command line.

    #!/usr/bin/perl use strict; use warnings; # First, open the file and read the contents... assuming one line open my $file, 'encrypted_file_name' or die "ERROR:\t$!\n"; my $enc_pass = shift( @{ [ <$file> ] } ); close $file; # Next, pipe the contents to gpg open my $gpg_command, "/usr/bin/gpg --option newfile oldfile | " my $gpg_out; while ( <$gpg_command> ) { $gpg_out .= $_; } close $gpg_command; print "$gpg_out\n"; exit;
    Given the syntax of your command line interface to gpg, this should do the exact same thing, though via perl.

    NOTE: I didn't test this being that I don't know what you are really trying to do here. This is really more of an idea seed that will start pointing you in the right direction!

    Good luck!!

    print map{$_.' '}grep{/\w+/}@{[reverse(qw{Perl Code})]} or die while ( 'trying' );
      not exactly... what I am doing is cating a file that has the clear text passphrase in it then piping this output as inout to the gpg binary for decryption like so:
      cat file |gpg --passphrase-fd 0 --decrypt --output oldfile newfile
      I do not understand what
      my $enc_pass = shift( @{ [ <$file> ] } );
      is doing? Is this the same as:
      for (;<FH>;) { print $_; }
      what does $gpg_out have in it?
        Sorry for the confusion:

        my $enc_pass = shift ( @{ [ <$file> ] } );
        Will simply take the first line within the file, whose handle is stored in the $file variable, treat the handle like a listed de-referenced array-ref and shift that first line into the $enc_pass variable.

        For example, if your file contains:
        when you:
        print $enc_pass;
        you will get the output:
        For $gpg_out, that is the handle to the command line gpg call. Another method of this would be to use backticks such as:
        my $gpg_output = `gpg --passphrase-fd 0 --decrypt --output oldfile new +file`;
        Simply enough, the backticks will automagically run the command specified, giving the output back to the $gpg_output variable.

        Hope this all clarifies!

        print map{$_.' '}grep{/\w+/}@{[reverse(qw{Perl Code})]} or die while ( 'trying' );

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://519861]
Approved by been42
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (5)
As of 2023-05-31 15:58 GMT
Find Nodes?
    Voting Booth?

    No recent polls found