Update gnutls code (require at least 2.2.0).
This commit is contained in:
parent
b00adb9607
commit
4e9e018b22
|
@ -77,7 +77,7 @@ AC_ARG_ENABLE(crypto, AC_HELP_STRING([ --disable-crypto ], [ disable gnutls/gcry
|
||||||
|
|
||||||
GNUTLS_MAN_STATUS="This copy of WMBiff was not compiled with GNUTLS."
|
GNUTLS_MAN_STATUS="This copy of WMBiff was not compiled with GNUTLS."
|
||||||
if test "$gnutls" = "ok"; then
|
if test "$gnutls" = "ok"; then
|
||||||
PKG_CHECK_MODULES([LIBGNUTLS], [gnutls > 1.0.4], [LIBS="$LIBS $LIBGNUTLS_LIBS"
|
PKG_CHECK_MODULES([LIBGNUTLS], [gnutls > 2.2.0], [LIBS="$LIBS $LIBGNUTLS_LIBS"
|
||||||
CFLAGS="$CFLAGS $LIBGNUTLS_CFLAGS"
|
CFLAGS="$CFLAGS $LIBGNUTLS_CFLAGS"
|
||||||
CPPFLAGS="$CPPFLAGS $LIBGNUTLS_CFLAGS"
|
CPPFLAGS="$CPPFLAGS $LIBGNUTLS_CFLAGS"
|
||||||
GNUTLS_COMMON_O="gnutls-common.o"
|
GNUTLS_COMMON_O="gnutls-common.o"
|
||||||
|
|
|
@ -507,16 +507,7 @@ int imap4Create( /*@notnull@ */ Pop3 pc, const char *const str)
|
||||||
/* If 'str' line is badly formatted, wmbiff won't display the mailbox. */
|
/* If 'str' line is badly formatted, wmbiff won't display the mailbox. */
|
||||||
if (strncmp("sslimap:", str, 8) == 0 || strncmp("imaps:", str, 6) == 0) {
|
if (strncmp("sslimap:", str, 8) == 0 || strncmp("imaps:", str, 6) == 0) {
|
||||||
#ifdef HAVE_GNUTLS_GNUTLS_H
|
#ifdef HAVE_GNUTLS_GNUTLS_H
|
||||||
static int haveBeenWarned;
|
|
||||||
PCU.dossl = 1;
|
PCU.dossl = 1;
|
||||||
if (!haveBeenWarned) {
|
|
||||||
printf("wmbiff uses gnutls for TLS/SSL encryption support:\n"
|
|
||||||
" If you distribute software that uses gnutls, don't forget\n"
|
|
||||||
" to warn the users of your software that gnutls is at a\n"
|
|
||||||
" testing phase and may be totally insecure.\n"
|
|
||||||
"\nConsider yourself warned.\n");
|
|
||||||
haveBeenWarned = 1;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
printf("This copy of wmbiff was not compiled with gnutls;\n"
|
printf("This copy of wmbiff was not compiled with gnutls;\n"
|
||||||
"imaps is unavailable. Exiting to protect your\n"
|
"imaps is unavailable. Exiting to protect your\n"
|
||||||
|
|
|
@ -233,16 +233,7 @@ int pop3Create(Pop3 pc, const char *str)
|
||||||
|
|
||||||
if (strncmp("pop3s:", str, 6) == 0) {
|
if (strncmp("pop3s:", str, 6) == 0) {
|
||||||
#ifdef HAVE_GNUTLS_GNUTLS_H
|
#ifdef HAVE_GNUTLS_GNUTLS_H
|
||||||
static int haveBeenWarned;
|
|
||||||
PCU.dossl = 1;
|
PCU.dossl = 1;
|
||||||
if (!haveBeenWarned) {
|
|
||||||
printf("wmbiff uses gnutls for TLS/SSL encryption support:\n"
|
|
||||||
" If you distribute software that uses gnutls, don't forget\n"
|
|
||||||
" to warn the users of your software that gnutls is at a\n"
|
|
||||||
" testing phase and may be totally insecure.\n"
|
|
||||||
"\nConsider yourself warned.\n");
|
|
||||||
haveBeenWarned = 1;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
printf("This copy of wmbiff was not compiled with gnutls;\n"
|
printf("This copy of wmbiff was not compiled with gnutls;\n"
|
||||||
"imaps is unavailable. Exiting to protect your\n"
|
"imaps is unavailable. Exiting to protect your\n"
|
||||||
|
|
|
@ -336,17 +336,20 @@ void print_openpgp_info(gnutls_session session, const char* hostname)
|
||||||
void print_cert_vrfy(gnutls_session session)
|
void print_cert_vrfy(gnutls_session session)
|
||||||
{
|
{
|
||||||
|
|
||||||
int status;
|
unsigned int status;
|
||||||
status = gnutls_certificate_verify_peers(session);
|
int ret;
|
||||||
|
|
||||||
|
ret = gnutls_certificate_verify_peers2(session, &status);
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
if (status == GNUTLS_E_NO_CERTIFICATE_FOUND) {
|
if(ret < 0)
|
||||||
printf("- Peer did not send any certificate.\n");
|
{
|
||||||
return;
|
if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND)
|
||||||
}
|
printf("- Peer did not send any certificate.\n");
|
||||||
if (status < 0) {
|
else
|
||||||
printf("- Could not verify certificate (err: %s)\n",
|
printf("- Could not verify certificate (err: %s (%d))\n",
|
||||||
gnutls_strerror(status));
|
gnutls_strerror(ret), ret);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
int debug_default = 2;
|
int debug_default = 2;
|
||||||
int SkipCertificateCheck = 0;
|
int SkipCertificateCheck = 0;
|
||||||
const char *certificate_filename = NULL;
|
const char *certificate_filename = NULL;
|
||||||
|
const char *tls = "NORMAL";
|
||||||
|
|
||||||
int exists(const char *filename __attribute__ ((unused)))
|
int exists(const char *filename __attribute__ ((unused)))
|
||||||
{
|
{
|
||||||
return (0);
|
return (0);
|
||||||
|
|
|
@ -398,6 +398,7 @@ int print_info(UNUSED(void *state))
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
const char *certificate_filename = NULL;
|
const char *certificate_filename = NULL;
|
||||||
|
const char *tls = "NORMAL";
|
||||||
int SkipCertificateCheck = 0;
|
int SkipCertificateCheck = 0;
|
||||||
int exists(UNUSED(const char *filename))
|
int exists(UNUSED(const char *filename))
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,6 +38,9 @@ extern const char *certificate_filename;
|
||||||
/* if set, don't fail when dealing with a bad certificate.
|
/* if set, don't fail when dealing with a bad certificate.
|
||||||
(continue to whine, though, as bad certs should be fixed) */
|
(continue to whine, though, as bad certs should be fixed) */
|
||||||
extern int SkipCertificateCheck;
|
extern int SkipCertificateCheck;
|
||||||
|
/* gnutls: specify the priorities to use on the ciphers, key exchange methods,
|
||||||
|
macs and compression methods. */
|
||||||
|
extern const char *tls;
|
||||||
|
|
||||||
/* WARNING: implcitly uses scs to gain access to the mailbox
|
/* WARNING: implcitly uses scs to gain access to the mailbox
|
||||||
that holds the per-mailbox debug flag. */
|
that holds the per-mailbox debug flag. */
|
||||||
|
@ -342,6 +345,16 @@ bad_certificate(const struct connection_state *scs, const char *msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
warn_certificate(const struct connection_state *scs, const char *msg)
|
||||||
|
{
|
||||||
|
if (!SkipCertificateCheck) {
|
||||||
|
TDM(DEBUG_ERROR, "%s", msg);
|
||||||
|
TDM(DEBUG_ERROR, "to ignore this warning, run wmbiff "
|
||||||
|
"with the -skip-certificate-check option\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* a start of a hack at verifying certificates. does not
|
/* a start of a hack at verifying certificates. does not
|
||||||
provide any security at all. I'm waiting for either
|
provide any security at all. I'm waiting for either
|
||||||
gnutls to make this as easy as it should be, or someone
|
gnutls to make this as easy as it should be, or someone
|
||||||
|
@ -412,7 +425,8 @@ static void
|
||||||
tls_check_certificate(struct connection_state *scs,
|
tls_check_certificate(struct connection_state *scs,
|
||||||
const char *remote_hostname)
|
const char *remote_hostname)
|
||||||
{
|
{
|
||||||
int certstat;
|
int ret;
|
||||||
|
unsigned int certstat;
|
||||||
const gnutls_datum *cert_list;
|
const gnutls_datum *cert_list;
|
||||||
unsigned int cert_list_size = 0;
|
unsigned int cert_list_size = 0;
|
||||||
gnutls_x509_crt cert;
|
gnutls_x509_crt cert;
|
||||||
|
@ -421,23 +435,35 @@ tls_check_certificate(struct connection_state *scs,
|
||||||
bad_certificate(scs, "Unable to get certificate from peer.\n");
|
bad_certificate(scs, "Unable to get certificate from peer.\n");
|
||||||
return; /* bad_cert will exit if -skip-certificate-check was not given */
|
return; /* bad_cert will exit if -skip-certificate-check was not given */
|
||||||
}
|
}
|
||||||
certstat = gnutls_certificate_verify_peers(scs->tls_state);
|
ret = gnutls_certificate_verify_peers2(scs->tls_state, &certstat);
|
||||||
if (certstat == GNUTLS_E_NO_CERTIFICATE_FOUND) {
|
|
||||||
bad_certificate(scs, "server presented no certificate.\n");
|
if (ret < 0) {
|
||||||
|
char errbuf[1024];
|
||||||
|
|
||||||
|
snprintf(errbuf, 1024, "could not verify certificate: %s (%d).\n",
|
||||||
|
gnutls_strerror(ret), ret);
|
||||||
|
bad_certificate(scs, (ret == GNUTLS_E_NO_CERTIFICATE_FOUND ?
|
||||||
|
"server presented no certificate.\n" :
|
||||||
|
errbuf));
|
||||||
|
return;
|
||||||
#ifdef GNUTLS_CERT_CORRUPTED
|
#ifdef GNUTLS_CERT_CORRUPTED
|
||||||
} else if (certstat & GNUTLS_CERT_CORRUPTED) {
|
} else if (certstat & GNUTLS_CERT_CORRUPTED) {
|
||||||
bad_certificate(scs, "server's certificate is corrupt.\n");
|
bad_certificate(scs, "server's certificate is corrupt.\n");
|
||||||
#endif
|
#endif
|
||||||
} else if (certstat & GNUTLS_CERT_REVOKED) {
|
} else if (certstat & GNUTLS_CERT_REVOKED) {
|
||||||
bad_certificate(scs, "server's certificate has been revoked.\n");
|
bad_certificate(scs, "server's certificate has been revoked.\n");
|
||||||
|
} else if (certstat & GNUTLS_CERT_EXPIRED) {
|
||||||
|
bad_certificate(scs, "server's certificate is expired.\n");
|
||||||
|
} else if (certstat & GNUTLS_CERT_INSECURE_ALGORITHM) {
|
||||||
|
warn_certificate(scs, "server's certificate use an insecure algorithm.\n");
|
||||||
} else if (certstat & GNUTLS_CERT_INVALID) {
|
} else if (certstat & GNUTLS_CERT_INVALID) {
|
||||||
if (gnutls_certificate_type_get(scs->tls_state) == GNUTLS_CRT_X509) {
|
if (gnutls_certificate_type_get(scs->tls_state) == GNUTLS_CRT_X509) {
|
||||||
/* bad_certificate(scs, "server's certificate is not trusted.\n"
|
/* bad_certificate(scs, "server's certificate is not trusted.\n"
|
||||||
"there may be a problem with the certificate stored in your certfile\n"); */
|
"there may be a problem with the certificate stored in your certfile\n"); */
|
||||||
} else {
|
} else {
|
||||||
bad_certificate(scs,
|
bad_certificate(scs,
|
||||||
"server's certificate is invalid or not X.509.\n"
|
"server's certificate is invalid or not X.509.\n"
|
||||||
"there may be a problem with the certificate stored in your certfile\n");
|
"there may be a problem with the certificate stored in your certfile\n");
|
||||||
}
|
}
|
||||||
#if defined(GNUTLS_CERT_SIGNER_NOT_FOUND)
|
#if defined(GNUTLS_CERT_SIGNER_NOT_FOUND)
|
||||||
} else if (certstat & GNUTLS_CERT_SIGNER_NOT_FOUND) {
|
} else if (certstat & GNUTLS_CERT_SIGNER_NOT_FOUND) {
|
||||||
|
@ -456,7 +482,7 @@ tls_check_certificate(struct connection_state *scs,
|
||||||
|
|
||||||
if (gnutls_x509_crt_init(&cert) < 0) {
|
if (gnutls_x509_crt_init(&cert) < 0) {
|
||||||
bad_certificate(scs,
|
bad_certificate(scs,
|
||||||
"Unable to initialize certificate data structure");
|
"Unable to initialize certificate data structure");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -504,7 +530,7 @@ tls_check_certificate(struct connection_state *scs,
|
||||||
if (certificate_filename != NULL &&
|
if (certificate_filename != NULL &&
|
||||||
tls_compare_certificates(&cert_list[0]) == 0) {
|
tls_compare_certificates(&cert_list[0]) == 0) {
|
||||||
bad_certificate(scs,
|
bad_certificate(scs,
|
||||||
"server's certificate was not found in the certificate file.\n");
|
"server's certificate was not found in the certificate file.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
gnutls_x509_crt_deinit(cert);
|
gnutls_x509_crt_deinit(cert);
|
||||||
|
@ -532,25 +558,16 @@ struct connection_state *initialize_gnutls(int sd, char *name, Pop3 pc,
|
||||||
|
|
||||||
assert(gnutls_init(&scs->tls_state, GNUTLS_CLIENT) == 0);
|
assert(gnutls_init(&scs->tls_state, GNUTLS_CLIENT) == 0);
|
||||||
{
|
{
|
||||||
const int protocols[] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
|
const char *err_pos;
|
||||||
const int ciphers[] =
|
if (GNUTLS_E_SUCCESS != gnutls_priority_set_direct(scs->tls_state, tls, &err_pos)) {
|
||||||
{ GNUTLS_CIPHER_RIJNDAEL_128_CBC, GNUTLS_CIPHER_3DES_CBC,
|
DMA(DEBUG_ERROR,
|
||||||
GNUTLS_CIPHER_RIJNDAEL_256_CBC,
|
"Unable to set the priorities to use on the ciphers, "
|
||||||
GNUTLS_CIPHER_ARCFOUR, 0
|
"key exchange methods, macs and/or compression methods.\n"
|
||||||
};
|
"See 'tls' parameter in config file: '%s'.\n",
|
||||||
const int compress[] = { GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL, 0 };
|
err_pos);
|
||||||
const int key_exch[] = { GNUTLS_KX_RSA, GNUTLS_KX_DHE_DSS,
|
exit(1);
|
||||||
GNUTLS_KX_DHE_RSA, 0
|
}
|
||||||
};
|
|
||||||
/* mutt with gnutls doesn't use kx_srp or kx_anon_dh */
|
|
||||||
const int mac[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 };
|
|
||||||
assert(gnutls_protocol_set_priority(scs->tls_state, protocols) ==
|
|
||||||
0);
|
|
||||||
assert(gnutls_cipher_set_priority(scs->tls_state, ciphers) == 0);
|
|
||||||
assert(gnutls_compression_set_priority(scs->tls_state, compress) ==
|
|
||||||
0);
|
|
||||||
assert(gnutls_kx_set_priority(scs->tls_state, key_exch) == 0);
|
|
||||||
assert(gnutls_mac_set_priority(scs->tls_state, mac) == 0);
|
|
||||||
/* no client private key */
|
/* no client private key */
|
||||||
if (gnutls_certificate_allocate_credentials(&scs->xcred) < 0) {
|
if (gnutls_certificate_allocate_credentials(&scs->xcred) < 0) {
|
||||||
DMA(DEBUG_ERROR, "gnutls memory error\n");
|
DMA(DEBUG_ERROR, "gnutls memory error\n");
|
||||||
|
@ -566,9 +583,9 @@ struct connection_state *initialize_gnutls(int sd, char *name, Pop3 pc,
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
zok = gnutls_certificate_set_x509_trust_file(scs->xcred,
|
zok = gnutls_certificate_set_x509_trust_file(scs->xcred,
|
||||||
(char *)
|
(char *)
|
||||||
certificate_filename,
|
certificate_filename,
|
||||||
GNUTLS_X509_FMT_PEM);
|
GNUTLS_X509_FMT_PEM);
|
||||||
if (zok < 0) {
|
if (zok < 0) {
|
||||||
DMA(DEBUG_ERROR,
|
DMA(DEBUG_ERROR,
|
||||||
"GNUTLS did not like your certificate file %s (%d).\n",
|
"GNUTLS did not like your certificate file %s (%d).\n",
|
||||||
|
|
|
@ -69,6 +69,10 @@ static const char *globalnotify = NULL;
|
||||||
static const char *skin_search_path = DEFAULT_SKIN_PATH;
|
static const char *skin_search_path = DEFAULT_SKIN_PATH;
|
||||||
/* for gnutls */
|
/* for gnutls */
|
||||||
const char *certificate_filename = NULL;
|
const char *certificate_filename = NULL;
|
||||||
|
/* gnutls: specify the priorities to use on the ciphers, key exchange methods,
|
||||||
|
macs and compression methods. */
|
||||||
|
const char *tls = NULL;
|
||||||
|
|
||||||
|
|
||||||
/* it could be argued that a better default exists. */
|
/* it could be argued that a better default exists. */
|
||||||
#define DEFAULT_FONT "-*-fixed-*-r-*-*-10-*-*-*-*-*-*-*"
|
#define DEFAULT_FONT "-*-fixed-*-r-*-*-10-*-*-*-*-*-*-*"
|
||||||
|
@ -260,6 +264,9 @@ static int Read_Config_File(char *filename, int *loopinterval)
|
||||||
} else if (!strcmp(setting, "globalnotify")) {
|
} else if (!strcmp(setting, "globalnotify")) {
|
||||||
globalnotify = strdup_ordie(value);
|
globalnotify = strdup_ordie(value);
|
||||||
continue;
|
continue;
|
||||||
|
} else if (!strcmp(setting, "tls")) {
|
||||||
|
tls = strdup_ordie(value);
|
||||||
|
continue;
|
||||||
} else if (mbox_index == -1) {
|
} else if (mbox_index == -1) {
|
||||||
DMA(DEBUG_INFO, "Unknown global setting '%s'\n", setting);
|
DMA(DEBUG_INFO, "Unknown global setting '%s'\n", setting);
|
||||||
continue; /* Didn't read any setting.[0-5] value */
|
continue; /* Didn't read any setting.[0-5] value */
|
||||||
|
@ -375,6 +382,11 @@ static int Read_Config_File(char *filename, int *loopinterval)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(void) fclose(fp);
|
(void) fclose(fp);
|
||||||
|
|
||||||
|
if (!tls)
|
||||||
|
// use GnuTLS's default ciphers.
|
||||||
|
tls = "NORMAL";
|
||||||
|
|
||||||
for (i = 0; i < num_mailboxes; i++)
|
for (i = 0; i < num_mailboxes; i++)
|
||||||
if (mbox[i].label[0] != '\0')
|
if (mbox[i].label[0] != '\0')
|
||||||
parse_mbox_path(i);
|
parse_mbox_path(i);
|
||||||
|
|
|
@ -43,6 +43,45 @@ example, if mutt is your mailreader, you may add:
|
||||||
certfile=/home/<me>/.muttsslcerts
|
certfile=/home/<me>/.muttsslcerts
|
||||||
.RE
|
.RE
|
||||||
.TP
|
.TP
|
||||||
|
\fBtls\fP
|
||||||
|
Specify cipher suite preferences on a TLS session. Can be a
|
||||||
|
predefined value from gnults or a custom value. Default value
|
||||||
|
is: \fINORMAL\fP.
|
||||||
|
|
||||||
|
gnutls predefined values:
|
||||||
|
.SP
|
||||||
|
.RS 8
|
||||||
|
\fIPERFORMANCE\fP (gnutls >= 2.2.0)
|
||||||
|
.RE
|
||||||
|
.RS 8
|
||||||
|
\fINORMAL\fP (gnutls >= 2.2.0)
|
||||||
|
.RE
|
||||||
|
.RS 8
|
||||||
|
\fISECURE128\fP (gnutls >= 2.2.0)
|
||||||
|
.RE
|
||||||
|
.RS 8
|
||||||
|
\fISECURE192\fP (gnutls >= 3.0.0)
|
||||||
|
.RE
|
||||||
|
.RS 8
|
||||||
|
\fISECURE256\fP (gnutls >= 2.2.0)
|
||||||
|
.RE
|
||||||
|
.RS 8
|
||||||
|
\fISUITEB128\fP (gnutls >= 3.0.0)
|
||||||
|
.RE
|
||||||
|
.RS 8
|
||||||
|
\fISUITEB192\fP (gnutls >= 3.0.0)
|
||||||
|
.RE
|
||||||
|
.RS 8
|
||||||
|
\fIEXPORT\fP (gnutls >= 2.2.0)
|
||||||
|
.RE
|
||||||
|
.RS 8
|
||||||
|
\fINONE\fP (gnutls >= 2.2.0)
|
||||||
|
.RE
|
||||||
|
.RS
|
||||||
|
.TP
|
||||||
|
See \fBhttp://gnutls.org/manual/gnutls.html#Priority-Strings\fR for more details.
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
\fBinterval\fP
|
\fBinterval\fP
|
||||||
Global interval between mailbox checking. Value is the number of seconds, 5
|
Global interval between mailbox checking. Value is the number of seconds, 5
|
||||||
is the default.
|
is the default.
|
||||||
|
|
Loading…
Reference in a new issue