freerdp: fix sending of TLS alert on NLA failure, add better handling of server-side NLA in shadow server
This commit is contained in:
parent
05d63c6874
commit
1ffbd774e9
@ -110,6 +110,7 @@ struct rdp_shadow_server
|
|||||||
HANDLE thread;
|
HANDLE thread;
|
||||||
HANDLE StopEvent;
|
HANDLE StopEvent;
|
||||||
wArrayList* clients;
|
wArrayList* clients;
|
||||||
|
rdpSettings* settings;
|
||||||
rdpShadowScreen* screen;
|
rdpShadowScreen* screen;
|
||||||
rdpShadowSurface* surface;
|
rdpShadowSurface* surface;
|
||||||
rdpShadowSurface* lobby;
|
rdpShadowSurface* lobby;
|
||||||
|
@ -1044,12 +1044,12 @@ BOOL rdp_server_accept_nego(rdpRdp* rdp, wStream* s)
|
|||||||
{
|
{
|
||||||
if (settings->NlaSecurity && !settings->TlsSecurity)
|
if (settings->NlaSecurity && !settings->TlsSecurity)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "server supports only NLA Security");
|
WLog_WARN(TAG, "server supports only NLA Security");
|
||||||
nego->SelectedProtocol |= HYBRID_REQUIRED_BY_SERVER;
|
nego->SelectedProtocol |= HYBRID_REQUIRED_BY_SERVER;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "server supports only a SSL based Security (TLS or NLA)");
|
WLog_WARN(TAG, "server supports only a SSL based Security (TLS or NLA)");
|
||||||
nego->SelectedProtocol |= SSL_REQUIRED_BY_SERVER;
|
nego->SelectedProtocol |= SSL_REQUIRED_BY_SERVER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -476,6 +476,10 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
client->settings->NlaSecurity = (rdp->nego->SelectedProtocol & PROTOCOL_NLA) ? TRUE : FALSE;
|
||||||
|
client->settings->TlsSecurity = (rdp->nego->SelectedProtocol & PROTOCOL_TLS) ? TRUE : FALSE;
|
||||||
|
client->settings->RdpSecurity = (rdp->nego->SelectedProtocol & PROTOCOL_RDP) ? TRUE : FALSE;
|
||||||
|
|
||||||
if (rdp->nego->SelectedProtocol & PROTOCOL_NLA)
|
if (rdp->nego->SelectedProtocol & PROTOCOL_NLA)
|
||||||
{
|
{
|
||||||
sspi_CopyAuthIdentity(&client->identity, rdp->nego->transport->nla->identity);
|
sspi_CopyAuthIdentity(&client->identity, rdp->nego->transport->nla->identity);
|
||||||
@ -686,6 +690,7 @@ BOOL freerdp_peer_context_new(freerdp_peer* client)
|
|||||||
|
|
||||||
context->peer = client;
|
context->peer = client;
|
||||||
context->ServerMode = TRUE;
|
context->ServerMode = TRUE;
|
||||||
|
context->settings = client->settings;
|
||||||
|
|
||||||
if (!(context->metrics = metrics_new(context)))
|
if (!(context->metrics = metrics_new(context)))
|
||||||
goto fail_metrics;
|
goto fail_metrics;
|
||||||
|
@ -363,6 +363,7 @@ BOOL transport_accept_nla(rdpTransport* transport)
|
|||||||
nla_free(transport->nla);
|
nla_free(transport->nla);
|
||||||
transport->nla = NULL;
|
transport->nla = NULL;
|
||||||
tls_set_alert_code(transport->tls, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DESCRIPTION_ACCESS_DENIED);
|
tls_set_alert_code(transport->tls, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DESCRIPTION_ACCESS_DENIED);
|
||||||
|
tls_send_alert(transport->tls);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1011,10 +1011,10 @@ BOOL tls_send_alert(rdpTls* tls)
|
|||||||
if (tls->ssl->s3->wbuf.left == 0)
|
if (tls->ssl->s3->wbuf.left == 0)
|
||||||
tls->ssl->method->ssl_dispatch_alert(tls->ssl);
|
tls->ssl->method->ssl_dispatch_alert(tls->ssl);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BIO *findBufferedBio(BIO *front)
|
BIO *findBufferedBio(BIO *front)
|
||||||
{
|
{
|
||||||
BIO *ret = front;
|
BIO *ret = front;
|
||||||
@ -1067,7 +1067,6 @@ int tls_set_alert_code(rdpTls* tls, int level, int description)
|
|||||||
{
|
{
|
||||||
tls->alertLevel = level;
|
tls->alertLevel = level;
|
||||||
tls->alertDescription = description;
|
tls->alertDescription = description;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ int main(int argc, char** argv)
|
|||||||
MSG msg;
|
MSG msg;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
DWORD dwExitCode;
|
DWORD dwExitCode;
|
||||||
|
rdpSettings* settings;
|
||||||
rdpShadowServer* server;
|
rdpShadowServer* server;
|
||||||
|
|
||||||
shadow_subsystem_set_entry_builtin(NULL);
|
shadow_subsystem_set_entry_builtin(NULL);
|
||||||
@ -54,6 +55,12 @@ int main(int argc, char** argv)
|
|||||||
goto fail_server_new;
|
goto fail_server_new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
settings = server->settings;
|
||||||
|
|
||||||
|
settings->NlaSecurity = FALSE;
|
||||||
|
settings->TlsSecurity = TRUE;
|
||||||
|
settings->RdpSecurity = TRUE;
|
||||||
|
|
||||||
#ifdef WITH_SHADOW_X11
|
#ifdef WITH_SHADOW_X11
|
||||||
server->authentication = TRUE;
|
server->authentication = TRUE;
|
||||||
#else
|
#else
|
||||||
@ -86,8 +93,7 @@ int main(int argc, char** argv)
|
|||||||
if (!GetExitCodeThread(server->thread, &dwExitCode))
|
if (!GetExitCodeThread(server->thread, &dwExitCode))
|
||||||
status = -1;
|
status = -1;
|
||||||
else
|
else
|
||||||
status = (int)dwExitCode;
|
status = (int) dwExitCode;
|
||||||
|
|
||||||
|
|
||||||
fail_server_start:
|
fail_server_start:
|
||||||
shadow_server_uninit(server);
|
shadow_server_uninit(server);
|
||||||
|
@ -70,10 +70,6 @@ BOOL shadow_client_context_new(freerdp_peer* peer, rdpShadowClient* client)
|
|||||||
|
|
||||||
settings->CompressionLevel = PACKET_COMPR_TYPE_RDP6;
|
settings->CompressionLevel = PACKET_COMPR_TYPE_RDP6;
|
||||||
|
|
||||||
settings->RdpSecurity = TRUE;
|
|
||||||
settings->TlsSecurity = TRUE;
|
|
||||||
settings->NlaSecurity = FALSE;
|
|
||||||
|
|
||||||
if (!(settings->CertificateFile = _strdup(server->CertificateFile)))
|
if (!(settings->CertificateFile = _strdup(server->CertificateFile)))
|
||||||
goto fail_cert_file;
|
goto fail_cert_file;
|
||||||
if (!(settings->PrivateKeyFile = _strdup(server->PrivateKeyFile)))
|
if (!(settings->PrivateKeyFile = _strdup(server->PrivateKeyFile)))
|
||||||
@ -250,17 +246,14 @@ BOOL shadow_client_post_connect(freerdp_peer* peer)
|
|||||||
if (settings->Username && settings->Password)
|
if (settings->Username && settings->Password)
|
||||||
settings->AutoLogonEnabled = TRUE;
|
settings->AutoLogonEnabled = TRUE;
|
||||||
|
|
||||||
if (server->authentication)
|
if (server->authentication && !settings->NlaSecurity)
|
||||||
{
|
{
|
||||||
if (subsystem->Authenticate)
|
if (subsystem->Authenticate)
|
||||||
{
|
{
|
||||||
authStatus = subsystem->Authenticate(subsystem, client,
|
authStatus = subsystem->Authenticate(subsystem, client,
|
||||||
settings->Username, settings->Domain, settings->Password);
|
settings->Username, settings->Domain, settings->Password);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (server->authentication)
|
|
||||||
{
|
|
||||||
if (authStatus < 0)
|
if (authStatus < 0)
|
||||||
{
|
{
|
||||||
WLog_ERR(TAG, "client authentication failure: %d", authStatus);
|
WLog_ERR(TAG, "client authentication failure: %d", authStatus);
|
||||||
@ -385,6 +378,64 @@ BOOL shadow_client_activate(freerdp_peer* peer)
|
|||||||
return shadow_client_refresh_rect(client, 0, NULL);
|
return shadow_client_refresh_rect(client, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL shadow_client_logon(freerdp_peer* peer, SEC_WINNT_AUTH_IDENTITY* identity, BOOL automatic)
|
||||||
|
{
|
||||||
|
char* user = NULL;
|
||||||
|
char* domain = NULL;
|
||||||
|
char* password = NULL;
|
||||||
|
rdpSettings* settings = peer->settings;
|
||||||
|
|
||||||
|
if (identity->Flags & SEC_WINNT_AUTH_IDENTITY_UNICODE)
|
||||||
|
{
|
||||||
|
if (identity->User)
|
||||||
|
ConvertFromUnicode(CP_UTF8, 0, identity->User, identity->UserLength, &user, 0, NULL, NULL);
|
||||||
|
|
||||||
|
if (identity->Domain)
|
||||||
|
ConvertFromUnicode(CP_UTF8, 0, identity->Domain, identity->DomainLength, &domain, 0, NULL, NULL);
|
||||||
|
|
||||||
|
if (identity->Password)
|
||||||
|
ConvertFromUnicode(CP_UTF8, 0, identity->Password, identity->PasswordLength, &user, 0, NULL, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (identity->User)
|
||||||
|
user = _strdup((char*) identity->User);
|
||||||
|
|
||||||
|
if (identity->Domain)
|
||||||
|
domain = _strdup((char*) identity->Domain);
|
||||||
|
|
||||||
|
if (identity->Password)
|
||||||
|
password = _strdup((char*) identity->Password);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user)
|
||||||
|
{
|
||||||
|
free(settings->Username);
|
||||||
|
settings->Username = user;
|
||||||
|
user = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (domain)
|
||||||
|
{
|
||||||
|
free(settings->Domain);
|
||||||
|
settings->Domain = domain;
|
||||||
|
user = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password)
|
||||||
|
{
|
||||||
|
free(settings->Password);
|
||||||
|
settings->Password = password;
|
||||||
|
password = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(user);
|
||||||
|
free(domain);
|
||||||
|
free(password);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL shadow_client_surface_frame_acknowledge(rdpShadowClient* client, UINT32 frameId)
|
BOOL shadow_client_surface_frame_acknowledge(rdpShadowClient* client, UINT32 frameId)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -993,6 +1044,7 @@ void* shadow_client_thread(rdpShadowClient* client)
|
|||||||
peer->Capabilities = shadow_client_capabilities;
|
peer->Capabilities = shadow_client_capabilities;
|
||||||
peer->PostConnect = shadow_client_post_connect;
|
peer->PostConnect = shadow_client_post_connect;
|
||||||
peer->Activate = shadow_client_activate;
|
peer->Activate = shadow_client_activate;
|
||||||
|
peer->Logon = shadow_client_logon;
|
||||||
|
|
||||||
shadow_input_register_callbacks(peer->input);
|
shadow_input_register_callbacks(peer->input);
|
||||||
|
|
||||||
@ -1199,6 +1251,8 @@ BOOL shadow_client_accepted(freerdp_listener* listener, freerdp_peer* peer)
|
|||||||
peer->ContextNew = (psPeerContextNew) shadow_client_context_new;
|
peer->ContextNew = (psPeerContextNew) shadow_client_context_new;
|
||||||
peer->ContextFree = (psPeerContextFree) shadow_client_context_free;
|
peer->ContextFree = (psPeerContextFree) shadow_client_context_free;
|
||||||
|
|
||||||
|
peer->settings = freerdp_settings_clone(server->settings);
|
||||||
|
|
||||||
if (!freerdp_peer_context_new(peer))
|
if (!freerdp_peer_context_new(peer))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -50,6 +50,11 @@ static COMMAND_LINE_ARGUMENT_A shadow_args[] =
|
|||||||
{ "auth", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Clients must authenticate" },
|
{ "auth", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Clients must authenticate" },
|
||||||
{ "may-view", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Clients may view without prompt" },
|
{ "may-view", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Clients may view without prompt" },
|
||||||
{ "may-interact", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Clients may interact without prompt" },
|
{ "may-interact", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Clients may interact without prompt" },
|
||||||
|
{ "sec", COMMAND_LINE_VALUE_REQUIRED, "<rdp|tls|nla|ext>", NULL, NULL, -1, NULL, "force specific protocol security" },
|
||||||
|
{ "sec-rdp", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "rdp protocol security" },
|
||||||
|
{ "sec-tls", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "tls protocol security" },
|
||||||
|
{ "sec-nla", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "nla protocol security" },
|
||||||
|
{ "sec-ext", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "nla extended protocol security" },
|
||||||
{ "version", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_VERSION, NULL, NULL, NULL, -1, NULL, "Print version" },
|
{ "version", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_VERSION, NULL, NULL, NULL, -1, NULL, "Print version" },
|
||||||
{ "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?", "Print help" },
|
{ "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?", "Print help" },
|
||||||
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
|
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
|
||||||
@ -149,6 +154,7 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a
|
|||||||
int status;
|
int status;
|
||||||
DWORD flags;
|
DWORD flags;
|
||||||
COMMAND_LINE_ARGUMENT_A* arg;
|
COMMAND_LINE_ARGUMENT_A* arg;
|
||||||
|
rdpSettings* settings = server->settings;
|
||||||
|
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
return 1;
|
return 1;
|
||||||
@ -253,6 +259,58 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a
|
|||||||
{
|
{
|
||||||
server->authentication = arg->Value ? TRUE : FALSE;
|
server->authentication = arg->Value ? TRUE : FALSE;
|
||||||
}
|
}
|
||||||
|
CommandLineSwitchCase(arg, "sec")
|
||||||
|
{
|
||||||
|
if (strcmp("rdp", arg->Value) == 0) /* Standard RDP */
|
||||||
|
{
|
||||||
|
settings->RdpSecurity = TRUE;
|
||||||
|
settings->TlsSecurity = FALSE;
|
||||||
|
settings->NlaSecurity = FALSE;
|
||||||
|
settings->ExtSecurity = FALSE;
|
||||||
|
settings->UseRdpSecurityLayer = TRUE;
|
||||||
|
}
|
||||||
|
else if (strcmp("tls", arg->Value) == 0) /* TLS */
|
||||||
|
{
|
||||||
|
settings->RdpSecurity = FALSE;
|
||||||
|
settings->TlsSecurity = TRUE;
|
||||||
|
settings->NlaSecurity = FALSE;
|
||||||
|
settings->ExtSecurity = FALSE;
|
||||||
|
}
|
||||||
|
else if (strcmp("nla", arg->Value) == 0) /* NLA */
|
||||||
|
{
|
||||||
|
settings->RdpSecurity = FALSE;
|
||||||
|
settings->TlsSecurity = FALSE;
|
||||||
|
settings->NlaSecurity = TRUE;
|
||||||
|
settings->ExtSecurity = FALSE;
|
||||||
|
}
|
||||||
|
else if (strcmp("ext", arg->Value) == 0) /* NLA Extended */
|
||||||
|
{
|
||||||
|
settings->RdpSecurity = FALSE;
|
||||||
|
settings->TlsSecurity = FALSE;
|
||||||
|
settings->NlaSecurity = FALSE;
|
||||||
|
settings->ExtSecurity = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "unknown protocol security: %s", arg->Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CommandLineSwitchCase(arg, "sec-rdp")
|
||||||
|
{
|
||||||
|
settings->RdpSecurity = arg->Value ? TRUE : FALSE;
|
||||||
|
}
|
||||||
|
CommandLineSwitchCase(arg, "sec-tls")
|
||||||
|
{
|
||||||
|
settings->TlsSecurity = arg->Value ? TRUE : FALSE;
|
||||||
|
}
|
||||||
|
CommandLineSwitchCase(arg, "sec-nla")
|
||||||
|
{
|
||||||
|
settings->NlaSecurity = arg->Value ? TRUE : FALSE;
|
||||||
|
}
|
||||||
|
CommandLineSwitchCase(arg, "sec-ext")
|
||||||
|
{
|
||||||
|
settings->ExtSecurity = arg->Value ? TRUE : FALSE;
|
||||||
|
}
|
||||||
CommandLineSwitchDefault(arg)
|
CommandLineSwitchDefault(arg)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -708,6 +766,11 @@ rdpShadowServer* shadow_server_new()
|
|||||||
|
|
||||||
server->authentication = FALSE;
|
server->authentication = FALSE;
|
||||||
|
|
||||||
|
server->settings = freerdp_settings_new(FREERDP_SETTINGS_SERVER_MODE);
|
||||||
|
|
||||||
|
if (!server)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
return server;
|
return server;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -716,8 +779,17 @@ void shadow_server_free(rdpShadowServer* server)
|
|||||||
if (!server)
|
if (!server)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (server->ipcSocket)
|
||||||
|
{
|
||||||
free(server->ipcSocket);
|
free(server->ipcSocket);
|
||||||
server->ipcSocket = NULL;
|
server->ipcSocket = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server->settings)
|
||||||
|
{
|
||||||
|
freerdp_settings_free(server->settings);
|
||||||
|
server->settings = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
free(server);
|
free(server);
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
#include "../sspi.h"
|
#include "../sspi.h"
|
||||||
#include "../log.h"
|
#include "../log.h"
|
||||||
#define TAG WINPR_TAG("negociate")
|
#define TAG WINPR_TAG("negotiate")
|
||||||
|
|
||||||
extern const SecurityFunctionTableA NTLM_SecurityFunctionTableA;
|
extern const SecurityFunctionTableA NTLM_SecurityFunctionTableA;
|
||||||
extern const SecurityFunctionTableW NTLM_SecurityFunctionTableW;
|
extern const SecurityFunctionTableW NTLM_SecurityFunctionTableW;
|
||||||
|
Loading…
Reference in New Issue
Block a user