server: receive client capabilities.

This commit is contained in:
Vic Lee 2011-08-21 15:52:44 +08:00
parent 281ceead2f
commit 82bed4a0e8
7 changed files with 87 additions and 17 deletions

View File

@ -775,6 +775,7 @@ void rdp_write_glyph_cache_capability_set(STREAM* s, rdpSettings* settings)
rdp_write_cache_definition(s, 254, 16);
rdp_write_cache_definition(s, 254, 32);
rdp_write_cache_definition(s, 254, 64);
rdp_write_cache_definition(s, 254, 128);
rdp_write_cache_definition(s, 254, 256);
rdp_write_cache_definition(s, 64, 2048);
@ -1425,25 +1426,12 @@ void rdp_write_frame_acknowledge_capability_set(STREAM* s, rdpSettings* settings
rdp_capability_set_finish(s, header, CAPSET_TYPE_FRAME_ACKNOWLEDGE);
}
void rdp_read_demand_active(STREAM* s, rdpSettings* settings)
boolean rdp_read_capability_sets(STREAM* s, rdpSettings* settings, uint16 numberCapabilities)
{
uint16 type;
uint16 length;
uint8 *bm, *em;
uint16 numberCapabilities;
uint16 lengthSourceDescriptor;
uint16 lengthCombinedCapabilities;
//printf("Demand Active PDU\n");
stream_read_uint32(s, settings->share_id); /* shareId (4 bytes) */
stream_read_uint16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */
stream_read_uint16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */
stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor */
stream_read_uint16(s, numberCapabilities); /* numberCapabilities (2 bytes) */
stream_seek(s, 2); /* pad2Octets (2 bytes) */
/* capabilitySets */
while (numberCapabilities > 0)
{
stream_get_mark(s, bm);
@ -1453,6 +1441,9 @@ void rdp_read_demand_active(STREAM* s, rdpSettings* settings)
settings->received_caps[type] = True;
em = bm + length;
if (stream_get_left(s) < length - 4)
return False;
switch (type)
{
case CAPSET_TYPE_GENERAL:
@ -1568,15 +1559,38 @@ void rdp_read_demand_active(STREAM* s, rdpSettings* settings)
break;
default:
printf("unknown capability type %d\n", type);
break;
}
if (s->p != em)
printf("incorrect offset, actual:%d expected:%d\n", (int) (s->p - bm), (int) (em - bm));
printf("incorrect offset, type:%d actual:%d expected:%d\n",
type, (int) (s->p - bm), (int) (em - bm));
stream_set_mark(s, em);
numberCapabilities--;
}
return True;
}
void rdp_read_demand_active(STREAM* s, rdpSettings* settings)
{
uint16 numberCapabilities;
uint16 lengthSourceDescriptor;
uint16 lengthCombinedCapabilities;
//printf("Demand Active PDU\n");
stream_read_uint32(s, settings->share_id); /* shareId (4 bytes) */
stream_read_uint16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */
stream_read_uint16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */
stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor */
stream_read_uint16(s, numberCapabilities); /* numberCapabilities (2 bytes) */
stream_seek(s, 2); /* pad2Octets (2 bytes) */
/* capabilitySets */
rdp_read_capability_sets(s, settings, numberCapabilities);
}
void rdp_recv_demand_active(rdpRdp* rdp, STREAM* s, rdpSettings* settings)
@ -1648,6 +1662,40 @@ boolean rdp_send_demand_active(rdpRdp* rdp)
return True;
}
boolean rdp_read_confirm_active(rdpRdp* rdp, STREAM* s)
{
uint16 length;
uint16 channelId;
uint16 pduType;
uint16 pduLength;
uint16 lengthSourceDescriptor;
uint16 lengthCombinedCapabilities;
uint16 numberCapabilities;
if (!rdp_read_header(rdp, s, &length, &channelId))
return False;
if (channelId != MCS_GLOBAL_CHANNEL_ID)
return False;
if (!rdp_read_share_control_header(s, &pduLength, &pduType, &rdp->settings->pdu_source))
return False;
if (pduType != PDU_TYPE_CONFIRM_ACTIVE)
return False;
stream_seek_uint32(s); /* shareId (4 bytes) */
stream_seek_uint16(s); /* originatorId (2 bytes) */
stream_read_uint16(s, lengthSourceDescriptor); /* lengthSourceDescriptor (2 bytes) */
stream_read_uint16(s, lengthCombinedCapabilities); /* lengthCombinedCapabilities (2 bytes) */
stream_seek(s, lengthSourceDescriptor); /* sourceDescriptor */
stream_read_uint16(s, numberCapabilities); /* numberCapabilities (2 bytes) */
stream_seek(s, 2); /* pad2Octets (2 bytes) */
if (!rdp_read_capability_sets(s, rdp->settings, numberCapabilities))
return False;
return True;
}
void rdp_write_confirm_active(STREAM* s, rdpSettings* settings)
{
uint8 *bm, *em, *lm;

View File

@ -173,6 +173,7 @@ void rdp_read_demand_active(STREAM* s, rdpSettings* settings);
void rdp_recv_demand_active(rdpRdp* rdp, STREAM* s, rdpSettings* settings);
void rdp_write_demand_active(STREAM* s, rdpSettings* settings);
boolean rdp_send_demand_active(rdpRdp* rdp);
boolean rdp_read_confirm_active(rdpRdp* rdp, STREAM* s);
void rdp_write_confirm_active(STREAM* s, rdpSettings* settings);
void rdp_send_confirm_active(rdpRdp* rdp);

View File

@ -261,3 +261,13 @@ boolean rdp_server_accept_client_info(rdpRdp* rdp, STREAM* s)
return True;
}
boolean rdp_server_accept_confirm_active(rdpRdp* rdp, STREAM* s)
{
if (!rdp_read_confirm_active(rdp, s))
return False;
rdp->state = CONNECTION_STATE_ACTIVE;
return True;
}

View File

@ -51,5 +51,6 @@ boolean rdp_server_accept_mcs_erect_domain_request(rdpRdp* rdp, STREAM* s);
boolean rdp_server_accept_mcs_attach_user_request(rdpRdp* rdp, STREAM* s);
boolean rdp_server_accept_mcs_channel_join_request(rdpRdp* rdp, STREAM* s);
boolean rdp_server_accept_client_info(rdpRdp* rdp, STREAM* s);
boolean rdp_server_accept_confirm_active(rdpRdp* rdp, STREAM* s);
#endif /* __CONNECTION_H */

View File

@ -90,6 +90,11 @@ static int peer_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
return -1;
break;
case CONNECTION_STATE_LICENSE:
if (!rdp_server_accept_confirm_active(peer->rdp, s))
return -1;
break;
default:
printf("Invalid state %d\n", peer->rdp->state);
return -1;

View File

@ -89,13 +89,18 @@ void rdp_write_security_header(STREAM* s, uint16 flags)
stream_write_uint16(s, 0); /* flagsHi (unused) */
}
void rdp_read_share_control_header(STREAM* s, uint16* length, uint16* type, uint16* channel_id)
boolean rdp_read_share_control_header(STREAM* s, uint16* length, uint16* type, uint16* channel_id)
{
/* Share Control Header */
stream_read_uint16(s, *length); /* totalLength */
stream_read_uint16(s, *type); /* pduType */
stream_read_uint16(s, *channel_id); /* pduSource */
*type &= 0x0F; /* type is in the 4 least significant bits */
if (*length - 6 > stream_get_left(s))
return False;
return True;
}
void rdp_write_share_control_header(STREAM* s, uint16 length, uint16 type, uint16 channel_id)

View File

@ -130,7 +130,7 @@ struct rdp_rdp
void rdp_read_security_header(STREAM* s, uint16* flags);
void rdp_write_security_header(STREAM* s, uint16 flags);
void rdp_read_share_control_header(STREAM* s, uint16* length, uint16* type, uint16* channel_id);
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);