From bebb2840c4b2d8dab162a707e7ebe6b9d4e3734c Mon Sep 17 00:00:00 2001 From: Stefan Becker Date: Sun, 13 Nov 2011 15:38:05 +0200 Subject: [PATCH] tls-dsk: flesh out state transitions Also started on TLS message debugging code. --- src/core/sip-sec-tls-dsk.c | 34 ++++++++++++++++++++++++++------- src/core/sip-transport.c | 19 +++++++++++++++---- src/core/sipe-tls.c | 47 ++++++++++++++++++++++++++++++++++++++++++++-- src/core/sipe-tls.h | 5 +++++ 4 files changed, 92 insertions(+), 13 deletions(-) diff --git a/src/core/sip-sec-tls-dsk.c b/src/core/sip-sec-tls-dsk.c index e97ec3f7..83b58cd8 100644 --- a/src/core/sip-sec-tls-dsk.c +++ b/src/core/sip-sec-tls-dsk.c @@ -43,7 +43,8 @@ enum tls_dsk_state { TLS_DSK_STATE_START, TLS_DSK_STATE_SERVER_HELLO, TLS_DSK_STATE_FINISHED, - TLS_DSK_STATE_COMPLETED + TLS_DSK_STATE_COMPLETED, + TLS_DSK_STATE_FAILED }; typedef struct _context_tls_dsk { @@ -86,25 +87,44 @@ sip_sec_init_sec_context__tls_dsk(SipSecContext context, SIPE_UNUSED_PARAMETER const char *service_name) { context_tls_dsk ctx = (context_tls_dsk) context; - sip_uint32 ret = SIP_SEC_E_INTERNAL_ERROR; - /* temporary */ - (void)in_buff; + out_buff->value = NULL; switch (ctx->state) { case TLS_DSK_STATE_START: - out_buff->value = sipe_tls_client_hello(&out_buff->length); ctx->state = TLS_DSK_STATE_SERVER_HELLO; - ret = SIP_SEC_E_OK; + + out_buff->value = sipe_tls_client_hello(&out_buff->length); break; case TLS_DSK_STATE_SERVER_HELLO: + ctx->state = TLS_DSK_STATE_FINISHED; + + out_buff->value = sipe_tls_server_hello(in_buff.value, + in_buff.length, + &out_buff->length); + break; + case TLS_DSK_STATE_FINISHED: + if (sipe_tls_finished(in_buff.value, + in_buff.length)) { + /* Authentication is completed */ + ctx->state = TLS_DSK_STATE_COMPLETED; + ctx->common.is_ready = TRUE; + } else { + ctx->state = TLS_DSK_STATE_FAILED; + } + break; + case TLS_DSK_STATE_COMPLETED: + case TLS_DSK_STATE_FAILED: + /* This should not happen */ + ctx->state = TLS_DSK_STATE_FAILED; break; } - return(ret); + return(((ctx->state == TLS_DSK_STATE_COMPLETED) || out_buff->value) ? + SIP_SEC_E_OK : SIP_SEC_E_INTERNAL_ERROR); } static sip_uint32 diff --git a/src/core/sip-transport.c b/src/core/sip-transport.c index 2f8e7a3e..d5fc35e3 100644 --- a/src/core/sip-transport.c +++ b/src/core/sip-transport.c @@ -203,6 +203,7 @@ static gchar *initialize_auth_context(struct sipe_core_private *sipe_private, gchar *ret; gchar *gssapi_data = NULL; gchar *sign_str; + gchar *gssapi_str; gchar *opaque_str; gchar *version_str; @@ -215,7 +216,9 @@ static gchar *initialize_auth_context(struct sipe_core_private *sipe_private, &gssapi_data, &auth->expires); - if ((status < 0) || !gssapi_data) { + /* If authentication is completed gssapi_data can be NULL */ + if ((status < 0) || + !(sip_sec_context_is_ready(auth->gssapi_context) || gssapi_data)) { SIPE_DEBUG_ERROR_NOFORMAT("initialize_auth_context: security context continuation failed"); g_free(gssapi_data); sipe_backend_connection_error(SIPE_CORE_PUBLIC, @@ -296,16 +299,24 @@ static gchar *initialize_auth_context(struct sipe_core_private *sipe_private, sign_str = g_strdup(""); } + if (gssapi_data) { + gssapi_str = g_strdup_printf(", gssapi-data=\"%s\"", + gssapi_data); + g_free(gssapi_data); + } else { + gssapi_str = g_strdup(""); + } + opaque_str = auth->opaque ? g_strdup_printf(", opaque=\"%s\"", auth->opaque) : g_strdup(""); version_str = auth_header_version(auth); - ret = g_strdup_printf("%s qop=\"auth\"%s, realm=\"%s\", targetname=\"%s\", gssapi-data=\"%s\"%s%s", + ret = g_strdup_printf("%s qop=\"auth\"%s, realm=\"%s\", targetname=\"%s\"%s%s%s", auth_type_to_protocol[auth->type], opaque_str, auth->realm, auth->target, - gssapi_data, version_str, sign_str); + gssapi_str, version_str, sign_str); g_free(version_str); g_free(opaque_str); + g_free(gssapi_str); g_free(sign_str); - g_free(gssapi_data); return(ret); } diff --git a/src/core/sipe-tls.c b/src/core/sipe-tls.c index 29f8e79a..2d767124 100644 --- a/src/core/sipe-tls.c +++ b/src/core/sipe-tls.c @@ -38,9 +38,33 @@ #include +#include "sipe-backend.h" #include "sipe-cert-crypto.h" #include "sipe-tls.h" +/* + * TLS message debugging + */ +static void message_debug(const guchar *bytes, + gsize length, + gboolean incoming) +{ + if (sipe_backend_debug_enabled()) { + GString *str = g_string_new(""); + + g_string_append_printf(str, "TLS MESSAGE %s\n", + incoming ? "INCOMING" : "OUTGOING"); + + /* temporary */ + (void)bytes; + g_string_append_printf(str, "message length %" G_GSIZE_FORMAT " bytes", + length); + + SIPE_DEBUG_INFO_NOFORMAT(str->str); + g_string_free(str, TRUE); + } +} + static const guchar const client_hello[] = { #if 0 @@ -126,7 +150,7 @@ static const guchar const client_hello[] = { #endif }; -guchar *sipe_tls_client_hello(gsize *length) +guchar *sipe_tls_client_hello(gsize *out_length) { guchar *msg = g_memdup(client_hello, sizeof(client_hello)); guint32 now = time(NULL); @@ -138,10 +162,29 @@ guchar *sipe_tls_client_hello(gsize *length) for (p = msg + RANDOM_OFFSET, i = 0; i < 2; i++) *p++ = rand() & 0xFF; - *length = sizeof(client_hello); + *out_length = sizeof(client_hello); + message_debug(msg, sizeof(client_hello), FALSE); return(msg); } +guchar *sipe_tls_server_hello(const guchar *incoming, + gsize in_length, + gsize *out_length) +{ + message_debug(incoming, in_length, TRUE); + + *out_length = 0; + return(NULL); +} + +gboolean sipe_tls_finished(const guchar *incoming, + gsize in_length) +{ + message_debug(incoming, in_length, TRUE); + + return(FALSE); +} + /* Local Variables: mode: c diff --git a/src/core/sipe-tls.h b/src/core/sipe-tls.h index 2ed56914..47e06a50 100644 --- a/src/core/sipe-tls.h +++ b/src/core/sipe-tls.h @@ -28,3 +28,8 @@ */ guchar *sipe_tls_client_hello(gsize *length); +guchar *sipe_tls_server_hello(const guchar *incoming, + gsize in_length, + gsize *out_length); +gboolean sipe_tls_finished(const guchar *incoming, + gsize in_length); -- 2.11.4.GIT