From 82863a85189745f0cb0e7653519f33dce361db0e Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 20 Nov 2018 16:48:59 +0100 Subject: [PATCH] Refactored NLA to be self contained. --- libfreerdp/core/nego.c | 2 +- libfreerdp/core/nla.c | 81 +++++++++++++++++++++++++++++++++++++++++++++ libfreerdp/core/nla.h | 53 ++++------------------------- libfreerdp/core/rdp.c | 18 ++++++---- libfreerdp/core/transport.c | 6 ++-- 5 files changed, 102 insertions(+), 58 deletions(-) diff --git a/libfreerdp/core/nego.c b/libfreerdp/core/nego.c index ece8a4b..dd663c7 100644 --- a/libfreerdp/core/nego.c +++ b/libfreerdp/core/nego.c @@ -1426,7 +1426,7 @@ SEC_WINNT_AUTH_IDENTITY* nego_get_identity(rdpNego* nego) if (!nego) return NULL; - return nego->transport->nla->identity; + return nla_get_identity(nego->transport->nla); } void nego_free_nla(rdpNego* nego) diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index 9a7659d..c146a97 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -99,6 +99,53 @@ #define TERMSRV_SPN_PREFIX "TERMSRV/" + +struct rdp_nla +{ + BOOL server; + NLA_STATE state; + int sendSeqNum; + int recvSeqNum; + freerdp* instance; + CtxtHandle context; + LPTSTR SspiModule; + char* SamFile; + rdpSettings* settings; + rdpTransport* transport; + UINT32 cbMaxToken; +#if defined(UNICODE) + SEC_WCHAR* packageName; +#else + SEC_CHAR* packageName; +#endif + UINT32 version; + UINT32 peerVersion; + UINT32 errorCode; + ULONG fContextReq; + ULONG pfContextAttr; + BOOL haveContext; + BOOL haveInputBuffer; + BOOL havePubKeyAuth; + SECURITY_STATUS status; + CredHandle credentials; + TimeStamp expiration; + PSecPkgInfo pPackageInfo; + SecBuffer inputBuffer; + SecBuffer outputBuffer; + SecBufferDesc inputBufferDesc; + SecBufferDesc outputBufferDesc; + SecBuffer negoToken; + SecBuffer pubKeyAuth; + SecBuffer authInfo; + SecBuffer ClientNonce; + SecBuffer PublicKey; + SecBuffer tsCredentials; + LPTSTR ServicePrincipalName; + SEC_WINNT_AUTH_IDENTITY* identity; + PSecurityFunctionTable table; + SecPkgContext_Sizes ContextSizes; +}; + static BOOL nla_send(rdpNla* nla); static int nla_recv(rdpNla* nla); static void nla_buffer_print(rdpNla* nla); @@ -2387,3 +2434,37 @@ void nla_free(rdpNla* nla) nla_identity_free(nla->identity); free(nla); } + +SEC_WINNT_AUTH_IDENTITY* nla_get_identity(rdpNla* nla) +{ + if (!nla) + return NULL; + + return nla->identity; +} + +NLA_STATE nla_get_state(rdpNla* nla) +{ + if (!nla) + return NLA_STATE_FINAL; + + return nla->state; +} + +BOOL nla_set_state(rdpNla* nla, NLA_STATE state) +{ + if (!nla) + return FALSE; + + nla->state = state; + return TRUE; +} + +BOOL nla_set_service_principal(rdpNla* nla, LPSTR principal) +{ + if (!nla || !principal) + return FALSE; + + nla->ServicePrincipalName = principal; + return TRUE; +} diff --git a/libfreerdp/core/nla.h b/libfreerdp/core/nla.h index fcd2ece..2c5a13e 100644 --- a/libfreerdp/core/nla.h +++ b/libfreerdp/core/nla.h @@ -47,52 +47,6 @@ enum _NLA_STATE }; typedef enum _NLA_STATE NLA_STATE; -struct rdp_nla -{ - BOOL server; - NLA_STATE state; - int sendSeqNum; - int recvSeqNum; - freerdp* instance; - CtxtHandle context; - LPTSTR SspiModule; - char* SamFile; - rdpSettings* settings; - rdpTransport* transport; - UINT32 cbMaxToken; -#if defined(UNICODE) - SEC_WCHAR* packageName; -#else - SEC_CHAR* packageName; -#endif - UINT32 version; - UINT32 peerVersion; - UINT32 errorCode; - ULONG fContextReq; - ULONG pfContextAttr; - BOOL haveContext; - BOOL haveInputBuffer; - BOOL havePubKeyAuth; - SECURITY_STATUS status; - CredHandle credentials; - TimeStamp expiration; - PSecPkgInfo pPackageInfo; - SecBuffer inputBuffer; - SecBuffer outputBuffer; - SecBufferDesc inputBufferDesc; - SecBufferDesc outputBufferDesc; - SecBuffer negoToken; - SecBuffer pubKeyAuth; - SecBuffer authInfo; - SecBuffer ClientNonce; - SecBuffer PublicKey; - SecBuffer tsCredentials; - LPTSTR ServicePrincipalName; - SEC_WINNT_AUTH_IDENTITY* identity; - PSecurityFunctionTable table; - SecPkgContext_Sizes ContextSizes; -}; - FREERDP_LOCAL int nla_authenticate(rdpNla* nla); FREERDP_LOCAL LPTSTR nla_make_spn(const char* ServiceClass, const char* hostname); @@ -100,6 +54,13 @@ FREERDP_LOCAL LPTSTR nla_make_spn(const char* ServiceClass, FREERDP_LOCAL int nla_client_begin(rdpNla* nla); FREERDP_LOCAL int nla_recv_pdu(rdpNla* nla, wStream* s); +FREERDP_LOCAL SEC_WINNT_AUTH_IDENTITY* nla_get_identity(rdpNla* nla); + +FREERDP_LOCAL NLA_STATE nla_get_state(rdpNla* nla); +FREERDP_LOCAL BOOL nla_set_state(rdpNla* nla, NLA_STATE state); + +FREERDP_LOCAL BOOL nla_set_service_principal(rdpNla* nla, LPSTR principal); + FREERDP_LOCAL rdpNla* nla_new(freerdp* instance, rdpTransport* transport, rdpSettings* settings); FREERDP_LOCAL void nla_free(rdpNla* nla); diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index 07492ac..f199fdf 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -1388,7 +1388,7 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra) switch (rdp->state) { case CONNECTION_STATE_NLA: - if (rdp->nla->state < NLA_STATE_AUTH_INFO) + if (nla_get_state(rdp->nla) < NLA_STATE_AUTH_INFO) { if (nla_recv_pdu(rdp->nla, s) < 1) { @@ -1396,7 +1396,7 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra) return -1; } } - else if (rdp->nla->state == NLA_STATE_POST_NEGO) + else if (nla_get_state(rdp->nla) == NLA_STATE_POST_NEGO) { nego_recv(rdp->transport, s, (void*) rdp->nego); @@ -1406,10 +1406,11 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra) return -1; } - rdp->nla->state = NLA_STATE_FINAL; + if (!nla_set_state(rdp->nla, NLA_STATE_FINAL)) + return -1; } - if (rdp->nla->state == NLA_STATE_AUTH_INFO) + if (nla_get_state(rdp->nla) == NLA_STATE_AUTH_INFO) { transport_set_nla_mode(rdp->transport, FALSE); @@ -1422,15 +1423,18 @@ int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra) return -1; nego_send_negotiation_request(rdp->nego); - rdp->nla->state = NLA_STATE_POST_NEGO; + + if (!nla_set_state(rdp->nla, NLA_STATE_POST_NEGO)) + return -1; } else { - rdp->nla->state = NLA_STATE_FINAL; + if (!nla_set_state(rdp->nla, NLA_STATE_FINAL)) + return -1; } } - if (rdp->nla->state == NLA_STATE_FINAL) + if (nla_get_state(rdp->nla) == NLA_STATE_FINAL) { nla_free(rdp->nla); rdp->nla = NULL; diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 14c6fe2..ee64eb9 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -334,10 +334,8 @@ BOOL transport_connect_nla(rdpTransport* transport) if (settings->AuthenticationServiceClass) { - rdp->nla->ServicePrincipalName = - nla_make_spn(settings->AuthenticationServiceClass, settings->ServerHostname); - - if (!rdp->nla->ServicePrincipalName) + if (!nla_set_service_principal(rdp->nla, nla_make_spn(settings->AuthenticationServiceClass, + settings->ServerHostname))) return FALSE; } -- 2.7.4