Hi!

This patch is a port for PGP support with new gpgme API.  This is tested with
gpgme 0.9.0.

It currently supports only specifying key in configuration file by
fingerprint, not by ID.  This is a security consideration because the ID is
not necessarily unique.  If you don't like this, it could be changed in
principle, but I would prefer not to do so.

Note that it will break if you translate licq with different _FILE_OFFSET_BITS
settings than you did with gpg stuff.  That means if you (or your
distribution) did -D_FILE_OFFSET_BITS when building gpg stuff, you have to do
this with licq as well.

For those that use SUSE 9.2 on ia32, I have put a binary (ans source) RPM
including this patch on
http://pi3.informatik.uni-mannheim.de/~schiele/suse/9.2-i586/.

If you find bugs or have comments, feel free to contact me.

Now for the patch:

--- include/licq_gpg.h  2004/11/22 18:58:15     1.1
+++ include/licq_gpg.h  2004/11/22 20:06:26
@@ -20,13 +20,13 @@
 protected:
   CIniFile mKeysIni;
 #ifdef HAVE_LIBGPGME
-  GpgmeCtx mCtx;
+  gpgme_ctx_t mCtx;
 #endif
   char *mGPGPassphrase;
 
   void gpgmeLock();
   void gpgmeUnlock();
-  static const char *PassphraseCallback(void *, const char *, void **);
+  static gpgme_error_t PassphraseCallback(void *, const char *, const char *, 
int, int);
 };
 
 class CGPGMEMutex
--- src/gpg.cpp 2004/11/22 18:57:26     1.1
+++ src/gpg.cpp 2004/11/22 20:15:36
@@ -41,23 +41,24 @@
   if (!mCtx) return 0;
 
   size_t nRead = 0;
-  GpgmeData cipher, plain;
+  gpgme_data_t cipher, plain;
 
   CGPGMEMutex mutex;
   if (!mutex.Lock()) return 0;
-  if (gpgme_data_new(&cipher) != GPGME_No_Error) return 0;
+  if (gpgme_data_new(&cipher) != GPG_ERR_NO_ERROR) return 0;
   char *buf = strdup(szCipher);
-  GpgmeError err;
+  gpgme_error_t err;
   gpgme_data_write(cipher, buf, strlen(buf));
   free(buf);
 
-  if (gpgme_data_new(&plain) != GPGME_No_Error)
+  if (gpgme_data_new(&plain) != GPG_ERR_NO_ERROR)
   {
     gpgme_data_release(cipher);
     return 0;
   }
 
-  if ((err = gpgme_op_decrypt(mCtx, cipher, plain)) != GPGME_No_Error)
+  gpgme_data_seek(cipher, 0, SEEK_SET);
+  if ((err = gpgme_op_decrypt(mCtx, cipher, plain)) != GPG_ERR_NO_ERROR)
     gLog.Warn("%sgpgme message decryption failed: %s\n", L_WARNxSTR, 
gpgme_strerror(err));
   
   gpgme_data_release(cipher);
@@ -88,28 +89,42 @@
 
   CGPGMEMutex mutex;
   if (!mutex.Lock()) return 0;
-  GpgmeRecipients rcps;
-  GpgmeData plain = 0, cipher = 0;
-  GpgmeError err;
+  gpgme_key_t rcps[2];
+  gpgme_data_t plain = 0, cipher = 0;
+  gpgme_error_t err;
   char *szCipher = 0;
 
-  if (gpgme_recipients_new(&rcps) != GPGME_No_Error) return 0;
-  if (gpgme_recipients_add_name_with_validity(rcps, buf, GPGME_VALIDITY_FULL) 
!= GPGME_No_Error)
+  rcps[1] = 0;
+  if (gpgme_get_key(mCtx, buf, rcps, 0) != GPG_ERR_NO_ERROR)
     gLog.Error("%sCouldn't use gpgme recipient: %s\n", L_ERRORxSTR, buf);
   else
   {
-    if (gpgme_data_new_from_mem(&plain, szPlain, strlen(szPlain), 1) == 
GPGME_No_Error &&
-        gpgme_data_new(&cipher) == GPGME_No_Error)
+    if (gpgme_data_new_from_mem(&plain, szPlain, strlen(szPlain), 1) == 
GPG_ERR_NO_ERROR &&
+        gpgme_data_new(&cipher) == GPG_ERR_NO_ERROR)
     {
-      if ((err = gpgme_op_encrypt(mCtx, rcps, plain, cipher)) == 
GPGME_No_Error) 
+      if ((err = gpgme_op_encrypt(mCtx, rcps, GPGME_ENCRYPT_ALWAYS_TRUST, 
plain, cipher)) == GPG_ERR_NO_ERROR) 
       {
-        size_t nRead;
-        if (gpgme_data_read(cipher, 0, 0, &nRead) == GPGME_No_Error)
-        {
-          szCipher = (char *)malloc(nRead+1);
-          memset(szCipher, 0, nRead+1);
-          gpgme_data_read(cipher, szCipher, nRead, &nRead);
+       size_t bufSize = 4096;
+        szCipher = (char *)malloc(bufSize);
+        size_t nReadAll = 0;
+       gpgme_data_seek(cipher, 0, SEEK_SET);
+       while (1)
+       {
+          size_t nRead = gpgme_data_read(cipher, szCipher + nReadAll, bufSize 
- nReadAll);
+         if (nRead > 0)
+          {
+           nReadAll += nRead;
+           if (nReadAll == bufSize)
+           {
+             bufSize *= 2;
+             szCipher = (char *)realloc(szCipher, bufSize);
+           }
+         }
+         else
+            break;
         }
+       szCipher = (char *)realloc(szCipher, nReadAll + 1);
+       szCipher[nReadAll] = 0;
       }
       else
         gLog.Error("%sEncryption failed: %s\n", L_ERRORxSTR, 
gpgme_strerror(err));
@@ -119,7 +134,7 @@
     if (plain) gpgme_data_release(plain);
   }
 
-  gpgme_recipients_release(rcps);
+  gpgme_key_unref(rcps[0]);
   return szCipher;
 #else
   return 0;
@@ -140,7 +155,7 @@
   const char *gpgme_ver = gpgme_check_version(0);
   gLog.Info("%sgpgme library found: %s\n", L_INITxSTR, gpgme_ver);
        
-  if (gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP) != GPGME_No_Error)
+  if (gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP) != GPG_ERR_NO_ERROR)
     gLog.Error("%sgpgme engine OpenPGP not found!\n", L_ERRORxSTR);
 
   gpgme_new(&mCtx);
@@ -151,9 +166,18 @@
 }
 
 
-const char *CGPGHelper::PassphraseCallback(void *, const char *, void **)
+gpgme_error_t CGPGHelper::PassphraseCallback(void *, const char *, const char 
*, int, int fd)
 {
-  return gGPGHelper.mGPGPassphrase;
+  const char nl = '\n';
+  const char* const pf = gGPGHelper.mGPGPassphrase;
+  if (pf == 0)
+  {
+    write(fd, &nl, 1);
+    return GPG_ERR_CANCELED;
+  }
+  write(fd, pf, strlen(pf));
+  write(fd, &nl, 1);
+  return GPG_ERR_NO_ERROR;
 }
 
 

Robert

-- 
Robert Schiele                  Tel.: +49-621-181-2214
Dipl.-Wirtsch.informatiker      mailto:[EMAIL PROTECTED]

Attachment: pgpq9HzB84atc.pgp
Description: PGP signature

Reply via email to