Merge branch 'devel' into v0.9

This commit is contained in:
Koichiro IWAO 2020-08-31 16:07:07 +09:00
commit 8faaa57cd7
52 changed files with 2775 additions and 372 deletions

View File

@ -12,7 +12,7 @@ addons:
# This is required to use a version of cppcheck other than that
# suplied with the operating system
cppcheck_defs: &cppcheck_defs
- CPPCHECK_VER=1.90
- CPPCHECK_VER=2.1
- CPPCHECK_REPO=https://github.com/danmar/cppcheck.git
min_amd64_deps: &min_amd64_deps
@ -53,6 +53,17 @@ max_amd64_conf: &max_amd64_conf
packages:
- *max_amd64_deps
max_debug_amd64_conf: &max_debug_amd64_conf
env:
- CONF_FLAGS="--enable-ipv6 --enable-jpeg --enable-fuse --enable-mp3lame
--enable-fdkaac --enable-opus --enable-rfxcodec --enable-painter
--enable-pixman --enable-xrdpdebug"
- DISTCHECK=1
addons:
apt:
packages:
- *max_amd64_deps
max_x86_deps: &max_x86_deps
- *common_deps
- g++-multilib
@ -92,10 +103,11 @@ cppcheck_conf: &cppcheck_conf
env:
- *cppcheck_defs
# addons:
# apt:
# packages:
# - cppcheck
addons:
apt:
packages:
- libz3-dev
- z3
script:
- ./bootstrap
@ -122,6 +134,10 @@ matrix:
- compiler: clang
<< : *max_amd64_conf
# Maximal debug amd64 build
- compiler: gcc
<< : *max_debug_amd64_conf
# Maximal x86 build
- compiler: gcc
<< : *max_x86_conf
@ -138,5 +154,5 @@ matrix:
script:
- ./bootstrap
- ./configure $CONF_FLAGS
- make CFLAGS="$CFLAGS -O2 -Wall -Wwrite-strings -Werror"
- make CFLAGS="$CFLAGS"
- test -z "$DISTCHECK" || make distcheck

31
NEWS.md
View File

@ -1,3 +1,34 @@
# Release notes for xrdp v0.9.14 (2020/08/31)
## New features
* VNC multi-monitor support if you are using a suitable Xvnc server #1343
* VNC sessions now resize by default on reconnection if you are using a suitable Xvnc server #1343
* Support Slackware for PAM #1558 #1560
* Support Programmer Dvorak Keyboard #1663
**[HEADS UP]** The VNC changes are significant. They described in more detail on the following wiki page.
* [Xvnc backend : Multi monitor and resize support](https://github.com/neutrinolabs/xrdp/wiki/Xvnc-backend-:-Multi-monitor-and-resize-support)
## Bug fixes
* Fix odd shift key behavior (workaround) #397 #1522
* Fix Xorg path in the document for Arch Linux #1448 #1529
* Fix Xorg path in the document for CentOS 8 #1646 #1647
* Fix internal username/password buffer is smaller than RDP protocol specification #1648 #1653
* Fix possible memory out-of-bounds accesses #1549
* Fix memory allocation overflow #1557
* Prevent chansrv input channels being scanned during a server reset #1595
* Ignore TS_MULTIFRAGMENTUPDATE_CAPABILITYSET from client if fp disabled #1593
* Minor manpage fixes #1611
## Other changes
* CI error fixes
* Introduce cppcheck
## Known issues
* FreeRDP 2.0.0-rc4 or later might not able to connect to xrdp due to
xrdp's bad-mannered behaviour, add `+glyph-cache` option to FreeRDP to connect #1266
* Audio redirection by MP3 codec doesn't sound with some client, use AAC instead #965
# Release notes for xrdp v0.9.13.1 (2020/06/30)
This is a security fix release that includes fixes for the following local buffer overflow vulnerability.

View File

@ -2,7 +2,7 @@
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/neutrinolabs/xrdp-questions)
![Apache-License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)
*Current Version:* 0.9.13.1
*Current Version:* 0.9.14
# xrdp - an open source RDP server

14
SECURITY.md Normal file
View File

@ -0,0 +1,14 @@
# Security Policy
## Reporting a Vulnerability
Please DO NOT report any security issues to public GitHub issue.
If you find a security vulnerability please kindly inform us about the problem immediately
so that we can fix the security problem to protect a lot of users around the world as soon
as possible.
Our email eddress for security report is:
* [xrdp-core@googlegroups.com](mailto:xrdp-core@googlegroups.com)

View File

@ -569,6 +569,7 @@ log_message(const enum logLevels lvl, const char *msg, ...)
if (len > LOG_BUFFER_SIZE)
{
log_message(LOG_LEVEL_WARNING, "next message will be truncated");
len = LOG_BUFFER_SIZE;
}
/* forcing the end of message string */

View File

@ -114,7 +114,7 @@ internal_log_lvl2str(const enum logLevels lvl, char *str);
*
*/
enum logLevels
internal_log_text2level(const char *s);
internal_log_text2level(const char *buf);
/**
* A function that init our struct that holds all state and

View File

@ -74,8 +74,11 @@
#define CONNECTION_TYPE_LAN 0x06
#define CONNECTION_TYPE_AUTODETECT 0x07
/* Virtual channel options */
/* Channel Definition Structure: options (2.2.1.3.4.1) */
/* Channel definition structure CHANNEL_DEF (2.2.1.3.4.1) */
/* This isn't explicitly named in MS-RDPBCGR */
#define CHANNEL_NAME_LEN 7
/* Oprions field */
/* NOTE: XR_ prefixed to avoid conflict with FreeRDP */
#define XR_CHANNEL_OPTION_INITIALIZED 0x80000000
#define XR_CHANNEL_OPTION_ENCRYPT_RDP 0x40000000

View File

@ -2896,6 +2896,12 @@ g_strtrim(char *str, int trim_flags)
text = (wchar_t *)malloc(len * sizeof(wchar_t) + 8);
text1 = (wchar_t *)malloc(len * sizeof(wchar_t) + 8);
if (text == NULL || text1 == NULL)
{
free(text);
free(text1);
return 1;
}
text1_index = 0;
mbstowcs(text, str, len + 1);

View File

@ -83,8 +83,16 @@
#define GOOD_RECT(rect) ((rect)->x1 < (rect)->x2 && (rect)->y1 < (rect)->y2)
#define BAD_RECT(rect) ((rect)->x1 > (rect)->x2 || (rect)->y1 > (rect)->y2)
/* This file is included by pixman-region16.c which defines PREFIX(x).
* This check allows cppcheck 2.x to scan this file separately */
#ifndef PREFIX
#define PREFIX(x) pixman_region##x
#endif
#ifdef XRDP_DEBUG
pixman_bool_t PREFIX(_selfcheck) (region_type_t *reg);
#define GOOD(reg) \
do \
{ \

View File

@ -452,17 +452,14 @@ trans_force_read_s(struct trans *self, struct stream *in_s, int size)
{
int rcvd;
if (self->status != TRANS_STATUS_UP)
if (self->status != TRANS_STATUS_UP ||
size < 0 || !s_check_rem_out(in_s, size))
{
return 1;
}
while (size > 0)
{
/* make sure stream has room */
if ((in_s->end + size) > (in_s->data + in_s->size))
{
return 1;
}
rcvd = self->trans_recv(self, in_s->end, size);
if (rcvd == -1)
{

View File

@ -18,6 +18,8 @@
* xrdp / xserver info / caps
*/
#include "xrdp_constants.h"
#if !defined(XRDP_CLIENT_INFO_H)
#define XRDP_CLIENT_INFO_H
@ -57,11 +59,11 @@ struct xrdp_client_info
char hostname[32];
int build;
int keylayout;
char username[256];
char password[256];
char domain[256];
char program[256];
char directory[256];
char username[INFO_CLIENT_MAX_CB_LEN];
char password[INFO_CLIENT_MAX_CB_LEN];
char domain[INFO_CLIENT_MAX_CB_LEN];
char program[INFO_CLIENT_MAX_CB_LEN];
char directory[INFO_CLIENT_MAX_CB_LEN];
int rdp_compression;
int rdp_autologin;
int crypt_level; /* 1, 2, 3 = low, medium, high */

View File

@ -38,6 +38,11 @@
******************************************************************************/
#define INFO_CLIENT_NAME_BYTES 32
/**
* Maximum length of a string including the mandatory null terminator
* [MS-RDPBCGR] TS_INFO_PACKET(2.2.1.11.1.1)
*/
#define INFO_CLIENT_MAX_CB_LEN 512
#define XRDP_MAX_BITMAP_CACHE_ID 3
#define XRDP_MAX_BITMAP_CACHE_IDX 2000

View File

@ -1,7 +1,7 @@
# Process this file with autoconf to produce a configure script
AC_PREREQ(2.65)
AC_INIT([xrdp], [0.9.13.1], [xrdp-devel@googlegroups.com])
AC_INIT([xrdp], [0.9.14], [xrdp-devel@googlegroups.com])
AC_CONFIG_HEADERS(config_ac.h:config_ac-h.in)
AM_INIT_AUTOMAKE([1.7.2 foreign])
AC_CONFIG_MACRO_DIR([m4])
@ -19,11 +19,6 @@ AC_CONFIG_SUBDIRS([libpainter librfxcodec])
# Use silent rules by default if supported by Automake
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
AX_CFLAGS_WARN_ALL
AX_APPEND_COMPILE_FLAGS([-Wwrite-strings])
AX_GCC_FUNC_ATTRIBUTE([format])
AX_TYPE_SOCKLEN_T
case $host_os in
*linux*)
linux=yes
@ -155,6 +150,19 @@ AC_ARG_ENABLE(rdpsndaudin, AS_HELP_STRING([--enable-rdpsndaudin],
[], [enable_rdpsndaudin=no])
AM_CONDITIONAL(XRDP_RDPSNDAUDIN, [test x$enable_rdpsndaudin = xyes])
# configure compiler options and CFLAGS
AX_GCC_FUNC_ATTRIBUTE([format])
AX_TYPE_SOCKLEN_T
AX_CFLAGS_WARN_ALL
AX_APPEND_COMPILE_FLAGS([-Wwrite-strings])
AM_COND_IF([LINUX],
[AX_APPEND_COMPILE_FLAGS([-Werror])]) # bsd has warnings that have not been fixed yet
AM_COND_IF([XRDP_DEBUG],
[AX_APPEND_COMPILE_FLAGS([-g -O0])],
[AX_APPEND_COMPILE_FLAGS([-O2])])
# Don't fail without working nasm if rfxcodec is not enabled
if test "x$enable_rfxcodec" != xyes; then
with_simd=no
@ -243,11 +251,6 @@ then
[AC_MSG_ERROR([please install libjpeg-dev or libjpeg-devel])])
fi
if test "x$enable_xrdpdebug" = "xyes"
then
CFLAGS="-g -O0"
fi
# checking for fuse
if test "x$enable_fuse" = "xyes"
then

View File

@ -133,27 +133,30 @@ Sets the maximum number of simultaneous sessions. If not set or set to
\fBKillDisconnected\fR=\fI[true|false]\fR
If set to \fB1\fR, \fBtrue\fR or \fByes\fR, every session will be killed
within 60 seconds after the user disconnects.
This setting currently only works with xorgxrdp sessions.
.TP
\fBDisconnectedTimeLimit\fR=\fInumber\fR
Sets the time limit (in seconds) before a disconnected session is killed.
If set to \fI0\fR, automatic killing is disabled.
Sets the time limit for \fBKillDisconnected\fR to a value greater than 60.
Values less than 60 cannot be set. You do not actually have to specify
\fBKillDisconnected\fR if you set this value.
This setting currently only works with xorgxrdp sessions.
.TP
\fBIdleTimeLimit\fR=\fInumber\fR
Sets the time limit (in seconds) before an idle session is disconnected.
Idle means no keyboard inputs and no mouse moves/clicks here.
If set to \fI0\fR, idle sessions will never be disconnected by timeout.
This works only with xorgxrdp session. Moreover, xorgxrdp must be v0.2.9 or later.
This works only with xorgxrdp sessions. Moreover, xorgxrdp must be v0.2.9 or later.
.TP
\fBPolicy\fR=\fI[Default|UBD|UBI|UBC|UBDI|UBDC]\fR
Session allocation policy. By default, a new session is created
for the combination <User,BitPerPixel> when using Xrdp, and
for the combination <User,BitPerPixel,DisplaySize> when using Xvnc.
This behavior can be changed by setting session policy to:
Session allocation policy. Used to decide when to allocate a
new session. Set to one of the following values:
.br
.br
\fBDefault\fR - session per <User,BitPerPixel>
.br
\fBUBD\fR - session per <User,BitPerPixel,DisplaySize>
.br
@ -168,7 +171,8 @@ This behavior can be changed by setting session policy to:
.br
Note that the \fBUser\fR and \fBBitPerPixel\fR criteria cannot be turned
off. For Xvnc connections, \fBDisplaySize\fR is always enabled as well.
off. \fBDisplaySize\fR refers to the initial geometry of a connection,
as actual display sizes can change dynamically.
.br
.SH "SECURITY"

View File

@ -17,11 +17,11 @@ to get the default host and display number.
.SH FILES
.TP
.I @socketdir@/xrdp_disconnect_display_*
UNIX socket used to communicate with the \fBxrdp\fP(8) session manager.
UNIX socket used to communicate the disconnect request to xorgxrdp.
.SH KNOWN ISSUES
.TP
This utility doesn't support disconnecting xorgxrdp sessions so far.
This utility doesn't support disconnecting Xvnc sessions so far.
.SH SEE ALSO
.BR xrdp (8).

View File

@ -302,6 +302,14 @@ Specifies color depth of the backend X server. The default is the color
depth of the client. Only Xvnc and X11rdp use that setting. Xorg runs at
\fI24\fR bpp.
.TP
\fBdisabled_encodings_mask\fR=\fI<number>\fR
Set this bitmask to a non-zero value to prevent \fBxrdp\fR(8) requesting
some features from the Xvnc server. You should only need to set this
to a non-zero value to work around bugs in your Xvnc server. The bit
values supported for a particular release of \fBxrdp\fR(8) are documented in
\fBxrdp.ini\fR.
.TP
\fBcode\fR=\fI<number>\fR|\fI0\fR
Specifies the session type. The default, \fI0\fR, is Xvnc, \fI10\fR is

View File

@ -32,3 +32,25 @@ Q. I get an error: "rail.c:31:35: fatal error: X11/extensions/Xrandr.h: No such
A. You need to install the Xrandr development package.
For Debian / Ubuntu this package is called libxrandr-dev.
For SUSE / openSUSE this package is called libXrandr-devel.
Q. How do I configure the same continuous integration bulids for my XRDP fork as the official XRDP repository?
A. The XRDP project uses both Travis-CI.org and Cirrus-CI.com for continuous integration.
Both of these services are free for open source projects (both the official
repository and forks), and these services integrate with Github to build any
changes pushed to public Github repositories.
To configure Travis CI for your XRDP fork on github:
1. Follow Travis CI instructions for connecting your github account to Travis CI
https://docs.travis-ci.com/user/tutorial/#to-get-started-with-travis-ci-using-github
2. In the Travis CI dashboard setting page select your XRDP fork repository for building pushed branches.
3. Push a commit to a branch in your XRDP fork on github and Travis CI should
start building the branch because the XRDP repository already contain a .travis.yml file.
To configure Cirrus CI for your XRDP fork on github:
1. Follow Cirrus CI instructions for connecting your github account to Cirrus CI
https://cirrus-ci.org/guide/quick-start/
2. In the Github setting page for the Cirrus CI application, enable Cirrus CI
access to your XRDP fork repository.
3. Push a commit to a branch in your XRDP fork on github and Cirrus CI should
start building the branch because the XRDP repository already contain a .cirrus.yml file.

View File

@ -15,6 +15,12 @@ setxkbmap -model pc104 -layout us
setxkbmap -model pc104 -layout dvorak
./xrdp-genkeymap ../instfiles/km-00010409.ini
# English - US 'dvp' 0x19360409
OLD_SETTINGS=$(setxkbmap -query -verbose 4 | sed "s/^\([a-z]\+\):\s*\(.*\)$/-\1 \2/;s/^-options/-option \"\" -option/;s/,/ -option /g" | xargs -d \\n)
setxkbmap -rules xfree86 -model pc105 -layout us -variant dvp -option "" -option compose:102 -option caps:shift -option numpad:sg -option numpad:shift3 -option keypad:hex -option keypad:atm -option kpdl:semi -option lv3:ralt_alt
./xrdp-genkeymap ../instfiles/km-19360409.ini
setxkbmap ${OLD_SETTINGS}
# English - UK 'en-GB' 0x00000809
setxkbmap -model pc105 -layout gb
./xrdp-genkeymap ../instfiles/km-00000809.ini

View File

@ -136,7 +136,7 @@ int main(int argc, char **argv)
fprintf(outf, "[%s]\n", sections[idx]);
e.state = states[idx];
for (i = 8; i <= 137; i++) /* Keycodes */
for (i = 8; i < 137; i++) /* Keycodes */
{
if (is_evdev)
e.keycode = xfree86_to_evdev[i-8];

View File

@ -50,7 +50,8 @@ dist_startscript_DATA = \
km-00000813.ini \
km-00000816.ini \
km-0000100c.ini \
km-00010409.ini
km-00010409.ini \
km-19360409.ini
#
# platform specific files

1047
instfiles/km-19360409.ini Normal file

File diff suppressed because it is too large Load Diff

View File

@ -10,51 +10,87 @@ service="xrdp-sesman"
pamdir="/etc/pam.d"
pamdir_suse="/usr/etc/pam.d"
# Modules needed by xrdp-sesman.unix, if we get to that
unix_modules_needed="pam_unix.so pam_env.so pam_nologin.so"
# Directories where pam modules might be installed
# Add to this list as platforms are added
pam_module_dir_searchpath="/lib*/security /usr/lib*/security /lib/*/security /usr/lib/*/security"
find_pam_module_dir()
{
# Looks for the pam security module directory
set -- $pam_module_dir_searchpath
for d in "$@"; do
if [ -s $d/pam_unix.so ]; then
echo $d
break
fi
done
}
can_apply_unix_config()
{
result=0
module_dir="$1"
for m in $unix_modules_needed; do
if [ ! -s $module_dir/$m ]; then
echo " ** $m not found" >&2
result=1
fi
done
return $result
}
guess_rules ()
{
if test -s "$pamdir/password-auth"; then
rules=
if [ -s "$pamdir/password-auth" ]; then
rules="redhat"
return
fi
if test -s "$pamdir_suse/common-account"; then
elif [ -s "$pamdir_suse/common-account" ]; then
rules="suse"
return
fi
if test -s "$pamdir/common-account"; then
elif [ -s "$pamdir/common-account" ]; then
if grep "^@include" "$pamdir/passwd" >/dev/null 2>&1; then
rules="debian"
else
rules="suse"
fi
return
fi
if test ! -f "$pamdir/system-auth" -a -s "$pamdir/system"; then
elif [ ! -f "$pamdir/system-auth" -a -s "$pamdir/system" ]; then
rules="freebsd"
return
fi
if test -s "$pamdir/authorization"; then
elif [ -s "$pamdir/authorization" ]; then
rules="macos"
return
fi
if test -s "$pamdir/system-remote-login"; then
elif [ -s "$pamdir/system-remote-login" ]; then
rules="arch"
return
fi
rules="unix"
return
elif [ -s "$pamdir/system-auth" ]; then
rules="system"
else
module_dir=`find_pam_module_dir`
if [ -d "$module_dir" ]; then
#echo "- Found pam modules in $module_dir" >&2
if can_apply_unix_config "$module_dir" ; then
rules="unix"
fi
fi
fi
}
if test "$rules" = "auto"; then
if [ "$rules" = "auto" ]; then
guess_rules
if [ -z "$rules" ]; then
echo "** Can't guess PAM rules for this system"
exit 1
fi
fi
if test -s "$srcdir/$service.$rules"; then
if [ -s "$srcdir/$service.$rules" ]; then
ln -nsf "$srcdir/$service.$rules" "$outfile"
else
echo "Cannot find $srcdir/$service.$rules"

View File

@ -0,0 +1,5 @@
#%PAM-1.0
auth include system-auth
account include system-auth
password include system-auth
session include system-auth

View File

@ -1,5 +1,16 @@
#%PAM-1.0
auth include system-auth
account include system-auth
password include system-auth
session include system-auth
#
# Really basic authentication set when nothing else is available
#
# You may need to edit this to suit your system depending on the
# required functionality.
#
auth required pam_unix.so shadow
auth required pam_env.so
password required pam_unix.so
account required pam_unix.so
account required pam_nologin.so
session required pam_unix.so

View File

@ -47,6 +47,7 @@ libxrdp_init(tbus id, struct trans *trans)
session->rdp = xrdp_rdp_create(session, trans);
session->orders = xrdp_orders_create(session, (struct xrdp_rdp *)session->rdp);
session->client_info = &(((struct xrdp_rdp *)session->rdp)->client_info);
session->check_for_app_input = 1;
return session;
}
@ -125,24 +126,18 @@ libxrdp_force_read(struct trans* trans)
if (trans_force_read(trans, 4) != 0)
{
g_writeln("libxrdp_force_read: error");
g_writeln("libxrdp_force_read: header read error");
return 0;
}
bytes = libxrdp_get_pdu_bytes(s->data);
if (bytes < 1)
if (bytes < 4 || bytes > s->size)
{
g_writeln("libxrdp_force_read: error");
g_writeln("libxrdp_force_read: bad header length %d", bytes);
return 0;
}
if (bytes > 32 * 1024)
{
g_writeln("libxrdp_force_read: error");
return 0;
}
if (trans_force_read(trans, bytes - 4) != 0)
{
g_writeln("libxrdp_force_read: error");
g_writeln("libxrdp_force_read: Can't read PDU");
return 0;
}
return s;
@ -1049,29 +1044,36 @@ libxrdp_orders_send_font(struct xrdp_session *session,
}
/*****************************************************************************/
/* Note : if this is called on a multimon setup, the client is resized
* to a single monitor */
int EXPORT_CC
libxrdp_reset(struct xrdp_session *session,
int width, int height, int bpp)
{
if (session->client_info != 0)
{
struct xrdp_client_info *client_info = session->client_info;
/* older client can't resize */
if (session->client_info->build <= 419)
if (client_info->build <= 419)
{
return 0;
}
/* if same, don't need to do anything */
if (session->client_info->width == width &&
session->client_info->height == height &&
session->client_info->bpp == bpp)
/* if same (and only one monitor on client) don't need to do anything */
if (client_info->width == width &&
client_info->height == height &&
client_info->bpp == bpp &&
(client_info->monitorCount == 0 || client_info->multimon == 0))
{
return 0;
}
session->client_info->width = width;
session->client_info->height = height;
session->client_info->bpp = bpp;
client_info->width = width;
client_info->height = height;
client_info->bpp = bpp;
client_info->monitorCount = 0;
client_info->multimon = 0;
}
else
{
@ -1084,7 +1086,12 @@ libxrdp_reset(struct xrdp_session *session,
return 1;
}
/* shut down the rdp client */
/* shut down the rdp client
*
* When resetting the lib, disable application input checks, as
* otherwise we can send a channel message to the other end while
* the channels are inactive ([MS-RDPBCGR] 3.2.5.5.1 */
session->check_for_app_input = 0;
if (xrdp_rdp_send_deactivate((struct xrdp_rdp *)session->rdp) != 0)
{
return 1;
@ -1096,6 +1103,9 @@ libxrdp_reset(struct xrdp_session *session,
return 1;
}
/* Re-enable application input checks */
session->check_for_app_input = 1;
return 0;
}

View File

@ -66,6 +66,7 @@ struct xrdp_session
struct trans *trans;
int (*callback)(intptr_t id, int msg, intptr_t param1, intptr_t param2,
intptr_t param3, intptr_t param4);
int check_for_app_input;
void *rdp;
void *orders;
struct xrdp_client_info *client_info;

View File

@ -561,7 +561,10 @@ xrdp_caps_process_multifragmentupdate(struct xrdp_rdp *self, struct stream *s,
int MaxRequestSize;
in_uint32_le(s, MaxRequestSize);
self->client_info.max_fastpath_frag_bytes = MaxRequestSize;
if (self->client_info.use_fast_path & 1)
{
self->client_info.max_fastpath_frag_bytes = MaxRequestSize;
}
return 0;
}

View File

@ -146,7 +146,10 @@ xrdp_fastpath_send(struct xrdp_fastpath *self, struct stream *s)
{
return 1;
}
xrdp_fastpath_session_callback(self, 0x5556, 0, 0, 0, 0);
if (self->session->check_for_app_input)
{
xrdp_fastpath_session_callback(self, 0x5556, 0, 0, 0, 0);
}
return 0;
}

View File

@ -129,6 +129,12 @@ xrdp_iso_process_rdp_neg_req(struct xrdp_iso *self, struct stream *s)
int flags;
int len;
if (!s_check_rem(s, 7))
{
LLOGLN(10, ("xrdp_iso_process_rdpNegReq: unexpected end-of-record"));
return 1;
}
in_uint8(s, flags);
if (flags != 0x0 && flags != 0x8 && flags != 0x1)
{
@ -153,13 +159,22 @@ xrdp_iso_process_rdp_neg_req(struct xrdp_iso *self, struct stream *s)
return 0;
}
/*****************************************************************************/
/* returns error */
/*****************************************************************************
* Reads an X.224 PDU (X.224 section 13) preceded by a T.123 TPKT
* header (T.123 section 8)
*
* On entry, the TPKT header length field will have been inspected and used to
* set up the input stream.
*
* On exit, the TPKT header and the fixed part of the PDU header will have been
* removed from the stream.
*
* Returns error
*****************************************************************************/
static int
xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len)
{
int ver;
int plen;
*code = 0;
*len = 0;
@ -169,7 +184,16 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len)
LLOGLN(10, ("xrdp_iso_recv_msg error logic"));
}
/* TPKT header is 4 bytes, then first 2 bytes of the X.224 CR-TPDU */
if (!s_check_rem(s, 6))
{
return 1;
}
in_uint8(s, ver);
in_uint8s(s, 3); /* Skip reserved field, plus length */
in_uint8(s, *len);
in_uint8(s, *code);
if (ver != 3)
{
@ -178,24 +202,17 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len)
return 1;
}
in_uint8s(s, 1);
in_uint16_be(s, plen);
if (plen < 4)
if (*len == 255)
{
/* X.224 13.2.1 - reserved value */
LLOGLN(10, ("xrdp_iso_recv_msg: reserved length encountered"));
LHEXDUMP(10, (s->data, 4));
return 1;
}
if (!s_check_rem(s, 2))
{
return 1;
}
in_uint8(s, *len);
in_uint8(s, *code);
if (*code == ISO_PDU_DT)
{
/* Data PDU : X.224 13.7 */
if (!s_check_rem(s, 1))
{
return 1;
@ -204,6 +221,7 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len)
}
else
{
/* Other supported PDUs : X.224 13.x */
if (!s_check_rem(s, 5))
{
return 1;
@ -302,7 +320,20 @@ xrdp_iso_send_cc(struct xrdp_iso *self)
free_stream(s);
return 0;
}
/*****************************************************************************/
/*****************************************************************************
* Process an X.224 connection request PDU
*
* See MS-RDPCGR v20190923 sections 2.2.1.1 and 3.3.5.3.1.
*
* From the latter, in particular:-
* - The length embedded in the TPKT header MUST be examined for
* consistency with the received data. If there is a discrepancy, the
* connection SHOULD be dropped
* - If the optional routingToken field exists it MUST be ignored.
* - If the optional cookie field is present it MUST be ignored.
* - If both the routingToken and cookie fields are present, the server
* SHOULD continue with the connection.
*****************************************************************************/
/* returns error */
int
xrdp_iso_incoming(struct xrdp_iso *self)
@ -310,16 +341,14 @@ xrdp_iso_incoming(struct xrdp_iso *self)
int rv = 0;
int code;
int len;
int cookie_index;
int cc_type;
char text[256];
char *pend;
struct stream *s;
int expected_pdu_len;
LLOGLN(10, (" in xrdp_iso_incoming"));
s = libxrdp_force_read(self->trans);
if (s == 0)
if (s == NULL)
{
return 1;
}
@ -330,15 +359,29 @@ xrdp_iso_incoming(struct xrdp_iso *self)
return 1;
}
if ((code != ISO_PDU_CR) || (len < 6))
if (code != ISO_PDU_CR)
{
return 1;
}
/*
* Make sure the length indicator field extracted from the X.224
* connection request TPDU corresponds to the length in the TPKT header.
*
* We do this by seeing how the indicator field minus the counted
* octets in the TPDU header (6) compares with the space left in
* the stream.
*/
expected_pdu_len = (s->end - s->p) + 6;
if (len != expected_pdu_len)
{
LLOGLN(0, ("xrdp_iso_incoming: X.224 CR-TPDU length exp %d got %d",
expected_pdu_len, len));
return 1;
}
/* process connection request */
pend = s->p + (len - 6);
cookie_index = 0;
while (s->p < pend)
while (s_check_rem(s, 1))
{
in_uint8(s, cc_type);
switch (cc_type)
@ -355,28 +398,30 @@ xrdp_iso_incoming(struct xrdp_iso *self)
break;
case RDP_CORRELATION_INFO: /* rdpCorrelationInfo 6 */
// TODO
if (!s_check_rem(s, 1 + 2 + 16 + 16))
{
LLOGLN(0, ("xrdp_iso_incoming: short correlation info"));
return 1;
}
in_uint8s(s, 1 + 2 + 16 + 16);
break;
case 'C': /* Cookie routingToken */
while (s->p < pend)
case 'C': /* Cookie */
/* The routingToken and cookie fields are both ASCII
* strings starting with the word 'Cookie: ' and
* ending with CR+LF. We ignore both, so we do
* not need to distinguish them */
while (s_check_rem(s, 1))
{
text[cookie_index] = cc_type;
cookie_index++;
if (cookie_index > 255)
{
cookie_index = 255;
}
if ((s->p[0] == 0x0D) && (s->p[1] == 0x0A))
{
in_uint8s(s, 2);
text[cookie_index] = 0;
cookie_index = 0;
if (g_strlen(text) > 0)
{
}
break;
}
in_uint8(s, cc_type);
if (cc_type == 0x0D && s_check_rem(s, 1))
{
in_uint8(s, cc_type);
if (cc_type == 0x0A)
{
break;
}
}
}
break;
}

View File

@ -997,8 +997,11 @@ xrdp_mcs_call_callback(struct xrdp_mcs *self)
{
if (session->callback != 0)
{
/* in xrdp_wm.c */
rv = session->callback(session->id, 0x5556, 0, 0, 0, 0);
if (session->check_for_app_input)
{
/* in xrdp_wm.c */
rv = session->callback(session->id, 0x5556, 0, 0, 0, 0);
}
}
else
{

View File

@ -735,7 +735,7 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
}
in_uint16_le(s, len_domain);
if (len_domain > 511)
if (len_domain >= INFO_CLIENT_MAX_CB_LEN)
{
DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_domain > 511"));
return 1;
@ -757,7 +757,7 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
self->rdp_layer->client_info.rdp_autologin = 0;
}
if (len_user > 511)
if (len_user >= INFO_CLIENT_MAX_CB_LEN)
{
DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_user > 511"));
return 1;
@ -769,7 +769,7 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
}
in_uint16_le(s, len_password);
if (len_password > 511)
if (len_password >= INFO_CLIENT_MAX_CB_LEN)
{
DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_password > 511"));
return 1;
@ -781,7 +781,7 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
}
in_uint16_le(s, len_program);
if (len_program > 511)
if (len_program >= INFO_CLIENT_MAX_CB_LEN)
{
DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_program > 511"));
return 1;
@ -793,7 +793,7 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
}
in_uint16_le(s, len_directory);
if (len_directory > 511)
if (len_directory >= INFO_CLIENT_MAX_CB_LEN)
{
DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_directory > 511"));
return 1;

View File

@ -54,7 +54,7 @@ struct mod
char* data, int width, int height, int srcx, int srcy);
int (*server_set_cursor)(struct mod* v, int x, int y, char* data, char* mask);
int (*server_palette)(struct mod* v, int* palette);
int (*server_msg)(struct mod* v, char* msg, int code);
int (*server_msg)(struct mod* v, const char* msg, int code);
int (*server_is_term)(struct mod* v);
int (*server_set_clip)(struct mod* v, int x, int y, int cx, int cy);
int (*server_reset_clip)(struct mod* v);

View File

@ -24,6 +24,7 @@
#include "defines.h"
#include "xrdp_rail.h"
#include "xrdp_client_info.h"
#include "xrdp_constants.h"
/* this is the freerdp main header */
#include <freerdp/freerdp.h>
@ -196,9 +197,9 @@ struct mod
int vmaj;
int vmin;
int vrev;
char username[256];
char password[256];
char domain[256];
char username[INFO_CLIENT_MAX_CB_LEN];
char password[INFO_CLIENT_MAX_CB_LEN];
char domain[INFO_CLIENT_MAX_CB_LEN];
int bool_keyBoardSynced ; /* Numlock can be out of sync, we hold state here to resolve */
int keyBoardLockInfo ; /* Holds initial numlock capslock state */

View File

@ -48,6 +48,45 @@ call_make()
return $status
}
# ----------------------------------------------------------------------------
# C R E A T E Z 3 V E R S I O N H
#
# Older versions of libz3-dev do not come packaged with z3_version.h. This
# function uses the z3 command to create a copy of this file in the
# cppcheck i#externalsi# directory.
# ----------------------------------------------------------------------------
create_z3_version_h()
{
set -- `z3 --version`
if [ $# != 3 -o "$1/$2" != Z3/version ]; then
echo "** Unexpected output from z3 command '$*'" >&2
false
else
z3ver=$3 ; # e.g. 4.4.3
set -- `echo $z3ver | tr '.' ' '`
if [ $# != 3 ]; then
echo "** Unable to determine Z3 version from '$z3ver'" >&2
false
else
{
echo "#ifndef Z3_MAJOR_VERSION"
echo "#define Z3_MAJOR_VERSION $1"
echo "#endif"
echo
echo "#ifndef Z3_MINOR_VERSION"
echo "#define Z3_MINOR_VERSION $2"
echo "#endif"
echo
echo "#ifndef Z3_BUILD_NUMBER"
echo "#define Z3_BUILD_NUMBER $3"
echo "#endif"
} >externals/z3_version.h
echo " - Created z3_version.h for $1.$2.$3"
fi
fi
}
# ----------------------------------------------------------------------------
# M A I N
# ----------------------------------------------------------------------------
@ -78,14 +117,23 @@ fi
# Put everything in this directory
FILESDIR=$INSTALL_ROOT/$CPPCHECK_VER
# CFGDIR is needed for cppcheck before 1.86
make_args="FILESDIR=$FILESDIR PREFIX=$FILESDIR CFGDIR=$FILESDIR"
# See https://stackoverflow.com/questions/
# 791959/download-a-specific-tag-with-git
git clone -b $CPPCHECK_VER --depth 1 $REPO_URL $workdir
cd $workdir
case "$CPPCHECK_VER" in
1.*)
# CFGDIR is needed for cppcheck before 1.86
make_args="FILESDIR=$FILESDIR PREFIX=$FILESDIR CFGDIR=$FILESDIR"
;;
*) make_args="FILESDIR=$FILESDIR PREFIX=$FILESDIR USE_Z3=yes"
if [ ! -f /usr/include/z3_version.h ]; then
create_z3_version_h
fi
esac
echo "Making cppcheck..."
# CFGDIR is needed for cppcheck before 1.86
call_make $make_args

View File

@ -48,8 +48,7 @@ access_login_allowed(const char *user)
if ((0 == g_cfg->sec.ts_users_enable) && (0==g_cfg->sec.ts_always_group_check))
{
LOG_DBG("Terminal Server Users group is disabled, allowing authentication",
1);
LOG_DBG("Terminal Server Users group is disabled, allowing authentication");
return 1;
}
@ -98,7 +97,7 @@ access_login_mng_allowed(const char *user)
if (0 == g_cfg->sec.ts_admins_enable)
{
LOG_DBG("[MNG] Terminal Server Admin group is disabled, "
"allowing authentication", 1);
"allowing authentication");
return 1;
}

View File

@ -39,6 +39,10 @@
#include "xrdp_sockets.h"
#include "audin.h"
#include "ms-rdpbcgr.h"
#define MAX_PATH 260
static struct trans *g_lis_trans = 0;
static struct trans *g_con_trans = 0;
static struct trans *g_api_lis_trans = 0;
@ -1042,9 +1046,13 @@ my_api_trans_data_in(struct trans *trans)
int rv;
int bytes;
int ver;
int channel_name_bytes;
struct chansrv_drdynvc_procs procs;
char *chan_name;
/*
* Name is limited to CHANNEL_NAME_LEN for an SVC, or MAX_PATH
* bytes for a DVC
*/
char chan_name[MAX(CHANNEL_NAME_LEN, MAX_PATH) + 1];
unsigned int channel_name_bytes;
//g_writeln("my_api_trans_data_in: extra_flags %d", trans->extra_flags);
rv = 0;
@ -1067,12 +1075,13 @@ my_api_trans_data_in(struct trans *trans)
rv = 1;
in_uint32_le(s, channel_name_bytes);
//g_writeln("my_api_trans_data_in: channel_name_bytes %d", channel_name_bytes);
chan_name = g_new0(char, channel_name_bytes + 1);
if (chan_name == NULL)
if (channel_name_bytes > (sizeof(chan_name) - 1))
{
return 1;
}
in_uint8a(s, chan_name, channel_name_bytes);
chan_name[channel_name_bytes] = '\0';
in_uint32_le(s, ad->chan_flags);
//g_writeln("my_api_trans_data_in: chan_name %s chan_flags 0x%8.8x", chan_name, ad->chan_flags);
if (ad->chan_flags == 0)
@ -1132,7 +1141,6 @@ my_api_trans_data_in(struct trans *trans)
// "chan_id %d", rv, ad->chan_id);
g_drdynvcs[ad->chan_id].xrdp_api_trans = trans;
}
g_free(chan_name);
init_stream(s, 0);
trans->extra_flags = 2;
trans->header_size = 0;

View File

@ -586,9 +586,18 @@ int
scard_process_list_readers(struct trans *con, struct stream *in_s)
{
int hContext;
int bytes_groups;
unsigned int bytes_groups;
int cchReaders;
char *groups;
/*
* At the time of writing, the groups strings which can be sent
* over this interface are all small:-
*
* "SCard$AllReaders", "SCard$DefaultReaders", "SCard$LocalReaders" and
* "SCard$SystemReaders"
*
* We'll allow a bit extra in case the interface changes
*/
char groups[256];
struct pcsc_uds_client *uds_client;
struct pcsc_context *lcontext;
struct pcsc_list_readers *pcscListReaders;
@ -597,8 +606,14 @@ scard_process_list_readers(struct trans *con, struct stream *in_s)
uds_client = (struct pcsc_uds_client *) (con->callback_data);
in_uint32_le(in_s, hContext);
in_uint32_le(in_s, bytes_groups);
groups = (char *) g_malloc(bytes_groups + 1, 1);
if (bytes_groups > (sizeof(groups) - 1))
{
LLOGLN(0, ("scard_process_list_readers: Unreasonable string length %u",
bytes_groups));
return 1;
}
in_uint8a(in_s, groups, bytes_groups);
groups[bytes_groups] = '\0';
in_uint32_le(in_s, cchReaders);
LLOGLN(10, ("scard_process_list_readers: hContext 0x%8.8x cchReaders %d",
hContext, cchReaders));
@ -615,7 +630,6 @@ scard_process_list_readers(struct trans *con, struct stream *in_s)
pcscListReaders->cchReaders = cchReaders;
scard_send_list_readers(pcscListReaders, lcontext->context,
lcontext->context_bytes, groups, cchReaders, 1);
g_free(groups);
return 0;
}

View File

@ -60,7 +60,7 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
while ((!data) && ((retries == 0) || (current_try > 0)))
{
LOG_DBG("data %d - retry %d - currenttry %d - expr %d",
LOG_DBG("data %ld - retry %d - currenttry %d - expr %d",
data, retries, current_try,
((!data) && ((retries == 0) || (current_try > 0))));

View File

@ -83,7 +83,7 @@ scp_v1_mng_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
case SCP_SERVER_STATE_MNG_LISTREQ:
/* list disconnected sessions */
slist = session_get_byuser(NULL, &scount, SESMAN_SESSION_STATUS_ALL);
LOG_DBG("sessions on TS: %d (slist: %x)", scount, slist);
LOG_DBG("sessions on TS: %d (slist: %p)", scount, slist);
if (0 == slist)
{
log_message(LOG_LEVEL_INFO, "No sessions on Terminal Server");

View File

@ -55,7 +55,7 @@ IdleTimeLimit=0
;; Policy - session allocation policy
; Type: enum [ "Default" | "UBD" | "UBI" | "UBC" | "UBDI" | "UBDC" ]
; Default: Xrdp:<User,BitPerPixel> and Xvnc:<User,BitPerPixel,DisplaySize>
; "Default" session per <User,BitPerPixel>
; "UBD" session per <User,BitPerPixel,DisplaySize>
; "UBI" session per <User,BitPerPixel,IPAddr>
; "UBC" session per <User,BitPerPixel,Connection>
@ -75,13 +75,15 @@ SyslogLevel=DEBUG
[Xorg]
; Specify the path of non-suid Xorg executable. It might differ depending
; on your distribution and version. The typical path is shown as follows:
; on your distribution and version. Find out the appropreate path for your
; environment. The typical path is known as follows:
;
; Fedora 26 or later : param=/usr/libexec/Xorg
; Debian 9 or later : param=/usr/lib/xorg/Xorg
; Ubuntu 16.04 or later : param=/usr/lib/xorg/Xorg
; Arch Linux : param=/usr/lib/xorg-server/Xorg
; Arch Linux : param=/usr/lib/Xorg
; CentOS 7 : param=/usr/bin/Xorg or param=Xorg
; CentOS 8 : param=/usr/libexec/Xorg
;
param=Xorg
; Leave the rest paramaters as-is unless you understand what will happen.

View File

@ -105,9 +105,6 @@ session_get_bydata(const char *name, int width, int height, int bpp, int type,
{
case SCP_SESSION_TYPE_XVNC: /* 0 */
type = SESMAN_SESSION_TYPE_XVNC; /* 2 */
/* Xvnc cannot resize */
policy = (enum SESMAN_CFG_SESS_POLICY)
(policy | SESMAN_CFG_SESS_POLICY_D);
break;
case SCP_SESSION_TYPE_XRDP: /* 1 */
type = SESMAN_SESSION_TYPE_XRDP; /* 1 */

View File

@ -31,6 +31,10 @@
#include "sesman.h"
#include "tcp.h"
#if !defined(PACKAGE_VERSION)
#define PACKAGE_VERSION "???"
#endif
struct config_sesman g_cfg; /* config.h */
/******************************************************************************/
@ -61,9 +65,9 @@ main(int argc, char **argv)
if (argc == 1)
{
g_printf("xrdp session starter v0.1\n");
g_printf("xrdp session starter v" PACKAGE_VERSION "\n");
g_printf("\nusage:\n");
g_printf("sesrun <server> <username> <password> <width> <height> <bpp> <session_cod>\n");
g_printf("sesrun <server> <username> <password> <width> <height> <bpp> <session_code>\n");
g_printf("session code 0 for Xvnc, 10 for X11RDP, 20 for Xorg\n");
}
else if (argc == 8)

View File

@ -34,10 +34,13 @@
#include <stdio.h>
#include <security/pam_appl.h>
/* Defines the maximum size of a username or password. With pam there is no real limit */
#define MAX_BUF 8192
struct t_user_pass
{
char user[256];
char pass[256];
char user[MAX_BUF];
char pass[MAX_BUF];
};
struct t_auth_info
@ -115,8 +118,8 @@ auth_userpass(const char *user, const char *pass, int *errorcode)
get_service_name(service_name);
auth_info = g_new0(struct t_auth_info, 1);
g_strncpy(auth_info->user_pass.user, user, 255);
g_strncpy(auth_info->user_pass.pass, pass, 255);
g_strncpy(auth_info->user_pass.user, user, MAX_BUF - 1);
g_strncpy(auth_info->user_pass.pass, pass, MAX_BUF - 1);
auth_info->pamc.conv = &verify_pam_conv;
auth_info->pamc.appdata_ptr = &(auth_info->user_pass);
error = pam_start(service_name, 0, &(auth_info->pamc), &(auth_info->ph));

1145
vnc/vnc.c

File diff suppressed because it is too large Load Diff

211
vnc/vnc.h
View File

@ -26,98 +26,129 @@
#define CURRENT_MOD_VER 4
/* Screen used for ExtendedDesktopSize / Set DesktopSize */
struct vnc_screen
{
int id;
int x;
int y;
int width;
int height;
int flags;
};
struct vnc_screen_layout
{
int total_width;
int total_height;
unsigned int count;
/* For comparison, screens are sorted in increasing order of ID */
struct vnc_screen *s;
};
/**
* Keep track of resize status at start of connection
*/
enum vnc_resize_status
{
VRS_WAITING_FOR_FIRST_UPDATE,
VRS_WAITING_FOR_RESIZE_CONFIRM,
VRS_DONE
};
struct vnc
{
int size; /* size of this struct */
int version; /* internal version */
/* client functions */
int (*mod_start)(struct vnc* v, int w, int h, int bpp);
int (*mod_connect)(struct vnc* v);
int (*mod_event)(struct vnc* v, int msg, long param1, long param2,
long param3, long param4);
int (*mod_signal)(struct vnc* v);
int (*mod_end)(struct vnc* v);
int (*mod_set_param)(struct vnc *v, const char *name, const char *value);
int (*mod_session_change)(struct vnc* v, int, int);
int (*mod_get_wait_objs)(struct vnc* v, tbus* read_objs, int* rcount,
tbus* write_objs, int* wcount, int* timeout);
int (*mod_check_wait_objs)(struct vnc* v);
int (*mod_frame_ack)(struct vnc* v, int flags, int frame_id);
int (*mod_suppress_output)(struct vnc* v, int suppress,
int left, int top, int right, int bottom);
tintptr mod_dumby[100 - 11]; /* align, 100 minus the number of mod
int size; /* size of this struct */
int version; /* internal version */
/* client functions */
int (*mod_start)(struct vnc *v, int w, int h, int bpp);
int (*mod_connect)(struct vnc *v);
int (*mod_event)(struct vnc *v, int msg, long param1, long param2,
long param3, long param4);
int (*mod_signal)(struct vnc *v);
int (*mod_end)(struct vnc *v);
int (*mod_set_param)(struct vnc *v, const char *name, const char *value);
int (*mod_session_change)(struct vnc *v, int, int);
int (*mod_get_wait_objs)(struct vnc *v, tbus *read_objs, int *rcount,
tbus *write_objs, int *wcount, int *timeout);
int (*mod_check_wait_objs)(struct vnc *v);
int (*mod_frame_ack)(struct vnc *v, int flags, int frame_id);
int (*mod_suppress_output)(struct vnc *v, int suppress,
int left, int top, int right, int bottom);
tintptr mod_dumby[100 - 11]; /* align, 100 minus the number of mod
functions above */
/* server functions */
int (*server_begin_update)(struct vnc* v);
int (*server_end_update)(struct vnc* v);
int (*server_fill_rect)(struct vnc* v, int x, int y, int cx, int cy);
int (*server_screen_blt)(struct vnc* v, int x, int y, int cx, int cy,
int srcx, int srcy);
int (*server_paint_rect)(struct vnc* v, int x, int y, int cx, int cy,
char* data, int width, int height, int srcx, int srcy);
int (*server_set_cursor)(struct vnc* v, int x, int y, char* data, char* mask);
int (*server_palette)(struct vnc* v, int* palette);
int (*server_msg)(struct vnc* v, const char *msg, int code);
int (*server_is_term)(struct vnc* v);
int (*server_set_clip)(struct vnc* v, int x, int y, int cx, int cy);
int (*server_reset_clip)(struct vnc* v);
int (*server_set_fgcolor)(struct vnc* v, int fgcolor);
int (*server_set_bgcolor)(struct vnc* v, int bgcolor);
int (*server_set_opcode)(struct vnc* v, int opcode);
int (*server_set_mixmode)(struct vnc* v, int mixmode);
int (*server_set_brush)(struct vnc* v, int x_origin, int y_origin,
int style, char* pattern);
int (*server_set_pen)(struct vnc* v, int style,
int width);
int (*server_draw_line)(struct vnc* v, int x1, int y1, int x2, int y2);
int (*server_add_char)(struct vnc* v, int font, int character,
int offset, int baseline,
int width, int height, char* data);
int (*server_draw_text)(struct vnc* v, int font,
int flags, int mixmode, int clip_left, int clip_top,
int clip_right, int clip_bottom,
int box_left, int box_top,
int box_right, int box_bottom,
int x, int y, char* data, int data_len);
int (*server_reset)(struct vnc* v, int width, int height, int bpp);
int (*server_query_channel)(struct vnc* v, int index,
char* channel_name,
int* channel_flags);
int (*server_get_channel_id)(struct vnc* v, const char *name);
int (*server_send_to_channel)(struct vnc* v, int channel_id,
char* data, int data_len,
int total_data_len, int flags);
int (*server_bell_trigger)(struct vnc* v);
tintptr server_dumby[100 - 25]; /* align, 100 minus the number of server
/* server functions */
int (*server_begin_update)(struct vnc *v);
int (*server_end_update)(struct vnc *v);
int (*server_fill_rect)(struct vnc *v, int x, int y, int cx, int cy);
int (*server_screen_blt)(struct vnc *v, int x, int y, int cx, int cy,
int srcx, int srcy);
int (*server_paint_rect)(struct vnc *v, int x, int y, int cx, int cy,
char *data, int width, int height, int srcx, int srcy);
int (*server_set_cursor)(struct vnc *v, int x, int y, char *data, char *mask);
int (*server_palette)(struct vnc *v, int *palette);
int (*server_msg)(struct vnc *v, const char *msg, int code);
int (*server_is_term)(struct vnc *v);
int (*server_set_clip)(struct vnc *v, int x, int y, int cx, int cy);
int (*server_reset_clip)(struct vnc *v);
int (*server_set_fgcolor)(struct vnc *v, int fgcolor);
int (*server_set_bgcolor)(struct vnc *v, int bgcolor);
int (*server_set_opcode)(struct vnc *v, int opcode);
int (*server_set_mixmode)(struct vnc *v, int mixmode);
int (*server_set_brush)(struct vnc *v, int x_origin, int y_origin,
int style, char *pattern);
int (*server_set_pen)(struct vnc *v, int style,
int width);
int (*server_draw_line)(struct vnc *v, int x1, int y1, int x2, int y2);
int (*server_add_char)(struct vnc *v, int font, int character,
int offset, int baseline,
int width, int height, char *data);
int (*server_draw_text)(struct vnc *v, int font,
int flags, int mixmode, int clip_left, int clip_top,
int clip_right, int clip_bottom,
int box_left, int box_top,
int box_right, int box_bottom,
int x, int y, char *data, int data_len);
int (*server_reset)(struct vnc *v, int width, int height, int bpp);
int (*server_query_channel)(struct vnc *v, int index,
char *channel_name,
int *channel_flags);
int (*server_get_channel_id)(struct vnc *v, const char *name);
int (*server_send_to_channel)(struct vnc *v, int channel_id,
char *data, int data_len,
int total_data_len, int flags);
int (*server_bell_trigger)(struct vnc *v);
tintptr server_dumby[100 - 25]; /* align, 100 minus the number of server
functions above */
/* common */
tintptr handle; /* pointer to self as long */
tintptr wm;
tintptr painter;
tintptr si;
/* mod data */
int server_width;
int server_height;
int server_bpp;
int mod_width;
int mod_height;
int mod_bpp;
char mod_name[256];
int mod_mouse_state;
int palette[256];
int vnc_desktop;
char username[256];
char password[256];
char ip[256];
char port[256];
int sck_closed;
int shift_state; /* 0 up, 1 down */
int keylayout;
int clip_chanid;
struct stream *clip_data_s;
int delay_ms;
struct trans *trans;
int got_guid;
tui8 guid[16];
int suppress_output;
/* common */
tintptr handle; /* pointer to self as long */
tintptr wm;
tintptr painter;
tintptr si;
/* mod data */
int server_width;
int server_height;
int server_bpp;
char mod_name[256];
int mod_mouse_state;
int palette[256];
int vnc_desktop;
char username[256];
char password[256];
char ip[256];
char port[256];
int sck_closed;
int shift_state; /* 0 up, 1 down */
int keylayout;
int clip_chanid;
struct stream *clip_data_s;
int delay_ms;
struct trans *trans;
int got_guid;
tui8 guid[16];
int suppress_output;
unsigned int enabled_encodings_mask;
/* Resizeable support */
struct vnc_screen_layout client_layout;
enum vnc_resize_status initial_resize_status;
};

View File

@ -196,6 +196,10 @@ ip=127.0.0.1
port=-1
#xserverbpp=24
#delay_ms=2000
; Disable requested encodings to support buggy VNC servers
; (1 = ExtendedDesktopSize)
#disabled_encodings_mask=0
[vnc-any]
name=vnc-any

View File

@ -25,6 +25,8 @@
#include <config_ac.h>
#endif
#include <limits.h>
#include "xrdp.h"
#include "log.h"
@ -93,6 +95,30 @@ static const unsigned int g_crc_table[256] =
(in_crc) = g_crc_table[((in_crc) ^ (in_pixel)) & 0xff] ^ ((in_crc) >> 8)
#define CRC_END(in_crc) (in_crc) = ((in_crc) ^ 0xFFFFFFFF)
/*****************************************************************************/
/* Allocate bitmap for specified dimensions, checking for int overflow */
static char *
alloc_bitmap_data(int width, int height, int Bpp)
{
char *result = NULL;
if (width > 0 && height > 0 && Bpp > 0)
{
int len = width;
/* g_malloc() currently takes an 'int' size */
if (len < INT_MAX / height)
{
len *= height;
if (len < INT_MAX / Bpp)
{
len *= Bpp;
result = (char *)malloc(len);
}
}
}
return result;
}
/*****************************************************************************/
struct xrdp_bitmap *
xrdp_bitmap_create(int width, int height, int bpp,
@ -123,14 +149,28 @@ xrdp_bitmap_create(int width, int height, int bpp,
if (self->type == WND_TYPE_BITMAP || self->type == WND_TYPE_IMAGE)
{
self->data = (char *)g_malloc(width * height * Bpp, 0);
self->data = alloc_bitmap_data(width, height, Bpp);
if (self->data == NULL)
{
LLOGLN(0, ("xrdp_bitmap_create: size overflow %dx%dx%d",
width, height, Bpp));
g_free(self);
return NULL;
}
}
#if defined(XRDP_PAINTER)
if (self->type == WND_TYPE_SCREEN) /* noorders */
{
LLOGLN(0, ("xrdp_bitmap_create: noorders"));
self->data = (char *) g_malloc(width * height * Bpp, 0);
self->data = alloc_bitmap_data(width, height, Bpp);
if (self->data == NULL)
{
LLOGLN(0, ("xrdp_bitmap_create: size overflow %dx%dx%d",
width, height, Bpp));
g_free(self);
return NULL;
}
}
#endif

View File

@ -59,6 +59,7 @@ layouts_map=default_layouts_map
[default_rdp_layouts]
rdp_layout_us=0x00000409
rdp_layout_us_dvorak=0x00010409
rdp_layout_us_dvp=0x19360409
rdp_layout_dk=0x00000406
rdp_layout_de=0x00000407
rdp_layout_es=0x0000040A
@ -85,6 +86,7 @@ rdp_layout_pt=0x00000816
[default_layouts_map]
rdp_layout_us=us
rdp_layout_us_dvorak=dvorak
rdp_layout_us_dvp=us(dvp)
rdp_layout_dk=dk
rdp_layout_de=de
rdp_layout_es=es
@ -122,6 +124,7 @@ layouts_map=default_layouts_map
[rdp_layouts_map_mac]
rdp_layout_us=us
rdp_layout_us_dvorak=dvorak
rdp_layout_us_dvp=us(dvp)
rdp_layout_dk=dk
rdp_layout_de=de
rdp_layout_es=es

View File

@ -3261,6 +3261,9 @@ server_draw_text(struct xrdp_mod *mod, int font,
}
/*****************************************************************************/
/* Note : if this is called on a multimon setup, the client is resized
* to a single monitor */
int
server_reset(struct xrdp_mod *mod, int width, int height, int bpp)
{
@ -3279,10 +3282,11 @@ server_reset(struct xrdp_mod *mod, int width, int height, int bpp)
return 0;
}
/* if same, don't need to do anything */
/* if same (and only one monitor on client) don't need to do anything */
if (wm->client_info->width == width &&
wm->client_info->height == height &&
wm->client_info->bpp == bpp)
wm->client_info->height == height &&
wm->client_info->bpp == bpp &&
(wm->client_info->monitorCount == 0 || wm->client_info->multimon == 0))
{
return 0;
}

View File

@ -913,7 +913,7 @@ xrdp_wm_xor_pat(struct xrdp_wm *self, int x, int y, int cx, int cy)
self->painter->brush.pattern[6] = 0xaa;
self->painter->brush.pattern[7] = 0x55;
self->painter->brush.x_origin = 0;
self->painter->brush.x_origin = 0;
self->painter->brush.y_origin = 0;
self->painter->brush.style = 3;
self->painter->bg_color = self->black;
self->painter->fg_color = self->white;
@ -1532,6 +1532,12 @@ xrdp_wm_key(struct xrdp_wm *self, int device_flags, int scan_code)
return 0;
}
// workaround odd shift behavior
// see https://github.com/neutrinolabs/xrdp/issues/397
if (scan_code == 42 && device_flags == (KBD_FLAG_UP | KBD_FLAG_EXT)) {
return 0;
}
if (device_flags & KBD_FLAG_UP) /* 0x8000 */
{
self->keys[scan_code] = 0;

View File

@ -1546,11 +1546,11 @@ lib_mod_set_param(struct mod *mod, const char *name, const char *value)
{
if (g_strcasecmp(name, "username") == 0)
{
g_strncpy(mod->username, value, 255);
g_strncpy(mod->username, value, INFO_CLIENT_MAX_CB_LEN-1);
}
else if (g_strcasecmp(name, "password") == 0)
{
g_strncpy(mod->password, value, 255);
g_strncpy(mod->password, value, INFO_CLIENT_MAX_CB_LEN-1);
}
else if (g_strcasecmp(name, "ip") == 0)
{

View File

@ -24,6 +24,7 @@
#include "os_calls.h"
#include "defines.h"
#include "xrdp_client_info.h"
#include "xrdp_constants.h"
#include "xrdp_rail.h"
#define CURRENT_MOD_VER 4
@ -154,8 +155,8 @@ struct mod
int height;
int bpp;
int sck_closed;
char username[256];
char password[256];
char username[INFO_CLIENT_MAX_CB_LEN];
char password[INFO_CLIENT_MAX_CB_LEN];
char ip[256];
char port[256];
int shift_state;