modified porting-tools/rdesktop-core-tester/activex.cpp

Getting closer and closer and closer yet...

modified   porting-tools/rdesktop-core-tester/mstsclib_h.h
modified   porting-tools/rdesktop-core-tester/mstsclib_i.c
modified   porting-tools/rdesktop-core-tester/mstsclib_redist_h.h
modified   porting-tools/rdesktop-core-tester/mstsclib_redist_i.c
    Regenerated, no code changes

modified   porting-tools/rdesktop-core-tester/rdesktop-core-tester.cpp
modified   rdesktop/cache.c
modified   rdesktop/iso.c
modified   rdesktop/licence.c
modified   rdesktop/mcs.c
modified   rdesktop/orders.c
modified   rdesktop/parse.h
modified   rdesktop/proto.h
modified   rdesktop/pstcache.c
modified   rdesktop/rdesktop.h
modified   rdesktop/rdp.c
modified   rdesktop/rdp5.c
modified   rdesktop/secure.c
modified   rdesktop/tcp.c
    Trimmed down rdesktop-core library to the maximum extent possible
    Handle errors gracefully
    Use actual Unicode strings
    Fixed most warnings
    Added hooks for events happening inside the protocol's main loop

modified   porting-tools/rdesktop-core-tester/stdafx.cpp
    Clean-up

svn path=/trunk/; revision=23612
This commit is contained in:
Michele Cicciotti
2006-08-19 18:40:53 +00:00
parent 10f76ae52b
commit efcb331e18
20 changed files with 1358 additions and 895 deletions
File diff suppressed because it is too large Load Diff
@@ -4,10 +4,10 @@
/* File created by MIDL compiler version 7.00.0493 */
/* at Sat Aug 12 22:21:54 2006
/* at Sun Aug 13 16:46:06 2006
*/
/* Compiler settings for .\mstsclib.idl:
Oicf, W2, Zp8, env=Win32 (32b run)
Oicf, W1, Zp8, env=Win32 (32b run)
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
@@ -6,10 +6,10 @@
/* File created by MIDL compiler version 7.00.0493 */
/* at Sat Aug 12 22:21:54 2006
/* at Sun Aug 13 16:46:06 2006
*/
/* Compiler settings for .\mstsclib.idl:
Oicf, W2, Zp8, env=Win32 (32b run)
Oicf, W1, Zp8, env=Win32 (32b run)
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
@@ -4,10 +4,10 @@
/* File created by MIDL compiler version 7.00.0493 */
/* at Sat Aug 12 22:21:53 2006
/* at Sun Aug 13 16:46:05 2006
*/
/* Compiler settings for .\mstsclib_redist.idl:
Oicf, W2, Zp8, env=Win32 (32b run)
Oicf, W1, Zp8, env=Win32 (32b run)
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
@@ -6,10 +6,10 @@
/* File created by MIDL compiler version 7.00.0493 */
/* at Sat Aug 12 22:21:53 2006
/* at Sun Aug 13 16:46:05 2006
*/
/* Compiler settings for .\mstsclib_redist.idl:
Oicf, W2, Zp8, env=Win32 (32b run)
Oicf, W1, Zp8, env=Win32 (32b run)
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
VC __declspec() decoration level:
@@ -7,7 +7,7 @@
template<class T, class U> T aligndown(const T& X, const U& align)
{
return X & ~(T(align) - 1);
return X & ~(T(align) - 1);
}
template<class T, class U> T alignup(const T& X, const U& align)
@@ -93,56 +93,6 @@ extern "C"
va_end(ap);
}
/* malloc; exit if out of memory */
void *
xmalloc(size_t size)
{
void *mem = malloc(size);
if (mem == NULL)
{
error("xmalloc %d\n", size);
exit(1);
}
return mem;
}
/* strdup */
char *
xstrdup(const char *s)
{
char *mem = _strdup(s);
if (mem == NULL)
{
perror("strdup");
exit(1);
}
return mem;
}
/* realloc; exit if out of memory */
void *
xrealloc(void *oldmem, size_t size)
{
void *mem;
if (size < 1)
size = 1;
mem = realloc(oldmem, size);
if (mem == NULL)
{
error("xrealloc %d\n", size);
exit(1);
}
return mem;
}
/* free */
void
xfree(void *mem)
{
free(mem);
}
/* Create the bitmap cache directory */
BOOL
rd_pstcache_mkdir(void)
@@ -231,78 +181,12 @@ extern "C"
int
load_licence(RDPCLIENT * This, unsigned char **data)
{
char *home, *path;
struct stat st;
int fd, length;
home = getenv("HOME");
if (home == NULL)
return -1;
path = (char *) xmalloc(strlen(home) + strlen(This->hostname) + sizeof("/.rdesktop/licence."));
sprintf(path, "%s/.rdesktop/licence.%s", home, This->hostname);
fd = _open(path, O_RDONLY);
if (fd == -1)
return -1;
if (fstat(fd, &st))
return -1;
*data = (uint8 *) xmalloc(st.st_size);
length = _read(fd, *data, st.st_size);
_close(fd);
xfree(path);
return length;
return -1;
}
void
save_licence(RDPCLIENT * This, unsigned char *data, int length)
{
char *home, *path, *tmppath;
int fd;
home = getenv("HOME");
if (home == NULL)
return;
path = (char *) xmalloc(strlen(home) + strlen(This->hostname) + sizeof("/.rdesktop/licence."));
sprintf(path, "%s/.rdesktop", home);
if ((_mkdir(path) == -1) && errno != EEXIST)
{
perror(path);
return;
}
/* write licence to licence.hostname.new, then atomically rename to licence.hostname */
sprintf(path, "%s/.rdesktop/licence.%s", home, This->hostname);
tmppath = (char *) xmalloc(strlen(path) + sizeof(".new"));
strcpy(tmppath, path);
strcat(tmppath, ".new");
fd = _open(tmppath, O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (fd == -1)
{
perror(tmppath);
return;
}
if (_write(fd, data, length) != length)
{
perror(tmppath);
_unlink(tmppath);
}
else if (rename(tmppath, path) == -1)
{
perror(path);
_unlink(tmppath);
}
_close(fd);
xfree(tmppath);
xfree(path);
}
/* ==== END POOP ==== */
@@ -381,7 +265,10 @@ extern "C"
int datasize = tostride * height;
uint8 * dibits = new(xmalloc(datasize)) uint8;
uint8 * dibits = new(malloc(datasize)) uint8;
if(dibits == NULL)
return NULL;
const uint8 * src = data;
uint8 * dest = dibits;
@@ -412,11 +299,13 @@ extern "C"
void
ui_resize_window(RDPCLIENT * This)
{
// EVENT: OnRemoteDesktopSizeChange
// TODO: resize buffer
SetWindowPos(hwnd, NULL, 0, 0, This->width, This->height, SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOMOVE);
}
int
ui_select(RDPCLIENT * This, int rdp_socket)
ui_select(RDPCLIENT * This, SOCKET rdp_socket)
{
return 1; // TODO: return 0 for user quit. Or just kill this silly function
}
@@ -451,11 +340,14 @@ extern "C"
{
uint8 * databuf = NULL;
uint8 * databits = win32_convert_scanlines(width, height, 1, 1, 2, data, &databuf);
if(databits == NULL)
return NULL;
HBITMAP hbm = CreateBitmap(width, height, 1, 1, databits);
if(databuf)
xfree(databuf);
free(databuf);
const uint8 * p = data;
int stride = alignup(alignup(width, 8) / 8, 1);
@@ -497,8 +389,18 @@ extern "C"
uint8 * xorbuf = NULL;
uint8 * andbits = win32_convert_scanlines(width, - height, 1, 2, 4, andmask, &andbuf);
if(andbits == NULL)
return NULL;
uint8 * xorbits = win32_convert_scanlines(width, height, 24, 2, 4, xormask, &xorbuf);
if(xorbits == NULL)
{
free(andbits);
return NULL;
}
HBITMAP hbmMask = CreateBitmap(width, height, 1, 1, andbits);
HBITMAP hbmColor = win32_create_dib(width, height, 24, xorbits);
@@ -508,17 +410,17 @@ extern "C"
iconinfo.yHotspot = y;
iconinfo.hbmMask = hbmMask;
iconinfo.hbmColor = hbmColor;
HICON icon = CreateIconIndirect(&iconinfo);
if(icon == NULL)
error("CreateIconIndirect %dx%d failed\n", width, height);
if(andbuf)
xfree(andbuf);
free(andbuf);
if(xorbuf)
xfree(xorbuf);
free(xorbuf);
DeleteObject(hbmMask);
DeleteObject(hbmColor);
@@ -763,7 +665,7 @@ extern "C"
SetBkColor(hdcBuffer, bgcolour);
SetTextColor(hdcBuffer, fgcolour);
SetBrushOrgEx(hdcBuffer, brush->xorigin, brush->yorigin, NULL);
SelectObject(hdcBuffer, hbr);
SelectObject(hdcBuffer, hbr);
PatBlt(hdcBuffer, x, y, cx, cy, MAKELONG(0, opcode));
@@ -841,7 +743,7 @@ extern "C"
DeleteObject(hpen);
RECT rcDamage;
if(startx < endx)
{
rcDamage.left = startx;
@@ -1058,7 +960,7 @@ extern "C"
SelectObject(hdcBuffer, holdpen);
SelectObject(hdcBuffer, holdbrush);
DeleteObject(hbr);
if(boxcx > 1)
@@ -1179,6 +1081,15 @@ extern "C"
{
RestoreDC(hdcBuffer, nSavedDC);
}
int event_pubkey(RDPCLIENT * This, const unsigned char * key, size_t key_size)
{
return True;
}
void event_logon(RDPCLIENT * This)
{
}
};
static
@@ -1268,7 +1179,7 @@ mstsc_WndProc(HWND hwnd, UINT uMsg, WPARAM wparam, LPARAM lparam)
/* Keyboard stuff */
case WM_SYSKEYDOWN:
case WM_KEYDOWN:
case WM_KEYDOWN:
rdp_send_input(This, GetMessageTime(), RDP_INPUT_SCANCODE, RDP_KEYPRESS | (lparam & 0x1000000 ? KBD_FLAG_EXT : 0), LOBYTE(HIWORD(lparam)), 0);
break;
@@ -1290,7 +1201,7 @@ mstsc_WndProc(HWND hwnd, UINT uMsg, WPARAM wparam, LPARAM lparam)
// Movement
case WM_MOUSEMOVE:
if(This->sendmotion || wparam & (MK_LBUTTON | MK_RBUTTON | MK_MBUTTON | MK_XBUTTON1 | MK_XBUTTON2))
//if(This->sendmotion || wparam & (MK_LBUTTON | MK_RBUTTON | MK_MBUTTON | MK_XBUTTON1 | MK_XBUTTON2))
rdp_send_input(This, GetMessageTime(), RDP_INPUT_MOUSE, MOUSE_FLAG_MOVE, LOWORD(lparam), HIWORD(lparam));
break;
@@ -1352,14 +1263,13 @@ mstsc_ProtocolIOThread
{
RDPCLIENT * This = static_cast<RDPCLIENT *>(lpArgument);
strcpy(This->username, "Administrator");
DWORD dw = sizeof(This->hostname);
GetComputerNameA(This->hostname, &dw);
WCHAR hostname[MAX_COMPUTERNAME_LENGTH + 1];
DWORD dw = ARRAYSIZE(hostname);
GetComputerNameW(hostname, &dw);
uint32 flags = RDP_LOGON_NORMAL | RDP_LOGON_COMPRESSION | RDP_LOGON_COMPRESSION2;
rdp_connect(This, "10.0.0.3", flags, "", "", "", "");
rdp_connect(This, "10.0.0.3", flags, L"Administrator", L"", L"", L"", L"", hostname, "");
//rdp_connect(This, "192.168.7.232", flags, "", "", "", "");
hdcBuffer = CreateCompatibleDC(NULL);
@@ -1390,6 +1300,8 @@ mstsc_ProtocolIOThread
uint32 ext_disc_reason;
rdp_main_loop(This, &deactivated, &ext_disc_reason);
// TODO: handle redirection
// EVENT: OnDisconnect
SendMessage(hwnd, WM_CLOSE, 0, 0);
@@ -1450,6 +1362,7 @@ VirtualChannelInit
memcpy(This->channel_defs + This->num_channels, pChannel, sizeof(*pChannel) * channelCount);
#if 0 // TODO
for(INT i = 0; i < channelCount; ++ i)
{
pChannel[i].options |= CHANNEL_OPTION_INITIALIZED;
@@ -1459,6 +1372,7 @@ VirtualChannelInit
This->channel_data[j].pChannelInitEventProc = pChannelInitEventProc;
This->channel_data[j].pChannelOpenEventProc = NULL;
}
#endif
This->num_channels += channelCount;
@@ -1491,6 +1405,7 @@ VirtualChannelOpen
RDPCLIENT * This = (RDPCLIENT *)pInitHandle;
#if 0 // TODO
for(unsigned i = 0; i < This->num_channels; ++ i)
{
if(strcmp(pChannelName, This->channel_defs[i].name) == 0)
@@ -1507,6 +1422,7 @@ VirtualChannelOpen
break;
}
}
#endif
return CHANNEL_RC_OK;
}
@@ -1562,7 +1478,7 @@ int wmain()
This->height = 600;
This->server_depth = 24;
This->bitmap_compression = True;
This->sendmotion = True;
//This->sendmotion = True;
This->bitmap_cache = True;
This->bitmap_cache_persist_enable = False;
This->bitmap_cache_precache = True;
@@ -1570,14 +1486,14 @@ int wmain()
This->packet_encryption = True;
This->desktop_save = True;
This->polygon_ellipse_orders = False; // = True;
This->fullscreen = False;
This->grab_keyboard = True;
This->hide_decorations = False;
//This->fullscreen = False;
//This->grab_keyboard = True;
//This->hide_decorations = False;
This->use_rdp5 = True;
This->rdpclip = True;
//This->rdpclip = True;
This->console_session = False;
This->numlock_sync = False;
This->seamless_rdp = False;
//This->numlock_sync = False;
//This->seamless_rdp = False;
This->rdp5_performanceflags = RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;
This->tcp_port_rdp = TCP_PORT_RDP;
@@ -1589,6 +1505,8 @@ int wmain()
This->cache.bmpcache_mru[1] = NOT_SET;
This->cache.bmpcache_mru[2] = NOT_SET;
This->rdp.current_status = 1;
hcursor = NULL;
WNDCLASS wc;
@@ -1,8 +1,3 @@
// stdafx.cpp : source file that includes just the standard includes
// rdesktop-core-tester.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file
// EOF
@@ -316,11 +316,15 @@ void
cache_put_text(RDPCLIENT * This, uint8 cache_id, void *data, int length)
{
DATABLOB *text;
void * p = malloc(length);
if(p == NULL)
return;
text = &This->cache.textcache[cache_id];
if (text->data != NULL)
xfree(text->data);
text->data = xmalloc(length);
free(text->data);
text->data = p;
text->size = length;
memcpy(text->data, data, length);
}
@@ -21,13 +21,16 @@
#include "rdesktop.h"
/* Send a self-contained ISO PDU */
static void
static BOOL
iso_send_msg(RDPCLIENT * This, uint8 code)
{
STREAM s;
s = tcp_init(This, 11);
if(s == NULL)
return False;
out_uint8(s, 3); /* version */
out_uint8(s, 0); /* reserved */
out_uint16_be(s, 11); /* length */
@@ -39,17 +42,21 @@ iso_send_msg(RDPCLIENT * This, uint8 code)
out_uint8(s, 0); /* class */
s_mark_end(s);
tcp_send(This, s);
return tcp_send(This, s);
}
static void
iso_send_connection_request(RDPCLIENT * This, char *username)
static BOOL
iso_send_connection_request(RDPCLIENT * This, char *cookie)
{
STREAM s;
int length = 30 + strlen(username);
int cookielen = (int)strlen(cookie);
int length = 11 + cookielen;
s = tcp_init(This, length);
if(s == NULL)
return False;
out_uint8(s, 3); /* version */
out_uint8(s, 0); /* reserved */
out_uint16_be(s, length); /* length */
@@ -60,14 +67,10 @@ iso_send_connection_request(RDPCLIENT * This, char *username)
out_uint16(s, 0); /* src_ref */
out_uint8(s, 0); /* class */
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_uint8p(s, cookie, cookielen);
s_mark_end(s);
tcp_send(This, s);
return tcp_send(This, s);
}
/* Receive a message on the ISO layer, return code */
@@ -121,19 +124,23 @@ iso_init(RDPCLIENT * This, int length)
STREAM s;
s = tcp_init(This, length + 7);
if(s == NULL)
return NULL;
s_push_layer(s, iso_hdr, 7);
return s;
}
/* Send an ISO data PDU */
void
BOOL
iso_send(RDPCLIENT * This, STREAM s)
{
uint16 length;
s_pop_layer(s, iso_hdr);
length = s->end - s->p;
length = (uint16)(s->end - s->p);
out_uint8(s, 3); /* version */
out_uint8(s, 0); /* reserved */
@@ -143,7 +150,7 @@ iso_send(RDPCLIENT * This, STREAM s)
out_uint8(s, ISO_PDU_DT); /* code */
out_uint8(s, 0x80); /* eot */
tcp_send(This, s);
return tcp_send(This, s);
}
/* Receive ISO transport data packet */
@@ -169,14 +176,15 @@ iso_recv(RDPCLIENT * This, uint8 * rdpver)
/* Establish a connection up to the ISO layer */
BOOL
iso_connect(RDPCLIENT * This, char *server, char *username)
iso_connect(RDPCLIENT * This, char *server, char *cookie)
{
uint8 code = 0;
if (!tcp_connect(This, server))
return False;
iso_send_connection_request(This, username);
if (!iso_send_connection_request(This, cookie))
return False;
if (iso_recv_msg(This, &code, NULL) == NULL)
return False;
@@ -193,14 +201,15 @@ iso_connect(RDPCLIENT * This, char *server, char *username)
/* Establish a reconnection up to the ISO layer */
BOOL
iso_reconnect(RDPCLIENT * This, char *server)
iso_reconnect(RDPCLIENT * This, char *server, char *cookie)
{
uint8 code = 0;
if (!tcp_connect(This, server))
return False;
iso_send_msg(This, ISO_PDU_CR);
if (!iso_send_connection_request(This, cookie)) // BUGBUG should we really pass the cookie here?
return False;
if (iso_recv_msg(This, &code, NULL) == NULL)
return False;
@@ -216,11 +225,13 @@ iso_reconnect(RDPCLIENT * This, char *server)
}
/* Disconnect from the ISO layer */
void
BOOL
iso_disconnect(RDPCLIENT * This)
{
iso_send_msg(This, ISO_PDU_DR);
tcp_disconnect(This);
if(!iso_send_msg(This, ISO_PDU_DR))
return False;
return tcp_disconnect(This);
}
/* reset the state to support reconnecting */
@@ -43,11 +43,11 @@ static void
licence_generate_hwid(RDPCLIENT * This, uint8 * hwid)
{
buf_out_uint32(hwid, 2);
strncpy((char *) (hwid + 4), This->hostname, LICENCE_HWID_SIZE - 4);
strncpy((char *) (hwid + 4), This->licence_hostname, LICENCE_HWID_SIZE - 4);
}
/* Present an existing licence to the server */
static void
static BOOL
licence_present(RDPCLIENT * This, uint8 * client_random, uint8 * rsa_data,
uint8 * licence_data, int licence_size, uint8 * hwid, uint8 * signature)
{
@@ -59,6 +59,9 @@ licence_present(RDPCLIENT * This, uint8 * client_random, uint8 * rsa_data,
s = sec_init(This, sec_flags, length + 4);
if(s == NULL)
return False;
out_uint8(s, LICENCE_TAG_PRESENT);
out_uint8(s, 2); /* version */
out_uint16_le(s, length);
@@ -84,21 +87,24 @@ licence_present(RDPCLIENT * This, uint8 * client_random, uint8 * rsa_data,
out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE);
s_mark_end(s);
sec_send(This, s, sec_flags);
return sec_send(This, s, sec_flags);
}
/* Send a licence request packet */
static void
static BOOL
licence_send_request(RDPCLIENT * This, 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 userlen = (uint16)strlen(user) + 1;
uint16 hostlen = (uint16)strlen(host) + 1;
uint16 length = 128 + userlen + hostlen;
STREAM s;
s = sec_init(This, sec_flags, length + 2);
if(s == NULL)
return False;
out_uint8(s, LICENCE_TAG_REQUEST);
out_uint8(s, 2); /* version */
out_uint16_le(s, length);
@@ -122,11 +128,11 @@ licence_send_request(RDPCLIENT * This, uint8 * client_random, uint8 * rsa_data,
out_uint8p(s, host, hostlen);
s_mark_end(s);
sec_send(This, s, sec_flags);
return sec_send(This, s, sec_flags);
}
/* Process a licence demand packet */
static void
static BOOL
licence_process_demand(RDPCLIENT * This, STREAM s)
{
uint8 null_data[SEC_MODULUS_SIZE];
@@ -156,16 +162,18 @@ licence_process_demand(RDPCLIENT * This, STREAM s)
RC4_set_key(&crypt_key, 16, This->licence.key);
RC4(&crypt_key, sizeof(hwid), hwid, hwid);
licence_present(This, null_data, null_data, licence_data, licence_size, hwid, signature);
xfree(licence_data);
return;
if(!licence_present(This, null_data, null_data, licence_data, licence_size, hwid, signature))
return False;
free(licence_data);
return True;
}
licence_send_request(This, null_data, null_data, This->username, This->hostname);
return licence_send_request(This, null_data, null_data, This->licence_username, This->licence_hostname);
}
/* Send an authentication response packet */
static void
static BOOL
licence_send_authresp(RDPCLIENT * This, uint8 * token, uint8 * crypt_hwid, uint8 * signature)
{
uint32 sec_flags = SEC_LICENCE_NEG;
@@ -174,6 +182,9 @@ licence_send_authresp(RDPCLIENT * This, uint8 * token, uint8 * crypt_hwid, uint8
s = sec_init(This, sec_flags, length + 2);
if(s == NULL)
return False;
out_uint8(s, LICENCE_TAG_AUTHRESP);
out_uint8(s, 2); /* version */
out_uint16_le(s, length);
@@ -189,7 +200,7 @@ licence_send_authresp(RDPCLIENT * This, uint8 * token, uint8 * crypt_hwid, uint8
out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE);
s_mark_end(s);
sec_send(This, s, sec_flags);
return sec_send(This, s, sec_flags);
}
/* Parse an authentication request packet */
@@ -113,15 +113,18 @@ mcs_parse_domain_params(STREAM s)
}
/* Send an MCS_CONNECT_INITIAL message (ASN.1 BER) */
static void
static BOOL
mcs_send_connect_initial(RDPCLIENT * This, STREAM mcs_data)
{
int datalen = mcs_data->end - mcs_data->data;
int datalen = (uint16)(mcs_data->end - mcs_data->data);
int length = 9 + 3 * 34 + 4 + datalen;
STREAM s;
s = iso_init(This, length + 5);
if(s == NULL)
return False;
ber_out_header(s, MCS_CONNECT_INITIAL, length);
ber_out_header(s, BER_TAG_OCTET_STRING, 1); /* calling domain */
out_uint8(s, 1);
@@ -139,7 +142,7 @@ mcs_send_connect_initial(RDPCLIENT * This, STREAM mcs_data)
out_uint8p(s, mcs_data->data, datalen);
s_mark_end(s);
iso_send(This, s);
return iso_send(This, s);
}
/* Expect a MCS_CONNECT_RESPONSE message (ASN.1 BER) */
@@ -187,33 +190,39 @@ mcs_recv_connect_response(RDPCLIENT * This, STREAM mcs_data)
}
/* Send an EDrq message (ASN.1 PER) */
static void
static BOOL
mcs_send_edrq(RDPCLIENT * This)
{
STREAM s;
s = iso_init(This, 5);
if(s == NULL)
return False;
out_uint8(s, (MCS_EDRQ << 2));
out_uint16_be(s, 1); /* height */
out_uint16_be(s, 1); /* interval */
s_mark_end(s);
iso_send(This, s);
return iso_send(This, s);
}
/* Send an AUrq message (ASN.1 PER) */
static void
static BOOL
mcs_send_aurq(RDPCLIENT * This)
{
STREAM s;
s = iso_init(This, 1);
if(s == NULL)
return False;
out_uint8(s, (MCS_AURQ << 2));
s_mark_end(s);
iso_send(This, s);
return iso_send(This, s);
}
/* Expect a AUcf message (ASN.1 PER) */
@@ -248,7 +257,7 @@ mcs_recv_aucf(RDPCLIENT * This, uint16 * mcs_userid)
}
/* Send a CJrq message (ASN.1 PER) */
static void
static BOOL
mcs_send_cjrq(RDPCLIENT * This, uint16 chanid)
{
STREAM s;
@@ -257,12 +266,15 @@ mcs_send_cjrq(RDPCLIENT * This, uint16 chanid)
s = iso_init(This, 5);
if(s == NULL)
return False;
out_uint8(s, (MCS_CJRQ << 2));
out_uint16_be(s, This->mcs_userid);
out_uint16_be(s, chanid);
s_mark_end(s);
iso_send(This, s);
return iso_send(This, s);
}
/* Expect a CJcf message (ASN.1 PER) */
@@ -304,19 +316,23 @@ mcs_init(RDPCLIENT * This, int length)
STREAM s;
s = iso_init(This, length + 8);
if(s == NULL)
return NULL;
s_push_layer(s, mcs_hdr, 8);
return s;
}
/* Send an MCS transport data packet to a specific channel */
void
BOOL
mcs_send_to_channel(RDPCLIENT * This, STREAM s, uint16 channel)
{
uint16 length;
s_pop_layer(s, mcs_hdr);
length = s->end - s->p - 8;
length = (uint16)(s->end - s->p - 8);
length |= 0x8000;
out_uint8(s, (MCS_SDRQ << 2));
@@ -325,14 +341,14 @@ mcs_send_to_channel(RDPCLIENT * This, STREAM s, uint16 channel)
out_uint8(s, 0x70); /* flags */
out_uint16_be(s, length);
iso_send(This, s);
return iso_send(This, s);
}
/* Send an MCS transport data packet to the global channel */
void
BOOL
mcs_send(RDPCLIENT * This, STREAM s)
{
mcs_send_to_channel(This, s, MCS_GLOBAL_CHANNEL);
return mcs_send_to_channel(This, s, MCS_GLOBAL_CHANNEL);
}
/* Receive an MCS transport data packet */
@@ -369,77 +385,67 @@ mcs_recv(RDPCLIENT * This, uint16 * channel, uint8 * rdpver)
/* Establish a connection up to the MCS layer */
BOOL
mcs_connect(RDPCLIENT * This, char *server, STREAM mcs_data, char *username)
mcs_connect(RDPCLIENT * This, char *server, char * cookie, STREAM mcs_data)
{
unsigned int i;
if (!iso_connect(This, server, username))
if (!iso_connect(This, server, cookie))
return False;
mcs_send_connect_initial(This, mcs_data);
if (!mcs_recv_connect_response(This, mcs_data))
if (!mcs_send_connect_initial(This, mcs_data) || !mcs_recv_connect_response(This, mcs_data))
goto error;
mcs_send_edrq(This);
if (!mcs_send_edrq(This) || !mcs_send_aurq(This))
goto error;
mcs_send_aurq(This);
if (!mcs_recv_aucf(This, &This->mcs_userid))
goto error;
mcs_send_cjrq(This, This->mcs_userid + MCS_USERCHANNEL_BASE);
if (!mcs_recv_cjcf(This))
if (!mcs_send_cjrq(This, This->mcs_userid + MCS_USERCHANNEL_BASE) || !mcs_recv_cjcf(This))
goto error;
mcs_send_cjrq(This, MCS_GLOBAL_CHANNEL);
if (!mcs_recv_cjcf(This))
if (!mcs_send_cjrq(This, MCS_GLOBAL_CHANNEL) || !mcs_recv_cjcf(This))
goto error;
for (i = 0; i < This->num_channels; i++)
{
mcs_send_cjrq(This, MCS_GLOBAL_CHANNEL + 1 + i);
if (!mcs_recv_cjcf(This))
if (!mcs_send_cjrq(This, MCS_GLOBAL_CHANNEL + 1 + i) || !mcs_recv_cjcf(This))
goto error;
}
return True;
error:
error:
iso_disconnect(This);
return False;
}
/* Establish a connection up to the MCS layer */
BOOL
mcs_reconnect(RDPCLIENT * This, char *server, STREAM mcs_data)
mcs_reconnect(RDPCLIENT * This, char *server, char *cookie, STREAM mcs_data)
{
unsigned int i;
if (!iso_reconnect(This, server))
if (!iso_reconnect(This, server, cookie))
return False;
mcs_send_connect_initial(This, mcs_data);
if (!mcs_recv_connect_response(This, mcs_data))
if (!mcs_send_connect_initial(This, mcs_data) || !mcs_recv_connect_response(This, mcs_data))
goto error;
mcs_send_edrq(This);
if (!mcs_send_edrq(This) || !mcs_send_aurq(This))
goto error;
mcs_send_aurq(This);
if (!mcs_recv_aucf(This, &This->mcs_userid))
goto error;
mcs_send_cjrq(This, This->mcs_userid + MCS_USERCHANNEL_BASE);
if (!mcs_recv_cjcf(This))
if (!mcs_send_cjrq(This, This->mcs_userid + MCS_USERCHANNEL_BASE) || !mcs_recv_cjcf(This))
goto error;
mcs_send_cjrq(This, MCS_GLOBAL_CHANNEL);
if (!mcs_recv_cjcf(This))
if (!mcs_send_cjrq(This, MCS_GLOBAL_CHANNEL) || !mcs_recv_cjcf(This))
goto error;
for (i = 0; i < This->num_channels; i++)
{
mcs_send_cjrq(This, MCS_GLOBAL_CHANNEL + 1 + i);
if (!mcs_recv_cjcf(This))
if (!mcs_send_cjrq(This, MCS_GLOBAL_CHANNEL + 1 + i) || !mcs_recv_cjcf(This))
goto error;
}
return True;
@@ -545,7 +545,11 @@ process_polygon(RDPCLIENT * This, STREAM s, POLYGON_ORDER * os, uint32 present,
return;
}
points = (POINT *) xmalloc((os->npoints + 1) * sizeof(POINT));
points = (POINT *) malloc((os->npoints + 1) * sizeof(POINT));
if(points == NULL)
return;
memset(points, 0, (os->npoints + 1) * sizeof(POINT));
points[0].x = os->x;
@@ -578,7 +582,7 @@ process_polygon(RDPCLIENT * This, STREAM s, POLYGON_ORDER * os, uint32 present,
else
error("polygon parse error\n");
xfree(points);
free(points);
}
/* Process a polygon2 order */
@@ -635,7 +639,11 @@ process_polygon2(RDPCLIENT * This, STREAM s, POLYGON2_ORDER * os, uint32 present
return;
}
points = (POINT *) xmalloc((os->npoints + 1) * sizeof(POINT));
points = (POINT *) malloc((os->npoints + 1) * sizeof(POINT));
if(points == NULL)
return;
memset(points, 0, (os->npoints + 1) * sizeof(POINT));
points[0].x = os->x;
@@ -668,7 +676,7 @@ process_polygon2(RDPCLIENT * This, STREAM s, POLYGON2_ORDER * os, uint32 present
else
error("polygon2 parse error\n");
xfree(points);
free(points);
}
/* Process a polyline order */
@@ -717,7 +725,11 @@ process_polyline(RDPCLIENT * This, STREAM s, POLYLINE_ORDER * os, uint32 present
return;
}
points = (POINT *) xmalloc((os->lines + 1) * sizeof(POINT));
points = (POINT *) malloc((os->lines + 1) * sizeof(POINT));
if(points == NULL)
return;
memset(points, 0, (os->lines + 1) * sizeof(POINT));
points[0].x = os->x;
@@ -750,7 +762,7 @@ process_polyline(RDPCLIENT * This, STREAM s, POLYLINE_ORDER * os, uint32 present
else
error("polyline parse error\n");
xfree(points);
free(points);
}
/* Process an ellipse order */
@@ -926,8 +938,7 @@ process_raw_bmpcache(RDPCLIENT * This, STREAM s)
HBITMAP bitmap;
uint16 cache_idx, bufsize;
uint8 cache_id, width, height, bpp, Bpp;
uint8 *data, *inverted;
int y;
uint8 *data;
in_uint8(s, cache_id);
in_uint8s(s, 1); /* pad */
@@ -1000,7 +1011,10 @@ process_bmpcache(RDPCLIENT * This, 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));
bmpdata = (uint8 *) xmalloc(width * height * Bpp);
bmpdata = (uint8 *) malloc(width * height * Bpp);
if(bmpdata == NULL)
return;
if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
{
@@ -1012,7 +1026,7 @@ process_bmpcache(RDPCLIENT * This, STREAM s)
DEBUG(("Failed to decompress bitmap data\n"));
}
xfree(bmpdata);
free(bmpdata);
}
/* Process a bitmap cache v2 order */
@@ -1020,7 +1034,6 @@ static void
process_bmpcache2(RDPCLIENT * This, STREAM s, uint16 flags, BOOL compressed)
{
HBITMAP bitmap;
int y;
uint8 cache_id, cache_idx_low, width, height, Bpp;
uint16 cache_idx, bufsize;
uint8 *data, *bmpdata, *bitmap_id;
@@ -1062,12 +1075,15 @@ process_bmpcache2(RDPCLIENT * This, STREAM s, uint16 flags, BOOL compressed)
if (compressed)
{
bmpdata = (uint8 *) xmalloc(width * height * Bpp);
bmpdata = (uint8 *) malloc(width * height * Bpp);
if(bmpdata == NULL)
return;
if (!bitmap_decompress(bmpdata, width, height, data, bufsize, Bpp))
{
DEBUG(("Failed to decompress bitmap data\n"));
xfree(bmpdata);
free(bmpdata);
return;
}
}
@@ -1097,7 +1113,7 @@ process_bmpcache2(RDPCLIENT * This, STREAM s, uint16 flags, BOOL compressed)
}
if (compressed)
xfree(bmpdata);
free(bmpdata);
}
/* Process a colourmap cache order */
@@ -1113,7 +1129,13 @@ process_colcache(RDPCLIENT * This, STREAM s)
in_uint8(s, cache_id);
in_uint16_le(s, map.ncolours);
map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
map.colours = (COLOURENTRY *) malloc(sizeof(COLOURENTRY) * map.ncolours);
if(map.colours == NULL)
{
in_uint8s(s, map.ncolours * 4);
return;
}
for (i = 0; i < map.ncolours; i++)
{
@@ -1131,7 +1153,7 @@ process_colcache(RDPCLIENT * This, STREAM s)
if (cache_id)
ui_set_colourmap(This, hmap);
xfree(map.colours);
free(map.colours);
}
/* Process a font cache order */
@@ -72,8 +72,8 @@ typedef struct stream
#else
#define in_uint16_be(s,v) { v = *((s)->p++); next_be(s,v); }
#define in_uint32_be(s,v) { in_uint16_be(s,v); next_be(s,v); next_be(s,v); }
#define out_uint16_be(s,v) { *((s)->p++) = ((v) >> 8) & 0xff; *((s)->p++) = (v) & 0xff; }
#define out_uint32_be(s,v) { out_uint16_be(s, ((v) >> 16) & 0xffff); out_uint16_be(s, (v) & 0xffff); }
#define out_uint16_be(s,v) { *((s)->p++) = (uint8)((v) >> 8) & 0xff; *((s)->p++) = (uint8)((v) & 0xff); }
#define out_uint32_be(s,v) { out_uint16_be(s, (uint16)(((v) >> 16) & 0xffff)); out_uint16_be(s, (uint16)((v) & 0xffff)); }
#endif
#ifndef B_ENDIAN_PREFERRED
@@ -73,21 +73,21 @@ int get_current_workarea(RDPCLIENT * This, uint32 * x, uint32 * y, uint32 * widt
void ewmh_init(RDPCLIENT * This);
/* iso.c */
STREAM iso_init(RDPCLIENT * This, int length);
void iso_send(RDPCLIENT * This, STREAM s);
BOOL iso_send(RDPCLIENT * This, STREAM s);
STREAM iso_recv(RDPCLIENT * This, uint8 * rdpver);
BOOL iso_connect(RDPCLIENT * This, char *server, char *username);
BOOL iso_reconnect(RDPCLIENT * This, char *server);
void iso_disconnect(RDPCLIENT * This);
BOOL iso_connect(RDPCLIENT * This, char *server, char *cookie);
BOOL iso_reconnect(RDPCLIENT * This, char *server, char *cookie);
BOOL iso_disconnect(RDPCLIENT * This);
void iso_reset_state(RDPCLIENT * This);
/* licence.c */
void licence_process(RDPCLIENT * This, STREAM s);
/* mcs.c */
STREAM mcs_init(RDPCLIENT * This, int length);
void mcs_send_to_channel(RDPCLIENT * This, STREAM s, uint16 channel);
void mcs_send(RDPCLIENT * This, STREAM s);
BOOL mcs_send_to_channel(RDPCLIENT * This, STREAM s, uint16 channel);
BOOL mcs_send(RDPCLIENT * This, STREAM s);
STREAM mcs_recv(RDPCLIENT * This, uint16 * channel, uint8 * rdpver);
BOOL mcs_connect(RDPCLIENT * This, char *server, STREAM mcs_data, char *username);
BOOL mcs_reconnect(RDPCLIENT * This, char *server, STREAM mcs_data);
BOOL mcs_connect(RDPCLIENT * This, char *server, char *cookie, STREAM mcs_data);
BOOL mcs_reconnect(RDPCLIENT * This, char *server, char *cookie, STREAM mcs_data);
void mcs_disconnect(RDPCLIENT * This);
void mcs_reset_state(RDPCLIENT * This);
/* orders.c */
@@ -110,10 +110,6 @@ BOOL pstcache_init(RDPCLIENT * This, uint8 cache_id);
/* rdesktop.c */
int main(int argc, char *argv[]);
void generate_random(uint8 * random);
void *xmalloc(size_t size);
char *xstrdup(const char *s);
void *xrealloc(void *oldmem, size_t size);
void xfree(void *mem);
void error(char *format, ...);
void warning(char *format, ...);
void unimpl(char *format, ...);
@@ -134,13 +130,13 @@ 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(RDPCLIENT * This, STREAM s);
BOOL rdp5_process(RDPCLIENT * This, STREAM s);
/* rdp.c */
void rdp_out_unistr(RDPCLIENT * This, STREAM s, char *string, int len);
int rdp_in_unistr(RDPCLIENT * This, STREAM s, char *string, int uni_len);
void rdp_send_input(RDPCLIENT * This, uint32 time, uint16 message_type, uint16 device_flags, uint16 param1,
void rdp_out_unistr(RDPCLIENT * This, STREAM s, wchar_t *string, int len);
int rdp_in_unistr(RDPCLIENT * This, STREAM s, wchar_t *string, int uni_len);
BOOL rdp_send_input(RDPCLIENT * This, uint32 time, uint16 message_type, uint16 device_flags, uint16 param1,
uint16 param2);
void rdp_send_client_window_status(RDPCLIENT * This, int status);
BOOL rdp_send_client_window_status(RDPCLIENT * This, int status);
void process_colour_pointer_pdu(RDPCLIENT * This, STREAM s);
void process_cached_pointer_pdu(RDPCLIENT * This, STREAM s);
void process_system_pointer_pdu(RDPCLIENT * This, STREAM s);
@@ -149,10 +145,10 @@ void process_palette(RDPCLIENT * This, STREAM s);
void process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason);
void rdp_main_loop(RDPCLIENT * This, BOOL * deactivated, uint32 * ext_disc_reason);
BOOL rdp_loop(RDPCLIENT * This, BOOL * deactivated, uint32 * ext_disc_reason);
BOOL rdp_connect(RDPCLIENT * This, char *server, uint32 flags, char *domain, char *password, char *command,
char *directory);
BOOL rdp_reconnect(RDPCLIENT * This, char *server, uint32 flags, char *domain, char *password, char *command,
char *directory, char *cookie);
BOOL rdp_connect(RDPCLIENT * This, char *server, uint32 flags, wchar_t *username, wchar_t *domain, wchar_t *password, wchar_t *command,
wchar_t *directory, wchar_t *hostname, char *cookie);
BOOL rdp_reconnect(RDPCLIENT * This, char *server, uint32 flags, wchar_t *username, wchar_t *domain, wchar_t *password, wchar_t *command,
wchar_t *directory, wchar_t *hostname, char *cookie);
void rdp_reset_state(RDPCLIENT * This);
void rdp_disconnect(RDPCLIENT * This);
#if 0
@@ -187,12 +183,12 @@ void sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, ui
int datalen);
void sec_decrypt(RDPCLIENT * This, uint8 * data, int length);
STREAM sec_init(RDPCLIENT * This, uint32 flags, int maxlen);
void sec_send_to_channel(RDPCLIENT * This, STREAM s, uint32 flags, uint16 channel);
void sec_send(RDPCLIENT * This, STREAM s, uint32 flags);
BOOL sec_send_to_channel(RDPCLIENT * This, STREAM s, uint32 flags, uint16 channel);
BOOL sec_send(RDPCLIENT * This, STREAM s, uint32 flags);
void sec_process_mcs_data(RDPCLIENT * This, STREAM s);
STREAM sec_recv(RDPCLIENT * This, uint8 * rdpver);
BOOL sec_connect(RDPCLIENT * This, char *server, char *username);
BOOL sec_reconnect(RDPCLIENT * This, char *server);
BOOL sec_connect(RDPCLIENT * This, char *server, wchar_t *hostname, char *cookie);
BOOL sec_reconnect(RDPCLIENT * This, char *server, wchar_t *hostname, char *cookie);
void sec_disconnect(RDPCLIENT * This);
void sec_reset_state(RDPCLIENT * This);
#if 0
@@ -203,11 +199,11 @@ BOOL serial_get_timeout(RDPCLIENT * This, NTHANDLE handle, uint32 length, uint32
#endif
/* tcp.c */
STREAM tcp_init(RDPCLIENT * This, uint32 maxlen);
void tcp_send(RDPCLIENT * This, STREAM s);
BOOL tcp_send(RDPCLIENT * This, STREAM s);
STREAM tcp_recv(RDPCLIENT * This, STREAM s, uint32 length);
BOOL tcp_connect(RDPCLIENT * This, char *server);
void tcp_disconnect(RDPCLIENT * This);
char *tcp_get_address(RDPCLIENT * This);
BOOL tcp_disconnect(RDPCLIENT * This);
wchar_t *tcp_get_address(RDPCLIENT * This);
void tcp_reset_state(RDPCLIENT * This);
/* xclip.c */
void ui_clip_format_announce(RDPCLIENT * This, uint8 * data, uint32 length);
@@ -245,7 +241,7 @@ BOOL ui_create_window(RDPCLIENT * This);
void ui_resize_window(RDPCLIENT * This);
void ui_destroy_window(RDPCLIENT * This);
void xwin_toggle_fullscreen(RDPCLIENT * This);
int ui_select(RDPCLIENT * This, int rdp_socket);
int ui_select(RDPCLIENT * This, SOCKET rdp_socket);
void ui_move_pointer(RDPCLIENT * This, int x, int y);
HBITMAP ui_create_bitmap(RDPCLIENT * This, int width, int height, uint8 * data);
void ui_paint_bitmap(RDPCLIENT * This, int x, int y, int cx, int cy, int width, int height, uint8 * data);
@@ -313,6 +309,10 @@ void seamless_select_timeout(RDPCLIENT * This, struct timeval *tv);
unsigned int seamless_send_zchange(RDPCLIENT * This, unsigned long id, unsigned long below, unsigned long flags);
unsigned int seamless_send_focus(RDPCLIENT * This, unsigned long id, unsigned long flags);
/* events */
int event_pubkey(RDPCLIENT * This, const unsigned char * key, size_t key_size);
void event_logon(RDPCLIENT * This);
/* *INDENT-OFF* */
#ifdef __cplusplus
}
@@ -59,14 +59,18 @@ pstcache_load_bitmap(RDPCLIENT * This, uint8 cache_id, uint16 cache_idx)
fd = This->pstcache_fd[cache_id];
rd_lseek_file(fd, cache_idx * (This->pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER)));
rd_read_file(fd, &cellhdr, sizeof(CELLHEADER));
celldata = (uint8 *) xmalloc(cellhdr.length);
celldata = (uint8 *) malloc(cellhdr.length);
if(celldata == NULL)
return False;
rd_read_file(fd, celldata, cellhdr.length);
bitmap = ui_create_bitmap(This, cellhdr.width, cellhdr.height, celldata);
DEBUG(("Load bitmap from disk: id=%d, idx=%d, bmp=0x%x)\n", cache_id, cache_idx, bitmap));
cache_put_bitmap(This, cache_id, cache_idx, bitmap);
xfree(celldata);
free(celldata);
return True;
}
@@ -23,6 +23,7 @@
#endif
#include <windows.h>
#include <winsock2.h>
#include <cchannel.h>
#if 0
@@ -191,23 +192,16 @@ typedef struct _seamless_window
} seamless_window;
#endif
typedef struct CHANNEL_PRIVATE_
{
int opened;
PCHANNEL_INIT_EVENT_FN pChannelInitEventProc;
PCHANNEL_OPEN_EVENT_FN pChannelOpenEventProc;
}
CHANNEL_PRIVATE;
/* holds the whole state of the RDP client */
struct rdpclient
{
/* channels.c */
CHANNEL_DEF channel_defs[CHANNEL_MAX_COUNT];
CHANNEL_PRIVATE channel_data[CHANNEL_MAX_COUNT];
unsigned int num_channels;
/* licence.c */
char * licence_username;
char licence_hostname[MAX_COMPUTERNAME_LENGTH + 1];
BOOL licence_issued;
/* mcs.c */
@@ -222,10 +216,7 @@ struct rdpclient
BOOL pstcache_enumerated;
/* rdesktop.c */
char title[64];
char username[64];
char hostname[16];
char keymapname[MAX_PATH];
int disconnect_reason;
unsigned int keylayout;
int keyboard_type;
int keyboard_subtype;
@@ -233,17 +224,8 @@ struct rdpclient
int width;
int height;
int xpos;
int ypos;
int pos; /* 0 position unspecified,
1 specified,
2 xpos neg,
4 ypos neg */
int server_depth;
int win_button_size; /* If zero, disable single app mode */
BOOL bitmap_compression;
BOOL sendmotion;
BOOL bitmap_cache;
BOOL bitmap_cache_persist_enable;
BOOL bitmap_cache_precache;
@@ -251,27 +233,17 @@ struct rdpclient
BOOL packet_encryption;
BOOL desktop_save; /* desktop save order */
BOOL polygon_ellipse_orders; /* polygon / ellipse orders */
BOOL fullscreen;
BOOL grab_keyboard;
BOOL hide_decorations;
BOOL use_rdp5;
BOOL rdpclip;
BOOL console_session;
BOOL numlock_sync;
BOOL lspci_enabled ;
BOOL owncolmap;
BOOL ownbackstore; /* We can't rely on external BackingStore */
BOOL seamless_rdp;
uint32 embed_wnd;
uint32 rdp5_performanceflags;
/* Session Directory redirection */
BOOL redirect;
char redirect_server[64];
char redirect_domain[16];
char redirect_password[64];
char redirect_username[64];
char redirect_cookie[128];
wchar_t * redirect_server;
wchar_t * redirect_domain;
wchar_t * redirect_password;
wchar_t * redirect_username;
char * redirect_cookie;
uint32 redirect_flags;
/* rdp.c */
@@ -319,7 +291,8 @@ struct rdpclient
/* rdp.c */
struct rdp_
{
int ignore_;
int current_status;
#if WITH_DEBUG
uint32 packetno;
#endif
@@ -355,269 +328,11 @@ struct rdpclient
/* tcp.c */
struct tcp_
{
int sock;
SOCKET sock;
struct stream in;
struct stream out;
}
tcp;
#if 0
/* Public fields */
/* disk.c */
#define MAX_OPEN_FILES 0x100
FILEINFO fileinfo[MAX_OPEN_FILES];
BOOL notify_stamp;
/* ewmhints.c */
Atom net_wm_state_atom, net_wm_desktop_atom;
/* rdpdr.c */
/* If select() times out, the request for the device with handle min_timeout_fd is aborted */
NTHANDLE min_timeout_fd;
uint32 num_devices;
/* Table with information about rdpdr devices */
RDPDR_DEVICE rdpdr_device[RDPDR_MAX_DEVICES];
char *rdpdr_clientname;
struct async_iorequest *iorequest;
/* rdpsndXXX.c */
#ifdef WITH_RDPSND
int dsp_fd;
BOOL dsp_busy;
#endif
#if 0
/* xwin.c */
Display *display;
BOOL enable_compose;
BOOL Unobscured; /* used for screenblt */
Time last_gesturetime;
Window wnd;
#endif
/* Private fields */
/* FIXME: it's not pretty to spill private fields this way. Use opaque pointers */
/* cliprdr.c */
struct cliprdr_
{
VCHANNEL *channel;
uint8 *last_formats;
uint32 last_formats_length;
}
cliprdr;
struct ewmhints_
{
Atom state_maximized_vert_atom, state_maximized_horz_atom,
state_hidden_atom, name_atom, utf8_string_atom,
state_skip_taskbar_atom, state_skip_pager_atom, state_modal_atom;
}
ewmhints;
/* rdpdr.c */
struct rdpdr_
{
VCHANNEL *channel;
}
rdpdr;
/* rdpsnd.c */
struct rdpsnd_
{
VCHANNEL *channel;
BOOL device_open;
#define MAX_FORMATS 10
WAVEFORMATEX formats[MAX_FORMATS];
unsigned int format_count;
unsigned int current_format;
}
rdpsnd;
/* seamless.c */
struct seamless_
{
VCHANNEL *channel;
unsigned int serial;
}
seamless;
/* xclip.c */
struct xclip_
{
#define MAX_TARGETS 8
/* Mode of operation.
- Auto: Look at both PRIMARY and CLIPBOARD and use the most recent.
- Non-auto: Look at just CLIPBOARD. */
BOOL auto_mode;
/* Atoms of the two X selections we're dealing with: CLIPBOARD (explicit-copy) and PRIMARY (selection-copy) */
Atom clipboard_atom, primary_atom;
/* Atom of the TARGETS clipboard target */
Atom targets_atom;
/* Atom of the TIMESTAMP clipboard target */
Atom timestamp_atom;
/* Atom _RDESKTOP_CLIPBOARD_TARGET which is used as the 'property' argument in
XConvertSelection calls: This is the property of our window into which
XConvertSelection will store the received clipboard data. */
Atom rdesktop_clipboard_target_atom;
/* Atoms _RDESKTOP_PRIMARY_TIMESTAMP_TARGET and _RDESKTOP_CLIPBOARD_TIMESTAMP_TARGET
are used to store the timestamps for when a window got ownership of the selections.
We use these to determine which is more recent and should be used. */
Atom rdesktop_primary_timestamp_target_atom, rdesktop_clipboard_timestamp_target_atom;
/* Storage for timestamps since we get them in two separate notifications. */
Time primary_timestamp, clipboard_timestamp;
/* Clipboard target for getting a list of native Windows clipboard formats. The
presence of this target indicates that the selection owner is another rdesktop. */
Atom rdesktop_clipboard_formats_atom;
/* The clipboard target (X jargon for "clipboard format") for rdesktop-to-rdesktop
interchange of Windows native clipboard data. The requestor must supply the
desired native Windows clipboard format in the associated property. */
Atom rdesktop_native_atom;
/* Local copy of the list of native Windows clipboard formats. */
uint8 *formats_data;
uint32 formats_data_length;
/* We need to know when another rdesktop process gets or loses ownership of a
selection. Without XFixes we do this by touching a property on the root window
which will generate PropertyNotify notifications. */
Atom rdesktop_selection_notify_atom;
/* State variables that indicate if we're currently probing the targets of the
selection owner. reprobe_selections indicate that the ownership changed in
the middle of the current probe so it should be restarted. */
BOOL probing_selections, reprobe_selections;
/* Atoms _RDESKTOP_PRIMARY_OWNER and _RDESKTOP_CLIPBOARD_OWNER. Used as properties
on the root window to indicate which selections that are owned by rdesktop. */
Atom rdesktop_primary_owner_atom, rdesktop_clipboard_owner_atom;
Atom format_string_atom, format_utf8_string_atom, format_unicode_atom;
/* Atom of the INCR clipboard type (see ICCCM on "INCR Properties") */
Atom incr_atom;
/* Stores the last "selection request" (= another X client requesting clipboard data from us).
To satisfy such a request, we request the clipboard data from the RDP server.
When we receive the response from the RDP server (asynchronously), this variable gives us
the context to proceed. */
XSelectionRequestEvent selection_request;
/* Denotes we have a pending selection request. */
Bool has_selection_request;
/* Stores the clipboard format (CF_TEXT, CF_UNICODETEXT etc.) requested in the last
CLIPDR_DATA_REQUEST (= the RDP server requesting clipboard data from us).
When we receive this data from whatever X client offering it, this variable gives us
the context to proceed.
*/
int rdp_clipboard_request_format;
/* Array of offered clipboard targets that will be sent to fellow X clients upon a TARGETS request. */
Atom targets[MAX_TARGETS];
int num_targets;
/* Denotes that an rdesktop (not this rdesktop) is owning the selection,
allowing us to interchange Windows native clipboard data directly. */
BOOL rdesktop_is_selection_owner;
/* Time when we acquired the selection. */
Time acquire_time;
/* Denotes that an INCR ("chunked") transfer is in progress. */
int waiting_for_INCR;
/* Denotes the target format of the ongoing INCR ("chunked") transfer. */
Atom incr_target;
/* Buffers an INCR transfer. */
uint8 *clip_buffer;
/* Denotes the size of clip_buffer. */
uint32 clip_buflen;
}
xclip;
/* xkeymap.c */
struct xkeymap_
{
#define KEYMAP_SIZE 0xffff+1
BOOL keymap_loaded;
key_translation *keymap[KEYMAP_SIZE];
int min_keycode;
uint16 remote_modifier_state;
uint16 saved_remote_modifier_state;
}
xkeymap;
#if 0
/* xwin.c */
struct xwin_
{
int x_socket;
Screen *screen;
/* SeamlessRDP support */
seamless_window *seamless_windows;
unsigned long seamless_focused;
BOOL seamless_started; /* Server end is up and running */
BOOL seamless_active; /* We are currently in seamless mode */
BOOL seamless_hidden; /* Desktop is hidden on server */
GC gc;
GC create_bitmap_gc;
GC create_glyph_gc;
XRectangle clip_rectangle;
Visual *visual;
/* Color depth of the X11 visual of our window (e.g. 24 for True Color R8G8B visual).
This may be 32 for R8G8B8 visuals, and then the rest of the bits are undefined
as far as we're concerned. */
int depth;
/* Bits-per-Pixel of the pixmaps we'll be using to draw on our window.
This may be larger than depth, in which case some of the bits would
be kept solely for alignment (e.g. 32bpp pixmaps on a 24bpp visual). */
int bpp;
XIM IM;
XIC IC;
XModifierKeymap *mod_map;
Cursor current_cursor;
HCURSOR null_cursor;
Atom protocol_atom, kill_atom;
BOOL focused;
BOOL mouse_in_wnd;
/* Indicates that:
1) visual has 15, 16 or 24 depth and the same color channel masks
as its RDP equivalent (implies X server is LE),
2) host is LE
This will trigger an optimization whose real value is questionable.
*/
BOOL compatible_arch;
/* Indicates whether RDP's bitmaps and our XImages have the same
binary format. If so, we can avoid an expensive translation.
Note that this can be true when compatible_arch is false,
e.g.:
RDP(LE) <-> host(BE) <-> X-Server(LE)
('host' is the machine running rdesktop; the host simply memcpy's
so its endianess doesn't matter)
*/
BOOL no_translate_image;
/* endianness */
BOOL host_be;
BOOL xserver_be;
int red_shift_r, blue_shift_r, green_shift_r;
int red_shift_l, blue_shift_l, green_shift_l;
/* software backing store */
Pixmap backstore;
/* Moving in single app mode */
BOOL moving_wnd;
int move_x_offset;
int move_y_offset;
BOOL using_full_workarea;
/* colour maps */
Colormap xcolmap;
uint32 *colmap;
XErrorHandler old_error_handler;
}
xwin;
#endif
#endif
};
#ifndef MAKE_PROTO
+149 -81
View File
@@ -35,9 +35,9 @@
/* Receive an RDP packet */
static STREAM
rdp_recv(RDPCLIENT * This, uint8 * type)
rdp_recv(RDPCLIENT * This, uint8 * type) // EXITS
{
static STREAM rdp_s;
static STREAM rdp_s; // FIXME HORROR
uint16 length, pdu_type;
uint8 rdpver;
@@ -55,7 +55,8 @@ rdp_recv(RDPCLIENT * This, uint8 * type)
else if (rdpver != 3)
{
/* rdp5_process should move This->next_packet ok */
rdp5_process(This, rdp_s);
if(!rdp5_process(This, rdp_s))
return NULL;
*type = 0;
return rdp_s;
}
@@ -95,19 +96,23 @@ rdp_init_data(RDPCLIENT * This, int maxlen)
STREAM s;
s = sec_init(This, This->encryption ? SEC_ENCRYPT : 0, maxlen + 18);
if(s == NULL)
return NULL;
s_push_layer(s, rdp_hdr, 18);
return s;
}
/* Send an RDP data packet */
static void
static BOOL
rdp_send_data(RDPCLIENT * This, STREAM s, uint8 data_pdu_type)
{
uint16 length;
s_pop_layer(s, rdp_hdr);
length = s->end - s->p;
length = (uint16)(s->end - s->p);
out_uint16_le(s, length);
out_uint16_le(s, (RDP_PDU_DATA | 0x10));
@@ -121,12 +126,12 @@ rdp_send_data(RDPCLIENT * This, STREAM s, uint8 data_pdu_type)
out_uint8(s, 0); /* compress_type */
out_uint16(s, 0); /* compress_len */
sec_send(This, s, This->encryption ? SEC_ENCRYPT : 0);
return sec_send(This, s, This->encryption ? SEC_ENCRYPT : 0);
}
/* Output a string in Unicode */
void
rdp_out_unistr(RDPCLIENT * This, STREAM s, char *string, int len)
rdp_out_unistr(RDPCLIENT * This, STREAM s, wchar_t *string, int len)
{
#ifdef HAVE_ICONV
size_t ibl = strlen(string), obl = len + 2;
@@ -180,6 +185,7 @@ rdp_out_unistr(RDPCLIENT * This, STREAM s, char *string, int len)
}
else
#endif
// TODO
{
int i = 0, j = 0;
@@ -187,8 +193,9 @@ rdp_out_unistr(RDPCLIENT * This, STREAM s, char *string, int len)
while (i < len)
{
s->p[i++] = string[j++];
s->p[i++] = 0;
int c = string[j++];
s->p[i++] = (c >> 0) & 0xFF;
s->p[i++] = (c >> 8) & 0xFF;
}
s->p += len;
@@ -200,7 +207,7 @@ rdp_out_unistr(RDPCLIENT * This, STREAM s, char *string, int len)
* Returns str_len of string
*/
int
rdp_in_unistr(RDPCLIENT * This, STREAM s, char *string, int uni_len)
rdp_in_unistr(RDPCLIENT * This, STREAM s, wchar_t *string, int uni_len)
{
#ifdef HAVE_ICONV
size_t ibl = uni_len, obl = uni_len;
@@ -238,6 +245,7 @@ rdp_in_unistr(RDPCLIENT * This, STREAM s, char *string, int uni_len)
}
else
#endif
// TODO
{
int i = 0;
@@ -253,18 +261,18 @@ rdp_in_unistr(RDPCLIENT * This, STREAM s, char *string, int uni_len)
/* Parse a logon info packet */
static void
rdp_send_logon_info(RDPCLIENT * This, uint32 flags, char *domain, char *user,
char *password, char *program, char *directory)
static BOOL
rdp_send_logon_info(RDPCLIENT * This, uint32 flags, wchar_t *domain, wchar_t *user,
wchar_t *password, wchar_t *program, wchar_t *directory)
{
char *ipaddr = tcp_get_address(This);
int len_domain = 2 * strlen(domain);
int len_user = 2 * strlen(user);
int len_password = 2 * strlen(password);
int len_program = 2 * strlen(program);
int len_directory = 2 * strlen(directory);
int len_ip = 2 * strlen(ipaddr);
int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
wchar_t *ipaddr = tcp_get_address(This);
int len_domain = 2 * (int)wcslen(domain);
int len_user = 2 * (int)wcslen(user);
int len_password = 2 * (int)wcslen(password);
int len_program = 2 * (int)wcslen(program);
int len_directory = 2 * (int)wcslen(directory);
int len_ip = 2 * (int)wcslen(ipaddr);
int len_dll = 2 * (int)wcslen(L"C:\\WINNT\\System32\\mstscax.dll");
int packetlen = 0;
uint32 sec_flags = This->encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
STREAM s;
@@ -278,6 +286,9 @@ rdp_send_logon_info(RDPCLIENT * This, uint32 flags, char *domain, char *user,
s = sec_init(This, sec_flags, 18 + len_domain + len_user + len_password
+ len_program + len_directory + 10);
if(s == NULL)
return False;
out_uint32(s, 0);
out_uint32_le(s, flags);
out_uint16_le(s, len_domain);
@@ -322,6 +333,9 @@ rdp_send_logon_info(RDPCLIENT * This, uint32 flags, char *domain, char *user,
s = sec_init(This, sec_flags, packetlen);
DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
if(s == NULL)
return False;
out_uint32(s, 0); /* Unknown */
out_uint32_le(s, flags);
out_uint16_le(s, len_domain);
@@ -371,13 +385,13 @@ rdp_send_logon_info(RDPCLIENT * This, uint32 flags, char *domain, char *user,
out_uint16_le(s, len_ip + 2); /* Length of client ip */
rdp_out_unistr(This, s, ipaddr, len_ip);
out_uint16_le(s, len_dll + 2);
rdp_out_unistr(This, s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
rdp_out_unistr(This, s, L"C:\\WINNT\\System32\\mstscax.dll", len_dll);
tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;
out_uint32_le(s, tzone);
out_uint32_le(s, (uint32)tzone);
rdp_out_unistr(This, s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
rdp_out_unistr(This, s, L"GTB, normaltid", 2 * (int)wcslen(L"GTB, normaltid"));
out_uint8s(s, 62 - 2 * wcslen(L"GTB, normaltid"));
out_uint32_le(s, 0x0a0000);
out_uint32_le(s, 0x050000);
@@ -385,8 +399,8 @@ rdp_send_logon_info(RDPCLIENT * This, uint32 flags, char *domain, char *user,
out_uint32_le(s, 0);
out_uint32_le(s, 0);
rdp_out_unistr(This, s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
rdp_out_unistr(This, s, L"GTB, sommartid", 2 * (int)wcslen(L"GTB, sommartid"));
out_uint8s(s, 62 - 2 * wcslen(L"GTB, sommartid"));
out_uint32_le(s, 0x30000);
out_uint32_le(s, 0x050000);
@@ -400,48 +414,57 @@ rdp_send_logon_info(RDPCLIENT * This, uint32 flags, char *domain, char *user,
}
s_mark_end(s);
sec_send(This, s, sec_flags);
return sec_send(This, s, sec_flags);
}
/* Send a control PDU */
static void
static BOOL
rdp_send_control(RDPCLIENT * This, uint16 action)
{
STREAM s;
s = rdp_init_data(This, 8);
if(s == NULL)
return False;
out_uint16_le(s, action);
out_uint16(s, 0); /* userid */
out_uint32(s, 0); /* control id */
s_mark_end(s);
rdp_send_data(This, s, RDP_DATA_PDU_CONTROL);
return rdp_send_data(This, s, RDP_DATA_PDU_CONTROL);
}
/* Send a synchronisation PDU */
static void
static BOOL
rdp_send_synchronise(RDPCLIENT * This)
{
STREAM s;
s = rdp_init_data(This, 4);
if(s == NULL)
return False;
out_uint16_le(s, 1); /* type */
out_uint16_le(s, 1002);
s_mark_end(s);
rdp_send_data(This, s, RDP_DATA_PDU_SYNCHRONISE);
return rdp_send_data(This, s, RDP_DATA_PDU_SYNCHRONISE);
}
/* Send a single input event */
void
BOOL
rdp_send_input(RDPCLIENT * This, uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
{
STREAM s;
s = rdp_init_data(This, 16);
if(s == NULL)
return False;
out_uint16_le(s, 1); /* number of events */
out_uint16(s, 0); /* pad */
@@ -452,21 +475,23 @@ rdp_send_input(RDPCLIENT * This, uint32 time, uint16 message_type, uint16 device
out_uint16_le(s, param2);
s_mark_end(s);
rdp_send_data(This, s, RDP_DATA_PDU_INPUT);
return rdp_send_data(This, s, RDP_DATA_PDU_INPUT);
}
/* Send a client window information PDU */
void
BOOL
rdp_send_client_window_status(RDPCLIENT * This, int status)
{
STREAM s;
static int current_status = 1;
if (current_status == status)
return;
if (This->rdp.current_status == status)
return True;
s = rdp_init_data(This, 12);
if(s == NULL)
return False;
out_uint32_le(s, status);
switch (status)
@@ -482,13 +507,13 @@ rdp_send_client_window_status(RDPCLIENT * This, int status)
}
s_mark_end(s);
rdp_send_data(This, s, RDP_DATA_PDU_CLIENT_WINDOW_STATUS);
current_status = status;
This->rdp.current_status = status;
return rdp_send_data(This, s, RDP_DATA_PDU_CLIENT_WINDOW_STATUS);
}
/* Send persistent bitmap cache enumeration PDU's */
static void
rdp_enum_bmpcache2(RDPCLIENT * This)
static BOOL
rdp_enum_bmpcache2(RDPCLIENT * This) // THIS
{
STREAM s;
HASH_KEY keylist[BMPCACHE2_NUM_PSTCELLS];
@@ -503,6 +528,9 @@ rdp_enum_bmpcache2(RDPCLIENT * This)
s = rdp_init_data(This, 24 + count * sizeof(HASH_KEY));
if(s == NULL)
return False;
flags = 0;
if (offset == 0)
flags |= PDU_FLAG_FIRST;
@@ -524,27 +552,33 @@ rdp_enum_bmpcache2(RDPCLIENT * This)
out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY));
s_mark_end(s);
rdp_send_data(This, s, 0x2b);
if(!rdp_send_data(This, s, 0x2b))
return False;
offset += 169;
}
return True;
}
/* Send an (empty) font information PDU */
static void
static BOOL
rdp_send_fonts(RDPCLIENT * This, uint16 seq)
{
STREAM s;
s = rdp_init_data(This, 8);
if(s == NULL)
return False;
out_uint16(s, 0); /* number of fonts */
out_uint16_le(s, 0); /* pad? */
out_uint16_le(s, seq); /* unknown */
out_uint16_le(s, 0x32); /* entry size */
s_mark_end(s);
rdp_send_data(This, s, RDP_DATA_PDU_FONT2);
return rdp_send_data(This, s, RDP_DATA_PDU_FONT2);
}
/* Output general capability set */
@@ -777,7 +811,7 @@ rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, const uint8 * caps)
#define RDP5_FLAG 0x0030
/* Send a confirm active PDU */
static void
static BOOL
rdp_send_confirm_active(RDPCLIENT * This)
{
STREAM s;
@@ -792,6 +826,9 @@ rdp_send_confirm_active(RDPCLIENT * This)
s = sec_init(This, sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
if(s == NULL)
return False;
out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10)); /* Version 1 */
out_uint16_le(s, (This->mcs_userid + 1001));
@@ -821,7 +858,7 @@ rdp_send_confirm_active(RDPCLIENT * This)
rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
s_mark_end(s);
sec_send(This, s, sec_flags);
return sec_send(This, s, sec_flags);
}
/* Process a general capability set */
@@ -910,8 +947,8 @@ rdp_process_server_caps(RDPCLIENT * This, STREAM s, uint16 length)
}
/* Respond to a demand active PDU */
static void
process_demand_active(RDPCLIENT * This, STREAM s)
static BOOL
process_demand_active(RDPCLIENT * This, STREAM s) // EXITS
{
uint8 type;
uint16 len_src_descriptor, len_combined_caps;
@@ -924,29 +961,36 @@ process_demand_active(RDPCLIENT * This, STREAM s)
DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", This->rdp_shareid));
rdp_process_server_caps(This, s, len_combined_caps);
rdp_send_confirm_active(This);
rdp_send_synchronise(This);
rdp_send_control(This, RDP_CTL_COOPERATE);
rdp_send_control(This, RDP_CTL_REQUEST_CONTROL);
rdp_recv(This, &type); /* RDP_PDU_SYNCHRONIZE */
rdp_recv(This, &type); /* RDP_CTL_COOPERATE */
rdp_recv(This, &type); /* RDP_CTL_GRANT_CONTROL */
rdp_send_input(This, 0, RDP_INPUT_SYNCHRONIZE, 0,
/*This->numlock_sync ? ui_get_numlock_state(This, read_keyboard_state(This)) :*/ 0, 0); // TODO: keyboard mess
if
(
!rdp_send_confirm_active(This) ||
!rdp_send_synchronise(This) ||
!rdp_send_control(This, RDP_CTL_COOPERATE) ||
!rdp_send_control(This, RDP_CTL_REQUEST_CONTROL) ||
!rdp_recv(This, &type) || /* RDP_PDU_SYNCHRONIZE */
!rdp_recv(This, &type) || /* RDP_CTL_COOPERATE */
!rdp_recv(This, &type) || /* RDP_CTL_GRANT_CONTROL */
!rdp_send_input(This, 0, RDP_INPUT_SYNCHRONIZE, 0,
/*This->numlock_sync ? ui_get_numlock_state(This, read_keyboard_state(This)) :*/ 0, 0) // TODO: keyboard mess
)
return False;
if (This->use_rdp5)
{
rdp_enum_bmpcache2(This);
rdp_send_fonts(This, 3);
if(!rdp_enum_bmpcache2(This) || !rdp_send_fonts(This, 3))
return False;
}
else
{
rdp_send_fonts(This, 1);
rdp_send_fonts(This, 2);
if(!rdp_send_fonts(This, 1) || !rdp_send_fonts(This, 2))
return False;
}
rdp_recv(This, &type); /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
if(!rdp_recv(This, &type)) /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
return False;
reset_order_state(This);
return True;
}
/* Process a colour pointer PDU */
@@ -1037,7 +1081,7 @@ process_pointer_pdu(RDPCLIENT * This, STREAM s)
/* Process bitmap updates */
void
process_bitmap_updates(RDPCLIENT * This, STREAM s)
process_bitmap_updates(RDPCLIENT * This, STREAM s) // EXITS
{
uint16 num_updates;
uint16 left, top, right, bottom, width, height;
@@ -1097,7 +1141,11 @@ process_bitmap_updates(RDPCLIENT * This, STREAM s)
in_uint8s(s, 4); /* line_size, final_size */
}
in_uint8p(s, data, size);
bmpdata = (uint8 *) xmalloc(width * height * Bpp);
bmpdata = (uint8 *) malloc(width * height * Bpp);
if(bmpdata == NULL)
return;
if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
{
ui_paint_bitmap(This, left, top, cx, cy, width, height, bmpdata);
@@ -1107,13 +1155,13 @@ process_bitmap_updates(RDPCLIENT * This, STREAM s)
DEBUG_RDP5(("Failed to decompress data\n"));
}
xfree(bmpdata);
free(bmpdata);
}
}
/* Process a palette update */
void
process_palette(RDPCLIENT * This, STREAM s)
process_palette(RDPCLIENT * This, STREAM s) // EXITS
{
COLOURENTRY *entry;
COLOURMAP map;
@@ -1124,7 +1172,13 @@ process_palette(RDPCLIENT * This, STREAM s)
in_uint16_le(s, map.ncolours);
in_uint8s(s, 2); /* pad */
map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
map.colours = (COLOURENTRY *) malloc(sizeof(COLOURENTRY) * map.ncolours);
if(map.colours == NULL)
{
in_uint8s(s, sizeof(*entry) * map.ncolours);
return;
}
DEBUG(("PALETTE(c=%d)\n", map.ncolours));
@@ -1139,7 +1193,7 @@ process_palette(RDPCLIENT * This, STREAM s)
hmap = ui_create_colourmap(This, &map);
ui_set_colourmap(This, hmap);
xfree(map.colours);
free(map.colours);
}
/* Process an update PDU */
@@ -1188,7 +1242,7 @@ process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
/* Process data PDU */
static BOOL
process_data_pdu(RDPCLIENT * This, STREAM s, uint32 * ext_disc_reason)
process_data_pdu(RDPCLIENT * This, STREAM s, uint32 * ext_disc_reason) // EXITS
{
uint8 data_pdu_type;
uint8 ctype;
@@ -1208,6 +1262,8 @@ process_data_pdu(RDPCLIENT * This, STREAM s, uint32 * ext_disc_reason)
if (ctype & RDP_MPPC_COMPRESSED)
{
void * p;
if (len > RDP_MPPC_DICT_SIZE)
error("error decompressed packet size exceeds max\n");
if (mppc_expand(This, s->p, clen, ctype, &roff, &rlen) == -1)
@@ -1216,7 +1272,15 @@ process_data_pdu(RDPCLIENT * This, STREAM s, uint32 * ext_disc_reason)
/* len -= 18; */
/* allocate memory and copy the uncompressed data into the temporary stream */
ns->data = (uint8 *) xrealloc(ns->data, rlen);
p = realloc(ns->data, rlen);
if(p == NULL)
{
This->disconnect_reason = 262;
return True;
}
ns->data = (uint8 *) p;
memcpy((ns->data), (unsigned char *) (This->mppc_dict.hist + roff), rlen);
@@ -1252,6 +1316,7 @@ process_data_pdu(RDPCLIENT * This, STREAM s, uint32 * ext_disc_reason)
case RDP_DATA_PDU_LOGON:
DEBUG(("Received Logon PDU\n"));
event_logon(This);
/* User logged on */
break;
@@ -1277,6 +1342,8 @@ process_redirect_pdu(RDPCLIENT * This, STREAM s /*, uint32 * ext_disc_reason */
{
uint32 len;
// FIXME!!! allocate the strings used here
/* these 2 bytes are unknown, seem to be zeros */
in_uint8s(s, 2);
@@ -1330,7 +1397,7 @@ rdp_main_loop(RDPCLIENT * This, BOOL * deactivated, uint32 * ext_disc_reason)
/* used in uiports and rdp_main_loop, processes the rdp packets waiting */
BOOL
rdp_loop(RDPCLIENT * This, BOOL * deactivated, uint32 * ext_disc_reason)
rdp_loop(RDPCLIENT * This, BOOL * deactivated, uint32 * ext_disc_reason) // EXITS
{
uint8 type;
BOOL disc = False; /* True when a disconnect PDU was received */
@@ -1345,7 +1412,8 @@ rdp_loop(RDPCLIENT * This, BOOL * deactivated, uint32 * ext_disc_reason)
switch (type)
{
case RDP_PDU_DEMAND_ACTIVE:
process_demand_active(This, s);
if(!process_demand_active(This, s))
return False;
*deactivated = False;
break;
case RDP_PDU_DEACTIVATE:
@@ -1372,25 +1440,25 @@ rdp_loop(RDPCLIENT * This, BOOL * deactivated, uint32 * ext_disc_reason)
/* Establish a connection up to the RDP layer */
BOOL
rdp_connect(RDPCLIENT * This, char *server, uint32 flags, char *domain, char *password,
char *command, char *directory)
rdp_connect(RDPCLIENT * This, char *server, uint32 flags, wchar_t *username, wchar_t *domain, wchar_t *password,
wchar_t *command, wchar_t *directory, wchar_t *hostname, char *cookie) // EXITS
{
if (!sec_connect(This, server, This->username))
if (!sec_connect(This, server, hostname, cookie))
return False;
rdp_send_logon_info(This, flags, domain, This->username, password, command, directory);
rdp_send_logon_info(This, flags, domain, username, password, command, directory);
return True;
}
/* Establish a reconnection up to the RDP layer */
BOOL
rdp_reconnect(RDPCLIENT * This, char *server, uint32 flags, char *domain, char *password,
char *command, char *directory, char *cookie)
rdp_reconnect(RDPCLIENT * This, char *server, uint32 flags, wchar_t *username, wchar_t *domain, wchar_t *password,
wchar_t *command, wchar_t *directory, wchar_t *hostname, char *cookie) // EXITS
{
if (!sec_reconnect(This, server))
if (!sec_reconnect(This, server, hostname, cookie))
return False;
rdp_send_logon_info(This, flags, domain, This->username, password, command, directory);
rdp_send_logon_info(This, flags, domain, username, password, command, directory);
return True;
}
@@ -21,7 +21,7 @@
#include "rdesktop.h"
void
BOOL
rdp5_process(RDPCLIENT * This, STREAM s)
{
uint16 length, count, x, y;
@@ -56,11 +56,21 @@ rdp5_process(RDPCLIENT * This, STREAM s)
if (ctype & RDP_MPPC_COMPRESSED)
{
void * p;
if (mppc_expand(This, s->p, length, ctype, &roff, &rlen) == -1)
error("error while decompressing packet\n");
/* allocate memory and copy the uncompressed data into the temporary stream */
ns->data = (uint8 *) xrealloc(ns->data, rlen);
p = realloc(ns->data, rlen);
if(p == NULL)
{
This->disconnect_reason = 262;
return False;
}
ns->data = (uint8 *) p;
memcpy((ns->data), (unsigned char *) (This->mppc_dict.hist + roff), rlen);
@@ -114,4 +124,5 @@ rdp5_process(RDPCLIENT * This, STREAM s)
s->p = next;
}
ui_end_update(This);
return True;
}
@@ -290,7 +290,7 @@ sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * m
BN_mod_exp(&y, &x, &exp, &mod, ctx);
outlen = BN_bn2bin(&y, out);
reverse(out, outlen);
if (outlen < modulus_size)
if ((uint32)outlen < modulus_size)
memset(out + outlen, 0, modulus_size - outlen);
BN_free(&y);
@@ -312,6 +312,10 @@ sec_init(RDPCLIENT * This, uint32 flags, int maxlen)
else
hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
s = mcs_init(This, maxlen + hdrlen);
if(s == NULL)
return s;
s_push_layer(s, sec_hdr, hdrlen);
return s;
@@ -320,7 +324,7 @@ sec_init(RDPCLIENT * This, uint32 flags, int maxlen)
/* Transmit secure transport packet over specified channel */
// !!! we need a lock here !!!
void
BOOL
sec_send_to_channel(RDPCLIENT * This, STREAM s, uint32 flags, uint16 channel)
{
int datalen;
@@ -332,7 +336,7 @@ sec_send_to_channel(RDPCLIENT * This, STREAM s, uint32 flags, uint16 channel)
if (flags & SEC_ENCRYPT)
{
flags &= ~SEC_ENCRYPT;
datalen = s->end - s->p - 8;
datalen = (int)(s->end - s->p - 8);
#if WITH_DEBUG
DEBUG(("Sending encrypted packet:\n"));
@@ -343,15 +347,15 @@ sec_send_to_channel(RDPCLIENT * This, STREAM s, uint32 flags, uint16 channel)
sec_encrypt(This, s->p + 8, datalen);
}
mcs_send_to_channel(This, s, channel);
return mcs_send_to_channel(This, s, channel);
}
/* Transmit secure transport packet */
void
BOOL
sec_send(RDPCLIENT * This, STREAM s, uint32 flags)
{
sec_send_to_channel(This, s, flags, MCS_GLOBAL_CHANNEL);
return sec_send_to_channel(This, s, flags, MCS_GLOBAL_CHANNEL);
}
@@ -375,9 +379,9 @@ sec_establish_key(RDPCLIENT * This)
/* Output connect initial data blob */
static void
sec_out_mcs_data(RDPCLIENT * This, STREAM s)
sec_out_mcs_data(RDPCLIENT * This, STREAM s, wchar_t * hostname)
{
int hostlen = 2 * strlen(This->hostname);
int hostlen = 2 * (int)wcslen(hostname);
int length = 158 + 76 + 12 + 4;
unsigned int i;
@@ -417,7 +421,7 @@ sec_out_mcs_data(RDPCLIENT * This, STREAM s)
out_uint32_le(s, 2600); /* Client build. We are now 2600 compatible :-) */
/* Unicode name of client, padded to 32 bytes */
rdp_out_unistr(This, s, This->hostname, hostlen);
rdp_out_unistr(This, s, hostname, hostlen);
out_uint8s(s, 30 - hostlen);
/* See
@@ -607,6 +611,7 @@ sec_parse_crypt_info(RDPCLIENT * This, STREAM s, uint32 * rc4_key_size,
if (certcount < 2)
{
error("Server didn't send enough X509 certificates\n");
This->disconnect_reason = 1798;
return False;
}
@@ -649,6 +654,7 @@ sec_parse_crypt_info(RDPCLIENT * This, STREAM s, uint32 * rc4_key_size,
if (NULL == cacert)
{
error("Couldn't load CA Certificate from server\n");
This->disconnect_reason = 1798;
return False;
}
@@ -670,6 +676,7 @@ sec_parse_crypt_info(RDPCLIENT * This, STREAM s, uint32 * rc4_key_size,
if (NULL == server_cert)
{
error("Couldn't load Certificate from server\n");
This->disconnect_reason = 1798;
return False;
}
@@ -683,6 +690,7 @@ sec_parse_crypt_info(RDPCLIENT * This, STREAM s, uint32 * rc4_key_size,
{
DEBUG_RDP5(("Didn't parse X509 correctly\n"));
X509_free(server_cert);
This->disconnect_reason = 1798;
return False;
}
X509_free(server_cert);
@@ -822,7 +830,7 @@ sec_recv(RDPCLIENT * This, uint8 * rdpver)
if (*rdpver & 0x80)
{
in_uint8s(s, 8); /* signature */
sec_decrypt(This, s->p, s->end - s->p);
sec_decrypt(This, s->p, (int)(s->end - s->p));
}
return s;
}
@@ -834,7 +842,7 @@ sec_recv(RDPCLIENT * This, uint8 * rdpver)
if (sec_flags & SEC_ENCRYPT)
{
in_uint8s(s, 8); /* signature */
sec_decrypt(This, s->p, s->end - s->p);
sec_decrypt(This, s->p, (int)(s->end - s->p));
}
if (sec_flags & SEC_LICENCE_NEG)
@@ -848,7 +856,7 @@ sec_recv(RDPCLIENT * This, uint8 * rdpver)
uint8 swapbyte;
in_uint8s(s, 8); /* signature */
sec_decrypt(This, s->p, s->end - s->p);
sec_decrypt(This, s->p, (int)(s->end - s->p));
/* Check for a redirect packet, starts with 00 04 */
if (s->p[0] == 0 && s->p[1] == 4)
@@ -894,43 +902,57 @@ sec_recv(RDPCLIENT * This, uint8 * rdpver)
/* Establish a secure connection */
BOOL
sec_connect(RDPCLIENT * This, char *server, char *username)
sec_connect(RDPCLIENT * This, char *server, wchar_t *hostname, char *cookie) // EXITS
{
struct stream mcs_data;
void * p = malloc(512);
if(p == NULL)
{
This->disconnect_reason = 262;
return False;
}
/* We exchange some RDP data during the MCS-Connect */
mcs_data.size = 512;
mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size);
sec_out_mcs_data(This, &mcs_data);
mcs_data.p = mcs_data.data = (uint8 *) p;
sec_out_mcs_data(This, &mcs_data, hostname);
if (!mcs_connect(This, server, &mcs_data, username))
if (!mcs_connect(This, server, cookie, &mcs_data))
return False;
/* sec_process_mcs_data(&mcs_data); */
if (This->encryption)
sec_establish_key(This);
xfree(mcs_data.data);
free(mcs_data.data);
return True;
}
/* Establish a secure connection */
BOOL
sec_reconnect(RDPCLIENT * This, char *server)
sec_reconnect(RDPCLIENT * This, char *server, wchar_t *hostname, char *cookie) // EXITS
{
struct stream mcs_data;
void * p = malloc(512);
if(p == NULL)
{
This->disconnect_reason = 262;
return False;
}
/* We exchange some RDP data during the MCS-Connect */
mcs_data.size = 512;
mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size);
sec_out_mcs_data(This, &mcs_data);
mcs_data.p = mcs_data.data = (uint8 *) p;
sec_out_mcs_data(This, &mcs_data, hostname);
if (!mcs_reconnect(This, server, &mcs_data))
if (!mcs_reconnect(This, server, cookie, &mcs_data))
return False;
/* sec_process_mcs_data(&mcs_data); */
if (This->encryption)
sec_establish_key(This);
xfree(mcs_data.data);
free(mcs_data.data);
return True;
}
@@ -44,7 +44,17 @@ tcp_init(RDPCLIENT * This, uint32 maxlen)
{
if (maxlen > This->tcp.out.size)
{
This->tcp.out.data = (uint8 *) xrealloc(This->tcp.out.data, maxlen);
void * p;
p = realloc(This->tcp.out.data, maxlen);
if (p == NULL)
{
This->disconnect_reason = 262;
return NULL;
}
This->tcp.out.data = (uint8 *)p;
This->tcp.out.size = maxlen;
}
@@ -54,10 +64,10 @@ tcp_init(RDPCLIENT * This, uint32 maxlen)
}
/* Send TCP transport data packet */
void
BOOL
tcp_send(RDPCLIENT * This, STREAM s)
{
int length = s->end - s->data;
int length = (int)(s->end - s->data);
int sent, total = 0;
while (total < length)
@@ -66,11 +76,14 @@ tcp_send(RDPCLIENT * This, STREAM s)
if (sent <= 0)
{
// error("send: %s\n", strerror(errno)); // EOF
return;
This->disconnect_reason = 772;
return False;
}
total += sent;
}
return True;
}
/* Receive a message on the TCP layer */
@@ -85,7 +98,15 @@ tcp_recv(RDPCLIENT * This, STREAM s, uint32 length)
/* read into "new" stream */
if (length > This->tcp.in.size)
{
This->tcp.in.data = (uint8 *) xrealloc(This->tcp.in.data, length);
void * p = realloc(This->tcp.in.data, length);
if(p == NULL)
{
This->disconnect_reason = 262;
return NULL;
}
This->tcp.in.data = (uint8 *) p;
This->tcp.in.size = length;
}
This->tcp.in.end = This->tcp.in.p = This->tcp.in.data;
@@ -94,12 +115,20 @@ tcp_recv(RDPCLIENT * This, STREAM s, uint32 length)
else
{
/* append to existing stream */
new_length = (s->end - s->data) + length;
new_length = (unsigned int)(s->end - s->data) + length;
if (new_length > s->size)
{
p_offset = s->p - s->data;
end_offset = s->end - s->data;
s->data = (uint8 *) xrealloc(s->data, new_length);
void * p = realloc(s->data, new_length);
if(p == NULL)
{
This->disconnect_reason = 262;
return NULL;
}
p_offset = (unsigned int)(s->p - s->data);
end_offset = (unsigned int)(s->end - s->data);
s->data = (uint8 *) p;
s->size = new_length;
s->p = s->data + p_offset;
s->end = s->data + end_offset;
@@ -116,11 +145,13 @@ tcp_recv(RDPCLIENT * This, STREAM s, uint32 length)
if (rcvd < 0)
{
// error("recv: %s\n", strerror(errno)); // EOF
This->disconnect_reason = 1028;
return NULL;
}
else if (rcvd == 0)
{
error("Connection closed\n");
This->disconnect_reason = 2308;
return NULL;
}
@@ -189,6 +220,7 @@ tcp_connect(RDPCLIENT * This, char *server)
else if ((servaddr.sin_addr.s_addr = inet_addr(server)) == INADDR_NONE)
{
error("%s: unable to resolve host\n", server);
This->disconnect_reason = 260;
return False;
}
@@ -204,7 +236,8 @@ tcp_connect(RDPCLIENT * This, char *server)
if (connect(This->tcp.sock, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) < 0)
{
// error("connect: %s\n", strerror(errno)); // EOF
close(This->tcp.sock);
This->disconnect_reason = 516;
closesocket(This->tcp.sock);
return False;
}
@@ -213,24 +246,38 @@ tcp_connect(RDPCLIENT * This, char *server)
setsockopt(This->tcp.sock, IPPROTO_TCP, TCP_NODELAY, (void *) &true_value, sizeof(true_value));
This->tcp.in.size = 4096;
This->tcp.in.data = (uint8 *) xmalloc(This->tcp.in.size);
This->tcp.in.data = (uint8 *) malloc(This->tcp.in.size);
if(This->tcp.in.data == NULL)
{
This->disconnect_reason = 262;
return False;
}
This->tcp.out.size = 4096;
This->tcp.out.data = (uint8 *) xmalloc(This->tcp.out.size);
This->tcp.out.data = (uint8 *) malloc(This->tcp.out.size);
if(This->tcp.out.data == NULL)
{
This->disconnect_reason = 262;
return False;
}
return True;
}
/* Disconnect on the TCP layer */
void
BOOL
tcp_disconnect(RDPCLIENT * This)
{
close(This->tcp.sock);
closesocket(This->tcp.sock);
return True;
}
char *
wchar_t *
tcp_get_address(RDPCLIENT * This)
{
#if 0
static char ipaddr[32];
struct sockaddr_in sockaddr;
socklen_t len = sizeof(sockaddr);
@@ -242,6 +289,8 @@ tcp_get_address(RDPCLIENT * This)
else
strcpy(ipaddr, "127.0.0.1");
return ipaddr;
#endif
return NULL; // TODO
}
/* reset the state of the tcp layer */
@@ -253,7 +302,7 @@ tcp_reset_state(RDPCLIENT * This)
/* Clear the incoming stream */
if (This->tcp.in.data != NULL)
xfree(This->tcp.in.data);
free(This->tcp.in.data);
This->tcp.in.p = NULL;
This->tcp.in.end = NULL;
This->tcp.in.data = NULL;
@@ -266,7 +315,7 @@ tcp_reset_state(RDPCLIENT * This)
/* Clear the outgoing stream */
if (This->tcp.out.data != NULL)
xfree(This->tcp.out.data);
free(This->tcp.out.data);
This->tcp.out.p = NULL;
This->tcp.out.end = NULL;
This->tcp.out.data = NULL;