ClientIfcBase.h
/**************************************************************************
* Copyright (c) 2006, 2021-2025 Cisco Systems, Inc.
* All Rights Reserved. Cisco Highly Confidential.
***************************************************************************
*
* File: ClientIfcBase.h
* Author: Chris Fitzgerald
* Date: 08/2007
*
***************************************************************************
* Client Interface Base class implementation for the Client API.
***************************************************************************/
#ifndef _CLIENTIFCBASE_
#define _CLIENTIFCBASE_
#include <list>
#include <vector>
#include <memory>
#include "ClientIfcCommon.h"
#include "api.h"
#if defined(ANYCONNECT_USE_SNAK)
#include "SNAK_CertPlugin.h"
#endif
#if defined(HOST_DATA_SUPPORTED)
class IHostData;
#endif
class ConnectPromptInfo;
class MsgWithArg;
class VPNStats;
class PreferenceInfo;
class ProxyIfc;
class CIpcMessage;
class CertObj;
class HostEntry;
class ClientIfcInternal;
#if defined(VPNAPI_TRANSMIGRATION_SUPPORTED)
class CSharedAccessLock;
#endif
#if defined(VPNAPI_EVENT_NOTIFICATION_SUPPORTED)
class CEventNotificationTlv;
#endif
#if defined(CREDENTIAL_PREFILL_SUPPORTED)
class CredentialPrefill;
#endif
#if (defined(ANYCONNECT_USE_SNAK) || defined(PLATFORM_APPLE_SSLVPN)) && !defined(PLATFORM_WIN_APP)
class ManagedCertificate;
#endif
#if defined(PROGRAM_DATA_IMPORT_SUPPORTED)
class IACImporterAsync;
class IACImporterAsyncCB;
#endif
class VPN_VPNAPI ClientIfcBase
{
friend class EventMgr;
friend class ClientIfcInternal;
protected:
ClientIfcBase();
virtual ~ClientIfcBase();
/**
* Callback used to deliver new statistics related to the VPN
* connection.
*
* When a connection is active, a new set of statistics is
* delivered each second.
*
* @see resetStats(), stopStats() and startStats()
*
*/
virtual void StatsCB(VPNStats &stats) = 0;
/**
* Callback used to deliver VPN state and state change string.
* The stateString delivered by this method is localized.
*
* See the ::VPNState enum found in api.h for set of valid states.
*/
virtual void StateCB(const VPNState state,
const VPNSubState subState,
const tstring stateString) = 0;
/**
* If a banner needs to be acknowledged, this CB delivers the banner
* to the client.
*
* NOTE: Connection establishment will block until the method
* setBannerResponse() is called.
*
* In a GUI, a banner would typically be displayed in a modal dialog
* with an accept or decline button selection.
*
* @see setBannerResponse() to set the user response to the banner.
*/
virtual void BannerCB(const tstring &banner) = 0;
/**
* If a pre-connect reminder needs to be acknowledged, this CB delivers
* the pre-connect reminder to the client.
*
* NOTE: Connection establishment will block until the method
* setPreConnectReminderResponse() is called.
*
* In a GUI, a pre-connect reminder would typically be displayed in a modal
* dialog with an OK button selection.
*
* @see setPreConnectReminderResponse() to set the user acknowledgement to
* the pre-connect reminder message.
*/
virtual void PreConnectReminderCB(const tstring &rtstrPreConnectReminder);
/**
* Messages are delivered via the NoticeCB and can come from multiple
* sources. There are four message types (error, warning, info and
* status). See the ::MessageType enum in api.h for the list.
*
* Clients using the API as an embedded application (not
* user visible) might want to further characterize
* messages. One option here is to use the AnyConnect message
* catalog and assign message codes as the translations for
* various messages. An application could then track messages based
* on its own error code scheme.
*/
virtual void NoticeCB(const tstring &notice,
const MessageType type,
const bool bSensitive = false) = 0;
#if defined(PLATFORM_APPLE_SSLVPN) || defined(PLATFORM_ANDROID) || defined(PLATFORM_CHROMEBOOK)
virtual void CertBannerCB(const tstring &certBannerSummary,
const uint32_t nCertBannerCertLen,
const uint8_t *pCertBannerCertDer,
const std::list<tstring> &confirmReasons,
const std::list<CertConfirmReason> &confirmReasonEnums,
bool bImportAllowed = true) = 0;
#endif
/**
* This CB would likely occur only during a connection when it was
* detected that the software needed to be upgraded, or when Start
* Before Logon (SBL) is being used.
*
* Unlike the other callback methods, this method provides a default
* implementation (calling the system's exit() function).
* If clients of the API wish to override this behavior, they are
* responsible for ensuring that the current running process exits with
* the return code specified by returnCode.
*
* <b>Caution</b>: IF YOU OVERRIDE THIS METHOD AND DO NOT EXIT WITH
* THE PROPER CODE SOFTWARE UPDATE FUNCTIONALITY IN YOUR CLIENT WILL
* BREAK
*/
virtual void ExitNoticeCB(const tstring &tstrNotice,
const int returnCode);
/**
* Under normal operating conditions, this CB is called as soon
* as the attach method completes. In case the service (vpn agent)
* is not ready, this CB is not called until it is.
*
* Any API calls made prior to this CB being called will result in a
* NoticeCB error message.
*/
virtual void ServiceReadyCB() = 0;
/**
* This method supports prompting for single or multiple values. All
* prompts are considered mandatory.
*
* The ConnectPromptInfo object contains a list of PromptEntry
* instances. The labels and their default values (if any) can be
* found in these instances. After the data has been collected from the user
* it can be set into these same instances. When ready, the client
* application should call the method UserSubmit() to have the
* responses read by the API.
*/
virtual void UserPromptCB(ConnectPromptInfo &ConnectPrompt) = 0;
/**
* Use this method to provide Window Manager hints to GUI
* applications. To receive these hints, the application must
* identify itself as a GUI in the attach method. In addition, this
* method should be overridden to receive any generated events.
*
* Event that can be received include those indicating that a user is
* starting a second instance of the GUI application. This information
* can be used to tell the already running application to un-minimize
* itself and let the new program know that it should Quit (since a GUI
* is already running).
*/
virtual void WMHintCB(const WMHint hint,
const WMHintReason reason);
/**
* This method is useful when the connection to the secure gateway
* has been established as part of a web-launch of the VPN tunnel.
*
* If the client application wishes to be notified of the secure
* gateway to which the VPN has been established, this method should
* be overridden.
*
* If the client application is started and a tunnel is already active,
* this method also delivers the name of the secure gateway host.
*/
virtual void deliverWebLaunchHostCB(const tstring &activeHost);
/**
* This method is called when the preference to block untrusted
* servers is enabled and the current VPN server being connected
* to is untrusted. Clients should present an error to the user
* notifying them that the current connection to rtstrUntrustedServer
* is being blocked. The client should also provide a way for the
* user to change the preference to block untrusted servers.
*
* The user response must be indicated using setCertBlockedResponse
*/
virtual void CertBlockedCB(const tstring &rtstrUntrustedServer) = 0;
/**
* This method is called when connections to untrusted VPN servers
* is allowed by policies and the current VPN server being connected
* to is untrusted. Clients should present a warning to the user
* notifying them that the current connection to rtstrUntrustedServer
* is unsafe. The reason the VPN server is untrusted is provided in
* rltstrCertErrors. The client should provide a way for the user to
* connect once, connect and always trust or cancel the connection.
* If bAllowImport is set to false then the always trust option should
* not be presented to users.
*
* The user response must be indicated using setCertWarningResponse
*/
virtual void CertWarningCB(const tstring &rtstrUntrustedServer,
const std::list<tstring> &rltstrCertErrors,
bool bAllowImport) = 0;
#if defined(PLATFORM_WIN_APP)
/**
* Same as above but also passes the Server certificate DER for details display
*/
virtual void CertWarningCB(const tstring &rtstrUntrustedServer,
const std::list<tstring> &rltstrCertErrors,
const std::vector<uint8_t> &rvServerCertDER,
bool bAllowImport) = 0;
#endif
/**
* This method should be overridden by the client application to
* exercise some control over the delivery of events from the other
* protected methods in this class.
*
* This might be necessary in cases where a GUI/CLI is being written and
* the data from this API needs to be delivered in the GUI/CLI or main
* thread. In this case, you should override this method and when it
* is called by the API post an event to your event queue (message
* pump, etc.). After this event executes in your GUI/CLI or main thread,
* call the method ClientIfc::ProcessEvents to have events delivered
* to your client application.
*/
virtual void EventAvailable();
#if defined(MANUAL_PKCS12_IMPORT_SUPPORTED)
virtual void ImportPKCS12ResultCB(const std::vector<uint8_t> &certHash,
const tstring &tstrError);
#endif
#if defined(PLATFORM_ANDROID)
virtual void ClientCertificateCB(std::vector< std::pair<uint32_t, uint8_t*> > certList) = 0;
virtual void AgentDetachedCB();
#endif
#if defined(VPNAPI_EVENT_NOTIFICATION_SUPPORTED)
/**
* Internal callback between ClientIfcBase and ClientIfc.
*/
virtual void EventNotificationInternalCB(
const std::shared_ptr<CEventNotificationTlv>& spEventNtfctnTlv) = 0;
#endif
/**
* Internal methods for use by ClientIfc.
*/
void ResetQuarantinedReconnect();
void ClientIfcTransmigration();
public:
bool attach(const ClientType clientType = ClientType_GUI,
const bool requestFullCapabilities = true,
const bool suppressAutoConnect = true,
const bool bSuppressEventAvailableCB = false);
void detach();
void ProcessEvents();
bool hasFullCapabilities();
bool isConnected(bool bSilent = false);
bool isAvailable();
std::list<tstring> getHostNames();
std::list<HostEntry> getHostEntries();
tstring getDefaultHostName();
bool connect(
#if defined(HOST_DATA_SUPPORTED)
const IHostData& host);
#else
tstring host);
#endif
bool connect(
#if defined(HOST_DATA_SUPPORTED)
const IHostData& host,
#else
tstring host,
#endif
unsigned int origin);
bool setNewTunnelGroup(const tstring & group);
void disconnect();
void disconnect(VPNDisconnectReason disconnectEvent);
void cancel();
void resetStats();
void getState();
VPNState getCurrentVPNState();
VPNSubState getCurrentVPNSubState();
VPNSubState getPreviousVPNSubState();
STATE getCurrentState();
tstring getStateText();
static tstring getNoticeTypeText(MessageType msgType);
static tstring getStateText(VPNState state,
VPNSubState subState = VPNSS_NORMAL,
NETENV_STATE netEnvState = NES_NETWORK_ACCESSIBLE,
const tstring& tstrConnectedHost = tstring());
void setNetworkStates(NETENV_STATE netEnvState,
NETCTRL_STATE netCtrlState,
NETWORK_TYPE netType,
bool bACBrowserForCPRemediation,
bool bUpdateUI);
void refreshOperatingModeForCurrentNetStates();
NETENV_STATE getCurrentNetEnvState();
NETENV_STATE getPreviousNetEnvState();
NETCTRL_STATE getCurrentNetCtrlState();
NETWORK_TYPE getCurrentNetType();
bool isACBrowserForCPRemediation();
static tstring getNetCtrlText(NETCTRL_STATE netCtrlState);
static tstring getNetEnvText(NETENV_STATE netEnvState,
bool bSimple = false);
static tstring getNetTypeText(NETWORK_TYPE netType);
static tstring getQuarantinedStatusText();
static tstring getNetworkStatusSimpleText(const NETENV_STATE netEnvState,
const NETCTRL_STATE netCtrlState);
// can't be static due to requiring operating mode information
tstring getNetworkStatusText(const VPNState state,
const VPNSubState subState,
const NETENV_STATE netEnvState,
const NETCTRL_STATE netCtrlState);
PreferenceInfo& getPreferences();
bool savePreferences();
void startStats();
void stopStats();
void UserSubmit();
void setBanner(const tstring &banner);
void setBannerResponse(bool bResponse);
void setPreConnectReminder(const tstring &tstrPreConnectReminder);
void setPreConnectReminderResponse();
bool getUserResponse();
bool isUserResponseSet();
void setCertBlocked(const tstring &tstrUntrustedServer);
void setCertWarning(const tstring &rtstrUntrustedServer,
const std::list<tstring> &rltstrCertErrors,
bool bAllowImport);
#if defined(PLATFORM_WIN_APP)
void setCertWarning(const tstring &rtstrUntrustedServer,
const std::list<tstring> &rltstrCertErrors,
const std::vector<uint8_t>& rvServerCertDER,
bool bAllowImport);
#endif
bool getCertImportResponse();
#if defined(PLATFORM_APPLE_SSLVPN) || defined(PLATFORM_ANDROID) || defined(PLATFORM_CHROMEBOOK)
void setCertBanner(tstring tstrCertBannerSummary,
uint32_t nCertBannerCertLen,
const uint8_t *pCertBannerCertDer,
const std::list<tstring> &confirmReasons,
const std::list<CertConfirmReason> &confirmReasonEnums,
bool bImportAllowed);
void setCertBannerResponse(bool bResponse, bool bImportCert);
void importServerCert(std::vector<uint8_t> certData);
bool setFipsMode(bool bEnableFips);
#if defined(PLATFORM_ANDROID)
bool setStrictMode(bool bEnableStrictMode);
bool setRevocationEnabled(bool bRevocationEnabled);
bool IsRevocationEnabled();
#endif // currently supported only for android
#endif
void setUserPrompt(ConnectPromptInfo &ConnectPrompt);
#if defined(PLATFORM_ANDROID)
void setClientCertResponse(std::vector< std::pair<uint32_t, uint8_t*> > &derList);
void setAgentDetached();
bool getClientCertificates();
#endif
#if defined(PLATFORM_APPLE_SSLVPN) || defined(PLATFORM_ANDROID)
void setSCEPEnrollInProgress(bool bInProgress);
bool isSCEPEnrollInProgress();
#endif
#if defined(MANUAL_PKCS12_IMPORT_SUPPORTED)
void setImportPKCS12Result(const std::vector<uint8_t> &certHash, const tstring &tstrError);
bool requestImportPKCS12(const std::vector<uint8_t> &data);
std::vector<uint8_t> importPKCS12WithPassword(const std::vector<uint8_t> &data, const tstring &password);
#endif
void setCertBlockedResponse(bool bUnlock);
void setCertWarningResponse(bool bConnect, bool bImportCert);
void insertStateToConnectPrompt(ConnectPromptInfo &ConnectPrompt);
void ExitNotice(const tstring &tstrNotice, const int code = 0);
void notice(const tstring &tstrNotice,
const MessageType type = MsgType_Info,
bool bClearLastMsg = false,
bool bForce = false,
bool bStateMsg = false,
bool bSensitiveMsg = false);
void notice(MsgWithArg &notice,
const MessageType type = MsgType_Info,
bool bClearLastMsg = false,
bool bForce = false,
bool bStateMsg = false,
bool bSensitiveMsg = false);
void getStats(void);
void setStats(VPNStats &stats);
void exportStats(const tstring &tstrFilePath);
void initState(VPNState state,
VPNState previousState,
VPNSubState subState);
void setState(VPNState state,
VPNState previousState,
VPNSubState subState = VPNSS_NORMAL,
bool bUpdateStateMsg = true,
bool bOnlyUpdateUI = false);
#if defined(PROGRAM_DATA_IMPORT_SUPPORTED)
IACImporterAsync *createACImporter(IACImporterAsyncCB *pCallback);
#endif
void setWMHint(WMHint hint,
WMHintReason reason);
bool isLastConnectType (const ConnectPromptType connPromptType);
bool isOperatingMode(OperatingMode opMode);
void setOperatingMode(OperatingMode opMode);
void unsetOperatingMode(OperatingMode opMode);
bool CanRemediateCaptivePortal();
bool policyAllowsCaptivePortalRemediation();
bool isEventShutdown();
bool isUsingEventModel();
time_t getLastDisconnectTime();
ConnectPromptInfo getConnectPromptInfo();
void resetConnectPromptPasswordData();
void setStandaloneConnection(bool isStandalone);
void deliverActiveHost(const tstring &activeHost,
ConnectProtocolType vpnProtocol = PROTOCOL_TYPE_UNKNOWN,
bool bActiveHostFriendlyName = false);
bool isVPNServiceReady();
// reset last disconnect time indicator.
//
void resetLastDisconnectTime(time_t time = 1);
void processMinimize();
// cert enrollment
void setEnrollClientCert(CertObj* pCert);
// Show user banner for cert import warning on linux
// SCEPIfc to ConnectMgr
void linuxCertImportWarnUser();
// Response to cert warning on linux
// ConnectMgr to SCEPIfc
void linuxCertImportWarnUserResponse(bool bAccept);
void setDefaultHost(tstring &host);
#if defined(HOST_DATA_SUPPORTED)
void setDefaultHostProfile(const IHostData &hostProfile);
IHostData* getDefaultHostData();
#endif
void setLastVpnError(VPNError vpnError);
VPNError getLastVpnError();
#if defined(PLATFORM_ANDROID)
bool requestClientCertificates();
#endif
bool requestImportLocalization(const tstring tstrLocale,
const std::vector<unsigned char> &MoFileData);
// Start the Automatic Headend Selection operation
void startAHS(const unsigned int uiReason,
const ProxyIfc& proxy);
// statusReturnCode is a long to match the current type of STATUSCODE.
// It is not using a STATUSCODE directly so that we do not have to
// expose the header files for STATUSCODEs to ClientIfcBase.h
void AHSSelectedHost(const unsigned int uiReason,
const std::vector<tstring> &headendList,
const long statusReturnCode,
const tstring& extraInfo);
std::vector<tstring> getAHSHostList();
unsigned int getAHSState();
bool isAHSHasRun();
bool IsAHSCachingRestricted();
bool suppressConnectionErrorPopups();
tstring getCaptivePortalDetectedMsg();
void setProxyAuthPrompts(ProxyIfc* pProxy,
const tstring& promptMsg);
#if defined(INTERPROCESS_COMMUNICATION_SUPPORTED)
bool handleIpcMessage(CIpcMessage *pIpcMessage);
#if defined(VPNAPI_EVENT_NOTIFICATION_SUPPORTED)
void signalDisconnectedToEventNtfctnThread();
#endif
#endif
bool IsCsdTokenVerified() const;
#if defined(PLATFORM_APPLE_SSLVPN) || defined(PLATFORM_ANDROID)
virtual void SCEPEnrollStartCB();
virtual void SCEPEnrollExitCB();
#endif
void activateConnectMgrTunnelInitiationCompletionEvent();
bool isConnectRequestActive();
bool isConnectRequestCleanup();
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_CHROMEBOOK)
bool deleteProfileByName(const tstring &profileName);
tstring getProfileContents(const tstring &profileName);
bool importProfile(const tstring &profileName, const tstring &profileContents);
#endif
bool syncProfileChange(const tstring &profileName);
#if defined(CREDENTIAL_PREFILL_SUPPORTED)
bool hasPrefilledCredentials();
bool prefillCredentials(ConnectPromptInfo &connectPrompt);
void setPrefilledCredentials(CredentialPrefill *prefill);
#endif
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_APPLE_SSLVPN)
std::list<ManagedCertificate *> enumerateCertificates(CertificateType certType);
bool deleteCertificates(CertificateType certType, const std::list<std::string> &idList);
bool deleteServerCertificates(const std::list<std::string> &idList);
#endif
#if defined(ANYCONNECT_USE_SNAK) && !defined(PLATFORM_WIN_APP)
std::list<ManagedCertificate *> enumerateSNAKCertificates(SNAK_CertType certType);
SNAK_CertType getSNAKCertType(CertificateType certType);
bool deleteClientCertificates(const std::list<std::string> &idList);
#endif
#if defined(PLATFORM_APPLE_SSLVPN)
bool canUseBackupServers();
#endif
tstring getConnectHost();
tstring getMgmtTunnelHostname();
VPN_TUNNEL_SCOPE getVpnTunnelScope();
bool isStandaloneConnection();
void sendSSoLogoutPrompt(ConnectPromptInfo &cpi);
void setExternalSSOLogoutUrlFromAgent(const tstring& logoutUrl);
private:
//
// Private Member Data
//
#if defined(VPNAPI_TRANSMIGRATION_SUPPORTED)
std::shared_ptr<CSharedAccessLock> m_spClientIfcInternalPtrSharedAccessLock;
#endif
std::unique_ptr<ClientIfcInternal> m_upClientIfcInternal;
//
// Private Member Methods
//
// Prevent copying by declaring but not defining copy constructor and operator= methods.
//
ClientIfcBase(const ClientIfcBase& other);
ClientIfcBase& operator=(const ClientIfcBase& other);
};
#endif // _CLIENTIFCBASE_
MsgType_Info
Definition: api.h:113
ConnectPromptType
ConnectPromptType
Definition: api.h:244
PreferenceInfo
Definition: PreferenceInfo.h:26
api.h
WMHintReason
WMHintReason
Definition: api.h:220
VPNDisconnectReason
VPNDisconnectReason
Definition: api.h:188
VPNState
VPNState
Definition: api.h:146
ClientIfcBase
Definition: ClientIfcBase.h:63
tstring
#define tstring
Definition: api.h:35
WMHint
WMHint
Definition: api.h:201
ConnectPromptInfo
Definition: ConnectPromptInfo.h:37
MessageType
MessageType
Definition: api.h:108
OperatingMode
OperatingMode
Definition: api.h:545
VPNSubState
VPNSubState
Definition: api.h:170
VPNError
VPNError
Definition: api.h:597
VPNStats
Definition: VPNStats.h:35