Preparing a new release gpgol-0.9.4
authorWerner Koch <wk@gnupg.org>
Tue, 6 Dec 2005 10:46:25 +0000 (10:46 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 6 Dec 2005 10:46:25 +0000 (10:46 +0000)
13 files changed:
ChangeLog
NEWS
configure.ac
po/de.po
src/ChangeLog
src/Makefile.am
src/display.cpp
src/engine-gpgme.c
src/engine.h
src/gpgmsg.cpp
src/gpgmsg.hh
src/olflange.cpp
src/recipient-dialog.c

index ebd4a28..5584a62 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2005-12-06  Werner Koch  <wk@g10code.com>
+
+       Released 0.9.4.
+
 2005-12-02  Werner Koch  <wk@g10code.com>
 
        * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): New.
diff --git a/NEWS b/NEWS
index 93204ed..4b98f30 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-Noteworthy changes for version 0.9.4
+Noteworthy changes for version 0.9.4 (2005-12-06)
 =================================================
 
 * Added translation framework.  Provided German translation.
@@ -7,6 +7,10 @@ Noteworthy changes for version 0.9.4
 
 * Removed deprecated options to configure gpg path and homedir.
 
+* Default key from the option dialog works.
+
+* Support for HTML mails.
+
 
 Noteworthy changes for version 0.9.3 (2005-09-29)
 =================================================
index f0ca324..c8e2c6b 100644 (file)
@@ -16,7 +16,7 @@ min_automake_version="1.9.4"
 # Version number: Remember to change it immediately *after* a release.
 #                 Make sure to run  "svn up" before a "make dist".
 #                 Add a "-cvs" prefix for non-released code.
-AC_INIT(gpgol, 0.9.4-cvs, bug-gpgol@g10code.com)
+AC_INIT(gpgol, 0.9.4, bug-gpgol@g10code.com)
 
 NEED_GPGME_API=1
 NEED_GPGME_VERSION=1.1.0
index 2c4a1e5..6cd4c3d 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: GPGol 0.9.4\n"
 "Report-Msgid-Bugs-To: bug-gpgol@g10code.com\n"
-"POT-Creation-Date: 2005-12-02 17:48+0100\n"
-"PO-Revision-Date: 2005-11-30 17:06+0100\n"
+"POT-Creation-Date: 2005-12-06 11:07+0100\n"
+"PO-Revision-Date: 2005-12-06 11:09+0100\n"
 "Last-Translator: Werner Koch <wk@gnupg.org>\n"
 "Language-Team: de\n"
 "MIME-Version: 1.0\n"
@@ -16,66 +16,65 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 
 #: src/config-dialog.c:298
-#, fuzzy
 msgid "Select GPG Key Manager"
-msgstr "Die GPG Schlüsselverwaltung öffnen"
+msgstr "Das Schlüsselverwaltungsprogramm festlegen"
 
-#: src/engine-gpgme.c:892
+#: src/engine-gpgme.c:942
 msgid "Fingerprint: "
 msgstr "Fingerabdruck: "
 
-#: src/engine-gpgme.c:949
+#: src/engine-gpgme.c:999
 msgid "This signature is valid\n"
 msgstr "Diese Unterschrift ist korrekt\n"
 
-#: src/engine-gpgme.c:951
+#: src/engine-gpgme.c:1001
 msgid "signature state is \"green\"\n"
 msgstr "Status der Unterschrift ist \"grün\"\n"
 
-#: src/engine-gpgme.c:953
+#: src/engine-gpgme.c:1003
 msgid "signature state is \"red\"\n"
 msgstr "Status der Unterschrift ist \"rot\"\n"
 
-#: src/engine-gpgme.c:957
+#: src/engine-gpgme.c:1007
 msgid "Warning: One of the keys has been revoked\n"
 msgstr "Warnung: Einer der Schlüssel wurde widerrufen\n"
 
-#: src/engine-gpgme.c:967
+#: src/engine-gpgme.c:1017
 msgid "Warning: The key used to create the signature expired at: "
 msgstr ""
 "Warnung: Der Schlüssel mit der diese Unterschrift erzeugt wurde verfiel am: "
 
-#: src/engine-gpgme.c:973
+#: src/engine-gpgme.c:1023
 msgid "Warning: At least one certification key has expired\n"
 msgstr ""
 "Warnung: Mindestens einer der Zertifizierungsschlüssel ist abgelaufen\n"
 
-#: src/engine-gpgme.c:979
+#: src/engine-gpgme.c:1029
 msgid "Warning: The signature expired at: "
 msgstr "Die Unterschrift verfiel am: "
 
-#: src/engine-gpgme.c:985
+#: src/engine-gpgme.c:1035
 msgid "Can't verify due to a missing key or certificate\n"
 msgstr ""
 "Aufrund eines fehlenden Schlüssels ist eine Überprüfung nicht möglich\n"
 
-#: src/engine-gpgme.c:989
+#: src/engine-gpgme.c:1039
 msgid "The CRL is not available\n"
 msgstr "Die CRL ist nicht verfügbar\n"
 
-#: src/engine-gpgme.c:995
+#: src/engine-gpgme.c:1045
 msgid "Available CRL is too old\n"
 msgstr "Die vorhandene CRL ist zu alt\n"
 
-#: src/engine-gpgme.c:1000
+#: src/engine-gpgme.c:1050
 msgid "A policy requirement was not met\n"
 msgstr "Eine Richtlinie wurde nicht erfüllt\n"
 
-#: src/engine-gpgme.c:1006
+#: src/engine-gpgme.c:1056
 msgid "A system error occured"
 msgstr "Ein Systemfehler ist aufgetreten"
 
-#: src/engine-gpgme.c:1043
+#: src/engine-gpgme.c:1093
 msgid ""
 "WARNING: We have NO indication whether the key belongs to the person named "
 "as shown above\n"
@@ -83,12 +82,12 @@ msgstr ""
 "WARNUNG: Es gibt keinen Hinweis darauf, ob der Schlüssel wirklich der Person "
 "gehört, die oben angezeigt ist\n"
 
-#: src/engine-gpgme.c:1050
+#: src/engine-gpgme.c:1100
 msgid "WARNING: The key does NOT BELONG to the person named as shown above\n"
 msgstr ""
 "WARNUNG: Der Schlüssel gehört NICHT der Person die oben angezeigt ist\n"
 
-#: src/engine-gpgme.c:1054
+#: src/engine-gpgme.c:1104
 msgid ""
 "WARNING: It is NOT certain that the key belongs to the person named as shown "
 "above\n"
@@ -96,78 +95,72 @@ msgstr ""
 "WARNING: Es ist nicht sicher, daß der Schlüssel der Person gehört, die oben "
 "angezeigt ist\n"
 
-#: src/engine-gpgme.c:1087
+#: src/engine-gpgme.c:1137
 msgid "Verification started at: "
 msgstr "Überprüfung begann am: "
 
-#: src/engine-gpgme.c:1092
+#: src/engine-gpgme.c:1142
 msgid "Verification result for: "
 msgstr "Prüfungsresultat für: "
 
-#: src/engine-gpgme.c:1093
+#: src/engine-gpgme.c:1143
 msgid "[unnamed part]"
 msgstr "[Unbenannter Teil]"
 
-#: src/engine-gpgme.c:1111 src/engine-gpgme.c:1141
+#: src/engine-gpgme.c:1161 src/engine-gpgme.c:1191
 msgid "Good signature from: "
 msgstr "Korrekte Unterschrift von: "
 
-#: src/engine-gpgme.c:1118
+#: src/engine-gpgme.c:1168
 msgid "                aka: "
 msgstr "                    alias: "
 
-#: src/engine-gpgme.c:1122 src/engine-gpgme.c:1144
+#: src/engine-gpgme.c:1172 src/engine-gpgme.c:1194
 msgid "            created: "
 msgstr "                  erzeugt: "
 
-#: src/engine-gpgme.c:1131
+#: src/engine-gpgme.c:1181
 msgid "*BAD* signature claimed to be from: "
 msgstr "*FALSCHE* Unterschrift, vorgeblich von: "
 
-#: src/engine-gpgme.c:1154
+#: src/engine-gpgme.c:1204
 msgid "Error checking signature"
 msgstr "Fehler beim Prüfen der Unetrschrift"
 
-#: src/engine-gpgme.c:1170
+#: src/engine-gpgme.c:1220
 msgid "*** Begin Notation (signature by: "
 msgstr "*** Anfang Notation (Unterschrift von: "
 
-#: src/engine-gpgme.c:1190
+#: src/engine-gpgme.c:1240
 msgid "*** End Notation ***\n"
 msgstr "*** Ende Notation ***\n"
 
-#: src/gpgmsg.cpp:767
-msgid "[No attestation computed (e.g. messages was not signed)"
-msgstr ""
-"[Kein Testat berechnet (z.B. da die Nachricht nicht unterschrieben war)"
-
-#: src/gpgmsg.cpp:892
+#: src/gpgmsg.cpp:1039
 msgid "No valid OpenPGP data found."
 msgstr "Keine gültigen OpenPGP Daten gefunden"
 
-#: src/gpgmsg.cpp:893 src/gpgmsg.cpp:937 src/gpgmsg.cpp:951 src/gpgmsg.cpp:967
-#: src/gpgmsg.cpp:1048
+#: src/gpgmsg.cpp:1040 src/gpgmsg.cpp:1084 src/gpgmsg.cpp:1098
+#: src/gpgmsg.cpp:1114 src/gpgmsg.cpp:1279
 msgid "Decryption"
 msgstr "Entschlüsselung"
 
-#: src/gpgmsg.cpp:928
-#, fuzzy
+#: src/gpgmsg.cpp:1075
 msgid "[This is a PGP/MIME message]"
 msgstr "[PGP/MIME Nachricht]"
 
-#: src/gpgmsg.cpp:936 src/gpgmsg.cpp:950 src/gpgmsg.cpp:966
+#: src/gpgmsg.cpp:1083 src/gpgmsg.cpp:1097 src/gpgmsg.cpp:1113
 msgid "Problem decrypting PGP/MIME message"
 msgstr "Problem bei Entschlüsseln einer PGP/MIME Nachricht"
 
-#: src/gpgmsg.cpp:1001
+#: src/gpgmsg.cpp:1234
 msgid "Verification Failure"
 msgstr "Überprüfungsfehler"
 
-#: src/gpgmsg.cpp:1004
+#: src/gpgmsg.cpp:1237
 msgid "Decryption Failure"
 msgstr "Entschlüsselungsfehler"
 
-#: src/gpgmsg.cpp:1042
+#: src/gpgmsg.cpp:1273
 msgid ""
 "The message text cannot be displayed.\n"
 "You have to save the decrypted message to view it.\n"
@@ -183,7 +176,7 @@ msgstr ""
 
 #. TRANSLATORS: Keep the @LIST@ verbatim on a separate line; it
 #. will be expanded to a list of atatchment names.
-#: src/gpgmsg.cpp:1069
+#: src/gpgmsg.cpp:1300
 msgid ""
 "Signed attachments found.\n"
 "\n"
@@ -195,13 +188,13 @@ msgstr ""
 "@LIST@\n"
 "Möchten Sie diese Unterschriften überprüfen?"
 
-#: src/gpgmsg.cpp:1077
+#: src/gpgmsg.cpp:1308
 msgid "Attachment Verification"
 msgstr "Überprüfung der Anhänge"
 
 #. TRANSLATORS: Keep the @LIST@ verbatim on a separate line; it
 #. will be expanded to a list of atatchment names.
-#: src/gpgmsg.cpp:1095
+#: src/gpgmsg.cpp:1329
 msgid ""
 "Encrypted attachments found.\n"
 "\n"
@@ -213,35 +206,35 @@ msgstr ""
 "@LIST@\n"
 "Möchten Sie diese entschlüsseln und abspeichern?"
 
-#: src/gpgmsg.cpp:1102
+#: src/gpgmsg.cpp:1336
 msgid "Attachment Decryption"
 msgstr "Entschlüsselung eines Anhangs"
 
-#: src/gpgmsg.cpp:1166
+#: src/gpgmsg.cpp:1405
 msgid "Signing Failure"
 msgstr "Unterschrifterstellungsfehler"
 
-#: src/gpgmsg.cpp:1314
+#: src/gpgmsg.cpp:1581
 msgid "Encryption Failure"
 msgstr "Verschlüsselungsfehler"
 
-#: src/gpgmsg.cpp:1350 src/gpgmsg.cpp:2645
+#: src/gpgmsg.cpp:1635 src/gpgmsg.cpp:2930
 msgid "Attachment Encryption Failure"
 msgstr "Verschlüsselungsfehler eines Anhangs"
 
-#: src/gpgmsg.cpp:2052
+#: src/gpgmsg.cpp:2337
 msgid "Attachment Verification Failure"
 msgstr "Überprüfungsfehler eines Anhangs"
 
-#: src/gpgmsg.cpp:2235 src/gpgmsg.cpp:2284
+#: src/gpgmsg.cpp:2520 src/gpgmsg.cpp:2569
 msgid "Attachment Decryption Failure"
 msgstr "Entschlüsselungsfehler eines Anhangs"
 
-#: src/gpgmsg.cpp:2454
+#: src/gpgmsg.cpp:2739
 msgid "Attachment Signing Failure"
 msgstr "Unterschrifterstellungsfehler eines Anhangs"
 
-#: src/olflange.cpp:884
+#: src/olflange.cpp:896
 msgid ""
 "Sorry, we can only encrypt plain text messages and\n"
 "no RTF messages. Please make sure that only the text\n"
@@ -252,51 +245,51 @@ msgstr ""
 "Sie sicher, daß lediglich das Text Format ausgewählt wurde.\n"
 "(In der Menüleiste: \"Format\" => \"Nur Text\")"
 
-#: src/olflange.cpp:1272
+#: src/olflange.cpp:1286
 msgid "&Decrypt and verify message"
 msgstr "Entschlüsseln/Prüfen der Nachricht"
 
-#: src/olflange.cpp:1310
+#: src/olflange.cpp:1324
 msgid "GPG &encrypt message"
 msgstr "Mit GPG &verschlüsseln"
 
-#: src/olflange.cpp:1316
+#: src/olflange.cpp:1330
 msgid "GPG &sign message"
 msgstr "Mit GPG unter&schreiben"
 
-#: src/olflange.cpp:1362
+#: src/olflange.cpp:1376
 msgid "GPG Key &Manager"
 msgstr "GPG Schlüssel&verwaltung"
 
-#: src/olflange.cpp:1494
+#: src/olflange.cpp:1508
 msgid "Could not start Key-Manager"
 msgstr "Dei Schlüsselverwaltung konnte nicht aufgerufen werden"
 
-#: src/olflange.cpp:1540
+#: src/olflange.cpp:1554
 msgid "Decrypt and verify the message."
 msgstr "Entschlüsseln und Prüfen der Nachricht."
 
-#: src/olflange.cpp:1548
+#: src/olflange.cpp:1562
 msgid "Select this option to encrypt the message."
 msgstr "Wählen Sie diese Option zum Verschlüsseln der Nachricht."
 
-#: src/olflange.cpp:1554
+#: src/olflange.cpp:1568
 msgid "Select this option to sign the message."
 msgstr "Wählen Sie diese Option zum Unterschreiben der Nachricht."
 
-#: src/olflange.cpp:1563 src/olflange.cpp:1624 src/olflange.cpp:1706
+#: src/olflange.cpp:1577 src/olflange.cpp:1638 src/olflange.cpp:1720
 msgid "Open GPG Key Manager"
 msgstr "Die GPG Schlüsselverwaltung öffnen"
 
-#: src/olflange.cpp:1593 src/olflange.cpp:1657
+#: src/olflange.cpp:1607 src/olflange.cpp:1671
 msgid "Decrypt message and verify signature"
 msgstr "Nachricht entschlüsseln und Unterschrift prüfen"
 
-#: src/olflange.cpp:1604 src/olflange.cpp:1675
+#: src/olflange.cpp:1618 src/olflange.cpp:1689
 msgid "Encrypt message with GPG"
 msgstr "Nachricht mit GPG verschlüsseln"
 
-#: src/olflange.cpp:1613 src/olflange.cpp:1690
+#: src/olflange.cpp:1627 src/olflange.cpp:1704
 msgid "Sign message with GPG"
 msgstr "Nachricht mit GPG unterschreiben"
 
@@ -368,7 +361,7 @@ msgstr "[PGP/MIME Nachricht]"
 msgid "[PGP/MIME message without plain text body]"
 msgstr "[PGP/MIME Nachricht ohne reinen Textkörper]"
 
-#: src/recipient-dialog.c:459
+#: src/recipient-dialog.c:477
 msgid ""
 "If you cancel this dialog, the message will be sent in cleartext.\n"
 "\n"
@@ -379,11 +372,11 @@ msgstr ""
 "\n"
 "Möchten Sie wirklich abbrechen?"
 
-#: src/recipient-dialog.c:462
+#: src/recipient-dialog.c:480
 msgid "Recipient Dialog"
 msgstr "Auswahl des Empfängerschlüssels"
 
-#: src/recipient-dialog.c:537 src/verify-dialog.c:152
+#: src/recipient-dialog.c:555 src/verify-dialog.c:152
 msgid "User-ID not found"
 msgstr "User-ID nicht gefunden"
 
@@ -431,3 +424,7 @@ msgstr "Die Unterschrift stammt von einem ungültigen Schlüssel."
 #: src/verify-dialog.c:205
 msgid "Verification Result"
 msgstr "Prüfungsresultat"
+
+#~ msgid "[No attestation computed (e.g. messages was not signed)"
+#~ msgstr ""
+#~ "[Kein Testat berechnet (z.B. da die Nachricht nicht unterschrieben war)"
index 6f4ee2c..619e601 100644 (file)
@@ -1,3 +1,26 @@
+2005-12-06  Werner Koch  <wk@g10code.com>
+
+       * gpgmsg.cpp (getRecipients): Add the default key to the list of
+       recipients.
+       * recipient-dialog.c (recipient_dlg_proc): Add the already found
+       keys to the selected ones.
+
+       * olflange.cpp (OnWriteComplete): Need to disable the deleting of
+       HTML bodys.
+
+2005-12-05  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (gpgol_LDADD): Add -loleaut32.
+       * engine-gpgme.c (op_verify_detached_sig_mem): New.
+       * olflange.cpp (OnWriteComplete): Pass HTML flag to sign call.
+       (put_outlook_property): Need to use a BSTR for the sake of putting
+       HTMLBody.
+       * gpgmsg.cpp (sign): Add arg WANT_HTML.
+       (free_attach_info): New.  Use it in the destructor.
+       (createHtmlAttachment): New.
+       (encrypt_and_sign, sign): Use it here.
+       (writeAttestation): Don't write an empty attestation.
+
 2005-12-02  Werner Koch  <wk@g10code.com>
 
        * verify-dialog.c (verify_dialog_box): Actually allow for German
index cb2e32e..cafc8dd 100644 (file)
@@ -69,7 +69,8 @@ clean-local:
        rm -f libmapi32.a libgpgme.a libgpg-error.a
 
 gpgol_LDADD = $(srcdir)/gpgol.def  \
-       -L . -lgpgme -lgpg-error -lmapi32 -lshell32 -lgdi32 -lcomdlg32
+       -L . -lgpgme -lgpg-error -lmapi32 -lshell32 -lgdi32 -lcomdlg32 \
+        -loleaut32
 
 resource.o: resource.rc versioninfo.rc gpgol-rsrcs.rc olflange-rsrcs.rc
 
index e8699a9..a3a1f75 100644 (file)
@@ -138,7 +138,7 @@ update_display (HWND hwnd, GpgMsg *msg, void *exchange_cb,
   HWND window;
 
   window = find_message_window (hwnd);
-  if (window)
+  if (window && !is_html)
     {
       const char *s;
 
@@ -161,7 +161,11 @@ update_display (HWND hwnd, GpgMsg *msg, void *exchange_cb,
     }
   else if (exchange_cb && !opt.compat.no_oom_write)
     {
-      log_debug ("updating display using OOM");
+      log_debug ("updating display using OOM to `%s'", text);
+      /* Bug in OL 2002 and 2003 - as a workaround set the body first
+         to empty. */
+      if (is_html)
+        put_outlook_property (exchange_cb, "Body", "" );
       return put_outlook_property (exchange_cb, is_html? "HTMLBody":"Body",
                                    text);
     }
@@ -185,6 +189,13 @@ set_message_body (LPMESSAGE message, const char *string, bool is_html)
   const char *s;
   
   assert (message);
+
+//   if (!is_html)
+//     {
+//       prop.ulPropTag = PR_BODY_HTML_A;
+//       prop.Value.lpszA = "";
+//       hr = HrSetOneProp (message, &prop);
+//     }
   
   /* Decide whether we need to use the Unicode version. */
   for (s=string; *s && !(*s & 0x80); s++)
index aa27ca9..664ccce 100644 (file)
@@ -866,6 +866,56 @@ op_verify_detached_sig (LPSTREAM data_stream,
   return err;
 }
 
+/* Verify a detached message where the data is in the string
+   DATA_STRING and the signature itself is expected to be the string
+   SIG_STRING.  FILENAME will be shown by the verification status
+   dialog box.  If ATTESTATION is not NULL a text with the result of
+   the signature verification will get printed to it.  */ 
+int
+op_verify_detached_sig_mem (const char *data_string,
+                            const char *sig_string, const char *filename,
+                            gpgme_data_t attestation)
+{
+  gpgme_data_t data = NULL;
+  gpgme_data_t sig = NULL;
+  gpgme_ctx_t ctx = NULL;
+  gpgme_error_t err;
+  gpgme_verify_result_t res = NULL;
+
+  op_init ();
+
+  err = gpgme_new (&ctx);
+  if (err)
+    goto leave;
+
+  err = gpgme_data_new_from_mem (&data, data_string, strlen (data_string), 0);
+  if (err)
+    goto leave;
+
+  err = gpgme_data_new_from_mem (&sig, sig_string, strlen (sig_string), 0);
+  if (err)
+    goto leave;
+
+  err = gpgme_op_verify (ctx, sig, data, NULL);
+  if (!err)
+    {
+      res = gpgme_op_verify_result (ctx);
+      if (res) 
+        verify_dialog_box (res, filename);
+      if (res && attestation)
+        add_verify_attestation (attestation, ctx, res, filename);
+    }
+
+ leave:
+  if (data)
+    gpgme_data_release (data);
+  if (sig)
+    gpgme_data_release (sig);
+  if (ctx)
+    gpgme_release (ctx);
+  return err;
+}
+
 
 \f
 static void
index d082fcb..e5b725d 100644 (file)
@@ -72,6 +72,9 @@ int op_verify (const char *inbuf, char **outbuf, const char *filename,
                gpgme_data_t attestation);
 int op_verify_detached_sig (LPSTREAM data, const char *sig,
                             const char *filename, gpgme_data_t attestation);
+int op_verify_detached_sig_mem (const char *data_string,
+                                const char *sig_string, const char *filename,
+                                gpgme_data_t attestation);
 
 
 int op_export_keys (const char *pattern[], const char *outfile);
index 6bcf65b..0aae83e 100644 (file)
@@ -84,6 +84,7 @@ typedef struct attach_info *attach_info_t;
 
 
 static int get_attach_method (LPATTACH obj);
+static char *get_short_attach_data (LPATTACH obj);
 static bool set_x_header (LPMESSAGE msg, const char *name, const char *val);
 
 
@@ -116,16 +117,7 @@ public:
     if (attestation)
       gpgme_data_release (attestation);
 
-    if (attach.att_table)
-      {
-        attach.att_table->Release ();
-        attach.att_table = NULL;
-      }
-    if (attach.rows)
-      {
-        FreeProws (attach.rows);
-        attach.rows = NULL;
-      }
+    free_attach_info ();
   }
 
   void destroy ()
@@ -168,7 +160,7 @@ public:
   const char *getPlainText (void);
 
   int decrypt (HWND hwnd);
-  int sign (HWND hwnd);
+  int sign (HWND hwnd, bool want_html);
   int encrypt (HWND hwnd, bool want_html)
   {
     return encrypt_and_sign (hwnd, want_html, false);
@@ -210,9 +202,11 @@ private:
     LPSRowSet   rows;     /* The retrieved set of rows from the table. */
   } attach;
   
+  void free_attach_info (void);
   char *loadBody (bool want_html);
   bool isPgpmimeVersionPart (int pos);
   void writeAttestation (void);
+  gpg_error_t createHtmlAttachment (const char *text);
   attach_info_t gatherAttachmentInfo (void);
   int encrypt_and_sign (HWND hwnd, bool want_html, bool sign);
 };
@@ -230,6 +224,20 @@ CreateGpgMsg (LPMESSAGE msg)
   return m;
 }
 
+void
+GpgMsgImpl::free_attach_info (void)
+{
+  if (attach.att_table)
+    {
+      attach.att_table->Release ();
+      attach.att_table = NULL;
+    }
+  if (attach.rows)
+    {
+      FreeProws (attach.rows);
+      attach.rows = NULL;
+    }
+}
 
 /* Release an array of GPGME keys. */
 static void 
@@ -615,7 +623,7 @@ GpgMsgImpl::getRecipients ()
       return NULL;
     }
 
-  rset = (char**)xcalloc (lpRecipientRows->cRows+1, sizeof *rset);
+  rset = (char**)xcalloc (lpRecipientRows->cRows+2, sizeof *rset);
 
   for (i = j = 0; (unsigned int)i < lpRecipientRows->cRows; i++)
     {
@@ -646,6 +654,8 @@ GpgMsgImpl::getRecipients ()
           break;
         }
     }
+  if (opt.default_key && *opt.default_key)
+    rset[j++] = xstrdup (opt.default_key);
   rset[j] = NULL;
 
   if (lpRecipientTable)
@@ -709,7 +719,7 @@ GpgMsgImpl::writeAttestation (void)
       goto leave;
     }
 
-  /* And not for the real name. */
+  /* And now for the real name. */
   prop.ulPropTag = PR_ATTACH_LONG_FILENAME_A;
   prop.Value.lpszA = "GPGol-Attestation.txt";
   hr = HrSetOneProp (newatt, &prop);
@@ -760,25 +770,130 @@ GpgMsgImpl::writeAttestation (void)
     }
   attestation = NULL;
 
+  if (!*buffer)
+    goto leave;
+
   log_debug ("writing attestation `%s'\n", buffer);
   hr = S_OK;
-  if (!*buffer)
+  for (p=buffer; hr == S_OK && (pend = strchr (p, '\n')); p = pend+1)
     {
-      const char *s = _("[No attestation computed "
-                        "(e.g. messages was not signed)");
-      hr = to->Write (s, strlen (s), &nwritten);
+      hr = to->Write (p, pend - p, &nwritten);
+      if (hr == S_OK)
+        hr = to->Write ("\r\n", 2, &nwritten);
     }
-  else
+  if (*p && hr == S_OK)
+    hr = to->Write (p, strlen (p), &nwritten);
+  if (hr != S_OK)
     {
-      for (p=buffer; hr == S_OK && (pend = strchr (p, '\n')); p = pend+1)
-        {
-          hr = to->Write (p, pend - p, &nwritten);
-          if (hr == S_OK)
-            hr = to->Write ("\r\n", 2, &nwritten);
-        }
-      if (*p && hr == S_OK)
-        hr = to->Write (p, strlen (p), &nwritten);
+      log_debug ("%s:%s: Write failed: hr=%#lx", SRCNAME, __func__, hr);
+      goto leave;
     }
+      
+  
+  to->Commit (0);
+  to->Release ();
+  to = NULL;
+  
+  hr = newatt->SaveChanges (0);
+  if (hr != S_OK)
+    {
+      log_error ("%s:%s: SaveChanges(attachment) failed: hr=%#lx\n",
+                 SRCNAME, __func__, hr); 
+      goto leave;
+    }
+  hr = message->SaveChanges (KEEP_OPEN_READWRITE|FORCE_SAVE);
+  if (hr != S_OK)
+    {
+      log_error ("%s:%s: SaveChanges(message) failed: hr=%#lx\n",
+                 SRCNAME, __func__, hr); 
+      goto leave;
+    }
+
+
+ leave:
+  if (to)
+    {
+      to->Revert ();
+      to->Release ();
+    }
+  if (newatt)
+    newatt->Release ();
+  gpgme_free (buffer);
+}
+
+
+/* Create a new HTML attachment from TEXT and store it as the standard
+   HTML attachment (according to PGP rules).  */
+gpg_error_t
+GpgMsgImpl::createHtmlAttachment (const char *text)
+{
+  HRESULT hr;
+  ULONG newpos;
+  SPropValue prop;
+  LPATTACH newatt = NULL;
+  LPSTREAM to = NULL;
+  ULONG nwritten;
+  gpg_error_t err = gpg_error (GPG_ERR_GENERAL);
+  
+  hr = message->CreateAttach (NULL, 0, &newpos, &newatt);
+  if (hr != S_OK)
+    {
+      log_error ("%s:%s: can't create HTML attachment: hr=%#lx\n",
+                 SRCNAME, __func__, hr); 
+      goto leave;
+    }
+          
+  prop.ulPropTag = PR_ATTACH_METHOD;
+  prop.Value.ul = ATTACH_BY_VALUE;
+  hr = HrSetOneProp (newatt, &prop);
+  if (hr != S_OK)
+    {
+      log_error ("%s:%s: can't set HTML attach method: hr=%#lx\n",
+                 SRCNAME, __func__, hr); 
+      goto leave;
+    }
+  
+  prop.ulPropTag = PR_ATTACH_LONG_FILENAME_A;
+  prop.Value.lpszA = "PGPexch.htm";
+  hr = HrSetOneProp (newatt, &prop);
+  if (hr != S_OK)
+    {
+      log_error ("%s:%s: can't set HTML attach filename: hr=%#lx\n",
+                 SRCNAME, __func__, hr); 
+      goto leave;
+    }
+
+  prop.ulPropTag = PR_ATTACH_TAG;
+  prop.Value.bin.cb  = sizeof oid_mimetag;
+  prop.Value.bin.lpb = (LPBYTE)oid_mimetag;
+  hr = HrSetOneProp (newatt, &prop);
+  if (hr != S_OK)
+    {
+      log_error ("%s:%s: can't set HTML attach tag: hr=%#lx\n",
+                 SRCNAME, __func__, hr); 
+      goto leave;
+    }
+
+  prop.ulPropTag = PR_ATTACH_MIME_TAG_A;
+  prop.Value.lpszA = "text/html";
+  hr = HrSetOneProp (newatt, &prop);
+  if (hr != S_OK)
+    {
+      log_error ("%s:%s: can't set HTML attach mime tag: hr=%#lx\n",
+                 SRCNAME, __func__, hr); 
+      goto leave;
+    }
+
+  hr = newatt->OpenProperty (PR_ATTACH_DATA_BIN, &IID_IStream, 0,
+                             MAPI_CREATE|MAPI_MODIFY, (LPUNKNOWN*)&to);
+  if (FAILED (hr)) 
+    {
+      log_error ("%s:%s: can't create output stream: hr=%#lx\n",
+                 SRCNAME, __func__, hr); 
+      goto leave;
+    }
+  
+  hr = to->Write (text, strlen (text), &nwritten);
   if (hr != S_OK)
     {
       log_debug ("%s:%s: Write failed: hr=%#lx", SRCNAME, __func__, hr);
@@ -805,6 +920,7 @@ GpgMsgImpl::writeAttestation (void)
       goto leave;
     }
 
+  err = 0;
 
  leave:
   if (to)
@@ -814,7 +930,7 @@ GpgMsgImpl::writeAttestation (void)
     }
   if (newatt)
     newatt->Release ();
-  gpgme_free (buffer);
+  return err;
 }
 
 
@@ -833,8 +949,12 @@ GpgMsgImpl::decrypt (HWND hwnd)
   unsigned int n_attach = 0;
   unsigned int n_encrypted = 0;
   unsigned int n_signed = 0;
+  int have_pgphtml_sig = 0;
+  int have_pgphtml_enc = 0;
+  unsigned int pgphtml_pos = 0;
   HRESULT hr;
   int pgpmime_succeeded = 0;
+  int is_html = 0;
   char *body;
 
   /* Load the body text into BODY.  Note that body may be NULL but in
@@ -851,15 +971,42 @@ GpgMsgImpl::decrypt (HWND hwnd)
     {
       for (pos=0; !table[pos].end_of_table; pos++)
         if (table[pos].is_encrypted)
-          n_encrypted++;
+          {
+            if (!have_pgphtml_enc && !have_pgphtml_sig
+                && table[pos].filename
+                && !strcmp (table[pos].filename, "PGPexch.htm.pgp")
+                && table[pos].content_type  
+                && !strcmp (table[pos].content_type,
+                            "application/pgp-encrypted"))
+              {
+                have_pgphtml_enc = 1;
+                pgphtml_pos = pos;
+              }
+            else
+              n_encrypted++;
+          }
         else if (table[pos].is_signed)
-          n_signed++;
+          {
+            if (!have_pgphtml_sig && !have_pgphtml_enc
+                && table[pos].filename
+                && !strcmp (table[pos].filename, "PGPexch.htm.asc")
+                && table[pos].content_type  
+                && !strcmp (table[pos].content_type,
+                            "application/pgp-signature"))
+              {
+                have_pgphtml_sig = 1;
+                pgphtml_pos = pos;
+              }
+            else
+              n_signed++;
+          }
       n_attach = pos;
     }
   log_debug ("%s:%s: message has %u attachments with "
              "%u signed and %d encrypted\n",
              SRCNAME, __func__, n_attach, n_signed, n_encrypted);
-  if (mtype == OPENPGP_NONE && !n_encrypted && !n_signed) 
+  if (mtype == OPENPGP_NONE && !n_encrypted && !n_signed
+      && !have_pgphtml_enc && !have_pgphtml_sig) 
     {
       /* Because we usually work around the OL object model, it can't
          notice that we changed the windows's text behind its back (by
@@ -989,6 +1136,92 @@ GpgMsgImpl::decrypt (HWND hwnd)
     {
       err = op_decrypt (body, &plaintext, opt.passwd_ttl, NULL,
                         attestation, preview);
+      if (!err && have_pgphtml_enc)
+        is_html = 1;
+    }
+  else if (mtype == OPENPGP_NONE && have_pgphtml_sig)
+    {
+      if (preview)
+        err = 0;
+      else
+        {
+          LPATTACH att;
+          char *htmlbody = loadBody (true);
+
+          if (htmlbody && *htmlbody)
+            {
+              is_html = 1;
+              hr = message->OpenAttach (pgphtml_pos, NULL,
+                                        MAPI_BEST_ACCESS, &att);       
+              if (FAILED (hr))
+                {
+                  log_error ("%s:%s: can't open attachment %d (sig): hr=%#lx",
+                             SRCNAME, __func__, pgphtml_pos, hr);
+                  err = gpg_error (GPG_ERR_GENERAL);
+                }
+              else if (table[pgphtml_pos].method != ATTACH_BY_VALUE)
+                {
+                  log_error ("%s:%s: HTML attachment: method not supported",
+                             SRCNAME, __func__);
+                  att->Release ();
+                  err = gpg_error (GPG_ERR_GENERAL);
+                }
+              else
+                {
+                  char *sigpart = get_short_attach_data (att);
+                  att->Release ();
+                  if (!sigpart)
+                    err = gpg_error (GPG_ERR_GENERAL);
+                  else
+                    {
+                      err = op_verify_detached_sig_mem (htmlbody, sigpart,
+                                                        NULL, attestation);
+                      xfree (sigpart);
+                    }
+                }
+            }
+          else
+            err = gpg_error (GPG_ERR_NO_DATA);
+          xfree (htmlbody);
+        }
+    }
+  else if (mtype == OPENPGP_NONE && have_pgphtml_enc)
+    {
+      LPATTACH att;
+      LPSTREAM from;
+
+      is_html = 1;
+      hr = message->OpenAttach (pgphtml_pos, NULL,
+                                MAPI_BEST_ACCESS, &att);       
+      if (FAILED (hr))
+        {
+          log_error ("%s:%s: can't open attachment %d (sig): hr=%#lx",
+                     SRCNAME, __func__, pgphtml_pos, hr);
+          err = gpg_error (GPG_ERR_GENERAL);
+        }
+      else if (table[pgphtml_pos].method != ATTACH_BY_VALUE)
+        {
+          log_error ("%s:%s: HTML attachment: method not supported",
+                     SRCNAME, __func__);
+          att->Release ();
+          err = gpg_error (GPG_ERR_GENERAL);
+        }
+      else if (FAILED(hr = att->OpenProperty (PR_ATTACH_DATA_BIN,
+                                              &IID_IStream, 
+                                              0, 0, (LPUNKNOWN*) &from)))
+        {
+          log_error ("%s:%s: can't open data stream of HTML attachment: "
+                     "hr=%#lx", SRCNAME, __func__, hr);
+          att->Release ();
+          err = gpg_error (GPG_ERR_GENERAL);
+        }
+      else
+        {
+          err = op_decrypt_stream_to_buffer (from, &plaintext, opt.passwd_ttl,
+                                             NULL, attestation);
+          from->Release ();
+          att->Release ();
+        }
     }
   else
     err = gpg_error (GPG_ERR_NO_DATA);
@@ -1005,8 +1238,6 @@ GpgMsgImpl::decrypt (HWND hwnd)
     }
   else if (plaintext && *plaintext)
     {  
-      int is_html = is_html_body (plaintext);
-
       log_debug ("decrypt isHtml=%d\n", is_html);
 
       /* Do we really need to set the body?  update_display below
@@ -1080,7 +1311,10 @@ GpgMsgImpl::decrypt (HWND hwnd)
       if (what == IDYES) 
         {
           for (pos=0; !table[pos].end_of_table; pos++)
-            if (table[pos].is_signed)
+            if ((have_pgphtml_sig || have_pgphtml_enc)
+                && pos == pgphtml_pos)
+              ; /* We already processed this attachment. */
+            else if (table[pos].is_signed)
               {
                 assert (table[pos].sig_pos < n_attach);
                 verifyAttachment (hwnd, table, pos, table[pos].sig_pos);
@@ -1105,7 +1339,10 @@ GpgMsgImpl::decrypt (HWND hwnd)
       if (what == IDYES) 
         {
           for (pos=0; !table[pos].end_of_table; pos++)
-            if (table[pos].is_encrypted)
+            if ((have_pgphtml_sig || have_pgphtml_enc)
+                && pos == pgphtml_pos)
+              ; /* We already processed this attachment. */
+            else if (table[pos].is_encrypted)
               decryptAttachment (hwnd, pos, true, opt.passwd_ttl,
                                  table[pos].filename);
         }
@@ -1127,7 +1364,7 @@ GpgMsgImpl::decrypt (HWND hwnd)
 \f
 /* Sign the current message. Returns 0 on success. */
 int
-GpgMsgImpl::sign (HWND hwnd)
+GpgMsgImpl::sign (HWND hwnd, bool want_html)
 {
   HRESULT hr;
   char *plaintext;
@@ -1135,11 +1372,13 @@ GpgMsgImpl::sign (HWND hwnd)
   int err = 0;
   gpgme_key_t sign_key = NULL;
   SPropValue prop;
+  int have_html_attach = 0;
 
   log_debug ("%s:%s: enter message=%p\n", SRCNAME, __func__, message);
   
   /* We don't sign an empty body - a signature on a zero length string
-     is pretty much useless. */
+     is pretty much useless.  We assume that a HTML message always
+     comes with a text/plain alternative. */
   plaintext = loadBody (false);
   if ( (!plaintext || !*plaintext) && !hasAttachments ()) 
     {
@@ -1168,7 +1407,34 @@ GpgMsgImpl::sign (HWND hwnd)
         }
     }
 
-  if (opt.auto_sign_attach && hasAttachments ())
+  
+  /* If those brain dead html mails are requested we now figure out
+     whether a HTML body is actually available and move it to an
+     attachment so that the code below will sign it as a regular
+     attachments.  */
+  if (want_html)
+    {
+      char *htmltext = loadBody (true);
+      
+      if (htmltext && *htmltext)
+        {
+          if (!createHtmlAttachment (htmltext))
+            have_html_attach = 1;
+        }
+      xfree (htmltext);
+
+      /* If we got a new attachment we need to release the loaded
+         attachment info so that the next getAttachment call will read
+         fresh info. */
+      if (have_html_attach)
+        free_attach_info ();
+    }
+
+
+  /* Note, there is a side-effect when we have HTML mails: The
+     auto-sign-attch option is ignored. I regard auto-sign-atatch as a
+     silly option anyway. */
+  if ((opt.auto_sign_attach || have_html_attach) && hasAttachments ())
     {
       unsigned int n;
       
@@ -1241,6 +1507,7 @@ GpgMsgImpl::encrypt_and_sign (HWND hwnd, bool want_html, bool sign_flag)
   int err = 0;
   size_t n_keys, n_unknown, n_recp;
   SPropValue prop;
+  int have_html_attach = 0;
     
   plaintext = loadBody (false);
   if ( (!plaintext || !*plaintext) && !hasAttachments ()) 
@@ -1315,13 +1582,6 @@ GpgMsgImpl::encrypt_and_sign (HWND hwnd, bool want_html, bool sign_flag)
           goto leave;
         }
 
-      if (want_html) 
-        {
-          char *tmp = add_html_line_endings (ciphertext);
-          xfree (ciphertext);
-          ciphertext = tmp;
-        }
-
 //       {
 //         SPropValue prop;
 //         prop.ulPropTag=PR_MESSAGE_CLASS_A;
@@ -1336,6 +1596,31 @@ GpgMsgImpl::encrypt_and_sign (HWND hwnd, bool want_html, bool sign_flag)
 
     }
 
+
+  /* If those brain dead html mails are requested we now figure out
+     whether a HTML body is actually available and move it to an
+     attachment so that the code below will sign it as a regular
+     attachments.  Note that the orginal HTML body will be deletated
+     in the code calling us. */
+  if (want_html)
+    {
+      char *htmltext = loadBody (true);
+      
+      if (htmltext && *htmltext)
+        {
+          if (!createHtmlAttachment (htmltext))
+            have_html_attach = 1;
+        }
+      xfree (htmltext);
+
+      /* If we got a new attachment we need to release the loaded
+         attachment info so that the next getAttachment call will read
+         fresh info. */
+      if (have_html_attach)
+        free_attach_info ();
+    }
+
+
   if (hasAttachments ())
     {
       unsigned int n;
@@ -1371,7 +1656,7 @@ GpgMsgImpl::encrypt_and_sign (HWND hwnd, bool want_html, bool sign_flag)
         }
 
 
-      err = set_message_body (message, ciphertext, want_html);
+      err = set_message_body (message, ciphertext, 0);
       if (err)
         goto leave;
 
@@ -1953,7 +2238,7 @@ GpgMsgImpl::gatherAttachmentInfo (void)
      OL2003 the content-type of the body is also correctly set but we
      don't make use of this as it is not clear whether this is true
      for other storage providers.  We use a hack to ignore extra
-     attesttation attachments: Those are assumed to come after the
+     attestation attachments: Those are assumed to come after the
      both PGP/MIME parts. */
   if (opt.compat.no_pgpmime)
     ;
@@ -1996,7 +2281,7 @@ GpgMsgImpl::verifyAttachment (HWND hwnd, attach_info_t table,
   assert (message);
 
   /* First we copy the actual signature into a memory buffer.  Such a
-     signature is expected to be samll enough to be readable directly
+     signature is expected to be small enough to be readable directly
      (i.e.less that 16k as suggested by the MS MAPI docs). */
   hr = message->OpenAttach (pos_sig, NULL, MAPI_BEST_ACCESS, &att);    
   if (FAILED (hr))
index f6c5459..481eb00 100644 (file)
@@ -68,7 +68,7 @@ public:
   virtual int decrypt (HWND hwnd) = 0;
 
   /* Sign the message and optionally the attachments. */
-  virtual int sign (HWND hwnd) = 0;
+  virtual int sign (HWND hwnd, bool want_html) = 0;
 
   /* Encrypt the entire message including any attachments. Returns 0
      on success. */
index f25081c..a0c6cdf 100644 (file)
@@ -208,7 +208,7 @@ ul_release (LPVOID punk)
   if (!punk)
     return;
   res = UlRelease (punk);
-  log_debug ("%s UlRelease(%p) had %lu references\n", __func__, punk, res);
+//   log_debug ("%s UlRelease(%p) had %lu references\n", __func__, punk, res);
 }
 
 
@@ -415,19 +415,31 @@ put_outlook_property (void *pEECB, const char *key, const char *value)
   else if ( (pDisp = find_outlook_property ((LPEXCHEXTCALLBACK)pEECB,
                                             key, &dispid)))
     {
+      BSTR abstr;
+
       dispparams.cNamedArgs = 1;
       dispparams.rgdispidNamedArgs = &dispid_put;
       dispparams.cArgs = 1;
       dispparams.rgvarg = &aVariant;
-      dispparams.rgvarg[0].vt = VT_LPWSTR;
-      dispparams.rgvarg[0].bstrVal = utf8_to_wchar (value);
-      hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
-                         DISPATCH_PROPERTYPUT, &dispparams,
-                         NULL, NULL, NULL);
-      xfree (dispparams.rgvarg[0].bstrVal);
-      log_debug ("%s:%s: PROPERTYPUT(%s) result -> %#lx\n",
-                 SRCNAME, __func__, key, hr);
-
+      {
+        wchar_t *tmp = utf8_to_wchar (value);
+        abstr = SysAllocString (tmp);
+        xfree (tmp);
+      }
+      if (!abstr)
+        log_error ("%s:%s: SysAllocString failed\n", SRCNAME, __func__);
+      else
+        {
+          dispparams.rgvarg[0].vt = VT_BSTR;
+          dispparams.rgvarg[0].bstrVal = abstr;
+          hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
+                              DISPATCH_PROPERTYPUT, &dispparams,
+                              NULL, NULL, NULL);
+          log_debug ("%s:%s: PROPERTYPUT(%s) result -> %#lx\n",
+                     SRCNAME, __func__, key, hr);
+          SysFreeString (abstr);
+        }
+      
       pDisp->Release ();
       pDisp = NULL;
       result = 0;
@@ -836,7 +848,7 @@ CGPGExchExtMessageEvents::OnWrite (LPEXCHEXTCALLBACK pEECB)
   /* If we are going to encrypt, check that the BodyFormat is
      something we support.  This helps avoiding surprise by sending
      out unencrypted messages. */
-  if (m_pExchExt->m_gpgEncrypt)
+  if (m_pExchExt->m_gpgEncrypt || m_pExchExt->m_gpgSign)
     {
       pDisp = find_outlook_property (pEECB, "BodyFormat", &dispid);
       if (!pDisp)
@@ -944,7 +956,7 @@ CGPGExchExtMessageEvents::OnWriteComplete (LPEXCHEXTCALLBACK pEECB,
       if (m_pExchExt->m_gpgEncrypt && !m_pExchExt->m_gpgSign)
         rc = m->encrypt (hWnd, m_want_html);
       if (!m_pExchExt->m_gpgEncrypt && m_pExchExt->m_gpgSign)
-        rc = m->sign (hWnd);
+        rc = m->sign (hWnd, m_want_html);
       else
         rc = 0;
       delete m;
@@ -955,15 +967,18 @@ CGPGExchExtMessageEvents::OnWriteComplete (LPEXCHEXTCALLBACK pEECB,
          moved that into an attachment and kept PR_BODY.  It seems
          that OL always creates text and HTML if HTML has been
          selected. */
-      if (m_pExchExt->m_gpgEncrypt)
-        {
-          log_debug ("%s:%s: deleting possible extra property PR_BODY_HTML\n",
-                     SRCNAME, __func__);
-          proparray.cValues = 1;
-          proparray.aulPropTag[0] = PR_BODY_HTML;
-          msg->DeleteProps (&proparray, NULL);
-        }
-      
+      /* ARGHH: This seems to delete also the PR_BODY for some reasonh
+         - need to disable this safe net. */
+//       if (m_pExchExt->m_gpgEncrypt)
+//         {
+//           log_debug ("%s:%s: deleting possible extra property PR_BODY_HTML\n",
+//                      SRCNAME, __func__);
+//           proparray.cValues = 1;
+//           proparray.aulPropTag[0] = PR_BODY_HTML;
+//           msg->DeleteProps (&proparray, NULL);
+//         }
+     
       if (rc)
         {
           hrReturn = E_FAIL;
@@ -974,9 +989,8 @@ CGPGExchExtMessageEvents::OnWriteComplete (LPEXCHEXTCALLBACK pEECB,
              now. */
           if (m_pExchExt->m_gpgEncrypt)
             {
-              log_debug ("%s:%s: deleting property %s due to error\n",
-                         SRCNAME, __func__,
-                         m_want_html?"PR_BODY":"PR_BODY_HTML");
+              log_debug ("%s:%s: deleting property PR_BODY due to error\n",
+                         SRCNAME, __func__);
               proparray.cValues = 1;
               proparray.aulPropTag[0] = PR_BODY;
               hr = msg->DeleteProps (&proparray, NULL);
@@ -1204,7 +1218,7 @@ CGPGExchExtCommands::InstallCommands (
                   key = wchar_to_utf8 (aVariant.bstrVal);
                   log_debug ("%s:%s: ConversationIndex is `%s'",
                            SRCNAME, __func__, key);
-                  /* The keyis a hex string.  Convert it to binary. */
+                  /* The key is a hex string.  Convert it to binary. */
                   for (keylen=0,p=key; hexdigitp(p) && hexdigitp(p+1); p += 2)
                     ((unsigned char*)key)[keylen++] = xtoi_2 (p);
                   
index c14ba82..3f806a9 100644 (file)
@@ -42,7 +42,11 @@ struct recipient_cb_s
                            unknown recipients. */
 
   char **fnd_keys;      /* A string array with the user IDs of already
-                           found keys. */
+                           found keys.  I am not sure why they are
+                           needed here at all - they won't get
+                           displayed for unknown reasons. */
+  gpgme_key_t *fnd_keys_key; /* Same as above but the actual gpgme object. */
+  
 
   /* A bit vector used to return selected options. */
   unsigned int opts;
@@ -352,7 +356,7 @@ recipient_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
   HWND hrset;
   const char *warn;
   size_t pos;
-  int i;
+  int i, j;
 
   switch (msg) 
     {
@@ -416,9 +420,13 @@ recipient_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
               return FALSE;
            }
 
+          for (j=0; rset_cb->fnd_keys_key && rset_cb->fnd_keys_key[j]; j++)
+            ;
           rset_cb->selected_keys_count = ListView_GetItemCount (hrset);
-          rset_cb->selected_keys = xcalloc (rset_cb->selected_keys_count + 1,
+          rset_cb->selected_keys = xcalloc (rset_cb->selected_keys_count
+                                            + j + 1,
                                             sizeof *rset_cb->selected_keys);
+          /* Add the selected keys. */
           for (i=0, pos=0; i < rset_cb->selected_keys_count; i++) 
             {
               gpgme_key_t key;
@@ -443,7 +451,10 @@ recipient_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
                       /* Force encryption if one key is not fully
                          trusted.  Actually this is a bit silly but
                          supposedly here to allow adding an option to
-                         disable this "feature".  */
+                         disable this "feature". It is however pretty
+                         much messed up: The default key should never
+                         be processed here but set into the gpg.conf
+                         file becuase it is always trusted.  */
                       rset_cb->opts |= OPT_FLAG_FORCE;
                       break;
                     }
@@ -451,6 +462,13 @@ recipient_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
               else
                 log_debug ("List item not correctly initialized - ignored\n");
             }
+          /* Add the already found keys. */
+          for (i=0; rset_cb->fnd_keys_key && rset_cb->fnd_keys_key[i]; i++)
+            {
+              gpgme_key_ref (rset_cb->fnd_keys_key[i]);
+              rset_cb->selected_keys[pos++] = rset_cb->fnd_keys_key[i];
+            }
+
           rset_cb->selected_keys_count = pos;
           EndDialog (dlg, TRUE);
           break;
@@ -537,6 +555,7 @@ recipient_dialog_box2 (gpgme_key_t *fnd, char **unknown,
        cb.fnd_keys[i] = xstrdup (_("User-ID not found"));
     }
 
+  cb.fnd_keys_key = fnd;
   cb.unknown_keys = unknown;
 
   if (!strncmp (gettext_localename (), "de", 2))