Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/neutrinolabs/NeutrinoRDP.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIdan Freiberg <speidy@gmail.com>2016-04-16 14:03:48 +0300
committerIdan Freiberg <speidy@gmail.com>2016-04-16 14:03:48 +0300
commit41954517e4ae984239afb0828dbdc71547cee311 (patch)
tree8f7b4437f85cf385ca70acd4ff1d1a8aeeb2afe9
parenta64fef8d1519e68735153a42f226162e9b7069cf (diff)
parent67ea8cae60cf6b1023f5c475d0f79e1652d93a10 (diff)
Merge pull request #6 from Osirium/devel
Osirium Fixes
-rw-r--r--client/X11/xf_monitor.c2
-rw-r--r--libfreerdp-core/ber.c248
-rw-r--r--libfreerdp-core/ber.h21
-rw-r--r--libfreerdp-core/credssp.c183
-rw-r--r--libfreerdp-core/gcc.c9
-rw-r--r--libfreerdp-core/ntlmssp.c2
-rw-r--r--libfreerdp-utils/args.c43
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] != '-')