forked from PsychoticNinja/irssi
Implement experimental DNSSEC DANE support
This patch adds experimental support for the DNSSEC DANE verification protocol using the libval library from the DNSSEC-Tools package. Thanks to Thomas Steen Ramussen for creating a test setup and suggesting the idea of experimenting with DANE support in Irssi :-) git-svn-id: file:///var/www/svn.irssi.org/SVN/irssi/trunk@5218 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
parent
02aa2682dc
commit
d826896f74
21
configure.in
21
configure.in
@ -156,6 +156,15 @@ AC_ARG_ENABLE(ipv6,
|
|||||||
fi,
|
fi,
|
||||||
want_ipv6=yes)
|
want_ipv6=yes)
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(dane,
|
||||||
|
[ --enable-dane Enable DANE support],
|
||||||
|
if test x$enableval = xno ; then
|
||||||
|
want_dane=no
|
||||||
|
else
|
||||||
|
want_dane=yes
|
||||||
|
fi,
|
||||||
|
want_dane=no)
|
||||||
|
|
||||||
dnl **
|
dnl **
|
||||||
dnl ** SSL Library checks (OpenSSL)
|
dnl ** SSL Library checks (OpenSSL)
|
||||||
dnl **
|
dnl **
|
||||||
@ -616,6 +625,17 @@ if test "x$want_ipv6" = "xyes"; then
|
|||||||
AC_MSG_RESULT($have_ipv6)
|
AC_MSG_RESULT($have_ipv6)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
have_dane=no
|
||||||
|
if test "x$want_dane" = "xyes"; then
|
||||||
|
AC_MSG_CHECKING([for DANE])
|
||||||
|
AC_CHECK_LIB(val-threads, val_getdaneinfo,
|
||||||
|
[
|
||||||
|
LIBS="$LIBS -lval-threads -lsres"
|
||||||
|
AC_DEFINE([HAVE_DANE], [], [DANE support])
|
||||||
|
have_dane=yes
|
||||||
|
])
|
||||||
|
fi
|
||||||
|
|
||||||
AC_CONFIG_FILES([
|
AC_CONFIG_FILES([
|
||||||
Makefile
|
Makefile
|
||||||
src/Makefile
|
src/Makefile
|
||||||
@ -733,6 +753,7 @@ echo "Building with IPv6 support ....... : $have_ipv6"
|
|||||||
echo "Building with SSL support ........ : $have_openssl"
|
echo "Building with SSL support ........ : $have_openssl"
|
||||||
echo "Building with 64bit DCC support .. : $offt_64bit"
|
echo "Building with 64bit DCC support .. : $offt_64bit"
|
||||||
echo "Building with garbage collector .. : $have_gc"
|
echo "Building with garbage collector .. : $have_gc"
|
||||||
|
echo "Building with DANE support ....... : $have_dane"
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "If there are any problems, read the INSTALL file."
|
echo "If there are any problems, read the INSTALL file."
|
||||||
|
@ -31,6 +31,11 @@
|
|||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_DANE
|
||||||
|
#include <validator/validator.h>
|
||||||
|
#include <validator/val_dane.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* ssl i/o channel object */
|
/* ssl i/o channel object */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -41,6 +46,7 @@ typedef struct
|
|||||||
SSL_CTX *ctx;
|
SSL_CTX *ctx;
|
||||||
unsigned int verify:1;
|
unsigned int verify:1;
|
||||||
const char *hostname;
|
const char *hostname;
|
||||||
|
int port;
|
||||||
} GIOSSLChannel;
|
} GIOSSLChannel;
|
||||||
|
|
||||||
static int ssl_inited = FALSE;
|
static int ssl_inited = FALSE;
|
||||||
@ -196,9 +202,42 @@ static gboolean irssi_ssl_verify_hostname(X509 *cert, const char *hostname)
|
|||||||
return matched;
|
return matched;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean irssi_ssl_verify(SSL *ssl, SSL_CTX *ctx, const char* hostname, X509 *cert)
|
static gboolean irssi_ssl_verify(SSL *ssl, SSL_CTX *ctx, const char* hostname, int port, X509 *cert)
|
||||||
{
|
{
|
||||||
long result;
|
long result;
|
||||||
|
#ifdef HAVE_DANE
|
||||||
|
int dane_ret;
|
||||||
|
struct val_daneparams daneparams;
|
||||||
|
struct val_danestatus *danestatus = NULL;
|
||||||
|
|
||||||
|
// Check if a TLSA record is available.
|
||||||
|
daneparams.port = port;
|
||||||
|
daneparams.proto = DANE_PARAM_PROTO_TCP;
|
||||||
|
|
||||||
|
dane_ret = val_getdaneinfo(NULL, hostname, &daneparams, &danestatus);
|
||||||
|
|
||||||
|
if (dane_ret == VAL_DANE_NOERROR) {
|
||||||
|
g_warning("DANE: TLSA record for hostname %s exists", hostname);
|
||||||
|
} else if (dane_ret != VAL_DANE_IGNORE_TLSA) {
|
||||||
|
g_warning("DANE: TLSA record for hostname %s could not be verified", hostname);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (danestatus != NULL) {
|
||||||
|
int do_certificate_check = 1;
|
||||||
|
|
||||||
|
if (val_dane_check(NULL, ssl, danestatus, &do_certificate_check) != VAL_DANE_NOERROR) {
|
||||||
|
g_warning("DANE: Failed to verify hostname %s", hostname);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_warning("DANE: SSL certificate verified using DANE");
|
||||||
|
|
||||||
|
if (do_certificate_check == 0) {
|
||||||
|
g_warning("DANE: Skipping additional checks");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
result = SSL_get_verify_result(ssl);
|
result = SSL_get_verify_result(ssl);
|
||||||
if (result != X509_V_OK) {
|
if (result != X509_V_OK) {
|
||||||
@ -389,7 +428,7 @@ static gboolean irssi_ssl_init(void)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, const char *hostname, const char *mycert, const char *mypkey, const char *cafile, const char *capath, gboolean verify)
|
static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, const char *hostname, int port, const char *mycert, const char *mypkey, const char *cafile, const char *capath, gboolean verify)
|
||||||
{
|
{
|
||||||
GIOSSLChannel *chan;
|
GIOSSLChannel *chan;
|
||||||
GIOChannel *gchan;
|
GIOChannel *gchan;
|
||||||
@ -474,6 +513,7 @@ static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, const char *hostn
|
|||||||
chan->ctx = ctx;
|
chan->ctx = ctx;
|
||||||
chan->verify = verify;
|
chan->verify = verify;
|
||||||
chan->hostname = hostname;
|
chan->hostname = hostname;
|
||||||
|
chan->port = port;
|
||||||
|
|
||||||
gchan = (GIOChannel *)chan;
|
gchan = (GIOChannel *)chan;
|
||||||
gchan->funcs = &irssi_ssl_channel_funcs;
|
gchan->funcs = &irssi_ssl_channel_funcs;
|
||||||
@ -491,7 +531,7 @@ GIOChannel *net_connect_ip_ssl(IPADDR *ip, int port, const char* hostname, IPADD
|
|||||||
handle = net_connect_ip(ip, port, my_ip);
|
handle = net_connect_ip(ip, port, my_ip);
|
||||||
if (handle == NULL)
|
if (handle == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
ssl_handle = irssi_ssl_get_iochannel(handle, hostname, cert, pkey, cafile, capath, verify);
|
ssl_handle = irssi_ssl_get_iochannel(handle, hostname, port, cert, pkey, cafile, capath, verify);
|
||||||
if (ssl_handle == NULL)
|
if (ssl_handle == NULL)
|
||||||
g_io_channel_unref(handle);
|
g_io_channel_unref(handle);
|
||||||
return ssl_handle;
|
return ssl_handle;
|
||||||
@ -533,7 +573,7 @@ int irssi_ssl_handshake(GIOChannel *handle)
|
|||||||
g_warning("SSL server supplied no certificate");
|
g_warning("SSL server supplied no certificate");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ret = !chan->verify || irssi_ssl_verify(chan->ssl, chan->ctx, chan->hostname, cert);
|
ret = !chan->verify || irssi_ssl_verify(chan->ssl, chan->ctx, chan->hostname, chan->port, cert);
|
||||||
X509_free(cert);
|
X509_free(cert);
|
||||||
return ret ? 0 : -1;
|
return ret ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user