Mercurial > pidgin
annotate src/ssl-nss.c @ 6764:6d0d4e9149b9
[gaim-migrate @ 7296]
well, jabber.org is being a pain in the moment, as is my server. but this seems to work, so here it is. Jabber SSL support. Make sure you set the port to 5223 and check the "Use SSL" checkbox in the account editor.
committer: Tailor Script <tailor@pidgin.im>
| author | Nathan Walp <nwalp@pidgin.im> |
|---|---|
| date | Sat, 06 Sep 2003 16:04:41 +0000 |
| parents | f9efcba2d02f |
| children | efef00de3f09 |
| rev | line source |
|---|---|
| 6738 | 1 /** |
| 2 * @file ssl-nss.c SSL Operations for Mozilla NSS | |
| 3 * @ingroup core | |
| 4 * | |
| 5 * gaim | |
| 6 * | |
| 7 * Copyright (C) 2003 Christian Hammond <chipx86@gnupdate.org> | |
| 8 * | |
| 9 * This program is free software; you can redistribute it and/or modify | |
| 10 * it under the terms of the GNU General Public License as published by | |
| 11 * the Free Software Foundation; either version 2 of the License, or | |
| 12 * (at your option) any later version. | |
| 13 * | |
| 14 * This program is distributed in the hope that it will be useful, | |
| 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 17 * GNU General Public License for more details. | |
| 18 * | |
| 19 * You should have received a copy of the GNU General Public License | |
| 20 * along with this program; if not, write to the Free Software | |
| 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 22 */ | |
|
6747
82348b5ab87e
[gaim-migrate @ 7279]
Christian Hammond <chipx86@chipx86.com>
parents:
6738
diff
changeset
|
23 #include "internal.h" |
|
82348b5ab87e
[gaim-migrate @ 7279]
Christian Hammond <chipx86@chipx86.com>
parents:
6738
diff
changeset
|
24 |
|
82348b5ab87e
[gaim-migrate @ 7279]
Christian Hammond <chipx86@chipx86.com>
parents:
6738
diff
changeset
|
25 #ifdef HAVE_NSS |
|
82348b5ab87e
[gaim-migrate @ 7279]
Christian Hammond <chipx86@chipx86.com>
parents:
6738
diff
changeset
|
26 |
| 6738 | 27 #include "debug.h" |
| 28 #include "sslconn.h" | |
| 29 | |
| 30 #include <nspr.h> | |
| 31 #include <nss.h> | |
| 32 #include <pk11func.h> | |
| 33 #include <prio.h> | |
| 34 #include <secerr.h> | |
| 35 #include <secmod.h> | |
| 36 #include <ssl.h> | |
| 37 #include <sslerr.h> | |
| 38 #include <sslproto.h> | |
| 39 | |
| 40 typedef struct | |
| 41 { | |
| 42 PRFileDesc *fd; | |
| 43 PRFileDesc *in; | |
| 44 | |
| 45 } GaimSslNssData; | |
| 46 | |
| 47 #define GAIM_SSL_NSS_DATA(gsc) ((GaimSslNssData *)gsc->private_data) | |
| 48 | |
| 49 static const PRIOMethods *_nss_methods = NULL; | |
| 50 static PRDescIdentity _identity; | |
| 51 | |
| 52 static SECStatus | |
| 53 ssl_auth_cert(void *arg, PRFileDesc *socket, PRBool checksig, | |
| 54 PRBool is_server) | |
| 55 { | |
| 56 return SECSuccess; | |
| 57 | |
| 58 #if 0 | |
| 59 CERTCertificate *cert; | |
| 60 void *pinArg; | |
| 61 SECStatus status; | |
| 62 | |
| 63 cert = SSL_PeerCertificate(socket); | |
| 64 pinArg = SSL_RevealPinArg(socket); | |
| 65 | |
| 66 status = CERT_VerifyCertNow((CERTCertDBHandle *)arg, cert, checksig, | |
| 67 certUsageSSLClient, pinArg); | |
| 68 | |
| 69 if (status != SECSuccess) { | |
| 70 gaim_debug_error("nss", "CERT_VerifyCertNow failed\n"); | |
| 71 CERT_DestroyCertificate(cert); | |
| 72 return status; | |
| 73 } | |
| 74 | |
| 75 CERT_DestroyCertificate(cert); | |
| 76 return SECSuccess; | |
| 77 #endif | |
| 78 } | |
| 79 | |
| 80 SECStatus | |
| 81 ssl_bad_cert(void *arg, PRFileDesc *socket) | |
| 82 { | |
| 83 SECStatus status = SECFailure; | |
| 84 PRErrorCode err; | |
| 85 | |
| 86 if (arg == NULL) | |
| 87 return status; | |
| 88 | |
| 89 *(PRErrorCode *)arg = err = PORT_GetError(); | |
| 90 | |
| 91 switch (err) | |
| 92 { | |
| 93 case SEC_ERROR_INVALID_AVA: | |
| 94 case SEC_ERROR_INVALID_TIME: | |
| 95 case SEC_ERROR_BAD_SIGNATURE: | |
| 96 case SEC_ERROR_EXPIRED_CERTIFICATE: | |
| 97 case SEC_ERROR_UNKNOWN_ISSUER: | |
| 98 case SEC_ERROR_UNTRUSTED_CERT: | |
| 99 case SEC_ERROR_CERT_VALID: | |
| 100 case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: | |
| 101 case SEC_ERROR_CRL_EXPIRED: | |
| 102 case SEC_ERROR_CRL_BAD_SIGNATURE: | |
| 103 case SEC_ERROR_EXTENSION_VALUE_INVALID: | |
| 104 case SEC_ERROR_CA_CERT_INVALID: | |
| 105 case SEC_ERROR_CERT_USAGES_INVALID: | |
| 106 case SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION: | |
| 107 status = SECSuccess; | |
| 108 break; | |
| 109 | |
| 110 default: | |
| 111 status = SECFailure; | |
| 112 break; | |
| 113 } | |
| 114 | |
| 115 gaim_debug_error("nss", "Bad certificate: %d\n"); | |
| 116 | |
| 117 return status; | |
| 118 } | |
| 119 | |
| 120 static gboolean | |
| 121 ssl_nss_init(void) | |
| 122 { | |
| 123 PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); | |
| 124 NSS_NoDB_Init(NULL); | |
| 125 | |
| 126 /* TODO: Fix this so autoconf does the work trying to find this lib. */ | |
| 127 SECMOD_AddNewModule("Builtins", LIBDIR "/libnssckbi.so", 0, 0); | |
| 128 NSS_SetDomesticPolicy(); | |
| 129 | |
| 130 _identity = PR_GetUniqueIdentity("Gaim"); | |
| 131 _nss_methods = PR_GetDefaultIOMethods(); | |
| 132 | |
| 133 return TRUE; | |
| 134 } | |
| 135 | |
| 136 static void | |
| 137 ssl_nss_uninit(void) | |
| 138 { | |
| 139 PR_Cleanup(); | |
| 140 | |
| 141 _nss_methods = NULL; | |
| 142 } | |
| 143 | |
| 144 static void | |
| 145 ssl_nss_connect_cb(gpointer data, gint source, GaimInputCondition cond) | |
| 146 { | |
| 147 GaimSslConnection *gsc = (GaimSslConnection *)data; | |
| 148 GaimSslNssData *nss_data = g_new0(GaimSslNssData, 1); | |
| 149 PRSocketOptionData socket_opt; | |
| 150 | |
| 151 gsc->private_data = nss_data; | |
| 152 | |
| 153 gsc->fd = source; | |
| 154 | |
| 155 nss_data->fd = PR_ImportTCPSocket(gsc->fd); | |
| 156 | |
| 157 if (nss_data->fd == NULL) | |
| 158 { | |
| 159 gaim_debug_error("nss", "nss_data->fd == NULL!\n"); | |
| 160 | |
| 161 gaim_ssl_close((GaimSslConnection *)gsc); | |
| 162 | |
| 163 return; | |
| 164 } | |
| 165 | |
| 166 socket_opt.option = PR_SockOpt_Nonblocking; | |
| 167 socket_opt.value.non_blocking = PR_FALSE; | |
| 168 | |
| 169 PR_SetSocketOption(nss_data->fd, &socket_opt); | |
| 170 | |
| 171 nss_data->in = SSL_ImportFD(NULL, nss_data->fd); | |
| 172 | |
| 173 if (nss_data->in == NULL) | |
| 174 { | |
| 175 gaim_debug_error("nss", "nss_data->in == NUL!\n"); | |
| 176 | |
| 177 gaim_ssl_close((GaimSslConnection *)gsc); | |
| 178 | |
| 179 return; | |
| 180 } | |
| 181 | |
| 182 SSL_OptionSet(nss_data->in, SSL_SECURITY, PR_TRUE); | |
| 183 SSL_OptionSet(nss_data->in, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); | |
| 184 | |
| 185 SSL_AuthCertificateHook(nss_data->in, | |
| 186 (SSLAuthCertificate)ssl_auth_cert, | |
| 187 (void *)CERT_GetDefaultCertDB()); | |
| 188 SSL_BadCertHook(nss_data->in, (SSLBadCertHandler)ssl_bad_cert, NULL); | |
| 189 | |
| 190 SSL_SetURL(nss_data->in, gsc->host); | |
| 191 | |
| 192 SSL_ResetHandshake(nss_data->in, PR_FALSE); | |
| 193 | |
| 194 if (SSL_ForceHandshake(nss_data->in)) | |
| 195 { | |
| 196 gaim_debug_error("nss", "Handshake failed\n"); | |
| 197 | |
|
6759
f9efcba2d02f
[gaim-migrate @ 7291]
Christian Hammond <chipx86@chipx86.com>
parents:
6747
diff
changeset
|
198 gaim_ssl_close(gsc); |
| 6738 | 199 |
| 200 return; | |
| 201 } | |
| 202 | |
| 6764 | 203 gsc->connect_cb(gsc->connect_cb_data, gsc, cond); |
| 204 } | |
| 205 | |
| 206 static void | |
| 207 ssl_nss_recv_cb(gpointer data, gint source, GaimInputCondition cond) | |
| 208 { | |
| 209 GaimSslConnection *gsc = data; | |
| 210 gsc->recv_cb(gsc->recv_cb_data, gsc, cond); | |
| 6738 | 211 } |
| 212 | |
| 213 static void | |
| 214 ssl_nss_close(GaimSslConnection *gsc) | |
| 215 { | |
| 216 GaimSslNssData *nss_data = GAIM_SSL_NSS_DATA(gsc); | |
| 217 | |
| 218 if (nss_data->in) PR_Close(nss_data->in); | |
| 219 if (nss_data->fd) PR_Close(nss_data->fd); | |
| 220 | |
| 221 g_free(nss_data); | |
| 222 } | |
| 223 | |
| 224 static size_t | |
| 225 ssl_nss_read(GaimSslConnection *gsc, void *data, size_t len) | |
| 226 { | |
| 227 GaimSslNssData *nss_data = GAIM_SSL_NSS_DATA(gsc); | |
| 228 | |
| 229 return PR_Read(nss_data->in, data, len); | |
| 230 } | |
| 231 | |
| 232 static size_t | |
| 233 ssl_nss_write(GaimSslConnection *gsc, const void *data, size_t len) | |
| 234 { | |
| 235 GaimSslNssData *nss_data = GAIM_SSL_NSS_DATA(gsc); | |
| 236 | |
| 237 return PR_Write(nss_data->in, data, len); | |
| 238 } | |
| 239 | |
| 240 static GaimSslOps ssl_ops = | |
| 241 { | |
| 242 ssl_nss_init, | |
| 243 ssl_nss_uninit, | |
| 244 ssl_nss_connect_cb, | |
| 6764 | 245 ssl_nss_recv_cb, |
| 6738 | 246 ssl_nss_close, |
| 247 ssl_nss_read, | |
| 248 ssl_nss_write | |
| 249 }; | |
| 250 | |
| 251 GaimSslOps * | |
| 252 gaim_ssl_nss_get_ops() | |
| 253 { | |
| 254 return &ssl_ops; | |
| 255 } | |
|
6747
82348b5ab87e
[gaim-migrate @ 7279]
Christian Hammond <chipx86@chipx86.com>
parents:
6738
diff
changeset
|
256 |
|
82348b5ab87e
[gaim-migrate @ 7279]
Christian Hammond <chipx86@chipx86.com>
parents:
6738
diff
changeset
|
257 #endif /* HAVE_NSS */ |
