static void load_auth (GsPlugin *plugin) { GsPluginData *priv = gs_plugin_get_data (plugin); GsAuth *auth; GoaObject *goa_object; GoaPasswordBased *password_based; g_autofree gchar *macaroon = NULL; g_autofree gchar *discharges_str = NULL; g_autoptr(GVariant) discharges_var = NULL; g_auto(GStrv) discharges = NULL; g_autoptr(SnapdAuthData) auth_data = NULL; g_autoptr(GError) error = NULL; auth = gs_plugin_get_auth_by_id (plugin, "snapd"); if (auth == NULL) return; g_clear_object (&priv->auth_data); goa_object = gs_auth_peek_goa_object (auth); if (goa_object == NULL) return; password_based = goa_object_peek_password_based (goa_object); g_return_if_fail (password_based != NULL); goa_password_based_call_get_password_sync (password_based, "macaroon", &macaroon, NULL, &error); if (error != NULL) { g_warning ("Failed to get macaroon: %s", error->message); return; } goa_password_based_call_get_password_sync (password_based, "discharges", &discharges_str, NULL, &error); if (error != NULL) { g_warning ("Failed to get discharges %s", error->message); return; } if (discharges_str) discharges_var = g_variant_parse (G_VARIANT_TYPE ("as"), discharges_str, NULL, NULL, NULL); if (discharges_var) discharges = g_variant_dup_strv (discharges_var, NULL); priv->auth_data = snapd_auth_data_new (macaroon, discharges); }
void goa_ews_autodiscover (GoaObject *goa_object, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { GoaAccount *goa_account; GoaExchange *goa_exchange; GoaPasswordBased *goa_password; GSimpleAsyncResult *simple; AutodiscoverData *data; AutodiscoverAuthData *auth; gchar *url1; gchar *url2; xmlDoc *doc; xmlOutputBuffer *buf; gchar *email; gchar *host; gchar *password = NULL; GError *error = NULL; g_return_if_fail (GOA_IS_OBJECT (goa_object)); goa_account = goa_object_get_account (goa_object); goa_exchange = goa_object_get_exchange (goa_object); goa_password = goa_object_get_password_based (goa_object); email = goa_account_dup_presentation_identity (goa_account); host = goa_exchange_dup_host (goa_exchange); doc = ews_create_autodiscover_xml (email); buf = xmlAllocOutputBuffer (NULL); xmlNodeDumpOutput (buf, doc, xmlDocGetRootElement (doc), 0, 1, NULL); xmlOutputBufferFlush (buf); url1 = g_strdup_printf ( "https://%s/autodiscover/autodiscover.xml", host); url2 = g_strdup_printf ( "https://autodiscover.%s/autodiscover/autodiscover.xml", host); g_free (host); g_free (email); /* http://msdn.microsoft.com/en-us/library/ee332364.aspx says we are * supposed to try $domain and then autodiscover.$domain. But some * people have broken firewalls on the former which drop packets * instead of rejecting connections, and make the request take ages * to time out. So run both queries in parallel and let the fastest * (successful) one win. */ data = g_slice_new0 (AutodiscoverData); data->buf = buf; data->msgs[0] = ews_create_msg_for_url (url1, buf); data->msgs[1] = ews_create_msg_for_url (url2, buf); data->session = soup_session_async_new_with_options ( SOUP_SESSION_USE_NTLM, TRUE, SOUP_SESSION_USE_THREAD_CONTEXT, TRUE, SOUP_SESSION_TIMEOUT, 90, SOUP_SESSION_ACCEPT_LANGUAGE_AUTO, TRUE, NULL); if (G_IS_CANCELLABLE (cancellable)) { data->cancellable = g_object_ref (cancellable); data->cancellable_id = g_cancellable_connect ( data->cancellable, G_CALLBACK (ews_autodiscover_cancelled_cb), data, NULL); } simple = g_simple_async_result_new ( G_OBJECT (goa_object), callback, user_data, goa_ews_autodiscover); g_simple_async_result_set_check_cancellable (simple, cancellable); g_simple_async_result_set_op_res_gpointer ( simple, data, (GDestroyNotify) ews_autodiscover_data_free); goa_password_based_call_get_password_sync ( goa_password, "", &password, cancellable, &error); /* Sanity check */ g_return_if_fail ( ((password != NULL) && (error == NULL)) || ((password == NULL) && (error != NULL))); if (error == NULL) { gchar *username; username = goa_account_dup_identity (goa_account); auth = g_slice_new0 (AutodiscoverAuthData); auth->username = username; /* takes ownership */ auth->password = password; /* takes ownership */ g_signal_connect_data ( data->session, "authenticate", G_CALLBACK (ews_authenticate), auth, ews_autodiscover_auth_data_free, 0); soup_session_queue_message ( data->session, data->msgs[0], ews_autodiscover_response_cb, simple); soup_session_queue_message ( data->session, data->msgs[1], ews_autodiscover_response_cb, simple); } else { g_dbus_error_strip_remote_error (error); g_simple_async_result_take_error (simple, error); g_simple_async_result_complete_in_idle (simple); g_object_unref (simple); } g_free (url2); g_free (url1); xmlFreeDoc (doc); g_object_unref (goa_account); g_object_unref (goa_exchange); g_object_unref (goa_password); }