[Libdexter-commits] SF.net SVN: libdexter: [371] libdexter/trunk
Brought to you by:
pkovacs
|
From: <pk...@us...> - 2007-06-10 03:36:40
|
Revision: 371
http://svn.sourceforge.net/libdexter/?rev=371&view=rev
Author: pkovacs
Date: 2007-06-09 20:36:38 -0700 (Sat, 09 Jun 2007)
Log Message:
-----------
Committing intermediate work on TLS.
Modified Paths:
--------------
libdexter/trunk/TODO
libdexter/trunk/dexter/dexter-network.c
libdexter/trunk/dexter/dexter-threadpool.h
libdexter/trunk/dexter/dexter-tls-gnutls.c
libdexter/trunk/dexter/dexter-tls.h
libdexter/trunk/programs/dexterd/dexterd.c
Modified: libdexter/trunk/TODO
===================================================================
--- libdexter/trunk/TODO 2007-06-09 22:29:28 UTC (rev 370)
+++ libdexter/trunk/TODO 2007-06-10 03:36:38 UTC (rev 371)
@@ -1,8 +1,17 @@
TLS work in progress
refs: RFC 2246 (TLS protcol), RFC 2487 (STARTTLS extention to SMTP)
-Libdexter will implement upward negociation for TLS, using a method similar to SMTP STARTTLS.
-Libdexter will use abstracted TLS commands to hide gnutls/openssl implementations.
+- 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.
- improve msgframer. perhaps add sscanf for complete protocol message on start
state and if \n in buffer.
Modified: libdexter/trunk/dexter/dexter-network.c
===================================================================
--- libdexter/trunk/dexter/dexter-network.c 2007-06-09 22:29:28 UTC (rev 370)
+++ libdexter/trunk/dexter/dexter-network.c 2007-06-10 03:36:38 UTC (rev 371)
@@ -333,6 +333,11 @@
guint flags,
GError **error)
{
+ GError *local_error = NULL;
+
+ g_return_val_if_fail (session != NULL, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
#ifdef G_ENABLE_DEBUG
g_message (G_STRFUNC);
g_message ("TLS cert file = %s", cert_file);
@@ -342,6 +347,62 @@
g_message ("TLS flags = %d", flags);
#endif
+ /* check if TLS already started */
+ if (session->tls)
+ {
+ g_set_error (error,
+ DEXTER_NETWORK_ERROR,
+ DEXTER_NETWORK_ERROR_FAILED,
+ "%s: TLS alreayd started", G_STRFUNC);
+ return FALSE;
+ }
+
+ /* create session TLS data */
+ session->tls = dexter_tls_new (role,
+ cert_file,
+ key_file,
+ trust_file,
+ crl_file,
+ flags,
+ &local_error);
+ if (local_error)
+ {
+ g_set_error (error,
+ DEXTER_NETWORK_ERROR,
+ DEXTER_NETWORK_ERROR_FAILED,
+ "%s: error creating TLS session: %s", G_STRFUNC, local_error->message);
+ g_clear_error (&local_error);
+ return FALSE;
+ }
+
+ /* TLS handshake */
+ dexter_tls_handshake (session->tls,
+ session->sockfd,
+ &local_error);
+ if (local_error)
+ {
+ g_set_error (error,
+ DEXTER_NETWORK_ERROR,
+ DEXTER_NETWORK_ERROR_FAILED,
+ "%s: error during TLS handshake: %s", G_STRFUNC, local_error->message);
+ g_clear_error (&local_error);
+ return FALSE;
+ }
+
+ /* verify peer */
+ dexter_tls_verify_peer (session->tls,
+ "localhost",
+ &local_error);
+ if (local_error)
+ {
+ g_set_error (error,
+ DEXTER_NETWORK_ERROR,
+ DEXTER_NETWORK_ERROR_FAILED,
+ "%s: error verifying TLS peer: %s", G_STRFUNC, local_error->message);
+ g_clear_error (&local_error);
+ return FALSE;
+ }
+
return TRUE;
}
#endif
@@ -651,8 +712,8 @@
#else
return _dexter_network_session_starttls (session,
DEXTER_TLS_ROLE_CLIENT,
+ cert_file,
key_file,
- cert_file,
trust_file,
crl_file,
0,
@@ -678,8 +739,8 @@
#else
return _dexter_network_session_starttls (session,
DEXTER_TLS_ROLE_SERVER,
+ cert_file,
key_file,
- cert_file,
trust_file,
crl_file,
1<<client_cert_flag,
@@ -756,8 +817,54 @@
g_return_val_if_fail (bufsize > 0, -1);
g_return_val_if_fail (error == NULL || *error == NULL, -1);
- if ((n = recv (session->sockfd, buffer, bufsize, flags)) == -1)
+ /* use TLS api if active */
+ if (session->tls)
{
+ GError *local_error = NULL;
+
+ n = dexter_tls_recv (session->tls, buffer, bufsize, &local_error);
+ if (local_error)
+ {
+ n = -1;
+ switch (local_error->code)
+ {
+ case DEXTER_TLS_ERROR_EINTR:
+ {
+ g_set_error (error,
+ DEXTER_NETWORK_ERROR,
+ DEXTER_NETWORK_ERROR_EINTR,
+ "%s: a signal occurred before any data was delivered",
+ G_STRFUNC);
+ g_clear_error (&local_error);
+ break;
+ }
+ case DEXTER_TLS_ERROR_EAGAIN:
+ {
+ g_set_error (error,
+ DEXTER_NETWORK_ERROR,
+ DEXTER_NETWORK_ERROR_EINTR,
+ "%s: operation would block",
+ G_STRFUNC);
+ g_clear_error (&local_error);
+ break;
+ }
+ default:
+ {
+ g_set_error (error,
+ DEXTER_NETWORK_ERROR,
+ DEXTER_NETWORK_ERROR_FAILED,
+ "%s: %s",
+ G_STRFUNC, local_error->message);
+ g_clear_error (&local_error);
+ break;
+ }
+ }
+ }
+ }
+
+ /* use ordinary network api */
+ else if ((n = recv (session->sockfd, buffer, bufsize, flags)) == -1)
+ {
if (errno == EINTR)
{
g_set_error (error,
@@ -806,8 +913,35 @@
while (total < remaining)
{
- if ((n = send (session->sockfd, buffer+total, bufsize, flags)) == -1)
+ /* use TLS api if active */
+ if (session->tls)
{
+ GError *local_error = NULL;
+ n = dexter_tls_send (session->tls, buffer+total, bufsize, &local_error);
+ if (local_error)
+ {
+ if ((local_error->code == DEXTER_TLS_ERROR_EINTR) ||
+ (local_error->code == DEXTER_TLS_ERROR_EAGAIN))
+ {
+ g_clear_error (&local_error);
+ continue;
+ }
+ else
+ {
+ g_set_error (error,
+ DEXTER_NETWORK_ERROR,
+ DEXTER_NETWORK_ERROR_FAILED,
+ "%s: %s",
+ G_STRFUNC, local_error->message);
+ g_clear_error (&local_error);
+ return -1;
+ }
+ }
+ }
+
+ /* use ordinary network api */
+ else if ((n = send (session->sockfd, buffer+total, bufsize, flags)) == -1)
+ {
if ((errno == EINTR) || (errno == EAGAIN))
continue;
else
@@ -839,6 +973,11 @@
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)
Modified: libdexter/trunk/dexter/dexter-threadpool.h
===================================================================
--- libdexter/trunk/dexter/dexter-threadpool.h 2007-06-09 22:29:28 UTC (rev 370)
+++ libdexter/trunk/dexter/dexter-threadpool.h 2007-06-10 03:36:38 UTC (rev 371)
@@ -31,8 +31,14 @@
/* defaults for g_thread_pool_new () */
#define DEFAULT_THREADPOOL_INIT_EXCLUSIVE TRUE
#define DEFAULT_THREADPOOL_INIT_MAX_THREADS 10 /* "ThreadPoolNumThreads" */
-/* defaults for g_thread_pool_exit () */
-#define DEFAULT_THREADPOOL_EXIT_IMMEDIATE TRUE
+/* defaults for g_thread_pool_exit ()
+ * Note: EXIT_IMMEDIATE changed to FALSE to allow all pending tasks to be processed
+ * before shutting down thread pool. The reason for doing this is to allow asynchronous
+ * callbacks to run and unref the objects they belong to, e.g. channels or servers.
+ * If we free the threadpool immediately with pending callbacks that are not run as
+ * a consequence, those object refs are not unwound and the objects do not finalize.
+ */
+#define DEFAULT_THREADPOOL_EXIT_IMMEDIATE FALSE
#define DEFAULT_THREADPOOL_EXIT_WAIT TRUE /* "ThreadPoolExitWait" */
Modified: libdexter/trunk/dexter/dexter-tls-gnutls.c
===================================================================
--- libdexter/trunk/dexter/dexter-tls-gnutls.c 2007-06-09 22:29:28 UTC (rev 370)
+++ libdexter/trunk/dexter/dexter-tls-gnutls.c 2007-06-10 03:36:38 UTC (rev 371)
@@ -142,8 +142,8 @@
dexter_tls_t *
dexter_tls_new (gboolean role,
+ const gchar *cert_file,
const gchar *key_file,
- const gchar *cert_file,
const gchar *trust_file,
const gchar *crl_file,
guint flags,
@@ -159,25 +159,25 @@
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
/* Require absolute paths on any files specified. */
- if (key_file && !g_path_is_absolute (key_file))
+ if (cert_file && *cert_file && !g_path_is_absolute (cert_file))
{
g_set_error (error,
DEXTER_TLS_ERROR,
DEXTER_TLS_ERROR_FILE,
"%s: %s is not an absolute path",
- G_STRFUNC, key_file);
+ G_STRFUNC, cert_file);
return NULL;
}
- if (cert_file && !g_path_is_absolute (cert_file))
+ if (key_file && *key_file && !g_path_is_absolute (key_file))
{
g_set_error (error,
DEXTER_TLS_ERROR,
DEXTER_TLS_ERROR_FILE,
"%s: %s is not an absolute path",
- G_STRFUNC, cert_file);
+ G_STRFUNC, key_file);
return NULL;
}
- if (trust_file && !g_path_is_absolute (trust_file))
+ if (trust_file && *trust_file && !g_path_is_absolute (trust_file))
{
g_set_error (error,
DEXTER_TLS_ERROR,
@@ -186,13 +186,14 @@
G_STRFUNC, trust_file);
return NULL;
}
- if (crl_file && !g_path_is_absolute (crl_file))
+ if (crl_file && *crl_file && !g_path_is_absolute (crl_file))
{
g_set_error (error,
DEXTER_TLS_ERROR,
DEXTER_TLS_ERROR_FILE,
"%s: %s is not an absolute path",
G_STRFUNC, crl_file);
+ return NULL;
}
tls = g_slice_new0 (dexter_tls_t);
@@ -242,7 +243,7 @@
}
/* Set x509 trust file */
- if (trust_file)
+ if (trust_file && *trust_file)
{
/* On success, returns number of certs processed, so we want a non-negative back */
if ((gnutls_error =
@@ -261,7 +262,7 @@
}
/* Set x509 cert revocation list file */
- if (crl_file)
+ if (crl_file && *crl_file)
{
/* On success, returns number of certs processed, so we want a non-negative back */
if ((gnutls_error =
@@ -280,7 +281,7 @@
}
/* Set x509 key and cert files */
- if (key_file && cert_file)
+ if (key_file && *key_file && cert_file && *cert_file)
{
if ((gnutls_error =
gnutls_certificate_set_x509_key_file (tls->cred, cert_file, key_file, GNUTLS_X509_FMT_PEM)) < 0)
@@ -512,7 +513,7 @@
}
- /* Check hostname on first cert */
+ /* Check hostname on first cert
if ((iter==0) && (gnutls_x509_crt_check_hostname (cert, canonical_hostname) != 0))
{
g_set_error (error,
@@ -524,6 +525,7 @@
gnutls_x509_crt_deinit (cert);
return FALSE;
}
+ */
/* Fetch cert activation time */
if ((activation_time = gnutls_x509_crt_get_activation_time (cert)) < 0)
@@ -620,7 +622,7 @@
DEXTER_TLS_ERROR_EINTR,
"%s: a signal occurred before any data was delivered",
G_STRFUNC);
- return DEXTER_TLS_ERROR_EINTR;
+ return -1;
}
if (sz == GNUTLS_E_AGAIN)
{
@@ -629,7 +631,7 @@
DEXTER_TLS_ERROR_EAGAIN,
"%s: operation would block",
G_STRFUNC);
- return DEXTER_TLS_ERROR_EAGAIN;
+ return -1;
}
if (sz < 0)
{
@@ -638,6 +640,7 @@
DEXTER_TLS_ERROR_FAILED,
"%s: error occurred during recv: %s",
G_STRFUNC, gnutls_strerror (sz));
+ return -1;
}
return sz;
@@ -665,7 +668,7 @@
DEXTER_TLS_ERROR_EINTR,
"%s: a signal occurred before any data was transmitted",
G_STRFUNC);
- return DEXTER_TLS_ERROR_EINTR;
+ return -1;
}
if (sz == GNUTLS_E_AGAIN)
{
@@ -674,7 +677,7 @@
DEXTER_TLS_ERROR_EAGAIN,
"%s: operation would block",
G_STRFUNC);
- return DEXTER_TLS_ERROR_EAGAIN;
+ return -1;
}
if (sz < 0)
{
@@ -683,12 +686,26 @@
DEXTER_TLS_ERROR_FAILED,
"%s: error occurred during send: %s",
G_STRFUNC, gnutls_strerror (sz));
+ return -1;
}
return sz;
}
+void
+dexter_tls_close (dexter_tls_t *tls)
+{
+ g_return_if_fail (tls != NULL);
+
+#ifdef G_ENABLE_DEBUG
+ g_message (G_STRFUNC);
+#endif
+
+ gnutls_bye (tls->session, GNUTLS_SHUT_WR);
+}
+
+
void
dexter_tls_free (dexter_tls_t *tls)
{
Modified: libdexter/trunk/dexter/dexter-tls.h
===================================================================
--- libdexter/trunk/dexter/dexter-tls.h 2007-06-09 22:29:28 UTC (rev 370)
+++ libdexter/trunk/dexter/dexter-tls.h 2007-06-10 03:36:38 UTC (rev 371)
@@ -57,8 +57,8 @@
gboolean dexter_tls_library_init (GError **error) G_GNUC_INTERNAL;
dexter_tls_t *dexter_tls_new (gboolean role,
+ const gchar *cert_file,
const gchar *key_file,
- const gchar *cert_file,
const gchar *trust_file,
const gchar *crl_file,
guint flags,
@@ -82,6 +82,8 @@
size_t bufsize,
GError **error) G_GNUC_INTERNAL;
+void dexter_tls_close (dexter_tls_t *tls) G_GNUC_INTERNAL;
+
void dexter_tls_free (dexter_tls_t *tls) G_GNUC_INTERNAL;
void dexter_tls_library_exit (void) G_GNUC_INTERNAL;
Modified: libdexter/trunk/programs/dexterd/dexterd.c
===================================================================
--- libdexter/trunk/programs/dexterd/dexterd.c 2007-06-09 22:29:28 UTC (rev 370)
+++ libdexter/trunk/programs/dexterd/dexterd.c 2007-06-10 03:36:38 UTC (rev 371)
@@ -166,6 +166,7 @@
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);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|