mirror of
https://github.com/irssi/irssi.git
synced 2025-02-02 15:08:01 -05:00
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,
|
||||
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 ** SSL Library checks (OpenSSL)
|
||||
dnl **
|
||||
@ -616,6 +625,17 @@ if test "x$want_ipv6" = "xyes"; then
|
||||
AC_MSG_RESULT($have_ipv6)
|
||||
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([
|
||||
Makefile
|
||||
src/Makefile
|
||||
@ -733,6 +753,7 @@ echo "Building with IPv6 support ....... : $have_ipv6"
|
||||
echo "Building with SSL support ........ : $have_openssl"
|
||||
echo "Building with 64bit DCC support .. : $offt_64bit"
|
||||
echo "Building with garbage collector .. : $have_gc"
|
||||
echo "Building with DANE support ....... : $have_dane"
|
||||
|
||||
echo
|
||||
echo "If there are any problems, read the INSTALL file."
|
||||
|
@ -31,6 +31,11 @@
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#ifdef HAVE_DANE
|
||||
#include <validator/validator.h>
|
||||
#include <validator/val_dane.h>
|
||||
#endif
|
||||
|
||||
/* ssl i/o channel object */
|
||||
typedef struct
|
||||
{
|
||||
@ -41,6 +46,7 @@ typedef struct
|
||||
SSL_CTX *ctx;
|
||||
unsigned int verify:1;
|
||||
const char *hostname;
|
||||
int port;
|
||||
} GIOSSLChannel;
|
||||
|
||||
static int ssl_inited = FALSE;
|
||||
@ -196,9 +202,42 @@ static gboolean irssi_ssl_verify_hostname(X509 *cert, const char *hostname)
|
||||
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;
|
||||
#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);
|
||||
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;
|
||||
GIOChannel *gchan;
|
||||
@ -474,6 +513,7 @@ static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, const char *hostn
|
||||
chan->ctx = ctx;
|
||||
chan->verify = verify;
|
||||
chan->hostname = hostname;
|
||||
chan->port = port;
|
||||
|
||||
gchan = (GIOChannel *)chan;
|
||||
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);
|
||||
if (handle == 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)
|
||||
g_io_channel_unref(handle);
|
||||
return ssl_handle;
|
||||
@ -533,7 +573,7 @@ int irssi_ssl_handshake(GIOChannel *handle)
|
||||
g_warning("SSL server supplied no certificate");
|
||||
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);
|
||||
return ret ? 0 : -1;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user