Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Cisco Anyconnect CSD wrapper for OpenConnect (exhanced to autodownload and autoupdate hostscan)
#!/bin/bash
# Cisco Anyconnect CSD wrapper for OpenConnect
# Enter your vpn host here
CSD_HOSTNAME=
if [[ -z ${CSD_HOSTNAME} ]]
then
echo "Define CSD_HOSTNAME with vpn-host in script text. Exiting."
exit 1
fi
HOSTSCAN_DIR="$HOME/.cisco/hostscan"
LIB_DIR="$HOSTSCAN_DIR/lib"
BIN_DIR="$HOSTSCAN_DIR/bin"
BINS=("cscan" "cstub" "cnotify")
# parsing command line
shift
URL=
TICKET=
STUB=
GROUP=
CERTHASH=
LANGSELEN=
while [ "$1" ]; do
if [ "$1" == "-ticket" ]; then shift; TICKET=$1; fi
if [ "$1" == "-stub" ]; then shift; STUB=$1; fi
if [ "$1" == "-group" ]; then shift; GROUP=$1; fi
if [ "$1" == "-certhash" ]; then shift; CERTHASH=$1; fi
if [ "$1" == "-url" ]; then shift; URL=$1; fi
if [ "$1" == "-langselen" ];then shift; LANGSELEN=$1; fi
shift
done
ARCH=$(uname -m)
if [[ "$ARCH" == "x86_64" ]]
then
ARCH="linux_x64"
else
ARCH="linux_i386"
fi
# creating dirs
for dir in $HOSTSCAN_DIR $LIB_DIR $BIN_DIR ; do
if [[ ! -f $dir ]]
then
mkdir -p $dir
fi
done
# getting manifest, and checking binaries
wget --no-check-certificate -c "https://${CSD_HOSTNAME}/CACHE/sdesktop/hostscan/$ARCH/manifest" -O "$HOSTSCAN_DIR/manifest"
# generating md5.sum with full paths from manifest
export HOSTSCAN_DIR=$HOSTSCAN_DIR
cat $HOSTSCAN_DIR/manifest | sed -r 's/\(|\)//g' | awk '{ cmd = "find $HOSTSCAN_DIR -iname " $2; while (cmd | getline line) { print $4, line; } }' > $HOSTSCAN_DIR/md5.sum
# check number of files either
MD5_LINES=`wc --lines $HOSTSCAN_DIR/md5.sum | awk '{ print $1; }'`
MANIFEST_LINES=`wc --lines $HOSTSCAN_DIR/manifest | awk '{ print $1; }'`
echo "Got $MANIFEST_LINES files in manifes, locally found $MD5_LINES"
# check md5
md5sum -c $HOSTSCAN_DIR/md5.sum
if [[ "$?" -ne "0" || "$MD5_LINES" -ne "$MANIFEST_LINES" ]]
then
echo "Corrupted files, or whatever wrong with md5 sums, or missing some file"
# just download every file mentioned in manifest (not ideal, but hopefully should be enough)
FILES=( $(cat $HOSTSCAN_DIR/manifest | sed -r 's/\(|\)//g' | awk '{ print $2; }') )
WORK_DIR=`pwd`
TMP_DIR=`mktemp -d` && cd $TMP_DIR
for i in ${FILES[@]} ; do
FILE="$(basename "$i")"
echo "Downloading: $FILE to $TMP_DIR"
wget --no-check-certificate -c "https://${CSD_HOSTNAME}/CACHE/sdesktop/hostscan/$ARCH/$FILE" -O $FILE
# some files are in gz (don't understand logic here)
if [[ ! -f $FILE || ! -s $FILE ]]
then
# remove 0 size files
if [[ ! -s $FILE ]]; then
rm $FILE
fi
echo "Failure on $FILE, trying gz"
FILE_GZ=$FILE.gz
wget --no-check-certificate -c "https://${CSD_HOSTNAME}/CACHE/sdesktop/hostscan/$ARCH/$FILE_GZ" -O $FILE_GZ
gunzip --verbose --decompress $FILE_GZ
fi
# don't know why, but my version of hostscan requires tables to be stored in libs
echo $FILE | grep --extended-regexp --quiet --invert-match ".so|tables.dat"
IS_LIB=$?
if [[ "$IS_LIB" -eq "1" ]]
then
cp --verbose $FILE $LIB_DIR
else
cp --verbose $FILE $BIN_DIR
fi
done
for i in ${BINS[@]} ; do
echo "Setting excecution bit on: $BIN_DIR/$i"
chmod u+x $BIN_DIR/$i
done
cd $WORK_DIR
rm -rf $TMP_DIR
fi
# cstub doesn't care about logging options, sic!
#ARGS="-log debug -ticket $TICKET -stub $STUB -group $GROUP -host $URL -certhash $CERTHASH"
ARGS="-log error -ticket $TICKET -stub $STUB -group $GROUP -host $URL -certhash $CERTHASH"
echo "Launching: $BIN_DIR/cstub $ARGS"
$BIN_DIR/cstub $ARGS

fjaeger commented Jan 9, 2016

Do you know whether this works on a Mac / OS X?

Would it be okay for you if we included a slightly modified version of your script in our commercial VPN client Shimo, which uses open connect internally?

Owner

l0ki000 commented Jan 18, 2016

Sorry for a long pause before reply, github doesn't notified me about your comment :-/

Regarding OS X, it should work since it's utilizing standard commands and programs.
Regarding using it, in short - yes, your are welcome. In long, this script is not production quality, and if you put my name somewhere in "thanks" section that would be great :-)

fjaeger commented Jan 19, 2016

Sure, we will mention you as the original source. Maybe we could even setup a repository for this CSD wrapper script and improve it further?

Another question: Is CSD_HOSTNAME provided by openconnect or do I need to modify the script manually before I connect to a particular VPN gateway address?

morhook commented Jun 24, 2016

@fjaeger you need to put in CSD_HOSTNAME the host you are connecting inside the script (also make a chmod +x to it)

morhook commented Jun 27, 2016

I had to call this script with some special parameters (to avoid some ubuntu specific errors on my specific VPN):

 sudo openconnect --user VPNUSER --csd-user MYLOCALUSER --csd-wrapper ~/.cisco/csd-wrapper.sh --os=mac-intel https://vpn.xxxx.com  

Also, an old download of anyconnect on /opt/cisco produced some ugly Segmentation faults on cstub binary

So I can confirm that it does not work on Mac.. some of the command have different options on MacOS; I get:

`HTTP request sent, awaiting response... 200 OK

The file is already fully retrieved; nothing to do.

sed: illegal option -- r
usage: sed script [-Ealn] [-i extension] [file ...]
sed [-Ealn] [-i extension] [-e script] ... [-f script_file] ... [file ...]
wc: illegal option -- -
usage: wc [-clmw] [file ...]
wc: illegal option -- -
usage: wc [-clmw] [file ...]
Got files in manifes, locally found
`

travishein commented Aug 5, 2016 edited

I have found to make it work on mac, we need to

  • set the ARCH differently. we need to switch this based on uname.
  • use sed -E (instead of sed -r). We need to switch this based on uname.
  • use wc -l. (instead of wc --lines) This is safe to use for Linux too.
  • use cp -v (instead of cp --verpose). This is safe to use for Linux too.
diff -u page csd-wrapper
--- page    2016-08-05 14:58:35.000000000 -0400
+++ csd-wrapper 2016-08-05 14:43:52.000000000 -0400
@@ -2,7 +2,6 @@
 # Cisco Anyconnect CSD wrapper for OpenConnect

 # Enter your vpn host here
-CSD_HOSTNAME=
 if [[ -z ${CSD_HOSTNAME} ]]
 then
     echo "Define CSD_HOSTNAME with vpn-host in script text. Exiting."
@@ -37,14 +36,20 @@
 done


-ARCH=$(uname -m)
-
-if [[ "$ARCH" == "x86_64" ]]
-then
-    ARCH="linux_x64"
-else
-    ARCH="linux_i386"
-fi
+case `uname` in
+  Darwin)
+    ARCH="darwin_i386"
+  ;;
+  linux)
+    ARCH=$(uname -m)
+    if [[ "$ARCH" == "x86_64" ]]     
+    then
+      ARCH="linux_x64"    
+    else
+      ARCH="linux_i386"
+    fi
+  ;;
+esac

 # creating dirs
 for dir in $HOSTSCAN_DIR $LIB_DIR $BIN_DIR ; do
@@ -57,14 +62,23 @@
 # getting manifest, and checking binaries
 wget --no-check-certificate -c "https://${CSD_HOSTNAME}/CACHE/sdesktop/hostscan/$ARCH/manifest" -O "$HOSTSCAN_DIR/manifest"

+case `uname` in
+  Darwin)
+    SED="sed -E";
+  ;;
+  *)
+    SED="sed -r";
+  ;;
+esac;
+
 # generating md5.sum with full paths from manifest
 export HOSTSCAN_DIR=$HOSTSCAN_DIR
-cat $HOSTSCAN_DIR/manifest | sed -r 's/\(|\)//g' | awk '{ cmd = "find $HOSTSCAN_DIR -iname " $2; while (cmd | getline line) { print $4, line; } }' > $HOSTSCAN_DIR/md5.sum
+cat $HOSTSCAN_DIR/manifest | ${SED} 's/\(|\)//g' | awk '{ cmd = "find $HOSTSCAN_DIR -iname " $2; while (cmd | getline line) { print $4, line; } }' > $HOSTSCAN_DIR/md5.sum

 # check number of files either
-MD5_LINES=`wc --lines $HOSTSCAN_DIR/md5.sum | awk '{ print $1; }'`
-MANIFEST_LINES=`wc --lines $HOSTSCAN_DIR/manifest | awk '{ print $1; }'`
-echo "Got $MANIFEST_LINES files in manifes, locally found $MD5_LINES"
+MD5_LINES=`wc -l $HOSTSCAN_DIR/md5.sum | awk '{ print $1; }'`
+MANIFEST_LINES=`wc -l $HOSTSCAN_DIR/manifest | awk '{ print $1; }'`
+echo "Got $MANIFEST_LINES files in manifest, locally found $MD5_LINES"

 # check md5
 md5sum -c $HOSTSCAN_DIR/md5.sum
@@ -72,7 +86,7 @@
 then
     echo "Corrupted files, or whatever wrong with md5 sums, or missing some file"
     # just download every file mentioned in manifest (not ideal, but hopefully should be enough)
-    FILES=( $(cat $HOSTSCAN_DIR/manifest | sed -r 's/\(|\)//g' | awk '{ print $2; }') )
+    FILES=( $(cat $HOSTSCAN_DIR/manifest | ${SED} 's/\(|\)//g' | awk '{ print $2; }') )
     WORK_DIR=`pwd`
     TMP_DIR=`mktemp -d` && cd $TMP_DIR
     for i in ${FILES[@]} ; do
@@ -100,9 +114,9 @@
         IS_LIB=$?
         if [[ "$IS_LIB" -eq "1" ]]
         then
-            cp --verbose $FILE $LIB_DIR
+            cp -v $FILE $LIB_DIR
         else
-            cp --verbose $FILE $BIN_DIR
+            cp -v $FILE $BIN_DIR
         fi

     done

(not sure if its like cool to make my own gist. figured a comment with a diff is OK. let me know if not i guess)

Rthur commented Aug 15, 2016

Your mktemp command doesn't work on OS 10.10 .... needs to be written as "mktemp -d -t some_dir"

dwmw2 commented Dec 15, 2016

I'd love to kill the --no-cert-check from all those wget invocations; that seems wrong. Should we add a download facility to OpenConnect, to use with --servercert md5:$CERTHASH ?

And should we ship this script (or its functionality) as part of OpenConnect itself?

Owner

l0ki000 commented Dec 15, 2016

Gist doesn't inform me about the new comments, unfortunately :-/
However, thanks for all of them and suggestions!

I'll merge diff (thanks, @travishein) and look closely to '--no-cert-hash' option.
As far as I remember, it was applied as wget was whining about certs. Seems like IT sometimes missing the right moment to update them.
And yes, Mac OS X. I was sure that no one using it. Will try to check it.

Regarding including this stuff to OpenConnect... Initially it was a kind of reverse engineering CSD. Not pretty sure that this few lines of junk script worth to be included anywhere. Will think about it a bit more.

Thank you @l0ki000, this Gist helped create a "Cisco Hostscan profile" for vpn-porthole, a Docker based solution to accessing VPNs.

grmpz commented Apr 18, 2017 edited

This is failing on RHE7 distro:
cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.2 (Maipo)

./csd-wrapper.sh
--2017-04-18 14:57:51-- https://[vpn]/CACHE/sdesktop/hostscan/linux_x64/manifest
Resolving [vpn]... XXX.XXX.XXX.XXX
Connecting to [VPN] ([VPN])|XXX.XXX.XXX.XXX|:443... connected.
WARNING: cannot verify [VPN]'s certificate, issued by ‘/O=Cisco/CN=cdca’:
Unable to locally verify the issuer's authority.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest [following]
--2017-04-18 14:57:51-- https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest
Connecting to XXX.XXX.XXX.XXX:443... connected.
WARNING: cannot verify XXX.XXX.XXX.XXX's certificate, issued by ‘/O=Cisco/CN=cdca’:
Unable to locally verify the issuer's authority.
WARNING: certificate common name ‘[VPN]’ doesn't match requested host name ‘XXX.XXX.XXX.XXX’.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest [following]
--2017-04-18 14:57:51-- https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest
Reusing existing connection to XXX.XXX.XXX.XXX:443.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest [following]
--2017-04-18 14:57:51-- https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest
Reusing existing connection to XXX.XXX.XXX.XXX:443.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest [following]
--2017-04-18 14:57:51-- https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest
Reusing existing connection to XXX.XXX.XXX.XXX:443.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest [following]
--2017-04-18 14:57:51-- https:/XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest
Reusing existing connection to XXX.XXX.XXX.XXX:443.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest [following]
--2017-04-18 14:57:51-- https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest
Reusing existing connection to XXX.XXX.XXX.XXX:443.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest [following]
--2017-04-18 14:57:51-- https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest
Reusing existing connection toXXX.XXX.XXX.XXX:443.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest [following]
--2017-04-18 14:57:51-- https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest
Reusing existing connection to XXX.XXX.XXX.XXX:443.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest [following]
--2017-04-18 14:57:51-- https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest
Reusing existing connection to XXX.XXX.XXX.XXX:443.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest [following]
--2017-04-18 14:57:51-- https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest
Reusing existing connection to XXX.XXX.XXX.XXX:443.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest [following]
--2017-04-18 14:57:51-- https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest
Reusing existing connection to XXX.XXX.XXX.XXX:443.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest [following]
--2017-04-18 14:57:51-- https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest
Reusing existing connection to XXX.XXX.XXX.XXX:443.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest [following]
--2017-04-18 14:57:51-- https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest
Reusing existing connection to XXX.XXX.XXX.XXX:443.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest [following]
--2017-04-18 14:57:51-- https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest
Reusing existing connection to XXX.XXX.XXX.XXX:443.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest [following]
--2017-04-18 14:57:51-- https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest
Reusing existing connection to XXX.XXX.XXX.XXX:443.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest [following]
--2017-04-18 14:57:51-- https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest
Reusing existing connection to XXX.XXX.XXX.XXX:443.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest [following]
--2017-04-18 14:57:51-- https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest
Reusing existing connection to XXX.XXX.XXX.XXX:443.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest [following]
--2017-04-18 14:57:51-- https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest
Reusing existing connection to XXX.XXX.XXX.XXX:443.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest [following]
--2017-04-18 14:57:51-- https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest
Reusing existing connection to XXX.XXX.XXX.XXX:443.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest [following]
--2017-04-18 14:57:51-- https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest
Reusing existing connection to XXX.XXX.XXX.XXX:443.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://XXX.XXX.XXX.XXX/CACHE/sdesktop/hostscan/linux_x64/manifest [following]
20 redirections exceeded.
Got 0 files in manifes, locally found 0
md5sum: /home/em7admin/.cisco/hostscan/md5.sum: no properly formatted MD5 checksum lines found
Corrupted files, or whatever wrong with md5 sums, or missing some file
Setting excecution bit on: /home/em7admin/.cisco/hostscan/bin/cscan
chmod: cannot access ‘/home/em7admin/.cisco/hostscan/bin/cscan’: No such file or directory
Setting excecution bit on: /home/em7admin/.cisco/hostscan/bin/cstub
chmod: cannot access ‘/home/em7admin/.cisco/hostscan/bin/cstub’: No such file or directory
Setting excecution bit on: /home/em7admin/.cisco/hostscan/bin/cnotify
chmod: cannot access ‘/home/em7admin/.cisco/hostscan/bin/cnotify’: No such file or directory
Launching: /home/em7admin/.cisco/hostscan/bin/cstub -log error -ticket -stub -group -host -certhash
./csd-wrapper.sh: line 125: /home/em7admin/.cisco/hostscan/bin/cstub: No such file or directory

The 301's are being returned from the VPN endpoint, is this failure because of how that VPN is configured?

bluca commented Jul 4, 2017

@l0ki000 some binaries do not exist in the older versions so the script errors out, here's a simple fix:

@@ -109,7 +109,7 @@
     
     for i in ${BINS[@]} ; do
         echo "Setting excecution bit on: $BIN_DIR/$i"
-        chmod u+x $BIN_DIR/$i
+        test -f $BIN_DIR/$i && chmod u+x $BIN_DIR/$i
     done
     
     cd $WORK_DIR

On Ubuntu 14.04, execution of this script lasts with:

[...]
Setting excecution bit on: /root/.cisco/hostscan/bin/cscan
Setting excecution bit on: /root/.cisco/hostscan/bin/cstub
Setting excecution bit on: /root/.cisco/hostscan/bin/cnotify
Launching: /root/.cisco/hostscan/bin/cstub -log error -ticket  -stub  -group  -host  -certhash 
No value set for `/system/proxy/secure_host'
No value set for `/system/http_proxy/host'

Is that fine? What about the last two lines? I don't have any proxy in my env. I just want to be sure that the wrapper is working as expected.
Until a few days ago I succeded connecting with that command: openconnect -v --os=win --csd-user=root --csd-wrapper=/root/.cisco/csd-wrapper.sh vpnservername (yes, I have to simulate I'm a Windows host, or the connection closes). But now it hangs on wait.html refresh:

Refreshing +CSCOE+/sdesktop/wait.html after 1 second...
GET https://vpnserver/+CSCOE+/sdesktop/wait.html
SSL negotiation with vpnservername
Server certificate verify failed: signer not found
Connected to HTTPS on vpnservername
Got HTTP response: HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Cache-Control: no-cache
Pragma: no-cache
Connection: Close
Date: Fri, 15 Sep 2017 09:08:38 GMT
X-Frame-Options: SAMEORIGIN
HTTP body chunked (-2)

Anyone with the same issue? Every existing post about that issue leads there, but it's not working anymore for me :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment