Skip to content

Commit d270ee9

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 42b830f commit d270ee9

8 files changed

Lines changed: 136 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: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ 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;
151+
char hostname[32];
150152
int build;
151153
int keylayout;
152154
char username[INFO_CLIENT_MAX_CB_LEN];
@@ -156,6 +158,7 @@ struct xrdp_client_info
156158
char directory[INFO_CLIENT_MAX_CB_LEN];
157159
int rdp_compression;
158160
int rdp_autologin;
161+
int rdp_logonnotify;
159162
int crypt_level; /* 1, 2, 3 = low, medium, high */
160163
int channels_allowed; /* 0 = no channels 1 = channels */
161164
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
@@ -3224,6 +3224,106 @@ xrdp_mm_display_server_connect(struct xrdp_mm *self)
32243224
return rv;
32253225
}
32263226

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

3652+
case MMCS_SEND_SESSIONINFO:
3653+
{
3654+
status = xrdp_mm_send_save_session_info(self);
3655+
}
3656+
break;
3657+
35523658
case MMCS_DONE:
35533659
{
35543660
/* 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)