diff --git a/Makefile.am b/Makefile.am index c1753e0..ee0b677 100644 --- a/Makefile.am +++ b/Makefile.am @@ -79,6 +79,7 @@ openvpn_gui_SOURCES = \ registry.c registry.h \ scripts.c scripts.h \ manage.c manage.h \ + misc.c misc.h \ openvpn_config.c \ openvpn_config.h \ chartable.h \ diff --git a/manage.c b/manage.c index 77ae048..c172e34 100644 --- a/manage.c +++ b/manage.c @@ -28,8 +28,9 @@ #include #include "options.h" -#include "main.h" #include "manage.h" +#include "main.h" +#include "misc.h" extern options_t o; @@ -155,6 +156,9 @@ UnqueueCommand(connection_t *c) if (!cmd) return FALSE; + /* Wipe command as it may contain passwords */ + memset(cmd->command, 'x', cmd->size); + if (cmd->type == combined) { cmd->type = regular; diff --git a/misc.c b/misc.c new file mode 100644 index 0000000..9d76a5f --- /dev/null +++ b/misc.c @@ -0,0 +1,104 @@ +/* + * OpenVPN-GUI -- A Windows GUI for OpenVPN. + * + * Copyright (C) 2012 Heiko Hund + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include "options.h" +#include "manage.h" +#include "misc.h" + +/* + * Helper function to convert UCS-2 text from a dialog item to UTF-8. + * Caller must free *str if *len != 0. + */ +static BOOL +GetDlgItemTextUtf8(HWND hDlg, int id, LPSTR *str, int *len) +{ + int ucs2_len, utf8_len; + BOOL retval = FALSE; + LPTSTR ucs2_str = NULL; + LPSTR utf8_str = NULL; + + *str = ""; + *len = 0; + + ucs2_len = GetWindowTextLength(GetDlgItem(hDlg, id)) + 1; + if (ucs2_len == 0) + goto out; + + ucs2_str = malloc(ucs2_len * sizeof(*ucs2_str)); + if (ucs2_str == NULL) + goto out; + + if (GetDlgItemText(hDlg, id, ucs2_str, ucs2_len) == 0) + goto out; + + utf8_len = WideCharToMultiByte(CP_UTF8, 0, ucs2_str, -1, NULL, 0, NULL, NULL); + utf8_str = malloc(utf8_len); + if (utf8_str == NULL) + goto out; + + WideCharToMultiByte(CP_UTF8, 0, ucs2_str, -1, utf8_str, utf8_len, NULL, NULL); + + *str = utf8_str; + *len = utf8_len - 1; + retval = TRUE; +out: + free(ucs2_str); + return retval; +} + + +/* + * Generate a management command from user input and send it + */ +BOOL +ManagementCommandFromInput(connection_t *c, LPSTR fmt, HWND hDlg, int id) +{ + BOOL retval = FALSE; + LPSTR input, cmd; + int input_len, cmd_len; + + GetDlgItemTextUtf8(hDlg, id, &input, &input_len); + + cmd_len = input_len + strlen(fmt); + cmd = malloc(cmd_len); + if (cmd) + { + snprintf(cmd, cmd_len, fmt, input); + retval = ManagementCommand(c, cmd, NULL, regular); + free(cmd); + } + + /* Clear buffers with potentially secret content */ + memset(input, 'x', input_len - 1); + SetDlgItemTextA(hDlg, id, input); + free(input); + + return retval; +} + diff --git a/misc.h b/misc.h new file mode 100644 index 0000000..48da5a2 --- /dev/null +++ b/misc.h @@ -0,0 +1,27 @@ +/* + * OpenVPN-GUI -- A Windows GUI for OpenVPN. + * + * Copyright (C) 2012 Heiko Hund + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING included with this + * distribution); if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef MISC_H +#define MISC_H + +BOOL ManagementCommandFromInput(connection_t *, LPSTR, HWND, int); + +#endif diff --git a/openvpn.c b/openvpn.c index 505670f..de399e0 100644 --- a/openvpn.c +++ b/openvpn.c @@ -42,6 +42,7 @@ #include "proxy.h" #include "passphrase.h" #include "localization.h" +#include "misc.h" #define WM_OVPN_STOP (WM_APP + 10) #define WM_OVPN_SUSPEND (WM_APP + 11) @@ -204,10 +205,6 @@ static INT_PTR CALLBACK UserAuthDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { connection_t *c; - TCHAR buf[50]; - char cmd[70] = "username \"Auth\" \""; - UINT username_len; - int length; switch (msg) { @@ -222,25 +219,8 @@ UserAuthDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) switch (LOWORD(wParam)) { case IDOK: - username_len = GetDlgItemText(hwndDlg, ID_EDT_AUTH_USER, buf, _countof(buf)); - if (username_len == 0) - return TRUE; - length = WideCharToMultiByte(CP_UTF8, 0, buf, -1, cmd + 17, sizeof(cmd) - 17, NULL, NULL); - memcpy(cmd + length + 16, "\"\0", 2); - ManagementCommand(c, cmd, NULL, regular); - - memcpy(cmd, "password", 8); - GetDlgItemText(hwndDlg, ID_EDT_AUTH_PASS, buf, _countof(buf)); - length = WideCharToMultiByte(CP_UTF8, 0, buf, -1, cmd + 17, sizeof(cmd) - 17, NULL, NULL); - memcpy(cmd + length + 16, "\"\0", 2); - ManagementCommand(c, cmd, NULL, regular); - - /* Clear buffers */ - memset(buf, 'x', sizeof(buf)); - buf[_countof(buf) - 1] = _T('\0'); - SetDlgItemText(hwndDlg, ID_EDT_AUTH_USER, buf); - SetDlgItemText(hwndDlg, ID_EDT_AUTH_PASS, buf); - + ManagementCommandFromInput(c, "username \"Auth\" \"%s\"", hwndDlg, ID_EDT_AUTH_USER); + ManagementCommandFromInput(c, "password \"Auth\" \"%s\"", hwndDlg, ID_EDT_AUTH_PASS); EndDialog(hwndDlg, LOWORD(wParam)); return TRUE; @@ -271,9 +251,6 @@ static INT_PTR CALLBACK PrivKeyPassDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { connection_t *c; - TCHAR buf[50]; - char cmd[80] = "password \"Private Key\" \""; - UINT length; switch (msg) { @@ -287,16 +264,7 @@ PrivKeyPassDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) switch (LOWORD(wParam)) { case IDOK: - GetDlgItemText(hwndDlg, ID_EDT_PASSPHRASE, buf, _countof(buf)); - length = WideCharToMultiByte(CP_UTF8, 0, buf, -1, cmd + 24, sizeof(cmd) - 24, NULL, NULL); - memcpy(cmd + length + 23, "\"\0", 2); - ManagementCommand(c, cmd, NULL, regular); - - /* Clear buffer */ - memset(buf, 'x', sizeof(buf)); - buf[_countof(buf) - 1] = _T('\0'); - SetDlgItemText(hwndDlg, ID_EDT_PASSPHRASE, buf); - + ManagementCommandFromInput(c, "password \"Private Key\" \"%s\"", hwndDlg, ID_EDT_PASSPHRASE); EndDialog(hwndDlg, LOWORD(wParam)); return TRUE; diff --git a/proxy.c b/proxy.c index 9860864..fb779c4 100644 --- a/proxy.c +++ b/proxy.c @@ -39,6 +39,7 @@ #include "localization.h" #include "manage.h" #include "openvpn.h" +#include "misc.h" extern options_t o; @@ -327,10 +328,6 @@ INT_PTR CALLBACK ProxyAuthDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { connection_t *c; - TCHAR buf[50]; - char cmd[70] = "username \"HTTP Proxy\" \""; - UINT username_len; - int length; switch (msg) { @@ -345,25 +342,8 @@ ProxyAuthDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { case IDOK: c = (connection_t *) GetProp(hwndDlg, cfgProp); - username_len = GetDlgItemText(hwndDlg, ID_EDT_PROXY_USER, buf, _countof(buf)); - if (username_len == 0) - return TRUE; - length = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, buf, -1, cmd + 23, sizeof(cmd) - 23, "_", NULL); - memcpy(cmd + length + 22, "\"\0", 2); - ManagementCommand(c, cmd, NULL, regular); - - memcpy(cmd, "password", 8); - GetDlgItemText(hwndDlg, ID_EDT_PROXY_PASS, buf, _countof(buf)); - length = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, buf, -1, cmd + 23, sizeof(cmd) - 23, "_", NULL); - memcpy(cmd + length + 22, "\"\0", 2); - ManagementCommand(c, cmd, NULL, regular); - - /* Clear buffers */ - memset(buf, 'x', sizeof(buf)); - buf[_countof(buf) - 1] = _T('\0'); - SetDlgItemText(hwndDlg, ID_EDT_PROXY_USER, buf); - SetDlgItemText(hwndDlg, ID_EDT_PROXY_PASS, buf); - + ManagementCommandFromInput(c, "username \"HTTP Proxy\" \"%s\"", hwndDlg, ID_EDT_PROXY_USER); + ManagementCommandFromInput(c, "password \"HTTP Proxy\" \"%s\"", hwndDlg, ID_EDT_PROXY_PASS); EndDialog(hwndDlg, LOWORD(wParam)); return TRUE; }