source: epoptes/trunk/fuentes/epoptes-client/epoptes-client @ 6030

Last change on this file since 6030 was 6030, checked in by daduve, 2 years ago

Adding new function to force server certified download if it does not exists in client

  • Property svn:executable set to *
File size: 15.1 KB
Line 
1#!/bin/bash
2
3###########################################################################
4# Connects to a remote server and offers it a local shell.
5# Usage: epoptes [server] [port]
6#
7# Copyright (C) 2010-2012 Alkis Georgopoulos <alkisg@gmail.com>
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program.  If not, see <http://www.gnu.org/licenses/>.
21#
22# On Debian GNU/Linux systems, the complete text of the GNU General
23# Public License can be found in `/usr/share/common-licenses/GPL'.
24###########################################################################
25
26# epoptes-client may be called either as root, to control the client, or as a
27# user, to control the user session.
28# As root, epoptes-client starts from if-up.d on standalone clients.
29# Unfortunately, thin and fat clients don't get if-up.d events, so just for
30# this case we're using a helper sysvinit script.
31# As a user, epoptes-client runs from /etc/xdg/autostart.
32# Users can cancel that from their System > Preferences > Services gnome menu.
33log_file="/tmp/.epoptes_log"
34VERSION=$(lliurex-version)
35download_certificate=False
36
37if [ ! -f $log_file ]; then
38        touch $log_file
39        chmod 777 $log_file
40fi
41
42
43discover() {
44        echo "  - Dentro de funcion discover -  " >> $log_file
45        echo >> $log_file
46        MATCH=""
47        if [[ "$VERSION" == *server* ]]
48        then
49                LIGHT=` echo "$DISPLAY" | cut -d ":" -f1`
50                if [[ -z "$LIGHT" ]]; then 
51                        MATCH="servidor"
52                else
53                        MATCH="ligero"
54                fi
55        else
56                if grep "client" $log_file > /dev/nul
57                then
58                        if [[ -z "$LTSP_FATCLIENT" ]]; then
59                                MATCH="Pesado"
60                                download_certificate=True
61                        else
62                                MATCH="Semiligero"
63                                download_certificate=True
64                        fi
65                fi
66        fi
67        echo >> $log_file
68        echo "** Soy un $MATCH **" >> $log_file
69        echo >> $log_file
70} 
71
72
73
74die() {
75    echo "epoptes-client ERROR: $@" >&2
76    echo "epoptes-client ERROR: $@" >> $log_file
77    exit 1
78}
79
80# The "boolean_is_true" name is used as a sentinel that prevents ltsp_config
81# from sourcing ltsp_common_functions. So we're using a different name.
82my_boolean_is_true() {
83    case "$1" in
84       # match all cases of true|y|yes
85       [Tt][Rr][Uu][Ee]|[Yy]|[Yy][Ee][Ss]) return 0 ;;
86       *) return 1 ;;
87    esac
88}
89
90# Return true if we're in a chroot.
91chrooted() {
92    # The result is cached in a variable with the same name as the function :P
93    test -n "$chrooted" && return "$chrooted"
94    test -n "$UID" || UID=$(id -u)
95    if [ "$UID" -gt 0 ]; then
96        chrooted=1
97    elif [ "$(stat -c %d/%i /)" = "$(stat -Lc %d/%i /proc/1/root 2>/dev/null)" ]
98    then
99        # the devicenumber/inode pair of / is the same as that of /sbin/init's
100        # root, so we're *not* in a chroot and hence return false.
101        chrooted=1
102    else
103        chrooted=0
104    fi
105    return "$chrooted"
106}
107
108# Get $UID and $TYPE of the client, and the default $SERVER and $PORT.
109basic_info() {
110    test -n "$UID" || UID=$(id -u)
111
112    # We temporarily need LTSP_CLIENT and LTSP_FATCLIENT to decide TYPE.
113    # Unfortunately, when epoptes-client is ran as a system service, they're
114    # not in our environment, and we need to source ltsp_config.
115    # But we don't want to pollute the environment with any of its other vars.
116    if [ "$UID" -eq 0 ] && [ -f /usr/share/ltsp/ltsp_config ] && ! chrooted &&
117        egrep -qs 'ltsp|nfs|nbd' /proc/cmdline
118    then
119        export $(
120            . /usr/share/ltsp/ltsp_config >/dev/null
121            echo "LTSP_CLIENT=$LTSP_CLIENT"
122            echo "LTSP_FATCLIENT=$LTSP_FATCLIENT"
123            echo "EPOPTES_CLIENT_VERIFY_CERTIFICATE=$EPOPTES_CLIENT_VERIFY_CERTIFICATE")
124        # LTSP_CLIENT may not be available in system sesssions, if so fake it
125        LTSP_CLIENT=${LTSP_CLIENT:-127.0.0.1}
126    fi
127
128    # LTSP_FATCLIENT may not be available in user sessions, autodetect it
129    if [ -n "$LTSP_CLIENT" ] && [ -z "$LTSP_FATCLIENT" ] &&
130        [ "$UID" -gt 0 ] && [ -x /usr/bin/getltscfg ] &&
131        egrep -qs 'ltsp|nfs|nbd' /proc/cmdline
132    then
133        LTSP_FATCLIENT=True
134    fi
135
136    if my_boolean_is_true "$LTSP_FATCLIENT"; then
137        TYPE="fat"
138    elif [ -n "$LTSP_CLIENT" ]; then
139        TYPE="thin"
140    else
141        TYPE="standalone"
142    fi
143
144    if ( [ "$TYPE" = "thin" ] && [ "$UID" -gt 0 ] ) || chrooted; then
145        SERVER=localhost
146    else
147        SERVER=server
148    fi
149    PORT=789
150
151    export UID TYPE SERVER PORT
152}
153
154fetch_certificate()
155{
156    echo "[fetch_certificate] Comprobando el certificado: epoptes-client -c">> $log_file
157    echo "[fetch_certificate]Debe ser 0 sino muere, UID : $UID" >> $log_file
158    test "$UID" -eq 0 || die "[fetch_certificate] Need to be root to fetch the certificate" >> $log_file
159    mkdir -p /etc/epoptes
160    openssl s_client -connect $SERVER:$PORT < /dev/null \
161        | sed '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/!d' \
162        > /etc/epoptes/server.crt
163    if [ -s /etc/epoptes/server.crt ]; then
164        echo "[fetch_certificate] Successfully fetched certificate from $SERVER:$PORT" >> $log_file
165        echo "[fetch_certificate] Successfully fetched certificate from $SERVER:$PORT"
166        exit 0
167    else
168        echo  "[fetch_certificate] FIRST Failed to fetch certificate from $SERVER:$PORT" >> $log_file
169        sleep 10
170        openssl s_client -connect $SERVER:$PORT < /dev/null \
171        | sed '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/!d' \
172        > /etc/epoptes/server.crt
173         if [ -s /etc/epoptes/server.crt ]; then
174                echo "[fetch_certificate] Successfully fetched certificate from $SERVER:$PORT" >> $log_file
175                echo "[fetch_certificate] Successfully fetched certificate from $SERVER:$PORT"
176                exit 0
177        else
178                die "[fetch_certificate] SECOND Failed to fetch certificate from $SERVER:$PORT"
179        fi
180       
181    fi
182}
183
184fetch_certificate_download()
185{
186    echo "[fetch_certificate_download] FORZANDO EL DOWNLOAD DEL CERTIFICADO">> $log_file
187    echo "[fetch_certificate_download] Comprobando el certificado">> $log_file
188    echo "[fetch_certificate_download] Debe ser 0 sino muere, UID : $UID" >> $log_file
189    test "$UID" -eq 0 || die "[fetch_certificate_download] Need to be root to fetch the certificate" >> $log_file
190    mkdir -p /etc/epoptes
191    openssl s_client -connect $SERVER:$PORT < /dev/null \
192        | sed '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/!d' \
193        > /etc/epoptes/server.crt
194    if [ -s /etc/epoptes/server.crt ]; then
195        echo "[fetch_certificate_download] Successfully fetched certificate from $SERVER:$PORT" >> $log_file
196        echo "[fetch_certificate_download] Successfully fetched certificate from $SERVER:$PORT"
197    else
198        echo  "[fetch_certificate_download] FIRST Failed to fetch certificate from $SERVER:$PORT" >> $log_file
199        sleep 10
200        openssl s_client -connect $SERVER:$PORT < /dev/null \
201        | sed '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/!d' \
202        > /etc/epoptes/server.crt
203         if [ -s /etc/epoptes/server.crt ]; then
204                echo "[fetch_certificate_download] Successfully fetched certificate from $SERVER:$PORT" >> $log_file
205                echo "[fetch_certificate_download] Successfully fetched certificate from $SERVER:$PORT"
206        else
207                die "[fetch_certificate_download] SECOND Failed to fetch certificate from $SERVER:$PORT"
208        fi
209       
210    fi
211}
212
213
214# Main.############################################
215
216# Check the first parameter as it may turn out we don't need to run at all
217case "$1" in
218    -v|--version)
219        echo "$VERSION"
220        exit
221        ;;
222    -h|--help)
223        if [ -x /usr/bin/man ]; then
224            exec man epoptes-client
225        else
226            echo "Usage: $0 [-c|-h|-v] [SERVER] [PORT]"
227            exit 0
228        fi
229        ;;
230    -c|--certificate)
231        need_certificate=True
232        shift
233        ;;
234esac
235
236echo "">> $log_file
237echo "*******DEPURANDO SCRIPT /USR/SBIN/EPOPTES PARA EL *************    USUARIO : $USER      ******">> $log_file
238echo "">> $log_file
239date >> $log_file
240echo "">> $log_file
241echo "$VERSION" >> $log_file
242echo "">> $log_file
243echo "_________MAIN_____________">> $log_file
244discover
245echo "Presesion Lightdm.........."  >> $log_file
246echo "">> $log_file
247ps aux | grep /usr/sbin/epoptes | grep -v root | grep -v "grep" >> $log_file
248USERS_SOCAT=`ps aux | grep /usr/sbin/epoptes | grep -v root | grep -v "grep" | awk '{print $2}' | uniq | wc -l `
249echo "USERS_SOCAT = $USERS_SOCAT">> $log_file;
250if [[ "$MATCH" != ligero  ]]; then
251        if (("$USERS_SOCAT" > 2 )); then
252                echo "Estoy dentro del if matando procesos.......">> $log_file
253                for i in `ps aux | grep /usr/sbin/epoptes | grep -v root | grep -v grep | awk '{print $2}' | uniq`; do
254                        echo "Dentro del FOR para .......">> $log_file
255                        ps -aux | grep $i >> $log_file
256                        echo "Matando el proceso $i"  >> $log_file
257                        kill -9 $i >> $log_file
258                done
259        fi
260fi
261
262
263export VERSION="0.5.7" # Automatically updated by mkdst
264
265
266
267# When called from /etc/xdg/autostart, /sbin is not in the system path.
268PATH="$PATH:/sbin:/usr/sbin"
269
270# When launched as a service, LANG might not be set.
271if [ -z "$LANG" ] && [ -r /etc/default/locale ]; then
272    . /etc/default/locale
273    export LANG
274fi
275
276basic_info
277echo "Capturo basic info UID:$UID TYPE:$TYPE SERVER:$SERVER PORT:$PORT">> $log_file
278# The configuration file overrides the default values
279if [ -f /etc/default/epoptes-client ]; then
280    . /etc/default/epoptes-client
281fi
282# And the command line parameters override the configuration file
283export SERVER=${1:-$SERVER}
284export PORT=${2:-$PORT}
285
286# Provide an easy way to fetch the server certificate
287test -n "$need_certificate" && fetch_certificate
288
289#Nos aseguramos de tener el certificado del server
290echo "Necesito el certificado -> $download_certificate" >> $log_file
291BAJAR_CERT=True
292if [ $download_certificate  =  $BAJAR_CERT ];then
293        echo "Compruebo si el certificado existe..... ">> $log_file
294        if [ ! -s /etc/epoptes/server.crt ]; then
295               echo "FORZADO -> No tengo el certificado debo adquirirlo del server" >> $log_file
296               fetch_certificate_download
297        else
298                echo "Tengo el certificado continua la ejecucion....." >> $log_file
299        fi
300fi
301
302# We don't want the epoptes-client system service running on the epoptes server
303if ( [ $UID -eq 0 ] && [ $TYPE = "standalone" ] && [ -x /usr/bin/epoptes ] ) ||
304    chrooted
305then
306   echo "--Parte del chrooted--" >> $log_file
307   if lliurex-version -t client; then
308        echo "Compruebo como TRUE --> lliurex-version -t client" >> $log_file
309   else
310        echo "FIN compruebo como FALSE --> lliurex-version -t client" >> $log_file
311        exit 0
312   fi
313fi
314
315# Go to the scripts directory, so that we can run them with ./xxx
316cd $(dirname "$0")
317if [ -d ../epoptes-client ]; then
318    cd ../epoptes-client
319else
320    cd /usr/share/epoptes-client
321fi
322
323# Source the lsb init functions, for log_begin_msg.
324# Unfortunately it seems that Centos and Fedora don't have that file.
325if [ -f /lib/lsb/init-functions ]; then
326    . /lib/lsb/init-functions
327else
328    alias log_begin_msg="echo -n"
329fi
330log_begin_msg "Epoptes-client connecting to $SERVER:$PORT..."
331echo "Epoptes-client connecting to $SERVER:$PORT..."
332# Call chain:
333#  * if-up.d executes /usr/sbin/epoptes-client
334#  * then socat is called
335#  * after a successful connection, socat exec's /bin/sh
336#  * and the daemon sends /usr/share/epoptes/client-functions to that shell
337
338# Kill all ghost instances of epoptes-client of the same user.
339# That may happen if network connectivity is lost for a while.
340# Standalone workstations don't hang if the network is down, and nbd might cope
341# with that for LTSP clients, but epoptes kills disconnected epoptes-clients.
342# The current epoptes-client is excluded because it starts with /bin/sh.
343echo "pkill de $UID"
344pkill -U $UID -f '^epoptes-client$'
345
346# Remember the stdout descriptor to use it in the second phase.
347# stdio will be redirected to the server, but stderr will be kept in the
348# local console, to avoid possible noise from applications started in the
349# background.
350# If the callee needs to grab stderr, it can use `cmd 2>&1`.
351exec 5>&1
352
353# Bash supports launching a program with a different zeroth argument,
354# this makes pgrep'ing for epoptes-client easier.
355cmdline='bash -c \"exec -a epoptes-client sh\"'
356
357# Offer an lts.conf (or environment) variable to disable cert verification.
358if my_boolean_is_true "${EPOPTES_CLIENT_VERIFY_CERTIFICATE:-True}"; then
359    cert_param="cafile=/etc/epoptes/server.crt"
360else
361    cert_param="verify=0"
362fi
363
364# Connect to the server, or keep retrying until the server gets online
365# (for standalone workstations booted before the server).
366RUN=1
367salida(){
368        RUN=0
369        echo "Estoy en la funcion de SALIDA de $USER" >> $log_file
370        date >> $log_file
371        echo "Quiero matar el proceso $BASHPID" >> $log_file
372        #kill -9 $BASHPID
373}
374echo "RUN = $RUN"
375test_conn(){
376    if [ -z ${LTSP_CLIENT} ]; then
377        echo "Testeando la funcion CONN $USER">> $log_file
378        #exit 0
379        #RUN=0
380        return 0
381    fi
382    ping -c 2 ${LTSP_CLIENT}
383    if [ $? -eq 0 ]; then
384        echo "Estamos en if del ping -c">> $log_file
385        #exit 0
386        return 0
387    fi
388    echo "vamos a salida">> $log_file
389    salida
390}
391
392trap salida KILL TERM QUIT INT STOP EXIT
393
394echo "-- Funcion Principal para abrir el SOCAT --" >> $log_file
395if [ -s /etc/epoptes/server.crt ] || [ "$cert_param" = "verify=0" ]; then
396   echo "Dentro del if antes del while 1 del usuario $USER" >> $log_file
397   while [ ${RUN} -eq 1 ] && sleep 1; do
398        ALIVE=$(ps ax|grep $PPID|grep -v grep|wc -l)
399        echo "Dentro del While porque el RUN es $RUN para usuario $USER">> $log_file
400        USERS_SOCAT_POST=`ps aux | grep /usr/sbin/epoptes | grep -v root | grep -v "grep" | awk '{print $2}' | uniq | wc -l `
401        echo "Calculando el USERS_SOCAT_POST: $USERS_SOCAT_POST" >> $log_file
402        if (("$USERS_SOCAT_POST" < 3 )) || [[ "$MATCH" == "ligero" ]]; then
403                echo "-----SOCAT se va a ejecutar para el usuario: $USER -----">> $log_file
404                sleep 20
405                echo 'socat openssl-connect:$SERVER:$PORT,$cert_param,interval=60,forever EXEC:"$cmdline",sigint,sigquit,sigterm' >> $log_file
406                socat openssl-connect:$SERVER:$PORT,$cert_param,interval=60,forever EXEC:"$cmdline",sigint,sigquit
407                echo "Muere el SOCAT de $USER: ">> $log_file
408                date >> $log_file
409        fi
410       
411        if [ "x${ALIVE}" != "x1" ]; then 
412                echo "Se aborta el script para el usuario $USER debido al AlIVE">> $log_file
413                exit 1
414        fi
415        echo "Paso del ALIVE y continuo porque RUN: $RUN del usuario $USER">> $log_file
416        test_conn
417        SESSION_GNOME=`ps aux | grep gnome-session | wc -l `
418        if (("$SESSION_GNOME" < 2 )); then
419                date >> $log_file
420                echo "La sesion no esta activa me quedo en la sesion SESSION_GNOME: $SESSION_GNOME modifico el RUN" >> $log_file
421                RUN=0
422        fi
423    done;
424elif [ -f /etc/epoptes/server.crt ]; then
425        echo "Antes del while2 del user: $USER" >> $log_file
426    while [ ${RUN} -eq 1 ] && sleep 1; do
427        ALIVE=$(ps ax|grep $PPID|grep -v grep|wc -l)
428        socat tcp:$SERVER:$PORT,interval=60,forever EXEC:"$cmdline",nofork
429        if [ "x${ALIVE}" != "x1" ]; then 
430            exit 1
431        fi
432        echo "RUN en ELIF es $RUN del usuario $USER">> $log_file
433        test_conn
434    done;
435else
436        echo "en el else del usuario $USER">> $log_file
437    $0 -c
438    exec $0
439fi
440echo "____________FIN_______SCRIPT____________">> $log_file
Note: See TracBrowser for help on using the repository browser.