Problem with my pipes

Discussion related to AES Crypt, the file encryption software for Windows, Linux, Mac, and Java.
Post Reply
gsayers
Posts: 3
Joined: Wed Jul 17, 2013 7:29 am

Problem with my pipes

Post by gsayers »

Yes, I know we all get problems like this when we get older, but this problem is of the "C" kind ;) .

I am using MinGW on Windows7 cross platform development tool and was planning to shell out from my console program to console Aescrypt to decrypt a file and re-encrypt it with a new password.

I can do this successfully as two "shells" with an intermediate unencrypted file, but for obvious reasons would prefer not to have anything like that hanging around to clean up. I tested pipes using the command line to see if I could pipe the output from the decryption into the input file of the encryption using STD In and STD OUT.

Combining two examples from the AEScrypt manual, on the windows command line this worked fine with the syntax:

Code: Select all

AEScrypt -d -p pswd1 -o -  infile1 | AEScrypt -e -p pswd2 - >outfile1
However, when I try to do this programmatically, I run into problems with the way AEScrypt seems to be interpreting this set of commands. In my code, the left-hand side of the pipe directive in the command line above is stored in cmd1, and the right-hand side in cmd2.

When I invoke my function the console gives the error:-

Code: Select all

Error writing decrypted block:: Invalid argument
After quite a bit of trawling for clues I found that pipe and redirection commands need to be escaped otherwise they are dropped by the command interpreter.
However, When I try escaping the redirection with a caret (ie: ^>outfile) or with escaped brackets (single and double) I get the additional error:-

Code: Select all

Error: STDIN may not be specified with multiple input files.
usage: aescrypt {-e|-d} [-p <password>] { [-o <output filename>] <file> | <file> [<file> ...] }
Error writing decrypted block:: Invalid argument
Note that in the AEScrypt source I have located the message "Error writing decrypted block:". So I must assume that the shell is appending ": Invalid argument", because I cannot find it anywhere in the source.

After execution, the output file contains the three AES headers only, no data is written, so it is getting as far as trying to process the first block to STD OUT. I have tried changing my block size to match or exceed the block size AES reads, but no luck with that either.

I appreciate this may well be a function of the way that the shell is (mis?)treating my parameters, but was wondering if you may be able to give me some clues as to what I'm doing wrong.

My function (tested with ls piped to SORT) is below:

Code: Select all

#include <stdio.h>
int pipe2pipe(char *cmd1, char *cmd2)
{
// -----------------------------------------------------------------------------
// Open two pipes allowing output from one command to be input to the other
// -----------------------------------------------------------------------------
        FILE *pipein_fp, *pipeout_fp;
        char readbuf[MAX_PIPE_BUFF];
        long bytes;

       
//     create one-way pipe for input
         if (( pipein_fp = popen(cmd1, "r")) == NULL)
        {
                perror("popen");
                return(1);
        }

//     create one-way pipe for output

        if (( pipeout_fp = popen(cmd2, "w")) == NULL)
        {
                perror("popen");
                return(2);
        }

//     Get input buffer and write it to the output pipe
         while( (bytes=fread(readbuf,sizeof(readbuf),1,pipein_fp))>0)
        {
               fwrite(readbuf,bytes,1,pipeout_fp);
        }

//     Clean up
        pclose(pipein_fp);
        pclose(pipeout_fp);

        return(0);
}
By the way, thanks for providing the community with such a useful tool :D .

Regards,
Gary
Last edited by gsayers on Thu Jul 18, 2013 12:03 am, edited 1 time in total.
User avatar
paulej
Posts: 593
Joined: Sun Aug 23, 2009 7:32 pm
Location: Research Triangle Park, NC, USA
Contact:

Re: Problem with my pipes

Post by paulej »

Gary,

If you know the names of the input and output files, why would you use "> %outfile1%", for example?

Why not set cmd1 to be this?

Code: Select all

aescrypt -d -p PASSWORD1 -o - INPUT_FILE
Where PASSWORD1 and INPUT_FILE are the actual password and input file.

Likewise, I would set cmd2 to be this:

Code: Select all

aescrypt -e -p PASSWORD2 -o OUTPUT_FILE -
If you want to use %pswd1% environment variables, I guess that will not hurt. One of these days, though, I need to port over the -k command to avoid having to pass environment variables like this.

In any case, I would assume the problem has to do with using ">" (and "<" if you were using it) in popen().
Post Reply