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!

5
  • You're using a for loop, not a while loop. Commented Oct 10, 2012 at 3:04
  • 1
    You should look into using subprocess.Popen instead of the now deprecated os.popen Commented Oct 10, 2012 at 3:10
  • Also, does gpg write that to stderr or stdout? Commented Oct 10, 2012 at 3:12
  • Can I use the same string concatenation for subprocess.Popen? Commented Oct 10, 2012 at 3:14
  • Have you considered using pygpgme to handle the decryption rather than directly calling gpg? Commented Oct 10, 2012 at 3:23

3 Answers 3

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():
Sign up to request clarification or add additional context in comments.

Comments

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

10 Comments

I'll be running this on Linux so I don't know if cmd does the same thing for both operating systems.
Traceback (most recent call last): File "decrypter2.py", line 12, in <module> output = subprocess.check_output(cmd) AttributeError: 'module' object has no attribute 'check_output'
That's the error I'm getting now. Sorry if I sound stupid, I'm very new to programming and even newer to python.
(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.
@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.
|
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.

3 Comments

Oops I just copied that out of the python documentation. I'll fix that.
How would the subprocess.call line look after I change 'newstring'?
You don't need all the parameters. I think: 'subprocess.call(newstring, shell=True)' is all you would need.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.