From aeb047260fefa187f5b2c5c740280c81b9ccb8f4 Mon Sep 17 00:00:00 2001
From: Přemysl Janouch
Date: Wed, 9 Dec 2015 00:53:56 +0100
Subject: Bump liberty, enable TLS SNI
Involves some rewrites to fit the new APIs.
SNI has been implemented Mostly just because we can, I don't think it's
widely in use and kike doesn't support this feature of the protocol either.
---
CMakeLists.txt | 15 ++++++++++++---
NEWS | 9 +++++++++
common.c | 28 +++++++++-------------------
degesch.c | 48 ++++++++++++++++++------------------------------
kike.c | 1 +
liberty | 2 +-
zyklonb.c | 4 +++-
7 files changed, 53 insertions(+), 54 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ca76dfa..2d25f6d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,6 +21,9 @@ set (project_VERSION "${project_VERSION}.${project_VERSION_MINOR}")
set (project_VERSION "${project_VERSION}.${project_VERSION_PATCH}")
# Dependencies
+set (CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/liberty/cmake)
+include (AddThreads)
+
find_package (Curses)
find_package (PkgConfig REQUIRED)
pkg_check_modules (libssl REQUIRED libssl libcrypto)
@@ -52,10 +55,9 @@ if (WITH_LUA)
link_directories (${lua_LIBRARY_DIRS})
endif (WITH_LUA)
-# -lpthread is only there for debugging (gdb & errno)
# -lrt is only for glibc < 2.17
# -liconv may or may not be a part of libc
-foreach (extra iconv rt pthread)
+foreach (extra iconv rt)
find_library (extra_lib_${extra} ${extra})
if (extra_lib_${extra})
list (APPEND project_libraries ${extra})
@@ -114,24 +116,31 @@ set_source_files_properties (${PROJECT_BINARY_DIR}/kike-replies.c
# Build
add_executable (zyklonb zyklonb.c ${common_sources} ${common_headers})
target_link_libraries (zyklonb ${project_libraries})
+add_threads (zyklonb)
add_executable (degesch degesch.c kike-replies.c
${common_sources} ${common_headers})
target_link_libraries (degesch ${project_libraries})
+add_threads (degesch)
add_executable (kike kike.c kike-replies.c ${common_sources} ${common_headers})
target_link_libraries (kike ${project_libraries})
+add_threads (kike)
# Tests
function (make_tests_for target_name)
get_target_property (sources ${target_name} SOURCES)
get_target_property (libraries ${target_name} LINK_LIBRARIES)
+ get_target_property (options ${target_name} COMPILE_OPTIONS)
set (test test-${target_name})
add_executable (${test} ${sources})
target_link_libraries (${test} ${libraries})
+ set_target_properties (${test} PROPERTIES
+ COMPILE_DEFINITIONS TESTING
+ COMPILE_OPTIONS ${options})
+
add_test (NAME ${test} COMMAND ${test})
- set_target_properties (${test} PROPERTIES COMPILE_DEFINITIONS TESTING)
endfunction (make_tests_for)
include (CTest)
diff --git a/NEWS b/NEWS
index 49473f4..fccdfbc 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,12 @@
+0.9.3 (2016-??-??)
+
+ * Use TLS Server Name Indication when connecting to servers
+
+ * degesch: resolve remote addresses asynchronously
+
+ * degesch: various bugfixes
+
+
0.9.2 (2015-12-31)
* degesch: added rudimentary support for Lua scripting
diff --git a/common.c b/common.c
index 0d34591..d4cf479 100644
--- a/common.c
+++ b/common.c
@@ -18,6 +18,7 @@
*/
#define LIBERTY_WANT_SSL
+#define LIBERTY_WANT_ASYNC
#define LIBERTY_WANT_POLLER
#define LIBERTY_WANT_PROTO_IRC
@@ -40,9 +41,6 @@
return 0; \
BLOCK_END
-#define CONTAINER_OF(pointer, type, member) \
- (type *) ((char *) pointer - offsetof (type, member))
-
// --- To be moved to liberty --------------------------------------------------
static ssize_t
@@ -223,7 +221,7 @@ struct socks_connector
// You may destroy the connector object in these two main callbacks:
/// Connection has been successfully established
- void (*on_connected) (void *user_data, int socket);
+ void (*on_connected) (void *user_data, int socket, const char *hostname);
/// Failed to establish a connection to either target
void (*on_failure) (void *user_data);
@@ -594,9 +592,11 @@ socks_connector_on_timeout (struct socks_connector *self)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static void
-socks_connector_on_connected (void *user_data, int socket_fd)
+socks_connector_on_connected
+ (void *user_data, int socket_fd, const char *hostname)
{
set_blocking (socket_fd, false);
+ (void) hostname;
struct socks_connector *self = user_data;
self->socket_fd = socket_fd;
@@ -658,20 +658,8 @@ socks_connector_start (struct socks_connector *self)
connector->on_error = socks_connector_on_error;
connector->on_failure = socks_connector_on_failure;
- struct error *e = NULL;
- if (!connector_add_target (connector, self->hostname, self->service, &e))
- {
- if (self->on_error)
- self->on_error (self->user_data, e->message);
- error_free (e);
-
- socks_connector_destroy_connector (self);
- socks_connector_fail (self);
- return;
- }
-
+ connector_add_target (connector, self->hostname, self->service);
poller_timer_set (&self->timeout, 60 * 1000);
- connector_step (connector);
self->done = false;
self->bound_port = 0;
@@ -762,8 +750,10 @@ socks_connector_on_ready
int fd = self->socket_fd;
self->socket_fd = -1;
+
+ struct socks_target *target = self->targets_iter;
set_blocking (fd, true);
- self->on_connected (self->user_data, fd);
+ self->on_connected (self->user_data, fd, target->address_str);
}
else
// We've failed this target, let's try to move on
diff --git a/degesch.c b/degesch.c
index 59a60a0..7163098 100644
--- a/degesch.c
+++ b/degesch.c
@@ -1150,7 +1150,7 @@ enum transport_io_result
struct transport
{
/// Initialize the transport
- bool (*init) (struct server *s, struct error **e);
+ bool (*init) (struct server *s, const char *hostname, struct error **e);
/// Destroy the user data pointer
void (*cleanup) (struct server *s);
@@ -4492,7 +4492,7 @@ transport_tls_init_cert (struct server *s, SSL *ssl, struct error **e)
}
static bool
-transport_tls_init (struct server *s, struct error **e)
+transport_tls_init (struct server *s, const char *hostname, struct error **e)
{
ERR_clear_error ();
@@ -4519,6 +4519,12 @@ transport_tls_init (struct server *s, struct error **e)
if (!SSL_set_fd (ssl, s->socket))
goto error_ssl_3;
+ // Enable SNI, FWIW; literal IP addresses aren't allowed
+ struct in6_addr dummy;
+ if (!inet_pton (AF_INET, hostname, &dummy)
+ && !inet_pton (AF_INET6, hostname, &dummy))
+ SSL_set_tlsext_host_name (ssl, hostname);
+
struct transport_tls_data *data = xcalloc (1, sizeof *data);
data->ssl_ctx = ssl_ctx;
data->ssl = ssl;
@@ -4749,7 +4755,7 @@ irc_register (struct server *s)
}
static void
-irc_finish_connection (struct server *s, int socket)
+irc_finish_connection (struct server *s, int socket, const char *hostname)
{
struct app_context *ctx = s->ctx;
@@ -4766,7 +4772,7 @@ irc_finish_connection (struct server *s, int socket)
: &g_transport_plain;
struct error *e = NULL;
- if (s->transport->init && !s->transport->init (s, &e))
+ if (s->transport->init && !s->transport->init (s, hostname, &e))
{
log_server_error (s, s->buffer, "Connection failed: #s", e->message);
error_free (e);
@@ -4837,16 +4843,17 @@ irc_on_connector_failure (void *user_data)
}
static void
-irc_on_connector_connected (void *user_data, int socket)
+irc_on_connector_connected (void *user_data, int socket, const char *hostname)
{
struct server *s = user_data;
+ char *hostname_copy = xstrdup (hostname);
irc_destroy_connector (s);
- irc_finish_connection (s, socket);
+ irc_finish_connection (s, socket, hostname_copy);
+ free (hostname_copy);
}
-static bool
-irc_setup_connector (struct server *s,
- const struct str_vector *addresses, struct error **e)
+static void
+irc_setup_connector (struct server *s, const struct str_vector *addresses)
{
struct connector *connector = xmalloc (sizeof *connector);
connector_init (connector, &s->ctx->poller);
@@ -4858,31 +4865,12 @@ irc_setup_connector (struct server *s,
connector->on_connected = irc_on_connector_connected;
connector->on_failure = irc_on_connector_failure;
- bool at_least_one_address_succeeded = false;
for (size_t i = 0; i < addresses->len; i++)
{
char *host, *port;
irc_split_host_port (addresses->vector[i], &host, &port);
-
- struct error *error = NULL;
- if (connector_add_target (connector, host, port, &error))
- at_least_one_address_succeeded = true;
- else
- {
- log_server_error (s, s->buffer,
- "Address resolution failed for #&s: #s",
- format_host_port_pair (host, port), error->message);
- error_free (error);
- }
- }
- if (!at_least_one_address_succeeded)
- {
- error_set (e, "No address to connect to");
- return false;
+ connector_add_target (connector, host, port);
}
-
- connector_step (connector);
- return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -4963,7 +4951,7 @@ irc_initiate_connect (struct server *s)
struct error *e = NULL;
if (!irc_setup_connector_socks (s, &servers, &e) && !e)
- irc_setup_connector (s, &servers, &e);
+ irc_setup_connector (s, &servers);
str_vector_free (&servers);
diff --git a/kike.c b/kike.c
index c81d91c..b672339 100644
--- a/kike.c
+++ b/kike.c
@@ -3385,6 +3385,7 @@ irc_try_fetch_client (struct server_context *ctx, int listen_fd)
return true;
}
+ // FIXME: use async_getnameinfo() so that we never ever block here
char host[NI_MAXHOST] = "unknown", port[NI_MAXSERV] = "unknown";
int err = getnameinfo ((struct sockaddr *) &peer, peer_len,
host, sizeof host, port, sizeof port, NI_NUMERICSERV);
diff --git a/liberty b/liberty
index f6d7454..bc7e831 160000
--- a/liberty
+++ b/liberty
@@ -1 +1 @@
-Subproject commit f6d74544f82ce8186e73a6ba268c2bc56b3ce5c7
+Subproject commit bc7e83137ed2a14957e1b3feb5de658f8505ed57
diff --git a/zyklonb.c b/zyklonb.c
index a99038d..34e6e7e 100644
--- a/zyklonb.c
+++ b/zyklonb.c
@@ -1663,8 +1663,10 @@ struct irc_socks_data
};
static void
-irc_on_socks_connected (void *user_data, int socket)
+irc_on_socks_connected (void *user_data, int socket, const char *hostname)
{
+ (void) hostname;
+
struct irc_socks_data *data = user_data;
data->ctx->irc_fd = socket;
data->succeeded = true;
--
cgit v1.2.3-70-g09d2