Skip to content

Commit 67f1dcf

Browse files
committed
Send INFOTYPE_LOGON to support vmconnect resize
INFOTYPE_LOGON or a variant is usually sent after the user has successfully logged in. This triggers a hook in vmconnect that enables automatic resizing, and also allows msrdc (the other RDP client) to accept connections to new servers.
1 parent 832edca commit 67f1dcf

8 files changed

Lines changed: 135 additions & 6 deletions

File tree

common/ms-rdpbcgr.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,12 @@
592592
#define CMDTYPE_FRAME_MARKER 0x0004
593593
#define CMDTYPE_STREAM_SURFACE_BITS 0x0006
594594

595+
/* Save Session Info PDU Data (2.2.10) */
596+
#define INFOTYPE_LOGON 0x00000000
597+
#define INFOTYPE_LOGON_LONG 0x00000001
598+
#define INFOTYPE_LOGON_PLAINNOTIFY 0x00000002
599+
#define INFOTYPE_LOGON_EXTENDED_INFO 0x00000003
600+
595601
/* Compression Flags (3.1.8.2.1) */
596602
/* TODO: to be renamed, not used anywhere */
597603
#define RDP_MPPC_COMPRESSED 0x20

common/xrdp_client_info.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ struct xrdp_client_info
147147
int desktop_cache;
148148
int use_compact_packets; /* rdp5 smaller packets */
149149
char client_name[INFO_CLIENT_NAME_BYTES_UTF8];
150+
int long_credentials_supported;
150151
int build;
151152
int keylayout;
152153
char username[INFO_CLIENT_MAX_CB_LEN];
@@ -156,6 +157,7 @@ struct xrdp_client_info
156157
char directory[INFO_CLIENT_MAX_CB_LEN];
157158
int rdp_compression;
158159
int rdp_autologin;
160+
int rdp_logonnotify;
159161
int crypt_level; /* 1, 2, 3 = low, medium, high */
160162
int channels_allowed; /* 0 = no channels 1 = channels */
161163
int sound_code; /* 1 = leave sound at server */

libxrdp/xrdp_caps.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ xrdp_caps_process_general(struct xrdp_rdp *self, struct stream *s,
107107
self->client_info.op1 = extraFlags & NO_BITMAP_COMPRESSION_HDR;
108108
/* use_compact_packets is pretty much 'use rdp5' */
109109
self->client_info.use_compact_packets = (extraFlags != 0);
110+
/* LONG_CREDENTIALS_SUPPORTED is used when sending session info */
111+
self->client_info.long_credentials_supported = (extraFlags & LONG_CREDENTIALS_SUPPORTED) != 0;
110112
/* op2 is a boolean to use compact bitmap headers in bitmap cache */
111113
/* set it to same as 'use rdp5' boolean */
112114
self->client_info.op2 = self->client_info.use_compact_packets;

libxrdp/xrdp_iso.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ xrdp_iso_create(struct xrdp_mcs *owner, struct trans *trans)
7373
self->mcs_layer = owner;
7474
self->trans = trans;
7575

76+
#ifndef VMCONNECT_FORCE
7677
// See if we're running in vmconnect mode on this connection
7778
struct xrdp_client_info *client_info = &(self->mcs_layer->sec_layer->rdp_layer->client_info);
7879
if (client_info->vmconnect && trans->mode != TRANS_MODE_VSOCK)
@@ -83,6 +84,7 @@ xrdp_iso_create(struct xrdp_mcs *owner, struct trans *trans)
8384
desc);
8485
client_info->vmconnect = 0;
8586
}
87+
#endif
8688
return self;
8789
}
8890

libxrdp/xrdp_rdp.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,7 @@ xrdp_rdp_send_data_from_channel(struct xrdp_rdp *self, struct stream *s,
619619
pdulen = len;
620620
dlen = len;
621621
ctype = 0;
622-
clen = len;
622+
clen = 0; /* When not using compression: the compressed length is 0 */
623623
tocomplen = pdulen - 18;
624624

625625
if (compress && self->client_info.rdp_compression &&
@@ -1683,11 +1683,15 @@ xrdp_rdp_send_session_info(struct xrdp_rdp *self, const char *data,
16831683

16841684
out_uint8a(s, data, data_bytes);
16851685
s_mark_end(s);
1686-
LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_SAVE_SESSION_INFO_PDU_DATA "
1687-
"infoType 0x%8.8x, infoData <omitted from log>",
1688-
*((unsigned int *) data));
1689-
1690-
if (xrdp_rdp_send_data(self, s, PDUTYPE2_SAVE_SESSION_INFO) != 0)
1686+
LOG(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_SAVE_SESSION_INFO_PDU_DATA "
1687+
"infoType 0x%8.8x, infoData <omitted from log> (%u bytes)",
1688+
*((unsigned int *) data),
1689+
data_bytes);
1690+
1691+
/* [MS-RDPBCGR] sect 3.3.5.10.1 - Sending Save Session Info PDU:
1692+
* "The contents of this PDU SHOULD NOT be compressed." */
1693+
if (xrdp_rdp_send_data_from_channel(self, s, PDUTYPE2_SAVE_SESSION_INFO,
1694+
self->mcs_channel, 0) != 0)
16911695
{
16921696
LOG(LOG_LEVEL_ERROR, "Sending [MS-RDPBCGR] TS_SAVE_SESSION_INFO_PDU_DATA failed");
16931697
free_stream(s);

libxrdp/xrdp_sec.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,12 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
448448
}
449449
}
450450

451+
if (flags & INFO_LOGONNOTIFY)
452+
{
453+
LOG_DEVEL(LOG_LEVEL_DEBUG, "[MS-RDPBCGR] TS_INFO_PACKET flag INFO_LOGONNOTIFY found");
454+
self->rdp_layer->client_info.rdp_logonnotify = 1;
455+
}
456+
451457
if (flags & INFO_COMPRESSION)
452458
{
453459
LOG_DEVEL(LOG_LEVEL_DEBUG, "[MS-RDPBCGR] TS_INFO_PACKET flag INFO_COMPRESSION found, "

xrdp/xrdp_mm.c

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3207,6 +3207,106 @@ xrdp_mm_display_server_connect(struct xrdp_mm *self)
32073207
return rv;
32083208
}
32093209

3210+
/*****************************************************************************/
3211+
static int
3212+
xrdp_mm_send_save_session_info(struct xrdp_mm *self)
3213+
{
3214+
int rv = 0;
3215+
int bytes;
3216+
const char *username;
3217+
size_t username_len;
3218+
struct stream *s;
3219+
3220+
make_stream(s);
3221+
init_stream(s, 8192);
3222+
3223+
/* Get username */
3224+
if ((username = xrdp_mm_get_value(self, "username")) == NULL)
3225+
{
3226+
username = "???";
3227+
username_len = 3;
3228+
}
3229+
else
3230+
{
3231+
username_len = g_strlen(username);
3232+
}
3233+
/* Check for overflow */
3234+
if (username_len > INFO_CLIENT_MAX_CB_LEN - 2)
3235+
{
3236+
rv = 1;
3237+
xrdp_wm_log_msg(self->wm, LOG_LEVEL_ERROR, "Username too big !");
3238+
goto cleanup;
3239+
}
3240+
3241+
/* [MS-RDPBCGR] sect 3.3.5.10.1 - Sending Save Session Info PDU */
3242+
3243+
/* "A logon notification of type INFOTYPE_LOGON or INFOTYPE_LOGON_LONG SHOULD
3244+
* be sent if the INFO_LOGONNOTIFY flag was set by the client
3245+
* in the Client Info PDU or if the username or domain used to log on to
3246+
* the session is different from what was sent in the Client Info PDU." */
3247+
3248+
if ((self->wm->client_info->rdp_logonnotify ||
3249+
g_strcmp(self->wm->client_info->username, username) != 0) && 0)
3250+
{
3251+
/* We should send a logon notification */
3252+
if (!self->wm->client_info->long_credentials_supported)
3253+
{
3254+
xrdp_wm_log_msg(self->wm, LOG_LEVEL_DEBUG,
3255+
"Sending Session Info 'INFOTYPE_LOGON'");
3256+
/* infoType */
3257+
out_uint32_le(s, INFOTYPE_LOGON);
3258+
/* [MS-RDPBCGR] sect 2.2.10.1.1.1 */
3259+
out_uint32_le(s, 2); /* cbDomain */
3260+
out_uint8s(s, 52); /* Domain (empty) */
3261+
out_uint32_le(s, username_len + 2); /* cbUserName */
3262+
out_utf8_as_utf16_le(s, username,
3263+
username_len); /* Username */
3264+
out_uint8s(s, 512 - 2 - username_len); /* Delimiter + pad */
3265+
out_uint32_le(s, 0); /* SessionId */
3266+
}
3267+
else
3268+
{
3269+
xrdp_wm_log_msg(self->wm, LOG_LEVEL_DEBUG,
3270+
"Sending Session Info 'INFOTYPE_LOGON_LONG'");
3271+
/* infoType */
3272+
out_uint32_le(s, INFOTYPE_LOGON_LONG);
3273+
/* [MS-RDPBCGR] sect 2.2.10.1.1.2 */
3274+
out_uint32_le(s, 0x0001); /* Version */
3275+
out_uint32_le(s, 574); /* Size */
3276+
out_uint32_le(s, 0); /* SessionId */
3277+
out_uint32_le(s, 2); /* cbDomain */
3278+
out_uint32_le(s, username_len + 2); /* cbUserName */
3279+
out_uint8s(s, 558); /* Pad */
3280+
out_uint8s(s, 2); /* Domain (empty) */
3281+
out_utf8_as_utf16_le(s, username,
3282+
username_len); /* Username */
3283+
out_uint8s(s, 2); /* Delimiter */
3284+
}
3285+
}
3286+
else
3287+
{
3288+
/* "A logon notification of type INFOTYPE_LOGON_PLAINNOTIFY SHOULD be sent whenever
3289+
* a notification of type INFOTYPE_LOGON or INFOTYPE_LOGON_LONG would not be sent." */
3290+
3291+
xrdp_wm_log_msg(self->wm, LOG_LEVEL_DEBUG,
3292+
"Sending Session Info 'INFOTYPE_LOGON_PLAINNOTIFY'");
3293+
3294+
/* infoType */
3295+
out_uint32_le(s, INFOTYPE_LOGON_PLAINNOTIFY);
3296+
/* [MS-RDPBCGR] sect 2.2.10.1.1.3 */
3297+
out_uint8s(s, 576); /* Pad */
3298+
}
3299+
s_mark_end(s);
3300+
3301+
/* send to client */
3302+
bytes = (int) (s->end - s->data);
3303+
self->mod->server_session_info(self->mod, s->data, bytes);
3304+
3305+
cleanup:
3306+
free_stream(s);
3307+
return rv;
3308+
}
3309+
32103310
/**************************************************************************//**
32113311
* Initialise and start the connect sequence
32123312
*
@@ -3532,6 +3632,12 @@ xrdp_mm_connect_sm(struct xrdp_mm *self)
35323632
}
35333633
break;
35343634

3635+
case MMCS_SEND_SESSIONINFO:
3636+
{
3637+
status = xrdp_mm_send_save_session_info(self);
3638+
}
3639+
break;
3640+
35353641
case MMCS_DONE:
35363642
{
35373643
/* Shouldn't get here */

xrdp/xrdp_types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ enum mm_connect_state
350350
MMCS_GET_SESSION_FILE_DESCRIPTORS,
351351
MMCS_CONNECT_TO_DISPLAY_SERVER,
352352
MMCS_CONNECT_TO_CHANSRV,
353+
MMCS_SEND_SESSIONINFO,
353354
MMCS_DONE
354355
};
355356

0 commit comments

Comments
 (0)