From f8ddd2c711cd502c74eb9d45360914fe2e6e1b3f Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Thu, 20 Aug 2020 13:34:19 -0400 Subject: [PATCH 06/15] subman: Handle subscription-manager giving invalid status better subscription-manager potentially returns status messages that the subman plugin treats as enum values translated in some unknown other language. It could be tied to system locale, or due to a caching bug a previous locale used. This commit tries to work around that bug, by instead relying on the GetUUID() method and valid attribute. If there's no UUID we know the system is unregistered. If there's a UUID but the valid attribute is FALSE we know the system is registered, but hasn't got proper entitlements. --- plugins/subman/gsd-subscription-manager.c | 69 ++++++++++++----------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c index 46f051a5..e2c16056 100644 --- a/plugins/subman/gsd-subscription-manager.c +++ b/plugins/subman/gsd-subscription-manager.c @@ -104,77 +104,60 @@ typedef struct gchar *starts; gchar *ends; } ProductData; static void product_data_free (ProductData *product) { g_free (product->product_name); g_free (product->product_id); g_free (product->version); g_free (product->arch); g_free (product->status); g_free (product->starts); g_free (product->ends); g_free (product); } G_DEFINE_AUTOPTR_CLEANUP_FUNC (ProductData, product_data_free); static gpointer manager_object = NULL; GQuark gsd_subscription_manager_error_quark (void) { static GQuark quark = 0; if (!quark) quark = g_quark_from_static_string ("gsd_subscription_manager_error"); return quark; } -static GsdSubmanSubscriptionStatus -_client_subscription_status_from_text (const gchar *status_txt) -{ - if (g_strcmp0 (status_txt, "Unknown") == 0) - return GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN; - if (g_strcmp0 (status_txt, "Current") == 0) - return GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID; - if (g_strcmp0 (status_txt, "Invalid") == 0) - return GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID; - if (g_strcmp0 (status_txt, "Disabled") == 0) - return GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED; - if (g_strcmp0 (status_txt, "Insufficient") == 0) - return GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID; - g_warning ("Unknown subscription status: %s", status_txt); // 'Current'? - return GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN; -} - static GVariant * _make_installed_products_variant (GPtrArray *installed_products) { GVariantBuilder builder; g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}")); for (guint i = 0; i < installed_products->len; i++) { ProductData *product = g_ptr_array_index (installed_products, i); g_auto(GVariantDict) dict; g_variant_dict_init (&dict, NULL); g_variant_dict_insert (&dict, "product-name", "s", product->product_name); g_variant_dict_insert (&dict, "product-id", "s", product->product_id); g_variant_dict_insert (&dict, "version", "s", product->version); g_variant_dict_insert (&dict, "arch", "s", product->arch); g_variant_dict_insert (&dict, "status", "s", product->status); g_variant_dict_insert (&dict, "starts", "s", product->starts); g_variant_dict_insert (&dict, "ends", "s", product->ends); g_variant_builder_add_value (&builder, g_variant_dict_end (&dict)); } return g_variant_builder_end (&builder); } static void _emit_property_changed (GsdSubscriptionManager *manager, const gchar *property_name, GVariant *property_value) @@ -248,94 +231,114 @@ _client_installed_products_update (GsdSubscriptionManager *manager, GError **err if (json_product == NULL) continue; if (json_array_get_length (json_product) < 8) { g_debug ("Unexpected number of array elements in InstalledProducts JSON"); continue; } product->product_name = g_strdup (json_array_get_string_element (json_product, 0)); product->product_id = g_strdup (json_array_get_string_element (json_product, 1)); product->version = g_strdup (json_array_get_string_element (json_product, 2)); product->arch = g_strdup (json_array_get_string_element (json_product, 3)); product->status = g_strdup (json_array_get_string_element (json_product, 4)); product->starts = g_strdup (json_array_get_string_element (json_product, 6)); product->ends = g_strdup (json_array_get_string_element (json_product, 7)); g_ptr_array_add (priv->installed_products, g_steal_pointer (&product)); } /* emit notification for g-c-c */ _emit_property_changed (manager, "InstalledProducts", _make_installed_products_variant (priv->installed_products)); return TRUE; } static gboolean _client_subscription_status_update (GsdSubscriptionManager *manager, GError **error) { GsdSubscriptionManagerPrivate *priv = manager->priv; + g_autoptr(GVariant) uuid = NULL; + const gchar *uuid_txt = NULL; JsonNode *json_root; JsonObject *json_obj; const gchar *json_txt = NULL; - const gchar *status_txt = NULL; - g_autoptr(GVariant) val = NULL; + g_autoptr(GVariant) status = NULL; g_autoptr(JsonParser) json_parser = json_parser_new (); /* save old value */ priv->subscription_status_last = priv->subscription_status; - val = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_ENTITLEMENT], - "GetStatus", - g_variant_new ("(ss)", - "", /* assumed as 'now' */ - "C.UTF-8"), - G_DBUS_CALL_FLAGS_NONE, - -1, NULL, error); - if (val == NULL) + uuid = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_CONSUMER], + "GetUuid", + g_variant_new ("(s)", + "C.UTF-8"), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, error); + if (uuid == NULL) return FALSE; - g_variant_get (val, "(&s)", &json_txt); + + g_variant_get (uuid, "(&s)", &uuid_txt); + + status = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_ENTITLEMENT], + "GetStatus", + g_variant_new ("(ss)", + "", /* assumed as 'now' */ + "C.UTF-8"), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, error); + if (status == NULL) + return FALSE; + g_variant_get (status, "(&s)", &json_txt); g_debug ("Entitlement.GetStatus JSON: %s", json_txt); if (!json_parser_load_from_data (json_parser, json_txt, -1, error)) return FALSE; json_root = json_parser_get_root (json_parser); json_obj = json_node_get_object (json_root); - if (!json_object_has_member (json_obj, "status")) { + if (!json_object_has_member (json_obj, "valid")) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, - "no Entitlement.GetStatus status in %s", json_txt); + "no Entitlement.GetStatus valid in %s", json_txt); return FALSE; } - status_txt = json_object_get_string_member (json_obj, "status"); - g_debug ("Entitlement.GetStatus: %s", status_txt); - priv->subscription_status = _client_subscription_status_from_text (status_txt); + gboolean is_valid = json_object_get_boolean_member (json_obj, "valid"); + + if (uuid_txt[0] != '\0') { + if (is_valid) { + priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID; + } else { + priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID; + } + } else { + priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN; + } /* emit notification for g-c-c */ if (priv->subscription_status != priv->subscription_status_last) { _emit_property_changed (manager, "SubscriptionStatus", g_variant_new_uint32 (priv->subscription_status)); } return TRUE; } static gboolean _client_syspurpose_update (GsdSubscriptionManager *manager, GError **error) { GsdSubscriptionManagerPrivate *priv = manager->priv; JsonNode *json_root; JsonObject *json_obj; const gchar *json_txt = NULL; g_autoptr(GVariant) val = NULL; g_autoptr(JsonParser) json_parser = json_parser_new (); val = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_SYSPURPOSE], "GetSyspurpose", g_variant_new ("(s)", "C.UTF-8"), G_DBUS_CALL_FLAGS_NONE, -1, NULL, error); if (val == NULL) return FALSE; g_variant_get (val, "(&s)", &json_txt); g_debug ("Syspurpose.GetSyspurpose JSON: %s", json_txt); if (!json_parser_load_from_data (json_parser, json_txt, -1, error)) -- 2.30.0