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

Reply via email to