Mercurial > ~mikael > mcabber > hg
comparison mcabber/mcabber/pgp.c @ 2196:8811fe9d6ef0
Improve support for GnuPG v2+
If the gnupg engine detected is not 1.x, do not check the environment
variable GPG_AGENT_INFO and do not set up a password callback.
author | Mikael Berthe <mikael@lilotux.net> |
---|---|
date | Wed, 07 Oct 2015 21:58:38 +0200 |
parents | 40ddaebeb81e |
children | fec172dbacc7 |
comparison
equal
deleted
inserted
replaced
2195:40ddaebeb81e | 2196:8811fe9d6ef0 |
---|---|
36 | 36 |
37 #define MIN_GPGME_VERSION "1.0.0" | 37 #define MIN_GPGME_VERSION "1.0.0" |
38 | 38 |
39 static struct gpg_struct | 39 static struct gpg_struct |
40 { | 40 { |
41 int enabled; | 41 int enabled; |
42 int version1; | |
42 char *private_key; | 43 char *private_key; |
43 char *passphrase; | 44 char *passphrase; |
44 } gpg; | 45 } gpg; |
45 | 46 |
46 | 47 |
51 // if not it returns the gpgme error code. | 52 // if not it returns the gpgme error code. |
52 int gpg_init(const char *priv_key, const char *passphrase) | 53 int gpg_init(const char *priv_key, const char *passphrase) |
53 { | 54 { |
54 gpgme_error_t err; | 55 gpgme_error_t err; |
55 | 56 |
57 gpgme_ctx_t ctx; | |
58 gpgme_engine_info_t info; | |
59 | |
56 // Check for version and OpenPGP protocol support. | 60 // Check for version and OpenPGP protocol support. |
57 if (!gpgme_check_version(MIN_GPGME_VERSION)) { | 61 if (!gpgme_check_version(MIN_GPGME_VERSION)) { |
58 scr_LogPrint(LPRINT_LOGNORM, | 62 scr_LogPrint(LPRINT_LOGNORM, |
59 "GPGME initialization error: Bad library version"); | 63 "GPGME initialization error: Bad library version"); |
60 return -1; | 64 return -1; |
73 | 77 |
74 // Store private data. | 78 // Store private data. |
75 gpg_set_private_key(priv_key); | 79 gpg_set_private_key(priv_key); |
76 gpg_set_passphrase(passphrase); | 80 gpg_set_passphrase(passphrase); |
77 | 81 |
82 err = gpgme_new(&ctx); | |
83 if (err) return -1; | |
84 | |
85 // Check OpenPGP engine version; with version 2+ the agent is mandatory | |
86 // and we do not manage the passphrase. | |
87 gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP); | |
88 if (err) return -1; | |
89 | |
90 err = gpgme_get_engine_info (&info); | |
91 if (!err) { | |
92 while (info && info->protocol != gpgme_get_protocol (ctx)) | |
93 info = info->next; | |
94 | |
95 if (info && info->version) { | |
96 if (!strncmp(info->version, "1.", 2)) | |
97 gpg.version1 = TRUE; | |
98 scr_log_print(LPRINT_DEBUG, "GPGME: Engine version is '%s'.", | |
99 info->version); | |
100 } | |
101 } | |
102 | |
78 gpg.enabled = 1; | 103 gpg.enabled = 1; |
79 return 0; | 104 return 0; |
105 } | |
106 | |
107 // gpg_is_version1() | |
108 // Return TRUE if the GnuPG OpenPGP engine version is 1.x | |
109 int gpg_is_version1(void) | |
110 { | |
111 return gpg.version1; | |
80 } | 112 } |
81 | 113 |
82 // gpg_terminate() | 114 // gpg_terminate() |
83 // Destroy data and free memory. | 115 // Destroy data and free memory. |
84 void gpg_terminate(void) | 116 void gpg_terminate(void) |
262 // The returned string must be freed with g_free() after use. | 294 // The returned string must be freed with g_free() after use. |
263 char *gpg_sign(const char *gpg_data) | 295 char *gpg_sign(const char *gpg_data) |
264 { | 296 { |
265 gpgme_ctx_t ctx; | 297 gpgme_ctx_t ctx; |
266 gpgme_data_t in, out; | 298 gpgme_data_t in, out; |
267 char *p; | |
268 char *signed_data = NULL; | 299 char *signed_data = NULL; |
269 size_t nread; | 300 size_t nread; |
270 gpgme_key_t key; | 301 gpgme_key_t key; |
271 gpgme_error_t err; | 302 gpgme_error_t err; |
272 | 303 |
282 | 313 |
283 gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP); | 314 gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP); |
284 gpgme_set_textmode(ctx, 0); | 315 gpgme_set_textmode(ctx, 0); |
285 gpgme_set_armor(ctx, 1); | 316 gpgme_set_armor(ctx, 1); |
286 | 317 |
287 p = getenv("GPG_AGENT_INFO"); | 318 if (gpg.version1) { |
288 if (!(p && strchr(p, ':'))) | 319 // GPG_AGENT_INFO isn't used by GnuPG version 2+ |
289 gpgme_set_passphrase_cb(ctx, passphrase_cb, 0); | 320 char *p = getenv("GPG_AGENT_INFO"); |
321 if (!(p && strchr(p, ':'))) | |
322 gpgme_set_passphrase_cb(ctx, passphrase_cb, 0); | |
323 } | |
290 | 324 |
291 err = gpgme_get_key(ctx, gpg.private_key, &key, 1); | 325 err = gpgme_get_key(ctx, gpg.private_key, &key, 1); |
292 if (err || !key) { | 326 if (err || !key) { |
293 scr_LogPrint(LPRINT_LOGNORM, "GPGME error: private key not found"); | 327 scr_LogPrint(LPRINT_LOGNORM, "GPGME error: private key not found"); |
294 gpgme_release(ctx); | 328 gpgme_release(ctx); |
330 // The returned string must be freed with g_free() after use. | 364 // The returned string must be freed with g_free() after use. |
331 char *gpg_decrypt(const char *gpg_data) | 365 char *gpg_decrypt(const char *gpg_data) |
332 { | 366 { |
333 gpgme_ctx_t ctx; | 367 gpgme_ctx_t ctx; |
334 gpgme_data_t in, out; | 368 gpgme_data_t in, out; |
335 char *p, *data; | 369 char *data; |
336 char *decrypted_data = NULL; | 370 char *decrypted_data = NULL; |
337 size_t nread; | 371 size_t nread; |
338 gpgme_error_t err; | 372 gpgme_error_t err; |
339 const char prefix[] = "-----BEGIN PGP MESSAGE-----\n\n"; | 373 const char prefix[] = "-----BEGIN PGP MESSAGE-----\n\n"; |
340 const char suffix[] = "\n-----END PGP MESSAGE-----\n"; | 374 const char suffix[] = "\n-----END PGP MESSAGE-----\n"; |
349 return NULL; | 383 return NULL; |
350 } | 384 } |
351 | 385 |
352 gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP); | 386 gpgme_set_protocol(ctx, GPGME_PROTOCOL_OpenPGP); |
353 | 387 |
354 p = getenv("GPG_AGENT_INFO"); | 388 if (gpg.version1) { |
355 if (!(p && strchr(p, ':'))) | 389 // GPG_AGENT_INFO isn't used by GnuPG version 2+ |
356 gpgme_set_passphrase_cb(ctx, passphrase_cb, 0); | 390 char *p = getenv("GPG_AGENT_INFO"); |
391 if (!(p && strchr(p, ':'))) | |
392 gpgme_set_passphrase_cb(ctx, passphrase_cb, 0); | |
393 } | |
357 | 394 |
358 // Surround the given data with the prefix & suffix | 395 // Surround the given data with the prefix & suffix |
359 data = g_new(char, sizeof(prefix) + sizeof(suffix) + strlen(gpg_data)); | 396 data = g_new(char, sizeof(prefix) + sizeof(suffix) + strlen(gpg_data)); |
360 strcpy(data, prefix); | 397 strcpy(data, prefix); |
361 strcat(data, gpg_data); | 398 strcat(data, gpg_data); |