static SoupMessage *make_token_request_msg( const char *token_uri, const char *consumer_key, const char *consumer_secret) { struct oauth_request *oa = oa_req_new_with_params( consumer_key, consumer_secret, token_uri, "POST", SIG_HMAC_SHA1, NULL); if(!oa_sign_request(oa, OA_REQ_REQUEST_TOKEN)) { /* FIXME: handle! */ printf("fail!\n"); oa_req_free(oa); return NULL; } SoupMessage *msg = soup_message_new("POST", token_uri); #if 0 soup_message_headers_append(msg->request_headers, "Authorization", oa_auth_header(oa, OA_REQ_REQUEST_TOKEN)); #elif 1 char *body = oa_request_params_to_post_body(oa, OA_REQ_REQUEST_TOKEN); soup_message_set_request(msg, OA_POST_MIME_TYPE, SOUP_MEMORY_COPY, body, strlen(body)); #else GHashTable *query = oa_request_token_params(oa); soup_uri_set_query_from_form(soup_message_get_uri(msg), query); g_hash_table_destroy(query); #endif oa_req_free(oa); return msg; }
char * flickr_proxy_build_login_url (FlickrProxy *proxy, const char *frob, const char *perms) { SoupURI *uri; GHashTable *params; char *sig, *s; g_return_val_if_fail (FLICKR_IS_PROXY (proxy), NULL); uri = soup_uri_new ("http://flickr.com/services/auth/"); params = g_hash_table_new (g_str_hash, g_str_equal); g_hash_table_insert (params, "api_key", proxy->priv->api_key); g_hash_table_insert (params, "perms", (gpointer)perms); if (frob) g_hash_table_insert (params, "frob", (gpointer)frob); sig = flickr_proxy_sign (proxy, params); g_hash_table_insert (params, "api_sig", sig); soup_uri_set_query_from_form (uri, params); s = soup_uri_to_string (uri, FALSE); g_free (sig); g_hash_table_destroy (params); soup_uri_free (uri); return s; }
static void seahorse_hkp_source_search_async (SeahorseServerSource *source, const gchar *match, GcrSimpleCollection *results, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { SeahorseHKPSource *self = SEAHORSE_HKP_SOURCE (source); source_search_closure *closure; GSimpleAsyncResult *res; SoupMessage *message; GHashTable *form; SoupURI *uri; gchar hexfpr[11]; res = g_simple_async_result_new (G_OBJECT (source), callback, user_data, seahorse_hkp_source_search_async); closure = g_new0 (source_search_closure, 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_simple_async_result_set_op_res_gpointer (res, 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"); if (is_hex_keyid (match)) { strncpy (hexfpr, "0x", 3); strncpy (hexfpr + 2, match, 9); g_hash_table_insert (form, "search", hexfpr); } else { g_hash_table_insert (form, "search", (char *)match); } g_hash_table_insert (form, "fingerprint", "on"); soup_uri_set_query_from_form (uri, form); g_hash_table_destroy (form); message = soup_message_new_from_uri ("GET", uri); soup_session_queue_message (closure->session, message, on_search_message_complete, g_object_ref (res)); seahorse_progress_prep_and_begin (cancellable, message, NULL); if (cancellable) closure->cancelled_sig = g_cancellable_connect (cancellable, G_CALLBACK (on_session_cancelled), closure->session, NULL); soup_uri_free (uri); g_object_unref (res); }
static SeahorseOperation* seahorse_hkp_source_search (SeahorseSource *src, const gchar *match) { SeahorseHKPOperation *hop; SoupMessage *message; GHashTable *form; gchar *t; SoupURI *uri; gchar hexfpr[11]; g_assert (SEAHORSE_IS_SOURCE (src)); g_assert (SEAHORSE_IS_HKP_SOURCE (src)); hop = setup_hkp_operation (SEAHORSE_HKP_SOURCE (src)); uri = get_http_server_uri (src, "/pks/lookup"); g_return_val_if_fail (uri, FALSE); form = g_hash_table_new (g_str_hash, g_str_equal); g_hash_table_insert (form, "op", "index"); if (is_hex_keyid (match)) { strncpy (hexfpr, "0x", 3); strncpy (hexfpr + 2, match, 9); g_hash_table_insert (form, "search", hexfpr); } else g_hash_table_insert (form, "search", (char *)match); soup_uri_set_query_from_form (uri, form); g_hash_table_destroy (form); message = soup_message_new_from_uri ("GET", uri); soup_session_queue_message (hop->session, message, (SoupSessionCallback)refresh_callback, hop); hop->total = hop->requests = 1; t = g_strdup_printf (_("Searching for keys on: %s"), uri->host); seahorse_operation_mark_progress (SEAHORSE_OPERATION (hop), t, -1); g_free (t); soup_uri_free (uri); seahorse_server_source_take_operation (SEAHORSE_SERVER_SOURCE (src), SEAHORSE_OPERATION (hop)); g_object_ref (hop); return SEAHORSE_OPERATION (hop); }
static void seahorse_hkp_source_export_async (SeahorseServerSource *source, const gchar **keyids, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { SeahorseHKPSource *self = SEAHORSE_HKP_SOURCE (source); ExportClosure *closure; g_autoptr(GTask) task = NULL; SoupURI *uri; g_autoptr(GHashTable) form = NULL; gchar hexfpr[11]; gint i; 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]) { g_task_return_pointer (task, NULL, NULL); return; } uri = get_http_server_uri (self, "/pks/lookup"); g_return_if_fail (uri); /* prepend the hex prefix (0x) to make keyservers happy */ strncpy (hexfpr, "0x", 3); form = g_hash_table_new (g_str_hash, g_str_equal); for (i = 0; keyids[i] != NULL; i++) { const gchar *fpr = keyids[i]; guint len; SoupMessage *message; g_hash_table_remove_all (form); /* Get the key id and limit it to 8 characters */ len = strlen (fpr); if (len > 8) fpr += (len - 8); strncpy (hexfpr + 2, fpr, 9); /* 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); soup_session_queue_message (closure->session, message, on_export_message_complete, g_object_ref (task)); closure->requests++; seahorse_progress_prep_and_begin (cancellable, message, NULL); } if (cancellable) closure->cancelled_sig = g_cancellable_connect (cancellable, G_CALLBACK (on_session_cancelled), closure->session, NULL); }
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 SeahorseOperation* seahorse_hkp_source_export_raw (SeahorseSource *sksrc, GSList *keyids, GOutputStream *output) { SeahorseHKPOperation *hop; SeahorseHKPSource *hsrc; SoupMessage *message; gchar *t; SoupURI *uri; const gchar *fpr; gchar hexfpr[11]; GHashTable *form; guint len; GSList *l; g_return_val_if_fail (SEAHORSE_IS_HKP_SOURCE (sksrc), NULL); g_return_val_if_fail (output == NULL || G_IS_OUTPUT_STREAM (output), NULL); hsrc = SEAHORSE_HKP_SOURCE (sksrc); if (g_slist_length (keyids) == 0) return seahorse_operation_new_complete (NULL); uri = get_http_server_uri (sksrc, "/pks/lookup"); g_return_val_if_fail (uri, FALSE); /* New operation started */ hop = setup_hkp_operation (hsrc); g_object_ref (output); seahorse_operation_mark_result (SEAHORSE_OPERATION (hop), output, g_object_unref); /* prepend the hex prefix (0x) to make keyservers happy */ strncpy(hexfpr, "0x", 3); form = g_hash_table_new (g_str_hash, g_str_equal); for (l = keyids; l; l = g_slist_next (l)) { /* Get the key id and limit it to 8 characters */ fpr = seahorse_pgp_key_calc_rawid (GPOINTER_TO_UINT (l->data)); len = strlen (fpr); if (len > 8) fpr += (len - 8); strncpy(hexfpr + 2, fpr, 9); /* 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); soup_session_queue_message (hop->session, message, (SoupSessionCallback)get_callback, hop); hop->requests++; } g_hash_table_destroy (form); hop->total = hop->requests; t = g_strdup_printf (_("Connecting to: %s"), uri->host); seahorse_operation_mark_progress (SEAHORSE_OPERATION (hop), t, -1); g_free (t); soup_uri_free (uri); return SEAHORSE_OPERATION (hop); }
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); } }