static gboolean start_handshake_cb(gpointer data) { PurpleSslConnection *gsc = data; PurpleSslGnutlsData *gnutls_data = PURPLE_SSL_GNUTLS_DATA(gsc); purple_debug_info("gnutls", "Starting handshake with %s\n", gsc->host); gnutls_data->handshake_timer = 0; ssl_gnutls_handshake_cb(gsc, gsc->fd, PURPLE_INPUT_READ); return FALSE; }
static void ssl_gnutls_connect(PurpleSslConnection *gsc) { PurpleSslGnutlsData *gnutls_data; static const int cert_type_priority[2] = { GNUTLS_CRT_X509, 0 }; gnutls_data = g_new0(PurpleSslGnutlsData, 1); gsc->private_data = gnutls_data; gnutls_init(&gnutls_data->session, GNUTLS_CLIENT); #ifdef HAVE_GNUTLS_PRIORITY_FUNCS if (gnutls_priority_set_direct(gnutls_data->session, "NORMAL:%SSL3_RECORD_VERSION", NULL)) gnutls_priority_set_direct(gnutls_data->session, "NORMAL", NULL); #else gnutls_set_default_priority(gnutls_data->session); #endif gnutls_certificate_type_set_priority(gnutls_data->session, cert_type_priority); gnutls_credentials_set(gnutls_data->session, GNUTLS_CRD_CERTIFICATE, xcred); gnutls_transport_set_ptr(gnutls_data->session, GINT_TO_POINTER(gsc->fd)); gnutls_data->handshake_handler = purple_input_add(gsc->fd, PURPLE_INPUT_READ, ssl_gnutls_handshake_cb, gsc); purple_debug_info("gnutls", "Starting handshake with %s\n", gsc->host); /* Orborde asks: Why are we configuring a callback, then immediately calling it? Answer: gnutls_handshake (up in handshake_cb) needs to be called once in order to get the ball rolling on the SSL connection. Once it has done so, only then will the server reply, triggering the callback. Since the logic driving gnutls_handshake is the same with the first and subsequent calls, we'll just fire the callback immediately to accomplish this. */ ssl_gnutls_handshake_cb(gsc, gsc->fd, PURPLE_INPUT_READ); }