Parse the config file for management i/f params

- Parse the management interface address and password
  from the config file
- Hide the status Window by default for persistent
  connections --- their startup is automated and may
  distract the user otherwise. The user can use the
  menu to review status when required.
- Seed srand() using threadId instead of time. Although we
  use rand() only for cosmetics, the latter is almost
  never unique among threads when multiple connections can
  get started in a succession with this patch set.

Signed-off-by: Selva Nair <selva.nair@gmail.com>
pull/519/head
Selva Nair 2022-07-05 01:48:49 -04:00
parent fc05de0c7b
commit 147bc1a106
3 changed files with 101 additions and 14 deletions

88
misc.c
View File

@ -30,6 +30,8 @@
#include <stdlib.h>
#include <malloc.h>
#include <shellapi.h>
#include <ws2tcpip.h>
#include <shlwapi.h>
#include "localization.h"
#include "options.h"
@ -40,6 +42,7 @@
#include "openvpn_config.h"
#include "openvpn-gui-res.h"
#include "tray.h"
#include "config_parser.h"
/*
* Helper function to do base64 conversion through CryptoAPI
@ -824,3 +827,88 @@ out:
WSACleanup();
return ret;
}
/* Parse the management address and password
* from a config file. Results are returned
* in c->manage.skaddr and c->magage.password.
* Returns false on parse error, or if address
* not found. Password not found is not an error.
*/
BOOL
ParseManagementAddress(connection_t *c)
{
BOOL ret = true;
wchar_t *pw_file = NULL;
wchar_t *workdir = c->config_dir;
wchar_t config_path[MAX_PATH];
wchar_t pw_path[MAX_PATH] = L"";
_sntprintf_0(config_path, L"%ls\\%ls", c->config_dir, c->config_file);
config_entry_t *head = config_parse(config_path);
config_entry_t *l = head;
if (!head)
{
return false;
}
SOCKADDR_IN *addr = &c->manage.skaddr;
addr->sin_port = 0;
while (l)
{
if (l->ntokens >= 3 && !wcscmp(l->tokens[0], L"management"))
{
/* we require the address to be a numerical ipv4 address -- e.g., 127.0.0.1*/
if (InetPtonW(AF_INET, l->tokens[1], &addr->sin_addr) != 1)
{
config_list_free(head);
return false;
}
addr->sin_port = htons(_wtoi(l->tokens[2]));
pw_file = l->tokens[3]; /* may be null */
}
else if (l->ntokens >= 2 && !wcscmp(l->tokens[0], L"cd"))
{
workdir = l->tokens[1];
}
l = l->next;
}
ret = (addr->sin_port != 0);
if (ret && pw_file)
{
if (PathIsRelativeW(pw_file))
{
_sntprintf_0(pw_path, L"%ls\\%ls", workdir, pw_file);
}
else
{
wcsncpy_s(pw_path, MAX_PATH, pw_file, _TRUNCATE);
}
FILE *fp = _wfopen(pw_path, L"r");
if (!fp
|| !fgets(c->manage.password, sizeof(c->manage.password), fp))
{
/* This may be normal as not all users may be given access to this secret */
ret = false;
}
StrTrimA(c->manage.password, "\n\r");
if (fp)
{
fclose(fp);
}
}
config_list_free(head);
PrintDebug(L"ParseManagementAddress: host = %hs port = %d passwd_file = %s",
inet_ntoa(addr->sin_addr), ntohs(addr->sin_port), pw_path);
return ret;
}

11
misc.h
View File

@ -98,4 +98,15 @@ char *escape_string(const char *str);
*/
BOOL find_free_tcp_port(SOCKADDR_IN *addr);
/**
* Parse the config file of a connection profile for
* Managegment address and password.
* @param c : Pointer to connection profile
* On return c->manage.skaddr and c->manage.password
* are populated.
* @returns true on success false on error.
* Password not specified in the config file is not an error.
*/
BOOL ParseManagementAddress(connection_t *c);
#endif

View File

@ -1778,18 +1778,6 @@ OnNeedStr (connection_t *c, UNUSED char *msg)
WriteStatusLog (c, L"GUI> ", L"Error: Received NEED-STR message -- not implemented", false);
}
/* Parse the management port and password of a
* a running daemon -- useful when the daemon is externally
* started (persistent) and we need to use the cached
* management interface address parameters to connect to it.
*/
static BOOL
ParseManagementAddress(connection_t *c)
{
/* Not implemented */
return false;
}
/* Stop the connection -- this sets the daemon to exit if
* started by us, else instructs the daemon to disconnect and
* and wait.
@ -2076,7 +2064,7 @@ ThreadOpenVPNStatus(void *p)
HANDLE wait_event;
CLEAR (msg);
srand(time(NULL));
srand(c->threadId);
/* Cut of extention from config filename. */
_tcsncpy(conn_name, c->config_file, _countof(conn_name));
@ -2118,7 +2106,7 @@ ThreadOpenVPNStatus(void *p)
wait_event = c->hProcess;
}
if (o.silent_connection == 0)
if (o.silent_connection == 0 && (c->flags & FLAG_DAEMON_PERSISTENT) == 0)
ShowWindow(c->hwndStatus, SW_SHOW);
/* Load echo msg histroy from registry */