Merge branch 'devel' of github.com:/neutrinolabs/xrdp into devel

ulab-next
Laxmikant Rashinkar 11 years ago
commit 1f51f62df9

@ -1,7 +1,7 @@
/** /**
* xrdp: A Remote Desktop Protocol server. * xrdp: A Remote Desktop Protocol server.
* *
* Copyright (C) Jay Sorg 2004-2012 * Copyright (C) Jay Sorg 2004-2014
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -24,6 +24,7 @@
#include <openssl/rc4.h> #include <openssl/rc4.h>
#include <openssl/md5.h> #include <openssl/md5.h>
#include <openssl/sha.h> #include <openssl/sha.h>
#include <openssl/hmac.h>
#include <openssl/bn.h> #include <openssl/bn.h>
#include <openssl/rsa.h> #include <openssl/rsa.h>
@ -157,6 +158,85 @@ ssl_md5_complete(void *md5_info, char *data)
MD5_Final((tui8 *)data, (MD5_CTX *)md5_info); MD5_Final((tui8 *)data, (MD5_CTX *)md5_info);
} }
/*****************************************************************************/
void *APP_CC
ssl_des3_encrypt_info_create(const char *key, const char* ivec)
{
EVP_CIPHER_CTX *des3_ctx;
const tui8 *lkey;
const tui8 *livec;
des3_ctx = (EVP_CIPHER_CTX *) g_malloc(sizeof(EVP_CIPHER_CTX), 1);
EVP_CIPHER_CTX_init(des3_ctx);
lkey = (const tui8 *) key;
livec = (const tui8 *) ivec;
EVP_EncryptInit_ex(des3_ctx, EVP_des_ede3_cbc(), NULL, lkey, livec);
EVP_CIPHER_CTX_set_padding(des3_ctx, 0);
return des3_ctx;
}
/*****************************************************************************/
void *APP_CC
ssl_des3_decrypt_info_create(const char *key, const char* ivec)
{
EVP_CIPHER_CTX *des3_ctx;
const tui8 *lkey;
const tui8 *livec;
des3_ctx = g_malloc(sizeof(EVP_CIPHER_CTX), 1);
EVP_CIPHER_CTX_init(des3_ctx);
lkey = (const tui8 *) key;
livec = (const tui8 *) ivec;
EVP_DecryptInit_ex(des3_ctx, EVP_des_ede3_cbc(), NULL, lkey, livec);
EVP_CIPHER_CTX_set_padding(des3_ctx, 0);
return des3_ctx;
}
/*****************************************************************************/
void APP_CC
ssl_des3_info_delete(void *des3)
{
EVP_CIPHER_CTX *des3_ctx;
des3_ctx = (EVP_CIPHER_CTX *) des3;
if (des3_ctx != 0)
{
EVP_CIPHER_CTX_cleanup(des3_ctx);
}
}
/*****************************************************************************/
int APP_CC
ssl_des3_encrypt(void *des3, int length, const char *in_data, char *out_data)
{
EVP_CIPHER_CTX *des3_ctx;
int len;
const tui8 *lin_data;
tui8 *lout_data;
des3_ctx = (EVP_CIPHER_CTX *) des3;
lin_data = (const tui8 *) in_data;
lout_data = (tui8 *) out_data;
EVP_EncryptUpdate(des3_ctx, lout_data, &len, lin_data, length);
return 0;
}
/*****************************************************************************/
int APP_CC
ssl_des3_decrypt(void *des3, int length, const char *in_data, char *out_data)
{
EVP_CIPHER_CTX *des3_ctx;
int len;
const tui8 *lin_data;
tui8 *lout_data;
des3_ctx = (EVP_CIPHER_CTX *) des3;
lin_data = (const tui8 *) in_data;
lout_data = (tui8 *) out_data;
EVP_DecryptUpdate(des3_ctx, lout_data, &len, lin_data, length);
return 0;
}
/*****************************************************************************/ /*****************************************************************************/
static void APP_CC static void APP_CC
ssl_reverse_it(char *p, int len) ssl_reverse_it(char *p, int len)

@ -1,7 +1,7 @@
/** /**
* xrdp: A Remote Desktop Protocol server. * xrdp: A Remote Desktop Protocol server.
* *
* Copyright (C) Jay Sorg 2004-2013 * Copyright (C) Jay Sorg 2004-2014
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -53,6 +53,16 @@ void APP_CC
ssl_md5_transform(void* md5_info, char* data, int len); ssl_md5_transform(void* md5_info, char* data, int len);
void APP_CC void APP_CC
ssl_md5_complete(void* md5_info, char* data); ssl_md5_complete(void* md5_info, char* data);
void *APP_CC
ssl_des3_encrypt_info_create(const char *key, const char* ivec);
void *APP_CC
ssl_des3_decrypt_info_create(const char *key, const char* ivec);
void APP_CC
ssl_des3_info_delete(void *des3);
int APP_CC
ssl_des3_encrypt(void *des3, int length, const char *in_data, char *out_data);
int APP_CC
ssl_des3_decrypt(void *des3, int length, const char *in_data, char *out_data);
int APP_CC int APP_CC
ssl_mod_exp(char* out, int out_len, char* in, int in_len, ssl_mod_exp(char* out, int out_len, char* in, int in_len,
char* mod, int mod_len, char* exp, int exp_len); char* mod, int mod_len, char* exp, int exp_len);

@ -113,6 +113,14 @@ struct xrdp_client_info
int keyboard_type; int keyboard_type;
int keyboard_subtype; int keyboard_subtype;
int png_codec_id;
int png_prop_len;
char png_prop[64];
int vendor_flags[4];
int mcs_connection_type;
int mcs_early_capability_flags;
}; };
#endif #endif

@ -57,6 +57,7 @@ libxrdp_la_SOURCES = \
xrdp_sec.c \ xrdp_sec.c \
xrdp_tcp.c \ xrdp_tcp.c \
xrdp_bitmap_compress.c \ xrdp_bitmap_compress.c \
xrdp_bitmap32_compress.c \
xrdp_jpeg_compress.c \ xrdp_jpeg_compress.c \
xrdp_orders_rail.c \ xrdp_orders_rail.c \
xrdp_mppc_enc.c xrdp_mppc_enc.c

@ -1,7 +1,7 @@
/** /**
* xrdp: A Remote Desktop Protocol server. * xrdp: A Remote Desktop Protocol server.
* *
* Copyright (C) Jay Sorg 2004-2013 * Copyright (C) Jay Sorg 2004-2014
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -73,6 +73,20 @@ struct xrdp_mcs
struct list* channel_list; struct list* channel_list;
}; };
/* Encryption Methods */
#define CRYPT_METHOD_NONE 0x00000000
#define CRYPT_METHOD_40BIT 0x00000001
#define CRYPT_METHOD_128BIT 0x00000002
#define CRYPT_METHOD_56BIT 0x00000008
#define CRYPT_METHOD_FIPS 0x00000010
/* Encryption Levels */
#define CRYPT_LEVEL_NONE 0x00000000
#define CRYPT_LEVEL_LOW 0x00000001
#define CRYPT_LEVEL_CLIENT_COMPATIBLE 0x00000002
#define CRYPT_LEVEL_HIGH 0x00000003
#define CRYPT_LEVEL_FIPS 0x00000004
/* sec */ /* sec */
struct xrdp_sec struct xrdp_sec
{ {
@ -90,9 +104,9 @@ struct xrdp_sec
char encrypt_key[16]; char encrypt_key[16];
char decrypt_update_key[16]; char decrypt_update_key[16];
char encrypt_update_key[16]; char encrypt_update_key[16];
int rc4_key_size; /* 1 = 40 bit, 2 = 128 bit */ int crypt_method;
int rc4_key_len; /* 8 = 40 bit, 16 = 128 bit */ int rc4_key_len; /* 8 = 40 bit, 16 = 128 bit */
int crypt_level; /* 1, 2, 3 = low, meduim, high */ int crypt_level;
char sign_key[16]; char sign_key[16];
void* decrypt_rc4_info; void* decrypt_rc4_info;
void* encrypt_rc4_info; void* encrypt_rc4_info;
@ -102,6 +116,11 @@ struct xrdp_sec
char pri_exp[64]; char pri_exp[64];
int channel_code; int channel_code;
int multimon; int multimon;
char fips_encrypt_key[24];
char fips_decrypt_key[24];
char fips_sign_key[20];
void* encrypt_fips_info;
void* decrypt_fips_info;
}; };
/* channel */ /* channel */
@ -469,6 +488,11 @@ xrdp_bitmap_compress(char* in_data, int width, int height,
int start_line, struct stream* temp_s, int start_line, struct stream* temp_s,
int e); int e);
int APP_CC int APP_CC
xrdp_bitmap32_compress(char* in_data, int width, int height,
struct stream* s, int bpp, int byte_limit,
int start_line, struct stream* temp_s,
int e);
int APP_CC
xrdp_jpeg_compress(void *handle, char* in_data, int width, int height, xrdp_jpeg_compress(void *handle, char* in_data, int width, int height,
struct stream* s, int bpp, int byte_limit, struct stream* s, int bpp, int byte_limit,
int start_line, struct stream* temp_s, int start_line, struct stream* temp_s,

@ -0,0 +1,32 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* planar bitmap compressor
* 32 bpp compression
*/
#include "libxrdp.h"
/*****************************************************************************/
int APP_CC
xrdp_bitmap32_compress(char *in_data, int width, int height,
struct stream *s, int bpp, int byte_limit,
int start_line, struct stream *temp_s,
int e)
{
return 0;
}

@ -1,7 +1,7 @@
/** /**
* xrdp: A Remote Desktop Protocol server. * xrdp: A Remote Desktop Protocol server.
* *
* Copyright (C) Jay Sorg 2004-2013 * Copyright (C) Jay Sorg 2004-2014
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,13 +16,15 @@
* limitations under the License. * limitations under the License.
* *
* bitmap compressor * bitmap compressor
* This is the original RDP bitmap compression algorithm. Pixel based.
* This does not do 32 bpp compression, nscodec, rfx, etc
*/ */
#include "libxrdp.h" #include "libxrdp.h"
/*****************************************************************************/ /*****************************************************************************/
#define IN_PIXEL8(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \ #define IN_PIXEL8(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \
{ \ do { \
if (in_ptr == 0) \ if (in_ptr == 0) \
{ \ { \
in_pixel = 0; \ in_pixel = 0; \
@ -35,11 +37,11 @@
{ \ { \
in_pixel = in_last_pixel; \ in_pixel = in_last_pixel; \
} \ } \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
#define IN_PIXEL16(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \ #define IN_PIXEL16(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \
{ \ do { \
if (in_ptr == 0) \ if (in_ptr == 0) \
{ \ { \
in_pixel = 0; \ in_pixel = 0; \
@ -52,11 +54,11 @@
{ \ { \
in_pixel = in_last_pixel; \ in_pixel = in_last_pixel; \
} \ } \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
#define IN_PIXEL32(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \ #define IN_PIXEL32(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \
{ \ do { \
if (in_ptr == 0) \ if (in_ptr == 0) \
{ \ { \
in_pixel = 0; \ in_pixel = 0; \
@ -69,12 +71,12 @@
{ \ { \
in_pixel = in_last_pixel; \ in_pixel = in_last_pixel; \
} \ } \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* color */ /* color */
#define OUT_COLOR_COUNT1(in_count, in_s, in_data) \ #define OUT_COLOR_COUNT1(in_count, in_s, in_data) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -98,12 +100,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* color */ /* color */
#define OUT_COLOR_COUNT2(in_count, in_s, in_data) \ #define OUT_COLOR_COUNT2(in_count, in_s, in_data) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -127,12 +129,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* color */ /* color */
#define OUT_COLOR_COUNT3(in_count, in_s, in_data) \ #define OUT_COLOR_COUNT3(in_count, in_s, in_data) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -162,12 +164,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* copy */ /* copy */
#define OUT_COPY_COUNT1(in_count, in_s, in_data) \ #define OUT_COPY_COUNT1(in_count, in_s, in_data) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -192,12 +194,12 @@
} \ } \
in_count = 0; \ in_count = 0; \
init_stream(in_data, 0); \ init_stream(in_data, 0); \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* copy */ /* copy */
#define OUT_COPY_COUNT2(in_count, in_s, in_data) \ #define OUT_COPY_COUNT2(in_count, in_s, in_data) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -225,12 +227,12 @@
} \ } \
in_count = 0; \ in_count = 0; \
init_stream(in_data, 0); \ init_stream(in_data, 0); \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* copy */ /* copy */
#define OUT_COPY_COUNT3(in_count, in_s, in_data) \ #define OUT_COPY_COUNT3(in_count, in_s, in_data) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -258,12 +260,12 @@
} \ } \
in_count = 0; \ in_count = 0; \
init_stream(in_data, 0); \ init_stream(in_data, 0); \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* bicolor */ /* bicolor */
#define OUT_BICOLOR_COUNT1(in_count, in_s, in_color1, in_color2) \ #define OUT_BICOLOR_COUNT1(in_count, in_s, in_color1, in_color2) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count / 2 < 16) \ if (in_count / 2 < 16) \
@ -291,12 +293,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* bicolor */ /* bicolor */
#define OUT_BICOLOR_COUNT2(in_count, in_s, in_color1, in_color2) \ #define OUT_BICOLOR_COUNT2(in_count, in_s, in_color1, in_color2) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count / 2 < 16) \ if (in_count / 2 < 16) \
@ -324,12 +326,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* bicolor */ /* bicolor */
#define OUT_BICOLOR_COUNT3(in_count, in_s, in_color1, in_color2) \ #define OUT_BICOLOR_COUNT3(in_count, in_s, in_color1, in_color2) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count / 2 < 16) \ if (in_count / 2 < 16) \
@ -369,12 +371,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* fill */ /* fill */
#define OUT_FILL_COUNT1(in_count, in_s) \ #define OUT_FILL_COUNT1(in_count, in_s) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -394,12 +396,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* fill */ /* fill */
#define OUT_FILL_COUNT2(in_count, in_s) \ #define OUT_FILL_COUNT2(in_count, in_s) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -419,12 +421,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* fill */ /* fill */
#define OUT_FILL_COUNT3(in_count, in_s) \ #define OUT_FILL_COUNT3(in_count, in_s) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -444,12 +446,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* mix */ /* mix */
#define OUT_MIX_COUNT1(in_count, in_s) \ #define OUT_MIX_COUNT1(in_count, in_s) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -470,12 +472,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* mix */ /* mix */
#define OUT_MIX_COUNT2(in_count, in_s) \ #define OUT_MIX_COUNT2(in_count, in_s) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -496,12 +498,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* mix */ /* mix */
#define OUT_MIX_COUNT3(in_count, in_s) \ #define OUT_MIX_COUNT3(in_count, in_s) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if (in_count < 32) \ if (in_count < 32) \
@ -522,12 +524,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* fom */ /* fom */
#define OUT_FOM_COUNT1(in_count, in_s, in_mask, in_mask_len) \ #define OUT_FOM_COUNT1(in_count, in_s, in_mask, in_mask_len) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if ((in_count % 8) == 0 && in_count < 249) \ if ((in_count % 8) == 0 && in_count < 249) \
@ -551,12 +553,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* fom */ /* fom */
#define OUT_FOM_COUNT2(in_count, in_s, in_mask, in_mask_len) \ #define OUT_FOM_COUNT2(in_count, in_s, in_mask, in_mask_len) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if ((in_count % 8) == 0 && in_count < 249) \ if ((in_count % 8) == 0 && in_count < 249) \
@ -580,12 +582,12 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
/* fill or mix (fom) */ /* fill or mix (fom) */
#define OUT_FOM_COUNT3(in_count, in_s, in_mask, in_mask_len) \ #define OUT_FOM_COUNT3(in_count, in_s, in_mask, in_mask_len) \
{ \ do { \
if (in_count > 0) \ if (in_count > 0) \
{ \ { \
if ((in_count % 8) == 0 && in_count < 249) \ if ((in_count % 8) == 0 && in_count < 249) \
@ -609,7 +611,7 @@
} \ } \
} \ } \
in_count = 0; \ in_count = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
#define TEST_FILL \ #define TEST_FILL \
@ -629,7 +631,7 @@
) \ ) \
) )
#define RESET_COUNTS \ #define RESET_COUNTS \
{ \ do { \
bicolor_count = 0; \ bicolor_count = 0; \
fill_count = 0; \ fill_count = 0; \
color_count = 0; \ color_count = 0; \
@ -637,7 +639,7 @@
fom_count = 0; \ fom_count = 0; \
fom_mask_len = 0; \ fom_mask_len = 0; \
bicolor_spin = 0; \ bicolor_spin = 0; \
} } while (0)
/*****************************************************************************/ /*****************************************************************************/
int APP_CC int APP_CC

@ -1,7 +1,7 @@
/** /**
* xrdp: A Remote Desktop Protocol server. * xrdp: A Remote Desktop Protocol server.
* *
* Copyright (C) Jay Sorg 2004-2013 * Copyright (C) Jay Sorg 2004-2014
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

@ -1,7 +1,7 @@
/** /**
* xrdp: A Remote Desktop Protocol server. * xrdp: A Remote Desktop Protocol server.
* *
* Copyright (C) Jay Sorg 2004-2013 * Copyright (C) Jay Sorg 2004-2014
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -946,16 +946,17 @@ xrdp_mcs_send(struct xrdp_mcs *self, struct stream *s, int chan)
* Internal help function to close the socket * Internal help function to close the socket
* @param self * @param self
*/ */
void close_rdp_socket(struct xrdp_mcs *self) void APP_CC
close_rdp_socket(struct xrdp_mcs *self)
{ {
if(self->iso_layer->tcp_layer) if (self->iso_layer->tcp_layer != 0)
{ {
if(self->iso_layer->tcp_layer->trans) if (self->iso_layer->tcp_layer->trans != 0)
{ {
g_tcp_close(self->iso_layer->tcp_layer->trans->sck); g_tcp_close(self->iso_layer->tcp_layer->trans->sck);
self->iso_layer->tcp_layer->trans->sck = 0 ; self->iso_layer->tcp_layer->trans->sck = 0 ;
g_writeln("xrdp_mcs_disconnect - socket closed"); g_writeln("xrdp_mcs_disconnect - socket closed");
return ; return;
} }
} }
g_writeln("Failed to close socket"); g_writeln("Failed to close socket");

@ -2570,8 +2570,16 @@ xrdp_orders_send_bitmap2(struct xrdp_orders *self,
init_stream(temp_s, 16384); init_stream(temp_s, 16384);
p = s->p; p = s->p;
i = height; i = height;
lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384, if (bpp > 24)
i - 1, temp_s, e); {
lines_sending = xrdp_bitmap32_compress(data, width, height, s, bpp, 16384,
i - 1, temp_s, e);
}
else
{
lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384,
i - 1, temp_s, e);
}
if (lines_sending != height) if (lines_sending != height)
{ {

@ -1,7 +1,7 @@
/** /**
* xrdp: A Remote Desktop Protocol server. * xrdp: A Remote Desktop Protocol server.
* *
* Copyright (C) Jay Sorg 2004-2013 * Copyright (C) Jay Sorg 2004-2014
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -80,6 +80,10 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
{ {
client_info->crypt_level = 3; client_info->crypt_level = 3;
} }
else if (g_strcasecmp(value, "fips") == 0)
{
client_info->crypt_level = 4;
}
else else
{ {
log_message(LOG_LEVEL_ALWAYS,"Warning: Your configured crypt level is" log_message(LOG_LEVEL_ALWAYS,"Warning: Your configured crypt level is"
@ -482,69 +486,6 @@ xrdp_rdp_send_data_update_sync(struct xrdp_rdp *self)
return 0; return 0;
} }
/*****************************************************************************/
static int APP_CC
xrdp_rdp_parse_client_mcs_data(struct xrdp_rdp *self)
{
struct stream *p = (struct stream *)NULL;
int i = 0;
p = &(self->sec_layer->client_mcs_data);
p->p = p->data;
if (!s_check_rem(p, 31 + 2 + 2 + 120 + 2))
{
g_writeln("xrdp_rdp_parse_client_mcs_data: error");
return 1;
}
in_uint8s(p, 31);
in_uint16_le(p, self->client_info.width);
in_uint16_le(p, self->client_info.height);
in_uint8s(p, 120);
self->client_info.bpp = 8;
in_uint16_le(p, i);
switch (i)
{
case 0xca01:
if (!s_check_rem(p, 6 + 1))
{
return 1;
}
in_uint8s(p, 6);
in_uint8(p, i);
if (i > 8)
{
self->client_info.bpp = i;
}
break;
case 0xca02:
self->client_info.bpp = 15;
break;
case 0xca03:
self->client_info.bpp = 16;
break;
case 0xca04:
self->client_info.bpp = 24;
break;
}
if (self->client_info.max_bpp > 0)
{
if (self->client_info.bpp > self->client_info.max_bpp)
{
self->client_info.bpp = self->client_info.max_bpp;
}
}
p->p = p->data;
DEBUG(("client width %d, client height %d bpp %d",
self->client_info.width, self->client_info.height,
self->client_info.bpp));
return 0;
}
/*****************************************************************************/ /*****************************************************************************/
int APP_CC int APP_CC
xrdp_rdp_incoming(struct xrdp_rdp *self) xrdp_rdp_incoming(struct xrdp_rdp *self)
@ -555,19 +496,15 @@ xrdp_rdp_incoming(struct xrdp_rdp *self)
{ {
return 1; return 1;
} }
self->mcs_channel = self->sec_layer->mcs_layer->userid + self->mcs_channel = self->sec_layer->mcs_layer->userid +
MCS_USERCHANNEL_BASE; MCS_USERCHANNEL_BASE;
xrdp_rdp_parse_client_mcs_data(self);
DEBUG(("out xrdp_rdp_incoming mcs channel %d", self->mcs_channel)); DEBUG(("out xrdp_rdp_incoming mcs channel %d", self->mcs_channel));
g_strncpy(self->client_info.client_addr, g_strncpy(self->client_info.client_addr,
self->sec_layer->mcs_layer->iso_layer->tcp_layer->trans->addr, self->sec_layer->mcs_layer->iso_layer->tcp_layer->trans->addr,
sizeof(self->client_info.client_addr) - 1); sizeof(self->client_info.client_addr) - 1);
g_strncpy(self->client_info.client_port, g_strncpy(self->client_info.client_port,
self->sec_layer->mcs_layer->iso_layer->tcp_layer->trans->port, self->sec_layer->mcs_layer->iso_layer->tcp_layer->trans->port,
sizeof(self->client_info.client_port) - 1); sizeof(self->client_info.client_port) - 1);
return 0; return 0;
} }

@ -1,7 +1,7 @@
/** /**
* xrdp: A Remote Desktop Protocol server. * xrdp: A Remote Desktop Protocol server.
* *
* Copyright (C) Jay Sorg 2004-2013 * Copyright (C) Jay Sorg 2004-2014
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,6 +21,12 @@
#include "libxrdp.h" #include "libxrdp.h"
#include "log.h" #include "log.h"
#define LOG_LEVEL 1
#define LLOG(_level, _args) \
do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
#define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
/* some compilers need unsigned char to avoid warnings */ /* some compilers need unsigned char to avoid warnings */
static tui8 g_pad_54[40] = static tui8 g_pad_54[40] =
{ {
@ -100,6 +106,83 @@ static tui8 g_lic3[20] =
0xf3, 0x99, 0x00, 0x00 0xf3, 0x99, 0x00, 0x00
}; };
static const tui8 g_fips_reverse_table[256] =
{
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
};
static const tui8 g_fips_oddparity_table[256] =
{
0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x07, 0x07,
0x08, 0x08, 0x0b, 0x0b, 0x0d, 0x0d, 0x0e, 0x0e,
0x10, 0x10, 0x13, 0x13, 0x15, 0x15, 0x16, 0x16,
0x19, 0x19, 0x1a, 0x1a, 0x1c, 0x1c, 0x1f, 0x1f,
0x20, 0x20, 0x23, 0x23, 0x25, 0x25, 0x26, 0x26,
0x29, 0x29, 0x2a, 0x2a, 0x2c, 0x2c, 0x2f, 0x2f,
0x31, 0x31, 0x32, 0x32, 0x34, 0x34, 0x37, 0x37,
0x38, 0x38, 0x3b, 0x3b, 0x3d, 0x3d, 0x3e, 0x3e,
0x40, 0x40, 0x43, 0x43, 0x45, 0x45, 0x46, 0x46,
0x49, 0x49, 0x4a, 0x4a, 0x4c, 0x4c, 0x4f, 0x4f,
0x51, 0x51, 0x52, 0x52, 0x54, 0x54, 0x57, 0x57,
0x58, 0x58, 0x5b, 0x5b, 0x5d, 0x5d, 0x5e, 0x5e,
0x61, 0x61, 0x62, 0x62, 0x64, 0x64, 0x67, 0x67,
0x68, 0x68, 0x6b, 0x6b, 0x6d, 0x6d, 0x6e, 0x6e,
0x70, 0x70, 0x73, 0x73, 0x75, 0x75, 0x76, 0x76,
0x79, 0x79, 0x7a, 0x7a, 0x7c, 0x7c, 0x7f, 0x7f,
0x80, 0x80, 0x83, 0x83, 0x85, 0x85, 0x86, 0x86,
0x89, 0x89, 0x8a, 0x8a, 0x8c, 0x8c, 0x8f, 0x8f,
0x91, 0x91, 0x92, 0x92, 0x94, 0x94, 0x97, 0x97,
0x98, 0x98, 0x9b, 0x9b, 0x9d, 0x9d, 0x9e, 0x9e,
0xa1, 0xa1, 0xa2, 0xa2, 0xa4, 0xa4, 0xa7, 0xa7,
0xa8, 0xa8, 0xab, 0xab, 0xad, 0xad, 0xae, 0xae,
0xb0, 0xb0, 0xb3, 0xb3, 0xb5, 0xb5, 0xb6, 0xb6,
0xb9, 0xb9, 0xba, 0xba, 0xbc, 0xbc, 0xbf, 0xbf,
0xc1, 0xc1, 0xc2, 0xc2, 0xc4, 0xc4, 0xc7, 0xc7,
0xc8, 0xc8, 0xcb, 0xcb, 0xcd, 0xcd, 0xce, 0xce,
0xd0, 0xd0, 0xd3, 0xd3, 0xd5, 0xd5, 0xd6, 0xd6,
0xd9, 0xd9, 0xda, 0xda, 0xdc, 0xdc, 0xdf, 0xdf,
0xe0, 0xe0, 0xe3, 0xe3, 0xe5, 0xe5, 0xe6, 0xe6,
0xe9, 0xe9, 0xea, 0xea, 0xec, 0xec, 0xef, 0xef,
0xf1, 0xf1, 0xf2, 0xf2, 0xf4, 0xf4, 0xf7, 0xf7,
0xf8, 0xf8, 0xfb, 0xfb, 0xfd, 0xfd, 0xfe, 0xfe
};
static const tui8 g_fips_ivec[8] =
{
0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF
};
/*****************************************************************************/ /*****************************************************************************/
static void APP_CC static void APP_CC
hex_str_to_bin(char *in, char *out, int out_len) hex_str_to_bin(char *in, char *out, int out_len)
@ -145,22 +228,25 @@ xrdp_sec_create(struct xrdp_rdp *owner, struct trans *trans, int crypt_level,
DEBUG((" in xrdp_sec_create")); DEBUG((" in xrdp_sec_create"));
self = (struct xrdp_sec *)g_malloc(sizeof(struct xrdp_sec), 1); self = (struct xrdp_sec *)g_malloc(sizeof(struct xrdp_sec), 1);
self->rdp_layer = owner; self->rdp_layer = owner;
self->rc4_key_size = 1; /* 1 = 40 bit, 2 = 128 bit */ self->crypt_method = CRYPT_METHOD_NONE;
self->crypt_level = 1; /* 1, 2, 3 = low, medium, high */ self->crypt_level = CRYPT_LEVEL_NONE;
switch (crypt_level) switch (crypt_level)
{ {
case 1: case 1: /* low */
self->rc4_key_size = 1; self->crypt_method = CRYPT_METHOD_40BIT;
self->crypt_level = 1; self->crypt_level = CRYPT_LEVEL_LOW;
break;
case 2: /* medium */
self->crypt_method = CRYPT_METHOD_40BIT;
self->crypt_level = CRYPT_LEVEL_CLIENT_COMPATIBLE;
break; break;
case 2: case 3: /* high */
self->rc4_key_size = 1; self->crypt_method = CRYPT_METHOD_128BIT;
self->crypt_level = 2; self->crypt_level = CRYPT_LEVEL_HIGH;
break; break;
case 3: case 4: /* fips */
self->rc4_key_size = 2; self->crypt_method = CRYPT_METHOD_FIPS;
self->crypt_level = 3; self->crypt_level = CRYPT_LEVEL_FIPS;
break; break;
default: default:
g_writeln("Fatal : Illegal crypt_level"); g_writeln("Fatal : Illegal crypt_level");
@ -204,6 +290,8 @@ xrdp_sec_delete(struct xrdp_sec *self)
xrdp_mcs_delete(self->mcs_layer); xrdp_mcs_delete(self->mcs_layer);
ssl_rc4_info_delete(self->decrypt_rc4_info); /* TODO clear all data */ ssl_rc4_info_delete(self->decrypt_rc4_info); /* TODO clear all data */
ssl_rc4_info_delete(self->encrypt_rc4_info); /* TODO clear all data */ ssl_rc4_info_delete(self->encrypt_rc4_info); /* TODO clear all data */
ssl_des3_info_delete(self->decrypt_fips_info);
ssl_des3_info_delete(self->encrypt_fips_info);
g_free(self->client_mcs_data.data); g_free(self->client_mcs_data.data);
g_free(self->server_mcs_data.data); g_free(self->server_mcs_data.data);
/* Crypto information must always be cleared */ /* Crypto information must always be cleared */
@ -221,7 +309,11 @@ xrdp_sec_init(struct xrdp_sec *self, struct stream *s)
return 1; return 1;
} }
if (self->crypt_level > 1) if (self->crypt_level == CRYPT_LEVEL_FIPS)
{
s_push_layer(s, sec_hdr, 4 + 4 + 8);
}
else if (self->crypt_level > CRYPT_LEVEL_LOW)
{ {
s_push_layer(s, sec_hdr, 4 + 8); s_push_layer(s, sec_hdr, 4 + 8);
} }
@ -285,34 +377,48 @@ xrdp_sec_update(char *key, char *update_key, int key_len)
static void APP_CC static void APP_CC
xrdp_sec_decrypt(struct xrdp_sec *self, char *data, int len) xrdp_sec_decrypt(struct xrdp_sec *self, char *data, int len)
{ {
if (self->decrypt_use_count == 4096) if (self->crypt_method == CRYPT_METHOD_FIPS)
{ {
xrdp_sec_update(self->decrypt_key, self->decrypt_update_key, ssl_des3_decrypt(self->decrypt_fips_info, len, data, data);
self->rc4_key_len);
ssl_rc4_set_key(self->decrypt_rc4_info, self->decrypt_key,
self->rc4_key_len);
self->decrypt_use_count = 0;
} }
else
{
if (self->decrypt_use_count == 4096)
{
xrdp_sec_update(self->decrypt_key, self->decrypt_update_key,
self->rc4_key_len);
ssl_rc4_set_key(self->decrypt_rc4_info, self->decrypt_key,
self->rc4_key_len);
self->decrypt_use_count = 0;
}
ssl_rc4_crypt(self->decrypt_rc4_info, data, len); ssl_rc4_crypt(self->decrypt_rc4_info, data, len);
self->decrypt_use_count++; self->decrypt_use_count++;
}
} }
/*****************************************************************************/ /*****************************************************************************/
static void APP_CC static void APP_CC
xrdp_sec_encrypt(struct xrdp_sec *self, char *data, int len) xrdp_sec_encrypt(struct xrdp_sec *self, char *data, int len)
{ {
if (self->encrypt_use_count == 4096) if (self->crypt_method == CRYPT_METHOD_FIPS)
{ {
xrdp_sec_update(self->encrypt_key, self->encrypt_update_key, ssl_des3_encrypt(self->encrypt_fips_info, len, data, data);
self->rc4_key_len);
ssl_rc4_set_key(self->encrypt_rc4_info, self->encrypt_key,
self->rc4_key_len);
self->encrypt_use_count = 0;
} }
else
{
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); ssl_rc4_crypt(self->encrypt_rc4_info, data, len);
self->encrypt_use_count++; self->encrypt_use_count++;
}
} }
/*****************************************************************************/ /*****************************************************************************/
@ -695,6 +801,50 @@ xrdp_sec_hash_16(char *out, char *in, char *salt1, char *salt2)
ssl_md5_info_delete(md5_info); ssl_md5_info_delete(md5_info);
} }
/*****************************************************************************/
static void APP_CC
fips_expand_key_bits(const char *in, char *out)
{
tui8 buf[32];
tui8 c;
int i;
int b;
int p;
int r;
/* reverse every byte in the key */
for (i = 0; i < 21; i++)
{
c = in[i];
buf[i] = g_fips_reverse_table[c];
}
/* insert a zero-bit after every 7th bit */
for (i = 0, b = 0; i < 24; i++, b += 7)
{
p = b / 8;
r = b % 8;
if (r == 0)
{
out[i] = buf[p] & 0xfe;
}
else
{
/* c is accumulator */
c = buf[p] << r;
c |= buf[p + 1] >> (8 - r);
out[i] = c & 0xfe;
}
}
/* reverse every byte */
/* alter lsb so the byte has odd parity */
for (i = 0; i < 24; i++)
{
c = out[i];
c = g_fips_reverse_table[c];
out[i] = g_fips_oddparity_table[c];
}
}
/*****************************************************************************/ /*****************************************************************************/
static void APP_CC static void APP_CC
xrdp_sec_establish_keys(struct xrdp_sec *self) xrdp_sec_establish_keys(struct xrdp_sec *self)
@ -702,6 +852,46 @@ xrdp_sec_establish_keys(struct xrdp_sec *self)
char session_key[48]; char session_key[48];
char temp_hash[48]; char temp_hash[48];
char input[48]; char input[48];
char client_encrypt_key[32];
char client_decrypt_key[32];
const char *fips_ivec;
void *sha1;
if (self->crypt_method == CRYPT_METHOD_FIPS)
{
LLOGLN(0, ("xrdp_sec_establish_keys: fips"));
sha1 = ssl_sha1_info_create();
ssl_sha1_transform(sha1, self->client_random + 16, 16);
ssl_sha1_transform(sha1, self->server_random + 16, 16);
ssl_sha1_complete(sha1, client_encrypt_key);
client_encrypt_key[20] = client_encrypt_key[0];
fips_expand_key_bits(client_encrypt_key, self->fips_encrypt_key);
ssl_sha1_info_delete(sha1);
sha1 = ssl_sha1_info_create();
ssl_sha1_transform(sha1, self->client_random, 16);
ssl_sha1_transform(sha1, self->server_random, 16);
ssl_sha1_complete(sha1, client_decrypt_key);
client_decrypt_key[20] = client_decrypt_key[0];
fips_expand_key_bits(client_decrypt_key, self->fips_decrypt_key);
ssl_sha1_info_delete(sha1);
sha1 = ssl_sha1_info_create();
ssl_sha1_transform(sha1, client_decrypt_key, 20);
ssl_sha1_transform(sha1, client_encrypt_key, 20);
ssl_sha1_complete(sha1, self->fips_sign_key);
ssl_sha1_info_delete(sha1);
fips_ivec = (const char *) g_fips_ivec;
self->encrypt_fips_info =
ssl_des3_encrypt_info_create(self->fips_encrypt_key, fips_ivec);
self->decrypt_fips_info =
ssl_des3_encrypt_info_create(self->fips_decrypt_key, fips_ivec);
}
else
{
LLOGLN(0, ("xrdp_sec_establish_keys: not fips"));
}
g_memcpy(input, self->client_random, 24); g_memcpy(input, self->client_random, 24);
g_memcpy(input + 24, self->server_random, 24); g_memcpy(input + 24, self->server_random, 24);
@ -715,7 +905,7 @@ xrdp_sec_establish_keys(struct xrdp_sec *self)
xrdp_sec_hash_16(self->decrypt_key, session_key + 32, self->client_random, xrdp_sec_hash_16(self->decrypt_key, session_key + 32, self->client_random,
self->server_random); self->server_random);
if (self->rc4_key_size == 1) if (self->crypt_method == CRYPT_METHOD_40BIT)
{ {
xrdp_sec_make_40bit(self->sign_key); xrdp_sec_make_40bit(self->sign_key);
xrdp_sec_make_40bit(self->encrypt_key); xrdp_sec_make_40bit(self->encrypt_key);
@ -758,12 +948,24 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
if (flags & SEC_ENCRYPT) /* 0x08 */ if (flags & SEC_ENCRYPT) /* 0x08 */
{ {
if (!s_check_rem(s, 8)) if (self->crypt_method == CRYPT_METHOD_FIPS)
{ {
return 1; if (!s_check_rem(s, 12))
{
return 1;
}
in_uint8s(s, 12); /* len(2), version(1), pad(1), signature(8) */
xrdp_sec_decrypt(self, s->p, (int)(s->end - s->p));
}
else
{
if (!s_check_rem(s, 8))
{
return 1;
}
in_uint8s(s, 8); /* signature(8) */
xrdp_sec_decrypt(self, s->p, (int)(s->end - s->p));
} }
in_uint8s(s, 8); /* signature */
xrdp_sec_decrypt(self, s->p, (int)(s->end - s->p));
} }
if (flags & SEC_CLIENT_RANDOM) /* 0x01 */ if (flags & SEC_CLIENT_RANDOM) /* 0x01 */
@ -881,7 +1083,10 @@ xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan)
DEBUG((" in xrdp_sec_send")); DEBUG((" in xrdp_sec_send"));
s_pop_layer(s, sec_hdr); s_pop_layer(s, sec_hdr);
if (self->crypt_level > 1) if (self->crypt_level == CRYPT_LEVEL_FIPS)
{
}
else if (self->crypt_level > CRYPT_LEVEL_LOW)
{ {
out_uint32_le(s, SEC_ENCRYPT); out_uint32_le(s, SEC_ENCRYPT);
datalen = (int)((s->end - s->p) - 8); datalen = (int)((s->end - s->p) - 8);
@ -902,6 +1107,235 @@ xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan)
return 0; return 0;
} }
/*****************************************************************************/
/* http://msdn.microsoft.com/en-us/library/cc240510.aspx
2.2.1.3.2 Client Core Data (TS_UD_CS_CORE) */
static int APP_CC
xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec* self, struct stream* s)
{
int colorDepth;
int postBeta2ColorDepth;
int highColorDepth;
int supportedColorDepths;
int earlyCapabilityFlags;
in_uint8s(s, 4); /* version */
in_uint16_le(s, self->rdp_layer->client_info.width);
in_uint16_le(s, self->rdp_layer->client_info.height);
in_uint16_le(s, colorDepth);
g_writeln("colorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp)", colorDepth);
switch (colorDepth)
{
case 0xca00: /* RNS_UD_COLOR_4BPP */
self->rdp_layer->client_info.bpp = 4;
break;
case 0xca01: /* RNS_UD_COLOR_8BPP */
self->rdp_layer->client_info.bpp = 8;
break;
}
in_uint8s(s, 2); /* SASSequence */
in_uint8s(s, 4); /* keyboardLayout */
in_uint8s(s, 4); /* clientBuild */
in_uint8s(s, 32); /* clientName */
in_uint8s(s, 4); /* keyboardType */
in_uint8s(s, 4); /* keyboardSubType */
in_uint8s(s, 4); /* keyboardFunctionKey */
in_uint8s(s, 64); /* imeFileName */
in_uint16_le(s, postBeta2ColorDepth);
g_writeln("postBeta2ColorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp "
"0xca02 15bpp 0xca03 16bpp 0xca04 24bpp)", postBeta2ColorDepth);
switch (postBeta2ColorDepth)
{
case 0xca00: /* RNS_UD_COLOR_4BPP */
self->rdp_layer->client_info.bpp = 4;
break;
case 0xca01: /* RNS_UD_COLOR_8BPP */
self->rdp_layer->client_info.bpp = 8;
break;
case 0xca02: /* RNS_UD_COLOR_16BPP_555 */
self->rdp_layer->client_info.bpp = 15;
break;
case 0xca03: /* RNS_UD_COLOR_16BPP_565 */
self->rdp_layer->client_info.bpp = 16;
break;
case 0xca04: /* RNS_UD_COLOR_24BPP */
self->rdp_layer->client_info.bpp = 24;
break;
}
if (!s_check_rem(s, 2))
{
return 0;
}
in_uint8s(s, 2); /* clientProductId */
if (!s_check_rem(s, 4))
{
return 0;
}
in_uint8s(s, 4); /* serialNumber */
if (!s_check_rem(s, 2))
{
return 0;
}
in_uint16_le(s, highColorDepth);
g_writeln("highColorDepth 0x%4.4x (0x0004 4bpp 0x0008 8bpp 0x000f 15bpp "
"0x0010 16 bpp 0x0018 24bpp)", highColorDepth);
self->rdp_layer->client_info.bpp = highColorDepth;
if (!s_check_rem(s, 2))
{
return 0;
}
in_uint16_le(s, supportedColorDepths);
g_writeln("supportedColorDepths 0x%4.4x (0x0001 24bpp 0x0002 16bpp "
"0x0004 15bpp 0x0008 32bpp)", supportedColorDepths);
if (!s_check_rem(s, 2))
{
return 0;
}
in_uint16_le(s, earlyCapabilityFlags);
self->rdp_layer->client_info.mcs_early_capability_flags = earlyCapabilityFlags;
g_writeln("earlyCapabilityFlags 0x%4.4x (0x0002 want32)",
earlyCapabilityFlags);
if ((earlyCapabilityFlags & 0x0002) && (supportedColorDepths & 0x0008))
{
self->rdp_layer->client_info.bpp = 32;
}
if (!s_check_rem(s, 64))
{
return 0;
}
in_uint8s(s, 64); /* clientDigProductId */
if (!s_check_rem(s, 1))
{
return 0;
}
in_uint8(s, self->rdp_layer->client_info.mcs_connection_type); /* connectionType */
g_writeln("got client client connection type 0x%8.8x",
self->rdp_layer->client_info.mcs_connection_type);
if (!s_check_rem(s, 1))
{
return 0;
}
in_uint8s(s, 1); /* pad1octet */
if (!s_check_rem(s, 4))
{
return 0;
}
in_uint8s(s, 4); /* serverSelectedProtocol */
if (!s_check_rem(s, 4))
{
return 0;
}
in_uint8s(s, 4); /* desktopPhysicalWidth */
if (!s_check_rem(s, 4))
{
return 0;
}
in_uint8s(s, 4); /* desktopPhysicalHeight */
if (!s_check_rem(s, 2))
{
return 0;
}
in_uint8s(s, 2); /* reserved */
return 0;
}
/*****************************************************************************/
static int APP_CC
xrdp_sec_process_mcs_data_CS_SECURITY(struct xrdp_sec *self, struct stream* s)
{
int crypt_method;
int found;
g_writeln("xrdp_sec_process_mcs_data_CS_SECURITY:");
in_uint32_le(s, crypt_method);
if (crypt_method & CRYPT_METHOD_40BIT)
{
g_writeln(" client supports 40 bit encryption");
}
if (crypt_method & CRYPT_METHOD_128BIT)
{
g_writeln(" client supports 128 bit encryption");
}
if (crypt_method & CRYPT_METHOD_56BIT)
{
g_writeln(" client supports 56 bit encryption");
}
if (crypt_method & CRYPT_METHOD_FIPS)
{
g_writeln(" client supports fips encryption");
}
found = 0;
if ((found == 0) &&
(self->crypt_method & CRYPT_METHOD_FIPS) &&
(self->crypt_level == CRYPT_LEVEL_FIPS))
{
if (crypt_method & CRYPT_METHOD_FIPS)
{
g_writeln(" client and server support fips, using fips");
self->crypt_method = CRYPT_METHOD_FIPS;
self->crypt_level = CRYPT_LEVEL_FIPS;
found = 1;
}
}
if ((found == 0) &&
(self->crypt_method & CRYPT_METHOD_128BIT) &&
(self->crypt_level == CRYPT_LEVEL_HIGH))
{
if (crypt_method & CRYPT_METHOD_128BIT)
{
g_writeln(" client and server support high crypt, using "
"high crypt");
self->crypt_method = CRYPT_METHOD_128BIT;
self->crypt_level = CRYPT_LEVEL_HIGH;
found = 1;
}
}
if ((found == 0) &&
(self->crypt_method & CRYPT_METHOD_40BIT) &&
(self->crypt_level == CRYPT_LEVEL_CLIENT_COMPATIBLE))
{
if (crypt_method & CRYPT_METHOD_40BIT)
{
g_writeln(" client and server support medium crypt, using "
"medium crypt");
self->crypt_method = CRYPT_METHOD_40BIT;
self->crypt_level = CRYPT_LEVEL_CLIENT_COMPATIBLE;
found = 1;
}
}
if ((found == 0) &&
(self->crypt_method & CRYPT_METHOD_40BIT) &&
(self->crypt_level == CRYPT_LEVEL_LOW))
{
if (crypt_method & CRYPT_METHOD_40BIT)
{
g_writeln(" client and server support low crypt, using "
"low crypt");
self->crypt_method = CRYPT_METHOD_40BIT;
self->crypt_level = CRYPT_LEVEL_LOW;
found = 1;
}
}
if (found == 0)
{
g_writeln(" no security");
}
return 0;
}
/*****************************************************************************/ /*****************************************************************************/
/* this adds the mcs channels in the list of channels to be used when /* this adds the mcs channels in the list of channels to be used when
creating the server mcs data */ creating the server mcs data */
@ -951,6 +1385,7 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
return 0; return 0;
} }
/*****************************************************************************/ /*****************************************************************************/
/* reads the client monitors data */ /* reads the client monitors data */
static int APP_CC static int APP_CC
@ -1006,6 +1441,7 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
} }
return 0; return 0;
} }
/*****************************************************************************/ /*****************************************************************************/
/* process client mcs data, we need some things in here to create the server /* process client mcs data, we need some things in here to create the server
mcs data */ mcs data */
@ -1035,40 +1471,71 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self)
if (size < 4 || !s_check_rem(s, size - 4)) if (size < 4 || !s_check_rem(s, size - 4))
{ {
g_writeln("error in xrdp_sec_process_mcs_data tag %d size %d", LLOGLN(0, ("error in xrdp_sec_process_mcs_data tag %d size %d",
tag, size); tag, size));
break; break;
} }
LLOGLN(10, ("xrdp_sec_process_mcs_data: 0x%8.8x", tag));
switch (tag) switch (tag)
{ {
case SEC_TAG_CLI_INFO: case SEC_TAG_CLI_INFO: /* CS_CORE 0xC001 */
if (xrdp_sec_process_mcs_data_CS_CORE(self, s) != 0)
{
return 1;
}
break; break;
case SEC_TAG_CLI_CRYPT: case SEC_TAG_CLI_CRYPT: /* CS_SECURITY 0xC002 */
if (xrdp_sec_process_mcs_data_CS_SECURITY(self, s) != 0)
{
return 1;
}
break; break;
case SEC_TAG_CLI_CHANNELS: case SEC_TAG_CLI_CHANNELS: /* CS_NET 0xC003 */
if (xrdp_sec_process_mcs_data_channels(self, s) != 0) if (xrdp_sec_process_mcs_data_channels(self, s) != 0)
{ {
return 1; return 1;
} }
break; break;
case SEC_TAG_CLI_4: case SEC_TAG_CLI_4: /* CS_CLUSTER 0xC004 */
break; break;
case SEC_TAG_CLI_MONITOR: case SEC_TAG_CLI_MONITOR: /* CS_MONITOR 0xC005 */
if (xrdp_sec_process_mcs_data_monitors(self, s) != 0) if (xrdp_sec_process_mcs_data_monitors(self, s) != 0)
{ {
return 1; return 1;
} }
break; break;
/* CS_MCS_MSGCHANNEL 0xC006
CS_MONITOR_EX 0xC008
CS_MULTITRANSPORT 0xC00A
SC_CORE 0x0C01
SC_SECURITY 0x0C02
SC_NET 0x0C03
SC_MCS_MSGCHANNEL 0x0C04
SC_MULTITRANSPORT 0x0C08 */
default: default:
g_writeln("error unknown xrdp_sec_process_mcs_data tag %d size %d", LLOGLN(0, ("error unknown xrdp_sec_process_mcs_data tag %d "
tag, size); "size %d", tag, size));
break; break;
} }
s->p = hold_p + size; s->p = hold_p + size;
} }
if (self->rdp_layer->client_info.max_bpp > 0)
{
if (self->rdp_layer->client_info.bpp >
self->rdp_layer->client_info.max_bpp)
{
LLOGLN(0, ("xrdp_rdp_parse_client_mcs_data: client asked "
"for %dbpp connection but configuration is limited "
"to %dbpp", self->rdp_layer->client_info.bpp,
self->rdp_layer->client_info.max_bpp));
self->rdp_layer->client_info.bpp =
self->rdp_layer->client_info.max_bpp;
}
}
/* set p to beginning */ /* set p to beginning */
s->p = s->data; s->p = s->data;
return 0; return 0;
@ -1152,9 +1619,8 @@ xrdp_sec_out_mcs_data(struct xrdp_sec *self)
out_uint16_le(s, SEC_TAG_SRV_CRYPT); out_uint16_le(s, SEC_TAG_SRV_CRYPT);
out_uint16_le(s, 0x00ec); /* len is 236 */ out_uint16_le(s, 0x00ec); /* len is 236 */
out_uint32_le(s, self->rc4_key_size); /* key len 1 = 40 bit 2 = 128 bit */ out_uint32_le(s, self->crypt_method);
out_uint32_le(s, self->crypt_level); /* crypt level 1 = low 2 = medium */ out_uint32_le(s, self->crypt_level);
/* 3 = high */
out_uint32_le(s, 32); /* 32 bytes random len */ out_uint32_le(s, 32); /* 32 bytes random len */
out_uint32_le(s, 0xb8); /* 184 bytes rsa info(certificate) len */ out_uint32_le(s, 0xb8); /* 184 bytes rsa info(certificate) len */
out_uint8a(s, self->server_random, 32); out_uint8a(s, self->server_random, 32);

@ -30,6 +30,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "rdpPri.h" #include "rdpPri.h"
/* PIXMAN_a8r8g8b8 */
#define XRDP_a8r8g8b8 \
((32 << 24) | (2 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8)
#define PixelDPI 100 #define PixelDPI 100
#define PixelToMM(_size) (((_size) * 254 + (PixelDPI) * 5) / ((PixelDPI) * 10)) #define PixelToMM(_size) (((_size) * 254 + (PixelDPI) * 5) / ((PixelDPI) * 10))

@ -38,65 +38,117 @@
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0) do { if (_level < LOG_LEVEL) { ErrorF _args ; ErrorF("\n"); } } while (0)
/** /******************************************************************************/
* Copy an array of rectangles from one memory area to another static Bool
*****************************************************************************/ rdpCapture0(RegionPtr in_reg, RegionPtr out_reg,
void *src, int src_width, int src_height,
Bool rdpCapture(RegionPtr in_reg, RegionPtr out_reg, int src_stride, int src_format,
void *src, int src_width, int src_height, int src_stride, int src_format, void *dst, int dst_width, int dst_height,
void *dst, int dst_width, int dst_height, int dst_stride, int dst_format, int dst_stride, int dst_format, int max_rects)
int mode)
{ {
BoxRec rect; BoxPtr prects;
char *src_rect; BoxRec rect;
char *dst_rect; RegionRec reg;
int num_regions; char *src_rect;
int bpp; char *dst_rect;
int width; int num_regions;
int height; int bytespp;
int offset; int width;
int bytes; int height;
int i; int src_offset;
int j; int dst_offset;
int bytes;
/* int i;
* note: mode = 0: default, one is to one copy int j;
* xxx_format = 0: default, 4 bytes per pixel Bool rv;
*/
LLOGLN(10, ("rdpCapture0:"));
/* for now we only handle defaults */
rv = TRUE;
/* number of rectangles to copy */
num_regions = REGION_NUM_RECTS(in_reg); rect.x1 = 0;
rect.y1 = 0;
/* get bytes per pixel */ rect.x2 = min(dst_width, src_width);
bpp = src_stride / src_width; rect.y2 = min(dst_height, src_height);
rdpRegionInit(&reg, &rect, 0);
for (i = 0; i < num_regions; i++) rdpRegionIntersect(&reg, in_reg, &reg);
num_regions = REGION_NUM_RECTS(&reg);
if (num_regions > max_rects)
{ {
/* get rect to copy */ num_regions = 1;
rect = REGION_RECTS(in_reg)[i]; prects = rdpRegionExtents(&reg);
rdpRegionUninit(out_reg);
/* get rect dimensions */ rdpRegionInit(out_reg, prects, 0);
width = rect.x2 - rect.x1; }
height = rect.y2 - rect.y1; else
{
/* point to start of each rect in respective memory */ prects = REGION_RECTS(&reg);
offset = rect.y1 * src_stride + rect.x1 * bpp; rdpRegionCopy(out_reg, &reg);
src_rect = src + offset; }
dst_rect = dst + offset;
/* bytes per line */ if ((src_format == XRDP_a8r8g8b8) && (dst_format == XRDP_a8r8g8b8))
bytes = width * bpp; {
bytespp = 4;
/* copy one line at a time */ for (i = 0; i < num_regions; i++)
for (j = 0; j < height; j++)
{ {
memcpy(dst_rect, src_rect, bytes); /* get rect to copy */
src_rect += src_stride; rect = prects[i];
dst_rect += src_stride;
/* get rect dimensions */
width = rect.x2 - rect.x1;
height = rect.y2 - rect.y1;
/* point to start of each rect in respective memory */
src_offset = rect.y1 * src_stride + rect.x1 * bytespp;
dst_offset = rect.y1 * dst_stride + rect.x1 * bytespp;
src_rect = src + src_offset;
dst_rect = dst + dst_offset;
/* bytes per line */
bytes = width * bytespp;
/* copy one line at a time */
for (j = 0; j < height; j++)
{
memcpy(dst_rect, src_rect, bytes);
src_rect += src_stride;
dst_rect += dst_stride;
}
} }
} }
else
{
LLOGLN(0, ("rdpCapture0: unimp color conversion"));
}
rdpRegionUninit(&reg);
return rv;
}
return rdpRegionCopy(out_reg, in_reg); /**
* Copy an array of rectangles from one memory area to another
*****************************************************************************/
Bool
rdpCapture(RegionPtr in_reg, RegionPtr out_reg,
void *src, int src_width, int src_height,
int src_stride, int src_format,
void *dst, int dst_width, int dst_height,
int dst_stride, int dst_format, int mode)
{
LLOGLN(10, ("rdpCapture:"));
switch (mode)
{
case 0:
return rdpCapture0(in_reg, out_reg,
src, src_width, src_height,
src_stride, src_format,
dst, dst_width, dst_height,
dst_stride, dst_format, 15);
default:
LLOGLN(0, ("rdpCapture: unimp mode"));
break;
}
return TRUE;
} }

@ -18,7 +18,10 @@
* Routines to copy regions from framebuffer to shared memory * Routines to copy regions from framebuffer to shared memory
*/ */
Bool rdpCapture(RegionPtr in_reg, RegionPtr out_reg, Bool
void *src, int src_width, int src_height, int src_stride, int src_format, rdpCapture(RegionPtr in_reg, RegionPtr out_reg,
void *dst, int dst_width, int dst_height, int dst_stride, int dst_format, void *src, int src_width, int src_height,
int mode) int src_stride, int src_format,
void *dst, int dst_width, int dst_height,
int dst_stride, int dst_format,
int mode);

@ -42,6 +42,7 @@ Client connection to xrdp
#include "rdpMisc.h" #include "rdpMisc.h"
#include "rdpInput.h" #include "rdpInput.h"
#include "rdpReg.h" #include "rdpReg.h"
#include "rdpCapture.h"
#define LOG_LEVEL 1 #define LOG_LEVEL 1
#define LLOGLN(_level, _args) \ #define LLOGLN(_level, _args) \
@ -116,6 +117,8 @@ rdpClientConGotConnection(ScreenPtr pScreen, rdpPtr dev)
LLOGLN(0, ("rdpClientConGotConnection:")); LLOGLN(0, ("rdpClientConGotConnection:"));
clientCon = (rdpClientCon *) g_malloc(sizeof(rdpClientCon), 1); clientCon = (rdpClientCon *) g_malloc(sizeof(rdpClientCon), 1);
clientCon->dev = dev; clientCon->dev = dev;
dev->do_dirty_ons = 1;
make_stream(clientCon->in_s); make_stream(clientCon->in_s);
init_stream(clientCon->in_s, 8192); init_stream(clientCon->in_s, 8192);
make_stream(clientCon->out_s); make_stream(clientCon->out_s);
@ -262,6 +265,8 @@ rdpClientConDisconnect(rdpPtr dev, rdpClientCon *clientCon)
dev->clientConTail = plcli; dev->clientConTail = plcli;
} }
} }
LLOGLN(0, ("rdpClientConDisconnect: clientCon removed from "
"dev list"));
break; break;
} }
plcli = pcli; plcli = pcli;
@ -797,6 +802,24 @@ rdpClientConProcessMsgClientRegion(rdpPtr dev, rdpClientCon *clientCon)
return 0; return 0;
} }
/******************************************************************************/
static int
rdpClientConProcessMsgClientRegionEx(rdpPtr dev, rdpClientCon *clientCon)
{
struct stream *s;
int flags;
LLOGLN(10, ("rdpClientConProcessMsgClientRegionEx:"));
s = clientCon->in_s;
in_uint32_le(s, flags);
in_uint32_le(s, clientCon->rect_id_ack);
LLOGLN(10, ("rdpClientConProcessMsgClientRegionEx: flags 0x%8.8x", flags));
LLOGLN(10, ("rdpClientConProcessMsgClientRegionEx: rect_id %d "
"rect_id_ack %d", clientCon->rect_id, clientCon->rect_id_ack));
return 0;
}
/******************************************************************************/ /******************************************************************************/
static int static int
rdpClientConProcessMsg(rdpPtr dev, rdpClientCon *clientCon) rdpClientConProcessMsg(rdpPtr dev, rdpClientCon *clientCon)
@ -819,6 +842,9 @@ rdpClientConProcessMsg(rdpPtr dev, rdpClientCon *clientCon)
case 105: /* client region */ case 105: /* client region */
rdpClientConProcessMsgClientRegion(dev, clientCon); rdpClientConProcessMsgClientRegion(dev, clientCon);
break; break;
case 106: /* client region ex */
rdpClientConProcessMsgClientRegionEx(dev, clientCon);
break;
default: default:
break; break;
} }
@ -1848,40 +1874,104 @@ rdpClientConCheckDirtyScreen(rdpPtr dev, rdpClientCon *clientCon)
return 0; return 0;
} }
/******************************************************************************/
static int
rdpClientConSendPaintRectShmEx(rdpPtr dev, rdpClientCon *clientCon,
struct image_data *id,
RegionPtr dirtyReg, RegionPtr copyReg)
{
int index;
int size;
int num_rects_d;
int num_rects_c;
struct stream *s;
BoxRec box;
rdpClientConBeginUpdate(dev, clientCon);
num_rects_d = REGION_NUM_RECTS(dirtyReg);
num_rects_c = REGION_NUM_RECTS(copyReg);
size = 2 + 2 + 2 + num_rects_d * 8 + 2 + num_rects_c * 8;
size += 4 + 4 + 4 + 4 + 2 + 2;
rdpClientConPreCheck(dev, clientCon, size);
s = clientCon->out_s;
out_uint16_le(s, 61);
out_uint16_le(s, size);
clientCon->count++;
out_uint16_le(s, num_rects_d);
for (index = 0; index < num_rects_d; index++)
{
box = REGION_RECTS(dirtyReg)[index];
out_uint16_le(s, box.x1);
out_uint16_le(s, box.y1);
out_uint16_le(s, box.x2 - box.x1);
out_uint16_le(s, box.y2 - box.y1);
}
out_uint16_le(s, num_rects_c);
for (index = 0; index < num_rects_c; index++)
{
box = REGION_RECTS(copyReg)[index];
out_uint16_le(s, box.x1);
out_uint16_le(s, box.y1);
out_uint16_le(s, box.x2 - box.x1);
out_uint16_le(s, box.y2 - box.y1);
}
out_uint32_le(s, 0);
clientCon->rect_id++;
out_uint32_le(s, clientCon->rect_id);
out_uint32_le(s, id->shmem_id);
out_uint32_le(s, id->shmem_offset);
out_uint16_le(s, clientCon->rdp_width);
out_uint16_le(s, clientCon->rdp_height);
rdpClientConEndUpdate(dev, clientCon);
return 0;
}
/******************************************************************************/ /******************************************************************************/
static CARD32 static CARD32
rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg) rdpDeferredUpdateCallback(OsTimerPtr timer, CARD32 now, pointer arg)
{ {
rdpClientCon *clientCon; rdpClientCon *clientCon;
int num_rects; RegionRec reg;
int index; struct image_data id;
BoxRec box;
LLOGLN(10, ("rdpDeferredUpdateCallback:")); LLOGLN(10, ("rdpDeferredUpdateCallback:"));
clientCon = (rdpClientCon *) arg; clientCon = (rdpClientCon *) arg;
if (clientCon->rect_id != clientCon->rect_id_ack) if (clientCon->rect_id != clientCon->rect_id_ack)
{ {
LLOGLN(10, ("rdpDeferredUpdateCallback: reschedual")); LLOGLN(0, ("rdpDeferredUpdateCallback: reschedual"));
clientCon->updateTimer = TimerSet(clientCon->updateTimer, 0, 40, clientCon->updateTimer = TimerSet(clientCon->updateTimer, 0, 40,
rdpDeferredUpdateCallback, clientCon); rdpDeferredUpdateCallback, clientCon);
return 0; return 0;
} }
else
clientCon->updateSchedualed = FALSE;
rdpClientConBeginUpdate(clientCon->dev, clientCon);
num_rects = REGION_NUM_RECTS(clientCon->dirtyRegion);
for (index = 0; index < num_rects; index++)
{ {
box = REGION_RECTS(clientCon->dirtyRegion)[index]; LLOGLN(10, ("rdpDeferredUpdateCallback: sending"));
LLOGLN(10, (" x1 %d y1 %d x2 %d y2 %d cx %d cy %d", box.x1, box.y1,
box.x2, box.y2, box.x2 - box.x1, box.y2 - box.y1));
rdpClientConSendArea(clientCon->dev, clientCon, NULL, box.x1, box.y1,
box.x2 - box.x1, box.y2 - box.y1);
} }
rdpClientConEndUpdate(clientCon->dev, clientCon); rdpClientConGetScreenImageRect(clientCon->dev, clientCon, &id);
LLOGLN(10, ("rdpDeferredUpdateCallback: rdp_width %d rdp_height %d "
"rdp_Bpp %d screen width %d screen height %d",
clientCon->rdp_width, clientCon->rdp_height, clientCon->rdp_Bpp,
id.width, id.height));
clientCon->updateSchedualed = FALSE;
rdpRegionInit(&reg, NullBox, 0);
rdpCapture(clientCon->dirtyRegion, &reg,
id.pixels, id.width, id.height,
id.lineBytes, XRDP_a8r8g8b8,
id.shmem_pixels, clientCon->rdp_width, clientCon->rdp_height,
clientCon->rdp_width * clientCon->rdp_Bpp , XRDP_a8r8g8b8, 0);
rdpClientConSendPaintRectShmEx(clientCon->dev, clientCon, &id,
clientCon->dirtyRegion, &reg);
rdpRegionDestroy(clientCon->dirtyRegion); rdpRegionDestroy(clientCon->dirtyRegion);
clientCon->dirtyRegion = rdpRegionCreate(NullBox, 0); clientCon->dirtyRegion = rdpRegionCreate(NullBox, 0);
rdpRegionUninit(&reg);
return 0; return 0;
} }
@ -1890,6 +1980,8 @@ int
rdpClientConAddDirtyScreenReg(rdpPtr dev, rdpClientCon *clientCon, rdpClientConAddDirtyScreenReg(rdpPtr dev, rdpClientCon *clientCon,
RegionPtr reg) RegionPtr reg)
{ {
LLOGLN(10, ("rdpClientConAddDirtyScreenReg:"));
rdpRegionUnion(clientCon->dirtyRegion, clientCon->dirtyRegion, reg); rdpRegionUnion(clientCon->dirtyRegion, clientCon->dirtyRegion, reg);
if (clientCon->updateSchedualed == FALSE) if (clientCon->updateSchedualed == FALSE)
{ {
@ -1969,7 +2061,6 @@ rdpClientConSendArea(rdpPtr dev, rdpClientCon *clientCon,
{ {
struct image_data lid; struct image_data lid;
BoxRec box; BoxRec box;
RegionRec reg;
int ly; int ly;
int size; int size;
char *src; char *src;
@ -2069,9 +2160,7 @@ rdpClientConSendArea(rdpPtr dev, rdpClientCon *clientCon,
out_uint16_le(s, id->height); out_uint16_le(s, id->height);
out_uint16_le(s, x); out_uint16_le(s, x);
out_uint16_le(s, y); out_uint16_le(s, y);
rdpRegionInit(&reg, &box, 0); rdpRegionUnionRect(clientCon->shmRegion, &box);
rdpRegionUnion(clientCon->shmRegion, clientCon->shmRegion, &reg);
rdpRegionUninit(&reg);
return; return;
} }
} }

@ -30,7 +30,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <xf86.h> #include <xf86.h>
#include <xf86_OSproc.h> #include <xf86_OSproc.h>
#include "mipict.h" #include <mipict.h>
#include <picture.h> #include <picture.h>
#include "rdp.h" #include "rdp.h"

@ -402,6 +402,10 @@ server_composite(struct xrdp_mod* mod, int srcidx, int srcformat, int srcwidth,
int srcx, int srcy, int mskx, int msky, int srcx, int srcy, int mskx, int msky,
int dstx, int dsty, int width, int height, int dstformat); int dstx, int dsty, int width, int height, int dstformat);
int DEFAULT_CC int DEFAULT_CC
server_paint_rects(struct xrdp_mod* mod, int num_drects, short *drects,
int num_crects, short *crects,
char *data, int width, int height, int flags);
int DEFAULT_CC
server_set_pointer(struct xrdp_mod* mod, int x, int y, server_set_pointer(struct xrdp_mod* mod, int x, int y,
char* data, char* mask); char* data, char* mask);
int DEFAULT_CC int DEFAULT_CC

@ -417,6 +417,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self)
self->mod->server_create_os_surface_bpp = server_create_os_surface_bpp; self->mod->server_create_os_surface_bpp = server_create_os_surface_bpp;
self->mod->server_paint_rect_bpp = server_paint_rect_bpp; self->mod->server_paint_rect_bpp = server_paint_rect_bpp;
self->mod->server_composite = server_composite; self->mod->server_composite = server_composite;
self->mod->server_paint_rects = server_paint_rects;
} }
} }
@ -2136,6 +2137,38 @@ server_composite(struct xrdp_mod* mod, int srcidx, int srcformat,
return 0; return 0;
} }
/*****************************************************************************/
int DEFAULT_CC
server_paint_rects(struct xrdp_mod* mod, int num_drects, short *drects,
int num_crects, short *crects,
char *data, int width, int height, int flags)
{
struct xrdp_wm* wm;
struct xrdp_painter* p;
struct xrdp_bitmap *b;
short *s;
int index;
//g_writeln("server_paint_rects:");
wm = (struct xrdp_wm*)(mod->wm);
p = (struct xrdp_painter*)(mod->painter);
if (p == 0)
{
return 0;
}
b = xrdp_bitmap_create_with_data(width, height, wm->screen->bpp,
data, wm);
s = crects;
for (index = 0; index < num_crects; index++)
{
xrdp_painter_copy(p, b, wm->target_surface, s[0], s[1], s[2], s[3],
s[0], s[1]);
s += 4;
}
xrdp_bitmap_delete(b);
return 0;
}
/*****************************************************************************/ /*****************************************************************************/
int DEFAULT_CC int DEFAULT_CC
server_set_pointer(struct xrdp_mod *mod, int x, int y, server_set_pointer(struct xrdp_mod *mod, int x, int y,

@ -139,7 +139,11 @@ struct xrdp_mod
int srcx, int srcy, int mskx, int msky, int srcx, int srcy, int mskx, int msky,
int dstx, int dsty, int width, int height, int dstx, int dsty, int width, int height,
int dstformat); int dstformat);
long server_dumby[100 - 42]; /* align, 100 minus the number of server int (*server_paint_rects)(struct xrdp_mod* v,
int num_drects, short *drects,
int num_crects, short *crects,
char *data, int width, int height, int flags);
long server_dumby[100 - 43]; /* align, 100 minus the number of server
functions above */ functions above */
/* common */ /* common */
long handle; /* pointer to self as int */ long handle; /* pointer to self as int */

@ -1174,20 +1174,53 @@ send_paint_rect_ex_ack(struct mod *mod, int flags, int frame_id)
/******************************************************************************/ /******************************************************************************/
/* return error */ /* return error */
static int APP_CC static int APP_CC
process_server_paint_rect_shmem_ex(struct mod *mod, struct stream *s) process_server_paint_rect_shmem_ex(struct mod *amod, struct stream *s)
{ {
int num_rects; int num_drects;
int num_crects;
int flags; int flags;
int frame_id; int frame_id;
int shmem_id; int shmem_id;
int shmem_offset; int shmem_offset;
int width; int width;
int height; int height;
int x;
int y;
int cx;
int cy;
int index;
int rv;
tsi16 *ldrects;
tsi16 *ldrects1;
tsi16 *lcrects;
tsi16 *lcrects1;
char *bmpdata;
in_uint16_le(s, num_rects); /* dirty pixels */
in_uint8s(s, num_rects * 8); in_uint16_le(s, num_drects);
in_uint16_le(s, num_rects); ldrects = (tsi16 *) g_malloc(2 * 4 * num_drects, 0);
in_uint8s(s, num_rects * 8); ldrects1 = ldrects;
for (index = 0; index < num_drects; index++)
{
in_sint16_le(s, ldrects1[0]);
in_sint16_le(s, ldrects1[1]);
in_sint16_le(s, ldrects1[2]);
in_sint16_le(s, ldrects1[3]);
ldrects1 += 4;
}
/* copied pixels */
in_uint16_le(s, num_crects);
lcrects = (tsi16 *) g_malloc(2 * 4 * num_crects, 0);
lcrects1 = lcrects;
for (index = 0; index < num_crects; index++)
{
in_sint16_le(s, lcrects1[0]);
in_sint16_le(s, lcrects1[1]);
in_sint16_le(s, lcrects1[2]);
in_sint16_le(s, lcrects1[3]);
lcrects1 += 4;
}
in_uint32_le(s, flags); in_uint32_le(s, flags);
in_uint32_le(s, frame_id); in_uint32_le(s, frame_id);
@ -1197,7 +1230,35 @@ process_server_paint_rect_shmem_ex(struct mod *mod, struct stream *s)
in_uint16_le(s, width); in_uint16_le(s, width);
in_uint16_le(s, height); in_uint16_le(s, height);
send_paint_rect_ex_ack(mod, flags, frame_id); bmpdata = 0;
if (flags == 0) /* screen */
{
if (amod->screen_shmem_id == 0)
{
amod->screen_shmem_id = shmem_id;
amod->screen_shmem_pixels = g_shmat(amod->screen_shmem_id);
}
if (amod->screen_shmem_pixels != 0)
{
bmpdata = amod->screen_shmem_pixels + shmem_offset;
}
}
if (bmpdata != 0)
{
rv = amod->server_paint_rects(amod, num_drects, ldrects,
num_crects, lcrects,
bmpdata, width, height, 0);
}
else
{
rv = 1;
}
send_paint_rect_ex_ack(amod, flags, frame_id);
g_free(lcrects);
g_free(ldrects);
return 0; return 0;
} }

@ -133,8 +133,12 @@ struct mod
int mskformat, int mskwidth, int mskrepeat, int op, int mskformat, int mskwidth, int mskrepeat, int op,
int srcx, int srcy, int mskx, int msky, int srcx, int srcy, int mskx, int msky,
int dstx, int dsty, int width, int height, int dstformat); int dstx, int dsty, int width, int height, int dstformat);
int (*server_paint_rects)(struct mod* v,
int num_drects, short *drects,
int num_crects, short *crects,
char *data, int width, int height, int flags);
tbus server_dumby[100 - 42]; /* align, 100 minus the number of server tbus server_dumby[100 - 43]; /* align, 100 minus the number of server
functions above */ functions above */
/* common */ /* common */
tbus handle; /* pointer to self as long */ tbus handle; /* pointer to self as long */

Loading…
Cancel
Save