Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 78540
Collapse All | Expand All

(-)licq-1.2.7/configure.in (+3 lines)
Lines 145-150 Link Here
145
AC_CHECK_SOCKS5
145
AC_CHECK_SOCKS5
146
LICQ_CHECK_OPENSSL
146
LICQ_CHECK_OPENSSL
147
147
148
dnl Check for gpgme
149
AC_CHECK_LIB(gpgme,gpgme_check_version)
150
148
dnl Switch to C++ mode and check for needed C++ headers
151
dnl Switch to C++ mode and check for needed C++ headers
149
AC_LANG_SAVE
152
AC_LANG_SAVE
150
AC_LANG_CPLUSPLUS
153
AC_LANG_CPLUSPLUS
(-)licq-1.2.7/include/licq_gpg.h (+42 lines)
Line 0 Link Here
1
2
#ifndef _LICQ_GPG_H_INCLUDED_
3
#define _LICQ_GPG_H_INCLUDED_
4
5
#include <gpgme.h>
6
#include <pthread.h>
7
8
class CGPGHelper
9
{
10
public:
11
	static const char pgpSig[];
12
	CGPGHelper();
13
	~CGPGHelper();
14
	char *Decrypt(const char *);
15
	char *Encrypt(const char *, unsigned long);
16
	void Start();
17
18
protected:
19
	CIniFile mKeysIni;
20
	GpgmeCtx mCtx;
21
	char *mGPGPassphrase;
22
	
23
	void gpgmeLock();
24
	void gpgmeUnlock();
25
	static const char *PassphraseCallback(void *, const char *, void **);
26
};
27
28
class CGPGMEMutex
29
{
30
public:
31
	~CGPGMEMutex();
32
	CGPGMEMutex();
33
	bool Lock();
34
35
protected:
36
	static pthread_mutex_t mutex;
37
};
38
39
40
extern CGPGHelper gGPGHelper;
41
42
#endif //_LICQ_GPG_H_INCLUDED_
(-)licq-1.2.7/src/gpg.cpp (+154 lines)
Line 0 Link Here
1
2
#ifdef HAVE_CONFIG_H
3
#include "config.h"
4
#endif
5
6
#include <stdio.h>
7
#include <string.h>
8
9
#include "licq_file.h"
10
#include "licq_gpg.h"
11
#include "licq_log.h"
12
13
CGPGHelper gGPGHelper;
14
15
const char CGPGHelper::pgpSig[] = "-----BEGIN PGP MESSAGE-----";
16
17
18
CGPGHelper::CGPGHelper()
19
	: mKeysIni(INI_FxALLOWxCREATE)
20
{
21
	mCtx = 0;
22
	mGPGPassphrase = 0;
23
}
24
25
26
CGPGHelper::~CGPGHelper()
27
{
28
	if (mCtx) gpgme_release(mCtx);
29
	if (mGPGPassphrase) free(mGPGPassphrase);
30
	mKeysIni.CloseFile();
31
}
32
33
34
char *CGPGHelper::Decrypt(const char *szCipher)
35
{
36
	if (!mCtx) return 0;
37
38
	size_t nRead = 0;
39
	GpgmeData cipher, plain;
40
41
	CGPGMEMutex mutex;
42
	if (!mutex.Lock()) return 0;
43
	if (gpgme_data_new(&cipher) != GPGME_No_Error) return 0;
44
	char *buf = strdup(szCipher);
45
	GpgmeError err;
46
	gpgme_data_write(cipher, buf, strlen(buf));
47
	free(buf);
48
	if (gpgme_data_new(&plain) != GPGME_No_Error) {
49
		gpgme_data_release(cipher);
50
		return 0;
51
	}
52
	if ((err = gpgme_op_decrypt(mCtx, cipher, plain)) != GPGME_No_Error)
53
		gLog.Warn("%sgpgme message decryption failed: %s\n", L_WARNxSTR, gpgme_strerror(err));
54
	gpgme_data_release(cipher);
55
	buf = gpgme_data_release_and_get_mem(plain, &nRead);
56
	if (!buf) return 0;
57
	buf = (char *)realloc(buf, nRead+1);
58
	buf[nRead] = 0;
59
	return buf;
60
}
61
62
63
char *CGPGHelper::Encrypt(const char *szPlain, unsigned long uin)
64
{
65
	if (!mCtx) return 0;
66
	if (!szPlain) return 0;
67
68
	gLog.Info("gpgme: Encrypting message to %lu\n", uin);
69
70
	char szUIN[20], buf[MAX_LINE_LEN];
71
	mKeysIni.SetSection("keys");
72
	snprintf(szUIN, 20, "%lu", uin);
73
	if (!mKeysIni.ReadStr(szUIN, buf)) return 0;
74
	
75
	CGPGMEMutex mutex;
76
	if (!mutex.Lock()) return 0;
77
	GpgmeRecipients rcps;
78
	GpgmeData plain = 0, cipher = 0;
79
	GpgmeError err;
80
	char *szCipher = 0;
81
82
	if (gpgme_recipients_new(&rcps) != GPGME_No_Error) return 0;
83
	if (gpgme_recipients_add_name_with_validity(rcps, buf, GPGME_VALIDITY_FULL) != GPGME_No_Error)
84
		gLog.Error("%sCouldn't use gpgme recipient: %s\n", L_ERRORxSTR, buf);
85
	else {
86
		if (gpgme_data_new_from_mem(&plain, szPlain, strlen(szPlain), 1) == GPGME_No_Error &&
87
			gpgme_data_new(&cipher) == GPGME_No_Error)
88
		{
89
			if ((err = gpgme_op_encrypt(mCtx, rcps, plain, cipher)) == GPGME_No_Error) {
90
				size_t nRead;
91
				if (gpgme_data_read(cipher, 0, 0, &nRead) == GPGME_No_Error) {
92
					szCipher = (char *)malloc(nRead+1);
93
					memset(szCipher, 0, nRead+1);
94
					gpgme_data_read(cipher, szCipher, nRead, &nRead);
95
				}
96
			} else
97
				gLog.Error("%sEncryption failed: %s\n", L_ERRORxSTR, gpgme_strerror(err));
98
		}
99
		if (cipher) gpgme_data_release(cipher);
100
		if (plain) gpgme_data_release(plain);
101
	}
102
	gpgme_recipients_release(rcps);
103
	return szCipher;
104
}
105
106
107
void CGPGHelper::Start()
108
{
109
	char buf[MAX_LINE_LEN];
110
	snprintf(buf, MAX_LINE_LEN, "%s/licq_gpg.conf", BASE_DIR);
111
	mKeysIni.LoadFile(buf);
112
113
	mKeysIni.SetSection("gpg");
114
	mKeysIni.ReadStr("passphrase", buf); mGPGPassphrase = strdup(buf);
115
116
	const char *gpgme_ver = gpgme_check_version(0);
117
	gLog.Info("%sgpgme library found: %s\n", L_INITxSTR, gpgme_ver);
118
	
119
	if (gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP) != GPGME_No_Error)
120
		gLog.Error("%sgpgme engine OpenPGP not found!\n", L_ERRORxSTR);
121
122
	gpgme_new(&mCtx);
123
	gpgme_set_protocol(mCtx, GPGME_PROTOCOL_OpenPGP);
124
	gpgme_set_armor(mCtx, 1);
125
	gpgme_set_passphrase_cb(mCtx, PassphraseCallback, 0);
126
}
127
128
129
const char *CGPGHelper::PassphraseCallback(void *, const char *, void **)
130
{
131
	return gGPGHelper.mGPGPassphrase;
132
}
133
134
135
136
/*** GPGME lock for thread safety ***/
137
138
pthread_mutex_t CGPGMEMutex::mutex;
139
140
CGPGMEMutex::~CGPGMEMutex()
141
{
142
	pthread_mutex_unlock(&mutex);
143
}
144
145
CGPGMEMutex::CGPGMEMutex()
146
{
147
	pthread_mutex_init(&mutex, 0);
148
}
149
150
bool CGPGMEMutex::Lock()
151
{
152
	return pthread_mutex_lock(&mutex) == 0;
153
}
154
(-)licq-1.2.7/src/icqd.cpp (+4 lines)
Lines 35-40 Link Here
35
#include "licq_translate.h"
35
#include "licq_translate.h"
36
#include "licq_packets.h"
36
#include "licq_packets.h"
37
#include "licq_plugind.h"
37
#include "licq_plugind.h"
38
#include "licq_gpg.h"    // ##
38
#include "licq.h"
39
#include "licq.h"
39
#include "support.h"
40
#include "support.h"
40
41
Lines 252-257 Link Here
252
  // Initialize the random number generator
253
  // Initialize the random number generator
253
  srand(time(NULL));
254
  srand(time(NULL));
254
255
256
  // start GPG helper
257
  gGPGHelper.Start();
258
255
  // Start up our threads
259
  // Start up our threads
256
  pthread_mutex_init(&mutex_runningevents, NULL);
260
  pthread_mutex_init(&mutex_runningevents, NULL);
257
  pthread_mutex_init(&mutex_extendedevents, NULL);
261
  pthread_mutex_init(&mutex_extendedevents, NULL);
(-)licq-1.2.7/src/icqd-tcp.cpp (-1 / +8 lines)
Lines 27-32 Link Here
27
#include "licq_log.h"
27
#include "licq_log.h"
28
#include "licq_chat.h"
28
#include "licq_chat.h"
29
#include "licq_filetransfer.h"
29
#include "licq_filetransfer.h"
30
#include "licq_gpg.h"
30
#include "support.h"
31
#include "support.h"
31
32
32
//-----ICQ::sendMessage--------------------------------------------------------
33
//-----ICQ::sendMessage--------------------------------------------------------
Lines 86-101 Link Here
86
  }
87
  }
87
  else        // send direct
88
  else        // send direct
88
  {
89
  {
90
	 /* get GPG key */
91
	 char *cipher = gGPGHelper.Encrypt(mDos, _nUin);
92
    if (cipher) f |= E_ENCRYPTED;
93
89
    u = gUserManager.FetchUser(_nUin, LOCK_W);
94
    u = gUserManager.FetchUser(_nUin, LOCK_W);
90
    if (u == NULL) return 0;
95
    if (u == NULL) return 0;
91
    if (u->Secure()) f |= E_ENCRYPTED;
96
    if (u->Secure()) f |= E_ENCRYPTED;
92
    e = new CEventMsg(m, ICQ_CMDxTCP_START, TIME_NOW, f);
97
    e = new CEventMsg(m, ICQ_CMDxTCP_START, TIME_NOW, f);
93
    if (pColor != NULL) e->SetColor(pColor);
98
    if (pColor != NULL) e->SetColor(pColor);
94
    CPT_Message *p = new CPT_Message(mDos, nLevel, bMultipleRecipients, pColor, u);
99
    CPT_Message *p = new CPT_Message(cipher?cipher:mDos, nLevel, bMultipleRecipients, pColor, u);
95
    gLog.Info("%sSending %smessage to %s (#%ld).\n", L_TCPxSTR,
100
    gLog.Info("%sSending %smessage to %s (#%ld).\n", L_TCPxSTR,
96
       nLevel == ICQ_TCPxMSG_URGENT ? "urgent " : "",
101
       nLevel == ICQ_TCPxMSG_URGENT ? "urgent " : "",
97
       u->GetAlias(), -p->Sequence());
102
       u->GetAlias(), -p->Sequence());
98
    result = SendExpectEvent_Client(u, p, e);
103
    result = SendExpectEvent_Client(u, p, e);
104
105
    if (cipher) free(cipher);
99
  }
106
  }
100
107
101
  if (u != NULL)
108
  if (u != NULL)
(-)licq-1.2.7/src/Makefile.am (-1 / +1 lines)
Lines 15-21 Link Here
15
	 file.cpp message.cpp support.c pthread_rdwr.c \
15
	 file.cpp message.cpp support.c pthread_rdwr.c \
16
	 onevent.cpp plugind.cpp sar.cpp languagecodes.c \
16
	 onevent.cpp plugind.cpp sar.cpp languagecodes.c \
17
         icqd-chat.cpp sighandler.c icqd-filetransfer.cpp \
17
         icqd-chat.cpp sighandler.c icqd-filetransfer.cpp \
18
         hebrev.c icqcolor.cpp fifo.cpp 
18
         hebrev.c icqcolor.cpp fifo.cpp gpg.cpp
19
19
20
#licq_LDADD = $(top_builddir)/src/daemon/liblicq-daemon.la @SOCKS_LIBS@ 
20
#licq_LDADD = $(top_builddir)/src/daemon/liblicq-daemon.la @SOCKS_LIBS@ 
21
licq_LDADD = @SOCKS_LIBS@ 
21
licq_LDADD = @SOCKS_LIBS@ 
(-)licq-1.2.7/src/message.cpp (+8 lines)
Lines 18-23 Link Here
18
#include "licq_user.h"
18
#include "licq_user.h"
19
#include "licq_translate.h"
19
#include "licq_translate.h"
20
#include "licq_icqd.h"
20
#include "licq_icqd.h"
21
#include "licq_gpg.h"
21
#include "support.h"
22
#include "support.h"
22
23
23
#ifdef USE_HEBREW
24
#ifdef USE_HEBREW
Lines 153-158 Link Here
153
   : CUserEvent(ICQ_CMDxSUB_MSG, _nCommand, 0, _tTime, _nFlags)
154
   : CUserEvent(ICQ_CMDxSUB_MSG, _nCommand, 0, _tTime, _nFlags)
154
{
155
{
155
  m_szMessage = strdup(_szMessage == NULL ? "" : _szMessage);
156
  m_szMessage = strdup(_szMessage == NULL ? "" : _szMessage);
157
  
158
  if (strstr(m_szMessage, CGPGHelper::pgpSig) == m_szMessage)
159
    if (char *plaintext = gGPGHelper.Decrypt(m_szMessage)) {
160
      m_nFlags |= E_ENCRYPTED;
161
	  free(m_szMessage);
162
	  m_szMessage = plaintext;
163
	}
156
}
164
}
157
165
158
166

Return to bug 78540