diff -urN flatpak-1.6.2/common/flatpak-oci-registry.c flatpak-1.6.2.new/common/flatpak-oci-registry.c --- flatpak-1.6.2/common/flatpak-oci-registry.c 2019-12-20 09:52:17.000000000 +0000 +++ flatpak-1.6.2.new/common/flatpak-oci-registry.c 2020-03-20 12:01:39.923000000 +0000 @@ -901,6 +901,7 @@ static char * get_token_for_www_auth (FlatpakOciRegistry *self, + const char *repository, const char *www_authenticate, const char *auth, GCancellable *cancellable, @@ -911,6 +912,7 @@ g_autoptr(GHashTable) params = NULL; g_autoptr(GHashTable) args = NULL; const char *realm, *service, *scope, *token; + g_autofree char *default_scope = NULL; g_autoptr(SoupURI) auth_uri = NULL; g_autoptr(GBytes) body = NULL; g_autoptr(JsonNode) json = NULL; @@ -941,16 +943,21 @@ service = g_hash_table_lookup (params, "service"); if (service) g_hash_table_insert (args, "service", (char *)service); + scope = g_hash_table_lookup (params, "scope"); - if (scope) - g_hash_table_insert (args, "scope", (char *)scope); + if (scope == NULL) + scope = default_scope = g_strdup_printf("repository:%s:pull", repository); + g_hash_table_insert (args, "scope", (char *)scope); soup_uri_set_query_from_form (auth_uri, args); auth_msg = soup_message_new_from_uri ("GET", auth_uri); - g_autofree char *basic_auth = g_strdup_printf ("Basic %s", auth); - soup_message_headers_replace (auth_msg->request_headers, "Authorization", basic_auth); + if (auth) + { + g_autofree char *basic_auth = g_strdup_printf ("Basic %s", auth); + soup_message_headers_replace (auth_msg->request_headers, "Authorization", basic_auth); + } auth_stream = soup_session_send (self->soup_session, auth_msg, NULL, error); if (auth_stream == NULL) @@ -1030,7 +1037,7 @@ return NULL; } - token = get_token_for_www_auth (self, www_authenticate, basic_auth, cancellable, error); + token = get_token_for_www_auth (self, repository, www_authenticate, basic_auth, cancellable, error); if (token == NULL) return NULL; diff -urN flatpak-1.6.2/oci-authenticator/flatpak-oci-authenticator.c flatpak-1.6.2.new/oci-authenticator/flatpak-oci-authenticator.c --- flatpak-1.6.2/oci-authenticator/flatpak-oci-authenticator.c 2019-12-19 09:33:40.000000000 +0000 +++ flatpak-1.6.2.new/oci-authenticator/flatpak-oci-authenticator.c 2020-03-20 12:01:39.936000000 +0000 @@ -428,10 +428,12 @@ g_autoptr(GError) error = NULL; g_autoptr(AutoFlatpakAuthenticatorRequest) request = NULL; const char *auth = NULL; + gboolean have_auth; const char *oci_registry_uri = NULL; gsize n_refs, i; gboolean no_interaction = FALSE; g_autoptr(FlatpakOciRegistry) registry = NULL; + g_autofree char *first_token = NULL; GVariantBuilder tokens; GVariantBuilder results; g_autofree char *sender = g_strdup (g_dbus_method_invocation_get_sender (invocation)); @@ -439,6 +441,7 @@ g_debug ("handling Authenticator.RequestRefTokens"); g_variant_lookup (arg_authenticator_options, "auth", "&s", &auth); + have_auth = auth != NULL; if (!g_variant_lookup (arg_options, "xa.oci-registry-uri", "&s", &oci_registry_uri)) { @@ -476,18 +479,33 @@ return error_request (request, sender, error->message); - if (auth == NULL) + /* Look up credentials in config files */ + if (!have_auth) { g_debug ("Looking for %s in auth info", oci_registry_uri); auth = lookup_auth_from_config (oci_registry_uri); + have_auth = auth != NULL; } + /* Try to see if we can get a token without presenting credentials */ n_refs = g_variant_n_children (arg_refs); - if (auth == NULL && n_refs > 0 && + if (!have_auth && n_refs > 0) + { + g_autoptr(GVariant) ref_data = g_variant_get_child_value (arg_refs, 0); + + first_token = get_token_for_ref (registry, ref_data, NULL, &error); + if (first_token != NULL) + have_auth = TRUE; + else + g_clear_error (&error); + } + + /* Prompt the user for credentials */ + n_refs = g_variant_n_children (arg_refs); + if (!have_auth && n_refs > 0 && !no_interaction) { g_autoptr(GVariant) ref_data = g_variant_get_child_value (arg_refs, 0); - g_autofree char *token = NULL; while (auth == NULL) { @@ -498,13 +516,21 @@ if (test_auth == NULL) return cancel_request (request, sender); - token = get_token_for_ref (registry, ref_data, test_auth, &error); - if (token != NULL) - auth = g_steal_pointer (&test_auth); + first_token = get_token_for_ref (registry, ref_data, test_auth, &error); + if (first_token != NULL) + { + auth = g_steal_pointer (&test_auth); + have_auth = TRUE; + } + else + { + g_debug ("Failed to get token: %s", error->message); + g_clear_error (&error); + } } } - if (auth == NULL) + if (!have_auth) return error_request (request, sender, "No authentication information available"); g_variant_builder_init (&tokens, G_VARIANT_TYPE ("a{sas}")); @@ -515,9 +541,16 @@ char *for_refs_strv[2] = { NULL, NULL}; g_autofree char *token = NULL; - token = get_token_for_ref (registry, ref_data, auth, &error); - if (token == NULL) - return error_request (request, sender, error->message); + if (i == 0 && first_token != NULL) + { + token = g_steal_pointer (&first_token); + } + else + { + token = get_token_for_ref (registry, ref_data, auth, &error); + if (token == NULL) + return error_request (request, sender, error->message); + } g_variant_get_child (ref_data, 0, "&s", &for_refs_strv[0]); g_variant_builder_add (&tokens, "{s^as}", token, for_refs_strv);