|
|
|
@ -1,7 +1,7 @@
|
|
|
|
|
/**
|
|
|
|
|
* xrdp: A Remote Desktop Protocol server.
|
|
|
|
|
*
|
|
|
|
|
* Copyright (C) Jay Sorg 2004-2013
|
|
|
|
|
* Copyright (C) Jay Sorg 2004-2015
|
|
|
|
|
*
|
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
@ -20,6 +20,7 @@
|
|
|
|
|
|
|
|
|
|
#include "vnc.h"
|
|
|
|
|
#include "log.h"
|
|
|
|
|
#include "trans.h"
|
|
|
|
|
|
|
|
|
|
#define LLOG_LEVEL 1
|
|
|
|
|
#define LLOGLN(_level, _args) \
|
|
|
|
@ -35,6 +36,16 @@
|
|
|
|
|
|
|
|
|
|
#define AS_LOG_MESSAGE log_message
|
|
|
|
|
|
|
|
|
|
static int APP_CC
|
|
|
|
|
lib_mod_process_message(struct vnc *v, struct stream *s);
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
static int APP_CC
|
|
|
|
|
lib_send_copy(struct vnc *v, struct stream *s)
|
|
|
|
|
{
|
|
|
|
|
return trans_write_copy_s(v->trans, s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
/* taken from vncauth.c */
|
|
|
|
|
void DEFAULT_CC
|
|
|
|
@ -50,101 +61,6 @@ rfbEncryptBytes(char *bytes, char *passwd)
|
|
|
|
|
rfbDes((unsigned char *)(bytes + 8), (unsigned char *)(bytes + 8));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
/* returns error */
|
|
|
|
|
int DEFAULT_CC
|
|
|
|
|
lib_recv(struct vnc *v, char *data, int len)
|
|
|
|
|
{
|
|
|
|
|
int rcvd;
|
|
|
|
|
|
|
|
|
|
if (v->sck_closed)
|
|
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (len > 0)
|
|
|
|
|
{
|
|
|
|
|
rcvd = g_tcp_recv(v->sck, data, len, 0);
|
|
|
|
|
|
|
|
|
|
if (rcvd == -1)
|
|
|
|
|
{
|
|
|
|
|
if (g_tcp_last_error_would_block(v->sck))
|
|
|
|
|
{
|
|
|
|
|
if (v->server_is_term(v))
|
|
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_tcp_can_recv(v->sck, 10);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
log_message(LOG_LEVEL_DEBUG, "VNC lib_recv return 1");
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (rcvd == 0)
|
|
|
|
|
{
|
|
|
|
|
v->sck_closed = 1;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
data += rcvd;
|
|
|
|
|
len -= rcvd;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
/* returns error */
|
|
|
|
|
int DEFAULT_CC
|
|
|
|
|
lib_send(struct vnc *v, char *data, int len)
|
|
|
|
|
{
|
|
|
|
|
int sent;
|
|
|
|
|
|
|
|
|
|
if (v->sck_closed)
|
|
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (len > 0)
|
|
|
|
|
{
|
|
|
|
|
sent = g_tcp_send(v->sck, data, len, 0);
|
|
|
|
|
|
|
|
|
|
if (sent == -1)
|
|
|
|
|
{
|
|
|
|
|
if (g_tcp_last_error_would_block(v->sck))
|
|
|
|
|
{
|
|
|
|
|
if (v->server_is_term(v))
|
|
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_tcp_can_send(v->sck, 10);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (sent == 0)
|
|
|
|
|
{
|
|
|
|
|
v->sck_closed = 1;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
data += sent;
|
|
|
|
|
len -= sent;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
static int DEFAULT_CC
|
|
|
|
|
lib_process_channel_data(struct vnc *v, int chanid, int flags, int size,
|
|
|
|
@ -153,6 +69,7 @@ lib_process_channel_data(struct vnc *v, int chanid, int flags, int size,
|
|
|
|
|
int type;
|
|
|
|
|
int status;
|
|
|
|
|
int length;
|
|
|
|
|
int clip_bytes;
|
|
|
|
|
int index;
|
|
|
|
|
int format;
|
|
|
|
|
struct stream *out_s;
|
|
|
|
@ -170,6 +87,18 @@ lib_process_channel_data(struct vnc *v, int chanid, int flags, int size,
|
|
|
|
|
case 2: /* CLIPRDR_FORMAT_ANNOUNCE */
|
|
|
|
|
AS_LOG_MESSAGE(LOG_LEVEL_DEBUG, "CLIPRDR_FORMAT_ANNOUNCE - "
|
|
|
|
|
"status %d length %d", status, length);
|
|
|
|
|
make_stream(out_s);
|
|
|
|
|
init_stream(out_s, 8192);
|
|
|
|
|
out_uint16_le(out_s, 3); // msg-type: CLIPRDR_FORMAT_ACK
|
|
|
|
|
out_uint16_le(out_s, 1); // msg-status-code: CLIPRDR_RESPONSE
|
|
|
|
|
out_uint32_le(out_s, 0); // null (?)
|
|
|
|
|
out_uint8s(out_s, 4); // pad
|
|
|
|
|
s_mark_end(out_s);
|
|
|
|
|
length = (int)(out_s->end - out_s->data);
|
|
|
|
|
v->server_send_to_channel(v, v->clip_chanid, out_s->data,
|
|
|
|
|
length, length, 3);
|
|
|
|
|
free_stream(out_s);
|
|
|
|
|
#if 0
|
|
|
|
|
// Send the CLIPRDR_DATA_REQUEST message to the cliprdr channel.
|
|
|
|
|
//
|
|
|
|
|
make_stream(out_s);
|
|
|
|
@ -184,7 +113,9 @@ lib_process_channel_data(struct vnc *v, int chanid, int flags, int size,
|
|
|
|
|
v->server_send_to_channel(v, v->clip_chanid, out_s->data,
|
|
|
|
|
length, length, 3);
|
|
|
|
|
free_stream(out_s);
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 3: /* CLIPRDR_FORMAT_ACK */
|
|
|
|
|
AS_LOG_MESSAGE(LOG_LEVEL_DEBUG, "CLIPRDR_FORMAT_ACK - "
|
|
|
|
|
"status %d length %d", status, length);
|
|
|
|
@ -212,11 +143,11 @@ lib_process_channel_data(struct vnc *v, int chanid, int flags, int size,
|
|
|
|
|
|
|
|
|
|
if (format == 13) /* CF_UNICODETEXT */
|
|
|
|
|
{
|
|
|
|
|
out_uint32_le(out_s, v->clip_data_size * 2 + 2);
|
|
|
|
|
out_uint32_le(out_s, v->clip_data_s->size * 2 + 2);
|
|
|
|
|
|
|
|
|
|
for (index = 0; index < v->clip_data_size; index++)
|
|
|
|
|
for (index = 0; index < v->clip_data_s->size; index++)
|
|
|
|
|
{
|
|
|
|
|
out_uint8(out_s, v->clip_data[index]);
|
|
|
|
|
out_uint8(out_s, v->clip_data_s->data[index]);
|
|
|
|
|
out_uint8(out_s, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -224,11 +155,11 @@ lib_process_channel_data(struct vnc *v, int chanid, int flags, int size,
|
|
|
|
|
}
|
|
|
|
|
else if (format == 1) /* CF_TEXT */
|
|
|
|
|
{
|
|
|
|
|
out_uint32_le(out_s, v->clip_data_size + 1);
|
|
|
|
|
out_uint32_le(out_s, v->clip_data_s->size + 1);
|
|
|
|
|
|
|
|
|
|
for (index = 0; index < v->clip_data_size; index++)
|
|
|
|
|
for (index = 0; index < v->clip_data_s->size; index++)
|
|
|
|
|
{
|
|
|
|
|
out_uint8(out_s, v->clip_data[index]);
|
|
|
|
|
out_uint8(out_s, v->clip_data_s->data[index]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out_uint8s(out_s, 1);
|
|
|
|
@ -245,48 +176,26 @@ lib_process_channel_data(struct vnc *v, int chanid, int flags, int size,
|
|
|
|
|
case 5: /* CLIPRDR_DATA_RESPONSE */
|
|
|
|
|
AS_LOG_MESSAGE(LOG_LEVEL_DEBUG, "CLIPRDR_DATA_RESPONSE - "
|
|
|
|
|
"status %d length %d", status, length);
|
|
|
|
|
|
|
|
|
|
clip_bytes = MIN(length, 256);
|
|
|
|
|
// - Read the response data from the cliprdr channel, stream 's'.
|
|
|
|
|
// - Send the response data to the vnc server, stream 'out_s'.
|
|
|
|
|
//
|
|
|
|
|
make_stream(out_s);
|
|
|
|
|
|
|
|
|
|
// Send the RFB message type (CLIENT_CUT_TEXT) to the vnc server.
|
|
|
|
|
init_stream(out_s, 8192);
|
|
|
|
|
init_stream(out_s, clip_bytes + 1 + 3 + 4 + 16);
|
|
|
|
|
out_uint8(out_s, 6); // RFB msg type: CLIENT_CUT_TEXT
|
|
|
|
|
out_uint8s(out_s, 3); // padding
|
|
|
|
|
lib_send(v, out_s->data, 4);
|
|
|
|
|
|
|
|
|
|
// Send the length of the cut-text to the vnc server.
|
|
|
|
|
init_stream(out_s, 8192);
|
|
|
|
|
out_uint32_be(out_s, length);
|
|
|
|
|
lib_send(v, out_s->data, 4);
|
|
|
|
|
|
|
|
|
|
out_uint32_be(out_s, clip_bytes);
|
|
|
|
|
// Send the cut-text (as read from 's') to the vnc server.
|
|
|
|
|
init_stream(out_s, 8192);
|
|
|
|
|
for (index = 0; index < length; index++)
|
|
|
|
|
for (index = 0; index < clip_bytes; index++)
|
|
|
|
|
{
|
|
|
|
|
char cur_char = '\0';
|
|
|
|
|
in_uint8(s, cur_char); // text in from 's'
|
|
|
|
|
out_uint8(out_s, cur_char); // text out to 'out_s'
|
|
|
|
|
}
|
|
|
|
|
lib_send(v, out_s->data, length);
|
|
|
|
|
|
|
|
|
|
free_stream(out_s);
|
|
|
|
|
|
|
|
|
|
// Now send a CLIPRDR_FORMAT_ACK to the cliprdr channel.
|
|
|
|
|
// This seems to be necessary for bi-directional copy/paste.
|
|
|
|
|
//
|
|
|
|
|
make_stream(out_s);
|
|
|
|
|
init_stream(out_s, 8192);
|
|
|
|
|
out_uint16_le(out_s, 3); // msg-type: CLIPRDR_FORMAT_ACK
|
|
|
|
|
out_uint16_le(out_s, 1); // msg-status-code: CLIPRDR_RESPONSE
|
|
|
|
|
out_uint32_le(out_s, 0); // null (?)
|
|
|
|
|
out_uint8s(out_s, 4); // pad
|
|
|
|
|
s_mark_end(out_s);
|
|
|
|
|
length = (int)(out_s->end - out_s->data);
|
|
|
|
|
v->server_send_to_channel(v, v->clip_chanid, out_s->data,
|
|
|
|
|
length, length, 3);
|
|
|
|
|
lib_send_copy(v, out_s);
|
|
|
|
|
free_stream(out_s);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
@ -364,7 +273,8 @@ lib_mod_event(struct vnc *v, int msg, long param1, long param2,
|
|
|
|
|
out_uint8(s, 0); /* down flag */
|
|
|
|
|
out_uint8s(s, 2);
|
|
|
|
|
out_uint32_be(s, 65507); /* left control */
|
|
|
|
|
lib_send(v, s->data, 8);
|
|
|
|
|
s_mark_end(s);
|
|
|
|
|
lib_send_copy(v, s);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -373,7 +283,8 @@ lib_mod_event(struct vnc *v, int msg, long param1, long param2,
|
|
|
|
|
out_uint8(s, msg == 15); /* down flag */
|
|
|
|
|
out_uint8s(s, 2);
|
|
|
|
|
out_uint32_be(s, key);
|
|
|
|
|
error = lib_send(v, s->data, 8);
|
|
|
|
|
s_mark_end(s);
|
|
|
|
|
error = lib_send_copy(v, s);
|
|
|
|
|
|
|
|
|
|
if (key == 65507) /* left control */
|
|
|
|
|
{
|
|
|
|
@ -424,7 +335,8 @@ lib_mod_event(struct vnc *v, int msg, long param1, long param2,
|
|
|
|
|
out_uint8(s, v->mod_mouse_state);
|
|
|
|
|
out_uint16_be(s, param1);
|
|
|
|
|
out_uint16_be(s, param2);
|
|
|
|
|
error = lib_send(v, s->data, 6);
|
|
|
|
|
s_mark_end(s);
|
|
|
|
|
error = lib_send_copy(v, s);
|
|
|
|
|
}
|
|
|
|
|
else if (msg == 200) /* invalidate */
|
|
|
|
|
{
|
|
|
|
@ -440,7 +352,8 @@ lib_mod_event(struct vnc *v, int msg, long param1, long param2,
|
|
|
|
|
out_uint16_be(s, cx);
|
|
|
|
|
cy = param2 & 0xffff;
|
|
|
|
|
out_uint16_be(s, cy);
|
|
|
|
|
error = lib_send(v, s->data, 10);
|
|
|
|
|
s_mark_end(s);
|
|
|
|
|
error = lib_send_copy(v, s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free_stream(s);
|
|
|
|
@ -634,7 +547,6 @@ make_color(int r, int g, int b, int bpp)
|
|
|
|
|
int DEFAULT_CC
|
|
|
|
|
lib_framebuffer_update(struct vnc *v)
|
|
|
|
|
{
|
|
|
|
|
char *data;
|
|
|
|
|
char *d1;
|
|
|
|
|
char *d2;
|
|
|
|
|
char cursor_data[32 * (32 * 3)];
|
|
|
|
@ -656,13 +568,11 @@ lib_framebuffer_update(struct vnc *v)
|
|
|
|
|
int r;
|
|
|
|
|
int g;
|
|
|
|
|
int b;
|
|
|
|
|
int data_size;
|
|
|
|
|
int need_size;
|
|
|
|
|
int error;
|
|
|
|
|
int need_size;
|
|
|
|
|
struct stream *s;
|
|
|
|
|
struct stream *pixel_s;
|
|
|
|
|
|
|
|
|
|
data_size = 0;
|
|
|
|
|
data = 0;
|
|
|
|
|
num_recs = 0;
|
|
|
|
|
Bpp = (v->mod_bpp + 7) / 8;
|
|
|
|
|
|
|
|
|
@ -671,9 +581,11 @@ lib_framebuffer_update(struct vnc *v)
|
|
|
|
|
Bpp = 4;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
make_stream(pixel_s);
|
|
|
|
|
|
|
|
|
|
make_stream(s);
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
error = lib_recv(v, s->data, 3);
|
|
|
|
|
error = trans_force_read_s(v->trans, s, 3);
|
|
|
|
|
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
@ -690,7 +602,7 @@ lib_framebuffer_update(struct vnc *v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
error = lib_recv(v, s->data, 12);
|
|
|
|
|
error = trans_force_read_s(v->trans, s, 12);
|
|
|
|
|
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
@ -703,25 +615,18 @@ lib_framebuffer_update(struct vnc *v)
|
|
|
|
|
if (encoding == 0) /* raw */
|
|
|
|
|
{
|
|
|
|
|
need_size = cx * cy * Bpp;
|
|
|
|
|
|
|
|
|
|
if (need_size > data_size)
|
|
|
|
|
{
|
|
|
|
|
g_free(data);
|
|
|
|
|
data = (char *)g_malloc(need_size, 0);
|
|
|
|
|
data_size = need_size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
error = lib_recv(v, data, need_size);
|
|
|
|
|
init_stream(pixel_s, need_size);
|
|
|
|
|
error = trans_force_read_s(v->trans, pixel_s, need_size);
|
|
|
|
|
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
error = v->server_paint_rect(v, x, y, cx, cy, data, cx, cy, 0, 0);
|
|
|
|
|
error = v->server_paint_rect(v, x, y, cx, cy, pixel_s->data, cx, cy, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (encoding == 1) /* copy rect */
|
|
|
|
|
{
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
error = lib_recv(v, s->data, 4);
|
|
|
|
|
error = trans_force_read_s(v->trans, s, 4);
|
|
|
|
|
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
@ -737,7 +642,7 @@ lib_framebuffer_update(struct vnc *v)
|
|
|
|
|
j = cx * cy * Bpp;
|
|
|
|
|
k = ((cx + 7) / 8) * cy;
|
|
|
|
|
init_stream(s, j + k);
|
|
|
|
|
error = lib_recv(v, s->data, j + k);
|
|
|
|
|
error = trans_force_read_s(v->trans, s, j + k);
|
|
|
|
|
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
@ -795,8 +700,6 @@ lib_framebuffer_update(struct vnc *v)
|
|
|
|
|
error = v->server_end_update(v);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_free(data);
|
|
|
|
|
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
/* FrambufferUpdateRequest */
|
|
|
|
@ -807,14 +710,17 @@ lib_framebuffer_update(struct vnc *v)
|
|
|
|
|
out_uint16_be(s, 0);
|
|
|
|
|
out_uint16_be(s, v->mod_width);
|
|
|
|
|
out_uint16_be(s, v->mod_height);
|
|
|
|
|
error = lib_send(v, s->data, 10);
|
|
|
|
|
s_mark_end(s);
|
|
|
|
|
error = lib_send_copy(v, s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free_stream(s);
|
|
|
|
|
free_stream(pixel_s);
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
/* clip data from the vnc server */
|
|
|
|
|
int DEFAULT_CC
|
|
|
|
|
lib_clip_data(struct vnc *v)
|
|
|
|
|
{
|
|
|
|
@ -823,20 +729,19 @@ lib_clip_data(struct vnc *v)
|
|
|
|
|
int size;
|
|
|
|
|
int error;
|
|
|
|
|
|
|
|
|
|
g_free(v->clip_data);
|
|
|
|
|
v->clip_data = 0;
|
|
|
|
|
v->clip_data_size = 0;
|
|
|
|
|
free_stream(v->clip_data_s);
|
|
|
|
|
v->clip_data_s = 0;
|
|
|
|
|
make_stream(s);
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
error = lib_recv(v, s->data, 7);
|
|
|
|
|
error = trans_force_read_s(v->trans, s, 7);
|
|
|
|
|
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
in_uint8s(s, 3);
|
|
|
|
|
in_uint32_be(s, size);
|
|
|
|
|
v->clip_data = (char *)g_malloc(size, 0);
|
|
|
|
|
v->clip_data_size = size;
|
|
|
|
|
error = lib_recv(v, v->clip_data, size);
|
|
|
|
|
make_stream(v->clip_data_s);
|
|
|
|
|
init_stream(v->clip_data_s, size);
|
|
|
|
|
error = trans_force_read_s(v->trans, v->clip_data_s, size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (error == 0)
|
|
|
|
@ -880,7 +785,7 @@ lib_palette_update(struct vnc *v)
|
|
|
|
|
|
|
|
|
|
make_stream(s);
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
error = lib_recv(v, s->data, 5);
|
|
|
|
|
error = trans_force_read_s(v->trans, s, 5);
|
|
|
|
|
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
@ -888,7 +793,7 @@ lib_palette_update(struct vnc *v)
|
|
|
|
|
in_uint16_be(s, first_color);
|
|
|
|
|
in_uint16_be(s, num_colors);
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
error = lib_recv(v, s->data, num_colors * 6);
|
|
|
|
|
error = trans_force_read_s(v->trans, s, num_colors * 6);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (error == 0)
|
|
|
|
@ -934,13 +839,22 @@ lib_bell_trigger(struct vnc *v)
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
int DEFAULT_CC
|
|
|
|
|
lib_mod_signal(struct vnc *v)
|
|
|
|
|
{
|
|
|
|
|
g_writeln("lib_mod_signal: not used");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
static int APP_CC
|
|
|
|
|
lib_mod_process_message(struct vnc *v, struct stream *s)
|
|
|
|
|
{
|
|
|
|
|
char type;
|
|
|
|
|
int error;
|
|
|
|
|
char text[256];
|
|
|
|
|
|
|
|
|
|
error = lib_recv(v, &type, 1);
|
|
|
|
|
in_uint8(s, type);
|
|
|
|
|
|
|
|
|
|
error = 0;
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
if (type == 0) /* framebuffer update */
|
|
|
|
@ -1000,6 +914,39 @@ lib_open_clip_channel(struct vnc *v)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
static int APP_CC
|
|
|
|
|
lib_data_in(struct trans *trans)
|
|
|
|
|
{
|
|
|
|
|
struct vnc *self;
|
|
|
|
|
struct stream *s;
|
|
|
|
|
|
|
|
|
|
LLOGLN(10, ("lib_data_in:"));
|
|
|
|
|
|
|
|
|
|
if (trans == 0)
|
|
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
self = (struct vnc *)(trans->callback_data);
|
|
|
|
|
s = trans_get_in_s(trans);
|
|
|
|
|
|
|
|
|
|
if (s == 0)
|
|
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (lib_mod_process_message(self, s) != 0)
|
|
|
|
|
{
|
|
|
|
|
g_writeln("lib_data_in: lib_mod_process_message failed");
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
init_stream(s, 0);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
/*
|
|
|
|
|
return error
|
|
|
|
@ -1016,6 +963,7 @@ lib_mod_connect(struct vnc *v)
|
|
|
|
|
int error;
|
|
|
|
|
int i;
|
|
|
|
|
int check_sec_result;
|
|
|
|
|
struct source_info *si;
|
|
|
|
|
|
|
|
|
|
v->server_msg(v, "VNC started connecting", 0);
|
|
|
|
|
check_sec_result = 1;
|
|
|
|
@ -1039,16 +987,15 @@ lib_mod_connect(struct vnc *v)
|
|
|
|
|
g_sprintf(con_port, "%s", v->port);
|
|
|
|
|
make_stream(pixel_format);
|
|
|
|
|
|
|
|
|
|
v->sck = g_tcp_socket();
|
|
|
|
|
if (v->sck < 0)
|
|
|
|
|
v->trans = trans_create(TRANS_MODE_TCP, 8 * 8192, 8192);
|
|
|
|
|
if (v->trans == 0)
|
|
|
|
|
{
|
|
|
|
|
v->server_msg(v, "VNC error: socket create error, g_tcp_socket() failed", 0);
|
|
|
|
|
v->server_msg(v, "VNC error: trans_create() failed", 0);
|
|
|
|
|
free_stream(s);
|
|
|
|
|
free_stream(pixel_format);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
v->sck_obj = g_create_wait_obj_from_socket(v->sck, 0);
|
|
|
|
|
v->sck_closed = 0;
|
|
|
|
|
if (v->delay_ms > 0)
|
|
|
|
|
{
|
|
|
|
@ -1059,27 +1006,32 @@ lib_mod_connect(struct vnc *v)
|
|
|
|
|
|
|
|
|
|
g_sprintf(text, "VNC connecting to %s %s", v->ip, con_port);
|
|
|
|
|
v->server_msg(v, text, 0);
|
|
|
|
|
error = g_tcp_connect(v->sck, v->ip, con_port);
|
|
|
|
|
|
|
|
|
|
si = (struct source_info *) (v->si);
|
|
|
|
|
v->trans->si = si;
|
|
|
|
|
v->trans->my_source = XRDP_SOURCE_MOD;
|
|
|
|
|
|
|
|
|
|
error = trans_connect(v->trans, v->ip, con_port, 3000);
|
|
|
|
|
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
v->server_msg(v, "VNC tcp connected", 0);
|
|
|
|
|
g_tcp_set_non_blocking(v->sck);
|
|
|
|
|
g_tcp_set_no_delay(v->sck);
|
|
|
|
|
/* protocal version */
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
error = lib_recv(v, s->data, 12);
|
|
|
|
|
|
|
|
|
|
error = trans_force_read_s(v->trans, s, 12);
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
error = lib_send(v, "RFB 003.003\n", 12);
|
|
|
|
|
s->p = s->data;
|
|
|
|
|
out_uint8a(s, "RFB 003.003\n", 12);
|
|
|
|
|
s_mark_end(s);
|
|
|
|
|
error = trans_force_write_s(v->trans, s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* sec type */
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
error = lib_recv(v, s->data, 4);
|
|
|
|
|
error = trans_force_read_s(v->trans, s, 4);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (error == 0)
|
|
|
|
@ -1095,12 +1047,15 @@ lib_mod_connect(struct vnc *v)
|
|
|
|
|
else if (i == 2) /* dec the password and the server random */
|
|
|
|
|
{
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
error = lib_recv(v, s->data, 16);
|
|
|
|
|
error = trans_force_read_s(v->trans, s, 16);
|
|
|
|
|
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
rfbEncryptBytes(s->data, v->password);
|
|
|
|
|
error = lib_send(v, s->data, 16);
|
|
|
|
|
s->p += 16;
|
|
|
|
|
s_mark_end(s);
|
|
|
|
|
error = trans_force_write_s(v->trans, s);
|
|
|
|
|
check_sec_result = 1; // not needed
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1126,7 +1081,7 @@ lib_mod_connect(struct vnc *v)
|
|
|
|
|
{
|
|
|
|
|
/* sec result */
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
error = lib_recv(v, s->data, 4);
|
|
|
|
|
error = trans_force_read_s(v->trans, s, 4);
|
|
|
|
|
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
@ -1149,7 +1104,9 @@ lib_mod_connect(struct vnc *v)
|
|
|
|
|
v->server_msg(v, "VNC sending share flag", 0);
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
s->data[0] = 1;
|
|
|
|
|
error = lib_send(v, s->data, 1); /* share flag */
|
|
|
|
|
s->p++;
|
|
|
|
|
s_mark_end(s);
|
|
|
|
|
error = trans_force_write_s(v->trans, s); /* share flag */
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@ -1159,7 +1116,8 @@ lib_mod_connect(struct vnc *v)
|
|
|
|
|
if (error == 0)
|
|
|
|
|
{
|
|
|
|
|
v->server_msg(v, "VNC receiving server init", 0);
|
|
|
|
|
error = lib_recv(v, s->data, 4); /* server init */
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
error = trans_force_read_s(v->trans, s, 4); /* server init */
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@ -1172,7 +1130,7 @@ lib_mod_connect(struct vnc *v)
|
|
|
|
|
in_uint16_be(s, v->mod_height);
|
|
|
|
|
init_stream(pixel_format, 8192);
|
|
|
|
|
v->server_msg(v, "VNC receiving pixel format", 0);
|
|
|
|
|
error = lib_recv(v, pixel_format->data, 16);
|
|
|
|
|
error = trans_force_read_s(v->trans, pixel_format, 16);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@ -1184,7 +1142,7 @@ lib_mod_connect(struct vnc *v)
|
|
|
|
|
v->mod_bpp = v->server_bpp;
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
v->server_msg(v, "VNC receiving name length", 0);
|
|
|
|
|
error = lib_recv(v, s->data, 4); /* name len */
|
|
|
|
|
error = trans_force_read_s(v->trans, s, 4); /* name len */
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@ -1201,8 +1159,10 @@ lib_mod_connect(struct vnc *v)
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
init_stream(s, 8192);
|
|
|
|
|
v->server_msg(v, "VNC receiving name", 0);
|
|
|
|
|
error = lib_recv(v, v->mod_name, i);
|
|
|
|
|
error = trans_force_read_s(v->trans, s, i); /* name len */
|
|
|
|
|
g_memcpy(v->mod_name, s->data, i);
|
|
|
|
|
v->mod_name[i] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1297,7 +1257,8 @@ lib_mod_connect(struct vnc *v)
|
|
|
|
|
|
|
|
|
|
out_uint8a(s, pixel_format->data, 16);
|
|
|
|
|
v->server_msg(v, "VNC sending pixel format", 0);
|
|
|
|
|
error = lib_send(v, s->data, 20);
|
|
|
|
|
s_mark_end(s);
|
|
|
|
|
error = trans_force_write_s(v->trans, s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (error == 0)
|
|
|
|
@ -1312,7 +1273,8 @@ lib_mod_connect(struct vnc *v)
|
|
|
|
|
out_uint32_be(s, 0xffffff11); /* cursor */
|
|
|
|
|
out_uint32_be(s, 0xffffff21); /* desktop size */
|
|
|
|
|
v->server_msg(v, "VNC sending encodings", 0);
|
|
|
|
|
error = lib_send(v, s->data, 4 + 4 * 4);
|
|
|
|
|
s_mark_end(s);
|
|
|
|
|
error = trans_force_write_s(v->trans, s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (error == 0)
|
|
|
|
@ -1331,7 +1293,8 @@ lib_mod_connect(struct vnc *v)
|
|
|
|
|
out_uint16_be(s, v->mod_width);
|
|
|
|
|
out_uint16_be(s, v->mod_height);
|
|
|
|
|
v->server_msg(v, "VNC sending framebuffer update request", 0);
|
|
|
|
|
error = lib_send(v, s->data, 10);
|
|
|
|
|
s_mark_end(s);
|
|
|
|
|
error = trans_force_write_s(v->trans, s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (error == 0)
|
|
|
|
@ -1368,6 +1331,22 @@ lib_mod_connect(struct vnc *v)
|
|
|
|
|
v->server_msg(v, "VNC error - problem connecting", 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (error != 0)
|
|
|
|
|
{
|
|
|
|
|
trans_delete(v->trans);
|
|
|
|
|
v->trans = 0;
|
|
|
|
|
v->server_msg(v, "some problem", 0);
|
|
|
|
|
LIB_DEBUG(mod, "out lib_mod_connect error");
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
v->server_msg(v, "connected ok", 0);
|
|
|
|
|
v->trans->trans_data_in = lib_data_in;
|
|
|
|
|
v->trans->header_size = 1;
|
|
|
|
|
v->trans->callback_data = v;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1379,9 +1358,7 @@ lib_mod_end(struct vnc *v)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_free(v->clip_data);
|
|
|
|
|
v->clip_data = 0;
|
|
|
|
|
v->clip_data_size = 0;
|
|
|
|
|
free_stream(v->clip_data_s);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1423,19 +1400,17 @@ int DEFAULT_CC
|
|
|
|
|
lib_mod_get_wait_objs(struct vnc *v, tbus *read_objs, int *rcount,
|
|
|
|
|
tbus *write_objs, int *wcount, int *timeout)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
i = *rcount;
|
|
|
|
|
LLOGLN(10, ("lib_mod_get_wait_objs:"));
|
|
|
|
|
|
|
|
|
|
if (v != 0)
|
|
|
|
|
{
|
|
|
|
|
if (v->sck_obj != 0)
|
|
|
|
|
if (v->trans != 0)
|
|
|
|
|
{
|
|
|
|
|
read_objs[i++] = v->sck_obj;
|
|
|
|
|
trans_get_wait_objs_rw(v->trans, read_objs, rcount,
|
|
|
|
|
write_objs, wcount);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*rcount = i;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1447,18 +1422,13 @@ lib_mod_check_wait_objs(struct vnc *v)
|
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
|
|
rv = 0;
|
|
|
|
|
|
|
|
|
|
if (v != 0)
|
|
|
|
|
{
|
|
|
|
|
if (v->sck_obj != 0)
|
|
|
|
|
if (v->trans != 0)
|
|
|
|
|
{
|
|
|
|
|
if (g_is_wait_obj_set(v->sck_obj))
|
|
|
|
|
{
|
|
|
|
|
rv = lib_mod_signal(v);
|
|
|
|
|
}
|
|
|
|
|
rv = trans_check_wait_objs(v->trans);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1494,9 +1464,7 @@ mod_exit(struct vnc *v)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_delete_wait_obj_from_socket(v->sck_obj);
|
|
|
|
|
g_tcp_close(v->sck);
|
|
|
|
|
trans_delete(v->trans);
|
|
|
|
|
g_free(v);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|