diff options
Diffstat (limited to 'libxrdp')
-rw-r--r-- | libxrdp/libxrdp.h | 9 | ||||
-rw-r--r-- | libxrdp/libxrdpinc.h | 1 | ||||
-rw-r--r-- | libxrdp/xrdp_rdp.c | 22 | ||||
-rw-r--r-- | libxrdp/xrdp_sec.c | 67 |
4 files changed, 84 insertions, 15 deletions
diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h index b5afde0a..dd87096e 100644 --- a/libxrdp/libxrdp.h +++ b/libxrdp/libxrdp.h @@ -75,8 +75,9 @@ struct xrdp_sec char encrypt_key[16]; char decrypt_update_key[16]; char encrypt_update_key[16]; - int rc4_key_size; - int rc4_key_len; + int rc4_key_size; /* 1 = 40 bit, 2 = 128 bit */ + int rc4_key_len; /* 8 = 40 bit, 16 = 128 bit */ + int crypt_level; /* 1, 2, 3 = low, meduim, high */ char sign_key[16]; void* decrypt_rc4_info; void* encrypt_rc4_info; @@ -230,7 +231,7 @@ xrdp_mcs_disconnect(struct xrdp_mcs* self); /* xrdp_sec.c */ struct xrdp_sec* APP_CC -xrdp_sec_create(struct xrdp_rdp* owner, int sck); +xrdp_sec_create(struct xrdp_rdp* owner, int sck, int crypt_level); void APP_CC xrdp_sec_delete(struct xrdp_sec* self); int APP_CC @@ -238,7 +239,7 @@ xrdp_sec_init(struct xrdp_sec* self, struct stream* s); int APP_CC xrdp_sec_recv(struct xrdp_sec* self, struct stream* s, int* chan); int APP_CC -xrdp_sec_send(struct xrdp_sec* self, struct stream* s, int flags); +xrdp_sec_send(struct xrdp_sec* self, struct stream* s); int APP_CC xrdp_sec_incoming(struct xrdp_sec* self); int APP_CC diff --git a/libxrdp/libxrdpinc.h b/libxrdp/libxrdpinc.h index cc8f77be..74ebfda3 100644 --- a/libxrdp/libxrdpinc.h +++ b/libxrdp/libxrdpinc.h @@ -56,6 +56,7 @@ struct xrdp_client_info char directory[256]; int rdp_compression; int rdp_autologin; + int crypt_level; /* 1, 2, 3 = low, medium, high */ }; struct xrdp_brush diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index 39aa8896..3aebcb28 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -87,6 +87,21 @@ xrdp_rdp_read_config(struct xrdp_client_info* client_info) client_info->use_bitmap_comp = 1; } } + else if (g_strncasecmp(item, "crypt_level", 255) == 0) + { + if (g_strncasecmp(value, "low", 255) == 0) + { + client_info->crypt_level = 1; + } + else if (g_strncasecmp(value, "medium", 255) == 0) + { + client_info->crypt_level = 2; + } + else if (g_strncasecmp(value, "high", 255) == 0) + { + client_info->crypt_level = 3; + } + } } list_delete(items); list_delete(values); @@ -104,9 +119,10 @@ xrdp_rdp_create(struct xrdp_session* session, int sck) self = (struct xrdp_rdp*)g_malloc(sizeof(struct xrdp_rdp), 1); self->session = session; self->share_id = 66538; - self->sec_layer = xrdp_sec_create(self, sck); /* read ini settings */ xrdp_rdp_read_config(&self->client_info); + /* create sec layer */ + self->sec_layer = xrdp_sec_create(self, sck, self->client_info.crypt_level); /* default 8 bit v1 color bitmap cache entries and size */ self->client_info.cache1_entries = 600; self->client_info.cache1_size = 256; @@ -221,7 +237,7 @@ xrdp_rdp_send(struct xrdp_rdp* self, struct stream* s, int pdu_type) out_uint16_le(s, len); out_uint16_le(s, 0x10 | pdu_type); out_uint16_le(s, self->mcs_channel); - if (xrdp_sec_send(self->sec_layer, s, 0) != 0) + if (xrdp_sec_send(self->sec_layer, s) != 0) { DEBUG(("out xrdp_rdp_send error\r\n")); return 1; @@ -250,7 +266,7 @@ xrdp_rdp_send_data(struct xrdp_rdp* self, struct stream* s, out_uint8(s, data_pdu_type); out_uint8(s, 0); out_uint16_le(s, 0); - if (xrdp_sec_send(self->sec_layer, s, 0) != 0) + if (xrdp_sec_send(self->sec_layer, s) != 0) { DEBUG(("out xrdp_rdp_send_data error\r\n")); return 1; diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 47f67815..3656af6d 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -169,7 +169,7 @@ hex_str_to_bin(char* in, char* out, int out_len) /*****************************************************************************/ struct xrdp_sec* APP_CC -xrdp_sec_create(struct xrdp_rdp* owner, int sck) +xrdp_sec_create(struct xrdp_rdp* owner, int sck, int crypt_level) { struct xrdp_sec* self; struct list* items; @@ -181,7 +181,23 @@ xrdp_sec_create(struct xrdp_rdp* owner, int sck) self = (struct xrdp_sec*)g_malloc(sizeof(struct xrdp_sec), 1); self->rdp_layer = owner; - self->rc4_key_size = 1; + self->rc4_key_size = 1; /* 1 = 40 bit, 2 = 128 bit */ + self->crypt_level = 1; /* 1, 2, 3 = low, medium, high */ + switch (crypt_level) + { + case 1: + self->rc4_key_size = 1; + self->crypt_level = 1; + break; + case 2: + self->rc4_key_size = 1; + self->crypt_level = 2; + break; + case 3: + self->rc4_key_size = 2; + self->crypt_level = 3; + break; + } self->decrypt_rc4_info = ssl_rc4_info_create(); self->encrypt_rc4_info = ssl_rc4_info_create(); g_random(self->server_random, 32); @@ -248,7 +264,14 @@ xrdp_sec_init(struct xrdp_sec* self, struct stream* s) { return 1; } - s_push_layer(s, sec_hdr, 4); + if (self->crypt_level > 1) + { + s_push_layer(s, sec_hdr, 4 + 8); + } + else + { + s_push_layer(s, sec_hdr, 4); + } return 0; } @@ -315,6 +338,22 @@ xrdp_sec_decrypt(struct xrdp_sec* self, char* data, int len) } /*****************************************************************************/ +static void APP_CC +xrdp_sec_encrypt(struct xrdp_sec* self, char* data, int len) +{ + if (self->encrypt_use_count == 4096) + { + xrdp_sec_update(self->encrypt_key, self->encrypt_update_key, + self->rc4_key_len); + ssl_rc4_set_key(self->encrypt_rc4_info, self->encrypt_key, + self->rc4_key_len); + self->encrypt_use_count = 0; + } + ssl_rc4_crypt(self->encrypt_rc4_info, data, len); + self->encrypt_use_count++; +} + +/*****************************************************************************/ static int APP_CC unicode_in(struct stream* s, int uni_len, char* dst, int dst_len) { @@ -642,13 +681,24 @@ xrdp_sec_sign(struct xrdp_sec* self, char* out, int out_len, /*****************************************************************************/ /* returns error */ -/* TODO needs outgoing encryption */ int APP_CC -xrdp_sec_send(struct xrdp_sec* self, struct stream* s, int flags) +xrdp_sec_send(struct xrdp_sec* self, struct stream* s) { + int datalen; + DEBUG((" in xrdp_sec_send\r\n")); s_pop_layer(s, sec_hdr); - out_uint32_le(s, flags); + if (self->crypt_level > 1) + { + out_uint32_le(s, SEC_ENCRYPT); + datalen = (s->end - s->p) - 8; + xrdp_sec_sign(self, s->p, 8, s->p + 8, datalen); + xrdp_sec_encrypt(self, s->p + 8, datalen); + } + else + { + out_uint32_le(s, 0); + } if (xrdp_mcs_send(self->mcs_layer, s) != 0) { return 1; @@ -698,8 +748,9 @@ xrdp_sec_out_mcs_data(struct xrdp_sec* self) out_uint8(p, 0); out_uint16_le(p, SEC_TAG_SRV_CRYPT); out_uint16_le(p, 0x00ec); /* len is 236 */ - out_uint32_le(p, 1); /* key len 1 = 40 bit 2 = 128 bit */ - out_uint32_le(p, 1); /* crypt level 1 = low 2 = medium 3 = high */ + out_uint32_le(p, self->rc4_key_size); /* key len 1 = 40 bit 2 = 128 bit */ + out_uint32_le(p, self->crypt_level); /* crypt level 1 = low 2 = medium */ + /* 3 = high */ out_uint32_le(p, 32); /* 32 bytes random len */ out_uint32_le(p, 0xb8); /* 184 bytes rsa info(certificate) len */ out_uint8a(p, self->server_random, 32); |