diff options
author | Laxmikant Rashinkar <LK.Rashinkar@gmail.com> | 2012-09-19 20:51:34 -0700 |
---|---|---|
committer | Laxmikant Rashinkar <LK.Rashinkar@gmail.com> | 2012-09-19 20:51:34 -0700 |
commit | 1123323fda6d128fb98b0427e0ea5f6a2dc9e632 (patch) | |
tree | 3407a3771a069f812554312ce7c36db625139cc2 /vnc | |
parent | 3cedfae76a2351bc8b1e5bd2ee33bbf8630dbacf (diff) | |
download | xrdp-proprietary-1123323fda6d128fb98b0427e0ea5f6a2dc9e632.tar.gz xrdp-proprietary-1123323fda6d128fb98b0427e0ea5f6a2dc9e632.zip |
o moved from GNU General Public License to Apache License, Version 2.0
o applied new coding standards to all .c files
o moved some files around
Diffstat (limited to 'vnc')
-rw-r--r-- | vnc/vnc.c | 2279 | ||||
-rw-r--r-- | vnc/vnc.h | 40 |
2 files changed, 1224 insertions, 1095 deletions
@@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - libvnc - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * libvnc + */ #include "vnc.h" #include "log.h" @@ -26,814 +24,909 @@ /******************************************************************************/ /* taken from vncauth.c */ void DEFAULT_CC -rfbEncryptBytes(char* bytes, char* passwd) +rfbEncryptBytes(char *bytes, char *passwd) { - char key[12]; - - /* key is simply password padded with nulls */ - g_memset(key, 0, sizeof(key)); - g_strncpy(key, passwd, 8); - rfbDesKey((unsigned char*)key, EN0); /* 0, encrypt */ - rfbDes((unsigned char*)bytes, (unsigned char*)bytes); - rfbDes((unsigned char*)(bytes + 8), (unsigned char*)(bytes + 8)); + char key[12]; + + /* key is simply password padded with nulls */ + g_memset(key, 0, sizeof(key)); + g_strncpy(key, passwd, 8); + rfbDesKey((unsigned char *)key, EN0); /* 0, encrypt */ + rfbDes((unsigned char *)bytes, (unsigned char *)bytes); + rfbDes((unsigned char *)(bytes + 8), (unsigned char *)(bytes + 8)); } /******************************************************************************/ /* returns error */ int DEFAULT_CC -lib_recv(struct vnc* v, char* data, int len) +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) + int rcvd; + + if (v->sck_closed) { - v->sck_closed = 1; - return 1; + return 1; } - else + + while (len > 0) { - data += rcvd; - len -= rcvd; + 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; + + return 0; } /*****************************************************************************/ /* returns error */ int DEFAULT_CC -lib_send(struct vnc* v, char* data, int len) +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) + int sent; + + if (v->sck_closed) { - v->sck_closed = 1; - return 1; + return 1; } - else + + while (len > 0) { - data += sent; - len -= sent; - } - } - return 0; -} + sent = g_tcp_send(v->sck, data, len, 0); -/******************************************************************************/ -static int DEFAULT_CC -lib_process_channel_data(struct vnc* v, int chanid, int flags, int size, - struct stream* s, int total_size) -{ - int type; - int status; - int length; - int index; - int format; - struct stream* out_s; - - if (chanid == v->clip_chanid) - { - in_uint16_le(s, type); - in_uint16_le(s, status); - in_uint32_le(s, length); - //g_writeln("clip data type %d status %d length %d", type, status, length); - //g_hexdump(s->p, s->end - s->p); - switch (type) - { - case 2: /* CLIPRDR_FORMAT_ANNOUNCE */ - make_stream(out_s); - init_stream(out_s, 8192); - out_uint16_le(out_s, 3); - out_uint16_le(out_s, 1); - out_uint32_le(out_s, 0); - 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); - break; - case 3: /* CLIPRDR_FORMAT_ACK */ - break; - case 4: /* CLIPRDR_DATA_REQUEST */ - format = 0; - if (length >= 4) + if (sent == -1) { - in_uint32_le(s, format); + 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; + } } - /* only support CF_TEXT and CF_UNICODETEXT */ - if ((format != 1) && (format != 13)) + else if (sent == 0) { - break; + v->sck_closed = 1; + return 1; } - make_stream(out_s); - init_stream(out_s, 8192); - out_uint16_le(out_s, 5); - out_uint16_le(out_s, 1); - if (format == 13) /* CF_UNICODETEXT */ + else { - out_uint32_le(out_s, v->clip_data_size * 2 + 2); - for (index = 0; index < v->clip_data_size; index++) - { - out_uint8(out_s, v->clip_data[index]); - out_uint8(out_s, 0); - } - out_uint8s(out_s, 2); + data += sent; + len -= sent; } - else if (format == 1) /* CF_TEXT */ + } + + return 0; +} + +/******************************************************************************/ +static int DEFAULT_CC +lib_process_channel_data(struct vnc *v, int chanid, int flags, int size, + struct stream *s, int total_size) +{ + int type; + int status; + int length; + int index; + int format; + struct stream *out_s; + + if (chanid == v->clip_chanid) + { + in_uint16_le(s, type); + in_uint16_le(s, status); + in_uint32_le(s, length); + + //g_writeln("clip data type %d status %d length %d", type, status, length); + //g_hexdump(s->p, s->end - s->p); + switch (type) { - out_uint32_le(out_s, v->clip_data_size + 1); - for (index = 0; index < v->clip_data_size; index++) - { - out_uint8(out_s, v->clip_data[index]); - } - out_uint8s(out_s, 1); + case 2: /* CLIPRDR_FORMAT_ANNOUNCE */ + make_stream(out_s); + init_stream(out_s, 8192); + out_uint16_le(out_s, 3); + out_uint16_le(out_s, 1); + out_uint32_le(out_s, 0); + 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); + break; + case 3: /* CLIPRDR_FORMAT_ACK */ + break; + case 4: /* CLIPRDR_DATA_REQUEST */ + format = 0; + + if (length >= 4) + { + in_uint32_le(s, format); + } + + /* only support CF_TEXT and CF_UNICODETEXT */ + if ((format != 1) && (format != 13)) + { + break; + } + + make_stream(out_s); + init_stream(out_s, 8192); + out_uint16_le(out_s, 5); + out_uint16_le(out_s, 1); + + if (format == 13) /* CF_UNICODETEXT */ + { + out_uint32_le(out_s, v->clip_data_size * 2 + 2); + + for (index = 0; index < v->clip_data_size; index++) + { + out_uint8(out_s, v->clip_data[index]); + out_uint8(out_s, 0); + } + + out_uint8s(out_s, 2); + } + else if (format == 1) /* CF_TEXT */ + { + out_uint32_le(out_s, v->clip_data_size + 1); + + for (index = 0; index < v->clip_data_size; index++) + { + out_uint8(out_s, v->clip_data[index]); + } + + out_uint8s(out_s, 1); + } + + 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); + break; + default: + { + log_message(LOG_LEVEL_DEBUG, "VNC clip information unhandled"); + break; + } } - 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); - break; - default:{ - log_message(LOG_LEVEL_DEBUG, "VNC clip information unhandled"); - break; - } - } - } - else - { - log_message(LOG_LEVEL_DEBUG, "lib_process_channel_data: unknown chanid:", - "%d :(v->clip_chanid) %d",chanid,v->clip_chanid); - } - return 0; + } + else + { + log_message(LOG_LEVEL_DEBUG, "lib_process_channel_data: unknown chanid:", + "%d :(v->clip_chanid) %d", chanid, v->clip_chanid); + } + + return 0; } /******************************************************************************/ int DEFAULT_CC -lib_mod_event(struct vnc* v, int msg, long param1, long param2, +lib_mod_event(struct vnc *v, int msg, long param1, long param2, long param3, long param4) { - struct stream* s; - int key; - int error; - int x; - int y; - int cx; - int cy; - int size; - int total_size; - int chanid; - int flags; - char* data; - char text[256]; - - error = 0; - make_stream(s); - if (msg == 0x5555) /* channel data */ - { - chanid = LOWORD(param1); - flags = HIWORD(param1); - size = (int)param2; - data = (char*)param3; - total_size = (int)param4; - if ((size >= 0) && (size <= (32 * 1024)) && (data != 0)) - { - init_stream(s, size); - out_uint8a(s, data, size); - s_mark_end(s); - s->p = s->data; - error = lib_process_channel_data(v, chanid, flags, size, s, total_size); + struct stream *s; + int key; + int error; + int x; + int y; + int cx; + int cy; + int size; + int total_size; + int chanid; + int flags; + char *data; + char text[256]; + + error = 0; + make_stream(s); + + if (msg == 0x5555) /* channel data */ + { + chanid = LOWORD(param1); + flags = HIWORD(param1); + size = (int)param2; + data = (char *)param3; + total_size = (int)param4; + + if ((size >= 0) && (size <= (32 * 1024)) && (data != 0)) + { + init_stream(s, size); + out_uint8a(s, data, size); + s_mark_end(s); + s->p = s->data; + error = lib_process_channel_data(v, chanid, flags, size, s, total_size); + } + else + { + error = 1; + } } - else + else if ((msg >= 15) && (msg <= 16)) /* key events */ { - error = 1; + key = param2; + + if (key > 0) + { + if (key == 65027) /* altgr */ + { + if (v->shift_state) + { + /* fix for mstsc sending left control down with altgr */ + init_stream(s, 8192); + out_uint8(s, 4); + out_uint8(s, 0); /* down flag */ + out_uint8s(s, 2); + out_uint32_be(s, 65507); /* left control */ + lib_send(v, s->data, 8); + } + } + + init_stream(s, 8192); + out_uint8(s, 4); + out_uint8(s, msg == 15); /* down flag */ + out_uint8s(s, 2); + out_uint32_be(s, key); + error = lib_send(v, s->data, 8); + + if (key == 65507) /* left control */ + { + v->shift_state = msg == 15; + } + } } - } - else if ((msg >= 15) && (msg <= 16)) /* key events */ - { - key = param2; - if (key > 0) + else if (msg >= 100 && msg <= 110) /* mouse events */ { - if (key == 65027) /* altgr */ - { - if (v->shift_state) + switch (msg) { - /* fix for mstsc sending left control down with altgr */ - init_stream(s, 8192); - out_uint8(s, 4); - out_uint8(s, 0); /* down flag */ - out_uint8s(s, 2); - out_uint32_be(s, 65507); /* left control */ - lib_send(v, s->data, 8); + case 100: + break; /* WM_MOUSEMOVE */ + case 101: + v->mod_mouse_state &= ~1; + break; /* WM_LBUTTONUP */ + case 102: + v->mod_mouse_state |= 1; + break; /* WM_LBUTTONDOWN */ + case 103: + v->mod_mouse_state &= ~4; + break; /* WM_RBUTTONUP */ + case 104: + v->mod_mouse_state |= 4; + break; /* WM_RBUTTONDOWN */ + case 105: + v->mod_mouse_state &= ~2; + break; + case 106: + v->mod_mouse_state |= 2; + break; + case 107: + v->mod_mouse_state &= ~8; + break; + case 108: + v->mod_mouse_state |= 8; + break; + case 109: + v->mod_mouse_state &= ~16; + break; + case 110: + v->mod_mouse_state |= 16; + break; } - } - init_stream(s, 8192); - out_uint8(s, 4); - out_uint8(s, msg == 15); /* down flag */ - out_uint8s(s, 2); - out_uint32_be(s, key); - error = lib_send(v, s->data, 8); - if (key == 65507) /* left control */ - { - v->shift_state = msg == 15; - } - } - } - else if (msg >= 100 && msg <= 110) /* mouse events */ - { - switch (msg) - { - case 100: break; /* WM_MOUSEMOVE */ - case 101: v->mod_mouse_state &= ~1; break; /* WM_LBUTTONUP */ - case 102: v->mod_mouse_state |= 1; break; /* WM_LBUTTONDOWN */ - case 103: v->mod_mouse_state &= ~4; break; /* WM_RBUTTONUP */ - case 104: v->mod_mouse_state |= 4; break; /* WM_RBUTTONDOWN */ - case 105: v->mod_mouse_state &= ~2; break; - case 106: v->mod_mouse_state |= 2; break; - case 107: v->mod_mouse_state &= ~8; break; - case 108: v->mod_mouse_state |= 8; break; - case 109: v->mod_mouse_state &= ~16; break; - case 110: v->mod_mouse_state |= 16; break; + + init_stream(s, 8192); + out_uint8(s, 5); + out_uint8(s, v->mod_mouse_state); + out_uint16_be(s, param1); + out_uint16_be(s, param2); + error = lib_send(v, s->data, 6); } - init_stream(s, 8192); - out_uint8(s, 5); - out_uint8(s, v->mod_mouse_state); - out_uint16_be(s, param1); - out_uint16_be(s, param2); - error = lib_send(v, s->data, 6); - } - else if (msg == 200) /* invalidate */ - { - /* FrambufferUpdateRequest */ - init_stream(s, 8192); - out_uint8(s, 3); - out_uint8(s, 0); - x = (param1 >> 16) & 0xffff; - out_uint16_be(s, x); - y = param1 & 0xffff; - out_uint16_be(s, y); - cx = (param2 >> 16) & 0xffff; - out_uint16_be(s, cx); - cy = param2 & 0xffff; - out_uint16_be(s, cy); - error = lib_send(v, s->data, 10); - } - free_stream(s); - return error; + else if (msg == 200) /* invalidate */ + { + /* FrambufferUpdateRequest */ + init_stream(s, 8192); + out_uint8(s, 3); + out_uint8(s, 0); + x = (param1 >> 16) & 0xffff; + out_uint16_be(s, x); + y = param1 & 0xffff; + out_uint16_be(s, y); + cx = (param2 >> 16) & 0xffff; + out_uint16_be(s, cx); + cy = param2 & 0xffff; + out_uint16_be(s, cy); + error = lib_send(v, s->data, 10); + } + + free_stream(s); + return error; } //****************************************************************************** int DEFAULT_CC -get_pixel_safe(char* data, int x, int y, int width, int height, int bpp) +get_pixel_safe(char *data, int x, int y, int width, int height, int bpp) { - int start = 0; - int shift = 0; + int start = 0; + int shift = 0; - if (x < 0) - { - return 0; - } - if (y < 0) - { - return 0; - } - if (x >= width) - { - return 0; - } - if (y >= height) - { - return 0; - } - if (bpp == 1) - { - width = (width + 7) / 8; - start = (y * width) + x / 8; - shift = x % 8; - return (data[start] & (0x80 >> shift)) != 0; - } - else if (bpp == 4) - { - width = (width + 1) / 2; - start = y * width + x / 2; - shift = x % 2; - if (shift == 0) - { - return (data[start] & 0xf0) >> 4; + if (x < 0) + { + return 0; + } + + if (y < 0) + { + return 0; + } + + if (x >= width) + { + return 0; + } + + if (y >= height) + { + return 0; + } + + if (bpp == 1) + { + width = (width + 7) / 8; + start = (y * width) + x / 8; + shift = x % 8; + return (data[start] & (0x80 >> shift)) != 0; + } + else if (bpp == 4) + { + width = (width + 1) / 2; + start = y * width + x / 2; + shift = x % 2; + + if (shift == 0) + { + return (data[start] & 0xf0) >> 4; + } + else + { + return data[start] & 0x0f; + } + } + else if (bpp == 8) + { + return *(((unsigned char *)data) + (y * width + x)); + } + else if (bpp == 15 || bpp == 16) + { + return *(((unsigned short *)data) + (y * width + x)); + } + else if (bpp == 24 || bpp == 32) + { + return *(((unsigned int *)data) + (y * width + x)); } else { - return data[start] & 0x0f; - } - } - else if (bpp == 8) - { - return *(((unsigned char*)data) + (y * width + x)); - } - else if (bpp == 15 || bpp == 16) - { - return *(((unsigned short*)data) + (y * width + x)); - } - else if (bpp == 24 || bpp == 32) - { - return *(((unsigned int*)data) + (y * width + x)); - } - else - { - log_message(LOG_LEVEL_ERROR, "error in get_pixel_safe bpp %d", bpp); - } - return 0; + log_message(LOG_LEVEL_ERROR, "error in get_pixel_safe bpp %d", bpp); + } + + return 0; } /******************************************************************************/ void DEFAULT_CC -set_pixel_safe(char* data, int x, int y, int width, int height, int bpp, +set_pixel_safe(char *data, int x, int y, int width, int height, int bpp, int pixel) { - int start = 0; - int shift = 0; - - if (x < 0) - { - return; - } - if (y < 0) - { - return; - } - if (x >= width) - { - return; - } - if (y >= height) - { - return; - } - if (bpp == 1) - { - width = (width + 7) / 8; - start = (y * width) + x / 8; - shift = x % 8; - if (pixel & 1) - { - data[start] = data[start] | (0x80 >> shift); + int start = 0; + int shift = 0; + + if (x < 0) + { + return; + } + + if (y < 0) + { + return; + } + + if (x >= width) + { + return; + } + + if (y >= height) + { + return; + } + + if (bpp == 1) + { + width = (width + 7) / 8; + start = (y * width) + x / 8; + shift = x % 8; + + if (pixel & 1) + { + data[start] = data[start] | (0x80 >> shift); + } + else + { + data[start] = data[start] & ~(0x80 >> shift); + } + } + else if (bpp == 15 || bpp == 16) + { + *(((unsigned short *)data) + (y * width + x)) = pixel; + } + else if (bpp == 24) + { + *(data + (3 * (y * width + x)) + 0) = pixel >> 0; + *(data + (3 * (y * width + x)) + 1) = pixel >> 8; + *(data + (3 * (y * width + x)) + 2) = pixel >> 16; } else { - data[start] = data[start] & ~(0x80 >> shift); - } - } - else if (bpp == 15 || bpp == 16) - { - *(((unsigned short*)data) + (y * width + x)) = pixel; - } - else if (bpp == 24) - { - *(data + (3 * (y * width + x)) + 0) = pixel >> 0; - *(data + (3 * (y * width + x)) + 1) = pixel >> 8; - *(data + (3 * (y * width + x)) + 2) = pixel >> 16; - } - else - { - log_message(LOG_LEVEL_ERROR, "error in set_pixel_safe bpp %d", bpp); - } + log_message(LOG_LEVEL_ERROR, "error in set_pixel_safe bpp %d", bpp); + } } /******************************************************************************/ int DEFAULT_CC -split_color(int pixel, int* r, int* g, int* b, int bpp, int* palette) +split_color(int pixel, int *r, int *g, int *b, int bpp, int *palette) { - if (bpp == 8) - { - if (pixel >= 0 && pixel < 256 && palette != 0) - { - *r = (palette[pixel] >> 16) & 0xff; - *g = (palette[pixel] >> 8) & 0xff; - *b = (palette[pixel] >> 0) & 0xff; - } - } - else if (bpp == 15) - { - *r = ((pixel >> 7) & 0xf8) | ((pixel >> 12) & 0x7); - *g = ((pixel >> 2) & 0xf8) | ((pixel >> 8) & 0x7); - *b = ((pixel << 3) & 0xf8) | ((pixel >> 2) & 0x7); - } - else if (bpp == 16) - { - *r = ((pixel >> 8) & 0xf8) | ((pixel >> 13) & 0x7); - *g = ((pixel >> 3) & 0xfc) | ((pixel >> 9) & 0x3); - *b = ((pixel << 3) & 0xf8) | ((pixel >> 2) & 0x7); - } - else if (bpp == 24 || bpp == 32) - { - *r = (pixel >> 16) & 0xff; - *g = (pixel >> 8) & 0xff; - *b = pixel & 0xff; - } - else - { - log_message(LOG_LEVEL_ERROR, "error in split_color bpp %d", bpp); - } - return 0; + if (bpp == 8) + { + if (pixel >= 0 && pixel < 256 && palette != 0) + { + *r = (palette[pixel] >> 16) & 0xff; + *g = (palette[pixel] >> 8) & 0xff; + *b = (palette[pixel] >> 0) & 0xff; + } + } + else if (bpp == 15) + { + *r = ((pixel >> 7) & 0xf8) | ((pixel >> 12) & 0x7); + *g = ((pixel >> 2) & 0xf8) | ((pixel >> 8) & 0x7); + *b = ((pixel << 3) & 0xf8) | ((pixel >> 2) & 0x7); + } + else if (bpp == 16) + { + *r = ((pixel >> 8) & 0xf8) | ((pixel >> 13) & 0x7); + *g = ((pixel >> 3) & 0xfc) | ((pixel >> 9) & 0x3); + *b = ((pixel << 3) & 0xf8) | ((pixel >> 2) & 0x7); + } + else if (bpp == 24 || bpp == 32) + { + *r = (pixel >> 16) & 0xff; + *g = (pixel >> 8) & 0xff; + *b = pixel & 0xff; + } + else + { + log_message(LOG_LEVEL_ERROR, "error in split_color bpp %d", bpp); + } + + return 0; } /******************************************************************************/ int DEFAULT_CC make_color(int r, int g, int b, int bpp) { - if (bpp == 24) - { - return (r << 16) | (g << 8) | b; - } - else - { - log_message(LOG_LEVEL_ERROR, "error in make_color bpp %d", bpp); - } - return 0; + if (bpp == 24) + { + return (r << 16) | (g << 8) | b; + } + else + { + log_message(LOG_LEVEL_ERROR, "error in make_color bpp %d", bpp); + } + + return 0; } /******************************************************************************/ int DEFAULT_CC -lib_framebuffer_update(struct vnc* v) +lib_framebuffer_update(struct vnc *v) { - char* data; - char* d1; - char* d2; - char cursor_data[32 * (32 * 3)]; - char cursor_mask[32 * (32 / 8)]; - char text[256]; - int num_recs; - int i; - int j; - int k; - int x; - int y; - int cx; - int cy; - int srcx; - int srcy; - int encoding; - int Bpp; - int pixel; - int r; - int g; - int b; - int data_size; - int need_size; - int error; - struct stream* s; - - data_size = 0; - data = 0; - num_recs = 0; - Bpp = (v->mod_bpp + 7) / 8; - if (Bpp == 3) - { - Bpp = 4; - } - make_stream(s); - init_stream(s, 8192); - error = lib_recv(v, s->data, 3); - if (error == 0) - { - in_uint8s(s, 1); - in_uint16_be(s, num_recs); - error = v->server_begin_update(v); - } - for (i = 0; i < num_recs; i++) - { - if (error != 0) + char *data; + char *d1; + char *d2; + char cursor_data[32 * (32 * 3)]; + char cursor_mask[32 * (32 / 8)]; + char text[256]; + int num_recs; + int i; + int j; + int k; + int x; + int y; + int cx; + int cy; + int srcx; + int srcy; + int encoding; + int Bpp; + int pixel; + int r; + int g; + int b; + int data_size; + int need_size; + int error; + struct stream *s; + + data_size = 0; + data = 0; + num_recs = 0; + Bpp = (v->mod_bpp + 7) / 8; + + if (Bpp == 3) { - break; + Bpp = 4; } + + make_stream(s); init_stream(s, 8192); - error = lib_recv(v, s->data, 12); + error = lib_recv(v, s->data, 3); + if (error == 0) { - in_uint16_be(s, x); - in_uint16_be(s, y); - in_uint16_be(s, cx); - in_uint16_be(s, cy); - in_uint32_be(s, encoding); - 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); - if (error == 0) + in_uint8s(s, 1); + in_uint16_be(s, num_recs); + error = v->server_begin_update(v); + } + + for (i = 0; i < num_recs; i++) + { + if (error != 0) { - error = v->server_paint_rect(v, x, y, cx, cy, data, cx, cy, 0, 0); + break; } - } - else if (encoding == 1) /* copy rect */ - { + init_stream(s, 8192); - error = lib_recv(v, s->data, 4); - if (error == 0) - { - in_uint16_be(s, srcx); - in_uint16_be(s, srcy); - error = v->server_screen_blt(v, x, y, cx, cy, srcx, srcy); - } - } - else if (encoding == 0xffffff11) /* cursor */ - { - g_memset(cursor_data, 0, 32 * (32 * 3)); - g_memset(cursor_mask, 0, 32 * (32 / 8)); - j = cx * cy * Bpp; - k = ((cx + 7) / 8) * cy; - init_stream(s, j + k); - error = lib_recv(v, s->data, j + k); + error = lib_recv(v, s->data, 12); + if (error == 0) { - in_uint8p(s, d1, j); - in_uint8p(s, d2, k); - for (j = 0; j < 32; j++) - { - for (k = 0; k < 32; k++) + in_uint16_be(s, x); + in_uint16_be(s, y); + in_uint16_be(s, cx); + in_uint16_be(s, cy); + in_uint32_be(s, encoding); + + if (encoding == 0) /* raw */ { - pixel = get_pixel_safe(d2, k, 31 - j, cx, cy, 1); - set_pixel_safe(cursor_mask, k, j, 32, 32, 1, !pixel); - if (pixel) - { - pixel = get_pixel_safe(d1, k, 31 - j, cx, cy, v->mod_bpp); - split_color(pixel, &r, &g, &b, v->mod_bpp, v->palette); - pixel = make_color(r, g, b, 24); - set_pixel_safe(cursor_data, k, j, 32, 32, 24, pixel); - } + 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); + + if (error == 0) + { + error = v->server_paint_rect(v, x, y, cx, cy, data, cx, cy, 0, 0); + } + } + else if (encoding == 1) /* copy rect */ + { + init_stream(s, 8192); + error = lib_recv(v, s->data, 4); + + if (error == 0) + { + in_uint16_be(s, srcx); + in_uint16_be(s, srcy); + error = v->server_screen_blt(v, x, y, cx, cy, srcx, srcy); + } + } + else if (encoding == 0xffffff11) /* cursor */ + { + g_memset(cursor_data, 0, 32 * (32 * 3)); + g_memset(cursor_mask, 0, 32 * (32 / 8)); + j = cx * cy * Bpp; + k = ((cx + 7) / 8) * cy; + init_stream(s, j + k); + error = lib_recv(v, s->data, j + k); + + if (error == 0) + { + in_uint8p(s, d1, j); + in_uint8p(s, d2, k); + + for (j = 0; j < 32; j++) + { + for (k = 0; k < 32; k++) + { + pixel = get_pixel_safe(d2, k, 31 - j, cx, cy, 1); + set_pixel_safe(cursor_mask, k, j, 32, 32, 1, !pixel); + + if (pixel) + { + pixel = get_pixel_safe(d1, k, 31 - j, cx, cy, v->mod_bpp); + split_color(pixel, &r, &g, &b, v->mod_bpp, v->palette); + pixel = make_color(r, g, b, 24); + set_pixel_safe(cursor_data, k, j, 32, 32, 24, pixel); + } + } + } + + /* keep these in 32x32, vnc cursor can be alot bigger */ + if (x > 31) + { + x = 31; + } + + if (y > 31) + { + y = 31; + } + + error = v->server_set_cursor(v, x, y, cursor_data, cursor_mask); + } + } + else if (encoding == 0xffffff21) /* desktop size */ + { + v->mod_width = cx; + v->mod_height = cy; + error = v->server_reset(v, cx, cy, v->mod_bpp); + } + else + { + g_sprintf(text, "VNC error in lib_framebuffer_update encoding = %8.8x", + encoding); + v->server_msg(v, text, 1); } - } - /* keep these in 32x32, vnc cursor can be alot bigger */ - if (x > 31) - { - x = 31; - } - if (y > 31) - { - y = 31; - } - error = v->server_set_cursor(v, x, y, cursor_data, cursor_mask); } - } - else if (encoding == 0xffffff21) /* desktop size */ - { - v->mod_width = cx; - v->mod_height = cy; - error = v->server_reset(v, cx, cy, v->mod_bpp); - } - else - { - g_sprintf(text, "VNC error in lib_framebuffer_update encoding = %8.8x", - encoding); - v->server_msg(v, text, 1); - } - } - } - if (error == 0) - { - error = v->server_end_update(v); - } - g_free(data); - if (error == 0) - { - /* FrambufferUpdateRequest */ - init_stream(s, 8192); - out_uint8(s, 3); - out_uint8(s, 1); - out_uint16_be(s, 0); - 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); - } - free_stream(s); - return error; -} + } -/******************************************************************************/ -int DEFAULT_CC -lib_clip_data(struct vnc* v) -{ - struct stream* s; - struct stream* out_s; - int size; - int error; - - g_free(v->clip_data); - v->clip_data = 0; - v->clip_data_size = 0; - make_stream(s); - init_stream(s, 8192); - error = lib_recv(v, s->data, 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); - } - if (error == 0) - { - make_stream(out_s); - init_stream(out_s, 8192); - out_uint16_le(out_s, 2); - out_uint16_le(out_s, 0); - out_uint32_le(out_s, 0x90); - out_uint8(out_s, 0x0d); - out_uint8s(out_s, 35); - out_uint8(out_s, 0x10); - out_uint8s(out_s, 35); - out_uint8(out_s, 0x01); - out_uint8s(out_s, 35); - out_uint8(out_s, 0x07); - out_uint8s(out_s, 35); - out_uint8s(out_s, 4); - s_mark_end(out_s); - size = (int)(out_s->end - out_s->data); - error = v->server_send_to_channel(v, v->clip_chanid, out_s->data, size, size, 3); - free_stream(out_s); - } - free_stream(s); - return error; + if (error == 0) + { + error = v->server_end_update(v); + } + + g_free(data); + + if (error == 0) + { + /* FrambufferUpdateRequest */ + init_stream(s, 8192); + out_uint8(s, 3); + out_uint8(s, 1); + out_uint16_be(s, 0); + 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); + } + + free_stream(s); + return error; } /******************************************************************************/ int DEFAULT_CC -lib_palette_update(struct vnc* v) +lib_clip_data(struct vnc *v) { - struct stream* s; - int first_color; - int num_colors; - int i; - int r; - int g; - int b; - int error; - - make_stream(s); - init_stream(s, 8192); - error = lib_recv(v, s->data, 5); - if (error == 0) - { - in_uint8s(s, 1); - in_uint16_be(s, first_color); - in_uint16_be(s, num_colors); + struct stream *s; + struct stream *out_s; + int size; + int error; + + g_free(v->clip_data); + v->clip_data = 0; + v->clip_data_size = 0; + make_stream(s); init_stream(s, 8192); - error = lib_recv(v, s->data, num_colors * 6); - } - if (error == 0) - { - for (i = 0; i < num_colors; i++) - { - in_uint16_be(s, r); - in_uint16_be(s, g); - in_uint16_be(s, b); - r = r >> 8; - g = g >> 8; - b = b >> 8; - v->palette[first_color + i] = (r << 16) | (g << 8) | b; - } - error = v->server_begin_update(v); - } - if (error == 0) - { - error = v->server_palette(v, v->palette); - } - if (error == 0) - { - error = v->server_end_update(v); - } - free_stream(s); - return error; -} + error = lib_recv(v, s->data, 7); -/******************************************************************************/ -int DEFAULT_CC -lib_bell_trigger(struct vnc* v) -{ - struct stream* s; - int error; + 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); + } + + if (error == 0) + { + make_stream(out_s); + init_stream(out_s, 8192); + out_uint16_le(out_s, 2); + out_uint16_le(out_s, 0); + out_uint32_le(out_s, 0x90); + out_uint8(out_s, 0x0d); + out_uint8s(out_s, 35); + out_uint8(out_s, 0x10); + out_uint8s(out_s, 35); + out_uint8(out_s, 0x01); + out_uint8s(out_s, 35); + out_uint8(out_s, 0x07); + out_uint8s(out_s, 35); + out_uint8s(out_s, 4); + s_mark_end(out_s); + size = (int)(out_s->end - out_s->data); + error = v->server_send_to_channel(v, v->clip_chanid, out_s->data, size, size, 3); + free_stream(out_s); + } - error = v->server_bell_trigger(v); - return error; + free_stream(s); + return error; } /******************************************************************************/ int DEFAULT_CC -lib_mod_signal(struct vnc* v) +lib_palette_update(struct vnc *v) { - char type; - int error; - char text[256]; + struct stream *s; + int first_color; + int num_colors; + int i; + int r; + int g; + int b; + int error; - error = lib_recv(v, &type, 1); - if (error == 0) - { - if (type == 0) /* framebuffer update */ + make_stream(s); + init_stream(s, 8192); + error = lib_recv(v, s->data, 5); + + if (error == 0) { - error = lib_framebuffer_update(v); + in_uint8s(s, 1); + 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); } - else if (type == 1) /* palette */ + + if (error == 0) { - error = lib_palette_update(v); + for (i = 0; i < num_colors; i++) + { + in_uint16_be(s, r); + in_uint16_be(s, g); + in_uint16_be(s, b); + r = r >> 8; + g = g >> 8; + b = b >> 8; + v->palette[first_color + i] = (r << 16) | (g << 8) | b; + } + + error = v->server_begin_update(v); } - else if (type == 2) /* bell */ + + if (error == 0) { - error = lib_bell_trigger(v); + error = v->server_palette(v, v->palette); } - else if (type == 3) /* clipboard */ + + if (error == 0) { - log_message(LOG_LEVEL_DEBUG, "VNC got clip data"); - error = lib_clip_data(v); + error = v->server_end_update(v); } - else + + free_stream(s); + return error; +} + +/******************************************************************************/ +int DEFAULT_CC +lib_bell_trigger(struct vnc *v) +{ + struct stream *s; + int error; + + error = v->server_bell_trigger(v); + return error; +} + +/******************************************************************************/ +int DEFAULT_CC +lib_mod_signal(struct vnc *v) +{ + char type; + int error; + char text[256]; + + error = lib_recv(v, &type, 1); + + if (error == 0) { - g_sprintf(text, "VNC unknown in lib_mod_signal %d", type); - v->server_msg(v, text, 1); + if (type == 0) /* framebuffer update */ + { + error = lib_framebuffer_update(v); + } + else if (type == 1) /* palette */ + { + error = lib_palette_update(v); + } + else if (type == 2) /* bell */ + { + error = lib_bell_trigger(v); + } + else if (type == 3) /* clipboard */ + { + log_message(LOG_LEVEL_DEBUG, "VNC got clip data"); + error = lib_clip_data(v); + } + else + { + g_sprintf(text, "VNC unknown in lib_mod_signal %d", type); + v->server_msg(v, text, 1); + } } - } - return error; + + return error; } /******************************************************************************/ int DEFAULT_CC -lib_mod_start(struct vnc* v, int w, int h, int bpp) +lib_mod_start(struct vnc *v, int w, int h, int bpp) { - v->server_begin_update(v); - v->server_set_fgcolor(v, 0); - v->server_fill_rect(v, 0, 0, w, h); - v->server_end_update(v); - v->server_width = w; - v->server_height = h; - v->server_bpp = bpp; - return 0; + v->server_begin_update(v); + v->server_set_fgcolor(v, 0); + v->server_fill_rect(v, 0, 0, w, h); + v->server_end_update(v); + v->server_width = w; + v->server_height = h; + v->server_bpp = bpp; + return 0; } /******************************************************************************/ static int APP_CC -lib_open_clip_channel(struct vnc* v) +lib_open_clip_channel(struct vnc *v) { - char init_data[12] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - - v->clip_chanid = v->server_get_channel_id(v, "cliprdr"); - if (v->clip_chanid >= 0) - { - v->server_send_to_channel(v, v->clip_chanid, init_data, 12, 12, 3); - } - return 0; + char init_data[12] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + v->clip_chanid = v->server_get_channel_id(v, "cliprdr"); + + if (v->clip_chanid >= 0) + { + v->server_send_to_channel(v, v->clip_chanid, init_data, 12, 12, 3); + } + + return 0; } /******************************************************************************/ @@ -841,440 +934,478 @@ lib_open_clip_channel(struct vnc* v) return error */ int DEFAULT_CC -lib_mod_connect(struct vnc* v) +lib_mod_connect(struct vnc *v) { - char cursor_data[32 * (32 * 3)]; - char cursor_mask[32 * (32 / 8)]; - char con_port[256]; - char text[256]; - struct stream* s; - struct stream* pixel_format; - int error; - int i; - int check_sec_result; - - v->server_msg(v, "VNC started connecting", 0); - check_sec_result = 1; - /* only support 8 and 16 bpp connections from rdp client */ - if ((v->server_bpp != 8) && (v->server_bpp != 15) && - (v->server_bpp != 16) && (v->server_bpp != 24)) - { - v->server_msg(v, "VNC error - only supporting 8, 15, 16 and 24 bpp rdp " - "connections", 0); - return 1; - } - if (g_strcmp(v->ip, "") == 0) - { - v->server_msg(v, "VNC error - no ip set", 0); - return 1; - } - make_stream(s); - g_sprintf(con_port, "%s", v->port); - make_stream(pixel_format); - v->sck = g_tcp_socket(); - v->sck_obj = g_create_wait_obj_from_socket(v->sck, 0); - v->sck_closed = 0; - 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); - 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); - if (error == 0) + char cursor_data[32 * (32 * 3)]; + char cursor_mask[32 * (32 / 8)]; + char con_port[256]; + char text[256]; + struct stream *s; + struct stream *pixel_format; + int error; + int i; + int check_sec_result; + + v->server_msg(v, "VNC started connecting", 0); + check_sec_result = 1; + + /* only support 8 and 16 bpp connections from rdp client */ + if ((v->server_bpp != 8) && (v->server_bpp != 15) && + (v->server_bpp != 16) && (v->server_bpp != 24)) { - error = lib_send(v, "RFB 003.003\n", 12); + v->server_msg(v, "VNC error - only supporting 8, 15, 16 and 24 bpp rdp " + "connections", 0); + return 1; } - /* sec type */ - if (error == 0) + + if (g_strcmp(v->ip, "") == 0) { - init_stream(s, 8192); - error = lib_recv(v, s->data, 4); + v->server_msg(v, "VNC error - no ip set", 0); + return 1; } + + make_stream(s); + g_sprintf(con_port, "%s", v->port); + make_stream(pixel_format); + v->sck = g_tcp_socket(); + v->sck_obj = g_create_wait_obj_from_socket(v->sck, 0); + v->sck_closed = 0; + 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); + if (error == 0) { - in_uint32_be(s, i); - g_sprintf(text, "VNC security level is %d (1 = none, 2 = standard)", i); - v->server_msg(v, text, 0); - if (i == 1) /* none */ - { - check_sec_result = 0; - } - else if (i == 2) /* dec the password and the server random */ - { + 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, 16); + error = lib_recv(v, s->data, 12); + if (error == 0) { - rfbEncryptBytes(s->data, v->password); - error = lib_send(v, s->data, 16); - check_sec_result = 1; // not needed + error = lib_send(v, "RFB 003.003\n", 12); } - } - else if (i == 0) - { - log_message(LOG_LEVEL_DEBUG, "VNC Server will disconnect"); - error = 1; - } - else - { - log_message(LOG_LEVEL_DEBUG, "VNC unsupported security level"); - error = 1; - } - } - } - if (error!=0) - { - log_message(LOG_LEVEL_DEBUG, "VNC Error after security negotiation"); - } - if (error == 0 && check_sec_result) - { - /* sec result */ - init_stream(s, 8192); - error = lib_recv(v, s->data, 4); + + /* sec type */ + if (error == 0) + { + init_stream(s, 8192); + error = lib_recv(v, s->data, 4); + } + + if (error == 0) + { + in_uint32_be(s, i); + g_sprintf(text, "VNC security level is %d (1 = none, 2 = standard)", i); + v->server_msg(v, text, 0); + + if (i == 1) /* none */ + { + check_sec_result = 0; + } + else if (i == 2) /* dec the password and the server random */ + { + init_stream(s, 8192); + error = lib_recv(v, s->data, 16); + + if (error == 0) + { + rfbEncryptBytes(s->data, v->password); + error = lib_send(v, s->data, 16); + check_sec_result = 1; // not needed + } + } + else if (i == 0) + { + log_message(LOG_LEVEL_DEBUG, "VNC Server will disconnect"); + error = 1; + } + else + { + log_message(LOG_LEVEL_DEBUG, "VNC unsupported security level"); + error = 1; + } + } + } + + if (error != 0) + { + log_message(LOG_LEVEL_DEBUG, "VNC Error after security negotiation"); + } + + if (error == 0 && check_sec_result) + { + /* sec result */ + init_stream(s, 8192); + error = lib_recv(v, s->data, 4); + + if (error == 0) + { + in_uint32_be(s, i); + + if (i != 0) + { + v->server_msg(v, "VNC password failed", 0); + error = 2; + } + else + { + v->server_msg(v, "VNC password ok", 0); + } + } + } + if (error == 0) { - in_uint32_be(s, i); - if (i != 0) - { - v->server_msg(v, "VNC password failed", 0); - error = 2; - } - else - { - v->server_msg(v, "VNC password ok", 0); - } - } - } - if (error == 0) - { - 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 */ - } - else - { - log_message(LOG_LEVEL_DEBUG, "VNC error before sending share flag"); - } - if (error == 0) - { - v->server_msg(v, "VNC receiving server init", 0); - error = lib_recv(v, s->data, 4); /* server init */ - } - else - { - log_message(LOG_LEVEL_DEBUG, "VNC error before receiving server init"); - } - if (error == 0) - { - in_uint16_be(s, v->mod_width); - 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); - } - else - { - log_message(LOG_LEVEL_DEBUG, "VNC error before receiving pixel format"); - } - if (error == 0) - { - 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 */ - } - else - { - log_message(LOG_LEVEL_DEBUG, "VNC error before receiving name length"); - } - if (error == 0) - { - in_uint32_be(s, i); - if (i > 255 || i < 0) - { - error = 3; + 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 */ } else { - v->server_msg(v, "VNC receiving name", 0); - error = lib_recv(v, v->mod_name, i); - v->mod_name[i] = 0; - } - } - else - { - log_message(LOG_LEVEL_DEBUG, "VNC error before receiving name"); - } - /* should be connected */ - if (error == 0) - { - /* SetPixelFormat */ - init_stream(s, 8192); - out_uint8(s, 0); - out_uint8(s, 0); - out_uint8(s, 0); - out_uint8(s, 0); - init_stream(pixel_format, 8192); - if (v->mod_bpp == 8) - { - out_uint8(pixel_format, 8); /* bits per pixel */ - out_uint8(pixel_format, 8); /* depth */ + log_message(LOG_LEVEL_DEBUG, "VNC error before sending share flag"); + } + + if (error == 0) + { + v->server_msg(v, "VNC receiving server init", 0); + error = lib_recv(v, s->data, 4); /* server init */ + } + else + { + log_message(LOG_LEVEL_DEBUG, "VNC error before receiving server init"); + } + + if (error == 0) + { + in_uint16_be(s, v->mod_width); + 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); + } + else + { + log_message(LOG_LEVEL_DEBUG, "VNC error before receiving pixel format"); + } + + if (error == 0) + { + 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 */ + } + else + { + log_message(LOG_LEVEL_DEBUG, "VNC error before receiving name length"); + } + + if (error == 0) + { + in_uint32_be(s, i); + + if (i > 255 || i < 0) + { + error = 3; + } + else + { + v->server_msg(v, "VNC receiving name", 0); + error = lib_recv(v, v->mod_name, i); + v->mod_name[i] = 0; + } + } + else + { + log_message(LOG_LEVEL_DEBUG, "VNC error before receiving name"); + } + + /* should be connected */ + if (error == 0) + { + /* SetPixelFormat */ + init_stream(s, 8192); + out_uint8(s, 0); + out_uint8(s, 0); + out_uint8(s, 0); + out_uint8(s, 0); + init_stream(pixel_format, 8192); + + if (v->mod_bpp == 8) + { + out_uint8(pixel_format, 8); /* bits per pixel */ + out_uint8(pixel_format, 8); /* depth */ #if defined(B_ENDIAN) - out_uint8(pixel_format, 1); /* big endian */ + out_uint8(pixel_format, 1); /* big endian */ #else - out_uint8(pixel_format, 0); /* big endian */ + out_uint8(pixel_format, 0); /* big endian */ #endif - out_uint8(pixel_format, 0); /* true color flag */ - out_uint16_be(pixel_format, 0); /* red max */ - out_uint16_be(pixel_format, 0); /* green max */ - out_uint16_be(pixel_format, 0); /* blue max */ - out_uint8(pixel_format, 0); /* red shift */ - out_uint8(pixel_format, 0); /* green shift */ - out_uint8(pixel_format, 0); /* blue shift */ - out_uint8s(pixel_format, 3); /* pad */ - } - else if (v->mod_bpp == 15) - { - out_uint8(pixel_format, 16); /* bits per pixel */ - out_uint8(pixel_format, 15); /* depth */ + out_uint8(pixel_format, 0); /* true color flag */ + out_uint16_be(pixel_format, 0); /* red max */ + out_uint16_be(pixel_format, 0); /* green max */ + out_uint16_be(pixel_format, 0); /* blue max */ + out_uint8(pixel_format, 0); /* red shift */ + out_uint8(pixel_format, 0); /* green shift */ + out_uint8(pixel_format, 0); /* blue shift */ + out_uint8s(pixel_format, 3); /* pad */ + } + else if (v->mod_bpp == 15) + { + out_uint8(pixel_format, 16); /* bits per pixel */ + out_uint8(pixel_format, 15); /* depth */ #if defined(B_ENDIAN) - out_uint8(pixel_format, 1); /* big endian */ + out_uint8(pixel_format, 1); /* big endian */ #else - out_uint8(pixel_format, 0); /* big endian */ + out_uint8(pixel_format, 0); /* big endian */ #endif - out_uint8(pixel_format, 1); /* true color flag */ - out_uint16_be(pixel_format, 31); /* red max */ - out_uint16_be(pixel_format, 31); /* green max */ - out_uint16_be(pixel_format, 31); /* blue max */ - out_uint8(pixel_format, 10); /* red shift */ - out_uint8(pixel_format, 5); /* green shift */ - out_uint8(pixel_format, 0); /* blue shift */ - out_uint8s(pixel_format, 3); /* pad */ - } - else if (v->mod_bpp == 16) - { - out_uint8(pixel_format, 16); /* bits per pixel */ - out_uint8(pixel_format, 16); /* depth */ + out_uint8(pixel_format, 1); /* true color flag */ + out_uint16_be(pixel_format, 31); /* red max */ + out_uint16_be(pixel_format, 31); /* green max */ + out_uint16_be(pixel_format, 31); /* blue max */ + out_uint8(pixel_format, 10); /* red shift */ + out_uint8(pixel_format, 5); /* green shift */ + out_uint8(pixel_format, 0); /* blue shift */ + out_uint8s(pixel_format, 3); /* pad */ + } + else if (v->mod_bpp == 16) + { + out_uint8(pixel_format, 16); /* bits per pixel */ + out_uint8(pixel_format, 16); /* depth */ #if defined(B_ENDIAN) - out_uint8(pixel_format, 1); /* big endian */ + out_uint8(pixel_format, 1); /* big endian */ #else - out_uint8(pixel_format, 0); /* big endian */ + out_uint8(pixel_format, 0); /* big endian */ #endif - out_uint8(pixel_format, 1); /* true color flag */ - out_uint16_be(pixel_format, 31); /* red max */ - out_uint16_be(pixel_format, 63); /* green max */ - out_uint16_be(pixel_format, 31); /* blue max */ - out_uint8(pixel_format, 11); /* red shift */ - out_uint8(pixel_format, 5); /* green shift */ - out_uint8(pixel_format, 0); /* blue shift */ - out_uint8s(pixel_format, 3); /* pad */ - } - else if (v->mod_bpp == 24) - { - out_uint8(pixel_format, 32); /* bits per pixel */ - out_uint8(pixel_format, 24); /* depth */ + out_uint8(pixel_format, 1); /* true color flag */ + out_uint16_be(pixel_format, 31); /* red max */ + out_uint16_be(pixel_format, 63); /* green max */ + out_uint16_be(pixel_format, 31); /* blue max */ + out_uint8(pixel_format, 11); /* red shift */ + out_uint8(pixel_format, 5); /* green shift */ + out_uint8(pixel_format, 0); /* blue shift */ + out_uint8s(pixel_format, 3); /* pad */ + } + else if (v->mod_bpp == 24) + { + out_uint8(pixel_format, 32); /* bits per pixel */ + out_uint8(pixel_format, 24); /* depth */ #if defined(B_ENDIAN) - out_uint8(pixel_format, 1); /* big endian */ + out_uint8(pixel_format, 1); /* big endian */ #else - out_uint8(pixel_format, 0); /* big endian */ + out_uint8(pixel_format, 0); /* big endian */ #endif - out_uint8(pixel_format, 1); /* true color flag */ - out_uint16_be(pixel_format, 255); /* red max */ - out_uint16_be(pixel_format, 255); /* green max */ - out_uint16_be(pixel_format, 255); /* blue max */ - out_uint8(pixel_format, 16); /* red shift */ - out_uint8(pixel_format, 8); /* green shift */ - out_uint8(pixel_format, 0); /* blue shift */ - out_uint8s(pixel_format, 3); /* pad */ - } - out_uint8a(s, pixel_format->data, 16); - v->server_msg(v, "VNC sending pixel format", 0); - error = lib_send(v, s->data, 20); - } - if (error == 0) - { - /* SetEncodings */ - init_stream(s, 8192); - out_uint8(s, 2); - out_uint8(s, 0); - out_uint16_be(s, 4); - out_uint32_be(s, 0); /* raw */ - out_uint32_be(s, 1); /* copy rect */ - 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); - } - if (error == 0) - { - error = v->server_reset(v, v->mod_width, v->mod_height, v->mod_bpp); - } - if (error == 0) - { - /* FrambufferUpdateRequest */ - init_stream(s, 8192); - out_uint8(s, 3); - out_uint8(s, 0); - out_uint16_be(s, 0); - out_uint16_be(s, 0); - 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); - } - if (error == 0) - { - if (v->server_bpp != v->mod_bpp) - { - v->server_msg(v, "VNC error - server bpp and client bpp do not match", 0); - error = 1; - } - } - if (error == 0) - { - /* set almost null cursor, this is the little dot cursor */ - g_memset(cursor_data, 0, 32 * (32 * 3)); - g_memset(cursor_data + (32 * (32 * 3) - 1 * 32 * 3), 0xff, 9); - g_memset(cursor_data + (32 * (32 * 3) - 2 * 32 * 3), 0xff, 9); - g_memset(cursor_data + (32 * (32 * 3) - 3 * 32 * 3), 0xff, 9); - g_memset(cursor_mask, 0xff, 32 * (32 / 8)); - v->server_msg(v, "VNC sending cursor", 0); - error = v->server_set_cursor(v, 3, 3, cursor_data, cursor_mask); - } - free_stream(s); - free_stream(pixel_format); - if (error == 0) - { - v->server_msg(v, "VNC connection complete, connected ok", 0); - lib_open_clip_channel(v); - } - else - { - v->server_msg(v, "VNC error - problem connecting", 0); - } - return error; + out_uint8(pixel_format, 1); /* true color flag */ + out_uint16_be(pixel_format, 255); /* red max */ + out_uint16_be(pixel_format, 255); /* green max */ + out_uint16_be(pixel_format, 255); /* blue max */ + out_uint8(pixel_format, 16); /* red shift */ + out_uint8(pixel_format, 8); /* green shift */ + out_uint8(pixel_format, 0); /* blue shift */ + out_uint8s(pixel_format, 3); /* pad */ + } + + out_uint8a(s, pixel_format->data, 16); + v->server_msg(v, "VNC sending pixel format", 0); + error = lib_send(v, s->data, 20); + } + + if (error == 0) + { + /* SetEncodings */ + init_stream(s, 8192); + out_uint8(s, 2); + out_uint8(s, 0); + out_uint16_be(s, 4); + out_uint32_be(s, 0); /* raw */ + out_uint32_be(s, 1); /* copy rect */ + 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); + } + + if (error == 0) + { + error = v->server_reset(v, v->mod_width, v->mod_height, v->mod_bpp); + } + + if (error == 0) + { + /* FrambufferUpdateRequest */ + init_stream(s, 8192); + out_uint8(s, 3); + out_uint8(s, 0); + out_uint16_be(s, 0); + out_uint16_be(s, 0); + 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); + } + + if (error == 0) + { + if (v->server_bpp != v->mod_bpp) + { + v->server_msg(v, "VNC error - server bpp and client bpp do not match", 0); + error = 1; + } + } + + if (error == 0) + { + /* set almost null cursor, this is the little dot cursor */ + g_memset(cursor_data, 0, 32 * (32 * 3)); + g_memset(cursor_data + (32 * (32 * 3) - 1 * 32 * 3), 0xff, 9); + g_memset(cursor_data + (32 * (32 * 3) - 2 * 32 * 3), 0xff, 9); + g_memset(cursor_data + (32 * (32 * 3) - 3 * 32 * 3), 0xff, 9); + g_memset(cursor_mask, 0xff, 32 * (32 / 8)); + v->server_msg(v, "VNC sending cursor", 0); + error = v->server_set_cursor(v, 3, 3, cursor_data, cursor_mask); + } + + free_stream(s); + free_stream(pixel_format); + + if (error == 0) + { + v->server_msg(v, "VNC connection complete, connected ok", 0); + lib_open_clip_channel(v); + } + else + { + v->server_msg(v, "VNC error - problem connecting", 0); + } + + return error; } /******************************************************************************/ int DEFAULT_CC -lib_mod_end(struct vnc* v) +lib_mod_end(struct vnc *v) { - if (v->vnc_desktop != 0) - { - } - g_free(v->clip_data); - v->clip_data = 0; - v->clip_data_size = 0; - return 0; + if (v->vnc_desktop != 0) + { + } + + g_free(v->clip_data); + v->clip_data = 0; + v->clip_data_size = 0; + return 0; } /******************************************************************************/ int DEFAULT_CC -lib_mod_set_param(struct vnc* v, char* name, char* value) +lib_mod_set_param(struct vnc *v, char *name, char *value) { - if (g_strcasecmp(name, "username") == 0) - { - g_strncpy(v->username, value, 255); - } - else if (g_strcasecmp(name, "password") == 0) - { - g_strncpy(v->password, value, 255); - } - else if (g_strcasecmp(name, "ip") == 0) - { - g_strncpy(v->ip, value, 255); - } - else if (g_strcasecmp(name, "port") == 0) - { - g_strncpy(v->port, value, 255); - } - else if (g_strcasecmp(name, "keylayout") == 0) - { - v->keylayout = g_atoi(value); - } - return 0; + if (g_strcasecmp(name, "username") == 0) + { + g_strncpy(v->username, value, 255); + } + else if (g_strcasecmp(name, "password") == 0) + { + g_strncpy(v->password, value, 255); + } + else if (g_strcasecmp(name, "ip") == 0) + { + g_strncpy(v->ip, value, 255); + } + else if (g_strcasecmp(name, "port") == 0) + { + g_strncpy(v->port, value, 255); + } + else if (g_strcasecmp(name, "keylayout") == 0) + { + v->keylayout = g_atoi(value); + } + + return 0; } /******************************************************************************/ /* return error */ int DEFAULT_CC -lib_mod_get_wait_objs(struct vnc* v, tbus* read_objs, int* rcount, - tbus* write_objs, int* wcount, int* timeout) +lib_mod_get_wait_objs(struct vnc *v, tbus *read_objs, int *rcount, + tbus *write_objs, int *wcount, int *timeout) { - int i; + int i; + + i = *rcount; - i = *rcount; - if (v != 0) - { - if (v->sck_obj != 0) + if (v != 0) { - read_objs[i++] = v->sck_obj; + if (v->sck_obj != 0) + { + read_objs[i++] = v->sck_obj; + } } - } - *rcount = i; - return 0; + + *rcount = i; + return 0; } /******************************************************************************/ /* return error */ int DEFAULT_CC -lib_mod_check_wait_objs(struct vnc* v) +lib_mod_check_wait_objs(struct vnc *v) { - int rv; + int rv; + + rv = 0; - rv = 0; - if (v != 0) - { - if (v->sck_obj != 0) + if (v != 0) { - if (g_is_wait_obj_set(v->sck_obj)) - { - rv = lib_mod_signal(v); - } + if (v->sck_obj != 0) + { + if (g_is_wait_obj_set(v->sck_obj)) + { + rv = lib_mod_signal(v); + } + } } - } - return rv; + + return rv; } /******************************************************************************/ -struct vnc* EXPORT_CC +struct vnc *EXPORT_CC mod_init(void) { - struct vnc* v; - - v = (struct vnc*)g_malloc(sizeof(struct vnc), 1); - /* set client functions */ - v->size = sizeof(struct vnc); - v->version = CURRENT_MOD_VER; - v->handle = (long)v; - v->mod_connect = lib_mod_connect; - v->mod_start = lib_mod_start; - v->mod_event = lib_mod_event; - v->mod_signal = lib_mod_signal; - v->mod_end = lib_mod_end; - v->mod_set_param = lib_mod_set_param; - v->mod_get_wait_objs = lib_mod_get_wait_objs; - v->mod_check_wait_objs = lib_mod_check_wait_objs; - return v; + struct vnc *v; + + v = (struct vnc *)g_malloc(sizeof(struct vnc), 1); + /* set client functions */ + v->size = sizeof(struct vnc); + v->version = CURRENT_MOD_VER; + v->handle = (long)v; + v->mod_connect = lib_mod_connect; + v->mod_start = lib_mod_start; + v->mod_event = lib_mod_event; + v->mod_signal = lib_mod_signal; + v->mod_end = lib_mod_end; + v->mod_set_param = lib_mod_set_param; + v->mod_get_wait_objs = lib_mod_get_wait_objs; + v->mod_check_wait_objs = lib_mod_check_wait_objs; + return v; } /******************************************************************************/ int EXPORT_CC -mod_exit(struct vnc* v) +mod_exit(struct vnc *v) { - log_message(LOG_LEVEL_DEBUG, "VNC mod_exit"); - if (v == 0) - { + log_message(LOG_LEVEL_DEBUG, "VNC mod_exit"); + + if (v == 0) + { + return 0; + } + + g_delete_wait_obj_from_socket(v->sck_obj); + g_tcp_close(v->sck); + g_free(v); return 0; - } - g_delete_wait_obj_from_socket(v->sck_obj); - g_tcp_close(v->sck); - g_free(v); - return 0; } @@ -1,24 +1,22 @@ -/* - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - libvnc - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * libvnc + */ /* include other h files */ #include "arch.h" |