Save cryto settings in a draft.
authorWerner Koch <wk@gnupg.org>
Wed, 25 Feb 2009 15:05:15 +0000 (15:05 +0000)
committerWerner Koch <wk@gnupg.org>
Wed, 25 Feb 2009 15:05:15 +0000 (15:05 +0000)
NEWS
doc/gpgol.texi
po/de.po
src/ChangeLog
src/Makefile.am
src/ext-commands.cpp
src/mapihelp.cpp
src/mapihelp.h
src/mimemaker.c
src/myexchext.h

diff --git a/NEWS b/NEWS
index acaeede..66c3461 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,9 @@
+Noteworthy changes for version 0.10.19
+===================================================
+
+ * Save the crypto settings in a message draft.
+
+
 Noteworthy changes for version 0.10.18 (2009-01-28)
 ===================================================
 
index 79b1c8c..ba061e3 100644 (file)
@@ -253,6 +253,11 @@ This property is of type STRING8 and used to store the MIME structure of
 the orginal message.  The content are lines of colon delimited fields.
 The specification has not yet been finished.
 
+@item GpgOL Draft Info
+This is a property of type STRING8 used to preserve crypto settings in a
+draft message.  For details see the function
+@code{mapi_set_gpgol_draft_info}.
+
 @end table
 
 
index df9ba31..45f4c16 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -121,7 +121,8 @@ msgstr "Warnung: Eines der Zertifikate wurde widerrufen\n"
 
 #: src/engine-gpgme.c:863
 msgid "Warning: The certificate used to create the signature expired at: "
-msgstr "Warnung: Das Zertifikat mit der diese Signatur erzeugt wurde verfiel am: "
+msgstr ""
+"Warnung: Das Zertifikat mit der diese Signatur erzeugt wurde verfiel am: "
 
 #: src/engine-gpgme.c:869
 msgid "Warning: At least one certification certificate has expired\n"
@@ -400,7 +401,10 @@ msgid ""
 "[The content of this message is not visible because it has been decrypted by "
 "another Outlook session.  Use the \"decrypt/verify\" command to make it "
 "visible]"
-msgstr "[Der Inhalt dieser Nachricht ist nicht sichtbar, da sie in einer anderen Outlook Sitzung entschlüsselt wurde.  Verwenden Sie den Menüpunkt \"entschlüsseln/überprüfen\" um den Inhalt wieder sichtbar zu machen.]"
+msgstr ""
+"[Der Inhalt dieser Nachricht ist nicht sichtbar, da sie in einer anderen "
+"Outlook Sitzung entschlüsselt wurde.  Verwenden Sie den Menüpunkt "
+"\"entschlüsseln/überprüfen\" um den Inhalt wieder sichtbar zu machen.]"
 
 #: src/mapihelp.cpp:2882
 msgid ""
@@ -446,17 +450,23 @@ msgstr "GpgOL - Informationen zu der Nachricht"
 
 #: src/message.cpp:540
 msgid "Signature verification of an encrypted message is not possible."
-msgstr "Die Prüfung der Signatur ist bei einer verschlüsselten Nachrichten nicht möglich."
+msgstr ""
+"Die Prüfung der Signatur ist bei einer verschlüsselten Nachrichten nicht "
+"möglich."
 
 #: src/message.cpp:551
 msgid "Signature verification of this message class is not possible."
-msgstr "Die Prüfung der Signatur ist bei dieser Nachrichtenklasse nicht möglich."
+msgstr ""
+"Die Prüfung der Signatur ist bei dieser Nachrichtenklasse nicht möglich."
 
 #: src/message.cpp:554
 msgid ""
 "Signature verification of this S/MIME message is not possible.  Please check "
 "that S/MIME processing has been enabled."
-msgstr "Die Prüfung der Signatur ist bei dieser S/MIME Nachricht nicht möglich.  Bitte überprüfen Sie in den Einstellungen, daß die Verarbeitung von S/MIME eingeschaltet ist."
+msgstr ""
+"Die Prüfung der Signatur ist bei dieser S/MIME Nachricht nicht möglich.  "
+"Bitte überprüfen Sie in den Einstellungen, daß die Verarbeitung von S/MIME "
+"eingeschaltet ist."
 
 #: src/message.cpp:558
 msgid "This message has no signature."
index 46127c1..a518715 100644 (file)
@@ -1,3 +1,11 @@
+2009-02-25  Werner Koch  <wk@g10code.com>
+
+       * mapihelp.cpp (get_gpgoldraftinfo_tag): New.
+       (mapi_get_gpgol_draft_info, mapi_set_gpgol_draft_info): New.
+       * ext-commands.cpp (DoCommand): Save encryption selection.
+       (InstallCommands): Get encryption selection from the draft info.
+       * mimemaker.c (finalize_message): Delete the property.
+
 2009-01-28  Werner Koch  <wk@g10code.com>
 
        * mimeparser.c (t2body): Take care of x-pkcs7-mime as used by
index 1844b5a..8f809f7 100644 (file)
@@ -14,6 +14,7 @@
 unused_sources = item-events.cpp 
 
 bin_PROGRAMS = gpgol 
+#treeview
 EXTRA_DIST = versioninfo.rc.in mapi32.def $(unused_sources) Outlook.gpl \
             logo.bmp decrypt.bmp encrypt.bmp sign.bmp key_mana.bmp \
              proto-auto.bmp proto-pgpmime.bmp proto-smime.bmp \
@@ -65,6 +66,8 @@ gpgol_SOURCES = \
        w32-gettext.c w32-gettext.h 
 
 
+#treeview_SOURCES = treeview.c
+
 # W32API 3.2 comes with an unusable libmapi32.a.  We build our own
 # version.  Note the omission of -k (--kill-at) from the DLLTOOL
 # command line.  We also create our own virtual copies to the _static_
index 0ad1fae..cbc0b36 100644 (file)
@@ -387,6 +387,8 @@ GpgolExtCommands::InstallCommands (
   DISPPARAMS dispparams;
   VARIANT aVariant;
   int force_encrypt = 0;
+  char *draft_info = NULL;
+  
 
   (void)hMenu;
   
@@ -494,6 +496,12 @@ GpgolExtCommands::InstallCommands (
           xfree (key);
         }
       
+      /* Because we have the message open, we use it to get the draft
+         info property.  */
+      if (message)
+        draft_info = mapi_get_gpgol_draft_info (message);
+
+
       ul_release (message, __func__, __LINE__);
       ul_release (mdb, __func__, __LINE__);
     }
@@ -591,13 +599,30 @@ GpgolExtCommands::InstallCommands (
                      "Sign",    IDB_SIGN,    m_nCmdSign,
                      NULL, 0, 0);
       
-
-      m_pExchExt->m_protoSelection = opt.default_protocol;
+      if (draft_info && strlen (draft_info) >= 3 && draft_info[2] == 'A')
+        m_pExchExt->m_protoSelection = PROTOCOL_UNKNOWN;
+      else if (draft_info && strlen (draft_info) >= 3 && draft_info[2] == 'P')
+        m_pExchExt->m_protoSelection = PROTOCOL_OPENPGP;
+      else if (draft_info && strlen (draft_info) >= 3 && draft_info[2] == 'X')
+        m_pExchExt->m_protoSelection = PROTOCOL_SMIME;
+      else
+        m_pExchExt->m_protoSelection = opt.default_protocol;
       update_protocol_menu (eecb);
 
-      m_pExchExt->m_gpgEncrypt = opt.encrypt_default;
+      if (draft_info && draft_info[0] == 'E')
+        m_pExchExt->m_gpgEncrypt = true;
+      else if (draft_info && draft_info[0] == 'e')
+        m_pExchExt->m_gpgEncrypt = false;
+      else
+        m_pExchExt->m_gpgEncrypt = opt.encrypt_default;
+
+      if (draft_info && draft_info[0] && draft_info[1] == 'S')
+        m_pExchExt->m_gpgSign = true;
+      else if (draft_info && draft_info[0] && draft_info[1] == 's')
+        m_pExchExt->m_gpgSign = false;
+      else
+        m_pExchExt->m_gpgSign = opt.sign_default;
 
-      m_pExchExt->m_gpgSign    = opt.sign_default;
       if (force_encrypt)
         m_pExchExt->m_gpgEncrypt = true;
       check_menu (eecb, m_nCmdEncrypt, m_pExchExt->m_gpgEncrypt);
@@ -615,6 +640,9 @@ GpgolExtCommands::InstallCommands (
         _("Open the certificate manager"), IDB_KEY_MANAGER, m_nCmdKeyManager,
         NULL, 0, 0);
     }
+
+  xfree (draft_info);
+
   return S_FALSE;
 }
 
@@ -868,6 +896,32 @@ GpgolExtCommands::DoCommand (LPEXCHEXTCALLBACK eecb, UINT nCommandID)
       ul_release (message, __func__, __LINE__);
       ul_release (mdb, __func__, __LINE__);
     }
+  else if (nCommandID == EECMDID_SaveMessage
+           && m_lContext == EECONTEXT_SENDNOTEMESSAGE) 
+    {
+      char buf[4];
+      
+      log_debug ("%s:%s: command SaveMessage called\n", SRCNAME, __func__);
+      buf[0] = m_pExchExt->m_gpgEncrypt? 'E':'e';
+      buf[1] = m_pExchExt->m_gpgSign? 'S':'s';
+      switch (m_pExchExt->m_protoSelection)
+        {
+        case PROTOCOL_UNKNOWN: buf[2] = 'A'; break;
+        case PROTOCOL_OPENPGP: buf[2] = 'P'; break;
+        case PROTOCOL_SMIME:   buf[2] = 'X'; break;
+        default: buf[2] = '-'; break;
+        }
+      buf[3] = 0;
+
+      hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message);
+      if (SUCCEEDED (hr))
+        mapi_set_gpgol_draft_info (message, buf);
+      else
+        log_debug ("%s:%s: getObject failed: hr=%#lx\n",SRCNAME, __func__, hr);
+      ul_release (message, __func__, __LINE__);
+      ul_release (mdb, __func__, __LINE__);
+      return S_FALSE; /* Pass on to next handler.  */
+    }
   else
     {
       if (debug_commands)
index 23368e1..060b5ba 100644 (file)
@@ -223,6 +223,17 @@ get_gpgolcharset_tag (LPMESSAGE message, ULONG *r_tag)
 }
 
 
+/* Return the property tag for GpgOL Draft Info.  */
+int 
+get_gpgoldraftinfo_tag (LPMESSAGE message, ULONG *r_tag)
+{
+  if (!(*r_tag = create_gpgol_tag (message, L"GpgOL Draft Info", __func__)))
+    return -1;
+  *r_tag |= PT_STRING8;
+  return 0;
+}
+
+
 /* Return the tag of the Internet Charset Body property which seems to
    hold the PR_BODY as received and thus before charset
    conversion.  */
@@ -2490,6 +2501,81 @@ mapi_set_gpgol_charset (LPMESSAGE obj, const char *charset)
 }
 
 
+
+/* Return GpgOL's draft info string as an allocated string.  If no
+   draft info is available, NULL is returned.  */
+char *
+mapi_get_gpgol_draft_info (LPMESSAGE msg)
+{
+  HRESULT hr;
+  LPSPropValue propval = NULL;
+  ULONG tag;
+  char *retstr;
+
+  if (get_gpgoldraftinfo_tag (msg, &tag) )
+    return NULL;
+  hr = HrGetOneProp ((LPMAPIPROP)msg, tag, &propval);
+  if (FAILED (hr))
+    return NULL;
+  if (PROP_TYPE (propval->ulPropTag) == PT_STRING8)
+    retstr = xstrdup (propval->Value.lpszA);
+  else
+    retstr = NULL;
+
+  MAPIFreeBuffer (propval);
+  return retstr;
+}
+
+
+/* Set GpgOL's draft info string to STRING.  This string is defined as:
+
+   Character 1:  'E' = encrypt selected,
+                 'e' = encrypt not selected.
+                 '-' = don't care
+   Character 2:  'S' = sign selected,
+                 's' = sign not selected.
+                 '-' = don't care
+   Character 3:  'A' = Auto protocol 
+                 'P' = OpenPGP protocol
+                 'X' = S/MIME protocol
+                 '-' = don't care
+                 
+   If string is NULL, the property will get deleted.
+
+   Note that this function does not call SaveChanges.  */
+int 
+mapi_set_gpgol_draft_info (LPMESSAGE message, const char *string)
+{
+  HRESULT hr;
+  SPropValue prop;
+  SPropTagArray proparray;
+
+  if (get_gpgoldraftinfo_tag (message, &prop.ulPropTag) )
+    return -1;
+  if (string)
+    {
+      prop.Value.lpszA = xstrdup (string);
+      hr = HrSetOneProp (message, &prop);      
+      xfree (prop.Value.lpszA);
+    }
+  else
+    {
+      proparray.cValues = 1;
+      proparray.aulPropTag[0] = prop.ulPropTag;
+      hr = message->DeleteProps (&proparray, NULL);
+    }
+  if (hr)
+    {
+      log_error ("%s:%s: can't %s %s property: hr=%#lx\n",
+                 SRCNAME, __func__, string?"set":"delete",
+                 "GpgOL Draft Info", hr); 
+      return -1;
+    }
+
+  return 0;
+}
+
+
 /* Return the MIME info as an allocated string.  Will never return
    NULL.  */
 char *
index 12f96b9..05417c6 100644 (file)
@@ -145,6 +145,10 @@ int mapi_set_gpgol_msg_class (LPMESSAGE message, const char *name);
 char *mapi_get_gpgol_charset (LPMESSAGE obj);
 int mapi_set_gpgol_charset (LPMESSAGE obj, const char *charset);
 
+char *mapi_get_gpgol_draft_info (LPMESSAGE msg);
+int   mapi_set_gpgol_draft_info (LPMESSAGE message, const char *string);
+
+
 int  mapi_set_attach_hidden (LPATTACH attach);
 int  mapi_test_attach_hidden (LPATTACH attach);
 
index c881ea6..e0c5f81 100644 (file)
@@ -1075,6 +1075,10 @@ finalize_message (LPMESSAGE message, mapi_attach_item_t *att_table,
   if (delete_all_attachments (message, att_table))
     return -1;
 
+  /* Remove the draft info so that we don't leak the information on
+     whether the message has been signed etc.  */
+  mapi_set_gpgol_draft_info (message, NULL);
+
   return mapi_save_changes (message, KEEP_OPEN_READWRITE|FORCE_SAVE);
 }
 
index b74b2fe..74f1143 100644 (file)
@@ -69,6 +69,7 @@ extern "C" {
 
 
 /* Command IDs. */
+#define EECMDID_SaveMessage                     13  /* (name guessed) */
 #define EECMDID_PrevMessage                     87  /* (name guessed) */
 #define EECMDID_NextMessage                     88  /* (name guessed) */
 #define EECMDID_Format                         110