diff --git a/include/libwebsockets/lws-callbacks.h b/include/libwebsockets/lws-callbacks.h index a31ab74cd..5a61e4c31 100644 --- a/include/libwebsockets/lws-callbacks.h +++ b/include/libwebsockets/lws-callbacks.h @@ -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 diff --git a/include/libwebsockets/lws-context-vhost.h b/include/libwebsockets/lws-context-vhost.h index 5574c7728..fa93a59df 100644 --- a/include/libwebsockets/lws-context-vhost.h +++ b/include/libwebsockets/lws-context-vhost.h @@ -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; - /**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; diff --git a/lib/roles/ws/server-ws.c b/lib/roles/ws/server-ws.c index 2006c3f76..3f1813aa5 100644 --- a/lib/roles/ws/server-ws.c +++ b/lib/roles/ws/server-ws.c @@ -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: