prompt user if they wish to continue if the server's X.509 certificate can't
be verified. sync_mailbox should consider uid == 0 to be "unknown"
This commit is contained in:
parent
a954aeec96
commit
04fdf7d120
88
imap.c
88
imap.c
|
@ -44,8 +44,65 @@ const char *Flags[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
#if HAVE_LIBSSL
|
#if HAVE_LIBSSL
|
||||||
|
|
||||||
|
#define MAX_DEPTH 1
|
||||||
|
|
||||||
SSL_CTX *SSLContext = 0;
|
SSL_CTX *SSLContext = 0;
|
||||||
|
|
||||||
|
/* this gets called when a certificate is to be verified */
|
||||||
|
static int
|
||||||
|
verify_cert (SSL * ssl)
|
||||||
|
{
|
||||||
|
X509 *cert;
|
||||||
|
int err;
|
||||||
|
char buf[256];
|
||||||
|
int ret = -1;
|
||||||
|
BIO *bio;
|
||||||
|
|
||||||
|
cert = SSL_get_peer_certificate (ssl);
|
||||||
|
if (!cert)
|
||||||
|
{
|
||||||
|
puts ("Error, no server certificate");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = SSL_get_verify_result (ssl);
|
||||||
|
if (err == X509_V_OK)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
printf ("Error, can't verify certificate: %s (%d)\n",
|
||||||
|
X509_verify_cert_error_string (err), err);
|
||||||
|
|
||||||
|
X509_NAME_oneline (X509_get_subject_name (cert), buf, sizeof (buf));
|
||||||
|
printf ("\nSubject: %s\n", buf);
|
||||||
|
X509_NAME_oneline (X509_get_issuer_name (cert), buf, sizeof (buf));
|
||||||
|
printf ("Issuer: %s\n", buf);
|
||||||
|
bio = BIO_new (BIO_s_mem ());
|
||||||
|
ASN1_TIME_print (bio, X509_get_notBefore (cert));
|
||||||
|
memset (buf, 0, sizeof (buf));
|
||||||
|
BIO_read (bio, buf, sizeof (buf) - 1);
|
||||||
|
printf ("Valid from: %s\n", buf);
|
||||||
|
ASN1_TIME_print (bio, X509_get_notAfter (cert));
|
||||||
|
memset (buf, 0, sizeof (buf));
|
||||||
|
BIO_read (bio, buf, sizeof (buf) - 1);
|
||||||
|
BIO_free (bio);
|
||||||
|
printf (" to: %s\n", buf);
|
||||||
|
|
||||||
|
printf
|
||||||
|
("\n*** WARNING *** There is no way to verify this certificate. It is\n"
|
||||||
|
" possible that a hostile attacker has replaced the\n"
|
||||||
|
" server certificate. Continue at your own risk!\n");
|
||||||
|
printf ("\nAccept this certificate anyway? [no]: ");
|
||||||
|
fflush (stdout);
|
||||||
|
if (fgets (buf, sizeof (buf), stdin) && (buf[0] == 'y' || buf[0] == 'Y'))
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
puts ("\n*** Fine, but don't say I didn't warn you!\n");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
init_ssl (config_t * conf)
|
init_ssl (config_t * conf)
|
||||||
{
|
{
|
||||||
|
@ -57,21 +114,29 @@ init_ssl (config_t * conf)
|
||||||
SSL_library_init ();
|
SSL_library_init ();
|
||||||
SSL_load_error_strings ();
|
SSL_load_error_strings ();
|
||||||
SSLContext = SSL_CTX_new (SSLv23_client_method ());
|
SSLContext = SSL_CTX_new (SSLv23_client_method ());
|
||||||
if (!SSL_CTX_load_verify_locations (SSLContext, conf->cert_file, NULL))
|
if (access (conf->cert_file, F_OK))
|
||||||
|
{
|
||||||
|
if (errno != ENOENT)
|
||||||
|
{
|
||||||
|
perror ("access");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
puts
|
||||||
|
("*** Warning, CertificateFile doesn't exist, can't verify server certificates");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (!SSL_CTX_load_verify_locations
|
||||||
|
(SSLContext, conf->cert_file, NULL))
|
||||||
{
|
{
|
||||||
printf ("Error, SSL_CTX_load_verify_locations: %s\n",
|
printf ("Error, SSL_CTX_load_verify_locations: %s\n",
|
||||||
ERR_error_string (ERR_get_error (), 0));
|
ERR_error_string (ERR_get_error (), 0));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
SSL_CTX_set_verify (SSLContext,
|
/* we check the result of the verification after SSL_connect() */
|
||||||
SSL_VERIFY_PEER |
|
SSL_CTX_set_verify (SSLContext, SSL_VERIFY_NONE, 0);
|
||||||
SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
|
|
||||||
SSL_VERIFY_CLIENT_ONCE, NULL);
|
|
||||||
SSL_CTX_set_verify_depth (SSLContext, 1);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif /* HAVE_LIBSSL */
|
||||||
#endif
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
socket_read (Socket_t * sock, char *buf, size_t len)
|
socket_read (Socket_t * sock, char *buf, size_t len)
|
||||||
|
@ -446,6 +511,11 @@ imap_open (config_t * box, unsigned int minuid)
|
||||||
printf ("Error, SSL_connect: %s\n", ERR_error_string (ret, 0));
|
printf ("Error, SSL_connect: %s\n", ERR_error_string (ret, 0));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* verify the server certificate */
|
||||||
|
if (verify_cert (imap->sock->ssl))
|
||||||
|
return 0;
|
||||||
|
|
||||||
imap->sock->use_ssl = 1;
|
imap->sock->use_ssl = 1;
|
||||||
puts ("SSL support enabled");
|
puts ("SSL support enabled");
|
||||||
}
|
}
|
||||||
|
@ -484,7 +554,7 @@ imap_open (config_t * box, unsigned int minuid)
|
||||||
if (imap->count > 0)
|
if (imap->count > 0)
|
||||||
{
|
{
|
||||||
ret = imap_exec (imap, "UID FETCH %d:* (FLAGS RFC822.SIZE)",
|
ret = imap_exec (imap, "UID FETCH %d:* (FLAGS RFC822.SIZE)",
|
||||||
imap->minuid);
|
imap->minuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
sync.c
4
sync.c
|
@ -51,7 +51,7 @@ sync_mailbox (mailbox_t * mbox, imap_t * imap, int flags, unsigned int max_size)
|
||||||
int fd;
|
int fd;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (mbox->uidvalidity != (unsigned int) -1)
|
if (mbox->uidvalidity > 0)
|
||||||
{
|
{
|
||||||
if (mbox->uidvalidity != imap->uidvalidity)
|
if (mbox->uidvalidity != imap->uidvalidity)
|
||||||
{
|
{
|
||||||
|
@ -68,7 +68,7 @@ sync_mailbox (mailbox_t * mbox, imap_t * imap, int flags, unsigned int max_size)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mbox->maxuid == (unsigned int) -1 || imap->maxuid > mbox->maxuid)
|
if (mbox->maxuid == 0 || imap->maxuid > mbox->maxuid)
|
||||||
{
|
{
|
||||||
mbox->maxuid = imap->maxuid;
|
mbox->maxuid = imap->maxuid;
|
||||||
mbox->maxuidchanged = 1;
|
mbox->maxuidchanged = 1;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user