Mercurial > pidgin.yaz
annotate plugins/ssl/ssl-nss.c @ 7665:0351ff7030d0
[gaim-migrate @ 8309]
Felipe Contreras (aka revo aka shx) writes:
" Basically that, currently gaim will not display
international "subjects" or "from" fields from emails,
like "a??a" or "Pa?l".
This implements the propper RFC that specify the format
for those fields."
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Sun, 30 Nov 2003 04:17:17 +0000 |
parents | f9ed27be344e |
children | 01e6e9c46a01 |
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 | |
54 static SECStatus | |
55 ssl_auth_cert(void *arg, PRFileDesc *socket, PRBool checksig, | |
56 PRBool is_server) | |
57 { | |
58 return SECSuccess; | |
59 | |
60 #if 0 | |
61 CERTCertificate *cert; | |
62 void *pinArg; | |
63 SECStatus status; | |
64 | |
65 cert = SSL_PeerCertificate(socket); | |
66 pinArg = SSL_RevealPinArg(socket); | |
67 | |
68 status = CERT_VerifyCertNow((CERTCertDBHandle *)arg, cert, checksig, | |
69 certUsageSSLClient, pinArg); | |
70 | |
71 if (status != SECSuccess) { | |
72 gaim_debug_error("nss", "CERT_VerifyCertNow failed\n"); | |
73 CERT_DestroyCertificate(cert); | |
74 return status; | |
75 } | |
76 | |
77 CERT_DestroyCertificate(cert); | |
78 return SECSuccess; | |
79 #endif | |
80 } | |
81 | |
82 static SECStatus | |
83 ssl_bad_cert(void *arg, PRFileDesc *socket) | |
84 { | |
85 SECStatus status = SECFailure; | |
86 PRErrorCode err; | |
87 | |
88 if (arg == NULL) | |
89 return status; | |
90 | |
91 *(PRErrorCode *)arg = err = PORT_GetError(); | |
92 | |
93 switch (err) | |
94 { | |
95 case SEC_ERROR_INVALID_AVA: | |
96 case SEC_ERROR_INVALID_TIME: | |
97 case SEC_ERROR_BAD_SIGNATURE: | |
98 case SEC_ERROR_EXPIRED_CERTIFICATE: | |
99 case SEC_ERROR_UNKNOWN_ISSUER: | |
100 case SEC_ERROR_UNTRUSTED_CERT: | |
101 case SEC_ERROR_CERT_VALID: | |
102 case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: | |
103 case SEC_ERROR_CRL_EXPIRED: | |
104 case SEC_ERROR_CRL_BAD_SIGNATURE: | |
105 case SEC_ERROR_EXTENSION_VALUE_INVALID: | |
106 case SEC_ERROR_CA_CERT_INVALID: | |
107 case SEC_ERROR_CERT_USAGES_INVALID: | |
108 case SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION: | |
109 status = SECSuccess; | |
110 break; | |
111 | |
112 default: | |
113 status = SECFailure; | |
114 break; | |
115 } | |
116 | |
117 gaim_debug_error("nss", "Bad certificate: %d\n"); | |
118 | |
119 return status; | |
120 } | |
121 | |
122 static gboolean | |
123 ssl_nss_init(void) | |
124 { | |
125 PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); | |
126 NSS_NoDB_Init(NULL); | |
127 | |
128 /* TODO: Fix this so autoconf does the work trying to find this lib. */ | |
129 SECMOD_AddNewModule("Builtins", | |
130 #ifndef _WIN32 | |
131 LIBDIR "/libnssckbi.so", | |
132 #else | |
133 "nssckbi.dll", | |
134 #endif | |
135 0, 0); | |
136 NSS_SetDomesticPolicy(); | |
137 | |
138 _identity = PR_GetUniqueIdentity("Gaim"); | |
139 _nss_methods = PR_GetDefaultIOMethods(); | |
140 | |
141 return TRUE; | |
142 } | |
143 | |
144 static void | |
145 ssl_nss_uninit(void) | |
146 { | |
147 PR_Cleanup(); | |
148 | |
149 _nss_methods = NULL; | |
150 } | |
151 | |
152 static void | |
153 ssl_nss_connect_cb(gpointer data, gint source, GaimInputCondition cond) | |
154 { | |
155 GaimSslConnection *gsc = (GaimSslConnection *)data; | |
156 GaimSslNssData *nss_data = g_new0(GaimSslNssData, 1); | |
157 PRSocketOptionData socket_opt; | |
158 | |
159 gsc->private_data = nss_data; | |
160 | |
161 gsc->fd = source; | |
162 | |
163 nss_data->fd = PR_ImportTCPSocket(gsc->fd); | |
164 | |
165 if (nss_data->fd == NULL) | |
166 { | |
167 gaim_debug_error("nss", "nss_data->fd == NULL!\n"); | |
168 | |
169 gaim_ssl_close((GaimSslConnection *)gsc); | |
170 | |
171 return; | |
172 } | |
173 | |
174 socket_opt.option = PR_SockOpt_Nonblocking; | |
175 socket_opt.value.non_blocking = PR_FALSE; | |
176 | |
177 PR_SetSocketOption(nss_data->fd, &socket_opt); | |
178 | |
179 nss_data->in = SSL_ImportFD(NULL, nss_data->fd); | |
180 | |
181 if (nss_data->in == NULL) | |
182 { | |
183 gaim_debug_error("nss", "nss_data->in == NUL!\n"); | |
184 | |
185 gaim_ssl_close((GaimSslConnection *)gsc); | |
186 | |
187 return; | |
188 } | |
189 | |
190 SSL_OptionSet(nss_data->in, SSL_SECURITY, PR_TRUE); | |
191 SSL_OptionSet(nss_data->in, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); | |
192 | |
193 SSL_AuthCertificateHook(nss_data->in, | |
194 (SSLAuthCertificate)ssl_auth_cert, | |
195 (void *)CERT_GetDefaultCertDB()); | |
196 SSL_BadCertHook(nss_data->in, (SSLBadCertHandler)ssl_bad_cert, NULL); | |
197 | |
7157 | 198 if(gsc->host) |
199 SSL_SetURL(nss_data->in, gsc->host); | |
7016 | 200 |
201 SSL_ResetHandshake(nss_data->in, PR_FALSE); | |
202 | |
203 if (SSL_ForceHandshake(nss_data->in)) | |
204 { | |
205 gaim_debug_error("nss", "Handshake failed\n"); | |
206 | |
7274
448e39ace278
[gaim-migrate @ 7851]
Christian Hammond <chipx86@chipx86.com>
parents:
7157
diff
changeset
|
207 if (gsc->error_cb != NULL) |
448e39ace278
[gaim-migrate @ 7851]
Christian Hammond <chipx86@chipx86.com>
parents:
7157
diff
changeset
|
208 gsc->error_cb(gsc, GAIM_SSL_HANDSHAKE_FAILED, data); |
448e39ace278
[gaim-migrate @ 7851]
Christian Hammond <chipx86@chipx86.com>
parents:
7157
diff
changeset
|
209 |
7016 | 210 gaim_ssl_close(gsc); |
211 | |
212 return; | |
213 } | |
214 | |
215 gsc->connect_cb(gsc->connect_cb_data, gsc, cond); | |
216 } | |
217 | |
218 static void | |
219 ssl_nss_close(GaimSslConnection *gsc) | |
220 { | |
221 GaimSslNssData *nss_data = GAIM_SSL_NSS_DATA(gsc); | |
222 | |
7467 | 223 if(!nss_data) |
224 return; | |
225 | |
7016 | 226 if (nss_data->in) PR_Close(nss_data->in); |
227 /* if (nss_data->fd) PR_Close(nss_data->fd); */ | |
228 | |
229 g_free(nss_data); | |
230 } | |
231 | |
232 static size_t | |
233 ssl_nss_read(GaimSslConnection *gsc, void *data, size_t len) | |
234 { | |
235 GaimSslNssData *nss_data = GAIM_SSL_NSS_DATA(gsc); | |
236 | |
237 return PR_Read(nss_data->in, data, len); | |
238 } | |
239 | |
240 static size_t | |
241 ssl_nss_write(GaimSslConnection *gsc, const void *data, size_t len) | |
242 { | |
243 GaimSslNssData *nss_data = GAIM_SSL_NSS_DATA(gsc); | |
244 | |
7467 | 245 if(!nss_data) |
246 return 0; | |
247 | |
7016 | 248 return PR_Write(nss_data->in, data, len); |
249 } | |
250 | |
251 static GaimSslOps ssl_ops = | |
252 { | |
253 ssl_nss_init, | |
254 ssl_nss_uninit, | |
255 ssl_nss_connect_cb, | |
256 ssl_nss_close, | |
257 ssl_nss_read, | |
258 ssl_nss_write | |
259 }; | |
260 | |
261 #endif /* HAVE_NSS */ | |
262 | |
263 | |
264 static gboolean | |
265 plugin_load(GaimPlugin *plugin) | |
266 { | |
267 #ifdef HAVE_NSS | |
268 gaim_ssl_set_ops(&ssl_ops); | |
269 | |
270 return TRUE; | |
271 #else | |
272 return FALSE; | |
273 #endif | |
274 } | |
275 | |
276 static gboolean | |
277 plugin_unload(GaimPlugin *plugin) | |
278 { | |
7053 | 279 #ifdef HAVE_NSS |
7050
e8cd8827fb25
[gaim-migrate @ 7613]
Christian Hammond <chipx86@chipx86.com>
parents:
7029
diff
changeset
|
280 gaim_ssl_set_ops(NULL); |
e8cd8827fb25
[gaim-migrate @ 7613]
Christian Hammond <chipx86@chipx86.com>
parents:
7029
diff
changeset
|
281 #endif |
e8cd8827fb25
[gaim-migrate @ 7613]
Christian Hammond <chipx86@chipx86.com>
parents:
7029
diff
changeset
|
282 |
7016 | 283 return TRUE; |
284 } | |
285 | |
286 static GaimPluginInfo info = | |
287 { | |
288 2, /**< api_version */ | |
289 GAIM_PLUGIN_STANDARD, /**< type */ | |
290 NULL, /**< ui_requirement */ | |
291 GAIM_PLUGIN_FLAG_INVISIBLE, /**< flags */ | |
292 NULL, /**< dependencies */ | |
293 GAIM_PRIORITY_DEFAULT, /**< priority */ | |
294 | |
7029
b80c7a4dfae7
[gaim-migrate @ 7592]
Christian Hammond <chipx86@chipx86.com>
parents:
7028
diff
changeset
|
295 SSL_NSS_PLUGIN_ID, /**< id */ |
7016 | 296 N_("NSS"), /**< name */ |
297 VERSION, /**< version */ | |
298 /** summary */ | |
299 N_("Provides SSL support through Mozilla NSS."), | |
300 /** description */ | |
301 N_("Provides SSL support through Mozilla NSS."), | |
302 "Christian Hammond <chipx86@gnupdate.org>", | |
303 GAIM_WEBSITE, /**< homepage */ | |
304 | |
305 plugin_load, /**< load */ | |
306 plugin_unload, /**< unload */ | |
307 NULL, /**< destroy */ | |
308 | |
309 NULL, /**< ui_info */ | |
310 NULL /**< extra_info */ | |
311 }; | |
312 | |
313 static void | |
314 init_plugin(GaimPlugin *plugin) | |
315 { | |
316 } | |
317 | |
318 GAIM_INIT_PLUGIN(ssl_nss, init_plugin, info) |