[gnome-software/gnome-3-22] snap: Use snapd-glib to perform snapd login. This fixes non-root access being removed in snapd.



commit 3124178fa089cfd614ac96196a46e964c7de5ba2
Author: Robert Ancell <robert ancell canonical com>
Date:   Mon Sep 12 20:13:34 2016 +1200

    snap: Use snapd-glib to perform snapd login. This fixes non-root access being removed in snapd.

 configure.ac                 |   23 +++++++++
 src/plugins/Makefile.am      |    9 +++-
 src/plugins/gs-plugin-snap.c |   34 ++++++++++----
 src/plugins/gs-snapd.c       |  109 ------------------------------------------
 src/plugins/gs-snapd.h       |    8 ---
 5 files changed, 56 insertions(+), 127 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index c73ac88..9157f37 100644
--- a/configure.ac
+++ b/configure.ac
@@ -396,6 +396,28 @@ GS_PLUGIN_API_VERSION=11
 AC_SUBST(GS_PLUGIN_API_VERSION)
 AC_DEFINE_UNQUOTED([GS_PLUGIN_API_VERSION], "$GS_PLUGIN_API_VERSION", [the plugin API version])
 
+# Snap
+AC_ARG_ENABLE(snap,
+              [AS_HELP_STRING([--enable-snap],
+                              [enable Snap support [default=auto]])],,
+              enable_snap=maybe)
+AS_IF([test "x$enable_snap" != "xno"], [
+    PKG_CHECK_MODULES(SNAP,
+                      [snapd-glib],
+                      [have_snap=yes],
+                      [have_snap=no])
+], [
+    have_snap=no
+])
+AS_IF([test "x$have_snap" = "xyes"], [
+    AC_DEFINE(HAVE_SNAP,1,[Build Snap support])
+], [
+    AS_IF([test "x$enable_snap" = "xyes"], [
+          AC_MSG_ERROR([Snap support requested but 'snapd-glib' was not found])
+    ])
+])
+AM_CONDITIONAL(HAVE_SNAP, test "$have_snap" != no)
+
 GLIB_TESTS
 
 dnl ---------------------------------------------------------------------------
@@ -452,4 +474,5 @@ echo "
         ODRS support:              ${enable_odrs}
         Webapps support:           ${enable_webapps}
         Ubuntu Reviews support:    ${enable_ubuntu_reviews}
+        Snap support:              ${have_snap}
 "
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index b4e98fb..555536c 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -17,6 +17,7 @@ AM_CPPFLAGS =                                         \
        $(FLATPAK_CFLAGS)                               \
        $(RPM_CFLAGS)                                   \
        $(OAUTH_CFLAGS)                                 \
+       $(SNAP_CFLAGS)                                  \
        -DI_KNOW_THE_GNOME_SOFTWARE_API_IS_SUBJECT_TO_CHANGE    \
        -DBINDIR=\"$(bindir)\"                          \
        -DDATADIR=\"$(datadir)\"                        \
@@ -45,9 +46,12 @@ plugin_LTLIBRARIES =                                 \
        libgs_plugin_repos.la                           \
        libgs_plugin_fedora-tagger-usage.la             \
        libgs_plugin_icons.la                           \
-       libgs_plugin_snap.la                            \
        libgs_plugin_ubuntuone.la
 
+if HAVE_SNAP
+plugin_LTLIBRARIES += libgs_plugin_snap.la
+endif
+
 if HAVE_PACKAGEKIT
 plugin_LTLIBRARIES +=                                  \
        libgs_plugin_systemd-updates.la                 \
@@ -356,16 +360,19 @@ libgs_plugin_packagekit_proxy_la_LIBADD = $(GS_PLUGIN_LIBS) $(PACKAGEKIT_LIBS)
 libgs_plugin_packagekit_proxy_la_LDFLAGS = -module -avoid-version
 libgs_plugin_packagekit_proxy_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
 
+if HAVE_SNAP
 libgs_plugin_snap_la_SOURCES =                         \
        gs-plugin-snap.c                                \
        gs-snapd.h                                      \
        gs-snapd.c
 libgs_plugin_snap_la_LIBADD =                          \
        $(GS_PLUGIN_LIBS)                               \
+       $(SNAP_LIBS)                                    \
        $(SOUP_LIBS)                                    \
        $(JSON_GLIB_LIBS)
 libgs_plugin_snap_la_LDFLAGS = -module -avoid-version
 libgs_plugin_snap_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
+endif
 
 libgs_plugin_ubuntuone_la_SOURCES =                    \
        gs-plugin-ubuntuone.c
diff --git a/src/plugins/gs-plugin-snap.c b/src/plugins/gs-plugin-snap.c
index 58cd34a..01eab0d 100644
--- a/src/plugins/gs-plugin-snap.c
+++ b/src/plugins/gs-plugin-snap.c
@@ -22,6 +22,7 @@
 #include <config.h>
 
 #include <json-glib/json-glib.h>
+#include <snapd-glib/snapd-glib.h>
 #include <gnome-software.h>
 
 #include "gs-snapd.h"
@@ -425,8 +426,7 @@ gs_plugin_auth_login (GsPlugin *plugin, GsAuth *auth,
                      GCancellable *cancellable, GError **error)
 {
        GsPluginData *priv = gs_plugin_get_data (plugin);
-       g_autofree gchar *macaroon = NULL;
-       g_auto(GStrv) discharges = NULL;
+       g_autoptr(SnapdAuthData) auth_data = NULL;
        g_autoptr(GVariant) macaroon_variant = NULL;
        g_autofree gchar *serialized_macaroon = NULL;
        g_autoptr(GError) local_error = NULL;
@@ -434,15 +434,31 @@ gs_plugin_auth_login (GsPlugin *plugin, GsAuth *auth,
        if (auth != priv->auth)
                return TRUE;
 
-       if (!gs_snapd_login (gs_auth_get_username (auth),
-                            gs_auth_get_password (auth),
-                            gs_auth_get_pin (auth),
-                            &macaroon,
-                            &discharges,
-                            cancellable, &local_error))
+       auth_data = snapd_login_sync (gs_auth_get_username (auth), gs_auth_get_password (auth), 
gs_auth_get_pin (auth), NULL, &local_error);
+       if (auth_data == NULL) {
+               if (g_error_matches (local_error, SNAPD_ERROR, SNAPD_ERROR_TWO_FACTOR_REQUIRED)) {
+                       g_set_error_literal (error,
+                                            GS_PLUGIN_ERROR,
+                                            GS_PLUGIN_ERROR_PIN_REQUIRED,
+                                            local_error->message);
+               } else if (g_error_matches (local_error, SNAPD_ERROR, SNAPD_ERROR_AUTH_DATA_INVALID) ||
+                          g_error_matches (local_error, SNAPD_ERROR, SNAPD_ERROR_TWO_FACTOR_INVALID)) {
+                       g_set_error_literal (error,
+                                            GS_PLUGIN_ERROR,
+                                            GS_PLUGIN_ERROR_AUTH_INVALID,
+                                            local_error->message);
+               } else {
+                       g_set_error_literal (error,
+                                            GS_PLUGIN_ERROR,
+                                            GS_PLUGIN_ERROR_NOT_SUPPORTED,
+                                            local_error->message);
+               }
                return FALSE;
+       }
 
-       macaroon_variant = g_variant_new ("(s^as)", macaroon, discharges);
+       macaroon_variant = g_variant_new ("(s^as)",
+                                         snapd_auth_data_get_macaroon (auth_data),
+                                         snapd_auth_data_get_discharges (auth_data));
        serialized_macaroon = g_variant_print (macaroon_variant, FALSE);
        gs_auth_add_metadata (auth, "macaroon", serialized_macaroon);
 
diff --git a/src/plugins/gs-snapd.c b/src/plugins/gs-snapd.c
index 7b07413..4a75bb6 100644
--- a/src/plugins/gs-snapd.c
+++ b/src/plugins/gs-snapd.c
@@ -344,115 +344,6 @@ parse_result (const gchar *response, const gchar *response_type, GError **error)
        return g_object_ref (parser);
 }
 
-gboolean
-gs_snapd_login (const gchar *username, const gchar *password, const gchar *otp,
-               gchar **macaroon, gchar ***discharges,
-               GCancellable *cancellable, GError **error)
-{
-       g_autofree gchar *escaped_username = NULL;
-       g_autofree gchar *escaped_password = NULL;
-       g_autofree gchar *escaped_otp = NULL;
-       g_autofree gchar *content = NULL;
-       guint status_code;
-       g_autofree gchar *response_type = NULL;
-       g_autofree gchar *response = NULL;
-       g_autoptr(JsonParser) parser = NULL;
-       JsonObject *root, *result;
-       const gchar *type;
-       g_autoptr(JsonArray) discharge_json_array = NULL;
-       g_autoptr(GPtrArray) discharge_array = NULL;
-       guint i;
-
-       escaped_username = g_strescape (username, NULL);
-       escaped_password = g_strescape (password, NULL);
-
-       if (otp != NULL) {
-               escaped_otp = g_strescape (otp, NULL);
-
-               content = g_strdup_printf ("{"
-                                          "  \"username\" : \"%s\","
-                                          "  \"password\" : \"%s\","
-                                          "  \"otp\" : \"%s\""
-                                          "}",
-                                          escaped_username,
-                                          escaped_password,
-                                          escaped_otp);
-       } else {
-               content = g_strdup_printf ("{"
-                                          "  \"username\" : \"%s\","
-                                          "  \"password\" : \"%s\""
-                                          "}",
-                                          escaped_username,
-                                          escaped_password);
-       }
-
-       if (!send_request ("POST", "/v2/login", content,
-                          NULL, NULL,
-                          &status_code, NULL,
-                          &response_type, &response, NULL,
-                          cancellable, error))
-               return FALSE;
-
-       parser = parse_result (response, response_type, error);
-       if (parser == NULL)
-               return FALSE;
-       root = json_node_get_object (json_parser_get_root (parser));
-       type = json_object_get_string_member (root, "type");
-       if (g_strcmp0 (type, "error") == 0) {
-               const gchar *kind, *message;
-
-               kind = json_object_get_string_member (root, "kind");
-               message = json_object_get_string_member (root, "message");
-               if (g_strcmp0 (kind, "invalid-auth-data") == 0 ||
-                   g_strcmp0 (kind, "two-factor-failed") == 0)
-                       g_set_error_literal (error,
-                                            GS_PLUGIN_ERROR,
-                                            GS_PLUGIN_ERROR_AUTH_INVALID,
-                                            message);
-               else if (g_strcmp0 (kind, "two-factor-required") == 0)
-                       g_set_error_literal (error,
-                                            GS_PLUGIN_ERROR,
-                                            GS_PLUGIN_ERROR_PIN_REQUIRED,
-                                            message);
-               else
-                       g_set_error_literal (error,
-                                            GS_PLUGIN_ERROR,
-                                            GS_PLUGIN_ERROR_FAILED,
-                                            message);
-
-               return FALSE;
-       }
-
-       result = json_object_get_object_member (root, "result");
-       if (result == NULL) {
-               g_set_error (error,
-                            GS_PLUGIN_ERROR,
-                            GS_PLUGIN_ERROR_INVALID_FORMAT,
-                            "snapd returned no login result");
-               return FALSE;
-       }
-       discharge_json_array = json_object_get_array_member (result, "discharges");
-       discharge_array = g_ptr_array_new ();
-       for (i = 0; i < json_array_get_length (discharge_json_array); i++) {
-               JsonNode *node = json_array_get_element (discharge_json_array, i);
-
-               if (json_node_get_value_type (node) != G_TYPE_STRING) {
-                       g_set_error (error,
-                                    GS_PLUGIN_ERROR,
-                                    GS_PLUGIN_ERROR_INVALID_FORMAT,
-                                    "Unexpected discharge type");
-                       return FALSE;
-               }
-
-               g_ptr_array_add (discharge_array, (gpointer) json_node_get_string (node));
-       }
-       g_ptr_array_add (discharge_array, NULL);
-       *macaroon = g_strdup (json_object_get_string_member (result, "macaroon"));
-       *discharges = g_strdupv ((gchar **) discharge_array->pdata);
-
-       return TRUE;
-}
-
 JsonObject *
 gs_snapd_list_one (const gchar *macaroon, gchar **discharges,
                   const gchar *name,
diff --git a/src/plugins/gs-snapd.h b/src/plugins/gs-snapd.h
index c5e80ff..af28bd1 100644
--- a/src/plugins/gs-snapd.h
+++ b/src/plugins/gs-snapd.h
@@ -29,14 +29,6 @@ typedef void (*GsSnapdProgressCallback) (JsonObject *object, gpointer user_data)
 
 gboolean gs_snapd_exists               (void);
 
-gboolean gs_snapd_login                        (const gchar    *username,
-                                        const gchar    *password,
-                                        const gchar    *otp,
-                                        gchar          **macaroon,
-                                        gchar          ***discharges,
-                                        GCancellable   *cancellable,
-                                        GError         **error);
-
 JsonObject *gs_snapd_list_one          (const gchar    *macaroon,
                                         gchar          **discharges,
                                         const gchar    *name,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]