Mercurial > pidgin
annotate plugins/ssl/ssl-gnutls.c @ 11851:3bfb2cffcef2
[gaim-migrate @ 14142]
inspired by Richard Stellingwerff's patch 1339606, this workaround for
annoying visible borders on tab close buttons is no longer required with
at least gtk 2.6 (if someone can confirm if it was fixed in 2.4 we could
remove it there too)
committer: Tailor Script <tailor@pidgin.im>
| author | Stu Tomlinson <stu@nosnilmot.com> |
|---|---|
| date | Thu, 27 Oct 2005 15:15:52 +0000 |
| parents | c18bd02be106 |
| children | 33bef17125c2 |
| rev | line source |
|---|---|
| 7016 | 1 /** |
| 2 * @file ssl-gnutls.c GNUTLS SSL plugin. | |
| 3 * | |
| 4 * gaim | |
| 5 * | |
| 6 * Copyright (C) 2003 Christian Hammond <chipx86@gnupdate.org> | |
| 7 * | |
| 8 * This program is free software; you can redistribute it and/or modify | |
| 9 * it under the terms of the GNU General Public License as published by | |
| 10 * the Free Software Foundation; either version 2 of the License, or | |
| 11 * (at your option) any later version. | |
| 12 * | |
| 13 * This program is distributed in the hope that it will be useful, | |
| 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 16 * GNU General Public License for more details. | |
| 17 * | |
| 18 * You should have received a copy of the GNU General Public License | |
| 19 * along with this program; if not, write to the Free Software | |
| 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 21 */ | |
| 22 #include "internal.h" | |
|
7051
e885d4963a68
[gaim-migrate @ 7614]
Christian Hammond <chipx86@chipx86.com>
parents:
7050
diff
changeset
|
23 #include "debug.h" |
| 7016 | 24 #include "plugin.h" |
|
7051
e885d4963a68
[gaim-migrate @ 7614]
Christian Hammond <chipx86@chipx86.com>
parents:
7050
diff
changeset
|
25 #include "sslconn.h" |
| 9943 | 26 #include "version.h" |
| 7016 | 27 |
| 28 #define SSL_GNUTLS_PLUGIN_ID "ssl-gnutls" | |
| 29 | |
| 30 #ifdef HAVE_GNUTLS | |
| 31 | |
| 32 #include <gnutls/gnutls.h> | |
| 33 | |
| 34 typedef struct | |
| 35 { | |
| 36 gnutls_session session; | |
| 37 | |
| 38 } GaimSslGnutlsData; | |
| 39 | |
| 40 #define GAIM_SSL_GNUTLS_DATA(gsc) ((GaimSslGnutlsData *)gsc->private_data) | |
| 41 | |
| 42 static gnutls_certificate_client_credentials xcred; | |
| 43 | |
| 7862 | 44 static void |
| 45 ssl_gnutls_init_gnutls(void) | |
| 7016 | 46 { |
| 47 gnutls_global_init(); | |
| 48 | |
| 49 gnutls_certificate_allocate_credentials(&xcred); | |
| 50 gnutls_certificate_set_x509_trust_file(xcred, "ca.pem", | |
| 51 GNUTLS_X509_FMT_PEM); | |
| 7862 | 52 } |
| 7016 | 53 |
| 7862 | 54 static gboolean |
| 55 ssl_gnutls_init(void) | |
| 56 { | |
| 57 return TRUE; | |
| 7016 | 58 } |
| 59 | |
| 60 static void | |
| 61 ssl_gnutls_uninit(void) | |
| 62 { | |
| 63 gnutls_global_deinit(); | |
| 64 | |
| 65 gnutls_certificate_free_credentials(xcred); | |
| 66 } | |
| 67 | |
| 68 static void | |
| 69 ssl_gnutls_connect_cb(gpointer data, gint source, GaimInputCondition cond) | |
| 70 { | |
| 71 GaimSslConnection *gsc = (GaimSslConnection *)data; | |
| 72 GaimSslGnutlsData *gnutls_data; | |
| 73 static const int cert_type_priority[2] = { GNUTLS_CRT_X509, 0 }; | |
| 74 int ret; | |
| 75 | |
| 8362 | 76 if (source < 0) { |
| 77 if(gsc->error_cb != NULL) | |
| 78 gsc->error_cb(gsc, GAIM_SSL_CONNECT_FAILED, gsc->connect_cb_data); | |
| 79 | |
| 80 gaim_ssl_close(gsc); | |
| 7016 | 81 return; |
| 8362 | 82 } |
| 7016 | 83 |
| 84 gsc->fd = source; | |
| 85 | |
| 86 gnutls_data = g_new0(GaimSslGnutlsData, 1); | |
| 87 gsc->private_data = gnutls_data; | |
| 88 | |
| 89 gnutls_init(&gnutls_data->session, GNUTLS_CLIENT); | |
| 90 gnutls_set_default_priority(gnutls_data->session); | |
| 91 | |
| 92 gnutls_certificate_type_set_priority(gnutls_data->session, | |
| 93 cert_type_priority); | |
| 94 | |
| 95 gnutls_credentials_set(gnutls_data->session, GNUTLS_CRD_CERTIFICATE, | |
| 96 xcred); | |
| 97 | |
| 98 gnutls_transport_set_ptr(gnutls_data->session, GINT_TO_POINTER(source)); | |
| 99 | |
|
7834
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
100 |
|
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
101 do |
|
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
102 { |
| 8375 | 103 gaim_debug_info("gnutls", "Handshaking\n"); |
|
7834
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
104 ret = gnutls_handshake(gnutls_data->session); |
|
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
105 } |
|
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
106 while ((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)); |
|
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
107 |
| 7016 | 108 if (ret < 0) |
| 109 { | |
|
7325
35e652831230
[gaim-migrate @ 7911]
Christian Hammond <chipx86@chipx86.com>
parents:
7274
diff
changeset
|
110 gaim_debug_error("gnutls", "Handshake failed. Error %d\n", ret); |
| 7016 | 111 |
|
7274
448e39ace278
[gaim-migrate @ 7851]
Christian Hammond <chipx86@chipx86.com>
parents:
7051
diff
changeset
|
112 if (gsc->error_cb != NULL) |
|
7481
5f0f9d7fba6a
[gaim-migrate @ 8094]
Christian Hammond <chipx86@chipx86.com>
parents:
7467
diff
changeset
|
113 gsc->error_cb(gsc, GAIM_SSL_HANDSHAKE_FAILED, |
|
5f0f9d7fba6a
[gaim-migrate @ 8094]
Christian Hammond <chipx86@chipx86.com>
parents:
7467
diff
changeset
|
114 gsc->connect_cb_data); |
|
7274
448e39ace278
[gaim-migrate @ 7851]
Christian Hammond <chipx86@chipx86.com>
parents:
7051
diff
changeset
|
115 |
| 7016 | 116 gaim_ssl_close(gsc); |
| 117 } | |
| 118 else | |
| 119 { | |
| 8369 | 120 gaim_debug_info("gnutls", "Handshake complete\n"); |
| 121 | |
| 7016 | 122 gsc->connect_cb(gsc->connect_cb_data, gsc, cond); |
| 123 } | |
| 124 } | |
| 125 | |
| 126 static void | |
| 127 ssl_gnutls_close(GaimSslConnection *gsc) | |
| 128 { | |
| 129 GaimSslGnutlsData *gnutls_data = GAIM_SSL_GNUTLS_DATA(gsc); | |
| 130 | |
| 7467 | 131 if(!gnutls_data) |
| 132 return; | |
| 133 | |
| 7016 | 134 gnutls_bye(gnutls_data->session, GNUTLS_SHUT_RDWR); |
| 135 | |
| 136 gnutls_deinit(gnutls_data->session); | |
| 137 | |
| 138 g_free(gnutls_data); | |
| 139 } | |
| 140 | |
| 141 static size_t | |
| 142 ssl_gnutls_read(GaimSslConnection *gsc, void *data, size_t len) | |
| 143 { | |
| 144 GaimSslGnutlsData *gnutls_data = GAIM_SSL_GNUTLS_DATA(gsc); | |
| 145 int s; | |
| 146 | |
|
7834
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
147 do |
|
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
148 { |
|
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
149 s = gnutls_record_recv(gnutls_data->session, data, len); |
|
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
150 } |
|
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
151 while ((s == GNUTLS_E_AGAIN) || (s == GNUTLS_E_INTERRUPTED)); |
| 7016 | 152 |
| 153 if (s < 0) | |
|
7834
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
154 { |
|
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
155 gaim_debug_error("gnutls", "receive failed: %d\n", s); |
| 7016 | 156 s = 0; |
|
7834
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
157 } |
| 7016 | 158 |
| 159 return s; | |
| 160 } | |
| 161 | |
| 162 static size_t | |
| 163 ssl_gnutls_write(GaimSslConnection *gsc, const void *data, size_t len) | |
| 164 { | |
| 165 GaimSslGnutlsData *gnutls_data = GAIM_SSL_GNUTLS_DATA(gsc); | |
| 7467 | 166 size_t s = 0; |
| 7016 | 167 |
| 7467 | 168 if(gnutls_data) |
| 169 s = gnutls_record_send(gnutls_data->session, data, len); | |
| 7016 | 170 |
| 171 return s; | |
| 172 } | |
| 173 | |
| 174 static GaimSslOps ssl_ops = | |
| 175 { | |
| 176 ssl_gnutls_init, | |
| 177 ssl_gnutls_uninit, | |
| 178 ssl_gnutls_connect_cb, | |
| 179 ssl_gnutls_close, | |
| 180 ssl_gnutls_read, | |
| 181 ssl_gnutls_write | |
| 182 }; | |
| 183 | |
| 184 #endif /* HAVE_GNUTLS */ | |
| 185 | |
| 186 static gboolean | |
| 187 plugin_load(GaimPlugin *plugin) | |
| 188 { | |
| 189 #ifdef HAVE_GNUTLS | |
| 7862 | 190 if (!gaim_ssl_get_ops()) { |
| 191 gaim_ssl_set_ops(&ssl_ops); | |
| 192 } | |
| 7016 | 193 |
|
11033
50224ac8184d
[gaim-migrate @ 12919]
Etan Reisner <pidgin@unreliablesource.net>
parents:
9943
diff
changeset
|
194 /* Init GNUTLS now so others can use it even if sslconn never does */ |
|
50224ac8184d
[gaim-migrate @ 12919]
Etan Reisner <pidgin@unreliablesource.net>
parents:
9943
diff
changeset
|
195 ssl_gnutls_init_gnutls(); |
|
50224ac8184d
[gaim-migrate @ 12919]
Etan Reisner <pidgin@unreliablesource.net>
parents:
9943
diff
changeset
|
196 |
| 7016 | 197 return TRUE; |
| 198 #else | |
| 199 return FALSE; | |
| 200 #endif | |
| 201 } | |
| 202 | |
| 203 static gboolean | |
| 204 plugin_unload(GaimPlugin *plugin) | |
| 205 { | |
|
7050
e8cd8827fb25
[gaim-migrate @ 7613]
Christian Hammond <chipx86@chipx86.com>
parents:
7016
diff
changeset
|
206 #ifdef HAVE_GNUTLS |
| 7862 | 207 if (gaim_ssl_get_ops() == &ssl_ops) { |
| 208 gaim_ssl_set_ops(NULL); | |
| 209 } | |
|
7050
e8cd8827fb25
[gaim-migrate @ 7613]
Christian Hammond <chipx86@chipx86.com>
parents:
7016
diff
changeset
|
210 #endif |
|
e8cd8827fb25
[gaim-migrate @ 7613]
Christian Hammond <chipx86@chipx86.com>
parents:
7016
diff
changeset
|
211 |
| 7016 | 212 return TRUE; |
| 213 } | |
| 214 | |
| 215 static GaimPluginInfo info = | |
| 216 { | |
| 9943 | 217 GAIM_PLUGIN_MAGIC, |
| 218 GAIM_MAJOR_VERSION, | |
| 219 GAIM_MINOR_VERSION, | |
| 7016 | 220 GAIM_PLUGIN_STANDARD, /**< type */ |
| 221 NULL, /**< ui_requirement */ | |
| 222 GAIM_PLUGIN_FLAG_INVISIBLE, /**< flags */ | |
| 223 NULL, /**< dependencies */ | |
| 224 GAIM_PRIORITY_DEFAULT, /**< priority */ | |
| 225 | |
| 226 SSL_GNUTLS_PLUGIN_ID, /**< id */ | |
| 227 N_("GNUTLS"), /**< name */ | |
| 228 VERSION, /**< version */ | |
| 229 /** summary */ | |
| 230 N_("Provides SSL support through GNUTLS."), | |
| 231 /** description */ | |
| 232 N_("Provides SSL support through GNUTLS."), | |
| 233 "Christian Hammond <chipx86@gnupdate.org>", | |
| 234 GAIM_WEBSITE, /**< homepage */ | |
| 235 | |
| 236 plugin_load, /**< load */ | |
| 237 plugin_unload, /**< unload */ | |
| 238 NULL, /**< destroy */ | |
| 239 | |
| 240 NULL, /**< ui_info */ | |
| 11513 | 241 NULL, /**< extra_info */ |
| 242 NULL, /**< prefs_info */ | |
| 243 NULL /**< actions */ | |
| 7016 | 244 }; |
| 245 | |
| 246 static void | |
| 247 init_plugin(GaimPlugin *plugin) | |
| 248 { | |
| 249 } | |
| 250 | |
| 251 GAIM_INIT_PLUGIN(ssl_gnutls, init_plugin, info) |
