libfreerdp-core: prepare client-side NLA for event-driven structure
This commit is contained in:
parent
ab5fdcc3f1
commit
eddfee56a3
@ -263,6 +263,8 @@ BOOL rdp_client_connect(rdpRdp* rdp)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rdp_client_transition_to_state(rdp, CONNECTION_STATE_NEGO);
|
||||
|
||||
if (!nego_connect(rdp->nego))
|
||||
{
|
||||
if (!freerdp_get_last_error(rdp->context))
|
||||
@ -281,10 +283,13 @@ BOOL rdp_client_connect(rdpRdp* rdp)
|
||||
settings->AutoLogonEnabled = TRUE;
|
||||
}
|
||||
|
||||
rdp_set_blocking_mode(rdp, FALSE);
|
||||
/* everything beyond this point is event-driven and non blocking */
|
||||
|
||||
rdp_client_transition_to_state(rdp, CONNECTION_STATE_NEGO);
|
||||
rdp->finalize_sc_pdus = 0;
|
||||
rdp->transport->ReceiveCallback = rdp_recv_callback;
|
||||
rdp->transport->ReceiveExtra = rdp;
|
||||
transport_set_blocking_mode(rdp->transport, FALSE);
|
||||
|
||||
rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CONNECT);
|
||||
|
||||
if (!mcs_send_connect_initial(rdp->mcs))
|
||||
{
|
||||
@ -648,38 +653,6 @@ end2:
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL rdp_client_connect_mcs_connect_response(rdpRdp* rdp, wStream* s)
|
||||
{
|
||||
if (!mcs_recv_connect_response(rdp->mcs, s))
|
||||
{
|
||||
WLog_ERR(TAG, "rdp_client_connect_mcs_connect_response: mcs_recv_connect_response failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!mcs_send_erect_domain_request(rdp->mcs))
|
||||
return FALSE;
|
||||
|
||||
if (!mcs_send_attach_user_request(rdp->mcs))
|
||||
return FALSE;
|
||||
|
||||
rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_ATTACH_USER);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL rdp_client_connect_mcs_attach_user_confirm(rdpRdp* rdp, wStream* s)
|
||||
{
|
||||
if (!mcs_recv_attach_user_confirm(rdp->mcs, s))
|
||||
return FALSE;
|
||||
|
||||
if (!mcs_send_channel_join_request(rdp->mcs, rdp->mcs->userId))
|
||||
return FALSE;
|
||||
|
||||
rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, wStream* s)
|
||||
{
|
||||
UINT32 i;
|
||||
|
@ -51,8 +51,6 @@ BOOL rdp_client_connect(rdpRdp* rdp);
|
||||
BOOL rdp_client_disconnect(rdpRdp* rdp);
|
||||
BOOL rdp_client_reconnect(rdpRdp* rdp);
|
||||
BOOL rdp_client_redirect(rdpRdp* rdp);
|
||||
BOOL rdp_client_connect_mcs_connect_response(rdpRdp* rdp, wStream* s);
|
||||
BOOL rdp_client_connect_mcs_attach_user_confirm(rdpRdp* rdp, wStream* s);
|
||||
BOOL rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, wStream* s);
|
||||
BOOL rdp_client_connect_auto_detect(rdpRdp* rdp, wStream* s);
|
||||
int rdp_client_connect_license(rdpRdp* rdp, wStream* s);
|
||||
|
@ -1033,8 +1033,6 @@ void nego_init(rdpNego* nego)
|
||||
{
|
||||
nego->state = NEGO_STATE_INITIAL;
|
||||
nego->RequestedProtocols = PROTOCOL_RDP;
|
||||
nego->transport->ReceiveCallback = nego_recv;
|
||||
nego->transport->ReceiveExtra = (void*) nego;
|
||||
nego->CookieMaxLength = DEFAULT_COOKIE_MAX_LENGTH;
|
||||
nego->sendNegoData = FALSE;
|
||||
nego->flags = 0;
|
||||
@ -1049,11 +1047,12 @@ void nego_init(rdpNego* nego)
|
||||
rdpNego* nego_new(rdpTransport* transport)
|
||||
{
|
||||
rdpNego* nego = (rdpNego*) calloc(1, sizeof(rdpNego));
|
||||
|
||||
if (!nego)
|
||||
return NULL;
|
||||
|
||||
|
||||
nego->transport = transport;
|
||||
|
||||
nego_init(nego);
|
||||
|
||||
return nego;
|
||||
|
@ -105,7 +105,7 @@ SECURITY_STATUS nla_decrypt_ts_credentials(rdpNla* nla);
|
||||
* @param credssp
|
||||
*/
|
||||
|
||||
int nla_ntlm_client_init(rdpNla* nla)
|
||||
int nla_client_init(rdpNla* nla)
|
||||
{
|
||||
char* spn;
|
||||
int length;
|
||||
@ -117,6 +117,8 @@ int nla_ntlm_client_init(rdpNla* nla)
|
||||
settings = nla->settings;
|
||||
instance = (freerdp*) settings->instance;
|
||||
|
||||
nla->state = NLA_STATE_INITIAL;
|
||||
|
||||
if (settings->RestrictedAdminModeRequired)
|
||||
settings->DisableCredentialsDelegation = TRUE;
|
||||
|
||||
@ -251,10 +253,10 @@ int nla_ntlm_client_init(rdpNla* nla)
|
||||
|
||||
int nla_client_authenticate(rdpNla* nla)
|
||||
{
|
||||
if (nla_ntlm_client_init(nla) < 1)
|
||||
if (nla_client_init(nla) < 1)
|
||||
return -1;
|
||||
|
||||
while (TRUE)
|
||||
if (nla->state == NLA_STATE_INITIAL)
|
||||
{
|
||||
nla->outputBufferDesc.ulVersion = SECBUFFER_VERSION;
|
||||
nla->outputBufferDesc.cBuffers = 1;
|
||||
@ -267,17 +269,69 @@ int nla_client_authenticate(rdpNla* nla)
|
||||
return -1;
|
||||
|
||||
nla->status = nla->table->InitializeSecurityContext(&nla->credentials,
|
||||
(nla->haveContext) ? &nla->context : NULL,
|
||||
nla->ServicePrincipalName, nla->fContextReq, 0,
|
||||
SECURITY_NATIVE_DREP, (nla->haveInputBuffer) ? &nla->inputBufferDesc : NULL,
|
||||
0, &nla->context, &nla->outputBufferDesc, &nla->pfContextAttr, &nla->expiration);
|
||||
NULL, nla->ServicePrincipalName, nla->fContextReq, 0,
|
||||
SECURITY_NATIVE_DREP, NULL, 0, &nla->context,
|
||||
&nla->outputBufferDesc, &nla->pfContextAttr, &nla->expiration);
|
||||
|
||||
if (nla->haveInputBuffer && (nla->inputBuffer.pvBuffer))
|
||||
if ((nla->status == SEC_I_COMPLETE_AND_CONTINUE) || (nla->status == SEC_I_COMPLETE_NEEDED))
|
||||
{
|
||||
free(nla->inputBuffer.pvBuffer);
|
||||
nla->inputBuffer.pvBuffer = NULL;
|
||||
if (nla->table->CompleteAuthToken)
|
||||
nla->table->CompleteAuthToken(&nla->context, &nla->outputBufferDesc);
|
||||
|
||||
if (nla->status == SEC_I_COMPLETE_NEEDED)
|
||||
nla->status = SEC_E_OK;
|
||||
else if (nla->status == SEC_I_COMPLETE_AND_CONTINUE)
|
||||
nla->status = SEC_I_CONTINUE_NEEDED;
|
||||
}
|
||||
|
||||
if (nla->status != SEC_I_CONTINUE_NEEDED)
|
||||
return -1;
|
||||
|
||||
if (nla->outputBuffer.cbBuffer < 1)
|
||||
return -1;
|
||||
|
||||
nla->negoToken.pvBuffer = nla->outputBuffer.pvBuffer;
|
||||
nla->negoToken.cbBuffer = nla->outputBuffer.cbBuffer;
|
||||
|
||||
WLog_DBG(TAG, "Sending Authentication Token");
|
||||
winpr_HexDump(TAG, WLOG_DEBUG, nla->negoToken.pvBuffer, nla->negoToken.cbBuffer);
|
||||
|
||||
nla_send(nla);
|
||||
nla_buffer_free(nla);
|
||||
|
||||
nla->state = NLA_STATE_NEGO_TOKEN;
|
||||
}
|
||||
|
||||
if (nla_recv(nla) < 0)
|
||||
return -1;
|
||||
|
||||
if (nla->state == NLA_STATE_NEGO_TOKEN)
|
||||
{
|
||||
nla->inputBufferDesc.ulVersion = SECBUFFER_VERSION;
|
||||
nla->inputBufferDesc.cBuffers = 1;
|
||||
nla->inputBufferDesc.pBuffers = &nla->inputBuffer;
|
||||
nla->inputBuffer.BufferType = SECBUFFER_TOKEN;
|
||||
nla->inputBuffer.pvBuffer = nla->negoToken.pvBuffer;
|
||||
nla->inputBuffer.cbBuffer = nla->negoToken.cbBuffer;
|
||||
|
||||
nla->outputBufferDesc.ulVersion = SECBUFFER_VERSION;
|
||||
nla->outputBufferDesc.cBuffers = 1;
|
||||
nla->outputBufferDesc.pBuffers = &nla->outputBuffer;
|
||||
nla->outputBuffer.BufferType = SECBUFFER_TOKEN;
|
||||
nla->outputBuffer.cbBuffer = nla->cbMaxToken;
|
||||
nla->outputBuffer.pvBuffer = malloc(nla->outputBuffer.cbBuffer);
|
||||
|
||||
if (!nla->outputBuffer.pvBuffer)
|
||||
return -1;
|
||||
|
||||
nla->status = nla->table->InitializeSecurityContext(&nla->credentials,
|
||||
&nla->context, nla->ServicePrincipalName, nla->fContextReq, 0,
|
||||
SECURITY_NATIVE_DREP, &nla->inputBufferDesc,
|
||||
0, &nla->context, &nla->outputBufferDesc, &nla->pfContextAttr, &nla->expiration);
|
||||
|
||||
free(nla->inputBuffer.pvBuffer);
|
||||
nla->inputBuffer.pvBuffer = NULL;
|
||||
|
||||
if ((nla->status == SEC_I_COMPLETE_AND_CONTINUE) || (nla->status == SEC_I_COMPLETE_NEEDED))
|
||||
{
|
||||
if (nla->table->CompleteAuthToken)
|
||||
@ -302,71 +356,55 @@ int nla_client_authenticate(rdpNla* nla)
|
||||
nla_encrypt_public_key_echo(nla);
|
||||
}
|
||||
|
||||
/* send authentication token to server */
|
||||
|
||||
if (nla->outputBuffer.cbBuffer > 0)
|
||||
{
|
||||
nla->negoToken.pvBuffer = nla->outputBuffer.pvBuffer;
|
||||
nla->negoToken.cbBuffer = nla->outputBuffer.cbBuffer;
|
||||
|
||||
WLog_DBG(TAG, "Sending Authentication Token");
|
||||
winpr_HexDump(TAG, WLOG_DEBUG, nla->negoToken.pvBuffer, nla->negoToken.cbBuffer);
|
||||
|
||||
nla_send(nla);
|
||||
nla_buffer_free(nla);
|
||||
}
|
||||
|
||||
if (nla->status != SEC_I_CONTINUE_NEEDED)
|
||||
break;
|
||||
|
||||
/* receive server response and place in input buffer */
|
||||
nla->inputBufferDesc.ulVersion = SECBUFFER_VERSION;
|
||||
nla->inputBufferDesc.cBuffers = 1;
|
||||
nla->inputBufferDesc.pBuffers = &nla->inputBuffer;
|
||||
nla->inputBuffer.BufferType = SECBUFFER_TOKEN;
|
||||
|
||||
if (nla_recv(nla) < 0)
|
||||
if (nla->outputBuffer.cbBuffer < 1)
|
||||
return -1;
|
||||
|
||||
WLog_DBG(TAG, "Receiving Authentication Token (%d)", (int) nla->negoToken.cbBuffer);
|
||||
nla->negoToken.pvBuffer = nla->outputBuffer.pvBuffer;
|
||||
nla->negoToken.cbBuffer = nla->outputBuffer.cbBuffer;
|
||||
|
||||
WLog_DBG(TAG, "Sending Authentication Token");
|
||||
winpr_HexDump(TAG, WLOG_DEBUG, nla->negoToken.pvBuffer, nla->negoToken.cbBuffer);
|
||||
|
||||
nla->inputBuffer.pvBuffer = nla->negoToken.pvBuffer;
|
||||
nla->inputBuffer.cbBuffer = nla->negoToken.cbBuffer;
|
||||
nla->haveInputBuffer = TRUE;
|
||||
nla->haveContext = TRUE;
|
||||
nla_send(nla);
|
||||
nla_buffer_free(nla);
|
||||
|
||||
nla->state = NLA_STATE_PUB_KEY_AUTH;
|
||||
}
|
||||
|
||||
/* Encrypted Public Key +1 */
|
||||
if (nla_recv(nla) < 0)
|
||||
return -1;
|
||||
|
||||
/* Verify Server Public Key Echo */
|
||||
nla->status = nla_decrypt_public_key_echo(nla);
|
||||
nla_buffer_free(nla);
|
||||
|
||||
if (nla->status != SEC_E_OK)
|
||||
if (nla->state == NLA_STATE_PUB_KEY_AUTH)
|
||||
{
|
||||
WLog_ERR(TAG, "Could not verify public key echo!");
|
||||
return -1;
|
||||
/* Verify Server Public Key Echo */
|
||||
nla->status = nla_decrypt_public_key_echo(nla);
|
||||
nla_buffer_free(nla);
|
||||
|
||||
if (nla->status != SEC_E_OK)
|
||||
{
|
||||
WLog_ERR(TAG, "Could not verify public key echo!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Send encrypted credentials */
|
||||
nla->status = nla_encrypt_ts_credentials(nla);
|
||||
|
||||
if (nla->status != SEC_E_OK)
|
||||
{
|
||||
WLog_ERR(TAG, "nla_encrypt_ts_credentials status: 0x%08X", nla->status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nla_send(nla);
|
||||
nla_buffer_free(nla);
|
||||
|
||||
nla->state = NLA_STATE_AUTH_INFO;
|
||||
|
||||
/* Free resources */
|
||||
nla->table->FreeCredentialsHandle(&nla->credentials);
|
||||
nla->table->FreeContextBuffer(nla->pPackageInfo);
|
||||
}
|
||||
|
||||
/* Send encrypted credentials */
|
||||
nla->status = nla_encrypt_ts_credentials(nla);
|
||||
|
||||
if (nla->status != SEC_E_OK)
|
||||
{
|
||||
WLog_ERR(TAG, "nla_encrypt_ts_credentials status: 0x%08X", nla->status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
nla_send(nla);
|
||||
nla_buffer_free(nla);
|
||||
|
||||
/* Free resources */
|
||||
nla->table->FreeCredentialsHandle(&nla->credentials);
|
||||
nla->table->FreeContextBuffer(nla->pPackageInfo);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -375,7 +413,7 @@ int nla_client_authenticate(rdpNla* nla)
|
||||
* @param credssp
|
||||
*/
|
||||
|
||||
int nla_ntlm_server_init(rdpNla* nla)
|
||||
int nla_server_init(rdpNla* nla)
|
||||
{
|
||||
rdpTls* tls = nla->transport->tls;
|
||||
|
||||
@ -460,7 +498,7 @@ int nla_ntlm_server_init(rdpNla* nla)
|
||||
|
||||
int nla_server_authenticate(rdpNla* nla)
|
||||
{
|
||||
if (nla_ntlm_server_init(nla) < 1)
|
||||
if (nla_server_init(nla) < 1)
|
||||
return -1;
|
||||
|
||||
while (TRUE)
|
||||
@ -1072,30 +1110,11 @@ void nla_send(rdpNla* nla)
|
||||
Stream_Free(s, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive CredSSP message.
|
||||
* @param credssp
|
||||
* @return
|
||||
*/
|
||||
|
||||
int nla_recv(rdpNla* nla)
|
||||
int nla_recv_ts_request(rdpNla* nla, wStream* s)
|
||||
{
|
||||
wStream* s;
|
||||
int length;
|
||||
int status;
|
||||
UINT32 version;
|
||||
|
||||
s = Stream_New(NULL, 4096);
|
||||
|
||||
status = transport_read_pdu(nla->transport, s);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "nla_recv() error: %d", status);
|
||||
Stream_Free(s, TRUE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* TSRequest */
|
||||
if (!ber_read_sequence_tag(s, &length) ||
|
||||
!ber_read_contextual_tag(s, 0, &length, TRUE) ||
|
||||
@ -1153,6 +1172,28 @@ int nla_recv(rdpNla* nla)
|
||||
nla->pubKeyAuth.cbBuffer = length;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int nla_recv(rdpNla* nla)
|
||||
{
|
||||
wStream* s;
|
||||
int status;
|
||||
|
||||
s = Stream_New(NULL, 4096);
|
||||
|
||||
status = transport_read_pdu(nla->transport, s);
|
||||
|
||||
if (status < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "nla_recv() error: %d", status);
|
||||
Stream_Free(s, TRUE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (nla_recv_ts_request(nla, s) < 1)
|
||||
return -1;
|
||||
|
||||
Stream_Free(s, TRUE);
|
||||
return 1;
|
||||
}
|
||||
|
@ -35,9 +35,20 @@ typedef struct rdp_nla rdpNla;
|
||||
|
||||
#include "transport.h"
|
||||
|
||||
enum _NLA_STATE
|
||||
{
|
||||
NLA_STATE_INITIAL,
|
||||
NLA_STATE_NEGO_TOKEN,
|
||||
NLA_STATE_PUB_KEY_AUTH,
|
||||
NLA_STATE_AUTH_INFO,
|
||||
NLA_STATE_FINAL
|
||||
};
|
||||
typedef enum _NLA_STATE NLA_STATE;
|
||||
|
||||
struct rdp_nla
|
||||
{
|
||||
BOOL server;
|
||||
NLA_STATE state;
|
||||
int sendSeqNum;
|
||||
int recvSeqNum;
|
||||
freerdp* instance;
|
||||
|
@ -361,7 +361,7 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channelId)
|
||||
rdp_set_error_info(rdp, ERRINFO_RPC_INITIATED_DISCONNECT);
|
||||
}
|
||||
|
||||
WLog_ERR(TAG, "DisconnectProviderUltimatum: reason: %d", reason);
|
||||
WLog_ERR(TAG, "DisconnectProviderUltimatum: reason: %d", reason);
|
||||
rdp->disconnect = TRUE;
|
||||
|
||||
EventArgsInit(&e, "freerdp");
|
||||
@ -748,7 +748,7 @@ int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s)
|
||||
|
||||
if (Stream_GetRemainingLength(s) < (size_t) SrcSize)
|
||||
{
|
||||
WLog_ERR(TAG, "bulk_decompress: not enough bytes for compressedLength %d", compressedLength);
|
||||
WLog_ERR(TAG, "bulk_decompress: not enough bytes for compressedLength %d", compressedLength);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -763,7 +763,7 @@ int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s)
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG, "bulk_decompress() failed");
|
||||
WLog_ERR(TAG, "bulk_decompress() failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -970,13 +970,13 @@ BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags)
|
||||
|
||||
if (!security_fips_decrypt(Stream_Pointer(s), length, rdp))
|
||||
{
|
||||
WLog_ERR(TAG, "FATAL: cannot decrypt");
|
||||
WLog_ERR(TAG, "FATAL: cannot decrypt");
|
||||
return FALSE; /* TODO */
|
||||
}
|
||||
|
||||
if (!security_fips_check_signature(Stream_Pointer(s), length - pad, sig, rdp))
|
||||
{
|
||||
WLog_ERR(TAG, "FATAL: invalid packet signature");
|
||||
WLog_ERR(TAG, "FATAL: invalid packet signature");
|
||||
return FALSE; /* TODO */
|
||||
}
|
||||
|
||||
@ -1000,7 +1000,7 @@ BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags)
|
||||
|
||||
if (memcmp(wmac, cmac, sizeof(wmac)) != 0)
|
||||
{
|
||||
WLog_ERR(TAG, "WARNING: invalid packet signature");
|
||||
WLog_ERR(TAG, "WARNING: invalid packet signature");
|
||||
/*
|
||||
* Because Standard RDP Security is totally broken,
|
||||
* and cannot protect against MITM, don't treat signature
|
||||
@ -1032,7 +1032,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
|
||||
|
||||
if (!rdp_read_header(rdp, s, &length, &channelId))
|
||||
{
|
||||
WLog_ERR(TAG, "Incorrect RDP header.");
|
||||
WLog_ERR(TAG, "Incorrect RDP header.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1053,7 +1053,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
|
||||
{
|
||||
if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
|
||||
{
|
||||
WLog_ERR(TAG, "rdp_decrypt failed");
|
||||
WLog_ERR(TAG, "rdp_decrypt failed");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1088,7 +1088,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
|
||||
case PDU_TYPE_DATA:
|
||||
if (rdp_recv_data_pdu(rdp, s) < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "rdp_recv_data_pdu failed");
|
||||
WLog_ERR(TAG, "rdp_recv_data_pdu failed");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
@ -1108,7 +1108,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "incorrect PDU type: 0x%04X", pduType);
|
||||
WLog_ERR(TAG, "incorrect PDU type: 0x%04X", pduType);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1140,7 +1140,7 @@ static int rdp_recv_fastpath_pdu(rdpRdp* rdp, wStream* s)
|
||||
|
||||
if ((length == 0) || (length > Stream_GetRemainingLength(s)))
|
||||
{
|
||||
WLog_ERR(TAG, "incorrect FastPath PDU header length %d", length);
|
||||
WLog_ERR(TAG, "incorrect FastPath PDU header length %d", length);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1168,7 +1168,7 @@ static int rdp_recv_pdu(rdpRdp* rdp, wStream* s)
|
||||
return rdp_recv_fastpath_pdu(rdp, s);
|
||||
}
|
||||
|
||||
static int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
{
|
||||
int status = 0;
|
||||
rdpRdp* rdp = (rdpRdp*) extra;
|
||||
@ -1179,8 +1179,7 @@ static int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
* enters the active state, an auto-detect PDU can be received
|
||||
* on the MCS message channel.
|
||||
*/
|
||||
if ((rdp->state > CONNECTION_STATE_MCS_CHANNEL_JOIN) &&
|
||||
(rdp->state < CONNECTION_STATE_ACTIVE))
|
||||
if ((rdp->state > CONNECTION_STATE_MCS_CHANNEL_JOIN) && (rdp->state < CONNECTION_STATE_ACTIVE))
|
||||
{
|
||||
if (rdp_client_connect_auto_detect(rdp, s))
|
||||
return 0;
|
||||
@ -1188,14 +1187,42 @@ static int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
|
||||
switch (rdp->state)
|
||||
{
|
||||
case CONNECTION_STATE_NEGO:
|
||||
if (!rdp_client_connect_mcs_connect_response(rdp, s))
|
||||
status = -1;
|
||||
case CONNECTION_STATE_MCS_CONNECT:
|
||||
if (!mcs_recv_connect_response(rdp->mcs, s))
|
||||
{
|
||||
WLog_ERR(TAG, "mcs_recv_connect_response failure");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!mcs_send_erect_domain_request(rdp->mcs))
|
||||
{
|
||||
WLog_ERR(TAG, "mcs_send_erect_domain_request failure");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!mcs_send_attach_user_request(rdp->mcs))
|
||||
{
|
||||
WLog_ERR(TAG, "mcs_send_attach_user_request failure");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_ATTACH_USER);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_MCS_ATTACH_USER:
|
||||
if (!rdp_client_connect_mcs_attach_user_confirm(rdp, s))
|
||||
status = -1;
|
||||
if (!mcs_recv_attach_user_confirm(rdp->mcs, s))
|
||||
{
|
||||
WLog_ERR(TAG, "mcs_recv_attach_user_confirm failure");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!mcs_send_channel_join_request(rdp->mcs, rdp->mcs->userId))
|
||||
{
|
||||
WLog_ERR(TAG, "mcs_send_channel_join_request failure");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN);
|
||||
break;
|
||||
|
||||
case CONNECTION_STATE_MCS_CHANNEL_JOIN:
|
||||
@ -1226,7 +1253,7 @@ static int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra)
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "Invalid state %d", rdp->state);
|
||||
WLog_ERR(TAG, "Invalid state %d", rdp->state);
|
||||
status = -1;
|
||||
break;
|
||||
}
|
||||
@ -1256,18 +1283,6 @@ BOOL rdp_send_error_info(rdpRdp* rdp)
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set non-blocking mode information.
|
||||
* @param rdp RDP module
|
||||
* @param blocking blocking mode
|
||||
*/
|
||||
void rdp_set_blocking_mode(rdpRdp* rdp, BOOL blocking)
|
||||
{
|
||||
rdp->transport->ReceiveCallback = rdp_recv_callback;
|
||||
rdp->transport->ReceiveExtra = rdp;
|
||||
transport_set_blocking_mode(rdp->transport, blocking);
|
||||
}
|
||||
|
||||
int rdp_check_fds(rdpRdp* rdp)
|
||||
{
|
||||
int status;
|
||||
|
@ -213,7 +213,8 @@ int rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, wStream* s);
|
||||
|
||||
void rdp_read_flow_control_pdu(wStream* s, UINT16* type);
|
||||
|
||||
void rdp_set_blocking_mode(rdpRdp* rdp, BOOL blocking);
|
||||
int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra);
|
||||
|
||||
int rdp_check_fds(rdpRdp* rdp);
|
||||
|
||||
rdpRdp* rdp_new(rdpContext* context);
|
||||
|
@ -435,7 +435,7 @@ int transport_read_pdu(rdpTransport* transport, wStream* s)
|
||||
/* Make sure there is enough space for the longest header within the stream */
|
||||
Stream_EnsureCapacity(s, 4);
|
||||
|
||||
/* Make sure at least two bytes are read for futher processing */
|
||||
/* Make sure at least two bytes are read for further processing */
|
||||
if (position < 2 && (status = transport_read_layer_bytes(transport, s, 2 - position)) != 1)
|
||||
{
|
||||
/* No data available at the moment */
|
||||
|
Loading…
Reference in New Issue
Block a user