#!/bin/bash ########################################################################### # Connects to a remote server and offers it a local shell. # Usage: epoptes [server] [port] # # Copyright (C) 2010-2012 Alkis Georgopoulos # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # On Debian GNU/Linux systems, the complete text of the GNU General # Public License can be found in `/usr/share/common-licenses/GPL'. ########################################################################### # epoptes-client may be called either as root, to control the client, or as a # user, to control the user session. # As root, epoptes-client starts from if-up.d on standalone clients. # Unfortunately, thin and fat clients don't get if-up.d events, so just for # this case we're using a helper sysvinit script. # As a user, epoptes-client runs from /etc/xdg/autostart. # Users can cancel that from their System > Preferences > Services gnome menu. log_file="/tmp/.epoptes_log" VERSION=$(lliurex-version) download_certificate=False if [ ! -f $log_file ]; then touch $log_file chmod 777 $log_file else chmod 777 $log_file fi discover() { echo " - Dentro de funcion discover - " >> $log_file echo >> $log_file MATCH="" if [[ "$VERSION" == *server* ]] then LIGHT=` echo "$DISPLAY" | cut -d ":" -f1` if [[ -z "$LIGHT" ]]; then MATCH="servidor" else MATCH="ligero" fi else if grep "client" $log_file > /dev/nul then if [[ -z "$LTSP_FATCLIENT" ]]; then MATCH="Pesado" download_certificate=True else MATCH="Semiligero" download_certificate=True fi fi fi echo >> $log_file echo "** Soy un $MATCH **" >> $log_file echo >> $log_file } die() { echo "epoptes-client ERROR: $@" >&2 echo "epoptes-client ERROR: $@" >> $log_file exit 1 } # The "boolean_is_true" name is used as a sentinel that prevents ltsp_config # from sourcing ltsp_common_functions. So we're using a different name. my_boolean_is_true() { case "$1" in # match all cases of true|y|yes [Tt][Rr][Uu][Ee]|[Yy]|[Yy][Ee][Ss]) return 0 ;; *) return 1 ;; esac } # Return true if we're in a chroot. chrooted() { # The result is cached in a variable with the same name as the function :P test -n "$chrooted" && return "$chrooted" test -n "$UID" || UID=$(id -u) if [ "$UID" -gt 0 ]; then chrooted=1 elif [ "$(stat -c %d/%i /)" = "$(stat -Lc %d/%i /proc/1/root 2>/dev/null)" ] then # the devicenumber/inode pair of / is the same as that of /sbin/init's # root, so we're *not* in a chroot and hence return false. chrooted=1 else chrooted=0 fi return "$chrooted" } # Get $UID and $TYPE of the client, and the default $SERVER and $PORT. basic_info() { test -n "$UID" || UID=$(id -u) # We temporarily need LTSP_CLIENT and LTSP_FATCLIENT to decide TYPE. # Unfortunately, when epoptes-client is ran as a system service, they're # not in our environment, and we need to source ltsp_config. # But we don't want to pollute the environment with any of its other vars. if [ "$UID" -eq 0 ] && [ -f /usr/share/ltsp/ltsp_config ] && ! chrooted && egrep -qs 'ltsp|nfs|nbd' /proc/cmdline then export $( . /usr/share/ltsp/ltsp_config >/dev/null echo "LTSP_CLIENT=$LTSP_CLIENT" echo "LTSP_FATCLIENT=$LTSP_FATCLIENT" echo "EPOPTES_CLIENT_VERIFY_CERTIFICATE=$EPOPTES_CLIENT_VERIFY_CERTIFICATE") # LTSP_CLIENT may not be available in system sesssions, if so fake it LTSP_CLIENT=${LTSP_CLIENT:-127.0.0.1} fi # LTSP_FATCLIENT may not be available in user sessions, autodetect it if [ -n "$LTSP_CLIENT" ] && [ -z "$LTSP_FATCLIENT" ] && [ "$UID" -gt 0 ] && [ -x /usr/bin/getltscfg ] && egrep -qs 'ltsp|nfs|nbd' /proc/cmdline then LTSP_FATCLIENT=True fi if my_boolean_is_true "$LTSP_FATCLIENT"; then TYPE="fat" elif [ -n "$LTSP_CLIENT" ]; then TYPE="thin" else TYPE="standalone" fi if ( [ "$TYPE" = "thin" ] && [ "$UID" -gt 0 ] ) || chrooted; then SERVER=localhost else SERVER=server fi PORT=789 export UID TYPE SERVER PORT } fetch_certificate() { echo "[fetch_certificate] Comprobando el certificado: epoptes-client -c">> $log_file echo "[fetch_certificate]Debe ser 0 sino muere, UID : $UID" >> $log_file test "$UID" -eq 0 || die "[fetch_certificate] Need to be root to fetch the certificate" >> $log_file mkdir -p /etc/epoptes openssl s_client -connect $SERVER:$PORT < /dev/null \ | sed '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/!d' \ > /etc/epoptes/server.crt if [ -s /etc/epoptes/server.crt ]; then echo "[fetch_certificate] Successfully fetched certificate from $SERVER:$PORT" >> $log_file echo "[fetch_certificate] Successfully fetched certificate from $SERVER:$PORT" exit 0 else echo "[fetch_certificate] FIRST Failed to fetch certificate from $SERVER:$PORT" >> $log_file sleep 10 openssl s_client -connect $SERVER:$PORT < /dev/null \ | sed '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/!d' \ > /etc/epoptes/server.crt if [ -s /etc/epoptes/server.crt ]; then echo "[fetch_certificate] Successfully fetched certificate from $SERVER:$PORT" >> $log_file echo "[fetch_certificate] Successfully fetched certificate from $SERVER:$PORT" exit 0 else die "[fetch_certificate] SECOND Failed to fetch certificate from $SERVER:$PORT" fi fi } fetch_certificate_download() { echo "[fetch_certificate_download] FORZANDO EL DOWNLOAD DEL CERTIFICADO">> $log_file echo "[fetch_certificate_download] Comprobando el certificado">> $log_file echo "[fetch_certificate_download] Debe ser 0 sino muere, UID : $UID" >> $log_file test "$UID" -eq 0 || die "[fetch_certificate_download] Need to be root to fetch the certificate" >> $log_file mkdir -p /etc/epoptes openssl s_client -connect $SERVER:$PORT < /dev/null \ | sed '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/!d' \ > /etc/epoptes/server.crt if [ -s /etc/epoptes/server.crt ]; then echo "[fetch_certificate_download] Successfully fetched certificate from $SERVER:$PORT" >> $log_file echo "[fetch_certificate_download] Successfully fetched certificate from $SERVER:$PORT" else echo "[fetch_certificate_download] FIRST Failed to fetch certificate from $SERVER:$PORT" >> $log_file sleep 10 openssl s_client -connect $SERVER:$PORT < /dev/null \ | sed '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/!d' \ > /etc/epoptes/server.crt if [ -s /etc/epoptes/server.crt ]; then echo "[fetch_certificate_download] Successfully fetched certificate from $SERVER:$PORT" >> $log_file echo "[fetch_certificate_download] Successfully fetched certificate from $SERVER:$PORT" else die "[fetch_certificate_download] SECOND Failed to fetch certificate from $SERVER:$PORT" fi fi } # Main.############################################ # Check the first parameter as it may turn out we don't need to run at all case "$1" in -v|--version) echo "$VERSION" exit ;; -h|--help) if [ -x /usr/bin/man ]; then exec man epoptes-client else echo "Usage: $0 [-c|-h|-v] [SERVER] [PORT]" exit 0 fi ;; -c|--certificate) need_certificate=True shift ;; esac echo "">> $log_file echo "*******DEPURANDO SCRIPT /USR/SBIN/EPOPTES PARA EL ************* USUARIO : $USER ******">> $log_file echo "">> $log_file date >> $log_file echo "">> $log_file echo "$VERSION" >> $log_file echo "">> $log_file echo "_________MAIN_____________">> $log_file discover echo "Presesion Lightdm.........." >> $log_file echo "">> $log_file name_aux=$(date | awk '{print $4}') file_socat="/tmp/.epoptes_socat_$name_aux" file_socat_post="/tmp/.epoptes_socat_post_$name_aux" ps aux | grep /usr/sbin/epoptes | grep -v root | grep -v "grep" >> $log_file ps aux | grep /usr/sbin/epoptes | grep -v root | grep -v "grep" | awk '{print $2}' | uniq > $file_socat cat $file_socat >> $log_file USERS_SOCAT=$(wc -l < $file_socat) #USERS_SOCAT=$(ps aux | grep /usr/sbin/epoptes | grep -v "root" | grep -v "grep" | awk '{print $2}' | uniq | wc -l) echo "USERS_SOCAT = $USERS_SOCAT">> $log_file; if [[ "$MATCH" != ligero ]]; then if (("$USERS_SOCAT" > 2 )); then echo "Estoy dentro del if matando procesos.......">> $log_file for i in $(ps aux | grep /usr/sbin/epoptes | grep -v "root" | grep -v "grep" | awk '{print $2}' | uniq); do echo "Dentro del FOR para .......">> $log_file ps -aux | grep $i >> $log_file echo "Matando el proceso $i" >> $log_file kill -9 $i >> $log_file done fi fi export VERSION="0.5.7" # Automatically updated by mkdst # When called from /etc/xdg/autostart, /sbin is not in the system path. PATH="$PATH:/sbin:/usr/sbin" # When launched as a service, LANG might not be set. if [ -z "$LANG" ] && [ -r /etc/default/locale ]; then . /etc/default/locale export LANG fi basic_info echo "Capturo basic info UID:$UID TYPE:$TYPE SERVER:$SERVER PORT:$PORT">> $log_file # The configuration file overrides the default values if [ -f /etc/default/epoptes-client ]; then . /etc/default/epoptes-client fi # And the command line parameters override the configuration file export SERVER=${1:-$SERVER} export PORT=${2:-$PORT} # Provide an easy way to fetch the server certificate test -n "$need_certificate" && fetch_certificate #Nos aseguramos de tener el certificado del server echo "Necesito el certificado -> $download_certificate" >> $log_file BAJAR_CERT=True if [ $download_certificate = $BAJAR_CERT ];then echo "Compruebo si el certificado existe..... ">> $log_file if [ ! -s /etc/epoptes/server.crt ]; then echo "FORZADO -> No tengo el certificado debo adquirirlo del server" >> $log_file fetch_certificate_download else echo "Tengo el certificado continua la ejecucion....." >> $log_file fi fi # We don't want the epoptes-client system service running on the epoptes server if ( [ $UID -eq 0 ] && [ $TYPE = "standalone" ] && [ -x /usr/bin/epoptes ] ) || chrooted then echo "--Parte del chrooted--" >> $log_file if lliurex-version -t client; then echo "Compruebo como TRUE --> lliurex-version -t client" >> $log_file else echo "FIN compruebo como FALSE --> lliurex-version -t client" >> $log_file exit 0 fi fi # Go to the scripts directory, so that we can run them with ./xxx cd $(dirname "$0") if [ -d ../epoptes-client ]; then cd ../epoptes-client else cd /usr/share/epoptes-client fi # Source the lsb init functions, for log_begin_msg. # Unfortunately it seems that Centos and Fedora don't have that file. if [ -f /lib/lsb/init-functions ]; then . /lib/lsb/init-functions else alias log_begin_msg="echo -n" fi log_begin_msg "Epoptes-client connecting to $SERVER:$PORT..." echo "Epoptes-client connecting to $SERVER:$PORT..." echo "Epoptes-client connecting to $SERVER:$PORT...">>$log_file # Call chain: # * if-up.d executes /usr/sbin/epoptes-client # * then socat is called # * after a successful connection, socat exec's /bin/sh # * and the daemon sends /usr/share/epoptes/client-functions to that shell # Kill all ghost instances of epoptes-client of the same user. # That may happen if network connectivity is lost for a while. # Standalone workstations don't hang if the network is down, and nbd might cope # with that for LTSP clients, but epoptes kills disconnected epoptes-clients. # The current epoptes-client is excluded because it starts with /bin/sh. echo "pkill de $UID" echo "pkill de $UID">>$lof_file pkill -U $UID -f '^epoptes-client$' # Remember the stdout descriptor to use it in the second phase. # stdio will be redirected to the server, but stderr will be kept in the # local console, to avoid possible noise from applications started in the # background. # If the callee needs to grab stderr, it can use `cmd 2>&1`. exec 5>&1 # Bash supports launching a program with a different zeroth argument, # this makes pgrep'ing for epoptes-client easier. cmdline='bash -c \"exec -a epoptes-client sh\"' # Offer an lts.conf (or environment) variable to disable cert verification. if my_boolean_is_true "${EPOPTES_CLIENT_VERIFY_CERTIFICATE:-True}"; then cert_param="cafile=/etc/epoptes/server.crt" else cert_param="verify=0" fi # Connect to the server, or keep retrying until the server gets online # (for standalone workstations booted before the server). RUN=1 salida(){ RUN=0 echo "Estoy en la funcion de SALIDA de $USER" >> $log_file date >> $log_file echo "Quiero matar el proceso $BASHPID" >> $log_file #kill -9 $BASHPID } echo "RUN = $RUN" test_conn(){ echo "Testeando la funcion CONN $USER">> $log_file if [ -z ${LTSP_CLIENT} ]; then echo "No es cliente LTSP">> $log_file #exit 0 #RUN=0 return 0 fi ping -c 2 ${LTSP_CLIENT} if [ $? -eq 0 ]; then echo "Estamos en if del ping -c">> $log_file #exit 0 return 0 fi echo "Vamos a salida -- No detecte nada en funcion CONN">> $log_file salida } trap salida KILL TERM QUIT INT STOP EXIT echo "__________________________________________________">>$log_file echo "">>$log_file echo "-- Funcion Principal para abrir el SOCAT --" >> $log_file if [ -s /etc/epoptes/server.crt ] || [ "$cert_param" = "verify=0" ]; then echo "Dentro del if antes del while 1 del usuario $USER" >> $log_file while [ ${RUN} -eq 1 ] && sleep 1; do ALIVE=$(ps ax|grep $PPID|grep -v grep|wc -l) echo "Dentro del While porque el RUN es $RUN para usuario $USER">> $log_file ps aux | grep /usr/sbin/epoptes | grep -v root | grep -v "grep" | awk '{print $2}' | uniq > $file_socat_post echo " - USERS_SOCAT_POST - ">>$log_file cat $file_socat_post >> $log_file USERS_SOCAT_POST=$(wc -l < $file_socat_post) #USERS_SOCAT_POST=`ps aux | grep /usr/sbin/epoptes | grep -v root | grep -v "grep" | awk '{print $2}' | uniq | wc -l ` echo "Calculando el USERS_SOCAT_POST: $USERS_SOCAT_POST" >> $log_file if (( $USERS_SOCAT_POST < 3 )) || [[ "$MATCH" == "ligero" ]]; then echo "-----SOCAT se va a ejecutar para el usuario: $USER -----">> $log_file sleep 20 date_create=$(date) echo 'socat openssl-connect:$SERVER:$PORT,$cert_param,interval=60,forever EXEC:"$cmdline",sigint,sigquit,sigterm' >> $log_file socat openssl-connect:$SERVER:$PORT,$cert_param,interval=60,forever EXEC:"$cmdline",sigint,sigquit echo "-------------------------------------" $log_file echo "Muere el SOCAT del usuario: $USER creado: $date_create">> $log_file date >> $log_file echo "-------------------------------------" $log_file fi if [ "x${ALIVE}" != "x1" ]; then echo "Se aborta el script para el usuario $USER debido al AlIVE">> $log_file exit 1 fi echo "Paso del ALIVE y continuo porque RUN: $RUN del usuario $USER">> $log_file test_conn SESSION_GNOME=`ps aux | grep mate-session | wc -l ` if (( $SESSION_GNOME < 2 )); then date >> $log_file echo "La sesion no esta activa me quedo en la sesion MATE-SESSION: $SESSION_GNOME modifico el RUN" >> $log_file RUN=0 fi done; elif [ -f /etc/epoptes/server.crt ]; then echo "Antes del while2 del user: $USER" >> $log_file while [ ${RUN} -eq 1 ] && sleep 1; do ALIVE=$(ps ax|grep $PPID|grep -v grep|wc -l) socat tcp:$SERVER:$PORT,interval=60,forever EXEC:"$cmdline",nofork if [ "x${ALIVE}" != "x1" ]; then exit 1 fi echo "RUN en ELIF es $RUN del usuario $USER">> $log_file test_conn done; else echo "en el else del usuario $USER">> $log_file $0 -c exec $0 fi echo "____________FIN_______SCRIPT____________">> $log_file