Update MSTSC with latest (1.8.3) rdesktop version.
Patch by 'hater', for more details see CORE-9013 #resolve #comment Committed, thanks!

svn path=/trunk/; revision=66502
This commit is contained in:
Hermès Bélusca-Maïto 2015-02-28 20:28:09 +00:00
parent 014d37e58e
commit 38ecef1f2b
26 changed files with 2747 additions and 1334 deletions

View file

@ -1,5 +1,6 @@
list(APPEND SOURCE
asn.c
bitmap.c
bsops.c
cache.c
@ -19,6 +20,14 @@ list(APPEND SOURCE
tcp.c
uimain.c
win32.c
bsops.h
constants.h
orders.h
proto.h
rdesktop.h
resource.h
types.h
uimain.h
precomp.h)
add_executable(mstsc ${SOURCE} rdc.rc)

View file

@ -0,0 +1,109 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
ASN.1 utility functions
Copyright 2012 Henrik Andersson <hean01@cendio.se> for Cendio AB
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "precomp.h"
/* Parse an ASN.1 BER header */
RD_BOOL
ber_parse_header(STREAM s, int tagval, int *length)
{
int tag, len;
if (tagval > 0xff)
{
in_uint16_be(s, tag);
}
else
{
in_uint8(s, tag);
}
if (tag != tagval)
{
error("expected tag %d, got %d\n", tagval, tag);
return False;
}
in_uint8(s, len);
if (len & 0x80)
{
len &= ~0x80;
*length = 0;
while (len--)
next_be(s, *length);
}
else
*length = len;
return s_check(s);
}
/* Output an ASN.1 BER header */
void
ber_out_header(STREAM s, int tagval, int length)
{
if (tagval > 0xff)
{
out_uint16_be(s, tagval);
}
else
{
out_uint8(s, tagval);
}
if (length >= 0x80)
{
out_uint8(s, 0x82);
out_uint16_be(s, length);
}
else
out_uint8(s, length);
}
/* Output an ASN.1 BER integer */
void
ber_out_integer(STREAM s, int value)
{
ber_out_header(s, BER_TAG_INTEGER, 2);
out_uint16_be(s, value);
}
RD_BOOL
ber_in_header(STREAM s, int *tagval, int *decoded_len)
{
in_uint8(s, *tagval);
in_uint8(s, *decoded_len);
if (*decoded_len < 0x80)
return True;
else if (*decoded_len == 0x81)
{
in_uint8(s, *decoded_len);
return True;
}
else if (*decoded_len == 0x82)
{
in_uint16_be(s, *decoded_len);
return True;
}
return False;
}

View file

@ -1,11 +1,11 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Bitmap decompression routines
Copyright (C) Matthew Chapman 1999-2005
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
This program is free software; you can redistribute it and/or modify
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@ -13,23 +13,19 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* three seperate function for speed when decompressing the bitmaps */
/* when modifing one function make the change in the others */
/* comment out #define BITMAP_SPEED_OVER_SIZE below for one slower function */
/* j@american-data.com */
/* three seperate function for speed when decompressing the bitmaps
when modifing one function make the change in the others
jay.sorg@gmail.com */
/* indent is confused by this file */
/* *INDENT-OFF* */
#include "precomp.h"
#define BITMAP_SPEED_OVER_SIZE
#define CVAL(p) (*(p++))
#ifdef NEED_ALIGN
#ifdef L_ENDIAN
@ -66,10 +62,8 @@
} \
}
#ifdef BITMAP_SPEED_OVER_SIZE
/* 1 byte bitmap decompress */
static BOOL
static RD_BOOL
bitmap_decompress1(uint8 * output, int width, int height, uint8 * input, int size)
{
uint8 *end = input + size;
@ -267,7 +261,7 @@ bitmap_decompress1(uint8 * output, int width, int height, uint8 * input, int siz
}
/* 2 byte bitmap decompress */
static BOOL
static RD_BOOL
bitmap_decompress2(uint8 * output, int width, int height, uint8 * input, int size)
{
uint8 *end = input + size;
@ -466,7 +460,7 @@ bitmap_decompress2(uint8 * output, int width, int height, uint8 * input, int siz
}
/* 3 byte bitmap decompress */
static BOOL
static RD_BOOL
bitmap_decompress3(uint8 * output, int width, int height, uint8 * input, int size)
{
uint8 *end = input + size;
@ -751,254 +745,146 @@ bitmap_decompress3(uint8 * output, int width, int height, uint8 * input, int siz
return True;
}
#else
static uint32
cvalx(uint8 **input, int Bpp)
/* decompress a colour plane */
static int
process_plane(uint8 * in, int width, int height, uint8 * out, int size)
{
uint32 rv = 0;
memcpy(&rv, *input, Bpp);
*input += Bpp;
return rv;
}
int indexw;
int indexh;
int code;
int collen;
int replen;
int color;
int x;
int revcode;
uint8 * last_line;
uint8 * this_line;
uint8 * org_in;
uint8 * org_out;
static void
setli(uint8 *input, int offset, uint32 value, int Bpp)
{
input += offset * Bpp;
memcpy(input, &value, Bpp);
}
static uint32
getli(uint8 *input, int offset, int Bpp)
{
uint32 rv = 0;
input += offset * Bpp;
memcpy(&rv, input, Bpp);
return rv;
}
static BOOL
bitmap_decompressx(uint8 *output, int width, int height, uint8 *input, int size, int Bpp)
{
uint8 *end = input + size;
uint8 *prevline = NULL, *line = NULL;
int opcode, count, offset, isfillormix, x = width;
int lastopcode = -1, insertmix = False, bicolour = False;
uint8 code;
uint32 colour1 = 0, colour2 = 0;
uint8 mixmask, mask = 0;
uint32 mix = 0xffffffff;
int fom_mask = 0;
while (input < end)
org_in = in;
org_out = out;
last_line = 0;
indexh = 0;
while (indexh < height)
{
fom_mask = 0;
code = CVAL(input);
opcode = code >> 4;
/* Handle different opcode forms */
switch (opcode)
out = (org_out + width * height * 4) - ((indexh + 1) * width * 4);
color = 0;
this_line = out;
indexw = 0;
if (last_line == 0)
{
case 0xc:
case 0xd:
case 0xe:
opcode -= 6;
count = code & 0xf;
offset = 16;
break;
case 0xf:
opcode = code & 0xf;
if (opcode < 9)
while (indexw < width)
{
code = CVAL(in);
replen = code & 0xf;
collen = (code >> 4) & 0xf;
revcode = (replen << 4) | collen;
if ((revcode <= 47) && (revcode >= 16))
{
count = CVAL(input);
count |= CVAL(input) << 8;
replen = revcode;
collen = 0;
}
else
while (collen > 0)
{
count = (opcode < 0xb) ? 8 : 1;
color = CVAL(in);
*out = color;
out += 4;
indexw++;
collen--;
}
while (replen > 0)
{
*out = color;
out += 4;
indexw++;
replen--;
}
offset = 0;
break;
default:
opcode >>= 1;
count = code & 0x1f;
offset = 32;
break;
}
/* Handle strange cases for counts */
if (offset != 0)
{
isfillormix = ((opcode == 2) || (opcode == 7));
if (count == 0)
{
if (isfillormix)
count = CVAL(input) + 1;
else
count = CVAL(input) + offset;
}
else if (isfillormix)
{
count <<= 3;
}
}
/* Read preliminary data */
switch (opcode)
else
{
case 0: /* Fill */
if ((lastopcode == opcode) && !((x == width) && (prevline == NULL)))
insertmix = True;
break;
case 8: /* Bicolour */
colour1 = cvalx(&input, Bpp);
case 3: /* Colour */
colour2 = cvalx(&input, Bpp);
break;
case 6: /* SetMix/Mix */
case 7: /* SetMix/FillOrMix */
mix = cvalx(&input, Bpp);
opcode -= 5;
break;
case 9: /* FillOrMix_1 */
mask = 0x03;
opcode = 0x02;
fom_mask = 3;
break;
case 0x0a: /* FillOrMix_2 */
mask = 0x05;
opcode = 0x02;
fom_mask = 5;
break;
}
lastopcode = opcode;
mixmask = 0;
/* Output body */
while (count > 0)
{
if (x >= width)
while (indexw < width)
{
if (height <= 0)
return False;
x = 0;
height--;
prevline = line;
line = output + height * width * Bpp;
}
switch (opcode)
{
case 0: /* Fill */
if (insertmix)
code = CVAL(in);
replen = code & 0xf;
collen = (code >> 4) & 0xf;
revcode = (replen << 4) | collen;
if ((revcode <= 47) && (revcode >= 16))
{
replen = revcode;
collen = 0;
}
while (collen > 0)
{
x = CVAL(in);
if (x & 1)
{
if (prevline == NULL)
setli(line, x, mix, Bpp);
else
setli(line, x,
getli(prevline, x, Bpp) ^ mix, Bpp);
insertmix = False;
count--;
x++;
}
if (prevline == NULL)
{
REPEAT(setli(line, x, 0, Bpp))}
else
{
REPEAT(setli
(line, x, getli(prevline, x, Bpp), Bpp));
}
break;
case 1: /* Mix */
if (prevline == NULL)
{
REPEAT(setli(line, x, mix, Bpp));
x = x >> 1;
x = x + 1;
color = -x;
}
else
{
REPEAT(setli
(line, x, getli(prevline, x, Bpp) ^ mix,
Bpp));
x = x >> 1;
color = x;
}
break;
case 2: /* Fill or Mix */
if (prevline == NULL)
{
REPEAT(MASK_UPDATE();
if (mask & mixmask) setli(line, x, mix, Bpp);
else
setli(line, x, 0, Bpp););
}
else
{
REPEAT(MASK_UPDATE();
if (mask & mixmask)
setli(line, x, getli(prevline, x, Bpp) ^ mix,
Bpp);
else
setli(line, x, getli(prevline, x, Bpp),
Bpp););
}
break;
case 3: /* Colour */
REPEAT(setli(line, x, colour2, Bpp));
break;
case 4: /* Copy */
REPEAT(setli(line, x, cvalx(&input, Bpp), Bpp));
break;
case 8: /* Bicolour */
REPEAT(if (bicolour)
{
setli(line, x, colour2, Bpp); bicolour = False;}
else
{
setli(line, x, colour1, Bpp); bicolour = True;
count++;}
);
break;
case 0xd: /* White */
REPEAT(setli(line, x, 0xffffffff, Bpp));
break;
case 0xe: /* Black */
REPEAT(setli(line, x, 0, Bpp));
break;
default:
unimpl("bitmap opcode 0x%x\n", opcode);
return False;
x = last_line[indexw * 4] + color;
*out = x;
out += 4;
indexw++;
collen--;
}
while (replen > 0)
{
x = last_line[indexw * 4] + color;
*out = x;
out += 4;
indexw++;
replen--;
}
}
}
indexh++;
last_line = this_line;
}
return True;
return (int) (in - org_in);
}
#endif
/* 4 byte bitmap decompress */
static RD_BOOL
bitmap_decompress4(uint8 * output, int width, int height, uint8 * input, int size)
{
int code;
int bytes_pro;
int total_pro;
code = CVAL(input);
if (code != 0x10)
{
return False;
}
total_pro = 1;
bytes_pro = process_plane(input, width, height, output + 3, size - total_pro);
total_pro += bytes_pro;
input += bytes_pro;
bytes_pro = process_plane(input, width, height, output + 2, size - total_pro);
total_pro += bytes_pro;
input += bytes_pro;
bytes_pro = process_plane(input, width, height, output + 1, size - total_pro);
total_pro += bytes_pro;
input += bytes_pro;
bytes_pro = process_plane(input, width, height, output + 0, size - total_pro);
total_pro += bytes_pro;
return size == total_pro;
}
/* main decompress function */
BOOL
RD_BOOL
bitmap_decompress(uint8 * output, int width, int height, uint8 * input, int size, int Bpp)
{
#ifdef BITMAP_SPEED_OVER_SIZE
BOOL rv = False;
RD_BOOL rv = False;
switch (Bpp)
{
case 1:
@ -1010,11 +896,13 @@ bitmap_decompress(uint8 * output, int width, int height, uint8 * input, int size
case 3:
rv = bitmap_decompress3(output, width, height, input, size);
break;
case 4:
rv = bitmap_decompress4(output, width, height, input, size);
break;
default:
unimpl("Bpp %d\n", Bpp);
break;
}
#else
BOOL rv;
rv = bitmap_decompressx(output, width, height, input, size, Bpp);
#endif
return rv;
}

View file

@ -223,12 +223,24 @@ bs_is_pixel_on(char * data, int x, int y, int width, int bpp)
{
return data[y * width + x] != 0;
}
else if (bpp == 15 || bpp == 16)
{
return data[(y * 2) * width + (x * 2)] != 0 ||
data[(y * 2) * width + (x * 2) + 1] != 0;
}
else if (bpp == 24)
{
return data[(y * 3) * width + (x * 3)] != 0 &&
data[(y * 3) * width + (x * 3) + 1] != 0 &&
return data[(y * 3) * width + (x * 3)] != 0 ||
data[(y * 3) * width + (x * 3) + 1] != 0 ||
data[(y * 3) * width + (x * 3) + 2] != 0;
}
else if (bpp == 32)
{
return data[(y * 4) * width + (x * 4)] != 0 ||
data[(y * 4) * width + (x * 4) + 1] != 0 ||
data[(y * 4) * width + (x * 4) + 2] != 0 ||
data[(y * 4) * width + (x * 4) + 3] != 0;
}
else
{
return 0;

View file

@ -1,12 +1,13 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Cache routines
Copyright (C) Matthew Chapman 1999-2005
Copyright (C) Jeroen Meijer 2005
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
Copyright (C) Jeroen Meijer <jeroen@oldambt7.com> 2005
Copyright 2003-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
This program is free software; you can redistribute it and/or modify
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@ -14,9 +15,8 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "precomp.h"
@ -50,6 +50,7 @@ static RD_HBITMAP g_volatile_bc[3];
static int g_bmpcache_lru[3] = { NOT_SET, NOT_SET, NOT_SET };
static int g_bmpcache_mru[3] = { NOT_SET, NOT_SET, NOT_SET };
static int g_bmpcache_count[3];
/* Setup the bitmap cache lru/mru linked list */
@ -94,7 +95,7 @@ cache_rebuild_bmpcache_linked_list(uint8 id, sint16 * idx, int count)
{
error("Oops. %d in bitmap cache linked list, %d in ui cache...\n", c,
g_bmpcache_count[id]);
exit(1);
exit(EX_SOFTWARE);
}
}
@ -176,7 +177,7 @@ cache_evict_bitmap(uint8 id)
idx = g_bmpcache_lru[id];
n_idx = g_bmpcache[id][idx].next;
DEBUG_RDP5(("evict bitmap: id=%d idx=%d n_idx=%d bmp=0x%x\n", id, idx, n_idx,
DEBUG_RDP5(("evict bitmap: id=%d idx=%d n_idx=%d bmp=%p\n", id, idx, n_idx,
g_bmpcache[id][idx].bitmap));
ui_destroy_bitmap(g_bmpcache[id][idx].bitmap);
@ -262,7 +263,7 @@ cache_save_state(void)
idx = g_bmpcache_lru[id];
while (idx >= 0)
{
pstcache_touch_bitmap((uint8) id, (uint16) idx, ++t);
pstcache_touch_bitmap(id, idx, ++t);
idx = g_bmpcache[id][idx].next;
}
DEBUG_RDP5((" %d stamps written.\n", t));
@ -430,3 +431,43 @@ cache_put_cursor(uint16 cache_idx, RD_HCURSOR cursor)
error("put cursor %d\n", cache_idx);
}
}
/* BRUSH CACHE */
/* index 0 is 2 colour brush, index 1 is muti colour brush */
static BRUSHDATA g_brushcache[2][64];
/* Retrieve brush from cache */
BRUSHDATA *
cache_get_brush_data(uint8 colour_code, uint8 idx)
{
colour_code = colour_code == 1 ? 0 : 1;
if (idx < NUM_ELEMENTS(g_brushcache[0]))
{
return &g_brushcache[colour_code][idx];
}
error("get brush %d %d\n", colour_code, idx);
return NULL;
}
/* Store brush in cache */
/* this function takes over the data pointer in struct, eg, caller gives it up */
void
cache_put_brush_data(uint8 colour_code, uint8 idx, BRUSHDATA * brush_data)
{
BRUSHDATA *bd;
colour_code = colour_code == 1 ? 0 : 1;
if (idx < NUM_ELEMENTS(g_brushcache[0]))
{
bd = &g_brushcache[colour_code][idx];
if (bd->data != 0)
{
xfree(bd->data);
}
memcpy(bd, brush_data, sizeof(BRUSHDATA));
}
else
{
error("put brush %d %d\n", colour_code, idx);
}
}

View file

@ -1,12 +1,12 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Protocol services - Virtual channels
Copyright (C) Erik Forsberg <forsberg@cendio.se> 2003
Copyright (C) Matthew Chapman 2003-2005
Copyright 2003 Erik Forsberg <forsberg@cendio.se> for Cendio AB
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 2003-2008
This program is free software; you can redistribute it and/or modify
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@ -14,9 +14,8 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "precomp.h"
@ -27,8 +26,8 @@
#define CHANNEL_FLAG_LAST 0x02
#define CHANNEL_FLAG_SHOW_PROTOCOL 0x10
extern BOOL g_use_rdp5;
extern BOOL g_encryption;
extern RDP_VERSION g_rdp_version;
extern RD_BOOL g_encryption;
VCHANNEL g_channels[MAX_CHANNELS];
unsigned int g_num_channels;
@ -48,7 +47,7 @@ channel_register(char *name, uint32 flags, void (*callback) (STREAM))
{
VCHANNEL *channel;
if (!g_use_rdp5)
if (g_rdp_version < RDP_V5)
return NULL;
if (g_num_channels >= MAX_CHANNELS)
@ -83,6 +82,10 @@ channel_send(STREAM s, VCHANNEL * channel)
uint32 thislength, remaining;
uint8 *data;
#ifdef WITH_SCARD
scard_lock(SCARD_LOCK_CHANNEL);
#endif
/* first fragment sent in-place */
s_pop_layer(s, channel_hdr);
length = s->end - s->p - 8;
@ -125,6 +128,10 @@ channel_send(STREAM s, VCHANNEL * channel)
data += thislength;
}
#ifdef WITH_SCARD
scard_unlock(SCARD_LOCK_CHANNEL);
#endif
}
void

View file

@ -1,11 +1,11 @@
/*
rdesktop: A Remote Desktop Protocol client.
Miscellaneous protocol constants
Copyright (C) Matthew Chapman 1999-2005
This program is free software; you can redistribute it and/or modify
Copyright (C) Matthew Chapman 1999-2008
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@ -14,8 +14,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* TCP port for Remote Desktop Protocol */
@ -34,6 +33,31 @@ enum ISO_PDU_CODE
ISO_PDU_ER = 0x70 /* Error */
};
/* RDP protocol negotiating constants */
enum RDP_NEG_TYPE_CODE
{
RDP_NEG_REQ = 1,
RDP_NEG_RSP = 2,
RDP_NEG_FAILURE = 3
};
enum RDP_NEG_REQ_CODE
{
PROTOCOL_RDP = 0,
PROTOCOL_SSL = 1,
PROTOCOL_HYBRID = 2
};
enum RDP_NEG_FAILURE_CODE
{
SSL_REQUIRED_BY_SERVER = 1,
SSL_NOT_ALLOWED_BY_SERVER = 2,
SSL_CERT_NOT_ON_SERVER = 3,
INCONSISTENT_FLAGS = 4,
HYBRID_REQUIRED_BY_SERVER = 5,
SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER = 6
};
/* MCS PDU codes */
enum MCS_PDU_TYPE
{
@ -54,17 +78,21 @@ enum MCS_PDU_TYPE
#define BER_TAG_INTEGER 2
#define BER_TAG_OCTET_STRING 4
#define BER_TAG_RESULT 10
#define BER_TAG_SEQUENCE 16
#define BER_TAG_CONSTRUCTED 0x20
#define BER_TAG_CTXT_SPECIFIC 0x80
#define MCS_TAG_DOMAIN_PARAMS 0x30
#define MCS_GLOBAL_CHANNEL 1003
#define MCS_USERCHANNEL_BASE 1001
/* RDP secure transport constants */
#define SEC_RANDOM_SIZE 32
#define SEC_MODULUS_SIZE 64
#define SEC_RANDOM_SIZE 32
#define SEC_MODULUS_SIZE 64
#define SEC_MAX_MODULUS_SIZE 256
#define SEC_PADDING_SIZE 8
#define SEC_EXPONENT_SIZE 4
#define SEC_PADDING_SIZE 8
#define SEC_EXPONENT_SIZE 4
#define SEC_CLIENT_RANDOM 0x0001
#define SEC_ENCRYPT 0x0008
@ -79,38 +107,50 @@ enum MCS_PDU_TYPE
#define SEC_TAG_CLI_INFO 0xc001
#define SEC_TAG_CLI_CRYPT 0xc002
#define SEC_TAG_CLI_CHANNELS 0xc003
#define SEC_TAG_CLI_4 0xc004
#define SEC_TAG_CLI_CLUSTER 0xc004
#define SEC_TAG_PUBKEY 0x0006
#define SEC_TAG_KEYSIG 0x0008
#define SEC_RSA_MAGIC 0x31415352 /* RSA1 */
/* Client cluster constants */
#define SEC_CC_REDIRECTION_SUPPORTED 0x00000001
#define SEC_CC_REDIRECT_SESSIONID_FIELD_VALID 0x00000002
#define SEC_CC_REDIRECTED_SMARTCARD 0x00000040
#define SEC_CC_REDIRECT_VERSION_MASK 0x0000003c
#define SEC_CC_REDIRECT_VERSION_3 0x02
#define SEC_CC_REDIRECT_VERSION_4 0x03
#define SEC_CC_REDIRECT_VERSION_5 0x04
#define SEC_CC_REDIRECT_VERSION_6 0x05
/* RDP licensing constants */
#define LICENCE_TOKEN_SIZE 10
#define LICENCE_HWID_SIZE 20
#define LICENCE_SIGNATURE_SIZE 16
#define LICENCE_TAG_DEMAND 0x01
#define LICENCE_TAG_AUTHREQ 0x02
#define LICENCE_TAG_ISSUE 0x03
#define LICENCE_TAG_REISSUE 0x04
#define LICENCE_TAG_PRESENT 0x12
#define LICENCE_TAG_REQUEST 0x13
#define LICENCE_TAG_AUTHRESP 0x15
#define LICENCE_TAG_RESULT 0xff
#define LICENCE_TAG_REQUEST 0x01
#define LICENCE_TAG_PLATFORM_CHALLANGE 0x02
#define LICENCE_TAG_NEW_LICENCE 0x03
#define LICENCE_TAG_UPGRADE_LICENCE 0x04
#define LICENCE_TAG_LICENCE_INFO 0x12
#define LICENCE_TAG_NEW_LICENCE_REQUEST 0x13
#define LICENCE_TAG_PLATFORM_CHALLANGE_RESPONSE 0x15
#define LICENCE_TAG_ERROR_ALERT 0xff
#define LICENCE_TAG_USER 0x000f
#define LICENCE_TAG_HOST 0x0010
#define BB_CLIENT_USER_NAME_BLOB 0x000f
#define BB_CLIENT_MACHINE_NAME_BLOB 0x0010
/* RDP PDU codes */
enum RDP_PDU_TYPE
{
RDP_PDU_DEMAND_ACTIVE = 1,
RDP_PDU_CONFIRM_ACTIVE = 3,
RDP_PDU_REDIRECT = 4, /* MS Server 2003 Session Redirect */
RDP_PDU_REDIRECT = 4, /* Standard Server Redirect */
RDP_PDU_DEACTIVATE = 6,
RDP_PDU_DATA = 7
RDP_PDU_DATA = 7,
RDP_PDU_ENHANCED_REDIRECT = 10 /* Enhanced Server Redirect */
};
enum RDP_DATA_PDU_TYPE
@ -122,10 +162,25 @@ enum RDP_DATA_PDU_TYPE
RDP_DATA_PDU_SYNCHRONISE = 31,
RDP_DATA_PDU_BELL = 34,
RDP_DATA_PDU_CLIENT_WINDOW_STATUS = 35,
RDP_DATA_PDU_LOGON = 38,
RDP_DATA_PDU_LOGON = 38, /* PDUTYPE2_SAVE_SESSION_INFO */
RDP_DATA_PDU_FONT2 = 39,
RDP_DATA_PDU_KEYBOARD_INDICATORS = 41,
RDP_DATA_PDU_DISCONNECT = 47
RDP_DATA_PDU_DISCONNECT = 47,
RDP_DATA_PDU_AUTORECONNECT_STATUS = 50
};
enum RDP_SAVE_SESSION_PDU_TYPE
{
INFOTYPE_LOGON = 0,
INFOTYPE_LOGON_LONG = 1,
INFOTYPE_LOGON_PLAINNOTIFY = 2,
INFOTYPE_LOGON_EXTENDED_INF = 3
};
enum RDP_LOGON_INFO_EXTENDED_TYPE
{
LOGON_EX_AUTORECONNECTCOOKIE = 1,
LOGON_EX_LOGONERRORS = 2
};
enum RDP_CONTROL_PDU_TYPE
@ -149,7 +204,8 @@ enum RDP_POINTER_PDU_TYPE
RDP_POINTER_SYSTEM = 1,
RDP_POINTER_MOVE = 3,
RDP_POINTER_COLOR = 6,
RDP_POINTER_CACHED = 7
RDP_POINTER_CACHED = 7,
RDP_POINTER_NEW = 8
};
enum RDP_SYSTEM_POINTER_TYPE
@ -192,9 +248,8 @@ enum RDP_INPUT_DEVICE
#define MOUSE_FLAG_DOWN 0x8000
/* Raster operation masks */
#define ROP2_S(rop3) ((uint8) (rop3 & 0xf))
#define ROP2_P(rop3) ((uint8) ((rop3 & 0x3) | ((rop3 & 0x30) >> 2)))
#define ROP_MINUS_1(rop) ((uint8) (rop - 1))
#define ROP2_S(rop3) (rop3 & 0xf)
#define ROP2_P(rop3) ((rop3 & 0x3) | ((rop3 & 0x30) >> 2))
#define ROP2_COPY 0xc
#define ROP2_XOR 0x6
@ -245,6 +300,7 @@ enum RDP_INPUT_DEVICE
#define RDP_CAPSET_POINTER 8
#define RDP_CAPLEN_POINTER 0x08
#define RDP_CAPLEN_NEWPOINTER 0x0a
#define RDP_CAPSET_SHARE 9
#define RDP_CAPLEN_SHARE 0x08
@ -252,6 +308,9 @@ enum RDP_INPUT_DEVICE
#define RDP_CAPSET_COLCACHE 10
#define RDP_CAPLEN_COLCACHE 0x08
#define RDP_CAPSET_BRUSHCACHE 15
#define RDP_CAPLEN_BRUSHCACHE 0x08
#define RDP_CAPSET_BMPCACHE2 19
#define RDP_CAPLEN_BMPCACHE2 0x28
#define BMPCACHE2_FLAG_PERSIST ((uint32)1<<31)
@ -259,12 +318,16 @@ enum RDP_INPUT_DEVICE
#define RDP_SOURCE "MSTSC"
/* Logon flags */
#define RDP_LOGON_AUTO 0x0008
#define RDP_LOGON_NORMAL 0x0033
#define RDP_LOGON_COMPRESSION 0x0080 /* mppc compression with 8kB histroy buffer */
#define RDP_LOGON_BLOB 0x0100
#define RDP_LOGON_COMPRESSION2 0x0200 /* rdp5 mppc compression with 64kB history buffer */
#define RDP_LOGON_LEAVE_AUDIO 0x2000
#define RDP_INFO_MOUSE 0x00000001
#define RDP_INFO_DISABLECTRLALTDEL 0x00000002
#define RDP_INFO_AUTOLOGON 0x00000008
#define RDP_INFO_UNICODE 0x00000010
#define RDP_INFO_MAXIMIZESHELL 0x00000020
#define RDP_INFO_COMPRESSION 0x00000080 /* mppc compression with 8kB histroy buffer */
#define RDP_INFO_ENABLEWINDOWSKEY 0x00000100
#define RDP_INFO_COMPRESSION2 0x00000200 /* rdp5 mppc compression with 64kB history buffer */
#define RDP_INFO_REMOTE_CONSOLE_AUDIO 0x00002000
#define RDP_INFO_PASSWORD_IS_SC_PIN 0x00040000
#define RDP5_DISABLE_NOTHING 0x00
#define RDP5_NO_WALLPAPER 0x01
@ -313,7 +376,8 @@ enum RDP_INPUT_DEVICE
#define MASK_CHANGE_BIT(var, mask, active) (var = ((var & ~mask) | (active ? mask : 0)))
/* Clipboard constants, "borrowed" from GCC system headers in
the w32 cross compiler */
the w32 cross compiler
this is the CF_ set when WINVER is 0x0400 */
#ifndef CF_TEXT
#define CF_TEXT 1
@ -357,37 +421,53 @@ enum RDP_INPUT_DEVICE
#define CHANNEL_OPTION_SHOW_PROTOCOL 0x00200000
/* NT status codes for RDPDR */
#undef STATUS_SUCCESS
#define STATUS_SUCCESS 0x00000000
#undef STATUS_NOT_IMPLEMENTED
#define STATUS_NOT_IMPLEMENTED 0x00000001
#undef STATUS_PENDING
#define STATUS_PENDING 0x00000103
#define RD_STATUS_SUCCESS 0x00000000
#define RD_STATUS_NOT_IMPLEMENTED 0x00000001
#define RD_STATUS_PENDING 0x00000103
#ifndef STATUS_NO_MORE_FILES
#define STATUS_NO_MORE_FILES 0x80000006
#define STATUS_DEVICE_PAPER_EMPTY 0x8000000e
#define STATUS_DEVICE_POWERED_OFF 0x8000000f
#define STATUS_DEVICE_OFF_LINE 0x80000010
#define STATUS_DEVICE_BUSY 0x80000011
#endif
#define RD_STATUS_NO_MORE_FILES 0x80000006
#define RD_STATUS_DEVICE_PAPER_EMPTY 0x8000000e
#define RD_STATUS_DEVICE_POWERED_OFF 0x8000000f
#define RD_STATUS_DEVICE_OFF_LINE 0x80000010
#define RD_STATUS_DEVICE_BUSY 0x80000011
#ifndef STATUS_INVALID_HANDLE
#define STATUS_INVALID_HANDLE 0xc0000008
#define STATUS_INVALID_PARAMETER 0xc000000d
#define STATUS_NO_SUCH_FILE 0xc000000f
#define STATUS_INVALID_DEVICE_REQUEST 0xc0000010
#define STATUS_ACCESS_DENIED 0xc0000022
#define STATUS_OBJECT_NAME_COLLISION 0xc0000035
#define STATUS_DISK_FULL 0xc000007f
#define STATUS_FILE_IS_A_DIRECTORY 0xc00000ba
#define STATUS_NOT_SUPPORTED 0xc00000bb
#define STATUS_TIMEOUT 0xc0000102
#define STATUS_NOTIFY_ENUM_DIR 0xc000010c
#define STATUS_CANCELLED 0xc0000120
#endif
#define RD_STATUS_INVALID_HANDLE 0xc0000008
#define RD_STATUS_INVALID_PARAMETER 0xc000000d
#define RD_STATUS_NO_SUCH_FILE 0xc000000f
#define RD_STATUS_INVALID_DEVICE_REQUEST 0xc0000010
#define RD_STATUS_ACCESS_DENIED 0xc0000022
#define RD_STATUS_OBJECT_NAME_COLLISION 0xc0000035
#define RD_STATUS_DISK_FULL 0xc000007f
#define RD_STATUS_FILE_IS_A_DIRECTORY 0xc00000ba
#define RD_STATUS_NOT_SUPPORTED 0xc00000bb
#define RD_STATUS_TIMEOUT 0xc0000102
#define RD_STATUS_NOTIFY_ENUM_DIR 0xc000010c
#define RD_STATUS_CANCELLED 0xc0000120
#define RD_STATUS_DIRECTORY_NOT_EMPTY 0xc0000101
/* RDPSND constants */
#define TSSNDCAPS_ALIVE 0x00000001
#define TSSNDCAPS_VOLUME 0x00000002
/* RDPDR constants */
#define RDPDR_CTYP_CORE 0x4472
#define RDPDR_CTYP_PRN 0x5052
#define PAKID_CORE_SERVER_ANNOUNCE 0x496e
#define PAKID_CORE_CLIENTID_CONFIRM 0x4343
#define PAKID_CORE_CLIENT_NAME 0x434e
#define PAKID_CORE_DEVICE_LIST_ANNOUNCE 0x4441
#define PAKID_CORE_DEVICE_REPLY 0x6472
#define PAKID_CORE_DEVICE_IOREQUEST 0x4952
#define PAKID_CORE_DEVICE_IOCOMPLETION 0x4943
#define PAKID_CORE_SERVER_CAPABILITY 0x5350
#define PAKID_CORE_CLIENT_CAPABILITY 0x4350
#define PAKID_CORE_DEVICELIST_REMOVE 0x444d
#define PAKID_PRN_CACHE_DATA 0x5043
#define PAKID_CORE_USER_LOGGEDON 0x554c
#define PAKID_PRN_USING_XPS 0x5543
#define RDPDR_MAX_DEVICES 0x10
#define DEVICE_TYPE_SERIAL 0x01
#define DEVICE_TYPE_PARALLEL 0x02
@ -411,6 +491,10 @@ enum RDP_INPUT_DEVICE
#define exDiscReasonOutOfMemory 0x0006
#define exDiscReasonServerDeniedConnection 0x0007
#define exDiscReasonServerDeniedConnectionFips 0x0008
#define exDiscReasonServerInsufficientPrivileges 0x0009
#define exDiscReasonServerFreshCredentialsRequired 0x000a
#define exDiscReasonRPCInitiatedDisconnectByUser 0x000b
#define exDiscReasonByUser 0x000c
#define exDiscReasonLicenseInternal 0x0100
#define exDiscReasonLicenseNoLicenseServer 0x0101
#define exDiscReasonLicenseNoLicense 0x0102
@ -431,6 +515,31 @@ enum RDP_INPUT_DEVICE
#define SEAMLESSRDP_POSITION_TIMER 200000
#define SEAMLESSRDP_CREATE_MODAL 0x0001
#define SEAMLESSRDP_CREATE_TOPMOST 0x0002
#define SEAMLESSRDP_HELLO_RECONNECT 0x0001
#define SEAMLESSRDP_HELLO_HIDDEN 0x0002
/* Smartcard constants */
#define SCARD_LOCK_TCP 0
#define SCARD_LOCK_SEC 1
#define SCARD_LOCK_CHANNEL 2
#define SCARD_LOCK_RDPDR 3
#define SCARD_LOCK_LAST 4
/* redirect flags, from [MS-RDPBCGR] 2.2.13.1 */
enum RDP_PDU_REDIRECT_FLAGS
{
PDU_REDIRECT_HAS_IP = 0x1,
PDU_REDIRECT_HAS_LOAD_BALANCE_INFO = 0x2,
PDU_REDIRECT_HAS_USERNAME = 0x4,
PDU_REDIRECT_HAS_DOMAIN = 0x8,
PDU_REDIRECT_HAS_PASSWORD = 0x10,
PDU_REDIRECT_DONT_STORE_USERNAME = 0x20,
PDU_REDIRECT_USE_SMARTCARD = 0x40,
PDU_REDIRECT_INFORMATIONAL = 0x80,
PDU_REDIRECT_HAS_TARGET_FQDN = 0x100,
PDU_REDIRECT_HAS_TARGET_NETBIOS = 0x200,
PDU_REDIRECT_HAS_TARGET_IP_ARRAY = 0x800
};

View file

@ -1,11 +1,13 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Protocol services - ISO layer
Copyright (C) Matthew Chapman 1999-2005
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
Copyright 2005-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
Copyright 2012 Henrik Andersson <hean01@cendio.se> for Cendio AB
This program is free software; you can redistribute it and/or modify
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@ -13,13 +15,25 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "precomp.h"
extern RD_BOOL g_encryption;
extern RD_BOOL g_encryption_initial;
extern RDP_VERSION g_rdp_version;
extern RD_BOOL g_use_password_as_pin;
static RD_BOOL g_negotiate_rdp_protocol = True;
extern char *g_sc_csp_name;
extern char *g_sc_reader_name;
extern char *g_sc_card_name;
extern char *g_sc_container_name;
/* Send a self-contained ISO PDU */
static void
iso_send_msg(uint8 code)
@ -43,11 +57,14 @@ iso_send_msg(uint8 code)
}
static void
iso_send_connection_request(char *username)
iso_send_connection_request(char *username, uint32 neg_proto)
{
STREAM s;
int length = 30 + strlen(username);
if (g_rdp_version >= RDP_V5 && g_negotiate_rdp_protocol)
length += 8;
s = tcp_init(length);
out_uint8(s, 3); /* version */
@ -63,8 +80,17 @@ iso_send_connection_request(char *username)
out_uint8p(s, "Cookie: mstshash=", strlen("Cookie: mstshash="));
out_uint8p(s, username, strlen(username));
out_uint8(s, 0x0d); /* Unknown */
out_uint8(s, 0x0a); /* Unknown */
out_uint8(s, 0x0d); /* cookie termination string: CR+LF */
out_uint8(s, 0x0a);
if (g_rdp_version >= RDP_V5 && g_negotiate_rdp_protocol)
{
/* optional rdp protocol negotiation request for RDPv5 */
out_uint8(s, RDP_NEG_REQ);
out_uint8(s, 0);
out_uint16(s, 8);
out_uint32(s, neg_proto);
}
s_mark_end(s);
tcp_send(s);
@ -98,6 +124,11 @@ iso_recv_msg(uint8 * code, uint8 * rdpver)
next_be(s, length);
}
}
if (length < 4)
{
error("Bad packet header\n");
return NULL;
}
s = tcp_recv(s, length - 4);
if (s == NULL)
return NULL;
@ -168,17 +199,38 @@ iso_recv(uint8 * rdpver)
}
/* Establish a connection up to the ISO layer */
BOOL
iso_connect(char *server, char *username)
RD_BOOL
iso_connect(char *server, char *username, char *domain, char *password,
RD_BOOL reconnect, uint32 * selected_protocol)
{
uint8 code = 0;
STREAM s;
uint8 code;
uint32 neg_proto;
g_negotiate_rdp_protocol = True;
neg_proto = PROTOCOL_SSL;
#ifdef WITH_CREDSSP
if (!g_use_password_as_pin)
neg_proto |= PROTOCOL_HYBRID;
else if (g_sc_csp_name || g_sc_reader_name || g_sc_card_name || g_sc_container_name)
neg_proto |= PROTOCOL_HYBRID;
else
warning("Disables CredSSP due to missing smartcard information for SSO.\n");
#endif
retry:
*selected_protocol = PROTOCOL_RDP;
code = 0;
if (!tcp_connect(server))
return False;
iso_send_connection_request(username);
iso_send_connection_request(username, neg_proto);
if (iso_recv_msg(&code, NULL) == NULL)
s = iso_recv_msg(&code, NULL);
if (s == NULL)
return False;
if (code != ISO_PDU_CC)
@ -188,30 +240,120 @@ iso_connect(char *server, char *username)
return False;
}
return True;
}
/* Establish a reconnection up to the ISO layer */
BOOL
iso_reconnect(char *server)
{
uint8 code = 0;
if (!tcp_connect(server))
return False;
iso_send_msg(ISO_PDU_CR);
if (iso_recv_msg(&code, NULL) == NULL)
return False;
if (code != ISO_PDU_CC)
if (g_rdp_version >= RDP_V5 && s_check_rem(s, 8))
{
error("expected CC, got 0x%x\n", code);
tcp_disconnect();
return False;
}
/* handle RDP_NEG_REQ response */
const char *reason = NULL;
uint8 type = 0, flags = 0;
uint16 length = 0;
uint32 data = 0;
in_uint8(s, type);
in_uint8(s, flags);
in_uint16(s, length);
in_uint32(s, data);
if (type == RDP_NEG_FAILURE)
{
RD_BOOL retry_without_neg = False;
switch (data)
{
case SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER:
reason = "SSL with user authentication required by server";
break;
case SSL_NOT_ALLOWED_BY_SERVER:
reason = "SSL not allowed by server";
retry_without_neg = True;
break;
case SSL_CERT_NOT_ON_SERVER:
reason = "no valid authentication certificate on server";
retry_without_neg = True;
break;
case INCONSISTENT_FLAGS:
reason = "inconsistent negotiation flags";
break;
case SSL_REQUIRED_BY_SERVER:
reason = "SSL required by server";
break;
case HYBRID_REQUIRED_BY_SERVER:
reason = "CredSSP required by server";
break;
default:
reason = "unknown reason";
}
tcp_disconnect();
if (retry_without_neg)
{
fprintf(stderr,
"Failed to negotiate protocol, retrying with plain RDP.\n");
g_negotiate_rdp_protocol = False;
goto retry;
}
fprintf(stderr, "Failed to connect, %s.\n", reason);
return False;
}
if (type != RDP_NEG_RSP)
{
tcp_disconnect();
error("Expected RDP_NEG_RSP, got type = 0x%x\n", type);
return False;
}
/* handle negotiation response */
if (data == PROTOCOL_SSL)
{
#ifdef WITH_SSL
if (!tcp_tls_connect())
{
/* failed to connect using cssp, let retry with plain TLS */
tcp_disconnect();
neg_proto = PROTOCOL_RDP;
goto retry;
}
/* do not use encryption when using TLS */
g_encryption = False;
fprintf(stderr, "Connection established using SSL.\n");
#else /* WITH_SSL */
fprintf(stderr, "SSL not compiled in.\n");
#endif /* WITH_SSL */
}
#ifdef WITH_CREDSSP
else if (data == PROTOCOL_HYBRID)
{
if (!cssp_connect(server, username, domain, password, s))
{
/* failed to connect using cssp, let retry with plain TLS */
tcp_disconnect();
neg_proto = PROTOCOL_SSL;
goto retry;
}
/* do not use encryption when using TLS */
fprintf(stderr, "Connection established using CredSSP.\n");
g_encryption = False;
}
#endif
else if (data == PROTOCOL_RDP)
{
fprintf(stderr, "Connection established using plain RDP.\n");
}
else if (data != PROTOCOL_RDP)
{
tcp_disconnect();
error("Unexpected protocol in negotiation response, got data = 0x%x.\n",
data);
return False;
}
if (length || flags) {}
*selected_protocol = data;
}
return True;
}
@ -227,5 +369,6 @@ iso_disconnect(void)
void
iso_reset_state(void)
{
g_encryption = g_encryption_initial;
tcp_reset_state();
}

View file

@ -1,11 +1,14 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
RDP licensing negotiation
Copyright (C) Matthew Chapman 1999-2005
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
Copyright (C) Thomas Uhle <thomas.uhle@mailbox.tu-dresden.de> 2011
Copyright (C) Henrik Andersson <henrik.andersson@cendio.com> 2014
This program is free software; you can redistribute it and/or modify
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@ -13,9 +16,8 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "precomp.h"
@ -32,13 +34,15 @@ int
ssl_mod_exp(char* out, int out_len, char* in, int in_len,
char* mod, int mod_len, char* exp, int exp_len);
extern char g_username[];
extern char g_hostname[];
extern char g_username[256];
extern char g_hostname[256];
extern RDP_VERSION g_rdp_version;
static uint8 g_licence_key[16];
static uint8 g_licence_sign_key[16];
BOOL g_licence_issued = False;
RD_BOOL g_licence_issued = False;
RD_BOOL g_licence_error_result = False;
/* Generate a session key and RC4 keys, given client and server randoms */
static void
@ -65,21 +69,21 @@ licence_generate_hwid(uint8 * hwid)
strncpy((char *) (hwid + 4), g_hostname, LICENCE_HWID_SIZE - 4);
}
/* Present an existing licence to the server */
/* Send a lincece info packet to server */
static void
licence_present(uint8 * client_random, uint8 * rsa_data,
uint8 * licence_data, int licence_size, uint8 * hwid, uint8 * signature)
licence_info(uint8 * client_random, uint8 * rsa_data,
uint8 * licence_data, int licence_size, uint8 * hwid, uint8 * signature)
{
uint32 sec_flags = SEC_LICENCE_NEG;
uint16 length =
16 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE +
24 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE +
licence_size + LICENCE_HWID_SIZE + LICENCE_SIGNATURE_SIZE;
STREAM s;
s = sec_init(sec_flags, length + 4);
s = sec_init(sec_flags, length + 2);
out_uint8(s, LICENCE_TAG_PRESENT);
out_uint8(s, 2); /* version */
out_uint8(s, LICENCE_TAG_LICENCE_INFO);
out_uint8(s, ((g_rdp_version >= RDP_V5) ? 3 : 2)); /* version */
out_uint16_le(s, length);
out_uint32_le(s, 1);
@ -87,7 +91,7 @@ licence_present(uint8 * client_random, uint8 * rsa_data,
out_uint16_le(s, 0x0201);
out_uint8p(s, client_random, SEC_RANDOM_SIZE);
out_uint16(s, 0);
out_uint16_le(s, 2);
out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE));
out_uint8p(s, rsa_data, SEC_MODULUS_SIZE);
out_uint8s(s, SEC_PADDING_SIZE);
@ -106,37 +110,40 @@ licence_present(uint8 * client_random, uint8 * rsa_data,
sec_send(s, sec_flags);
}
/* Send a licence request packet */
/* Send a new licence request packet */
static void
licence_send_request(uint8 * client_random, uint8 * rsa_data, char *user, char *host)
licence_send_new_licence_request(uint8 * client_random, uint8 * rsa_data, char *user, char *host)
{
uint32 sec_flags = SEC_LICENCE_NEG;
uint16 userlen = strlen(user) + 1;
uint16 hostlen = strlen(host) + 1;
uint16 length = 128 + userlen + hostlen;
uint16 length =
24 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE + userlen + hostlen;
STREAM s;
s = sec_init(sec_flags, length + 2);
out_uint8(s, LICENCE_TAG_REQUEST);
out_uint8(s, 2); /* version */
out_uint8(s, LICENCE_TAG_NEW_LICENCE_REQUEST);
out_uint8(s, ((g_rdp_version >= RDP_V5) ? 3 : 2)); /* version */
out_uint16_le(s, length);
out_uint32_le(s, 1);
out_uint32_le(s, 1); // KEY_EXCHANGE_ALG_RSA
out_uint16(s, 0);
out_uint16_le(s, 0xff01);
out_uint8p(s, client_random, SEC_RANDOM_SIZE);
out_uint16(s, 0);
out_uint16_le(s, 2);
out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE));
out_uint8p(s, rsa_data, SEC_MODULUS_SIZE);
out_uint8s(s, SEC_PADDING_SIZE);
out_uint16_le(s, LICENCE_TAG_USER);
/* Username LICENSE_BINARY_BLOB */
out_uint16_le(s, BB_CLIENT_USER_NAME_BLOB);
out_uint16_le(s, userlen);
out_uint8p(s, user, userlen);
out_uint16_le(s, LICENCE_TAG_HOST);
/* Machinename LICENSE_BINARY_BLOB */
out_uint16_le(s, BB_CLIENT_MACHINE_NAME_BLOB);
out_uint16_le(s, hostlen);
out_uint8p(s, host, hostlen);
@ -144,9 +151,9 @@ licence_send_request(uint8 * client_random, uint8 * rsa_data, char *user, char *
sec_send(s, sec_flags);
}
/* Process a licence demand packet */
/* Process a licence request packet */
static void
licence_process_demand(STREAM s)
licence_process_request(STREAM s)
{
uint8 null_data[SEC_MODULUS_SIZE];
uint8 *server_random;
@ -177,17 +184,24 @@ licence_process_demand(STREAM s)
ssl_rc4_crypt(crypt_key, (char *)hwid, (char *)hwid, sizeof(hwid));
ssl_rc4_info_delete(crypt_key);
licence_present(null_data, null_data, licence_data, licence_size, hwid, signature);
#if WITH_DEBUG
DEBUG(("Sending licensing PDU (message type 0x%02x)\n", LICENCE_TAG_LICENCE_INFO));
#endif
licence_info(null_data, null_data, licence_data, licence_size, hwid, signature);
xfree(licence_data);
return;
}
licence_send_request(null_data, null_data, g_username, g_hostname);
#if WITH_DEBUG
DEBUG(("Sending licensing PDU (message type 0x%02x)\n", LICENCE_TAG_NEW_LICENCE_REQUEST));
#endif
licence_send_new_licence_request(null_data, null_data, g_username, g_hostname);
}
/* Send an authentication response packet */
/* Send a platform challange response packet */
static void
licence_send_authresp(uint8 * token, uint8 * crypt_hwid, uint8 * signature)
licence_send_platform_challange_response(uint8 * token, uint8 * crypt_hwid, uint8 * signature)
{
uint32 sec_flags = SEC_LICENCE_NEG;
uint16 length = 58;
@ -195,8 +209,8 @@ licence_send_authresp(uint8 * token, uint8 * crypt_hwid, uint8 * signature)
s = sec_init(sec_flags, length + 2);
out_uint8(s, LICENCE_TAG_AUTHRESP);
out_uint8(s, 2); /* version */
out_uint8(s, LICENCE_TAG_PLATFORM_CHALLANGE_RESPONSE);
out_uint8(s, ((g_rdp_version >= RDP_V5) ? 3 : 2)); /* version */
out_uint16_le(s, length);
out_uint16_le(s, 1);
@ -213,9 +227,9 @@ licence_send_authresp(uint8 * token, uint8 * crypt_hwid, uint8 * signature)
sec_send(s, sec_flags);
}
/* Parse an authentication request packet */
static BOOL
licence_parse_authreq(STREAM s, uint8 ** token, uint8 ** signature)
/* Parse an platform challange request packet */
static RD_BOOL
licence_parse_platform_challange(STREAM s, uint8 ** token, uint8 ** signature)
{
uint16 tokenlen;
@ -234,9 +248,9 @@ licence_parse_authreq(STREAM s, uint8 ** token, uint8 ** signature)
return s_check_end(s);
}
/* Process an authentication request packet */
/* Process a platform challange packet */
static void
licence_process_authreq(STREAM s)
licence_process_platform_challange(STREAM s)
{
uint8 *in_token = NULL, *in_sig;
uint8 out_token[LICENCE_TOKEN_SIZE], decrypt_token[LICENCE_TOKEN_SIZE];
@ -246,7 +260,7 @@ licence_process_authreq(STREAM s)
void * crypt_key;
/* Parse incoming packet and save the encrypted token */
licence_parse_authreq(s, &in_token, &in_sig);
licence_parse_platform_challange(s, &in_token, &in_sig);
memcpy(out_token, in_token, LICENCE_TOKEN_SIZE);
/* Decrypt the token. It should read TEST in Unicode. */
@ -267,19 +281,18 @@ licence_process_authreq(STREAM s)
ssl_rc4_crypt(crypt_key, (char *)hwid, (char *)crypt_hwid, LICENCE_HWID_SIZE);
ssl_rc4_info_delete(crypt_key);
licence_send_authresp(out_token, crypt_hwid, out_sig);
licence_send_platform_challange_response(out_token, crypt_hwid, out_sig);
}
/* Process an licence issue packet */
/* Process a new licence packet */
static void
licence_process_issue(STREAM s)
licence_process_new_license(STREAM s)
{
void * crypt_key;
uint32 length;
uint16 check;
int i;
in_uint8s(s, 2); /* 3d 45 - unknown */
in_uint8s(s, 2); // Skip license binary blob type
in_uint16_le(s, length);
if (!s_check_rem(s, length))
return;
@ -289,15 +302,11 @@ licence_process_issue(STREAM s)
ssl_rc4_crypt(crypt_key, (char *)s->p, (char *)s->p, length);
ssl_rc4_info_delete(crypt_key);
in_uint16(s, check);
if (check != 0)
return;
/* Parse NEW_LICENSE_INFO block */
in_uint8s(s, 4); // skip dwVersion
g_licence_issued = True;
in_uint8s(s, 2); /* pad */
/* advance to fourth string */
/* Skip strings, Scope, CompanyName and ProductId to get
to the LicenseInfo which we store in license blob. */
length = 0;
for (i = 0; i < 4; i++)
{
@ -311,6 +320,60 @@ licence_process_issue(STREAM s)
save_licence(s->p, length);
}
/* process a licence error alert packet */
void
licence_process_error_alert(STREAM s)
{
uint32 error_code;
uint32 state_transition;
uint32 error_info;
in_uint32(s, error_code);
in_uint32(s, state_transition);
in_uint32(s, error_info);
/* There is a special case in the error alert handling, when licensing is all good
and the server is not sending a license to client, a "Server License Error PDU -
Valid Client" packet is sent which means, every thing is ok.
Therefor we should flag that everything is ok with license here.
*/
if (error_code == 0x07)
{
g_licence_issued = True;
return;
}
/* handle error codes, for now, jsut report them */
switch (error_code)
{
case 0x6: // ERR_NO_LICENSE_SERVER
warning("License error alert from server: No license server\n");
break;
case 0x8: // ERR_INVALID_CLIENT
warning("License error alert from server: Invalid client\n");
break;
case 0x4: // ERR_INVALID_SCOPE
case 0xb: // ERR_INVALID_PRODUCTID
case 0xc: // ERR_INVALID_MESSAGE_LENGTH
default:
warning("License error alert from server: code %u, state transition %u\n",
error_code, state_transition);
break;
}
/* handle error codes, for now, jsut report them */
switch (error_info)
{
default:
break;
}
g_licence_error_result = True;
}
/* Process a licence packet */
void
licence_process(STREAM s)
@ -320,25 +383,31 @@ licence_process(STREAM s)
in_uint8(s, tag);
in_uint8s(s, 3); /* version, length */
#if WITH_DEBUG
DEBUG(("Received licensing PDU (message type 0x%02x)\n", tag));
#endif
switch (tag)
{
case LICENCE_TAG_DEMAND:
licence_process_demand(s);
case LICENCE_TAG_REQUEST:
licence_process_request(s);
break;
case LICENCE_TAG_AUTHREQ:
licence_process_authreq(s);
case LICENCE_TAG_PLATFORM_CHALLANGE:
licence_process_platform_challange(s);
break;
case LICENCE_TAG_ISSUE:
licence_process_issue(s);
case LICENCE_TAG_NEW_LICENCE:
case LICENCE_TAG_UPGRADE_LICENCE:
/* we can handle new and upgrades of licences the same way. */
licence_process_new_license(s);
break;
case LICENCE_TAG_REISSUE:
case LICENCE_TAG_RESULT:
case LICENCE_TAG_ERROR_ALERT:
licence_process_error_alert(s);
break;
default:
unimpl("licence tag 0x%x\n", tag);
unimpl("licence tag 0x%02x\n", tag);
}
}

View file

@ -1,11 +1,12 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Protocol services - Multipoint Communications Service
Copyright (C) Matthew Chapman 1999-2005
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
Copyright 2005-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
This program is free software; you can redistribute it and/or modify
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@ -13,9 +14,8 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "precomp.h"
@ -24,70 +24,6 @@ uint16 g_mcs_userid;
extern VCHANNEL g_channels[];
extern unsigned int g_num_channels;
/* Parse an ASN.1 BER header */
static BOOL
ber_parse_header(STREAM s, int tagval, int *length)
{
int tag, len;
if (tagval > 0xff)
{
in_uint16_be(s, tag);
}
else
{
in_uint8(s, tag)}
if (tag != tagval)
{
error("expected tag %d, got %d\n", tagval, tag);
return False;
}
in_uint8(s, len);
if (len & 0x80)
{
len &= ~0x80;
*length = 0;
while (len--)
next_be(s, *length);
}
else
*length = len;
return s_check(s);
}
/* Output an ASN.1 BER header */
static void
ber_out_header(STREAM s, int tagval, int length)
{
if (tagval > 0xff)
{
out_uint16_be(s, tagval);
}
else
{
out_uint8(s, tagval);
}
if (length >= 0x80)
{
out_uint8(s, 0x82);
out_uint16_be(s, length);
}
else
out_uint8(s, length);
}
/* Output an ASN.1 BER integer */
static void
ber_out_integer(STREAM s, int value)
{
ber_out_header(s, BER_TAG_INTEGER, 2);
out_uint16_be(s, value);
}
/* Output a DOMAIN_PARAMS structure (ASN.1 BER) */
static void
@ -105,7 +41,7 @@ mcs_out_domain_params(STREAM s, int max_channels, int max_users, int max_tokens,
}
/* Parse a DOMAIN_PARAMS structure (ASN.1 BER) */
static BOOL
static RD_BOOL
mcs_parse_domain_params(STREAM s)
{
int length;
@ -147,7 +83,7 @@ mcs_send_connect_initial(STREAM mcs_data)
}
/* Expect a MCS_CONNECT_RESPONSE message (ASN.1 BER) */
static BOOL
static RD_BOOL
mcs_recv_connect_response(STREAM mcs_data)
{
uint8 result;
@ -221,7 +157,7 @@ mcs_send_aurq(void)
}
/* Expect a AUcf message (ASN.1 PER) */
static BOOL
static RD_BOOL
mcs_recv_aucf(uint16 * mcs_userid)
{
uint8 opcode, result;
@ -270,7 +206,7 @@ mcs_send_cjrq(uint16 chanid)
}
/* Expect a CJcf message (ASN.1 PER) */
static BOOL
static RD_BOOL
mcs_recv_cjcf(void)
{
uint8 opcode, result;
@ -371,56 +307,18 @@ mcs_recv(uint16 * channel, uint8 * rdpver)
return s;
}
/* Establish a connection up to the MCS layer */
BOOL
mcs_connect(char *server, STREAM mcs_data, char *username)
RD_BOOL
mcs_connect_start(char *server, char *username, char *domain, char *password,
RD_BOOL reconnect, uint32 * selected_protocol)
{
unsigned int i;
if (!iso_connect(server, username))
return False;
mcs_send_connect_initial(mcs_data);
if (!mcs_recv_connect_response(mcs_data))
goto error;
mcs_send_edrq();
mcs_send_aurq();
if (!mcs_recv_aucf(&g_mcs_userid))
goto error;
mcs_send_cjrq((uint16) (g_mcs_userid + MCS_USERCHANNEL_BASE));
if (!mcs_recv_cjcf())
goto error;
mcs_send_cjrq(MCS_GLOBAL_CHANNEL);
if (!mcs_recv_cjcf())
goto error;
for (i = 0; i < g_num_channels; i++)
{
mcs_send_cjrq(g_channels[i].mcs_id);
if (!mcs_recv_cjcf())
goto error;
}
return True;
error:
iso_disconnect();
return False;
return iso_connect(server, username, domain, password, reconnect, selected_protocol);
}
/* Establish a connection up to the MCS layer */
BOOL
mcs_reconnect(char *server, STREAM mcs_data)
RD_BOOL
mcs_connect_finalize(STREAM mcs_data)
{
unsigned int i;
if (!iso_reconnect(server))
return False;
mcs_send_connect_initial(mcs_data);
if (!mcs_recv_connect_response(mcs_data))
goto error;
@ -431,7 +329,7 @@ mcs_reconnect(char *server, STREAM mcs_data)
if (!mcs_recv_aucf(&g_mcs_userid))
goto error;
mcs_send_cjrq((uint16) (g_mcs_userid + MCS_USERCHANNEL_BASE));
mcs_send_cjrq(g_mcs_userid + MCS_USERCHANNEL_BASE);
if (!mcs_recv_cjcf())
goto error;

View file

@ -1,11 +1,11 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Protocol services - RDP decompression
Copyright (C) Matthew Chapman 1999-2005
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
This program is free software; you can redistribute it and/or modify
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@ -13,11 +13,13 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <string.h>
#include "precomp.h"
/* mppc decompression */
@ -60,7 +62,7 @@ mppc_expand(uint8 * data, uint32 clen, uint8 ctype, uint32 * roff, uint32 * rlen
int next_offset, match_off;
int match_len;
int old_offset, match_bits;
BOOL big = ctype & RDP_MPPC_BIG ? True : False;
RD_BOOL big = ctype & RDP_MPPC_BIG ? True : False;
uint8 *dict = g_mppc_dict.hist;

View file

@ -1,11 +1,11 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
RDP order processing
Copyright (C) Matthew Chapman 1999-2005
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
This program is free software; you can redistribute it and/or modify
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@ -13,18 +13,16 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "precomp.h"
#include "orders.h"
extern uint8 *g_next_packet;
static RDP_ORDER_STATE g_order_state;
extern BOOL g_use_rdp5;
extern RDP_VERSION g_rdp_version;
/* Read field indicating which parameters are present */
static void
@ -56,7 +54,7 @@ rdp_in_present(STREAM s, uint32 * present, uint8 flags, int size)
/* Read a co-ordinate (16-bit, or 8-bit delta) */
static void
rdp_in_coord(STREAM s, sint16 * coord, BOOL delta)
rdp_in_coord(STREAM s, sint16 * coord, RD_BOOL delta)
{
sint8 change;
@ -103,7 +101,7 @@ rdp_in_colour(STREAM s, uint32 * colour)
}
/* Parse bounds information */
static BOOL
static RD_BOOL
rdp_parse_bounds(STREAM s, BOUNDS * bounds)
{
uint8 present;
@ -134,7 +132,7 @@ rdp_parse_bounds(STREAM s, BOUNDS * bounds)
}
/* Parse a pen */
static BOOL
static RD_BOOL
rdp_parse_pen(STREAM s, PEN * pen, uint32 present)
{
if (present & 1)
@ -149,8 +147,35 @@ rdp_parse_pen(STREAM s, PEN * pen, uint32 present)
return s_check(s);
}
static void
setup_brush(BRUSH * out_brush, BRUSH * in_brush)
{
BRUSHDATA *brush_data;
uint8 cache_idx;
uint8 colour_code;
memcpy(out_brush, in_brush, sizeof(BRUSH));
if (out_brush->style & 0x80)
{
colour_code = out_brush->style & 0x0f;
cache_idx = out_brush->pattern[0];
brush_data = cache_get_brush_data(colour_code, cache_idx);
if ((brush_data == NULL) || (brush_data->data == NULL))
{
error("error getting brush data, style %x\n", out_brush->style);
out_brush->bd = NULL;
memset(out_brush->pattern, 0, 8);
}
else
{
out_brush->bd = brush_data;
}
out_brush->style = 3;
}
}
/* Parse a brush */
static BOOL
static RD_BOOL
rdp_parse_brush(STREAM s, BRUSH * brush, uint32 present)
{
if (present & 1)
@ -173,7 +198,7 @@ rdp_parse_brush(STREAM s, BRUSH * brush, uint32 present)
/* Process a destination blt order */
static void
process_destblt(STREAM s, DESTBLT_ORDER * os, uint32 present, BOOL delta)
process_destblt(STREAM s, DESTBLT_ORDER * os, uint32 present, RD_BOOL delta)
{
if (present & 0x01)
rdp_in_coord(s, &os->x, delta);
@ -198,8 +223,10 @@ process_destblt(STREAM s, DESTBLT_ORDER * os, uint32 present, BOOL delta)
/* Process a pattern blt order */
static void
process_patblt(STREAM s, PATBLT_ORDER * os, uint32 present, BOOL delta)
process_patblt(STREAM s, PATBLT_ORDER * os, uint32 present, RD_BOOL delta)
{
BRUSH brush;
if (present & 0x0001)
rdp_in_coord(s, &os->x, delta);
@ -226,13 +253,15 @@ process_patblt(STREAM s, PATBLT_ORDER * os, uint32 present, BOOL delta)
DEBUG(("PATBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,bs=%d,bg=0x%x,fg=0x%x)\n", os->opcode, os->x,
os->y, os->cx, os->cy, os->brush.style, os->bgcolour, os->fgcolour));
setup_brush(&brush, &os->brush);
ui_patblt(ROP2_P(os->opcode), os->x, os->y, os->cx, os->cy,
&os->brush, os->bgcolour, os->fgcolour);
&brush, os->bgcolour, os->fgcolour);
}
/* Process a screen blt order */
static void
process_screenblt(STREAM s, SCREENBLT_ORDER * os, uint32 present, BOOL delta)
process_screenblt(STREAM s, SCREENBLT_ORDER * os, uint32 present, RD_BOOL delta)
{
if (present & 0x0001)
rdp_in_coord(s, &os->x, delta);
@ -263,7 +292,7 @@ process_screenblt(STREAM s, SCREENBLT_ORDER * os, uint32 present, BOOL delta)
/* Process a line order */
static void
process_line(STREAM s, LINE_ORDER * os, uint32 present, BOOL delta)
process_line(STREAM s, LINE_ORDER * os, uint32 present, RD_BOOL delta)
{
if (present & 0x0001)
in_uint16_le(s, os->mixmode);
@ -297,12 +326,12 @@ process_line(STREAM s, LINE_ORDER * os, uint32 present, BOOL delta)
return;
}
ui_line(ROP_MINUS_1(os->opcode), os->startx, os->starty, os->endx, os->endy, &os->pen);
ui_line(os->opcode - 1, os->startx, os->starty, os->endx, os->endy, &os->pen);
}
/* Process an opaque rectangle order */
static void
process_rect(STREAM s, RECT_ORDER * os, uint32 present, BOOL delta)
process_rect(STREAM s, RECT_ORDER * os, uint32 present, RD_BOOL delta)
{
uint32 i;
if (present & 0x01)
@ -342,7 +371,7 @@ process_rect(STREAM s, RECT_ORDER * os, uint32 present, BOOL delta)
/* Process a desktop save order */
static void
process_desksave(STREAM s, DESKSAVE_ORDER * os, uint32 present, BOOL delta)
process_desksave(STREAM s, DESKSAVE_ORDER * os, uint32 present, RD_BOOL delta)
{
int width, height;
@ -378,9 +407,9 @@ process_desksave(STREAM s, DESKSAVE_ORDER * os, uint32 present, BOOL delta)
/* Process a memory blt order */
static void
process_memblt(STREAM s, MEMBLT_ORDER * os, uint32 present, BOOL delta)
process_memblt(STREAM s, MEMBLT_ORDER * os, uint32 present, RD_BOOL delta)
{
HBITMAP bitmap;
RD_HBITMAP bitmap;
if (present & 0x0001)
{
@ -424,9 +453,10 @@ process_memblt(STREAM s, MEMBLT_ORDER * os, uint32 present, BOOL delta)
/* Process a 3-way blt order */
static void
process_triblt(STREAM s, TRIBLT_ORDER * os, uint32 present, BOOL delta)
process_triblt(STREAM s, TRIBLT_ORDER * os, uint32 present, RD_BOOL delta)
{
HBITMAP bitmap;
RD_HBITMAP bitmap;
BRUSH brush;
if (present & 0x000001)
{
@ -477,17 +507,19 @@ process_triblt(STREAM s, TRIBLT_ORDER * os, uint32 present, BOOL delta)
if (bitmap == NULL)
return;
setup_brush(&brush, &os->brush);
ui_triblt(os->opcode, os->x, os->y, os->cx, os->cy,
bitmap, os->srcx, os->srcy, &os->brush, os->bgcolour, os->fgcolour);
bitmap, os->srcx, os->srcy, &brush, os->bgcolour, os->fgcolour);
}
/* Process a polygon order */
static void
process_polygon(STREAM s, POLYGON_ORDER * os, uint32 present, BOOL delta)
process_polygon(STREAM s, POLYGON_ORDER * os, uint32 present, RD_BOOL delta)
{
int index, data, next;
uint8 flags = 0;
POINT *points;
RD_POINT *points;
if (present & 0x01)
rdp_in_coord(s, &os->x, delta);
@ -529,8 +561,8 @@ process_polygon(STREAM s, POLYGON_ORDER * os, uint32 present, BOOL delta)
return;
}
points = (POINT *) xmalloc((os->npoints + 1) * sizeof(POINT));
memset(points, 0, (os->npoints + 1) * sizeof(POINT));
points = (RD_POINT *) xmalloc((os->npoints + 1) * sizeof(RD_POINT));
memset(points, 0, (os->npoints + 1) * sizeof(RD_POINT));
points[0].x = os->x;
points[0].y = os->y;
@ -552,7 +584,7 @@ process_polygon(STREAM s, POLYGON_ORDER * os, uint32 present, BOOL delta)
}
if (next - 1 == os->npoints)
ui_polygon(ROP_MINUS_1(os->opcode), os->fillmode, points, os->npoints + 1, NULL, 0,
ui_polygon(os->opcode - 1, os->fillmode, points, os->npoints + 1, NULL, 0,
os->fgcolour);
else
error("polygon parse error\n");
@ -562,11 +594,12 @@ process_polygon(STREAM s, POLYGON_ORDER * os, uint32 present, BOOL delta)
/* Process a polygon2 order */
static void
process_polygon2(STREAM s, POLYGON2_ORDER * os, uint32 present, BOOL delta)
process_polygon2(STREAM s, POLYGON2_ORDER * os, uint32 present, RD_BOOL delta)
{
int index, data, next;
uint8 flags = 0;
POINT *points;
RD_POINT *points;
BRUSH brush;
if (present & 0x0001)
rdp_in_coord(s, &os->x, delta);
@ -614,8 +647,10 @@ process_polygon2(STREAM s, POLYGON2_ORDER * os, uint32 present, BOOL delta)
return;
}
points = (POINT *) xmalloc((os->npoints + 1) * sizeof(POINT));
memset(points, 0, (os->npoints + 1) * sizeof(POINT));
setup_brush(&brush, &os->brush);
points = (RD_POINT *) xmalloc((os->npoints + 1) * sizeof(RD_POINT));
memset(points, 0, (os->npoints + 1) * sizeof(RD_POINT));
points[0].x = os->x;
points[0].y = os->y;
@ -637,8 +672,8 @@ process_polygon2(STREAM s, POLYGON2_ORDER * os, uint32 present, BOOL delta)
}
if (next - 1 == os->npoints)
ui_polygon(ROP_MINUS_1(os->opcode), os->fillmode, points, os->npoints + 1,
&os->brush, os->bgcolour, os->fgcolour);
ui_polygon(os->opcode - 1, os->fillmode, points, os->npoints + 1,
&brush, os->bgcolour, os->fgcolour);
else
error("polygon2 parse error\n");
@ -647,12 +682,12 @@ process_polygon2(STREAM s, POLYGON2_ORDER * os, uint32 present, BOOL delta)
/* Process a polyline order */
static void
process_polyline(STREAM s, POLYLINE_ORDER * os, uint32 present, BOOL delta)
process_polyline(STREAM s, POLYLINE_ORDER * os, uint32 present, RD_BOOL delta)
{
int index, next, data;
uint8 flags = 0;
PEN pen;
POINT *points;
RD_POINT *points;
if (present & 0x01)
rdp_in_coord(s, &os->x, delta);
@ -691,8 +726,8 @@ process_polyline(STREAM s, POLYLINE_ORDER * os, uint32 present, BOOL delta)
return;
}
points = (POINT *) xmalloc((os->lines + 1) * sizeof(POINT));
memset(points, 0, (os->lines + 1) * sizeof(POINT));
points = (RD_POINT *) xmalloc((os->lines + 1) * sizeof(RD_POINT));
memset(points, 0, (os->lines + 1) * sizeof(RD_POINT));
points[0].x = os->x;
points[0].y = os->y;
@ -716,7 +751,7 @@ process_polyline(STREAM s, POLYLINE_ORDER * os, uint32 present, BOOL delta)
}
if (next - 1 == os->lines)
ui_polyline(ROP_MINUS_1(os->opcode), points, os->lines + 1, &pen);
ui_polyline(os->opcode - 1, points, os->lines + 1, &pen);
else
error("polyline parse error\n");
@ -725,7 +760,7 @@ process_polyline(STREAM s, POLYLINE_ORDER * os, uint32 present, BOOL delta)
/* Process an ellipse order */
static void
process_ellipse(STREAM s, ELLIPSE_ORDER * os, uint32 present, BOOL delta)
process_ellipse(STREAM s, ELLIPSE_ORDER * os, uint32 present, RD_BOOL delta)
{
if (present & 0x01)
rdp_in_coord(s, &os->left, delta);
@ -751,14 +786,16 @@ process_ellipse(STREAM s, ELLIPSE_ORDER * os, uint32 present, BOOL delta)
DEBUG(("ELLIPSE(l=%d,t=%d,r=%d,b=%d,op=0x%x,fm=%d,fg=0x%x)\n", os->left, os->top,
os->right, os->bottom, os->opcode, os->fillmode, os->fgcolour));
ui_ellipse(ROP_MINUS_1(os->opcode), os->fillmode, os->left, os->top, os->right - os->left,
ui_ellipse(os->opcode - 1, os->fillmode, os->left, os->top, os->right - os->left,
os->bottom - os->top, NULL, 0, os->fgcolour);
}
/* Process an ellipse2 order */
static void
process_ellipse2(STREAM s, ELLIPSE2_ORDER * os, uint32 present, BOOL delta)
process_ellipse2(STREAM s, ELLIPSE2_ORDER * os, uint32 present, RD_BOOL delta)
{
BRUSH brush;
if (present & 0x0001)
rdp_in_coord(s, &os->left, delta);
@ -789,15 +826,18 @@ process_ellipse2(STREAM s, ELLIPSE2_ORDER * os, uint32 present, BOOL delta)
os->left, os->top, os->right, os->bottom, os->opcode, os->fillmode, os->brush.style,
os->bgcolour, os->fgcolour));
ui_ellipse(ROP_MINUS_1(os->opcode), os->fillmode, os->left, os->top, os->right - os->left,
os->bottom - os->top, &os->brush, os->bgcolour, os->fgcolour);
setup_brush(&brush, &os->brush);
ui_ellipse(os->opcode - 1, os->fillmode, os->left, os->top, os->right - os->left,
os->bottom - os->top, &brush, os->bgcolour, os->fgcolour);
}
/* Process a text order */
static void
process_text2(STREAM s, TEXT2_ORDER * os, uint32 present, BOOL delta)
process_text2(STREAM s, TEXT2_ORDER * os, uint32 present, RD_BOOL delta)
{
int i;
BRUSH brush;
if (present & 0x000001)
in_uint8(s, os->font);
@ -864,18 +904,20 @@ process_text2(STREAM s, TEXT2_ORDER * os, uint32 present, BOOL delta)
DEBUG(("\n"));
ui_draw_text(os->font, os->flags, ROP_MINUS_1(os->opcode), os->mixmode, os->x, os->y,
setup_brush(&brush, &os->brush);
ui_draw_text(os->font, os->flags, os->opcode - 1, os->mixmode, os->x, os->y,
os->clipleft, os->cliptop, os->clipright - os->clipleft,
os->clipbottom - os->cliptop, os->boxleft, os->boxtop,
os->boxright - os->boxleft, os->boxbottom - os->boxtop,
&os->brush, os->bgcolour, os->fgcolour, os->text, os->length);
&brush, os->bgcolour, os->fgcolour, os->text, os->length);
}
/* Process a raw bitmap cache order */
static void
process_raw_bmpcache(STREAM s)
{
HBITMAP bitmap;
RD_HBITMAP bitmap;
uint16 cache_idx, bufsize;
uint8 cache_id, width, height, bpp, Bpp;
uint8 *data, *inverted;
@ -908,7 +950,7 @@ process_raw_bmpcache(STREAM s)
static void
process_bmpcache(STREAM s)
{
HBITMAP bitmap;
RD_HBITMAP bitmap;
uint16 cache_idx, size;
uint8 cache_id, width, height, bpp, Bpp;
uint8 *data, *bmpdata;
@ -926,7 +968,7 @@ process_bmpcache(STREAM s)
in_uint16_le(s, bufsize); /* bufsize */
in_uint16_le(s, cache_idx);
if (g_use_rdp5)
if (g_rdp_version >= RDP_V5)
{
size = bufsize;
}
@ -944,7 +986,6 @@ process_bmpcache(STREAM s)
in_uint8p(s, data, size);
DEBUG(("BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d,bpp=%d,size=%d,pad1=%d,bufsize=%d,pad2=%d,rs=%d,fs=%d)\n", width, height, cache_id, cache_idx, bpp, size, pad1, bufsize, pad2, row_size, final_size));
(void)pad1; (void)pad2;
bmpdata = (uint8 *) xmalloc(width * height * Bpp);
@ -957,15 +998,16 @@ process_bmpcache(STREAM s)
{
DEBUG(("Failed to decompress bitmap data\n"));
}
if (pad1 || pad2) {}
xfree(bmpdata);
}
/* Process a bitmap cache v2 order */
static void
process_bmpcache2(STREAM s, uint16 flags, BOOL compressed)
process_bmpcache2(STREAM s, uint16 flags, RD_BOOL compressed)
{
HBITMAP bitmap;
RD_HBITMAP bitmap;
int y;
uint8 cache_id, cache_idx_low, width, height, Bpp;
uint16 cache_idx, bufsize;
@ -1031,7 +1073,7 @@ process_bmpcache2(STREAM s, uint16 flags, BOOL compressed)
cache_put_bitmap(cache_id, cache_idx, bitmap);
if (flags & PERSIST)
pstcache_save_bitmap(cache_id, cache_idx, bitmap_id, width, height,
(uint16) (width * height * Bpp), bmpdata);
width * height * Bpp, bmpdata);
}
else
{
@ -1106,6 +1148,109 @@ process_fontcache(STREAM s)
}
}
static void
process_compressed_8x8_brush_data(uint8 * in, uint8 * out, int Bpp)
{
int x, y, pal_index, in_index, shift, do2, i;
uint8 *pal;
in_index = 0;
pal = in + 16;
/* read it bottom up */
for (y = 7; y >= 0; y--)
{
/* 2 bytes per row */
x = 0;
for (do2 = 0; do2 < 2; do2++)
{
/* 4 pixels per byte */
shift = 6;
while (shift >= 0)
{
pal_index = (in[in_index] >> shift) & 3;
/* size of palette entries depends on Bpp */
for (i = 0; i < Bpp; i++)
{
out[(y * 8 + x) * Bpp + i] = pal[pal_index * Bpp + i];
}
x++;
shift -= 2;
}
in_index++;
}
}
}
/* Process a brush cache order */
static void
process_brushcache(STREAM s, uint16 flags)
{
BRUSHDATA brush_data;
uint8 cache_idx, colour_code, width, height, size, type;
uint8 *comp_brush;
int index;
int Bpp;
in_uint8(s, cache_idx);
in_uint8(s, colour_code);
in_uint8(s, width);
in_uint8(s, height);
in_uint8(s, type); /* type, 0x8x = cached */
in_uint8(s, size);
DEBUG(("BRUSHCACHE(idx=%d,wd=%d,ht=%d,sz=%d)\n", cache_idx, width, height, size));
if ((width == 8) && (height == 8))
{
if (colour_code == 1)
{
brush_data.colour_code = 1;
brush_data.data_size = 8;
brush_data.data = xmalloc(8);
if (size == 8)
{
/* read it bottom up */
for (index = 7; index >= 0; index--)
{
in_uint8(s, brush_data.data[index]);
}
}
else
{
warning("incompatible brush, colour_code %d size %d\n", colour_code,
size);
}
cache_put_brush_data(1, cache_idx, &brush_data);
}
else if ((colour_code >= 3) && (colour_code <= 6))
{
Bpp = colour_code - 2;
brush_data.colour_code = colour_code;
brush_data.data_size = 8 * 8 * Bpp;
brush_data.data = xmalloc(8 * 8 * Bpp);
if (size == 16 + 4 * Bpp)
{
in_uint8p(s, comp_brush, 16 + 4 * Bpp);
process_compressed_8x8_brush_data(comp_brush, brush_data.data, Bpp);
}
else
{
in_uint8a(s, brush_data.data, 8 * 8 * Bpp);
}
cache_put_brush_data(colour_code, cache_idx, &brush_data);
}
else
{
warning("incompatible brush, colour_code %d size %d\n", colour_code, size);
}
}
else
{
warning("incompatible brush, width height %d %d\n", width, height);
}
if (type) {}
}
/* Process a secondary order */
static void
process_secondary_order(STREAM s)
@ -1150,6 +1295,10 @@ process_secondary_order(STREAM s)
process_bmpcache2(s, flags, True); /* compressed */
break;
case RDP_ORDER_BRUSHCACHE:
process_brushcache(s, flags);
break;
default:
unimpl("secondary order %d\n", type);
}
@ -1165,7 +1314,7 @@ process_orders(STREAM s, uint16 num_orders)
uint32 present;
uint8 order_flags;
int size, processed = 0;
BOOL delta;
RD_BOOL delta;
while (processed < num_orders)
{

View file

@ -1,11 +1,11 @@
/*
rdesktop: A Remote Desktop Protocol client.
RDP order processing
Copyright (C) Matthew Chapman 1999-2005
Copyright (C) Matthew Chapman 1999-2008
This program is free software; you can redistribute it and/or modify
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@ -13,13 +13,10 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#define RDP_ORDER_STANDARD 0x01
#define RDP_ORDER_SECONDARY 0x02
#define RDP_ORDER_BOUNDS 0x04

View file

@ -1,11 +1,12 @@
/*
rdesktop: A Remote Desktop Protocol client.
Parsing primitives
Copyright (C) Matthew Chapman 1999-2005
Copyright (C) Matthew Chapman 1999-2008
Copyright 2012 Henrik Andersson <hean01@cendio.se> for Cendio AB
This program is free software; you can redistribute it and/or modify
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@ -13,9 +14,8 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Parser state */
@ -42,6 +42,8 @@ typedef struct stream
#define s_check(s) ((s)->p <= (s)->end)
#define s_check_rem(s,n) ((s)->p + n <= (s)->end)
#define s_check_end(s) ((s)->p == (s)->end)
#define s_length(s) ((s)->end - (s)->data)
#define s_reset(s) ((s)->end = (s)->p = (s)->data)
#if defined(L_ENDIAN) && !defined(NEED_ALIGN)
#define in_uint16_le(s,v) { v = *(uint16 *)((s)->p); (s)->p += 2; }

View file

@ -20,6 +20,22 @@
#ifndef __TODO_MSTSC_H
#define __TODO_MSTSC_H
#define RDP_INFO_MOUSE 0x00000001
#define RDP_INFO_DISABLECTRLALTDEL 0x00000002
#define RDP_INFO_AUTOLOGON 0x00000008
#define RDP_INFO_UNICODE 0x00000010
#define RDP_INFO_MAXIMIZESHELL 0x00000020
#define RDP_INFO_COMPRESSION 0x00000080 /* mppc compression with 8kB histroy buffer */
#define RDP_INFO_ENABLEWINDOWSKEY 0x00000100
#define RDP_INFO_COMPRESSION2 0x00000200 /* rdp5 mppc compression with 64kB history buffer */
#define RDP_INFO_REMOTE_CONSOLE_AUDIO 0x00002000
#define RDP_INFO_PASSWORD_IS_SC_PIN 0x00040000
#define RDP5_DISABLE_NOTHING 0x00
#define RDP5_NO_WALLPAPER 0x01
#define RDP_LOGON_NORMAL (RDP_INFO_MOUSE | RDP_INFO_DISABLECTRLALTDEL | RDP_INFO_UNICODE | RDP_INFO_MAXIMIZESHELL)
#define IS_PERSISTENT(id) (id < 8 && g_pstcache_fd[id] > 0)
#define MAXKEY 256

View file

@ -1,10 +1,10 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Copyright (C) Matthew Chapman 1999-2005
Copyright (C) Matthew Chapman 1999-2008
This program is free software; you can redistribute it and/or modify
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@ -12,20 +12,26 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifndef RDESKTOP_PROTO_H
#define RDESKTOP_PROTO_H
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/* utils.c */
char *utils_string_escape(const char *str);
char *utils_string_unescape(const char *str);
int utils_locale_to_utf8(const char *src, size_t is, char *dest, size_t os);
int utils_mkdir_safe(const char *path, int mask);
int utils_mkdir_p(const char *path, int mask);
/* bitmap.c */
BOOL bitmap_decompress(uint8 * output, int width, int height, uint8 * input, int size, int Bpp);
RD_BOOL bitmap_decompress(uint8 * output, int width, int height, uint8 * input, int size, int Bpp);
/* cache.c */
void cache_rebuild_bmpcache_linked_list(uint8 id, sint16 * idx, int count);
void cache_bump_bitmap(uint8 id, uint16 idx, int bump);
@ -43,6 +49,8 @@ void cache_put_desktop(uint32 offset, int cx, int cy, int scanline, int bytes_pe
uint8 * data);
RD_HCURSOR cache_get_cursor(uint16 cache_idx);
void cache_put_cursor(uint16 cache_idx, RD_HCURSOR cursor);
BRUSHDATA *cache_get_brush_data(uint8 colour_code, uint8 idx);
void cache_put_brush_data(uint8 colour_code, uint8 idx, BRUSHDATA * brush_data);
/* channels.c */
VCHANNEL *channel_register(char *name, uint32 flags, void (*callback) (STREAM));
STREAM channel_init(VCHANNEL * channel, uint32 length);
@ -54,7 +62,15 @@ void cliprdr_send_native_format_announce(uint8 * formats_data, uint32 formats_da
void cliprdr_send_data_request(uint32 format);
void cliprdr_send_data(uint8 * data, uint32 length);
void cliprdr_set_mode(const char *optarg);
BOOL cliprdr_init(void);
RD_BOOL cliprdr_init(void);
/* ctrl.c */
int ctrl_init(const char *user, const char *domain, const char *host);
void ctrl_cleanup();
RD_BOOL ctrl_is_slave();
int ctrl_send_command(const char *cmd, const char *args);
void ctrl_add_fds(int *n, fd_set * rfds);
void ctrl_check_fds(fd_set * rfds, fd_set * wfds);
/* disk.c */
int disk_enum_devices(uint32 * id, char *optarg);
RD_NTSTATUS disk_query_information(RD_NTHANDLE handle, uint32 info_class, STREAM out);
@ -72,10 +88,12 @@ void ewmh_init(void);
STREAM iso_init(int length);
void iso_send(STREAM s);
STREAM iso_recv(uint8 * rdpver);
BOOL iso_connect(char *server, char *username);
BOOL iso_reconnect(char *server);
RD_BOOL iso_connect(char *server, char *username, char *domain, char *password, RD_BOOL reconnect,
uint32 * selected_protocol);
void iso_disconnect(void);
void iso_reset_state(void);
/* cssp.c */
RD_BOOL cssp_connect(char *server, char *user, char *domain, char *password, STREAM s);
/* licence.c */
void licence_process(STREAM s);
/* mcs.c */
@ -83,8 +101,9 @@ STREAM mcs_init(int length);
void mcs_send_to_channel(STREAM s, uint16 channel);
void mcs_send(STREAM s);
STREAM mcs_recv(uint16 * channel, uint8 * rdpver);
BOOL mcs_connect(char *server, STREAM mcs_data, char *username);
BOOL mcs_reconnect(char *server, STREAM mcs_data);
RD_BOOL mcs_connect_start(char *server, char *username, char *domain, char *password,
RD_BOOL reconnect, uint32 * selected_protocol);
RD_BOOL mcs_connect_finalize(STREAM s);
void mcs_disconnect(void);
void mcs_reset_state(void);
/* orders.c */
@ -99,17 +118,18 @@ int printercache_load_blob(char *printer_name, uint8 ** data);
void printercache_process(STREAM s);
/* pstcache.c */
void pstcache_touch_bitmap(uint8 cache_id, uint16 cache_idx, uint32 stamp);
BOOL pstcache_load_bitmap(uint8 cache_id, uint16 cache_idx);
BOOL pstcache_save_bitmap(uint8 cache_id, uint16 cache_idx, uint8 * key, uint8 width,
uint8 height, uint16 length, uint8 * data);
RD_BOOL pstcache_load_bitmap(uint8 cache_id, uint16 cache_idx);
RD_BOOL pstcache_save_bitmap(uint8 cache_id, uint16 cache_idx, uint8 * key, uint8 width,
uint8 height, uint16 length, uint8 * data);
int pstcache_enumerate(uint8 id, HASH_KEY * keylist);
BOOL pstcache_init(uint8 cache_id);
RD_BOOL pstcache_init(uint8 cache_id);
/* rdesktop.c */
int main(int argc, char *argv[]);
void generate_random(uint8 * random);
void *xmalloc(int size);
void exit_if_null(void *ptr);
char *xstrdup(const char *s);
void *xrealloc(void *oldmem, int size);
void *xrealloc(void *oldmem, size_t size);
void xfree(void *mem);
void error(char *format, ...);
void warning(char *format, ...);
@ -117,62 +137,67 @@ void unimpl(char *format, ...);
void hexdump(unsigned char *p, unsigned int len);
char *next_arg(char *src, char needle);
void toupper_str(char *p);
BOOL str_startswith(const char *s, const char *prefix);
BOOL str_handle_lines(const char *input, char **rest, str_handle_lines_t linehandler, void *data);
BOOL subprocess(char *const argv[], str_handle_lines_t linehandler, void *data);
RD_BOOL str_startswith(const char *s, const char *prefix);
RD_BOOL str_handle_lines(const char *input, char **rest, str_handle_lines_t linehandler,
void *data);
RD_BOOL subprocess(char *const argv[], str_handle_lines_t linehandler, void *data);
char *l_to_a(long N, int base);
int load_licence(unsigned char **data);
void save_licence(unsigned char *data, int length);
BOOL rd_pstcache_mkdir(void);
void rd_create_ui(void);
RD_BOOL rd_pstcache_mkdir(void);
int rd_open_file(char *filename);
void rd_close_file(int fd);
int rd_read_file(int fd, void *ptr, int len);
int rd_write_file(int fd, void *ptr, int len);
int rd_lseek_file(int fd, int offset);
BOOL rd_lock_file(int fd, int start, int len);
RD_BOOL rd_lock_file(int fd, int start, int len);
/* rdp5.c */
void rdp5_process(STREAM s);
/* rdp.c */
void rdp_out_unistr(STREAM s, char *string, int len);
int rdp_in_unistr(STREAM s, char *string, int uni_len);
void rdp_in_unistr(STREAM s, int in_len, char **string, uint32 * str_size);
void rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1,
uint16 param2);
void rdp_send_client_window_status(int status);
void process_colour_pointer_pdu(STREAM s);
void process_new_pointer_pdu(STREAM s);
void process_cached_pointer_pdu(STREAM s);
void process_system_pointer_pdu(STREAM s);
void process_bitmap_updates(STREAM s);
void process_palette(STREAM s);
void process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason);
void rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason);
BOOL rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason);
BOOL rdp_connect(char *server, uint32 flags, char *domain, char *password, char *command,
char *directory);
BOOL rdp_reconnect(char *server, uint32 flags, char *domain, char *password, char *command,
char *directory, char *cookie);
void rdp_main_loop(RD_BOOL * deactivated, uint32 * ext_disc_reason);
RD_BOOL rdp_loop(RD_BOOL * deactivated, uint32 * ext_disc_reason);
RD_BOOL rdp_connect(char *server, uint32 flags, char *domain, char *password, char *command,
char *directory, RD_BOOL reconnect);
void rdp_reset_state(void);
void rdp_disconnect(void);
/* rdpdr.c */
int get_device_index(RD_NTHANDLE handle);
void convert_to_unix_filename(char *filename);
BOOL rdpdr_init(void);
void rdpdr_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv, BOOL * timeout);
void rdpdr_send_completion(uint32 device, uint32 id, uint32 status, uint32 result, uint8 * buffer,
uint32 length);
RD_BOOL rdpdr_init();
void rdpdr_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv, RD_BOOL * timeout);
struct async_iorequest *rdpdr_remove_iorequest(struct async_iorequest *prev,
struct async_iorequest *iorq);
void rdpdr_check_fds(fd_set * rfds, fd_set * wfds, BOOL timed_out);
BOOL rdpdr_abort_io(uint32 fd, uint32 major, RD_NTSTATUS status);
void rdpdr_check_fds(fd_set * rfds, fd_set * wfds, RD_BOOL timed_out);
RD_BOOL rdpdr_abort_io(uint32 fd, uint32 major, RD_NTSTATUS status);
/* rdpsnd.c */
void rdpsnd_send_completion(uint16 tick, uint8 packet_index);
BOOL rdpsnd_init(void);
/* rdpsnd_oss.c */
BOOL wave_out_open(void);
void wave_out_close(void);
BOOL wave_out_format_supported(WAVEFORMATEX * pwfx);
BOOL wave_out_set_format(WAVEFORMATEX * pwfx);
void wave_out_volume(uint16 left, uint16 right);
void wave_out_write(STREAM s, uint16 tick, uint8 index);
void wave_out_play(void);
void rdpsnd_record(const void *data, unsigned int size);
RD_BOOL rdpsnd_init(char *optarg);
void rdpsnd_show_help(void);
void rdpsnd_add_fds(int *n, fd_set * rfds, fd_set * wfds, struct timeval *tv);
void rdpsnd_check_fds(fd_set * rfds, fd_set * wfds);
struct audio_packet *rdpsnd_queue_current_packet(void);
RD_BOOL rdpsnd_queue_empty(void);
void rdpsnd_queue_next(unsigned long completed_in_us);
int rdpsnd_queue_next_tick(void);
void rdpsnd_reset_state(void);
/* secure.c */
void sec_hash_to_string(char *out, int out_size, uint8 * in, int in_size);
void sec_hash_sha1_16(uint8 * out, uint8 * in, uint8 * salt1);
void sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt);
void sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2);
void buf_out_uint32(uint8 * buffer, uint32 value);
@ -184,22 +209,33 @@ void sec_send_to_channel(STREAM s, uint32 flags, uint16 channel);
void sec_send(STREAM s, uint32 flags);
void sec_process_mcs_data(STREAM s);
STREAM sec_recv(uint8 * rdpver);
BOOL sec_connect(char *server, char *username);
BOOL sec_reconnect(char *server);
RD_BOOL sec_connect(char *server, char *username, char *domain, char *password, RD_BOOL reconnect);
void sec_disconnect(void);
void sec_reset_state(void);
/* serial.c */
int serial_enum_devices(uint32 * id, char *optarg);
BOOL serial_get_event(RD_NTHANDLE handle, uint32 * result);
BOOL serial_get_timeout(RD_NTHANDLE handle, uint32 length, uint32 * timeout, uint32 * itv_timeout);
RD_BOOL serial_get_event(RD_NTHANDLE handle, uint32 * result);
RD_BOOL serial_get_timeout(RD_NTHANDLE handle, uint32 length, uint32 * timeout,
uint32 * itv_timeout);
/* tcp.c */
STREAM tcp_init(uint32 maxlen);
void tcp_send(STREAM s);
STREAM tcp_recv(STREAM s, uint32 length);
BOOL tcp_connect(char *server);
RD_BOOL tcp_connect(char *server);
void tcp_disconnect(void);
char *tcp_get_address(void);
RD_BOOL tcp_is_connected(void);
void tcp_reset_state(void);
RD_BOOL tcp_tls_connect(void);
RD_BOOL tcp_tls_get_server_pubkey(STREAM s);
void tcp_run_ui(RD_BOOL run);
/* asn.c */
RD_BOOL ber_in_header(STREAM s, int *tagval, int *length);
void ber_out_header(STREAM s, int tagval, int length);
RD_BOOL ber_parse_header(STREAM s, int tagval, int *length);
void ber_out_integer(STREAM s, int value);
/* xclip.c */
void ui_clip_format_announce(uint8 * data, uint32 length);
void ui_clip_handle_data(uint8 * data, uint32 length);
@ -208,14 +244,15 @@ void ui_clip_request_data(uint32 format);
void ui_clip_sync(void);
void ui_clip_set_mode(const char *optarg);
void xclip_init(void);
void xclip_deinit(void);
/* xkeymap.c */
BOOL xkeymap_from_locale(const char *locale);
RD_BOOL xkeymap_from_locale(const char *locale);
FILE *xkeymap_open(const char *filename);
void xkeymap_init(void);
BOOL handle_special_keys(uint32 keysym, unsigned int state, uint32 ev_time, BOOL pressed);
RD_BOOL handle_special_keys(uint32 keysym, unsigned int state, uint32 ev_time, RD_BOOL pressed);
key_translation xkeymap_translate_key(uint32 keysym, unsigned int keycode, unsigned int state);
void xkeymap_send_keys(uint32 keysym, unsigned int keycode, unsigned int state, uint32 ev_time,
BOOL pressed, uint8 nesting);
RD_BOOL pressed, uint8 nesting);
uint16 xkeymap_translate_button(unsigned int button);
char *get_ksname(uint32 keysym);
void save_remote_modifiers(uint8 scancode);
@ -226,12 +263,14 @@ uint16 ui_get_numlock_state(unsigned int state);
void reset_modifier_keys(void);
void rdp_send_scancode(uint32 time, uint16 flags, uint8 scancode);
/* xwin.c */
BOOL get_key_state(unsigned int state, uint32 keysym);
BOOL ui_init(void);
RD_BOOL get_key_state(unsigned int state, uint32 keysym);
RD_BOOL ui_init(void);
void ui_init_connection(void);
void ui_deinit(void);
BOOL ui_create_window(void);
RD_BOOL ui_create_window(void);
void ui_resize_window(void);
void ui_destroy_window(void);
RD_BOOL ui_have_window(void);
void xwin_toggle_fullscreen(void);
int ui_select(int rdp_socket);
void ui_move_pointer(int x, int y);
@ -241,7 +280,7 @@ void ui_destroy_bitmap(RD_HBITMAP bmp);
RD_HGLYPH ui_create_glyph(int width, int height, uint8 * data);
void ui_destroy_glyph(RD_HGLYPH glyph);
RD_HCURSOR ui_create_cursor(unsigned int x, unsigned int y, int width, int height, uint8 * andmask,
uint8 * xormask);
uint8 * xormask, int bpp);
void ui_set_cursor(RD_HCURSOR cursor);
void ui_destroy_cursor(RD_HCURSOR cursor);
void ui_set_null_cursor(void);
@ -260,9 +299,9 @@ void ui_triblt(uint8 opcode, int x, int y, int cx, int cy, RD_HBITMAP src, int s
BRUSH * brush, int bgcolour, int fgcolour);
void ui_line(uint8 opcode, int startx, int starty, int endx, int endy, PEN * pen);
void ui_rect(int x, int y, int cx, int cy, int colour);
void ui_polygon(uint8 opcode, uint8 fillmode, POINT * point, int npoints, BRUSH * brush,
void ui_polygon(uint8 opcode, uint8 fillmode, RD_POINT * point, int npoints, BRUSH * brush,
int bgcolour, int fgcolour);
void ui_polyline(uint8 opcode, POINT * points, int npoints, PEN * pen);
void ui_polyline(uint8 opcode, RD_POINT * points, int npoints, PEN * pen);
void ui_ellipse(uint8 opcode, uint8 fillmode, int x, int y, int cx, int cy, BRUSH * brush,
int bgcolour, int fgcolour);
void ui_draw_glyph(int mixmode, int x, int y, int cx, int cy, RD_HGLYPH glyph, int srcx, int srcy,
@ -274,13 +313,18 @@ void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy);
void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy);
void ui_begin_update(void);
void ui_end_update(void);
void ui_seamless_begin(BOOL hidden);
void ui_seamless_begin(RD_BOOL hidden);
void ui_seamless_end();
void ui_seamless_hide_desktop(void);
void ui_seamless_unhide_desktop(void);
void ui_seamless_toggle(void);
void ui_seamless_create_window(unsigned long id, unsigned long group, unsigned long parent,
unsigned long flags);
void ui_seamless_destroy_window(unsigned long id, unsigned long flags);
void ui_seamless_destroy_group(unsigned long id, unsigned long flags);
void ui_seamless_seticon(unsigned long id, const char *format, int width, int height, int chunk,
const char *data, int chunk_len);
void ui_seamless_delicon(unsigned long id, const char *format, int width, int height);
void ui_seamless_move_window(unsigned long id, int x, int y, int width, int height,
unsigned long flags);
void ui_seamless_restack_window(unsigned long id, unsigned long behind, unsigned long flags);
@ -289,9 +333,10 @@ void ui_seamless_setstate(unsigned long id, unsigned int state, unsigned long fl
void ui_seamless_syncbegin(unsigned long flags);
void ui_seamless_ack(unsigned int serial);
/* lspci.c */
BOOL lspci_init(void);
RD_BOOL lspci_init(void);
/* seamless.c */
BOOL seamless_init(void);
RD_BOOL seamless_init(void);
void seamless_reset_state(void);
unsigned int seamless_send_sync(void);
unsigned int seamless_send_state(unsigned long id, unsigned int state, unsigned long flags);
unsigned int seamless_send_position(unsigned long id, int x, int y, int width, int height,
@ -299,9 +344,21 @@ unsigned int seamless_send_position(unsigned long id, int x, int y, int width, i
void seamless_select_timeout(struct timeval *tv);
unsigned int seamless_send_zchange(unsigned long id, unsigned long below, unsigned long flags);
unsigned int seamless_send_focus(unsigned long id, unsigned long flags);
unsigned int seamless_send_destroy(unsigned long id);
unsigned int seamless_send_spawn(char *cmd);
unsigned int seamless_send_persistent(RD_BOOL);
/* scard.c */
void scard_lock(int lock);
void scard_unlock(int lock);
int scard_enum_devices(uint32 * id, char *optarg);
void scardSetInfo(uint32 epoch, uint32 device, uint32 id, uint32 bytes_out);
void scard_reset_state();
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif

View file

@ -1,11 +1,11 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Persistent Bitmap Cache routines
Copyright (C) Jeroen Meijer 2004-2005
Copyright (C) Jeroen Meijer <jeroen@oldambt7.com> 2004-2008
This program is free software; you can redistribute it and/or modify
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@ -13,23 +13,24 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "precomp.h"
#define MAX_CELL_SIZE 0x1000 /* pixels */
#define IS_PERSISTENT(id) (id < 8 && g_pstcache_fd[id] > 0)
extern int g_server_depth;
extern BOOL g_bitmap_cache;
extern BOOL g_bitmap_cache_persist_enable;
extern BOOL g_bitmap_cache_precache;
extern RD_BOOL g_bitmap_cache;
extern RD_BOOL g_bitmap_cache_persist_enable;
extern RD_BOOL g_bitmap_cache_precache;
int g_pstcache_fd[8];
int g_pstcache_Bpp;
BOOL g_pstcache_enumerated = False;
RD_BOOL g_pstcache_enumerated = False;
uint8 zero_key[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
@ -48,13 +49,13 @@ pstcache_touch_bitmap(uint8 cache_id, uint16 cache_idx, uint32 stamp)
}
/* Load a bitmap from the persistent cache */
BOOL
RD_BOOL
pstcache_load_bitmap(uint8 cache_id, uint16 cache_idx)
{
uint8 *celldata;
int fd;
CELLHEADER cellhdr;
HBITMAP bitmap;
RD_HBITMAP bitmap;
if (!g_bitmap_cache_persist_enable)
return False;
@ -62,8 +63,6 @@ pstcache_load_bitmap(uint8 cache_id, uint16 cache_idx)
if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS)
return False;
memset(&cellhdr, 0, sizeof(CELLHEADER));
fd = g_pstcache_fd[cache_id];
rd_lseek_file(fd, cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
rd_read_file(fd, &cellhdr, sizeof(CELLHEADER));
@ -71,7 +70,7 @@ pstcache_load_bitmap(uint8 cache_id, uint16 cache_idx)
rd_read_file(fd, celldata, cellhdr.length);
bitmap = ui_create_bitmap(cellhdr.width, cellhdr.height, celldata);
DEBUG(("Load bitmap from disk: id=%d, idx=%d, bmp=0x%x)\n", cache_id, cache_idx, bitmap));
DEBUG(("Load bitmap from disk: id=%d, idx=%d, bmp=%p)\n", cache_id, cache_idx, bitmap));
cache_put_bitmap(cache_id, cache_idx, bitmap);
xfree(celldata);
@ -79,7 +78,7 @@ pstcache_load_bitmap(uint8 cache_id, uint16 cache_idx)
}
/* Store a bitmap in the persistent cache */
BOOL
RD_BOOL
pstcache_save_bitmap(uint8 cache_id, uint16 cache_idx, uint8 * key,
uint8 width, uint8 height, uint16 length, uint8 * data)
{
@ -160,7 +159,7 @@ pstcache_enumerate(uint8 id, HASH_KEY * keylist)
}
/* initialise the persistent bitmap cache */
BOOL
RD_BOOL
pstcache_init(uint8 cache_id)
{
int fd;

View file

@ -1,11 +1,11 @@
/*
rdesktop: A Remote Desktop Protocol client.
Master include file
Copyright (C) Matthew Chapman 1999-2005
Copyright (C) Matthew Chapman 1999-2008
This program is free software; you can redistribute it and/or modify
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@ -13,19 +13,22 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef _WIN32
#include <winsock2.h> /* winsock2.h first */
#include <mmsystem.h>
#include <time.h>
#define DIR int
#else /* WIN32 */
#include <dirent.h>
#include <sys/types.h>
#include <sys/time.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
@ -35,8 +38,90 @@
#endif /* HAVE_SYS_SELECT_H */
#endif /* WIN32 */
//#include <limits.h> /* PATH_MAX */
#ifdef HAVE_SYSEXITS_H
#include <sysexits.h>
#endif
#define VERSION "1.4.1"
#define VERSION "1.8.3"
/* standard exit codes */
#ifndef EX_OK
#define EX_OK 0
#endif
#ifndef EX_USAGE
#define EX_USAGE 64
#endif
#ifndef EX_DATAERR
#define EX_DATAERR 65
#endif
#ifndef EX_NOINPUT
#define EX_NOINPUT 66
#endif
#ifndef EX_NOUSER
#define EX_NOUSER 67
#endif
#ifndef EX_NOHOST
#define EX_NOHOST 68
#endif
#ifndef EX_UNAVAILABLE
#define EX_UNAVAILABLE 69
#endif
#ifndef EX_SOFTWARE
#define EX_SOFTWARE 70
#endif
#ifndef EX_OSERR
#define EX_OSERR 71
#endif
#ifndef EX_OSFILE
#define EX_OSFILE 72
#endif
#ifndef EX_CANTCREAT
#define EX_CANTCREAT 73
#endif
#ifndef EX_IOERR
#define EX_IOERR 74
#endif
#ifndef EX_TEMPFAIL
#define EX_TEMPFAIL 75
#endif
#ifndef EX_PROTOCOL
#define EX_PROTOCOL 76
#endif
#ifndef EX_NOPERM
#define EX_NOPERM 77
#endif
#ifndef EX_CONFIG
#define EX_CONFIG 78
#endif
/* rdesktop specific exit codes, lined up with disconnect PDU reasons */
#define EXRD_API_DISCONNECT 1
#define EXRD_API_LOGOFF 2
#define EXRD_IDLE_TIMEOUT 3
#define EXRD_LOGON_TIMEOUT 4
#define EXRD_REPLACED 5
#define EXRD_OUT_OF_MEM 6
#define EXRD_DENIED 7
#define EXRD_DENIED_FIPS 8
#define EXRD_INSUFFICIENT_PRIVILEGES 9
#define EXRD_FRESH_CREDENTIALS_REQUIRED 10
#define EXRD_RPC_DISCONNECT_BY_USER 11
#define EXRD_DISCONNECT_BY_USER 12
#define EXRD_LIC_INTERNAL 16
#define EXRD_LIC_NOSERVER 17
#define EXRD_LIC_NOLICENSE 18
#define EXRD_LIC_MSG 19
#define EXRD_LIC_HWID 20
#define EXRD_LIC_CLIENT 21
#define EXRD_LIC_NET 22
#define EXRD_LIC_PROTO 23
#define EXRD_LIC_ENC 24
#define EXRD_LIC_UPGRADE 25
#define EXRD_LIC_NOREMOTE 26
/* other exit codes */
#define EXRD_WINDOW_CLOSED 62
#define EXRD_UNKNOWN 63
#ifdef WITH_DEBUG
#define DEBUG(args) printf args;
@ -62,12 +147,24 @@
#define DEBUG_CLIPBOARD(args)
#endif
#ifdef WITH_DEBUG_SOUND
#define DEBUG_SOUND(args) printf args;
#else
#define DEBUG_SOUND(args)
#endif
#ifdef WITH_DEBUG_CHANNEL
#define DEBUG_CHANNEL(args) printf args;
#else
#define DEBUG_CHANNEL(args)
#endif
#ifdef WITH_DEBUG_SCARD
#define DEBUG_SCARD(args) printf args;
#else
#define DEBUG_SCARD(args)
#endif
#define STRNCPY(dst,src,n) { strncpy(dst,src,n-1); dst[n-1] = 0; }
#ifndef MIN

File diff suppressed because it is too large Load diff

View file

@ -1,12 +1,12 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Protocol services - RDP5 short form PDU processing
Copyright (C) Matthew Chapman 1999-2005
Copyright (C) Erik Forsberg 2003
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
Copyright 2003-2008 Erik Forsberg <forsberg@cendio.se> for Cendio AB
This program is free software; you can redistribute it and/or modify
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@ -14,9 +14,8 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "precomp.h"
@ -111,6 +110,9 @@ rdp5_process(STREAM s)
case 10: /* cached pointer */
process_cached_pointer_pdu(ts);
break;
case 11:
process_new_pointer_pdu(ts);
break;
default:
unimpl("RDP5 opcode %d\n", type);
}

File diff suppressed because it is too large Load diff

View file

@ -713,6 +713,43 @@ ssl_md5_complete(void* md5_info, char* data)
PUT_UINT32(ctx->state[3], data, 12);
}
void APP_CC ssl_hmac_md5(char* key, int keylen, char* data, int len, char* output)
{
int i;
char ipad[64];
char opad[64];
char sum[16];
void* ctx;
if( keylen > 64 )
{
ctx = ssl_md5_info_create();
ssl_md5_transform(ctx, key, keylen);
ssl_md5_complete(ctx, sum);
ssl_md5_info_delete(ctx);
keylen = 16;
key = sum;
}
memset( ipad, 0x36, sizeof(ipad) );
memset( opad, 0x5C, sizeof(opad) );
for( i = 0; i < keylen; i++ )
{
ipad[i] = ipad[i] ^ key[i];
opad[i] = opad[i] ^ key[i];
}
ctx = ssl_md5_info_create();
ssl_md5_transform(ctx, ipad, sizeof(ipad));
ssl_md5_transform(ctx, data, len);
ssl_md5_complete(ctx, sum);
ssl_md5_info_delete(ctx);
ctx = ssl_md5_info_create();
ssl_md5_transform(ctx, opad, sizeof(opad));
ssl_md5_complete(ctx, output);
ssl_md5_info_delete(ctx);
}
/*****************************************************************************/
/*****************************************************************************/
/* big number stuff */

View file

@ -1,11 +1,13 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Protocol services - TCP layer
Copyright (C) Matthew Chapman 1999-2005
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
Copyright 2005-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
Copyright 2012-2013 Henrik Andersson <hean01@cendio.se> for Cendio AB
This program is free software; you can redistribute it and/or modify
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@ -13,9 +15,8 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "precomp.h"
@ -37,70 +38,150 @@
#define INADDR_NONE ((unsigned long) -1)
#endif
static int sock;
static struct stream in;
static struct stream out;
#ifdef WITH_SCARD
#define STREAM_COUNT 8
#else
#define STREAM_COUNT 1
#endif
#ifdef WITH_SSL
static RD_BOOL g_ssl_initialized = False;
static SSL *g_ssl = NULL;
static SSL_CTX *g_ssl_ctx = NULL;
#endif /* WITH_SSL */
static int g_sock;
static struct stream g_in;
static struct stream g_out[STREAM_COUNT];
int g_tcp_port_rdp = TCP_PORT_RDP;
extern RD_BOOL g_user_quit;
extern RD_BOOL g_network_error;
extern RD_BOOL g_reconnect_loop;
/* Initialise TCP transport data packet */
STREAM
tcp_init(uint32 maxlen)
{
if (maxlen > out.size)
static int cur_stream_id = 0;
STREAM result = NULL;
#ifdef WITH_SCARD
scard_lock(SCARD_LOCK_TCP);
#endif
result = &g_out[cur_stream_id];
cur_stream_id = (cur_stream_id + 1) % STREAM_COUNT;
if (maxlen > result->size)
{
out.data = (uint8 *) xrealloc(out.data, maxlen);
out.size = maxlen;
result->data = (uint8 *) xrealloc(result->data, maxlen);
result->size = maxlen;
}
out.p = out.data;
out.end = out.data + out.size;
return &out;
result->p = result->data;
result->end = result->data + result->size;
#ifdef WITH_SCARD
scard_unlock(SCARD_LOCK_TCP);
#endif
return result;
}
/* Send TCP transport data packet */
void
tcp_send(STREAM s)
{
#ifdef WITH_SSL
int ssl_err;
#endif /* WITH_SSL */
int length = s->end - s->data;
int sent, total = 0;
if (g_network_error == True)
return;
#ifdef WITH_SCARD
scard_lock(SCARD_LOCK_TCP);
#endif
while (total < length)
{
sent = send(sock, (char *)s->data + total, length - total, 0);
if (sent <= 0)
#ifdef WITH_SSL
if (g_ssl)
{
if (sent == -1 && TCP_BLOCKS)
sent = SSL_write(g_ssl, s->data + total, length - total);
if (sent <= 0)
{
TCP_SLEEP(0);
sent = 0;
}
else
{
error("send: %s\n", TCP_STRERROR);
return;
ssl_err = SSL_get_error(g_ssl, sent);
if (sent < 0 && (ssl_err == SSL_ERROR_WANT_READ ||
ssl_err == SSL_ERROR_WANT_WRITE))
{
TCP_SLEEP(0);
sent = 0;
}
else
{
#ifdef WITH_SCARD
scard_unlock(SCARD_LOCK_TCP);
#endif
error("SSL_write: %d (%s)\n", ssl_err, TCP_STRERROR);
g_network_error = True;
return;
}
}
}
else
{
#endif /* WITH_SSL */
sent = send(g_sock, (const char *)s->data + total, length - total, 0);
if (sent <= 0)
{
if (sent == -1 && TCP_BLOCKS)
{
TCP_SLEEP(0);
sent = 0;
}
else
{
#ifdef WITH_SCARD
scard_unlock(SCARD_LOCK_TCP);
#endif
error("send: %s\n", TCP_STRERROR);
g_network_error = True;
return;
}
}
#ifdef WITH_SSL
}
#endif /* WITH_SSL */
total += sent;
}
#ifdef WITH_SCARD
scard_unlock(SCARD_LOCK_TCP);
#endif
}
/* Receive a message on the TCP layer */
STREAM
tcp_recv(STREAM s, uint32 length)
{
unsigned int new_length, end_offset, p_offset;
uint32 new_length, end_offset, p_offset;
int rcvd = 0;
#ifdef WITH_SSL
int ssl_err;
#endif /* WITH_SSL */
if (g_network_error == True)
return NULL;
if (s == NULL)
{
/* read into "new" stream */
if (length > in.size)
if (length > g_in.size)
{
in.data = (uint8 *) xrealloc(in.data, length);
in.size = length;
g_in.data = (uint8 *) xrealloc(g_in.data, length);
g_in.size = length;
}
in.end = in.p = in.data;
s = &in;
g_in.end = g_in.p = g_in.data;
s = &g_in;
}
else
{
@ -119,29 +200,74 @@ tcp_recv(STREAM s, uint32 length)
while (length > 0)
{
if (!ui_select(sock))
/* User quit */
return NULL;
rcvd = recv(sock, (char *)s->end, length, 0);
if (rcvd < 0)
#ifdef WITH_SSL
if (!g_ssl || SSL_pending(g_ssl) <= 0)
#endif /* WITH_SSL */
{
if (rcvd == -1 && TCP_BLOCKS)
if (!ui_select(g_sock))
{
TCP_SLEEP(0);
rcvd = 0;
}
else
{
error("recv: %s\n", TCP_STRERROR);
/* User quit */
g_user_quit = True;
return NULL;
}
}
else if (rcvd == 0)
#ifdef WITH_SSL
if (g_ssl)
{
error("Connection closed\n");
return NULL;
rcvd = SSL_read(g_ssl, s->end, length);
ssl_err = SSL_get_error(g_ssl, rcvd);
if (ssl_err == SSL_ERROR_SSL)
{
if (SSL_get_shutdown(g_ssl) & SSL_RECEIVED_SHUTDOWN)
{
error("Remote peer initiated ssl shutdown.\n");
return NULL;
}
ERR_print_errors_fp(stdout);
g_network_error = True;
return NULL;
}
if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE)
{
rcvd = 0;
}
else if (ssl_err != SSL_ERROR_NONE)
{
error("SSL_read: %d (%s)\n", ssl_err, TCP_STRERROR);
g_network_error = True;
return NULL;
}
}
else
{
#endif /* WITH_SSL */
rcvd = recv(g_sock, (char *)s->end, length, 0);
if (rcvd < 0)
{
if (rcvd == -1 && TCP_BLOCKS)
{
rcvd = 0;
}
else
{
error("recv: %s\n", TCP_STRERROR);
g_network_error = True;
return NULL;
}
}
else if (rcvd == 0)
{
error("Connection closed\n");
return NULL;
}
#ifdef WITH_SSL
}
#endif /* WITH_SSL */
s->end += rcvd;
length -= rcvd;
@ -150,11 +276,137 @@ tcp_recv(STREAM s, uint32 length)
return s;
}
#ifdef WITH_SSL
/* Establish a SSL/TLS 1.0 connection */
RD_BOOL
tcp_tls_connect(void)
{
int err;
long options;
if (!g_ssl_initialized)
{
SSL_load_error_strings();
SSL_library_init();
g_ssl_initialized = True;
}
/* create process context */
if (g_ssl_ctx == NULL)
{
g_ssl_ctx = SSL_CTX_new(TLSv1_client_method());
if (g_ssl_ctx == NULL)
{
error("tcp_tls_connect: SSL_CTX_new() failed to create TLS v1.0 context\n");
goto fail;
}
options = 0;
#ifdef SSL_OP_NO_COMPRESSION
options |= SSL_OP_NO_COMPRESSION;
#endif // __SSL_OP_NO_COMPRESSION
options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
SSL_CTX_set_options(g_ssl_ctx, options);
}
/* free old connection */
if (g_ssl)
SSL_free(g_ssl);
/* create new ssl connection */
g_ssl = SSL_new(g_ssl_ctx);
if (g_ssl == NULL)
{
error("tcp_tls_connect: SSL_new() failed\n");
goto fail;
}
if (SSL_set_fd(g_ssl, g_sock) < 1)
{
error("tcp_tls_connect: SSL_set_fd() failed\n");
goto fail;
}
do
{
err = SSL_connect(g_ssl);
}
while (SSL_get_error(g_ssl, err) == SSL_ERROR_WANT_READ);
if (err < 0)
{
ERR_print_errors_fp(stdout);
goto fail;
}
return True;
fail:
if (g_ssl)
SSL_free(g_ssl);
if (g_ssl_ctx)
SSL_CTX_free(g_ssl_ctx);
g_ssl = NULL;
g_ssl_ctx = NULL;
return False;
}
/* Get public key from server of TLS 1.0 connection */
RD_BOOL
tcp_tls_get_server_pubkey(STREAM s)
{
X509 *cert = NULL;
EVP_PKEY *pkey = NULL;
s->data = s->p = NULL;
s->size = 0;
if (g_ssl == NULL)
goto out;
cert = SSL_get_peer_certificate(g_ssl);
if (cert == NULL)
{
error("tcp_tls_get_server_pubkey: SSL_get_peer_certificate() failed\n");
goto out;
}
pkey = X509_get_pubkey(cert);
if (pkey == NULL)
{
error("tcp_tls_get_server_pubkey: X509_get_pubkey() failed\n");
goto out;
}
s->size = i2d_PublicKey(pkey, NULL);
if (s->size < 1)
{
error("tcp_tls_get_server_pubkey: i2d_PublicKey() failed\n");
goto out;
}
s->data = s->p = xmalloc(s->size);
i2d_PublicKey(pkey, &s->p);
s->p = s->data;
s->end = s->p + s->size;
out:
if (cert)
X509_free(cert);
if (pkey)
EVP_PKEY_free(pkey);
return (s->size != 0);
}
#endif /* WITH_SSL */
/* Establish a connection on the TCP layer */
BOOL
RD_BOOL
tcp_connect(char *server)
{
int true_value = 1;
socklen_t option_len;
uint32 option_value;
int i;
#ifdef IPv6
@ -175,22 +427,22 @@ tcp_connect(char *server)
}
ressave = res;
sock = -1;
g_sock = -1;
while (res)
{
sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (!(sock < 0))
g_sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (!(g_sock < 0))
{
if (connect(sock, res->ai_addr, res->ai_addrlen) == 0)
if (connect(g_sock, res->ai_addr, res->ai_addrlen) == 0)
break;
TCP_CLOSE(sock);
sock = -1;
TCP_CLOSE(g_sock);
g_sock = -1;
}
res = res->ai_next;
}
freeaddrinfo(ressave);
if (sock == -1)
if (g_sock == -1)
{
error("%s: unable to connect\n", server);
return False;
@ -211,7 +463,7 @@ tcp_connect(char *server)
return False;
}
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
if ((g_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
error("socket: %s\n", TCP_STRERROR);
return False;
@ -220,22 +472,41 @@ tcp_connect(char *server)
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons((uint16) g_tcp_port_rdp);
if (connect(sock, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) < 0)
if (connect(g_sock, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) < 0)
{
error("connect: %s\n", TCP_STRERROR);
TCP_CLOSE(sock);
if (!g_reconnect_loop)
error("connect: %s\n", TCP_STRERROR);
TCP_CLOSE(g_sock);
g_sock = -1;
return False;
}
#endif /* IPv6 */
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *) &true_value, sizeof(true_value));
option_value = 1;
option_len = sizeof(option_value);
setsockopt(g_sock, IPPROTO_TCP, TCP_NODELAY, (void *) &option_value, option_len);
/* receive buffer must be a least 16 K */
if (getsockopt(g_sock, SOL_SOCKET, SO_RCVBUF, (void *) &option_value, &option_len) == 0)
{
if (option_value < (1024 * 16))
{
option_value = 1024 * 16;
option_len = sizeof(option_value);
setsockopt(g_sock, SOL_SOCKET, SO_RCVBUF, (void *) &option_value,
option_len);
}
}
in.size = 4096;
in.data = (uint8 *) xmalloc(in.size);
g_in.size = 4096;
g_in.data = (uint8 *) xmalloc(g_in.size);
out.size = 4096;
out.data = (uint8 *) xmalloc(out.size);
for (i = 0; i < STREAM_COUNT; i++)
{
g_out[i].size = 4096;
g_out[i].data = (uint8 *) xmalloc(g_out[i].size);
}
return True;
}
@ -244,7 +515,19 @@ tcp_connect(char *server)
void
tcp_disconnect(void)
{
TCP_CLOSE(sock);
#ifdef WITH_SSL
if (g_ssl)
{
if (!g_network_error)
(void) SSL_shutdown(g_ssl);
SSL_free(g_ssl);
g_ssl = NULL;
SSL_CTX_free(g_ssl_ctx);
g_ssl_ctx = NULL;
}
#endif /* WITH_SSL */
TCP_CLOSE(g_sock);
g_sock = -1;
}
char *
@ -253,9 +536,9 @@ tcp_get_address()
static char ipaddr[32];
struct sockaddr_in sockaddr;
socklen_t len = sizeof(sockaddr);
if (getsockname(sock, (struct sockaddr *) &sockaddr, &len) == 0)
if (getsockname(g_sock, (struct sockaddr *) &sockaddr, &len) == 0)
{
unsigned char *ip = (unsigned char *) &sockaddr.sin_addr;
uint8 *ip = (uint8 *) & sockaddr.sin_addr;
sprintf(ipaddr, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
}
else
@ -263,36 +546,49 @@ tcp_get_address()
return ipaddr;
}
RD_BOOL
tcp_is_connected()
{
struct sockaddr_in sockaddr;
socklen_t len = sizeof(sockaddr);
if (getpeername(g_sock, (struct sockaddr *) &sockaddr, &len))
return True;
return False;
}
/* reset the state of the tcp layer */
/* Support for Session Directory */
void
tcp_reset_state(void)
{
sock = -1; /* reset socket */
int i;
/* Clear the incoming stream */
if (in.data != NULL)
xfree(in.data);
in.p = NULL;
in.end = NULL;
in.data = NULL;
in.size = 0;
in.iso_hdr = NULL;
in.mcs_hdr = NULL;
in.sec_hdr = NULL;
in.rdp_hdr = NULL;
in.channel_hdr = NULL;
if (g_in.data != NULL)
xfree(g_in.data);
g_in.p = NULL;
g_in.end = NULL;
g_in.data = NULL;
g_in.size = 0;
g_in.iso_hdr = NULL;
g_in.mcs_hdr = NULL;
g_in.sec_hdr = NULL;
g_in.rdp_hdr = NULL;
g_in.channel_hdr = NULL;
/* Clear the outgoing stream */
if (out.data != NULL)
xfree(out.data);
out.p = NULL;
out.end = NULL;
out.data = NULL;
out.size = 0;
out.iso_hdr = NULL;
out.mcs_hdr = NULL;
out.sec_hdr = NULL;
out.rdp_hdr = NULL;
out.channel_hdr = NULL;
/* Clear the outgoing stream(s) */
for (i = 0; i < STREAM_COUNT; i++)
{
if (g_out[i].data != NULL)
xfree(g_out[i].data);
g_out[i].p = NULL;
g_out[i].end = NULL;
g_out[i].data = NULL;
g_out[i].size = 0;
g_out[i].iso_hdr = NULL;
g_out[i].mcs_hdr = NULL;
g_out[i].sec_hdr = NULL;
g_out[i].rdp_hdr = NULL;
g_out[i].channel_hdr = NULL;
}
}

View file

@ -1,11 +1,12 @@
/*
rdesktop: A Remote Desktop Protocol client.
Common data types
Copyright (C) Matthew Chapman 1999-2005
Copyright (C) Matthew Chapman 1999-2008
Copyright 2014 Henrik Andersson <hean01@cendio.se> for Cendio AB
This program is free software; you can redistribute it and/or modify
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@ -13,11 +14,12 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
typedef int RD_BOOL;
#ifndef True
#define True (1)
#define False (0)
@ -35,6 +37,15 @@ typedef void *RD_HGLYPH;
typedef void *RD_HCOLOURMAP;
typedef void *RD_HCURSOR;
typedef enum _RDP_VERSION
{
RDP_V4 = 4,
RDP_V5 = 5,
RDP_V6 = 6
} RDP_VERSION;
typedef struct _RD_POINT
{
sint16 x, y;
@ -77,13 +88,22 @@ typedef struct _PEN
}
PEN;
/* this is whats in the brush cache */
typedef struct _BRUSHDATA
{
uint32 colour_code;
uint32 data_size;
uint8 *data;
}
BRUSHDATA;
typedef struct _BRUSH
{
uint8 xorigin;
uint8 yorigin;
uint8 style;
uint8 pattern[8];
BRUSHDATA *bd;
}
BRUSH;
@ -117,6 +137,16 @@ typedef struct _key_translation
}
key_translation;
typedef struct _key_translation_entry
{
key_translation *tr;
/* The full KeySym for this entry, not KEYMAP_MASKed */
uint32 keysym;
/* This will be non-NULL if there has been a hash collision */
struct _key_translation_entry *next;
}
key_translation_entry;
typedef struct _VCHANNEL
{
uint16 mcs_id;
@ -143,7 +173,7 @@ CELLHEADER;
#define MAX_CBSIZE 256
/* RDPSND */
typedef struct
typedef struct _RD_WAVEFORMATEX
{
uint16 wFormatTag;
uint16 nChannels;
@ -170,13 +200,13 @@ typedef uint32 RD_NTHANDLE;
typedef struct _DEVICE_FNS
{
RD_NTSTATUS(*create) (uint32 device, uint32 desired_access, uint32 share_mode,
uint32 create_disposition, uint32 flags_and_attributes, char *filename,
RD_NTHANDLE * handle);
uint32 create_disposition, uint32 flags_and_attributes,
char *filename, RD_NTHANDLE * handle);
RD_NTSTATUS(*close) (RD_NTHANDLE handle);
RD_NTSTATUS(*read) (RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset,
uint32 * result);
uint32 * result);
RD_NTSTATUS(*write) (RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset,
uint32 * result);
uint32 * result);
RD_NTSTATUS(*device_control) (RD_NTHANDLE handle, uint32 request, STREAM in, STREAM out);
}
DEVICE_FNS;
@ -233,7 +263,7 @@ typedef struct rdpdr_printer_info
char *driver, *printer;
uint32 bloblen;
uint8 *blob;
BOOL default_printer;
RD_BOOL default_printer;
}
PRINTER;
@ -250,7 +280,6 @@ NOTIFY;
#define PATH_MAX 256
#endif
#ifndef _WIN32
typedef struct fileinfo
{
uint32 device_id, flags_and_attributes, accessmask;
@ -258,11 +287,10 @@ typedef struct fileinfo
DIR *pdir;
struct dirent *pdirent;
char pattern[PATH_MAX];
BOOL delete_on_close;
RD_BOOL delete_on_close;
NOTIFY notify;
uint32 info_class;
}
FILEINFO;
#endif
typedef BOOL(*str_handle_lines_t) (const char *line, void *data);
typedef RD_BOOL(*str_handle_lines_t) (const char *line, void *data);

View file

@ -29,43 +29,63 @@ char g_password[256] = "";
char g_shell[256] = "";
char g_directory[256] = "";
char g_domain[256] = "";
BOOL g_desktop_save = False; /* desktop save order */
BOOL g_polygon_ellipse_orders = False; /* polygon / ellipse orders */
BOOL g_bitmap_compression = True;
RD_BOOL g_desktop_save = False; /* desktop save order */
RD_BOOL g_polygon_ellipse_orders = False; /* polygon / ellipse orders */
RD_BOOL g_bitmap_compression = True;
uint32 g_rdp5_performanceflags =
RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;
BOOL g_bitmap_cache_persist_enable = False;
BOOL g_bitmap_cache_precache = True;
BOOL g_bitmap_cache = True;
BOOL g_encryption = True;
RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS | RDP5_NO_CURSOR_SHADOW;
RD_BOOL g_bitmap_cache_persist_enable = False;
RD_BOOL g_bitmap_cache_precache = True;
RD_BOOL g_bitmap_cache = True;
RD_BOOL g_encryption = True;
int g_server_depth = 8;
BOOL g_use_rdp5 = False;
RD_BOOL g_use_rdp5 = False;
int g_width = 800;
int g_height = 600;
uint32 g_keylayout = 0x409; /* Defaults to US keyboard layout */
int g_keyboard_type = 0x4; /* Defaults to US keyboard layout */
int g_keyboard_subtype = 0x0; /* Defaults to US keyboard layout */
int g_keyboard_functionkeys = 0xc; /* Defaults to US keyboard layout */
BOOL g_console_session = False;
RD_BOOL g_console_session = False;
/* can't be static, hardware file or bsops need these */
int g_tcp_sck = 0;
int pal_entries[256];
/* Session Directory redirection */
BOOL g_redirect = False;
char g_redirect_server[64];
char g_redirect_domain[16];
char g_redirect_password[64];
char g_redirect_username[64];
char g_redirect_cookie[128];
RD_BOOL g_redirect = False;
char g_redirect_server[256];
uint32 g_redirect_server_len;
char g_redirect_domain[256];
uint32 g_redirect_domain_len;
char g_redirect_username[256];
uint32 g_redirect_username_len;
uint8 g_redirect_lb_info[256];
uint32 g_redirect_lb_info_len;
uint8 g_redirect_cookie[256];
uint32 g_redirect_cookie_len;
uint32 g_redirect_flags = 0;
uint32 g_redirect_session_id = 0;
extern int g_tcp_port_rdp;
static int g_deactivated = 0;
static uint32 g_ext_disc_reason = 0;
RDP_VERSION g_rdp_version = RDP_V5; /* Default to version 5 */
RD_BOOL g_encryption_initial = True;
RD_BOOL g_user_quit = False;
RD_BOOL g_network_error = False;
uint8 g_client_random[SEC_RANDOM_SIZE];
RD_BOOL g_pending_resize = False;
RD_BOOL g_numlock_sync = False;
uint32 g_reconnect_logonid = 0;
char g_reconnect_random[16];
time_t g_reconnect_random_ts;
RD_BOOL g_has_reconnect_random = False;
RD_BOOL g_reconnect_loop = False;
struct bitmap
{
uint8 * data;
@ -153,9 +173,9 @@ ui_select(int in)
/*****************************************************************************/
void *
ui_create_cursor(uint32 x, uint32 y,
ui_create_cursor(unsigned int x, unsigned int y,
int width, int height,
uint8 * andmask, uint8 * xormask)
uint8 * andmask, uint8 * xormask, int xor_bpp)
{
int i;
int j;
@ -164,7 +184,11 @@ ui_create_cursor(uint32 x, uint32 y,
if (width != 32 || height != 32)
{
return 0;
return NULL;
}
if (xor_bpp==1)
{
return (void *) mi_create_cursor(x, y, width, height, (unsigned char *)andmask, (unsigned char *)xormask);
}
memset(am, 0, 32 * 4);
memset(xm, 0, 32 * 4);
@ -645,7 +669,7 @@ ui_end_update(void)
/*****************************************************************************/
void
ui_polygon(uint8 opcode, uint8 fillmode, POINT * point, int npoints,
ui_polygon(uint8 opcode, uint8 fillmode, RD_POINT * point, int npoints,
BRUSH * brush, int bgcolour, int fgcolour)
{
/* not used */
@ -653,7 +677,7 @@ ui_polygon(uint8 opcode, uint8 fillmode, POINT * point, int npoints,
/*****************************************************************************/
void
ui_polyline(uint8 opcode, POINT * points, int npoints, PEN * pen)
ui_polyline(uint8 opcode, RD_POINT * points, int npoints, PEN * pen)
{
int i, x, y, dx, dy;
if (npoints > 0)
@ -691,7 +715,7 @@ generate_random(uint8 * random)
rand();
for (i = 0; i < 32; i++)
{
random[i] = rand() >> 16; /* higher bits are more random */
random[i] = rand(); /* higher bits are more random */
}
}
@ -710,7 +734,7 @@ load_licence(uint8 ** data)
/*****************************************************************************/
void *
xrealloc(void * in, int size)
xrealloc(void * in, size_t size)
{
if (size < 1)
{
@ -933,10 +957,10 @@ ui_main(void)
flags = RDP_LOGON_NORMAL;
if (g_password[0] != 0)
{
flags |= RDP_LOGON_AUTO;
flags |= RDP_INFO_AUTOLOGON;
}
if (!rdp_connect(g_servername, flags, g_domain, g_password,
g_shell, g_directory))
g_shell, g_directory, FALSE))
{
return 0;
}

View file

@ -1114,6 +1114,7 @@ wWinMain(HINSTANCE hInstance,
uni_to_str(szValue, GetStringFromSettings(pRdpSettings, L"username"));
SetDomainAndUsername(szValue);
strcpy(g_password, "");
strcpy(g_hostname, tcp_get_address());
g_server_depth = GetIntegerFromSettings(pRdpSettings, L"session bpp");
if (g_server_depth > 16) g_server_depth = 16; /* hack, we don't support 24bpp yet */
g_screen_width = GetSystemMetrics(SM_CXSCREEN);