diff --git a/libfreerdp-core/ber.c b/libfreerdp-core/ber.c index e0f7bc20f..f9d79fd34 100644 --- a/libfreerdp-core/ber.c +++ b/libfreerdp-core/ber.c @@ -163,6 +163,39 @@ boolean ber_read_contextual_tag(STREAM* s, uint8 tag, int* length, boolean pc) return True; } +boolean ber_write_contextual_tag(STREAM* s, uint8 tag, int length, boolean pc) +{ + stream_write_uint8(s, (BER_CLASS_CTXT | BER_PC(pc)) | (BER_TAG_MASK & tag)); + ber_write_length(s, length); + return True; +} + +boolean ber_read_sequence_tag(STREAM* s, int* length) +{ + uint8 byte; + + stream_read_uint8(s, byte); + + if (byte != ((BER_CLASS_UNIV | BER_CONSTRUCT) | (BER_TAG_SEQUENCE_OF))) + return False; + + ber_read_length(s, length); + + return True; +} + +/** + * Write BER SEQUENCE tag. + * @param s stream + * @param length length + */ + +void ber_write_sequence_tag(STREAM* s, int length) +{ + stream_write_uint8(s, (BER_CLASS_UNIV | BER_CONSTRUCT) | (BER_TAG_MASK & BER_TAG_SEQUENCE)); + ber_write_length(s, length); +} + boolean ber_read_sequence_of_tag(STREAM* s, int* length) { uint8 byte; diff --git a/libfreerdp-core/ber.h b/libfreerdp-core/ber.h index 173c0b156..0e1a1819c 100644 --- a/libfreerdp-core/ber.h +++ b/libfreerdp-core/ber.h @@ -45,6 +45,7 @@ #define BER_TAG_OCTET_STRING 0x04 #define BER_TAG_OBJECT_IDENFIER 0x06 #define BER_TAG_ENUMERATED 0x0A +#define BER_TAG_SEQUENCE 0x10 #define BER_TAG_SEQUENCE_OF 0x10 #define BER_PC(_pc) (_pc ? BER_CONSTRUCT : BER_PRIMITIVE) @@ -59,6 +60,10 @@ boolean ber_read_application_tag(STREAM* s, uint8 tag, int* length); boolean ber_read_enumerated(STREAM* s, uint8* enumerated, uint8 count); boolean ber_read_sequence_of_tag(STREAM* s, int* length); boolean ber_read_contextual_tag(STREAM* s, uint8 tag, int* length, boolean pc); +boolean ber_write_contextual_tag(STREAM* s, uint8 tag, int length, boolean pc); +boolean ber_read_sequence_tag(STREAM* s, int* length); +void ber_write_sequence_tag(STREAM* s, int length); +boolean ber_read_sequence_of_tag(STREAM* s, int* length); void ber_write_sequence_of_tag(STREAM* s, int length); boolean ber_read_bit_string(STREAM* s, int* length, uint8* padding); boolean ber_read_octet_string(STREAM* s, int* length); diff --git a/libfreerdp-core/connection.c b/libfreerdp-core/connection.c index db2ae1ec8..0adf752e0 100644 --- a/libfreerdp-core/connection.c +++ b/libfreerdp-core/connection.c @@ -64,7 +64,7 @@ boolean rdp_client_connect(rdpRdp* rdp) nego_set_cookie(rdp->nego, rdp->settings->username); nego_set_protocols(rdp->nego, 1, 1, 1); - if (nego_connect(rdp->nego) == False) + if (nego_connect(rdp->nego) != True) { printf("Error: protocol security negotiation failure\n"); return False; @@ -77,11 +77,21 @@ boolean rdp_client_connect(rdpRdp* rdp) else if (rdp->nego->selected_protocol & PROTOCOL_RDP) transport_connect_rdp(rdp->transport); - mcs_connect(rdp->mcs); + if (mcs_connect(rdp->mcs) != True) + { + printf("Error: Multipoint Connection Service (MCS) connection failure\n"); + return False; + } rdp_send_client_info(rdp); - license_connect(rdp->license); + if (license_connect(rdp->license) != True) + { + printf("Error: license connection sequence failure\n"); + return False; + } + + rdp_recv(rdp); return True; } diff --git a/libfreerdp-core/credssp.c b/libfreerdp-core/credssp.c index bfa90aefc..ff063219c 100644 --- a/libfreerdp-core/credssp.c +++ b/libfreerdp-core/credssp.c @@ -32,6 +32,56 @@ #include "credssp.h" +/** + * TSRequest ::= SEQUENCE { + * version [0] INTEGER, + * negoTokens [1] NegoData OPTIONAL, + * authInfo [2] OCTET STRING OPTIONAL, + * pubKeyAuth [3] OCTET STRING OPTIONAL + * } + * + * NegoData ::= SEQUENCE OF NegoDataItem + * + * NegoDataItem ::= SEQUENCE { + * negoToken [0] OCTET STRING + * } + * + * TSCredentials ::= SEQUENCE { + * credType [0] INTEGER, + * credentials [1] OCTET STRING + * } + * + * TSPasswordCreds ::= SEQUENCE { + * domainName [0] OCTET STRING, + * userName [1] OCTET STRING, + * password [2] OCTET STRING + * } + * + * TSSmartCardCreds ::= SEQUENCE { + * pin [0] OCTET STRING, + * cspData [1] TSCspDataDetail, + * userHint [2] OCTET STRING OPTIONAL, + * domainHint [3] OCTET STRING OPTIONAL + * } + * + * TSCspDataDetail ::= SEQUENCE { + * keySpec [0] INTEGER, + * cardName [1] OCTET STRING OPTIONAL, + * readerName [2] OCTET STRING OPTIONAL, + * containerName [3] OCTET STRING OPTIONAL, + * cspName [4] OCTET STRING OPTIONAL + * } + * + */ + +/** + * + * @param buffer + * @param size + * @param fd + * @return + */ + static int asn1_write(const void *buffer, size_t size, void *fd) { @@ -338,6 +388,7 @@ void credssp_encode_ts_credentials(rdpCredssp* credssp) * @param authInfo */ +#if 1 void credssp_send(rdpCredssp* credssp, BLOB* negoToken, BLOB* pubKeyAuth, BLOB* authInfo) { STREAM* s; @@ -392,6 +443,34 @@ void credssp_send(rdpCredssp* credssp, BLOB* negoToken, BLOB* pubKeyAuth, BLOB* asn_DEF_TSRequest.free_struct(&asn_DEF_TSRequest, ts_request, 0); } } +#else +void credssp_send(rdpCredssp* credssp, BLOB* negoToken, BLOB* pubKeyAuth, BLOB* authInfo) +{ + STREAM* s; + int length; + int ber_length; + + s = stream_new(2048); + + /* TSRequest */ + ber_write_sequence_tag(s, length); /* SEQUENCE */ + ber_write_contextual_tag(s, 0, 3, True); /* [0] version */ + ber_write_integer(s, 2); /* INTEGER */ + length -= 7; + + /* NegoData */ + ber_write_contextual_tag(s, 1, length, True); /* [1] negoTokens */ + ber_write_sequence_of_tag(s, length - 2); /* SEQUENCE OF NegoDataItem */ + ber_write_sequence_of_tag(s, length - 4); /* NegoDataItem */ + length -= 6; + + /* negoToken */ + ber_write_contextual_tag(s, 0, length, True); /* [0] negoToken */ + ber_write_octet_string(s, negoToken->data, negoToken->length); /* OCTET STRING */ + + transport_write(credssp->transport, s); +} +#endif /** * Receive CredSSP message. diff --git a/libfreerdp-core/credssp.h b/libfreerdp-core/credssp.h index 0dc69eaad..e47c42ab7 100644 --- a/libfreerdp-core/credssp.h +++ b/libfreerdp-core/credssp.h @@ -23,6 +23,7 @@ typedef struct rdp_credssp rdpCredssp; #include "tls.h" +#include "ber.h" #include "crypto.h" #include "transport.h" #include diff --git a/libfreerdp-core/mcs.c b/libfreerdp-core/mcs.c index ef94fc1af..ee8c12e2b 100644 --- a/libfreerdp-core/mcs.c +++ b/libfreerdp-core/mcs.c @@ -224,7 +224,9 @@ boolean mcs_read_domain_mcspdu_header(STREAM* s, enum DomainMCSPDU* domainMCSPDU enum DomainMCSPDU MCSPDU; *length = tpkt_read_header(s); - tpdu_read_data(s); + + if (tpdu_read_data(s) == 0) + return False; MCSPDU = *domainMCSPDU; per_read_choice(s, &choice); @@ -448,7 +450,9 @@ void mcs_recv_connect_response(rdpMcs* mcs) transport_read(mcs->transport, s); tpkt_read_header(s); - tpdu_read_data(s); + + if (tpdu_read_data(s) == 0) + return; ber_read_application_tag(s, MCS_TYPE_CONNECT_RESPONSE, &length); ber_read_enumerated(s, &result, MCS_Result_enum_length); diff --git a/libfreerdp-core/rdp.c b/libfreerdp-core/rdp.c index 2086e083f..10ee4a70e 100644 --- a/libfreerdp-core/rdp.c +++ b/libfreerdp-core/rdp.c @@ -124,6 +124,11 @@ void rdp_recv(rdpRdp* rdp) rdp_read_security_header(s, &sec_flags); + if (sec_flags & SEC_ENCRYPT) + { + printf("RDP packet is encrypted\n"); + } + if (sec_flags & SEC_PKT_MASK) { switch (sec_flags & SEC_PKT_MASK) diff --git a/libfreerdp-core/tpdu.c b/libfreerdp-core/tpdu.c index d66617bca..630b61e0a 100644 --- a/libfreerdp-core/tpdu.c +++ b/libfreerdp-core/tpdu.c @@ -183,10 +183,7 @@ tpdu_read_data(STREAM* s) li = tpdu_read_header(s, &code); if (code != X224_TPDU_DATA) - { - printf("expected X224_TPDU_DATA\n"); return 0; - } return li; }