changeset 1197:6f602d3270a4

Add /pgp [-]force With this command it becomes possible to enforce PGP encryption without checking if the remote client has PGP support. It can be used to send encrypted offline messages too.
author Mikael Berthe <mikael@lilotux.net>
date Fri, 27 Apr 2007 00:37:57 +0200
parents d657a13fd71a
children 3a2ac3d96eed
files mcabber/doc/help/en/hlp_pgp.txt mcabber/doc/help/fr/hlp_pgp.txt mcabber/src/commands.c mcabber/src/jabglue.c mcabber/src/jabglue.h mcabber/src/settings.c mcabber/src/settings.h
diffstat 7 files changed, 112 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/mcabber/doc/help/en/hlp_pgp.txt	Sun Apr 22 15:01:20 2007 +0200
+++ b/mcabber/doc/help/en/hlp_pgp.txt	Fri Apr 27 00:37:57 2007 +0200
@@ -1,14 +1,16 @@
 
- /PGP disable|enable|info [jid]
+ /PGP disable|enable|force|info [jid]
  /PGP setkey [jid [key]]
 
-This command manipulate PGP settings for the specified jid (by default the currently selected contact).
-Please note that PGP encryption won't be used if no remote PGP support is detected, even if PGP is enabled with this command.
+This command manipulates PGP settings for the specified jid (by default the currently selected contact).
+Please note that PGP encryption won't be used if no remote PGP support is detected, even if PGP is enabled with this command.  You can force PGP encryption with the "force" subcommand.
 
 /pgp disable [jid]
  Disable PGP encryption for jid (or the currently selected contact)
 /pgp enable [jid]
  Enable PGP encryption for jid (or the currently selected contact)
+/pgp [+|-]force [jid]
+ Enforce PGP encryption, even for offline messages, and always assume the recipient has PGP support.  If a message can't be encrypted (missing key or key id), the messages won't be sent at all.  This option is ignored when PGP is disabled.
 /pgp info [jid]
  Show current PGP settings for the contact
 /pgp setkey [jid [key]]
--- a/mcabber/doc/help/fr/hlp_pgp.txt	Sun Apr 22 15:01:20 2007 +0200
+++ b/mcabber/doc/help/fr/hlp_pgp.txt	Fri Apr 27 00:37:57 2007 +0200
@@ -1,14 +1,16 @@
 
- /PGP disable|enable|info [jid]
+ /PGP disable|enable|force|info [jid]
  /PGP setkey [jid [clé]]
 
 Cette commande permet de manipuler les paramètres PGP pour le contact jid (s'il n'est pas précisé, c'est le contact sélectionné).
-Veuillez noter que le chiffrement PGP ne sera pas utilisé si le support de PGP n'est pas détecté chez le client distant (i.e. le contact), même si vous activez PGP avec cette commande.
+Veuillez noter que le chiffrement PGP ne sera pas utilisé si le support de PGP n'est pas détecté chez le client distant (i.e. le contact), même si vous activez PGP avec cette commande. Vous pouvez forcer le chiffrement PGP avec "/pgp force".
 
 /pgp disable [jid]
  Désactive le chiffrement PGP pour jid (ou le contact sélectionné)
 /pgp enable [jid]
  Active le chiffrement PGP pour jid (ou le contact sélectionné)
+/pgp [+|-]force [jid]
+ Force le chiffrement PGP, y compris lorsque le contact est déconnecté, en supposant toujours que le destinataire peut lire les messages chiffrés avec PGP. Lorsqu'un message ne peut pas être chiffré (clé ou keyid manquant), il ne sera pas envoyé. Cette option est ignorée quand PGP est désactivé.
 /pgp info [jid]
  Affiche les paramètres PGP du contact
 /pgp setkey [jid [key]]
--- a/mcabber/src/commands.c	Sun Apr 22 15:01:20 2007 +0200
+++ b/mcabber/src/commands.c	Fri Apr 27 00:37:57 2007 +0200
@@ -247,6 +247,7 @@
   // PGP category
   compl_add_category_word(COMPL_PGP, "disable");
   compl_add_category_word(COMPL_PGP, "enable");
+  compl_add_category_word(COMPL_PGP, "force");
   compl_add_category_word(COMPL_PGP, "info");
   compl_add_category_word(COMPL_PGP, "setkey");
 }
@@ -322,7 +323,7 @@
 static void send_message(const char *msg, const char *subj)
 {
   const char *bjid;
-  guint crypted;
+  gint crypted;
 
   if (!jb_getonline()) {
     scr_LogPrint(LPRINT_NORMAL, "You are not connected.");
@@ -344,6 +345,11 @@
   jb_send_msg(bjid, msg, buddy_gettype(BUDDATA(current_buddy)), subj, NULL,
               &crypted);
 
+  if (crypted == -1) {
+    scr_LogPrint(LPRINT_LOGNORM, "Encryption error.  Message was not sent.");
+    return;
+  }
+
   // Hook
   if (buddy_gettype(BUDDATA(current_buddy)) != ROSTER_TYPE_ROOM) {
     // local part (UI, logging, etc.)
@@ -954,7 +960,8 @@
 {
   char *bare_jid, *rp;
   char *hmsg;
-  guint crypted;
+  gint crypted;
+  gint retval = 0;
 
   if (!fjid || !*fjid) {
     scr_LogPrint(LPRINT_NORMAL, "You must specify a Jabber ID.");
@@ -994,12 +1001,19 @@
   // Network part
   jb_send_msg(fjid, msg, ROSTER_TYPE_USER, subj, NULL, &crypted);
 
+  if (crypted == -1) {
+    scr_LogPrint(LPRINT_LOGNORM, "Encryption error.  Message was not sent.");
+    retval = 1;
+    goto send_message_to_return;
+  }
+
   // Hook
   hk_message_out(bare_jid, rp, 0, hmsg, crypted);
+
+send_message_to_return:
   if (hmsg != msg) g_free(hmsg);
-
   if (rp) g_free(bare_jid);
-  return 0;
+  return retval;
 }
 
 static void do_say(char *arg)
@@ -2640,8 +2654,10 @@
     pgp_enable,
     pgp_disable,
     pgp_setkey,
+    pgp_force,
     pgp_info
   } op = 0;
+  int force = FALSE;
 
   paramlst = split_arg(arg, 3, 0); // subcmd, jid, [key]
   subcmd = *paramlst;
@@ -2660,6 +2676,12 @@
       op = pgp_disable;
     else if (!strcasecmp(subcmd, "setkey"))
       op = pgp_setkey;
+    else if ((!strcasecmp(subcmd, "force")) ||
+             (!strcasecmp(subcmd, "+force"))) {
+      op = pgp_force;
+      force = TRUE;
+    } else if (!strcasecmp(subcmd, "-force"))
+      op = pgp_force;
     else if (!strcasecmp(subcmd, "info"))
       op = pgp_info;
   }
@@ -2702,12 +2724,16 @@
   }
 
   if (fjid) { // fjid is actually a bare jid...
+    guint disabled;
     GString *sbuf;
     switch (op) {
       case pgp_enable:
       case pgp_disable:
           settings_pgp_setdisabled(fjid, (op == pgp_disable ? TRUE : FALSE));
           break;
+      case pgp_force:
+          settings_pgp_setforce(fjid, force);
+          break;
       case pgp_setkey:
           settings_pgp_setkeyid(fjid, keyid);
           break;
@@ -2718,10 +2744,15 @@
                             settings_pgp_getkeyid(fjid));
             scr_WriteIncomingMessage(fjid, sbuf->str, 0, HBB_PREFIX_INFO);
           }
+          disabled = settings_pgp_getdisabled(fjid);
           g_string_printf(sbuf, "PGP encryption is %s",
-                          (settings_pgp_getdisabled(fjid) ?  "disabled" :
-                           "enabled"));
+                          (disabled ?  "disabled" : "enabled"));
           scr_WriteIncomingMessage(fjid, sbuf->str, 0, HBB_PREFIX_INFO);
+          if (!disabled && settings_pgp_getforce(fjid)) {
+            scr_WriteIncomingMessage(fjid,
+                                     "Encryption enforced (no negotiation)",
+                                     0, HBB_PREFIX_INFO);
+          }
           g_string_free(sbuf, TRUE);
           break;
       default:
--- a/mcabber/src/jabglue.c	Sun Apr 22 15:01:20 2007 +0200
+++ b/mcabber/src/jabglue.c	Fri Apr 27 00:37:57 2007 +0200
@@ -510,10 +510,11 @@
 }
 
 //  jb_send_msg(jid, test, type, subject, msgid, *encrypted)
-// When encrypted is not NULL, the function set *encrypted to TRUE if the
-// message has been PGP-encrypted.
+// When encrypted is not NULL, the function set *encrypted to 1 if the
+// message has been PGP-encrypted.  If encryption enforcement is set and
+// encryption fails, *encrypted is set to -1.
 void jb_send_msg(const char *fjid, const char *text, int type,
-                 const char *subject, const char *msgid, guint *encrypted)
+                 const char *subject, const char *msgid, gint *encrypted)
 {
   xmlnode x;
   gchar *strtype;
@@ -532,7 +533,7 @@
   gchar *enc = NULL;
 
   if (encrypted)
-    *encrypted = FALSE;
+    *encrypted = 0;
 
   if (!online) return;
 
@@ -553,19 +554,29 @@
 
 #ifdef HAVE_GPGME
   if (type == ROSTER_TYPE_USER && sl_buddy && gpg_enabled()) {
-    if (!settings_pgp_getdisabled(barejid)) { // disabled for this contact?
+    if (!settings_pgp_getdisabled(barejid)) { // not disabled for this contact?
+      guint force;
       struct pgp_data *res_pgpdata;
+      force = settings_pgp_getforce(barejid);
       res_pgpdata = buddy_resource_pgp(sl_buddy->data, rname);
-      if (res_pgpdata && res_pgpdata->sign_keyid) {
-        /* Remote client has PGP support (we have a signature).
+      if (force || (res_pgpdata && res_pgpdata->sign_keyid)) {
+        /* Remote client has PGP support (we have a signature)
+         * OR encryption is enforced (force = TRUE).
          * If the contact has a specific KeyId, we'll use it;
          * if not, we'll use the key used for the signature.
          * Both keys should match, in theory (cf. XEP-0027). */
         const char *key;
         key = settings_pgp_getkeyid(barejid);
-        if (!key)
+        if (!key && res_pgpdata)
           key = res_pgpdata->sign_keyid;
-        enc = gpg_encrypt(text, key);
+        if (key)
+          enc = gpg_encrypt(text, key);
+        if (!enc && force) {
+          if (encrypted)
+            *encrypted = -1;
+          g_free(barejid);
+          return;
+        }
       }
     }
   }
@@ -587,7 +598,7 @@
     xmlnode_put_attrib(y, "xmlns", NS_ENCRYPTED);
     xmlnode_insert_cdata(y, enc, (unsigned) -1);
     if (encrypted)
-      *encrypted = TRUE;
+      *encrypted = 1;
     g_free(enc);
   }
 
--- a/mcabber/src/jabglue.h	Sun Apr 22 15:01:20 2007 +0200
+++ b/mcabber/src/jabglue.h	Fri Apr 27 00:37:57 2007 +0200
@@ -62,7 +62,7 @@
                   int do_not_sign);
 inline void jb_setprevstatus(void);
 void jb_send_msg(const char *fjid, const char *text, int type,
-                 const char *subject, const char *id, guint *encrypted);
+                 const char *subject, const char *id, gint *encrypted);
 void jb_send_raw(const char *str);
 void jb_send_chatstate(gpointer buddy, guint chatstate);
 void jb_keepalive(void);
--- a/mcabber/src/settings.c	Sun Apr 22 15:01:20 2007 +0200
+++ b/mcabber/src/settings.c	Fri Apr 27 00:37:57 2007 +0200
@@ -38,6 +38,7 @@
 typedef struct {
   gchar *pgp_keyid;   /* KeyId the contact is supposed to use */
   guint pgp_disabled; /* If TRUE, PGP is disabled for outgoing messages */
+  guint pgp_force;    /* If TRUE, PGP is used w/o negotiation */
 } T_pgpopt;
 #endif
 
@@ -403,12 +404,52 @@
   if (pgpdata)
     return pgpdata->pgp_disabled;
   else
-    return FALSE; // default: not disabled
+    return FALSE; // Default: not disabled
 #else
   return TRUE;    // No PGP support, let's say it's disabled.
 #endif
 }
 
+//  settings_pgp_setforce(jid, value)
+// Force (or not) PGP encryption for jid.
+// When value is TRUE, PGP support will be assumed for the remote client.
+void settings_pgp_setforce(const char *bjid, guint value)
+{
+#ifdef HAVE_GPGME
+  T_pgpopt *pgpdata;
+  pgpdata = g_hash_table_lookup(pgpopt, bjid);
+  if (!pgpdata) {
+    // If value is 0, we do not need to create a structure (that's
+    // the default value).
+    if (value) {
+      pgpdata = g_new0(T_pgpopt, 1);
+      pgpdata->pgp_force = value;
+      g_hash_table_insert(pgpopt, g_strdup(bjid), pgpdata);
+    }
+  } else {
+    pgpdata->pgp_force = value;
+  }
+  if (!pgpdata->pgp_keyid)
+    scr_LogPrint(LPRINT_NORMAL, "Warning: the Key Id is not set!");
+#endif
+}
+
+//  settings_pgp_getforce(jid)
+// Return TRUE if PGP enforcement is set for jid.
+guint settings_pgp_getforce(const char *bjid)
+{
+#ifdef HAVE_GPGME
+  T_pgpopt *pgpdata;
+  pgpdata = g_hash_table_lookup(pgpopt, bjid);
+  if (pgpdata)
+    return pgpdata->pgp_force;
+  else
+    return FALSE; // Default
+#else
+  return FALSE;   // No PGP support
+#endif
+}
+
 //  settings_pgp_setkeyid(jid, keyid)
 // Set the PGP KeyId for user jid.
 // Use keyid = NULL to erase the previous KeyId.
--- a/mcabber/src/settings.h	Sun Apr 22 15:01:20 2007 +0200
+++ b/mcabber/src/settings.h	Fri Apr 27 00:37:57 2007 +0200
@@ -37,6 +37,8 @@
 
 void    settings_pgp_setdisabled(const char *bjid, guint value);
 guint   settings_pgp_getdisabled(const char *bjid);
+void    settings_pgp_setforce(const char *bjid, guint value);
+guint   settings_pgp_getforce(const char *bjid);
 void    settings_pgp_setkeyid(const char *bjid, const char *keyid);
 const char *settings_pgp_getkeyid(const char *bjid);