diff --git a/access.c b/access.c index de164ae..69e2460 100644 --- a/access.c +++ b/access.c @@ -44,7 +44,9 @@ extern options_t o; #define MAX_UNAME_LEN (UNLEN + DNLEN + 2) /* UNLEN, DNLEN from lmcons.h +2 for '\' and NULL */ static BOOL GetOwnerSID(PSID sid, DWORD sid_size); + static BOOL IsUserInGroup(PSID sid, PTOKEN_GROUPS token_groups, const WCHAR *group_name); + static PTOKEN_GROUPS GetProcessTokenGroups(void); /* @@ -52,7 +54,7 @@ static PTOKEN_GROUPS GetProcessTokenGroups(void); * Get the local name of the group using the SID. */ static BOOL -GetBuiltinAdminGroupName (WCHAR *name, DWORD nlen) +GetBuiltinAdminGroupName(WCHAR *name, DWORD nlen) { BOOL b = FALSE; PSID admin_sid = NULL; @@ -64,19 +66,21 @@ GetBuiltinAdminGroupName (WCHAR *name, DWORD nlen) admin_sid = malloc(sid_size); if (!admin_sid) + { return FALSE; + } b = CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, - &sid_size); - if(b) + &sid_size); + if (b) { b = LookupAccountSidW(NULL, admin_sid, name, &nlen, domain, &dlen, &su); } #ifdef DEBUG - PrintDebug (L"builtin admin group name = %ls", name); + PrintDebug(L"builtin admin group name = %ls", name); #endif - free (admin_sid); + free(admin_sid); return b; } @@ -86,7 +90,7 @@ GetBuiltinAdminGroupName (WCHAR *name, DWORD nlen) * Reject if the group name contains certain illegal characters. */ static BOOL -AddUserToGroup (const WCHAR *group) +AddUserToGroup(const WCHAR *group) { WCHAR username[MAX_UNAME_LEN]; WCHAR cmd[MAX_PATH] = L"C:\\windows\\system32\\cmd.exe"; @@ -109,17 +113,19 @@ AddUserToGroup (const WCHAR *group) if (wcspbrk(group, reject) != NULL) { #ifdef DEBUG - PrintDebug (L"AddUSerToGroup: illegal characters in group name: '%ls'.", group); + PrintDebug(L"AddUSerToGroup: illegal characters in group name: '%ls'.", group); #endif return retval; } size = _countof(username); - if (!GetUserNameExW (NameSamCompatible, username, &size)) + if (!GetUserNameExW(NameSamCompatible, username, &size)) + { return retval; + } size = _countof(syspath); - if (GetSystemDirectory (syspath, size)) + if (GetSystemDirectory(syspath, size)) { syspath[size-1] = L'\0'; size = _countof(cmd); @@ -130,26 +136,34 @@ AddUserToGroup (const WCHAR *group) netcmd[size-1] = L'\0'; } size = (wcslen(fmt) + wcslen(username) + 2*wcslen(group) + 2*wcslen(netcmd)+ 1); - if ((params = malloc (size*sizeof(WCHAR))) == NULL) + if ((params = malloc(size*sizeof(WCHAR))) == NULL) + { return retval; + } _snwprintf(params, size, fmt, netcmd, group, netcmd, group, username); params[size-1] = L'\0'; - status = RunAsAdmin (cmd, params); + status = RunAsAdmin(cmd, params); if (status == 0) + { retval = TRUE; + } #ifdef DEBUG if (status == (DWORD) -1) + { PrintDebug(L"RunAsAdmin: failed to execute the command [%ls %ls] : error = 0x%x", - cmd, params, GetLastError()); + cmd, params, GetLastError()); + } else if (status) + { PrintDebug(L"RunAsAdmin: command [%ls %ls] returned exit_code = %lu", - cmd, params, status); + cmd, params, status); + } #endif - free (params); + free(params); return retval; } @@ -158,18 +172,22 @@ AddUserToGroup (const WCHAR *group) * interactive service. */ static BOOL -CheckConfigPath (const WCHAR *config_dir) +CheckConfigPath(const WCHAR *config_dir) { BOOL ret = FALSE; int size = wcslen(o.global_config_dir); /* if interactive service is not running, no access control: return TRUE */ if (!CheckIServiceStatus(FALSE)) + { ret = TRUE; + } /* if config is from the global location allow it */ else if (wcsncmp(config_dir, o.global_config_dir, size) == 0 && wcsstr(config_dir + size, L"..") == NULL) + { ret = TRUE; + } return ret; } @@ -192,19 +210,27 @@ AuthorizeConfig(const connection_t *c) PTOKEN_GROUPS groups = NULL; if (GetBuiltinAdminGroupName(sysadmin_group, _countof(sysadmin_group))) + { admin_group = sysadmin_group; + } else + { admin_group = L"Administrators"; + } PrintDebug(L"Authorized groups: '%ls', '%ls'", admin_group, o.ovpn_admin_group); if (CheckConfigPath(c->config_dir)) + { return TRUE; + } if (!GetOwnerSID(sid, sid_size)) { if (!o.silent_connection) + { MessageBoxW(NULL, L"Failed to determine process owner SID", L""PACKAGE_NAME, MB_OK); + } return FALSE; } groups = GetProcessTokenGroups(); @@ -225,7 +251,7 @@ AuthorizeConfig(const connection_t *c) return FALSE; } - if (WaitForSingleObject (o.netcmd_semaphore, 0) != WAIT_OBJECT_0) + if (WaitForSingleObject(o.netcmd_semaphore, 0) != WAIT_OBJECT_0) { /* Could not lock semaphore -- auth dialog already running? */ ShowLocalizedMsg(IDS_NFO_CONFIG_AUTH_PENDING, c->config_name, o.ovpn_admin_group); @@ -237,17 +263,21 @@ AuthorizeConfig(const connection_t *c) o.ovpn_admin_group); if (res == IDYES) { - AddUserToGroup (o.ovpn_admin_group); + AddUserToGroup(o.ovpn_admin_group); /* * Check the success of above by testing the group membership again */ if (IsUserInGroup(sid, NULL, o.ovpn_admin_group)) + { retval = TRUE; + } else + { ShowLocalizedMsg(IDS_ERR_ADD_USER_TO_ADMIN_GROUP, o.ovpn_admin_group); - SetForegroundWindow (o.hWnd); + } + SetForegroundWindow(o.hWnd); } - ReleaseSemaphore (o.netcmd_semaphore, 1, NULL); + ReleaseSemaphore(o.netcmd_semaphore, 1, NULL); return retval; } @@ -287,7 +317,9 @@ GetProcessTokenGroups(void) DWORD buf_size = 0; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) + { return NULL; + } if (!GetTokenInformation(token, TokenGroups, NULL, 0, &buf_size) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { @@ -301,7 +333,7 @@ GetProcessTokenGroups(void) if (!GetTokenInformation(token, TokenGroups, groups, buf_size, &buf_size)) { PrintDebug(L"Failed to get Token Group Information: error = %lu", GetLastError); - free (groups); + free(groups); groups = NULL; } @@ -345,7 +377,9 @@ IsUserInGroup(PSID sid, const PTOKEN_GROUPS token_groups, const WCHAR *group_nam } if (!sid) + { return FALSE; + } do { @@ -354,7 +388,9 @@ IsUserInGroup(PSID sid, const PTOKEN_GROUPS token_groups, const WCHAR *group_nam err = NetLocalGroupGetMembers(NULL, group_name, 0, (LPBYTE *) &members, MAX_PREFERRED_LENGTH, &nread, &nmax, &resume); if (err != NERR_Success && err != ERROR_MORE_DATA) + { break; + } /* If a match is already found, ret = TRUE, the loop is skipped */ for (DWORD i = 0; i < nread && !ret; ++i) @@ -362,13 +398,17 @@ IsUserInGroup(PSID sid, const PTOKEN_GROUPS token_groups, const WCHAR *group_nam ret = EqualSid(members[i].lgrmi0_sid, sid); } NetApiBufferFree(members); - /* MSDN says the lookup should always iterate until err != ERROR_MORE_DATA */ + /* MSDN says the lookup should always iterate until err != ERROR_MORE_DATA */ } while (err == ERROR_MORE_DATA && nloop++ < 100); if (err != NERR_Success && err != NERR_GroupNotFound) + { PrintDebug(L"NetLocalGroupGetMembers for group '%ls' failed: error = %lu", group_name, err); + } if (ret) + { PrintDebug(L"User is in group '%ls'", group_name); + } return ret; } diff --git a/access.h b/access.h index 51cb2fd..3b17f60 100644 --- a/access.h +++ b/access.h @@ -24,6 +24,6 @@ #include "options.h" -BOOL AuthorizeConfig (const connection_t *c); +BOOL AuthorizeConfig(const connection_t *c); #endif diff --git a/as.c b/as.c index 9c23648..a87595e 100644 --- a/as.c +++ b/as.c @@ -44,7 +44,8 @@ void SanitizeFilename(wchar_t *fname) { const wchar_t *reserved = L"<>:\"/\\|?*;"; /* remap these and ascii 1 to 31 */ - while (*fname) { + while (*fname) + { wchar_t c = *fname; if (c < 32 || wcschr(reserved, c)) { @@ -80,12 +81,15 @@ ExtractProfileName(const WCHAR *profile, const WCHAR *default_name, WCHAR *out_n WCHAR *ctx = NULL; pch = wcstok_s(buf, L"\r\n", &ctx); - while (pch != NULL) { - if (wcsbegins(pch, PROFILE_NAME_TOKEN)) { + while (pch != NULL) + { + if (wcsbegins(pch, PROFILE_NAME_TOKEN)) + { wcsncpy(profile_name, pch + wcslen(PROFILE_NAME_TOKEN), PROFILE_NAME_LEN - 1); profile_name[PROFILE_NAME_LEN - 1] = L'\0'; } - else if (wcsbegins(pch, FRIENDLY_NAME_TOKEN)) { + else if (wcsbegins(pch, FRIENDLY_NAME_TOKEN)) + { wcsncpy(friendly_name, pch + wcslen(FRIENDLY_NAME_TOKEN), PROFILE_NAME_LEN - 1); friendly_name[PROFILE_NAME_LEN - 1] = L'\0'; } @@ -96,11 +100,17 @@ ExtractProfileName(const WCHAR *profile, const WCHAR *default_name, WCHAR *out_n /* we use .ovpn here, but extension could be customized */ /* actual extension will be applied during import */ if (wcslen(friendly_name) > 0) + { swprintf(out_name, out_name_length, L"%ls.ovpn", friendly_name); + } else if (wcslen(profile_name) > 0) + { swprintf(out_name, out_name_length, L"%ls.ovpn", profile_name); + } else + { swprintf(out_name, out_name_length, L"%ls.ovpn", default_name); + } out_name[out_name_length - 1] = L'\0'; @@ -114,7 +124,7 @@ ShowWinInetError(HANDLE hWnd) { WCHAR err[256] = { 0 }; FormatMessageW(FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_FROM_SYSTEM, GetModuleHandleW(L"wininet.dll"), - GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err, _countof(err), NULL); + GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err, _countof(err), NULL); ShowLocalizedMsgEx(MB_OK, hWnd, _T(PACKAGE_NAME), IDS_ERR_URL_IMPORT_PROFILE, GetLastError(), err); } @@ -128,26 +138,30 @@ struct UrlComponents }; /** -* Extracts protocol, port and hostname from URL -* -* @param url URL to parse, length must be less than URL_MAX -*/ + * Extracts protocol, port and hostname from URL + * + * @param url URL to parse, length must be less than URL_MAX + */ void -ParseUrl(const WCHAR *url, struct UrlComponents* comps) +ParseUrl(const WCHAR *url, struct UrlComponents *comps) { ZeroMemory(comps, sizeof(struct UrlComponents)); comps->port = 443; comps->https = true; - if (wcsbegins(url, L"http://")) { + if (wcsbegins(url, L"http://")) + { url += 7; - } else if (wcsbegins(url, L"https://")) { - url +=8; + } + else if (wcsbegins(url, L"https://")) + { + url += 8; } WCHAR *strport = wcsstr(url, L":"); WCHAR *pathptr = wcsstr(url, L"/"); - if (strport) { + if (strport) + { wcsncpy_s(comps->host, URL_LEN, url, strport - url); comps->port = wcstol(strport + 1, NULL, 10); } @@ -175,35 +189,41 @@ ParseUrl(const WCHAR *url, struct UrlComponents* comps) * @param psize pointer to a profile size, assigned by this function */ BOOL -DownloadProfileContent(HANDLE hWnd, HINTERNET hRequest, char** pbuf, size_t* psize) +DownloadProfileContent(HANDLE hWnd, HINTERNET hRequest, char **pbuf, size_t *psize) { size_t pos = 0; size_t size = READ_CHUNK_LEN; *pbuf = calloc(1, size + 1); - char* buf = *pbuf; - if (buf == NULL) { + char *buf = *pbuf; + if (buf == NULL) + { MessageBoxW(hWnd, L"Out of memory", _T(PACKAGE_NAME), MB_OK); return FALSE; } - while (true) { + while (true) + { DWORD bytesRead = 0; - if (!InternetReadFile(hRequest, buf + pos, READ_CHUNK_LEN, &bytesRead)) { + if (!InternetReadFile(hRequest, buf + pos, READ_CHUNK_LEN, &bytesRead)) + { ShowWinInetError(hWnd); return FALSE; } buf[pos + bytesRead] = '\0'; - if (bytesRead == 0) { + if (bytesRead == 0) + { size = pos; break; } - if (pos + bytesRead >= size) { + if (pos + bytesRead >= size) + { size += READ_CHUNK_LEN; *pbuf = realloc(*pbuf, size + 1); - if (!*pbuf) { + if (!*pbuf) + { free(buf); MessageBoxW(hWnd, L"Out of memory", _T(PACKAGE_NAME), MB_OK); return FALSE; @@ -225,15 +245,17 @@ DownloadProfileContent(HANDLE hWnd, HINTERNET hRequest, char** pbuf, size_t* psi INT_PTR CALLBACK CRDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { - auth_param_t * param = NULL; + auth_param_t *param = NULL; - switch (msg) { + switch (msg) + { case WM_INITDIALOG: - param = (auth_param_t*)lParam; + param = (auth_param_t *)lParam; TRY_SETPROP(hwndDlg, cfgProp, (HANDLE)param); WCHAR *wstr = Widen(param->str); - if (!wstr) { + if (!wstr) + { EndDialog(hwndDlg, LOWORD(wParam)); break; } @@ -242,7 +264,9 @@ CRDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) /* Set password echo on if needed */ if (param->flags & FLAG_CR_ECHO) + { SendMessage(GetDlgItem(hwndDlg, ID_EDT_RESPONSE), EM_SETPASSWORDCHAR, 0, 0); + } SetForegroundWindow(hwndDlg); @@ -253,28 +277,30 @@ CRDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) break; case WM_COMMAND: - param = (auth_param_t*)GetProp(hwndDlg, cfgProp); + param = (auth_param_t *)GetProp(hwndDlg, cfgProp); - switch (LOWORD(wParam)) { - case ID_EDT_RESPONSE: - if (!(param->flags & FLAG_CR_ECHO)) - { - ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_RESPONSE), - GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); - } - if (HIWORD(wParam) == EN_UPDATE) { - /* enable OK if response is non-empty */ - BOOL enableOK = GetWindowTextLength((HWND)lParam); - EnableWindow(GetDlgItem(hwndDlg, IDOK), enableOK); - } - break; + switch (LOWORD(wParam)) + { + case ID_EDT_RESPONSE: + if (!(param->flags & FLAG_CR_ECHO)) + { + ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_RESPONSE), + GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); + } + if (HIWORD(wParam) == EN_UPDATE) + { + /* enable OK if response is non-empty */ + BOOL enableOK = GetWindowTextLength((HWND)lParam); + EnableWindow(GetDlgItem(hwndDlg, IDOK), enableOK); + } + break; case IDOK: { int len = 0; GetDlgItemTextUtf8(hwndDlg, ID_EDT_RESPONSE, ¶m->cr_response, &len); EndDialog(hwndDlg, LOWORD(wParam)); } - return TRUE; + return TRUE; case IDCANCEL: EndDialog(hwndDlg, LOWORD(wParam)); @@ -408,7 +434,7 @@ DownloadProfile(HANDLE hWnd, const struct UrlComponents *comps, const char *user HANDLE hConnect = NULL; HANDLE hRequest = NULL; BOOL result = FALSE; - char* buf = NULL; + char *buf = NULL; /* need to make copy of password to use it for dynamic response */ char password[USER_PASS_LEN] = { 0 }; @@ -421,7 +447,8 @@ DownloadProfile(HANDLE hWnd, const struct UrlComponents *comps, const char *user } hInternet = InternetOpenW(L"openvpn-gui/1.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); - if (!hInternet) { + if (!hInternet) + { ShowWinInetError(hWnd); goto done; } @@ -435,7 +462,8 @@ DownloadProfile(HANDLE hWnd, const struct UrlComponents *comps, const char *user SetCursor(LoadCursorW(0, IDC_WAIT)); hConnect = InternetConnectW(hInternet, comps->host, comps->port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); - if (!hConnect) { + if (!hConnect) + { ShowWinInetError(hWnd); goto done; } @@ -443,13 +471,15 @@ DownloadProfile(HANDLE hWnd, const struct UrlComponents *comps, const char *user DWORD req_flags = INTERNET_FLAG_RELOAD; /* load from server, do not use cached data */ req_flags |= comps->https ? INTERNET_FLAG_SECURE : 0; hRequest = HttpOpenRequestW(hConnect, NULL, comps->path, NULL, NULL, NULL, req_flags, 0); - if (!hRequest) { + if (!hRequest) + { ShowWinInetError(hWnd); goto done; } again: - if (buf) { + if (buf) + { free(buf); buf = NULL; } @@ -462,26 +492,30 @@ again: /* handle cert errors */ /* https://www.betaarchive.com/wiki/index.php/Microsoft_KB_Archive/182888 */ - if (!HttpSendRequestW(hRequest, NULL, 0, NULL, 0)) { + if (!HttpSendRequestW(hRequest, NULL, 0, NULL, 0)) + { #ifdef DEBUG DWORD err = GetLastError(); - if ((err == ERROR_INTERNET_INVALID_CA) || - (err == ERROR_INTERNET_SEC_CERT_CN_INVALID) || - (err == ERROR_INTERNET_SEC_CERT_DATE_INVALID) || - (err == ERROR_INTERNET_SEC_CERT_REV_FAILED)) { + if ((err == ERROR_INTERNET_INVALID_CA) + || (err == ERROR_INTERNET_SEC_CERT_CN_INVALID) + || (err == ERROR_INTERNET_SEC_CERT_DATE_INVALID) + || (err == ERROR_INTERNET_SEC_CERT_REV_FAILED)) + { /* ask user what to do and modify options if needed */ DWORD dlg_result = InternetErrorDlg(hWnd, hRequest, - err, - FLAGS_ERROR_UI_FILTER_FOR_ERRORS | - FLAGS_ERROR_UI_FLAGS_GENERATE_DATA | - FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS, - NULL); + err, + FLAGS_ERROR_UI_FILTER_FOR_ERRORS + |FLAGS_ERROR_UI_FLAGS_GENERATE_DATA + |FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS, + NULL); - if (dlg_result == ERROR_SUCCESS) { + if (dlg_result == ERROR_SUCCESS) + { /* for unknown reasons InternetErrorDlg() doesn't change options for ERROR_INTERNET_SEC_CERT_REV_FAILED, * despite user is willing to continue, so we have to do it manually */ - if (err == ERROR_INTERNET_SEC_CERT_REV_FAILED) { + if (err == ERROR_INTERNET_SEC_CERT_REV_FAILED) + { DWORD flags; DWORD len = sizeof(flags); InternetQueryOptionW(hRequest, INTERNET_OPTION_SECURITY_FLAGS, (LPVOID)&flags, &len); @@ -495,9 +529,11 @@ again: goto again; } else + { goto done; + } } -#endif +#endif /* ifdef DEBUG */ ShowWinInetError(hWnd); goto done; } @@ -510,36 +546,49 @@ again: size_t size = 0; /* download profile content */ - if ((status_code == 200) || (status_code == 401)) { + if ((status_code == 200) || (status_code == 401)) + { if (!DownloadProfileContent(hWnd, hRequest, &buf, &size)) + { goto done; + } - char* msg_begin = strstr(buf, "CRV1:"); - char* msg_end = strstr(buf, ""); - if ((status_code == 401) && msg_begin && msg_end) { + char *msg_begin = strstr(buf, "CRV1:"); + char *msg_end = strstr(buf, ""); + if ((status_code == 401) && msg_begin && msg_end) + { *msg_end = '\0'; - auth_param_t* param = (auth_param_t*)calloc(1, sizeof(auth_param_t)); + auth_param_t *param = (auth_param_t *)calloc(1, sizeof(auth_param_t)); if (!param) + { goto done; + } - if (parse_dynamic_cr(msg_begin + 14, param)) { + if (parse_dynamic_cr(msg_begin + 14, param)) + { /* prompt user for dynamic challenge */ INT_PTR res = LocalizedDialogBoxParam(ID_DLG_CHALLENGE_RESPONSE, CRDialogFunc, (LPARAM)param); if (res == IDOK) + { _snprintf_0(password, "CRV1::%s::%s", param->id, param->cr_response); + } free_auth_param(param); if (res == IDOK) + { goto again; + } } - else { + else + { free_auth_param(param); } } } - if (status_code != 200) { + if (status_code != 200) + { ShowLocalizedMsgEx(MB_OK, hWnd, _T(PACKAGE_NAME), IDS_ERR_URL_IMPORT_PROFILE, status_code, L"HTTP error"); goto done; } @@ -563,8 +612,9 @@ again: if (strlen(comps->content_type) == 0 /* AS profile */ || !ExtractFilenameFromHeader(hRequest, name, MAX_PATH)) { - WCHAR* wbuf = Widen(buf); - if (!wbuf) { + WCHAR *wbuf = Widen(buf); + if (!wbuf) + { MessageBoxW(hWnd, L"Failed to convert profile content to wchar", _T(PACKAGE_NAME), MB_OK); goto done; } @@ -574,14 +624,16 @@ again: /* save profile content into tmp file */ DWORD res = GetTempPathW((DWORD)out_path_size, out_path); - if (res == 0 || res > out_path_size) { + if (res == 0 || res > out_path_size) + { MessageBoxW(hWnd, L"Failed to get TMP path", _T(PACKAGE_NAME), MB_OK); goto done; } swprintf(out_path, out_path_size, L"%ls%ls", out_path, name); out_path[out_path_size - 1] = '\0'; - FILE* f = _wfopen(out_path, L"w"); - if (f == NULL) { + FILE *f = _wfopen(out_path, L"w"); + if (f == NULL) + { MessageBoxW(hWnd, L"Unable to save downloaded profile", _T(PACKAGE_NAME), MB_OK); goto done; } @@ -592,26 +644,34 @@ again: done: if (buf) + { free(buf); + } /* wipe the password */ SecureZeroMemory(password, sizeof(password)); if (hRequest) + { InternetCloseHandle(hRequest); + } if (hConnect) + { InternetCloseHandle(hConnect); + } if (hInternet) + { InternetCloseHandle(hInternet); + } return result; } typedef enum { - server_as = 1, - server_generic = 2 + server_as = 1, + server_generic = 2 } server_type_t; INT_PTR CALLBACK @@ -623,116 +683,123 @@ ImportProfileFromURLDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lPa switch (msg) { - case WM_INITDIALOG: - type = (server_type_t) lParam; - TRY_SETPROP(hwndDlg, cfgProp, (HANDLE)lParam); - SetStatusWinIcon(hwndDlg, ID_ICO_APP); + case WM_INITDIALOG: + type = (server_type_t) lParam; + TRY_SETPROP(hwndDlg, cfgProp, (HANDLE)lParam); + SetStatusWinIcon(hwndDlg, ID_ICO_APP); - if (type == server_generic) - { - /* Change window title and hide autologin checkbox */ - SetWindowTextW(hwndDlg, LoadLocalizedString(IDS_MENU_IMPORT_URL)); - ShowWindow(GetDlgItem(hwndDlg, ID_CHK_AUTOLOGIN), SW_HIDE); - } - /* disable OK button until required data is filled in */ - EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE); - ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS), - GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), 0); - break; - - case WM_COMMAND: - type = (server_type_t) GetProp(hwndDlg, cfgProp); - switch (LOWORD(wParam)) - { - case ID_EDT_AUTH_PASS: - ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS), - GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); - /* fall through */ - case ID_EDT_AUTH_USER: - case ID_EDT_URL: - if (HIWORD(wParam) == EN_UPDATE) { - /* enable OK button only if url and username are filled */ - BOOL enableOK = GetWindowTextLengthW(GetDlgItem(hwndDlg, ID_EDT_URL)) - && GetWindowTextLengthW(GetDlgItem(hwndDlg, ID_EDT_AUTH_USER)); - EnableWindow(GetDlgItem(hwndDlg, IDOK), enableOK); + if (type == server_generic) + { + /* Change window title and hide autologin checkbox */ + SetWindowTextW(hwndDlg, LoadLocalizedString(IDS_MENU_IMPORT_URL)); + ShowWindow(GetDlgItem(hwndDlg, ID_CHK_AUTOLOGIN), SW_HIDE); } + /* disable OK button until required data is filled in */ + EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE); + ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS), + GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), 0); break; - case IDOK: - - GetDlgItemTextW(hwndDlg, ID_EDT_URL, url, _countof(url)); - - int username_len = 0; - char *username = NULL; - GetDlgItemTextUtf8(hwndDlg, ID_EDT_AUTH_USER, &username, &username_len); - - int password_len = 0; - char *password = NULL; - GetDlgItemTextUtf8(hwndDlg, ID_EDT_AUTH_PASS, &password, &password_len); - - WCHAR path[MAX_PATH + 1] = { 0 }; - struct UrlComponents comps = {0}; - if (type == server_as) + case WM_COMMAND: + type = (server_type_t) GetProp(hwndDlg, cfgProp); + switch (LOWORD(wParam)) { + case ID_EDT_AUTH_PASS: + ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS), + GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); - autologin = IsDlgButtonChecked(hwndDlg, ID_CHK_AUTOLOGIN) == BST_CHECKED; - GetASUrl(url, autologin, &comps); - } - else - { - ParseUrl(url, &comps); - strncpy_s(comps.content_type, _countof(comps.content_type), - "application/x-openvpn-profile", _TRUNCATE); - } - BOOL downloaded = DownloadProfile(hwndDlg, &comps, username, password, path, _countof(path)); + /* fall through */ + case ID_EDT_AUTH_USER: + case ID_EDT_URL: + if (HIWORD(wParam) == EN_UPDATE) + { + /* enable OK button only if url and username are filled */ + BOOL enableOK = GetWindowTextLengthW(GetDlgItem(hwndDlg, ID_EDT_URL)) + && GetWindowTextLengthW(GetDlgItem(hwndDlg, ID_EDT_AUTH_USER)); + EnableWindow(GetDlgItem(hwndDlg, IDOK), enableOK); + } + break; + + case IDOK: + + GetDlgItemTextW(hwndDlg, ID_EDT_URL, url, _countof(url)); + + int username_len = 0; + char *username = NULL; + GetDlgItemTextUtf8(hwndDlg, ID_EDT_AUTH_USER, &username, &username_len); + + int password_len = 0; + char *password = NULL; + GetDlgItemTextUtf8(hwndDlg, ID_EDT_AUTH_PASS, &password, &password_len); + + WCHAR path[MAX_PATH + 1] = { 0 }; + struct UrlComponents comps = {0}; + if (type == server_as) + { + + autologin = IsDlgButtonChecked(hwndDlg, ID_CHK_AUTOLOGIN) == BST_CHECKED; + GetASUrl(url, autologin, &comps); + } + else + { + ParseUrl(url, &comps); + strncpy_s(comps.content_type, _countof(comps.content_type), + "application/x-openvpn-profile", _TRUNCATE); + } + BOOL downloaded = DownloadProfile(hwndDlg, &comps, username, password, path, _countof(path)); + + if (username_len > 0) + { + free(username); + } + + if (password_len > 0) + { + SecureZeroMemory(password, strlen(password)); + free(password); + } + + if (downloaded) + { + EndDialog(hwndDlg, LOWORD(wParam)); + + ImportConfigFile(path, false); /* do not prompt user */ + _wunlink(path); + } + return TRUE; - if (username_len > 0) - free(username); + case IDCANCEL: + EndDialog(hwndDlg, LOWORD(wParam)); + return TRUE; - if (password_len > 0) - { - SecureZeroMemory(password, strlen(password)); - free(password); + case ID_PASSWORD_REVEAL: /* password reveal symbol clicked */ + ChangePasswordVisibility(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS), + GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); + return TRUE; } + break; - if (downloaded) { - EndDialog(hwndDlg, LOWORD(wParam)); - - ImportConfigFile(path, false); /* do not prompt user */ - _wunlink(path); - } - return TRUE; - case IDCANCEL: + case WM_CLOSE: EndDialog(hwndDlg, LOWORD(wParam)); return TRUE; - case ID_PASSWORD_REVEAL: /* password reveal symbol clicked */ - ChangePasswordVisibility(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS), - GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); - return TRUE; - } - break; - - - case WM_CLOSE: - EndDialog(hwndDlg, LOWORD(wParam)); - return TRUE; - - case WM_NCDESTROY: - RemoveProp(hwndDlg, cfgProp); - break; + case WM_NCDESTROY: + RemoveProp(hwndDlg, cfgProp); + break; } return FALSE; } -void ImportConfigFromAS() +void +ImportConfigFromAS() { LocalizedDialogBoxParam(ID_DLG_URL_PROFILE_IMPORT, ImportProfileFromURLDialogFunc, (LPARAM) server_as); } -void ImportConfigFromURL() +void +ImportConfigFromURL() { LocalizedDialogBoxParam(ID_DLG_URL_PROFILE_IMPORT, ImportProfileFromURLDialogFunc, (LPARAM) server_generic); } diff --git a/as.h b/as.h index d404e47..d8189a7 100644 --- a/as.h +++ b/as.h @@ -20,4 +20,5 @@ */ void ImportConfigFromAS(); + void ImportConfigFromURL(); diff --git a/chartable.h b/chartable.h index f61622d..9b780c2 100644 --- a/chartable.h +++ b/chartable.h @@ -20,261 +20,260 @@ */ WCHAR unicode_to_ascii[256] = { -0x0000, -0x0001, -0x0002, -0x0003, -0x0004, -0x0005, -0x0006, -0x0007, -0x0008, -0x0009, -0x000a, -0x000b, -0x000c, -0x000d, -0x000e, -0x000f, -0x0010, -0x0011, -0x0012, -0x0013, -0x0014, -0x0015, -0x0016, -0x0017, -0x0018, -0x0019, -0x001a, -0x001b, -0x001c, -0x001d, -0x001e, -0x001f, -0x0020, -0x0021, -0x0022, -0x0023, -0x0024, -0x0025, -0x0026, -0x0027, -0x0028, -0x0029, -0x002a, -0x002b, -0x002c, -0x002d, -0x002e, -0x002f, -0x0030, -0x0031, -0x0032, -0x0033, -0x0034, -0x0035, -0x0036, -0x0037, -0x0038, -0x0039, -0x003a, -0x003b, -0x003c, -0x003d, -0x003e, -0x003f, -0x0040, -0x0041, -0x0042, -0x0043, -0x0044, -0x0045, -0x0046, -0x0047, -0x0048, -0x0049, -0x004a, -0x004b, -0x004c, -0x004d, -0x004e, -0x004f, -0x0050, -0x0051, -0x0052, -0x0053, -0x0054, -0x0055, -0x0056, -0x0057, -0x0058, -0x0059, -0x005a, -0x005b, -0x005c, -0x005d, -0x005e, -0x005f, -0x0060, -0x0061, -0x0062, -0x0063, -0x0064, -0x0065, -0x0066, -0x0067, -0x0068, -0x0069, -0x006a, -0x006b, -0x006c, -0x006d, -0x006e, -0x006f, -0x0070, -0x0071, -0x0072, -0x0073, -0x0074, -0x0075, -0x0076, -0x0077, -0x0078, -0x0079, -0x007a, -0x007b, -0x007c, -0x007d, -0x007e, -0x007f, -0x00c7, -0x00fc, -0x00e9, -0x00e2, -0x00e4, -0x00e0, -0x00e5, -0x00e7, -0x00ea, -0x00eb, -0x00e8, -0x00ef, -0x00ee, -0x00ec, -0x00c4, -0x00c5, -0x00c9, -0x00e6, -0x00c6, -0x00f4, -0x00f6, -0x00f2, -0x00fb, -0x00f9, -0x00ff, -0x00d6, -0x00dc, -0x00f8, -0x00a3, -0x00d8, -0x00d7, -0x0192, -0x00e1, -0x00ed, -0x00f3, -0x00fa, -0x00f1, -0x00d1, -0x00aa, -0x00ba, -0x00bf, -0x00ae, -0x00ac, -0x00bd, -0x00bc, -0x00a1, -0x00ab, -0x00bb, -0x2591, -0x2592, -0x2593, -0x2502, -0x2524, -0x00c1, -0x00c2, -0x00c0, -0x00a9, -0x2563, -0x2551, -0x2557, -0x255d, -0x00a2, -0x00a5, -0x2510, -0x2514, -0x2534, -0x252c, -0x251c, -0x2500, -0x253c, -0x00e3, -0x00c3, -0x255a, -0x2554, -0x2569, -0x2566, -0x2560, -0x2550, -0x256c, -0x00a4, -0x00f0, -0x00d0, -0x00ca, -0x00cb, -0x00c8, -0x0131, -0x00cd, -0x00ce, -0x00cf, -0x2518, -0x250c, -0x2588, -0x2584, -0x00a6, -0x00cc, -0x2580, -0x00d3, -0x00df, -0x00d4, -0x00d2, -0x00f5, -0x00d5, -0x00b5, -0x00fe, -0x00de, -0x00da, -0x00db, -0x00d9, -0x00fd, -0x00dd, -0x00af, -0x00b4, -0x00ad, -0x00b1, -0x2017, -0x00be, -0x00b6, -0x00a7, -0x00f7, -0x00b8, -0x00b0, -0x00a8, -0x00b7, -0x00b9, -0x00b3, -0x00b2, -0x25a0, -0x00a0 + 0x0000, + 0x0001, + 0x0002, + 0x0003, + 0x0004, + 0x0005, + 0x0006, + 0x0007, + 0x0008, + 0x0009, + 0x000a, + 0x000b, + 0x000c, + 0x000d, + 0x000e, + 0x000f, + 0x0010, + 0x0011, + 0x0012, + 0x0013, + 0x0014, + 0x0015, + 0x0016, + 0x0017, + 0x0018, + 0x0019, + 0x001a, + 0x001b, + 0x001c, + 0x001d, + 0x001e, + 0x001f, + 0x0020, + 0x0021, + 0x0022, + 0x0023, + 0x0024, + 0x0025, + 0x0026, + 0x0027, + 0x0028, + 0x0029, + 0x002a, + 0x002b, + 0x002c, + 0x002d, + 0x002e, + 0x002f, + 0x0030, + 0x0031, + 0x0032, + 0x0033, + 0x0034, + 0x0035, + 0x0036, + 0x0037, + 0x0038, + 0x0039, + 0x003a, + 0x003b, + 0x003c, + 0x003d, + 0x003e, + 0x003f, + 0x0040, + 0x0041, + 0x0042, + 0x0043, + 0x0044, + 0x0045, + 0x0046, + 0x0047, + 0x0048, + 0x0049, + 0x004a, + 0x004b, + 0x004c, + 0x004d, + 0x004e, + 0x004f, + 0x0050, + 0x0051, + 0x0052, + 0x0053, + 0x0054, + 0x0055, + 0x0056, + 0x0057, + 0x0058, + 0x0059, + 0x005a, + 0x005b, + 0x005c, + 0x005d, + 0x005e, + 0x005f, + 0x0060, + 0x0061, + 0x0062, + 0x0063, + 0x0064, + 0x0065, + 0x0066, + 0x0067, + 0x0068, + 0x0069, + 0x006a, + 0x006b, + 0x006c, + 0x006d, + 0x006e, + 0x006f, + 0x0070, + 0x0071, + 0x0072, + 0x0073, + 0x0074, + 0x0075, + 0x0076, + 0x0077, + 0x0078, + 0x0079, + 0x007a, + 0x007b, + 0x007c, + 0x007d, + 0x007e, + 0x007f, + 0x00c7, + 0x00fc, + 0x00e9, + 0x00e2, + 0x00e4, + 0x00e0, + 0x00e5, + 0x00e7, + 0x00ea, + 0x00eb, + 0x00e8, + 0x00ef, + 0x00ee, + 0x00ec, + 0x00c4, + 0x00c5, + 0x00c9, + 0x00e6, + 0x00c6, + 0x00f4, + 0x00f6, + 0x00f2, + 0x00fb, + 0x00f9, + 0x00ff, + 0x00d6, + 0x00dc, + 0x00f8, + 0x00a3, + 0x00d8, + 0x00d7, + 0x0192, + 0x00e1, + 0x00ed, + 0x00f3, + 0x00fa, + 0x00f1, + 0x00d1, + 0x00aa, + 0x00ba, + 0x00bf, + 0x00ae, + 0x00ac, + 0x00bd, + 0x00bc, + 0x00a1, + 0x00ab, + 0x00bb, + 0x2591, + 0x2592, + 0x2593, + 0x2502, + 0x2524, + 0x00c1, + 0x00c2, + 0x00c0, + 0x00a9, + 0x2563, + 0x2551, + 0x2557, + 0x255d, + 0x00a2, + 0x00a5, + 0x2510, + 0x2514, + 0x2534, + 0x252c, + 0x251c, + 0x2500, + 0x253c, + 0x00e3, + 0x00c3, + 0x255a, + 0x2554, + 0x2569, + 0x2566, + 0x2560, + 0x2550, + 0x256c, + 0x00a4, + 0x00f0, + 0x00d0, + 0x00ca, + 0x00cb, + 0x00c8, + 0x0131, + 0x00cd, + 0x00ce, + 0x00cf, + 0x2518, + 0x250c, + 0x2588, + 0x2584, + 0x00a6, + 0x00cc, + 0x2580, + 0x00d3, + 0x00df, + 0x00d4, + 0x00d2, + 0x00f5, + 0x00d5, + 0x00b5, + 0x00fe, + 0x00de, + 0x00da, + 0x00db, + 0x00d9, + 0x00fd, + 0x00dd, + 0x00af, + 0x00b4, + 0x00ad, + 0x00b1, + 0x2017, + 0x00be, + 0x00b6, + 0x00a7, + 0x00f7, + 0x00b8, + 0x00b0, + 0x00a8, + 0x00b7, + 0x00b9, + 0x00b3, + 0x00b2, + 0x25a0, + 0x00a0 }; - diff --git a/config-msvc.h.in b/config-msvc.h.in index b7d0bd5..7955bec 100644 --- a/config-msvc.h.in +++ b/config-msvc.h.in @@ -22,7 +22,7 @@ #define PACKAGE_VERSION "11" /* Version in windows resource format */ -#define PACKAGE_VERSION_RESOURCE @GUI_VERSION_MAJOR@,@GUI_VERSION_MINOR@,0,0 +#define PACKAGE_VERSION_RESOURCE @GUI_VERSION_MAJOR@, @GUI_VERSION_MINOR@, 0, 0 /* Version as a string */ #define PACKAGE_VERSION_RESOURCE_STR "@GUI_VERSION_MAJOR@.@GUI_VERSION_MINOR@.0.0" diff --git a/config_parser.c b/config_parser.c index 377dbf9..9b854f0 100644 --- a/config_parser.c +++ b/config_parser.c @@ -43,7 +43,7 @@ is_comment(wchar_t *s) } static int -copy_token(wchar_t **dest, wchar_t **src, wchar_t* delim) +copy_token(wchar_t **dest, wchar_t **src, wchar_t *delim) { wchar_t *p = *src; wchar_t *s = *dest; @@ -61,7 +61,9 @@ copy_token(wchar_t **dest, wchar_t **src, wchar_t* delim) return -1; /* parse error -- illegal backslash in input */ } else + { *s = *p; + } } /* at this point p is one of the delimiters or null */ *s = L'\0'; @@ -79,9 +81,12 @@ tokenize(config_entry_t *ce) unsigned int i = 0; int status = 0; - for ( ; *p != L'\0'; p++, s++) + for ( ; *p != L'\0'; p++, s++) { - if (*p == L' ' || *p == L'\t') continue; + if (*p == L' ' || *p == L'\t') + { + continue; + } if (_countof(ce->tokens) <= i) { @@ -89,7 +94,7 @@ tokenize(config_entry_t *ce) } ce->tokens[i++] = s; - if (*p == L'\'' ) + if (*p == L'\'') { int len = wcscspn(++p, L"\'"); wcsncpy(s, p, len); @@ -119,7 +124,10 @@ tokenize(config_entry_t *ce) return status; } - if (*p == L'\0') break; + if (*p == L'\0') + { + break; + } } ce->ntokens = i; return 0; @@ -145,8 +153,8 @@ config_readline(FILE *fd, int first) config_entry_t *ce = calloc(sizeof(*ce), 1); if (!ce) { - MsgToEventLog(EVENTLOG_ERROR_TYPE, L"Out of memory in config_readline"); - return NULL; + MsgToEventLog(EVENTLOG_ERROR_TYPE, L"Out of memory in config_readline"); + return NULL; } mbstowcs(ce->line, &tmp[offset], _countof(ce->line)-1); diff --git a/config_parser.h b/config_parser.h index acffa9b..c369fe9 100644 --- a/config_parser.h +++ b/config_parser.h @@ -52,4 +52,4 @@ config_entry_t *config_parse(wchar_t *fname); */ void config_list_free(config_entry_t *head); -#endif +#endif /* ifndef CONFIG_PARSER_H */ diff --git a/echo.c b/echo.c index 88e042a..a51ac18 100644 --- a/echo.c +++ b/echo.c @@ -80,9 +80,11 @@ echo_msg_add_fp(struct echo_msg *msg, time_t timestamp) msg->fp.timestamp = timestamp; if (md_init(&ctx, CALG_SHA1) != 0) + { return; - md_update(&ctx, (BYTE*) msg->text, msg->txtlen*sizeof(msg->text[0])); - md_update(&ctx, (BYTE*) msg->title, wcslen(msg->title)*sizeof(msg->title[0])); + } + md_update(&ctx, (BYTE *) msg->text, msg->txtlen*sizeof(msg->text[0])); + md_update(&ctx, (BYTE *) msg->title, wcslen(msg->title)*sizeof(msg->title[0])); md_final(&ctx, msg->fp.digest); return; } @@ -91,15 +93,18 @@ echo_msg_add_fp(struct echo_msg *msg, time_t timestamp) static struct echo_msg_history * echo_msg_recall(const BYTE *digest, struct echo_msg_history *hist) { - for( ; hist; hist = hist->next) + for (; hist; hist = hist->next) { - if (memcmp(hist->fp.digest, digest, HASHLEN) == 0) break; + if (memcmp(hist->fp.digest, digest, HASHLEN) == 0) + { + break; + } } return hist; } /* Add an item to message history and return the head of the list */ -static struct echo_msg_history* +static struct echo_msg_history * echo_msg_history_add(struct echo_msg_history *head, const struct echo_msg_fp *fp) { struct echo_msg_history *hist = malloc(sizeof(struct echo_msg_history)); @@ -137,10 +142,15 @@ echo_msg_persist(connection_t *c) for (hist = c->echo_msg.history; hist; hist = hist->next) { len++; - if (len > 99) break; /* max 100 history items persisted */ + if (len > 99) + { + break; /* max 100 history items persisted */ + } } if (len == 0) + { return; + } size_t size = len*sizeof(struct echo_msg_fp); struct echo_msg_fp *data = malloc(size); @@ -156,7 +166,9 @@ echo_msg_persist(connection_t *c) data[i++] = hist->fp; } if (!SetConfigRegistryValueBinary(c->config_name, L"echo_msg_history", (BYTE *) data, size)) + { WriteStatusLog(c, L"GUI> ", L"Failed to persist echo msg history: error writing to registry", false); + } free(data); return; @@ -171,7 +183,9 @@ echo_msg_load(connection_t *c) size_t size = GetConfigRegistryValue(c->config_name, L"echo_msg_history", NULL, 0); if (size == 0) + { return; /* no history in registry */ + } else if (size%item_len != 0) { WriteStatusLog(c, L"GUI> ", L"echo msg history in registry has invalid size", false); @@ -179,11 +193,13 @@ echo_msg_load(connection_t *c) } data = malloc(size); - if (!data || !GetConfigRegistryValue(c->config_name, L"echo_msg_history", (BYTE*) data, size)) + if (!data || !GetConfigRegistryValue(c->config_name, L"echo_msg_history", (BYTE *) data, size)) + { goto out; + } size_t len = size/item_len; - for(size_t i = 0; i < len; i++) + for (size_t i = 0; i < len; i++) { c->echo_msg.history = echo_msg_history_add(c->echo_msg.history, &data[i]); } @@ -255,7 +271,7 @@ echo_msg_display(connection_t *c, time_t timestamp, const char *title, int type) } echo_msg_add_fp(&c->echo_msg, timestamp); /* add fingerprint: digest+timestamp */ - /* Check whether the message is muted */ + /* Check whether the message is muted */ if (c->flags & FLAG_DISABLE_ECHO_MSG || echo_msg_repeated(&c->echo_msg)) { return; @@ -356,7 +372,9 @@ static wchar_t * get_text_in_range(HWND h, CHARRANGE chrg) { if (chrg.cpMax <= chrg.cpMin) - return NULL; + { + return NULL; + } size_t len = chrg.cpMax - chrg.cpMin; wchar_t *txt = malloc((len + 1)*sizeof(wchar_t)); @@ -365,9 +383,13 @@ get_text_in_range(HWND h, CHARRANGE chrg) { TEXTRANGEW txtrg = {chrg, txt}; if (SendMessage(h, EM_GETTEXTRANGE, 0, (LPARAM)&txtrg) <= 0) + { txt[0] = '\0'; + } else + { txt[len] = '\0'; /* safety */ + } } return txt; } @@ -392,7 +414,9 @@ OnEnLinkNotify(HWND UNUSED hwnd, ENLINK *el) /* get the link text */ wchar_t *url = get_text_in_range(el->nmhdr.hwndFrom, el->chrg); if (url) + { open_url(url); + } free(url); return 1; } @@ -431,7 +455,7 @@ AddMessageBoxText(HWND hwnd, const wchar_t *text, const wchar_t *title, const wc cfm.dwEffects |= CFE_ITALIC; SendMessage(hmsg, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cfm); - /* Align to right */ + /* Align to right */ pf.wAlignment = align[1]; SendMessage(hmsg, EM_SETPARAFORMAT, 0, (LPARAM) &pf); SendMessage(hmsg, EM_REPLACESEL, FALSE, (LPARAM) from); @@ -500,69 +524,70 @@ MessageDialogFunc(HWND hwnd, UINT msg, UNUSED WPARAM wParam, LPARAM lParam) switch (msg) { - case WM_INITDIALOG: - hIcon = LoadLocalizedIcon(ID_ICO_APP); - if (hIcon) { - SendMessage(hwnd, WM_SETICON, (WPARAM) (ICON_SMALL), (LPARAM) (hIcon)); - SendMessage(hwnd, WM_SETICON, (WPARAM) (ICON_BIG), (LPARAM) (hIcon)); - } - hmsg = GetDlgItem(hwnd, ID_TXT_MESSAGE); - SetWindowText(hwnd, L"OpenVPN Messages"); - SendMessage(hmsg, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, - MAKELPARAM(side_margin, side_margin)); - if (LangFlowDirection() == 1) - { - LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); - SetWindowLong(hwnd, GWL_EXSTYLE, exstyle | WS_EX_RTLREADING | WS_EX_LAYOUTRTL); - exstyle = GetWindowLong(hmsg, GWL_EXSTYLE); - SetWindowLong(hmsg, GWL_EXSTYLE, exstyle | WS_EX_LEFTSCROLLBAR); - } - - enable_url_detection(hmsg); - - /* Position the window close to top right corner of the screen */ - RECT rc; - GetWindowRect(hwnd, &rc); - OffsetRect(&rc, -rc.left, -rc.top); - int ox = GetSystemMetrics(SM_CXSCREEN); /* screen size along x */ - ox -= rc.right + DPI_SCALE(rand()%50 + 25); - int oy = DPI_SCALE(rand()%50 + 25); - SetWindowPos(hwnd, HWND_TOP, ox > 0 ? ox:0, oy, 0, 0, SWP_NOSIZE); - - return TRUE; - - case WM_SIZE: - hmsg = GetDlgItem(hwnd, ID_TXT_MESSAGE); - /* leave some space as top margin */ - SetWindowPos(hmsg, NULL, 0, top_margin, LOWORD(lParam), HIWORD(lParam)-top_margin, 0); - InvalidateRect(hwnd, NULL, TRUE); - break; - - /* set the whole client area background to white */ - case WM_CTLCOLORDLG: - case WM_CTLCOLORSTATIC: - return (INT_PTR) GetStockObject(WHITE_BRUSH); - break; - - case WM_COMMAND: - if (LOWORD(wParam) == ID_TXT_MESSAGE) - { - /* The caret is distracting in a readonly msg box: hide it when we get focus */ - if (HIWORD(wParam) == EN_SETFOCUS) + case WM_INITDIALOG: + hIcon = LoadLocalizedIcon(ID_ICO_APP); + if (hIcon) { - HideCaret((HWND)lParam); + SendMessage(hwnd, WM_SETICON, (WPARAM) (ICON_SMALL), (LPARAM) (hIcon)); + SendMessage(hwnd, WM_SETICON, (WPARAM) (ICON_BIG), (LPARAM) (hIcon)); } - else if (HIWORD(wParam) == EN_KILLFOCUS) + hmsg = GetDlgItem(hwnd, ID_TXT_MESSAGE); + SetWindowText(hwnd, L"OpenVPN Messages"); + SendMessage(hmsg, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, + MAKELPARAM(side_margin, side_margin)); + if (LangFlowDirection() == 1) { - ShowCaret((HWND)lParam); + LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); + SetWindowLong(hwnd, GWL_EXSTYLE, exstyle | WS_EX_RTLREADING | WS_EX_LAYOUTRTL); + exstyle = GetWindowLong(hmsg, GWL_EXSTYLE); + SetWindowLong(hmsg, GWL_EXSTYLE, exstyle | WS_EX_LEFTSCROLLBAR); } - } - break; - /* Must be sent with lParam = connection pointer - * Adds the current echo message and shows the window. - */ - case WM_OVPN_ECHOMSG: + enable_url_detection(hmsg); + + /* Position the window close to top right corner of the screen */ + RECT rc; + GetWindowRect(hwnd, &rc); + OffsetRect(&rc, -rc.left, -rc.top); + int ox = GetSystemMetrics(SM_CXSCREEN); /* screen size along x */ + ox -= rc.right + DPI_SCALE(rand()%50 + 25); + int oy = DPI_SCALE(rand()%50 + 25); + SetWindowPos(hwnd, HWND_TOP, ox > 0 ? ox : 0, oy, 0, 0, SWP_NOSIZE); + + return TRUE; + + case WM_SIZE: + hmsg = GetDlgItem(hwnd, ID_TXT_MESSAGE); + /* leave some space as top margin */ + SetWindowPos(hmsg, NULL, 0, top_margin, LOWORD(lParam), HIWORD(lParam)-top_margin, 0); + InvalidateRect(hwnd, NULL, TRUE); + break; + + /* set the whole client area background to white */ + case WM_CTLCOLORDLG: + case WM_CTLCOLORSTATIC: + return (INT_PTR) GetStockObject(WHITE_BRUSH); + break; + + case WM_COMMAND: + if (LOWORD(wParam) == ID_TXT_MESSAGE) + { + /* The caret is distracting in a readonly msg box: hide it when we get focus */ + if (HIWORD(wParam) == EN_SETFOCUS) + { + HideCaret((HWND)lParam); + } + else if (HIWORD(wParam) == EN_KILLFOCUS) + { + ShowCaret((HWND)lParam); + } + } + break; + + /* Must be sent with lParam = connection pointer + * Adds the current echo message and shows the window. + */ + case WM_OVPN_ECHOMSG: { connection_t *c = (connection_t *) lParam; wchar_t from[256]; @@ -570,7 +595,9 @@ MessageDialogFunc(HWND hwnd, UINT msg, UNUSED WPARAM wParam, LPARAM lParam) /* strip \n added by _wctime */ if (wcslen(from) > 0) + { from[wcslen(from)-1] = L'\0'; + } AddMessageBoxText(hwnd, c->echo_msg.text, c->echo_msg.title, from); SetForegroundWindow(hwnd); @@ -578,16 +605,18 @@ MessageDialogFunc(HWND hwnd, UINT msg, UNUSED WPARAM wParam, LPARAM lParam) } break; - case WM_NOTIFY: - nmh = (NMHDR*) lParam; - /* We handle only EN_LINK messages */ - if (nmh->idFrom == ID_TXT_MESSAGE && nmh->code == EN_LINK) - return OnEnLinkNotify(hwnd, (ENLINK*)lParam); - break; + case WM_NOTIFY: + nmh = (NMHDR *) lParam; + /* We handle only EN_LINK messages */ + if (nmh->idFrom == ID_TXT_MESSAGE && nmh->code == EN_LINK) + { + return OnEnLinkNotify(hwnd, (ENLINK *)lParam); + } + break; - case WM_CLOSE: - ShowWindow(hwnd, SW_HIDE); - return TRUE; + case WM_CLOSE: + ShowWindow(hwnd, SW_HIDE); + return TRUE; } return 0; diff --git a/echo.h b/echo.h index 5ade93d..bb443a1 100644 --- a/echo.h +++ b/echo.h @@ -54,4 +54,4 @@ void echo_msg_clear(connection_t *c, BOOL clear_history); /* Load echo msg history from the registry */ void echo_msg_load(connection_t *c); -#endif +#endif /* ifndef ECHO_H */ diff --git a/env_set.c b/env_set.c index f551075..ba2f769 100644 --- a/env_set.c +++ b/env_set.c @@ -94,7 +94,10 @@ env_item_del(struct env_item *head, const wchar_t *name) { struct env_item *item, *prev = NULL; - if (!name) return head; + if (!name) + { + return head; + } for (item = head; item; item = item->next) { @@ -102,9 +105,13 @@ env_item_del(struct env_item *head, const wchar_t *name) { /* matching item found */ if (prev) + { prev->next = item->next; + } else /* head is going to be deleted */ + { head = item->next; + } env_item_free(item); break; } @@ -132,7 +139,7 @@ env_item_insert(struct env_item *head, struct env_item *item) cmp = env_name_compare(item->nameval, tmp->nameval); if (cmp <= 0) /* found the position to add */ { - break; + break; } prev = tmp; continue; @@ -148,9 +155,13 @@ env_item_insert(struct env_item *head, struct env_item *item) } if (prev) + { prev->next = item; + } else + { head = item; + } return head; } @@ -194,13 +205,15 @@ env_item_new_utf8(const char *nameval) /* Insert an env item to the set given nameval: name=val. * Returns new head of the list. */ -static struct env_item* +static struct env_item * env_item_insert_utf8(struct env_item *head, const char *nameval) { struct env_item *item = env_item_new_utf8(nameval); if (!item) + { return head; + } return env_item_insert(head, item); } @@ -247,11 +260,10 @@ merge_env_block(const struct env_item *es) for (pe = e; *pe; pe += wcslen(pe)+1) { - ; } len = (pe + 1 - e); /* including the extra '\0' at the end */ - for(item = es; item; item = item->next) + for (item = es; item; item = item->next) { len += wcslen(item->nameval) + 1; } @@ -291,7 +303,9 @@ merge_env_block(const struct env_item *es) { pe += len; if (*pe) /* update len */ + { len = wcslen(pe) + 1; + } } } /* Add any remaining entries -- either item or *pe is NULL at this point. @@ -326,7 +340,9 @@ process_setenv(connection_t *c, UNUSED time_t timestamp, const char *msg) char *nameval; if (!strbegins(msg, "setenv ")) + { return; + } msg += strlen("setenv "); /* character following "setenv" */ msg += strspn(msg, " \t"); /* skip leading space */ diff --git a/env_set.h b/env_set.h index dbd4f49..70d3bf7 100644 --- a/env_set.h +++ b/env_set.h @@ -41,6 +41,6 @@ void process_setenv(connection_t *c, time_t timestamp, const char *msg); * as the env block or NULL on error. The caller must free the returned * pointer. */ -wchar_t * merge_env_block(const struct env_item *es); +wchar_t *merge_env_block(const struct env_item *es); #endif diff --git a/localization.c b/localization.c index 50fb1ec..1e93c72 100644 --- a/localization.c +++ b/localization.c @@ -52,18 +52,24 @@ FindResourceLang(PTSTR resType, PTSTR resId, LANGID langId) /* try to find the resource in requested language */ res = FindResourceEx(o.hInstance, resType, resId, langId); if (res) + { return res; + } /* try to find the resource in the default sublanguage */ LANGID defLangId = MAKELANGID(PRIMARYLANGID(langId), SUBLANG_DEFAULT); res = FindResourceEx(o.hInstance, resType, resId, defLangId); if (res) + { return res; + } /* try to find the resource in the default language */ res = FindResourceEx(o.hInstance, resType, resId, fallbackLangId); if (res) + { return res; + } /* try to find the resource in any language */ return FindResource(o.hInstance, resId, resType); @@ -90,7 +96,9 @@ LANGID GetGUILanguage(void) { if (gui_language != 0) + { return gui_language; + } HKEY regkey; DWORD value = 0; @@ -113,8 +121,10 @@ SetGUILanguage(LANGID langId) { HKEY regkey; if (RegCreateKeyEx(HKEY_CURRENT_USER, GUI_REGKEY_HKCU, 0, NULL, 0, - KEY_WRITE, NULL, ®key, NULL) != ERROR_SUCCESS ) + KEY_WRITE, NULL, ®key, NULL) != ERROR_SUCCESS) + { ShowLocalizedMsg(IDS_ERR_CREATE_REG_HKCU_KEY, GUI_REGKEY_HKCU); + } SetRegistryValueNumeric(regkey, _T("ui_language"), langId); InitMUILanguage(langId); @@ -197,12 +207,16 @@ LoadStringLang(UINT stringId, LANGID langId, PTSTR buffer, int bufferSize, va_li /* find resource block for string */ HRSRC res = FindResourceLang(RT_STRING, resBlockId, langId); if (res == NULL) + { goto err; + } /* get pointer to first entry in resource block */ entry = (PWCH) LoadResource(o.hInstance, res); if (entry == NULL) + { goto err; + } /* search for string in block */ for (int i = 0; i < 16; i++) @@ -216,12 +230,16 @@ LoadStringLang(UINT stringId, LANGID langId, PTSTR buffer, int bufferSize, va_li /* string does not exist */ if (i == resIndex && *entry == 0) + { break; + } /* string found, copy it */ PTSTR formatStr = (PTSTR) malloc((*entry + 1) * sizeof(TCHAR)); if (formatStr == NULL) + { break; + } formatStr[*entry] = 0; wcsncpy(formatStr, entry + 1, *entry); @@ -234,7 +252,9 @@ LoadStringLang(UINT stringId, LANGID langId, PTSTR buffer, int bufferSize, va_li err: /* not found, try again with the default language */ if (langId != fallbackLangId) + { return LoadStringLang(stringId, fallbackLangId, buffer, bufferSize, args); + } return 0; } @@ -276,7 +296,7 @@ static int __ShowLocalizedMsgEx(const UINT type, HANDLE parent, LPCTSTR caption, const UINT stringId, va_list args) { return MessageBoxEx(parent, __LoadLocalizedString(stringId, args), caption, - type | MB_SETFOREGROUND | MBOX_RTL_FLAGS, GetGUILanguage()); + type | MB_SETFOREGROUND | MBOX_RTL_FLAGS, GetGUILanguage()); } int @@ -305,12 +325,16 @@ LoadLocalizedIconEx(const UINT iconId, int cxDesired, int cyDesired) LANGID langId = GetGUILanguage(); HICON hIcon = - (HICON) LoadImage (o.hInstance, MAKEINTRESOURCE(iconId), - IMAGE_ICON, cxDesired, cyDesired, LR_DEFAULTSIZE|LR_SHARED); + (HICON) LoadImage(o.hInstance, MAKEINTRESOURCE(iconId), + IMAGE_ICON, cxDesired, cyDesired, LR_DEFAULTSIZE|LR_SHARED); if (hIcon) + { return hIcon; + } else - PrintDebug (L"Loading icon using LoadImage failed."); + { + PrintDebug(L"Loading icon using LoadImage failed."); + } /* Fallback to CreateIconFromResource which always scales * from the first image in the resource @@ -318,51 +342,63 @@ LoadLocalizedIconEx(const UINT iconId, int cxDesired, int cyDesired) /* find group icon resource */ HRSRC res = FindResourceLang(RT_GROUP_ICON, MAKEINTRESOURCE(iconId), langId); if (res == NULL) + { return NULL; + } HGLOBAL resInfo = LoadResource(o.hInstance, res); if (resInfo == NULL) + { return NULL; + } int id = LookupIconIdFromDirectory(resInfo, TRUE); if (id == 0) + { return NULL; + } /* find the actual icon */ res = FindResourceLang(RT_ICON, MAKEINTRESOURCE(id), langId); if (res == NULL) + { return NULL; + } resInfo = LoadResource(o.hInstance, res); if (resInfo == NULL) + { return NULL; + } DWORD resSize = SizeofResource(o.hInstance, res); if (resSize == 0) + { return NULL; + } /* Note: this uses the first icon in the resource and scales it */ hIcon = CreateIconFromResourceEx(resInfo, resSize, TRUE, 0x30000, - cxDesired, cyDesired, LR_DEFAULTSIZE|LR_SHARED); + cxDesired, cyDesired, LR_DEFAULTSIZE|LR_SHARED); return hIcon; } HICON LoadLocalizedIcon(const UINT iconId) { - /* get the required normal icon size (e.g., taskbar icon) */ - int cx = GetSystemMetrics(SM_CXICON); - int cy = GetSystemMetrics(SM_CYICON); - return LoadLocalizedIconEx(iconId, cx, cy); + /* get the required normal icon size (e.g., taskbar icon) */ + int cx = GetSystemMetrics(SM_CXICON); + int cy = GetSystemMetrics(SM_CYICON); + return LoadLocalizedIconEx(iconId, cx, cy); } HICON LoadLocalizedSmallIcon(const UINT iconId) { - /* get the required small icon size (e.g., tray icon) */ - int cx = GetSystemMetrics(SM_CXSMICON); - int cy = GetSystemMetrics(SM_CYSMICON); - return LoadLocalizedIconEx(iconId, cx, cy); + /* get the required small icon size (e.g., tray icon) */ + int cx = GetSystemMetrics(SM_CXSMICON); + int cy = GetSystemMetrics(SM_CYSMICON); + return LoadLocalizedIconEx(iconId, cx, cy); } LPCDLGTEMPLATE @@ -371,7 +407,9 @@ LocalizedDialogResource(const UINT dialogId) /* find dialog resource */ HRSRC res = FindResourceLang(RT_DIALOG, MAKEINTRESOURCE(dialogId), GetGUILanguage()); if (res == NULL) + { return NULL; + } return LoadResource(o.hInstance, res); } @@ -388,7 +426,9 @@ LocalizedDialogBoxParamEx(const UINT dialogId, HWND owner, DLGPROC dialogFunc, c { LPCDLGTEMPLATE resInfo = LocalizedDialogResource(dialogId); if (resInfo == NULL) + { return -1; + } return DialogBoxIndirectParam(o.hInstance, resInfo, owner, dialogFunc, param); } @@ -399,11 +439,15 @@ CreateLocalizedDialogParam(const UINT dialogId, DLGPROC dialogFunc, const LPARAM /* find dialog resource */ HRSRC res = FindResourceLang(RT_DIALOG, MAKEINTRESOURCE(dialogId), GetGUILanguage()); if (res == NULL) + { return NULL; + } HGLOBAL resInfo = LoadResource(o.hInstance, res); if (resInfo == NULL) + { return NULL; + } return CreateDialogIndirectParam(o.hInstance, resInfo, o.hWnd, dialogFunc, param); } @@ -438,59 +482,71 @@ typedef struct { static BOOL FillLangListProc(UNUSED HANDLE module, UNUSED PTSTR type, UNUSED PTSTR stringId, WORD langId, LONG_PTR lParam) { - langProcData *data = (langProcData*) lParam; + langProcData *data = (langProcData *) lParam; int index = ComboBox_AddString(data->languages, LangListEntry(IDS_LANGUAGE_NAME, langId)); ComboBox_SetItemData(data->languages, index, langId); /* Select this item if it is the currently displayed language */ if (langId == data->language - || (PRIMARYLANGID(langId) == PRIMARYLANGID(data->language) - && ComboBox_GetCurSel(data->languages) == CB_ERR) ) + || (PRIMARYLANGID(langId) == PRIMARYLANGID(data->language) + && ComboBox_GetCurSel(data->languages) == CB_ERR) ) + { ComboBox_SetCurSel(data->languages, index); + } return TRUE; } -static BOOL +static BOOL GetLaunchOnStartup() { - - WCHAR regPath[MAX_PATH], exePath[MAX_PATH]; + + WCHAR regPath[MAX_PATH], exePath[MAX_PATH]; BOOL result = FALSE; HKEY regkey; - if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_READ, ®key) == ERROR_SUCCESS) { + if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_READ, ®key) == ERROR_SUCCESS) + { - if (GetRegistryValue(regkey, L"OpenVPN-GUI", regPath, MAX_PATH) && - GetModuleFileNameW(NULL, exePath, MAX_PATH)) { + if (GetRegistryValue(regkey, L"OpenVPN-GUI", regPath, MAX_PATH) + && GetModuleFileNameW(NULL, exePath, MAX_PATH)) + { if (_wcsicmp(regPath, exePath) == 0) + { result = TRUE; + } } RegCloseKey(regkey); } - + return result; } static void -SetLaunchOnStartup(BOOL value) +SetLaunchOnStartup(BOOL value) { WCHAR exePath[MAX_PATH]; HKEY regkey; - if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_WRITE, ®key) == ERROR_SUCCESS) { + if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_WRITE, ®key) == ERROR_SUCCESS) + { - if (value) { - if (GetModuleFileNameW(NULL, exePath, MAX_PATH)) + if (value) + { + if (GetModuleFileNameW(NULL, exePath, MAX_PATH)) + { SetRegistryValue(regkey, L"OpenVPN-GUI", exePath); + } + } + else + { + RegDeleteValue(regkey, L"OpenVPN-GUI"); } - else - RegDeleteValue(regkey, L"OpenVPN-GUI"); RegCloseKey(regkey); @@ -507,108 +563,155 @@ GeneralSettingsDlgProc(HWND hwndDlg, UINT msg, UNUSED WPARAM wParam, LPARAM lPar .language = GetGUILanguage() }; - switch(msg) { - - case WM_INITDIALOG: - /* Populate UI language selection combo box */ - EnumResourceLanguages( NULL, RT_STRING, MAKEINTRESOURCE(IDS_LANGUAGE_NAME / 16 + 1), - (ENUMRESLANGPROC) FillLangListProc, (LONG_PTR) &langData ); - - /* If none of the available languages matched, select the fallback */ - if (ComboBox_GetCurSel(langData.languages) == CB_ERR) - ComboBox_SelectString(langData.languages, -1, - LangListEntry(IDS_LANGUAGE_NAME, fallbackLangId)); - - /* Clear language id data for the selected item */ - ComboBox_SetItemData(langData.languages, ComboBox_GetCurSel(langData.languages), 0); - - if (GetLaunchOnStartup()) - Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_STARTUP), BST_CHECKED); - - if (o.log_append) - 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.iservice_admin) - Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_ALWAYS_USE_ISERVICE), BST_CHECKED); - if (o.show_balloon == 0) - CheckRadioButton (hwndDlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON0); - else if (o.show_balloon == 1) - CheckRadioButton (hwndDlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON1); - else if (o.show_balloon == 2) - CheckRadioButton (hwndDlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON2); - if (o.show_script_window) - Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_SHOW_SCRIPT_WIN), BST_CHECKED); - if (o.enable_persistent == 0) /* Never */ - CheckRadioButton (hwndDlg, ID_RB_BALLOON3, ID_RB_BALLOON5, ID_RB_BALLOON5); - else if (o.enable_persistent == 1) /* Enabled, but no auto-attach */ - CheckRadioButton (hwndDlg, ID_RB_BALLOON3, ID_RB_BALLOON5, ID_RB_BALLOON4); - else if (o.enable_persistent == 2) /* Enabled and auto-attach */ - CheckRadioButton (hwndDlg, ID_RB_BALLOON3, ID_RB_BALLOON5, ID_RB_BALLOON3); - - int plap_status = GetPLAPRegistrationStatus(); - if (plap_status == -1) /* PLAP not supported in this version */ - ShowWindow(GetDlgItem(hwndDlg, ID_CHK_PLAP_REG), SW_HIDE); - else if (plap_status != 0) - Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_PLAP_REG), BST_CHECKED); - if (o.enable_auto_restart) - Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_AUTO_RESTART), BST_CHECKED); - - break; - - case WM_COMMAND: - if (LOWORD(wParam) == ID_CHK_PLAP_REG && HIWORD(wParam) == BN_CLICKED) - { - /* change PLAPRegistration state */ - HWND h = GetDlgItem(hwndDlg, ID_CHK_PLAP_REG); - BOOL newstate = Button_GetCheck(h) == BST_CHECKED ? TRUE : FALSE; - if (SetPLAPRegistration(newstate) != 0) /* failed or user cancelled -- reset checkmark */ - Button_SetCheck(h, newstate ? BST_UNCHECKED : BST_CHECKED); - } - break; + switch (msg) + { - case WM_NOTIFY: - psn = (LPPSHNOTIFY) lParam; - if (psn->hdr.code == (UINT) PSN_APPLY) - { - LANGID langId = (LANGID) ComboBox_GetItemData(langData.languages, - ComboBox_GetCurSel(langData.languages)); - - if (langId != 0) - SetGUILanguage(langId); - - SetLaunchOnStartup(Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_STARTUP)) == BST_CHECKED); - - o.log_append = - (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_LOG_APPEND)) == BST_CHECKED); - o.silent_connection = - (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_SILENT)) == BST_CHECKED); - o.iservice_admin = - (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_ALWAYS_USE_ISERVICE)) == BST_CHECKED); - if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON0)) - o.show_balloon = 0; - else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON2)) - o.show_balloon = 2; - else - o.show_balloon = 1; - if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON3)) - o.enable_persistent = 2; - else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON4)) - o.enable_persistent = 1; - else - o.enable_persistent = 0; - o.show_script_window = - (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_SHOW_SCRIPT_WIN)) == BST_CHECKED); - o.enable_auto_restart = - (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_AUTO_RESTART)) == BST_CHECKED); - - - SaveRegistryKeys(); - - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); - return TRUE; - } - break; + case WM_INITDIALOG: + /* Populate UI language selection combo box */ + EnumResourceLanguages( NULL, RT_STRING, MAKEINTRESOURCE(IDS_LANGUAGE_NAME / 16 + 1), + (ENUMRESLANGPROC) FillLangListProc, (LONG_PTR) &langData ); + + /* If none of the available languages matched, select the fallback */ + if (ComboBox_GetCurSel(langData.languages) == CB_ERR) + { + ComboBox_SelectString(langData.languages, -1, + LangListEntry(IDS_LANGUAGE_NAME, fallbackLangId)); + } + + /* Clear language id data for the selected item */ + ComboBox_SetItemData(langData.languages, ComboBox_GetCurSel(langData.languages), 0); + + if (GetLaunchOnStartup()) + { + Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_STARTUP), BST_CHECKED); + } + + if (o.log_append) + { + 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.iservice_admin) + { + Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_ALWAYS_USE_ISERVICE), BST_CHECKED); + } + if (o.show_balloon == 0) + { + CheckRadioButton(hwndDlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON0); + } + else if (o.show_balloon == 1) + { + CheckRadioButton(hwndDlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON1); + } + else if (o.show_balloon == 2) + { + CheckRadioButton(hwndDlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON2); + } + if (o.show_script_window) + { + Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_SHOW_SCRIPT_WIN), BST_CHECKED); + } + if (o.enable_persistent == 0) /* Never */ + { + CheckRadioButton(hwndDlg, ID_RB_BALLOON3, ID_RB_BALLOON5, ID_RB_BALLOON5); + } + else if (o.enable_persistent == 1) /* Enabled, but no auto-attach */ + { + CheckRadioButton(hwndDlg, ID_RB_BALLOON3, ID_RB_BALLOON5, ID_RB_BALLOON4); + } + else if (o.enable_persistent == 2) /* Enabled and auto-attach */ + { + CheckRadioButton(hwndDlg, ID_RB_BALLOON3, ID_RB_BALLOON5, ID_RB_BALLOON3); + } + + int plap_status = GetPLAPRegistrationStatus(); + if (plap_status == -1) /* PLAP not supported in this version */ + { + ShowWindow(GetDlgItem(hwndDlg, ID_CHK_PLAP_REG), SW_HIDE); + } + else if (plap_status != 0) + { + Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_PLAP_REG), BST_CHECKED); + } + if (o.enable_auto_restart) + { + Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_AUTO_RESTART), BST_CHECKED); + } + + break; + + case WM_COMMAND: + if (LOWORD(wParam) == ID_CHK_PLAP_REG && HIWORD(wParam) == BN_CLICKED) + { + /* change PLAPRegistration state */ + HWND h = GetDlgItem(hwndDlg, ID_CHK_PLAP_REG); + BOOL newstate = Button_GetCheck(h) == BST_CHECKED ? TRUE : FALSE; + if (SetPLAPRegistration(newstate) != 0) /* failed or user cancelled -- reset checkmark */ + { + Button_SetCheck(h, newstate ? BST_UNCHECKED : BST_CHECKED); + } + } + break; + + case WM_NOTIFY: + psn = (LPPSHNOTIFY) lParam; + if (psn->hdr.code == (UINT) PSN_APPLY) + { + LANGID langId = (LANGID) ComboBox_GetItemData(langData.languages, + ComboBox_GetCurSel(langData.languages)); + + if (langId != 0) + { + SetGUILanguage(langId); + } + + SetLaunchOnStartup(Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_STARTUP)) == BST_CHECKED); + + o.log_append = + (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_LOG_APPEND)) == BST_CHECKED); + o.silent_connection = + (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_SILENT)) == BST_CHECKED); + o.iservice_admin = + (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_ALWAYS_USE_ISERVICE)) == BST_CHECKED); + if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON0)) + { + o.show_balloon = 0; + } + else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON2)) + { + o.show_balloon = 2; + } + else + { + o.show_balloon = 1; + } + if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON3)) + { + o.enable_persistent = 2; + } + else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON4)) + { + o.enable_persistent = 1; + } + else + { + o.enable_persistent = 0; + } + o.show_script_window = + (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_SHOW_SCRIPT_WIN)) == BST_CHECKED); + o.enable_auto_restart = + (Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_AUTO_RESTART)) == BST_CHECKED); + + + SaveRegistryKeys(); + + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); + return TRUE; + } + break; } return FALSE; diff --git a/localization.h b/localization.h index b83b47c..cb2bab4 100644 --- a/localization.h +++ b/localization.h @@ -23,26 +23,43 @@ #define LOCALIZATION_H int LocalizedTime(const time_t, LPTSTR, size_t); + wchar_t *LocalizedFileTime(const FILETIME *ft); + PTSTR LoadLocalizedString(const UINT, ...); + int LoadLocalizedStringBuf(PTSTR, const int, const UINT, ...); + void ShowLocalizedMsg(const UINT, ...); + int ShowLocalizedMsgEx(const UINT, HANDLE, LPCTSTR, const UINT, ...); + HICON LoadLocalizedIconEx(const UINT, int cx, int cy); + HICON LoadLocalizedIcon(const UINT); + HICON LoadLocalizedSmallIcon(const UINT); + LPCDLGTEMPLATE LocalizedDialogResource(const UINT); + INT_PTR LocalizedDialogBoxParam(const UINT, DLGPROC, const LPARAM); + INT_PTR LocalizedDialogBoxParamEx(const UINT, HWND parent, DLGPROC, const LPARAM); + HWND CreateLocalizedDialogParam(const UINT, DLGPROC, const LPARAM); + HWND CreateLocalizedDialog(const UINT, DLGPROC); + INT_PTR CALLBACK GeneralSettingsDlgProc(HWND, UINT, WPARAM, LPARAM); + LANGID GetGUILanguage(void); + /* * Detect whether the selected UI language is LTR or RTL. * Returns 0 for LTR, 1 for RTL, 2 or 3 for vertical */ int LangFlowDirection(void); + #define MBOX_RTL_FLAGS ((LangFlowDirection() == 1) ? MB_RIGHT|MB_RTLREADING : 0) -#endif +#endif /* ifndef LOCALIZATION_H */ diff --git a/main.c b/main.c index d5903b6..338acc3 100644 --- a/main.c +++ b/main.c @@ -56,17 +56,23 @@ #define OVPN_EXITCODE_NOTREADY 3 /* Declare Windows procedure */ -LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM); +LRESULT CALLBACK WindowProcedure(HWND, UINT, WPARAM, LPARAM); + static void ShowSettingsDialog(); + void CloseApplication(HWND hwnd, BOOL ask_user); + void ImportConfigFileFromDisk(); + void ImportConfigFromAS(); + static void SaveAutoRestartList(); + static void LoadAutoRestartList(); /* Class name and window title */ -TCHAR szClassName[ ] = _T("OpenVPN-GUI"); -TCHAR szTitleText[ ] = _T("OpenVPN"); +TCHAR szClassName[] = _T("OpenVPN-GUI"); +TCHAR szTitleText[] = _T("OpenVPN"); /* Options structure */ options_t o; @@ -106,12 +112,12 @@ NotifyRunningInstance() * Even if we are not the first instance this may return null * if the previous instance has not fully started up */ - HANDLE hwnd_master = FindWindow (szClassName, NULL); + HANDLE hwnd_master = FindWindow(szClassName, NULL); int exit_code = 0; if (hwnd_master) { /* GUI up and running -- send a message if any action is pecified, - else show the balloon */ + * else show the balloon */ COPYDATASTRUCT config_data = {0}; int timeout = 30*1000; /* 30 seconds */ if (!o.action) @@ -126,8 +132,8 @@ NotifyRunningInstance() config_data.lpData = (void *) o.action_arg; } PrintDebug(L"Instance 2: called with action %d : %ls", o.action, o.action_arg); - if (!SendMessageTimeout (hwnd_master, WM_COPYDATA, 0, - (LPARAM) &config_data, 0, timeout, NULL)) + if (!SendMessageTimeout(hwnd_master, WM_COPYDATA, 0, + (LPARAM) &config_data, 0, timeout, NULL)) { DWORD error = GetLastError(); if (error == ERROR_TIMEOUT) @@ -154,190 +160,203 @@ NotifyRunningInstance() return exit_code; } -int WINAPI _tWinMain (HINSTANCE hThisInstance, - UNUSED HINSTANCE hPrevInstance, - UNUSED LPTSTR lpszArgument, - UNUSED int nCmdShow) +int WINAPI +_tWinMain(HINSTANCE hThisInstance, + UNUSED HINSTANCE hPrevInstance, + UNUSED LPTSTR lpszArgument, + UNUSED int nCmdShow) { - MSG messages; /* Here messages to the application are saved */ - WNDCLASSEX wincl; /* Data structure for the windowclass */ - DWORD shell32_version; - BOOL first_instance = TRUE; - /* a session local semaphore to detect second instance */ - HANDLE session_semaphore = InitSemaphore(L"Local\\"PACKAGE_NAME); - - srand(time(NULL)); - /* try to lock the semaphore, else we are not the first instance */ - if (session_semaphore && - WaitForSingleObject(session_semaphore, 200) != WAIT_OBJECT_0) - { - first_instance = FALSE; - } - - /* Initialize handlers for manangement interface notifications */ - mgmt_rtmsg_handler handler[] = { - { ready_, OnReady }, - { hold_, OnHold }, - { log_, OnLogLine }, - { state_, OnStateChange }, - { password_, OnPassword }, - { proxy_, OnProxy }, - { stop_, OnStop }, - { needok_, OnNeedOk }, - { needstr_, OnNeedStr }, - { echo_, OnEcho }, - { bytecount_,OnByteCount }, - { infomsg_, OnInfoMsg }, - { timeout_, OnTimeout }, - { 0, NULL } - }; - InitManagement(handler); - - /* initialize options to default state */ - InitOptions(&o); - if (first_instance) - o.session_semaphore = session_semaphore; + MSG messages; /* Here messages to the application are saved */ + WNDCLASSEX wincl; /* Data structure for the windowclass */ + DWORD shell32_version; + BOOL first_instance = TRUE; + /* a session local semaphore to detect second instance */ + HANDLE session_semaphore = InitSemaphore(L"Local\\"PACKAGE_NAME); + + srand(time(NULL)); + /* try to lock the semaphore, else we are not the first instance */ + if (session_semaphore + && WaitForSingleObject(session_semaphore, 200) != WAIT_OBJECT_0) + { + first_instance = FALSE; + } + + /* Initialize handlers for manangement interface notifications */ + mgmt_rtmsg_handler handler[] = { + { ready_, OnReady }, + { hold_, OnHold }, + { log_, OnLogLine }, + { state_, OnStateChange }, + { password_, OnPassword }, + { proxy_, OnProxy }, + { stop_, OnStop }, + { needok_, OnNeedOk }, + { needstr_, OnNeedStr }, + { echo_, OnEcho }, + { bytecount_, OnByteCount }, + { infomsg_, OnInfoMsg }, + { timeout_, OnTimeout }, + { 0, NULL } + }; + InitManagement(handler); + + /* initialize options to default state */ + InitOptions(&o); + if (first_instance) + { + o.session_semaphore = session_semaphore; + } #ifdef DEBUG - /* Open debug file for output */ - if (!(o.debug_fp = _wfopen(DEBUG_FILE, L"a+,ccs=UTF-8"))) + /* Open debug file for output */ + if (!(o.debug_fp = _wfopen(DEBUG_FILE, L"a+,ccs=UTF-8"))) { - /* can't open debug file */ - ShowLocalizedMsg(IDS_ERR_OPEN_DEBUG_FILE, DEBUG_FILE); - exit(1); + /* can't open debug file */ + ShowLocalizedMsg(IDS_ERR_OPEN_DEBUG_FILE, DEBUG_FILE); + exit(1); } - PrintDebug(_T("Starting OpenVPN GUI v%hs"), PACKAGE_VERSION); + PrintDebug(_T("Starting OpenVPN GUI v%hs"), PACKAGE_VERSION); #endif - o.hInstance = hThisInstance; + o.hInstance = hThisInstance; - if(!GetModuleHandle(_T("RICHED20.DLL"))) + if (!GetModuleHandle(_T("RICHED20.DLL"))) { - LoadLibrary(_T("RICHED20.DLL")); + LoadLibrary(_T("RICHED20.DLL")); } - else + else { - /* can't load riched20.dll */ - ShowLocalizedMsg(IDS_ERR_LOAD_RICHED20); - exit(1); + /* can't load riched20.dll */ + ShowLocalizedMsg(IDS_ERR_LOAD_RICHED20); + exit(1); } - /* Check version of shell32.dll */ - shell32_version=GetDllVersion(_T("shell32.dll")); - if (shell32_version < PACKVERSION(5,0)) + /* Check version of shell32.dll */ + shell32_version = GetDllVersion(_T("shell32.dll")); + if (shell32_version < PACKVERSION(5, 0)) { - /* shell32.dll version to low */ - ShowLocalizedMsg(IDS_ERR_SHELL_DLL_VERSION, shell32_version); - exit(1); + /* shell32.dll version to low */ + ShowLocalizedMsg(IDS_ERR_SHELL_DLL_VERSION, shell32_version); + exit(1); } #ifdef DEBUG - PrintDebug(_T("Shell32.dll version: 0x%lx"), shell32_version); + PrintDebug(_T("Shell32.dll version: 0x%lx"), shell32_version); #endif - if (first_instance) - UpdateRegistry(); /* Checks version change and update keys/values */ - - GetRegistryKeys(); - /* Parse command-line options */ - ProcessCommandLine(&o, GetCommandLine()); - - EnsureDirExists(o.config_dir); - - if (!first_instance) - { - int res = NotifyRunningInstance(); - exit(res); - } - else if (o.action == WM_OVPN_START) - { - PrintDebug(L"Instance 1: Called with --command connect xxx. Treating it as --connect xxx"); - } - else if (o.action == WM_OVPN_IMPORT) - { - ; /* pass -- import is handled after Window initialization */ - } - else if (o.action) - { - MsgToEventLog(EVENTLOG_ERROR_TYPE, L"Called with --command when no previous instance available"); - exit(OVPN_EXITCODE_ERROR); - } - - if (!CheckVersion()) { - exit(1); - } - - if (!EnsureDirExists(o.log_dir)) - { - ShowLocalizedMsg(IDS_ERR_CREATE_PATH, _T("log_dir"), o.log_dir); - exit(1); - } - - BOOL use_iservice = (o.iservice_admin && IsWindows7OrGreater()) || !IsUserAdmin(); - if (use_iservice && strtod(o.ovpn_version, NULL) > 2.3 && !o.silent_connection) - CheckIServiceStatus(TRUE); - - CheckServiceStatus(); /* Check if automatic service is running or not */ - BuildFileList(); - - if (!VerifyAutoConnections()) { - exit(1); - } - - GetProxyRegistrySettings(); - - /* The Window structure */ - wincl.hInstance = hThisInstance; - wincl.lpszClassName = szClassName; - wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ - wincl.style = CS_DBLCLKS; /* Catch double-clicks */ - wincl.cbSize = sizeof (WNDCLASSEX); - - /* Use default icon and mouse-pointer */ - wincl.hIcon = LoadLocalizedIcon(ID_ICO_APP); - wincl.hIconSm = LoadLocalizedIcon(ID_ICO_APP); - wincl.hCursor = LoadCursor (NULL, IDC_ARROW); - wincl.lpszMenuName = NULL; /* No menu */ - wincl.cbClsExtra = 0; /* No extra bytes after the window class */ - wincl.cbWndExtra = 0; /* structure or the window instance */ - /* Use Windows's default color as the background of the window */ - wincl.hbrBackground = (HBRUSH) COLOR_3DSHADOW; //COLOR_BACKGROUND; - - /* Register the window class, and if it fails quit the program */ - if (!RegisterClassEx (&wincl)) - return 1; - - /* The class is registered, let's create the program*/ - CreateWindowEx ( - 0, /* Extended possibilites for variation */ - szClassName, /* Classname */ - szTitleText, /* Title Text */ - WS_OVERLAPPEDWINDOW, /* default window */ - (int)CW_USEDEFAULT, /* Windows decides the position */ - (int)CW_USEDEFAULT, /* where the window ends up on the screen */ - 230, /* The programs width */ - 200, /* and height in pixels */ - HWND_DESKTOP, /* The window is a child-window to desktop */ - NULL, /* No menu */ - hThisInstance, /* Program Instance handler */ - NULL /* No Window Creation data */ - ); - - - /* Run the message loop. It will run until GetMessage() returns 0 */ - while (GetMessage (&messages, NULL, 0, 0)) - { - TranslateMessage(&messages); - DispatchMessage(&messages); - } - - CloseSemaphore(o.session_semaphore); - o.session_semaphore = NULL; /* though we're going to die.. */ - if (o.event_log) - DeregisterEventSource(o.event_log); - - /* The program return-value is 0 - The value that PostQuitMessage() gave */ - return messages.wParam; + if (first_instance) + { + UpdateRegistry(); /* Checks version change and update keys/values */ + + } + GetRegistryKeys(); + /* Parse command-line options */ + ProcessCommandLine(&o, GetCommandLine()); + + EnsureDirExists(o.config_dir); + + if (!first_instance) + { + int res = NotifyRunningInstance(); + exit(res); + } + else if (o.action == WM_OVPN_START) + { + PrintDebug(L"Instance 1: Called with --command connect xxx. Treating it as --connect xxx"); + } + else if (o.action == WM_OVPN_IMPORT) + { + /* pass -- import is handled after Window initialization */ + } + else if (o.action) + { + MsgToEventLog(EVENTLOG_ERROR_TYPE, L"Called with --command when no previous instance available"); + exit(OVPN_EXITCODE_ERROR); + } + + if (!CheckVersion()) + { + exit(1); + } + + if (!EnsureDirExists(o.log_dir)) + { + ShowLocalizedMsg(IDS_ERR_CREATE_PATH, _T("log_dir"), o.log_dir); + exit(1); + } + + BOOL use_iservice = (o.iservice_admin && IsWindows7OrGreater()) || !IsUserAdmin(); + if (use_iservice && strtod(o.ovpn_version, NULL) > 2.3 && !o.silent_connection) + { + CheckIServiceStatus(TRUE); + } + + CheckServiceStatus(); /* Check if automatic service is running or not */ + BuildFileList(); + + if (!VerifyAutoConnections()) + { + exit(1); + } + + GetProxyRegistrySettings(); + + /* The Window structure */ + wincl.hInstance = hThisInstance; + wincl.lpszClassName = szClassName; + wincl.lpfnWndProc = WindowProcedure; /* This function is called by windows */ + wincl.style = CS_DBLCLKS; /* Catch double-clicks */ + wincl.cbSize = sizeof(WNDCLASSEX); + + /* Use default icon and mouse-pointer */ + wincl.hIcon = LoadLocalizedIcon(ID_ICO_APP); + wincl.hIconSm = LoadLocalizedIcon(ID_ICO_APP); + wincl.hCursor = LoadCursor(NULL, IDC_ARROW); + wincl.lpszMenuName = NULL; /* No menu */ + wincl.cbClsExtra = 0; /* No extra bytes after the window class */ + wincl.cbWndExtra = 0; /* structure or the window instance */ + /* Use Windows's default color as the background of the window */ + wincl.hbrBackground = (HBRUSH) COLOR_3DSHADOW; /*COLOR_BACKGROUND; */ + + /* Register the window class, and if it fails quit the program */ + if (!RegisterClassEx(&wincl)) + { + return 1; + } + + /* The class is registered, let's create the program*/ + CreateWindowEx( + 0, /* Extended possibilites for variation */ + szClassName, /* Classname */ + szTitleText, /* Title Text */ + WS_OVERLAPPEDWINDOW, /* default window */ + (int)CW_USEDEFAULT, /* Windows decides the position */ + (int)CW_USEDEFAULT, /* where the window ends up on the screen */ + 230, /* The programs width */ + 200, /* and height in pixels */ + HWND_DESKTOP, /* The window is a child-window to desktop */ + NULL, /* No menu */ + hThisInstance, /* Program Instance handler */ + NULL /* No Window Creation data */ + ); + + + /* Run the message loop. It will run until GetMessage() returns 0 */ + while (GetMessage(&messages, NULL, 0, 0)) + { + TranslateMessage(&messages); + DispatchMessage(&messages); + } + + CloseSemaphore(o.session_semaphore); + o.session_semaphore = NULL; /* though we're going to die.. */ + if (o.event_log) + { + DeregisterEventSource(o.event_log); + } + + /* The program return-value is 0 - The value that PostQuitMessage() gave */ + return messages.wParam; } @@ -388,7 +407,9 @@ AutoStartConnections() for (connection_t *c = o.chead; c; c = c->next) { if (c->auto_connect && !(c->flags & FLAG_DAEMON_PERSISTENT)) + { StartOpenVPN(c); + } } return TRUE; @@ -402,11 +423,15 @@ ResumeConnections() { /* Restart suspend connections */ if (c->state == suspended) + { StartOpenVPN(c); + } /* If some connection never reached SUSPENDED state */ if (c->state == suspending) + { StopOpenVPN(c); + } } } @@ -415,49 +440,59 @@ HandleCopyDataMessage(const COPYDATASTRUCT *copy_data) { WCHAR *str = NULL; connection_t *c = NULL; - PrintDebug (L"WM_COPYDATA message received. (dwData: %lu, cbData: %lu, lpData: %ls)", - copy_data->dwData, copy_data->cbData, copy_data->lpData); + PrintDebug(L"WM_COPYDATA message received. (dwData: %lu, cbData: %lu, lpData: %ls)", + copy_data->dwData, copy_data->cbData, copy_data->lpData); if (copy_data->cbData >= sizeof(WCHAR) && copy_data->lpData) { - str = (WCHAR*) copy_data->lpData; + str = (WCHAR *) copy_data->lpData; str[copy_data->cbData/sizeof(WCHAR)-1] = L'\0'; /* in case not nul-terminated */ c = GetConnByName(str); } - if(copy_data->dwData == WM_OVPN_START && c) + if (copy_data->dwData == WM_OVPN_START && c) { if (!o.silent_connection) + { ForceForegroundWindow(o.hWnd); + } StartOpenVPN(c); } - else if(copy_data->dwData == WM_OVPN_STOP && c) + else if (copy_data->dwData == WM_OVPN_STOP && c) + { StopOpenVPN(c); - else if(copy_data->dwData == WM_OVPN_RESTART && c) + } + else if (copy_data->dwData == WM_OVPN_RESTART && c) { if (!o.silent_connection) + { ForceForegroundWindow(o.hWnd); + } RestartOpenVPN(c); } - else if(copy_data->dwData == WM_OVPN_SHOWSTATUS && c && c->hwndStatus) + else if (copy_data->dwData == WM_OVPN_SHOWSTATUS && c && c->hwndStatus) { ForceForegroundWindow(o.hWnd); ShowWindow(c->hwndStatus, SW_SHOW); } - else if(copy_data->dwData == WM_OVPN_STOPALL) + else if (copy_data->dwData == WM_OVPN_STOPALL) { StopAllOpenVPN(false); } - else if(copy_data->dwData == WM_OVPN_SILENT && str) + else if (copy_data->dwData == WM_OVPN_SILENT && str) { if (_wtoi(str) == 0) + { o.silent_connection = 0; + } else + { o.silent_connection = 1; + } } - else if(copy_data->dwData == WM_OVPN_EXIT) + else if (copy_data->dwData == WM_OVPN_EXIT) { CloseApplication(o.hWnd, true); } - else if(copy_data->dwData == WM_OVPN_IMPORT && str) + else if (copy_data->dwData == WM_OVPN_IMPORT && str) { ImportConfigFile(str, true); /* prompt user */ } @@ -541,224 +576,251 @@ HandleSessionUnlock(void) if (c->flags & FLAG_WAIT_UNLOCK) { c->auto_connect = true; /* so that ManagePersistent will trigger attach */ - c->flags &= ~ FLAG_WAIT_UNLOCK; + c->flags &= ~FLAG_WAIT_UNLOCK; } } } /* This function is called by the Windows function DispatchMessage() */ -LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +LRESULT CALLBACK +WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - static UINT s_uTaskbarRestart; - MENUINFO minfo = {.cbSize = sizeof(MENUINFO)}; - connection_t *c = NULL; + static UINT s_uTaskbarRestart; + MENUINFO minfo = {.cbSize = sizeof(MENUINFO)}; + connection_t *c = NULL; - switch (message) { - case WM_CREATE: + switch (message) + { + case WM_CREATE: - /* Save Window Handle */ - o.hWnd = hwnd; - dpi_initialize(&o); + /* Save Window Handle */ + o.hWnd = hwnd; + dpi_initialize(&o); - s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated")); + s_uTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated")); - WTSRegisterSessionNotification(hwnd, NOTIFY_FOR_THIS_SESSION); + WTSRegisterSessionNotification(hwnd, NOTIFY_FOR_THIS_SESSION); - /* Load application icon */ - HICON hIcon = LoadLocalizedIcon(ID_ICO_APP); - if (hIcon) { - SendMessage(hwnd, WM_SETICON, (WPARAM) (ICON_SMALL), (LPARAM) (hIcon)); - SendMessage(hwnd, WM_SETICON, (WPARAM) (ICON_BIG), (LPARAM) (hIcon)); - } + /* Load application icon */ + HICON hIcon = LoadLocalizedIcon(ID_ICO_APP); + if (hIcon) + { + SendMessage(hwnd, WM_SETICON, (WPARAM) (ICON_SMALL), (LPARAM) (hIcon)); + SendMessage(hwnd, WM_SETICON, (WPARAM) (ICON_BIG), (LPARAM) (hIcon)); + } - /* Enable next line to accept WM_COPYDATA messages from lower level processes */ + /* Enable next line to accept WM_COPYDATA messages from lower level processes */ #if 0 - ChangeWindowMessageFilterEx(hwnd, WM_COPYDATA, MSGFLT_ALLOW, NULL); + ChangeWindowMessageFilterEx(hwnd, WM_COPYDATA, MSGFLT_ALLOW, NULL); #endif - echo_msg_init(); - - CreatePopupMenus(); /* Create popup menus */ - ShowTrayIcon(); - - /* if '--import' was specified, do it now */ - if (o.action == WM_OVPN_IMPORT && o.action_arg) - { - ImportConfigFile(o.action_arg, true); /* prompt user */ - } - - if (o.enable_auto_restart) - { - LoadAutoRestartList(); - } - - if (!AutoStartConnections()) { - SendMessage(hwnd, WM_CLOSE, 0, 0); - break; - } - /* A timer to periodically tend to persistent connections */ - SetTimer(hwnd, 1, 100, ManagePersistent); - - break; - - case WM_NOTIFYICONTRAY: - OnNotifyTray(lParam); // Manages message from tray - break; - - case WM_COPYDATA: // custom messages with data from other processes - HandleCopyDataMessage((COPYDATASTRUCT*) lParam); - return TRUE; /* lets the sender free copy_data */ - - case WM_MENUCOMMAND: - /* Get the menu item id and save it in wParam for use below */ - wParam = GetMenuItemID((HMENU) lParam, wParam); - - /* we first check global menu items which do not require a connnection index */ - if (LOWORD(wParam) == IDM_IMPORT_FILE) { - ImportConfigFileFromDisk(); - } - else if (LOWORD(wParam) == IDM_IMPORT_AS) { - ImportConfigFromAS(); - } - else if (LOWORD(wParam) == IDM_IMPORT_URL) { - ImportConfigFromURL(); - } - else if (LOWORD(wParam) == IDM_SETTINGS) { - ShowSettingsDialog(); - } - else if (LOWORD(wParam) == IDM_CLOSE) { - CloseApplication(hwnd, true); - } - /* rest of the handlers require a connection id */ - else { - minfo.fMask = MIM_MENUDATA; - GetMenuInfo((HMENU) lParam, &minfo); - c = (connection_t *) minfo.dwMenuData; - if (!c) - break; /* ignore invalid connection */ - } - - /* reach here only if the command did not match any global items and a valid connection id is available */ - - if (LOWORD(wParam) == IDM_CONNECTMENU) { - StartOpenVPN(c); - } - else if (LOWORD(wParam) == IDM_DISCONNECTMENU) { - StopOpenVPN(c); - } - else if (LOWORD(wParam) == IDM_RECONNECTMENU) { - RestartOpenVPN(c); - } - else if (LOWORD(wParam) == IDM_STATUSMENU) { - ShowWindow(c->hwndStatus, SW_SHOW); - } - else if (LOWORD(wParam) == IDM_VIEWLOGMENU) { - ViewLog(c); - } - else if (LOWORD(wParam) == IDM_EDITMENU) { - EditConfig(c); - } - else if (LOWORD(wParam) == IDM_CLEARPASSMENU) { - ResetSavePasswords(c); - } - break; - - case WM_CLOSE: - CloseApplication(hwnd, false); /* do not wait for user confirmation */ - break; - - case WM_DESTROY: - WTSUnRegisterSessionNotification(hwnd); - StopAllOpenVPN(true); - OnDestroyTray(); /* Remove Tray Icon and destroy menus */ - PostQuitMessage (0); /* Send a WM_QUIT to the message queue */ - break; - - case WM_QUERYENDSESSION: - return(TRUE); - - case WM_ENDSESSION: - SaveAutoRestartList(); - StopAllOpenVPN(true); - OnDestroyTray(); - break; - - case WM_WTSSESSION_CHANGE: - switch (wParam) { - case WTS_SESSION_LOCK: - PrintDebug(L"Session lock triggered"); - o.session_locked = TRUE; - /* Detach persistent connections so that other users can connect to it */ - HandleSessionLock(); - KillTimer(hwnd, 1); /* This ensure ManagePersistent is not called when session is locked */ - break; - - case WTS_SESSION_UNLOCK: - PrintDebug(L"Session unlock triggered"); - o.session_locked = FALSE; - HandleSessionUnlock(); - SetTimer(hwnd, 1, 100, ManagePersistent); - if (CountConnState(suspended) != 0) - ResumeConnections(); - break; - - default: - PrintDebug(L"Session change with wParam = %lu", wParam); - break; - } - break; - - default: /* for messages that we don't deal with */ - if (message == s_uTaskbarRestart) - { - /* Explorer has restarted, re-register the tray icon. */ - ShowTrayIcon(); - CheckAndSetTrayIcon(); - break; - } - return DefWindowProc (hwnd, message, wParam, lParam); - } + echo_msg_init(); - return 0; + CreatePopupMenus(); /* Create popup menus */ + ShowTrayIcon(); + + /* if '--import' was specified, do it now */ + if (o.action == WM_OVPN_IMPORT && o.action_arg) + { + ImportConfigFile(o.action_arg, true); /* prompt user */ + } + + if (o.enable_auto_restart) + { + LoadAutoRestartList(); + } + + if (!AutoStartConnections()) + { + SendMessage(hwnd, WM_CLOSE, 0, 0); + break; + } + /* A timer to periodically tend to persistent connections */ + SetTimer(hwnd, 1, 100, ManagePersistent); + + break; + + case WM_NOTIFYICONTRAY: + OnNotifyTray(lParam); /* Manages message from tray */ + break; + + case WM_COPYDATA: /* custom messages with data from other processes */ + HandleCopyDataMessage((COPYDATASTRUCT *) lParam); + return TRUE; /* lets the sender free copy_data */ + + case WM_MENUCOMMAND: + /* Get the menu item id and save it in wParam for use below */ + wParam = GetMenuItemID((HMENU) lParam, wParam); + + /* we first check global menu items which do not require a connnection index */ + if (LOWORD(wParam) == IDM_IMPORT_FILE) + { + ImportConfigFileFromDisk(); + } + else if (LOWORD(wParam) == IDM_IMPORT_AS) + { + ImportConfigFromAS(); + } + else if (LOWORD(wParam) == IDM_IMPORT_URL) + { + ImportConfigFromURL(); + } + else if (LOWORD(wParam) == IDM_SETTINGS) + { + ShowSettingsDialog(); + } + else if (LOWORD(wParam) == IDM_CLOSE) + { + CloseApplication(hwnd, true); + } + /* rest of the handlers require a connection id */ + else + { + minfo.fMask = MIM_MENUDATA; + GetMenuInfo((HMENU) lParam, &minfo); + c = (connection_t *) minfo.dwMenuData; + if (!c) + { + break; /* ignore invalid connection */ + } + } + + /* reach here only if the command did not match any global items and a valid connection id is available */ + + if (LOWORD(wParam) == IDM_CONNECTMENU) + { + StartOpenVPN(c); + } + else if (LOWORD(wParam) == IDM_DISCONNECTMENU) + { + StopOpenVPN(c); + } + else if (LOWORD(wParam) == IDM_RECONNECTMENU) + { + RestartOpenVPN(c); + } + else if (LOWORD(wParam) == IDM_STATUSMENU) + { + ShowWindow(c->hwndStatus, SW_SHOW); + } + else if (LOWORD(wParam) == IDM_VIEWLOGMENU) + { + ViewLog(c); + } + else if (LOWORD(wParam) == IDM_EDITMENU) + { + EditConfig(c); + } + else if (LOWORD(wParam) == IDM_CLEARPASSMENU) + { + ResetSavePasswords(c); + } + break; + + case WM_CLOSE: + CloseApplication(hwnd, false); /* do not wait for user confirmation */ + break; + + case WM_DESTROY: + WTSUnRegisterSessionNotification(hwnd); + StopAllOpenVPN(true); + OnDestroyTray(); /* Remove Tray Icon and destroy menus */ + PostQuitMessage(0); /* Send a WM_QUIT to the message queue */ + break; + + case WM_QUERYENDSESSION: + return(TRUE); + + case WM_ENDSESSION: + SaveAutoRestartList(); + StopAllOpenVPN(true); + OnDestroyTray(); + break; + + case WM_WTSSESSION_CHANGE: + switch (wParam) + { + case WTS_SESSION_LOCK: + PrintDebug(L"Session lock triggered"); + o.session_locked = TRUE; + /* Detach persistent connections so that other users can connect to it */ + HandleSessionLock(); + KillTimer(hwnd, 1); /* This ensure ManagePersistent is not called when session is locked */ + break; + + case WTS_SESSION_UNLOCK: + PrintDebug(L"Session unlock triggered"); + o.session_locked = FALSE; + HandleSessionUnlock(); + SetTimer(hwnd, 1, 100, ManagePersistent); + if (CountConnState(suspended) != 0) + { + ResumeConnections(); + } + break; + + default: + PrintDebug(L"Session change with wParam = %lu", wParam); + break; + } + break; + + default: /* for messages that we don't deal with */ + if (message == s_uTaskbarRestart) + { + /* Explorer has restarted, re-register the tray icon. */ + ShowTrayIcon(); + CheckAndSetTrayIcon(); + break; + } + return DefWindowProc(hwnd, message, wParam, lParam); + } + + return 0; } static INT_PTR CALLBACK AboutDialogFunc(UNUSED HWND hDlg, UINT msg, UNUSED WPARAM wParam, LPARAM lParam) { - LPPSHNOTIFY psn; - wchar_t tmp1[300], tmp2[300]; - switch (msg) { - case WM_INITDIALOG: - if (GetDlgItemText(hDlg, ID_TXT_VERSION, tmp1, _countof(tmp1))) { - _sntprintf_0(tmp2, tmp1, TEXT(PACKAGE_VERSION_RESOURCE_STR)); - SetDlgItemText(hDlg, ID_TXT_VERSION, tmp2); - } - /* Modify the ABOUT3 line that reads as "OpenVPN ... " by - * including the version, like "OpenVPN v2.5.8 ... ". - * The logic used depends on this text starting with - * "OpenVPN", which is the case in all languages. - */ - const wchar_t *prefix = L"OpenVPN "; - if (GetDlgItemText(hDlg, ID_LTEXT_ABOUT3, tmp1, _countof(tmp1)) - && wcsbegins(tmp1, prefix)) - { - _sntprintf_0(tmp2, L"%lsv%hs %ls", prefix, o.ovpn_version, tmp1 + wcslen(prefix)); - SetDlgItemText(hDlg, ID_LTEXT_ABOUT3, tmp2); - } - break; - case WM_NOTIFY: - psn = (LPPSHNOTIFY) lParam; - if (psn->hdr.code == (UINT) PSN_APPLY) - return TRUE; - } - return FALSE; + LPPSHNOTIFY psn; + wchar_t tmp1[300], tmp2[300]; + switch (msg) + { + case WM_INITDIALOG: + if (GetDlgItemText(hDlg, ID_TXT_VERSION, tmp1, _countof(tmp1))) + { + _sntprintf_0(tmp2, tmp1, TEXT(PACKAGE_VERSION_RESOURCE_STR)); + SetDlgItemText(hDlg, ID_TXT_VERSION, tmp2); + } + /* Modify the ABOUT3 line that reads as "OpenVPN ... " by + * including the version, like "OpenVPN v2.5.8 ... ". + * The logic used depends on this text starting with + * "OpenVPN", which is the case in all languages. + */ + const wchar_t *prefix = L"OpenVPN "; + if (GetDlgItemText(hDlg, ID_LTEXT_ABOUT3, tmp1, _countof(tmp1)) + && wcsbegins(tmp1, prefix)) + { + _sntprintf_0(tmp2, L"%lsv%hs %ls", prefix, o.ovpn_version, tmp1 + wcslen(prefix)); + SetDlgItemText(hDlg, ID_LTEXT_ABOUT3, tmp2); + } + break; + + case WM_NOTIFY: + psn = (LPPSHNOTIFY) lParam; + if (psn->hdr.code == (UINT) PSN_APPLY) + { + return TRUE; + } + } + return FALSE; } static int CALLBACK SettingsPsCallback(HWND hwnd, UINT msg, UNUSED LPARAM lParam) { - switch(msg) + switch (msg) { case PSCB_INITIALIZED: settings_window = hwnd; @@ -781,59 +843,59 @@ ShowSettingsDialog() return; } - /* General tab */ - psp[page_number].dwSize = sizeof(PROPSHEETPAGE); - psp[page_number].dwFlags = PSP_DLGINDIRECT; - psp[page_number].hInstance = o.hInstance; - psp[page_number].pResource = LocalizedDialogResource(ID_DLG_GENERAL); - psp[page_number].pfnDlgProc = GeneralSettingsDlgProc; - psp[page_number].lParam = 0; - psp[page_number].pfnCallback = NULL; - ++page_number; - - /* Proxy tab */ - psp[page_number].dwSize = sizeof(PROPSHEETPAGE); - psp[page_number].dwFlags = PSP_DLGINDIRECT; - psp[page_number].hInstance = o.hInstance; - psp[page_number].pResource = LocalizedDialogResource(ID_DLG_PROXY); - psp[page_number].pfnDlgProc = ProxySettingsDialogFunc; - psp[page_number].lParam = 0; - psp[page_number].pfnCallback = NULL; - ++page_number; - - /* Advanced tab */ - psp[page_number].dwSize = sizeof(PROPSHEETPAGE); - psp[page_number].dwFlags = PSP_DLGINDIRECT; - psp[page_number].hInstance = o.hInstance; - psp[page_number].pResource = LocalizedDialogResource(ID_DLG_ADVANCED); - psp[page_number].pfnDlgProc = AdvancedSettingsDlgProc; - psp[page_number].lParam = 0; - psp[page_number].pfnCallback = NULL; - ++page_number; - - /* About tab */ - psp[page_number].dwSize = sizeof(PROPSHEETPAGE); - psp[page_number].dwFlags = PSP_DLGINDIRECT; - psp[page_number].hInstance = o.hInstance; - psp[page_number].pResource = LocalizedDialogResource(ID_DLG_ABOUT); - psp[page_number].pfnDlgProc = AboutDialogFunc; - psp[page_number].lParam = 0; - psp[page_number].pfnCallback = NULL; - ++page_number; - - PROPSHEETHEADER psh; - psh.dwSize = sizeof(PROPSHEETHEADER); - psh.dwFlags = PSH_USEHICON | PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW | PSH_NOCONTEXTHELP | PSH_USECALLBACK; - psh.hwndParent = o.hWnd; - psh.hInstance = o.hInstance; - psh.hIcon = LoadLocalizedIcon(ID_ICO_APP); - psh.pszCaption = LoadLocalizedString(IDS_SETTINGS_CAPTION); - psh.nPages = page_number; - psh.nStartPage = 0; - psh.ppsp = (LPCPROPSHEETPAGE) &psp; - psh.pfnCallback = SettingsPsCallback; - - PropertySheet(&psh); + /* General tab */ + psp[page_number].dwSize = sizeof(PROPSHEETPAGE); + psp[page_number].dwFlags = PSP_DLGINDIRECT; + psp[page_number].hInstance = o.hInstance; + psp[page_number].pResource = LocalizedDialogResource(ID_DLG_GENERAL); + psp[page_number].pfnDlgProc = GeneralSettingsDlgProc; + psp[page_number].lParam = 0; + psp[page_number].pfnCallback = NULL; + ++page_number; + + /* Proxy tab */ + psp[page_number].dwSize = sizeof(PROPSHEETPAGE); + psp[page_number].dwFlags = PSP_DLGINDIRECT; + psp[page_number].hInstance = o.hInstance; + psp[page_number].pResource = LocalizedDialogResource(ID_DLG_PROXY); + psp[page_number].pfnDlgProc = ProxySettingsDialogFunc; + psp[page_number].lParam = 0; + psp[page_number].pfnCallback = NULL; + ++page_number; + + /* Advanced tab */ + psp[page_number].dwSize = sizeof(PROPSHEETPAGE); + psp[page_number].dwFlags = PSP_DLGINDIRECT; + psp[page_number].hInstance = o.hInstance; + psp[page_number].pResource = LocalizedDialogResource(ID_DLG_ADVANCED); + psp[page_number].pfnDlgProc = AdvancedSettingsDlgProc; + psp[page_number].lParam = 0; + psp[page_number].pfnCallback = NULL; + ++page_number; + + /* About tab */ + psp[page_number].dwSize = sizeof(PROPSHEETPAGE); + psp[page_number].dwFlags = PSP_DLGINDIRECT; + psp[page_number].hInstance = o.hInstance; + psp[page_number].pResource = LocalizedDialogResource(ID_DLG_ABOUT); + psp[page_number].pfnDlgProc = AboutDialogFunc; + psp[page_number].lParam = 0; + psp[page_number].pfnCallback = NULL; + ++page_number; + + PROPSHEETHEADER psh; + psh.dwSize = sizeof(PROPSHEETHEADER); + psh.dwFlags = PSH_USEHICON | PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW | PSH_NOCONTEXTHELP | PSH_USECALLBACK; + psh.hwndParent = o.hWnd; + psh.hInstance = o.hInstance; + psh.hIcon = LoadLocalizedIcon(ID_ICO_APP); + psh.pszCaption = LoadLocalizedString(IDS_SETTINGS_CAPTION); + psh.nPages = page_number; + psh.nStartPage = 0; + psh.ppsp = (LPCPROPSHEETPAGE) &psp; + psh.pfnCallback = SettingsPsCallback; + + PropertySheet(&psh); } @@ -897,50 +959,52 @@ ImportConfigFileFromDisk() } #ifdef DEBUG -void PrintDebugMsg(TCHAR *msg) +void +PrintDebugMsg(TCHAR *msg) { - time_t log_time; - struct tm *time_struct; - TCHAR date[30]; - - log_time = time(NULL); - time_struct = localtime(&log_time); - _sntprintf(date, _countof(date), _T("%d-%.2d-%.2d %.2d:%.2d:%.2d"), - time_struct->tm_year + 1900, - time_struct->tm_mon + 1, - time_struct->tm_mday, - time_struct->tm_hour, - time_struct->tm_min, - time_struct->tm_sec); - - _ftprintf(o.debug_fp, _T("%ls %ls\n"), date, msg); - fflush(o.debug_fp); + time_t log_time; + struct tm *time_struct; + TCHAR date[30]; + + log_time = time(NULL); + time_struct = localtime(&log_time); + _sntprintf(date, _countof(date), _T("%d-%.2d-%.2d %.2d:%.2d:%.2d"), + time_struct->tm_year + 1900, + time_struct->tm_mon + 1, + time_struct->tm_mday, + time_struct->tm_hour, + time_struct->tm_min, + time_struct->tm_sec); + + _ftprintf(o.debug_fp, _T("%ls %ls\n"), date, msg); + fflush(o.debug_fp); } -#endif +#endif /* ifdef DEBUG */ -#define PACKVERSION(major,minor) MAKELONG(minor,major) -DWORD GetDllVersion(LPCTSTR lpszDllName) +#define PACKVERSION(major, minor) MAKELONG(minor, major) +DWORD +GetDllVersion(LPCTSTR lpszDllName) { HINSTANCE hinstDll; DWORD dwVersion = 0; /* For security purposes, LoadLibrary should be provided with a - fully-qualified path to the DLL. The lpszDllName variable should be - tested to ensure that it is a fully qualified path before it is used. */ + * fully-qualified path to the DLL. The lpszDllName variable should be + * tested to ensure that it is a fully qualified path before it is used. */ hinstDll = LoadLibrary(lpszDllName); - if(hinstDll) + if (hinstDll) { DLLGETVERSIONPROC pDllGetVersion; pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, - "DllGetVersion"); + "DllGetVersion"); /* Because some DLLs might not implement this function, you - must test for it explicitly. Depending on the particular - DLL, the lack of a DllGetVersion function can be a useful - indicator of the version. */ + * must test for it explicitly. Depending on the particular + * DLL, the lack of a DllGetVersion function can be a useful + * indicator of the version. */ - if(pDllGetVersion) + if (pDllGetVersion) { DLLVERSIONINFO dvi; HRESULT hr; @@ -950,9 +1014,9 @@ DWORD GetDllVersion(LPCTSTR lpszDllName) hr = (*pDllGetVersion)(&dvi); - if(SUCCEEDED(hr)) + if (SUCCEEDED(hr)) { - dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion); + dwVersion = PACKVERSION(dvi.dwMajorVersion, dvi.dwMinorVersion); } } @@ -965,8 +1029,10 @@ void ErrorExit(int exit_code, const wchar_t *msg) { if (msg) + { MessageBoxExW(NULL, msg, TEXT(PACKAGE_NAME), MB_OK | MB_SETFOREGROUND | MB_ICONERROR | MBOX_RTL_FLAGS, GetGUILanguage()); + } if (o.hWnd) { StopAllOpenVPN(true); @@ -1019,8 +1085,11 @@ SaveAutoRestartList() } len++; /* for double nul termination */ - if (len == 1) len++; /* two nuls for empty string */ + if (len == 1) + { + len++; /* two nuls for empty string */ + } /* Make a double nul terminated list of active connections */ wchar_t *list = calloc(len, sizeof(wchar_t)); if (!list) @@ -1040,7 +1109,7 @@ SaveAutoRestartList() /* Save the list in registry for auto-connect on restart */ LSTATUS status = RegSetKeyValueW(HKEY_CURRENT_USER, GUI_REGKEY_HKCU, L"auto_restart_list", - REG_MULTI_SZ, list, (DWORD) len*sizeof(wchar_t)); + REG_MULTI_SZ, list, (DWORD) len*sizeof(wchar_t)); if (status != ERROR_SUCCESS) { MsgToEventLog(EVENTLOG_ERROR_TYPE, L"RegSetKeyValue returned error: status = %lu", status); @@ -1060,7 +1129,7 @@ LoadAutoRestartList() DWORD len = 0; LSTATUS status = RegGetValueW(HKEY_CURRENT_USER, GUI_REGKEY_HKCU, L"auto_restart_list", - RRF_RT_REG_MULTI_SZ, NULL, NULL, &len); + RRF_RT_REG_MULTI_SZ, NULL, NULL, &len); if (status != ERROR_SUCCESS || len == 0) { return; @@ -1074,7 +1143,7 @@ LoadAutoRestartList() } status = RegGetValueW(HKEY_CURRENT_USER, GUI_REGKEY_HKCU, L"auto_restart_list", - RRF_RT_REG_MULTI_SZ, NULL, list, &len); + RRF_RT_REG_MULTI_SZ, NULL, list, &len); if (status != ERROR_SUCCESS) { MsgToEventLog(EVENTLOG_ERROR_TYPE, L"Error reading state from registry"); diff --git a/main.h b/main.h index 2ba4108..69ac714 100644 --- a/main.h +++ b/main.h @@ -28,16 +28,16 @@ #include /* Define this to enable DEBUG build */ -//#define DEBUG -#define DEBUG_FILE L"C:\\windows\\temp\\openvpngui_debug.txt" +/*#define DEBUG */ +#define DEBUG_FILE L"C:\\windows\\temp\\openvpngui_debug.txt" /* Registry key for User Settings */ -#define GUI_REGKEY_HKCU _T("Software\\OpenVPN-GUI") +#define GUI_REGKEY_HKCU _T("Software\\OpenVPN-GUI") #define MAX_LOG_LENGTH 1024/* Max number of characters per log line */ -#define MAX_LOG_LINES 500 /* Max number of lines in LogWindow */ -#define DEL_LOG_LINES 10 /* Number of lines to delete from LogWindow */ -#define USAGE_BUF_SIZE 3000 /* Size of buffer used to display usage message */ +#define MAX_LOG_LINES 500 /* Max number of lines in LogWindow */ +#define DEL_LOG_LINES 10 /* Number of lines to delete from LogWindow */ +#define USAGE_BUF_SIZE 3000 /* Size of buffer used to display usage message */ /* Authorized group who can use any options and config locations */ #define OVPN_ADMIN_GROUP TEXT("OpenVPN Administrators") /* May be reset in registry */ @@ -78,11 +78,11 @@ #define NORETURN __attribute__ ((noreturn)) #endif -#define PACKVERSION(major,minor) MAKELONG(minor,major) +#define PACKVERSION(major, minor) MAKELONG(minor, major) struct security_attributes { - SECURITY_ATTRIBUTES sa; - SECURITY_DESCRIPTOR sd; + SECURITY_ATTRIBUTES sa; + SECURITY_DESCRIPTOR sd; }; /* clear an object */ @@ -90,9 +90,9 @@ struct security_attributes /* _sntprintf with guaranteed \0 termination */ #define _sntprintf_0(buf, ...) \ - do { \ - __sntprintf_0(buf, _countof(buf), __VA_ARGS__); \ - } while(0); + do { \ + __sntprintf_0(buf, _countof(buf), __VA_ARGS__); \ + } while(0); static inline int __sntprintf_0(TCHAR *buf, size_t size, TCHAR *format, ...) @@ -108,9 +108,9 @@ __sntprintf_0(TCHAR *buf, size_t size, TCHAR *format, ...) /* _snprintf with guaranteed \0 termination */ #define _snprintf_0(buf, ...) \ - do { \ - __snprintf_0(buf, sizeof(buf), __VA_ARGS__); \ - } while(0); + do { \ + __snprintf_0(buf, sizeof(buf), __VA_ARGS__); \ + } while(0); static inline int __snprintf_0(char *buf, size_t size, char *format, ...) { @@ -126,14 +126,15 @@ __snprintf_0(char *buf, size_t size, char *format, ...) #ifdef DEBUG /* Print Debug Message */ #define PrintDebug(...) \ - do { \ - TCHAR x_msg[256]; \ - _sntprintf_0(x_msg, __VA_ARGS__); \ - PrintDebugMsg(x_msg); \ - } while(0) + do { \ + TCHAR x_msg[256]; \ + _sntprintf_0(x_msg, __VA_ARGS__); \ + PrintDebugMsg(x_msg); \ + } while(0) void PrintDebugMsg(TCHAR *msg); -#else + +#else /* ifdef DEBUG */ #define PrintDebug(...) do { } while(0) #endif @@ -141,4 +142,4 @@ DWORD GetDllVersion(LPCTSTR lpszDllName); void ErrorExit(int exit_code, const wchar_t *msg); -#endif +#endif /* ifndef MAIN_H */ diff --git a/manage.c b/manage.c index afa5e0c..5ad56ce 100644 --- a/manage.c +++ b/manage.c @@ -63,18 +63,22 @@ OpenManagement(connection_t *c) { WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) + { return FALSE; + } c->manage.connected = 0; c->manage.sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (c->manage.sk == INVALID_SOCKET) { - WSACleanup (); + WSACleanup(); return FALSE; } if (WSAAsyncSelect(c->manage.sk, c->hwndStatus, WM_MANAGEMENT, - FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE) != 0) + FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE) != 0) + { return FALSE; + } connect(c->manage.sk, (SOCKADDR *)&c->manage.skaddr, sizeof(c->manage.skaddr)); c->manage.timeout = time(NULL) + max_connect_time; @@ -92,14 +96,20 @@ SendCommand(connection_t *c) int res; mgmt_cmd_t *cmd = c->manage.cmd_queue; if (cmd == NULL || cmd->size == 0) + { return; + } res = send(c->manage.sk, cmd->command, cmd->size, 0); if (res < 1) + { return; + } if (res != cmd->size) + { memmove(cmd->command, cmd->command + res, cmd->size - res); + } cmd->size -= res; } @@ -113,7 +123,9 @@ ManagementCommand(connection_t *c, char *command, mgmt_msg_func handler, mgmt_cm { mgmt_cmd_t *cmd = calloc(1, sizeof(*cmd)); if (cmd == NULL) + { return FALSE; + } cmd->size = strlen(command) + 1; cmd->command = malloc(cmd->size); @@ -141,7 +153,9 @@ ManagementCommand(connection_t *c, char *command, mgmt_msg_func handler, mgmt_cm } if (c->manage.cmd_queue == cmd) + { SendCommand(c); + } return TRUE; } @@ -155,7 +169,9 @@ UnqueueCommand(connection_t *c) { mgmt_cmd_t *cmd = c->manage.cmd_queue; if (!cmd) + { return FALSE; + } /* Wipe command as it may contain passwords */ memset(cmd->command, 'x', cmd->size); @@ -197,241 +213,281 @@ OnManagement(SOCKET sk, LPARAM lParam) connection_t *c = GetConnByManagement(sk); if (c == NULL) + { return; + } switch (WSAGETSELECTEVENT(lParam)) { - case FD_CONNECT: - if (WSAGETSELECTERROR(lParam)) - { - /* keep trying for connections with persistent daemons */ - if (c->flags & FLAG_DAEMON_PERSISTENT - || time(NULL) < c->manage.timeout) + case FD_CONNECT: + if (WSAGETSELECTERROR(lParam)) { - /* show a message on status window */ - if (rtmsg_handler[log_] && (c->flags & FLAG_DAEMON_PERSISTENT)) + /* keep trying for connections with persistent daemons */ + if (c->flags & FLAG_DAEMON_PERSISTENT + || time(NULL) < c->manage.timeout) { - char buf[256]; - _snprintf_0(buf, "%lld,W,Waiting for the management interface to come up", - (long long)time(NULL)) - rtmsg_handler[log_](c, buf); + /* show a message on status window */ + if (rtmsg_handler[log_] && (c->flags & FLAG_DAEMON_PERSISTENT)) + { + char buf[256]; + _snprintf_0(buf, "%lld,W,Waiting for the management interface to come up", + (long long)time(NULL)) + rtmsg_handler[log_](c, buf); + } + + connect(c->manage.sk, (SOCKADDR *)&c->manage.skaddr, sizeof(c->manage.skaddr)); + } + else + { + /* Connection to MI timed out. */ + CloseManagement(c); + if (c->state != disconnected) + { + rtmsg_handler[timeout_](c, ""); + } } - - connect(c->manage.sk, (SOCKADDR *)&c->manage.skaddr, sizeof(c->manage.skaddr)); } else { - /* Connection to MI timed out. */ - CloseManagement (c); - if (c->state != disconnected) - rtmsg_handler[timeout_](c, ""); + c->manage.connected = 1; } - } - else - c->manage.connected = 1; - break; - - case FD_READ: - if (ioctlsocket(c->manage.sk, FIONREAD, &data_size) != 0 - || data_size == 0) - return; - - data = malloc(c->manage.saved_size + data_size); - if (data == NULL) - return; - - res = recv(c->manage.sk, data + c->manage.saved_size, data_size, 0); - if (res != (int) data_size) - { - free(data); - return; - } - - /* Copy previously saved management data */ - if (c->manage.saved_size) - { - memcpy(data, c->manage.saved_data, c->manage.saved_size); - data_size += c->manage.saved_size; - free(c->manage.saved_data); - c->manage.saved_data = NULL; - c->manage.saved_size = 0; - } + break; - offset = 0; - while (offset < data_size) - { - char *pos; - char *line = data + offset; - size_t line_size = data_size - offset; - BOOL passwd_request = false; - const char *passwd_prompt = "ENTER PASSWORD:"; - - if (line_size >= strlen(passwd_prompt) - && memcmp(line, passwd_prompt, strlen(passwd_prompt)) == 0) - { - pos = memchr(line, ':', line_size); - passwd_request = true; - } - else + case FD_READ: + if (ioctlsocket(c->manage.sk, FIONREAD, &data_size) != 0 + || data_size == 0) { - pos = memchr(line, '\n', line_size); + return; } - if (pos == NULL) + data = malloc(c->manage.saved_size + data_size); + if (data == NULL) { - c->manage.saved_data = malloc(line_size); - if (c->manage.saved_data) - { - c->manage.saved_size = line_size; - memcpy(c->manage.saved_data, line, c->manage.saved_size); - } - break; + return; } - offset += (pos - line) + 1; - - /* Reply to a management password request */ - if (*c->manage.password && passwd_request) + res = recv(c->manage.sk, data + c->manage.saved_size, data_size, 0); + if (res != (int) data_size) { - ManagementCommand(c, c->manage.password, NULL, regular); - SecureZeroMemory(c->manage.password, sizeof(c->manage.password)); - - continue; + free(data); + return; } - if (!*c->manage.password && passwd_request) + /* Copy previously saved management data */ + if (c->manage.saved_size) { - /* either we don't have a password or we used it and didn't match */ - MsgToEventLog(EVENTLOG_WARNING_TYPE, L"%ls: management password mismatch", - c->config_name); - c->state = disconnecting; - CloseManagement (c); - rtmsg_handler[stop_](c, ""); - - continue; + memcpy(data, c->manage.saved_data, c->manage.saved_size); + data_size += c->manage.saved_size; + free(c->manage.saved_data); + c->manage.saved_data = NULL; + c->manage.saved_size = 0; } - /* Handle regular management interface output */ - line[pos - line - 1] = '\0'; - if (line[0] == '>') + offset = 0; + while (offset < data_size) { - /* Real time notifications */ - pos = line + 1; - if (strncmp(pos, "LOG:", 4) == 0) - { - if (rtmsg_handler[log_]) - rtmsg_handler[log_](c, pos + 4); - } - else if (strncmp(pos, "STATE:", 6) == 0) - { - if (rtmsg_handler[state_]) - rtmsg_handler[state_](c, pos + 6); - } - else if (strncmp(pos, "HOLD:", 5) == 0) + char *pos; + char *line = data + offset; + size_t line_size = data_size - offset; + BOOL passwd_request = false; + const char *passwd_prompt = "ENTER PASSWORD:"; + + if (line_size >= strlen(passwd_prompt) + && memcmp(line, passwd_prompt, strlen(passwd_prompt)) == 0) { - if (rtmsg_handler[hold_]) - rtmsg_handler[hold_](c, pos + 5); + pos = memchr(line, ':', line_size); + passwd_request = true; } - else if (strncmp(pos, "PASSWORD:", 9) == 0) + else { - if (rtmsg_handler[password_]) - rtmsg_handler[password_](c, pos + 9); + pos = memchr(line, '\n', line_size); } - else if (strncmp(pos, "PROXY:", 6) == 0) - { - if (rtmsg_handler[proxy_]) - rtmsg_handler[proxy_](c, pos + 6); - } - else if (strncmp(pos, "INFO:", 5) == 0) - { - /* delay until management interface accepts input */ - /* use real sleep here, since WM_MANAGEMENT might arrive before management is ready */ - Sleep(100); - c->manage.connected = 2; - if (rtmsg_handler[ready_]) - rtmsg_handler[ready_](c, pos + 5); - } - else if (strncmp(pos, "NEED-OK:", 8) == 0) - { - if (rtmsg_handler[needok_]) - rtmsg_handler[needok_](c, pos + 8); - } - else if (strncmp(pos, "NEED-STR:", 9) == 0) + + if (pos == NULL) { - if (rtmsg_handler[needstr_]) - rtmsg_handler[needstr_](c, pos + 9); + c->manage.saved_data = malloc(line_size); + if (c->manage.saved_data) + { + c->manage.saved_size = line_size; + memcpy(c->manage.saved_data, line, c->manage.saved_size); + } + break; } - else if (strncmp(pos, "ECHO:", 5) == 0) + + offset += (pos - line) + 1; + + /* Reply to a management password request */ + if (*c->manage.password && passwd_request) { - if (rtmsg_handler[echo_]) - rtmsg_handler[echo_](c, pos + 5); + ManagementCommand(c, c->manage.password, NULL, regular); + SecureZeroMemory(c->manage.password, sizeof(c->manage.password)); + + continue; } - else if (strncmp(pos, "BYTECOUNT:", 10) == 0) + + if (!*c->manage.password && passwd_request) { - if (rtmsg_handler[bytecount_]) - rtmsg_handler[bytecount_](c, pos + 10); + /* either we don't have a password or we used it and didn't match */ + MsgToEventLog(EVENTLOG_WARNING_TYPE, L"%ls: management password mismatch", + c->config_name); + c->state = disconnecting; + CloseManagement(c); + rtmsg_handler[stop_](c, ""); + + continue; } - else if (strncmp(pos, "INFOMSG:", 8) == 0) + + /* Handle regular management interface output */ + line[pos - line - 1] = '\0'; + if (line[0] == '>') { - if (rtmsg_handler[infomsg_]) - rtmsg_handler[infomsg_](c, pos + 8); + /* Real time notifications */ + pos = line + 1; + if (strncmp(pos, "LOG:", 4) == 0) + { + if (rtmsg_handler[log_]) + { + rtmsg_handler[log_](c, pos + 4); + } + } + else if (strncmp(pos, "STATE:", 6) == 0) + { + if (rtmsg_handler[state_]) + { + rtmsg_handler[state_](c, pos + 6); + } + } + else if (strncmp(pos, "HOLD:", 5) == 0) + { + if (rtmsg_handler[hold_]) + { + rtmsg_handler[hold_](c, pos + 5); + } + } + else if (strncmp(pos, "PASSWORD:", 9) == 0) + { + if (rtmsg_handler[password_]) + { + rtmsg_handler[password_](c, pos + 9); + } + } + else if (strncmp(pos, "PROXY:", 6) == 0) + { + if (rtmsg_handler[proxy_]) + { + rtmsg_handler[proxy_](c, pos + 6); + } + } + else if (strncmp(pos, "INFO:", 5) == 0) + { + /* delay until management interface accepts input */ + /* use real sleep here, since WM_MANAGEMENT might arrive before management is ready */ + Sleep(100); + c->manage.connected = 2; + if (rtmsg_handler[ready_]) + { + rtmsg_handler[ready_](c, pos + 5); + } + } + else if (strncmp(pos, "NEED-OK:", 8) == 0) + { + if (rtmsg_handler[needok_]) + { + rtmsg_handler[needok_](c, pos + 8); + } + } + else if (strncmp(pos, "NEED-STR:", 9) == 0) + { + if (rtmsg_handler[needstr_]) + { + rtmsg_handler[needstr_](c, pos + 9); + } + } + else if (strncmp(pos, "ECHO:", 5) == 0) + { + if (rtmsg_handler[echo_]) + { + rtmsg_handler[echo_](c, pos + 5); + } + } + else if (strncmp(pos, "BYTECOUNT:", 10) == 0) + { + if (rtmsg_handler[bytecount_]) + { + rtmsg_handler[bytecount_](c, pos + 10); + } + } + else if (strncmp(pos, "INFOMSG:", 8) == 0) + { + if (rtmsg_handler[infomsg_]) + { + rtmsg_handler[infomsg_](c, pos + 8); + } + } + else if (strncmp(pos, "PKCS11ID", 8) == 0 + && c->manage.cmd_queue) + { + /* This is not a real-time message, but unfortunately implemented + * in the core as one. Work around by handling the response here. + */ + mgmt_cmd_t *cmd = c->manage.cmd_queue; + if (cmd->handler) + { + cmd->handler(c, line); + } + UnqueueCommand(c); + } } - else if (strncmp(pos, "PKCS11ID", 8) == 0 - && c->manage.cmd_queue) + else if (c->manage.cmd_queue) { - /* This is not a real-time message, but unfortunately implemented - * in the core as one. Work around by handling the response here. - */ + /* Response to commands */ mgmt_cmd_t *cmd = c->manage.cmd_queue; - if (cmd->handler) + if (strncmp(line, "SUCCESS:", 8) == 0) + { + if (cmd->handler) + { + cmd->handler(c, line + 9); + } + UnqueueCommand(c); + } + else if (strncmp(line, "ERROR:", 6) == 0) + { + /* Response sent to management is not processed. Log an error in status window */ + char buf[256]; + _snprintf_0(buf, "%lld,N,Previous command sent to management failed: %s", + (long long)time(NULL), line) + rtmsg_handler[log_](c, buf); + + if (cmd->handler) + { + cmd->handler(c, NULL); + } + UnqueueCommand(c); + } + else if (strcmp(line, "END") == 0) + { + UnqueueCommand(c); + } + else if (cmd->handler) + { cmd->handler(c, line); - UnqueueCommand(c); - } - } - else if (c->manage.cmd_queue) - { - /* Response to commands */ - mgmt_cmd_t *cmd = c->manage.cmd_queue; - if (strncmp(line, "SUCCESS:", 8) == 0) - { - if (cmd->handler) - cmd->handler(c, line + 9); - UnqueueCommand(c); - } - else if (strncmp(line, "ERROR:", 6) == 0) - { - /* Response sent to management is not processed. Log an error in status window */ - char buf[256]; - _snprintf_0(buf, "%lld,N,Previous command sent to management failed: %s", - (long long)time(NULL), line) - rtmsg_handler[log_](c, buf); - - if (cmd->handler) - cmd->handler(c, NULL); - UnqueueCommand(c); - } - else if (strcmp(line, "END") == 0) - { - UnqueueCommand(c); - } - else if (cmd->handler) - { - cmd->handler(c, line); + } } } - } - free(data); - break; + free(data); + break; - case FD_WRITE: - SendCommand(c); - break; + case FD_WRITE: + SendCommand(c); + break; - case FD_CLOSE: - CloseManagement (c); - if (rtmsg_handler[stop_]) - rtmsg_handler[stop_](c, ""); - break; + case FD_CLOSE: + CloseManagement(c); + if (rtmsg_handler[stop_]) + { + rtmsg_handler[stop_](c, ""); + } + break; } } @@ -450,7 +506,8 @@ CloseManagement(connection_t *c) c->manage.sk = INVALID_SOCKET; c->manage.connected = 0; while (UnqueueCommand(c)) - ; + { + } WSACleanup(); } } diff --git a/manage.h b/manage.h index 7c9dba4..74739bb 100644 --- a/manage.h +++ b/manage.h @@ -64,10 +64,13 @@ typedef struct mgmt_cmd { void InitManagement(const mgmt_rtmsg_handler *handler); + BOOL OpenManagement(connection_t *); + BOOL ManagementCommand(connection_t *, char *, mgmt_msg_func, mgmt_cmd_type); void OnManagement(SOCKET, LPARAM); + void CloseManagement(connection_t *); -#endif +#endif /* ifndef MANAGE_H */ diff --git a/misc.c b/misc.c index e9ff670..37d0cb1 100644 --- a/misc.c +++ b/misc.c @@ -57,27 +57,29 @@ Base64Encode(const char *input, int input_len, char **output) if (input_len == 0) { /* set output to empty string -- matches the behavior in openvpn */ - *output = calloc (1, sizeof(char)); + *output = calloc(1, sizeof(char)); return TRUE; } if (!CryptBinaryToStringA((const BYTE *) input, (DWORD) input_len, - flags, NULL, &output_len) || output_len == 0) + flags, NULL, &output_len) || output_len == 0) { #ifdef DEBUG - PrintDebug (L"Error in CryptBinaryToStringA: input = '%.*hs'", input_len, input); + PrintDebug(L"Error in CryptBinaryToStringA: input = '%.*hs'", input_len, input); #endif *output = NULL; return FALSE; } *output = (char *)malloc(output_len); if (*output == NULL) + { return FALSE; + } if (!CryptBinaryToStringA((const BYTE *) input, (DWORD) input_len, - flags, *output, &output_len)) + flags, *output, &output_len)) { #ifdef DEBUG - PrintDebug (L"Error in CryptBinaryToStringA: input = '%.*hs'", input_len, input); + PrintDebug(L"Error in CryptBinaryToStringA: input = '%.*hs'", input_len, input); #endif free(*output); *output = NULL; @@ -100,7 +102,7 @@ Base64Decode(const char *input, char **output) { DWORD len; - PrintDebug (L"decoding %hs", input); + PrintDebug(L"decoding %hs", input); if (!CryptStringToBinaryA(input, 0, CRYPT_STRING_BASE64_ANY, NULL, &len, NULL, NULL) || len == 0) { @@ -110,10 +112,12 @@ Base64Decode(const char *input, char **output) *output = malloc(len + 1); if (*output == NULL) + { return -1; + } if (!CryptStringToBinaryA(input, 0, - CRYPT_STRING_BASE64, (BYTE *) *output, &len, NULL, NULL)) + CRYPT_STRING_BASE64, (BYTE *) *output, &len, NULL, NULL)) { free(*output); *output = NULL; @@ -122,7 +126,7 @@ Base64Decode(const char *input, char **output) /* NUL terminate output */ (*output)[len] = '\0'; - PrintDebug (L"Decoded output %hs", *output); + PrintDebug(L"Decoded output %hs", *output); return len; } @@ -140,19 +144,27 @@ GetDlgItemTextUtf8(HWND hDlg, int id, LPSTR *str, int *len) ucs2_len = GetWindowTextLength(GetDlgItem(hDlg, id)) + 1; if (ucs2_len == 1) + { 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); @@ -255,7 +267,7 @@ out: * Generate a management command from double user inputs and send it */ BOOL -ManagementCommandFromTwoInputsBase64(connection_t *c, LPCSTR fmt, HWND hDlg,int id, int id2) +ManagementCommandFromTwoInputsBase64(connection_t *c, LPCSTR fmt, HWND hDlg, int id, int id2) { BOOL retval = FALSE; LPSTR input, input2, input_b64, input2_b64, cmd; @@ -268,9 +280,13 @@ ManagementCommandFromTwoInputsBase64(connection_t *c, LPCSTR fmt, HWND hDlg,int GetDlgItemTextUtf8(hDlg, id2, &input2, &input2_len); if (!Base64Encode(input, input_len, &input_b64)) + { goto out; + } if (!Base64Encode(input2, input2_len, &input2_b64)) + { goto out; + } cmd_len = strlen(input_b64) + strlen(input2_b64) + strlen(fmt); cmd = malloc(cmd_len); @@ -284,9 +300,13 @@ ManagementCommandFromTwoInputsBase64(connection_t *c, LPCSTR fmt, HWND hDlg,int out: /* Clear buffers with potentially secret content */ if (input_b64) + { memset(input_b64, 0, strlen(input_b64)); + } if (input2_b64) + { memset(input2_b64, 0, strlen(input2_b64)); + } free(input_b64); free(input2_b64); @@ -310,7 +330,7 @@ out: * Generate a management command from base64-encoded user inputs and send it */ BOOL -ManagementCommandFromInputBase64(connection_t* c, LPCSTR fmt, HWND hDlg, int id) +ManagementCommandFromInputBase64(connection_t *c, LPCSTR fmt, HWND hDlg, int id) { BOOL retval = FALSE; LPSTR input, input_b64, cmd; @@ -321,7 +341,9 @@ ManagementCommandFromInputBase64(connection_t* c, LPCSTR fmt, HWND hDlg, int id) GetDlgItemTextUtf8(hDlg, id, &input, &input_len); if (!Base64Encode(input, input_len, &input_b64)) + { goto out; + } cmd_len = strlen(input_b64) + strlen(fmt); cmd = malloc(cmd_len); @@ -335,7 +357,9 @@ ManagementCommandFromInputBase64(connection_t* c, LPCSTR fmt, HWND hDlg, int id) out: /* Clear buffers with potentially secret content */ if (input_b64) + { memset(input_b64, 0, strlen(input_b64)); + } free(input_b64); if (input_len) @@ -365,20 +389,26 @@ EnsureDirExists(LPTSTR dir) { LPTSTR pos = _tcsrchr(dir, '\\'); if (pos == NULL) + { return FALSE; + } *pos = '\0'; BOOL ret = EnsureDirExists(dir); *pos = '\\'; if (ret == FALSE) + { return FALSE; + } } else if (error != ERROR_FILE_NOT_FOUND) + { return FALSE; + } /* No error if directory already exists */ return (CreateDirectory(dir, NULL) == TRUE - || GetLastError() == ERROR_ALREADY_EXISTS); + || GetLastError() == ERROR_ALREADY_EXISTS); } return (attr & FILE_ATTRIBUTE_DIRECTORY ? TRUE : FALSE); @@ -425,13 +455,17 @@ ForceForegroundWindow(HWND hWnd) * Set scale factor of windows in pixels. Scale = 100% for dpi = 96 */ void -DpiSetScale(options_t* options, UINT dpix) +DpiSetScale(options_t *options, UINT dpix) { /* scale factor in percentage compared to the reference dpi of 96 */ if (dpix != 0) + { options->dpi_scale = MulDiv(dpix, 100, 96); + } else + { options->dpi_scale = 100; + } PrintDebug(L"DPI scale set to %u", options->dpi_scale); } @@ -442,19 +476,22 @@ DpiSetScale(options_t* options, UINT dpix) * in its SID. Assumes the caller is not impersonating and has access to open its own * process token. */ -BOOL IsUserAdmin(VOID) +BOOL +IsUserAdmin(VOID) { BOOL b; SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY}; PSID AdministratorsGroup; - b = AllocateAndInitializeSid (&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, - &AdministratorsGroup); - if(b) + b = AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, + &AdministratorsGroup); + if (b) { if (!CheckTokenMembership(NULL, AdministratorsGroup, &b)) + { b = FALSE; + } FreeSid(AdministratorsGroup); } @@ -462,15 +499,15 @@ BOOL IsUserAdmin(VOID) } HANDLE -InitSemaphore (WCHAR *name) +InitSemaphore(WCHAR *name) { HANDLE semaphore = NULL; - semaphore = CreateSemaphore (NULL, 1, 1, name); + semaphore = CreateSemaphore(NULL, 1, 1, name); if (!semaphore) { - MessageBoxW (NULL, L"Error creating semaphore", TEXT(PACKAGE_NAME), MB_OK); + MessageBoxW(NULL, L"Error creating semaphore", TEXT(PACKAGE_NAME), MB_OK); #ifdef DEBUG - PrintDebug (L"InitSemaphore: CreateSemaphore failed [error = %lu]", GetLastError()); + PrintDebug(L"InitSemaphore: CreateSemaphore failed [error = %lu]", GetLastError()); #endif } return semaphore; @@ -488,17 +525,17 @@ CloseSemaphore(HANDLE sem) /* Check access rights on an existing file */ BOOL -CheckFileAccess (const TCHAR *path, int access) +CheckFileAccess(const TCHAR *path, int access) { HANDLE h; bool ret = FALSE; - h = CreateFile (path, access, FILE_SHARE_READ, NULL, OPEN_EXISTING, + h = CreateFile(path, access, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if ( h != INVALID_HANDLE_VALUE ) + if (h != INVALID_HANDLE_VALUE) { ret = TRUE; - CloseHandle (h); + CloseHandle(h); } return ret; @@ -514,17 +551,23 @@ WidenEx(UINT codepage, const char *str) { WCHAR *wstr = NULL; if (!str) + { return wstr; + } int nch = MultiByteToWideChar(codepage, 0, str, -1, NULL, 0); if (nch > 0) + { wstr = malloc(sizeof(WCHAR) * nch); + } if (wstr) + { nch = MultiByteToWideChar(codepage, 0, str, -1, wstr, nch); + } if (nch == 0 && wstr) { - free (wstr); + free(wstr); wstr = NULL; } @@ -545,7 +588,9 @@ BOOL validate_input(const WCHAR *input, const WCHAR *exclude) { if (!exclude) + { exclude = L"\n"; + } return (wcspbrk(input, exclude) == NULL); } @@ -556,17 +601,27 @@ wcs_concat2(WCHAR *dest, int len, const WCHAR *src1, const WCHAR *src2, const WC int n = 0; if (!dest || len == 0) + { return; + } if (src1 && src2 && src1[0] && src2[0]) + { n = swprintf(dest, len, L"%ls%ls%ls", src1, sep, src2); + } else if (src1 && src1[0]) + { n = swprintf(dest, len, L"%ls", src1); + } else if (src2 && src2[0]) + { n = swprintf(dest, len, L"%ls", src2); + } if (n < 0 || n >= len) /*swprintf failed */ + { n = 0; + } dest[n] = L'\0'; } @@ -594,7 +649,9 @@ url_decode(const char *src) char *o; if (!out) + { return NULL; + } for (o = out; *s; o++) { @@ -618,7 +675,9 @@ md_init(md_ctx *ctx, ALG_ID hash_type) DWORD status = 0; if (!CryptAcquireContext(&ctx->prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + { goto err; + } if (!CryptCreateHash(ctx->prov, hash_type, 0, 0, &ctx->hash)) { CryptReleaseContext(ctx->prov, 0); @@ -684,7 +743,7 @@ open_url(const wchar_t *url) extern options_t o; void -ImportConfigFile(const TCHAR* source, bool prompt_user) +ImportConfigFile(const TCHAR *source, bool prompt_user) { TCHAR fileName[MAX_PATH] = _T(""); TCHAR ext[MAX_PATH] = _T(""); @@ -723,7 +782,7 @@ ImportConfigFile(const TCHAR* source, bool prompt_user) { if (prompt_user && ShowLocalizedMsgEx(MB_YESNO|MB_TOPMOST, o.hWnd, TEXT(PACKAGE_NAME), - IDS_NFO_IMPORT_SOURCE, fileName) == IDNO) + IDS_NFO_IMPORT_SOURCE, fileName) == IDNO) { return; } @@ -741,10 +800,10 @@ ImportConfigFile(const TCHAR* source, bool prompt_user) if (!CopyFile(source, destination, no_overwrite)) { - MsgToEventLog(EVENTLOG_ERROR_TYPE, L"Copy file <%ls> to <%ls> failed (error = %lu)", - source, destination, GetLastError()); - ShowLocalizedMsg(IDS_ERR_IMPORT_FAILED, destination); - return; + MsgToEventLog(EVENTLOG_ERROR_TYPE, L"Copy file <%ls> to <%ls> failed (error = %lu)", + source, destination, GetLastError()); + ShowLocalizedMsg(IDS_ERR_IMPORT_FAILED, destination); + return; } ShowTrayBalloon(LoadLocalizedString(IDS_NFO_IMPORT_SUCCESS), fileName); @@ -900,7 +959,9 @@ MsgToEventLog(WORD type, wchar_t *format, ...) { o.event_log = RegisterEventSource(NULL, TEXT(PACKAGE_NAME)); if (!o.event_log) + { return; + } } va_list args; @@ -908,7 +969,10 @@ MsgToEventLog(WORD type, wchar_t *format, ...) int nchar = vswprintf(buf, size-1, format, args); va_end(args); - if (nchar == -1) return; + if (nchar == -1) + { + return; + } buf[size - 1] = '\0'; @@ -954,11 +1018,13 @@ GetPLAPRegistrationStatus(void) wchar_t dllPath[MAX_PATH]; _sntprintf_0(dllPath, L"%ls%ls", o.install_path, L"bin\\libopenvpn_plap.dll"); - if (!CheckFileAccess(dllPath, GENERIC_READ)) { + if (!CheckFileAccess(dllPath, GENERIC_READ)) + { res = -1; } else if (RegOpenKeyExW(HKEY_CLASSES_ROOT, L"CLSID\\"PLAP_CLASSID, 0, KEY_READ, ®key) - == ERROR_SUCCESS) { + == ERROR_SUCCESS) + { res = 1; RegCloseKey(regkey); } @@ -975,19 +1041,24 @@ SetPLAPRegistration(BOOL value) /* Run only if the state has changed */ int plap_status = GetPLAPRegistrationStatus(); - if (plap_status > 0 && (BOOL) plap_status == value) return 0; + if (plap_status > 0 && (BOOL) plap_status == value) + { + return 0; + } - if (value) { + if (value) + { _sntprintf_0( params, L"import \"%ls%ls\"", o.install_path, L"bin\\openvpn-plap-install.reg"); } - else { + else + { _sntprintf_0( params, L"import \"%ls%ls\"", o.install_path, L"bin\\openvpn-plap-uninstall.reg"); } res = RunAsAdmin(cmd, params); if (res != 0) { - ShowLocalizedMsg(value? IDS_ERR_PLAP_REG : IDS_ERR_PLAP_UNREG, res); + ShowLocalizedMsg(value ? IDS_ERR_PLAP_REG : IDS_ERR_PLAP_UNREG, res); } return res; } @@ -1003,7 +1074,7 @@ RunAsAdmin(const WCHAR *cmd, const WCHAR *params) SHELLEXECUTEINFO shinfo; DWORD status = -1; - CLEAR (shinfo); + CLEAR(shinfo); shinfo.cbSize = sizeof(shinfo); shinfo.fMask = SEE_MASK_NOCLOSEPROCESS; shinfo.hwnd = NULL; @@ -1038,7 +1109,7 @@ OVPNMsgWait(DWORD timeout, HWND hdlg) if (MsgWaitForMultipleObjectsEx(0, NULL, end - now, QS_ALLINPUT, MWMO_INPUTAVAILABLE) == WAIT_OBJECT_0) { MSG msg; - while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) { @@ -1069,14 +1140,20 @@ GetRandomPassword(char *buf, size_t len) unsigned i; if (!CryptAcquireContext(&cp, NULL, NULL, PROV_DSS, CRYPT_VERIFYCONTEXT)) + { return FALSE; + } if (!CryptGenRandom(cp, len, (PBYTE) buf)) + { goto out; + } /* Make sure all values are between 0x21 '!' and 0x7e '~' */ for (i = 0; i < len; ++i) + { buf[i] = (buf[i] & 0x5d) + 0x21; + } retval = TRUE; out: diff --git a/misc.h b/misc.h index 2e5f093..7da7dc2 100644 --- a/misc.h +++ b/misc.h @@ -27,30 +27,44 @@ #include "options.h" BOOL ManagementCommandFromInput(connection_t *, LPCSTR, HWND, int); -BOOL ManagementCommandFromTwoInputsBase64(connection_t*, LPCSTR, HWND, int, int); + +BOOL ManagementCommandFromTwoInputsBase64(connection_t *, LPCSTR, HWND, int, int); + BOOL ManagementCommandFromInputBase64(connection_t *, LPCSTR, HWND, int); BOOL EnsureDirExists(LPTSTR); BOOL streq(LPCSTR, LPCSTR); + BOOL strbegins(const char *str, const char *begin); + BOOL wcsbegins(LPCWSTR, LPCWSTR); BOOL ForceForegroundWindow(HWND); -void DpiSetScale(options_t*, UINT dpix); + +void DpiSetScale(options_t *, UINT dpix); BOOL IsUserAdmin(VOID); -HANDLE InitSemaphore (WCHAR *); -BOOL CheckFileAccess (const TCHAR *path, int access); + +HANDLE InitSemaphore(WCHAR *); + +BOOL CheckFileAccess(const TCHAR *path, int access); BOOL Base64Encode(const char *input, int input_len, char **output); + int Base64Decode(const char *input, char **output); + WCHAR *Widen(const char *utf8); + WCHAR *WidenEx(UINT codepage, const char *utf8); + BOOL validate_input(const WCHAR *input, const WCHAR *exclude); + /* Concatenate two wide strings with a separator */ void wcs_concat2(WCHAR *dest, int len, const WCHAR *src1, const WCHAR *src2, const WCHAR *sep); + void CloseSemaphore(HANDLE sem); + /* Close a handle if not null or invalid */ void CloseHandleEx(LPHANDLE h); @@ -61,25 +75,27 @@ char *url_decode(const char *src); /* digest functions */ typedef struct md_ctx { - HCRYPTPROV prov; - HCRYPTHASH hash; + HCRYPTPROV prov; + HCRYPTHASH hash; } md_ctx; DWORD md_init(md_ctx *ctx, ALG_ID hash_type); + DWORD md_update(md_ctx *ctx, const BYTE *data, size_t size); + DWORD md_final(md_ctx *ctx, BYTE *md); /* Open specified http/https URL using ShellExecute. */ BOOL open_url(const wchar_t *url); -void ImportConfigFile(const TCHAR* path, bool prompt_user); +void ImportConfigFile(const TCHAR *path, bool prompt_user); /* * Helper function to convert UCS-2 text from a dialog item to UTF-8. * Caller must free *str if *len != 0. */ BOOL -GetDlgItemTextUtf8(HWND hDlg, int id, LPSTR* str, int* len); +GetDlgItemTextUtf8(HWND hDlg, int id, LPSTR *str, int *len); /* Return escaped copy of a string */ char *escape_string(const char *str); @@ -157,6 +173,7 @@ bool OVPNMsgWait(DWORD timeout, HWND hdlg); bool GetRandomPassword(char *buf, size_t len); void ResetPasswordReveal(HWND edit, HWND btn, WPARAM wParam); + void ChangePasswordVisibility(HWND edit, HWND btn, WPARAM wParam); -#endif +#endif /* ifndef MISC_H */ diff --git a/openvpn-gui-res.h b/openvpn-gui-res.h index 149bac2..41ce3ce 100644 --- a/openvpn-gui-res.h +++ b/openvpn-gui-res.h @@ -409,4 +409,4 @@ /* Timer IDs */ #define IDT_STOP_TIMER 2500 /* Timer used to trigger force termination */ -#endif +#endif /* ifndef OPENVPN_GUI_RES_H */ diff --git a/openvpn.c b/openvpn.c index 5c2e4f5..9cd6527 100644 --- a/openvpn.c +++ b/openvpn.c @@ -67,30 +67,33 @@ extern options_t o; static BOOL TerminateOpenVPN(connection_t *c); + static BOOL LaunchOpenVPN(connection_t *c); const TCHAR *cfgProp = _T("conn"); void -free_auth_param (auth_param_t *param) +free_auth_param(auth_param_t *param) { if (!param) + { return; - free (param->str); - free (param->id); - free (param->user); - free (param->cr_response); - free (param); + } + free(param->str); + free(param->id); + free(param->user); + free(param->cr_response); + free(param); } void -AppendTextToCaption (HANDLE hwnd, const WCHAR *str) +AppendTextToCaption(HANDLE hwnd, const WCHAR *str) { WCHAR old[256]; WCHAR new[256]; - GetWindowTextW (hwnd, old, _countof(old)); - _sntprintf_0 (new, L"%ls (%ls)", old, str); - SetWindowText (hwnd, new); + GetWindowTextW(hwnd, old, _countof(old)); + _sntprintf_0(new, L"%ls (%ls)", old, str); + SetWindowText(hwnd, new); } /* @@ -174,11 +177,15 @@ OnLogLine(connection_t *c, char *line) flags = strchr(line, ',') + 1; if (flags - 1 == NULL) + { return; + } message = strchr(flags, ',') + 1; if (message - 1 == NULL) + { return; + } size_t flag_size = message - flags - 1; /* message is always > flags */ /* Remove lines from log window if it is getting full */ @@ -200,17 +207,20 @@ OnLogLine(connection_t *c, char *line) COLORREF text_clr = 0; if (memchr(flags, 'N', flag_size) || memchr(flags, 'F', flag_size)) + { text_clr = o.clr_error; + } else if (memchr(flags, 'W', flag_size)) + { text_clr = o.clr_warning; + } if (text_clr != 0) { CHARFORMAT cfm = { .cbSize = sizeof(CHARFORMAT), .dwMask = CFM_COLOR|CFM_BOLD, .dwEffects = 0, - .crTextColor = text_clr, - }; + .crTextColor = text_clr, }; SendMessage(logWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cfm); } @@ -234,7 +244,9 @@ parse_assigned_ip(connection_t *c, const char *msg) /* extract local ipv4 address if available*/ sep = strchr(msg, ','); if (sep == NULL) + { return; + } /* Convert the IP address to Unicode */ if (sep - msg > 0 @@ -253,7 +265,9 @@ parse_assigned_ip(connection_t *c, const char *msg) sep = strchr(sep + 1, ','); } if (!sep) + { return; + } sep++; /* start of ipv6 address */ /* Convert the IP address to Unicode */ @@ -289,23 +303,31 @@ OnStateChange(connection_t *c, char *data) char *pos, *state, *message; if (data == NULL) + { return; + } pos = strchr(data, ','); if (pos == NULL) + { return; + } *pos = '\0'; state = pos + 1; pos = strchr(state, ','); if (pos == NULL) + { return; + } *pos = '\0'; message = pos + 1; pos = strchr(message, ','); if (pos == NULL) + { return; + } *pos = '\0'; /* notify the all windows in the thread of state change */ @@ -355,8 +377,8 @@ OnStateChange(connection_t *c, char *data) /* Show connection tray balloon */ if ((c->state == connecting && o.show_balloon != 0) - || (c->state == resuming && o.show_balloon != 0) - || (c->state == reconnecting && o.show_balloon == 2)) + || (c->state == resuming && o.show_balloon != 0) + || (c->state == reconnecting && o.show_balloon == 2)) { TCHAR msg[256]; DWORD id = success ? IDS_NFO_NOW_CONNECTED : IDS_NFO_NOTIFY_ROUTE_ERROR; @@ -392,21 +414,25 @@ OnStateChange(connection_t *c, char *data) if (!c->dynamic_cr) { if (strcmp(message, "auth-failure") == 0) + { c->failed_auth_attempts++; + } else if (strcmp(message, "private-key-password-failure") == 0) + { c->failed_psw_attempts++; + } } echo_msg_clear(c, false); /* do not clear history */ - // We change the state to reconnecting only if there was a prior successful connection. + /* We change the state to reconnecting only if there was a prior successful connection. */ if (c->state == connected) { c->state = reconnecting; - // Update the tray icon + /* Update the tray icon */ CheckAndSetTrayIcon(); - // And the texts in the status window + /* And the texts in the status window */ SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_RECONNECTING)); SetDlgItemTextW(c->hwndStatus, ID_TXT_IP, L""); SetStatusWinIcon(c->hwndStatus, ID_ICO_CONNECTING); @@ -427,8 +453,8 @@ typedef struct autoclose { UINT btn; /* button which is 'pressed' for autoclose */ UINT txtid; /* id of a text control to display an informaltional message */ UINT txtres; /* resource id of localized text to use for message: - LoadLocalizedString(txtid, time_remaining_in_seconds) - is used to generate the message */ + * LoadLocalizedString(txtid, time_remaining_in_seconds) + * is used to generate the message */ COLORREF txtclr; /* color for message text */ } autoclose; @@ -438,10 +464,14 @@ AutoCloseCancel(HWND hwnd) { autoclose *ac = (autoclose *)GetProp(hwnd, L"AutoClose"); if (!ac) + { return; + } if (ac->txtid) + { SetDlgItemText(hwnd, ac->txtid, L""); + } KillTimer(hwnd, 1); RemoveProp(hwnd, L"AutoClose"); free(ac); @@ -453,7 +483,9 @@ AutoCloseHandler(HWND hwnd, UINT UNUSED msg, UINT_PTR id, DWORD now) { autoclose *ac = (autoclose *)GetProp(hwnd, L"AutoClose"); if (!ac) + { return; + } DWORD elapsed = now - ac->start; if (elapsed >= ac->timeout) @@ -479,19 +511,25 @@ static void AutoCloseSetup(HWND hwnd, UINT btn, UINT timeout, UINT txtid, UINT txtres) { if (timeout == 0) + { SimulateButtonPress(hwnd, btn); + } else { autoclose *ac = GetPropW(hwnd, L"AutoClose"); /* reuse if set */ if (!ac && (ac = malloc(sizeof(autoclose))) == NULL) + { return; + } *ac = (autoclose) {.start = GetTickCount(), .timeout = timeout*1000, .btn = btn, - .txtid = txtid, .txtres = txtres, .txtclr = GetSysColor(COLOR_WINDOWTEXT)}; + .txtid = txtid, .txtres = txtres, .txtclr = GetSysColor(COLOR_WINDOWTEXT)}; SetTimer(hwnd, 1, 500, AutoCloseHandler); /* using timer id = 1 */ if (txtid && txtres) + { SetDlgItemText(hwnd, txtid, LoadLocalizedString(txtres, timeout)); + } SetPropW(hwnd, L"AutoClose", (HANDLE) ac); /* failure not critical */ } } @@ -508,194 +546,219 @@ UserAuthDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) switch (msg) { - case WM_INITDIALOG: - /* Set connection for this dialog and show it */ - param = (auth_param_t *) lParam; - TRY_SETPROP(hwndDlg, cfgProp, (HANDLE) param); - SetStatusWinIcon(hwndDlg, ID_ICO_APP); + case WM_INITDIALOG: + /* Set connection for this dialog and show it */ + param = (auth_param_t *) lParam; + TRY_SETPROP(hwndDlg, cfgProp, (HANDLE) param); + SetStatusWinIcon(hwndDlg, ID_ICO_APP); - if (param->str) - { - LPWSTR wstr = Widen (param->str); - HWND wnd_challenge = GetDlgItem(hwndDlg, ID_EDT_AUTH_CHALLENGE); + if (param->str) + { + LPWSTR wstr = Widen(param->str); + HWND wnd_challenge = GetDlgItem(hwndDlg, ID_EDT_AUTH_CHALLENGE); - if (!wstr) - WriteStatusLog(param->c, L"GUI> ", L"Error converting challenge string to widechar", false); - else - SetDlgItemTextW(hwndDlg, ID_TXT_AUTH_CHALLENGE, wstr); + if (!wstr) + { + WriteStatusLog(param->c, L"GUI> ", L"Error converting challenge string to widechar", false); + } + else + { + SetDlgItemTextW(hwndDlg, ID_TXT_AUTH_CHALLENGE, wstr); + } - free(wstr); + free(wstr); - /* Set/Remove style ES_PASSWORD by SetWindowLong(GWL_STYLE) does nothing, - send EM_SETPASSWORDCHAR just works. */ - if (param->flags & FLAG_CR_ECHO) - SendMessage(wnd_challenge, EM_SETPASSWORDCHAR, 0, 0); + /* Set/Remove style ES_PASSWORD by SetWindowLong(GWL_STYLE) does nothing, + * send EM_SETPASSWORDCHAR just works. */ + if (param->flags & FLAG_CR_ECHO) + { + SendMessage(wnd_challenge, EM_SETPASSWORDCHAR, 0, 0); + } - } - if (RecallUsername(param->c->config_name, username)) - { - SetDlgItemTextW(hwndDlg, ID_EDT_AUTH_USER, username); - SetFocus(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS)); - } - if (RecallAuthPass(param->c->config_name, password)) - { - 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) + } + if (RecallUsername(param->c->config_name, username)) { - /* user/pass available and no challenge response needed: skip dialog - * if silent_connection is on, else auto submit after a few seconds. - * User can interrupt. - */ - SetFocus(GetDlgItem(hwndDlg, IDOK)); - UINT timeout = o.silent_connection ? 0 : 6; /* in seconds */ - AutoCloseSetup(hwndDlg, IDOK, timeout, ID_TXT_WARNING, IDS_NFO_AUTO_CONNECT); + SetDlgItemTextW(hwndDlg, ID_EDT_AUTH_USER, username); + SetFocus(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS)); } - /* if auth failed, highlight password so that user can type over */ - else if (param->c->failed_auth_attempts) + if (RecallAuthPass(param->c->config_name, password)) { - SendMessage(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS), EM_SETSEL, 0, MAKELONG(0,-1)); + 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) + { + /* user/pass available and no challenge response needed: skip dialog + * if silent_connection is on, else auto submit after a few seconds. + * User can interrupt. + */ + SetFocus(GetDlgItem(hwndDlg, IDOK)); + UINT timeout = o.silent_connection ? 0 : 6; /* in seconds */ + AutoCloseSetup(hwndDlg, IDOK, timeout, ID_TXT_WARNING, IDS_NFO_AUTO_CONNECT); + } + /* if auth failed, highlight password so that user can type over */ + else if (param->c->failed_auth_attempts) + { + SendMessage(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS), EM_SETSEL, 0, MAKELONG(0, -1)); + } + else if (param->flags & FLAG_CR_TYPE_SCRV1) + { + SetFocus(GetDlgItem(hwndDlg, ID_EDT_AUTH_CHALLENGE)); + } + SecureZeroMemory(password, sizeof(password)); } - else if (param->flags & FLAG_CR_TYPE_SCRV1) + if (param->c->flags & FLAG_DISABLE_SAVE_PASS) { - SetFocus(GetDlgItem(hwndDlg, ID_EDT_AUTH_CHALLENGE)); + ShowWindow(GetDlgItem(hwndDlg, ID_CHK_SAVE_PASS), SW_HIDE); + } + else if (param->c->flags & FLAG_SAVE_AUTH_PASS) + { + Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_SAVE_PASS), BST_CHECKED); } - SecureZeroMemory(password, sizeof(password)); - } - if (param->c->flags & FLAG_DISABLE_SAVE_PASS) - ShowWindow(GetDlgItem (hwndDlg, ID_CHK_SAVE_PASS), SW_HIDE); - else if (param->c->flags & FLAG_SAVE_AUTH_PASS) - Button_SetCheck(GetDlgItem (hwndDlg, ID_CHK_SAVE_PASS), BST_CHECKED); - - SetWindowText (hwndDlg, param->c->config_name); - if (param->c->failed_auth_attempts > 0) - SetDlgItemTextW(hwndDlg, ID_TXT_WARNING, LoadLocalizedString(IDS_NFO_AUTH_PASS_RETRY)); - if (param->c->state == resuming) - ForceForegroundWindow(hwndDlg); - else - SetForegroundWindow(hwndDlg); - ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS), - GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), 0); - break; - - case WM_LBUTTONDOWN: - case WM_RBUTTONDOWN: - case WM_NCLBUTTONDOWN: - case WM_NCRBUTTONDOWN: - /* user interrupt */ - AutoCloseCancel(hwndDlg); - break; - - case WM_COMMAND: - param = (auth_param_t *) GetProp(hwndDlg, cfgProp); - switch (LOWORD(wParam)) - { - case ID_EDT_AUTH_PASS: - ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS), - GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); - /* fall through */ - case ID_EDT_AUTH_USER: - case ID_EDT_AUTH_CHALLENGE: - if (HIWORD(wParam) == EN_UPDATE) + SetWindowText(hwndDlg, param->c->config_name); + if (param->c->failed_auth_attempts > 0) { - /* enable OK button only if username and either password or response are filled */ - BOOL enableOK = GetWindowTextLength(GetDlgItem(hwndDlg, ID_EDT_AUTH_USER)) - && (GetWindowTextLength(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS)) - || ((param->flags & FLAG_CR_TYPE_SCRV1) - && GetWindowTextLength(GetDlgItem(hwndDlg, ID_EDT_AUTH_CHALLENGE))) - ); - EnableWindow(GetDlgItem(hwndDlg, IDOK), enableOK); + SetDlgItemTextW(hwndDlg, ID_TXT_WARNING, LoadLocalizedString(IDS_NFO_AUTH_PASS_RETRY)); } - AutoCloseCancel(hwndDlg); /* user interrupt */ - break; - case ID_CHK_SAVE_PASS: - param->c->flags ^= FLAG_SAVE_AUTH_PASS; - if (param->c->flags & FLAG_SAVE_AUTH_PASS) - Button_SetCheck(GetDlgItem (hwndDlg, ID_CHK_SAVE_PASS), BST_CHECKED); + if (param->c->state == resuming) + { + ForceForegroundWindow(hwndDlg); + } else { - DeleteSavedAuthPass(param->c->config_name); - Button_SetCheck(GetDlgItem (hwndDlg, ID_CHK_SAVE_PASS), BST_UNCHECKED); + SetForegroundWindow(hwndDlg); } - AutoCloseCancel(hwndDlg); /* user interrupt */ + ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS), + GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), 0); + break; + + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_NCLBUTTONDOWN: + case WM_NCRBUTTONDOWN: + /* user interrupt */ + AutoCloseCancel(hwndDlg); break; - case IDOK: - if (GetDlgItemTextW(hwndDlg, ID_EDT_AUTH_USER, username, _countof(username))) + case WM_COMMAND: + param = (auth_param_t *) GetProp(hwndDlg, cfgProp); + switch (LOWORD(wParam)) { - if (!validate_input(username, L"\n")) - { - show_error_tip(GetDlgItem(hwndDlg, ID_EDT_AUTH_USER), LoadLocalizedString(IDS_ERR_INVALID_USERNAME_INPUT)); - return 0; - } - SaveUsername(param->c->config_name, username); + case ID_EDT_AUTH_PASS: + ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS), + GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); + + /* fall through */ + case ID_EDT_AUTH_USER: + case ID_EDT_AUTH_CHALLENGE: + if (HIWORD(wParam) == EN_UPDATE) + { + /* enable OK button only if username and either password or response are filled */ + BOOL enableOK = GetWindowTextLength(GetDlgItem(hwndDlg, ID_EDT_AUTH_USER)) + && (GetWindowTextLength(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS)) + || ((param->flags & FLAG_CR_TYPE_SCRV1) + && GetWindowTextLength(GetDlgItem(hwndDlg, ID_EDT_AUTH_CHALLENGE))) + ); + EnableWindow(GetDlgItem(hwndDlg, IDOK), enableOK); + } + AutoCloseCancel(hwndDlg); /* user interrupt */ + break; + + case ID_CHK_SAVE_PASS: + param->c->flags ^= FLAG_SAVE_AUTH_PASS; + if (param->c->flags & FLAG_SAVE_AUTH_PASS) + { + Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_SAVE_PASS), BST_CHECKED); + } + else + { + DeleteSavedAuthPass(param->c->config_name); + Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_SAVE_PASS), BST_UNCHECKED); + } + AutoCloseCancel(hwndDlg); /* user interrupt */ + break; + + case IDOK: + if (GetDlgItemTextW(hwndDlg, ID_EDT_AUTH_USER, username, _countof(username))) + { + if (!validate_input(username, L"\n")) + { + show_error_tip(GetDlgItem(hwndDlg, ID_EDT_AUTH_USER), LoadLocalizedString(IDS_ERR_INVALID_USERNAME_INPUT)); + return 0; + } + SaveUsername(param->c->config_name, username); + } + if (GetDlgItemTextW(hwndDlg, ID_EDT_AUTH_PASS, password, _countof(password))) + { + if (!validate_input(password, L"\n")) + { + show_error_tip(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS), LoadLocalizedString(IDS_ERR_INVALID_PASSWORD_INPUT)); + SecureZeroMemory(password, sizeof(password)); + return 0; + } + if (param->c->flags & FLAG_SAVE_AUTH_PASS && wcslen(password) ) + { + SaveAuthPass(param->c->config_name, password); + } + SecureZeroMemory(password, sizeof(password)); + } + 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 + { + ManagementCommandFromInput(param->c, "password \"Auth\" \"%s\"", hwndDlg, ID_EDT_AUTH_PASS); + } + EndDialog(hwndDlg, LOWORD(wParam)); + return TRUE; + + case IDCANCEL: + EndDialog(hwndDlg, LOWORD(wParam)); + StopOpenVPN(param->c); + return TRUE; + + case ID_PASSWORD_REVEAL: /* password reveal symbol clicked */ + ChangePasswordVisibility(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS), + GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); + return TRUE; } - if (GetDlgItemTextW(hwndDlg, ID_EDT_AUTH_PASS, password, _countof(password))) + break; + + case WM_OVPN_STATE: /* state changed -- destroy the dialog */ + EndDialog(hwndDlg, LOWORD(wParam)); + return TRUE; + + case WM_CTLCOLORSTATIC: + if (GetDlgCtrlID((HWND) lParam) == ID_TXT_WARNING) { - if (!validate_input(password, L"\n")) - { - show_error_tip(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS), LoadLocalizedString(IDS_ERR_INVALID_PASSWORD_INPUT)); - SecureZeroMemory(password, sizeof(password)); - return 0; - } - if ( param->c->flags & FLAG_SAVE_AUTH_PASS && wcslen(password) ) + autoclose *ac = (autoclose *)GetProp(hwndDlg, L"AutoClose"); + HBRUSH br = (HBRUSH) DefWindowProc(hwndDlg, msg, wParam, lParam); + /* This text id is used for auth failure warning or autoclose message. Use appropriate color */ + COLORREF clr = o.clr_warning; + if (ac && ac->txtid == ID_TXT_WARNING) { - SaveAuthPass(param->c->config_name, password); + clr = ac->txtclr; } - SecureZeroMemory(password, sizeof(password)); + SetTextColor((HDC) wParam, clr); + return (INT_PTR) br; } - 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 - ManagementCommandFromInput(param->c, "password \"Auth\" \"%s\"", hwndDlg, ID_EDT_AUTH_PASS); - EndDialog(hwndDlg, LOWORD(wParam)); - return TRUE; + break; - case IDCANCEL: + case WM_CLOSE: EndDialog(hwndDlg, LOWORD(wParam)); + param = (auth_param_t *) GetProp(hwndDlg, cfgProp); StopOpenVPN(param->c); return TRUE; - case ID_PASSWORD_REVEAL: /* password reveal symbol clicked */ - ChangePasswordVisibility(GetDlgItem(hwndDlg, ID_EDT_AUTH_PASS), - GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); - return TRUE; - } - break; - - case WM_OVPN_STATE: /* state changed -- destroy the dialog */ - EndDialog(hwndDlg, LOWORD(wParam)); - return TRUE; - - case WM_CTLCOLORSTATIC: - if (GetDlgCtrlID((HWND) lParam) == ID_TXT_WARNING) - { - autoclose *ac = (autoclose *)GetProp(hwndDlg, L"AutoClose"); - HBRUSH br = (HBRUSH) DefWindowProc(hwndDlg, msg, wParam, lParam); - /* This text id is used for auth failure warning or autoclose message. Use appropriate color */ - COLORREF clr = o.clr_warning; - if (ac && ac->txtid == ID_TXT_WARNING) - clr = ac->txtclr; - SetTextColor((HDC) wParam, clr); - return (INT_PTR) br; - } - break; - - case WM_CLOSE: - EndDialog(hwndDlg, LOWORD(wParam)); - param = (auth_param_t *) GetProp(hwndDlg, cfgProp); - StopOpenVPN(param->c); - return TRUE; - - case WM_NCDESTROY: - param = (auth_param_t *) GetProp(hwndDlg, cfgProp); - free_auth_param (param); - AutoCloseCancel(hwndDlg); - RemoveProp(hwndDlg, cfgProp); - break; + case WM_NCDESTROY: + param = (auth_param_t *) GetProp(hwndDlg, cfgProp); + free_auth_param(param); + AutoCloseCancel(hwndDlg); + RemoveProp(hwndDlg, cfgProp); + break; } return FALSE; @@ -712,197 +775,203 @@ GenericPassDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) switch (msg) { - case WM_INITDIALOG: - param = (auth_param_t *) lParam; - TRY_SETPROP(hwndDlg, cfgProp, (HANDLE) param); - - WCHAR *wstr = Widen (param->str); - if (!wstr) - { - WriteStatusLog(param->c, L"GUI> ", L"Error converting challenge string to widechar", false); - EndDialog(hwndDlg, LOWORD(wParam)); - break; - } - if (param->flags & FLAG_CR_TYPE_CRV1 || param->flags & FLAG_CR_TYPE_CRTEXT) - { - SetDlgItemTextW(hwndDlg, ID_TXT_DESCRIPTION, wstr); - - /* Set password echo on if needed */ - if (param->flags & FLAG_CR_ECHO) - SendMessage(GetDlgItem(hwndDlg, ID_EDT_RESPONSE), EM_SETPASSWORDCHAR, 0, 0); - - /* Rendered size of challenge text and window rectangle */ - SIZE sz = {0}; - RECT rect = {0}; - HDC hdc = GetDC(GetDlgItem(hwndDlg, ID_TXT_DESCRIPTION)); - GetWindowRect(hwndDlg, &rect); - rect.right -= rect.left; - rect.bottom -= rect.top; + case WM_INITDIALOG: + param = (auth_param_t *) lParam; + TRY_SETPROP(hwndDlg, cfgProp, (HANDLE) param); - /* if space for text + some margin exceeds the window size, resize */ - if (GetTextExtentPoint32W(hdc, wstr, wcslen(wstr), &sz) - && LPtoDP(hdc, (POINT *) &sz, 1) /* logical to device units */ - && sz.cx + DPI_SCALE(15) > rect.right) /* 15 nominal pixel margin space */ + WCHAR *wstr = Widen(param->str); + if (!wstr) { - /* new horizontal dimension with a max of 640 nominal pixels */ - rect.right = min(DPI_SCALE(640), sz.cx + DPI_SCALE(15)); - SetWindowPos(hwndDlg, NULL, 0, 0, rect.right, rect.bottom, SWP_NOMOVE); - PrintDebug(L"Window resized to = %d %d", rect.right, rect.bottom); + WriteStatusLog(param->c, L"GUI> ", L"Error converting challenge string to widechar", false); + EndDialog(hwndDlg, LOWORD(wParam)); + break; } - } - else if (param->flags & FLAG_PASS_TOKEN) - { - SetWindowText(hwndDlg, LoadLocalizedString(IDS_NFO_TOKEN_PASSWORD_CAPTION)); - SetDlgItemText(hwndDlg, ID_TXT_DESCRIPTION, LoadLocalizedString(IDS_NFO_TOKEN_PASSWORD_REQUEST, param->id)); - } - else - { - WriteStatusLog(param->c, L"GUI> ", L"Unknown password request", false); - SetDlgItemText(hwndDlg, ID_TXT_DESCRIPTION, wstr); - } - free(wstr); - - AppendTextToCaption (hwndDlg, param->c->config_name); - if (param->c->state == resuming) - ForceForegroundWindow(hwndDlg); - else - SetForegroundWindow(hwndDlg); - - /* If response is not required hide the response field */ - if ((param->flags & FLAG_CR_TYPE_CRV1 || param->flags & FLAG_CR_TYPE_CRTEXT) - && !(param->flags & FLAG_CR_RESPONSE)) - { - ShowWindow(GetDlgItem(hwndDlg, ID_LTEXT_RESPONSE), SW_HIDE); - ShowWindow(GetDlgItem(hwndDlg, ID_EDT_RESPONSE), SW_HIDE); - } - else - { - /* disable OK button until response is filled-in */ - EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE); - } - ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_RESPONSE), - GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), 0); + if (param->flags & FLAG_CR_TYPE_CRV1 || param->flags & FLAG_CR_TYPE_CRTEXT) + { + SetDlgItemTextW(hwndDlg, ID_TXT_DESCRIPTION, wstr); - break; + /* Set password echo on if needed */ + if (param->flags & FLAG_CR_ECHO) + { + SendMessage(GetDlgItem(hwndDlg, ID_EDT_RESPONSE), EM_SETPASSWORDCHAR, 0, 0); + } - case WM_COMMAND: - param = (auth_param_t *) GetProp(hwndDlg, cfgProp); - const char *template; - char *fmt; - switch (LOWORD(wParam)) - { - case ID_EDT_RESPONSE: - if (!(param->flags & FLAG_CR_ECHO)) + /* Rendered size of challenge text and window rectangle */ + SIZE sz = {0}; + RECT rect = {0}; + HDC hdc = GetDC(GetDlgItem(hwndDlg, ID_TXT_DESCRIPTION)); + GetWindowRect(hwndDlg, &rect); + rect.right -= rect.left; + rect.bottom -= rect.top; + + /* if space for text + some margin exceeds the window size, resize */ + if (GetTextExtentPoint32W(hdc, wstr, wcslen(wstr), &sz) + && LPtoDP(hdc, (POINT *) &sz, 1) /* logical to device units */ + && sz.cx + DPI_SCALE(15) > rect.right) /* 15 nominal pixel margin space */ + { + /* new horizontal dimension with a max of 640 nominal pixels */ + rect.right = min(DPI_SCALE(640), sz.cx + DPI_SCALE(15)); + SetWindowPos(hwndDlg, NULL, 0, 0, rect.right, rect.bottom, SWP_NOMOVE); + PrintDebug(L"Window resized to = %d %d", rect.right, rect.bottom); + } + } + else if (param->flags & FLAG_PASS_TOKEN) { - ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_RESPONSE), - GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); + SetWindowText(hwndDlg, LoadLocalizedString(IDS_NFO_TOKEN_PASSWORD_CAPTION)); + SetDlgItemText(hwndDlg, ID_TXT_DESCRIPTION, LoadLocalizedString(IDS_NFO_TOKEN_PASSWORD_REQUEST, param->id)); } - if (HIWORD(wParam) == EN_UPDATE) + else { - /* enable OK if response is non-empty */ - BOOL enableOK = GetWindowTextLength((HWND) lParam); - EnableWindow(GetDlgItem(hwndDlg, IDOK), enableOK); + WriteStatusLog(param->c, L"GUI> ", L"Unknown password request", false); + SetDlgItemText(hwndDlg, ID_TXT_DESCRIPTION, wstr); } - break; + free(wstr); - case IDOK: - if (GetDlgItemTextW(hwndDlg, ID_EDT_RESPONSE, password, _countof(password)) - && !validate_input(password, L"\n")) + AppendTextToCaption(hwndDlg, param->c->config_name); + if (param->c->state == resuming) { - show_error_tip(GetDlgItem(hwndDlg, ID_EDT_RESPONSE), LoadLocalizedString(IDS_ERR_INVALID_PASSWORD_INPUT)); - SecureZeroMemory(password, sizeof(password)); - return 0; + ForceForegroundWindow(hwndDlg); } - if (param->flags & FLAG_CR_TYPE_CRTEXT) + else { - ManagementCommandFromInputBase64(param->c, "cr-response \"%s\"", hwndDlg, ID_EDT_RESPONSE); - EndDialog(hwndDlg, LOWORD(wParam)); - return TRUE; + SetForegroundWindow(hwndDlg); } - if (param->flags & FLAG_CR_TYPE_CRV1) - { - /* send username */ - template = "username \"Auth\" \"%s\""; - char *username = escape_string(param->user); - fmt = malloc(strlen(template) + strlen(username)); - - if (fmt && username) - { - sprintf(fmt, template, username); - ManagementCommand(param->c, fmt, NULL, regular); - } - else /* no memory? send an emty username and let it error out */ - { - WriteStatusLog(param->c, L"GUI> ", - L"Out of memory: sending a generic username for dynamic CR", false); - ManagementCommand(param->c, "username \"Auth\" \"user\"", NULL, regular); - } - free(fmt); - free(username); - /* password template */ - template = "password \"Auth\" \"CRV1::%s::%%s\""; + /* If response is not required hide the response field */ + if ((param->flags & FLAG_CR_TYPE_CRV1 || param->flags & FLAG_CR_TYPE_CRTEXT) + && !(param->flags & FLAG_CR_RESPONSE)) + { + ShowWindow(GetDlgItem(hwndDlg, ID_LTEXT_RESPONSE), SW_HIDE); + ShowWindow(GetDlgItem(hwndDlg, ID_EDT_RESPONSE), SW_HIDE); } - else /* generic password request of type param->id */ + else { - template = "password \"%s\" \"%%s\""; + /* disable OK button until response is filled-in */ + EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE); } + ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_RESPONSE), + GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), 0); + + break; - fmt = malloc(strlen(template) + strlen(param->id)); - if (fmt) + case WM_COMMAND: + param = (auth_param_t *) GetProp(hwndDlg, cfgProp); + const char *template; + char *fmt; + switch (LOWORD(wParam)) { - sprintf(fmt, template, param->id); - PrintDebug(L"Send passwd to mgmt with format: '%hs'", fmt); - ManagementCommandFromInput(param->c, fmt, hwndDlg, ID_EDT_RESPONSE); - free (fmt); + case ID_EDT_RESPONSE: + if (!(param->flags & FLAG_CR_ECHO)) + { + ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_RESPONSE), + GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); + } + if (HIWORD(wParam) == EN_UPDATE) + { + /* enable OK if response is non-empty */ + BOOL enableOK = GetWindowTextLength((HWND) lParam); + EnableWindow(GetDlgItem(hwndDlg, IDOK), enableOK); + } + break; + + case IDOK: + if (GetDlgItemTextW(hwndDlg, ID_EDT_RESPONSE, password, _countof(password)) + && !validate_input(password, L"\n")) + { + show_error_tip(GetDlgItem(hwndDlg, ID_EDT_RESPONSE), LoadLocalizedString(IDS_ERR_INVALID_PASSWORD_INPUT)); + SecureZeroMemory(password, sizeof(password)); + return 0; + } + if (param->flags & FLAG_CR_TYPE_CRTEXT) + { + ManagementCommandFromInputBase64(param->c, "cr-response \"%s\"", hwndDlg, ID_EDT_RESPONSE); + EndDialog(hwndDlg, LOWORD(wParam)); + return TRUE; + } + if (param->flags & FLAG_CR_TYPE_CRV1) + { + /* send username */ + template = "username \"Auth\" \"%s\""; + char *username = escape_string(param->user); + fmt = malloc(strlen(template) + strlen(username)); + + if (fmt && username) + { + sprintf(fmt, template, username); + ManagementCommand(param->c, fmt, NULL, regular); + } + else /* no memory? send an emty username and let it error out */ + { + WriteStatusLog(param->c, L"GUI> ", + L"Out of memory: sending a generic username for dynamic CR", false); + ManagementCommand(param->c, "username \"Auth\" \"user\"", NULL, regular); + } + free(fmt); + free(username); + + /* password template */ + template = "password \"Auth\" \"CRV1::%s::%%s\""; + } + else /* generic password request of type param->id */ + { + template = "password \"%s\" \"%%s\""; + } + + fmt = malloc(strlen(template) + strlen(param->id)); + if (fmt) + { + sprintf(fmt, template, param->id); + PrintDebug(L"Send passwd to mgmt with format: '%hs'", fmt); + ManagementCommandFromInput(param->c, fmt, hwndDlg, ID_EDT_RESPONSE); + free(fmt); + } + else /* no memory? send stop signal */ + { + WriteStatusLog(param->c, L"GUI> ", + L"Out of memory in password dialog: sending stop signal", false); + StopOpenVPN(param->c); + } + + EndDialog(hwndDlg, LOWORD(wParam)); + return TRUE; + + case IDCANCEL: + EndDialog(hwndDlg, LOWORD(wParam)); + StopOpenVPN(param->c); + return TRUE; + + case ID_PASSWORD_REVEAL: /* password reveal symbol clicked */ + ChangePasswordVisibility(GetDlgItem(hwndDlg, ID_EDT_RESPONSE), + GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); + return TRUE; } - else /* no memory? send stop signal */ + break; + + case WM_OVPN_STATE: /* state change message is received from OpenVPN daemon */ + /* + * AUTH_PENDING immediately transitions to GET_CONFIG until + * auth succeeds or connection restarts/aborts. + * Close the CR_TEXT dialog if state changes to anything + * other than GET_CONFIG. The state is in lParam. + * For other auth dialogs any state change signals a restart: end the dialog + */ + param = (auth_param_t *) GetProp(hwndDlg, cfgProp); + if (!(param->flags & FLAG_CR_TYPE_CRTEXT) + || strcmp((const char *) lParam, "GET_CONFIG")) { - WriteStatusLog(param->c, L"GUI> ", - L"Out of memory in password dialog: sending stop signal", false); - StopOpenVPN (param->c); + EndDialog(hwndDlg, LOWORD(wParam)); } - - EndDialog(hwndDlg, LOWORD(wParam)); return TRUE; - case IDCANCEL: + case WM_CLOSE: EndDialog(hwndDlg, LOWORD(wParam)); - StopOpenVPN(param->c); - return TRUE; - - case ID_PASSWORD_REVEAL: /* password reveal symbol clicked */ - ChangePasswordVisibility(GetDlgItem(hwndDlg, ID_EDT_RESPONSE), - GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); return TRUE; - } - break; - - case WM_OVPN_STATE: /* state change message is received from OpenVPN daemon */ - /* - * AUTH_PENDING immediately transitions to GET_CONFIG until - * auth succeeds or connection restarts/aborts. - * Close the CR_TEXT dialog if state changes to anything - * other than GET_CONFIG. The state is in lParam. - * For other auth dialogs any state change signals a restart: end the dialog - */ - param = (auth_param_t *) GetProp(hwndDlg, cfgProp); - if (!(param->flags & FLAG_CR_TYPE_CRTEXT) - || strcmp((const char *) lParam, "GET_CONFIG")) - { - EndDialog(hwndDlg, LOWORD(wParam)); - } - return TRUE; - case WM_CLOSE: - EndDialog(hwndDlg, LOWORD(wParam)); - return TRUE; - - case WM_NCDESTROY: - param = (auth_param_t *) GetProp(hwndDlg, cfgProp); - free_auth_param (param); - RemoveProp(hwndDlg, cfgProp); - break; + case WM_NCDESTROY: + param = (auth_param_t *) GetProp(hwndDlg, cfgProp); + free_auth_param(param); + RemoveProp(hwndDlg, cfgProp); + break; } return FALSE; @@ -919,123 +988,135 @@ PrivKeyPassDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) switch (msg) { - case WM_INITDIALOG: - /* Set connection for this dialog and show it */ - c = (connection_t *) lParam; - TRY_SETPROP(hwndDlg, cfgProp, (HANDLE) c); - AppendTextToCaption (hwndDlg, c->config_name); - if (RecallKeyPass(c->config_name, passphrase) && wcslen(passphrase) - && c->failed_psw_attempts == 0) - { - /* Use the saved password and skip the dialog */ - SetDlgItemTextW(hwndDlg, ID_EDT_PASSPHRASE, passphrase); - SecureZeroMemory(passphrase, sizeof(passphrase)); - ManagementCommandFromInput(c, "password \"Private Key\" \"%s\"", hwndDlg, ID_EDT_PASSPHRASE); - EndDialog(hwndDlg, IDOK); - return TRUE; - } - if (c->flags & FLAG_DISABLE_SAVE_PASS) - ShowWindow(GetDlgItem (hwndDlg, ID_CHK_SAVE_PASS), SW_HIDE); - else if (c->flags & FLAG_SAVE_KEY_PASS) - Button_SetCheck (GetDlgItem (hwndDlg, ID_CHK_SAVE_PASS), BST_CHECKED); - if (c->failed_psw_attempts > 0) - SetDlgItemTextW(hwndDlg, ID_TXT_WARNING, LoadLocalizedString(IDS_NFO_KEY_PASS_RETRY)); - if (c->state == resuming) - ForceForegroundWindow(hwndDlg); - else - SetForegroundWindow(hwndDlg); - - /* disable OK button by default - not disabled in resources */ - EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE); - ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_PASSPHRASE), - GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), 0); - break; - - case WM_COMMAND: - c = (connection_t *) GetProp(hwndDlg, cfgProp); - switch (LOWORD(wParam)) - { - case ID_CHK_SAVE_PASS: - c->flags ^= FLAG_SAVE_KEY_PASS; - if (c->flags & FLAG_SAVE_KEY_PASS) - Button_SetCheck (GetDlgItem (hwndDlg, ID_CHK_SAVE_PASS), BST_CHECKED); + case WM_INITDIALOG: + /* Set connection for this dialog and show it */ + c = (connection_t *) lParam; + TRY_SETPROP(hwndDlg, cfgProp, (HANDLE) c); + AppendTextToCaption(hwndDlg, c->config_name); + if (RecallKeyPass(c->config_name, passphrase) && wcslen(passphrase) + && c->failed_psw_attempts == 0) + { + /* Use the saved password and skip the dialog */ + SetDlgItemTextW(hwndDlg, ID_EDT_PASSPHRASE, passphrase); + SecureZeroMemory(passphrase, sizeof(passphrase)); + ManagementCommandFromInput(c, "password \"Private Key\" \"%s\"", hwndDlg, ID_EDT_PASSPHRASE); + EndDialog(hwndDlg, IDOK); + return TRUE; + } + if (c->flags & FLAG_DISABLE_SAVE_PASS) + { + ShowWindow(GetDlgItem(hwndDlg, ID_CHK_SAVE_PASS), SW_HIDE); + } + else if (c->flags & FLAG_SAVE_KEY_PASS) + { + Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_SAVE_PASS), BST_CHECKED); + } + if (c->failed_psw_attempts > 0) + { + SetDlgItemTextW(hwndDlg, ID_TXT_WARNING, LoadLocalizedString(IDS_NFO_KEY_PASS_RETRY)); + } + if (c->state == resuming) + { + ForceForegroundWindow(hwndDlg); + } else { - Button_SetCheck (GetDlgItem (hwndDlg, ID_CHK_SAVE_PASS), BST_UNCHECKED); - DeleteSavedKeyPass(c->config_name); + SetForegroundWindow(hwndDlg); } - break; - case ID_EDT_PASSPHRASE: + /* disable OK button by default - not disabled in resources */ + EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE); ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_PASSPHRASE), - GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); - if (HIWORD(wParam) == EN_UPDATE) - { - /* enable OK if response is non-empty */ - BOOL enableOK = GetWindowTextLength((HWND) lParam); - EnableWindow(GetDlgItem(hwndDlg, IDOK), enableOK); - } + GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), 0); break; - case IDOK: - if (GetDlgItemTextW(hwndDlg, ID_EDT_PASSPHRASE, passphrase, _countof(passphrase))) + case WM_COMMAND: + c = (connection_t *) GetProp(hwndDlg, cfgProp); + switch (LOWORD(wParam)) { - if (!validate_input(passphrase, L"\n")) - { - show_error_tip(GetDlgItem(hwndDlg, ID_EDT_PASSPHRASE), LoadLocalizedString(IDS_ERR_INVALID_PASSWORD_INPUT)); - SecureZeroMemory(passphrase, sizeof(passphrase)); - return 0; - } - if ((c->flags & FLAG_SAVE_KEY_PASS) && wcslen(passphrase) > 0) - { - SaveKeyPass(c->config_name, passphrase); - } - SecureZeroMemory(passphrase, sizeof(passphrase)); + case ID_CHK_SAVE_PASS: + c->flags ^= FLAG_SAVE_KEY_PASS; + if (c->flags & FLAG_SAVE_KEY_PASS) + { + Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_SAVE_PASS), BST_CHECKED); + } + else + { + Button_SetCheck(GetDlgItem(hwndDlg, ID_CHK_SAVE_PASS), BST_UNCHECKED); + DeleteSavedKeyPass(c->config_name); + } + break; + + case ID_EDT_PASSPHRASE: + ResetPasswordReveal(GetDlgItem(hwndDlg, ID_EDT_PASSPHRASE), + GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); + if (HIWORD(wParam) == EN_UPDATE) + { + /* enable OK if response is non-empty */ + BOOL enableOK = GetWindowTextLength((HWND) lParam); + EnableWindow(GetDlgItem(hwndDlg, IDOK), enableOK); + } + break; + + case IDOK: + if (GetDlgItemTextW(hwndDlg, ID_EDT_PASSPHRASE, passphrase, _countof(passphrase))) + { + if (!validate_input(passphrase, L"\n")) + { + show_error_tip(GetDlgItem(hwndDlg, ID_EDT_PASSPHRASE), LoadLocalizedString(IDS_ERR_INVALID_PASSWORD_INPUT)); + SecureZeroMemory(passphrase, sizeof(passphrase)); + return 0; + } + if ((c->flags & FLAG_SAVE_KEY_PASS) && wcslen(passphrase) > 0) + { + SaveKeyPass(c->config_name, passphrase); + } + SecureZeroMemory(passphrase, sizeof(passphrase)); + } + ManagementCommandFromInput(c, "password \"Private Key\" \"%s\"", hwndDlg, ID_EDT_PASSPHRASE); + EndDialog(hwndDlg, LOWORD(wParam)); + return TRUE; + + case IDCANCEL: + EndDialog(hwndDlg, LOWORD(wParam)); + StopOpenVPN(c); + return TRUE; + + case ID_PASSWORD_REVEAL: /* password reveal symbol clicked */ + ChangePasswordVisibility(GetDlgItem(hwndDlg, ID_EDT_PASSPHRASE), + GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); + return TRUE; } - ManagementCommandFromInput(c, "password \"Private Key\" \"%s\"", hwndDlg, ID_EDT_PASSPHRASE); - EndDialog(hwndDlg, LOWORD(wParam)); - return TRUE; + break; - case IDCANCEL: + case WM_OVPN_STATE: /* state changed -- destroy the dialog */ EndDialog(hwndDlg, LOWORD(wParam)); - StopOpenVPN (c); - return TRUE; - - case ID_PASSWORD_REVEAL: /* password reveal symbol clicked */ - ChangePasswordVisibility(GetDlgItem(hwndDlg, ID_EDT_PASSPHRASE), - GetDlgItem(hwndDlg, ID_PASSWORD_REVEAL), wParam); return TRUE; - } - break; - case WM_OVPN_STATE: /* state changed -- destroy the dialog */ - EndDialog(hwndDlg, LOWORD(wParam)); - return TRUE; - - case WM_CTLCOLORSTATIC: - if (GetDlgCtrlID((HWND) lParam) == ID_TXT_WARNING) - { - HBRUSH br = (HBRUSH) DefWindowProc(hwndDlg, msg, wParam, lParam); - SetTextColor((HDC) wParam, o.clr_warning); - return (INT_PTR) br; - } - break; + case WM_CTLCOLORSTATIC: + if (GetDlgCtrlID((HWND) lParam) == ID_TXT_WARNING) + { + HBRUSH br = (HBRUSH) DefWindowProc(hwndDlg, msg, wParam, lParam); + SetTextColor((HDC) wParam, o.clr_warning); + return (INT_PTR) br; + } + break; - case WM_CLOSE: - EndDialog(hwndDlg, LOWORD(wParam)); - return TRUE; + case WM_CLOSE: + EndDialog(hwndDlg, LOWORD(wParam)); + return TRUE; - case WM_NCDESTROY: - RemoveProp(hwndDlg, cfgProp); - break; - } - return FALSE; + case WM_NCDESTROY: + RemoveProp(hwndDlg, cfgProp); + break; + } + return FALSE; } static void -free_dynamic_cr (connection_t *c) +free_dynamic_cr(connection_t *c) { - free (c->dynamic_cr); + free(c->dynamic_cr); c->dynamic_cr = NULL; } @@ -1045,24 +1126,29 @@ free_dynamic_cr (connection_t *c) * even on error. */ BOOL -parse_dynamic_cr (const char *str, auth_param_t *param) +parse_dynamic_cr(const char *str, auth_param_t *param) { BOOL ret = FALSE; char *token[4] = {0}; - char *p = strdup (str); + char *p = strdup(str); int i; char *p1; - if (!param || !p) goto out; + if (!param || !p) + { + goto out; + } /* expected: str = "E,R:challenge_id:user_b64:challenge_str" */ const char *delim = ":"; for (i = 0, p1 = p; i < 4; ++i, p1 = NULL) { if (i == 3) - delim = "" ; /* take the entire trailing string as the challenge */ - token[i] = strtok (p1, delim); /* strtok is thread-safe on Windows */ + { + delim = ""; /* take the entire trailing string as the challenge */ + } + token[i] = strtok(p1, delim); /* strtok is thread-safe on Windows */ if (!token[i]) { WriteStatusLog(param->c, L"GUI> ", L"Error parsing dynamic challenge string", false); @@ -1082,12 +1168,14 @@ parse_dynamic_cr (const char *str, auth_param_t *param) param->id = strdup(token[1]); param->str = strdup(token[3]); if (!param->id || !param->str) + { goto out; + } ret = TRUE; out: - free (p); + free(p); return ret; } @@ -1096,14 +1184,17 @@ out: * true on success. The caller must free param->str even on error. */ static BOOL -parse_crtext (const char* str, auth_param_t* param) +parse_crtext(const char *str, auth_param_t *param) { BOOL ret = FALSE; - char* token[2] = { 0 }; - char* p = strdup(str); - char* p1; + char *token[2] = { 0 }; + char *p = strdup(str); + char *p1; - if (!param || !p) goto out; + if (!param || !p) + { + goto out; + } /* expected: str = "E,R:challenge_str" */ token[0] = p; @@ -1122,7 +1213,9 @@ parse_crtext (const char* str, auth_param_t* param) param->flags |= strchr(token[0], 'R') ? FLAG_CR_RESPONSE : 0; param->str = strdup(token[1]); if (!param->str) + { goto out; + } ret = TRUE; @@ -1138,59 +1231,77 @@ out: * Return true on succsess. The caller must free param even when the function fails. */ static BOOL -parse_input_request (const char *msg, auth_param_t *param) +parse_input_request(const char *msg, auth_param_t *param) { BOOL ret = FALSE; - char *p = strdup (msg); + char *p = strdup(msg); char *sep[4] = {" ", "'", " ", ""}; /* separators to use to break up msg */ char *token[4]; char *p1 = p; for (int i = 0; i < 4; ++i, p1 = NULL) { - token[i] = strtok (p1, sep[i]); /* strtok is thread-safe on Windows */ + token[i] = strtok(p1, sep[i]); /* strtok is thread-safe on Windows */ if (!token[i] && i < 3) /* first three tokens required */ + { goto out; + } } if (token[3] && strncmp(token[3], "MSG:", 4) == 0) + { token[3] += 4; + } if (!token[3] || !*token[3]) /* use id as the description if none provided */ + { token[3] = token[1]; + } - PrintDebug (L"Tokens: '%hs' '%hs' '%hs' '%hs'", token[0], token[1], - token[2], token[3]); + PrintDebug(L"Tokens: '%hs' '%hs' '%hs' '%hs'", token[0], token[1], + token[2], token[3]); - if (strcmp (token[0], "Need") != 0) + if (strcmp(token[0], "Need") != 0) + { goto out; + } if ((param->id = strdup(token[1])) == NULL) + { goto out; + } if (strcmp(token[2], "password") == 0) { - if (strcmp (param->id, "Private Key") == 0) + if (strcmp(param->id, "Private Key") == 0) + { param->flags |= FLAG_PASS_PKEY; + } else + { param->flags |= FLAG_PASS_TOKEN; + } } else if (strcmp(token[2], "string") == 0 - && strcmp (param->id, "pkcs11-id-request") == 0) + && strcmp(param->id, "pkcs11-id-request") == 0) { param->flags |= FLAG_STRING_PKCS11; } - param->str = strdup (token[3]); + param->str = strdup(token[3]); if (param->str == NULL) + { goto out; + } - PrintDebug (L"parse_input_request: id = '%hs' str = '%hs' flags = %u", - param->id, param->str, param->flags); + PrintDebug(L"parse_input_request: id = '%hs' str = '%hs' flags = %u", + param->id, param->str, param->flags); ret = TRUE; out: - free (p); + free(p); if (!ret) - PrintDebug (L"Error parsing password/string request msg: <%hs>", msg); + { + PrintDebug(L"Error parsing password/string request msg: <%hs>", msg); + } return ret; } @@ -1217,10 +1328,14 @@ OnEcho(connection_t *c, char *msg) else if (strcmp(msg, "save-passwords") == 0) { if (c->flags & FLAG_DISABLE_SAVE_PASS) + { WriteStatusLog(c, L"GUI> echo save-passwords: ", - L"Ignored as disable_save_passwords is enabled.", false); + L"Ignored as disable_save_passwords is enabled.", false); + } else + { c->flags |= (FLAG_SAVE_KEY_PASS | FLAG_SAVE_AUTH_PASS); + } } else if (strbegins(msg, "setenv ")) { @@ -1250,15 +1365,17 @@ OnPassword(connection_t *c, char *msg) /* If the failure is due to dynamic challenge save the challenge string */ char *chstr = strstr(msg, "CRV1:"); - free_dynamic_cr (c); + free_dynamic_cr(c); if (chstr) { chstr += 5; /* beginning of dynamic CR string */ /* Save the string for later processing during next Auth request */ c->dynamic_cr = strdup(chstr); - if (c->dynamic_cr && (chstr = strstr (c->dynamic_cr, "']")) != NULL) + if (c->dynamic_cr && (chstr = strstr(c->dynamic_cr, "']")) != NULL) + { *chstr = '\0'; + } PrintDebug(L"Got dynamic challenge: <%hs>", c->dynamic_cr); } @@ -1273,24 +1390,24 @@ OnPassword(connection_t *c, char *msg) if (!param) { - WriteStatusLog (c, L"GUI> ", L"Error: Out of memory - ignoring user-auth request", false); + WriteStatusLog(c, L"GUI> ", L"Error: Out of memory - ignoring user-auth request", false); return; } param->c = c; if (c->dynamic_cr) { - if (!parse_dynamic_cr (c->dynamic_cr, param)) + if (!parse_dynamic_cr(c->dynamic_cr, param)) { - WriteStatusLog (c, L"GUI> ", L"Error parsing dynamic challenge string", FALSE); - free_dynamic_cr (c); - free_auth_param (param); + WriteStatusLog(c, L"GUI> ", L"Error parsing dynamic challenge string", FALSE); + free_dynamic_cr(c); + free_auth_param(param); return; } LocalizedDialogBoxParamEx(ID_DLG_CHALLENGE_RESPONSE, c->hwndStatus, GenericPassDialogFunc, (LPARAM) param); - free_dynamic_cr (c); + free_dynamic_cr(c); } - else if ( (chstr = strstr(msg, "SC:")) && strlen (chstr) > 5) + else if ( (chstr = strstr(msg, "SC:")) && strlen(chstr) > 5) { param->flags |= FLAG_CR_TYPE_SCRV1; param->flags |= (*(chstr + 3) != '0') ? FLAG_CR_ECHO : 0; @@ -1321,11 +1438,11 @@ OnPassword(connection_t *c, char *msg) if (!param) { - WriteStatusLog (c, L"GUI> ", L"Error: Out of memory - ignoring user-auth request", false); + WriteStatusLog(c, L"GUI> ", L"Error: Out of memory - ignoring user-auth request", false); return; } param->c = c; - if (!parse_input_request (msg, param)) + if (!parse_input_request(msg, param)) { free_auth_param(param); return; @@ -1349,13 +1466,13 @@ OnTimeout(connection_t *c, UNUSED char *msg) SetForegroundWindow(c->hwndStatus); ShowWindow(c->hwndStatus, SW_SHOW); } - WriteStatusLog (c, L"GUI> ", LoadLocalizedString(IDS_NFO_CONN_TIMEOUT, c->log_path), false); - WriteStatusLog (c, L"GUI> ", L"Retrying. Press disconnect to abort", false); + WriteStatusLog(c, L"GUI> ", LoadLocalizedString(IDS_NFO_CONN_TIMEOUT, c->log_path), false); + WriteStatusLog(c, L"GUI> ", L"Retrying. Press disconnect to abort", false); c->state = connecting; if (!OpenManagement(c)) { MessageBoxExW(c->hwndStatus, L"Failed to open management", _T(PACKAGE_NAME), - MB_OK | MB_SETFOREGROUND | MB_ICONERROR | MBOX_RTL_FLAGS, GetGUILanguage()); + MB_OK | MB_SETFOREGROUND | MB_ICONERROR | MBOX_RTL_FLAGS, GetGUILanguage()); StopOpenVPN(c); } return; @@ -1372,81 +1489,81 @@ OnStop(connection_t *c, UNUSED char *msg) switch (c->state) { - case connected: - /* OpenVPN process ended unexpectedly */ - c->failed_psw_attempts = 0; - c->failed_auth_attempts = 0; - c->state = disconnected; - CheckAndSetTrayIcon(); - SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_DISCONNECTED)); - SetStatusWinIcon(c->hwndStatus, ID_ICO_DISCONNECTED); - EnableWindow(GetDlgItem(c->hwndStatus, ID_DISCONNECT), FALSE); - EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), FALSE); - if (o.silent_connection == 0) - { - SetForegroundWindow(c->hwndStatus); - ShowWindow(c->hwndStatus, SW_SHOW); - } - MessageBoxExW(c->hwndStatus, LoadLocalizedString(IDS_NFO_CONN_TERMINATED, c->config_file), - _T(PACKAGE_NAME), MB_OK | MBOX_RTL_FLAGS, GetGUILanguage()); - SendMessage(c->hwndStatus, WM_CLOSE, 0, 0); - break; - - case resuming: - case connecting: - case reconnecting: - /* We have failed to (re)connect */ - txt_id = c->state == reconnecting ? IDS_NFO_STATE_FAILED_RECONN : IDS_NFO_STATE_FAILED; - msg_id = c->state == reconnecting ? IDS_NFO_RECONN_FAILED : IDS_NFO_CONN_FAILED; - - c->state = disconnecting; - CheckAndSetTrayIcon(); - c->state = disconnected; - EnableWindow(GetDlgItem(c->hwndStatus, ID_DISCONNECT), FALSE); - EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), FALSE); - SetStatusWinIcon(c->hwndStatus, ID_ICO_DISCONNECTED); - SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(txt_id)); - if (o.silent_connection == 0) - { - SetForegroundWindow(c->hwndStatus); - ShowWindow(c->hwndStatus, SW_SHOW); - } - MessageBoxExW(c->hwndStatus, LoadLocalizedString(msg_id, c->config_name), - _T(PACKAGE_NAME), MB_OK | MBOX_RTL_FLAGS, GetGUILanguage()); - SendMessage(c->hwndStatus, WM_CLOSE, 0, 0); - break; + case connected: + /* OpenVPN process ended unexpectedly */ + c->failed_psw_attempts = 0; + c->failed_auth_attempts = 0; + c->state = disconnected; + CheckAndSetTrayIcon(); + SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_DISCONNECTED)); + SetStatusWinIcon(c->hwndStatus, ID_ICO_DISCONNECTED); + EnableWindow(GetDlgItem(c->hwndStatus, ID_DISCONNECT), FALSE); + EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), FALSE); + if (o.silent_connection == 0) + { + SetForegroundWindow(c->hwndStatus); + ShowWindow(c->hwndStatus, SW_SHOW); + } + MessageBoxExW(c->hwndStatus, LoadLocalizedString(IDS_NFO_CONN_TERMINATED, c->config_file), + _T(PACKAGE_NAME), MB_OK | MBOX_RTL_FLAGS, GetGUILanguage()); + SendMessage(c->hwndStatus, WM_CLOSE, 0, 0); + break; - case disconnecting: - /* Shutdown was initiated by us */ - c->failed_psw_attempts = 0; - c->failed_auth_attempts = 0; - c->state = disconnected; - if (c->flags & FLAG_DAEMON_PERSISTENT) - { - /* user initiated disconnection -- stay detached and do not auto-reconnect */ - c->auto_connect = false; - } - CheckAndSetTrayIcon(); - SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_DISCONNECTED)); - SendMessage(c->hwndStatus, WM_CLOSE, 0, 0); - break; + case resuming: + case connecting: + case reconnecting: + /* We have failed to (re)connect */ + txt_id = c->state == reconnecting ? IDS_NFO_STATE_FAILED_RECONN : IDS_NFO_STATE_FAILED; + msg_id = c->state == reconnecting ? IDS_NFO_RECONN_FAILED : IDS_NFO_CONN_FAILED; + + c->state = disconnecting; + CheckAndSetTrayIcon(); + c->state = disconnected; + EnableWindow(GetDlgItem(c->hwndStatus, ID_DISCONNECT), FALSE); + EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), FALSE); + SetStatusWinIcon(c->hwndStatus, ID_ICO_DISCONNECTED); + SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(txt_id)); + if (o.silent_connection == 0) + { + SetForegroundWindow(c->hwndStatus); + ShowWindow(c->hwndStatus, SW_SHOW); + } + MessageBoxExW(c->hwndStatus, LoadLocalizedString(msg_id, c->config_name), + _T(PACKAGE_NAME), MB_OK | MBOX_RTL_FLAGS, GetGUILanguage()); + SendMessage(c->hwndStatus, WM_CLOSE, 0, 0); + break; + + case disconnecting: + /* Shutdown was initiated by us */ + c->failed_psw_attempts = 0; + c->failed_auth_attempts = 0; + c->state = disconnected; + if (c->flags & FLAG_DAEMON_PERSISTENT) + { + /* user initiated disconnection -- stay detached and do not auto-reconnect */ + c->auto_connect = false; + } + CheckAndSetTrayIcon(); + SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_DISCONNECTED)); + SendMessage(c->hwndStatus, WM_CLOSE, 0, 0); + break; - case onhold: + case onhold: /* stop triggered while on hold -- possibly the daemon exited. Treat same as detaching */ - case detaching: - c->state = disconnected; - CheckAndSetTrayIcon(); - SendMessage(c->hwndStatus, WM_CLOSE, 0, 0); - break; + case detaching: + c->state = disconnected; + CheckAndSetTrayIcon(); + SendMessage(c->hwndStatus, WM_CLOSE, 0, 0); + break; - case suspending: - c->state = suspended; - CheckAndSetTrayIcon(); - SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_SUSPENDED)); - break; + case suspending: + c->state = suspended; + CheckAndSetTrayIcon(); + SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_SUSPENDED)); + break; - default: - break; + default: + break; } } @@ -1484,15 +1601,18 @@ format_bytecount(wchar_t *buf, size_t len, unsigned long long c) * Handle bytecount report from OpenVPN * Expect bytes-in,bytes-out */ -void OnByteCount(connection_t *c, char *msg) +void +OnByteCount(connection_t *c, char *msg) { if (!msg || sscanf(msg, "%I64u,%I64u", &c->bytes_in, &c->bytes_out) != 2) + { return; + } wchar_t in[32], out[32]; format_bytecount(in, _countof(in), c->bytes_in); format_bytecount(out, _countof(out), c->bytes_out); SetDlgItemTextW(c->hwndStatus, ID_TXT_BYTECOUNT, - LoadLocalizedString(IDS_NFO_BYTECOUNT, in, out)); + LoadLocalizedString(IDS_NFO_BYTECOUNT, in, out)); } /* @@ -1500,7 +1620,8 @@ void OnByteCount(connection_t *c, char *msg) * WEB_AUTH::, OPEN_URL: and CR_TEXT:: messages * used by two-step authentication. */ -void OnInfoMsg(connection_t* c, char* msg) +void +OnInfoMsg(connection_t *c, char *msg) { PrintDebug(L"OnInfoMsg with msg = %hs", msg); @@ -1519,7 +1640,9 @@ void OnInfoMsg(connection_t* c, char* msg) *p = '\0'; wchar_t *flags = Widen(msg + 9); if (flags) - WriteStatusLog (c, L"GUI> Unsupported flags in WEB_AUTH request ignored: ", flags, false); + { + WriteStatusLog(c, L"GUI> Unsupported flags in WEB_AUTH request ignored: ", flags, false); + } free(flags); } url = Widen(p+1); @@ -1535,7 +1658,7 @@ void OnInfoMsg(connection_t* c, char* msg) } else if (strbegins(msg, "CR_TEXT:")) { - auth_param_t* param = (auth_param_t*)calloc(1, sizeof(auth_param_t)); + auth_param_t *param = (auth_param_t *)calloc(1, sizeof(auth_param_t)); if (!param) { WriteStatusLog(c, L"GUI> ", L"Error: Out of memory - ignoring CR_TEXT request", false); @@ -1558,7 +1681,7 @@ void OnInfoMsg(connection_t* c, char* msg) * Break a long line into shorter segments */ static WCHAR * -WrapLine (WCHAR *line) +WrapLine(WCHAR *line) { int i = 0; WCHAR *next = NULL; @@ -1567,11 +1690,22 @@ WrapLine (WCHAR *line) for (i = 0; *line; i++, ++line) { if ((*line == L'\r') || (*line == L'\n')) + { *line = L' '; - if (next && i > len) break; - if (iswspace(*line)) next = line; + } + if (next && i > len) + { + break; + } + if (iswspace(*line)) + { + next = line; + } + } + if (!*line) + { + next = NULL; } - if (!*line) next = NULL; if (next) { *next = L'\0'; @@ -1584,19 +1718,22 @@ WrapLine (WCHAR *line) * Write a line to the status log window and optionally to the log file */ void -WriteStatusLog (connection_t *c, const WCHAR *prefix, const WCHAR *line, BOOL fileio) +WriteStatusLog(connection_t *c, const WCHAR *prefix, const WCHAR *line, BOOL fileio) { /* this can be called without connection (AS profile import), so do nothing in this case */ - if (!c) return; + if (!c) + { + return; + } HWND logWnd = GetDlgItem(c->hwndStatus, ID_EDT_LOG); FILE *log_fd; time_t now; WCHAR datetime[26]; - time (&now); + time(&now); /* TODO: change this to use _wctime_s when mingw supports it */ - wcsncpy (datetime, _wctime(&now), _countof(datetime)); + wcsncpy(datetime, _wctime(&now), _countof(datetime)); datetime[24] = L' '; /* change text color if Warning or Error */ @@ -1616,8 +1753,7 @@ WriteStatusLog (connection_t *c, const WCHAR *prefix, const WCHAR *line, BOOL fi CHARFORMAT cfm = { .cbSize = sizeof(CHARFORMAT), .dwMask = CFM_COLOR|CFM_BOLD, .dwEffects = 0, - .crTextColor = text_clr, - }; + .crTextColor = text_clr, }; SendMessage(logWnd, EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM) &cfm); } @@ -1636,26 +1772,33 @@ WriteStatusLog (connection_t *c, const WCHAR *prefix, const WCHAR *line, BOOL fi SendMessage(logWnd, EM_REPLACESEL, FALSE, (LPARAM) line); SendMessage(logWnd, EM_REPLACESEL, FALSE, (LPARAM) L"\n"); - if (!fileio) return; + if (!fileio) + { + return; + } - log_fd = _tfopen (c->log_path, TEXT("at+,ccs=UTF-8")); + log_fd = _tfopen(c->log_path, TEXT("at+,ccs=UTF-8")); if (log_fd) { - fwprintf (log_fd, L"%ls%ls%ls\n", datetime, prefix, line); - fclose (log_fd); + fwprintf(log_fd, L"%ls%ls%ls\n", datetime, prefix, line); + fclose(log_fd); } } #define IO_TIMEOUT 5000 /* milliseconds */ static void -CloseServiceIO (service_io_t *s) +CloseServiceIO(service_io_t *s) { if (s->hEvent) + { CloseHandle(s->hEvent); + } s->hEvent = NULL; if (s->pipe && s->pipe != INVALID_HANDLE_VALUE) + { CloseHandle(s->pipe); + } s->pipe = NULL; } @@ -1664,29 +1807,29 @@ CloseServiceIO (service_io_t *s) * Failure is not fatal. */ static BOOL -InitServiceIO (service_io_t *s) +InitServiceIO(service_io_t *s) { DWORD dwMode = o.ovpn_engine == OPENVPN_ENGINE_OVPN3 ? PIPE_READMODE_BYTE : PIPE_READMODE_MESSAGE; CLEAR(*s); /* auto-reset event used for signalling i/o completion*/ - s->hEvent = CreateEvent (NULL, FALSE, FALSE, NULL); + s->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (!s->hEvent) { return FALSE; } - s->pipe = CreateFile (o.ovpn_engine == OPENVPN_ENGINE_OVPN3 ? - OPENVPN_SERVICE_PIPE_NAME_OVPN3 : OPENVPN_SERVICE_PIPE_NAME_OVPN2, - GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); + s->pipe = CreateFile(o.ovpn_engine == OPENVPN_ENGINE_OVPN3 ? + OPENVPN_SERVICE_PIPE_NAME_OVPN3 : OPENVPN_SERVICE_PIPE_NAME_OVPN2, + GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); - if ( !s->pipe || - s->pipe == INVALID_HANDLE_VALUE || - !SetNamedPipeHandleState(s->pipe, &dwMode, NULL, NULL) - ) + if (!s->pipe + || s->pipe == INVALID_HANDLE_VALUE + || !SetNamedPipeHandleState(s->pipe, &dwMode, NULL, NULL) + ) { - CloseServiceIO (s); + CloseServiceIO(s); return FALSE; } @@ -1698,7 +1841,7 @@ InitServiceIO (service_io_t *s) * err = 0, bytes = 0 to queue a new read request. */ static void WINAPI -HandleServiceIO (DWORD err, DWORD bytes, LPOVERLAPPED lpo) +HandleServiceIO(DWORD err, DWORD bytes, LPOVERLAPPED lpo) { service_io_t *s = (service_io_t *) lpo; int len, capacity; @@ -1711,19 +1854,19 @@ HandleServiceIO (DWORD err, DWORD bytes, LPOVERLAPPED lpo) /* messages from the service are not nul terminated */ int nchars = bytes/sizeof(s->readbuf[0]); s->readbuf[nchars] = L'\0'; - SetEvent (s->hEvent); + SetEvent(s->hEvent); return; } if (err) { _snwprintf(s->readbuf, len, L"0x%08x\nInteractive Service disconnected\n", err); s->readbuf[len-1] = L'\0'; - SetEvent (s->hEvent); + SetEvent(s->hEvent); return; } /* Otherwise queue next read request */ - ReadFileEx (s->pipe, s->readbuf, capacity, lpo, HandleServiceIO); + ReadFileEx(s->pipe, s->readbuf, capacity, lpo, HandleServiceIO); /* Any error in the above call will get checked in next round */ } @@ -1732,27 +1875,31 @@ HandleServiceIO (DWORD err, DWORD bytes, LPOVERLAPPED lpo) * Retun value: TRUE on success FLASE on error */ static BOOL -WritePipe (HANDLE pipe, LPVOID buf, DWORD size) +WritePipe(HANDLE pipe, LPVOID buf, DWORD size) { OVERLAPPED o; BOOL retval = FALSE; CLEAR(o); - o.hEvent = CreateEvent (NULL, TRUE, FALSE, NULL); + o.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if (!o.hEvent) { return retval; } - if (WriteFile (pipe, buf, size, NULL, &o) || - GetLastError() == ERROR_IO_PENDING ) + if (WriteFile(pipe, buf, size, NULL, &o) + || GetLastError() == ERROR_IO_PENDING) { if (WaitForSingleObject(o.hEvent, IO_TIMEOUT) == WAIT_OBJECT_0) + { retval = TRUE; + } else - CancelIo (pipe); - // TODO report error -- timeout + { + CancelIo(pipe); + } + /* TODO report error -- timeout */ } CloseHandle(o.hEvent); @@ -1777,51 +1924,62 @@ OnService(connection_t *c, UNUSED char *msg) buf = wcsdup(c->iserv.readbuf); HandleServiceIO(0, 0, (LPOVERLAPPED) &c->iserv); - if (buf == NULL) return; + if (buf == NULL) + { + return; + } /* messages from the service are in the format "0x08x\n%s\n%s" */ - if (swscanf (buf, L"0x%08x\n", &err) != 1) + if (swscanf(buf, L"0x%08x\n", &err) != 1) { - free (buf); + free(buf); return; } p = buf + 11; /* next line is the pid if followed by "\nProcess ID" */ - if (!err && wcsstr(p, L"\nProcess ID") && swscanf (p, L"0x%08x", &pid) == 1 && pid != 0) + if (!err && wcsstr(p, L"\nProcess ID") && swscanf(p, L"0x%08x", &pid) == 1 && pid != 0) { - PrintDebug (L"Process ID of openvpn started by IService: %d", pid); - c->hProcess = OpenProcess (PROCESS_TERMINATE|PROCESS_QUERY_INFORMATION, FALSE, pid); + PrintDebug(L"Process ID of openvpn started by IService: %d", pid); + c->hProcess = OpenProcess(PROCESS_TERMINATE|PROCESS_QUERY_INFORMATION, FALSE, pid); if (!c->hProcess) - PrintDebug (L"Failed to get process handle from pid of openvpn: error = %lu", - GetLastError()); - free (buf); + { + PrintDebug(L"Failed to get process handle from pid of openvpn: error = %lu", + GetLastError()); + } + free(buf); return; } - while (iswspace(*p)) ++p; + while (iswspace(*p)) + { + ++p; + } while (p && *p) { - next = WrapLine (p); - WriteStatusLog (c, prefix, p, false); + next = WrapLine(p); + WriteStatusLog(c, prefix, p, false); p = next; } - free (buf); + free(buf); /* Error from iservice before management interface is connected */ switch (err) { case 0: break; + case ERROR_STARTUP_DATA: - WriteStatusLog (c, prefix, L"OpenVPN not started due to previous errors", true); - OnStop (c, NULL); + WriteStatusLog(c, prefix, L"OpenVPN not started due to previous errors", true); + OnStop(c, NULL); break; + case ERROR_OPENVPN_STARTUP: - WriteStatusLog (c, prefix, L"Check the log file for details", false); + WriteStatusLog(c, prefix, L"Check the log file for details", false); OnStop(c, NULL); break; + default: OnStop(c, NULL); break; @@ -1832,27 +1990,29 @@ OnService(connection_t *c, UNUSED char *msg) * Called when the directly started openvpn process exits */ static void -OnProcess (connection_t *c, UNUSED char *msg) +OnProcess(connection_t *c, UNUSED char *msg) { DWORD err; WCHAR tmp[256]; if (!GetExitCodeProcess(c->hProcess, &err) || err == STILL_ACTIVE) + { return; + } _snwprintf(tmp, _countof(tmp), L"OpenVPN terminated with exit code %lu. " - L"See the log file for details", err); + L"See the log file for details", err); tmp[_countof(tmp)-1] = L'\0'; WriteStatusLog(c, L"OpenVPN GUI> ", tmp, false); - OnStop (c, NULL); + OnStop(c, NULL); } /* * Called when NEED-OK is received */ void -OnNeedOk (connection_t *c, char *msg) +OnNeedOk(connection_t *c, char *msg) { char *resp = NULL; WCHAR *wstr = NULL; @@ -1865,10 +2025,12 @@ OnNeedOk (connection_t *c, char *msg) return; } if (!parse_input_request(msg, param)) + { goto out; + } /* allocate space for response : "needok param->id cancel/ok" */ - resp = malloc (strlen(param->id) + strlen("needok \' \' cancel")); + resp = malloc(strlen(param->id) + strlen("needok \' \' cancel")); wstr = Widen(param->str); if (!wstr || !resp) @@ -1885,15 +2047,15 @@ OnNeedOk (connection_t *c, char *msg) } else { - ManagementCommand (c, "auth-retry none", NULL, regular); + ManagementCommand(c, "auth-retry none", NULL, regular); fmt = "needok \'%s\' cancel"; } - sprintf (resp, fmt, param->id); - ManagementCommand (c, resp, NULL, regular); + sprintf(resp, fmt, param->id); + ManagementCommand(c, resp, NULL, regular); out: - free_auth_param (param); + free_auth_param(param); free(wstr); free(resp); } @@ -1902,7 +2064,7 @@ out: * Called when NEED-STR is received */ void -OnNeedStr (connection_t *c, UNUSED char *msg) +OnNeedStr(connection_t *c, UNUSED char *msg) { if (strstr(msg, "Need 'pkcs11-id-request'")) { @@ -1910,7 +2072,7 @@ OnNeedStr (connection_t *c, UNUSED char *msg) OnPkcs11(c, msg ? msg + 4 : ""); return; } - WriteStatusLog (c, L"GUI> ", L"Error: Received NEED-STR message -- not implemented", false); + WriteStatusLog(c, L"GUI> ", L"Error: Received NEED-STR message -- not implemented", false); } /* Stop the connection -- this sets the daemon to exit if @@ -1944,25 +2106,31 @@ DisconnectDaemon(connection_t *c) * Close open handles */ static void -Cleanup (connection_t *c) +Cleanup(connection_t *c) { - CloseManagement (c); + CloseManagement(c); - free_dynamic_cr (c); + free_dynamic_cr(c); env_item_del_all(c->es); c->es = NULL; echo_msg_clear(c, true); /* clear history */ pkcs11_list_clear(&c->pkcs11_list); if (c->hProcess) - CloseHandle (c->hProcess); + { + CloseHandle(c->hProcess); + } c->hProcess = NULL; if (c->iserv.hEvent) - CloseServiceIO (&c->iserv); + { + CloseServiceIO(&c->iserv); + } if (c->exit_event) - CloseHandle (c->exit_event); + { + CloseHandle(c->exit_event); + } c->exit_event = NULL; c->daemon_state[0] = '\0'; } @@ -1973,15 +2141,15 @@ Cleanup (connection_t *c) void RenderStatusWindow(HWND hwndDlg, UINT w, UINT h) { - MoveWindow(GetDlgItem(hwndDlg, ID_EDT_LOG), DPI_SCALE(20), DPI_SCALE(25), w - DPI_SCALE(40), h - DPI_SCALE(110), TRUE); - MoveWindow(GetDlgItem(hwndDlg, ID_TXT_STATUS), DPI_SCALE(20), DPI_SCALE(5), w-DPI_SCALE(30), DPI_SCALE(15), TRUE); - MoveWindow(GetDlgItem(hwndDlg, ID_TXT_IP), DPI_SCALE(20), h - DPI_SCALE(75), w-DPI_SCALE(30), DPI_SCALE(15), TRUE); - MoveWindow(GetDlgItem(hwndDlg, ID_TXT_BYTECOUNT), DPI_SCALE(20), h - DPI_SCALE(55), w-DPI_SCALE(210), DPI_SCALE(15), TRUE); - MoveWindow(GetDlgItem(hwndDlg, ID_TXT_VERSION), w-DPI_SCALE(180), h - DPI_SCALE(55), DPI_SCALE(170), DPI_SCALE(15), TRUE); - MoveWindow(GetDlgItem(hwndDlg, ID_DISCONNECT), DPI_SCALE(20), h - DPI_SCALE(30), DPI_SCALE(110), DPI_SCALE(23), TRUE); - MoveWindow(GetDlgItem(hwndDlg, ID_RESTART), DPI_SCALE(145), h - DPI_SCALE(30), DPI_SCALE(110), DPI_SCALE(23), TRUE); - MoveWindow(GetDlgItem(hwndDlg, ID_DETACH), DPI_SCALE(270), h - DPI_SCALE(30), DPI_SCALE(110), DPI_SCALE(23), TRUE); - MoveWindow(GetDlgItem(hwndDlg, ID_HIDE), w - DPI_SCALE(130), h - DPI_SCALE(30), DPI_SCALE(110), DPI_SCALE(23), TRUE); + MoveWindow(GetDlgItem(hwndDlg, ID_EDT_LOG), DPI_SCALE(20), DPI_SCALE(25), w - DPI_SCALE(40), h - DPI_SCALE(110), TRUE); + MoveWindow(GetDlgItem(hwndDlg, ID_TXT_STATUS), DPI_SCALE(20), DPI_SCALE(5), w-DPI_SCALE(30), DPI_SCALE(15), TRUE); + MoveWindow(GetDlgItem(hwndDlg, ID_TXT_IP), DPI_SCALE(20), h - DPI_SCALE(75), w-DPI_SCALE(30), DPI_SCALE(15), TRUE); + MoveWindow(GetDlgItem(hwndDlg, ID_TXT_BYTECOUNT), DPI_SCALE(20), h - DPI_SCALE(55), w-DPI_SCALE(210), DPI_SCALE(15), TRUE); + MoveWindow(GetDlgItem(hwndDlg, ID_TXT_VERSION), w-DPI_SCALE(180), h - DPI_SCALE(55), DPI_SCALE(170), DPI_SCALE(15), TRUE); + MoveWindow(GetDlgItem(hwndDlg, ID_DISCONNECT), DPI_SCALE(20), h - DPI_SCALE(30), DPI_SCALE(110), DPI_SCALE(23), TRUE); + MoveWindow(GetDlgItem(hwndDlg, ID_RESTART), DPI_SCALE(145), h - DPI_SCALE(30), DPI_SCALE(110), DPI_SCALE(23), TRUE); + MoveWindow(GetDlgItem(hwndDlg, ID_DETACH), DPI_SCALE(270), h - DPI_SCALE(30), DPI_SCALE(110), DPI_SCALE(23), TRUE); + MoveWindow(GetDlgItem(hwndDlg, ID_HIDE), w - DPI_SCALE(130), h - DPI_SCALE(30), DPI_SCALE(110), DPI_SCALE(23), TRUE); } /* @@ -1994,220 +2162,230 @@ StatusDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) switch (msg) { - case WM_MANAGEMENT: - /* Management interface related event */ - OnManagement(wParam, lParam); - return TRUE; + case WM_MANAGEMENT: + /* Management interface related event */ + OnManagement(wParam, lParam); + return TRUE; - case WM_INITDIALOG: - c = (connection_t *) lParam; + case WM_INITDIALOG: + c = (connection_t *) lParam; - /* Set window icon "disconnected" */ - SetStatusWinIcon(hwndDlg, ID_ICO_CONNECTING); + /* Set window icon "disconnected" */ + SetStatusWinIcon(hwndDlg, ID_ICO_CONNECTING); - /* Set connection for this dialog */ - if (!SetPropW(hwndDlg, cfgProp, (HANDLE) c)) - { - MsgToEventLog(EVENTLOG_ERROR_TYPE, L"%hs:%d SetProp failed (error = 0x%08x)", - __func__, __LINE__, GetLastError()); - DisconnectDaemon(c); - DestroyWindow(hwndDlg); - break; - } + /* Set connection for this dialog */ + if (!SetPropW(hwndDlg, cfgProp, (HANDLE) c)) + { + MsgToEventLog(EVENTLOG_ERROR_TYPE, L"%hs:%d SetProp failed (error = 0x%08x)", + __func__, __LINE__, GetLastError()); + DisconnectDaemon(c); + DestroyWindow(hwndDlg); + break; + } - /* Create log window */ - HWND hLogWnd = CreateWindowEx(0, RICHEDIT_CLASS, NULL, - WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|ES_SUNKEN|ES_LEFT| - ES_MULTILINE|ES_READONLY|ES_AUTOHSCROLL|ES_AUTOVSCROLL, - 20, 25, 350, 160, hwndDlg, (HMENU) ID_EDT_LOG, o.hInstance, NULL); - if (!hLogWnd) - { - ShowLocalizedMsgEx(MB_OK|MB_ICONERROR, c->hwndStatus, TEXT(PACKAGE_NAME), IDS_ERR_CREATE_EDIT_LOGWINDOW); - /* We can't continue without a log window */ - StopOpenVPN(c); - return FALSE; - } + /* Create log window */ + HWND hLogWnd = CreateWindowEx(0, RICHEDIT_CLASS, NULL, + WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|ES_SUNKEN|ES_LEFT + |ES_MULTILINE|ES_READONLY|ES_AUTOHSCROLL|ES_AUTOVSCROLL, + 20, 25, 350, 160, hwndDlg, (HMENU) ID_EDT_LOG, o.hInstance, NULL); + if (!hLogWnd) + { + ShowLocalizedMsgEx(MB_OK|MB_ICONERROR, c->hwndStatus, TEXT(PACKAGE_NAME), IDS_ERR_CREATE_EDIT_LOGWINDOW); + /* We can't continue without a log window */ + StopOpenVPN(c); + return FALSE; + } - /* Set font and fontsize of the log window */ - CHARFORMAT cfm = { - .cbSize = sizeof(CHARFORMAT), - .dwMask = CFM_SIZE|CFM_FACE|CFM_BOLD, - .szFaceName = _T("Microsoft Sans Serif"), - .dwEffects = 0, - .yHeight = 160 - }; - if (SendMessage(hLogWnd, EM_SETCHARFORMAT, SCF_DEFAULT, (LPARAM) &cfm) == 0) - ShowLocalizedMsgEx(MB_OK|MB_ICONERROR, c->hwndStatus, TEXT(PACKAGE_NAME), IDS_ERR_SET_SIZE); - - /* display version string as "OpenVPN GUI gui_version/core_version" */ - wchar_t version[256]; - _sntprintf_0(version, L"%hs %hs/%hs", PACKAGE_NAME, PACKAGE_VERSION_RESOURCE_STR, o.ovpn_version) - SetDlgItemText(hwndDlg, ID_TXT_VERSION, version); - - /* Set size and position of controls */ - RECT rect; - GetWindowRect(hwndDlg, &rect); - /* Move the window by upto 100 random pixels to avoid all - * status windows fall on top of each other. - */ - SetWindowPos(hwndDlg, HWND_TOP, rect.left + rand()%100, - rect.top + rand()%100, 0, 0, SWP_NOSIZE); - GetClientRect(hwndDlg, &rect); - RenderStatusWindow(hwndDlg, rect.right, rect.bottom); - if (c->flags & FLAG_DAEMON_PERSISTENT && o.enable_persistent > 0) - { - EnableWindow(GetDlgItem(hwndDlg, ID_DETACH), TRUE); - } - else - { - ShowWindow(GetDlgItem(hwndDlg, ID_DETACH), SW_HIDE); - } - /* Set focus on the LogWindow so it scrolls automatically */ - SetFocus(hLogWnd); - return FALSE; + /* Set font and fontsize of the log window */ + CHARFORMAT cfm = { + .cbSize = sizeof(CHARFORMAT), + .dwMask = CFM_SIZE|CFM_FACE|CFM_BOLD, + .szFaceName = _T("Microsoft Sans Serif"), + .dwEffects = 0, + .yHeight = 160 + }; + if (SendMessage(hLogWnd, EM_SETCHARFORMAT, SCF_DEFAULT, (LPARAM) &cfm) == 0) + { + ShowLocalizedMsgEx(MB_OK|MB_ICONERROR, c->hwndStatus, TEXT(PACKAGE_NAME), IDS_ERR_SET_SIZE); + } - case WM_DPICHANGED: - DpiSetScale(&o, HIWORD(wParam)); - RECT dlgRect; - GetClientRect(hwndDlg, &dlgRect); - RenderStatusWindow(hwndDlg, dlgRect.right, dlgRect.bottom); - return FALSE; + /* display version string as "OpenVPN GUI gui_version/core_version" */ + wchar_t version[256]; + _sntprintf_0(version, L"%hs %hs/%hs", PACKAGE_NAME, PACKAGE_VERSION_RESOURCE_STR, o.ovpn_version) + SetDlgItemText(hwndDlg, ID_TXT_VERSION, version); - case WM_SIZE: - RenderStatusWindow(hwndDlg, LOWORD(lParam), HIWORD(lParam)); - InvalidateRect(hwndDlg, NULL, TRUE); - return TRUE; + /* Set size and position of controls */ + RECT rect; + GetWindowRect(hwndDlg, &rect); + /* Move the window by upto 100 random pixels to avoid all + * status windows fall on top of each other. + */ + SetWindowPos(hwndDlg, HWND_TOP, rect.left + rand()%100, + rect.top + rand()%100, 0, 0, SWP_NOSIZE); + GetClientRect(hwndDlg, &rect); + RenderStatusWindow(hwndDlg, rect.right, rect.bottom); + if (c->flags & FLAG_DAEMON_PERSISTENT && o.enable_persistent > 0) + { + EnableWindow(GetDlgItem(hwndDlg, ID_DETACH), TRUE); + } + else + { + ShowWindow(GetDlgItem(hwndDlg, ID_DETACH), SW_HIDE); + } + /* Set focus on the LogWindow so it scrolls automatically */ + SetFocus(hLogWnd); + return FALSE; - case WM_COMMAND: - c = (connection_t *) GetProp(hwndDlg, cfgProp); - switch (LOWORD(wParam)) - { - case ID_DISCONNECT: - SetFocus(GetDlgItem(c->hwndStatus, ID_EDT_LOG)); - StopOpenVPN(c); + case WM_DPICHANGED: + DpiSetScale(&o, HIWORD(wParam)); + RECT dlgRect; + GetClientRect(hwndDlg, &dlgRect); + RenderStatusWindow(hwndDlg, dlgRect.right, dlgRect.bottom); + return FALSE; + + case WM_SIZE: + RenderStatusWindow(hwndDlg, LOWORD(lParam), HIWORD(lParam)); + InvalidateRect(hwndDlg, NULL, TRUE); return TRUE; - case ID_HIDE: - if (c->state != disconnected) + case WM_COMMAND: + c = (connection_t *) GetProp(hwndDlg, cfgProp); + switch (LOWORD(wParam)) + { + case ID_DISCONNECT: + SetFocus(GetDlgItem(c->hwndStatus, ID_EDT_LOG)); + StopOpenVPN(c); + return TRUE; + + case ID_HIDE: + if (c->state != disconnected) + { + ShowWindow(hwndDlg, SW_HIDE); + } + else + { + DestroyWindow(hwndDlg); + } + return TRUE; + + case ID_RESTART: + SetFocus(GetDlgItem(c->hwndStatus, ID_EDT_LOG)); + RestartOpenVPN(c); + return TRUE; + + case ID_DETACH: + SetFocus(GetDlgItem(c->hwndStatus, ID_EDT_LOG)); + DetachOpenVPN(c); + return TRUE; + } + break; + + case WM_SHOWWINDOW: + if (wParam == TRUE) + { + SetFocus(GetDlgItem(hwndDlg, ID_EDT_LOG)); + } + return FALSE; + + case WM_CLOSE: + c = (connection_t *) GetProp(hwndDlg, cfgProp); + if (c->state != disconnected && c->state != detached) + { ShowWindow(hwndDlg, SW_HIDE); + } else + { DestroyWindow(hwndDlg); + } return TRUE; - case ID_RESTART: - SetFocus(GetDlgItem(c->hwndStatus, ID_EDT_LOG)); - RestartOpenVPN(c); - return TRUE; - - case ID_DETACH: - SetFocus(GetDlgItem(c->hwndStatus, ID_EDT_LOG)); - DetachOpenVPN(c); - return TRUE; - } - break; - - case WM_SHOWWINDOW: - if (wParam == TRUE) - { - SetFocus(GetDlgItem(hwndDlg, ID_EDT_LOG)); - } - return FALSE; - - case WM_CLOSE: - c = (connection_t *) GetProp(hwndDlg, cfgProp); - if (c->state != disconnected && c->state != detached) - ShowWindow(hwndDlg, SW_HIDE); - else - DestroyWindow(hwndDlg); - return TRUE; - - case WM_NCDESTROY: - KillTimer(hwndDlg, IDT_STOP_TIMER); - RemoveProp(hwndDlg, cfgProp); - break; - - case WM_DESTROY: - PostQuitMessage(0); - break; - - case WM_OVPN_RELEASE: - c = (connection_t *) GetProp(hwndDlg, cfgProp); - c->state = reconnecting; - SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_RECONNECTING)); - SetDlgItemTextW(c->hwndStatus, ID_TXT_IP, L""); - SetStatusWinIcon(c->hwndStatus, ID_ICO_CONNECTING); - OnHold(c, ""); - break; - - case WM_OVPN_STOP: - c = (connection_t *) GetProp(hwndDlg, cfgProp); - /* external messages can trigger when we are not ready -- check the state */ - if (!IsWindowEnabled(GetDlgItem(c->hwndStatus, ID_DISCONNECT)) - || c->state == onhold) - { + case WM_NCDESTROY: + KillTimer(hwndDlg, IDT_STOP_TIMER); + RemoveProp(hwndDlg, cfgProp); break; - } - c->state = disconnecting; - if (!(c->flags & FLAG_DAEMON_PERSISTENT)) - { - RunDisconnectScript(c, false); - } - EnableWindow(GetDlgItem(c->hwndStatus, ID_DISCONNECT), FALSE); - EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), FALSE); - SetMenuStatus(c, disconnecting); - SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_WAIT_TERM)); - DisconnectDaemon(c); - break; - - case WM_OVPN_DETACH: - c = (connection_t *) GetProp(hwndDlg, cfgProp); - /* just stop the thread keeping openvpn.exe running */ - c->state = detaching; - EnableWindow(GetDlgItem(c->hwndStatus, ID_DISCONNECT), FALSE); - EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), FALSE); - OnStop(c, NULL); - break; - - case WM_OVPN_SUSPEND: - c = (connection_t *) GetProp(hwndDlg, cfgProp); - c->state = suspending; - EnableWindow(GetDlgItem(c->hwndStatus, ID_DISCONNECT), FALSE); - EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), FALSE); - SetMenuStatus(c, disconnecting); - SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_WAIT_TERM)); - SetEvent(c->exit_event); - SetTimer(hwndDlg, IDT_STOP_TIMER, 15000, NULL); - break; - case WM_TIMER: - PrintDebug(L"WM_TIMER message with wParam = %lu", wParam); - c = (connection_t *) GetProp(hwndDlg, cfgProp); - if (wParam == IDT_STOP_TIMER) - { - /* openvpn failed to respond to stop signal -- terminate */ - TerminateOpenVPN(c); - KillTimer (hwndDlg, IDT_STOP_TIMER); - OnStop(c, NULL); - } - break; + case WM_DESTROY: + PostQuitMessage(0); + break; - case WM_OVPN_RESTART: - c = (connection_t *) GetProp(hwndDlg, cfgProp); - /* external messages can trigger when we are not ready -- check the state */ - if (IsWindowEnabled(GetDlgItem(c->hwndStatus, ID_RESTART))) - { + case WM_OVPN_RELEASE: + c = (connection_t *) GetProp(hwndDlg, cfgProp); c->state = reconnecting; - ManagementCommand(c, "signal SIGHUP", NULL, regular); SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_RECONNECTING)); SetDlgItemTextW(c->hwndStatus, ID_TXT_IP, L""); SetStatusWinIcon(c->hwndStatus, ID_ICO_CONNECTING); - } - if (!o.silent_connection) - { - SetForegroundWindow(c->hwndStatus); - ShowWindow(c->hwndStatus, SW_SHOW); - } - break; + OnHold(c, ""); + break; + + case WM_OVPN_STOP: + c = (connection_t *) GetProp(hwndDlg, cfgProp); + /* external messages can trigger when we are not ready -- check the state */ + if (!IsWindowEnabled(GetDlgItem(c->hwndStatus, ID_DISCONNECT)) + || c->state == onhold) + { + break; + } + c->state = disconnecting; + if (!(c->flags & FLAG_DAEMON_PERSISTENT)) + { + RunDisconnectScript(c, false); + } + EnableWindow(GetDlgItem(c->hwndStatus, ID_DISCONNECT), FALSE); + EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), FALSE); + SetMenuStatus(c, disconnecting); + SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_WAIT_TERM)); + DisconnectDaemon(c); + break; + + case WM_OVPN_DETACH: + c = (connection_t *) GetProp(hwndDlg, cfgProp); + /* just stop the thread keeping openvpn.exe running */ + c->state = detaching; + EnableWindow(GetDlgItem(c->hwndStatus, ID_DISCONNECT), FALSE); + EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), FALSE); + OnStop(c, NULL); + break; + + case WM_OVPN_SUSPEND: + c = (connection_t *) GetProp(hwndDlg, cfgProp); + c->state = suspending; + EnableWindow(GetDlgItem(c->hwndStatus, ID_DISCONNECT), FALSE); + EnableWindow(GetDlgItem(c->hwndStatus, ID_RESTART), FALSE); + SetMenuStatus(c, disconnecting); + SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_WAIT_TERM)); + SetEvent(c->exit_event); + SetTimer(hwndDlg, IDT_STOP_TIMER, 15000, NULL); + break; + + case WM_TIMER: + PrintDebug(L"WM_TIMER message with wParam = %lu", wParam); + c = (connection_t *) GetProp(hwndDlg, cfgProp); + if (wParam == IDT_STOP_TIMER) + { + /* openvpn failed to respond to stop signal -- terminate */ + TerminateOpenVPN(c); + KillTimer(hwndDlg, IDT_STOP_TIMER); + OnStop(c, NULL); + } + break; + + case WM_OVPN_RESTART: + c = (connection_t *) GetProp(hwndDlg, cfgProp); + /* external messages can trigger when we are not ready -- check the state */ + if (IsWindowEnabled(GetDlgItem(c->hwndStatus, ID_RESTART))) + { + c->state = reconnecting; + ManagementCommand(c, "signal SIGHUP", NULL, regular); + SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_RECONNECTING)); + SetDlgItemTextW(c->hwndStatus, ID_TXT_IP, L""); + SetStatusWinIcon(c->hwndStatus, ID_ICO_CONNECTING); + } + if (!o.silent_connection) + { + SetForegroundWindow(c->hwndStatus); + ShowWindow(c->hwndStatus, SW_SHOW); + } + break; } return FALSE; } @@ -2223,7 +2401,7 @@ ThreadOpenVPNStatus(void *p) MSG msg; HANDLE wait_event; - CLEAR (msg); + CLEAR(msg); srand(c->threadId); /* Cut of extention from config filename. */ @@ -2249,14 +2427,14 @@ ThreadOpenVPNStatus(void *p) if (!OpenManagement(c)) { MessageBoxExW(c->hwndStatus, L"Failed to open management", _T(PACKAGE_NAME), - MB_OK | MB_SETFOREGROUND | MB_ICONERROR | MBOX_RTL_FLAGS, GetGUILanguage()); + MB_OK | MB_SETFOREGROUND | MB_ICONERROR | MBOX_RTL_FLAGS, GetGUILanguage()); StopOpenVPN(c); } /* Start the async read loop for service and set it as the wait event */ if (c->iserv.hEvent) { - HandleServiceIO (0, 0, (LPOVERLAPPED) &c->iserv); + HandleServiceIO(0, 0, (LPOVERLAPPED) &c->iserv); wait_event = c->iserv.hEvent; } else @@ -2268,7 +2446,7 @@ ThreadOpenVPNStatus(void *p) BOOL show_status_win = (o.silent_connection == 0); if ((c->flags & FLAG_DAEMON_PERSISTENT) && c->state == resuming) { - show_status_win = false; + show_status_win = false; } ShowWindow(c->hwndStatus, show_status_win ? SW_SHOW : SW_HIDE); @@ -2295,13 +2473,17 @@ ThreadOpenVPNStatus(void *p) } else if (!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - if ((res = MsgWaitForMultipleObjectsEx (1, &wait_event, INFINITE, QS_ALLINPUT, - MWMO_ALERTABLE)) == WAIT_OBJECT_0) + if ((res = MsgWaitForMultipleObjectsEx(1, &wait_event, INFINITE, QS_ALLINPUT, + MWMO_ALERTABLE)) == WAIT_OBJECT_0) { if (wait_event == c->hProcess) - OnProcess (c, NULL); + { + OnProcess(c, NULL); + } else if (wait_event == c->iserv.hEvent) - OnService (c, NULL); + { + OnService(c, NULL); + } } continue; } @@ -2314,7 +2496,7 @@ ThreadOpenVPNStatus(void *p) } /* release handles etc.*/ - Cleanup (c); + Cleanup(c); c->hwndStatus = NULL; return 0; } @@ -2327,15 +2509,25 @@ SetProcessPriority(DWORD *priority) { *priority = NORMAL_PRIORITY_CLASS; if (!_tcscmp(o.priority_string, _T("IDLE_PRIORITY_CLASS"))) + { *priority = IDLE_PRIORITY_CLASS; + } else if (!_tcscmp(o.priority_string, _T("BELOW_NORMAL_PRIORITY_CLASS"))) + { *priority = BELOW_NORMAL_PRIORITY_CLASS; + } else if (!_tcscmp(o.priority_string, _T("NORMAL_PRIORITY_CLASS"))) + { *priority = NORMAL_PRIORITY_CLASS; + } else if (!_tcscmp(o.priority_string, _T("ABOVE_NORMAL_PRIORITY_CLASS"))) + { *priority = ABOVE_NORMAL_PRIORITY_CLASS; + } else if (!_tcscmp(o.priority_string, _T("HIGH_PRIORITY_CLASS"))) + { *priority = HIGH_PRIORITY_CLASS; + } else { ShowLocalizedMsgEx(MB_OK|MB_ICONERROR, o.hWnd, TEXT(PACKAGE_NAME), IDS_ERR_UNKNOWN_PRIORITY, o.priority_string); @@ -2346,10 +2538,11 @@ SetProcessPriority(DWORD *priority) #ifdef ENABLE_OVPN3 inline static -struct json_object* json_object_new_utf16_string(wchar_t *utf16) +struct json_object * +json_object_new_utf16_string(wchar_t *utf16) { DWORD input_size = WideCharToMultiByte(CP_UTF8, 0, utf16, -1, NULL, 0, NULL, NULL); - struct json_object* jobj = NULL; + struct json_object *jobj = NULL; char *utf8 = malloc(input_size); if (!utf8) { @@ -2365,7 +2558,8 @@ out: return jobj; } -static char* PrepareStartJsonRequest(connection_t *c, wchar_t *exit_event_name) +static char * +PrepareStartJsonRequest(connection_t *c, wchar_t *exit_event_name) { const char *request_header = "POST /start HTTP/1.1\r\nContent-Type: application/json\r\nContent-Length: %zd\r\n\r\n"; json_object *jobj = json_object_new_object(); @@ -2382,7 +2576,7 @@ static char* PrepareStartJsonRequest(connection_t *c, wchar_t *exit_event_name) const char *body = json_object_to_json_string(jobj); int len = snprintf(NULL, 0, request_header, strlen(body)) + strlen(body) + 1; - char* request = calloc(1, len); + char *request = calloc(1, len); if (request == NULL) { goto out; @@ -2394,7 +2588,7 @@ out: json_object_put(jobj); return request; } -#endif +#endif /* ifdef ENABLE_OVPN3 */ /* If state is on hold -- release */ void @@ -2423,12 +2617,14 @@ StartOpenVPN(connection_t *c) PrintDebug(L"Connection request when already started -- ignored"); /* the tread can hang around after disconnect if user has not dismissed any popups */ if (c->state == disconnected) + { WriteStatusLog(c, L"OpenVPN GUI> ", - L"Complete any pending dialog before starting a new connection", false); + L"Complete any pending dialog before starting a new connection", false); + } if (!o.silent_connection) { - SetForegroundWindow(c->hwndStatus); - ShowWindow(c->hwndStatus, SW_SHOW); + SetForegroundWindow(c->hwndStatus); + ShowWindow(c->hwndStatus, SW_SHOW); } return FALSE; } @@ -2453,10 +2649,14 @@ StartOpenVPN(connection_t *c) { /* Show an error if manually connecting */ if (c->state == disconnected) + { ShowLocalizedMsgEx(MB_OK|MB_ICONERROR, o.hWnd, TEXT(PACKAGE_NAME), IDS_ERR_PARSE_MGMT_OPTION, c->config_dir, c->config_file); + } else + { c->state = disconnected; + } TerminateThread(hThread, 1); return false; } @@ -2474,7 +2674,9 @@ StartOpenVPN(connection_t *c) ResumeThread(hThread); if (hThread && hThread != INVALID_HANDLE_VALUE) + { CloseHandle(hThread); + } return true; } @@ -2517,13 +2719,13 @@ LaunchOpenVPN(connection_t *c) /* Construct command line -- put log first */ _sntprintf_0(cmdline, _T("openvpn --log%ls \"%ls\" --config \"%ls\" " - "--setenv IV_GUI_VER \"%hs\" --setenv IV_SSO openurl,webauth,crtext --service %ls 0 --auth-retry interact " - "--management %hs %hd stdin --management-query-passwords %ls" - "--management-hold"), - (o.log_append ? _T("-append") : _T("")), c->log_path, - c->config_file, PACKAGE_STRING, exit_event_name, - inet_ntoa(c->manage.skaddr.sin_addr), ntohs(c->manage.skaddr.sin_port), - (o.proxy_source != config ? _T("--management-query-proxy ") : _T(""))); + "--setenv IV_GUI_VER \"%hs\" --setenv IV_SSO openurl,webauth,crtext --service %ls 0 --auth-retry interact " + "--management %hs %hd stdin --management-query-passwords %ls" + "--management-hold"), + (o.log_append ? _T("-append") : _T("")), c->log_path, + c->config_file, PACKAGE_STRING, exit_event_name, + inet_ntoa(c->manage.skaddr.sin_addr), ntohs(c->manage.skaddr.sin_port), + (o.proxy_source != config ? _T("--management-query-proxy ") : _T(""))); BOOL use_iservice = (o.iservice_admin && IsWindows7OrGreater()) || !IsUserAdmin(); /* Try to open the service pipe */ @@ -2556,11 +2758,11 @@ LaunchOpenVPN(connection_t *c) c->manage.password[passwd_len - 1] = '\n'; /* Ignore pushed route-method when service is in use */ - const wchar_t* extra_options = L" --pull-filter ignore route-method"; + const wchar_t *extra_options = L" --pull-filter ignore route-method"; size += wcslen(extra_options); _sntprintf_0(startup_info, L"%ls%lc%ls%ls%lc%.*hs", c->config_dir, L'\0', - options, extra_options, L'\0', passwd_len, c->manage.password); + options, extra_options, L'\0', passwd_len, c->manage.password); c->manage.password[passwd_len - 1] = '\0'; res = WritePipe(c->iserv.pipe, startup_info, size * sizeof(TCHAR)); @@ -2650,7 +2852,7 @@ LaunchOpenVPN(connection_t *c) /* Create an OpenVPN process for the connection */ if (!CreateProcess(o.exe_path, cmdline, NULL, NULL, TRUE, - priority | CREATE_NO_WINDOW, NULL, c->config_dir, &si, &pi)) + priority | CREATE_NO_WINDOW, NULL, c->config_dir, &si, &pi)) { ShowLocalizedMsgEx(MB_OK|MB_ICONERROR, o.hWnd, TEXT(PACKAGE_NAME), IDS_ERR_CREATE_PROCESS, o.exe_path, cmdline, c->config_dir); CloseHandle(c->exit_event); @@ -2673,11 +2875,17 @@ LaunchOpenVPN(connection_t *c) out: if (hStdInWrite && hStdInWrite != INVALID_HANDLE_VALUE) + { CloseHandle(hStdInWrite); + } if (hStdInRead && hStdInRead != INVALID_HANDLE_VALUE) + { CloseHandle(hStdInRead); + } if (hNul && hNul != INVALID_HANDLE_VALUE) + { CloseHandle(hNul); + } return retval; } @@ -2689,7 +2897,7 @@ out: void DetachOpenVPN(connection_t *c) { - /* currently supported only for persistent connections */ + /* currently supported only for persistent connections */ if (c->flags & FLAG_DAEMON_PERSISTENT) { c->auto_connect = false; @@ -2705,28 +2913,36 @@ StopOpenVPN(connection_t *c) /* force-kill as a last resort */ static BOOL -TerminateOpenVPN (connection_t *c) +TerminateOpenVPN(connection_t *c) { DWORD exit_code = 0; BOOL retval = TRUE; if (!c->hProcess) + { return retval; - if (!GetExitCodeProcess (c->hProcess, &exit_code)) + } + if (!GetExitCodeProcess(c->hProcess, &exit_code)) { - PrintDebug (L"In TerminateOpenVPN: failed to get process status: error = %lu", GetLastError()); + PrintDebug(L"In TerminateOpenVPN: failed to get process status: error = %lu", GetLastError()); return FALSE; } if (exit_code == STILL_ACTIVE) { - retval = TerminateProcess (c->hProcess, 1); + retval = TerminateProcess(c->hProcess, 1); if (retval) - PrintDebug (L"Openvpn Process for config '%ls' terminated", c->config_name); + { + PrintDebug(L"Openvpn Process for config '%ls' terminated", c->config_name); + } else - PrintDebug (L"Failed to terminate openvpn Process for config '%ls'", c->config_name); + { + PrintDebug(L"Failed to terminate openvpn Process for config '%ls'", c->config_name); + } } else + { PrintDebug(L"In TerminateOpenVPN: Process is not active"); + } return retval; } @@ -2753,10 +2969,14 @@ SetStatusWinIcon(HWND hwndDlg, int iconId) { HICON hIcon = LoadLocalizedSmallIcon(iconId); if (!hIcon) + { return; + } HICON hIconBig = LoadLocalizedIcon(ID_ICO_APP); if (!hIconBig) + { hIconBig = hIcon; + } SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_SMALL, (LPARAM) hIcon); SendMessage(hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, (LPARAM) hIconBig); } @@ -2775,7 +2995,9 @@ ReadLineFromStdOut(HANDLE hStdOut, char *line, DWORD size) if (!PeekNamedPipe(hStdOut, line, size, &read, NULL, NULL)) { if (GetLastError() != ERROR_BROKEN_PIPE) + { ShowLocalizedMsg(IDS_ERR_READ_STDOUT_PIPE); + } return FALSE; } @@ -2784,13 +3006,17 @@ ReadLineFromStdOut(HANDLE hStdOut, char *line, DWORD size) { len = pos - line + 2; if (len > size) + { return FALSE; + } break; } /* Line doesn't fit into the buffer */ if (read == size) + { return FALSE; + } Sleep(100); /* called when no UI is yet initialized */ } @@ -2798,7 +3024,9 @@ ReadLineFromStdOut(HANDLE hStdOut, char *line, DWORD size) if (!ReadFile(hStdOut, line, len, &read, NULL) || read != len) { if (GetLastError() != ERROR_BROKEN_PIPE) + { ShowLocalizedMsg(IDS_ERR_READ_STDOUT_PIPE); + } return FALSE; } @@ -2858,7 +3086,9 @@ CheckVersion() _tcsncpy(pwd, o.exe_path, _countof(pwd)); p = _tcsrchr(pwd, _T('\\')); if (p != NULL) + { *p = _T('\0'); + } /* Fill in STARTUPINFO struct */ si.cb = sizeof(si); @@ -2869,7 +3099,7 @@ CheckVersion() /* Start OpenVPN to check version */ bool success = CreateProcess(o.exe_path, cmdline, NULL, NULL, TRUE, - CREATE_NO_WINDOW, NULL, pwd, &si, &pi); + CREATE_NO_WINDOW, NULL, pwd, &si, &pi); if (!success) { ShowLocalizedMsg(IDS_ERR_CREATE_PROCESS, o.exe_path, cmdline, pwd); @@ -2907,7 +3137,9 @@ void ResetSavePasswords(connection_t *c) { if (ShowLocalizedMsgEx(MB_OKCANCEL, o.hWnd, TEXT(PACKAGE_NAME), IDS_NFO_DELETE_PASS, c->config_name) == IDCANCEL) + { return; + } DeleteSavedPasswords(c->config_name); c->flags &= ~(FLAG_SAVE_KEY_PASS | FLAG_SAVE_AUTH_PASS); SetMenuStatus(c, c->state); @@ -2915,8 +3147,8 @@ ResetSavePasswords(connection_t *c) /* keep this array in same order as corresponding resource ids -- IDS_NFO_OVPN_STATE_xxxxx */ static const char *daemon_states[] = {"INITIAL", "CONNECTING", "ASSIGN_IP", - "ADD_ROUTES", "CONNECTED", "RECONNECTING", "EXITING", "WAIT", - "AUTH", "GET_CONFIG", "RESOLVE", "TCP_CONNECT", "AUTH_PENDING", NULL}; + "ADD_ROUTES", "CONNECTED", "RECONNECTING", "EXITING", "WAIT", + "AUTH", "GET_CONFIG", "RESOLVE", "TCP_CONNECT", "AUTH_PENDING", NULL}; /* * Given an OpenVPN state as reported by the management interface @@ -2929,7 +3161,7 @@ daemon_state_resid(const char *state) int i = 0; while (daemon_states[i] && strcmp(daemon_states[i], state)) { - i++; + i++; } return daemon_states[i] ? IDS_NFO_OVPN_STATE_INITIAL + i : IDS_NFO_OVPN_STATE_UNKNOWN; } diff --git a/openvpn.h b/openvpn.h index acec295..e529cea 100644 --- a/openvpn.h +++ b/openvpn.h @@ -26,33 +26,51 @@ #include "options.h" #define TRY_SETPROP(hwnd, name, p) \ - do { if (SetPropW(hwnd, name, p)) break; \ - MsgToEventLog(EVENTLOG_ERROR_TYPE, L"%hs:%d GetProp returned null", \ - __func__, __LINE__); \ - EndDialog(hwnd, IDABORT); \ - return false; \ - } while(0) + do { if (SetPropW(hwnd, name, p)) break; \ + MsgToEventLog(EVENTLOG_ERROR_TYPE, L"%hs:%d GetProp returned null", \ + __func__, __LINE__); \ + EndDialog(hwnd, IDABORT); \ + return false; \ + } while(0) BOOL StartOpenVPN(connection_t *); + void StopOpenVPN(connection_t *); + void DetachOpenVPN(connection_t *); + void SuspendOpenVPN(int config); + void RestartOpenVPN(connection_t *); + void ReleaseOpenVPN(connection_t *); + BOOL CheckVersion(); + void SetStatusWinIcon(HWND hwndDlg, int IconID); void OnReady(connection_t *, char *); + void OnHold(connection_t *, char *); + void OnLogLine(connection_t *, char *); + void OnStateChange(connection_t *, char *); + void OnPassword(connection_t *, char *); + void OnStop(connection_t *, char *); + void OnNeedOk(connection_t *, char *); + void OnNeedStr(connection_t *, char *); + void OnEcho(connection_t *, char *); + void OnByteCount(connection_t *, char *); -void OnInfoMsg(connection_t*, char*); + +void OnInfoMsg(connection_t *, char *); + void OnTimeout(connection_t *, char *); void ResetSavePasswords(connection_t *); @@ -66,7 +84,7 @@ extern const TCHAR *cfgProp; #define ERROR_MESSAGE_TYPE 0x20000003 /* Write a line to status window and optionally to the log file */ -void WriteStatusLog (connection_t *c, const WCHAR *prefix, const WCHAR *line, BOOL fileio); +void WriteStatusLog(connection_t *c, const WCHAR *prefix, const WCHAR *line, BOOL fileio); #define FLAG_CR_TYPE_SCRV1 0x1 /* static challenege */ #define FLAG_CR_TYPE_CRV1 0x2 /* dynamic challenege */ @@ -78,12 +96,12 @@ void WriteStatusLog (connection_t *c, const WCHAR *prefix, const WCHAR *line, BO #define FLAG_CR_TYPE_CRTEXT 0x80 /* crtext */ typedef struct { - connection_t* c; + connection_t *c; unsigned int flags; - char* str; - char* id; - char* user; - char* cr_response; + char *str; + char *id; + char *user; + char *cr_response; } auth_param_t; /* @@ -92,10 +110,10 @@ typedef struct { * even on error. */ BOOL -parse_dynamic_cr(const char* str, auth_param_t* param); +parse_dynamic_cr(const char *str, auth_param_t *param); void -free_auth_param(auth_param_t* param); +free_auth_param(auth_param_t *param); /* * Given an OpenVPN state as reported by the management interface @@ -103,4 +121,4 @@ free_auth_param(auth_param_t* param); */ int daemon_state_resid(const char *name); -#endif +#endif /* ifndef OPENVPN_H */ diff --git a/openvpn_config.c b/openvpn_config.c index c8497e5..56f055e 100644 --- a/openvpn_config.c +++ b/openvpn_config.c @@ -50,28 +50,34 @@ match(const WIN32_FIND_DATA *find, const TCHAR *ext) int i; if (find->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { return match_dir; + } if (ext_len == 0) + { return match_file; + } i = _tcslen(find->cFileName) - ext_len - 1; if (i > 0 && find->cFileName[i] == '.' - && _tcsicmp(find->cFileName + i + 1, ext) == 0) + && _tcsicmp(find->cFileName + i + 1, ext) == 0) + { return match_file; + } return match_false; } static bool -CheckReadAccess (const TCHAR *dir, const TCHAR *file) +CheckReadAccess(const TCHAR *dir, const TCHAR *file) { TCHAR path[MAX_PATH]; - _sntprintf_0 (path, _T("%ls\\%ls"), dir, file); + _sntprintf_0(path, _T("%ls\\%ls"), dir, file); - return CheckFileAccess (path, GENERIC_READ); + return CheckFileAccess(path, GENERIC_READ); } static int @@ -80,7 +86,9 @@ ConfigAlreadyExists(TCHAR *newconfig) for (connection_t *c = o.chead; c; c = c->next) { if (_tcsicmp(c->config_file, newconfig) == 0) + { return true; + } } return false; } @@ -148,9 +156,13 @@ AddConfigFileToList(int group, const TCHAR *filename, const TCHAR *config_dir) else { if (IsAuthPassSaved(c->config_name)) + { c->flags |= FLAG_SAVE_AUTH_PASS; + } if (IsKeyPassSaved(c->config_name)) + { c->flags |= FLAG_SAVE_KEY_PASS; + } } if (o.disable_popup_messages) { @@ -214,7 +226,9 @@ ActivateConfigGroups(void) /* children is a counter re-used for activation, menu indexing etc. -- reset before use */ for (int i = 0; i < o.num_groups; i++) + { o.groups[i].children = 0; + } /* count children of each group -- this includes groups * and configs which have it as parent @@ -229,7 +243,9 @@ ActivateConfigGroups(void) config_group_t *this = &o.groups[i]; config_group_t *parent = PARENT_GROUP(this); if (parent) /* should be true as i = 0 is omitted */ + { parent->children++; + } /* unless activated below the group stays inactive */ this->active = false; @@ -290,7 +306,9 @@ BuildFileList0(const TCHAR *config_dir, int recurse_depth, int group, int flags) _sntprintf_0(find_string, _T("%ls\\*"), config_dir); find_handle = FindFirstFile(find_string, &find_obj); if (find_handle == INVALID_HANDLE_VALUE) + { return; + } /* Loop over each config file in config dir */ do @@ -301,11 +319,13 @@ BuildFileList0(const TCHAR *config_dir, int recurse_depth, int group, int flags) if (ConfigAlreadyExists(find_obj.cFileName)) { if (flags & FLAG_WARN_DUPLICATES) + { ShowLocalizedMsg(IDS_ERR_CONFIG_EXIST, find_obj.cFileName); + } continue; } - if (CheckReadAccess (config_dir, find_obj.cFileName)) + if (CheckReadAccess(config_dir, find_obj.cFileName)) { AddConfigFileToList(group, find_obj.cFileName, config_dir); } @@ -316,11 +336,15 @@ BuildFileList0(const TCHAR *config_dir, int recurse_depth, int group, int flags) /* optionally loop over each subdir */ if (recurse_depth < 1) + { return; + } - find_handle = FindFirstFile (find_string, &find_obj); + find_handle = FindFirstFile(find_string, &find_obj); if (find_handle == INVALID_HANDLE_VALUE) + { return; + } do { @@ -389,13 +413,16 @@ IsSamePath(const wchar_t *path1, const wchar_t *path2) BOOL ret = false; BY_HANDLE_FILE_INFORMATION info1, info2; - if (_wcsicmp(path1, path2) == 0) return true; + if (_wcsicmp(path1, path2) == 0) + { + return true; + } if (GetFileInfo(path1, &info1) && GetFileInfo(path2, &info2)) { ret = (info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber - && info1.nFileIndexLow == info2.nFileIndexLow - && info1.nFileIndexHigh == info2.nFileIndexHigh); + && info1.nFileIndexLow == info2.nFileIndexLow + && info1.nFileIndexHigh == info2.nFileIndexHigh); } return ret; @@ -410,7 +437,9 @@ BuildFileList() static int root_gp, system_gp, persistent_gp; if (o.silent_connection) + { issue_warnings = false; + } /* * If first time or no entries in the connection list reset groups and rescan @@ -438,11 +467,11 @@ BuildFileList() flags |= FLAG_WARN_DUPLICATES | FLAG_WARN_MAX_CONFIGS; } - BuildFileList0 (o.config_dir, recurse_depth, root_gp, flags); + BuildFileList0(o.config_dir, recurse_depth, root_gp, flags); if (!IsSamePath(o.global_config_dir, o.config_dir)) { - BuildFileList0 (o.global_config_dir, recurse_depth, system_gp, flags); + BuildFileList0(o.global_config_dir, recurse_depth, system_gp, flags); } if (o.service_state == service_connected @@ -450,12 +479,14 @@ BuildFileList() { if (!IsSamePath(o.config_auto_dir, o.config_dir)) { - BuildFileList0 (o.config_auto_dir, recurse_depth, persistent_gp, flags); + BuildFileList0(o.config_auto_dir, recurse_depth, persistent_gp, flags); } } if (o.num_configs == 0 && issue_warnings) + { ShowLocalizedMsg(IDS_NFO_NO_CONFIGS, o.config_dir, o.global_config_dir); + } ActivateConfigGroups(); diff --git a/openvpn_config.h b/openvpn_config.h index d634657..25f2a59 100644 --- a/openvpn_config.h +++ b/openvpn_config.h @@ -25,7 +25,9 @@ #include "main.h" void BuildFileList(void); + bool ConfigFileOptionExist(int, const char *); + void FreeConfigList(options_t *o); #endif diff --git a/options.c b/options.c index 690e1be..2be0c3b 100644 --- a/options.c +++ b/options.c @@ -50,37 +50,37 @@ extern options_t o; static version_t -MakeVersion (short ma, short mi, short b, short r) +MakeVersion(short ma, short mi, short b, short r) { version_t v = {ma, mi, b, r}; return v; } static void -ExpandString (WCHAR *str, int max_len) +ExpandString(WCHAR *str, int max_len) { - WCHAR expanded_string[MAX_PATH]; - int len = ExpandEnvironmentStringsW (str, expanded_string, _countof(expanded_string)); - - if (len > max_len || len > (int) _countof(expanded_string)) - { - PrintDebug (L"Failed to expanded env vars in '%ls'. String too long", str); - return; - } - wcsncpy (str, expanded_string, max_len); + WCHAR expanded_string[MAX_PATH]; + int len = ExpandEnvironmentStringsW(str, expanded_string, _countof(expanded_string)); + + if (len > max_len || len > (int) _countof(expanded_string)) + { + PrintDebug(L"Failed to expanded env vars in '%ls'. String too long", str); + return; + } + wcsncpy(str, expanded_string, max_len); } void -ExpandOptions (void) +ExpandOptions(void) { - ExpandString (o.exe_path, _countof(o.exe_path)); - ExpandString (o.config_dir, _countof(o.config_dir)); - ExpandString (o.global_config_dir, _countof(o.global_config_dir)); - ExpandString (o.config_auto_dir, _countof(o.config_auto_dir)); - ExpandString (o.log_dir, _countof(o.log_dir)); - ExpandString (o.editor, _countof(o.editor)); - ExpandString (o.log_viewer, _countof(o.log_viewer)); - ExpandString (o.install_path, _countof(o.install_path)); + ExpandString(o.exe_path, _countof(o.exe_path)); + ExpandString(o.config_dir, _countof(o.config_dir)); + ExpandString(o.global_config_dir, _countof(o.global_config_dir)); + ExpandString(o.config_auto_dir, _countof(o.config_auto_dir)); + ExpandString(o.log_dir, _countof(o.log_dir)); + ExpandString(o.editor, _countof(o.editor)); + ExpandString(o.log_viewer, _countof(o.log_viewer)); + ExpandString(o.install_path, _countof(o.install_path)); } static int @@ -157,8 +157,8 @@ add_option(options_t *options, int i, TCHAR **p) ++i; _tcsncpy(options->priority_string, p[1], _countof(options->priority_string) - 1); } - else if ( (streq(p[0], _T("append_string")) || - streq(p[0], _T("log_append"))) && p[1] ) + else if ( (streq(p[0], _T("append_string")) + || streq(p[0], _T("log_append"))) && p[1]) { ++i; options->log_append = _ttoi(p[1]) ? 1 : 0; @@ -181,22 +181,22 @@ add_option(options_t *options, int i, TCHAR **p) else if (streq(p[0], _T("allow_edit")) && p[1]) { ++i; - PrintDebug (L"Deprecated option: '%ls' ignored.", p[0]); + PrintDebug(L"Deprecated option: '%ls' ignored.", p[0]); } else if (streq(p[0], _T("allow_service")) && p[1]) { ++i; - PrintDebug (L"Deprecated option: '%ls' ignored.", p[0]); + PrintDebug(L"Deprecated option: '%ls' ignored.", p[0]); } else if (streq(p[0], _T("allow_password")) && p[1]) { ++i; - PrintDebug (L"Deprecated option: '%ls' ignored.", p[0]); + PrintDebug(L"Deprecated option: '%ls' ignored.", p[0]); } else if (streq(p[0], _T("allow_proxy")) && p[1]) { ++i; - PrintDebug (L"Deprecated option: '%ls' ignored.", p[0]); + PrintDebug(L"Deprecated option: '%ls' ignored.", p[0]); } else if (streq(p[0], _T("show_balloon")) && p[1]) { @@ -206,7 +206,7 @@ add_option(options_t *options, int i, TCHAR **p) else if (streq(p[0], _T("service_only")) && p[1]) { ++i; - PrintDebug (L"Deprecated option: '%ls' ignored.", p[0]); + PrintDebug(L"Deprecated option: '%ls' ignored.", p[0]); } else if (streq(p[0], _T("show_script_window")) && p[1]) { @@ -221,7 +221,7 @@ add_option(options_t *options, int i, TCHAR **p) else if (streq(p[0], _T("passphrase_attempts")) && p[1]) { ++i; - PrintDebug (L"Deprecated option: '%ls' ignored.", p[0]); + PrintDebug(L"Deprecated option: '%ls' ignored.", p[0]); } else if (streq(p[0], _T("connectscript_timeout")) && p[1]) { @@ -362,7 +362,9 @@ parse_argv(options_t *options, int argc, TCHAR **argv) { TCHAR *arg = argv[i + j]; if (_tcsncmp(arg, _T("--"), 2) == 0) + { break; + } p[j] = arg; } } @@ -375,8 +377,8 @@ void InitOptions(options_t *opt) { CLEAR(*opt); - opt->netcmd_semaphore = InitSemaphore (NULL); - opt->version = MakeVersion (PACKAGE_VERSION_RESOURCE); + opt->netcmd_semaphore = InitSemaphore(NULL); + opt->version = MakeVersion(PACKAGE_VERSION_RESOURCE); opt->clr_warning = RGB(0xff, 0, 0); opt->clr_error = RGB(0xff, 0, 0); } @@ -393,49 +395,67 @@ ProcessCommandLine(options_t *options, TCHAR *command_line) do { while (*pos == _T(' ')) + { ++pos; + } if (*pos == _T('\0')) + { break; + } ++argc; while (*pos != _T('\0') && *pos != _T(' ')) - ++pos; + { + ++pos; + } } while (*pos != _T('\0')); if (argc == 0) + { return; + } /* Tokenize the arguments */ - argv = (TCHAR**) malloc(argc * sizeof(TCHAR*)); + argv = (TCHAR **) malloc(argc * sizeof(TCHAR *)); pos = command_line; argc = 0; do { while (*pos == _T(' ')) + { pos++; + } if (*pos == _T('\0')) + { break; + } if (*pos == _T('\"')) { argv[argc++] = ++pos; while (*pos != _T('\0') && *pos != _T('\"')) + { ++pos; + } } else { argv[argc++] = pos; while (*pos != _T('\0') && *pos != _T(' ')) + { ++pos; + } } if (*pos == _T('\0')) + { break; + } *pos++ = _T('\0'); } @@ -445,7 +465,7 @@ ProcessCommandLine(options_t *options, TCHAR *command_line) free(argv); - ExpandOptions (); + ExpandOptions(); } @@ -458,52 +478,58 @@ CountConnState(conn_state_t check) for (connection_t *c = o.chead; c; c = c->next) { if (c->state == check) + { ++count; + } } return count; } -connection_t* +connection_t * GetConnByManagement(SOCKET sk) { for (connection_t *c = o.chead; c; c = c->next) { if (c->manage.sk == sk) + { return c; + } } return NULL; } -connection_t* +connection_t * GetConnByName(const WCHAR *name) { for (connection_t *c = o.chead; c; c = c->next) { - if (wcsicmp (c->config_file, name) == 0 + if (wcsicmp(c->config_file, name) == 0 || wcsicmp(c->config_name, name) == 0) + { return c; + } } return NULL; } static BOOL -BrowseFolder (const WCHAR* initial_path, WCHAR* selected_path, size_t selected_path_size) +BrowseFolder(const WCHAR *initial_path, WCHAR *selected_path, size_t selected_path_size) { - IFileOpenDialog* pfd; + IFileOpenDialog *pfd; HRESULT initResult, result, dialogResult = E_FAIL; - // Create dialog + /* Create dialog */ initResult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); if (FAILED(initResult)) { return false; } - result = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_ALL, &IID_IFileOpenDialog, (void**)&pfd); + result = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_ALL, &IID_IFileOpenDialog, (void **)&pfd); if (SUCCEEDED(result)) { - // Select folders, not files + /* Select folders, not files */ DWORD dwOptions; result = pfd->lpVtbl->GetOptions(pfd, &dwOptions); if (SUCCEEDED(result)) @@ -512,24 +538,24 @@ BrowseFolder (const WCHAR* initial_path, WCHAR* selected_path, size_t selected_p result = pfd->lpVtbl->SetOptions(pfd, dwOptions); } - // Set initial path - IShellItem* psi; - result = SHCreateItemFromParsingName(initial_path, NULL, &IID_IShellItem, (void**)&psi); + /* Set initial path */ + IShellItem *psi; + result = SHCreateItemFromParsingName(initial_path, NULL, &IID_IShellItem, (void **)&psi); if (SUCCEEDED(result)) { pfd->lpVtbl->SetFolder(pfd, psi); psi->lpVtbl->Release(psi); } - // Show dialog and copy the selected file path if the user didn't cancel + /* Show dialog and copy the selected file path if the user didn't cancel */ dialogResult = pfd->lpVtbl->Show(pfd, NULL); if (SUCCEEDED(dialogResult)) { - IShellItem* psi; + IShellItem *psi; LPOLESTR path = NULL; result = pfd->lpVtbl->GetResult(pfd, &psi); - if(SUCCEEDED(result)) + if (SUCCEEDED(result)) { result = psi->lpVtbl->GetDisplayName(psi, SIGDN_FILESYSPATH, &path); } @@ -548,65 +574,71 @@ BrowseFolder (const WCHAR* initial_path, WCHAR* selected_path, size_t selected_p } } - // Cleanup + /* Cleanup */ pfd->lpVtbl->Release(pfd); } if (initResult != RPC_E_CHANGED_MODE && SUCCEEDED(initResult)) { - CoUninitialize(); //All successful CoInitializeEx calls must be balanced by a corresponding CoUninitialize + CoUninitialize(); /*All successful CoInitializeEx calls must be balanced by a corresponding CoUninitialize */ } return SUCCEEDED(dialogResult); } static BOOL -CheckAdvancedDlgParams (HWND hdlg) +CheckAdvancedDlgParams(HWND hdlg) { WCHAR tmp_path[MAX_PATH]; /* replace empty entries by current values */ - if (GetWindowTextLength (GetDlgItem(hdlg, ID_EDT_CONFIG_DIR)) == 0) - SetDlgItemText (hdlg, ID_EDT_CONFIG_DIR, o.config_dir); - if (GetWindowTextLength (GetDlgItem(hdlg, ID_EDT_LOG_DIR)) == 0) - SetDlgItemText (hdlg, ID_EDT_LOG_DIR, o.log_dir); - if (GetWindowTextLength (GetDlgItem(hdlg, ID_EDT_CONFIG_EXT)) == 0) - SetDlgItemText (hdlg, ID_EDT_CONFIG_EXT, o.ext_string); + if (GetWindowTextLength(GetDlgItem(hdlg, ID_EDT_CONFIG_DIR)) == 0) + { + SetDlgItemText(hdlg, ID_EDT_CONFIG_DIR, o.config_dir); + } + if (GetWindowTextLength(GetDlgItem(hdlg, ID_EDT_LOG_DIR)) == 0) + { + SetDlgItemText(hdlg, ID_EDT_LOG_DIR, o.log_dir); + } + if (GetWindowTextLength(GetDlgItem(hdlg, ID_EDT_CONFIG_EXT)) == 0) + { + SetDlgItemText(hdlg, ID_EDT_CONFIG_EXT, o.ext_string); + } /* ensure paths are absolute */ - GetDlgItemText (hdlg, ID_EDT_CONFIG_DIR, tmp_path, _countof(tmp_path)); - ExpandString (tmp_path, _countof(tmp_path)); - if (PathIsRelativeW (tmp_path)) + GetDlgItemText(hdlg, ID_EDT_CONFIG_DIR, tmp_path, _countof(tmp_path)); + ExpandString(tmp_path, _countof(tmp_path)); + if (PathIsRelativeW(tmp_path)) { - MessageBox (hdlg, L"Specified config directory is not an absolute path", - L"Option error", MB_OK); + MessageBox(hdlg, L"Specified config directory is not an absolute path", + L"Option error", MB_OK); return false; } - GetDlgItemText (hdlg, ID_EDT_LOG_DIR, tmp_path, _countof(tmp_path)); - ExpandString (tmp_path, _countof(tmp_path)); - if (PathIsRelativeW (tmp_path)) + GetDlgItemText(hdlg, ID_EDT_LOG_DIR, tmp_path, _countof(tmp_path)); + ExpandString(tmp_path, _countof(tmp_path)); + if (PathIsRelativeW(tmp_path)) { - MessageBox (hdlg, L"Specified log directory is not an absolute path", - L"Option error", MB_OK); + MessageBox(hdlg, L"Specified log directory is not an absolute path", + L"Option error", MB_OK); return false; } BOOL status; - int tmp = GetDlgItemInt (hdlg, ID_EDT_MGMT_PORT, &status, FALSE); + int tmp = GetDlgItemInt(hdlg, ID_EDT_MGMT_PORT, &status, FALSE); /* Restrict the port offset to sensible range -- port used is this + upto ~4000 as connection index */ if (!status || (tmp < 1 || tmp > 61000)) { - MessageBox (hdlg, L"Specified port is not valid (must be in the range 1 to 61000)", - L"Option error", MB_OK); + MessageBox(hdlg, L"Specified port is not valid (must be in the range 1 to 61000)", + L"Option error", MB_OK); return false; } - tmp = GetDlgItemInt (hdlg, ID_EDT_POPUP_MUTE, &status, FALSE); + tmp = GetDlgItemInt(hdlg, ID_EDT_POPUP_MUTE, &status, FALSE); if (!status || tmp < 0) { - MessageBox (hdlg, L"Specified mute interval is not valid (must be a positive integer)", - L"Option error", MB_OK); + MessageBox(hdlg, L"Specified mute interval is not valid (must be a positive integer)", + L"Option error", MB_OK); return false; } @@ -614,159 +646,202 @@ CheckAdvancedDlgParams (HWND hdlg) } static BOOL -SaveAdvancedDlgParams (HWND hdlg) +SaveAdvancedDlgParams(HWND hdlg) { WCHAR tmp_path[MAX_PATH], tmp_path1[MAX_PATH]; UINT tmp; BOOL status; - GetDlgItemText (hdlg, ID_EDT_CONFIG_DIR, o.config_dir, _countof(o.config_dir)); + GetDlgItemText(hdlg, ID_EDT_CONFIG_DIR, o.config_dir, _countof(o.config_dir)); - GetDlgItemText (hdlg, ID_EDT_LOG_DIR, tmp_path, _countof(tmp_path)); - wcsncpy (tmp_path1, tmp_path, _countof(tmp_path1)); - ExpandString (tmp_path1, _countof(tmp_path1)); + GetDlgItemText(hdlg, ID_EDT_LOG_DIR, tmp_path, _countof(tmp_path)); + wcsncpy(tmp_path1, tmp_path, _countof(tmp_path1)); + ExpandString(tmp_path1, _countof(tmp_path1)); - if (EnsureDirExists (tmp_path1)) /* this will try to create the path if needed */ - wcsncpy (o.log_dir, tmp_path, _countof(o.log_dir)); /* save unexpanded path */ + if (EnsureDirExists(tmp_path1)) /* this will try to create the path if needed */ + { + wcsncpy(o.log_dir, tmp_path, _countof(o.log_dir)); /* save unexpanded path */ + } else { ShowLocalizedMsg(IDS_ERR_CREATE_PATH, L"Log", tmp_path1); return false; } - GetDlgItemText (hdlg, ID_EDT_CONFIG_EXT, o.ext_string, _countof(o.ext_string)); + GetDlgItemText(hdlg, ID_EDT_CONFIG_EXT, o.ext_string, _countof(o.ext_string)); - tmp = GetDlgItemInt (hdlg, ID_EDT_PRECONNECT_TIMEOUT, &status, FALSE); - if (status && tmp > 0) o.preconnectscript_timeout = tmp; + tmp = GetDlgItemInt(hdlg, ID_EDT_PRECONNECT_TIMEOUT, &status, FALSE); + if (status && tmp > 0) + { + o.preconnectscript_timeout = tmp; + } - tmp = GetDlgItemInt (hdlg, ID_EDT_CONNECT_TIMEOUT, &status, FALSE); - if (status) o.connectscript_timeout = tmp; + tmp = GetDlgItemInt(hdlg, ID_EDT_CONNECT_TIMEOUT, &status, FALSE); + if (status) + { + o.connectscript_timeout = tmp; + } - tmp = GetDlgItemInt (hdlg, ID_EDT_DISCONNECT_TIMEOUT, &status, FALSE); - if (status && tmp > 0) o.disconnectscript_timeout = tmp; + tmp = GetDlgItemInt(hdlg, ID_EDT_DISCONNECT_TIMEOUT, &status, FALSE); + if (status && tmp > 0) + { + o.disconnectscript_timeout = tmp; + } - tmp = GetDlgItemInt (hdlg, ID_EDT_MGMT_PORT, &status, FALSE); - if (status) o.mgmt_port_offset = tmp; + tmp = GetDlgItemInt(hdlg, ID_EDT_MGMT_PORT, &status, FALSE); + if (status) + { + o.mgmt_port_offset = tmp; + } - tmp = GetDlgItemInt (hdlg, ID_EDT_POPUP_MUTE, &status, FALSE); - if (status) o.popup_mute_interval = tmp; + tmp = GetDlgItemInt(hdlg, ID_EDT_POPUP_MUTE, &status, FALSE); + if (status) + { + o.popup_mute_interval = tmp; + } o.ovpn_engine = IsDlgButtonChecked(hdlg, ID_RB_ENGINE_OVPN3) ? - OPENVPN_ENGINE_OVPN3 : OPENVPN_ENGINE_OVPN2; + OPENVPN_ENGINE_OVPN3 : OPENVPN_ENGINE_OVPN2; - SaveRegistryKeys (); - ExpandOptions (); + SaveRegistryKeys(); + ExpandOptions(); return true; } static void -LoadAdvancedDlgParams (HWND hdlg) +LoadAdvancedDlgParams(HWND hdlg) { - SetDlgItemText (hdlg, ID_EDT_CONFIG_DIR, o.config_dir); - SetDlgItemText (hdlg, ID_EDT_CONFIG_EXT, o.ext_string); - SetDlgItemText (hdlg, ID_EDT_LOG_DIR, o.log_dir); - SetDlgItemInt (hdlg, ID_EDT_PRECONNECT_TIMEOUT, o.preconnectscript_timeout, FALSE); - SetDlgItemInt (hdlg, ID_EDT_CONNECT_TIMEOUT, o.connectscript_timeout, FALSE); - SetDlgItemInt (hdlg, ID_EDT_DISCONNECT_TIMEOUT, o.disconnectscript_timeout, FALSE); - SetDlgItemInt (hdlg, ID_EDT_MGMT_PORT, o.mgmt_port_offset, FALSE); - SetDlgItemInt (hdlg, ID_EDT_POPUP_MUTE, o.popup_mute_interval, FALSE); + SetDlgItemText(hdlg, ID_EDT_CONFIG_DIR, o.config_dir); + SetDlgItemText(hdlg, ID_EDT_CONFIG_EXT, o.ext_string); + SetDlgItemText(hdlg, ID_EDT_LOG_DIR, o.log_dir); + SetDlgItemInt(hdlg, ID_EDT_PRECONNECT_TIMEOUT, o.preconnectscript_timeout, FALSE); + SetDlgItemInt(hdlg, ID_EDT_CONNECT_TIMEOUT, o.connectscript_timeout, FALSE); + SetDlgItemInt(hdlg, ID_EDT_DISCONNECT_TIMEOUT, o.disconnectscript_timeout, FALSE); + SetDlgItemInt(hdlg, ID_EDT_MGMT_PORT, o.mgmt_port_offset, FALSE); + SetDlgItemInt(hdlg, ID_EDT_POPUP_MUTE, o.popup_mute_interval, FALSE); if (o.config_menu_view == 0) - CheckRadioButton (hdlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON0); + { + CheckRadioButton(hdlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON0); + } else if (o.config_menu_view == 1) - CheckRadioButton (hdlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON1); + { + CheckRadioButton(hdlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON1); + } else if (o.config_menu_view == 2) - CheckRadioButton (hdlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON2); + { + CheckRadioButton(hdlg, ID_RB_BALLOON0, ID_RB_BALLOON2, ID_RB_BALLOON2); + } /* BALLOON3 sets echo msg display to auto, BALLOON4 to never */ if (o.disable_popup_messages) - CheckRadioButton (hdlg, ID_RB_BALLOON3, ID_RB_BALLOON4, ID_RB_BALLOON4); + { + CheckRadioButton(hdlg, ID_RB_BALLOON3, ID_RB_BALLOON4, ID_RB_BALLOON4); + } else - CheckRadioButton (hdlg, ID_RB_BALLOON3, ID_RB_BALLOON4, ID_RB_BALLOON3); + { + CheckRadioButton(hdlg, ID_RB_BALLOON3, ID_RB_BALLOON4, ID_RB_BALLOON3); + } #ifdef ENABLE_OVPN3 CheckRadioButton(hdlg, ID_RB_ENGINE_OVPN2, ID_RB_ENGINE_OVPN3, - o.ovpn_engine == OPENVPN_ENGINE_OVPN3 ? ID_RB_ENGINE_OVPN3 : ID_RB_ENGINE_OVPN2); + o.ovpn_engine == OPENVPN_ENGINE_OVPN3 ? ID_RB_ENGINE_OVPN3 : ID_RB_ENGINE_OVPN2); #endif } INT_PTR CALLBACK -AdvancedSettingsDlgProc (HWND hwndDlg, UINT msg, UNUSED WPARAM wParam, LPARAM lParam) +AdvancedSettingsDlgProc(HWND hwndDlg, UINT msg, UNUSED WPARAM wParam, LPARAM lParam) { LPPSHNOTIFY psn; - switch(msg) { - - case WM_INITDIALOG: - /* Limit extension editbox to 4 chars. */ - SendMessage (GetDlgItem(hwndDlg, ID_EDT_CONFIG_EXT), EM_SETLIMITTEXT, 4, 0); - /* Limit management port editbox to 5 chars */ - SendMessage(GetDlgItem(hwndDlg, ID_EDT_MGMT_PORT), EM_SETLIMITTEXT, 5, 0); - /* Populate UI */ - LoadAdvancedDlgParams (hwndDlg); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - WCHAR path[MAX_PATH]; - - case ID_BTN_CONFIG_DIR: - GetDlgItemText (hwndDlg, ID_EDT_CONFIG_DIR, path, _countof(path)); - if (BrowseFolder (path, path, _countof(path))) - SetDlgItemText (hwndDlg, ID_EDT_CONFIG_DIR, path); + switch (msg) + { + + case WM_INITDIALOG: + /* Limit extension editbox to 4 chars. */ + SendMessage(GetDlgItem(hwndDlg, ID_EDT_CONFIG_EXT), EM_SETLIMITTEXT, 4, 0); + /* Limit management port editbox to 5 chars */ + SendMessage(GetDlgItem(hwndDlg, ID_EDT_MGMT_PORT), EM_SETLIMITTEXT, 5, 0); + /* Populate UI */ + LoadAdvancedDlgParams(hwndDlg); break; - case ID_BTN_LOG_DIR: - GetDlgItemText (hwndDlg, ID_EDT_LOG_DIR, path, _countof(path)); - if (BrowseFolder (path, path, _countof(path))) - SetDlgItemText (hwndDlg, ID_EDT_LOG_DIR, path); + case WM_COMMAND: + switch (LOWORD(wParam)) + { + WCHAR path[MAX_PATH]; + + case ID_BTN_CONFIG_DIR: + GetDlgItemText(hwndDlg, ID_EDT_CONFIG_DIR, path, _countof(path)); + if (BrowseFolder(path, path, _countof(path))) + { + SetDlgItemText(hwndDlg, ID_EDT_CONFIG_DIR, path); + } + break; + + case ID_BTN_LOG_DIR: + GetDlgItemText(hwndDlg, ID_EDT_LOG_DIR, path, _countof(path)); + if (BrowseFolder(path, path, _countof(path))) + { + SetDlgItemText(hwndDlg, ID_EDT_LOG_DIR, path); + } + break; + } break; - } - break; - case WM_NOTIFY: - psn = (LPPSHNOTIFY) lParam; - if (psn->hdr.code == (UINT) PSN_KILLACTIVE) - { - SetWindowLongPtr (hwndDlg, DWLP_MSGRESULT, (CheckAdvancedDlgParams(hwndDlg) ? FALSE : TRUE)); - return TRUE; - } - if (psn->hdr.code == (UINT) PSN_APPLY) - { - BOOL status = SaveAdvancedDlgParams (hwndDlg); - SetWindowLongPtr (hwndDlg, DWLP_MSGRESULT, status? PSNRET_NOERROR:PSNRET_INVALID); - return TRUE; - } - if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON2)) - o.config_menu_view = 2; - else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON1)) - o.config_menu_view = 1; - else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON0)) - o.config_menu_view = 0; - else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON3)) - o.disable_popup_messages = 0; - else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON4)) - o.disable_popup_messages = 1; - break; + case WM_NOTIFY: + psn = (LPPSHNOTIFY) lParam; + if (psn->hdr.code == (UINT) PSN_KILLACTIVE) + { + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (CheckAdvancedDlgParams(hwndDlg) ? FALSE : TRUE)); + return TRUE; + } + if (psn->hdr.code == (UINT) PSN_APPLY) + { + BOOL status = SaveAdvancedDlgParams(hwndDlg); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, status ? PSNRET_NOERROR : PSNRET_INVALID); + return TRUE; + } + if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON2)) + { + o.config_menu_view = 2; + } + else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON1)) + { + o.config_menu_view = 1; + } + else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON0)) + { + o.config_menu_view = 0; + } + else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON3)) + { + o.disable_popup_messages = 0; + } + else if (IsDlgButtonChecked(hwndDlg, ID_RB_BALLOON4)) + { + o.disable_popup_messages = 1; + } + break; } return FALSE; } int -CompareStringExpanded (const WCHAR *str1, const WCHAR *str2) +CompareStringExpanded(const WCHAR *str1, const WCHAR *str2) { WCHAR str1_cpy[MAX_PATH], str2_cpy[MAX_PATH]; - wcsncpy (str1_cpy, str1, _countof(str1_cpy)); - wcsncpy (str2_cpy, str2, _countof(str2_cpy)); + wcsncpy(str1_cpy, str1, _countof(str1_cpy)); + wcsncpy(str2_cpy, str2, _countof(str2_cpy)); str1_cpy[MAX_PATH-1] = L'\0'; str2_cpy[MAX_PATH-1] = L'\0'; - ExpandString (str1_cpy, _countof(str1_cpy)); - ExpandString (str2_cpy, _countof(str2_cpy)); + ExpandString(str1_cpy, _countof(str1_cpy)); + ExpandString(str2_cpy, _countof(str2_cpy)); - return wcsicmp (str1_cpy, str2_cpy); + return wcsicmp(str1_cpy, str2_cpy); } /* Hide the password save options from user */ diff --git a/options.h b/options.h index d466f16..678396b 100644 --- a/options.h +++ b/options.h @@ -249,16 +249,27 @@ typedef struct { } options_t; void InitOptions(options_t *); + void ProcessCommandLine(options_t *, TCHAR *); + int CountConnState(conn_state_t); -connection_t* GetConnByManagement(SOCKET); -connection_t* GetConnByName(const WCHAR *config_name); + +connection_t *GetConnByManagement(SOCKET); + +connection_t *GetConnByName(const WCHAR *config_name); + INT_PTR CALLBACK ScriptSettingsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + INT_PTR CALLBACK ConnectionSettingsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + INT_PTR CALLBACK AdvancedSettingsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); + void DisableSavePasswords(connection_t *); + void DisablePopupMessages(connection_t *); void ExpandOptions(void); + int CompareStringExpanded(const WCHAR *str1, const WCHAR *str2); -#endif + +#endif /* ifndef OPTIONS_H */ diff --git a/pkcs11.c b/pkcs11.c index d429d0a..07b5b25 100644 --- a/pkcs11.c +++ b/pkcs11.c @@ -553,7 +553,7 @@ display_certificate(HWND parent, connection_t *c, UINT i) */ #if defined(HAVE_LIBCRYPTUI) || defined (_MSC_VER) CryptUIDlgViewContext(CERT_STORE_CERTIFICATE_CONTEXT, l->pe[i].cert.ctx, - parent, L"Certificate", 0, NULL); + parent, L"Certificate", 0, NULL); #else (void) i; (void) parent; @@ -652,7 +652,7 @@ QueryPkcs11DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) } if (ln->hdr.code == NM_DBLCLK && ln->iItem >= 0) { - display_certificate(hwndDlg, c, (UINT) ln->iItem); + display_certificate(hwndDlg, c, (UINT) ln->iItem); } } break; diff --git a/plap/plap_common.c b/plap/plap_common.c index f6dad50..8790046 100644 --- a/plap/plap_common.c +++ b/plap/plap_common.c @@ -37,7 +37,9 @@ void init_debug() { if (!fp) + { fp = _wfopen(L"C:\\Windows\\Temp\\openvpn-plap-debug.txt", L"a+,ccs=UTF-8"); + } InitializeCriticalSection(&log_write); } @@ -45,7 +47,9 @@ void uninit_debug() { if (fp) + { fclose(fp); + } DeleteCriticalSection(&log_write); } @@ -58,8 +62,8 @@ x_dmsg(const char *file, const char *func, const wchar_t *fmt, ...) return; } - va_list args; - va_start (args, fmt); + va_list args; + va_start(args, fmt); vswprintf(buf, _countof(buf), fmt, args); va_end(args); @@ -93,7 +97,7 @@ void debug_print_guid(const GUID *riid, const wchar_t *context) { RPC_CSTR str = NULL; - if (UuidToStringA((GUID*) riid, &str) == RPC_S_OK) + if (UuidToStringA((GUID *) riid, &str) == RPC_S_OK) { x_dmsg(NULL, NULL, L"%ls %hs", context, str); RpcStringFreeA(&str); diff --git a/plap/plap_common.h b/plap/plap_common.h index 143f6d0..5bbe6e1 100644 --- a/plap/plap_common.h +++ b/plap/plap_common.h @@ -36,14 +36,17 @@ extern "C" { #endif #ifdef DEBUG -#define dmsg(fmt, ...) x_dmsg(__FILE__, __func__, fmt, ##__VA_ARGS__) +#define dmsg(fmt, ...) x_dmsg(__FILE__, __func__, fmt, ## __VA_ARGS__) #else -#define dmsg(...) do { ; } while (0) +#define dmsg(...) do {; } while (0) #endif void x_dmsg(const char *file, const char *func, const wchar_t *fmt, ...); + void init_debug(); + void uninit_debug(); + void debug_print_guid(const GUID *riid, const wchar_t *context); /* Shortcuts for cumbersome calls to COM methods of an object through its v-table */ @@ -64,6 +67,5 @@ void debug_print_guid(const GUID *riid, const wchar_t *context); */ #ifdef DEFINE_GUID DEFINE_GUID(CLSID_OpenVPNProvider, 0x4fbb8b67, 0xcf02, 0x4982, 0xa7, 0xa8, - 0x3d, 0xd0, 0x6a, 0x2c, 0x2e, 0xbd); + 0x3d, 0xd0, 0x6a, 0x2c, 0x2e, 0xbd); #endif - diff --git a/plap/plap_connection.c b/plap/plap_connection.c index 132947b..53c9f3a 100644 --- a/plap/plap_connection.c +++ b/plap/plap_connection.c @@ -59,36 +59,55 @@ extern DWORD status_menu_id; /* Methods in IConnectableCredentialProviderCredential that we need to define */ /* IUnknown */ -static HRESULT WINAPI QueryInterface(ICCPC *this, REFIID riid, void** ppv); +static HRESULT WINAPI QueryInterface(ICCPC *this, REFIID riid, void **ppv); + static ULONG WINAPI AddRef(ICCPC *this); + static ULONG WINAPI Release(ICCPC *this); /* ICredentialProviderCredential */ static HRESULT WINAPI Advise(ICCPC *this, ICredentialProviderCredentialEvents *e); + static HRESULT WINAPI UnAdvise(ICCPC *this); + static HRESULT WINAPI SetSelected(ICCPC *this, BOOL *auto_logon); + static HRESULT WINAPI SetDeselected(ICCPC *this); + static HRESULT WINAPI GetFieldState(ICCPC *this, DWORD field, CREDENTIAL_PROVIDER_FIELD_STATE *fs, - CREDENTIAL_PROVIDER_FIELD_INTERACTIVE_STATE *fis); + CREDENTIAL_PROVIDER_FIELD_INTERACTIVE_STATE *fis); + static HRESULT WINAPI GetStringValue(ICCPC *this, DWORD index, WCHAR **ws); + static HRESULT WINAPI GetBitmapValue(ICCPC *this, DWORD field, HBITMAP *bmp); + static HRESULT WINAPI GetSubmitButtonValue(ICCPC *this, DWORD field, DWORD *adjacent); + static HRESULT WINAPI SetStringValue(ICCPC *this, DWORD field, const WCHAR *ws); + static HRESULT WINAPI GetCheckboxValue(ICCPC *this, DWORD field, BOOL *checked, wchar_t **label); + static HRESULT WINAPI GetComboBoxValueCount(ICCPC *this, DWORD field, DWORD *items, DWORD *selected_item); + static HRESULT WINAPI GetComboBoxValueAt(ICCPC *this, DWORD field, DWORD item, wchar_t **item_value); + static HRESULT WINAPI SetCheckboxValue(ICCPC *this, DWORD field, BOOL checked); + static HRESULT WINAPI SetComboBoxSelectedValue(ICCPC *this, DWORD field, DWORD selected_item); + static HRESULT WINAPI CommandLinkClicked(ICCPC *this, DWORD field); + static HRESULT WINAPI GetSerialization(ICCPC *this, - CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE *response, - CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *cs, wchar_t **text, - CREDENTIAL_PROVIDER_STATUS_ICON *icon); + CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE *response, + CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *cs, wchar_t **text, + CREDENTIAL_PROVIDER_STATUS_ICON *icon); + static HRESULT WINAPI ReportResult(ICCPC *this, NTSTATUS status, NTSTATUS substatus, - wchar_t **status_text, CREDENTIAL_PROVIDER_STATUS_ICON *icon); + wchar_t **status_text, CREDENTIAL_PROVIDER_STATUS_ICON *icon); /* IConnectableCredentialProviderCredential */ static HRESULT WINAPI Connect(ICCPC *this, IQueryContinueWithStatus *qc); + static HRESULT WINAPI Disconnect(ICCPC *this); /* use a static table for filling in the methods */ @@ -169,7 +188,7 @@ Release(ICCPC *this) } static HRESULT WINAPI -QueryInterface(ICCPC *this, REFIID riid, void** ppv) +QueryInterface(ICCPC *this, REFIID riid, void **ppv) { HRESULT hr; @@ -205,7 +224,8 @@ QueryInterface(ICCPC *this, REFIID riid, void** ppv) * making callbacks to notify changes asynchronously */ static HRESULT -WINAPI Advise(ICCPC *this, ICredentialProviderCredentialEvents *e) +WINAPI +Advise(ICCPC *this, ICredentialProviderCredentialEvents *e) { HWND hwnd; @@ -214,7 +234,9 @@ WINAPI Advise(ICCPC *this, ICredentialProviderCredentialEvents *e) OpenVPNConnection *oc = (OpenVPNConnection *) this; if (oc->events) + { RELEASE(oc->events); + } oc->events = e; ADDREF(e); @@ -236,7 +258,9 @@ UnAdvise(ICCPC *this) OpenVPNConnection *oc = (OpenVPNConnection *) this; if (oc->events) + { RELEASE(oc->events); + } oc->events = NULL; return S_OK; } @@ -282,8 +306,8 @@ SetDeselected(ICCPC *this) */ static HRESULT WINAPI GetFieldState(UNUSED ICCPC *this, DWORD field, - CREDENTIAL_PROVIDER_FIELD_STATE *fs, - CREDENTIAL_PROVIDER_FIELD_INTERACTIVE_STATE *fis) + CREDENTIAL_PROVIDER_FIELD_STATE *fs, + CREDENTIAL_PROVIDER_FIELD_INTERACTIVE_STATE *fis) { HRESULT hr; @@ -292,9 +316,13 @@ GetFieldState(UNUSED ICCPC *this, DWORD field, if (field < _countof(field_states)) { if (fs) + { *fs = field_states[field]; + } if (fis) + { *fis = (field_desc[field].cpft == CPFT_SUBMIT_BUTTON) ? CPFIS_FOCUSED : CPFIS_NONE; + } hr = S_OK; } else @@ -418,7 +446,7 @@ SetStringValue(UNUSED ICCPC *this, UNUSED DWORD field, UNUSED const WCHAR *ws ) static HRESULT WINAPI GetCheckboxValue(UNUSED ICCPC *this, UNUSED DWORD field, - UNUSED BOOL *checked, UNUSED wchar_t **label) + UNUSED BOOL *checked, UNUSED wchar_t **label) { dmsg(L"Entry"); return E_NOTIMPL; @@ -426,7 +454,7 @@ GetCheckboxValue(UNUSED ICCPC *this, UNUSED DWORD field, static HRESULT WINAPI GetComboBoxValueCount(UNUSED ICCPC *this, UNUSED DWORD field, UNUSED DWORD *items, - UNUSED DWORD *selected_item) + UNUSED DWORD *selected_item) { dmsg(L"Entry"); return E_NOTIMPL; @@ -434,7 +462,7 @@ GetComboBoxValueCount(UNUSED ICCPC *this, UNUSED DWORD field, UNUSED DWORD *item static HRESULT WINAPI GetComboBoxValueAt(UNUSED ICCPC *this, UNUSED DWORD field, UNUSED DWORD item, - UNUSED wchar_t **item_value) + UNUSED wchar_t **item_value) { dmsg(L"Entry"); return E_NOTIMPL; @@ -470,8 +498,8 @@ CommandLinkClicked(UNUSED ICCPC *this, UNUSED DWORD field) */ static HRESULT WINAPI GetSerialization(ICCPC *this, CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE *response, - UNUSED CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *cs, wchar_t **text, - CREDENTIAL_PROVIDER_STATUS_ICON *icon) + UNUSED CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *cs, wchar_t **text, + CREDENTIAL_PROVIDER_STATUS_ICON *icon) { HRESULT hr = S_OK; @@ -490,9 +518,13 @@ GetSerialization(ICCPC *this, CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE *re if (text && icon) { if (oc->connect_cancelled) + { hr = SHStrDupW(LoadLocalizedString(IDS_NFO_CONN_CANCELLED), text); + } else + { hr = SHStrDupW(LoadLocalizedString(IDS_NFO_CONN_FAILED, oc->display_name), text); + } *icon = CPSI_ERROR; } @@ -513,7 +545,7 @@ GetSerialization(ICCPC *this, CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE *re static HRESULT WINAPI ReportResult(UNUSED ICCPC *this, UNUSED NTSTATUS status, UNUSED NTSTATUS substatus, - UNUSED wchar_t **status_text, UNUSED CREDENTIAL_PROVIDER_STATUS_ICON *icon) + UNUSED wchar_t **status_text, UNUSED CREDENTIAL_PROVIDER_STATUS_ICON *icon) { dmsg(L"Entry"); return E_NOTIMPL; @@ -525,8 +557,8 @@ NotifyEvents(OpenVPNConnection *oc, const wchar_t *status) { if (oc->events) { - oc->events->lpVtbl->SetFieldString(oc->events, (ICredentialProviderCredential*) oc, - STATUS_FIELD_INDEX, status); + oc->events->lpVtbl->SetFieldString(oc->events, (ICredentialProviderCredential *) oc, + STATUS_FIELD_INDEX, status); } if (oc->qc) { @@ -646,7 +678,7 @@ again: oc->qc = NULL; SetActiveProfile(NULL); - dmsg (L"Exit with: <%ls>", ISCONNECTED(oc->c) ? L"success" : L"error/cancel"); + dmsg(L"Exit with: <%ls>", ISCONNECTED(oc->c) ? L"success" : L"error/cancel"); return ISCONNECTED(oc->c) ? S_OK : E_FAIL; } @@ -655,7 +687,7 @@ static HRESULT WINAPI Disconnect(ICCPC *this) { OpenVPNConnection *oc = (OpenVPNConnection *) this; - dmsg (L"profile <%ls>", oc->display_name); + dmsg(L"profile <%ls>", oc->display_name); NotifyEvents(oc, LoadLocalizedString(IDS_NFO_STATE_DISCONNECTING)); @@ -679,8 +711,9 @@ OVPNConnection_Initialize(OpenVPNConnection *this, connection_t *conn, const wch } /* Copy field descriptor -- caller will free using CoTaskMemFree, alloc using compatible allocator */ -HRESULT CopyFieldDescriptor(CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR *fd_out, - const CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR *fd_in) +HRESULT +CopyFieldDescriptor(CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR *fd_out, + const CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR *fd_in) { HRESULT hr = S_OK; diff --git a/plap/plap_connection.h b/plap/plap_connection.h index 7d95c8e..1924445 100644 --- a/plap/plap_connection.h +++ b/plap/plap_connection.h @@ -52,7 +52,7 @@ static const CREDENTIAL_PROVIDER_FIELD_STATE field_states[] = /** Helper to deep copy field descriptor */ HRESULT CopyFieldDescriptor(CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR *fd_out, - const CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR *fd_in); + const CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR *fd_in); typedef struct OpenVPNConnection OpenVPNConnection; diff --git a/plap/plap_dll.c b/plap/plap_dll.c index ce2130b..9732a21 100644 --- a/plap/plap_dll.c +++ b/plap/plap_dll.c @@ -48,25 +48,29 @@ DllMain(HINSTANCE hinstDll, DWORD dwReason, UNUSED LPVOID pReserved) DisableThreadLibraryCalls(hinstDll); init_debug(); break; + case DLL_PROCESS_DETACH: uninit_debug(); break; + case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: - break; + break; } hinst_global = hinstDll; /* global */ return TRUE; } -void dll_addref() +void +dll_addref() { InterlockedIncrement(&dll_ref_count); dmsg(L"ref_count after increment = %lu", dll_ref_count); } -void dll_release() +void +dll_release() { InterlockedDecrement(&dll_ref_count); dmsg(L"ref_count after decrement = %lu", dll_ref_count); @@ -79,9 +83,13 @@ void dll_release() /* ClassFactory methods we have to implement */ static ULONG WINAPI AddRef(IClassFactory *this); + static ULONG WINAPI Release(IClassFactory *this); + static HRESULT WINAPI QueryInterface(IClassFactory *this, REFIID riid, void **ppv); + static HRESULT WINAPI CreateInstance(IClassFactory *this, IUnknown *iunk, REFIID riid, void **ppv); + static HRESULT WINAPI LockServer(IClassFactory *this, BOOL lock); /* template object for creation */ @@ -116,7 +124,7 @@ static HRESULT WINAPI QueryInterface(IClassFactory *this, REFIID riid, void **ppv) { HRESULT hr; - dmsg (L"Entry"); + dmsg(L"Entry"); #ifdef DEBUG debug_print_guid(riid, L"In CF_Queryinterface with iid = "); @@ -184,7 +192,8 @@ LockServer(UNUSED IClassFactory *this, BOOL lock) } /* exported methods */ -STDAPI DllCanUnloadNow() +STDAPI +DllCanUnloadNow() { HRESULT hr; @@ -206,7 +215,8 @@ STDAPI DllCanUnloadNow() * create class of type rclsid. We support only OpenVPNProvider * class and check it here. */ -STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv) +STDAPI +DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv) { dmsg(L"Entry"); HRESULT hr; diff --git a/plap/plap_dll.h b/plap/plap_dll.h index 3f62001..ae6a395 100644 --- a/plap/plap_dll.h +++ b/plap/plap_dll.h @@ -33,10 +33,12 @@ extern HINSTANCE hinst_global; HRESULT OpenVPNProvider_CreateInstance(REFIID riid, void **ppv); void dll_addref(); + void dll_release(); STDAPI DllCanUnloadNow(); -STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv); + +STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv); #ifdef __cplusplus } diff --git a/plap/plap_provider.c b/plap/plap_provider.c index f770137..65846b3 100644 --- a/plap/plap_provider.c +++ b/plap/plap_provider.c @@ -47,25 +47,31 @@ typedef struct OpenVPNProvider /* methods we have to implement */ static HRESULT WINAPI QueryInterface(ICredentialProvider *this, REFIID riid, void **ppv); + static ULONG WINAPI AddRef(ICredentialProvider *this); + static ULONG WINAPI Release(ICredentialProvider *this); static HRESULT WINAPI SetUsageScenario(ICredentialProvider *this, - CREDENTIAL_PROVIDER_USAGE_SCENARIO us, DWORD flags); + CREDENTIAL_PROVIDER_USAGE_SCENARIO us, DWORD flags); + static HRESULT WINAPI SetSerialization(ICredentialProvider *this, - const CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *cs); + const CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *cs); static HRESULT WINAPI Advise(ICredentialProvider *this, ICredentialProviderEvents *e, UINT_PTR context); + static HRESULT WINAPI UnAdvise(ICredentialProvider *this); static HRESULT WINAPI GetFieldDescriptorCount(ICredentialProvider *this, DWORD *count); + static HRESULT WINAPI GetFieldDescriptorAt(ICredentialProvider *this, DWORD index, - CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR **fd); + CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR **fd); static HRESULT WINAPI GetCredentialCount(ICredentialProvider *this, DWORD *count, - DWORD *default_cred, BOOL *autologon_default); + DWORD *default_cred, BOOL *autologon_default); + static HRESULT WINAPI GetCredentialAt(ICredentialProvider *this, DWORD index, - ICredentialProviderCredential **c); + ICredentialProviderCredential **c); /* a helper function for generating our connection array */ static HRESULT CreateOVPNConnectionArray(OpenVPNProvider *op); @@ -118,7 +124,7 @@ OpenVPNProvider_free(OpenVPNProvider *this) { if (this->connections[i]) { - RELEASE((ICCPC*) this->connections[i]); + RELEASE((ICCPC *) this->connections[i]); } } /* Destroy GUI threads and any associated data */ @@ -200,7 +206,7 @@ QueryInterface(ICredentialProvider *this, REFIID riid, void **ppv) */ static HRESULT WINAPI SetUsageScenario(ICredentialProvider *this, - CREDENTIAL_PROVIDER_USAGE_SCENARIO us, UNUSED DWORD flags) + CREDENTIAL_PROVIDER_USAGE_SCENARIO us, UNUSED DWORD flags) { /* I think flags may be ignored for PLAP */ @@ -223,7 +229,7 @@ SetUsageScenario(ICredentialProvider *this, */ static HRESULT WINAPI SetSerialization(UNUSED ICredentialProvider *this, - UNUSED const CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *cs) + UNUSED const CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION *cs) { dmsg(L"Entry"); return E_NOTIMPL; @@ -234,7 +240,7 @@ SetSerialization(UNUSED ICredentialProvider *this, */ static HRESULT WINAPI Advise(UNUSED ICredentialProvider *this, - UNUSED ICredentialProviderEvents *e, UNUSED UINT_PTR ctx) + UNUSED ICredentialProviderEvents *e, UNUSED UINT_PTR ctx) { dmsg(L"Entry"); return S_OK; @@ -273,7 +279,7 @@ GetFieldDescriptorCount(UNUSED ICredentialProvider *this, DWORD *count) */ static HRESULT WINAPI GetFieldDescriptorAt(UNUSED ICredentialProvider *this, DWORD index, - CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR **fd) + CREDENTIAL_PROVIDER_FIELD_DESCRIPTOR **fd) { HRESULT hr = E_OUTOFMEMORY; @@ -315,7 +321,7 @@ GetFieldDescriptorAt(UNUSED ICredentialProvider *this, DWORD index, */ static HRESULT WINAPI GetCredentialCount(ICredentialProvider *this, DWORD *count, DWORD *default_cred, - BOOL *autologon_default) + BOOL *autologon_default) { OpenVPNProvider *op = (OpenVPNProvider *) this; @@ -341,7 +347,7 @@ GetCredentialAt(ICredentialProvider *this, DWORD index, ICredentialProviderCrede OpenVPNProvider *op = (OpenVPNProvider *) this; - if(index < op->conn_count && ic) + if (index < op->conn_count && ic) { hr = QUERY_INTERFACE((ICredentialProviderCredential *) op->connections[index], &IID_ICredentialProviderCredential, (void **)ic); @@ -374,7 +380,7 @@ CreateOVPNConnectionArray(OpenVPNProvider *op) /* delete previous connections if any */ for (size_t i = 0; i < op->conn_count; i++) { - RELEASE((ICCPC*) op->connections[i]); + RELEASE((ICCPC *) op->connections[i]); } op->conn_count = 0; @@ -404,7 +410,7 @@ CreateOVPNConnectionArray(OpenVPNProvider *op) } else { - RELEASE((ICCPC*) oc); + RELEASE((ICCPC *) oc); } } else diff --git a/plap/stub.c b/plap/stub.c index 116a2d4..cad373c 100644 --- a/plap/stub.c +++ b/plap/stub.c @@ -31,7 +31,8 @@ #include "localization.h" #include "ui_glue.h" -void PrintDebugMsg(wchar_t *msg) +void +PrintDebugMsg(wchar_t *msg) { x_dmsg("GUI-source", "", msg); } @@ -40,143 +41,176 @@ void ErrorExit(UNUSED int exit_code, const wchar_t *msg) { if (msg) + { MessageBoxExW(NULL, msg, TEXT(PACKAGE_NAME), MB_OK | MB_SETFOREGROUND|MB_ICONERROR, GetGUILanguage()); + } DetachAllOpenVPN(); /* do not exit */ } -void RecreatePopupMenus(void) +void +RecreatePopupMenus(void) { return; } -void CreatePopupMenus(void) +void +CreatePopupMenus(void) { return; } -void OnNotifyTray(UNUSED LPARAM lp) +void +OnNotifyTray(UNUSED LPARAM lp) { return; } -void OnDestroyTray(void) +void +OnDestroyTray(void) { return; } -void ShowTrayIcon(void) +void +ShowTrayIcon(void) { return; } -void SetTrayIcon(UNUSED conn_state_t state) +void +SetTrayIcon(UNUSED conn_state_t state) { return; } -void SetMenuStatus(UNUSED connection_t *c, UNUSED conn_state_t state) +void +SetMenuStatus(UNUSED connection_t *c, UNUSED conn_state_t state) { return; } -void SetServiceMenuStatus(void) +void +SetServiceMenuStatus(void) { return; } -void ShowTrayBalloon(UNUSED wchar_t *s1, UNUSED wchar_t *s2) +void +ShowTrayBalloon(UNUSED wchar_t *s1, UNUSED wchar_t *s2) { return; } -void CheckAndSetTrayIcon(void) +void +CheckAndSetTrayIcon(void) { return; } -void RunPreconnectScript(UNUSED connection_t *c) +void +RunPreconnectScript(UNUSED connection_t *c) { return; } -void RunConnectScript(UNUSED connection_t *ic, UNUSED int run_as_service) +void +RunConnectScript(UNUSED connection_t *ic, UNUSED int run_as_service) { return; } -void RunDisconnectScript(UNUSED connection_t *c, UNUSED int run_as_service) +void +RunDisconnectScript(UNUSED connection_t *c, UNUSED int run_as_service) { return; } -int SaveKeyPass(UNUSED const WCHAR *config_name, UNUSED const WCHAR *password) +int +SaveKeyPass(UNUSED const WCHAR *config_name, UNUSED const WCHAR *password) { return 1; } -int SaveAuthPass(UNUSED const WCHAR *config_name, UNUSED const WCHAR *password) +int +SaveAuthPass(UNUSED const WCHAR *config_name, UNUSED const WCHAR *password) { return 1; } -int SaveUsername(UNUSED const WCHAR *config_name, UNUSED const WCHAR *username) +int +SaveUsername(UNUSED const WCHAR *config_name, UNUSED const WCHAR *username) { return 1; } -int RecallKeyPass(UNUSED const WCHAR *config_name, UNUSED WCHAR *password) +int +RecallKeyPass(UNUSED const WCHAR *config_name, UNUSED WCHAR *password) { return 0; } -int RecallAuthPass(UNUSED const WCHAR *config_name, UNUSED WCHAR *password) +int +RecallAuthPass(UNUSED const WCHAR *config_name, UNUSED WCHAR *password) { return 0; } -int RecallUsername(UNUSED const WCHAR *config_name, UNUSED WCHAR *username) +int +RecallUsername(UNUSED const WCHAR *config_name, UNUSED WCHAR *username) { return 0; } -void DeleteSavedAuthPass(UNUSED const WCHAR *config_name) +void +DeleteSavedAuthPass(UNUSED const WCHAR *config_name) { return; } -void DeleteSavedKeyPass(UNUSED const WCHAR *config_name) +void +DeleteSavedKeyPass(UNUSED const WCHAR *config_name) { return; } -void DeleteSavedPasswords(UNUSED const WCHAR *config_name) +void +DeleteSavedPasswords(UNUSED const WCHAR *config_name) { return; } -BOOL IsAuthPassSaved(UNUSED const WCHAR *config_name) +BOOL +IsAuthPassSaved(UNUSED const WCHAR *config_name) { return 0; } -BOOL IsKeyPassSaved(UNUSED const WCHAR *config_name) +BOOL +IsKeyPassSaved(UNUSED const WCHAR *config_name) { return 0; } -void env_item_del_all(UNUSED struct env_item *head) +void +env_item_del_all(UNUSED struct env_item *head) { return; } -void process_setenv(UNUSED connection_t *c, UNUSED time_t timestamp, UNUSED const char *msg) +void +process_setenv(UNUSED connection_t *c, UNUSED time_t timestamp, UNUSED const char *msg) { return; } -BOOL AuthorizeConfig(UNUSED const connection_t *c) +BOOL +AuthorizeConfig(UNUSED const connection_t *c) { return 1; } -void echo_msg_process(UNUSED connection_t *c, UNUSED time_t timestamp, UNUSED const char *msg) +void +echo_msg_process(UNUSED connection_t *c, UNUSED time_t timestamp, UNUSED const char *msg) { return; } -void echo_msg_clear(UNUSED connection_t *c, UNUSED BOOL clear_history) +void +echo_msg_clear(UNUSED connection_t *c, UNUSED BOOL clear_history) { return; } -void echo_msg_load(UNUSED connection_t *c) +void +echo_msg_load(UNUSED connection_t *c) { return; } -BOOL CheckKeyFileWriteAccess(UNUSED connection_t *c) +BOOL +CheckKeyFileWriteAccess(UNUSED connection_t *c) { return 0; } diff --git a/plap/ui_glue.c b/plap/ui_glue.c index 3c66ca3..9496b90 100644 --- a/plap/ui_glue.c +++ b/plap/ui_glue.c @@ -72,7 +72,7 @@ OnStop_(connection_t *c, UNUSED char *msg) * in PLAP context. */ static void -OnInfoMsg_(connection_t* c, char* msg) +OnInfoMsg_(connection_t *c, char *msg) { if (strbegins(msg, "CR_TEXT:")) { @@ -167,7 +167,7 @@ InitializeUI(HINSTANCE hinstance) WSADATA wsaData; /* a session local semaphore to detect second instance */ - HANDLE session_semaphore = InitSemaphore(L"Local\\"PACKAGE_NAME"-PLAP"); + HANDLE session_semaphore = InitSemaphore(L"Local\\"PACKAGE_NAME "-PLAP"); srand(time(NULL)); /* try to lock the semaphore, else we are not the first instance */ @@ -188,7 +188,7 @@ InitializeUI(HINSTANCE hinstance) dmsg(L"Starting OpenVPN UI v%hs", PACKAGE_VERSION); - if(!GetModuleHandle(_T("RICHED20.DLL"))) + if (!GetModuleHandle(_T("RICHED20.DLL"))) { LoadLibrary(_T("RICHED20.DLL")); } @@ -202,20 +202,20 @@ InitializeUI(HINSTANCE hinstance) * Some handlers are replaced by local functions */ mgmt_rtmsg_handler handler[] = { - { ready_, OnReady }, - { hold_, OnHold }, - { log_, OnLogLine }, - { state_, OnStateChange_ }, - { password_, OnPassword_ }, - { proxy_, OnProxy_ }, - { stop_, OnStop_ }, - { needok_, OnNeedOk_ }, - { needstr_, OnNeedStr_ }, - { echo_, OnEcho }, - { bytecount_,OnByteCount }, - { infomsg_, OnInfoMsg_ }, - { timeout_, OnTimeout }, - { 0, NULL} + { ready_, OnReady }, + { hold_, OnHold }, + { log_, OnLogLine }, + { state_, OnStateChange_ }, + { password_, OnPassword_ }, + { proxy_, OnProxy_ }, + { stop_, OnStop_ }, + { needok_, OnNeedOk_ }, + { needstr_, OnNeedStr_ }, + { echo_, OnEcho }, + { bytecount_, OnByteCount }, + { infomsg_, OnInfoMsg_ }, + { timeout_, OnTimeout }, + { 0, NULL} }; InitManagement(handler); @@ -267,10 +267,14 @@ InitializeUI(HINSTANCE hinstance) for (connection_t *c = o.chead; c; c = c->next) { - if (c->flags & FLAG_DAEMON_PERSISTENT) num_persistent++; + if (c->flags & FLAG_DAEMON_PERSISTENT) + { + num_persistent++; + } } - if (o.service_state == service_disconnected && num_persistent > 0) { + if (o.service_state == service_disconnected && num_persistent > 0) + { dmsg(L"Attempting to start automatic service"); StartAutomaticService(); CheckServiceStatus(); @@ -301,7 +305,7 @@ FindPLAPConnections(connection_t *conn[], size_t max_count) } static void -WaitOnThread (connection_t *c, DWORD timeout) +WaitOnThread(connection_t *c, DWORD timeout) { HANDLE h = OpenThread(THREAD_ALL_ACCESS, FALSE, c->threadId); if (!h) @@ -311,8 +315,8 @@ WaitOnThread (connection_t *c, DWORD timeout) } DWORD exit_code; - if (WaitForSingleObject(h, timeout) == WAIT_OBJECT_0 && - GetExitCodeThread(h, &exit_code) && exit_code != STILL_ACTIVE) + if (WaitForSingleObject(h, timeout) == WAIT_OBJECT_0 + && GetExitCodeThread(h, &exit_code) && exit_code != STILL_ACTIVE) { dmsg(L"Connection thread closed"); goto out; @@ -320,7 +324,7 @@ WaitOnThread (connection_t *c, DWORD timeout) /* Kill the thread */ dmsg(L"Force terminating a connection thread"); - TerminateThread (h, 1); + TerminateThread(h, 1); c->hwndStatus = NULL; c->threadId = 0; @@ -365,7 +369,7 @@ GetConnectionStatusText(connection_t *c, wchar_t *status, DWORD len) void SetParentWindow(HWND hwnd) { - o.hWnd = hwnd; + o.hWnd = hwnd; } void @@ -442,7 +446,7 @@ DeleteUI(void) FreeConfigList(&o); CloseSemaphore(o.session_semaphore); WSACleanup(); - memset (&o, 0, sizeof(o)); + memset(&o, 0, sizeof(o)); } void @@ -527,7 +531,7 @@ RunProgressDialog(connection_t *c, PFTASKDIALOGCALLBACK cb_fn, LONG_PTR cb_data) .cButtons = _countof(extra_buttons), .pButtons = extra_buttons, .dwCommonButtons = TDCBF_CANCEL_BUTTON|TDCBF_RETRY_BUTTON, - .pszWindowTitle = L""PACKAGE_NAME" PLAP", + .pszWindowTitle = L""PACKAGE_NAME " PLAP", .pszMainInstruction = main_text, .pszContent = L"Starting", /* updated in progress callback */ .pfCallback = cb_fn, diff --git a/proxy.c b/proxy.c index 68ecdec..b71ea3e 100644 --- a/proxy.c +++ b/proxy.c @@ -52,95 +52,95 @@ ProxySettingsDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, UNUSED LPARAM lPa switch (msg) { - case WM_INITDIALOG: - hIcon = LoadLocalizedIcon(ID_ICO_APP); - if (hIcon) - { - SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_SMALL), (LPARAM) (hIcon)); - SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_BIG), (LPARAM) (hIcon)); - } - - /* Limit Port editbox to 5 chars. */ - SendMessage(GetDlgItem(hwndDlg, ID_EDT_PROXY_PORT), EM_SETLIMITTEXT, 5, 0); - - LoadProxySettings(hwndDlg); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case ID_RB_PROXY_OPENVPN: - if (HIWORD(wParam) == BN_CLICKED) + case WM_INITDIALOG: + hIcon = LoadLocalizedIcon(ID_ICO_APP); + if (hIcon) { - EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_HTTP), FALSE); - EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_SOCKS), FALSE); - EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_ADDRESS), FALSE); - EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_PORT), FALSE); - EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_ADDRESS), FALSE); - EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_PORT), FALSE); + SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_SMALL), (LPARAM) (hIcon)); + SendMessage(hwndDlg, WM_SETICON, (WPARAM) (ICON_BIG), (LPARAM) (hIcon)); } - break; - case ID_RB_PROXY_MSIE: - if (HIWORD(wParam) == BN_CLICKED) - { - EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_HTTP), FALSE); - EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_SOCKS), FALSE); - EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_ADDRESS), FALSE); - EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_PORT), FALSE); - EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_ADDRESS), FALSE); - EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_PORT), FALSE); - } + /* Limit Port editbox to 5 chars. */ + SendMessage(GetDlgItem(hwndDlg, ID_EDT_PROXY_PORT), EM_SETLIMITTEXT, 5, 0); + + LoadProxySettings(hwndDlg); break; - case ID_RB_PROXY_MANUAL: - if (HIWORD(wParam) == BN_CLICKED) + case WM_COMMAND: + switch (LOWORD(wParam)) { - EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_HTTP), TRUE); - EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_SOCKS), TRUE); - EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_ADDRESS), TRUE); - EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_PORT), TRUE); - EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_ADDRESS), TRUE); - EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_PORT), TRUE); + case ID_RB_PROXY_OPENVPN: + if (HIWORD(wParam) == BN_CLICKED) + { + EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_HTTP), FALSE); + EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_SOCKS), FALSE); + EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_ADDRESS), FALSE); + EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_PORT), FALSE); + EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_ADDRESS), FALSE); + EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_PORT), FALSE); + } + break; + + case ID_RB_PROXY_MSIE: + if (HIWORD(wParam) == BN_CLICKED) + { + EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_HTTP), FALSE); + EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_SOCKS), FALSE); + EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_ADDRESS), FALSE); + EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_PORT), FALSE); + EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_ADDRESS), FALSE); + EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_PORT), FALSE); + } + break; + + case ID_RB_PROXY_MANUAL: + if (HIWORD(wParam) == BN_CLICKED) + { + EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_HTTP), TRUE); + EnableWindow(GetDlgItem(hwndDlg, ID_RB_PROXY_SOCKS), TRUE); + EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_ADDRESS), TRUE); + EnableWindow(GetDlgItem(hwndDlg, ID_EDT_PROXY_PORT), TRUE); + EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_ADDRESS), TRUE); + EnableWindow(GetDlgItem(hwndDlg, ID_TXT_PROXY_PORT), TRUE); + } + break; + + case ID_RB_PROXY_HTTP: + if (HIWORD(wParam) == BN_CLICKED) + { + SetDlgItemText(hwndDlg, ID_EDT_PROXY_ADDRESS, o.proxy_http_address); + SetDlgItemText(hwndDlg, ID_EDT_PROXY_PORT, o.proxy_http_port); + } + break; + + case ID_RB_PROXY_SOCKS: + if (HIWORD(wParam) == BN_CLICKED) + { + SetDlgItemText(hwndDlg, ID_EDT_PROXY_ADDRESS, o.proxy_socks_address); + SetDlgItemText(hwndDlg, ID_EDT_PROXY_PORT, o.proxy_socks_port); + } + break; } break; - case ID_RB_PROXY_HTTP: - if (HIWORD(wParam) == BN_CLICKED) + case WM_NOTIFY: + psn = (LPPSHNOTIFY) lParam; + if (psn->hdr.code == (UINT) PSN_KILLACTIVE) { - SetDlgItemText(hwndDlg, ID_EDT_PROXY_ADDRESS, o.proxy_http_address); - SetDlgItemText(hwndDlg, ID_EDT_PROXY_PORT, o.proxy_http_port); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (CheckProxySettings(hwndDlg) ? FALSE : TRUE)); + return TRUE; } - break; - - case ID_RB_PROXY_SOCKS: - if (HIWORD(wParam) == BN_CLICKED) + else if (psn->hdr.code == (UINT) PSN_APPLY) { - SetDlgItemText(hwndDlg, ID_EDT_PROXY_ADDRESS, o.proxy_socks_address); - SetDlgItemText(hwndDlg, ID_EDT_PROXY_PORT, o.proxy_socks_port); + SaveProxySettings(hwndDlg); + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); + return TRUE; } break; - } - break; - case WM_NOTIFY: - psn = (LPPSHNOTIFY) lParam; - if (psn->hdr.code == (UINT) PSN_KILLACTIVE) - { - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (CheckProxySettings(hwndDlg) ? FALSE : TRUE)); - return TRUE; - } - else if (psn->hdr.code == (UINT) PSN_APPLY) - { - SaveProxySettings(hwndDlg); - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); + case WM_CLOSE: + EndDialog(hwndDlg, LOWORD(wParam)); return TRUE; - } - break; - - case WM_CLOSE: - EndDialog(hwndDlg, LOWORD(wParam)); - return TRUE; } return FALSE; } @@ -250,9 +250,9 @@ SaveProxySettings(HWND hwndDlg) proxy_type_string[0] = _T('0'); GetDlgItemText(hwndDlg, ID_EDT_PROXY_ADDRESS, o.proxy_http_address, - _countof(o.proxy_http_address)); + _countof(o.proxy_http_address)); GetDlgItemText(hwndDlg, ID_EDT_PROXY_PORT, o.proxy_http_port, - _countof(o.proxy_http_port)); + _countof(o.proxy_http_port)); } else { @@ -260,9 +260,9 @@ SaveProxySettings(HWND hwndDlg) proxy_type_string[0] = _T('1'); GetDlgItemText(hwndDlg, ID_EDT_PROXY_ADDRESS, o.proxy_socks_address, - _countof(o.proxy_socks_address)); + _countof(o.proxy_socks_address)); GetDlgItemText(hwndDlg, ID_EDT_PROXY_PORT, o.proxy_socks_port, - _countof(o.proxy_socks_port)); + _countof(o.proxy_socks_port)); } /* Open Registry for writing */ @@ -300,7 +300,9 @@ GetProxyRegistrySettings() _sntprintf_0(proxy_subkey, _T("%ls\\proxy"), GUI_REGKEY_HKCU); status = RegOpenKeyEx(HKEY_CURRENT_USER, proxy_subkey, 0, KEY_READ, ®key); if (status != ERROR_SUCCESS) + { return; + } /* get registry settings */ GetRegistryValue(regkey, _T("proxy_http_address"), o.proxy_http_address, _countof(o.proxy_http_address)); @@ -338,53 +340,57 @@ ProxyAuthDialogFunc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) switch (msg) { - case WM_INITDIALOG: - /* Set connection for this dialog and show it */ - c = (connection_t *) lParam; - TRY_SETPROP(hwndDlg, cfgProp, (HANDLE) c); - if (c->state == resuming) - ForceForegroundWindow(hwndDlg); - else - SetForegroundWindow(hwndDlg); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case ID_EDT_PROXY_USER: - if (HIWORD(wParam) == EN_UPDATE) + case WM_INITDIALOG: + /* Set connection for this dialog and show it */ + c = (connection_t *) lParam; + TRY_SETPROP(hwndDlg, cfgProp, (HANDLE) c); + if (c->state == resuming) + { + ForceForegroundWindow(hwndDlg); + } + else { - int len = Edit_GetTextLength((HWND) lParam); - EnableWindow(GetDlgItem(hwndDlg, IDOK), (len ? TRUE : FALSE)); + SetForegroundWindow(hwndDlg); } break; - case IDOK: - c = (connection_t *) GetProp(hwndDlg, cfgProp); - proxy_type = (c->proxy_type == http ? "HTTP" : "SOCKS"); - - snprintf(fmt, sizeof(fmt), "username \"%s Proxy\" \"%%s\"", proxy_type); - ManagementCommandFromInput(c, fmt, hwndDlg, ID_EDT_PROXY_USER); - - snprintf(fmt, sizeof(fmt), "password \"%s Proxy\" \"%%s\"", proxy_type); - ManagementCommandFromInput(c, fmt, hwndDlg, ID_EDT_PROXY_PASS); + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case ID_EDT_PROXY_USER: + if (HIWORD(wParam) == EN_UPDATE) + { + int len = Edit_GetTextLength((HWND) lParam); + EnableWindow(GetDlgItem(hwndDlg, IDOK), (len ? TRUE : FALSE)); + } + break; + + case IDOK: + c = (connection_t *) GetProp(hwndDlg, cfgProp); + proxy_type = (c->proxy_type == http ? "HTTP" : "SOCKS"); + + snprintf(fmt, sizeof(fmt), "username \"%s Proxy\" \"%%s\"", proxy_type); + ManagementCommandFromInput(c, fmt, hwndDlg, ID_EDT_PROXY_USER); + + snprintf(fmt, sizeof(fmt), "password \"%s Proxy\" \"%%s\"", proxy_type); + ManagementCommandFromInput(c, fmt, hwndDlg, ID_EDT_PROXY_PASS); + + EndDialog(hwndDlg, LOWORD(wParam)); + return TRUE; + } + break; + case WM_OVPN_STATE: /* state changed -- destroy the dialog */ EndDialog(hwndDlg, LOWORD(wParam)); return TRUE; - } - break; - - case WM_OVPN_STATE: /* state changed -- destroy the dialog */ - EndDialog(hwndDlg, LOWORD(wParam)); - return TRUE; - case WM_CLOSE: - EndDialog(hwndDlg, LOWORD(wParam)); - return TRUE; + case WM_CLOSE: + EndDialog(hwndDlg, LOWORD(wParam)); + return TRUE; - case WM_NCDESTROY: - RemoveProp(hwndDlg, cfgProp); - break; + case WM_NCDESTROY: + RemoveProp(hwndDlg, cfgProp); + break; } return FALSE; } @@ -428,13 +434,15 @@ QueryWindowsProxySettings(const url_scheme scheme, LPCSTR host) LPWSTR old_url = auto_config_url; DWORD flags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A; if (WinHttpDetectAutoProxyConfigUrl(flags, &auto_config_url)) + { GlobalFree(old_url); + } } if (auto_config_url) { HINTERNET session = WinHttpOpen(NULL, WINHTTP_ACCESS_TYPE_NO_PROXY, - WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); + WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (session) { int size = _snwprintf(NULL, 0, L"%ls://%hs", UrlSchemeStr(scheme), host) + 1; @@ -476,7 +484,9 @@ ParseProxyString(LPWSTR proxy_str, url_scheme scheme, LPCSTR *type, LPCWSTR *host, LPCWSTR *port) { if (proxy_str == NULL) + { return; + } LPCWSTR delim = L"; "; LPWSTR ctx = NULL; @@ -518,9 +528,13 @@ ParseProxyString(LPWSTR proxy_str, url_scheme scheme, { LPWSTR server = token; if (css) + { server = css + 3; + } else if (eq) + { server = eq + 1; + } /* IPv6 addresses are surrounded by brackets */ LPWSTR port_delim; @@ -529,7 +543,9 @@ ParseProxyString(LPWSTR proxy_str, url_scheme scheme, server += 1; LPWSTR end = wcschr(server, ']'); if (end == NULL) + { continue; + } *end++ = '\0'; port_delim = (*end == ':' ? end : NULL); @@ -538,15 +554,21 @@ ParseProxyString(LPWSTR proxy_str, url_scheme scheme, { port_delim = wcsrchr(server, ':'); if (port_delim) + { *port_delim = '\0'; + } } *type = (scheme == HTTPS_URL ? "HTTP" : "SOCKS"); *host = server; if (port_delim) + { *port = port_delim + 1; + } else - *port = (scheme == HTTPS_URL ? L"80": L"1080"); + { + *port = (scheme == HTTPS_URL ? L"80" : L"1080"); + } break; } @@ -565,17 +587,23 @@ OnProxy(connection_t *c, char *line) LPSTR proto, host; char *pos = strchr(line, ','); if (pos == NULL) + { return; + } proto = ++pos; pos = strchr(pos, ','); if (pos == NULL) + { return; + } *pos = '\0'; host = ++pos; if (host[0] == '\0') + { return; + } LPCSTR type = "NONE"; LPCWSTR addr = L"", port = L""; diff --git a/proxy.h b/proxy.h index 31f9861..8395029 100644 --- a/proxy.h +++ b/proxy.h @@ -23,13 +23,17 @@ #define PROXY_H INT_PTR CALLBACK ProxySettingsDialogFunc(HWND, UINT, WPARAM, LPARAM); + void QueryProxyAuth(connection_t *, proxy_t); void OnProxy(connection_t *, char *); int CheckProxySettings(HWND); + void LoadProxySettings(HWND); + void SaveProxySettings(HWND); + void GetProxyRegistrySettings(); #endif diff --git a/registry.c b/registry.c index 1e088a1..336268f 100644 --- a/registry.c +++ b/registry.c @@ -43,159 +43,174 @@ struct regkey_str { int len; const WCHAR *value; } regkey_str[] = { - {L"config_dir", o.config_dir, _countof(o.config_dir), L"%USERPROFILE%\\OpenVPN\\config"}, - {L"config_ext", o.ext_string, _countof(o.ext_string), L"ovpn"}, - {L"log_dir", o.log_dir, _countof(o.log_dir), L"%USERPROFILE%\\OpenVPN\\log"} - }; + {L"config_dir", o.config_dir, _countof(o.config_dir), L"%USERPROFILE%\\OpenVPN\\config"}, + {L"config_ext", o.ext_string, _countof(o.ext_string), L"ovpn"}, + {L"log_dir", o.log_dir, _countof(o.log_dir), L"%USERPROFILE%\\OpenVPN\\log"} +}; struct regkey_int { const WCHAR *name; DWORD *var; DWORD value; } regkey_int[] = { - {L"log_append", &o.log_append, 0}, - {L"iservice_admin", &o.iservice_admin, 1}, - {L"show_balloon", &o.show_balloon, 1}, - {L"silent_connection", &o.silent_connection, 0}, - {L"preconnectscript_timeout", &o.preconnectscript_timeout, 10}, - {L"connectscript_timeout", &o.connectscript_timeout, 30}, - {L"disconnectscript_timeout", &o.disconnectscript_timeout, 10}, - {L"show_script_window", &o.show_script_window, 0}, - {L"config_menu_view", &o.config_menu_view, CONFIG_VIEW_AUTO}, - {L"popup_mute_interval", &o.popup_mute_interval, 24}, - {L"disable_popup_messages", &o.disable_popup_messages, 0}, - {L"management_port_offset", &o.mgmt_port_offset, 25340}, - {L"enable_peristent_connections", &o.enable_persistent, 2}, - {L"enable_auto_restart", &o.enable_auto_restart, 1}, - {L"ovpn_engine", &o.ovpn_engine, OPENVPN_ENGINE_OVPN2} - }; + {L"log_append", &o.log_append, 0}, + {L"iservice_admin", &o.iservice_admin, 1}, + {L"show_balloon", &o.show_balloon, 1}, + {L"silent_connection", &o.silent_connection, 0}, + {L"preconnectscript_timeout", &o.preconnectscript_timeout, 10}, + {L"connectscript_timeout", &o.connectscript_timeout, 30}, + {L"disconnectscript_timeout", &o.disconnectscript_timeout, 10}, + {L"show_script_window", &o.show_script_window, 0}, + {L"config_menu_view", &o.config_menu_view, CONFIG_VIEW_AUTO}, + {L"popup_mute_interval", &o.popup_mute_interval, 24}, + {L"disable_popup_messages", &o.disable_popup_messages, 0}, + {L"management_port_offset", &o.mgmt_port_offset, 25340}, + {L"enable_peristent_connections", &o.enable_persistent, 2}, + {L"enable_auto_restart", &o.enable_auto_restart, 1}, + {L"ovpn_engine", &o.ovpn_engine, OPENVPN_ENGINE_OVPN2} +}; static int -RegValueExists (HKEY regkey, const WCHAR *name) +RegValueExists(HKEY regkey, const WCHAR *name) { - return (RegQueryValueEx (regkey, name, NULL, NULL, NULL, NULL) == ERROR_SUCCESS); + return (RegQueryValueEx(regkey, name, NULL, NULL, NULL, NULL) == ERROR_SUCCESS); } static int GetGlobalRegistryKeys() { - TCHAR windows_dir[MAX_PATH]; - HKEY regkey; + TCHAR windows_dir[MAX_PATH]; + HKEY regkey; - if (!GetWindowsDirectory(windows_dir, _countof(windows_dir))) { - /* can't get windows dir */ - ShowLocalizedMsg(IDS_ERR_GET_WINDOWS_DIR); - /* Use a default value */ - _sntprintf_0(windows_dir, L"C:\\Windows"); - } + if (!GetWindowsDirectory(windows_dir, _countof(windows_dir))) + { + /* can't get windows dir */ + ShowLocalizedMsg(IDS_ERR_GET_WINDOWS_DIR); + /* Use a default value */ + _sntprintf_0(windows_dir, L"C:\\Windows"); + } - /* set default editor and log_viewer as a fallback for opening config/log files */ - _sntprintf_0(o.editor, L"%ls\\%ls", windows_dir, L"System32\\notepad.exe"); - _sntprintf_0(o.log_viewer, L"%ls", o.editor); + /* set default editor and log_viewer as a fallback for opening config/log files */ + _sntprintf_0(o.editor, L"%ls\\%ls", windows_dir, L"System32\\notepad.exe"); + _sntprintf_0(o.log_viewer, L"%ls", o.editor); - /* Get path to OpenVPN installation. */ - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\OpenVPN"), 0, KEY_READ, ®key) - != ERROR_SUCCESS) + /* Get path to OpenVPN installation. */ + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\OpenVPN"), 0, KEY_READ, ®key) + != ERROR_SUCCESS) { - /* registry key not found */ - regkey = NULL; - ShowLocalizedMsg(IDS_ERR_OPEN_REGISTRY); + /* registry key not found */ + regkey = NULL; + ShowLocalizedMsg(IDS_ERR_OPEN_REGISTRY); } - if (!regkey || !GetRegistryValue(regkey, _T(""), o.install_path, _countof(o.install_path)) - || _tcslen(o.install_path) == 0) + if (!regkey || !GetRegistryValue(regkey, _T(""), o.install_path, _countof(o.install_path)) + || _tcslen(o.install_path) == 0) { - /* error reading registry value */ - if (regkey) - ShowLocalizedMsg(IDS_ERR_READING_REGISTRY); - /* Use a sane default value */ - _sntprintf_0(o.install_path, _T("%ls"), _T("C:\\Program Files\\OpenVPN\\")); + /* error reading registry value */ + if (regkey) + { + ShowLocalizedMsg(IDS_ERR_READING_REGISTRY); + } + /* Use a sane default value */ + _sntprintf_0(o.install_path, _T("%ls"), _T("C:\\Program Files\\OpenVPN\\")); + } + if (o.install_path[_tcslen(o.install_path) - 1] != _T('\\')) + { + _tcscat(o.install_path, _T("\\")); } - if (o.install_path[_tcslen(o.install_path) - 1] != _T('\\')) - _tcscat(o.install_path, _T("\\")); - /* an admin-defined global config dir defined in HKLM\OpenVPN\config_dir */ - if (!regkey || !GetRegistryValue(regkey, _T("config_dir"), o.global_config_dir, _countof(o.global_config_dir))) + /* an admin-defined global config dir defined in HKLM\OpenVPN\config_dir */ + if (!regkey || !GetRegistryValue(regkey, _T("config_dir"), o.global_config_dir, _countof(o.global_config_dir))) { - /* use default = openvpnpath\config */ - _sntprintf_0(o.global_config_dir, _T("%lsconfig"), o.install_path); + /* use default = openvpnpath\config */ + _sntprintf_0(o.global_config_dir, _T("%lsconfig"), o.install_path); } - if (!regkey || !GetRegistryValue(regkey, _T("autostart_config_dir"), o.config_auto_dir, _countof(o.config_auto_dir))) + if (!regkey || !GetRegistryValue(regkey, _T("autostart_config_dir"), o.config_auto_dir, _countof(o.config_auto_dir))) { - /* use default = openvpnpath\config-auto */ - _sntprintf_0(o.config_auto_dir, L"%lsconfig-auto", o.install_path); + /* use default = openvpnpath\config-auto */ + _sntprintf_0(o.config_auto_dir, L"%lsconfig-auto", o.install_path); } - if (!regkey || !GetRegistryValue(regkey, _T("log_dir"), o.global_log_dir, _countof(o.global_log_dir))) + if (!regkey || !GetRegistryValue(regkey, _T("log_dir"), o.global_log_dir, _countof(o.global_log_dir))) { - /* use default = openvpnpath\log */ - _sntprintf_0(o.global_log_dir, L"%lslog", o.install_path); + /* use default = openvpnpath\log */ + _sntprintf_0(o.global_log_dir, L"%lslog", o.install_path); } - if (!regkey || !GetRegistryValue(regkey, _T("ovpn_admin_group"), o.ovpn_admin_group, _countof(o.ovpn_admin_group))) + if (!regkey || !GetRegistryValue(regkey, _T("ovpn_admin_group"), o.ovpn_admin_group, _countof(o.ovpn_admin_group))) { - _tcsncpy(o.ovpn_admin_group, OVPN_ADMIN_GROUP, _countof(o.ovpn_admin_group)-1); + _tcsncpy(o.ovpn_admin_group, OVPN_ADMIN_GROUP, _countof(o.ovpn_admin_group)-1); } - if (!regkey || !GetRegistryValue(regkey, _T("exe_path"), o.exe_path, _countof(o.exe_path))) + if (!regkey || !GetRegistryValue(regkey, _T("exe_path"), o.exe_path, _countof(o.exe_path))) { - _sntprintf_0(o.exe_path, _T("%lsbin\\openvpn.exe"), o.install_path); + _sntprintf_0(o.exe_path, _T("%lsbin\\openvpn.exe"), o.install_path); } - if (!regkey || !GetRegistryValue(regkey, _T("priority"), o.priority_string, _countof(o.priority_string))) + if (!regkey || !GetRegistryValue(regkey, _T("priority"), o.priority_string, _countof(o.priority_string))) + { + _tcsncpy(o.priority_string, _T("NORMAL_PRIORITY_CLASS"), _countof(o.priority_string)-1); + } + if (!regkey || !GetRegistryValueNumeric(regkey, _T("disable_save_passwords"), &o.disable_save_passwords)) { - _tcsncpy(o.priority_string, _T("NORMAL_PRIORITY_CLASS"), _countof(o.priority_string)-1); + o.disable_save_passwords = 0; } - if (!regkey || !GetRegistryValueNumeric(regkey, _T("disable_save_passwords"), &o.disable_save_passwords)) - { - o.disable_save_passwords = 0; - } - if (regkey) - RegCloseKey(regkey); - return true; + if (regkey) + { + RegCloseKey(regkey); + } + return true; } int -GetRegistryKeys () +GetRegistryKeys() { HKEY regkey; DWORD status; int i; if (!GetGlobalRegistryKeys()) + { return false; + } status = RegOpenKeyEx(HKEY_CURRENT_USER, GUI_REGKEY_HKCU, 0, KEY_READ, ®key); - for (i = 0 ; i < (int) _countof (regkey_str); ++i) + for (i = 0; i < (int) _countof(regkey_str); ++i) { - if ( status != ERROR_SUCCESS || - !GetRegistryValue (regkey, regkey_str[i].name, regkey_str[i].var, regkey_str[i].len)) + if (status != ERROR_SUCCESS + || !GetRegistryValue(regkey, regkey_str[i].name, regkey_str[i].var, regkey_str[i].len)) { /* no value found in registry, use the default */ - wcsncpy (regkey_str[i].var, regkey_str[i].value, regkey_str[i].len); + wcsncpy(regkey_str[i].var, regkey_str[i].value, regkey_str[i].len); regkey_str[i].var[regkey_str[i].len-1] = L'\0'; PrintDebug(L"default: %ls = %ls", regkey_str[i].name, regkey_str[i].var); } else + { PrintDebug(L"from registry: %ls = %ls", regkey_str[i].name, regkey_str[i].var); + } } - for (i = 0 ; i < (int) _countof (regkey_int); ++i) + for (i = 0; i < (int) _countof(regkey_int); ++i) { - if ( status != ERROR_SUCCESS || - !GetRegistryValueNumeric (regkey, regkey_int[i].name, regkey_int[i].var)) + if (status != ERROR_SUCCESS + || !GetRegistryValueNumeric(regkey, regkey_int[i].name, regkey_int[i].var)) { /* no value found in registry, use the default */ *regkey_int[i].var = regkey_int[i].value; PrintDebug(L"default: %ls = %lu", regkey_int[i].name, *regkey_int[i].var); } else + { PrintDebug(L"from registry: %ls = %lu", regkey_int[i].name, *regkey_int[i].var); + } } - if ( status == ERROR_SUCCESS) - RegCloseKey (regkey); + if (status == ERROR_SUCCESS) + { + RegCloseKey(regkey); + } if ((o.disconnectscript_timeout == 0)) { @@ -229,12 +244,12 @@ GetRegistryKeys () RegCloseKey(regkey); } - ExpandOptions (); + ExpandOptions(); return true; } int -SaveRegistryKeys () +SaveRegistryKeys() { HKEY regkey; DWORD status; @@ -245,27 +260,31 @@ SaveRegistryKeys () KEY_WRITE|KEY_READ, NULL, ®key, NULL); if (status != ERROR_SUCCESS) { - ShowLocalizedMsg (IDS_ERR_CREATE_REG_HKCU_KEY, GUI_REGKEY_HKCU); + ShowLocalizedMsg(IDS_ERR_CREATE_REG_HKCU_KEY, GUI_REGKEY_HKCU); goto out; } - for (i = 0 ; i < (int) _countof (regkey_str); ++i) + for (i = 0; i < (int) _countof(regkey_str); ++i) { /* save only if the value differs from default or already present in registry */ - if ( CompareStringExpanded (regkey_str[i].var, regkey_str[i].value) != 0 || - RegValueExists(regkey, regkey_str[i].name) ) + if (CompareStringExpanded(regkey_str[i].var, regkey_str[i].value) != 0 + || RegValueExists(regkey, regkey_str[i].name) ) { - if (!SetRegistryValue (regkey, regkey_str[i].name, regkey_str[i].var)) + if (!SetRegistryValue(regkey, regkey_str[i].name, regkey_str[i].var)) + { goto out; + } } } - for (i = 0 ; i < (int) _countof (regkey_int); ++i) + for (i = 0; i < (int) _countof(regkey_int); ++i) { - if ( *regkey_int[i].var != regkey_int[i].value || - RegValueExists(regkey, regkey_int[i].name) ) + if (*regkey_int[i].var != regkey_int[i].value + || RegValueExists(regkey, regkey_int[i].name) ) { - if (!SetRegistryValueNumeric (regkey, regkey_int[i].name, *regkey_int[i].var)) + if (!SetRegistryValueNumeric(regkey, regkey_int[i].name, *regkey_int[i].var)) + { goto out; + } } } ret = true; @@ -273,29 +292,33 @@ SaveRegistryKeys () out: if (status == ERROR_SUCCESS) + { RegCloseKey(regkey); + } return ret; } static BOOL -GetRegistryVersion (version_t *v) +GetRegistryVersion(version_t *v) { HKEY regkey; - CLEAR (*v); + CLEAR(*v); DWORD len = sizeof(*v); if (RegOpenKeyEx(HKEY_CURRENT_USER, GUI_REGKEY_HKCU, 0, KEY_READ, ®key) == ERROR_SUCCESS) { - if (RegGetValueW (regkey, NULL, L"version", RRF_RT_REG_BINARY, NULL, v, &len) - != ERROR_SUCCESS) - CLEAR (*v); + if (RegGetValueW(regkey, NULL, L"version", RRF_RT_REG_BINARY, NULL, v, &len) + != ERROR_SUCCESS) + { + CLEAR(*v); + } RegCloseKey(regkey); } return true; } static BOOL -SetRegistryVersion (const version_t *v) +SetRegistryVersion(const version_t *v) { HKEY regkey; DWORD status; @@ -305,12 +328,16 @@ SetRegistryVersion (const version_t *v) KEY_WRITE, NULL, ®key, NULL); if (status == ERROR_SUCCESS) { - if (RegSetValueEx(regkey, L"version", 0, REG_BINARY, (const BYTE*) v, sizeof(*v)) == ERROR_SUCCESS) + if (RegSetValueEx(regkey, L"version", 0, REG_BINARY, (const BYTE *) v, sizeof(*v)) == ERROR_SUCCESS) + { ret = true; + } RegCloseKey(regkey); } else - PrintDebug (L"Eror opening/creating 'HKCU\\%ls' registry key", GUI_REGKEY_HKCU); + { + PrintDebug(L"Eror opening/creating 'HKCU\\%ls' registry key", GUI_REGKEY_HKCU); + } return ret; } @@ -322,16 +349,18 @@ MigrateNilingsKeys() HKEY regkey, regkey_proxy, regkey_nilings; status = RegOpenKeyEx(HKEY_CURRENT_USER, L"Software\\Nilings\\OpenVPN-GUI", 0, - KEY_READ, ®key_nilings); + KEY_READ, ®key_nilings); if (status != ERROR_SUCCESS) + { return true; /* No old keys to migrate */ + } status = RegCreateKeyEx(HKEY_CURRENT_USER, GUI_REGKEY_HKCU, 0, NULL, REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, NULL, ®key, NULL); + KEY_ALL_ACCESS, NULL, ®key, NULL); if (status != ERROR_SUCCESS) { - ShowLocalizedMsg (IDS_ERR_CREATE_REG_HKCU_KEY, GUI_REGKEY_HKCU); - RegCloseKey (regkey_nilings); + ShowLocalizedMsg(IDS_ERR_CREATE_REG_HKCU_KEY, GUI_REGKEY_HKCU); + RegCloseKey(regkey_nilings); return false; } @@ -343,112 +372,132 @@ MigrateNilingsKeys() DWORD ui_lang; /* Move language setting from Nilings to GUI_REGKEY_HKCU */ if (GetRegistryValueNumeric(regkey_nilings, L"ui_language", &ui_lang)) - SetRegistryValueNumeric (regkey, L"ui_language", ui_lang); + { + SetRegistryValueNumeric(regkey, L"ui_language", ui_lang); + } - status = RegCopyTree (regkey_nilings, NULL, regkey_proxy); + status = RegCopyTree(regkey_nilings, NULL, regkey_proxy); if (status == ERROR_SUCCESS) { - RegDeleteValue (regkey_proxy, L"ui_language"); /* in case copied here */ + RegDeleteValue(regkey_proxy, L"ui_language"); /* in case copied here */ ret = true; } - RegCloseKey (regkey_proxy); + RegCloseKey(regkey_proxy); } else - PrintDebug (L"Error creating key 'proxy' in HKCU\\%ls", GUI_REGKEY_HKCU); + { + PrintDebug(L"Error creating key 'proxy' in HKCU\\%ls", GUI_REGKEY_HKCU); + } - RegCloseKey (regkey); - RegCloseKey (regkey_nilings); + RegCloseKey(regkey); + RegCloseKey(regkey_nilings); return ret; } int -UpdateRegistry (void) +UpdateRegistry(void) { version_t v; - GetRegistryVersion (&v); + GetRegistryVersion(&v); if (memcmp(&v, &o.version, sizeof(v)) == 0) + { return true; + } switch (v.major) { case 0: /* Cleanup GUI_REGKEY_HKCU and migrate any values under Nilings */ - RegDeleteTree (HKEY_CURRENT_USER, GUI_REGKEY_HKCU); /* delete all values and subkeys */ + RegDeleteTree(HKEY_CURRENT_USER, GUI_REGKEY_HKCU); /* delete all values and subkeys */ if (!MigrateNilingsKeys()) + { return false; + } + /* fall through to handle further updates */ case 11: /* current version -- nothing to do */ break; + default: break; } - SetRegistryVersion (&o.version); - PrintDebug (L"Registry updated to version %hu.%hu", o.version.major, o.version.minor); + SetRegistryVersion(&o.version); + PrintDebug(L"Registry updated to version %hu.%hu", o.version.major, o.version.minor); return true; } -LONG GetRegistryValue(HKEY regkey, const TCHAR *name, TCHAR *data, DWORD len) +LONG +GetRegistryValue(HKEY regkey, const TCHAR *name, TCHAR *data, DWORD len) { - LONG status; - DWORD type; - DWORD data_len; + LONG status; + DWORD type; + DWORD data_len; - data_len = len * sizeof(*data); + data_len = len * sizeof(*data); - /* get a registry string */ - status = RegQueryValueEx(regkey, name, NULL, &type, (byte *) data, &data_len); - if (status != ERROR_SUCCESS || type != REG_SZ) - return(0); + /* get a registry string */ + status = RegQueryValueEx(regkey, name, NULL, &type, (byte *) data, &data_len); + if (status != ERROR_SUCCESS || type != REG_SZ) + { + return(0); + } - data_len /= sizeof(*data); - if (data_len > 0) - data[data_len - 1] = L'\0'; /* REG_SZ strings are not guaranteed to be null-terminated */ - else - data[0] = L'\0'; + data_len /= sizeof(*data); + if (data_len > 0) + { + data[data_len - 1] = L'\0'; /* REG_SZ strings are not guaranteed to be null-terminated */ + } + else + { + data[0] = L'\0'; + } - return(data_len); + return(data_len); } LONG GetRegistryValueNumeric(HKEY regkey, const TCHAR *name, DWORD *data) { - DWORD type; - DWORD size = sizeof(*data); - LONG status = RegQueryValueEx(regkey, name, NULL, &type, (PBYTE) data, &size); - return (type == REG_DWORD && status == ERROR_SUCCESS) ? 1 : 0; + DWORD type; + DWORD size = sizeof(*data); + LONG status = RegQueryValueEx(regkey, name, NULL, &type, (PBYTE) data, &size); + return (type == REG_DWORD && status == ERROR_SUCCESS) ? 1 : 0; } -int SetRegistryValue(HKEY regkey, const TCHAR *name, const TCHAR *data) +int +SetRegistryValue(HKEY regkey, const TCHAR *name, const TCHAR *data) { - /* set a registry string */ - DWORD size = (_tcslen(data) + 1) * sizeof(*data); - if(RegSetValueEx(regkey, name, 0, REG_SZ, (PBYTE) data, size) != ERROR_SUCCESS) + /* set a registry string */ + DWORD size = (_tcslen(data) + 1) * sizeof(*data); + if (RegSetValueEx(regkey, name, 0, REG_SZ, (PBYTE) data, size) != ERROR_SUCCESS) { - /* Error writing registry value */ - ShowLocalizedMsg(IDS_ERR_WRITE_REGVALUE, GUI_REGKEY_HKCU, name); - return(0); + /* Error writing registry value */ + ShowLocalizedMsg(IDS_ERR_WRITE_REGVALUE, GUI_REGKEY_HKCU, name); + return(0); } - return(1); + return(1); } int SetRegistryValueNumeric(HKEY regkey, const TCHAR *name, DWORD data) { - LONG status = RegSetValueEx(regkey, name, 0, REG_DWORD, (PBYTE) &data, sizeof(data)); - if (status == ERROR_SUCCESS) - return 1; + LONG status = RegSetValueEx(regkey, name, 0, REG_DWORD, (PBYTE) &data, sizeof(data)); + if (status == ERROR_SUCCESS) + { + return 1; + } - ShowLocalizedMsg(IDS_ERR_WRITE_REGVALUE, GUI_REGKEY_HKCU, name); - return 0; + ShowLocalizedMsg(IDS_ERR_WRITE_REGVALUE, GUI_REGKEY_HKCU, name); + return 0; } /* @@ -464,18 +513,24 @@ OpenConfigRegistryKey(const WCHAR *config_name, HKEY *regkey, BOOL create) WCHAR *name = malloc(count * sizeof(WCHAR)); if (!name) + { return 0; + } _snwprintf(name, count, fmt, config_name); name[count-1] = L'\0'; if (!create) - status = RegOpenKeyEx (HKEY_CURRENT_USER, name, 0, KEY_READ | KEY_WRITE, regkey); + { + status = RegOpenKeyEx(HKEY_CURRENT_USER, name, 0, KEY_READ | KEY_WRITE, regkey); + } else - /* create if key doesn't exist */ - status = RegCreateKeyEx(HKEY_CURRENT_USER, name, 0, NULL, - REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, regkey, NULL); - free (name); + { + /* create if key doesn't exist */ + status = RegCreateKeyEx(HKEY_CURRENT_USER, name, 0, NULL, + REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, regkey, NULL); + } + free(name); return (status == ERROR_SUCCESS); } @@ -487,7 +542,9 @@ SetConfigRegistryValueBinary(const WCHAR *config_name, const WCHAR *name, const DWORD status; if (!OpenConfigRegistryKey(config_name, ®key, TRUE)) + { return 0; + } status = RegSetValueEx(regkey, name, 0, REG_BINARY, data, len); RegCloseKey(regkey); @@ -507,13 +564,19 @@ GetConfigRegistryValue(const WCHAR *config_name, const WCHAR *name, BYTE *data, HKEY regkey; if (!OpenConfigRegistryKey(config_name, ®key, FALSE)) + { return 0; + } status = RegQueryValueEx(regkey, name, NULL, &type, data, &len); RegCloseKey(regkey); if (status == ERROR_SUCCESS) + { return len; + } else + { return 0; + } } int @@ -523,7 +586,9 @@ DeleteConfigRegistryValue(const WCHAR *config_name, const WCHAR *name) HKEY regkey; if (!OpenConfigRegistryKey(config_name, ®key, FALSE)) + { return 0; + } status = RegDeleteValue(regkey, name); RegCloseKey(regkey); diff --git a/registry.h b/registry.h index 272e7c0..5128c24 100644 --- a/registry.h +++ b/registry.h @@ -23,15 +23,25 @@ #define REGISTRY_H int GetRegistryKeys(void); + int SaveRegistryKeys(void); + int UpdateRegistry(void); + int GetRegKey(const TCHAR name[], TCHAR data[], const TCHAR default_data[], DWORD len); + LONG GetRegistryValue(HKEY regkey, const TCHAR *name, TCHAR *data, DWORD len); + LONG GetRegistryValueNumeric(HKEY regkey, const TCHAR *name, DWORD *data); + int SetRegistryValue(HKEY regkey, const TCHAR *name, const TCHAR *data); + int SetRegistryValueNumeric(HKEY regkey, const TCHAR *name, DWORD data); + int SetConfigRegistryValueBinary(const WCHAR *config_name, const WCHAR *name, const BYTE *data, DWORD len); + DWORD GetConfigRegistryValue(const WCHAR *config_name, const WCHAR *name, BYTE *data, DWORD len); + int DeleteConfigRegistryValue(const WCHAR *config_name, const WCHAR *name); -#endif +#endif /* ifndef REGISTRY_H */ diff --git a/save_pass.c b/save_pass.c index aa9df66..f2dff33 100644 --- a/save_pass.c +++ b/save_pass.c @@ -46,10 +46,10 @@ crypt_protect(BYTE *data, int szdata, char *entropy, BYTE **out) data_in.pbData = data; data_in.cbData = szdata; - e.pbData = (BYTE*) entropy; - e.cbData = entropy? strlen(entropy) : 0; + e.pbData = (BYTE *) entropy; + e.cbData = entropy ? strlen(entropy) : 0; - if(CryptProtectData(&data_in, NULL, &e, NULL, NULL, 0, &data_out)) + if (CryptProtectData(&data_in, NULL, &e, NULL, NULL, 0, &data_out)) { *out = data_out.pbData; return data_out.cbData; @@ -62,15 +62,15 @@ static DWORD crypt_unprotect(BYTE *data, int szdata, char *entropy, BYTE **out) { DATA_BLOB data_in; - DATA_BLOB data_out = {0,0}; + DATA_BLOB data_out = {0, 0}; DATA_BLOB e; data_in.pbData = data; data_in.cbData = szdata; e.pbData = (BYTE *) entropy; - e.cbData = entropy? strlen(entropy) : 0; + e.cbData = entropy ? strlen(entropy) : 0; - if(CryptUnprotectData(&data_in, NULL, &e, NULL, NULL, 0, &data_out)) + if (CryptUnprotectData(&data_in, NULL, &e, NULL, NULL, 0, &data_out)) { *out = data_out.pbData; return data_out.cbData; @@ -78,7 +78,7 @@ crypt_unprotect(BYTE *data, int szdata, char *entropy, BYTE **out) else { PrintDebug(L"CryptUnprotectData: decryption failed"); - LocalFree (data_out.pbData); + LocalFree(data_out.pbData); return 0; } } @@ -105,10 +105,14 @@ get_entropy(const WCHAR *config_name, char *e, int sz, BOOL generate) e[sz-1] = '\0'; PrintDebug(L"Created new entropy string : %hs", e); if (SetConfigRegistryValueBinary(config_name, ENTROPY_DATA, (BYTE *)e, sz)) + { return; + } } if (generate) + { PrintDebug(L"Failed to generate or save new entropy string -- using null string"); + } *e = '\0'; return; } @@ -125,15 +129,17 @@ save_encrypted(const WCHAR *config_name, const WCHAR *password, const WCHAR *nam char entropy[ENTROPY_LEN+1]; get_entropy(config_name, entropy, sizeof(entropy), true); - len = crypt_protect((BYTE*) password, len, entropy, &out); - if(len > 0) + len = crypt_protect((BYTE *) password, len, entropy, &out); + if (len > 0) { SetConfigRegistryValueBinary(config_name, name, out, len); LocalFree(out); return 1; } else + { return 0; + } } /* @@ -171,15 +177,19 @@ recall_encrypted(const WCHAR *config_name, WCHAR *password, DWORD capacity, cons get_entropy(config_name, entropy, sizeof(entropy), false); - memset (password, 0, capacity); + memset(password, 0, capacity); len = GetConfigRegistryValue(config_name, name, in, sizeof(in)); - if(len == 0) + if (len == 0) + { return 0; + } len = crypt_unprotect(in, len, entropy, &out); - if(len == 0) + if (len == 0) + { return 0; + } if (len <= capacity * sizeof(*password)) { @@ -188,7 +198,9 @@ recall_encrypted(const WCHAR *config_name, WCHAR *password, DWORD capacity, cons retval = 1; } else + { PrintDebug(L"recall_encrypted: saved '%ls' too long (len = %d bytes)", name, len); + } SecureZeroMemory(out, len); LocalFree(out); @@ -222,7 +234,7 @@ int SaveUsername(const WCHAR *config_name, const WCHAR *username) { DWORD len = (wcslen(username) + 1) * sizeof(*username); - SetConfigRegistryValueBinary(config_name, AUTH_USER_DATA,(BYTE *) username, len); + SetConfigRegistryValueBinary(config_name, AUTH_USER_DATA, (BYTE *) username, len); return 1; } /* @@ -237,7 +249,9 @@ RecallUsername(const WCHAR *config_name, WCHAR *username) len = GetConfigRegistryValue(config_name, AUTH_USER_DATA, (BYTE *) username, capacity); if (len == 0) + { return 0; + } username[USER_PASS_LEN-1] = L'\0'; return 1; } diff --git a/save_pass.h b/save_pass.h index 5f4c7a5..034854f 100644 --- a/save_pass.h +++ b/save_pass.h @@ -28,17 +28,25 @@ #define KEY_PASS_LEN 128 int SaveKeyPass(const WCHAR *config_name, const WCHAR *password); + int SaveAuthPass(const WCHAR *config_name, const WCHAR *password); + int SaveUsername(const WCHAR *config_name, const WCHAR *username); int RecallKeyPass(const WCHAR *config_name, WCHAR *password); + int RecallAuthPass(const WCHAR *config_name, WCHAR *password); + int RecallUsername(const WCHAR *config_name, WCHAR *username); void DeleteSavedAuthPass(const WCHAR *config_name); + void DeleteSavedKeyPass(const WCHAR *config_name); + void DeleteSavedPasswords(const WCHAR *config_name); BOOL IsAuthPassSaved(const WCHAR *config_name); + BOOL IsKeyPassSaved(const WCHAR *config_name); -#endif + +#endif /* ifndef SAVEPASS_H */ diff --git a/scripts.c b/scripts.c index f37fb65..d7b3cb6 100644 --- a/scripts.c +++ b/scripts.c @@ -60,13 +60,15 @@ RunPreconnectScript(connection_t *c) /* Return if no script exists */ if (_tstat(cmdline, &st) == -1) + { return; + } - // Create the filename of the logfile + /* Create the filename of the logfile */ TCHAR script_log_filename[MAX_PATH]; _sntprintf_0(script_log_filename, _T("%ls\\%ls_pre.log"), o.log_dir, c->config_name); - // Create the log file + /* Create the log file */ SECURITY_ATTRIBUTES sa; CLEAR(sa); sa.nLength = sizeof(SECURITY_ATTRIBUTES); @@ -133,16 +135,20 @@ RunConnectScript(connection_t *c, int run_as_service) /* Return if no script exists */ if (_tstat(cmdline, &st) == -1) + { return; + } if (!run_as_service) + { SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_CONN_SCRIPT)); + } - // Create the filename of the logfile + /* Create the filename of the logfile */ TCHAR script_log_filename[MAX_PATH]; _sntprintf_0(script_log_filename, _T("%ls\\%ls_up.log"), o.log_dir, c->config_name); - // Create the log file + /* Create the log file */ SECURITY_ATTRIBUTES sa; CLEAR(sa); sa.nLength = sizeof(SECURITY_ATTRIBUTES); @@ -175,7 +181,9 @@ RunConnectScript(connection_t *c, int run_as_service) } if (o.connectscript_timeout == 0) + { goto out; + } for (i = 0; i <= (int) o.connectscript_timeout; i++) { @@ -188,7 +196,9 @@ RunConnectScript(connection_t *c, int run_as_service) if (exit_code != STILL_ACTIVE) { if (exit_code != 0) + { ShowLocalizedMsgEx(MB_OK|MB_ICONERROR, c->hwndStatus, TEXT(PACKAGE_NAME), IDS_ERR_CONN_SCRIPT_FAILED, exit_code); + } goto out; } @@ -227,16 +237,20 @@ RunDisconnectScript(connection_t *c, int run_as_service) /* Return if no script exists */ if (_tstat(cmdline, &st) == -1) + { return; + } if (!run_as_service) + { SetDlgItemText(c->hwndStatus, ID_TXT_STATUS, LoadLocalizedString(IDS_NFO_STATE_DISCONN_SCRIPT)); + } - // Create the filename of the logfile + /* Create the filename of the logfile */ TCHAR script_log_filename[MAX_PATH]; _sntprintf_0(script_log_filename, _T("%ls\\%ls_down.log"), o.log_dir, c->config_name); - // Create the log file + /* Create the log file */ SECURITY_ATTRIBUTES sa; CLEAR(sa); sa.nLength = sizeof(SECURITY_ATTRIBUTES); diff --git a/scripts.h b/scripts.h index b9a5a14..33207d0 100644 --- a/scripts.h +++ b/scripts.h @@ -24,7 +24,9 @@ #define SCRIPTS_H void RunPreconnectScript(connection_t *); + void RunConnectScript(connection_t *, int run_as_service); + void RunDisconnectScript(connection_t *, int run_as_service); #endif diff --git a/service.c b/service.c index 60d5ca7..9540ab4 100644 --- a/service.c +++ b/service.c @@ -46,26 +46,32 @@ CheckIServiceStatus(BOOL warn) SERVICE_STATUS ssStatus; BOOL ret = false; - // Open a handle to the SC Manager database. + /* Open a handle to the SC Manager database. */ schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (NULL == schSCManager) + { return(false); + } schService = OpenService(schSCManager, o.ovpn_engine == OPENVPN_ENGINE_OVPN3 ? - OPENVPN_SERVICE_NAME_OVPN3 : OPENVPN_SERVICE_NAME_OVPN2, SERVICE_QUERY_STATUS); + OPENVPN_SERVICE_NAME_OVPN3 : OPENVPN_SERVICE_NAME_OVPN2, SERVICE_QUERY_STATUS); - if (schService == NULL && - GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) + if (schService == NULL + && GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) { /* warn that iservice is not installed */ if (warn) + { ShowLocalizedMsg(IDS_ERR_INSTALL_ISERVICE); + } goto out; } if (!QueryServiceStatus(schService, &ssStatus)) + { goto out; + } if (ssStatus.dwCurrentState != SERVICE_RUNNING) { @@ -73,9 +79,13 @@ CheckIServiceStatus(BOOL warn) if (warn) { if (IsUserAdmin()) + { ShowLocalizedMsg(IDS_ERR_NOTSTARTED_ISERVICE_ADM); + } else + { ShowLocalizedMsg(IDS_ERR_NOTSTARTED_ISERVICE); + } } goto out; } @@ -83,42 +93,49 @@ CheckIServiceStatus(BOOL warn) out: if (schService) + { CloseServiceHandle(schService); + } if (schSCManager) + { CloseServiceHandle(schSCManager); + } return ret; } -VOID CheckServiceStatus() +VOID +CheckServiceStatus() { SC_HANDLE schSCManager = NULL; SC_HANDLE schService = NULL; SERVICE_STATUS ssStatus; - // Open a handle to the SC Manager database. + /* Open a handle to the SC Manager database. */ schSCManager = OpenSCManager( - NULL, // local machine - NULL, // ServicesActive database - SC_MANAGER_CONNECT); // Connect rights + NULL, /* local machine */ + NULL, /* ServicesActive database */ + SC_MANAGER_CONNECT); /* Connect rights */ - if (NULL == schSCManager) { + if (NULL == schSCManager) + { o.service_state = service_noaccess; goto out; } schService = OpenService( - schSCManager, // SCM database - _T("OpenVPNService"), // service name + schSCManager, /* SCM database */ + _T("OpenVPNService"), /* service name */ SERVICE_QUERY_STATUS); - if (schService == NULL) { + if (schService == NULL) + { o.service_state = service_noaccess; goto out; } if (!QueryServiceStatus( - schService, // handle to service - &ssStatus) ) // address of status information structure + schService, /* handle to service */ + &ssStatus) ) /* address of status information structure */ { /* query failed */ o.service_state = service_noaccess; @@ -139,25 +156,32 @@ VOID CheckServiceStatus() out: if (schService) + { CloseServiceHandle(schService); + } if (schSCManager) + { CloseServiceHandle(schSCManager); + } } /* Attempt to start OpenVPN Automatc Service */ -void StartAutomaticService(void) +void +StartAutomaticService(void) { SC_HANDLE schSCManager = NULL; SC_HANDLE schService = NULL; schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); - if (schSCManager) { + if (schSCManager) + { schService = OpenService(schSCManager, L"OpenVPNService", SERVICE_START); - if (schService) { - StartService(schService, 0, NULL); - CloseServiceHandle(schService); + if (schService) + { + StartService(schService, 0, NULL); + CloseServiceHandle(schService); } CloseServiceHandle(schSCManager); diff --git a/service.h b/service.h index 511017a..d7f0de5 100644 --- a/service.h +++ b/service.h @@ -20,6 +20,8 @@ */ VOID CheckServiceStatus(); + BOOL CheckIServiceStatus(BOOL warn); + /* Attempt to start OpenVPN Automatc Service */ void StartAutomaticService(void); diff --git a/tray.c b/tray.c index 0e0f1ba..2c645b1 100644 --- a/tray.c +++ b/tray.c @@ -50,13 +50,14 @@ NOTIFYICONDATA ni; extern options_t o; #define USE_NESTED_CONFIG_MENU ((o.config_menu_view == CONFIG_VIEW_AUTO && o.num_configs > 25) \ - || (o.config_menu_view == CONFIG_VIEW_NESTED)) + || (o.config_menu_view == CONFIG_VIEW_NESTED)) static void DeleteMenuBitmaps(void) { - if (hbmpConnecting) { + if (hbmpConnecting) + { DeleteObject(hbmpConnecting); hbmpConnecting = NULL; } @@ -92,8 +93,14 @@ CreateMenuBitmaps(void) { DeleteObject(iconinfo.hbmMask); DeleteObject(iconinfo.hbmColor); - if (maskDC) DeleteDC(maskDC); - if (imgDC) DeleteDC(imgDC); + if (maskDC) + { + DeleteDC(maskDC); + } + if (imgDC) + { + DeleteDC(imgDC); + } MsgToEventLog(EVENTLOG_ERROR_TYPE, L"Error creating DCs for drawing"); return; } @@ -106,10 +113,14 @@ CreateMenuBitmaps(void) COLORREF ref = RGB(255, 255, 255); COLORREF bg = GetSysColor(COLOR_MENU); - for (int x = 0; x < cx; x++) { - for (int y = 0; y < cy; y++) { + for (int x = 0; x < cx; x++) + { + for (int y = 0; y < cy; y++) + { if (GetPixel(maskDC, x, y) == ref) + { SetPixel(imgDC, x, y, bg); + } } } @@ -132,13 +143,18 @@ CreateMenuBitmaps(void) void AllocateConnectionMenu() { - if (hmenu_size >= o.num_configs) return; + if (hmenu_size >= o.num_configs) + { + return; + } HMENU *tmp = (HMENU *) realloc(hMenuConn, sizeof(HMENU)*(o.num_configs + 50)); - if (tmp) { + if (tmp) + { hmenu_size = o.num_configs + 50; hMenuConn = tmp; } - else { + else + { o.num_configs = hmenu_size; MsgToEventLog(EVENTLOG_ERROR_TYPE, L"Allocation of hMenuConn failed. Ignoring configs beyond index = %d", o.num_configs); } @@ -175,7 +191,9 @@ CreatePopupMenus() for (int i = 0; i < o.num_groups; i++) { if (!o.groups[i].active) + { continue; + } o.groups[i].menu = CreatePopupMenu(); o.groups[i].children = 0; /* we have to recount this when assigning menu position index */ } @@ -188,7 +206,8 @@ CreatePopupMenus() minfo.dwStyle |= MNS_NOTIFYBYPOS; SetMenuInfo(hMenu, &minfo); - if (o.num_configs == 1 && o.chead) { + if (o.num_configs == 1 && o.chead) + { /* Set main menu's menudata to first connection */ minfo.fMask = MIM_MENUDATA; GetMenuInfo(hMenu, &minfo); @@ -215,12 +234,13 @@ CreatePopupMenus() AppendMenu(hMenuImport, MF_STRING, IDM_IMPORT_AS, LoadLocalizedString(IDS_MENU_IMPORT_AS)); AppendMenu(hMenuImport, MF_STRING, IDM_IMPORT_URL, LoadLocalizedString(IDS_MENU_IMPORT_URL)); - AppendMenu(hMenu, MF_STRING ,IDM_SETTINGS, LoadLocalizedString(IDS_MENU_SETTINGS)); - AppendMenu(hMenu, MF_STRING ,IDM_CLOSE, LoadLocalizedString(IDS_MENU_CLOSE)); + AppendMenu(hMenu, MF_STRING, IDM_SETTINGS, LoadLocalizedString(IDS_MENU_SETTINGS)); + AppendMenu(hMenu, MF_STRING, IDM_CLOSE, LoadLocalizedString(IDS_MENU_CLOSE)); SetMenuStatus(o.chead, o.chead->state); } - else { + else + { /* construct the submenu tree first */ /* i = 0 is the root menu and has no parent */ for (int i = 1; i < o.num_groups; i++) @@ -240,7 +260,7 @@ CreatePopupMenus() this->pos = parent->children++; PrintDebug(L"Submenu %d named %ls added to parent %ls with position %d", - i, this->name, parent->name, this->pos); + i, this->name, parent->name, this->pos); } /* add config file (connection) entries */ @@ -268,11 +288,13 @@ CreatePopupMenus() c->pos = parent->children++; PrintDebug(L"Config %d named %ls added to submenu %ls with position %d", - c->id, c->config_name, parent->name, c->pos); + c->id, c->config_name, parent->name, c->pos); } if (o.num_configs > 0) + { AppendMenu(hMenu, MF_SEPARATOR, 0, 0); + } hMenuImport = CreatePopupMenu(); AppendMenu(hMenu, MF_POPUP, (UINT_PTR) hMenuImport, LoadLocalizedString(IDS_MENU_IMPORT)); @@ -337,17 +359,18 @@ OnNotifyTray(LPARAM lParam) { POINT pt; - switch (lParam) { - case WM_RBUTTONUP: - RecreatePopupMenus(); + switch (lParam) + { + case WM_RBUTTONUP: + RecreatePopupMenus(); - GetCursorPos(&pt); - SetForegroundWindow(o.hWnd); - TrackPopupMenu(hMenu, TPM_RIGHTALIGN, pt.x, pt.y, 0, o.hWnd, NULL); - PostMessage(o.hWnd, WM_NULL, 0, 0); - break; + GetCursorPos(&pt); + SetForegroundWindow(o.hWnd); + TrackPopupMenu(hMenu, TPM_RIGHTALIGN, pt.x, pt.y, 0, o.hWnd, NULL); + PostMessage(o.hWnd, WM_NULL, 0, 0); + break; - case WM_LBUTTONDBLCLK: + case WM_LBUTTONDBLCLK: { int disconnected_conns = CountConnState(disconnected); @@ -355,26 +378,33 @@ OnNotifyTray(LPARAM lParam) /* Start connection if only one config exist */ if (o.num_configs == 1 && o.chead->state == disconnected) - StartOpenVPN(o.chead); + { + StartOpenVPN(o.chead); + } /* show the status window of all connected/connecting profiles upto a max of 10 */ - else if (disconnected_conns < o.num_configs) { + else if (disconnected_conns < o.num_configs) + { int num_shown = 0; for (connection_t *c = o.chead; c; c = c->next) { - if (c->state != disconnected && c->hwndStatus) { + if (c->state != disconnected && c->hwndStatus) + { ShowWindow(c->hwndStatus, SW_SHOW); SetForegroundWindow(c->hwndStatus); - if (++num_shown >= 10) break; + if (++num_shown >= 10) + { + break; + } } } } } break; - case WM_OVPN_RESCAN: - /* Rescan config folders and recreate popup menus */ - RecreatePopupMenus(); - break; + case WM_OVPN_RESCAN: + /* Rescan config folders and recreate popup menus */ + RecreatePopupMenus(); + break; } } @@ -398,15 +428,15 @@ OnDestroyTray() void ShowTrayIcon() { - ni.cbSize = sizeof(ni); - ni.uID = 0; - ni.hWnd = o.hWnd; - ni.uFlags = NIF_MESSAGE | NIF_TIP | NIF_ICON; - ni.uCallbackMessage = WM_NOTIFYICONTRAY; - ni.hIcon = LoadLocalizedSmallIcon(ID_ICO_DISCONNECTED); - _tcsncpy(ni.szTip, LoadLocalizedString(IDS_TIP_DEFAULT), _countof(ni.szTip)); - - Shell_NotifyIcon(NIM_ADD, &ni); + ni.cbSize = sizeof(ni); + ni.uID = 0; + ni.hWnd = o.hWnd; + ni.uFlags = NIF_MESSAGE | NIF_TIP | NIF_ICON; + ni.uCallbackMessage = WM_NOTIFYICONTRAY; + ni.hIcon = LoadLocalizedSmallIcon(ID_ICO_DISCONNECTED); + _tcsncpy(ni.szTip, LoadLocalizedString(IDS_TIP_DEFAULT), _countof(ni.szTip)); + + Shell_NotifyIcon(NIM_ADD, &ni); } void @@ -426,7 +456,8 @@ SetTrayIcon(conn_state_t state) first_conn = TRUE; for (connection_t *c = o.chead; c; c = c->next) { - if (c->state == connected) { + if (c->state == connected) + { /* Append connection name to Icon Tip Msg */ _tcsncat(msg, (first_conn ? msg_connected : _T(", ")), _countof(msg) - _tcslen(msg) - 1); _tcsncat(msg, c->config_name, _countof(msg) - _tcslen(msg) - 1); @@ -438,7 +469,8 @@ SetTrayIcon(conn_state_t state) first_conn = TRUE; for (connection_t *c = o.chead; c; c = c->next) { - if (c->state == connecting || c->state == resuming || c->state == reconnecting) { + if (c->state == connecting || c->state == resuming || c->state == reconnecting) + { /* Append connection name to Icon Tip Msg */ _tcsncat(msg, (first_conn ? msg_connecting : _T(", ")), _countof(msg) - _tcslen(msg) - 1); _tcsncat(msg, c->config_name, _countof(msg) - _tcslen(msg) - 1); @@ -446,7 +478,8 @@ SetTrayIcon(conn_state_t state) } } - if (CountConnState(connected) == 1 && cc) { + if (CountConnState(connected) == 1 && cc) + { /* Append "Connected since and assigned IP" to message */ TCHAR time[50]; @@ -463,9 +496,13 @@ SetTrayIcon(conn_state_t state) icon_id = ID_ICO_CONNECTING; if (state == connected) + { icon_id = ID_ICO_CONNECTED; + } else if (state == disconnected) + { icon_id = ID_ICO_DISCONNECTED; + } ni.cbSize = sizeof(ni); ni.uID = 0; @@ -490,9 +527,13 @@ CheckAndSetTrayIcon() { if (CountConnState(connecting) != 0 || CountConnState(reconnecting) != 0 || CountConnState(resuming) != 0) + { SetTrayIcon(connecting); + } else + { SetTrayIcon(disconnected); + } } } @@ -519,8 +560,14 @@ SetMenuStatus(connection_t *c, conn_state_t state) int checked = 0; int i = c->id; - if (state == connected || state == disconnecting) checked = 1; - else if (state != disconnected && state != detached && state != onhold) checked = 2; + if (state == connected || state == disconnecting) + { + checked = 1; + } + else if (state != disconnected && state != detached && state != onhold) + { + checked = 2; + } if (o.num_configs == 1) { @@ -553,9 +600,13 @@ SetMenuStatus(connection_t *c, conn_state_t state) 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); + } } else { @@ -584,7 +635,7 @@ SetMenuStatus(connection_t *c, conn_state_t state) CheckMenuItem(parent->menu, pos, MF_BYPOSITION | (checked ? MF_CHECKED : MF_UNCHECKED)); PrintDebug(L"Setting state of config %ls checked = %d, parent %ls, pos %d", - c->config_name, checked, (parent->id == 0)? L"Main Menu" : L"SubMenu", pos); + c->config_name, checked, (parent->id == 0) ? L"Main Menu" : L"SubMenu", pos); if (checked) /* also check all parent groups */ { @@ -625,8 +676,12 @@ SetMenuStatus(connection_t *c, conn_state_t state) EnableMenuItem(hMenuConn[i], IDM_STATUSMENU, MF_ENABLED); } if (c->flags & (FLAG_SAVE_AUTH_PASS | FLAG_SAVE_KEY_PASS)) + { EnableMenuItem(hMenuConn[i], IDM_CLEARPASSMENU, MF_ENABLED); + } else + { EnableMenuItem(hMenuConn[i], IDM_CLEARPASSMENU, MF_GRAYED); + } } } diff --git a/tray.h b/tray.h index 3f4e69b..199d3c3 100644 --- a/tray.h +++ b/tray.h @@ -46,15 +46,25 @@ #define IDM_RECONNECTMENU (1 + IDM_CLEARPASSMENU) void RecreatePopupMenus(void); + void CreatePopupMenus(); + void OnNotifyTray(LPARAM); + void OnDestroyTray(void); + void ShowTrayIcon(); + void RemoveTrayIcon(); + void SetTrayIcon(conn_state_t); + void SetMenuStatus(connection_t *, conn_state_t); + void SetServiceMenuStatus(); + void ShowTrayBalloon(TCHAR *, TCHAR *); + void CheckAndSetTrayIcon(); -#endif +#endif /* ifndef TRAY_H */ diff --git a/viewlog.c b/viewlog.c index 94d80cb..c1ea744 100644 --- a/viewlog.c +++ b/viewlog.c @@ -37,112 +37,122 @@ extern options_t o; -void ViewLog(connection_t *c) +void +ViewLog(connection_t *c) { - TCHAR filename[2*MAX_PATH]; - - STARTUPINFO start_info; - PROCESS_INFORMATION proc_info; - SECURITY_ATTRIBUTES sa; - SECURITY_DESCRIPTOR sd; - HINSTANCE status; - - CLEAR (start_info); - CLEAR (proc_info); - CLEAR (sa); - CLEAR (sd); - - /* Try first using file association */ - CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); /* Safe to init COM multiple times */ - status = ShellExecuteW (o.hWnd, L"open", c->log_path, NULL, o.log_dir, SW_SHOWNORMAL); - - if (status > (HINSTANCE) 32) /* Success */ - return; - else - PrintDebug (L"Opening log file using ShellExecute with verb = open failed" - " for config '%ls' (status = %lu)", c->config_name, status); - - _sntprintf_0(filename, _T("%ls \"%ls\""), o.log_viewer, c->log_path); - - /* fill in STARTUPINFO struct */ - GetStartupInfo(&start_info); - start_info.cb = sizeof(start_info); - start_info.dwFlags = 0; - start_info.wShowWindow = SW_SHOWDEFAULT; - start_info.hStdInput = NULL; - start_info.hStdOutput = NULL; - - if (!CreateProcess(NULL, - filename, //commandline - NULL, - NULL, - TRUE, - CREATE_NEW_CONSOLE, - NULL, - o.log_dir, //start-up dir - &start_info, - &proc_info)) + TCHAR filename[2*MAX_PATH]; + + STARTUPINFO start_info; + PROCESS_INFORMATION proc_info; + SECURITY_ATTRIBUTES sa; + SECURITY_DESCRIPTOR sd; + HINSTANCE status; + + CLEAR(start_info); + CLEAR(proc_info); + CLEAR(sa); + CLEAR(sd); + + /* Try first using file association */ + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); /* Safe to init COM multiple times */ + status = ShellExecuteW(o.hWnd, L"open", c->log_path, NULL, o.log_dir, SW_SHOWNORMAL); + + if (status > (HINSTANCE) 32) /* Success */ + { + return; + } + else + { + PrintDebug(L"Opening log file using ShellExecute with verb = open failed" + " for config '%ls' (status = %lu)", c->config_name, status); + } + + _sntprintf_0(filename, _T("%ls \"%ls\""), o.log_viewer, c->log_path); + + /* fill in STARTUPINFO struct */ + GetStartupInfo(&start_info); + start_info.cb = sizeof(start_info); + start_info.dwFlags = 0; + start_info.wShowWindow = SW_SHOWDEFAULT; + start_info.hStdInput = NULL; + start_info.hStdOutput = NULL; + + if (!CreateProcess(NULL, + filename, /*commandline */ + NULL, + NULL, + TRUE, + CREATE_NEW_CONSOLE, + NULL, + o.log_dir, /*start-up dir */ + &start_info, + &proc_info)) { - /* could not start log viewer */ - ShowLocalizedMsg(IDS_ERR_START_LOG_VIEWER, o.log_viewer); + /* could not start log viewer */ + ShowLocalizedMsg(IDS_ERR_START_LOG_VIEWER, o.log_viewer); } - CloseHandle(proc_info.hThread); - CloseHandle(proc_info.hProcess); + CloseHandle(proc_info.hThread); + CloseHandle(proc_info.hProcess); } -void EditConfig(connection_t *c) +void +EditConfig(connection_t *c) { - TCHAR filename[2*MAX_PATH]; - - STARTUPINFO start_info; - PROCESS_INFORMATION proc_info; - SECURITY_ATTRIBUTES sa; - SECURITY_DESCRIPTOR sd; - HINSTANCE status; - - CLEAR (start_info); - CLEAR (proc_info); - CLEAR (sa); - CLEAR (sd); - - /* Try first using file association */ - _sntprintf_0(filename, L"%ls\\%ls", c->config_dir, c->config_file); - - CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); /* Safe to init COM multiple times */ - status = ShellExecuteW (o.hWnd, L"open", filename, NULL, c->config_dir, SW_SHOWNORMAL); - if (status > (HINSTANCE) 32) - return; - else - PrintDebug (L"Opening config file using ShellExecute with verb = open failed" - " for config '%ls' (status = %lu)", c->config_name, status); - - _sntprintf_0(filename, _T("%ls \"%ls\\%ls\""), o.editor, c->config_dir, c->config_file); - - /* fill in STARTUPINFO struct */ - GetStartupInfo(&start_info); - start_info.cb = sizeof(start_info); - start_info.dwFlags = 0; - start_info.wShowWindow = SW_SHOWDEFAULT; - start_info.hStdInput = NULL; - start_info.hStdOutput = NULL; - - if (!CreateProcess(NULL, - filename, //commandline - NULL, - NULL, - TRUE, - CREATE_NEW_CONSOLE, - NULL, - c->config_dir, //start-up dir - &start_info, - &proc_info)) + TCHAR filename[2*MAX_PATH]; + + STARTUPINFO start_info; + PROCESS_INFORMATION proc_info; + SECURITY_ATTRIBUTES sa; + SECURITY_DESCRIPTOR sd; + HINSTANCE status; + + CLEAR(start_info); + CLEAR(proc_info); + CLEAR(sa); + CLEAR(sd); + + /* Try first using file association */ + _sntprintf_0(filename, L"%ls\\%ls", c->config_dir, c->config_file); + + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); /* Safe to init COM multiple times */ + status = ShellExecuteW(o.hWnd, L"open", filename, NULL, c->config_dir, SW_SHOWNORMAL); + if (status > (HINSTANCE) 32) + { + return; + } + else + { + PrintDebug(L"Opening config file using ShellExecute with verb = open failed" + " for config '%ls' (status = %lu)", c->config_name, status); + } + + _sntprintf_0(filename, _T("%ls \"%ls\\%ls\""), o.editor, c->config_dir, c->config_file); + + /* fill in STARTUPINFO struct */ + GetStartupInfo(&start_info); + start_info.cb = sizeof(start_info); + start_info.dwFlags = 0; + start_info.wShowWindow = SW_SHOWDEFAULT; + start_info.hStdInput = NULL; + start_info.hStdOutput = NULL; + + if (!CreateProcess(NULL, + filename, /*commandline */ + NULL, + NULL, + TRUE, + CREATE_NEW_CONSOLE, + NULL, + c->config_dir, /*start-up dir */ + &start_info, + &proc_info)) { - /* could not start editor */ - ShowLocalizedMsg(IDS_ERR_START_CONF_EDITOR, o.editor); + /* could not start editor */ + ShowLocalizedMsg(IDS_ERR_START_CONF_EDITOR, o.editor); } - CloseHandle(proc_info.hThread); - CloseHandle(proc_info.hProcess); + CloseHandle(proc_info.hThread); + CloseHandle(proc_info.hProcess); }