summaryrefslogtreecommitdiff
path: root/desktop
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2019-08-06 11:25:11 +0100
committerDaniel Silverstone <dsilvers@digital-scurf.org>2019-08-06 11:26:47 +0100
commit8469f4cc8e62e80a3165a1d4f13b62b5b4a04720 (patch)
tree707b46c3cf0b373b53adf8c54d290e4c546ebb2c /desktop
parent9c9c26a308995c22210c90e3772e86f49a1948b9 (diff)
downloadnetsurf-8469f4cc8e62e80a3165a1d4f13b62b5b4a04720.tar.gz
netsurf-8469f4cc8e62e80a3165a1d4f13b62b5b4a04720.tar.bz2
Reimplement handling of BAD_AUTH inside browser_window
We now handle authentication requests via an `about:` page which presents a nice form built into the browser window. In order to do this, we add internal navigation as a concept to the browser window and we strip the 401login support from all frontends except monkey. The 401login callback is now intended for password safe type support rather than an immediately interactive prompt. Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
Diffstat (limited to 'desktop')
-rw-r--r--desktop/browser_private.h2
-rw-r--r--desktop/browser_window.c491
-rw-r--r--desktop/gui_factory.c14
-rw-r--r--desktop/netsurf.c200
4 files changed, 442 insertions, 265 deletions
diff --git a/desktop/browser_private.h b/desktop/browser_private.h
index 8838436fb..0995561f6 100644
--- a/desktop/browser_private.h
+++ b/desktop/browser_private.h
@@ -167,6 +167,8 @@ struct browser_window {
bool throbbing;
/** Add loading_content to the window history when it loads. */
bool history_add;
+ /** Internal navigation, do not update URL etc */
+ bool internal_nav;
/** Fragment identifier for current_content. */
lwc_string *frag_id;
diff --git a/desktop/browser_window.c b/desktop/browser_window.c
index 78f1cc2fd..911d7abde 100644
--- a/desktop/browser_window.c
+++ b/desktop/browser_window.c
@@ -92,6 +92,33 @@ static nserror browser_window__navigate_internal(
/**
+ * Close and destroy all child browser window.
+ *
+ * \param bw browser window
+ */
+static void browser_window_destroy_children(struct browser_window *bw)
+{
+ int i;
+
+ if (bw->children) {
+ for (i = 0; i < (bw->rows * bw->cols); i++)
+ browser_window_destroy_internal(&bw->children[i]);
+ free(bw->children);
+ bw->children = NULL;
+ bw->rows = 0;
+ bw->cols = 0;
+ }
+ if (bw->iframes) {
+ for (i = 0; i < bw->iframe_count; i++)
+ browser_window_destroy_internal(&bw->iframes[i]);
+ free(bw->iframes);
+ bw->iframes = NULL;
+ bw->iframe_count = 0;
+ }
+}
+
+
+/**
* Free the stored fetch parameters
*
* \param bw The browser window
@@ -679,14 +706,16 @@ static nserror browser_window_content_ready(struct browser_window *bw)
bw->current_content = bw->loading_content;
bw->loading_content = NULL;
- /* Transfer the fetch parameters */
- browser_window__free_fetch_parameters(&bw->current_parameters);
- bw->current_parameters = bw->loading_parameters;
- memset(&bw->loading_parameters, 0, sizeof(bw->loading_parameters));
+ if (!bw->internal_nav) {
+ /* Transfer the fetch parameters */
+ browser_window__free_fetch_parameters(&bw->current_parameters);
+ bw->current_parameters = bw->loading_parameters;
+ memset(&bw->loading_parameters, 0, sizeof(bw->loading_parameters));
+ /* Transfer the SSL info */
+ bw->current_ssl_info = bw->loading_ssl_info;
+ bw->loading_ssl_info.num = 0;
+ }
- /* Transfer the SSL info */
- bw->current_ssl_info = bw->loading_ssl_info;
- bw->loading_ssl_info.num = 0;
/* Format the new content to the correct dimensions */
browser_window_get_dimensions(bw, &width, &height);
@@ -800,7 +829,9 @@ browser_window_content_done(struct browser_window *bw)
}
browser_window_history_update(bw, bw->current_content);
- hotlist_update_url(hlcache_handle_get_url(bw->current_content));
+ if (!bw->internal_nav) {
+ hotlist_update_url(hlcache_handle_get_url(bw->current_content));
+ }
if (bw->refresh_interval != -1) {
guit->misc->schedule(bw->refresh_interval * 10,
@@ -810,12 +841,8 @@ browser_window_content_done(struct browser_window *bw)
return NSERROR_OK;
}
-/* Cheeky import for now */
-nserror netsurf__handle_login(const char * realm, nsurl *url,
- browser_window_query_callback cb, void *cbpw);
-
/**
- * Handle query responses from authentication or SSL requests
+ * Handle query responses from SSL requests
*/
static nserror
browser_window__handle_query_response(bool proceed, void *pw)
@@ -837,6 +864,215 @@ browser_window__handle_query_response(bool proceed, void *pw)
return res;
}
+/**
+ * Unpack a "username:password" to components.
+ *
+ * \param[in] userpass The input string to split.
+ * \param[in] username_out Returns username on success. Owned by caller.
+ * \param[out] password_out Returns password on success. Owned by caller.
+ * \return NSERROR_OK, or appropriate error code.
+ */
+static nserror
+browser_window__unpack_userpass(const char *userpass,
+ char **username_out,
+ char **password_out)
+{
+ const char *tmp;
+ char *username;
+ char *password;
+ size_t len;
+
+ if (userpass == NULL) {
+ username = malloc(1);
+ password = malloc(1);
+ if (username == NULL || password == NULL) {
+ free(username);
+ free(password);
+ return NSERROR_NOMEM;
+ }
+ username[0] = '\0';
+ password[0] = '\0';
+
+ *username_out = username;
+ *password_out = password;
+ return NSERROR_OK;
+ }
+
+ tmp = strchr(userpass, ':');
+ if (tmp == NULL) {
+ return NSERROR_BAD_PARAMETER;
+ } else {
+ size_t len2;
+ len = tmp - userpass;
+ len2 = strlen(++tmp);
+
+ username = malloc(len + 1);
+ password = malloc(len2 + 1);
+ if (username == NULL || password == NULL) {
+ free(username);
+ free(password);
+ return NSERROR_NOMEM;
+ }
+ memcpy(username, userpass, len);
+ username[len] = '\0';
+ memcpy(password, tmp, len2 + 1);
+ }
+
+ *username_out = username;
+ *password_out = password;
+ return NSERROR_OK;
+}
+
+/**
+ * Build a "username:password" from components.
+ *
+ * \param[in] username The username component.
+ * \param[in] password The password component.
+ * \param[out] userpass_out Returns combined string on success.
+ * Owned by caller.
+ * \return NSERROR_OK, or appropriate error code.
+ */
+static nserror
+browser_window__build_userpass(const char *username,
+ const char *password,
+ char **userpass_out)
+{
+ char *userpass;
+ size_t len;
+
+ len = strlen(username) + 1 + strlen(password) + 1;
+
+ userpass = malloc(len);
+ if (userpass == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ snprintf(userpass, len, "%s:%s", username, password);
+
+ *userpass_out = userpass;
+ return NSERROR_OK;
+}
+
+/**
+ * Handle a response from the UI when prompted for credentials
+ */
+static nserror
+browser_window__handle_userpass_response(nsurl *url,
+ const char *realm,
+ const char *username,
+ const char *password,
+ void *pw)
+{
+ struct browser_window *bw = (struct browser_window *)pw;
+ char *userpass;
+ nserror err;
+
+ err = browser_window__build_userpass(username, password, &userpass);
+ if (err != NSERROR_OK) {
+ return err;
+ }
+
+ urldb_set_auth_details(url, realm, userpass);
+
+ free(userpass);
+
+ /**
+ * \todo QUERY - Eventually this should fill out the form *NOT* nav
+ * to the original location
+ */
+ /* Finally navigate to the original loading parameters */
+ if (bw->loading_content != NULL) {
+ /* We had a loading content (maybe auth page?) */
+ browser_window_stop(bw);
+ browser_window_remove_caret(bw, false);
+ browser_window_destroy_children(bw);
+ }
+ bw->internal_nav = false;
+ return browser_window__navigate_internal(bw, &bw->loading_parameters);
+}
+
+/**
+ * Handle login request (BAD_AUTH) during fetch
+ *
+ */
+static nserror
+browser_window__handle_login(struct browser_window *bw,
+ const char *realm,
+ nsurl *url) {
+ char *username = NULL, *password = NULL;
+ nserror err = NSERROR_OK;
+ struct browser_fetch_parameters params;
+
+ memset(&params, 0, sizeof(params));
+
+ /* Step one, retrieve what we have */
+ err = browser_window__unpack_userpass(
+ urldb_get_auth_details(url, realm),
+ &username, &password);
+ if (err != NSERROR_OK) {
+ goto out;
+ }
+
+ /* Step two, construct our fetch parameters */
+ err = nsurl_create("about:query/auth", &params.url);
+ if (err != NSERROR_OK) {
+ goto out;
+ }
+ params.referrer = nsurl_ref(url);
+ params.flags = BW_NAVIGATE_HISTORY | BW_NAVIGATE_NO_TERMINAL_HISTORY_UPDATE | BW_NAVIGATE_INTERNAL;
+
+ err = fetch_multipart_data_new_kv(&params.post_multipart,
+ "siteurl",
+ nsurl_access(url));
+ if (err != NSERROR_OK) {
+ goto out;
+ }
+
+ err = fetch_multipart_data_new_kv(&params.post_multipart,
+ "realm",
+ realm);
+ if (err != NSERROR_OK) {
+ goto out;
+ }
+
+ err = fetch_multipart_data_new_kv(&params.post_multipart,
+ "username",
+ username);
+ if (err != NSERROR_OK) {
+ goto out;
+ }
+
+ err = fetch_multipart_data_new_kv(&params.post_multipart,
+ "password",
+ password);
+ if (err != NSERROR_OK) {
+ goto out;
+ }
+
+ /* Now we issue the fetch */
+ bw->internal_nav = true;
+ err = browser_window__navigate_internal(bw, &params);
+
+ if (err != NSERROR_OK) {
+ goto out;
+ }
+
+ err = guit->misc->login(url, realm, username, password,
+ browser_window__handle_userpass_response, bw);
+
+ if (err == NSERROR_NOT_IMPLEMENTED) {
+ err = NSERROR_OK;
+ }
+out:
+ if (username != NULL) {
+ free(username);
+ }
+ if (password != NULL) {
+ free(password);
+ }
+ browser_window__free_fetch_parameters(&params);
+ return err;
+}
/**
* Handle errors during content fetch
@@ -891,9 +1127,7 @@ browser_window__handle_error(struct browser_window *bw,
switch (code) {
case NSERROR_BAD_AUTH:
- res = netsurf__handle_login(message, url,
- browser_window__handle_query_response,
- bw);
+ res = browser_window__handle_login(bw, message, url);
break;
case NSERROR_BAD_CERTS:
res = guit->misc->cert_verify(url,
@@ -1235,33 +1469,6 @@ browser_window_callback(hlcache_handle *c, const hlcache_event *event, void *pw)
/**
- * Close and destroy all child browser window.
- *
- * \param bw browser window
- */
-static void browser_window_destroy_children(struct browser_window *bw)
-{
- int i;
-
- if (bw->children) {
- for (i = 0; i < (bw->rows * bw->cols); i++)
- browser_window_destroy_internal(&bw->children[i]);
- free(bw->children);
- bw->children = NULL;
- bw->rows = 0;
- bw->cols = 0;
- }
- if (bw->iframes) {
- for (i = 0; i < bw->iframe_count; i++)
- browser_window_destroy_internal(&bw->iframes[i]);
- free(bw->iframes);
- bw->iframes = NULL;
- bw->iframe_count = 0;
- }
-}
-
-
-/**
* internal scheduled reformat callback.
*
* scheduled reformat callback to allow reformats from unthreaded context.
@@ -2717,12 +2924,23 @@ nserror browser_window_refresh_url_bar(struct browser_window *bw)
ret = browser_window_refresh_url_bar_internal(bw,
corestring_nsurl_about_blank);
} else if (bw->frag_id == NULL) {
- ret = browser_window_refresh_url_bar_internal(bw,
- hlcache_handle_get_url(bw->current_content));
+ nsurl *url;
+ if (bw->internal_nav) {
+ url = bw->loading_parameters.url;
+ } else {
+ url = hlcache_handle_get_url(bw->current_content);
+ }
+ ret = browser_window_refresh_url_bar_internal(bw, url);
} else {
/* Combine URL and Fragment */
+ nsurl *url;
+ if (bw->internal_nav) {
+ url = bw->loading_parameters.url;
+ } else {
+ url = hlcache_handle_get_url(bw->current_content);
+ }
ret = nsurl_refragment(
- hlcache_handle_get_url(bw->current_content),
+ url,
bw->frag_id, &display_url);
if (ret == NSERROR_OK) {
ret = browser_window_refresh_url_bar_internal(bw,
@@ -2752,12 +2970,38 @@ browser_window_navigate(struct browser_window *bw,
llcache_post_data post;
hlcache_child_context child;
nserror error;
+ bool is_internal = false;
+ struct browser_fetch_parameters params, *pass_params = NULL;
+ lwc_string *scheme, *path;
assert(bw);
assert(url);
NSLOG(netsurf, INFO, "bw %p, url %s", bw, nsurl_access(url));
+ /* Check if this is an internal navigation URL, if so, we do not
+ * do certain things during the load
+ */
+ scheme = nsurl_get_component(url, NSURL_SCHEME);
+ path = nsurl_get_component(url, NSURL_PATH);
+ if (scheme == corestring_lwc_about) {
+ if (path == corestring_lwc_query_auth) {
+ is_internal = true;
+ }
+ }
+ lwc_string_unref(scheme);
+ lwc_string_unref(path);
+
+ if (is_internal &&
+ !(flags & BW_NAVIGATE_INTERNAL)) {
+ /* Internal navigation detected, but flag not set, only allow
+ * this is there's a fetch multipart
+ */
+ if (post_multipart == NULL) {
+ return NSERROR_NEED_DATA;
+ }
+ }
+
/* If we're navigating and we have a history entry and a content
* then update the history entry before we navigate to save our
* current state. However since history navigation pre-moves
@@ -2768,6 +3012,7 @@ browser_window_navigate(struct browser_window *bw,
if (bw->current_content != NULL &&
bw->history != NULL &&
bw->history->current != NULL &&
+ !is_internal &&
!(flags & BW_NAVIGATE_NO_TERMINAL_HISTORY_UPDATE)) {
browser_window_history_update(bw, bw->current_content);
}
@@ -2872,31 +3117,43 @@ browser_window_navigate(struct browser_window *bw,
browser_window_remove_caret(bw, false);
browser_window_destroy_children(bw);
- /* At this point, we're navigating, so store the fetch parameters */
- browser_window__free_fetch_parameters(&bw->loading_parameters);
+ /* Set up the fetch parameters */
+ memset(&params, 0, sizeof(params));
- bw->loading_parameters.url = nsurl_ref(url);
+ params.url = nsurl_ref(url);
if (referrer != NULL) {
- bw->loading_parameters.referrer = nsurl_ref(referrer);
+ params.referrer = nsurl_ref(referrer);
}
- bw->loading_parameters.flags = flags;
+ params.flags = flags;
if (post_urlenc != NULL) {
- bw->loading_parameters.post_urlenc = strdup(post_urlenc);
+ params.post_urlenc = strdup(post_urlenc);
}
if (post_multipart != NULL) {
- bw->loading_parameters.post_multipart = fetch_multipart_data_clone(post_multipart);
+ params.post_multipart = fetch_multipart_data_clone(post_multipart);
}
if (parent != NULL) {
- bw->loading_parameters.parent_charset = strdup(child.charset);
- bw->loading_parameters.parent_quirks = child.quirks;
+ params.parent_charset = strdup(child.charset);
+ params.parent_quirks = child.quirks;
}
- error = browser_window__navigate_internal(bw, &bw->loading_parameters);
+ bw->internal_nav = is_internal;
+
+ if (is_internal) {
+ pass_params = &params;
+ } else {
+ /* At this point, we're navigating, so store the fetch parameters */
+ browser_window__free_fetch_parameters(&bw->loading_parameters);
+ memcpy(&bw->loading_parameters, &params, sizeof(params));
+ memset(&params, 0, sizeof(params));
+ pass_params = &bw->loading_parameters;
+ }
+
+ error = browser_window__navigate_internal(bw, pass_params);
nsurl_unref(url);
@@ -2904,12 +3161,16 @@ browser_window_navigate(struct browser_window *bw,
nsurl_unref(referrer);
}
+ if (is_internal) {
+ browser_window__free_fetch_parameters(&params);
+ }
+
return error;
}
-nserror
-browser_window__navigate_internal(struct browser_window *bw,
- struct browser_fetch_parameters *params)
+static nserror
+browser_window__navigate_internal_real(struct browser_window *bw,
+ struct browser_fetch_parameters *params)
{
uint32_t fetch_flags = 0;
bool fetch_is_post = (params->post_urlenc != NULL || params->post_multipart != NULL);
@@ -2985,6 +3246,118 @@ browser_window__navigate_internal(struct browser_window *bw,
return error;
}
+/**
+ * Internal navigation handler for the authentication query handler
+ *
+ * If the parameters indicate we're processing a *response* from the handler
+ * then we deal with that, otherwise we pass it on to the about: handler
+ */
+static nserror
+browser_window__navigate_internal_query_auth(struct browser_window *bw,
+ struct browser_fetch_parameters *params)
+{
+ char *userpass = NULL;
+ const char *username, *password, *realm, *siteurl;
+ nsurl *sitensurl;
+ nserror res;
+ bool is_login = false, is_cancel = false;
+
+ assert(params->post_multipart != NULL);
+
+ is_login = fetch_multipart_data_find(params->post_multipart, "login") != NULL;
+ is_cancel = fetch_multipart_data_find(params->post_multipart, "cancel") != NULL;
+
+ if (!(is_login || is_cancel)) {
+ /* This is a request, so pass it on */
+ return browser_window__navigate_internal_real(bw, params);
+ }
+
+ if (is_cancel) {
+ /* We're processing a cancel, do a rough-and-ready nav to
+ * about:blank
+ */
+ browser_window__free_fetch_parameters(&bw->loading_parameters);
+ res = nsurl_create("about:blank", &bw->loading_parameters.url);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+ bw->loading_parameters.flags = BW_NAVIGATE_NO_TERMINAL_HISTORY_UPDATE | BW_NAVIGATE_INTERNAL;
+ bw->internal_nav = true;
+ return browser_window__navigate_internal(bw, &bw->loading_parameters);
+ }
+
+ /* We're processing a "login" attempt from the form */
+
+ /* Retrieve the data */
+ username = fetch_multipart_data_find(params->post_multipart, "username");
+ password = fetch_multipart_data_find(params->post_multipart, "password");
+ realm = fetch_multipart_data_find(params->post_multipart, "realm");
+ siteurl = fetch_multipart_data_find(params->post_multipart, "siteurl");
+
+ if (username == NULL || password == NULL ||
+ realm == NULL || siteurl == NULL) {
+ /* Bad inputs, simply fail */
+ return NSERROR_INVALID;
+ }
+
+ /* Parse the URL */
+ res = nsurl_create(siteurl, &sitensurl);
+ if (res != NSERROR_OK) {
+ return res;
+ }
+
+ /* Construct the username/password */
+ res = browser_window__build_userpass(username, password, &userpass);
+ if (res != NSERROR_OK) {
+ nsurl_unref(sitensurl);
+ return res;
+ }
+
+ /* And let urldb know */
+ urldb_set_auth_details(sitensurl, realm, userpass);
+
+ /* Clean up */
+ free(userpass);
+ nsurl_unref(sitensurl);
+
+ /* Finally navigate to the original loading parameters */
+ return browser_window__navigate_internal_real(bw, &bw->loading_parameters);
+}
+
+
+nserror
+browser_window__navigate_internal(struct browser_window *bw,
+ struct browser_fetch_parameters *params)
+{
+ lwc_string *scheme, *path;
+ /* Here we determine if we're navigating to an internal query URI
+ * and if so, what we need to do about it.
+ *
+ * If we're not, then we just move on to the real navigate.
+ */
+
+ /* All our special URIs are in the about: scheme */
+ scheme = nsurl_get_component(params->url, NSURL_SCHEME);
+ if (scheme != corestring_lwc_about) {
+ lwc_string_unref(scheme);
+ goto normal_fetch;
+ }
+ lwc_string_unref(scheme);
+
+ /* Is it the auth query handler? */
+ path = nsurl_get_component(params->url, NSURL_PATH);
+ if (path == corestring_lwc_query_auth) {
+ lwc_string_unref(path);
+ return browser_window__navigate_internal_query_auth(bw, params);
+ }
+ lwc_string_unref(path);
+
+ /* Fall through to a normal about: fetch */
+
+normal_fetch:
+ return browser_window__navigate_internal_real(bw, params);
+}
+
/* Exported interface, documented in netsurf/browser_window.h */
bool browser_window_up_available(struct browser_window *bw)
diff --git a/desktop/gui_factory.c b/desktop/gui_factory.c
index 5628caad5..bd8d35bc5 100644
--- a/desktop/gui_factory.c
+++ b/desktop/gui_factory.c
@@ -691,12 +691,14 @@ static nserror gui_default_cert_verify(nsurl *url,
return NSERROR_NOT_IMPLEMENTED;
}
-static nserror gui_default_401login_open(nsurl *url, const char *realm,
- const char *username, const char *password,
- nserror (*cb)(const char *username,
- const char *password,
- void *pw),
- void *cbpw)
+static nserror gui_default_401login_open(
+ nsurl *url, const char *realm,
+ const char *username, const char *password,
+ nserror (*cb)(nsurl *url, const char * realm,
+ const char *username,
+ const char *password,
+ void *pw),
+ void *cbpw)
{
return NSERROR_NOT_IMPLEMENTED;
}
diff --git a/desktop/netsurf.c b/desktop/netsurf.c
index 706ca7be0..0928442dc 100644
--- a/desktop/netsurf.c
+++ b/desktop/netsurf.c
@@ -98,206 +98,6 @@ static void netsurf_lwc_iterator(lwc_string *str, void *pw)
(int)lwc_string_length(str), lwc_string_data(str));
}
-/**
- * Build a "username:password" from components.
- *
- * \param[in] username The username component.
- * \param[in] password The password component.
- * \param[out] userpass_out Returns combined string on success.
- * Owned by caller.
- * \return NSERROR_OK, or appropriate error code.
- */
-static nserror netsurf__build_userpass(
- const char *username,
- const char *password,
- char **userpass_out)
-{
- char *userpass;
- size_t len;
-
- len = strlen(username) + 1 + strlen(password) + 1;
-
- userpass = malloc(len);
- if (userpass == NULL) {
- return NSERROR_NOMEM;
- }
-
- snprintf(userpass, len, "%s:%s", username, password);
-
- *userpass_out = userpass;
- return NSERROR_OK;
-}
-
-/**
- * Unpack a "username:password" to components.
- *
- * \param[in] userpass The input string to split.
- * \param[in] username_out Returns username on success. Owned by caller.
- * \param[out] password_out Returns password on success. Owned by caller.
- * \return NSERROR_OK, or appropriate error code.
- */
-static nserror netsurf__unpack_userpass(
- const char *userpass,
- char **username_out,
- char **password_out)
-{
- const char *tmp;
- char *username;
- char *password;
- size_t len;
-
- if (userpass == NULL) {
- username = malloc(1);
- password = malloc(1);
- if (username == NULL || password == NULL) {
- free(username);
- free(password);
- return NSERROR_NOMEM;
- }
- username[0] = '\0';
- password[0] = '\0';
-
- *username_out = username;
- *password_out = password;
- return NSERROR_OK;
- }
-
- tmp = strchr(userpass, ':');
- if (tmp == NULL) {
- return NSERROR_BAD_PARAMETER;
- } else {
- size_t len2;
- len = tmp - userpass;
- len2 = strlen(++tmp);
-
- username = malloc(len + 1);
- password = malloc(len2 + 1);
- if (username == NULL || password == NULL) {
- free(username);
- free(password);
- return NSERROR_NOMEM;
- }
- memcpy(username, userpass, len);
- username[len] = '\0';
- memcpy(password, tmp, len2 + 1);
- }
-
- *username_out = username;
- *password_out = password;
- return NSERROR_OK;
-}
-
-/**
- * Contect for login callbacks to front ends.
- */
-struct auth_data {
- char *realm;
- nsurl *url;
-
- browser_window_query_callback cb;
- void *pw;
-};
-
-/**
- * Callback function passed to front ends for handling logins.
- *
- * \param[in] username The username.
- * \param[in] password The password.
- * \param[in] cbpw Our context.
- * \return NSERROR_OK, or appropriate error code.
- */
-static nserror netsurf__handle_login_response(
- const char *username,
- const char *password,
- void *cbpw)
-{
- struct auth_data *ctx = cbpw;
- bool proceed = false;
- nserror err;
-
- if (username != NULL && password != NULL) {
- char *userpass;
-
- err = netsurf__build_userpass(username, password, &userpass);
- if (err != NSERROR_OK) {
- return err;
- }
-
- urldb_set_auth_details(ctx->url, ctx->realm, userpass);
- free(userpass);
- proceed = true;
- }
-
- err = ctx->cb(proceed, ctx->pw);
- nsurl_unref(ctx->url);
- free(ctx->realm);
- free(ctx);
- return err;
-}
-
-/* Cheeky */
-nserror netsurf__handle_login(const char * realm, nsurl *url,
- browser_window_query_callback cb, void *cbpw);
-/**
- * Helper for getting front end to handle logins.
- *
- * \param[in] query Query descriptor
- * \param[in] pw Private data
- * \param[in] cb Continuation callback
- * \param[in] cbpw Private data for continuation
- * \return NSERROR_OK, or appropriate error code.
- */
-nserror netsurf__handle_login(const char * realm, nsurl *url,
- browser_window_query_callback cb, void *cbpw)
-{
- struct auth_data *ctx;
- char *username;
- char *password;
- nserror err;
-
- NSLOG(llcache, INFO, "HTTP Auth for: %s: %s",
- realm, nsurl_access(url));
-
- ctx = malloc(sizeof(*ctx));
- if (ctx == NULL) {
- return NSERROR_NOMEM;
- }
-
- ctx->realm = strdup(realm);
- if (ctx->realm == NULL) {
- free(ctx);
- return NSERROR_NOMEM;
- }
- ctx->url = nsurl_ref(url);
- ctx->cb = cb;
- ctx->pw = cbpw;
-
- err = netsurf__unpack_userpass(
- urldb_get_auth_details(ctx->url, ctx->realm),
- &username, &password);
- if (err != NSERROR_OK) {
- nsurl_unref(ctx->url);
- free(ctx->realm);
- free(ctx);
- return err;
- }
-
- err = guit->misc->login(ctx->url, ctx->realm, username, password,
- netsurf__handle_login_response, ctx);
- free(username);
- free(password);
- if (err != NSERROR_OK) {
- ctx->cb(false, ctx->pw);
- nsurl_unref(ctx->url);
- free(ctx->realm);
- free(ctx);
- return err;
- }
-
- return NSERROR_OK;
-}
-
-
/* exported interface documented in netsurf/netsurf.h */
nserror netsurf_init(const char *store_path)
{