gee
oldstatus
2005-09-19, Nathan Walp
* @file ssl-gnutls.c GNUTLS SSL plugin. * Copyright (C) 2003 Christian Hammond <chipx86@gnupdate.org> * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define SSL_GNUTLS_PLUGIN_ID "ssl-gnutls" #include <gnutls/gnutls.h> #define GAIM_SSL_GNUTLS_DATA(gsc) ((GaimSslGnutlsData *)gsc->private_data) static gnutls_certificate_client_credentials xcred; ssl_gnutls_init_gnutls(void) gnutls_certificate_allocate_credentials(&xcred); gnutls_certificate_set_x509_trust_file(xcred, "ca.pem", gnutls_certificate_free_credentials(xcred); ssl_gnutls_connect_cb(gpointer data, gint source, GaimInputCondition cond) GaimSslConnection *gsc = (GaimSslConnection *)data; GaimSslGnutlsData *gnutls_data; static const int cert_type_priority[2] = { GNUTLS_CRT_X509, 0 }; if(gsc->error_cb != NULL) gsc->error_cb(gsc, GAIM_SSL_CONNECT_FAILED, gsc->connect_cb_data); gnutls_data = g_new0(GaimSslGnutlsData, 1); gsc->private_data = gnutls_data; gnutls_init(&gnutls_data->session, GNUTLS_CLIENT); gnutls_set_default_priority(gnutls_data->session); gnutls_certificate_type_set_priority(gnutls_data->session, gnutls_credentials_set(gnutls_data->session, GNUTLS_CRD_CERTIFICATE, gnutls_transport_set_ptr(gnutls_data->session, GINT_TO_POINTER(source)); gaim_debug_info("gnutls", "Handshaking\n"); ret = gnutls_handshake(gnutls_data->session); while ((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)); gaim_debug_error("gnutls", "Handshake failed. Error %d\n", ret); if (gsc->error_cb != NULL) gsc->error_cb(gsc, GAIM_SSL_HANDSHAKE_FAILED, gaim_debug_info("gnutls", "Handshake complete\n"); gsc->connect_cb(gsc->connect_cb_data, gsc, cond); ssl_gnutls_close(GaimSslConnection *gsc) GaimSslGnutlsData *gnutls_data = GAIM_SSL_GNUTLS_DATA(gsc); gnutls_bye(gnutls_data->session, GNUTLS_SHUT_RDWR); gnutls_deinit(gnutls_data->session); ssl_gnutls_read(GaimSslConnection *gsc, void *data, size_t len) GaimSslGnutlsData *gnutls_data = GAIM_SSL_GNUTLS_DATA(gsc); s = gnutls_record_recv(gnutls_data->session, data, len); while ((s == GNUTLS_E_AGAIN) || (s == GNUTLS_E_INTERRUPTED)); gaim_debug_error("gnutls", "receive failed: %d\n", s); ssl_gnutls_write(GaimSslConnection *gsc, const void *data, size_t len) GaimSslGnutlsData *gnutls_data = GAIM_SSL_GNUTLS_DATA(gsc); s = gnutls_record_send(gnutls_data->session, data, len); static GaimSslOps ssl_ops = plugin_load(GaimPlugin *plugin) if (!gaim_ssl_get_ops()) { gaim_ssl_set_ops(&ssl_ops); /* Init GNUTLS now so others can use it even if sslconn never does */ ssl_gnutls_init_gnutls(); plugin_unload(GaimPlugin *plugin) if (gaim_ssl_get_ops() == &ssl_ops) { static GaimPluginInfo info = GAIM_PLUGIN_STANDARD, /**< type */ NULL, /**< ui_requirement */ GAIM_PLUGIN_FLAG_INVISIBLE, /**< flags */ NULL, /**< dependencies */ GAIM_PRIORITY_DEFAULT, /**< priority */ SSL_GNUTLS_PLUGIN_ID, /**< id */ N_("GNUTLS"), /**< name */ N_("Provides SSL support through GNUTLS."), N_("Provides SSL support through GNUTLS."), "Christian Hammond <chipx86@gnupdate.org>", GAIM_WEBSITE, /**< homepage */ plugin_load, /**< load */ plugin_unload, /**< unload */ init_plugin(GaimPlugin *plugin) GAIM_INIT_PLUGIN(ssl_gnutls, init_plugin, info)