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 StopEvent;
|
||||
wArrayList* clients;
|
||||
rdpSettings* settings;
|
||||
rdpShadowScreen* screen;
|
||||
rdpShadowSurface* surface;
|
||||
rdpShadowSurface* lobby;
|
||||
|
@ -1044,12 +1044,12 @@ BOOL rdp_server_accept_nego(rdpRdp* rdp, wStream* s)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -476,6 +476,10 @@ static int peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
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)
|
||||
{
|
||||
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->ServerMode = TRUE;
|
||||
context->settings = client->settings;
|
||||
|
||||
if (!(context->metrics = metrics_new(context)))
|
||||
goto fail_metrics;
|
||||
|
@ -363,6 +363,7 @@ BOOL transport_accept_nla(rdpTransport* transport)
|
||||
nla_free(transport->nla);
|
||||
transport->nla = NULL;
|
||||
tls_set_alert_code(transport->tls, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DESCRIPTION_ACCESS_DENIED);
|
||||
tls_send_alert(transport->tls);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1011,10 +1011,10 @@ BOOL tls_send_alert(rdpTls* tls)
|
||||
if (tls->ssl->s3->wbuf.left == 0)
|
||||
tls->ssl->method->ssl_dispatch_alert(tls->ssl);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BIO *findBufferedBio(BIO *front)
|
||||
{
|
||||
BIO *ret = front;
|
||||
@ -1067,7 +1067,6 @@ int tls_set_alert_code(rdpTls* tls, int level, int description)
|
||||
{
|
||||
tls->alertLevel = level;
|
||||
tls->alertDescription = description;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,7 @@ int main(int argc, char** argv)
|
||||
MSG msg;
|
||||
int status = 0;
|
||||
DWORD dwExitCode;
|
||||
rdpSettings* settings;
|
||||
rdpShadowServer* server;
|
||||
|
||||
shadow_subsystem_set_entry_builtin(NULL);
|
||||
@ -54,6 +55,12 @@ int main(int argc, char** argv)
|
||||
goto fail_server_new;
|
||||
}
|
||||
|
||||
settings = server->settings;
|
||||
|
||||
settings->NlaSecurity = FALSE;
|
||||
settings->TlsSecurity = TRUE;
|
||||
settings->RdpSecurity = TRUE;
|
||||
|
||||
#ifdef WITH_SHADOW_X11
|
||||
server->authentication = TRUE;
|
||||
#else
|
||||
@ -86,8 +93,7 @@ int main(int argc, char** argv)
|
||||
if (!GetExitCodeThread(server->thread, &dwExitCode))
|
||||
status = -1;
|
||||
else
|
||||
status = (int)dwExitCode;
|
||||
|
||||
status = (int) dwExitCode;
|
||||
|
||||
fail_server_start:
|
||||
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->RdpSecurity = TRUE;
|
||||
settings->TlsSecurity = TRUE;
|
||||
settings->NlaSecurity = FALSE;
|
||||
|
||||
if (!(settings->CertificateFile = _strdup(server->CertificateFile)))
|
||||
goto fail_cert_file;
|
||||
if (!(settings->PrivateKeyFile = _strdup(server->PrivateKeyFile)))
|
||||
@ -146,7 +142,7 @@ void shadow_client_context_free(freerdp_peer* peer, rdpShadowClient* client)
|
||||
|
||||
WTSCloseServer((HANDLE) client->vcm);
|
||||
|
||||
/* Clear queued messages and free resource */
|
||||
/* Clear queued messages and free resource */
|
||||
MessageQueue_Clear(client->MsgQueue);
|
||||
MessageQueue_Free(client->MsgQueue);
|
||||
|
||||
@ -250,17 +246,14 @@ BOOL shadow_client_post_connect(freerdp_peer* peer)
|
||||
if (settings->Username && settings->Password)
|
||||
settings->AutoLogonEnabled = TRUE;
|
||||
|
||||
if (server->authentication)
|
||||
if (server->authentication && !settings->NlaSecurity)
|
||||
{
|
||||
if (subsystem->Authenticate)
|
||||
{
|
||||
authStatus = subsystem->Authenticate(subsystem, client,
|
||||
settings->Username, settings->Domain, settings->Password);
|
||||
}
|
||||
}
|
||||
|
||||
if (server->authentication)
|
||||
{
|
||||
if (authStatus < 0)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
/*
|
||||
@ -993,6 +1044,7 @@ void* shadow_client_thread(rdpShadowClient* client)
|
||||
peer->Capabilities = shadow_client_capabilities;
|
||||
peer->PostConnect = shadow_client_post_connect;
|
||||
peer->Activate = shadow_client_activate;
|
||||
peer->Logon = shadow_client_logon;
|
||||
|
||||
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->ContextFree = (psPeerContextFree) shadow_client_context_free;
|
||||
|
||||
peer->settings = freerdp_settings_clone(server->settings);
|
||||
|
||||
if (!freerdp_peer_context_new(peer))
|
||||
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" },
|
||||
{ "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" },
|
||||
{ "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" },
|
||||
{ "help", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "?", "Print help" },
|
||||
{ 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;
|
||||
DWORD flags;
|
||||
COMMAND_LINE_ARGUMENT_A* arg;
|
||||
rdpSettings* settings = server->settings;
|
||||
|
||||
if (argc < 2)
|
||||
return 1;
|
||||
@ -253,6 +259,58 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
||||
@ -708,6 +766,11 @@ rdpShadowServer* shadow_server_new()
|
||||
|
||||
server->authentication = FALSE;
|
||||
|
||||
server->settings = freerdp_settings_new(FREERDP_SETTINGS_SERVER_MODE);
|
||||
|
||||
if (!server)
|
||||
return NULL;
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
@ -716,8 +779,17 @@ void shadow_server_free(rdpShadowServer* server)
|
||||
if (!server)
|
||||
return;
|
||||
|
||||
free(server->ipcSocket);
|
||||
server->ipcSocket = NULL;
|
||||
if (server->ipcSocket)
|
||||
{
|
||||
free(server->ipcSocket);
|
||||
server->ipcSocket = NULL;
|
||||
}
|
||||
|
||||
if (server->settings)
|
||||
{
|
||||
freerdp_settings_free(server->settings);
|
||||
server->settings = NULL;
|
||||
}
|
||||
|
||||
free(server);
|
||||
}
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#include "../sspi.h"
|
||||
#include "../log.h"
|
||||
#define TAG WINPR_TAG("negociate")
|
||||
#define TAG WINPR_TAG("negotiate")
|
||||
|
||||
extern const SecurityFunctionTableA NTLM_SecurityFunctionTableA;
|
||||
extern const SecurityFunctionTableW NTLM_SecurityFunctionTableW;
|
||||
|
Loading…
Reference in New Issue
Block a user