1
import os

dictionaryfile = "/root/john.txt"
pgpencryptedfile = "helloworld.txt.gpg"

array = open(dictionaryfile).readlines()


for x in array:
    x = x.rstrip('\n')
    newstring = "echo " + x + " | gpg --passphrase-fd 0 " + pgpencryptedfile
    os.popen(newstring)

I need to create something inside the for loop that will read gpg's output. When gpg outputs this string gpg: WARNING: message was not integrity protected, I need the loop to close and print Success!

How can I do this, and what is the reasoning behind it?

Thanks Everyone!

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72

3 Answers3

1

Use subprocess.check_output to call gpg and break the loop based on its output.

Something like this (untested since I don't know anything about gpg):

import subprocess

dictionaryfile = "/root/john.txt"
pgpencryptedfile = "helloworld.txt.gpg"

with open(dictionaryfile, 'r') as f:
    for line in f:
        x = line.rstrip('\n')
        cmd = ["echo " + x + " | gpg --passphrase-fd 0 " + pgpencryptedfile]
        output = subprocess.check_output(cmd, shell=True)
        if 'gpg: WARNING: message was not integrity protected' in output:
            break
Matthew Adams
  • 9,426
  • 3
  • 27
  • 43
  • I'll be running this on Linux so I don't know if cmd does the same thing for both operating systems. – user1732102 Oct 10 '12 at 03:33
  • Traceback (most recent call last): File "decrypter2.py", line 12, in output = subprocess.check_output(cmd) AttributeError: 'module' object has no attribute 'check_output' – user1732102 Oct 10 '12 at 03:34
  • That's the error I'm getting now. Sorry if I sound stupid, I'm very new to programming and even newer to python. – user1732102 Oct 10 '12 at 03:35
  • (You don't, but no worries anyway.) Hmm, that seems to say that `check_output` is not defined in `subprocess`. But it is... Try opening an interpreter and running `import subprocess` then `subprocess.check_output(['ls'])` and see if that gives you the same error. – Matthew Adams Oct 10 '12 at 03:46
  • 1
    @user1732102 -- `subprocess.check_output` was added in python version 2.7. If you're working with an older version, that would explain why you don't have it. – mgilson Oct 10 '12 at 11:02
  • I installed python2.7.3. After running the script then, I got this error. Traceback (most recent call last): File "decrypter2.py", line 12, in output = subprocess.check_output(cmd) File "/usr/local/lib/python2.7/subprocess.py", line 537, in check_output process = Popen(stdout=PIPE, *popenargs, **kwargs) File "/usr/local/lib/python2.7/subprocess.py", line 679, in __init__ errread, errwrite) File "/usr/local/lib/python2.7/subprocess.py", line 1249, in _execute_child raise child_exception OSError: [Errno 2] No such file or directory – user1732102 Oct 10 '12 at 23:47
  • Dumb question: do `/root/john.txt` and `helloworld.txt.gpg` actually exist in those locations? – Matthew Adams Oct 10 '12 at 23:54
  • Yes sir. Both those files exist where they are. – user1732102 Oct 11 '12 at 00:02
  • I think the code that you came up with is going to work the best, I just don't know what all these errors I'm getting are from. – user1732102 Oct 11 '12 at 00:13
  • Hmm... I'm not sure what's going on just from the error message then... Can you post small example files in your question for me to try out? (Also, I just changed the `open` call a bit, but it shouldn't make a difference.) – Matthew Adams Oct 11 '12 at 05:45
1
import subprocess


def check_file(dictfile, pgpfile):
    # Command to run, constructed as a list to prevent shell-escaping accidents
    cmd = ["gpg", "--passphrase-fd", "0", pgpfile]

    # Launch process, with stdin/stdout wired up to `p.stdout` and `p.stdin`
    p = subprocess.Popen(cmd, stdin = subprocess.PIPE, stdout = subprocess.PIPE)

    # Read dictfile, and send contents to stdin
    passphrase = open(dictfile).read()
    p.stdin.write(passphrase)

    # Read stdout and check for message
    stdout, stderr = p.communicate()
    for line in stdout.splitlines():
        if line.strip() == "gpg: WARNING: message was not integrity protected":
            # Relevant line was found
            return True

    # Line not found
    return False

Then to use:

not_integrity_protected = check_file("/root/john.txt", "helloworld.txt.gpg")
if not_integrity_protected:
    print "Success!"

If the "gpg: WARNING:" message is actually on stderr (which I would suspect it is), change the subprocess.Popen line to this:

p = subprocess.Popen(cmd, stdin = subprocess.PIPE, stderr = subprocess.PIPE)

..and the for loop from stdout to stderr, like this:

for line in stderr.splitlines():
dbr
  • 165,801
  • 69
  • 278
  • 343
0

You could use the subprocess module which allows you to use:

subprocess.call(args, *, stdin, stdout, stderr, shell)

(See the Python Documentation for how to use the parameters.)

This is good because you can easily read in the exit code of whatever program you call.

For example if you change 'newstring' to:

"echo " + x + " | gpg --passphrase-fd 0 " + pgpencryptedfile | grep 'gpg: WARNING: message was not integrity protected'

grep will then return 0 if there is a match and a 1 if not matches are found. (Source)

This exit code from grep will be returned from the subprocess.call() function and you can easily store it in a variable and use an if statement.

Edit: As Matthew Adams mentions below, you could also read the exit code of gpg itself.

Sean Dawson
  • 5,587
  • 2
  • 27
  • 34