diff options
author | Philip Withnall <withnall@endlessm.com> | 2019-08-21 11:43:13 +0300 |
---|---|---|
committer | Philip Withnall <withnall@endlessm.com> | 2019-08-21 12:31:30 +0300 |
commit | 3c6321a00e17c6f1b2d519699c1e958047162ab0 (patch) | |
tree | 1d0fba5a6a09b5d0732d88e43d3016d4111cd913 /gdata | |
parent | 427e3bed7b5e6edaa23ca4cc48e3caa9a224e6ed (diff) | |
download | libgdata-3c6321a00e17c6f1b2d519699c1e958047162ab0.tar.gz |
goa: Drop OAuth 1.0 support from GDataGoaAuthorizer
None of the account types supported by recent versions of GOA support
OAuth 1.0 authentication/authorisation, so drop it entirely in favour of
OAuth 2.0.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #1
Diffstat (limited to 'gdata')
-rw-r--r-- | gdata/gdata-goa-authorizer.c | 216 |
1 files changed, 5 insertions, 211 deletions
diff --git a/gdata/gdata-goa-authorizer.c b/gdata/gdata-goa-authorizer.c index ecfecaea..a5e650d8 100644 --- a/gdata/gdata-goa-authorizer.c +++ b/gdata/gdata-goa-authorizer.c @@ -60,9 +60,9 @@ * Since: 0.13.1 */ +#include <config.h> #include <stdlib.h> #include <string.h> -#include <oauth.h> #include <glib.h> #include "gdata-goa-authorizer.h" @@ -98,206 +98,6 @@ enum { G_DEFINE_TYPE_WITH_CODE (GDataGoaAuthorizer, gdata_goa_authorizer, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (GDATA_TYPE_AUTHORIZER, gdata_goa_authorizer_interface_init)) -static GHashTable * -gdata_goa_authorizer_get_oauth1_parameters (SoupMessage *message, const gchar *consumer_key, const gchar *consumer_secret, const gchar *access_token, - const gchar *access_token_secret) -{ - GString *query; - GString *base_string; - GString *signing_key; - GHashTable *parameters; - GHashTableIter iter; - SoupURI *soup_uri; - GList *keys, *i; - gchar *string; - gchar *request_uri; - gpointer key; - guchar signature_buf[HMAC_SHA1_LEN]; - gsize signature_buf_len; - GHmac *signature_hmac; - - parameters = g_hash_table_new_full ((GHashFunc) g_str_hash, (GEqualFunc) g_str_equal, (GDestroyNotify) NULL, (GDestroyNotify) g_free); - - /* soup_form_decode() uses an awkward allocation style for - * its hash table entries, so it's easier to copy its content - * into our own hash table than try to use the returned hash - * table directly. */ - - soup_uri = soup_message_get_uri (message); - if (soup_uri->query != NULL) { - GHashTable *hash_table; - gpointer value; - - hash_table = soup_form_decode (soup_uri->query); - g_hash_table_iter_init (&iter, hash_table); - while (g_hash_table_iter_next (&iter, &key, &value)) { - key = (gpointer) g_intern_string (key); - value = g_strdup (value); - g_hash_table_insert (parameters, key, value); - } - g_hash_table_destroy (hash_table); - } - - /* Add OAuth parameters. */ - - key = (gpointer) "oauth_version"; - g_hash_table_insert (parameters, key, g_strdup ("1.0")); - - string = oauth_gen_nonce (); - key = (gpointer) "oauth_nonce"; - g_hash_table_insert (parameters, key, g_strdup (string)); - free (string); /* do not use g_free () */ - - key = (gpointer) "oauth_timestamp"; - string = g_strdup_printf ("%" G_GINT64_FORMAT, (gint64) time (NULL)); - g_hash_table_insert (parameters, key, string); /* takes ownership */ - - key = (gpointer) "oauth_consumer_key"; - g_hash_table_insert (parameters, key, g_strdup (consumer_key)); - - key = (gpointer) "oauth_token"; - g_hash_table_insert (parameters, key, g_strdup (access_token)); - - key = (gpointer) "oauth_signature_method"; - g_hash_table_insert (parameters, key, g_strdup ("HMAC-SHA1")); - - /* Build the query part of the signature base string. */ - - query = g_string_sized_new (512); - keys = g_hash_table_get_keys (parameters); - keys = g_list_sort (keys, (GCompareFunc) g_strcmp0); - for (i = keys; i != NULL; i = g_list_next (i)) { - const gchar *_key = i->data; - const gchar *val; - - val = g_hash_table_lookup (parameters, _key); - - if (i != keys) { - g_string_append_c (query, '&'); - } - - g_string_append_uri_escaped (query, _key, NULL, FALSE); - g_string_append_c (query, '='); - g_string_append_uri_escaped (query, val, NULL, FALSE); - } - g_list_free (keys); - - /* Build the signature base string. */ - - soup_uri = soup_uri_copy (soup_uri); - soup_uri_set_query (soup_uri, NULL); - soup_uri_set_fragment (soup_uri, NULL); - request_uri = soup_uri_to_string (soup_uri, FALSE); - soup_uri_free (soup_uri); - - base_string = g_string_sized_new (512); - g_string_append_uri_escaped (base_string, message->method, NULL, FALSE); - g_string_append_c (base_string, '&'); - g_string_append_uri_escaped (base_string, request_uri, NULL, FALSE); - g_string_append_c (base_string, '&'); - g_string_append_uri_escaped (base_string, query->str, NULL, FALSE); - - /* Build the HMAC-SHA1 signing key. */ - - signing_key = g_string_sized_new (512); - g_string_append_uri_escaped (signing_key, consumer_secret, NULL, FALSE); - g_string_append_c (signing_key, '&'); - g_string_append_uri_escaped (signing_key, access_token_secret, NULL, FALSE); - - /* Sign the request. */ - signature_hmac = g_hmac_new (G_CHECKSUM_SHA1, (const guchar*) signing_key->str, signing_key->len); - g_hmac_update (signature_hmac, (const guchar*) base_string->str, base_string->len); - - signature_buf_len = G_N_ELEMENTS (signature_buf); - g_hmac_get_digest (signature_hmac, signature_buf, &signature_buf_len); - - g_hmac_unref (signature_hmac); - - key = (gpointer) "oauth_signature"; - string = g_base64_encode (signature_buf, signature_buf_len); - g_hash_table_insert (parameters, key, g_strdup (string)); - g_free (string); - - g_free (request_uri); - - g_string_free (query, TRUE); - g_string_free (base_string, TRUE); - g_string_free (signing_key, TRUE); - - return parameters; -} - -static void -gdata_goa_authorizer_add_oauth1_authorization (GDataAuthorizer *authorizer, SoupMessage *message) -{ - GDataGoaAuthorizerPrivate *priv; - GoaOAuthBased *goa_oauth_based; - GHashTable *parameters; - GString *authorization; - const gchar *consumer_key; - const gchar *consumer_secret; - guint ii; - - const gchar *oauth_keys[] = { - "oauth_version", - "oauth_nonce", - "oauth_timestamp", - "oauth_consumer_key", - "oauth_token", - "oauth_signature_method", - "oauth_signature" - }; - - /* This MUST be called with the mutex already locked. */ - - priv = GDATA_GOA_AUTHORIZER (authorizer)->priv; - - /* We can't add an Authorization header without an access token. - * Let the request fail. GData should refresh us if it gets back - * a "401 Authorization required" response from Google, and then - * automatically retry the request. */ - if (priv->access_token == NULL) { - return; - } - - goa_oauth_based = goa_object_get_oauth_based (priv->goa_object); - - consumer_key = goa_oauth_based_get_consumer_key (goa_oauth_based); - consumer_secret = goa_oauth_based_get_consumer_secret (goa_oauth_based); - - parameters = gdata_goa_authorizer_get_oauth1_parameters (message, consumer_key, consumer_secret, - priv->access_token, priv->access_token_secret); - - authorization = g_string_new ("OAuth "); - - for (ii = 0; ii < G_N_ELEMENTS (oauth_keys); ii++) { - const gchar *key; - const gchar *val; - - key = oauth_keys[ii]; - val = g_hash_table_lookup (parameters, key); - - if (ii > 0) { - g_string_append (authorization, ", "); - } - - g_string_append (authorization, key); - g_string_append_c (authorization, '='); - g_string_append_c (authorization, '"'); - g_string_append_uri_escaped (authorization, val, NULL, FALSE); - g_string_append_c (authorization, '"'); - } - - /* Use replace here, not append, to make sure - * there's only one "Authorization" header. */ - soup_message_headers_replace (message->request_headers, "Authorization", authorization->str); - - g_string_free (authorization, TRUE); - g_hash_table_destroy (parameters); - - g_object_unref (goa_oauth_based); -} - static void gdata_goa_authorizer_add_oauth2_authorization (GDataAuthorizer *authorizer, SoupMessage *message) { @@ -332,11 +132,11 @@ gdata_goa_authorizer_add_authorization (GDataAuthorizer *authorizer, SoupMessage priv = GDATA_GOA_AUTHORIZER (authorizer)->priv; - /* Prefer OAuth 2.0 over OAuth 1.0. */ + /* Only support OAuth 2.0. OAuth 1.0 was deprecated in 2012. */ if (goa_object_peek_oauth2_based (priv->goa_object) != NULL) { gdata_goa_authorizer_add_oauth2_authorization (authorizer, message); - } else if (goa_object_peek_oauth_based (priv->goa_object) != NULL) { - gdata_goa_authorizer_add_oauth1_authorization (authorizer, message); + } else { + g_warn_if_reached (); } } @@ -480,7 +280,6 @@ static gboolean gdata_goa_authorizer_refresh_authorization (GDataAuthorizer *authorizer, GCancellable *cancellable, GError **error) { GDataGoaAuthorizerPrivate *priv; - GoaOAuthBased *goa_oauth1_based; GoaOAuth2Based *goa_oauth2_based; GoaAccount *goa_account; gboolean success = FALSE; @@ -496,7 +295,6 @@ gdata_goa_authorizer_refresh_authorization (GDataAuthorizer *authorizer, GCancel priv->access_token_secret = NULL; goa_account = goa_object_get_account (priv->goa_object); - goa_oauth1_based = goa_object_get_oauth_based (priv->goa_object); goa_oauth2_based = goa_object_get_oauth2_based (priv->goa_object); success = goa_account_call_ensure_credentials_sync (goa_account, NULL, cancellable, error); @@ -505,19 +303,15 @@ gdata_goa_authorizer_refresh_authorization (GDataAuthorizer *authorizer, GCancel goto exit; } - /* Prefer OAuth 2.0 over OAuth 1.0. */ + /* Only support OAuth 2.0. */ if (goa_oauth2_based != NULL) { success = goa_oauth2_based_call_get_access_token_sync (goa_oauth2_based, &priv->access_token, NULL, cancellable, error); - } else if (goa_oauth1_based != NULL) { - success = goa_oauth_based_call_get_access_token_sync (goa_oauth1_based, &priv->access_token, &priv->access_token_secret, NULL, - cancellable, error); } else { g_warn_if_reached (); /* should never happen */ } exit: g_clear_object (&goa_account); - g_clear_object (&goa_oauth1_based); g_clear_object (&goa_oauth2_based); g_mutex_unlock (&mutex); |