[Libdexter-commits] SF.net SVN: libdexter: [372] libdexter/trunk
Brought to you by:
pkovacs
|
From: <pk...@us...> - 2007-06-11 02:30:34
|
Revision: 372
http://svn.sourceforge.net/libdexter/?rev=372&view=rev
Author: pkovacs
Date: 2007-06-10 19:30:30 -0700 (Sun, 10 Jun 2007)
Log Message:
-----------
Committing intermediate work on TLS.
Modified Paths:
--------------
libdexter/trunk/TODO
libdexter/trunk/dexter/dexter-channel.c
libdexter/trunk/dexter/dexter-network.c
libdexter/trunk/dexter/dexter-network.h
libdexter/trunk/dexter/dexter-server-internal.h
libdexter/trunk/dexter/dexter-server.c
libdexter/trunk/dexter/dexter-tls-gnutls.c
libdexter/trunk/dexter/dexter-tls.h
libdexter/trunk/docs/reference/dexter/config-example.sgml
libdexter/trunk/docs/reference/dexter/config-structure.sgml
libdexter/trunk/programs/dexterd/dexterd.c
Modified: libdexter/trunk/TODO
===================================================================
--- libdexter/trunk/TODO 2007-06-10 03:36:38 UTC (rev 371)
+++ libdexter/trunk/TODO 2007-06-11 02:30:30 UTC (rev 372)
@@ -1,17 +1,14 @@
TLS work in progress
refs: RFC 2246 (TLS protcol), RFC 2487 (STARTTLS extention to SMTP)
-- when server starts with tls permitted, seed the tls params *then*
- and not during deter_tls_new () as client is connecting for first time.
-- create daily event that discards/updates tls seed params, completely
- eliminating the seeding and client connecting association.
- create new config items: ChannelTLSVerifyServerHostname/ServerTLSVerifyClientHostname
to optionally verify hostname on first cert in the chain. Useful for situations
where the peer does not have a reliable DNS entry.
-- during TLS handshake/verify, loop on EAGAIN/EINTR network errors
- servercomm changes to *require* tls when that is indicated.
- dexter_tls_recv: 'A TLS packet with unexpected length was received'
when breaking off client or server. There should not be any error.
+- syslog certificate failures.
+- add DEXTER_NETWORK_ERROR_CERTIFICATE.
- improve msgframer. perhaps add sscanf for complete protocol message on start
state and if \n in buffer.
Modified: libdexter/trunk/dexter/dexter-channel.c
===================================================================
--- libdexter/trunk/dexter/dexter-channel.c 2007-06-10 03:36:38 UTC (rev 371)
+++ libdexter/trunk/dexter/dexter-channel.c 2007-06-11 02:30:30 UTC (rev 372)
@@ -807,9 +807,11 @@
{
/* read bytes from server and frame them into dexter messages */
msgbytes=dexter_network_session_recv (channel->session, recvbuf, channel->recvbufsize, 0, &local_error);
- if (local_error && local_error->code==DEXTER_NETWORK_ERROR_EINTR)
+ if (local_error &&
+ ((local_error->code==DEXTER_NETWORK_ERROR_EINTR) ||
+ (local_error->code==DEXTER_NETWORK_ERROR_EAGAIN)))
{
- /* non-fatal EINTR */
+ /* non-fatal EINTR/EAGAIN */
g_clear_error (&local_error);
continue;
}
@@ -1117,7 +1119,7 @@
channel->thread = NULL;
}
- dexter_network_session_close (channel->session, NULL);
+ dexter_network_session_close (channel->session);
dexter_channel_event (channel, DEXTER_CHANNEL_EVENT_CLOSED);
g_object_unref (channel);
Modified: libdexter/trunk/dexter/dexter-network.c
===================================================================
--- libdexter/trunk/dexter/dexter-network.c 2007-06-10 03:36:38 UTC (rev 371)
+++ libdexter/trunk/dexter/dexter-network.c 2007-06-11 02:30:30 UTC (rev 372)
@@ -963,44 +963,19 @@
}
-gboolean
-dexter_network_session_close (dexter_network_session_t *session,
- GError **error)
+void
+dexter_network_session_close (dexter_network_session_t *session)
{
- int ret;
+ g_return_if_fail (session != NULL);
+ g_return_if_fail (session->sockfd > 0);
- g_return_val_if_fail (session != NULL, FALSE);
- g_return_val_if_fail (session->sockfd > 0, FALSE);
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
#ifdef HAVE_TLS
if (session->tls)
dexter_tls_close (session->tls);
#endif
- if ((ret = close (session->sockfd)) == -1)
- {
- if (errno == EINTR)
- {
- g_set_error (error,
- DEXTER_NETWORK_ERROR,
- DEXTER_NETWORK_ERROR_EINTR,
- "%s: close operation was interrupted by a signal",
- G_STRFUNC);
- return FALSE;
- }
- else
- {
- g_set_error (error,
- DEXTER_NETWORK_ERROR,
- DEXTER_NETWORK_ERROR_FAILED,
- "%s: %s",
- G_STRFUNC, g_strerror (errno));
- return FALSE;
- }
- }
-
- return TRUE;
+ shutdown (session->sockfd, SHUT_RDWR);
+ close (session->sockfd);
}
Modified: libdexter/trunk/dexter/dexter-network.h
===================================================================
--- libdexter/trunk/dexter/dexter-network.h 2007-06-10 03:36:38 UTC (rev 371)
+++ libdexter/trunk/dexter/dexter-network.h 2007-06-11 02:30:30 UTC (rev 372)
@@ -111,8 +111,7 @@
int flags,
GError **error) G_GNUC_INTERNAL;
-gboolean dexter_network_session_close (dexter_network_session_t *session,
- GError **error) G_GNUC_INTERNAL;
+void dexter_network_session_close (dexter_network_session_t *session) G_GNUC_INTERNAL;
void dexter_network_session_free (dexter_network_session_t *session) G_GNUC_INTERNAL;
Modified: libdexter/trunk/dexter/dexter-server-internal.h
===================================================================
--- libdexter/trunk/dexter/dexter-server-internal.h 2007-06-10 03:36:38 UTC (rev 371)
+++ libdexter/trunk/dexter/dexter-server-internal.h 2007-06-11 02:30:30 UTC (rev 372)
@@ -33,6 +33,9 @@
#define DEFAULT_SERVER_SOCKET_OPTIONS NULL
#define DEFAULT_SERVER_MAX_CLIENTS 5
#define DEFAULT_SERVER_RECV_BUFFER_SIZE 512
+#ifdef HAVE_TLS
+#define DEFAULT_SERVER_TLS_SUPPORT_FLAG DEXTER_SERVER_TLS_SUPPORT_NONE
+#endif
#define DEXTER_TYPE_SERVER (dexter_server_get_type ())
Modified: libdexter/trunk/dexter/dexter-server.c
===================================================================
--- libdexter/trunk/dexter/dexter-server.c 2007-06-10 03:36:38 UTC (rev 371)
+++ libdexter/trunk/dexter/dexter-server.c 2007-06-11 02:30:30 UTC (rev 372)
@@ -41,7 +41,7 @@
*
* Several settings in the configuration file control the default behavior of
* Libdexter server objects, including default host name/ip, listening service/port,
- * socket options, etc.
+ * socket options, TLS settings, etc.
*
* Applications should stop any running servers when done with dexter_server_stop().
* You should then free the server objects as a last step with dexter_server_free().
@@ -70,6 +70,9 @@
#include <dexter-network.h>
#include <dexter-msgframer.h>
#include <dexter-servercomm.h>
+#ifdef HAVE_TLS
+#include <dexter-tls.h>
+#endif
#include <dexter-private.h>
#include <dexter-alias.h>
@@ -87,11 +90,13 @@
static GError *dexter_server_convert_network_error (GError **network_error);
#ifdef HAVE_TLS
static DexterServerTLSSettings
- *dexter_server_tls_settings_new (DexterServerTLSSupportFlag support_flag,
+ *dexter_server_tls_settings_new (DexterServerTLSSupportFlag support_flag,
DexterServerTLSStartCallback starttls_callback);
static DexterServerTLSSettings
*dexter_server_tls_settings_dup (const DexterServerTLSSettings *source);
static void dexter_server_tls_settings_free (DexterServerTLSSettings *tls_settings);
+ /* refresh tls seed in event loop */
+static gboolean _tls_seed_refresh_func (gpointer unused);
#endif
/* accept loop runs in a thread */
@@ -102,11 +107,17 @@
#ifdef HAVE_LIBWRAP
-static struct request_info _request; /* client request for libwrap */
+static struct request_info _request; /* client request for libwrap */
static gboolean _request_initialized = FALSE;
-G_LOCK_DEFINE_STATIC (_request); /* assume libwrap is not thread-safe */
+G_LOCK_DEFINE_STATIC (_request); /* assume libwrap is not thread-safe */
#endif
+#ifdef HAVE_TLS
+static GSource *tls_seed_refresh_source = NULL; /* event source to refresh tls seed periodically */
+G_LOCK_DEFINE_STATIC (_tls_seed_refresh_mutex); /* mutex for tls seed refresh operations */
+static volatile int tls_server_count = 0; /* tls seed refresh source destroyed when count 0 */
+#endif
+
struct _DexterServer
{
GObject parent;
@@ -131,7 +142,7 @@
gint max_clients; /* max number of simultaneous client connections */
int recvbufsize; /* receive buffer size for service sockets */
-#if HAVE_TLS
+#ifdef HAVE_TLS
DexterServerTLSSettings
*tls_settings; /* TLS settings from dexter_server_start () */
#endif
@@ -428,9 +439,22 @@
g_slice_free (DexterServerTLSSettings, tls_settings);
}
+
+
+static gboolean
+_tls_seed_refresh_func (gpointer unused)
+{
+#ifdef G_ENABLE_DEBUG
+ g_message (G_STRFUNC);
#endif
+ /* seed the TLS parameters for certificate servers */
+ dexter_tls_server_seed ();
+ return TRUE;
+}
+#endif
+
static void
_server_thread_func (DexterServer *server)
{
@@ -667,9 +691,11 @@
{
/* read bytes from client and frame them into dexter messages */
msgbytes=dexter_network_session_recv (session, recvbuf, sd->recvbufsize, 0, &local_error);
- if (local_error && local_error->code==DEXTER_NETWORK_ERROR_EINTR)
+ if (local_error &&
+ ((local_error->code==DEXTER_NETWORK_ERROR_EINTR) ||
+ (local_error->code==DEXTER_NETWORK_ERROR_EAGAIN)))
{
- /* non-fatal EINTR */
+ /* non-fatal EINTR/EAGAIN */
g_clear_error (&local_error);
continue;
}
@@ -729,7 +755,7 @@
}
while ((!done) && (dexter_get_state () == DEXTER_STATE_UP));
- dexter_network_session_close (session, NULL);
+ dexter_network_session_close (session);
dexter_network_session_free (session);
/* decrement client count. thread that decrements count to zero frees the counter. */
@@ -852,9 +878,13 @@
* program. The server will accept connections immediately and continue to accept connections
* until dexter_server_stop() is called.
*
- * If @tls_settings is supplied, those settings will be used to control how the server runs TLS.
- * If %NULL, the server will not support TLS services.
+ * On TLS-enabled installations, @tls_settings may be supplied to control how the server support TLS.
+ * If %NULL is indicated, the server will use settings from the config file, e.g. ServerTLSSupportFlag,
+ * to determine the level of TLS support.
*
+ * On non-TLS installations, you <emphasis>must</emphasis> specify %NULL for @tls_settings,
+ * otherwise @error will be set to @DEXTER_SERVER_ERROR_TLS_NOT_ENABLED.
+ *
* Returns: #gboolean indicating success or failure.
**/
gboolean
@@ -870,23 +900,60 @@
g_return_val_if_fail (DEXTER_IS_SERVER (server), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+ g_return_val_if_fail (tls_settings == NULL
#ifdef HAVE_TLS
- g_return_val_if_fail (tls_settings == NULL ||
- tls_settings->support_flag == DEXTER_SERVER_TLS_SUPPORT_NONE ||
- tls_settings->support_flag == DEXTER_SERVER_TLS_SUPPORT_AVAILABLE ||
- tls_settings->support_flag == DEXTER_SERVER_TLS_SUPPORT_REQUIRED, FALSE);
-#else
- g_return_val_if_fail (tls_settings == NULL, FALSE);
+ || tls_settings->support_flag == DEXTER_SERVER_TLS_SUPPORT_NONE
+ || tls_settings->support_flag == DEXTER_SERVER_TLS_SUPPORT_AVAILABLE
+ || tls_settings->support_flag == DEXTER_SERVER_TLS_SUPPORT_REQUIRED
#endif
+ , FALSE);
+#ifdef HAVE_TLS
+ dexter_server_tls_settings_free (server->tls_settings);
if (tls_settings)
-#ifdef HAVE_TLS
{
- dexter_server_tls_settings_free (server->tls_settings);
server->tls_settings = dexter_server_tls_settings_dup (tls_settings);
+
}
+ else /* if (tls_settings) */
+ {
+ /* grab default support flag from config */
+ gint tmp_support_flag;
+
+ server->tls_settings = dexter_server_tls_settings_new (DEXTER_SERVER_TLS_SUPPORT_NONE, NULL);
+ if (!dexter_config_get_integer (__ICONFIG, "Main", "ServerTLSSupportFlag",
+ &tmp_support_flag, NULL))
+ {
+ server->tls_settings->support_flag = DEFAULT_SERVER_TLS_SUPPORT_FLAG;
+ g_warning ("%s: using default %d for ServerTLSSupportFlag",
+ G_STRFUNC, server->tls_settings->support_flag);
+ }
+ else
+ {
+ server->tls_settings->support_flag = (DexterServerTLSSupportFlag) tmp_support_flag;
+ }
+ }
+
+ if ((server->tls_settings->support_flag == DEXTER_SERVER_TLS_SUPPORT_AVAILABLE) ||
+ (server->tls_settings->support_flag == DEXTER_SERVER_TLS_SUPPORT_REQUIRED))
+ {
+ G_LOCK (_tls_seed_refresh_mutex);
+
+ if (!tls_seed_refresh_source)
+ {
+ /* no refresh source is running in the event loop, so we know the the TLS parameters
+ * have never yet been seeded, i.e. this is the first TLS-enabled server to be started.
+ * seed the parameters for the first time now. */
+ dexter_tls_server_seed ();
+ }
+
+ G_UNLOCK (_tls_seed_refresh_mutex);
+ }
#else
+
+ if (tls_settings)
{
+ /* specifying tls_settings parameter on installations without TLS is not permitted */
g_set_error (error,
DEXTER_SERVER_ERROR,
DEXTER_SERVER_ERROR_TLS_NOT_ENABLED,
@@ -940,6 +1007,34 @@
dexter_server_set_state (server, DEXTER_SERVER_STATE_STARTED);
+#ifdef HAVE_TLS
+ if ((server->tls_settings->support_flag == DEXTER_SERVER_TLS_SUPPORT_AVAILABLE) ||
+ (server->tls_settings->support_flag == DEXTER_SERVER_TLS_SUPPORT_REQUIRED))
+ {
+ G_LOCK (_tls_seed_refresh_mutex);
+
+ /* if not yet started, start a refresh source func to reseed TLS parameters daily */
+ if (!tls_seed_refresh_source)
+ {
+ tls_seed_refresh_source = g_timeout_source_new (1000 /* millisec/sec */ *
+ 60 /* sec/min */ *
+ 60 /* min/hour */ *
+ 24 /* hour/day */); /* millisec/day */
+ g_source_set_callback (tls_seed_refresh_source,
+ (GSourceFunc) _tls_seed_refresh_func,
+ NULL,
+ NULL);
+ g_source_set_can_recurse (tls_seed_refresh_source, FALSE);
+ dexter_event_loop_source_attach (__EVENTLOOP, tls_seed_refresh_source);
+ }
+
+ G_UNLOCK (_tls_seed_refresh_mutex);
+
+ /* increment count of TLS-enabled servers */
+ g_atomic_int_add (&tls_server_count, 1);
+ }
+#endif /* HAVE_TLS */
+
g_object_unref (server);
return TRUE;
@@ -992,6 +1087,18 @@
}
dexter_server_set_state (server, DEXTER_SERVER_STATE_STOPPED);
+#ifdef HAVE_TLS
+ if (g_atomic_int_dec_and_test (&tls_server_count))
+ {
+ /* no more TLS servers running, so stop the TLS parameter refresh source */
+ G_LOCK (_tls_seed_refresh_mutex);
+ g_source_destroy (tls_seed_refresh_source);
+ g_source_unref (tls_seed_refresh_source);
+ tls_seed_refresh_source=NULL;
+ G_UNLOCK (_tls_seed_refresh_mutex);
+ }
+#endif
+
g_object_unref (server);
return TRUE;
Modified: libdexter/trunk/dexter/dexter-tls-gnutls.c
===================================================================
--- libdexter/trunk/dexter/dexter-tls-gnutls.c 2007-06-10 03:36:38 UTC (rev 371)
+++ libdexter/trunk/dexter/dexter-tls-gnutls.c 2007-06-11 02:30:30 UTC (rev 372)
@@ -35,11 +35,8 @@
#define DH_BITS 1024
-static void test_and_generate_dh_params (void);
-
/* We will discard and regenerate the dh_params once a day */
static gnutls_dh_params_t _dh_params;
-static GDate _dh_params_date;
static gboolean _dh_params_initialized = FALSE;
G_LOCK_DEFINE_STATIC (_dh_params_mutex);
G_LOCK_DEFINE_STATIC (_tls_lib_mutex);
@@ -60,34 +57,6 @@
};
-void test_and_generate_dh_params (void)
-{
- /* Generate static dh params, or regenerate them if one day has since past */
- GTimeVal current_time;
- GDate current_date;
-
- g_get_current_time (¤t_time);
- g_date_set_time_val (¤t_date, ¤t_time);
-
- G_LOCK (_dh_params_mutex);
-
- if (!_dh_params_initialized)
- {
- g_date_clear (&_dh_params_date, 1);
- gnutls_dh_params_init (&_dh_params);
- _dh_params_initialized=TRUE;
- }
-
- if (!g_date_valid (&_dh_params_date) || g_date_days_between (&_dh_params_date, ¤t_date) > 0)
- {
- gnutls_dh_params_generate2 (_dh_params, DH_BITS);
- g_date_set_time_val (&_dh_params_date, ¤t_time);
- }
-
- G_UNLOCK (_dh_params_mutex);
-}
-
-
gboolean
dexter_tls_library_init (GError **error)
{
@@ -140,6 +109,27 @@
}
+void
+dexter_tls_server_seed (void)
+{
+#ifdef G_ENABLE_DEBUG
+ g_message (G_STRFUNC);
+#endif
+ /* Generate dh params for certificate servers */
+ G_LOCK (_dh_params_mutex);
+
+ if (!_dh_params_initialized)
+ {
+ gnutls_dh_params_init (&_dh_params);
+ _dh_params_initialized=TRUE;
+ }
+
+ gnutls_dh_params_generate2 (_dh_params, DH_BITS);
+
+ G_UNLOCK (_dh_params_mutex);
+}
+
+
dexter_tls_t *
dexter_tls_new (gboolean role,
const gchar *cert_file,
@@ -315,9 +305,6 @@
/* Server-side only */
if (role==DEXTER_TLS_ROLE_SERVER)
{
- /* Check for possible regeneration of dh params */
- test_and_generate_dh_params ();
-
/* Set up cert request from client */
if (flags & DEXTER_TLS_CERT_REQUEST)
gnutls_certificate_server_set_request (tls->session, GNUTLS_CERT_REQUEST);
@@ -354,25 +341,14 @@
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
gnutls_transport_set_ptr (tls->session, (gnutls_transport_ptr_t) sockfd);
- gnutls_error = gnutls_handshake (tls->session);
- if (gnutls_error == GNUTLS_E_INTERRUPTED)
+
+ do
{
- g_set_error (error,
- DEXTER_TLS_ERROR,
- DEXTER_TLS_ERROR_EINTR,
- "%s: a signal occurred during handshake",
- G_STRFUNC);
- return FALSE;
+ gnutls_error = gnutls_handshake (tls->session);
+ g_usleep (20); /* avoid tight loop */
}
- if (gnutls_error == GNUTLS_E_AGAIN)
- {
- g_set_error (error,
- DEXTER_TLS_ERROR,
- DEXTER_TLS_ERROR_EAGAIN,
- "%s: operation would block",
- G_STRFUNC);
- return FALSE;
- }
+ while ((gnutls_error == GNUTLS_E_AGAIN) || (gnutls_error == GNUTLS_E_INTERRUPTED));
+
if (gnutls_error < 0)
{
g_set_error (error,
@@ -702,7 +678,7 @@
g_message (G_STRFUNC);
#endif
- gnutls_bye (tls->session, GNUTLS_SHUT_WR);
+ gnutls_bye (tls->session, GNUTLS_SHUT_RDWR);
}
Modified: libdexter/trunk/dexter/dexter-tls.h
===================================================================
--- libdexter/trunk/dexter/dexter-tls.h 2007-06-10 03:36:38 UTC (rev 371)
+++ libdexter/trunk/dexter/dexter-tls.h 2007-06-11 02:30:30 UTC (rev 372)
@@ -56,6 +56,8 @@
gboolean dexter_tls_library_init (GError **error) G_GNUC_INTERNAL;
+void dexter_tls_server_seed (void) G_GNUC_INTERNAL;
+
dexter_tls_t *dexter_tls_new (gboolean role,
const gchar *cert_file,
const gchar *key_file,
Modified: libdexter/trunk/docs/reference/dexter/config-example.sgml
===================================================================
--- libdexter/trunk/docs/reference/dexter/config-example.sgml 2007-06-10 03:36:38 UTC (rev 371)
+++ libdexter/trunk/docs/reference/dexter/config-example.sgml 2007-06-11 02:30:30 UTC (rev 372)
@@ -34,6 +34,7 @@
ServerTLSTrustFile=/etc/ssl/libdexter/server-trust.pem
ServerTLSCrlFile=/etc/ssl/libdexter/server-crl.pem
ServerTLSClientCertFlag=1
+ServerTLSSupportFlag=1
ChannelHost=0.0.0.0
ChannelService=3663
Modified: libdexter/trunk/docs/reference/dexter/config-structure.sgml
===================================================================
--- libdexter/trunk/docs/reference/dexter/config-structure.sgml 2007-06-10 03:36:38 UTC (rev 371)
+++ libdexter/trunk/docs/reference/dexter/config-structure.sgml 2007-06-11 02:30:30 UTC (rev 372)
@@ -181,6 +181,16 @@
</listitem>
</varlistentry>
<varlistentry>
+ <term><emphasis role="bold">ServerTLSSupportFlag</emphasis></term>
+ <listitem>
+ <para>
+ <userinput>[n=0,1 or 2, default: 0]</userinput> Flag indicating server support for TLS.
+ See <ulink url="libdexter-Servers.html#DexterServerTLSSupportFlag">
+ DexterServerTLSSupportFlag</ulink>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term><emphasis role="bold">ChannelHost</emphasis></term>
<listitem>
<para>
Modified: libdexter/trunk/programs/dexterd/dexterd.c
===================================================================
--- libdexter/trunk/programs/dexterd/dexterd.c 2007-06-10 03:36:38 UTC (rev 371)
+++ libdexter/trunk/programs/dexterd/dexterd.c 2007-06-11 02:30:30 UTC (rev 372)
@@ -72,7 +72,6 @@
{
GOptionContext *context;
DexterServer *server;
- DexterServerTLSSettings tls_settings;
GError *err = NULL;
/* Abort on any warning within this program's domain */
@@ -163,14 +162,7 @@
if (!(server = dexter_server_new (NULL, NULL, NULL)))
g_warning ("unable to create server");
- tls_settings.starttls_callback = NULL;
-#ifdef HAVE_TLS
- tls_settings.support_flag = DEXTER_SERVER_TLS_SUPPORT_AVAILABLE;
- tls_settings.starttls_callback = NULL;
- dexter_server_start (server, &tls_settings, &err);
-#else
dexter_server_start (server, NULL, &err);
-#endif
if (err)
g_warning (err->message);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|