capabilities support
This commit is contained in:
parent
af7f943e05
commit
156363f3de
8 changed files with 91 additions and 0 deletions
|
@ -495,6 +495,9 @@ CHECK_INCLUDE_FILE(sys/stat.h LWS_HAVE_SYS_STAT_H)
|
||||||
CHECK_INCLUDE_FILE(sys/types.h LWS_HAVE_SYS_TYPES_H)
|
CHECK_INCLUDE_FILE(sys/types.h LWS_HAVE_SYS_TYPES_H)
|
||||||
CHECK_INCLUDE_FILE(unistd.h LWS_HAVE_UNISTD_H)
|
CHECK_INCLUDE_FILE(unistd.h LWS_HAVE_UNISTD_H)
|
||||||
CHECK_INCLUDE_FILE(vfork.h LWS_HAVE_VFORK_H)
|
CHECK_INCLUDE_FILE(vfork.h LWS_HAVE_VFORK_H)
|
||||||
|
CHECK_INCLUDE_FILE(sys/capability.h LWS_HAVE_SYS_CAPABILITY_H)
|
||||||
|
|
||||||
|
CHECK_LIBRARY_EXISTS(cap cap_set_flag "" LWS_HAVE_LIBCAP)
|
||||||
|
|
||||||
if (LWS_WITH_LIBUV)
|
if (LWS_WITH_LIBUV)
|
||||||
CHECK_INCLUDE_FILE(uv-version.h LWS_HAVE_UV_VERSION_H)
|
CHECK_INCLUDE_FILE(uv-version.h LWS_HAVE_UV_VERSION_H)
|
||||||
|
@ -1016,6 +1019,12 @@ if (UNIX)
|
||||||
list(APPEND LIB_LIST m)
|
list(APPEND LIB_LIST m)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (LWS_HAVE_LIBCAP)
|
||||||
|
list(APPEND LIB_LIST cap )
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Setup the linking for all libs.
|
# Setup the linking for all libs.
|
||||||
foreach (lib ${LWS_LIBRARIES})
|
foreach (lib ${LWS_LIBRARIES})
|
||||||
target_link_libraries(${lib} ${LIB_LIST})
|
target_link_libraries(${lib} ${LIB_LIST})
|
||||||
|
@ -1767,6 +1776,8 @@ message(" LWS_WITH_ZIP_FOPS = ${LWS_WITH_ZIP_FOPS}")
|
||||||
message(" LWS_AVOID_SIGPIPE_IGN = ${LWS_AVOID_SIGPIPE_IGN}")
|
message(" LWS_AVOID_SIGPIPE_IGN = ${LWS_AVOID_SIGPIPE_IGN}")
|
||||||
message(" LWS_WITH_STATS = ${LWS_WITH_STATS}")
|
message(" LWS_WITH_STATS = ${LWS_WITH_STATS}")
|
||||||
message(" LWS_WITH_SOCKS5 = ${LWS_WITH_SOCKS5}")
|
message(" LWS_WITH_SOCKS5 = ${LWS_WITH_SOCKS5}")
|
||||||
|
message(" LWS_HAVE_SYS_CAPABILITY_H = ${LWS_HAVE_SYS_CAPABILITY_H}")
|
||||||
|
message(" LWS_HAVE_LIBCAP = ${LWS_HAVE_LIBCAP}")
|
||||||
|
|
||||||
message("---------------------------------------------------------------------")
|
message("---------------------------------------------------------------------")
|
||||||
|
|
||||||
|
|
|
@ -122,12 +122,25 @@ and libnsl, and only builds in 64bit mode.
|
||||||
$ make
|
$ make
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@section lcap Linux Capabilities
|
||||||
|
|
||||||
|
On Linux, lws now lets you retain selected root capabilities when dropping
|
||||||
|
privileges. If libcap-dev or similar package is installed providing
|
||||||
|
sys/capabilities.h, and libcap or similar package is installed providing
|
||||||
|
libcap.so, CMake will enable the capability features.
|
||||||
|
|
||||||
|
The context creation info struct .caps[] and .count_caps members can then
|
||||||
|
be set by user code to enable selected root capabilities to survive the
|
||||||
|
transition to running under an unprivileged user.
|
||||||
|
|
||||||
@section cmq Quirk of cmake
|
@section cmq Quirk of cmake
|
||||||
|
|
||||||
When changing cmake options, for some reason the only way to get it to see the
|
When changing cmake options, for some reason the only way to get it to see the
|
||||||
changes sometimes is delete the contents of your build directory and do the
|
changes sometimes is delete the contents of your build directory and do the
|
||||||
cmake from scratch.
|
cmake from scratch.
|
||||||
|
|
||||||
|
deleting build/CMakeCache.txt may be enough.
|
||||||
|
|
||||||
|
|
||||||
@section cmw Building on Windows (Visual Studio)
|
@section cmw Building on Windows (Visual Studio)
|
||||||
|
|
||||||
|
|
|
@ -892,6 +892,11 @@ lws_create_context(struct lws_context_creation_info *info)
|
||||||
context->uid = info->uid;
|
context->uid = info->uid;
|
||||||
context->gid = info->gid;
|
context->gid = info->gid;
|
||||||
|
|
||||||
|
#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
|
||||||
|
memcpy(context->caps, info->caps, sizeof(context->caps));
|
||||||
|
context->count_caps = info->count_caps;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* drop any root privs for this process
|
* drop any root privs for this process
|
||||||
* to listen on port < 1023 we would have needed root, but now we are
|
* to listen on port < 1023 we would have needed root, but now we are
|
||||||
|
|
|
@ -2220,6 +2220,11 @@ lws_finalize_startup(struct lws_context *context)
|
||||||
info.uid = context->uid;
|
info.uid = context->uid;
|
||||||
info.gid = context->gid;
|
info.gid = context->gid;
|
||||||
|
|
||||||
|
#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
|
||||||
|
memcpy(info.caps, context->caps, sizeof(info.caps));
|
||||||
|
info.count_caps = context->count_caps;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (lws_check_opt(context->options, LWS_SERVER_OPTION_EXPLICIT_VHOSTS))
|
if (lws_check_opt(context->options, LWS_SERVER_OPTION_EXPLICIT_VHOSTS))
|
||||||
lws_plat_drop_app_privileges(&info);
|
lws_plat_drop_app_privileges(&info);
|
||||||
|
|
||||||
|
|
|
@ -102,6 +102,9 @@ struct sockaddr_in;
|
||||||
|
|
||||||
#else /* NOT WIN32 */
|
#else /* NOT WIN32 */
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
|
||||||
|
#include <sys/capability.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__NetBSD__) || defined(__FreeBSD__)
|
#if defined(__NetBSD__) || defined(__FreeBSD__)
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
@ -1976,6 +1979,18 @@ struct lws_context_creation_info {
|
||||||
* If proxy auth is required, use format "username:password\@server:port" */
|
* If proxy auth is required, use format "username:password\@server:port" */
|
||||||
unsigned int socks_proxy_port;
|
unsigned int socks_proxy_port;
|
||||||
/**< VHOST: If socks_proxy_address was non-NULL, uses this port */
|
/**< VHOST: If socks_proxy_address was non-NULL, uses this port */
|
||||||
|
#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
|
||||||
|
cap_value_t caps[4];
|
||||||
|
/**< CONTEXT: array holding Linux capabilities you want to
|
||||||
|
* continue to be available to the server after it transitions
|
||||||
|
* to a noprivileged user. Usually none are needed but for, eg,
|
||||||
|
* .bind_iface, CAP_NET_RAW is required. This gives you a way
|
||||||
|
* to still have the capability but drop root.
|
||||||
|
*/
|
||||||
|
char count_caps;
|
||||||
|
/**< CONTEXT: count of Linux capabilities in .caps[]. 0 means
|
||||||
|
* no capabilities will be inherited from root (the default) */
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Add new things just above here ---^
|
/* Add new things just above here ---^
|
||||||
* This is part of the ABI, don't needlessly break compatibility
|
* This is part of the ABI, don't needlessly break compatibility
|
||||||
|
|
|
@ -279,9 +279,29 @@ lws_plat_set_socket_options(struct lws_vhost *vhost, int fd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
|
||||||
|
static void
|
||||||
|
_lws_plat_apply_caps(int mode, cap_value_t *cv, int count)
|
||||||
|
{
|
||||||
|
cap_t caps = cap_get_proc();
|
||||||
|
|
||||||
|
if (!count)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cap_set_flag(caps, mode, count, cv, CAP_SET);
|
||||||
|
cap_set_proc(caps);
|
||||||
|
prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
|
||||||
|
cap_free(caps);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
LWS_VISIBLE void
|
LWS_VISIBLE void
|
||||||
lws_plat_drop_app_privileges(struct lws_context_creation_info *info)
|
lws_plat_drop_app_privileges(struct lws_context_creation_info *info)
|
||||||
{
|
{
|
||||||
|
#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
|
||||||
|
int n;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (info->gid != -1)
|
if (info->gid != -1)
|
||||||
if (setgid(info->gid))
|
if (setgid(info->gid))
|
||||||
lwsl_warn("setgid: %s\n", strerror(LWS_ERRNO));
|
lwsl_warn("setgid: %s\n", strerror(LWS_ERRNO));
|
||||||
|
@ -290,11 +310,25 @@ lws_plat_drop_app_privileges(struct lws_context_creation_info *info)
|
||||||
struct passwd *p = getpwuid(info->uid);
|
struct passwd *p = getpwuid(info->uid);
|
||||||
|
|
||||||
if (p) {
|
if (p) {
|
||||||
|
|
||||||
|
#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
|
||||||
|
_lws_plat_apply_caps(CAP_PERMITTED, info->caps, info->count_caps);
|
||||||
|
#endif
|
||||||
|
|
||||||
initgroups(p->pw_name, info->gid);
|
initgroups(p->pw_name, info->gid);
|
||||||
if (setuid(info->uid))
|
if (setuid(info->uid))
|
||||||
lwsl_warn("setuid: %s\n", strerror(LWS_ERRNO));
|
lwsl_warn("setuid: %s\n", strerror(LWS_ERRNO));
|
||||||
else
|
else
|
||||||
lwsl_notice("Set privs to user '%s'\n", p->pw_name);
|
lwsl_notice("Set privs to user '%s'\n", p->pw_name);
|
||||||
|
|
||||||
|
#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
|
||||||
|
_lws_plat_apply_caps(CAP_EFFECTIVE, info->caps, info->count_caps);
|
||||||
|
|
||||||
|
if (info->count_caps)
|
||||||
|
for (n = 0; n < info->count_caps; n++)
|
||||||
|
lwsl_notice(" RETAINING CAPABILITY %d\n", (int)info->caps[n]);
|
||||||
|
#endif
|
||||||
|
|
||||||
} else
|
} else
|
||||||
lwsl_warn("getpwuid: unable to find uid %d", info->uid);
|
lwsl_warn("getpwuid: unable to find uid %d", info->uid);
|
||||||
}
|
}
|
||||||
|
|
|
@ -935,6 +935,11 @@ struct lws_context {
|
||||||
const struct lws_protocol_vhost_options *reject_service_keywords;
|
const struct lws_protocol_vhost_options *reject_service_keywords;
|
||||||
lws_reload_func deprecation_cb;
|
lws_reload_func deprecation_cb;
|
||||||
|
|
||||||
|
#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP)
|
||||||
|
cap_value_t caps[4];
|
||||||
|
char count_caps;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(LWS_USE_LIBEV)
|
#if defined(LWS_USE_LIBEV)
|
||||||
lws_ev_signal_cb_t * lws_ev_sigint_cb;
|
lws_ev_signal_cb_t * lws_ev_sigint_cb;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -136,6 +136,9 @@
|
||||||
#cmakedefine LWS_WITH_STATS
|
#cmakedefine LWS_WITH_STATS
|
||||||
#cmakedefine LWS_WITH_SOCKS5
|
#cmakedefine LWS_WITH_SOCKS5
|
||||||
|
|
||||||
|
#cmakedefine LWS_HAVE_SYS_CAPABILITY_H
|
||||||
|
#cmakedefine LWS_HAVE_LIBCAP
|
||||||
|
|
||||||
/* OpenSSL various APIs */
|
/* OpenSSL various APIs */
|
||||||
|
|
||||||
#cmakedefine LWS_HAVE_TLS_CLIENT_METHOD
|
#cmakedefine LWS_HAVE_TLS_CLIENT_METHOD
|
||||||
|
|
Loading…
Add table
Reference in a new issue