2

サポートされなくなった Python パッケージの代わりに、暗号化に GPG を使用するように更新している古い Python ベースの Web フォームがあります。コマンドラインからスクリプトを呼び出すと問題なく動作しますが、Web ブラウザーと CGI を介してエラーが発生します: IOError: [Errno 32] Broken pipe。このエラーは、gnupg パッケージを使用した場合、またはサブプロセス経由で gpg と直接通信しようとした場合に発生します。

バージョン:

Python 2.4.1 
gnupg 0.2.2 (python GPG wrapper)
Apache/2.2.9 
gpg 1.4.9

簡単なスクリプトを次に示します。

#!/usr/bin/python 

import sys
# send python tracebacks out to the web browser
sys.stderr = sys.stdout
import gnupg
gpg = gnupg.GPG()
gpgkey = 'np'
message = 'Our secret message!'
print "Content-type: text/html\r\n"
print '''<html><head><title>Test GPG access via cgi</title>
          </head><body><pre>'''
print 'message in the clear:'
print message
encrypted = str(gpg.encrypt(message, 'np'))
print 'message encrypted:' 
print encrypted
print '''</pre></body></html>'''sf

上記のスクリプトをコマンド ラインから呼び出すと問題なく実行されますが、CGI から呼び出すと次のエラーが発生します。

message in the clear:
Our secret message!
Traceback (most recent call last):
  File "/home/dkmaster/www/nickads/secure-cgi/gpgtest.py", line 23, in 
    encrypted = str(gpg.encrypt(message, 'np'))
  File "/home/dkmaster/www/nickads/secure-cgi/gnupg.py", line 517, in encrypt
    return self.encrypt_file(StringIO(data), recipients, **kwargs)
  File "/home/dkmaster/www/nickads/secure-cgi/gnupg.py", line 467, in encrypt_file
    self._handle_io(args, file, result, passphrase=passphrase)
  File "/home/dkmaster/www/nickads/secure-cgi/gnupg.py", line 201, in _handle_io
    _copy_data(file, stdin)
  File "/home/dkmaster/www/nickads/secure-cgi/gnupg.py", line 75, in _copy_data
    outstream.write(data)
IOError: [Errno 32] Broken pipe

また、gnupg モジュールではなく、サブプロセスを介して直接 GPG と通信しようとしました。

#!/usr/bin/python

import sys
import subprocess
sys.stderr = sys.stdout
print "Content-type: text/html\r\n"
print '''<html><head><title>Test subprocess via cgi</title>
           </head><body><pre>'''

plain_text = 'the quick fox ' * 10
print plain_text
gpgCommand = "/usr/bin/gpg --quiet -a -e -r 'np' "
gpgProcess = subprocess.Popen(
                      gpgCommand,
                      stdin=subprocess.PIPE, 
                      stdout=subprocess.PIPE, 
                      stderr=subprocess.PIPE, 
                      shell=True
                      )
encrypted_text = gpgProcess.communicate(plain_text)[0]
print encrypted_text

繰り返しますが、これはコマンドラインからは正常に機能しますが、同様のエラーを生成する CGI 経由では機能しません:

Traceback (most recent call last):
  File "/home/dkmaster/www/nickads/secure-cgi/subprocesstest.py", line 20, in 
    encrypted_text = gpgProcess.communicate(plain_text)[0]
  File "/usr/lib/python2.5/subprocess.py", line 670, in communicate
    return self._communicate(input)
  File "/usr/lib/python2.5/subprocess.py", line 1220, in _communicate
    bytes_written = self._write_no_intr(self.stdin.fileno(), buffer(input, input_offset, 512))
  File "/usr/lib/python2.5/subprocess.py", line 999, in _write_no_intr
    return os.write(fd, s)
OSError: [Errno 32] Broken pipe

では、CGI でパイプを修正するにはどうすればよいでしょうか。

4

2 に答える 2

2

答えが遅すぎるかもしれませんが、最近同じ問題が発生し、解決できたと思います。

GPGは、リダイレクトされているstdoutに関係なく、端末にいくつかのもの( "パスフレーズが必要です"blabla)を出力しているようです-方法を聞かないでください:)

ただし、gpgがcgi環境でこれらのメッセージを出力できないためにパイプの破損が発生しているようです(uwsgiで発生します)。--quiet合格した場合は、それらを印刷することもできます。さらにパスした場合にのみ、本当に静かに見えます--batch

于 2010-01-12T22:38:59.897 に答える
0

python-gnupg良い質問です。それが問題なのか、問題なのかさえわかりませんgpgsubprocessこれは、2つの間の相互作用の問題である可能性がありますcgi。標準入力から読み取り、出力をファイルに書き込む非常に最小限のスクリプトでこれを試すとどうなりますか? それは動作しますか?

ログを有効にして、それが何をスローするかを確認することも価値があります。test_gnupg.pyその方法の例については、スクリプトを参照してください。

于 2009-11-25T19:56:01.170 に答える