-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add xrdp-chkpriv script to check xrdp privileges
- Loading branch information
1 parent
ce355fc
commit 48255da
Showing
7 changed files
with
301 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
|
||
SUBDIRS = \ | ||
chkpriv \ | ||
devel |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
xrdppkgdatadir=$(datadir)/xrdp | ||
|
||
pkglibexec_PROGRAMS = \ | ||
xrdp-droppriv | ||
|
||
dist_xrdppkgdata_SCRIPTS = \ | ||
xrdp-chkpriv | ||
|
||
AM_LDFLAGS = | ||
|
||
AM_CPPFLAGS = \ | ||
-I$(top_srcdir)/common | ||
|
||
xrdp_droppriv_SOURCES = xrdp-droppriv.c | ||
|
||
xrdp_droppriv_LDADD = \ | ||
$(top_builddir)/common/libcommon.la | ||
|
||
SUBST_VARS = sed \ | ||
-e 's|@pkglibexecdir[@]|$(pkglibexecdir)|g' | ||
|
||
subst_verbose = $(subst_verbose_@AM_V@) | ||
subst_verbose_ = $(subst_verbose_@AM_DEFAULT_V@) | ||
subst_verbose_0 = @echo " SUBST $@"; | ||
|
||
SUFFIXES = .in | ||
.in: | ||
$(subst_verbose)$(SUBST_VARS) $< > $@ | ||
|
||
CLEANFILES = xrdp-chkpriv | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
#!/bin/sh | ||
# | ||
# xrdp: A Remote Desktop Protocol server. | ||
# | ||
# Copyright (C) Jay Sorg and contributors 2004-2024 | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
# Program to check permissions for xrdp when running in a non-privileged | ||
# mode | ||
|
||
# Change these if they do not match your installation | ||
CONF_DIR=/etc/xrdp | ||
XRDP_INI="$CONF_DIR"/xrdp.ini | ||
SESMAN_INI="$CONF_DIR"/sesman.ini | ||
RSAKEYS_INI="$CONF_DIR"/rsakeys.ini | ||
DROPPRIV=@pkglibexecdir@/xrdp-droppriv | ||
|
||
# ----------------------------------------------------------------------------- | ||
# G E T I N I V A L U E | ||
# | ||
# Gets a value from an ini file. | ||
# | ||
# Params [ini_file] [key] | ||
# ----------------------------------------------------------------------------- | ||
GetIniValue() | ||
{ | ||
# Look for a line matching 'key=' with optional whitespace | ||
# either side of the key. When we find one, strip everything | ||
# up to and including the first '=', print it, and quit | ||
# | ||
# This doesn't take sections into account | ||
sed -n -e '/^ *'"$2"' *=/{ | ||
s/^[^=]*=//p | ||
q | ||
}' "$1" | ||
} | ||
|
||
# ----------------------------------------------------------------------------- | ||
# M A I N | ||
# ----------------------------------------------------------------------------- | ||
|
||
if [ "$(id -u)" != 0 ]; then | ||
echo "** Must run this script as root" >&2 | ||
exit 1 | ||
fi | ||
|
||
OS=$(uname) | ||
case "$OS" in | ||
FreeBSD | Linux) ;; | ||
*) echo "Unsupported operating system $OS" >&2 | ||
exit 1 | ||
esac | ||
|
||
errors=0 | ||
|
||
runtime_user=$(GetIniValue "$XRDP_INI" runtime_user) | ||
runtime_group=$(GetIniValue "$XRDP_INI" runtime_group) | ||
certificate=$(GetIniValue "$XRDP_INI" certificate) | ||
key_file=$(GetIniValue "$XRDP_INI" key_file) | ||
SessionSockdirGroup=$(GetIniValue "$SESMAN_INI" SessionSockdirGroup) | ||
|
||
case "$certificate" in | ||
'') certificate="$CONF_DIR"/cert.pem ;; | ||
/*) ;; | ||
*) certificate="$CONF_DIR"/"$certificate" | ||
esac | ||
|
||
case "$key_file" in | ||
'') key_file="$CONF_DIR"/key.pem ;; | ||
/*) ;; | ||
*) key_file="$CONF_DIR"/"$key_file" | ||
esac | ||
|
||
echo "Settings" | ||
echo " - [xrdp.ini] runtime_user : $runtime_user" | ||
echo " - [xrdp.ini] runtime_group : $runtime_group" | ||
echo " - [xrdp.ini] certificate : $certificate" | ||
echo " - [xrdp.ini] key_file : $key_file" | ||
echo " - [sesman.ini] SessionSockdirGroup : $SessionSockdirGroup" | ||
echo | ||
|
||
# Basic checks on runtime user/group | ||
if [ -z "$runtime_user" ] && [ -z "$runtime_group" ]; then | ||
echo "-Info- This system is not configured to run xrdp without privilege" | ||
exit 0 | ||
fi | ||
|
||
if [ -z "$runtime_user" ] || [ -z "$runtime_group" ]; then | ||
echo "-Error- Both 'runtime_user' and 'runtime_group' must be set" | ||
errors=$(( errors + 1 )) | ||
exit 1 | ||
fi | ||
|
||
if getent passwd "$runtime_user" >/dev/null ; then | ||
echo "-Info- runtime_user '$runtime_user' appears to exist" | ||
else | ||
echo "-Error- runtime_user '$runtime_user' does not exist" | ||
errors=$(( errors + 1 )) | ||
fi | ||
|
||
GID= | ||
if getent group "$runtime_group" >/dev/null ; then | ||
echo "-Info- runtime_group '$runtime_group' appears to exist" | ||
GID=$(getent group xrdp | cut -d: -f3) | ||
else | ||
echo "-Error- runtime_group '$runtime_group' does not exist" | ||
errors=$(( errors + 1 )) | ||
fi | ||
|
||
# Groups agree between sesman and xrdp? | ||
if [ "$runtime_user" = "$SessionSockdirGroup" ]; then | ||
echo "-Info- xrdp.ini and sesman.ini agree on group ownbership" | ||
else | ||
echo "-Error- xrdp.ini and sesman.ini do not agree on group ownbership" | ||
errors=$(( errors + 1 )) | ||
fi | ||
|
||
# Check we can access rsakeys.ini | ||
# | ||
# This is our file, so we can be completely prescriptive about | ||
# the permissions | ||
if [ -e $RSAKEYS_INI ]; then | ||
# Only check if we have a GID | ||
if [ -n "$GID" ]; then | ||
# Get the permissions, UID and GID in $1..$3 | ||
case "$OS" in | ||
FreeBSD) | ||
# shellcheck disable=SC2046 | ||
set -- $(stat -f "%Lp %u %g" $RSAKEYS_INI) | ||
;; | ||
*) | ||
# shellcheck disable=SC2046 | ||
set -- $(stat -c "%a %u %g" $RSAKEYS_INI) | ||
esac | ||
if [ "$1/$2/$3" = "640/0/$GID" ]; then | ||
echo "-Info- $RSAKEYS_INI has correct permissions" | ||
else | ||
if [ "$1" != 640 ]; then | ||
echo "-Error- $RSAKEYS_INI should have permissions -rw-r-----" | ||
errors=$(( errors + 1 )) | ||
fi | ||
if [ "$2" != 0 ]; then | ||
echo "-Error- $RSAKEYS_INI should be owned by root" | ||
errors=$(( errors + 1 )) | ||
fi | ||
if [ "$3" != "$GID" ]; then | ||
echo "-Error- $RSAKEYS_INI should be in the $runtime_group group" | ||
errors=$(( errors + 1 )) | ||
fi | ||
fi | ||
fi | ||
else | ||
echo "-Error- $RSAKEYS_INI does not exist" | ||
errors=$(( errors + 1 )) | ||
fi | ||
|
||
# Are cert and key readable by the user? | ||
# | ||
# These aren't necessarily our files, so we can't be prescriptive about | ||
# privileges. On Debian for example, we might be using the 'ssl-cert' | ||
# group to obtain access to /etc/ssl/private/ssl-cert-snakeoil.key | ||
if ! [ -e $certificate ]; then | ||
echo "-Error- $certificate does not exist" | ||
errors=$(( errors + 1 )) | ||
elif $DROPPRIV "$runtime_user" "$runtime_group" sh -c '[ -r '"$certificate"' ]' | ||
then | ||
echo "-Info- $certificate is readable by $runtime_user:$runtime_group" | ||
else | ||
echo "-Error- $certificate is not readable by $runtime_user:$runtime_group" | ||
errors=$(( errors + 1 )) | ||
fi | ||
|
||
if ! [ -e $key_file ]; then | ||
echo "-Error- $key_file does not exist" | ||
errors=$(( errors + 1 )) | ||
elif $DROPPRIV "$runtime_user" "$runtime_group" sh -c '[ -r '"$key_file"' ]' | ||
sh -c '[ -r '"$key_file"' ]' | ||
then | ||
echo "-Info- $key_file is readable by $runtime_user:$runtime_group" | ||
else | ||
echo "-Error- $key_file is not readable by $runtime_user:$runtime_group" | ||
errors=$(( errors + 1 )) | ||
fi | ||
|
||
echo | ||
if [ $errors -eq 0 ]; then | ||
echo "-Summary- Permissions appear to be correct to run xrdp unprivileged" | ||
status=0 | ||
else | ||
echo "-Summary- $errors error(s) found. Please correct these and try again" | ||
status=1 | ||
fi | ||
|
||
exit $status |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* | ||
* | ||
* xrdp: A Remote Desktop Protocol server. | ||
* | ||
* Copyright (C) Jay Sorg and contributors 2004-2024 | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* | ||
* Shell around the g_drop_privileges() call | ||
*/ | ||
|
||
#if defined(HAVE_CONFIG_H) | ||
#include "config_ac.h" | ||
#endif | ||
|
||
#include "os_calls.c" | ||
#include "log.h" | ||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
struct log_config *logging; | ||
int status = 1; | ||
logging = log_config_init_for_console(LOG_LEVEL_WARNING, | ||
g_getenv("DROPPRIV_LOG_LEVEL")); | ||
log_start_from_param(logging); | ||
log_config_free(logging); | ||
|
||
if (argc < 4) | ||
{ | ||
LOG(LOG_LEVEL_ERROR, "Usage : %s [user] [group] [cmd...]\n", argv[0]); | ||
} | ||
else if (g_drop_privileges(argv[1], argv[2]) == 0) | ||
{ | ||
status = g_execvp(argv[3], &argv[3]); | ||
} | ||
|
||
log_end(); | ||
return status; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters