diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Makefile.am | 9 | ||||
-rw-r--r-- | common/arch.h | 26 | ||||
-rw-r--r-- | common/crc16.h | 0 | ||||
-rw-r--r-- | common/defines.h | 10 | ||||
-rw-r--r-- | common/fifo.c | 169 | ||||
-rw-r--r-- | common/fifo.h | 47 | ||||
-rw-r--r-- | common/file.c | 55 | ||||
-rw-r--r-- | common/file.h | 2 | ||||
-rw-r--r-- | common/file_loc.h | 26 | ||||
-rw-r--r-- | common/list.c | 2 | ||||
-rw-r--r-- | common/list.h | 20 | ||||
-rw-r--r-- | common/list16.c | 188 | ||||
-rw-r--r-- | common/list16.h | 56 | ||||
-rw-r--r-- | common/log.c | 80 | ||||
-rw-r--r-- | common/log.h | 62 | ||||
-rw-r--r-- | common/os_calls.c | 69 | ||||
-rw-r--r-- | common/os_calls.h | 3 | ||||
-rw-r--r-- | common/parse.h | 297 | ||||
-rw-r--r-- | common/rail.h | 2 | ||||
-rw-r--r-- | common/ssl_calls.c | 6 | ||||
-rw-r--r-- | common/thread_calls.c | 2 | ||||
-rw-r--r-- | common/thread_calls.h | 2 | ||||
-rw-r--r-- | common/trans.c | 159 | ||||
-rw-r--r-- | common/trans.h | 77 | ||||
-rw-r--r-- | common/xrdp_client_info.h | 18 | ||||
-rw-r--r-- | common/xrdp_constants.h | 21 | ||||
-rw-r--r-- | common/xrdp_rail.h | 102 | ||||
-rw-r--r-- | common/xrdp_tls.c | 269 |
28 files changed, 1405 insertions, 374 deletions
diff --git a/common/Makefile.am b/common/Makefile.am index 3d7e8bd1..9feac9fb 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -5,6 +5,8 @@ EXTRA_DIST = \ file.h \ file_loc.h \ list.h \ + list16.h \ + fifo.h \ log.h \ os_calls.h \ os_calls.h \ @@ -15,7 +17,7 @@ EXTRA_DIST = \ trans.h \ xrdp_client_info.h \ xrdp_constants.h \ - xrdp_rail.h + xrdp_rail.h AM_CFLAGS = \ -DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \ @@ -31,11 +33,14 @@ libcommon_la_SOURCES = \ d3des.c \ file.c \ list.c \ + list16.c \ + fifo.c \ log.c \ os_calls.c \ ssl_calls.c \ thread_calls.c \ - trans.c + trans.c \ + xrdp_tls.c libcommon_la_LIBADD = \ -lcrypto \ diff --git a/common/arch.h b/common/arch.h index b4eb4719..14ab9d7d 100644 --- a/common/arch.h +++ b/common/arch.h @@ -1,7 +1,7 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Jay Sorg 2004-2013 + * Copyright (C) Jay Sorg 2004-2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,21 +19,41 @@ #if !defined(ARCH_H) #define ARCH_H -#if !(defined(L_ENDIAN) || defined(B_ENDIAN)) +/* you can define L_ENDIAN or B_ENDIAN and NEED_ALIGN or NO_NEED_ALIGN + in the makefile to override */ + /* check endianess */ +#if !(defined(L_ENDIAN) || defined(B_ENDIAN)) +#if !defined(__BYTE_ORDER) && defined(__linux__) +#include <endian.h> +#endif + +#if defined(BYTE_ORDER) +#if BYTE_ORDER == BIG_ENDIAN +#define B_ENDIAN +#else +#define L_ENDIAN +#endif +#endif + +#if !(defined(L_ENDIAN) || defined(B_ENDIAN)) #if defined(__sparc__) || defined(__PPC__) || defined(__ppc__) || \ defined(__hppa__) #define B_ENDIAN #else #define L_ENDIAN #endif +#endif +#endif + /* check if we need to align data */ +#if !(defined(NEED_ALIGN) || defined(NO_NEED_ALIGN)) #if defined(__sparc__) || defined(__alpha__) || defined(__hppa__) || \ defined(__AIX__) || defined(__PPC__) || defined(__mips__) || \ defined(__ia64__) || defined(__ppc__) || defined(__arm__) #define NEED_ALIGN #elif defined(__x86__) || defined(__x86_64__) || \ - defined(__AMD64__) || defined(_M_IX86) || \ + defined(__AMD64__) || defined(_M_IX86) || defined (_M_AMD64) || \ defined(__i386__) #define NO_NEED_ALIGN #else diff --git a/common/crc16.h b/common/crc16.h new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/common/crc16.h diff --git a/common/defines.h b/common/defines.h index 502a41e8..d87ddae7 100644 --- a/common/defines.h +++ b/common/defines.h @@ -1,7 +1,7 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Jay Sorg 2004-2012 + * Copyright (C) Jay Sorg 2004-2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -72,7 +72,7 @@ (bpp==8?COLOR8(HRED(c),HGREEN(c),HBLUE(c)): \ (bpp==15?COLOR15(HRED(c),HGREEN(c),HBLUE(c)): \ (bpp==16?COLOR16(HRED(c),HGREEN(c),HBLUE(c)): \ - (bpp==24?COLOR24BGR(HRED(c),HGREEN(c),HBLUE(c)):c) \ + (bpp>=24?COLOR24BGR(HRED(c),HGREEN(c),HBLUE(c)):c) \ ) \ ) \ ) \ @@ -101,4 +101,10 @@ /* use crc for bitmap cache lookups */ #define USE_CRC +#define XR_RGB2BGR(a_ulColor) \ + (a_ulColor & 0xFF000000) | \ + ((a_ulColor & 0x00FF0000) >> 16) | \ + (a_ulColor & 0x0000FF00) | \ + ((a_ulColor & 0x000000FF) << 16) + #endif diff --git a/common/fifo.c b/common/fifo.c new file mode 100644 index 00000000..e3f6f3bc --- /dev/null +++ b/common/fifo.c @@ -0,0 +1,169 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Laxmikant Rashinkar 2004-2014 + * + * 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. + * + * FIFO implementation to store pointer to data struct + */ + +#include "fifo.h" +#include "os_calls.h" + +/** + * Create new fifo data struct + * + * @return pointer to new FIFO or NULL if system out of memory + *****************************************************************************/ + +FIFO * APP_CC +fifo_create(void) +{ + return (FIFO *) g_malloc(sizeof(FIFO), 1); +} + +/** + * Delete specified FIFO + *****************************************************************************/ + +void APP_CC +fifo_delete(FIFO *self) +{ + USER_DATA *udp; + + if (!self) + return; + + if (!self->head) + { + /* FIFO is empty */ + g_free(self); + return; + } + + if (self->head == self->tail) + { + /* only one item in FIFO */ + if (self->auto_free) + g_free(self->head->item); + + g_free(self->head); + g_free(self); + return; + } + + /* more then one item in FIFO */ + while (self->head) + { + udp = self->head; + + if (self->auto_free) + g_free(udp->item); + + self->head = udp->next; + g_free(udp); + } + + g_free(self); +} + +/** + * Add an item to the specified FIFO + * + * @param self FIFO to operate on + * @param item item to add to specified FIFO + * + * @return 0 on success, -1 on error + *****************************************************************************/ + +int APP_CC +fifo_add_item(FIFO *self, void *item) +{ + USER_DATA *udp; + + if (!self || !item) + return -1; + + if ((udp = (USER_DATA *) g_malloc(sizeof(USER_DATA), 0)) == 0) + return -1; + + udp->item = item; + udp->next = 0; + + /* if fifo is empty, add to head */ + if (!self->head) + { + self->head = udp; + self->tail = udp; + return 0; + } + + /* add to tail */ + self->tail->next = udp; + self->tail = udp; + + return 0; +} + +/** + * Return an item from top of FIFO + * + * @param self FIFO to operate on + * + * @return top item from FIFO or NULL if FIFO is empty + *****************************************************************************/ + +void * APP_CC +fifo_remove_item(FIFO *self) +{ + void *item; + USER_DATA *udp; + + if (!self || !self->head) + return 0; + + if (self->head == self->tail) + { + /* only one item in FIFO */ + item = self->head->item; + g_free(self->head); + self->head = 0; + self->tail = 0; + return item; + } + + /* more then one item in FIFO */ + udp = self->head; + item = self->head->item; + self->head = self->head->next; + g_free(udp); + return item; +} + +/** + * Return FIFO status + * + * @param self FIFO to operate on + * + * @return true if FIFO is empty, false otherwise + *****************************************************************************/ + +int APP_CC +fifo_is_empty(FIFO *self) +{ + if (!self) + return 1; + + return (self->head == 0); +} diff --git a/common/fifo.h b/common/fifo.h new file mode 100644 index 00000000..3d44c453 --- /dev/null +++ b/common/fifo.h @@ -0,0 +1,47 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Laxmikant Rashinkar 2004-2014 + * + * 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. + * + * FIFO implementation to store pointer to data struct + */ + +#ifndef _FIFO_H +#define _FIFO_H + +#include "arch.h" + +typedef struct user_data USER_DATA; + +struct user_data +{ + USER_DATA *next; + void *item; +}; + +typedef struct fifo +{ + USER_DATA *head; + USER_DATA *tail; + int auto_free; +} FIFO; + +FIFO * APP_CC fifo_create(void); +void APP_CC fifo_delete(FIFO *self); +int APP_CC fifo_add_item(FIFO *self, void *item); +void * APP_CC fifo_remove_item(FIFO *self); +int APP_CC fifo_is_empty(FIFO *self); + +#endif diff --git a/common/file.c b/common/file.c index f1ba5a87..b51a37cc 100644 --- a/common/file.c +++ b/common/file.c @@ -1,7 +1,7 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Jay Sorg 2004-2013 + * Copyright (C) Jay Sorg 2004-2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,8 @@ #include "file.h" #include "parse.h" +#define FILE_MAX_LINE_BYTES 2048 + /*****************************************************************************/ /* returns error returns 0 if everything is ok @@ -32,7 +34,7 @@ static int APP_CC l_file_read_sections(int fd, int max_file_size, struct list *names) { struct stream *s; - char text[256]; + char text[FILE_MAX_LINE_BYTES]; char c; int in_it; int in_it_index; @@ -44,7 +46,7 @@ l_file_read_sections(int fd, int max_file_size, struct list *names) g_file_seek(fd, 0); in_it_index = 0; in_it = 0; - g_memset(text, 0, 256); + g_memset(text, 0, FILE_MAX_LINE_BYTES); list_clear(names); make_stream(s); init_stream(s, max_file_size); @@ -67,7 +69,7 @@ l_file_read_sections(int fd, int max_file_size, struct list *names) list_add_item(names, (tbus)g_strdup(text)); in_it = 0; in_it_index = 0; - g_memset(text, 0, 256); + g_memset(text, 0, FILE_MAX_LINE_BYTES); } else if (in_it) { @@ -86,8 +88,9 @@ l_file_read_sections(int fd, int max_file_size, struct list *names) } /*****************************************************************************/ +/* returns error */ static int APP_CC -file_read_line(struct stream *s, char *text) +file_read_line(struct stream *s, char *text, int text_bytes) { int i; int skip_to_end; @@ -108,6 +111,7 @@ file_read_line(struct stream *s, char *text) while (c != 10 && c != 13) { + /* these mean skip the rest of the line */ if (c == '#' || c == '!' || c == ';') { skip_to_end = 1; @@ -117,6 +121,10 @@ file_read_line(struct stream *s, char *text) { text[i] = c; i++; + if (i >= text_bytes) + { + return 1; + } } if (s_check_rem(s, 1)) @@ -214,9 +222,10 @@ l_file_read_section(int fd, int max_file_size, const char *section, struct list *names, struct list *values) { struct stream *s; - char text[512]; - char name[512]; - char value[512]; + char *data; + char *text; + char *name; + char *value; char *lvalue; char c; int in_it; @@ -225,11 +234,16 @@ l_file_read_section(int fd, int max_file_size, const char *section, int index; int file_size; + data = (char *) g_malloc(FILE_MAX_LINE_BYTES * 3, 0); + text = data; + name = text + FILE_MAX_LINE_BYTES; + value = name + FILE_MAX_LINE_BYTES; + file_size = 32 * 1024; /* 32 K file size limit */ g_file_seek(fd, 0); in_it_index = 0; in_it = 0; - g_memset(text, 0, 512); + g_memset(text, 0, FILE_MAX_LINE_BYTES); list_clear(names); list_clear(values); make_stream(s); @@ -249,10 +263,13 @@ l_file_read_section(int fd, int max_file_size, const char *section, in_uint8(s, c); if ((c == '#') || (c == ';')) { - file_read_line(s, text); + if (file_read_line(s, text, FILE_MAX_LINE_BYTES) != 0) + { + break; + } in_it = 0; in_it_index = 0; - g_memset(text, 0, 512); + g_memset(text, 0, FILE_MAX_LINE_BYTES); continue; } if (c == '[') @@ -263,8 +280,8 @@ l_file_read_section(int fd, int max_file_size, const char *section, { if (g_strcasecmp(section, text) == 0) { - file_read_line(s, text); - while (file_read_line(s, text) == 0) + file_read_line(s, text, FILE_MAX_LINE_BYTES); + while (file_read_line(s, text, FILE_MAX_LINE_BYTES) == 0) { if (g_strlen(text) > 0) { @@ -292,21 +309,27 @@ l_file_read_section(int fd, int max_file_size, const char *section, } free_stream(s); + g_free(data); return 0; } in_it = 0; in_it_index = 0; - g_memset(text, 0, 512); + g_memset(text, 0, FILE_MAX_LINE_BYTES); } else if (in_it) { text[in_it_index] = c; in_it_index++; + if (in_it_index >= FILE_MAX_LINE_BYTES) + { + break; + } } } } free_stream(s); + g_free(data); return 1; } @@ -341,7 +364,7 @@ file_by_name_read_sections(const char *file_name, struct list *names) fd = g_file_open(file_name); - if (fd < 1) + if (fd < 0) { return 1; } @@ -382,7 +405,7 @@ file_by_name_read_section(const char *file_name, const char *section, fd = g_file_open(file_name); - if (fd < 1) + if (fd < 0) { return 1; } diff --git a/common/file.h b/common/file.h index cab4304c..ec3bbcb1 100644 --- a/common/file.h +++ b/common/file.h @@ -1,7 +1,7 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Jay Sorg 2004-2013 + * Copyright (C) Jay Sorg 2004-2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/common/file_loc.h b/common/file_loc.h index c8b3a76f..7389a1ed 100644 --- a/common/file_loc.h +++ b/common/file_loc.h @@ -1,7 +1,7 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Jay Sorg 2004-2012 + * Copyright (C) Jay Sorg 2004-2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,4 +41,28 @@ #define XRDP_LIB_PATH "/usr/local/lib/xrdp" #endif +#if !defined(XRDP_LOG_PATH) +#define XRDP_LOG_PATH "/var/log" +#endif + +#if !defined(XRDP_CHANSRV_STR) +#define XRDP_CHANSRV_STR "/tmp/.xrdp/xrdp_chansrv_socket_%d" +#endif + +#if !defined(CHANSRV_PORT_OUT_STR) +#define CHANSRV_PORT_OUT_STR "/tmp/.xrdp/xrdp_chansrv_audio_out_socket_%d" +#endif + +#if !defined(CHANSRV_PORT_IN_STR) +#define CHANSRV_PORT_IN_STR "/tmp/.xrdp/xrdp_chansrv_audio_in_socket_%d" +#endif + +#if !defined(CHANSRV_API_STR) +#define CHANSRV_API_STR "/tmp/.xrdp/xrdpapi_%d" +#endif + +#if !defined(XRDP_X11RDP_STR) +#define XRDP_X11RDP_STR "/tmp/.xrdp/xrdp_display_%d" +#endif + #endif diff --git a/common/list.c b/common/list.c index 2868d767..9fde1f6f 100644 --- a/common/list.c +++ b/common/list.c @@ -1,7 +1,7 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Jay Sorg 2004-2013 + * Copyright (C) Jay Sorg 2004-2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/common/list.h b/common/list.h index f92cc843..cdc545a0 100644 --- a/common/list.h +++ b/common/list.h @@ -1,7 +1,7 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Jay Sorg 2004-2013 + * Copyright (C) Jay Sorg 2004-2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,11 +26,11 @@ /* list */ struct list { - tbus* items; - int count; - int alloc_size; - int grow_by; - int auto_free; + tintptr* items; + int count; + int alloc_size; + int grow_by; + int auto_free; }; struct list* APP_CC @@ -38,17 +38,17 @@ list_create(void); void APP_CC list_delete(struct list* self); void APP_CC -list_add_item(struct list* self, tbus item); -tbus APP_CC +list_add_item(struct list* self, tintptr item); +tintptr APP_CC list_get_item(struct list* self, int index); void APP_CC list_clear(struct list* self); int APP_CC -list_index_of(struct list* self, tbus item); +list_index_of(struct list* self, tintptr item); void APP_CC list_remove_item(struct list* self, int index); void APP_CC -list_insert_item(struct list* self, int index, tbus item); +list_insert_item(struct list* self, int index, tintptr item); void APP_CC list_append_list_strdup(struct list* self, struct list* dest, int start_index); void APP_CC diff --git a/common/list16.c b/common/list16.c new file mode 100644 index 00000000..5e5c3d7f --- /dev/null +++ b/common/list16.c @@ -0,0 +1,188 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2014 + * + * 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. + * + * simple list + */ + +#include "arch.h" +#include "os_calls.h" +#include "list16.h" + +/*****************************************************************************/ +struct list16 *APP_CC +list16_create(void) +{ + struct list16 *self; + + self = (struct list16 *)g_malloc(sizeof(struct list16), 0); + list16_init(self); + return self; +} + +/*****************************************************************************/ +void APP_CC +list16_delete(struct list16 *self) +{ + if (self == 0) + { + return; + } + + list16_deinit(self); + g_free(self); +} + +/*****************************************************************************/ +void APP_CC +list16_init(struct list16* self) +{ + g_memset(self, 0, sizeof(struct list16)); + self->max_count = 4; + self->items = self->mitems; +} + +/*****************************************************************************/ +void APP_CC +list16_deinit(struct list16* self) +{ + if (self->items != self->mitems) + { + g_free(self->items); + } +} + +/*****************************************************************************/ +void APP_CC +list16_add_item(struct list16 *self, tui16 item) +{ + tui16 *p; + int i; + + if (self->count >= self->max_count) + { + i = self->max_count; + self->max_count += 4; + p = (tui16 *)g_malloc(sizeof(tui16) * self->max_count, 1); + g_memcpy(p, self->items, sizeof(tui16) * i); + if (self->items != self->mitems) + { + g_free(self->items); + } + self->items = p; + } + + self->items[self->count] = item; + self->count++; +} + +/*****************************************************************************/ +tui16 APP_CC +list16_get_item(struct list16 *self, int index) +{ + if (index < 0 || index >= self->count) + { + return 0; + } + + return self->items[index]; +} + +/*****************************************************************************/ +void APP_CC +list16_clear(struct list16 *self) +{ + if (self->items != self->mitems) + { + g_free(self->items); + } + self->count = 0; + self->max_count = 4; + self->items = self->mitems; +} + +/*****************************************************************************/ +int APP_CC +list16_index_of(struct list16 *self, tui16 item) +{ + int i; + + for (i = 0; i < self->count; i++) + { + if (self->items[i] == item) + { + return i; + } + } + + return -1; +} + +/*****************************************************************************/ +void APP_CC +list16_remove_item(struct list16 *self, int index) +{ + int i; + + if (index >= 0 && index < self->count) + { + for (i = index; i < (self->count - 1); i++) + { + self->items[i] = self->items[i + 1]; + } + + self->count--; + } +} + +/*****************************************************************************/ +void APP_CC +list16_insert_item(struct list16 *self, int index, tui16 item) +{ + tui16 *p; + int i; + + if (index == self->count) + { + list16_add_item(self, item); + return; + } + + if (index >= 0 && index < self->count) + { + self->count++; + + if (self->count > self->max_count) + { + i = self->max_count; + self->max_count += 4; + p = (tui16 *)g_malloc(sizeof(tui16) * self->max_count, 1); + g_memcpy(p, self->items, sizeof(tui16) * i); + if (self->items != self->mitems) + { + g_free(self->items); + } + self->items = p; + } + + for (i = (self->count - 2); i >= index; i--) + { + self->items[i + 1] = self->items[i]; + } + + self->items[index] = item; + } +} diff --git a/common/list16.h b/common/list16.h new file mode 100644 index 00000000..1a328ea7 --- /dev/null +++ b/common/list16.h @@ -0,0 +1,56 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2014 + * + * 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. + * + * simple list + */ + +#if !defined(LIST16_H) +#define LIST16_H + +#include "arch.h" + +/* list */ +struct list16 +{ + tui16* items; + int count; + int max_count; + tui16 mitems[4]; +}; + +struct list16* APP_CC +list16_create(void); +void APP_CC +list16_delete(struct list16* self); +void APP_CC +list16_init(struct list16* self); +void APP_CC +list16_deinit(struct list16* self); +void APP_CC +list16_add_item(struct list16* self, tui16 item); +tui16 APP_CC +list16_get_item(struct list16* self, int index); +void APP_CC +list16_clear(struct list16* self); +int APP_CC +list16_index_of(struct list16* self, tui16 item); +void APP_CC +list16_remove_item(struct list16* self, int index); +void APP_CC +list16_insert_item(struct list16* self, int index, tui16 item); + +#endif diff --git a/common/log.c b/common/log.c index 55353a8f..97053178 100644 --- a/common/log.c +++ b/common/log.c @@ -1,7 +1,7 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Jay Sorg 2004-2013 + * Copyright (C) Jay Sorg 2004-2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ #include "log.h" /* Here we store the current state and configuration of the log */ -static struct log_config *staticLogConfig = NULL; +static struct log_config *g_staticLogConfig = NULL; /* This file first start with all private functions. In the end of the file the public functions is defined */ @@ -284,6 +284,7 @@ internalReadConfiguration(const char *inFilename, const char *applicationName) if (ret != LOG_STARTUP_OK) { + g_file_close(fd); return ret; } @@ -296,11 +297,12 @@ internalReadConfiguration(const char *inFilename, const char *applicationName) param_v->auto_free = 1; /* read logging config */ - ret = internal_config_read_logging(fd, staticLogConfig, param_n, + ret = internal_config_read_logging(fd, g_staticLogConfig, param_n, param_v, applicationName); if (ret != LOG_STARTUP_OK) { + g_file_close(fd); return ret; } @@ -392,12 +394,12 @@ enum logReturns DEFAULT_CC internalInitAndAllocStruct(void) { enum logReturns ret = LOG_GENERAL_ERROR; - staticLogConfig = g_malloc(sizeof(struct log_config), 1); + g_staticLogConfig = g_malloc(sizeof(struct log_config), 1); - if (staticLogConfig != NULL) + if (g_staticLogConfig != NULL) { - staticLogConfig->fd = -1; - staticLogConfig->enable_syslog = 0; + g_staticLogConfig->fd = -1; + g_staticLogConfig->enable_syslog = 0; ret = LOG_STARTUP_OK; } else @@ -418,7 +420,7 @@ log_start_from_param(const struct log_config *iniParams) { enum logReturns ret = LOG_GENERAL_ERROR; - if (staticLogConfig != NULL) + if (g_staticLogConfig != NULL) { log_message(LOG_LEVEL_ALWAYS, "Log already initialized"); return ret; @@ -440,24 +442,24 @@ log_start_from_param(const struct log_config *iniParams) return ret; } - staticLogConfig->enable_syslog = iniParams->enable_syslog; - staticLogConfig->fd = iniParams->fd; - staticLogConfig->log_file = g_strdup(iniParams->log_file); - staticLogConfig->log_level = iniParams->log_level; - staticLogConfig->log_lock = iniParams->log_lock; - staticLogConfig->log_lock_attr = iniParams->log_lock_attr; - staticLogConfig->program_name = g_strdup(iniParams->program_name); - staticLogConfig->syslog_level = iniParams->syslog_level; - ret = internal_log_start(staticLogConfig); + g_staticLogConfig->enable_syslog = iniParams->enable_syslog; + g_staticLogConfig->fd = iniParams->fd; + g_staticLogConfig->log_file = g_strdup(iniParams->log_file); + g_staticLogConfig->log_level = iniParams->log_level; + g_staticLogConfig->log_lock = iniParams->log_lock; + g_staticLogConfig->log_lock_attr = iniParams->log_lock_attr; + g_staticLogConfig->program_name = g_strdup(iniParams->program_name); + g_staticLogConfig->syslog_level = iniParams->syslog_level; + ret = internal_log_start(g_staticLogConfig); if (ret != LOG_STARTUP_OK) { g_writeln("Could not start log"); - if (staticLogConfig != NULL) + if (g_staticLogConfig != NULL) { - g_free(staticLogConfig); - staticLogConfig = NULL; + g_free(g_staticLogConfig); + g_staticLogConfig = NULL; } } } @@ -487,16 +489,16 @@ log_start(const char *iniFile, const char *applicationName) if (ret == LOG_STARTUP_OK) { - ret = internal_log_start(staticLogConfig); + ret = internal_log_start(g_staticLogConfig); if (ret != LOG_STARTUP_OK) { g_writeln("Could not start log"); - if (staticLogConfig != NULL) + if (g_staticLogConfig != NULL) { - g_free(staticLogConfig); - staticLogConfig = NULL; + g_free(g_staticLogConfig); + g_staticLogConfig = NULL; } } } @@ -517,12 +519,12 @@ enum logReturns DEFAULT_CC log_end(void) { enum logReturns ret = LOG_GENERAL_ERROR; - ret = internal_log_end(staticLogConfig); + ret = internal_log_end(g_staticLogConfig); - if (staticLogConfig != NULL) + if (g_staticLogConfig != NULL) { - g_free(staticLogConfig); - staticLogConfig = NULL; + g_free(g_staticLogConfig); + g_staticLogConfig = NULL; } return ret; @@ -539,13 +541,13 @@ log_message(const enum logLevels lvl, const char *msg, ...) time_t now_t; struct tm *now; - if (staticLogConfig == NULL) + if (g_staticLogConfig == NULL) { g_writeln("The log reference is NULL - log not initialized properly"); return LOG_ERROR_NO_CFG; } - if (0 > staticLogConfig->fd && staticLogConfig->enable_syslog == 0) + if (0 > g_staticLogConfig->fd && g_staticLogConfig->enable_syslog == 0) { return LOG_ERROR_FILE_NOT_OPEN; } @@ -584,7 +586,7 @@ log_message(const enum logLevels lvl, const char *msg, ...) #endif #endif - if (staticLogConfig->enable_syslog && (lvl <= staticLogConfig->syslog_level)) + if (g_staticLogConfig->enable_syslog && (lvl <= g_staticLogConfig->syslog_level)) { /* log to syslog*/ /* %s fix compiler warning 'not a string literal' */ @@ -592,19 +594,19 @@ log_message(const enum logLevels lvl, const char *msg, ...) tc_get_threadid(), buff + 20); } - if (lvl <= staticLogConfig->log_level) + if (lvl <= g_staticLogConfig->log_level) { /* log to console */ g_printf("%s", buff); /* log to application logfile */ #ifdef LOG_ENABLE_THREAD - pthread_mutex_lock(&(staticLogConfig->log_lock)); + pthread_mutex_lock(&(g_staticLogConfig->log_lock)); #endif - if (staticLogConfig->fd > 0) + if (g_staticLogConfig->fd > 0) { - writereply = g_file_write(staticLogConfig->fd, buff, g_strlen(buff)); + writereply = g_file_write(g_staticLogConfig->fd, buff, g_strlen(buff)); if (writereply <= 0) { @@ -613,7 +615,7 @@ log_message(const enum logLevels lvl, const char *msg, ...) } #ifdef LOG_ENABLE_THREAD - pthread_mutex_unlock(&(staticLogConfig->log_lock)); + pthread_mutex_unlock(&(g_staticLogConfig->log_lock)); #endif } @@ -627,11 +629,11 @@ log_message(const enum logLevels lvl, const char *msg, ...) char *DEFAULT_CC getLogFile(char *replybuf, int bufsize) { - if (staticLogConfig) + if (g_staticLogConfig) { - if (staticLogConfig->log_file) + if (g_staticLogConfig->log_file) { - g_strncpy(replybuf, staticLogConfig->log_file, bufsize); + g_strncpy(replybuf, g_staticLogConfig->log_file, bufsize); } else { diff --git a/common/log.h b/common/log.h index 7a38bf38..b95c615a 100644 --- a/common/log.h +++ b/common/log.h @@ -1,7 +1,7 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Jay Sorg 2004-2013 + * Copyright (C) Jay Sorg 2004-2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,23 +29,23 @@ /* logging levels */ enum logLevels { - LOG_LEVEL_ALWAYS = 0, - LOG_LEVEL_ERROR, - LOG_LEVEL_WARNING, - LOG_LEVEL_INFO, - LOG_LEVEL_DEBUG + LOG_LEVEL_ALWAYS = 0, + LOG_LEVEL_ERROR, + LOG_LEVEL_WARNING, + LOG_LEVEL_INFO, + LOG_LEVEL_DEBUG }; /* startup return values */ enum logReturns { - LOG_STARTUP_OK = 0, - LOG_ERROR_MALLOC, - LOG_ERROR_NULL_FILE, - LOG_ERROR_FILE_OPEN, - LOG_ERROR_NO_CFG, - LOG_ERROR_FILE_NOT_OPEN, - LOG_GENERAL_ERROR + LOG_STARTUP_OK = 0, + LOG_ERROR_MALLOC, + LOG_ERROR_NULL_FILE, + LOG_ERROR_FILE_OPEN, + LOG_ERROR_NO_CFG, + LOG_ERROR_FILE_NOT_OPEN, + LOG_GENERAL_ERROR }; #define SESMAN_CFG_LOGGING "Logging" @@ -65,14 +65,14 @@ enum logReturns struct log_config { - char* program_name; - char* log_file; - int fd; - unsigned int log_level; - int enable_syslog; - unsigned int syslog_level; - pthread_mutex_t log_lock; - pthread_mutexattr_t log_lock_attr; + char *program_name; + char *log_file; + int fd; + unsigned int log_level; + int enable_syslog; + unsigned int syslog_level; + pthread_mutex_t log_lock; + pthread_mutexattr_t log_lock_attr; }; /* internal functions, only used in log.c if this ifdef is defined.*/ @@ -86,7 +86,7 @@ struct log_config * */ enum logReturns DEFAULT_CC -internal_log_start(struct log_config* l_cfg); +internal_log_start(struct log_config *l_cfg); /** * @@ -95,7 +95,7 @@ internal_log_start(struct log_config* l_cfg); * */ enum logReturns DEFAULT_CC -internal_log_end(struct log_config* l_cfg); +internal_log_end(struct log_config *l_cfg); /** * Converts a log level to a string @@ -103,7 +103,7 @@ internal_log_end(struct log_config* l_cfg); * @param str pointer where the string will be stored. */ void DEFAULT_CC -internal_log_lvl2str(const enum logLevels lvl, char* str); +internal_log_lvl2str(const enum logLevels lvl, char *str); /** * @@ -113,7 +113,7 @@ internal_log_lvl2str(const enum logLevels lvl, char* str); * */ enum logLevels DEFAULT_CC -internal_log_text2level(char* s); +internal_log_text2level(char *s); /** * A function that init our struct that holds all state and @@ -133,9 +133,9 @@ internalInitAndAllocStruct(void); * @return */ enum logReturns DEFAULT_CC -internal_config_read_logging(int file, struct log_config* lc, - struct list* param_n, - struct list* param_v, +internal_config_read_logging(int file, struct log_config *lc, + struct list *param_n, + struct list *param_v, const char *applicationName); /*End of internal functions*/ #endif @@ -147,7 +147,7 @@ internal_config_read_logging(int file, struct log_config* lc, * @return LOG_STARTUP_OK on success */ enum logReturns DEFAULT_CC -log_start(const char* iniFile, const char* applicationName); +log_start(const char *iniFile, const char *applicationName); /** * An alternative log_start where the caller gives the params directly. @@ -171,7 +171,7 @@ log_end(void); * @return */ enum logReturns DEFAULT_CC -log_message(const enum logLevels lvl, const char* msg, ...); +log_message(const enum logLevels lvl, const char *msg, ...); /** * @@ -181,7 +181,7 @@ log_message(const enum logLevels lvl, const char* msg, ...); * @return 0 on success, 1 on failure * */ -int APP_CC text2bool(char* s); +int APP_CC text2bool(char *s); /** * This function returns the configured file name for the logfile diff --git a/common/os_calls.c b/common/os_calls.c index 80b2d235..ef057497 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -471,8 +471,11 @@ g_tcp_socket(void) { option_value = 0; option_len = sizeof(option_value); - setsockopt(rv, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&option_value, - option_len); + if (setsockopt(rv, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&option_value, + option_len) < 0) + { + log_message(LOG_LEVEL_ERROR, "g_tcp_socket: setsockopt() failed\n"); + } } } #endif @@ -484,8 +487,11 @@ g_tcp_socket(void) { option_value = 1; option_len = sizeof(option_value); - setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *)&option_value, - option_len); + if (setsockopt(rv, SOL_SOCKET, SO_REUSEADDR, (char *)&option_value, + option_len) < 0) + { + log_message(LOG_LEVEL_ERROR, "g_tcp_socket: setsockopt() failed\n"); + } } } @@ -498,8 +504,11 @@ g_tcp_socket(void) { option_value = 1024 * 32; option_len = sizeof(option_value); - setsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *)&option_value, - option_len); + if (setsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *)&option_value, + option_len) < 0) + { + log_message(LOG_LEVEL_ERROR, "g_tcp_socket: setsockopt() failed\n"); + } } } @@ -768,7 +777,9 @@ g_tcp_local_connect(int sck, const char *port) memset(&s, 0, sizeof(struct sockaddr_un)); s.sun_family = AF_UNIX; - strcpy(s.sun_path, port); + strncpy(s.sun_path, port, sizeof(s.sun_path)); + s.sun_path[sizeof(s.sun_path) - 1] = 0; + return connect(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_un)); #endif } @@ -785,7 +796,10 @@ g_tcp_set_non_blocking(int sck) #else i = fcntl(sck, F_GETFL); i = i | O_NONBLOCK; - fcntl(sck, F_SETFL, i); + if (fcntl(sck, F_SETFL, i) < 0) + { + log_message(LOG_LEVEL_ERROR, "g_tcp_set_non_blocking: fcntl() failed\n"); + } #endif return 0; } @@ -925,7 +939,9 @@ g_tcp_local_bind(int sck, const char *port) memset(&s, 0, sizeof(struct sockaddr_un)); s.sun_family = AF_UNIX; - strcpy(s.sun_path, port); + strncpy(s.sun_path, port, sizeof(s.sun_path)); + s.sun_path[sizeof(s.sun_path) - 1] = 0; + return bind(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_un)); #endif } @@ -1421,7 +1437,12 @@ g_set_wait_obj(tbus obj) return 1; } - sendto(s, "sig", 4, 0, (struct sockaddr *)&sa, sa_size); + if (sendto(s, "sig", 4, 0, (struct sockaddr *)&sa, sa_size) < 0) + { + close(s); + return 1; + } + close(s); return 0; #endif @@ -1934,8 +1955,7 @@ g_mkdir(const char *dirname) #if defined(_WIN32) return 0; #else - mkdir(dirname, S_IRWXU); - return 0; + return mkdir(dirname, S_IRWXU); #endif } @@ -2266,6 +2286,27 @@ g_strncmp(const char *c1, const char *c2, int len) } /*****************************************************************************/ +/* compare up to delim */ +int APP_CC +g_strncmp_d(const char *s1, const char *s2, const char delim, int n) +{ + char c1; + char c2; + + while (n > 0) + { + c1 = *s1++; + c2 = *s2++; + if ((c1 == 0) || (c1 != c2) || (c1 == delim) || (c2 == delim)) + { + return c1 - c2; + } + n--; + } + return c1 - c2; +} + +/*****************************************************************************/ int APP_CC g_strcasecmp(const char *c1, const char *c2) { @@ -2907,8 +2948,12 @@ g_clearenv(void) { #if defined(_WIN32) #else +#if defined(BSD) + environ[0] = 0; +#else environ = 0; #endif +#endif } /*****************************************************************************/ diff --git a/common/os_calls.h b/common/os_calls.h index 06ce8494..1805a6a1 100644 --- a/common/os_calls.h +++ b/common/os_calls.h @@ -1,7 +1,7 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Jay Sorg 2004-2013 + * Copyright (C) Jay Sorg 2004-2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -115,6 +115,7 @@ char* APP_CC g_strdup(const char* in); char* APP_CC g_strndup(const char* in, const unsigned int maxlen); int APP_CC g_strcmp(const char* c1, const char* c2); int APP_CC g_strncmp(const char* c1, const char* c2, int len); +int APP_CC g_strncmp_d(const char* c1, const char* c2, const char delim, int len); int APP_CC g_strcasecmp(const char* c1, const char* c2); int APP_CC g_strncasecmp(const char* c1, const char* c2, int len); int APP_CC g_atoi(const char* str); diff --git a/common/parse.h b/common/parse.h index 69a57ff8..2ae3927b 100644 --- a/common/parse.h +++ b/common/parse.h @@ -1,7 +1,7 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Jay Sorg 2004-2013 + * Copyright (C) Jay Sorg 2004-2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,17 +36,17 @@ /* parser state */ struct stream { - char* p; - char* end; - char* data; - int size; - /* offsets of various headers */ - char* iso_hdr; - char* mcs_hdr; - char* sec_hdr; - char* rdp_hdr; - char* channel_hdr; - char* next_packet; + char *p; + char *end; + char *data; + int size; + /* offsets of various headers */ + char *iso_hdr; + char *mcs_hdr; + char *sec_hdr; + char *rdp_hdr; + char *channel_hdr; + char *next_packet; }; /******************************************************************************/ @@ -63,76 +63,77 @@ struct stream /******************************************************************************/ #define make_stream(s) \ - (s) = (struct stream*)g_malloc(sizeof(struct stream), 1) + (s) = (struct stream*)g_malloc(sizeof(struct stream), 1) /******************************************************************************/ #define init_stream(s, v) do \ { \ - if ((v) > (s)->size) \ - { \ - g_free((s)->data); \ - (s)->data = (char*)g_malloc((v), 0); \ - (s)->size = (v); \ - } \ - (s)->p = (s)->data; \ - (s)->end = (s)->data; \ - (s)->next_packet = 0; \ + if ((v) > (s)->size) \ + { \ + g_free((s)->data); \ + (s)->data = (char*)g_malloc((v), 0); \ + (s)->size = (v); \ + } \ + (s)->p = (s)->data; \ + (s)->end = (s)->data; \ + (s)->next_packet = 0; \ } while (0) /******************************************************************************/ #define free_stream(s) do \ { \ - if ((s) != 0) \ - { \ - g_free((s)->data); \ - } \ - g_free((s)); \ + if ((s) != 0) \ + { \ + g_free((s)->data); \ + } \ + g_free((s)); \ } while (0) /******************************************************************************/ #define s_push_layer(s, h, n) do \ { \ - (s)->h = (s)->p; \ - (s)->p += (n); \ + (s)->h = (s)->p; \ + (s)->p += (n); \ } while (0) /******************************************************************************/ #define s_pop_layer(s, h) \ - (s)->p = (s)->h + (s)->p = (s)->h /******************************************************************************/ #define s_mark_end(s) \ - (s)->end = (s)->p + (s)->end = (s)->p #define in_sint8(s, v) do \ { \ - (v) = *((signed char*)((s)->p)); \ - (s)->p++; \ + (v) = *((signed char*)((s)->p)); \ + (s)->p++; \ } while (0) /******************************************************************************/ #define in_uint8(s, v) do \ { \ - (v) = *((unsigned char*)((s)->p)); \ - (s)->p++; \ + (v) = *((unsigned char*)((s)->p)); \ + (s)->p++; \ } while (0) - +/******************************************************************************/ +#define in_uint8_peek(s, v) do { v = *s->p; } while (0) /******************************************************************************/ #if defined(B_ENDIAN) || defined(NEED_ALIGN) #define in_sint16_le(s, v) do \ { \ - (v) = (signed short) \ - ( \ - (*((unsigned char*)((s)->p + 0)) << 0) | \ - (*((unsigned char*)((s)->p + 1)) << 8) \ - ); \ - (s)->p += 2; \ + (v) = (signed short) \ + ( \ + (*((unsigned char*)((s)->p + 0)) << 0) | \ + (*((unsigned char*)((s)->p + 1)) << 8) \ + ); \ + (s)->p += 2; \ } while (0) #else #define in_sint16_le(s, v) do \ { \ - (v) = *((signed short*)((s)->p)); \ - (s)->p += 2; \ + (v) = *((signed short*)((s)->p)); \ + (s)->p += 2; \ } while (0) #endif @@ -140,49 +141,49 @@ struct stream #if defined(B_ENDIAN) || defined(NEED_ALIGN) #define in_uint16_le(s, v) do \ { \ - (v) = (unsigned short) \ - ( \ - (*((unsigned char*)((s)->p + 0)) << 0) | \ - (*((unsigned char*)((s)->p + 1)) << 8) \ - ); \ - (s)->p += 2; \ + (v) = (unsigned short) \ + ( \ + (*((unsigned char*)((s)->p + 0)) << 0) | \ + (*((unsigned char*)((s)->p + 1)) << 8) \ + ); \ + (s)->p += 2; \ } while (0) #else #define in_uint16_le(s, v) do \ { \ - (v) = *((unsigned short*)((s)->p)); \ - (s)->p += 2; \ + (v) = *((unsigned short*)((s)->p)); \ + (s)->p += 2; \ } while (0) #endif /******************************************************************************/ #define in_uint16_be(s, v) do \ { \ - (v) = *((unsigned char*)((s)->p)); \ - (s)->p++; \ - (v) <<= 8; \ - (v) |= *((unsigned char*)((s)->p)); \ - (s)->p++; \ + (v) = *((unsigned char*)((s)->p)); \ + (s)->p++; \ + (v) <<= 8; \ + (v) |= *((unsigned char*)((s)->p)); \ + (s)->p++; \ } while (0) /******************************************************************************/ #if defined(B_ENDIAN) || defined(NEED_ALIGN) #define in_uint32_le(s, v) do \ { \ - (v) = (unsigned int) \ - ( \ - (*((unsigned char*)((s)->p + 0)) << 0) | \ - (*((unsigned char*)((s)->p + 1)) << 8) | \ - (*((unsigned char*)((s)->p + 2)) << 16) | \ - (*((unsigned char*)((s)->p + 3)) << 24) \ - ); \ - (s)->p += 4; \ + (v) = (unsigned int) \ + ( \ + (*((unsigned char*)((s)->p + 0)) << 0) | \ + (*((unsigned char*)((s)->p + 1)) << 8) | \ + (*((unsigned char*)((s)->p + 2)) << 16) | \ + (*((unsigned char*)((s)->p + 3)) << 24) \ + ); \ + (s)->p += 4; \ } while (0) #else #define in_uint32_le(s, v) do \ { \ - (v) = *((unsigned int*)((s)->p)); \ - (s)->p += 4; \ + (v) = *((unsigned int*)((s)->p)); \ + (s)->p += 4; \ } while (0) #endif @@ -190,41 +191,41 @@ struct stream #if defined(B_ENDIAN) || defined(NEED_ALIGN) #define in_uint64_le(s, v) do \ { \ - (v) = (tui64) \ - ( \ - (((tui64)(*((unsigned char*)((s)->p + 0)))) << 0) | \ - (((tui64)(*((unsigned char*)((s)->p + 1)))) << 8) | \ - (((tui64)(*((unsigned char*)((s)->p + 2)))) << 16) | \ - (((tui64)(*((unsigned char*)((s)->p + 3)))) << 24) | \ - (((tui64)(*((unsigned char*)((s)->p + 4)))) << 32) | \ - (((tui64)(*((unsigned char*)((s)->p + 5)))) << 40) | \ - (((tui64)(*((unsigned char*)((s)->p + 6)))) << 48) | \ - (((tui64)(*((unsigned char*)((s)->p + 7)))) << 56) \ - ); \ - (s)->p += 8; \ + (v) = (tui64) \ + ( \ + (((tui64)(*((unsigned char*)((s)->p + 0)))) << 0) | \ + (((tui64)(*((unsigned char*)((s)->p + 1)))) << 8) | \ + (((tui64)(*((unsigned char*)((s)->p + 2)))) << 16) | \ + (((tui64)(*((unsigned char*)((s)->p + 3)))) << 24) | \ + (((tui64)(*((unsigned char*)((s)->p + 4)))) << 32) | \ + (((tui64)(*((unsigned char*)((s)->p + 5)))) << 40) | \ + (((tui64)(*((unsigned char*)((s)->p + 6)))) << 48) | \ + (((tui64)(*((unsigned char*)((s)->p + 7)))) << 56) \ + ); \ + (s)->p += 8; \ } while (0) #else #define in_uint64_le(s, v) do \ { \ - (v) = *((tui64*)((s)->p)); \ - (s)->p += 8; \ + (v) = *((tui64*)((s)->p)); \ + (s)->p += 8; \ } while (0) #endif /******************************************************************************/ #define in_uint32_be(s, v) do \ { \ - (v) = *((unsigned char*)((s)->p)); \ - (s)->p++; \ - (v) <<= 8; \ - (v) |= *((unsigned char*)((s)->p)); \ - (s)->p++; \ - (v) <<= 8; \ - (v) |= *((unsigned char*)((s)->p)); \ - (s)->p++; \ - (v) <<= 8; \ - (v) |= *((unsigned char*)((s)->p)); \ - (s)->p++; \ + (v) = *((unsigned char*)((s)->p)); \ + (s)->p++; \ + (v) <<= 8; \ + (v) |= *((unsigned char*)((s)->p)); \ + (s)->p++; \ + (v) <<= 8; \ + (v) |= *((unsigned char*)((s)->p)); \ + (s)->p++; \ + (v) <<= 8; \ + (v) |= *((unsigned char*)((s)->p)); \ + (s)->p++; \ } while (0) /******************************************************************************/ @@ -238,46 +239,46 @@ struct stream #if defined(B_ENDIAN) || defined(NEED_ALIGN) #define out_uint16_le(s, v) do \ { \ - *((s)->p) = (unsigned char)((v) >> 0); \ - (s)->p++; \ - *((s)->p) = (unsigned char)((v) >> 8); \ - (s)->p++; \ + *((s)->p) = (unsigned char)((v) >> 0); \ + (s)->p++; \ + *((s)->p) = (unsigned char)((v) >> 8); \ + (s)->p++; \ } while (0) #else #define out_uint16_le(s, v) do \ { \ - *((unsigned short*)((s)->p)) = (unsigned short)(v); \ - (s)->p += 2; \ + *((unsigned short*)((s)->p)) = (unsigned short)(v); \ + (s)->p += 2; \ } while (0) #endif /******************************************************************************/ #define out_uint16_be(s, v) do \ { \ - *((s)->p) = (unsigned char)((v) >> 8); \ - (s)->p++; \ - *((s)->p) = (unsigned char)((v) >> 0); \ - (s)->p++; \ + *((s)->p) = (unsigned char)((v) >> 8); \ + (s)->p++; \ + *((s)->p) = (unsigned char)((v) >> 0); \ + (s)->p++; \ } while (0) /******************************************************************************/ #if defined(B_ENDIAN) || defined(NEED_ALIGN) #define out_uint32_le(s, v) do \ { \ - *((s)->p) = (unsigned char)((v) >> 0); \ - (s)->p++; \ - *((s)->p) = (unsigned char)((v) >> 8); \ - (s)->p++; \ - *((s)->p) = (unsigned char)((v) >> 16); \ - (s)->p++; \ - *((s)->p) = (unsigned char)((v) >> 24); \ - (s)->p++; \ + *((s)->p) = (unsigned char)((v) >> 0); \ + (s)->p++; \ + *((s)->p) = (unsigned char)((v) >> 8); \ + (s)->p++; \ + *((s)->p) = (unsigned char)((v) >> 16); \ + (s)->p++; \ + *((s)->p) = (unsigned char)((v) >> 24); \ + (s)->p++; \ } while (0) #else #define out_uint32_le(s, v) do \ { \ - *((unsigned int*)((s)->p)) = (v); \ - (s)->p += 4; \ + *((unsigned int*)((s)->p)) = (v); \ + (s)->p += 4; \ } while (0) #endif @@ -285,78 +286,78 @@ struct stream #if defined(B_ENDIAN) || defined(NEED_ALIGN) #define out_uint64_le(s, v) do \ { \ - *((s)->p) = (unsigned char)((v) >> 0); \ - (s)->p++; \ - *((s)->p) = (unsigned char)((v) >> 8); \ - (s)->p++; \ - *((s)->p) = (unsigned char)((v) >> 16); \ - (s)->p++; \ - *((s)->p) = (unsigned char)((v) >> 24); \ - (s)->p++; \ - *((s)->p) = (unsigned char)((v) >> 32); \ - (s)->p++; \ - *((s)->p) = (unsigned char)((v) >> 40); \ - (s)->p++; \ - *((s)->p) = (unsigned char)((v) >> 48); \ - (s)->p++; \ - *((s)->p) = (unsigned char)((v) >> 56); \ - (s)->p++; \ + *((s)->p) = (unsigned char)((v) >> 0); \ + (s)->p++; \ + *((s)->p) = (unsigned char)((v) >> 8); \ + (s)->p++; \ + *((s)->p) = (unsigned char)((v) >> 16); \ + (s)->p++; \ + *((s)->p) = (unsigned char)((v) >> 24); \ + (s)->p++; \ + *((s)->p) = (unsigned char)((v) >> 32); \ + (s)->p++; \ + *((s)->p) = (unsigned char)((v) >> 40); \ + (s)->p++; \ + *((s)->p) = (unsigned char)((v) >> 48); \ + (s)->p++; \ + *((s)->p) = (unsigned char)((v) >> 56); \ + (s)->p++; \ } while (0) #else #define out_uint64_le(s, v) do \ { \ - *((tui64*)((s)->p)) = (v); \ - (s)->p += 8; \ + *((tui64*)((s)->p)) = (v); \ + (s)->p += 8; \ } while (0) #endif /******************************************************************************/ #define out_uint32_be(s, v) do \ { \ - *((s)->p) = (unsigned char)((v) >> 24); \ - s->p++; \ - *((s)->p) = (unsigned char)((v) >> 16); \ - s->p++; \ - *((s)->p) = (unsigned char)((v) >> 8); \ - s->p++; \ - *((s)->p) = (unsigned char)(v); \ - (s)->p++; \ + *((s)->p) = (unsigned char)((v) >> 24); \ + s->p++; \ + *((s)->p) = (unsigned char)((v) >> 16); \ + s->p++; \ + *((s)->p) = (unsigned char)((v) >> 8); \ + s->p++; \ + *((s)->p) = (unsigned char)(v); \ + (s)->p++; \ } while (0) /******************************************************************************/ #define in_uint8p(s, v, n) do \ { \ - (v) = (s)->p; \ - (s)->p += (n); \ + (v) = (s)->p; \ + (s)->p += (n); \ } while (0) /******************************************************************************/ #define in_uint8a(s, v, n) do \ { \ - g_memcpy((v), (s)->p, (n)); \ - (s)->p += (n); \ + g_memcpy((v), (s)->p, (n)); \ + (s)->p += (n); \ } while (0) /******************************************************************************/ #define in_uint8s(s, n) \ - (s)->p += (n) + (s)->p += (n) /******************************************************************************/ #define out_uint8p(s, v, n) do \ { \ - g_memcpy((s)->p, (v), (n)); \ - (s)->p += (n); \ + g_memcpy((s)->p, (v), (n)); \ + (s)->p += (n); \ } while (0) /******************************************************************************/ #define out_uint8a(s, v, n) \ - out_uint8p((s), (v), (n)) + out_uint8p((s), (v), (n)) /******************************************************************************/ #define out_uint8s(s, n) do \ { \ - g_memset((s)->p, 0, (n)); \ - (s)->p += (n); \ + g_memset((s)->p, 0, (n)); \ + (s)->p += (n); \ } while (0) /* diff --git a/common/rail.h b/common/rail.h index deed3a9e..26605cd9 100644 --- a/common/rail.h +++ b/common/rail.h @@ -1,7 +1,7 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Jay Sorg 2012 + * Copyright (C) Jay Sorg 2012-2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/common/ssl_calls.c b/common/ssl_calls.c index a187edc9..134f5afd 100644 --- a/common/ssl_calls.c +++ b/common/ssl_calls.c @@ -400,7 +400,8 @@ ssl_gen_key_xrdp1(int key_size_in_bits, char *exp, int exp_len, int error; int len; - if ((exp_len != 4) || (mod_len != 64) || (pri_len != 64)) + if ((exp_len != 4) || ((mod_len != 64) && (mod_len != 256)) || + ((pri_len != 64) && (pri_len != 256))) { return 1; } @@ -469,7 +470,8 @@ ssl_gen_key_xrdp1(int key_size_in_bits, char *exp, int exp_len, int error; int len; - if ((exp_len != 4) || (mod_len != 64) || (pri_len != 64)) + if ((exp_len != 4) || ((mod_len != 64) && (mod_len != 256)) || + ((pri_len != 64) && (pri_len != 256))) { return 1; } diff --git a/common/thread_calls.c b/common/thread_calls.c index b571fb62..a68e902a 100644 --- a/common/thread_calls.c +++ b/common/thread_calls.c @@ -1,7 +1,7 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Jay Sorg 2004-2013 + * Copyright (C) Jay Sorg 2004-2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/common/thread_calls.h b/common/thread_calls.h index 9d2c4a11..2a3122fc 100644 --- a/common/thread_calls.h +++ b/common/thread_calls.h @@ -1,7 +1,7 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Jay Sorg 2004-2013 + * Copyright (C) Jay Sorg 2004-2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/common/trans.c b/common/trans.c index aced0667..5503ea61 100644 --- a/common/trans.c +++ b/common/trans.c @@ -1,7 +1,7 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Jay Sorg 2004-2013 + * Copyright (C) Jay Sorg 2004-2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,12 +24,49 @@ #include "parse.h" /*****************************************************************************/ -struct trans *APP_CC +int APP_CC +trans_tls_recv(struct trans *self, void *ptr, int len) +{ + if (self->tls == NULL) + { + return 1; + } + return xrdp_tls_read(self->tls, ptr, len); +} + +/*****************************************************************************/ +int APP_CC +trans_tls_send(struct trans *self, const void *data, int len) +{ + if (self->tls == NULL) + { + return 1; + } + return xrdp_tls_write(self->tls, data, len); +} + +/*****************************************************************************/ +int APP_CC +trans_tcp_recv(struct trans *self, void *ptr, int len) +{ + return g_tcp_recv(self->sck, ptr, len, 0); +} + +/*****************************************************************************/ +int APP_CC +trans_tcp_send(struct trans *self, const void *data, int len) +{ + return g_tcp_send(self->sck, data, len, 0); +} + +/*****************************************************************************/ +struct trans * +APP_CC trans_create(int mode, int in_size, int out_size) { - struct trans *self = (struct trans *)NULL; + struct trans *self = (struct trans *) NULL; - self = (struct trans *)g_malloc(sizeof(struct trans), 1); + self = (struct trans *) g_malloc(sizeof(struct trans), 1); if (self != NULL) { @@ -38,6 +75,10 @@ trans_create(int mode, int in_size, int out_size) make_stream(self->out_s); init_stream(self->out_s, out_size); self->mode = mode; + self->tls = 0; + /* assign tcp calls by default */ + self->trans_recv = trans_tcp_recv; + self->trans_send = trans_tcp_send; } return self; @@ -68,6 +109,11 @@ trans_delete(struct trans *self) g_free(self->listen_filename); } + if (self->tls != 0) + { + xrdp_tls_delete(self->tls); + } + g_free(self); } @@ -92,8 +138,7 @@ trans_get_wait_objs(struct trans *self, tbus *objs, int *count) /*****************************************************************************/ int APP_CC -trans_get_wait_objs_rw(struct trans *self, - tbus *robjs, int *rcount, +trans_get_wait_objs_rw(struct trans *self, tbus *robjs, int *rcount, tbus *wobjs, int *wcount) { if (self == 0) @@ -138,7 +183,7 @@ send_waiting(struct trans *self, int block) if (g_tcp_can_send(self->sck, timeout)) { bytes = (int) (temp_s->end - temp_s->p); - sent = g_tcp_send(self->sck, temp_s->p, bytes, 0); + sent = self->trans_send(self, temp_s->p, bytes); if (sent > 0) { temp_s->p += sent; @@ -174,8 +219,8 @@ send_waiting(struct trans *self, int block) int APP_CC trans_check_wait_objs(struct trans *self) { - tbus in_sck = (tbus)0; - struct trans *in_trans = (struct trans *)NULL; + tbus in_sck = (tbus) 0; + struct trans *in_trans = (struct trans *) NULL; int read_bytes = 0; int to_read = 0; int read_so_far = 0; @@ -224,8 +269,10 @@ trans_check_wait_objs(struct trans *self) in_trans->type1 = TRANS_TYPE_SERVER; in_trans->status = TRANS_STATUS_UP; in_trans->is_term = self->is_term; - g_strncpy(in_trans->addr, self->addr, sizeof(self->addr) - 1); - g_strncpy(in_trans->port, self->port, sizeof(self->port) - 1); + g_strncpy(in_trans->addr, self->addr, + sizeof(self->addr) - 1); + g_strncpy(in_trans->port, self->port, + sizeof(self->port) - 1); if (self->trans_conn_in(self, in_trans) != 0) { @@ -243,12 +290,12 @@ trans_check_wait_objs(struct trans *self) { if (g_tcp_can_recv(self->sck, 0)) { - read_so_far = (int)(self->in_s->end - self->in_s->data); + read_so_far = (int) (self->in_s->end - self->in_s->data); to_read = self->header_size - read_so_far; if (to_read > 0) { - read_bytes = g_tcp_recv(self->sck, self->in_s->end, to_read, 0); + read_bytes = self->trans_recv(self, self->in_s->end, to_read); if (read_bytes == -1) { @@ -275,7 +322,7 @@ trans_check_wait_objs(struct trans *self) } } - read_so_far = (int)(self->in_s->end - self->in_s->data); + read_so_far = (int) (self->in_s->end - self->in_s->data); if (read_so_far == self->header_size) { @@ -299,7 +346,6 @@ trans_check_wait_objs(struct trans *self) return rv; } - /*****************************************************************************/ int APP_CC trans_force_read_s(struct trans *self, struct stream *in_s, int size) @@ -318,7 +364,9 @@ trans_force_read_s(struct trans *self, struct stream *in_s, int size) { return 1; } - rcvd = g_tcp_recv(self->sck, in_s->end, size, 0); + + rcvd = self->trans_recv(self, in_s->end, size); + if (rcvd == -1) { if (g_tcp_last_error_would_block(self->sck)) @@ -380,7 +428,7 @@ trans_force_write_s(struct trans *self, struct stream *out_s) return 1; } - size = (int)(out_s->end - out_s->data); + size = (int) (out_s->end - out_s->data); total = 0; if (send_waiting(self, 1) != 0) @@ -391,7 +439,7 @@ trans_force_write_s(struct trans *self, struct stream *out_s) while (total < size) { - sent = g_tcp_send(self->sck, out_s->data + total, size - total, 0); + sent = self->trans_send(self, out_s->data + total, size - total); if (sent == -1) { @@ -455,7 +503,7 @@ trans_write_copy(struct trans *self) } out_s = self->out_s; - size = (int)(out_s->end - out_s->data); + size = (int) (out_s->end - out_s->data); make_stream(wait_s); init_stream(wait_s, size); out_uint8a(wait_s, out_s->data, size); @@ -501,12 +549,18 @@ trans_connect(struct trans *self, const char *server, const char *port, if (self->mode == TRANS_MODE_TCP) /* tcp */ { self->sck = g_tcp_socket(); + if (self->sck < 0) + return 1; + g_tcp_set_non_blocking(self->sck); error = g_tcp_connect(self->sck, server, port); } else if (self->mode == TRANS_MODE_UNIX) /* unix socket */ { self->sck = g_tcp_local_socket(); + if (self->sck < 0) + return 1; + g_tcp_set_non_blocking(self->sck); error = g_tcp_local_connect(self->sck, port); } @@ -537,6 +591,10 @@ trans_connect(struct trans *self, const char *server, const char *port, } /*****************************************************************************/ + +/** + * @return 0 on success, 1 on failure + */ int APP_CC trans_listen_address(struct trans *self, char *port, const char *address) { @@ -548,6 +606,9 @@ trans_listen_address(struct trans *self, char *port, const char *address) if (self->mode == TRANS_MODE_TCP) /* tcp */ { self->sck = g_tcp_socket(); + if (self->sck < 0) + return 1; + g_tcp_set_non_blocking(self->sck); if (g_tcp_bind_address(self->sck, port, address) == 0) @@ -565,7 +626,11 @@ trans_listen_address(struct trans *self, char *port, const char *address) g_free(self->listen_filename); self->listen_filename = 0; g_file_delete(port); + self->sck = g_tcp_local_socket(); + if (self->sck < 0) + return 1; + g_tcp_set_non_blocking(self->sck); if (g_tcp_local_bind(self->sck, port) == 0) @@ -574,7 +639,7 @@ trans_listen_address(struct trans *self, char *port, const char *address) if (g_tcp_listen(self->sck) == 0) { - g_chmod_hex(port, 0xffff); + g_chmod_hex(port, 0x0660); self->status = TRANS_STATUS_UP; /* ok */ self->type1 = TRANS_TYPE_LISTENER; /* listener */ return 0; @@ -593,14 +658,15 @@ trans_listen(struct trans *self, char *port) } /*****************************************************************************/ -struct stream *APP_CC +struct stream * +APP_CC trans_get_in_s(struct trans *self) { - struct stream *rv = (struct stream *)NULL; + struct stream *rv = (struct stream *) NULL; if (self == NULL) { - rv = (struct stream *)NULL; + rv = (struct stream *) NULL; } else { @@ -611,14 +677,15 @@ trans_get_in_s(struct trans *self) } /*****************************************************************************/ -struct stream *APP_CC +struct stream * +APP_CC trans_get_out_s(struct trans *self, int size) { - struct stream *rv = (struct stream *)NULL; + struct stream *rv = (struct stream *) NULL; if (self == NULL) { - rv = (struct stream *)NULL; + rv = (struct stream *) NULL; } else { @@ -628,3 +695,43 @@ trans_get_out_s(struct trans *self, int size) return rv; } +/*****************************************************************************/ +/* returns error */ +int APP_CC +trans_set_tls_mode(struct trans *self, const char *key, const char *cert) +{ + self->tls = xrdp_tls_create(self, key, cert); + if (self->tls == NULL) + { + g_writeln("trans_set_tls_mode: xrdp_tls_create malloc error"); + return 1; + } + + if (xrdp_tls_accept(self->tls) != 0) + { + g_writeln("trans_set_tls_mode: xrdp_tls_accept failed"); + return 1; + } + + /* assign tls functions */ + self->trans_recv = trans_tls_recv; + self->trans_send = trans_tls_send; + + return 0; +} +/*****************************************************************************/ +/* returns error */ +int APP_CC +trans_shutdown_tls_mode(struct trans *self) +{ + if (self->tls != NULL) + { + return xrdp_tls_disconnect(self->tls); + } + + /* assign callback back to tcp cal */ + self->trans_recv = trans_tcp_recv; + self->trans_send = trans_tcp_send; + + return 0; +} diff --git a/common/trans.h b/common/trans.h index c2e5e0df..a169e9cb 100644 --- a/common/trans.h +++ b/common/trans.h @@ -1,7 +1,7 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Jay Sorg 2004-2013 + * Copyright (C) Jay Sorg 2004-2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,32 +35,59 @@ #define TRANS_STATUS_UP 1 struct trans; /* forward declaration */ +struct xrdp_tls; -typedef int (*ttrans_data_in)(struct trans* self); -typedef int (*ttrans_conn_in)(struct trans* self, struct trans* new_self); -typedef int (*tis_term)(void); +typedef int (DEFAULT_CC *ttrans_data_in)(struct trans* self); +typedef int (DEFAULT_CC *ttrans_conn_in)(struct trans* self, + struct trans* new_self); +typedef int (DEFAULT_CC *tis_term)(void); +typedef int (APP_CC *trans_recv) (struct trans *self, void *ptr, int len); +typedef int (APP_CC *trans_send) (struct trans *self, const void *data, int len); struct trans { - tbus sck; /* socket handle */ - int mode; /* 1 tcp, 2 unix socket */ - int status; - int type1; /* 1 listener 2 server 3 client */ - ttrans_data_in trans_data_in; - ttrans_conn_in trans_conn_in; - void* callback_data; - int header_size; - struct stream* in_s; - struct stream* out_s; - char* listen_filename; - tis_term is_term; /* used to test for exit */ - struct stream* wait_s; - char addr[256]; - char port[256]; - int no_stream_init_on_data_in; - int extra_flags; /* user defined */ + tbus sck; /* socket handle */ + int mode; /* 1 tcp, 2 unix socket */ + int status; + int type1; /* 1 listener 2 server 3 client */ + ttrans_data_in trans_data_in; + ttrans_conn_in trans_conn_in; + void* callback_data; + int header_size; + struct stream* in_s; + struct stream* out_s; + char* listen_filename; + tis_term is_term; /* used to test for exit */ + struct stream* wait_s; + char addr[256]; + char port[256]; + int no_stream_init_on_data_in; + int extra_flags; /* user defined */ + struct xrdp_tls *tls; + trans_recv trans_recv; + trans_send trans_send; }; +/* xrdp_tls */ +struct xrdp_tls +{ + void *ssl; /* SSL * */ + void *ctx; /* SSL_CTX * */ + char *cert; + char *key; + struct trans *trans; +}; + +/* xrdp_tls.c */ +struct xrdp_tls *APP_CC +xrdp_tls_create(struct trans *trans, const char *key, const char *cert); +int APP_CC +xrdp_tls_accept(struct xrdp_tls *self); +int APP_CC +xrdp_tls_disconnect(struct xrdp_tls *self); +void APP_CC +xrdp_tls_delete(struct xrdp_tls *self); + struct trans* APP_CC trans_create(int mode, int in_size, int out_size); void APP_CC @@ -94,5 +121,13 @@ struct stream* APP_CC trans_get_in_s(struct trans* self); struct stream* APP_CC trans_get_out_s(struct trans* self, int size); +int APP_CC +trans_set_tls_mode(struct trans *self, const char *key, const char *cert); +int APP_CC +trans_shutdown_tls_mode(struct trans *self); +int APP_CC +trans_tcp_force_read_s(struct trans *self, struct stream *in_s, int size); +int APP_CC +trans_force_write_s(struct trans *self, struct stream *out_s); #endif diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h index 50c9f143..7e906c92 100644 --- a/common/xrdp_client_info.h +++ b/common/xrdp_client_info.h @@ -1,7 +1,7 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Jay Sorg 2004-2013 + * Copyright (C) Jay Sorg 2004-2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -106,14 +106,14 @@ struct xrdp_client_info char client_addr[256]; char client_port[256]; - int nego_sec_layer; /* 0, 1, 2 = RDP security layer, TLS , Negotiate */ + int security_layer; /* 0 = rdp, 1 = tls , 2 = hybrid */ int multimon; /* 0 = deny , 1 = allow */ int monitorCount; /* number of monitors detected (max = 16) */ struct monitor_info minfo[16]; /* client monitor data */ int keyboard_type; int keyboard_subtype; - + int png_codec_id; int png_prop_len; char png_prop[64]; @@ -121,6 +121,18 @@ struct xrdp_client_info int mcs_connection_type; int mcs_early_capability_flags; + int max_fastpath_frag_bytes; + int capture_code; + int capture_format; + + char certificate[1024]; + char key_file[1024]; + + /* X11 keyboard layout - inferred from keyboard type/subtype */ + char model[16]; + char layout[16]; + char variant[16]; + }; #endif diff --git a/common/xrdp_constants.h b/common/xrdp_constants.h index ed74fd01..2ee034c3 100644 --- a/common/xrdp_constants.h +++ b/common/xrdp_constants.h @@ -3,7 +3,7 @@ * Miscellaneous protocol constants * * Copyright (C) Matthew Chapman 1999-2008 - * Copyright (C) Jay Sorg 2004-2013 + * Copyright (C) Jay Sorg 2004-2014 * Copyright (C) Kevin Zhou 2012 * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -161,6 +161,7 @@ #define RDP_INPUT_VIRTKEY 2 #define RDP_INPUT_SCANCODE 4 #define RDP_INPUT_MOUSE 0x8001 +#define RDP_INPUT_MOUSEX 0x8002 /* Device flags */ #define KBD_FLAG_RIGHT 0x0001 @@ -560,6 +561,24 @@ #define RDP_CAPSET_LPOINTER 0x27 #define RDP_CAPLEN_LPOINTER 0x06 +/* fastpath input */ +#define FASTPATH_INPUT_SECURE_CHECKSUM 0x1 +#define FASTPATH_INPUT_ENCRYPTED 0x2 + +#define FASTPATH_INPUT_ACTION_FASTPATH 0x0 +#define FASTPATH_INPUT_ACTION_X224 0x3 + +#define FASTPATH_INPUT_EVENT_SCANCODE 0x0 +#define FASTPATH_INPUT_EVENT_MOUSE 0x1 +#define FASTPATH_INPUT_EVENT_MOUSEX 0x2 +#define FASTPATH_INPUT_EVENT_SYNC 0x3 +#define FASTPATH_INPUT_EVENT_UNICODE 0x4 + +#define FASTPATH_INPUT_KBDFLAGS_RELEASE 0x01 +#define FASTPATH_INPUT_KBDFLAGS_EXTENDED 0x02 + + +/* fastpath output */ #define FASTPATH_OUTPUT_ACTION_FASTPATH 0x0 #define FASTPATH_OUTPUT_ACTION_X224 0x3 diff --git a/common/xrdp_rail.h b/common/xrdp_rail.h index 89cd9f95..b93672be 100644 --- a/common/xrdp_rail.h +++ b/common/xrdp_rail.h @@ -1,7 +1,7 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Jay Sorg 2012-2013 + * Copyright (C) Jay Sorg 2012-2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -72,76 +72,76 @@ struct rail_icon_info { - int bpp; - int width; - int height; - int cmap_bytes; - int mask_bytes; - int data_bytes; - char* mask; - char* cmap; - char* data; + int bpp; + int width; + int height; + int cmap_bytes; + int mask_bytes; + int data_bytes; + char *mask; + char *cmap; + char *data; }; struct rail_window_rect { - short left; - short top; - short right; - short bottom; + short left; + short top; + short right; + short bottom; }; struct rail_notify_icon_infotip { - int timeout; - int flags; - char* text; - char* title; + int timeout; + int flags; + char *text; + char *title; }; struct rail_window_state_order { - int owner_window_id; - int style; - int extended_style; - int show_state; - char* title_info; - int client_offset_x; - int client_offset_y; - int client_area_width; - int client_area_height; - int rp_content; - int root_parent_handle; - int window_offset_x; - int window_offset_y; - int window_client_delta_x; - int window_client_delta_y; - int window_width; - int window_height; - int num_window_rects; - struct rail_window_rect* window_rects; - int visible_offset_x; - int visible_offset_y; - int num_visibility_rects; - struct rail_window_rect* visibility_rects; + int owner_window_id; + int style; + int extended_style; + int show_state; + char *title_info; + int client_offset_x; + int client_offset_y; + int client_area_width; + int client_area_height; + int rp_content; + int root_parent_handle; + int window_offset_x; + int window_offset_y; + int window_client_delta_x; + int window_client_delta_y; + int window_width; + int window_height; + int num_window_rects; + struct rail_window_rect *window_rects; + int visible_offset_x; + int visible_offset_y; + int num_visibility_rects; + struct rail_window_rect *visibility_rects; }; struct rail_notify_state_order { - int version; - char* tool_tip; - struct rail_notify_icon_infotip infotip; - int state; - int icon_cache_entry; - int icon_cache_id; - struct rail_icon_info icon_info; + int version; + char *tool_tip; + struct rail_notify_icon_infotip infotip; + int state; + int icon_cache_entry; + int icon_cache_id; + struct rail_icon_info icon_info; }; struct rail_monitored_desktop_order { - int active_window_id; - int num_window_ids; - int* window_ids; + int active_window_id; + int num_window_ids; + int *window_ids; }; #endif diff --git a/common/xrdp_tls.c b/common/xrdp_tls.c new file mode 100644 index 00000000..28f1af55 --- /dev/null +++ b/common/xrdp_tls.c @@ -0,0 +1,269 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Idan Freiberg 2013-2014 + * + * 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. + * + * transport layer security + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <openssl/ssl.h> + +#include "os_calls.h" +#include "trans.h" +#include "ssl_calls.h" + + +/*****************************************************************************/ +struct xrdp_tls * +APP_CC +xrdp_tls_create(struct trans *trans, const char *key, const char *cert) +{ + struct xrdp_tls *self; + self = (struct xrdp_tls *) g_malloc(sizeof(struct xrdp_tls), 1); + + if (self != NULL) + { + self->trans = trans; + self->cert = (char *) cert; + self->key = (char *) key; + } + + return self; +} + +/*****************************************************************************/ +int APP_CC +xrdp_tls_print_error(char *func, SSL *connection, int value) +{ + switch (SSL_get_error(connection, value)) + { + case SSL_ERROR_ZERO_RETURN: + g_writeln("xrdp_tls_print_error: %s: Server closed TLS connection", + func); + return 1; + + case SSL_ERROR_WANT_READ: + g_writeln("xrdp_tls_print_error: SSL_ERROR_WANT_READ"); + return 0; + + case SSL_ERROR_WANT_WRITE: + g_writeln("xrdp_tls_print_error: SSL_ERROR_WANT_WRITE"); + return 0; + + case SSL_ERROR_SYSCALL: + g_writeln("xrdp_tls_print_error: %s: I/O error", func); + return 1; + + case SSL_ERROR_SSL: + g_writeln("xrdp_tls_print_error: %s: Failure in SSL library (protocol error?)", + func); + return 1; + + default: + g_writeln("xrdp_tls_print_error: %s: Unknown error", func); + return 1; + } +} + +/*****************************************************************************/ +int APP_CC +xrdp_tls_accept(struct xrdp_tls *self) +{ + int connection_status; + long options = 0; + + /** + * SSL_OP_NO_SSLv2: + * + * We only want SSLv3 and TLSv1, so disable SSLv2. + * SSLv3 is used by, eg. Microsoft RDC for Mac OS X. + */ + options |= SSL_OP_NO_SSLv2; + +#if defined(SSL_OP_NO_COMPRESSION) + /** + * SSL_OP_NO_COMPRESSION: + * + * The Microsoft RDP server does not advertise support + * for TLS compression, but alternative servers may support it. + * This was observed between early versions of the FreeRDP server + * and the FreeRDP client, and caused major performance issues, + * which is why we're disabling it. + */ + options |= SSL_OP_NO_COMPRESSION; +#endif + + /** + * SSL_OP_TLS_BLOCK_PADDING_BUG: + * + * The Microsoft RDP server does *not* support TLS padding. + * It absolutely needs to be disabled otherwise it won't work. + */ + options |= SSL_OP_TLS_BLOCK_PADDING_BUG; + + /** + * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: + * + * Just like TLS padding, the Microsoft RDP server does not + * support empty fragments. This needs to be disabled. + */ + options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; + + self->ctx = SSL_CTX_new(SSLv23_server_method()); + /* set context options */ + SSL_CTX_set_mode(self->ctx, + SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | + SSL_MODE_ENABLE_PARTIAL_WRITE); + SSL_CTX_set_options(self->ctx, options); + SSL_CTX_set_read_ahead(self->ctx, 1); + + if (self->ctx == NULL) + { + g_writeln("xrdp_tls_accept: SSL_CTX_new failed"); + return 1; + } + + if (SSL_CTX_use_RSAPrivateKey_file(self->ctx, self->key, SSL_FILETYPE_PEM) + <= 0) + { + g_writeln("xrdp_tls_accept: SSL_CTX_use_RSAPrivateKey_file failed"); + return 1; + } + + self->ssl = SSL_new(self->ctx); + + if (self->ssl == NULL) + { + g_writeln("xrdp_tls_accept: SSL_new failed"); + return 1; + } + + if (SSL_use_certificate_file(self->ssl, self->cert, SSL_FILETYPE_PEM) <= 0) + { + g_writeln("xrdp_tls_accept: SSL_use_certificate_file failed"); + return 1; + } + + if (SSL_set_fd(self->ssl, self->trans->sck) < 1) + { + g_writeln("xrdp_tls_accept: SSL_set_fd failed"); + return 1; + } + + connection_status = SSL_accept(self->ssl); + + if (connection_status <= 0) + { + if (xrdp_tls_print_error("SSL_accept", self->ssl, connection_status)) + { + return 1; + } + } + + g_writeln("xrdp_tls_accept: TLS connection accepted"); + + return 0; +} +/*****************************************************************************/ +int APP_CC +xrdp_tls_disconnect(struct xrdp_tls *self) +{ + int status = SSL_shutdown(self->ssl); + while (status != 1) + { + status = SSL_shutdown(self->ssl); + + if (status <= 0) + { + if (xrdp_tls_print_error("SSL_shutdown", self->ssl, status)) + { + return 1; + } + } + } + return 0; +} +/*****************************************************************************/ +void APP_CC +xrdp_tls_delete(struct xrdp_tls *self) +{ + if (self != NULL) + { + if (self->ssl) + SSL_free(self->ssl); + + if (self->ctx) + SSL_CTX_free(self->ctx); + + g_free(self); + } +} +/*****************************************************************************/ +int APP_CC +xrdp_tls_read(struct xrdp_tls *tls, char *data, int length) +{ + int status; + + status = SSL_read(tls->ssl, data, length); + + switch (SSL_get_error(tls->ssl, status)) + { + case SSL_ERROR_NONE: + break; + + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + status = 0; + break; + + default: + xrdp_tls_print_error("SSL_read", tls->ssl, status); + status = -1; + break; + } + + return status; +} +/*****************************************************************************/ +int APP_CC +xrdp_tls_write(struct xrdp_tls *tls, char *data, int length) +{ + int status; + + status = SSL_write(tls->ssl, data, length); + + switch (SSL_get_error(tls->ssl, status)) + { + case SSL_ERROR_NONE: + break; + + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + status = 0; + break; + + default: + xrdp_tls_print_error("SSL_write", tls->ssl, status); + status = -1; + break; + } + + return status; +} + |