diff --git a/include/freerdp/sspi/credssp.h b/include/freerdp/sspi/credssp.h index 22874dbf3..cf478a234 100644 --- a/include/freerdp/sspi/credssp.h +++ b/include/freerdp/sspi/credssp.h @@ -59,6 +59,7 @@ FREERDP_API int credssp_authenticate(rdpCredssp* credssp); FREERDP_API void credssp_send(rdpCredssp* credssp); FREERDP_API int credssp_recv(rdpCredssp* credssp); +FREERDP_API void credssp_buffer_print(rdpCredssp* credssp); FREERDP_API void credssp_buffer_free(rdpCredssp* credssp); SECURITY_STATUS credssp_verify_public_key_echo(rdpCredssp* credssp); diff --git a/libfreerdp-crypto/tls.c b/libfreerdp-crypto/tls.c index ca342ad86..26b1e1edc 100644 --- a/libfreerdp-crypto/tls.c +++ b/libfreerdp-crypto/tls.c @@ -22,16 +22,19 @@ #include -static CryptoCert tls_get_certificate(rdpTls* tls) +static CryptoCert tls_get_certificate(rdpTls* tls, boolean peer) { CryptoCert cert; X509* server_cert; - server_cert = SSL_get_peer_certificate(tls->ssl); + if (peer) + server_cert = SSL_get_peer_certificate(tls->ssl); + else + server_cert = SSL_get_certificate(tls->ssl); if (!server_cert) { - printf("ssl_verify: failed to get the server SSL certificate\n"); + printf("tls_get_certificate: failed to get the server TLS certificate\n"); cert = NULL; } else @@ -102,7 +105,7 @@ boolean tls_connect(rdpTls* tls) } } - cert = tls_get_certificate(tls); + cert = tls_get_certificate(tls, true); if (cert == NULL) { @@ -126,6 +129,7 @@ boolean tls_connect(rdpTls* tls) boolean tls_accept(rdpTls* tls, const char* cert_file, const char* privatekey_file) { + CryptoCert cert; int connection_status; tls->ctx = SSL_CTX_new(SSLv23_server_method()); @@ -162,6 +166,20 @@ boolean tls_accept(rdpTls* tls, const char* cert_file, const char* privatekey_fi return false; } + cert = tls_get_certificate(tls, false); + + if (cert == NULL) + { + printf("tls_connect: tls_get_certificate failed to return the server certificate.\n"); + return false; + } + + if (!crypto_cert_get_public_key(cert, &tls->public_key)) + { + printf("tls_connect: crypto_cert_get_public_key failed to return the server public key.\n"); + return false; + } + if (SSL_set_fd(tls->ssl, tls->sockfd) < 1) { printf("SSL_set_fd failed\n"); diff --git a/libfreerdp-sspi/credssp.c b/libfreerdp-sspi/credssp.c index b336de610..f0025a936 100644 --- a/libfreerdp-sspi/credssp.c +++ b/libfreerdp-sspi/credssp.c @@ -73,7 +73,9 @@ * */ -//#define WITH_DEBUG_CREDSSP 1 +#ifdef WITH_DEBUG_NLA +#define WITH_DEBUG_CREDSSP +#endif void credssp_SetContextIdentity(rdpCredssp* context, SEC_WINNT_AUTH_IDENTITY* identity) { @@ -170,6 +172,7 @@ int credssp_ntlm_client_init(rdpCredssp* credssp) xfree(identity.User); xfree(identity.Domain); xfree(identity.Password); + return 1; } @@ -178,15 +181,36 @@ int credssp_ntlm_client_init(rdpCredssp* credssp) * @param credssp */ +char* test_User = "username"; +char* test_Password = "password"; + int credssp_ntlm_server_init(rdpCredssp* credssp) { + size_t size; freerdp* instance; + SEC_WINNT_AUTH_IDENTITY identity; rdpSettings* settings = credssp->settings; instance = (freerdp*) settings->instance; + identity.User = (uint16*) freerdp_uniconv_out(credssp->uniconv, test_User, &size); + identity.UserLength = (uint32) size; + + identity.Domain = (uint16*) NULL; + identity.DomainLength = 0; + + identity.Password = (uint16*) freerdp_uniconv_out(credssp->uniconv, test_Password, &size); + identity.PasswordLength = (uint32) size; + + identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; + + credssp_SetContextIdentity(credssp, &identity); + sspi_SecBufferAlloc(&credssp->PublicKey, credssp->tls->public_key.length); memcpy(credssp->PublicKey.pvBuffer, credssp->tls->public_key.data, credssp->tls->public_key.length); + xfree(identity.User); + xfree(identity.Password); + return 1; } @@ -494,7 +518,7 @@ int credssp_server_authenticate(rdpCredssp* credssp) #ifdef WITH_DEBUG_CREDSSP printf("Receiving Authentication Token\n"); - freerdp_hexdump(credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer); + credssp_buffer_print(credssp); #endif p_buffer = &input_buffer_desc.pBuffers[0]; @@ -519,6 +543,10 @@ int credssp_server_authenticate(rdpCredssp* credssp) input_buffer.pvBuffer = NULL; } + p_buffer = &output_buffer_desc.pBuffers[0]; + credssp->negoToken.pvBuffer = p_buffer->pvBuffer; + credssp->negoToken.cbBuffer = p_buffer->cbBuffer; + if ((status == SEC_I_COMPLETE_AND_CONTINUE) || (status == SEC_I_COMPLETE_NEEDED)) { if (credssp->table->CompleteAuthToken != NULL) @@ -526,6 +554,10 @@ int credssp_server_authenticate(rdpCredssp* credssp) have_pub_key_auth = true; + sspi_SecBufferFree(&credssp->negoToken); + credssp->negoToken.pvBuffer = NULL; + credssp->negoToken.cbBuffer = 0; + if (credssp->table->QueryContextAttributes(&credssp->context, SECPKG_ATTR_SIZES, &credssp->ContextSizes) != SEC_E_OK) { printf("QueryContextAttributes SECPKG_ATTR_SIZES failure\n"); @@ -572,14 +604,9 @@ int credssp_server_authenticate(rdpCredssp* credssp) /* send authentication token */ - p_buffer = &output_buffer_desc.pBuffers[0]; - - credssp->negoToken.pvBuffer = p_buffer->pvBuffer; - credssp->negoToken.cbBuffer = p_buffer->cbBuffer; - #ifdef WITH_DEBUG_CREDSSP printf("Sending Authentication Token\n"); - freerdp_hexdump(credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer); + credssp_buffer_print(credssp); #endif credssp_send(credssp); @@ -591,6 +618,16 @@ int credssp_server_authenticate(rdpCredssp* credssp) have_context = true; } + /* Send Encrypted Public Key +1 */ + + //credssp_send(credssp); + //credssp_buffer_free(credssp); + + /* Receive encrypted credentials */ + + if (credssp_recv(credssp) < 0) + return -1; + if (status != SEC_E_OK) { printf("AcceptSecurityContext status: 0x%08X\n", status); @@ -1002,6 +1039,27 @@ int credssp_recv(rdpCredssp* credssp) return 0; } +void credssp_buffer_print(rdpCredssp* credssp) +{ + if (credssp->negoToken.cbBuffer > 0) + { + printf("CredSSP.negoToken (length = %d):\n", credssp->negoToken.cbBuffer); + freerdp_hexdump(credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer); + } + + if (credssp->pubKeyAuth.cbBuffer > 0) + { + printf("CredSSP.pubKeyAuth (length = %d):\n", credssp->pubKeyAuth.cbBuffer); + freerdp_hexdump(credssp->pubKeyAuth.pvBuffer, credssp->pubKeyAuth.cbBuffer); + } + + if (credssp->authInfo.cbBuffer > 0) + { + printf("CredSSP.authInfo (length = %d):\n", credssp->authInfo.cbBuffer); + freerdp_hexdump(credssp->authInfo.pvBuffer, credssp->authInfo.cbBuffer); + } +} + void credssp_buffer_free(rdpCredssp* credssp) { sspi_SecBufferFree(&credssp->negoToken);