summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCendio <cendio@pairstation.lkpg.cendio.se>2018-01-22 13:04:41 +0100
committerCendio <cendio@pairstation.lkpg.cendio.se>2018-01-31 11:03:32 +0100
commite112b69c619e833e934d2428f6556c9047e955ed (patch)
treec48b564a844a973795eddc6ed9cc4c285df376eb
parent293680c034e495bf228da84e6bd08e5d96f45674 (diff)
downloadrdesktop-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.h11
-rw-r--r--mcs.c29
-rw-r--r--proto.h2
-rw-r--r--secure.c4
-rw-r--r--tests/mcs_test.c18
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
diff --git a/mcs.c b/mcs.c
index 8ddf1d0..615aa61 100644
--- a/mcs.c
+++ b/mcs.c
@@ -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();
}
diff --git a/proto.h b/proto.h
index 54ed81b..a5aa2f5 100644
--- a/proto.h
+++ b/proto.h
@@ -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);
diff --git a/secure.c b/secure.c
index f416aba..679f4a0 100644
--- a/secure.c
+++ b/secure.c
@@ -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);
+}