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

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

Fix bug in test to need certificate

  • Property svn:executable set to *
File size: 12.9 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)
35
36if [ ! -f $log_file ]; then
37        touch $log_file
38        chmod 777 $log_file
39fi
40
41
42echo "$VERSION" >> $log_file
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                                need_certificate=True
61                        else
62                                MATCH="Semiligero"
63                                need_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 "Comprobando el certificado">> $log_file
157    echo "Debe ser 0 sino muere, UID : $UID" >> $log_file
158    test "$UID" -eq 0 || die "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 "Successfully fetched certificate from $SERVER:$PORT" >> $log_file
165        echo "Successfully fetched certificate from $SERVER:$PORT"
166        exit 0
167    else
168        echo  "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 "Successfully fetched certificate from $SERVER:$PORT" >> $log_file
175                echo "Successfully fetched certificate from $SERVER:$PORT"
176                exit 0
177        else
178                die "SECOND Failed to fetch certificate from $SERVER:$PORT"
179        fi
180       
181    fi
182}
183
184
185# Main.############################################
186
187echo "">> $log_file
188echo "*******DEPURANDO SCRIPT /USR/SBIN/EPOPTES PARA EL *************    USUARIO : $USER      ******">> $log_file
189echo "">> $log_file
190date >> $log_file
191echo "">> $log_file
192discover
193echo "*************** Presesion Lightdm ************"  >> $log_file
194ps aux | grep /usr/sbin/epoptes | grep -v root | grep -v "grep" >> $log_file
195USERS_SOCAT=`ps aux | grep /usr/sbin/epoptes | grep -v root | grep -v "grep" | awk '{print $2}' | uniq | wc -l `
196echo "USERS_SOCAT = $USERS_SOCAT">> $log_file;
197if [[ "$MATCH" != ligero  ]]; then
198        if (("$USERS_SOCAT" > 2 )); then
199                echo "Estoy dentro del if matando procesos.......">> $log_file
200                for i in `ps aux | grep /usr/sbin/epoptes | grep -v root | grep -v grep | awk '{print $2}' | uniq`; do
201                        echo "Dentro del FOR para .......">> $log_file
202                        ps -aux | grep $i >> $log_file
203                        echo "Matando el proceso $i"  >> $log_file
204                        kill -9 $i >> $log_file
205                done
206        fi
207fi
208
209echo "_________MAIN_____________">> $log_file
210
211
212export VERSION="0.5.7" # Automatically updated by mkdst
213
214# Check the first parameter as it may turn out we don't need to run at all
215case "$1" in
216    -v|--version)
217        echo "$VERSION"
218        exit
219        ;;
220    -h|--help)
221        if [ -x /usr/bin/man ]; then
222            exec man epoptes-client
223        else
224            echo "Usage: $0 [-c|-h|-v] [SERVER] [PORT]"
225            exit 0
226        fi
227        ;;
228    -c|--certificate)
229        need_certificate=True
230        shift
231        ;;
232esac
233
234# When called from /etc/xdg/autostart, /sbin is not in the system path.
235PATH="$PATH:/sbin:/usr/sbin"
236
237# When launched as a service, LANG might not be set.
238if [ -z "$LANG" ] && [ -r /etc/default/locale ]; then
239    . /etc/default/locale
240    export LANG
241fi
242
243basic_info
244echo "Capturo basic info UID:$UID TYPE:$TYPE SERVER:$SERVER PORT:$PORT">> $log_file
245# The configuration file overrides the default values
246if [ -f /etc/default/epoptes-client ]; then
247    . /etc/default/epoptes-client
248fi
249# And the command line parameters override the configuration file
250export SERVER=${1:-$SERVER}
251export PORT=${2:-$PORT}
252
253# Provide an easy way to fetch the server certificate
254echo "Necesito el certificado -> $need_certificate" >> $log_file
255test -n "$need_certificate" && fetch_certificate
256
257
258# We don't want the epoptes-client system service running on the epoptes server
259if ( [ $UID -eq 0 ] && [ $TYPE = "standalone" ] && [ -x /usr/bin/epoptes ] ) ||
260    chrooted
261then
262   echo "--Parte del chrooted--" >> $log_file
263   if lliurex-version -t client; then
264        echo "Compruebo como TRUE --> lliurex-version -t client" >> $log_file
265   else
266        echo "FIN compruebo como FALSE --> lliurex-version -t client" >> $log_file
267        exit 0
268   fi
269fi
270
271# Go to the scripts directory, so that we can run them with ./xxx
272cd $(dirname "$0")
273if [ -d ../epoptes-client ]; then
274    cd ../epoptes-client
275else
276    cd /usr/share/epoptes-client
277fi
278
279# Source the lsb init functions, for log_begin_msg.
280# Unfortunately it seems that Centos and Fedora don't have that file.
281if [ -f /lib/lsb/init-functions ]; then
282    . /lib/lsb/init-functions
283else
284    alias log_begin_msg="echo -n"
285fi
286log_begin_msg "Epoptes-client connecting to $SERVER:$PORT..."
287echo "Epoptes-client connecting to $SERVER:$PORT..."
288# Call chain:
289#  * if-up.d executes /usr/sbin/epoptes-client
290#  * then socat is called
291#  * after a successful connection, socat exec's /bin/sh
292#  * and the daemon sends /usr/share/epoptes/client-functions to that shell
293
294# Kill all ghost instances of epoptes-client of the same user.
295# That may happen if network connectivity is lost for a while.
296# Standalone workstations don't hang if the network is down, and nbd might cope
297# with that for LTSP clients, but epoptes kills disconnected epoptes-clients.
298# The current epoptes-client is excluded because it starts with /bin/sh.
299echo "pkill de $UID"
300pkill -U $UID -f '^epoptes-client$'
301
302# Remember the stdout descriptor to use it in the second phase.
303# stdio will be redirected to the server, but stderr will be kept in the
304# local console, to avoid possible noise from applications started in the
305# background.
306# If the callee needs to grab stderr, it can use `cmd 2>&1`.
307exec 5>&1
308
309# Bash supports launching a program with a different zeroth argument,
310# this makes pgrep'ing for epoptes-client easier.
311cmdline='bash -c \"exec -a epoptes-client sh\"'
312
313# Offer an lts.conf (or environment) variable to disable cert verification.
314if my_boolean_is_true "${EPOPTES_CLIENT_VERIFY_CERTIFICATE:-True}"; then
315    cert_param="cafile=/etc/epoptes/server.crt"
316else
317    cert_param="verify=0"
318fi
319
320# Connect to the server, or keep retrying until the server gets online
321# (for standalone workstations booted before the server).
322RUN=1
323salida(){
324        RUN=0
325        echo "Estoy en la funcion de SALIDA de $USER" >> $log_file
326        date >> $log_file
327        echo "Quiero matar el proceso $BASHPID" >> $log_file
328        #kill -9 $BASHPID
329}
330echo "RUN = $RUN"
331test_conn(){
332    if [ -z ${LTSP_CLIENT} ]; then
333        echo "Testeando la funcion CONN $USER">> $log_file
334        #exit 0
335        #RUN=0
336        return 0
337    fi
338    ping -c 2 ${LTSP_CLIENT}
339    if [ $? -eq 0 ]; then
340        echo "Estamos en if del ping -c">> $log_file
341        #exit 0
342        return 0
343    fi
344    echo "vamos a salida">> $log_file
345    salida
346}
347
348trap salida KILL TERM QUIT INT STOP EXIT
349
350
351if [ -s /etc/epoptes/server.crt ] || [ "$cert_param" = "verify=0" ]; then
352   echo "Dentro del if antes del while 1 del usuario $USER" >> $log_file
353   while [ ${RUN} -eq 1 ] && sleep 1; do
354        ALIVE=$(ps ax|grep $PPID|grep -v grep|wc -l)
355        echo "Dentro del While porque el RUN es $RUN para usuario $USER">> $log_file
356        echo "Haciendo el wait.....Ahora nop" >> $log_file
357        USERS_SOCAT_POST=`ps aux | grep /usr/sbin/epoptes | grep -v root | grep -v "grep" | awk '{print $2}' | uniq | wc -l `
358        echo "Calculado el USERS_SOCAT_POST: $USERS_SOCAT_POST" >> $log_file
359        if (("$USERS_SOCAT_POST" < 3 )) || [[ "$MATCH" == "ligero" ]]; then
360                echo "-----SOCAT se va a ejecutar para el usuario: $USER -----">> $log_file
361                sleep 20
362                echo 'socat openssl-connect:$SERVER:$PORT,$cert_param,interval=60,forever EXEC:"$cmdline",sigint,sigquit,sigterm' >> $log_file
363                socat openssl-connect:$SERVER:$PORT,$cert_param,interval=60,forever EXEC:"$cmdline",sigint,sigquit
364                echo "Muere el SOCAT de $USER: ">> $log_file
365                date >> $log_file
366        fi
367       
368        if [ "x${ALIVE}" != "x1" ]; then
369                echo "Se aborta el script para el usuario $USER debido al AlIVE">> $log_file
370                exit 1
371        fi
372        echo "Paso del ALIVE y continuo porque RUN: $RUN del usuario $USER">> $log_file
373        test_conn
374        SESSION_GNOME=`ps aux | grep gnome-session | wc -l `
375        if (("$SESSION_GNOME" < 2 )); then
376                date >> $log_file
377                echo "La sesion no esta activa me quedo en la sesion SESSION_GNOME: $SESSION_GNOME modifico el RUN" >> $log_file
378                RUN=0
379        fi
380    done;
381elif [ -f /etc/epoptes/server.crt ]; then
382        echo "Antes del while2 del user: $USER" >> $log_file
383    while [ ${RUN} -eq 1 ] && sleep 1; do
384        ALIVE=$(ps ax|grep $PPID|grep -v grep|wc -l)
385        socat tcp:$SERVER:$PORT,interval=60,forever EXEC:"$cmdline",nofork
386        if [ "x${ALIVE}" != "x1" ]; then
387            exit 1
388        fi
389        echo "RUN en ELIF es $RUN del usuario $USER">> $log_file
390        test_conn
391    done;
392else
393        echo "en el else del usuario $USER">> $log_file
394    $0 -c
395    exec $0
396fi
397echo "____________FIN_______SCRIPT____________">> $log_file
Note: See TracBrowser for help on using the repository browser.