diff options
author | Cendio <cendio@pairstation.lkpg.cendio.se> | 2018-01-22 13:04:41 +0100 |
---|---|---|
committer | Cendio <cendio@pairstation.lkpg.cendio.se> | 2018-01-31 11:03:32 +0100 |
commit | e112b69c619e833e934d2428f6556c9047e955ed (patch) | |
tree | c48b564a844a973795eddc6ed9cc4c285df376eb | |
parent | 293680c034e495bf228da84e6bd08e5d96f45674 (diff) | |
download | rdesktop-e112b69c619e833e934d2428f6556c9047e955ed.zip |
Use proper user-initiated disconnect sequence
A correct user initated disconnect sequence should send
a MCS Disconnect Provider Ultimatum PDU defined in T.128
upon a disconnect. This commit adds the implementation
the mentioned PDU and the actual write of the packet.
Signed-off-by: Henrik Andersson <hean01@cendio.com>
-rw-r--r-- | constants.h | 11 | ||||
-rw-r--r-- | mcs.c | 29 | ||||
-rw-r--r-- | proto.h | 2 | ||||
-rw-r--r-- | secure.c | 4 | ||||
-rw-r--r-- | tests/mcs_test.c | 18 |
5 files changed, 61 insertions, 3 deletions
diff --git a/constants.h b/constants.h index 753a250..267522b 100644 --- a/constants.h +++ b/constants.h @@ -126,6 +126,17 @@ enum MCS_PDU_TYPE #define MCS_GLOBAL_CHANNEL 1003 #define MCS_USERCHANNEL_BASE 1001 +/* ITU-T Rec. T.125, Reason enumeration used with Disconnect Provider + Ultimatum, see mcs_send_dpu(reason) */ +enum MCS_DPU_REASON +{ + RN_DOMAIN_DISCONNECTED = 0, + RN_PROVIDER_INITIATED, + RN_TOKEN_PURGED, + RN_USER_REQUESTED, + RN_CHANNEL_PURGED, +}; + /* RDP secure transport constants */ #define SEC_RANDOM_SIZE 32 #define SEC_MODULUS_SIZE 64 @@ -237,6 +237,32 @@ mcs_recv_cjcf(void) return s_check_end(s); } + +/* Send MCS Disconnect provider ultimatum PDU */ +void +mcs_send_dpu(unsigned short reason) +{ + STREAM s, contents; + + logger(Protocol, Debug, "mcs_send_dpu(), reason=%d", reason); + + contents = malloc(sizeof(struct stream)); + memset(contents, 0, sizeof(struct stream)); + s_realloc(contents, 6); + s_reset(contents); + ber_out_integer(contents, reason); /* Reason */ + ber_out_sequence(contents, NULL); /* SEQUENCE OF NonStandradParameters OPTIONAL */ + s_mark_end(contents); + + s = iso_init(8); + ber_out_sequence(s, contents); + s_free(contents); + + s_mark_end(s); + + iso_send(s); +} + /* Initialise an MCS transport data packet */ STREAM mcs_init(int length) @@ -353,8 +379,9 @@ mcs_connect_finalize(STREAM mcs_data) /* Disconnect from the MCS layer */ void -mcs_disconnect(void) +mcs_disconnect(int reason) { + mcs_send_dpu(reason); iso_disconnect(); } @@ -99,7 +99,7 @@ STREAM mcs_recv(uint16 * channel, uint8 * rdpver); RD_BOOL mcs_connect_start(char *server, char *username, char *domain, char *password, RD_BOOL reconnect, uint32 * selected_protocol); RD_BOOL mcs_connect_finalize(STREAM s); -void mcs_disconnect(void); +void mcs_disconnect(int reason); void mcs_reset_state(void); /* orders.c */ void process_orders(STREAM s, uint16 num_orders); @@ -958,7 +958,9 @@ sec_connect(char *server, char *username, char *domain, char *password, RD_BOOL void sec_disconnect(void) { - mcs_disconnect(); + /* Perform a User-initiated disconnect sequence, see + [MS-RDPBCGR] 1.3.1.4 Disconnect Sequences */ + mcs_disconnect(RN_USER_REQUESTED); } /* reset the state of the sec layer */ diff --git a/tests/mcs_test.c b/tests/mcs_test.c index 5799602..37d6ff5 100644 --- a/tests/mcs_test.c +++ b/tests/mcs_test.c @@ -81,3 +81,21 @@ Ensure(MCS, should_produce_valid_packet_for_McsSendCJrq) mcs_send_cjrq(chan_id); s_free(s); } + +/* Test function */ +Ensure(MCS, should_produce_valid_packet_for_McsSendDPU) +{ + int reason = 1; + struct stream *s; + uint8_t content[] = {0x30, 0x06, 0x02, 0x02, 0x00, reason, 0x30, 0x00}; + + s = stream_new(8); + + expect(logger); + expect(iso_init, will_return(s)); + + expect(iso_send, when(stream->data, is_equal_to_contents_of(content, sizeof(content)))); + + mcs_send_dpu(reason); + s_free(s); +} |