mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
basic auth: add callback option
Allow an http mount to specify it wants to check Basic Auth requests via a protocol callback instead of a text file.
This commit is contained in:
parent
6879574d8d
commit
10290048b0
5 changed files with 49 additions and 12 deletions
|
@ -280,6 +280,15 @@ enum lws_callback_reasons {
|
|||
* break;
|
||||
*/
|
||||
|
||||
LWS_CALLBACK_VERIFY_BASIC_AUTHORIZATION = 102,
|
||||
/**< This gives the user code a chance to accept or reject credentials
|
||||
* provided HTTP to basic authorization. It will only be called if the
|
||||
* http mount's authentication_mode is set to LWSAUTHM_BASIC_AUTH_CALLBACK
|
||||
* `in` points to a credential string of the form `username:password` If
|
||||
* the callback returns zero (the default if unhandled), then the
|
||||
* transaction ends with HTTP_STATUS_UNAUTHORIZED, otherwise the request
|
||||
* will be processed */
|
||||
|
||||
LWS_CALLBACK_CHECK_ACCESS_RIGHTS = 51,
|
||||
/**< This gives the user code a chance to forbid an http access.
|
||||
* `in` points to a `struct lws_process_html_args`, which
|
||||
|
|
|
@ -1040,6 +1040,18 @@ enum lws_mount_protocols {
|
|||
LWSMPRO_CALLBACK = 6, /**< hand by named protocol's callback */
|
||||
};
|
||||
|
||||
/** enum lws_authentication_mode
|
||||
* This specifies the authentication mode of the mount. The basic_auth_login_file mount parameter
|
||||
* is ignored unless LWSAUTHM_DEFAULT is set.
|
||||
*/
|
||||
enum lws_authentication_mode {
|
||||
LWSAUTHM_DEFAULT = 0, /**< default authenticate only if basic_auth_login_file is provided */
|
||||
LWSAUTHM_BASIC_AUTH_CALLBACK = 1 << 28 /**< Basic auth with a custom verifier */
|
||||
};
|
||||
|
||||
/** The authentication mode is stored in the top 4 bits of lws_http_mount.auth_mask */
|
||||
#define AUTH_MODE_MASK 0xF0000000
|
||||
|
||||
/** struct lws_http_mount
|
||||
*
|
||||
* arguments for mounting something in a vhost's url namespace
|
||||
|
@ -1080,7 +1092,7 @@ struct lws_http_mount {
|
|||
unsigned char mountpoint_len; /**< length of mountpoint string */
|
||||
|
||||
const char *basic_auth_login_file;
|
||||
/**<NULL, or filepath to use to check basic auth logins against */
|
||||
/**<NULL, or filepath to use to check basic auth logins against. (requires LWSAUTHM_DEFAULT) */
|
||||
|
||||
/* Add new things just above here ---^
|
||||
* This is part of the ABI, don't needlessly break compatibility
|
||||
|
|
|
@ -300,7 +300,7 @@ enum lws_check_basic_auth_results {
|
|||
};
|
||||
|
||||
enum lws_check_basic_auth_results
|
||||
lws_check_basic_auth(struct lws *wsi, const char *basic_auth_login_file);
|
||||
lws_check_basic_auth(struct lws *wsi, const char *basic_auth_login_file, unsigned int auth_mode);
|
||||
|
||||
int
|
||||
lws_unauthorised_basic_auth(struct lws *wsi);
|
||||
|
|
|
@ -946,16 +946,15 @@ lws_http_get_uri_and_method(struct lws *wsi, char **puri_ptr, int *puri_len)
|
|||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
enum lws_check_basic_auth_results
|
||||
lws_check_basic_auth(struct lws *wsi, const char *basic_auth_login_file)
|
||||
lws_check_basic_auth(struct lws *wsi, const char *basic_auth_login_file,
|
||||
unsigned int auth_mode)
|
||||
{
|
||||
#if defined(LWS_WITH_FILE_OPS)
|
||||
char b64[160], plain[(sizeof(b64) * 3) / 4], *pcolon;
|
||||
int m, ml, fi;
|
||||
int m, ml, fi, bar;
|
||||
|
||||
if (!basic_auth_login_file)
|
||||
if (!basic_auth_login_file && auth_mode == LWSAUTHM_DEFAULT)
|
||||
return LCBA_CONTINUE;
|
||||
|
||||
/* Did he send auth? */
|
||||
|
@ -998,8 +997,23 @@ lws_check_basic_auth(struct lws *wsi, const char *basic_auth_login_file)
|
|||
lwsl_err("basic auth format broken\n");
|
||||
return LCBA_END_TRANSACTION;
|
||||
}
|
||||
if (!lws_find_string_in_file(basic_auth_login_file, plain, m)) {
|
||||
lwsl_err("basic auth lookup failed\n");
|
||||
|
||||
switch (auth_mode) {
|
||||
case LWSAUTHM_DEFAULT:
|
||||
if (lws_find_string_in_file(basic_auth_login_file, plain, m))
|
||||
break;
|
||||
lwsl_err("%s: basic auth lookup failed\n", __func__);
|
||||
return LCBA_FAILED_AUTH;
|
||||
|
||||
case LWSAUTHM_BASIC_AUTH_CALLBACK:
|
||||
bar = wsi->protocol->callback(wsi,
|
||||
LWS_CALLBACK_VERIFY_BASIC_AUTHORIZATION,
|
||||
wsi->user_space, plain, m);
|
||||
if (!bar)
|
||||
return LCBA_FAILED_AUTH;
|
||||
break;
|
||||
default:
|
||||
/* Invalid auth mode so lets fail all authentication attempts */
|
||||
return LCBA_FAILED_AUTH;
|
||||
}
|
||||
|
||||
|
@ -1468,7 +1482,8 @@ lws_http_action(struct lws *wsi)
|
|||
|
||||
/* basic auth? */
|
||||
|
||||
switch(lws_check_basic_auth(wsi, hit->basic_auth_login_file)) {
|
||||
switch (lws_check_basic_auth(wsi, hit->basic_auth_login_file,
|
||||
hit->auth_mask & AUTH_MODE_MASK)) {
|
||||
case LCBA_CONTINUE:
|
||||
break;
|
||||
case LCBA_FAILED_AUTH:
|
||||
|
@ -1527,7 +1542,7 @@ lws_http_action(struct lws *wsi)
|
|||
|
||||
args.p = uri_ptr;
|
||||
args.len = uri_len;
|
||||
args.max_len = hit->auth_mask;
|
||||
args.max_len = hit->auth_mask & ~AUTH_MODE_MASK;
|
||||
args.final = 0; /* used to signal callback dealt with it */
|
||||
args.chunked = 0;
|
||||
|
||||
|
|
|
@ -271,7 +271,8 @@ lws_process_ws_upgrade2(struct lws *wsi)
|
|||
!lws_pvo_get_str((void *)pvos->options, "basic-auth",
|
||||
&ws_prot_basic_auth)) {
|
||||
lwsl_info("%s: ws upgrade requires basic auth\n", __func__);
|
||||
switch(lws_check_basic_auth(wsi, ws_prot_basic_auth)) {
|
||||
switch (lws_check_basic_auth(wsi, ws_prot_basic_auth, LWSAUTHM_DEFAULT
|
||||
/* no callback based auth here */)) {
|
||||
case LCBA_CONTINUE:
|
||||
break;
|
||||
case LCBA_FAILED_AUTH:
|
||||
|
|
Loading…
Add table
Reference in a new issue