static gchar* _make_base_string( GSignondSessionData *session_data, SoupURI* uri, gchar* nonce, gchar* timestamp) { GString* base_string = g_string_new("POST&"); gchar* base_uri; if (soup_uri_uses_default_port(uri)) base_uri = g_strdup_printf("https://%s%s", soup_uri_get_host(uri), soup_uri_get_path(uri)); else base_uri = g_strdup_printf("https://%s:%u%s", soup_uri_get_host(uri), soup_uri_get_port(uri), soup_uri_get_path(uri)); gchar* base_uri_e = _percent_encode(base_uri); g_string_append(base_string, base_uri_e); g_string_append(base_string, "&"); g_free(base_uri); g_free(base_uri_e); GTree* parameters = g_tree_new((GCompareFunc)g_strcmp0); const gchar* query_s = soup_uri_get_query(uri); GHashTable* query; if (query_s != NULL) query = soup_form_decode(query_s); else query = soup_form_decode(""); g_hash_table_foreach(query, _insert_into_tree, parameters); const gchar* callback_uri = gsignond_dictionary_get_string(session_data, "Callback"); if (callback_uri != NULL) g_tree_insert(parameters, "oauth_callback", (gchar*)callback_uri); const gchar* oauth_verifier = gsignond_dictionary_get_string(session_data, "_OauthVerifier"); if (oauth_verifier != NULL) g_tree_insert(parameters, "oauth_verifier", (gchar*)oauth_verifier); g_tree_insert(parameters, "oauth_consumer_key", (gchar*)gsignond_dictionary_get_string(session_data, "ConsumerKey")); const gchar* oauth_temp_token = gsignond_dictionary_get_string(session_data, "_OauthTemporaryToken"); if (oauth_temp_token != NULL) g_tree_insert(parameters, "oauth_token", (gchar*)oauth_temp_token); g_tree_insert(parameters, "oauth_signature_method", (gchar*)gsignond_dictionary_get_string(session_data, "SignatureMethod")); g_tree_insert(parameters, "oauth_nonce", nonce); g_tree_insert(parameters, "oauth_timestamp", timestamp); g_tree_insert(parameters, "oauth_version", "1.0"); GString* parameters_string = g_string_new(NULL); g_tree_foreach(parameters, _make_parameters_string, parameters_string); gchar* parameters_s = g_string_free(parameters_string, FALSE); parameters_s[strlen(parameters_s)-1] = '\0'; //remove trailing '&' gchar* parameters_encoded = _percent_encode(parameters_s); g_string_append(base_string, parameters_encoded); g_free(parameters_encoded); g_free(parameters_s); g_tree_destroy(parameters); g_hash_table_destroy(query); return g_string_free(base_string, FALSE); }
static void _oauth_service_get_request_token_ready_cb (SoupSession *session, SoupMessage *msg, gpointer user_data) { OAuthService *self = user_data; GSimpleAsyncResult *result; SoupBuffer *body; GHashTable *values; char *token; char *token_secret; result = _web_service_get_result (WEB_SERVICE (self)); if (msg->status_code != 200) { g_simple_async_result_set_error (result, SOUP_HTTP_ERROR, msg->status_code, "%s", soup_status_get_phrase (msg->status_code)); g_simple_async_result_complete_in_idle (result); return; } body = soup_message_body_flatten (msg->response_body); values = soup_form_decode (body->data); token = g_hash_table_lookup (values, "oauth_token"); token_secret = g_hash_table_lookup (values, "oauth_token_secret"); if ((token != NULL) && (token_secret != NULL)) { oauth_service_set_token (self, token); oauth_service_set_token_secret (self, token_secret); g_simple_async_result_set_op_res_gboolean (result, TRUE); } else { GError *error; error = g_error_new_literal (WEB_SERVICE_ERROR, WEB_SERVICE_ERROR_GENERIC, _("Unknown error")); g_simple_async_result_set_from_error (result, error); } g_simple_async_result_complete_in_idle (result); g_hash_table_destroy (values); soup_buffer_free (body); }
static void flickr_access_token_response (OAuthService *self, SoupMessage *msg, SoupBuffer *body, GSimpleAsyncResult *result) { GHashTable *values; char *username; char *token; char *token_secret; values = soup_form_decode (body->data); username = g_hash_table_lookup (values, "username"); token = g_hash_table_lookup (values, "oauth_token"); token_secret = g_hash_table_lookup (values, "oauth_token_secret"); if ((username != NULL) && (token != NULL) && (token_secret != NULL)) { FlickrAccount *account; oauth_service_set_token (OAUTH_SERVICE (self), token); oauth_service_set_token_secret (OAUTH_SERVICE (self), token_secret); account = g_object_new (FLICKR_TYPE_ACCOUNT, "id", g_hash_table_lookup (values, "user_nsid"), "name", username, "token", token, "token-secret", token_secret, NULL); g_simple_async_result_set_op_res_gpointer (result, account, g_object_unref); } else { GError *error; error = g_error_new_literal (WEB_SERVICE_ERROR, WEB_SERVICE_ERROR_GENERIC, _("Unknown error")); g_simple_async_result_set_from_error (result, error); } g_hash_table_destroy (values); }
static void ask_authorization_dialog_load_request_cb (OAuthAskAuthorizationDialog *dialog, gpointer user_data) { OAuthService *self = user_data; const char *uri; uri = oauth_ask_authorization_dialog_get_uri (dialog); if (uri == NULL) return; if (g_str_has_prefix (uri, OAUTH_CALLBACK)) { const char *uri_data; GHashTable *data; gboolean success = FALSE; uri_data = uri + strlen (OAUTH_CALLBACK "?"); data = soup_form_decode (uri_data); _g_strset (&self->priv->token, g_hash_table_lookup (data, "oauth_token")); if (self->priv->token != NULL) { gtk_widget_hide (GTK_WIDGET (dialog)); gth_task_dialog (GTH_TASK (self), FALSE, NULL); success = TRUE; _oauth_service_get_access_token (self, g_hash_table_lookup (data, "oauth_verifier"), gth_task_get_cancellable (GTH_TASK (self)), get_access_token_ready_cb, self); } if (! success) gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL); g_hash_table_destroy (data); } }
static void handle_uri (BishoWindow *window, const char *s) { SoupURI *uri = NULL; GHashTable *params = NULL; uri = soup_uri_new (s); if (strcmp (uri->scheme, "x-bisho") != 0) { soup_uri_free (uri); return; } if (uri->query) params = soup_form_decode (uri->query); else params = g_hash_table_new (NULL, NULL); bisho_window_callback (window, uri->path, params); g_hash_table_destroy (params); soup_uri_free (uri); }
void oauth_proxy_call_parse_token_reponse (OAuthProxyCall *call) { OAuthProxyPrivate *priv; GHashTable *form; /* TODO: sanity checks, error handling, probably return gboolean */ g_return_if_fail (OAUTH_IS_PROXY_CALL (call)); priv = PROXY_GET_PRIVATE (REST_PROXY_CALL (call)->priv->proxy); g_assert (priv); form = soup_form_decode (rest_proxy_call_get_payload (REST_PROXY_CALL (call))); priv->token = g_strdup (g_hash_table_lookup (form, "oauth_token")); priv->token_secret = g_strdup (g_hash_table_lookup (form, "oauth_token_secret")); /* This header should only exist for request_token replies, but its easier just to always check it */ priv->oauth_10a = g_hash_table_lookup (form, "oauth_callback_confirmed") != NULL; g_hash_table_destroy (form); }
GHashTable * gss_config_get_post_hash (GssTransaction * t) { GHashTable *hash; const char *content_type; content_type = soup_message_headers_get_one (t->msg->request_headers, "Content-Type"); hash = NULL; if (g_str_equal (content_type, "application/x-www-form-urlencoded")) { hash = soup_form_decode (t->msg->request_body->data); } else if (g_str_has_prefix (content_type, "multipart/form-data")) { SoupBuffer *buffer; hash = soup_form_decode_multipart (t->msg, "none", NULL, NULL, &buffer); if (buffer && buffer->length > 0) { soup_buffer_free (buffer); } } return hash; }
static void on_login_content_read (GObject *obj, GAsyncResult *res, gpointer user_data) { LoginData *data = user_data; LiaWebview *self; EvdHttpConnection *conn; gchar *content; gssize size; GError *error = NULL; GHashTable *params; GCancellable *cancellable; SoupURI *uri; GDBusConnection *bus_conn; const gchar *core_service_name; const gchar *user; const gchar *passw; gchar *domain; self = data->self; conn = data->conn; content = evd_http_connection_read_all_content_finish (conn, res, &size, &error); if (content == NULL) { /* @TODO: Failed reading login data */ g_debug ("Error reading login daa: %s", error->message); g_error_free (error); return; } params = soup_form_decode (content); g_free (content); /* call authenticate method of AuthService interface */ user = (const gchar *) g_hash_table_lookup (params, "user"); passw = (const gchar *) g_hash_table_lookup (params, "passw"); cancellable = g_cancellable_new (); g_signal_connect (conn, "close", G_CALLBACK (on_login_conn_closed), cancellable); uri = evd_http_request_get_uri (data->request); domain = g_strdup_printf ("%s:%d", uri->host, uri->port); bus_conn = lia_application_get_bus (LIA_APPLICATION (self), LIA_BUS_PRIVATE); core_service_name = lia_application_get_core_service_name (LIA_APPLICATION (self)); g_dbus_connection_call (bus_conn, core_service_name, LIA_AUTH_SERVICE_OBJ_PATH, LIA_AUTH_SERVICE_IFACE_NAME, "Authenticate", g_variant_new ("(sss)", user, passw, domain), NULL, G_DBUS_CALL_FLAGS_NONE, 30000, cancellable, on_auth_response, data); g_free (domain); g_hash_table_unref (params); }
static void _request_new_token(GSignondOauthPlugin *self, GSignondSessionData *session_data, GError** error) { const gchar* response_type = gsignond_dictionary_get_string(session_data, "ResponseType"); const gchar* grant_type = gsignond_dictionary_get_string(session_data, "GrantType"); if (response_type != NULL && (g_strcmp0(response_type, "code") == 0 || g_strcmp0(response_type, "token") == 0)) { const gchar* host = gsignond_dictionary_get_string(session_data, "AuthHost"); if (host == NULL) { *error = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_MISSING_DATA, "AuthHost not set"); return; } gsignond_oauth_plugin_check_host(host, gsignond_session_data_get_allowed_realms (session_data), error); if (*error != NULL) return; const gchar* auth_path = gsignond_dictionary_get_string(session_data, "AuthPath"); if (auth_path == NULL) { *error = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_MISSING_DATA, "AuthPath not set"); return; } const gchar* client_id = gsignond_dictionary_get_string(session_data, "ClientId"); if (client_id == NULL) { *error = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_MISSING_DATA, "ClientId not set"); return; } SoupURI* open_url = soup_uri_new(NULL); soup_uri_set_scheme(open_url, SOUP_URI_SCHEME_HTTPS); soup_uri_set_host(open_url, host); soup_uri_set_path(open_url, auth_path); guint port; if (gsignond_dictionary_get_uint32(session_data, "AuthPort", &port) != FALSE) soup_uri_set_port(open_url, port); GHashTable* query = g_hash_table_new((GHashFunc)g_str_hash, (GEqualFunc)g_str_equal); const gchar* auth_query_str = gsignond_dictionary_get_string(session_data, "AuthQuery"); GHashTable *auth_query = NULL; if (auth_query_str != NULL) { auth_query = soup_form_decode(auth_query_str); if (auth_query) // insert all key/values in AuthQuery into final query // according to RFC6749 section 3.1 g_hash_table_foreach(auth_query, _insert_key_value, query); } g_hash_table_insert(query, "response_type", (gchar*)response_type); g_hash_table_insert(query, "client_id", (gchar*)client_id); const gchar* redirect_uri = gsignond_dictionary_get_string(session_data, "RedirectUri"); if (redirect_uri != NULL) { g_hash_table_insert(query, "redirect_uri", (gchar*)redirect_uri); } const gchar* scope_str = gsignond_dictionary_get_string(session_data, "Scope"); if (scope_str != NULL) { g_hash_table_insert(query, "scope", (gchar*)scope_str); } gchar* state = gsignond_oauth_plugin_generate_random_data(20); g_hash_table_insert(query, "state", state); gsignond_dictionary_set_string(self->oauth2_request, "_Oauth2State", state); const gchar* username = gsignond_session_data_get_username(session_data); const gchar* secret = gsignond_session_data_get_secret(session_data); // login_hint is a google extension specified here: // https://developers.google.com/accounts/docs/OAuth2InstalledApp#formingtheurl gboolean use_login_hint = FALSE; if (gsignond_dictionary_get_boolean(session_data, "UseLoginHint", &use_login_hint) && use_login_hint && username != NULL) g_hash_table_insert(query, "login_hint", (gchar*)username); // display is a facebook extension specified here: // https://developers.facebook.com/docs/reference/dialogs/oauth/ const gchar* display = gsignond_dictionary_get_string(session_data, "UseDisplay"); if (display != NULL) { g_hash_table_insert(query, "display", (gchar*)display); } soup_uri_set_query_from_form(open_url, query); g_free(state); g_hash_table_unref(query); if (auth_query) g_hash_table_unref(auth_query); char* open_url_str = soup_uri_to_string(open_url, FALSE); soup_uri_free(open_url); GSignondSignonuiData* ui_request = gsignond_dictionary_new(); gsignond_signonui_data_set_open_url(ui_request, open_url_str); free(open_url_str); if (redirect_uri != NULL) gsignond_signonui_data_set_final_url(ui_request, redirect_uri); /* add username and password, for fields initialization (the * decision on whether to actually use them is up to the signon UI */ if (username != NULL) gsignond_signonui_data_set_username(ui_request, username); if (secret != NULL) gsignond_signonui_data_set_password(ui_request, secret); gsignond_plugin_user_action_required(GSIGNOND_PLUGIN(self), ui_request); gsignond_dictionary_unref(ui_request); } else if (grant_type != NULL && (g_strcmp0(grant_type, "password") == 0)) { const gchar* username = gsignond_session_data_get_username(session_data); const gchar* secret = gsignond_session_data_get_secret(session_data); if (username == NULL || secret == NULL) { *error = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_MISSING_DATA, "username or password not set"); return; } GHashTable* params = g_hash_table_new((GHashFunc)g_str_hash, (GEqualFunc)g_str_equal); g_hash_table_insert(params, "grant_type", "password"); g_hash_table_insert(params, "username", (gchar*)username); g_hash_table_insert(params, "password", (gchar*)secret); _set_scope(params, session_data); _do_token_query(self, session_data, params, error); g_hash_table_unref(params); } else if (grant_type != NULL && (g_strcmp0(grant_type, "client_credentials") == 0)) { GHashTable* params = g_hash_table_new((GHashFunc)g_str_hash, (GEqualFunc)g_str_equal); g_hash_table_insert(params, "grant_type", "client_credentials"); _set_scope(params, session_data); _do_token_query(self, session_data, params, error); g_hash_table_unref(params); } else { *error = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_MISSING_DATA, "Unknown ResponseType or GrantType"); } }
static void control_callback (G_GNUC_UNUSED SoupServer * soup, SoupMessage * msg, const char *path, GHashTable * query, G_GNUC_UNUSED SoupClientContext * client, SnraManager * manager) { gchar **parts = g_strsplit (path, "/", 3); guint n_parts = g_strv_length (parts); SnraControlEvent event_type; GHashTable *post_params = NULL; const gchar *content_type; if (n_parts < 3 || !g_str_equal ("control", parts[1])) goto done; /* Invalid request */ event_type = str_to_control_event_type (parts[2]); content_type = soup_message_headers_get_content_type (msg->request_headers, NULL); if (g_str_equal (msg->method, "POST") && content_type && g_str_equal (content_type, SOUP_FORM_MIME_TYPE_URLENCODED)) post_params = soup_form_decode (msg->request_body->data); switch (event_type) { case SNRA_CONTROL_NEXT:{ gchar *id_str = find_param_str ("id", query, post_params); guint resource_id; if (id_str == NULL || !sscanf (id_str, "%d", &resource_id)) { /* No or invalid resource id: skip to another random track */ resource_id = (guint) g_random_int_range (0, get_playlist_len (manager)) + 1; } else { resource_id = CLAMP (resource_id, 1, get_playlist_len (manager)); } if (resource_id != 0) { manager->paused = FALSE; snra_manager_play_resource (manager, resource_id); } break; } case SNRA_CONTROL_PAUSE:{ if (!manager->paused) snra_manager_send_pause (manager, NULL); manager->paused = TRUE; break; } case SNRA_CONTROL_PLAY:{ if (manager->paused) { if (manager->current_resource == 0) { guint resource_id = g_random_int_range (0, get_playlist_len (manager) + 1); if (resource_id != 0) { manager->paused = FALSE; snra_manager_play_resource (manager, resource_id); } } else { manager->paused = FALSE; snra_manager_send_play (manager, NULL); } } break; } case SNRA_CONTROL_VOLUME:{ gchar *vol_str = find_param_str ("level", query, post_params); gchar *id_str = find_param_str ("client_id", query, post_params); guint client_id = 0; gdouble new_vol; if (id_str != NULL) sscanf (id_str, "%u", &client_id); if (vol_str && sscanf (vol_str, "%lf", &new_vol)) { new_vol = CLAMP (new_vol, 0.0, 10.0); if (client_id == 0) snra_manager_adjust_volume (manager, new_vol); else snra_manager_adjust_client_volume (manager, client_id, new_vol); } break; } case SNRA_CONTROL_CLIENT_SETTING:{ gchar *set_str = find_param_str ("enable", query, post_params); gchar *id_str = find_param_str ("client_id", query, post_params); guint client_id = 0; gint enable = 1; if (id_str != NULL) sscanf (id_str, "%u", &client_id); if (set_str && sscanf (set_str, "%d", &enable)) { if (client_id > 0) snra_manager_adjust_client_setting (manager, client_id, enable != 0); } break; } default: g_message ("Ignoring unknown/unimplemented control %s\n", parts[2]); soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND); goto done; } soup_message_set_response (msg, "text/plain", SOUP_MEMORY_STATIC, " ", 1); soup_message_set_status (msg, SOUP_STATUS_OK); done: if (post_params) g_hash_table_destroy (post_params); g_strfreev (parts); }
void _process_oauth1_user_action_finished(GSignondOauthPlugin *self, GSignondSignonuiData *ui_data) { GError* error = NULL; GSignondSignonuiError query_error; gboolean res = gsignond_signonui_data_get_query_error(ui_data, &query_error); if (res == FALSE) { error = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_USER_INTERACTION, "userActionFinished did not return an error value"); goto out; } if (query_error == SIGNONUI_ERROR_CANCELED) { error = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_SESSION_CANCELED, "Session canceled"); goto out; } else if (query_error != SIGNONUI_ERROR_NONE) { error = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_USER_INTERACTION, "userActionFinished error: %d", query_error); goto out; } const gchar* response_url = gsignond_signonui_data_get_url_response(ui_data); const gchar* callback_uri = gsignond_dictionary_get_string( self->oauth1_request, "Callback"); if (response_url == NULL || callback_uri == NULL || g_str_has_prefix(response_url, callback_uri) == FALSE) { error = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_NOT_AUTHORIZED, "Callback URI and URI supplied by UI don't match"); goto out; } SoupURI* response = soup_uri_new(response_url); const gchar* query = soup_uri_get_query(response); if (query == NULL) { soup_uri_free(response); error = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_NOT_AUTHORIZED, "No query in returned redirect URI"); goto out; } GHashTable* params = soup_form_decode(query); soup_uri_free(response); const gchar* oauth_token_response = g_hash_table_lookup(params, "oauth_token"); if (g_strcmp0(oauth_token_response, gsignond_dictionary_get_string(self->oauth1_request, "_OauthTemporaryToken")) != 0) { g_hash_table_destroy(params); error = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_NOT_AUTHORIZED, "Token returned by callback URI and temporary token don't match"); goto out; } const gchar* oauth_verifier = g_hash_table_lookup(params, "oauth_verifier"); if (oauth_verifier == NULL) { g_hash_table_destroy(params); error = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_NOT_AUTHORIZED, "No oauth_verifier in callback URI"); goto out; } gsignond_dictionary_set_string(self->oauth1_request, "_OauthVerifier", oauth_verifier); gsignond_dictionary_remove(self->oauth1_request, "Callback"); g_hash_table_destroy(params); _request_access_token(self, self->oauth1_request, &error); out: if (error != NULL) { _do_reset_oauth1(self); gsignond_plugin_error (GSIGNOND_PLUGIN(self), error); g_error_free(error); } }
static void _access_token_callback (SoupSession *session, SoupMessage *msg, gpointer user_data) { GError* error = NULL; GSignondOauthPlugin *self = GSIGNOND_OAUTH_PLUGIN(user_data); if (msg->status_code != SOUP_STATUS_OK) { error = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_NOT_AUTHORIZED, "Access token endpoint returned an error: %d %s", msg->status_code, msg->reason_phrase); goto out; } SoupBuffer* response_s = soup_message_body_flatten(msg->response_body); GHashTable* response = soup_form_decode(response_s->data); soup_buffer_free(response_s); const gchar* token = g_hash_table_lookup(response, "oauth_token"); const gchar* token_secret = g_hash_table_lookup(response, "oauth_token_secret"); if (token == NULL || token_secret == NULL) { g_hash_table_destroy(response); error = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_NOT_AUTHORIZED, "Access token endpoint returned an invalid response"); goto out; } GSignondDictionary* token_dict = gsignond_dictionary_new(); gsignond_dictionary_set_string(token_dict, "AccessToken", token); gsignond_dictionary_set_string(token_dict, "TokenSecret", token_secret); const gchar* realm = gsignond_dictionary_get_string(self->oauth1_request, "Realm"); if (realm != NULL) gsignond_dictionary_set_string(token_dict, "Realm", realm); GSignondDictionary* parameters_dict = gsignond_dictionary_new(); g_hash_table_foreach(response, _insert_token_parameters, parameters_dict); g_hash_table_destroy(response); gsignond_dictionary_set(token_dict, "TokenParameters", gsignond_dictionary_to_variant(parameters_dict)); gsignond_dictionary_unref(parameters_dict); const gchar* client_id = gsignond_dictionary_get_string(self->oauth1_request, "ConsumerKey"); gsignond_dictionary_set(self->token_cache, client_id, gsignond_dictionary_to_variant(token_dict)); gsignond_plugin_store(GSIGNOND_PLUGIN(self), self->token_cache); _do_reset_oauth1(self); gsignond_plugin_response_final(GSIGNOND_PLUGIN(self), token_dict); gsignond_dictionary_unref(token_dict); out: if (error != NULL) { _do_reset_oauth1(self); gsignond_plugin_error (GSIGNOND_PLUGIN(self), error); g_error_free(error); } }
static void _temporary_token_callback (SoupSession *session, SoupMessage *msg, gpointer user_data) { GError* error = NULL; GSignondOauthPlugin *self = GSIGNOND_OAUTH_PLUGIN(user_data); if (msg->status_code != SOUP_STATUS_OK) { error = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_NOT_AUTHORIZED, "Temporary token endpoint returned an error: %d %s", msg->status_code, msg->reason_phrase); goto out; } SoupBuffer* response_s = soup_message_body_flatten(msg->response_body); GHashTable* response = soup_form_decode(response_s->data); soup_buffer_free(response_s); const gchar* callback_confirmed = g_hash_table_lookup(response, "oauth_callback_confirmed"); const gchar* token = g_hash_table_lookup(response, "oauth_token"); const gchar* token_secret = g_hash_table_lookup(response, "oauth_token_secret"); if (token == NULL || token_secret == NULL || g_strcmp0(callback_confirmed, "true") != 0) { g_hash_table_destroy(response); error = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_NOT_AUTHORIZED, "Temporary token endpoint returned an invalid response"); goto out; } const gchar* callback_url = gsignond_dictionary_get_string(self->oauth1_request, "Callback"); if (callback_url == NULL) { g_hash_table_destroy(response); error = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_NOT_AUTHORIZED, "Client did not supply Callback"); goto out; } const gchar* authorization_url_s = gsignond_dictionary_get_string(self->oauth1_request, "AuthorizationEndpoint"); if (authorization_url_s == NULL) { g_hash_table_destroy(response); error = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_NOT_AUTHORIZED, "Client did not supply AuthorizationEndpoint"); goto out; } SoupURI* authorization_url = soup_uri_new(authorization_url_s); if (authorization_url == NULL) { g_hash_table_destroy(response); error = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_NOT_AUTHORIZED, "Client did not supply a valid AuthorizationEndpoint"); goto out; } gsignond_oauth_plugin_check_host(soup_uri_get_host(authorization_url), gsignond_session_data_get_allowed_realms (self->oauth1_request), &error); if (error != NULL) { soup_uri_free(authorization_url); g_hash_table_destroy(response); return; } GHashTable* query = g_hash_table_new((GHashFunc)g_str_hash, (GEqualFunc)g_str_equal); const gchar* authorization_query_s = soup_uri_get_query(authorization_url); GHashTable *auth_query = NULL; if (authorization_query_s != NULL) { auth_query = soup_form_decode(authorization_query_s); g_hash_table_foreach(auth_query, _insert_key_value, query); } g_hash_table_insert(query, "oauth_token", (gchar*)token); soup_uri_set_query_from_form(authorization_url, query); if (auth_query) g_hash_table_destroy(auth_query); g_hash_table_destroy(query); gchar* open_url = soup_uri_to_string(authorization_url, FALSE); soup_uri_free(authorization_url); gsignond_dictionary_set_string(self->oauth1_request, "_OauthTemporaryToken", token); gsignond_dictionary_set_string(self->oauth1_request, "_OauthTemporaryTokenSecret", token_secret); GSignondSignonuiData* ui_request = gsignond_dictionary_new(); gsignond_signonui_data_set_open_url(ui_request, open_url); g_free(open_url); if (g_strcmp0(callback_url, "oob") != 0) gsignond_signonui_data_set_final_url(ui_request, callback_url); /* add username and password, for fields initialization (the * decision on whether to actually use them is up to the signon UI */ const gchar* username = gsignond_session_data_get_username(self->oauth1_request); if (username != NULL) gsignond_signonui_data_set_username(ui_request, username); const gchar* secret = gsignond_session_data_get_secret(self->oauth1_request); if (secret != NULL) gsignond_signonui_data_set_password(ui_request, secret); gsignond_plugin_user_action_required(GSIGNOND_PLUGIN(self), ui_request); gsignond_dictionary_unref(ui_request); g_hash_table_destroy(response); out: if (error != NULL) { _do_reset_oauth1(self); gsignond_plugin_error (GSIGNOND_PLUGIN(self), error); g_error_free(error); } }