From 12f0afd1e034d39c938270d97af7c947ee81520f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 27 Nov 2012 18:34:00 -0500 Subject: [PATCH] libfreerdp-core: fix TSG socket blocking mode --- libfreerdp/core/rdp.c | 3 ++ libfreerdp/core/rpc.c | 1 + libfreerdp/core/rts.c | 7 ++++- libfreerdp/core/transport.c | 18 +++++++++-- libfreerdp/core/tsg.c | 1 + libfreerdp/crypto/tls.c | 63 ++++++++++++++++++++++++------------- 6 files changed, 68 insertions(+), 25 deletions(-) diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index 4798d8b0a..64008ba28 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -678,10 +678,12 @@ BOOL rdp_decrypt(rdpRdp* rdp, STREAM* s, int length, UINT16 securityFlags) stream_read(s, wmac, sizeof(wmac)); length -= sizeof(wmac); security_decrypt(s->p, length, rdp); + if (securityFlags & SEC_SECURE_CHECKSUM) security_salted_mac_signature(rdp, s->p, length, FALSE, cmac); else security_mac_signature(rdp, s->p, length, cmac); + if (memcmp(wmac, cmac, sizeof(wmac)) != 0) { printf("WARNING: invalid packet signature\n"); @@ -694,6 +696,7 @@ BOOL rdp_decrypt(rdpRdp* rdp, STREAM* s, int length, UINT16 securityFlags) */ //return FALSE; } + return TRUE; } diff --git a/libfreerdp/core/rpc.c b/libfreerdp/core/rpc.c index 154d56d13..8ea5e7ae4 100644 --- a/libfreerdp/core/rpc.c +++ b/libfreerdp/core/rpc.c @@ -934,6 +934,7 @@ int rpc_recv_pdu_fragment(rdpRpc* rpc) printf("Receiving Out-of-Sequence RTS PDU\n"); rts_recv_out_of_sequence_pdu(rpc); + return rpc_recv_pdu_fragment(rpc); } else if (header->common.ptype == PTYPE_FAULT) diff --git a/libfreerdp/core/rts.c b/libfreerdp/core/rts.c index 5ccaeed2c..9842b7a92 100644 --- a/libfreerdp/core/rts.c +++ b/libfreerdp/core/rts.c @@ -869,6 +869,11 @@ int rts_send_flow_control_ack_pdu(rdpRpc* rpc) return 0; } +int rts_recv_flow_control_ack_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) +{ + return 0; +} + int rts_recv_flow_control_ack_with_destination_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) { UINT32 offset; @@ -1362,7 +1367,7 @@ int rts_recv_out_of_sequence_pdu(rdpRpc* rpc) if (SignatureId == RTS_PDU_FLOW_CONTROL_ACK) { - + return rts_recv_flow_control_ack_pdu(rpc, rpc->buffer, rpc->length); } else if (SignatureId == RTS_PDU_FLOW_CONTROL_ACK_WITH_DESTINATION) { diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 184e1162d..f89a053c5 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -282,7 +282,7 @@ int transport_read(rdpTransport* transport, STREAM* s) else if (transport->layer == TRANSPORT_LAYER_TSG) status = tsg_read(transport->tsg, stream_get_tail(s), stream_get_left(s)); - if (status == 0 && transport->blocking) + if ((status == 0) && (transport->blocking)) { freerdp_usleep(transport->usleep_interval); continue; @@ -517,8 +517,22 @@ int transport_check_fds(rdpTransport** ptransport) BOOL transport_set_blocking_mode(rdpTransport* transport, BOOL blocking) { + BOOL status; + + status = TRUE; transport->blocking = blocking; - return tcp_set_blocking_mode(transport->TcpIn, blocking); + + if (transport->SplitInputOutput) + { + status &= tcp_set_blocking_mode(transport->TcpIn, blocking); + status &= tcp_set_blocking_mode(transport->TcpOut, blocking); + } + else + { + status &= tcp_set_blocking_mode(transport->TcpIn, blocking); + } + + return status; } rdpTransport* transport_new(rdpSettings* settings) diff --git a/libfreerdp/core/tsg.c b/libfreerdp/core/tsg.c index 275327ce7..d2e890f3b 100644 --- a/libfreerdp/core/tsg.c +++ b/libfreerdp/core/tsg.c @@ -1158,6 +1158,7 @@ int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length) { DEBUG_TSG("Ignoring TsProxySetupReceivePipe Response"); return tsg_read(tsg, data, length); + return 0; } tsg->PendingPdu = TRUE; diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index 5c0301808..d977b2e5a 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -284,29 +284,39 @@ BOOL tls_disconnect(rdpTls* tls) { if (tls->ssl) SSL_shutdown(tls->ssl); + return TRUE; } int tls_read(rdpTls* tls, BYTE* data, int length) { + int error; int status; status = SSL_read(tls->ssl, data, length); - switch (SSL_get_error(tls->ssl, status)) + if (status <= 0) { - case SSL_ERROR_NONE: - break; + error = SSL_get_error(tls->ssl, status); - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - status = 0; - break; + //printf("tls_read: length: %d status: %d error: 0x%08X\n", + // length, status, error); - default: - tls_print_error("SSL_read", tls->ssl, status); - status = -1; - break; + switch (error) + { + case SSL_ERROR_NONE: + break; + + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + status = 0; + break; + + default: + tls_print_error("SSL_read", tls->ssl, status); + status = -1; + break; + } } return status; @@ -327,24 +337,33 @@ int tls_read_all(rdpTls* tls, BYTE* data, int length) int tls_write(rdpTls* tls, BYTE* data, int length) { + int error; int status; status = SSL_write(tls->ssl, data, length); - switch (SSL_get_error(tls->ssl, status)) + if (status <= 0) { - case SSL_ERROR_NONE: - break; + error = SSL_get_error(tls->ssl, status); - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - status = 0; - break; + //printf("tls_write: length: %d status: %d error: 0x%08X\n", + // length, status, error); - default: - tls_print_error("SSL_write", tls->ssl, status); - status = -1; - break; + switch (error) + { + case SSL_ERROR_NONE: + break; + + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + status = 0; + break; + + default: + tls_print_error("SSL_write", tls->ssl, status); + status = -1; + break; + } } return status;