mirror of https://github.com/FreeRDP/FreeRDP
wfreerdp-server: fix server-side TLS on Windows
This commit is contained in:
parent
209d44e843
commit
33d0d59306
|
@ -49,6 +49,7 @@ FREERDP_API boolean tls_disconnect(rdpTls* tls);
|
|||
FREERDP_API int tls_read(rdpTls* tls, uint8* data, int length);
|
||||
FREERDP_API int tls_write(rdpTls* tls, uint8* data, int length);
|
||||
|
||||
FREERDP_API int tls_read_all(rdpTls* tls, uint8* data, int length);
|
||||
FREERDP_API int tls_write_all(rdpTls* tls, uint8* data, int length);
|
||||
|
||||
FREERDP_API boolean tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname);
|
||||
|
|
|
@ -190,12 +190,13 @@ static void freerdp_listener_close(freerdp_listener* instance)
|
|||
{
|
||||
int i;
|
||||
|
||||
rdpListener* listener = (rdpListener*)instance->listener;
|
||||
rdpListener* listener = (rdpListener*) instance->listener;
|
||||
|
||||
for (i = 0; i < listener->num_sockfds; i++)
|
||||
{
|
||||
close(listener->sockfds[i]);
|
||||
}
|
||||
|
||||
listener->num_sockfds = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -189,8 +189,14 @@ boolean tcp_set_blocking_mode(rdpTcp* tcp, boolean blocking)
|
|||
else
|
||||
fcntl(tcp->sockfd, F_SETFL, flags | O_NONBLOCK);
|
||||
#else
|
||||
int status;
|
||||
u_long arg = blocking;
|
||||
ioctlsocket(tcp->sockfd, FIONBIO, &arg);
|
||||
|
||||
status = ioctlsocket(tcp->sockfd, FIONBIO, &arg);
|
||||
|
||||
if (status != NO_ERROR)
|
||||
printf("ioctlsocket() failed with error: %ld\n", status);
|
||||
|
||||
tcp->wsa_event = WSACreateEvent();
|
||||
WSAEventSelect(tcp->sockfd, tcp->wsa_event, FD_READ);
|
||||
#endif
|
||||
|
|
|
@ -342,7 +342,7 @@ int credssp_client_authenticate(rdpCredssp* credssp)
|
|||
return -1;
|
||||
|
||||
#ifdef WITH_DEBUG_CREDSSP
|
||||
printf("Receiving Authentication Token\n");
|
||||
printf("Receiving Authentication Token (%d)\n", credssp->negoToken.cbBuffer);
|
||||
winpr_HexDump(credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer);
|
||||
#endif
|
||||
|
||||
|
@ -457,9 +457,9 @@ int credssp_server_authenticate(rdpCredssp* credssp)
|
|||
have_context = false;
|
||||
have_input_buffer = false;
|
||||
have_pub_key_auth = false;
|
||||
memset(&input_buffer, 0, sizeof(SecBuffer));
|
||||
memset(&output_buffer, 0, sizeof(SecBuffer));
|
||||
memset(&credssp->ContextSizes, 0, sizeof(SecPkgContext_Sizes));
|
||||
ZeroMemory(&input_buffer, sizeof(SecBuffer));
|
||||
ZeroMemory(&output_buffer, sizeof(SecBuffer));
|
||||
ZeroMemory(&credssp->ContextSizes, sizeof(SecPkgContext_Sizes));
|
||||
|
||||
fContextReq = ASC_REQ_REPLAY_DETECT | ASC_REQ_SEQUENCE_DETECT |
|
||||
ASC_REQ_CONFIDENTIALITY | ASC_REQ_DELEGATE;
|
||||
|
@ -490,6 +490,12 @@ int credssp_server_authenticate(rdpCredssp* credssp)
|
|||
p_buffer->pvBuffer = credssp->negoToken.pvBuffer;
|
||||
p_buffer->cbBuffer = credssp->negoToken.cbBuffer;
|
||||
|
||||
if (credssp->negoToken.cbBuffer < 1)
|
||||
{
|
||||
printf("CredSSP: invalid negoToken!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
output_buffer_desc.ulVersion = SECBUFFER_VERSION;
|
||||
output_buffer_desc.cBuffers = 1;
|
||||
output_buffer_desc.pBuffers = &output_buffer;
|
||||
|
@ -1060,12 +1066,13 @@ int credssp_recv(rdpCredssp* credssp)
|
|||
int status;
|
||||
UINT32 version;
|
||||
|
||||
s = stream_new(2048);
|
||||
status = tls_read(credssp->tls, s->data, stream_get_left(s));
|
||||
s->size = status;
|
||||
s = stream_new(4096);
|
||||
|
||||
status = tls_read_all(credssp->tls, s->p, stream_get_left(s));
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
printf("credssp_recv() error: %d\n", status);
|
||||
stream_free(s);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -115,7 +115,8 @@ boolean tls_connect(rdpTls* tls)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!tls_verify_certificate(tls, cert, tls->settings->hostname)) {
|
||||
if (!tls_verify_certificate(tls, cert, tls->settings->hostname))
|
||||
{
|
||||
printf("tls_connect: certificate not trusted, aborting.\n");
|
||||
tls_disconnect(tls);
|
||||
tls_free_certificate(cert);
|
||||
|
@ -187,12 +188,29 @@ boolean tls_accept(rdpTls* tls, const char* cert_file, const char* privatekey_fi
|
|||
return false;
|
||||
}
|
||||
|
||||
connection_status = SSL_accept(tls->ssl);
|
||||
|
||||
if (connection_status <= 0)
|
||||
while (1)
|
||||
{
|
||||
if (tls_print_error("SSL_accept", tls->ssl, connection_status))
|
||||
return false;
|
||||
connection_status = SSL_accept(tls->ssl);
|
||||
|
||||
if (connection_status <= 0)
|
||||
{
|
||||
switch (SSL_get_error(tls->ssl, connection_status))
|
||||
{
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
break;
|
||||
|
||||
default:
|
||||
if (tls_print_error("SSL_accept", tls->ssl, connection_status))
|
||||
return false;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("TLS connection accepted\n");
|
||||
|
@ -231,6 +249,19 @@ int tls_read(rdpTls* tls, uint8* data, int length)
|
|||
return status;
|
||||
}
|
||||
|
||||
int tls_read_all(rdpTls* tls, uint8* data, int length)
|
||||
{
|
||||
int status;
|
||||
|
||||
do
|
||||
{
|
||||
status = tls_read(tls, data, length);
|
||||
}
|
||||
while (status == 0);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int tls_write(rdpTls* tls, uint8* data, int length)
|
||||
{
|
||||
int status;
|
||||
|
@ -297,11 +328,11 @@ boolean tls_print_error(char* func, SSL* connection, int value)
|
|||
return true;
|
||||
|
||||
case SSL_ERROR_WANT_READ:
|
||||
printf("SSL_ERROR_WANT_READ\n");
|
||||
printf("%s: SSL_ERROR_WANT_READ\n", func);
|
||||
return false;
|
||||
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
printf("SSL_ERROR_WANT_WRITE\n");
|
||||
printf("%s: SSL_ERROR_WANT_WRITE\n", func);
|
||||
return false;
|
||||
|
||||
case SSL_ERROR_SYSCALL:
|
||||
|
|
|
@ -167,7 +167,10 @@ static DWORD WINAPI wf_peer_main_loop(LPVOID lpParam)
|
|||
/* Initialize the real server settings here */
|
||||
client->settings->cert_file = xstrdup("server.crt");
|
||||
client->settings->privatekey_file = xstrdup("server.key");
|
||||
|
||||
client->settings->nla_security = true;
|
||||
client->settings->tls_security = false;
|
||||
client->settings->rdp_security = false;
|
||||
|
||||
client->PostConnect = wf_peer_post_connect;
|
||||
client->Activate = wf_peer_activate;
|
||||
|
@ -217,7 +220,7 @@ static void wf_peer_accepted(freerdp_listener* instance, freerdp_peer* client)
|
|||
g_thread_count++;
|
||||
}
|
||||
|
||||
static void test_server_main_loop(freerdp_listener* instance)
|
||||
static void wf_server_main_loop(freerdp_listener* instance)
|
||||
{
|
||||
int rcount;
|
||||
void* rfds[32];
|
||||
|
@ -267,7 +270,7 @@ int main(int argc, char* argv[])
|
|||
if (instance->Open(instance, NULL, port))
|
||||
{
|
||||
/* Entering the server main loop. In a real server the listener can be run in its own thread. */
|
||||
test_server_main_loop(instance);
|
||||
wf_server_main_loop(instance);
|
||||
}
|
||||
|
||||
if (g_thread_count > 0)
|
||||
|
|
Loading…
Reference in New Issue