chansrv improved config support
This commit is contained in:
parent
f2dda1e0bd
commit
edda1b064d
@ -7,10 +7,11 @@
|
|||||||
|
|
||||||
.SH "DESCRIPTION"
|
.SH "DESCRIPTION"
|
||||||
\fBxrdp\-chansrv\fR is the \fBxrdp\fR(8) channel server, which manages the Remote Desktop Protocol (RDP) sub-channels.
|
\fBxrdp\-chansrv\fR is the \fBxrdp\fR(8) channel server, which manages the Remote Desktop Protocol (RDP) sub-channels.
|
||||||
|
.PP
|
||||||
This program is only forked internally by \fBxrdp\-sesman\fP(8).
|
This program is only forked internally by \fBxrdp\-sesman\fP(8).
|
||||||
.br
|
.PP
|
||||||
Currently \fBxrdp\-chansrv\fP knows about the following channels:
|
Currently \fBxrdp\-chansrv\fP knows about the following channels:
|
||||||
.RE 8
|
.RS 8
|
||||||
.TP
|
.TP
|
||||||
.B cliprdr
|
.B cliprdr
|
||||||
Clipboard Redirection
|
Clipboard Redirection
|
||||||
@ -26,18 +27,55 @@ Remote Applications Integrated Locally
|
|||||||
.TP
|
.TP
|
||||||
.B drdynvc
|
.B drdynvc
|
||||||
Dynamic Virtual Channel
|
Dynamic Virtual Channel
|
||||||
.RS
|
.RE
|
||||||
|
|
||||||
|
.SH ENVIRONMENT
|
||||||
|
.TP
|
||||||
|
.I CHANSRV_LOG_LEVEL
|
||||||
|
Logging level for chansrv. Case-insensitive. Takes one of these string values:
|
||||||
|
.RS 8
|
||||||
|
.TP
|
||||||
|
.B LOG_LEVEL_ALWAYS
|
||||||
|
Only log essential messages
|
||||||
|
.TP
|
||||||
|
.B LOG_LEVEL_ERROR
|
||||||
|
Log errors and above
|
||||||
|
.TP
|
||||||
|
.B LOG_LEVEL_WARNING
|
||||||
|
Log warnings and above
|
||||||
|
.TP
|
||||||
|
.B LOG_LEVEL_INFO
|
||||||
|
Log info and above. This is the default if nothing is specified
|
||||||
|
.TP
|
||||||
|
.B LOG_LEVEL_DEBUG
|
||||||
|
Log debug and above
|
||||||
|
.TP
|
||||||
|
.B LOG_LEVEL_TRACE
|
||||||
|
Log everything
|
||||||
|
.TP
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
|
.I CHANSRV_LOG_PATH
|
||||||
|
Path to the location where the log file is stored. If not specified,
|
||||||
|
$\fBXDG_DATA_HOME/xrdp\fP or \fB$HOME/.local/share/xrdp\fP is used instead.
|
||||||
|
.TP
|
||||||
|
.I DISPLAY
|
||||||
|
X11 display number. Must be specified.
|
||||||
|
|
||||||
.SH FILES
|
.SH FILES
|
||||||
.TP
|
.TP
|
||||||
|
.I @sysconfdir@/xrdp/sesman.ini
|
||||||
|
Contains some settings for this program.
|
||||||
|
.TP
|
||||||
.I @socketdir@/xrdp_chansrv_socket_*
|
.I @socketdir@/xrdp_chansrv_socket_*
|
||||||
UNIX socket used by external programs to implement channels.
|
UNIX socket used by external programs to implement channels.
|
||||||
.TP
|
.TP
|
||||||
.I @socketdir@/xrdp_api_*
|
.I @socketdir@/xrdp_api_*
|
||||||
UNIX socket used by \fBxrdp\-chansrv\fP to communicate with \fBxrdp\-sesman\fP.
|
UNIX socket used by \fBxrdp\-chansrv\fP to communicate with \fBxrdp\-sesman\fP.
|
||||||
.TP
|
.TP
|
||||||
.I $XDG_DATA_HOME/xrdp/xrdp-chansrv.%s.log
|
.I xrdp-chansrv.%s.log
|
||||||
Log file used by \fBxrdp\-chansrv\fP(8). \fB%s\fP is display number.
|
Log file used by \fBxrdp\-chansrv\fP(8). \fB%s\fP is display number. See the
|
||||||
|
description of \fBCHANSRV_LOG_PATH\fP above for the file's location.
|
||||||
|
|
||||||
.SH "SEE ALSO"
|
.SH "SEE ALSO"
|
||||||
.BR xrdp\-sesman (8),
|
.BR xrdp\-sesman (8),
|
||||||
|
@ -51,6 +51,8 @@ xrdp_chansrv_SOURCES = \
|
|||||||
chansrv.h \
|
chansrv.h \
|
||||||
chansrv_common.c \
|
chansrv_common.c \
|
||||||
chansrv_common.h \
|
chansrv_common.h \
|
||||||
|
chansrv_config.c \
|
||||||
|
chansrv_config.h \
|
||||||
chansrv_fuse.c \
|
chansrv_fuse.c \
|
||||||
chansrv_fuse.h \
|
chansrv_fuse.h \
|
||||||
chansrv_xfs.c \
|
chansrv_xfs.c \
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "rail.h"
|
#include "rail.h"
|
||||||
#include "xcommon.h"
|
#include "xcommon.h"
|
||||||
#include "chansrv_fuse.h"
|
#include "chansrv_fuse.h"
|
||||||
|
#include "chansrv_config.h"
|
||||||
#include "xrdp_sockets.h"
|
#include "xrdp_sockets.h"
|
||||||
#include "audin.h"
|
#include "audin.h"
|
||||||
|
|
||||||
@ -57,17 +58,16 @@ static int g_rail_index = -1;
|
|||||||
static tbus g_term_event = 0;
|
static tbus g_term_event = 0;
|
||||||
static tbus g_thread_done_event = 0;
|
static tbus g_thread_done_event = 0;
|
||||||
|
|
||||||
static int g_use_unix_socket = 0;
|
struct config_chansrv *g_cfg = NULL;
|
||||||
|
|
||||||
int g_display_num = 0;
|
int g_display_num = 0;
|
||||||
int g_cliprdr_chan_id = -1; /* cliprdr */
|
int g_cliprdr_chan_id = -1; /* cliprdr */
|
||||||
int g_rdpsnd_chan_id = -1; /* rdpsnd */
|
int g_rdpsnd_chan_id = -1; /* rdpsnd */
|
||||||
int g_rdpdr_chan_id = -1; /* rdpdr */
|
int g_rdpdr_chan_id = -1; /* rdpdr */
|
||||||
int g_rail_chan_id = -1; /* rail */
|
int g_rail_chan_id = -1; /* rail */
|
||||||
int g_restrict_outbound_clipboard = 0;
|
|
||||||
|
|
||||||
char *g_exec_name;
|
char *g_exec_name;
|
||||||
tbus g_exec_event;
|
tbus g_exec_event = 0;
|
||||||
tbus g_exec_mutex;
|
tbus g_exec_mutex;
|
||||||
tbus g_exec_sem;
|
tbus g_exec_sem;
|
||||||
int g_exec_pid = 0;
|
int g_exec_pid = 0;
|
||||||
@ -1244,7 +1244,7 @@ setup_listen(void)
|
|||||||
trans_delete(g_lis_trans);
|
trans_delete(g_lis_trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_use_unix_socket)
|
if (g_cfg->use_unix_socket)
|
||||||
{
|
{
|
||||||
g_lis_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
|
g_lis_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
|
||||||
g_lis_trans->is_term = g_is_term;
|
g_lis_trans->is_term = g_is_term;
|
||||||
@ -1623,52 +1623,23 @@ get_display_num_from_display(char *display_text)
|
|||||||
int
|
int
|
||||||
main_cleanup(void)
|
main_cleanup(void)
|
||||||
{
|
{
|
||||||
g_delete_wait_obj(g_term_event);
|
if (g_term_event != 0)
|
||||||
g_delete_wait_obj(g_thread_done_event);
|
|
||||||
g_delete_wait_obj(g_exec_event);
|
|
||||||
tc_mutex_delete(g_exec_mutex);
|
|
||||||
g_deinit(); /* os_calls */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
static int
|
|
||||||
read_ini(void)
|
|
||||||
{
|
|
||||||
char filename[256];
|
|
||||||
struct list *names;
|
|
||||||
struct list *values;
|
|
||||||
char *name;
|
|
||||||
char *value;
|
|
||||||
int index;
|
|
||||||
|
|
||||||
g_memset(filename, 0, (sizeof(char) * 256));
|
|
||||||
names = list_create();
|
|
||||||
names->auto_free = 1;
|
|
||||||
values = list_create();
|
|
||||||
values->auto_free = 1;
|
|
||||||
g_use_unix_socket = 0;
|
|
||||||
g_snprintf(filename, 255, "%s/sesman.ini", XRDP_CFG_PATH);
|
|
||||||
|
|
||||||
if (file_by_name_read_section(filename, "Globals", names, values) == 0)
|
|
||||||
{
|
{
|
||||||
for (index = 0; index < names->count; index++)
|
g_delete_wait_obj(g_term_event);
|
||||||
{
|
|
||||||
name = (char *)list_get_item(names, index);
|
|
||||||
value = (char *)list_get_item(values, index);
|
|
||||||
|
|
||||||
if (g_strcasecmp(name, "ListenAddress") == 0)
|
|
||||||
{
|
|
||||||
if (g_strcasecmp(value, "127.0.0.1") == 0)
|
|
||||||
{
|
|
||||||
g_use_unix_socket = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (g_thread_done_event != 0)
|
||||||
list_delete(names);
|
{
|
||||||
list_delete(values);
|
g_delete_wait_obj(g_thread_done_event);
|
||||||
|
}
|
||||||
|
if (g_exec_event != 0)
|
||||||
|
{
|
||||||
|
g_delete_wait_obj(g_exec_event);
|
||||||
|
tc_mutex_delete(g_exec_mutex);
|
||||||
|
tc_sem_delete(g_exec_sem);
|
||||||
|
}
|
||||||
|
log_end();
|
||||||
|
config_free(g_cfg);
|
||||||
|
g_deinit(); /* os_calls */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1792,32 +1763,33 @@ main(int argc, char **argv)
|
|||||||
enum logReturns error;
|
enum logReturns error;
|
||||||
struct log_config logconfig;
|
struct log_config logconfig;
|
||||||
enum logLevels log_level;
|
enum logLevels log_level;
|
||||||
char *restrict_outbound_clipboard_env;
|
|
||||||
g_init("xrdp-chansrv"); /* os_calls */
|
g_init("xrdp-chansrv"); /* os_calls */
|
||||||
|
|
||||||
|
|
||||||
log_path[255] = 0;
|
log_path[255] = 0;
|
||||||
if (get_log_path(log_path, 255) != 0)
|
if (get_log_path(log_path, 255) != 0)
|
||||||
{
|
{
|
||||||
g_writeln("error reading CHANSRV_LOG_PATH and HOME environment variable");
|
g_writeln("error reading CHANSRV_LOG_PATH and HOME environment variable");
|
||||||
g_deinit();
|
main_cleanup();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
restrict_outbound_clipboard_env = g_getenv("CHANSRV_RESTRICT_OUTBOUND_CLIPBOARD");
|
/*
|
||||||
if (restrict_outbound_clipboard_env != 0)
|
* The user is unable at present to override the sysadmin-provided
|
||||||
|
* sesman.ini location */
|
||||||
|
if ((g_cfg = config_read(0, XRDP_CFG_PATH "/sesman.ini")) == NULL)
|
||||||
{
|
{
|
||||||
if (g_strcmp(restrict_outbound_clipboard_env, "1") == 0)
|
main_cleanup();
|
||||||
{
|
return 1;
|
||||||
g_restrict_outbound_clipboard = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
config_dump(g_cfg);
|
||||||
|
|
||||||
read_ini();
|
|
||||||
pid = g_getpid();
|
pid = g_getpid();
|
||||||
display_text = g_getenv("DISPLAY");
|
display_text = g_getenv("DISPLAY");
|
||||||
|
if (display_text != NULL)
|
||||||
if (display_text)
|
{
|
||||||
get_display_num_from_display(display_text);
|
get_display_num_from_display(display_text);
|
||||||
|
}
|
||||||
|
|
||||||
log_level = get_log_level(g_getenv("CHANSRV_LOG_LEVEL"), LOG_LEVEL_INFO);
|
log_level = get_log_level(g_getenv("CHANSRV_LOG_LEVEL"), LOG_LEVEL_INFO);
|
||||||
|
|
||||||
@ -1857,7 +1829,7 @@ main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_deinit();
|
main_cleanup();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1877,7 +1849,7 @@ main(int argc, char **argv)
|
|||||||
if (g_display_num == 0)
|
if (g_display_num == 0)
|
||||||
{
|
{
|
||||||
LOGM((LOG_LEVEL_ERROR, "main: error, display is zero"));
|
LOGM((LOG_LEVEL_ERROR, "main: error, display is zero"));
|
||||||
g_deinit();
|
main_cleanup();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1928,7 +1900,6 @@ main(int argc, char **argv)
|
|||||||
/* cleanup */
|
/* cleanup */
|
||||||
main_cleanup();
|
main_cleanup();
|
||||||
LOGM((LOG_LEVEL_INFO, "main: app exiting pid %d(0x%8.8x)", pid, pid));
|
LOGM((LOG_LEVEL_INFO, "main: app exiting pid %d(0x%8.8x)", pid, pid));
|
||||||
g_deinit();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
294
sesman/chansrv/chansrv_config.c
Normal file
294
sesman/chansrv/chansrv_config.c
Normal file
@ -0,0 +1,294 @@
|
|||||||
|
/**
|
||||||
|
* xrdp: A Remote Desktop Protocol server.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* This file implements the interface in chansrv_config.h
|
||||||
|
*/
|
||||||
|
#if defined(HAVE_CONFIG_H)
|
||||||
|
#include <config_ac.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "arch.h"
|
||||||
|
|
||||||
|
#include "list.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "file.h"
|
||||||
|
#include "os_calls.h"
|
||||||
|
|
||||||
|
#include "chansrv_config.h"
|
||||||
|
|
||||||
|
/* Default settings */
|
||||||
|
#define DEFAULT_USE_UNIX_SOCKET 0
|
||||||
|
#define DEFAULT_RESTRICT_OUTBOUND_CLIPBOARD 0
|
||||||
|
#define DEFAULT_FUSE_MOUNT_NAME "xrdp-client"
|
||||||
|
#define DEFAULT_FILE_UMASK 077
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type used for passing a logging function about
|
||||||
|
*/
|
||||||
|
typedef
|
||||||
|
printflike(2, 3)
|
||||||
|
enum logReturns (*log_func_t)(const enum logLevels lvl,
|
||||||
|
const char *msg, ...);
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* @brief Error logging function to use to log to stdout
|
||||||
|
*
|
||||||
|
* Has the same signature as the log_message() function
|
||||||
|
*/
|
||||||
|
static enum logReturns
|
||||||
|
log_to_stdout(const enum logLevels lvl, const char *msg, ...)
|
||||||
|
{
|
||||||
|
char buff[256];
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, msg);
|
||||||
|
vsnprintf(buff, sizeof(buff), msg, ap);
|
||||||
|
va_end(ap);
|
||||||
|
g_writeln("%s", buff);
|
||||||
|
|
||||||
|
return LOG_STARTUP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* Reads the config values we need from the [Globals] section
|
||||||
|
*
|
||||||
|
* @param logmsg Function to use to log messages
|
||||||
|
* @param names List of definitions in the section
|
||||||
|
* @params values List of corresponding values for the names
|
||||||
|
* @params cfg Pointer to structure we're filling in
|
||||||
|
*
|
||||||
|
* @return 0 for success
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
read_config_globals(log_func_t logmsg,
|
||||||
|
struct list *names, struct list *values,
|
||||||
|
struct config_chansrv *cfg)
|
||||||
|
{
|
||||||
|
int error = 0;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
for (index = 0; index < names->count; ++index)
|
||||||
|
{
|
||||||
|
const char *name = (const char *)list_get_item(names, index);
|
||||||
|
const char *value = (const char *)list_get_item(values, index);
|
||||||
|
|
||||||
|
if (g_strcasecmp(name, "ListenAddress") == 0)
|
||||||
|
{
|
||||||
|
if (g_strcasecmp(value, "127.0.0.1") == 0)
|
||||||
|
{
|
||||||
|
cfg->use_unix_socket = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* Reads the config values we need from the [Security] section
|
||||||
|
*
|
||||||
|
* @param logmsg Function to use to log messages
|
||||||
|
* @param names List of definitions in the section
|
||||||
|
* @params values List of corresponding values for the names
|
||||||
|
* @params cfg Pointer to structure we're filling in
|
||||||
|
*
|
||||||
|
* @return 0 for success
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
read_config_security(log_func_t logmsg,
|
||||||
|
struct list *names, struct list *values,
|
||||||
|
struct config_chansrv *cfg)
|
||||||
|
{
|
||||||
|
int error = 0;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
for (index = 0; index < names->count; ++index)
|
||||||
|
{
|
||||||
|
const char *name = (const char *)list_get_item(names, index);
|
||||||
|
const char *value = (const char *)list_get_item(values, index);
|
||||||
|
|
||||||
|
if (g_strcasecmp(name, "RestrictOutboundClipboard") == 0)
|
||||||
|
{
|
||||||
|
cfg->restrict_outbound_clipboard = g_text2bool(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* Reads the config values we need from the [Chansrv] section
|
||||||
|
*
|
||||||
|
* @param logmsg Function to use to log messages
|
||||||
|
* @param names List of definitions in the section
|
||||||
|
* @params values List of corresponding values for the names
|
||||||
|
* @params cfg Pointer to structure we're filling in
|
||||||
|
*
|
||||||
|
* @return 0 for success
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
read_config_chansrv(log_func_t logmsg,
|
||||||
|
struct list *names, struct list *values,
|
||||||
|
struct config_chansrv *cfg)
|
||||||
|
{
|
||||||
|
int error = 0;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
for (index = 0; index < names->count; ++index)
|
||||||
|
{
|
||||||
|
const char *name = (const char *)list_get_item(names, index);
|
||||||
|
const char *value = (const char *)list_get_item(values, index);
|
||||||
|
|
||||||
|
if (g_strcasecmp(name, "FuseMountName") == 0)
|
||||||
|
{
|
||||||
|
g_free(cfg->fuse_mount_name);
|
||||||
|
cfg->fuse_mount_name = g_strdup(value);
|
||||||
|
if (cfg->fuse_mount_name == NULL)
|
||||||
|
{
|
||||||
|
logmsg(LOG_LEVEL_ERROR, "Can't alloc FuseMountName");
|
||||||
|
error = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (g_strcasecmp(name, "FileUmask") == 0)
|
||||||
|
{
|
||||||
|
cfg->file_umask = strtol(value, NULL, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************//**
|
||||||
|
* @brief returns a config block with default values
|
||||||
|
*
|
||||||
|
* @return Block, or NULL for no memory
|
||||||
|
*/
|
||||||
|
static struct config_chansrv *
|
||||||
|
new_config(void)
|
||||||
|
{
|
||||||
|
/* Do all the allocations at the beginning, then check them together */
|
||||||
|
struct config_chansrv *cfg = g_new0(struct config_chansrv, 1);
|
||||||
|
char *fuse_mount_name = g_strdup(DEFAULT_FUSE_MOUNT_NAME);
|
||||||
|
if (cfg == NULL || fuse_mount_name == NULL)
|
||||||
|
{
|
||||||
|
/* At least one memory allocation failed */
|
||||||
|
g_free(fuse_mount_name);
|
||||||
|
g_free(cfg);
|
||||||
|
cfg = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cfg->use_unix_socket = DEFAULT_USE_UNIX_SOCKET;
|
||||||
|
cfg->restrict_outbound_clipboard = DEFAULT_RESTRICT_OUTBOUND_CLIPBOARD;
|
||||||
|
cfg->fuse_mount_name = fuse_mount_name;
|
||||||
|
cfg->file_umask = DEFAULT_FILE_UMASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
struct config_chansrv *
|
||||||
|
config_read(int use_logger, const char *sesman_ini)
|
||||||
|
{
|
||||||
|
int error = 0;
|
||||||
|
struct config_chansrv *cfg = NULL;
|
||||||
|
log_func_t logmsg = (use_logger) ? log_message : log_to_stdout;
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
fd = g_file_open_ex(sesman_ini, 1, 0, 0, 0);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
logmsg(LOG_LEVEL_ERROR, "Can't open config file %s", sesman_ini);
|
||||||
|
error = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((cfg = new_config()) == NULL)
|
||||||
|
{
|
||||||
|
logmsg(LOG_LEVEL_ERROR, "Can't alloc config block");
|
||||||
|
error = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct list *names = list_create();
|
||||||
|
struct list *values = list_create();
|
||||||
|
|
||||||
|
names->auto_free = 1;
|
||||||
|
values->auto_free = 1;
|
||||||
|
|
||||||
|
if (!error && file_read_section(fd, "Globals", names, values) == 0)
|
||||||
|
{
|
||||||
|
error = read_config_globals(logmsg, names, values, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!error && file_read_section(fd, "Security", names, values) == 0)
|
||||||
|
{
|
||||||
|
error = read_config_security(logmsg, names, values, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!error && file_read_section(fd, "Chansrv", names, values) == 0)
|
||||||
|
{
|
||||||
|
error = read_config_chansrv(logmsg, names, values, cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
list_delete(names);
|
||||||
|
list_delete(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_file_close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
config_free(cfg);
|
||||||
|
cfg = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
void
|
||||||
|
config_dump(struct config_chansrv *config)
|
||||||
|
{
|
||||||
|
g_writeln("Global configuration:");
|
||||||
|
g_writeln(" UseUnixSocket (derived): %d", config->use_unix_socket);
|
||||||
|
|
||||||
|
g_writeln("\nSecurity configuration:");
|
||||||
|
g_writeln(" RestrictOutboundClipboard: %d",
|
||||||
|
config->restrict_outbound_clipboard);
|
||||||
|
|
||||||
|
g_writeln("\nChansrv configuration:");
|
||||||
|
g_writeln(" FuseMountName: %s", config->fuse_mount_name);
|
||||||
|
g_writeln(" FileMask: 0%o", config->file_umask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
void
|
||||||
|
config_free(struct config_chansrv *cc)
|
||||||
|
{
|
||||||
|
if (cc != NULL)
|
||||||
|
{
|
||||||
|
g_free(cc->fuse_mount_name);
|
||||||
|
g_free(cc);
|
||||||
|
}
|
||||||
|
}
|
72
sesman/chansrv/chansrv_config.h
Normal file
72
sesman/chansrv/chansrv_config.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
* xrdp: A Remote Desktop Protocol server.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* This file contains the chansrv configuration parameters from sesman.ini
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CHANSRV_CONFIG
|
||||||
|
#define _CHANSRV_CONFIG
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
struct config_chansrv
|
||||||
|
{
|
||||||
|
/** Whether to use a UNIX socket for chansrv */
|
||||||
|
int use_unix_socket;
|
||||||
|
|
||||||
|
/** RestrictOutboundClipboard setting from sesman.ini */
|
||||||
|
int restrict_outbound_clipboard;
|
||||||
|
|
||||||
|
/** * FuseMountName from sesman.ini */
|
||||||
|
char *fuse_mount_name;
|
||||||
|
/** FileUmask from sesman.ini */
|
||||||
|
mode_t file_umask;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Reads sesman configuration
|
||||||
|
* @param use_logger Use logger to log errors (otherwise stdout)
|
||||||
|
* @param sesman_ini Name of configuration file to read
|
||||||
|
*
|
||||||
|
* @return configuration on success, NULL on failure
|
||||||
|
*
|
||||||
|
* @pre logging is assumed to be active
|
||||||
|
* @post pass return value to config_free() to prevent memory leaks
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct config_chansrv *
|
||||||
|
config_read(int use_logger, const char *sesman_ini);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Dumps configuration to stdout
|
||||||
|
* @param pointer to a config_chansrv struct
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
config_dump(struct config_chansrv *config);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @brief Frees configuration allocated by config_read()
|
||||||
|
* @param pointer to a config_chansrv struct (may be NULL)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
config_free(struct config_chansrv *cs);
|
||||||
|
|
||||||
|
#endif /* _CHANSRV_CONFIG */
|
@ -121,6 +121,7 @@ void xfuse_devredir_cb_file_close(struct state_close *fip)
|
|||||||
#include "clipboard_file.h"
|
#include "clipboard_file.h"
|
||||||
#include "chansrv_fuse.h"
|
#include "chansrv_fuse.h"
|
||||||
#include "chansrv_xfs.h"
|
#include "chansrv_xfs.h"
|
||||||
|
#include "chansrv_config.h"
|
||||||
#include "devredir.h"
|
#include "devredir.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
@ -310,8 +311,7 @@ struct req_list_item
|
|||||||
int size;
|
int size;
|
||||||
};
|
};
|
||||||
|
|
||||||
static char g_fuse_mount_name[256] = "xrdp_client";
|
extern struct config_chansrv *g_cfg; /* in chansrv.c */
|
||||||
static mode_t g_umask = 077; /* Umask for files in fs */
|
|
||||||
|
|
||||||
static struct list *g_req_list = 0;
|
static struct list *g_req_list = 0;
|
||||||
static struct xfs_fs *g_xfs; /* an inst of xrdp file system */
|
static struct xfs_fs *g_xfs; /* an inst of xrdp file system */
|
||||||
@ -404,35 +404,6 @@ static char *get_name_for_entry_in_parent(fuse_ino_t parent, const char *name);
|
|||||||
int
|
int
|
||||||
load_fuse_config(void)
|
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);
|
|
||||||
}
|
|
||||||
else if (g_strcasecmp(item, "FileUmask") == 0)
|
|
||||||
{
|
|
||||||
g_umask = strtol(value, NULL, 0);
|
|
||||||
log_info("g_umask set to 0%o", g_umask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
list_delete(items);
|
|
||||||
list_delete(values);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,7 +440,7 @@ xfuse_init(void)
|
|||||||
load_fuse_config();
|
load_fuse_config();
|
||||||
|
|
||||||
/* define FUSE mount point to ~/xrdp_client, ~/thinclient_drives */
|
/* 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_root_path, 255, "%s/%s", g_getenv("HOME"), g_cfg->fuse_mount_name);
|
||||||
g_snprintf(g_fuse_clipboard_path, 255, "%s/.clipboard", g_fuse_root_path);
|
g_snprintf(g_fuse_clipboard_path, 255, "%s/.clipboard", g_fuse_root_path);
|
||||||
|
|
||||||
/* if FUSE mount point does not exist, create it */
|
/* if FUSE mount point does not exist, create it */
|
||||||
@ -1561,7 +1532,7 @@ static int xfuse_dirbuf_add1(fuse_req_t req, struct dirbuf1 *b,
|
|||||||
|
|
||||||
memset(&stbuf, 0, sizeof(stbuf));
|
memset(&stbuf, 0, sizeof(stbuf));
|
||||||
stbuf.st_ino = xinode->inum;
|
stbuf.st_ino = xinode->inum;
|
||||||
stbuf.st_mode = xinode->mode & ~g_umask;
|
stbuf.st_mode = xinode->mode & ~g_cfg->file_umask;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to add the entry. From the docs for fuse_add_direntry():-
|
* Try to add the entry. From the docs for fuse_add_direntry():-
|
||||||
@ -2453,7 +2424,7 @@ static void xfs_inode_to_fuse_entry_param(const XFS_INODE *xinode,
|
|||||||
e->attr_timeout = XFUSE_ATTR_TIMEOUT;
|
e->attr_timeout = XFUSE_ATTR_TIMEOUT;
|
||||||
e->entry_timeout = XFUSE_ENTRY_TIMEOUT;
|
e->entry_timeout = XFUSE_ENTRY_TIMEOUT;
|
||||||
e->attr.st_ino = xinode->inum;
|
e->attr.st_ino = xinode->inum;
|
||||||
e->attr.st_mode = xinode->mode & ~g_umask;
|
e->attr.st_mode = xinode->mode & ~g_cfg->file_umask;
|
||||||
e->attr.st_nlink = 1;
|
e->attr.st_nlink = 1;
|
||||||
e->attr.st_uid = xinode->uid;
|
e->attr.st_uid = xinode->uid;
|
||||||
e->attr.st_gid = xinode->gid;
|
e->attr.st_gid = xinode->gid;
|
||||||
@ -2477,7 +2448,7 @@ static void make_fuse_attr_reply(fuse_req_t req, const XFS_INODE *xinode)
|
|||||||
|
|
||||||
memset(&st, 0, sizeof(st));
|
memset(&st, 0, sizeof(st));
|
||||||
st.st_ino = xinode->inum;
|
st.st_ino = xinode->inum;
|
||||||
st.st_mode = xinode->mode & ~g_umask;
|
st.st_mode = xinode->mode & ~g_cfg->file_umask;
|
||||||
st.st_nlink = 1;
|
st.st_nlink = 1;
|
||||||
st.st_uid = xinode->uid;
|
st.st_uid = xinode->uid;
|
||||||
st.st_gid = xinode->gid;
|
st.st_gid = xinode->gid;
|
||||||
|
@ -170,6 +170,7 @@ x-special/gnome-copied-files
|
|||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
#include "os_calls.h"
|
#include "os_calls.h"
|
||||||
#include "chansrv.h"
|
#include "chansrv.h"
|
||||||
|
#include "chansrv_config.h"
|
||||||
#include "clipboard.h"
|
#include "clipboard.h"
|
||||||
#include "clipboard_file.h"
|
#include "clipboard_file.h"
|
||||||
#include "clipboard_common.h"
|
#include "clipboard_common.h"
|
||||||
@ -235,7 +236,7 @@ extern tbus g_x_wait_obj; /* in xcommon.c */
|
|||||||
extern Screen *g_screen; /* in xcommon.c */
|
extern Screen *g_screen; /* in xcommon.c */
|
||||||
extern int g_screen_num; /* in xcommon.c */
|
extern int g_screen_num; /* in xcommon.c */
|
||||||
|
|
||||||
extern int g_restrict_outbound_clipboard; /* in chansrv.c */
|
extern struct config_chansrv *g_cfg; /* in chansrv.c */
|
||||||
|
|
||||||
int g_clip_up = 0;
|
int g_clip_up = 0;
|
||||||
|
|
||||||
@ -2499,7 +2500,7 @@ clipboard_xevent(void *xevent)
|
|||||||
switch (lxevent->type)
|
switch (lxevent->type)
|
||||||
{
|
{
|
||||||
case SelectionNotify:
|
case SelectionNotify:
|
||||||
if (g_restrict_outbound_clipboard == 0)
|
if (g_cfg->restrict_outbound_clipboard == 0)
|
||||||
{
|
{
|
||||||
clipboard_event_selection_notify(lxevent);
|
clipboard_event_selection_notify(lxevent);
|
||||||
}
|
}
|
||||||
|
@ -371,11 +371,6 @@ session_start_chansrv(char *username, int display)
|
|||||||
g_cfg->env_names,
|
g_cfg->env_names,
|
||||||
g_cfg->env_values);
|
g_cfg->env_values);
|
||||||
|
|
||||||
if (g_cfg->sec.restrict_outbound_clipboard == 1)
|
|
||||||
{
|
|
||||||
g_setenv("CHANSRV_RESTRICT_OUTBOUND_CLIPBOARD", "1", 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* executing chansrv */
|
/* executing chansrv */
|
||||||
g_execvp(exe_path, (char **) (chansrv_params->items));
|
g_execvp(exe_path, (char **) (chansrv_params->items));
|
||||||
/* should not get here */
|
/* should not get here */
|
||||||
|
Loading…
Reference in New Issue
Block a user