From e64b18074f937454b92a6215306c43eac15b6c10 Mon Sep 17 00:00:00 2001 From: Selva Nair Date: Mon, 8 Aug 2022 22:12:01 -0400 Subject: [PATCH] Intercept management callbacks for better control of the UI - Dialog windows of connections can popup at any time due to restarts not in user's control. Avoid this by marking current current profile being connected, and intercepting dialogs for other profiles. This is implemented by hooking into management callbacks such as OnPassword, OnNeedOk etc. Signed-off-by: Selva Nair --- plap/plap_connection.c | 3 + plap/ui_glue.c | 135 ++++++++++++++++++++++++++++++++++++++--- plap/ui_glue.h | 6 ++ 3 files changed, 137 insertions(+), 7 deletions(-) diff --git a/plap/plap_connection.c b/plap/plap_connection.c index 48d44f9..45595c7 100644 --- a/plap/plap_connection.c +++ b/plap/plap_connection.c @@ -540,6 +540,8 @@ Connect(ICCPC *this, IQueryContinueWithStatus *qc) NotifyEvents(oc, L""); oc->connect_cancelled = FALSE; + SetActiveProfile(oc->c); + ConnectHelper(oc->c); Sleep(100); @@ -570,6 +572,7 @@ Connect(ICCPC *this, IQueryContinueWithStatus *qc) ShowStatusWindow(oc->c, FALSE); oc->qc = NULL; + SetActiveProfile(NULL); dmsg (L"Exit with: <%ls>", ISCONNECTED(oc->c) ? L"success" : L"error/cancel"); diff --git a/plap/ui_glue.c b/plap/ui_glue.c index 2395db7..a5b3004 100644 --- a/plap/ui_glue.c +++ b/plap/ui_glue.c @@ -42,9 +42,121 @@ /* Global options structure */ options_t o; + int state_connected = connected, state_disconnected = disconnected, state_onhold = onhold; +static connection_t *active_profile; + +/* Override management handlers that generate user dialogs + * and pass them on only for currently active profile. + * Also ensure no unwanted popus are generated. + */ +static void +OnStop_(connection_t *c, UNUSED char *msg) +{ + dmsg(L"profile: %ls with state = %d", c->config_name, c->state); + + /* do not show any popup error messages */ + c->state = disconnected; + SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_DISCONNECTED)); + SetStatusWinIcon(c->hwndStatus, ID_ICO_DISCONNECTED); + SendMessage(c->hwndStatus, WM_CLOSE, 0, 0); +} + +/* Override OnInfoMsg: We filter out anything other + * than CR_TEXT: In particular, OPEN_URL is not supported + * in PLAP context. + */ +static void +OnInfoMsg_(connection_t* c, char* msg) +{ + if (strbegins(msg, "CR_TEXT:")) + { + if (c == active_profile) + { + OnInfoMsg(c, msg); + } + else + { + DetachOpenVPN(c); /* next attach will handle it */ + } + } +} + +static void +OnNeedOk_(connection_t *c, char *msg) +{ + if (c == active_profile) + { + OnNeedOk(c, msg); + } + else + { + DetachOpenVPN(c); /* next attach will handle it */ + } +} + +static void +OnNeedStr_(connection_t *c, char *msg) +{ + if (c == active_profile) + { + OnNeedStr(c, msg); + } + else + { + DetachOpenVPN(c); /* next attach will handle it */ + } +} + +static void +OnPassword_(connection_t *c, char *msg) +{ + if (c == active_profile) + { + OnPassword(c, msg); + } + else + { + DetachOpenVPN(c); /* next attach will handle it */ + } +} + +static void +OnProxy_(connection_t *c, char *msg) +{ + if (c == active_profile) + { + OnProxy(c, msg); + } + else + { + DetachOpenVPN(c); /* next attach will handle it */ + } +} + +/* Intercept state change. Keep track of previous state and handle + * cases like user wants to disconnect but connection completed in + * the meantime. + */ +void +OnStateChange_(connection_t *c, char *msg) +{ + int state_prev = c->state; + + OnStateChange(c, msg); + + if (c->state == connected && state_prev == disconnecting) + { + /* connection completed while user clicked disconnect, + * let disconnect process continue. This is required to + * retain the hold state after SIGHUP restart. + */ + c->state = disconnecting; + } +} + /* Initialize GUI data structures. Returns 0 on success */ DWORD InitializeUI(HINSTANCE hinstance) @@ -90,15 +202,15 @@ InitializeUI(HINSTANCE hinstance) { ready_, OnReady }, { hold_, OnHold }, { log_, OnLogLine }, - { state_, OnStateChange }, - { password_, OnPassword }, - { proxy_, OnProxy }, - { stop_, OnStop }, - { needok_, OnNeedOk }, - { needstr_, OnNeedStr }, + { state_, OnStateChange_ }, + { password_, OnPassword_ }, + { proxy_, OnProxy_ }, + { stop_, OnStop_ }, + { needok_, OnNeedOk_ }, + { needstr_, OnNeedStr_ }, { echo_, OnEcho }, { bytecount_,OnByteCount }, - { infomsg_, OnInfoMsg }, + { infomsg_, OnInfoMsg_ }, { timeout_, OnTimeout }, { 0, NULL} }; @@ -356,3 +468,12 @@ DisconnectHelper(connection_t *c) dmsg(L"profile: %ls state = %d", c->config_name, c->state); } + +/* Set the currently active profile in Connect() operation -- pass NULL to unset. + * We allow UI dialogs only on the current profile. + */ +void +SetActiveProfile(connection_t *c) +{ + active_profile = c; +} diff --git a/plap/ui_glue.h b/plap/ui_glue.h index a3abb56..7dcde7b 100644 --- a/plap/ui_glue.h +++ b/plap/ui_glue.h @@ -101,6 +101,12 @@ void ConnectHelper(connection_t *c); */ void DisconnectHelper(connection_t *c); +/** + * Set c as the currently active profile selected for user interaction + * UI dialogs are suppressed for non-active profiles + */ +void SetActiveProfile(connection_t *c); + #ifdef __cplusplus } #endif