diff --git a/libfreerdp-core/connection.c b/libfreerdp-core/connection.c index 5b3d7969e..0d5be304b 100644 --- a/libfreerdp-core/connection.c +++ b/libfreerdp-core/connection.c @@ -217,8 +217,22 @@ boolean rdp_client_connect_license(rdpRdp* rdp, STREAM* s) boolean rdp_client_connect_demand_active(rdpRdp* rdp, STREAM* s) { + uint8* mark; + + stream_get_mark(s, mark); + if (!rdp_recv_demand_active(rdp, s)) - return False; + { + stream_set_mark(s, mark); + stream_seek(s, RDP_PACKET_HEADER_LENGTH); + + if (rdp_recv_out_of_sequence_pdu(rdp, s) != True) + { + printf("Unexpected PDU when expecting Demand Active PDU\n"); + return False; + } + return True; + } if (!rdp_send_confirm_active(rdp)) return False; diff --git a/libfreerdp-core/errinfo.h b/libfreerdp-core/errinfo.h index 5e9445461..d63f078c4 100644 --- a/libfreerdp-core/errinfo.h +++ b/libfreerdp-core/errinfo.h @@ -30,7 +30,7 @@ #define ERRINFO_DISCONNECTED_BY_OTHER_CONNECTION 0x00000005 #define ERRINFO_OUT_OF_MEMORY 0x00000006 #define ERRINFO_SERVER_DENIED_CONNECTION 0x00000007 -#define ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES 0x00000008 +#define ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES 0x00000009 #define ERRINFO_SERVER_FRESH_CREDENTIALS_REQUIRED 0x0000000A #define ERRINFO_RPC_INITIATED_DISCONNECT_BY_USER 0x0000000B diff --git a/libfreerdp-core/license.c b/libfreerdp-core/license.c index 39d2fc097..9a23ab3b3 100644 --- a/libfreerdp-core/license.c +++ b/libfreerdp-core/license.c @@ -17,6 +17,8 @@ * limitations under the License. */ +#include "redirection.h" + #include "license.h" uint8 LICENSE_MESSAGE_STRINGS[][32] = @@ -179,8 +181,13 @@ boolean license_recv(rdpLicense* license, STREAM* s) rdp_read_security_header(s, &sec_flags); if (!(sec_flags & SEC_LICENSE_PKT)) { - printf("Unexpected license packet.\n"); - return False; + stream_rewind(s, RDP_SECURITY_HEADER_LENGTH); + if (rdp_recv_out_of_sequence_pdu(license->rdp, s) != True) + { + printf("Unexpected license packet.\n"); + return False; + } + return True; } license_read_preamble(s, &bMsgType, &flags, &wMsgSize); /* preamble (4 bytes) */ @@ -825,7 +832,6 @@ void license_send_platform_challenge_response_packet(rdpLicense* license) license_send(license, s, PLATFORM_CHALLENGE_RESPONSE); } - /** * Send Server License Error - Valid Client Packet.\n * @msdn{cc241922} diff --git a/libfreerdp-core/rdp.c b/libfreerdp-core/rdp.c index 7d0312994..064935923 100644 --- a/libfreerdp-core/rdp.c +++ b/libfreerdp-core/rdp.c @@ -399,6 +399,30 @@ void rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s) } } +boolean rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, STREAM* s) +{ + uint16 type; + uint16 length; + uint16 channelId; + + rdp_read_share_control_header(s, &length, &type, &channelId); + + if (type == PDU_TYPE_DATA) + { + rdp_recv_data_pdu(rdp, s); + return True; + } + else if (type == PDU_TYPE_SERVER_REDIRECTION) + { + rdp_recv_enhanced_security_redirection_packet(rdp, s); + return True; + } + else + { + return False; + } +} + /** * Process an RDP packet.\n * @param rdp RDP module diff --git a/libfreerdp-core/rdp.h b/libfreerdp-core/rdp.h index 9ba3e3bcd..fb50fea27 100644 --- a/libfreerdp-core/rdp.h +++ b/libfreerdp-core/rdp.h @@ -153,6 +153,8 @@ void rdp_recv(rdpRdp* rdp); int rdp_send_channel_data(rdpRdp* rdp, int channel_id, uint8* data, int size); +boolean rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, STREAM* s); + void rdp_set_blocking_mode(rdpRdp* rdp, boolean blocking); int rdp_check_fds(rdpRdp* rdp); diff --git a/libfreerdp-core/redirection.c b/libfreerdp-core/redirection.c index a80c55b7f..2c8d63a99 100644 --- a/libfreerdp-core/redirection.c +++ b/libfreerdp-core/redirection.c @@ -19,25 +19,136 @@ #include "redirection.h" -/** - * Read an RDP Server Redirection Packet.\n - * @msdn{ee441959} - * @param rdp RDP module - * @param s stream - * @param sec_flags security flags - */ +void rdp_print_redirection_flags(uint32 flags) +{ + printf("redirectionFlags = {\n"); + + if (flags & LB_TARGET_NET_ADDRESS) + printf("\tLB_TARGET_NET_ADDRESS\n"); + if (flags & LB_LOAD_BALANCE_INFO) + printf("\tLB_LOAD_BALANCE_INFO\n"); + if (flags & LB_USERNAME) + printf("\tLB_USERNAME\n"); + if (flags & LB_DOMAIN) + printf("\tLB_DOMAIN\n"); + if (flags & LB_PASSWORD) + printf("\tLB_PASSWORD\n"); + if (flags & LB_DONTSTOREUSERNAME) + printf("\tLB_DONTSTOREUSERNAME\n"); + if (flags & LB_SMARTCARD_LOGON) + printf("\tLB_SMARTCARD_LOGON\n"); + if (flags & LB_NOREDIRECT) + printf("\tLB_NOREDIRECT\n"); + if (flags & LB_TARGET_FQDN) + printf("\tLB_TARGET_FQDN\n"); + if (flags & LB_TARGET_NETBIOS_NAME) + printf("\tLB_TARGET_NETBIOS_NAME\n"); + if (flags & LB_TARGET_NET_ADDRESSES) + printf("\tLB_TARGET_NET_ADDRESSES\n"); + if (flags & LB_CLIENT_TSV_URL) + printf("\tLB_CLIENT_TSV_URL\n"); + if (flags & LB_SERVER_TSV_CAPABLE) + printf("\tLB_SERVER_TSV_CAPABLE\n"); + + printf("}\n"); +} + +boolean rdp_recv_server_redirection_pdu(rdpRdp* rdp, STREAM* s) +{ + uint16 flags; + uint16 length; + uint32 sessionID; + uint32 redirFlags; + uint32 targetNetAddressLength; + uint32 loadBalanceInfoLength; + uint32 userNameLength; + uint32 domainLength; + uint32 passwordLength; + uint32 targetFQDNLength; + uint32 targetNetBiosNameLength; + uint32 tsvUrlLength; + uint32 targetNetAddressesLength; + + stream_read_uint16(s, flags); /* flags (2 bytes) */ + stream_read_uint16(s, length); /* length (2 bytes) */ + stream_read_uint32(s, sessionID); /* sessionID (4 bytes) */ + stream_read_uint32(s, redirFlags); /* redirFlags (4 bytes) */ + + DEBUG_REDIR("flags: 0x%04X, length:%d, sessionID:0x%08X", flags, length, sessionID); + +#ifdef WITH_DEBUG_REDIR + rdp_print_redirection_flags(redirFlags); +#endif + + if (redirFlags & LB_TARGET_NET_ADDRESS) + { + stream_read_uint32(s, targetNetAddressLength); /* targetNetAddressLength (4 bytes) */ + stream_seek(s, targetNetAddressLength); + } + + if (redirFlags & LB_LOAD_BALANCE_INFO) + { + stream_read_uint32(s, loadBalanceInfoLength); /* loadBalanceInfoLength (4 bytes) */ + stream_seek(s, loadBalanceInfoLength); + } + + if (redirFlags & LB_USERNAME) + { + stream_read_uint32(s, userNameLength); /* userNameLength (4 bytes) */ + stream_seek(s, userNameLength); + } + + if (redirFlags & LB_DOMAIN) + { + stream_read_uint32(s, domainLength); /* domainLength (4 bytes) */ + stream_seek(s, domainLength); + } + + if (redirFlags & LB_PASSWORD) + { + stream_read_uint32(s, passwordLength); /* passwordLength (4 bytes) */ + stream_seek(s, passwordLength); + } + + if (redirFlags & LB_TARGET_FQDN) + { + stream_read_uint32(s, targetFQDNLength); /* targetFQDNLength (4 bytes) */ + stream_seek(s, targetFQDNLength); + } + + if (redirFlags & LB_TARGET_NETBIOS_NAME) + { + stream_read_uint32(s, targetNetBiosNameLength); /* targetNetBiosNameLength (4 bytes) */ + stream_seek(s, targetNetBiosNameLength); + } + + if (redirFlags & LB_CLIENT_TSV_URL) + { + stream_read_uint32(s, tsvUrlLength); /* tsvUrlLength (4 bytes) */ + stream_seek(s, tsvUrlLength); + } + + if (redirFlags & LB_TARGET_NET_ADDRESSES) + { + stream_read_uint32(s, targetNetAddressesLength); /* targetNetAddressesLength (4 bytes) */ + stream_seek(s, targetNetAddressesLength); + } + + stream_seek(s, 8); /* pad (8 bytes) */ + + return True; +} boolean rdp_recv_redirection_packet(rdpRdp* rdp, STREAM* s) { - printf("Redirection Packet\n"); - return True; } boolean rdp_recv_enhanced_security_redirection_packet(rdpRdp* rdp, STREAM* s) { - printf("Enhanced Security Redirection Packet\n"); - + stream_seek_uint16(s); /* pad2Octets (2 bytes) */ + rdp_recv_server_redirection_pdu(rdp, s); + stream_seek_uint8(s); /* pad2Octets (1 byte) */ return True; } diff --git a/libfreerdp-core/redirection.h b/libfreerdp-core/redirection.h index 02c6ddf8c..afccbbc7d 100644 --- a/libfreerdp-core/redirection.h +++ b/libfreerdp-core/redirection.h @@ -23,9 +23,31 @@ #include "rdp.h" #include +#include #include +/* Redirection Flags */ +#define LB_TARGET_NET_ADDRESS 0x00000001 +#define LB_LOAD_BALANCE_INFO 0x00000002 +#define LB_USERNAME 0x00000004 +#define LB_DOMAIN 0x00000008 +#define LB_PASSWORD 0x00000010 +#define LB_DONTSTOREUSERNAME 0x00000020 +#define LB_SMARTCARD_LOGON 0x00000040 +#define LB_NOREDIRECT 0x00000080 +#define LB_TARGET_FQDN 0x00000100 +#define LB_TARGET_NETBIOS_NAME 0x00000200 +#define LB_TARGET_NET_ADDRESSES 0x00000800 +#define LB_CLIENT_TSV_URL 0x00001000 +#define LB_SERVER_TSV_CAPABLE 0x00002000 + boolean rdp_recv_redirection_packet(rdpRdp* rdp, STREAM* s); boolean rdp_recv_enhanced_security_redirection_packet(rdpRdp* rdp, STREAM* s); +#ifdef WITH_DEBUG_REDIR +#define DEBUG_REDIR(fmt, ...) DEBUG_CLASS(REDIR, fmt, ## __VA_ARGS__) +#else +#define DEBUG_REDIR(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) +#endif + #endif /* __REDIRECTION_H */