--- /dev/null
+#define _GNU_SOURCE
+
+#include <libsoup/soup.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+struct ews_auth {
+ const char *username;
+ const char *password;
+};
+static int parse_protocol(xmlNode *node);
+
+static void souptest_authenticate(SoupSession *sess, SoupMessage *msg,
+ SoupAuth *auth, gboolean retrying, gpointer data)
+{
+ struct ews_auth *authdata = data;
+ soup_auth_authenticate (auth, authdata->username, authdata->password);
+}
+
+int main(int argc, char **argv)
+{
+ SoupSession *sess;
+ SoupMessage *msg;
+ xmlDoc *doc;
+ xmlNode *node, *child;
+ guint status;
+ xmlOutputBuffer *buf;
+ struct ews_auth auth;
+ char *domain;
+ char *url;
+
+ if (argc != 4) {
+ usage:
+ fprintf(stderr, "Usage: ews_autodiscover <email> <DOMAIN\\username> <password>\n");
+ fprintf(stderr, "Sorry, no Kerberos auth support yet (https://bugzilla.gnome.org/587145)\n");
+ exit (1);
+ }
+ auth.username = argv[2];
+ auth.password = argv[3];
+
+ domain = strchr(argv[1], '@');
+ if (!domain) {
+ fprintf(stderr, "No @ sign in email address\n");
+ goto usage;
+ }
+ domain++;
+
+ if (!strchr(argv[2], '\\')) {
+ fprintf(stderr, "No domain in username (https://bugzilla.gnome.org/624613)\n");
+ goto usage;
+ }
+
+ g_thread_init (NULL);
+ g_type_init ();
+ asprintf(&url, "https://autodiscover.%s/autodiscover/autodiscover.xml", domain);
+
+ sess = soup_session_sync_new_with_options(SOUP_SESSION_USE_NTLM, TRUE, NULL);
+ g_signal_connect (sess, "authenticate",
+ G_CALLBACK(souptest_authenticate), &auth);
+
+ if (getenv("EWS_DEBUG")) {
+ SoupLogger *logger;
+ logger = soup_logger_new(SOUP_LOGGER_LOG_BODY, -1);
+ soup_session_add_feature(sess, SOUP_SESSION_FEATURE(logger));
+ }
+
+ printf("url is %s\n", url);
+ msg = soup_message_new("GET", url);
+
+ soup_message_headers_append (msg->request_headers,
+ "User-Agent", "libews/0.1");
+
+ doc = xmlNewDoc((xmlChar *) "1.0");
+ node = xmlNewDocNode(doc, NULL, (xmlChar *)"Autodiscover", NULL);
+ xmlNewProp(node, (xmlChar *)"xmlns", (xmlChar *)"http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006");
+ xmlDocSetRootElement(doc, node);
+
+ node = xmlNewChild(node, NULL, (xmlChar *)"Request", NULL);
+ child = xmlNewChild(node, NULL, (xmlChar *)"EMailAddress",
+ (xmlChar *)argv[1]);
+ child = xmlNewChild(node, NULL, (xmlChar *)"AcceptableResponseSchema",
+ (xmlChar *)"http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a");
+
+ buf = xmlAllocOutputBuffer(NULL);
+ xmlNodeDumpOutput(buf, doc, xmlDocGetRootElement(doc), 0, 1, NULL);
+ xmlOutputBufferFlush(buf);
+
+ soup_message_set_request(msg, "application/xml", SOUP_MEMORY_COPY,
+ (gchar *)buf->buffer->content,
+ buf->buffer->use);
+
+ status = soup_session_send_message(sess, msg);
+
+ xmlOutputBufferClose (buf);
+ xmlFreeDoc (doc);
+
+ if (status != 200) {
+ fprintf(stderr, "Unexpected response from server: %d\n", status);
+ exit(1);
+ }
+
+ doc = xmlReadMemory (msg->response_body->data, msg->response_body->length,
+ "autodiscover.xml", NULL, 0);
+ if (!doc) {
+ fprintf(stderr, "Failed to parse autodiscover response XML\n");
+ exit(1);
+ }
+ node = xmlDocGetRootElement(doc);
+ if (strcmp((char *)node->name, "Autodiscover")) {
+ fprintf(stderr, "Failed to find <Autodiscover> element\n");
+ exit (1);
+ }
+ for (node = node->children; node; node = node->next) {
+ if (node->type == XML_ELEMENT_NODE &&
+ !strcmp((char *)node->name, "Response"))
+ break;
+ }
+ if (!node) {
+ fprintf(stderr, "Failed to find <Response> element\n");
+ exit (1);
+ }
+ for (node = node->children; node; node = node->next) {
+ if (node->type == XML_ELEMENT_NODE &&
+ !strcmp((char *)node->name, "Account"))
+ break;
+ }
+ if (!node) {
+ fprintf(stderr, "Failed to find <Account> element\n");
+ exit (1);
+ }
+ for (node = node->children; node; node = node->next) {
+ if (node->type == XML_ELEMENT_NODE &&
+ !strcmp((char *)node->name, "Protocol") &&
+ parse_protocol(node))
+ break;
+ }
+ return 0;
+}
+static int parse_protocol(xmlNode *node)
+{
+ for (node = node->children; node; node = node->next) {
+ if (node->type == XML_ELEMENT_NODE &&
+ !strcmp((char *)node->name, "ASUrl")) {
+ char *asurl = (char *)xmlNodeGetContent(node);
+ if (asurl) {
+ printf("Got ASUrl %s\n", asurl);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}