diff --git a/libfreerdp/core/gateway/ntlm.c b/libfreerdp/core/gateway/ntlm.c index eec770b5d..c9795b648 100644 --- a/libfreerdp/core/gateway/ntlm.c +++ b/libfreerdp/core/gateway/ntlm.c @@ -234,21 +234,25 @@ BOOL ntlm_authenticate(rdpNtlm* ntlm) WLog_VRB(TAG, "InitializeSecurityContext status %s [%08X]", GetSecurityStatusString(status), status); + if ((status == SEC_I_COMPLETE_AND_CONTINUE) || (status == SEC_I_COMPLETE_NEEDED) || (status == SEC_E_OK)) { - if (ntlm->table->CompleteAuthToken) + if ((status != SEC_E_OK) && ntlm->table->CompleteAuthToken) { SECURITY_STATUS cStatus; + cStatus = ntlm->table->CompleteAuthToken(&ntlm->context, &ntlm->outputBufferDesc); + if (cStatus != SEC_E_OK) { WLog_WARN(TAG, "CompleteAuthToken status %s [%08X]", - GetSecurityStatusString(cStatus), cStatus); + GetSecurityStatusString(cStatus), cStatus); return FALSE; } } status = ntlm->table->QueryContextAttributes(&ntlm->context, SECPKG_ATTR_SIZES, &ntlm->ContextSizes); + if (status != SEC_E_OK) { WLog_ERR(TAG, "QueryContextAttributes SECPKG_ATTR_SIZES failure %s [%08X]", diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index 3259bcce7..82ecea9a9 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -637,17 +637,23 @@ BOOL tls_prepare(rdpTls* tls, BIO* underlying, const SSL_METHOD* method, int opt int tls_do_handshake(rdpTls* tls, BOOL clientMode) { CryptoCert cert; - int verify_status, status; + int verify_status; do { #ifdef HAVE_POLL_H - struct pollfd pollfds; -#else - struct timeval tv; - fd_set rset; -#endif int fd; + int status; + struct pollfd pollfds; +#elif !defined(_WIN32) + int fd; + int status; + fd_set rset; + struct timeval tv; +#else + HANDLE event; + DWORD status; +#endif status = BIO_do_handshake(tls->bio); @@ -657,6 +663,7 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode) if (!BIO_should_retry(tls->bio)) return -1; +#ifndef _WIN32 /* we select() only for read even if we should test both read and write * depending of what have blocked */ fd = BIO_get_fd(tls->bio, NULL); @@ -666,6 +673,15 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode) WLog_ERR(TAG, "unable to retrieve BIO fd"); return -1; } +#else + BIO_get_event(tls->bio, &event); + + if (!event) + { + WLog_ERR(TAG, "unable to retrieve BIO event"); + return -1; + } +#endif #ifdef HAVE_POLL_H pollfds.fd = fd; @@ -677,23 +693,35 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode) status = poll(&pollfds, 1, 10 * 1000); } while ((status < 0) && (errno == EINTR)); -#else +#elif !defined(_WIN32) FD_ZERO(&rset); FD_SET(fd, &rset); tv.tv_sec = 0; tv.tv_usec = 10 * 1000; /* 10ms */ status = _select(fd + 1, &rset, NULL, NULL, &tv); +#else + status = WaitForSingleObject(event, 10); #endif + +#ifndef _WIN32 if (status < 0) { WLog_ERR(TAG, "error during select()"); return -1; } +#else + if ((status != WAIT_OBJECT_0) && (status != WAIT_TIMEOUT)) + { + WLog_ERR(TAG, "error during WaitForSingleObject(): 0x%04X", status); + return -1; + } +#endif } while (TRUE); cert = tls_get_certificate(tls, clientMode); + if (!cert) { WLog_ERR(TAG, "tls_get_certificate failed to return the server certificate."); @@ -701,6 +729,7 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode) } tls->Bindings = tls_get_channel_bindings(cert->px509); + if (!tls->Bindings) { WLog_ERR(TAG, "unable to retrieve bindings"); @@ -715,10 +744,9 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode) goto out; } - /* Note: server-side NLA needs public keys (keys from us, the server) but no - * certificate verify - */ + /* server-side NLA needs public keys (keys from us, the server) but no certificate verify */ verify_status = 1; + if (clientMode) { verify_status = tls_verify_certificate(tls, cert, tls->hostname, tls->port); diff --git a/winpr/libwinpr/sspi/sspi.c b/winpr/libwinpr/sspi/sspi.c index bcc8fd841..628a07430 100644 --- a/winpr/libwinpr/sspi/sspi.c +++ b/winpr/libwinpr/sspi/sspi.c @@ -319,6 +319,30 @@ const char* GetSecurityStatusString(SECURITY_STATUS status) return "SEC_E_UNKNOWN"; } +BOOL IsSecurityStatusError(SECURITY_STATUS status) +{ + BOOL error = TRUE; + + switch (status) + { + case SEC_E_OK: + case SEC_I_CONTINUE_NEEDED: + case SEC_I_COMPLETE_NEEDED: + case SEC_I_COMPLETE_AND_CONTINUE: + case SEC_I_LOCAL_LOGON: + case SEC_I_CONTEXT_EXPIRED: + case SEC_I_INCOMPLETE_CREDENTIALS: + case SEC_I_RENEGOTIATE: + case SEC_I_NO_LSA_CONTEXT: + case SEC_I_SIGNATURE_NEEDED: + case SEC_I_NO_RENEGOTIATION: + error = FALSE; + break; + } + + return error; +} + SecurityFunctionTableW* SEC_ENTRY InitSecurityInterfaceExW(DWORD flags) { if (!g_Initialized) diff --git a/winpr/libwinpr/sspi/sspi.h b/winpr/libwinpr/sspi/sspi.h index dd34aafaf..430efd1d2 100644 --- a/winpr/libwinpr/sspi/sspi.h +++ b/winpr/libwinpr/sspi/sspi.h @@ -83,6 +83,8 @@ enum SecurityFunctionTableIndex SetContextAttributesIndex = 28 }; +BOOL IsSecurityStatusError(SECURITY_STATUS status); + #include "sspi_winpr.h" #endif /* WINPR_SSPI_PRIVATE_H */ diff --git a/winpr/libwinpr/sspi/sspi_winpr.c b/winpr/libwinpr/sspi/sspi_winpr.c index cc9dca62d..cde1196dc 100644 --- a/winpr/libwinpr/sspi/sspi_winpr.c +++ b/winpr/libwinpr/sspi/sspi_winpr.c @@ -804,11 +804,12 @@ SECURITY_STATUS SEC_ENTRY winpr_AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipa status = table->AcquireCredentialsHandleW(pszPrincipal, pszPackage, fCredentialUse, pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "AcquireCredentialsHandleW status %s [%08X]", GetSecurityStatusString(status), status); } + return status; } @@ -828,7 +829,7 @@ SECURITY_STATUS SEC_ENTRY winpr_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal status = table->AcquireCredentialsHandleA(pszPrincipal, pszPackage, fCredentialUse, pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential, ptsExpiry); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "AcquireCredentialsHandleA status %s [%08X]", GetSecurityStatusString(status), status); @@ -858,7 +859,7 @@ SECURITY_STATUS SEC_ENTRY winpr_ExportSecurityContext(PCtxtHandle phContext, ULO status = table->ExportSecurityContext(phContext, fFlags, pPackedContext, pToken); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "ExportSecurityContext status %s [%08X]", GetSecurityStatusString(status), status); @@ -888,11 +889,12 @@ SECURITY_STATUS SEC_ENTRY winpr_FreeCredentialsHandle(PCredHandle phCredential) status = table->FreeCredentialsHandle(phCredential); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "FreeCredentialsHandle status %s [%08X]", GetSecurityStatusString(status), status); } + return status; } @@ -917,7 +919,7 @@ SECURITY_STATUS SEC_ENTRY winpr_ImportSecurityContextW(SEC_WCHAR* pszPackage, PS status = table->ImportSecurityContextW(pszPackage, pPackedContext, pToken, phContext); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "ImportSecurityContextW status %s [%08X]", GetSecurityStatusString(status), status); @@ -947,7 +949,7 @@ SECURITY_STATUS SEC_ENTRY winpr_ImportSecurityContextA(SEC_CHAR* pszPackage, PSe status = table->ImportSecurityContextA(pszPackage, pPackedContext, pToken, phContext); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "ImportSecurityContextA status %s [%08X]", GetSecurityStatusString(status), status); @@ -977,7 +979,7 @@ SECURITY_STATUS SEC_ENTRY winpr_QueryCredentialsAttributesW(PCredHandle phCreden status = table->QueryCredentialsAttributesW(phCredential, ulAttribute, pBuffer); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "QueryCredentialsAttributesW status %s [%08X]", GetSecurityStatusString(status), status); @@ -1007,7 +1009,7 @@ SECURITY_STATUS SEC_ENTRY winpr_QueryCredentialsAttributesA(PCredHandle phCreden status = table->QueryCredentialsAttributesA(phCredential, ulAttribute, pBuffer); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "QueryCredentialsAttributesA status %s [%08X]", GetSecurityStatusString(status), status); @@ -1042,7 +1044,7 @@ SECURITY_STATUS SEC_ENTRY winpr_AcceptSecurityContext(PCredHandle phCredential, status = table->AcceptSecurityContext(phCredential, phContext, pInput, fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr, ptsTimeStamp); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "AcceptSecurityContext status %s [%08X]", GetSecurityStatusString(status), status); @@ -1072,7 +1074,7 @@ SECURITY_STATUS SEC_ENTRY winpr_ApplyControlToken(PCtxtHandle phContext, PSecBuf status = table->ApplyControlToken(phContext, pInput); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "ApplyControlToken status %s [%08X]", GetSecurityStatusString(status), status); @@ -1102,7 +1104,7 @@ SECURITY_STATUS SEC_ENTRY winpr_CompleteAuthToken(PCtxtHandle phContext, PSecBuf status = table->CompleteAuthToken(phContext, pToken); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "CompleteAuthToken status %s [%08X]", GetSecurityStatusString(status), status); @@ -1132,7 +1134,7 @@ SECURITY_STATUS SEC_ENTRY winpr_DeleteSecurityContext(PCtxtHandle phContext) status = table->DeleteSecurityContext(phContext); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "DeleteSecurityContext status %s [%08X]", GetSecurityStatusString(status), status); @@ -1172,7 +1174,7 @@ SECURITY_STATUS SEC_ENTRY winpr_ImpersonateSecurityContext(PCtxtHandle phContext status = table->ImpersonateSecurityContext(phContext); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "ImpersonateSecurityContext status %s [%08X]", GetSecurityStatusString(status), status); @@ -1207,7 +1209,7 @@ SECURITY_STATUS SEC_ENTRY winpr_InitializeSecurityContextW(PCredHandle phCredent pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput, Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "InitializeSecurityContextW status %s [%08X]", GetSecurityStatusString(status), status); @@ -1242,7 +1244,7 @@ SECURITY_STATUS SEC_ENTRY winpr_InitializeSecurityContextA(PCredHandle phCredent pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput, Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "InitializeSecurityContextA status %s [%08X]", GetSecurityStatusString(status), status); @@ -1272,7 +1274,7 @@ SECURITY_STATUS SEC_ENTRY winpr_QueryContextAttributesW(PCtxtHandle phContext, U status = table->QueryContextAttributesW(phContext, ulAttribute, pBuffer); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "QueryContextAttributesW status %s [%08X]", GetSecurityStatusString(status), status); @@ -1302,7 +1304,7 @@ SECURITY_STATUS SEC_ENTRY winpr_QueryContextAttributesA(PCtxtHandle phContext, U status = table->QueryContextAttributesA(phContext, ulAttribute, pBuffer); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "QueryContextAttributesA status %s [%08X]", GetSecurityStatusString(status), status); @@ -1332,7 +1334,7 @@ SECURITY_STATUS SEC_ENTRY winpr_QuerySecurityContextToken(PCtxtHandle phContext, status = table->QuerySecurityContextToken(phContext, phToken); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "QuerySecurityContextToken status %s [%08X]", GetSecurityStatusString(status), status); @@ -1362,7 +1364,7 @@ SECURITY_STATUS SEC_ENTRY winpr_SetContextAttributesW(PCtxtHandle phContext, ULO status = table->SetContextAttributesW(phContext, ulAttribute, pBuffer, cbBuffer); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "SetContextAttributesW status %s [%08X]", GetSecurityStatusString(status), status); @@ -1392,7 +1394,7 @@ SECURITY_STATUS SEC_ENTRY winpr_SetContextAttributesA(PCtxtHandle phContext, ULO status = table->SetContextAttributesA(phContext, ulAttribute, pBuffer, cbBuffer); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "SetContextAttributesA status %s [%08X]", GetSecurityStatusString(status), status); @@ -1422,7 +1424,7 @@ SECURITY_STATUS SEC_ENTRY winpr_RevertSecurityContext(PCtxtHandle phContext) status = table->RevertSecurityContext(phContext); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "RevertSecurityContext status %s [%08X]", GetSecurityStatusString(status), status); @@ -1454,7 +1456,7 @@ SECURITY_STATUS SEC_ENTRY winpr_DecryptMessage(PCtxtHandle phContext, PSecBuffer status = table->DecryptMessage(phContext, pMessage, MessageSeqNo, pfQOP); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "DecryptMessage status %s [%08X]", GetSecurityStatusString(status), status); @@ -1514,7 +1516,7 @@ SECURITY_STATUS SEC_ENTRY winpr_MakeSignature(PCtxtHandle phContext, ULONG fQOP, status = table->MakeSignature(phContext, fQOP, pMessage, MessageSeqNo); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "MakeSignature status %s [%08X]", GetSecurityStatusString(status), status); @@ -1544,7 +1546,7 @@ SECURITY_STATUS SEC_ENTRY winpr_VerifySignature(PCtxtHandle phContext, PSecBuffe status = table->VerifySignature(phContext, pMessage, MessageSeqNo, pfQOP); - if (status != SEC_E_OK) + if (IsSecurityStatusError(status)) { WLog_WARN(TAG, "VerifySignature status %s [%08X]", GetSecurityStatusString(status), status); diff --git a/winpr/libwinpr/synch/wait.c b/winpr/libwinpr/synch/wait.c index 7891e85f4..3192b431e 100644 --- a/winpr/libwinpr/synch/wait.c +++ b/winpr/libwinpr/synch/wait.c @@ -479,9 +479,9 @@ DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE *lpHandles, BOOL bWaitAl signal_set = pollfds[index].revents & pollfds[index].events; #else if (Object->Mode & WINPR_FD_READ) - signal_set = FD_ISSET(fd, &rfds); + signal_set = FD_ISSET(fd, &rfds) ? 1 : 0; if (Object->Mode & WINPR_FD_WRITE) - signal_set = FD_ISSET(fd, &wfds); + signal_set |= FD_ISSET(fd, &wfds) ? 1 : 0; #endif if (signal_set) {