From e9cb844a980f5fcb187c45cbc3cf885828b98f37 Mon Sep 17 00:00:00 2001 From: Selva Nair Date: Sun, 24 Jun 2018 20:02:24 -0400 Subject: [PATCH] Make script security setting editable by user - Add a connection-specific dialog with - options to override in the config file (currently only script-security) - check boxes for saving credentials or clearing saved ones. - stubs for "save username" and change the config display name are added (not enabled). Accessible via tray->config-name->Options popup menu The clear-saved-passwords menu item is removed as that functionality is moved to this dialog. Signed-off-by: Selva Nair --- main.c | 3 + openvpn-gui-res.h | 9 +++ openvpn_config.c | 121 +++++++++++++++++++++++++++++++++++++- openvpn_config.h | 3 + res/openvpn-gui-res-en.rc | 30 ++++++++++ tray.c | 14 ++--- tray.h | 1 + 7 files changed, 170 insertions(+), 11 deletions(-) diff --git a/main.c b/main.c index ff91b4f..e68bcdb 100644 --- a/main.c +++ b/main.c @@ -559,6 +559,9 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM if ( (LOWORD(wParam) >= IDM_CLEARPASSMENU) && (LOWORD(wParam) < IDM_CLEARPASSMENU + MAX_CONFIGS) ) { ResetSavePasswords(&o.conn[LOWORD(wParam) - IDM_CLEARPASSMENU]); } + if ( (LOWORD(wParam) >= IDM_CONFIGUREMENU) && (LOWORD(wParam) < IDM_CONFIGUREMENU + MAX_CONFIGS) ) { + ConfigOptions(&o.conn[LOWORD(wParam) - IDM_CONFIGUREMENU]); + } #ifndef DISABLE_CHANGE_PASSWORD if ( (LOWORD(wParam) >= IDM_PASSPHRASEMENU) && (LOWORD(wParam) < IDM_PASSPHRASEMENU + MAX_CONFIGS) ) { ShowChangePassphraseDialog(&o.conn[LOWORD(wParam) - IDM_PASSPHRASEMENU]); diff --git a/openvpn-gui-res.h b/openvpn-gui-res.h index 6b1d3d9..641afb2 100644 --- a/openvpn-gui-res.h +++ b/openvpn-gui-res.h @@ -122,6 +122,14 @@ /* Connections dialog */ #define ID_DLG_CONNECTIONS 290 +#define ID_TXT_PATH 291 +#define ID_EDT_DISPLAY_NAME 292 +#define ID_CHK_AUTH_USER 293 +#define ID_CHK_AUTH_PASS 294 +#define ID_CHK_KEY_PASS 295 +#define ID_CMB_SCRIPT_SECURITY 296 +#define IDS_SCRIPT_NO_OVERRIDE 297 +#define IDS_ALLOW_SCRIPT_BUILT_IN 299 /* * String Table Resources @@ -154,6 +162,7 @@ #define IDS_MENU_IMPORT 1023 #define IDS_MENU_CLEARPASS 1024 #define IDS_MENU_RECONNECT 1025 +#define IDS_MENU_CONFIGURE 1026 /* LogViewer Dialog */ #define IDS_ERR_START_LOG_VIEWER 1101 diff --git a/openvpn_config.c b/openvpn_config.c index 350ee6a..c2ecf68 100644 --- a/openvpn_config.c +++ b/openvpn_config.c @@ -3,7 +3,7 @@ * * Copyright (C) 2004 Mathias Sundman * 2010 Heiko Hund - * 2016 Selva Nair + * 2016-2018 Selva Nair * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,6 +26,7 @@ #endif #include +#include #include "main.h" #include "openvpn-gui-res.h" @@ -35,6 +36,7 @@ #include "misc.h" #include "passphrase.h" #include "openvpn_config.h" +#include "script_security.h" typedef enum { @@ -45,6 +47,8 @@ typedef enum extern options_t o; +static const wchar_t *cfgProp = L"config"; + static match_t match(const WIN32_FIND_DATA *find, const TCHAR *ext) { @@ -411,3 +415,118 @@ RecallConfigFlags(const connection_t *c) flags = 0; return flags; } + +/* + * DialogProc for connection specific options + */ +INT_PTR CALLBACK +ConfigOptionsDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + wchar_t fname[MAX_PATH]; + connection_t *c; + int ssec_flag; + HWND h; + struct { + int id; + int flag; + } ssec_data[] = {{IDS_ALLOW_SCRIPT_BUILT_IN, SSEC_BUILT_IN}, + {IDS_SCRIPT_NO_OVERRIDE, SSEC_UNDEF}}; + + switch (msg) + { + case WM_INITDIALOG: + c = (connection_t *) lParam; + SetProp(hwndDlg, cfgProp, (HANDLE) c); + + wcs_concat2(fname, _countof(fname), c->config_dir, c->config_file, L"\\"); + SetDlgItemText(hwndDlg, ID_TXT_PATH, fname); + SetDlgItemText(hwndDlg, ID_EDT_DISPLAY_NAME, c->config_name); + + if (c->flags & FLAG_SAVE_AUTH_PASS) + Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_AUTH_PASS), BST_CHECKED); + if (c->flags & FLAG_SAVE_KEY_PASS) + Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_KEY_PASS), BST_CHECKED); + + /* disable/hide items not yet user-editable */ + SendDlgItemMessage(hwndDlg, ID_EDT_DISPLAY_NAME, EM_SETREADONLY, 1, 0); + ShowWindow(GetDlgItem(hwndDlg, ID_CHK_AUTH_USER), SW_HIDE); + + h = GetDlgItem(hwndDlg, ID_CMB_SCRIPT_SECURITY); + ssec_flag = get_script_security(c); + + for (size_t i = 0; i < _countof(ssec_data); i++) + { + int index = ComboBox_AddString(h, LoadLocalizedString(ssec_data[i].id)); + ComboBox_SetItemData(h, index, ssec_data[i].flag); + if (ssec_flag == ssec_data[i].flag) + ComboBox_SetCurSel(h, index); + } + SetFocus(h); + + break; + + case WM_COMMAND: + c = (connection_t *) GetProp(hwndDlg, cfgProp); + switch (LOWORD(wParam)) + { + case IDOK: + if (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_AUTH_PASS)) == BST_CHECKED) + { + if (!(c->flags & FLAG_SAVE_AUTH_PASS)) + c->flags |= FLAG_SAVE_AUTH_PASS; + } + else if (c->flags & FLAG_SAVE_AUTH_PASS) + { + c->flags &= ~FLAG_SAVE_AUTH_PASS; + DeleteSavedAuthPass(c->config_name); + } + if (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_KEY_PASS)) == BST_CHECKED) + { + if (!(c->flags & FLAG_SAVE_KEY_PASS)) + c->flags |= FLAG_SAVE_KEY_PASS; + } + else if (c->flags & FLAG_SAVE_KEY_PASS) + { + c->flags &= ~FLAG_SAVE_KEY_PASS; + DeleteSavedKeyPass(c->config_name); + } + /* toggling user name save not yet implemented */ + + /* save flags in registry */ + PersistConfigFlags(c); + + /* set script security preference, if changed */ + { + int sel = ComboBox_GetCurSel(GetDlgItem(hwndDlg, ID_CMB_SCRIPT_SECURITY)); + int ssec_flag = sel != CB_ERR ? ssec_data[sel].flag : ssec_default(); + + if (ssec_flag != get_script_security(c)) + set_script_security(c, ssec_flag); + } + + EndDialog(hwndDlg, LOWORD(wParam)); + return TRUE; + + case IDCANCEL: + EndDialog(hwndDlg, LOWORD(wParam)); + return TRUE; + } + break; + + case WM_CLOSE: + EndDialog(hwndDlg, LOWORD(wParam)); + return TRUE; + + case WM_NCDESTROY: + RemoveProp(hwndDlg, cfgProp); + break; + } + + return FALSE; +} + +void +ConfigOptions(connection_t *c) +{ + LocalizedDialogBoxParam(ID_DLG_CONNECTIONS, ConfigOptionsDialogFunc, (LPARAM) c); +} diff --git a/openvpn_config.h b/openvpn_config.h index 320c92d..3ae8811 100644 --- a/openvpn_config.h +++ b/openvpn_config.h @@ -34,4 +34,7 @@ void PersistConfigFlags(const connection_t *c); /* recall config preference flags from registry */ DWORD RecallConfigFlags(const connection_t *c); +/* Open a dialog to edit connection specific options */ +void ConfigOptions(connection_t *c); + #endif diff --git a/res/openvpn-gui-res-en.rc b/res/openvpn-gui-res-en.rc index 7a4f32d..add6dda 100644 --- a/res/openvpn-gui-res-en.rc +++ b/res/openvpn-gui-res-en.rc @@ -195,6 +195,31 @@ BEGIN EDITTEXT ID_EDT_DISCONNECT_TIMEOUT, 103, 138, 20, 12, ES_AUTOHSCROLL|ES_NUMBER END +/* Connection specific options */ +ID_DLG_CONNECTIONS DIALOGEX 6, 18, 252, 218 +STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_CENTER +CAPTION "Connection profile configuration" +FONT 8, "Microsoft Sans Serif" +LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT +BEGIN + GROUPBOX "Configuration File", 201, 6, 12, 235, 45 + CONTROL "Path:", ID_TXT_PATH, "Static", SS_LEFTNOWORDWRAP, 17, 25, 225, 10 + LTEXT "&Display Name:", 202, 17, 40, 50, 10 + EDITTEXT ID_EDT_DISPLAY_NAME, 67, 38, 100, 12, ES_AUTOHSCROLL + + GROUPBOX "Credentials", 203, 6, 62, 235, 45 + AUTOCHECKBOX "Save &password", ID_CHK_AUTH_PASS, 17, 75, 90, 10 + AUTOCHECKBOX "Save &username", ID_CHK_AUTH_USER, 115, 90, 90, 10 + AUTOCHECKBOX "Save private &key password", ID_CHK_KEY_PASS, 17, 90, 110, 10 + + GROUPBOX "Security", 204, 6, 112, 235, 45 + LTEXT "Allow &script execution", 205, 17, 125, 100, 10 + COMBOBOX ID_CMB_SCRIPT_SECURITY, 17, 138, 200, 60, CBS_DROPDOWNLIST | WS_TABSTOP + + PUSHBUTTON "&OK", IDOK, 132, 195, 50, 14 + PUSHBUTTON "&Cancel", IDCANCEL, 192, 195, 50, 14 +END + /* About Dialog */ ID_DLG_ABOUT DIALOG 6, 18, 249, 104 STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_CENTER @@ -261,6 +286,7 @@ BEGIN IDS_MENU_SERVICEONLY_STOP "Disconnect" IDS_MENU_SERVICEONLY_RESTART "Reconnect" IDS_MENU_ASK_STOP_SERVICE "Do you want to disconnect (Stop the OpenVPN Service)?" + IDS_MENU_CONFIGURE "Options" /* Logviewer - Resources */ IDS_ERR_START_LOG_VIEWER "Error starting log-viewer: %s" @@ -475,4 +501,8 @@ BEGIN IDS_NFO_CLICK_HERE_TO_START "OpenVPN GUI is already running. Right click on the tray icon to start." IDS_NFO_BYTECOUNT "Bytes in: %s out: %s" + /* script security related */ + IDS_ALLOW_SCRIPT_BUILT_IN "Built-in commands only (recommended)" + IDS_SCRIPT_NO_OVERRIDE "Use config file setting (potentially unsafe)" + END diff --git a/tray.c b/tray.c index fa6e8cb..b3fcfb7 100644 --- a/tray.c +++ b/tray.c @@ -95,7 +95,7 @@ CreatePopupMenus() AppendMenu(hMenu, MF_STRING, IDM_VIEWLOGMENU, LoadLocalizedString(IDS_MENU_VIEWLOG)); AppendMenu(hMenu, MF_STRING, IDM_EDITMENU, LoadLocalizedString(IDS_MENU_EDITCONFIG)); - AppendMenu(hMenu, MF_STRING, IDM_CLEARPASSMENU, LoadLocalizedString(IDS_MENU_CLEARPASS)); + AppendMenu(hMenu, MF_STRING, IDM_CONFIGUREMENU, LoadLocalizedString(IDS_MENU_CONFIGURE)); #ifndef DISABLE_CHANGE_PASSWORD if (o.conn[0].flags & FLAG_ALLOW_CHANGE_PASSPHRASE) @@ -178,7 +178,7 @@ CreatePopupMenus() AppendMenu(hMenuConn[i], MF_STRING, IDM_VIEWLOGMENU + i, LoadLocalizedString(IDS_MENU_VIEWLOG)); AppendMenu(hMenuConn[i], MF_STRING, IDM_EDITMENU + i, LoadLocalizedString(IDS_MENU_EDITCONFIG)); - AppendMenu(hMenuConn[i], MF_STRING, IDM_CLEARPASSMENU + i, LoadLocalizedString(IDS_MENU_CLEARPASS)); + AppendMenu(hMenuConn[i], MF_STRING, IDM_CONFIGUREMENU + i, LoadLocalizedString(IDS_MENU_CONFIGURE)); #ifndef DISABLE_CHANGE_PASSWORD if (o.conn[i].flags & FLAG_ALLOW_CHANGE_PASSPHRASE) @@ -441,10 +441,7 @@ SetMenuStatusById(int i, conn_state_t state) EnableMenuItem(hMenu, IDM_RECONNECTMENU, MF_GRAYED); EnableMenuItem(hMenu, IDM_STATUSMENU, MF_ENABLED); } - if (c->flags & (FLAG_SAVE_AUTH_PASS | FLAG_SAVE_KEY_PASS)) - EnableMenuItem(hMenu, IDM_CLEARPASSMENU, MF_ENABLED); - else - EnableMenuItem(hMenu, IDM_CLEARPASSMENU, MF_GRAYED); + EnableMenuItem(hMenu, IDM_CONFIGUREMENU, MF_ENABLED); } else { @@ -490,10 +487,7 @@ SetMenuStatusById(int i, conn_state_t state) EnableMenuItem(hMenuConn[i], IDM_RECONNECTMENU + i, MF_GRAYED); EnableMenuItem(hMenuConn[i], IDM_STATUSMENU + i, MF_ENABLED); } - if (c->flags & (FLAG_SAVE_AUTH_PASS | FLAG_SAVE_KEY_PASS)) - EnableMenuItem(hMenuConn[i], IDM_CLEARPASSMENU + i, MF_ENABLED); - else - EnableMenuItem(hMenuConn[i], IDM_CLEARPASSMENU + i, MF_GRAYED); + EnableMenuItem(hMenuConn[i], IDM_CONFIGUREMENU + i, MF_ENABLED); } } diff --git a/tray.h b/tray.h index 7aa6924..31e08db 100644 --- a/tray.h +++ b/tray.h @@ -41,6 +41,7 @@ #define IDM_PASSPHRASEMENU (MAX_CONFIGS + IDM_EDITMENU) #define IDM_CLEARPASSMENU (MAX_CONFIGS + IDM_PASSPHRASEMENU) #define IDM_RECONNECTMENU (MAX_CONFIGS + IDM_CLEARPASSMENU) +#define IDM_CONFIGUREMENU (MAX_CONFIGS + IDM_RECONNECTMENU) void CreatePopupMenus(); void OnNotifyTray(LPARAM);