got rdp encryption working

This commit is contained in:
Jay Sorg 2011-09-14 14:14:50 -07:00
parent 2e2875966f
commit a406cd6619
10 changed files with 112 additions and 18 deletions

View File

@ -60,6 +60,6 @@ target_link_libraries(xfreerdp freerdp-kbd)
target_link_libraries(xfreerdp freerdp-rail)
target_link_libraries(xfreerdp freerdp-chanman)
target_link_libraries(xfreerdp freerdp-utils)
target_link_libraries(xfreerdp ${X11_LIBRARIES})
target_link_libraries(xfreerdp ${X11_LIBRARIES} dl)
install(TARGETS xfreerdp DESTINATION bin)

View File

@ -23,4 +23,4 @@ add_executable(freerdp-test
target_link_libraries(freerdp-test freerdp-core)
target_link_libraries(freerdp-test freerdp-gdi)
target_link_libraries(freerdp-test freerdp-utils)
target_link_libraries(freerdp-test freerdp-chanman)
target_link_libraries(freerdp-test freerdp-chanman dl)

View File

@ -1492,17 +1492,25 @@ boolean rdp_read_capability_sets(STREAM* s, rdpSettings* settings, uint16 number
uint16 length;
uint8 *bm, *em;
printf("rdp_read_capability_sets: numberCapabilities %d\n", numberCapabilities);
while (numberCapabilities > 0)
{
stream_get_mark(s, bm);
freerdp_hexdump(s->p, 4);
rdp_read_capability_set_header(s, &length, &type);
//printf("%s Capability Set (0x%02X), length:%d\n", CAPSET_TYPE_STRINGS[type], type, length);
settings->received_caps[type] = True;
em = bm + length;
printf("%d %d\n", stream_get_left(s), length - 4);
if (stream_get_left(s) < length - 4)
{
printf("stream problem\n");
return False;
}
printf("type %d\n", type);
switch (type)
{
@ -1643,18 +1651,46 @@ boolean rdp_recv_demand_active(rdpRdp* rdp, STREAM* s)
uint16 numberCapabilities;
uint16 lengthSourceDescriptor;
uint16 lengthCombinedCapabilities;
uint32 securityHeader;
if (!rdp_read_header(rdp, s, &length, &channelId))
return False;
if (rdp->settings->encryption)
{
stream_read_uint32(s, securityHeader);
if (securityHeader & SEC_SECURE_CHECKSUM)
{
printf("Error: TODO\n");
return False;
}
if (securityHeader & SEC_ENCRYPT)
{
if (!rdp_decrypt(rdp, s, length - 4))
{
printf("rdp_decrypt failed\n");
return False;
}
}
}
if (channelId != MCS_GLOBAL_CHANNEL_ID)
{
printf("channelId bad\n");
return False;
}
if (!rdp_read_share_control_header(s, &pduLength, &pduType, &rdp->settings->pdu_source))
{
printf("rdp_read_share_control_header failed\n");
return False;
}
if (pduType != PDU_TYPE_DEMAND_ACTIVE)
{
printf("pduType bad\n");
return False;
}
//printf("Demand Active PDU\n");
@ -1667,7 +1703,10 @@ boolean rdp_recv_demand_active(rdpRdp* rdp, STREAM* s)
/* capabilitySets */
if (!rdp_read_capability_sets(s, rdp->settings, numberCapabilities))
{
printf("rdp_read_capability_sets failes\n");
return False;
}
rdp->update->glyph_v2 = (rdp->settings->glyphSupportLevel > GLYPH_SUPPORT_FULL) ? True : False;

View File

@ -74,6 +74,36 @@ uint16 fastpath_read_header(rdpFastPath* fastpath, STREAM* s)
return length;
}
uint16 fastpath_read_header_rdp(rdpFastPath* fastpath, STREAM* s)
{
uint8 header;
uint16 length;
uint8 t;
uint16 hs;
hs = 2;
stream_read_uint8(s, header);
if (fastpath != NULL)
{
fastpath->encryptionFlags = (header & 0xC0) >> 6;
printf("fastpath_read_header: fastpath->encryptionFlags %d\n", fastpath->encryptionFlags);
fastpath->numberEvents = (header & 0x3C) >> 2;
}
stream_read_uint8(s, length); /* length1 */
/* If most significant bit is not set, length2 is not presented. */
if ((length & 0x80))
{
hs++;
length &= 0x7F;
length <<= 8;
stream_read_uint8(s, t);
length += t;
}
return length - hs;
}
boolean fastpath_read_security_header(rdpFastPath* fastpath, STREAM* s)
{
/* TODO: fipsInformation */

View File

@ -91,6 +91,7 @@ struct rdp_fastpath
};
uint16 fastpath_read_header(rdpFastPath* fastpath, STREAM* s);
uint16 fastpath_read_header_rdp(rdpFastPath* fastpath, STREAM* s);
boolean fastpath_read_security_header(rdpFastPath* fastpath, STREAM* s);
boolean fastpath_recv_updates(rdpFastPath* fastpath, STREAM* s);
boolean fastpath_recv_inputs(rdpFastPath* fastpath, STREAM* s);

View File

@ -139,15 +139,20 @@ static boolean peer_recv_fastpath_pdu(rdpPeer* peer, STREAM* s)
{
uint16 length;
length = fastpath_read_header(peer->rdp->fastpath, s);
if (length == 0 || length > stream_get_size(s))
length = fastpath_read_header_rdp(peer->rdp->fastpath, s);
if (length == 0 || length > stream_get_left(s))
{
printf("incorrect FastPath PDU header length %d\n", length);
return False;
}
if (!fastpath_read_security_header(peer->rdp->fastpath, s))
return False;
if (peer->rdp->fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED)
{
rdp_decrypt(peer->rdp, s, length);
}
//if (!fastpath_read_security_header(peer->rdp->fastpath, s))
// return False;
return fastpath_recv_inputs(peer->rdp->fastpath, s);
}

View File

@ -495,10 +495,16 @@ void rdp_recv_data_pdu(rdpRdp* rdp, STREAM* s)
* @param length int
*/
static boolean rdp_decrypt(rdpRdp* rdp, STREAM* s, int length)
boolean rdp_decrypt(rdpRdp* rdp, STREAM* s, int length)
{
printf("rdp_decrypt:\n");
int cryptlen;
//printf("rdp_decrypt:\n");
stream_seek(s, 8); /* signature */
cryptlen = length - 8;
//printf("length %d cryptlen %d\n", length, cryptlen);
security_decrypt(s->p, cryptlen, rdp);
//freerdp_hexdump(s->p, cryptlen);
return True;
}
@ -532,7 +538,7 @@ static boolean rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
}
if (securityHeader & SEC_ENCRYPT)
{
if (!rdp_decrypt(rdp, s, length))
if (!rdp_decrypt(rdp, s, length - 4))
{
printf("rdp_decrypt failed\n");
return False;
@ -576,15 +582,23 @@ static boolean rdp_recv_fastpath_pdu(rdpRdp* rdp, STREAM* s)
{
uint16 length;
length = fastpath_read_header(rdp->fastpath, s);
if (length == 0 || length > stream_get_size(s))
length = fastpath_read_header_rdp(rdp->fastpath, s);
if (length == 0 || length > stream_get_left(s))
{
printf("incorrect FastPath PDU header length %d\n", length);
return False;
}
if (!fastpath_read_security_header(rdp->fastpath, s))
return False;
printf("rdp_recv_fastpath_pdu: length %d stream size %d\n", length, stream_get_size(s));
if (rdp->fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED)
{
rdp_decrypt(rdp, s, length);
}
//if (!fastpath_read_security_header(rdp->fastpath, s))
// return False;
return fastpath_recv_updates(rdp->fastpath, s);
}
@ -641,7 +655,10 @@ static int rdp_recv_callback(rdpTransport* transport, STREAM* s, void* extra)
case CONNECTION_STATE_CAPABILITY:
if (!rdp_client_connect_demand_active(rdp, s))
{
printf("rdp_client_connect_demand_active failed\n");
return -1;
}
break;
case CONNECTION_STATE_ACTIVE:

View File

@ -162,4 +162,6 @@ int rdp_check_fds(rdpRdp* rdp);
rdpRdp* rdp_new(freerdp* instance);
void rdp_free(rdpRdp* rdp);
boolean rdp_decrypt(rdpRdp* rdp, STREAM* s, int length);
#endif /* __RDP_H */

View File

@ -167,8 +167,8 @@ int tcp_read(rdpTcp* tcp, uint8* data, int length)
}
else
{
printf("tcp_read: length %d\n", status);
freerdp_hexdump(data, status);
//printf("tcp_read: length %d\n", status);
//freerdp_hexdump(data, status);
}
return status;
@ -180,8 +180,8 @@ int tcp_write(rdpTcp* tcp, uint8* data, int length)
status = send(tcp->sockfd, data, length, MSG_NOSIGNAL);
printf("tcp_write: length %d\n", status);
freerdp_hexdump(data, status);
//printf("tcp_write: length %d\n", status);
//freerdp_hexdump(data, status);
if (status < 0)
{

View File

@ -22,4 +22,4 @@ add_executable(freerdp-server-test
target_link_libraries(freerdp-server-test freerdp-core)
target_link_libraries(freerdp-server-test freerdp-utils)
target_link_libraries(freerdp-server-test freerdp-rfx)
target_link_libraries(freerdp-server-test freerdp-rfx dl)