Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,16 @@ if test x"$HAVE_XRANDR" = "x1"; then
AC_DEFINE(HAVE_XRANDR)
fi

# xinerama
if test -n "$PKG_CONFIG"; then
PKG_CHECK_MODULES(XINERAMA, xinerama, [HAVE_XINERAMA=1], [HAVE_XINERAMA=0])
fi
if test x"$HAVE_XINERAMA" = "x1"; then
CFLAGS="$CFLAGS $XINERAMA_CFLAGS"
LIBS="$LIBS $XINERAMA_LIBS"
AC_DEFINE(HAVE_XINERAMA)
fi

# Xcursor
if test -n "$PKG_CONFIG"; then
PKG_CHECK_MODULES(XCURSOR, xcursor, [HAVE_XCURSOR=1], [HAVE_XCURSOR=0])
Expand Down
10 changes: 10 additions & 0 deletions constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,15 @@ enum RDP_NEG_FAILURE_CODE
SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER = 6
};

enum RDP_NEG_REQ_FLAGS
{
EXTENDED_CLIENT_DATA_SUPPORTED = 1,
DYNVC_GFX_PROTOCOL_SUPPORTED = 2,
NEGRSP_FLAG_RESERVED = 4,
RESTRICTED_ADMIN_MODE_SUPPORTED = 8,
REDIRECTED_AUTHENTICATION_MODE_SUPPORTED = 0x10
};

/* MCS PDU codes */
enum MCS_PDU_TYPE
{
Expand Down Expand Up @@ -168,6 +177,7 @@ enum MCS_DPU_REASON
#define CS_SECURITY 0xc002
#define CS_NET 0xc003
#define CS_CLUSTER 0xc004
#define CS_MONITOR 0xc005

#define SEC_TAG_PUBKEY 0x0006
#define SEC_TAG_KEYSIG 0x0008
Expand Down
41 changes: 28 additions & 13 deletions iso.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ extern RD_BOOL g_encryption_initial;
extern RDP_VERSION g_rdp_version;
extern RD_BOOL g_use_password_as_pin;

static RD_BOOL g_negotiate_rdp_protocol = True;

extern char *g_sc_csp_name;
extern char *g_sc_reader_name;
extern char *g_sc_card_name;
extern char *g_sc_container_name;

extern int g_num_monitors;
extern RD_BOOL g_extended_data_supported;

/* Send a self-contained ISO PDU */
static void
Expand Down Expand Up @@ -62,7 +62,7 @@ iso_send_connection_request(char *username, uint32 neg_proto)
STREAM s;
int length = 30 + strlen(username);

if (g_rdp_version >= RDP_V5 && g_negotiate_rdp_protocol)
if (g_rdp_version >= RDP_V5)
length += 8;

s = tcp_init(length);
Expand All @@ -83,7 +83,7 @@ iso_send_connection_request(char *username, uint32 neg_proto)
out_uint8(s, 0x0d); /* cookie termination string: CR+LF */
out_uint8(s, 0x0a);

if (g_rdp_version >= RDP_V5 && g_negotiate_rdp_protocol)
if (g_rdp_version >= RDP_V5)
{
/* optional RDP protocol negotiation request for RDPv5 */
out_uint8(s, RDP_NEG_REQ);
Expand Down Expand Up @@ -223,7 +223,7 @@ iso_connect(char *server, char *username, char *domain, char *password,
RD_BOOL is_fastpath;
uint8 fastpath_hdr;

g_negotiate_rdp_protocol = True;
RD_BOOL ok_to_reconnect = False;

neg_proto = PROTOCOL_SSL;

Expand All @@ -242,7 +242,7 @@ iso_connect(char *server, char *username, char *domain, char *password,
logger(Core, Verbose, "Connecting to server using SSL...");

retry:
*selected_protocol = PROTOCOL_RDP;
*selected_protocol = neg_proto;
code = 0;

if (!tcp_connect(server))
Expand All @@ -267,29 +267,28 @@ iso_connect(char *server, char *username, char *domain, char *password,
const char *reason = NULL;

uint8 type = 0;
uint8 flags = 0;
uint32 data = 0;

in_uint8(s, type);
in_uint8s(s, 1); /* skip flags */
in_uint8(s, flags); /* skip flags */
in_uint8s(s, 2); /* skip length */
in_uint32(s, data);

if (type == RDP_NEG_FAILURE)
{
RD_BOOL retry_without_neg = False;

switch (data)
{
case SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER:
reason = "SSL with user authentication required by server";
break;
case SSL_NOT_ALLOWED_BY_SERVER:
reason = "SSL not allowed by server";
retry_without_neg = True;
ok_to_reconnect = True;
break;
case SSL_CERT_NOT_ON_SERVER:
reason = "no valid authentication certificate on server";
retry_without_neg = True;
ok_to_reconnect = True;
break;
case INCONSISTENT_FLAGS:
reason = "inconsistent negotiation flags";
Expand All @@ -306,7 +305,7 @@ iso_connect(char *server, char *username, char *domain, char *password,

tcp_disconnect();

if (retry_without_neg)
if (ok_to_reconnect)
{
if (reason != NULL)
{
Expand All @@ -316,7 +315,9 @@ iso_connect(char *server, char *username, char *domain, char *password,
}

logger(Core, Notice, "Retrying with plain RDP.");
g_negotiate_rdp_protocol = False;

neg_proto = PROTOCOL_RDP;

goto retry;
}

Expand All @@ -332,6 +333,20 @@ iso_connect(char *server, char *username, char *domain, char *password,
return False;
}

if (flags & EXTENDED_CLIENT_DATA_SUPPORTED) {
g_extended_data_supported = True;
logger(Protocol, Debug, "Server supports Extended Client Data");
}
else {
g_extended_data_supported = False;
logger(Protocol, Debug, "Server does not support Extended Client Data");
}

if ((g_num_monitors > 1) && !g_extended_data_supported) {
logger(Protocol, Warning, "Got more than 1 monitor but server does not support Extended Client Data");
g_num_monitors = 1;
}

/* handle negotiation response */
if (data == PROTOCOL_SSL)
{
Expand Down
6 changes: 6 additions & 0 deletions rdesktop.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@ RD_BOOL g_pending_resize = False;
RD_BOOL g_pending_resize_defer = True;
struct timeval g_pending_resize_defer_timer = {0};

RD_BOOL g_extended_data_supported = False;

/* According to MS-RDPBCGR 2.2.1.3.6 max value for monitorCount is 16 */
int g_num_monitors = 0;
RDP_MONITOR g_monitors[MAX_MONITORS];

#ifdef WITH_RDPSND
RD_BOOL g_rdpsnd = False;
#endif
Expand Down
2 changes: 2 additions & 0 deletions rdesktop.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@
#define EXRD_WINDOW_CLOSED 62
#define EXRD_UNKNOWN 63

#define MAX_MONITORS 16

#define STRNCPY(dst,src,n) { strncpy(dst,src,n-1); dst[n-1] = 0; }

#ifndef MIN
Expand Down
36 changes: 36 additions & 0 deletions secure.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ uint16 g_server_rdp_version = 0;
static int g_sec_encrypt_use_count = 0;
static int g_sec_decrypt_use_count = 0;

extern int g_num_monitors;
extern RDP_MONITOR g_monitors[MAX_MONITORS];

extern RD_BOOL g_extended_data_supported;

/*
* I believe this is based on SSLv3 with the following differences:
* MAC algorithm (5.2.3.1) uses only 32-bit length in place of seq_num/type/length fields
Expand Down Expand Up @@ -407,6 +412,10 @@ sec_out_mcs_connect_initial_pdu(STREAM s, uint32 selected_protocol)
if (g_num_channels > 0)
length += g_num_channels * 12 + 8;

if ((g_num_monitors > 1) && g_extended_data_supported) {
length += (g_num_monitors * 20) + 12;
}

/* Generic Conference Control (T.124) ConferenceCreateRequest */
out_uint16_be(s, 5);
out_uint16_be(s, 0x14);
Expand Down Expand Up @@ -507,6 +516,33 @@ sec_out_mcs_connect_initial_pdu(STREAM s, uint32 selected_protocol)
}
}

/* 2.2.1.3.6 Client Monitor Data (TS_UD_CS_MONITOR) */
if ((g_num_monitors > 1) && g_extended_data_supported) {
int lengthMonitors, n;

logger(Protocol, Debug, "Informing server about %d monitors\n", g_num_monitors);
out_uint16_le(s, CS_MONITOR); /* User Data Header type */

lengthMonitors = 12 + (20 * g_num_monitors);
out_uint16_le(s, lengthMonitors);
out_uint32_le(s, 0); /* flags (unused) */
out_uint32_le(s, g_num_monitors); /* monitorCount */
for (n = 0; n < g_num_monitors; n++) {
out_uint32_le(s, g_monitors[n].x); /* left */
out_uint32_le(s, g_monitors[n].y); /* top */
out_uint32_le(s, g_monitors[n].x +
g_monitors[n].width-1); /* right */
out_uint32_le(s, g_monitors[n].y +
g_monitors[n].height-1); /* bottom */
out_uint32_le(s, g_monitors[n].is_primary ? 1 : 0); /* isPrimary */
logger(Protocol, Debug, "Setting monitors %d %dx%d at %d,%d rect(l:%d,t:%d,r:%d,b:%d)\n",
n,g_monitors[n].width,g_monitors[n].height,g_monitors[n].x,g_monitors[n].y,
g_monitors[n].x, g_monitors[n].y,
g_monitors[n].x + g_monitors[n].width-1, g_monitors[n].y +g_monitors[n].height-1
);
}
}

s_mark_end(s);
}

Expand Down
10 changes: 10 additions & 0 deletions types.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,16 @@ typedef struct fileinfo
}
FILEINFO;

typedef struct rdp_monitor
{
int x;
int y;
int width;
int height;
RD_BOOL is_primary;
} RDP_MONITOR;


typedef RD_BOOL(*str_handle_lines_t) (const char *line, void *data);

typedef enum {
Expand Down
Loading