The branch, build-main has been updated via d9c17a236357d7939415afae5b420917f0e2f212 (commit) from 176c5d672d301ed401172f23f5dac5d765d7f2f6 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- ----------------------------------------------------------------------- Summary of changes: debian/changelog | 2 + debian/x2gobroker-daemon.default | 28 ++++++++---- debian/x2gobroker-daemon.init | 51 ++++++++++++++++----- debian/x2gobroker.install | 1 + sbin/x2gobroker | 2 + sbin/x2gobroker-authservice | 67 +++++++++++++++++++++++++++ x2gobroker/authmechs/pam_authmech.py | 4 +- x2gobroker/authservice.py | 84 ++++++++++++++++++++++++++++++++++ x2gobroker/defaults.py | 6 +++ 9 files changed, 223 insertions(+), 22 deletions(-) create mode 100755 sbin/x2gobroker-authservice create mode 100644 x2gobroker/authservice.py The diff of changes is: diff --git a/debian/changelog b/debian/changelog index ad2e00c..ebbbbd3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -13,6 +13,8 @@ x2gobroker (0.0.0.2-0~x2go1) UNRELEASED; urgency=low - Make sure the unprivileged daemon user (x2gobroker) has access to the PID file directory. - Set log level to CRITICAL if running unit tests. + - Perform PAM authentication via an authentication service (the broker + runs as non-privileged user, the authentication service as root). * /debian/control: + Add bin:package x2gobroker-agent. * /debian/x2gobroker-daemon.init: diff --git a/debian/x2gobroker-daemon.default b/debian/x2gobroker-daemon.default index ff315d5..f3c5bc0 100644 --- a/debian/x2gobroker-daemon.default +++ b/debian/x2gobroker-daemon.default @@ -1,35 +1,47 @@ # X2Go Session Broker configuration for Debian # Uncomment to enable the X2Go Session Broker standalone daemon -START_DAEMON=true +START_BROKER=true -# the posix user ID the broker runs under (do not change!) +# For PAM authentication the X2Go Session Broker needs its authentication +# service. The session broker itself runs as a non-privileged user (see below) +# whereas the authentication service must run as super-user root. +# +# If you do not use PAM as authentication mechanism with the X2Go Session Broker, +# you can disable the authentication service here. +START_AUTHSERVICE=true + +# The posix user ID the broker runs under (do not change!) # if you change it nonetheless, make sure that the log file # directory (default: /var/log/x2gobroker) and files in there are # writable by that user #X2GOBROKER_DAEMON_USER=x2gobroker -# run X2Go Session Broker in debug mode, this will make the broker +# Run X2Go Session Broker in debug mode, this will make the broker # available through http GET method calls (otherwise: POST method # only) and you will be able to test the broker through your web # browser (0=disable, 1=enable). #X2GOBROKER_DEBUG=0 -# bind standalone daemon to this address:port +# Bind standalone daemon to this address:port #DAEMON_BIND_ADDRESS=127.0.0.1:8080 -# default X2Go Session Broker backend (available: zeroconf, inifile) +# Default X2Go Session Broker backend (available: zeroconf, inifile) #X2GOBROKER_DEFAULT_BACKEND=zeroconf -# path to the X2Go Session Broker's configuration file +# Path to the X2Go Session Broker's configuration file #X2GOBROKER_CONFIG=/etc/x2go/x2gobroker.conf -# path to the X2Go Session Broker's session profiles file (when using the inifile backend) +# Path to the X2Go Session Broker's session profiles file (when using the inifile backend) #X2GOBROKER_SESSIONPROFILES=/etc/x2go/broker/x2gobroker-sessionprofiles.conf -# path to the X2Go Session Broker's agent command +# Path to the X2Go Session Broker's agent command #X2GOBROKER_AGENT_CMD=/usr/lib/x2go/x2gobroker-agent +# The unix socket file for communication between the broker and the authentication service. +#X2GOBROKER_AUTHSERVICE_SOCKET=/run/x2gobroker/x2gobroker-authservice.socket + + ########################################################## ### ### ### Enable SSL Support ### diff --git a/debian/x2gobroker-daemon.init b/debian/x2gobroker-daemon.init index fba7672..67276e4 100755 --- a/debian/x2gobroker-daemon.init +++ b/debian/x2gobroker-daemon.init @@ -19,13 +19,16 @@ set -eu DAEMON=/usr/sbin/x2gobroker +AUTHSERVICE=/usr/sbin/x2gobroker-authservice test -d /run && RUNDIR=/run || RUNDIR=/var/run -PIDFILE=$RUNDIR/x2gobroker/x2gobroker-daemon.pid +PIDFILE_BROKER=$RUNDIR/x2gobroker/x2gobroker-daemon.pid +PIDFILE_AUTHSERVICE=$RUNDIR/x2gobroker/x2gobroker-authservice.pid DEBIANCONFIG=/etc/default/x2gobroker-daemon test -x "$DAEMON" || exit 0 -START_DAEMON=false +START_BROKER=false +START_AUTHSERVICE=false DAEMON_BIND_ADDRESS=127.0.0.1:8080 X2GOBROKER_DEBUG=0 X2GOBROKER_DAEMON_USER='x2gobroker' @@ -33,6 +36,7 @@ X2GOBROKER_DEFAULT_BACKEND="zeroconf" X2GOBROKER_CONFIG="/etc/x2go/x2gobroker.conf" X2GOBROKER_SESSIONPROFILES="/etc/x2go/broker/x2gobroker-sessionprofiles.conf" X2GOBROKER_AGENT_CMD="/usr/lib/x2go/x2gobroker-agent" +X2GOBROKER_AUTHSERVICE_SOCKET="$RUNDIR/x2gobroker/x2gobroker-authservice.socket" X2GOBROKER_SSL_CERTFILE= X2GOBROKER_SSL_KEYFILE= test -f $DEBIANCONFIG && . $DEBIANCONFIG @@ -57,6 +61,7 @@ export X2GOBROKER_CONFIG export X2GOBROKER_DEFAULT_BACKEND export X2GOBROKER_SESSIONPROFILES export X2GOBROKER_AGENT_CMD +export X2GOBROKER_AUTHSERVICE_SOCKET export X2GOBROKER_SSL_CERTFILE export X2GOBROKER_SSL_KEYFILE @@ -72,28 +77,50 @@ is_true() case "${1:-}" in start) - if [ -e $PIDFILE ]; then + if [ -e $PIDFILE_BROKER ]; then if ps -u $X2GOBROKER_DAEMON_USER | grep $(basename $DAEMON) 1>/dev/null 2>/dev/null; then log_warning_msg "X2Go Session Broker already running" else - log_warning_msg "X2Go Session Broker: stale PID file ($PIDFILE). Delete it manually!" + log_warning_msg "X2Go Session Broker: stale PID file ($PIDFILE_BROKER). Delete it manually!" fi - START_DAEMON=no + START_BROKER=no fi - if is_true $START_DAEMON; then - log_daemon_msg "Starting X2Go Session Broker standalone daemon" $(basename $DAEMON) + if is_true $START_BROKER; then + log_daemon_msg "Starting X2Go Session Broker standalone daemon" "$(basename $DAEMON)" set +e - start-stop-daemon --chuid $X2GOBROKER_DAEMON_USER -b -m -S -p $PIDFILE -x $DAEMON -- -b $DAEMON_BIND_ADDRESS + start-stop-daemon --chuid $X2GOBROKER_DAEMON_USER -b -m -S -p $PIDFILE_BROKER -x $DAEMON -- -b $DAEMON_BIND_ADDRESS log_end_msg $? set -e + if [ -e $PIDFILE_AUTHSERVICE ]; then + if ps -u root | grep $(basename $AUTHSERVICE) 1>/dev/null 2>/dev/null; then + log_warning_msg "X2Go Broker Authentication Service already running" + else + log_warning_msg "X2Go Broker Authentication Service: stale PID file ($PIDFILE_AUTHSERVICE). Delete it manually!" + fi + START_AUTHSERVICE=no + fi + if is_true $START_AUTHSERVICE; then + set +e + log_daemon_msg "Starting X2Go Broker Authentication Service" "$(basename $AUTHSERVICE)" + start-stop-daemon -b -m -S -p $PIDFILE_AUTHSERVICE -x $AUTHSERVICE -- -s $X2GOBROKER_AUTHSERVICE_SOCKET + set -e + fi fi ;; stop) - if [ -f $PIDFILE ] ; then - log_daemon_msg "Stopping X2Go Session Broker standalone daemon" "x2gobroker" + if [ -f $PIDFILE_BROKER ] ; then + log_daemon_msg "Stopping X2Go Session Broker standalone daemon" "$(basename $DAEMON)" + set +e + start-stop-daemon -K -p $PIDFILE_BROKER + rm -f $PIDFILE_BROKER + log_end_msg $? + set -e + fi + if [ -f $PIDFILE_AUTHSERVICE ] ; then + log_daemon_msg "X2Go Broker Authentication Service" "$(basename $AUTHSERVICE)" set +e - start-stop-daemon -K -p $PIDFILE - rm -f $PIDFILE + start-stop-daemon -K -p $PIDFILE_AUTHSERVICE + rm -f $PIDFILE_AUTHSERVICE log_end_msg $? set -e fi diff --git a/debian/x2gobroker.install b/debian/x2gobroker.install index fac20e4..29dc1c0 100644 --- a/debian/x2gobroker.install +++ b/debian/x2gobroker.install @@ -1 +1,2 @@ sbin/x2gobroker usr/sbin/ +sbin/x2gobroker-authservice usr/sbin/ \ No newline at end of file diff --git a/sbin/x2gobroker b/sbin/x2gobroker index da91b0e..bb52019 100755 --- a/sbin/x2gobroker +++ b/sbin/x2gobroker @@ -1,5 +1,7 @@ #!/usr/bin/env python +# -*- coding: utf-8 -*- + # This file is part of the X2Go Project - http://www.x2go.org # Copyright (C) 2011-2012 by Oleksandr Shneyder <oleksandr.shneyder@obviously-nice.de> # Copyright (C) 2011-2012 by Heinz-Markus Graesing <heinz-m.graesing@obviously-nice.de> diff --git a/sbin/x2gobroker-authservice b/sbin/x2gobroker-authservice new file mode 100755 index 0000000..12974f8 --- /dev/null +++ b/sbin/x2gobroker-authservice @@ -0,0 +1,67 @@ +#!/usr/bin/env python + +# -*- coding: utf-8 -*- + +# This file is part of the X2Go Project - http://www.x2go.org +# Copyright (C) 2011-2012 by Oleksandr Shneyder <oleksandr.shneyder@obviously-nice.de> +# Copyright (C) 2011-2012 by Heinz-Markus Graesing <heinz-m.graesing@obviously-nice.de> +# Copyright (C) 2012 by Mike Gabriel <mike.gabriel@das-netzwerkteam.de> +# +# X2Go Session Broker is free software; you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# X2Go Session Broker is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +import os +import sys +import setproctitle +import argparse + +try: + import x2gobroker.authservice +except ImportError: + sys.path.insert(0, os.path.join(os.getcwd(), '..')) + import x2gobroker.authservice + +PROG_NAME = os.path.basename(sys.argv[0]) +PROG_OPTIONS = sys.argv[1:] +setproctitle.setproctitle("%s %s" % (PROG_NAME, " ".join(PROG_OPTIONS))) + +if __name__ == '__main__': + + common_options = [ + {'args':['-s','--socket-file'], 'default': x2gobroker.defaults.X2GOBROKER_AUTHSERVICE_SOCKET, 'metavar': 'AUTHSOCKET', 'help': 'socket file for AuthService communication', }, + {'args':['-d','--debug'], 'default': False, 'action': 'store_true', 'help': 'enable debugging code', }, + ] + p = argparse.ArgumentParser(description='X2Go Session Broker (PAM Auth Service)',\ + formatter_class=argparse.RawDescriptionHelpFormatter, \ + add_help=True, argument_default=None) + p_common = p.add_argument_group('common parameters') + + for (p_group, opts) in ( (p_common, common_options), ): + for opt in opts: + args = opt['args'] + del opt['args'] + p_group.add_argument(*args, **opt) + + cmdline_args = p.parse_args() + + if cmdline_args.debug: + x2gobroker.defaults.X2GOBROKER_DEBUG = cmdline_args.debug + + socket_file = cmdline_args.socket_file + x2gobroker.authservice.AuthService(socket_file) + try: + x2gobroker.authservice.loop() + except KeyboardInterrupt: + pass diff --git a/x2gobroker/authmechs/pam_authmech.py b/x2gobroker/authmechs/pam_authmech.py index fca5ec0..b46d1a2 100644 --- a/x2gobroker/authmechs/pam_authmech.py +++ b/x2gobroker/authmechs/pam_authmech.py @@ -18,7 +18,7 @@ # Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. -import pam +import x2gobroker.authservice class X2GoBrokerAuthMech(object): @@ -26,7 +26,7 @@ class X2GoBrokerAuthMech(object): # do a simple PAM authentication against the PAM service ,,x2gobroker'' if username and password: - if pam.authenticate(username, password, service="x2gobroker"): + if x2gobroker.authservice.authenticate(username, password, service="x2gobroker"): return True return False diff --git a/x2gobroker/authservice.py b/x2gobroker/authservice.py new file mode 100644 index 0000000..018be90 --- /dev/null +++ b/x2gobroker/authservice.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- + +# This file is part of the X2Go Project - http://www.x2go.org +# Copyright (C) 2011-2012 by Oleksandr Shneyder <oleksandr.shneyder@obviously-nice.de> +# Copyright (C) 2011-2012 by Heinz-Markus Graesing <heinz-m.graesing@obviously-nice.de> +# Copyright (C) 2012 by Mike Gabriel <mike.gabriel@das-netzwerkteam.de> +# +# X2Go Session Broker is free software; you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# X2Go Session Broker is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +import asyncore +import pam +import socket + +import x2gobroker.defaults + +class AuthClient(asyncore.dispatcher_with_send): + + def __init__(self, sock): + asyncore.dispatcher_with_send.__init__(self, sock) + self._buf = '' + + def handle_read(self): + data = self._buf + self.recv(1024) + if not data: + self.close() + return + reqs, data = data.rsplit('\n', 1) + self._buf = data + for req in reqs.split('\n'): + try: + user, passwd, service = req.split() + except: + self.send('bad\n') + else: + if pam.authenticate(user, passwd, service): + self.send('ok\n') + else: + self.send('fail\n') + + def handle_close(self): + self.close() + + +class AuthService(asyncore.dispatcher_with_send): + + def __init__(self, socketfile): + asyncore.dispatcher_with_send.__init__(self) + self.create_socket(socket.AF_UNIX, socket.SOCK_STREAM) + self.set_reuse_addr() + self.bind(socketfile) + self.listen(1) + + def handle_accept(self): + conn, _ = self.accept() + AuthClient(conn) + + +def loop(): + asyncore.loop() + + +def authenticate(username, password, service="x2gobroker"): + s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + s.connect(x2gobroker.defaults.X2GOBROKER_AUTHSERVICE_SOCKET) + + s.send('{username} {password} {service}\n'.format(username=username, password=password, service=service)) + result = s.recv(1024) + s.close() + if result.startswith('ok'): + return True + return False diff --git a/x2gobroker/defaults.py b/x2gobroker/defaults.py index 4e90837..c02ce43 100644 --- a/x2gobroker/defaults.py +++ b/x2gobroker/defaults.py @@ -84,6 +84,12 @@ else: X2GOBROKER_AGENT_CMD = "/usr/lib/x2go/x2gobroker-agent" logger_broker.info(' X2GOBROKER_AGENT_CMD: {value}'.format(value=X2GOBROKER_AGENT_CMD)) +if os.environ.has_key('X2GOBROKER_AUTHSERVICE_SOCKET'): + X2GOBROKER_AUTHSERVICE_SOCKET=os.environ['X2GOBROKER_AUTHSERVICE_SOCKET'] +else: + X2GOBROKER_AUTHSERVICE_SOCKET="/var/run/x2gobroker-authservice.socket" +logger_broker.info(' X2GOBROKER_AUTHSERVICE_SOCKET: {value}'.format(value=X2GOBROKER_AUTHSERVICE_SOCKET)) + if os.environ.has_key('X2GOBROKER_DEFAULT_BACKEND'): X2GOBROKER_DEFAULT_BACKEND = os.environ['X2GOBROKER_DEFAULT_BACKEND'] else: hooks/post-receive -- x2gobroker.git (HTTP(S) Session broker for X2Go) This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "x2gobroker.git" (HTTP(S) Session broker for X2Go).