win32 stuff

ulab-original
jsorg71 18 years ago
parent baf82d45bc
commit a2b270e57a

File diff suppressed because it is too large Load Diff

@ -0,0 +1,822 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Generics backingstore operations
Copyright (C) Jay Sorg 2005-2006
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
(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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdlib.h>
#include <string.h>
#include "bsops.h"
/* externals */
extern int g_width;
extern int g_height;
extern int g_bs_bpp;
extern int g_bs_Bpp;
extern char * g_bs;
/* globals */
static int g_clip_left = 0;
static int g_clip_top = 0;
static int g_clip_right = 800;
static int g_clip_bottom = 600;
/* for bs_patblt */
static unsigned char g_hatch_patterns[] =
{
0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, /* 0 - bsHorizontal */
0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, /* 1 - bsVertical */
0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, /* 2 - bsFDiagonal */
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, /* 3 - bsBDiagonal */
0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08, 0x08, /* 4 - bsCross */
0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81 /* 5 - bsDiagCross */
};
/*****************************************************************************/
/* do a raster op */
int
bs_do_rop(int rop, int src, int dst)
{
switch (rop)
{
case 0x0: return 0;
case 0x1: return ~(src | dst);
case 0x2: return (~src) & dst;
case 0x3: return ~src;
case 0x4: return src & (~dst);
case 0x5: return ~(dst);
case 0x6: return src ^ dst;
case 0x7: return ~(src & dst);
case 0x8: return src & dst;
case 0x9: return ~(src) ^ dst;
case 0xa: return dst;
case 0xb: return (~src) | dst;
case 0xc: return src;
case 0xd: return src | (~dst);
case 0xe: return src | dst;
case 0xf: return ~0;
}
return dst;
}
/*****************************************************************************/
/* get a pixel from the in memory copy of whats on the screen */
int
bs_get_pixel(int x, int y)
{
char * p;
if (x >= 0 && x < g_width && y >= 0 && y < g_height)
{
p = g_bs + (y * g_width * g_bs_Bpp) + (x * g_bs_Bpp);
if (g_bs_Bpp == 1)
{
return *((unsigned char *) p);
}
else if (g_bs_Bpp == 2)
{
return *((unsigned short *) p);
}
else
{
return *((unsigned int *) p);
}
}
else
{
return 0;
}
}
/*****************************************************************************/
/* set a pixel on the screen using the clip */
void
bs_set_pixel(int x, int y, int pixel, int rop, int use_clip)
{
char * p;
if (!use_clip ||
(x >= g_clip_left && x < g_clip_right &&
y >= g_clip_top && y < g_clip_bottom))
{
if (x >= 0 && x < g_width && y >= 0 && y < g_height)
{
p = g_bs + (y * g_width * g_bs_Bpp) + (x * g_bs_Bpp);
if (rop != 12)
{
pixel = bs_do_rop(rop, pixel, bs_get_pixel(x, y));
}
if (g_bs_Bpp == 1)
{
*((unsigned char *) p) = pixel;
}
else if (g_bs_Bpp == 2)
{
*((unsigned short *) p) = pixel;
}
else
{
*((unsigned int *) p) = pixel;
}
}
}
}
/*****************************************************************************/
static char *
get_bs_ptr(int x, int y)
{
char * p;
if (x >= 0 && x < g_width && y >= 0 && y < g_height)
{
p = g_bs + (y * g_width * g_bs_Bpp) + (x * g_bs_Bpp);
return p;
}
else
{
return 0;
}
}
/*****************************************************************************/
void
bs_init(void)
{
g_clip_left = 0;
g_clip_top = 0;
g_clip_right = g_width;
g_clip_bottom = g_height;
}
/*****************************************************************************/
void
bs_exit(void)
{
}
/*****************************************************************************/
void
bs_set_clip(int x, int y, int cx, int cy)
{
g_clip_left = x;
g_clip_top = y;
g_clip_right = x + cx;
g_clip_bottom = y + cy;
}
/*****************************************************************************/
void
bs_reset_clip(void)
{
g_clip_left = 0;
g_clip_top = 0;
g_clip_right = g_width;
g_clip_bottom = g_height;
}
/*****************************************************************************/
/* check if a certain pixel is set in a bitmap */
int
bs_is_pixel_on(char * data, int x, int y, int width, int bpp)
{
int start;
int shift;
if (bpp == 1)
{
width = (width + 7) / 8;
start = (y * width) + x / 8;
shift = x % 8;
return (data[start] & (0x80 >> shift)) != 0;
}
else if (bpp == 8)
{
return data[y * width + x] != 0;
}
else if (bpp == 24)
{
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
{
return 0;
}
}
/*****************************************************************************/
void
bs_set_pixel_on(char * data, int x, int y, int width, int bpp,
int pixel)
{
int start;
int shift;
if (bpp == 1)
{
width = (width + 7) / 8;
start = (y * width) + x / 8;
shift = x % 8;
if (pixel != 0)
{
data[start] = data[start] | (0x80 >> shift);
}
else
{
data[start] = data[start] & ~(0x80 >> shift);
}
}
else if (bpp == 8)
{
data[y * width + x] = pixel;
}
else if (bpp == 15 || bpp == 16)
{
((unsigned short *) data)[y * width + x] = pixel;
}
}
/*****************************************************************************/
void
bs_copy_mem(char * d, char * s, int n)
{
while (n & (~7))
{
*(d++) = *(s++);
*(d++) = *(s++);
*(d++) = *(s++);
*(d++) = *(s++);
*(d++) = *(s++);
*(d++) = *(s++);
*(d++) = *(s++);
*(d++) = *(s++);
n = n - 8;
}
while (n > 0)
{
*(d++) = *(s++);
n--;
}
}
/*****************************************************************************/
void
bs_copy_memb(char * d, char * s, int n)
{
d = (d + n) - 1;
s = (s + n) - 1;
while (n & (~7))
{
*(d--) = *(s--);
*(d--) = *(s--);
*(d--) = *(s--);
*(d--) = *(s--);
*(d--) = *(s--);
*(d--) = *(s--);
*(d--) = *(s--);
*(d--) = *(s--);
n = n - 8;
}
while (n > 0)
{
*(d--) = *(s--);
n--;
}
}
/*****************************************************************************/
/* return true is the is something to draw */
int
bs_warp_coords(int * x, int * y, int * cx, int * cy,
int * srcx, int * srcy)
{
int dx;
int dy;
if (g_clip_left > *x)
{
dx = g_clip_left - *x;
}
else
{
dx = 0;
}
if (g_clip_top > *y)
{
dy = g_clip_top - *y;
}
else
{
dy = 0;
}
if (*x + *cx > g_clip_right)
{
*cx = (*cx - ((*x + *cx) - g_clip_right));
}
if (*y + *cy > g_clip_bottom)
{
*cy = (*cy - ((*y + *cy) - g_clip_bottom));
}
*cx = *cx - dx;
*cy = *cy - dy;
if (*cx <= 0)
{
return 0;
}
if (*cy <= 0)
{
return 0;
}
*x = *x + dx;
*y = *y + dy;
if (srcx != 0)
{
*srcx = *srcx + dx;
}
if (srcy != 0)
{
*srcy = *srcy + dy;
}
return 1;
}
/*****************************************************************************/
void
bs_rect(int x, int y, int cx, int cy, int colour, int rop)
{
int i;
int j;
unsigned char * p8;
unsigned short * p16;
unsigned int * p32;
if (bs_warp_coords(&x, &y, &cx, &cy, 0, 0))
{
if (rop == 0) /* black */
{
rop = 12;
colour = 0;
}
else if (rop == 15) /* white */
{
rop = 12;
colour = 0xffffff;
}
if (rop == 12) /* copy */
{
if (g_bs_Bpp == 1)
{
for (i = 0; i < cy; i++)
{
p8 = (unsigned char *) get_bs_ptr(x, y + i);
if (p8 != 0)
{
for (j = 0; j < cx; j++)
{
*p8 = colour;
p8++;
}
}
}
}
else if (g_bs_Bpp == 2)
{
for (i = 0; i < cy; i++)
{
p16 = (unsigned short *) get_bs_ptr(x, y + i);
if (p16 != 0)
{
for (j = 0; j < cx; j++)
{
*p16 = colour;
p16++;
}
}
}
}
else
{
for (i = 0; i < cy; i++)
{
p32 = (unsigned int *) get_bs_ptr(x, y + i);
if (p32 != 0)
{
for (j = 0; j < cx; j++)
{
*p32 = colour;
p32++;
}
}
}
}
}
else /* slow */
{
for (i = 0; i < cy; i++)
{
for (j = 0; j < cx; j++)
{
bs_set_pixel(j + x, i + y, colour, rop, 0);
}
}
}
}
}
/*****************************************************************************/
void
bs_screenblt(int rop, int x, int y, int cx, int cy,
int srcx, int srcy)
{
int p;
int i;
int j;
char * src;
char * dst;
if (bs_warp_coords(&x, &y, &cx, &cy, &srcx, &srcy))
{
if (rop == 12) /* copy */
{
if (srcy < y) /* copy down - bottom to top */
{
for (i = cy - 1; i >= 0; i--)
{
src = get_bs_ptr(srcx, srcy + i);
dst = get_bs_ptr(x, y + i);
if (src != 0 && dst != 0)
{
bs_copy_mem(dst, src, cx * g_bs_Bpp);
}
}
}
else if (srcy > y || srcx > x) /* copy up or left - top to bottom */
{
for (i = 0; i < cy; i++)
{
src = get_bs_ptr(srcx, srcy + i);
dst = get_bs_ptr(x, y + i);
if (src != 0 && dst != 0)
{
bs_copy_mem(dst, src, cx * g_bs_Bpp);
}
}
}
else /* copy straight right */
{
for (i = 0; i < cy; i++)
{
src = get_bs_ptr(srcx, srcy + i);
dst = get_bs_ptr(x, y + i);
if (src != 0 && dst != 0)
{
bs_copy_memb(dst, src, cx * g_bs_Bpp);
}
}
}
}
else /* slow */
{
if (srcy < y) /* copy down - bottom to top */
{
for (i = cy - 1; i >= 0; i--)
{
for (j = 0; j < cx; j++)
{
p = bs_get_pixel(srcx + j, srcy + i);
bs_set_pixel(x + j, y + i, p, rop, 0);
}
}
}
else if (srcy > y || srcx > x) /* copy up or left - top to bottom */
{
for (i = 0; i < cy; i++)
{
for (j = 0; j < cx; j++)
{
p = bs_get_pixel(srcx + j, srcy + i);
bs_set_pixel(x + j, y + i, p, rop, 0);
}
}
}
else /* copy straight right */
{
for (i = 0; i < cy; i++)
{
for (j = cx - 1; j >= 0; j--)
{
p = bs_get_pixel(srcx + j, srcy + i);
bs_set_pixel(x + j, y + i, p, rop, 0);
}
}
}
}
}
}
/*****************************************************************************/
void
bs_memblt(int opcode, int x, int y, int cx, int cy,
void * srcdata, int srcwidth, int srcheight,
int srcx, int srcy)
{
int i;
int j;
int p;
char * dst;
char * src;
if (bs_warp_coords(&x, &y, &cx, &cy, &srcx, &srcy))
{
if (opcode == 12) /* copy */
{
if (g_bs_Bpp == 1)
{
src = (char *) (((unsigned char *) srcdata) + srcy * srcwidth + srcx);
}
else if (g_bs_Bpp == 2)
{
src = (char *) (((unsigned short *) srcdata) + srcy * srcwidth + srcx);
}
else
{
src = (char *) (((unsigned int *) srcdata) + srcy * srcwidth + srcx);
}
for (i = 0; i < cy; i++)
{
dst = get_bs_ptr(x, y + i);
if (dst != 0)
{
bs_copy_mem(dst, src, cx * g_bs_Bpp);
src += srcwidth * g_bs_Bpp;
}
}
}
else /* slow */
{
if (g_bs_Bpp == 1)
{
for (i = 0; i < cy; i++)
{
for (j = 0; j < cx; j++)
{
p = *(((unsigned char *) srcdata) +
((i + srcy) * srcwidth + (j + srcx)));
bs_set_pixel(x + j, y + i, p, opcode, 0);
}
}
}
else if (g_bs_Bpp == 2)
{
for (i = 0; i < cy; i++)
{
for (j = 0; j < cx; j++)
{
p = *(((unsigned short *) srcdata) +
((i + srcy) * srcwidth + (j + srcx)));
bs_set_pixel(x + j, y + i, p, opcode, 0);
}
}
}
else
{
for (i = 0; i < cy; i++)
{
for (j = 0; j < cx; j++)
{
p = *(((unsigned int *) srcdata) +
((i + srcy) * srcwidth + (j + srcx)));
bs_set_pixel(x + j, y + i, p, opcode, 0);
}
}
}
}
}
}
/*****************************************************************************/
void
bs_draw_glyph(int x, int y, char * glyph_data, int glyph_width,
int glyph_height, int fgcolour)
{
int i;
int j;
for (i = 0; i < glyph_height; i++)
{
for (j = 0; j < glyph_width; j++)
{
if (bs_is_pixel_on(glyph_data, j, i, glyph_width, 8))
{
bs_set_pixel(x + j, y + i, fgcolour, 12, 1);
}
}
}
}
/*****************************************************************************/
/* Bresenham's line drawing algorithm */
void
bs_line(int opcode, int startx, int starty, int endx, int endy,
int pen_width, int pen_style, int pen_colour)
{
int dx;
int dy;
int incx;
int incy;
int dpr;
int dpru;
int p;
if (startx > endx)
{
dx = startx - endx;
incx = -1;
}
else
{
dx = endx - startx;
incx = 1;
}
if (starty > endy)
{
dy = starty - endy;
incy = -1;
}
else
{
dy = endy - starty;
incy = 1;
}
if (dx >= dy)
{
dpr = dy << 1;
dpru = dpr - (dx << 1);
p = dpr - dx;
for (; dx >= 0; dx--)
{
if (startx != endx || starty != endy)
{
bs_set_pixel(startx, starty, pen_colour, opcode, 1);
}
if (p > 0)
{
startx += incx;
starty += incy;
p += dpru;
}
else
{
startx += incx;
p += dpr;
}
}
}
else
{
dpr = dx << 1;
dpru = dpr - (dy << 1);
p = dpr - dy;
for (; dy >= 0; dy--)
{
if (startx != endx || starty != endy)
{
bs_set_pixel(startx, starty, pen_colour, opcode, 1);
}
if (p > 0)
{
startx += incx;
starty += incy;
p += dpru;
}
else
{
starty += incy;
p += dpr;
}
}
}
}
/*****************************************************************************/
void
bs_patblt(int opcode, int x, int y, int cx, int cy,
int brush_style, char * brush_pattern,
int brush_x_org, int brush_y_org,
int bgcolour, int fgcolour)
{
int i;
int j;
char ipattern[8];
char * b;
b = 0;
switch (brush_style)
{
case 0:
bs_rect(x, y, cx, cy, fgcolour, opcode);
break;
case 2: /* Hatch */
b = g_hatch_patterns + brush_pattern[0] * 8;
break;
case 3:
for (i = 0; i < 8; i++)
{
ipattern[i] = ~brush_pattern[7 - i];
}
b = ipattern;
break;
}
if (b != 0)
{
for (i = 0; i < cy; i++)
{
for (j = 0; j < cx; j++)
{
if (bs_is_pixel_on(b, (x + j + brush_x_org) % 8,
(y + i + brush_y_org) % 8, 8, 1))
{
bs_set_pixel(x + j, y + i, fgcolour, opcode, 1);
}
else
{
bs_set_pixel(x + j, y + i, bgcolour, opcode, 1);
}
}
}
}
}
/*****************************************************************************/
void
bs_copy_box(char * dst, int x, int y, int cx, int cy, int line_size)
{
char * src;
int i;
/* shouldn't happen */
if (cx < 1 || cy < 1)
{
return;
}
/* nothing to draw, memset and leave */
if (x + cx < 0 || y + cy < 0 || x >= g_width || y >= g_height)
{
memset(dst, 0, cx * cy * g_bs_Bpp);
return;
}
/* check if it goes over an edge */
if (x < 0 || y < 0 || x + cx > g_width || y + cy > g_height)
{
memset(dst, 0, cx * cy * g_bs_Bpp);
if (x < 0)
{
cx += x;
dst += -x * g_bs_Bpp;
x = 0;
}
if (x + cx > g_width)
{
cx = g_width - x;
}
for (i = 0; i < cy; i++)
{
src = get_bs_ptr(x, y + i);
if (src != 0)
{
bs_copy_mem(dst, src, cx * g_bs_Bpp);
}
dst += line_size;
}
}
else /* whole box is within */
{
for (i = 0; i < cy; i++)
{
src = get_bs_ptr(x, y + i);
if (src != 0)
{
bs_copy_mem(dst, src, cx * g_bs_Bpp);
}
dst += line_size;
}
}
}

@ -0,0 +1,49 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Generics backingstore operations
Copyright (C) Jay Sorg 2005-2006
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
(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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
int bs_get_pixel(int x, int y);
void bs_set_pixel(int x, int y, int pixel, int rop, int use_clip);
int bs_do_rop(int rop, int src, int dst);
void bs_init(void);
void bs_exit(void);
void bs_set_clip(int x, int y, int cx, int cy);
void bs_reset_clip(void);
void bs_set_pixel_on(char * data, int x, int y, int width, int bpp,
int pixel);
int bs_is_pixel_on(char * data, int x, int y, int width, int bpp);
void bs_copy_mem(char * d, char * s, int n);
void bs_copy_memb(char * d, char * s, int n);
int bs_warp_coords(int * x, int * y, int * cx, int * cy,
int * srcx, int * srcy);
void bs_rect(int x, int y, int cx, int cy, int colour, int rop);
void bs_screenblt(int opcode, int x, int y, int cx, int cy,
int srcx, int srcy);
void bs_memblt(int opcode, int x, int y, int cx, int cy,
void * srcdata, int srcwidth, int srcheight,
int srcx, int srcy);
void bs_copy_box(char * dst, int x, int y, int cx, int cy, int line_size);
void bs_draw_glyph(int x, int y, char * glyph_data, int glyph_width,
int glyph_height, int fgcolour);
void bs_line(int opcode, int startx, int starty, int endx, int endy,
int pen_width, int pen_style, int pen_colour);
void bs_patblt(int opcode, int x, int y, int cx, int cy,
int brush_style, char * brush_pattern,
int brush_x_org, int brush_y_org,
int bgcolour, int fgcolour);

@ -40,13 +40,13 @@ extern int g_pstcache_fd[];
struct bmpcache_entry
{
HBITMAP bitmap;
RD_HBITMAP bitmap;
sint16 previous;
sint16 next;
};
static struct bmpcache_entry g_bmpcache[3][0xa00];
static HBITMAP g_volatile_bc[3];
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 };
@ -190,7 +190,7 @@ cache_evict_bitmap(uint8 id)
}
/* Retrieve a bitmap from the cache */
HBITMAP
RD_HBITMAP
cache_get_bitmap(uint8 id, uint16 idx)
{
if ((id < NUM_ELEMENTS(g_bmpcache)) && (idx < NUM_ELEMENTS(g_bmpcache[0])))
@ -214,9 +214,9 @@ cache_get_bitmap(uint8 id, uint16 idx)
/* Store a bitmap in the cache */
void
cache_put_bitmap(uint8 id, uint16 idx, HBITMAP bitmap)
cache_put_bitmap(uint8 id, uint16 idx, RD_HBITMAP bitmap)
{
HBITMAP old;
RD_HBITMAP old;
if ((id < NUM_ELEMENTS(g_bmpcache)) && (idx < NUM_ELEMENTS(g_bmpcache[0])))
{
@ -262,7 +262,7 @@ cache_save_state(void)
idx = g_bmpcache_lru[id];
while (idx >= 0)
{
pstcache_touch_bitmap(id, idx, ++t);
pstcache_touch_bitmap((uint8) id, (uint16) idx, ++t);
idx = g_bmpcache[id][idx].next;
}
DEBUG_RDP5((" %d stamps written.\n", t));
@ -293,7 +293,7 @@ cache_get_font(uint8 font, uint16 character)
/* Store a glyph in the font cache */
void
cache_put_font(uint8 font, uint16 character, uint16 offset,
uint16 baseline, uint16 width, uint16 height, HGLYPH pixmap)
uint16 baseline, uint16 width, uint16 height, RD_HGLYPH pixmap)
{
FONTGLYPH *glyph;
@ -392,13 +392,13 @@ cache_put_desktop(uint32 offset, int cx, int cy, int scanline, int bytes_per_pix
/* CURSOR CACHE */
static HCURSOR g_cursorcache[0x20];
static RD_HCURSOR g_cursorcache[0x20];
/* Retrieve cursor from cache */
HCURSOR
RD_HCURSOR
cache_get_cursor(uint16 cache_idx)
{
HCURSOR cursor;
RD_HCURSOR cursor;
if (cache_idx < NUM_ELEMENTS(g_cursorcache))
{
@ -413,9 +413,9 @@ cache_get_cursor(uint16 cache_idx)
/* Store cursor in cache */
void
cache_put_cursor(uint16 cache_idx, HCURSOR cursor)
cache_put_cursor(uint16 cache_idx, RD_HCURSOR cursor)
{
HCURSOR old;
RD_HCURSOR old;
if (cache_idx < NUM_ELEMENTS(g_cursorcache))
{

@ -0,0 +1,435 @@
/*
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
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* TCP port for Remote Desktop Protocol */
#define TCP_PORT_RDP 3389
#define DEFAULT_CODEPAGE "UTF-8"
#define WINDOWS_CODEPAGE "UTF-16LE"
/* ISO PDU codes */
enum ISO_PDU_CODE
{
ISO_PDU_CR = 0xE0, /* Connection Request */
ISO_PDU_CC = 0xD0, /* Connection Confirm */
ISO_PDU_DR = 0x80, /* Disconnect Request */
ISO_PDU_DT = 0xF0, /* Data */
ISO_PDU_ER = 0x70 /* Error */
};
/* MCS PDU codes */
enum MCS_PDU_TYPE
{
MCS_EDRQ = 1, /* Erect Domain Request */
MCS_DPUM = 8, /* Disconnect Provider Ultimatum */
MCS_AURQ = 10, /* Attach User Request */
MCS_AUCF = 11, /* Attach User Confirm */
MCS_CJRQ = 14, /* Channel Join Request */
MCS_CJCF = 15, /* Channel Join Confirm */
MCS_SDRQ = 25, /* Send Data Request */
MCS_SDIN = 26 /* Send Data Indication */
};
#define MCS_CONNECT_INITIAL 0x7f65
#define MCS_CONNECT_RESPONSE 0x7f66
#define BER_TAG_BOOLEAN 1
#define BER_TAG_INTEGER 2
#define BER_TAG_OCTET_STRING 4
#define BER_TAG_RESULT 10
#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_PADDING_SIZE 8
#define SEC_EXPONENT_SIZE 4
#define SEC_CLIENT_RANDOM 0x0001
#define SEC_ENCRYPT 0x0008
#define SEC_LOGON_INFO 0x0040
#define SEC_LICENCE_NEG 0x0080
#define SEC_REDIRECT_ENCRYPT 0x0C00
#define SEC_TAG_SRV_INFO 0x0c01
#define SEC_TAG_SRV_CRYPT 0x0c02
#define SEC_TAG_SRV_CHANNELS 0x0c03
#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_PUBKEY 0x0006
#define SEC_TAG_KEYSIG 0x0008
#define SEC_RSA_MAGIC 0x31415352 /* RSA1 */
/* 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_USER 0x000f
#define LICENCE_TAG_HOST 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_DEACTIVATE = 6,
RDP_PDU_DATA = 7
};
enum RDP_DATA_PDU_TYPE
{
RDP_DATA_PDU_UPDATE = 2,
RDP_DATA_PDU_CONTROL = 20,
RDP_DATA_PDU_POINTER = 27,
RDP_DATA_PDU_INPUT = 28,
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_FONT2 = 39,
RDP_DATA_PDU_KEYBOARD_INDICATORS = 41,
RDP_DATA_PDU_DISCONNECT = 47
};
enum RDP_CONTROL_PDU_TYPE
{
RDP_CTL_REQUEST_CONTROL = 1,
RDP_CTL_GRANT_CONTROL = 2,
RDP_CTL_DETACH = 3,
RDP_CTL_COOPERATE = 4
};
enum RDP_UPDATE_PDU_TYPE
{
RDP_UPDATE_ORDERS = 0,
RDP_UPDATE_BITMAP = 1,
RDP_UPDATE_PALETTE = 2,
RDP_UPDATE_SYNCHRONIZE = 3
};
enum RDP_POINTER_PDU_TYPE
{
RDP_POINTER_SYSTEM = 1,
RDP_POINTER_MOVE = 3,
RDP_POINTER_COLOR = 6,
RDP_POINTER_CACHED = 7
};
enum RDP_SYSTEM_POINTER_TYPE
{
RDP_NULL_POINTER = 0,
RDP_DEFAULT_POINTER = 0x7F00
};
enum RDP_INPUT_DEVICE
{
RDP_INPUT_SYNCHRONIZE = 0,
RDP_INPUT_CODEPOINT = 1,
RDP_INPUT_VIRTKEY = 2,
RDP_INPUT_SCANCODE = 4,
RDP_INPUT_MOUSE = 0x8001
};
/* Device flags */
#define KBD_FLAG_RIGHT 0x0001
#define KBD_FLAG_EXT 0x0100
#define KBD_FLAG_QUIET 0x1000
#define KBD_FLAG_DOWN 0x4000
#define KBD_FLAG_UP 0x8000
/* These are for synchronization; not for keystrokes */
#define KBD_FLAG_SCROLL 0x0001
#define KBD_FLAG_NUMLOCK 0x0002
#define KBD_FLAG_CAPITAL 0x0004
/* See T.128 */
#define RDP_KEYPRESS 0
#define RDP_KEYRELEASE (KBD_FLAG_DOWN | KBD_FLAG_UP)
#define MOUSE_FLAG_MOVE 0x0800
#define MOUSE_FLAG_BUTTON1 0x1000
#define MOUSE_FLAG_BUTTON2 0x2000
#define MOUSE_FLAG_BUTTON3 0x4000
#define MOUSE_FLAG_BUTTON4 0x0280
#define MOUSE_FLAG_BUTTON5 0x0380
#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_COPY 0xc
#define ROP2_XOR 0x6
#define ROP2_AND 0x8
#define ROP2_NXOR 0x9
#define ROP2_OR 0xe
#define MIX_TRANSPARENT 0
#define MIX_OPAQUE 1
#define TEXT2_VERTICAL 0x04
#define TEXT2_IMPLICIT_X 0x20
#define ALTERNATE 1
#define WINDING 2
/* RDP bitmap cache (version 2) constants */
#define BMPCACHE2_C0_CELLS 0x78
#define BMPCACHE2_C1_CELLS 0x78
#define BMPCACHE2_C2_CELLS 0x150
#define BMPCACHE2_NUM_PSTCELLS 0x9f6
#define PDU_FLAG_FIRST 0x01
#define PDU_FLAG_LAST 0x02
/* RDP capabilities */
#define RDP_CAPSET_GENERAL 1 /* Maps to generalCapabilitySet in T.128 page 138 */
#define RDP_CAPLEN_GENERAL 0x18
#define OS_MAJOR_TYPE_UNIX 4
#define OS_MINOR_TYPE_XSERVER 7
#define RDP_CAPSET_BITMAP 2
#define RDP_CAPLEN_BITMAP 0x1C
#define RDP_CAPSET_ORDER 3
#define RDP_CAPLEN_ORDER 0x58
#define ORDER_CAP_NEGOTIATE 2
#define ORDER_CAP_NOSUPPORT 4
#define RDP_CAPSET_BMPCACHE 4
#define RDP_CAPLEN_BMPCACHE 0x28
#define RDP_CAPSET_CONTROL 5
#define RDP_CAPLEN_CONTROL 0x0C
#define RDP_CAPSET_ACTIVATE 7
#define RDP_CAPLEN_ACTIVATE 0x0C
#define RDP_CAPSET_POINTER 8
#define RDP_CAPLEN_POINTER 0x08
#define RDP_CAPSET_SHARE 9
#define RDP_CAPLEN_SHARE 0x08
#define RDP_CAPSET_COLCACHE 10
#define RDP_CAPLEN_COLCACHE 0x08
#define RDP_CAPSET_BMPCACHE2 19
#define RDP_CAPLEN_BMPCACHE2 0x28
#define BMPCACHE2_FLAG_PERSIST ((uint32)1<<31)
#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 RDP5_DISABLE_NOTHING 0x00
#define RDP5_NO_WALLPAPER 0x01
#define RDP5_NO_FULLWINDOWDRAG 0x02
#define RDP5_NO_MENUANIMATIONS 0x04
#define RDP5_NO_THEMING 0x08
#define RDP5_NO_CURSOR_SHADOW 0x20
#define RDP5_NO_CURSORSETTINGS 0x40 /* disables cursor blinking */
/* compression types */
#define RDP_MPPC_BIG 0x01
#define RDP_MPPC_COMPRESSED 0x20
#define RDP_MPPC_RESET 0x40
#define RDP_MPPC_FLUSH 0x80
#define RDP_MPPC_DICT_SIZE 65536
#define RDP5_COMPRESSED 0x80
/* Keymap flags */
#define MapRightShiftMask (1<<0)
#define MapLeftShiftMask (1<<1)
#define MapShiftMask (MapRightShiftMask | MapLeftShiftMask)
#define MapRightAltMask (1<<2)
#define MapLeftAltMask (1<<3)
#define MapAltGrMask MapRightAltMask
#define MapRightCtrlMask (1<<4)
#define MapLeftCtrlMask (1<<5)
#define MapCtrlMask (MapRightCtrlMask | MapLeftCtrlMask)
#define MapRightWinMask (1<<6)
#define MapLeftWinMask (1<<7)
#define MapWinMask (MapRightWinMask | MapLeftWinMask)
#define MapNumLockMask (1<<8)
#define MapCapsLockMask (1<<9)
#define MapLocalStateMask (1<<10)
#define MapInhibitMask (1<<11)
#define MASK_ADD_BITS(var, mask) (var |= mask)
#define MASK_REMOVE_BITS(var, mask) (var &= ~mask)
#define MASK_HAS_BITS(var, mask) ((var & mask)>0)
#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 */
#ifndef CF_TEXT
#define CF_TEXT 1
#define CF_BITMAP 2
#define CF_METAFILEPICT 3
#define CF_SYLK 4
#define CF_DIF 5
#define CF_TIFF 6
#define CF_OEMTEXT 7
#define CF_DIB 8
#define CF_PALETTE 9
#define CF_PENDATA 10
#define CF_RIFF 11
#define CF_WAVE 12
#define CF_UNICODETEXT 13
#define CF_ENHMETAFILE 14
#define CF_HDROP 15
#define CF_LOCALE 16
#define CF_MAX 17
#define CF_OWNERDISPLAY 128
#define CF_DSPTEXT 129
#define CF_DSPBITMAP 130
#define CF_DSPMETAFILEPICT 131
#define CF_DSPENHMETAFILE 142
#define CF_PRIVATEFIRST 512
#define CF_PRIVATELAST 767
#define CF_GDIOBJFIRST 768
#define CF_GDIOBJLAST 1023
#endif
/* Sound format constants */
#define WAVE_FORMAT_PCM 1
#define WAVE_FORMAT_ADPCM 2
#define WAVE_FORMAT_ALAW 6
#define WAVE_FORMAT_MULAW 7
/* Virtual channel options */
#define CHANNEL_OPTION_INITIALIZED 0x80000000
#define CHANNEL_OPTION_ENCRYPT_RDP 0x40000000
#define CHANNEL_OPTION_COMPRESS_RDP 0x00800000
#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
#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
#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
/* RDPDR constants */
#define RDPDR_MAX_DEVICES 0x10
#define DEVICE_TYPE_SERIAL 0x01
#define DEVICE_TYPE_PARALLEL 0x02
#define DEVICE_TYPE_PRINTER 0x04
#define DEVICE_TYPE_DISK 0x08
#define DEVICE_TYPE_SCARD 0x20
#define FILE_DIRECTORY_FILE 0x00000001
#define FILE_NON_DIRECTORY_FILE 0x00000040
#define FILE_COMPLETE_IF_OPLOCKED 0x00000100
#define FILE_DELETE_ON_CLOSE 0x00001000
#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000
/* RDP5 disconnect PDU */
#define exDiscReasonNoInfo 0x0000
#define exDiscReasonAPIInitiatedDisconnect 0x0001
#define exDiscReasonAPIInitiatedLogoff 0x0002
#define exDiscReasonServerIdleTimeout 0x0003
#define exDiscReasonServerLogonTimeout 0x0004
#define exDiscReasonReplacedByOtherConnection 0x0005
#define exDiscReasonOutOfMemory 0x0006
#define exDiscReasonServerDeniedConnection 0x0007
#define exDiscReasonServerDeniedConnectionFips 0x0008
#define exDiscReasonLicenseInternal 0x0100
#define exDiscReasonLicenseNoLicenseServer 0x0101
#define exDiscReasonLicenseNoLicense 0x0102
#define exDiscReasonLicenseErrClientMsg 0x0103
#define exDiscReasonLicenseHwidDoesntMatchLicense 0x0104
#define exDiscReasonLicenseErrClientLicense 0x0105
#define exDiscReasonLicenseCantFinishProtocol 0x0106
#define exDiscReasonLicenseClientEndedProtocol 0x0107
#define exDiscReasonLicenseErrClientEncryption 0x0108
#define exDiscReasonLicenseCantUpgradeLicense 0x0109
#define exDiscReasonLicenseNoRemoteConnections 0x010a
/* SeamlessRDP constants */
#define SEAMLESSRDP_NOTYETMAPPED -1
#define SEAMLESSRDP_NORMAL 0
#define SEAMLESSRDP_MINIMIZED 1
#define SEAMLESSRDP_MAXIMIZED 2
#define SEAMLESSRDP_POSITION_TIMER 200000
#define SEAMLESSRDP_CREATE_MODAL 0x0001
#define SEAMLESSRDP_HELLO_RECONNECT 0x0001
#define SEAMLESSRDP_HELLO_HIDDEN 0x0002

@ -0,0 +1,8 @@
[main]
server=192.168.1.1
port=3389
username=user1
password=password1
bpp=16
#geometry=300x400
fullscreen

@ -0,0 +1,345 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
RDP licensing negotiation
Copyright (C) Matthew Chapman 1999-2005
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
(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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rdesktop.h"
//#include <openssl/rc4.h>
void *
ssl_rc4_info_create(void);
void
ssl_rc4_info_delete(void * rc4_info);
void
ssl_rc4_set_key(void * rc4_info, char * key, int len);
void
ssl_rc4_crypt(void * rc4_info, char * in_data, char * out_data, int len);
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[64];
extern char g_hostname[16];
static uint8 g_licence_key[16];
static uint8 g_licence_sign_key[16];
BOOL g_licence_issued = False;
/* Generate a session key and RC4 keys, given client and server randoms */
static void
licence_generate_keys(uint8 * client_random, uint8 * server_random, uint8 * pre_master_secret)
{
uint8 master_secret[48];
uint8 key_block[48];
/* Generate master secret and then key material */
sec_hash_48(master_secret, pre_master_secret, client_random, server_random, 'A');
sec_hash_48(key_block, master_secret, server_random, client_random, 'A');
/* Store first 16 bytes of session key as MAC secret */
memcpy(g_licence_sign_key, key_block, 16);
/* Generate RC4 key from next 16 bytes */
sec_hash_16(g_licence_key, &key_block[16], client_random, server_random);
}
static void
licence_generate_hwid(uint8 * hwid)
{
buf_out_uint32(hwid, 2);
strncpy((char *) (hwid + 4), g_hostname, LICENCE_HWID_SIZE - 4);
}
/* Present an existing licence to the server */
static void
licence_present(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 +
licence_size + LICENCE_HWID_SIZE + LICENCE_SIGNATURE_SIZE;
STREAM s;
s = sec_init(sec_flags, length + 4);
out_uint8(s, LICENCE_TAG_PRESENT);
out_uint8(s, 2); /* version */
out_uint16_le(s, length);
out_uint32_le(s, 1);
out_uint16(s, 0);
out_uint16_le(s, 0x0201);
out_uint8p(s, client_random, SEC_RANDOM_SIZE);
out_uint16(s, 0);
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, 1);
out_uint16_le(s, licence_size);
out_uint8p(s, licence_data, licence_size);
out_uint16_le(s, 1);
out_uint16_le(s, LICENCE_HWID_SIZE);
out_uint8p(s, hwid, LICENCE_HWID_SIZE);
out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE);
s_mark_end(s);
sec_send(s, sec_flags);
}
/* Send a licence request packet */
static void
licence_send_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;
STREAM s;
s = sec_init(sec_flags, length + 2);
out_uint8(s, LICENCE_TAG_REQUEST);
out_uint8(s, 2); /* version */
out_uint16_le(s, length);
out_uint32_le(s, 1);
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, (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);
out_uint16_le(s, userlen);
out_uint8p(s, user, userlen);
out_uint16_le(s, LICENCE_TAG_HOST);
out_uint16_le(s, hostlen);
out_uint8p(s, host, hostlen);
s_mark_end(s);
sec_send(s, sec_flags);
}
/* Process a licence demand packet */
static void
licence_process_demand(STREAM s)
{
uint8 null_data[SEC_MODULUS_SIZE];
uint8 *server_random;
uint8 signature[LICENCE_SIGNATURE_SIZE];
uint8 hwid[LICENCE_HWID_SIZE];
uint8 *licence_data;
int licence_size;
void * crypt_key;
/* Retrieve the server random from the incoming packet */
in_uint8p(s, server_random, SEC_RANDOM_SIZE);
/* We currently use null client keys. This is a bit naughty but, hey,
the security of licence negotiation isn't exactly paramount. */
memset(null_data, 0, sizeof(null_data));
licence_generate_keys(null_data, server_random, null_data);
licence_size = load_licence(&licence_data);
if (licence_size > 0)
{
/* Generate a signature for the HWID buffer */
licence_generate_hwid(hwid);
sec_sign(signature, 16, g_licence_sign_key, 16, hwid, sizeof(hwid));
/* Now encrypt the HWID */
crypt_key = ssl_rc4_info_create();
ssl_rc4_set_key(crypt_key, g_licence_key, 16);
ssl_rc4_crypt(crypt_key, hwid, hwid, sizeof(hwid));
ssl_rc4_info_delete(crypt_key);
licence_present(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);
}
/* Send an authentication response packet */
static void
licence_send_authresp(uint8 * token, uint8 * crypt_hwid, uint8 * signature)
{
uint32 sec_flags = SEC_LICENCE_NEG;
uint16 length = 58;
STREAM s;
s = sec_init(sec_flags, length + 2);
out_uint8(s, LICENCE_TAG_AUTHRESP);
out_uint8(s, 2); /* version */
out_uint16_le(s, length);
out_uint16_le(s, 1);
out_uint16_le(s, LICENCE_TOKEN_SIZE);
out_uint8p(s, token, LICENCE_TOKEN_SIZE);
out_uint16_le(s, 1);
out_uint16_le(s, LICENCE_HWID_SIZE);
out_uint8p(s, crypt_hwid, LICENCE_HWID_SIZE);
out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE);
s_mark_end(s);
sec_send(s, sec_flags);
}
/* Parse an authentication request packet */
static BOOL
licence_parse_authreq(STREAM s, uint8 ** token, uint8 ** signature)
{
uint16 tokenlen;
in_uint8s(s, 6); /* unknown: f8 3d 15 00 04 f6 */
in_uint16_le(s, tokenlen);
if (tokenlen != LICENCE_TOKEN_SIZE)
{
error("token len %d\n", tokenlen);
return False;
}
in_uint8p(s, *token, tokenlen);
in_uint8p(s, *signature, LICENCE_SIGNATURE_SIZE);
return s_check_end(s);
}
/* Process an authentication request packet */
static void
licence_process_authreq(STREAM s)
{
uint8 *in_token, *in_sig;
uint8 out_token[LICENCE_TOKEN_SIZE], decrypt_token[LICENCE_TOKEN_SIZE];
uint8 hwid[LICENCE_HWID_SIZE], crypt_hwid[LICENCE_HWID_SIZE];
uint8 sealed_buffer[LICENCE_TOKEN_SIZE + LICENCE_HWID_SIZE];
uint8 out_sig[LICENCE_SIGNATURE_SIZE];
void * crypt_key;
/* Parse incoming packet and save the encrypted token */
licence_parse_authreq(s, &in_token, &in_sig);
memcpy(out_token, in_token, LICENCE_TOKEN_SIZE);
/* Decrypt the token. It should read TEST in Unicode. */
crypt_key = ssl_rc4_info_create();
ssl_rc4_set_key(crypt_key, g_licence_key, 16);
ssl_rc4_crypt(crypt_key, in_token, decrypt_token, LICENCE_TOKEN_SIZE);
ssl_rc4_info_delete(crypt_key);
/* Generate a signature for a buffer of token and HWID */
licence_generate_hwid(hwid);
memcpy(sealed_buffer, decrypt_token, LICENCE_TOKEN_SIZE);
memcpy(sealed_buffer + LICENCE_TOKEN_SIZE, hwid, LICENCE_HWID_SIZE);
sec_sign(out_sig, 16, g_licence_sign_key, 16, sealed_buffer, sizeof(sealed_buffer));
/* Now encrypt the HWID */
crypt_key = ssl_rc4_info_create();
ssl_rc4_set_key(crypt_key, g_licence_key, 16);
ssl_rc4_crypt(crypt_key, hwid, crypt_hwid, LICENCE_HWID_SIZE);
ssl_rc4_info_delete(crypt_key);
licence_send_authresp(out_token, crypt_hwid, out_sig);
}
/* Process an licence issue packet */
static void
licence_process_issue(STREAM s)
{
void * crypt_key;
uint32 length;
uint16 check;
int i;
in_uint8s(s, 2); /* 3d 45 - unknown */
in_uint16_le(s, length);
if (!s_check_rem(s, length))
return;
crypt_key = ssl_rc4_info_create();
ssl_rc4_set_key(crypt_key, g_licence_key, 16);
ssl_rc4_crypt(crypt_key, s->p, s->p, length);
ssl_rc4_info_delete(crypt_key);
in_uint16(s, check);
if (check != 0)
return;
g_licence_issued = True;
in_uint8s(s, 2); /* pad */
/* advance to fourth string */
length = 0;
for (i = 0; i < 4; i++)
{
in_uint8s(s, length);
in_uint32_le(s, length);
if (!s_check_rem(s, length))
return;
}
g_licence_issued = True;
save_licence(s->p, length);
}
/* Process a licence packet */
void
licence_process(STREAM s)
{
uint8 tag;
in_uint8(s, tag);
in_uint8s(s, 3); /* version, length */
switch (tag)
{
case LICENCE_TAG_DEMAND:
licence_process_demand(s);
break;
case LICENCE_TAG_AUTHREQ:
licence_process_authreq(s);
break;
case LICENCE_TAG_ISSUE:
licence_process_issue(s);
break;
case LICENCE_TAG_REISSUE:
case LICENCE_TAG_RESULT:
break;
default:
unimpl("licence tag 0x%x\n", tag);
}
}

@ -0,0 +1,19 @@
# makefile
OBJS = tcp.obj iso.obj mcs.obj secure.obj rdp.obj rdp5.obj orders.obj \
bitmap.obj cache.obj mppc.obj pstcache.obj channels.obj licence.obj \
ssl_calls.obj
UIOBJS = uimain.obj bsops.obj win32.obj
#-w-aus -w-rch
CFLAGS = -O2 -w-par -I.. -Ic:\borland\bcc55\include
LDFLAGS = -W -Lc:\borland\bcc55\lib
all: rd
rd: $(OBJS) $(UIOBJS)
$(CC) -ewinrdesktop.exe $(LDFLAGS) $(OBJS) $(UIOBJS)
clean:
del /q $(OBJS) $(UIOBJS) winrdesktop.exe *.tds

@ -390,7 +390,7 @@ mcs_connect(char *server, STREAM mcs_data, char *username)
if (!mcs_recv_aucf(&g_mcs_userid))
goto error;
mcs_send_cjrq(g_mcs_userid + MCS_USERCHANNEL_BASE);
mcs_send_cjrq((uint16) (g_mcs_userid + MCS_USERCHANNEL_BASE));
if (!mcs_recv_cjcf())
goto error;
@ -431,7 +431,7 @@ mcs_reconnect(char *server, STREAM mcs_data)
if (!mcs_recv_aucf(&g_mcs_userid))
goto error;
mcs_send_cjrq(g_mcs_userid + MCS_USERCHANNEL_BASE);
mcs_send_cjrq((uint16) (g_mcs_userid + MCS_USERCHANNEL_BASE));
if (!mcs_recv_cjcf())
goto error;

@ -296,7 +296,7 @@ process_line(STREAM s, LINE_ORDER * os, uint32 present, BOOL delta)
return;
}
ui_line(os->opcode - 1, os->startx, os->starty, os->endx, os->endy, &os->pen);
ui_line(ROP_MINUS_1(os->opcode), os->startx, os->starty, os->endx, os->endy, &os->pen);
}
/* Process an opaque rectangle order */
@ -379,7 +379,7 @@ process_desksave(STREAM s, DESKSAVE_ORDER * os, uint32 present, BOOL delta)
static void
process_memblt(STREAM s, MEMBLT_ORDER * os, uint32 present, BOOL delta)
{
HBITMAP bitmap;
RD_HBITMAP bitmap;
if (present & 0x0001)
{
@ -425,7 +425,7 @@ process_memblt(STREAM s, MEMBLT_ORDER * os, uint32 present, BOOL delta)
static void
process_triblt(STREAM s, TRIBLT_ORDER * os, uint32 present, BOOL delta)
{
HBITMAP bitmap;
RD_HBITMAP bitmap;
if (present & 0x000001)
{
@ -551,7 +551,7 @@ process_polygon(STREAM s, POLYGON_ORDER * os, uint32 present, BOOL delta)
}
if (next - 1 == os->npoints)
ui_polygon(os->opcode - 1, os->fillmode, points, os->npoints + 1, NULL, 0,
ui_polygon(ROP_MINUS_1(os->opcode), os->fillmode, points, os->npoints + 1, NULL, 0,
os->fgcolour);
else
error("polygon parse error\n");
@ -636,7 +636,7 @@ process_polygon2(STREAM s, POLYGON2_ORDER * os, uint32 present, BOOL delta)
}
if (next - 1 == os->npoints)
ui_polygon(os->opcode - 1, os->fillmode, points, os->npoints + 1,
ui_polygon(ROP_MINUS_1(os->opcode), os->fillmode, points, os->npoints + 1,
&os->brush, os->bgcolour, os->fgcolour);
else
error("polygon2 parse error\n");
@ -715,7 +715,7 @@ process_polyline(STREAM s, POLYLINE_ORDER * os, uint32 present, BOOL delta)
}
if (next - 1 == os->lines)
ui_polyline(os->opcode - 1, points, os->lines + 1, &pen);
ui_polyline(ROP_MINUS_1(os->opcode), points, os->lines + 1, &pen);
else
error("polyline parse error\n");
@ -750,7 +750,7 @@ 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(os->opcode - 1, os->fillmode, os->left, os->top, os->right - os->left,
ui_ellipse(ROP_MINUS_1(os->opcode), os->fillmode, os->left, os->top, os->right - os->left,
os->bottom - os->top, NULL, 0, os->fgcolour);
}
@ -788,7 +788,7 @@ 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(os->opcode - 1, os->fillmode, os->left, os->top, os->right - os->left,
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);
}
@ -863,7 +863,7 @@ process_text2(STREAM s, TEXT2_ORDER * os, uint32 present, BOOL delta)
DEBUG(("\n"));
ui_draw_text(os->font, os->flags, os->opcode - 1, os->mixmode, os->x, os->y,
ui_draw_text(os->font, os->flags, ROP_MINUS_1(os->opcode), 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,
@ -874,10 +874,10 @@ process_text2(STREAM s, TEXT2_ORDER * os, uint32 present, BOOL delta)
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;
uint8 *data/*, *inverted*/;
int y;
in_uint8(s, cache_id);
@ -889,7 +889,8 @@ process_raw_bmpcache(STREAM s)
in_uint16_le(s, bufsize);
in_uint16_le(s, cache_idx);
in_uint8p(s, data, bufsize);
bitmap = ui_create_bitmap_ex(width, height, data, bufsize, False);
/*
DEBUG(("RAW_BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n", width, height, cache_id, cache_idx));
inverted = (uint8 *) xmalloc(width * height * Bpp);
for (y = 0; y < height; y++)
@ -900,6 +901,7 @@ process_raw_bmpcache(STREAM s)
bitmap = ui_create_bitmap(width, height, inverted);
xfree(inverted);
*/
cache_put_bitmap(cache_id, cache_idx, bitmap);
}
@ -907,10 +909,10 @@ 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;
uint8 *data/*, *bmpdata*/;
uint16 bufsize, pad2, row_size, final_size;
uint8 pad1;
@ -944,6 +946,9 @@ process_bmpcache(STREAM s)
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));
bitmap = ui_create_bitmap_ex(width, height, data, size, True);
cache_put_bitmap(cache_id, cache_idx, bitmap);
/*
bmpdata = (uint8 *) xmalloc(width * height * Bpp);
if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
@ -957,13 +962,14 @@ process_bmpcache(STREAM s)
}
xfree(bmpdata);
*/
}
/* Process a bitmap cache v2 order */
static void
process_bmpcache2(STREAM s, uint16 flags, BOOL compressed)
{
HBITMAP bitmap;
RD_HBITMAP bitmap;
int y;
uint8 cache_id, cache_idx_low, width, height, Bpp;
uint16 cache_idx, bufsize;
@ -1004,6 +1010,11 @@ process_bmpcache2(STREAM s, uint16 flags, BOOL compressed)
DEBUG(("BMPCACHE2(compr=%d,flags=%x,cx=%d,cy=%d,id=%d,idx=%d,Bpp=%d,bs=%d)\n",
compressed, flags, width, height, cache_id, cache_idx, Bpp, bufsize));
bitmap = ui_create_bitmap_ex(width, height, data, bufsize, compressed);
cache_put_bitmap(cache_id, cache_idx, bitmap);
/* todo, persitant bitmap not working this was */
/*
bmpdata = (uint8 *) xmalloc(width * height * Bpp);
if (compressed)
@ -1029,7 +1040,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,
width * height * Bpp, bmpdata);
(uint16) (width * height * Bpp), bmpdata);
}
else
{
@ -1037,6 +1048,7 @@ process_bmpcache2(STREAM s, uint16 flags, BOOL compressed)
}
xfree(bmpdata);
*/
}
/* Process a colourmap cache order */
@ -1045,7 +1057,7 @@ process_colcache(STREAM s)
{
COLOURENTRY *entry;
COLOURMAP map;
HCOLOURMAP hmap;
RD_HCOLOURMAP hmap;
uint8 cache_id;
int i;
@ -1077,7 +1089,7 @@ process_colcache(STREAM s)
static void
process_fontcache(STREAM s)
{
HGLYPH bitmap;
RD_HGLYPH bitmap;
uint8 font, nglyphs;
uint16 character, offset, baseline, width, height;
int i, datasize;

@ -0,0 +1,315 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Copyright (C) Matthew Chapman 1999-2005
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
(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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef RDESKTOP_PROTO_H
#define RDESKTOP_PROTO_H
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/* bitmap.c */
BOOL bitmap_decompress(uint8 * output, int width, int height, uint8 * input, int size, int Bpp);
BOOL bitmap_decompress_ex(uint8 * output, int width, int height, uint8 * input, int size,
int in_bpp, int out_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);
void cache_evict_bitmap(uint8 id);
RD_HBITMAP cache_get_bitmap(uint8 id, uint16 idx);
void cache_put_bitmap(uint8 id, uint16 idx, RD_HBITMAP bitmap);
void cache_save_state(void);
FONTGLYPH *cache_get_font(uint8 font, uint16 character);
void cache_put_font(uint8 font, uint16 character, uint16 offset, uint16 baseline, uint16 width,
uint16 height, RD_HGLYPH pixmap);
DATABLOB *cache_get_text(uint8 cache_id);
void cache_put_text(uint8 cache_id, void *data, int length);
uint8 *cache_get_desktop(uint32 offset, int cx, int cy, int bytes_per_pixel);
void cache_put_desktop(uint32 offset, int cx, int cy, int scanline, int bytes_per_pixel,
uint8 * data);
RD_HCURSOR cache_get_cursor(uint16 cache_idx);
void cache_put_cursor(uint16 cache_idx, RD_HCURSOR cursor);
/* channels.c */
VCHANNEL *channel_register(char *name, uint32 flags, void (*callback) (STREAM));
STREAM channel_init(VCHANNEL * channel, uint32 length);
void channel_send(STREAM s, VCHANNEL * channel);
void channel_process(STREAM s, uint16 mcs_channel);
/* cliprdr.c */
void cliprdr_send_simple_native_format_announce(uint32 format);
void cliprdr_send_native_format_announce(uint8 * formats_data, uint32 formats_data_length);
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);
/* disk.c */
int disk_enum_devices(uint32 * id, char *optarg);
RD_NTSTATUS disk_query_information(RD_NTHANDLE handle, uint32 info_class, STREAM out);
RD_NTSTATUS disk_set_information(RD_NTHANDLE handle, uint32 info_class, STREAM in, STREAM out);
RD_NTSTATUS disk_check_notify(RD_NTHANDLE handle);
RD_NTSTATUS disk_create_notify(RD_NTHANDLE handle, uint32 info_class);
RD_NTSTATUS disk_query_volume_information(RD_NTHANDLE handle, uint32 info_class, STREAM out);
RD_NTSTATUS disk_query_directory(RD_NTHANDLE handle, uint32 info_class, char *pattern, STREAM out);
/* mppc.c */
int mppc_expand(uint8 * data, uint32 clen, uint8 ctype, uint32 * roff, uint32 * rlen);
/* ewmhints.c */
int get_current_workarea(uint32 * x, uint32 * y, uint32 * width, uint32 * height);
void ewmh_init(void);
/* iso.c */
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);
void iso_disconnect(void);
void iso_reset_state(void);
/* licence.c */
void licence_process(STREAM s);
/* mcs.c */
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);
void mcs_disconnect(void);
void mcs_reset_state(void);
/* orders.c */
void process_orders(STREAM s, uint16 num_orders);
void reset_order_state(void);
/* parallel.c */
int parallel_enum_devices(uint32 * id, char *optarg);
/* printer.c */
int printer_enum_devices(uint32 * id, char *optarg);
/* printercache.c */
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);
int pstcache_enumerate(uint8 id, HASH_KEY * keylist);
BOOL pstcache_init(uint8 cache_id);
/* rdesktop.c */
int main(int argc, char *argv[]);
void generate_random(uint8 * random);
void *xmalloc(int size);
char *xstrdup(const char *s);
void *xrealloc(void *oldmem, int size);
void xfree(void *mem);
void error(char *format, ...);
void warning(char *format, ...);
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);
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);
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);
/* 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_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_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_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);
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);
/* 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);
/* secure.c */
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);
void sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 * data,
int datalen);
void sec_decrypt(uint8 * data, int length);
STREAM sec_init(uint32 flags, int maxlen);
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);
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);
/* tcp.c */
STREAM tcp_init(uint32 maxlen);
void tcp_send(STREAM s);
STREAM tcp_recv(STREAM s, uint32 length);
BOOL tcp_connect(char *server);
void tcp_disconnect(void);
char *tcp_get_address(void);
void tcp_reset_state(void);
/* xclip.c */
void ui_clip_format_announce(uint8 * data, uint32 length);
void ui_clip_handle_data(uint8 * data, uint32 length);
void ui_clip_request_failed(void);
void ui_clip_request_data(uint32 format);
void ui_clip_sync(void);
void ui_clip_set_mode(const char *optarg);
void xclip_init(void);
/* xkeymap.c */
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);
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);
uint16 xkeymap_translate_button(unsigned int button);
char *get_ksname(uint32 keysym);
void save_remote_modifiers(uint8 scancode);
void restore_remote_modifiers(uint32 ev_time, uint8 scancode);
void ensure_remote_modifiers(uint32 ev_time, key_translation tr);
unsigned int read_keyboard_state(void);
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);
void ui_deinit(void);
BOOL ui_create_window(void);
void ui_resize_window(void);
void ui_destroy_window(void);
void xwin_toggle_fullscreen(void);
int ui_select(int rdp_socket);
void ui_move_pointer(int x, int y);
RD_HBITMAP ui_create_bitmap(int width, int height, uint8 * data);
RD_HBITMAP ui_create_bitmap_ex(int width, int height, uint8 * data, int data_size, int compressed);
void ui_paint_bitmap(int x, int y, int cx, int cy, int width, int height, uint8 * data);
void ui_paint_bitmap_ex(int x, int y, int cx, int cy, int width, int height, uint8 * data,
int data_size, int compressed);
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);
void ui_set_cursor(RD_HCURSOR cursor);
void ui_destroy_cursor(RD_HCURSOR cursor);
void ui_set_null_cursor(void);
RD_HCOLOURMAP ui_create_colourmap(COLOURMAP * colours);
void ui_destroy_colourmap(RD_HCOLOURMAP map);
void ui_set_colourmap(RD_HCOLOURMAP map);
void ui_set_clip(int x, int y, int cx, int cy);
void ui_reset_clip(void);
void ui_bell(void);
void ui_destblt(uint8 opcode, int x, int y, int cx, int cy);
void ui_patblt(uint8 opcode, int x, int y, int cx, int cy, BRUSH * brush, int bgcolour,
int fgcolour);
void ui_screenblt(uint8 opcode, int x, int y, int cx, int cy, int srcx, int srcy);
void ui_memblt(uint8 opcode, int x, int y, int cx, int cy, RD_HBITMAP src, int srcx, int srcy);
void ui_triblt(uint8 opcode, int x, int y, int cx, int cy, RD_HBITMAP src, int srcx, int srcy,
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,
int bgcolour, int fgcolour);
void ui_polyline(uint8 opcode, 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,
int bgcolour, int fgcolour);
void ui_draw_text(uint8 font, uint8 flags, uint8 opcode, int mixmode, int x, int y, int clipx,
int clipy, int clipcx, int clipcy, int boxx, int boxy, int boxcx, int boxcy,
BRUSH * brush, int bgcolour, int fgcolour, uint8 * text, uint8 length);
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_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_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);
void ui_seamless_settitle(unsigned long id, const char *title, unsigned long flags);
void ui_seamless_setstate(unsigned long id, unsigned int state, unsigned long flags);
void ui_seamless_syncbegin(unsigned long flags);
void ui_seamless_ack(unsigned int serial);
/* lspci.c */
BOOL lspci_init(void);
/* seamless.c */
BOOL seamless_init(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,
unsigned long flags);
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);
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif

@ -107,7 +107,7 @@ pstcache_save_bitmap(uint8 cache_id, uint16 cache_idx, uint8 * key,
int
pstcache_enumerate(uint8 id, HASH_KEY * keylist)
{
int fd, n;
int fd, n;
uint16 idx;
sint16 mru_idx[0xa00];
uint32 mru_stamp[0xa00];

@ -2,17 +2,17 @@
rdesktop: A Remote Desktop Protocol client.
Master include file
Copyright (C) Matthew Chapman 1999-2005
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
(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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@ -20,15 +20,22 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <sys/time.h>
#include <string.h>
#ifdef _WIN32
#include <winsock2.h> /* winsock2.h first */
#include <windows.h>
#include <time.h>
#else /* WIN32 */
#include <dirent.h>
#include <sys/types.h>
#include <sys/time.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#else
#else /* HAVE_SYS_SELECT_H */
#include <sys/types.h>
#include <unistd.h>
#endif
#endif /* HAVE_SYS_SELECT_H */
#endif /* WIN32 */
#include <limits.h> /* PATH_MAX */
#define VERSION "1.4.1"

File diff suppressed because it is too large Load Diff

@ -20,12 +20,48 @@
#include "rdesktop.h"
#include <openssl/rc4.h>
#include <openssl/md5.h>
#include <openssl/sha.h>
#include <openssl/bn.h>
#include <openssl/x509v3.h>
//#include <openssl/rc4.h>
//#include <openssl/md5.h>
//#include <openssl/sha.h>
//#include <openssl/bn.h>
//#include <openssl/x509v3.h>
void *
ssl_sha1_info_create(void);
void
ssl_sha1_info_delete(void * sha1_info);
void
ssl_sha1_clear(void * sha1_info);
void
ssl_sha1_transform(void * sha1_info, char * data, int len);
void
ssl_sha1_complete(void * sha1_info, char * data);
void *
ssl_md5_info_create(void);
void
ssl_md5_info_delete(void * md5_info);
void *
ssl_md5_info_create(void);
void
ssl_md5_info_delete(void * md5_info);
void
ssl_md5_clear(void * md5_info);
void
ssl_md5_transform(void * md5_info, char * data, int len);
void
ssl_md5_complete(void * md5_info, char * data);
void *
ssl_rc4_info_create(void);
void
ssl_rc4_info_delete(void * rc4_info);
void
ssl_rc4_set_key(void * rc4_info, char * key, int len);
void
ssl_rc4_crypt(void * rc4_info, char * in_data, char * out_data, int len);
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_hostname[16];
extern int g_width;
extern int g_height;
@ -43,17 +79,17 @@ extern VCHANNEL g_channels[];
extern unsigned int g_num_channels;
static int rc4_key_len;
static RC4_KEY rc4_decrypt_key;
static RC4_KEY rc4_encrypt_key;
static RSA *server_public_key;
static uint32 server_public_key_len;
static void * rc4_decrypt_key = 0;
static void * rc4_encrypt_key = 0;
//static RSA *server_public_key;
static void * server_public_key;
static uint8 sec_sign_key[16];
static uint8 sec_decrypt_key[16];
static uint8 sec_encrypt_key[16];
static uint8 sec_decrypt_update_key[16];
static uint8 sec_encrypt_update_key[16];
static uint8 sec_crypted_random[SEC_MAX_MODULUS_SIZE];
static uint8 sec_crypted_random[SEC_MODULUS_SIZE];
uint16 g_server_rdp_version = 0;
@ -80,25 +116,27 @@ sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt)
{
uint8 shasig[20];
uint8 pad[4];
SHA_CTX sha;
MD5_CTX md5;
void * sha;
void * md5;
int i;
for (i = 0; i < 3; i++)
{
memset(pad, salt + i, i + 1);
SHA1_Init(&sha);
SHA1_Update(&sha, pad, i + 1);
SHA1_Update(&sha, in, 48);
SHA1_Update(&sha, salt1, 32);
SHA1_Update(&sha, salt2, 32);
SHA1_Final(shasig, &sha);
MD5_Init(&md5);
MD5_Update(&md5, in, 48);
MD5_Update(&md5, shasig, 20);
MD5_Final(&out[i * 16], &md5);
sha = ssl_sha1_info_create();
ssl_sha1_clear(sha);
ssl_sha1_transform(sha, pad, i + 1);
ssl_sha1_transform(sha, in, 48);
ssl_sha1_transform(sha, salt1, 32);
ssl_sha1_transform(sha, salt2, 32);
ssl_sha1_complete(sha, shasig);
ssl_sha1_info_delete(sha);
md5 = ssl_md5_info_create();
ssl_md5_clear(md5);
ssl_md5_transform(md5, in, 48);
ssl_md5_transform(md5, shasig, 20);
ssl_md5_complete(md5, out + i * 16);
ssl_md5_info_delete(md5);
}
}
@ -108,13 +146,15 @@ 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)
{
MD5_CTX md5;
MD5_Init(&md5);
MD5_Update(&md5, in, 16);
MD5_Update(&md5, salt1, 32);
MD5_Update(&md5, salt2, 32);
MD5_Final(out, &md5);
void * md5;
md5 = ssl_md5_info_create();
ssl_md5_clear(md5);
ssl_md5_transform(md5, in, 16);
ssl_md5_transform(md5, salt1, 32);
ssl_md5_transform(md5, salt2, 32);
ssl_md5_complete(md5, out);
ssl_md5_info_delete(md5);
}
/* Reduce key entropy from 64 to 40 bits */
@ -167,9 +207,15 @@ sec_generate_keys(uint8 * client_random, uint8 * server_random, int rc4_key_size
memcpy(sec_decrypt_update_key, sec_decrypt_key, 16);
memcpy(sec_encrypt_update_key, sec_encrypt_key, 16);
/* Initialise RC4 state arrays */
RC4_set_key(&rc4_decrypt_key, rc4_key_len, sec_decrypt_key);
RC4_set_key(&rc4_encrypt_key, rc4_key_len, sec_encrypt_key);
/* Initialise RC4 state arrays */
ssl_rc4_info_delete(rc4_decrypt_key);
rc4_decrypt_key = ssl_rc4_info_create();
ssl_rc4_set_key(rc4_decrypt_key, sec_decrypt_key, rc4_key_len);
ssl_rc4_info_delete(rc4_encrypt_key);
rc4_encrypt_key = ssl_rc4_info_create();
ssl_rc4_set_key(rc4_encrypt_key, sec_encrypt_key, rc4_key_len);
}
static uint8 pad_54[40] = {
@ -203,24 +249,28 @@ sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 *
uint8 shasig[20];
uint8 md5sig[16];
uint8 lenhdr[4];
SHA_CTX sha;
MD5_CTX md5;
void * sha;
void * md5;
buf_out_uint32(lenhdr, datalen);
SHA1_Init(&sha);
SHA1_Update(&sha, session_key, keylen);
SHA1_Update(&sha, pad_54, 40);
SHA1_Update(&sha, lenhdr, 4);
SHA1_Update(&sha, data, datalen);
SHA1_Final(shasig, &sha);
MD5_Init(&md5);
MD5_Update(&md5, session_key, keylen);
MD5_Update(&md5, pad_92, 48);
MD5_Update(&md5, shasig, 20);
MD5_Final(md5sig, &md5);
sha = ssl_sha1_info_create();
ssl_sha1_clear(sha);
ssl_sha1_transform(sha, session_key, keylen);
ssl_sha1_transform(sha, pad_54, 40);
ssl_sha1_transform(sha, lenhdr, 4);
ssl_sha1_transform(sha, data, datalen);
ssl_sha1_complete(sha, shasig);
ssl_sha1_info_delete(sha);
md5 = ssl_md5_info_create();
ssl_md5_clear(md5);
ssl_md5_transform(md5, session_key, keylen);
ssl_md5_transform(md5, pad_92, 48);
ssl_md5_transform(md5, shasig, 20);
ssl_md5_complete(md5, md5sig);
ssl_md5_info_delete(md5);
memcpy(signature, md5sig, siglen);
}
@ -229,25 +279,32 @@ static void
sec_update(uint8 * key, uint8 * update_key)
{
uint8 shasig[20];
SHA_CTX sha;
MD5_CTX md5;
RC4_KEY update;
SHA1_Init(&sha);
SHA1_Update(&sha, update_key, rc4_key_len);
SHA1_Update(&sha, pad_54, 40);
SHA1_Update(&sha, key, rc4_key_len);
SHA1_Final(shasig, &sha);
MD5_Init(&md5);
MD5_Update(&md5, update_key, rc4_key_len);
MD5_Update(&md5, pad_92, 48);
MD5_Update(&md5, shasig, 20);
MD5_Final(key, &md5);
RC4_set_key(&update, rc4_key_len, key);
RC4(&update, rc4_key_len, key, key);
void * sha;
void * md5;
void * update;
sha = ssl_sha1_info_create();
ssl_sha1_clear(sha);
ssl_sha1_transform(sha, update_key, rc4_key_len);
ssl_sha1_transform(sha, pad_54, 40);
ssl_sha1_transform(sha, key, rc4_key_len);
ssl_sha1_complete(sha, shasig);
ssl_sha1_info_delete(sha);
md5 = ssl_md5_info_create();
ssl_md5_clear(md5);
ssl_md5_transform(md5, update_key, rc4_key_len);
ssl_md5_transform(md5, pad_92, 48);
ssl_md5_transform(md5, shasig, 20);
ssl_md5_complete(md5, key);
ssl_md5_info_delete(md5);
update = ssl_rc4_info_create();
ssl_rc4_set_key(update, key, rc4_key_len);
ssl_rc4_crypt(update, key, key, rc4_key_len);
ssl_rc4_info_delete(update);
if (rc4_key_len == 8)
sec_make_40bit(key);
}
@ -258,12 +315,11 @@ sec_encrypt(uint8 * data, int length)
{
if (sec_encrypt_use_count == 4096)
{
sec_update(sec_encrypt_key, sec_encrypt_update_key);
RC4_set_key(&rc4_encrypt_key, rc4_key_len, sec_encrypt_key);
sec_update(sec_encrypt_key, sec_encrypt_update_key);
ssl_rc4_set_key(rc4_encrypt_key, sec_encrypt_key, rc4_key_len);
sec_encrypt_use_count = 0;
}
RC4(&rc4_encrypt_key, length, data, data);
ssl_rc4_crypt(rc4_encrypt_key, data, data, length);
sec_encrypt_use_count++;
}
@ -274,15 +330,14 @@ sec_decrypt(uint8 * data, int length)
if (sec_decrypt_use_count == 4096)
{
sec_update(sec_decrypt_key, sec_decrypt_update_key);
RC4_set_key(&rc4_decrypt_key, rc4_key_len, sec_decrypt_key);
ssl_rc4_set_key(rc4_decrypt_key, sec_decrypt_key, rc4_key_len);
sec_decrypt_use_count = 0;
}
RC4(&rc4_decrypt_key, length, data, data);
ssl_rc4_crypt(rc4_decrypt_key, data, data, length);
sec_decrypt_use_count++;
}
static void
/*static void
reverse(uint8 * p, int len)
{
int i, j;
@ -294,18 +349,20 @@ reverse(uint8 * p, int len)
p[i] = p[j];
p[j] = temp;
}
}
}*/
/* Perform an RSA public key encryption operation */
static void
sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * modulus, uint8 * exponent)
{
sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint8 * modulus, uint8 * exponent)
{
ssl_mod_exp(out, 64, in, 32, modulus, 64, exponent, 4);
/*
BN_CTX *ctx;
BIGNUM mod, exp, x, y;
uint8 inr[SEC_MAX_MODULUS_SIZE];
uint8 inr[SEC_MODULUS_SIZE];
int outlen;
reverse(modulus, modulus_size);
reverse(modulus, SEC_MODULUS_SIZE);
reverse(exponent, SEC_EXPONENT_SIZE);
memcpy(inr, in, len);
reverse(inr, len);
@ -316,20 +373,20 @@ sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * m
BN_init(&x);
BN_init(&y);
BN_bin2bn(modulus, modulus_size, &mod);
BN_bin2bn(modulus, SEC_MODULUS_SIZE, &mod);
BN_bin2bn(exponent, SEC_EXPONENT_SIZE, &exp);
BN_bin2bn(inr, len, &x);
BN_mod_exp(&y, &x, &exp, &mod, ctx);
outlen = BN_bn2bin(&y, out);
reverse(out, outlen);
if (outlen < modulus_size)
memset(out + outlen, 0, modulus_size - outlen);
if (outlen < SEC_MODULUS_SIZE)
memset(out + outlen, 0, SEC_MODULUS_SIZE - outlen);
BN_free(&y);
BN_clear_free(&x);
BN_free(&exp);
BN_free(&mod);
BN_CTX_free(ctx);
BN_CTX_free(ctx);*/
}
/* Initialise secure transport packet */
@ -364,7 +421,7 @@ sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
flags &= ~SEC_ENCRYPT;
datalen = s->end - s->p - 8;
#if WITH_DEBUG
#ifdef WITH_DEBUG
DEBUG(("Sending encrypted packet:\n"));
hexdump(s->p + 8, datalen);
#endif
@ -389,14 +446,14 @@ sec_send(STREAM s, uint32 flags)
static void
sec_establish_key(void)
{
uint32 length = server_public_key_len + SEC_PADDING_SIZE;
uint32 length = SEC_MODULUS_SIZE + SEC_PADDING_SIZE;
uint32 flags = SEC_CLIENT_RANDOM;
STREAM s;
s = sec_init(flags, length+4);
s = sec_init(flags, 76);
out_uint32_le(s, length);
out_uint8p(s, sec_crypted_random, server_public_key_len);
out_uint8p(s, sec_crypted_random, SEC_MODULUS_SIZE);
out_uint8s(s, SEC_PADDING_SIZE);
s_mark_end(s);
@ -508,66 +565,28 @@ sec_parse_public_key(STREAM s, uint8 ** modulus, uint8 ** exponent)
}
in_uint32_le(s, modulus_len);
modulus_len -= SEC_PADDING_SIZE;
if ((modulus_len < 64) || (modulus_len > SEC_MAX_MODULUS_SIZE))
if (modulus_len != SEC_MODULUS_SIZE + SEC_PADDING_SIZE)
{
error("Bad server public key size (%u bits)\n", modulus_len*8);
error("modulus len 0x%x\n", modulus_len);
return False;
}
in_uint8s(s, 8); /* modulus_bits, unknown */
in_uint8p(s, *exponent, SEC_EXPONENT_SIZE);
in_uint8p(s, *modulus, modulus_len);
in_uint8p(s, *modulus, SEC_MODULUS_SIZE);
in_uint8s(s, SEC_PADDING_SIZE);
server_public_key_len = modulus_len;
return s_check(s);
}
static BOOL
sec_parse_x509_key(X509 * cert)
{
EVP_PKEY *epk = NULL;
/* By some reason, Microsoft sets the OID of the Public RSA key to
the oid for "MD5 with RSA Encryption" instead of "RSA Encryption"
Kudos to Richard Levitte for the following (. intiutive .)
lines of code that resets the OID and let's us extract the key. */
if (OBJ_obj2nid(cert->cert_info->key->algor->algorithm) == NID_md5WithRSAEncryption)
{
DEBUG_RDP5(("Re-setting algorithm type to RSA in server certificate\n"));
ASN1_OBJECT_free(cert->cert_info->key->algor->algorithm);
cert->cert_info->key->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
}
epk = X509_get_pubkey(cert);
if (NULL == epk)
{
error("Failed to extract public key from certificate\n");
return False;
}
server_public_key = RSAPublicKey_dup((RSA *) epk->pkey.ptr);
EVP_PKEY_free(epk);
server_public_key_len = RSA_size(server_public_key);
if ((server_public_key_len < 64) || (server_public_key_len > SEC_MAX_MODULUS_SIZE))
{
error("Bad server public key size (%u bits)\n", server_public_key_len*8);
return False;
}
return True;
}
/* Parse a crypto information structure */
static BOOL
sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
uint8 ** server_random, uint8 ** modulus, uint8 ** exponent)
{
uint32 crypt_level, random_len, rsa_info_len;
uint32 cacert_len, cert_len, flags;
X509 *cacert, *server_cert;
uint32 /*cacert_len, cert_len,*/ flags;
//X509 *cacert, *server_cert;
uint16 tag, length;
uint8 *next_tag, *end;
@ -628,7 +647,8 @@ sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
}
}
else
{
{
#if 0
uint32 certcount;
DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
@ -717,6 +737,7 @@ sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
}
X509_free(server_cert);
return True; /* There's some garbage here we don't care about */
#endif
}
return s_check_end(s);
}
@ -728,6 +749,7 @@ sec_process_crypt_info(STREAM s)
uint8 *server_random, *modulus, *exponent;
uint8 client_random[SEC_RANDOM_SIZE];
uint32 rc4_key_size;
uint8 inr[SEC_MODULUS_SIZE];
if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random, &modulus, &exponent))
{
@ -736,38 +758,38 @@ sec_process_crypt_info(STREAM s)
}
DEBUG(("Generating client random\n"));
generate_random(client_random);
/* Generate a client random, and hence determine encryption keys */
/* This is what the MS client do: */
memset(inr, 0, SEC_RANDOM_SIZE);
/* *ARIGL!* Plaintext attack, anyone?
I tried doing:
generate_random(inr);
..but that generates connection errors now and then (yes,
"now and then". Something like 0 to 3 attempts needed before a
successful connection. Nice. Not!
*/
generate_random(client_random);
if (NULL != server_public_key)
{ /* Which means we should use
RDP5-style encryption */
uint8 inr[SEC_MAX_MODULUS_SIZE];
uint32 padding_len = server_public_key_len - SEC_RANDOM_SIZE;
/* This is what the MS client do: */
memset(inr, 0, padding_len);
/* *ARIGL!* Plaintext attack, anyone?
I tried doing:
generate_random(inr);
..but that generates connection errors now and then (yes,
"now and then". Something like 0 to 3 attempts needed before a
successful connection. Nice. Not!
*/
memcpy(inr + padding_len, client_random, SEC_RANDOM_SIZE);
reverse(inr + padding_len, SEC_RANDOM_SIZE);
#if 0
memcpy(inr + SEC_RANDOM_SIZE, client_random, SEC_RANDOM_SIZE);
reverse(inr + SEC_RANDOM_SIZE, SEC_RANDOM_SIZE);
RSA_public_encrypt(server_public_key_len,
RSA_public_encrypt(SEC_MODULUS_SIZE,
inr, sec_crypted_random, server_public_key, RSA_NO_PADDING);
reverse(sec_crypted_random, server_public_key_len);
reverse(sec_crypted_random, SEC_MODULUS_SIZE);
RSA_free(server_public_key);
server_public_key = NULL;
server_public_key = NULL;
#endif
}
else
{ /* RDP4-style encryption */
sec_rsa_encrypt(sec_crypted_random,
client_random, SEC_RANDOM_SIZE, server_public_key_len, modulus, exponent);
client_random, SEC_RANDOM_SIZE, modulus, exponent);
}
sec_generate_keys(client_random, server_random, rc4_key_size);
}

File diff suppressed because it is too large Load Diff

@ -2,12 +2,12 @@
rdesktop: A Remote Desktop Protocol client.
Protocol services - TCP layer
Copyright (C) Matthew Chapman 1999-2005
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
(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
@ -18,6 +18,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _WIN32
#include <unistd.h> /* select read write close */
#include <sys/socket.h> /* socket connect setsockopt */
#include <sys/time.h> /* timeval */
@ -26,8 +27,23 @@
#include <netinet/tcp.h> /* TCP_NODELAY */
#include <arpa/inet.h> /* inet_addr */
#include <errno.h> /* errno */
#include "rdesktop.h"
#endif /* _WIN32 */
#include "rdesktop.h"
#ifdef _WIN32
#define socklen_t int
#define TCP_CLOSE(_sck) closesocket(_sck)
#define TCP_STRERROR "tcp error"
#define TCP_SLEEP(_n) Sleep(_n)
#define TCP_BLOCKS (WSAGetLastError() == WSAEWOULDBLOCK)
#else /* _WIN32 */
#define TCP_CLOSE(_sck) close(_sck)
#define TCP_STRERROR strerror(errno)
#define TCP_SLEEP(_n) sleep(_n)
#define TCP_BLOCKS (errno == EWOULDBLOCK)
#endif /* _WIN32 */
#ifndef INADDR_NONE
#define INADDR_NONE ((unsigned long) -1)
#endif
@ -64,10 +80,17 @@ tcp_send(STREAM s)
sent = send(sock, s->data + total, length - total, 0);
if (sent <= 0)
{
error("send: %s\n", strerror(errno));
return;
if (sent == -1 && TCP_BLOCKS)
{
TCP_SLEEP(0);
sent = 0;
}
else
{
error("send: %s\n", TCP_STRERROR);
return;
}
}
total += sent;
}
}
@ -114,8 +137,16 @@ tcp_recv(STREAM s, uint32 length)
rcvd = recv(sock, s->end, length, 0);
if (rcvd < 0)
{
error("recv: %s\n", strerror(errno));
return NULL;
if (rcvd == -1 && TCP_BLOCKS)
{
TCP_SLEEP(0);
rcvd = 0;
}
else
{
error("recv: %s\n", TCP_STRERROR);
return NULL;
}
}
else if (rcvd == 0)
{
@ -163,7 +194,7 @@ tcp_connect(char *server)
{
if (connect(sock, res->ai_addr, res->ai_addrlen) == 0)
break;
close(sock);
TCP_CLOSE(sock);
sock = -1;
}
res = res->ai_next;
@ -193,17 +224,17 @@ tcp_connect(char *server)
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
error("socket: %s\n", strerror(errno));
error("socket: %s\n", TCP_STRERROR);
return False;
}
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(g_tcp_port_rdp);
servaddr.sin_port = htons((uint16) g_tcp_port_rdp);
if (connect(sock, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) < 0)
{
error("connect: %s\n", strerror(errno));
close(sock);
error("connect: %s\n", TCP_STRERROR);
TCP_CLOSE(sock);
return False;
}
@ -224,7 +255,7 @@ tcp_connect(char *server)
void
tcp_disconnect(void)
{
close(sock);
TCP_CLOSE(sock);
}
char *

@ -32,16 +32,16 @@ typedef signed short sint16;
typedef unsigned int uint32;
typedef signed int sint32;
typedef void *HBITMAP;
typedef void *HGLYPH;
typedef void *HCOLOURMAP;
typedef void *HCURSOR;
typedef void *RD_HBITMAP;
typedef void *RD_HGLYPH;
typedef void *RD_HCOLOURMAP;
typedef void *RD_HCURSOR;
typedef struct _POINT
typedef struct _RD_POINT
{
sint16 x, y;
}
POINT;
RD_POINT;
typedef struct _COLOURENTRY
{
@ -95,7 +95,7 @@ typedef struct _FONTGLYPH
sint16 baseline;
uint16 width;
uint16 height;
HBITMAP pixmap;
RD_HBITMAP pixmap;
}
FONTGLYPH;
@ -155,7 +155,7 @@ typedef struct
uint16 wBitsPerSample;
uint16 cbSize;
uint8 cb[MAX_CBSIZE];
} WAVEFORMATEX;
} RD_WAVEFORMATEX;
typedef struct _RDPCOMP
{
@ -166,20 +166,20 @@ typedef struct _RDPCOMP
RDPCOMP;
/* RDPDR */
typedef uint32 NTSTATUS;
typedef uint32 NTHANDLE;
typedef uint32 RD_NTSTATUS;
typedef uint32 RD_NTHANDLE;
typedef struct _DEVICE_FNS
{
NTSTATUS(*create) (uint32 device, uint32 desired_access, uint32 share_mode,
RD_NTSTATUS(*create) (uint32 device, uint32 desired_access, uint32 share_mode,
uint32 create_disposition, uint32 flags_and_attributes, char *filename,
NTHANDLE * handle);
NTSTATUS(*close) (NTHANDLE handle);
NTSTATUS(*read) (NTHANDLE handle, uint8 * data, uint32 length, uint32 offset,
RD_NTHANDLE * handle);
RD_NTSTATUS(*close) (RD_NTHANDLE handle);
RD_NTSTATUS(*read) (RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset,
uint32 * result);
NTSTATUS(*write) (NTHANDLE handle, uint8 * data, uint32 length, uint32 offset,
RD_NTSTATUS(*write) (RD_NTHANDLE handle, uint8 * data, uint32 length, uint32 offset,
uint32 * result);
NTSTATUS(*device_control) (NTHANDLE handle, uint32 request, STREAM in, STREAM out);
RD_NTSTATUS(*device_control) (RD_NTHANDLE handle, uint32 request, STREAM in, STREAM out);
}
DEVICE_FNS;
@ -187,7 +187,7 @@ DEVICE_FNS;
typedef struct rdpdr_device_info
{
uint32 device_type;
NTHANDLE handle;
RD_NTHANDLE handle;
char name[8];
char *local_path;
void *pdevice_data;
@ -251,7 +251,8 @@ NOTIFY;
#ifndef PATH_MAX
#define PATH_MAX 256
#endif
#ifndef _WIN32
typedef struct fileinfo
{
uint32 device_id, flags_and_attributes, accessmask;
@ -263,6 +264,7 @@ typedef struct fileinfo
NOTIFY notify;
uint32 info_class;
}
FILEINFO;
FILEINFO;
#endif
typedef BOOL(*str_handle_lines_t) (const char *line, void *data);

File diff suppressed because it is too large Load Diff

@ -0,0 +1,83 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
main ui header
Copyright (C) Jay Sorg 2005-2006
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
(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, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* in uimain.c */
int
ui_main(void);
void
ui_invalidate(int x, int y, int cx, int cy);
int
ui_read_wire(void);
void
ui_mouse_move(int x, int y);
void
ui_mouse_button(int button, int x, int y, int down);
void
ui_key_down(int key, int ext);
void
ui_key_up(int key, int ext);
void
ui_set_modifier_state(int code);
#define SPLIT_COLOUR15(c, r, g, b) \
{ \
r = ((c >> 7) & 0xf8) | ((c >> 12) & 0x7); \
g = ((c >> 2) & 0xf8) | ((c >> 8) & 0x7); \
b = ((c << 3) & 0xf8) | ((c >> 2) & 0x7); \
}
#define SPLIT_COLOUR16(c, r, g, b) \
{ \
r = ((c >> 8) & 0xf8) | ((c >> 13) & 0x7); \
g = ((c >> 3) & 0xfc) | ((c >> 9) & 0x3); \
b = ((c << 3) & 0xf8) | ((c >> 2) & 0x7); \
}
#define SPLIT_COLOUR32(c, r, g, b) \
{ \
r = ((c >> 0) & 0xff); \
g = ((c >> 8) & 0xff); \
b = ((c >> 16) & 0xff); \
}
#define MAKE_COLOUR15(c, r, g, b) \
{ \
c = ( \
(((r & 0xff) >> 3) << 10) | \
(((g & 0xff) >> 3) << 5) | \
(((b & 0xff) >> 3) << 0) \
); \
}
#define MAKE_COLOUR32(c, r, g, b) \
{ \
c = ( \
((r & 0xff) << 16) | \
((g & 0xff) << 8) | \
((b & 0xff) << 0) \
); \
}
#undef UI_MAX
#define UI_MAX(a, b) (((a) > (b)) ? (a) : (b))
#undef UI_MIN
#define UI_MIN(a, b) (((a) < (b)) ? (a) : (b))

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save