#!/bin/sh
#
# Copyright © 2021 Daniel Lenski
#
# This file is part of openconnect.
#
# This is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1 of
# the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>

# This test uses LD_PRELOAD
PRELOAD=1
srcdir=${srcdir:-.}
top_builddir=${top_builddir:-..}

. `dirname $0`/common.sh

FINGERPRINT="--servercert=pin-sha256:xp3scfzy3rO"
CERT=$certdir/server-cert.pem
KEY=$certdir/server-key.pem

echo "Testing GlobalProtect auth against fake server ..."

OCSERV=${srcdir}/fake-gp-server.py
launch_simple_sr_server $ADDRESS 443 $CERT $KEY >/dev/null 2>&1
PID=$!
wait_server $PID

SERVURL="https://$ADDRESS:443"
CLIENT="$OPENCONNECT -q --protocol=gp $FINGERPRINT -u test"
export LD_PRELOAD=libsocket_wrapper.so

echo -n "Authenticating with username/password via portal... "
( echo "test" | $CLIENT $SERVURL/portal --cookieonly >/dev/null 2>&1) ||
    fail $PID "Could not receive cookie from fake GlobalProtect server"

echo ok

echo -n "Authenticating with username/password via gateway... "
( echo "test" | $CLIENT $SERVURL/gateway --cookieonly >/dev/null 2>&1) ||
    fail $PID "Could not receive cookie from fake GlobalProtect server"

echo ok

echo "Configuring fake server to present a choice of 3 gateways in the portal."
curl -sk $SERVURL/CONFIGURE -d gateways=foo,bar,baz

echo -n "Authenticating with username/password, and selecting gateway, via portal... "
( echo "test" | $CLIENT $SERVURL/portal --authgroup=bar --cookieonly >/dev/null 2>&1) ||
    fail $PID "Could not receive cookie from fake GlobalProtect server"

echo ok

echo "Configuring fake server to require 2FA-token and to propagate portal authentication to gateway."
curl -sk $SERVURL/CONFIGURE -d portal_2fa=random -d gw_2fa=random -d portal_cookie=portal-userauthcookie

echo -n "Authenticating with username/password/2FA-token via portal, then continuing through 2FA-requiring gateway... "
( echo "test" | $CLIENT $SERVURL/portal --token-mode=totp --token-secret=FAKE --cookieonly >/dev/null 2>&1) ||
    fail $PID "Could not receive cookie from fake GlobalProtect server"

echo ok

echo "Configuring fake server to require SAML for portal and gateway authentication, and to propagate portal authentication to gateway."
curl -sk $SERVURL/CONFIGURE -d portal_saml=prelogin-cookie -d gateway_saml=prelogin-cookie -d portal_cookie=portal-userauthcookie

echo -n "Simulating completed SAML to portal, then continuing through SAML-requiring gateway... "
( echo "prelogin-cookie" | $CLIENT $SERVURL/portal:prelogin-cookie --cookieonly >/dev/null 2>&1) ||
test $? = 2 || # what OpenConnect returns when server rejects cookie upon tunnel connection, as the fake server does
    fail $PID "Something went wrong in fake GlobalProtect server (other than the expected rejection of cookie)"

echo ok

echo "Configuring fake server to require SAML for gateway authentication only."
curl -sk $SERVURL/CONFIGURE -d gateway_saml=prelogin-cookie

echo -n "Simulating completed SAML to gateway... "
( echo "prelogin-cookie" | $CLIENT $SERVURL/gateway:prelogin-cookie --cookieonly >/dev/null 2>&1) ||
test $? = 2 || # what OpenConnect returns when server rejects cookie upon tunnel connection, as the fake server does
    fail $PID "Something went wrong in fake GlobalProtect server (other than the expected rejection of cookie)"

echo ok

echo "Configuring fake server to require 2FA-token for gateway authentication."
curl -sk $SERVURL/CONFIGURE -d gw_2fa=random

echo -n "Authenticating with username/password via portal, then +token via gateway... "
( echo "test" | $CLIENT $SERVURL/portal --token-mode=totp --token-secret=FAKE --cookieonly >/dev/null 2>&1) ||
    fail $PID "Could not receive cookie from fake GlobalProtect server"

echo ok

for cht in XML JS HTML; do
    echo "Configuring fake server to require 2FA-token for gateway authentication ($cht-based challenge)."
    curl -sk $SERVURL/CONFIGURE -d gw_2fa=$cht

    echo -n "Authenticating with username/password/token via gateway... "
    ( echo "test" | $CLIENT $SERVURL/gateway --token-mode=totp --token-secret=FAKE --cookieonly >/dev/null 2>&1) ||
	fail $PID "Could not receive cookie from fake GlobalProtect server"

    echo ok
done

echo "Resetting fake server to default configuration."
curl -sk $SERVURL/CONFIGURE -d ''

echo -n "Authenticating with username/password via portal, then proceeding to tunnel stage... "
echo "test" | $CLIENT $SERVURL/portal >/dev/null 2>&1
test $? = 2 || # what OpenConnect returns when server rejects cookie upon tunnel connection, as the fake server does
    fail $PID "Something went wrong in fake GlobalProtect server (other than the expected rejection of cookie)"

echo ok

echo -n "Authenticating with username/password via portal, then proceeding to tunnel stage (with IPv6 disabled)... "
echo "test" | $CLIENT $SERVURL/portal --disable-ipv6 >/dev/null 2>&1
test $? = 2 || # what OpenConnect returns when server rejects cookie upon tunnel connection, as the fake server does
    fail $PID "Something went wrong in fake GlobalProtect server (other than the expected rejection of cookie)"

echo ok

cleanup

exit 0
