diff options
| -rw-r--r-- | libxrdp/libxrdp.c | 23 | ||||
| -rw-r--r-- | libxrdp/libxrdp.h | 4 | ||||
| -rw-r--r-- | libxrdp/xrdp_iso.c | 9 | ||||
| -rw-r--r-- | libxrdp/xrdp_mcs.c | 10 | ||||
| -rw-r--r-- | libxrdp/xrdp_sec.c | 15 | ||||
| -rw-r--r-- | libxrdp/xrdp_tls.c | 179 | 
6 files changed, 230 insertions, 10 deletions
diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c index 6a79e8fb..44e9d775 100644 --- a/libxrdp/libxrdp.c +++ b/libxrdp/libxrdp.c @@ -143,7 +143,12 @@ libxrdp_force_read(struct trans* trans)      init_stream(s, 32 * 1024);      if (trans->do_tls)      { -    	/*TLS*/ +    	g_writeln("libxrdp_force_read: tls data in"); +    	if (xrdp_tls_force_read_s(trans, s, 4) != 0) +    	{ +    		return 0; +    	} +    	g_hexdump(s->data, 4);      }      else if (trans_force_read(trans, 4) != 0) /*TCP*/      { @@ -161,11 +166,25 @@ libxrdp_force_read(struct trans* trans)          g_writeln("libxrdp_force_read: error");          return 0;      } -    if (trans_force_read(trans, bytes - 4) != 0) + +    if (trans->do_tls) +    { +    	g_writeln("libxrdp_force_read: tls data in"); +    	xrdp_tls_force_read_s(trans, s, bytes - 4); +    	g_hexdump(s->data, bytes); +    } +    else if (trans_force_read(trans, bytes - 4) != 0) /*TCP*/      {          g_writeln("libxrdp_force_read: error");          return 0;      } + + +//    if (trans_force_read(trans, bytes - 4) != 0) +//    { +//        g_writeln("libxrdp_force_read: error"); +//        return 0; +//    }      return s;  } diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h index c2800abf..4ce39eb3 100644 --- a/libxrdp/libxrdp.h +++ b/libxrdp/libxrdp.h @@ -312,9 +312,9 @@ xrdp_tls_disconnect(struct xrdp_tls *self);  void APP_CC  xrdp_tls_delete(struct xrdp_tls *self);  int APP_CC -xrdp_tls_read(struct xrdp_tls *tls, unsigned char *data, int length); +xrdp_tls_force_read_s(struct trans *self, struct stream *in_s, int size);  int APP_CC -xrdp_tls_write(struct xrdp_tls *tls, unsigned char *data, int length); +xrdp_tls_force_write_s(struct trans *self, struct stream *out_s);  int APP_CC  compress_rdp(struct xrdp_mppc_enc *enc, tui8 *srcData, int len); diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index b15be2ad..33570e19 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -416,7 +416,14 @@ xrdp_iso_send(struct xrdp_iso *self, struct stream *s)      out_uint8(s, ISO_PDU_DT);      out_uint8(s, 0x80); -    if (trans_force_write_s(self->trans, s) != 0) +    if (self->trans->do_tls) +    { +    	if (xrdp_tls_force_write_s(self->trans, s) != 0) +    	{ +    		return 1; +    	} +    } +    else if (trans_force_write_s(self->trans, s) != 0)      {          return 1;      } diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c index df4f81f5..13d190d2 100644 --- a/libxrdp/xrdp_mcs.c +++ b/libxrdp/xrdp_mcs.c @@ -630,6 +630,7 @@ static int APP_CC  xrdp_mcs_ber_out_header(struct xrdp_mcs *self, struct stream *s,                          int tag_val, int len)  { +	g_writeln("tag_val > 0xff ? %d", tag_val > 0xff);      if (tag_val > 0xff)      {          out_uint16_be(s, tag_val); @@ -639,6 +640,7 @@ xrdp_mcs_ber_out_header(struct xrdp_mcs *self, struct stream *s,          out_uint8(s, tag_val);      } +    g_writeln("len >= 0x80 ? %d", len >= 0x80);      if (len >= 0x80)      {          out_uint8(s, 0x82); @@ -720,7 +722,8 @@ xrdp_mcs_send_connect_response(struct xrdp_mcs *self)      init_stream(s, 8192);      data_len = (int) (self->server_mcs_data->end - self->server_mcs_data->data);      xrdp_iso_init(self->iso_layer, s); -    xrdp_mcs_ber_out_header(self, s, MCS_CONNECT_RESPONSE, data_len + 38); +    //TODO: 36 - tls , 38 - rdp - we should calculate that +    xrdp_mcs_ber_out_header(self, s, MCS_CONNECT_RESPONSE, data_len + 36);      xrdp_mcs_ber_out_header(self, s, BER_TAG_RESULT, 1);      out_uint8(s, 0);      xrdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 1); @@ -750,17 +753,19 @@ xrdp_mcs_incoming(struct xrdp_mcs *self)  {      DEBUG(("  in xrdp_mcs_incoming")); +    /* ISO */      if (xrdp_iso_incoming(self->iso_layer) != 0)      {          return 1;      } -    /* tls */ +    /* TLS */      if (PROTOCOL_SSL & self->iso_layer->selectedProtocol)      {      	g_writeln("xrdp_mcs_incoming: TLS mode!");      	self->sec_layer->crypt_level = CRYPT_LEVEL_NONE;      	self->sec_layer->crypt_method = CRYPT_METHOD_NONE; +    	self->sec_layer->rsa_key_bytes = 0;      	if (xrdp_tls_accept(self->sec_layer->tls) != 0)      	{ @@ -770,6 +775,7 @@ xrdp_mcs_incoming(struct xrdp_mcs *self)      	g_writeln("xrdp_mcs_incoming: ssl_tls_accept done!!!!");      } +    /* MCS */      if (xrdp_mcs_recv_connect_initial(self) != 0)      {          return 1; diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index c908c081..ef1b94f9 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -277,7 +277,8 @@ xrdp_sec_create(struct xrdp_rdp *owner, struct trans *trans, int crypt_level,      self->fastpath_layer = xrdp_fastpath_create(self, trans);      self->chan_layer = xrdp_channel_create(self, self->mcs_layer);      //TODO: add cert to config -    self->tls = xrdp_tls_create(trans, "/opt/xrdpdev/etc/xrdp/pkey.pem", "/opt/xrdpdev/etc/xrdp/cert.pem"); +    self->tls = xrdp_tls_create(trans, "/opt/xrdpdev/etc/xrdp/pkey.pem", +			"/opt/xrdpdev/etc/xrdp/cert.pem");      DEBUG((" out xrdp_sec_create"));      return self;  } @@ -1857,7 +1858,7 @@ xrdp_sec_out_mcs_data(struct xrdp_sec *self)      ud_ptr = s->p; /* User Data */      out_uint16_le(s, SEC_TAG_SRV_INFO); -    if (self->mcs_layer->iso_layer->selectedProtocol != -1) +    if (self->mcs_layer->iso_layer->rdpNegData)      {          out_uint16_le(s, 12); /* len */      } @@ -1869,7 +1870,7 @@ xrdp_sec_out_mcs_data(struct xrdp_sec *self)      out_uint8(s, 0);      out_uint8(s, 8);      out_uint8(s, 0); -    if (self->mcs_layer->iso_layer->selectedProtocol != -1)  +    if (self->mcs_layer->iso_layer->rdpNegData)      {           /* ReqeustedProtocol */          out_uint32_le(s, self->mcs_layer->iso_layer->selectedProtocol); @@ -1952,6 +1953,14 @@ xrdp_sec_out_mcs_data(struct xrdp_sec *self)          out_uint8a(s, self->pub_sig, 64); /* pub sig */          out_uint8s(s, 8); /* pad */      } +    else if (self->rsa_key_bytes == 0) /* no security */ +    { +    	g_writeln("xrdp_sec_out_mcs_data: using no security"); +		out_uint16_le(s, SEC_TAG_SRV_CRYPT); +		out_uint16_le(s, 12); /* len is 12 */ +		out_uint32_le(s, self->crypt_method); +		out_uint32_le(s, self->crypt_level); +	}      else      {          LLOGLN(0, ("xrdp_sec_out_mcs_data: error")); diff --git a/libxrdp/xrdp_tls.c b/libxrdp/xrdp_tls.c index d893ca3c..1f6e847e 100644 --- a/libxrdp/xrdp_tls.c +++ b/libxrdp/xrdp_tls.c @@ -237,3 +237,182 @@ xrdp_tls_write(struct xrdp_tls *tls, unsigned char *data, int length)  	return status;  }  /*****************************************************************************/ +int APP_CC +xrdp_tls_force_read_s(struct trans *self, struct stream *in_s, int size) +{ +    int rcvd; + +    if (self->status != TRANS_STATUS_UP) +    { +        return 1; +    } + +    while (size > 0) +    { +        /* make sure stream has room */ +        if ((in_s->end + size) > (in_s->data + in_s->size)) +        { +            return 1; +        } + +		g_writeln("xrdp_tls_force_read_s: Pending= %d", SSL_pending(self->tls->ssl)); +		rcvd = xrdp_tls_read(self->tls, in_s->end, size); + +        if (rcvd == -1) +        { +            if (g_tcp_last_error_would_block(self->sck)) +            { +                if (!g_tcp_can_recv(self->sck, 100)) +                { +                    /* check for term here */ +                    if (self->is_term != 0) +                    { +                        if (self->is_term()) +                        { +                            /* term */ +                            self->status = TRANS_STATUS_DOWN; +                            return 1; +                        } +                    } +                } +            } +            else +            { +                /* error */ +                self->status = TRANS_STATUS_DOWN; +                return 1; +            } +        } +        else if (rcvd == 0) +        { +            /* error */ +            self->status = TRANS_STATUS_DOWN; +            return 1; +        } +        else +        { +            in_s->end += rcvd; +            size -= rcvd; +        } +    } + +    return 0; +} + +/*****************************************************************************/ +int APP_CC +xrdp_tls_force_write_s(struct trans *self, struct stream *out_s) +{ +    int size; +    int total; +    int sent; + +    if (self->status != TRANS_STATUS_UP) +    { +        return 1; +    } + +    size = (int)(out_s->end - out_s->data); +    g_writeln("packet size= %d", size); +    total = 0; + +    if (send_waiting(self, 1) != 0) +    { +        self->status = TRANS_STATUS_DOWN; +        return 1; +    } + +    while (total < size) +    { +		sent = xrdp_tls_write(self->tls, out_s->data + total, size - total); + +        if (sent == -1) +        { +            if (g_tcp_last_error_would_block(self->sck)) +            { +                if (!g_tcp_can_send(self->sck, 100)) +                { +                    /* check for term here */ +                    if (self->is_term != 0) +                    { +                        if (self->is_term()) +                        { +                            /* term */ +                            self->status = TRANS_STATUS_DOWN; +                            return 1; +                        } +                    } +                } +            } +            else +            { +                /* error */ +                self->status = TRANS_STATUS_DOWN; +                return 1; +            } +        } +        else if (sent == 0) +        { +            /* error */ +            self->status = TRANS_STATUS_DOWN; +            return 1; +        } +        else +        { +            total = total + sent; +        } +    } + +    return 0; +} +/*****************************************************************************/ +int APP_CC +send_waiting(struct trans *self, int block) +{ +    struct stream *temp_s; +    int bytes; +    int sent; +    int timeout; +    int cont; + +    timeout = block ? 100 : 0; +    cont = 1; +    while (cont) +    { +        if (self->wait_s != 0) +        { +            temp_s = self->wait_s; +            if (g_tcp_can_send(self->sck, timeout)) +            { +                bytes = (int) (temp_s->end - temp_s->p); +                sent = xrdp_tls_write(self->tls, temp_s->p, bytes); +                if (sent > 0) +                { +                    temp_s->p += sent; +                    if (temp_s->p >= temp_s->end) +                    { +                        self->wait_s = (struct stream *) (temp_s->next_packet); +                        free_stream(temp_s); +                    } +                } +                else if (sent == 0) +                { +                    return 1; +                } +                else +                { +                    if (!g_tcp_last_error_would_block(self->sck)) +                    { +                        return 1; +                    } +                } +            } +        } +        else +        { +            break; +        } +        cont = block; +    } +    return 0; +}  | 
