Merge pull request #1298 from jaroslaw-osmanski/restrict-outbound-clipboard
Restrict outbound clipboard
This commit is contained in:
commit
ec05d4208d
@ -196,6 +196,12 @@ login for all users is enabled.
|
||||
\fIThis option is currently ignored!\fR Only members of this group can
|
||||
have session management rights.
|
||||
|
||||
.TP
|
||||
\fBRestrictOutboundClipboard\fR=\fI[true|false]\fR
|
||||
If set to \fB1\fR, \fBtrue\fR or \fByes\fR, will restrict the clipboard
|
||||
outbound from the server, to prevent data copied inside the xrdp session
|
||||
to be be pasted in the client host. Default value is \fBfalse\fR.
|
||||
|
||||
.TP
|
||||
\fBAlwaysGroupCheck\fR=\fI[true|false]\fR
|
||||
If set to \fB1\fR, \fBtrue\fR or \fByes\fR, require group membership even
|
||||
|
@ -59,6 +59,7 @@ int g_cliprdr_chan_id = -1; /* cliprdr */
|
||||
int g_rdpsnd_chan_id = -1; /* rdpsnd */
|
||||
int g_rdpdr_chan_id = -1; /* rdpdr */
|
||||
int g_rail_chan_id = -1; /* rail */
|
||||
int g_restrict_outbound_clipboard = 0;
|
||||
|
||||
char *g_exec_name;
|
||||
tbus g_exec_event;
|
||||
@ -1780,7 +1781,7 @@ main(int argc, char **argv)
|
||||
enum logReturns error;
|
||||
struct log_config logconfig;
|
||||
enum logLevels log_level;
|
||||
|
||||
char *restrict_outbound_clipboard_env;
|
||||
g_init("xrdp-chansrv"); /* os_calls */
|
||||
|
||||
log_path[255] = 0;
|
||||
@ -1791,6 +1792,15 @@ main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
restrict_outbound_clipboard_env = g_getenv("CHANSRV_RESTRICT_OUTBOUND_CLIPBOARD");
|
||||
if (restrict_outbound_clipboard_env != 0)
|
||||
{
|
||||
if (g_strcmp(restrict_outbound_clipboard_env, "1") == 0)
|
||||
{
|
||||
g_restrict_outbound_clipboard = 1;
|
||||
}
|
||||
}
|
||||
|
||||
read_ini();
|
||||
pid = g_getpid();
|
||||
display_text = g_getenv("DISPLAY");
|
||||
|
@ -185,38 +185,38 @@ x-special/gnome-copied-files
|
||||
#define LOG_LEVEL LOG_ERROR
|
||||
|
||||
#define log_error(_params...) \
|
||||
{ \
|
||||
g_write("[%10.10u]: CLIPBOARD %s: %d : ERROR: ", \
|
||||
g_time3(), __func__, __LINE__); \
|
||||
g_writeln (_params); \
|
||||
}
|
||||
{ \
|
||||
g_write("[%10.10u]: CLIPBOARD %s: %d : ERROR: ", \
|
||||
g_time3(), __func__, __LINE__); \
|
||||
g_writeln (_params); \
|
||||
}
|
||||
|
||||
#define log_always(_params...) \
|
||||
{ \
|
||||
g_write("[%10.10u]: CLIPBOARD %s: %d : ALWAYS: ", \
|
||||
g_time3(), __func__, __LINE__); \
|
||||
g_writeln (_params); \
|
||||
}
|
||||
{ \
|
||||
g_write("[%10.10u]: CLIPBOARD %s: %d : ALWAYS: ", \
|
||||
g_time3(), __func__, __LINE__); \
|
||||
g_writeln (_params); \
|
||||
}
|
||||
|
||||
#define log_info(_params...) \
|
||||
{ \
|
||||
if (LOG_INFO <= LOG_LEVEL) \
|
||||
{ \
|
||||
g_write("[%10.10u]: CLIPBOARD %s: %d : ", \
|
||||
g_time3(), __func__, __LINE__); \
|
||||
g_writeln (_params); \
|
||||
} \
|
||||
}
|
||||
{ \
|
||||
if (LOG_INFO <= LOG_LEVEL) \
|
||||
{ \
|
||||
g_write("[%10.10u]: CLIPBOARD %s: %d : ", \
|
||||
g_time3(), __func__, __LINE__); \
|
||||
g_writeln (_params); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define log_debug(_params...) \
|
||||
{ \
|
||||
if (LOG_DEBUG <= LOG_LEVEL) \
|
||||
{ \
|
||||
g_write("[%10.10u]: CLIPBOARD %s: %d : ", \
|
||||
g_time3(), __func__, __LINE__); \
|
||||
g_writeln (_params); \
|
||||
} \
|
||||
}
|
||||
{ \
|
||||
if (LOG_DEBUG <= LOG_LEVEL) \
|
||||
{ \
|
||||
g_write("[%10.10u]: CLIPBOARD %s: %d : ", \
|
||||
g_time3(), __func__, __LINE__); \
|
||||
g_writeln (_params); \
|
||||
} \
|
||||
}
|
||||
|
||||
static char g_bmp_image_header[] =
|
||||
{
|
||||
@ -235,6 +235,8 @@ extern tbus g_x_wait_obj; /* in xcommon.c */
|
||||
extern Screen *g_screen; /* in xcommon.c */
|
||||
extern int g_screen_num; /* in xcommon.c */
|
||||
|
||||
extern int g_restrict_outbound_clipboard; /* in chansrv.c */
|
||||
|
||||
int g_clip_up = 0;
|
||||
|
||||
static Atom g_clipboard_atom = 0; /* CLIPBOARD */
|
||||
@ -286,10 +288,10 @@ static int g_file_format_id = -1;
|
||||
static char g_last_atom_name[256] = "";
|
||||
|
||||
/*****************************************************************************/
|
||||
static char*
|
||||
static char *
|
||||
get_atom_text(Atom atom)
|
||||
{
|
||||
char* name;
|
||||
char *name;
|
||||
int failed;
|
||||
|
||||
failed = 0;
|
||||
@ -405,10 +407,10 @@ clipboard_init(void)
|
||||
if (rv == 0)
|
||||
{
|
||||
log_debug("clipboard_init: g_xfixes_event_base %d",
|
||||
g_xfixes_event_base);
|
||||
g_xfixes_event_base);
|
||||
st = XFixesQueryVersion(g_display, &ver_maj, &ver_min);
|
||||
log_debug("clipboard_init st %d, maj %d min %d", st,
|
||||
ver_maj, ver_min);
|
||||
ver_maj, ver_min);
|
||||
g_clip_property_atom = XInternAtom(g_display, "XRDP_CLIP_PROPERTY_ATOM",
|
||||
False);
|
||||
g_get_time_atom = XInternAtom(g_display, "XRDP_GET_TIME_ATOM",
|
||||
@ -428,7 +430,7 @@ clipboard_init(void)
|
||||
if (g_image_bmp_atom == None)
|
||||
{
|
||||
log_error("clipboard_init: g_image_bmp_atom was "
|
||||
"not allocated");
|
||||
"not allocated");
|
||||
}
|
||||
|
||||
g_wnd = XCreateSimpleWindow(g_display, RootWindowOfScreen(g_screen),
|
||||
@ -463,12 +465,12 @@ clipboard_init(void)
|
||||
s_mark_end(s);
|
||||
size = (int)(s->end - s->data);
|
||||
log_debug("clipboard_init: data out, sending "
|
||||
"CB_CLIP_CAPS (clip_msg_id = 1)");
|
||||
"CB_CLIP_CAPS (clip_msg_id = 1)");
|
||||
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
|
||||
if (rv != 0)
|
||||
{
|
||||
log_error("clipboard_init: send_channel_data failed "
|
||||
"rv = %d", rv);
|
||||
"rv = %d", rv);
|
||||
rv = 4;
|
||||
}
|
||||
}
|
||||
@ -484,12 +486,12 @@ clipboard_init(void)
|
||||
s_mark_end(s);
|
||||
size = (int)(s->end - s->data);
|
||||
log_debug("clipboard_init: data out, sending "
|
||||
"CB_MONITOR_READY (clip_msg_id = 1)");
|
||||
"CB_MONITOR_READY (clip_msg_id = 1)");
|
||||
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
|
||||
if (rv != 0)
|
||||
{
|
||||
log_error("clipboard_init: send_channel_data failed "
|
||||
"rv = %d", rv);
|
||||
"rv = %d", rv);
|
||||
rv = 4;
|
||||
}
|
||||
}
|
||||
@ -554,7 +556,7 @@ clipboard_send_data_request(int format_id)
|
||||
s_mark_end(s);
|
||||
size = (int)(s->end - s->data);
|
||||
log_debug("clipboard_send_data_request: data out, sending "
|
||||
"CLIPRDR_DATA_REQUEST (clip_msg_id = 4)");
|
||||
"CLIPRDR_DATA_REQUEST (clip_msg_id = 4)");
|
||||
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
|
||||
free_stream(s);
|
||||
return rv;
|
||||
@ -577,7 +579,7 @@ clipboard_send_format_ack(void)
|
||||
s_mark_end(s);
|
||||
size = (int)(s->end - s->data);
|
||||
log_debug("clipboard_send_format_ack: data out, sending "
|
||||
"CLIPRDR_FORMAT_ACK (clip_msg_id = 3)");
|
||||
"CLIPRDR_FORMAT_ACK (clip_msg_id = 3)");
|
||||
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
|
||||
free_stream(s);
|
||||
return rv;
|
||||
@ -715,7 +717,7 @@ clipboard_send_format_announce(int xrdp_clip_type)
|
||||
break;
|
||||
default:
|
||||
log_debug("clipboard_send_format_announce: unknown "
|
||||
"xrdp_clip_type %d", xrdp_clip_type);
|
||||
"xrdp_clip_type %d", xrdp_clip_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -759,7 +761,7 @@ clipboard_send_format_announce(int xrdp_clip_type)
|
||||
break;
|
||||
default:
|
||||
log_debug("clipboard_send_format_announce: unknown "
|
||||
"xrdp_clip_type %d", xrdp_clip_type);
|
||||
"xrdp_clip_type %d", xrdp_clip_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -774,7 +776,7 @@ clipboard_send_format_announce(int xrdp_clip_type)
|
||||
size = (int)(s->end - s->data);
|
||||
//g_hexdump(s->data, size);
|
||||
log_debug("clipboard_send_format_announce: data out, sending "
|
||||
"CLIPRDR_FORMAT_ANNOUNCE (clip_msg_id = 2)");
|
||||
"CLIPRDR_FORMAT_ANNOUNCE (clip_msg_id = 2)");
|
||||
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
|
||||
free_stream(s);
|
||||
return rv;
|
||||
@ -789,7 +791,7 @@ clipboard_send_data_response_for_image(const char *data, int data_size)
|
||||
int rv;
|
||||
|
||||
log_debug("clipboard_send_data_response_for_image: data_size %d",
|
||||
data_size);
|
||||
data_size);
|
||||
make_stream(s);
|
||||
init_stream(s, 64 + data_size);
|
||||
out_uint16_le(s, CB_FORMAT_DATA_RESPONSE); /* 5 CLIPRDR_DATA_RESPONSE */
|
||||
@ -814,17 +816,17 @@ clipboard_send_data_response_for_text(const char *data, int data_size)
|
||||
int num_chars;
|
||||
|
||||
log_debug("clipboard_send_data_response_for_text: data_size %d",
|
||||
data_size);
|
||||
data_size);
|
||||
//g_hexdump(data, data_size);
|
||||
num_chars = g_mbstowcs(0, data, 0);
|
||||
if (num_chars < 0)
|
||||
{
|
||||
log_error("clipboard_send_data_response_for_text: "
|
||||
"bad string");
|
||||
"bad string");
|
||||
num_chars = 0;
|
||||
}
|
||||
log_debug("clipboard_send_data_response_for_text: data_size %d "
|
||||
"num_chars %d", data_size, num_chars);
|
||||
"num_chars %d", data_size, num_chars);
|
||||
make_stream(s);
|
||||
init_stream(s, 64 + num_chars * 2);
|
||||
out_uint16_le(s, CB_FORMAT_DATA_RESPONSE); /* 5 CLIPRDR_DATA_RESPONSE */
|
||||
@ -833,15 +835,15 @@ clipboard_send_data_response_for_text(const char *data, int data_size)
|
||||
if (clipboard_out_unicode(s, data, num_chars) != num_chars * 2)
|
||||
{
|
||||
log_error("clipboard_send_data_response_for_text: error "
|
||||
"clipboard_out_unicode didn't write right number of bytes");
|
||||
"clipboard_out_unicode didn't write right number of bytes");
|
||||
}
|
||||
out_uint16_le(s, 0); /* nil for string */
|
||||
out_uint32_le(s, 0);
|
||||
s_mark_end(s);
|
||||
size = (int)(s->end - s->data);
|
||||
log_debug("clipboard_send_data_response_for_text: data out, "
|
||||
"sending CLIPRDR_DATA_RESPONSE (clip_msg_id = 5) size %d "
|
||||
"num_chars %d", size, num_chars);
|
||||
"sending CLIPRDR_DATA_RESPONSE (clip_msg_id = 5) size %d "
|
||||
"num_chars %d", size, num_chars);
|
||||
rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
|
||||
free_stream(s);
|
||||
return rv;
|
||||
@ -869,7 +871,7 @@ clipboard_send_data_response(int xrdp_clip_type, const char *data, int data_size
|
||||
else
|
||||
{
|
||||
log_debug("clipboard_send_data_response: unknown "
|
||||
"xrdp_clip_type %d", xrdp_clip_type);
|
||||
"xrdp_clip_type %d", xrdp_clip_type);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -908,7 +910,7 @@ clipboard_provide_selection_c2s(XSelectionRequestEvent *req, Atom type)
|
||||
long val1[2];
|
||||
|
||||
log_debug("clipboard_provide_selection_c2s: bytes %d",
|
||||
g_clip_c2s.total_bytes);
|
||||
g_clip_c2s.total_bytes);
|
||||
if (g_clip_c2s.total_bytes < g_incr_max_req_size)
|
||||
{
|
||||
XChangeProperty(g_display, req->requestor, req->property,
|
||||
@ -934,8 +936,8 @@ clipboard_provide_selection_c2s(XSelectionRequestEvent *req, Atom type)
|
||||
g_clip_c2s.property = req->property;
|
||||
g_clip_c2s.window = req->requestor;
|
||||
log_debug("clipboard_provide_selection_c2s: start INCR property %s "
|
||||
"type %s", get_atom_text(req->property),
|
||||
get_atom_text(type));
|
||||
"type %s", get_atom_text(req->property),
|
||||
get_atom_text(type));
|
||||
val1[0] = g_clip_c2s.total_bytes;
|
||||
val1[1] = 0;
|
||||
XChangeProperty(g_display, req->requestor, req->property,
|
||||
@ -1020,7 +1022,7 @@ clipboard_process_format_announce(struct stream *s, int clip_msg_status,
|
||||
char *holdp;
|
||||
|
||||
log_debug("clipboard_process_format_announce: "
|
||||
"CLIPRDR_FORMAT_ANNOUNCE");
|
||||
"CLIPRDR_FORMAT_ANNOUNCE");
|
||||
log_debug("clipboard_process_format_announce %d", clip_msg_len);
|
||||
clipboard_send_format_ack();
|
||||
|
||||
@ -1052,8 +1054,8 @@ clipboard_process_format_announce(struct stream *s, int clip_msg_status,
|
||||
clip_msg_len -= 32;
|
||||
}
|
||||
log_debug("clipboard_process_format_announce: formatId 0x%8.8x "
|
||||
"wszFormatName [%s] clip_msg_len %d", formatId, desc,
|
||||
clip_msg_len);
|
||||
"wszFormatName [%s] clip_msg_len %d", formatId, desc,
|
||||
clip_msg_len);
|
||||
if (g_num_formatIds <= 15)
|
||||
{
|
||||
g_formatIds[g_num_formatIds] = formatId;
|
||||
@ -1073,13 +1075,13 @@ clipboard_process_format_announce(struct stream *s, int clip_msg_status,
|
||||
}
|
||||
|
||||
if ((g_num_formatIds > 0) &&
|
||||
(g_clip_c2s.incr_in_progress == 0) && /* don't interrupt incr */
|
||||
(g_clip_s2c.incr_in_progress == 0))
|
||||
(g_clip_c2s.incr_in_progress == 0) && /* don't interrupt incr */
|
||||
(g_clip_s2c.incr_in_progress == 0))
|
||||
{
|
||||
if (clipboard_set_selection_owner() != 0)
|
||||
{
|
||||
log_error("clipboard_process_format_announce: "
|
||||
"XSetSelectionOwner failed");
|
||||
"XSetSelectionOwner failed");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1130,7 +1132,7 @@ clipboard_process_data_request(struct stream *s, int clip_msg_status,
|
||||
int requestedFormatId;
|
||||
|
||||
log_debug("clipboard_process_data_request: "
|
||||
"CLIPRDR_DATA_REQUEST");
|
||||
"CLIPRDR_DATA_REQUEST");
|
||||
log_debug("clipboard_process_data_request:");
|
||||
log_debug(" %d", g_clip_s2c.xrdp_clip_type);
|
||||
in_uint32_le(s, requestedFormatId);
|
||||
@ -1146,7 +1148,7 @@ clipboard_process_data_request(struct stream *s, int clip_msg_status,
|
||||
else
|
||||
{
|
||||
log_debug("clipboard_process_data_request: CB_FORMAT_FILE, "
|
||||
"calling XConvertSelection to g_utf8_atom");
|
||||
"calling XConvertSelection to g_utf8_atom");
|
||||
g_clip_s2c.xrdp_clip_type = XRDP_CB_FILE;
|
||||
XConvertSelection(g_display, g_clipboard_atom, g_clip_s2c.type,
|
||||
g_clip_property_atom, g_wnd, CurrentTime);
|
||||
@ -1162,7 +1164,7 @@ clipboard_process_data_request(struct stream *s, int clip_msg_status,
|
||||
else
|
||||
{
|
||||
log_debug("clipboard_process_data_request: CB_FORMAT_DIB, "
|
||||
"calling XConvertSelection to g_image_bmp_atom");
|
||||
"calling XConvertSelection to g_image_bmp_atom");
|
||||
g_clip_s2c.xrdp_clip_type = XRDP_CB_BITMAP;
|
||||
XConvertSelection(g_display, g_clipboard_atom, g_image_bmp_atom,
|
||||
g_clip_property_atom, g_wnd, CurrentTime);
|
||||
@ -1178,7 +1180,7 @@ clipboard_process_data_request(struct stream *s, int clip_msg_status,
|
||||
else
|
||||
{
|
||||
log_debug("clipboard_process_data_request: CB_FORMAT_UNICODETEXT, "
|
||||
"calling XConvertSelection to g_utf8_atom");
|
||||
"calling XConvertSelection to g_utf8_atom");
|
||||
g_clip_s2c.xrdp_clip_type = XRDP_CB_TEXT;
|
||||
XConvertSelection(g_display, g_clipboard_atom, g_utf8_atom,
|
||||
g_clip_property_atom, g_wnd, CurrentTime);
|
||||
@ -1186,7 +1188,7 @@ clipboard_process_data_request(struct stream *s, int clip_msg_status,
|
||||
break;
|
||||
default:
|
||||
log_debug("clipboard_process_data_request: unknown type %d",
|
||||
requestedFormatId);
|
||||
requestedFormatId);
|
||||
clipboard_send_data_response_failed();
|
||||
break;
|
||||
}
|
||||
@ -1201,14 +1203,14 @@ clipboard_process_data_request(struct stream *s, int clip_msg_status,
|
||||
clipboard data. */
|
||||
static int
|
||||
clipboard_process_data_response_for_image(struct stream *s,
|
||||
int clip_msg_status,
|
||||
int clip_msg_len)
|
||||
int clip_msg_status,
|
||||
int clip_msg_len)
|
||||
{
|
||||
XSelectionRequestEvent *lxev;
|
||||
int len;
|
||||
|
||||
log_debug("clipboard_process_data_response_for_image: "
|
||||
"CLIPRDR_DATA_RESPONSE_FOR_IMAGE");
|
||||
"CLIPRDR_DATA_RESPONSE_FOR_IMAGE");
|
||||
lxev = &g_saved_selection_req_event;
|
||||
len = (int)(s->end - s->p);
|
||||
if (len < 1)
|
||||
@ -1231,7 +1233,7 @@ clipboard_process_data_response_for_image(struct stream *s,
|
||||
g_memcpy(g_clip_c2s.data, g_bmp_image_header, 14);
|
||||
in_uint8a(s, g_clip_c2s.data + 14, len);
|
||||
log_debug("clipboard_process_data_response_for_image: calling "
|
||||
"clipboard_provide_selection_c2s");
|
||||
"clipboard_provide_selection_c2s");
|
||||
clipboard_provide_selection_c2s(lxev, lxev->target);
|
||||
return 0;
|
||||
}
|
||||
@ -1259,7 +1261,7 @@ clipboard_process_data_response(struct stream *s, int clip_msg_status,
|
||||
if (g_clip_c2s.xrdp_clip_type == XRDP_CB_BITMAP)
|
||||
{
|
||||
clipboard_process_data_response_for_image(s, clip_msg_status,
|
||||
clip_msg_len);
|
||||
clip_msg_len);
|
||||
return 0;
|
||||
}
|
||||
if (g_clip_c2s.xrdp_clip_type == XRDP_CB_FILE)
|
||||
@ -1287,7 +1289,7 @@ clipboard_process_data_response(struct stream *s, int clip_msg_status,
|
||||
return 0;
|
||||
}
|
||||
log_debug("clipboard_process_data_response: "
|
||||
"CLIPRDR_DATA_RESPONSE");
|
||||
"CLIPRDR_DATA_RESPONSE");
|
||||
len = (int)(s->end - s->p);
|
||||
if (len < 1)
|
||||
{
|
||||
@ -1362,10 +1364,10 @@ clipboard_process_clip_caps(struct stream *s, int clip_msg_status,
|
||||
in_uint32_le(s, version); /* version */
|
||||
in_uint32_le(s, flags); /* generalFlags */
|
||||
log_debug("clipboard_process_clip_caps: "
|
||||
"g_cliprdr_version %d version %d "
|
||||
"g_cliprdr_flags 0x%x flags 0x%x",
|
||||
g_cliprdr_version, version,
|
||||
g_cliprdr_flags, flags);
|
||||
"g_cliprdr_version %d version %d "
|
||||
"g_cliprdr_flags 0x%x flags 0x%x",
|
||||
g_cliprdr_version, version,
|
||||
g_cliprdr_flags, flags);
|
||||
if (version < g_cliprdr_version)
|
||||
{
|
||||
g_cliprdr_version = version;
|
||||
@ -1374,7 +1376,7 @@ clipboard_process_clip_caps(struct stream *s, int clip_msg_status,
|
||||
break;
|
||||
default:
|
||||
log_debug("clipboard_process_clip_caps: unknown "
|
||||
"capabilitySetType %d", capabilitySetType);
|
||||
"capabilitySetType %d", capabilitySetType);
|
||||
break;
|
||||
}
|
||||
s->p = holdp + lengthCapability;
|
||||
@ -1552,16 +1554,16 @@ clipboard_data_in(struct stream *s, int chan_id, int chan_flags, int length,
|
||||
if (!g_clip_up)
|
||||
{
|
||||
log_error("aborting clipboard_data_in - clipboard has not "
|
||||
"been initialized");
|
||||
"been initialized");
|
||||
/* we return 0 here to indicate no protocol problem occurred */
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_debug("clipboard_data_in: chan_id %d "
|
||||
"chan_flags 0x%x length %d total_length %d "
|
||||
"in_request %d g_ins->size %d",
|
||||
chan_id, chan_flags, length, total_length,
|
||||
g_clip_c2s.in_request, g_ins->size);
|
||||
"chan_flags 0x%x length %d total_length %d "
|
||||
"in_request %d g_ins->size %d",
|
||||
chan_id, chan_flags, length, total_length,
|
||||
g_clip_c2s.in_request, g_ins->size);
|
||||
|
||||
if (g_clip_c2s.doing_response_ss)
|
||||
{
|
||||
@ -1621,37 +1623,37 @@ clipboard_data_in(struct stream *s, int chan_id, int chan_flags, int length,
|
||||
in_uint32_le(ls, clip_msg_len);
|
||||
|
||||
log_debug("clipboard_data_in: clip_msg_id %d "
|
||||
"clip_msg_status %d clip_msg_len %d",
|
||||
clip_msg_id, clip_msg_status, clip_msg_len);
|
||||
"clip_msg_status %d clip_msg_len %d",
|
||||
clip_msg_id, clip_msg_status, clip_msg_len);
|
||||
rv = 0;
|
||||
|
||||
log_debug("clipboard_data_in: %d", clip_msg_id);
|
||||
switch (clip_msg_id)
|
||||
{
|
||||
/* sent by client or server when its local system clipboard is */
|
||||
/* updated with new clipboard data; contains Clipboard Format ID */
|
||||
/* and name pairs of new Clipboard Formats on the clipboard. */
|
||||
/* sent by client or server when its local system clipboard is */
|
||||
/* updated with new clipboard data; contains Clipboard Format ID */
|
||||
/* and name pairs of new Clipboard Formats on the clipboard. */
|
||||
case CB_FORMAT_LIST: /* 2 CLIPRDR_FORMAT_ANNOUNCE */
|
||||
rv = clipboard_process_format_announce(ls, clip_msg_status,
|
||||
clip_msg_len);
|
||||
break;
|
||||
/* response to CB_FORMAT_LIST; used to indicate whether */
|
||||
/* processing of the Format List PDU was successful */
|
||||
/* response to CB_FORMAT_LIST; used to indicate whether */
|
||||
/* processing of the Format List PDU was successful */
|
||||
case CB_FORMAT_LIST_RESPONSE: /* 3 CLIPRDR_FORMAT_ACK */
|
||||
rv = clipboard_process_format_ack(ls, clip_msg_status,
|
||||
clip_msg_len);
|
||||
break;
|
||||
/* sent by recipient of CB_FORMAT_LIST; used to request data for one */
|
||||
/* of the formats that was listed in CB_FORMAT_LIST */
|
||||
/* sent by recipient of CB_FORMAT_LIST; used to request data for one */
|
||||
/* of the formats that was listed in CB_FORMAT_LIST */
|
||||
case CB_FORMAT_DATA_REQUEST: /* 4 CLIPRDR_DATA_REQUEST */
|
||||
rv = clipboard_process_data_request(ls, clip_msg_status,
|
||||
clip_msg_len);
|
||||
break;
|
||||
/* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate */
|
||||
/* whether processing of the CB_FORMAT_DATA_REQUEST was */
|
||||
/* successful; if processing was successful, */
|
||||
/* CB_FORMAT_DATA_RESPONSE includes contents of requested */
|
||||
/* clipboard data. */
|
||||
/* sent as a reply to CB_FORMAT_DATA_REQUEST; used to indicate */
|
||||
/* whether processing of the CB_FORMAT_DATA_REQUEST was */
|
||||
/* successful; if processing was successful, */
|
||||
/* CB_FORMAT_DATA_RESPONSE includes contents of requested */
|
||||
/* clipboard data. */
|
||||
case CB_FORMAT_DATA_RESPONSE: /* 5 CLIPRDR_DATA_RESPONSE */
|
||||
rv = clipboard_process_data_response(ls, clip_msg_status,
|
||||
clip_msg_len);
|
||||
@ -1671,7 +1673,7 @@ clipboard_data_in(struct stream *s, int chan_id, int chan_flags, int length,
|
||||
default:
|
||||
log_debug("clipboard_data_in: unknown clip_msg_id %d", clip_msg_id);
|
||||
log_error("clipboard_data_in: unknown clip_msg_id %d",
|
||||
clip_msg_id);
|
||||
clip_msg_id);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1703,21 +1705,22 @@ clipboard_event_selection_owner_notify(XEvent *xevent)
|
||||
lxevent = (XFixesSelectionNotifyEvent *)xevent;
|
||||
log_debug("clipboard_event_selection_owner_notify: 0x%lx", lxevent->owner);
|
||||
log_debug("clipboard_event_selection_owner_notify: "
|
||||
"window %ld subtype %d owner %ld g_wnd %ld",
|
||||
lxevent->window, lxevent->subtype, lxevent->owner, g_wnd);
|
||||
"window %ld subtype %d owner %ld g_wnd %ld",
|
||||
lxevent->window, lxevent->subtype, lxevent->owner, g_wnd);
|
||||
|
||||
if (lxevent->owner == g_wnd)
|
||||
{
|
||||
log_debug("clipboard_event_selection_owner_notify: matches g_wnd");
|
||||
log_debug("clipboard_event_selection_owner_notify: skipping, "
|
||||
"owner == g_wnd");
|
||||
"owner == g_wnd");
|
||||
g_got_selection = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_got_selection = 0;
|
||||
if (lxevent->owner != 0) /* nil owner comes when selection */
|
||||
{ /* window is closed */
|
||||
{
|
||||
/* window is closed */
|
||||
XConvertSelection(g_display, g_clipboard_atom, g_targets_atom,
|
||||
g_clip_property_atom, g_wnd, lxevent->timestamp);
|
||||
}
|
||||
@ -1871,22 +1874,22 @@ clipboard_event_selection_notify(XEvent *xevent)
|
||||
if (lxevent->property == None)
|
||||
{
|
||||
log_error("clipboard_event_selection_notify: clip could "
|
||||
"not be converted");
|
||||
"not be converted");
|
||||
rv = 1;
|
||||
}
|
||||
|
||||
if (rv == 0)
|
||||
{
|
||||
log_debug("clipboard_event_selection_notify: wnd 0x%lx prop %s",
|
||||
lxevent->requestor,
|
||||
get_atom_text(lxevent->property));
|
||||
lxevent->requestor,
|
||||
get_atom_text(lxevent->property));
|
||||
rv = clipboard_get_window_property(lxevent->requestor, lxevent->property,
|
||||
&type, &fmt,
|
||||
&n_items, &data, &data_size);
|
||||
if (rv != 0)
|
||||
{
|
||||
log_error("clipboard_event_selection_notify: "
|
||||
"clipboard_get_window_property failed error %d", rv);
|
||||
"clipboard_get_window_property failed error %d", rv);
|
||||
return 0;
|
||||
}
|
||||
//g_hexdump(data, data_size);
|
||||
@ -1896,9 +1899,9 @@ clipboard_event_selection_notify(XEvent *xevent)
|
||||
/* nothing more to do here, the data is coming in through
|
||||
PropertyNotify */
|
||||
log_debug("clipboard_event_selection_notify: type is INCR "
|
||||
"data_size %d property name %s type %s", data_size,
|
||||
get_atom_text(lxevent->property),
|
||||
get_atom_text(lxevent->type));
|
||||
"data_size %d property name %s type %s", data_size,
|
||||
get_atom_text(lxevent->property),
|
||||
get_atom_text(lxevent->type));
|
||||
g_clip_s2c.incr_in_progress = 1;
|
||||
g_clip_s2c.property = lxevent->property;
|
||||
g_clip_s2c.type = lxevent->target;
|
||||
@ -1928,7 +1931,7 @@ clipboard_event_selection_notify(XEvent *xevent)
|
||||
"clipboard_event_selection_notify: 0x%lx %s 0x%lx",
|
||||
atom, get_atom_text(atom), XA_STRING));
|
||||
log_debug("clipboard_event_selection_notify: 0x%lx %s",
|
||||
atom, get_atom_text(atom));
|
||||
atom, get_atom_text(atom));
|
||||
if (atom == g_utf8_atom)
|
||||
{
|
||||
got_utf8 = 1;
|
||||
@ -1955,16 +1958,16 @@ clipboard_event_selection_notify(XEvent *xevent)
|
||||
else
|
||||
{
|
||||
log_error("clipboard_event_selection_notify: error, "
|
||||
"target is 'TARGETS' and type[%ld] or fmt[%d] not right, "
|
||||
"should be type[%ld], fmt[%d]", type, fmt, XA_ATOM, 32);
|
||||
"target is 'TARGETS' and type[%ld] or fmt[%d] not right, "
|
||||
"should be type[%ld], fmt[%d]", type, fmt, XA_ATOM, 32);
|
||||
}
|
||||
}
|
||||
else if (lxevent->target == g_utf8_atom)
|
||||
{
|
||||
log_debug("clipboard_event_selection_notify: UTF8_STRING "
|
||||
"data_size %d", data_size);
|
||||
"data_size %d", data_size);
|
||||
log_debug("clipboard_event_selection_notify: UTF8_STRING "
|
||||
"data_size %d", data_size);
|
||||
"data_size %d", data_size);
|
||||
if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0))
|
||||
{
|
||||
g_free(g_clip_s2c.data);
|
||||
@ -1987,9 +1990,9 @@ clipboard_event_selection_notify(XEvent *xevent)
|
||||
else if (lxevent->target == XA_STRING)
|
||||
{
|
||||
log_debug("clipboard_event_selection_notify: XA_STRING "
|
||||
"data_size %d", data_size);
|
||||
"data_size %d", data_size);
|
||||
log_debug("clipboard_event_selection_notify: XA_STRING "
|
||||
"data_size %d", data_size);
|
||||
"data_size %d", data_size);
|
||||
if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0))
|
||||
{
|
||||
g_free(g_clip_s2c.data);
|
||||
@ -2004,9 +2007,9 @@ clipboard_event_selection_notify(XEvent *xevent)
|
||||
else if (lxevent->target == g_image_bmp_atom)
|
||||
{
|
||||
log_debug("clipboard_event_selection_notify: image/bmp "
|
||||
"data_size %d", data_size);
|
||||
"data_size %d", data_size);
|
||||
log_debug("clipboard_event_selection_notify: image/bmp "
|
||||
"data_size %d", data_size);
|
||||
"data_size %d", data_size);
|
||||
if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 14))
|
||||
{
|
||||
g_free(g_clip_s2c.data);
|
||||
@ -2020,9 +2023,9 @@ clipboard_event_selection_notify(XEvent *xevent)
|
||||
else if (lxevent->target == g_file_atom1)
|
||||
{
|
||||
log_debug("clipboard_event_selection_notify: text/uri-list "
|
||||
"data_size %d", data_size);
|
||||
"data_size %d", data_size);
|
||||
log_debug("clipboard_event_selection_notify: text/uri-list "
|
||||
"data_size %d", data_size);
|
||||
"data_size %d", data_size);
|
||||
if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0))
|
||||
{
|
||||
g_free(g_clip_s2c.data);
|
||||
@ -2037,9 +2040,9 @@ clipboard_event_selection_notify(XEvent *xevent)
|
||||
else if (lxevent->target == g_file_atom2)
|
||||
{
|
||||
log_debug("clipboard_event_selection_notify: text/uri-list "
|
||||
"data_size %d", data_size);
|
||||
"data_size %d", data_size);
|
||||
log_debug("clipboard_event_selection_notify: text/uri-list "
|
||||
"data_size %d", data_size);
|
||||
"data_size %d", data_size);
|
||||
if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0))
|
||||
{
|
||||
g_free(g_clip_s2c.data);
|
||||
@ -2054,13 +2057,13 @@ clipboard_event_selection_notify(XEvent *xevent)
|
||||
else
|
||||
{
|
||||
log_error("clipboard_event_selection_notify: "
|
||||
"unknown target");
|
||||
"unknown target");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error("clipboard_event_selection_notify: "
|
||||
"unknown selection");
|
||||
"unknown selection");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2145,24 +2148,24 @@ clipboard_event_selection_request(XEvent *xevent)
|
||||
lxev = (XSelectionRequestEvent *)xevent;
|
||||
log_debug("clipboard_event_selection_request: 0x%lx", lxev->property);
|
||||
log_debug("clipboard_event_selection_request: g_wnd %ld, "
|
||||
".requestor %ld .owner %ld .selection %ld '%s' .target %ld .property %ld",
|
||||
g_wnd, lxev->requestor, lxev->owner, lxev->selection,
|
||||
get_atom_text(lxev->selection),
|
||||
lxev->target, lxev->property);
|
||||
".requestor %ld .owner %ld .selection %ld '%s' .target %ld .property %ld",
|
||||
g_wnd, lxev->requestor, lxev->owner, lxev->selection,
|
||||
get_atom_text(lxev->selection),
|
||||
lxev->target, lxev->property);
|
||||
|
||||
if (lxev->property == None)
|
||||
{
|
||||
log_debug("clipboard_event_selection_request: lxev->property "
|
||||
"is None");
|
||||
"is None");
|
||||
log_debug("clipboard_event_selection_request: "
|
||||
"lxev->property is None");
|
||||
"lxev->property is None");
|
||||
}
|
||||
else if (lxev->target == g_targets_atom)
|
||||
{
|
||||
log_debug("clipboard_event_selection_request: g_targets_atom");
|
||||
/* requestor is asking what the selection can be converted to */
|
||||
log_debug("clipboard_event_selection_request: "
|
||||
"g_targets_atom");
|
||||
"g_targets_atom");
|
||||
atom_buf[0] = g_targets_atom;
|
||||
atom_buf[1] = g_timestamp_atom;
|
||||
atom_buf[2] = g_multiple_atom;
|
||||
@ -2193,7 +2196,7 @@ clipboard_event_selection_request(XEvent *xevent)
|
||||
{
|
||||
/* requestor is asking the time I got the selection */
|
||||
log_debug("clipboard_event_selection_request: "
|
||||
"g_timestamp_atom");
|
||||
"g_timestamp_atom");
|
||||
atom_buf[0] = g_selection_time;
|
||||
atom_buf[1] = 0;
|
||||
return clipboard_provide_selection(lxev, XA_INTEGER, 32,
|
||||
@ -2203,7 +2206,7 @@ clipboard_event_selection_request(XEvent *xevent)
|
||||
{
|
||||
/* target, property pairs */
|
||||
log_debug("clipboard_event_selection_request: "
|
||||
"g_multiple_atom");
|
||||
"g_multiple_atom");
|
||||
|
||||
xdata = 0;
|
||||
if (clipboard_get_window_property(lxev->requestor, lxev->property,
|
||||
@ -2211,7 +2214,7 @@ clipboard_event_selection_request(XEvent *xevent)
|
||||
&xdata_size) == 0)
|
||||
{
|
||||
log_debug("clipboard_event_selection_request: g_multiple_atom "
|
||||
"n_items %d", n_items);
|
||||
"n_items %d", n_items);
|
||||
/* todo */
|
||||
g_free(xdata);
|
||||
}
|
||||
@ -2276,7 +2279,7 @@ clipboard_event_selection_request(XEvent *xevent)
|
||||
else
|
||||
{
|
||||
log_debug("clipboard_event_selection_request: unknown "
|
||||
"target %s", get_atom_text(lxev->target));
|
||||
"target %s", get_atom_text(lxev->target));
|
||||
LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_request: unknown "
|
||||
"target %s", get_atom_text(lxev->target)));
|
||||
}
|
||||
@ -2332,9 +2335,9 @@ clipboard_event_property_notify(XEvent *xevent)
|
||||
|
||||
log_debug("clipboard_event_property_notify:");
|
||||
log_debug("clipboard_event_property_notify: PropertyNotify .window %ld "
|
||||
".state %d .atom %ld %s", xevent->xproperty.window,
|
||||
xevent->xproperty.state, xevent->xproperty.atom,
|
||||
get_atom_text(xevent->xproperty.atom));
|
||||
".state %d .atom %ld %s", xevent->xproperty.window,
|
||||
xevent->xproperty.state, xevent->xproperty.atom,
|
||||
get_atom_text(xevent->xproperty.atom));
|
||||
|
||||
if (g_clip_c2s.incr_in_progress &&
|
||||
(xevent->xproperty.window == g_clip_c2s.window) &&
|
||||
@ -2353,7 +2356,7 @@ clipboard_event_property_notify(XEvent *xevent)
|
||||
data = (tui8 *)(g_clip_c2s.data + g_clip_c2s.incr_bytes_done);
|
||||
data_bytes = g_clip_c2s.read_bytes_done - g_clip_c2s.incr_bytes_done;
|
||||
if ((data_bytes < 1) &&
|
||||
(g_clip_c2s.read_bytes_done < g_clip_c2s.total_bytes))
|
||||
(g_clip_c2s.read_bytes_done < g_clip_c2s.total_bytes))
|
||||
{
|
||||
g_clip_c2s.incr_in_progress = 0;
|
||||
return 0;
|
||||
@ -2423,7 +2426,7 @@ clipboard_event_property_notify(XEvent *xevent)
|
||||
else
|
||||
{
|
||||
log_error("clipboard_event_property_notify: error unknown type %ld",
|
||||
g_clip_s2c.type);
|
||||
g_clip_s2c.type);
|
||||
clipboard_send_data_response_failed();
|
||||
}
|
||||
|
||||
@ -2484,6 +2487,8 @@ clipboard_xevent(void *xevent)
|
||||
{
|
||||
XEvent *lxevent;
|
||||
|
||||
log_debug("clipboard_xevent: event detected");
|
||||
|
||||
if (!g_clip_up)
|
||||
{
|
||||
return 1;
|
||||
@ -2494,7 +2499,15 @@ clipboard_xevent(void *xevent)
|
||||
switch (lxevent->type)
|
||||
{
|
||||
case SelectionNotify:
|
||||
clipboard_event_selection_notify(lxevent);
|
||||
if (g_restrict_outbound_clipboard == 0)
|
||||
{
|
||||
clipboard_event_selection_notify(lxevent);
|
||||
}
|
||||
else
|
||||
{
|
||||
log_debug("outbound clipboard is restricted because of config");
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case SelectionRequest:
|
||||
clipboard_event_selection_request(lxevent);
|
||||
|
@ -235,6 +235,7 @@ config_read_security(int file, struct config_security *sc,
|
||||
sc->login_retry = 3;
|
||||
sc->ts_users_enable = 0;
|
||||
sc->ts_admins_enable = 0;
|
||||
sc->restrict_outbound_clipboard = 0;
|
||||
|
||||
file_read_section(file, SESMAN_CFG_SECURITY, param_n, param_v);
|
||||
|
||||
@ -273,6 +274,12 @@ config_read_security(int file, struct config_security *sc,
|
||||
{
|
||||
sc->ts_always_group_check = g_text2bool((char *)list_get_item(param_v, i));
|
||||
}
|
||||
|
||||
if (0 == g_strcasecmp(buf, SESMAN_CFG_SEC_RESTRICT_OUTBOUND_CLIPBOARD))
|
||||
{
|
||||
sc->restrict_outbound_clipboard = g_text2bool((char *)list_get_item(param_v, i));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -481,7 +488,7 @@ config_dump(struct config_sesman *config)
|
||||
g_writeln(" DefaultWindowManager: %s", config->default_wm);
|
||||
g_writeln(" ReconnectScript: %s", config->reconnect_sh);
|
||||
g_writeln(" AuthFilePath: %s",
|
||||
((config->auth_file_path) ? (config->auth_file_path) : ("disabled")));
|
||||
((config->auth_file_path) ? (config->auth_file_path) : ("disabled")));
|
||||
|
||||
/* Session configuration */
|
||||
g_writeln("Session configuration:");
|
||||
@ -497,6 +504,7 @@ config_dump(struct config_sesman *config)
|
||||
g_writeln(" AllowRootLogin: %d", sc->allow_root);
|
||||
g_writeln(" MaxLoginRetry: %d", sc->login_retry);
|
||||
g_writeln(" AlwaysGroupCheck: %d", sc->ts_always_group_check);
|
||||
g_writeln(" RestrictOutboundClipboard: %d", sc->restrict_outbound_clipboard);
|
||||
|
||||
g_printf( " TSUsersGroup: ");
|
||||
if (sc->ts_users_enable)
|
||||
@ -530,7 +538,7 @@ config_dump(struct config_sesman *config)
|
||||
for (i = 0; i < config->xorg_params->count; i++)
|
||||
{
|
||||
g_writeln(" Parameter %02d %s",
|
||||
i, (char *) list_get_item(config->xorg_params, i));
|
||||
i, (char *) list_get_item(config->xorg_params, i));
|
||||
}
|
||||
|
||||
/* Xvnc */
|
||||
@ -542,7 +550,7 @@ config_dump(struct config_sesman *config)
|
||||
for (i = 0; i < config->vnc_params->count; i++)
|
||||
{
|
||||
g_writeln(" Parameter %02d %s",
|
||||
i, (char *)list_get_item(config->vnc_params, i));
|
||||
i, (char *)list_get_item(config->vnc_params, i));
|
||||
}
|
||||
|
||||
/* X11rdp */
|
||||
@ -554,7 +562,7 @@ config_dump(struct config_sesman *config)
|
||||
for (i = 0; i < config->rdp_params->count; i++)
|
||||
{
|
||||
g_writeln(" Parameter %02d %s",
|
||||
i, (char *)list_get_item(config->rdp_params, i));
|
||||
i, (char *)list_get_item(config->rdp_params, i));
|
||||
}
|
||||
|
||||
/* SessionVariables */
|
||||
@ -567,7 +575,7 @@ config_dump(struct config_sesman *config)
|
||||
{
|
||||
g_writeln(" Parameter %02d %s=%s",
|
||||
i, (char *) list_get_item(config->env_names, i),
|
||||
(char *) list_get_item(config->env_values, i));
|
||||
(char *) list_get_item(config->env_values, i));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,12 +54,13 @@
|
||||
#define SESMAN_CFG_LOG_ENABLE_SYSLOG "EnableSyslog"
|
||||
#define SESMAN_CFG_LOG_SYSLOG_LEVEL "SyslogLevel"
|
||||
*/
|
||||
#define SESMAN_CFG_SECURITY "Security"
|
||||
#define SESMAN_CFG_SEC_LOGIN_RETRY "MaxLoginRetry"
|
||||
#define SESMAN_CFG_SEC_ALLOW_ROOT "AllowRootLogin"
|
||||
#define SESMAN_CFG_SEC_USR_GROUP "TerminalServerUsers"
|
||||
#define SESMAN_CFG_SEC_ADM_GROUP "TerminalServerAdmins"
|
||||
#define SESMAN_CFG_SEC_ALWAYSGROUPCHECK "AlwaysGroupCheck"
|
||||
#define SESMAN_CFG_SECURITY "Security"
|
||||
#define SESMAN_CFG_SEC_LOGIN_RETRY "MaxLoginRetry"
|
||||
#define SESMAN_CFG_SEC_ALLOW_ROOT "AllowRootLogin"
|
||||
#define SESMAN_CFG_SEC_USR_GROUP "TerminalServerUsers"
|
||||
#define SESMAN_CFG_SEC_ADM_GROUP "TerminalServerAdmins"
|
||||
#define SESMAN_CFG_SEC_ALWAYSGROUPCHECK "AlwaysGroupCheck"
|
||||
#define SESMAN_CFG_SEC_RESTRICT_OUTBOUND_CLIPBOARD "RestrictOutboundClipboard"
|
||||
|
||||
#define SESMAN_CFG_SESSIONS "Sessions"
|
||||
#define SESMAN_CFG_SESS_MAX "MaxSessions"
|
||||
@ -126,6 +127,11 @@ struct config_security
|
||||
* @brief if the Groups are not found deny access
|
||||
*/
|
||||
int ts_always_group_check;
|
||||
/**
|
||||
* @var restrict_outbound_clipboard
|
||||
* @brief if the clipboard should be enforced restricted. If true only allow client -> server, not vice versa.
|
||||
*/
|
||||
int restrict_outbound_clipboard;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -19,6 +19,9 @@ TerminalServerAdmins=tsadmins
|
||||
; When AlwaysGroupCheck=false access will be permitted
|
||||
; if the group TerminalServerUsers is not defined.
|
||||
AlwaysGroupCheck=false
|
||||
; When RestrictOutboundClipboard=true clipboard from the
|
||||
; server is not pushed to the client.
|
||||
RestrictOutboundClipboard=false
|
||||
|
||||
[Sessions]
|
||||
;; X11DisplayOffset - x11 display number offset
|
||||
|
@ -374,6 +374,11 @@ session_start_chansrv(char *username, int display)
|
||||
g_cfg->env_names,
|
||||
g_cfg->env_values);
|
||||
|
||||
if (g_cfg->sec.restrict_outbound_clipboard == 1)
|
||||
{
|
||||
g_setenv("CHANSRV_RESTRICT_OUTBOUND_CLIPBOARD", "1", 1);
|
||||
}
|
||||
|
||||
/* executing chansrv */
|
||||
g_execvp(exe_path, (char **) (chansrv_params->items));
|
||||
/* should not get here */
|
||||
|
Loading…
Reference in New Issue
Block a user