From bfb716ed09e9b4fe5aa181a77d3bb5b2028618a9 Mon Sep 17 00:00:00 2001 From: Timollo78 Date: Thu, 23 Feb 2023 16:16:33 +0100 Subject: [PATCH] - remove general configuration option to enable a token field in the auth-user-pass dialog - introduce an "Annotation" (# @OpenVPN_GUI token) to the configuration file to control, whether a token field in the user/password authentication dialog is needed or not --- README.rst | 15 +++++++++++---- localization.c | 4 ---- openvpn-gui-res.h | 2 -- openvpn.c | 11 +++++++---- openvpn_config.c | 40 +++++++++++++++++++++++++++++++++++++++ options.c | 5 ----- options.h | 14 +++++++------- registry.c | 1 - res/openvpn-gui-res-de.rc | 29 ++++++++++++++-------------- res/openvpn-gui-res-en.rc | 29 ++++++++++++++-------------- 10 files changed, 93 insertions(+), 57 deletions(-) diff --git a/README.rst b/README.rst index e25043b..20552e6 100644 --- a/README.rst +++ b/README.rst @@ -56,6 +56,17 @@ itself. There are sample config files in the *sample-config* folder. Please refer to the `OpenVPN How To `_ for more information regarding creating the configuration file. +Annotations in configuration file: + +To make OpenVPN GUI displaying a separate token field for a 2factor authentication in the user/password dialog a +special annotation can be added to the configuration file. This is needed, because OpenVPN GUI can handle multiple +connections (configuration files) where some might have a 2factor authentication and some not. OpenVPN GUI does +not offer the possibilty to handle connection specific configurations on its own, so the configuration file can be +extended. + +* By adding the comment '# @OpenVPN_GUI token' to the configuration file, the additional token field in the user/password + dialog will be shown + Once the configuration file is ready, you need to let OpenVPN GUI know about it. There are three ways to do this: @@ -313,10 +324,6 @@ silent_connection not be shown while connecting. Warnings such as interactive service not started or multiple config files with same name are also suppressed. -mfa_token - If set to "1", a separate field token field will be added to the - authentication window. - show_balloon 0: Never show any connected balloon diff --git a/localization.c b/localization.c index 3736a09..9714d6e 100644 --- a/localization.c +++ b/localization.c @@ -521,8 +521,6 @@ GeneralSettingsDlgProc(HWND hwndDlg, UINT msg, UNUSED WPARAM wParam, LPARAM lPar Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_LOG_APPEND), BST_CHECKED); if (o.silent_connection) Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_SILENT), BST_CHECKED); - if (o.mfa_token) - Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_TOKEN), BST_CHECKED); if (o.iservice_admin) Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_ALWAYS_USE_ISERVICE), BST_CHECKED); if (o.show_balloon == 0) @@ -577,8 +575,6 @@ GeneralSettingsDlgProc(HWND hwndDlg, UINT msg, UNUSED WPARAM wParam, LPARAM lPar (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_LOG_APPEND)) == BST_CHECKED); o.silent_connection = (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_SILENT)) == BST_CHECKED); - o.mfa_token = - (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_TOKEN)) == BST_CHECKED); o.iservice_admin = (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_ALWAYS_USE_ISERVICE)) == BST_CHECKED); if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON0)) diff --git a/openvpn-gui-res.h b/openvpn-gui-res.h index 0cf911b..4ba6bea 100644 --- a/openvpn-gui-res.h +++ b/openvpn-gui-res.h @@ -125,8 +125,6 @@ #define ID_CHK_PLAP_REG 248 #define ID_CHK_AUTO_RESTART 249 -#define ID_CHK_TOKEN 260 - /* Proxy Auth Dialog */ #define ID_DLG_PROXY_AUTH 250 #define ID_EDT_PROXY_USER 251 diff --git a/openvpn.c b/openvpn.c index ec968db..1b973a9 100644 --- a/openvpn.c +++ b/openvpn.c @@ -541,7 +541,7 @@ UserAuthDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) SetDlgItemTextW(hwndDlg, ID_EDT_AUTH_PASS, password); if (username[0] != L'\0' && !(param->flags & FLAG_CR_TYPE_SCRV1) && password[0] != L'\0' && param->c->failed_auth_attempts == 0 - && o.mfa_token == 0) + && !(param->c->flags & FLAG_TOKEN)) { /* user/pass available and no challenge response needed: skip dialog * if silent_connection is on, else auto submit after a few seconds. @@ -603,7 +603,10 @@ UserAuthDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) || ((param->flags & FLAG_CR_TYPE_SCRV1) && GetWindowTextLength(GetDlgItem(hwndDlg, ID_EDT_AUTH_CHALLENGE))) ) - && (o.mfa_token == 0 || param->flags & FLAG_CR_TYPE_SCRV1 || GetWindowTextLength(GetDlgItem(hwndDlg, ID_EDT_AUTH_TOKEN))); + && (!(param->c->flags & FLAG_TOKEN) + || param->flags & FLAG_CR_TYPE_SCRV1 + || GetWindowTextLength(GetDlgItem(hwndDlg, ID_EDT_AUTH_TOKEN)) + ); EnableWindow(GetDlgItem(hwndDlg, IDOK), enableOK); } AutoCloseCancel(hwndDlg); /* user interrupt */ @@ -658,7 +661,7 @@ UserAuthDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) ManagementCommandFromInput(param->c, "username \"Auth\" \"%s\"", hwndDlg, ID_EDT_AUTH_USER); if (param->flags & FLAG_CR_TYPE_SCRV1) ManagementCommandFromTwoInputsBase64(param->c, "password \"Auth\" \"SCRV1:%s:%s\"", hwndDlg, ID_EDT_AUTH_PASS, ID_EDT_AUTH_CHALLENGE); - else if (o.mfa_token == 1) + else if (param->c->flags & FLAG_TOKEN) ManagementCommandFromTwoInputs(param->c, "password \"Auth\" \"%s%s\"", hwndDlg, ID_EDT_AUTH_PASS, ID_EDT_AUTH_TOKEN); else ManagementCommandFromInput(param->c, "password \"Auth\" \"%s\"", hwndDlg, ID_EDT_AUTH_PASS); @@ -1272,7 +1275,7 @@ OnPassword(connection_t *c, char *msg) param->str = strdup(chstr + 5); LocalizedDialogBoxParam(ID_DLG_AUTH_CHALLENGE, UserAuthDialogFunc, (LPARAM) param); } - else if (o.mfa_token == 1) + else if (param->c->flags & FLAG_TOKEN) { LocalizedDialogBoxParam(ID_DLG_AUTH_TOKEN, UserAuthDialogFunc, (LPARAM)param); } diff --git a/openvpn_config.c b/openvpn_config.c index e34401b..89e3a57 100644 --- a/openvpn_config.c +++ b/openvpn_config.c @@ -86,6 +86,43 @@ ConfigAlreadyExists(TCHAR *newconfig) return false; } +static int +IsTokenConfigured(connection_t* c, bool silent) +{ + FILE* fp = NULL; + char line[256]; + TCHAR configfile_path[MAX_PATH]; + int ret = 0; + + _tcsncpy(configfile_path, c->config_dir, _countof(configfile_path)); + if (!(configfile_path[_tcslen(configfile_path) - 1] == '\\')) + _tcscat(configfile_path, _T("\\")); + _tcsncat(configfile_path, c->config_file, + _countof(configfile_path) - _tcslen(configfile_path) - 1); + + if (!(fp = _tfopen(configfile_path, _T("r")))) + { + /* can't open config file */ + if (!silent) + ShowLocalizedMsg(IDS_ERR_OPEN_CONFIG, configfile_path); + goto out; + } + + while (fgets(line, sizeof(line), fp)) + { + if (strncmp(line, "# @OpenVPN_GUI token", 20) == 0) + { + ret = 1; + break; + } + } +out: + if (fp) + fclose(fp); + + return ret; +} + static void AddConfigFileToList(int group, const TCHAR *filename, const TCHAR *config_dir) { @@ -161,6 +198,9 @@ AddConfigFileToList(int group, const TCHAR *filename, const TCHAR *config_dir) { DisablePopupMessages(c); } + + if (IsTokenConfigured(c, true)) + c->flags |= FLAG_TOKEN; } #define FLAG_WARN_DUPLICATES (0x1) diff --git a/options.c b/options.c index 3b44dce..94e2581 100644 --- a/options.c +++ b/options.c @@ -218,11 +218,6 @@ add_option(options_t *options, int i, TCHAR **p) ++i; options->silent_connection = _ttoi(p[1]) ? 1 : 0; } - else if (streq(p[0], _T("mfa_token")) && p[1]) - { - ++i; - options->mfa_token = _ttoi(p[1]) ? 1 : 0; - } else if (streq(p[0], _T("passphrase_attempts")) && p[1]) { ++i; diff --git a/options.h b/options.h index b16eb21..19042b3 100644 --- a/options.h +++ b/options.h @@ -86,12 +86,13 @@ typedef struct { } service_io_t; #define FLAG_ALLOW_CHANGE_PASSPHRASE (1<<1) -#define FLAG_SAVE_KEY_PASS (1<<4) -#define FLAG_SAVE_AUTH_PASS (1<<5) -#define FLAG_DISABLE_SAVE_PASS (1<<6) -#define FLAG_DISABLE_ECHO_MSG (1<<7) -#define FLAG_DAEMON_PERSISTENT (1<<8) -#define FLAG_WAIT_UNLOCK (1<<9) +#define FLAG_SAVE_KEY_PASS (1<<4) +#define FLAG_SAVE_AUTH_PASS (1<<5) +#define FLAG_DISABLE_SAVE_PASS (1<<6) +#define FLAG_DISABLE_ECHO_MSG (1<<7) +#define FLAG_DAEMON_PERSISTENT (1<<8) +#define FLAG_WAIT_UNLOCK (1<<9) +#define FLAG_TOKEN (1<<10) #define CONFIG_VIEW_AUTO (0) #define CONFIG_VIEW_FLAT (1) @@ -214,7 +215,6 @@ typedef struct { TCHAR log_viewer[MAX_PATH]; TCHAR editor[MAX_PATH]; DWORD silent_connection; - DWORD mfa_token; DWORD iservice_admin; DWORD show_balloon; DWORD show_script_window; diff --git a/registry.c b/registry.c index a8c59e2..88cb17b 100644 --- a/registry.c +++ b/registry.c @@ -57,7 +57,6 @@ struct regkey_int { {L"iservice_admin", &o.iservice_admin, 1}, {L"show_balloon", &o.show_balloon, 1}, {L"silent_connection", &o.silent_connection, 0}, - {L"mfa_token", &o.mfa_token, 0}, {L"preconnectscript_timeout", &o.preconnectscript_timeout, 10}, {L"connectscript_timeout", &o.connectscript_timeout, 30}, {L"disconnectscript_timeout", &o.disconnectscript_timeout, 10}, diff --git a/res/openvpn-gui-res-de.rc b/res/openvpn-gui-res-de.rc index c1e5203..d6d87d2 100644 --- a/res/openvpn-gui-res-de.rc +++ b/res/openvpn-gui-res-de.rc @@ -175,26 +175,25 @@ BEGIN GROUPBOX "Benutzeroberfläche", 201, 6, 12, 235, 30 LTEXT "Spr&ache:", ID_TXT_LANGUAGE, 17, 25, 29, 12 COMBOBOX ID_CMB_LANGUAGE, 51, 23, 177, 400, CBS_DROPDOWNLIST | WS_TABSTOP - + GROUPBOX "Systemstart", 202, 6, 47, 235, 30 AUTOCHECKBOX "Mit &Windows starten", ID_CHK_STARTUP, 17, 59, 200, 12 - - GROUPBOX "Einstellungen", ID_GROUPBOX3, 6, 82, 235, 180 + + GROUPBOX "Einstellungen", ID_GROUPBOX3, 6, 82, 235, 165 AUTOCHECKBOX "An &Log anhängen", ID_CHK_LOG_APPEND, 17, 95, 200, 10 AUTOCHECKBOX "&Skriptfenster zeigen", ID_CHK_SHOW_SCRIPT_WIN, 17, 110, 200, 10 AUTOCHECKBOX "Stille &Verbindung", ID_CHK_SILENT, 17, 125, 200, 10 - AUTOCHECKBOX "MFA &Token", ID_CHK_TOKEN, 17, 140, 200, 10 - AUTOCHECKBOX "Interactive Service immer verwenden", ID_CHK_ALWAYS_USE_ISERVICE, 17, 155, 200, 10 - LTEXT "Zeige Benachrichtigung", ID_TXT_BALLOON, 17, 170, 100, 10 - AUTORADIOBUTTON "Beim Verb&inden", ID_RB_BALLOON1, 17, 185, 60, 10, WS_GROUP | WS_TABSTOP - AUTORADIOBUTTON "Beim Verbinden/&erneut Verbinden", ID_RB_BALLOON2, 83, 185, 120, 10 - AUTORADIOBUTTON "&Nie", ID_RB_BALLOON0, 210, 185, 30, 10 - LTEXT "Persistent Connections", ID_TXT_PERSISTENT, 17, 200, 100, 10 - AUTORADIOBUTTON "A&uto", ID_RB_BALLOON3, 17, 215, 60, 10, WS_GROUP | WS_TABSTOP - AUTORADIOBUTTON "&Manual", ID_RB_BALLOON4, 83, 215, 90, 10 - AUTORADIOBUTTON "&Disable", ID_RB_BALLOON5, 180, 215, 50, 10 - AUTOCHECKBOX "Enable Pre-Logon A&ccess Provider (requires admin access)", ID_CHK_PLAP_REG, 17, 230, 200, 10 - AUTOCHECKBOX "Enable auto restart of active connections", ID_CHK_AUTO_RESTART, 17, 245, 200, 10 + AUTOCHECKBOX "Interactive Service immer verwenden", ID_CHK_ALWAYS_USE_ISERVICE, 17, 140, 200, 10 + LTEXT "Zeige Benachrichtigung", ID_TXT_BALLOON, 17, 155, 100, 10 + AUTORADIOBUTTON "Beim Verb&inden", ID_RB_BALLOON1, 17, 170, 60, 10, WS_GROUP | WS_TABSTOP + AUTORADIOBUTTON "Beim Verbinden/&erneut Verbinden", ID_RB_BALLOON2, 83, 170, 120, 10 + AUTORADIOBUTTON "&Nie", ID_RB_BALLOON0, 210, 170, 30, 10 + LTEXT "Persistent Connections", ID_TXT_PERSISTENT, 17, 185, 100, 10 + AUTORADIOBUTTON "A&uto", ID_RB_BALLOON3, 17, 200, 60, 10, WS_GROUP | WS_TABSTOP + AUTORADIOBUTTON "&Manual", ID_RB_BALLOON4, 83, 200, 90, 10 + AUTORADIOBUTTON "&Disable", ID_RB_BALLOON5, 180, 200, 50, 10 + AUTOCHECKBOX "Enable Pre-Logon A&ccess Provider (requires admin access)", ID_CHK_PLAP_REG, 17, 215, 200, 10 + AUTOCHECKBOX "Enable auto restart of active connections", ID_CHK_AUTO_RESTART, 17, 230, 200, 10 END /* Advanced Dialog */ diff --git a/res/openvpn-gui-res-en.rc b/res/openvpn-gui-res-en.rc index 0525940..4bb1621 100644 --- a/res/openvpn-gui-res-en.rc +++ b/res/openvpn-gui-res-en.rc @@ -189,26 +189,25 @@ BEGIN GROUPBOX "User Interface", 201, 6, 12, 235, 30 LTEXT "&Language:", ID_TXT_LANGUAGE, 17, 25, 52, 12 COMBOBOX ID_CMB_LANGUAGE, 57, 23, 171, 400, CBS_DROPDOWNLIST | WS_TABSTOP - + GROUPBOX "Startup", 202, 6, 47, 235, 30 AUTOCHECKBOX "Launch on User &Logon", ID_CHK_STARTUP, 17, 59, 100, 12 - - GROUPBOX "Preferences", ID_GROUPBOX3, 6, 82, 235, 180 + + GROUPBOX "Preferences", ID_GROUPBOX3, 6, 82, 235, 165 AUTOCHECKBOX "A&ppend to log", ID_CHK_LOG_APPEND, 17, 95, 60, 10 AUTOCHECKBOX "Show script &window", ID_CHK_SHOW_SCRIPT_WIN, 17, 110, 200, 10 AUTOCHECKBOX "S&ilent connection", ID_CHK_SILENT, 17, 125, 200, 10 - AUTOCHECKBOX "MFA &Token", ID_CHK_TOKEN, 17, 140, 200, 10 - AUTOCHECKBOX "&Always use interactive service", ID_CHK_ALWAYS_USE_ISERVICE, 17, 155, 200, 10 - LTEXT "Show Balloon", ID_TXT_BALLOON, 17, 170, 100, 10 - AUTORADIOBUTTON "On &connect", ID_RB_BALLOON1, 28, 185, 50, 10, WS_GROUP | WS_TABSTOP - AUTORADIOBUTTON "On connect/&reconnect", ID_RB_BALLOON2, 86, 185, 90, 10 - AUTORADIOBUTTON "&Never", ID_RB_BALLOON0, 181, 185, 40, 10 - LTEXT "Persistent Connections", ID_TXT_PERSISTENT, 17, 200, 100, 10 - AUTORADIOBUTTON "A&uto", ID_RB_BALLOON3, 28, 215, 50, 10, WS_GROUP | WS_TABSTOP - AUTORADIOBUTTON "&Manual", ID_RB_BALLOON4, 86, 215, 90, 10 - AUTORADIOBUTTON "&Disable", ID_RB_BALLOON5, 181, 215, 40, 10 - AUTOCHECKBOX "Enable Pre-Logon A&ccess Provider (requires admin access)", ID_CHK_PLAP_REG, 17, 230, 200, 10 - AUTOCHECKBOX "Enable auto restart of active connections", ID_CHK_AUTO_RESTART, 17, 245, 200, 10 + AUTOCHECKBOX "&Always use interactive service", ID_CHK_ALWAYS_USE_ISERVICE, 17, 140, 200, 10 + LTEXT "Show Balloon", ID_TXT_BALLOON, 17, 155, 100, 10 + AUTORADIOBUTTON "On &connect", ID_RB_BALLOON1, 28, 170, 50, 10, WS_GROUP | WS_TABSTOP + AUTORADIOBUTTON "On connect/&reconnect", ID_RB_BALLOON2, 86, 170, 90, 10 + AUTORADIOBUTTON "&Never", ID_RB_BALLOON0, 181, 170, 40, 10 + LTEXT "Persistent Connections", ID_TXT_PERSISTENT, 17, 185, 100, 10 + AUTORADIOBUTTON "A&uto", ID_RB_BALLOON3, 28, 200, 50, 10, WS_GROUP | WS_TABSTOP + AUTORADIOBUTTON "&Manual", ID_RB_BALLOON4, 86, 200, 90, 10 + AUTORADIOBUTTON "&Disable", ID_RB_BALLOON5, 181, 200, 40, 10 + AUTOCHECKBOX "Enable Pre-Logon A&ccess Provider (requires admin access)", ID_CHK_PLAP_REG, 17, 215, 200, 10 + AUTOCHECKBOX "Enable auto restart of active connections", ID_CHK_AUTO_RESTART, 17, 230, 200, 10 END /* Advanced Dialog */