Update of /cvsroot/mahogany/M/src/modules/crypt
In directory sc8-pr-cvs1:/tmp/cvs-serv428a/src/modules/crypt
Modified Files:
PGPEngine.cpp
Log Message:
some work on PGPEngine::Decrypt() -- it works sporadically, something is
still very wrong but hopefully we're on the right track
Index: PGPEngine.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/modules/crypt/PGPEngine.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -b -u -2 -r1.1 -r1.2
--- PGPEngine.cpp 3 Dec 2002 00:00:25 -0000 1.1
+++ PGPEngine.cpp 3 Dec 2002 02:52:09 -0000 1.2
@@ -30,4 +30,6 @@
#include "modules/MCrypt.h"
+#include <wx/file.h>
+#include <wx/textfile.h>
#include <wx/process.h>
#include <wx/txtstrm.h>
@@ -139,6 +141,5 @@
public:
// implement the base class pure virtuals
- virtual int Decrypt(const String& user,
- const String& messageIn,
+ virtual int Decrypt(const String& messageIn,
String& messageOut);
@@ -159,5 +160,7 @@
Executes the tool with messageIn on stdin and puts stdout into messageOut
*/
- int ExecCommand(const String& messageIn, String& messageOut);
+ int ExecCommand(const String& options,
+ const String& messageIn,
+ String& messageOut);
private:
@@ -451,25 +454,56 @@
0x04 = this attribute packet is expired
*/
+
+class PGPProcess : public wxProcess
+{
+public:
+ PGPProcess() { m_done = false; Redirect(); }
+
+ virtual void OnTerminate(int /* pid */, int /* status */)
+ {
+ m_done = true;
+ }
+
+ bool IsDone() const { return m_done; }
+
+private:
+ bool m_done;
+};
+
int
-PGPEngine::ExecCommand(const String& messageIn, String& messageOut)
+PGPEngine::ExecCommand(const String& options,
+ const String& messageIn,
+ String& messageOut)
{
- wxProcess *process = wxProcess::Open
+ PGPProcess process;
+ long pid = wxExecute
(
wxString::Format
(
- "%s --status-fd=2",
- "G:\\Internet\\PGP\\GPG-1.2.1\\gpg.exe" // TODO
- )
+ "%s --status-fd=2 --command-fd 0 --output - -a %s",
+ "G:\\Internet\\PGP\\GPG-1.2.1\\gpg.exe", // TODO
+ options.c_str()
+ ),
+ wxEXEC_ASYNC,
+ &process
);
- if ( !process )
+
+ if ( !pid )
{
return CANNOT_EXEC_PROGRAM;
}
- process->GetOutputStream()->Write(messageIn.c_str(), messageIn.length());
- process->CloseOutput();
+ // if we have data to write to PGP stdin, do it
+ wxOutputStream *in = process.GetOutputStream();
+ CHECK( in, CANNOT_EXEC_PROGRAM, _T("where is PGP subprocess stdin?") );
- wxInputStream *out = process->GetInputStream(),
- *err = process->GetErrorStream();
+ if ( !messageIn.empty() )
+ {
+ in->Write(messageIn.c_str(), messageIn.length());
+ process.CloseOutput();
+ }
+
+ wxInputStream *out = process.GetInputStream(),
+ *err = process.GetErrorStream();
wxTextInputStream errText(*err);
@@ -477,16 +511,16 @@
Status status = MAX_ERROR;
+ // the user hint and the passphrase
+ String user,
+ pass;
+
messageOut.clear();
char buf[4096];
- bool outEof = false,
- errEof = false;
- while ( !outEof && !errEof )
+ while ( !process.IsDone() )
{
- if ( out->GetLastError() == wxSTREAM_EOF )
- {
- outEof = true;
- }
- else if ( out->CanRead() )
+ wxYield();
+
+ if ( out->CanRead() )
{
buf[out->Read(buf, WXSIZEOF(buf)).LastRead()] = '\0';
@@ -495,9 +529,5 @@
}
- if ( err->GetLastError() == wxSTREAM_EOF )
- {
- errEof = true;
- }
- else if ( err->CanRead() )
+ if ( err->CanRead() )
{
String line = errText.ReadLine();
@@ -505,5 +535,6 @@
{
String code;
- for ( const char *pc = line.c_str(); !isspace(*pc); pc++ )
+ const char *pc;
+ for ( pc = line.c_str(); *pc && !isspace(*pc); pc++ )
{
code += *pc;
@@ -512,7 +543,7 @@
if ( code == _T("GOODSIG") ||
code == _T("VALIDSIG") ||
- code == _T("SIG_ID") )
+ code == _T("SIG_ID") ||
+ code == _T("DECRYPTION_OKAY") )
{
- // signature checked ok
status = OK;
}
@@ -539,4 +570,72 @@
// TODO: something
}
+ else if ( code == _T("USERID_HINT") )
+ {
+ // skip the key id
+ for ( pc++; *pc && !isspace(*pc); pc++ )
+ ;
+
+ // remember the user
+ user = ++pc;
+ }
+ else if ( code == _T("NEED_PASSPHRASE") )
+ {
+ if ( user.empty() )
+ {
+ FAIL_MSG( _T("got NEED_PASSPHRASE without USERID_HINT?") );
+
+ user = _("default user");
+ }
+
+ if ( !PassphraseManager::Get(user, pass) )
+ {
+ status = OPERATION_CANCELED_BY_USER;
+
+ process.CloseOutput();
+
+ break;
+ }
+
+ String pass2 = pass;
+ pass2 += wxTextFile::GetEOL();
+
+ in->Write(pass2.c_str(), pass2.length());
+ }
+ else if ( code == _T("GOOD_PASSPHRASE") )
+ {
+ PassphraseManager::Unget(user, pass);
+ }
+ else if ( code == _T("BAD_PASSPHRASE") )
+ {
+ wxLogWarning(_("The passphrase you entered was invalid."));
+ }
+ else if ( code == _T("MISSING_PASSPHRASE") )
+ {
+ wxLogWarning(_("Passphrase for the user \"%s\" unavailable."),
+ user.c_str());
+ }
+ else if ( code == _T("NO_SECKEY") )
+ {
+ wxLogWarning(_("Secret key for the user \"%s\" not available."),
+ user.c_str());
+ }
+ else if ( code == _T("DECRYPTION_FAILED") )
+ {
+ status = DECRYPTION_ERROR;
+ }
+ else if ( code == _T("GET_BOOL") ||
+ code == _T("GET_LINE") ||
+ code == _T("GET_HIDDEN") )
+ {
+ // TODO: give gpg whatever it's asking for, otherwise
+ // we'd deadlock!
+ }
+ else if ( code == _T("ENC_TO") ||
+ code == _T("BEGIN_DECRYPTION") ||
+ code == _T("END_DECRYPTION") ||
+ code == _T("GOT_IT") )
+ {
+ // ignore these
+ }
else
{
@@ -559,11 +658,26 @@
int
-PGPEngine::Decrypt(const String& user,
- const String& messageIn,
+PGPEngine::Decrypt(const String& messageIn,
String& messageOut)
{
- FAIL_MSG( _T("TODO") );
+ // as wxExecute() doesn't allow redirecting anything but stdin/out/err we
+ // have no way to pass both the encrypted data and the passphrase to PGP on
+ // the same stream -- and so we must use a temp file :-(
+ MTempFileName tmpfname;
+ bool ok = tmpfname.IsOk();
+ if ( ok )
+ {
+ wxFile file(tmpfname.GetName(), wxFile::write);
+ ok = file.IsOpened() && file.Write(messageIn);
+ }
- return NOT_IMPLEMENTED_ERROR;
+ if ( !ok )
+ {
+ wxLogError(_("Can't pass the encrypted data to PGP."));
+
+ return CANNOT_EXEC_PROGRAM;
+ }
+
+ return ExecCommand(tmpfname.GetName(), _T(""), messageOut);
}
@@ -599,5 +713,5 @@
String& messageOut)
{
- return ExecCommand(messageIn, messageOut);
+ return ExecCommand(_T(""), messageIn, messageOut);
}
-------------------------------------------------------
This SF.net email is sponsored by: Get the new Palm Tungsten T
handheld. Power & Color in a compact size!
http://ads.sourceforge.net/cgi-bin/redirect.pl?palm0002en
_______________________________________________
Mahogany-cvsupdates mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates