summaryrefslogtreecommitdiffstats
path: root/sesman
diff options
context:
space:
mode:
Diffstat (limited to 'sesman')
-rw-r--r--sesman/chansrv/Makefile.am10
-rw-r--r--sesman/chansrv/chansrv.c135
-rw-r--r--sesman/chansrv/chansrv_fuse.c86
-rw-r--r--sesman/chansrv/chansrv_fuse.h4
-rw-r--r--sesman/chansrv/clipboard.c7
-rw-r--r--sesman/chansrv/clipboard_file.c8
-rw-r--r--sesman/chansrv/devredir.c39
-rw-r--r--sesman/chansrv/pcsc/xrdp_pcsc.c129
-rw-r--r--sesman/chansrv/pulse/module-xrdp-sink.c28
-rw-r--r--sesman/chansrv/pulse/module-xrdp-source.c22
-rw-r--r--sesman/chansrv/rail.c93
-rw-r--r--sesman/chansrv/smartcard.c5
-rw-r--r--sesman/chansrv/smartcard_pcsc.c2
-rw-r--r--sesman/chansrv/sound.c410
-rw-r--r--sesman/chansrv/sound.h20
-rw-r--r--sesman/config.c110
-rw-r--r--sesman/config.h58
-rw-r--r--sesman/env.c26
-rw-r--r--sesman/env.h5
-rw-r--r--sesman/libscp/libscp_session.c8
-rw-r--r--sesman/libscp/libscp_types.h2
-rw-r--r--sesman/libscp/libscp_v0.c12
-rw-r--r--sesman/scp_v0.c13
-rw-r--r--sesman/scp_v1.c3
-rw-r--r--sesman/sesman.c30
-rw-r--r--sesman/sesman.ini49
-rw-r--r--sesman/session.c161
-rw-r--r--sesman/session.h9
-rw-r--r--sesman/sig.c1
-rw-r--r--sesman/tools/dis.c7
-rw-r--r--sesman/tools/sesadmin.c16
-rw-r--r--sesman/tools/sesrun.c3
-rw-r--r--sesman/tools/sestest.c3
-rw-r--r--sesman/verify_user_pam.c3
34 files changed, 952 insertions, 565 deletions
diff --git a/sesman/chansrv/Makefile.am b/sesman/chansrv/Makefile.am
index 9aa3ebe7..81218db1 100644
--- a/sesman/chansrv/Makefile.am
+++ b/sesman/chansrv/Makefile.am
@@ -16,21 +16,11 @@ EXTRA_INCLUDES =
EXTRA_LIBS =
EXTRA_FLAGS =
-if XRDP_SIMPLESOUND
-EXTRA_DEFINES += -DXRDP_SIMPLESOUND
-EXTRA_LIBS += -lpthread -lpulse -lpulse-simple
-endif
-
if XRDP_FUSE
EXTRA_DEFINES += -DXRDP_FUSE
EXTRA_LIBS += -lfuse
endif
-if XRDP_LOAD_PULSE_MODULES
-EXTRA_DEFINES += -DXRDP_LOAD_PULSE_MODULES
-EXTRA_LIBS += -lpulse
-endif
-
AM_CFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c
index a89957ba..af2f6957 100644
--- a/sesman/chansrv/chansrv.c
+++ b/sesman/chansrv/chansrv.c
@@ -38,7 +38,7 @@
static struct trans *g_lis_trans = 0;
static struct trans *g_con_trans = 0;
static struct trans *g_api_lis_trans = 0;
-static struct trans *g_api_con_trans = 0;
+static struct list *g_api_con_trans_list = 0; /* list of apps using api functions */
static struct chan_item g_chan_items[32];
static int g_num_chan_items = 0;
static int g_cliprdr_index = -1;
@@ -608,7 +608,10 @@ process_message_channel_data(struct stream *s)
int rv = 0;
int length = 0;
int total_length = 0;
+ int index;
struct stream *ls;
+ struct trans *ltran;
+ struct xrdp_api_data *api_data;
in_uint16_le(s, chan_id);
in_uint16_le(s, chan_flags);
@@ -641,29 +644,36 @@ process_message_channel_data(struct stream *s)
{
rv = drdynvc_data_in(s, chan_id, chan_flags, length, total_length);
}
- else if ((g_api_con_trans != 0) &&
- (chan_id == ((struct xrdp_api_data *)
- (g_api_con_trans->callback_data))->chan_id))
+ else if (g_api_con_trans_list != 0)
{
- LOG(10, ("process_message_channel_data length %d total_length %d "
- "chan_flags 0x%8.8x", length, total_length, chan_flags));
- ls = g_api_con_trans->out_s;
-
- if (chan_flags & 1) /* first */
- {
- init_stream(ls, total_length);
- }
-
- out_uint8a(ls, s->p, length);
-
- if (chan_flags & 2) /* last */
+ for (index = 0; index < g_api_con_trans_list->count; index++)
{
- s_mark_end(ls);
- rv = trans_force_write(g_api_con_trans);
+ ltran = (struct trans *) list_get_item(g_api_con_trans_list, index);
+ if (ltran != 0)
+ {
+ api_data = (struct xrdp_api_data *) (ltran->callback_data);
+ if (api_data != 0)
+ {
+ if (api_data->chan_id == chan_id)
+ {
+ ls = ltran->out_s;
+ if (chan_flags & 1) /* first */
+ {
+ init_stream(ls, total_length);
+ }
+ out_uint8a(ls, s->p, length);
+ if (chan_flags & 2) /* last */
+ {
+ s_mark_end(ls);
+ rv = trans_force_write(ltran);
+ }
+ break;
+ }
+ }
+ }
}
}
}
-
return rv;
}
@@ -796,9 +806,12 @@ my_api_trans_data_in(struct trans *trans)
return 0;
}
- if (trans != g_api_con_trans)
+ if (g_api_con_trans_list != 0)
{
- return 1;
+ if (list_index_of(g_api_con_trans_list, (tintptr) trans) == -1)
+ {
+ return 1;
+ }
}
LOGM((LOG_LEVEL_DEBUG, "my_api_trans_data_in:"));
@@ -812,7 +825,8 @@ my_api_trans_data_in(struct trans *trans)
in_uint8s(s, 12);
in_uint32_le(s, bytes_read);
init_stream(s, bytes_read);
- trans_force_read(trans, bytes_read);
+ if (trans_force_read(trans, bytes_read))
+ log_message(LOG_LEVEL_ERROR, "chansrv.c: error reading from transport");
}
else if (g_tcp_select(trans->sck, 0) & 1)
{
@@ -932,6 +946,7 @@ my_api_trans_conn_in(struct trans *trans, struct trans *new_trans)
{
LOG(0, ("my_api_trans_conn_in: trans_force_read failed"));
trans_delete(new_trans);
+ return 1;
}
s->end = s->data;
@@ -987,10 +1002,13 @@ my_api_trans_conn_in(struct trans *trans, struct trans *new_trans)
new_trans->callback_data = ad;
- trans_delete(g_api_con_trans);
- g_api_con_trans = new_trans;
- g_api_con_trans->trans_data_in = my_api_trans_data_in;
- g_api_con_trans->header_size = 0;
+ if (g_api_con_trans_list == 0)
+ {
+ g_api_con_trans_list = list_create();
+ }
+ new_trans->trans_data_in = my_api_trans_data_in;
+ new_trans->header_size = 0;
+ list_add_item(g_api_con_trans_list, (tintptr) new_trans);
return 0;
}
@@ -1011,8 +1029,7 @@ setup_listen(void)
{
g_lis_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
g_lis_trans->is_term = g_is_term;
- g_snprintf(port, 255, "/tmp/.xrdp/xrdp_chansrv_socket_%d",
- 7200 + g_display_num);
+ g_snprintf(port, 255, XRDP_CHANSRV_STR, g_display_num);
}
else
{
@@ -1043,7 +1060,7 @@ setup_api_listen(void)
g_api_lis_trans = trans_create(TRANS_MODE_UNIX, 8192 * 4, 8192 * 4);
g_api_lis_trans->is_term = g_is_term;
- g_snprintf(port, 255, "/tmp/.xrdp/xrdpapi_%d", g_display_num);
+ g_snprintf(port, 255, CHANSRV_API_STR, g_display_num);
g_api_lis_trans->trans_conn_in = my_api_trans_conn_in;
error = trans_listen(g_api_lis_trans, port);
@@ -1067,7 +1084,9 @@ channel_thread_loop(void *in_val)
int num_wobjs;
int timeout;
int error;
+ int index;
THREAD_RV rv;
+ struct trans *ltran;
LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread start"));
rv = 0;
@@ -1137,19 +1156,20 @@ channel_thread_loop(void *in_val)
}
}
- LOG(10, ("0 %p", g_api_con_trans));
-
- if (g_api_con_trans != 0)
+ if (g_api_con_trans_list != 0)
{
- LOG(10, ("1 %p %d", g_api_con_trans, g_tcp_can_recv(g_api_con_trans->sck, 0)));
-
- if (trans_check_wait_objs(g_api_con_trans) != 0)
+ for (index = g_api_con_trans_list->count - 1; index >= 0; index--)
{
- LOG(10, ("channel_thread_loop: trans_check_wait_objs failed, "
- "or disconnected"));
- g_free(g_api_con_trans->callback_data);
- trans_delete(g_api_con_trans);
- g_api_con_trans = 0;
+ ltran = (struct trans *) list_get_item(g_api_con_trans_list, index);
+ if (ltran != 0)
+ {
+ if (trans_check_wait_objs(ltran) != 0)
+ {
+ list_remove_item(g_api_con_trans_list, index);
+ g_free(ltran->callback_data);
+ trans_delete(ltran);
+ }
+ }
}
}
@@ -1166,7 +1186,19 @@ channel_thread_loop(void *in_val)
trans_get_wait_objs_rw(g_con_trans, objs, &num_objs,
wobjs, &num_wobjs);
trans_get_wait_objs(g_api_lis_trans, objs, &num_objs);
- trans_get_wait_objs(g_api_con_trans, objs, &num_objs);
+
+ if (g_api_con_trans_list != 0)
+ {
+ for (index = g_api_con_trans_list->count - 1; index >= 0; index--)
+ {
+ ltran = (struct trans *) list_get_item(g_api_con_trans_list, index);
+ if (ltran != 0)
+ {
+ trans_get_wait_objs(ltran, objs, &num_objs);
+ }
+ }
+ }
+
xcommon_get_wait_objs(objs, &num_objs, &timeout);
sound_get_wait_objs(objs, &num_objs, &timeout);
dev_redir_get_wait_objs(objs, &num_objs, &timeout);
@@ -1181,8 +1213,20 @@ channel_thread_loop(void *in_val)
g_con_trans = 0;
trans_delete(g_api_lis_trans);
g_api_lis_trans = 0;
- trans_delete(g_api_con_trans);
- g_api_con_trans = 0;
+ if (g_api_con_trans_list != 0)
+ {
+ for (index = g_api_con_trans_list->count - 1; index >= 0; index--)
+ {
+ ltran = (struct trans *) list_get_item(g_api_con_trans_list, index);
+ if (ltran != 0)
+ {
+ list_remove_item(g_api_con_trans_list, index);
+ g_free(ltran->callback_data);
+ trans_delete(ltran);
+ }
+ }
+ list_delete(g_api_con_trans_list);
+ }
LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread stop"));
g_set_wait_obj(g_thread_done_event);
return rv;
@@ -1599,11 +1643,6 @@ remove_struct_with_chan_id(tui32 dvc_chan_id)
{
int i;
- if (dvc_chan_id < 0)
- {
- return -1;
- }
-
for (i = 0; i < MAX_DVC_CHANNELS; i++)
{
if (g_dvc_channels[i]->dvc_chan_id == dvc_chan_id)
diff --git a/sesman/chansrv/chansrv_fuse.c b/sesman/chansrv/chansrv_fuse.c
index 2eb78ea0..c4532ead 100644
--- a/sesman/chansrv/chansrv_fuse.c
+++ b/sesman/chansrv/chansrv_fuse.c
@@ -39,6 +39,8 @@
//#define USE_SYNC_FLAG
+static char g_fuse_mount_name[256] = "xrdp_client";
+
/* FUSE mount point */
char g_fuse_root_path[256] = "";
char g_fuse_clipboard_path[256] = ""; /* for clipboard use */
@@ -71,7 +73,7 @@ int xfuse_create_share(tui32 device_id, char *dirname) { r
void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId, tui32 FileId) {}
void xfuse_devredir_cb_write_file(void *vp, char *buf, size_t length) {}
void xfuse_devredir_cb_read_file(void *vp, char *buf, size_t length) {}
-void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode) {}
+int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode) {}
void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus) {}
void xfuse_devredir_cb_rmdir_or_file(void *vp, tui32 IoStatus) {}
void xfuse_devredir_cb_rename_file(void *vp, tui32 IoStatus) {}
@@ -369,6 +371,37 @@ int clipboard_request_file_data(int stream_id, int lindex, int offset,
static void xfuse_mark_as_stale(int pinode);
static void xfuse_delete_stale_entries(int pinode);
+/*****************************************************************************/
+int APP_CC
+load_fuse_config(void)
+{
+ int index;
+ char cfg_file[256];
+ struct list *items;
+ struct list *values;
+ char *item;
+ char *value;
+
+ items = list_create();
+ items->auto_free = 1;
+ values = list_create();
+ values->auto_free = 1;
+ g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH);
+ file_by_name_read_section(cfg_file, "Chansrv", items, values);
+ for (index = 0; index < items->count; index++)
+ {
+ item = (char *)list_get_item(items, index);
+ value = (char *)list_get_item(values, index);
+ if (g_strcasecmp(item, "FuseMountName") == 0)
+ {
+ g_strncpy(g_fuse_mount_name, value, 255);
+ }
+ }
+ list_delete(items);
+ list_delete(values);
+ return 0;
+}
+
/*****************************************************************************
** **
** public functions - can be called from any code path **
@@ -381,7 +414,8 @@ static void xfuse_delete_stale_entries(int pinode);
* @return 0 on success, -1 on failure
*****************************************************************************/
-int xfuse_init()
+int APP_CC
+xfuse_init(void)
{
struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
@@ -398,8 +432,10 @@ int xfuse_init()
return -1;
}
- /* define FUSE mount point to ~/xrdp_client */
- g_snprintf(g_fuse_root_path, 255, "%s/xrdp_client", g_getenv("HOME"));
+ load_fuse_config();
+
+ /* define FUSE mount point to ~/xrdp_client, ~/thinclient_drives */
+ g_snprintf(g_fuse_root_path, 255, "%s/%s", g_getenv("HOME"), g_fuse_mount_name);
g_snprintf(g_fuse_clipboard_path, 255, "%s/.clipboard", g_fuse_root_path);
/* if FUSE mount point does not exist, create it */
@@ -460,7 +496,8 @@ int xfuse_init()
* @return 0 on success, -1 on failure
*****************************************************************************/
-int xfuse_deinit()
+int APP_CC
+xfuse_deinit(void)
{
xfuse_deinit_xrdp_fs();
fifo_deinit(&g_fifo_opendir);
@@ -1385,7 +1422,7 @@ static void xfuse_update_xrdpfs_size()
* Add a file or directory to xrdp file system
*****************************************************************************/
-void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
+int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
{
XFUSE_INFO *fip = (XFUSE_INFO *) vp;
XRDP_INODE *xip = NULL;
@@ -1393,13 +1430,14 @@ void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
if ((fip == NULL) || (xinode == NULL))
{
log_error("fip or xinode are NULL");
- return;
+ return -1;
}
if (!xfuse_is_inode_valid(fip->inode))
{
log_error("inode %d is not valid", fip->inode);
- return;
+ g_free(xinode);
+ return -1;
}
log_debug("parent_inode=%d name=%s", fip->inode, xinode->name);
@@ -1407,8 +1445,8 @@ void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
/* if filename is . or .. don't add it */
if ((strcmp(xinode->name, ".") == 0) || (strcmp(xinode->name, "..") == 0))
{
- free(xinode);
- return;
+ g_free(xinode);
+ return -1;
}
xfuse_dump_fs();
@@ -1417,9 +1455,9 @@ void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
{
log_debug("inode=%d name=%s already exists in xrdp_fs; not adding it",
fip->inode, xinode->name);
- free(xinode);
+ g_free(xinode);
xip->stale = 0;
- return;
+ return -1;
}
xinode->parent_inode = fip->inode;
@@ -1436,6 +1474,7 @@ void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode)
xfuse_update_xrdpfs_size();
xfuse_dump_fs();
+ return 0;
}
/**
@@ -1742,12 +1781,15 @@ void xfuse_devredir_cb_rename_file(void *vp, tui32 IoStatus)
new_xinode = xfuse_get_inode_from_pinode_name(fip->new_inode,
fip->new_name);
- if (new_xinode->mode & S_IFREG)
- xfuse_delete_file_with_xinode(new_xinode);
- else
- xfuse_delete_dir_with_xinode(new_xinode);
+ if (new_xinode)
+ {
+ if (new_xinode->mode & S_IFREG)
+ xfuse_delete_file_with_xinode(new_xinode);
+ else
+ xfuse_delete_dir_with_xinode(new_xinode);
- new_xinode = NULL;
+ new_xinode = NULL;
+ }
}
old_xinode = xfuse_get_inode_from_pinode_name(fip->inode, fip->name);
@@ -1759,7 +1801,8 @@ void xfuse_devredir_cb_rename_file(void *vp, tui32 IoStatus)
}
old_xinode->parent_inode = fip->new_inode;
- strcpy(old_xinode->name, fip->new_name);
+ strncpy(old_xinode->name, fip->new_name, 1023);
+ old_xinode->name[1023] = 0;
if (fip->inode != fip->new_inode)
{
@@ -1987,7 +2030,7 @@ static void xfuse_cb_readdir(fuse_req_t req, fuse_ino_t ino, size_t size,
return;
}
- di = (struct dir_info *) fi->fh;
+ di = (struct dir_info *) (tintptr) (fi->fh);
if (di == NULL)
{
/* something seriously wrong somewhere! */
@@ -2142,7 +2185,7 @@ static void xfuse_remove_dir_or_file(fuse_req_t req, fuse_ino_t parent,
}
strcat(full_path, "/");
- strcat(full_path, name);
+ strncat(full_path, name, sizeof(full_path) - strlen(full_path));
if (xinode->is_loc_resource)
{
@@ -2583,7 +2626,6 @@ static void xfuse_cb_release(fuse_req_t req, fuse_ino_t ino, struct
fip, fip->fi, fip->fi->fh);
FileId = handle->FileId;
- free(handle);
fip->fi->fh = 0;
xinode->close_in_progress = 1;
@@ -2592,6 +2634,8 @@ static void xfuse_cb_release(fuse_req_t req, fuse_ino_t ino, struct
log_error("failed to send devredir_close_file() cmd");
fuse_reply_err(req, EREMOTEIO);
}
+
+ free(handle);
}
/**
diff --git a/sesman/chansrv/chansrv_fuse.h b/sesman/chansrv/chansrv_fuse.h
index 09011452..4638add5 100644
--- a/sesman/chansrv/chansrv_fuse.h
+++ b/sesman/chansrv/chansrv_fuse.h
@@ -34,7 +34,7 @@ struct xrdp_inode
time_t atime; /* Time of last access. */
time_t mtime; /* Time of last modification. */
time_t ctime; /* Time of last status change. */
- char name[256]; /* Dir or filename */
+ char name[1024]; /* Dir or filename */
tui32 device_id; /* for file system redirection */
char is_synced; /* dir struct has been read from */
/* remote device, done just once */
@@ -57,7 +57,7 @@ int xfuse_file_contents_size(int stream_id, int file_size);
int xfuse_add_clip_dir_item(char *filename, int flags, int size, int lindex);
/* functions that are invoked from devredir */
-void xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode);
+int xfuse_devredir_cb_enum_dir(void *vp, struct xrdp_inode *xinode);
void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus);
void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId, tui32 FileId);
void xfuse_devredir_cb_read_file(void *vp, char *buf, size_t length);
diff --git a/sesman/chansrv/clipboard.c b/sesman/chansrv/clipboard.c
index 6d52da85..310e2093 100644
--- a/sesman/chansrv/clipboard.c
+++ b/sesman/chansrv/clipboard.c
@@ -1048,8 +1048,11 @@ clipboard_process_format_announce(struct stream *s, int clip_msg_status,
log_debug("clipboard_process_format_announce: formatId 0x%8.8x "
"wszFormatName [%s] clip_msg_len %d", formatId, desc,
clip_msg_len);
- g_formatIds[g_num_formatIds] = formatId;
- g_num_formatIds++;
+ if (g_num_formatIds <= 15)
+ {
+ g_formatIds[g_num_formatIds] = formatId;
+ g_num_formatIds++;
+ }
if (g_num_formatIds > 15)
{
log_debug("clipboard_process_format_announce: max formats");
diff --git a/sesman/chansrv/clipboard_file.c b/sesman/chansrv/clipboard_file.c
index 96f1b0e8..ff95b0a0 100644
--- a/sesman/chansrv/clipboard_file.c
+++ b/sesman/chansrv/clipboard_file.c
@@ -446,7 +446,13 @@ clipboard_send_file_data(int streamId, int lindex,
full_fn);
return 1;
}
- g_file_seek(fd, nPositionLow);
+ if (g_file_seek(fd, nPositionLow) < 0)
+ {
+ log_message(LOG_LEVEL_ERROR, "clipboard_send_file_data: seek error "
+ "in file: %s\n", full_fn);
+ g_file_close(fd);
+ return 1;
+ }
make_stream(s);
init_stream(s, cbRequested + 64);
size = g_file_read(fd, s->data + 12, cbRequested);
diff --git a/sesman/chansrv/devredir.c b/sesman/chansrv/devredir.c
index cdcc9e94..cea42c81 100644
--- a/sesman/chansrv/devredir.c
+++ b/sesman/chansrv/devredir.c
@@ -118,7 +118,7 @@ dev_redir_init(void)
} u;
/* get a random number that will act as a unique clientID */
- if ((fd = open("/dev/urandom", O_RDONLY)))
+ if ((fd = open("/dev/urandom", O_RDONLY)) != -1)
{
if (read(fd, u.buf, 4) != 4)
{
@@ -790,10 +790,14 @@ dev_redir_proc_device_iocompletion(struct stream *s)
fuse_data = devredir_fuse_data_dequeue(irp);
if (fuse_data == NULL)
+ {
log_error("fuse_data is NULL");
-
- xfuse_devredir_cb_read_file(fuse_data->data_ptr, s->p, Length);
- devredir_irp_delete(irp);
+ }
+ else
+ {
+ xfuse_devredir_cb_read_file(fuse_data->data_ptr, s->p, Length);
+ devredir_irp_delete(irp);
+ }
break;
case CID_WRITE:
@@ -802,10 +806,14 @@ dev_redir_proc_device_iocompletion(struct stream *s)
fuse_data = devredir_fuse_data_dequeue(irp);
if (fuse_data == NULL)
+ {
log_error("fuse_data is NULL");
-
- xfuse_devredir_cb_write_file(fuse_data->data_ptr, s->p, Length);
- devredir_irp_delete(irp);
+ }
+ else
+ {
+ xfuse_devredir_cb_write_file(fuse_data->data_ptr, s->p, Length);
+ devredir_irp_delete(irp);
+ }
break;
case CID_CLOSE:
@@ -879,7 +887,7 @@ dev_redir_proc_query_dir_response(IRP *irp,
tui32 IoStatus)
{
FUSE_DATA *fuse_data = NULL;
- XRDP_INODE *xinode = NULL;
+ XRDP_INODE *xinode;
tui32 Length;
tui32 NextEntryOffset;
@@ -1017,7 +1025,8 @@ dev_redir_get_dir_listing(void *fusep, tui32 device_id, char *path)
irp->CompletionId = g_completion_id++;
irp->completion_type = CID_CREATE_DIR_REQ;
irp->DeviceId = device_id;
- strcpy(irp->pathname, path);
+
+ strncpy(irp->pathname, path, 255);
devredir_fuse_data_enqueue(irp, fusep);
DesiredAccess = DA_FILE_READ_DATA | DA_SYNCHRONIZE;
@@ -1060,7 +1069,7 @@ dev_redir_file_open(void *fusep, tui32 device_id, char *path,
if (type & OP_RENAME_FILE)
{
irp->completion_type = CID_RENAME_FILE;
- strcpy(irp->gen_buf, gen_buf);
+ strncpy(irp->gen_buf, gen_buf, 1023);
}
else
{
@@ -1069,7 +1078,8 @@ dev_redir_file_open(void *fusep, tui32 device_id, char *path,
irp->CompletionId = g_completion_id++;
irp->DeviceId = device_id;
- strcpy(irp->pathname, path);
+
+ strncpy(irp->pathname, path, 255);
devredir_fuse_data_enqueue(irp, fusep);
if (mode & O_CREAT)
@@ -1174,7 +1184,8 @@ devredir_rmdir_or_file(void *fusep, tui32 device_id, char *path, int mode)
irp->CompletionId = g_completion_id++;
irp->completion_type = CID_RMDIR_OR_FILE;
irp->DeviceId = device_id;
- strcpy(irp->pathname, path);
+
+ strncpy(irp->pathname, path, 255);
devredir_fuse_data_enqueue(irp, fusep);
//DesiredAccess = DA_DELETE | DA_FILE_READ_ATTRIBUTES | DA_SYNCHRONIZE;
@@ -1216,6 +1227,7 @@ devredir_file_read(void *fusep, tui32 DeviceId, tui32 FileId,
{
log_error("no IRP found with FileId = %d", FileId);
xfuse_devredir_cb_read_file(fusep, NULL, 0);
+ xstream_free(s);
return -1;
}
@@ -1224,6 +1236,7 @@ devredir_file_read(void *fusep, tui32 DeviceId, tui32 FileId,
{
/* system out of memory */
xfuse_devredir_cb_read_file(fusep, NULL, 0);
+ xstream_free(s);
return -1;
}
new_irp->FileId = 0;
@@ -1268,6 +1281,7 @@ dev_redir_file_write(void *fusep, tui32 DeviceId, tui32 FileId,
{
log_error("no IRP found with FileId = %d", FileId);
xfuse_devredir_cb_write_file(fusep, NULL, 0);
+ xstream_free(s);
return -1;
}
@@ -1276,6 +1290,7 @@ dev_redir_file_write(void *fusep, tui32 DeviceId, tui32 FileId,
{
/* system out of memory */
xfuse_devredir_cb_write_file(fusep, NULL, 0);
+ xstream_free(s);
return -1;
}
new_irp->FileId = 0;
diff --git a/sesman/chansrv/pcsc/xrdp_pcsc.c b/sesman/chansrv/pcsc/xrdp_pcsc.c
index f4aaba14..3b830d60 100644
--- a/sesman/chansrv/pcsc/xrdp_pcsc.c
+++ b/sesman/chansrv/pcsc/xrdp_pcsc.c
@@ -15,8 +15,13 @@
typedef unsigned char BYTE;
typedef BYTE *LPBYTE;
-typedef unsigned int LONG;
+#ifdef __APPLE__
+typedef int LONG;
typedef unsigned int DWORD;
+#else
+typedef long LONG;
+typedef unsigned long DWORD;
+#endif
typedef DWORD *LPDWORD;
typedef const void *LPCVOID;
typedef const char *LPCSTR;
@@ -59,6 +64,8 @@ PCSC_API SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 };
#define LLOG_LEVEL 5
#define LLOGLN(_level, _args) \
do { if (_level < LLOG_LEVEL) { printf _args ; printf("\n"); } } while (0)
+#define LHEXDUMP(_level, _args) \
+ do { if (_level < LLOG_LEVEL) { lhexdump _args ; } } while (0)
#define SCARD_ESTABLISH_CONTEXT 0x01
#define SCARD_RELEASE_CONTEXT 0x02
@@ -103,6 +110,50 @@ static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
static char g_error_str[512];
/*****************************************************************************/
+/* produce a hex dump */
+static void
+lhexdump(void *p, int len)
+{
+ unsigned char *line;
+ int i;
+ int thisline;
+ int offset;
+
+ line = (unsigned char *)p;
+ offset = 0;
+
+ while (offset < len)
+ {
+ printf("%04x ", offset);
+ thisline = len - offset;
+
+ if (thisline > 16)
+ {
+ thisline = 16;
+ }
+
+ for (i = 0; i < thisline; i++)
+ {
+ printf("%02x ", line[i]);
+ }
+
+ for (; i < 16; i++)
+ {
+ printf(" ");
+ }
+
+ for (i = 0; i < thisline; i++)
+ {
+ printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
+ }
+
+ printf("\n");
+ offset += thisline;
+ line += thisline;
+ }
+}
+
+/*****************************************************************************/
static int
get_display_num_from_display(const char *display_text)
{
@@ -156,7 +207,7 @@ get_display_num_from_display(const char *display_text)
host[host_index] = 0;
disp[disp_index] = 0;
scre[scre_index] = 0;
- LLOGLN(0, ("get_display_num_from_display: host [%s] disp [%s] scre [%s]",
+ LLOGLN(10, ("get_display_num_from_display: host [%s] disp [%s] scre [%s]",
host, disp, scre));
rv = atoi(disp);
return rv;
@@ -219,7 +270,7 @@ connect_to_chansrv(void)
bytes = sizeof(saddr.sun_path);
snprintf(saddr.sun_path, bytes, "%s/.pcsc%d/pcscd.comm", home_str, dis);
saddr.sun_path[bytes - 1] = 0;
- LLOGLN(0, ("connect_to_chansrv: connecting to %s", saddr.sun_path));
+ LLOGLN(10, ("connect_to_chansrv: connecting to %s", saddr.sun_path));
psaddr = (struct sockaddr *) &saddr;
bytes = sizeof(struct sockaddr_un);
error = connect(g_sck, psaddr, bytes);
@@ -256,6 +307,8 @@ send_message(int code, char *data, int bytes)
pthread_mutex_unlock(&g_mutex);
return 1;
}
+ LLOGLN(10, ("send_message:"));
+ LHEXDUMP(10, (data, bytes));
pthread_mutex_unlock(&g_mutex);
return 0;
}
@@ -392,7 +445,7 @@ SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2,
}
context = GET_UINT32(msg, 0);
status = GET_UINT32(msg, 4);
- LLOGLN(10, ("SCardEstablishContext: got context 0x%8.8x", context));
+ LLOGLN(10, ("SCardEstablishContext: got context 0x%8.8x", (int)context));
*phContext = context;
return status;
}
@@ -463,7 +516,7 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
LLOGLN(10, ("SCardConnect:"));
LLOGLN(10, ("SCardConnect: hContext 0x%8.8x szReader %s dwShareMode %d "
"dwPreferredProtocols %d",
- hContext, szReader, dwShareMode, dwPreferredProtocols));
+ (int)hContext, szReader, (int)dwShareMode, (int)dwPreferredProtocols));
if (g_sck == -1)
{
LLOGLN(0, ("SCardConnect: error, not connected"));
@@ -507,7 +560,7 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
status = GET_UINT32(msg, 8);
LLOGLN(10, ("SCardConnect: got status 0x%8.8x hCard 0x%8.8x "
"dwActiveProtocol %d",
- status, *phCard, *pdwActiveProtocol));
+ status, (int)*phCard, (int)*pdwActiveProtocol));
return status;
}
@@ -536,7 +589,7 @@ SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
int status;
LLOGLN(10, ("SCardDisconnect: hCard 0x%8.8x dwDisposition %d",
- hCard, dwDisposition));
+ (int)hCard, (int)dwDisposition));
if (g_sck == -1)
{
LLOGLN(0, ("SCardDisconnect: error, not connected"));
@@ -575,7 +628,7 @@ SCardBeginTransaction(SCARDHANDLE hCard)
int bytes;
int status;
- LLOGLN(10, ("SCardBeginTransaction: hCard 0x%8.8x", hCard));
+ LLOGLN(10, ("SCardBeginTransaction: hCard 0x%8.8x", (int)hCard));
if (hCard == 0)
{
LLOGLN(0, ("SCardBeginTransaction: error, bad hCard"));
@@ -665,7 +718,7 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen,
LLOGLN(10, ("SCardStatus:"));
if (hCard == 0)
{
- LLOGLN(0, ("SCardStatus: error, bad hCard"));
+ LLOGLN(10, ("SCardStatus: error, bad hCard"));
return SCARD_F_INTERNAL_ERROR;
}
if (g_sck == -1)
@@ -673,9 +726,9 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen,
LLOGLN(0, ("SCardStatus: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
- LLOGLN(10, (" hCard 0x%8.8x", hCard));
- LLOGLN(10, (" cchReaderLen %d", *pcchReaderLen));
- LLOGLN(10, (" cbAtrLen %d", *pcbAtrLen));
+ LLOGLN(10, (" hCard 0x%8.8x", (int)hCard));
+ LLOGLN(10, (" cchReaderLen %d", (int)*pcchReaderLen));
+ LLOGLN(10, (" cbAtrLen %d", (int)*pcbAtrLen));
cchReaderLen = *pcchReaderLen;
msg = (char *) malloc(8192);
@@ -703,10 +756,10 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen,
return SCARD_F_INTERNAL_ERROR;
}
- LLOGLN(10, ("SCardStatus: cchReaderLen in %d", *pcchReaderLen));
+ LLOGLN(10, ("SCardStatus: cchReaderLen in %d", (int)*pcchReaderLen));
offset = 0;
*pcchReaderLen = GET_UINT32(msg, offset);
- LLOGLN(10, ("SCardStatus: cchReaderLen out %d", *pcchReaderLen));
+ LLOGLN(10, ("SCardStatus: cchReaderLen out %d", (int)*pcchReaderLen));
offset += 4;
if (cchReaderLen > 0)
{
@@ -721,14 +774,18 @@ SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderName, LPDWORD pcchReaderLen,
LLOGLN(10, ("SCardStatus: mszReaderName out %s", mszReaderName));
offset += *pcchReaderLen;
*pdwState = GET_UINT32(msg, offset);
- LLOGLN(10, ("SCardStatus: dwState %d", *pdwState));
+ if (*pdwState == 1)
+ {
+ *pdwState = 0x34;
+ }
+ LLOGLN(10, ("SCardStatus: dwState %d", (int)*pdwState));
offset += 4;
*pdwProtocol = GET_UINT32(msg, offset);
- LLOGLN(10, ("SCardStatus: dwProtocol %d", *pdwProtocol));
+ LLOGLN(10, ("SCardStatus: dwProtocol %d", (int)*pdwProtocol));
offset += 4;
*pcbAtrLen = GET_UINT32(msg, offset);
offset += 4;
- LLOGLN(10, ("SCardStatus: cbAtrLen %d", *pcbAtrLen));
+ LLOGLN(10, ("SCardStatus: cbAtrLen %d", (int)*pcbAtrLen));
memcpy(pbAtr, msg + offset, *pcbAtrLen);
offset += *pcbAtrLen;
status = GET_UINT32(msg, offset);
@@ -757,7 +814,7 @@ SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
char atr[36];
LLOGLN(10, ("SCardGetStatusChange:"));
- LLOGLN(10, (" dwTimeout %d cReaders %d", dwTimeout, cReaders));
+ LLOGLN(10, (" dwTimeout %d cReaders %d", (int)dwTimeout, (int)cReaders));
if (g_sck == -1)
{
LLOGLN(0, ("SCardGetStatusChange: error, not connected"));
@@ -829,7 +886,7 @@ SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
}
cReaders = GET_UINT32(msg, 0);
offset = 4;
- LLOGLN(10, ("SCardGetStatusChange: got back cReaders %d", cReaders));
+ LLOGLN(10, ("SCardGetStatusChange: got back cReaders %d", (int)cReaders));
for (index = 0; index < cReaders; index++)
{
rname = rgReaderStates[index].szReader;
@@ -897,10 +954,10 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
LLOGLN(0, ("SCardControl: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
- LLOGLN(10, (" hCard 0x%8.8x", hCard));
- LLOGLN(10, (" dwControlCode 0x%8.8x", dwControlCode));
- LLOGLN(10, (" cbSendLength %d", cbSendLength));
- LLOGLN(10, (" cbRecvLength %d", cbRecvLength));
+ LLOGLN(10, (" hCard 0x%8.8x", (int)hCard));
+ LLOGLN(10, (" dwControlCode 0x%8.8x", (int)dwControlCode));
+ LLOGLN(10, (" cbSendLength %d", (int)cbSendLength));
+ LLOGLN(10, (" cbRecvLength %d", (int)cbRecvLength));
/* #define SCARD_CTL_CODE(code) (0x42000000 + (code))
control_code = (control_code & 0x3ffc) >> 2;
@@ -910,7 +967,7 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
dwControlCode = dwControlCode - 0x42000000;
dwControlCode = dwControlCode << 2;
dwControlCode = dwControlCode | (49 << 16);
- LLOGLN(10, (" MS dwControlCode 0x%8.8x", dwControlCode));
+ LLOGLN(10, (" MS dwControlCode 0x%8.8d", (int)dwControlCode));
msg = (char *) malloc(8192);
offset = 0;
@@ -946,7 +1003,7 @@ SCardControl(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
}
offset = 0;
*lpBytesReturned = GET_UINT32(msg, offset);
- LLOGLN(10, (" cbRecvLength %d", *lpBytesReturned));
+ LLOGLN(10, (" cbRecvLength %d", (int)*lpBytesReturned));
offset += 4;
memcpy(pbRecvBuffer, msg + offset, *lpBytesReturned);
offset += *lpBytesReturned;
@@ -976,9 +1033,10 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
LLOGLN(0, ("SCardTransmit: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
- LLOGLN(10, (" hCard 0x%8.8x", hCard));
- LLOGLN(10, (" cbSendLength %d", cbSendLength));
- LLOGLN(10, (" cbRecvLength %d", *pcbRecvLength));
+
+ LLOGLN(10, (" hCard 0x%8.8x", (int)hCard));
+ LLOGLN(10, (" cbSendLength %d", (int)cbSendLength));
+ LLOGLN(10, (" cbRecvLength %d", (int)*pcbRecvLength));
LLOGLN(10, (" pioSendPci->dwProtocol %d", (int)(pioSendPci->dwProtocol)));
LLOGLN(10, (" pioSendPci->cbPciLength %d", (int)(pioSendPci->cbPciLength)));
LLOGLN(10, (" pioRecvPci %p", pioRecvPci));
@@ -993,9 +1051,11 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
offset += 4;
SET_UINT32(msg, offset, pioSendPci->dwProtocol);
offset += 4;
- SET_UINT32(msg, offset, pioSendPci->cbPciLength);
+/* SET_UINT32(msg, offset, pioSendPci->cbPciLength); */
+ SET_UINT32(msg, offset, 8);
offset += 4;
- extra_len = pioSendPci->cbPciLength - 8;
+/* extra_len = pioSendPci->cbPciLength - 8; */
+ extra_len = 0;
SET_UINT32(msg, offset, extra_len);
offset += 4;
memcpy(msg + offset, pioSendPci + 1, extra_len);
@@ -1070,8 +1130,9 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
}
*pcbRecvLength = GET_UINT32(msg, offset);
offset += 4;
- LLOGLN(10, (" cbRecvLength %d", *pcbRecvLength));
+ LLOGLN(10, (" cbRecvLength %d", (int)*pcbRecvLength));
memcpy(pbRecvBuffer, msg + offset, *pcbRecvLength);
+ LHEXDUMP(10, (pbRecvBuffer, *pcbRecvLength));
offset += *pcbRecvLength;
status = GET_UINT32(msg, offset);
free(msg);
@@ -1113,12 +1174,16 @@ SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders,
LLOGLN(10, ("SCardListReaders:"));
LLOGLN(10, ("SCardListReaders: mszGroups %s", mszGroups));
- LLOGLN(10, ("SCardListReaders: *pcchReaders %d", *pcchReaders));
+ LLOGLN(10, ("SCardListReaders: *pcchReaders %d", (int)*pcchReaders));
if (g_sck == -1)
{
LLOGLN(0, ("SCardListReaders: error, not connected"));
return SCARD_F_INTERNAL_ERROR;
}
+ if ((mszGroups == NULL) && (mszReaders == NULL))
+ {
+ *pcchReaders = 0;
+ }
msg = (char *) malloc(8192);
offset = 0;
SET_UINT32(msg, offset, hContext);
diff --git a/sesman/chansrv/pulse/module-xrdp-sink.c b/sesman/chansrv/pulse/module-xrdp-sink.c
index d56a4883..8606f412 100644
--- a/sesman/chansrv/pulse/module-xrdp-sink.c
+++ b/sesman/chansrv/pulse/module-xrdp-sink.c
@@ -58,6 +58,15 @@
#include <pulsecore/thread-mq.h>
#include <pulsecore/rtpoll.h>
+/* defined in pulse/version.h */
+#if PA_PROTOCOL_VERSION > 28
+/* these used to be defined in pulsecore/macro.h */
+typedef bool pa_bool_t;
+#define FALSE ((pa_bool_t) 0)
+#define TRUE (!FALSE)
+#else
+#endif
+
#include "module-xrdp-sink-symdef.h"
PA_MODULE_AUTHOR("Jay Sorg");
@@ -268,6 +277,19 @@ static int get_display_num_from_display(char *display_text) {
return display_num;
}
+static int lsend(int fd, char *data, int bytes) {
+ int sent = 0;
+ int error;
+ while (sent < bytes) {
+ error = send(fd, data + sent, bytes - sent, 0);
+ if (error < 1) {
+ return error;
+ }
+ sent += error;
+ }
+ return sent;
+}
+
static int data_send(struct userdata *u, pa_memchunk *chunk) {
char *data;
int bytes;
@@ -316,7 +338,7 @@ static int data_send(struct userdata *u, pa_memchunk *chunk) {
h.code = 0;
h.bytes = bytes + 8;
- if (send(u->fd, &h, 8, 0) != 8) {
+ if (lsend(u->fd, (char*)(&h), 8) != 8) {
pa_log("data_send: send failed");
close(u->fd);
u->fd = 0;
@@ -327,7 +349,7 @@ static int data_send(struct userdata *u, pa_memchunk *chunk) {
data = (char*)pa_memblock_acquire(chunk->memblock);
data += chunk->index;
- sent = send(u->fd, data, bytes, 0);
+ sent = lsend(u->fd, data, bytes);
pa_memblock_release(chunk->memblock);
if (sent != bytes) {
@@ -349,7 +371,7 @@ static int close_send(struct userdata *u) {
}
h.code = 1;
h.bytes = 8;
- if (send(u->fd, &h, 8, 0) != 8) {
+ if (lsend(u->fd, (char*)(&h), 8) != 8) {
pa_log("close_send: send failed");
close(u->fd);
u->fd = 0;
diff --git a/sesman/chansrv/pulse/module-xrdp-source.c b/sesman/chansrv/pulse/module-xrdp-source.c
index 2d7ec4fa..1c03b069 100644
--- a/sesman/chansrv/pulse/module-xrdp-source.c
+++ b/sesman/chansrv/pulse/module-xrdp-source.c
@@ -45,6 +45,15 @@
#include <pulsecore/thread-mq.h>
#include <pulsecore/thread.h>
+/* defined in pulse/version.h */
+#if PA_PROTOCOL_VERSION > 28
+/* these used to be defined in pulsecore/macro.h */
+typedef bool pa_bool_t;
+#define FALSE ((pa_bool_t) 0)
+#define TRUE (!FALSE)
+#else
+#endif
+
#include "module-xrdp-source-symdef.h"
PA_MODULE_AUTHOR("Laxmikant Rashinkar");
@@ -329,8 +338,7 @@ int pa__init(pa_module *m) {
pa_source_new_data_set_name(&data, pa_modargs_get_value(ma, "source_name", DEFAULT_SOURCE_NAME));
pa_source_new_data_set_sample_spec(&data, &ss);
pa_source_new_data_set_channel_map(&data, &map);
- //pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, pa_modargs_get_value(ma, "description", "Null Input"));
- pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, pa_modargs_get_value(ma, "description", "xrdp Input"));
+ pa_proplist_sets(data.proplist, PA_PROP_DEVICE_DESCRIPTION, pa_modargs_get_value(ma, "description", "xrdp source"));
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_CLASS, "abstract");
u->source = pa_source_new(m->core, &data, PA_SOURCE_LATENCY | PA_SOURCE_DYNAMIC_LATENCY);
@@ -361,7 +369,15 @@ int pa__init(pa_module *m) {
u->source->thread_info.max_rewind =
pa_usec_to_bytes(u->block_usec, &u->source->sample_spec);
- if (!(u->thread = pa_thread_new("null-source", thread_func, u))) {
+ #if defined(PA_CHECK_VERSION)
+ #if PA_CHECK_VERSION(0, 9, 22)
+ if (!(u->thread = pa_thread_new("xrdp-source", thread_func, u))) {
+ #else
+ if (!(u->thread = pa_thread_new(thread_func, u))) {
+ #endif
+ #else
+ if (!(u->thread = pa_thread_new(thread_func, u)))
+ #endif
pa_log("Failed to create thread.");
goto fail;
}
diff --git a/sesman/chansrv/rail.c b/sesman/chansrv/rail.c
index 4bfeef7e..f3777970 100644
--- a/sesman/chansrv/rail.c
+++ b/sesman/chansrv/rail.c
@@ -71,6 +71,8 @@ static int g_xrr_event_base = 0; /* non zero means we got extension */
static Cursor g_default_cursor = 0;
+static char *g_override_window_title = 0;
+
/* used in valid field of struct rail_window_data */
#define RWD_X (1 << 0)
#define RWD_Y (1 << 1)
@@ -621,6 +623,18 @@ rail_process_activate(struct stream *s, int size)
}
/*****************************************************************************/
+static int
+rail_select_input(Window window_id)
+{
+ XSelectInput(g_display, window_id,
+ PropertyChangeMask | StructureNotifyMask |
+ SubstructureNotifyMask | FocusChangeMask |
+ EnterWindowMask | LeaveWindowMask);
+ XSync(g_display, 0);
+ return 0;
+}
+
+/*****************************************************************************/
static int APP_CC
rail_restore_windows(void)
{
@@ -637,6 +651,7 @@ rail_restore_windows(void)
XGetWindowAttributes(g_display, children[i], &window_attributes);
if (!window_attributes.override_redirect)
{
+ rail_select_input(children[i]);
if (window_attributes.map_state == IsViewable)
{
rail_win_set_state(children[i], 0x0); /* WithdrawnState */
@@ -724,7 +739,7 @@ rail_win_get_state(Window win)
(unsigned char **)&data,
&nitems);
- if (data || nitems > 0)
+ if (data && nitems > 0)
{
rv = *(unsigned long *)data;
XFree(data);
@@ -760,31 +775,40 @@ rail_win_set_state(Window win, unsigned long state)
}
/*****************************************************************************/
+/* *data pointer that needs g_free */
static int APP_CC
rail_win_get_text(Window win, char **data)
{
int ret = 0;
int i = 0;
unsigned long nitems = 0;
+ unsigned char *ldata = 0;
+ char *lldata = 0;
+ if (g_override_window_title != 0)
+ {
+ *data = g_strdup(g_override_window_title);
+ return g_strlen(*data);
+ }
ret = rail_get_property(g_display, win, g_utf8_string, g_net_wm_name,
- (unsigned char **)data, &nitems);
+ &ldata, &nitems);
if (ret != 0)
{
/* _NET_WM_NAME isn't set, use WM_NAME (XFetchName) instead */
- XFetchName(g_display, win, data);
+ XFetchName(g_display, win, &lldata);
+ *data = g_strdup(lldata);
+ i = g_strlen(*data);
+ XFree(lldata);
+ return i;
}
- if (data)
+ *data = 0;
+ if (ldata)
{
- char *ptr = *data;
- for (; ptr != NULL; i++)
- {
- if (ptr[i] == '\0')
- {
- break;
- }
- }
+ *data = g_strdup((char *)ldata);
+ i = g_strlen(*data);
+ XFree(ldata);
+ return i;
}
return i;
@@ -1207,6 +1231,7 @@ rail_win_send_text(Window win)
int crc;
struct rail_window_data* rwd;
+ LOG(10, ("chansrv::rail_win_send_text:"));
len = rail_win_get_text(win, &data);
rwd = rail_get_window_data_safe(win);
if (rwd != 0)
@@ -1219,7 +1244,7 @@ rail_win_send_text(Window win)
if (rwd->title_crc == crc)
{
LOG(10, ("chansrv::rail_win_send_text: skipping, title not changed"));
- XFree(data);
+ g_free(data);
XFree(rwd);
return 0;
}
@@ -1229,13 +1254,15 @@ rail_win_send_text(Window win)
else
{
LOG(0, ("chansrv::rail_win_send_text: error rail_get_window_data_safe failed"));
+ g_free(data);
return 1;
}
- if (data && len > 0) {
+ if (data && len > 0)
+ {
LOG(10, ("chansrv::rail_win_send_text: 0x%8.8x text %s length %d",
win, data, len));
make_stream(s);
- init_stream(s, 1024);
+ init_stream(s, len + 1024);
flags = WINDOW_ORDER_TYPE_WINDOW | WINDOW_ORDER_FIELD_TITLE;
out_uint32_le(s, 8); /* update title info */
out_uint32_le(s, win); /* window id */
@@ -1251,10 +1278,7 @@ rail_win_send_text(Window win)
rwd->title_crc = crc;
rail_set_window_data(win, rwd);
}
- if (data != 0)
- {
- XFree(data);
- }
+ g_free(data);
XFree(rwd);
return 0;
}
@@ -1355,7 +1379,8 @@ rail_create_window(Window window_id, Window owner_id)
flags = WINDOW_ORDER_TYPE_WINDOW;
}
- title_size = rail_win_get_text(window_id, &title_bytes);
+ title_size = 0;
+ title_bytes = 0;
XGetTransientForHint(g_display, window_id, &transient_for);
@@ -1363,21 +1388,24 @@ rail_create_window(Window window_id, Window owner_id)
{
style = RAIL_STYLE_TOOLTIP;
ext_style = RAIL_EXT_STYLE_TOOLTIP;
+ /* for tooltips, we don't grab the window text */
}
else if (transient_for > 0)
{
style = RAIL_STYLE_DIALOG;
ext_style = RAIL_EXT_STYLE_DIALOG;
owner_id = transient_for;
+ title_size = rail_win_get_text(window_id, &title_bytes);
}
else
{
style = RAIL_STYLE_NORMAL;
ext_style = RAIL_EXT_STYLE_NORMAL;
+ title_size = rail_win_get_text(window_id, &title_bytes);
}
make_stream(s);
- init_stream(s, 1024);
+ init_stream(s, title_size + 1024 + num_window_rects * 8 + num_visibility_rects * 8);
out_uint32_le(s, 2); /* create_window */
out_uint32_le(s, window_id); /* window_id */
@@ -1387,6 +1415,7 @@ rail_create_window(Window window_id, Window owner_id)
out_uint32_le(s, ext_style); /* extended_style */
flags |= WINDOW_ORDER_FIELD_STYLE;
out_uint32_le(s, 0x05); /* show_state */
+ LOG(10, (" title %s", title_bytes));
flags |= WINDOW_ORDER_FIELD_SHOW;
if (title_size > 0)
{
@@ -1449,7 +1478,7 @@ rail_create_window(Window window_id, Window owner_id)
s_mark_end(s);
send_rail_drawing_orders(s->data, (int)(s->end - s->data));
free_stream(s);
- XFree(title_bytes);
+ g_free(title_bytes);
rail_set_window_data(window_id, rwd);
XFree(rwd);
return 0;
@@ -1608,7 +1637,7 @@ rail_configure_request_window(XConfigureRequestEvent* config)
flags = WINDOW_ORDER_TYPE_WINDOW;
make_stream(s);
- init_stream(s, 1024);
+ init_stream(s, 1024 + num_window_rects * 8 + num_visibility_rects * 8);
out_uint32_le(s, 10); /* configure_window */
out_uint32_le(s, window_id); /* window_id */
@@ -1692,7 +1721,7 @@ rail_configure_window(XConfigureEvent *config)
flags = WINDOW_ORDER_TYPE_WINDOW;
make_stream(s);
- init_stream(s, 1024);
+ init_stream(s, 1024 + num_window_rects * 8 + num_visibility_rects * 8);
out_uint32_le(s, 10); /* configure_window */
out_uint32_le(s, window_id); /* window_id */
@@ -1822,10 +1851,7 @@ rail_xevent(void *xevent)
case CreateNotify:
LOG(10, (" got CreateNotify window 0x%8.8x parent 0x%8.8x",
lxevent->xcreatewindow.window, lxevent->xcreatewindow.parent));
- XSelectInput(g_display, lxevent->xcreatewindow.window,
- PropertyChangeMask | StructureNotifyMask |
- SubstructureNotifyMask | FocusChangeMask |
- EnterWindowMask | LeaveWindowMask);
+ rail_select_input(lxevent->xcreatewindow.window);
break;
case DestroyNotify:
@@ -1865,7 +1891,7 @@ rail_xevent(void *xevent)
XGetWindowAttributes(g_display, lxevent->xmap.window, &wnd_attributes);
if (wnd_attributes.map_state == IsViewable)
{
- rail_create_window(lxevent->xmap.window, lxevent->xmap.event);
+ rail_create_window(lxevent->xmap.window, g_root_window);
if (!wnd_attributes.override_redirect)
{
rail_win_set_state(lxevent->xmap.window, 0x1); /* NormalState */
@@ -1887,7 +1913,16 @@ rail_xevent(void *xevent)
LOG(10, (" window 0x%8.8x is unmapped", lxevent->xunmap.window));
if (index >= 0)
{
+ XGetWindowAttributes(g_display, lxevent->xunmap.window, &wnd_attributes);
+ if (wnd_attributes.override_redirect)
+ {
+ // remove popups
+ rail_destroy_window(lxevent->xunmap.window);
+ list_remove_item(g_window_list, index);
+ } else {
rail_show_window(lxevent->xunmap.window, 0x0);
+ }
+
rv = 0;
}
}
diff --git a/sesman/chansrv/smartcard.c b/sesman/chansrv/smartcard.c
index 0d6d5405..a07e36eb 100644
--- a/sesman/chansrv/smartcard.c
+++ b/sesman/chansrv/smartcard.c
@@ -861,11 +861,6 @@ scard_make_new_ioctl(IRP *irp, tui32 ioctl)
struct stream *s;
xstream_new(s, 1024 * 4);
- if (s == NULL)
- {
- log_error("system out of memory");
- return s;
- }
devredir_insert_DeviceIoRequest(s,
irp->DeviceId,
diff --git a/sesman/chansrv/smartcard_pcsc.c b/sesman/chansrv/smartcard_pcsc.c
index 1d1618dc..9824432e 100644
--- a/sesman/chansrv/smartcard_pcsc.c
+++ b/sesman/chansrv/smartcard_pcsc.c
@@ -603,6 +603,7 @@ scard_process_list_readers(struct trans *con, struct stream *in_s)
{
LLOGLN(0, ("scard_process_list_readers: "
"get_pcsc_context_by_app_context failed"));
+ g_free(groups);
return 1;
}
pcscListReaders = g_malloc(sizeof(struct pcsc_list_readers), 1);
@@ -1489,6 +1490,7 @@ scard_process_get_status_change(struct trans *con, struct stream *in_s)
{
LLOGLN(0, ("scard_process_get_status_change: "
"get_pcsc_context_by_app_context failed"));
+ g_free(rsa);
return 1;
}
scard_send_get_status_change(user_data,
diff --git a/sesman/chansrv/sound.c b/sesman/chansrv/sound.c
index 8c76c9bc..f5e17fef 100644
--- a/sesman/chansrv/sound.c
+++ b/sesman/chansrv/sound.c
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2009-2013
+ * Copyright (C) Jay Sorg 2009-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,14 +23,11 @@
#include <signal.h>
#include <sys/un.h>
-#ifdef XRDP_LOAD_PULSE_MODULES
-#include <pulse/util.h>
-#endif
-
#include "sound.h"
#include "thread_calls.h"
#include "defines.h"
#include "fifo.h"
+#include "file_loc.h"
extern int g_rdpsnd_chan_id; /* in chansrv.c */
extern int g_display_num; /* in chansrv.c */
@@ -56,14 +53,6 @@ int g_buf_index = 0;
int g_sent_time[256];
int g_sent_flag[256];
-#if defined(XRDP_SIMPLESOUND)
-static void *DEFAULT_CC
-read_raw_audio_data(void *arg);
-#endif
-
-#define CHANSRV_PORT_OUT_STR "/tmp/.xrdp/xrdp_chansrv_audio_out_socket_%d"
-#define CHANSRV_PORT_IN_STR "/tmp/.xrdp/xrdp_chansrv_audio_in_socket_%d"
-
struct xr_wave_format_ex
{
int wFormatTag;
@@ -155,6 +144,25 @@ static struct xr_wave_format_ex *g_wave_inp_formats[SND_NUM_INP_FORMATS] =
static int g_client_input_format_index = 0;
static int g_server_input_format_index = 0;
+/* microphone related */
+static int APP_CC
+sound_send_server_input_formats(void);
+static int APP_CC
+sound_process_input_format(int aindex, int wFormatTag,
+ int nChannels, int nSamplesPerSec,
+ int nAvgBytesPerSec, int nBlockAlign,
+ int wBitsPerSample, int cbSize, char *data);
+static int APP_CC
+sound_process_input_formats(struct stream *s, int size);
+static int APP_CC
+sound_input_start_recording(void);
+static int APP_CC
+sound_input_stop_recording(void);
+static int APP_CC
+sound_process_input_data(struct stream *s, int bytes);
+static int DEFAULT_CC
+sound_sndsrvr_source_data_in(struct trans *trans);
+
/*****************************************************************************/
static int APP_CC
sound_send_server_output_formats(void)
@@ -224,7 +232,6 @@ sound_send_server_output_formats(void)
}
/*****************************************************************************/
-
static int
sound_send_training(void)
{
@@ -365,13 +372,15 @@ sound_send_wave_data_chunk(char *data, int data_bytes)
if ((data_bytes < 4) || (data_bytes > 128 * 1024))
{
LOG(0, ("sound_send_wave_data_chunk: bad data_bytes %d", data_bytes));
- return 0;
+ return 1;
}
+ LOG(20, ("sound_send_wave_data_chunk: g_sent_flag[%d] = %d",
+ g_cBlockNo + 1, g_sent_flag[(g_cBlockNo + 1) & 0xff]));
if (g_sent_flag[(g_cBlockNo + 1) & 0xff] & 1)
{
LOG(10, ("sound_send_wave_data_chunk: no room"));
- return 0;
+ return 2;
}
else
{
@@ -430,9 +439,12 @@ sound_send_wave_data(char *data, int data_bytes)
int space_left;
int chunk_bytes;
int data_index;
+ int error;
+ int res;
LOG(10, ("sound_send_wave_data: sending %d bytes", data_bytes));
data_index = 0;
+ error = 0;
while (data_bytes > 0)
{
space_left = BBUF_SIZE - g_buf_index;
@@ -440,19 +452,33 @@ sound_send_wave_data(char *data, int data_bytes)
if (chunk_bytes < 1)
{
LOG(10, ("sound_send_wave_data: error"));
+ error = 1;
break;
}
g_memcpy(g_buffer + g_buf_index, data + data_index, chunk_bytes);
g_buf_index += chunk_bytes;
if (g_buf_index >= BBUF_SIZE)
{
- sound_send_wave_data_chunk(g_buffer, BBUF_SIZE);
g_buf_index = 0;
+ res = sound_send_wave_data_chunk(g_buffer, BBUF_SIZE);
+ if (res == 2)
+ {
+ /* don't need to error on this */
+ LOG(0, ("sound_send_wave_data: dropped, no room"));
+ break;
+ }
+ else if (res != 0)
+ {
+ LOG(10, ("sound_send_wave_data: error"));
+ error = 1;
+ break;
+ }
}
data_bytes -= chunk_bytes;
data_index += chunk_bytes;
}
- return 0;
+
+ return error;
}
/*****************************************************************************/
@@ -467,9 +493,18 @@ sound_send_close(void)
LOG(10, ("sound_send_close:"));
/* send any left over data */
- sound_send_wave_data_chunk(g_buffer, g_buf_index);
+ if (g_buf_index)
+ {
+ if (sound_send_wave_data_chunk(g_buffer, g_buf_index) != 0)
+ {
+ LOG(10, ("sound_send_close: sound_send_wave_data_chunk failed"));
+ return 1;
+ }
+ }
g_buf_index = 0;
+ g_memset(g_sent_flag, 0, sizeof(g_sent_flag));
+ /* send close msg */
make_stream(s);
init_stream(s, 8182);
out_uint16_le(s, SNDC_CLOSE);
@@ -522,23 +557,23 @@ sound_process_wave_confirm(struct stream *s, int size)
/*****************************************************************************/
/* process message in from the audio source, eg pulse, alsa
- on it's way to the client */
+ on it's way to the client. returns error */
static int APP_CC
process_pcm_message(int id, int size, struct stream *s)
{
switch (id)
{
case 0:
- sound_send_wave_data(s->p, size);
+ return sound_send_wave_data(s->p, size);
break;
case 1:
- sound_send_close();
+ return sound_send_close();
break;
default:
LOG(10, ("process_pcm_message: unknown id %d", id));
break;
}
- return 0;
+ return 1;
}
/*****************************************************************************/
@@ -652,11 +687,6 @@ sound_init(void)
g_memset(g_sent_flag, 0, sizeof(g_sent_flag));
-#ifdef XRDP_LOAD_PULSE_MODULES
- if (load_pulse_modules())
- LOG(0, ("Audio and microphone redirection will not work!"));
-#endif
-
/* init sound output */
sound_send_server_output_formats();
@@ -682,13 +712,6 @@ sound_init(void)
/* save data from sound_server_source */
fifo_init(&in_fifo, 100);
-#if defined(XRDP_SIMPLESOUND)
-
- /* start thread to read raw audio data from pulseaudio device */
- tc_thread_create(read_raw_audio_data, 0);
-
-#endif
-
return 0;
}
@@ -696,6 +719,7 @@ sound_init(void)
int APP_CC
sound_deinit(void)
{
+ LOG(10, ("sound_deinit:"));
if (g_audio_l_trans_out != 0)
{
trans_delete(g_audio_l_trans_out);
@@ -722,10 +746,6 @@ sound_deinit(void)
fifo_deinit(&in_fifo);
-#ifdef XRDP_LOAD_PULSE_MODULES
- system("pulseaudio --kill");
-#endif
-
return 0;
}
@@ -814,180 +834,49 @@ sound_get_wait_objs(tbus *objs, int *count, int *timeout)
int APP_CC
sound_check_wait_objs(void)
{
+
if (g_audio_l_trans_out != 0)
{
- trans_check_wait_objs(g_audio_l_trans_out);
+ if (trans_check_wait_objs(g_audio_l_trans_out) != 0)
+ {
+ LOG(10, ("sound_check_wait_objs: g_audio_l_trans_out returned non-zero"));
+ trans_delete(g_audio_l_trans_out);
+ g_audio_l_trans_out = 0;
+ }
}
if (g_audio_c_trans_out != 0)
{
- trans_check_wait_objs(g_audio_c_trans_out);
- }
-
- if (g_audio_l_trans_in != 0)
- {
- trans_check_wait_objs(g_audio_l_trans_in);
- }
-
- if (g_audio_c_trans_in != 0)
- {
- trans_check_wait_objs(g_audio_c_trans_in);
- }
-
- return 0;
-}
-
-/**
- * Load xrdp pulseaudio sink and source modules
- *
- * @return 0 on success, -1 on failure
- *****************************************************************************/
-
-#ifdef XRDP_LOAD_PULSE_MODULES
-
-static int APP_CC
-load_pulse_modules()
-{
- struct sockaddr_un sa;
-
- pid_t pid;
- char* cli;
- int fd;
- int i;
- int rv;
- char buf[1024];
-
- /* is pulse audio daemon running? */
- if (pa_pid_file_check_running(&pid, "pulseaudio") < 0)
- {
- LOG(0, ("load_pulse_modules: No PulseAudio daemon running, "
- "or not running as session daemon"));
- }
-
- /* get name of unix domain socket used by pulseaudio for CLI */
- if ((cli = (char *) pa_runtime_path("cli")) == NULL)
- {
- LOG(0, ("load_pulse_modules: Error getting PulesAudio runtime path"));
- return -1;
- }
-
- /* open a socket */
- if ((fd = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0)
- {
- pa_xfree(cli);
- LOG(0, ("load_pulse_modules: Socket open error"));
- return -1;
- }
-
- /* set it up */
- memset(&sa, 0, sizeof(struct sockaddr_un));
- sa.sun_family = AF_UNIX;
- pa_strlcpy(sa.sun_path, cli, sizeof(sa.sun_path));
- pa_xfree(cli);
-
- for (i = 0; i < 20; i++)
- {
- if (pa_pid_file_kill(SIGUSR2, NULL, "pulseaudio") < 0)
- LOG(0, ("load_pulse_modules: Failed to kill PulseAudio daemon"));
-
- if ((rv = connect(fd, (struct sockaddr*) &sa, sizeof(sa))) < 0 &&
- (errno != ECONNREFUSED && errno != ENOENT))
+ if (trans_check_wait_objs(g_audio_c_trans_out) != 0)
{
- LOG(0, ("load_pulse_modules: connect() failed with error: %s",
- strerror(errno)));
- return -1;
+ LOG(10, ("sound_check_wait_objs: g_audio_c_trans_out returned non-zero"));
+ trans_delete(g_audio_c_trans_out);
+ g_audio_c_trans_out = 0;
}
-
- if (rv >= 0)
- break;
-
- pa_msleep(300);
}
- if (i >= 20)
- {
- LOG(0, ("load_pulse_modules: Daemon not responding"));
- return -1;
- }
-
- LOG(0, ("load_pulse_modules: connected to pulseaudio daemon"));
-
- /* read back PulseAudio sign on message */
- memset(buf, 0, 1024);
- recv(fd, buf, 1024, 0);
-
- /* send cmd to load source module */
- memset(buf, 0, 1024);
- sprintf(buf, "load-module module-xrdp-source\n");
- send(fd, buf, strlen(buf), 0);
-
- /* read back response */
- memset(buf, 0, 1024);
- recv(fd, buf, 1024, 0);
- if (strcasestr(buf, "Module load failed") != 0)
- {
- LOG(0, ("load_pulse_modules: Error loading module-xrdp-source"));
- }
- else
+ if (g_audio_l_trans_in != 0)
{
- LOG(0, ("load_pulse_modules: Loaded module-xrdp-source"));
-
- /* success, set it as the default source */
- memset(buf, 0, 1024);
- sprintf(buf, "set-default-source xrdp-source\n");
- send(fd, buf, strlen(buf), 0);
-
- memset(buf, 0, 1024);
- recv(fd, buf, 1024, 0);
-
- if (strcasestr(buf, "does not exist") != 0)
- {
- LOG(0, ("load_pulse_modules: Error setting default source"));
- }
- else
+ if (trans_check_wait_objs(g_audio_l_trans_in) != 0)
{
- LOG(0, ("load_pulse_modules: set default source"));
+ LOG(10, ("sound_check_wait_objs: g_audio_l_trans_in returned non-zero"));
+ trans_delete(g_audio_l_trans_in);
+ g_audio_l_trans_in = 0;
}
}
- /* send cmd to load sink module */
- memset(buf, 0, 1024);
- sprintf(buf, "load-module module-xrdp-sink\n");
- send(fd, buf, strlen(buf), 0);
-
- /* read back response */
- memset(buf, 0, 1024);
- recv(fd, buf, 1024, 0);
- if (strcasestr(buf, "Module load failed") != 0)
- {
- LOG(0, ("load_pulse_modules: Error loading module-xrdp-sink"));
- }
- else
+ if (g_audio_c_trans_in != 0)
{
- LOG(0, ("load_pulse_modules: Loaded module-xrdp-sink"));
-
- /* success, set it as the default sink */
- memset(buf, 0, 1024);
- sprintf(buf, "set-default-sink xrdp-sink\n");
- send(fd, buf, strlen(buf), 0);
-
- memset(buf, 0, 1024);
- recv(fd, buf, 1024, 0);
-
- if (strcasestr(buf, "does not exist") != 0)
- {
- LOG(0, ("load_pulse_modules: Error setting default sink"));
- }
- else
+ if (trans_check_wait_objs(g_audio_c_trans_in) != 0)
{
- LOG(0, ("load_pulse_modules: set default sink"));
+ LOG(10, ("sound_check_wait_objs: g_audio_c_trans_in returned non-zero"));
+ trans_delete(g_audio_c_trans_in);
+ g_audio_c_trans_in = 0;
}
}
- close(fd);
return 0;
}
-#endif
/******************************************************************************
** **
@@ -1152,7 +1041,7 @@ sound_process_input_formats(struct stream *s, int size)
*****************************************************************************/
static int APP_CC
-sound_input_start_recording()
+sound_input_start_recording(void)
{
struct stream* s;
@@ -1186,7 +1075,7 @@ sound_input_start_recording()
*****************************************************************************/
static int APP_CC
-sound_input_stop_recording()
+sound_input_stop_recording(void)
{
struct stream* s;
@@ -1252,14 +1141,14 @@ sound_sndsrvr_source_data_in(struct trans *trans)
return 1;
ts = trans_get_in_s(trans);
- trans_force_read(trans, 3);
+ if (trans_force_read(trans, 3))
+ log_message(LOG_LEVEL_ERROR, "sound.c: error reading from transport");
ts->p = ts->data + 8;
in_uint8(ts, cmd);
in_uint16_le(ts, bytes_req);
- if (bytes_req != 0)
- xstream_new(s, bytes_req + 2);
+ xstream_new(s, bytes_req + 2);
if (cmd == PA_CMD_SEND_DATA)
{
@@ -1309,7 +1198,6 @@ sound_sndsrvr_source_data_in(struct trans *trans)
s_mark_end(s);
trans_force_write_s(trans, s);
- xstream_free(s);
}
else if (cmd == PA_CMD_START_REC)
{
@@ -1320,133 +1208,7 @@ sound_sndsrvr_source_data_in(struct trans *trans)
sound_input_stop_recording();
}
- return 0;
-}
-
-/*****************************************************************************/
-
-#if defined(XRDP_SIMPLESOUND)
-
-#define AUDIO_BUF_SIZE 2048
+ xstream_free(s);
-static int DEFAULT_CC
-sttrans_data_in(struct trans *self)
-{
- LOG(0, ("sttrans_data_in:\n"));
return 0;
}
-
-/**
- * read raw audio data from pulseaudio device and write it
- * to a unix domain socket on which trans server is listening
- */
-
-static void *DEFAULT_CC
-read_raw_audio_data(void *arg)
-{
- pa_sample_spec samp_spec;
- pa_simple *simple = NULL;
- uint32_t bytes_read;
- char *cptr;
- int i;
- int error;
- struct trans *strans;
- char path[256];
- struct stream *outs;
-
- strans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
-
- if (strans == 0)
- {
- LOG(0, ("read_raw_audio_data: trans_create failed\n"));
- return 0;
- }
-
- strans->trans_data_in = sttrans_data_in;
- g_snprintf(path, 255, CHANSRV_PORT_OUT_STR, g_display_num);
-
- if (trans_connect(strans, "", path, 100) != 0)
- {
- LOG(0, ("read_raw_audio_data: trans_connect failed\n"));
- trans_delete(strans);
- return 0;
- }
-
- /* setup audio format */
- samp_spec.format = PA_SAMPLE_S16LE;
- samp_spec.rate = 44100;
- samp_spec.channels = 2;
-
- /* if we are root, then for first 8 seconds connection to pulseaudo server
- fails; if we are non-root, then connection succeeds on first attempt;
- for now we have changed code to be non-root, but this may change in the
- future - so pretend we are root and try connecting to pulseaudio server
- for upto one minute */
- for (i = 0; i < 60; i++)
- {
- simple = pa_simple_new(NULL, "xrdp", PA_STREAM_RECORD, NULL,
- "record", &samp_spec, NULL, NULL, &error);
-
- if (simple)
- {
- /* connected to pulseaudio server */
- LOG(0, ("read_raw_audio_data: connected to pulseaudio server\n"));
- break;
- }
-
- LOG(0, ("read_raw_audio_data: ERROR creating PulseAudio async interface\n"));
- LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error)));
- g_sleep(1000);
- }
-
- if (i == 60)
- {
- /* failed to connect to audio server */
- trans_delete(strans);
- return NULL;
- }
-
- /* insert header just once */
- outs = trans_get_out_s(strans, 8192);
- out_uint32_le(outs, 0);
- out_uint32_le(outs, AUDIO_BUF_SIZE + 8);
- cptr = outs->p;
- out_uint8s(outs, AUDIO_BUF_SIZE);
- s_mark_end(outs);
-
- while (1)
- {
- /* read a block of raw audio data... */
- g_memset(cptr, 0, 4);
- bytes_read = pa_simple_read(simple, cptr, AUDIO_BUF_SIZE, &error);
-
- if (bytes_read < 0)
- {
- LOG(0, ("read_raw_audio_data: ERROR reading from pulseaudio stream\n"));
- LOG(0, ("read_raw_audio_data: %s\n", pa_strerror(error)));
- break;
- }
-
- /* bug workaround:
- even when there is no audio data, pulseaudio is returning without
- errors but the data itself is zero; we use this zero data to
- determine that there is no audio data present */
- if (*cptr == 0 && *(cptr + 1) == 0 && *(cptr + 2) == 0 && *(cptr + 3) == 0)
- {
- g_sleep(10);
- continue;
- }
-
- if (trans_force_write_s(strans, outs) != 0)
- {
- LOG(0, ("read_raw_audio_data: ERROR writing audio data to server\n"));
- break;
- }
- }
-
- pa_simple_free(simple);
- trans_delete(strans);
- return NULL;
-}
-
-#endif
diff --git a/sesman/chansrv/sound.h b/sesman/chansrv/sound.h
index c26d0913..f3563dab 100644
--- a/sesman/chansrv/sound.h
+++ b/sesman/chansrv/sound.h
@@ -1,7 +1,7 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
- * Copyright (C) Jay Sorg 2009-2013
+ * Copyright (C) Jay Sorg 2009-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,11 +19,6 @@
#ifndef _SOUND_H_
#define _SOUND_H_
-#if defined(XRDP_SIMPLESOUND)
-#include <pulse/simple.h>
-#include <pulse/error.h>
-#endif
-
#include "arch.h"
#include "parse.h"
#include "os_calls.h"
@@ -63,17 +58,4 @@ int APP_CC sound_check_wait_objs(void);
int APP_CC sound_data_in(struct stream* s, int chan_id, int chan_flags,
int length, int total_length);
-/* microphone related */
-static int APP_CC sound_send_server_input_formats(void);
-
-static int APP_CC sound_process_input_format(int aindex, int wFormatTag,
- int nChannels, int nSamplesPerSec, int nAvgBytesPerSec,
- int nBlockAlign, int wBitsPerSample, int cbSize, char *data);
-
-static int APP_CC sound_process_input_formats(struct stream *s, int size);
-static int APP_CC sound_input_start_recording();
-static int APP_CC sound_input_stop_recording();
-static int APP_CC sound_process_input_data(struct stream *s, int bytes);
-static int DEFAULT_CC sound_sndsrvr_source_data_in(struct trans *trans);
-static int APP_CC load_pulse_modules();
#endif
diff --git a/sesman/config.c b/sesman/config.c
index 877a949c..5a904fc3 100644
--- a/sesman/config.c
+++ b/sesman/config.c
@@ -74,9 +74,10 @@ config_read(struct config_sesman *cfg)
/* read global config */
config_read_globals(fd, cfg, param_n, param_v);
- /* read Xvnc/X11rdp parameter list */
+ /* read Xvnc/X11rdp/XOrg parameter list */
config_read_vnc_params(fd, cfg, param_n, param_v);
config_read_rdp_params(fd, cfg, param_n, param_v);
+ config_read_xorg_params(fd, cfg, param_n, param_v);
/* read logging config */
// config_read_logging(fd, &(cfg->log), param_n, param_v);
@@ -87,6 +88,8 @@ config_read(struct config_sesman *cfg)
/* read session config */
config_read_sessions(fd, &(cfg->sess), param_n, param_v);
+ config_read_session_variables(fd, cfg, param_n, param_v);
+
/* cleanup */
list_delete(sec);
list_delete(param_v);
@@ -336,6 +339,7 @@ config_read_sessions(int file, struct config_sessions *se, struct list *param_n,
se->max_idle_time = 0;
se->max_disc_time = 0;
se->kill_disconnected = 0;
+ se->policy = SESMAN_CFG_SESS_POLICY_DFLT;
file_read_section(file, SESMAN_CFG_SESSIONS, param_n, param_v);
@@ -367,15 +371,49 @@ config_read_sessions(int file, struct config_sessions *se, struct list *param_n,
{
se->max_disc_time = g_atoi((char *)list_get_item(param_v, i));
}
+
+ if (0 == g_strcasecmp(buf, SESMAN_CFG_SESS_POLICY_S))
+ {
+ char *value = (char *)list_get_item(param_v, i);
+ if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_DFLT_S))
+ {
+ se->policy = SESMAN_CFG_SESS_POLICY_DFLT;
+ }
+ else if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_UBD_S))
+ {
+ se->policy = SESMAN_CFG_SESS_POLICY_UBD;
+ }
+ else if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_UBI_S))
+ {
+ se->policy = SESMAN_CFG_SESS_POLICY_UBI;
+ }
+ else if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_UBC_S))
+ {
+ se->policy = SESMAN_CFG_SESS_POLICY_UBC;
+ }
+ else if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_UBDI_S))
+ {
+ se->policy = SESMAN_CFG_SESS_POLICY_UBDI;
+ }
+ else if (0 == g_strcasecmp(value, SESMAN_CFG_SESS_POLICY_UBDC_S))
+ {
+ se->policy = SESMAN_CFG_SESS_POLICY_UBDC;
+ }
+ else /* silently ignore typos */
+ {
+ se->policy = SESMAN_CFG_SESS_POLICY_DFLT;
+ }
+ }
}
- /* printing security config */
+ /* printing session config */
g_printf("session configuration:\r\n");
g_printf("\tMaxSessions: %i\r\n", se->max_sessions);
g_printf("\tX11DisplayOffset: %i\r\n", se->x11_display_offset);
g_printf("\tKillDisconnected: %i\r\n", se->kill_disconnected);
g_printf("\tIdleTimeLimit: %i\r\n", se->max_idle_time);
g_printf("\tDisconnectedTimeLimit: %i\r\n", se->max_idle_time);
+ g_printf("\tPolicy: %i\r\n", se->policy);
return 0;
}
@@ -412,6 +450,38 @@ config_read_rdp_params(int file, struct config_sesman *cs, struct list *param_n,
/******************************************************************************/
int DEFAULT_CC
+config_read_xorg_params(int file, struct config_sesman *cs,
+ struct list *param_n, struct list *param_v)
+{
+ int i;
+
+ list_clear(param_v);
+ list_clear(param_n);
+
+ cs->xorg_params = list_create();
+
+ file_read_section(file, SESMAN_CFG_XORG_PARAMS, param_n, param_v);
+
+ for (i = 0; i < param_n->count; i++)
+ {
+ list_add_item(cs->xorg_params,
+ (long) g_strdup((char *) list_get_item(param_v, i)));
+ }
+
+ /* printing security config */
+ g_printf("XOrg parameters:\r\n");
+
+ for (i = 0; i < cs->xorg_params->count; i++)
+ {
+ g_printf("\tParameter %02d %s\r\n",
+ i, (char *) list_get_item(cs->xorg_params, i));
+ }
+
+ return 0;
+}
+
+/******************************************************************************/
+int DEFAULT_CC
config_read_vnc_params(int file, struct config_sesman *cs, struct list *param_n,
struct list *param_v)
{
@@ -439,3 +509,39 @@ config_read_vnc_params(int file, struct config_sesman *cs, struct list *param_n,
return 0;
}
+
+/******************************************************************************/
+int DEFAULT_CC
+config_read_session_variables(int file, struct config_sesman *cs,
+ struct list *param_n, struct list *param_v)
+{
+ int i;
+
+ list_clear(param_v);
+ list_clear(param_n);
+
+ cs->session_variables1 = list_create();
+ cs->session_variables2 = list_create();
+
+ file_read_section(file, SESMAN_CFG_SESSION_VARIABLES, param_n, param_v);
+
+ for (i = 0; i < param_n->count; i++)
+ {
+ list_add_item(cs->session_variables1,
+ (tintptr) g_strdup((char *) list_get_item(param_n, i)));
+ list_add_item(cs->session_variables2,
+ (tintptr) g_strdup((char *) list_get_item(param_v, i)));
+ }
+
+ /* printing security config */
+ g_writeln("%s parameters:", SESMAN_CFG_SESSION_VARIABLES);
+
+ for (i = 0; i < cs->session_variables1->count; i++)
+ {
+ g_writeln(" Parameter %02d %s=%s", i,
+ (char *) list_get_item(cs->session_variables1, i),
+ (char *) list_get_item(cs->session_variables2, i));
+ }
+
+ return 0;
+}
diff --git a/sesman/config.h b/sesman/config.h
index b011ca9b..08d84ce1 100644
--- a/sesman/config.h
+++ b/sesman/config.h
@@ -42,8 +42,11 @@
#define SESMAN_CFG_AUTH_FILE_PATH "AuthFilePath"
#define SESMAN_CFG_RDP_PARAMS "X11rdp"
+#define SESMAN_CFG_XORG_PARAMS "Xorg"
#define SESMAN_CFG_VNC_PARAMS "Xvnc"
+#define SESMAN_CFG_SESSION_VARIABLES "SessionVariables"
+
/*
#define SESMAN_CFG_LOGGING "Logging"
#define SESMAN_CFG_LOG_FILE "LogFile"
@@ -64,6 +67,29 @@
#define SESMAN_CFG_SESS_IDLE_LIMIT "IdleTimeLimit"
#define SESMAN_CFG_SESS_DISC_LIMIT "DisconnectedTimeLimit"
+#define SESMAN_CFG_SESS_POLICY_S "Policy"
+#define SESMAN_CFG_SESS_POLICY_DFLT_S "Default"
+#define SESMAN_CFG_SESS_POLICY_UBD_S "UBD"
+#define SESMAN_CFG_SESS_POLICY_UBI_S "UBI"
+#define SESMAN_CFG_SESS_POLICY_UBC_S "UBC"
+#define SESMAN_CFG_SESS_POLICY_UBDI_S "UBDI"
+#define SESMAN_CFG_SESS_POLICY_UBDC_S "UBDC"
+
+enum SESMAN_CFG_SESS_POLICY_BITS {
+ SESMAN_CFG_SESS_POLICY_D = 0x01,
+ SESMAN_CFG_SESS_POLICY_I = 0x02,
+ SESMAN_CFG_SESS_POLICY_C = 0x04
+};
+
+enum SESMAN_CFG_SESS_POLICY {
+ SESMAN_CFG_SESS_POLICY_DFLT = 0,
+ SESMAN_CFG_SESS_POLICY_UBD = SESMAN_CFG_SESS_POLICY_D,
+ SESMAN_CFG_SESS_POLICY_UBI = SESMAN_CFG_SESS_POLICY_I,
+ SESMAN_CFG_SESS_POLICY_UBC = SESMAN_CFG_SESS_POLICY_C,
+ SESMAN_CFG_SESS_POLICY_UBDI = SESMAN_CFG_SESS_POLICY_D | SESMAN_CFG_SESS_POLICY_I,
+ SESMAN_CFG_SESS_POLICY_UBDC = SESMAN_CFG_SESS_POLICY_D | SESMAN_CFG_SESS_POLICY_C
+};
+
/**
*
* @struct config_security
@@ -134,6 +160,11 @@ struct config_sessions
* @brief enables automatic killing of disconnected session
*/
int kill_disconnected;
+ /**
+ * @var policy
+ * @brief session allocation policy
+ */
+ enum SESMAN_CFG_SESS_POLICY policy;
};
/**
@@ -192,6 +223,13 @@ struct config_sesman
* @var log
* @brief Log configuration struct
*/
+
+ struct list* xorg_params;
+ /**
+ * @var log
+ * @brief Log configuration struct
+ */
+
//struct log_config log;
/**
* @var sec
@@ -203,6 +241,9 @@ struct config_sesman
* @brief Session configuration options struct
*/
struct config_sessions sess;
+
+ struct list* session_variables1;
+ struct list* session_variables2;
};
/**
@@ -285,6 +326,19 @@ int DEFAULT_CC
config_read_rdp_params(int file, struct config_sesman* cs, struct list* param_n,
struct list* param_v);
+/**
+ *
+ * @brief Reads sesman [XOrg] configuration section
+ * @param file configuration file descriptor
+ * @param cs pointer to a config_sesman struct
+ * @param param_n parameter name list
+ * @param param_v parameter value list
+ * @return 0 on success, 1 on failure
+ *
+ */
+int DEFAULT_CC
+config_read_xorg_params(int file, struct config_sesman* cs, struct list* param_n,
+ struct list* param_v);
/**
*
@@ -300,4 +354,8 @@ int DEFAULT_CC
config_read_vnc_params(int file, struct config_sesman* cs, struct list* param_n,
struct list* param_v);
+int DEFAULT_CC
+config_read_session_variables(int file, struct config_sesman *cs,
+ struct list *param_n, struct list *param_v);
+
#endif
diff --git a/sesman/env.c b/sesman/env.c
index b650d0b3..227f6bbf 100644
--- a/sesman/env.c
+++ b/sesman/env.c
@@ -24,6 +24,8 @@
*
*/
+#include "list.h"
+
#include "sesman.h"
#include "sys/types.h"
@@ -60,12 +62,16 @@ env_check_password_file(char *filename, char *password)
/******************************************************************************/
int DEFAULT_CC
-env_set_user(char *username, char *passwd_file, int display)
+env_set_user(char *username, char *passwd_file, int display,
+ struct list *env_names, struct list* env_values)
{
int error;
int pw_uid;
int pw_gid;
int uid;
+ int index;
+ char *name;
+ char *value;
char pw_shell[256];
char pw_dir[256];
char pw_gecos[256];
@@ -96,7 +102,7 @@ env_set_user(char *username, char *passwd_file, int display)
{
g_clearenv();
g_setenv("SHELL", pw_shell, 1);
- g_setenv("PATH", "/bin:/usr/bin:/usr/X11R6/bin:/usr/local/bin", 1);
+ g_setenv("PATH", "/bin:/usr/bin:/usr/local/bin", 1);
g_setenv("USER", username, 1);
g_sprintf(text, "%d", uid);
g_setenv("UID", text, 1);
@@ -106,6 +112,16 @@ env_set_user(char *username, char *passwd_file, int display)
g_setenv("DISPLAY", text, 1);
g_setenv("LANG", "en_US.UTF-8", 1);
g_setenv("XRDP_SESSION", "1", 1);
+ if ((env_names != 0) && (env_values != 0) &&
+ (env_names->count == env_values->count))
+ {
+ for (index = 0; index < env_names->count; index++)
+ {
+ name = (char *) list_get_item(env_names, index),
+ value = (char *) list_get_item(env_values, index),
+ g_setenv(name, value, 1);
+ }
+ }
if (passwd_file != 0)
{
@@ -113,7 +129,11 @@ env_set_user(char *username, char *passwd_file, int display)
{
/* if no auth_file_path is set, then we go for
$HOME/.vnc/sesman_username_passwd */
- g_mkdir(".vnc");
+ if (g_mkdir(".vnc") < 0)
+ {
+ log_message(LOG_LEVEL_ERROR,
+ "env_set_user: error creating .vnc dir");
+ }
g_sprintf(passwd_file, "%s/.vnc/sesman_%s_passwd", pw_dir, username);
}
else
diff --git a/sesman/env.h b/sesman/env.h
index e70bfe6a..50473a01 100644
--- a/sesman/env.h
+++ b/sesman/env.h
@@ -27,6 +27,8 @@
#ifndef ENV_H
#define ENV_H
+#include "list.h"
+
/**
*
* @brief Creates vnc password file
@@ -48,6 +50,7 @@ env_check_password_file(char* filename, char* password);
*
*/
int DEFAULT_CC
-env_set_user(char* username, char* passwd_file, int display);
+env_set_user(char* username, char* passwd_file, int display,
+ struct list *env_names, struct list* env_values);
#endif
diff --git a/sesman/libscp/libscp_session.c b/sesman/libscp/libscp_session.c
index 4c389655..d25fc64a 100644
--- a/sesman/libscp/libscp_session.c
+++ b/sesman/libscp/libscp_session.c
@@ -58,12 +58,19 @@ scp_session_set_type(struct SCP_SESSION *s, tui8 type)
case SCP_SESSION_TYPE_XVNC:
s->type = SCP_SESSION_TYPE_XVNC;
break;
+
case SCP_SESSION_TYPE_XRDP:
s->type = SCP_SESSION_TYPE_XRDP;
break;
+
+ case SCP_SESSION_TYPE_XORG:
+ s->type = SCP_SESSION_TYPE_XORG;
+ break;
+
case SCP_GW_AUTHENTICATION:
s->type = SCP_GW_AUTHENTICATION;
break;
+
case SCP_SESSION_TYPE_MANAGE:
s->type = SCP_SESSION_TYPE_MANAGE;
s->mng = (struct SCP_MNG_DATA *)g_malloc(sizeof(struct SCP_MNG_DATA), 1);
@@ -75,6 +82,7 @@ scp_session_set_type(struct SCP_SESSION *s, tui8 type)
}
break;
+
default:
log_message(LOG_LEVEL_WARNING, "[session:%d] set_type: unknown type", __LINE__);
return 1;
diff --git a/sesman/libscp/libscp_types.h b/sesman/libscp/libscp_types.h
index 2140eced..de851867 100644
--- a/sesman/libscp/libscp_types.h
+++ b/sesman/libscp/libscp_types.h
@@ -41,6 +41,8 @@
#define SCP_SESSION_TYPE_XVNC 0x00
#define SCP_SESSION_TYPE_XRDP 0x01
#define SCP_SESSION_TYPE_MANAGE 0x02
+#define SCP_SESSION_TYPE_XORG 0x03
+
/* SCP_GW_AUTHENTICATION can be used when XRDP + sesman act as a gateway
* XRDP sends this command to let sesman verify if the user is allowed
* to use the gateway */
diff --git a/sesman/libscp/libscp_v0.c b/sesman/libscp/libscp_v0.c
index afa09bd8..8cf1340b 100644
--- a/sesman/libscp/libscp_v0.c
+++ b/sesman/libscp/libscp_v0.c
@@ -56,6 +56,10 @@ scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
{
out_uint16_be(c->out_s, 10);
}
+ else if (s->type == SCP_SESSION_TYPE_XORG)
+ {
+ out_uint16_be(c->out_s, 20);
+ }
else
{
log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
@@ -191,7 +195,7 @@ scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk)
in_uint16_be(c->in_s, code);
- if (code == 0 || code == 10)
+ if (code == 0 || code == 10 || code == 20)
{
session = scp_session_create();
@@ -207,10 +211,14 @@ scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk)
{
scp_session_set_type(session, SCP_SESSION_TYPE_XVNC);
}
- else
+ else if (code == 10)
{
scp_session_set_type(session, SCP_SESSION_TYPE_XRDP);
}
+ else if (code == 20)
+ {
+ scp_session_set_type(session, SCP_SESSION_TYPE_XORG);
+ }
/* reading username */
in_uint16_be(c->in_s, sz);
diff --git a/sesman/scp_v0.c b/sesman/scp_v0.c
index aeaa22ee..ce528d46 100644
--- a/sesman/scp_v0.c
+++ b/sesman/scp_v0.c
@@ -74,7 +74,7 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
else if (data)
{
s_item = session_get_bydata(s->username, s->width, s->height,
- s->bpp, s->type);
+ s->bpp, s->type, s->client_ip);
if (s_item != 0)
{
@@ -122,12 +122,21 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
s->domain, s->program, s->directory,
s->client_ip);
}
- else
+ else if (SCP_SESSION_TYPE_XRDP == s->type)
{
log_message(LOG_LEVEL_INFO, "starting X11rdp session...");
display = session_start(s->width, s->height, s->bpp, s->username,
s->password, data, SESMAN_SESSION_TYPE_XRDP,
s->domain, s->program, s->directory,
+ s->client_ip);
+ }
+ else if (SCP_SESSION_TYPE_XORG == s->type)
+ {
+ /* type is SCP_SESSION_TYPE_XORG */
+ log_message(LOG_LEVEL_INFO, "starting Xorg session...");
+ display = session_start(s->width, s->height, s->bpp, s->username,
+ s->password, data, SESMAN_SESSION_TYPE_XORG,
+ s->domain, s->program, s->directory,
s->client_ip);
}
}
diff --git a/sesman/scp_v1.c b/sesman/scp_v1.c
index 12115929..2324b750 100644
--- a/sesman/scp_v1.c
+++ b/sesman/scp_v1.c
@@ -195,8 +195,6 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
parseCommonStates(e, "scp_v1s_list_sessions()");
break;
}
-
- g_free(slist);
}
/* resource management */
@@ -208,6 +206,7 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
/* cleanup */
scp_session_destroy(s);
auth_end(data);
+ g_free(slist);
}
static void parseCommonStates(enum SCP_SERVER_STATES_E e, char *f)
diff --git a/sesman/sesman.c b/sesman/sesman.c
index 83db5961..1c620210 100644
--- a/sesman/sesman.c
+++ b/sesman/sesman.c
@@ -54,7 +54,14 @@ sesman_main_loop(void)
/*main program loop*/
log_message(LOG_LEVEL_INFO, "listening...");
+
g_sck = g_tcp_socket();
+ if (g_sck < 0)
+ {
+ log_message(LOG_LEVEL_ERROR, "error opening socket, g_tcp_socket() failed...");
+ return 1;
+ }
+
g_tcp_set_non_blocking(g_sck);
error = scp_tcp_bind(g_sck, g_cfg->listen_address, g_cfg->listen_port);
@@ -132,7 +139,8 @@ sesman_main_loop(void)
g_get_errno(), g_get_strerror());
}
- g_tcp_close(g_sck);
+ if (g_sck != -1)
+ g_tcp_close(g_sck);
}
/******************************************************************************/
@@ -308,9 +316,17 @@ main(int argc, char **argv)
g_file_close(1);
g_file_close(2);
- g_file_open("/dev/null");
- g_file_open("/dev/null");
- g_file_open("/dev/null");
+ if (g_file_open("/dev/null") < 0)
+ {
+ }
+
+ if (g_file_open("/dev/null") < 0)
+ {
+ }
+
+ if (g_file_open("/dev/null") < 0)
+ {
+ }
}
/* initializing locks */
@@ -361,7 +377,11 @@ main(int argc, char **argv)
/* make sure the /tmp/.X11-unix directory exist */
if (!g_directory_exist("/tmp/.X11-unix"))
{
- g_create_dir("/tmp/.X11-unix");
+ if (!g_create_dir("/tmp/.X11-unix"))
+ {
+ log_message(LOG_LEVEL_ERROR,
+ "sesman.c: error creating dir /tmp/.X11-unix");
+ }
g_chmod_hex("/tmp/.X11-unix", 0x1777);
}
diff --git a/sesman/sesman.ini b/sesman/sesman.ini
index 5ee0b4cd..a58af383 100644
--- a/sesman/sesman.ini
+++ b/sesman/sesman.ini
@@ -10,22 +10,52 @@ AllowRootLogin=1
MaxLoginRetry=4
TerminalServerUsers=tsusers
TerminalServerAdmins=tsadmins
-# When AlwaysGroupCheck = false access will be permitted
+# When AlwaysGroupCheck = false access will be permitted
# if the group TerminalServerUsers is not defined.
AlwaysGroupCheck = false
[Sessions]
+
+## X11DisplayOffset - x11 display number offset
+# Type: integer
+# Default: 10
X11DisplayOffset=10
+
+## MaxSessions - maximum number of connections to an xrdp server
+# Type: integer
+# Default: 0
MaxSessions=50
+
+## KillDisconnected - kill disconnected sessions
+# Type: integer
+# Default: 0
# if 1, true, or yes, kill session after 60 seconds
KillDisconnected=0
+
+## IdleTimeLimit - when to disconnect idle sessions
+# Type: integer
+# Default: 0
# if not zero, the seconds without mouse or keyboard input before disconnect
# not complete yet
IdleTimeLimit=0
+
+## DisconnectedTimeLimit - when to kill idle sessions
+# Type: integer
+# Default: 0
# if not zero, the seconds before a disconnected session is killed
# min 60 seconds
DisconnectedTimeLimit=0
+## Policy - session allocation policy
+# Type: enum [ "Default" | "UBD" | "UBI" | "UBC" | "UBDI" | "UBDC" ]
+# Default: Xrdp:<User,BitPerPixel> and Xvnc:<User,BitPerPixel,DisplaySize>
+# "UBD" session per <User,BitPerPixel,DisplaySize>
+# "UBI" session per <User,BitPerPixel,IPAddr>
+# "UBC" session per <User,BitPerPixel,Connection>
+# "UBDI" session per <User,BitPerPixel,DisplaySize,IPAddr>
+# "UBDC" session per <User,BitPerPixel,DisplaySize,Connection>
+Policy=Default
+
[Logging]
LogFile=xrdp-sesman.log
LogLevel=DEBUG
@@ -47,3 +77,20 @@ param4=tcp
param5=-localhost
param6=-dpi
param7=96
+
+[Xorg]
+param1=-config
+param2=xrdp/xorg.conf
+param3=-logfile
+param4=/dev/null
+param5=-noreset
+param6=-ac
+param7=-nolisten
+param8=tcp
+
+[Chansrv]
+# drive redirection, defaults to xrdp_client if not set
+FuseMountName=thinclient_drives
+
+[SessionVariables]
+PULSE_SCRIPT=/etc/xrdp/pulse/default.pa
diff --git a/sesman/session.c b/sesman/session.c
index 665d1138..856c969e 100644
--- a/sesman/session.c
+++ b/sesman/session.c
@@ -90,9 +90,10 @@ dumpItemsToString(struct list *self, char *outstr, int len)
/******************************************************************************/
struct session_item *DEFAULT_CC
-session_get_bydata(char *name, int width, int height, int bpp, int type)
+session_get_bydata(char *name, int width, int height, int bpp, int type, char *client_ip)
{
struct session_chain *tmp;
+ enum SESMAN_CFG_SESS_POLICY policy = g_cfg->sess.policy;
/*THREAD-FIX require chain lock */
lock_chain_acquire();
@@ -104,23 +105,49 @@ session_get_bydata(char *name, int width, int height, int bpp, int type)
{
case SCP_SESSION_TYPE_XVNC: /* 0 */
type = SESMAN_SESSION_TYPE_XVNC; /* 2 */
+ policy |= SESMAN_CFG_SESS_POLICY_D; /* Xvnc cannot resize */
break;
case SCP_SESSION_TYPE_XRDP: /* 1 */
type = SESMAN_SESSION_TYPE_XRDP; /* 1 */
break;
+ case SCP_SESSION_TYPE_XORG:
+ type = SESMAN_SESSION_TYPE_XORG;
+ break;
default:
lock_chain_release();
return 0;
}
+#if 0
+ log_message(LOG_LEVEL_INFO,
+ "session_get_bydata: search policy %d U %s W %d H %d bpp %d T %d IP %s",
+ policy, name, width, height, bpp, type, client_ip);
+#endif
+
while (tmp != 0)
{
+#if 0
+ log_message(LOG_LEVEL_INFO,
+ "session_get_bydata: try %p U %s W %d H %d bpp %d T %d IP %s",
+ tmp->item,
+ tmp->item->name,
+ tmp->item->width, tmp->item->height,
+ tmp->item->bpp, tmp->item->type,
+ tmp->item->client_ip);
+#endif
+
if (type == SESMAN_SESSION_TYPE_XRDP)
{
/* only name and bpp need to match for X11rdp, it can resize */
if (g_strncmp(name, tmp->item->name, 255) == 0 &&
- tmp->item->bpp == bpp &&
- tmp->item->type == type)
+ (!(policy & SESMAN_CFG_SESS_POLICY_D) ||
+ (tmp->item->width == width && tmp->item->height == height)) &&
+ (!(policy & SESMAN_CFG_SESS_POLICY_I) ||
+ (g_strncmp_d(client_ip, tmp->item->client_ip, ':', 255) == 0)) &&
+ (!(policy & SESMAN_CFG_SESS_POLICY_C) ||
+ (g_strncmp(client_ip, tmp->item->client_ip, 255) == 0)) &&
+ tmp->item->bpp == bpp &&
+ tmp->item->type == type)
{
/*THREAD-FIX release chain lock */
lock_chain_release();
@@ -129,10 +156,13 @@ session_get_bydata(char *name, int width, int height, int bpp, int type)
}
if (g_strncmp(name, tmp->item->name, 255) == 0 &&
- tmp->item->width == width &&
- tmp->item->height == height &&
- tmp->item->bpp == bpp &&
- tmp->item->type == type)
+ (tmp->item->width == width && tmp->item->height == height) &&
+ (!(policy & SESMAN_CFG_SESS_POLICY_I) ||
+ (g_strncmp_d(client_ip, tmp->item->client_ip, ':', 255) == 0)) &&
+ (!(policy & SESMAN_CFG_SESS_POLICY_C) ||
+ (g_strncmp(client_ip, tmp->item->client_ip, 255) == 0)) &&
+ tmp->item->bpp == bpp &&
+ tmp->item->type == type)
{
/*THREAD-FIX release chain lock */
lock_chain_release();
@@ -173,26 +203,62 @@ x_server_running_check_ports(int display)
if (!x_running) /* check 59xx */
{
- sck = g_tcp_socket();
- g_sprintf(text, "59%2.2d", display);
- x_running = g_tcp_bind(sck, text);
- g_tcp_close(sck);
+ if ((sck = g_tcp_socket()) != -1)
+ {
+ g_sprintf(text, "59%2.2d", display);
+ x_running = g_tcp_bind(sck, text);
+ g_tcp_close(sck);
+ }
}
if (!x_running) /* check 60xx */
{
- sck = g_tcp_socket();
- g_sprintf(text, "60%2.2d", display);
- x_running = g_tcp_bind(sck, text);
- g_tcp_close(sck);
+ if ((sck = g_tcp_socket()) != -1)
+ {
+ g_sprintf(text, "60%2.2d", display);
+ x_running = g_tcp_bind(sck, text);
+ g_tcp_close(sck);
+ }
}
if (!x_running) /* check 62xx */
{
- sck = g_tcp_socket();
- g_sprintf(text, "62%2.2d", display);
- x_running = g_tcp_bind(sck, text);
- g_tcp_close(sck);
+ if ((sck = g_tcp_socket()) != -1)
+ {
+ g_sprintf(text, "62%2.2d", display);
+ x_running = g_tcp_bind(sck, text);
+ g_tcp_close(sck);
+ }
+ }
+
+ if (!x_running)
+ {
+ g_sprintf(text, XRDP_CHANSRV_STR, display);
+ x_running = g_file_exist(text);
+ }
+
+ if (!x_running)
+ {
+ g_sprintf(text, CHANSRV_PORT_OUT_STR, display);
+ x_running = g_file_exist(text);
+ }
+
+ if (!x_running)
+ {
+ g_sprintf(text, CHANSRV_PORT_IN_STR, display);
+ x_running = g_file_exist(text);
+ }
+
+ if (!x_running)
+ {
+ g_sprintf(text, CHANSRV_API_STR, display);
+ x_running = g_file_exist(text);
+ }
+
+ if (!x_running)
+ {
+ g_sprintf(text, XRDP_X11RDP_STR, display);
+ x_running = g_file_exist(text);
}
return x_running;
@@ -258,7 +324,8 @@ session_start_sessvc(int xpid, int wmpid, long data, char *username, int display
list_add_item(sessvc_params, (long)g_strdup(wmpid_str));
list_add_item(sessvc_params, 0); /* mandatory */
- env_set_user(username, 0, display);
+ env_set_user(username, 0, display,
+ g_cfg->session_variables1, g_cfg->session_variables2);
/* executing sessvc */
g_execvp(exe_path, ((char **)sessvc_params->items));
@@ -471,7 +538,9 @@ session_start_fork(int width, int height, int bpp, char *username,
}
else if (pampid == 0) /* child: X11/client */
{
- env_set_user(username, 0, display);
+ env_set_user(username, 0, display,
+ g_cfg->session_variables1,
+ g_cfg->session_variables2);
if (x_server_running(display))
{
auth_set_env(data);
@@ -564,7 +633,9 @@ session_start_fork(int width, int height, int bpp, char *username,
}
else if (xpid == 0) /* child */
{
- env_set_user(username, passwd_file, display);
+ env_set_user(username, passwd_file, display,
+ g_cfg->session_variables1,
+ g_cfg->session_variables2);
env_check_password_file(passwd_file, password);
g_snprintf(text, 255, "%d", g_cfg->sess.max_idle_time);
@@ -574,10 +645,40 @@ session_start_fork(int width, int height, int bpp, char *username,
g_snprintf(text, 255, "%d", g_cfg->sess.kill_disconnected);
g_setenv("XRDP_SESMAN_KILL_DISCONNECTED", text, 1);
- if (type == SESMAN_SESSION_TYPE_XVNC)
+ if (type == SESMAN_SESSION_TYPE_XORG)
{
xserver_params = list_create();
xserver_params->auto_free = 1;
+
+ /* these are the must have parameters */
+ list_add_item(xserver_params, (long) g_strdup("/usr/bin/Xorg"));
+ list_add_item(xserver_params, (long) g_strdup(screen));
+
+ /* additional parameters from sesman.ini file */
+ list_append_list_strdup(g_cfg->xorg_params, xserver_params, 0);
+
+ /* make sure it ends with a zero */
+ list_add_item(xserver_params, 0);
+
+ pp1 = (char **) xserver_params->items;
+
+ log_message(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048));
+
+ /* some args are passed via env vars */
+ g_sprintf(geometry, "%d", width);
+ g_setenv("XRDP_START_WIDTH", geometry, 1);
+
+ g_sprintf(geometry, "%d", height);
+ g_setenv("XRDP_START_HEIGHT", geometry, 1);
+
+ /* fire up Xorg */
+ g_execvp("/usr/bin/Xorg", pp1);
+ }
+ else if (type == SESMAN_SESSION_TYPE_XVNC)
+ {
+ xserver_params = list_create();
+ xserver_params->auto_free = 1;
+
/* these are the must have parameters */
list_add_item(xserver_params, (long)g_strdup("Xvnc"));
list_add_item(xserver_params, (long)g_strdup(screen));
@@ -596,13 +697,14 @@ session_start_fork(int width, int height, int bpp, char *username,
/* make sure it ends with a zero */
list_add_item(xserver_params, 0);
pp1 = (char **)xserver_params->items;
- log_message(LOG_LEVEL_INFO, "Xvnc start:%s", dumpItemsToString(xserver_params, execvpparams, 2048));
+ log_message(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048));
g_execvp("Xvnc", pp1);
}
else if (type == SESMAN_SESSION_TYPE_XRDP)
{
xserver_params = list_create();
xserver_params->auto_free = 1;
+
/* these are the must have parameters */
list_add_item(xserver_params, (long)g_strdup("X11rdp"));
list_add_item(xserver_params, (long)g_strdup(screen));
@@ -619,7 +721,7 @@ session_start_fork(int width, int height, int bpp, char *username,
/* make sure it ends with a zero */
list_add_item(xserver_params, 0);
pp1 = (char **)xserver_params->items;
- log_message(LOG_LEVEL_INFO, "X11rdp start:%s", dumpItemsToString(xserver_params, execvpparams, 2048));
+ log_message(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048));
g_execvp("X11rdp", pp1);
}
else
@@ -693,8 +795,12 @@ session_start_fork(int width, int height, int bpp, char *username,
/*THREAD-FIX release chain lock */
lock_chain_release();
+
+ return display;
}
+ g_free(temp->item);
+ g_free(temp);
return display;
}
@@ -713,7 +819,8 @@ session_reconnect_fork(int display, char *username)
}
else if (pid == 0)
{
- env_set_user(username, 0, display);
+ env_set_user(username, 0, display,
+ g_cfg->session_variables1, g_cfg->session_variables2);
g_snprintf(text, 255, "%s/%s", XRDP_CFG_PATH, "reconnectwm.sh");
if (g_file_exist(text))
@@ -936,6 +1043,7 @@ session_get_bypid(int pid)
"pid %d is null!", pid);
/*THREAD-FIX release chain lock */
lock_chain_release();
+ g_free(dummy);
return 0;
}
@@ -954,6 +1062,7 @@ session_get_bypid(int pid)
/*THREAD-FIX release chain lock */
lock_chain_release();
+ g_free(dummy);
return 0;
}
diff --git a/sesman/session.h b/sesman/session.h
index 4329df12..05e3b3a9 100644
--- a/sesman/session.h
+++ b/sesman/session.h
@@ -30,8 +30,9 @@
#include "libscp_types.h"
-#define SESMAN_SESSION_TYPE_XRDP 1
-#define SESMAN_SESSION_TYPE_XVNC 2
+#define SESMAN_SESSION_TYPE_XRDP 1
+#define SESMAN_SESSION_TYPE_XVNC 2
+#define SESMAN_SESSION_TYPE_XORG 3
#define SESMAN_SESSION_STATUS_ACTIVE 0x01
#define SESMAN_SESSION_STATUS_IDLE 0x02
@@ -90,9 +91,9 @@ struct session_chain
*
*/
struct session_item* DEFAULT_CC
-session_get_bydata(char* name, int width, int height, int bpp, int type);
+session_get_bydata(char* name, int width, int height, int bpp, int type, char *client_ip);
#ifndef session_find_item
- #define session_find_item(a, b, c, d, e) session_get_bydata(a, b, c, d, e);
+ #define session_find_item(a, b, c, d, e, f) session_get_bydata(a, b, c, d, e, f);
#endif
/**
diff --git a/sesman/sig.c b/sesman/sig.c
index 7bb881ce..72892fb2 100644
--- a/sesman/sig.c
+++ b/sesman/sig.c
@@ -86,6 +86,7 @@ sig_sesman_reload_cfg(int sig)
if (config_read(cfg) != 0)
{
log_message(LOG_LEVEL_ERROR, "error reading config - keeping old cfg");
+ g_free(cfg);
return;
}
diff --git a/sesman/tools/dis.c b/sesman/tools/dis.c
index adcc3ee0..a21fbac4 100644
--- a/sesman/tools/dis.c
+++ b/sesman/tools/dis.c
@@ -58,7 +58,12 @@ int main(int argc, char **argv)
return 1;
}
- sck = socket(PF_UNIX, SOCK_DGRAM, 0);
+ if ((sck = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0)
+ {
+ printf("socket open error\n");
+ return 1;
+ }
+
len = sizeof(sa);
if (sendto(sck, "sig", 4, 0, (struct sockaddr *)&sa, len) > 0)
diff --git a/sesman/tools/sesadmin.c b/sesman/tools/sesadmin.c
index 25af850b..32789c6d 100644
--- a/sesman/tools/sesadmin.c
+++ b/sesman/tools/sesadmin.c
@@ -107,6 +107,12 @@ int main(int argc, char **argv)
scp_init(&logging);
sock = g_tcp_socket();
+ if (sock < 0)
+ {
+ LOG_DBG("Socket open error, g_tcp_socket() failed\n");
+ return 1;
+ }
+
s = scp_session_create();
c = scp_connection_create(sock);
@@ -179,16 +185,16 @@ void cmndList(struct SCP_CONNECTION *c)
(dsl[idx]).idle_days, (dsl[idx]).idle_hours, (dsl[idx]).idle_minutes, \
(dsl[idx]).conn_year, (dsl[idx]).conn_month, (dsl[idx]).conn_day, (dsl[idx]).conn_hour, (dsl[idx]).conn_minute);
}
-
- if (0 != dsl)
- {
- g_free(dsl);
- }
}
else
{
printf("No sessions.\n");
}
+
+ if (0 != dsl)
+ {
+ g_free(dsl);
+ }
}
void cmndKill(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
diff --git a/sesman/tools/sesrun.c b/sesman/tools/sesrun.c
index 7ac10102..a9181583 100644
--- a/sesman/tools/sesrun.c
+++ b/sesman/tools/sesrun.c
@@ -75,7 +75,10 @@ main(int argc, char **argv)
init_stream(in_s, 8192);
make_stream(out_s);
init_stream(out_s, 8192);
+
sck = g_tcp_socket();
+ if (sck < 0)
+ return 1;
if (g_tcp_connect(sck, argv[1], g_cfg.listen_port) == 0)
{
diff --git a/sesman/tools/sestest.c b/sesman/tools/sestest.c
index f2823eb6..d42b31de 100644
--- a/sesman/tools/sestest.c
+++ b/sesman/tools/sestest.c
@@ -38,6 +38,9 @@ int main(int argc, char **argv)
scp_init(&log);
sock = g_tcp_socket();
+ if (sock < 0)
+ return 1;
+
s = scp_session_create();
c = scp_connection_create(sock);
diff --git a/sesman/verify_user_pam.c b/sesman/verify_user_pam.c
index 4d73f85d..eec12c66 100644
--- a/sesman/verify_user_pam.c
+++ b/sesman/verify_user_pam.c
@@ -122,6 +122,7 @@ auth_userpass(char *user, char *pass, int *errorcode)
*errorcode = error ;
}
g_printf("pam_start failed: %s\r\n", pam_strerror(auth_info->ph, error));
+ pam_end(auth_info->ph, error);
g_free(auth_info);
return 0;
}
@@ -135,6 +136,7 @@ auth_userpass(char *user, char *pass, int *errorcode)
}
g_printf("pam_authenticate failed: %s\r\n",
pam_strerror(auth_info->ph, error));
+ pam_end(auth_info->ph, error);
g_free(auth_info);
return 0;
}
@@ -153,6 +155,7 @@ auth_userpass(char *user, char *pass, int *errorcode)
}
g_printf("pam_acct_mgmt failed: %s\r\n",
pam_strerror(auth_info->ph, error));
+ pam_end(auth_info->ph, error);
g_free(auth_info);
return 0;
}