From fb306e624ef60552d4a09e09d7ba0ca932c30328 Mon Sep 17 00:00:00 2001 From: speidy Date: Sat, 13 Dec 2014 16:24:07 +0200 Subject: [PATCH] libxrdp: changes for security layer negotiation, security_layer=negotiate is working now --- libxrdp/xrdp_iso.c | 122 ++++++++++++++++----------------------------- libxrdp/xrdp_sec.c | 2 +- 2 files changed, 44 insertions(+), 80 deletions(-) diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index ee490839..0e69811c 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -48,10 +48,45 @@ xrdp_iso_delete(struct xrdp_iso *self) g_free(self); } +/*****************************************************************************/ +static int APP_CC +xrdp_iso_negotiate_security(struct xrdp_iso *self) { + int server_security_layer = self->mcs_layer->sec_layer->rdp_layer->client_info.security_layer; + + self->selectedProtocol = server_security_layer; + + switch (server_security_layer) { + case PROTOCOL_RDP: + self->rdpNegData = 0; /* no need to send rdp_neg_data back to client */ + break; + case PROTOCOL_SSL: + if (self->requestedProtocol & PROTOCOL_SSL) { + self->selectedProtocol = PROTOCOL_SSL; + } else { + self->failureCode = SSL_REQUIRED_BY_SERVER; + } + break; + case PROTOCOL_HYBRID: + case PROTOCOL_HYBRID_EX: + default: + if (self->requestedProtocol & PROTOCOL_SSL) { + /* thats a patch since we don't support CredSSP for now */ + self->selectedProtocol = PROTOCOL_SSL; + } else { + self->selectedProtocol = PROTOCOL_RDP; + } + break; + } + + DEBUG(("xrdp_iso_negotiate_security: server security layer %d , client security layer %d", + self->selectedProtocol, self->requestedProtocol)); + return 0; +} + /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_iso_process_rdpNegReq(struct xrdp_iso *self, struct stream *s) +xrdp_iso_process_rdp_neg_req(struct xrdp_iso *self, struct stream *s) { int flags; int len; @@ -85,11 +120,11 @@ xrdp_iso_process_rdpNegReq(struct xrdp_iso *self, struct stream *s) static int APP_CC xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len) { - int ver; // tpkt ver - int plen; // tpkt len + int ver; + int plen; - *code = 0; // x.244 type - *len = 0; // X.224 len indicator + *code = 0; + *len = 0; if (s != self->trans->in_s) { @@ -212,7 +247,6 @@ xrdp_iso_send_cc(struct xrdp_iso *self) out_uint32_le(s, self->selectedProtocol); /* selected protocol */ } } - s_mark_end(s); len = (int) (s->end - holdp); @@ -274,7 +308,7 @@ xrdp_iso_incoming(struct xrdp_iso *self) break; case RDP_NEG_REQ: /* rdpNegReq 1 */ self->rdpNegData = 1; - if (xrdp_iso_process_rdpNegReq(self, s) != 0) + if (xrdp_iso_process_rdp_neg_req(self, s) != 0) { g_writeln("xrdp_iso_incoming: xrdp_iso_process_rdpNegReq returned non zero"); return 1; @@ -302,78 +336,8 @@ xrdp_iso_incoming(struct xrdp_iso *self) } } - int serverSecurityLayer = self->mcs_layer->sec_layer->rdp_layer->client_info.security_layer; - /* security layer negotiation */ - if (self->rdpNegData) - { - self->selectedProtocol = PROTOCOL_RDP; /* set default security layer */ - - switch (serverSecurityLayer) - { - case (PROTOCOL_SSL | PROTOCOL_HYBRID | PROTOCOL_HYBRID_EX): - /* server supports tls+hybrid+hybrid_ex */ - if (self->requestedProtocol == (PROTOCOL_SSL | PROTOCOL_HYBRID - | PROTOCOL_HYBRID_EX)) - { - /* client supports tls+hybrid+hybrid_ex */ - self->selectedProtocol = PROTOCOL_SSL; //TODO: change - } - else - { - self->failureCode = SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER; - } - break; - case (PROTOCOL_SSL | PROTOCOL_HYBRID): - /* server supports tls+hybrid */ - if (self->requestedProtocol == (PROTOCOL_SSL | PROTOCOL_HYBRID)) - { - /* client supports tls+hybrid */ - self->selectedProtocol = PROTOCOL_SSL; //TODO: change - } - else - { - self->failureCode = HYBRID_REQUIRED_BY_SERVER; - } - break; - case PROTOCOL_SSL: - /* server supports tls */ - if (self->requestedProtocol & PROTOCOL_SSL) //TODO - { - /* client supports tls */ - self->selectedProtocol = PROTOCOL_SSL; - } - else - { - self->failureCode = SSL_REQUIRED_BY_SERVER; - } - break; - case PROTOCOL_RDP: - /* server supports rdp */ - if (self->requestedProtocol == PROTOCOL_RDP) - { - /* client supports rdp */ - self->selectedProtocol = PROTOCOL_RDP; - } - else - { - self->failureCode = SSL_NOT_ALLOWED_BY_SERVER; - } - break; - default: - /* unsupported protocol */ - g_writeln("xrdp_iso_incoming: unsupported protocol %d", - self->requestedProtocol); - self->failureCode = INCONSISTENT_FLAGS; //TODO: ? - } - } - else if (self->requestedProtocol != serverSecurityLayer) - { - /* enforce server security */ - return 1; - } - - /* set things for tls connection */ - + /* negotiate client-server security layer */ + xrdp_iso_negotiate_security(self); /* send connection confirm back to client */ if (xrdp_iso_send_cc(self) != 0) diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 561acd1f..b0291ef9 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -2151,7 +2151,7 @@ xrdp_sec_incoming(struct xrdp_sec *self) } /* initialize selected security layer */ - if (iso->requestedProtocol > PROTOCOL_RDP) + if (iso->selectedProtocol > PROTOCOL_RDP) { /* init tls security */ DEBUG((" in xrdp_sec_incoming: init tls security"));