mirror of
https://github.com/irssi/irssi.git
synced 2024-12-04 14:46:39 -05:00
Added OpenSSL support by vjt@users.sf.net. Also fixes a possible crash after
using /SERVER ADD -ircnet. git-svn-id: http://svn.irssi.org/repos/irssi/trunk@2890 dbcabf3a-b0e7-0310-adc4-f8d773084564
This commit is contained in:
parent
13effe87e4
commit
1539cf81f3
@ -36,3 +36,6 @@
|
|||||||
#undef HAVE_GETTEXT
|
#undef HAVE_GETTEXT
|
||||||
#undef HAVE_LC_MESSAGES
|
#undef HAVE_LC_MESSAGES
|
||||||
#undef HAVE_STPCPY
|
#undef HAVE_STPCPY
|
||||||
|
|
||||||
|
/* SSL */
|
||||||
|
#undef HAVE_OPENSSL
|
||||||
|
73
configure.in
73
configure.in
@ -112,7 +112,7 @@ if test "x$prefix" != "xNONE"; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
AC_ARG_WITH(tests,
|
AC_ARG_WITH(tests,
|
||||||
[ --with-glib2 Use GLIB 2.0 instead of 1.2],
|
[ --with-glib2 Use GLIB 2.0 instead of 1.2],
|
||||||
if test x$withval = xyes; then
|
if test x$withval = xyes; then
|
||||||
want_glib2=yes
|
want_glib2=yes
|
||||||
else
|
else
|
||||||
@ -126,7 +126,7 @@ AC_ARG_WITH(tests,
|
|||||||
|
|
||||||
AC_ARG_WITH(perl-staticlib,
|
AC_ARG_WITH(perl-staticlib,
|
||||||
[ --with-perl-staticlib Specify that we want to link perl libraries
|
[ --with-perl-staticlib Specify that we want to link perl libraries
|
||||||
statically in irssi, default is no],
|
statically in irssi, default is no],
|
||||||
if test x$withval = xyes; then
|
if test x$withval = xyes; then
|
||||||
want_staticperllib=yes
|
want_staticperllib=yes
|
||||||
else
|
else
|
||||||
@ -141,7 +141,7 @@ AC_ARG_WITH(perl-staticlib,
|
|||||||
|
|
||||||
AC_ARG_WITH(perl-lib,
|
AC_ARG_WITH(perl-lib,
|
||||||
[ --with-perl-lib=[site|vendor|DIR] Specify where to install the
|
[ --with-perl-lib=[site|vendor|DIR] Specify where to install the
|
||||||
Perl libraries for irssi, default is site],
|
Perl libraries for irssi, default is site],
|
||||||
if test "x$withval" = xyes; then
|
if test "x$withval" = xyes; then
|
||||||
want_perl=yes
|
want_perl=yes
|
||||||
elif test "x$withval" = xno; then
|
elif test "x$withval" = xno; then
|
||||||
@ -170,8 +170,8 @@ AC_ARG_WITH(perl-lib,
|
|||||||
|
|
||||||
AC_ARG_WITH(perl,
|
AC_ARG_WITH(perl,
|
||||||
[ --with-perl[=yes|no|module] Build with Perl support - also specifies
|
[ --with-perl[=yes|no|module] Build with Perl support - also specifies
|
||||||
if it should be built into main irssi binary
|
if it should be built into main irssi binary
|
||||||
(static, default) or as module],
|
(static, default) or as module],
|
||||||
if test x$withval = xyes; then
|
if test x$withval = xyes; then
|
||||||
want_perl=static
|
want_perl=static
|
||||||
elif test x$withval = xstatic; then
|
elif test x$withval = xstatic; then
|
||||||
@ -196,6 +196,62 @@ AC_ARG_ENABLE(ipv6,
|
|||||||
fi,
|
fi,
|
||||||
want_ipv6=no)
|
want_ipv6=no)
|
||||||
|
|
||||||
|
dnl **
|
||||||
|
dnl ** SSL Library checks (OpenSSL)
|
||||||
|
dnl **
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(ssl,
|
||||||
|
[ --disable-ssl Turn on Secure Sockets Layer support [default=yes]],,
|
||||||
|
enable_ssl=yes)
|
||||||
|
|
||||||
|
AC_ARG_WITH(openssl-includes,
|
||||||
|
[ --with-openssl-includes Specify location of OpenSSL header files],
|
||||||
|
[openssl_inc_prefix=-I$withval])
|
||||||
|
|
||||||
|
AC_ARG_WITH(openssl-libs,
|
||||||
|
[ --with-openssl-libs Specify location of OpenSSL libs],
|
||||||
|
[openssl_prefix=$withval],
|
||||||
|
[openssl_prefix=/usr/lib])
|
||||||
|
|
||||||
|
if test "x$enable_ssl" = xyes; then
|
||||||
|
###
|
||||||
|
### Check for OpenSSL
|
||||||
|
###
|
||||||
|
save_CFLAGS=$CFLAGS;
|
||||||
|
CFLAGS="-lcrypto";
|
||||||
|
|
||||||
|
enable_openssl="no";
|
||||||
|
OPENSSL_LDFLAGS="";
|
||||||
|
AC_CHECK_LIB(ssl, SSL_read,
|
||||||
|
AC_CHECK_LIB(crypto, X509_new,
|
||||||
|
AC_CHECK_HEADERS(openssl/ssl.h openssl/err.h,
|
||||||
|
[
|
||||||
|
enable_openssl="yes";
|
||||||
|
OPENSSL_LDFLAGS="-lssl -lcrypto"
|
||||||
|
],
|
||||||
|
AC_ERROR([Cannot find OpenSSL includes !])),
|
||||||
|
AC_ERROR([Cannot find libCrypto !])),
|
||||||
|
AC_ERROR([Cannot find libSSL !]))
|
||||||
|
CFLAGS=$save_CFLAGS
|
||||||
|
|
||||||
|
if test "x$enable_openssl" = xyes; then
|
||||||
|
AC_DEFINE(HAVE_OPENSSL)
|
||||||
|
OPENSSL_LIBS="-L$openssl_prefix $OPENSSL_LDFLAGS"
|
||||||
|
OPENSSL_CFLAGS="$openssl_inc_prefix"
|
||||||
|
else
|
||||||
|
OPENSSL_LIBS=
|
||||||
|
OPENSSL_CFLAGS=
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST(OPENSSL_CFLAGS)
|
||||||
|
AC_SUBST(OPENSSL_LIBS)
|
||||||
|
LIBS="$LIBS $OPENSSL_LIBS"
|
||||||
|
CFLAGS="$CFLAGS $OPENSSL_CFLAGS"
|
||||||
|
else
|
||||||
|
enable_openssl="no"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
dnl **
|
dnl **
|
||||||
dnl ** just some generic stuff...
|
dnl ** just some generic stuff...
|
||||||
dnl **
|
dnl **
|
||||||
@ -830,7 +886,6 @@ fi
|
|||||||
echo "Building text frontend ..... : $text"
|
echo "Building text frontend ..... : $text"
|
||||||
echo "Building irssi bot ......... : $want_irssibot"
|
echo "Building irssi bot ......... : $want_irssibot"
|
||||||
echo "Building irssi proxy ....... : $want_irssiproxy"
|
echo "Building irssi proxy ....... : $want_irssiproxy"
|
||||||
echo "Building with IPv6 support . : $want_ipv6"
|
|
||||||
if test "x$have_gmodule" = "xyes"; then
|
if test "x$have_gmodule" = "xyes"; then
|
||||||
echo "Building with module support : yes"
|
echo "Building with module support : yes"
|
||||||
else
|
else
|
||||||
@ -877,8 +932,12 @@ if test "x$want_perl" != "xno"; then
|
|||||||
echo " Anyway, installing perl to this directory should work just as well."
|
echo " Anyway, installing perl to this directory should work just as well."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Install prefix ............. : $prefix"
|
echo "Install prefix ............. : $prefix"
|
||||||
|
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo "Building with IPv6 support . : $want_ipv6"
|
||||||
|
echo "Building with SSL support .. : ${enable_openssl}"
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "If there was any problems, read the INSTALL file."
|
echo "If there was any problems, read the INSTALL file."
|
||||||
|
@ -30,6 +30,7 @@ libcore_a_SOURCES = \
|
|||||||
net-nonblock.c \
|
net-nonblock.c \
|
||||||
net-sendbuffer.c \
|
net-sendbuffer.c \
|
||||||
network.c \
|
network.c \
|
||||||
|
network-openssl.c \
|
||||||
nicklist.c \
|
nicklist.c \
|
||||||
nickmatch-cache.c \
|
nickmatch-cache.c \
|
||||||
pidwait.c \
|
pidwait.c \
|
||||||
|
@ -88,12 +88,16 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr,
|
|||||||
else if (g_hash_table_lookup(optlist, "4") != NULL)
|
else if (g_hash_table_lookup(optlist, "4") != NULL)
|
||||||
conn->family = AF_INET;
|
conn->family = AF_INET;
|
||||||
|
|
||||||
|
if(g_hash_table_lookup(optlist, "ssl") != NULL)
|
||||||
|
conn->use_ssl = TRUE;
|
||||||
|
|
||||||
if (g_hash_table_lookup(optlist, "!") != NULL)
|
if (g_hash_table_lookup(optlist, "!") != NULL)
|
||||||
conn->no_autojoin_channels = TRUE;
|
conn->no_autojoin_channels = TRUE;
|
||||||
|
|
||||||
if (g_hash_table_lookup(optlist, "noproxy") != NULL)
|
if (g_hash_table_lookup(optlist, "noproxy") != NULL)
|
||||||
g_free_and_null(conn->proxy);
|
g_free_and_null(conn->proxy);
|
||||||
|
|
||||||
|
|
||||||
*rawlog_file = g_strdup(g_hash_table_lookup(optlist, "rawlog"));
|
*rawlog_file = g_strdup(g_hash_table_lookup(optlist, "rawlog"));
|
||||||
|
|
||||||
host = g_hash_table_lookup(optlist, "host");
|
host = g_hash_table_lookup(optlist, "host");
|
||||||
@ -108,7 +112,7 @@ static SERVER_CONNECT_REC *get_server_connect(const char *data, int *plus_addr,
|
|||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SYNTAX: CONNECT [-4 | -6] [-ircnet <ircnet>] [-host <hostname>]
|
/* SYNTAX: CONNECT [-4 | -6] [-ssl] [-ircnet <ircnet>] [-host <hostname>]
|
||||||
<address>|<chatnet> [<port> [<password> [<nick>]]] */
|
<address>|<chatnet> [<port> [<password> [<nick>]]] */
|
||||||
static void cmd_connect(const char *data)
|
static void cmd_connect(const char *data)
|
||||||
{
|
{
|
||||||
@ -209,7 +213,7 @@ static void sig_default_command_server(const char *data, SERVER_REC *server,
|
|||||||
signal_emit("command server connect", 3, data, server, item);
|
signal_emit("command server connect", 3, data, server, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SYNTAX: SERVER [-4 | -6] [-ircnet <ircnet>] [-host <hostname>]
|
/* SYNTAX: SERVER [-4 | -6] [-ssl] [-ircnet <ircnet>] [-host <hostname>]
|
||||||
[+]<address>|<chatnet> [<port> [<password> [<nick>]]] */
|
[+]<address>|<chatnet> [<port> [<password> [<nick>]]] */
|
||||||
static void cmd_server_connect(const char *data, SERVER_REC *server)
|
static void cmd_server_connect(const char *data, SERVER_REC *server)
|
||||||
{
|
{
|
||||||
@ -439,7 +443,7 @@ void chat_commands_init(void)
|
|||||||
|
|
||||||
signal_add("default command server", (SIGNAL_FUNC) sig_default_command_server);
|
signal_add("default command server", (SIGNAL_FUNC) sig_default_command_server);
|
||||||
|
|
||||||
command_set_options("connect", "4 6 !! +host noproxy -rawlog");
|
command_set_options("connect", "4 6 !! ssl +host noproxy -rawlog");
|
||||||
command_set_options("join", "invite");
|
command_set_options("join", "invite");
|
||||||
command_set_options("msg", "channel nick");
|
command_set_options("msg", "channel nick");
|
||||||
}
|
}
|
||||||
|
291
src/core/network-openssl.c
Normal file
291
src/core/network-openssl.c
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
/*
|
||||||
|
network-ssl.c : SSL support
|
||||||
|
|
||||||
|
Copyright (C) 2002 vjt
|
||||||
|
|
||||||
|
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-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "module.h"
|
||||||
|
#include "network.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_OPENSSL
|
||||||
|
|
||||||
|
#include <openssl/crypto.h>
|
||||||
|
#include <openssl/x509.h>
|
||||||
|
#include <openssl/pem.h>
|
||||||
|
#include <openssl/ssl.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
|
||||||
|
/* ssl read */
|
||||||
|
GIOError irssi_ssl_read(GIOChannel *, gchar *, guint, guint *);
|
||||||
|
/* ssl write */
|
||||||
|
GIOError irssi_ssl_write(GIOChannel *, gchar *, guint, guint*);
|
||||||
|
/* ssl seek */
|
||||||
|
GIOError irssi_ssl_seek(GIOChannel *, gint, GSeekType);
|
||||||
|
/* ssl close */
|
||||||
|
void irssi_ssl_close(GIOChannel *);
|
||||||
|
/* ssl create watch */
|
||||||
|
guint irssi_ssl_create_watch(GIOChannel *, gint, GIOCondition, GIOFunc, gpointer, GDestroyNotify);
|
||||||
|
/* ssl free */
|
||||||
|
void irssi_ssl_free(GIOChannel *);
|
||||||
|
|
||||||
|
/* ssl i/o channel object */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GIOChannel pad;
|
||||||
|
gint fd;
|
||||||
|
GIOChannel *giochan;
|
||||||
|
SSL *ssl;
|
||||||
|
X509 *cert;
|
||||||
|
} GIOSSLChannel;
|
||||||
|
|
||||||
|
/* ssl function pointers */
|
||||||
|
GIOFuncs irssi_ssl_channel_funcs =
|
||||||
|
{
|
||||||
|
irssi_ssl_read,
|
||||||
|
irssi_ssl_write,
|
||||||
|
irssi_ssl_seek,
|
||||||
|
irssi_ssl_close,
|
||||||
|
irssi_ssl_create_watch,
|
||||||
|
irssi_ssl_free
|
||||||
|
};
|
||||||
|
|
||||||
|
SSL_CTX *ssl_ctx = NULL;
|
||||||
|
|
||||||
|
#ifdef G_CAN_INLINE
|
||||||
|
G_INLINE_FUNC
|
||||||
|
#endif
|
||||||
|
gint ssl_errno(gint e)
|
||||||
|
{
|
||||||
|
switch(e)
|
||||||
|
{
|
||||||
|
case EINVAL:
|
||||||
|
return G_IO_ERROR_INVAL;
|
||||||
|
case EINTR:
|
||||||
|
case EAGAIN:
|
||||||
|
return G_IO_ERROR_AGAIN;
|
||||||
|
default:
|
||||||
|
return G_IO_ERROR_INVAL;
|
||||||
|
}
|
||||||
|
/*UNREACH*/
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean irssi_ssl_cert_step(GIOSSLChannel *chan)
|
||||||
|
{
|
||||||
|
gint err;
|
||||||
|
switch(err = SSL_do_handshake(chan->ssl))
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
if(!(chan->cert = SSL_get_peer_certificate(chan->ssl)))
|
||||||
|
{
|
||||||
|
g_warning("SSL server supplied no certificate");
|
||||||
|
return G_IO_ERROR_INVAL;
|
||||||
|
}
|
||||||
|
return G_IO_ERROR_NONE;
|
||||||
|
default:
|
||||||
|
if(SSL_get_error(chan->ssl, err) == SSL_ERROR_WANT_READ)
|
||||||
|
return G_IO_ERROR_AGAIN;
|
||||||
|
return ssl_errno(errno);
|
||||||
|
}
|
||||||
|
/*UNREACH*/
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
GIOError irssi_ssl_read(GIOChannel *handle, gchar *buf, guint len, guint *ret)
|
||||||
|
{
|
||||||
|
GIOSSLChannel *chan = (GIOSSLChannel *)handle;
|
||||||
|
gint err;
|
||||||
|
|
||||||
|
if(chan->cert == NULL)
|
||||||
|
{
|
||||||
|
gint cert_err = irssi_ssl_cert_step(chan);
|
||||||
|
if(cert_err != G_IO_ERROR_NONE)
|
||||||
|
return cert_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = SSL_read(chan->ssl, buf, len);
|
||||||
|
if(err < 0)
|
||||||
|
{
|
||||||
|
*ret = 0;
|
||||||
|
if(SSL_get_error(chan->ssl, err) == SSL_ERROR_WANT_READ)
|
||||||
|
return G_IO_ERROR_AGAIN;
|
||||||
|
return ssl_errno(errno);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ret = err;
|
||||||
|
return G_IO_ERROR_NONE;
|
||||||
|
}
|
||||||
|
/*UNREACH*/
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
GIOError irssi_ssl_write(GIOChannel *handle, gchar *buf, guint len, guint *ret)
|
||||||
|
{
|
||||||
|
GIOSSLChannel *chan = (GIOSSLChannel *)handle;
|
||||||
|
gint err;
|
||||||
|
|
||||||
|
if(chan->cert == NULL)
|
||||||
|
{
|
||||||
|
gint cert_err = irssi_ssl_cert_step(chan);
|
||||||
|
if(cert_err != G_IO_ERROR_NONE)
|
||||||
|
return cert_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
err = SSL_write(chan->ssl, (const char *)buf, len);
|
||||||
|
if(err < 0)
|
||||||
|
{
|
||||||
|
*ret = 0;
|
||||||
|
if(SSL_get_error(chan->ssl, err) == SSL_ERROR_WANT_READ)
|
||||||
|
return G_IO_ERROR_AGAIN;
|
||||||
|
return ssl_errno(errno);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ret = err;
|
||||||
|
return G_IO_ERROR_NONE;
|
||||||
|
}
|
||||||
|
/*UNREACH*/
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
GIOError irssi_ssl_seek(GIOChannel *handle, gint offset, GSeekType type)
|
||||||
|
{
|
||||||
|
GIOSSLChannel *chan = (GIOSSLChannel *)handle;
|
||||||
|
GIOError e;
|
||||||
|
e = g_io_channel_seek(chan->giochan, offset, type);
|
||||||
|
return (e == G_IO_ERROR_NONE) ? G_IO_ERROR_NONE : G_IO_ERROR_INVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void irssi_ssl_close(GIOChannel *handle)
|
||||||
|
{
|
||||||
|
GIOSSLChannel *chan = (GIOSSLChannel *)handle;
|
||||||
|
g_io_channel_close(chan->giochan);
|
||||||
|
}
|
||||||
|
|
||||||
|
guint irssi_ssl_create_watch(GIOChannel *handle, gint priority, GIOCondition cond,
|
||||||
|
GIOFunc func, gpointer data, GDestroyNotify notify)
|
||||||
|
{
|
||||||
|
GIOSSLChannel *chan = (GIOSSLChannel *)handle;
|
||||||
|
return chan->giochan->funcs->io_add_watch(handle, priority, cond, func, data, notify);
|
||||||
|
}
|
||||||
|
|
||||||
|
void irssi_ssl_free(GIOChannel *handle)
|
||||||
|
{
|
||||||
|
GIOSSLChannel *chan = (GIOSSLChannel *)handle;
|
||||||
|
g_io_channel_unref(chan->giochan);
|
||||||
|
SSL_free(chan->ssl);
|
||||||
|
g_free(chan);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean irssi_ssl_init(void)
|
||||||
|
{
|
||||||
|
SSL_library_init();
|
||||||
|
SSL_load_error_strings();
|
||||||
|
|
||||||
|
ssl_ctx = SSL_CTX_new(SSLv23_client_method());
|
||||||
|
if(!ssl_ctx)
|
||||||
|
{
|
||||||
|
g_error("Initialization of the SSL library failed");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle)
|
||||||
|
{
|
||||||
|
GIOSSLChannel *chan;
|
||||||
|
GIOChannel *gchan;
|
||||||
|
int err, fd;
|
||||||
|
SSL *ssl;
|
||||||
|
X509 *cert = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail(handle != NULL, NULL);
|
||||||
|
|
||||||
|
if(!ssl_ctx && !irssi_ssl_init())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if(!(fd = g_io_channel_unix_get_fd(handle)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if(!(ssl = SSL_new(ssl_ctx)))
|
||||||
|
{
|
||||||
|
g_warning("Failed to allocate SSL structure");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!(err = SSL_set_fd(ssl, fd)))
|
||||||
|
{
|
||||||
|
g_warning("Failed to associate socket to SSL stream");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((err = SSL_connect(ssl)) <= 0)
|
||||||
|
{
|
||||||
|
switch(err = SSL_get_error(ssl, err))
|
||||||
|
{
|
||||||
|
case SSL_ERROR_SYSCALL:
|
||||||
|
if(errno == EINTR || errno == EAGAIN)
|
||||||
|
case SSL_ERROR_WANT_READ:
|
||||||
|
case SSL_ERROR_WANT_WRITE:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(!(cert = SSL_get_peer_certificate(ssl)))
|
||||||
|
{
|
||||||
|
g_warning("SSL server supplied no certificate");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
X509_free(cert);
|
||||||
|
|
||||||
|
chan = g_new0(GIOSSLChannel, 1);
|
||||||
|
chan->fd = fd;
|
||||||
|
chan->giochan = handle;
|
||||||
|
chan->ssl = ssl;
|
||||||
|
chan->cert = cert;
|
||||||
|
g_io_channel_ref(handle);
|
||||||
|
|
||||||
|
gchan = (GIOChannel *)chan;
|
||||||
|
gchan->funcs = &irssi_ssl_channel_funcs;
|
||||||
|
g_io_channel_init(gchan);
|
||||||
|
|
||||||
|
return gchan;
|
||||||
|
}
|
||||||
|
|
||||||
|
GIOChannel *net_connect_ip_ssl(IPADDR *ip, int port, IPADDR *my_ip)
|
||||||
|
{
|
||||||
|
GIOChannel *gret = net_connect_ip(ip, port, my_ip);
|
||||||
|
gret = irssi_ssl_get_iochannel(gret);
|
||||||
|
return gret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* HAVE_OPENSSL */
|
||||||
|
|
||||||
|
GIOChannel *net_connect_ip_ssl(IPADDR *ip, int port, IPADDR *my_ip)
|
||||||
|
{
|
||||||
|
g_warning("Connection failed: SSL support not enabled in this build.");
|
||||||
|
errno = ENOSYS;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ! HAVE_OPENSSL */
|
@ -44,6 +44,8 @@ int net_ip_compare(IPADDR *ip1, IPADDR *ip2);
|
|||||||
|
|
||||||
/* Connect to socket */
|
/* Connect to socket */
|
||||||
GIOChannel *net_connect(const char *addr, int port, IPADDR *my_ip);
|
GIOChannel *net_connect(const char *addr, int port, IPADDR *my_ip);
|
||||||
|
/* Connect to socket with ip address and SSL*/
|
||||||
|
GIOChannel *net_connect_ip_ssl(IPADDR *ip, int port, IPADDR *my_ip);
|
||||||
/* Connect to socket with ip address */
|
/* Connect to socket with ip address */
|
||||||
GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip);
|
GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip);
|
||||||
/* Connect to named UNIX socket */
|
/* Connect to named UNIX socket */
|
||||||
|
@ -29,5 +29,6 @@ GIOChannel *connect_handle; /* connect using this handle */
|
|||||||
unsigned int reconnection:1; /* we're trying to reconnect */
|
unsigned int reconnection:1; /* we're trying to reconnect */
|
||||||
unsigned int no_autojoin_channels:1; /* don't autojoin any channels */
|
unsigned int no_autojoin_channels:1; /* don't autojoin any channels */
|
||||||
unsigned int unix_socket:1; /* Connect using named unix socket */
|
unsigned int unix_socket:1; /* Connect using named unix socket */
|
||||||
|
unsigned int use_ssl:1; /* this connection uses SSL */
|
||||||
char *channels;
|
char *channels;
|
||||||
char *away_reason;
|
char *away_reason;
|
||||||
|
@ -18,5 +18,6 @@ unsigned int no_proxy:1;
|
|||||||
unsigned int last_failed:1; /* if last connection attempt failed */
|
unsigned int last_failed:1; /* if last connection attempt failed */
|
||||||
unsigned int banned:1; /* if we're banned from this server */
|
unsigned int banned:1; /* if we're banned from this server */
|
||||||
unsigned int dns_error:1; /* DNS said the host doesn't exist */
|
unsigned int dns_error:1; /* DNS said the host doesn't exist */
|
||||||
|
unsigned int use_ssl:1; /* this connection uses SSL */
|
||||||
|
|
||||||
GHashTable *module_data;
|
GHashTable *module_data;
|
||||||
|
@ -164,6 +164,8 @@ server_connect_copy_skeleton(SERVER_CONNECT_REC *src, int connect_info)
|
|||||||
dest->away_reason = g_strdup(src->away_reason);
|
dest->away_reason = g_strdup(src->away_reason);
|
||||||
dest->no_autojoin_channels = src->no_autojoin_channels;
|
dest->no_autojoin_channels = src->no_autojoin_channels;
|
||||||
|
|
||||||
|
dest->use_ssl = src->use_ssl;
|
||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,6 +108,8 @@ void server_setup_fill_reconn(SERVER_CONNECT_REC *conn,
|
|||||||
if (sserver->password != NULL && conn->password == NULL)
|
if (sserver->password != NULL && conn->password == NULL)
|
||||||
conn->password = g_strdup(sserver->password);
|
conn->password = g_strdup(sserver->password);
|
||||||
|
|
||||||
|
conn->use_ssl = sserver->use_ssl;
|
||||||
|
|
||||||
signal_emit("server setup fill reconn", 2, conn, sserver);
|
signal_emit("server setup fill reconn", 2, conn, sserver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,6 +393,7 @@ static SERVER_SETUP_REC *server_setup_read(CONFIG_NODE *node)
|
|||||||
(g_strcasecmp(family, "inet") == 0 ? AF_INET : 0);
|
(g_strcasecmp(family, "inet") == 0 ? AF_INET : 0);
|
||||||
rec->address = g_strdup(server);
|
rec->address = g_strdup(server);
|
||||||
rec->password = g_strdup(config_node_get_str(node, "password", NULL));
|
rec->password = g_strdup(config_node_get_str(node, "password", NULL));
|
||||||
|
rec->use_ssl = config_node_get_bool(node, "use_ssl", FALSE);
|
||||||
rec->port = port;
|
rec->port = port;
|
||||||
rec->autoconnect = config_node_get_bool(node, "autoconnect", FALSE);
|
rec->autoconnect = config_node_get_bool(node, "autoconnect", FALSE);
|
||||||
rec->no_proxy = config_node_get_bool(node, "no_proxy", FALSE);
|
rec->no_proxy = config_node_get_bool(node, "no_proxy", FALSE);
|
||||||
@ -420,6 +423,7 @@ static void server_setup_save(SERVER_SETUP_REC *rec)
|
|||||||
|
|
||||||
iconfig_node_set_int(node, "port", rec->port);
|
iconfig_node_set_int(node, "port", rec->port);
|
||||||
iconfig_node_set_str(node, "password", rec->password);
|
iconfig_node_set_str(node, "password", rec->password);
|
||||||
|
iconfig_node_set_bool(node, "use_ssl", rec->use_ssl);
|
||||||
iconfig_node_set_str(node, "own_host", rec->own_host);
|
iconfig_node_set_str(node, "own_host", rec->own_host);
|
||||||
|
|
||||||
iconfig_node_set_str(node, "family",
|
iconfig_node_set_str(node, "family",
|
||||||
|
@ -178,13 +178,18 @@ static void server_real_connect(SERVER_REC *server, IPADDR *ip,
|
|||||||
server->connrec->own_ip4);
|
server->connrec->own_ip4);
|
||||||
port = server->connrec->proxy != NULL ?
|
port = server->connrec->proxy != NULL ?
|
||||||
server->connrec->proxy_port : server->connrec->port;
|
server->connrec->proxy_port : server->connrec->port;
|
||||||
handle = net_connect_ip(ip, port, own_ip);
|
handle = server->connrec->use_ssl ?
|
||||||
|
net_connect_ip_ssl(ip, port, own_ip) :
|
||||||
|
net_connect_ip(ip, port, own_ip);
|
||||||
} else {
|
} else {
|
||||||
handle = net_connect_unix(unix_socket);
|
handle = net_connect_unix(unix_socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle == NULL) {
|
if (handle == NULL) {
|
||||||
/* failed */
|
/* failed */
|
||||||
|
if (server->connrec->use_ssl && errno == ENOSYS)
|
||||||
|
server->no_reconnect = TRUE;
|
||||||
|
|
||||||
server->connection_lost = TRUE;
|
server->connection_lost = TRUE;
|
||||||
server_connect_failed(server, g_strerror(errno));
|
server_connect_failed(server, g_strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
|
@ -182,6 +182,8 @@ static void session_save_server(SERVER_REC *server, CONFIG_REC *config,
|
|||||||
config_node_set_str(config, node, "password", server->connrec->password);
|
config_node_set_str(config, node, "password", server->connrec->password);
|
||||||
config_node_set_str(config, node, "nick", server->nick);
|
config_node_set_str(config, node, "nick", server->nick);
|
||||||
|
|
||||||
|
config_node_set_bool(config, node, "use_ssl", server->connrec->use_ssl);
|
||||||
|
|
||||||
handle = g_io_channel_unix_get_fd(net_sendbuffer_handle(server->handle));
|
handle = g_io_channel_unix_get_fd(net_sendbuffer_handle(server->handle));
|
||||||
config_node_set_int(config, node, "handle", handle);
|
config_node_set_int(config, node, "handle", handle);
|
||||||
|
|
||||||
|
@ -144,6 +144,9 @@ static void cmd_server_add(const char *data)
|
|||||||
else if (g_hash_table_lookup(optlist, "4"))
|
else if (g_hash_table_lookup(optlist, "4"))
|
||||||
rec->family = AF_INET;
|
rec->family = AF_INET;
|
||||||
|
|
||||||
|
if (g_hash_table_lookup(optlist, "ssl"))
|
||||||
|
rec->use_ssl = TRUE;
|
||||||
|
|
||||||
if (g_hash_table_lookup(optlist, "auto")) rec->autoconnect = TRUE;
|
if (g_hash_table_lookup(optlist, "auto")) rec->autoconnect = TRUE;
|
||||||
if (g_hash_table_lookup(optlist, "noauto")) rec->autoconnect = FALSE;
|
if (g_hash_table_lookup(optlist, "noauto")) rec->autoconnect = FALSE;
|
||||||
if (g_hash_table_lookup(optlist, "proxy")) rec->no_proxy = FALSE;
|
if (g_hash_table_lookup(optlist, "proxy")) rec->no_proxy = FALSE;
|
||||||
@ -327,7 +330,7 @@ void fe_server_init(void)
|
|||||||
command_bind("server connect", NULL, (SIGNAL_FUNC) cmd_server_connect);
|
command_bind("server connect", NULL, (SIGNAL_FUNC) cmd_server_connect);
|
||||||
command_bind("server add", NULL, (SIGNAL_FUNC) cmd_server_add);
|
command_bind("server add", NULL, (SIGNAL_FUNC) cmd_server_add);
|
||||||
command_bind("server remove", NULL, (SIGNAL_FUNC) cmd_server_remove);
|
command_bind("server remove", NULL, (SIGNAL_FUNC) cmd_server_remove);
|
||||||
command_set_options("server add", "4 6 auto noauto proxy noproxy -host -port");
|
command_set_options("server add", "4 6 ssl auto noauto proxy noproxy -host -port");
|
||||||
|
|
||||||
signal_add("server looking", (SIGNAL_FUNC) sig_server_looking);
|
signal_add("server looking", (SIGNAL_FUNC) sig_server_looking);
|
||||||
signal_add("server connecting", (SIGNAL_FUNC) sig_server_connecting);
|
signal_add("server connecting", (SIGNAL_FUNC) sig_server_connecting);
|
||||||
|
@ -917,6 +917,7 @@ void fe_events_numeric_init(void)
|
|||||||
signal_add("event 378", (SIGNAL_FUNC) event_whois_realhost);
|
signal_add("event 378", (SIGNAL_FUNC) event_whois_realhost);
|
||||||
signal_add("event 377", (SIGNAL_FUNC) event_whois_usermode);
|
signal_add("event 377", (SIGNAL_FUNC) event_whois_usermode);
|
||||||
signal_add("event 320", (SIGNAL_FUNC) event_whois_special);
|
signal_add("event 320", (SIGNAL_FUNC) event_whois_special);
|
||||||
|
signal_add("event 275", (SIGNAL_FUNC) event_whois_special);
|
||||||
signal_add("event 314", (SIGNAL_FUNC) event_whowas);
|
signal_add("event 314", (SIGNAL_FUNC) event_whowas);
|
||||||
signal_add("event 317", (SIGNAL_FUNC) event_whois_idle);
|
signal_add("event 317", (SIGNAL_FUNC) event_whois_idle);
|
||||||
signal_add("event 318", (SIGNAL_FUNC) event_end_of_whois);
|
signal_add("event 318", (SIGNAL_FUNC) event_end_of_whois);
|
||||||
@ -1002,6 +1003,7 @@ void fe_events_numeric_deinit(void)
|
|||||||
signal_remove("event 378", (SIGNAL_FUNC) event_whois_realhost);
|
signal_remove("event 378", (SIGNAL_FUNC) event_whois_realhost);
|
||||||
signal_remove("event 377", (SIGNAL_FUNC) event_whois_usermode);
|
signal_remove("event 377", (SIGNAL_FUNC) event_whois_usermode);
|
||||||
signal_remove("event 320", (SIGNAL_FUNC) event_whois_special);
|
signal_remove("event 320", (SIGNAL_FUNC) event_whois_special);
|
||||||
|
signal_remove("event 275", (SIGNAL_FUNC) event_whois_special);
|
||||||
signal_remove("event 314", (SIGNAL_FUNC) event_whowas);
|
signal_remove("event 314", (SIGNAL_FUNC) event_whowas);
|
||||||
signal_remove("event 317", (SIGNAL_FUNC) event_whois_idle);
|
signal_remove("event 317", (SIGNAL_FUNC) event_whois_idle);
|
||||||
signal_remove("event 318", (SIGNAL_FUNC) event_end_of_whois);
|
signal_remove("event 318", (SIGNAL_FUNC) event_end_of_whois);
|
||||||
|
Loading…
Reference in New Issue
Block a user