mirror of https://github.com/FreeRDP/FreeRDP
Added config dump function, improved resource cleanup
This commit is contained in:
parent
4daa09c3e5
commit
4463e5eda9
|
@ -93,6 +93,13 @@ extern "C"
|
|||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief pf_server_config_dump Dumps a default INI configuration file
|
||||
* @param file The file to write to. Existing files are truncated.
|
||||
* @return TRUE for success, FALSE if the file could not be written.
|
||||
*/
|
||||
FREERDP_API BOOL pf_server_config_dump(const char* file);
|
||||
|
||||
/**
|
||||
* @brief server_config_load_ini Create a proxyConfig from a already loaded
|
||||
* INI file.
|
||||
|
|
|
@ -69,6 +69,16 @@ static void pf_server_register_signal_handlers(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static WINPR_NORETURN(void usage(const char* app))
|
||||
{
|
||||
printf("Usage:\n");
|
||||
printf("%s -h Display this help text.\n", app);
|
||||
printf("%s --help Display this help text.\n", app);
|
||||
printf("%s <config ini file> Start the proxy with <config.ini>\n", app);
|
||||
printf("%s --dump-config <config ini file> Create a template <config.ini>\n", app);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
proxyConfig* config = NULL;
|
||||
|
@ -82,8 +92,27 @@ int main(int argc, char* argv[])
|
|||
WLog_INFO(TAG, "\tGit commit: %s", FREERDP_GIT_REVISION);
|
||||
WLog_DBG(TAG, "\tBuild config: %s", freerdp_get_build_config());
|
||||
|
||||
if (argc >= 2)
|
||||
if (argc < 2)
|
||||
usage(argv[0]);
|
||||
|
||||
{
|
||||
const char* arg = argv[1];
|
||||
|
||||
if (_stricmp(arg, "-h") == 0)
|
||||
usage(argv[0]);
|
||||
else if (_stricmp(arg, "--help") == 0)
|
||||
usage(argv[0]);
|
||||
else if (_stricmp(arg, "--dump-config") == 0)
|
||||
{
|
||||
if (argc <= 2)
|
||||
usage(argv[0]);
|
||||
pf_server_config_dump(argv[2]);
|
||||
status = 0;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
config_path = argv[1];
|
||||
}
|
||||
|
||||
config = pf_server_config_load_file(config_path);
|
||||
if (!config)
|
||||
|
|
|
@ -681,18 +681,19 @@ out:
|
|||
* Connects RDP, loops while running and handles event and dispatch, cleans up
|
||||
* after the connection ends.
|
||||
*/
|
||||
static DWORD WINAPI pf_client_thread_proc(LPVOID arg)
|
||||
static DWORD WINAPI pf_client_thread_proc(pClientContext* pc)
|
||||
{
|
||||
freerdp* instance = (freerdp*)arg;
|
||||
pClientContext* pc;
|
||||
freerdp* instance;
|
||||
proxyData* pdata;
|
||||
DWORD nCount = 0;
|
||||
DWORD status;
|
||||
HANDLE handles[MAXIMUM_WAIT_OBJECTS] = { 0 };
|
||||
|
||||
WINPR_ASSERT(instance);
|
||||
pc = (pClientContext*)instance->context;
|
||||
WINPR_ASSERT(pc);
|
||||
|
||||
instance = pc->context.instance;
|
||||
WINPR_ASSERT(instance);
|
||||
|
||||
pdata = pc->pdata;
|
||||
WINPR_ASSERT(pdata);
|
||||
/*
|
||||
|
@ -904,17 +905,6 @@ static int pf_client_client_stop(rdpContext* context)
|
|||
proxy_data_abort_connect(pdata);
|
||||
freerdp_abort_connect(context->instance);
|
||||
|
||||
if (pdata->client_thread)
|
||||
{
|
||||
/*
|
||||
* Wait for client thread to finish. No need to call CloseHandle() here, as
|
||||
* it is the responsibility of `proxy_data_free`.
|
||||
*/
|
||||
PROXY_LOG_DBG(TAG, pc, "waiting for client thread to finish");
|
||||
WaitForSingleObject(pdata->client_thread, INFINITE);
|
||||
PROXY_LOG_DBG(TAG, pc, "thread finished");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -938,11 +928,12 @@ int RdpClientEntry(RDP_CLIENT_ENTRY_POINTS* pEntryPoints)
|
|||
*/
|
||||
DWORD WINAPI pf_client_start(LPVOID arg)
|
||||
{
|
||||
rdpContext* context = (rdpContext*)arg;
|
||||
DWORD rc = 1;
|
||||
pClientContext* pc = (pClientContext*)arg;
|
||||
|
||||
WINPR_ASSERT(context);
|
||||
if (freerdp_client_start(context) != 0)
|
||||
return 1;
|
||||
|
||||
return pf_client_thread_proc(context->instance);
|
||||
WINPR_ASSERT(pc);
|
||||
if (freerdp_client_start(&pc->context) == 0)
|
||||
rc = pf_client_thread_proc(pc);
|
||||
freerdp_client_stop(&pc->context);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -437,6 +437,116 @@ out:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
BOOL pf_server_config_dump(const char* file)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
wIniFile* ini = IniFile_New();
|
||||
if (!ini)
|
||||
return FALSE;
|
||||
|
||||
/* Proxy server configuration */
|
||||
if (IniFile_SetKeyValueString(ini, "Server", "Host", "0.0.0.0") < 0)
|
||||
goto fail;
|
||||
if (IniFile_SetKeyValueInt(ini, "Server", "Port", 3389) < 0)
|
||||
goto fail;
|
||||
|
||||
/* Target configuration */
|
||||
if (IniFile_SetKeyValueString(ini, "Target", "Host", "somehost.example.com") < 0)
|
||||
goto fail;
|
||||
if (IniFile_SetKeyValueInt(ini, "Target", "Port", 3389) < 0)
|
||||
goto fail;
|
||||
if (IniFile_SetKeyValueString(ini, "Target", "FixedTarget", "true") < 0)
|
||||
goto fail;
|
||||
|
||||
/* Channel configuration */
|
||||
if (IniFile_SetKeyValueString(ini, "Channels", "GFX", "true") < 0)
|
||||
goto fail;
|
||||
if (IniFile_SetKeyValueString(ini, "Channels", "DisplayControl", "true") < 0)
|
||||
goto fail;
|
||||
if (IniFile_SetKeyValueString(ini, "Channels", "Clipboard", "true") < 0)
|
||||
goto fail;
|
||||
if (IniFile_SetKeyValueString(ini, "Channels", "AudioOutput", "true") < 0)
|
||||
goto fail;
|
||||
if (IniFile_SetKeyValueString(ini, "Channels", "RemoteApp", "false") < 0)
|
||||
goto fail;
|
||||
|
||||
if (IniFile_SetKeyValueString(ini, "Channels", "PassthroughIsBlacklist", "true") < 0)
|
||||
goto fail;
|
||||
if (IniFile_SetKeyValueString(ini, "Channels", "Passthrough", "") < 0)
|
||||
goto fail;
|
||||
|
||||
/* Input configuration */
|
||||
if (IniFile_SetKeyValueString(ini, "Input", "Keyboard", "true") < 0)
|
||||
goto fail;
|
||||
if (IniFile_SetKeyValueString(ini, "Input", "Mouse", "true") < 0)
|
||||
goto fail;
|
||||
|
||||
/* Security settings */
|
||||
if (IniFile_SetKeyValueString(ini, "Security", "ServerTlsSecurity", "true") < 0)
|
||||
goto fail;
|
||||
if (IniFile_SetKeyValueString(ini, "Security", "ServerNlaSecurity", "false") < 0)
|
||||
goto fail;
|
||||
if (IniFile_SetKeyValueString(ini, "Security", "ServerRdpSecurity", "true") < 0)
|
||||
goto fail;
|
||||
|
||||
if (IniFile_SetKeyValueString(ini, "Security", "ClientTlsSecurity", "true") < 0)
|
||||
goto fail;
|
||||
if (IniFile_SetKeyValueString(ini, "Security", "ClientNlaSecurity", "true") < 0)
|
||||
goto fail;
|
||||
if (IniFile_SetKeyValueString(ini, "Security", "ClientRdpSecurity", "true") < 0)
|
||||
goto fail;
|
||||
if (IniFile_SetKeyValueString(ini, "Security", "ClientAllowFallbackToTls", "true") < 0)
|
||||
goto fail;
|
||||
|
||||
/* Module configuration */
|
||||
if (IniFile_SetKeyValueString(ini, "Plugins", "Modules", "module1,module2,...") < 0)
|
||||
goto fail;
|
||||
if (IniFile_SetKeyValueString(ini, "Plugins", "Required", "module1,module2,...") < 0)
|
||||
goto fail;
|
||||
|
||||
/* Clipboard configuration */
|
||||
if (IniFile_SetKeyValueString(ini, "Clipboard", "TextOnly", "false") < 0)
|
||||
goto fail;
|
||||
if (IniFile_SetKeyValueInt(ini, "Clipboard", "MaxTextLength", 0) < 0)
|
||||
goto fail;
|
||||
|
||||
/* GFX configuration */
|
||||
if (IniFile_SetKeyValueString(ini, "GFXSettings", "DecodeGFX", "false") < 0)
|
||||
goto fail;
|
||||
|
||||
/* Certificate configuration */
|
||||
if (IniFile_SetKeyValueString(ini, "Certificates", "CertificateFile",
|
||||
"<absolute path to some certificate file> OR") < 0)
|
||||
goto fail;
|
||||
if (IniFile_SetKeyValueString(ini, "Certificates", "CertificateContent",
|
||||
"<Contents of some certificate file in PEM format>") < 0)
|
||||
goto fail;
|
||||
|
||||
if (IniFile_SetKeyValueString(ini, "Certificates", "PrivateKeyFile",
|
||||
"<absolute path to some private key file> OR") < 0)
|
||||
goto fail;
|
||||
if (IniFile_SetKeyValueString(ini, "Certificates", "PrivateKeyContent",
|
||||
"<Contents of some private key file in PEM format>") < 0)
|
||||
goto fail;
|
||||
|
||||
if (IniFile_SetKeyValueString(ini, "Certificates", "RdpKeyFile",
|
||||
"<absolute path to some private key file> OR") < 0)
|
||||
goto fail;
|
||||
if (IniFile_SetKeyValueString(ini, "Certificates", "RdpKeyContent",
|
||||
"<Contents of some private key file in PEM format>") < 0)
|
||||
goto fail;
|
||||
|
||||
/* store configuration */
|
||||
if (IniFile_WriteFile(ini, file) < 0)
|
||||
goto fail;
|
||||
|
||||
rc = TRUE;
|
||||
|
||||
fail:
|
||||
IniFile_Free(ini);
|
||||
return rc;
|
||||
}
|
||||
|
||||
proxyConfig* pf_server_config_load_buffer(const char* buffer)
|
||||
{
|
||||
proxyConfig* config = NULL;
|
||||
|
|
|
@ -259,6 +259,9 @@ void proxy_data_free(proxyData* pdata)
|
|||
if (pdata->modules_info)
|
||||
HashTable_Free(pdata->modules_info);
|
||||
|
||||
if (pdata->pc)
|
||||
freerdp_client_context_free(&pdata->pc->context);
|
||||
|
||||
free(pdata);
|
||||
}
|
||||
|
||||
|
|
|
@ -127,10 +127,13 @@ static BOOL pf_server_get_target_info(rdpContext* context, rdpSettings* settings
|
|||
case PROXY_FETCH_TARGET_METHOD_CONFIG:
|
||||
{
|
||||
WINPR_ASSERT(config);
|
||||
settings->ServerPort = config->TargetPort > 0 ? 3389 : settings->ServerPort;
|
||||
settings->ServerHostname = _strdup(config->TargetHost);
|
||||
|
||||
if (!settings->ServerHostname)
|
||||
if (config->TargetPort > 0)
|
||||
freerdp_settings_set_uint32(settings, FreeRDP_ServerPort, config->TargetPort);
|
||||
else
|
||||
freerdp_settings_set_uint32(settings, FreeRDP_ServerPort, 3389);
|
||||
|
||||
if (!freerdp_settings_set_string(settings, FreeRDP_ServerHostname, config->TargetHost))
|
||||
{
|
||||
PROXY_LOG_ERR(TAG, ps, "strdup failed!");
|
||||
return FALSE;
|
||||
|
@ -558,16 +561,26 @@ fail:
|
|||
PROXY_LOG_INFO(TAG, ps, "starting shutdown of connection");
|
||||
PROXY_LOG_INFO(TAG, ps, "stopping proxy's client");
|
||||
|
||||
pc = (rdpContext*)pdata->pc;
|
||||
freerdp_client_stop(pc);
|
||||
if (pdata->client_thread)
|
||||
{
|
||||
if (pdata->pc)
|
||||
freerdp_abort_connect(pdata->pc->context.instance);
|
||||
/*
|
||||
* Wait for client thread to finish. No need to call CloseHandle() here, as
|
||||
* it is the responsibility of `proxy_data_free`.
|
||||
*/
|
||||
PROXY_LOG_DBG(TAG, pdata->pc, "waiting for client thread to finish");
|
||||
WaitForSingleObject(pdata->client_thread, INFINITE);
|
||||
PROXY_LOG_DBG(TAG, pdata->pc, "thread finished");
|
||||
}
|
||||
|
||||
pf_modules_run_hook(pdata->module, HOOK_TYPE_SERVER_SESSION_END, pdata, client);
|
||||
|
||||
PROXY_LOG_INFO(TAG, ps, "freeing server's channels");
|
||||
pf_server_channels_free(ps, client);
|
||||
PROXY_LOG_INFO(TAG, ps, "freeing proxy data");
|
||||
ArrayList_Remove(server->clients, pdata);
|
||||
proxy_data_free(pdata);
|
||||
freerdp_client_context_free(pc);
|
||||
|
||||
WINPR_ASSERT(client->Close);
|
||||
client->Close(client);
|
||||
|
|
Loading…
Reference in New Issue