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 (*open_response)(struct xrdp_process *id, int chan_id,
|
||||||
int creation_status);
|
int creation_status);
|
||||||
int (*close_response)(struct xrdp_process *id, int chan_id);
|
int (*close_response)(struct xrdp_process *id, int chan_id);
|
||||||
int (*data_first)(struct xrdp_process *id, int chan_id, char *data,
|
int (*data_first)(struct xrdp_process *id, int chan_id, struct stream *s,
|
||||||
int bytes, int total_bytes);
|
int total_bytes);
|
||||||
int (*data)(struct xrdp_process *id, int chan_id, char *data, int bytes);
|
int (*data)(struct xrdp_process *id, int chan_id, struct stream *s);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vc_dechunker; // Forward declaration
|
struct vc_dechunker; // Forward declaration
|
||||||
|
|||||||
@@ -91,9 +91,9 @@ struct xrdp_drdynvc_procs
|
|||||||
int (*open_response)(struct xrdp_process *id, int chan_id,
|
int (*open_response)(struct xrdp_process *id, int chan_id,
|
||||||
int creation_status);
|
int creation_status);
|
||||||
int (*close_response)(struct xrdp_process *id, int chan_id);
|
int (*close_response)(struct xrdp_process *id, int chan_id);
|
||||||
int (*data_first)(struct xrdp_process *id, int chan_id,
|
int (*data_first)(struct xrdp_process *id, int chan_id, struct stream *s,
|
||||||
char *data, int bytes, int total_bytes);
|
int total_bytes);
|
||||||
int (*data)(struct xrdp_process *id, int chan_id, char *data, int bytes);
|
int (*data)(struct xrdp_process *id, int chan_id, struct stream *s);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Defined in xrdp_client_info.h */
|
/* Defined in xrdp_client_info.h */
|
||||||
|
|||||||
@@ -488,8 +488,7 @@ drdynvc_process_data_first(struct xrdp_channel *self,
|
|||||||
drdynvc = self->drdynvcs + chan_id;
|
drdynvc = self->drdynvcs + chan_id;
|
||||||
if (drdynvc->data_first != NULL)
|
if (drdynvc->data_first != NULL)
|
||||||
{
|
{
|
||||||
return drdynvc->data_first(session->id, chan_id, s->p,
|
return drdynvc->data_first(session->id, chan_id, s, total_bytes);
|
||||||
bytes, total_bytes);
|
|
||||||
}
|
}
|
||||||
LOG_DEVEL(LOG_LEVEL_WARNING, "Dynamic Virtual Channel %s (%d): "
|
LOG_DEVEL(LOG_LEVEL_WARNING, "Dynamic Virtual Channel %s (%d): "
|
||||||
"callback 'data_first' is NULL",
|
"callback 'data_first' is NULL",
|
||||||
@@ -530,7 +529,7 @@ drdynvc_process_data(struct xrdp_channel *self,
|
|||||||
drdynvc = self->drdynvcs + chan_id;
|
drdynvc = self->drdynvcs + chan_id;
|
||||||
if (drdynvc->data != NULL)
|
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): "
|
LOG_DEVEL(LOG_LEVEL_WARNING, "Dynamic Virtual Channel %s (%d): "
|
||||||
"callback 'data' is NULL",
|
"callback 'data' is NULL",
|
||||||
|
|||||||
+8
-11
@@ -946,9 +946,10 @@ xrdp_egfx_close_response(struct xrdp_process *id, int chan_id)
|
|||||||
/* from client */
|
/* from client */
|
||||||
static int
|
static int
|
||||||
xrdp_egfx_data_first(struct xrdp_process *id, int chan_id,
|
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;
|
struct xrdp_egfx *egfx;
|
||||||
|
int bytes = s_rem(s);
|
||||||
|
|
||||||
LOG(LOG_LEVEL_TRACE, "xrdp_egfx_data_first: bytes %d"
|
LOG(LOG_LEVEL_TRACE, "xrdp_egfx_data_first: bytes %d"
|
||||||
" total_bytes %d", bytes, total_bytes);
|
" 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);
|
make_stream(egfx->s);
|
||||||
// Caller has checked total_bytes is >= 0 and bytes is < total_bytes
|
// Caller has checked total_bytes is >= 0 and bytes is < total_bytes
|
||||||
init_stream(egfx->s, total_bytes);
|
init_stream(egfx->s, total_bytes);
|
||||||
out_uint8a(egfx->s, data, bytes);
|
out_uint8a(egfx->s, s->p, bytes);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* from client */
|
/* from client */
|
||||||
static int
|
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;
|
int error;
|
||||||
struct stream ls;
|
|
||||||
struct xrdp_wm *wm;
|
struct xrdp_wm *wm;
|
||||||
struct xrdp_mm *mm;
|
struct xrdp_mm *mm;
|
||||||
struct xrdp_egfx *egfx;
|
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)
|
if (egfx->s == NULL)
|
||||||
{
|
{
|
||||||
g_memset(&ls, 0, sizeof(ls));
|
return xrdp_egfx_process(egfx, s);
|
||||||
ls.data = data;
|
|
||||||
ls.size = bytes;
|
|
||||||
ls.p = data;
|
|
||||||
ls.end = data + bytes;
|
|
||||||
return xrdp_egfx_process(egfx, &ls);
|
|
||||||
}
|
}
|
||||||
|
int bytes = s_rem(s);
|
||||||
|
|
||||||
if (!s_check_rem_out(egfx->s, bytes))
|
if (!s_check_rem_out(egfx->s, bytes))
|
||||||
{
|
{
|
||||||
LOG(LOG_LEVEL_ERROR, "DYNVC_DATA PDU data overflow on channel %d",
|
LOG(LOG_LEVEL_ERROR, "DYNVC_DATA PDU data overflow on channel %d",
|
||||||
chan_id);
|
chan_id);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
out_uint8a(egfx->s, data, bytes);
|
out_uint8a(egfx->s, s->p, bytes);
|
||||||
if (!s_check_rem_out(egfx->s, 1))
|
if (!s_check_rem_out(egfx->s, 1))
|
||||||
{
|
{
|
||||||
s_mark_end(egfx->s);
|
s_mark_end(egfx->s);
|
||||||
|
|||||||
+30
-38
@@ -1047,7 +1047,7 @@ dynamic_monitor_close_response(struct xrdp_process *id, int chan_id)
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
static int
|
static int
|
||||||
dynamic_monitor_data_first(struct xrdp_process *id, int chan_id,
|
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:");
|
LOG_DEVEL(LOG_LEVEL_TRACE, "dynamic_monitor_data_first:");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1529,12 +1529,9 @@ add_resize_request_to_queue(struct xrdp_mm *self,
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
static int
|
static int
|
||||||
dynamic_monitor_data(struct xrdp_process *id, int chan_id,
|
dynamic_monitor_data(struct xrdp_process *id, int chan_id, struct stream *s)
|
||||||
char *data, int bytes)
|
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
struct stream ls;
|
|
||||||
struct stream *s;
|
|
||||||
int msg_type;
|
int msg_type;
|
||||||
int msg_length;
|
int msg_length;
|
||||||
struct xrdp_wm *wm;
|
struct xrdp_wm *wm;
|
||||||
@@ -1552,12 +1549,6 @@ dynamic_monitor_data(struct xrdp_process *id, int chan_id,
|
|||||||
return error;
|
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_type);
|
||||||
in_uint32_le(s, msg_length);
|
in_uint32_le(s, msg_length);
|
||||||
LOG_DEVEL(LOG_LEVEL_DEBUG,
|
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 */
|
/* part data from client going to channel server */
|
||||||
static int
|
static int
|
||||||
xrdp_mm_drdynvc_data_first(struct xrdp_process *id, int chan_id, char *data,
|
xrdp_mm_drdynvc_data_first(struct xrdp_process *id, int chan_id,
|
||||||
int bytes, int total_bytes)
|
struct stream *s, int total_bytes)
|
||||||
{
|
{
|
||||||
struct trans *trans;
|
struct trans *trans;
|
||||||
struct stream *s;
|
struct stream *out_s;
|
||||||
struct xrdp_wm *wm;
|
struct xrdp_wm *wm;
|
||||||
int chansrv_chan_id;
|
int chansrv_chan_id;
|
||||||
|
int bytes = s_rem(s);
|
||||||
|
|
||||||
// Size of PDU sent to chansrv
|
// Size of PDU sent to chansrv
|
||||||
int pdu_size = 8 + 8 + 4 + 4 + 4 + bytes;
|
int pdu_size = 8 + 8 + 4 + 4 + 4 + bytes;
|
||||||
wm = id->wm;
|
wm = id->wm;
|
||||||
trans = wm->mm->chan_trans;
|
trans = wm->mm->chan_trans;
|
||||||
s = trans_get_out_s(trans, pdu_size);
|
out_s = trans_get_out_s(trans, pdu_size);
|
||||||
if (s == NULL)
|
if (out_s == NULL)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
out_uint32_le(s, 0); /* version */
|
out_uint32_le(out_s, 0); /* version */
|
||||||
out_uint32_le(s, pdu_size);
|
out_uint32_le(out_s, pdu_size);
|
||||||
out_uint32_le(s, 17); /* msg id */
|
out_uint32_le(out_s, 17); /* msg id */
|
||||||
out_uint32_le(s, pdu_size - 8);
|
out_uint32_le(out_s, pdu_size - 8);
|
||||||
chansrv_chan_id = wm->mm->xr2cr_cid_map[chan_id];
|
chansrv_chan_id = wm->mm->xr2cr_cid_map[chan_id];
|
||||||
out_uint32_le(s, chansrv_chan_id);
|
out_uint32_le(out_s, chansrv_chan_id);
|
||||||
out_uint32_le(s, bytes);
|
out_uint32_le(out_s, bytes);
|
||||||
out_uint32_le(s, total_bytes);
|
out_uint32_le(out_s, total_bytes);
|
||||||
out_uint8a(s, data, bytes);
|
out_uint8p(out_s, s->p, bytes);
|
||||||
s_mark_end(s);
|
s_mark_end(out_s);
|
||||||
return trans_write_copy(trans);
|
return trans_write_copy(trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* data from client going to channel server */
|
/* data from client going to channel server */
|
||||||
static int
|
static int
|
||||||
xrdp_mm_drdynvc_data(struct xrdp_process *id, int chan_id,
|
xrdp_mm_drdynvc_data(struct xrdp_process *id, int chan_id, struct stream *s)
|
||||||
char *data, int bytes)
|
|
||||||
{
|
{
|
||||||
struct trans *trans;
|
struct trans *trans;
|
||||||
struct stream *s;
|
struct stream *out_s;
|
||||||
struct xrdp_wm *wm;
|
struct xrdp_wm *wm;
|
||||||
int chansrv_chan_id;
|
int chansrv_chan_id;
|
||||||
|
int bytes = s_rem(s);
|
||||||
|
|
||||||
// Size of PDU sent to chansrv
|
// Size of PDU sent to chansrv
|
||||||
int pdu_size = 8 + 8 + 4 + 4 + bytes;
|
int pdu_size = 8 + 8 + 4 + 4 + bytes;
|
||||||
wm = id->wm;
|
wm = id->wm;
|
||||||
trans = wm->mm->chan_trans;
|
trans = wm->mm->chan_trans;
|
||||||
s = trans_get_out_s(trans, pdu_size);
|
out_s = trans_get_out_s(trans, pdu_size);
|
||||||
if (s == NULL)
|
if (out_s == NULL)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
out_uint32_le(s, 0); /* version */
|
out_uint32_le(out_s, 0); /* version */
|
||||||
out_uint32_le(s, pdu_size);
|
out_uint32_le(out_s, pdu_size);
|
||||||
out_uint32_le(s, 19); /* msg id */
|
out_uint32_le(out_s, 19); /* msg id */
|
||||||
out_uint32_le(s, pdu_size - 8);
|
out_uint32_le(out_s, pdu_size - 8);
|
||||||
chansrv_chan_id = wm->mm->xr2cr_cid_map[chan_id];
|
chansrv_chan_id = wm->mm->xr2cr_cid_map[chan_id];
|
||||||
out_uint32_le(s, chansrv_chan_id);
|
out_uint32_le(out_s, chansrv_chan_id);
|
||||||
out_uint32_le(s, bytes);
|
out_uint32_le(out_s, bytes);
|
||||||
out_uint8a(s, data, bytes);
|
out_uint8p(out_s, s->p, bytes);
|
||||||
s_mark_end(s);
|
s_mark_end(out_s);
|
||||||
return trans_write_copy(trans);
|
return trans_write_copy(trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user