From 81a59f2f7c7cf06c1457893880ebfeba82e902cc Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Mon, 13 Aug 2018 16:50:17 +0100 Subject: HTTP Auth: Do get/set auth in the core. --- desktop/gui_factory.c | 10 ++- desktop/netsurf.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++++- include/netsurf/misc.h | 33 ++++++++- 3 files changed, 231 insertions(+), 10 deletions(-) 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" @@ -93,6 +94,198 @@ 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) { + 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 * @@ -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/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. -- cgit v1.2.3 From 42d596bc11d920f953a8d19a46981cb359cf9144 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Mon, 13 Aug 2018 16:51:09 +0100 Subject: Amiga: Update for new HTTP auth API. --- frontends/amiga/login.c | 52 +++++++++++++++++++++---------------------------- frontends/amiga/login.h | 8 ++++++-- 2 files changed, 28 insertions(+), 32 deletions(-) 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 -- cgit v1.2.3 From 6144993c8a9e93332c47e9b57da190ad57ac28fb Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Mon, 13 Aug 2018 16:51:27 +0100 Subject: GTK: Update for new HTTP auth API. --- frontends/gtk/login.c | 46 ++++++++++++++++++++++++---------------------- frontends/gtk/login.h | 7 ++++++- 2 files changed, 30 insertions(+), 23 deletions(-) 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 -- cgit v1.2.3 From e41e558c5faeac4c9619362ac441f0e0ac831d25 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Mon, 13 Aug 2018 17:43:41 +0100 Subject: Haiku: Update for new HTTP auth API. --- frontends/beos/gui.h | 7 ++++++- frontends/beos/login.cpp | 31 ++++++++++++++++++++++++------- frontends/beos/window.cpp | 15 +++++++++------ 3 files changed, 39 insertions(+), 14 deletions(-) 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: -- cgit v1.2.3 From 97810d0c1aeab995d0b27c976c8d3e9e1a0c8b3f Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Mon, 13 Aug 2018 17:52:44 +0100 Subject: Monkey: Update for new HTTP auth API. --- frontends/monkey/401login.c | 15 ++++++++++----- frontends/monkey/401login.h | 8 ++++++-- 2 files changed, 16 insertions(+), 7 deletions(-) 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); -- cgit v1.2.3 From c55a31aa110cd5f469a7758f63c0f0dbb26da2c9 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Tue, 14 Aug 2018 11:15:44 +0100 Subject: RISC OS: Update to new HTTP auth API. --- frontends/riscos/401login.c | 77 +++++++++++++++++++++------------------------ frontends/riscos/gui.h | 8 +++-- 2 files changed, 42 insertions(+), 43 deletions(-) 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; -- cgit v1.2.3 From 66a97b863ce450bb0932ea4813b81c9b62d84b83 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Tue, 14 Aug 2018 11:34:30 +0100 Subject: Atari: Move to new HTTP auth API. --- frontends/atari/gui.c | 39 +++++++++++++++++++++++---------------- frontends/atari/login.c | 18 ++++++++++++------ frontends/atari/login.h | 2 +- 3 files changed, 36 insertions(+), 23 deletions(-) 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 -- cgit v1.2.3 From 5e97a3cb26e99ceac27f95be7a7527c630910ebf Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Tue, 14 Aug 2018 11:40:34 +0100 Subject: API: Don't expose urldb_{g|s}et_auth_details to frontends. --- content/urldb.h | 21 +++++++++++++++++++++ include/netsurf/url_db.h | 21 --------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/content/urldb.h b/content/urldb.h index 0ad64267f..c68c2a611 100644 --- a/content/urldb.h +++ b/content/urldb.h @@ -74,6 +74,27 @@ nserror urldb_set_url_title(struct nsurl *url, const char *title); 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 * 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 @@ -57,27 +57,6 @@ nserror urldb_load(const char *filename); 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 * -- cgit v1.2.3