Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FreeRDP/FreeRDP-WebConnect.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md (renamed from README)25
-rwxr-xr-xinstall_prereqs.sh7
-rw-r--r--wsgate/RDP.cpp48
-rw-r--r--wsgate/debian/control2
-rw-r--r--wsgate/debian/docs1
-rw-r--r--wsgate/myrawsocket.cpp27
-rw-r--r--wsgate/nova_token_auth.cpp176
-rw-r--r--wsgate/nova_token_auth.hpp7
-rw-r--r--wsgate/rdpcommon.hpp24
-rw-r--r--wsgate/webroot/index-debug.html2
-rw-r--r--wsgate/wsgate.ini.sample.in3
-rw-r--r--wsgate/wsgateEHS.cpp217
-rw-r--r--wsgate/wsgateEHS.hpp23
13 files changed, 371 insertions, 191 deletions
diff --git a/README b/README.md
index 9fa6e9a..745d01f 100644
--- a/README
+++ b/README.md
@@ -1,7 +1,10 @@
+FreeRDP-WebConnect
+======
FreeRDP-WebConnect will be a gateway for seamless access to your RDP-Sessions
-in any HTML5-compliant browser. In particular it relies on the
-Canvas (http://www.w3.org/TR/2dcontext/) and
-WebSockets (http://www.w3.org/TR/websockets/) feature.
+in any HTML5-compliant browser.
+In particular it relies on the features
+* Canvas (http://www.w3.org/TR/2dcontext/)
+* WebSockets (http://www.w3.org/TR/websockets/)
The server side WebSockets implementation handles current RFC6455
(http://tools.ietf.org/html/rfc6455) only, so browsers that implement
@@ -15,8 +18,18 @@ connect as a client to any RDP session.
Although the project is still in a very early development phase (project was started
on April 3, 2012), it already can display an RDP session right now.
-Added automated build/install script setup-all.sh
-For unattended setup, installing all prereqs and deleting conflicting packages, run the script as root, specifying the following command:
+### Installation ###
+**Automated build/install script**::
+```sh
+setup-all.sh
+```
+**Unattended install script**
+```sh
./setup-all.sh -f -i -d
+```
+* Force to run as root user (-f)
+* Install all dependency packages (-i)
+* Remove conflicting packages (-d)
-For addition details on the setup script and webconnect prereqs consult wsgate/README. \ No newline at end of file
+### More Details ###
+For addition details on the setup script and webconnect prereqs consult [wsgate/README](wsgate/README).
diff --git a/install_prereqs.sh b/install_prereqs.sh
index 05fa03a..e2289be 100755
--- a/install_prereqs.sh
+++ b/install_prereqs.sh
@@ -52,10 +52,9 @@ case $DISTRO in
yum install -y gcc-c++ autoconf automake libtool cmake svn svn2cl \
openssl-devel boost-devel libpng-devel elfutils-devel
;;
- SUSE*)
- echo 'SUSE not yet supported! Please install prereqs by hand:'
- echo 'git, svn-devel, autotools, gcc, g++, boost, openssl-devel and libpng-devel. For tracing to work, libdwarf is also required'
- exit 1
+ *SUSE*)
+ echo 'SUSE detected.Installing required packages...'
+ zypper --non-interactive install gcc-c++ make cmake openssl-devel zlib-devel boost-devel libpng-devel
;;
Red\sHat\sEnterprise\sLinux\sServer*7*|CentOS*7*)
echo 'CentOS detected. Installing required packages...'
diff --git a/wsgate/RDP.cpp b/wsgate/RDP.cpp
index 4f0894a..dae424f 100644
--- a/wsgate/RDP.cpp
+++ b/wsgate/RDP.cpp
@@ -30,9 +30,10 @@
#include "Update.hpp"
#include "Primary.hpp"
#include "Png.hpp"
-#include <cpprest/json.h>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
+#include <boost/property_tree/json_parser.hpp>
+#include <boost/property_tree/ptree.hpp>
#include "myrawsocket.hpp"
#include "base64.hpp"
@@ -624,30 +625,29 @@ namespace wsgate {
const uint32_t *op = reinterpret_cast<const uint32_t *>(data.data());
switch (*op) {
case WSOP_CS_CREDENTIAL_JSON:
- utility::string_t infoJSON;
+ std::stringstream stream;
for (int i = 1; i < data.length() / 4; i++){
- infoJSON += (char)op[i];
+ stream << (char)op[i];
}
try{
- web::json::value jsonValue = web::json::value::parse(infoJSON);
- utility::string_t w_host = jsonValue[utility::conversions::to_string_t("host")].as_string();
- utility::string_t w_pcb = jsonValue[utility::conversions::to_string_t("pcb")].as_string();
- utility::string_t w_user = jsonValue[utility::conversions::to_string_t("user")].as_string();
- utility::string_t w_pass = jsonValue[utility::conversions::to_string_t("pass")].as_string();
- utility::string_t w_dtsize = jsonValue[utility::conversions::to_string_t("dtsize")].as_string();
-
- utility::string_t size(w_dtsize.begin(), w_dtsize.end());
+ boost::property_tree::ptree pt;
+ boost::property_tree::read_json(stream, pt);
+ std::string host = pt.get<std::string>("host");
+ std::string pcb = pt.get<std::string>("pcb");
+ std::string user = pt.get<std::string>("user");
+ std::string pass = pt.get<std::string>("pass");
+ std::string size = pt.get<std::string>("dtsize");
WsRdpParams params;
- params.fntlm = jsonValue[utility::conversions::to_string_t("fntlm")].as_integer();
- params.nomani = jsonValue[utility::conversions::to_string_t("nomani")].as_integer();
- params.nonla = jsonValue[utility::conversions::to_string_t("nonla")].as_integer();
- params.notheme = jsonValue[utility::conversions::to_string_t("notheme")].as_integer();
- params.notls = jsonValue[utility::conversions::to_string_t("notls")].as_integer();
- params.nowallp = jsonValue[utility::conversions::to_string_t("nowallp")].as_integer();
- params.nowdrag = jsonValue[utility::conversions::to_string_t("nowdrag")].as_integer();
- params.perf = jsonValue[utility::conversions::to_string_t("perf")].as_integer();
- params.port = jsonValue[utility::conversions::to_string_t("port")].as_integer();
+ params.fntlm = pt.get<int>("fntlm");
+ params.nomani = pt.get<int>("nomani");
+ params.nonla = pt.get<int>("nonla");
+ params.notheme = pt.get<int>("notheme");
+ params.notls = pt.get<int>("notls");
+ params.nowallp = pt.get<int>("nowallp");
+ params.nowdrag = pt.get<int>("nowdrag");
+ params.perf = pt.get<int>("perf");
+ params.port = pt.get<int>("port");
if (!size.empty()) {
try {
@@ -663,11 +663,7 @@ namespace wsgate {
params.height = 768;
}
}
- this->m_rsh->PrepareRDP(std::string(w_host.begin(), w_host.end()),
- std::string(w_pcb.begin() , w_pcb.end()),
- std::string(w_user.begin(), w_user.end()),
- std::string(w_pass.begin(), w_pass.end()),
- params);
+ this->m_rsh->PrepareRDP(host, pcb, user, pass, params);
}
catch (exception &e){
log::err << "Error starting RDP session:" << e.what() << std::endl;
@@ -1121,7 +1117,7 @@ namespace wsgate {
case STATE_CLOSED:
break;
}
- usleep(100);
+ usleep(1000);
}
log::debug << "RDP client thread terminated" << endl;
if (STATE_CONNECTED == m_State) {
diff --git a/wsgate/debian/control b/wsgate/debian/control
index 644aa6e..137587e 100644
--- a/wsgate/debian/control
+++ b/wsgate/debian/control
@@ -2,7 +2,7 @@ Source: wsgate
Section: net
Priority: extra
Maintainer: Fritz Elfert <wsgate@fritz-elfert.de>
-Build-Depends: debhelper (>= 8.0.0), autotools-dev, g++, libehs-dev, libfreerdp-dev, libssl-dev, libdw-dev, libboost-dev, libboost-regex-dev, libboost-filesystem-dev, libboost-program-options-dev, libboost-system-dev, libpcre3-dev, libpng-dev, libtool, doxygen, graphviz, openjdk-6-jre-headless
+Build-Depends: debhelper (>= 8.0.0), autotools-dev, g++, libehs-dev, libfreerdp-dev, libssl-dev, libdw-dev, libboost-dev, libboost-regex-dev, libboost-filesystem-dev, libboost-program-options-dev, libboost-system-dev, libpcre3-dev, libpng-dev, libtool, doxygen, graphviz, openjdk-6-jre-headless | openjdk-7-jre-headless | openjdk-8-jre-headless
Standards-Version: 3.9.2
Homepage: https://github.com/FreeRDP/FreeRDP-WebConnect
#Vcs-Git: git://git.debian.org/collab-maint/wsgate.git
diff --git a/wsgate/debian/docs b/wsgate/debian/docs
index 538ca5e..841c52d 100644
--- a/wsgate/debian/docs
+++ b/wsgate/debian/docs
@@ -1,3 +1,2 @@
NOTICE
README
-doc/html
diff --git a/wsgate/myrawsocket.cpp b/wsgate/myrawsocket.cpp
index 8405b9f..fc493e6 100644
--- a/wsgate/myrawsocket.cpp
+++ b/wsgate/myrawsocket.cpp
@@ -61,9 +61,32 @@ namespace wsgate{
return true;
}
- void MyRawSocketHandler::PrepareRDP(const std::string host, const std::string pcb, const std::string user, const std::string pass, const WsRdpParams &params){
+ void MyRawSocketHandler::PrepareRDP(const std::string _host, const std::string _pcb, const std::string _user, const std::string _pass, const WsRdpParams &_params){
+ std::string host = _host;
+ std::string pcb = _pcb;
+ std::string user = _user;
+ std::string pass = _pass;
+ WsRdpParams params = _params;
+
string username;
string domain;
+
+ //do needed overrides
+ WsRdpOverrideParams op = this->m_parent->getOverrideParams();
+ if (op.m_bOverrideRdpFntlm) params.fntlm = op.m_RdpOverrideParams.fntlm;
+ if (op.m_bOverrideRdpNomani) params.nomani = op.m_RdpOverrideParams.nomani;
+ if (op.m_bOverrideRdpNonla) params.nonla = op.m_RdpOverrideParams.nonla;
+ if (op.m_bOverrideRdpNotheme) params.notheme = op.m_RdpOverrideParams.notheme;
+ if (op.m_bOverrideRdpNotls) params.notls = op.m_RdpOverrideParams.notls;
+ if (op.m_bOverrideRdpNowallp) params.nowallp = op.m_RdpOverrideParams.nowallp;
+ if (op.m_bOverrideRdpNowdrag) params.nowdrag = op.m_bOverrideRdpNowdrag;
+ if (op.m_bOverrideRdpPerf) params.perf = op.m_RdpOverrideParams.perf;
+ if (op.m_bOverrideRdpPort) params.port = op.m_RdpOverrideParams.port;
+ if (op.m_bOverrideRdpHost) host = op.m_sRdpOverrideHost;
+ if (op.m_bOverrideRdpPass) pass = op.m_sRdpOverridePass;
+ if (op.m_bOverrideRdpPcb) pcb = op.m_sRdpOverridePcb;
+ if (op.m_bOverrideRdpUser) user = op.m_sRdpOverrideUser;
+
SplitUserDomain(user, username, domain);
rdp_ptr r = this->m_cmap[this->conn].get<2>();
@@ -79,7 +102,7 @@ namespace wsgate{
log::debug << "RDP No wallpaper: " << params.nowallp << endl;
log::debug << "RDP No full windowdrag: " << params.nowdrag << endl;
log::debug << "RDP No menu animation: " << params.nomani << endl;
- log::debug << "RDP No theming: " << params.nomani << endl;
+ log::debug << "RDP No theming: " << params.notheme << endl;
log::debug << "RDP Disable TLS: " << params.notls << endl;
log::debug << "RDP Disable NLA: " << params.nonla << endl;
log::debug << "RDP NTLM auth: " << params.fntlm << endl;
diff --git a/wsgate/nova_token_auth.cpp b/wsgate/nova_token_auth.cpp
index 5008e1e..7c5cd06 100644
--- a/wsgate/nova_token_auth.cpp
+++ b/wsgate/nova_token_auth.cpp
@@ -20,6 +20,7 @@
#include <cpprest/json.h>
#include "nova_token_auth.hpp"
+#include <iostream>
using namespace pplx;
using namespace std;
@@ -27,36 +28,44 @@ using namespace web;
using namespace wsgate;
using namespace utility::conversions;
-
class nova_console_token_auth_impl : public nova_console_token_auth
{
private:
- web::json::value execute_request_and_get_json_value(
+ web::http::http_response execute_request_and_get_response(
web::http::client::http_client& client,
web::http::http_request& request);
- web::json::value get_auth_token_data(std::string osAuthUrl,
- std::string osUserName,
- std::string osPassword,
- std::string osTenantName);
+ web::json::value get_json_from_response(web::http::http_response response);
+
+ std::pair<std::string, std::string> get_auth_token_data_v2(std::string osAuthUrl,
+ std::string osUserName,
+ std::string osPassword,
+ std::string osTenantName,
+ std::string osRegion);
+
+ std::pair<std::string, std::string> get_auth_token_data_v3(std::string osAuthUrl,
+ std::string osUserName,
+ std::string osPassword,
+ std::string osTenantName,
+ std::string osRegion);
web::json::value get_console_token_data(std::string authToken,
std::string novaUrl,
std::string consoleToken);
- utility::string_t get_nova_url(web::json::value token_data);
-
public:
virtual nova_console_info get_console_info(std::string osAuthUrl,
std::string osUserName,
std::string osPassword,
std::string osTenantName,
- std::string consoleToken);
+ std::string consoleToken,
+ std::string keystoneVersion,
+ std::string osRegion);
};
-json::value nova_console_token_auth_impl::execute_request_and_get_json_value(
+http::http_response nova_console_token_auth_impl::execute_request_and_get_response(
http::client::http_client& client,
http::http_request& request)
{
@@ -69,15 +78,22 @@ json::value nova_console_token_auth_impl::execute_request_and_get_json_value(
throw http_exception(response.status_code(), to_utf8string(response.reason_phrase()));
}
+ return response;
+}
+
+json::value nova_console_token_auth_impl::get_json_from_response(
+ http::http_response response)
+{
auto json_task = response.extract_json();
json_task.wait();
return json_task.get();
}
-json::value nova_console_token_auth_impl::get_auth_token_data(
+std::pair<std::string, std::string> nova_console_token_auth_impl::get_auth_token_data_v2(
string osAuthUrl, string osUserName,
- string osPassword, string osTenantName)
+ string osPassword, string osTenantName,
+ string osRegion)
{
auto jsonRequestBody = json::value::object();
auto auth = json::value::object();
@@ -94,7 +110,95 @@ json::value nova_console_token_auth_impl::get_auth_token_data(
request.set_body(jsonRequestBody);
http::client::http_client client(to_string_t(osAuthUrl));
- return execute_request_and_get_json_value(client, request);
+ auto response_json = get_json_from_response(execute_request_and_get_response(client, request));
+
+ utility::string_t authToken;
+ utility::string_t novaUrl;
+ //get the authentication token
+ authToken = response_json[U("access")][U("token")][U("id")].as_string();
+
+ //get the nova api endpoint
+ for (auto serviceCatalog : response_json[U("access")][U("serviceCatalog")].as_array())
+ if (serviceCatalog[U("name")].as_string() == U("nova")){
+ if (osRegion.empty()){
+ novaUrl = serviceCatalog[U("endpoints")][0][U("adminURL")].as_string();
+ }
+ else{
+ for (auto endpoint : serviceCatalog[U("endpoints")].as_array()){
+ if (endpoint[U("region")].as_string() == to_string_t(osRegion)){
+ novaUrl = endpoint[U("adminURL")].as_string();
+ }
+ }
+ }
+ }
+
+
+ return std::pair<std::string, std::string>(
+ to_utf8string(authToken),
+ to_utf8string(novaUrl));
+}
+
+std::pair<std::string, std::string> nova_console_token_auth_impl::get_auth_token_data_v3(
+ string osAuthUrl, string osUserName,
+ string osPassword, string osTenantName,
+ string osRegion)
+{
+ auto jsonRequestBody = json::value::object();
+ auto auth = json::value::object();
+ auto identity = json::value::object();
+ auto methods = json::value::array();
+ methods[0] = json::value::string(to_string_t("password"));
+
+ auto password = json::value::object();
+ auto user = json::value::object();
+ user[U("name")] = json::value::string(to_string_t(osUserName));
+ user[U("password")] = json::value::string(to_string_t(osPassword));
+
+ auto domain = json::value::object();
+ domain[U("id")] = json::value::string(to_string_t("default"));
+
+ user[U("domain")] = domain;
+ password[U("user")] = user;
+ identity[U("methods")] = methods;
+ identity[U("password")] = password;
+
+ auto scope = json::value::object();
+ auto project = json::value::object();
+ project[U("name")] = json::value::string(to_string_t(osTenantName));
+ project[U("domain")] = domain;
+ scope[U("project")] = project;
+
+ auth[U("identity")] = identity;
+ auth[U("scope")] = scope;
+ jsonRequestBody[U("auth")] = auth;
+
+ http::http_request request(http::methods::POST);
+ request.set_request_uri(U("auth/tokens"));
+ request.headers().add(http::header_names::accept, U("application/json"));
+ request.headers().set_content_type(U("application/json"));
+ request.set_body(jsonRequestBody);
+
+ http::client::http_client client(to_string_t(osAuthUrl));
+ auto response = execute_request_and_get_response(client, request);
+ auto response_json = get_json_from_response(response);
+
+ utility::string_t authToken;
+ utility::string_t novaUrl;
+ //get the authentication token
+ authToken = response.headers()[U("X-Subject-Token")];
+
+ //get the nova api endpoint
+ for (auto serviceCatalog : response_json[U("token")][U("catalog")].as_array())
+ if (serviceCatalog[U("name")].as_string() == U("nova"))
+ for (auto endpoint : serviceCatalog[U("endpoints")].as_array())
+ if (endpoint[U("interface")].as_string() == U("admin") &&
+ (endpoint[U("region")].as_string() == to_string_t(osRegion) || osRegion.empty())){
+ novaUrl = endpoint[U("url")].as_string();
+ }
+
+ return std::pair<std::string, std::string>(
+ to_utf8string(authToken),
+ to_utf8string(novaUrl));
}
json::value nova_console_token_auth_impl::get_console_token_data(
@@ -111,35 +215,43 @@ json::value nova_console_token_auth_impl::get_console_token_data(
request.headers().add(http::header_names::accept, U("application/json"));
request.headers().set_content_type(U("application/json"));
- return execute_request_and_get_json_value(client, request);
-}
-
-utility::string_t nova_console_token_auth_impl::get_nova_url(web::json::value token_data)
-{
- for (auto serviceCatalog : token_data[U("access")][U("serviceCatalog")].as_array())
- if (serviceCatalog[U("name")].as_string() == U("nova"))
- return serviceCatalog[U("endpoints")][0][U("adminURL")].as_string();
+ return get_json_from_response(execute_request_and_get_response(client, request));
}
nova_console_info nova_console_token_auth_impl::get_console_info(
std::string osAuthUrl, std::string osUserName,
std::string osPassword, std::string osTenantName,
- std::string consoleToken)
+ std::string consoleToken, std::string keystoneVersion,
+ std::string osRegion)
{
- auto token_data = get_auth_token_data(osAuthUrl, osUserName,
- osPassword, osTenantName);
-
- auto novaUrl = get_nova_url(token_data);
+ std::string authToken;
+ std::string novaUrl;
+
+ if (keystoneVersion == KEYSTONE_V2){
+ std::tie(authToken, novaUrl) = get_auth_token_data_v2(osAuthUrl,
+ osUserName,
+ osPassword,
+ osTenantName,
+ osRegion);
+ }
+ else if (keystoneVersion == KEYSTONE_V3){
+ std::tie(authToken, novaUrl) = get_auth_token_data_v3(osAuthUrl,
+ osUserName,
+ osPassword,
+ osTenantName,
+ osRegion);
+ }
+ else{
+ throw std::invalid_argument("Unknown Keystone version");
+ }
- auto authToken = token_data[U("access")][U("token")]
- [U("id")].as_string();
+ nova_console_info info;
- auto consoleTokenData = get_console_token_data(to_utf8string(authToken),
- to_utf8string(novaUrl),
+ auto consoleTokenData = get_console_token_data(
+ authToken,
+ novaUrl,
consoleToken);
- nova_console_info info;
-
info.host = to_utf8string(consoleTokenData[U("console")][U("host")].as_string());
auto portValue = consoleTokenData[U("console")][U("port")];
diff --git a/wsgate/nova_token_auth.hpp b/wsgate/nova_token_auth.hpp
index 45fd9c8..d8f4332 100644
--- a/wsgate/nova_token_auth.hpp
+++ b/wsgate/nova_token_auth.hpp
@@ -21,6 +21,9 @@
#include <exception>
#include <string>
+#define KEYSTONE_V2 "v2.0"
+#define KEYSTONE_V3 "v3"
+
namespace wsgate {
class http_exception: public std::exception {
@@ -66,7 +69,9 @@ namespace wsgate {
std::string osUserName,
std::string osPassword,
std::string osTenantName,
- std::string consoleToken) = 0;
+ std::string consoleToken,
+ std::string keystoneVersion,
+ std::string osRegion) = 0;
};
diff --git a/wsgate/rdpcommon.hpp b/wsgate/rdpcommon.hpp
index e132d58..fd7aea0 100644
--- a/wsgate/rdpcommon.hpp
+++ b/wsgate/rdpcommon.hpp
@@ -109,6 +109,30 @@ namespace wsgate {
} WsRdpParams;
/**
+ * Set of override parameters
+ */
+ typedef struct{
+ bool m_bOverrideRdpHost;
+ bool m_bOverrideRdpPort;
+ bool m_bOverrideRdpUser;
+ bool m_bOverrideRdpPass;
+ bool m_bOverrideRdpPcb;
+ bool m_bOverrideRdpPerf;
+ bool m_bOverrideRdpNowallp;
+ bool m_bOverrideRdpNowdrag;
+ bool m_bOverrideRdpNomani;
+ bool m_bOverrideRdpNotheme;
+ bool m_bOverrideRdpNotls;
+ bool m_bOverrideRdpNonla;
+ bool m_bOverrideRdpFntlm;
+ string m_sRdpOverrideHost;
+ string m_sRdpOverrideUser;
+ string m_sRdpOverridePass;
+ string m_sRdpOverridePcb;
+ WsRdpParams m_RdpOverrideParams;
+ } WsRdpOverrideParams;
+
+ /**
* Our extension of FreeRDP's context
*/
typedef struct {
diff --git a/wsgate/webroot/index-debug.html b/wsgate/webroot/index-debug.html
index f466c36..7cf042c 100644
--- a/wsgate/webroot/index-debug.html
+++ b/wsgate/webroot/index-debug.html
@@ -521,7 +521,7 @@
<div id="rdpdialog" class="dialog">
<h4 title="Main connection settings">General</h4>
<div>
- <form onkeypress="if (event.keyCode == 13) { document.getElementById('rdpconnect').focus();document.getElementById('rdpconnect').click(); return event.preventDevault();}">
+ <form onkeypress="if (event.keyCode == 13) { document.getElementById('rdpconnect').focus();document.getElementById('rdpconnect').click(); return event.preventDefault();}">
<fieldset>
<legend>Session parameters</legend>
<table>
diff --git a/wsgate/wsgate.ini.sample.in b/wsgate/wsgate.ini.sample.in
index 8b9a80f..c4a9c93 100644
--- a/wsgate/wsgate.ini.sample.in
+++ b/wsgate/wsgate.ini.sample.in
@@ -151,9 +151,12 @@ nofullwindowdrag = true
[openstack]
#authurl = http://10.0.0.1:5000/v2.0
+#Specify the version for keystone
+#keystoneversion = v2.0 or v3
#username = admin
#password = secret
#tenantname = admin
+#region = optional region
[hyperv]
diff --git a/wsgate/wsgateEHS.cpp b/wsgate/wsgateEHS.cpp
index f113945..bd75806 100644
--- a/wsgate/wsgateEHS.cpp
+++ b/wsgate/wsgateEHS.cpp
@@ -36,28 +36,25 @@ namespace wsgate{
, m_allowedHosts()
, m_deniedHosts()
, m_bOrderDenyAllow(true)
- , m_bOverrideRdpHost(false)
- , m_bOverrideRdpPort(false)
- , m_bOverrideRdpUser(false)
- , m_bOverrideRdpPass(false)
- , m_bOverrideRdpPerf(false)
- , m_bOverrideRdpNowallp(false)
- , m_bOverrideRdpNowdrag(false)
- , m_bOverrideRdpNomani(false)
- , m_bOverrideRdpNotheme(false)
- , m_bOverrideRdpNotls(false)
- , m_bOverrideRdpNonla(false)
- , m_bOverrideRdpFntlm(false)
- , m_sRdpOverrideHost()
- , m_sRdpOverrideUser()
- , m_sRdpOverridePass()
- , m_RdpOverrideParams()
, m_sConfigFile()
, m_ptIniConfig()
, m_bDaemon(false)
, m_bRedirect(false)
, m_StaticCache()
{
+ overrideParams.m_bOverrideRdpHost = false;
+ overrideParams.m_bOverrideRdpPort = false;
+ overrideParams.m_bOverrideRdpUser = false;
+ overrideParams.m_bOverrideRdpPass = false;
+ overrideParams.m_bOverrideRdpPcb = false;
+ overrideParams.m_bOverrideRdpPerf = false;
+ overrideParams.m_bOverrideRdpNowallp = false;
+ overrideParams.m_bOverrideRdpNowdrag = false;
+ overrideParams.m_bOverrideRdpNomani = false;
+ overrideParams.m_bOverrideRdpNotheme = false;
+ overrideParams.m_bOverrideRdpNotls = false;
+ overrideParams.m_bOverrideRdpNonla = false;
+ overrideParams.m_bOverrideRdpFntlm = false;
}
WsGate::~WsGate()
@@ -93,14 +90,14 @@ namespace wsgate{
void WsGate::CheckForPredefined(string& rdpHost, string& rdpUser, string& rdpPass)
{
- if (m_bOverrideRdpHost)
- rdpHost.assign(m_sRdpOverrideHost);
+ if (this->overrideParams.m_bOverrideRdpHost)
+ rdpHost.assign(this->overrideParams.m_sRdpOverrideHost);
- if (m_bOverrideRdpUser)
- rdpUser.assign(m_sRdpOverrideUser);
+ if (this->overrideParams.m_bOverrideRdpUser)
+ rdpUser.assign(this->overrideParams.m_sRdpOverrideUser);
- if (m_bOverrideRdpPass)
- rdpPass.assign(m_sRdpOverridePass);
+ if (this->overrideParams.m_bOverrideRdpPass)
+ rdpPass.assign(this->overrideParams.m_sRdpOverridePass);
}
bool WsGate::ConnectionIsAllowed(string rdphost)
@@ -290,7 +287,7 @@ namespace wsgate{
nova_console_info info = token_auth->get_console_info(m_sOpenStackAuthUrl, m_sOpenStackUsername,
m_sOpenStackPassword, m_sOpenStackTenantName,
- tokenId);
+ tokenId, m_sOpenStackKeystoneVersion, m_sOpenStackRegion);
log::info << "Host: " << info.host << " Port: " << info.port
<< " Internal access path: " << info.internal_access_path
@@ -317,14 +314,14 @@ namespace wsgate{
rdpport,
1024,
768,
- m_bOverrideRdpPerf ? m_RdpOverrideParams.perf : nFormValue(request, "perf", 0),
- m_bOverrideRdpFntlm ? m_RdpOverrideParams.fntlm : nFormValue(request, "fntlm", 0),
- m_bOverrideRdpNotls ? m_RdpOverrideParams.notls : nFormValue(request, "notls", 0),
- m_bOverrideRdpNonla ? m_RdpOverrideParams.nonla : nFormValue(request, "nonla", 0),
- m_bOverrideRdpNowallp ? m_RdpOverrideParams.nowallp : nFormValue(request, "nowallp", 0),
- m_bOverrideRdpNowdrag ? m_RdpOverrideParams.nowdrag : nFormValue(request, "nowdrag", 0),
- m_bOverrideRdpNomani ? m_RdpOverrideParams.nomani : nFormValue(request, "nomani", 0),
- m_bOverrideRdpNotheme ? m_RdpOverrideParams.notheme : nFormValue(request, "notheme", 0),
+ this->overrideParams.m_bOverrideRdpPerf ? this->overrideParams.m_RdpOverrideParams.perf : nFormValue(request, "perf", 0),
+ this->overrideParams.m_bOverrideRdpFntlm ? this->overrideParams.m_RdpOverrideParams.fntlm : nFormValue(request, "fntlm", 0),
+ this->overrideParams.m_bOverrideRdpNotls ? this->overrideParams.m_RdpOverrideParams.notls : nFormValue(request, "notls", 0),
+ this->overrideParams.m_bOverrideRdpNonla ? this->overrideParams.m_RdpOverrideParams.nonla : nFormValue(request, "nonla", 0),
+ this->overrideParams.m_bOverrideRdpNowallp ? this->overrideParams.m_RdpOverrideParams.nowallp : nFormValue(request, "nowallp", 0),
+ this->overrideParams.m_bOverrideRdpNowdrag ? this->overrideParams.m_RdpOverrideParams.nowdrag : nFormValue(request, "nowdrag", 0),
+ this->overrideParams.m_bOverrideRdpNomani ? this->overrideParams.m_RdpOverrideParams.nomani : nFormValue(request, "nomani", 0),
+ this->overrideParams.m_bOverrideRdpNotheme ? this->overrideParams.m_RdpOverrideParams.notheme : nFormValue(request, "notheme", 0),
};
CheckForPredefined(rdphost, rdpuser, rdppass);
@@ -555,23 +552,23 @@ namespace wsgate{
}
else
{
- tmp.assign(m_bOverrideRdpUser ? "<predefined>" : request->Cookies("lastuser"));
+ tmp.assign(this->overrideParams.m_bOverrideRdpUser ? "<predefined>" : request->Cookies("lastuser"));
replace_all(body, "%COOKIE_LASTUSER%", tmp);
- tmp.assign(m_bOverrideRdpUser ? "disabled=\"disabled\"" : "");
+ tmp.assign(this->overrideParams.m_bOverrideRdpUser ? "disabled=\"disabled\"" : "");
replace_all(body, "%DISABLED_USER%", tmp);
- tmp.assign(m_bOverrideRdpPass ? "SomthingUseless" : base64_decode(request->Cookies("lastpass")));
+ tmp.assign(this->overrideParams.m_bOverrideRdpPass ? "SomthingUseless" : base64_decode(request->Cookies("lastpass")));
replace_all(body, "%COOKIE_LASTPASS%", tmp);
- tmp.assign(m_bOverrideRdpPass ? "disabled=\"disabled\"" : "");
+ tmp.assign(this->overrideParams.m_bOverrideRdpPass ? "disabled=\"disabled\"" : "");
replace_all(body, "%DISABLED_PASS%", tmp);
- tmp.assign(m_bOverrideRdpHost ? "<predefined>" : request->Cookies("lasthost"));
+ tmp.assign(this->overrideParams.m_bOverrideRdpHost ? "<predefined>" : request->Cookies("lasthost"));
replace_all(body, "%COOKIE_LASTHOST%", tmp);
- tmp.assign(m_bOverrideRdpHost ? "disabled=\"disabled\"" : "");
+ tmp.assign(this->overrideParams.m_bOverrideRdpHost ? "disabled=\"disabled\"" : "");
replace_all(body, "%DISABLED_HOST%", tmp);
- tmp.assign(request->Cookies("lastpcb"));
+ tmp.assign(this->overrideParams.m_bOverrideRdpPcb ? "<predefined>" : request->Cookies("lastpcb"));
replace_all(body, "%COOKIE_LASTPCB%", tmp);
- tmp.assign("");
+ tmp.assign(this->overrideParams.m_bOverrideRdpPcb ? "disabled=\"disabled\"" : "");
replace_all(body, "%DISABLED_PCB%", tmp);
}
@@ -579,21 +576,21 @@ namespace wsgate{
replace_all(body, "%VERSION%", tmp);
//The new Port Selector
- if(m_bOverrideRdpPort) {
+ if (this->overrideParams.m_bOverrideRdpPort) {
replace_all(body, "%DISABLED_PORT%", "disabled=\"disabled\"");
} else {
replace_all(body, "%DISABLED_PORT%", "");
}
- tmp.assign(m_bOverrideRdpPort ? boost::lexical_cast<string>(m_RdpOverrideParams.port) : "3389");
+ tmp.assign(this->overrideParams.m_bOverrideRdpPort ? boost::lexical_cast<string>(this->overrideParams.m_RdpOverrideParams.port) : "3389");
replace_all(body, "%DEFAULT_PORT%", tmp);
//The Desktop Resolution
- if (m_bOverrideRdpPerf) {
+ if (this->overrideParams.m_bOverrideRdpPerf) {
replace_all(body, "%DISABLED_PERF%", "disabled=\"disabled\"");
- replace_all(body, "%SELECTED_PERF0%", (0 == m_RdpOverrideParams.perf) ? "selected" : "");
- replace_all(body, "%SELECTED_PERF1%", (1 == m_RdpOverrideParams.perf) ? "selected" : "");
- replace_all(body, "%SELECTED_PERF2%", (2 == m_RdpOverrideParams.perf) ? "selected" : "");
+ replace_all(body, "%SELECTED_PERF0%", (0 == this->overrideParams.m_RdpOverrideParams.perf) ? "selected" : "");
+ replace_all(body, "%SELECTED_PERF1%", (1 == this->overrideParams.m_RdpOverrideParams.perf) ? "selected" : "");
+ replace_all(body, "%SELECTED_PERF2%", (2 == this->overrideParams.m_RdpOverrideParams.perf) ? "selected" : "");
} else {
replace_all(body, "%DISABLED_PERF%", "");
replace_all(body, "%SELECTED_PERF0%", "");
@@ -602,49 +599,49 @@ namespace wsgate{
}
- if (m_bOverrideRdpFntlm) {
+ if (this->overrideParams.m_bOverrideRdpFntlm) {
replace_all(body, "%DISABLED_FNTLM%", "disabled=\"disabled\"");
- replace_all(body, "%SELECTED_FNTLM0%", (0 == m_RdpOverrideParams.fntlm) ? "selected" : "");
- replace_all(body, "%SELECTED_FNTLM1%", (1 == m_RdpOverrideParams.fntlm) ? "selected" : "");
- replace_all(body, "%SELECTED_FNTLM2%", (2 == m_RdpOverrideParams.fntlm) ? "selected" : "");
+ replace_all(body, "%SELECTED_FNTLM0%", (0 == this->overrideParams.m_RdpOverrideParams.fntlm) ? "selected" : "");
+ replace_all(body, "%SELECTED_FNTLM1%", (1 == this->overrideParams.m_RdpOverrideParams.fntlm) ? "selected" : "");
+ replace_all(body, "%SELECTED_FNTLM2%", (2 == this->overrideParams.m_RdpOverrideParams.fntlm) ? "selected" : "");
} else {
replace_all(body, "%DISABLED_FNTLM%", "");
replace_all(body, "%SELECTED_FNTLM0%", "");
replace_all(body, "%SELECTED_FNTLM1%", "");
replace_all(body, "%SELECTED_FNTLM2%", "");
}
- if (m_bOverrideRdpNowallp) {
- tmp.assign("disabled=\"disabled\"").append((m_RdpOverrideParams.nowallp) ? " checked=\"checked\"" : "");
+ if (this->overrideParams.m_bOverrideRdpNowallp) {
+ tmp.assign("disabled=\"disabled\"").append((this->overrideParams.m_RdpOverrideParams.nowallp) ? " checked=\"checked\"" : "");
} else {
tmp.assign("");
}
replace_all(body, "%CHECKED_NOWALLP%", tmp);
- if (m_bOverrideRdpNowdrag) {
- tmp.assign("disabled=\"disabled\"").append((m_RdpOverrideParams.nowdrag) ? " checked=\"checked\"" : "");
+ if (this->overrideParams.m_bOverrideRdpNowdrag) {
+ tmp.assign("disabled=\"disabled\"").append((this->overrideParams.m_RdpOverrideParams.nowdrag) ? " checked=\"checked\"" : "");
} else {
tmp.assign("");
}
replace_all(body, "%CHECKED_NOWDRAG%", tmp);
- if (m_bOverrideRdpNomani) {
- tmp.assign("disabled=\"disabled\"").append((m_RdpOverrideParams.nomani) ? " checked=\"checked\"" : "");
+ if (this->overrideParams.m_bOverrideRdpNomani) {
+ tmp.assign("disabled=\"disabled\"").append((this->overrideParams.m_RdpOverrideParams.nomani) ? " checked=\"checked\"" : "");
} else {
tmp.assign("");
}
replace_all(body, "%CHECKED_NOMANI%", tmp);
- if (m_bOverrideRdpNotheme) {
- tmp.assign("disabled=\"disabled\"").append((m_RdpOverrideParams.notheme) ? " checked=\"checked\"" : "");
+ if (this->overrideParams.m_bOverrideRdpNotheme) {
+ tmp.assign("disabled=\"disabled\"").append((this->overrideParams.m_RdpOverrideParams.notheme) ? " checked=\"checked\"" : "");
} else {
tmp.assign("");
}
replace_all(body, "%CHECKED_NOTHEME%", tmp);
- if (m_bOverrideRdpNotls) {
- tmp.assign("disabled=\"disabled\"").append((m_RdpOverrideParams.notls) ? " checked=\"checked\"" : "");
+ if (this->overrideParams.m_bOverrideRdpNotls) {
+ tmp.assign("disabled=\"disabled\"").append((this->overrideParams.m_RdpOverrideParams.notls) ? " checked=\"checked\"" : "");
} else {
tmp.assign("");
}
replace_all(body, "%CHECKED_NOTLS%", tmp);
- if (m_bOverrideRdpNonla) {
- tmp.assign("disabled=\"disabled\"").append((m_RdpOverrideParams.nonla) ? " checked=\"checked\"" : "");
+ if (this->overrideParams.m_bOverrideRdpNonla) {
+ tmp.assign("disabled=\"disabled\"").append((this->overrideParams.m_RdpOverrideParams.nonla) ? " checked=\"checked\"" : "");
} else {
tmp.assign("");
}
@@ -804,33 +801,41 @@ namespace wsgate{
}
if (pt.get_optional<std::string>("rdpoverride.host")) {
- m_sRdpOverrideHost.assign(pt.get<std::string>("rdpoverride.host"));
- m_bOverrideRdpHost = true;
+ this->overrideParams.m_sRdpOverrideHost.assign(pt.get<std::string>("rdpoverride.host"));
+ this->overrideParams.m_bOverrideRdpHost = true;
} else {
- m_bOverrideRdpHost = false;
+ this->overrideParams.m_bOverrideRdpHost = false;
}
if (pt.get_optional<std::string>("rdpoverride.user")) {
- m_sRdpOverrideUser.assign(pt.get<std::string>("rdpoverride.user"));
- m_bOverrideRdpUser = true;
+ this->overrideParams.m_sRdpOverrideUser.assign(pt.get<std::string>("rdpoverride.user"));
+ this->overrideParams.m_bOverrideRdpUser = true;
} else {
- m_bOverrideRdpUser = false;
+ this->overrideParams.m_bOverrideRdpUser = false;
}
if (pt.get_optional<std::string>("rdpoverride.pass")) {
- m_sRdpOverridePass.assign(pt.get<std::string>("rdpoverride.pass"));
- m_bOverrideRdpPass = true;
+ this->overrideParams.m_sRdpOverridePass.assign(pt.get<std::string>("rdpoverride.pass"));
+ this->overrideParams.m_bOverrideRdpPass = true;
} else {
- m_bOverrideRdpPass = false;
+ this->overrideParams.m_bOverrideRdpPass = false;
+ }
+
+ if (pt.get_optional<std::string>("rdpoverride.pcb")) {
+ this->overrideParams.m_sRdpOverridePcb.assign(pt.get<std::string>("rdpoverride.pcb"));
+ this->overrideParams.m_bOverrideRdpPcb = true;
+ }
+ else {
+ this->overrideParams.m_bOverrideRdpPcb = false;
}
if (pt.get_optional<int>("rdpoverride.port")) {
int n = pt.get<int>("rdpoverride.port");
- if ((0 > n) || (2 < n)) {
+ if ((0 > n) || (65536 < n)) {
throw tracing::invalid_argument("Invalid port value.");
}
- m_RdpOverrideParams.port = n;
- m_bOverrideRdpPort = true;
+ this->overrideParams.m_RdpOverrideParams.port = n;
+ this->overrideParams.m_bOverrideRdpPort = true;
} else {
- m_bOverrideRdpPort = false;
+ this->overrideParams.m_bOverrideRdpPort = false;
}
if (pt.get_optional<int>("rdpoverride.performance")) {
@@ -838,56 +843,56 @@ namespace wsgate{
if ((0 > n) || (2 < n)) {
throw tracing::invalid_argument("Invalid performance value.");
}
- m_RdpOverrideParams.perf = n;
- m_bOverrideRdpPerf = true;
+ this->overrideParams.m_RdpOverrideParams.perf = n;
+ this->overrideParams.m_bOverrideRdpPerf = true;
} else {
- m_bOverrideRdpPerf = false;
+ this->overrideParams.m_bOverrideRdpPerf = false;
}
if (pt.get_optional<int>("rdpoverride.forcentlm")) {
int n = pt.get<int>("rdpoverride.forcentlm");
if ((0 > n) || (2 < n)) {
throw tracing::invalid_argument("Invalid forcentlm value.");
}
- m_RdpOverrideParams.fntlm = n;
- m_bOverrideRdpFntlm = true;
+ this->overrideParams.m_RdpOverrideParams.fntlm = n;
+ this->overrideParams.m_bOverrideRdpFntlm = true;
} else {
- m_bOverrideRdpFntlm = false;
+ this->overrideParams.m_bOverrideRdpFntlm = false;
}
if (pt.get_optional<std::string>("rdpoverride.nowallpaper")) {
- m_RdpOverrideParams.nowallp = str2bint(pt.get<std::string>("rdpoverride.nowallpaper"));
- m_bOverrideRdpNowallp = true;
+ this->overrideParams.m_RdpOverrideParams.nowallp = str2bint(pt.get<std::string>("rdpoverride.nowallpaper"));
+ this->overrideParams.m_bOverrideRdpNowallp = true;
} else {
- m_bOverrideRdpNowallp = false;
+ this->overrideParams.m_bOverrideRdpNowallp = false;
}
if (pt.get_optional<std::string>("rdpoverride.nofullwindowdrag")) {
- m_RdpOverrideParams.nowdrag = str2bint(pt.get<std::string>("rdpoverride.nofullwindowdrag"));
- m_bOverrideRdpNowdrag = true;
+ this->overrideParams.m_RdpOverrideParams.nowdrag = str2bint(pt.get<std::string>("rdpoverride.nofullwindowdrag"));
+ this->overrideParams.m_bOverrideRdpNowdrag = true;
} else {
- m_bOverrideRdpNowdrag = false;
+ this->overrideParams.m_bOverrideRdpNowdrag = false;
}
if (pt.get_optional<std::string>("rdpoverride.nomenuanimation")) {
- m_RdpOverrideParams.nomani = str2bint(pt.get<std::string>("rdpoverride.nomenuanimation"));
- m_bOverrideRdpNomani = true;
+ this->overrideParams.m_RdpOverrideParams.nomani = str2bint(pt.get<std::string>("rdpoverride.nomenuanimation"));
+ this->overrideParams.m_bOverrideRdpNomani = true;
} else {
- m_bOverrideRdpNomani = false;
+ this->overrideParams.m_bOverrideRdpNomani = false;
}
if (pt.get_optional<std::string>("rdpoverride.notheming")) {
- m_RdpOverrideParams.notheme = str2bint(pt.get<std::string>("rdpoverride.notheming"));
- m_bOverrideRdpNotheme = true;
+ this->overrideParams.m_RdpOverrideParams.notheme = str2bint(pt.get<std::string>("rdpoverride.notheming"));
+ this->overrideParams.m_bOverrideRdpNotheme = true;
} else {
- m_bOverrideRdpNotheme = false;
+ this->overrideParams.m_bOverrideRdpNotheme = false;
}
if (pt.get_optional<std::string>("rdpoverride.notls")) {
- m_RdpOverrideParams.notls = str2bint(pt.get<std::string>("rdpoverride.notls"));
- m_bOverrideRdpNotls = true;
+ this->overrideParams.m_RdpOverrideParams.notls = str2bint(pt.get<std::string>("rdpoverride.notls"));
+ this->overrideParams.m_bOverrideRdpNotls = true;
} else {
- m_bOverrideRdpNotls = false;
+ this->overrideParams.m_bOverrideRdpNotls = false;
}
if (pt.get_optional<std::string>("rdpoverride.nonla")) {
- m_RdpOverrideParams.nonla = str2bint(pt.get<std::string>("rdpoverride.nonla"));
- m_bOverrideRdpNonla = true;
+ this->overrideParams.m_RdpOverrideParams.nonla = str2bint(pt.get<std::string>("rdpoverride.nonla"));
+ this->overrideParams.m_bOverrideRdpNonla = true;
} else {
- m_bOverrideRdpNonla = false;
+ this->overrideParams.m_bOverrideRdpNonla = false;
}
if (pt.get_optional<std::string>("global.hostname")) {
m_sHostname.assign(pt.get<std::string>("global.hostname"));
@@ -914,6 +919,18 @@ namespace wsgate{
} else {
m_sOpenStackTenantName.clear();
}
+ if (pt.get_optional<std::string>("openstack.keystoneversion")) {
+ m_sOpenStackKeystoneVersion.assign(pt.get<std::string>("openstack.keystoneversion"));
+ }
+ else {
+ m_sOpenStackKeystoneVersion = KEYSTONE_V2;
+ }
+ if (pt.get_optional<std::string>("openstack.region")) {
+ m_sOpenStackRegion.assign(pt.get<std::string>("openstack.region"));
+ }
+ else {
+ m_sOpenStackRegion.clear();
+ }
if (pt.get_optional<std::string>("hyperv.hostusername")) {
m_sHyperVHostUsername.assign(pt.get<std::string>("hyperv.hostusername"));
} else {
@@ -1071,4 +1088,8 @@ namespace wsgate{
oss << hex << rdp.get();
m_SessionMap.erase(oss.str());
}
+
+ WsRdpOverrideParams WsGate::getOverrideParams(){
+ return this->overrideParams;
+ }
}
diff --git a/wsgate/wsgateEHS.hpp b/wsgate/wsgateEHS.hpp
index 8aca448..27499e5 100644
--- a/wsgate/wsgateEHS.hpp
+++ b/wsgate/wsgateEHS.hpp
@@ -26,8 +26,6 @@
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/property_tree/detail/file_parser_error.hpp>
-#include <cpprest/uri.h>
-#include <cpprest/asyncrt_utils.h>
#include "common.hpp"
#include "btexception.hpp"
@@ -52,7 +50,6 @@ namespace po = boost::program_options;
namespace fs = boost::filesystem;
namespace pt = boost::posix_time;
using boost::filesystem::path;
-using namespace utility::conversions;
namespace wsgate{
// subclass of EHS that defines a custom HTTP response.
@@ -81,6 +78,7 @@ namespace wsgate{
void SetPidFile(const string &name);
void RegisterRdpSession(rdp_ptr rdp);
void UnregisterRdpSession(rdp_ptr rdp);
+ WsRdpOverrideParams getOverrideParams();
private:
typedef enum {
TEXT,
@@ -106,23 +104,8 @@ namespace wsgate{
SessionMap m_SessionMap;
vector<boost::regex> m_allowedHosts;
vector<boost::regex> m_deniedHosts;
+ WsRdpOverrideParams overrideParams;
bool m_bOrderDenyAllow;
- bool m_bOverrideRdpHost;
- bool m_bOverrideRdpPort;
- bool m_bOverrideRdpUser;
- bool m_bOverrideRdpPass;
- bool m_bOverrideRdpPerf;
- bool m_bOverrideRdpNowallp;
- bool m_bOverrideRdpNowdrag;
- bool m_bOverrideRdpNomani;
- bool m_bOverrideRdpNotheme;
- bool m_bOverrideRdpNotls;
- bool m_bOverrideRdpNonla;
- bool m_bOverrideRdpFntlm;
- string m_sRdpOverrideHost;
- string m_sRdpOverrideUser;
- string m_sRdpOverridePass;
- WsRdpParams m_RdpOverrideParams;
string m_sConfigFile;
boost::property_tree::ptree m_ptIniConfig;
bool m_bDaemon;
@@ -132,6 +115,8 @@ namespace wsgate{
string m_sOpenStackUsername;
string m_sOpenStackPassword;
string m_sOpenStackTenantName;
+ string m_sOpenStackKeystoneVersion;
+ string m_sOpenStackRegion;
string m_sHyperVHostUsername;
string m_sHyperVHostPassword;