Mercurial > pidgin
annotate plugins/ssl/ssl-nss.c @ 10849:c203cd637f95
[gaim-migrate @ 12521]
sf patch #1185449, from Richard Laager
"As the comment in gtkconv.c says, saving a duplicate copy
of the entire conversation is completely bogus. Saving a
copy of a conversation is a UI thing (if the UI is only showing
the last five messages, for example, that's all the user
would expect to be saved). Therefore, there's no problem
having the UI save its own buffer. The GTK+ UI is already
doing this with the imhtml object. This patch removes the
history from GaimConversation and uses the buffer in the
imhtml object when saving a conversation.
It also adds <html>, <head>, <title>, and <body> tags to
the file to make it a bit more valid.
This patch is extremely likely to break plugins because it
changes the size of the GaimConversation struct. As such,
if this is committed, I recommend the developers recompile
non-default plugins. This broke Gaim-Encryption for me,
hence the warning."
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Tue, 19 Apr 2005 04:21:39 +0000 |
parents | bec9130b24d2 |
children | 50224ac8184d |
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" |
9943 | 26 #include "version.h" |
7016 | 27 |
7029
b80c7a4dfae7
[gaim-migrate @ 7592]
Christian Hammond <chipx86@chipx86.com>
parents:
7028
diff
changeset
|
28 #define SSL_NSS_PLUGIN_ID "ssl-nss" |
7016 | 29 |
30 #ifdef HAVE_NSS | |
31 | |
9582
fec83fb0b6a9
[gaim-migrate @ 10425]
Christian Hammond <chipx86@chipx86.com>
parents:
8749
diff
changeset
|
32 #undef HAVE_LONG_LONG /* Make Mozilla less angry. If angry, Mozilla SMASH! */ |
fec83fb0b6a9
[gaim-migrate @ 10425]
Christian Hammond <chipx86@chipx86.com>
parents:
8749
diff
changeset
|
33 |
7016 | 34 #include <nspr.h> |
35 #include <private/pprio.h> | |
36 #include <nss.h> | |
37 #include <pk11func.h> | |
38 #include <prio.h> | |
39 #include <secerr.h> | |
40 #include <secmod.h> | |
41 #include <ssl.h> | |
42 #include <sslerr.h> | |
43 #include <sslproto.h> | |
44 | |
45 typedef struct | |
46 { | |
47 PRFileDesc *fd; | |
48 PRFileDesc *in; | |
49 | |
50 } GaimSslNssData; | |
51 | |
52 #define GAIM_SSL_NSS_DATA(gsc) ((GaimSslNssData *)gsc->private_data) | |
53 | |
54 static const PRIOMethods *_nss_methods = NULL; | |
55 static PRDescIdentity _identity; | |
56 | |
7993
495d3dbb4e84
[gaim-migrate @ 8670]
Christian Hammond <chipx86@chipx86.com>
parents:
7862
diff
changeset
|
57 static void |
7862 | 58 ssl_nss_init_nss(void) |
59 { | |
10519 | 60 char *lib; |
7862 | 61 PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); |
62 NSS_NoDB_Init(NULL); | |
63 | |
64 /* TODO: Fix this so autoconf does the work trying to find this lib. */ | |
65 #ifndef _WIN32 | |
10519 | 66 lib = g_strdup(BR_LIBDIR("/libnssckbi.so")); |
7862 | 67 #else |
10519 | 68 lib = g_strdup("nssckbi.dll"); |
7862 | 69 #endif |
10519 | 70 SECMOD_AddNewModule("Builtins", lib, 0, 0); |
71 g_free(lib); | |
7862 | 72 NSS_SetDomesticPolicy(); |
73 | |
74 _identity = PR_GetUniqueIdentity("Gaim"); | |
75 _nss_methods = PR_GetDefaultIOMethods(); | |
76 } | |
77 | |
7016 | 78 static SECStatus |
79 ssl_auth_cert(void *arg, PRFileDesc *socket, PRBool checksig, | |
80 PRBool is_server) | |
81 { | |
82 return SECSuccess; | |
83 | |
84 #if 0 | |
85 CERTCertificate *cert; | |
86 void *pinArg; | |
87 SECStatus status; | |
88 | |
89 cert = SSL_PeerCertificate(socket); | |
90 pinArg = SSL_RevealPinArg(socket); | |
91 | |
92 status = CERT_VerifyCertNow((CERTCertDBHandle *)arg, cert, checksig, | |
93 certUsageSSLClient, pinArg); | |
94 | |
95 if (status != SECSuccess) { | |
96 gaim_debug_error("nss", "CERT_VerifyCertNow failed\n"); | |
97 CERT_DestroyCertificate(cert); | |
98 return status; | |
99 } | |
100 | |
101 CERT_DestroyCertificate(cert); | |
102 return SECSuccess; | |
103 #endif | |
104 } | |
105 | |
106 static SECStatus | |
107 ssl_bad_cert(void *arg, PRFileDesc *socket) | |
108 { | |
109 SECStatus status = SECFailure; | |
110 PRErrorCode err; | |
111 | |
112 if (arg == NULL) | |
113 return status; | |
114 | |
115 *(PRErrorCode *)arg = err = PORT_GetError(); | |
116 | |
117 switch (err) | |
118 { | |
119 case SEC_ERROR_INVALID_AVA: | |
120 case SEC_ERROR_INVALID_TIME: | |
121 case SEC_ERROR_BAD_SIGNATURE: | |
122 case SEC_ERROR_EXPIRED_CERTIFICATE: | |
123 case SEC_ERROR_UNKNOWN_ISSUER: | |
124 case SEC_ERROR_UNTRUSTED_CERT: | |
125 case SEC_ERROR_CERT_VALID: | |
126 case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: | |
127 case SEC_ERROR_CRL_EXPIRED: | |
128 case SEC_ERROR_CRL_BAD_SIGNATURE: | |
129 case SEC_ERROR_EXTENSION_VALUE_INVALID: | |
130 case SEC_ERROR_CA_CERT_INVALID: | |
131 case SEC_ERROR_CERT_USAGES_INVALID: | |
132 case SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION: | |
133 status = SECSuccess; | |
134 break; | |
135 | |
136 default: | |
137 status = SECFailure; | |
138 break; | |
139 } | |
140 | |
141 gaim_debug_error("nss", "Bad certificate: %d\n"); | |
142 | |
143 return status; | |
144 } | |
145 | |
146 static gboolean | |
147 ssl_nss_init(void) | |
148 { | |
7862 | 149 return TRUE; |
7016 | 150 } |
151 | |
152 static void | |
153 ssl_nss_uninit(void) | |
154 { | |
155 PR_Cleanup(); | |
156 | |
157 _nss_methods = NULL; | |
158 } | |
159 | |
160 static void | |
161 ssl_nss_connect_cb(gpointer data, gint source, GaimInputCondition cond) | |
162 { | |
163 GaimSslConnection *gsc = (GaimSslConnection *)data; | |
164 GaimSslNssData *nss_data = g_new0(GaimSslNssData, 1); | |
165 PRSocketOptionData socket_opt; | |
166 | |
167 gsc->private_data = nss_data; | |
168 | |
169 gsc->fd = source; | |
170 | |
171 nss_data->fd = PR_ImportTCPSocket(gsc->fd); | |
172 | |
173 if (nss_data->fd == NULL) | |
174 { | |
175 gaim_debug_error("nss", "nss_data->fd == NULL!\n"); | |
176 | |
8362 | 177 if (gsc->error_cb != NULL) |
178 gsc->error_cb(gsc, GAIM_SSL_CONNECT_FAILED, gsc->connect_cb_data); | |
179 | |
7016 | 180 gaim_ssl_close((GaimSslConnection *)gsc); |
181 | |
182 return; | |
183 } | |
184 | |
185 socket_opt.option = PR_SockOpt_Nonblocking; | |
186 socket_opt.value.non_blocking = PR_FALSE; | |
187 | |
188 PR_SetSocketOption(nss_data->fd, &socket_opt); | |
189 | |
190 nss_data->in = SSL_ImportFD(NULL, nss_data->fd); | |
191 | |
192 if (nss_data->in == NULL) | |
193 { | |
194 gaim_debug_error("nss", "nss_data->in == NUL!\n"); | |
195 | |
8362 | 196 if (gsc->error_cb != NULL) |
197 gsc->error_cb(gsc, GAIM_SSL_CONNECT_FAILED, gsc->connect_cb_data); | |
198 | |
7016 | 199 gaim_ssl_close((GaimSslConnection *)gsc); |
200 | |
201 return; | |
202 } | |
203 | |
204 SSL_OptionSet(nss_data->in, SSL_SECURITY, PR_TRUE); | |
205 SSL_OptionSet(nss_data->in, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); | |
206 | |
207 SSL_AuthCertificateHook(nss_data->in, | |
208 (SSLAuthCertificate)ssl_auth_cert, | |
209 (void *)CERT_GetDefaultCertDB()); | |
210 SSL_BadCertHook(nss_data->in, (SSLBadCertHandler)ssl_bad_cert, NULL); | |
211 | |
7157 | 212 if(gsc->host) |
213 SSL_SetURL(nss_data->in, gsc->host); | |
7016 | 214 |
215 SSL_ResetHandshake(nss_data->in, PR_FALSE); | |
216 | |
217 if (SSL_ForceHandshake(nss_data->in)) | |
218 { | |
219 gaim_debug_error("nss", "Handshake failed\n"); | |
220 | |
7274
448e39ace278
[gaim-migrate @ 7851]
Christian Hammond <chipx86@chipx86.com>
parents:
7157
diff
changeset
|
221 if (gsc->error_cb != NULL) |
8360 | 222 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
|
223 |
7016 | 224 gaim_ssl_close(gsc); |
225 | |
226 return; | |
227 } | |
228 | |
229 gsc->connect_cb(gsc->connect_cb_data, gsc, cond); | |
230 } | |
231 | |
232 static void | |
233 ssl_nss_close(GaimSslConnection *gsc) | |
234 { | |
235 GaimSslNssData *nss_data = GAIM_SSL_NSS_DATA(gsc); | |
236 | |
7467 | 237 if(!nss_data) |
238 return; | |
239 | |
7016 | 240 if (nss_data->in) PR_Close(nss_data->in); |
241 /* if (nss_data->fd) PR_Close(nss_data->fd); */ | |
242 | |
243 g_free(nss_data); | |
244 } | |
245 | |
246 static size_t | |
247 ssl_nss_read(GaimSslConnection *gsc, void *data, size_t len) | |
248 { | |
249 GaimSslNssData *nss_data = GAIM_SSL_NSS_DATA(gsc); | |
250 | |
251 return PR_Read(nss_data->in, data, len); | |
252 } | |
253 | |
254 static size_t | |
255 ssl_nss_write(GaimSslConnection *gsc, const void *data, size_t len) | |
256 { | |
257 GaimSslNssData *nss_data = GAIM_SSL_NSS_DATA(gsc); | |
258 | |
7467 | 259 if(!nss_data) |
260 return 0; | |
261 | |
7016 | 262 return PR_Write(nss_data->in, data, len); |
263 } | |
264 | |
265 static GaimSslOps ssl_ops = | |
266 { | |
267 ssl_nss_init, | |
268 ssl_nss_uninit, | |
269 ssl_nss_connect_cb, | |
270 ssl_nss_close, | |
271 ssl_nss_read, | |
272 ssl_nss_write | |
273 }; | |
274 | |
275 #endif /* HAVE_NSS */ | |
276 | |
277 | |
278 static gboolean | |
279 plugin_load(GaimPlugin *plugin) | |
280 { | |
281 #ifdef HAVE_NSS | |
7862 | 282 if (!gaim_ssl_get_ops()) { |
283 gaim_ssl_set_ops(&ssl_ops); | |
284 } | |
7016 | 285 |
7862 | 286 /* Init NSS now, so others can use it even if sslconn never does */ |
287 ssl_nss_init_nss(); | |
7016 | 288 return TRUE; |
289 #else | |
290 return FALSE; | |
291 #endif | |
292 } | |
293 | |
294 static gboolean | |
295 plugin_unload(GaimPlugin *plugin) | |
296 { | |
7053 | 297 #ifdef HAVE_NSS |
7862 | 298 if (gaim_ssl_get_ops() == &ssl_ops) { |
299 gaim_ssl_set_ops(NULL); | |
300 } | |
7050
e8cd8827fb25
[gaim-migrate @ 7613]
Christian Hammond <chipx86@chipx86.com>
parents:
7029
diff
changeset
|
301 #endif |
e8cd8827fb25
[gaim-migrate @ 7613]
Christian Hammond <chipx86@chipx86.com>
parents:
7029
diff
changeset
|
302 |
7016 | 303 return TRUE; |
304 } | |
305 | |
306 static GaimPluginInfo info = | |
307 { | |
9943 | 308 GAIM_PLUGIN_MAGIC, |
309 GAIM_MAJOR_VERSION, | |
310 GAIM_MINOR_VERSION, | |
7016 | 311 GAIM_PLUGIN_STANDARD, /**< type */ |
312 NULL, /**< ui_requirement */ | |
313 GAIM_PLUGIN_FLAG_INVISIBLE, /**< flags */ | |
314 NULL, /**< dependencies */ | |
315 GAIM_PRIORITY_DEFAULT, /**< priority */ | |
316 | |
7029
b80c7a4dfae7
[gaim-migrate @ 7592]
Christian Hammond <chipx86@chipx86.com>
parents:
7028
diff
changeset
|
317 SSL_NSS_PLUGIN_ID, /**< id */ |
7016 | 318 N_("NSS"), /**< name */ |
319 VERSION, /**< version */ | |
320 /** summary */ | |
321 N_("Provides SSL support through Mozilla NSS."), | |
322 /** description */ | |
323 N_("Provides SSL support through Mozilla NSS."), | |
324 "Christian Hammond <chipx86@gnupdate.org>", | |
325 GAIM_WEBSITE, /**< homepage */ | |
326 | |
327 plugin_load, /**< load */ | |
328 plugin_unload, /**< unload */ | |
329 NULL, /**< destroy */ | |
330 | |
331 NULL, /**< ui_info */ | |
332 NULL /**< extra_info */ | |
333 }; | |
334 | |
335 static void | |
336 init_plugin(GaimPlugin *plugin) | |
337 { | |
338 } | |
339 | |
340 GAIM_INIT_PLUGIN(ssl_nss, init_plugin, info) |