Many more cleanups. MapiGPGME has gone.
authorWerner Koch <wk@gnupg.org>
Fri, 26 Aug 2005 08:09:02 +0000 (08:09 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 26 Aug 2005 08:09:02 +0000 (08:09 +0000)
18 files changed:
src/ChangeLog
src/Makefile.am
src/MapiGPGME.cpp [deleted file]
src/MapiGPGME.h [deleted file]
src/display.cpp [new file with mode: 0644]
src/display.h [new file with mode: 0644]
src/engine-gpgme.c
src/engine.h
src/gpgmsg.cpp
src/gpgmsg.hh
src/intern.h
src/main.c
src/mymapitags.h
src/olflange-def.h
src/olflange-dlgs.cpp
src/olflange.cpp
src/outlgpg.def
src/util.h

index 420bbeb..c7cc142 100644 (file)
@@ -1,3 +1,8 @@
+2005-08-26  Werner Koch  <wk@g10code.com>
+
+       * MapiGPGME.cpp, MapiGPGME.h: Removed.
+       * display.cpp, display.h: New. 
+
 2005-08-23  Werner Koch  <wk@g10code.com>
 
        * msgcache.c, msgcache.h: New.
index 5e4ed23..48ad0c7 100644 (file)
@@ -28,7 +28,7 @@ outlgpg_SOURCES = \
        olflange-dlgs.cpp           \
        olflange-ids.h              \
        myexchext.h                 \
-       MapiGPGME.cpp MapiGPGME.h   \
+       display.cpp display.h       \
        gpgmsg.cpp gpgmsg.hh        \
        msgcache.c msgcache.h       \
         engine-gpgme.c engine.h    \
diff --git a/src/MapiGPGME.cpp b/src/MapiGPGME.cpp
deleted file mode 100644 (file)
index ade8bb8..0000000
+++ /dev/null
@@ -1,1086 +0,0 @@
-/* MapiGPGME.cpp - Mapi support with GPGME
- *     Copyright (C) 2005 g10 Code GmbH
- *
- * This file is part of OutlGPG.
- * 
- * OutlGPG is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- * 
- * OutlGPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <windows.h>
-#include <time.h>
-#include <assert.h>
-#include <string.h>
-
-#ifdef __MINGW32__
-# include "mymapi.h"
-# include "mymapitags.h"
-#else /* !__MINGW32__ */
-# include <atlbase.h>
-# include <mapidefs.h>
-# include <mapiutil.h>
-# include <initguid.h>
-# include <mapiguid.h>
-#endif /* !__MINGW32__ */
-
-#include "gpgme.h"
-#include "keycache.h"
-#include "intern.h"
-#include "HashTable.h"
-#include "MapiGPGME.h"
-#include "engine.h"
-
-
-/* Attachment information. */
-#define ATT_SIGN(action) ((action) & GPG_ATTACH_SIGN)
-#define ATT_ENCR(action) ((action) & GPG_ATTACH_ENCRYPT)
-#define ATT_PREFIX ".pgpenc"
-
-#define DEFAULT_ATTACHMENT_FORMAT GPG_FMT_CLASSIC
-
-
-/* default extension for attachments */
-#define EXT_MSG "pgp"
-#define EXT_SIG "sig"
-
-
-
-/* Given that we are only able to configure one log file, it does not
-   make much sense t bind a log file to a specific instance of this
-   class. We use a global variable instead which will be set by any
-   instance.  The same goes for the respecive file pointer and the
-   enable_logging state. */
-static char *logfile;
-static FILE *logfp;
-static bool enable_logging;
-
-/* For certain operations we need to acquire a log on the logging
-   functions.  This lock is controlled by this Mutex. */
-static HANDLE log_mutex;
-
-
-static int lock_log (void);
-static void unlock_log (void);
-
-
-static HWND find_message_window (HWND parent, GpgMsg *msg);
-static void log_key_info (MapiGPGME *g, const char *prefix,
-                          gpgme_key_t *keys, gpgme_key_t locusr);
-
-
-
-
-
-/*
-   The implementation class of MapiGPGME.  
- */
-class MapiGPGMEImpl : public MapiGPGME
-{
-public:    
-  MapiGPGMEImpl () 
-  {
-    clearConfig ();
-    clearObject ();
-    this->passCache = new HashTable ();
-    op_init ();
-    prepareLogging ();
-    log_debug ("MapiGPGME.constructor: ready\n");
-  }
-
-  ~MapiGPGMEImpl ()
-  {
-    unsigned int i=0;
-
-    log_debug ("MapiGPGME.destructor: called\n");
-    op_deinit ();
-    xfree (defaultKey);
-    log_debug ("hash entries %d\n", passCache->size ());
-    for (i = 0; i < passCache->size (); i++) 
-      {
-       cache_item_t t = (cache_item_t)passCache->get (i);
-       if (t != NULL)
-          cache_item_free (t);
-      }
-    delete passCache; 
-    passCache = NULL;
-  }
-
-  void __stdcall destroy ()
-  {
-    delete this;
-  }
-
-  void operator delete (void *p) 
-  {
-    ::operator delete (p);
-  }  
-
-  
-public:
-  const char * __stdcall versionString (void)
-  {
-    return PACKAGE_VERSION;
-  }
-    
-  int __stdcall decrypt (HWND hwnd, GpgMsg *msg);
-  int __stdcall signEncrypt (HWND hwnd, GpgMsg *msg);
-  int __stdcall verify (HWND hwnd, GpgMsg *msg);
-  int __stdcall attachPublicKey (const char *keyid);
-
-  int __stdcall doCmdAttach(int action);
-
-  const char* __stdcall getLogFile (void) { return logfile; }
-  void __stdcall setLogFile (const char *name)
-  { 
-    if (!lock_log ())
-      {
-        if (logfp)
-          {
-            fclose (logfp);
-            logfp = NULL;
-          }
-    
-        xfree (logfile);
-        logfile = name? xstrdup (name) : NULL;
-        unlock_log ();
-      }
-  }
-
-  int __stdcall getStorePasswdTime (void)
-  {
-    return nstorePasswd;
-  }
-
-  void __stdcall setStorePasswdTime (int nCacheTime)
-  {
-    this->nstorePasswd = nCacheTime; 
-  }
-
-  bool __stdcall getEncryptDefault (void)
-  {
-    return doEncrypt;
-  }
-
-  void __stdcall setEncryptDefault (bool doEncrypt)
-  {
-    this->doEncrypt = doEncrypt; 
-  }
-
-  bool __stdcall getSignDefault (void)
-  { 
-    return doSign; 
-  }
-
-  void __stdcall setSignDefault (bool doSign)
-  {
-    this->doSign = doSign;
-  }
-
-  bool __stdcall getEncryptWithDefaultKey (void)
-  {
-    return encryptDefault;
-  }
-  
-  void __stdcall setEncryptWithDefaultKey (bool encryptDefault)
-  {
-    this->encryptDefault = encryptDefault;
-  }
-
-  bool __stdcall getSaveDecryptedAttachments (void) 
-  { 
-    return saveDecryptedAtt;
-  }
-
-  void __stdcall setSaveDecryptedAttachments (bool saveDecrAtt)
-  {
-    this->saveDecryptedAtt = saveDecrAtt;
-  }
-
-  void __stdcall setEncodingFormat (int fmt)
-  {
-    encFormat = fmt; 
-  }
-
-  int __stdcall getEncodingFormat (void) 
-  {
-    return encFormat;
-  }
-
-  void __stdcall setSignAttachments (bool signAtt)
-  {
-    this->autoSignAtt = signAtt; 
-  }
-
-  bool __stdcall getSignAttachments (void)
-  {
-    return autoSignAtt;
-  }
-
-  void __stdcall setEnableLogging (bool val)
-  {
-    enable_logging = val;
-  }
-
-  bool __stdcall getEnableLogging (void)
-  {
-    return enable_logging;
-  }
-
-  int __stdcall readOptions (void);
-  int __stdcall writeOptions (void);
-
-  const char* __stdcall getAttachmentExtension (const char *fname);
-  
-
-  bool __stdcall deleteAttachment (GpgMsg * msg, int pos)
-  {
-//     if (msg->DeleteAttach (pos, 0, NULL, 0) == S_OK)
-//       return true;
-//     return false;
-  }
-
-  LPATTACH __stdcall createAttachment (GpgMsg * msg, int &pos)
-  {
-    ULONG attnum;      
-    LPATTACH newatt = NULL;
-    
-//     if (msg->CreateAttach (NULL, 0, &attnum, &newatt) == S_OK)
-//       {
-//         pos = attnum;
-//         return newatt;
-//       }
-    return NULL;
-  }
-
-  void  __stdcall showVersion (void);
-
-  int __stdcall startKeyManager ();
-  void __stdcall startConfigDialog (HWND parent);
-
-  void __stdcall setDefaultKey (const char *key);
-  const char * __stdcall getDefaultKey (void);
-
-  void __stdcall clearPassphrase (void) 
-  {
-    if (passCache != NULL)
-      passCache->clear ();
-  }
-
-
-private:
-  char       *defaultKey; /* Malloced default key or NULL. */
-  HashTable   *passCache;
-  LPMAPITABLE attachTable;
-  LPSRowSet   attachRows;
-  void       *recipSet;
-
-  /* Options */
-  int    nstorePasswd;  /* Time in seconds the passphrase is stored. */
-  bool    encryptDefault;
-  bool    doEncrypt;
-  bool    doSign;
-  bool    saveDecryptedAtt; /* Save decrypted attachments. */
-  bool    autoSignAtt;     /* Sign all outgoing attachments. */
-  int    encFormat;        /* Encryption format for attachments. */
-
-  void displayError (HWND root, const char *title);
-  void prepareLogging (void)
-  {
-    char *val = NULL;
-    
-    load_extension_value ("logFile", &val);
-    if (val && *val != '\"' && *val)
-      {
-        setLogFile (val);
-        setEnableLogging (true);
-      }
-    xfree (val);       
-  }
-
-  void clearObject (void)
-  {
-    this->attachRows = NULL;
-    this->attachTable = NULL;
-    this->defaultKey = NULL;
-    this->recipSet = NULL;
-  }
-
-  void clearConfig (void)
-  {
-    nstorePasswd = 0;
-    doEncrypt = false;
-    doSign = false;
-    encryptDefault = false;
-    saveDecryptedAtt = false;
-    autoSignAtt = false;
-    encFormat = DEFAULT_ATTACHMENT_FORMAT;
-  }
-
-  void freeUnknownKeys (char **unknown, int n);
-  void freeKeyArray (void **key);
-};
-
-
-/* Create an instance of the MapiGPGME class. */
-MapiGPGME *
-CreateMapiGPGME (void)
-{
-  return new MapiGPGMEImpl ();
-}
-
-
-/* Early initialization of this module.  This is done right at startup
-   with only one thread running.  Should be called only once. Returns
-   0 on success. */
-int
-initialize_mapi_gpgme (void)
-{
-  SECURITY_ATTRIBUTES sa;
-  
-  memset (&sa, 0, sizeof sa);
-  sa.bInheritHandle = FALSE;
-  sa.lpSecurityDescriptor = NULL;
-  sa.nLength = sizeof sa;
-  log_mutex = CreateMutex (&sa, FALSE, NULL);
-  return log_mutex? 0 : -1;
-}
-
-/* Acquire the mutex for logging.  Returns 0 on success. */
-static int 
-lock_log (void)
-{
-  int code = WaitForSingleObject (log_mutex, INFINITE);
-  return code != WAIT_OBJECT_0;
-}
-
-/* Release the mutex for logging. No error return is done because this
-   is a fatal error anyway and we have no means for proper
-   notification. */
-static void
-unlock_log (void)
-{
-  ReleaseMutex (log_mutex);
-}
-
-
-
-
-static void
-do_log (const char *fmt, va_list a, int w32err, int err,
-        const void *buf, size_t buflen)
-{
-  if (enable_logging == false || !logfile)
-    return;
-
-  if (!logfp)
-    {
-      if ( !lock_log ())
-        {
-          if (!logfp)
-            logfp = fopen (logfile, "a+");
-          unlock_log ();
-        }
-    }
-  if (!logfp)
-    return;
-  fprintf (logfp, "%lu/", (unsigned long)GetCurrentThreadId ());
-  if (err == 1)
-    fputs ("ERROR/", logfp);
-  vfprintf (logfp, fmt, a);
-  if (w32err) 
-    {
-      char buf[256];
-      
-      FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, w32err, 
-                     MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), 
-                     buf, sizeof (buf)-1, NULL);
-      fputs (": ", logfp);
-      fputs (buf, logfp);
-    }
-  if (buf)
-    {
-      const unsigned char *p = (const unsigned char*)buf;
-
-      for ( ; buflen; buflen--, p++)
-        fprintf (logfp, "%02X", *p);
-      putc ('\n', logfp);
-    }
-  else if ( *fmt && fmt[strlen (fmt) - 1] != '\n')
-    putc ('\n', logfp);
-
-  fflush (logfp);
-}
-
-
-void 
-log_debug (const char *fmt, ...)
-{
-  va_list a;
-  
-  va_start (a, fmt);
-  do_log (fmt, a, 0, 0, NULL, 0);
-  va_end (a);
-}
-
-void 
-log_error (const char *fmt, ...)
-{
-  va_list a;
-  
-  va_start (a, fmt);
-  do_log (fmt, a, 0, 1, NULL, 0);
-  va_end (a);
-}
-
-void 
-log_vdebug (const char *fmt, va_list a)
-{
-  do_log (fmt, a, 0, 0, NULL, 0);
-}
-
-
-void 
-log_debug_w32 (int w32err, const char *fmt, ...)
-{
-  va_list a;
-
-  if (w32err == -1)
-      w32err = GetLastError ();
-  
-  va_start (a, fmt);
-  do_log (fmt, a, w32err, 0, NULL, 0);
-  va_end (a);
-}
-
-void 
-log_error_w32 (int w32err, const char *fmt, ...)
-{
-  va_list a;
-
-  if (w32err == -1)
-      w32err = GetLastError ();
-  
-  va_start (a, fmt);
-  do_log (fmt, a, w32err, 1, NULL, 0);
-  va_end (a);
-}
-
-
-void 
-log_hexdump (const void *buf, size_t buflen, const char *fmt, ...)
-{
-  va_list a;
-
-  va_start (a, fmt);
-  do_log (fmt, a, 0, 2, buf, buflen);
-  va_end (a);
-}
-
-
-
-/* Update the display using the message MSG.  Return 0 on success. */
-static int
-update_display (HWND hwnd, GpgMsg *msg)
-{
-  HWND window;
-
-  window = find_message_window (hwnd, msg);
-  if (window)
-    {
-      log_debug ("%s:%s: window handle %p\n", __FILE__, __func__, window);
-      SetWindowText (window, msg->getDisplayText ());
-      log_debug ("%s:%s: window text is now `%s'",
-                 __FILE__, __func__, msg->getDisplayText ());
-      return 0;
-    }
-  else
-    {
-      log_debug ("%s: window handle not found for parent %p\n",
-                 __func__, hwnd);
-      return -1;
-    }
-}
-
-
-static bool 
-is_html_body (const char *body)
-{
-  char *p1, *p2;
-  
-  /* XXX: it is possible but unlikely that the message text
-     contains the used keywords. */
-  p1 = strstr (body, "<HTML>");
-  p2 = strstr (body, "</HTML>");
-  if (p1 && p2)
-    return true;
-  p1 = strstr (body, "<html>");
-  p2 = strstr (body, "</html>");
-  if (p1 && p2)
-       return true;
-  /* XXX: use case insentensive strstr version. */
-  return false;
-}
-
-
-
-
-void 
-MapiGPGMEImpl::freeKeyArray (void **key)
-{
-    gpgme_key_t *buf = (gpgme_key_t *)key;
-    int i=0;
-
-    if (buf == NULL)
-       return;
-    for (i = 0; buf[i] != NULL; i++) {
-       gpgme_key_release (buf[i]);
-       buf[i] = NULL;
-    }
-    xfree (buf);
-}
-
-
-
-
-void
-MapiGPGMEImpl::freeUnknownKeys (char **unknown, int n)
-{    
-    for (int i=0; i < n; i++) {
-       if (unknown[i] != NULL) {
-           xfree (unknown[i]);
-           unknown[i] = NULL;
-       }
-    }
-    if (n > 0)
-       xfree (unknown);
-}
-
-
-/* Release an array of strings with recipient names. */
-static void
-free_recipient_array (char **recipients)
-{
-  int i;
-
-  if (recipients)
-    {
-      for (i=0; recipients[i]; i++) 
-       xfree (recipients[i]);  
-      xfree (recipients);
-    }
-}
-
-
-
-/* Create a new body from body wth suitable line endings. aller must
-   release the result. */
-static char *
-add_html_line_endings (const char *body)
-{
-  size_t count;
-  const char *s;
-  char *p, *result;
-
-  for (count=0, s = body; *s; s++)
-    if (*s == '\n')
-      count++;
-  
-  result = (char*)xmalloc ((s - body) + count*10 + 1);
-  
-  for (s=body, p = result; *s; s++ )
-    if (*s == '\n')
-      p = stpcpy (p, "&nbsp;<br>\n");
-    else
-      *p++ = *s;
-  *p = 0;
-  
-  return result;
-  
-}
-
-
-
-/* Decrypt the message MSG and update the window.  HWND identifies the
-   current window. */
-int 
-MapiGPGMEImpl::decrypt (HWND hwnd, GpgMsg * msg)
-{
-  log_debug ("%s:%s: enter\n", __FILE__, __func__);
-  openpgp_t mtype;
-  char *plaintext = NULL;
-  int has_attach;
-  int err;
-
-  mtype = msg->getMessageType ();
-  if (mtype == OPENPGP_CLEARSIG)
-    {
-      log_debug ("%s:%s: leave (passing on to verify)\n", __FILE__, __func__);
-      return verify (hwnd, msg);
-    }
-
-  /* Check whether this possibly encrypted message as attachments.  We
-     check right now because we need to get into the decryptio code
-     even if the body is not encrypted but attachments are
-     available. FIXME: I am not sure whether this is the best
-     solution, we might want to skip the decryption step later and
-     also test for encrypted attachments right now.*/
-  has_attach = msg->hasAttachments ();
-
-  if (mtype == OPENPGP_NONE && !has_attach ) 
-    {
-      MessageBox (NULL, "No valid OpenPGP data found.",
-                  "GPG Decryption", MB_ICONERROR|MB_OK);
-      log_debug ("MapiGPGME.decrypt: leave (no OpenPGP data)\n");
-      return 0;
-    }
-
-  err = op_decrypt (msg->getOrigText (), &plaintext, nstorePasswd);
-
-  if (err)
-    {
-      if (has_attach && gpg_err_code (err) == GPG_ERR_NO_DATA)
-        ;
-      else
-        MessageBox (NULL, op_strerror (err),
-                    "GPG Decryption", MB_ICONERROR|MB_OK);
-    }
-  else if (plaintext && *plaintext)
-    {  
-      int is_html = is_html_body (plaintext);
-
-      msg->setPlainText (plaintext);
-      plaintext = NULL;
-
-      /* Also set PR_BODY but do not use 'SaveChanges' to make it
-         permanently.  This way the user can reply with the
-         plaintext but the ciphertext is still stored. */
-      log_debug ("decrypt isHtml=%d\n", is_html);
-
-      /* XXX: find a way to handle text/html message in a better way! */
-      if (is_html || update_display (hwnd, msg))
-        {
-          const char s[] = 
-            "The message text cannot be displayed.\n"
-            "You have to save the decrypted message to view it.\n"
-            "Then you need to re-open the message.\n\n"
-            "Do you want to save the decrypted message?";
-          int what;
-          
-          what = MessageBox (NULL, s, "GPG Decryption",
-                             MB_YESNO|MB_ICONWARNING);
-          if (what == IDYES) 
-            {
-              log_debug ("decrypt: saving plaintext message.\n");
-              msg->saveChanges (1);
-            }
-       }
-      else
-        msg->saveChanges (0);
-    }
-
-  if (has_attach)
-    {
-      unsigned int n;
-      
-      n = msg->getAttachments ();
-      log_debug ("%s:%s: message has %u attachments\n", __FILE__, __func__, n);
-      for (int i=0; i < n; i++) 
-        msg->decryptAttachment (hwnd, i, true, nstorePasswd);
-    }
-
-  log_debug ("%s:%s: leave (rc=%d)\n", __FILE__, __func__, err);
-  return err;
-}
-
-
-
-/* Perform a sign+encrypt operation using the data already store in
-   the instance variables. Return 0 on success. */
-int
-MapiGPGMEImpl::signEncrypt (HWND hwnd, GpgMsg *msg)
-{
-#if 0
-  log_debug ("%s:%s: enter\n", __FILE__, __func__);
-  char **recipients = msg->getRecipients ();
-  char **unknown = NULL;
-  gpgme_key_t locusr=NULL, *keys = NULL, *keys2 =NULL;
-  char *ciphertext = NULL;
-  int is_html;
-
-  /* Check for trivial case: We don't encrypt or sign an empty
-     message. */
-  if (!msg || !*msg->getOrigText ()) 
-    {
-      free_recipient_array (recipients);
-      log_debug ("%s.%s: leave (empty message)\n", __FILE__, __func__);
-      return 0;  /* Empty message - Nothing to encrypt.  FIXME: What
-                    about attachments without a body - is that possible?  */
-    }
-
-  /* Pop up a dialog box to ask for the signer of the message. */
-  if (signer_dialog_box (&locusr, NULL) == -1)
-    {
-      free_recipient_array (recipients);
-      log_debug ("%s.%s: leave (dialog failed)\n", __FILE__, __func__);
-      return gpg_error (GPG_ERR_CANCELED);  
-    }
-
-  /* Now lookup the keys of all recipients. */
-  size_t all;
-  int n = op_lookup_keys (recipients, &keys, &unknown, &all);
-  if (n != count_recipients (recipients)) 
-    {
-      /* FIXME: The implementation is not correct: op_lookup_keys
-         returns the number of missing keys but we compare against the
-         total number of keys; thus the box would pop up even when all
-         have been found. */
-       recipient_dialog_box2 (keys, unknown, all, &keys2, NULL);
-       xfree (keys);
-       keys = keys2;
-    }
-  
-  log_key_info (this, "signEncrypt", keys, locusr);
-
-  is_html = is_html_body (msg->getOrigText ());
-
-  int err = op_encrypt (msg->getOrigText (), &ciphertext,
-                        keys, locusr, nstorePasswd);
-  if (err)
-    MessageBox (NULL, op_strerror (err),
-                "GPG Sign Encrypt", MB_ICONERROR|MB_OK);
-  else 
-    {
-      if (is_html) 
-        {
-          msg->setCipherText (add_html_line_endings (ciphertext), true);
-          ciphertext = NULL;
-        }
-      else
-        msg->setCipherText (ciphertext, false);
-      xfree (ciphertext);
-    }
-
-  freeUnknownKeys (unknown, n);
-  if (!err && msg->hasAttachments ())
-    {
-      unsigned int n;
-      
-      n = msg->getAttachments ();
-      log_debug ("%s:%s: message has %u attachments\n", __FILE__, __func__, n);
-      for (int i=0; !err && i < n; i++) 
-        err = msg->encryptAttachment (hwnd, i, keys, locusr, nstorePasswd);
-      if (err)
-        MessageBox (NULL, op_strerror (err),
-                    "GPG Attachment Encryption", MB_ICONERROR|MB_OK);
-    }
-  freeKeyArray ((void **)keys);
-  gpgme_key_release (locusr);
-  free_recipient_array (recipients);
-  log_debug ("%s:%s: leave (rc=%d)\n", err);
-  return err;
-#endif
-}
-
-
-int 
-MapiGPGMEImpl::verify (HWND hwnd, GpgMsg *msg)
-{
-  log_debug ("%s:%s: enter\n", __FILE__, __func__);
-  openpgp_t mtype;
-  int has_attach;
-  
-  mtype = msg->getMessageType ();
-  has_attach = msg->hasAttachments ();
-  if (mtype == OPENPGP_NONE && !has_attach ) 
-    {
-      log_debug ("%s:%s: leave (no OpenPGP data)\n", __FILE__, __func__);
-      return 0;
-    }
-
-  int err = op_verify (msg->getOrigText (), NULL);
-  if (err)
-    MessageBox (NULL, op_strerror (err), "GPG Verify", MB_ICONERROR|MB_OK);
-  else
-    update_display (hwnd, msg);
-
-  log_debug ("%s:%s: leave (rc=%d)\n", __FILE__, __func__, err);
-  return err;
-}
-
-
-
-
-
-static const char *
-userid_from_key (gpgme_key_t k)
-{
-  if (k && k->uids && k->uids->uid)
-    return k->uids->uid;
-  else
-    return "?";
-}
-
-static const char *
-keyid_from_key (gpgme_key_t k)
-{
-  
-  if (k && k->subkeys && k->subkeys->keyid)
-    return k->subkeys->keyid;
-  else
-    return "????????";
-}
-
-/* Print information on the keys in KEYS and LOCUSR. */
-static void 
-log_key_info (MapiGPGME *g, const char *prefix,
-              gpgme_key_t *keys, gpgme_key_t locusr)
-{
-    if (locusr)
-      log_debug ("MapiGPGME.%s: signer: 0x%s %s\n", prefix,
-                   keyid_from_key (locusr), userid_from_key (locusr));
-    
-    else
-      log_debug ("MapiGPGME.%s: no signer\n", prefix);
-    
-    gpgme_key_t n;
-    int i;
-
-    if (keys == NULL)
-       return;
-    i=0;
-    for (n=keys[0]; keys[i] != NULL; i++)
-      log_debug ("MapiGPGME.%s: recp.%d 0x%s %s\n", prefix,
-                   i, keyid_from_key (keys[i]), userid_from_key (keys[i]));
-}
-           
-
-
-void 
-MapiGPGMEImpl::setDefaultKey (const char *key)
-{
-    xfree (defaultKey);
-    defaultKey = xstrdup (key);
-}
-
-
-const char* 
-MapiGPGMEImpl::getDefaultKey (void)
-{
-  return defaultKey;
-}
-
-
-
-/* We need this to find the mailer window because we directly change
-   the text of the window instead of the MAPI object itself. */
-static HWND
-find_message_window (HWND parent, GpgMsg *msg)
-{
-  HWND child;
-
-  if (!parent)
-    return NULL;
-
-  child = GetWindow (parent, GW_CHILD);
-  while (child)
-    {
-      char buf[1024+1];
-      HWND w;
-
-      memset (buf, 0, sizeof (buf));
-      GetWindowText (child, buf, sizeof (buf)-1);
-      if (msg->matchesString (buf))
-        return child;
-      w = find_message_window (child, msg);
-      if (w)
-        return w;
-      child = GetNextWindow (child, GW_HWNDNEXT);      
-    }
-
-  return NULL;
-}
-
-
-
-
-
-
-void  
-MapiGPGMEImpl::showVersion (void)
-{
-  /* Not yet available. */
-}
-
-
-int
-MapiGPGMEImpl::startKeyManager (void)
-{
-    return start_key_manager ();
-}
-
-
-void
-MapiGPGMEImpl::startConfigDialog (HWND parent)
-{
-    config_dialog_box (parent);
-}
-
-
-int
-MapiGPGMEImpl::readOptions (void)
-{
-    char *val=NULL;
-
-    load_extension_value ("autoSignAttachments", &val);
-    autoSignAtt = val == NULL || *val != '1' ? 0 : 1;
-    xfree (val); val =NULL;
-
-    load_extension_value ("saveDecryptedAttachments", &val);
-    saveDecryptedAtt = val == NULL || *val != '1'? 0 : 1;
-    xfree (val); val =NULL;
-
-    load_extension_value ("encryptDefault", &val);
-    doEncrypt = val == NULL || *val != '1'? 0 : 1;
-    xfree (val); val=NULL;
-
-    load_extension_value ("signDefault", &val);
-    doSign = val == NULL || *val != '1'? 0 : 1;
-    xfree (val); val = NULL;
-
-    load_extension_value ("addDefaultKey", &val);
-    encryptDefault = val == NULL || *val != '1' ? 0 : 1;
-    xfree (val); val = NULL;
-
-    load_extension_value ("storePasswdTime", &val);
-    nstorePasswd = val == NULL || *val == '0'? 0 : atol (val);
-    xfree (val); val = NULL;
-
-    load_extension_value ("encodingFormat", &val);
-    encFormat = val == NULL? GPG_FMT_CLASSIC  : atol (val);
-    xfree (val); val = NULL;
-
-    load_extension_value ("logFile", &val);
-    if (val == NULL ||*val == '"' || *val == 0) {
-        setLogFile (NULL);
-    }
-    else {
-       setLogFile (val);
-       setEnableLogging (true);
-    }
-    xfree (val); val=NULL;
-
-    load_extension_value ("defaultKey", &val);
-    if (val == NULL || *val == '"') {
-       encryptDefault = 0;
-        xfree (defaultKey);
-       defaultKey = NULL;
-    }
-    else {
-       setDefaultKey (val);
-       encryptDefault = 1;
-    }
-
-    xfree (val); val=NULL;
-
-    return 0;
-}
-
-
-void
-MapiGPGMEImpl::displayError (HWND root, const char *title)
-{      
-    char buf[256];
-    
-    FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError (), 
-                  MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), 
-                  buf, sizeof (buf)-1, NULL);
-    MessageBox (root, buf, title, MB_OK|MB_ICONERROR);
-}
-
-
-int
-MapiGPGMEImpl::writeOptions (void)
-{
-    struct conf {
-       const char *name;
-       bool value;
-    };
-    struct conf opt[] = {
-       {"encryptDefault", doEncrypt},
-       {"signDefault", doSign},
-       {"addDefaultKey", encryptDefault},
-       {"saveDecryptedAttachments", saveDecryptedAtt},
-       {"autoSignAttachments", autoSignAtt},
-       {NULL, 0}
-    };
-    char buf[32];
-
-    for (int i=0; opt[i].name != NULL; i++) {
-       int rc = store_extension_value (opt[i].name, opt[i].value? "1": "0");
-       if (rc)
-           displayError (NULL, "Save options in the registry");
-       /* XXX: also show the name of the value */
-    }
-
-    if (logfile != NULL)
-       store_extension_value ("logFile", logfile);
-    if (defaultKey != NULL)
-       store_extension_value ("defaultKey", defaultKey);
-    
-    sprintf (buf, "%d", nstorePasswd);
-    store_extension_value ("storePasswdTime", buf);
-    
-    sprintf (buf, "%d", encFormat);
-    store_extension_value ("encodingFormat", buf);
-
-    return 0;
-}
-
-
-int 
-MapiGPGMEImpl::attachPublicKey (const char *keyid)
-{
-    /* @untested@ */
-#if 0
-    const char *patt[1];
-    char *keyfile;
-    int err, pos = 0;
-    LPATTACH newatt;
-
-    keyfile = generateTempname (keyid);
-    patt[0] = xstrdup (keyid);
-    err = op_export_keys (patt, keyfile);
-
-    newatt = createAttachment (NULL/*FIXME*/,pos);
-    setAttachMethod (newatt, ATTACH_BY_VALUE);
-    setAttachFilename (newatt, keyfile, false);
-    /* XXX: set proper RFC3156 MIME types. */
-
-    if (streamFromFile (keyfile, newatt)) {
-       log_debug ("attachPublicKey: commit changes.\n");
-       newatt->SaveChanges (FORCE_SAVE);
-    }
-    releaseAttachment (newatt);
-    xfree (keyfile);
-    xfree ((void *)patt[0]);
-    return err;
-#endif
-    return -1;
-    
-}
diff --git a/src/MapiGPGME.h b/src/MapiGPGME.h
deleted file mode 100644 (file)
index d69189e..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/* MapiGPGME.h - Mapi support with GPGME
- *     Copyright (C) 2005 g10 Code GmbH
- *
- * This file is part of OutlGPG.
- * 
- * OutlGPG is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- * 
- * OutlGPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-#ifndef MAPI_GPGME_H
-#define MAPI_GPGME_H
-
-#include "gpgmsg.hh"
-
-typedef enum {
-    GPG_ATTACH_NONE = 0,
-    GPG_ATTACH_DECRYPT = 1,
-    GPG_ATTACH_ENCRYPT = 2,
-    GPG_ATTACH_SIGN = 4,
-    GPG_ATTACH_SIGNENCRYPT = GPG_ATTACH_SIGN|GPG_ATTACH_ENCRYPT,
-} outlgpg_attachment_action_t;
-
-typedef enum {
-    GPG_FMT_NONE = 0,      /* do not encrypt attachments */
-    GPG_FMT_CLASSIC = 1,    /* encrypt attachments without any encoding */
-    GPG_FMT_PGP_PEF = 2            /* use the PGP partioned encoding format (PEF) */
-} outlgpg_format_t;
-
-
-class MapiGPGME
-{
-public:    
-  virtual void __stdcall destroy () = 0;
-
-  virtual const char * __stdcall versionString (void) = 0;
-
-  virtual int __stdcall decrypt (HWND hwnd, GpgMsg *msg) = 0;
-  virtual int __stdcall signEncrypt (HWND hwnd, GpgMsg *msg) = 0;
-  virtual int __stdcall verify (HWND hwnd, GpgMsg *msg) = 0;
-  virtual int __stdcall attachPublicKey (const char *keyid) = 0;
-
-  virtual int __stdcall readOptions (void) = 0;
-  virtual int __stdcall writeOptions (void) = 0;
-
-  virtual int  __stdcall getStorePasswdTime (void) = 0;
-  virtual void __stdcall setStorePasswdTime (int nCacheTime) = 0;
-  virtual bool __stdcall getEncryptDefault (void) = 0;
-  virtual void __stdcall setEncryptDefault (bool doEncrypt) = 0;
-  virtual bool __stdcall getSignDefault (void) = 0;
-  virtual void __stdcall setSignDefault (bool doSign) = 0;
-  virtual bool __stdcall getEncryptWithDefaultKey (void) = 0;
-  virtual void __stdcall setEncryptWithDefaultKey (bool encryptDefault) = 0;
-  virtual bool __stdcall getSaveDecryptedAttachments (void) = 0;
-  virtual void __stdcall setSaveDecryptedAttachments (bool saveDecrAtt) = 0;
-  virtual void __stdcall setEncodingFormat (int fmt) = 0;
-  virtual int  __stdcall getEncodingFormat (void) = 0;
-  virtual void __stdcall setSignAttachments (bool signAtt) = 0;
-  virtual bool __stdcall getSignAttachments (void) = 0;
-  virtual void __stdcall setEnableLogging (bool val) = 0;
-  virtual bool __stdcall getEnableLogging (void) = 0;
-  virtual const char * __stdcall getLogFile (void) = 0;
-  virtual void __stdcall setLogFile (const char *logfile) = 0;
-  virtual void __stdcall setDefaultKey (const char *key) = 0;
-  virtual const char * __stdcall getDefaultKey (void) = 0;
-
-  virtual void  __stdcall showVersion (void) = 0;
-
-  virtual int __stdcall startKeyManager () = 0;
-  virtual void __stdcall startConfigDialog (HWND parent) = 0;
-
-
-  void operator delete (void *p)
-    {
-      if (p)
-        {
-          MapiGPGME *m = (MapiGPGME*)(p);
-          m->destroy();
-        }
-    }
-
-};
-
-
-extern "C" {
-
-MapiGPGME * __stdcall CreateMapiGPGME (void);
-
-}
-
-#endif /*MAPI_GPGME_H*/
diff --git a/src/display.cpp b/src/display.cpp
new file mode 100644 (file)
index 0000000..a54d1aa
--- /dev/null
@@ -0,0 +1,135 @@
+/* display.cpp - Helper functions to display messages.
+ *     Copyright (C) 2005 g10 Code GmbH
+ *
+ * This file is part of OutlGPG.
+ * 
+ * OutlGPG is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * OutlGPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <config.h>
+
+#include <time.h>
+#include <assert.h>
+#include <string.h>
+#include <windows.h>
+
+#include "mymapi.h"
+#include "mymapitags.h"
+#include "intern.h"
+#include "display.h"
+
+
+/* Check wether the string BODY is HTML formatted. */
+int 
+is_html_body (const char *body)
+{
+  char *p1, *p2;
+  
+  /* XXX: it is possible but unlikely that the message text
+     contains the used keywords. */
+  p1 = strstr (body, "<HTML>");
+  p2 = strstr (body, "</HTML>");
+  if (p1 && p2)
+    return 1;
+  p1 = strstr (body, "<html>");
+  p2 = strstr (body, "</html>");
+  if (p1 && p2)
+       return 1;
+  /* XXX: use case insentensive strstr version. */
+  return 0;
+}
+
+
+/* Create a new body from body wth suitable line endings. Caller must
+   release the result. */
+char *
+add_html_line_endings (const char *body)
+{
+  size_t count;
+  const char *s;
+  char *p, *result;
+
+  for (count=0, s = body; *s; s++)
+    if (*s == '\n')
+      count++;
+  
+  result = (char*)xmalloc ((s - body) + count*10 + 1);
+  
+  for (s=body, p = result; *s; s++ )
+    if (*s == '\n')
+      p = stpcpy (p, "&nbsp;<br>\n");
+    else
+      *p++ = *s;
+  *p = 0;
+  
+  return result;
+  
+}
+
+
+/* We need this to find the mailer window because we directly change
+   the text of the window instead of the MAPI object itself. */
+static HWND
+find_message_window (HWND parent, GpgMsg *msg)
+{
+  HWND child;
+
+  if (!parent)
+    return NULL;
+
+  child = GetWindow (parent, GW_CHILD);
+  while (child)
+    {
+      char buf[1024+1];
+      HWND w;
+
+      memset (buf, 0, sizeof (buf));
+      GetWindowText (child, buf, sizeof (buf)-1);
+      if (msg->matchesString (buf))
+        return child;
+      w = find_message_window (child, msg);
+      if (w)
+        return w;
+      child = GetNextWindow (child, GW_HWNDNEXT);      
+    }
+
+  return NULL;
+}
+
+
+/* Update the display using the message MSG.  Return 0 on success. */
+int
+update_display (HWND hwnd, GpgMsg *msg)
+{
+  HWND window;
+
+  window = find_message_window (hwnd, msg);
+  if (window)
+    {
+      log_debug ("%s:%s: window handle %p\n", __FILE__, __func__, window);
+      SetWindowText (window, msg->getDisplayText ());
+      log_debug ("%s:%s: window text is now `%s'",
+                 __FILE__, __func__, msg->getDisplayText ());
+      return 0;
+    }
+  else
+    {
+      log_debug ("%s: window handle not found for parent %p\n",
+                 __func__, hwnd);
+      return -1;
+    }
+}
+
diff --git a/src/display.h b/src/display.h
new file mode 100644 (file)
index 0000000..a6d09e9
--- /dev/null
@@ -0,0 +1,33 @@
+/* display.h - Helper functions for displaying messages.
+ *     Copyright (C) 2005 g10 Code GmbH
+ *
+ * This file is part of OutlGPG.
+ * 
+ * OutlGPG is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * OutlGPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef DISPLAY_H
+#define DISPLAY_H
+
+#include "gpgmsg.hh"
+
+int is_html_body (const char *body);
+
+char *add_html_line_endings (const char *body);
+
+int update_display (HWND hwnd, GpgMsg *msg);
+
+#endif /*DISPLAY_H*/
index f03ec51..6a59aeb 100644 (file)
@@ -746,6 +746,26 @@ op_export_keys (const char *pattern[], const char *outfile)
 }
 
 
+const char *
+userid_from_key (gpgme_key_t k)
+{
+  if (k && k->uids && k->uids->uid)
+    return k->uids->uid;
+  else
+    return "?";
+}
+
+const char *
+keyid_from_key (gpgme_key_t k)
+{
+  
+  if (k && k->subkeys && k->subkeys->keyid)
+    return k->subkeys->keyid;
+  else
+    return "????????";
+}
+
+
 const char*
 op_strerror (int err)
 {
index ac4c53c..7bc98a2 100644 (file)
@@ -66,6 +66,9 @@ int op_export_keys (const char *pattern[], const char *outfile);
 
 int op_lookup_keys (char **id, gpgme_key_t **keys, char ***unknown, size_t *n);
 
+const char *userid_from_key (gpgme_key_t k);
+const char *keyid_from_key (gpgme_key_t k);
+
 const char* op_strerror (int err);
 
 
index 093be8b..beb61c2 100644 (file)
@@ -35,6 +35,7 @@
 #include "util.h"
 #include "msgcache.h"
 #include "engine.h"
+#include "display.h"
 
 static const char oid_mimetag[] =
   {0x2A, 0x86, 0x48, 0x86, 0xf7, 0x14, 0x03, 0x0a, 0x04};
@@ -108,9 +109,7 @@ public:
       }
     if (msg)
       {
-      log_debug ("%s:%s:%d: here\n", __FILE__, __func__, __LINE__);
         msg->AddRef ();
-      log_debug ("%s:%s:%d: here\n", __FILE__, __func__, __LINE__);
         message = msg;
       }
   }
@@ -126,8 +125,18 @@ public:
   void saveChanges (bool permanent);
   bool matchesString (const char *string);
 
-  int encrypt (HWND hwnd);
+  int decrypt (HWND hwnd);
+  int verify (HWND hwnd);
   int sign (HWND hwnd);
+  int encrypt (HWND hwnd)
+  {
+    return encrypt_and_sign (hwnd, false);
+  }
+  int signEncrypt (HWND hwnd)
+  {
+    return encrypt_and_sign (hwnd, true);
+  }
+  int attachPublicKey (const char *keyid);
 
   char **getRecipients (void);
   unsigned int getAttachments (void);
@@ -153,6 +162,7 @@ private:
   } attach;
   
   void loadBody (void);
+  int encrypt_and_sign (HWND hwnd, bool sign);
 };
 
 
@@ -169,6 +179,45 @@ CreateGpgMsg (LPMESSAGE msg)
 }
 
 
+/* Release an array of GPGME keys. */
+static void 
+free_key_array (gpgme_key_t *keys)
+{
+  if (keys)
+    {
+      for (int i = 0; keys[i]; i++) 
+       gpgme_key_release (keys[i]);
+      xfree (keys);
+    }
+}
+
+/* Release an array of strings with recipient names. */
+static void
+free_recipient_array (char **recipients)
+{
+  int i;
+
+  if (recipients)
+    {
+      for (i=0; recipients[i]; i++) 
+       xfree (recipients[i]);  
+      xfree (recipients);
+    }
+}
+
+/* Return the number of recipients in the array RECIPIENTS. */
+static int 
+count_recipients (char **recipients)
+{
+  int i;
+  
+  for (i=0; recipients[i] != NULL; i++)
+    ;
+  return i;
+}
+
+
+\f
 /* Load the body and make it available as an UTF8 string in the
    instance variable BODY.  */
 void
@@ -528,52 +577,198 @@ GpgMsgImpl::getRecipients ()
 }
 
 
-\f
-/* Release an arrat of GPGME keys. */
-static void 
-free_key_array (gpgme_key_t *keys)
+
+
+/* Decrypt the message MSG and update the window.  HWND identifies the
+   current window. */
+int 
+GpgMsgImpl::decrypt (HWND hwnd)
 {
-  if (keys)
+  log_debug ("%s:%s: enter\n", __FILE__, __func__);
+  openpgp_t mtype;
+  char *plaintext = NULL;
+  int has_attach;
+  int err;
+
+  mtype = getMessageType ();
+  if (mtype == OPENPGP_CLEARSIG)
     {
-      for (int i = 0; keys[i]; i++) 
-       gpgme_key_release (keys[i]);
-      xfree (keys);
+      log_debug ("%s:%s: leave (passing on to verify)\n", __FILE__, __func__);
+      return verify (hwnd);
     }
+
+  /* Check whether this possibly encrypted message as attachments.  We
+     check right now because we need to get into the decryptio code
+     even if the body is not encrypted but attachments are
+     available. FIXME: I am not sure whether this is the best
+     solution, we might want to skip the decryption step later and
+     also test for encrypted attachments right now.*/
+  has_attach = hasAttachments ();
+  if (mtype == OPENPGP_NONE && !has_attach ) 
+    {
+      MessageBox (NULL, "No valid OpenPGP data found.",
+                  "GPG Decryption", MB_ICONERROR|MB_OK);
+      log_debug ("%s:%s: leave (no OpenPGP data)\n", __FILE__, __func__);
+      return 0;
+    }
+
+  err = op_decrypt (getOrigText (), &plaintext, opt.passwd_ttl);
+  if (err)
+    {
+      if (has_attach && gpg_err_code (err) == GPG_ERR_NO_DATA)
+        ;
+      else
+        MessageBox (NULL, op_strerror (err),
+                    "GPG Decryption", MB_ICONERROR|MB_OK);
+    }
+  else if (plaintext && *plaintext)
+    {  
+      int is_html = is_html_body (plaintext);
+
+      setPlainText (plaintext);
+      plaintext = NULL;
+
+      /* Also set PR_BODY but do not use 'SaveChanges' to make it
+         permanently.  This way the user can reply with the
+         plaintext but the ciphertext is still stored. */
+      log_debug ("decrypt isHtml=%d\n", is_html);
+
+      /* XXX: find a way to handle text/html message in a better way! */
+      if (is_html || update_display (hwnd, this))
+        {
+          const char s[] = 
+            "The message text cannot be displayed.\n"
+            "You have to save the decrypted message to view it.\n"
+            "Then you need to re-open the message.\n\n"
+            "Do you want to save the decrypted message?";
+          int what;
+          
+          what = MessageBox (NULL, s, "GPG Decryption",
+                             MB_YESNO|MB_ICONWARNING);
+          if (what == IDYES) 
+            {
+              log_debug ("decrypt: saving plaintext message.\n");
+              saveChanges (1);
+            }
+       }
+      else
+        saveChanges (0);
+    }
+
+  if (has_attach)
+    {
+      unsigned int n;
+      
+      n = getAttachments ();
+      log_debug ("%s:%s: message has %u attachments\n", __FILE__, __func__, n);
+      for (int i=0; i < n; i++) 
+        decryptAttachment (hwnd, i, true, opt.passwd_ttl);
+    }
+
+  log_debug ("%s:%s: leave (rc=%d)\n", __FILE__, __func__, err);
+  return err;
 }
 
-/* Release an array of strings with recipient names. */
-static void
-free_recipient_array (char **recipients)
-{
-  int i;
 
-  if (recipients)
+/* Verify the message and displaythe verification result. */
+int 
+GpgMsgImpl::verify (HWND hwnd)
+{
+  log_debug ("%s:%s: enter\n", __FILE__, __func__);
+  openpgp_t mtype;
+  int err, has_attach;
+  
+  mtype = getMessageType ();
+  has_attach = hasAttachments ();
+  if (mtype == OPENPGP_NONE && !has_attach ) 
     {
-      for (i=0; recipients[i]; i++) 
-       xfree (recipients[i]);  
-      xfree (recipients);
+      log_debug ("%s:%s: leave (no OpenPGP data)\n", __FILE__, __func__);
+      return 0;
     }
+
+  err = op_verify (getOrigText (), NULL);
+  if (err)
+    MessageBox (NULL, op_strerror (err), "GPG Verify", MB_ICONERROR|MB_OK);
+  else
+    update_display (hwnd, this);
+
+  log_debug ("%s:%s: leave (rc=%d)\n", __FILE__, __func__, err);
+  return err;
 }
 
-/* Return the number of recipients in the array RECIPIENTS. */
-static int 
-count_recipients (char **recipients)
+
+
+
+\f
+/* Sign the current message. Returns 0 on success. */
+int
+GpgMsgImpl::sign (HWND hwnd)
 {
-  int i;
+  const char *plaintext;
+  char *signedtext = NULL;
+  int err = 0;
+  gpgme_key_t sign_key = NULL;
+
+  log_debug ("%s:%s: enter\n", __FILE__, __func__);
   
-  for (i=0; recipients[i] != NULL; i++)
-    ;
-  return i;
+  /* We don't sign an empty body - a signature on a zero length string
+     is pretty much useless. */
+  if (!*(plaintext = getOrigText ()) && !hasAttachments ()) 
+    {
+      log_debug ("%s:%s: leave (empty)", __FILE__, __func__);
+      return 0; 
+    }
+
+  /* Pop up a dialog box to ask for the signer of the message. */
+  if (signer_dialog_box (&sign_key, NULL) == -1)
+    {
+      log_debug ("%s.%s: leave (dialog failed)\n", __FILE__, __func__);
+      return gpg_error (GPG_ERR_CANCELED);  
+    }
+
+  if (*plaintext)
+    {
+      err = op_sign (plaintext, &signedtext, 
+                     OP_SIG_CLEAR, sign_key, opt.passwd_ttl);
+      if (err)
+        {
+          MessageBox (NULL, op_strerror (err),
+                      "GPG Sign", MB_ICONERROR|MB_OK);
+          goto leave;
+        }
+      setSignedText (signedtext);
+      signedtext = NULL;
+    }
+
+  if (opt.auto_sign_attach && hasAttachments ())
+    {
+      unsigned int n;
+      
+      n = getAttachments ();
+      log_debug ("%s:%s: message has %u attachments\n", __FILE__, __func__, n);
+      for (int i=0; i < n; i++) 
+        signAttachment (hwnd, i, sign_key, opt.passwd_ttl);
+      /* FIXME: we should throw an error if signing of any attachment
+         failed. */
+    }
+
+ leave:
+  xfree (signedtext);
+  gpgme_key_release (sign_key);
+  log_debug ("%s:%s: leave (err=%s)\n", __FILE__, __func__, op_strerror (err));
+  return err;
 }
 
 
-/* Encrypt the entire message including all attachments. Returns 0 on
-   success. */
+\f
+/* Encrypt and optionally sign (if SIGN is true) the entire message
+   including all attachments. Returns 0 on success. */
 int 
-GpgMsgImpl::encrypt (HWND hwnd)
+GpgMsgImpl::encrypt_and_sign (HWND hwnd, bool sign)
 {
   log_debug ("%s:%s: enter\n", __FILE__, __func__);
   gpgme_key_t *keys = NULL;
+  gpgme_key_t sign_key = NULL;
   bool is_html;
   const char *plaintext;
   char *ciphertext = NULL;
@@ -589,6 +784,17 @@ GpgMsgImpl::encrypt (HWND hwnd)
       return 0; 
     }
 
+  /* Pop up a dialog box to ask for the signer of the message. */
+  if (sign)
+    {
+      if (signer_dialog_box (&sign_key, NULL) == -1)
+        {
+          log_debug ("%s.%s: leave (dialog failed)\n", __FILE__, __func__);
+          return gpg_error (GPG_ERR_CANCELED);  
+        }
+    }
+
+  /* Gather the keys for the recipients. */
   recipients = getRecipients ();
   n_keys = op_lookup_keys (recipients, &keys, &unknown, &all);
 
@@ -600,6 +806,10 @@ GpgMsgImpl::encrypt (HWND hwnd)
       int opts = 0;
       gpgme_key_t *keys2 = NULL;
 
+      /* FIXME: The implementation is not correct: op_lookup_keys
+         returns the number of missing keys but we compare against the
+         total number of keys; thus the box would pop up even when all
+         have been found. */
       log_debug ("%s:%s: calling recipient_dialog_box2", __FILE__, __func__);
       recipient_dialog_box2 (keys, unknown, all, &keys2, &opts);
       xfree (keys);
@@ -611,8 +821,23 @@ GpgMsgImpl::encrypt (HWND hwnd)
        }
     }
 
+  if (sign_key)
+    log_debug ("%s:%s: signer: 0x%s %s\n",  __FILE__, __func__,
+               keyid_from_key (sign_key), userid_from_key (sign_key));
+  else
+    log_debug ("%s:%s: no signer\n", __FILE__, __func__);
+  if (keys)
+    {
+      for (int i=0; keys[i] != NULL; i++)
+        log_debug ("%s.%s: recp.%d 0x%s %s\n", __FILE__, __func__,
+                   i, keyid_from_key (keys[i]), userid_from_key (keys[i]));
+    }
+
+
   if (*plaintext)
     {
+      is_html = is_html_body (plaintext);
+
       err = op_encrypt (plaintext, &ciphertext, keys, NULL, 0);
       if (err)
         {
@@ -621,15 +846,35 @@ GpgMsgImpl::encrypt (HWND hwnd)
           goto leave;
         }
 
-      // Need to figure out whether the plaintext was HTML encoded.
-//       if (is_html) 
-//         {
-//           setCipherText (add_html_line_endings (ciphertext), true);
-//           ciphertext = NULL;
-//         }
-//       else
-      setCipherText (ciphertext, false);
+      if (is_html) 
+        setCipherText (add_html_line_endings (ciphertext), true);
+      else
+        setCipherText (ciphertext, false);
       ciphertext = NULL;
+
+//       {
+//         HRESULT hr;
+//         SPropValue prop;
+
+//         prop.ulPropTag=PR_MESSAGE_CLASS_A;
+//         prop.Value.lpszA="IPM.Note.OPENPGP";
+//         hr = HrSetOneProp (message, &prop);
+//         if (hr != S_OK)
+//           {
+//             log_error ("%s:%s: can't set message class: hr=%#lx\n",
+//                        __FILE__, __func__, hr); 
+//           }
+
+//         prop.ulPropTag=PR_CONTENT_TYPE_A;
+//         prop.Value.lpszA="application/encrypted;foo=bar;type=mytype";
+//         hr = HrSetOneProp (message, &prop);
+//         if (hr != S_OK)
+//           {
+//             log_error ("%s:%s: can't set content type: hr=%#lx\n",
+//                        __FILE__, __func__, hr); 
+//           }
+//       }
+
     }
 
   if (hasAttachments ())
@@ -659,71 +904,43 @@ GpgMsgImpl::encrypt (HWND hwnd)
 }
 
 
-/* Sign the current message. Returns 0 on success. */
-int
-GpgMsgImpl::sign (HWND hwnd)
-{
-  const char *plaintext;
-  char *signedtext = NULL;
-  int err = 0;
-  gpgme_key_t sign_key = NULL;
-
-  log_debug ("%s:%s: enter\n", __FILE__, __func__);
-  
-  /* We don't sign an empty body - a signature on a zero length string
-     is pretty much useless. */
-  if (!*(plaintext = getOrigText ()) && !hasAttachments ()) 
-    {
-      log_debug ("%s:%s: leave (empty)", __FILE__, __func__);
-      return 0; 
-    }
-
-  /* Pop up a dialog box to ask for the signer of the message. */
-  if (signer_dialog_box (&sign_key, NULL) == -1)
-    {
-      log_debug ("%s.%s: leave (dialog failed)\n", __FILE__, __func__);
-      return gpg_error (GPG_ERR_CANCELED);  
-    }
-
-  int nstorePasswd = 10; /* FIXME*/
-  int autoSignAtt = 1; /* FIXME*/
-  if (*plaintext)
-    {
-      err = op_sign (plaintext, &signedtext, 
-                     OP_SIG_CLEAR, sign_key, nstorePasswd);
-      if (err)
-        {
-          MessageBox (NULL, op_strerror (err),
-                      "GPG Sign", MB_ICONERROR|MB_OK);
-          goto leave;
-        }
-      setSignedText (signedtext);
-      signedtext = NULL;
-    }
 
-  if (autoSignAtt && hasAttachments ())
-    {
-      unsigned int n;
-      
-      n = getAttachments ();
-      log_debug ("%s:%s: message has %u attachments\n", __FILE__, __func__, n);
-      for (int i=0; i < n; i++) 
-        signAttachment (hwnd, i, sign_key, nstorePasswd);
-      /* FIXME: we should throw an error if signing of any attachment
-         failed. */
+\f
+/* Attach a public key to a message. */
+int 
+GpgMsgImpl::attachPublicKey (const char *keyid)
+{
+    /* @untested@ */
+#if 0
+    const char *patt[1];
+    char *keyfile;
+    int err, pos = 0;
+    LPATTACH newatt;
+
+    keyfile = generateTempname (keyid);
+    patt[0] = xstrdup (keyid);
+    err = op_export_keys (patt, keyfile);
+
+    newatt = createAttachment (NULL/*FIXME*/,pos);
+    setAttachMethod (newatt, ATTACH_BY_VALUE);
+    setAttachFilename (newatt, keyfile, false);
+    /* XXX: set proper RFC3156 MIME types. */
+
+    if (streamFromFile (keyfile, newatt)) {
+       log_debug ("attachPublicKey: commit changes.\n");
+       newatt->SaveChanges (FORCE_SAVE);
     }
-
- leave:
-  xfree (signedtext);
-  gpgme_key_release (sign_key);
-  log_debug ("%s:%s: leave (err=%s)\n", __FILE__, __func__, op_strerror (err));
-  return err;
+    releaseAttachment (newatt);
+    xfree (keyfile);
+    xfree ((void *)patt[0]);
+    return err;
+#endif
+    return -1;
 }
 
 
 
 
-
 \f
 /* Returns whether the message has any attachments. */
 bool
index 4ccbbd6..9a367f4 100644 (file)
 
 #include <gpgme.h>
 
-/* Type of a message. */
-typedef enum 
-  {
-    OPENPGP_NONE = 0,
-    OPENPGP_MSG,
-    OPENPGP_SIG,
-    OPENPGP_CLEARSIG,
-    OPENPGP_PUBKEY,   /* Note, that this type is only partly supported */
-    OPENPGP_SECKEY    /* Note, that this type is only partly supported */
-  }
-openpgp_t;
-
-
+#include "intern.h"
 
 /* To manage a message we use our own class to keep track about all
    the information we known on the content of a message.  This is
@@ -100,13 +88,25 @@ public:
      the strings.  On failure NULL is returned.  */
   virtual char **getRecipients (void);
 
+  /* Decrypt the message and all attachments.  */
+  virtual int decrypt (HWND hwnd);
 
-  /* Encrypt the entire message including any attachments. Return 0 on
-     success. */
-  virtual int encrypt (HWND hwnd);
+  /* Verify the message. */
+  virtual int verify (HWND hwnd);
 
+  /* Sign the message and optionally the attachments. */
   virtual int sign (HWND hwnd);
 
+  /* Encrypt the entire message including any attachments. Returns 0
+     on success. */
+  virtual int encrypt (HWND hwnd);
+
+  /* Encrypt and sign the entire message including any
+     attachments. Return 0 on success. */
+  virtual int signEncrypt (HWND hwnd);
+
+  /* Attach the key identified by KEYID to the message. */
+  virtual int attachPublicKey (const char *keyid);
 
   /* Return the number of attachments. */
   virtual unsigned int getAttachments (void);
index 50e420e..10d63e1 100644 (file)
@@ -24,6 +24,7 @@
 #include <gpgme.h>
 
 #include "util.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -32,23 +33,58 @@ extern "C" {
 #endif
 #endif
 
-
 #ifndef STRICT
 #define STRICT
 #endif
 
-extern HINSTANCE glob_hinst;
-extern UINT      this_dll;
 
-enum {
+enum
+  {
     OPT_FLAG_ARMOR    =  1,
     OPT_FLAG_TEXT     =  2,
     OPT_FLAG_FORCE    =  4,
     OPT_FLAG_CANCEL   =  8,
-};
+  };
+
+
+typedef enum 
+  {
+    GPG_ATTACH_NONE = 0,
+    GPG_ATTACH_DECRYPT = 1,
+    GPG_ATTACH_ENCRYPT = 2,
+    GPG_ATTACH_SIGN = 4,
+    GPG_ATTACH_SIGNENCRYPT = GPG_ATTACH_SIGN|GPG_ATTACH_ENCRYPT
+  }
+outlgpg_attachment_action_t;
+
+
+typedef enum
+  {
+    GPG_FMT_NONE = 0,       /* do not encrypt attachments */
+    GPG_FMT_CLASSIC = 1,    /* encrypt attachments without any encoding */
+    GPG_FMT_PGP_PEF = 2     /* use the PGP partioned encoding format (PEF) */
+  } 
+outlgpg_format_t;
+
+/* Type of a message. */
+typedef enum 
+  {
+    OPENPGP_NONE = 0,
+    OPENPGP_MSG,
+    OPENPGP_SIG,
+    OPENPGP_CLEARSIG,
+    OPENPGP_PUBKEY,   /* Note, that this type is only partly supported */
+    OPENPGP_SECKEY    /* Note, that this type is only partly supported */
+  }
+openpgp_t;
+
+
+extern HINSTANCE glob_hinst;
+extern UINT      this_dll;
 
 
-struct decrypt_key_s {
+struct decrypt_key_s 
+{
   gpgme_key_t signer;
   char keyid[16+1];
   char *user_id;
@@ -62,13 +98,33 @@ struct decrypt_key_s {
   unsigned int last_was_bad:1;
 };
 
-struct cache_item_s {
-    char keyid[16+1];
-    char *pass;
-    unsigned ttl;
+struct cache_item_s 
+{
+  char keyid[16+1];
+  char *pass;
+  unsigned ttl;
 };
 typedef struct cache_item_s *cache_item_t;
 
+/* Global options - initialized to default by main.c. */
+#ifdef __cplusplus
+extern
+#endif
+struct 
+{
+  int passwd_ttl;            /* Time in seconds the passphrase is stored. */
+  int encrypt_default;       /* Encrypt by default. */
+  int sign_default;          /* Sign by default. */
+  int save_decrypted_attach; /* Save decrypted attachments. */
+  int auto_sign_attach;             /* Sign all outgoing attachments. */
+  int enc_format;            /* Encryption format for attachments. */
+  char *default_key;         /* Malloced default key or NULL. */
+  int add_default_key;       /* Always also encrypt to the default key. */
+} opt;
+
+
+
+
 /*-- common.c --*/
 void set_global_hinstance (HINSTANCE hinst);
 void center_window (HWND childwnd, HWND style);
index d7f6347..cb087ec 100644 (file)
 #include "mymapi.h"
 
 
+/* The malloced name of the logfile and the logging stream.  If
+   LOGFILE is NULL, no logging is done. */
+static char *logfile;
+static FILE *logfp;
+
+/* For certain operations we need to acquire a log on the logging
+   functions.  This lock is controlled by this Mutex. */
+static HANDLE log_mutex;
+
+
+/* Initialization of gloabl options.  These are merely the defaults
+   and will get updated later from the Registry.  That is done later
+   at the time Outlook calls its entry point the first time. */
+static void
+init_options (void)
+{
+  opt.passwd_ttl = 10; /* Seconds. Use a small value, so that no
+                          multiple prompts for attachment encryption
+                          are issued. */
+  opt.enc_format = GPG_FMT_CLASSIC;
+  opt.add_default_key = 1;
+}
+
+
+/* Early initialization of this module.  This is done right at startup
+   with only one thread running.  Should be called only once. Returns
+   0 on success. */
+static int
+initialize_main (void)
+{
+  SECURITY_ATTRIBUTES sa;
+  
+  memset (&sa, 0, sizeof sa);
+  sa.bInheritHandle = FALSE;
+  sa.lpSecurityDescriptor = NULL;
+  sa.nLength = sizeof sa;
+  log_mutex = CreateMutex (&sa, FALSE, NULL);
+  return log_mutex? 0 : -1;
+}
+
+
+/* Entry point called by DLL loader. */
 int WINAPI
 DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserved)
 {
@@ -42,20 +84,276 @@ DllMain (HINSTANCE hinst, DWORD reason, LPVOID reserved)
       set_global_hinstance (hinst);
       /* The next call initializes subsystems of gpgme and should be
          done as early as possible.  The actual return value is (the
-         version string) is not used here.  It may be called at anty
+         version string) is not used here.  It may be called at any
          time later for this. */
       gpgme_check_version (NULL);
 
       /* Early initializations of our subsystems. */
+      if (initialize_main ())
+        return FALSE;
       if (initialize_passcache ())
         return FALSE;
       if (initialize_msgcache ())
         return FALSE;
-      if (initialize_mapi_gpgme ())
-        return FALSE;
+      init_options ();
     }
 
   return TRUE;
 }
 
 
+/* Acquire the mutex for logging.  Returns 0 on success. */
+static int 
+lock_log (void)
+{
+  int code = WaitForSingleObject (log_mutex, INFINITE);
+  return code != WAIT_OBJECT_0;
+}
+
+/* Release the mutex for logging. No error return is done because this
+   is a fatal error anyway and we have no means for proper
+   notification. */
+static void
+unlock_log (void)
+{
+  ReleaseMutex (log_mutex);
+}
+
+
+
+static void
+do_log (const char *fmt, va_list a, int w32err, int err,
+        const void *buf, size_t buflen)
+{
+  if (!logfile)
+    return;
+
+  if (lock_log ())
+    return;
+  
+  if (!logfp)
+    logfp = fopen (logfile, "a+");
+  if (!logfp)
+    {
+      unlock_log ();
+      return;
+    }
+  
+  fprintf (logfp, "%lu/", (unsigned long)GetCurrentThreadId ());
+  if (err == 1)
+    fputs ("ERROR/", logfp);
+  vfprintf (logfp, fmt, a);
+  if (w32err) 
+    {
+      char tmpbuf[256];
+      
+      FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, w32err, 
+                     MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), 
+                     tmpbuf, sizeof (tmpbuf)-1, NULL);
+      fputs (": ", logfp);
+      fputs (tmpbuf, logfp);
+    }
+  if (buf)
+    {
+      const unsigned char *p = (const unsigned char*)buf;
+
+      for ( ; buflen; buflen--, p++)
+        fprintf (logfp, "%02X", *p);
+      putc ('\n', logfp);
+    }
+  else if ( *fmt && fmt[strlen (fmt) - 1] != '\n')
+    putc ('\n', logfp);
+
+  fflush (logfp);
+  unlock_log ();
+}
+
+
+void 
+log_debug (const char *fmt, ...)
+{
+  va_list a;
+  
+  va_start (a, fmt);
+  do_log (fmt, a, 0, 0, NULL, 0);
+  va_end (a);
+}
+
+void 
+log_error (const char *fmt, ...)
+{
+  va_list a;
+  
+  va_start (a, fmt);
+  do_log (fmt, a, 0, 1, NULL, 0);
+  va_end (a);
+}
+
+void 
+log_vdebug (const char *fmt, va_list a)
+{
+  do_log (fmt, a, 0, 0, NULL, 0);
+}
+
+
+void 
+log_debug_w32 (int w32err, const char *fmt, ...)
+{
+  va_list a;
+
+  if (w32err == -1)
+      w32err = GetLastError ();
+  
+  va_start (a, fmt);
+  do_log (fmt, a, w32err, 0, NULL, 0);
+  va_end (a);
+}
+
+void 
+log_error_w32 (int w32err, const char *fmt, ...)
+{
+  va_list a;
+
+  if (w32err == -1)
+      w32err = GetLastError ();
+  
+  va_start (a, fmt);
+  do_log (fmt, a, w32err, 1, NULL, 0);
+  va_end (a);
+}
+
+
+void 
+log_hexdump (const void *buf, size_t buflen, const char *fmt, ...)
+{
+  va_list a;
+
+  va_start (a, fmt);
+  do_log (fmt, a, 0, 2, buf, buflen);
+  va_end (a);
+}
+
+
+const char *
+get_log_file (void)
+{
+  return logfile? logfile : "";
+}
+
+void
+set_log_file (const char *name)
+{
+  if (!lock_log ())
+    {
+      if (logfp)
+        {
+          fclose (logfp);
+          logfp = NULL;
+        }
+      xfree (logfile);
+      if (!name || *name == '\"' || !*name) 
+        logfile = NULL;
+      else
+        logfile = xstrdup (name);
+      unlock_log ();
+    }
+}
+
+void
+set_default_key (const char *name)
+{
+  if (!lock_log ())
+    {
+      if (!name || *name == '\"' || !*name)
+        {
+          xfree (opt.default_key);
+          opt.default_key = NULL;
+        }
+      else
+        {
+          xfree (opt.default_key);
+          opt.default_key = xstrdup (name);;
+        }
+      unlock_log ();
+    }
+}
+
+
+/* Read option settings from the Registry. */
+void
+read_options (void)
+{
+  char *val = NULL;
+  load_extension_value ("autoSignAttachments", &val);
+  opt.auto_sign_attach = val == NULL || *val != '1' ? 0 : 1;
+  xfree (val); val = NULL;
+  
+  load_extension_value ("saveDecryptedAttachments", &val);
+  opt.save_decrypted_attach = val == NULL || *val != '1'? 0 : 1;
+  xfree (val); val = NULL;
+
+  load_extension_value ("encryptDefault", &val);
+  opt.encrypt_default = val == NULL || *val != '1'? 0 : 1;
+  xfree (val); val = NULL;
+
+  load_extension_value ("signDefault", &val);
+  opt.sign_default = val == NULL || *val != '1'? 0 : 1;
+  xfree (val); val = NULL;
+
+  load_extension_value ("addDefaultKey", &val);
+  opt.add_default_key = val == NULL || *val != '1' ? 0 : 1;
+  xfree (val); val = NULL;
+
+  load_extension_value ("storePasswdTime", &val);
+  opt.passwd_ttl = val == NULL || *val == '0'? 0 : atol (val);
+  xfree (val); val = NULL;
+
+  load_extension_value ("encodingFormat", &val);
+  opt.enc_format = val == NULL? GPG_FMT_CLASSIC  : atol (val);
+  xfree (val); val = NULL;
+
+  load_extension_value ("logFile", &val);
+  set_log_file (val);
+  xfree (val); val = NULL;
+  
+  load_extension_value ("defaultKey", &val);
+  set_default_key (val);
+  xfree (val); val = NULL;
+}
+
+
+/* Write current options back to the Registry. */
+int
+write_options (void)
+{
+  struct 
+  {
+    const char *name;
+    int  value;
+  } table[] = {
+    {"encryptDefault",           opt.encrypt_default},
+    {"signDefault",              opt.sign_default},
+    {"addDefaultKey",            opt.add_default_key},
+    {"saveDecryptedAttachments", opt.save_decrypted_attach},
+    {"autoSignAttachments",      opt.auto_sign_attach},
+    {NULL, 0}
+  };
+  char buf[32];
+  int i;
+
+  for (i=0; table[i].name; i++) 
+    store_extension_value (table[i].name, table[i].value? "1": "0");
+
+  store_extension_value ("logFile", logfile? logfile: "");
+  store_extension_value ("defaultKey", opt.default_key? opt.default_key:"");
+  
+  sprintf (buf, "%d", opt.passwd_ttl);
+  store_extension_value ("storePasswdTime", buf);
+  
+  sprintf (buf, "%d", opt.enc_format);
+  store_extension_value ("encodingFormat", buf);
+
+  return 0;
+}
+
index 259500d..a017861 100644 (file)
@@ -80,6 +80,7 @@
 #define PR_AUTO_FORWARD_COMMENT_W               PROP_TAG( PT_UNICODE,   0x0004)
 #define PR_AUTO_FORWARD_COMMENT_A               PROP_TAG( PT_STRING8,   0x0004)
 #define PR_AUTO_FORWARDED                       PROP_TAG( PT_BOOLEAN,   0x0005)
+#define PR_CONTENT_TYPE_A                       PROP_TAG( PT_STRING8,   0x8095)
 #define PR_CONTENT_CONFIDENTIALITY_ALGORITHM_ID PROP_TAG( PT_BINARY,    0x0006)
 #define PR_CONTENT_CORRELATOR                   PROP_TAG( PT_BINARY,    0x0007)
 #define PR_CONTENT_IDENTIFIER                   PROP_TAG( PT_TSTRING,   0x0008)
index 0123892..d60db08 100644 (file)
@@ -27,12 +27,6 @@ class CGPGExchExtCommands;
 class CGPGExchExtPropertySheets;
 class CGPGExchApp;
 
-class MapiGPGME;
-
-
-extern MapiGPGME *m_gpg;
-
-
 bool GPGOptionsDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
 
 
index 038f7b3..2efbcf5 100644 (file)
@@ -30,7 +30,7 @@
 #include "intern.h"
 #include "mymapi.h"
 #include "mymapitags.h"
-#include "MapiGPGME.h"
+#include "display.h"
 
 #include "olflange-def.h"
 #include "olflange-ids.h"
@@ -71,10 +71,7 @@ GPGOptionsDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
               }                
           }
         
-       const char *s;
-       s = NULL;
-       s = m_gpg->getDefaultKey ();
-       enable = s && *s? 1 : 0;
+       enable = !!(opt.default_key && *opt.default_key);
        EnableWindow (GetDlgItem (hDlg, IDC_ENCRYPT_TO), enable? TRUE:FALSE);
        if (enable == 1)
           CheckDlgButton (hDlg, IDC_ENCRYPT_WITH_STANDARD_KEY, BST_CHECKED);
@@ -118,7 +115,7 @@ GPGOptionsDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
            EnableWindow (GetDlgItem (hDlg, IDC_ENCRYPT_TO), enable==0? FALSE: TRUE);
        }
        if (LOWORD(wParam) == IDC_GPG_OPTIONS)
-           m_gpg->startConfigDialog (hDlg);
+           config_dialog_box (hDlg);
        break;
        
     case WM_NOTIFY:
@@ -129,26 +126,29 @@ GPGOptionsDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
            break;
 
        case PSN_SETACTIVE: {
-           TCHAR s[20];
-           const char * f;
+           TCHAR s[30];
+           const char *f;
            
-           if (m_gpg->getDefaultKey () != NULL)                
-               SetDlgItemText (hDlg, IDC_ENCRYPT_TO, m_gpg->getDefaultKey ());
-           wsprintf(s, "%d", m_gpg->getStorePasswdTime ());
-           SendDlgItemMessage(hDlg, IDC_TIME_PHRASES, WM_SETTEXT, 0, (LPARAM) s);
-           f = m_gpg->getLogFile ();
-           SendDlgItemMessage (hDlg, IDC_DEBUG_LOGFILE, WM_SETTEXT, 0, (LPARAM)f);
+           if (opt.default_key)                
+               SetDlgItemText (hDlg, IDC_ENCRYPT_TO, opt.default_key);
+           wsprintf(s, "%d", opt.passwd_ttl);
+           SendDlgItemMessage(hDlg, IDC_TIME_PHRASES, WM_SETTEXT,
+                               0, (LPARAM) s);
+           f = get_log_file ();
+           SendDlgItemMessage (hDlg, IDC_DEBUG_LOGFILE, WM_SETTEXT,
+                                0, (LPARAM)f);
            hWndPage = pnmhdr->hwndFrom;   // to be used in WM_COMMAND
            SendDlgItemMessage (hDlg, IDC_ENCRYPT_DEFAULT, BM_SETCHECK, 
-                               m_gpg->getEncryptDefault () ? 1 : 0, 0L);
+                               !!opt.encrypt_default, 0L);
            SendDlgItemMessage (hDlg, IDC_SIGN_DEFAULT, BM_SETCHECK, 
-                               m_gpg->getSignDefault () ? 1 : 0, 0L);
-           SendDlgItemMessage (hDlg, IDC_ENCRYPT_WITH_STANDARD_KEY, BM_SETCHECK, 
-                               m_gpg->getEncryptWithDefaultKey () && enable? 1 : 0, 0L);
+                               !!opt.sign_default, 0L);
+           SendDlgItemMessage (hDlg, IDC_ENCRYPT_WITH_STANDARD_KEY,
+                                BM_SETCHECK, 
+                               (opt.add_default_key && enable), 0L);
            SendDlgItemMessage (hDlg, IDC_SAVE_DECRYPTED, BM_SETCHECK, 
-                               m_gpg->getSaveDecryptedAttachments () ? 1 : 0, 0L);
+                               !!opt.save_decrypted_attach, 0L);
            SendDlgItemMessage (hDlg, IDC_SIGN_ATTACHMENTS, BM_SETCHECK,
-                               m_gpg->getSignAttachments() ? 1 : 0, 0L);
+                               !!opt.auto_sign_attach, 0L);
            bMsgResult = FALSE;  /* accepts activation */
            break; }
                
@@ -157,27 +157,38 @@ GPGOptionsDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
            GetDlgItemText (hDlg, IDC_ENCRYPT_TO, s, 200);
            if (strlen (s) > 0 && strchr (s, ' ')) {
-               MessageBox (hDlg, "The default key cannot contain any spaces.",
+               MessageBox (hDlg,
+                            "The default key may not contain any spaces.",
                            "Outlook GnuPG-Plugin", MB_ICONERROR|MB_OK);
                bMsgResult = PSNRET_INVALID_NOCHANGEPAGE ;
                break;
            }
-           if (strlen (s) == 0)
-               m_gpg->setEncryptWithDefaultKey (false);
+           if (!*s)
+              opt.add_default_key = 0;
            else
-               m_gpg->setEncryptWithDefaultKey (SendDlgItemMessage(hDlg, IDC_ENCRYPT_WITH_STANDARD_KEY, BM_GETCHECK, 0, 0L));
-           SendDlgItemMessage (hDlg, IDC_TIME_PHRASES, WM_GETTEXT, 20, (LPARAM) s);            
-           m_gpg->setStorePasswdTime (atol (s));
-           SendDlgItemMessage (hDlg, IDC_DEBUG_LOGFILE, WM_GETTEXT, 200, (LPARAM)s);
-           m_gpg->setLogFile (s);
-           SendDlgItemMessage (hDlg, IDC_ENCRYPT_TO, WM_GETTEXT, 200, (LPARAM)s);
-           m_gpg->setDefaultKey (s);
+              opt.add_default_key = !!SendDlgItemMessage
+                (hDlg, IDC_ENCRYPT_WITH_STANDARD_KEY, BM_GETCHECK, 0, 0L);
+
+           SendDlgItemMessage (hDlg, IDC_TIME_PHRASES, WM_GETTEXT,
+                                20, (LPARAM)s);                
+           opt.passwd_ttl = (int)atol (s);
+           SendDlgItemMessage (hDlg, IDC_DEBUG_LOGFILE, WM_GETTEXT,
+                                200, (LPARAM)s);
+           set_log_file (s);
+           SendDlgItemMessage (hDlg, IDC_ENCRYPT_TO, WM_GETTEXT,
+                                200, (LPARAM)s);
+           set_default_key (s);
                
-           m_gpg->setEncryptDefault (SendDlgItemMessage(hDlg, IDC_ENCRYPT_DEFAULT, BM_GETCHECK, 0, 0L));
-           m_gpg->setSignDefault (SendDlgItemMessage(hDlg, IDC_SIGN_DEFAULT, BM_GETCHECK, 0, 0L));
-           m_gpg->setSaveDecryptedAttachments (SendDlgItemMessage(hDlg, IDC_SAVE_DECRYPTED, BM_GETCHECK, 0, 0L));
-           m_gpg->setSignAttachments (SendDlgItemMessage (hDlg, IDC_SIGN_ATTACHMENTS,  BM_GETCHECK, 0, 0L));
-           m_gpg->writeOptions ();
+           opt.encrypt_default = !!SendDlgItemMessage
+              (hDlg, IDC_ENCRYPT_DEFAULT, BM_GETCHECK, 0, 0L);
+           opt.sign_default = !!SendDlgItemMessage 
+              (hDlg, IDC_SIGN_DEFAULT, BM_GETCHECK, 0, 0L);
+           opt.save_decrypted_attach = !!SendDlgItemMessage
+              (hDlg, IDC_SAVE_DECRYPTED, BM_GETCHECK, 0, 0L);
+            opt.auto_sign_attach = !!SendDlgItemMessage
+              (hDlg, IDC_SIGN_ATTACHMENTS,  BM_GETCHECK, 0, 0L);
+
+           write_options ();
            bMsgResult = PSNRET_NOERROR;
            break; }
                
index b7aacfd..2ca9162 100644 (file)
 #include "mymapi.h"
 #include "mymapitags.h"
 #include "myexchext.h"
-#include "MapiGPGME.h"
+#include "display.h"
 #include "intern.h"
 #include "gpgmsg.hh"
 #include "msgcache.h"
+#include "engine.h"
 
 #include "olflange-ids.h"
 #include "olflange-def.h"
 bool g_bInitDll = FALSE;
 
 
-/* FIXME!!!! Huh?  We only have one m_gpg object??? This is strange,
-   AFAICS, Exchange may create several contexts and thus we may be
-   required to run several instances of mapiGPGME concurrently. */
-MapiGPGME *m_gpg = NULL;
-
-
-
-
 /* Registers this module as an Exchange extension. This basically updates
    some Registry entries. */
 STDAPI 
@@ -371,33 +364,28 @@ CGPGExchExt::CGPGExchExt (void)
   
   if (!g_bInitDll)
     {
-      if (!m_gpg)
-        {
-          m_gpg = CreateMapiGPGME ();
-          m_gpg->readOptions ();
-        }
+      read_options ();
+      op_init ();
       g_bInitDll = TRUE;
-      log_debug ("%s:%s: one time init done\n", __FILE__, __func__);
+      log_debug ("%s:%s: first time initialization done\n",
+                 __FILE__, __func__);
     }
 }
 
 
-/*  Uninitializes the dll in the session context. 
-   FIXME:  One instance only????  For what the hell do we use g_bInitDll then?
-*/
+/*  Uninitializes the DLL in the session context. */
 CGPGExchExt::~CGPGExchExt (void) 
 {
   log_debug ("%s:%s: cleaning up CGPGExchExt object\n", __FILE__, __func__);
 
-    if (m_lContext == EECONTEXT_SESSION) {
-       if (g_bInitDll) {
-           if (m_gpg != NULL) {
-               m_gpg->writeOptions ();
-               delete m_gpg;
-               m_gpg = NULL;
-           }
-           g_bInitDll = FALSE;
-            log_debug ("%s:%s: one time deinit done\n", __FILE__, __func__);
+  if (m_lContext == EECONTEXT_SESSION)
+    {
+      if (g_bInitDll)
+        {
+          op_deinit ();
+          write_options ();
+          g_bInitDll = FALSE;
+          log_debug ("%s:%s: DLL shutdown down\n", __FILE__, __func__);
        }       
     }
 }
@@ -613,7 +601,7 @@ CGPGExchExtMessageEvents::OnWriteComplete (LPEXCHEXTCALLBACK pEECB,
     {
       GpgMsg *m = CreateGpgMsg (msg);
       if (m_pExchExt->m_gpgEncrypt && m_pExchExt->m_gpgSign)
-        rc = m_gpg->signEncrypt (hWnd, m);
+        rc = m->signEncrypt (hWnd);
       if (m_pExchExt->m_gpgEncrypt && !m_pExchExt->m_gpgSign)
         rc = m->encrypt (hWnd);
       if (!m_pExchExt->m_gpgEncrypt && m_pExchExt->m_gpgSign)
@@ -937,8 +925,8 @@ CGPGExchExtCommands::InstallCommands (
       m_nToolbarBitmap2 = SendMessage(hwndToolbar, TB_ADDBITMAP,
                                       1, (LPARAM)&tbab);
     }
-    m_pExchExt->m_gpgEncrypt = m_gpg->getEncryptDefault ();
-    m_pExchExt->m_gpgSign = m_gpg->getSignDefault ();
+    m_pExchExt->m_gpgEncrypt = opt.encrypt_default;
+    m_pExchExt->m_gpgSign    = opt.sign_default;
     if (force_encrypt)
       m_pExchExt->m_gpgEncrypt = true;
   }
@@ -1007,7 +995,7 @@ CGPGExchExtCommands::DoCommand (
           if (nCommandID == m_nCmdEncrypt)
             {
               GpgMsg *m = CreateGpgMsg (pMessage);
-              m_gpg->decrypt (hWnd, m);
+              m->decrypt (hWnd);
               delete m;
            }
        }
@@ -1025,7 +1013,7 @@ CGPGExchExtCommands::DoCommand (
     }
   else if (m_lContext == EECONTEXT_VIEWER)
     {
-      if (m_gpg->startKeyManager ())
+      if (start_key_manager ())
         MessageBox (NULL, "Could not start Key-Manager",
                     "OutlGPG", MB_ICONERROR|MB_OK);
     }
index 56c477d..3a21a84 100644 (file)
@@ -6,4 +6,3 @@ EXPORTS
     ExchEntryPoint = ExchEntryPoint@0            @1
     DllRegisterServer = DllRegisterServer@0      @2    PRIVATE
     DllUnregisterServer = DllUnregisterServer@0  @3    PRIVATE
-    CreateMapiGPGME@0                            @4
index 53e22a7..6972882 100644 (file)
@@ -56,7 +56,7 @@ wchar_t *utf8_to_wchar (const char *string);
 wchar_t *utf8_to_wchar2 (const char *string, size_t len);
 
 
-/*-- MapiGPGME.cpp --*/
+/*-- main.c --*/
 void log_debug (const char *fmt, ...) __attribute__ ((format (printf,1,2)));
 void log_error (const char *fmt, ...) __attribute__ ((format (printf,1,2)));
 void log_vdebug (const char *fmt, va_list a);
@@ -64,8 +64,15 @@ void log_debug_w32 (int w32err, const char *fmt,
                     ...) __attribute__ ((format (printf,2,3)));
 void log_error_w32 (int w32err, const char *fmt,
                     ...) __attribute__ ((format (printf,2,3)));
-void log_hexdump (const void *buf, size_t buflen, const char *fmt, ...)
-     __attribute__ ((format (printf,3,4)));
+void log_hexdump (const void *buf, size_t buflen, const char *fmt, 
+                  ...)  __attribute__ ((format (printf,3,4)));
+     
+const char *get_log_file (void);
+void set_log_file (const char *name);
+void set_default_key (const char *name);
+void read_options (void);
+int write_options (void);
+
 
 /*****  Missing functions.  ****/