drdynvc: Change channel processing to use streams
The channel processor in xrdp_channel.c for dynamic streams uses a data pointer and a length for passing PDUs or PDU fragments. We replace this with a standard stream pointer, so that the usual facilities can be used for checking length violcations.
This commit is contained in:
+3
-3
@@ -146,9 +146,9 @@ struct xrdp_drdynvc
|
||||
int (*open_response)(struct xrdp_process *id, int chan_id,
|
||||
int creation_status);
|
||||
int (*close_response)(struct xrdp_process *id, int chan_id);
|
||||
int (*data_first)(struct xrdp_process *id, int chan_id, char *data,
|
||||
int bytes, int total_bytes);
|
||||
int (*data)(struct xrdp_process *id, int chan_id, char *data, int bytes);
|
||||
int (*data_first)(struct xrdp_process *id, int chan_id, struct stream *s,
|
||||
int total_bytes);
|
||||
int (*data)(struct xrdp_process *id, int chan_id, struct stream *s);
|
||||
};
|
||||
|
||||
struct vc_dechunker; // Forward declaration
|
||||
|
||||
@@ -91,9 +91,9 @@ struct xrdp_drdynvc_procs
|
||||
int (*open_response)(struct xrdp_process *id, int chan_id,
|
||||
int creation_status);
|
||||
int (*close_response)(struct xrdp_process *id, int chan_id);
|
||||
int (*data_first)(struct xrdp_process *id, int chan_id,
|
||||
char *data, int bytes, int total_bytes);
|
||||
int (*data)(struct xrdp_process *id, int chan_id, char *data, int bytes);
|
||||
int (*data_first)(struct xrdp_process *id, int chan_id, struct stream *s,
|
||||
int total_bytes);
|
||||
int (*data)(struct xrdp_process *id, int chan_id, struct stream *s);
|
||||
};
|
||||
|
||||
/* Defined in xrdp_client_info.h */
|
||||
|
||||
@@ -488,8 +488,7 @@ drdynvc_process_data_first(struct xrdp_channel *self,
|
||||
drdynvc = self->drdynvcs + chan_id;
|
||||
if (drdynvc->data_first != NULL)
|
||||
{
|
||||
return drdynvc->data_first(session->id, chan_id, s->p,
|
||||
bytes, total_bytes);
|
||||
return drdynvc->data_first(session->id, chan_id, s, total_bytes);
|
||||
}
|
||||
LOG_DEVEL(LOG_LEVEL_WARNING, "Dynamic Virtual Channel %s (%d): "
|
||||
"callback 'data_first' is NULL",
|
||||
@@ -530,7 +529,7 @@ drdynvc_process_data(struct xrdp_channel *self,
|
||||
drdynvc = self->drdynvcs + chan_id;
|
||||
if (drdynvc->data != NULL)
|
||||
{
|
||||
return drdynvc->data(session->id, chan_id, s->p, bytes);
|
||||
return drdynvc->data(session->id, chan_id, s);
|
||||
}
|
||||
LOG_DEVEL(LOG_LEVEL_WARNING, "Dynamic Virtual Channel %s (%d): "
|
||||
"callback 'data' is NULL",
|
||||
|
||||
+8
-11
@@ -946,9 +946,10 @@ xrdp_egfx_close_response(struct xrdp_process *id, int chan_id)
|
||||
/* from client */
|
||||
static int
|
||||
xrdp_egfx_data_first(struct xrdp_process *id, int chan_id,
|
||||
char *data, int bytes, int total_bytes)
|
||||
struct stream *s, int total_bytes)
|
||||
{
|
||||
struct xrdp_egfx *egfx;
|
||||
int bytes = s_rem(s);
|
||||
|
||||
LOG(LOG_LEVEL_TRACE, "xrdp_egfx_data_first: bytes %d"
|
||||
" total_bytes %d", bytes, total_bytes);
|
||||
@@ -962,17 +963,16 @@ xrdp_egfx_data_first(struct xrdp_process *id, int chan_id,
|
||||
make_stream(egfx->s);
|
||||
// Caller has checked total_bytes is >= 0 and bytes is < total_bytes
|
||||
init_stream(egfx->s, total_bytes);
|
||||
out_uint8a(egfx->s, data, bytes);
|
||||
out_uint8a(egfx->s, s->p, bytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* from client */
|
||||
static int
|
||||
xrdp_egfx_data(struct xrdp_process *id, int chan_id, char *data, int bytes)
|
||||
xrdp_egfx_data(struct xrdp_process *id, int chan_id, struct stream *s)
|
||||
{
|
||||
int error;
|
||||
struct stream ls;
|
||||
struct xrdp_wm *wm;
|
||||
struct xrdp_mm *mm;
|
||||
struct xrdp_egfx *egfx;
|
||||
@@ -1004,20 +1004,17 @@ xrdp_egfx_data(struct xrdp_process *id, int chan_id, char *data, int bytes)
|
||||
|
||||
if (egfx->s == NULL)
|
||||
{
|
||||
g_memset(&ls, 0, sizeof(ls));
|
||||
ls.data = data;
|
||||
ls.size = bytes;
|
||||
ls.p = data;
|
||||
ls.end = data + bytes;
|
||||
return xrdp_egfx_process(egfx, &ls);
|
||||
return xrdp_egfx_process(egfx, s);
|
||||
}
|
||||
int bytes = s_rem(s);
|
||||
|
||||
if (!s_check_rem_out(egfx->s, bytes))
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "DYNVC_DATA PDU data overflow on channel %d",
|
||||
chan_id);
|
||||
return 1;
|
||||
}
|
||||
out_uint8a(egfx->s, data, bytes);
|
||||
out_uint8a(egfx->s, s->p, bytes);
|
||||
if (!s_check_rem_out(egfx->s, 1))
|
||||
{
|
||||
s_mark_end(egfx->s);
|
||||
|
||||
+30
-38
@@ -1047,7 +1047,7 @@ dynamic_monitor_close_response(struct xrdp_process *id, int chan_id)
|
||||
/******************************************************************************/
|
||||
static int
|
||||
dynamic_monitor_data_first(struct xrdp_process *id, int chan_id,
|
||||
char *data, int bytes, int total_bytes)
|
||||
struct stream *s, int total_bytes)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "dynamic_monitor_data_first:");
|
||||
return 0;
|
||||
@@ -1529,12 +1529,9 @@ add_resize_request_to_queue(struct xrdp_mm *self,
|
||||
|
||||
/******************************************************************************/
|
||||
static int
|
||||
dynamic_monitor_data(struct xrdp_process *id, int chan_id,
|
||||
char *data, int bytes)
|
||||
dynamic_monitor_data(struct xrdp_process *id, int chan_id, struct stream *s)
|
||||
{
|
||||
int error = 0;
|
||||
struct stream ls;
|
||||
struct stream *s;
|
||||
int msg_type;
|
||||
int msg_length;
|
||||
struct xrdp_wm *wm;
|
||||
@@ -1552,12 +1549,6 @@ dynamic_monitor_data(struct xrdp_process *id, int chan_id,
|
||||
return error;
|
||||
}
|
||||
|
||||
g_memset(&ls, 0, sizeof(ls));
|
||||
ls.data = data;
|
||||
ls.p = ls.data;
|
||||
ls.size = bytes;
|
||||
ls.end = ls.data + bytes;
|
||||
s = &ls;
|
||||
in_uint32_le(s, msg_type);
|
||||
in_uint32_le(s, msg_length);
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG,
|
||||
@@ -2156,65 +2147,66 @@ xrdp_mm_drdynvc_close_response(struct xrdp_process *id, int chan_id)
|
||||
/*****************************************************************************/
|
||||
/* part data from client going to channel server */
|
||||
static int
|
||||
xrdp_mm_drdynvc_data_first(struct xrdp_process *id, int chan_id, char *data,
|
||||
int bytes, int total_bytes)
|
||||
xrdp_mm_drdynvc_data_first(struct xrdp_process *id, int chan_id,
|
||||
struct stream *s, int total_bytes)
|
||||
{
|
||||
struct trans *trans;
|
||||
struct stream *s;
|
||||
struct stream *out_s;
|
||||
struct xrdp_wm *wm;
|
||||
int chansrv_chan_id;
|
||||
int bytes = s_rem(s);
|
||||
|
||||
// Size of PDU sent to chansrv
|
||||
int pdu_size = 8 + 8 + 4 + 4 + 4 + bytes;
|
||||
wm = id->wm;
|
||||
trans = wm->mm->chan_trans;
|
||||
s = trans_get_out_s(trans, pdu_size);
|
||||
if (s == NULL)
|
||||
out_s = trans_get_out_s(trans, pdu_size);
|
||||
if (out_s == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
out_uint32_le(s, 0); /* version */
|
||||
out_uint32_le(s, pdu_size);
|
||||
out_uint32_le(s, 17); /* msg id */
|
||||
out_uint32_le(s, pdu_size - 8);
|
||||
out_uint32_le(out_s, 0); /* version */
|
||||
out_uint32_le(out_s, pdu_size);
|
||||
out_uint32_le(out_s, 17); /* msg id */
|
||||
out_uint32_le(out_s, pdu_size - 8);
|
||||
chansrv_chan_id = wm->mm->xr2cr_cid_map[chan_id];
|
||||
out_uint32_le(s, chansrv_chan_id);
|
||||
out_uint32_le(s, bytes);
|
||||
out_uint32_le(s, total_bytes);
|
||||
out_uint8a(s, data, bytes);
|
||||
s_mark_end(s);
|
||||
out_uint32_le(out_s, chansrv_chan_id);
|
||||
out_uint32_le(out_s, bytes);
|
||||
out_uint32_le(out_s, total_bytes);
|
||||
out_uint8p(out_s, s->p, bytes);
|
||||
s_mark_end(out_s);
|
||||
return trans_write_copy(trans);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* data from client going to channel server */
|
||||
static int
|
||||
xrdp_mm_drdynvc_data(struct xrdp_process *id, int chan_id,
|
||||
char *data, int bytes)
|
||||
xrdp_mm_drdynvc_data(struct xrdp_process *id, int chan_id, struct stream *s)
|
||||
{
|
||||
struct trans *trans;
|
||||
struct stream *s;
|
||||
struct stream *out_s;
|
||||
struct xrdp_wm *wm;
|
||||
int chansrv_chan_id;
|
||||
int bytes = s_rem(s);
|
||||
|
||||
// Size of PDU sent to chansrv
|
||||
int pdu_size = 8 + 8 + 4 + 4 + bytes;
|
||||
wm = id->wm;
|
||||
trans = wm->mm->chan_trans;
|
||||
s = trans_get_out_s(trans, pdu_size);
|
||||
if (s == NULL)
|
||||
out_s = trans_get_out_s(trans, pdu_size);
|
||||
if (out_s == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
out_uint32_le(s, 0); /* version */
|
||||
out_uint32_le(s, pdu_size);
|
||||
out_uint32_le(s, 19); /* msg id */
|
||||
out_uint32_le(s, pdu_size - 8);
|
||||
out_uint32_le(out_s, 0); /* version */
|
||||
out_uint32_le(out_s, pdu_size);
|
||||
out_uint32_le(out_s, 19); /* msg id */
|
||||
out_uint32_le(out_s, pdu_size - 8);
|
||||
chansrv_chan_id = wm->mm->xr2cr_cid_map[chan_id];
|
||||
out_uint32_le(s, chansrv_chan_id);
|
||||
out_uint32_le(s, bytes);
|
||||
out_uint8a(s, data, bytes);
|
||||
s_mark_end(s);
|
||||
out_uint32_le(out_s, chansrv_chan_id);
|
||||
out_uint32_le(out_s, bytes);
|
||||
out_uint8p(out_s, s->p, bytes);
|
||||
s_mark_end(out_s);
|
||||
return trans_write_copy(trans);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user