wfreerdp-server: fix server-side TLS on Windows

This commit is contained in:
Marc-André Moreau 2012-06-12 23:09:30 -04:00
parent 209d44e843
commit 33d0d59306
6 changed files with 68 additions and 19 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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:

View File

@ -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)