diff --git a/cunit/test_ntlmssp.c b/cunit/test_ntlmssp.c index c74eea6ba..c19318571 100644 --- a/cunit/test_ntlmssp.c +++ b/cunit/test_ntlmssp.c @@ -85,7 +85,7 @@ void test_ntlmssp_compute_ntlm_hash(void) char password[] = "Password"; char expected_ntlm_hash[16] = "\xa4\xf4\x9c\x40\x65\x10\xbd\xca\xb6\x82\x4e\xe7\xc3\x0f\xd8\x52"; - ntlmssp = ntlmssp_new(); + ntlmssp = ntlmssp_client_new(); ntlmssp_set_password(ntlmssp, password); ntlmssp_compute_ntlm_hash(&ntlmssp->password, ntlm_hash); @@ -113,7 +113,7 @@ void test_ntlmssp_compute_ntlm_v2_hash(void) char domain[] = "Domain"; char expected_ntlm_v2_hash[16] = "\x0c\x86\x8a\x40\x3b\xfd\x7a\x93\xa3\x00\x1e\xf2\x2e\xf0\x2e\x3f"; - ntlmssp = ntlmssp_new(); + ntlmssp = ntlmssp_client_new(); ntlmssp_set_password(ntlmssp, password); ntlmssp_set_username(ntlmssp, username); ntlmssp_set_domain(ntlmssp, domain); @@ -166,7 +166,7 @@ void test_ntlmssp_compute_lm_v2_response(void) char lm_client_challenge[8] = "\x47\xa2\xe5\xcf\x27\xf7\x3c\x43"; char expected_lm_v2_response[24] = "\xa0\x98\x01\x10\x19\xbb\x5d\x00\xf6\xbe\x00\x33\x90\x20\x34\xb3\x47\xa2\xe5\xcf\x27\xf7\x3c\x43"; - ntlmssp = ntlmssp_new(); + ntlmssp = ntlmssp_client_new(); ntlmssp_set_password(ntlmssp, password); ntlmssp_set_username(ntlmssp, username); ntlmssp_set_domain(ntlmssp, domain); @@ -228,7 +228,7 @@ void test_ntlmssp_compute_ntlm_v2_response(void) char expected_session_base_key[16] = "\x6e\xf1\x6b\x79\x88\xf2\x3d\x7e\x54\x2a\x1a\x38\x4e\xa0\x6b\x52"; - ntlmssp = ntlmssp_new(); + ntlmssp = ntlmssp_client_new(); ntlmssp_set_password(ntlmssp, password); ntlmssp_set_username(ntlmssp, username); ntlmssp_set_domain(ntlmssp, domain); @@ -288,7 +288,7 @@ void test_ntlmssp_generate_client_signing_key(void) uint8 exported_session_key[16] = "\x89\x90\x0d\x5d\x2c\x53\x2b\x36\x31\xcc\x1a\x46\xce\xa9\x34\xf1"; uint8 expected_client_signing_key[16] = "\xbf\x5e\x42\x76\x55\x68\x38\x97\x45\xd3\xb4\x9f\x5e\x2f\xbc\x89"; - ntlmssp = ntlmssp_new(); + ntlmssp = ntlmssp_client_new(); memcpy(ntlmssp->exported_session_key, exported_session_key, sizeof(exported_session_key)); ntlmssp_generate_client_signing_key(ntlmssp); @@ -312,7 +312,7 @@ void test_ntlmssp_generate_server_signing_key(void) uint8 exported_session_key[16] = "\x89\x90\x0d\x5d\x2c\x53\x2b\x36\x31\xcc\x1a\x46\xce\xa9\x34\xf1"; uint8 expected_server_signing_key[16] = "\x9b\x3b\x64\x89\xda\x84\x52\x17\xd5\xc2\x6e\x90\x16\x3b\x42\x11"; - ntlmssp = ntlmssp_new(); + ntlmssp = ntlmssp_client_new(); memcpy(ntlmssp->exported_session_key, exported_session_key, sizeof(exported_session_key)); ntlmssp_generate_server_signing_key(ntlmssp); @@ -336,7 +336,7 @@ void test_ntlmssp_generate_client_sealing_key(void) uint8 exported_session_key[16] = "\x89\x90\x0d\x5d\x2c\x53\x2b\x36\x31\xcc\x1a\x46\xce\xa9\x34\xf1"; uint8 expected_client_sealing_key[16] = "\xca\x41\xcd\x08\x48\x07\x22\x6e\x0d\x84\xc3\x88\xa5\x07\xa9\x73"; - ntlmssp = ntlmssp_new(); + ntlmssp = ntlmssp_client_new(); memcpy(ntlmssp->exported_session_key, exported_session_key, sizeof(exported_session_key)); ntlmssp_generate_client_sealing_key(ntlmssp); @@ -360,7 +360,7 @@ void test_ntlmssp_generate_server_sealing_key(void) uint8 exported_session_key[16] = "\x89\x90\x0d\x5d\x2c\x53\x2b\x36\x31\xcc\x1a\x46\xce\xa9\x34\xf1"; uint8 expected_server_sealing_key[16] = "\x14\xb7\x1d\x06\x2c\x68\x2e\xad\x4b\x0e\x95\x23\x70\x91\x98\x90"; - ntlmssp = ntlmssp_new(); + ntlmssp = ntlmssp_client_new(); memcpy(ntlmssp->exported_session_key, exported_session_key, sizeof(exported_session_key)); ntlmssp_generate_server_sealing_key(ntlmssp); @@ -385,7 +385,7 @@ void test_ntlmssp_encrypt_random_session_key(void) uint8 exported_session_key[16] = "\x89\x90\x0d\x5d\x2c\x53\x2b\x36\x31\xcc\x1a\x46\xce\xa9\x34\xf1"; uint8 expected_encrypted_random_session_key[16] = "\xb1\xd2\x45\x42\x0f\x37\x9a\x0e\xe0\xce\x77\x40\x10\x8a\xda\xba"; - ntlmssp = ntlmssp_new(); + ntlmssp = ntlmssp_client_new(); memcpy(ntlmssp->key_exchange_key, key_exchange_key, 16); memcpy(ntlmssp->exported_session_key, exported_session_key, 16); memcpy(ntlmssp->random_session_key, exported_session_key, 16); @@ -470,7 +470,7 @@ void test_ntlmssp_compute_message_integrity_check(void) "\x00\x00\x00\x00\x00\x00\x00\x00\xd5\x82\xff\x1e\xb6\xf8\x4a\x1c" "\x08\x78\x69\x9f\xa8\x84\x32\xaa"; - ntlmssp = ntlmssp_new(); + ntlmssp = ntlmssp_client_new(); memcpy(ntlmssp->exported_session_key, exported_session_key, 16); ntlmssp->negotiate_message.data = (void*) negotiate_message_data; @@ -574,7 +574,7 @@ void test_ntlmssp_encrypt_message(void) public_key.data = public_key_data; public_key.length = sizeof(public_key_data); - ntlmssp = ntlmssp_new(); + ntlmssp = ntlmssp_client_new(); memcpy(ntlmssp->client_signing_key, client_signing_key, 16); memcpy(ntlmssp->client_sealing_key, client_sealing_key, 16); ntlmssp_init_rc4_seal_states(ntlmssp); @@ -684,7 +684,7 @@ void test_ntlmssp_decrypt_message(void) encrypted_public_key.data = encrypted_public_key_data; encrypted_public_key.length = sizeof(encrypted_public_key_data); - ntlmssp = ntlmssp_new(); + ntlmssp = ntlmssp_client_new(); memcpy(ntlmssp->server_signing_key, server_signing_key, 16); memcpy(ntlmssp->server_sealing_key, server_sealing_key, 16); ntlmssp_init_rc4_seal_states(ntlmssp); diff --git a/libfreerdp-core/connection.c b/libfreerdp-core/connection.c index 92ece9f9b..9c7bf931f 100644 --- a/libfreerdp-core/connection.c +++ b/libfreerdp-core/connection.c @@ -502,7 +502,7 @@ boolean rdp_client_connect_finalize(rdpRdp* rdp) boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s) { - boolean ret; + boolean status; transport_set_blocking_mode(rdp->transport, true); @@ -547,15 +547,15 @@ boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s) if (!nego_send_negotiation_response(rdp->nego)) return false; - ret = false; + status = false; if (rdp->nego->selected_protocol & PROTOCOL_NLA) - ret = transport_accept_nla(rdp->transport); + status = transport_accept_nla(rdp->transport); else if (rdp->nego->selected_protocol & PROTOCOL_TLS) - ret = transport_accept_tls(rdp->transport); + status = transport_accept_tls(rdp->transport); else if (rdp->nego->selected_protocol == PROTOCOL_RDP) /* 0 */ - ret = transport_accept_rdp(rdp->transport); + status = transport_accept_rdp(rdp->transport); - if (!ret) + if (!status) return false; transport_set_blocking_mode(rdp->transport, false); diff --git a/libfreerdp-core/credssp.c b/libfreerdp-core/credssp.c index 6ef40e103..4eb1acdc7 100644 --- a/libfreerdp-core/credssp.c +++ b/libfreerdp-core/credssp.c @@ -68,11 +68,11 @@ */ /** - * Initialize NTLMSSP authentication module. + * Initialize NTLMSSP authentication module (client). * @param credssp */ -int credssp_ntlmssp_init(rdpCredssp* credssp) +int credssp_ntlmssp_client_init(rdpCredssp* credssp) { freerdp* instance; NTLMSSP* ntlmssp = credssp->ntlmssp; @@ -81,7 +81,7 @@ int credssp_ntlmssp_init(rdpCredssp* credssp) if ((settings->password == NULL) || (settings->username == NULL)) { - if(instance->Authenticate) + if (instance->Authenticate) { boolean proceed = instance->Authenticate(instance, &settings->username, &settings->password, &settings->domain); @@ -119,18 +119,28 @@ int credssp_ntlmssp_init(rdpCredssp* credssp) } /** - * Authenticate with server using CredSSP. + * Initialize NTLMSSP authentication module (server). + * @param credssp + */ + +int credssp_ntlmssp_server_init(rdpCredssp* credssp) +{ + return 1; +} + +/** + * Authenticate with server using CredSSP (client). * @param credssp * @return 1 if authentication is successful */ -int credssp_authenticate(rdpCredssp* credssp) +int credssp_client_authenticate(rdpCredssp* credssp) { NTLMSSP* ntlmssp = credssp->ntlmssp; STREAM* s = stream_new(0); uint8* negoTokenBuffer = (uint8*) xmalloc(2048); - if (credssp_ntlmssp_init(credssp) == 0) + if (credssp_ntlmssp_client_init(credssp) == 0) return 0; /* NTLMSSP NEGOTIATE MESSAGE */ @@ -184,6 +194,34 @@ int credssp_authenticate(rdpCredssp* credssp) return 1; } +/** + * Authenticate with client using CredSSP (server). + * @param credssp + * @return 1 if authentication is successful + */ + +int credssp_server_authenticate(rdpCredssp* credssp) +{ + if (credssp_ntlmssp_server_init(credssp) == 0) + return 0; + + return 1; +} + +/** + * Authenticate using CredSSP. + * @param credssp + * @return 1 if authentication is successful + */ + +int credssp_authenticate(rdpCredssp* credssp) +{ + if (credssp->server) + return credssp_server_authenticate(credssp); + else + return credssp_client_authenticate(credssp); +} + /** * Encrypt TLS public key using CredSSP. * @param credssp @@ -610,19 +648,25 @@ void credssp_current_time(uint8* timestamp) rdpCredssp* credssp_new(rdpTransport* transport) { - rdpCredssp* self; + rdpCredssp* credssp; - self = (rdpCredssp*) xzalloc(sizeof(rdpCredssp)); + credssp = (rdpCredssp*) xzalloc(sizeof(rdpCredssp)); - if (self != NULL) + if (credssp != NULL) { - self->transport = transport; - self->send_seq_num = 0; - self->ntlmssp = ntlmssp_new(); - self->settings = transport->settings; + credssp->transport = transport; + credssp->send_seq_num = 0; + credssp->settings = transport->settings; + + credssp->server = credssp->settings->server_mode; + + if (credssp->server) + credssp->ntlmssp = ntlmssp_server_new(); + else + credssp->ntlmssp = ntlmssp_client_new(); } - return self; + return credssp; } /** diff --git a/libfreerdp-core/credssp.h b/libfreerdp-core/credssp.h index d98554ac1..8a9f1264e 100644 --- a/libfreerdp-core/credssp.h +++ b/libfreerdp-core/credssp.h @@ -36,6 +36,7 @@ typedef struct rdp_credssp rdpCredssp; struct rdp_credssp { + boolean server; rdpBlob negoToken; rdpBlob pubKeyAuth; rdpBlob authInfo; diff --git a/libfreerdp-core/ntlmssp.c b/libfreerdp-core/ntlmssp.c index 761507a69..07e208d7b 100644 --- a/libfreerdp-core/ntlmssp.c +++ b/libfreerdp-core/ntlmssp.c @@ -1940,6 +1940,26 @@ int ntlmssp_recv(NTLMSSP* ntlmssp, STREAM* s) return ntlmssp_client_recv(ntlmssp, s); } +/** + * Create new NTLMSSP state machine instance. + * @return + */ + +NTLMSSP* ntlmssp_new() +{ + NTLMSSP* ntlmssp = (NTLMSSP*) xmalloc(sizeof(NTLMSSP)); + + if (ntlmssp != NULL) + { + memset(ntlmssp, '\0', sizeof(NTLMSSP)); + ntlmssp->av_pairs = (AV_PAIRS*) xmalloc(sizeof(AV_PAIRS)); + memset(ntlmssp->av_pairs, 0, sizeof(AV_PAIRS)); + ntlmssp_init(ntlmssp); + } + + return ntlmssp; +} + /** * Create new NTLMSSP client state machine instance. * @return @@ -1964,26 +1984,6 @@ NTLMSSP* ntlmssp_server_new() return ntlmssp; } -/** - * Create new NTLMSSP state machine instance. - * @return - */ - -NTLMSSP* ntlmssp_new() -{ - NTLMSSP* ntlmssp = (NTLMSSP*) xmalloc(sizeof(NTLMSSP)); - - if (ntlmssp != NULL) - { - memset(ntlmssp, '\0', sizeof(NTLMSSP)); - ntlmssp->av_pairs = (AV_PAIRS*) xmalloc(sizeof(AV_PAIRS)); - memset(ntlmssp->av_pairs, 0, sizeof(AV_PAIRS)); - ntlmssp_init(ntlmssp); - } - - return ntlmssp; -} - /** * Initialize NTLMSSP state machine. * @param ntlmssp diff --git a/libfreerdp-core/ntlmssp.h b/libfreerdp-core/ntlmssp.h index 1767c11fd..2c64f0ade 100644 --- a/libfreerdp-core/ntlmssp.h +++ b/libfreerdp-core/ntlmssp.h @@ -154,7 +154,8 @@ int ntlmssp_decrypt_message(NTLMSSP* ntlmssp, rdpBlob* encrypted_msg, rdpBlob* m int ntlmssp_recv(NTLMSSP* ntlmssp, STREAM* s); int ntlmssp_send(NTLMSSP* ntlmssp, STREAM* s); -NTLMSSP* ntlmssp_new(); +NTLMSSP* ntlmssp_client_new(); +NTLMSSP* ntlmssp_server_new(); void ntlmssp_init(NTLMSSP* ntlmssp); void ntlmssp_free(NTLMSSP* ntlmssp); diff --git a/libfreerdp-core/transport.c b/libfreerdp-core/transport.c index 90c6948be..358e53343 100644 --- a/libfreerdp-core/transport.c +++ b/libfreerdp-core/transport.c @@ -167,7 +167,17 @@ boolean transport_accept_nla(rdpTransport* transport) if (transport->settings->authentication != true) return true; - /* Blocking here until NLA is complete */ + if (transport->credssp == NULL) + transport->credssp = credssp_new(transport); + + if (credssp_authenticate(transport->credssp) < 0) + { + printf("client authentication failure\n"); + credssp_free(transport->credssp); + return false; + } + + credssp_free(transport->credssp); return true; } diff --git a/server/X11/xf_peer.c b/server/X11/xf_peer.c index 2a55af829..14967f175 100644 --- a/server/X11/xf_peer.c +++ b/server/X11/xf_peer.c @@ -629,6 +629,8 @@ void* xf_peer_main_loop(void* arg) settings->privatekey_file = freerdp_construct_path(server_file_path, "server.key"); settings->nla_security = false; + //settings->nla_security = true; + settings->rfx_codec = true; client->Capabilities = xf_peer_capabilities;