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]
pgpq9HzB84atc.pgp
Description: PGP signature