diff options
author | Idan Freiberg <speidy@gmail.com> | 2016-04-16 14:03:48 +0300 |
---|---|---|
committer | Idan Freiberg <speidy@gmail.com> | 2016-04-16 14:03:48 +0300 |
commit | 41954517e4ae984239afb0828dbdc71547cee311 (patch) | |
tree | 8f7b4437f85cf385ca70acd4ff1d1a8aeeb2afe9 | |
parent | a64fef8d1519e68735153a42f226162e9b7069cf (diff) | |
parent | 67ea8cae60cf6b1023f5c475d0f79e1652d93a10 (diff) |
Merge pull request #6 from Osirium/devel
Osirium Fixes
-rw-r--r-- | client/X11/xf_monitor.c | 2 | ||||
-rw-r--r-- | libfreerdp-core/ber.c | 248 | ||||
-rw-r--r-- | libfreerdp-core/ber.h | 21 | ||||
-rw-r--r-- | libfreerdp-core/credssp.c | 183 | ||||
-rw-r--r-- | libfreerdp-core/gcc.c | 9 | ||||
-rw-r--r-- | libfreerdp-core/ntlmssp.c | 2 | ||||
-rw-r--r-- | libfreerdp-utils/args.c | 43 |
7 files changed, 309 insertions, 199 deletions
diff --git a/client/X11/xf_monitor.c b/client/X11/xf_monitor.c index 7ede960..b5877a0 100644 --- a/client/X11/xf_monitor.c +++ b/client/X11/xf_monitor.c @@ -56,7 +56,7 @@ tbool xf_detect_monitors(xfInfo* xfi, rdpSettings* settings) if (settings->num_monitors > 0) { - /* already setup */ + /* already setup in args */ return true; } diff --git a/libfreerdp-core/ber.c b/libfreerdp-core/ber.c index bb81493..22c2af5 100644 --- a/libfreerdp-core/ber.c +++ b/libfreerdp-core/ber.c @@ -19,25 +19,44 @@ #include "ber.h" -void ber_read_length(STREAM* s, int* length) +int ber_read_length(STREAM* s, int* length) { uint8 byte; + if (stream_get_left(s) < 1) + { + return 0; + } stream_read_uint8(s, byte); if (byte & 0x80) { byte &= ~(0x80); + if (stream_get_left(s) < byte) + { + return 0; + } + if (byte == 1) + { stream_read_uint8(s, *length); - if (byte == 2) + } + else if (byte == 2) + { stream_read_uint16_be(s, *length); + } + else + { + return 0; + } } else { *length = byte; } + + return 1; } /** @@ -48,34 +67,38 @@ void ber_read_length(STREAM* s, int* length) int ber_write_length(STREAM* s, int length) { - if (length > 0x7F) + if (length > 0xFF) { - stream_write_uint8(s, 0x82); + stream_write_uint8(s, 0x80 ^ 2); stream_write_uint16_be(s, length); return 3; } - else + if (length > 0x7F) { + stream_write_uint8(s, 0x80 ^ 1); stream_write_uint8(s, length); - return 1; + return 2; } + stream_write_uint8(s, length); + return 1; } -int _ber_skip_length(int length) +int _ber_sizeof_length(int length) { - if (length > 0x7F) + if (length > 0xFF) return 3; - else - return 1; + if (length > 0x7F) + return 2; + return 1; } -int ber_get_content_length(int length) -{ - if (length - 1 > 0x7F) - return length - 4; - else - return length - 2; -} +//int ber_get_content_length(int length) +//{ +// if (length - 1 > 0x7F) +// return length - 4; +// else +// return length - 2; +//} /** * Read BER Universal tag. @@ -84,12 +107,17 @@ int ber_get_content_length(int length) * @return */ -tbool ber_read_universal_tag(STREAM* s, uint8 tag, tbool pc) +int ber_read_universal_tag(STREAM* s, uint8 tag, tbool pc) { uint8 byte; + if (stream_get_left(s) < 1) + { + return 0; + } stream_read_uint8(s, byte); + if (byte != (BER_CLASS_UNIV | BER_PC(pc) | (BER_TAG_MASK & tag))) return false; @@ -103,9 +131,10 @@ tbool ber_read_universal_tag(STREAM* s, uint8 tag, tbool pc) * @param pc primitive (false) or constructed (true) */ -void ber_write_universal_tag(STREAM* s, uint8 tag, tbool pc) +int ber_write_universal_tag(STREAM* s, uint8 tag, tbool pc) { stream_write_uint8(s, (BER_CLASS_UNIV | BER_PC(pc)) | (BER_TAG_MASK & tag)); + return 1; } /** @@ -121,26 +150,38 @@ tbool ber_read_application_tag(STREAM* s, uint8 tag, int* length) if (tag > 30) { + if (stream_get_left(s) < 1) + { + return 0; + } stream_read_uint8(s, byte); if (byte != ((BER_CLASS_APPL | BER_CONSTRUCT) | BER_TAG_MASK)) return false; + if (stream_get_left(s) < 1) + { + return 0; + } stream_read_uint8(s, byte); if (byte != tag) return false; - ber_read_length(s, length); + return ber_read_length(s, length); } else { + if (stream_get_left(s) < 1) + { + return 0; + } stream_read_uint8(s, byte); if (byte != ((BER_CLASS_APPL | BER_CONSTRUCT) | (BER_TAG_MASK & tag))) return false; - ber_read_length(s, length); + return ber_read_length(s, length); } return true; @@ -172,6 +213,10 @@ tbool ber_read_contextual_tag(STREAM* s, uint8 tag, int* length, tbool pc) { uint8 byte; + if (stream_get_left(s) < 1) + { + return 0; + } stream_read_uint8(s, byte); if (byte != ((BER_CLASS_CTXT | BER_PC(pc)) | (BER_TAG_MASK & tag))) @@ -180,34 +225,34 @@ tbool ber_read_contextual_tag(STREAM* s, uint8 tag, int* length, tbool pc) return false; } - ber_read_length(s, length); - - return true; + return ber_read_length(s, length); } int ber_write_contextual_tag(STREAM* s, uint8 tag, int length, tbool pc) { stream_write_uint8(s, (BER_CLASS_CTXT | BER_PC(pc)) | (BER_TAG_MASK & tag)); - return ber_write_length(s, length) + 1; + return 1 + ber_write_length(s, length); } -int ber_skip_contextual_tag(int length) +int ber_sizeof_contextual_tag(int length) { - return _ber_skip_length(length) + 1; + return 1 + _ber_sizeof_length(length); } tbool ber_read_sequence_tag(STREAM* s, int* length) { uint8 byte; + if (stream_get_left(s) < 1) + { + return 0; + } 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; + return ber_read_length(s, length); } /** @@ -219,30 +264,36 @@ tbool ber_read_sequence_tag(STREAM* s, int* length) int ber_write_sequence_tag(STREAM* s, int length) { stream_write_uint8(s, (BER_CLASS_UNIV | BER_CONSTRUCT) | (BER_TAG_MASK & BER_TAG_SEQUENCE)); - return ber_write_length(s, length) + 1; + return 1 + ber_write_length(s, length); } -int ber_skip_sequence(int length) +int ber_sizeof_sequence(int length) { - return 1 + _ber_skip_length(length) + length; + return 1 + _ber_sizeof_length(length) + length; } -int ber_skip_sequence_tag(int length) +int ber_sizeof_sequence_tag(int length) { - return 1 + _ber_skip_length(length); + return 1 + _ber_sizeof_length(length); } tbool ber_read_enumerated(STREAM* s, uint8* enumerated, uint8 count) { int length; - ber_read_universal_tag(s, BER_TAG_ENUMERATED, false); - ber_read_length(s, &length); + if (!ber_read_universal_tag(s, BER_TAG_ENUMERATED, false) || + !ber_read_length(s, &length)) + { + return false; + } - if (length == 1) - stream_read_uint8(s, *enumerated); - else + + if (length != 1 || stream_get_left(s) < 1) + { return false; + } + + stream_read_uint8(s, *enumerated); /* check that enumerated value falls within expected range */ if (*enumerated + 1 > count) @@ -260,8 +311,17 @@ void ber_write_enumerated(STREAM* s, uint8 enumerated, uint8 count) tbool ber_read_bit_string(STREAM* s, int* length, uint8* padding) { - ber_read_universal_tag(s, BER_TAG_BIT_STRING, false); - ber_read_length(s, length); + if (!ber_read_universal_tag(s, BER_TAG_BIT_STRING, false) || + !ber_read_length(s, length)) + { + return false; + } + + if (stream_get_left(s) < 1) + { + return false; + } + stream_read_uint8(s, *padding); return true; @@ -282,23 +342,35 @@ tbool ber_read_octet_string(STREAM* s, int* length) * @param length string length */ -void ber_write_octet_string(STREAM* s, const uint8* oct_str, int length) +int ber_write_octet_string(STREAM* s, const uint8* oct_str, int length) { - ber_write_universal_tag(s, BER_TAG_OCTET_STRING, false); - ber_write_length(s, length); + int size = 0; + size += ber_write_universal_tag(s, BER_TAG_OCTET_STRING, false); + size += ber_write_length(s, length); stream_write(s, oct_str, length); + size += length; + return size; + } +tbool ber_read_octet_string_tag(STREAM* s, int* length) +{ + return + ber_read_universal_tag(s, BER_TAG_OCTET_STRING, false) && + ber_read_length(s, length); +} + + int ber_write_octet_string_tag(STREAM* s, int length) { ber_write_universal_tag(s, BER_TAG_OCTET_STRING, false); ber_write_length(s, length); - return 1 + _ber_skip_length(length); + return 1 + _ber_sizeof_length(length); } -int ber_skip_octet_string(int length) +int ber_sizeof_octet_string(int length) { - return 1 + _ber_skip_length(length) + length; + return 1 + _ber_sizeof_length(length) + length; } /** @@ -312,13 +384,16 @@ tbool ber_read_boolean(STREAM* s, tbool* value) int length; uint8 v; - if (!ber_read_universal_tag(s, BER_TAG_BOOLEAN, false)) + if (!ber_read_universal_tag(s, BER_TAG_BOOLEAN, false) || + !ber_read_length(s, &length)) return false; - ber_read_length(s, &length); - if (length != 1) + + if (length != 1 || stream_get_left(s) < 1) return false; + stream_read_uint8(s, v); *value = (v ? true : false); + return true; } @@ -339,19 +414,31 @@ tbool ber_read_integer(STREAM* s, uint32* value) { int length; - ber_read_universal_tag(s, BER_TAG_INTEGER, false); - ber_read_length(s, &length); + if (!ber_read_universal_tag(s, BER_TAG_INTEGER, false) || + !ber_read_length(s, &length) || + stream_get_left(s) < length) + { + return false; + } if (value == NULL) { + if (stream_get_left(s) < length) + { + return false; + } stream_seek(s, length); return true; } if (length == 1) + { stream_read_uint8(s, *value); + } else if (length == 2) + { stream_read_uint16_be(s, *value); + } else if (length == 3) { uint8 byte; @@ -360,9 +447,19 @@ tbool ber_read_integer(STREAM* s, uint32* value) *value += (byte << 16); } else if (length == 4) + { stream_read_uint32_be(s, *value); + } + else if (length == 8) + { + fprintf(stderr, "%s: should implement reading an 8 bytes integer\n", __FUNCTION__); + return false; + } else + { + fprintf(stderr, "%s: should implement reading an integer with length=%d\n", __FUNCTION__, length); return false; + } return true; } @@ -375,50 +472,57 @@ tbool ber_read_integer(STREAM* s, uint32* value) int ber_write_integer(STREAM* s, uint32 value) { - ber_write_universal_tag(s, BER_TAG_INTEGER, false); - if (value <= 0xFF) + if (value < 0x80) { + ber_write_universal_tag(s, BER_TAG_INTEGER, false); ber_write_length(s, 1); stream_write_uint8(s, value); - return 2; + return 3; } - else if (value < 0xFF80) + else if (value < 0x8000) { + ber_write_universal_tag(s, BER_TAG_INTEGER, false); ber_write_length(s, 2); stream_write_uint16_be(s, value); - return 3; + return 4; } - else if (value < 0xFF8000) + else if (value < 0x800000) { + ber_write_universal_tag(s, BER_TAG_INTEGER, false); ber_write_length(s, 3); stream_write_uint8(s, (value >> 16)); stream_write_uint16_be(s, (value & 0xFFFF)); - return 4; + return 5; } - else if (value <= 0xFFFFFFFF) + else if (value < 0x80000000) { + ber_write_universal_tag(s, BER_TAG_INTEGER, false); ber_write_length(s, 4); stream_write_uint32_be(s, value); - return 5; + return 6; } return 0; } -int ber_skip_integer(uint32 value) +int ber_sizeof_integer(uint32 value) { - if (value <= 0xFF) + if (value < 0x80) { - return _ber_skip_length(1) + 2; + return 3; } - else if (value <= 0xFFFF) + else if (value < 0x8000) { - return _ber_skip_length(2) + 3; + return 4; } - else if (value <= 0xFFFFFFFF) + else if (value < 0x800000) { - return _ber_skip_length(4) + 5; + return 5; + } + else if (value < 0x80000000) + { + return 6; } return 0; @@ -426,7 +530,7 @@ int ber_skip_integer(uint32 value) tbool ber_read_integer_length(STREAM* s, int* length) { - ber_read_universal_tag(s, BER_TAG_INTEGER, false); - ber_read_length(s, length); - return true; + return + ber_read_universal_tag(s, BER_TAG_INTEGER, false) && + ber_read_length(s, length); } diff --git a/libfreerdp-core/ber.h b/libfreerdp-core/ber.h index b03ce13..292860f 100644 --- a/libfreerdp-core/ber.h +++ b/libfreerdp-core/ber.h @@ -50,12 +50,12 @@ #define BER_PC(_pc) (_pc ? BER_CONSTRUCT : BER_PRIMITIVE) -void ber_read_length(STREAM* s, int* length); +int ber_read_length(STREAM* s, int* length); int ber_write_length(STREAM* s, int length); -int _ber_skip_length(int length); +int _ber_sizeof_length(int length); int ber_get_content_length(int length); -tbool ber_read_universal_tag(STREAM* s, uint8 tag, tbool pc); -void ber_write_universal_tag(STREAM* s, uint8 tag, tbool pc); +int ber_read_universal_tag(STREAM* s, uint8 tag, tbool pc); +int ber_write_universal_tag(STREAM* s, uint8 tag, tbool pc); tbool ber_read_application_tag(STREAM* s, uint8 tag, int* length); void ber_write_application_tag(STREAM* s, uint8 tag, int length); tbool ber_read_application_tag(STREAM* s, uint8 tag, int* length); @@ -63,21 +63,22 @@ tbool ber_read_enumerated(STREAM* s, uint8* enumerated, uint8 count); void ber_write_enumerated(STREAM* s, uint8 enumerated, uint8 count); tbool ber_read_contextual_tag(STREAM* s, uint8 tag, int* length, tbool pc); int ber_write_contextual_tag(STREAM* s, uint8 tag, int length, tbool pc); -int ber_skip_contextual_tag(int length); +int ber_sizeof_contextual_tag(int length); tbool ber_read_sequence_tag(STREAM* s, int* length); int ber_write_sequence_tag(STREAM* s, int length); -int ber_skip_sequence(int length); -int ber_skip_sequence_tag(int length); +int ber_sizeof_sequence(int length); +int ber_sizeof_sequence_tag(int length); tbool ber_read_bit_string(STREAM* s, int* length, uint8* padding); tbool ber_read_octet_string(STREAM* s, int* length); -void ber_write_octet_string(STREAM* s, const uint8* oct_str, int length); +int ber_write_octet_string(STREAM* s, const uint8* oct_str, int length); +tbool ber_read_octet_string_tag(STREAM* s, int* length); int ber_write_octet_string_tag(STREAM* s, int length); -int ber_skip_octet_string(int length); +int ber_sizeof_octet_string(int length); tbool ber_read_boolean(STREAM* s, tbool* value); void ber_write_boolean(STREAM* s, tbool value); tbool ber_read_integer(STREAM* s, uint32* value); int ber_write_integer(STREAM* s, uint32 value); tbool ber_read_integer_length(STREAM* s, int* length); -int ber_skip_integer(uint32 value); +int ber_sizeof_integer(uint32 value); #endif /* __BER_H */ diff --git a/libfreerdp-core/credssp.c b/libfreerdp-core/credssp.c index ad45549..4402c00 100644 --- a/libfreerdp-core/credssp.c +++ b/libfreerdp-core/credssp.c @@ -67,6 +67,12 @@ * */ + +#define ber_sizeof_sequence_octet_string(length) ber_sizeof_contextual_tag(ber_sizeof_octet_string(length)) + ber_sizeof_octet_string(length) +#define ber_write_sequence_octet_string(stream, context, value, length) ber_write_contextual_tag(stream, context, ber_sizeof_octet_string(length), true) + ber_write_octet_string(stream, value, length) + + + /** * Initialize NTLMSSP authentication module. * @param credssp @@ -324,93 +330,73 @@ void credssp_encrypt_ts_credentials(rdpCredssp* credssp, rdpBlob* d) freerdp_blob_free(&encrypted_ts_credentials); } -int credssp_skip_ts_password_creds(rdpCredssp* credssp) +int credssp_sizeof_ts_password_creds(rdpCredssp* credssp) { - int length; - int ts_password_creds_length = 0; - - length = ber_skip_octet_string(credssp->ntlmssp->domain.length); - length += ber_skip_contextual_tag(length); - ts_password_creds_length += length; + int length = 0; - length = ber_skip_octet_string(credssp->ntlmssp->username.length); - length += ber_skip_contextual_tag(length); - ts_password_creds_length += length; - - length = ber_skip_octet_string(credssp->ntlmssp->password.length); - length += ber_skip_contextual_tag(length); - ts_password_creds_length += length; - - length = ber_skip_sequence(ts_password_creds_length); + length += ber_sizeof_sequence_octet_string(credssp->ntlmssp->domain.length * 2); + length += ber_sizeof_sequence_octet_string(credssp->ntlmssp->username.length * 2); + length += ber_sizeof_sequence_octet_string(credssp->ntlmssp->password.length * 2); return length; } -void credssp_write_ts_password_creds(rdpCredssp* credssp, STREAM* s) +int credssp_write_ts_password_creds(rdpCredssp* credssp, STREAM* s) { - int length; + int size = 0; + int innerSize = credssp_sizeof_ts_password_creds(credssp); - length = credssp_skip_ts_password_creds(credssp); + if (innerSize > stream_get_left(s)) + { + printf("\033[91m[ ERROR ] Not enough space allocated for ts_password_creds\033[0m"); + } /* TSPasswordCreds (SEQUENCE) */ - length = ber_get_content_length(length); - ber_write_sequence_tag(s, length); + size += ber_write_sequence_tag(s, innerSize); /* [0] domainName (OCTET STRING) */ - ber_write_contextual_tag(s, 0, credssp->ntlmssp->domain.length + 2, true); - ber_write_octet_string(s, credssp->ntlmssp->domain.data, credssp->ntlmssp->domain.length); + size += ber_write_sequence_octet_string(s, 0, credssp->ntlmssp->domain.data, credssp->ntlmssp->domain.length * 2); /* [1] userName (OCTET STRING) */ - ber_write_contextual_tag(s, 1, credssp->ntlmssp->username.length + 2, true); - ber_write_octet_string(s, credssp->ntlmssp->username.data, credssp->ntlmssp->username.length); + size += ber_write_sequence_octet_string(s, 1, credssp->ntlmssp->username.data, credssp->ntlmssp->username.length * 2); /* [2] password (OCTET STRING) */ - ber_write_contextual_tag(s, 2, credssp->ntlmssp->password.length + 2, true); - ber_write_octet_string(s, credssp->ntlmssp->password.data, credssp->ntlmssp->password.length); + size += ber_write_sequence_octet_string(s, 2, credssp->ntlmssp->password.data, credssp->ntlmssp->password.length * 2); + + return size; } -int credssp_skip_ts_credentials(rdpCredssp* credssp) +int credssp_sizeof_ts_credentials(rdpCredssp* credssp) { - int length; - int ts_password_creds_length; - int ts_credentials_length = 0; - - length = ber_skip_integer(0); - length += ber_skip_contextual_tag(length); - ts_credentials_length += length; - - ts_password_creds_length = credssp_skip_ts_password_creds(credssp); - length = ber_skip_octet_string(ts_password_creds_length); - length += ber_skip_contextual_tag(length); - ts_credentials_length += length; + int size = 0; - length = ber_skip_sequence(ts_credentials_length); + size += ber_sizeof_integer(1); + size += ber_sizeof_contextual_tag(ber_sizeof_integer(1)); + size += ber_sizeof_sequence_octet_string(ber_sizeof_sequence(credssp_sizeof_ts_password_creds(credssp))); - return length; + return size; } -void credssp_write_ts_credentials(rdpCredssp* credssp, STREAM* s) +int credssp_write_ts_credentials(rdpCredssp* credssp, STREAM* s) { - int length; - int ts_password_creds_length; - - length = credssp_skip_ts_credentials(credssp); - ts_password_creds_length = credssp_skip_ts_password_creds(credssp); + int size = 0; + int innerSize = credssp_sizeof_ts_credentials(credssp); /* TSCredentials (SEQUENCE) */ - length = ber_get_content_length(length); - length -= ber_write_sequence_tag(s, length); + size += ber_write_sequence_tag(s, innerSize); /* [0] credType (INTEGER) */ - length -= ber_write_contextual_tag(s, 0, 3, true); - length -= ber_write_integer(s, 1); + size += ber_write_contextual_tag(s, 0, ber_sizeof_integer(1), true); + size += ber_write_integer(s, 1); /* [1] credentials (OCTET STRING) */ - length -= 1; - length -= ber_write_contextual_tag(s, 1, length, true); - length -= ber_write_octet_string_tag(s, ts_password_creds_length); + int passwordSize = ber_sizeof_sequence(credssp_sizeof_ts_password_creds(credssp)); - credssp_write_ts_password_creds(credssp, s); + size += ber_write_contextual_tag(s, 1, ber_sizeof_octet_string(passwordSize), true); + size += ber_write_octet_string_tag(s, passwordSize); + size += credssp_write_ts_password_creds(credssp, s); + + return size; } /** @@ -424,7 +410,7 @@ void credssp_encode_ts_credentials(rdpCredssp* credssp) int length; s = stream_new(0); - length = credssp_skip_ts_credentials(credssp); + length = ber_sizeof_sequence(credssp_sizeof_ts_credentials(credssp)); freerdp_blob_alloc(&credssp->ts_credentials, length); stream_attach(s, credssp->ts_credentials.data, length); @@ -433,41 +419,40 @@ void credssp_encode_ts_credentials(rdpCredssp* credssp) stream_free(s); } -int credssp_skip_nego_token(int length) +int credssp_sizeof_nego_token(int length) { - length = ber_skip_octet_string(length); - length += ber_skip_contextual_tag(length); + length = ber_sizeof_octet_string(length); + length += ber_sizeof_contextual_tag(length); return length; } -int credssp_skip_nego_tokens(int length) +int credssp_sizeof_nego_tokens(int length) { - length = credssp_skip_nego_token(length); - length += ber_skip_sequence_tag(length); - length += ber_skip_sequence_tag(length); - length += ber_skip_contextual_tag(length); + length = credssp_sizeof_nego_token(length); + length += ber_sizeof_sequence_tag(length); + length += ber_sizeof_sequence_tag(length); + length += ber_sizeof_contextual_tag(length); return length; } -int credssp_skip_pub_key_auth(int length) +int credssp_sizeof_pub_key_auth(int length) { - length = ber_skip_octet_string(length); - length += ber_skip_contextual_tag(length); + length = ber_sizeof_octet_string(length); + length += ber_sizeof_contextual_tag(length); return length; } -int credssp_skip_auth_info(int length) +int credssp_sizeof_auth_info(int length) { - length = ber_skip_octet_string(length); - length += ber_skip_contextual_tag(length); + length = ber_sizeof_octet_string(length); + length += ber_sizeof_contextual_tag(length); return length; } -int credssp_skip_ts_request(int length) +int credssp_sizeof_ts_request(int length) { - length += ber_skip_integer(2); - length += ber_skip_contextual_tag(3); - length += ber_skip_sequence_tag(length); + length += ber_sizeof_integer(2); + length += ber_sizeof_contextual_tag(3); return length; } @@ -488,46 +473,46 @@ void credssp_send(rdpCredssp* credssp, rdpBlob* negoToken, rdpBlob* authInfo, rd int pub_key_auth_length; int auth_info_length; - nego_tokens_length = (negoToken != NULL) ? credssp_skip_nego_tokens(negoToken->length) : 0; - pub_key_auth_length = (pubKeyAuth != NULL) ? credssp_skip_pub_key_auth(pubKeyAuth->length) : 0; - auth_info_length = (authInfo != NULL) ? credssp_skip_auth_info(authInfo->length) : 0; + nego_tokens_length = (negoToken != NULL) ? credssp_sizeof_nego_tokens(negoToken->length) : 0; + pub_key_auth_length = (pubKeyAuth != NULL) ? credssp_sizeof_pub_key_auth(pubKeyAuth->length) : 0; + auth_info_length = (authInfo != NULL) ? credssp_sizeof_auth_info(authInfo->length) : 0; length = nego_tokens_length + pub_key_auth_length + auth_info_length; - ts_request_length = credssp_skip_ts_request(length); - s = stream_new(ts_request_length); + ts_request_length = credssp_sizeof_ts_request(length); + + s = stream_new(ber_sizeof_sequence(ts_request_length)); /* TSRequest */ - length = ber_get_content_length(ts_request_length); - ber_write_sequence_tag(s, length); /* SEQUENCE */ - ber_write_contextual_tag(s, 0, 3, true); /* [0] version */ + ber_write_sequence_tag(s, ts_request_length); /* SEQUENCE */ + + /* [0] version */ + ber_write_contextual_tag(s, 0, 3, true); ber_write_integer(s, 2); /* INTEGER */ /* [1] negoTokens (NegoData) */ if (nego_tokens_length > 0) { - length = ber_get_content_length(nego_tokens_length); - length -= ber_write_contextual_tag(s, 1, length, true); /* NegoData */ - length -= ber_write_sequence_tag(s, length); /* SEQUENCE OF NegoDataItem */ - length -= ber_write_sequence_tag(s, length); /* NegoDataItem */ - length -= ber_write_contextual_tag(s, 0, length, true); /* [0] negoToken */ - ber_write_octet_string(s, negoToken->data, length); /* OCTET STRING */ + length = nego_tokens_length; + + length -= ber_write_contextual_tag(s, 1, ber_sizeof_sequence(ber_sizeof_sequence(ber_sizeof_sequence_octet_string(credssp->negoToken.length))), true); /* NegoData */ + length -= ber_write_sequence_tag(s, ber_sizeof_sequence(ber_sizeof_sequence_octet_string(credssp->negoToken.length))); /* SEQUENCE OF NegoDataItem */ + length -= ber_write_sequence_tag(s, ber_sizeof_sequence_octet_string(credssp->negoToken.length)); /* NegoDataItem */ + length -= ber_write_sequence_octet_string(s, 0, negoToken->data, negoToken->length); /* OCTET STRING */ } /* [2] authInfo (OCTET STRING) */ if (auth_info_length > 0) { - length = ber_get_content_length(auth_info_length); - length -= ber_write_contextual_tag(s, 2, length, true); - ber_write_octet_string(s, authInfo->data, authInfo->length); + length = auth_info_length; + length -= ber_write_sequence_octet_string(s, 2, authInfo->data, authInfo->length); } /* [3] pubKeyAuth (OCTET STRING) */ if (pub_key_auth_length > 0) { - length = ber_get_content_length(pub_key_auth_length); - length -= ber_write_contextual_tag(s, 3, length, true); - ber_write_octet_string(s, pubKeyAuth->data, length); + length = pub_key_auth_length; + length -= ber_write_sequence_octet_string(s, 3, pubKeyAuth->data, pubKeyAuth->length); } tls_write(credssp->tls, s->data, stream_get_length(s)); @@ -553,6 +538,7 @@ int credssp_recv(rdpCredssp* credssp, rdpBlob* negoToken, rdpBlob* authInfo, rdp s = stream_new(2048); status = tls_read(credssp->tls, s->data, stream_get_left(s)); + if (status < 0) return -1; @@ -562,12 +548,13 @@ int credssp_recv(rdpCredssp* credssp, rdpBlob* negoToken, rdpBlob* authInfo, rdp ber_read_integer(s, &version); /* [1] negoTokens (NegoData) */ + if (ber_read_contextual_tag(s, 1, &length, true) != false) { ber_read_sequence_tag(s, &length); /* SEQUENCE OF NegoDataItem */ ber_read_sequence_tag(s, &length); /* NegoDataItem */ ber_read_contextual_tag(s, 0, &length, true); /* [0] negoToken */ - ber_read_octet_string(s, &length); /* OCTET STRING */ + ber_read_octet_string_tag(s, &length); /* OCTET STRING */ freerdp_blob_alloc(negoToken, length); stream_read(s, negoToken->data, length); } @@ -575,7 +562,7 @@ int credssp_recv(rdpCredssp* credssp, rdpBlob* negoToken, rdpBlob* authInfo, rdp /* [2] authInfo (OCTET STRING) */ if (ber_read_contextual_tag(s, 2, &length, true) != false) { - ber_read_octet_string(s, &length); /* OCTET STRING */ + ber_read_octet_string_tag(s, &length); /* OCTET STRING */ freerdp_blob_alloc(authInfo, length); stream_read(s, authInfo->data, length); } @@ -583,7 +570,7 @@ int credssp_recv(rdpCredssp* credssp, rdpBlob* negoToken, rdpBlob* authInfo, rdp /* [3] pubKeyAuth (OCTET STRING) */ if (ber_read_contextual_tag(s, 3, &length, true) != false) { - ber_read_octet_string(s, &length); /* OCTET STRING */ + ber_read_octet_string_tag(s, &length); /* OCTET STRING */ freerdp_blob_alloc(pubKeyAuth, length); stream_read(s, pubKeyAuth->data, length); } diff --git a/libfreerdp-core/gcc.c b/libfreerdp-core/gcc.c index 6721937..a7fba4f 100644 --- a/libfreerdp-core/gcc.c +++ b/libfreerdp-core/gcc.c @@ -358,9 +358,10 @@ void gcc_write_client_data_blocks(STREAM* s, rdpSettings* settings) gcc_write_client_network_data(s, settings); /* extended client data supported */ - - //if (settings->negotiationFlags) + if (settings->negotiationFlags & EXTENDED_CLIENT_DATA_SUPPORTED) + { gcc_write_client_monitor_data(s, settings); + } } tbool gcc_read_server_data_blocks(STREAM* s, rdpSettings* settings, int length) @@ -1154,8 +1155,8 @@ void gcc_write_client_monitor_data(STREAM* s, rdpSettings* settings) { left = settings->monitors[i].x; top = settings->monitors[i].y; - right = settings->monitors[i].x + settings->monitors[i].width - 1; - bottom = settings->monitors[i].y + settings->monitors[i].height - 1; + right = settings->monitors[i].width; + bottom = settings->monitors[i].height; flags = settings->monitors[i].is_primary ? MONITOR_PRIMARY : 0; stream_write_uint32(s, left); /* left */ diff --git a/libfreerdp-core/ntlmssp.c b/libfreerdp-core/ntlmssp.c index 0069cb4..5a175f0 100644 --- a/libfreerdp-core/ntlmssp.c +++ b/libfreerdp-core/ntlmssp.c @@ -1816,7 +1816,9 @@ int ntlmssp_recv(NTLMSSP* ntlmssp, STREAM* s) stream_read_uint32(s, messageType); if (messageType == 2 && ntlmssp->state == NTLMSSP_STATE_CHALLENGE) + { ntlmssp_recv_challenge_message(ntlmssp, s); + } return 1; } diff --git a/libfreerdp-utils/args.c b/libfreerdp-utils/args.c index 7f010eb..7257472 100644 --- a/libfreerdp-utils/args.c +++ b/libfreerdp-utils/args.c @@ -127,8 +127,8 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, " --secure-checksum: use salted checksums with Standard RDP encryption\n" " --version: print version information\n" " --skip-bs: do not keep backing store\n" - " --multimon-set: hard set monitor list num x y width height isprimary x y...\n" - " two screen example --multimon-set 2 0 0 512 768 512 0 512 768\n" + " --multimon-set: hard set monitor list: <num of monitors> <x> <y> <width> <height> <isprimary>, ...\n" + " two screen example --multimon-set 2 0 0 512 768 1 512 0 512 768 0\n" "\n", argv[0]); return FREERDP_ARGS_PARSE_HELP; //TODO: What is the correct return } @@ -789,18 +789,33 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, int n; settings->num_monitors = atoi(argv[index + 1]); index++; - for (n = 0; n < settings->num_monitors; n++) - { - settings->monitors[n].x = atoi(argv[index + 1]); - index++; - settings->monitors[n].y = atoi(argv[index + 1]); - index++; - settings->monitors[n].width = atoi(argv[index + 1]); - index++; - settings->monitors[n].height = atoi(argv[index + 1]); - index++; - settings->monitors[n].is_primary = atoi(argv[index + 1]); - index++; + + if ((argc - index) <= (settings->num_monitors * 5)) + { + printf("--multimon-set: error, not enough multimon args to parse\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + + if (settings->num_monitors > 1 && settings->num_monitors <= 16) + { + for (n = 0; n < settings->num_monitors; n++) + { + settings->monitors[n].x = atoi(argv[index + 1]); + index++; + settings->monitors[n].y = atoi(argv[index + 1]); + index++; + settings->monitors[n].width = settings->monitors[n].x + atoi(argv[index + 1]) - 1; + index++; + settings->monitors[n].height = settings->monitors[n].y + atoi(argv[index + 1]) - 1; + index++; + settings->monitors[n].is_primary = atoi(argv[index + 1]); + index++; + } + } + else + { + printf("--multimon-set: invalid number of monitors (%d), should be between 2 to 16\n", settings->num_monitors); + return FREERDP_ARGS_PARSE_FAILURE; } } else if (argv[index][0] != '-') |