Commit cbef6677 authored by rkjnsn's avatar rkjnsn Committed by Commit bot

Add PAM session wrapper

Adds a wrapper to launch me2me script in a proper PAM session.

BUG=616962

Review-Url: https://codereview.chromium.org/2323153002
Cr-Commit-Position: refs/heads/master@{#435044}
parent b7153161
...@@ -80,6 +80,7 @@ action("remoting_me2me_host_deb_installer") { ...@@ -80,6 +80,7 @@ action("remoting_me2me_host_deb_installer") {
"//remoting/host:remoting_native_messaging_manifests", "//remoting/host:remoting_native_messaging_manifests",
"//remoting/host:remoting_start_host", "//remoting/host:remoting_start_host",
"//remoting/host/it2me:remote_assistance_host", "//remoting/host/it2me:remote_assistance_host",
"//remoting/host/linux:remoting_user_session",
"//remoting/resources", "//remoting/resources",
"//third_party/icu:icudata", "//third_party/icu:icudata",
] ]
......
...@@ -19,6 +19,8 @@ ME2ME_PROGNAME = $(BUILD_DIR)/remoting_me2me_host ...@@ -19,6 +19,8 @@ ME2ME_PROGNAME = $(BUILD_DIR)/remoting_me2me_host
ME2ME_DEBUGFILE = $(ME2ME_PROGNAME).debug ME2ME_DEBUGFILE = $(ME2ME_PROGNAME).debug
START_PROGNAME = $(BUILD_DIR)/remoting_start_host START_PROGNAME = $(BUILD_DIR)/remoting_start_host
START_DEBUGFILE = $(START_PROGNAME).debug START_DEBUGFILE = $(START_PROGNAME).debug
SESSION_WRAPPER_PROGNAME = $(BUILD_DIR)/remoting_user_session
SESSION_WRAPPER_DEBUGFILE = $(SESSION_WRAPPER_PROGNAME).debug
ME2ME_NM_PROGNAME = $(BUILD_DIR)/remoting_native_messaging_host ME2ME_NM_PROGNAME = $(BUILD_DIR)/remoting_native_messaging_host
ME2ME_NM_DEBUGFILE = $(ME2ME_NM_PROGNAME).debug ME2ME_NM_DEBUGFILE = $(ME2ME_NM_PROGNAME).debug
REMOTE_ASSISTANCE_PROGNAME = $(BUILD_DIR)/remote_assistance_host REMOTE_ASSISTANCE_PROGNAME = $(BUILD_DIR)/remote_assistance_host
...@@ -53,6 +55,9 @@ install: ...@@ -53,6 +55,9 @@ install:
eu-strip -f "$(START_DEBUGFILE)" "$(START_PROGNAME)" eu-strip -f "$(START_DEBUGFILE)" "$(START_PROGNAME)"
install "$(START_PROGNAME)" "$(INSTALL_DIR)/start-host" install "$(START_PROGNAME)" "$(INSTALL_DIR)/start-host"
eu-strip -f "$(SESSION_WRAPPER_DEBUGFILE)" "$(SESSION_WRAPPER_PROGNAME)"
install "$(SESSION_WRAPPER_PROGNAME)" "$(INSTALL_DIR)/user-session"
eu-strip -f "$(ME2ME_NM_DEBUGFILE)" "$(ME2ME_NM_PROGNAME)" eu-strip -f "$(ME2ME_NM_DEBUGFILE)" "$(ME2ME_NM_PROGNAME)"
install "$(ME2ME_NM_PROGNAME)" "$(INSTALL_DIR)/native-messaging-host" install "$(ME2ME_NM_PROGNAME)" "$(INSTALL_DIR)/native-messaging-host"
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
# /etc/init.d/chrome-remote-desktop: Start and stop Chrome Remote Desktop host daemon. # /etc/init.d/chrome-remote-desktop: Start and stop Chrome Remote Desktop host daemon.
HOST_PATH=/opt/google/chrome-remote-desktop/chrome-remote-desktop HOST_PATH=/opt/google/chrome-remote-desktop/chrome-remote-desktop
USER_SESSION_PATH=/opt/google/chrome-remote-desktop/user-session
# Group of users for which Chrome Remote Desktop is enabled. Users are added # Group of users for which Chrome Remote Desktop is enabled. Users are added
# to that group when they start the host for the first time. # to that group when they start the host for the first time.
...@@ -46,47 +47,46 @@ run_with_timeout() { ...@@ -46,47 +47,46 @@ run_with_timeout() {
return 1 return 1
} }
# Usage: run_and_ignore_error [--login] user program [args...] # Usage: run_and_ignore_error user action
# --login: # Carries out the specified action, ignoring any errors.
# Run program in a clean login shell. This requires backgrounding, since # action:
# the user's .profile or .login script might be run, which might contain # --start is handled specially using the user-session wrapper to start a
# blocking commands. # clean log-in session. In any other case, the host script is called through
# sudo with the specified action flag.
run_and_ignore_error() { run_and_ignore_error() {
login_options="" user="$1"
if [ "$1" = "--login" ]; then action="$2"
login_options="-b -i"
shift
fi
user=$1
shift
set +e set +e
sudo -u "$user" $login_options "$@" if [ "$action" = "--start" ]; then
"$USER_SESSION_PATH" --user="$user" --me2me-script="$HOST_PATH"
else
sudo -u "$user" "$HOST_PATH" "$action"
fi
} }
do_start() { do_start() {
log_begin_msg "Starting Chrome Remote Desktop host for $1..." log_begin_msg "Starting Chrome Remote Desktop host for $1..."
run_and_ignore_error --login $1 "$HOST_PATH" --start run_and_ignore_error $1 --start
log_end_msg $? log_end_msg $?
} }
do_stop() { do_stop() {
log_begin_msg "Stopping Chrome Remote Desktop host for $1..." log_begin_msg "Stopping Chrome Remote Desktop host for $1..."
run_with_timeout run_and_ignore_error $1 "$HOST_PATH" --stop run_with_timeout run_and_ignore_error $1 --stop
log_end_msg $? log_end_msg $?
} }
do_reload() { do_reload() {
log_begin_msg "Reloading Chrome Remote Desktop host configuration for $1..." log_begin_msg "Reloading Chrome Remote Desktop host configuration for $1..."
run_and_ignore_error $1 "$HOST_PATH" --reload run_and_ignore_error $1 --reload
log_end_msg $? log_end_msg $?
} }
do_restart() { do_restart() {
log_begin_msg "Restarting Chrome Remote Desktop host for $1..." log_begin_msg "Restarting Chrome Remote Desktop host for $1..."
run_and_ignore_error $1 "$HOST_PATH" --stop run_and_ignore_error $1 --stop
run_and_ignore_error --login $1 "$HOST_PATH" --start run_and_ignore_error $1 --start
log_end_msg $? log_end_msg $?
} }
......
...@@ -5,4 +5,9 @@ ...@@ -5,4 +5,9 @@
@include common-auth @include common-auth
@include common-account @include common-account
@include common-password @include common-password
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close
session required pam_limits.so
@include common-session @include common-session
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open
session required pam_env.so readenv=1
session required pam_env.so readenv=1 user_readenv=1 envfile=/etc/default/locale
...@@ -9,6 +9,18 @@ group("all_tests") { ...@@ -9,6 +9,18 @@ group("all_tests") {
} }
if (enable_me2me_host) { if (enable_me2me_host) {
executable("remoting_user_session") {
sources = [
"remoting_user_session.cc",
]
deps = [
"//base",
]
libs = [ "pam" ]
}
copy("remoting_me2me_host_copy_script") { copy("remoting_me2me_host_copy_script") {
sources = [ sources = [
"linux_me2me_host.py", "linux_me2me_host.py",
......
...@@ -359,9 +359,12 @@ class Desktop: ...@@ -359,9 +359,12 @@ class Desktop:
display += 1 display += 1
return display return display
def _init_child_env(self): def _init_child_env(self, keep_env):
# Create clean environment for new session, so it is cleanly separated from if keep_env:
# the user's console X session. self.child_env = dict(os.environ)
else:
# Create clean environment for new session, so it is cleanly separated
# from the user's console X session.
self.child_env = {} self.child_env = {}
for key in [ for key in [
...@@ -376,14 +379,6 @@ class Desktop: ...@@ -376,14 +379,6 @@ class Desktop:
if key in os.environ: if key in os.environ:
self.child_env[key] = os.environ[key] self.child_env[key] = os.environ[key]
# Ensure that the software-rendering GL drivers are loaded by the desktop
# session, instead of any hardware GL drivers installed on the system.
self.child_env["LD_LIBRARY_PATH"] = (
"/usr/lib/%(arch)s-linux-gnu/mesa:"
"/usr/lib/%(arch)s-linux-gnu/dri:"
"/usr/lib/%(arch)s-linux-gnu/gallium-pipe" %
{ "arch": platform.machine() })
# Initialize the environment from files that would normally be read in a # Initialize the environment from files that would normally be read in a
# PAM-authenticated session. # PAM-authenticated session.
for env_filename in [ for env_filename in [
...@@ -408,6 +403,19 @@ class Desktop: ...@@ -408,6 +403,19 @@ class Desktop:
except IOError: except IOError:
logging.error("Failed to read file: %s" % env_filename) logging.error("Failed to read file: %s" % env_filename)
# Ensure that the software-rendering GL drivers are loaded by the desktop
# session, instead of any hardware GL drivers installed on the system.
library_path = (
"/usr/lib/%(arch)s-linux-gnu/mesa:"
"/usr/lib/%(arch)s-linux-gnu/dri:"
"/usr/lib/%(arch)s-linux-gnu/gallium-pipe" %
{ "arch": platform.machine() })
if "LD_LIBRARY_PATH" in self.child_env:
library_path += ":" + self.child_env["LD_LIBRARY_PATH"]
self.child_env["LD_LIBRARY_PATH"] = library_path
def _setup_pulseaudio(self): def _setup_pulseaudio(self):
self.pulseaudio_pipe = None self.pulseaudio_pipe = None
...@@ -649,8 +657,8 @@ class Desktop: ...@@ -649,8 +657,8 @@ class Desktop:
if not self.session_proc.pid: if not self.session_proc.pid:
raise Exception("Could not start X session") raise Exception("Could not start X session")
def launch_session(self, x_args): def launch_session(self, keep_env, x_args):
self._init_child_env() self._init_child_env(keep_env)
self._setup_pulseaudio() self._setup_pulseaudio()
self._setup_gnubby() self._setup_gnubby()
self._launch_x_server(x_args) self._launch_x_server(x_args)
...@@ -1236,6 +1244,9 @@ Web Store: https://chrome.google.com/remotedesktop""" ...@@ -1236,6 +1244,9 @@ Web Store: https://chrome.google.com/remotedesktop"""
action="store", metavar="USER", action="store", metavar="USER",
help="Adds the specified user to the chrome-remote-desktop " help="Adds the specified user to the chrome-remote-desktop "
"group (must be run as root).") "group (must be run as root).")
parser.add_option("", "--keep-parent-env", dest="keep_env", default=False,
action="store_true",
help=optparse.SUPPRESS_HELP)
parser.add_option("", "--watch-resolution", dest="watch_resolution", parser.add_option("", "--watch-resolution", dest="watch_resolution",
type="int", nargs=2, default=False, action="store", type="int", nargs=2, default=False, action="store",
help=optparse.SUPPRESS_HELP) help=optparse.SUPPRESS_HELP)
...@@ -1469,7 +1480,7 @@ Web Store: https://chrome.google.com/remotedesktop""" ...@@ -1469,7 +1480,7 @@ Web Store: https://chrome.google.com/remotedesktop"""
relaunch_times.append(x_server_inhibitor.earliest_relaunch_time) relaunch_times.append(x_server_inhibitor.earliest_relaunch_time)
else: else:
logging.info("Launching X server and X session.") logging.info("Launching X server and X session.")
desktop.launch_session(args) desktop.launch_session(options.keep_env, args)
x_server_inhibitor.record_started(MINIMUM_PROCESS_LIFETIME, x_server_inhibitor.record_started(MINIMUM_PROCESS_LIFETIME,
backoff_time) backoff_time)
allow_relaunch_self = True allow_relaunch_self = True
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment