From 7aa0d2eb53d622864c15f7c24c43e4b507657827 Mon Sep 17 00:00:00 2001 From: Stefan Becker Date: Tue, 14 Nov 2017 15:21:52 +0200 Subject: [PATCH] Fix #336: Lync autodiscover does not follow user redirect It seems that the User response does not always point directly to the users home server, but instead contains another "Redirect" token. Add support to follow such redirects. This requires that the code only does the final parse of an User response when nothing else matched in the parser. --- src/core/sipe-lync-autodiscover.c | 93 ++++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 35 deletions(-) diff --git a/src/core/sipe-lync-autodiscover.c b/src/core/sipe-lync-autodiscover.c index 3b632d66..c083f2e9 100644 --- a/src/core/sipe-lync-autodiscover.c +++ b/src/core/sipe-lync-autodiscover.c @@ -151,9 +151,8 @@ static void sipe_lync_autodiscover_parse(struct sipe_core_private *sipe_private, sipe_xml *xml = sipe_xml_parse(body, strlen(body)); const sipe_xml *node; gboolean next = TRUE; - const gchar *access_location; - /* Root: resources exposed by this server */ + /* Root/Link: resources exposed by this server */ for (node = sipe_xml_child(xml, "Root/Link"); node; node = sipe_xml_twin(node)) { @@ -187,48 +186,72 @@ static void sipe_lync_autodiscover_parse(struct sipe_core_private *sipe_private, } } - access_location = sipe_xml_attribute(xml, "AccessLocation"); + /* User/Link: topology information of the user’s home server */ + for (node = sipe_xml_child(xml, "User/Link"); + node; + node = sipe_xml_twin(node)) { + const gchar *token = sipe_xml_attribute(node, "token"); + const gchar *uri = sipe_xml_attribute(node, "href"); - /* User: topology information of the user’s home server */ - if ((node = sipe_xml_child(xml, "User")) != NULL) { - gpointer id = request->id; + if (token && uri) { + /* Redirect? */ + if (sipe_strcase_equal(token, "Redirect")) { + SIPE_DEBUG_INFO("sipe_lync_autodiscover_parse: redirect to %s", + uri); + lync_request(sipe_private, request, uri, NULL); + next = FALSE; + break; + } else + SIPE_DEBUG_INFO("sipe_lync_autodiscover_parse: unknown token %s", + token); + } + } - /* Active request? */ - if (id) { - GSList *servers; + /* if nothing else matched */ + if (next) { + const gchar *access_location = sipe_xml_attribute(xml, "AccessLocation"); - /* List is reversed, i.e. internal will be tried first */ - servers = g_slist_prepend(NULL, NULL); + /* User: topology information of the user’s home server */ + if ((node = sipe_xml_child(xml, "User")) != NULL) { + gpointer id = request->id; - if (!access_location || - sipe_strcase_equal(access_location, "external")) { - servers = sipe_lync_autodiscover_add(servers, - node, - "SipClientExternalAccess"); - } + /* Active request? */ + if (id) { + GSList *servers; - if (!access_location || - sipe_strcase_equal(access_location, "internal")) { - servers = sipe_lync_autodiscover_add(servers, - node, - "SipClientInternalAccess"); - } + /* List is reversed, i.e. internal will be tried first */ + servers = g_slist_prepend(NULL, NULL); - /* Callback takes ownership of servers list */ - (*request->cb)(sipe_private, servers, request->cb_data); + if (!access_location || + sipe_strcase_equal(access_location, "external")) { + servers = sipe_lync_autodiscover_add(servers, + node, + "SipClientExternalAccess"); + } - /* We're done with requests for this callback */ - FOR_ALL_REQUESTS_WITH_SAME_ID( \ - lar->cb = NULL; \ - lar->id = NULL \ - ); + if (!access_location || + sipe_strcase_equal(access_location, "internal")) { + servers = sipe_lync_autodiscover_add(servers, + node, + "SipClientInternalAccess"); + } - } + /* Callback takes ownership of servers list */ + (*request->cb)(sipe_private, servers, request->cb_data); - /* Request completed */ - next = FALSE; - sipe_lync_autodiscover_request_free(sipe_private, request); - /* request is invalid */ + /* We're done with requests for this callback */ + FOR_ALL_REQUESTS_WITH_SAME_ID( \ + lar->cb = NULL; \ + lar->id = NULL \ + ); + + } + + /* Request completed */ + next = FALSE; + sipe_lync_autodiscover_request_free(sipe_private, request); + /* request is invalid */ + } } sipe_xml_free(xml); -- 2.11.4.GIT