package: x2gobroker
priority: wishlist

Hi everyone,

A while ago, I wrote a small broker demo in bash.

I would like to get this added to X2Go's official repository, in the
x2gobroker.git tree, as a separate binpkg (maybe called
x2gobroker-ssh-mini).


Limitations:

1) This script is not suitable for a multi-server setup.
   It needs to run on the only X2GoServer there is.
   (There's an idea in the comments how to overcome this limitation,
   though.)
   This is, however, also its advantage: You don't need to mess with
   LDAP, postgres and NFS just to be able to use a central configuration
   for your X2GoClients.

2) It does not offer all the ACL options of the "big" broker
   implementations.


Problems:

1) There's currently no manpage for it.  All documentation is in the
   comments in the bash script.

2) IIRC, Alex made some changes to X2GoClient and/or X2GoServer that
   will cause this script to break - however, these changes are not part
   of our stable release yet.  So it should be possible to release this
   package right now, but it needs to be kept in mind that it will have
   to be adapted once Alex' changes make it to stable.
   This was related to more "chatter" about "Access granted" and similar
   status messages being exchanged between server/broker/client.

Script attached.

Kind Regards,
Stefan Baur

-- 
BAUR-ITCS UG (haftungsbeschränkt)
Geschäftsführer: Stefan Baur
Eichenäckerweg 10, 89081 Ulm | Registergericht Ulm, HRB 724364
Fon/Fax 0731 40 34 66-36/-35 | USt-IdNr.: DE268653243
#!/bin/bash

# This file is part of the  X2Go Project - http://www.x2go.org
# Copyright (C) 2018 by Stefan Baur <[email protected]>
#
# X2Go Mini SSH 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 Mini SSH 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.

# Features and Limitations
# You can add sessions as for-everyone (defaultsessions), per-group, and 
per-user
# You cannot add sessions based on IP range
# You cannot deny sessions based on group, user, or IP range
# Checking for suspended sessions and resuming them only works if you are 
logged in 
#   to the broker with the same credentials that you want to use to start/resume
#   the session AND 
#   if broker and X2Go server are one and the same machine
#   (This could be expanded so it works with separate machines, as long as ssh
#   public/private key authentication and autologin is used.)

# Config goes here - always only one session per file!
# /etc/x2go/x2go-mini-sshbroker/defaultsessions/*.session
# /etc/x2go/x2go-mini-sshbroker/${USER}/*.session
# /etc/x2go/x2go-mini-sshbroker/groups/${GROUP}/*.session

### init ###
# make a list of the parameters we received on the command line
PARAMLIST=$(echo -e "$@" | sed -e 's/ --/\n--/g')

# make sure we have a directory to write our config file to
mkdir -p ~/.x2go

### main ###

# check if we were asked to list sessions
if (echo -e "$PARAMLIST" | grep -q -- '--task listsessions'); then

        # this is so we can request data for a username that is different from 
the one we used
        # to log in and run this script with
        REQUESTEDUSER=$(echo -e "$PARAMLIST" | awk '$1 == "--user" { print $2}')
        if [ -n "$REQUESTEDUSER" ]; then
                USER=$REQUESTEDUSER
        fi

        # fetch default sessions
        if [ -d /etc/x2go/x2go-mini-sshbroker/defaultsessions ]; then
                for SINGLESESSIONFILE in 
/etc/x2go/x2go-mini-sshbroker/defaultsessions/*.session ; do
                        # add session file name to the list of sessionfiles
                        SESSIONFILES+="$SINGLESESSIONFILE\n"
                        # figure out what the name of the session should be, 
based on the filename
                        SINGLESESSIONNAME=$(basename $SINGLESESSIONFILE | sed 
-e 's/\.session$//')
                        # check if the session file already contains a proper 
header block
                        if (grep -q "^\[$SINGLESESSIONNAME\]" 
$SINGLESESSIONFILE); then
                                # if it does, all we do is replace the user name
                                SESSIONLIST+="\n$(grep -v '^user=' 
$SINGLESESSIONFILE)\nuser=$USER\n"
                        else
                                # if it does not, we add a header based on the 
file name, and replace the user name
                                SESSIONLIST+="\n[$SINGLESESSIONNAME]\n$(grep -v 
'^\[' $SINGLESESSIONFILE | grep -v '^user=')\nuser=$USER\n"
                        fi
                done
        fi

        # fetch user-specific sessions
        if [ -d /etc/x2go/x2go-mini-sshbroker/$USER ]; then
                for SINGLESESSIONFILE in 
/etc/x2go/x2go-mini-sshbroker/$USER/*.session ; do
                        # add session file name to the list of sessionfiles
                        SESSIONFILES+="$SINGLESESSIONFILE\n"
                        # figure out what the name of the session should be, 
based on the filename
                        SINGLESESSIONNAME=$(basename $SINGLESESSIONFILE | sed 
-e 's/\.session$//')
                        # check if the session file already contains a proper 
header block
                        if (grep -q "^\[$SINGLESESSIONNAME\]" 
$SINGLESESSIONFILE); then
                                # if it does, all we do is replace the user name
                                SESSIONLIST+="\n$(grep -v '^user=' 
$SINGLESESSIONFILE)\nuser=$USER\n"
                        else
                                # if it does not, we add a header based on the 
file name, and replace the user name
                                SESSIONLIST+="\n[$SINGLESESSIONNAME]\n$(grep -v 
'^\[' $SINGLESESSIONFILE | grep -v '^user=')\nuser=$USER\n"
                        fi
                done
        fi

        # fetch group-specific sessions
        if [ -d /etc/x2go/x2go-mini-sshbroker/groups ]; then
                # determine groups for this user and work through the list
                for SINGLEGROUP in $(id -Gn $USER) ; do
                        if [ -d 
/etc/x2go/x2go-mini-sshbroker/groups/$SINGLEGROUP ]; then
                                for SINGLESESSIONFILE in 
/etc/x2go/x2go-mini-sshbroker/groups/$SINGLEGROUP/*.session ; do
                                        # add session file name to the list of 
sessionfiles
                                        SESSIONFILES+="$SINGLESESSIONFILE\n"
                                        # figure out what the name of the 
session should be, based on the filename
                                        SINGLESESSIONNAME=$(basename 
$SINGLESESSIONFILE | sed -e 's/\.session$//')
                                        # check if the session file already 
contains a proper header block
                                        if (grep -q "^\[$SINGLESESSIONNAME\]" 
$SINGLESESSIONFILE); then
                                                # if it does, all we do is 
replace the user name
                                                SESSIONLIST+="\n$(grep -v 
'^user=' $SINGLESESSIONFILE)\nuser=$USER\n"
                                        else
                                                # if it does not, we add a 
header based on the file name, and replace the user name
                                                
SESSIONLIST+="\n[$SINGLESESSIONNAME]\n$(grep -v '^\[' $SINGLESESSIONFILE | grep 
-v '^user=')\nuser=$USER\n"
                                        fi
                                done
                        fi
                done
        fi

        # store list of session files
        TEMPBROKERSESSIONFILE=$(mktemp -p ~/.x2go)
        echo -e "$SESSIONFILES">$TEMPBROKERSESSIONFILE
        # atomic transaction, so it is always complete when accessed, even when 
multiple instances are run in parallel
        mv $TEMPBROKERSESSIONFILE ~/.x2go/brokersessionfile-${USER} # needs 
user name, in case we ssh'ed into the broker using different credentials

        # output all session data
        echo -e "Access granted"
        echo -e "START_USER_SESSIONS"
        echo -e "$SESSIONLIST"
        echo -e "END_USER_SESSIONS"

# check if we were asked to provide a server name/IP and port for a specific 
session
elif (echo -e "$PARAMLIST" | grep -q -- '--task selectsession'); then
                SESSIONID=$(echo -e "$PARAMLIST" | awk '$1 == "--sid" { print 
$2 }')
                # search for the line with the corresponding session file in 
our stored list of files
                SESSIONFILE=$(grep "$SESSIONID" 
~/.x2go/brokersessionfile-${USER})
                # determine server name/IP and port from this file
                SERVER=$(awk -F '=' '$1 == "host" { print $2 }' $SESSIONFILE)
                PORT=$(awk -F '=' '$1 == "sshport" { print $2 }' $SESSIONFILE)
                # if this failed, set default values
                if [ -z "$SERVER" ] && [ -f 
/etc/x2go/x2go-mini-sshbroker/defaulthost ]; then
                        # determine default hostname/IP
                        read DEFAULTHOST 
</etc/x2go/x2go-mini-sshbroker/defaulthost
                        SERVER=$DEFAULTHOST
                fi

                if [ -z "PORT" ]; then
                        PORT=22
                fi

                # output all data
                echo -e "Access granted"
                echo -e "SERVER:$SERVER:$PORT"
                # check for suspended sessions
                SESSIONLIST=$(x2golistsessions)
                # NOTE: at present, this only checks for local sessions 
(X2GoBroker==X2GoServer)
                # to make this work with a separate X2GoServer, we would need 
something like
                #if [ -z "$SESSIONLIST" ] && [ -n "$SSH_AUTH_SOCK" ]; then
                #       # very hackish and not safe! Try to add hosts to a 
shared known_hosts file in advance, and place it in 
/etc/x2go/x2go-mini-sshbroker/
                #       # then point UserKnownHostsFile at that and get rid of 
the StrictHostKeyChecking=false
                #       SESSIONLIST=$(ssh -oStrictHostKeyChecking=false 
-oUserKnownHostsFile=/dev/null -p $PORT -A $USER@$SERVER x2golistsessions 
2>/dev/null)
                #fi
                # but the problem is, that it seems SSH_AUTH_SOCK is not set by 
the broker when logging in
                # one way around this might be an ssh private key stored in 
/etc/x2go/x2go-mini-sshbroker/, that is added as a limited key with
                # "forced-command=x2golistsessions_root" to 
/root/.ssh/authorized_keys to all servers - the output would then have to be 
filtered for the
                # username in question, as _root shows the data of all users on 
that particular host
                if [ -n "$SESSIONLIST" ]; then
                        echo "SESSION_INFO:$SESSIONLIST"
                fi
fi
# DEBUG echo "$@" >>/tmp/x2go-mini-sshbroker-commands
_______________________________________________
x2go-dev mailing list
[email protected]
https://lists.x2go.org/listinfo/x2go-dev

Reply via email to