mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-23 20:46:50 +03:00
HTTP Auth: Do get/set auth in the core.
This commit is contained in:
parent
9fa6c1e0fb
commit
81a59f2f7c
@ -679,10 +679,14 @@ static nserror gui_default_cert_verify(nsurl *url,
|
|||||||
return NSERROR_NOT_IMPLEMENTED;
|
return NSERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gui_default_401login_open(nsurl *url, const char *realm,
|
static nserror gui_default_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)
|
||||||
{
|
{
|
||||||
cb(false, cbpw);
|
return NSERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "utils/nsoption.h"
|
#include "utils/nsoption.h"
|
||||||
#include "utils/corestrings.h"
|
#include "utils/corestrings.h"
|
||||||
#include "utils/log.h"
|
#include "utils/log.h"
|
||||||
|
#include "utils/string.h"
|
||||||
#include "utils/utf8.h"
|
#include "utils/utf8.h"
|
||||||
#include "utils/messages.h"
|
#include "utils/messages.h"
|
||||||
#include "content/content_factory.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));
|
(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
|
* 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) {
|
switch (query->type) {
|
||||||
case LLCACHE_QUERY_AUTH:
|
case LLCACHE_QUERY_AUTH:
|
||||||
NSLOG(llcache, INFO, "HTTP Auth for: %s: %s",
|
res = netsurf__handle_login(query, pw, cb, cbpw);
|
||||||
query->data.auth.realm,
|
|
||||||
nsurl_access(query->url));
|
|
||||||
guit->misc->login(query->url, query->data.auth.realm, cb, cbpw);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LLCACHE_QUERY_REDIRECT:
|
case LLCACHE_QUERY_REDIRECT:
|
||||||
|
@ -91,13 +91,40 @@ struct gui_misc_table {
|
|||||||
* \param cbpw Context pointer passed to cb
|
* \param cbpw Context pointer passed to cb
|
||||||
* \return NSERROR_OK on sucess else error and cb never called
|
* \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
|
* 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 (*login)(struct 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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prompt the user for a password for a PDF.
|
* Prompt the user for a password for a PDF.
|
||||||
|
Loading…
Reference in New Issue
Block a user