static gboolean check_password (SoupAuthDomain *domain, SoupMessage *msg, const char *username, const char *password) { const char *header; GHashTable *params; const char *msg_username; char hex_urp[33]; gboolean accept; header = soup_message_headers_get_one (msg->request_headers, "Authorization"); if (strncmp (header, "Digest ", 7) != 0) return FALSE; params = soup_header_parse_param_list (header + 7); if (!params) return FALSE; msg_username = g_hash_table_lookup (params, "username"); if (!msg_username || strcmp (msg_username, username) != 0) { soup_header_free_param_list (params); return FALSE; } soup_auth_digest_compute_hex_urp (username, soup_auth_domain_get_realm (domain), password, hex_urp); accept = check_hex_urp (domain, msg, params, username, hex_urp); soup_header_free_param_list (params); return accept; }
/** * soup_auth_update: * @auth: a #SoupAuth * @msg: the #SoupMessage @auth is being updated for * @auth_header: the WWW-Authenticate/Proxy-Authenticate header * * Updates @auth with the information from @msg and @auth_header, * possibly un-authenticating it. As with soup_auth_new(), this is * normally only used by #SoupSession. * * Return value: %TRUE if @auth is still a valid (but potentially * unauthenticated) #SoupAuth. %FALSE if something about @auth_params * could not be parsed or incorporated into @auth at all. **/ gboolean soup_auth_update (SoupAuth *auth, SoupMessage *msg, const char *auth_header) { GHashTable *params; const char *scheme, *realm; gboolean was_authenticated, success; g_return_val_if_fail (SOUP_IS_AUTH (auth), FALSE); g_return_val_if_fail (SOUP_IS_MESSAGE (msg), FALSE); g_return_val_if_fail (auth_header != NULL, FALSE); scheme = soup_auth_get_scheme_name (auth); if (g_ascii_strncasecmp (auth_header, scheme, strlen (scheme)) != 0) return FALSE; params = soup_header_parse_param_list (auth_header + strlen (scheme)); if (!params) params = g_hash_table_new (NULL, NULL); realm = g_hash_table_lookup (params, "realm"); if (realm && auth->realm && strcmp (realm, auth->realm) != 0) { soup_header_free_param_list (params); return FALSE; } was_authenticated = soup_auth_is_authenticated (auth); success = SOUP_AUTH_GET_CLASS (auth)->update (auth, msg, params); if (was_authenticated != soup_auth_is_authenticated (auth)) g_object_notify (G_OBJECT (auth), SOUP_AUTH_IS_AUTHENTICATED); soup_header_free_param_list (params); return success; }
static void authentication_info_cb (SoupMessage *msg, gpointer data) { SoupAuth *auth = data; SoupAuthDigestPrivate *priv = SOUP_AUTH_DIGEST_GET_PRIVATE (auth); const char *header; GHashTable *auth_params; char *nextnonce; if (auth != soup_message_get_auth (msg)) return; header = soup_message_headers_get_one (msg->response_headers, soup_auth_is_for_proxy (auth) ? "Proxy-Authentication-Info" : "Authentication-Info"); g_return_if_fail (header != NULL); auth_params = soup_header_parse_param_list (header); if (!auth_params) return; nextnonce = g_strdup (g_hash_table_lookup (auth_params, "nextnonce")); if (nextnonce) { g_free (priv->nonce); priv->nonce = nextnonce; } soup_header_free_param_list (auth_params); }
static char * soup_auth_domain_digest_accepts (SoupAuthDomain *domain, SoupMessage *msg, const char *header) { SoupAuthDomainDigestPrivate *priv = SOUP_AUTH_DOMAIN_DIGEST_GET_PRIVATE (domain); GHashTable *params; const char *username; gboolean accept = FALSE; char *ret_user; if (strncmp (header, "Digest ", 7) != 0) return NULL; params = soup_header_parse_param_list (header + 7); if (!params) return NULL; username = g_hash_table_lookup (params, "username"); if (!username) { soup_header_free_param_list (params); return NULL; } if (priv->auth_callback) { char *hex_urp; hex_urp = priv->auth_callback (domain, msg, username, priv->auth_data); if (hex_urp) { accept = check_hex_urp (domain, msg, params, username, hex_urp); g_free (hex_urp); } else accept = FALSE; } else { accept = soup_auth_domain_try_generic_auth_callback ( domain, msg, username); } ret_user = accept ? g_strdup (username) : NULL; soup_header_free_param_list (params); return ret_user; }
/** * soup_auth_new: * @type: the type of auth to create (a subtype of #SoupAuth) * @msg: the #SoupMessage the auth is being created for * @auth_header: the WWW-Authenticate/Proxy-Authenticate header * * Creates a new #SoupAuth of type @type with the information from * @msg and @auth_header. * * This is called by #SoupSession; you will normally not create auths * yourself. * * Return value: the new #SoupAuth, or %NULL if it could not be * created **/ SoupAuth * soup_auth_new (GType type, SoupMessage *msg, const char *auth_header) { SoupAuth *auth; GHashTable *params; const char *scheme, *realm; g_return_val_if_fail (g_type_is_a (type, SOUP_TYPE_AUTH), NULL); g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL); g_return_val_if_fail (auth_header != NULL, NULL); auth = g_object_new (type, SOUP_AUTH_IS_FOR_PROXY, (msg->status_code == SOUP_STATUS_PROXY_UNAUTHORIZED), SOUP_AUTH_HOST, soup_message_get_uri (msg)->host, NULL); scheme = soup_auth_get_scheme_name (auth); if (g_ascii_strncasecmp (auth_header, scheme, strlen (scheme)) != 0) { g_object_unref (auth); return NULL; } params = soup_header_parse_param_list (auth_header + strlen (scheme)); if (!params) { g_object_unref (auth); return NULL; } realm = g_hash_table_lookup (params, "realm"); if (!realm) { soup_header_free_param_list (params); g_object_unref (auth); return NULL; } auth->realm = g_strdup (realm); if (!SOUP_AUTH_GET_CLASS (auth)->update (auth, msg, params)) { g_object_unref (auth); auth = NULL; } soup_header_free_param_list (params); return auth; }
/** * Parses the hsts directives from given header like specified in RFC 6797 6.1 */ static void parse_hsts_header(HSTSProvider *provider, const char *host, const char *header) { GHashTable *directives = soup_header_parse_semi_param_list(header); HSTSEntry *entry; int max_age = G_MAXINT; gboolean include_sub_domains = false; GHashTableIter iter; gpointer key, value; gboolean success = true; HSTSProviderClass *klass = g_type_class_ref(HSTS_TYPE_PROVIDER); g_hash_table_iter_init(&iter, directives); while (g_hash_table_iter_next(&iter, &key, &value)) { /* parse the max-age directive */ if (!g_ascii_strncasecmp(key, "max-age", 7)) { /* max age needs a value */ if (value) { max_age = g_ascii_strtoll(value, NULL, 10); if (max_age < 0) { success = false; break; } } else { success = false; break; } } else if (g_ascii_strncasecmp(key, "includeSubDomains", 17)) { /* includeSubDomains must not have a value */ if (!value) { include_sub_domains = true; } else { success = false; break; } } } soup_header_free_param_list(directives); g_type_class_unref(klass); if (success) { /* remove host if max-age = 0 RFC 6797 6.1.1 */ if (max_age == 0) { remove_host_entry(provider, host); } else { entry = g_slice_new(HSTSEntry); entry->expires_at = soup_date_new_from_now(max_age); entry->include_sub_domains = include_sub_domains; add_host_entry(provider, host, entry); add_host_entry_to_file(provider, host, entry); } } }
/** * Handle dbus method calls. */ static void dbus_handle_method_call(GDBusConnection *conn, const char *sender, const char *object_path, const char *interface_name, const char *method, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer extension) { char *value; guint64 pageid; WebKitWebPage *page; if (g_str_has_prefix(method, "EvalJs")) { char *result = NULL; gboolean success; gboolean no_result; JSValueRef ref = NULL; JSGlobalContextRef jsContext; g_variant_get(parameters, "(ts)", &pageid, &value); page = get_web_page_or_return_dbus_error(invocation, WEBKIT_WEB_EXTENSION(extension), pageid); if (!page) { return; } no_result = !g_strcmp0(method, "EvalJsNoResult"); jsContext = webkit_frame_get_javascript_context_for_script_world( webkit_web_page_get_main_frame(page), webkit_script_world_get_default() ); success = ext_util_js_eval(jsContext, value, &ref); if (no_result) { g_dbus_method_invocation_return_value(invocation, NULL); } else { result = ext_util_js_ref_to_string(jsContext, ref); g_dbus_method_invocation_return_value(invocation, g_variant_new("(bs)", success, result)); g_free(result); } } else if (!g_strcmp0(method, "FocusInput")) { g_variant_get(parameters, "(t)", &pageid); page = get_web_page_or_return_dbus_error(invocation, WEBKIT_WEB_EXTENSION(extension), pageid); if (!page) { return; } ext_dom_focus_input(webkit_web_page_get_dom_document(page)); g_dbus_method_invocation_return_value(invocation, NULL); } else if (!g_strcmp0(method, "SetHeaderSetting")) { g_variant_get(parameters, "(s)", &value); if (ext.headers) { soup_header_free_param_list(ext.headers); ext.headers = NULL; } ext.headers = soup_header_parse_param_list(value); g_dbus_method_invocation_return_value(invocation, NULL); } }