diff options
Diffstat (limited to 'common')
| -rw-r--r-- | common/arch.h | 2 | ||||
| -rw-r--r-- | common/log.c | 24 | ||||
| -rw-r--r-- | common/os_calls.c | 183 | ||||
| -rw-r--r-- | common/os_calls.h | 9 | ||||
| -rw-r--r-- | common/parse.h | 32 | ||||
| -rw-r--r-- | common/trans.c | 163 | ||||
| -rw-r--r-- | common/trans.h | 7 | ||||
| -rw-r--r-- | common/xrdp_client_info.h | 7 | ||||
| -rw-r--r-- | common/xrdp_constants.h | 38 |
9 files changed, 434 insertions, 31 deletions
diff --git a/common/arch.h b/common/arch.h index b8780926..6a29b0a9 100644 --- a/common/arch.h +++ b/common/arch.h @@ -1,7 +1,7 @@ /** * xrdp: A Remote Desktop Protocol server. * - * Copyright (C) Jay Sorg 2004-2012 + * Copyright (C) Jay Sorg 2004-2013 * * 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/log.c b/common/log.c index ce0000aa..55353a8f 100644 --- a/common/log.c +++ b/common/log.c @@ -363,7 +363,7 @@ internal_config_read_logging(int file, struct log_config *lc, if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_ENABLE_SYSLOG)) { - lc->enable_syslog = text2bool((char *)list_get_item(param_v, i)); + lc->enable_syslog = g_text2bool((char *)list_get_item(param_v, i)); } if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_SYSLOG_LEVEL)) @@ -413,28 +413,6 @@ internalInitAndAllocStruct(void) * Here below the public functions */ - -/** - * - * @brief Reads sesman configuration - * @param s translates the strings "1", "true" and "yes" in 1 (true) and other strings in 0 - * @return 0 on false, 1 on 1,true, yes - * - */ -int APP_CC -text2bool(char *s) -{ - if ( (g_atoi(s) != 0) || - (0 == g_strcasecmp(s, "true")) || - (0 == g_strcasecmp(s, "on")) || - (0 == g_strcasecmp(s, "yes"))) - { - return 1; - } - - return 0; -} - enum logReturns DEFAULT_CC log_start_from_param(const struct log_config *iniParams) { diff --git a/common/os_calls.c b/common/os_calls.c index f5f5cd60..2d5b4280 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -493,6 +493,96 @@ g_tcp_socket(void) } /*****************************************************************************/ +/* returns error */ +int APP_CC +g_sck_set_send_buffer_bytes(int sck, int bytes) +{ + int option_value; +#if defined(_WIN32) + int option_len; +#else + unsigned int option_len; +#endif + + option_value = bytes; + option_len = sizeof(option_value); + if (setsockopt(sck, SOL_SOCKET, SO_SNDBUF, (char *)&option_value, + option_len) != 0) + { + return 1; + } + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +g_sck_get_send_buffer_bytes(int sck, int *bytes) +{ + int option_value; +#if defined(_WIN32) + int option_len; +#else + unsigned int option_len; +#endif + + option_value = 0; + option_len = sizeof(option_value); + if (getsockopt(sck, SOL_SOCKET, SO_SNDBUF, (char *)&option_value, + &option_len) != 0) + { + return 1; + } + *bytes = option_value; + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +g_sck_set_recv_buffer_bytes(int sck, int bytes) +{ + int option_value; +#if defined(_WIN32) + int option_len; +#else + unsigned int option_len; +#endif + + option_value = bytes; + option_len = sizeof(option_value); + if (setsockopt(sck, SOL_SOCKET, SO_RCVBUF, (char *)&option_value, + option_len) != 0) + { + return 1; + } + return 0; +} + +/*****************************************************************************/ +/* returns error */ +int APP_CC +g_sck_get_recv_buffer_bytes(int sck, int *bytes) +{ + int option_value; +#if defined(_WIN32) + int option_len; +#else + unsigned int option_len; +#endif + + option_value = 0; + option_len = sizeof(option_value); + if (getsockopt(sck, SOL_SOCKET, SO_RCVBUF, (char *)&option_value, + &option_len) != 0) + { + return 1; + } + *bytes = option_value; + return 0; +} + +/*****************************************************************************/ int APP_CC g_tcp_local_socket(void) { @@ -504,6 +594,38 @@ g_tcp_local_socket(void) } /*****************************************************************************/ +int APP_CC +g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid) +{ + int ucred_length; + struct myucred + { + pid_t pid; + uid_t uid; + gid_t gid; + } credentials; + + ucred_length = sizeof(credentials); + if (getsockopt(sck, SOL_SOCKET, SO_PEERCRED, &credentials, &ucred_length)) + { + return 1; + } + if (pid != 0) + { + *pid = credentials.pid; + } + if (uid != 0) + { + *uid = credentials.uid; + } + if (gid != 0) + { + *gid = credentials.gid; + } + return 0; +} + +/*****************************************************************************/ void APP_CC g_tcp_close(int sck) { @@ -848,6 +970,41 @@ g_tcp_accept(int sck) } /*****************************************************************************/ +int APP_CC +g_sck_accept(int sck, char *addr, int addr_bytes, char *port, int port_bytes) +{ + int ret; + char ipAddr[256]; + struct sockaddr_in s; +#if defined(_WIN32) + signed int i; +#else + unsigned int i; +#endif + + i = sizeof(struct sockaddr_in); + memset(&s, 0, i); + ret = accept(sck, (struct sockaddr *)&s, &i); + if (ret > 0) + { + g_snprintf(ipAddr, 255, "A connection received from: %s port %d", + inet_ntoa(s.sin_addr), ntohs(s.sin_port)); + log_message(LOG_LEVEL_INFO,ipAddr); + if (s.sin_family == AF_INET) + { + g_snprintf(addr, addr_bytes, "%s", inet_ntoa(s.sin_addr)); + g_snprintf(port, port_bytes, "%d", ntohs(s.sin_port)); + } + if (s.sin_family == AF_UNIX) + { + g_strncpy(addr, "", addr_bytes - 1); + g_strncpy(port, "", port_bytes - 1); + } + } + return ret; +} + +/*****************************************************************************/ void APP_CC g_write_ip_address(int rcv_sck, char *ip_address, int bytes) { @@ -2501,6 +2658,17 @@ g_signal_child_stop(void (*func)(int)) } /*****************************************************************************/ + +void APP_CC +g_signal_segfault(void (*func)(int)) +{ +#if defined(_WIN32) +#else + signal(SIGSEGV, func); +#endif +} + +/*****************************************************************************/ /* does not work in win32 */ void APP_CC g_signal_hang_up(void (*func)(int)) @@ -2935,3 +3103,18 @@ g_time3(void) return (tp.tv_sec * 1000) + (tp.tv_usec / 1000); #endif } + +/*****************************************************************************/ +/* returns boolean */ +int APP_CC +g_text2bool(const char *s) +{ + if ( (g_atoi(s) != 0) || + (0 == g_strcasecmp(s, "true")) || + (0 == g_strcasecmp(s, "on")) || + (0 == g_strcasecmp(s, "yes"))) + { + return 1; + } + return 0; +} diff --git a/common/os_calls.h b/common/os_calls.h index cba37588..b6e1c91a 100644 --- a/common/os_calls.h +++ b/common/os_calls.h @@ -45,7 +45,12 @@ int APP_CC g_getchar(void); int APP_CC g_tcp_set_no_delay(int sck); int APP_CC g_tcp_set_keepalive(int sck); int APP_CC g_tcp_socket(void); +int APP_CC g_sck_set_send_buffer_bytes(int sck, int bytes); +int APP_CC g_sck_get_send_buffer_bytes(int sck, int *bytes); +int APP_CC g_sck_set_recv_buffer_bytes(int sck, int bytes); +int APP_CC g_sck_get_recv_buffer_bytes(int sck, int *bytes); int APP_CC g_tcp_local_socket(void); +int APP_CC g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid); void APP_CC g_tcp_close(int sck); int APP_CC g_tcp_connect(int sck, const char* address, const char* port); int APP_CC g_tcp_local_connect(int sck, const char* port); @@ -57,6 +62,8 @@ int APP_CC g_tcp_local_bind(int sck, const char* port); int APP_CC g_tcp_bind_address(int sck, const char* port, const char* address); int APP_CC g_tcp_listen(int sck); int APP_CC g_tcp_accept(int sck); +int APP_CC g_sck_accept(int sck, char *addr, int addr_bytes, + char *port, int port_bytes); int APP_CC g_tcp_recv(int sck, void* ptr, int len, int flags); int APP_CC g_tcp_send(int sck, const void* ptr, int len, int flags); int APP_CC g_tcp_last_error_would_block(int sck); @@ -125,6 +132,7 @@ int APP_CC g_get_errno(void); int APP_CC g_execvp(const char* p1, char* args[]); int APP_CC g_execlp3(const char* a1, const char* a2, const char* a3); void APP_CC g_signal_child_stop(void (*func)(int)); +void APP_CC g_signal_segfault(void (*func)(int)); void APP_CC g_signal_hang_up(void (*func)(int)); void APP_CC g_signal_user_interrupt(void (*func)(int)); void APP_CC g_signal_kill(void (*func)(int)); @@ -152,5 +160,6 @@ int APP_CC g_check_user_in_group(const char* username, int gid, int* ok); int APP_CC g_time1(void); int APP_CC g_time2(void); int APP_CC g_time3(void); +int APP_CC g_text2bool(const char *s); #endif diff --git a/common/parse.h b/common/parse.h index f92e76de..69a57ff8 100644 --- a/common/parse.h +++ b/common/parse.h @@ -56,6 +56,9 @@ struct stream #define s_check_rem(s, n) ((s)->p + (n) <= (s)->end) /******************************************************************************/ +#define s_check_rem_out(s, n) ((s)->p + (n) <= (s)->data + (s)->size) + +/******************************************************************************/ #define s_check_end(s) ((s)->p == (s)->end) /******************************************************************************/ @@ -279,6 +282,35 @@ struct stream #endif /******************************************************************************/ +#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++; \ +} while (0) +#else +#define out_uint64_le(s, v) do \ +{ \ + *((tui64*)((s)->p)) = (v); \ + (s)->p += 8; \ +} while (0) +#endif + +/******************************************************************************/ #define out_uint32_be(s, v) do \ { \ *((s)->p) = (unsigned char)((v) >> 24); \ diff --git a/common/trans.c b/common/trans.c index e862249e..bb349298 100644 --- a/common/trans.c +++ b/common/trans.c @@ -92,6 +92,86 @@ 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, + tbus *wobjs, int *wcount) +{ + if (self == 0) + { + return 1; + } + + if (self->status != TRANS_STATUS_UP) + { + return 1; + } + + robjs[*rcount] = self->sck; + (*rcount)++; + + if (self->wait_s != 0) + { + wobjs[*wcount] = self->sck; + (*wcount)++; + } + + return 0; +} + +/*****************************************************************************/ +int APP_CC +send_waiting(struct trans *self, int block) +{ + struct stream *temp_s; + int bytes; + int sent; + int timeout; + int cont; + + timeout = block ? 100 : 0; + cont = 1; + while (cont) + { + if (self->wait_s != 0) + { + temp_s = self->wait_s; + 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); + if (sent > 0) + { + temp_s->p += sent; + if (temp_s->p >= temp_s->end) + { + self->wait_s = (struct stream *) (temp_s->next_packet); + free_stream(temp_s); + } + } + else if (sent == 0) + { + return 1; + } + else + { + if (!g_tcp_last_error_would_block(self->sck)) + { + return 1; + } + } + } + } + else + { + break; + } + cont = block; + } + return 0; +} + +/*****************************************************************************/ +int APP_CC trans_check_wait_objs(struct trans *self) { tbus in_sck = (tbus)0; @@ -117,7 +197,8 @@ trans_check_wait_objs(struct trans *self) { if (g_tcp_can_recv(self->sck, 0)) { - in_sck = g_tcp_accept(self->sck); + in_sck = g_sck_accept(self->sck, self->addr, sizeof(self->addr), + self->port, sizeof(self->port)); if (in_sck == -1) { @@ -142,6 +223,9 @@ trans_check_wait_objs(struct trans *self) in_trans->sck = in_sck; 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); if (self->trans_conn_in(self, in_trans) != 0) { @@ -202,6 +286,12 @@ trans_check_wait_objs(struct trans *self) } } } + if (send_waiting(self, 0) != 0) + { + /* error */ + self->status = TRANS_STATUS_DOWN; + return 1; + } } return rv; @@ -220,15 +310,28 @@ trans_force_read_s(struct trans *self, struct stream *in_s, int size) while (size > 0) { + /* make sure stream has room */ + if ((in_s->end + size) > (in_s->data + in_s->size)) + { + return 1; + } rcvd = g_tcp_recv(self->sck, in_s->end, size, 0); - if (rcvd == -1) { if (g_tcp_last_error_would_block(self->sck)) { - if (!g_tcp_can_recv(self->sck, 10)) + if (!g_tcp_can_recv(self->sck, 100)) { /* check for term here */ + if (self->is_term != 0) + { + if (self->is_term()) + { + /* term */ + self->status = TRANS_STATUS_DOWN; + return 1; + } + } } } else @@ -277,6 +380,12 @@ trans_force_write_s(struct trans *self, struct stream *out_s) size = (int)(out_s->end - out_s->data); total = 0; + if (send_waiting(self, 1) != 0) + { + self->status = TRANS_STATUS_DOWN; + return 1; + } + while (total < size) { sent = g_tcp_send(self->sck, out_s->data + total, size - total, 0); @@ -285,9 +394,18 @@ trans_force_write_s(struct trans *self, struct stream *out_s) { if (g_tcp_last_error_would_block(self->sck)) { - if (!g_tcp_can_send(self->sck, 10)) + if (!g_tcp_can_send(self->sck, 100)) { /* check for term here */ + if (self->is_term != 0) + { + if (self->is_term()) + { + /* term */ + self->status = TRANS_STATUS_DOWN; + return 1; + } + } } } else @@ -321,6 +439,43 @@ trans_force_write(struct trans *self) /*****************************************************************************/ int APP_CC +trans_write_copy(struct trans *self) +{ + int size; + struct stream *out_s; + struct stream *wait_s; + struct stream *temp_s; + + if (self->status != TRANS_STATUS_UP) + { + return 1; + } + + out_s = self->out_s; + 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); + s_mark_end(wait_s); + wait_s->p = wait_s->data; + if (self->wait_s == 0) + { + self->wait_s = wait_s; + } + else + { + temp_s = self->wait_s; + while (temp_s->next_packet != 0) + { + temp_s = (struct stream *) (temp_s->next_packet); + } + temp_s->next_packet = (char *) wait_s; + } + return 0; +} + +/*****************************************************************************/ +int APP_CC trans_connect(struct trans *self, const char *server, const char *port, int timeout) { diff --git a/common/trans.h b/common/trans.h index 8daa980a..350f05cc 100644 --- a/common/trans.h +++ b/common/trans.h @@ -38,6 +38,7 @@ struct trans; /* forward declaration */ 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); struct trans { @@ -52,6 +53,10 @@ struct trans 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]; }; struct trans* APP_CC @@ -71,6 +76,8 @@ trans_force_read(struct trans* self, int size); int APP_CC trans_force_write(struct trans* self); int APP_CC +trans_write_copy(struct trans* self); +int APP_CC trans_connect(struct trans* self, const char* server, const char* port, int timeout); int APP_CC diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h index 43ff3f82..effac271 100644 --- a/common/xrdp_client_info.h +++ b/common/xrdp_client_info.h @@ -38,6 +38,7 @@ struct xrdp_client_info int bitmap_cache_version; /* ored 1 = original version, 2 = v2, 4 = v3 */ /* pointer info */ int pointer_cache_entries; + int pointer_flags; /* 0 color, 1 new, 2 no new */ /* other */ int use_bitmap_comp; int use_bitmap_cache; @@ -69,6 +70,9 @@ struct xrdp_client_info int offscreen_cache_size; int offscreen_cache_entries; int rfx; + int nego_sec_layer; /* 0, 1, 2 = RDP security layer, TLS , Negotiate */ + int multimon; /* 0 = deny , 1 = allow */ + /* CAPSETTYPE_RAIL */ int rail_support_level; /* CAPSETTYPE_WINDOW */ @@ -90,9 +94,10 @@ struct xrdp_client_info char orders[32]; int order_flags_ex; int use_bulk_comp; - int pointer_flags; /* 0 color, 1 new, 2 no new */ int use_fast_path; int require_credentials; /* when true, credentials *must* be passed on cmd line */ + char client_addr[256]; + char client_port[256]; }; #endif diff --git a/common/xrdp_constants.h b/common/xrdp_constants.h index b978d2de..ed74fd01 100644 --- a/common/xrdp_constants.h +++ b/common/xrdp_constants.h @@ -25,12 +25,36 @@ /* TCP port for Remote Desktop Protocol */ #define TCP_PORT_RDP 3389 -#define ISO_PDU_CR 0xE0 /* Connection Request */ -#define ISO_PDU_CC 0xD0 /* Connection Confirm */ +#define ISO_PDU_CR 0xE0 /* X.224 Connection Request */ +#define ISO_PDU_CC 0xD0 /* X.224 Connection Confirm */ #define ISO_PDU_DR 0x80 /* Disconnect Request */ #define ISO_PDU_DT 0xF0 /* Data */ #define ISO_PDU_ER 0x70 /* Error */ + +/* RDP Security Negotiation codes */ +#define RDP_NEG_REQ 0x01 +#define RDP_NEG_RSP 0x02 +#define RDP_NEG_FAILURE 0x03 +#define RDP_CORRELATION_INFO 0x06 +/* Protocol types codes */ +#define PROTOCOL_RDP 0x0 +#define PROTOCOL_SSL 0x1 +#define PROTOCOL_HYBRID 0x2 +#define PROTOCOL_HYBRID_EX 0x8 +/* Negotiation packet flags */ +#define EXTENDED_CLIENT_DATA_SUPPORTED 0x1 +#define DYNVC_GFX_PROTOCOL_SUPPORTED 0x2 +#define RDP_NEGRSP_RESERVED 0x4 +/* Failure Codes */ +#define SSL_REQUIRED_BY_SERVER 0x1 +#define SSL_NOT_ALLOWED_BY_SERVER 0x2 +#define SSL_CERT_NOT_ON_SERVER 0x3 +#define INCONSISTENT_FLAGS 0x4 +#define HYBRID_REQUIRED_BY_SERVER 0x5 +#define SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER 0x6 + + /* MCS PDU codes */ #define MCS_EDRQ 1 /* Erect Domain Request */ #define MCS_DPUM 8 /* Disconnect Provider Ultimatum */ @@ -72,6 +96,7 @@ #define SEC_TAG_CLI_CRYPT 0xc002 #define SEC_TAG_CLI_CHANNELS 0xc003 #define SEC_TAG_CLI_4 0xc004 +#define SEC_TAG_CLI_MONITOR 0xc005 #define SEC_TAG_PUBKEY 0x0006 #define SEC_TAG_KEYSIG 0x0008 @@ -416,6 +441,7 @@ #define RDP_ORDER_TRIBLT 14 #define RDP_ORDER_POLYLINE 22 #define RDP_ORDER_TEXT2 27 +#define RDP_ORDER_COMPOSITE 37 /* 0x25 */ #define RDP_ORDER_RAW_BMPCACHE 0 #define RDP_ORDER_COLCACHE 1 @@ -463,6 +489,10 @@ #define WM_BUTTON4DOWN 108 #define WM_BUTTON5UP 109 #define WM_BUTTON5DOWN 110 +#define WM_BUTTON6UP 111 +#define WM_BUTTON6DOWN 112 +#define WM_BUTTON7UP 113 +#define WM_BUTTON7DOWN 114 #define WM_INVALIDATE 200 #define CB_ITEMCHANGE 300 @@ -559,4 +589,8 @@ #define CMDTYPE_FRAME_MARKER 0x0004 #define CMDTYPE_STREAM_SURFACE_BITS 0x0006 +#define XRDP_MAX_BITMAP_CACHE_ID 3 +#define XRDP_MAX_BITMAP_CACHE_IDX 2000 +#define XRDP_BITMAP_CACHE_ENTRIES 2048 + #endif |
