mirror of https://github.com/OpenVPN/openvpn-gui
Reformat source code with uncrustify
Closes: #445 Signed-off-by: Frank Lichtenheld <frank@lichtenheld.com>pull/643/head
parent
f2aad3a879
commit
2cb3c6e417
82
access.c
82
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;
|
||||
}
|
||||
|
||||
|
|
2
access.h
2
access.h
|
@ -24,6 +24,6 @@
|
|||
|
||||
#include "options.h"
|
||||
|
||||
BOOL AuthorizeConfig (const connection_t *c);
|
||||
BOOL AuthorizeConfig(const connection_t *c);
|
||||
|
||||
#endif
|
||||
|
|
399
as.c
399
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, "<Message>CRV1:");
|
||||
char* msg_end = strstr(buf, "</Message>");
|
||||
if ((status_code == 401) && msg_begin && msg_end) {
|
||||
char *msg_begin = strstr(buf, "<Message>CRV1:");
|
||||
char *msg_end = strstr(buf, "</Message>");
|
||||
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:
|
||||
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), 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);
|
||||
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);
|
||||
}
|
||||
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;
|
||||
|
||||
case IDCANCEL:
|
||||
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 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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
513
chartable.h
513
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
|
||||
};
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
185
echo.c
185
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;
|
||||
|
|
2
echo.h
2
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 */
|
||||
|
|
26
env_set.c
26
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 */
|
||||
|
|
|
@ -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
|
||||
|
|
337
localization.c
337
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) {
|
||||
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 );
|
||||
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));
|
||||
/* 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);
|
||||
/* 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 (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);
|
||||
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);
|
||||
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;
|
||||
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_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));
|
||||
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);
|
||||
if (langId != 0)
|
||||
{
|
||||
SetGUILanguage(langId);
|
||||
}
|
||||
|
||||
SetLaunchOnStartup(Button_GetCheck(GetDlgItem(hwndDlg, ID_CHK_STARTUP)) == BST_CHECKED);
|
||||
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);
|
||||
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();
|
||||
SaveRegistryKeys();
|
||||
|
||||
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
|
|
@ -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 */
|
||||
|
|
45
main.h
45
main.h
|
@ -28,16 +28,16 @@
|
|||
#include <tchar.h>
|
||||
|
||||
/* 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 */
|
||||
|
|
445
manage.c
445
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));
|
||||
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, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
case FD_READ:
|
||||
if (ioctlsocket(c->manage.sk, FIONREAD, &data_size) != 0
|
||||
|| data_size == 0)
|
||||
{
|
||||
pos = memchr(line, ':', line_size);
|
||||
passwd_request = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
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)
|
||||
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[log_])
|
||||
rtmsg_handler[log_](c, pos + 4);
|
||||
pos = memchr(line, ':', line_size);
|
||||
passwd_request = true;
|
||||
}
|
||||
else if (strncmp(pos, "STATE:", 6) == 0)
|
||||
else
|
||||
{
|
||||
if (rtmsg_handler[state_])
|
||||
rtmsg_handler[state_](c, pos + 6);
|
||||
pos = memchr(line, '\n', line_size);
|
||||
}
|
||||
else if (strncmp(pos, "HOLD:", 5) == 0)
|
||||
|
||||
if (pos == NULL)
|
||||
{
|
||||
if (rtmsg_handler[hold_])
|
||||
rtmsg_handler[hold_](c, pos + 5);
|
||||
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, "PASSWORD:", 9) == 0)
|
||||
|
||||
offset += (pos - line) + 1;
|
||||
|
||||
/* Reply to a management password request */
|
||||
if (*c->manage.password && passwd_request)
|
||||
{
|
||||
if (rtmsg_handler[password_])
|
||||
rtmsg_handler[password_](c, pos + 9);
|
||||
ManagementCommand(c, c->manage.password, NULL, regular);
|
||||
SecureZeroMemory(c->manage.password, sizeof(c->manage.password));
|
||||
|
||||
continue;
|
||||
}
|
||||
else if (strncmp(pos, "PROXY:", 6) == 0)
|
||||
|
||||
if (!*c->manage.password && passwd_request)
|
||||
{
|
||||
if (rtmsg_handler[proxy_])
|
||||
rtmsg_handler[proxy_](c, pos + 6);
|
||||
/* 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, "INFO:", 5) == 0)
|
||||
|
||||
/* Handle regular management interface output */
|
||||
line[pos - line - 1] = '\0';
|
||||
if (line[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);
|
||||
/* 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, "NEED-OK:", 8) == 0)
|
||||
else if (c->manage.cmd_queue)
|
||||
{
|
||||
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.
|
||||
*/
|
||||
/* 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)
|
||||
free(data);
|
||||
break;
|
||||
|
||||
case FD_WRITE:
|
||||
SendCommand(c);
|
||||
break;
|
||||
|
||||
case FD_CLOSE:
|
||||
CloseManagement(c);
|
||||
if (rtmsg_handler[stop_])
|
||||
{
|
||||
/* 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);
|
||||
}
|
||||
rtmsg_handler[stop_](c, "");
|
||||
}
|
||||
}
|
||||
free(data);
|
||||
break;
|
||||
|
||||
case FD_WRITE:
|
||||
SendCommand(c);
|
||||
break;
|
||||
|
||||
case FD_CLOSE:
|
||||
CloseManagement (c);
|
||||
if (rtmsg_handler[stop_])
|
||||
rtmsg_handler[stop_](c, "");
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -450,7 +506,8 @@ CloseManagement(connection_t *c)
|
|||
c->manage.sk = INVALID_SOCKET;
|
||||
c->manage.connected = 0;
|
||||
while (UnqueueCommand(c))
|
||||
;
|
||||
{
|
||||
}
|
||||
WSACleanup();
|
||||
}
|
||||
}
|
||||
|
|
5
manage.h
5
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 */
|
||||
|
|
159
misc.c
159
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:
|
||||
|
|
35
misc.h
35
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 */
|
||||
|
|
|
@ -409,4 +409,4 @@
|
|||
/* Timer IDs */
|
||||
#define IDT_STOP_TIMER 2500 /* Timer used to trigger force termination */
|
||||
|
||||
#endif
|
||||
#endif /* ifndef OPENVPN_GUI_RES_H */
|
||||
|
|
50
openvpn.h
50
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 */
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -25,7 +25,9 @@
|
|||
#include "main.h"
|
||||
|
||||
void BuildFileList(void);
|
||||
|
||||
bool ConfigFileOptionExist(int, const char *);
|
||||
|
||||
void FreeConfigList(options_t *o);
|
||||
|
||||
#endif
|
||||
|
|
401
options.c
401
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));
|
||||
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);
|
||||
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) {
|
||||
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);
|
||||
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);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
WCHAR path[MAX_PATH];
|
||||
|
||||
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 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;
|
||||
|
||||
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 */
|
||||
|
|
17
options.h
17
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 */
|
||||
|
|
4
pkcs11.c
4
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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
98
plap/stub.c
98
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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
272
proxy.c
272
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));
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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_MSIE:
|
||||
if (HIWORD(wParam) == BN_CLICKED)
|
||||
case WM_NOTIFY:
|
||||
psn = (LPPSHNOTIFY) lParam;
|
||||
if (psn->hdr.code == (UINT) PSN_KILLACTIVE)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
return TRUE;
|
||||
}
|
||||
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 WM_NOTIFY:
|
||||
psn = (LPPSHNOTIFY) lParam;
|
||||
if (psn->hdr.code == (UINT) PSN_KILLACTIVE)
|
||||
{
|
||||
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (CheckProxySettings(hwndDlg) ? FALSE : TRUE));
|
||||
case WM_CLOSE:
|
||||
EndDialog(hwndDlg, LOWORD(wParam));
|
||||
return TRUE;
|
||||
}
|
||||
else if (psn->hdr.code == (UINT) PSN_APPLY)
|
||||
{
|
||||
SaveProxySettings(hwndDlg);
|
||||
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
|
||||
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)
|
||||
{
|
||||
int len = Edit_GetTextLength((HWND) lParam);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDOK), (len ? TRUE : FALSE));
|
||||
ForceForegroundWindow(hwndDlg);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetForegroundWindow(hwndDlg);
|
||||
}
|
||||
break;
|
||||
|
||||
case IDOK:
|
||||
c = (connection_t *) GetProp(hwndDlg, cfgProp);
|
||||
proxy_type = (c->proxy_type == http ? "HTTP" : "SOCKS");
|
||||
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;
|
||||
|
||||
snprintf(fmt, sizeof(fmt), "username \"%s Proxy\" \"%%s\"", proxy_type);
|
||||
ManagementCommandFromInput(c, fmt, hwndDlg, ID_EDT_PROXY_USER);
|
||||
case IDOK:
|
||||
c = (connection_t *) GetProp(hwndDlg, cfgProp);
|
||||
proxy_type = (c->proxy_type == http ? "HTTP" : "SOCKS");
|
||||
|
||||
snprintf(fmt, sizeof(fmt), "password \"%s Proxy\" \"%%s\"", proxy_type);
|
||||
ManagementCommandFromInput(c, fmt, hwndDlg, ID_EDT_PROXY_PASS);
|
||||
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"";
|
||||
|
|
4
proxy.h
4
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
|
||||
|
|
393
registry.c
393
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");
|
||||
}
|
||||
|
||||
/* 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)
|
||||
if (!GetWindowsDirectory(windows_dir, _countof(windows_dir)))
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
/* 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("\\"));
|
||||
|
||||
/* 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);
|
||||
/* can't get windows dir */
|
||||
ShowLocalizedMsg(IDS_ERR_GET_WINDOWS_DIR);
|
||||
/* Use a default value */
|
||||
_sntprintf_0(windows_dir, L"C:\\Windows");
|
||||
}
|
||||
|
||||
if (!regkey || !GetRegistryValue(regkey, _T("autostart_config_dir"), o.config_auto_dir, _countof(o.config_auto_dir)))
|
||||
/* 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)
|
||||
{
|
||||
/* use default = openvpnpath\config-auto */
|
||||
_sntprintf_0(o.config_auto_dir, L"%lsconfig-auto", o.install_path);
|
||||
/* 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)
|
||||
{
|
||||
/* 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 (!regkey || !GetRegistryValue(regkey, _T("log_dir"), o.global_log_dir, _countof(o.global_log_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\log */
|
||||
_sntprintf_0(o.global_log_dir, L"%lslog", o.install_path);
|
||||
/* use default = openvpnpath\config */
|
||||
_sntprintf_0(o.global_config_dir, _T("%lsconfig"), 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("autostart_config_dir"), o.config_auto_dir, _countof(o.config_auto_dir)))
|
||||
{
|
||||
_tcsncpy(o.ovpn_admin_group, OVPN_ADMIN_GROUP, _countof(o.ovpn_admin_group)-1);
|
||||
/* use default = openvpnpath\config-auto */
|
||||
_sntprintf_0(o.config_auto_dir, L"%lsconfig-auto", o.install_path);
|
||||
}
|
||||
|
||||
if (!regkey || !GetRegistryValue(regkey, _T("exe_path"), o.exe_path, _countof(o.exe_path)))
|
||||
if (!regkey || !GetRegistryValue(regkey, _T("log_dir"), o.global_log_dir, _countof(o.global_log_dir)))
|
||||
{
|
||||
_sntprintf_0(o.exe_path, _T("%lsbin\\openvpn.exe"), o.install_path);
|
||||
/* use default = openvpnpath\log */
|
||||
_sntprintf_0(o.global_log_dir, L"%lslog", o.install_path);
|
||||
}
|
||||
|
||||
if (!regkey || !GetRegistryValue(regkey, _T("priority"), o.priority_string, _countof(o.priority_string)))
|
||||
if (!regkey || !GetRegistryValue(regkey, _T("ovpn_admin_group"), o.ovpn_admin_group, _countof(o.ovpn_admin_group)))
|
||||
{
|
||||
_tcsncpy(o.priority_string, _T("NORMAL_PRIORITY_CLASS"), _countof(o.priority_string)-1);
|
||||
_tcsncpy(o.ovpn_admin_group, OVPN_ADMIN_GROUP, _countof(o.ovpn_admin_group)-1);
|
||||
}
|
||||
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 || !GetRegistryValue(regkey, _T("exe_path"), o.exe_path, _countof(o.exe_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)))
|
||||
{
|
||||
_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))
|
||||
{
|
||||
o.disable_save_passwords = 0;
|
||||
}
|
||||
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);
|
||||
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_READ, ®key_nilings);
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
ShowLocalizedMsg (IDS_ERR_CREATE_REG_HKCU_KEY, GUI_REGKEY_HKCU);
|
||||
RegCloseKey (regkey_nilings);
|
||||
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);
|
||||
if (status != ERROR_SUCCESS)
|
||||
{
|
||||
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);
|
||||
|
||||
|
|
12
registry.h
12
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 */
|
||||
|
|
40
save_pass.c
40
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;
|
||||
}
|
||||
|
|
10
save_pass.h
10
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 */
|
||||
|
|
26
scripts.c
26
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);
|
||||
|
|
|
@ -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
|
||||
|
|
64
service.c
64
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);
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
*/
|
||||
|
||||
VOID CheckServiceStatus();
|
||||
|
||||
BOOL CheckIServiceStatus(BOOL warn);
|
||||
|
||||
/* Attempt to start OpenVPN Automatc Service */
|
||||
void StartAutomaticService(void);
|
||||
|
|
147
tray.c
147
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));
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
12
tray.h
12
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 */
|
||||
|
|
188
viewlog.c
188
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];
|
||||
TCHAR filename[2*MAX_PATH];
|
||||
|
||||
STARTUPINFO start_info;
|
||||
PROCESS_INFORMATION proc_info;
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
SECURITY_DESCRIPTOR sd;
|
||||
HINSTANCE status;
|
||||
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);
|
||||
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);
|
||||
/* 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))
|
||||
if (status > (HINSTANCE) 32) /* Success */
|
||||
{
|
||||
/* could not start log viewer */
|
||||
ShowLocalizedMsg(IDS_ERR_START_LOG_VIEWER, o.log_viewer);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintDebug(L"Opening log file using ShellExecute with verb = open failed"
|
||||
" for config '%ls' (status = %lu)", c->config_name, status);
|
||||
}
|
||||
|
||||
CloseHandle(proc_info.hThread);
|
||||
CloseHandle(proc_info.hProcess);
|
||||
_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);
|
||||
}
|
||||
|
||||
CloseHandle(proc_info.hThread);
|
||||
CloseHandle(proc_info.hProcess);
|
||||
}
|
||||
|
||||
|
||||
void EditConfig(connection_t *c)
|
||||
void
|
||||
EditConfig(connection_t *c)
|
||||
{
|
||||
TCHAR filename[2*MAX_PATH];
|
||||
TCHAR filename[2*MAX_PATH];
|
||||
|
||||
STARTUPINFO start_info;
|
||||
PROCESS_INFORMATION proc_info;
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
SECURITY_DESCRIPTOR sd;
|
||||
HINSTANCE status;
|
||||
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);
|
||||
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);
|
||||
/* 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))
|
||||
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)
|
||||
{
|
||||
/* could not start editor */
|
||||
ShowLocalizedMsg(IDS_ERR_START_CONF_EDITOR, o.editor);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
PrintDebug(L"Opening config file using ShellExecute with verb = open failed"
|
||||
" for config '%ls' (status = %lu)", c->config_name, status);
|
||||
}
|
||||
|
||||
CloseHandle(proc_info.hThread);
|
||||
CloseHandle(proc_info.hProcess);
|
||||
_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);
|
||||
}
|
||||
|
||||
CloseHandle(proc_info.hThread);
|
||||
CloseHandle(proc_info.hProcess);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue