From 8e116e9a98b3b70b096e4f244dde60da557b8798e6b7bf254fb6d74fc37cb170 Mon Sep 17 00:00:00 2001 From: Dominique Leuenberger Date: Tue, 13 Sep 2022 07:36:38 +0000 Subject: [PATCH] Accepting request 1002686 from GNOME:Next GNOME 43.rc - let's get this into Staging to see what we break (e.g meson:test seems to be an issue already) OBS-URL: https://build.opensuse.org/request/show/1002686 OBS-URL: https://build.opensuse.org/package/show/GNOME:Factory/seahorse?expand=0&rev=219 --- ab2f253c.patch | 760 +++++++++++++++++++++++++++++++++++++++++++++++ seahorse.changes | 7 + seahorse.spec | 6 +- 3 files changed, 772 insertions(+), 1 deletion(-) create mode 100644 ab2f253c.patch diff --git a/ab2f253c.patch b/ab2f253c.patch new file mode 100644 index 0000000..770baca --- /dev/null +++ b/ab2f253c.patch @@ -0,0 +1,760 @@ +From ab2f253ca7ff65462c3f429cdeb9e58798f7091d Mon Sep 17 00:00:00 2001 +From: Niels De Graef +Date: Sun, 26 Jun 2022 20:22:06 +0200 +Subject: [PATCH] hkp: Port to libsoup3 + +--- + meson.build | 2 +- + pgp/seahorse-hkp-source.c | 436 +++++++++++++++++--------------------- + 2 files changed, 198 insertions(+), 240 deletions(-) + +diff --git a/meson.build b/meson.build +index ec83e64f..0e3c7b16 100644 +--- a/meson.build ++++ b/meson.build +@@ -78,7 +78,7 @@ endif + if get_option('hkp-support') + add_project_arguments('-D', 'WITH_HKP', language: 'vala') + endif +-libsoup = dependency('libsoup-2.4', version: '>= 2.33.92', required: get_option('hkp-support')) ++libsoup = dependency('libsoup-3.0', required: get_option('hkp-support')) + avahi_client = dependency('avahi-client', required: get_option('key-sharing')) + avahi_glib = dependency('avahi-glib', version: '>= 0.6', required: get_option('key-sharing')) + +diff --git a/pgp/seahorse-hkp-source.c b/pgp/seahorse-hkp-source.c +index 515e0da4..1e906f90 100644 +--- a/pgp/seahorse-hkp-source.c ++++ b/pgp/seahorse-hkp-source.c +@@ -51,11 +51,6 @@ + #define PGP_KEY_BEGIN "-----BEGIN PGP PUBLIC KEY BLOCK-----" + #define PGP_KEY_END "-----END PGP PUBLIC KEY BLOCK-----" + +-#define SOUP_MESSAGE_IS_ERROR(msg) \ +- (SOUP_STATUS_IS_TRANSPORT_ERROR((msg)->status_code) || \ +- SOUP_STATUS_IS_CLIENT_ERROR((msg)->status_code) || \ +- SOUP_STATUS_IS_SERVER_ERROR((msg)->status_code)) +- + G_DEFINE_QUARK (seahorse-hkp-error, seahorse_hkp_error); + + struct _SeahorseHKPSource { +@@ -64,33 +59,48 @@ struct _SeahorseHKPSource { + + G_DEFINE_TYPE (SeahorseHKPSource, seahorse_hkp_source, SEAHORSE_TYPE_SERVER_SOURCE); + +-/** +- * self: The SeahorseSource to use as server for the uri +- * path: The path to add to the SOUP uri +- * +- * Returns: A #SoupUri with server, port and paths +- */ +-static SoupURI* +-get_http_server_uri (SeahorseHKPSource *self, const char *path) ++/* Helper method */ ++static GUri * ++get_http_server_uri (SeahorseHKPSource *self, ++ const char *path, ++ GHashTable *query_hash) + { +- g_autoptr(SoupURI) uri = NULL; +- g_autofree char *conf_uri = NULL; +- +- conf_uri = seahorse_place_get_uri (SEAHORSE_PLACE (self)); +- g_return_val_if_fail (conf_uri != NULL, NULL); +- +- if (strncasecmp (conf_uri, "hkp:", 4) == 0) { +- g_autofree char *t = g_strdup_printf ("http:%s", conf_uri + 4); +- uri = soup_uri_new (t); +- } else if (strncasecmp (conf_uri, "hkps:", 5) == 0) { +- g_autofree char *t = g_strdup_printf ("https:%s", conf_uri + 5); +- uri = soup_uri_new (t); ++ g_autofree char *uri = NULL; ++ gboolean parsed; ++ g_autofree char *scheme = NULL; ++ g_autofree char *host = NULL; ++ int port; ++ g_autoptr(GError) error = NULL; ++ g_autofree char *query = NULL; ++ ++ /* Take the (user-)configured URI */ ++ uri = seahorse_place_get_uri (SEAHORSE_PLACE (self)); ++ g_return_val_if_fail (uri != NULL, NULL); ++ ++ /* NOTE: seahorse_hkp_is_valid_uri already checked certain fields */ ++ parsed = g_uri_split (uri, G_URI_FLAGS_NONE, ++ &scheme, NULL, &host, &port, NULL, NULL, NULL, ++ &error); ++ if (!parsed) { ++ g_warning ("Bad URL for HKP server '%s': %s", uri, error->message); ++ return NULL; + } + +- soup_uri_set_path (uri, path); ++ /* Fixup the scheme if needed */ ++ if (g_strcmp0 (scheme, "hkp") == 0) { ++ g_free (scheme); ++ scheme = g_strdup ("http"); ++ } else if (g_strcmp0 (scheme, "hkps") == 0) { ++ g_free (scheme); ++ scheme = g_strdup ("https"); ++ } + +- g_debug ("HTTP Server URI: %s", soup_uri_to_string(uri, FALSE)); +- return g_steal_pointer (&uri); ++ /* We assume people won't use a query (and validate that earlier also) */ ++ if (query_hash != NULL) ++ query = soup_form_encode_hash (query_hash); ++ ++ return g_uri_build (G_URI_FLAGS_NONE, ++ scheme, NULL, host, port, path, query, NULL); + } + + static SoupSession * +@@ -99,7 +109,7 @@ create_hkp_soup_session (void) + SoupSession *session; + #ifdef WITH_DEBUG + g_autoptr(SoupLogger) logger = NULL; +- const gchar *env; ++ const char *env; + #endif + + session = soup_session_new (); +@@ -107,7 +117,7 @@ create_hkp_soup_session (void) + #ifdef WITH_DEBUG + env = g_getenv ("G_MESSAGES_DEBUG"); + if (env && strstr (env, "seahorse")) { +- logger = soup_logger_new (SOUP_LOGGER_LOG_BODY, -1); ++ logger = soup_logger_new (SOUP_LOGGER_LOG_BODY); + soup_session_add_feature (session, SOUP_SESSION_FEATURE (logger)); + } + #endif +@@ -127,10 +137,10 @@ create_hkp_soup_session (void) + * + **/ + static void +-dehtmlize (gchar *line) ++dehtmlize (char *line) + { + int parsedindex = 0; +- gchar *parsed = line; ++ char *parsed = line; + + g_return_if_fail (line); + +@@ -230,10 +240,8 @@ parse_hkp_flags (char *flags) + GList * + seahorse_hkp_parse_lookup_response (const char *response) + { +- /* +- * Use The OpenPGP HTTP Keyserver Protocol (HKP) to search and get keys +- * https://tools.ietf.org/html/draft-shaw-openpgp-hkp-00#section-5 +- */ ++ /* Use The OpenPGP HTTP Keyserver Protocol (HKP) to search and get keys ++ * https://tools.ietf.org/html/draft-shaw-openpgp-hkp-00#section-5 */ + g_auto(GStrv) lines = NULL; + SeahorsePgpKey *key = NULL; + GList *keys = NULL; +@@ -377,7 +385,7 @@ seahorse_hkp_parse_lookup_response (const char *response) + seahorse_pgp_key_realize (SEAHORSE_PGP_KEY (k->data)); + + if (key_total != 0 && key_total != key_count) { +- g_message ("HKP Parse; Warning: Issue during HKP parsing, only %d keys were parsed out of %d", key_count, key_total); ++ g_warning ("HKP Parse: Could only parse %d keys out of %d", key_count, key_total); + } else { + g_debug ("HKP Parse: %d keys parsed successfully", key_count); + } +@@ -441,10 +449,7 @@ get_send_result (const char *response) + static gboolean + detect_key (const char *text, int len, const char **start, const char **end) + { +- const gchar *t; +- +- if (len == -1) +- len = strlen (text); ++ const char *t; + + /* Find the first of the headers */ + if ((t = g_strstr_len (text, len, PGP_KEY_BEGIN)) == NULL) +@@ -461,55 +466,9 @@ detect_key (const char *text, int len, const char **start, const char **end) + return TRUE; + } + +-static gboolean +-hkp_message_propagate_error (SeahorseHKPSource *self, +- SoupMessage *message, +- GError **error) +-{ +- g_autofree char *uri = NULL; +- g_autofree char *text = NULL; +- +- if (!SOUP_MESSAGE_IS_ERROR (message)) +- return FALSE; +- +- if (message->status_code == SOUP_STATUS_CANCELLED) { +- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CANCELLED, +- _("The operation was cancelled")); +- return TRUE; +- } +- +- uri = seahorse_place_get_uri (SEAHORSE_PLACE (self)); +- +- /* Make the body lower case, and no tags */ +- text = g_strndup (message->response_body->data, message->response_body->length); +- if (text != NULL) { +- char *text_lower; +- +- dehtmlize (text); +- text_lower = g_ascii_strdown (text, -1); +- g_free (text); +- text = text_lower; +- } +- +- if (text && strstr (text, "no keys")) +- return FALSE; /* not found is not an error */ +- +- if (text && strstr (text, "too many")) { +- g_set_error (error, HKP_ERROR_DOMAIN, 0, +- _("Search was not specific enough. Server “%s” found too many keys."), +- uri); +- } else { +- g_set_error (error, HKP_ERROR_DOMAIN, message->status_code, +- _("Couldn’t communicate with server “%s”: %s"), +- uri, message->reason_phrase); +- } +- +- return TRUE; +-} +- + static void + on_session_cancelled (GCancellable *cancellable, +- gpointer user_data) ++ void *user_data) + { + SoupSession *session = user_data; + soup_session_abort (session); +@@ -517,49 +476,54 @@ on_session_cancelled (GCancellable *cancellable, + + typedef struct { + SeahorseHKPSource *source; +- GCancellable *cancellable; +- gulong cancelled_sig; + SoupSession *session; ++ SoupMessage *message; ++ GString *response; + int requests; + GcrSimpleCollection *results; +-} source_search_closure; ++} SearchClosure; + + static void +-source_search_free (gpointer data) ++source_search_free (void *data) + { +- source_search_closure *closure = data; +- g_object_unref (closure->source); +- g_cancellable_disconnect (closure->cancellable, closure->cancelled_sig); +- g_clear_object (&closure->cancellable); +- g_object_unref (closure->session); ++ SearchClosure *closure = data; ++ g_clear_object (&closure->source); ++ g_clear_object (&closure->message); ++ if (closure->response != NULL) ++ g_string_free (closure->response, TRUE); ++ g_clear_object (&closure->session); + g_clear_object (&closure->results); + g_free (closure); + } + + static void +-on_search_message_complete (SoupSession *session, +- SoupMessage *message, +- gpointer user_data) ++on_search_message_complete (GObject *object, ++ GAsyncResult *result, ++ void *user_data) + { ++ SoupSession *session = SOUP_SESSION (object); + g_autoptr(GTask) task = G_TASK (user_data); +- source_search_closure *closure = g_task_get_task_data (task); ++ SearchClosure *closure = g_task_get_task_data (task); ++ GCancellable *cancellable = g_task_get_cancellable (task); ++ g_autoptr(GBytes) response = NULL; + g_autoptr(GError) error = NULL; +- GList *keys, *l; ++ g_autolist(SeahorsePgpKey) keys = NULL; + +- seahorse_progress_end (closure->cancellable, message); ++ seahorse_progress_end (cancellable, closure->message); + +- if (hkp_message_propagate_error (closure->source, message, &error)) { ++ response = soup_session_send_and_read_finish (session, result, &error); ++ if (response == NULL) { + g_task_return_error (task, g_steal_pointer (&error)); + return; + } + +- keys = seahorse_hkp_parse_lookup_response (message->response_body->data); +- for (l = keys; l; l = g_list_next (l)) { ++ closure->response = g_string_new_len (g_bytes_get_data (response, NULL), ++ g_bytes_get_size (response)); ++ keys = seahorse_hkp_parse_lookup_response (closure->response->str); ++ for (GList *l = keys; l; l = g_list_next (l)) { + g_object_set (l->data, "place", closure->source, NULL); + gcr_simple_collection_add (closure->results, l->data); + } +- g_list_free_full (keys, g_object_unref); +- + g_task_return_boolean (task, TRUE); + } + +@@ -589,24 +553,19 @@ seahorse_hkp_source_search_async (SeahorseServerSource *source, + void *user_data) + { + SeahorseHKPSource *self = SEAHORSE_HKP_SOURCE (source); +- source_search_closure *closure; ++ SearchClosure *closure; + g_autoptr(GTask) task = NULL; + g_autoptr(GHashTable) form = NULL; +- SoupMessage *message; +- g_autoptr(SoupURI) uri = NULL; ++ g_autoptr(GUri) uri = NULL; + g_autofree char *uri_str = NULL; + + task = g_task_new (source, cancellable, callback, user_data); +- closure = g_new0 (source_search_closure, 1); ++ closure = g_new0 (SearchClosure, 1); + closure->source = g_object_ref (self); +- closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + closure->session = create_hkp_soup_session (); + closure->results = g_object_ref (results); + g_task_set_task_data (task, closure, source_search_free); + +- uri = get_http_server_uri (self, "/pks/lookup"); +- g_return_if_fail (uri); +- + form = g_hash_table_new (g_str_hash, g_str_equal); + g_hash_table_insert (form, "op", "index"); + g_hash_table_insert (form, "options", "mr"); +@@ -622,22 +581,27 @@ seahorse_hkp_source_search_async (SeahorseServerSource *source, + + g_hash_table_insert (form, "fingerprint", "on"); + +- soup_uri_set_query_from_form (uri, form); +- message = soup_message_new_from_uri ("GET", uri); ++ uri = get_http_server_uri (self, "/pks/lookup", form); ++ g_return_if_fail (uri); ++ ++ closure->message = soup_message_new_from_uri ("GET", uri); + +- seahorse_progress_prep_and_begin (cancellable, message, NULL); ++ seahorse_progress_prep_and_begin (cancellable, closure->message, NULL); + +- uri_str = soup_uri_to_string (uri, TRUE); ++ uri_str = g_uri_to_string_partial (uri, G_URI_HIDE_PASSWORD); + g_debug ("Sending HKP search query to '%s'", uri_str); + +- soup_session_queue_message (closure->session, g_steal_pointer (&message), +- on_search_message_complete, +- g_steal_pointer (&task)); ++ soup_session_send_and_read_async (closure->session, ++ closure->message, ++ G_PRIORITY_DEFAULT, ++ cancellable, ++ on_search_message_complete, ++ g_steal_pointer (&task)); + + if (cancellable) +- closure->cancelled_sig = g_cancellable_connect (cancellable, +- G_CALLBACK (on_session_cancelled), +- closure->session, NULL); ++ g_cancellable_connect (cancellable, ++ G_CALLBACK (on_session_cancelled), ++ closure->session, NULL); + } + + static gboolean +@@ -654,45 +618,51 @@ seahorse_hkp_source_search_finish (SeahorseServerSource *source, + typedef struct { + SeahorseHKPSource *source; + GInputStream *input; +- GCancellable *cancellable; +- gulong cancelled_sig; + SoupSession *session; ++ SoupMessage *message; + int requests; +-} source_import_closure; ++} ImportClosure; + + static void +-source_import_free (gpointer data) ++source_import_free (void *data) + { +- source_import_closure *closure = data; ++ ImportClosure *closure = data; + g_object_unref (closure->source); + g_object_unref (closure->input); +- g_cancellable_disconnect (closure->cancellable, closure->cancelled_sig); +- g_clear_object (&closure->cancellable); ++ g_object_unref (closure->message); + g_object_unref (closure->session); + g_free (closure); + } + + static void +-on_import_message_complete (SoupSession *session, +- SoupMessage *message, +- gpointer user_data) ++on_import_message_complete (GObject *object, ++ GAsyncResult *result, ++ void *user_data) + { ++ SoupSession *session = SOUP_SESSION (object); + g_autoptr(GTask) task = G_TASK (user_data); +- source_import_closure *closure = g_task_get_task_data (task); ++ ImportClosure *closure = g_task_get_task_data (task); ++ GCancellable *cancellable = g_task_get_cancellable (task); ++ g_autoptr(GBytes) response = NULL; ++ g_autoptr(GString) response_str = NULL; + g_autoptr(GError) error = NULL; +- g_autofree gchar *errmsg = NULL; ++ g_autofree char *errmsg = NULL; + + g_assert (closure->requests > 0); +- seahorse_progress_end (closure->cancellable, GUINT_TO_POINTER (closure->requests)); ++ seahorse_progress_end (cancellable, GUINT_TO_POINTER (closure->requests)); + closure->requests--; + +- if (hkp_message_propagate_error (closure->source, message, &error)) { ++ response = soup_session_send_and_read_finish (session, result, &error); ++ if (!response) { + g_task_return_error (task, g_steal_pointer (&error)); + return; + } + +- if ((errmsg = get_send_result (message->response_body->data)) != NULL) { +- g_task_return_new_error (task, HKP_ERROR_DOMAIN, message->status_code, ++ response_str = g_string_new_len (g_bytes_get_data (response, NULL), ++ g_bytes_get_size (response)); ++ if ((errmsg = get_send_result (response_str->str)) != NULL) { ++ g_task_return_new_error (task, HKP_ERROR_DOMAIN, ++ soup_message_get_status (closure->message), + "%s", errmsg); + return; + } +@@ -709,24 +679,22 @@ seahorse_hkp_source_import_async (SeahorseServerSource *source, + GInputStream *input, + GCancellable *cancellable, + GAsyncReadyCallback callback, +- gpointer user_data) ++ void *user_data) + { + SeahorseHKPSource *self = SEAHORSE_HKP_SOURCE (source); + g_autoptr(GTask) task = NULL; +- source_import_closure *closure; +- g_autoptr(GList) keydata = NULL; +- g_autoptr(GHashTable) form = NULL; +- g_autoptr(SoupURI) uri = NULL; +- GList *l; ++ ImportClosure *closure; ++ g_autoptr(GPtrArray) keydata = NULL; ++ g_autoptr(GUri) uri = NULL; + + task = g_task_new (source, cancellable, callback, user_data); +- closure = g_new0 (source_import_closure, 1); +- closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL; ++ closure = g_new0 (ImportClosure, 1); + closure->input = g_object_ref (input); + closure->source = g_object_ref (self); + closure->session = create_hkp_soup_session (); + g_task_set_task_data (task, closure, source_import_free); + ++ keydata = g_ptr_array_new_with_free_func (g_free); + for (;;) { + g_autoptr(GString) buf = g_string_sized_new (2048); + guint len; +@@ -737,53 +705,46 @@ seahorse_hkp_source_import_async (SeahorseServerSource *source, + if (len <= 0) + break; + +- keydata = g_list_prepend (keydata, +- g_string_free (g_steal_pointer (&buf), FALSE)); ++ g_ptr_array_add (keydata, g_string_free (g_steal_pointer (&buf), FALSE)); + } + +- if (g_list_length (keydata) == 0) { ++ if (keydata->len == 0) { + g_task_return_pointer (task, NULL, NULL); + return; + } + + /* Figure out the URI we're sending to */ +- uri = get_http_server_uri (self, "/pks/add"); ++ uri = get_http_server_uri (self, "/pks/add", NULL); + g_return_if_fail (uri); + +- /* New operation and away we go */ +- keydata = g_list_reverse (keydata); +- +- form = g_hash_table_new (g_str_hash, g_str_equal); +- for (l = keydata; l; l = g_list_next (l)) { +- g_autoptr(SoupMessage) message = NULL; +- gchar *key; +- +- g_assert (l->data != NULL); +- g_hash_table_remove_all (form); ++ for (unsigned int i = 0; i < keydata->len; i++) { ++ const char *keytext = g_ptr_array_index (keydata, i); ++ g_autofree char *key = NULL; ++ g_autoptr(GBytes) bytes = NULL; + +- g_hash_table_insert (form, "keytext", l->data); +- key = soup_form_encode_urlencoded (form); ++ closure->message = soup_message_new_from_uri ("POST", uri); + +- message = soup_message_new_from_uri ("POST", uri); +- soup_message_set_request (message, "application/x-www-form-urlencoded", +- SOUP_MEMORY_TAKE, key, strlen (key)); ++ key = soup_form_encode ("keytext", keytext, NULL); ++ bytes = g_bytes_new_static (key, strlen (key)); ++ soup_message_set_request_body_from_bytes (closure->message, ++ "application/x-www-form-urlencoded", ++ bytes); + +- soup_session_queue_message (closure->session, +- g_steal_pointer (&message), +- on_import_message_complete, +- g_object_ref (task)); ++ soup_session_send_and_read_async (closure->session, ++ closure->message, ++ G_PRIORITY_DEFAULT, ++ cancellable, ++ on_import_message_complete, ++ g_steal_pointer (&task)); + + closure->requests++; + seahorse_progress_prep_and_begin (cancellable, GUINT_TO_POINTER (closure->requests), NULL); + } + + if (cancellable) +- closure->cancelled_sig = g_cancellable_connect (cancellable, +- G_CALLBACK (on_session_cancelled), +- closure->session, NULL); +- +- for (l = keydata; l != NULL; l = g_list_next (l)) +- g_free (l->data); ++ g_cancellable_connect (cancellable, ++ G_CALLBACK (on_session_cancelled), ++ closure->session, NULL); + } + + static GList * +@@ -801,46 +762,46 @@ typedef struct { + SeahorseHKPSource *source; + GString *data; + gsize data_len; +- GCancellable *cancellable; +- gulong cancelled_sig; + SoupSession *session; ++ SoupMessage *message; + int requests; + } ExportClosure; + + static void +-export_closure_free (gpointer data) ++export_closure_free (void *data) + { + ExportClosure *closure = data; +- g_object_unref (closure->source); ++ g_clear_object (&closure->source); + if (closure->data) + g_string_free (closure->data, TRUE); +- g_cancellable_disconnect (closure->cancellable, closure->cancelled_sig); +- g_clear_object (&closure->cancellable); +- g_object_unref (closure->session); ++ g_clear_object (&closure->message); ++ g_clear_object (&closure->session); + g_free (closure); + } + + static void +-on_export_message_complete (SoupSession *session, +- SoupMessage *message, +- gpointer user_data) ++on_export_message_complete (GObject *object, ++ GAsyncResult *result, ++ void *user_data) + { ++ SoupSession *session = SOUP_SESSION (object); + g_autoptr(GTask) task = G_TASK (user_data); + ExportClosure *closure = g_task_get_task_data (task); ++ GCancellable *cancellable = g_task_get_cancellable (task); ++ g_autoptr(GBytes) response = NULL; + g_autoptr(GError) error = NULL; +- const gchar *start, *end, *text; +- guint len; ++ const char *start, *end, *text; ++ size_t len; + +- seahorse_progress_end (closure->cancellable, message); ++ seahorse_progress_end (cancellable, closure->message); + +- if (hkp_message_propagate_error (closure->source, message, &error)) { ++ response = soup_session_send_and_read_finish (session, result, &error); ++ if (response == NULL) { + g_task_return_error (task, g_steal_pointer (&error)); + return; + } + +- end = text = message->response_body->data; +- len = message->response_body->length; +- ++ end = text = g_bytes_get_data (response, &len); + for (;;) { + len -= end - text; + text = end; +@@ -865,23 +826,20 @@ on_export_message_complete (SoupSession *session, + + static void + seahorse_hkp_source_export_async (SeahorseServerSource *source, +- const gchar **keyids, ++ const char **keyids, + GCancellable *cancellable, + GAsyncReadyCallback callback, +- gpointer user_data) ++ void *user_data) + { + SeahorseHKPSource *self = SEAHORSE_HKP_SOURCE (source); + ExportClosure *closure; + g_autoptr(GTask) task = NULL; +- SoupURI *uri; +- g_autoptr(GHashTable) form = NULL; + + task = g_task_new (self, cancellable, callback, user_data); + closure = g_new0 (ExportClosure, 1); + closure->source = g_object_ref (self); + closure->data = g_string_sized_new (1024); + closure->session = create_hkp_soup_session (); +- closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + g_task_set_task_data (task, closure, export_closure_free); + + if (!keyids || !keyids[0]) { +@@ -889,17 +847,15 @@ seahorse_hkp_source_export_async (SeahorseServerSource *source, + return; + } + +- uri = get_http_server_uri (self, "/pks/lookup"); +- g_return_if_fail (uri); + +- form = g_hash_table_new (g_str_hash, g_str_equal); + for (int i = 0; keyids[i] != NULL; i++) { + const char *fpr = keyids[i]; + size_t len; + g_autofree char *hexfpr = NULL; +- SoupMessage *message; ++ g_autoptr(GHashTable) form = NULL; ++ g_autoptr(GUri) uri = NULL; + +- g_hash_table_remove_all (form); ++ form = g_hash_table_new (g_str_hash, g_str_equal); + + /* Get the key id and limit it to 16 characters */ + len = strlen (fpr); +@@ -912,25 +868,30 @@ seahorse_hkp_source_export_async (SeahorseServerSource *source, + /* The get key URI */ + g_hash_table_insert (form, "op", "get"); + g_hash_table_insert (form, "search", (char *)hexfpr); +- soup_uri_set_query_from_form (uri, form); + +- message = soup_message_new_from_uri ("GET", uri); ++ uri = get_http_server_uri (self, "/pks/lookup", form); ++ g_return_if_fail (uri); + +- soup_session_queue_message (closure->session, message, +- on_export_message_complete, +- g_object_ref (task)); ++ closure->message = soup_message_new_from_uri ("GET", uri); ++ ++ soup_session_send_and_read_async (closure->session, ++ closure->message, ++ G_PRIORITY_DEFAULT, ++ cancellable, ++ on_export_message_complete, ++ g_steal_pointer (&task)); + + closure->requests++; +- seahorse_progress_prep_and_begin (cancellable, message, NULL); ++ seahorse_progress_prep_and_begin (cancellable, closure->message, NULL); + } + + if (cancellable) +- closure->cancelled_sig = g_cancellable_connect (cancellable, +- G_CALLBACK (on_session_cancelled), +- closure->session, NULL); ++ g_cancellable_connect (cancellable, ++ G_CALLBACK (on_session_cancelled), ++ closure->session, NULL); + } + +-static gpointer ++static void * + seahorse_hkp_source_export_finish (SeahorseServerSource *source, + GAsyncResult *result, + gsize *size, +@@ -987,35 +948,32 @@ seahorse_hkp_source_new (const char *uri) + * Returns: Whether the passed uri is valid for an HKP key source + */ + gboolean +-seahorse_hkp_is_valid_uri (const gchar *uri) ++seahorse_hkp_is_valid_uri (const char *uri) + { +- SoupURI *soup; +- gboolean ret = FALSE; ++ g_autoptr(GUri) parsed = NULL; ++ const char *scheme; + + g_return_val_if_fail (uri && uri[0], FALSE); + +- /* Replace 'hkp' with 'http' at the beginning of the URI */ +- if (strncasecmp (uri, "hkp:", 4) == 0) { +- g_autofree char *t = g_strdup_printf ("http:%s", uri + 4); +- soup = soup_uri_new (t); +- /* Not 'hkp', but maybe 'http' */ +- } else if (strncasecmp (uri, "hkps:", 5) == 0) { +- g_autofree char *t = g_strdup_printf ("https:%s", uri + 5); +- soup = soup_uri_new (t); +- } else { +- soup = soup_uri_new (uri); +- } ++ parsed = g_uri_parse (uri, G_URI_FLAGS_NONE, NULL); ++ if (!parsed) ++ return FALSE; + +- if (soup) { +- /* Must be http or https, have a host. No querystring, user, path, passwd etc... */ +- if ((soup->scheme == SOUP_URI_SCHEME_HTTP || soup->scheme == SOUP_URI_SCHEME_HTTPS) && +- !soup->user && !soup->password && !soup->query && !soup->fragment && +- soup->host && soup->host[0] && g_str_equal (soup->path ? soup->path : "/", "/")) +- ret = TRUE; +- soup_uri_free (soup); +- } ++ scheme = g_uri_get_scheme (parsed); ++ if (g_strcmp0 (scheme, "hkp") && g_strcmp0 (scheme, "hkps") && ++ g_strcmp0 (scheme, "http") && g_strcmp0 (scheme, "https")) ++ return FALSE; ++ ++ if (g_uri_get_host (parsed) == NULL) ++ return FALSE; ++ if (g_uri_get_userinfo (parsed) != NULL && g_uri_get_userinfo (parsed)[0] != '\0') ++ return FALSE; ++ if (g_uri_get_path (parsed) != NULL && g_uri_get_path (parsed)[0] != '\0') ++ return FALSE; ++ if (g_uri_get_query (parsed) != NULL) ++ return FALSE; + +- return ret; ++ return TRUE; + } + + #endif /* WITH_HKP */ +-- +GitLab + diff --git a/seahorse.changes b/seahorse.changes index 2f0affa..23401d9 100644 --- a/seahorse.changes +++ b/seahorse.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Thu Sep 1 13:49:50 UTC 2022 - Bjørn Lie + +- Add ab2f253c.patch: Port to soup3. Following this, replace + pkgconfig(libsoup-2.4) with pkgconfig(libsoup-3.0) BuildRequires. +- Build sub-package gnome-shell-search-provider-seahorse as noarch. + ------------------------------------------------------------------- Mon May 23 14:34:16 UTC 2022 - Dominique Leuenberger diff --git a/seahorse.spec b/seahorse.spec index 8044d8a..5fbab1b 100644 --- a/seahorse.spec +++ b/seahorse.spec @@ -24,6 +24,9 @@ License: GFDL-1.1-only AND GPL-2.0-or-later AND LGPL-2.1-or-later Group: Productivity/Security URL: https://wiki.gnome.org/Apps/Seahorse Source0: https://download.gnome.org/sources/seahorse/42/%{name}-%{version}.tar.xz +# PATCH-FIX-UPSTREAM ab2f253c.patch -- Port to soup3 +Patch0: https://gitlab.gnome.org/GNOME/seahorse/-/commit/ab2f253c.patch + BuildRequires: docbook-xsl-stylesheets BuildRequires: fdupes BuildRequires: gpg2 >= 2.2.0 @@ -48,7 +51,7 @@ BuildRequires: pkgconfig(gpgme) >= 1.14.0 BuildRequires: pkgconfig(gtk+-3.0) >= 3.24.0 BuildRequires: pkgconfig(libhandy-1) >= 1.5.0 BuildRequires: pkgconfig(libsecret-1) >= 0.16 -BuildRequires: pkgconfig(libsoup-2.4) >= 2.33.92 +BuildRequires: pkgconfig(libsoup-3.0) >= 2.33.92 BuildRequires: pkgconfig(pwquality) Obsoletes: %{name}-devel < %{version} @@ -59,6 +62,7 @@ Seahorse is a GNOME interface for gnupg. It uses gpgme as the backend. Summary: GNOME interface for gnupg -- Search Provider for GNOME Shell Group: Productivity/Security Supplements: (%{name} and gnome-shell) +BuildArch: noarch %description -n gnome-shell-search-provider-seahorse Seahorse is a GNOME interface for gnupg. It uses gpgme as the backend.