server: process client control PDUs.

This commit is contained in:
Vic Lee 2011-08-21 22:52:37 +08:00
parent 9a7f56a2a1
commit 5b4759b75d
5 changed files with 127 additions and 5 deletions

View File

@ -64,6 +64,21 @@ boolean rdp_send_server_synchronize_pdu(rdpRdp* rdp)
return True;
}
boolean rdp_read_client_synchronize_pdu(STREAM* s)
{
uint16 messageType;
if (stream_get_left(s) < 4)
return False;
stream_read_uint16(s, messageType); /* messageType (2 bytes) */
if (messageType != SYNCMSGTYPE_SYNC)
return False;
/* targetUser (2 bytes) */
return True;
}
boolean rdp_send_client_synchronize_pdu(rdpRdp* rdp)
{
STREAM* s;
@ -77,11 +92,16 @@ boolean rdp_send_client_synchronize_pdu(rdpRdp* rdp)
return True;
}
void rdp_read_server_control_pdu(STREAM* s, uint16* action)
boolean rdp_read_control_pdu(STREAM* s, uint16* action)
{
if (stream_get_left(s) < 8)
return False;
stream_read_uint16(s, *action); /* action (2 bytes) */
stream_seek_uint16(s); /* grantId (2 bytes) */
stream_seek_uint32(s); /* controlId (4 bytes) */
return True;
}
void rdp_write_client_control_pdu(STREAM* s, uint16 action)
@ -95,7 +115,7 @@ void rdp_recv_server_control_pdu(rdpRdp* rdp, STREAM* s, rdpSettings* settings)
{
uint16 action;
rdp_read_server_control_pdu(s, &action);
rdp_read_control_pdu(s, &action);
if (action == CTRLACTION_COOPERATE)
{

View File

@ -43,9 +43,10 @@ void rdp_recv_deactivate_all(rdpRdp* rdp, STREAM* s);
void rdp_recv_server_synchronize_pdu(rdpRdp* rdp, STREAM* s, rdpSettings* settings);
boolean rdp_send_server_synchronize_pdu(rdpRdp* rdp);
boolean rdp_read_client_synchronize_pdu(STREAM* s);
boolean rdp_send_client_synchronize_pdu(rdpRdp* rdp);
boolean rdp_read_control_pdu(STREAM* s, uint16* action);
void rdp_recv_server_control_pdu(rdpRdp* rdp, STREAM* s, rdpSettings* settings);
void rdp_read_server_control_pdu(STREAM* s, uint16* action);
boolean rdp_send_server_control_cooperate_pdu(rdpRdp* rdp);
boolean rdp_send_server_control_granted_pdu(rdpRdp* rdp);
void rdp_send_client_control_pdu(rdpRdp* rdp, uint16 action);

View File

@ -54,6 +54,93 @@ static boolean freerdp_peer_check_fds(freerdp_peer* client)
return True;
}
static boolean peer_read_data_pdu(rdpPeer* peer, STREAM* s)
{
uint8 type;
uint16 length;
uint32 share_id;
uint16 action;
if (!rdp_read_share_data_header(s, &length, &type, &share_id))
return False;
switch (type)
{
case DATA_PDU_TYPE_SYNCHRONIZE:
if (!rdp_read_client_synchronize_pdu(s))
return False;
break;
case DATA_PDU_TYPE_CONTROL:
if (!rdp_read_control_pdu(s, &action))
return False;
if (action == CTRLACTION_REQUEST_CONTROL)
{
if (!rdp_send_server_control_granted_pdu(peer->rdp))
return False;
}
break;
default:
printf("Data PDU type %d\n", type);
break;
}
return True;
}
static boolean peer_read_tpkt_pdu(rdpPeer* peer, STREAM* s)
{
uint16 length;
uint16 pduType;
uint16 pduLength;
uint16 channelId;
if (!rdp_read_header(peer->rdp, s, &length, &channelId))
{
printf("Incorrect RDP header.\n");
return False;
}
if (channelId != MCS_GLOBAL_CHANNEL_ID)
{
/* TODO: process channel data from client */
}
else
{
if (!rdp_read_share_control_header(s, &pduLength, &pduType, &peer->rdp->settings->pdu_source))
return False;
switch (pduType)
{
case PDU_TYPE_DATA:
if (!peer_read_data_pdu(peer, s))
return False;
break;
default:
printf("Client sent pduType %d\n", pduType);
return False;
}
}
return True;
}
static boolean peer_read_fastpath_pdu(rdpPeer* peer, STREAM* s)
{
printf("FastPath Input PDU\n");
return True;
}
static boolean peer_read_pdu(rdpPeer* peer, STREAM* s)
{
if (tpkt_verify_header(s))
return peer_read_tpkt_pdu(peer, s);
else
return peer_read_fastpath_pdu(peer, s);
}
static int peer_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
{
rdpPeer* peer = (rdpPeer*)extra;
@ -95,6 +182,11 @@ static int peer_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
return -1;
break;
case CONNECTION_STATE_ACTIVE:
if (!peer_read_pdu(peer, s))
return -1;
break;
default:
printf("Invalid state %d\n", peer->rdp->state);
return -1;

View File

@ -113,16 +113,25 @@ void rdp_write_share_control_header(STREAM* s, uint16 length, uint16 type, uint1
stream_write_uint16(s, channel_id); /* pduSource */
}
void rdp_read_share_data_header(STREAM* s, uint16* length, uint8* type, uint32* share_id)
boolean rdp_read_share_data_header(STREAM* s, uint16* length, uint8* type, uint32* share_id)
{
if (stream_get_left(s) < 12)
return False;
/* Share Data Header */
stream_read_uint32(s, *share_id); /* shareId (4 bytes) */
stream_seek_uint8(s); /* pad1 (1 byte) */
stream_seek_uint8(s); /* streamId (1 byte) */
stream_read_uint16(s, *length); /* uncompressedLength (2 bytes) */
if (stream_get_left(s) < *length)
return False;
stream_read_uint8(s, *type); /* pduType2, Data PDU Type (1 byte) */
stream_seek_uint8(s); /* compressedType (1 byte) */
stream_seek_uint16(s); /* compressedLength (2 bytes) */
return True;
}
void rdp_write_share_data_header(STREAM* s, uint16 length, uint8 type, uint32 share_id)

View File

@ -133,7 +133,7 @@ void rdp_write_security_header(STREAM* s, uint16 flags);
boolean rdp_read_share_control_header(STREAM* s, uint16* length, uint16* type, uint16* channel_id);
void rdp_write_share_control_header(STREAM* s, uint16 length, uint16 type, uint16 channel_id);
void rdp_read_share_data_header(STREAM* s, uint16* length, uint8* type, uint32* share_id);
boolean rdp_read_share_data_header(STREAM* s, uint16* length, uint8* type, uint32* share_id);
void rdp_write_share_data_header(STREAM* s, uint16 length, uint8 type, uint32 share_id);
STREAM* rdp_send_stream_init(rdpRdp* rdp);