boolean nego_recv(rdpTransport* transport, STREAM* s, void* extra) { uint8 li; uint8 type; rdpNego* nego = (rdpNego*) extra; if (tpkt_read_header(s) == 0) return false; li = tpdu_read_connection_confirm(s); if (li > 6) { /* rdpNegData (optional) */ stream_read_uint8(s, type); /* Type */ switch (type) { case TYPE_RDP_NEG_RSP: nego_process_negotiation_response(nego, s); break; case TYPE_RDP_NEG_FAILURE: nego_process_negotiation_failure(nego, s); break; } } else { nego->state = NEGO_STATE_FINAL; } return true; }
BOOL nego_read_request(rdpNego* nego, wStream* s) { BYTE li; BYTE c; BYTE type; tpkt_read_header(s); if (!tpdu_read_connection_request(s, &li)) return FALSE; if (li != Stream_GetRemainingLength(s) + 6) { fprintf(stderr, "Incorrect TPDU length indicator.\n"); return FALSE; } if (Stream_GetRemainingLength(s) > 8) { /* Optional routingToken or cookie, ending with CR+LF */ while (Stream_GetRemainingLength(s) > 0) { Stream_Read_UINT8(s, c); if (c != '\x0D') continue; Stream_Peek_UINT8(s, c); if (c != '\x0A') continue; Stream_Seek_UINT8(s); break; } } if (Stream_GetRemainingLength(s) >= 8) { /* rdpNegData (optional) */ Stream_Read_UINT8(s, type); /* Type */ if (type != TYPE_RDP_NEG_REQ) { fprintf(stderr, "Incorrect negotiation request type %d\n", type); return FALSE; } nego_process_negotiation_request(nego, s); } return TRUE; }
BOOL nego_read_request(rdpNego* nego, STREAM* s) { BYTE li; BYTE c; BYTE type; tpkt_read_header(s); if(!tpdu_read_connection_request(s, &li)) return FALSE; if (li != stream_get_left(s) + 6) { printf("Incorrect TPDU length indicator.\n"); return FALSE; } if (stream_get_left(s) > 8) { /* Optional routingToken or cookie, ending with CR+LF */ while (stream_get_left(s) > 0) { stream_read_BYTE(s, c); if (c != '\x0D') continue; stream_peek_BYTE(s, c); if (c != '\x0A') continue; stream_seek_BYTE(s); break; } } if (stream_get_left(s) >= 8) { /* rdpNegData (optional) */ stream_read_BYTE(s, type); /* Type */ if (type != TYPE_RDP_NEG_REQ) { printf("Incorrect negotiation request type %d\n", type); return FALSE; } nego_process_negotiation_request(nego, s); } return TRUE; }
BOOL nego_read_request(rdpNego* nego, wStream* s) { BYTE li; BYTE type; UINT16 length; if (!tpkt_read_header(s, &length)) return FALSE; if (!tpdu_read_connection_request(s, &li)) return FALSE; if (li != Stream_GetRemainingLength(s) + 6) { WLog_ERR(TAG, "Incorrect TPDU length indicator."); return FALSE; } if (!nego_read_request_token_or_cookie(nego, s)) { WLog_ERR(TAG, "Failed to parse routing token or cookie."); return FALSE; } if (Stream_GetRemainingLength(s) >= 8) { /* rdpNegData (optional) */ Stream_Read_UINT8(s, type); /* Type */ if (type != TYPE_RDP_NEG_REQ) { WLog_ERR(TAG, "Incorrect negotiation request type %"PRIu8"", type); return FALSE; } nego_process_negotiation_request(nego, s); } return TRUE; }
int nego_recv(rdpTransport* transport, wStream* s, void* extra) { BYTE li; BYTE type; UINT16 length; rdpNego* nego = (rdpNego*) extra; length = tpkt_read_header(s); if (length == 0) return -1; if (!tpdu_read_connection_confirm(s, &li)) return -1; if (li > 6) { /* rdpNegData (optional) */ Stream_Read_UINT8(s, type); /* Type */ switch (type) { case TYPE_RDP_NEG_RSP: nego_process_negotiation_response(nego, s); WLog_DBG(TAG, "selected_protocol: %d", nego->SelectedProtocol); /* enhanced security selected ? */ if (nego->SelectedProtocol) { if ((nego->SelectedProtocol == PROTOCOL_NLA) && (!nego->EnabledProtocols[PROTOCOL_NLA])) { nego->state = NEGO_STATE_FAIL; } if ((nego->SelectedProtocol == PROTOCOL_TLS) && (!nego->EnabledProtocols[PROTOCOL_TLS])) { nego->state = NEGO_STATE_FAIL; } } else if (!nego->EnabledProtocols[PROTOCOL_RDP]) { nego->state = NEGO_STATE_FAIL; } break; case TYPE_RDP_NEG_FAILURE: nego_process_negotiation_failure(nego, s); break; } } else if (li == 6) { WLog_DBG(TAG, "no rdpNegData"); if (!nego->EnabledProtocols[PROTOCOL_RDP]) nego->state = NEGO_STATE_FAIL; else nego->state = NEGO_STATE_FINAL; } else { WLog_ERR(TAG, "invalid negotiation response"); nego->state = NEGO_STATE_FAIL; } return 0; }
int transport_check_fds(rdpTransport* transport) { int pos; int status; uint16 length; STREAM* received; wait_obj_clear(transport->recv_event); status = transport_read_nonblocking(transport); if (status < 0) return status; while ((pos = stream_get_pos(transport->recv_buffer)) > 0) { stream_set_pos(transport->recv_buffer, 0); if (tpkt_verify_header(transport->recv_buffer)) /* TPKT */ { /* Ensure the TPKT header is available. */ if (pos <= 4) { stream_set_pos(transport->recv_buffer, pos); return 0; } length = tpkt_read_header(transport->recv_buffer); } else /* Fast Path */ { /* Ensure the Fast Path header is available. */ if (pos <= 2) { stream_set_pos(transport->recv_buffer, pos); return 0; } length = fastpath_read_header(NULL, transport->recv_buffer); } if (length == 0) { printf("transport_check_fds: protocol error, not a TPKT or Fast Path header.\n"); freerdp_hexdump(stream_get_head(transport->recv_buffer), pos); return -1; } if (pos < length) { stream_set_pos(transport->recv_buffer, pos); return 0; /* Packet is not yet completely received. */ } /* * A complete packet has been received. In case there are trailing data * for the next packet, we copy it to the new receive buffer. */ received = transport->recv_buffer; transport->recv_buffer = stream_new(BUFFER_SIZE); if (pos > length) { stream_set_pos(received, length); stream_check_size(transport->recv_buffer, pos - length); stream_copy(transport->recv_buffer, received, pos - length); } stream_set_pos(received, length); stream_seal(received); stream_set_pos(received, 0); if (transport->recv_callback(transport, received, transport->recv_extra) == False) status = -1; stream_free(received); if (status < 0) return status; } return 0; }
BOOL nego_recv(rdpTransport* transport, STREAM* s, void* extra) { BYTE li; BYTE type; UINT16 length; rdpNego* nego = (rdpNego*) extra; length = tpkt_read_header(s); if (length == 0) return FALSE; if(!tpdu_read_connection_confirm(s, &li)) return FALSE; if (li > 6) { /* rdpNegData (optional) */ stream_read_BYTE(s, type); /* Type */ switch (type) { case TYPE_RDP_NEG_RSP: nego_process_negotiation_response(nego, s); DEBUG_NEGO("selected_protocol: %d", nego->selected_protocol); /* enhanced security selected ? */ if (nego->selected_protocol) { if ((nego->selected_protocol == PROTOCOL_NLA) && (!nego->enabled_protocols[PROTOCOL_NLA])) { nego->state = NEGO_STATE_FAIL; } if ((nego->selected_protocol == PROTOCOL_TLS) && (!nego->enabled_protocols[PROTOCOL_TLS])) { nego->state = NEGO_STATE_FAIL; } } else if (!nego->enabled_protocols[PROTOCOL_RDP]) { nego->state = NEGO_STATE_FAIL; } break; case TYPE_RDP_NEG_FAILURE: nego_process_negotiation_failure(nego, s); break; } } else if (li == 6) { DEBUG_NEGO("no rdpNegData"); if (!nego->enabled_protocols[PROTOCOL_RDP]) nego->state = NEGO_STATE_FAIL; else nego->state = NEGO_STATE_FINAL; } else { printf("invalid negotiation response\n"); nego->state = NEGO_STATE_FAIL; } return TRUE; }
int transport_check_fds(rdpTransport** ptransport) { int pos; int status; uint16 length; STREAM* received; rdpTransport* transport = *ptransport; wait_obj_clear(transport->recv_event); status = transport_read_nonblocking(transport); if (status < 0) return status; while ((pos = stream_get_pos(transport->recv_buffer)) > 0) { stream_set_pos(transport->recv_buffer, 0); if (tpkt_verify_header(transport->recv_buffer)) /* TPKT */ { /* Ensure the TPKT header is available. */ if (pos <= 4) { stream_set_pos(transport->recv_buffer, pos); return 0; } length = tpkt_read_header(transport->recv_buffer); } else /* Fast Path */ { /* Ensure the Fast Path header is available. */ if (pos <= 2) { stream_set_pos(transport->recv_buffer, pos); return 0; } /* Fastpath header can be two or three bytes long. */ length = fastpath_header_length(transport->recv_buffer); if (pos < length) { stream_set_pos(transport->recv_buffer, pos); return 0; } length = fastpath_read_header(NULL, transport->recv_buffer); } if (length == 0) { printf("transport_check_fds: protocol error, not a TPKT or Fast Path header.\n"); freerdp_hexdump(stream_get_head(transport->recv_buffer), pos); return -1; } if (pos < length) { stream_set_pos(transport->recv_buffer, pos); return 0; /* Packet is not yet completely received. */ } /* * A complete packet has been received. In case there are trailing data * for the next packet, we copy it to the new receive buffer. */ received = transport->recv_buffer; transport->recv_buffer = stream_new(BUFFER_SIZE); if (pos > length) { stream_set_pos(received, length); stream_check_size(transport->recv_buffer, pos - length); stream_copy(transport->recv_buffer, received, pos - length); } stream_set_pos(received, length); stream_seal(received); stream_set_pos(received, 0); if (transport->recv_callback(transport, received, transport->recv_extra) == false) status = -1; stream_free(received); if (status < 0) return status; /* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */ transport = *ptransport; if (transport->process_single_pdu) { /* one at a time but set event if data buffered * so the main loop will call freerdp_check_fds asap */ if (stream_get_pos(transport->recv_buffer) > 0) wait_obj_set(transport->recv_event); break; } } return 0; }
boolean nego_recv(rdpTransport* transport, STREAM* s, void* extra) { uint8 li; uint8 type; rdpNego* nego = (rdpNego*) extra; if (tpkt_read_header(s) == 0) return false; li = tpdu_read_connection_confirm(s); if (li > 6) { /* rdpNegData (optional) */ stream_read_uint8(s, type); /* Type */ switch (type) { case TYPE_RDP_NEG_RSP: nego_process_negotiation_response(nego, s); DEBUG_NEGO("selected_protocol: %d", nego->selected_protocol); /* enhanced security selected ? */ if (nego->selected_protocol) { if ((nego->selected_protocol == PROTOCOL_NLA) && (!nego->enabled_protocols[PROTOCOL_NLA])) { nego->state = NEGO_STATE_FAIL; } if ((nego->selected_protocol == PROTOCOL_TLS) && (!nego->enabled_protocols[PROTOCOL_TLS])) { nego->state = NEGO_STATE_FAIL; } } else if (!nego->enabled_protocols[PROTOCOL_RDP]) { nego->state = NEGO_STATE_FAIL; } break; case TYPE_RDP_NEG_FAILURE: nego_process_negotiation_failure(nego, s); break; } } else { DEBUG_NEGO("no rdpNegData"); if (!nego->enabled_protocols[PROTOCOL_RDP]) nego->state = NEGO_STATE_FAIL; else nego->state = NEGO_STATE_FINAL; } return true; }
int transport_check_fds(rdpTransport** ptransport) { int pos; int status; UINT16 length; int recv_status; STREAM* received; rdpTransport* transport = *ptransport; #ifdef _WIN32 WSAResetEvent(transport->TcpIn->wsa_event); #endif ResetEvent(transport->ReceiveEvent); status = transport_read_nonblocking(transport); if (status < 0) return status; while ((pos = stream_get_pos(transport->ReceiveBuffer)) > 0) { stream_set_pos(transport->ReceiveBuffer, 0); if (tpkt_verify_header(transport->ReceiveBuffer)) /* TPKT */ { /* Ensure the TPKT header is available. */ if (pos <= 4) { stream_set_pos(transport->ReceiveBuffer, pos); return 0; } length = tpkt_read_header(transport->ReceiveBuffer); } else if (nla_verify_header(transport->ReceiveBuffer)) { /* TSRequest */ /* Ensure the TSRequest header is available. */ if (pos <= 4) { stream_set_pos(transport->ReceiveBuffer, pos); return 0; } /* TSRequest header can be 2, 3 or 4 bytes long */ length = nla_header_length(transport->ReceiveBuffer); if (pos < length) { stream_set_pos(transport->ReceiveBuffer, pos); return 0; } length = nla_read_header(transport->ReceiveBuffer); } else /* Fast Path */ { /* Ensure the Fast Path header is available. */ if (pos <= 2) { stream_set_pos(transport->ReceiveBuffer, pos); return 0; } /* Fastpath header can be two or three bytes long. */ length = fastpath_header_length(transport->ReceiveBuffer); if (pos < length) { stream_set_pos(transport->ReceiveBuffer, pos); return 0; } length = fastpath_read_header(NULL, transport->ReceiveBuffer); } if (length == 0) { printf("transport_check_fds: protocol error, not a TPKT or Fast Path header.\n"); winpr_HexDump(stream_get_head(transport->ReceiveBuffer), pos); return -1; } if (pos < length) { stream_set_pos(transport->ReceiveBuffer, pos); return 0; /* Packet is not yet completely received. */ } received = transport->ReceiveBuffer; transport->ReceiveBuffer = transport_receive_pool_take(transport); stream_set_pos(received, length); stream_seal(received); stream_set_pos(received, 0); /** * ReceiveCallback return values: * * -1: synchronous failure * 0: synchronous success * 1: asynchronous return */ recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra); transport_receive_pool_return(transport, received); if (recv_status < 0) status = -1; if (status < 0) return status; /* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */ transport = *ptransport; } return 0; }
int transport_check_fds(rdpTransport* transport) { int pos; int status; UINT16 length; int recv_status; wStream* received; if (!transport) return -1; #ifdef _WIN32 WSAResetEvent(transport->TcpIn->wsa_event); #endif ResetEvent(transport->ReceiveEvent); status = transport_read_nonblocking(transport); if (status < 0) return status; while ((pos = Stream_GetPosition(transport->ReceiveBuffer)) > 0) { Stream_SetPosition(transport->ReceiveBuffer, 0); if (tpkt_verify_header(transport->ReceiveBuffer)) /* TPKT */ { /* Ensure the TPKT header is available. */ if (pos <= 4) { Stream_SetPosition(transport->ReceiveBuffer, pos); return 0; } length = tpkt_read_header(transport->ReceiveBuffer); } else if (nla_verify_header(transport->ReceiveBuffer)) { /* TSRequest */ /* Ensure the TSRequest header is available. */ if (pos <= 4) { Stream_SetPosition(transport->ReceiveBuffer, pos); return 0; } /* TSRequest header can be 2, 3 or 4 bytes long */ length = nla_header_length(transport->ReceiveBuffer); if (pos < length) { Stream_SetPosition(transport->ReceiveBuffer, pos); return 0; } length = nla_read_header(transport->ReceiveBuffer); } else /* Fast Path */ { /* Ensure the Fast Path header is available. */ if (pos <= 2) { Stream_SetPosition(transport->ReceiveBuffer, pos); return 0; } /* Fastpath header can be two or three bytes long. */ length = fastpath_header_length(transport->ReceiveBuffer); if (pos < length) { Stream_SetPosition(transport->ReceiveBuffer, pos); return 0; } length = fastpath_read_header(NULL, transport->ReceiveBuffer); } if (length == 0) { fprintf(stderr, "transport_check_fds: protocol error, not a TPKT or Fast Path header.\n"); winpr_HexDump(Stream_Buffer(transport->ReceiveBuffer), pos); return -1; } if (pos < length) { Stream_SetPosition(transport->ReceiveBuffer, pos); return 0; /* Packet is not yet completely received. */ } received = transport->ReceiveBuffer; transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0); Stream_SetPosition(received, length); Stream_SealLength(received); Stream_SetPosition(received, 0); /** * status: * -1: error * 0: success * 1: redirection */ recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra); if (recv_status == 1) { /** * Last call to ReceiveCallback resulted in a session redirection, * which means the current rdpTransport* transport pointer has been freed. * Return 0 for success, the rest of this function is meant for non-redirected cases. */ return 0; } Stream_Release(received); if (recv_status < 0) status = -1; if (status < 0) return status; } return 0; }
int transport_check_fds(rdpTransport** ptransport) { int pos; int status; UINT16 length; int recv_status; wStream* received; rdpTransport* transport = *ptransport; #ifdef _WIN32 WSAResetEvent(transport->TcpIn->wsa_event); #endif ResetEvent(transport->ReceiveEvent); status = transport_read_nonblocking(transport); if (status < 0) return status; while ((pos = Stream_GetPosition(transport->ReceiveBuffer)) > 0) { Stream_SetPosition(transport->ReceiveBuffer, 0); if (tpkt_verify_header(transport->ReceiveBuffer)) /* TPKT */ { /* Ensure the TPKT header is available. */ if (pos <= 4) { Stream_SetPosition(transport->ReceiveBuffer, pos); return 0; } length = tpkt_read_header(transport->ReceiveBuffer); } else if (nla_verify_header(transport->ReceiveBuffer)) { /* TSRequest */ /* Ensure the TSRequest header is available. */ if (pos <= 4) { Stream_SetPosition(transport->ReceiveBuffer, pos); return 0; } /* TSRequest header can be 2, 3 or 4 bytes long */ length = nla_header_length(transport->ReceiveBuffer); if (pos < length) { Stream_SetPosition(transport->ReceiveBuffer, pos); return 0; } length = nla_read_header(transport->ReceiveBuffer); } else /* Fast Path */ { /* Ensure the Fast Path header is available. */ if (pos <= 2) { Stream_SetPosition(transport->ReceiveBuffer, pos); return 0; } /* Fastpath header can be two or three bytes long. */ length = fastpath_header_length(transport->ReceiveBuffer); if (pos < length) { Stream_SetPosition(transport->ReceiveBuffer, pos); return 0; } length = fastpath_read_header(NULL, transport->ReceiveBuffer); } if (length == 0) { fprintf(stderr, "transport_check_fds: protocol error, not a TPKT or Fast Path header.\n"); winpr_HexDump(Stream_Buffer(transport->ReceiveBuffer), pos); return -1; } if (pos < length) { Stream_SetPosition(transport->ReceiveBuffer, pos); return 0; /* Packet is not yet completely received. */ } received = transport->ReceiveBuffer; transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0); Stream_SetPosition(received, length); Stream_SealLength(received); Stream_SetPosition(received, 0); recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra); if (transport == *ptransport) /* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */ /* so only release if still valid */ Stream_Release(received); if (recv_status < 0) status = -1; if (status < 0) return status; /* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */ transport = *ptransport; } return 0; }