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