Mercurial > pidgin
comparison libpurple/plugins/ssl/ssl-nss.c @ 29659:df9de37e0274
gnutls/nss: Don't call the handshake functions synchronously. Fixes #11525
If the handshake callbacks are called sychronously and they fail
(e.g. passing GnuTLS a bad priority string or doing voodoo with NSS, see
#11524 for details), the error_cb is called and the gsc destroyed, but this
happens /before/ the assignment to, e.g., js->gsc happens (see
jabber.c:tls_init). Thus, js->gsc is assigned a (now invalid) pointer
and jabber_close tries to free it (again).
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Thu, 01 Apr 2010 05:26:44 +0000 |
parents | c35fd54ec64b |
children | fc4bacb35cbc |
comparison
equal
deleted
inserted
replaced
29658:89de871ecffc | 29659:df9de37e0274 |
---|---|
49 typedef struct | 49 typedef struct |
50 { | 50 { |
51 PRFileDesc *fd; | 51 PRFileDesc *fd; |
52 PRFileDesc *in; | 52 PRFileDesc *in; |
53 guint handshake_handler; | 53 guint handshake_handler; |
54 | 54 guint handshake_timer; |
55 } PurpleSslNssData; | 55 } PurpleSslNssData; |
56 | 56 |
57 #define PURPLE_SSL_NSS_DATA(gsc) ((PurpleSslNssData *)gsc->private_data) | 57 #define PURPLE_SSL_NSS_DATA(gsc) ((PurpleSslNssData *)gsc->private_data) |
58 | 58 |
59 static const PRIOMethods *_nss_methods = NULL; | 59 static const PRIOMethods *_nss_methods = NULL; |
366 callback */ | 366 callback */ |
367 gsc->connect_cb(gsc->connect_cb_data, gsc, cond); | 367 gsc->connect_cb(gsc->connect_cb_data, gsc, cond); |
368 } | 368 } |
369 } | 369 } |
370 | 370 |
371 static gboolean | |
372 start_handshake_cb(gpointer data) | |
373 { | |
374 PurpleSslConnection *gsc = data; | |
375 PurpleSslNssData *nss_data = PURPLE_SSL_NSS_DATA(gsc); | |
376 | |
377 nss_data->handshake_timer = 0; | |
378 | |
379 ssl_nss_handshake_cb(gsc, gsc->fd, PURPLE_INPUT_READ); | |
380 return FALSE; | |
381 } | |
382 | |
371 static void | 383 static void |
372 ssl_nss_connect(PurpleSslConnection *gsc) | 384 ssl_nss_connect(PurpleSslConnection *gsc) |
373 { | 385 { |
374 PurpleSslNssData *nss_data = g_new0(PurpleSslNssData, 1); | 386 PurpleSslNssData *nss_data = g_new0(PurpleSslNssData, 1); |
375 PRSocketOptionData socket_opt; | 387 PRSocketOptionData socket_opt; |
436 SSL_ResetHandshake(nss_data->in, PR_FALSE); | 448 SSL_ResetHandshake(nss_data->in, PR_FALSE); |
437 | 449 |
438 nss_data->handshake_handler = purple_input_add(gsc->fd, | 450 nss_data->handshake_handler = purple_input_add(gsc->fd, |
439 PURPLE_INPUT_READ, ssl_nss_handshake_cb, gsc); | 451 PURPLE_INPUT_READ, ssl_nss_handshake_cb, gsc); |
440 | 452 |
441 ssl_nss_handshake_cb(gsc, gsc->fd, PURPLE_INPUT_READ); | 453 nss_data->handshake_timer = purple_timeout_add(0, start_handshake_cb, gsc); |
442 } | 454 } |
443 | 455 |
444 static void | 456 static void |
445 ssl_nss_close(PurpleSslConnection *gsc) | 457 ssl_nss_close(PurpleSslConnection *gsc) |
446 { | 458 { |
457 gsc->fd = -1; | 469 gsc->fd = -1; |
458 } | 470 } |
459 | 471 |
460 if (nss_data->handshake_handler) | 472 if (nss_data->handshake_handler) |
461 purple_input_remove(nss_data->handshake_handler); | 473 purple_input_remove(nss_data->handshake_handler); |
474 | |
475 if (nss_data->handshake_timer) | |
476 purple_timeout_remove(nss_data->handshake_timer); | |
462 | 477 |
463 g_free(nss_data); | 478 g_free(nss_data); |
464 gsc->private_data = NULL; | 479 gsc->private_data = NULL; |
465 } | 480 } |
466 | 481 |