Mercurial > pidgin
annotate plugins/ssl/ssl-nss.c @ 8479:dc07d60d1183
[gaim-migrate @ 9212]
Actually, that sucks pretty hard ... fortunately there is a trivial
fix for that. There may be bustage of old versions of automake, but
it seems this was introduced when the autoconf syntax was changed, so
it should only bust busted systems as best I can tell. (Removes
version information redundancy in configure.ac)
committer: Tailor Script <tailor@pidgin.im>
author | Ethan Blanton <elb@pidgin.im> |
---|---|
date | Sun, 21 Mar 2004 06:18:55 +0000 |
parents | 1976914caa51 |
children | d7b8eb1f0a18 |
rev | line source |
---|---|
7016 | 1 /** |
2 * @file ssl-nss.c Mozilla NSS 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 |
7029
b80c7a4dfae7
[gaim-migrate @ 7592]
Christian Hammond <chipx86@chipx86.com>
parents:
7028
diff
changeset
|
27 #define SSL_NSS_PLUGIN_ID "ssl-nss" |
7016 | 28 |
29 #ifdef HAVE_NSS | |
30 | |
31 #include <nspr.h> | |
32 #include <private/pprio.h> | |
33 #include <nss.h> | |
34 #include <pk11func.h> | |
35 #include <prio.h> | |
36 #include <secerr.h> | |
37 #include <secmod.h> | |
38 #include <ssl.h> | |
39 #include <sslerr.h> | |
40 #include <sslproto.h> | |
41 | |
42 typedef struct | |
43 { | |
44 PRFileDesc *fd; | |
45 PRFileDesc *in; | |
46 | |
47 } GaimSslNssData; | |
48 | |
49 #define GAIM_SSL_NSS_DATA(gsc) ((GaimSslNssData *)gsc->private_data) | |
50 | |
51 static const PRIOMethods *_nss_methods = NULL; | |
52 static PRDescIdentity _identity; | |
53 | |
7993
495d3dbb4e84
[gaim-migrate @ 8670]
Christian Hammond <chipx86@chipx86.com>
parents:
7862
diff
changeset
|
54 static void |
7862 | 55 ssl_nss_init_nss(void) |
56 { | |
57 PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); | |
58 NSS_NoDB_Init(NULL); | |
59 | |
60 /* TODO: Fix this so autoconf does the work trying to find this lib. */ | |
61 SECMOD_AddNewModule("Builtins", | |
62 #ifndef _WIN32 | |
63 LIBDIR "/libnssckbi.so", | |
64 #else | |
65 "nssckbi.dll", | |
66 #endif | |
67 0, 0); | |
68 NSS_SetDomesticPolicy(); | |
69 | |
70 _identity = PR_GetUniqueIdentity("Gaim"); | |
71 _nss_methods = PR_GetDefaultIOMethods(); | |
72 } | |
73 | |
7016 | 74 static SECStatus |
75 ssl_auth_cert(void *arg, PRFileDesc *socket, PRBool checksig, | |
76 PRBool is_server) | |
77 { | |
78 return SECSuccess; | |
79 | |
80 #if 0 | |
81 CERTCertificate *cert; | |
82 void *pinArg; | |
83 SECStatus status; | |
84 | |
85 cert = SSL_PeerCertificate(socket); | |
86 pinArg = SSL_RevealPinArg(socket); | |
87 | |
88 status = CERT_VerifyCertNow((CERTCertDBHandle *)arg, cert, checksig, | |
89 certUsageSSLClient, pinArg); | |
90 | |
91 if (status != SECSuccess) { | |
92 gaim_debug_error("nss", "CERT_VerifyCertNow failed\n"); | |
93 CERT_DestroyCertificate(cert); | |
94 return status; | |
95 } | |
96 | |
97 CERT_DestroyCertificate(cert); | |
98 return SECSuccess; | |
99 #endif | |
100 } | |
101 | |
102 static SECStatus | |
103 ssl_bad_cert(void *arg, PRFileDesc *socket) | |
104 { | |
105 SECStatus status = SECFailure; | |
106 PRErrorCode err; | |
107 | |
108 if (arg == NULL) | |
109 return status; | |
110 | |
111 *(PRErrorCode *)arg = err = PORT_GetError(); | |
112 | |
113 switch (err) | |
114 { | |
115 case SEC_ERROR_INVALID_AVA: | |
116 case SEC_ERROR_INVALID_TIME: | |
117 case SEC_ERROR_BAD_SIGNATURE: | |
118 case SEC_ERROR_EXPIRED_CERTIFICATE: | |
119 case SEC_ERROR_UNKNOWN_ISSUER: | |
120 case SEC_ERROR_UNTRUSTED_CERT: | |
121 case SEC_ERROR_CERT_VALID: | |
122 case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: | |
123 case SEC_ERROR_CRL_EXPIRED: | |
124 case SEC_ERROR_CRL_BAD_SIGNATURE: | |
125 case SEC_ERROR_EXTENSION_VALUE_INVALID: | |
126 case SEC_ERROR_CA_CERT_INVALID: | |
127 case SEC_ERROR_CERT_USAGES_INVALID: | |
128 case SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION: | |
129 status = SECSuccess; | |
130 break; | |
131 | |
132 default: | |
133 status = SECFailure; | |
134 break; | |
135 } | |
136 | |
137 gaim_debug_error("nss", "Bad certificate: %d\n"); | |
138 | |
139 return status; | |
140 } | |
141 | |
142 static gboolean | |
143 ssl_nss_init(void) | |
144 { | |
7862 | 145 return TRUE; |
7016 | 146 } |
147 | |
148 static void | |
149 ssl_nss_uninit(void) | |
150 { | |
151 PR_Cleanup(); | |
152 | |
153 _nss_methods = NULL; | |
154 } | |
155 | |
156 static void | |
157 ssl_nss_connect_cb(gpointer data, gint source, GaimInputCondition cond) | |
158 { | |
159 GaimSslConnection *gsc = (GaimSslConnection *)data; | |
160 GaimSslNssData *nss_data = g_new0(GaimSslNssData, 1); | |
161 PRSocketOptionData socket_opt; | |
162 | |
163 gsc->private_data = nss_data; | |
164 | |
165 gsc->fd = source; | |
166 | |
167 nss_data->fd = PR_ImportTCPSocket(gsc->fd); | |
168 | |
169 if (nss_data->fd == NULL) | |
170 { | |
171 gaim_debug_error("nss", "nss_data->fd == NULL!\n"); | |
172 | |
8362 | 173 if (gsc->error_cb != NULL) |
174 gsc->error_cb(gsc, GAIM_SSL_CONNECT_FAILED, gsc->connect_cb_data); | |
175 | |
7016 | 176 gaim_ssl_close((GaimSslConnection *)gsc); |
177 | |
178 return; | |
179 } | |
180 | |
181 socket_opt.option = PR_SockOpt_Nonblocking; | |
182 socket_opt.value.non_blocking = PR_FALSE; | |
183 | |
184 PR_SetSocketOption(nss_data->fd, &socket_opt); | |
185 | |
186 nss_data->in = SSL_ImportFD(NULL, nss_data->fd); | |
187 | |
188 if (nss_data->in == NULL) | |
189 { | |
190 gaim_debug_error("nss", "nss_data->in == NUL!\n"); | |
191 | |
8362 | 192 if (gsc->error_cb != NULL) |
193 gsc->error_cb(gsc, GAIM_SSL_CONNECT_FAILED, gsc->connect_cb_data); | |
194 | |
7016 | 195 gaim_ssl_close((GaimSslConnection *)gsc); |
196 | |
197 return; | |
198 } | |
199 | |
200 SSL_OptionSet(nss_data->in, SSL_SECURITY, PR_TRUE); | |
201 SSL_OptionSet(nss_data->in, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); | |
202 | |
203 SSL_AuthCertificateHook(nss_data->in, | |
204 (SSLAuthCertificate)ssl_auth_cert, | |
205 (void *)CERT_GetDefaultCertDB()); | |
206 SSL_BadCertHook(nss_data->in, (SSLBadCertHandler)ssl_bad_cert, NULL); | |
207 | |
7157 | 208 if(gsc->host) |
209 SSL_SetURL(nss_data->in, gsc->host); | |
7016 | 210 |
211 SSL_ResetHandshake(nss_data->in, PR_FALSE); | |
212 | |
213 if (SSL_ForceHandshake(nss_data->in)) | |
214 { | |
215 gaim_debug_error("nss", "Handshake failed\n"); | |
216 | |
7274
448e39ace278
[gaim-migrate @ 7851]
Christian Hammond <chipx86@chipx86.com>
parents:
7157
diff
changeset
|
217 if (gsc->error_cb != NULL) |
8360 | 218 gsc->error_cb(gsc, GAIM_SSL_HANDSHAKE_FAILED, gsc->connect_cb_data); |
7274
448e39ace278
[gaim-migrate @ 7851]
Christian Hammond <chipx86@chipx86.com>
parents:
7157
diff
changeset
|
219 |
7016 | 220 gaim_ssl_close(gsc); |
221 | |
222 return; | |
223 } | |
224 | |
225 gsc->connect_cb(gsc->connect_cb_data, gsc, cond); | |
226 } | |
227 | |
228 static void | |
229 ssl_nss_close(GaimSslConnection *gsc) | |
230 { | |
231 GaimSslNssData *nss_data = GAIM_SSL_NSS_DATA(gsc); | |
232 | |
7467 | 233 if(!nss_data) |
234 return; | |
235 | |
7016 | 236 if (nss_data->in) PR_Close(nss_data->in); |
237 /* if (nss_data->fd) PR_Close(nss_data->fd); */ | |
238 | |
239 g_free(nss_data); | |
240 } | |
241 | |
242 static size_t | |
243 ssl_nss_read(GaimSslConnection *gsc, void *data, size_t len) | |
244 { | |
245 GaimSslNssData *nss_data = GAIM_SSL_NSS_DATA(gsc); | |
246 | |
247 return PR_Read(nss_data->in, data, len); | |
248 } | |
249 | |
250 static size_t | |
251 ssl_nss_write(GaimSslConnection *gsc, const void *data, size_t len) | |
252 { | |
253 GaimSslNssData *nss_data = GAIM_SSL_NSS_DATA(gsc); | |
254 | |
7467 | 255 if(!nss_data) |
256 return 0; | |
257 | |
7016 | 258 return PR_Write(nss_data->in, data, len); |
259 } | |
260 | |
261 static GaimSslOps ssl_ops = | |
262 { | |
263 ssl_nss_init, | |
264 ssl_nss_uninit, | |
265 ssl_nss_connect_cb, | |
266 ssl_nss_close, | |
267 ssl_nss_read, | |
268 ssl_nss_write | |
269 }; | |
270 | |
271 #endif /* HAVE_NSS */ | |
272 | |
273 | |
274 static gboolean | |
275 plugin_load(GaimPlugin *plugin) | |
276 { | |
277 #ifdef HAVE_NSS | |
7862 | 278 if (!gaim_ssl_get_ops()) { |
279 gaim_ssl_set_ops(&ssl_ops); | |
280 } | |
7016 | 281 |
7862 | 282 /* Init NSS now, so others can use it even if sslconn never does */ |
283 ssl_nss_init_nss(); | |
7016 | 284 return TRUE; |
285 #else | |
286 return FALSE; | |
287 #endif | |
288 } | |
289 | |
290 static gboolean | |
291 plugin_unload(GaimPlugin *plugin) | |
292 { | |
7053 | 293 #ifdef HAVE_NSS |
7862 | 294 if (gaim_ssl_get_ops() == &ssl_ops) { |
295 gaim_ssl_set_ops(NULL); | |
296 } | |
7050
e8cd8827fb25
[gaim-migrate @ 7613]
Christian Hammond <chipx86@chipx86.com>
parents:
7029
diff
changeset
|
297 #endif |
e8cd8827fb25
[gaim-migrate @ 7613]
Christian Hammond <chipx86@chipx86.com>
parents:
7029
diff
changeset
|
298 |
7016 | 299 return TRUE; |
300 } | |
301 | |
302 static GaimPluginInfo info = | |
303 { | |
304 2, /**< api_version */ | |
305 GAIM_PLUGIN_STANDARD, /**< type */ | |
306 NULL, /**< ui_requirement */ | |
307 GAIM_PLUGIN_FLAG_INVISIBLE, /**< flags */ | |
308 NULL, /**< dependencies */ | |
309 GAIM_PRIORITY_DEFAULT, /**< priority */ | |
310 | |
7029
b80c7a4dfae7
[gaim-migrate @ 7592]
Christian Hammond <chipx86@chipx86.com>
parents:
7028
diff
changeset
|
311 SSL_NSS_PLUGIN_ID, /**< id */ |
7016 | 312 N_("NSS"), /**< name */ |
313 VERSION, /**< version */ | |
314 /** summary */ | |
315 N_("Provides SSL support through Mozilla NSS."), | |
316 /** description */ | |
317 N_("Provides SSL support through Mozilla NSS."), | |
318 "Christian Hammond <chipx86@gnupdate.org>", | |
319 GAIM_WEBSITE, /**< homepage */ | |
320 | |
321 plugin_load, /**< load */ | |
322 plugin_unload, /**< unload */ | |
323 NULL, /**< destroy */ | |
324 | |
325 NULL, /**< ui_info */ | |
326 NULL /**< extra_info */ | |
327 }; | |
328 | |
329 static void | |
330 init_plugin(GaimPlugin *plugin) | |
331 { | |
332 } | |
333 | |
334 GAIM_INIT_PLUGIN(ssl_nss, init_plugin, info) |