* @file sslconn.c SSL API * Purple is the legal property of its developers, whose names are too numerous * to list here. Please refer to the COPYRIGHT file distributed with this * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA #define _PURPLE_SSLCONN_C_ static gboolean _ssl_initialized = FALSE; static PurpleSslOps *_ssl_ops = NULL; plugin = purple_plugins_find_with_id("core-ssl"); if (plugin != NULL && !purple_plugin_is_loaded(plugin)) purple_plugin_load(plugin); ops = purple_ssl_get_ops(); if ((ops == NULL) || (ops->init == NULL) || (ops->uninit == NULL) || (ops->connectfunc == NULL) || (ops->close == NULL) || (ops->read == NULL) || (ops->write == NULL)) return (_ssl_initialized = ops->init()); purple_ssl_is_supported(void) return (purple_ssl_get_ops() != NULL); purple_ssl_connect_cb(gpointer data, gint source, const gchar *error_message) PurpleSslConnection *gsc; gsc->connect_data = NULL; if (gsc->error_cb != NULL) gsc->error_cb(gsc, PURPLE_SSL_CONNECT_FAILED, gsc->connect_cb_data); ops = purple_ssl_get_ops(); purple_ssl_connect(PurpleAccount *account, const char *host, int port, PurpleSslInputFunction func, PurpleSslErrorFunction error_func, return purple_ssl_connect_with_ssl_cn(account, host, port, func, error_func, purple_ssl_connect_with_ssl_cn(PurpleAccount *account, const char *host, int port, PurpleSslInputFunction func, PurpleSslErrorFunction error_func, const char *ssl_cn, void *data) PurpleSslConnection *gsc; g_return_val_if_fail(host != NULL, NULL); g_return_val_if_fail(port != 0 && port != -1, NULL); g_return_val_if_fail(func != NULL, NULL); g_return_val_if_fail(purple_ssl_is_supported(), NULL); gsc = g_new0(PurpleSslConnection, 1); gsc->host = ssl_cn ? g_strdup(ssl_cn) : g_strdup(host); gsc->connect_cb_data = data; gsc->error_cb = error_func; /* TODO: Move this elsewhere */ gsc->verifier = purple_certificate_find_verifier("x509","tls_cached"); gsc->connect_data = purple_proxy_connect(NULL, account, host, port, purple_ssl_connect_cb, gsc); if (gsc->connect_data == NULL) return (PurpleSslConnection *)gsc; recv_cb(gpointer data, gint source, PurpleInputCondition cond) PurpleSslConnection *gsc = data; gsc->recv_cb(gsc->recv_cb_data, gsc, cond); purple_ssl_input_add(PurpleSslConnection *gsc, PurpleSslInputFunction func, g_return_if_fail(func != NULL); g_return_if_fail(purple_ssl_is_supported()); gsc->recv_cb_data = data; gsc->inpa = purple_input_add(gsc->fd, PURPLE_INPUT_READ, recv_cb, gsc); purple_ssl_strerror(PurpleSslErrorType error) case PURPLE_SSL_CONNECT_FAILED: return _("SSL Connection Failed"); case PURPLE_SSL_HANDSHAKE_FAILED: return _("SSL Handshake Failed"); case PURPLE_SSL_CERTIFICATE_INVALID: return _("SSL peer presented an invalid certificate"); purple_debug_warning("sslconn", "Unknown SSL error code %d\n", error); return _("Unknown SSL error"); purple_ssl_connect_fd(PurpleAccount *account, int fd, PurpleSslInputFunction func, PurpleSslErrorFunction error_func, return purple_ssl_connect_with_host_fd(account, fd, func, error_func, NULL, data); purple_ssl_connect_with_host_fd(PurpleAccount *account, int fd, PurpleSslInputFunction func, PurpleSslErrorFunction error_func, PurpleSslConnection *gsc; g_return_val_if_fail(fd != -1, NULL); g_return_val_if_fail(func != NULL, NULL); g_return_val_if_fail(purple_ssl_is_supported(), NULL); gsc = g_new0(PurpleSslConnection, 1); gsc->connect_cb_data = data; gsc->error_cb = error_func; gsc->host = g_strdup(host); /* TODO: Move this elsewhere */ gsc->verifier = purple_certificate_find_verifier("x509","tls_cached"); ops = purple_ssl_get_ops(); return (PurpleSslConnection *)gsc; purple_ssl_close(PurpleSslConnection *gsc) g_return_if_fail(gsc != NULL); purple_request_close_with_handle(gsc); purple_notify_close_with_handle(gsc); ops = purple_ssl_get_ops(); if (gsc->connect_data != NULL) purple_proxy_connect_cancel(gsc->connect_data); purple_input_remove(gsc->inpa); purple_ssl_read(PurpleSslConnection *gsc, void *data, size_t len) g_return_val_if_fail(gsc != NULL, 0); g_return_val_if_fail(data != NULL, 0); g_return_val_if_fail(len > 0, 0); ops = purple_ssl_get_ops(); return (ops->read)(gsc, data, len); purple_ssl_write(PurpleSslConnection *gsc, const void *data, size_t len) g_return_val_if_fail(gsc != NULL, 0); g_return_val_if_fail(data != NULL, 0); g_return_val_if_fail(len > 0, 0); ops = purple_ssl_get_ops(); return (ops->write)(gsc, data, len); purple_ssl_get_peer_certificates(PurpleSslConnection *gsc) g_return_val_if_fail(gsc != NULL, NULL); ops = purple_ssl_get_ops(); return (ops->get_peer_certificates)(gsc); purple_ssl_set_ops(PurpleSslOps *ops) /* Although purple_ssl_is_supported will do the initialization on command, SSL plugins tend to register CertificateSchemes as well purple_debug_error("sslconn", "Unable to initialize SSL.\n"); ops = purple_ssl_get_ops(); _ssl_initialized = FALSE;