aboutsummaryrefslogtreecommitdiffstats
path: root/camel/camel-tcp-stream-ssl.c
diff options
context:
space:
mode:
authorJeffrey Stedfast <fejj@ximian.com>2001-03-16 12:41:49 +0800
committerJeffrey Stedfast <fejj@src.gnome.org>2001-03-16 12:41:49 +0800
commit403205b15e9f14472711ee115cae17031eb4ce7b (patch)
tree85d123987b81da533ac065d2cc0683cb03cec6d8 /camel/camel-tcp-stream-ssl.c
parent323a1f08cc0bdff8bba6ec1631f6e7111296093e (diff)
downloadgsoc2013-evolution-403205b15e9f14472711ee115cae17031eb4ce7b.tar
gsoc2013-evolution-403205b15e9f14472711ee115cae17031eb4ce7b.tar.gz
gsoc2013-evolution-403205b15e9f14472711ee115cae17031eb4ce7b.tar.bz2
gsoc2013-evolution-403205b15e9f14472711ee115cae17031eb4ce7b.tar.lz
gsoc2013-evolution-403205b15e9f14472711ee115cae17031eb4ce7b.tar.xz
gsoc2013-evolution-403205b15e9f14472711ee115cae17031eb4ce7b.tar.zst
gsoc2013-evolution-403205b15e9f14472711ee115cae17031eb4ce7b.zip
Don't use the hardcoded cert db directory, use the one passed in.
2001-03-15 Jeffrey Stedfast <fejj@ximian.com> * camel.c (camel_init): Don't use the hardcoded cert db directory, use the one passed in. * camel-tcp-stream-ssl.c (ssl_get_client_auth): Wrote the default implementation. Not that we'll use this though, since this is the default implementation provided by NSS anyway. This more or less serves as a reference in case we want to change anything. (ssl_auth_cert): Same. (ssl_bad_cert): Changed the prompt string and free it when we're done. svn path=/trunk/; revision=8753
Diffstat (limited to 'camel/camel-tcp-stream-ssl.c')
-rw-r--r--camel/camel-tcp-stream-ssl.c133
1 files changed, 120 insertions, 13 deletions
diff --git a/camel/camel-tcp-stream-ssl.c b/camel/camel-tcp-stream-ssl.c
index 243c68403b..332234291c 100644
--- a/camel/camel-tcp-stream-ssl.c
+++ b/camel/camel-tcp-stream-ssl.c
@@ -53,10 +53,6 @@ static int stream_connect (CamelTcpStream *stream, struct hostent *host, int
static int stream_getsockopt (CamelTcpStream *stream, CamelSockOptData *data);
static int stream_setsockopt (CamelTcpStream *stream, const CamelSockOptData *data);
-/* callbacks */
-static SECStatus ssl_bad_cert (void *data, PRFileDesc *fd);
-static SECStatus ssl_auth_cert (void *data, PRFileDesc *fd, PRBool checksig, PRBool is_server);
-
static void
camel_tcp_stream_ssl_class_init (CamelTcpStreamSSLClass *camel_tcp_stream_ssl_class)
@@ -210,36 +206,146 @@ stream_close (CamelStream *stream)
return 0;
}
+#if 0
+/* Since this is default implementation, let NSS handle it. */
+static SECStatus
+ssl_get_client_auth (void *data, PRFileDesc *sockfd,
+ struct CERTDistNamesStr *caNames,
+ struct CERTCertificateStr **pRetCert,
+ struct SECKEYPrivateKeyStr **pRetKey)
+{
+ SECStatus status = SECFailure;
+ SECKEYPrivateKey *privkey;
+ CERTCertificate *cert;
+ void *proto_win;
+
+ proto_win = SSL_RevealPinArg (sockfd);
+
+ if ((char *)data) {
+ cert = PK11_FindCertFromNickname ((char *)data, proto_win);
+ if (cert) {
+ privKey = PK11_FindKeyByAnyCert (cert, proto_win);
+ if (privkey) {
+ status = SECSuccess;
+ } else {
+ CERT_DestroyCertificate (cert);
+ }
+ }
+ } else {
+ /* no nickname given, automatically find the right cert */
+ CERTCertNicknames *names;
+ int i;
+
+ names = CERT_GetCertNicknames (CERT_GetDefaultCertDB (),
+ SEC_CERT_NICKNAMES_USER,
+ proto_win);
+
+ if (names != NULL) {
+ for (i = 0; i < names->numnicknames; i++) {
+
+ cert = PK11_FindCertFromNickname (names->nicknames[i],
+ proto_win);
+ if (!cert)
+ continue;
+
+ /* Only check unexpired certs */
+ if (CERT_CheckCertValidTimes (cert, PR_Now (), PR_FALSE) != secCertTimeValid) {
+ CERT_DestroyCertificate (cert);
+ continue;
+ }
+
+ status = NSS_CmpCertChainWCANames (cert, caNames);
+ if (status == SECSuccess) {
+ privkey = PK11_FindKeyByAnyCert (cert, proto_win);
+ if (privkey)
+ break;
+
+ status = SECFailure;
+ break;
+ }
+
+ CERT_FreeNicknames (names);
+ }
+ }
+ }
+
+ if (status == SECSuccess) {
+ *pRetCert = cert;
+ *pRetKey = privkey;
+ }
+
+ return status;
+}
+#endif
+#if 0
+/* Since this is the default NSS implementation, no need for us to use this. */
static SECStatus
-ssl_auth_cert (void *data, PRFileDesc *fd, PRBool checksig, PRBool is_server)
+ssl_auth_cert (void *data, PRFileDesc *sockfd, PRBool checksig, PRBool is_server)
{
- return SSL_AuthCertificate (NULL, fd, TRUE, FALSE);
+ CERTCertificate *cert;
+ SECStatus status;
+ void *pinarg;
+ char *host;
+
+ cert = SSL_PeerCertificate (sockfd);
+ pinarg = SSL_RevealPinArg (sockfd);
+ status = CERT_VerifyCertNow ((CERTCertDBHandle *)data, cert,
+ checksig, certUsageSSLClient, pinarg);
+
+ if (status != SECSuccess)
+ return SECFailure;
+
+ /* Certificate is OK. Since this is the client side of an SSL
+ * connection, we need to verify that the name field in the cert
+ * matches the desired hostname. This is our defense against
+ * man-in-the-middle attacks.
+ */
+
+ /* SSL_RevealURL returns a hostname, not a URL. */
+ host = SSL_RevealURL (sockfd);
+
+ if (host && *host) {
+ status = CERT_VerifyCertName (cert, host);
+ } else {
+ PR_SetError (SSL_ERROR_BAD_CERT_DOMAIN, 0);
+ status = SECFailure;
+ }
+
+ if (host)
+ PR_Free (hostName);
+
+ return secStatus;
}
+#endif
static SECStatus
-ssl_bad_cert (void *data, PRFileDesc *fd)
+ssl_bad_cert (void *data, PRFileDesc *sockfd)
{
CamelService *service;
- char *string, *err;
+ char *prompt, *err;
gpointer accept;
- PRInt32 len;
+ PRUint32 len;
g_return_val_if_fail (data != NULL, SECFailure);
g_return_val_if_fail (CAMEL_IS_SERVICE (data), SECFailure);
service = CAMEL_SERVICE (data);
- /* FIXME: International issues here?? */
len = PR_GetErrorTextLength ();
err = g_malloc0 (len + 1);
PR_GetErrorText (err);
- string = g_strdup_printf (_("Do you wish to accept this certificate from %s?\n\n%s"),
+ /* construct our user prompt */
+ prompt = g_strdup_printf (_("Bad certificate from %s:%s\n\nDo you wish to accept anyway?"),
service->url->host, err);
+ g_free (err);
+ /* query the user to find out if we want to accept this certificate */
accept = camel_session_query_authenticator (service->session, CAMEL_AUTHENTICATOR_ACCEPT,
- string, FALSE, service, NULL, NULL);
+ prompt, FALSE, service, NULL, NULL);
+
+ g_free (prompt);
if (GPOINTER_TO_INT (accept))
return SECSuccess;
@@ -275,7 +381,8 @@ stream_connect (CamelTcpStream *stream, struct hostent *host, int port)
return -1;
}
- /*SSL_AuthCertificateHook (ssl_fd, ssl_auth_cert, NULL);*/
+ /*SSL_GetClientAuthDataHook (sslSocket, ssl_get_client_auth, (void *)certNickname);*/
+ /*SSL_AuthCertificateHook (ssl_fd, ssl_auth_cert, (void *) CERT_GetDefaultCertDB ());*/
SSL_BadCertHook (ssl_fd, ssl_bad_cert, ssl->service);
ssl->sockfd = ssl_fd;