Cisco Secure Client Uninstall Script (5.1.2.42)

tgd
New Contributor II

Hello Jamf Community,

 

iam looking for a Script to uninstall the Cisco Client Silent.

I have a script that does it, but the Users will always get a Pop-Up Message that the Socket Filter needs Admin Permission. You can ignore the window, and it is uninstalled, but I would like to have it more clean.

 

Greetings TGD

3 REPLIES 3

obi-k
Valued Contributor II

Are you running this script?

 

#!/bin/bash

/opt/cisco/secureclient/bin/cisco_secure_client_uninstall.sh

 

exit 0

JMontey1
New Contributor II

If you use the XML custom setup, this pop-up doesn't appear. Would highly recommend but takes some time to setup. https://docs.umbrella.com/umbrella-user-guide/docs/customize-macos-installation-of-cisco-secure-clie...

Otherwise, I had to make a script to make the user an admin, install the software, remove the components (thousand eyes, DART, etc...), and then demote the user admin rights. This way the user can at least use their credentials to accept or cancel out. We found an issue with the umbrella going this route, that the umbrella wasn't active until after the first time the user connected to the VPN. 

CSCC-JS
Contributor III

I used Suspicious Package https://mothersruin.com/software/SuspiciousPackage/ to copy out uninstall script(s) from the pkg installer(s). To make back up "clean up" removal policies when the normal process (invoke the uninstall script) fails.

Here's the VPN/VPN Socket removal script from the pkg (but won't remove the other module(s) from 5.1.2.42

 

 

 

#!/bin/bash
INSTPREFIX="/opt/cisco/secureclient"
BINDIR="${INSTPREFIX}/bin"
PLUGINDIR="${BINDIR}/plugins"
LIBDIR="${INSTPREFIX}/lib"
PROFDIR="${INSTPREFIX}/vpn/profile"
MGMTPROFDIR="${INSTPREFIX}/vpn/profile/mgmttun"
SCRIPTDIR="${INSTPREFIX}/vpn/script"
HELPDIR="${INSTPREFIX}/help"
KEXTDIR="/Library/Application Support/Cisco/Cisco Secure Client"
APPDIR="/Applications/Cisco"
GUIAPP="Cisco Secure Client.app"
NWEXT_KDF_APP="Cisco Secure Client - Socket Filter.app"
UNINSTALLER="Uninstall Cisco Secure Client.app"
LAUNCHD_DAEMON_DIR="/Library/LaunchDaemons"
LAUNCHD_DAEMON_VPNAGENT_FILE="com.cisco.secureclient.vpnagentd.plist"
LAUNCHD_AGENT_DIR="/Library/LaunchAgents"
LAUNCHD_AGENT_GUI_FILE="com.cisco.secureclient.gui.plist"
LAUNCHD_AGENT_NOTIFICATION_FILE="com.cisco.secureclient.vpn.notification.plist"
ACMANIFESTDAT="${INSTPREFIX}/VPNManifest.dat"
VPNMANIFEST="ACManifestVPN.xml"
LOGDIR="/var/log/secureclient"
UNINSTALLLOG="${LOGDIR}/csc_vpn_uninstall.log"
KDFDIR="${INSTPREFIX}/kdf"
KDF_BINDIR="${KDFDIR}/bin"
KDF_LIBDIR="${KDFDIR}/lib"
INSTALL_DIR="${INSTPREFIX}/install"
COMPONENT_DIR="${INSTALL_DIR}/component"
DEPENDENCY_DIR="${INSTALL_DIR}/dependency"
SERVICE_APP="Cisco Secure Client - AnyConnect VPN Service.app"

CSC_VPN_PACKAGE_ID=com.cisco.pkg.anyconnect.vpn

# When AnyConnect VPN is being uninstalled, the plugins for
# modules that depend on VPN must also be removed. This is
# done to ensure that AnyConnect VPN and dependent modules 
# have same version.
#
VPN_DEPENDENT_FILELIST=("${PLUGINDIR}/libacampctrl.dylib" \
                        "${PLUGINDIR}/libacampshim.dylib" \
                        "${PLUGINDIR}/libacisectrl.dylib" \
                        "${PLUGINDIR}/libaciseshim.dylib" \
                        "${PLUGINDIR}/libacnvmctrl.dylib" \
                        "${PLUGINDIR}/libacswgplugin.dylib" \
                        "${PLUGINDIR}/libacumbrellaapi.dylib" \
                        "${PLUGINDIR}/libacumbrellactrl.dylib" \
                        "${PLUGINDIR}/libacumbrellaplugin.dylib" \
                        "${PLUGINDIR}/csc_sfpuiplugin.dylib")

# Array of files to remove
FILELIST=("${BINDIR}/vpnagentd" \
          "${BINDIR}/vpn_uninstall.sh" \
          "${BINDIR}/cisco_secure_client_uninstall.sh" \
          "${BINDIR}/vpn" \
          "${BINDIR}/vpnmgmttun" \
          "${BINDIR}/acextwebhelper" \
          "${BINDIR}/acinstallhelper" \
          "${BINDIR}/vpndownloader.app" \
          "${BINDIR}/UpdateComponentManifest.json" \
          "${BINDIR}/manifesttool" \
          "${BINDIR}/manifesttool_vpn" \
          "${BINDIR}/SetUIDTool_vpn" \
          "${BINDIR}/Cisco Secure Client - Web Browser.app" \
          "${INSTPREFIX}/AnyConnectLocalPolicy.xsd" \
          "${INSTPREFIX}/gui_keepalive" \
          "${INSTPREFIX}/OpenSource.html" \
          "${INSTPREFIX}/update.txt" \
          "${INSTPREFIX}/${VPNMANIFEST}" \
          "${LIBDIR}/libacciscossl.dylib" \
          "${LIBDIR}/libacciscocrypto.dylib" \
          "${LIBDIR}/libaccurl.4.dylib" \
          "${LIBDIR}/libboost_atomic.dylib" \
          "${LIBDIR}/libboost_filesystem.dylib" \
          "${LIBDIR}/libboost_system.dylib" \
          "${LIBDIR}/libboost_thread.dylib" \
          "${LIBDIR}/libboost_date_time.dylib" \
          "${LIBDIR}/libboost_chrono.dylib" \
          "${LIBDIR}/libvpncommon.dylib" \
          "${LIBDIR}/libvpncommoncrypt.dylib" \
          "${LIBDIR}/libvpnapi.dylib" \
          "${LIBDIR}/libacruntime.dylib" \
          "${PLUGINDIR}/libvpnipsec.dylib" \
          "${PLUGINDIR}/libacfeedback.dylib" \
          "${PLUGINDIR}/libacwebhelper.dylib" \
          "${PLUGINDIR}/libvpnapishim.dylib" \
          "${PLUGINDIR}/libacdownloader.dylib" \
          "${PROFDIR}/AnyConnectProfile.xsd" \
          "${MGMTPROFDIR}/AnyConnectProfile.xsd" \
          "${LAUNCHD_DAEMON_DIR}/${LAUNCHD_DAEMON_VPNAGENT_FILE}" \
          "${LAUNCHD_AGENT_DIR}/${LAUNCHD_AGENT_GUI_FILE}" \
          "${LAUNCHD_AGENT_DIR}/${LAUNCHD_AGENT_NOTIFICATION_FILE}" \
          "${APPDIR}/${GUIAPP}" \
          "${APPDIR}/${UNINSTALLER}" \
          "${KEXTDIR}/acsock.kext" \
          "${KDFDIR}/gui_kext.plist" \
          "${BINDIR}/Cisco Secure Client - Notification.app" \
          "${KDF_BINDIR}/acsocktool" \
          "${KDF_LIBDIR}/libacsock_api_common.dylib" \
          "${COMPONENT_DIR}/acsock64.json" \
          "${COMPONENT_DIR}/acsock64-kext.json" \
          "${COMPONENT_DIR}/acsock-arm64.json" \
          "${COMPONENT_DIR}/acsock-arm64-kext.json" \
          "${DEPENDENCY_DIR}/vpn_manifest.json" \
          ${VPN_DEPENDENT_FILELIST[@]})

# Create log directory if not exist
if [ ! -d ${LOGDIR} ]; then
  mkdir -p ${LOGDIR} >/dev/null 2>&1
fi

echo "Uninstalling Cisco Secure Client..."
echo "Uninstalling Cisco Secure Client..." > "${UNINSTALLLOG}"
echo `whoami` "invoked $0 from " `pwd` " at " `date` >> "${UNINSTALLLOG}"

# Check for root privileges
if [ `whoami` != "root" ]; then
  echo "Sorry, you need super user privileges to run this script."
  echo "Sorry, you need super user privileges to run this script." >> "${UNINSTALLLOG}"
  exit 1
fi

IS_UPGRADE=${1-false}

# update the VPNManifest.dat
echo "${BINDIR}/manifesttool -x ${INSTPREFIX} ${INSTPREFIX}/${VPNMANIFEST}" >> "${UNINSTALLLOG}"
${BINDIR}/manifesttool -x ${INSTPREFIX} ${INSTPREFIX}/${VPNMANIFEST} >> "${UNINSTALLLOG}"

OS_VER_MAJOR=$(sw_vers -productVersion | awk -F. '{ print $1; }')
OS_VER_MINOR=$(sw_vers -productVersion | awk -F. '{ print $2; }')
MYUID=`echo "show State:/Users/ConsoleUser" | scutil | awk '/kCGSSessionUserIDKey/ { print $3 }'`

# Stop the GUI app launch agent if it exists
if [ -e ${LAUNCHD_AGENT_DIR}/${LAUNCHD_AGENT_GUI_FILE} ] ; then 
    echo "Stopping GUI launch agent..." >> "${UNINSTALLLOG}"
    logger "Stopping the GUI launch agent..."
    echo "launchctl bootout gui/${MYUID} ${LAUNCHD_AGENT_DIR}/${LAUNCHD_AGENT_GUI_FILE}" >> "${UNINSTALLLOG}"
    launchctl bootout gui/${MYUID} ${LAUNCHD_AGENT_DIR}/${LAUNCHD_AGENT_GUI_FILE} >> "${UNINSTALLLOG}" 2>&1
fi

# Stop the Notification app launch agent if it exists
if [ -e ${LAUNCHD_AGENT_DIR}/${LAUNCHD_AGENT_NOTIFICATION_FILE} ] ; then
    echo "Stopping Notification launch agent..." >> "${UNINSTALLLOG}"
    logger "Stopping the Notification launch agent..."
    echo "launchctl bootout gui/${MYUID} ${LAUNCHD_AGENT_DIR}/${LAUNCHD_AGENT_NOTIFICATION_FILE}" >> "${UNINSTALLLOG}"
    launchctl bootout gui/${MYUID} ${LAUNCHD_AGENT_DIR}/${LAUNCHD_AGENT_NOTIFICATION_FILE} >> "${UNINSTALLLOG}" 2>&1
fi

# Stop the VPN agent launch daemon if it exists
if [ -e ${LAUNCHD_DAEMON_DIR}/${LAUNCHD_DAEMON_VPNAGENT_FILE} ] ; then
    echo "Stopping agent..." >> "${UNINSTALLLOG}"
    logger "Stopping the VPN agent..."
    echo "launchctl bootout system ${LAUNCHD_DAEMON_DIR}/${LAUNCHD_DAEMON_VPNAGENT_FILE}" >> "${UNINSTALLLOG}"
    launchctl bootout system ${LAUNCHD_DAEMON_DIR}/${LAUNCHD_DAEMON_VPNAGENT_FILE} >> "${UNINSTALLLOG}" 2>&1
fi

# Stop the AnyConnect VPN Service app
echo "Stopping AnyConnect VPN Service..." >> "${UNINSTALLLOG}"
logger "Stopping AnyConnect VPN Service..."
osascript -e "quit app \"${SERVICE_APP}\""
pkill -x "${SERVICE_APP}"
# Unregister services
echo "Unregistering AnyConnect VPN Service..." >> "${UNINSTALLLOG}"
logger "Unregistering AnyConnect VPN Service..."
sudo -u \#${MYUID} open -W -a "${BINDIR}/${SERVICE_APP}" --args uninstall

# grep pattern to skip processes that shouldn't be considered as "Cisco Secure Client" related processes.
SKIPPROCS="grep|installer|preinstall|vpn_uninstall|cisco_secure_client_uninstall|${UNINSTALLER}"

# ensure that the agent, gui and cli are not running - show no mercy
OURPROCS=`ps -A -o pid,command | egrep "vpnagentd|(${INSTPREFIX}/bin)|(Cisco Secure Client)" | egrep -v "${SKIPPROCS}" | awk '{print $1}'`
if [ -n "${OURPROCS}" ] ; then
    for DOOMED in ${OURPROCS}; do
        echo Killing `ps -A -o pid,command -p ${DOOMED} | grep ${DOOMED} | egrep -v 'ps|grep'` >> "${UNINSTALLLOG}"
        kill -KILL ${DOOMED} >> "${UNINSTALLLOG}" 2>&1
    done
fi

# Revert the system pf.conf file updates performed during install, unless this uninstall is part of an upgrade. 
if [ "x${IS_UPGRADE}" != "xtrue" ]; then
    echo "Reverting pf.conf changes" >> "${UNINSTALLLOG}"
    ${BINDIR}/acinstallhelper -pfConfUpdate -revert
else
    echo "Skip reverting pf.conf changes during upgrade" >> "${UNINSTALLLOG}"
fi

# Remove the AnyConnect VPN Service app, unless this is part of an upgrade
if [ "x${IS_UPGRADE}" != "xtrue" ]; then
    echo "rm -rf ${BINDIR}/${SERVICE_APP}" >> "${UNINSTALLLOG}"
    rm -rf "${BINDIR}/${SERVICE_APP}" >> "${UNINSTALLLOG}"
else
    echo "Skip removing AnyConnect VPN Service app during upgrade" >> "${UNINSTALLLOG}"
fi

# Notify KDF upgrade start.
# TODO: REVISIT ONCE THE KDF PACKAGE IS AVAILABLE.
if [ "x${IS_UPGRADE}" = "xtrue" ]; then
    echo "Notifying KDF upgrade start" >> "${UNINSTALLLOG}"
    ${KDF_BINDIR}/acsocktool -us >> "${UNINSTALLLOG}"
fi

# unload the acsock if it is still loaded by the system
ACSOCKLOADED=`kextstat | grep acsock`
if [ ! "x${ACSOCKLOADED}" = "x" ]; then
  echo "Unloading {KEXTDIR}/acsock.kext" >> "${UNINSTALLLOG}"
  kextunload "${KEXTDIR}/acsock.kext" >> "${UNINSTALLLOG}" 2>&1
  echo "${KEXTDIR}/acsock.kext unloaded" >> "${UNINSTALLLOG}"
fi

# The network extension KDF is installed regardless of OS version, but only used on macOS 10.16+.
if [[ "$OS_VER_MAJOR" -ge 11 ]] || [[ "$OS_VER_MINOR" -ge 16 ]] ; then
  # Deactivate the network extension KDF if not upgrade. For upgrade, the KDF app will simply be 
  # upgraded to avoid deactivation/activation approval prompts.
  if [ "x${IS_UPGRADE}" != "xtrue" ]; then
    ACSOCKEXTACTIVE=`systemextensionsctl list | grep acsockext`
    if [ ! "x${ACSOCKEXTACTIVE}" = "x" ]; then
      echo "Deactivating network extension acsockext" >> "${UNINSTALLLOG}"
      # Need to run as logged in user, as user needs to authorize the extension deactivation.
      sudo -u \#${MYUID} "${APPDIR}/${NWEXT_KDF_APP}/Contents/MacOS/Cisco Secure Client - Socket Filter" -deactivateExt >> "${UNINSTALLLOG}"
      echo "Network extension acsockext deactivated" >> "${UNINSTALLLOG}"
    fi
  else
    echo "Skip deactivating of network extension acsockext during upgrade" >> "${UNINSTALLLOG}"
  fi
fi
# Remove the network extension KDF app.
echo "rm -rf ${APPDIR}/${NWEXT_KDF_APP}" >> "${UNINSTALLLOG}"
rm -rf "${APPDIR}/${NWEXT_KDF_APP}" >> "${UNINSTALLLOG}"

# Remove only those files that are installed for AnyConnect VPN,
# or are dependent on AnyConnect VPN being installed.
#
INDEX=0
while [ $INDEX -lt ${#FILELIST[@]} ] ; do
  echo "rm -rf "${FILELIST[${INDEX}]}"" >> "${UNINSTALLLOG}"
  rm -rf "${FILELIST[${INDEX}]}"
  let "INDEX = $INDEX + 1"
done

# Remove the kdf/lib directory
if [ -e ${KDF_LIBDIR} ] ; then
  echo "rm -rf "${KDF_LIBDIR}"" >> "${UNINSTALLLOG}"
  rm -rf "${KDF_LIBDIR}" >> "${UNINSTALLLOG}" 2>&1
fi

# Remove the kdf directory if it is empty
if [ -e ${KDFDIR} ] ; then
  if [ ! -z `find "${KDFDIR}" -prune -empty` ] ; then
    echo "rm -df "${KDFDIR}"" >> "${UNINSTALLLOG}"
    rm -df "${KDFDIR}" >> "${UNINSTALLLOG}" 2>&1
  fi
fi

# Since modules that are NOT dependent on AnyConnect VPN can be
# present (even after VPN is uninstalled), remove the "plugins"
# directory only if it is NOT empty.
# 
if [ -e ${PLUGINDIR} ] ; then
  if [ ! -z `find "${PLUGINDIR}" -prune -empty` ] ; then
    echo "rm -rf "${PLUGINDIR}"" >> "${UNINSTALLLOG}"
    rm -rf "${PLUGINDIR}" >> "${UNINSTALLLOG}" 2>&1
  fi
fi

# Remove Disable VPN Profile unless an upgrade is in progress
if [ "x${IS_UPGRADE}" != "xtrue" ]; then
  echo "rm -rf \"${PROFDIR}/VPNDisable_ServiceProfile.xml\"" >> "${UNINSTALLLOG}"
  rm -rf "${PROFDIR}/VPNDisable_ServiceProfile.xml"
fi

# Remove the bin directory if it is empty
if [ -e ${BINDIR} ] ; then
  if [ ! -z `find "${BINDIR}" -prune -empty` ] ; then
    echo "rm -df "${BINDIR}"" >> "${UNINSTALLLOG}"
    rm -df "${BINDIR}" >> "${UNINSTALLLOG}" 2>&1
  fi
fi

# Only remove the Application directory if it is empty
if [ ! -z `find "${APPDIR}" -prune -empty` ] ; then
  echo "rm -rf "${APPDIR}"" >> "${UNINSTALLLOG}"
  rm -rf "${APPDIR}" >> "${UNINSTALLLOG}" 2>&1
fi

# Remove the lib directory if it is empty
if [ -e ${LIBDIR} ] ; then
  if [ ! -z `find "${LIBDIR}" -prune -empty` ] ; then
    echo "rm -df "${LIBDIR}"" >> "${UNINSTALLLOG}"
    rm -df "${LIBDIR}" >> "${UNINSTALLLOG}" 2>&1
  fi
fi

# Remove the script directory if it is empty
if [ -e ${SCRIPTDIR} ] ; then
  if [ ! -z `find "${SCRIPTDIR}" -prune -empty` ] ; then
    echo "rm -df "${SCRIPTDIR}"" >> "${UNINSTALLLOG}"
    rm -df "${SCRIPTDIR}" >> "${UNINSTALLLOG}" 2>&1
  fi
fi

# Remove the help directory if it is empty
if [ -e ${HELPDIR} ] ; then
  if [ ! -z `find "${HELPDIR}" -prune -empty` ] ; then
    echo "rm -df "${HELPDIR}"" >> "${UNINSTALLLOG}"
    rm -df "${HELPDIR}" >> "${UNINSTALLLOG}" 2>&1
  fi
fi

# Remove the management profile directory if it is empty
if [ -e ${MGMTPROFDIR} ] ; then
  if [ ! -z `find "${MGMTPROFDIR}" -prune -empty` ] ; then
    echo "rm -df "${MGMTPROFDIR}"" >> "${UNINSTALLLOG}"
    rm -df "${MGMTPROFDIR}" >> "${UNINSTALLLOG}" 2>&1
  fi
fi

# Remove the profile directory if it is empty
if [ -e ${PROFDIR} ] ; then
  if [ ! -z `find "${PROFDIR}" -prune -empty` ] ; then
    echo "rm -df "${PROFDIR}"" >> "${UNINSTALLLOG}"
    rm -df "${PROFDIR}" >> "${UNINSTALLLOG}" 2>&1
  fi
fi

# Remove the install directory/subdirectories if empty.
if [ -e ${COMPONENT_DIR} ] ; then
  if [ ! -z `find "${COMPONENT_DIR}" -prune -empty` ] ; then
    echo "rm -df "${COMPONENT_DIR}"" >> "${UNINSTALLLOG}"
    rm -df "${COMPONENT_DIR}" >> "${UNINSTALLLOG}" 2>&1
  fi
fi
if [ -e ${DEPENDENCY_DIR} ] ; then
  if [ ! -z `find "${DEPENDENCY_DIR}" -prune -empty` ] ; then
    echo "rm -df "${DEPENDENCY_DIR}"" >> "${UNINSTALLLOG}"
    rm -df "${DEPENDENCY_DIR}" >> "${UNINSTALLLOG}" 2>&1
  fi
fi
if [ -e ${INSTALL_DIR} ] ; then
  if [ ! -z `find "${INSTALL_DIR}" -prune -empty` ] ; then
    echo "rm -df "${INSTALL_DIR}"" >> "${UNINSTALLLOG}"
    rm -df "${INSTALL_DIR}" >> "${UNINSTALLLOG}" 2>&1
  fi
fi

# remove installer receipt
pkgutil --forget ${CSC_VPN_PACKAGE_ID} >> "${UNINSTALLLOG}" 2>&1

echo "Successfully removed Cisco Secure Client from the system." >> "${UNINSTALLLOG}"
echo "Successfully removed Cisco Secure Client from the system."

exit 0