Mercurial > pidgin.yaz
annotate plugins/ssl/ssl-gnutls.c @ 7834:99ffabc6ce73
[gaim-migrate @ 8487]
This patch from Mike Hearn should fix HTTP proxy support for MSN, and
provides another step toward the MSN HTTP access method working. The HTTP
proxy may need testing from other people, but looks like it shouldn't give
any problems.
committer: Tailor Script <tailor@pidgin.im>
author | Christian Hammond <chipx86@chipx86.com> |
---|---|
date | Fri, 12 Dec 2003 00:14:40 +0000 |
parents | ea2d07ad05a9 |
children | 01e6e9c46a01 |
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" |
7016 | 26 |
27 #define SSL_GNUTLS_PLUGIN_ID "ssl-gnutls" | |
28 | |
29 #ifdef HAVE_GNUTLS | |
30 | |
31 #include <gnutls/gnutls.h> | |
32 | |
33 typedef struct | |
34 { | |
35 gnutls_session session; | |
36 | |
37 } GaimSslGnutlsData; | |
38 | |
39 #define GAIM_SSL_GNUTLS_DATA(gsc) ((GaimSslGnutlsData *)gsc->private_data) | |
40 | |
41 static gnutls_certificate_client_credentials xcred; | |
42 | |
43 static gboolean | |
44 ssl_gnutls_init(void) | |
45 { | |
46 gnutls_global_init(); | |
47 | |
48 gnutls_certificate_allocate_credentials(&xcred); | |
49 gnutls_certificate_set_x509_trust_file(xcred, "ca.pem", | |
50 GNUTLS_X509_FMT_PEM); | |
51 | |
52 return TRUE; | |
53 } | |
54 | |
55 static void | |
56 ssl_gnutls_uninit(void) | |
57 { | |
58 gnutls_global_deinit(); | |
59 | |
60 gnutls_certificate_free_credentials(xcred); | |
61 } | |
62 | |
63 static void | |
64 ssl_gnutls_connect_cb(gpointer data, gint source, GaimInputCondition cond) | |
65 { | |
66 GaimSslConnection *gsc = (GaimSslConnection *)data; | |
67 GaimSslGnutlsData *gnutls_data; | |
68 static const int cert_type_priority[2] = { GNUTLS_CRT_X509, 0 }; | |
69 int ret; | |
70 | |
71 if (source < 0) | |
72 return; | |
73 | |
74 gsc->fd = source; | |
75 | |
76 gnutls_data = g_new0(GaimSslGnutlsData, 1); | |
77 gsc->private_data = gnutls_data; | |
78 | |
79 gnutls_init(&gnutls_data->session, GNUTLS_CLIENT); | |
80 gnutls_set_default_priority(gnutls_data->session); | |
81 | |
82 gnutls_certificate_type_set_priority(gnutls_data->session, | |
83 cert_type_priority); | |
84 | |
85 gnutls_credentials_set(gnutls_data->session, GNUTLS_CRD_CERTIFICATE, | |
86 xcred); | |
87 | |
88 gnutls_transport_set_ptr(gnutls_data->session, GINT_TO_POINTER(source)); | |
89 | |
90 gaim_debug_info("gnutls", "Handshaking\n"); | |
7834
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
91 |
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
92 do |
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
93 { |
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
94 ret = gnutls_handshake(gnutls_data->session); |
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
95 } |
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
96 while ((ret == GNUTLS_E_AGAIN) || (ret == GNUTLS_E_INTERRUPTED)); |
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
97 |
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
98 gaim_debug_info("gnutls", "Handshake complete\n"); |
7016 | 99 |
100 if (ret < 0) | |
101 { | |
7325
35e652831230
[gaim-migrate @ 7911]
Christian Hammond <chipx86@chipx86.com>
parents:
7274
diff
changeset
|
102 gaim_debug_error("gnutls", "Handshake failed. Error %d\n", ret); |
7016 | 103 |
7274
448e39ace278
[gaim-migrate @ 7851]
Christian Hammond <chipx86@chipx86.com>
parents:
7051
diff
changeset
|
104 if (gsc->error_cb != NULL) |
7481
5f0f9d7fba6a
[gaim-migrate @ 8094]
Christian Hammond <chipx86@chipx86.com>
parents:
7467
diff
changeset
|
105 gsc->error_cb(gsc, GAIM_SSL_HANDSHAKE_FAILED, |
5f0f9d7fba6a
[gaim-migrate @ 8094]
Christian Hammond <chipx86@chipx86.com>
parents:
7467
diff
changeset
|
106 gsc->connect_cb_data); |
7274
448e39ace278
[gaim-migrate @ 7851]
Christian Hammond <chipx86@chipx86.com>
parents:
7051
diff
changeset
|
107 |
7016 | 108 gaim_ssl_close(gsc); |
109 } | |
110 else | |
111 { | |
112 gsc->connect_cb(gsc->connect_cb_data, gsc, cond); | |
113 } | |
114 } | |
115 | |
116 static void | |
117 ssl_gnutls_close(GaimSslConnection *gsc) | |
118 { | |
119 GaimSslGnutlsData *gnutls_data = GAIM_SSL_GNUTLS_DATA(gsc); | |
120 | |
7467 | 121 if(!gnutls_data) |
122 return; | |
123 | |
7016 | 124 gnutls_bye(gnutls_data->session, GNUTLS_SHUT_RDWR); |
125 | |
126 gnutls_deinit(gnutls_data->session); | |
127 | |
128 g_free(gnutls_data); | |
129 } | |
130 | |
131 static size_t | |
132 ssl_gnutls_read(GaimSslConnection *gsc, void *data, size_t len) | |
133 { | |
134 GaimSslGnutlsData *gnutls_data = GAIM_SSL_GNUTLS_DATA(gsc); | |
135 int s; | |
136 | |
7834
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
137 do |
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
138 { |
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
139 s = gnutls_record_recv(gnutls_data->session, data, len); |
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
140 } |
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
141 while ((s == GNUTLS_E_AGAIN) || (s == GNUTLS_E_INTERRUPTED)); |
7016 | 142 |
143 if (s < 0) | |
7834
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
144 { |
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
145 gaim_debug_error("gnutls", "receive failed: %d\n", s); |
7016 | 146 s = 0; |
7834
99ffabc6ce73
[gaim-migrate @ 8487]
Christian Hammond <chipx86@chipx86.com>
parents:
7631
diff
changeset
|
147 } |
7016 | 148 |
149 return s; | |
150 } | |
151 | |
152 static size_t | |
153 ssl_gnutls_write(GaimSslConnection *gsc, const void *data, size_t len) | |
154 { | |
155 GaimSslGnutlsData *gnutls_data = GAIM_SSL_GNUTLS_DATA(gsc); | |
7467 | 156 size_t s = 0; |
7016 | 157 |
7467 | 158 if(gnutls_data) |
159 s = gnutls_record_send(gnutls_data->session, data, len); | |
7016 | 160 |
161 return s; | |
162 } | |
163 | |
164 static GaimSslOps ssl_ops = | |
165 { | |
166 ssl_gnutls_init, | |
167 ssl_gnutls_uninit, | |
168 ssl_gnutls_connect_cb, | |
169 ssl_gnutls_close, | |
170 ssl_gnutls_read, | |
171 ssl_gnutls_write | |
172 }; | |
173 | |
174 #endif /* HAVE_GNUTLS */ | |
175 | |
176 static gboolean | |
177 plugin_load(GaimPlugin *plugin) | |
178 { | |
179 #ifdef HAVE_GNUTLS | |
180 gaim_ssl_set_ops(&ssl_ops); | |
181 | |
182 return TRUE; | |
183 #else | |
184 return FALSE; | |
185 #endif | |
186 } | |
187 | |
188 static gboolean | |
189 plugin_unload(GaimPlugin *plugin) | |
190 { | |
7050
e8cd8827fb25
[gaim-migrate @ 7613]
Christian Hammond <chipx86@chipx86.com>
parents:
7016
diff
changeset
|
191 #ifdef HAVE_GNUTLS |
e8cd8827fb25
[gaim-migrate @ 7613]
Christian Hammond <chipx86@chipx86.com>
parents:
7016
diff
changeset
|
192 gaim_ssl_set_ops(NULL); |
e8cd8827fb25
[gaim-migrate @ 7613]
Christian Hammond <chipx86@chipx86.com>
parents:
7016
diff
changeset
|
193 #endif |
e8cd8827fb25
[gaim-migrate @ 7613]
Christian Hammond <chipx86@chipx86.com>
parents:
7016
diff
changeset
|
194 |
7016 | 195 return TRUE; |
196 } | |
197 | |
198 static GaimPluginInfo info = | |
199 { | |
200 2, /**< api_version */ | |
201 GAIM_PLUGIN_STANDARD, /**< type */ | |
202 NULL, /**< ui_requirement */ | |
203 GAIM_PLUGIN_FLAG_INVISIBLE, /**< flags */ | |
204 NULL, /**< dependencies */ | |
205 GAIM_PRIORITY_DEFAULT, /**< priority */ | |
206 | |
207 SSL_GNUTLS_PLUGIN_ID, /**< id */ | |
208 N_("GNUTLS"), /**< name */ | |
209 VERSION, /**< version */ | |
210 /** summary */ | |
211 N_("Provides SSL support through GNUTLS."), | |
212 /** description */ | |
213 N_("Provides SSL support through GNUTLS."), | |
214 "Christian Hammond <chipx86@gnupdate.org>", | |
215 GAIM_WEBSITE, /**< homepage */ | |
216 | |
217 plugin_load, /**< load */ | |
218 plugin_unload, /**< unload */ | |
219 NULL, /**< destroy */ | |
220 | |
221 NULL, /**< ui_info */ | |
222 NULL /**< extra_info */ | |
223 }; | |
224 | |
225 static void | |
226 init_plugin(GaimPlugin *plugin) | |
227 { | |
228 } | |
229 | |
230 GAIM_INIT_PLUGIN(ssl_gnutls, init_plugin, info) |