/** * 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) { g_autoptr(SoupURI) uri = NULL; g_autofree gchar *server = NULL; gchar *port; g_object_get (self, "key-server", &server, NULL); g_return_val_if_fail (server != NULL, NULL); uri = soup_uri_new (NULL); soup_uri_set_scheme (uri, SOUP_URI_SCHEME_HTTP); /* If it already has a port then use that */ port = strchr (server, ':'); if (port) { *port++ = '\0'; soup_uri_set_port (uri, atoi (port)); } else { /* default HKP port */ soup_uri_set_port (uri, 11371); } soup_uri_set_host (uri, server); soup_uri_set_path (uri, path); return g_steal_pointer (&uri); }
/** * Change scheme and port of soup messages uri if the host is a known and * valid hsts host. * * This logic should be implemented in request_queued function but the changes * that are done there to the uri do not appear in webkit_web_view_get_uri(). * If a valid hsts host is requested via http and the url is changed to https * vimb would still show the http uri in url bar. This seems to be a * missbehaviour in webkit, but for now we provide this function to put in the * logic in the scope of the navigation-policy-decision-requested event of the * webview. * * Returns newly allocated string with new URI if the URI was change to * fullfill HSTS, else NULL. */ char *hsts_get_changed_uri(SoupSession* session, SoupMessage *msg) { SoupSessionFeature *feature; HSTSProvider *provider; SoupURI *uri; if (!msg) { return NULL; } feature = soup_session_get_feature_for_message(session, HSTS_TYPE_PROVIDER, msg); uri = soup_message_get_uri(msg); if (!feature || !uri) { return NULL; } provider = HSTS_PROVIDER(feature); /* if URI uses still https we don't nee to rewrite it */ if (uri->scheme != SOUP_URI_SCHEME_HTTPS && should_secure_host(provider, uri->host) ) { /* the ports is set by soup uri if scheme is changed */ soup_uri_set_scheme(uri, SOUP_URI_SCHEME_HTTPS); return soup_uri_to_string(uri, false); } return NULL; }
int main (int argc, char **argv) { SoupServer *server; SoupURI *uri; guint port; int ret; /* Force this test to use the dummy TLS backend */ g_setenv ("GIO_USE_TLS", "dummy", TRUE); test_init (argc, argv, NULL); /* Make a non-SSL server and pretend that it's ssl, which is fine * since we won't ever actually talk to it anyway. We don't * currently test that failing to construct an SSL server works. */ server = soup_test_server_new (TRUE); soup_server_add_handler (server, NULL, server_handler, NULL, NULL); uri = soup_test_server_get_uri (server, "http", NULL); port = uri->port; soup_uri_set_scheme (uri, SOUP_URI_SCHEME_HTTPS); soup_uri_set_port (uri, port); g_test_add_func ("/no-ssl/session-properties", do_session_property_tests); g_test_add_data_func ("/no-ssl/request-error", uri, do_ssl_tests); ret = g_test_run (); soup_uri_free (uri); soup_test_server_quit_unref (server); test_cleanup (); return ret; }
static GSocketAddressEnumerator * soup_address_connectable_proxy_enumerate (GSocketConnectable *connectable) { SoupAddress *addr = SOUP_ADDRESS (connectable); SoupAddressPrivate *priv = SOUP_ADDRESS_GET_PRIVATE (addr); GSocketAddressEnumerator *proxy_enum; SoupURI *uri; char *uri_string; /* We cheerily assume "http" here because you shouldn't be * using SoupAddress any more if you're not doing HTTP anyway. */ uri = soup_uri_new (NULL); soup_uri_set_scheme (uri, priv->protocol ? priv->protocol : "http"); soup_uri_set_host (uri, priv->name ? priv->name : soup_address_get_physical (addr)); soup_uri_set_port (uri, priv->port); soup_uri_set_path (uri, ""); uri_string = soup_uri_to_string_internal (uri, FALSE, TRUE); proxy_enum = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR, "connectable", connectable, "uri", uri_string, NULL); g_free (uri_string); soup_uri_free (uri); return proxy_enum; }
static SoupURI * uri_from_address (SoupAddress *addr) { SoupURI *proxy_uri; proxy_uri = soup_uri_new (NULL); soup_uri_set_scheme (proxy_uri, SOUP_URI_SCHEME_HTTP); soup_uri_set_host (proxy_uri, soup_address_get_name (addr)); soup_uri_set_port (proxy_uri, soup_address_get_port (addr)); return proxy_uri; }
static void seahorse_hkp_operation_init (SeahorseHKPOperation *hop) { SoupURI *uri; gchar *host; #if DEBUG_HKP_ENABLE SoupLogger *logger; #endif if (seahorse_gconf_get_boolean (GCONF_USE_HTTP_PROXY)) { host = seahorse_gconf_get_string (GCONF_HTTP_PROXY_HOST); if (host) { uri = soup_uri_new (NULL); if (!uri) { g_warning ("creation of SoupURI from '%s' failed", host); } else { soup_uri_set_scheme (uri, SOUP_URI_SCHEME_HTTP); soup_uri_set_host (uri, host); g_free (host); soup_uri_set_port (uri, seahorse_gconf_get_integer (GCONF_PROXY_PORT)); if (seahorse_gconf_get_boolean (GCONF_USE_AUTH)) { char *user, *pass; user = seahorse_gconf_get_string (GCONF_AUTH_USER); soup_uri_set_user (uri, user); g_free (user); pass = seahorse_gconf_get_string (GCONF_AUTH_PASS); soup_uri_set_password (uri, pass); g_free (pass); } hop->session = soup_session_async_new_with_options (SOUP_SESSION_PROXY_URI, uri, NULL); soup_uri_free (uri); } } } /* Without a proxy */ if (!hop->session) hop->session = soup_session_async_new (); #if DEBUG_HKP_ENABLE logger = soup_logger_new (SOUP_LOGGER_LOG_BODY, -1); soup_logger_attach (logger, hop->session); g_object_unref (logger); #endif }
void dmap_connection_setup (DMAPConnection * connection) { connection->priv->session = soup_session_async_new (); connection->priv->base_uri = soup_uri_new (NULL); soup_uri_set_scheme (connection->priv->base_uri, SOUP_URI_SCHEME_HTTP); soup_uri_set_host (connection->priv->base_uri, connection->priv->host); soup_uri_set_port (connection->priv->base_uri, connection->priv->port); }
/** * Check if the host is known and switch the URI scheme to https. */ static void request_queued(SoupSessionFeature *feature, SoupSession *session, SoupMessage *msg) { SoupURI *uri = soup_message_get_uri(msg); HSTSProvider *provider = HSTS_PROVIDER(feature); /* only look for HSTS headers sent over https RFC 6797 7.2*/ if (uri->scheme == SOUP_URI_SCHEME_HTTPS) { soup_message_add_header_handler( msg, "got-headers", HSTS_HEADER_NAME, G_CALLBACK(process_hsts_header), feature ); } else if (should_secure_host(provider, uri->host)) { /* the ports is set by soup uri if scheme is changed */ soup_uri_set_scheme(uri, SOUP_URI_SCHEME_HTTPS); soup_session_requeue_message(session, msg); } }
static SoupURI * network_get_proxy_uri (void) { SoupURI *uri = NULL; if (!proxyname) return uri; uri = soup_uri_new (NULL); soup_uri_set_scheme (uri, SOUP_URI_SCHEME_HTTP); soup_uri_set_host (uri, proxyname); soup_uri_set_port (uri, proxyport); soup_uri_set_user (uri, proxyusername); soup_uri_set_password (uri, proxypassword); return uri; }
/** * Change scheme and port of soup messages uri if the host is a known and * valid hsts host. * This logic should be implemented in request_queued function but the changes * that are done there to the uri do not appear in webkit_web_view_get_uri(). * If a valid hsts host is requested via http and the url is changed to https * vimb would still show the http uri in url bar. This seems to be a * missbehaviour in webkit, but for now we provide this function to put in the * logic in the scope of the resource-request-starting event of the webview. */ void hsts_prepare_message(SoupSession* session, SoupMessage *msg) { SoupSessionFeature *feature; HSTSProvider *provider; SoupURI *uri; feature = soup_session_get_feature_for_message(session, HSTS_TYPE_PROVIDER, msg); uri = soup_message_get_uri(msg); if (!feature || !uri) { return; } provider = HSTS_PROVIDER(feature); if (should_secure_host(provider, uri->host)) { /* the ports is set by soup uri if scheme is changed */ soup_uri_set_scheme(uri, SOUP_URI_SCHEME_HTTPS); } }
static void liferea_webkit_set_proxy (const gchar *host, guint port, const gchar *user, const gchar *pwd) { SoupURI *proxy = NULL; if (host) { proxy = soup_uri_new (NULL); soup_uri_set_scheme (proxy, SOUP_URI_SCHEME_HTTP); soup_uri_set_host (proxy, host); soup_uri_set_port (proxy, port); soup_uri_set_user (proxy, user); soup_uri_set_password (proxy, pwd); } g_object_set (webkit_get_default_session (), SOUP_SESSION_PROXY_URI, proxy, NULL); }
const gchar * soupcut_server_build_uri(SoupServer *server, const gchar *path) { SoupAddress *address; SoupURI *uri; const gchar *uri_string; g_object_get(server, SOUP_SERVER_INTERFACE, &address, NULL); uri = soup_uri_new(NULL); soup_uri_set_scheme(uri, SOUP_URI_SCHEME_HTTP); soup_uri_set_host(uri, "localhost"); soup_uri_set_port(uri, soup_address_get_port(address)); soup_uri_set_path(uri, path); uri_string = cut_take_string(soup_uri_to_string(uri, FALSE)); soup_uri_free(uri); return uri_string; }
static void network_set_soup_session_proxy (SoupSession *session, ProxyDetectMode mode, const gchar *host, guint port, const gchar *user, const gchar *password) { SoupURI *uri = NULL; switch (mode) { case PROXY_DETECT_MODE_AUTO: /* Sets proxy-resolver to the default resolver, this unsets proxy-uri. */ g_object_set (G_OBJECT (session), SOUP_SESSION_PROXY_RESOLVER, g_proxy_resolver_get_default (), NULL); break; case PROXY_DETECT_MODE_NONE: /* Sets proxy-resolver to NULL, this unsets proxy-uri. */ g_object_set (G_OBJECT (session), SOUP_SESSION_PROXY_RESOLVER, NULL, NULL); break; case PROXY_DETECT_MODE_MANUAL: uri = soup_uri_new (NULL); soup_uri_set_scheme (uri, SOUP_URI_SCHEME_HTTP); soup_uri_set_host (uri, host); soup_uri_set_port (uri, port); soup_uri_set_user (uri, user); soup_uri_set_password (uri, password); soup_uri_set_path (uri, "/"); if (SOUP_URI_IS_VALID (uri)) { /* Sets proxy-uri, this unsets proxy-resolver. */ g_object_set (G_OBJECT (session), SOUP_SESSION_PROXY_URI, uri, NULL); } soup_uri_free (uri); break; } }
SoupMessageQueueItem * soup_session_make_connect_message (SoupSession *session, SoupAddress *server_addr) { SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session); SoupURI *uri; SoupMessage *msg; uri = soup_uri_new (NULL); soup_uri_set_scheme (uri, SOUP_URI_SCHEME_HTTPS); soup_uri_set_host (uri, soup_address_get_name (server_addr)); soup_uri_set_port (uri, soup_address_get_port (server_addr)); soup_uri_set_path (uri, ""); msg = soup_message_new_from_uri (SOUP_METHOD_CONNECT, uri); soup_message_set_flags (msg, SOUP_MESSAGE_NO_REDIRECT); soup_uri_free (uri); /* Call the base implementation of soup_session_queue_message * directly, to add msg to the SoupMessageQueue and cause all * the right signals to be emitted. */ queue_message (session, msg, tunnel_connected, NULL); return soup_message_queue_lookup (priv->queue, msg); }
static guint parse_request_headers (SoupMessage *msg, char *headers, guint headers_len, SoupEncoding *encoding, gpointer sock) { SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg); char *req_method, *req_path, *url; SoupHTTPVersion version; const char *req_host; guint status; SoupURI *uri; status = soup_headers_parse_request (headers, headers_len, msg->request_headers, &req_method, &req_path, &version); if (!SOUP_STATUS_IS_SUCCESSFUL (status)) return status; g_object_set (G_OBJECT (msg), SOUP_MESSAGE_METHOD, req_method, SOUP_MESSAGE_HTTP_VERSION, version, NULL); g_free (req_method); /* Handle request body encoding */ *encoding = soup_message_headers_get_encoding (msg->request_headers); if (*encoding == SOUP_ENCODING_UNRECOGNIZED) { if (soup_message_headers_get_list (msg->request_headers, "Transfer-Encoding")) return SOUP_STATUS_NOT_IMPLEMENTED; else return SOUP_STATUS_BAD_REQUEST; } /* Generate correct context for request */ req_host = soup_message_headers_get_one (msg->request_headers, "Host"); if (req_host && strchr (req_host, '/')) { g_free (req_path); return SOUP_STATUS_BAD_REQUEST; } if (!strcmp (req_path, "*") && req_host) { /* Eg, "OPTIONS * HTTP/1.1" */ url = g_strdup_printf ("%s://%s", soup_socket_is_ssl (sock) ? "https" : "http", req_host); uri = soup_uri_new (url); if (uri) soup_uri_set_path (uri, "*"); g_free (url); } else if (*req_path != '/') { /* Must be an absolute URI */ uri = soup_uri_new (req_path); } else if (req_host) { url = g_strdup_printf ("%s://%s%s", soup_socket_is_ssl (sock) ? "https" : "http", req_host, req_path); uri = soup_uri_new (url); g_free (url); } else if (priv->http_version == SOUP_HTTP_1_0) { /* No Host header, no AbsoluteUri */ SoupAddress *addr = soup_socket_get_local_address (sock); uri = soup_uri_new (NULL); soup_uri_set_scheme (uri, soup_socket_is_ssl (sock) ? SOUP_URI_SCHEME_HTTPS : SOUP_URI_SCHEME_HTTP); soup_uri_set_host (uri, soup_address_get_physical (addr)); soup_uri_set_port (uri, soup_address_get_port (addr)); soup_uri_set_path (uri, req_path); } else uri = NULL; g_free (req_path); if (!SOUP_URI_VALID_FOR_HTTP (uri)) { /* certainly not "a valid host on the server" (RFC2616 5.2.3) * SOUP_URI_VALID_FOR_HTTP also guards against uri == NULL */ if (uri) soup_uri_free (uri); return SOUP_STATUS_BAD_REQUEST; } soup_message_set_uri (msg, uri); soup_uri_free (uri); return SOUP_STATUS_OK; }
static gboolean do_one_attempt (gpointer user_data) { GError *local_error = NULL; MinCloudAgentApp *self = user_data; gs_free char *uri_str = NULL; gs_unref_object SoupRequest *request = NULL; gs_unref_object GInputStream *instream = NULL; gs_unref_object GFileOutputStream *outstream = NULL; gs_unref_object GFile *authorized_keys_path = NULL; gs_unref_object SoupMessage *msg = NULL; SoupURI *uri = NULL; const int max_request_failures = 5; const char *state_description = NULL; /* Skip over already completed states */ again: switch (self->state) { case MCA_STATE_USER_DATA: if (g_file_query_exists (self->userdata_done_stamp, NULL)) { self->state++; goto again; } break; case MCA_STATE_OPENSSH_KEY: if (g_file_query_exists (self->authorized_keys_path, NULL)) { self->state++; goto again; } break; case MCA_STATE_DONE: goto out; } uri = soup_uri_new (NULL); soup_uri_set_scheme (uri, "http"); { gs_free char *addr_str = g_inet_address_to_string (self->addr); soup_uri_set_host (uri, addr_str); } soup_uri_set_port (uri, g_inet_socket_address_get_port (self->addr_port)); switch (self->state) { case MCA_STATE_USER_DATA: soup_uri_set_path (uri, "/2009-04-04/user-data"); state_description = "user-data"; break; case MCA_STATE_OPENSSH_KEY: soup_uri_set_path (uri, "/2009-04-04/meta-data/public-keys/0/openssh-key"); state_description = "openssh-key"; break; case MCA_STATE_DONE: g_assert_not_reached (); } uri_str = soup_uri_to_string (uri, FALSE); g_print ("Requesting '%s'...\n", uri_str); request = soup_session_request_uri (self->session, uri, &local_error); soup_uri_free (uri); if (!request) goto out; instream = soup_request_send (request, NULL, &local_error); if (!instream) goto out; msg = soup_request_http_get_message ((SoupRequestHTTP*) request); if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) { switch (msg->status_code) { case 404: case 410: { gs_log_structured_print_id_v (MCA_NOT_FOUND_ID, "No %s found", state_description); g_clear_error (&local_error); /* Note fallthrough to out, where we'll advance to the next state */ goto out; } default: /* Don't actually set the error, we will just continue to * the next phase. */ gs_log_structured_print_id_v (MCA_TIMEOUT_ID, "Error fetching %s: %u %s", uri_str, msg->status_code, soup_status_get_phrase (msg->status_code)); goto out; } } switch (self->state) { case MCA_STATE_USER_DATA: if (!handle_userdata_script (self, instream, self->cancellable, &local_error)) goto out; break; case MCA_STATE_OPENSSH_KEY: if (!handle_install_authorized_keys (self, instream, self->cancellable, &local_error)) goto out; break; default: g_assert_not_reached (); } g_assert (self->state != MCA_STATE_DONE); self->state++; self->request_failure_count = 0; out: if (local_error) { self->request_failure_count++; if (self->request_failure_count >= max_request_failures) { g_error_free (local_error); gs_log_structured_print_id_v (MCA_TIMEOUT_ID, "Reached maximum failed attempts (%u) to fetch metadata", self->request_failure_count); self->do_one_attempt_id = 0; self->running = FALSE; } else { gs_log_structured_print_id_v (MCA_REQUEST_FAILED_ID, "Request failed (count: %u): %s", self->request_failure_count, local_error->message); g_error_free (local_error); self->do_one_attempt_id = g_timeout_add_seconds (self->request_failure_count, do_one_attempt, self); } } else { /* If we advanced in state, schedule the next callback in an * idle so we're consistently scheduled out of an idle. */ if (self->state != MCA_STATE_DONE) self->do_one_attempt_id = g_idle_add (do_one_attempt, self); else { self->do_one_attempt_id = 0; self->running = FALSE; } } return FALSE; }
static void do_soup_uri_null_tests (void) { SoupURI *uri, *uri2; char *uri_string; debug_printf (1, "\nsoup_uri_new (NULL)\n"); uri = soup_uri_new (NULL); if (SOUP_URI_IS_VALID (uri) || SOUP_URI_VALID_FOR_HTTP (uri)) { debug_printf (1, " ERROR: soup_uri_new(NULL) returns valid URI?\n"); errors++; } /* This implicitly also verifies that none of these methods g_warn */ if (soup_uri_get_scheme (uri) || soup_uri_get_user (uri) || soup_uri_get_password (uri) || soup_uri_get_host (uri) || soup_uri_get_port (uri) || soup_uri_get_path (uri) || soup_uri_get_query (uri) || soup_uri_get_fragment (uri)) { debug_printf (1, " ERROR: soup_uri_new(NULL) returns non-empty URI?\n"); errors++; } expect_warning = TRUE; uri2 = soup_uri_new_with_base (uri, "/path"); if (uri2 || expect_warning) { debug_printf (1, " ERROR: soup_uri_new_with_base didn't fail on NULL URI?\n"); errors++; expect_warning = FALSE; } expect_warning = TRUE; uri_string = soup_uri_to_string (uri, FALSE); if (expect_warning) { debug_printf (1, " ERROR: soup_uri_to_string didn't fail on NULL URI?\n"); errors++; expect_warning = FALSE; } else if (*uri_string) { debug_printf (1, " ERROR: soup_uri_to_string on NULL URI returned '%s'\n", uri_string); errors++; } g_free (uri_string); soup_uri_set_scheme (uri, SOUP_URI_SCHEME_HTTP); if (SOUP_URI_IS_VALID (uri) || SOUP_URI_VALID_FOR_HTTP (uri)) { debug_printf (1, " ERROR: setting scheme on NULL URI makes it valid?\n"); errors++; } expect_warning = TRUE; uri_string = soup_uri_to_string (uri, FALSE); if (expect_warning) { debug_printf (1, " ERROR: soup_uri_to_string didn't fail on scheme-only URI?\n"); errors++; expect_warning = FALSE; } else if (strcmp (uri_string, "http:") != 0) { debug_printf (1, " ERROR: soup_uri_to_string returned '%s' instead of 'http:'\n", uri_string); errors++; } g_free (uri_string); soup_uri_set_host (uri, "localhost"); if (SOUP_URI_IS_VALID (uri)) { debug_printf (1, " ERROR: setting scheme+host on NULL URI makes it valid?\n"); errors++; } if (SOUP_URI_VALID_FOR_HTTP (uri)) { debug_printf (1, " ERROR: setting scheme+host on NULL URI makes it valid for http?\n"); errors++; } expect_warning = TRUE; uri_string = soup_uri_to_string (uri, FALSE); if (expect_warning) { debug_printf (1, " ERROR: soup_uri_to_string didn't fail on scheme+host URI?\n"); errors++; expect_warning = FALSE; } else if (strcmp (uri_string, "http://localhost/") != 0) { debug_printf (1, " ERROR: soup_uri_to_string with NULL path returned '%s' instead of 'http://localhost/'\n", uri_string); errors++; } g_free (uri_string); expect_warning = TRUE; uri2 = soup_uri_new_with_base (uri, "/path"); if (expect_warning) { debug_printf (1, " ERROR: soup_uri_new_with_base didn't warn on NULL+scheme URI?\n"); errors++; expect_warning = FALSE; } else if (!uri2) { debug_printf (1, " ERROR: soup_uri_new_with_base didn't fix path on NULL+scheme URI\n"); errors++; } if (uri2) { uri_string = soup_uri_to_string (uri2, FALSE); if (!uri_string) { debug_printf (1, " ERROR: soup_uri_to_string failed on uri2?\n"); errors++; } else if (strcmp (uri_string, "http://localhost/path") != 0) { debug_printf (1, " ERROR: soup_uri_to_string returned '%s' instead of 'http://localhost/path'\n", uri_string); errors++; } g_free (uri_string); soup_uri_free (uri2); } expect_warning = TRUE; soup_uri_set_path (uri, NULL); if (expect_warning) { debug_printf (1, " ERROR: setting path to NULL doesn't warn\n"); errors++; expect_warning = FALSE; } if (!uri->path || *uri->path) { debug_printf (1, " ERROR: setting path to NULL != \"\"\n"); errors++; soup_uri_set_path (uri, ""); } uri_string = soup_uri_to_string (uri, FALSE); if (!uri_string) { debug_printf (1, " ERROR: soup_uri_to_string failed on complete URI?\n"); errors++; } else if (strcmp (uri_string, "http://localhost/") != 0) { debug_printf (1, " ERROR: soup_uri_to_string with empty path returned '%s' instead of 'http://localhost/'\n", uri_string); errors++; } g_free (uri_string); if (!SOUP_URI_IS_VALID (uri)) { debug_printf (1, " ERROR: setting scheme+path on NULL URI doesn't make it valid?\n"); errors++; } if (!SOUP_URI_VALID_FOR_HTTP (uri)) { debug_printf (1, " ERROR: setting scheme+host+path on NULL URI doesn't make it valid for http?\n"); errors++; } soup_uri_free (uri); }
static void _do_token_query(GSignondOauthPlugin *self, GSignondSessionData *session_data, GHashTable* params, GError** error) { gboolean force_request_body_auth; if (gsignond_dictionary_get_boolean(session_data, "ForceClientAuthViaRequestBody", &force_request_body_auth) && force_request_body_auth) { const gchar* client_id = gsignond_dictionary_get_string(session_data, "ClientId"); const gchar* client_secret = gsignond_dictionary_get_string(session_data, "ClientSecret"); if (client_id != NULL && client_secret != NULL) { g_hash_table_insert(params, "client_id", (gchar*)client_id); g_hash_table_insert(params, "client_secret", (gchar*)client_secret); } } const gchar* host = gsignond_dictionary_get_string(session_data, "TokenHost"); if (host == NULL) { *error = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_MISSING_DATA, "TokenHost not set"); return; } gsignond_oauth_plugin_check_host(host, gsignond_session_data_get_allowed_realms (session_data), error); if (*error != NULL) return; const gchar* token_path = gsignond_dictionary_get_string(session_data, "TokenPath"); if (token_path == NULL) { *error = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_MISSING_DATA, "TokenPath not set"); return; } const gchar* token_query_str = gsignond_dictionary_get_string(session_data, "TokenQuery"); 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, token_path); guint port; if (gsignond_dictionary_get_uint32(session_data, "TokenPort", &port) != FALSE) soup_uri_set_port(open_url, port); if (token_query_str != NULL) { soup_uri_set_query(open_url, token_query_str); } SoupMessage *msg = soup_message_new_from_uri ("POST", open_url); soup_uri_free(open_url); gchar* formdata = soup_form_encode_hash(params); soup_message_set_request (msg, "application/x-www-form-urlencoded", SOUP_MEMORY_TAKE, formdata, strlen (formdata)); soup_session_queue_message (self->soup_session, msg, _http_token_callback, self); }
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 server_callback (SoupServer *server, SoupMessage *msg, const char *path, GHashTable *query, SoupClientContext *context, gpointer data) { SoupURI *uri = soup_message_get_uri (msg); const char *server_protocol = data; soup_message_headers_append (msg->response_headers, "X-Handled-By", "server_callback"); if (!strcmp (path, "*")) { debug_printf (1, " default server_callback got request for '*'!\n"); errors++; soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); return; } if (msg->method != SOUP_METHOD_GET && msg->method != SOUP_METHOD_POST) { soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); return; } if (!strcmp (path, "/redirect")) { soup_message_set_redirect (msg, SOUP_STATUS_FOUND, "/"); return; } if (!strcmp (path, "/alias-redirect")) { SoupURI *redirect_uri; char *redirect_string; const char *redirect_protocol; redirect_protocol = soup_message_headers_get_one (msg->request_headers, "X-Redirect-Protocol"); redirect_uri = soup_uri_copy (uri); soup_uri_set_scheme (redirect_uri, "foo"); if (!g_strcmp0 (redirect_protocol, "https")) soup_uri_set_port (redirect_uri, ssl_base_uri->port); else soup_uri_set_port (redirect_uri, base_uri->port); soup_uri_set_path (redirect_uri, "/alias-redirected"); redirect_string = soup_uri_to_string (redirect_uri, FALSE); soup_message_set_redirect (msg, SOUP_STATUS_FOUND, redirect_string); g_free (redirect_string); soup_uri_free (redirect_uri); return; } else if (!strcmp (path, "/alias-redirected")) { soup_message_set_status (msg, SOUP_STATUS_OK); soup_message_headers_append (msg->response_headers, "X-Redirected-Protocol", server_protocol); return; } if (!strcmp (path, "/slow")) { soup_server_pause_message (server, msg); g_object_set_data (G_OBJECT (msg), "server", server); soup_add_timeout (soup_server_get_async_context (server), 1000, timeout_finish_message, msg); } soup_message_set_status (msg, SOUP_STATUS_OK); if (!strcmp (uri->host, "foo")) { soup_message_set_response (msg, "text/plain", SOUP_MEMORY_STATIC, "foo-index", 9); return; } else { soup_message_set_response (msg, "text/plain", SOUP_MEMORY_STATIC, "index", 5); return; } }