From 715828d26c33f1bb38d8eda7e403318a16bcbf0b Mon Sep 17 00:00:00 2001 From: Stefan Becker Date: Thu, 24 Nov 2011 00:23:28 +0200 Subject: [PATCH] sign: fix protocol name for TLS-DSK sipmsg_breakdown_parse() was hard-coded to Kerberos or NTLM. Now we supply the protocol name directly from sip-transport.c and generate the correct message signature for TLS-DSK. This was the last piece missing to get a successful MAC calculation and verification with TLS-DSK. *** THE EAGLE HAS LANDED!!! *** BTW: Lync365 rejects non-Lync clients with a non-standard 403 Forbidden response. Make sure to change the User Agent value in your account! --- src/core/sip-sec-ntlm-tests.c | 8 ++++---- src/core/sip-transport.c | 23 +++++++++++++++-------- src/core/sipe-sign.c | 6 ++++-- src/core/sipe-sign.h | 3 ++- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/core/sip-sec-ntlm-tests.c b/src/core/sip-sec-ntlm-tests.c index 1ec5cdfd..05ba442d 100644 --- a/src/core/sip-sec-ntlm-tests.c +++ b/src/core/sip-sec-ntlm-tests.c @@ -491,7 +491,7 @@ Response: msg = sipmsg_parse_msg(msg2); msgbd.msg = msg; - sipmsg_breakdown_parse(&msgbd, "SIP Communications Service", "ocs1.ocs.provo.novell.com"); + sipmsg_breakdown_parse(&msgbd, "SIP Communications Service", "ocs1.ocs.provo.novell.com", NULL); msg_str = sipmsg_breakdown_get_string(2, &msgbd); sip_sec_ntlm_sipe_signature_make (NEGOTIATE_FLAGS_CONNLESS & ~NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY, msg_str, 0, exported_session_key2, exported_session_key2, mac); @@ -747,7 +747,7 @@ Message (length 352): printf ("\n\nTesting (NTLMv2 / OC 2007 R2) Message Parsing, Signing, and Verification\nClient request\n(Authentication Protocol version 4)\n"); msg = sipmsg_parse_msg(request); msgbd.msg = msg; - sipmsg_breakdown_parse(&msgbd, "SIP Communications Service", "cosmo-ocs-r2.cosmo.local"); + sipmsg_breakdown_parse(&msgbd, "SIP Communications Service", "cosmo-ocs-r2.cosmo.local", NULL); msg_str = sipmsg_breakdown_get_string(4, &msgbd); assert_equal (request_sig, (guchar *)msg_str, strlen(request_sig), FALSE); sip_sec_ntlm_sipe_signature_make (flags, msg_str, 0, client_sign_key, client_seal_key, mac); @@ -758,7 +758,7 @@ Message (length 352): printf ("\n\nTesting (NTLMv2 / OC 2007 R2) Message Parsing, Signing, and Verification\nServer response\n(Authentication Protocol version 4)\n"); msg = sipmsg_parse_msg(response); msgbd.msg = msg; - sipmsg_breakdown_parse(&msgbd, "SIP Communications Service", "cosmo-ocs-r2.cosmo.local"); + sipmsg_breakdown_parse(&msgbd, "SIP Communications Service", "cosmo-ocs-r2.cosmo.local", NULL); msg_str = sipmsg_breakdown_get_string(4, &msgbd); assert_equal (response_sig, (guchar *)msg_str, strlen(response_sig), FALSE); // server keys here @@ -844,7 +844,7 @@ Message (length 352): msg = sipmsg_parse_msg(response_symbian); msgbd.msg = msg; - sipmsg_breakdown_parse(&msgbd, "SIP Communications Service", "LOC-COMPANYT-FE03.COMPANY.COM"); + sipmsg_breakdown_parse(&msgbd, "SIP Communications Service", "LOC-COMPANYT-FE03.COMPANY.COM", NULL); msg_str = sipmsg_breakdown_get_string(4, &msgbd); assert_equal (response_sig, (guchar *)msg_str, strlen(response_sig), FALSE); diff --git a/src/core/sip-transport.c b/src/core/sip-transport.c index 5113ff74..4990f753 100644 --- a/src/core/sip-transport.c +++ b/src/core/sip-transport.c @@ -81,6 +81,7 @@ struct sip_auth { struct sip_sec_context *gssapi_context; gchar *gssapi_data; gchar *opaque; + const gchar *protocol; gchar *realm; gchar *sts_uri; gchar *target; @@ -130,6 +131,7 @@ static void sipe_auth_free(struct sip_auth *auth) { g_free(auth->opaque); auth->opaque = NULL; + auth->protocol = NULL; g_free(auth->realm); auth->realm = NULL; g_free(auth->sts_uri); @@ -155,7 +157,8 @@ static void sipe_make_signature(struct sipe_core_private *sipe_private, struct sipmsg_breakdown msgbd; gchar *signature_input_str; msgbd.msg = msg; - sipmsg_breakdown_parse(&msgbd, transport->registrar.realm, transport->registrar.target); + sipmsg_breakdown_parse(&msgbd, transport->registrar.realm, transport->registrar.target, + transport->registrar.protocol); msgbd.rand = g_strdup_printf("%08x", g_random_int()); transport->registrar.ntlm_num++; msgbd.num = g_strdup_printf("%d", transport->registrar.ntlm_num); @@ -191,7 +194,7 @@ static gchar *msg_signature_to_auth(struct sip_auth *auth, struct sipmsg *msg) { return(g_strdup_printf("%s qop=\"auth\", opaque=\"%s\", realm=\"%s\", targetname=\"%s\", crand=\"%s\", cnum=\"%s\", response=\"%s\"", - auth_type_to_protocol[auth->type], + auth->protocol, auth->opaque, auth->realm, auth->target, msg->rand, msg->num, msg->signature)); } @@ -265,6 +268,7 @@ static gchar *initialize_auth_context(struct sipe_core_private *sipe_private, /* we can't authenticate the message yet */ sipe_private->transport->auth_incomplete = TRUE; + return(NULL); } else { SIPE_DEBUG_INFO("initialize_auth_context: TLS-DSK certificate for target '%s' found.", @@ -310,7 +314,7 @@ static gchar *initialize_auth_context(struct sipe_core_private *sipe_private, 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\"%s%s%s", - auth_type_to_protocol[auth->type], opaque_str, + auth->protocol, opaque_str, auth->realm, auth->target, gssapi_str, version_str, sign_str); g_free(version_str); @@ -325,7 +329,7 @@ static gchar *start_auth_handshake(struct sip_auth *auth) { gchar *version_str = auth_header_version(auth); gchar *ret = g_strdup_printf("%s qop=\"auth\", realm=\"%s\", targetname=\"%s\", gssapi-data=\"\"%s", - auth_type_to_protocol[auth->type], + auth->protocol, auth->realm, auth->target, version_str); g_free(version_str); @@ -893,8 +897,9 @@ static const gchar *get_auth_header(struct sipe_core_private *sipe_private, if (SIPE_CORE_PUBLIC_FLAG_IS(TLS_DSK)) { auth->type = AUTH_TYPE_TLS_DSK; } - return(sipmsg_find_auth_header(msg, - auth_type_to_protocol[auth->type])); + auth->protocol = auth_type_to_protocol[auth->type]; + + return(sipmsg_find_auth_header(msg, auth->protocol)); } static void do_register(struct sipe_core_private *sipe_private, @@ -1524,7 +1529,8 @@ static void process_input_message(struct sipe_core_private *sipe_private, if (protocol && !g_strncasecmp(auth_hdr, protocol, strlen(protocol))) { SIPE_DEBUG_INFO("proxy auth: type %s", protocol); - transport->proxy.type = i; + transport->proxy.type = i; + transport->proxy.protocol = protocol; break; } } @@ -1631,7 +1637,8 @@ static void sip_transport_input(struct sipe_transport_connection *conn) gchar *signature_input_str; gchar *rspauth; msgbd.msg = msg; - sipmsg_breakdown_parse(&msgbd, transport->registrar.realm, transport->registrar.target); + sipmsg_breakdown_parse(&msgbd, transport->registrar.realm, transport->registrar.target, + transport->registrar.protocol); signature_input_str = sipmsg_breakdown_get_string(transport->registrar.version, &msgbd); rspauth = sipmsg_find_part_of_header(sipmsg_find_header(msg, "Authentication-Info"), "rspauth=\"", "\"", NULL); diff --git a/src/core/sipe-sign.c b/src/core/sipe-sign.c index 6ec1e27b..d953f9c4 100644 --- a/src/core/sipe-sign.c +++ b/src/core/sipe-sign.c @@ -3,6 +3,7 @@ * * pidgin-sipe * + * Copyright (C) 2011 SIPE Project * Copyright (C) 2008 Novell, Inc. * * This program is free software; you can redistribute it and/or modify @@ -30,7 +31,8 @@ static gchar * const empty_string = ""; -void sipmsg_breakdown_parse(struct sipmsg_breakdown * msg, gchar * realm, gchar * target) +void sipmsg_breakdown_parse(struct sipmsg_breakdown * msg, gchar * realm, gchar * target, + const gchar *protocol) { const gchar * hdr; if (msg == NULL || msg->msg == NULL) { @@ -53,7 +55,7 @@ void sipmsg_breakdown_parse(struct sipmsg_breakdown * msg, gchar * realm, gchar msg->realm = sipmsg_find_part_of_header(hdr, "realm=\"", "\"", empty_string); msg->target_name = sipmsg_find_part_of_header(hdr, "targetname=\"", "\"", empty_string); } else { - msg->protocol = strstr(target, "sip/") ? g_strdup("Kerberos") : g_strdup("NTLM"); + msg->protocol = g_strdup(protocol); msg->realm = g_strdup(realm); msg->target_name = g_strdup(target); } diff --git a/src/core/sipe-sign.h b/src/core/sipe-sign.h index f7417320..55ba9168 100644 --- a/src/core/sipe-sign.h +++ b/src/core/sipe-sign.h @@ -43,7 +43,8 @@ struct sipmsg_breakdown { //response code }; -void sipmsg_breakdown_parse(struct sipmsg_breakdown * msg, gchar * realm, gchar * target); +void sipmsg_breakdown_parse(struct sipmsg_breakdown * msg, gchar * realm, gchar * target, + const gchar *protocol); gchar* sipmsg_breakdown_get_string(int version, struct sipmsg_breakdown * msgbd); -- 2.11.4.GIT