From mike.gabriel@das-netzwerkteam.de Mon Apr 15 23:08:42 2013 Received: (at 155) by bugs.x2go.org; 15 Apr 2013 21:08:51 +0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on ymir.das-netzwerkteam.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=URIBL_BLOCKED autolearn=unavailable version=3.3.2 Received: from freya.das-netzwerkteam.de (freya.das-netzwerkteam.de [88.198.48.199]) by ymir (Postfix) with ESMTPS id AB1155DB11; Mon, 15 Apr 2013 23:08:42 +0200 (CEST) Received: from grimnir.das-netzwerkteam.de (grimnir.das-netzwerkteam.de [78.46.204.98]) by freya.das-netzwerkteam.de (Postfix) with ESMTPS id 735781837; Mon, 15 Apr 2013 23:08:42 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by grimnir.das-netzwerkteam.de (Postfix) with ESMTP id 4713E3BAE7; Mon, 15 Apr 2013 23:08:42 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at grimnir.das-netzwerkteam.de Received: from grimnir.das-netzwerkteam.de ([127.0.0.1]) by localhost (grimnir.das-netzwerkteam.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 60czUAMA7sQR; Mon, 15 Apr 2013 23:08:41 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by grimnir.das-netzwerkteam.de (Postfix) with ESMTP id D4D6F3BB9B; Mon, 15 Apr 2013 23:08:41 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by grimnir.das-netzwerkteam.de (Postfix) with ESMTP id B44173B9E5; Mon, 15 Apr 2013 23:08:41 +0200 (CEST) Received: by grimnir.das-netzwerkteam.de (Postfix, from userid 33) id ABD1E3BB8B; Mon, 15 Apr 2013 23:08:40 +0200 (CEST) Received: from 77-2-142-46.pool.kielnet.net (77-2-142-46.pool.kielnet.net [46.142.2.77]) by mail.das-netzwerkteam.de (Horde Framework) with HTTP; Mon, 15 Apr 2013 23:08:40 +0200 Message-ID: <20130415230840.103249kxioog6tso@mail.das-netzwerkteam.de> X-Priority: 3 (Normal) Date: Mon, 15 Apr 2013 23:08:40 +0200 From: Mike Gabriel To: Thomas Hanschke , 155@bugs.x2go.org Cc: control@bugs.x2go.org Subject: Re: 25 user logon problem References: <1364484683.17230.2.camel@thh-imedia-S1300> In-Reply-To: <1364484683.17230.2.camel@thh-imedia-S1300> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=_413g2ofty994"; protocol="application/pgp-signature"; micalg="pgp-sha1" Content-Transfer-Encoding: 7bit User-Agent: Internet Messaging Program (IMP) H3 (4.3.4) This message is in MIME format and has been PGP signed. --=_413g2ofty994 Content-Type: multipart/mixed; boundary="=_t5eqxwqwhug" Content-Transfer-Encoding: 7bit This message is in MIME format. --=_t5eqxwqwhug Content-Type: text/plain; charset=UTF-8; DelSp="Yes"; format="flowed" Content-Disposition: inline Content-Transfer-Encoding: quoted-printable tag #155 moreinfo thanks Hi Thomas, thanks for reporting the below issue. On Do 28 M=C3=A4r 2013 16:31:23 CET Thomas Hanschke wrote: > I have 25 thinclients (wyse with windows7 embedded) in a classroom. > If more than 2 or 3 clients log on at exactly the same time, some of > them stop at the black screen before the gray X2Go Logo appears. > There is no error message. With a little timeshift of 2 or 3 seconds > between the logons, there are no problems. > > I suggest a while-loop in x2gostartagent that looped through the > displays until it had a valid display and free ports. I have attached a slightly modified x2gostartagent script and patch =20 file that document the changes to this mail. Please copy the x2gostartagent script to /usr/bin/x2gostartagent on =20 the server and report back if the performed modification fixes your =20 25-user-issue. @Devs: I suspect we have to query x2gogetport 3x times during one run =20 of x2gostartagent to make sure that more-than-one instances of =20 x2gostartagent (run by different users at the very same time, a =20 typical class room situation) do not interfere with each other. This =20 probably has to happen in x2goresume-session, as well. I am not 100% sure if the modified x2gostartagent reduces the reported =20 issue to zero, but my guess is that the reported issue should go down =20 in occurrence tremendously. Please test with your setup and give feedback. Greets+thanks, Mike --=20 DAS-NETZWERKTEAM mike gabriel, rothenstein 5, 24214 neudorf-bornstein fon: +49 (1520) 1976 148 GnuPG Key ID 0x25771B31 mail: mike.gabriel@das-netzwerkteam.de, http://das-netzwerkteam.de freeBusy: https://mail.das-netzwerkteam.de/freebusy/m.gabriel%40das-netzwerkteam.de.xf= b --=_t5eqxwqwhug Content-Type: application/x-sh; name="x2gostartagent" Content-Disposition: attachment; filename="x2gostartagent" Content-Transfer-Encoding: 7bit #!/bin/bash # Copyright (C) 2007-2012 X2Go Project - http://wiki.x2go.org # # 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 2 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, write to the # Free Software Foundation, Inc., # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. # # Copyright (C) 2007-2012 Oleksandr Shneyder # Copyright (C) 2007-2012 Heinz-Markus Graesing X2GO_LIB_PATH="$(x2gopath libexec)"; $X2GO_LIB_PATH/x2gosyslog "$0" "info" "$(basename $0) called with options: $@" X2GO_PORT=49 #First port for X2GO=50 SSH_PORT=30000 #First ssh port 30001 X2GO_ROOT="${HOME}/.x2go" export NX_ROOT=$X2GO_ROOT if [ -r /etc/x2go/x2goagent.options ]; then source /etc/x2go/x2goagent.options fi if [ -z "$X2GO_NXAGENT_OPTIONS" ]; then X2GO_NXAGENT_OPTIONS="$X2GO_NXAGENT_DEFAULT_OPTIONS" fi REMOTE=localhost X2GO_CLIENT=`echo $SSH_CLIENT | awk '{print $1}'` $X2GO_LIB_PATH/x2gosyslog "$0" "debug" "client announced itself as ,,$X2GO_CLIENT''" X2GO_GEOMETRY="$1"; shift X2GO_LINK="$1"; shift X2GO_PACK="$1"; shift X2GO_TYPE="$1"; shift X2GO_KBD_LAYOUT="$1"; shift X2GO_KBD_TYPE="$1"; shift X2GO_SET_KBD="$1"; shift X2GO_STYPE="$1"; shift X2GO_CMD="$1"; shift X2GO_RESIZE=0 X2GO_FULLSCREEN=0 XAUTHORITY=${XAUTHORITY:-"$HOME/.Xauthority"} if [ "$X2GO_STYPE" == "S" ]; then SHADOW_MODE=`echo $X2GO_CMD |awk '{split($0,a,"XSHAD"); print a[1]}'` SHADOW_USER=`echo $X2GO_CMD |awk '{split($0,a,"XSHAD"); print a[2]}'` SHADOW_DESKTOP=`echo $X2GO_CMD |awk '{split($0,a,"XSHAD"); print a[3]}'` test -z $1 && { # can this line be removed? #echo "suser $SHADOW_USER user $USER " >> /tmp/uagent $X2GO_LIB_PATH/x2gosyslog "$0" "debug" "shadow session requested: mode $SHADOW_MODE, user: $SHADOW_USER, desktop: $SHADOW_DESKTOP" } || { SHADREQ_USER="$1"; shift $X2GO_LIB_PATH/x2gosyslog "$0" "debug" "preparing shadow session request for user $SHADREQ_USER, agent starts for user ${USER}" } if [ "$SHADOW_USER" != "$USER" ]; then $X2GO_LIB_PATH/x2gosyslog "$0" "notice" "user ,,$USER'' requests desktop sharing from user ,,$SHADOW_USER'' for desktop ,,$SHADOW_DESKTOP''" $X2GO_LIB_PATH/x2gosyslog "$0" "debug" "executing command: x2godesktopsharing client $X2GO_CLIENT $X2GO_GEOMETRY $X2GO_LINK $X2GO_PACK $X2GO_TYPE $X2GO_KBD_LAYOUT $X2GO_KBD_TYPE $X2GO_SET_KBD $X2GO_STYPE $X2GO_CMD $USER" OUTPUT=`x2godesktopsharing client "$X2GO_CLIENT" "$X2GO_GEOMETRY" "$X2GO_LINK" "$X2GO_PACK" "$X2GO_TYPE" "$X2GO_KBD_LAYOUT" "$X2GO_KBD_TYPE" "$X2GO_SET_KBD" "$X2GO_STYPE" "$X2GO_CMD" "$USER"` $X2GO_LIB_PATH/x2gosyslog "$0" "debug" "command result is: $OUTPUT" if [ "$OUTPUT" == "DENY" ]; then echo "ACCESS DENIED" 1>&2 $X2GO_LIB_PATH/x2gosyslog "$0" "err" "ERROR: user $SHADOW_USER denied desktop sharing session" exit -1 fi X2GO_COOKIE=`echo $OUTPUT | awk '{print $2}'` X2GO_PORT=`echo $OUTPUT | awk '{print $1}'` $X2GO_LIB_PATH/x2gosyslog "$0" "debug" "received shadow session information: cookie: $X2GO_COOKIE, port: $X2GO_PORT" xauth -f "$XAUTHORITY" add "${HOSTNAME}/unix:${X2GO_PORT}" MIT-MAGIC-COOKIE-1 "${X2GO_COOKIE}" xauth -f "$XAUTHORITY" add "${HOSTNAME}:${X2GO_PORT}" MIT-MAGIC-COOKIE-1 "${X2GO_COOKIE}" echo $X2GO_PORT echo $X2GO_COOKIE echo $OUTPUT | awk '{print $3}' echo $OUTPUT | awk '{print $4}' echo $OUTPUT | awk '{print $5}' echo $OUTPUT | awk '{print $6}' echo $OUTPUT | awk '{print $7}' exit 0 fi fi LIMIT=`x2gosessionlimit` LWORD=`echo $LIMIT | awk '{print $1}'` if [ "$LWORD" == "LIMIT" ]; then echo $LIMIT 1>&2 exit -1 fi export NX_CLIENT="$X2GO_LIB_PATH/x2gosuspend-agent" COLORDEPTH=`echo $X2GO_TYPE | awk '{split($0,a,"-depth_"); print a[2]}'` SESSION_TYPE="D" NOEXITPARAM="" if [ "$X2GO_STYPE" == "R" ]; then SESSION_TYPE="R" elif [ "$X2GO_STYPE" == "P" ]; then SESSION_TYPE="R" NOEXITPARAM="-norootlessexit" elif [ "$X2GO_STYPE" == "S" ]; then SESSION_TYPE="S" fi if [ "$X2GO_CLIENT" == "" ]; then X2GO_CLIENT="$HOSTNAME" fi USED_DISPLAYS=`$X2GO_LIB_PATH/x2gogetdisplays $HOSTNAME` #Get all used in system ports from X2Go database and ss output ss=$(PATH="$PATH:/usr/sbin:/sbin" type -P ss); USED_NONSSH_PORTS=$( "$ss" -lnt | perl -lne 'print$d{$2}="|$2|"if/^(\S+\s+){2}\S+:(\d+)/&&!exists$d{$2}'; ); while [ "$OUTPUT" != "inserted" ]; do X2GO_PORT=$(($X2GO_PORT + 1)) X2GO_PORT=`echo "for(\\$i=$X2GO_PORT;\\$br ne \"true\";\\$i++){ if(\"$USED_DISPLAYS\" =~ m/\\|\\$i\\|/){\\$br=\"false\";}else{\\$br=\"true\";print \\$i;}}"|perl` #Test if the session is already in use. nxagent uses 6000+DISPLAY to open a port. Therefore this must be tested, too. NX_PORT=$(($X2GO_PORT + 6000)) if [ -e "/tmp/.X${X2GO_PORT}-lock" ] || [ -e "/tmp/.X11-unix/X${X2GO_PORT}" ] || grep -q "|${NX_PORT}|" <<<$USED_NONSSH_PORTS ; then OUTPUT="XXX" else SESSION_NAME="${USER}-${X2GO_PORT}-`date +\"%s\"`" if [ "$COLORDEPTH" != "" ]; then SESSION_NAME="${SESSION_NAME}_st${SESSION_TYPE}${X2GO_CMD}_dp${COLORDEPTH}" SESSION_NAME=`echo "$SESSION_NAME" | sed -e "s/:/PP/g"` fi OUTPUT=`$X2GO_LIB_PATH/x2goinsertsession "$X2GO_PORT" "$HOSTNAME" "$SESSION_NAME"` fi done while [ "$GR_PORT" == "" ] || [ "$SOUND_PORT" == "" ] || [ "$FS_PORT" == "" ]; do OUTPUT="" USED_PORTS=`echo -e "$(\"$X2GO_LIB_PATH/x2gogetports\" \"$HOSTNAME\")\n$USED_NONSSH_PORTS"` while [ "$OUTPUT" != "inserted" ]; do SSH_PORT=$(($SSH_PORT + 1)) #get free port SSH_PORT=`echo "for(\\$i=$SSH_PORT;\\$br ne \"true\";\\$i++){ if(\"$USED_PORTS\" =~ m/\\|\\$i\\|/){\\$br=\"false\";}else{\\$br=\"true\";print \\$i;}}"|perl` #check if port in /etc/services SERV=`grep $SSH_PORT /etc/services` if [ "$SERV" == "" ]; then OUTPUT=`$X2GO_LIB_PATH/x2goinsertport "$HOSTNAME" "$SESSION_NAME" "$SSH_PORT"` fi done if [ "$GR_PORT" == "" ]; then GR_PORT="$SSH_PORT" elif [ "$SOUND_PORT" == "" ]; then SOUND_PORT="$SSH_PORT" else FS_PORT="$SSH_PORT" fi done if [ "$X2GO_GEOMETRY" == "" ]; then X2GO_GEOMETRY=fullscreen fi if [ "$X2GO_GEOMETRY" == "fullscreen" ]; then X2GO_RESIZE=1 X2GO_FULLSCREEN=1 fi if [ "$X2GO_STYPE" == "S" ]; then X2GO_GEOMETRY=`DISPLAY="$SHADOW_DESKTOP" xwininfo -root | grep geometry` X2GO_GEOMETRY=`echo "$X2GO_GEOMETRY" | sed -e "s/ //g"` X2GO_GEOMETRY=`echo "$X2GO_GEOMETRY" | sed -e "s/-geometry//"` fi SESSION_DIR="${X2GO_ROOT}/C-${SESSION_NAME}" # do not use $TMP or $TEMP here, the session.log file location has to be accessible by root SESSION_LOG="/tmp/.x2go-${USER}/session-C-${SESSION_NAME}.log" mkdir -p $(dirname "${SESSION_LOG}") chmod -f 0700 $(dirname "${SESSION_LOG}") touch "${SESSION_LOG}" chmod -f 0600 "${SESSION_LOG}" ln -s "${SESSION_DIR}/session.log" "${SESSION_LOG}" if [ ! -d "$X2GO_ROOT" ]; then mkdir "$X2GO_ROOT" fi if [ ! -d "$X2GO_ROOT/ssh" ]; then mkdir "$X2GO_ROOT/ssh" fi if [ ! -d "$SESSION_DIR" ]; then mkdir "$SESSION_DIR" fi X2GO_COOKIE=`mcookie` PATH="${PATH}:${X2GO_BIN}/" export PATH xauth -f "$XAUTHORITY" add "${HOSTNAME}/unix:${X2GO_PORT}" MIT-MAGIC-COOKIE-1 "${X2GO_COOKIE}" xauth -f "$XAUTHORITY" add "${HOSTNAME}:${X2GO_PORT}" MIT-MAGIC-COOKIE-1 "${X2GO_COOKIE}" if [ "$X2GO_SET_KBD" == "0" ] || [ "$X2GO_KBD_TYPE" == "auto" ];then X2GO_HOST="nx/nx,link=${X2GO_LINK},pack=${X2GO_PACK},limit=0,root=${SESSION_DIR},cache=8M,images=32M,type=${X2GO_TYPE},id=${SESSION_NAME},cookie=$X2GO_COOKIE,errors=${SESSION_LOG},kbtype=null/null,geometry=${X2GO_GEOMETRY},resize=${X2GO_RESIZE},fullscreen=${X2GO_FULLSCREEN},accept=${REMOTE},listen=${GR_PORT},client=linux,menu=0" else X2GO_HOST="nx/nx,link=${X2GO_LINK},pack=${X2GO_PACK},limit=0,root=${SESSION_DIR},cache=8M,images=32M,type=${X2GO_TYPE},id=${SESSION_NAME},cookie=$X2GO_COOKIE,errors=${SESSION_LOG},kbtype=${X2GO_KBD_TYPE},geometry=${X2GO_GEOMETRY},resize=${X2GO_RESIZE},fullscreen=${X2GO_FULLSCREEN},accept=${REMOTE},listen=${GR_PORT},client=linux,menu=0" fi echo "${X2GO_HOST}:${X2GO_PORT}" >"${SESSION_DIR}/options" NX_AGENT=":${X2GO_PORT}" SAVED_DISPLAY="$DISPLAY" DISPLAY="nx/nx,options=${SESSION_DIR}/options:${X2GO_PORT}" export DISPLAY if [ "$X2GODPI" == "" ]; then X2GODPIOPTION_="" else X2GODPIOPTION_="-dpi $X2GODPI" fi NOLISTOPT="" if [ "$X2GOXDMCP" == "" ] ;then XDMCPOPT="" NOLISTOPT="-nolisten tcp" else XDMCPOPT="-query $X2GOXDMCP" fi # run x2goserver-extensions for pre-start x2gofeature X2GO_RUN_EXTENSIONS &>/dev/null && x2goserver-run-extensions "$SESSION_NAME" pre-start || true SESSION_WINDOW_TITLE="X2GO-${SESSION_NAME}" if [ "$X2GO_STYPE" == "S" ]; then # set NX_TEMP to /tmp, make sure x2goagent starts when pam_tmpdir.so is in use NX_TEMP=/tmp x2goagent $X2GO_NXAGENT_OPTIONS $NOLISTOPT $X2GODPIOPTION_ -$SESSION_TYPE -auth "$XAUTHORITY" -shadow $SHADOW_DESKTOP -shadowmode $SHADOW_MODE -geometry ${X2GO_GEOMETRY} -name "${SESSION_WINDOW_TITLE}" "${NX_AGENT}" 2>"${SESSION_LOG}" & else # set NX_TEMP to /tmp, make sure x2goagent starts when pam_tmpdir.so is in use NX_TEMP=/tmp x2goagent $X2GO_NXAGENT_OPTIONS $NOLISTOPT $X2GODPIOPTION_ $XDMCPOPT -$SESSION_TYPE $NOEXITPARAM -auth "$XAUTHORITY" -geometry ${X2GO_GEOMETRY} -name "${SESSION_WINDOW_TITLE}" "${NX_AGENT}" 2>"${SESSION_LOG}" & fi X2GO_AGENT_PID=$! X2GO_AGENT_RETVAL=$? test $X2GO_AGENT_RETVAL && { $X2GO_LIB_PATH/x2gosyslog "$0" "notice" "successfully started X2Go agent session with ID $SESSION_NAME" # run x2goserver-extensions for post-start x2gofeature X2GO_RUN_EXTENSIONS &>/dev/null && x2goserver-run-extensions "$SESSION_NAME" post-start || true } || { $X2GO_LIB_PATH/x2gosyslog "$0" "err" "ERROR: failed to start X2Go agent session with ID $SESSION_NAME" # run x2goserver-extensions for fail-start x2gofeature X2GO_RUN_EXTENSIONS &>/dev/null && x2goserver-run-extensions "$SESSION_NAME" fail-start || true } X2GO_SND_PORT=1024 $X2GO_LIB_PATH/x2gocreatesession "$X2GO_COOKIE" "$X2GO_AGENT_PID" "$X2GO_CLIENT" "$GR_PORT" "$SOUND_PORT" "$FS_PORT" "$SESSION_NAME" > /dev/null if [ "$X2GO_SET_KBD" == "0" ] || [ "$X2GO_KBD_TYPE" != "auto" ]; then $X2GO_LIB_PATH/x2gosyslog "$0" "info" "blocking creation of agent's keyboard file ${SESSION_DIR}/keyboard as requested by session startup command" mkdir -p ${SESSION_DIR}/keyboard fi echo $X2GO_PORT echo $X2GO_COOKIE echo $X2GO_AGENT_PID echo $SESSION_NAME echo $GR_PORT echo $SOUND_PORT echo $FS_PORT --=_t5eqxwqwhug Content-Type: text/x-patch; charset=UTF-8; name="25-user-x2goserver.patch" Content-Disposition: attachment; filename="25-user-x2goserver.patch" Content-Transfer-Encoding: 7bit diff --git a/x2goserver/bin/x2gostartagent b/x2goserver/bin/x2gostartagent index 45b3ba5..0d43de7 100755 --- a/x2goserver/bin/x2gostartagent +++ b/x2goserver/bin/x2gostartagent @@ -135,8 +135,7 @@ USED_DISPLAYS=`$X2GO_LIB_PATH/x2gogetdisplays $HOSTNAME` #Get all used in system ports from X2Go database and ss output ss=$(PATH="$PATH:/usr/sbin:/sbin" type -P ss); -USED_PORTS=$( - "$X2GO_LIB_PATH/x2gogetports" "$HOSTNAME"; +USED_NONSSH_PORTS=$( "$ss" -lnt | perl -lne 'print$d{$2}="|$2|"if/^(\S+\s+){2}\S+:(\d+)/&&!exists$d{$2}'; ); @@ -144,12 +143,12 @@ USED_PORTS=$( while [ "$OUTPUT" != "inserted" ]; do X2GO_PORT=$(($X2GO_PORT + 1)) X2GO_PORT=`echo "for(\\$i=$X2GO_PORT;\\$br ne \"true\";\\$i++){ if(\"$USED_DISPLAYS\" =~ m/\\|\\$i\\|/){\\$br=\"false\";}else{\\$br=\"true\";print \\$i;}}"|perl` - + #Test if the session is already in use. nxagent uses 6000+DISPLAY to open a port. Therefore this must be tested, too. NX_PORT=$(($X2GO_PORT + 6000)) if [ -e "/tmp/.X${X2GO_PORT}-lock" ] || [ -e "/tmp/.X11-unix/X${X2GO_PORT}" ] || - grep -q "|${NX_PORT}|" <<<$USED_PORTS ; then + grep -q "|${NX_PORT}|" <<<$USED_NONSSH_PORTS ; then OUTPUT="XXX" else SESSION_NAME="${USER}-${X2GO_PORT}-`date +\"%s\"`" @@ -164,6 +163,7 @@ done while [ "$GR_PORT" == "" ] || [ "$SOUND_PORT" == "" ] || [ "$FS_PORT" == "" ]; do OUTPUT="" + USED_PORTS=`echo -e "$(\"$X2GO_LIB_PATH/x2gogetports\" \"$HOSTNAME\")\n$USED_NONSSH_PORTS"` while [ "$OUTPUT" != "inserted" ]; do SSH_PORT=$(($SSH_PORT + 1)) --=_t5eqxwqwhug-- --=_413g2ofty994 Content-Type: application/pgp-signature Content-Description: Digitale PGP-Unterschrift Content-Disposition: inline Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) iQIcBAABAgAGBQJRbGxYAAoJEJr0azAldxsxXwwP/0Q4M632J5nYtPn2rclCaLQh styLZ8Su5mgyQB+b7qolvxC4owpwYQ0fexXIhHAclOQzx2UAnGfAKZhSgZRmnXEY z9bIT/hkZavk1a6Adru+yFm4VvitIyT2w66FNus8Pf5evisYsSDCMA+0Slg8v/RB Ht21jh+y/ndAU8XUzx4EUJDqSno1FKegpinGVv7wpT/noDOvpmWfSEEd9aHyD6GM KTo9qESAL+vbdcH/FMJn+gOlW9YzNOwb83Ub98FTxA9VU9n9InEg3BxIwI5hZ0vM K5VDcVvZfuqoAKW12xcGKxMLYtXix4g2TQwob4xGY9I+NTVre3tKGhv+VNdsuN0a jKI1AXZ6VmylnE1qVIB+MfuIKw4CCuHYzf8LobnLWzShpAKdUXm0uYL3zouKeJNc DEumyks2y88Y0lzLikSOC79brsA+VG/rEKi2TNXGtRJJM9h0rGLX9ROjHQAtMcAh RXKtpqRwI2Hp2j/EWXSvnRfd24ZXJ4aQ04o0PlW1+6W3Qz1kj1baoVDmPEatGCB+ tFdvY1SThKi+8zeAe7y7FMv00toZe365Urdd6G5iIj+Q8kn+4c5ckwjcoigVHOSL Rburc8NZJaIupovoPKQj5EjBWEqTLDsFcAu8X7gm9s5ho5ZxSUeUtElq9GHC48Iz wqH+SZJY7y3NKlqPoDpX =kCJ9 -----END PGP SIGNATURE----- --=_413g2ofty994--