summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2018-08-15 07:32:56 +0100
committerMichael Drake <tlsa@netsurf-browser.org>2018-08-15 07:32:56 +0100
commit77ae1ed7581e80691fc9e5bafd910a3f36a7d12a (patch)
tree88b47533d23194832786c759ea8123d11d6283be
parent9fa6c1e0fb2d6f5a0c95e7680b0ad24f9f7615db (diff)
parent5e97a3cb26e99ceac27f95be7a7527c630910ebf (diff)
downloadnetsurf-77ae1ed7581e80691fc9e5bafd910a3f36a7d12a.tar.gz
netsurf-77ae1ed7581e80691fc9e5bafd910a3f36a7d12a.tar.bz2
Merge branch 'tlsa/401'
-rw-r--r--content/urldb.h21
-rw-r--r--desktop/gui_factory.c10
-rw-r--r--desktop/netsurf.c198
-rwxr-xr-xfrontends/amiga/login.c52
-rwxr-xr-xfrontends/amiga/login.h8
-rw-r--r--frontends/atari/gui.c39
-rw-r--r--frontends/atari/login.c18
-rw-r--r--frontends/atari/login.h2
-rw-r--r--frontends/beos/gui.h7
-rw-r--r--frontends/beos/login.cpp31
-rw-r--r--frontends/beos/window.cpp15
-rw-r--r--frontends/gtk/login.c46
-rw-r--r--frontends/gtk/login.h7
-rw-r--r--frontends/monkey/401login.c15
-rw-r--r--frontends/monkey/401login.h8
-rw-r--r--frontends/riscos/401login.c77
-rw-r--r--frontends/riscos/gui.h8
-rw-r--r--include/netsurf/misc.h33
-rw-r--r--include/netsurf/url_db.h21
19 files changed, 443 insertions, 173 deletions
diff --git a/content/urldb.h b/content/urldb.h
index 0ad64267f..c68c2a611 100644
--- a/content/urldb.h
+++ b/content/urldb.h
@@ -75,6 +75,27 @@ nserror urldb_set_url_content_type(struct nsurl *url, content_type type);
/**
+ * Set authentication data for an URL
+ *
+ * \param url The URL to consider
+ * \param realm The authentication realm
+ * \param auth The authentication details (in form username:password)
+ */
+void urldb_set_auth_details(struct nsurl *url, const char *realm, const char *auth);
+
+
+/**
+ * Look up authentication details in database
+ *
+ * \param url Absolute URL to search for
+ * \param realm When non-NULL, it is realm which can be used to determine
+ * the protection space when that's not been done before for given URL.
+ * \return Pointer to authentication details, or NULL if not found
+ */
+const char *urldb_get_auth_details(struct nsurl *url, const char *realm);
+
+
+/**
* Update an URL's visit data
*
* \param url The URL to update
diff --git a/desktop/gui_factory.c b/desktop/gui_factory.c
index ca9eff1da..b2b9a3bf8 100644
--- a/desktop/gui_factory.c
+++ b/desktop/gui_factory.c
@@ -679,10 +679,14 @@ static nserror gui_default_cert_verify(nsurl *url,
return NSERROR_NOT_IMPLEMENTED;
}
-static void gui_default_401login_open(nsurl *url, const char *realm,
- nserror (*cb)(bool proceed, void *pw), void *cbpw)
+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)
{
- cb(false, cbpw);
+ return NSERROR_NOT_IMPLEMENTED;
}
static void
diff --git a/desktop/netsurf.c b/desktop/netsurf.c
index f39a6baef..3757a2a34 100644
--- a/desktop/netsurf.c
+++ b/desktop/netsurf.c
@@ -30,6 +30,7 @@
#include "utils/nsoption.h"
#include "utils/corestrings.h"
#include "utils/log.h"
+#include "utils/string.h"
#include "utils/utf8.h"
#include "utils/messages.h"
#include "content/content_factory.h"
@@ -94,6 +95,198 @@ static void netsurf_lwc_iterator(lwc_string *str, void *pw)
}
/**
+ * 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) {
+ 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) {
+ 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;
+
+ llcache_query_response 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;
+}
+
+/**
+ * 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.
+ */
+static nserror netsurf__handle_login(const llcache_query *query,
+ void *pw, llcache_query_response cb, void *cbpw)
+{
+ struct auth_data *ctx;
+ char *username;
+ char *password;
+ nserror err;
+
+ NSLOG(llcache, INFO, "HTTP Auth for: %s: %s",
+ query->data.auth.realm, nsurl_access(query->url));
+
+ ctx = malloc(sizeof(*ctx));
+ if (ctx == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ ctx->realm = strdup(query->data.auth.realm);
+ if (ctx->realm == NULL) {
+ free(ctx);
+ return NSERROR_NOMEM;
+ }
+ ctx->url = nsurl_ref(query->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;
+}
+
+/**
* Dispatch a low-level cache query to the frontend
*
* \param query Query descriptor
@@ -109,10 +302,7 @@ static nserror netsurf_llcache_query_handler(const llcache_query *query,
switch (query->type) {
case LLCACHE_QUERY_AUTH:
- NSLOG(llcache, INFO, "HTTP Auth for: %s: %s",
- query->data.auth.realm,
- nsurl_access(query->url));
- guit->misc->login(query->url, query->data.auth.realm, cb, cbpw);
+ res = netsurf__handle_login(query, pw, cb, cbpw);
break;
case LLCACHE_QUERY_REDIRECT:
diff --git a/frontends/amiga/login.c b/frontends/amiga/login.c
index db15b431d..6735f9350 100755
--- a/frontends/amiga/login.c
+++ b/frontends/amiga/login.c
@@ -53,7 +53,7 @@ struct gui_login_window {
struct ami_generic_window w;
struct Window *win;
Object *objects[GID_LAST];
- nserror (*cb)(bool proceed, void *pw);
+ nserror (*cb)(const char *username, const char *password, void *pw);
void *cbpw;
nsurl *url;
char *realm;
@@ -70,14 +70,20 @@ static const struct ami_win_event_table ami_login_table = {
@todo check if this prevents us from quitting NetSurf */
};
-void gui_401login_open(nsurl *url, const char *realm,
- nserror (*cb)(bool proceed, void *pw), void *cbpw)
+nserror gui_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)
{
- const char *auth;
struct gui_login_window *lw = calloc(1, sizeof(struct gui_login_window));
lwc_string *host = nsurl_get_component(url, NSURL_HOST);
+ size_t len;
assert(host != NULL);
+ assert(username != NULL);
+ assert(password != NULL);
lw->host = host;
lw->url = nsurl_ref(url);
@@ -85,25 +91,13 @@ void gui_401login_open(nsurl *url, const char *realm,
lw->cb = cb;
lw->cbpw = cbpw;
- auth = urldb_get_auth_details(lw->url, realm);
-
- if (auth == NULL) {
- lw->uname[0] = '\0';
- lw->pwd[0] = '\0';
- } else {
- const char *pwd;
- size_t pwd_len;
-
- pwd = strchr(auth, ':');
- assert(pwd && pwd < auth + sizeof(lw->uname));
- memcpy(lw->uname, auth, pwd - auth);
- lw->uname[pwd - auth] = '\0';
- ++pwd;
- pwd_len = strlen(pwd);
- assert(pwd_len < sizeof(lw->pwd));
- memcpy(lw->pwd, pwd, pwd_len);
- lw->pwd[pwd_len] = '\0';
- }
+ len = strlen(username);
+ assert(len < sizeof(lw->uname));
+ memcpy(lw->uname, username, len + 1);
+
+ len = strlen(password);
+ assert(len < sizeof(lw->pwd));
+ memcpy(lw->pwd, password, len + 1);
lw->objects[OID_MAIN] = WindowObj,
WA_ScreenTitle, ami_gui_get_screen_title(),
@@ -177,13 +171,15 @@ void gui_401login_open(nsurl *url, const char *realm,
lw->win = (struct Window *)RA_OpenWindow(lw->objects[OID_MAIN]);
ami_gui_win_list_add(lw, AMINS_LOGINWINDOW, &ami_login_table);
+
+ return NSERROR_OK;
}
static void ami_401login_close(struct gui_login_window *lw)
{
/* If continuation exists, then forbid refetch */
if (lw->cb != NULL)
- lw->cb(false, lw->cbpw);
+ lw->cb(NULL, NULL, lw->cbpw);
DisposeObject(lw->objects[OID_MAIN]);
lwc_string_unref(lw->host);
@@ -195,16 +191,12 @@ static void ami_401login_close(struct gui_login_window *lw)
static void ami_401login_login(struct gui_login_window *lw)
{
ULONG *user,*pass;
- STRPTR userpass;
GetAttr(STRINGA_TextVal,lw->objects[GID_USER],(ULONG *)&user);
GetAttr(STRINGA_TextVal,lw->objects[GID_PASS],(ULONG *)&pass);
- userpass = ASPrintf("%s:%s",user,pass);
- urldb_set_auth_details(lw->url,lw->realm,userpass);
- FreeVec(userpass);
-
- lw->cb(true, lw->cbpw);
+ /* TODO: Encoding conversion to UTF8 for `user` and `pass`? */
+ lw->cb(user, pass, lw->cbpw);
/* Invalidate continuation */
lw->cb = NULL;
diff --git a/frontends/amiga/login.h b/frontends/amiga/login.h
index 058fa5948..e2fdf1705 100755
--- a/frontends/amiga/login.h
+++ b/frontends/amiga/login.h
@@ -23,7 +23,11 @@
struct gui_login_window;
-void gui_401login_open(nsurl *url, const char *realm,
- nserror (*cb)(bool proceed, void *pw), void *cbpw);
+nserror gui_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);
#endif
diff --git a/frontends/atari/gui.c b/frontends/atari/gui.c
index 6ee63b301..14e02e5f8 100644
--- a/frontends/atari/gui.c
+++ b/frontends/atari/gui.c
@@ -767,23 +767,30 @@ static void gui_set_clipboard(const char *buffer, size_t length,
}
static void gui_401login_open(nsurl *url, const char *realm,
- nserror (*cb)(bool proceed, void *pw), void *cbpw)
+ const char *username, const char *password,
+ nserror (*cb)(const char *username,
+ const char *password,
+ void *pw),
+ void *cbpw)
{
- bool bres;
- char * out = NULL;
- bres = login_form_do( url, (char*)realm, &out);
- if (bres) {
- NSLOG(netsurf, INFO, "url: %s, realm: %s, auth: %s\n",
- nsurl_access(url), realm, out);
- urldb_set_auth_details(url, realm, out);
- }
- if (out != NULL) {
- free( out );
- }
- if (cb != NULL) {
- cb(bres, cbpw);
- }
-
+ bool bres;
+ char * u_out = NULL;
+ char * p_out = NULL;
+
+ bres = login_form_do(url, (char*)realm, &u_out, &p_out);
+ if (bres) {
+ NSLOG(netsurf, INFO, "url: %s, realm: %s, auth: %s\n",
+ nsurl_access(url), realm, out);
+ }
+ if (cb != NULL) {
+ cb(u_out, p_out, cbpw);
+ }
+ if (u_out != NULL) {
+ free(u_out);
+ }
+ if (p_out != NULL) {
+ free(p_out);
+ }
}
static nserror
diff --git a/frontends/atari/login.c b/frontends/atari/login.c
index 1b21c5d2a..6736c3ab2 100644
--- a/frontends/atari/login.c
+++ b/frontends/atari/login.c
@@ -34,7 +34,7 @@
#include "atari/res/netsurf.rsh"
-bool login_form_do(nsurl * url, char * realm, char ** out)
+bool login_form_do(nsurl * url, char * realm, char ** u_out char ** p_out)
{
char user[255];
char pass[255];
@@ -45,8 +45,6 @@ bool login_form_do(nsurl * url, char * realm, char ** out)
user[0] = 0;
pass[0] = 0;
- // TODO: use auth details for predefined login data
- // auth = urldb_get_auth_details(url, realm);
tree = gemtk_obj_get_tree(LOGIN);
assert(tree != NULL);
@@ -57,10 +55,18 @@ bool login_form_do(nsurl * url, char * realm, char ** out)
get_string(tree, LOGIN_TB_USER, user);
get_string(tree, LOGIN_TB_PASSWORD, pass);
int size = strlen((char*)&user) + strlen((char*)&pass) + 2 ;
- *out = malloc(size);
- snprintf(*out, size, "%s:%s", user, pass);
+ *u_out = malloc(strlen((char*)&user) + 1);
+ *p_out = malloc(strlen((char*)&pass) + 1);
+ if (u_out == NULL || p_out == NULL) {
+ free(*u_out);
+ free(*p_out);
+ return false;
+ }
+ memcpy(*u_out, (char*)&user, strlen((char*)&user) + 1);
+ memcpy(*p_out, (char*)&pass, strlen((char*)&pass) + 1);
} else {
- *out = NULL;
+ *u_out = NULL;
+ *p_out = NULL;
}
return((exit_obj == LOGIN_BT_LOGIN));
}
diff --git a/frontends/atari/login.h b/frontends/atari/login.h
index b61808c71..3b714dd9d 100644
--- a/frontends/atari/login.h
+++ b/frontends/atari/login.h
@@ -21,6 +21,6 @@
#include "utils/nsurl.h"
-bool login_form_do( nsurl * host, char * realm, char **cbpw );
+bool login_form_do(nsurl * url, char * realm, char ** u_out char ** p_out);
#endif
diff --git a/frontends/beos/gui.h b/frontends/beos/gui.h
index debb5f339..35f3134fb 100644
--- a/frontends/beos/gui.h
+++ b/frontends/beos/gui.h
@@ -35,7 +35,12 @@ extern bool nsbeos_done;
extern bool replicated;
int gui_init_replicant(int argc, char** argv);
-extern "C" void gui_401login_open(struct nsurl *url, const char *realm, nserror (*cb)(bool proceed, void *pw), void *cbpw);
+extern "C" void nserror gui_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);
extern "C" void nsbeos_gui_poll(void);
diff --git a/frontends/beos/login.cpp b/frontends/beos/login.cpp
index 85062987c..b7e20edf5 100644
--- a/frontends/beos/login.cpp
+++ b/frontends/beos/login.cpp
@@ -44,7 +44,9 @@ extern "C" {
class LoginAlert : public BAlert {
public:
- LoginAlert(nserror (*callback)(bool proceed, void *pw),
+ LoginAlert(nserror (*callback)(const char *username,
+ const char *password,
+ void *pw),
void *callbaclpw,
nsurl *url,
const char *host,
@@ -57,7 +59,9 @@ private:
nsurl* fUrl; /**< URL being fetched */
BString fHost; /**< Host for user display */
BString fRealm; /**< Authentication realm */
- nserror (*fCallback)(bool proceed, void *pw);
+ nserror (*fCallback)(const char *username,
+ const char *password,
+ void *pw);
void *fCallbackPw;
BTextControl *fUserControl;
@@ -66,13 +70,17 @@ private:
static void create_login_window(nsurl *host,
lwc_string *realm, const char *fetchurl,
- nserror (*cb)(bool proceed, void *pw), void *cbpw);
+ nserror (*cb)(const char *username,
+ const char *password,
+ void *pw), void *cbpw);
#define TC_H 25
#define TC_MARGIN 10
-LoginAlert::LoginAlert(nserror (*callback)(bool proceed, void *pw),
+LoginAlert::LoginAlert(nserror (*callback)(const char *username,
+ const char *password,
+ void *pw),
void *callbackpw,
nsurl *url,
const char *host,
@@ -164,8 +172,12 @@ LoginAlert::MessageReceived(BMessage *message)
}
-extern "C" void gui_401login_open(nsurl *url, const char *realm,
- nserror (*cb)(bool proceed, void *pw), void *cbpw)
+extern "C" nserror gui_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)
{
lwc_string *host;
@@ -174,12 +186,17 @@ extern "C" void gui_401login_open(nsurl *url, const char *realm,
create_login_window(url, host, realm, cb, cbpw);
free(host);
+
+ return NSERROR_OK;
}
//void create_login_window(struct browser_window *bw, const char *host,
// const char *realm, const char *fetchurl)
static void create_login_window(nsurl *url, lwc_string *host,
- const char *realm, nserror (*cb)(bool proceed, void *pw),
+ const char *realm, nserror (*cb)(
+ const char *username,
+ const char *password,
+ void *pw),
void *cbpw)
{
BString r("Secure Area");
diff --git a/frontends/beos/window.cpp b/frontends/beos/window.cpp
index f4229207b..49d049c28 100644
--- a/frontends/beos/window.cpp
+++ b/frontends/beos/window.cpp
@@ -655,23 +655,26 @@ void nsbeos_dispatch_event(BMessage *message)
{
nsurl* url;
BString realm;
- BString auth;
+ BString username;
+ BString password;
void* cbpw;
- nserror (*cb)(bool proceed, void* pw);
+ nserror (*cb)(const char *username,
+ const char *password,
+ void *pw);
if (message->FindPointer("URL", (void**)&url) < B_OK)
break;
if (message->FindString("Realm", &realm) < B_OK)
break;
- if (message->FindString("Auth", &auth) < B_OK)
+ if (message->FindString("User", &username) < B_OK)
+ break;
+ if (message->FindString("Pass", &password) < B_OK)
break;
if (message->FindPointer("callback", (void**)&cb) < B_OK)
break;
if (message->FindPointer("callback_pw", (void**)&cbpw) < B_OK)
break;
- //printf("login to '%s' with '%s'\n", url.String(), auth.String());
- urldb_set_auth_details(url, realm.String(), auth.String());
- cb(true, cbpw);
+ cb(username.String(), password.String(), cbpw);
break;
}
default:
diff --git a/frontends/gtk/login.c b/frontends/gtk/login.c
index 91d8b37f0..83253a5d3 100644
--- a/frontends/gtk/login.c
+++ b/frontends/gtk/login.c
@@ -32,7 +32,9 @@ struct session_401 {
nsurl *url; /**< URL being fetched */
lwc_string *host; /**< Host for user display */
char *realm; /**< Authentication realm */
- nserror (*cb)(bool proceed, void *pw); /**< Continuation callback */
+ nserror (*cb)(const char *username,
+ const char *password,
+ void *pw); /**< Continuation callback */
void *cbpw; /**< Continuation data */
GtkBuilder *x; /**< Our builder windows */
GtkWindow *wnd; /**< The login window itself */
@@ -83,14 +85,8 @@ static void nsgtk_login_ok_clicked(GtkButton *w, gpointer data)
struct session_401 *session = (struct session_401 *)data;
const gchar *user = gtk_entry_get_text(session->user);
const gchar *pass = gtk_entry_get_text(session->pass);
- char *auth;
- auth = malloc(strlen(user) + strlen(pass) + 2);
- sprintf(auth, "%s:%s", user, pass);
- urldb_set_auth_details(session->url, session->realm, auth);
- free(auth);
-
- session->cb(true, session->cbpw);
+ session->cb(user, pass, session->cbpw);
destroy_login_window(session);
}
@@ -106,7 +102,7 @@ static void nsgtk_login_cancel_clicked(GtkButton *w, gpointer data)
{
struct session_401 *session = (struct session_401 *) data;
- session->cb(false, session->cbpw);
+ session->cb(NULL, NULL, session->cbpw);
/* close and destroy the window */
destroy_login_window(session);
@@ -128,10 +124,12 @@ static void nsgtk_login_cancel_clicked(GtkButton *w, gpointer data)
*/
static nserror
create_login_window(nsurl *url,
- lwc_string *host,
- const char *realm,
- nserror (*cb)(bool proceed, void *pw),
- void *cbpw)
+ lwc_string *host, const char *realm,
+ const char *username, const char *password,
+ nserror (*cb)(const char *username,
+ const char *password,
+ void *pw),
+ void *cbpw)
{
struct session_401 *session;
GtkWindow *wnd;
@@ -177,8 +175,8 @@ create_login_window(nsurl *url,
gtk_label_set_text(GTK_LABEL(lhost), lwc_string_data(host));
gtk_label_set_text(lrealm, realm);
- gtk_entry_set_text(euser, "");
- gtk_entry_set_text(epass, "");
+ gtk_entry_set_text(euser, username);
+ gtk_entry_set_text(epass, password);
/* attach signal handlers to the Login and Cancel buttons in our new
* window to call functions in this file to process the login
@@ -209,10 +207,12 @@ create_login_window(nsurl *url,
/* exported function documented in gtk/login.h */
-void gui_401login_open(nsurl *url,
- const char *realm,
- nserror (*cb)(bool proceed, void *pw),
- void *cbpw)
+nserror gui_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)
{
lwc_string *host;
nserror res;
@@ -220,13 +220,15 @@ void gui_401login_open(nsurl *url,
host = nsurl_get_component(url, NSURL_HOST);
assert(host != NULL);
- res = create_login_window(url, host, realm, cb, cbpw);
+ res = create_login_window(url, host, realm, username, password,
+ cb, cbpw);
if (res != NSERROR_OK) {
NSLOG(netsurf, INFO, "Login init failed");
- /* creating login failed so cancel navigation */
- cb(false, cbpw);
+ return res;
}
lwc_string_unref(host);
+
+ return NSERROR_OK;
}
diff --git a/frontends/gtk/login.h b/frontends/gtk/login.h
index 00c29000c..1be1b4c29 100644
--- a/frontends/gtk/login.h
+++ b/frontends/gtk/login.h
@@ -26,6 +26,11 @@
/**
* login window request.
*/
-extern void gui_401login_open(struct nsurl *url, const char *realm, nserror (*cb)(bool proceed, void *pw), void *cbpw);
+extern nserror gui_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);
#endif
diff --git a/frontends/monkey/401login.c b/frontends/monkey/401login.c
index 090f18984..58335dd7b 100644
--- a/frontends/monkey/401login.c
+++ b/frontends/monkey/401login.c
@@ -27,20 +27,23 @@ typedef struct monkey401 {
struct monkey401 *r_next, *r_prev;
uint32_t num;
lwc_string *host; /* Ignore */
- nserror (*cb)(bool,void*);
+ nserror (*cb)(const char *, const char *, void *);
void *pw;
} monkey401_t;
static monkey401_t *m4_ring = NULL;
static uint32_t m4_ctr = 0;
-void gui_401login_open(nsurl *url, const char *realm,
- nserror (*cb)(bool proceed, void *pw), void *cbpw)
+nserror gui_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)
{
monkey401_t *m4t = calloc(sizeof(*m4t), 1);
if (m4t == NULL) {
- cb(false, cbpw);
- return;
+ return NSERROR_NOMEM;
}
m4t->cb = cb;
m4t->pw = cbpw;
@@ -50,6 +53,8 @@ void gui_401login_open(nsurl *url, const char *realm,
fprintf(stdout, "401LOGIN OPEN M4 %u URL %s REALM %s\n",
m4t->num, nsurl_access(url), realm);
+
+ return NSERROR_OK;
}
diff --git a/frontends/monkey/401login.h b/frontends/monkey/401login.h
index e78355ea2..93606e5b9 100644
--- a/frontends/monkey/401login.h
+++ b/frontends/monkey/401login.h
@@ -5,5 +5,9 @@
#include "utils/errors.h"
-void gui_401login_open(nsurl *url, const char *realm,
- nserror (*cb)(bool proceed, void *pw), void *cbpw);
+nserror gui_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);
diff --git a/frontends/riscos/401login.c b/frontends/riscos/401login.c
index 4b2deb16b..f14cdbbfb 100644
--- a/frontends/riscos/401login.c
+++ b/frontends/riscos/401login.c
@@ -43,7 +43,11 @@ static void ro_gui_401login_close(wimp_w w);
static bool ro_gui_401login_apply(wimp_w w);
static void ro_gui_401login_open(nsurl *url, lwc_string *host,
const char *realm,
- nserror (*cb)(bool proceed, void *pw), void *cbpw);
+ const char *username, const char *password,
+ nserror (*cb)(const char *username,
+ const char *password,
+ void *pw),
+ void *cbpw);
static wimp_window *dialog_401_template;
@@ -53,7 +57,9 @@ struct session_401 {
char uname[256]; /**< Buffer for username */
nsurl *url; /**< URL being fetched */
char pwd[256]; /**< Buffer for password */
- nserror (*cb)(bool proceed, void *pw); /**< Continuation callback */
+ nserror (*cb)(const char *username,
+ const char *password,
+ void *pw); /**< Continuation callback */
void *cbpw; /**< Continuation callback data */
};
@@ -72,12 +78,16 @@ void ro_gui_401login_init(void)
* Open the login dialog
*/
void gui_401login_open(nsurl *url, const char *realm,
- nserror (*cb)(bool proceed, void *pw), void *cbpw)
+ const char *username, const char *password,
+ nserror (*cb)(const char *username,
+ const char *password,
+ void *pw),
+ void *cbpw)
{
lwc_string *host = nsurl_get_component(url, NSURL_HOST);
assert(host != NULL);
- ro_gui_401login_open(url, host, realm, cb, cbpw);
+ ro_gui_401login_open(url, host, realm, username, password, cb, cbpw);
lwc_string_unref(host);
}
@@ -88,11 +98,19 @@ void gui_401login_open(nsurl *url, const char *realm,
*/
void ro_gui_401login_open(nsurl *url, lwc_string *host, const char *realm,
- nserror (*cb)(bool proceed, void *pw), void *cbpw)
+ const char *username, const char *password,
+ nserror (*cb)(const char *username,
+ const char *password,
+ void *pw),
+ void *cbpw)
{
struct session_401 *session;
+ size_t len;
wimp_w w;
- const char *auth;
+
+ assert(host != NULL);
+ assert(username != NULL);
+ assert(password != NULL);
session = calloc(1, sizeof(struct session_401));
if (!session) {
@@ -100,32 +118,23 @@ void ro_gui_401login_open(nsurl *url, lwc_string *host, const char *realm,
return;
}
- session->url = nsurl_ref(url);
if (realm == NULL)
realm = "Secure Area";
- auth = urldb_get_auth_details(session->url, realm);
- if (auth == NULL) {
- session->uname[0] = '\0';
- session->pwd[0] = '\0';
- } else {
- const char *pwd;
- size_t pwd_len;
-
- pwd = strchr(auth, ':');
- assert(pwd && pwd < auth + sizeof(session->uname));
- memcpy(session->uname, auth, pwd - auth);
- session->uname[pwd - auth] = '\0';
- ++pwd;
- pwd_len = strlen(pwd);
- assert(pwd_len < sizeof(session->pwd));
- memcpy(session->pwd, pwd, pwd_len);
- session->pwd[pwd_len] = '\0';
- }
+
+ session->url = nsurl_ref(url);
session->host = lwc_string_ref(host);
session->realm = strdup(realm);
session->cb = cb;
session->cbpw = cbpw;
+ len = strlen(username);
+ assert(len < sizeof(session->uname));
+ memcpy(session->uname, username, len + 1);
+
+ len = strlen(password);
+ assert(len < sizeof(session->pwd));
+ memcpy(session->pwd, password, len + 1);
+
if (!session->realm) {
nsurl_unref(session->url);
lwc_string_unref(session->host);
@@ -182,7 +191,7 @@ void ro_gui_401login_close(wimp_w w)
/* If ok didn't happen, send failure response */
if (session->cb != NULL)
- session->cb(false, session->cbpw);
+ session->cb(NULL, NULL, session->cbpw);
nsurl_unref(session->url);
lwc_string_unref(session->host);
@@ -205,26 +214,12 @@ void ro_gui_401login_close(wimp_w w)
bool ro_gui_401login_apply(wimp_w w)
{
struct session_401 *session;
- char *auth;
session = (struct session_401 *)ro_gui_wimp_event_get_user_data(w);
assert(session);
- auth = malloc(strlen(session->uname) + strlen(session->pwd) + 2);
- if (!auth) {
- NSLOG(netsurf, INFO, "calloc failed");
- ro_warn_user("NoMemory", 0);
- return false;
- }
-
- sprintf(auth, "%s:%s", session->uname, session->pwd);
-
- urldb_set_auth_details(session->url, session->realm, auth);
-
- free(auth);
-
- session->cb(true, session->cbpw);
+ session->cb(session->uname, session->pwd, session->cbpw);
/* Flag that we sent response by invalidating callback details */
session->cb = NULL;
diff --git a/frontends/riscos/gui.h b/frontends/riscos/gui.h
index 49a8ba417..b308c00c8 100644
--- a/frontends/riscos/gui.h
+++ b/frontends/riscos/gui.h
@@ -136,8 +136,12 @@ extern struct gui_download_table *riscos_download_table;
/* in 401login.c */
void ro_gui_401login_init(void);
-void gui_401login_open(struct nsurl *url, const char *realm,
- nserror (*cb)(bool proceed, void *pw), void *cbpw);
+void gui_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);
/* in schedule.c */
extern bool sched_active;
diff --git a/include/netsurf/misc.h b/include/netsurf/misc.h
index 2647b9a1c..cd86cf644 100644
--- a/include/netsurf/misc.h
+++ b/include/netsurf/misc.h
@@ -91,13 +91,40 @@ struct gui_misc_table {
* \param cbpw Context pointer passed to cb
* \return NSERROR_OK on sucess else error and cb never called
*/
- nserror (*cert_verify)(struct nsurl *url, const struct ssl_cert_info *certs, unsigned long num, nserror (*cb)(bool proceed, void *pw), void *cbpw);
+ nserror (*cert_verify)(struct nsurl *url,
+ const struct ssl_cert_info *certs,
+ unsigned long num,
+ nserror (*cb)(bool proceed, void *pw),
+ void *cbpw);
/**
* Prompt user for login
+ *
+ * To cancel a login, clients should call the `cb` callback passing
+ * NULL for username, and password. Otherwise, for logins, username
+ * and password should both be non-NULL. Pass "" if the empty string
+ * is required.
+ *
+ * If the front end returns NSERROR_OK for this function, they must,
+ * at some future time, call the `cb` with `cbpw` callback exactly once.
+ *
+ * If ther front end returns other than NSERROR_OK, they should not
+ * call the `cb` callback.
+ *
+ * \param url The URL being verified.
+ * \param realm The authorization realm.
+ * \param username Any current username (or empty string).
+ * \param password Any current password (or empty string).
+ * \param cb Callback upon user decision.
+ * \param cbpw Context pointer passed to cb
+ * \return NSERROR_OK on sucess else error and cb never called
*/
- void (*login)(struct nsurl *url, const char *realm,
- nserror (*cb)(bool proceed, void *pw), void *cbpw);
+ nserror (*login)(struct nsurl *url, const char *realm,
+ const char *username, const char *password,
+ nserror (*cb)(const char *username,
+ const char *password,
+ void *pw),
+ void *cbpw);
/**
* Prompt the user for a password for a PDF.
diff --git a/include/netsurf/url_db.h b/include/netsurf/url_db.h
index 217cf8fcd..071675652 100644
--- a/include/netsurf/url_db.h
+++ b/include/netsurf/url_db.h
@@ -58,27 +58,6 @@ nserror urldb_save(const char *filename);
/**
- * Set authentication data for an URL
- *
- * \param url The URL to consider
- * \param realm The authentication realm
- * \param auth The authentication details (in form username:password)
- */
-void urldb_set_auth_details(struct nsurl *url, const char *realm, const char *auth);
-
-
-/**
- * Look up authentication details in database
- *
- * \param url Absolute URL to search for
- * \param realm When non-NULL, it is realm which can be used to determine
- * the protection space when that's not been done before for given URL.
- * \return Pointer to authentication details, or NULL if not found
- */
-const char *urldb_get_auth_details(struct nsurl *url, const char *realm);
-
-
-/**
* Iterate over entries in the database which match the given prefix
*
* \param prefix Prefix to match