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;
}
Example #2
0
/**
 * 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;
}
Example #3
0
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);
}
Example #4
0
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;
}
Example #5
0
/**
 * 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;
}
Example #6
0
/**
 * 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);
        }
    }
}
Example #7
0
/**
 * 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);
    }
}