-/* Copyright (C) 2000 Michael R. Elkins <me@mutt.org>
+/*
+ * Copyright notice from original mutt:
+ * Copyright (C) 2000 Michael R. Elkins <me@mutt.org>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ * This file is part of mutt-ng, see http://www.muttng.org/.
+ * It's licensed under the GNU General Public License,
+ * please see the file GPL in the top level source directory.
*/
#if HAVE_CONFIG_H
#include "mutt_socket.h"
#include "mutt_curses.h"
+#include "lib/mem.h"
+#include "lib/intl.h"
+
static int MuttNssInitialized = 0;
/* internal data struct we use with the CONNECTION. this is where NSS-specific
* data gets stuffed so that the main mutt_socket.h doesn't have to be
* modified.
*/
-typedef struct
-{
+typedef struct {
PRFileDesc *fd;
CERTCertDBHandle *db;
-}
-mutt_nss_t;
+} mutt_nss_t;
/* nss callback to grab the user's password. */
-static char *
-mutt_nss_password_func (PK11SlotInfo * slot, PRBool retry, void *arg)
+static char *mutt_nss_password_func (PK11SlotInfo * slot, PRBool retry,
+ void *arg)
{
return NULL;
}
-static int
-mutt_nss_error (const char *call)
+static int mutt_nss_error (const char *call)
{
mutt_error (_("%s failed (error %d)"), call, PR_GetError ());
return -1;
/* initialize the NSS library for use. must be called prior to any other
* functions in this module.
*/
-static int
-mutt_nss_init (void)
+static int mutt_nss_init (void)
{
- if (!MuttNssInitialized)
- {
+ if (!MuttNssInitialized) {
PK11_SetPasswordFunc (mutt_nss_password_func);
if (NSS_Init (SslCertFile) == SECFailure)
return mutt_nss_error ("NSS_Init");
-
+
/* always use strong crypto. */
if (NSS_SetDomesticPolicy () == SECFailure)
return mutt_nss_error ("NSS_SetDomesticPolicy");
-
+
/* intialize the session cache */
SSL_ClearSessionCache ();
-
+
MuttNssInitialized = 1;
}
return 0;
}
/* convert from int64 to a readable string and print on the screen */
-static void
-mutt_nss_pretty_time (int64 usecs)
+static void mutt_nss_pretty_time (int64 usecs)
{
struct tm t;
PRExplodedTime ex;
char timebuf[128];
-
+
PR_ExplodeTime (usecs, PR_LocalTimeParameters, &ex);
-
+
t.tm_sec = ex.tm_sec;
t.tm_min = ex.tm_min;
t.tm_hour = ex.tm_hour;
t.tm_mday = ex.tm_mday;
t.tm_mon = ex.tm_month;
- t.tm_year = ex.tm_year - 1900; /* PRExplodedTime uses the absolute year */
+ t.tm_year = ex.tm_year - 1900; /* PRExplodedTime uses the absolute year */
t.tm_wday = ex.tm_wday;
t.tm_yday = ex.tm_yday;
-
+
strfcpy (timebuf, asctime (&t), sizeof (timebuf));
- timebuf[strlen (timebuf) - 1] = 0;
-
+ timebuf[safe_strlen (timebuf) - 1] = 0;
+
addstr (timebuf);
}
* database. we are given the option to override the decision and accept
* it anyway.
*/
-static SECStatus
-mutt_nss_bad_cert (void *arg, PRFileDesc * fd)
+static SECStatus mutt_nss_bad_cert (void *arg, PRFileDesc * fd)
{
PRErrorCode err;
CERTCertificate *cert, *issuer;
/* calculate the MD5 hash of the raw certificate */
HASH_HashBuf (HASH_AlgMD5, hash, cert->derCert.data, cert->derCert.len);
- for (i = 0; i < 16; i++)
- {
+ for (i = 0; i < 16; i++) {
printw ("%0x", hash[i]);
if (i != 15)
addch (':');
}
-
+
mvaddstr (LINES - 3, 0, "Signature: ");
clrtoeol ();
else
status[sizeof (status) - 1] = 0;
memcpy (status, "--- SSL Certificate Check",
- sizeof ("--- SSL Certificate Check") - 1);
+ sizeof ("--- SSL Certificate Check") - 1);
addstr (status);
clrtoeol ();
SETCOLOR (MT_COLOR_NORMAL);
- for (;;)
- {
+ for (;;) {
mvaddstr (LINES - 1, 0, "(r)eject, accept (o)nce, (a)lways accept?");
clrtoeol ();
ch = mutt_getch ();
- if (ch.ch == -1)
- {
+ if (ch.ch == -1) {
i = SECFailure;
break;
}
- else if (ascii_tolower (ch.ch) == 'r')
- {
+ else if (ascii_tolower (ch.ch) == 'r') {
i = SECFailure;
break;
}
- else if (ascii_tolower (ch.ch) == 'o')
- {
+ else if (ascii_tolower (ch.ch) == 'o') {
i = SECSuccess;
break;
}
- else if (ascii_tolower (ch.ch) == 'a')
- {
+ else if (ascii_tolower (ch.ch) == 'a') {
/* push this certificate onto the user's certificate store so it
* automatically becomes valid next time we see it
*/
-
+
/* set this certificate as a valid peer for SSL-auth ONLY. */
CERT_DecodeTrustString (&trust, "P,,");
-
+
CERT_AddTempCertToPerm (cert, NULL, &trust);
i = SECSuccess;
break;
}
BEEP ();
}
-
+
/* SSL_PeerCertificate() returns a copy with an updated ref count, so
* we have to destroy our copy here.
*/
CERT_DestroyCertificate (cert);
-
+
return i;
}
-static int
-mutt_nss_socket_open (CONNECTION * con)
+static int mutt_nss_socket_open (CONNECTION * con)
{
mutt_nss_t *sockdata;
PRNetAddr addr;
addr.inet.family = AF_INET;
addr.inet.port = PR_htons (con->account.port);
he = gethostbyname (con->account.host);
- if (!he)
- {
+ if (!he) {
mutt_error (_("Unable to find ip for host %s"), con->account.host);
return -1;
}
sockdata = safe_calloc (1, sizeof (mutt_nss_t));
- do
- {
+ do {
sockdata->fd = PR_NewTCPSocket ();
- if (sockdata->fd == NULL)
- {
+ if (sockdata->fd == NULL) {
mutt_error (_("PR_NewTCPSocket failed."));
break;
}
/* make this a SSL socket */
sockdata->fd = SSL_ImportFD (NULL, sockdata->fd);
-
+
/* set SSL version options based upon user's preferences */
if (!option (OPTTLSV1))
SSL_OptionSet (sockdata->fd, SSL_ENABLE_TLS, PR_FALSE);
-
+
if (!option (OPTSSLV2))
SSL_OptionSet (sockdata->fd, SSL_ENABLE_SSL2, PR_FALSE);
if (!option (OPTSSLV3))
SSL_OptionSet (sockdata->fd, SSL_ENABLE_SSL3, PR_FALSE);
-
+
/* set the host we were attempting to connect to in order to verify
* the name in the certificate we get back.
*/
- if (SSL_SetURL (sockdata->fd, con->account.host))
- {
+ if (SSL_SetURL (sockdata->fd, con->account.host)) {
mutt_nss_error ("SSL_SetURL");
break;
}
* via SSL.
*/
SSL_SetPKCS11PinArg (sockdata->fd, 0);
-
+
sockdata->db = CERT_GetDefaultCertDB ();
-
+
/* use the default supplied hook. it takes an argument to our
* certificate database. the manual lies, you can't really specify
* NULL for the callback to get the default!
*/
- SSL_AuthCertificateHook (sockdata->fd, SSL_AuthCertificate,
- sockdata->db);
+ SSL_AuthCertificateHook (sockdata->fd, SSL_AuthCertificate, sockdata->db);
/* set the callback to be used when SSL_AuthCertificate() fails. this
* allows us to override and insert the cert back into the db
*/
SSL_BadCertHook (sockdata->fd, mutt_nss_bad_cert, sockdata->db);
-
+
if (PR_Connect (sockdata->fd, &addr, PR_INTERVAL_NO_TIMEOUT) ==
- PR_FAILURE)
- {
+ PR_FAILURE) {
mutt_error (_("Unable to connect to host %s"), con->account.host);
break;
}
-
+
/* store the extra info in the CONNECTION struct for later use. */
con->sockdata = sockdata;
-
+
/* HACK. some of the higher level calls in mutt_socket.c depend on this
* being >0 when we are in the connected state. we just set this to
* an arbitrary value to avoid hitting that bug, since we neve have the
* real fd.
*/
con->fd = 42;
-
+
/* success */
return 0;
}
while (0);
-
+
/* we get here when we had an oops. clean up the mess. */
- if (sockdata)
- {
+ if (sockdata) {
if (sockdata->fd)
PR_Close (sockdata->fd);
if (sockdata->db)
return -1;
}
-static int
-mutt_nss_socket_close (CONNECTION * con)
+static int mutt_nss_socket_close (CONNECTION * con)
{
mutt_nss_t *sockdata = (mutt_nss_t *) con->sockdata;
return 0;
}
-static int
-mutt_nss_socket_read (CONNECTION* conn, char* buf, size_t len)
+static int mutt_nss_socket_read (CONNECTION * conn, char *buf, size_t len)
{
- return PR_Read (((mutt_nss_t*) conn->sockdata)->fd, buf, len);
+ return PR_Read (((mutt_nss_t *) conn->sockdata)->fd, buf, len);
}
static int
}
/* initialize a new connection for use with NSS */
-int
-mutt_nss_socket_setup (CONNECTION * con)
+int mutt_nss_socket_setup (CONNECTION * con)
{
if (mutt_nss_init ())
return -1;
- con->open = mutt_nss_socket_open;
- con->read = mutt_nss_socket_read;
- con->write = mutt_nss_socket_write;
- con->close = mutt_nss_socket_close;
+ con->conn_open = mutt_nss_socket_open;
+ con->conn_read = mutt_nss_socket_read;
+ con->conn_write = mutt_nss_socket_write;
+ con->conn_close = mutt_nss_socket_close;
return 0;
}