summaryrefslogtreecommitdiff
path: root/desktop/netsurf.c
diff options
context:
space:
mode:
authorMichael Drake <michael.drake@codethink.co.uk>2018-08-13 16:50:17 +0100
committerMichael Drake <tlsa@netsurf-browser.org>2018-08-14 18:52:11 +0100
commit81a59f2f7c7cf06c1457893880ebfeba82e902cc (patch)
treef6f41992fa64e49f0777a2df33e232f8a0809a3e /desktop/netsurf.c
parent9fa6c1e0fb2d6f5a0c95e7680b0ad24f9f7615db (diff)
downloadnetsurf-81a59f2f7c7cf06c1457893880ebfeba82e902cc.tar.gz
netsurf-81a59f2f7c7cf06c1457893880ebfeba82e902cc.tar.bz2
HTTP Auth: Do get/set auth in the core.
Diffstat (limited to 'desktop/netsurf.c')
-rw-r--r--desktop/netsurf.c198
1 files changed, 194 insertions, 4 deletions
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: