summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/arch.h2
-rw-r--r--common/log.c24
-rw-r--r--common/os_calls.c183
-rw-r--r--common/os_calls.h9
-rw-r--r--common/parse.h32
-rw-r--r--common/trans.c163
-rw-r--r--common/trans.h7
-rw-r--r--common/xrdp_client_info.h7
-rw-r--r--common/xrdp_constants.h38
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