diff -Nru xrdp-0.9.12/aclocal.m4 xrdp-0.9.15/aclocal.m4 --- xrdp-0.9.12/aclocal.m4 2019-12-28 12:36:36.000000000 +0000 +++ xrdp-0.9.15/aclocal.m4 2020-12-28 14:06:37.000000000 +0000 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.16.1 -*- Autoconf -*- +# generated automatically by aclocal 1.16.3 -*- Autoconf -*- -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002-2018 Free Software Foundation, Inc. +# Copyright (C) 2002-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -35,7 +35,7 @@ [am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.16.1], [], +m4_if([$1], [1.16.3], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,14 +51,14 @@ # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.16.1])dnl +[AM_AUTOMAKE_VERSION([1.16.3])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -108,9 +108,46 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) +# AM_COND_IF -*- Autoconf -*- + +# Copyright (C) 2008-2020 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_COND_IF +# _AM_COND_ELSE +# _AM_COND_ENDIF +# -------------- +# These macros are only used for tracing. +m4_define([_AM_COND_IF]) +m4_define([_AM_COND_ELSE]) +m4_define([_AM_COND_ENDIF]) + +# AM_COND_IF(COND, [IF-TRUE], [IF-FALSE]) +# --------------------------------------- +# If the shell condition COND is true, execute IF-TRUE, otherwise execute +# IF-FALSE. Allow automake to learn about conditional instantiating macros +# (the AC_CONFIG_FOOS). +AC_DEFUN([AM_COND_IF], +[m4_ifndef([_AM_COND_VALUE_$1], + [m4_fatal([$0: no such condition "$1"])])dnl +_AM_COND_IF([$1])dnl +if test -z "$$1_TRUE"; then : + m4_n([$2])[]dnl +m4_ifval([$3], +[_AM_COND_ELSE([$1])dnl +else + $3 +])dnl +_AM_COND_ENDIF([$1])dnl +fi[]dnl +]) + # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2018 Free Software Foundation, Inc. +# Copyright (C) 1997-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -141,7 +178,7 @@ Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -332,7 +369,7 @@ # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -371,7 +408,9 @@ done if test $am_rc -ne 0; then AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments - for automatic dependency tracking. Try re-running configure with the + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE="gmake" (or whatever is + necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking).]) fi @@ -398,7 +437,7 @@ # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -595,7 +634,7 @@ done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -616,7 +655,7 @@ fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2018 Free Software Foundation, Inc. +# Copyright (C) 2003-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -637,7 +676,7 @@ # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -680,7 +719,7 @@ # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2018 Free Software Foundation, Inc. +# Copyright (C) 1997-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -701,12 +740,7 @@ [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac + MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then @@ -719,7 +753,7 @@ # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -748,7 +782,7 @@ AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -795,7 +829,7 @@ # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -814,7 +848,7 @@ # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -895,7 +929,7 @@ rm -f conftest.file ]) -# Copyright (C) 2009-2018 Free Software Foundation, Inc. +# Copyright (C) 2009-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -955,7 +989,7 @@ _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -983,7 +1017,7 @@ INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2018 Free Software Foundation, Inc. +# Copyright (C) 2006-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1002,7 +1036,7 @@ # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2018 Free Software Foundation, Inc. +# Copyright (C) 2004-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/common/arch.h xrdp-0.9.15/common/arch.h --- xrdp-0.9.12/common/arch.h 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/common/arch.h 2020-12-28 14:03:43.000000000 +0000 @@ -84,7 +84,8 @@ #define NEED_ALIGN #elif defined(__x86__) || defined(__x86_64__) || \ defined(__AMD64__) || defined(_M_IX86) || defined (_M_AMD64) || \ - defined(__i386__) || defined(__aarch64__) + defined(__i386__) || defined(__aarch64__) || \ + defined(__riscv) #define NO_NEED_ALIGN #else #warning unknown arch diff -Nru xrdp-0.9.12/common/base64.c xrdp-0.9.15/common/base64.c --- xrdp-0.9.12/common/base64.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/common/base64.c 2020-12-28 14:03:43.000000000 +0000 @@ -22,7 +22,7 @@ #include #endif -#include "os_calls.h" +#include "string_calls.h" #include #include diff -Nru xrdp-0.9.12/common/defines.h xrdp-0.9.15/common/defines.h --- xrdp-0.9.12/common/defines.h 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/common/defines.h 2020-12-28 14:03:43.000000000 +0000 @@ -40,6 +40,9 @@ #define LOWORD(in) ((in) & 0x0000ffff) #undef MAKELONG #define MAKELONG(lo, hi) ((((hi) & 0xffff) << 16) | ((lo) & 0xffff)) +#define UNUSED_VAR(x) ((void) (x)) + +/* graphics macros */ #define MAKERECT(r, x, y, cx, cy) \ { (r).left = x; (r).top = y; (r).right = (x) + (cx); (r).bottom = (y) + (cy); } #define ISRECTEMPTY(r) (((r).right <= (r).left) || ((r).bottom <= (r).top)) diff -Nru xrdp-0.9.12/common/file.c xrdp-0.9.15/common/file.c --- xrdp-0.9.12/common/file.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/common/file.c 2020-12-28 14:03:43.000000000 +0000 @@ -24,6 +24,7 @@ #include "arch.h" #include "os_calls.h" +#include "string_calls.h" #include "list.h" #include "file.h" #include "parse.h" diff -Nru xrdp-0.9.12/common/list.c xrdp-0.9.15/common/list.c --- xrdp-0.9.12/common/list.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/common/list.c 2020-12-28 14:03:43.000000000 +0000 @@ -24,6 +24,7 @@ #include "arch.h" #include "os_calls.h" +#include "string_calls.h" #include "list.h" /*****************************************************************************/ diff -Nru xrdp-0.9.12/common/log.c xrdp-0.9.15/common/log.c --- xrdp-0.9.12/common/log.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/common/log.c 2020-12-28 14:03:43.000000000 +0000 @@ -31,6 +31,7 @@ #include "file.h" #include "os_calls.h" #include "thread_calls.h" +#include "string_calls.h" /* Add a define here so that the log.h will hold more information * when compiled from this C file. @@ -66,7 +67,7 @@ #ifdef FD_CLOEXEC if (ret != -1) { - fcntl(ret, F_SETFD, FD_CLOEXEC); + fcntl(ret, F_SETFD, FD_CLOEXEC); } #endif @@ -150,13 +151,6 @@ return ret; } - /* if logfile is NULL, we return error */ - if (0 == l_cfg->log_file) - { - g_writeln("log_file not properly assigned"); - return ret; - } - /* if progname is NULL, we return error */ if (0 == l_cfg->program_name) { @@ -164,12 +158,20 @@ return ret; } - /* open file */ - l_cfg->fd = internal_log_file_open(l_cfg->log_file); + if (l_cfg->dump_on_start) + { + internal_log_config_dump(l_cfg); + } - if (-1 == l_cfg->fd) + /* open file */ + if (l_cfg->log_file != NULL) { - return LOG_ERROR_FILE_OPEN; + l_cfg->fd = internal_log_file_open(l_cfg->log_file); + + if (-1 == l_cfg->fd) + { + return LOG_ERROR_FILE_OPEN; + } } /* if syslog is enabled, open it */ @@ -265,37 +267,24 @@ return LOG_LEVEL_DEBUG; } -enum logReturns -internalReadConfiguration(const char *inFilename, const char *applicationName) +/******************************************************************************/ +struct log_config * +internal_config_read_logging(int file, + const char *applicationName, + const char *section_prefix) { - int fd; - enum logReturns ret = LOG_GENERAL_ERROR; + int i; + char *buf; + char *temp_buf; + char section_name[512]; + struct log_config *lc; struct list *param_n; struct list *param_v; - if (inFilename == NULL) + lc = internalInitAndAllocStruct(); + if (lc == NULL) { - g_writeln("The inifile is null to readConfiguration!"); - return ret; - } - - fd = g_file_open(inFilename); - - if (-1 == fd) - { - ret = LOG_ERROR_NO_CFG; - g_writeln("We could not open the configuration file to read log parameters"); - return ret; - } - - /* we initialize the memory for the configuration and set all content - to zero. */ - ret = internalInitAndAllocStruct(); - - if (ret != LOG_STARTUP_OK) - { - g_file_close(fd); - return ret; + return NULL; } param_n = list_create(); @@ -303,28 +292,6 @@ param_v = list_create(); param_v->auto_free = 1; - /* read logging config */ - ret = internal_config_read_logging(fd, g_staticLogConfig, param_n, - param_v, applicationName); - - /* cleanup */ - list_delete(param_v); - list_delete(param_n); - g_file_close(fd); - return ret; -} - -/******************************************************************************/ -enum logReturns -internal_config_read_logging(int file, struct log_config *lc, - struct list *param_n, - struct list *param_v, - const char *applicationName) -{ - int i; - char *buf; - char *temp_buf; - list_clear(param_v); list_clear(param_n); @@ -332,11 +299,16 @@ lc->program_name = applicationName; lc->log_file = 0; lc->fd = -1; - lc->log_level = LOG_LEVEL_DEBUG; + lc->log_level = LOG_LEVEL_INFO; + lc->enable_console = 0; + lc->console_level = LOG_LEVEL_INFO; lc->enable_syslog = 0; - lc->syslog_level = LOG_LEVEL_DEBUG; + lc->syslog_level = LOG_LEVEL_INFO; + lc->dump_on_start = 1; + lc->enable_pid = 0; - file_read_section(file, SESMAN_CFG_LOGGING, param_n, param_v); + g_snprintf(section_name, 511, "%s%s", section_prefix, SESMAN_CFG_LOGGING); + file_read_section(file, section_name, param_n, param_v); for (i = 0; i < param_n->count; i++) { @@ -372,6 +344,21 @@ { lc->syslog_level = internal_log_text2level((char *)list_get_item(param_v, i)); } + + if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_ENABLE_CONSOLE)) + { + lc->enable_console = g_text2bool((char *)list_get_item(param_v, i)); + } + + if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_CONSOLE_LEVEL)) + { + lc->console_level = internal_log_text2level((char *)list_get_item(param_v, i)); + } + + if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_ENABLE_PID)) + { + lc->enable_pid = g_text2bool((char *)list_get_item(param_v, i)); + } } if (0 == lc->log_file) @@ -382,41 +369,313 @@ /* try to create path if not exist */ g_create_path(lc->log_file); +#ifdef LOG_PER_LOGGER_LEVEL + int len; + struct log_logger_level *logger; + + list_clear(param_v); + list_clear(param_n); + g_snprintf(section_name, 511, "%s%s", section_prefix, SESMAN_CFG_LOGGING_LOGGER); + file_read_section(file, section_name, param_n, param_v); + for (i = 0; i < param_n->count; i++) + { + logger = (struct log_logger_level *)g_malloc(sizeof(struct log_logger_level), 1); + list_add_item(lc->per_logger_level, (tbus) logger); + logger->log_level = internal_log_text2level((char *)list_get_item(param_v, i)); + + g_strncpy(logger->logger_name, (char *)list_get_item(param_n, i), LOGGER_NAME_SIZE); + logger->logger_name[LOGGER_NAME_SIZE] = '\0'; + len = g_strlen(logger->logger_name); + if (len >= 2 + && logger->logger_name[len - 2] == '(' + && logger->logger_name[len - 1] == ')' ) + { + logger->logger_type = LOG_TYPE_FUNCTION; + logger->logger_name[len - 2] = '\0'; + } + else + { + logger->logger_type = LOG_TYPE_FILE; + } + } +#endif + + list_delete(param_v); + list_delete(param_n); + return lc; +} + +void +internal_log_config_dump(struct log_config *config) +{ + char str_level[20]; +#ifdef LOG_PER_LOGGER_LEVEL + struct log_logger_level *logger; + int i; +#endif + g_printf("logging configuration:\r\n"); - g_printf("\tLogFile: %s\r\n", lc->log_file); - g_printf("\tLogLevel: %i\r\n", lc->log_level); - g_printf("\tEnableSyslog: %i\r\n", lc->enable_syslog); - g_printf("\tSyslogLevel: %i\r\n", lc->syslog_level); - return LOG_STARTUP_OK; + if (config->log_file) + { + internal_log_lvl2str(config->log_level, str_level); + g_printf("\tLogFile: %s\r\n", config->log_file); + g_printf("\tLogLevel: %s\r\n", str_level); + } + else + { + g_printf("\tLogFile: %s\r\n", ""); + } + + if (config->enable_console) + { + internal_log_lvl2str(config->console_level, str_level); + } + else + { + g_strcpy(str_level, ""); + } + g_printf("\tConsoleLevel: %s\r\n", str_level); + + if (config->enable_syslog) + { + internal_log_lvl2str(config->syslog_level, str_level); + } + else + { + g_strcpy(str_level, ""); + } + g_printf("\tSyslogLevel: %s\r\n", str_level); + +#ifdef LOG_PER_LOGGER_LEVEL + g_printf("per logger configuration:\r\n"); + for (i = 0; i < config->per_logger_level->count; i++) + { + logger = (struct log_logger_level *)list_get_item(config->per_logger_level, i); + internal_log_lvl2str(logger->log_level, str_level); + g_printf("\t%-*s: %s\r\n", LOGGER_NAME_SIZE, logger->logger_name, str_level); + } + if (config->per_logger_level->count == 0) + { + g_printf("\tNone\r\n"); + } +#endif } -enum logReturns +struct log_config * internalInitAndAllocStruct(void) { - enum logReturns ret = LOG_GENERAL_ERROR; - g_staticLogConfig = g_new0(struct log_config, 1); + struct log_config *ret = g_new0(struct log_config, 1); - if (g_staticLogConfig != NULL) + if (ret != NULL) { - g_staticLogConfig->fd = -1; - g_staticLogConfig->enable_syslog = 0; - ret = LOG_STARTUP_OK; + ret->fd = -1; + ret->enable_syslog = 0; + ret->per_logger_level = list_create(); + if (ret->per_logger_level != NULL) + { + ret->per_logger_level->auto_free = 1; + } + else + { + g_writeln("could not allocate memory for log struct"); + g_free(ret); + ret = NULL; + } } else { g_writeln("could not allocate memory for log struct"); - ret = LOG_ERROR_MALLOC; } return ret; } +void +internal_log_config_copy(struct log_config *dest, const struct log_config *src) +{ + int i; + + dest->enable_syslog = src->enable_syslog; + dest->fd = src->fd; + dest->log_file = g_strdup(src->log_file); + dest->log_level = src->log_level; + dest->log_lock = src->log_lock; + dest->log_lock_attr = src->log_lock_attr; + dest->program_name = src->program_name; + dest->enable_syslog = src->enable_syslog; + dest->syslog_level = src->syslog_level; + dest->enable_console = src->enable_console; + dest->console_level = src->console_level; + dest->enable_pid = src->enable_pid; + dest->dump_on_start = src->dump_on_start; + for (i = 0; i < src->per_logger_level->count; ++i) + { + struct log_logger_level *dst_logger = + (struct log_logger_level *)g_malloc(sizeof(struct log_logger_level), 1); + + g_memcpy(dst_logger, + (struct log_logger_level *) list_get_item(src->per_logger_level, i), + sizeof(struct log_logger_level)); + + list_add_item(dest->per_logger_level, (tbus) dst_logger); + } +} + +bool_t +internal_log_is_enabled_for_level(const enum logLevels log_level, + const bool_t override_destination_level, + const enum logLevels override_log_level) +{ + /* Is log initialized? */ + if (g_staticLogConfig == NULL) + { + return 0; + } + else if (g_staticLogConfig->fd < 0 + && !g_staticLogConfig->enable_syslog + && !g_staticLogConfig->enable_console) + { + /* all logging outputs are disabled */ + return 0; + } + else if (override_destination_level) + { + /* Override is enabled - should the message should be logged? */ + return log_level <= override_log_level; + } + /* Override is disabled - Is there at least one log destination + * which will accept the message based on the log level? */ + else if (g_staticLogConfig->fd >= 0 + && log_level <= g_staticLogConfig->log_level) + { + return 1; + } + else if (g_staticLogConfig->enable_syslog + && log_level <= g_staticLogConfig->syslog_level) + { + return 1; + } + else if (g_staticLogConfig->enable_console + && log_level <= g_staticLogConfig->console_level) + { + return 1; + } + else + { + return 0; + } +} + +bool_t +internal_log_location_overrides_level(const char *function_name, + const char *file_name, + enum logLevels *log_level_return) +{ + struct log_logger_level *logger = NULL; + int i; + + if (g_staticLogConfig == NULL) + { + return 0; + } + for (i = 0; i < g_staticLogConfig->per_logger_level->count; i++) + { + logger = (struct log_logger_level *)list_get_item(g_staticLogConfig->per_logger_level, i); + + if ((logger->logger_type == LOG_TYPE_FILE + && 0 == g_strncmp(logger->logger_name, file_name, LOGGER_NAME_SIZE)) + || (logger->logger_type == LOG_TYPE_FUNCTION + && 0 == g_strncmp(logger->logger_name, function_name, LOGGER_NAME_SIZE))) + { + *log_level_return = logger->log_level; + return 1; + } + } + + return 0; +} + /* * Here below the public functions */ +struct log_config * +log_config_init_for_console(enum logLevels lvl, const char *override_name) +{ + struct log_config *config = internalInitAndAllocStruct(); + + if (config != NULL) + { + config->program_name = ""; + config->enable_console = 1; + if (override_name != NULL && override_name[0] != '\0') + { + config->console_level = internal_log_text2level(override_name); + } + else + { + config->console_level = lvl; + } + config->dump_on_start = 0; /* Don't need dump for console only */ + } + return config; +} + + +struct log_config * +log_config_init_from_config(const char *iniFilename, + const char *applicationName, + const char *section_prefix) +{ + int fd; + struct log_config *config; + + if (applicationName == NULL) + { + g_writeln("Programming error your application name cannot be null"); + return NULL; + } + + if (iniFilename == NULL) + { + g_writeln("The inifile is null to log_config_init_from_config!"); + return NULL; + } + + fd = g_file_open_ex(iniFilename, 1, 0, 0, 0); + + if (-1 == fd) + { + g_writeln("We could not open the configuration file to read log parameters"); + return NULL; + } + + /* read logging config */ + config = internal_config_read_logging(fd, applicationName, section_prefix); + + /* cleanup */ + g_file_close(fd); + return config; +} + +enum logReturns +log_config_free(struct log_config *config) +{ + if (config != NULL) + { + if (config->per_logger_level != NULL) + { + list_delete(config->per_logger_level); + config->per_logger_level = NULL; + } + g_free(config); + } + + return LOG_STARTUP_OK; +} + enum logReturns -log_start_from_param(const struct log_config *iniParams) +log_start_from_param(const struct log_config *src_log_config) { enum logReturns ret = LOG_GENERAL_ERROR; @@ -426,41 +685,28 @@ return ret; } - if (iniParams == NULL) + if (src_log_config == NULL) { - g_writeln("inparam to log_start_from_param is NULL"); + g_writeln("src_log_config to log_start_from_param is NULL"); return ret; } else { - /*Copy the struct information*/ - ret = internalInitAndAllocStruct(); - - if (ret != LOG_STARTUP_OK) + g_staticLogConfig = internalInitAndAllocStruct(); + if (g_staticLogConfig == NULL) { g_writeln("internalInitAndAllocStruct failed"); - return ret; + return LOG_ERROR_MALLOC; } + internal_log_config_copy(g_staticLogConfig, src_log_config); - g_staticLogConfig->enable_syslog = iniParams->enable_syslog; - g_staticLogConfig->fd = iniParams->fd; - g_staticLogConfig->log_file = g_strdup(iniParams->log_file); - g_staticLogConfig->log_level = iniParams->log_level; - g_staticLogConfig->log_lock = iniParams->log_lock; - g_staticLogConfig->log_lock_attr = iniParams->log_lock_attr; - g_staticLogConfig->program_name = iniParams->program_name; - g_staticLogConfig->syslog_level = iniParams->syslog_level; ret = internal_log_start(g_staticLogConfig); - if (ret != LOG_STARTUP_OK) { g_writeln("Could not start log"); - if (g_staticLogConfig != NULL) - { - g_free(g_staticLogConfig); - g_staticLogConfig = NULL; - } + log_config_free(g_staticLogConfig); + g_staticLogConfig = NULL; } } @@ -478,28 +724,18 @@ log_start(const char *iniFile, const char *applicationName) { enum logReturns ret = LOG_GENERAL_ERROR; + struct log_config *config; - if (applicationName == NULL) - { - g_writeln("Programming error your application name cannot be null"); - return ret; - } + config = log_config_init_from_config(iniFile, applicationName, ""); - ret = internalReadConfiguration(iniFile, applicationName); - - if (ret == LOG_STARTUP_OK) + if (config != NULL) { - ret = internal_log_start(g_staticLogConfig); + ret = log_start_from_param(config); + log_config_free(config); if (ret != LOG_STARTUP_OK) { g_writeln("Could not start log"); - - if (g_staticLogConfig != NULL) - { - g_free(g_staticLogConfig); - g_staticLogConfig = NULL; - } } } else @@ -520,21 +756,230 @@ { enum logReturns ret = LOG_GENERAL_ERROR; ret = internal_log_end(g_staticLogConfig); + log_config_free(g_staticLogConfig); + g_staticLogConfig = NULL; - if (g_staticLogConfig != NULL) + return ret; +} + +/*****************************************************************************/ +/* produce a hex dump */ +enum logReturns +log_hexdump_with_location(const char *function_name, + const char *file_name, + const int line_number, + const enum logLevels log_level, + const char *message, + const char *src, + int len) +{ + unsigned char *line; + int i; + int dump_number_lines; + int dump_line_length; + int dump_length; + int dump_offset; + int thisline; + int offset; + char *dump_buffer; + enum logReturns rv; + enum logLevels override_log_level; + bool_t override_destination_level = 0; + + /* Start the dump on a new line so that the first line of the dump is + aligned to the first column instead of to after the log message + preamble (eg. time, log level, ...) + */ +#define HEX_DUMP_SOURCE_BYTES_PER_LINE (16) +#ifdef _WIN32 +#define HEX_DUMP_HEADER ("%s Hex Dump:\r\n") +#define HEX_DUMP_NEWLINE_SIZE (2) +#else +#ifdef _MACOS +#define HEX_DUMP_HEADER ("%s Hex Dump:\r") +#define HEX_DUMP_NEWLINE_SIZE (1) +#else +#define HEX_DUMP_HEADER ("%s Hex Dump:\n") +#define HEX_DUMP_NEWLINE_SIZE (1) +#endif +#endif +#define HEX_DUMP_HEADER_SIZE (sizeof(HEX_DUMP_HEADER) - 1) + + override_destination_level = internal_log_location_overrides_level( + function_name, + file_name, + &override_log_level); + if (!internal_log_is_enabled_for_level(log_level, override_destination_level, override_log_level)) { - g_free(g_staticLogConfig); - g_staticLogConfig = NULL; + return LOG_STARTUP_OK; } - return ret; + dump_line_length = (4 + 3 /* = 4 offset + 3 space */ + + ((2 + 1) * HEX_DUMP_SOURCE_BYTES_PER_LINE) /* + (2 hex char + 1 space) per source byte */ + + 2 /* + 2 space */ + + HEX_DUMP_SOURCE_BYTES_PER_LINE + + HEX_DUMP_NEWLINE_SIZE); + + dump_number_lines = (len / HEX_DUMP_SOURCE_BYTES_PER_LINE) + 1; /* +1 to round up */ + dump_length = (dump_number_lines *dump_line_length /* hex dump lines */ + + HEX_DUMP_HEADER_SIZE + + 1); /* terminating NULL */ + dump_buffer = (char *)g_malloc(dump_length, 1); + if (dump_buffer == NULL) + { + LOG_DEVEL(LOG_LEVEL_WARNING, + "Failed to allocate buffer for hex dump of size %d", + dump_length); + return LOG_ERROR_MALLOC; + } + + line = (unsigned char *)src; + offset = 0; + + g_memcpy(dump_buffer, HEX_DUMP_HEADER, HEX_DUMP_HEADER_SIZE); + dump_offset = HEX_DUMP_HEADER_SIZE; + + while (offset < len) + { + g_sprintf(dump_buffer + dump_offset, "%04x ", offset); + dump_offset += 7; + thisline = len - offset; + + if (thisline > HEX_DUMP_SOURCE_BYTES_PER_LINE) + { + thisline = HEX_DUMP_SOURCE_BYTES_PER_LINE; + } + + for (i = 0; i < thisline; i++) + { + g_sprintf(dump_buffer + dump_offset, "%02x ", line[i]); + dump_offset += 3; + } + + for (; i < HEX_DUMP_SOURCE_BYTES_PER_LINE; i++) + { + dump_buffer[dump_offset++] = ' '; + dump_buffer[dump_offset++] = ' '; + dump_buffer[dump_offset++] = ' '; + } + + dump_buffer[dump_offset++] = ' '; + dump_buffer[dump_offset++] = ' '; + + for (i = 0; i < thisline; i++) + { + dump_buffer[dump_offset++] = (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.'; + } + + for (; i < HEX_DUMP_SOURCE_BYTES_PER_LINE; i++) + { + dump_buffer[dump_offset++] = ' '; + } + +#ifdef _WIN32 + dump_buffer[dump_offset++] = '\r'; + dump_buffer[dump_offset++] = '\n'; +#else +#ifdef _MACOS + dump_buffer[dump_offset++] = '\r'; +#else + dump_buffer[dump_offset++] = '\n'; +#endif +#endif + offset += thisline; + line += thisline; + + + if ((dump_offset - HEX_DUMP_HEADER_SIZE) % dump_line_length != 0) + { + LOG_DEVEL(LOG_LEVEL_ERROR, + "BUG: dump_offset (%d) at the end of a line is not a " + "multiple of the line length (%d)", + dump_offset, dump_line_length); + } + + } + if (dump_offset > dump_length) + { + LOG_DEVEL(LOG_LEVEL_ERROR, + "BUG: dump_offset (%d) is larger than the dump_buffer length (%d)", + dump_offset, dump_length); + g_free(dump_buffer); + return LOG_GENERAL_ERROR; + } + + /* replace the last new line with the end of the string since log_message + will add a new line */ + dump_buffer[dump_offset - HEX_DUMP_NEWLINE_SIZE] = '\0'; + + rv = log_message_with_location(function_name, file_name, line_number, + log_level, dump_buffer, message); + g_free(dump_buffer); + return rv; +} + +enum logReturns +log_message_with_location(const char *function_name, + const char *file_name, + const int line_number, + const enum logLevels level, + const char *msg, + ...) +{ + va_list ap; + enum logReturns rv; + char buff[LOG_BUFFER_SIZE]; + enum logLevels override_log_level = LOG_LEVEL_NEVER; + bool_t override_destination_level = 0; + + if (g_staticLogConfig == NULL) + { + g_writeln("The log reference is NULL - log not initialized properly " + "when called from [%s(%s:%d)]", + (function_name != NULL ? function_name : "unknown_function"), + (file_name != NULL ? file_name : "unknown_file"), + line_number); + return LOG_ERROR_NO_CFG; + } + + override_destination_level = internal_log_location_overrides_level( + function_name, + file_name, + &override_log_level); + if (!internal_log_is_enabled_for_level(level, override_destination_level, override_log_level)) + { + return LOG_STARTUP_OK; + } + + g_snprintf(buff, LOG_BUFFER_SIZE, "[%s(%s:%d)] %s", + function_name, file_name, line_number, msg); + + va_start(ap, msg); + rv = internal_log_message(level, override_destination_level, override_log_level, buff, ap); + va_end(ap); + return rv; } enum logReturns log_message(const enum logLevels lvl, const char *msg, ...) { - char buff[LOG_BUFFER_SIZE + 31]; /* 19 (datetime) 4 (space+cr+lf+\0) */ va_list ap; + enum logReturns rv; + + va_start(ap, msg); + rv = internal_log_message(lvl, 0, LOG_LEVEL_NEVER, msg, ap); + va_end(ap); + return rv; +} + +enum logReturns +internal_log_message(const enum logLevels lvl, + const bool_t override_destination_level, + const enum logLevels override_log_level, + const char *msg, + va_list ap) +{ + char buff[LOG_BUFFER_SIZE + 31]; /* 19 (datetime) 4 (space+cr+lf+\0) */ int len = 0; enum logReturns rv = LOG_STARTUP_OK; int writereply = 0; @@ -547,28 +992,38 @@ return LOG_ERROR_NO_CFG; } - if (0 > g_staticLogConfig->fd && g_staticLogConfig->enable_syslog == 0) + if (0 > g_staticLogConfig->fd + && g_staticLogConfig->enable_syslog == 0 + && g_staticLogConfig->enable_console == 0) { return LOG_ERROR_FILE_NOT_OPEN; } + if (!internal_log_is_enabled_for_level(lvl, override_destination_level, override_log_level)) + { + return LOG_STARTUP_OK; + } + now_t = time(&now_t); now = localtime(&now_t); - snprintf(buff, 21, "[%.4d%.2d%.2d-%.2d:%.2d:%.2d] ", now->tm_year + 1900, - now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min, - now->tm_sec); + strftime(buff, 21, "[%Y%m%d-%H:%M:%S] ", now); internal_log_lvl2str(lvl, buff + 20); - va_start(ap, msg); - len = vsnprintf(buff + 28, LOG_BUFFER_SIZE, msg, ap); - va_end(ap); + if (g_staticLogConfig->enable_pid) + { + g_snprintf(buff + 28, LOG_BUFFER_SIZE, "[pid:%d tid:%lld] ", + g_getpid(), (long long) tc_get_threadid()); + len = g_strlen(buff + 28); + } + len += vsnprintf(buff + 28 + len, LOG_BUFFER_SIZE - len, msg, ap); /* checking for truncated messages */ 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 */ @@ -586,37 +1041,44 @@ #endif #endif - if (g_staticLogConfig->enable_syslog && (lvl <= g_staticLogConfig->syslog_level)) + if (g_staticLogConfig->enable_syslog + && ((override_destination_level && lvl <= override_log_level) + || (!override_destination_level && lvl <= g_staticLogConfig->syslog_level))) { /* log to syslog*/ /* %s fix compiler warning 'not a string literal' */ - syslog(internal_log_xrdp2syslog(lvl), "(%d)(%lld)%s", g_getpid(), - (long long) tc_get_threadid(), buff + 20); + syslog(internal_log_xrdp2syslog(lvl), "%s", buff + 20); } - if (lvl <= g_staticLogConfig->log_level) + if (g_staticLogConfig->enable_console + && ((override_destination_level && lvl <= override_log_level) + || (!override_destination_level && lvl <= g_staticLogConfig->console_level))) { /* log to console */ g_printf("%s", buff); + } + if ((override_destination_level && lvl <= override_log_level) + || (!override_destination_level && lvl <= g_staticLogConfig->log_level)) + { /* log to application logfile */ + if (g_staticLogConfig->fd >= 0) + { #ifdef LOG_ENABLE_THREAD - pthread_mutex_lock(&(g_staticLogConfig->log_lock)); + pthread_mutex_lock(&(g_staticLogConfig->log_lock)); #endif - if (g_staticLogConfig->fd >= 0) - { writereply = g_file_write(g_staticLogConfig->fd, buff, g_strlen(buff)); if (writereply <= 0) { rv = LOG_ERROR_NULL_FILE; } - } #ifdef LOG_ENABLE_THREAD - pthread_mutex_unlock(&(g_staticLogConfig->log_lock)); + pthread_mutex_unlock(&(g_staticLogConfig->log_lock)); #endif + } } return rv; diff -Nru xrdp-0.9.12/common/log.h xrdp-0.9.15/common/log.h --- xrdp-0.9.12/common/log.h 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/common/log.h 2020-12-28 14:03:43.000000000 +0000 @@ -22,19 +22,22 @@ #include #include "arch.h" +#include "list.h" /* logging buffer size */ -#define LOG_BUFFER_SIZE 1024 +#define LOG_BUFFER_SIZE 8192 +#define LOGGER_NAME_SIZE 50 /* logging levels */ enum logLevels { LOG_LEVEL_ALWAYS = 0, - LOG_LEVEL_ERROR, - LOG_LEVEL_WARNING, - LOG_LEVEL_INFO, - LOG_LEVEL_DEBUG, - LOG_LEVEL_TRACE + LOG_LEVEL_ERROR, /* for describing non-recoverable error states in a request or method */ + LOG_LEVEL_WARNING, /* for describing recoverable error states in a request or method */ + LOG_LEVEL_INFO, /* for low verbosity and high level descriptions of normal operations */ + LOG_LEVEL_DEBUG, /* for medium verbosity and low level descriptions of normal operations */ + LOG_LEVEL_TRACE, /* for high verbosity and low level descriptions of normal operations (eg. method or wire tracing) */ + LOG_LEVEL_NEVER, }; /* startup return values */ @@ -49,29 +52,113 @@ LOG_GENERAL_ERROR }; -#define SESMAN_CFG_LOGGING "Logging" -#define SESMAN_CFG_LOG_FILE "LogFile" -#define SESMAN_CFG_LOG_LEVEL "LogLevel" -#define SESMAN_CFG_LOG_ENABLE_SYSLOG "EnableSyslog" -#define SESMAN_CFG_LOG_SYSLOG_LEVEL "SyslogLevel" +#define SESMAN_CFG_LOGGING "Logging" +#define SESMAN_CFG_LOGGING_LOGGER "LoggingPerLogger" +#define SESMAN_CFG_LOG_FILE "LogFile" +#define SESMAN_CFG_LOG_LEVEL "LogLevel" +#define SESMAN_CFG_LOG_ENABLE_CONSOLE "EnableConsole" +#define SESMAN_CFG_LOG_CONSOLE_LEVEL "ConsoleLevel" +#define SESMAN_CFG_LOG_ENABLE_SYSLOG "EnableSyslog" +#define SESMAN_CFG_LOG_SYSLOG_LEVEL "SyslogLevel" +#define SESMAN_CFG_LOG_ENABLE_PID "EnableProcessId" /* enable threading */ /*#define LOG_ENABLE_THREAD*/ #ifdef XRDP_DEBUG -#define LOG_DBG(args...) log_message(LOG_LEVEL_DEBUG, args); + +#define LOG_PER_LOGGER_LEVEL + +/** + * @brief Logging macro for messages that are for an XRDP developer to + * understand and debug XRDP code. + * + * Note: all log levels are relavant to help a developer understand XRDP at + * different levels of granularity. + * + * Note: the logging function calls are removed when XRDP_DEBUG is NOT defined. + * + * Note: when the build is configured with --enable-xrdpdebug, then + * the log level can be configured per the source file name or method name + * (with the suffix "()") in the [LoggingPerLogger] + * section of the configuration file. + * + * For example: + * ``` + * [LoggingPerLogger] + * xrdp.c=DEBUG + * main()=WARNING + * ``` + * + * @param lvl, the log level + * @param msg, the log text as a printf format c-string + * @param ... the arguments for the printf format c-string + */ +#define LOG_DEVEL(log_level, args...) \ + log_message_with_location(__func__, __FILE__, __LINE__, log_level, args); + +/** + * @brief Logging macro for messages that are for a systeam administrator to + * configure and run XRDP on their machine. + * + * Note: the logging function calls contain additional code location info when + * XRDP_DEBUG is defined. + * + * @param lvl, the log level + * @param msg, the log text as a printf format c-string + * @param ... the arguments for the printf format c-string + */ +#define LOG(log_level, args...) \ + log_message_with_location(__func__, __FILE__, __LINE__, log_level, args); + +/** + * @brief Logging macro for logging the contents of a byte array using a hex + * dump format. + * + * Note: the logging function calls are removed when XRDP_DEBUG is NOT defined. + * + * @param log_level, the log level + * @param message, a message prefix for the hex dump. Note: no printf like + * formatting is done to this message. + * @param buffer, a pointer to the byte array to log as a hex dump + * @param length, the length of the byte array to log + */ +#define LOG_DEVEL_HEXDUMP(log_level, message, buffer, length) \ + log_hexdump_with_location(__func__, __FILE__, __LINE__, log_level, message, buffer, length); + #else -#define LOG_DBG(args...) +#define LOG_DEVEL(log_level, args...) +#define LOG(log_level, args...) log_message(log_level, args); +#define LOG_DEVEL_HEXDUMP(log_level, message, buffer, length) + #endif +enum log_logger_type +{ + LOG_TYPE_FILE = 0, + LOG_TYPE_FUNCTION, +}; + +struct log_logger_level +{ + enum logLevels log_level; + enum log_logger_type logger_type; + char logger_name[LOGGER_NAME_SIZE + 1]; +}; + struct log_config { const char *program_name; char *log_file; int fd; enum logLevels log_level; + int enable_console; + enum logLevels console_level; int enable_syslog; enum logLevels syslog_level; + struct list *per_logger_level; + int dump_on_start; + int enable_pid; pthread_mutex_t log_lock; pthread_mutexattr_t log_lock_attr; }; @@ -114,32 +201,64 @@ * */ 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 * also init its content. * @return LOG_STARTUP_OK or LOG_ERROR_MALLOC */ -enum logReturns +struct log_config * internalInitAndAllocStruct(void); /** - * Read configuration from a file and store the values in lists. - * @param file - * @param lc - * @param param_n - * @param param_v - * @param applicationName, the application name used in the log events. + * Print the contents of the logging config to stdout. + */ +void +internal_log_config_dump(struct log_config *config); + +/** + * the log function that all files use to log an event. + * @param lvl, the loglevel + * @param override_destination_level, if true then the destination log level is not used + * @param override_log_level, the loglevel instead of the destination log level if override_destination_level is true + * @param msg, the logtext. + * @param ap, the values for the message format arguments * @return */ enum logReturns -internal_config_read_logging(int file, struct log_config *lc, - struct list *param_n, - struct list *param_v, - const char *applicationName); +internal_log_message(const enum logLevels lvl, + const bool_t override_destination_level, + const enum logLevels override_log_level, + const char *msg, + va_list ap); + +/** + * @param log_level, the log level + * @param override_destination_level, if true then the destination log level is ignored. + * @param override_log_level, the log level to use instead of the destination log level + * if override_destination_level is true + * @return true if at least one log destination will accept a message logged at the given level. + */ +bool_t +internal_log_is_enabled_for_level(const enum logLevels log_level, + const bool_t override_destination_level, + const enum logLevels override_log_level); + +/** + * @param function_name, the function name (typicaly the __func__ macro) + * @param file_name, the file name (typicaly the __FILE__ macro) + * @param[out] log_level_return, the log level to use instead of the destination log level + * @return true if the logger location overrides the destination log levels + */ +bool_t +internal_log_location_overrides_level(const char *function_name, + const char *file_name, + enum logLevels *log_level_return); + /*End of internal functions*/ #endif + /** * This function initialize the log facilities according to the configuration * file, that is described by the in parameter. @@ -152,11 +271,51 @@ /** * An alternative log_start where the caller gives the params directly. - * @param iniParams + * @param config * @return + * + * @post to avoid memory leaks, the config argument must be free'ed using + * `log_config_free()` */ enum logReturns -log_start_from_param(const struct log_config *iniParams); +log_start_from_param(const struct log_config *src_log_config); + +/** + * Sets up a suitable log config for writing to the console only + * (i.e. for a utility) + * + * The config can be customised by the caller before calling + * log_start_from_param() + * + * @param Default log level + * @param Log level name, or NULL. This can be used to provide an + * override to the default log level, by environment variable or + * argument. + * + * @return pointer to struct log_config. + */ +struct log_config * +log_config_init_for_console(enum logLevels lvl, const char *override_name); + +/** + * Read configuration from a file and store the values in the returned + * log_config. + * @param file + * @param applicationName, the application name used in the log events. + * @param section_prefix, prefix for the logging sections to parse + * @return + */ +struct log_config * +log_config_init_from_config(const char *iniFilename, + const char *applicationName, + const char *section_prefix); + +/** + * Free the memory for the log_config struct. + */ +enum logReturns +log_config_free(struct log_config *config); + /** * Function that terminates all logging * @return @@ -166,6 +325,9 @@ /** * the log function that all files use to log an event. + * + * Please prefer to use the LOG and LOG_DEVEL macros instead of this function directly. + * * @param lvl, the loglevel * @param msg, the logtext. * @param ... @@ -175,6 +337,37 @@ log_message(const enum logLevels lvl, const char *msg, ...) printflike(2, 3); /** + * the log function that all files use to log an event, + * with the function name and file line. + * + * Please prefer to use the LOG and LOG_DEVEL macros instead of this function directly. + * + * @param function_name, the function name (typicaly the __func__ macro) + * @param file_name, the file name (typicaly the __FILE__ macro) + * @param line_number, the line number in the file (typicaly the __LINE__ macro) + * @param lvl, the loglevel + * @param msg, the logtext. + * @param ... + * @return + */ +enum logReturns +log_message_with_location(const char *function_name, + const char *file_name, + const int line_number, + const enum logLevels lvl, + const char *msg, + ...) printflike(5, 6); + +enum logReturns +log_hexdump_with_location(const char *function_name, + const char *file_name, + const int line_number, + const enum logLevels log_level, + const char *msg, + const char *p, + int len); + +/** * This function returns the configured file name for the logfile * @param replybuf the buffer where the reply is stored * @param bufsize how big is the reply buffer. diff -Nru xrdp-0.9.12/common/Makefile.am xrdp-0.9.15/common/Makefile.am --- xrdp-0.9.12/common/Makefile.am 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/common/Makefile.am 2020-12-28 14:03:43.000000000 +0000 @@ -7,6 +7,14 @@ EXTRA_DIST = pixman-region.c include_HEADERS = \ + ms-erref.h \ + ms-fscc.h \ + ms-rdpbcgr.h \ + ms-rdpefs.h \ + ms-rdpegdi.h \ + ms-rdpele.h \ + ms-rdperp.h \ + ms-smb2.h \ xrdp_client_info.h \ xrdp_constants.h \ xrdp_rail.h \ @@ -46,11 +54,12 @@ log.h \ os_calls.c \ os_calls.h \ - os_calls.h \ parse.h \ rail.h \ ssl_calls.c \ ssl_calls.h \ + string_calls.c \ + string_calls.h \ thread_calls.c \ thread_calls.h \ trans.c \ diff -Nru xrdp-0.9.12/common/Makefile.in xrdp-0.9.15/common/Makefile.in --- xrdp-0.9.12/common/Makefile.in 2019-12-28 12:36:37.000000000 +0000 +++ xrdp-0.9.15/common/Makefile.in 2020-12-28 14:06:38.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -146,12 +146,13 @@ am__libcommon_la_SOURCES_DIST = arch.h base64.h base64.c defines.h \ fifo.c fifo.h file.c file.h list.c list.h list16.c list16.h \ log.c log.h os_calls.c os_calls.h parse.h rail.h ssl_calls.c \ - ssl_calls.h thread_calls.c thread_calls.h trans.c trans.h \ - pixman-region16.c pixman-region.h + ssl_calls.h string_calls.c string_calls.h thread_calls.c \ + thread_calls.h trans.c trans.h pixman-region16.c \ + pixman-region.h @XRDP_PIXMAN_FALSE@am__objects_1 = pixman-region16.lo am_libcommon_la_OBJECTS = base64.lo fifo.lo file.lo list.lo list16.lo \ - log.lo os_calls.lo ssl_calls.lo thread_calls.lo trans.lo \ - $(am__objects_1) + log.lo os_calls.lo ssl_calls.lo string_calls.lo \ + thread_calls.lo trans.lo $(am__objects_1) libcommon_la_OBJECTS = $(am_libcommon_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -176,8 +177,8 @@ ./$(DEPDIR)/file.Plo ./$(DEPDIR)/list.Plo \ ./$(DEPDIR)/list16.Plo ./$(DEPDIR)/log.Plo \ ./$(DEPDIR)/os_calls.Plo ./$(DEPDIR)/pixman-region16.Plo \ - ./$(DEPDIR)/ssl_calls.Plo ./$(DEPDIR)/thread_calls.Plo \ - ./$(DEPDIR)/trans.Plo + ./$(DEPDIR)/ssl_calls.Plo ./$(DEPDIR)/string_calls.Plo \ + ./$(DEPDIR)/thread_calls.Plo ./$(DEPDIR)/trans.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -373,6 +374,14 @@ @XRDP_PIXMAN_TRUE@PIXMAN_SOURCES = EXTRA_DIST = pixman-region.c include_HEADERS = \ + ms-erref.h \ + ms-fscc.h \ + ms-rdpbcgr.h \ + ms-rdpefs.h \ + ms-rdpegdi.h \ + ms-rdpele.h \ + ms-rdperp.h \ + ms-smb2.h \ xrdp_client_info.h \ xrdp_constants.h \ xrdp_rail.h \ @@ -405,11 +414,12 @@ log.h \ os_calls.c \ os_calls.h \ - os_calls.h \ parse.h \ rail.h \ ssl_calls.c \ ssl_calls.h \ + string_calls.c \ + string_calls.h \ thread_calls.c \ thread_calls.h \ trans.c \ @@ -508,6 +518,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os_calls.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pixman-region16.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_calls.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string_calls.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread_calls.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trans.Plo@am__quote@ # am--include-marker @@ -702,6 +713,7 @@ -rm -f ./$(DEPDIR)/os_calls.Plo -rm -f ./$(DEPDIR)/pixman-region16.Plo -rm -f ./$(DEPDIR)/ssl_calls.Plo + -rm -f ./$(DEPDIR)/string_calls.Plo -rm -f ./$(DEPDIR)/thread_calls.Plo -rm -f ./$(DEPDIR)/trans.Plo -rm -f Makefile @@ -758,6 +770,7 @@ -rm -f ./$(DEPDIR)/os_calls.Plo -rm -f ./$(DEPDIR)/pixman-region16.Plo -rm -f ./$(DEPDIR)/ssl_calls.Plo + -rm -f ./$(DEPDIR)/string_calls.Plo -rm -f ./$(DEPDIR)/thread_calls.Plo -rm -f ./$(DEPDIR)/trans.Plo -rm -f Makefile diff -Nru xrdp-0.9.12/common/ms-erref.h xrdp-0.9.15/common/ms-erref.h --- xrdp-0.9.12/common/ms-erref.h 1970-01-01 00:00:00.000000000 +0000 +++ xrdp-0.9.15/common/ms-erref.h 2020-12-28 13:47:11.000000000 +0000 @@ -0,0 +1,43 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * MS-ERREF : Definitions from [MS-ERREF] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * References to MS-ERREF are currently correct for v20180912 of that + * document + */ + +#if !defined(MS_ERREF_H) +#define MS_ERREF_H + +/* + * NTSTATUS codes (section 2.3) + */ +enum NTSTATUS +{ + STATUS_SUCCESS = 0x00000000, + + STATUS_NO_MORE_FILES = 0x80000006, + + STATUS_UNSUCCESSFUL = 0xc0000001, + STATUS_NO_SUCH_FILE = 0xc000000f, + STATUS_ACCESS_DENIED = 0xc0000022, + STATUS_OBJECT_NAME_INVALID = 0xc0000033, + STATUS_OBJECT_NAME_NOT_FOUND = 0xc0000034, + STATUS_SHARING_VIOLATION = 0xc0000043, + STATUS_NOT_SUPPORTED = 0xc00000bb +}; + +#endif /* MS_ERREF_H */ diff -Nru xrdp-0.9.12/common/ms-fscc.h xrdp-0.9.15/common/ms-fscc.h --- xrdp-0.9.12/common/ms-fscc.h 1970-01-01 00:00:00.000000000 +0000 +++ xrdp-0.9.15/common/ms-fscc.h 2020-12-28 13:47:11.000000000 +0000 @@ -0,0 +1,64 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * MS-FSCC : Definitions from [MS-FSCC] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * References to MS-FSCC are currently correct for v20190923 of that + * document + */ + +#if !defined(MS_FSCC_H) +#define MS_FSCC_H + +/* + * File system ioctl codes (section 2.3) + */ +#define FSCTL_DELETE_OBJECT_ID 0x900a0 + +/* + * File information classes (section 2.4) + */ +enum FS_INFORMATION_CLASS +{ + FileAllocationInformation = 19, /* Set */ + FileBasicInformation = 4, /* Query, Set */ + FileBothDirectoryInformation = 3, /* Query */ + FileDirectoryInformation = 1, /* Query */ + FileDispositionInformation = 13, /* Set */ + FileEndOfFileInformation = 20, /* Set */ + FileFullDirectoryInformation = 2, /* Query */ + FileNamesInformation = 12, /* Query */ + FileRenameInformation = 10, /* Set */ + FileStandardInformation = 5 /* Query */ +}; + +/* + * Size of structs above without trailing RESERVED fields (MS-RDPEFS + * 2.2.3.3.8) + */ +#define FILE_BASIC_INFORMATION_SIZE 36 +#define FILE_STD_INFORMATION_SIZE 22 +#define FILE_END_OF_FILE_INFORMATION_SIZE 8 + +/* Windows file attributes (section 2.6) */ +#define W_FILE_ATTRIBUTE_DIRECTORY 0x00000010 +#define W_FILE_ATTRIBUTE_READONLY 0x00000001 +#define W_FILE_ATTRIBUTE_SYSTEM 0x00000004 +#define W_FILE_ATTRIBUTE_NORMAL 0x00000080 + +#endif /* MS_FSCC_H */ + + + diff -Nru xrdp-0.9.12/common/ms-rdpbcgr.h xrdp-0.9.15/common/ms-rdpbcgr.h --- xrdp-0.9.12/common/ms-rdpbcgr.h 1970-01-01 00:00:00.000000000 +0000 +++ xrdp-0.9.15/common/ms-rdpbcgr.h 2020-12-28 13:47:11.000000000 +0000 @@ -0,0 +1,512 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * MS-RDPBCGR : Definitions from [MS-RDPBCGR] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * References to MS-RDPBCGR are currently correct for v20190923 of that + * document + */ + +#if !defined(MS_RDPBCGR_H) +#define MS_RDPBCGR_H + +/* RDP Security Negotiation codes */ +#define RDP_NEG_REQ 0x01 /* MS-RDPBCGR 2.2.1.1.1 */ +#define RDP_NEG_RSP 0x02 /* MS-RDPBCGR 2.2.1.2.1 */ +#define RDP_NEG_FAILURE 0x03 /* MS-RDPBCGR 2.2.1.2.2 */ +#define RDP_CORRELATION_INFO 0x06 /* MS-RDPBCGR 2.2.1.1.2 */ + +/* Protocol types codes (2.2.1.1.1, 2.2.1.2.1) */ +#define PROTOCOL_RDP 0x00000000 +#define PROTOCOL_SSL 0x00000001 +#define PROTOCOL_HYBRID 0x00000002 +#define PROTOCOL_RDSTLS 0x00000004 +#define PROTOCOL_HYBRID_EX 0x00000008 + +/* Negotiation packet flags (2.2.1.2.1) */ +#define EXTENDED_CLIENT_DATA_SUPPORTED 0x01 +#define DYNVC_GFX_PROTOCOL_SUPPORTED 0x02 +#define NEGRSP_RESERVED 0x04 +#define RESTRICTED_ADMIN_MODE_SUPPORTED 0x08 +#define REDIRECTED_AUTHENTICATION_MODE_SUPPORTED 0x10 + +/* RDP Negotiation Failure Codes (2.2.1.2.2) */ +#define SSL_REQUIRED_BY_SERVER 0x00000001 +#define SSL_NOT_ALLOWED_BY_SERVER 0x00000002 +#define SSL_CERT_NOT_ON_SERVER 0x00000003 +#define INCONSISTENT_FLAGS 0x00000004 +#define HYBRID_REQUIRED_BY_SERVER 0x00000005 +#define SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER 0x00000006 + +/* TS_UD_HEADER: type ((2.2.1.3.1) */ +/* TODO: to be renamed */ +#define SEC_TAG_CLI_INFO 0xc001 /* CS_CORE? */ +#define SEC_TAG_CLI_CRYPT 0xc002 /* CS_SECURITY? */ +#define SEC_TAG_CLI_CHANNELS 0xc003 /* CS_CHANNELS? */ +#define SEC_TAG_CLI_4 0xc004 /* CS_CLUSTER? */ +#define SEC_TAG_CLI_MONITOR 0xc005 /* CS_MONITOR */ + +/* Client Core Data: colorDepth, postBeta2ColorDepth (2.2.1.3.2) */ +#define RNS_UD_COLOR_4BPP 0xCA00 +#define RNS_UD_COLOR_8BPP 0xCA01 +#define RNS_UD_COLOR_16BPP_555 0xCA02 +#define RNS_UD_COLOR_16BPP_565 0xCA03 +#define RNS_UD_COLOR_24BPP 0xCA04 + +/* Client Core Data: connectionType (2.2.1.3.2) */ +#define CONNECTION_TYPE_MODEM 0x01 +#define CONNECTION_TYPE_BROADBAND_LOW 0x02 +#define CONNECTION_TYPE_SATELLITE 0x03 +#define CONNECTION_TYPE_BROADBAND_HIGH 0x04 +#define CONNECTION_TYPE_WAN 0x05 +#define CONNECTION_TYPE_LAN 0x06 +#define CONNECTION_TYPE_AUTODETECT 0x07 + +/* 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 +#define XR_CHANNEL_OPTION_ENCRYPT_SC 0x20000000 +#define XR_CHANNEL_OPTION_ENCRYPT_CS 0x10000000 +#define XR_CHANNEL_OPTION_PRI_HIGH 0x08000000 +#define XR_CHANNEL_OPTION_PRI_MED 0x04000000 +#define XR_CHANNEL_OPTION_PRI_LOW 0x02000000 +#define XR_CHANNEL_OPTION_COMPRESS_RDP 0x00800000 +#define XR_CHANNEL_OPTION_COMPRESS 0x00400000 +#define XR_CHANNEL_OPTION_SHOW_PROTOCOL 0x00200000 +#define REMOTE_CONTROL_PERSISTENT 0x00100000 + +/* Server Proprietary Certificate (2.2.1.4.3.1.1) */ +/* TODO: to be renamed */ +#define SEC_TAG_PUBKEY 0x0006 /* BB_RSA_KEY_BLOB */ +#define SEC_TAG_KEYSIG 0x0008 /* BB_SIGNATURE_KEY_BLOB */ + +/* Info Packet (TS_INFO_PACKET): flags (2.2.1.11.1.1) */ +/* TODO: to be renamed */ +#define RDP_LOGON_AUTO 0x0008 +#define RDP_LOGON_NORMAL 0x0033 +#define RDP_COMPRESSION 0x0080 +#define RDP_LOGON_BLOB 0x0100 +#define RDP_LOGON_LEAVE_AUDIO 0x2000 +#define RDP_LOGON_RAIL 0x8000 + +/* Extended Info Packet: performanceFlags (2.2.1.11.1.1.1) */ +/* TODO: to be renamed */ +#define RDP5_DISABLE_NOTHING 0x00 +#define RDP5_NO_WALLPAPER 0x01 +#define RDP5_NO_FULLWINDOWDRAG 0x02 +#define RDP5_NO_MENUANIMATIONS 0x04 +#define RDP5_NO_THEMING 0x08 +#define RDP5_NO_CURSOR_SHADOW 0x20 +#define RDP5_NO_CURSORSETTINGS 0x40 /* disables cursor blinking */ + +/* LICENSE_BINARY_BLOB (2.2.1.12.1.2) */ +#define LICENCE_TAG_USER 0x000f /* BB_CLIENT_USER_NAME_BLOB */ +#define LICENCE_TAG_HOST 0x0010 /* BB_CLIENT_MACHINE_NAME_BLOB */ + +/* Maps to generalCapabilitySet in T.128 page 138 */ + +/* Capability Set: capabilitySetType (2.2.1.13.1.1.1) */ +#define CAPSTYPE_GENERAL 0x0001 +#define CAPSTYPE_GENERAL_LEN 0x18 + +#define CAPSTYPE_BITMAP 0x0002 +#define CAPSTYPE_BITMAP_LEN 0x1C + +#define CAPSTYPE_ORDER 0x0003 +#define CAPSTYPE_ORDER_LEN 0x58 +#define ORDER_CAP_NEGOTIATE 2 /* NEGOTIATEORDERSUPPORT? not used */ +#define ORDER_CAP_NOSUPPORT 4 /* not used */ + +#define CAPSTYPE_BITMAPCACHE 0x0004 +#define CAPSTYPE_BITMAPCACHE_LEN 0x28 + +#define CAPSTYPE_CONTROL 0x0005 +#define CAPSTYPE_CONTROL_LEN 0x0C + +#define CAPSTYPE_ACTIVATION 0x0007 +#define CAPSTYPE_ACTIVATION_LEN 0x0C + +#define CAPSTYPE_POINTER 0x0008 +#define CAPSTYPE_POINTER_LEN 0x0a +#define CAPSTYPE_POINTER_MONO_LEN 0x08 + +#define CAPSTYPE_SHARE 0x0009 +#define CAPSTYPE_SHARE_LEN 0x08 + +#define CAPSTYPE_COLORCACHE 0x000A +#define CAPSTYPE_COLORCACHE_LEN 0x08 + +#define CAPSTYPE_SOUND 0x000C + +#define CAPSTYPE_INPUT 0x000D +#define CAPSTYPE_INPUT_LEN 0x58 + +#define CAPSTYPE_FONT 0x000E +#define CAPSTYPE_FONT_LEN 0x04 + +#define CAPSTYPE_BRUSH 0x000F +#define CAPSTYPE_BRUSH_LEN 0x08 + +#define CAPSTYPE_GLYPHCACHE 0x0010 +#define CAPSTYPE_OFFSCREENCACHE 0x0011 + +#define CAPSTYPE_BITMAPCACHE_HOSTSUPPORT 0x0012 +#define CAPSTYPE_BITMAPCACHE_HOSTSUPPORT_LEN 0x08 + +#define CAPSTYPE_BITMAPCACHE_REV2 0x0013 +#define CAPSTYPE_BITMAPCACHE_REV2_LEN 0x28 +#define BMPCACHE2_FLAG_PERSIST ((long)1<<31) + +#define CAPSTYPE_VIRTUALCHANNEL 0x0014 +#define CAPSTYPE_VIRTUALCHANNEL_LEN 0x08 + +#define CAPSTYPE_DRAWNINGRIDCACHE 0x0015 +#define CAPSTYPE_DRAWGDIPLUS 0x0016 +#define CAPSTYPE_RAIL 0x0017 +#define CAPSTYPE_WINDOW 0x0018 + +#define CAPSSETTYPE_COMPDESK 0x0019 +#define CAPSSETTYPE_COMPDESK_LEN 0x06 + +#define CAPSSETTYPE_MULTIFRAGMENTUPDATE 0x001A +#define CAPSSETTYPE_MULTIFRAGMENTUPDATE_LEN 0x08 + +#define CAPSETTYPE_LARGE_POINTER 0x001B +#define CAPSETTYPE_LARGE_POINTER_LEN 0x06 + +#define CAPSETTYPE_SURFACE_COMMANDS 0x001C +#define CAPSETTYPE_SURFACE_COMMANDS_LEN 0x0C + +#define CAPSSETTYPE_BITMAP_CODECS 0x001D +#define CAPSSETTYPE_BITMAP_CODECS_LEN 0x1C + +#define CAPSTYPE_FRAME_ACKNOWLEDGE 0x001E +#define CAPSTYPE_FRAME_ACKNOWLEDGE_LEN 0x08 + +/* Control PDU Data: action (2.2.1.15.1) */ +/* TODO: to be renamed */ +#define RDP_CTL_REQUEST_CONTROL 1 /* CTRLACTION_REQUEST_CONTROL */ +#define RDP_CTL_GRANT_CONTROL 2 +#define RDP_CTL_DETACH 3 +#define RDP_CTL_COOPERATE 4 + +/* RDP5 disconnect PDU */ +/* Set Error Info PDU Data: errorInfo (2.2.5.1.1) */ +/* TODO: to be renamed */ +#define exDiscReasonNoInfo 0x0000 +#define exDiscReasonAPIInitiatedDisconnect 0x0001 +#define exDiscReasonAPIInitiatedLogoff 0x0002 +#define exDiscReasonServerIdleTimeout 0x0003 +#define exDiscReasonServerLogonTimeout 0x0004 +#define exDiscReasonReplacedByOtherConnection 0x0005 +#define exDiscReasonOutOfMemory 0x0006 +#define exDiscReasonServerDeniedConnection 0x0007 +#define exDiscReasonServerDeniedConnectionFips 0x0008 +#define exDiscReasonLicenseInternal 0x0100 +#define exDiscReasonLicenseNoLicenseServer 0x0101 +#define exDiscReasonLicenseNoLicense 0x0102 +#define exDiscReasonLicenseErrClientMsg 0x0103 +#define exDiscReasonLicenseHwidDoesntMatchLicense 0x0104 +#define exDiscReasonLicenseErrClientLicense 0x0105 +#define exDiscReasonLicenseCantFinishProtocol 0x0106 +#define exDiscReasonLicenseClientEndedProtocol 0x0107 +#define exDiscReasonLicenseErrClientEncryption 0x0108 +#define exDiscReasonLicenseCantUpgradeLicense 0x0109 +#define exDiscReasonLicenseNoRemoteConnections 0x010a + +/* General Capability Set: osMajorType (2.2.7.1.1) */ +#define OSMAJORTYPE_UNSPECIFIED 0x0000 +#define OSMAJORTYPE_WINDOWS 0x0001 +#define OSMAJORTYPE_OS2 0x0002 +#define OSMAJORTYPE_MACINTOSH 0x0003 +#define OSMAJORTYPE_UNIX 0x0004 +#define OSMAJORTYPE_IOS 0x0005 +#define OSMAJORTYPE_OSX 0x0006 +#define OSMAJORTYPE_ANDROID 0x0007 +#define OSMAJORTYPE_CHROME_OS 0x0008 + +/* General Capability Set: osMinorType (2.2.7.1.1) */ +#define OSMINORTYPE_UNSPECIFIED 0x0000 +#define OSMINORTYPE_WINDOWS_31X 0x0001 +#define OSMINORTYPE_WINDOWS_95 0x0002 +#define OSMINORTYPE_WINDOWS_NT 0x0003 +#define OSMINORTYPE_OS2_V21 0x0004 +#define OSMINORTYPE_POWER_PC 0x0005 +#define OSMINORTYPE_MACINTOSH 0x0006 +#define OSMINORTYPE_NATIVE_XSERVER 0x0007 +#define OSMINORTYPE_PSEUDO_XSERVER 0x0008 +#define OSMINORTYPE_WINDOWS_RT 0x0009 + +/* General Capability Set: protocolVersion (2.2.7.1.1) */ +#define TS_CAPS_PROTOCOLVERSION 0x0200 + +/* General Capability Set: extraFlags (2.2.7.1.1) */ +#define FASTPATH_OUTPUT_SUPPORTED 0x0001 +#define NO_BITMAP_COMPRESSION_HDR 0x0400 +#define LONG_CREDENTIALS_SUPPORTED 0x0004 +#define AUTORECONNECT_SUPPORTED 0x0008 +#define ENC_SALTED_CHECKSUM 0x0010 + +/* Order Capability Set: orderSupportExFlags (2.2.7.1.3) */ +/* NOTE: XR_ prefixed to avoid conflict with FreeRDP */ +#define XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT 0x0002 +#define XR_ORDERFLAGS_EX_ALTSEC_FRAME_MARKER_SUPPORT 0x0004 + +/* Order Capability Set: orderFlags (2.2.7.1.3) */ +#define NEGOTIATEORDERSUPPORT 0x0002 +#define ZEROBOUNDSDELTASUPPORT 0x0008 +#define COLORINDEXSUPPORT 0x0020 +#define SOLIDPATTERNBRUSHONLY 0x0040 +#define ORDERFLAGS_EXTRA_FLAGS 0x0080 + +/* Order Capability Set: orderSupport (2.2.7.1.3) */ +#define TS_NEG_DSTBLT_INDEX 0x00 +#define TS_NEG_PATBLT_INDEX 0x01 +#define TS_NEG_SCRBLT_INDEX 0x02 +#define TS_NEG_MEMBLT_INDEX 0x03 +#define TS_NEG_MEM3BLT_INDEX 0x04 + /* 0x05 */ + /* 0x06 */ +#define TS_NEG_DRAWNINEGRID_INDEX 0x07 +#define TS_NEG_LINETO_INDEX 0x08 +#define TS_NEG_MULTI_DRAWNINEGRID_INDEX 0x09 + /* 0x0A */ +#define TS_NEG_SAVEBITMAP_INDEX 0x0B + /* 0x0C */ + /* 0x0D */ + /* 0x0E */ +#define TS_NEG_MULTIDSTBLT_INDEX 0x0F +#define TS_NEG_MULTIPATBLT_INDEX 0x10 +#define TS_NEG_MULTISCRBLT_INDEX 0x11 +#define TS_NEG_MULTIOPAQUERECT_INDEX 0x12 +#define TS_NEG_FAST_INDEX_INDEX 0x13 +#define TS_NEG_POLYGON_SC_INDEX 0x14 +#define TS_NEG_POLYGON_CB_INDEX 0x15 +#define TS_NEG_POLYLINE_INDEX 0x16 + /* 0x17 */ +#define TS_NEG_FAST_GLYPH_INDEX 0x18 +#define TS_NEG_ELLIPSE_SC_INDEX 0x19 +#define TS_NEG_ELLIPSE_CB_INDEX 0x1A +#define TS_NEG_INDEX_INDEX 0x1B + /* 0x1C */ + /* 0x1D */ + /* 0x1E */ + /* 0x1F */ + +/* Input Capability Set: inputFlags (2.2.7.1.6) */ +#define INPUT_FLAG_SCANCODES 0x0001 +#define INPUT_FLAG_MOUSEX 0x0004 +#define INPUT_FLAG_FASTPATH_INPUT 0x0008 +#define INPUT_FLAG_UNICODE 0x0010 +#define INPUT_FLAG_FASTPATH_INPUT2 0x0020 +#define INPUT_FLAG_UNUSED1 0x0040 +#define INPUT_FLAG_UNUSED2 0x0080 +#define TS_INPUT_FLAG_MOUSE_HWHEEL 0x0100 +#define TS_INPUT_FLAG_QOE_TIMESTAMPS 0x0200 + +/* Glyph Cache Capability Set: GlyphSupportLevel (2.2.7.1.8) */ +#define GLYPH_SUPPORT_NONE 0x0000 +#define GLYPH_SUPPORT_PARTIAL 0x0001 +#define GLYPH_SUPPORT_FULL 0x0002 +#define GLYPH_SUPPORT_ENCODE 0x0003 + +/* Desktop Composition Capability Set: CompDeskSupportLevel (2.2.7.2.8) */ +#define COMPDESK_NOT_SUPPORTED 0x0000 +#define COMPDESK_SUPPORTED 0x0001 + +/* Surface Commands Capability Set: cmdFlags (2.2.7.2.9) */ +#define SURFCMDS_SETSURFACEBITS 0x00000002 +#define SURFCMDS_FRAMEMARKER 0x00000010 +#define SURFCMDS_STREAMSUFRACEBITS 0x00000040 + +/* Bitmap Codec: codecGUID (2.2.7.2.10.1.1) */ + +/* CODEC_GUID_NSCODEC CA8D1BB9-000F-154F-589FAE2D1A87E2D6 */ +#define XR_CODEC_GUID_NSCODEC \ + "\xb9\x1b\x8d\xca\x0f\x00\x4f\x15\x58\x9f\xae\x2d\x1a\x87\xe2\xd6" + +/* CODEC_GUID_REMOTEFX 76772F12-BD72-4463-AFB3B73C9C6F7886 */ +#define XR_CODEC_GUID_REMOTEFX \ + "\x12\x2F\x77\x76\x72\xBD\x63\x44\xAF\xB3\xB7\x3C\x9C\x6F\x78\x86" + +/* CODEC_GUID_IMAGE_REMOTEFX 2744CCD4-9D8A-4E74-803C-0ECBEEA19C54 */ +#define XR_CODEC_GUID_IMAGE_REMOTEFX \ + "\xD4\xCC\x44\x27\x8A\x9D\x74\x4E\x80\x3C\x0E\xCB\xEE\xA1\x9C\x54" + +/* MFVideoFormat_H264 0x34363248-0000-0010-800000AA00389B71 */ +#define XR_CODEC_GUID_H264 \ + "\x48\x32\x36\x34\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71" + +/* CODEC_GUID_JPEG 1BAF4CE6-9EED-430C-869ACB8B37B66237 */ +#define XR_CODEC_GUID_JPEG \ + "\xE6\x4C\xAF\x1B\xED\x9E\x0C\x43\x86\x9A\xCB\x8B\x37\xB6\x62\x37" + +/* CODEC_GUID_PNG 0E0C858D-28E0-45DB-ADAA0F83E57CC560 */ +#define XR_CODEC_GUID_PNG \ + "\x8D\x85\x0C\x0E\xE0\x28\xDB\x45\xAD\xAA\x0F\x83\xE5\x7C\xC5\x60" + +/* PDU Types (2.2.8.1.1.1.1) */ +#define PDUTYPE_DEMANDACTIVEPDU 0x1 +#define PDUTYPE_CONFIRMACTIVEPDU 0x3 +#define PDUTYPE_DEACTIVATEALLPDU 0x6 +#define PDUTYPE_DATAPDU 0x7 +#define PDUTYPE_SERVER_REDIR_PKT 0xA + +/* Share Data Header: pduType2 (2.2.8.1.1.1.2) */ +/* TODO: to be renamed */ +#define RDP_DATA_PDU_UPDATE 2 /* PDUTYPE2_UPDATE */ +#define RDP_DATA_PDU_CONTROL 20 +#define RDP_DATA_PDU_POINTER 27 +#define RDP_DATA_PDU_INPUT 28 +#define RDP_DATA_PDU_SYNCHRONISE 31 +#define PDUTYPE2_REFRESH_RECT 33 +#define RDP_DATA_PDU_PLAY_SOUND 34 +#define RDP_DATA_PDU_LOGON 38 +#define RDP_DATA_PDU_FONT2 39 +#define RDP_DATA_PDU_DISCONNECT 47 + +/* TS_SECURITY_HEADER: flags (2.2.8.1.1.2.1) */ +/* TODO: to be renamed */ +#define SEC_CLIENT_RANDOM 0x0001 /* SEC_EXCHANGE_PKT? */ +#define SEC_ENCRYPT 0x0008 +#define SEC_LOGON_INFO 0x0040 /* SEC_INFO_PKT */ +#define SEC_LICENCE_NEG 0x0080 /* SEC_LICENSE_PKT */ + +#define SEC_TAG_SRV_INFO 0x0c01 /* SC_CORE */ +#define SEC_TAG_SRV_CRYPT 0x0c02 /* SC_SECURITY */ +#define SEC_TAG_SRV_CHANNELS 0x0c03 /* SC_NET? */ + +/* Slow-Path Input Event: messageType (2.2.8.1.1.3.1.1) */ +/* TODO: to be renamed */ +#define RDP_INPUT_SYNCHRONIZE 0 +#define RDP_INPUT_CODEPOINT 1 +#define RDP_INPUT_VIRTKEY 2 +#define RDP_INPUT_SCANCODE 4 +#define RDP_INPUT_UNICODE 5 +#define RDP_INPUT_MOUSE 0x8001 +#define RDP_INPUT_MOUSEX 0x8002 + +/* Keyboard Event: keyboardFlags (2.2.8.1.1.3.1.1.1) */ +/* TODO: to be renamed */ +#define KBD_FLAG_RIGHT 0x0001 +#define KBD_FLAG_EXT 0x0100 /* KBDFLAGS_EXTENDED */ +#define KBD_FLAG_QUIET 0x1000 +#define KBD_FLAG_DOWN 0x4000 +#define KBD_FLAG_UP 0x8000 + +/* Mouse Event: pointerFlags (2.2.8.1.1.3.1.1.3) */ +#define PTRFLAGS_HWHEEL 0x0400 +#define PTRFLAGS_WHEEL 0x0200 +#define PTRFLAGS_WHEEL_NEGATIVE 0x0100 +#define WheelRotationMask 0x01FF +#define PTRFLAGS_MOVE 0x0800 +#define PTRFLAGS_DOWN 0x8000 +#define PTRFLAGS_BUTTON1 0x1000 +#define PTRFLAGS_BUTTON2 0x2000 +#define PTRFLAGS_BUTTON3 0x4000 + +/* Extended Mouse Event: pointerFlags (2.2.8.1.1.3.1.1.4) */ +#define PTRXFLAGS_DOWN 0x8000 +#define PTRXFLAGS_BUTTON1 0x0001 +#define PTRXFLAGS_BUTTON2 0x0002 + +/* Synchronize Event: toggleFlags (2.2.8.1.1.3.1.1.5) */ +/* TODO: to be renamed */ +#define KBD_FLAG_SCROLL 0x0001 /* TS_SYNC_SCROLL_LOCK */ +#define KBD_FLAG_NUMLOCK 0x0002 +#define KBD_FLAG_CAPITAL 0x0004 +#define TS_SYNC_KANA_LOCK 0x0008 + +/* Client Fast-Path Input Event PDU 2.2.8.1.2 */ +#define FASTPATH_INPUT_ENCRYPTED 0x2 + +/* Fast-Path Input Event: eventCode (2.2.8.1.2.2) */ +#define FASTPATH_INPUT_EVENT_SCANCODE 0x0 +#define FASTPATH_INPUT_EVENT_MOUSE 0x1 +#define FASTPATH_INPUT_EVENT_MOUSEX 0x2 +#define FASTPATH_INPUT_EVENT_SYNC 0x3 +#define FASTPATH_INPUT_EVENT_UNICODE 0x4 +#define FASTPATH_INPUT_EVENT_QOE_TIMESTAMP 0x6 + +/* Fast-Path Keyboard Event: eventHeader (2.2.8.1.2.2.1) */ +#define FASTPATH_INPUT_KBDFLAGS_RELEASE 0x01 +#define FASTPATH_INPUT_KBDFLAGS_EXTENDED 0x02 +#define FASTPATH_INPUT_KBDFLAGS_EXTENDED1 0x04 + +/* Slow-Path Graphics Update: updateType (2.2.9.1.1.3.1) */ +/* TODO: to be renamed */ +#define RDP_UPDATE_ORDERS 0 +#define RDP_UPDATE_BITMAP 1 +#define RDP_UPDATE_PALETTE 2 +#define RDP_UPDATE_SYNCHRONIZE 3 + +/* Server Pointer Update PDU: messageType (2.2.9.1.1.4) */ +/* TODO: to be renamed */ +#define RDP_POINTER_SYSTEM 1 /* TS_PTRMSGTYPE_SYSTEM */ +#define RDP_POINTER_MOVE 3 +#define RDP_POINTER_COLOR 6 +#define RDP_POINTER_CACHED 7 +#define RDP_POINTER_POINTER 8 + +/* System Pointer Update: systemPointerType (2.2.9.1.1.4.3) */ +#define RDP_NULL_POINTER 0 +#define RDP_DEFAULT_POINTER 0x7F00 + +/* Server Fast-Path Update PDU: action (2.2.9.1.2) */ +#define FASTPATH_OUTPUT_ACTION_FASTPATH 0x0 +#define FASTPATH_OUTPUT_ACTION_X224 0x3 + +/* Server Fast-Path Update PDU: flags (2.2.9.1.2) */ +#define FASTPATH_OUTPUT_SECURE_CHECKSUM 0x1 +#define FASTPATH_OUTPUT_ENCRYPTED 0x2 + +/* Fast-Path Update: updateCode (2.2.9.1.2.1) */ +#define FASTPATH_UPDATETYPE_ORDERS 0x0 +#define FASTPATH_UPDATETYPE_BITMAP 0x1 +#define FASTPATH_UPDATETYPE_PALETTE 0x2 +#define FASTPATH_UPDATETYPE_SYNCHRONIZE 0x3 +#define FASTPATH_UPDATETYPE_SURFCMDS 0x4 +#define FASTPATH_UPDATETYPE_PTR_NULL 0x5 +#define FASTPATH_UPDATETYPE_PTR_DEFAULT 0x6 +#define FASTPATH_UPDATETYPE_PTR_POSITION 0x8 +#define FASTPATH_UPDATETYPE_COLOR 0x9 +#define FASTPATH_UPDATETYPE_CACHED 0xA +#define FASTPATH_UPDATETYPE_POINTER 0xB + +/* Fast-Path Update: fragmentation (2.2.9.1.2.1) */ +#define FASTPATH_FRAGMENT_SINGLE 0x0 +#define FASTPATH_FRAGMENT_LAST 0x1 +#define FASTPATH_FRAGMENT_FIRST 0x2 +#define FASTPATH_FRAGMENT_NEXT 0x3 +#define FASTPATH_OUTPUT_COMPRESSION_USED 0x2 + +/* Surface Command Type (2.2.9.1.2.1.10.1) */ +#define CMDTYPE_SET_SURFACE_BITS 0x0001 +#define CMDTYPE_FRAME_MARKER 0x0004 +#define CMDTYPE_STREAM_SURFACE_BITS 0x0006 + +/* Compression Flags (3.1.8.2.1) */ +/* TODO: to be renamed, not used anywhere */ +#define RDP_MPPC_COMPRESSED 0x20 +#define RDP_MPPC_RESET 0x40 +#define RDP_MPPC_FLUSH 0x80 +#define RDP_MPPC_DICT_SIZE 8192 /* RDP 4.0 | MS-RDPBCGR 3.1.8 */ + +#endif /* MS_RDPBCGR_H */ diff -Nru xrdp-0.9.12/common/ms-rdpefs.h xrdp-0.9.15/common/ms-rdpefs.h --- xrdp-0.9.12/common/ms-rdpefs.h 1970-01-01 00:00:00.000000000 +0000 +++ xrdp-0.9.15/common/ms-rdpefs.h 2020-12-28 13:47:11.000000000 +0000 @@ -0,0 +1,123 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * MS-RDPEFS : Definitions from [MS-RDPEFS] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * References to MS-RDPEFS are currently correct for v20180912 of that + * document + */ + +#if !defined(MS_RDPEFS_H) +#define MS_RDPEFS_H + +/* + * RDPDR_HEADER definitions (2.2.1.1) + */ + +/* device redirector core component; most of the packets in this protocol */ +/* are sent under this component ID */ +#define RDPDR_CTYP_CORE 0x4472 + +/* printing component. the packets that use this ID are typically about */ +/* printer cache management and identifying XPS printers */ +#define RDPDR_CTYP_PRN 0x5052 + +/* Server Announce Request, as specified in section 2.2.2.2 */ +#define PAKID_CORE_SERVER_ANNOUNCE 0x496E + +/* Client Announce Reply and Server Client ID Confirm, as specified in */ +/* sections 2.2.2.3 and 2.2.2.6. */ +#define PAKID_CORE_CLIENTID_CONFIRM 0x4343 + +/* Client Name Request, as specified in section 2.2.2.4 */ +#define PAKID_CORE_CLIENT_NAME 0x434E + +/* Client Device List Announce Request, as specified in section 2.2.2.9 */ +#define PAKID_CORE_DEVICELIST_ANNOUNCE 0x4441 + +/* Server Device Announce Response, as specified in section 2.2.2.1 */ +#define PAKID_CORE_DEVICE_REPLY 0x6472 + +/* Device I/O Request, as specified in section 2.2.1.4 */ +#define PAKID_CORE_DEVICE_IOREQUEST 0x4952 + +/* Device I/O Response, as specified in section 2.2.1.5 */ +#define PAKID_CORE_DEVICE_IOCOMPLETION 0x4943 + +/* Server Core Capability Request, as specified in section 2.2.2.7 */ +#define PAKID_CORE_SERVER_CAPABILITY 0x5350 + +/* Client Core Capability Response, as specified in section 2.2.2.8 */ +#define PAKID_CORE_CLIENT_CAPABILITY 0x4350 + +/* Client Drive Device List Remove, as specified in section 2.2.3.2 */ +#define PAKID_CORE_DEVICELIST_REMOVE 0x444D + +/* Add Printer Cachedata, as specified in [MS-RDPEPC] section 2.2.2.3 */ +#define PAKID_PRN_CACHE_DATA 0x5043 + +/* Server User Logged On, as specified in section 2.2.2.5 */ +#define PAKID_CORE_USER_LOGGEDON 0x554C + +/* Server Printer Set XPS Mode, as specified in [MS-RDPEPC] section 2.2.2.2 */ +#define PAKID_PRN_USING_XPS 0x5543 + +/* + * Capability header definitions (2.2.1.2) + */ + +#define CAP_GENERAL_TYPE 0x0001 /* General cap set - GENERAL_CAPS_SET */ +#define CAP_PRINTER_TYPE 0x0002 /* Print cap set - PRINTER_CAPS_SET */ +#define CAP_PORT_TYPE 0x0003 /* Port cap set - PORT_CAPS_SET */ +#define CAP_DRIVE_TYPE 0x0004 /* Drive cap set - DRIVE_CAPS_SET */ +#define CAP_SMARTCARD_TYPE 0x0005 /* Smart card cap set - SMARTCARD_CAPS_SET */ + +/* + * Device announce header (2.2.1.3) + */ +#define RDPDR_DTYP_SERIAL 0x0001 +#define RDPDR_DTYP_PARALLEL 0x0002 +#define RDPDR_DTYP_PRINT 0x0004 +#define RDPDR_DTYP_FILESYSTEM 0x0008 +#define RDPDR_DTYP_SMARTCARD 0x0020 + +/* Device I/O Request definitions (2.2.1.4) */ +/* MajorFunction */ +enum IRP_MJ +{ + IRP_MJ_CREATE = 0x00000000, + IRP_MJ_CLOSE = 0x00000002, + IRP_MJ_READ = 0x00000003, + IRP_MJ_WRITE = 0x00000004, + IRP_MJ_DEVICE_CONTROL = 0x0000000E, + IRP_MJ_QUERY_VOLUME_INFORMATION = 0x0000000A, + IRP_MJ_SET_VOLUME_INFORMATION = 0x0000000B, + IRP_MJ_QUERY_INFORMATION = 0x00000005, + IRP_MJ_SET_INFORMATION = 0x00000006, + IRP_MJ_DIRECTORY_CONTROL = 0x0000000C, + IRP_MJ_LOCK_CONTROL = 0x00000011 +}; + +/* MinorFunction */ +/* Set to zero unless MajorFunction code == IRP_MJ_DIRECTORY_CONTROL */ +enum IRP_MN +{ + IRP_MN_NONE = 0x00000000, /* Name not in MS docs */ + IRP_MN_QUERY_DIRECTORY = 0x00000001, + IRP_MN_NOTIFY_CHANGE_DIRECTORY = 0x00000002 +}; + + +#endif /* MS_RDPEFS_H */ diff -Nru xrdp-0.9.12/common/ms-rdpegdi.h xrdp-0.9.15/common/ms-rdpegdi.h --- xrdp-0.9.12/common/ms-rdpegdi.h 1970-01-01 00:00:00.000000000 +0000 +++ xrdp-0.9.15/common/ms-rdpegdi.h 2020-12-28 13:47:11.000000000 +0000 @@ -0,0 +1,59 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * MS-RDPEGDI : Definitions from [MS-RDPEGDI] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * References to MS-RDPEGDI are currently correct for v20180912 of that + * document + */ + +#if !defined(MS_RDPEGDI_H) +#define MS_RDPEGDI_H + +/* Drawing Order: controlFlags (2.2.2.2.1, 2.2.2.2.1.1.2) */ +#define TS_STANDARD 0x01 +#define TS_SECONDARY 0x02 +#define TS_BOUNDS 0x04 +#define TS_TYPE_CHANGE 0x08 +#define TS_DELTA_COORDINATES 0x10 +#define TS_ZERO_BOUNDS_DELTAS 0x20 +#define TS_ZERO_FIELD_BYTE_BIT0 0x40 +#define TS_ZERO_FIELD_BYTE_BIT1 0x80 + +/* Drawing Order: orderType (2.2.2.2.1.1.2) */ +/* Should be renamed */ +#define RDP_ORDER_DESTBLT 0 /* TS_ENC_DSTBLT_ORDER */ +#define RDP_ORDER_PATBLT 1 +#define RDP_ORDER_SCREENBLT 2 +#define RDP_ORDER_LINE 9 +#define RDP_ORDER_RECT 10 +#define RDP_ORDER_DESKSAVE 11 +#define RDP_ORDER_MEMBLT 13 +#define RDP_ORDER_TRIBLT 14 +#define RDP_ORDER_POLYLINE 22 +#define RDP_ORDER_TEXT2 27 +#define RDP_ORDER_COMPOSITE 37 /* 0x25 - not defined in RDPEGDI */ + +/* Secondary Drawing Order Header: orderType (2.2.2.2.1.2.1.1) */ +#define TS_CACHE_BITMAP_UNCOMPRESSED 0x00 +#define TS_CACHE_COLOR_TABLE 0x01 +#define TS_CACHE_BITMAP_COMPRESSED 0x02 +#define TS_CACHE_GLYPH 0x03 +#define TS_CACHE_BITMAP_UNCOMPRESSED_REV2 0x04 +#define TS_CACHE_BITMAP_COMPRESSED_REV2 0x05 +#define TS_CACHE_BRUSH 0x07 +#define TS_CACHE_BITMAP_COMPRESSED_REV3 0x08 + +#endif /* MS_RDPEGDI_H */ diff -Nru xrdp-0.9.12/common/ms-rdpele.h xrdp-0.9.15/common/ms-rdpele.h --- xrdp-0.9.12/common/ms-rdpele.h 1970-01-01 00:00:00.000000000 +0000 +++ xrdp-0.9.15/common/ms-rdpele.h 2020-12-28 13:47:11.000000000 +0000 @@ -0,0 +1,36 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * MS-RDPELE : Definitions from [MS-RDPELE] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * References to MS-RDPELE are currently correct for v20180912 of that + * document + */ + +#if !defined(MS_RDPELE_H) +#define MS_RDPELE_H + +/* LicensingMessage (MS-RDPELE 2.2.2) */ +/* TODO: to be renamed */ +#define LICENCE_TAG_DEMAND 0x01 /* LICNSE_REQUEST */ +#define LICENCE_TAG_AUTHREQ 0x02 /* PLATFORM_CHALLENGE */ +#define LICENCE_TAG_ISSUE 0x03 /* NEW_LICENSE */ +#define LICENCE_TAG_REISSUE 0x04 /* UPGRADE_LICENSE */ +#define LICENCE_TAG_PRESENT 0x12 /* LICENSE_INFO */ +#define LICENCE_TAG_REQUEST 0x13 /* NEW_LICENSE_REQUEST */ +#define LICENCE_TAG_AUTHRESP 0x15 /* PLATFORM_CHALLENGE_RESPONSE */ +#define LICENCE_TAG_RESULT 0xff + +#endif /* MS_RDPELE_H */ diff -Nru xrdp-0.9.12/common/ms-rdperp.h xrdp-0.9.15/common/ms-rdperp.h --- xrdp-0.9.12/common/ms-rdperp.h 1970-01-01 00:00:00.000000000 +0000 +++ xrdp-0.9.15/common/ms-rdperp.h 2020-12-28 13:47:11.000000000 +0000 @@ -0,0 +1,31 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * MS-RDPERP : Definitions from [MS-RDPERP] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * References to MS-RDPERP are currently correct for v20190923 of that + * document + */ + +#if !defined(MS_RDPERP_H) +#define MS_RDPERP_H + +/* Window List Capability Set: WndSupportLevel (2.2.1.1.2) */ +#define TS_WINDOW_LEVEL_NOT_SUPPORTED 0x00000000 +#define TS_WINDOW_LEVEL_SUPPORTED 0x00000001 +#define TS_WINDOW_LEVEL_SUPPORTED_EX 0x00000002 + + +#endif /* MS_RDPERP_H */ diff -Nru xrdp-0.9.12/common/ms-smb2.h xrdp-0.9.15/common/ms-smb2.h --- xrdp-0.9.12/common/ms-smb2.h 1970-01-01 00:00:00.000000000 +0000 +++ xrdp-0.9.15/common/ms-smb2.h 2020-12-28 13:47:11.000000000 +0000 @@ -0,0 +1,79 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * MS-SMB2 : Definitions from [MS-SMB2] + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * References to MS-SMB2 are currently correct for v20190923 of that + * document + */ + +#if !defined(MS_SMB2_H) +#define MS_SMB2_H + +/* SMB2 CREATE request values (section 2.2.13) */ + +/* + * ShareAccess Mask. Currently, this is referred + * to in MS-RDPEFS 2.2.1.4.1 as 'SharedAccess' rather than 'ShareAccess'. + */ +#define SA_FILE_SHARE_READ 0x00000001 +#define SA_FILE_SHARE_WRITE 0x00000002 +#define SA_FILE_SHARE_DELETE 0x00000004 + +/* CreateDisposition Mask */ +#define CD_FILE_SUPERSEDE 0x00000000 +#define CD_FILE_OPEN 0x00000001 +#define CD_FILE_CREATE 0x00000002 +#define CD_FILE_OPEN_IF 0x00000003 +#define CD_FILE_OVERWRITE 0x00000004 +#define CD_FILE_OVERWRITE_IF 0x00000005 + +/* CreateOptions Mask */ +enum CREATE_OPTIONS +{ + CO_FILE_DIRECTORY_FILE = 0x00000001, + CO_FILE_WRITE_THROUGH = 0x00000002, + CO_FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020, + CO_FILE_DELETE_ON_CLOSE = 0x00001000 +}; + +/* + * DesiredAccess Mask (section 2.2.13.1.1) + */ + +#define DA_FILE_READ_DATA 0x00000001 +#define DA_FILE_WRITE_DATA 0x00000002 +#define DA_FILE_APPEND_DATA 0x00000004 +#define DA_FILE_READ_EA 0x00000008 /* rd extended attributes */ +#define DA_FILE_WRITE_EA 0x00000010 /* wr extended attributes */ +#define DA_FILE_EXECUTE 0x00000020 +#define DA_FILE_READ_ATTRIBUTES 0x00000080 +#define DA_FILE_WRITE_ATTRIBUTES 0x00000100 +#define DA_DELETE 0x00010000 +#define DA_READ_CONTROL 0x00020000 /* rd security descriptor */ +#define DA_WRITE_DAC 0x00040000 +#define DA_WRITE_OWNER 0x00080000 +#define DA_SYNCHRONIZE 0x00100000 +#define DA_ACCESS_SYSTEM_SECURITY 0x01000000 +#define DA_MAXIMUM_ALLOWED 0x02000000 +#define DA_GENERIC_ALL 0x10000000 +#define DA_GENERIC_EXECUTE 0x20000000 +#define DA_GENERIC_WRITE 0x40000000 +#define DA_GENERIC_READ 0x80000000 + +#endif /* MS_SMB2_H */ + + + diff -Nru xrdp-0.9.12/common/os_calls.c xrdp-0.9.15/common/os_calls.c --- xrdp-0.9.12/common/os_calls.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/common/os_calls.c 2020-12-28 14:03:43.000000000 +0000 @@ -76,7 +76,7 @@ #endif #include "os_calls.h" -#include "arch.h" +#include "string_calls.h" #include "log.h" /* for clearenv() */ @@ -166,6 +166,8 @@ #if defined(_WIN32) WSACleanup(); #endif + fflush(stdout); + fflush(stderr); g_rm_temp_dir(); } @@ -2508,499 +2510,6 @@ } /*****************************************************************************/ -/* returns length of text */ -int -g_strlen(const char *text) -{ - if (text == NULL) - { - return 0; - } - - return strlen(text); -} - -/*****************************************************************************/ -/* locates char in text */ -const char * -g_strchr(const char* text, int c) -{ - if (text == NULL) - { - return 0; - } - - return strchr(text,c); -} - -/*****************************************************************************/ -/* returns dest */ -char * -g_strcpy(char *dest, const char *src) -{ - if (src == 0 && dest != 0) - { - dest[0] = 0; - return dest; - } - - if (dest == 0 || src == 0) - { - return 0; - } - - return strcpy(dest, src); -} - -/*****************************************************************************/ -/* returns dest */ -char * -g_strncpy(char *dest, const char *src, int len) -{ - char *rv; - - if (src == 0 && dest != 0) - { - dest[0] = 0; - return dest; - } - - if (dest == 0 || src == 0) - { - return 0; - } - - rv = strncpy(dest, src, len); - dest[len] = 0; - return rv; -} - -/*****************************************************************************/ -/* returns dest */ -char * -g_strcat(char *dest, const char *src) -{ - if (dest == 0 || src == 0) - { - return dest; - } - - return strcat(dest, src); -} - -/*****************************************************************************/ -/* if in = 0, return 0 else return newly alloced copy of in */ -char * -g_strdup(const char *in) -{ - int len; - char *p; - - if (in == 0) - { - return 0; - } - - len = g_strlen(in); - p = (char *)g_malloc(len + 1, 0); - - if (p != NULL) - { - g_strcpy(p, in); - } - - return p; -} - -/*****************************************************************************/ -/* if in = 0, return 0 else return newly alloced copy of input string - * if the input string is larger than maxlen the returned string will be - * truncated. All strings returned will include null termination*/ -char * -g_strndup(const char *in, const unsigned int maxlen) -{ - unsigned int len; - char *p; - - if (in == 0) - { - return 0; - } - - len = g_strlen(in); - - if (len > maxlen) - { - len = maxlen - 1; - } - - p = (char *)g_malloc(len + 2, 0); - - if (p != NULL) - { - g_strncpy(p, in, len + 1); - } - - return p; -} - -/*****************************************************************************/ -int -g_strcmp(const char *c1, const char *c2) -{ - return strcmp(c1, c2); -} - -/*****************************************************************************/ -int -g_strncmp(const char *c1, const char *c2, int len) -{ - return strncmp(c1, c2, len); -} - -/*****************************************************************************/ -/* compare up to delim */ -int -g_strncmp_d(const char *s1, const char *s2, const char delim, int n) -{ - char c1; - char c2; - - c1 = 0; - c2 = 0; - while (n > 0) - { - c1 = *(s1++); - c2 = *(s2++); - if ((c1 == 0) || (c1 != c2) || (c1 == delim) || (c2 == delim)) - { - return c1 - c2; - } - n--; - } - return c1 - c2; -} - -/*****************************************************************************/ -int -g_strcasecmp(const char *c1, const char *c2) -{ -#if defined(_WIN32) - return stricmp(c1, c2); -#else - return strcasecmp(c1, c2); -#endif -} - -/*****************************************************************************/ -int -g_strncasecmp(const char *c1, const char *c2, int len) -{ -#if defined(_WIN32) - return strnicmp(c1, c2, len); -#else - return strncasecmp(c1, c2, len); -#endif -} - -/*****************************************************************************/ -int -g_atoi(const char *str) -{ - if (str == 0) - { - return 0; - } - - return atoi(str); -} - -/*****************************************************************************/ -int -g_htoi(char *str) -{ - int len; - int index; - int rv; - int val; - int shift; - - rv = 0; - len = strlen(str); - index = len - 1; - shift = 0; - - while (index >= 0) - { - val = 0; - - switch (str[index]) - { - case '1': - val = 1; - break; - case '2': - val = 2; - break; - case '3': - val = 3; - break; - case '4': - val = 4; - break; - case '5': - val = 5; - break; - case '6': - val = 6; - break; - case '7': - val = 7; - break; - case '8': - val = 8; - break; - case '9': - val = 9; - break; - case 'a': - case 'A': - val = 10; - break; - case 'b': - case 'B': - val = 11; - break; - case 'c': - case 'C': - val = 12; - break; - case 'd': - case 'D': - val = 13; - break; - case 'e': - case 'E': - val = 14; - break; - case 'f': - case 'F': - val = 15; - break; - } - - rv = rv | (val << shift); - index--; - shift += 4; - } - - return rv; -} - -/*****************************************************************************/ -/* returns number of bytes copied into out_str */ -int -g_bytes_to_hexstr(const void *bytes, int num_bytes, char *out_str, - int bytes_out_str) -{ - int rv; - int index; - char *lout_str; - const tui8 *lbytes; - - rv = 0; - lbytes = (const tui8 *) bytes; - lout_str = out_str; - for (index = 0; index < num_bytes; index++) - { - if (bytes_out_str < 3) - { - break; - } - g_snprintf(lout_str, bytes_out_str, "%2.2x", lbytes[index]); - lout_str += 2; - bytes_out_str -= 2; - rv += 2; - } - return rv; -} - -/*****************************************************************************/ -int -g_pos(const char *str, const char *to_find) -{ - const char *pp; - - pp = strstr(str, to_find); - - if (pp == 0) - { - return -1; - } - - return (pp - str); -} - -/*****************************************************************************/ -int -g_mbstowcs(twchar *dest, const char *src, int n) -{ - wchar_t *ldest; - int rv; - - ldest = (wchar_t *)dest; - rv = mbstowcs(ldest, src, n); - return rv; -} - -/*****************************************************************************/ -int -g_wcstombs(char *dest, const twchar *src, int n) -{ - const wchar_t *lsrc; - int rv; - - lsrc = (const wchar_t *)src; - rv = wcstombs(dest, lsrc, n); - return rv; -} - -/*****************************************************************************/ -/* returns error */ -/* trim spaces and tabs, anything <= space */ -/* trim_flags 1 trim left, 2 trim right, 3 trim both, 4 trim through */ -/* this will always shorten the string or not change it */ -int -g_strtrim(char *str, int trim_flags) -{ - int index; - int len; - int text1_index; - int got_char; - wchar_t *text; - wchar_t *text1; - - len = mbstowcs(0, str, 0); - - if (len < 1) - { - return 0; - } - - if ((trim_flags < 1) || (trim_flags > 4)) - { - return 1; - } - - text = (wchar_t *)malloc(len * sizeof(wchar_t) + 8); - text1 = (wchar_t *)malloc(len * sizeof(wchar_t) + 8); - text1_index = 0; - mbstowcs(text, str, len + 1); - - switch (trim_flags) - { - case 4: /* trim through */ - - for (index = 0; index < len; index++) - { - if (text[index] > 32) - { - text1[text1_index] = text[index]; - text1_index++; - } - } - - text1[text1_index] = 0; - break; - case 3: /* trim both */ - got_char = 0; - - for (index = 0; index < len; index++) - { - if (got_char) - { - text1[text1_index] = text[index]; - text1_index++; - } - else - { - if (text[index] > 32) - { - text1[text1_index] = text[index]; - text1_index++; - got_char = 1; - } - } - } - - text1[text1_index] = 0; - len = text1_index; - - /* trim right */ - for (index = len - 1; index >= 0; index--) - { - if (text1[index] > 32) - { - break; - } - } - - text1_index = index + 1; - text1[text1_index] = 0; - break; - case 2: /* trim right */ - - /* copy it */ - for (index = 0; index < len; index++) - { - text1[text1_index] = text[index]; - text1_index++; - } - - /* trim right */ - for (index = len - 1; index >= 0; index--) - { - if (text1[index] > 32) - { - break; - } - } - - text1_index = index + 1; - text1[text1_index] = 0; - break; - case 1: /* trim left */ - got_char = 0; - - for (index = 0; index < len; index++) - { - if (got_char) - { - text1[text1_index] = text[index]; - text1_index++; - } - else - { - if (text[index] > 32) - { - text1[text1_index] = text[index]; - text1_index++; - got_char = 1; - } - } - } - - text1[text1_index] = 0; - break; - } - - wcstombs(str, text1, text1_index + 1); - free(text); - free(text1); - return 0; -} - -/*****************************************************************************/ long g_load_library(char *in) { @@ -3288,6 +2797,17 @@ /*****************************************************************************/ int +g_getlogin(char *name, unsigned int len) +{ +#if defined(_WIN32) + return -1; +#else + return getlogin_r(name, len); +#endif +} + +/*****************************************************************************/ +int g_setlogin(const char *name) { #ifdef BSD @@ -3398,7 +2918,7 @@ int g_exit(int exit_code) { - _exit(exit_code); + exit(exit_code); return 0; } @@ -3739,21 +3259,6 @@ return 0; } -/*****************************************************************************/ -/* returns boolean */ -int -g_text2bool(const char *s) -{ - if ( (g_atoi(s) != 0) || - (0 == g_strcasecmp(s, "true")) || - (0 == g_strcasecmp(s, "on")) || - (0 == g_strcasecmp(s, "yes"))) - { - return 1; - } - return 0; -} - /*****************************************************************************/ /* returns pointer or nil on error */ void * diff -Nru xrdp-0.9.12/common/os_calls.h xrdp-0.9.15/common/os_calls.h --- xrdp-0.9.12/common/os_calls.h 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/common/os_calls.h 2020-12-28 14:03:43.000000000 +0000 @@ -119,26 +119,6 @@ int g_remove_dir(const char* dirname); int g_file_delete(const char* filename); int g_file_get_size(const char* filename); -int g_strlen(const char* text); -const char *g_strchr(const char *text, int c); -char* g_strcpy(char* dest, const char* src); -char* g_strncpy(char* dest, const char* src, int len); -char* g_strcat(char* dest, const char* src); -char* g_strdup(const char* in); -char* g_strndup(const char* in, const unsigned int maxlen); -int g_strcmp(const char* c1, const char* c2); -int g_strncmp(const char* c1, const char* c2, int len); -int g_strncmp_d(const char* c1, const char* c2, const char delim, int len); -int g_strcasecmp(const char* c1, const char* c2); -int g_strncasecmp(const char* c1, const char* c2, int len); -int g_atoi(const char* str); -int g_htoi(char* str); -int g_bytes_to_hexstr(const void *bytes, int num_bytes, char *out_str, - int bytes_out_str); -int g_pos(const char* str, const char* to_find); -int g_mbstowcs(twchar* dest, const char* src, int n); -int g_wcstombs(char* dest, const twchar* src, int n); -int g_strtrim(char* str, int trim_flags); long g_load_library(char* in); int g_free_library(long lib); void* g_get_proc_address(long lib, const char* name); @@ -161,6 +141,7 @@ int g_getgid(void); int g_setuid(int pid); int g_setsid(void); +int g_getlogin(char *name, unsigned int len); int g_setlogin(const char *name); int g_waitchild(void); int g_waitpid(int pid); @@ -179,7 +160,6 @@ int g_time3(void); int g_save_to_bmp(const char* filename, char* data, int stride_bytes, int width, int height, int depth, int bits_per_pixel); -int g_text2bool(const char *s); void * g_shmat(int shmid); int g_shmdt(const void *shmaddr); int g_gethostname(char *name, int len); diff -Nru xrdp-0.9.12/common/pixman-region.c xrdp-0.9.15/common/pixman-region.c --- xrdp-0.9.12/common/pixman-region.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/common/pixman-region.c 2020-12-28 13:47:11.000000000 +0000 @@ -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 \ { \ diff -Nru xrdp-0.9.12/common/ssl_calls.c xrdp-0.9.15/common/ssl_calls.c --- xrdp-0.9.12/common/ssl_calls.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/common/ssl_calls.c 2020-12-28 14:03:43.000000000 +0000 @@ -36,6 +36,7 @@ #include #include "os_calls.h" +#include "string_calls.h" #include "arch.h" #include "ssl_calls.h" #include "trans.h" @@ -720,7 +721,10 @@ DH_free(dh); // ok to free, copied into ctx by SSL_CTX_set_tmp_dh() #if defined(SSL_CTX_set_ecdh_auto) - SSL_CTX_set_ecdh_auto(self->ctx, 1); + if(!SSL_CTX_set_ecdh_auto(self->ctx, 1)) + { + LOG(LOG_LEVEL_WARNING, "TLS ecdh auto failed to be enabled"); + } #endif if (g_strlen(tls_ciphers) > 1) diff -Nru xrdp-0.9.12/common/string_calls.c xrdp-0.9.15/common/string_calls.c --- xrdp-0.9.12/common/string_calls.c 1970-01-01 00:00:00.000000000 +0000 +++ xrdp-0.9.15/common/string_calls.c 2020-12-28 14:03:43.000000000 +0000 @@ -0,0 +1,653 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2020 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * generic string handling calls + */ + +#if defined(HAVE_CONFIG_H) +#include "config_ac.h" +#endif +#include +#include +#include + +#include "string_calls.h" +#include "os_calls.h" + +unsigned int +g_format_info_string(char *dest, unsigned int len, + const char *format, + const struct info_string_tag map[]) +{ + unsigned int result = 0; + const char *copy_from; /* Data to add to output */ + unsigned int copy_len; /* Length of above */ + unsigned int skip; /* Date to skip over in format string */ + const char *p; + const struct info_string_tag *m; + + for ( ; *format != '\0'; format += skip) + { + if (*format == '%') + { + char ch = *(format + 1); + if (ch == '%') + { + /* '%%' in format - replace with single '%' */ + copy_from = format; + copy_len = 1; + skip = 2; + } + else if (ch == '\0') + { + /* Percent at end of string - ignore */ + copy_from = NULL; + copy_len = 0; + skip = 1; + } + else + { + /* Look up the character in the map, assuming failure */ + copy_from = NULL; + copy_len = 0; + skip = 2; + + for (m = map ; m->ch != '\0' ; ++m) + { + if (ch == m->ch) + { + copy_from = m->val; + copy_len = strlen(copy_from); + break; + } + } + } + } + else if ((p = strchr(format, '%')) != NULL) + { + /* Copy up to the next '%' */ + copy_from = format; + copy_len = p - format; + skip = copy_len; + } + else + { + /* Copy the rest of the format string */ + copy_from = format; + copy_len = strlen(format); + skip = copy_len; + } + + /* Update the result before any truncation */ + result += copy_len; + + /* Do we have room in the output buffer for any more data? We + * must always write a terminator if possible */ + if (len > 1) + { + if (copy_len > (len - 1)) + { + copy_len = len - 1; + } + memcpy(dest, copy_from, copy_len); + dest += copy_len; + len -= copy_len; + } + } + + /* Room for a terminator? */ + if (len > 0) + { + *dest = '\0'; + } + + return result; +} + +/******************************************************************************/ +const char * +g_bool2text(int value) +{ + return value ? "true" : "false"; +} + +/*****************************************************************************/ +int +g_text2bool(const char *s) +{ + if ( (g_atoi(s) != 0) || + (0 == g_strcasecmp(s, "true")) || + (0 == g_strcasecmp(s, "on")) || + (0 == g_strcasecmp(s, "yes"))) + { + return 1; + } + return 0; +} + +/*****************************************************************************/ +/* returns length of text */ +int +g_strlen(const char *text) +{ + if (text == NULL) + { + return 0; + } + + return strlen(text); +} + +/*****************************************************************************/ +/* locates char in text */ +const char * +g_strchr(const char *text, int c) +{ + if (text == NULL) + { + return 0; + } + + return strchr(text, c); +} + +/*****************************************************************************/ +/* returns dest */ +char * +g_strcpy(char *dest, const char *src) +{ + if (src == 0 && dest != 0) + { + dest[0] = 0; + return dest; + } + + if (dest == 0 || src == 0) + { + return 0; + } + + return strcpy(dest, src); +} + +/*****************************************************************************/ +/* returns dest */ +char * +g_strncpy(char *dest, const char *src, int len) +{ + char *rv; + + if (src == 0 && dest != 0) + { + dest[0] = 0; + return dest; + } + + if (dest == 0 || src == 0) + { + return 0; + } + + rv = strncpy(dest, src, len); + dest[len] = 0; + return rv; +} + +/*****************************************************************************/ +/* returns dest */ +char * +g_strcat(char *dest, const char *src) +{ + if (dest == 0 || src == 0) + { + return dest; + } + + return strcat(dest, src); +} + +/*****************************************************************************/ +/* returns dest */ +char * +g_strncat(char *dest, const char *src, int len) +{ + if (dest == 0 || src == 0) + { + return dest; + } + + return strncat(dest, src, len); +} + +/*****************************************************************************/ +/* if in = 0, return 0 else return newly alloced copy of in */ +char * +g_strdup(const char *in) +{ + int len; + char *p; + + if (in == 0) + { + return 0; + } + + len = g_strlen(in); + p = (char *)g_malloc(len + 1, 0); + + if (p != NULL) + { + g_strcpy(p, in); + } + + return p; +} + +/*****************************************************************************/ +/* if in = 0, return 0 else return newly alloced copy of input string + * if the input string is larger than maxlen the returned string will be + * truncated. All strings returned will include null termination*/ +char * +g_strndup(const char *in, const unsigned int maxlen) +{ + unsigned int len; + char *p; + + if (in == 0) + { + return 0; + } + + len = g_strlen(in); + + if (len > maxlen) + { + len = maxlen - 1; + } + + p = (char *)g_malloc(len + 2, 0); + + if (p != NULL) + { + g_strncpy(p, in, len + 1); + } + + return p; +} + +/*****************************************************************************/ +int +g_strcmp(const char *c1, const char *c2) +{ + return strcmp(c1, c2); +} + +/*****************************************************************************/ +int +g_strncmp(const char *c1, const char *c2, int len) +{ + return strncmp(c1, c2, len); +} + +/*****************************************************************************/ +/* compare up to delim */ +int +g_strncmp_d(const char *s1, const char *s2, const char delim, int n) +{ + char c1; + char c2; + + c1 = 0; + c2 = 0; + while (n > 0) + { + c1 = *(s1++); + c2 = *(s2++); + if ((c1 == 0) || (c1 != c2) || (c1 == delim) || (c2 == delim)) + { + return c1 - c2; + } + n--; + } + return c1 - c2; +} + +/*****************************************************************************/ +int +g_strcasecmp(const char *c1, const char *c2) +{ +#if defined(_WIN32) + return stricmp(c1, c2); +#else + return strcasecmp(c1, c2); +#endif +} + +/*****************************************************************************/ +int +g_strncasecmp(const char *c1, const char *c2, int len) +{ +#if defined(_WIN32) + return strnicmp(c1, c2, len); +#else + return strncasecmp(c1, c2, len); +#endif +} + +/*****************************************************************************/ +int +g_atoi(const char *str) +{ + if (str == 0) + { + return 0; + } + + return atoi(str); +} + +/*****************************************************************************/ +int +g_htoi(char *str) +{ + int len; + int index; + int rv; + int val; + int shift; + + rv = 0; + len = strlen(str); + index = len - 1; + shift = 0; + + while (index >= 0) + { + val = 0; + + switch (str[index]) + { + case '1': + val = 1; + break; + case '2': + val = 2; + break; + case '3': + val = 3; + break; + case '4': + val = 4; + break; + case '5': + val = 5; + break; + case '6': + val = 6; + break; + case '7': + val = 7; + break; + case '8': + val = 8; + break; + case '9': + val = 9; + break; + case 'a': + case 'A': + val = 10; + break; + case 'b': + case 'B': + val = 11; + break; + case 'c': + case 'C': + val = 12; + break; + case 'd': + case 'D': + val = 13; + break; + case 'e': + case 'E': + val = 14; + break; + case 'f': + case 'F': + val = 15; + break; + } + + rv = rv | (val << shift); + index--; + shift += 4; + } + + return rv; +} + +/*****************************************************************************/ +/* returns number of bytes copied into out_str */ +int +g_bytes_to_hexstr(const void *bytes, int num_bytes, char *out_str, + int bytes_out_str) +{ + int rv; + int index; + char *lout_str; + const tui8 *lbytes; + + rv = 0; + lbytes = (const tui8 *) bytes; + lout_str = out_str; + for (index = 0; index < num_bytes; index++) + { + if (bytes_out_str < 3) + { + break; + } + g_snprintf(lout_str, bytes_out_str, "%2.2x", lbytes[index]); + lout_str += 2; + bytes_out_str -= 2; + rv += 2; + } + return rv; +} + +/*****************************************************************************/ +int +g_pos(const char *str, const char *to_find) +{ + const char *pp; + + pp = strstr(str, to_find); + + if (pp == 0) + { + return -1; + } + + return (pp - str); +} + +/*****************************************************************************/ +int +g_mbstowcs(twchar *dest, const char *src, int n) +{ + wchar_t *ldest; + int rv; + + ldest = (wchar_t *)dest; + rv = mbstowcs(ldest, src, n); + return rv; +} + +/*****************************************************************************/ +int +g_wcstombs(char *dest, const twchar *src, int n) +{ + const wchar_t *lsrc; + int rv; + + lsrc = (const wchar_t *)src; + rv = wcstombs(dest, lsrc, n); + return rv; +} + +/*****************************************************************************/ +/* returns error */ +/* trim spaces and tabs, anything <= space */ +/* trim_flags 1 trim left, 2 trim right, 3 trim both, 4 trim through */ +/* this will always shorten the string or not change it */ +int +g_strtrim(char *str, int trim_flags) +{ + int index; + int len; + int text1_index; + int got_char; + wchar_t *text; + wchar_t *text1; + + len = mbstowcs(0, str, 0); + + if (len < 1) + { + return 0; + } + + if ((trim_flags < 1) || (trim_flags > 4)) + { + return 1; + } + + 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); + + switch (trim_flags) + { + case 4: /* trim through */ + + for (index = 0; index < len; index++) + { + if (text[index] > 32) + { + text1[text1_index] = text[index]; + text1_index++; + } + } + + text1[text1_index] = 0; + break; + case 3: /* trim both */ + got_char = 0; + + for (index = 0; index < len; index++) + { + if (got_char) + { + text1[text1_index] = text[index]; + text1_index++; + } + else + { + if (text[index] > 32) + { + text1[text1_index] = text[index]; + text1_index++; + got_char = 1; + } + } + } + + text1[text1_index] = 0; + len = text1_index; + + /* trim right */ + for (index = len - 1; index >= 0; index--) + { + if (text1[index] > 32) + { + break; + } + } + + text1_index = index + 1; + text1[text1_index] = 0; + break; + case 2: /* trim right */ + + /* copy it */ + for (index = 0; index < len; index++) + { + text1[text1_index] = text[index]; + text1_index++; + } + + /* trim right */ + for (index = len - 1; index >= 0; index--) + { + if (text1[index] > 32) + { + break; + } + } + + text1_index = index + 1; + text1[text1_index] = 0; + break; + case 1: /* trim left */ + got_char = 0; + + for (index = 0; index < len; index++) + { + if (got_char) + { + text1[text1_index] = text[index]; + text1_index++; + } + else + { + if (text[index] > 32) + { + text1[text1_index] = text[index]; + text1_index++; + got_char = 1; + } + } + } + + text1[text1_index] = 0; + break; + } + + wcstombs(str, text1, text1_index + 1); + free(text); + free(text1); + return 0; +} + diff -Nru xrdp-0.9.12/common/string_calls.h xrdp-0.9.15/common/string_calls.h --- xrdp-0.9.12/common/string_calls.h 1970-01-01 00:00:00.000000000 +0000 +++ xrdp-0.9.15/common/string_calls.h 2020-12-28 14:03:43.000000000 +0000 @@ -0,0 +1,104 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2020 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * generic string handling calls + */ + +#if !defined(STRING_CALLS_H) +#define STRING_CALLS_H + +#include "arch.h" + +/** + * Map a character to a string value + * + * This structure is used by g_format_info_string() to specify the + * string which chould be output for %'ch', where ch is a character + */ +struct info_string_tag +{ + char ch; + const char *val; +}; + +#define INFO_STRING_END_OF_LIST { '\0', NULL } + +/** + * Processes a format string for general info + * + * @param[out] dest Destination buffer + * @param[in] len Length of buffer, including space for a terminator + * @param[in] format Format string to process + * @param[in] map Array of struct info_string_tag. + * + * Where a '%' is encountered in the format string, the map is scanned + * and the corresponding string is copied instead of '%'. + * + * '%%' is always replaced with a single '%' in the output. % strings + * not present in the map are ignored. + * + * The map is terminated with INFO_STRING_END_OF_LIST + * + * Caller can check for buffer truncation by comparing the result with + * the buffer length (as in snprintf()) + */ +unsigned int +g_format_info_string(char *dest, unsigned int len, + const char *format, + const struct info_string_tag map[]); + + +/** + * Converts a boolean to a string for output + * + * @param[in] value Value to convert + * @return String representation + */ +const char * +g_bool2text(int value); + +/** + * Converts a string to a boolean value + * + * @param[in] s String to convert + * @return machine representation + */ +int +g_text2bool(const char *s); + +int g_strlen(const char *text); +const char *g_strchr(const char *text, int c); +char *g_strcpy(char *dest, const char *src); +char *g_strncpy(char *dest, const char *src, int len); +char *g_strcat(char *dest, const char *src); +char *g_strncat(char *dest, const char *src, int len); +char *g_strdup(const char *in); +char *g_strndup(const char *in, const unsigned int maxlen); +int g_strcmp(const char *c1, const char *c2); +int g_strncmp(const char *c1, const char *c2, int len); +int g_strncmp_d(const char *c1, const char *c2, const char delim, int len); +int g_strcasecmp(const char *c1, const char *c2); +int g_strncasecmp(const char *c1, const char *c2, int len); +int g_atoi(const char *str); +int g_htoi(char *str); +int g_bytes_to_hexstr(const void *bytes, int num_bytes, char *out_str, + int bytes_out_str); +int g_pos(const char *str, const char *to_find); +int g_mbstowcs(twchar *dest, const char *src, int n); +int g_wcstombs(char *dest, const twchar *src, int n); +int g_strtrim(char *str, int trim_flags); +#endif diff -Nru xrdp-0.9.12/common/trans.c xrdp-0.9.15/common/trans.c --- xrdp-0.9.12/common/trans.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/common/trans.c 2020-12-28 14:03:43.000000000 +0000 @@ -23,6 +23,7 @@ #endif #include "os_calls.h" +#include "string_calls.h" #include "trans.h" #include "arch.h" #include "parse.h" @@ -302,7 +303,7 @@ int to_read = 0; int read_so_far = 0; int rv = 0; - int cur_source; + enum xrdp_source cur_source; if (self == 0) { @@ -371,7 +372,7 @@ } else if (self->trans_can_recv(self, self->sck, 0)) { - cur_source = 0; + cur_source = XRDP_SOURCE_NONE; if (self->si != 0) { cur_source = self->si->cur_source; @@ -452,17 +453,14 @@ { 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) { @@ -636,7 +634,7 @@ init_stream(wait_s, size); if (self->si != 0) { - if ((self->si->cur_source != 0) && + if ((self->si->cur_source != XRDP_SOURCE_NONE) && (self->si->cur_source != self->my_source)) { self->si->source[self->si->cur_source] += size; diff -Nru xrdp-0.9.12/common/trans.h xrdp-0.9.15/common/trans.h --- xrdp-0.9.12/common/trans.h 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/common/trans.h 2020-12-28 14:03:43.000000000 +0000 @@ -50,16 +50,43 @@ /* optional source info */ -#define XRDP_SOURCE_NONE 0 -#define XRDP_SOURCE_CLIENT 1 -#define XRDP_SOURCE_SESMAN 2 -#define XRDP_SOURCE_CHANSRV 3 -#define XRDP_SOURCE_MOD 4 +enum xrdp_source +{ + XRDP_SOURCE_NONE = 0, + XRDP_SOURCE_CLIENT, + XRDP_SOURCE_SESMAN, + XRDP_SOURCE_CHANSRV, + XRDP_SOURCE_MOD, + + XRDP_SOURCE_MAX_COUNT +}; +/* + * @brief Provide flow control mechanism for (primarily) xrdp + * + * There is one of these data structures per-program. + * + * While input is being read from a 'struct trans' and processed, the + * cur_source member is set to the my_source member from the transport. + * During this processing, trans_write_copy() may be called to send output + * on another struct trans. If this happens, and the ouput needs to be + * buffered, trans_write_copy() can add the number of bytes generated by + * the input trans to the source field for the cur_source. This allows us to + * see how much output has been buffered for each input source. + * + * When the program assembles 'struct trans' objects to scan for input + * (normally in trans_get_wait_objs()), it is able to see how much buffered + * output is registered for each input. Inputs which have too much buffered + * output owing are skipped, and not considered for input. + * + * This provides a simple means of providing back-pressure on an input + * where the data it is providing is being processed and then sent out on + * a much slower link. + */ struct source_info { - int cur_source; - int source[7]; + enum xrdp_source cur_source; + int source[XRDP_SOURCE_MAX_COUNT]; }; struct trans @@ -88,7 +115,7 @@ trans_send_proc trans_send; trans_can_recv_proc trans_can_recv; struct source_info *si; - int my_source; + enum xrdp_source my_source; }; struct trans* diff -Nru xrdp-0.9.12/common/xrdp_client_info.h xrdp-0.9.15/common/xrdp_client_info.h --- xrdp-0.9.12/common/xrdp_client_info.h 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/common/xrdp_client_info.h 2020-12-28 14:03:43.000000000 +0000 @@ -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 @@ 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 */ @@ -157,6 +159,9 @@ int use_cache_glyph_v2; int rail_enable; int suppress_output; + + int enable_token_login; + char domain_user_separator[16]; }; #endif diff -Nru xrdp-0.9.12/common/xrdp_constants.h xrdp-0.9.15/common/xrdp_constants.h --- xrdp-0.9.12/common/xrdp_constants.h 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/common/xrdp_constants.h 2020-12-28 13:47:11.000000000 +0000 @@ -29,9 +29,20 @@ * * xrdp constants * + * Constants defined in publically available Microsoft documents are not + * stored here, but are stored in the include files ms-*.h, where the name + * of the file is the name of the document defining the constant. + * + * So for example, NTSTATUS values found in [MS-ERREF] are found in + * ms-erref.h ******************************************************************************/ #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 @@ -60,542 +71,6 @@ #define MCS_SDRQ 25 /* Send Data Request */ #define MCS_SDIN 26 /* Send Data Indication */ -/* - * Constants come from Remote Desktop Protocol - */ - -/* RDP Security Negotiation codes */ -#define RDP_NEG_REQ 0x01 /* MS-RDPBCGR 2.2.1.1.1 */ -#define RDP_NEG_RSP 0x02 /* MS-RDPBCGR 2.2.1.2.1 */ -#define RDP_NEG_FAILURE 0x03 /* MS-RDPBCGR 2.2.1.2.2 */ -#define RDP_CORRELATION_INFO 0x06 /* MS-RDPBCGR 2.2.1.1.2 */ - -/* Protocol types codes (MS-RDPBCGR 2.2.1.1.1) */ -#define PROTOCOL_RDP 0x00000000 -#define PROTOCOL_SSL 0x00000001 -#define PROTOCOL_HYBRID 0x00000002 -#define PROTOCOL_RDSTLS 0x00000004 -#define PROTOCOL_HYBRID_EX 0x00000008 - -/* Negotiation packet flags (MS-RDPBCGR 2.2.1.2.1) */ -#define EXTENDED_CLIENT_DATA_SUPPORTED 0x01 -#define DYNVC_GFX_PROTOCOL_SUPPORTED 0x02 -#define NEGRSP_RESERVED 0x04 -#define RESTRICTED_ADMIN_MODE_SUPPORTED 0x08 -#define REDIRECTED_AUTHENTICATION_MODE_SUPPORTED 0x10 - -/* RDP Negotiation Failure Codes (MS-RDPBCGR 2.2.1.2.2) */ -#define SSL_REQUIRED_BY_SERVER 0x00000001 -#define SSL_NOT_ALLOWED_BY_SERVER 0x00000002 -#define SSL_CERT_NOT_ON_SERVER 0x00000003 -#define INCONSISTENT_FLAGS 0x00000004 -#define HYBRID_REQUIRED_BY_SERVER 0x00000005 -#define SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER 0x00000006 - -/* Client Core Data: connectionType (MS-RDPBCGR 2.2.1.3.2) */ -#define CONNECTION_TYPE_MODEM 0x01 -#define CONNECTION_TYPE_BROADBAND_LOW 0x02 -#define CONNECTION_TYPE_SATELLITE 0x03 -#define CONNECTION_TYPE_BROADBAND_HIGH 0x04 -#define CONNECTION_TYPE_WAN 0x05 -#define CONNECTION_TYPE_LAN 0x06 -#define CONNECTION_TYPE_AUTODETECT 0x07 - -/* Client Core Data: colorDepth, postBeta2ColorDepth (MS-RDPBCGR 2.2.1.3.2) */ -#define RNS_UD_COLOR_4BPP 0xCA00 -#define RNS_UD_COLOR_8BPP 0xCA01 -#define RNS_UD_COLOR_16BPP_555 0xCA02 -#define RNS_UD_COLOR_16BPP_565 0xCA03 -#define RNS_UD_COLOR_24BPP 0xCA04 - -/* Slow-Path Input Event: messageType (MS-RDPBCGR 2.2.8.1.1.3.1.1) */ -/* TODO: to be renamed */ -#define RDP_INPUT_SYNCHRONIZE 0 -#define RDP_INPUT_CODEPOINT 1 -#define RDP_INPUT_VIRTKEY 2 -#define RDP_INPUT_SCANCODE 4 -#define RDP_INPUT_UNICODE 5 -#define RDP_INPUT_MOUSE 0x8001 -#define RDP_INPUT_MOUSEX 0x8002 - -#define FASTPATH_INPUT_ENCRYPTED 0x2 - -/* Fast-Path Input Event: eventCode (MS-RDPBCGR 2.2.8.1.2.2) */ -#define FASTPATH_INPUT_EVENT_SCANCODE 0x0 -#define FASTPATH_INPUT_EVENT_MOUSE 0x1 -#define FASTPATH_INPUT_EVENT_MOUSEX 0x2 -#define FASTPATH_INPUT_EVENT_SYNC 0x3 -#define FASTPATH_INPUT_EVENT_UNICODE 0x4 -#define FASTPATH_INPUT_EVENT_QOE_TIMESTAMP 0x6 - -/* Fast-Path Keyboard Event: eventHeader (MS-RDPBCGR 2.2.8.2.2.1) */ -#define FASTPATH_INPUT_KBDFLAGS_RELEASE 0x01 -#define FASTPATH_INPUT_KBDFLAGS_EXTENDED 0x02 -#define FASTPATH_INPUT_KBDFLAGS_EXTENDED1 0x04 - -/* Server Fast-Path Update PDU: action (MS-RDPBCGR 2.2.0.1.2) */ -#define FASTPATH_OUTPUT_ACTION_FASTPATH 0x0 -#define FASTPATH_OUTPUT_ACTION_X224 0x3 - -/* Server Fast-Path Update PDU: flags (MS-RDPBCGR 2.2.0.1.2) */ -#define FASTPATH_OUTPUT_ACTION_FASTPATH 0x0 -#define FASTPATH_OUTPUT_SECURE_CHECKSUM 0x1 -#define FASTPATH_OUTPUT_ENCRYPTED 0x2 - -/* Fast-Path Update: updateCode (MS-RDPBCGR 2.2.9.1.2.1) */ -#define FASTPATH_UPDATETYPE_ORDERS 0x0 -#define FASTPATH_UPDATETYPE_BITMAP 0x1 -#define FASTPATH_UPDATETYPE_PALETTE 0x2 -#define FASTPATH_UPDATETYPE_SYNCHRONIZE 0x3 -#define FASTPATH_UPDATETYPE_SURFCMDS 0x4 -#define FASTPATH_UPDATETYPE_PTR_NULL 0x5 -#define FASTPATH_UPDATETYPE_PTR_DEFAULT 0x6 -#define FASTPATH_UPDATETYPE_PTR_POSITION 0x8 -#define FASTPATH_UPDATETYPE_COLOR 0x9 -#define FASTPATH_UPDATETYPE_CACHED 0xA -#define FASTPATH_UPDATETYPE_POINTER 0xB - -/* Fast-Path Update: fragmentation (MS-RDPBCGR 2.2.9.1.2.1) */ -#define FASTPATH_FRAGMENT_SINGLE 0x0 -#define FASTPATH_FRAGMENT_LAST 0x1 -#define FASTPATH_FRAGMENT_FIRST 0x2 -#define FASTPATH_FRAGMENT_NEXT 0x3 -#define FASTPATH_OUTPUT_COMPRESSION_USED 0x2 - -/* Mouse Event: pointerFlags (MS-RDPBCGR 2.2.8.1.1.3.1.1.3) */ -#define PTRFLAGS_HWHEEL 0x0400 -#define PTRFLAGS_WHEEL 0x0200 -#define PTRFLAGS_WHEEL_NEGATIVE 0x0100 -#define WheelRotationMask 0x01FF -#define PTRFLAGS_MOVE 0x0800 -#define PTRFLAGS_DOWN 0x8000 -#define PTRFLAGS_BUTTON1 0x1000 -#define PTRFLAGS_BUTTON2 0x2000 -#define PTRFLAGS_BUTTON3 0x4000 - -/* Extended Mouse Event: pointerFlags (MS-RDPBCGR 2.2.8.1.1.3.1.1.4) */ -#define PTRXFLAGS_DOWN 0x8000 -#define PTRXFLAGS_BUTTON1 0x0001 -#define PTRXFLAGS_BUTTON2 0x0002 - -/* General Capability Set: osMajorType (MS-RDPBCGR 2.2.7.1.1) */ -#define OSMAJORTYPE_UNSPECIFIED 0x0000 -#define OSMAJORTYPE_WINDOWS 0x0001 -#define OSMAJORTYPE_OS2 0x0002 -#define OSMAJORTYPE_MACINTOSH 0x0003 -#define OSMAJORTYPE_UNIX 0x0004 -#define OSMAJORTYPE_IOS 0x0005 -#define OSMAJORTYPE_OSX 0x0006 -#define OSMAJORTYPE_ANDROID 0x0007 -#define OSMAJORTYPE_CHROME_OS 0x0008 - -/* General Capability Set: osMinorType (MS-RDPBCGR 2.2.7.1.1) */ -#define OSMINORTYPE_UNSPECIFIED 0x0000 -#define OSMINORTYPE_WINDOWS_31X 0x0001 -#define OSMINORTYPE_WINDOWS_95 0x0002 -#define OSMINORTYPE_WINDOWS_NT 0x0003 -#define OSMINORTYPE_OS2_V21 0x0004 -#define OSMINORTYPE_POWER_PC 0x0005 -#define OSMINORTYPE_MACINTOSH 0x0006 -#define OSMINORTYPE_NATIVE_XSERVER 0x0007 -#define OSMINORTYPE_PSEUDO_XSERVER 0x0008 -#define OSMINORTYPE_WINDOWS_RT 0x0009 - -/* Window List Capability Set: WndSupportLevel (MS-RDPERP 2.2.1.1.2) */ -#define TS_WINDOW_LEVEL_NOT_SUPPORTED 0x00000000 -#define TS_WINDOW_LEVEL_SUPPORTED 0x00000001 -#define TS_WINDOW_LEVEL_SUPPORTED_EX 0x00000002 - -/* Extended Info Packet: performanceFlags (MS-RDPBCGR 2.2.1.11.1.1.1) */ -/* TODO: to be renamed */ -#define RDP5_DISABLE_NOTHING 0x00 -#define RDP5_NO_WALLPAPER 0x01 -#define RDP5_NO_FULLWINDOWDRAG 0x02 -#define RDP5_NO_MENUANIMATIONS 0x04 -#define RDP5_NO_THEMING 0x08 -#define RDP5_NO_CURSOR_SHADOW 0x20 -#define RDP5_NO_CURSORSETTINGS 0x40 /* disables cursor blinking */ - -/* Virtual channel options */ -/* Channel Definition Structure: options (MS-RDPBCGR 2.2.1.3.4.1) */ -#define REMOTE_CONTROL_PERSISTENT 0x00100000 -/* NOTE: XR_ prefixed to avoid conflict with FreeRDP */ -#define XR_CHANNEL_OPTION_SHOW_PROTOCOL 0x00200000 -#define XR_CHANNEL_OPTION_COMPRESS 0x00400000 -#define XR_CHANNEL_OPTION_COMPRESS_RDP 0x00800000 -#define XR_CHANNEL_OPTION_PRI_LOW 0x02000000 -#define XR_CHANNEL_OPTION_PRI_MED 0x04000000 -#define XR_CHANNEL_OPTION_PRI_HIGH 0x08000000 -#define XR_CHANNEL_OPTION_ENCRYPT_CS 0x10000000 -#define XR_CHANNEL_OPTION_ENCRYPT_SC 0x20000000 -#define XR_CHANNEL_OPTION_ENCRYPT_RDP 0x40000000 -#define XR_CHANNEL_OPTION_INITIALIZED 0x80000000 - -/* RDPDR: Device Announce Header: DeviceType (MS-RDPEFS 2.2.1.3) */ -/* TODO: to be renamed */ -#define DEVICE_TYPE_SERIAL 0x01 -#define DEVICE_TYPE_PARALLEL 0x02 -#define DEVICE_TYPE_PRINTER 0x04 -#define DEVICE_TYPE_DISK 0x08 -#define DEVICE_TYPE_SCARD 0x20 - -/* Order Capability Set: orderSupportExFlags (MS-RDPBCGR 2.2.7.1.3) */ -#define XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT 0x0002 -#define XR_ORDERFLAGS_EX_ALTSEC_FRAME_MARKER_SUPPORT 0x0004 -#define XR_ORDERFLAGS_EX_OFFSCREEN_COMPOSITE_SUPPORT 0x0100 - -/* Order Capability Set: orderSupport (MS-RDPBCGR 2.2.7.1.3) */ -#define TS_NEG_DSTBLT_INDEX 0x00 -#define TS_NEG_PATBLT_INDEX 0x01 -#define TS_NEG_SCRBLT_INDEX 0x02 -#define TS_NEG_MEMBLT_INDEX 0x03 -#define TS_NEG_MEM3BLT_INDEX 0x04 - /* 0x05 */ - /* 0x06 */ -#define TS_NEG_DRAWNINEGRID_INDEX 0x07 -#define TS_NEG_LINETO_INDEX 0x08 -#define TS_NEG_MULTI_DRAWNINEGRID_INDEX 0x09 - /* 0x0A */ -#define TS_NEG_SAVEBITMAP_INDEX 0x0B - /* 0x0C */ - /* 0x0D */ - /* 0x0E */ -#define TS_NEG_MULTIDSTBLT_INDEX 0x0F -#define TS_NEG_MULTIPATBLT_INDEX 0x10 -#define TS_NEG_MULTISCRBLT_INDEX 0x11 -#define TS_NEG_MULTIOPAQUERECT_INDEX 0x12 -#define TS_NEG_FAST_INDEX_INDEX 0x13 -#define TS_NEG_POLYGON_SC_INDEX 0x14 -#define TS_NEG_POLYGON_CB_INDEX 0x15 -#define TS_NEG_POLYLINE_INDEX 0x16 - /* 0x17 */ -#define TS_NEG_FAST_GLYPH_INDEX 0x18 -#define TS_NEG_ELLIPSE_SC_INDEX 0x19 -#define TS_NEG_ELLIPSE_CB_INDEX 0x1A -#define TS_NEG_INDEX_INDEX 0x1B - /* 0x1C */ - /* 0x1D */ - /* 0x1E */ - /* 0x1F */ - -/* General Capability Set: extraFlags (MS-RDPBCGR 2.2.7.1.1) */ -#define TS_CAPS_PROTOCOLVERSION 0x0200 -#define FASTPATH_OUTPUT_SUPPORTED 0x0001 -#define NO_BITMAP_COMPRESSION_HDR 0x0400 -#define LONG_CREDENTIALS_SUPPORTED 0x0004 -#define AUTORECONNECT_SUPPORTED 0x0008 -#define ENC_SALTED_CHECKSUM 0x0010 - -/* Order Capability Set: orderFlags (MS-RDPBCGR 2.2.7.1.3) */ -#define NEGOTIATEORDERSUPPORT 0x0002 -#define ZEROBOUNDSDELTASUPPORT 0x0008 -#define COLORINDEXSUPPORT 0x0020 -#define SOLIDPATTERNBRUSHONLY 0x0040 -#define ORDERFLAGS_EXTRA_FLAGS 0x0080 - -/* Input Capability Set: inputFlags (MS-RDPBCGR 2.2.7.1.6) */ -#define INPUT_FLAG_SCANCODES 0x0001 -#define INPUT_FLAG_MOUSEX 0x0004 -#define INPUT_FLAG_FASTPATH_INPUT 0x0008 -#define INPUT_FLAG_UNICODE 0x0010 -#define INPUT_FLAG_FASTPATH_INPUT2 0x0020 -#define INPUT_FLAG_UNUSED1 0x0040 -#define INPUT_FLAG_UNUSED2 0x0080 -#define TS_INPUT_FLAG_MOUSE_HWHEEL 0x0100 -#define TS_INPUT_FLAG_QOE_TIMESTAMPS 0x0200 - -/* Desktop Composition Capability Set: CompDeskSupportLevel (MS-RDPBCGR 2.2.7.2.8) */ -#define COMPDESK_NOT_SUPPORTED 0x0000 -#define COMPDESK_SUPPORTED 0x0001 - -/* Surface Commands Capability Set: cmdFlags (MS-RDPBCGR 2.2.7.2.9) */ -#define SURFCMDS_SETSURFACEBITS 0x00000002 -#define SURFCMDS_FRAMEMARKER 0x00000010 -#define SURFCMDS_STREAMSUFRACEBITS 0x00000040 - -/* Bitmap Codec: codecGUID (MS-RDPBCGR 2.2.7.2.10.1.1) */ - -/* CODEC_GUID_NSCODEC CA8D1BB9-000F-154F-589FAE2D1A87E2D6 */ -#define XR_CODEC_GUID_NSCODEC \ - "\xb9\x1b\x8d\xca\x0f\x00\x4f\x15\x58\x9f\xae\x2d\x1a\x87\xe2\xd6" - -/* CODEC_GUID_REMOTEFX 76772F12-BD72-4463-AFB3B73C9C6F7886 */ -#define XR_CODEC_GUID_REMOTEFX \ - "\x12\x2F\x77\x76\x72\xBD\x63\x44\xAF\xB3\xB7\x3C\x9C\x6F\x78\x86" - -/* CODEC_GUID_IMAGE_REMOTEFX 2744CCD4-9D8A-4E74-803C-0ECBEEA19C54 */ -#define XR_CODEC_GUID_IMAGE_REMOTEFX \ - "\xD4\xCC\x44\x27\x8A\x9D\x74\x4E\x80\x3C\x0E\xCB\xEE\xA1\x9C\x54" - -/* MFVideoFormat_H264 0x34363248-0000-0010-800000AA00389B71 */ -#define XR_CODEC_GUID_H264 \ - "\x48\x32\x36\x34\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71" - -/* CODEC_GUID_JPEG 1BAF4CE6-9EED-430C-869ACB8B37B66237 */ -#define XR_CODEC_GUID_JPEG \ - "\xE6\x4C\xAF\x1B\xED\x9E\x0C\x43\x86\x9A\xCB\x8B\x37\xB6\x62\x37" - -/* CODEC_GUID_PNG 0E0C858D-28E0-45DB-ADAA0F83E57CC560 */ -#define XR_CODEC_GUID_PNG \ - "\x8D\x85\x0C\x0E\xE0\x28\xDB\x45\xAD\xAA\x0F\x83\xE5\x7C\xC5\x60" - -/* Surface Command Type (MS-RDPBCGR 2.2.9.1.2.1.10.1) */ -#define CMDTYPE_SET_SURFACE_BITS 0x0001 -#define CMDTYPE_FRAME_MARKER 0x0004 -#define CMDTYPE_STREAM_SURFACE_BITS 0x0006 - -/* RDP5 disconnect PDU */ -/* Set Error Info PDU Data: errorInfo (MS-RDPBCGR 2.2.5.1.1) */ -/* TODO: to be renamed */ -#define exDiscReasonNoInfo 0x0000 -#define exDiscReasonAPIInitiatedDisconnect 0x0001 -#define exDiscReasonAPIInitiatedLogoff 0x0002 -#define exDiscReasonServerIdleTimeout 0x0003 -#define exDiscReasonServerLogonTimeout 0x0004 -#define exDiscReasonReplacedByOtherConnection 0x0005 -#define exDiscReasonOutOfMemory 0x0006 -#define exDiscReasonServerDeniedConnection 0x0007 -#define exDiscReasonServerDeniedConnectionFips 0x0008 -#define exDiscReasonLicenseInternal 0x0100 -#define exDiscReasonLicenseNoLicenseServer 0x0101 -#define exDiscReasonLicenseNoLicense 0x0102 -#define exDiscReasonLicenseErrClientMsg 0x0103 -#define exDiscReasonLicenseHwidDoesntMatchLicense 0x0104 -#define exDiscReasonLicenseErrClientLicense 0x0105 -#define exDiscReasonLicenseCantFinishProtocol 0x0106 -#define exDiscReasonLicenseClientEndedProtocol 0x0107 -#define exDiscReasonLicenseErrClientEncryption 0x0108 -#define exDiscReasonLicenseCantUpgradeLicense 0x0109 -#define exDiscReasonLicenseNoRemoteConnections 0x010a - -/* Info Packet (TS_INFO_PACKET): flags (MS-RDPBCGR 2.2.1.11.1.1) */ -/* TODO: to be renamed */ -#define RDP_LOGON_AUTO 0x0008 -#define RDP_LOGON_NORMAL 0x0033 -#define RDP_COMPRESSION 0x0080 -#define RDP_LOGON_BLOB 0x0100 -#define RDP_LOGON_LEAVE_AUDIO 0x2000 -#define RDP_LOGON_RAIL 0x8000 - -/* Compression Flags (MS-RDPBCGR 3.1.8.2.1) */ -/* TODO: to be renamed, not used anywhere */ -#define RDP_MPPC_COMPRESSED 0x20 -#define RDP_MPPC_RESET 0x40 -#define RDP_MPPC_FLUSH 0x80 -#define RDP_MPPC_DICT_SIZE 8192 /* RDP 4.0 | MS-RDPBCGR 3.1.8 */ - -/* Drawing Order: controlFlags (MS-RDPEGDI 2.2.2.2.1, ) */ -#define TS_STANDARD 0x01 -#define TS_SECONDARY 0x02 -#define TS_BOUNDS 0x04 -#define TS_TYPE_CHANGE 0x08 -#define TS_DELTA_COORDINATES 0x10 -#define TS_ZERO_BOUNDS_DELTAS 0x20 -#define TS_ZERO_FIELD_BYTE_BIT0 0x40 -#define TS_ZERO_FIELD_BYTE_BIT1 0x80 - -/* Drawing Order: orderType (MS-RDPEGDI 2.2.2.2.1.1.2) ? */ -#define RDP_ORDER_DESTBLT 0 -#define RDP_ORDER_PATBLT 1 -#define RDP_ORDER_SCREENBLT 2 -#define RDP_ORDER_LINE 9 -#define RDP_ORDER_RECT 10 -#define RDP_ORDER_DESKSAVE 11 -#define RDP_ORDER_MEMBLT 13 -#define RDP_ORDER_TRIBLT 14 -#define RDP_ORDER_POLYLINE 22 -#define RDP_ORDER_TEXT2 27 -#define RDP_ORDER_COMPOSITE 37 /* 0x25 */ - -/* Secondary Drawing Order Header: orderType (MS-RDPEGDI 2.2.2.2.1.2.1.1) */ -#define TS_CACHE_BITMAP_UNCOMPRESSED 0x00 -#define TS_CACHE_COLOR_TABLE 0x01 -#define TS_CACHE_BITMAP_COMPRESSED 0x02 -#define TS_CACHE_GLYPH 0x03 -#define TS_CACHE_BITMAP_UNCOMPRESSED_REV2 0x04 -#define TS_CACHE_BITMAP_COMPRESSED_REV2 0x05 -#define TS_CACHE_BRUSH 0x07 -#define TS_CACHE_BITMAP_COMPRESSED_REV3 0x08 - -/* Maps to generalCapabilitySet in T.128 page 138 */ - -/* Capability Set: capabilitySetType (MS-RDPBCGR 2.2.1.13.1.1.1) */ -#define CAPSTYPE_GENERAL 0x0001 -#define CAPSTYPE_GENERAL_LEN 0x18 - -#define CAPSTYPE_BITMAP 0x0002 -#define CAPSTYPE_BITMAP_LEN 0x1C - -#define CAPSTYPE_ORDER 0x0003 -#define CAPSTYPE_ORDER_LEN 0x58 -#define ORDER_CAP_NEGOTIATE 2 /* NEGOTIATEORDERSUPPORT? not used */ -#define ORDER_CAP_NOSUPPORT 4 /* not used */ - -#define CAPSTYPE_BITMAPCACHE 0x0004 -#define CAPSTYPE_BITMAPCACHE_LEN 0x28 - -#define CAPSTYPE_CONTROL 0x0005 -#define CAPSTYPE_CONTROL_LEN 0x0C - -#define CAPSTYPE_ACTIVATION 0x0007 -#define CAPSTYPE_ACTIVATION_LEN 0x0C - -#define CAPSTYPE_POINTER 0x0008 -#define CAPSTYPE_POINTER_LEN 0x0a -#define CAPSTYPE_POINTER_MONO_LEN 0x08 - -#define CAPSTYPE_SHARE 0x0009 -#define CAPSTYPE_SHARE_LEN 0x08 - -#define CAPSTYPE_COLORCACHE 0x000A -#define CAPSTYPE_COLORCACHE_LEN 0x08 - -#define CAPSTYPE_SOUND 0x000C - -#define CAPSTYPE_INPUT 0x000D -#define CAPSTYPE_INPUT_LEN 0x58 - -#define CAPSTYPE_FONT 0x000E -#define CAPSTYPE_FONT_LEN 0x04 - -#define CAPSTYPE_BRUSH 0x000F -#define CAPSTYPE_BRUSH_LEN 0x08 - -#define CAPSTYPE_GLYPHCACHE 0x0010 -#define CAPSTYPE_OFFSCREENCACHE 0x0011 - -#define CAPSTYPE_BITMAPCACHE_HOSTSUPPORT 0x0012 -#define CAPSTYPE_BITMAPCACHE_HOSTSUPPORT_LEN 0x08 - -#define CAPSTYPE_BITMAPCACHE_REV2 0x0013 -#define CAPSTYPE_BITMAPCACHE_REV2_LEN 0x28 -#define BMPCACHE2_FLAG_PERSIST ((long)1<<31) - -#define CAPSTYPE_VIRTUALCHANNEL 0x0014 -#define CAPSTYPE_VIRTUALCHANNEL_LEN 0x08 - -#define CAPSTYPE_DRAWNINGRIDCACHE 0x0015 -#define CAPSTYPE_DRAWGDIPLUS 0x0016 -#define CAPSTYPE_RAIL 0x0017 -#define CAPSTYPE_WINDOW 0x0018 - -#define CAPSSETTYPE_COMPDESK 0x0019 -#define CAPSSETTYPE_COMPDESK_LEN 0x06 - -#define CAPSSETTYPE_MULTIFRAGMENTUPDATE 0x001A -#define CAPSSETTYPE_MULTIFRAGMENTUPDATE_LEN 0x08 - -#define CAPSETTYPE_LARGE_POINTER 0x001B -#define CAPSETTYPE_LARGE_POINTER_LEN 0x06 - -#define CAPSETTYPE_SURFACE_COMMANDS 0x001C -#define CAPSETTYPE_SURFACE_COMMANDS_LEN 0x0C - -#define CAPSSETTYPE_BITMAP_CODECS 0x001D -#define CAPSSETTYPE_BITMAP_CODECS_LEN 0x1C - -#define CAPSTYPE_FRAME_ACKNOWLEDGE 0x001E -#define CAPSTYPE_FRAME_ACKNOWLEDGE_LEN 0x08 - -/* TS_SECURITY_HEADER: flags (MS-RDPBCGR 2.2.8.1.1.2.1) */ -/* TODO: to be renamed */ -#define SEC_CLIENT_RANDOM 0x0001 /* SEC_EXCHANGE_PKT? */ -#define SEC_ENCRYPT 0x0008 -#define SEC_LOGON_INFO 0x0040 /* SEC_INFO_PKT */ -#define SEC_LICENCE_NEG 0x0080 /* SEC_LICENSE_PKT */ - -#define SEC_TAG_SRV_INFO 0x0c01 /* SC_CORE */ -#define SEC_TAG_SRV_CRYPT 0x0c02 /* SC_SECURITY */ -#define SEC_TAG_SRV_CHANNELS 0x0c03 /* SC_NET? */ - -/* TS_UD_HEADER: type (MS-RDPBCGR (2.2.1.3.1) */ -/* TODO: to be renamed */ -#define SEC_TAG_CLI_INFO 0xc001 /* CS_CORE? */ -#define SEC_TAG_CLI_CRYPT 0xc002 /* CS_SECURITY? */ -#define SEC_TAG_CLI_CHANNELS 0xc003 /* CS_CHANNELS? */ -#define SEC_TAG_CLI_4 0xc004 /* CS_CLUSTER? */ -#define SEC_TAG_CLI_MONITOR 0xc005 /* CS_MONITOR */ - -/* Server Proprietary Certificate (MS-RDPBCGR 2.2.1.4.3.1.1) */ -/* TODO: to be renamed */ -#define SEC_TAG_PUBKEY 0x0006 /* BB_RSA_KEY_BLOB */ -#define SEC_TAG_KEYSIG 0x0008 /* BB_SIGNATURE_KEY_BLOB */ - -/* LicensingMessage (MS-RDPELE 2.2.2) */ -/* TODO: to be renamed */ -#define LICENCE_TAG_DEMAND 0x01 /* LICNSE_REQUEST */ -#define LICENCE_TAG_AUTHREQ 0x02 /* PLATFORM_CHALLENGE */ -#define LICENCE_TAG_ISSUE 0x03 /* NEW_LICENSE */ -#define LICENCE_TAG_REISSUE 0x04 /* UPGRADE_LICENSE */ -#define LICENCE_TAG_PRESENT 0x12 /* LICENSE_INFO */ -#define LICENCE_TAG_REQUEST 0x13 /* NEW_LICENSE_REQUEST */ -#define LICENCE_TAG_AUTHRESP 0x15 /* PLATFORM_CHALLENGE_RESPONSE */ -#define LICENCE_TAG_RESULT 0xff - -/* LICENSE_BINARY_BLOB (MS-RDPBCGR 2.2.1.12.1.2) */ -#define LICENCE_TAG_USER 0x000f /* BB_CLIENT_USER_NAME_BLOB */ -#define LICENCE_TAG_HOST 0x0010 /* BB_CLIENT_MACHINE_NAME_BLOB */ - -/* Share Data Header: pduType2 (MS-RDPBCGR 2.2.8.1.1.1.2) */ -/* TODO: to be renamed */ -#define RDP_DATA_PDU_UPDATE 2 /* PDUTYPE2_UPDATE */ -#define RDP_DATA_PDU_CONTROL 20 -#define RDP_DATA_PDU_POINTER 27 -#define RDP_DATA_PDU_INPUT 28 -#define RDP_DATA_PDU_SYNCHRONISE 31 -#define PDUTYPE2_REFRESH_RECT 33 -#define RDP_DATA_PDU_PLAY_SOUND 34 -#define RDP_DATA_PDU_LOGON 38 -#define RDP_DATA_PDU_FONT2 39 -#define RDP_DATA_PDU_DISCONNECT 47 - -/* Control PDU Data: action (MS-RDPBCGR 2.2.1.15.1) */ -/* TODO: to be renamed */ -#define RDP_CTL_REQUEST_CONTROL 1 /* CTRLACTION_REQUEST_CONTROL */ -#define RDP_CTL_GRANT_CONTROL 2 -#define RDP_CTL_DETACH 3 -#define RDP_CTL_COOPERATE 4 - -/* Slow-Path Graphics Update: updateType (MS-RDPBCGR 2.2.9.1.1.3.1) */ -/* TODO: to be renamed */ -#define RDP_UPDATE_ORDERS 0 -#define RDP_UPDATE_BITMAP 1 -#define RDP_UPDATE_PALETTE 2 -#define RDP_UPDATE_SYNCHRONIZE 3 - -/* Server Pointer Update PDU: messageType (MS-RDPBCGR 2.2.9.1.1.4) */ -/* TODO: to be renamed */ -#define RDP_POINTER_SYSTEM 1 /* TS_PTRMSGTYPE_SYSTEM */ -#define RDP_POINTER_MOVE 3 -#define RDP_POINTER_COLOR 6 -#define RDP_POINTER_CACHED 7 -#define RDP_POINTER_POINTER 8 - -/* System Pointer Update: systemPointerType (MS-RDPBCGR 2.2.9.1.1.4.3) */ -#define RDP_NULL_POINTER 0 -#define RDP_DEFAULT_POINTER 0x7F00 - -/* Keyboard Event: keyboardFlags (MS-RDPBCGR 2.2.8.1.1.3.1.1.1) */ -/* TODO: to be renamed */ -#define KBD_FLAG_RIGHT 0x0001 -#define KBD_FLAG_EXT 0x0100 /* KBDFLAGS_EXTENDED */ -#define KBD_FLAG_QUIET 0x1000 -#define KBD_FLAG_DOWN 0x4000 -#define KBD_FLAG_UP 0x8000 - -/* Synchronize Event: toggleFlags (MS-RDPBCGR 2.2.8.1.1.3.1.1.5) */ -/* TODO: to be renamed */ -#define KBD_FLAG_SCROLL 0x0001 /* TS_SYNC_SCROLL_LOCK */ -#define KBD_FLAG_NUMLOCK 0x0002 -#define KBD_FLAG_CAPITAL 0x0004 -#define TS_SYNC_KANA_LOCK 0x0008 - -/* Glyph Cache Capability Set: GlyphSupportLevel (MS-RDPBCGR 2.2.7.1.8) */ -#define GLYPH_SUPPORT_NONE 0x0000 -#define GLYPH_SUPPORT_PARTIAL 0x0001 -#define GLYPH_SUPPORT_FULL 0x0002 -#define GLYPH_SUPPORT_ENCODE 0x0003 - /****************************************************************************** * * Constants come from other Microsoft products @@ -616,33 +91,6 @@ /* NTSTATUS Values (MS-ERREF 2.3.1) */ /* used for RDPDR */ -#define STATUS_SUCCESS 0x00000000 -#define STATUS_PENDING 0x00000103 - -#define STATUS_NO_MORE_FILES 0x80000006 -#define STATUS_DEVICE_PAPER_EMPTY 0x8000000e -#define STATUS_DEVICE_POWERED_OFF 0x8000000f -#define STATUS_DEVICE_OFF_LINE 0x80000010 -#define STATUS_DEVICE_BUSY 0x80000011 - -#define STATUS_INVALID_HANDLE 0xc0000008 -#define STATUS_INVALID_PARAMETER 0xc000000d -#define STATUS_NO_SUCH_FILE 0xc000000f -#define STATUS_INVALID_DEVICE_REQUEST 0xc0000010 -#define STATUS_ACCESS_DENIED 0xc0000022 -#define STATUS_OBJECT_NAME_COLLISION 0xc0000035 -#define STATUS_DISK_FULL 0xc000007f -#define STATUS_FILE_IS_A_DIRECTORY 0xc00000ba -#define STATUS_NOT_SUPPORTED 0xc00000bb -#define STATUS_TIMEOUT 0xc0000102 -#define STATUS_CANCELLED 0xc0000120 - -/* MS-SMB2 2.2.13 */ -/* TODO: not used anywhere */ -#define FILE_DIRECTORY_FILE 0x00000001 -#define FILE_NON_DIRECTORY_FILE 0x00000040 -#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000 - /* * not yet sorted out */ @@ -672,13 +120,6 @@ #define LICENCE_SIGNATURE_SIZE 16 -/* PDU Types (MS-RDPBCGR 2.2.8.1.1.1.1) */ -#define PDUTYPE_DEMANDACTIVEPDU 0x1 -#define PDUTYPE_CONFIRMACTIVEPDU 0x3 -#define PDUTYPE_DEACTIVATEALLPDU 0x6 -#define PDUTYPE_DATAPDU 0x7 -#define PDUTYPE_SERVER_REDIR_PKT 0xA - /* See T.128 */ /* not used anywhere */ #define RDP_KEYPRESS 0 @@ -810,6 +251,10 @@ #define WM_BUTTON6DOWN 112 #define WM_BUTTON7UP 113 #define WM_BUTTON7DOWN 114 +#define WM_BUTTON8UP 115 +#define WM_BUTTON8DOWN 116 +#define WM_BUTTON9UP 117 +#define WM_BUTTON9DOWN 118 #define WM_INVALIDATE 200 #define CB_ITEMCHANGE 300 diff -Nru xrdp-0.9.12/compile xrdp-0.9.15/compile --- xrdp-0.9.12/compile 2019-12-28 12:36:37.000000000 +0000 +++ xrdp-0.9.15/compile 2020-12-28 14:06:38.000000000 +0000 @@ -3,7 +3,7 @@ scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify @@ -53,7 +53,7 @@ MINGW*) file_conv=mingw ;; - CYGWIN*) + CYGWIN* | MSYS*) file_conv=cygwin ;; *) @@ -67,7 +67,7 @@ mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; - cygwin/*) + cygwin/* | msys/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) diff -Nru xrdp-0.9.12/configure xrdp-0.9.15/configure --- xrdp-0.9.12/configure 2019-12-28 12:36:36.000000000 +0000 +++ xrdp-0.9.15/configure 2020-12-28 14:06:37.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for xrdp 0.9.12. +# Generated by GNU Autoconf 2.69 for xrdp 0.9.15. # # Report bugs to . # @@ -590,8 +590,8 @@ # Identity of this package. PACKAGE_NAME='xrdp' PACKAGE_TARNAME='xrdp' -PACKAGE_VERSION='0.9.12' -PACKAGE_STRING='xrdp 0.9.12' +PACKAGE_VERSION='0.9.15' +PACKAGE_STRING='xrdp 0.9.15' PACKAGE_BUGREPORT='xrdp-devel@googlegroups.com' PACKAGE_URL='' @@ -1427,7 +1427,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures xrdp 0.9.12 to adapt to many kinds of systems. +\`configure' configures xrdp 0.9.15 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1501,7 +1501,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of xrdp 0.9.12:";; + short | recursive ) echo "Configuration of xrdp 0.9.15:";; esac cat <<\_ACEOF @@ -1520,13 +1520,14 @@ --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) - --disable-pam Build PAM support (default: yes) + --enable-pam Build PAM support (default: yes) --enable-vsock Build AF_VSOCK support (default: no) --enable-ipv6 Build IPv6 support (default: no, experimental) --enable-ipv6only Build IPv6-only (default: no) - --enable-kerberos Build kerberos support (default: no) + --enable-kerberos Build kerberos support (prefer --enable-pam if + available) (default: no) --enable-bsd Build BSD auth support (default: no) - --enable-pamuserpass Build pam userpass support (default: no) + --enable-pamuserpass Build PAM userpass support (default: no) --enable-pam-config=CONF Select PAM config to install: arch, debian, redhat, suse, freebsd, macos, unix (default: autodetect) @@ -1667,7 +1668,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -xrdp configure 0.9.12 +xrdp configure 0.9.15 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2036,7 +2037,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by xrdp $as_me 0.9.12, which was +It was created by xrdp $as_me 0.9.15, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2591,12 +2592,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac + MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then @@ -2901,7 +2897,7 @@ # Define the identity of the package. PACKAGE='xrdp' - VERSION='0.9.12' + VERSION='0.9.15' cat >>confdefs.h <<_ACEOF @@ -12355,248 +12351,6 @@ AM_BACKSLASH='\' -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking CFLAGS for maximum warnings" >&5 -$as_echo_n "checking CFLAGS for maximum warnings... " >&6; } -if ${ac_cv_cflags_warn_all+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_cflags_warn_all="no, unknown" -ac_save_CFLAGS="$CFLAGS" -for ac_arg in "-warn all % -warn all" "-pedantic % -Wall" "-xstrconst % -v" "-std1 % -verbose -w0 -warnprotos" "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" "-ansi -ansiE % -fullwarn" "+ESlit % +w1" "-Xc % -pvctl,fullmsg" "-h conform % -h msglevel 2" # -do CFLAGS="$ac_save_CFLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_cflags_warn_all=`echo $ac_arg | sed -e 's,.*% *,,'` ; break -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -done -CFLAGS="$ac_save_CFLAGS" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cflags_warn_all" >&5 -$as_echo "$ac_cv_cflags_warn_all" >&6; } - - -case ".$ac_cv_cflags_warn_all" in - .ok|.ok,*) ;; - .|.no|.no,*) ;; - *) -if ${CFLAGS+:} false; then : - - case " $CFLAGS " in #( - *" $ac_cv_cflags_warn_all "*) : - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$ac_cv_cflags_warn_all"; } >&5 - (: CFLAGS already contains $ac_cv_cflags_warn_all) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } ;; #( - *) : - - as_fn_append CFLAGS " $ac_cv_cflags_warn_all" - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 - (: CFLAGS="$CFLAGS") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - ;; -esac - -else - - CFLAGS=$ac_cv_cflags_warn_all - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 - (: CFLAGS="$CFLAGS") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - -fi - ;; -esac - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - - - -for flag in -Wwrite-strings; do - as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5 -$as_echo_n "checking whether C compiler accepts $flag... " >&6; } -if eval \${$as_CACHEVAR+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ax_check_save_flags=$CFLAGS - CFLAGS="$CFLAGS $flag" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$as_CACHEVAR=yes" -else - eval "$as_CACHEVAR=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS=$ax_check_save_flags -fi -eval ac_res=\$$as_CACHEVAR - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_CACHEVAR"\" = x"yes"; then : - -if ${CFLAGS+:} false; then : - - case " $CFLAGS " in #( - *" $flag "*) : - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5 - (: CFLAGS already contains $flag) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } ;; #( - *) : - - as_fn_append CFLAGS " $flag" - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 - (: CFLAGS="$CFLAGS") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - ;; -esac - -else - - CFLAGS=$flag - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 - (: CFLAGS="$CFLAGS") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - -fi - -else - : -fi - -done - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __attribute__((format))" >&5 -$as_echo_n "checking for __attribute__((format))... " >&6; } -if ${ax_cv_have_func_attribute_format+:} false; then : - $as_echo_n "(cached) " >&6 -else - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - - int foo(const char *p, ...) __attribute__((format(printf, 1, 2))); - -int -main () -{ - - ; - return 0; -} - -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - if test -s conftest.err; then : - ax_cv_have_func_attribute_format=no -else - ax_cv_have_func_attribute_format=yes -fi -else - ax_cv_have_func_attribute_format=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_have_func_attribute_format" >&5 -$as_echo "$ax_cv_have_func_attribute_format" >&6; } - - if test yes = $ax_cv_have_func_attribute_format; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_FUNC_ATTRIBUTE_FORMAT 1 -_ACEOF - -fi - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t" >&5 -$as_echo_n "checking for socklen_t... " >&6; } -if ${ac_cv_ax_type_socklen_t+:} false; then : - $as_echo_n "(cached) " >&6 -else - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - #include -int -main () -{ -socklen_t len = (socklen_t) 42; return (!len); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_ax_type_socklen_t=yes -else - ac_cv_ax_type_socklen_t=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_ax_type_socklen_t" >&5 -$as_echo "$ac_cv_ax_type_socklen_t" >&6; } - if test $ac_cv_ax_type_socklen_t != yes; then - -$as_echo "#define socklen_t int" >>confdefs.h - - fi - - case $host_os in *linux*) linux=yes @@ -12982,18 +12736,493 @@ fi -# Don't fail without working nasm if rfxcodec is not enabled -if test "x$enable_rfxcodec" != xyes; then - with_simd=no - export with_simd -fi +# configure compiler options and CFLAGS -# Check if -ldl is needed to use dlopen() -DLOPEN_LIBS= -ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" -if test "x$ac_cv_func_dlopen" = xyes; then : -else + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __attribute__((format))" >&5 +$as_echo_n "checking for __attribute__((format))... " >&6; } +if ${ax_cv_have_func_attribute_format+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + + int foo(const char *p, ...) __attribute__((format(printf, 1, 2))); + +int +main () +{ + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if test -s conftest.err; then : + ax_cv_have_func_attribute_format=no +else + ax_cv_have_func_attribute_format=yes +fi +else + ax_cv_have_func_attribute_format=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_have_func_attribute_format" >&5 +$as_echo "$ax_cv_have_func_attribute_format" >&6; } + + if test yes = $ax_cv_have_func_attribute_format; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_FUNC_ATTRIBUTE_FORMAT 1 +_ACEOF + +fi + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t" >&5 +$as_echo_n "checking for socklen_t... " >&6; } +if ${ac_cv_ax_type_socklen_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include +int +main () +{ +socklen_t len = (socklen_t) 42; return (!len); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_ax_type_socklen_t=yes +else + ac_cv_ax_type_socklen_t=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_ax_type_socklen_t" >&5 +$as_echo "$ac_cv_ax_type_socklen_t" >&6; } + if test $ac_cv_ax_type_socklen_t != yes; then + +$as_echo "#define socklen_t int" >>confdefs.h + + fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking CFLAGS for maximum warnings" >&5 +$as_echo_n "checking CFLAGS for maximum warnings... " >&6; } +if ${ac_cv_cflags_warn_all+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_cflags_warn_all="no, unknown" +ac_save_CFLAGS="$CFLAGS" +for ac_arg in "-warn all % -warn all" "-pedantic % -Wall" "-xstrconst % -v" "-std1 % -verbose -w0 -warnprotos" "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" "-ansi -ansiE % -fullwarn" "+ESlit % +w1" "-Xc % -pvctl,fullmsg" "-h conform % -h msglevel 2" # +do CFLAGS="$ac_save_CFLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_cflags_warn_all=`echo $ac_arg | sed -e 's,.*% *,,'` ; break +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +CFLAGS="$ac_save_CFLAGS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cflags_warn_all" >&5 +$as_echo "$ac_cv_cflags_warn_all" >&6; } + + +case ".$ac_cv_cflags_warn_all" in + .ok|.ok,*) ;; + .|.no|.no,*) ;; + *) +if ${CFLAGS+:} false; then : + + case " $CFLAGS " in #( + *" $ac_cv_cflags_warn_all "*) : + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$ac_cv_cflags_warn_all"; } >&5 + (: CFLAGS already contains $ac_cv_cflags_warn_all) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } ;; #( + *) : + + as_fn_append CFLAGS " $ac_cv_cflags_warn_all" + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 + (: CFLAGS="$CFLAGS") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + ;; +esac + +else + + CFLAGS=$ac_cv_cflags_warn_all + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 + (: CFLAGS="$CFLAGS") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + +fi + ;; +esac + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + +for flag in -Wwrite-strings; do + as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5 +$as_echo_n "checking whether C compiler accepts $flag... " >&6; } +if eval \${$as_CACHEVAR+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS $flag" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$as_CACHEVAR=yes" +else + eval "$as_CACHEVAR=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +eval ac_res=\$$as_CACHEVAR + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_CACHEVAR"\" = x"yes"; then : + +if ${CFLAGS+:} false; then : + + case " $CFLAGS " in #( + *" $flag "*) : + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5 + (: CFLAGS already contains $flag) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } ;; #( + *) : + + as_fn_append CFLAGS " $flag" + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 + (: CFLAGS="$CFLAGS") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + ;; +esac + +else + + CFLAGS=$flag + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 + (: CFLAGS="$CFLAGS") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + +fi + +else + : +fi + +done + + +if test -z "$LINUX_TRUE"; then : + + + + +for flag in -Werror; do + as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5 +$as_echo_n "checking whether C compiler accepts $flag... " >&6; } +if eval \${$as_CACHEVAR+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS $flag" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$as_CACHEVAR=yes" +else + eval "$as_CACHEVAR=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +eval ac_res=\$$as_CACHEVAR + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_CACHEVAR"\" = x"yes"; then : + +if ${CFLAGS+:} false; then : + + case " $CFLAGS " in #( + *" $flag "*) : + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5 + (: CFLAGS already contains $flag) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } ;; #( + *) : + + as_fn_append CFLAGS " $flag" + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 + (: CFLAGS="$CFLAGS") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + ;; +esac + +else + + CFLAGS=$flag + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 + (: CFLAGS="$CFLAGS") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + +fi + +else + : +fi + +done + +fi # bsd has warnings that have not been fixed yet + +if test -z "$XRDP_DEBUG_TRUE"; then : + + + + +for flag in -g -O0; do + as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5 +$as_echo_n "checking whether C compiler accepts $flag... " >&6; } +if eval \${$as_CACHEVAR+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS $flag" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$as_CACHEVAR=yes" +else + eval "$as_CACHEVAR=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +eval ac_res=\$$as_CACHEVAR + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_CACHEVAR"\" = x"yes"; then : + +if ${CFLAGS+:} false; then : + + case " $CFLAGS " in #( + *" $flag "*) : + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5 + (: CFLAGS already contains $flag) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } ;; #( + *) : + + as_fn_append CFLAGS " $flag" + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 + (: CFLAGS="$CFLAGS") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + ;; +esac + +else + + CFLAGS=$flag + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 + (: CFLAGS="$CFLAGS") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + +fi + +else + : +fi + +done + +else + + + + +for flag in -O2; do + as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5 +$as_echo_n "checking whether C compiler accepts $flag... " >&6; } +if eval \${$as_CACHEVAR+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ax_check_save_flags=$CFLAGS + CFLAGS="$CFLAGS $flag" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$as_CACHEVAR=yes" +else + eval "$as_CACHEVAR=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS=$ax_check_save_flags +fi +eval ac_res=\$$as_CACHEVAR + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_CACHEVAR"\" = x"yes"; then : + +if ${CFLAGS+:} false; then : + + case " $CFLAGS " in #( + *" $flag "*) : + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5 + (: CFLAGS already contains $flag) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } ;; #( + *) : + + as_fn_append CFLAGS " $flag" + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 + (: CFLAGS="$CFLAGS") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + ;; +esac + +else + + CFLAGS=$flag + { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5 + (: CFLAGS="$CFLAGS") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + +fi + +else + : +fi + +done + +fi + +# Don't fail without working nasm if rfxcodec is not enabled +if test "x$enable_rfxcodec" != xyes; then + with_simd=no + export with_simd +fi + +# Check if -ldl is needed to use dlopen() +DLOPEN_LIBS= +ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + +else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : @@ -13161,7 +13390,7 @@ test -n "$OPENSSL" || OPENSSL=":" -# checking for pam variation +# checking for PAM variation # Linux-PAM is used in Linux systems # OpenPAM is used by FreeBSD, NetBSD, DragonFly BSD and OS X # OpenBSD uses BSD Authentication rather than both PAMs @@ -13182,14 +13411,41 @@ +# Check only one auth mechanism is specified, and give it a name +auth_cnt=0 +auth_mech="Builtin" +if test x$enable_pam = xyes +then + auth_cnt=`expr $auth_cnt + 1` + auth_mech="PAM" +fi +if test x$bsd = xtrue +then + auth_cnt=`expr $auth_cnt + 1` + auth_mech="BSD" +fi +if test x$enable_kerberos = xyes +then + auth_cnt=`expr $auth_cnt + 1` + auth_mech="Kerberos" +fi +if test x$enable_pamuserpass = xyes +then + auth_cnt=`expr $auth_cnt + 1` + auth_mech="PAM userpass" +fi + +if test $auth_cnt -gt 1 +then + as_fn_error $? "--enable-pam, --enable-bsd, --enable-pamuserpass and --enable-kerberos are mutually exclusive" "$LINENO" 5 +fi + # checking if pam should be autodetected. if test "x$enable_pam" = "xyes" then - if test "x$enable_kerberos" != "xyes" + if test -z "$enable_bsd" then - if test -z "$enable_bsd" - then - ac_fn_c_check_header_mongrel "$LINENO" "security/pam_appl.h" "ac_cv_header_security_pam_appl_h" "$ac_includes_default" + ac_fn_c_check_header_mongrel "$LINENO" "security/pam_appl.h" "ac_cv_header_security_pam_appl_h" "$ac_includes_default" if test "x$ac_cv_header_security_pam_appl_h" = xyes; then : else @@ -13197,7 +13453,6 @@ fi - fi fi if test "x$enable_pam_config" = "x"; then PAM_RULES="auto" @@ -13249,7 +13504,7 @@ fi -if test "x$enable_pam" != "xyes" || test "x$bsd" = "xtrue" +if test "x$enable_pam" != "xyes" then $as_echo "#define USE_NOPAM 1" >>confdefs.h @@ -13363,11 +13618,6 @@ fi -if test "x$enable_xrdpdebug" = "xyes" -then - CFLAGS="-g -O0" -fi - # checking for fuse if test "x$enable_fuse" = "xyes" then @@ -15075,7 +15325,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by xrdp $as_me 0.9.12, which was +This file was extended by xrdp $as_me 0.9.15, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -15141,7 +15391,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -xrdp config.status 0.9.12 +xrdp config.status 0.9.15 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -16260,7 +16510,9 @@ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "Something went wrong bootstrapping makefile fragments - for automatic dependency tracking. Try re-running configure with the + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE=\"gmake\" (or whatever is + necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking). See \`config.log' for more details" "$LINENO" 5; } @@ -17014,8 +17266,7 @@ echo " ipv6 $enable_ipv6" echo " ipv6only $enable_ipv6only" echo " vsock $enable_vsock" -echo " pam $enable_pam" -echo " kerberos $enable_kerberos" +echo " auth mechanism $auth_mech" echo " debug $enable_xrdpdebug" echo " rdpsndaudin $enable_rdpsndaudin" echo "" @@ -17025,6 +17276,9 @@ echo " libdir $libdir" echo " bindir $bindir" echo " sysconfdir $sysconfdir" +echo "" +echo " CFLAGS = $CFLAGS" +echo " LDFLAGS = $LDFLAGS" # xrdp_configure_options.h will be written to the build directory, not the source directory echo '#define XRDP_CONFIGURE_OPTIONS \' > ./xrdp_configure_options.h diff -Nru xrdp-0.9.12/configure.ac xrdp-0.9.15/configure.ac --- xrdp-0.9.12/configure.ac 2019-12-28 12:30:26.000000000 +0000 +++ xrdp-0.9.15/configure.ac 2020-12-28 14:03:43.000000000 +0000 @@ -1,7 +1,7 @@ # Process this file with autoconf to produce a configure script AC_PREREQ(2.65) -AC_INIT([xrdp], [0.9.12], [xrdp-devel@googlegroups.com]) +AC_INIT([xrdp], [0.9.15], [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 @@ # 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 @@ -70,7 +65,7 @@ fi AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ]) -AC_ARG_ENABLE(pam, AS_HELP_STRING([--disable-pam], +AC_ARG_ENABLE(pam, AS_HELP_STRING([--enable-pam], [Build PAM support (default: yes)]), [], [enable_pam=yes]) AM_CONDITIONAL(SESMAN_NOPAM, [test x$enable_pam != xyes]) @@ -84,7 +79,7 @@ [Build IPv6-only (default: no)]), [], [enable_ipv6only=no]) AC_ARG_ENABLE(kerberos, AS_HELP_STRING([--enable-kerberos], - [Build kerberos support (default: no)]), + [Build kerberos support (prefer --enable-pam if available) (default: no)]), [], [enable_kerberos=no]) AC_ARG_ENABLE(bsd, AS_HELP_STRING([--enable-bsd], [Build BSD auth support (default: no)]), @@ -92,7 +87,7 @@ AM_CONDITIONAL(SESMAN_BSD, [test x$bsd = xtrue]) AM_CONDITIONAL(SESMAN_KERBEROS, [test x$enable_kerberos = xyes]) AC_ARG_ENABLE(pamuserpass, AS_HELP_STRING([--enable-pamuserpass], - [Build pam userpass support (default: no)]), + [Build PAM userpass support (default: no)]), [], [enable_pamuserpass=no]) AM_CONDITIONAL(SESMAN_PAMUSERPASS, [test x$enable_pamuserpass = xyes]) AC_ARG_ENABLE(pam-config, AS_HELP_STRING([--enable-pam-config=CONF], @@ -155,6 +150,19 @@ [], [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 @@ -175,7 +183,7 @@ OPENSSL_BIN=`$PKG_CONFIG --variable=exec_prefix openssl`/bin AC_PATH_PROGS([OPENSSL], [openssl], [:], [$OPENSSL_BIN:$PATH]) -# checking for pam variation +# checking for PAM variation # Linux-PAM is used in Linux systems # OpenPAM is used by FreeBSD, NetBSD, DragonFly BSD and OS X # OpenBSD uses BSD Authentication rather than both PAMs @@ -184,16 +192,42 @@ AC_CHECK_HEADER([security/pam_constants.h], [AC_DEFINE([HAVE_PAM_CONSTANTS_H], 1, [Using OpenPAM], [])]) +# Check only one auth mechanism is specified, and give it a name +auth_cnt=0 +auth_mech="Builtin" +if test x$enable_pam = xyes +then + auth_cnt=`expr $auth_cnt + 1` + auth_mech="PAM" +fi +if test x$bsd = xtrue +then + auth_cnt=`expr $auth_cnt + 1` + auth_mech="BSD" +fi +if test x$enable_kerberos = xyes +then + auth_cnt=`expr $auth_cnt + 1` + auth_mech="Kerberos" +fi +if test x$enable_pamuserpass = xyes +then + auth_cnt=`expr $auth_cnt + 1` + auth_mech="PAM userpass" +fi + +if test $auth_cnt -gt 1 +then + AC_MSG_ERROR([--enable-pam, --enable-bsd, --enable-pamuserpass and --enable-kerberos are mutually exclusive]) +fi + # checking if pam should be autodetected. if test "x$enable_pam" = "xyes" then - if test "x$enable_kerberos" != "xyes" + if test -z "$enable_bsd" then - if test -z "$enable_bsd" - then - AC_CHECK_HEADER([security/pam_appl.h], [], - [AC_MSG_ERROR([please install libpam0g-dev or pam-devel])]) - fi + AC_CHECK_HEADER([security/pam_appl.h], [], + [AC_MSG_ERROR([please install libpam0g-dev or pam-devel])]) fi if test "x$enable_pam_config" = "x"; then PAM_RULES="auto" @@ -229,7 +263,7 @@ AC_DEFINE([XRDP_ENABLE_IPV6],1,[Enable IPv6]) fi -if test "x$enable_pam" != "xyes" || test "x$bsd" = "xtrue" +if test "x$enable_pam" != "xyes" then AC_DEFINE([USE_NOPAM],1,[Disable PAM]) fi @@ -243,11 +277,6 @@ [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 @@ -392,8 +421,7 @@ echo " ipv6 $enable_ipv6" echo " ipv6only $enable_ipv6only" echo " vsock $enable_vsock" -echo " pam $enable_pam" -echo " kerberos $enable_kerberos" +echo " auth mechanism $auth_mech" echo " debug $enable_xrdpdebug" echo " rdpsndaudin $enable_rdpsndaudin" echo "" @@ -403,6 +431,9 @@ echo " libdir $libdir" echo " bindir $bindir" echo " sysconfdir $sysconfdir" +echo "" +echo " CFLAGS = $CFLAGS" +echo " LDFLAGS = $LDFLAGS" # xrdp_configure_options.h will be written to the build directory, not the source directory echo '#define XRDP_CONFIGURE_OPTIONS \' > ./xrdp_configure_options.h diff -Nru xrdp-0.9.12/debian/changelog xrdp-0.9.15/debian/changelog --- xrdp-0.9.12/debian/changelog 2020-07-19 15:11:20.000000000 +0000 +++ xrdp-0.9.15/debian/changelog 2021-09-29 17:29:28.000000000 +0000 @@ -1,11 +1,26 @@ -xrdp (0.9.12-1.1) unstable; urgency=medium +xrdp (0.9.15-1ubuntu1) impish; urgency=medium - * Non-maintainer upload. - * xrdp-sesman can be crashed remotely over port 3350 (CVE-2020-4044) - (Closes: #964573) - * Fixed CVE-2020-4044 CI errors + * debian/patches/known-arch-list.diff: fix build failure on ppc64el + and s390x due to unknown arch. - -- Salvatore Bonaccorso Sun, 19 Jul 2020 17:11:20 +0200 + -- Steve Langasek Wed, 29 Sep 2021 10:29:28 -0700 + +xrdp (0.9.15-1) unstable; urgency=medium + + [ Thorsten Glaser ] + * Do not source /etc/profile twice in startwm.sh + * Drop xrdp-pulseaudio-installer (defunct) from Suggests + * README.Debian: Link current pulseaudio-module-xrdp instructions + * d/p/pulse-debian.patch: Update comment w.r.t. the above + + [ Dominik George ] + * New upstream release. + * Bump Standards-Version. + + No changes needed. + * Refresh patches. + * Add new files to d/copyright. + + -- Dominik George Mon, 01 Mar 2021 22:27:36 +0100 xrdp (0.9.12-1) unstable; urgency=low diff -Nru xrdp-0.9.12/debian/control xrdp-0.9.15/debian/control --- xrdp-0.9.12/debian/control 2020-07-19 15:11:20.000000000 +0000 +++ xrdp-0.9.15/debian/control 2021-09-29 17:29:28.000000000 +0000 @@ -1,5 +1,6 @@ Source: xrdp -Maintainer: Debian Remote Maintainers +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: Debian Remote Maintainers Uploaders: Dominik George , Andreas Tille , @@ -25,7 +26,7 @@ pkg-config, systemd [linux-any], Homepage: http://www.xrdp.org/ -Standards-Version: 4.4.1 +Standards-Version: 4.5.1 Rules-Requires-Root: no Vcs-Browser: https://salsa.debian.org/debian-remote-team/xrdp Vcs-Git: https://salsa.debian.org/debian-remote-team/xrdp.git @@ -44,7 +45,6 @@ xorgxrdp, Suggests: guacamole, - xrdp-pulseaudio-installer Description: Remote Desktop Protocol (RDP) server xrdp offers a graphical login to a remote client using RDP (the Remote Desktop Protocol). xrdp can connect to diff -Nru xrdp-0.9.12/debian/copyright xrdp-0.9.15/debian/copyright --- xrdp-0.9.12/debian/copyright 2020-07-19 15:11:20.000000000 +0000 +++ xrdp-0.9.15/debian/copyright 2021-03-01 21:27:36.000000000 +0000 @@ -313,6 +313,21 @@ Copyright: 2019, Jay Sorg License: Apache-2.0 +Files: common/ms-erref.h + common/ms-fscc.h + common/ms-rdpbcgr.h + common/ms-rdpefs.h + common/ms-rdpegdi.h + common/ms-rdpele.h + common/ms-rdperp.h + common/ms-smb2.h + common/string_calls.c + common/string_calls.h + sesman/chansrv/chansrv_config.c + sesman/chansrv/chansrv_config.h +Copyright: 2020, Jay Sorg +License: Apache-2.0 + Files: common/fifo.c common/fifo.h sesman/chansrv/chansrv_common.c @@ -549,7 +564,6 @@ License: GPL-3+~autoconf Files: configure - libpainter/configure librfxcodec/configure libpainter/configure m4/libtool.m4 diff -Nru xrdp-0.9.12/debian/patches/config.diff xrdp-0.9.15/debian/patches/config.diff --- xrdp-0.9.12/debian/patches/config.diff 2020-07-19 15:11:20.000000000 +0000 +++ xrdp-0.9.15/debian/patches/config.diff 2021-03-01 21:27:36.000000000 +0000 @@ -3,9 +3,9 @@ --- a/sesman/sesman.ini +++ b/sesman/sesman.ini -@@ -83,7 +83,7 @@ SyslogLevel=DEBUG - ; Arch Linux : param=/usr/lib/xorg-server/Xorg +@@ -94,7 +94,7 @@ ; CentOS 7 : param=/usr/bin/Xorg or param=Xorg + ; CentOS 8 : param=/usr/libexec/Xorg ; -param=Xorg +param=/usr/lib/xorg/Xorg diff -Nru xrdp-0.9.12/debian/patches/document-certs.diff xrdp-0.9.15/debian/patches/document-certs.diff --- xrdp-0.9.12/debian/patches/document-certs.diff 2020-07-19 15:11:20.000000000 +0000 +++ xrdp-0.9.15/debian/patches/document-certs.diff 2021-03-01 21:27:36.000000000 +0000 @@ -5,7 +5,7 @@ --- a/xrdp/xrdp.ini +++ b/xrdp/xrdp.ini -@@ -49,6 +49,8 @@ crypt_level=high +@@ -50,6 +50,8 @@ ; X.509 certificate and private key ; openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -days 365 diff -Nru xrdp-0.9.12/debian/patches/Fixed-CVE-2020-4044-CI-errors.patch xrdp-0.9.15/debian/patches/Fixed-CVE-2020-4044-CI-errors.patch --- xrdp-0.9.12/debian/patches/Fixed-CVE-2020-4044-CI-errors.patch 2020-07-19 15:11:20.000000000 +0000 +++ xrdp-0.9.15/debian/patches/Fixed-CVE-2020-4044-CI-errors.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,102 +0,0 @@ -From: matt335672 <30179339+matt335672@users.noreply.github.com> -Date: Mon, 29 Jun 2020 11:22:13 +0100 -Subject: Fixed CVE-2020-4044 CI errors -Origin: https://github.com/neutrinolabs/xrdp/commit/cfd653c6e541ccba38cadbc8776423b288d14042 - ---- - sesman/libscp/libscp_v0.c | 12 ++++++------ - sesman/libscp/libscp_v1s.c | 6 +++--- - sesman/libscp/libscp_v1s_mng.c | 2 +- - 3 files changed, 10 insertions(+), 10 deletions(-) - -diff --git a/sesman/libscp/libscp_v0.c b/sesman/libscp/libscp_v0.c -index 55168b4f515f..90bf921e9783 100644 ---- a/sesman/libscp/libscp_v0.c -+++ b/sesman/libscp/libscp_v0.c -@@ -99,7 +99,7 @@ enum SCP_CLIENT_STATES_E - scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s) - { - tui32 version; -- tui32 size; -+ int size; - tui16 sz; - - init_stream(c->in_s, c->in_s->size); -@@ -187,8 +187,8 @@ scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s) - if (size < (8 + 2 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE) - { - log_message(LOG_LEVEL_WARNING, -- "[v0:%d] connection aborted: msg size = %u", -- __LINE__, (unsigned int)size); -+ "[v0:%d] connection aborted: msg size = %d", -+ __LINE__, size); - return SCP_CLIENT_STATE_SIZE_ERR; - } - -@@ -240,7 +240,7 @@ scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s) - static enum SCP_SERVER_STATES_E - scp_v0s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session) - { -- tui32 size; -+ int size; - tui16 height; - tui16 width; - tui16 bpp; -@@ -254,8 +254,8 @@ scp_v0s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session) - if (size < (8 + 2) || size > SCP_MAX_MESSAGE_SIZE) - { - log_message(LOG_LEVEL_WARNING, -- "[v0:%d] connection aborted: msg size = %u", -- __LINE__, (unsigned int)size); -+ "[v0:%d] connection aborted: msg size = %d", -+ __LINE__, size); - return SCP_SERVER_STATE_SIZE_ERR; - } - -diff --git a/sesman/libscp/libscp_v1s.c b/sesman/libscp/libscp_v1s.c -index 37e8a01c42f8..7aab200df522 100644 ---- a/sesman/libscp/libscp_v1s.c -+++ b/sesman/libscp/libscp_v1s.c -@@ -218,7 +218,7 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SES - enum SCP_SERVER_STATES_E result; - struct SCP_SESSION *session; - tui32 version; -- tui32 size; -+ int size; - tui16 cmdset; - tui16 cmd; - -@@ -354,7 +354,7 @@ scp_v1s_request_password(struct SCP_CONNECTION *c, struct SCP_SESSION *s, - const char *reason) - { - tui32 version; -- tui32 size; -+ int size; - tui16 cmdset; - tui16 cmd; - int rlen; -@@ -539,7 +539,7 @@ enum SCP_SERVER_STATES_E - scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNECTED_SESSION *ds, SCP_SID *sid) - { - tui32 version = 1; -- tui32 size = 12; -+ int size = 12; - tui16 cmd = 40; - int pktcnt; - int idx; -diff --git a/sesman/libscp/libscp_v1s_mng.c b/sesman/libscp/libscp_v1s_mng.c -index 8e9aed12b84f..28c8290f8ff7 100644 ---- a/sesman/libscp/libscp_v1s_mng.c -+++ b/sesman/libscp/libscp_v1s_mng.c -@@ -381,7 +381,7 @@ static enum SCP_SERVER_STATES_E - _scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s) - { - tui32 version; -- tui32 size; -+ int size; - tui16 cmd; - // tui8 dim; - // char buf[257]; --- -2.28.0.rc0 - diff -Nru xrdp-0.9.12/debian/patches/Fix-for-CVE-2020-4044.patch xrdp-0.9.15/debian/patches/Fix-for-CVE-2020-4044.patch --- xrdp-0.9.12/debian/patches/Fix-for-CVE-2020-4044.patch 2020-07-19 15:11:20.000000000 +0000 +++ xrdp-0.9.15/debian/patches/Fix-for-CVE-2020-4044.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,1270 +0,0 @@ -From: matt335672 <30179339+matt335672@users.noreply.github.com> -Date: Fri, 12 Jun 2020 09:56:47 +0100 -Subject: Fix for CVE-2020-4044 -Origin: https://github.com/neutrinolabs/xrdp/commit/ba2f727c9a2acbee59c27b5883b36b43b022ea9c -Bug-Debian: https://bugs.debian.org/964573 -Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2020-4044 - -Reported by: Ashley Newson ---- - sesman/libscp/libscp_types.h | 4 + - sesman/libscp/libscp_v0.c | 335 ++++++++++++++++++++------------ - sesman/libscp/libscp_v1s.c | 336 +++++++++++++++++++++++---------- - sesman/libscp/libscp_v1s_mng.c | 164 +++++++++++++--- - sesman/scp.c | 12 +- - 5 files changed, 592 insertions(+), 259 deletions(-) - -diff --git a/sesman/libscp/libscp_types.h b/sesman/libscp/libscp_types.h -index 8cb9166c515f..84e6c4651e7e 100644 ---- a/sesman/libscp/libscp_types.h -+++ b/sesman/libscp/libscp_types.h -@@ -59,6 +59,10 @@ - - #include "libscp_types_mng.h" - -+/* Max server incoming and outgoing message size, used to stop memory -+ exhaustion attempts (CVE-2020-4044) */ -+#define SCP_MAX_MESSAGE_SIZE 8192 -+ - struct SCP_CONNECTION - { - int in_sck; -diff --git a/sesman/libscp/libscp_v0.c b/sesman/libscp/libscp_v0.c -index 61bf4fdae43a..55168b4f515f 100644 ---- a/sesman/libscp/libscp_v0.c -+++ b/sesman/libscp/libscp_v0.c -@@ -34,6 +34,65 @@ - - extern struct log_config *s_log; - -+/** Maximum length of a string (two bytes + len), excluding the terminator -+ * -+ * Practially this is limited by [MS-RDPBCGR] TS_INFO_PACKET -+ * */ -+#define STRING16_MAX_LEN 512 -+ -+/** -+ * Reads a big-endian uint16 followed by a string into a buffer -+ * -+ * Buffer is null-terminated on success -+ * -+ * @param s Input stream -+ * @param [out] Output buffer (must be >= (STRING16_MAX_LEN+1) chars) -+ * @param param Parameter we're reading -+ * @param line Line number reference -+ * @return != 0 if string read OK -+ */ -+static -+int in_string16(struct stream *s, char str[], const char *param, int line) -+{ -+ int result; -+ -+ if (!s_check_rem(s, 2)) -+ { -+ log_message(LOG_LEVEL_WARNING, -+ "[v0:%d] connection aborted: %s len missing", -+ line, param); -+ result = 0; -+ } -+ else -+ { -+ unsigned int sz; -+ -+ in_uint16_be(s, sz); -+ if (sz > STRING16_MAX_LEN) -+ { -+ log_message(LOG_LEVEL_WARNING, -+ "[v0:%d] connection aborted: %s too long (%u chars)", -+ line, param, sz); -+ result = 0; -+ } -+ else -+ { -+ result = s_check_rem(s, sz); -+ if (!result) -+ { -+ log_message(LOG_LEVEL_WARNING, -+ "[v0:%d] connection aborted: %s data missing", -+ line, param); -+ } -+ else -+ { -+ in_uint8a(s, str, sz); -+ str[sz] = '\0'; -+ } -+ } -+ } -+ return result; -+} - /* client API */ - /******************************************************************************/ - enum SCP_CLIENT_STATES_E -@@ -71,10 +130,24 @@ scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s) - } - - sz = g_strlen(s->username); -+ if (sz > STRING16_MAX_LEN) -+ { -+ log_message(LOG_LEVEL_WARNING, -+ "[v0:%d] connection aborted: username too long", -+ __LINE__); -+ return SCP_CLIENT_STATE_SIZE_ERR; -+ } - out_uint16_be(c->out_s, sz); - out_uint8a(c->out_s, s->username, sz); - - sz = g_strlen(s->password); -+ if (sz > STRING16_MAX_LEN) -+ { -+ log_message(LOG_LEVEL_WARNING, -+ "[v0:%d] connection aborted: password too long", -+ __LINE__); -+ return SCP_CLIENT_STATE_SIZE_ERR; -+ } - out_uint16_be(c->out_s, sz); - out_uint8a(c->out_s, s->password, sz); - out_uint16_be(c->out_s, s->width); -@@ -111,14 +184,16 @@ scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s) - - in_uint32_be(c->in_s, size); - -- if (size < 14) -+ if (size < (8 + 2 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE) - { -- log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: packet size error", __LINE__); -+ log_message(LOG_LEVEL_WARNING, -+ "[v0:%d] connection aborted: msg size = %u", -+ __LINE__, (unsigned int)size); - return SCP_CLIENT_STATE_SIZE_ERR; - } - - /* getting payload */ -- init_stream(c->in_s, c->in_s->size); -+ init_stream(c->in_s, size - 8); - - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) - { -@@ -126,6 +201,8 @@ scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s) - return SCP_CLIENT_STATE_NETWORK_ERR; - } - -+ c->in_s->end = c->in_s->data + (size - 8); -+ - /* check code */ - in_uint16_be(c->in_s, sz); - -@@ -151,43 +228,38 @@ scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s) - return SCP_CLIENT_STATE_END; - } - --/* server API */ --/******************************************************************************/ --enum SCP_SERVER_STATES_E --scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk) -+/** -+ * Initialises a V0 session object -+ * -+ * At the time of the call, the version has been read from the connection -+ * -+ * @param c Connection -+ * @param [out] session pre-allocated session object -+ * @return SCP_SERVER_STATE_OK for success -+ */ -+static enum SCP_SERVER_STATES_E -+scp_v0s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session) - { -- tui32 version = 0; - tui32 size; -- struct SCP_SESSION *session = 0; -- tui16 sz; -+ tui16 height; -+ tui16 width; -+ tui16 bpp; - tui32 code = 0; -- char *buf = 0; -- -- if (!skipVchk) -- { -- LOG_DBG("[v0:%d] starting connection", __LINE__); -+ char buf[STRING16_MAX_LEN + 1]; - -- if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) -- { -- c->in_s->end = c->in_s->data + 8; -- in_uint32_be(c->in_s, version); -- -- if (version != 0) -- { -- log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__); -- return SCP_SERVER_STATE_VERSION_ERR; -- } -- } -- else -- { -- log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); -- return SCP_SERVER_STATE_NETWORK_ERR; -- } -- } -+ scp_session_set_version(session, 0); - -+ /* Check for a header and a code value in the length */ - in_uint32_be(c->in_s, size); -+ if (size < (8 + 2) || size > SCP_MAX_MESSAGE_SIZE) -+ { -+ log_message(LOG_LEVEL_WARNING, -+ "[v0:%d] connection aborted: msg size = %u", -+ __LINE__, (unsigned int)size); -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } - -- init_stream(c->in_s, 8196); -+ init_stream(c->in_s, size - 8); - - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) - { -@@ -201,16 +273,6 @@ scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk) - - if (code == 0 || code == 10 || code == 20) - { -- session = scp_session_create(); -- -- if (0 == session) -- { -- log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); -- return SCP_SERVER_STATE_INTERNAL_ERR; -- } -- -- scp_session_set_version(session, version); -- - if (code == 0) - { - scp_session_set_type(session, SCP_SESSION_TYPE_XVNC); -@@ -225,154 +287,130 @@ scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk) - } - - /* reading username */ -- in_uint16_be(c->in_s, sz); -- buf = g_new0(char, sz + 1); -- in_uint8a(c->in_s, buf, sz); -- buf[sz] = '\0'; -+ if (!in_string16(c->in_s, buf, "username", __LINE__)) -+ { -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } - if (0 != scp_session_set_username(session, buf)) - { -- scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__); -- g_free(buf); - return SCP_SERVER_STATE_INTERNAL_ERR; - } -- g_free(buf); - - /* reading password */ -- in_uint16_be(c->in_s, sz); -- buf = g_new0(char, sz + 1); -- in_uint8a(c->in_s, buf, sz); -- buf[sz] = '\0'; -+ if (!in_string16(c->in_s, buf, "passwd", __LINE__)) -+ { -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } - if (0 != scp_session_set_password(session, buf)) - { -- scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__); -- g_free(buf); - return SCP_SERVER_STATE_INTERNAL_ERR; - } -- g_free(buf); -- -- /* width */ -- in_uint16_be(c->in_s, sz); -- scp_session_set_width(session, sz); -- /* height */ -- in_uint16_be(c->in_s, sz); -- scp_session_set_height(session, sz); -- /* bpp */ -- in_uint16_be(c->in_s, sz); -- if (0 != scp_session_set_bpp(session, (tui8)sz)) -+ -+ /* width + height + bpp */ -+ if (!s_check_rem(c->in_s, 2 + 2 + 2)) -+ { -+ log_message(LOG_LEVEL_WARNING, -+ "[v0:%d] connection aborted: width+height+bpp missing", -+ __LINE__); -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } -+ in_uint16_be(c->in_s, width); -+ scp_session_set_width(session, width); -+ in_uint16_be(c->in_s, height); -+ scp_session_set_height(session, height); -+ in_uint16_be(c->in_s, bpp); -+ if (0 != scp_session_set_bpp(session, (tui8)bpp)) - { -- scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, - "[v0:%d] connection aborted: unsupported bpp: %d", -- __LINE__, (tui8)sz); -+ __LINE__, (tui8)bpp); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - if (s_check_rem(c->in_s, 2)) - { - /* reading domain */ -- in_uint16_be(c->in_s, sz); -- -- if (sz > 0) -+ if (!in_string16(c->in_s, buf, "domain", __LINE__)) -+ { -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } -+ if (buf[0] != '\0') - { -- buf = g_new0(char, sz + 1); -- in_uint8a(c->in_s, buf, sz); -- buf[sz] = '\0'; - scp_session_set_domain(session, buf); -- g_free(buf); - } - } - - if (s_check_rem(c->in_s, 2)) - { - /* reading program */ -- in_uint16_be(c->in_s, sz); -+ if (!in_string16(c->in_s, buf, "program", __LINE__)) -+ { -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } - -- if (sz > 0) -+ if (buf[0] != '\0') - { -- buf = g_new0(char, sz + 1); -- in_uint8a(c->in_s, buf, sz); -- buf[sz] = '\0'; - scp_session_set_program(session, buf); -- g_free(buf); - } - } - - if (s_check_rem(c->in_s, 2)) - { - /* reading directory */ -- in_uint16_be(c->in_s, sz); -+ if (!in_string16(c->in_s, buf, "directory", __LINE__)) -+ { -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } - -- if (sz > 0) -+ if (buf[0] != '\0') - { -- buf = g_new0(char, sz + 1); -- in_uint8a(c->in_s, buf, sz); -- buf[sz] = '\0'; - scp_session_set_directory(session, buf); -- g_free(buf); - } - } - - if (s_check_rem(c->in_s, 2)) - { - /* reading client IP address */ -- in_uint16_be(c->in_s, sz); -- -- if (sz > 0) -+ if (!in_string16(c->in_s, buf, "client IP", __LINE__)) -+ { -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } -+ if (buf[0] != '\0') - { -- buf = g_new0(char, sz + 1); -- in_uint8a(c->in_s, buf, sz); -- buf[sz] = '\0'; - scp_session_set_client_ip(session, buf); -- g_free(buf); - } - } - } - else if (code == SCP_GW_AUTHENTICATION) - { -- /* g_writeln("Command is SCP_GW_AUTHENTICATION"); */ -- session = scp_session_create(); -- -- if (0 == session) -- { -- /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);*/ -- return SCP_SERVER_STATE_INTERNAL_ERR; -- } -- -- scp_session_set_version(session, version); - scp_session_set_type(session, SCP_GW_AUTHENTICATION); - /* reading username */ -- in_uint16_be(c->in_s, sz); -- buf = g_new0(char, sz + 1); -- in_uint8a(c->in_s, buf, sz); -- buf[sz] = '\0'; -+ if (!in_string16(c->in_s, buf, "username", __LINE__)) -+ { -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } - - /* g_writeln("Received user name: %s",buf); */ - if (0 != scp_session_set_username(session, buf)) - { -- scp_session_destroy(session); - /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__);*/ -- g_free(buf); - return SCP_SERVER_STATE_INTERNAL_ERR; - } -- g_free(buf); - - /* reading password */ -- in_uint16_be(c->in_s, sz); -- buf = g_new0(char, sz + 1); -- in_uint8a(c->in_s, buf, sz); -- buf[sz] = '\0'; -+ if (!in_string16(c->in_s, buf, "passwd", __LINE__)) -+ { -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } - - /* g_writeln("Received password: %s",buf); */ - if (0 != scp_session_set_password(session, buf)) - { -- scp_session_destroy(session); - /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__); */ -- g_free(buf); - return SCP_SERVER_STATE_INTERNAL_ERR; - } -- g_free(buf); - } - else - { -@@ -380,10 +418,67 @@ scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk) - return SCP_SERVER_STATE_SEQUENCE_ERR; - } - -- (*s) = session; - return SCP_SERVER_STATE_OK; - } - -+ -+/* server API */ -+/******************************************************************************/ -+enum SCP_SERVER_STATES_E -+scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk) -+{ -+ enum SCP_SERVER_STATES_E result = SCP_SERVER_STATE_OK; -+ struct SCP_SESSION *session = NULL; -+ tui32 version = 0; -+ -+ if (!skipVchk) -+ { -+ LOG_DBG("[v0:%d] starting connection", __LINE__); -+ -+ if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) -+ { -+ c->in_s->end = c->in_s->data + 8; -+ in_uint32_be(c->in_s, version); -+ -+ if (version != 0) -+ { -+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__); -+ result = SCP_SERVER_STATE_VERSION_ERR; -+ } -+ } -+ else -+ { -+ log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); -+ result = SCP_SERVER_STATE_NETWORK_ERR; -+ } -+ } -+ -+ if (result == SCP_SERVER_STATE_OK) -+ { -+ session = scp_session_create(); -+ if (NULL == session) -+ { -+ log_message(LOG_LEVEL_WARNING, -+ "[v0:%d] connection aborted: no memory", -+ __LINE__); -+ result = SCP_SERVER_STATE_INTERNAL_ERR; -+ } -+ else -+ { -+ result = scp_v0s_init_session(c, session); -+ if (result != SCP_SERVER_STATE_OK) -+ { -+ scp_session_destroy(session); -+ session = NULL; -+ } -+ } -+ } -+ -+ (*s) = session; -+ -+ return result; -+} -+ - /******************************************************************************/ - enum SCP_SERVER_STATES_E - scp_v0s_allow_connection(struct SCP_CONNECTION *c, SCP_DISPLAY d, const tui8 *guid) -diff --git a/sesman/libscp/libscp_v1s.c b/sesman/libscp/libscp_v1s.c -index 27e5ef13db30..37e8a01c42f8 100644 ---- a/sesman/libscp/libscp_v1s.c -+++ b/sesman/libscp/libscp_v1s.c -@@ -35,16 +35,194 @@ - - //extern struct log_config* s_log; - -+/** -+ * Reads a uint8 followed by a string into a buffer -+ * -+ * Buffer is null-terminated on success -+ * -+ * @param s Input stream -+ * @param [out] Output buffer (must be >= 256 chars) -+ * @param param Parameter we're reading -+ * @param line Line number reference -+ * @return != 0 if string read OK -+ * -+ * @todo -+ * This needs to be merged with the func of the same name in -+ * libscp_v1s_mng.c -+ */ -+static -+int in_string8(struct stream *s, char str[], const char *param, int line) -+{ -+ int result; -+ -+ if (!s_check_rem(s, 1)) -+ { -+ log_message(LOG_LEVEL_WARNING, -+ "[v1s:%d] connection aborted: %s len missing", -+ line, param); -+ result = 0; -+ } -+ else -+ { -+ unsigned int sz; -+ -+ in_uint8(s, sz); -+ result = s_check_rem(s, sz); -+ if (!result) -+ { -+ log_message(LOG_LEVEL_WARNING, -+ "[v1s:%d] connection aborted: %s data missing", -+ line, param); -+ } -+ else -+ { -+ in_uint8a(s, str, sz); -+ str[sz] = '\0'; -+ } -+ } -+ return result; -+} -+/* server API */ -+ -+/** -+ * Initialises a V1 session object -+ * -+ * This is called after the V1 header, command set and command have been read -+ * -+ * @param c Connection -+ * @param [out] session pre-allocated session object -+ * @return SCP_SERVER_STATE_OK for success -+ */ -+static enum SCP_SERVER_STATES_E -+scp_v1s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session) -+{ -+ tui8 type; -+ tui16 height; -+ tui16 width; -+ tui8 bpp; -+ tui8 sz; -+ char buf[256]; -+ -+ scp_session_set_version(session, 1); -+ -+ /* Check there's data for the session type, the height, the width, the -+ * bpp, the resource sharing indicator and the locale */ -+ if (!s_check_rem(c->in_s, 1 + 2 + 2 + 1 + 1 + 17)) -+ { -+ log_message(LOG_LEVEL_WARNING, -+ "[v1s:%d] connection aborted: short packet", -+ __LINE__); -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } -+ -+ in_uint8(c->in_s, type); -+ -+ if ((type != SCP_SESSION_TYPE_XVNC) && (type != SCP_SESSION_TYPE_XRDP)) -+ { -+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: unknown session type", __LINE__); -+ return SCP_SERVER_STATE_SESSION_TYPE_ERR; -+ } -+ -+ scp_session_set_type(session, type); -+ -+ in_uint16_be(c->in_s, height); -+ scp_session_set_height(session, height); -+ in_uint16_be(c->in_s, width); -+ scp_session_set_width(session, width); -+ in_uint8(c->in_s, bpp); -+ if (0 != scp_session_set_bpp(session, bpp)) -+ { -+ log_message(LOG_LEVEL_WARNING, -+ "[v1s:%d] connection aborted: unsupported bpp: %d", -+ __LINE__, bpp); -+ return SCP_SERVER_STATE_INTERNAL_ERR; -+ } -+ in_uint8(c->in_s, sz); -+ scp_session_set_rsr(session, sz); -+ in_uint8a(c->in_s, buf, 17); -+ buf[17] = '\0'; -+ scp_session_set_locale(session, buf); -+ -+ /* Check there's enough data left for at least an IPv4 address (+len) */ -+ if (!s_check_rem(c->in_s, 1 + 4)) -+ { -+ log_message(LOG_LEVEL_WARNING, -+ "[v1s:%d] connection aborted: IP addr len missing", -+ __LINE__); -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } -+ -+ in_uint8(c->in_s, sz); -+ -+ if (sz == SCP_ADDRESS_TYPE_IPV4) -+ { -+ tui32 ipv4; -+ in_uint32_be(c->in_s, ipv4); -+ scp_session_set_addr(session, sz, &ipv4); -+ } -+ else if (sz == SCP_ADDRESS_TYPE_IPV6) -+ { -+ if (!s_check_rem(c->in_s, 16)) -+ { -+ log_message(LOG_LEVEL_WARNING, -+ "[v1s:%d] connection aborted: IP addr missing", -+ __LINE__); -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } -+ in_uint8a(c->in_s, buf, 16); -+ scp_session_set_addr(session, sz, buf); -+ } -+ -+ /* reading hostname */ -+ if (!in_string8(c->in_s, buf, "hostname", __LINE__)) -+ { -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } -+ -+ if (0 != scp_session_set_hostname(session, buf)) -+ { -+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); -+ return SCP_SERVER_STATE_INTERNAL_ERR; -+ } -+ -+ /* reading username */ -+ if (!in_string8(c->in_s, buf, "username", __LINE__)) -+ { -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } -+ -+ if (0 != scp_session_set_username(session, buf)) -+ { -+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); -+ return SCP_SERVER_STATE_INTERNAL_ERR; -+ } -+ -+ /* reading password */ -+ if (!in_string8(c->in_s, buf, "passwd", __LINE__)) -+ { -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } -+ -+ if (0 != scp_session_set_password(session, buf)) -+ { -+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); -+ return SCP_SERVER_STATE_INTERNAL_ERR; -+ } -+ -+ return SCP_SERVER_STATE_OK; -+} -+ - /* server API */ - enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk) - { -+ enum SCP_SERVER_STATES_E result; - struct SCP_SESSION *session; - tui32 version; - tui32 size; - tui16 cmdset; - tui16 cmd; -- tui8 sz; -- char buf[257]; -+ -+ (*s) = NULL; - - if (!skipVchk) - { -@@ -68,13 +246,15 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SES - - in_uint32_be(c->in_s, size); - -- if (size < 12) -+ /* Check the message is big enough for the header, the command set, and -+ * the command (but not too big) */ -+ if (size < (8 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); - return SCP_SERVER_STATE_SIZE_ERR; - } - -- init_stream(c->in_s, c->in_s->size); -+ init_stream(c->in_s, size - 8); - - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size - 8))) - { -@@ -82,6 +262,8 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SES - return SCP_SERVER_STATE_NETWORK_ERR; - } - -+ c->in_s->end = c->in_s->data + (size - 8); -+ - /* reading command set */ - in_uint16_be(c->in_s, cmdset); - -@@ -111,98 +293,27 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SES - - session = scp_session_create(); - -- if (0 == session) -- { -- log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (malloc returned NULL)", __LINE__); -- return SCP_SERVER_STATE_INTERNAL_ERR; -- } -- -- scp_session_set_version(session, 1); -- -- in_uint8(c->in_s, sz); -- -- if ((sz != SCP_SESSION_TYPE_XVNC) && (sz != SCP_SESSION_TYPE_XRDP)) -+ if (NULL == session) - { -- scp_session_destroy(session); -- log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: unknown session type", __LINE__); -- return SCP_SERVER_STATE_SESSION_TYPE_ERR; -- } -- -- scp_session_set_type(session, sz); -- -- in_uint16_be(c->in_s, cmd); -- scp_session_set_height(session, cmd); -- in_uint16_be(c->in_s, cmd); -- scp_session_set_width(session, cmd); -- in_uint8(c->in_s, sz); -- if (0 != scp_session_set_bpp(session, sz)) -- { -- scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, -- "[v1s:%d] connection aborted: unsupported bpp: %d", -- __LINE__, sz); -- return SCP_SERVER_STATE_INTERNAL_ERR; -- } -- in_uint8(c->in_s, sz); -- scp_session_set_rsr(session, sz); -- in_uint8a(c->in_s, buf, 17); -- buf[17] = '\0'; -- scp_session_set_locale(session, buf); -- -- in_uint8(c->in_s, sz); -- -- if (sz == SCP_ADDRESS_TYPE_IPV4) -- { -- in_uint32_be(c->in_s, size); -- scp_session_set_addr(session, sz, &size); -- } -- else if (sz == SCP_ADDRESS_TYPE_IPV6) -- { -- in_uint8a(c->in_s, buf, 16); -- scp_session_set_addr(session, sz, buf); -+ "[v1s:%d] connection aborted: internal error " -+ "(malloc returned NULL)", __LINE__); -+ result = SCP_SERVER_STATE_INTERNAL_ERR; - } -- -- buf[256] = '\0'; -- /* reading hostname */ -- in_uint8(c->in_s, sz); -- buf[sz] = '\0'; -- in_uint8a(c->in_s, buf, sz); -- -- if (0 != scp_session_set_hostname(session, buf)) -- { -- scp_session_destroy(session); -- log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); -- return SCP_SERVER_STATE_INTERNAL_ERR; -- } -- -- /* reading username */ -- in_uint8(c->in_s, sz); -- buf[sz] = '\0'; -- in_uint8a(c->in_s, buf, sz); -- -- if (0 != scp_session_set_username(session, buf)) -- { -- scp_session_destroy(session); -- log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); -- return SCP_SERVER_STATE_INTERNAL_ERR; -- } -- -- /* reading password */ -- in_uint8(c->in_s, sz); -- buf[sz] = '\0'; -- in_uint8a(c->in_s, buf, sz); -- -- if (0 != scp_session_set_password(session, buf)) -+ else - { -- scp_session_destroy(session); -- log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); -- return SCP_SERVER_STATE_INTERNAL_ERR; -+ result = scp_v1s_init_session(c, session); -+ if (result != SCP_SERVER_STATE_OK) -+ { -+ scp_session_destroy(session); -+ session = NULL; -+ } - } - - /* returning the struct */ - (*s) = session; - -- return SCP_SERVER_STATE_OK; -+ return result; - } - - enum SCP_SERVER_STATES_E -@@ -242,13 +353,12 @@ enum SCP_SERVER_STATES_E - scp_v1s_request_password(struct SCP_CONNECTION *c, struct SCP_SESSION *s, - const char *reason) - { -- tui8 sz; - tui32 version; - tui32 size; - tui16 cmdset; - tui16 cmd; - int rlen; -- char buf[257]; -+ char buf[256]; - - init_stream(c->in_s, c->in_s->size); - init_stream(c->out_s, c->out_s->size); -@@ -296,13 +406,17 @@ scp_v1s_request_password(struct SCP_CONNECTION *c, struct SCP_SESSION *s, - - in_uint32_be(c->in_s, size); - -- if (size < 12) -+ /* Check the message is big enough for the header, the command set, and -+ * the command (but not too big) */ -+ if (size < (8 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE) - { -- log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); -+ log_message(LOG_LEVEL_WARNING, -+ "[v1s:%d] connection aborted: size error", -+ __LINE__); - return SCP_SERVER_STATE_SIZE_ERR; - } - -- init_stream(c->in_s, c->in_s->size); -+ init_stream(c->in_s, size - 8); - - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size - 8))) - { -@@ -310,6 +424,8 @@ scp_v1s_request_password(struct SCP_CONNECTION *c, struct SCP_SESSION *s, - return SCP_SERVER_STATE_NETWORK_ERR; - } - -+ c->in_s->end = c->in_s->data + (size - 8); -+ - in_uint16_be(c->in_s, cmdset); - - if (cmdset != SCP_COMMAND_SET_DEFAULT) -@@ -326,11 +442,11 @@ scp_v1s_request_password(struct SCP_CONNECTION *c, struct SCP_SESSION *s, - return SCP_SERVER_STATE_SEQUENCE_ERR; - } - -- buf[256] = '\0'; - /* reading username */ -- in_uint8(c->in_s, sz); -- buf[sz] = '\0'; -- in_uint8a(c->in_s, buf, sz); -+ if (!in_string8(c->in_s, buf, "username", __LINE__)) -+ { -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } - - if (0 != scp_session_set_username(s, buf)) - { -@@ -339,9 +455,10 @@ scp_v1s_request_password(struct SCP_CONNECTION *c, struct SCP_SESSION *s, - } - - /* reading password */ -- in_uint8(c->in_s, sz); -- buf[sz] = '\0'; -- in_uint8a(c->in_s, buf, sz); -+ if (!in_string8(c->in_s, buf, "passwd", __LINE__)) -+ { -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } - - if (0 != scp_session_set_password(s, buf)) - { -@@ -468,13 +585,15 @@ scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNEC - - in_uint32_be(c->in_s, size); - -- if (size < 12) -+ /* Check the message is big enough for the header, the command set, and -+ * the command (but not too big) */ -+ if (size < (8 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); - return SCP_SERVER_STATE_SIZE_ERR; - } - -- init_stream(c->in_s, c->in_s->size); -+ init_stream(c->in_s, size - 8); - - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size - 8))) - { -@@ -482,6 +601,8 @@ scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNEC - return SCP_SERVER_STATE_NETWORK_ERR; - } - -+ c->in_s->end = c->in_s->data + (size - 8); -+ - in_uint16_be(c->in_s, cmd); - - if (cmd != SCP_COMMAND_SET_DEFAULT) -@@ -606,14 +727,16 @@ scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNEC - - in_uint32_be(c->in_s, size); - -- if (size < 12) -+ /* Check the message is big enough for the header, the command set, and -+ * the command (but not too big) */ -+ if (size < (8 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); - return SCP_SERVER_STATE_SIZE_ERR; - } - - /* rest of the packet */ -- init_stream(c->in_s, c->in_s->size); -+ init_stream(c->in_s, size - 8); - - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size - 8))) - { -@@ -621,6 +744,8 @@ scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNEC - return SCP_SERVER_STATE_NETWORK_ERR; - } - -+ c->in_s->end = c->in_s->data + (size - 8); -+ - in_uint16_be(c->in_s, cmd); - - if (cmd != SCP_COMMAND_SET_DEFAULT) -@@ -633,6 +758,11 @@ scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNEC - - if (cmd == 43) - { -+ if (!s_check_rem(c->in_s, 4)) -+ { -+ log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: missing session", __LINE__); -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } - /* select session */ - in_uint32_be(c->in_s, (*sid)); - -diff --git a/sesman/libscp/libscp_v1s_mng.c b/sesman/libscp/libscp_v1s_mng.c -index 3a3e1d980870..8e9aed12b84f 100644 ---- a/sesman/libscp/libscp_v1s_mng.c -+++ b/sesman/libscp/libscp_v1s_mng.c -@@ -38,17 +38,79 @@ - static enum SCP_SERVER_STATES_E - _scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s); - --/* server API */ --enum SCP_SERVER_STATES_E --scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s) -+/** -+ * Reads a uint8 followed by a string into a buffer -+ * -+ * Buffer is null-terminated on success -+ * -+ * @param s Input stream -+ * @param [out] Output buffer (must be >= 256 chars) -+ * @param param Parameter we're reading -+ * @param line Line number reference -+ * @return != 0 if string read OK -+ * -+ * @todo -+ * This needs to be merged with the func of the same name in -+ * libscp_v1s.c -+ */ -+static -+int in_string8(struct stream *s, char str[], const char *param, int line) -+{ -+ int result; -+ -+ if (!s_check_rem(s, 1)) -+ { -+ log_message(LOG_LEVEL_WARNING, -+ "[v1s_mng:%d] connection aborted: %s len missing", -+ line, param); -+ result = 0; -+ } -+ else -+ { -+ unsigned int sz; -+ -+ in_uint8(s, sz); -+ result = s_check_rem(s, sz); -+ if (!result) -+ { -+ log_message(LOG_LEVEL_WARNING, -+ "[v1s_mng:%d] connection aborted: %s data missing", -+ line, param); -+ } -+ else -+ { -+ in_uint8a(s, str, sz); -+ str[sz] = '\0'; -+ } -+ } -+ return result; -+} -+/** -+ * Initialises a V1 management session object -+ * -+ * At call time, the command set value has been read from the wire, and -+ * the command still needs to be processed. -+ * -+ * @param c Connection -+ * @param [out] session pre-allocated session object -+ * @return SCP_SERVER_STATE_START_MANAGE for success -+ */ -+static enum SCP_SERVER_STATES_E -+scp_v1s_mng_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session) - { -- struct SCP_SESSION *session; - tui32 ipaddr; - tui16 cmd; - tui8 sz; -- char buf[257]; -+ char buf[256]; -+ -+ scp_session_set_version(session, 1); - - /* reading command */ -+ if (!s_check_rem(c->in_s, 2)) -+ { -+ /* Caller should have checked this */ -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } - in_uint16_be(c->in_s, cmd); - - if (cmd != 1) /* manager login */ -@@ -56,41 +118,39 @@ scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s) - return SCP_SERVER_STATE_SEQUENCE_ERR; - } - -- session = scp_session_create(); -- -- if (0 == session) -+ /* reading username */ -+ if (!in_string8(c->in_s, buf, "username", __LINE__)) - { -- return SCP_SERVER_STATE_INTERNAL_ERR; -+ return SCP_SERVER_STATE_SIZE_ERR; - } - -- scp_session_set_version(session, 1); -- scp_session_set_type(session, SCP_SESSION_TYPE_MANAGE); -- -- /* reading username */ -- in_uint8(c->in_s, sz); -- buf[sz] = '\0'; -- in_uint8a(c->in_s, buf, sz); -- - if (0 != scp_session_set_username(session, buf)) - { -- scp_session_destroy(session); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - /* reading password */ -- in_uint8(c->in_s, sz); -- buf[sz] = '\0'; -- in_uint8a(c->in_s, buf, sz); -+ if (!in_string8(c->in_s, buf, "passwd", __LINE__)) -+ { -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } - - if (0 != scp_session_set_password(session, buf)) - { -- scp_session_destroy(session); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - -- /* reading remote address */ -- in_uint8(c->in_s, sz); -+ /* reading remote address -+ * Check there's enough data left for at least an IPv4 address (+len) */ -+ if (!s_check_rem(c->in_s, 1 + 4)) -+ { -+ log_message(LOG_LEVEL_WARNING, -+ "[v1s_mng:%d] connection aborted: IP addr len missing", -+ __LINE__); -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } - -+ in_uint8(c->in_s, sz); - if (sz == SCP_ADDRESS_TYPE_IPV4) - { - in_uint32_be(c->in_s, ipaddr); -@@ -98,25 +158,57 @@ scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s) - } - else if (sz == SCP_ADDRESS_TYPE_IPV6) - { -+ if (!s_check_rem(c->in_s, 16)) -+ { -+ log_message(LOG_LEVEL_WARNING, -+ "[v1s_mng:%d] connection aborted: IP addr missing", -+ __LINE__); -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } - in_uint8a(c->in_s, buf, 16); - scp_session_set_addr(session, sz, buf); - } - - /* reading hostname */ -- in_uint8(c->in_s, sz); -- buf[sz] = '\0'; -- in_uint8a(c->in_s, buf, sz); -+ if (!in_string8(c->in_s, buf, "hostname", __LINE__)) -+ { -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } - - if (0 != scp_session_set_hostname(session, buf)) - { -- scp_session_destroy(session); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - -- /* returning the struct */ -+ return SCP_SERVER_STATE_START_MANAGE; -+} -+ -+enum SCP_SERVER_STATES_E -+scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s) -+{ -+ enum SCP_SERVER_STATES_E result; -+ struct SCP_SESSION *session; -+ -+ session = scp_session_create(); -+ if (NULL == session) -+ { -+ result = SCP_SERVER_STATE_INTERNAL_ERR; -+ } -+ else -+ { -+ scp_session_set_type(session, SCP_SESSION_TYPE_MANAGE); -+ -+ result = scp_v1s_mng_init_session(c, session); -+ if (result != SCP_SERVER_STATE_START_MANAGE) -+ { -+ scp_session_destroy(session); -+ session = NULL; -+ } -+ } -+ - (*s) = session; - -- return SCP_SERVER_STATE_START_MANAGE; -+ return result; - } - - /* 002 */ -@@ -312,7 +404,15 @@ _scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s) - - in_uint32_be(c->in_s, size); - -- init_stream(c->in_s, c->in_s->size); -+ /* Check the message is big enough for the header, the command set, and -+ * the command (but not too big) */ -+ if (size < (8 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE) -+ { -+ log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: size error", __LINE__); -+ return SCP_SERVER_STATE_SIZE_ERR; -+ } -+ -+ init_stream(c->in_s, size - 8); - - /* read the rest of the packet */ - if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) -@@ -321,6 +421,8 @@ _scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s) - return SCP_SERVER_STATE_NETWORK_ERR; - } - -+ c->in_s->end = c->in_s->data + (size - 8); -+ - in_uint16_be(c->in_s, cmd); - - if (cmd != SCP_COMMAND_SET_MANAGE) -diff --git a/sesman/scp.c b/sesman/scp.c -index d548052aeb39..7fa4d2a78b64 100644 ---- a/sesman/scp.c -+++ b/sesman/scp.c -@@ -48,8 +48,8 @@ scp_process_start(void *sck) - make_stream(scon.in_s); - make_stream(scon.out_s); - -- init_stream(scon.in_s, 8192); -- init_stream(scon.out_s, 8192); -+ init_stream(scon.in_s, SCP_MAX_MESSAGE_SIZE); -+ init_stream(scon.out_s, SCP_MAX_MESSAGE_SIZE); - - switch (scp_vXs_accept(&scon, &(sdata))) - { -@@ -76,10 +76,12 @@ scp_process_start(void *sck) - scp_v1_mng_process(&scon, sdata); - break; - case SCP_SERVER_STATE_VERSION_ERR: -- /* an unknown scp version was requested, so we shut down the */ -- /* connection (and log the fact) */ -+ case SCP_SERVER_STATE_SIZE_ERR: -+ /* an unknown scp version was requested, or the message sizes -+ are inconsistent. Shut down the connection and log the -+ fact */ - log_message(LOG_LEVEL_WARNING, -- "unknown protocol version specified. connection refused."); -+ "protocol violation. connection refused."); - break; - case SCP_SERVER_STATE_NETWORK_ERR: - log_message(LOG_LEVEL_WARNING, "libscp network error."); --- -2.28.0.rc0 - diff -Nru xrdp-0.9.12/debian/patches/known-arch-list.diff xrdp-0.9.15/debian/patches/known-arch-list.diff --- xrdp-0.9.12/debian/patches/known-arch-list.diff 1970-01-01 00:00:00.000000000 +0000 +++ xrdp-0.9.15/debian/patches/known-arch-list.diff 2021-09-29 17:29:28.000000000 +0000 @@ -0,0 +1,23 @@ +Description: fix build failure on ppc64el and s390x due to unknown arch + This package has failed to build on ppc64el and s390x because a previous + warning about "unknown arch" has now been promoted to an error. + Treat s390x and ppc64el as architectures that do not require alignment - + I am not certain this is correct for the code in question, but this was + the previous behavior and no one complained, so letting the package build + in this configuration without a warning is not a regression. +Author: Steve Langasek +Last-Update: 2021-09-29 + +Index: xrdp-0.9.15/common/arch.h +=================================================================== +--- xrdp-0.9.15.orig/common/arch.h ++++ xrdp-0.9.15/common/arch.h +@@ -85,7 +85,7 @@ + #elif defined(__x86__) || defined(__x86_64__) || \ + defined(__AMD64__) || defined(_M_IX86) || defined (_M_AMD64) || \ + defined(__i386__) || defined(__aarch64__) || \ +- defined(__riscv) ++ defined(__riscv) || defined(__powerpc64__) || defined(__s390x__) + #define NO_NEED_ALIGN + #else + #warning unknown arch diff -Nru xrdp-0.9.12/debian/patches/lfs.diff xrdp-0.9.15/debian/patches/lfs.diff --- xrdp-0.9.12/debian/patches/lfs.diff 2020-07-19 15:11:20.000000000 +0000 +++ xrdp-0.9.15/debian/patches/lfs.diff 2021-03-01 21:27:36.000000000 +0000 @@ -5,7 +5,7 @@ --- a/configure.ac +++ b/configure.ac -@@ -6,6 +6,8 @@ AC_CONFIG_HEADERS(config_ac.h:config_ac- +@@ -6,6 +6,8 @@ AM_INIT_AUTOMAKE([1.7.2 foreign]) AC_CONFIG_MACRO_DIR([m4]) AC_PROG_CC @@ -14,7 +14,7 @@ AC_C_CONST AC_PROG_LIBTOOL -@@ -375,6 +377,7 @@ AC_CONFIG_FILES([ +@@ -404,6 +406,7 @@ xup/Makefile ]) @@ -24,7 +24,7 @@ echo "" --- a/libpainter/configure.ac +++ b/libpainter/configure.ac -@@ -6,6 +6,8 @@ AC_CONFIG_HEADERS(config_ac.h:config_ac- +@@ -6,6 +6,8 @@ AM_INIT_AUTOMAKE([1.6 foreign]) AC_CONFIG_MACRO_DIR([m4]) AC_PROG_CC @@ -33,7 +33,7 @@ AC_C_CONST AC_PROG_LIBTOOL PKG_INSTALLDIR -@@ -31,4 +33,5 @@ AC_CONFIG_FILES([ +@@ -31,4 +33,5 @@ tests/Makefile ]) @@ -41,7 +41,7 @@ AC_OUTPUT --- a/librfxcodec/configure.ac +++ b/librfxcodec/configure.ac -@@ -7,6 +7,8 @@ AM_INIT_AUTOMAKE([1.6 foreign]) +@@ -7,6 +7,8 @@ AC_CONFIG_MACRO_DIR([m4]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) AC_PROG_CC @@ -50,7 +50,7 @@ AC_C_CONST AC_PROG_LIBTOOL PKG_INSTALLDIR -@@ -53,5 +55,6 @@ AC_CONFIG_FILES([Makefile +@@ -53,5 +55,6 @@ rfxcodec-uninstalled.pc ]) diff -Nru xrdp-0.9.12/debian/patches/pulse-debian.patch xrdp-0.9.15/debian/patches/pulse-debian.patch --- xrdp-0.9.12/debian/patches/pulse-debian.patch 2020-07-19 15:11:20.000000000 +0000 +++ xrdp-0.9.15/debian/patches/pulse-debian.patch 2021-03-01 21:26:39.000000000 +0000 @@ -1,6 +1,11 @@ From: Dominik George Subject: Use absolute path to PulseAudio modules - The modules are installed to their locations by the xrdp-build-pulse-modules script. + The modules are installed to their locations by the + xrdp-build-pulse-modules script from the former + xrdp-pulseaudio-installer package. The upstream + pulseaudio-module-xrdp/wiki/README instructions + install the module into the PA directory and do + not need this patch. --- a/instfiles/pulse/default.pa +++ b/instfiles/pulse/default.pa diff -Nru xrdp-0.9.12/debian/patches/series xrdp-0.9.15/debian/patches/series --- xrdp-0.9.12/debian/patches/series 2020-07-19 15:11:20.000000000 +0000 +++ xrdp-0.9.15/debian/patches/series 2021-09-29 17:13:22.000000000 +0000 @@ -7,5 +7,4 @@ pulse-debian.patch var-run.diff document-certs.diff -Fix-for-CVE-2020-4044.patch -Fixed-CVE-2020-4044-CI-errors.patch +known-arch-list.diff diff -Nru xrdp-0.9.12/debian/patches/shutup-daemon.diff xrdp-0.9.15/debian/patches/shutup-daemon.diff --- xrdp-0.9.12/debian/patches/shutup-daemon.diff 2020-07-19 15:11:20.000000000 +0000 +++ xrdp-0.9.15/debian/patches/shutup-daemon.diff 2021-03-01 21:27:36.000000000 +0000 @@ -1,23 +1,9 @@ From: Thorsten Glaser Subject: don’t spit on the console when starting ---- a/common/log.c -+++ b/common/log.c -@@ -382,11 +382,6 @@ internal_config_read_logging(int file, s - /* try to create path if not exist */ - g_create_path(lc->log_file); - -- g_printf("logging configuration:\r\n"); -- g_printf("\tLogFile: %s\r\n", lc->log_file); -- g_printf("\tLogLevel: %i\r\n", lc->log_level); -- g_printf("\tEnableSyslog: %i\r\n", lc->enable_syslog); -- g_printf("\tSyslogLevel: %i\r\n", lc->syslog_level); - return LOG_STARTUP_OK; - } - --- a/xrdp/xrdp.c +++ b/xrdp/xrdp.c -@@ -604,7 +604,6 @@ main(int argc, char **argv) +@@ -626,7 +626,6 @@ if (0 != pid) { diff -Nru xrdp-0.9.12/debian/README.Debian xrdp-0.9.15/debian/README.Debian --- xrdp-0.9.12/debian/README.Debian 2020-07-19 15:11:20.000000000 +0000 +++ xrdp-0.9.15/debian/README.Debian 2021-03-01 21:26:39.000000000 +0000 @@ -18,11 +18,9 @@ The PulseAudio module can currently not be packaged correctly due to a lack of headers in Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=794692 -You can install the xrdp-pulseaudio-installer package, which pulls in all -the build dependencies and contains a script that downloads the PulseAudio -source, builds the modules and installs them locally. - -After installing the package, run xrdp-build-pulse-modules as root. +https://github.com/neutrinolabs/pulseaudio-module-xrdp/wiki/README +contains upstream-provided information of how to enable audio redirection; +you’ll also have to install the libpulse-dev package, as prerequisite. xrdpvr ------ diff -Nru xrdp-0.9.12/debian/startwm.sh xrdp-0.9.15/debian/startwm.sh --- xrdp-0.9.12/debian/startwm.sh 2020-07-19 15:11:20.000000000 +0000 +++ xrdp-0.9.15/debian/startwm.sh 2021-03-01 21:26:39.000000000 +0000 @@ -2,10 +2,6 @@ # xrdp X session start script (c) 2015, 2017 mirabilos # published under The MirOS Licence -if test -r /etc/profile; then - . /etc/profile -fi - if test -r /etc/default/locale; then . /etc/default/locale test -z "${LANG+x}" || export LANG diff -Nru xrdp-0.9.12/debian/xrdp.lintian-overrides xrdp-0.9.15/debian/xrdp.lintian-overrides --- xrdp-0.9.12/debian/xrdp.lintian-overrides 2020-07-19 15:11:20.000000000 +0000 +++ xrdp-0.9.15/debian/xrdp.lintian-overrides 2021-03-01 21:27:36.000000000 +0000 @@ -1,5 +1,4 @@ # debhelper-generated -xrdp: postinst-has-useless-call-to-ldconfig xrdp: package-has-unnecessary-activation-of-ldconfig-trigger # this is a dlopen()'ed plugin diff -Nru xrdp-0.9.12/depcomp xrdp-0.9.15/depcomp --- xrdp-0.9.12/depcomp 2019-12-28 12:36:38.000000000 +0000 +++ xrdp-0.9.15/depcomp 2020-12-28 14:06:39.000000000 +0000 @@ -3,7 +3,7 @@ scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff -Nru xrdp-0.9.12/docs/Makefile.in xrdp-0.9.15/docs/Makefile.in --- xrdp-0.9.12/docs/Makefile.in 2019-12-28 12:36:37.000000000 +0000 +++ xrdp-0.9.15/docs/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/docs/man/Makefile.in xrdp-0.9.15/docs/man/Makefile.in --- xrdp-0.9.12/docs/man/Makefile.in 2019-12-28 12:36:37.000000000 +0000 +++ xrdp-0.9.15/docs/man/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/docs/man/sesman.ini.5.in xrdp-0.9.15/docs/man/sesman.ini.5.in --- xrdp-0.9.12/docs/man/sesman.ini.5.in 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/docs/man/sesman.ini.5.in 2020-12-28 14:03:43.000000000 +0000 @@ -33,6 +33,10 @@ Settings for xrdp-chansrv(8) .TP +\fB[ChansrvLogging]\fR +Logging settings for xrdp-chansrv(8) + +.TP \fB[SessionVariables]\fR Environment variables for the session @@ -81,12 +85,15 @@ \fI@xrdpconfdir@/reconnectwm.sh\fR. .SH "LOGGING" -Following parameters can be used in the \fB[Logging]\fR section. +Following parameters can be used in the \fB[Logging]\fR and \fB[ChansrvLogging]\fR +sections. .TP \fBLogFile\fR=\fIfilename\fR Log file path. It can be either absolute or relative. If not specified, -defaults to \fI./sesman.log\fR +defaults to \fI./sesman.log\fR It is ignored in the [ChansrvLogging] section +since the channel server creates one log file per display and instead uses the +following log file naming convention \fIxrdp-chansrv.${DISPLAY}.log\fR .TP \fBLogLevel\fR=\fIlevel\fR @@ -112,8 +119,22 @@ .TP \fBSyslogLevel\fR=\fIlevel\fR Logging level for syslog. It can have the same values as \fBLogLevel\fR. -If \fBSyslogLevel\fR and \fBLogLevel\fR differ, the least verbose setting -takes effect for syslog. +Defaults to \fBDEBUG\fR. + +.TP +\fBEnableConsole\fR=\fI[true|false]\fR +If set to \fB1\fR, \fBtrue\fR or \fByes\fR, this option enables logging to +the console (ie. stdout). + +.TP +\fBConsoleLevel\fR=\fIlevel\fR +Logging level for the console. It can have the same values as \fBLogLevel\fR. +Defaults to \fBDEBUG\fR. + +.TP +\fBEnableProcessId\fR=\fI[true|false]\fR +If set to \fB1\fR, \fBtrue\fR or \fByes\fR, this option enables logging the +process id in all log messages. Defaults to \fBfalse\fR. .SH "SESSIONS" Following parameters can be used in the \fB[Sessions]\fR section. @@ -132,29 +153,31 @@ .TP \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. +within \fBDisconnectedTimeLimit\fR 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 are to be overridden with 60. +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 when using Xrdp, and -for the combination 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 +.br \fBUBD\fR - session per .br \fBUBI\fR - session per @@ -168,7 +191,8 @@ .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" @@ -222,8 +246,27 @@ .TP \fBFuseMountName\fR=\fIstring\fR -Directory for drive redirection, relative to the user home directory. +Directory for drive redirection. Created if it doesn't exist. If not specified, defaults to \fIxrdp_client\fR. +If first character is not a '/', this is relative to $HOME. +.P +.RS +If first character is a '/' this is an absolute path. The following +substitutions are made in this string:- + %U - Username + %u - Numeric UID + %% - Percent character +.P +If this format is used:- +.HP 3 +1) The directory path permissions MUST be configured correctly by +the system administrator or the system itself - xrdp-chansrv will not +do this for you (although it will create the final directories owned by +the user). +.HP 3 +2) The desktop may not automatically display a link for the redirected +drive. To fix this, consult the docs for your chosen desktop. +.RE .TP \fBFileUmask\fR=\fImode\fR @@ -233,6 +276,21 @@ environents, and so you can change this value to allow other users to access your remote files if required. +.TP +\fBEnableFuseMount\fR=\fI[true|false]\fR +Defaults to \fItrue\fR. +Set to \fIfalse\fR to disable xrdp-chansrv's use of the FUSE system +feature, even if it has been built with this feature enabled. +.P +.RS +Setting this value to \fIfalse\fR will disable the following application +features:- +.P +- drive redirection +.P +- copying-and-pasting of files +.RE + .SH "SESSIONS VARIABLES" All entries in the \fB[SessionVariables]\fR section are set as environment variables in the user's session. diff -Nru xrdp-0.9.12/docs/man/xrdp.8.in xrdp-0.9.15/docs/man/xrdp.8.in --- xrdp-0.9.12/docs/man/xrdp.8.in 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/docs/man/xrdp.8.in 2020-12-28 14:03:43.000000000 +0000 @@ -3,7 +3,17 @@ \fBxrdp\fR \- a Remote Desktop Protocol (RDP) server .SH "SYNTAX" -xrdp [ \-\-nodaemon | \-\-kill | \-\-help ] +.B xrdp +\-\-kill +.br +.B xrdp +\-\-help +.br +.B xrdp +\-\-version +.br +.B xrdp +[ \-\-nodaemon ] [ --port port ] [ --fork ] [ --config /path/to/xrdp.ini ] .SH "DESCRIPTION" \fBxrdp\fR is a Remote Desktop Protocol (RDP) Server. @@ -14,15 +24,18 @@ .SH "OPTIONS" .TP -\fB\-n\fR, \fB\-\-nodaemon\fR -Start \fBxrdp\fR in foreground instead of starting it as a daemon. -.TP \fB\-k\fR, \fB\-\-kill\fR Kill running \fBxrdp\fR daemon. .TP \fB\-h\fR, \fB\-\-help\fR Output help information and exit. .TP +\fB\-v\fR, \fB\-\-version\fR +Output version information and exit. +.TP +\fB\-n\fR, \fB\-\-nodaemon\fR +Start \fBxrdp\fR in foreground instead of starting it as a daemon. +.TP \fB\-p\fR, \fB\-\-port\fR Specify TCP port to listen to. This overrides \fIport\fR setting in \fIxrdp.ini\fR file. @@ -31,6 +44,11 @@ Fork a new process on a new connection. If not enabled, use a new thread for every connection. This overrides \fIfork\fR setting in \fIxrdp.ini\fR file. +.TP +\fB\-c\fR, \fB\-\-config\fR +Specify a path to a different \fIxrdp.ini\fR file. This option is intended +to be used primarily for testing or for unusual configurations. + .SH "FILES" @bindir@/xrdp diff -Nru xrdp-0.9.12/docs/man/xrdp-chansrv.8.in xrdp-0.9.15/docs/man/xrdp-chansrv.8.in --- xrdp-0.9.12/docs/man/xrdp-chansrv.8.in 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/docs/man/xrdp-chansrv.8.in 2020-12-28 14:03:43.000000000 +0000 @@ -7,10 +7,11 @@ .SH "DESCRIPTION" \fBxrdp\-chansrv\fR is the \fBxrdp\fR(8) channel server, which manages the Remote Desktop Protocol (RDP) sub-channels. +.PP This program is only forked internally by \fBxrdp\-sesman\fP(8). -.br +.PP Currently \fBxrdp\-chansrv\fP knows about the following channels: -.RE 8 +.RS 8 .TP .B cliprdr Clipboard Redirection @@ -26,18 +27,31 @@ .TP .B drdynvc Dynamic Virtual Channel -.RS +.RE + +.SH ENVIRONMENT +.TP +.I CHANSRV_LOG_PATH +Path to the location where the log file is stored. If not specified, +$\fBXDG_DATA_HOME/xrdp\fP or \fB$HOME/.local/share/xrdp\fP is used instead. +.TP +.I DISPLAY +X11 display number. Must be specified. .SH FILES .TP +.I @sysconfdir@/xrdp/sesman.ini +Contains some settings for this program. +.TP .I @socketdir@/xrdp_chansrv_socket_* UNIX socket used by external programs to implement channels. .TP .I @socketdir@/xrdp_api_* UNIX socket used by \fBxrdp\-chansrv\fP to communicate with \fBxrdp\-sesman\fP. .TP -.I $XDG_DATA_HOME/xrdp/xrdp-chansrv.%s.log -Log file used by \fBxrdp\-chansrv\fP(8). \fB%s\fP is display number. +.I xrdp-chansrv.%s.log +Log file used by \fBxrdp\-chansrv\fP(8). \fB%s\fP is display number. See the +description of \fBCHANSRV_LOG_PATH\fP above for the file's location. .SH "SEE ALSO" .BR xrdp\-sesman (8), diff -Nru xrdp-0.9.12/docs/man/xrdp-dis.1.in xrdp-0.9.15/docs/man/xrdp-dis.1.in --- xrdp-0.9.12/docs/man/xrdp-dis.1.in 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/docs/man/xrdp-dis.1.in 2020-12-28 13:47:11.000000000 +0000 @@ -17,11 +17,11 @@ .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). diff -Nru xrdp-0.9.12/docs/man/xrdp.ini.5.in xrdp-0.9.15/docs/man/xrdp.ini.5.in --- xrdp-0.9.12/docs/man/xrdp.ini.5.in 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/docs/man/xrdp.ini.5.in 2020-12-28 14:03:43.000000000 +0000 @@ -24,10 +24,6 @@ The options to be specified in the \fB[Globals]\fR section are the following: .TP -\fBaddress\fP=\fIip address\fP -Specify xrdp listening address. If not specified, defaults to 0.0.0.0 (all interfaces). - -.TP \fBautorun\fP=\fIsession_name\fP Section name for automatic login. If set and the client supplies valid username and password, the user will be logged in automatically using the @@ -115,11 +111,26 @@ .TP \fBport\fP=\fIport\fP -Specify TCP port to listen on for incoming connections. -The default for RDP is \fB3389\fP. +Specify TCP port and interface to listen on for incoming connections. +Specifying only the port means that xrdp will listen on all interfaces. +The default port for RDP is \fB3389\fP. +Multiple address:port instances must be separated by spaces or commas. Check the .ini file for examples. +Specifying interfaces requires said interfaces to be UP before xrdp starts. .TP \fBrequire_credentials\fP=\fI[true|false]\fP +If set to \fB1\fP, \fBtrue\fP or \fByes\fP, \fBxrdp\fP will scan the user name provided by the +client for the ASCII field separator character (0x1F). It will then copy over what is after the +separator as the password supplied by the user and treats it as autologon. If not specified, +defaults to \fBfalse\fP. + +.TP +\domain_user_separator\fP=\separator\fP +If specified the domain name supplied by the client is appended to the username separated +by \fBseparator\fP. + +.TP +\enable_token_login\fP=\fI[true|false]\fP If set to \fB1\fP, \fBtrue\fP or \fByes\fP, \fBxrdp\fP requires clients to include username and password initial connection phase. In other words, xrdp doesn't allow clients to show login screen if set to true. If not specified, defaults to \fBfalse\fP. @@ -231,6 +242,18 @@ \fBSyslogLevel\fR=\fIlevel\fR This option sets the logging level for syslog. It can have the same values of \fBLogLevel\fR. If \fBSyslogLevel\fR is greater than \fBLogLevel\fR, its value is lowered to that of \fBLogLevel\fR. +.TP +\fBEnableConsole\fR=\fI[true|false]\fR +If set to \fB1\fR, \fBtrue\fR or \fByes\fR, this option enables logging to the console (ie. stdout). + +.TP +\fBConsoleLevel\fR=\fIlevel\fR +Logging level for the console. It can have the same values as \fBLogLevel\fR. Defaults to \fBDEBUG\fR. + +.TP +\fBEnableProcessId\fR=\fI[true|false]\fR +If set to \fB1\fR, \fBtrue\fR or \fByes\fR, this option enables logging the process id in all log messages. Defaults to \fBfalse\fR. + .SH "CHANNELS" The Remote Desktop Protocol supports several channels, which are used to transfer additional data like sound, clipboard data and others. Channel names not listed here will be blocked by \fBxrdp\fP. @@ -303,6 +326,14 @@ \fI24\fR bpp. .TP +\fBdisabled_encodings_mask\fR=\fI\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\fR|\fI0\fR Specifies the session type. The default, \fI0\fR, is Xvnc, \fI10\fR is X11rdp, and \fI20\fR is Xorg with xorgxrdp modules. diff -Nru xrdp-0.9.12/docs/man/xrdp-sesman.8.in xrdp-0.9.15/docs/man/xrdp-sesman.8.in --- xrdp-0.9.12/docs/man/xrdp-sesman.8.in 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/docs/man/xrdp-sesman.8.in 2020-12-28 14:03:43.000000000 +0000 @@ -4,7 +4,16 @@ .SH "SYNTAX" .B xrdp\-sesman -.RB [ \-\-nodaemon | \-\-kill | \-\-help ] +\-\-kill +.br +.B xrdp\-sesman +\-\-help +.br +.B xrdp\-sesman +\-\-version +.br +.B xrdp\-sesman +[ \-\-nodaemon ] [ --config /path/to/sesman.ini ] .SH "DESCRIPTION" \fBxrdp\-sesman\fR is \fBxrdp\fR(8) session manager. @@ -13,15 +22,28 @@ .SH "OPTIONS" .TP -\fB\-n\fR, \fB\-\-nodaemon\fR -Starts \fBxrdp\-sesman\fR in foreground instead of starting it as a daemon. -.TP \fB\-k\fR, \fB\-\-kill\fR Kills running \fBxrdp\-sesman\fR daemon. .TP \fB\-h\fR, \fB\-\-help\fR Output help information and exit. - +.TP +\fB\-v\fR, \fB\-\-version\fR +Output version information and exit. +.TP +\fB\-n\fR, \fB\-\-nodaemon\fR +Starts \fBxrdp\-sesman\fR in foreground instead of starting it as a daemon. +.TP +\fB\-c\fR, \fB\-\-config\fR +Specify a path to a different \fIsesman.ini\fR file. This option is intended +to be used primarily for testing or for unusual configurations. +.P +.RS +If you use this option, be aware that you will have to have a +\fB@sysconfdir@/xrdp/sesman.ini\fR in place too, as a few elements of +the system (notably \fBxrdp(8)\fR and \fBxrdp\-chansrv(8)\fR) will want +to read it. +.RE .SH "FILES" @bindir@/xrdp\-sesman .br diff -Nru xrdp-0.9.12/docs/man/xrdp-sesrun.8.in xrdp-0.9.15/docs/man/xrdp-sesrun.8.in --- xrdp-0.9.12/docs/man/xrdp-sesrun.8.in 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/docs/man/xrdp-sesrun.8.in 2020-12-28 14:03:43.000000000 +0000 @@ -1,40 +1,87 @@ .TH "xrdp\-sesrun" "8" "@PACKAGE_VERSION@" "xrdp team" "" .SH "NAME" -xrdp\-sesrun \- \fBsesman\fR(8) session launcher +\fBxrdp\-sesrun\fR \- \fBxrdp\-sesman\fR(8) session launcher .SH "SYNTAX" .B xrdp\-sesrun -.I server username password width height bpp +.I [ options ] username .SH "DESCRIPTION" \fBxrdp\-sesrun\fR starts a session using \fBxrdp\-sesman\fR(8). .br -This is a tool useful for testing, it simply behaves like xrdp when some user logs in a new session and authenticates, thus starting a new session. +This is a tool useful for testing, it simply behaves like xrdp when some +user logs in a new session and authenticates, thus starting a new session. + +Default values for the options are set at compile-time. Run the utility without +a username to see what the defaults are for your installation. + +The utility prompts for a password if neither \fB-p\fR or \fB-F\fR is used. .SH "OPTIONS" .TP -.I server -Server on which sesman is running +.B -g x +Set session geometry. +.br +Note that most configurations will resize the session on connection, so this +option may not do what you expect. +.TP +.B -b +Set session bits-per-pixel (colour depth). Some session types (i.e. Xorg) +will ignore this setting. +.TP +.B -s +Server on which sesman is running (probably 'localhost'). +.br +Use of this option is discouraged as it will be removed in the future. +.TP +.B -t +Session type - one of Xorg, Xvnc or X11rdp. Alternatively, for testing +only, use the numeric session code. +.TP +.B -D +Directory to run the new session in. Defaults to $HOME for the specified user. +.TP +.B -S +Specify an alternate shell to run, instead of the default window manager. .TP -.I username -user name of the session being started +.B -p +Password for user. USE FOR TESTING ONLY - the password will be visible +in the output of the \fBps\fR command. .TP -.I password -user password +.B -F +Specify a file descriptor (normally 0) to read the password in from. This +is a secure way to pass the password in to the utility. .TP -.I width -Screen width +.B -c +Specify a different sesman.ini file. This file is used to find out how to +connect to \fBxrdp\-sesman\fR. + +.SH "ENVIRONMENT" .TP -.I height -Screen height +.I SESRUN_LOG_LEVEL +Override the default logging level. One of "error", "warn", "info", +"debug", "trace" or a number 1-5. + +.SH "EXAMPLES" .TP -.I bpp -Session color depth +.B +xrdp-sesrun -F 0 user1 diff -Nru xrdp-0.9.12/faq-compile.txt xrdp-0.9.15/faq-compile.txt --- xrdp-0.9.12/faq-compile.txt 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/faq-compile.txt 2020-12-28 13:47:11.000000000 +0000 @@ -32,3 +32,25 @@ 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. diff -Nru xrdp-0.9.12/genkeymap/dump-keymaps.sh xrdp-0.9.15/genkeymap/dump-keymaps.sh --- xrdp-0.9.12/genkeymap/dump-keymaps.sh 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/genkeymap/dump-keymaps.sh 2020-12-28 13:47:12.000000000 +0000 @@ -15,6 +15,12 @@ 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 diff -Nru xrdp-0.9.12/genkeymap/genkeymap.c xrdp-0.9.15/genkeymap/genkeymap.c --- xrdp-0.9.12/genkeymap/genkeymap.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/genkeymap/genkeymap.c 2020-12-28 14:03:43.000000000 +0000 @@ -44,7 +44,7 @@ #include #include -extern int xfree86_to_evdev[137-8]; +extern int xfree86_to_evdev[137-8+1]; int main(int argc, char **argv) { @@ -136,7 +136,7 @@ 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]; diff -Nru xrdp-0.9.12/genkeymap/Makefile.in xrdp-0.9.15/genkeymap/Makefile.in --- xrdp-0.9.12/genkeymap/Makefile.in 2019-12-28 12:36:37.000000000 +0000 +++ xrdp-0.9.15/genkeymap/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/install-sh xrdp-0.9.15/install-sh --- xrdp-0.9.12/install-sh 2019-12-28 12:36:37.000000000 +0000 +++ xrdp-0.9.15/install-sh 2020-12-28 14:06:38.000000000 +0000 @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2018-03-11.20; # UTC +scriptversion=2020-11-14.01; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -69,6 +69,11 @@ # Desired mode of installed file. mode=0755 +# Create dirs (including intermediate dirs) using mode 755. +# This is like GNU 'install' as of coreutils 8.32 (2020). +mkdir_umask=22 + +backupsuffix= chgrpcmd= chmodcmd=$chmodprog chowncmd= @@ -99,18 +104,28 @@ --version display version info and exit. -c (ignored) - -C install only if different (preserve the last data modification time) + -C install only if different (preserve data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. + -p pass -p to $cpprog. -s $stripprog installed files. + -S SUFFIX attempt to back up existing files, with suffix SUFFIX. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG + +By default, rm is invoked with -f; when overridden with RMPROG, +it's up to you to specify -f if you want it. + +If -S is not specified, no backups are attempted. + +Email bug reports to bug-automake@gnu.org. +Automake home page: https://www.gnu.org/software/automake/ " while test $# -ne 0; do @@ -137,8 +152,13 @@ -o) chowncmd="$chownprog $2" shift;; + -p) cpprog="$cpprog -p";; + -s) stripcmd=$stripprog;; + -S) backupsuffix="$2" + shift;; + -t) is_target_a_directory=always dst_arg=$2 @@ -255,6 +275,10 @@ dstdir=$dst test -d "$dstdir" dstdir_status=$? + # Don't chown directories that already exist. + if test $dstdir_status = 0; then + chowncmd="" + fi else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command @@ -301,22 +325,6 @@ if test $dstdir_status != 0; then case $posix_mkdir in '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then @@ -326,52 +334,49 @@ fi posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - # Note that $RANDOM variable is not portable (e.g. dash); Use it - # here however when possible just to lower collision chance. - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - - trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 - - # Because "mkdir -p" follows existing symlinks and we likely work - # directly in world-writeable /tmp, make sure that the '$tmpdir' - # directory is successfully created first before we actually test - # 'mkdir -p' feature. - if (umask $mkdir_umask && - $mkdirprog $mkdir_mode "$tmpdir" && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - test_tmpdir="$tmpdir/a" - ls_ld_tmpdir=`ls -ld "$test_tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null - fi - trap '' 0;; - esac;; + # The $RANDOM variable is not portable (e.g., dash). Use it + # here however when possible just to lower collision chance. + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + + trap ' + ret=$? + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null + exit $ret + ' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p'. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; esac if @@ -382,7 +387,7 @@ then : else - # The umask is ridiculous, or mkdir does not conform to POSIX, + # mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. @@ -411,7 +416,7 @@ prefixes= else if $posix_mkdir; then - (umask=$mkdir_umask && + (umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 @@ -451,7 +456,18 @@ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + (umask $cp_umask && + { test -z "$stripcmd" || { + # Create $dsttmp read-write so that cp doesn't create it read-only, + # which would cause strip to fail. + if test -z "$doit"; then + : >"$dsttmp" # No need to fork-exec 'touch'. + else + $doit touch "$dsttmp" + fi + } + } && + $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # @@ -477,6 +493,13 @@ then rm -f "$dsttmp" else + # If $backupsuffix is set, and the file being installed + # already exists, attempt a backup. Don't worry if it fails, + # e.g., if mv doesn't support -f. + if test -n "$backupsuffix" && test -f "$dst"; then + $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null + fi + # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || @@ -491,9 +514,9 @@ # file should still install successfully. { test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || + $doit $rmcmd "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 diff -Nru xrdp-0.9.12/instfiles/default/Makefile.in xrdp-0.9.15/instfiles/default/Makefile.in --- xrdp-0.9.12/instfiles/default/Makefile.in 2019-12-28 12:36:37.000000000 +0000 +++ xrdp-0.9.15/instfiles/default/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/instfiles/init.d/Makefile.in xrdp-0.9.15/instfiles/init.d/Makefile.in --- xrdp-0.9.12/instfiles/init.d/Makefile.in 2019-12-28 12:36:37.000000000 +0000 +++ xrdp-0.9.15/instfiles/init.d/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/instfiles/km-19360409.ini xrdp-0.9.15/instfiles/km-19360409.ini --- xrdp-0.9.12/instfiles/km-19360409.ini 1970-01-01 00:00:00.000000000 +0000 +++ xrdp-0.9.15/instfiles/km-19360409.ini 2020-12-28 13:47:12.000000000 +0000 @@ -0,0 +1,1047 @@ +[noshift] +Key8=65406:0 +Key9=65307:27 +Key10=38:38 +Key11=91:91 +Key12=123:123 +Key13=125:125 +Key14=40:40 +Key15=61:61 +Key16=42:42 +Key17=41:41 +Key18=43:43 +Key19=93:93 +Key20=33:33 +Key21=35:35 +Key22=65288:8 +Key23=65289:9 +Key24=59:59 +Key25=44:44 +Key26=46:46 +Key27=112:112 +Key28=121:121 +Key29=102:102 +Key30=103:103 +Key31=99:99 +Key32=114:114 +Key33=108:108 +Key34=47:47 +Key35=64:64 +Key36=65293:13 +Key37=65507:0 +Key38=97:97 +Key39=111:111 +Key40=101:101 +Key41=117:117 +Key42=105:105 +Key43=100:100 +Key44=104:104 +Key45=116:116 +Key46=110:110 +Key47=115:115 +Key48=45:45 +Key49=36:36 +Key50=65505:0 +Key51=92:92 +Key52=39:39 +Key53=113:113 +Key54=106:106 +Key55=107:107 +Key56=120:120 +Key57=98:98 +Key58=109:109 +Key59=119:119 +Key60=118:118 +Key61=122:122 +Key62=65506:0 +Key63=65450:42 +Key64=65513:0 +Key65=32:32 +Key66=65509:0 +Key67=65470:0 +Key68=65471:0 +Key69=65472:0 +Key70=65473:0 +Key71=65474:0 +Key72=65475:0 +Key73=65476:0 +Key74=65477:0 +Key75=65478:0 +Key76=65479:0 +Key77=65407:0 +Key78=65300:0 +Key79=65429:0 +Key80=65431:0 +Key81=65434:0 +Key82=65453:45 +Key83=65430:0 +Key84=65437:0 +Key85=65432:0 +Key86=65451:43 +Key87=65436:0 +Key88=65433:0 +Key89=65435:0 +Key90=65438:0 +Key91=65439:0 +Key92=0:0 +Key93=0:0 +Key94=65312:0 +Key95=65480:0 +Key96=65481:0 +Key97=65360:0 +Key98=65362:0 +Key99=65365:0 +Key100=65361:0 +Key101=0:0 +Key102=65363:0 +Key103=65367:0 +Key104=65364:0 +Key105=65366:0 +Key106=65379:0 +Key107=65535:127 +Key108=65421:13 +Key109=65508:0 +Key110=65299:0 +Key111=65377:0 +Key112=65455:47 +Key113=65514:0 +Key114=0:0 +Key115=65515:0 +Key116=65516:0 +Key117=65383:0 +Key118=0:0 +Key119=0:0 +Key120=0:0 +Key121=0:0 +Key122=0:0 +Key123=0:0 +Key124=65027:0 +Key125=0:0 +Key126=65469:61 +Key127=0:0 +Key128=0:0 +Key129=0:0 +Key130=0:0 +Key131=0:0 +Key132=0:0 +Key133=0:0 +Key134=65454:46 +Key135=0:0 +Key136=0:0 + +[shift] +Key8=65406:0 +Key9=65307:27 +Key10=37:37 +Key11=55:55 +Key12=53:53 +Key13=51:51 +Key14=49:49 +Key15=57:57 +Key16=48:48 +Key17=50:50 +Key18=52:52 +Key19=54:54 +Key20=56:56 +Key21=96:96 +Key22=65288:8 +Key23=65056:0 +Key24=58:58 +Key25=60:60 +Key26=62:62 +Key27=80:80 +Key28=89:89 +Key29=70:70 +Key30=71:71 +Key31=67:67 +Key32=82:82 +Key33=76:76 +Key34=63:63 +Key35=94:94 +Key36=65293:13 +Key37=65507:0 +Key38=65:65 +Key39=79:79 +Key40=69:69 +Key41=85:85 +Key42=73:73 +Key43=68:68 +Key44=72:72 +Key45=84:84 +Key46=78:78 +Key47=83:83 +Key48=95:95 +Key49=126:126 +Key50=65505:0 +Key51=124:124 +Key52=34:34 +Key53=81:81 +Key54=74:74 +Key55=75:75 +Key56=88:88 +Key57=66:66 +Key58=77:77 +Key59=87:87 +Key60=86:86 +Key61=90:90 +Key62=65506:0 +Key63=65450:42 +Key64=65511:0 +Key65=32:32 +Key66=65509:0 +Key67=65470:0 +Key68=65471:0 +Key69=65472:0 +Key70=65473:0 +Key71=65474:0 +Key72=65475:0 +Key73=65476:0 +Key74=65477:0 +Key75=65478:0 +Key76=65479:0 +Key77=65407:0 +Key78=65300:0 +Key79=65429:0 +Key80=65431:0 +Key81=65434:0 +Key82=65453:45 +Key83=65430:0 +Key84=65437:0 +Key85=65432:0 +Key86=65451:43 +Key87=65436:0 +Key88=65433:0 +Key89=65435:0 +Key90=65438:0 +Key91=65439:0 +Key92=0:0 +Key93=0:0 +Key94=65312:0 +Key95=65480:0 +Key96=65481:0 +Key97=65360:0 +Key98=65362:0 +Key99=65365:0 +Key100=65361:0 +Key101=0:0 +Key102=65363:0 +Key103=65367:0 +Key104=65364:0 +Key105=65366:0 +Key106=65379:0 +Key107=65535:127 +Key108=65421:13 +Key109=65508:0 +Key110=65299:0 +Key111=65377:0 +Key112=65455:47 +Key113=65512:0 +Key114=0:0 +Key115=65515:0 +Key116=65516:0 +Key117=65383:0 +Key118=0:0 +Key119=0:0 +Key120=0:0 +Key121=0:0 +Key122=0:0 +Key123=0:0 +Key124=65027:0 +Key125=65513:0 +Key126=61:61 +Key127=65515:0 +Key128=65517:0 +Key129=0:0 +Key130=0:0 +Key131=0:0 +Key132=0:0 +Key133=0:0 +Key134=65454:46 +Key135=0:0 +Key136=0:0 + +[altgr] +Key8=65406:0 +Key9=65307:27 +Key10=38:38 +Key11=164:164 +Key12=162:162 +Key13=165:165 +Key14=8364:8364 +Key15=163:163 +Key16=0:0 +Key17=189:189 +Key18=65104:96 +Key19=0:0 +Key20=161:161 +Key21=65104:96 +Key22=65288:8 +Key23=65289:9 +Key24=65111:168 +Key25=171:171 +Key26=187:187 +Key27=182:182 +Key28=252:252 +Key29=102:102 +Key30=103:103 +Key31=231:231 +Key32=174:174 +Key33=108:108 +Key34=191:191 +Key35=65106:94 +Key36=65293:13 +Key37=65507:0 +Key38=229:229 +Key39=248:248 +Key40=230:230 +Key41=233:233 +Key42=105:105 +Key43=240:240 +Key44=65105:180 +Key45=254:254 +Key46=241:241 +Key47=223:223 +Key48=173:173 +Key49=65107:126 +Key50=65505:0 +Key51=92:92 +Key52=65105:180 +Key53=113:113 +Key54=106:106 +Key55=107:107 +Key56=120:120 +Key57=98:98 +Key58=109:109 +Key59=119:119 +Key60=118:118 +Key61=122:122 +Key62=65506:0 +Key63=65450:42 +Key64=65513:0 +Key65=32:32 +Key66=65509:0 +Key67=65470:0 +Key68=65471:0 +Key69=65472:0 +Key70=65473:0 +Key71=65474:0 +Key72=65475:0 +Key73=65476:0 +Key74=65477:0 +Key75=65478:0 +Key76=65479:0 +Key77=65407:0 +Key78=65300:0 +Key79=65429:0 +Key80=65431:0 +Key81=65434:0 +Key82=65453:45 +Key83=65430:0 +Key84=65437:0 +Key85=65432:0 +Key86=65451:43 +Key87=65436:0 +Key88=65433:0 +Key89=65435:0 +Key90=65438:0 +Key91=65439:0 +Key92=0:0 +Key93=0:0 +Key94=65312:0 +Key95=65480:0 +Key96=65481:0 +Key97=65360:0 +Key98=65362:0 +Key99=65365:0 +Key100=65361:0 +Key101=0:0 +Key102=65363:0 +Key103=65367:0 +Key104=65364:0 +Key105=65366:0 +Key106=65379:0 +Key107=65535:127 +Key108=65421:13 +Key109=65508:0 +Key110=65299:0 +Key111=65377:0 +Key112=65455:47 +Key113=65514:0 +Key114=0:0 +Key115=65515:0 +Key116=65516:0 +Key117=65383:0 +Key118=0:0 +Key119=0:0 +Key120=0:0 +Key121=0:0 +Key122=0:0 +Key123=0:0 +Key124=65027:0 +Key125=0:0 +Key126=65469:61 +Key127=0:0 +Key128=0:0 +Key129=0:0 +Key130=0:0 +Key131=0:0 +Key132=0:0 +Key133=0:0 +Key134=65454:46 +Key135=0:0 +Key136=0:0 + +[shiftaltgr] +Key8=65406:0 +Key9=65307:27 +Key10=37:37 +Key11=0:0 +Key12=0:0 +Key13=0:0 +Key14=0:0 +Key15=65106:94 +Key16=0:0 +Key17=0:0 +Key18=0:0 +Key19=0:0 +Key20=16789016:11800 +Key21=0:0 +Key22=65288:8 +Key23=65056:0 +Key24=65111:168 +Key25=16785436:8220 +Key26=16785437:8221 +Key27=167:167 +Key28=220:220 +Key29=70:70 +Key30=71:71 +Key31=199:199 +Key32=2761:8482 +Key33=76:76 +Key34=16785469:8253 +Key35=65114:711 +Key36=65293:13 +Key37=65507:0 +Key38=197:197 +Key39=216:216 +Key40=198:198 +Key41=201:201 +Key42=73:73 +Key43=208:208 +Key44=0:0 +Key45=222:222 +Key46=209:209 +Key47=0:0 +Key48=2730:8211 +Key49=65107:126 +Key50=65505:0 +Key51=124:124 +Key52=65113:733 +Key53=81:81 +Key54=74:74 +Key55=75:75 +Key56=88:88 +Key57=66:66 +Key58=77:77 +Key59=87:87 +Key60=86:86 +Key61=90:90 +Key62=65506:0 +Key63=65450:42 +Key64=65511:0 +Key65=32:32 +Key66=65509:0 +Key67=65470:0 +Key68=65471:0 +Key69=65472:0 +Key70=65473:0 +Key71=65474:0 +Key72=65475:0 +Key73=65476:0 +Key74=65477:0 +Key75=65478:0 +Key76=65479:0 +Key77=65407:0 +Key78=65300:0 +Key79=65429:0 +Key80=65431:0 +Key81=65434:0 +Key82=65453:45 +Key83=65430:0 +Key84=65437:0 +Key85=65432:0 +Key86=65451:43 +Key87=65436:0 +Key88=65433:0 +Key89=65435:0 +Key90=65438:0 +Key91=65439:0 +Key92=0:0 +Key93=0:0 +Key94=65312:0 +Key95=65480:0 +Key96=65481:0 +Key97=65360:0 +Key98=65362:0 +Key99=65365:0 +Key100=65361:0 +Key101=0:0 +Key102=65363:0 +Key103=65367:0 +Key104=65364:0 +Key105=65366:0 +Key106=65379:0 +Key107=65535:127 +Key108=65421:13 +Key109=65508:0 +Key110=65299:0 +Key111=65377:0 +Key112=65455:47 +Key113=65512:0 +Key114=0:0 +Key115=65515:0 +Key116=65516:0 +Key117=65383:0 +Key118=0:0 +Key119=0:0 +Key120=0:0 +Key121=0:0 +Key122=0:0 +Key123=0:0 +Key124=65027:0 +Key125=65513:0 +Key126=61:61 +Key127=65515:0 +Key128=65517:0 +Key129=0:0 +Key130=0:0 +Key131=0:0 +Key132=0:0 +Key133=0:0 +Key134=65454:46 +Key135=0:0 +Key136=0:0 + +[capslock] +Key8=65406:0 +Key9=65307:27 +Key10=38:38 +Key11=55:55 +Key12=53:53 +Key13=51:51 +Key14=49:49 +Key15=57:57 +Key16=48:48 +Key17=50:50 +Key18=52:52 +Key19=54:54 +Key20=56:56 +Key21=35:35 +Key22=65288:8 +Key23=65289:9 +Key24=59:59 +Key25=44:44 +Key26=46:46 +Key27=80:80 +Key28=89:89 +Key29=70:70 +Key30=71:71 +Key31=67:67 +Key32=82:82 +Key33=76:76 +Key34=47:47 +Key35=64:64 +Key36=65293:13 +Key37=65507:0 +Key38=65:65 +Key39=79:79 +Key40=69:69 +Key41=85:85 +Key42=73:73 +Key43=68:68 +Key44=72:72 +Key45=84:84 +Key46=78:78 +Key47=83:83 +Key48=95:95 +Key49=36:36 +Key50=65505:0 +Key51=92:92 +Key52=39:39 +Key53=81:81 +Key54=74:74 +Key55=75:75 +Key56=88:88 +Key57=66:66 +Key58=77:77 +Key59=87:87 +Key60=86:86 +Key61=90:90 +Key62=65506:0 +Key63=65450:42 +Key64=65513:0 +Key65=32:32 +Key66=65509:0 +Key67=65470:0 +Key68=65471:0 +Key69=65472:0 +Key70=65473:0 +Key71=65474:0 +Key72=65475:0 +Key73=65476:0 +Key74=65477:0 +Key75=65478:0 +Key76=65479:0 +Key77=65407:0 +Key78=65300:0 +Key79=65429:0 +Key80=65431:0 +Key81=65434:0 +Key82=65453:45 +Key83=65430:0 +Key84=65437:0 +Key85=65432:0 +Key86=65451:43 +Key87=65436:0 +Key88=65433:0 +Key89=65435:0 +Key90=65438:0 +Key91=65439:0 +Key92=0:0 +Key93=0:0 +Key94=65312:0 +Key95=65480:0 +Key96=65481:0 +Key97=65360:0 +Key98=65362:0 +Key99=65365:0 +Key100=65361:0 +Key101=0:0 +Key102=65363:0 +Key103=65367:0 +Key104=65364:0 +Key105=65366:0 +Key106=65379:0 +Key107=65535:127 +Key108=65421:13 +Key109=65508:0 +Key110=65299:0 +Key111=65377:0 +Key112=65455:47 +Key113=65514:0 +Key114=0:0 +Key115=65515:0 +Key116=65516:0 +Key117=65383:0 +Key118=0:0 +Key119=0:0 +Key120=0:0 +Key121=0:0 +Key122=0:0 +Key123=0:0 +Key124=65027:0 +Key125=0:0 +Key126=65469:61 +Key127=0:0 +Key128=0:0 +Key129=0:0 +Key130=0:0 +Key131=0:0 +Key132=0:0 +Key133=0:0 +Key134=65454:46 +Key135=0:0 +Key136=0:0 + +[capslockaltgr] +Key8=65406:0 +Key9=65307:27 +Key10=38:38 +Key11=0:0 +Key12=0:0 +Key13=0:0 +Key14=0:0 +Key15=65106:94 +Key16=0:0 +Key17=0:0 +Key18=0:0 +Key19=0:0 +Key20=16789016:11800 +Key21=65104:96 +Key22=65288:8 +Key23=65289:9 +Key24=65111:168 +Key25=171:171 +Key26=187:187 +Key27=182:182 +Key28=220:220 +Key29=70:70 +Key30=71:71 +Key31=199:199 +Key32=174:174 +Key33=76:76 +Key34=191:191 +Key35=65106:94 +Key36=65293:13 +Key37=65507:0 +Key38=197:197 +Key39=216:216 +Key40=198:198 +Key41=201:201 +Key42=73:73 +Key43=208:208 +Key44=65105:180 +Key45=222:222 +Key46=209:209 +Key47=223:223 +Key48=2730:8211 +Key49=65107:126 +Key50=65505:0 +Key51=92:92 +Key52=65105:180 +Key53=81:81 +Key54=74:74 +Key55=75:75 +Key56=88:88 +Key57=66:66 +Key58=77:77 +Key59=87:87 +Key60=86:86 +Key61=90:90 +Key62=65506:0 +Key63=65450:42 +Key64=65513:0 +Key65=32:32 +Key66=65509:0 +Key67=65470:0 +Key68=65471:0 +Key69=65472:0 +Key70=65473:0 +Key71=65474:0 +Key72=65475:0 +Key73=65476:0 +Key74=65477:0 +Key75=65478:0 +Key76=65479:0 +Key77=65407:0 +Key78=65300:0 +Key79=65429:0 +Key80=65431:0 +Key81=65434:0 +Key82=65453:45 +Key83=65430:0 +Key84=65437:0 +Key85=65432:0 +Key86=65451:43 +Key87=65436:0 +Key88=65433:0 +Key89=65435:0 +Key90=65438:0 +Key91=65439:0 +Key92=0:0 +Key93=0:0 +Key94=65312:0 +Key95=65480:0 +Key96=65481:0 +Key97=65360:0 +Key98=65362:0 +Key99=65365:0 +Key100=65361:0 +Key101=0:0 +Key102=65363:0 +Key103=65367:0 +Key104=65364:0 +Key105=65366:0 +Key106=65379:0 +Key107=65535:127 +Key108=65421:13 +Key109=65508:0 +Key110=65299:0 +Key111=65377:0 +Key112=65455:47 +Key113=65514:0 +Key114=0:0 +Key115=65515:0 +Key116=65516:0 +Key117=65383:0 +Key118=0:0 +Key119=0:0 +Key120=0:0 +Key121=0:0 +Key122=0:0 +Key123=0:0 +Key124=65027:0 +Key125=0:0 +Key126=65469:61 +Key127=0:0 +Key128=0:0 +Key129=0:0 +Key130=0:0 +Key131=0:0 +Key132=0:0 +Key133=0:0 +Key134=65454:46 +Key135=0:0 +Key136=0:0 + +[shiftcapslock] +Key8=65406:0 +Key9=65307:27 +Key10=37:37 +Key11=91:91 +Key12=123:123 +Key13=125:125 +Key14=40:40 +Key15=61:61 +Key16=42:42 +Key17=41:41 +Key18=43:43 +Key19=93:93 +Key20=33:33 +Key21=96:96 +Key22=65288:8 +Key23=65056:0 +Key24=58:58 +Key25=60:60 +Key26=62:62 +Key27=112:112 +Key28=121:121 +Key29=102:102 +Key30=103:103 +Key31=99:99 +Key32=114:114 +Key33=108:108 +Key34=63:63 +Key35=94:94 +Key36=65293:13 +Key37=65507:0 +Key38=97:97 +Key39=111:111 +Key40=101:101 +Key41=117:117 +Key42=105:105 +Key43=100:100 +Key44=104:104 +Key45=116:116 +Key46=110:110 +Key47=115:115 +Key48=45:45 +Key49=126:126 +Key50=65505:0 +Key51=124:124 +Key52=34:34 +Key53=113:113 +Key54=106:106 +Key55=107:107 +Key56=120:120 +Key57=98:98 +Key58=109:109 +Key59=119:119 +Key60=118:118 +Key61=122:122 +Key62=65506:0 +Key63=65450:42 +Key64=65511:0 +Key65=32:32 +Key66=65509:0 +Key67=65470:0 +Key68=65471:0 +Key69=65472:0 +Key70=65473:0 +Key71=65474:0 +Key72=65475:0 +Key73=65476:0 +Key74=65477:0 +Key75=65478:0 +Key76=65479:0 +Key77=65407:0 +Key78=65300:0 +Key79=65429:0 +Key80=65431:0 +Key81=65434:0 +Key82=65453:45 +Key83=65430:0 +Key84=65437:0 +Key85=65432:0 +Key86=65451:43 +Key87=65436:0 +Key88=65433:0 +Key89=65435:0 +Key90=65438:0 +Key91=65439:0 +Key92=0:0 +Key93=0:0 +Key94=65312:0 +Key95=65480:0 +Key96=65481:0 +Key97=65360:0 +Key98=65362:0 +Key99=65365:0 +Key100=65361:0 +Key101=0:0 +Key102=65363:0 +Key103=65367:0 +Key104=65364:0 +Key105=65366:0 +Key106=65379:0 +Key107=65535:127 +Key108=65421:13 +Key109=65508:0 +Key110=65299:0 +Key111=65377:0 +Key112=65455:47 +Key113=65512:0 +Key114=0:0 +Key115=65515:0 +Key116=65516:0 +Key117=65383:0 +Key118=0:0 +Key119=0:0 +Key120=0:0 +Key121=0:0 +Key122=0:0 +Key123=0:0 +Key124=65027:0 +Key125=65513:0 +Key126=61:61 +Key127=65515:0 +Key128=65517:0 +Key129=0:0 +Key130=0:0 +Key131=0:0 +Key132=0:0 +Key133=0:0 +Key134=65454:46 +Key135=0:0 +Key136=0:0 + +[shiftcapslockaltgr] +Key8=65406:0 +Key9=65307:27 +Key10=37:37 +Key11=164:164 +Key12=162:162 +Key13=165:165 +Key14=8364:8364 +Key15=163:163 +Key16=0:0 +Key17=189:189 +Key18=65104:96 +Key19=0:0 +Key20=161:161 +Key21=0:0 +Key22=65288:8 +Key23=65056:0 +Key24=65111:168 +Key25=16785436:8220 +Key26=16785437:8221 +Key27=167:167 +Key28=252:252 +Key29=102:102 +Key30=103:103 +Key31=231:231 +Key32=2761:8482 +Key33=108:108 +Key34=16785469:8253 +Key35=65114:711 +Key36=65293:13 +Key37=65507:0 +Key38=229:229 +Key39=248:248 +Key40=230:230 +Key41=233:233 +Key42=105:105 +Key43=240:240 +Key44=0:0 +Key45=254:254 +Key46=241:241 +Key47=0:0 +Key48=173:173 +Key49=65107:126 +Key50=65505:0 +Key51=124:124 +Key52=65113:733 +Key53=113:113 +Key54=106:106 +Key55=107:107 +Key56=120:120 +Key57=98:98 +Key58=109:109 +Key59=119:119 +Key60=118:118 +Key61=122:122 +Key62=65506:0 +Key63=65450:42 +Key64=65511:0 +Key65=32:32 +Key66=65509:0 +Key67=65470:0 +Key68=65471:0 +Key69=65472:0 +Key70=65473:0 +Key71=65474:0 +Key72=65475:0 +Key73=65476:0 +Key74=65477:0 +Key75=65478:0 +Key76=65479:0 +Key77=65407:0 +Key78=65300:0 +Key79=65429:0 +Key80=65431:0 +Key81=65434:0 +Key82=65453:45 +Key83=65430:0 +Key84=65437:0 +Key85=65432:0 +Key86=65451:43 +Key87=65436:0 +Key88=65433:0 +Key89=65435:0 +Key90=65438:0 +Key91=65439:0 +Key92=0:0 +Key93=0:0 +Key94=65312:0 +Key95=65480:0 +Key96=65481:0 +Key97=65360:0 +Key98=65362:0 +Key99=65365:0 +Key100=65361:0 +Key101=0:0 +Key102=65363:0 +Key103=65367:0 +Key104=65364:0 +Key105=65366:0 +Key106=65379:0 +Key107=65535:127 +Key108=65421:13 +Key109=65508:0 +Key110=65299:0 +Key111=65377:0 +Key112=65455:47 +Key113=65512:0 +Key114=0:0 +Key115=65515:0 +Key116=65516:0 +Key117=65383:0 +Key118=0:0 +Key119=0:0 +Key120=0:0 +Key121=0:0 +Key122=0:0 +Key123=0:0 +Key124=65027:0 +Key125=65513:0 +Key126=61:61 +Key127=65515:0 +Key128=65517:0 +Key129=0:0 +Key130=0:0 +Key131=0:0 +Key132=0:0 +Key133=0:0 +Key134=65454:46 +Key135=0:0 +Key136=0:0 diff -Nru xrdp-0.9.12/instfiles/Makefile.am xrdp-0.9.15/instfiles/Makefile.am --- xrdp-0.9.12/instfiles/Makefile.am 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/instfiles/Makefile.am 2020-12-28 13:47:12.000000000 +0000 @@ -50,7 +50,8 @@ km-00000813.ini \ km-00000816.ini \ km-0000100c.ini \ - km-00010409.ini + km-00010409.ini \ + km-19360409.ini # # platform specific files diff -Nru xrdp-0.9.12/instfiles/Makefile.in xrdp-0.9.15/instfiles/Makefile.in --- xrdp-0.9.12/instfiles/Makefile.in 2019-12-28 12:36:37.000000000 +0000 +++ xrdp-0.9.15/instfiles/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -427,7 +427,8 @@ km-00000813.ini \ km-00000816.ini \ km-0000100c.ini \ - km-00010409.ini + km-00010409.ini \ + km-19360409.ini # diff -Nru xrdp-0.9.12/instfiles/pam.d/Makefile.in xrdp-0.9.15/instfiles/pam.d/Makefile.in --- xrdp-0.9.12/instfiles/pam.d/Makefile.in 2019-12-28 12:36:37.000000000 +0000 +++ xrdp-0.9.15/instfiles/pam.d/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/instfiles/pam.d/mkpamrules xrdp-0.9.15/instfiles/pam.d/mkpamrules --- xrdp-0.9.12/instfiles/pam.d/mkpamrules 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/instfiles/pam.d/mkpamrules 2020-12-28 13:47:12.000000000 +0000 @@ -10,51 +10,87 @@ 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" diff -Nru xrdp-0.9.12/instfiles/pam.d/xrdp-sesman.unix xrdp-0.9.15/instfiles/pam.d/xrdp-sesman.unix --- xrdp-0.9.12/instfiles/pam.d/xrdp-sesman.unix 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/instfiles/pam.d/xrdp-sesman.unix 2020-12-28 13:47:12.000000000 +0000 @@ -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 diff -Nru xrdp-0.9.12/instfiles/pulse/Makefile.in xrdp-0.9.15/instfiles/pulse/Makefile.in --- xrdp-0.9.12/instfiles/pulse/Makefile.in 2019-12-28 12:36:37.000000000 +0000 +++ xrdp-0.9.15/instfiles/pulse/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/instfiles/rc.d/Makefile.in xrdp-0.9.15/instfiles/rc.d/Makefile.in --- xrdp-0.9.12/instfiles/rc.d/Makefile.in 2019-12-28 12:36:37.000000000 +0000 +++ xrdp-0.9.15/instfiles/rc.d/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/keygen/keygen.c xrdp-0.9.15/keygen/keygen.c --- xrdp-0.9.12/keygen/keygen.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/keygen/keygen.c 2020-12-28 14:03:43.000000000 +0000 @@ -30,6 +30,7 @@ #endif #include "os_calls.h" +#include "string_calls.h" #include "ssl_calls.h" #include "arch.h" #include "list.h" diff -Nru xrdp-0.9.12/keygen/Makefile.in xrdp-0.9.15/keygen/Makefile.in --- xrdp-0.9.12/keygen/Makefile.in 2019-12-28 12:36:38.000000000 +0000 +++ xrdp-0.9.15/keygen/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/libpainter/aclocal.m4 xrdp-0.9.15/libpainter/aclocal.m4 --- xrdp-0.9.12/libpainter/aclocal.m4 2019-12-28 12:36:26.000000000 +0000 +++ xrdp-0.9.15/libpainter/aclocal.m4 2020-12-28 14:06:28.000000000 +0000 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.16.1 -*- Autoconf -*- +# generated automatically by aclocal 1.16.3 -*- Autoconf -*- -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002-2018 Free Software Foundation, Inc. +# Copyright (C) 2002-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -35,7 +35,7 @@ [am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.16.1], [], +m4_if([$1], [1.16.3], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,14 +51,14 @@ # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.16.1])dnl +[AM_AUTOMAKE_VERSION([1.16.3])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -110,7 +110,7 @@ # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2018 Free Software Foundation, Inc. +# Copyright (C) 1997-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -141,7 +141,7 @@ Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -332,7 +332,7 @@ # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -371,7 +371,9 @@ done if test $am_rc -ne 0; then AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments - for automatic dependency tracking. Try re-running configure with the + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE="gmake" (or whatever is + necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking).]) fi @@ -398,7 +400,7 @@ # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -595,7 +597,7 @@ done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -616,7 +618,7 @@ fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2018 Free Software Foundation, Inc. +# Copyright (C) 2003-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -637,7 +639,7 @@ # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -680,7 +682,7 @@ # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2018 Free Software Foundation, Inc. +# Copyright (C) 1997-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -701,12 +703,7 @@ [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac + MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then @@ -719,7 +716,7 @@ # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -748,7 +745,7 @@ AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -795,7 +792,7 @@ # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -814,7 +811,7 @@ # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -895,7 +892,7 @@ rm -f conftest.file ]) -# Copyright (C) 2009-2018 Free Software Foundation, Inc. +# Copyright (C) 2009-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -955,7 +952,7 @@ _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -983,7 +980,7 @@ INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2018 Free Software Foundation, Inc. +# Copyright (C) 2006-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1002,7 +999,7 @@ # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2018 Free Software Foundation, Inc. +# Copyright (C) 2004-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/libpainter/compile xrdp-0.9.15/libpainter/compile --- xrdp-0.9.12/libpainter/compile 2019-12-28 12:36:27.000000000 +0000 +++ xrdp-0.9.15/libpainter/compile 2020-12-28 14:06:29.000000000 +0000 @@ -3,7 +3,7 @@ scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify @@ -53,7 +53,7 @@ MINGW*) file_conv=mingw ;; - CYGWIN*) + CYGWIN* | MSYS*) file_conv=cygwin ;; *) @@ -67,7 +67,7 @@ mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; - cygwin/*) + cygwin/* | msys/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) diff -Nru xrdp-0.9.12/libpainter/configure xrdp-0.9.15/libpainter/configure --- xrdp-0.9.12/libpainter/configure 2019-12-28 12:36:27.000000000 +0000 +++ xrdp-0.9.15/libpainter/configure 2020-12-28 14:06:29.000000000 +0000 @@ -2333,12 +2333,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac + MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then @@ -13859,7 +13854,9 @@ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "Something went wrong bootstrapping makefile fragments - for automatic dependency tracking. Try re-running configure with the + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE=\"gmake\" (or whatever is + necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking). See \`config.log' for more details" "$LINENO" 5; } diff -Nru xrdp-0.9.12/libpainter/depcomp xrdp-0.9.15/libpainter/depcomp --- xrdp-0.9.12/libpainter/depcomp 2019-12-28 12:36:27.000000000 +0000 +++ xrdp-0.9.15/libpainter/depcomp 2020-12-28 14:06:29.000000000 +0000 @@ -3,7 +3,7 @@ scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff -Nru xrdp-0.9.12/libpainter/include/Makefile.in xrdp-0.9.15/libpainter/include/Makefile.in --- xrdp-0.9.12/libpainter/include/Makefile.in 2019-12-28 12:36:27.000000000 +0000 +++ xrdp-0.9.15/libpainter/include/Makefile.in 2020-12-28 14:06:29.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/libpainter/include/painter.h xrdp-0.9.15/libpainter/include/painter.h --- xrdp-0.9.12/libpainter/include/painter.h 2017-01-10 08:10:22.000000000 +0000 +++ xrdp-0.9.15/libpainter/include/painter.h 2017-01-10 08:10:32.000000000 +0000 @@ -24,20 +24,20 @@ #define LIBPAINTER_VERSION_MICRO 0 #define PT_FORMAT_a8b8g8r8 \ -((32 << 24) | (3 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8) + ((32 << 24) | (3 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8) #define PT_FORMAT_a8r8g8b8 \ -((32 << 24) | (2 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8) + ((32 << 24) | (2 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8) #define PT_FORMAT_r5g6b5 \ -((16 << 24) | (2 << 16) | (0 << 12) | (5 << 8) | (6 << 4) | 5) + ((16 << 24) | (2 << 16) | (0 << 12) | (5 << 8) | (6 << 4) | 5) #define PT_FORMAT_a1r5g5b5 \ -((16 << 24) | (2 << 16) | (1 << 12) | (5 << 8) | (5 << 4) | 5) + ((16 << 24) | (2 << 16) | (1 << 12) | (5 << 8) | (5 << 4) | 5) #define PT_FORMAT_r3g3b2 \ -((8 << 24) | (2 << 16) | (0 << 12) | (3 << 8) | (3 << 4) | 2) + ((8 << 24) | (2 << 16) | (0 << 12) | (3 << 8) | (3 << 4) | 2) #define PT_FORMAT_c1 \ -((1 << 24) | (4 << 16) | (0 << 12) | (0 << 8) | (0 << 4) | 0) + ((1 << 24) | (4 << 16) | (0 << 12) | (0 << 8) | (0 << 4) | 0) #define PT_FORMAT_c8 \ -((8 << 24) | (4 << 16) | (0 << 12) | (0 << 8) | (0 << 4) | 0) + ((8 << 24) | (4 << 16) | (0 << 12) | (0 << 8) | (0 << 4) | 0) struct painter_bitmap { @@ -58,8 +58,8 @@ #define PT_LINE_FLAGS_NONE 0 - /* reverse Windows X11 */ - /* polish */ +/* reverse Windows X11 */ +/* polish */ #define PT_ROP_0 0x00 /* 0 BLACKNESS GXclear */ #define PT_ROP_DSon 0x11 /* DSon NOTSRCERASE GXnor */ #define PT_ROP_DSna 0x22 /* DSna GXandInverted */ diff -Nru xrdp-0.9.12/libpainter/install-sh xrdp-0.9.15/libpainter/install-sh --- xrdp-0.9.12/libpainter/install-sh 2019-12-28 12:36:27.000000000 +0000 +++ xrdp-0.9.15/libpainter/install-sh 2020-12-28 14:06:29.000000000 +0000 @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2018-03-11.20; # UTC +scriptversion=2020-11-14.01; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -69,6 +69,11 @@ # Desired mode of installed file. mode=0755 +# Create dirs (including intermediate dirs) using mode 755. +# This is like GNU 'install' as of coreutils 8.32 (2020). +mkdir_umask=22 + +backupsuffix= chgrpcmd= chmodcmd=$chmodprog chowncmd= @@ -99,18 +104,28 @@ --version display version info and exit. -c (ignored) - -C install only if different (preserve the last data modification time) + -C install only if different (preserve data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. + -p pass -p to $cpprog. -s $stripprog installed files. + -S SUFFIX attempt to back up existing files, with suffix SUFFIX. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG + +By default, rm is invoked with -f; when overridden with RMPROG, +it's up to you to specify -f if you want it. + +If -S is not specified, no backups are attempted. + +Email bug reports to bug-automake@gnu.org. +Automake home page: https://www.gnu.org/software/automake/ " while test $# -ne 0; do @@ -137,8 +152,13 @@ -o) chowncmd="$chownprog $2" shift;; + -p) cpprog="$cpprog -p";; + -s) stripcmd=$stripprog;; + -S) backupsuffix="$2" + shift;; + -t) is_target_a_directory=always dst_arg=$2 @@ -255,6 +275,10 @@ dstdir=$dst test -d "$dstdir" dstdir_status=$? + # Don't chown directories that already exist. + if test $dstdir_status = 0; then + chowncmd="" + fi else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command @@ -301,22 +325,6 @@ if test $dstdir_status != 0; then case $posix_mkdir in '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then @@ -326,52 +334,49 @@ fi posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - # Note that $RANDOM variable is not portable (e.g. dash); Use it - # here however when possible just to lower collision chance. - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - - trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 - - # Because "mkdir -p" follows existing symlinks and we likely work - # directly in world-writeable /tmp, make sure that the '$tmpdir' - # directory is successfully created first before we actually test - # 'mkdir -p' feature. - if (umask $mkdir_umask && - $mkdirprog $mkdir_mode "$tmpdir" && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - test_tmpdir="$tmpdir/a" - ls_ld_tmpdir=`ls -ld "$test_tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null - fi - trap '' 0;; - esac;; + # The $RANDOM variable is not portable (e.g., dash). Use it + # here however when possible just to lower collision chance. + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + + trap ' + ret=$? + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null + exit $ret + ' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p'. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; esac if @@ -382,7 +387,7 @@ then : else - # The umask is ridiculous, or mkdir does not conform to POSIX, + # mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. @@ -411,7 +416,7 @@ prefixes= else if $posix_mkdir; then - (umask=$mkdir_umask && + (umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 @@ -451,7 +456,18 @@ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + (umask $cp_umask && + { test -z "$stripcmd" || { + # Create $dsttmp read-write so that cp doesn't create it read-only, + # which would cause strip to fail. + if test -z "$doit"; then + : >"$dsttmp" # No need to fork-exec 'touch'. + else + $doit touch "$dsttmp" + fi + } + } && + $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # @@ -477,6 +493,13 @@ then rm -f "$dsttmp" else + # If $backupsuffix is set, and the file being installed + # already exists, attempt a backup. Don't worry if it fails, + # e.g., if mv doesn't support -f. + if test -n "$backupsuffix" && test -f "$dst"; then + $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null + fi + # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || @@ -491,9 +514,9 @@ # file should still install successfully. { test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || + $doit $rmcmd "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 diff -Nru xrdp-0.9.12/libpainter/Makefile.in xrdp-0.9.15/libpainter/Makefile.in --- xrdp-0.9.12/libpainter/Makefile.in 2019-12-28 12:36:27.000000000 +0000 +++ xrdp-0.9.15/libpainter/Makefile.in 2020-12-28 14:06:29.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -144,8 +144,8 @@ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir distdir-am dist dist-all distcheck -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ - $(LISP)config_ac-h.in +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ + config_ac-h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. @@ -207,6 +207,8 @@ DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip +# Exists only to be overridden by the user if desired. +AM_DISTCHECK_DVI_TARGET = dvi distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' @@ -587,6 +589,10 @@ tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) +dist-zstd: distdir + tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst + $(am__post_remove_distdir) + dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @@ -629,6 +635,8 @@ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ + *.tar.zst*) \ + zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) @@ -644,7 +652,7 @@ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ @@ -806,18 +814,18 @@ am--refresh check check-am clean clean-cscope clean-generic \ clean-libtool cscope cscopelist-am ctags ctags-am dist \ dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ - dist-xz dist-zip distcheck distclean distclean-generic \ - distclean-hdr distclean-libtool distclean-tags distcleancheck \ - distdir distuninstallcheck dvi dvi-am html html-am info \ - info-am install install-am install-data install-data-am \ - install-dvi install-dvi-am install-exec install-exec-am \ - install-html install-html-am install-info install-info-am \ - install-man install-pdf install-pdf-am install-ps \ - install-ps-am install-strip installcheck installcheck-am \ - installdirs installdirs-am maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am + dist-xz dist-zip dist-zstd distcheck distclean \ + distclean-generic distclean-hdr distclean-libtool \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am .PRECIOUS: Makefile diff -Nru xrdp-0.9.12/libpainter/missing xrdp-0.9.15/libpainter/missing --- xrdp-0.9.12/libpainter/missing 2019-12-28 12:36:27.000000000 +0000 +++ xrdp-0.9.15/libpainter/missing 2020-12-28 14:06:29.000000000 +0000 @@ -3,7 +3,7 @@ scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify diff -Nru xrdp-0.9.12/libpainter/pkgconfig/Makefile.in xrdp-0.9.15/libpainter/pkgconfig/Makefile.in --- xrdp-0.9.12/libpainter/pkgconfig/Makefile.in 2019-12-28 12:36:27.000000000 +0000 +++ xrdp-0.9.15/libpainter/pkgconfig/Makefile.in 2020-12-28 14:06:29.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/libpainter/src/Makefile.in xrdp-0.9.15/libpainter/src/Makefile.in --- xrdp-0.9.12/libpainter/src/Makefile.in 2019-12-28 12:36:27.000000000 +0000 +++ xrdp-0.9.15/libpainter/src/Makefile.in 2020-12-28 14:06:29.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/libpainter/src/painter_utils.c xrdp-0.9.15/libpainter/src/painter_utils.c --- xrdp-0.9.12/libpainter/src/painter_utils.c 2017-03-14 02:31:16.000000000 +0000 +++ xrdp-0.9.15/libpainter/src/painter_utils.c 2017-03-14 02:31:26.000000000 +0000 @@ -34,22 +34,38 @@ { switch (rop) { - case PT_ROP_0: return 0; - case PT_ROP_DSon: return ~(src | dst); - case PT_ROP_DSna: return (~src) & dst; - case PT_ROP_Sn: return ~src; - case PT_ROP_SDna: return src & (~dst); - case PT_ROP_Dn: return ~(dst); - case PT_ROP_DSx: return src ^ dst; - case PT_ROP_DSan: return ~(src & dst); - case PT_ROP_DSa: return src & dst; - case PT_ROP_DSxn: return ~(src) ^ dst; - case PT_ROP_D: return dst; - case PT_ROP_DSno: return (~src) | dst; - case PT_ROP_S: return src; - case PT_ROP_SDno: return src | (~dst); - case PT_ROP_DSo: return src | dst; - case PT_ROP_1: return ~0; + case PT_ROP_0: + return 0; + case PT_ROP_DSon: + return ~(src | dst); + case PT_ROP_DSna: + return (~src) & dst; + case PT_ROP_Sn: + return ~src; + case PT_ROP_SDna: + return src & (~dst); + case PT_ROP_Dn: + return ~(dst); + case PT_ROP_DSx: + return src ^ dst; + case PT_ROP_DSan: + return ~(src & dst); + case PT_ROP_DSa: + return src & dst; + case PT_ROP_DSxn: + return ~(src) ^ dst; + case PT_ROP_D: + return dst; + case PT_ROP_DSno: + return (~src) | dst; + case PT_ROP_S: + return src; + case PT_ROP_SDno: + return src | (~dst); + case PT_ROP_DSo: + return src | dst; + case PT_ROP_1: + return ~0; } return dst; } @@ -63,7 +79,7 @@ int Bpp; if ((x >= 0) && (x < bitmap->width) && - (y >= 0) && (y < bitmap->height)) + (y >= 0) && (y < bitmap->height)) { bpp = bitmap->format >> 24; if (bpp < 8) @@ -239,11 +255,11 @@ int x, int y, int pixel, int pixel_format) { if ((painter->clip_valid == 0) || - ((x >= painter->clip.x1) && (x < painter->clip.x2) && - (y >= painter->clip.y1) && (y < painter->clip.y2))) + ((x >= painter->clip.x1) && (x < painter->clip.x2) && + (y >= painter->clip.y1) && (y < painter->clip.y2))) { if ((x >= 0) && (x < bitmap->width) && - (y >= 0) && (y < bitmap->height)) + (y >= 0) && (y < bitmap->height)) { pixel = pixel_convert(pixel, pixel_format, bitmap->format, painter->palette); diff -Nru xrdp-0.9.12/libpainter/src/painter_utils.h xrdp-0.9.15/libpainter/src/painter_utils.h --- xrdp-0.9.12/libpainter/src/painter_utils.h 2016-09-28 13:53:13.000000000 +0000 +++ xrdp-0.9.15/libpainter/src/painter_utils.h 2016-09-28 13:53:23.000000000 +0000 @@ -20,76 +20,76 @@ #define __PAINTER_UTILS_H #define SPLIT_a8r8g8b8(_c, _a, _r, _g, _b) \ -do { \ - _a = ((_c) & 0xff000000) >> 24; \ - _r = ((_c) & 0x00ff0000) >> 16; \ - _g = ((_c) & 0x0000ff00) >> 8; \ - _b = ((_c) & 0x000000ff) >> 0; \ -} while (0) + do { \ + _a = ((_c) & 0xff000000) >> 24; \ + _r = ((_c) & 0x00ff0000) >> 16; \ + _g = ((_c) & 0x0000ff00) >> 8; \ + _b = ((_c) & 0x000000ff) >> 0; \ + } while (0) #define SPLIT_a8b8g8r8(_c, _a, _r, _g, _b) \ -do { \ - _a = ((_c) & 0xff000000) >> 24; \ - _b = ((_c) & 0x00ff0000) >> 16; \ - _g = ((_c) & 0x0000ff00) >> 8; \ - _r = ((_c) & 0x000000ff) >> 0; \ -} while (0) + do { \ + _a = ((_c) & 0xff000000) >> 24; \ + _b = ((_c) & 0x00ff0000) >> 16; \ + _g = ((_c) & 0x0000ff00) >> 8; \ + _r = ((_c) & 0x000000ff) >> 0; \ + } while (0) #define SPLIT_a1r5g5b5(_c, _a, _r, _g, _b) \ -do { \ - _a = (((_c) >> 15) & 1) * 0xff; \ - _r = (((_c) >> 7) & 0xf8) | (((_c) >> 12) & 0x7); \ - _g = (((_c) >> 2) & 0xf8) | (((_c) >> 8) & 0x7); \ - _b = (((_c) << 3) & 0xf8) | (((_c) >> 2) & 0x7); \ -} while (0) + do { \ + _a = (((_c) >> 15) & 1) * 0xff; \ + _r = (((_c) >> 7) & 0xf8) | (((_c) >> 12) & 0x7); \ + _g = (((_c) >> 2) & 0xf8) | (((_c) >> 8) & 0x7); \ + _b = (((_c) << 3) & 0xf8) | (((_c) >> 2) & 0x7); \ + } while (0) #define SPLIT_r5g6b5(_c, _a, _r, _g, _b) \ -do { \ - _a = 0xff; \ - _r = (((_c) >> 8) & 0xf8) | (((_c) >> 13) & 0x7); \ - _g = (((_c) >> 3) & 0xfc) | (((_c) >> 9) & 0x3); \ - _b = (((_c) << 3) & 0xf8) | (((_c) >> 2) & 0x7); \ -} while (0) + do { \ + _a = 0xff; \ + _r = (((_c) >> 8) & 0xf8) | (((_c) >> 13) & 0x7); \ + _g = (((_c) >> 3) & 0xfc) | (((_c) >> 9) & 0x3); \ + _b = (((_c) << 3) & 0xf8) | (((_c) >> 2) & 0x7); \ + } while (0) #define SPLIT_r3g3b2(_c, _a, _r, _g, _b) \ -do { \ - _a = 0xff; \ - _r = 0; \ - _g = 0; \ - _b = 0; \ -} while (0) + do { \ + _a = 0xff; \ + _r = 0; \ + _g = 0; \ + _b = 0; \ + } while (0) #define MAKE_a1r5g5b5(_c, _a, _r, _g, _b) \ -do { \ - _c = (((_a) & 0xff) >> 7) << 15 | \ - (((_r) & 0xff) >> 3) << 10 | \ - (((_g) & 0xff) >> 3) << 5 | \ - (((_b) & 0xff) >> 3) << 0; \ -} while (0) + do { \ + _c = (((_a) & 0xff) >> 7) << 15 | \ + (((_r) & 0xff) >> 3) << 10 | \ + (((_g) & 0xff) >> 3) << 5 | \ + (((_b) & 0xff) >> 3) << 0; \ + } while (0) #define MAKE_r5g6b5(_c, _a, _r, _g, _b) \ -do { \ - _c = \ - (((_r) & 0xff) >> 3) << 11 | \ - (((_g) & 0xff) >> 2) << 5 | \ - (((_b) & 0xff) >> 3) << 0; \ -} while (0) + do { \ + _c = \ + (((_r) & 0xff) >> 3) << 11 | \ + (((_g) & 0xff) >> 2) << 5 | \ + (((_b) & 0xff) >> 3) << 0; \ + } while (0) #define MAKE_a8r8g8b8(_c, _a, _r, _g, _b) \ -do { \ - _c = ((_a) & 0xff) << 24 | \ - ((_r) & 0xff) << 16 | \ - ((_g) & 0xff) << 8 | \ - ((_b) & 0xff) << 0; \ -} while (0) + do { \ + _c = ((_a) & 0xff) << 24 | \ + ((_r) & 0xff) << 16 | \ + ((_g) & 0xff) << 8 | \ + ((_b) & 0xff) << 0; \ + } while (0) #define MAKE_a8b8g8r8(_c, _a, _r, _g, _b) \ -do { \ - _c = ((_a) & 0xff) << 24 | \ - ((_b) & 0xff) << 16 | \ - ((_g) & 0xff) << 8 | \ - ((_r) & 0xff) << 0; \ -} while (0) + do { \ + _c = ((_a) & 0xff) << 24 | \ + ((_b) & 0xff) << 16 | \ + ((_g) & 0xff) << 8 | \ + ((_r) & 0xff) << 0; \ + } while (0) struct painter_rect { diff -Nru xrdp-0.9.12/libpainter/tests/Makefile.in xrdp-0.9.15/libpainter/tests/Makefile.in --- xrdp-0.9.12/libpainter/tests/Makefile.in 2019-12-28 12:36:28.000000000 +0000 +++ xrdp-0.9.15/libpainter/tests/Makefile.in 2020-12-28 14:06:29.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/librfxcodec/aclocal.m4 xrdp-0.9.15/librfxcodec/aclocal.m4 --- xrdp-0.9.12/librfxcodec/aclocal.m4 2019-12-28 12:36:32.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/aclocal.m4 2020-12-28 14:06:34.000000000 +0000 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.16.1 -*- Autoconf -*- +# generated automatically by aclocal 1.16.3 -*- Autoconf -*- -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002-2018 Free Software Foundation, Inc. +# Copyright (C) 2002-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -35,7 +35,7 @@ [am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.16.1], [], +m4_if([$1], [1.16.3], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,14 +51,14 @@ # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.16.1])dnl +[AM_AUTOMAKE_VERSION([1.16.3])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -110,7 +110,7 @@ # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2018 Free Software Foundation, Inc. +# Copyright (C) 1997-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -141,7 +141,7 @@ Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -332,7 +332,7 @@ # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -371,7 +371,9 @@ done if test $am_rc -ne 0; then AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments - for automatic dependency tracking. Try re-running configure with the + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE="gmake" (or whatever is + necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking).]) fi @@ -398,7 +400,7 @@ # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -595,7 +597,7 @@ done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -616,7 +618,7 @@ fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2018 Free Software Foundation, Inc. +# Copyright (C) 2003-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -637,7 +639,7 @@ # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -680,7 +682,7 @@ # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2018 Free Software Foundation, Inc. +# Copyright (C) 1997-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -701,12 +703,7 @@ [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac + MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then @@ -719,7 +716,7 @@ # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -748,7 +745,7 @@ AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -795,7 +792,7 @@ # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -814,7 +811,7 @@ # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -895,7 +892,7 @@ rm -f conftest.file ]) -# Copyright (C) 2009-2018 Free Software Foundation, Inc. +# Copyright (C) 2009-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -955,7 +952,7 @@ _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -983,7 +980,7 @@ INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2018 Free Software Foundation, Inc. +# Copyright (C) 2006-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1002,7 +999,7 @@ # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2018 Free Software Foundation, Inc. +# Copyright (C) 2004-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/librfxcodec/compile xrdp-0.9.15/librfxcodec/compile --- xrdp-0.9.12/librfxcodec/compile 2019-12-28 12:36:33.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/compile 2020-12-28 14:06:35.000000000 +0000 @@ -3,7 +3,7 @@ scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify @@ -53,7 +53,7 @@ MINGW*) file_conv=mingw ;; - CYGWIN*) + CYGWIN* | MSYS*) file_conv=cygwin ;; *) @@ -67,7 +67,7 @@ mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; - cygwin/*) + cygwin/* | msys/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) diff -Nru xrdp-0.9.12/librfxcodec/configure xrdp-0.9.15/librfxcodec/configure --- xrdp-0.9.12/librfxcodec/configure 2019-12-28 12:36:33.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/configure 2020-12-28 14:06:34.000000000 +0000 @@ -2337,12 +2337,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac + MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then @@ -12308,7 +12303,7 @@ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the assembler ($NASM $NAFLAGS) works" >&5 $as_echo_n "checking whether the assembler ($NASM $NAFLAGS) works... " >&6; } cat > conftest.asm <&5 $as_echo_n "checking whether the assembler ($NASM $NAFLAGS) works... " >&6; } cat > conftest.asm <&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "Something went wrong bootstrapping makefile fragments - for automatic dependency tracking. Try re-running configure with the + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE=\"gmake\" (or whatever is + necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking). See \`config.log' for more details" "$LINENO" 5; } diff -Nru xrdp-0.9.12/librfxcodec/depcomp xrdp-0.9.15/librfxcodec/depcomp --- xrdp-0.9.12/librfxcodec/depcomp 2019-12-28 12:36:34.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/depcomp 2020-12-28 14:06:35.000000000 +0000 @@ -3,7 +3,7 @@ scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by diff -Nru xrdp-0.9.12/librfxcodec/include/Makefile.in xrdp-0.9.15/librfxcodec/include/Makefile.in --- xrdp-0.9.12/librfxcodec/include/Makefile.in 2019-12-28 12:36:34.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/include/Makefile.in 2020-12-28 14:06:35.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/librfxcodec/install-sh xrdp-0.9.15/librfxcodec/install-sh --- xrdp-0.9.12/librfxcodec/install-sh 2019-12-28 12:36:33.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/install-sh 2020-12-28 14:06:35.000000000 +0000 @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2018-03-11.20; # UTC +scriptversion=2020-11-14.01; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -69,6 +69,11 @@ # Desired mode of installed file. mode=0755 +# Create dirs (including intermediate dirs) using mode 755. +# This is like GNU 'install' as of coreutils 8.32 (2020). +mkdir_umask=22 + +backupsuffix= chgrpcmd= chmodcmd=$chmodprog chowncmd= @@ -99,18 +104,28 @@ --version display version info and exit. -c (ignored) - -C install only if different (preserve the last data modification time) + -C install only if different (preserve data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. + -p pass -p to $cpprog. -s $stripprog installed files. + -S SUFFIX attempt to back up existing files, with suffix SUFFIX. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG + +By default, rm is invoked with -f; when overridden with RMPROG, +it's up to you to specify -f if you want it. + +If -S is not specified, no backups are attempted. + +Email bug reports to bug-automake@gnu.org. +Automake home page: https://www.gnu.org/software/automake/ " while test $# -ne 0; do @@ -137,8 +152,13 @@ -o) chowncmd="$chownprog $2" shift;; + -p) cpprog="$cpprog -p";; + -s) stripcmd=$stripprog;; + -S) backupsuffix="$2" + shift;; + -t) is_target_a_directory=always dst_arg=$2 @@ -255,6 +275,10 @@ dstdir=$dst test -d "$dstdir" dstdir_status=$? + # Don't chown directories that already exist. + if test $dstdir_status = 0; then + chowncmd="" + fi else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command @@ -301,22 +325,6 @@ if test $dstdir_status != 0; then case $posix_mkdir in '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then @@ -326,52 +334,49 @@ fi posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - # Note that $RANDOM variable is not portable (e.g. dash); Use it - # here however when possible just to lower collision chance. - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - - trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 - - # Because "mkdir -p" follows existing symlinks and we likely work - # directly in world-writeable /tmp, make sure that the '$tmpdir' - # directory is successfully created first before we actually test - # 'mkdir -p' feature. - if (umask $mkdir_umask && - $mkdirprog $mkdir_mode "$tmpdir" && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - test_tmpdir="$tmpdir/a" - ls_ld_tmpdir=`ls -ld "$test_tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null - fi - trap '' 0;; - esac;; + # The $RANDOM variable is not portable (e.g., dash). Use it + # here however when possible just to lower collision chance. + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + + trap ' + ret=$? + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null + exit $ret + ' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p'. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; esac if @@ -382,7 +387,7 @@ then : else - # The umask is ridiculous, or mkdir does not conform to POSIX, + # mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. @@ -411,7 +416,7 @@ prefixes= else if $posix_mkdir; then - (umask=$mkdir_umask && + (umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 @@ -451,7 +456,18 @@ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + (umask $cp_umask && + { test -z "$stripcmd" || { + # Create $dsttmp read-write so that cp doesn't create it read-only, + # which would cause strip to fail. + if test -z "$doit"; then + : >"$dsttmp" # No need to fork-exec 'touch'. + else + $doit touch "$dsttmp" + fi + } + } && + $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # @@ -477,6 +493,13 @@ then rm -f "$dsttmp" else + # If $backupsuffix is set, and the file being installed + # already exists, attempt a backup. Don't worry if it fails, + # e.g., if mv doesn't support -f. + if test -n "$backupsuffix" && test -f "$dst"; then + $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null + fi + # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || @@ -491,9 +514,9 @@ # file should still install successfully. { test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || + $doit $rmcmd "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 diff -Nru xrdp-0.9.12/librfxcodec/Makefile.in xrdp-0.9.15/librfxcodec/Makefile.in --- xrdp-0.9.12/librfxcodec/Makefile.in 2019-12-28 12:36:33.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/Makefile.in 2020-12-28 14:06:35.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -173,8 +173,8 @@ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir distdir-am dist dist-all distcheck -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ - $(LISP)config_ac-h.in +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ + config_ac-h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. @@ -236,6 +236,8 @@ DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip +# Exists only to be overridden by the user if desired. +AM_DISTCHECK_DVI_TARGET = dvi distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' @@ -642,6 +644,10 @@ tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) +dist-zstd: distdir + tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst + $(am__post_remove_distdir) + dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @@ -684,6 +690,8 @@ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ + *.tar.zst*) \ + zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) @@ -699,7 +707,7 @@ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ @@ -864,18 +872,19 @@ am--refresh check check-am clean clean-cscope clean-generic \ clean-libtool cscope cscopelist-am ctags ctags-am dist \ dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ - dist-xz dist-zip distcheck distclean distclean-generic \ - distclean-hdr distclean-libtool distclean-tags distcleancheck \ - distdir distuninstallcheck dvi dvi-am html html-am info \ - info-am install install-am install-data install-data-am \ - install-dvi install-dvi-am install-exec install-exec-am \ - install-html install-html-am install-info install-info-am \ - install-man install-pdf install-pdf-am install-pkgconfigDATA \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs installdirs-am maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am uninstall-pkgconfigDATA + dist-xz dist-zip dist-zstd distcheck distclean \ + distclean-generic distclean-hdr distclean-libtool \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-pkgconfigDATA install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-pkgconfigDATA .PRECIOUS: Makefile diff -Nru xrdp-0.9.12/librfxcodec/missing xrdp-0.9.15/librfxcodec/missing --- xrdp-0.9.12/librfxcodec/missing 2019-12-28 12:36:33.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/missing 2020-12-28 14:06:35.000000000 +0000 @@ -3,7 +3,7 @@ scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify diff -Nru xrdp-0.9.12/librfxcodec/src/amd64/Makefile.in xrdp-0.9.15/librfxcodec/src/amd64/Makefile.in --- xrdp-0.9.12/librfxcodec/src/amd64/Makefile.in 2019-12-28 12:36:34.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/src/amd64/Makefile.in 2020-12-28 14:06:35.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/librfxcodec/src/amd64/rfxencode_tile_amd64.c xrdp-0.9.15/librfxcodec/src/amd64/rfxencode_tile_amd64.c --- xrdp-0.9.12/librfxcodec/src/amd64/rfxencode_tile_amd64.c 2017-03-14 02:31:16.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/src/amd64/rfxencode_tile_amd64.c 2017-03-14 02:31:26.000000000 +0000 @@ -49,7 +49,7 @@ { LLOGLN(10, ("rfx_encode_component_rlgr1_amd64_sse2:")); if (rfxcodec_encode_dwt_shift_amd64_sse2(qtable, data, enc->dwt_buffer1, - enc->dwt_buffer) != 0) + enc->dwt_buffer) != 0) { return 1; } @@ -65,7 +65,7 @@ { LLOGLN(10, ("rfx_encode_component_rlgr3_amd64_sse2:")); if (rfxcodec_encode_dwt_shift_amd64_sse2(qtable, data, enc->dwt_buffer1, - enc->dwt_buffer) != 0) + enc->dwt_buffer) != 0) { return 1; } @@ -81,7 +81,7 @@ { LLOGLN(10, ("rfx_encode_component_rlgr1_amd64_sse41:")); if (rfxcodec_encode_dwt_shift_amd64_sse41(qtable, data, enc->dwt_buffer1, - enc->dwt_buffer) != 0) + enc->dwt_buffer) != 0) { return 1; } @@ -97,7 +97,7 @@ { LLOGLN(10, ("rfx_encode_component_rlgr3_amd64_sse41:")); if (rfxcodec_encode_dwt_shift_amd64_sse41(qtable, data, enc->dwt_buffer1, - enc->dwt_buffer) != 0) + enc->dwt_buffer) != 0) { return 1; } diff -Nru xrdp-0.9.12/librfxcodec/src/Makefile.in xrdp-0.9.15/librfxcodec/src/Makefile.in --- xrdp-0.9.12/librfxcodec/src/Makefile.in 2019-12-28 12:36:34.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/src/Makefile.in 2020-12-28 14:06:35.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/librfxcodec/src/rfx_bitstream.h xrdp-0.9.15/librfxcodec/src/rfx_bitstream.h --- xrdp-0.9.12/librfxcodec/src/rfx_bitstream.h 2017-07-06 05:01:50.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/src/rfx_bitstream.h 2017-07-06 05:02:00.000000000 +0000 @@ -32,52 +32,52 @@ typedef struct _RFX_BITSTREAM RFX_BITSTREAM; #define rfx_bitstream_attach(bs, _buffer, _nbytes) do { \ - bs.buffer = (uint8 *) (_buffer); \ - bs.nbytes = (_nbytes); \ - bs.byte_pos = 0; \ - bs.bits_left = 8; } while (0) + bs.buffer = (uint8 *) (_buffer); \ + bs.nbytes = (_nbytes); \ + bs.byte_pos = 0; \ + bs.bits_left = 8; } while (0) #define rfx_bitstream_get_bits(bs, _nbits, _r) do { \ - int nbits = _nbits; \ - int b; \ - uint16 n = 0; \ - while (bs.byte_pos < bs.nbytes && nbits > 0) \ - { \ - b = nbits; \ - if (b > bs.bits_left) \ - b = bs.bits_left; \ - if (n) \ - n <<= b; \ - n |= (bs.buffer[bs.byte_pos] >> (bs.bits_left - b)) & ((1 << b) - 1); \ - bs.bits_left -= b; \ - nbits -= b; \ - if (bs.bits_left == 0) \ + int nbits = _nbits; \ + int b; \ + uint16 n = 0; \ + while (bs.byte_pos < bs.nbytes && nbits > 0) \ { \ - bs.bits_left = 8; \ - bs.byte_pos++; \ + b = nbits; \ + if (b > bs.bits_left) \ + b = bs.bits_left; \ + if (n) \ + n <<= b; \ + n |= (bs.buffer[bs.byte_pos] >> (bs.bits_left - b)) & ((1 << b) - 1); \ + bs.bits_left -= b; \ + nbits -= b; \ + if (bs.bits_left == 0) \ + { \ + bs.bits_left = 8; \ + bs.byte_pos++; \ + } \ } \ - } \ - _r = n; } while (0) + _r = n; } while (0) #define rfx_bitstream_put_bits(bs, _bits, _nbits) do { \ - uint16 bits = (_bits); \ - int nbits = (_nbits); \ - int b; \ - while (bs.byte_pos < bs.nbytes && nbits > 0) \ - { \ - b = nbits; \ - if (b > bs.bits_left) \ - b = bs.bits_left; \ - bs.buffer[bs.byte_pos] &= ~((1 << bs.bits_left) - 1); \ - bs.buffer[bs.byte_pos] |= ((bits >> (nbits - b)) & ((1 << b) - 1)) << (bs.bits_left - b); \ - bs.bits_left -= b; \ - nbits -= b; \ - if (bs.bits_left == 0) \ + uint16 bits = (_bits); \ + int nbits = (_nbits); \ + int b; \ + while (bs.byte_pos < bs.nbytes && nbits > 0) \ { \ - bs.bits_left = 8; \ - bs.byte_pos++; \ - } \ - } } while (0) + b = nbits; \ + if (b > bs.bits_left) \ + b = bs.bits_left; \ + bs.buffer[bs.byte_pos] &= ~((1 << bs.bits_left) - 1); \ + bs.buffer[bs.byte_pos] |= ((bits >> (nbits - b)) & ((1 << b) - 1)) << (bs.bits_left - b); \ + bs.bits_left -= b; \ + nbits -= b; \ + if (bs.bits_left == 0) \ + { \ + bs.bits_left = 8; \ + bs.byte_pos++; \ + } \ + } } while (0) #define rfx_bitstream_eos(_bs) ((_bs).byte_pos >= (_bs).nbytes) #define rfx_bitstream_left(_bs) ((_bs).byte_pos >= (_bs).nbytes ? 0 : ((_bs).nbytes - (_bs).byte_pos - 1) * 8 + (_bs)->bits_left) diff -Nru xrdp-0.9.12/librfxcodec/src/rfxcommon.h xrdp-0.9.15/librfxcodec/src/rfxcommon.h --- xrdp-0.9.12/librfxcodec/src/rfxcommon.h 2017-07-06 05:01:34.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/src/rfxcommon.h 2017-07-06 05:01:44.000000000 +0000 @@ -51,37 +51,37 @@ #define stream_write_uint32(_s, _v) do { ((uint32 *) ((_s)->p))[0] = _v; (_s)->p += 4; } while (0) #else #define stream_read_uint8(_s, _v) do { \ - _v = ((uint8 *) ((_s)->p))[0]; \ - (_s)->p += 1; \ -} while (0) + _v = ((uint8 *) ((_s)->p))[0]; \ + (_s)->p += 1; \ + } while (0) #define stream_read_uint16(_s, _v) do { \ - _v = (((uint8 *) ((_s)->p))[0]) | \ - ((((uint8 *) ((_s)->p))[1]) << 8); \ - (_s)->p += 2; \ -} while (0) + _v = (((uint8 *) ((_s)->p))[0]) | \ + ((((uint8 *) ((_s)->p))[1]) << 8); \ + (_s)->p += 2; \ + } while (0) #define stream_read_uint32(_s, _v) do { \ - _v = (((uint8 *) ((_s)->p))[0]) | \ - ((((uint8 *) ((_s)->p))[1]) << 8) | \ - ((((uint8 *) ((_s)->p))[2]) << 16) | \ - ((((uint8 *) ((_s)->p))[3]) << 24); \ - (_s)->p += 4; \ -} while (0) + _v = (((uint8 *) ((_s)->p))[0]) | \ + ((((uint8 *) ((_s)->p))[1]) << 8) | \ + ((((uint8 *) ((_s)->p))[2]) << 16) | \ + ((((uint8 *) ((_s)->p))[3]) << 24); \ + (_s)->p += 4; \ + } while (0) #define stream_write_uint8(_s, _v) do { \ - ((uint8 *) ((_s)->p))[0] = _v; \ - (_s)->p += 1; \ -} while (0) + ((uint8 *) ((_s)->p))[0] = _v; \ + (_s)->p += 1; \ + } while (0) #define stream_write_uint16(_s, _v) do { \ - ((uint8 *) ((_s)->p))[0] = (uint8) (_v); \ - ((uint8 *) ((_s)->p))[1] = (uint8) ((_v) >> 8); \ - (_s)->p += 2; \ -} while (0) + ((uint8 *) ((_s)->p))[0] = (uint8) (_v); \ + ((uint8 *) ((_s)->p))[1] = (uint8) ((_v) >> 8); \ + (_s)->p += 2; \ + } while (0) #define stream_write_uint32(_s, _v) do { \ - ((uint8 *) ((_s)->p))[0] = (uint8) (_v); \ - ((uint8 *) ((_s)->p))[1] = (uint8) ((_v) >> 8); \ - ((uint8 *) ((_s)->p))[2] = (uint8) ((_v) >> 16); \ - ((uint8 *) ((_s)->p))[3] = (uint8) ((_v) >> 24); \ - (_s)->p += 4; \ -} while (0) + ((uint8 *) ((_s)->p))[0] = (uint8) (_v); \ + ((uint8 *) ((_s)->p))[1] = (uint8) ((_v) >> 8); \ + ((uint8 *) ((_s)->p))[2] = (uint8) ((_v) >> 16); \ + ((uint8 *) ((_s)->p))[3] = (uint8) ((_v) >> 24); \ + (_s)->p += 4; \ + } while (0) #endif #define stream_seek(_s, _n) (_s)->p += _n @@ -106,25 +106,25 @@ */ #if defined(__GNUC__) #define GBSR(_in, _r) do { \ - _r = __builtin_clz(_in) ^ 31; \ -} while (0) + _r = __builtin_clz(_in) ^ 31; \ + } while (0) #elif defined(_MSC_VER) && (_MSC_VER > 1000) #define GBSR(_in, _r) do { \ - unsigned long rv = 0; \ - _BitScanReverse(&rv, _in); \ - _r = rv; \ -} while (0) + unsigned long rv = 0; \ + _BitScanReverse(&rv, _in); \ + _r = rv; \ + } while (0) #else #define GBSR(_in, _r) do { \ - int rv = -1; \ - int x = _in; \ - while (x != 0) \ - { \ - rv++; \ - x = x >> 1; \ - } \ - _r = rv; \ -} while (0) + int rv = -1; \ + int x = _in; \ + while (x != 0) \ + { \ + rv++; \ + x = x >> 1; \ + } \ + _r = rv; \ + } while (0) #endif #endif diff -Nru xrdp-0.9.12/librfxcodec/src/rfxencode_alpha.c xrdp-0.9.15/librfxcodec/src/rfxencode_alpha.c --- xrdp-0.9.12/librfxcodec/src/rfxencode_alpha.c 2017-07-06 05:01:34.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/src/rfxencode_alpha.c 2017-07-06 05:01:44.000000000 +0000 @@ -75,13 +75,13 @@ #if 0 /*****************************************************************************/ #define DELTA_ONE \ -do { \ - delta = src8[cx] - src8[0]; \ - is_neg = (delta >> 7) & 1; \ - dst8[cx] = (((delta ^ -is_neg) + is_neg) << 1) - is_neg; \ - src8++; \ - dst8++; \ -} while (0) + do { \ + delta = src8[cx] - src8[0]; \ + is_neg = (delta >> 7) & 1; \ + dst8[cx] = (((delta ^ -is_neg) + is_neg) << 1) - is_neg; \ + src8++; \ + dst8++; \ + } while (0) /*****************************************************************************/ static int diff -Nru xrdp-0.9.12/librfxcodec/src/rfxencode_diff_rlgr1.c xrdp-0.9.15/librfxcodec/src/rfxencode_diff_rlgr1.c --- xrdp-0.9.12/librfxcodec/src/rfxencode_diff_rlgr1.c 2017-07-06 05:01:50.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/src/rfxencode_diff_rlgr1.c 2017-07-06 05:02:00.000000000 +0000 @@ -44,57 +44,57 @@ #define DQ_GR (3) /* decrease in kp after zero symbol in GR mode */ #define GetNextInput do { \ - input = *coef; \ - coef++; \ - coef_size--; \ -} while (0) + input = *coef; \ + coef++; \ + coef_size--; \ + } while (0) #define CheckWrite do { \ - while (bit_count >= 8) \ - { \ - bit_count -= 8; \ - *cdata = bits >> bit_count; \ - cdata++; \ - } \ -} while (0) + while (bit_count >= 8) \ + { \ + bit_count -= 8; \ + *cdata = bits >> bit_count; \ + cdata++; \ + } \ + } while (0) /* output GR code for (mag - 1) */ #define CodeGR(_krp, _lmag) do { \ - int lkr = _krp >> LSGR; \ - /* unary part of GR code */ \ - int lvk = _lmag >> lkr; \ - int llvk = lvk; \ - while (llvk >= 8) \ - { \ - bits <<= 8; \ - bits |= 0xFF; \ - llvk -= 8; \ - *cdata = bits >> bit_count; \ - cdata++; \ - } \ - bits <<= llvk; \ - bits |= (1 << llvk) - 1; \ - bit_count += llvk; \ - bits <<= 1; \ - bit_count++; \ - CheckWrite; \ - /* remainder part of GR code, if needed */ \ - if (lkr) \ - { \ - bits <<= lkr; \ - bits |= _lmag & ((1 << lkr) - 1); \ - bit_count += lkr; \ - } \ - /* update _krp, only if it is not equal to 1 */ \ - if (lvk == 0) \ - { \ - _krp = MAX(0, _krp - 2); \ - } \ - else if (lvk > 1) \ - { \ - _krp = MIN(KPMAX, _krp + lvk); \ - } \ -} while (0) + int lkr = _krp >> LSGR; \ + /* unary part of GR code */ \ + int lvk = _lmag >> lkr; \ + int llvk = lvk; \ + while (llvk >= 8) \ + { \ + bits <<= 8; \ + bits |= 0xFF; \ + llvk -= 8; \ + *cdata = bits >> bit_count; \ + cdata++; \ + } \ + bits <<= llvk; \ + bits |= (1 << llvk) - 1; \ + bit_count += llvk; \ + bits <<= 1; \ + bit_count++; \ + CheckWrite; \ + /* remainder part of GR code, if needed */ \ + if (lkr) \ + { \ + bits <<= lkr; \ + bits |= _lmag & ((1 << lkr) - 1); \ + bit_count += lkr; \ + } \ + /* update _krp, only if it is not equal to 1 */ \ + if (lvk == 0) \ + { \ + _krp = MAX(0, _krp - 2); \ + } \ + else if (lvk > 1) \ + { \ + _krp = MIN(KPMAX, _krp + lvk); \ + } \ + } while (0) int rfx_encode_diff_rlgr1(sint16 *coef, uint8 *cdata, int cdata_size) diff -Nru xrdp-0.9.12/librfxcodec/src/rfxencode_diff_rlgr3.c xrdp-0.9.15/librfxcodec/src/rfxencode_diff_rlgr3.c --- xrdp-0.9.12/librfxcodec/src/rfxencode_diff_rlgr3.c 2017-07-06 05:01:50.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/src/rfxencode_diff_rlgr3.c 2017-07-06 05:02:00.000000000 +0000 @@ -44,57 +44,57 @@ #define DQ_GR (3) /* decrease in kp after zero symbol in GR mode */ #define GetNextInput do { \ - input = *coef; \ - coef++; \ - coef_size--; \ -} while (0) + input = *coef; \ + coef++; \ + coef_size--; \ + } while (0) #define CheckWrite do { \ - while (bit_count >= 8) \ - { \ - bit_count -= 8; \ - *cdata = bits >> bit_count; \ - cdata++; \ - } \ -} while (0) + while (bit_count >= 8) \ + { \ + bit_count -= 8; \ + *cdata = bits >> bit_count; \ + cdata++; \ + } \ + } while (0) /* output GR code for (mag - 1) */ #define CodeGR(_krp, _lmag) do { \ - int lkr = _krp >> LSGR; \ - /* unary part of GR code */ \ - int lvk = _lmag >> lkr; \ - int llvk = lvk; \ - while (llvk >= 8) \ - { \ - bits <<= 8; \ - bits |= 0xFF; \ - llvk -= 8; \ - *cdata = bits >> bit_count; \ - cdata++; \ - } \ - bits <<= llvk; \ - bits |= (1 << llvk) - 1; \ - bit_count += llvk; \ - bits <<= 1; \ - bit_count++; \ - CheckWrite; \ - /* remainder part of GR code, if needed */ \ - if (lkr) \ - { \ - bits <<= lkr; \ - bits |= _lmag & ((1 << lkr) - 1); \ - bit_count += lkr; \ - } \ - /* update _krp, only if it is not equal to 1 */ \ - if (lvk == 0) \ - { \ - _krp = MAX(0, _krp - 2); \ - } \ - else if (lvk > 1) \ - { \ - _krp = MIN(KPMAX, _krp + lvk); \ - } \ -} while (0) + int lkr = _krp >> LSGR; \ + /* unary part of GR code */ \ + int lvk = _lmag >> lkr; \ + int llvk = lvk; \ + while (llvk >= 8) \ + { \ + bits <<= 8; \ + bits |= 0xFF; \ + llvk -= 8; \ + *cdata = bits >> bit_count; \ + cdata++; \ + } \ + bits <<= llvk; \ + bits |= (1 << llvk) - 1; \ + bit_count += llvk; \ + bits <<= 1; \ + bit_count++; \ + CheckWrite; \ + /* remainder part of GR code, if needed */ \ + if (lkr) \ + { \ + bits <<= lkr; \ + bits |= _lmag & ((1 << lkr) - 1); \ + bit_count += lkr; \ + } \ + /* update _krp, only if it is not equal to 1 */ \ + if (lvk == 0) \ + { \ + _krp = MAX(0, _krp - 2); \ + } \ + else if (lvk > 1) \ + { \ + _krp = MIN(KPMAX, _krp + lvk); \ + } \ + } while (0) int rfx_encode_diff_rlgr3(sint16 *coef, uint8 *cdata, int cdata_size) diff -Nru xrdp-0.9.12/librfxcodec/src/rfxencode.h xrdp-0.9.15/librfxcodec/src/rfxencode.h --- xrdp-0.9.12/librfxcodec/src/rfxencode.h 2017-12-27 14:40:05.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/src/rfxencode.h 2017-12-27 14:40:15.000000000 +0000 @@ -22,13 +22,13 @@ struct rfxencode; typedef int (*rfx_encode_rgb_to_yuv_proc)(struct rfxencode *enc, - const char *rgb_data, - int width, int height, - int stride_bytes); + const char *rgb_data, + int width, int height, + int stride_bytes); typedef int (*rfx_encode_argb_to_yuva_proc)(struct rfxencode *enc, - const char *argb_data, - int width, int height, - int stride_bytes); + const char *argb_data, + int width, int height, + int stride_bytes); typedef int (*rfx_encode_proc)(struct rfxencode *enc, const char *qtable, const uint8 *data, uint8 *buffer, int buffer_size, int *size); diff -Nru xrdp-0.9.12/librfxcodec/src/rfxencode_quantization.c xrdp-0.9.15/librfxcodec/src/rfxencode_quantization.c --- xrdp-0.9.12/librfxcodec/src/rfxencode_quantization.c 2017-07-06 05:01:34.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/src/rfxencode_quantization.c 2017-07-06 05:01:44.000000000 +0000 @@ -50,8 +50,8 @@ #if 0 #define DIVROUND(_d1, _d2) \ (_d1) < 0 ? \ - ((_d1) - ((_d2) / 2)) / (_d2) : \ - ((_d1) + ((_d2) / 2)) / (_d2) + ((_d1) - ((_d2) / 2)) / (_d2) : \ + ((_d1) + ((_d2) / 2)) / (_d2) /******************************************************************************/ static int diff -Nru xrdp-0.9.12/librfxcodec/src/rfxencode_rlgr1.c xrdp-0.9.15/librfxcodec/src/rfxencode_rlgr1.c --- xrdp-0.9.12/librfxcodec/src/rfxencode_rlgr1.c 2017-03-14 02:31:16.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/src/rfxencode_rlgr1.c 2017-03-14 02:31:26.000000000 +0000 @@ -42,90 +42,90 @@ /* Returns the least number of bits required to represent a given value */ #define GetMinBits(_val, _nbits) \ -do { \ - uint32 _v = _val; \ - _nbits = 0; \ - while (_v) \ - { \ - _v >>= 1; \ - _nbits++; \ - } \ -} while (0) + do { \ + uint32 _v = _val; \ + _nbits = 0; \ + while (_v) \ + { \ + _v >>= 1; \ + _nbits++; \ + } \ + } while (0) /* * Update the passed parameter and clamp it to the range [0, KPMAX] * Return the value of parameter right-shifted by LSGR */ #define UpdateParam(_param, _deltaP, _k) \ -do { \ - _param += _deltaP; \ - if (_param > KPMAX) \ - { \ - _param = KPMAX; \ - } \ - if (_param < 0) \ - { \ - _param = 0; \ - } \ - _k = (_param >> LSGR); \ -} while (0) + do { \ + _param += _deltaP; \ + if (_param > KPMAX) \ + { \ + _param = KPMAX; \ + } \ + if (_param < 0) \ + { \ + _param = 0; \ + } \ + _k = (_param >> LSGR); \ + } while (0) /* Returns the next coefficient (a signed int) to encode, from the input stream */ #define GetNextInput(_n) \ -do { \ - if (data_size > 0) \ - { \ - _n = *data++; \ - data_size--; \ - } \ - else \ - { \ - _n = 0; \ - } \ -} while (0) + do { \ + if (data_size > 0) \ + { \ + _n = *data++; \ + data_size--; \ + } \ + else \ + { \ + _n = 0; \ + } \ + } while (0) /* Emit bitPattern to the output bitstream */ #define OutputBits(_numBits, _bitPattern) rfx_bitstream_put_bits(bs, _bitPattern, _numBits) /* Emit a bit (0 or 1), count number of times, to the output bitstream */ #define OutputBit(_count, _bit) \ -do \ -{ \ - uint16 b = (_bit ? 0xFFFF : 0); \ - int c = _count; \ - for (; c > 0; c -= 16) \ - { \ - rfx_bitstream_put_bits(bs, b, (c > 16 ? 16 : c)); \ - } \ -} while (0) + do \ + { \ + uint16 b = (_bit ? 0xFFFF : 0); \ + int c = _count; \ + for (; c > 0; c -= 16) \ + { \ + rfx_bitstream_put_bits(bs, b, (c > 16 ? 16 : c)); \ + } \ + } while (0) /* Converts the input value to (2 * abs(input) - sign(input)), where sign(input) = (input < 0 ? 1 : 0) and returns it */ #define Get2MagSign(_input) ((_input) >= 0 ? 2 * (_input) : -2 * (_input) - 1) /* Outputs the Golomb/Rice encoding of a non-negative integer */ #define CodeGR(_krp, _val) \ -do { \ - int lkr = (_krp) >> LSGR; \ - int lval = _val; \ - /* unary part of GR code */ \ - uint32 lvk = lval >> lkr; \ - OutputBit(lvk, 1); \ - OutputBit(1, 0); \ - /* remainder part of GR code, if needed */ \ - if (lkr) \ - { \ - OutputBits(lkr, lval & ((1 << lkr) - 1)); \ - } \ - /* update krp, only if it is not equal to 1 */ \ - if (lvk == 0) \ - { \ - UpdateParam(_krp, -2, lkr); \ - } \ - else if (lvk > 1) \ - { \ - UpdateParam(_krp, lvk, lkr); \ - } \ -} while (0) + do { \ + int lkr = (_krp) >> LSGR; \ + int lval = _val; \ + /* unary part of GR code */ \ + uint32 lvk = lval >> lkr; \ + OutputBit(lvk, 1); \ + OutputBit(1, 0); \ + /* remainder part of GR code, if needed */ \ + if (lkr) \ + { \ + OutputBits(lkr, lval & ((1 << lkr) - 1)); \ + } \ + /* update krp, only if it is not equal to 1 */ \ + if (lvk == 0) \ + { \ + UpdateParam(_krp, -2, lkr); \ + } \ + else if (lvk > 1) \ + { \ + UpdateParam(_krp, lvk, lkr); \ + } \ + } while (0) int rfx_rlgr1_encode(const sint16 *data, uint8 *buffer, int buffer_size) diff -Nru xrdp-0.9.12/librfxcodec/src/rfxencode_rlgr3.c xrdp-0.9.15/librfxcodec/src/rfxencode_rlgr3.c --- xrdp-0.9.12/librfxcodec/src/rfxencode_rlgr3.c 2017-03-14 02:31:16.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/src/rfxencode_rlgr3.c 2017-03-14 02:31:26.000000000 +0000 @@ -42,90 +42,90 @@ /* Returns the least number of bits required to represent a given value */ #define GetMinBits(_val, _nbits) \ -do { \ - uint32 _v = _val; \ - _nbits = 0; \ - while (_v) \ - { \ - _v >>= 1; \ - _nbits++; \ - } \ -} while (0) + do { \ + uint32 _v = _val; \ + _nbits = 0; \ + while (_v) \ + { \ + _v >>= 1; \ + _nbits++; \ + } \ + } while (0) /* * Update the passed parameter and clamp it to the range [0, KPMAX] * Return the value of parameter right-shifted by LSGR */ #define UpdateParam(_param, _deltaP, _k) \ -do { \ - _param += _deltaP; \ - if (_param > KPMAX) \ - { \ - _param = KPMAX; \ - } \ - if (_param < 0) \ - { \ - _param = 0; \ - } \ - _k = (_param >> LSGR); \ -} while (0) + do { \ + _param += _deltaP; \ + if (_param > KPMAX) \ + { \ + _param = KPMAX; \ + } \ + if (_param < 0) \ + { \ + _param = 0; \ + } \ + _k = (_param >> LSGR); \ + } while (0) /* Returns the next coefficient (a signed int) to encode, from the input stream */ #define GetNextInput(_n) \ -do { \ - if (data_size > 0) \ - { \ - _n = *data++; \ - data_size--; \ - } \ - else \ - { \ - _n = 0; \ - } \ -} while (0) + do { \ + if (data_size > 0) \ + { \ + _n = *data++; \ + data_size--; \ + } \ + else \ + { \ + _n = 0; \ + } \ + } while (0) /* Emit bitPattern to the output bitstream */ #define OutputBits(_numBits, _bitPattern) rfx_bitstream_put_bits(bs, _bitPattern, _numBits) /* Emit a bit (0 or 1), count number of times, to the output bitstream */ #define OutputBit(_count, _bit) \ -do \ -{ \ - uint16 b = (_bit ? 0xFFFF : 0); \ - int c = _count; \ - for (; c > 0; c -= 16) \ - { \ - rfx_bitstream_put_bits(bs, b, (c > 16 ? 16 : c)); \ - } \ -} while (0) + do \ + { \ + uint16 b = (_bit ? 0xFFFF : 0); \ + int c = _count; \ + for (; c > 0; c -= 16) \ + { \ + rfx_bitstream_put_bits(bs, b, (c > 16 ? 16 : c)); \ + } \ + } while (0) /* Converts the input value to (2 * abs(input) - sign(input)), where sign(input) = (input < 0 ? 1 : 0) and returns it */ #define Get2MagSign(_input) ((_input) >= 0 ? 2 * (_input) : -2 * (_input) - 1) /* Outputs the Golomb/Rice encoding of a non-negative integer */ #define CodeGR(_krp, _val) \ -do { \ - int lkr = (_krp) >> LSGR; \ - int lval = _val; \ - /* unary part of GR code */ \ - uint32 lvk = lval >> lkr; \ - OutputBit(lvk, 1); \ - OutputBit(1, 0); \ - /* remainder part of GR code, if needed */ \ - if (lkr) \ - { \ - OutputBits(lkr, lval & ((1 << lkr) - 1)); \ - } \ - /* update krp, only if it is not equal to 1 */ \ - if (lvk == 0) \ - { \ - UpdateParam(_krp, -2, lkr); \ - } \ - else if (lvk > 1) \ - { \ - UpdateParam(_krp, lvk, lkr); \ - } \ -} while (0) + do { \ + int lkr = (_krp) >> LSGR; \ + int lval = _val; \ + /* unary part of GR code */ \ + uint32 lvk = lval >> lkr; \ + OutputBit(lvk, 1); \ + OutputBit(1, 0); \ + /* remainder part of GR code, if needed */ \ + if (lkr) \ + { \ + OutputBits(lkr, lval & ((1 << lkr) - 1)); \ + } \ + /* update krp, only if it is not equal to 1 */ \ + if (lvk == 0) \ + { \ + UpdateParam(_krp, -2, lkr); \ + } \ + else if (lvk > 1) \ + { \ + UpdateParam(_krp, lvk, lkr); \ + } \ + } while (0) int rfx_rlgr3_encode(const sint16 *data, uint8 *buffer, int buffer_size) diff -Nru xrdp-0.9.12/librfxcodec/src/x86/Makefile.in xrdp-0.9.15/librfxcodec/src/x86/Makefile.in --- xrdp-0.9.12/librfxcodec/src/x86/Makefile.in 2019-12-28 12:36:34.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/src/x86/Makefile.in 2020-12-28 14:06:35.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/librfxcodec/tests/Makefile.in xrdp-0.9.15/librfxcodec/tests/Makefile.in --- xrdp-0.9.12/librfxcodec/tests/Makefile.in 2019-12-28 12:36:34.000000000 +0000 +++ xrdp-0.9.15/librfxcodec/tests/Makefile.in 2020-12-28 14:06:35.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/libxrdp/libxrdp.c xrdp-0.9.15/libxrdp/libxrdp.c --- xrdp-0.9.12/libxrdp/libxrdp.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/libxrdp/libxrdp.c 2020-12-28 14:03:43.000000000 +0000 @@ -23,28 +23,36 @@ #endif #include "libxrdp.h" +#include "string_calls.h" #include "xrdp_orders_rail.h" -#define LOG_LEVEL 1 -#define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0) -#define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0) +#include "ms-rdpbcgr.h" + + #define MAX_BITMAP_BUF_SIZE (16 * 1024) /* 16K */ /******************************************************************************/ struct xrdp_session *EXPORT_CC -libxrdp_init(tbus id, struct trans *trans) +libxrdp_init(tbus id, struct trans *trans, const char *xrdp_ini) { struct xrdp_session *session; session = (struct xrdp_session *)g_malloc(sizeof(struct xrdp_session), 1); session->id = id; session->trans = trans; + if (xrdp_ini != NULL) + { + session->xrdp_ini = g_strdup(xrdp_ini); + } + else + { + session->xrdp_ini = g_strdup(XRDP_CFG_PATH "/xrdp.ini"); + } 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; } @@ -59,6 +67,7 @@ xrdp_orders_delete((struct xrdp_orders *)session->orders); xrdp_rdp_delete((struct xrdp_rdp *)session->rdp); + g_free(session->xrdp_ini); g_free(session); return 0; } @@ -113,7 +122,7 @@ /******************************************************************************/ /* only used during connection */ struct stream * -libxrdp_force_read(struct trans* trans) +libxrdp_force_read(struct trans *trans) { int bytes; struct stream *s; @@ -123,24 +132,18 @@ if (trans_force_read(trans, 4) != 0) { - g_writeln("libxrdp_force_read: error"); + LOG(LOG_LEVEL_WARNING, "libxrdp_force_read: header read error"); return 0; } bytes = libxrdp_get_pdu_bytes(s->data); - if (bytes < 1) - { - g_writeln("libxrdp_force_read: error"); - return 0; - } - if (bytes > 32 * 1024) + if (bytes < 4 || bytes > s->size) { - g_writeln("libxrdp_force_read: error"); + LOG(LOG_LEVEL_WARNING, "libxrdp_force_read: bad header length %d", bytes); return 0; } - if (trans_force_read(trans, bytes - 4) != 0) { - g_writeln("libxrdp_force_read: error"); + LOG(LOG_LEVEL_WARNING, "libxrdp_force_read: Can't read PDU"); return 0; } return s; @@ -161,12 +164,12 @@ do_read = s == 0; if (do_read && session->up_and_running) { - g_writeln("libxrdp_process_data: error logic"); + LOG(LOG_LEVEL_ERROR, "libxrdp_process_data: error logic"); return 1; } if (session->in_process_data != 0) { - g_writeln("libxrdp_process_data: error reentry"); + LOG(LOG_LEVEL_ERROR, "libxrdp_process_data: error reentry"); return 1; } session->in_process_data++; @@ -206,7 +209,7 @@ } if (s == 0) { - g_writeln("libxrdp_process_data: libxrdp_force_read failed"); + LOG(LOG_LEVEL_ERROR, "libxrdp_process_data: libxrdp_force_read failed"); rv = 1; break; } @@ -214,12 +217,12 @@ if (xrdp_rdp_recv(rdp, s, &code) != 0) { - g_writeln("libxrdp_process_data: xrdp_rdp_recv failed"); + LOG(LOG_LEVEL_ERROR, "libxrdp_process_data: xrdp_rdp_recv failed"); rv = 1; break; } - DEBUG(("libxrdp_process_data code %d", code)); + LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_process_data code %d", code); switch (code) { @@ -236,7 +239,7 @@ case PDUTYPE_DATAPDU: if (xrdp_rdp_process_data(rdp, s) != 0) { - DEBUG(("libxrdp_process_data returned non zero")); + LOG(LOG_LEVEL_ERROR, "libxrdp_process_data returned non zero"); cont = 0; term = 1; } @@ -244,13 +247,13 @@ case 2: /* FASTPATH_INPUT_EVENT */ if (xrdp_fastpath_process_input_event(rdp->sec_layer->fastpath_layer, s) != 0) { - DEBUG(("libxrdp_process_data returned non zero")); - cont = 0; - term = 1; + LOG(LOG_LEVEL_ERROR, "libxrdp_process_data returned non zero"); + cont = 0; + term = 1; } break; default: - g_writeln("unknown in libxrdp_process_data: code= %d", code); + LOG(LOG_LEVEL_ERROR, "unknown in libxrdp_process_data: code= %d", code); dead_lock_counter++; break; } @@ -259,8 +262,8 @@ { /*This situation can happen and this is a workaround*/ cont = 0; - g_writeln("Serious programming error: we were locked in a deadly loop"); - g_writeln("Remaining: %d", (int) (s->end - s->next_packet)); + LOG(LOG_LEVEL_ERROR, "Serious programming error: we were locked in a deadly loop"); + LOG(LOG_LEVEL_ERROR, "Remaining: %d", (int) (s->end - s->next_packet)); s->next_packet = 0; } @@ -289,7 +292,7 @@ return 0; } - DEBUG(("libxrdp_send_palette sending palette")); + LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_send_palette sending palette"); /* clear orders */ libxrdp_orders_force_send(session); @@ -298,15 +301,16 @@ if (session->client_info->use_fast_path & 1) /* fastpath output supported */ { - LLOGLN(10, ("libxrdp_send_palette: fastpath")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_palette: fastpath"); if (xrdp_rdp_init_fastpath((struct xrdp_rdp *)session->rdp, s) != 0) { free_stream(s); return 1; } } - else { - LLOGLN(10, ("libxrdp_send_palette: slowpath")); + else + { + LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_palette: slowpath"); xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s); } @@ -327,16 +331,16 @@ s_mark_end(s); if (session->client_info->use_fast_path & 1) /* fastpath output supported */ { - if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s, + if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s, FASTPATH_UPDATETYPE_PALETTE) != 0) - { - free_stream(s); - return 1; - } + { + free_stream(s); + return 1; + } } else { - xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, + xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, RDP_DATA_PDU_UPDATE); } free_stream(s); @@ -360,7 +364,7 @@ { struct stream *s = (struct stream *)NULL; - DEBUG(("libxrdp_send_bell sending bell signal")); + LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_send_bell sending bell signal"); /* see MS documentation: Server play sound PDU, TS_PLAY_SOUND_PDU_DATA */ make_stream(s); @@ -411,7 +415,7 @@ struct stream *temp_s = (struct stream *)NULL; tui32 pixel; - LLOGLN(10, ("libxrdp_send_bitmap: sending bitmap")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: sending bitmap"); Bpp = (bpp + 7) / 8; e = (4 - width) & 3; switch (bpp) @@ -431,14 +435,14 @@ line_bytes = width * Bpp; line_pad_bytes = line_bytes + e * Bpp; - LLOGLN(10, ("libxrdp_send_bitmap: bpp %d Bpp %d line_bytes %d " - "server_line_bytes %d", bpp, Bpp, line_bytes, server_line_bytes)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: bpp %d Bpp %d line_bytes %d " + "server_line_bytes %d", bpp, Bpp, line_bytes, server_line_bytes); make_stream(s); init_stream(s, MAX_BITMAP_BUF_SIZE); if (session->client_info->use_bitmap_comp) { - LLOGLN(10, ("libxrdp_send_bitmap: compression")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: compression"); make_stream(temp_s); init_stream(temp_s, 65536); i = 0; @@ -450,7 +454,7 @@ while (i > 0) { - LLOGLN(10, ("libxrdp_send_bitmap: i %d", i)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: i %d", i); total_bufsize = 0; num_updates = 0; @@ -474,22 +478,22 @@ if (bpp > 24) { - LLOGLN(10, ("libxrdp_send_bitmap: 32 bpp")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: 32 bpp"); lines_sending = xrdp_bitmap32_compress(data, width, height, s, 32, - (MAX_BITMAP_BUF_SIZE - 100) - total_bufsize, + (MAX_BITMAP_BUF_SIZE - 100) - total_bufsize, i - 1, temp_s, e, 0x10); - LLOGLN(10, ("libxrdp_send_bitmap: i %d lines_sending %d", - i, lines_sending)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: i %d lines_sending %d", + i, lines_sending); } else { lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, - (MAX_BITMAP_BUF_SIZE - 100) - total_bufsize, + (MAX_BITMAP_BUF_SIZE - 100) - total_bufsize, i - 1, temp_s, e); - LLOGLN(10, ("libxrdp_send_bitmap: i %d lines_sending %d", - i, lines_sending)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: i %d lines_sending %d", + i, lines_sending); } if (lines_sending == 0) @@ -532,29 +536,29 @@ total_bufsize += 26; /* bytes since pop layer */ } - LLOGLN(10, ("libxrdp_send_bitmap: decompressed pixels %d " - "decompressed bytes %d compressed bytes %d", - lines_sending * (width + e), - line_pad_bytes * lines_sending, bufsize)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: decompressed pixels %d " + "decompressed bytes %d compressed bytes %d", + lines_sending * (width + e), + line_pad_bytes * lines_sending, bufsize); if (j > MAX_BITMAP_BUF_SIZE) { - LLOGLN(0, ("libxrdp_send_bitmap: error, decompressed " - "size too big: %d bytes", j)); + LOG(LOG_LEVEL_WARNING, "libxrdp_send_bitmap: error, decompressed " + "size too big: %d bytes", j); } if (bufsize > MAX_BITMAP_BUF_SIZE) { - LLOGLN(0, ("libxrdp_send_bitmap: error, compressed size " - "too big: %d bytes", bufsize)); + LOG(LOG_LEVEL_WARNING, "libxrdp_send_bitmap: error, compressed size " + "too big: %d bytes", bufsize); } s->p = s->end; } while (total_bufsize < MAX_BITMAP_BUF_SIZE && i > 0); - LLOGLN(10, ("libxrdp_send_bitmap: num_updates %d total_bufsize %d", - num_updates, total_bufsize)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: num_updates %d total_bufsize %d", + num_updates, total_bufsize); p_num_updates[0] = num_updates; p_num_updates[1] = num_updates >> 8; @@ -563,8 +567,8 @@ if (total_bufsize > MAX_BITMAP_BUF_SIZE) { - LLOGLN(0, ("libxrdp_send_bitmap: error, total compressed " - "size too big: %d bytes", total_bufsize)); + LOG(LOG_LEVEL_WARNING, "libxrdp_send_bitmap: error, total compressed " + "size too big: %d bytes", total_bufsize); } } @@ -572,7 +576,7 @@ } else { - LLOGLN(10, ("libxrdp_send_bitmap: no compression")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: no compression"); total_lines = height; i = 0; p = data; @@ -591,7 +595,7 @@ if (lines_sending == 0) { - LLOGLN(0, ("libxrdp_send_bitmap: error, lines_sending == zero")); + LOG(LOG_LEVEL_WARNING, "libxrdp_send_bitmap: error, lines_sending == zero"); break; } @@ -627,7 +631,7 @@ q = q - server_line_bytes; for (k = 0; k < width; k++) { - pixel = *((tui16*)(q + k * 2)); + pixel = *((tui16 *)(q + k * 2)); out_uint16_le(s, pixel); } out_uint8s(s, e * 2); @@ -639,7 +643,7 @@ q = q - server_line_bytes; for (k = 0; k < width; k++) { - pixel = *((tui32*)(q + k * 4)); + pixel = *((tui32 *)(q + k * 4)); out_uint8(s, pixel); out_uint8(s, pixel >> 8); out_uint8(s, pixel >> 16); @@ -653,7 +657,7 @@ q = q - server_line_bytes; for (k = 0; k < width; k++) { - pixel = *((int*)(q + k * 4)); + pixel = *((int *)(q + k * 4)); out_uint32_le(s, pixel); } out_uint8s(s, e * 4); @@ -686,7 +690,7 @@ int j; int data_bytes; - DEBUG(("libxrdp_send_pointer sending cursor")); + LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_send_pointer sending cursor"); if (bpp == 0) { bpp = 24; @@ -696,14 +700,14 @@ { if (bpp != 24) { - g_writeln("libxrdp_send_pointer: error client does not support " - "new cursors and bpp is %d", bpp); + LOG(LOG_LEVEL_ERROR, "libxrdp_send_pointer: error client does not support " + "new cursors and bpp is %d", bpp); return 1; } } if ((bpp == 15) && (bpp != 16) && (bpp != 24) && (bpp != 32)) { - g_writeln("libxrdp_send_pointer: error"); + LOG(LOG_LEVEL_ERROR, "libxrdp_send_pointer: error"); return 1; } make_stream(s); @@ -711,7 +715,7 @@ if (session->client_info->use_fast_path & 1) /* fastpath output supported */ { - LLOGLN(10, ("libxrdp_send_pointer: fastpath")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_pointer: fastpath"); if (xrdp_rdp_init_fastpath((struct xrdp_rdp *)session->rdp, s) != 0) { free_stream(s); @@ -730,21 +734,21 @@ } else /* slowpath */ { - LLOGLN(10, ("libxrdp_send_pointer: slowpath")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_pointer: slowpath"); xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s); if ((session->client_info->pointer_flags & 1) == 0) - { - out_uint16_le(s, RDP_POINTER_COLOR); - out_uint16_le(s, 0); /* pad */ - data_bytes = 3072; - } - else - { - out_uint16_le(s, RDP_POINTER_POINTER); - out_uint16_le(s, 0); /* pad */ - out_uint16_le(s, bpp); - data_bytes = ((bpp + 7) / 8) * 32 * 32; - } + { + out_uint16_le(s, RDP_POINTER_COLOR); + out_uint16_le(s, 0); /* pad */ + data_bytes = 3072; + } + else + { + out_uint16_le(s, RDP_POINTER_POINTER); + out_uint16_le(s, 0); /* pad */ + out_uint16_le(s, bpp); + data_bytes = ((bpp + 7) / 8) * 32 * 32; + } } @@ -806,7 +810,7 @@ if ((session->client_info->pointer_flags & 1) == 0) { if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s, - FASTPATH_UPDATETYPE_COLOR) != 0) + FASTPATH_UPDATETYPE_COLOR) != 0) { free_stream(s); return 1; @@ -815,7 +819,7 @@ else { if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s, - FASTPATH_UPDATETYPE_POINTER) != 0) + FASTPATH_UPDATETYPE_POINTER) != 0) { free_stream(s); return 1; @@ -825,7 +829,7 @@ else { xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, - RDP_DATA_PDU_POINTER); + RDP_DATA_PDU_POINTER); } free_stream(s); return 0; @@ -837,14 +841,14 @@ { struct stream *s; - DEBUG(("libxrdp_set_pointer sending cursor index")); + LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_set_pointer sending cursor index"); make_stream(s); init_stream(s, 8192); if (session->client_info->use_fast_path & 1) /* fastpath output supported */ { - LLOGLN(10, ("libxrdp_send_pointer: fastpath")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_pointer: fastpath"); if (xrdp_rdp_init_fastpath((struct xrdp_rdp *)session->rdp, s) != 0) { free_stream(s); @@ -853,7 +857,7 @@ } else { - LLOGLN(10, ("libxrdp_send_pointer: slowpath")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_pointer: slowpath"); xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s); out_uint16_le(s, RDP_POINTER_CACHED); out_uint16_le(s, 0); /* pad */ @@ -865,7 +869,7 @@ if (session->client_info->use_fast_path & 1) /* fastpath output supported */ { if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s, - FASTPATH_UPDATETYPE_CACHED) != 0) + FASTPATH_UPDATETYPE_CACHED) != 0) { free_stream(s); return 1; @@ -874,7 +878,7 @@ else { xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, - RDP_DATA_PDU_POINTER); + RDP_DATA_PDU_POINTER); } free_stream(s); return 0; @@ -969,21 +973,21 @@ /******************************************************************************/ int -libxrdp_orders_composite_blt(struct xrdp_session* session, int srcidx, +libxrdp_orders_composite_blt(struct xrdp_session *session, int srcidx, int srcformat, int srcwidth, int srcrepeat, - int* srctransform, int mskflags, + int *srctransform, int mskflags, int mskidx, int mskformat, int mskwidth, int mskrepeat, int op, int srcx, int srcy, int mskx, int msky, int dstx, int dsty, int width, int height, int dstformat, - struct xrdp_rect* rect) + struct xrdp_rect *rect) { - return xrdp_orders_composite_blt((struct xrdp_orders*)session->orders, - srcidx, srcformat, srcwidth, srcrepeat, - srctransform, mskflags, - mskidx, mskformat, mskwidth, mskrepeat, - op, srcx, srcy, mskx, msky, dstx, dsty, - width, height, dstformat, rect); + return xrdp_orders_composite_blt((struct xrdp_orders *)session->orders, + srcidx, srcformat, srcwidth, srcrepeat, + srctransform, mskflags, + mskidx, mskformat, mskwidth, mskrepeat, + op, srcx, srcy, mskx, msky, dstx, dsty, + width, height, dstformat, rect); } /******************************************************************************/ @@ -1047,29 +1051,36 @@ } /*****************************************************************************/ +/* 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 { @@ -1082,7 +1093,12 @@ 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; @@ -1094,6 +1110,9 @@ return 1; } + /* Re-enable application input checks */ + session->check_for_app_input = 1; + return 0; } @@ -1149,7 +1168,7 @@ if (mcs->channel_list == NULL) { - g_writeln("libxrdp_query_channel - No channel initialized"); + LOG(LOG_LEVEL_ERROR, "libxrdp_query_channel - No channel initialized"); return 1 ; } @@ -1157,7 +1176,7 @@ if (index < 0 || index >= count) { - DEBUG(("libxrdp_query_channel - Channel out of range %d", index)); + LOG(LOG_LEVEL_ERROR, "libxrdp_query_channel - Channel out of range %d", index); return 1; } @@ -1167,14 +1186,14 @@ if (channel_item == 0) { /* this should not happen */ - g_writeln("libxrdp_query_channel - channel item is 0"); + LOG(LOG_LEVEL_ERROR, "libxrdp_query_channel - channel item is 0"); return 1; } if (channel_name != 0) { g_strncpy(channel_name, channel_item->name, 8); - DEBUG(("libxrdp_query_channel - Channel %d name %s", index, channel_name)); + LOG(LOG_LEVEL_ERROR, "libxrdp_query_channel - Channel %d name %s", index, channel_name); } if (channel_flags != 0) @@ -1202,7 +1221,7 @@ if (mcs->channel_list == NULL) { - g_writeln("libxrdp_get_channel_id No channel initialized"); + LOG(LOG_LEVEL_ERROR, "libxrdp_get_channel_id No channel initialized"); return -1 ; } @@ -1254,7 +1273,7 @@ if (xrdp_channel_send(chan, s, channel_id, total_data_len, flags) != 0) { - g_writeln("libxrdp_send_to_channel: error, server channel data NOT sent to client channel"); + LOG(LOG_LEVEL_ERROR, "libxrdp_send_to_channel: error, server channel data NOT sent to client channel"); free_stream(s); return 1; } @@ -1476,7 +1495,7 @@ char *out_data, int *io_len) { struct xrdp_orders *orders; - void* jpeg_han; + void *jpeg_han; orders = (struct xrdp_orders *)(session->orders); jpeg_han = orders->jpeg_han; @@ -1488,7 +1507,7 @@ /*****************************************************************************/ int EXPORT_CC libxrdp_fastpath_send_surface(struct xrdp_session *session, - char* data_pad, int pad_bytes, + char *data_pad, int pad_bytes, int data_bytes, int destLeft, int destTop, int destRight, int destBottom, int bpp, @@ -1502,7 +1521,7 @@ int max_bytes; int cmd_bytes; - LLOGLN(10, ("libxrdp_fastpath_send_surface:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_fastpath_send_surface:"); if ((session->client_info->use_fast_path & 1) == 0) { return 1; @@ -1561,7 +1580,7 @@ struct stream *s; struct xrdp_rdp *rdp; - LLOGLN(10, ("libxrdp_fastpath_send_frame_marker:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_fastpath_send_frame_marker:"); if ((session->client_info->use_fast_path & 1) == 0) { return 1; @@ -1595,7 +1614,7 @@ { struct xrdp_rdp *rdp; - LLOGLN(10, ("libxrdp_send_session_info:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_session_info:"); rdp = (struct xrdp_rdp *) (session->rdp); return xrdp_rdp_send_session_info(rdp, data, data_bytes); } diff -Nru xrdp-0.9.12/libxrdp/libxrdp.h xrdp-0.9.15/libxrdp/libxrdp.h --- xrdp-0.9.12/libxrdp/libxrdp.h 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/libxrdp/libxrdp.h 2020-12-28 14:03:43.000000000 +0000 @@ -29,6 +29,7 @@ #include "os_calls.h" #include "ssl_calls.h" #include "list.h" +#include "log.h" #include "file.h" #include "libxrdpinc.h" #include "xrdp_client_info.h" diff -Nru xrdp-0.9.12/libxrdp/libxrdpinc.h xrdp-0.9.15/libxrdp/libxrdpinc.h --- xrdp-0.9.12/libxrdp/libxrdpinc.h 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/libxrdp/libxrdpinc.h 2020-12-28 14:03:43.000000000 +0000 @@ -66,6 +66,7 @@ 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; @@ -74,6 +75,7 @@ int in_process_data; /* inc / dec libxrdp_process_data calls */ struct source_info si; + char *xrdp_ini; /* path to xrdp.ini */ }; struct xrdp_drdynvc_procs @@ -84,8 +86,16 @@ int (*data)(intptr_t id, int chan_id, char *data, int bytes); }; +/*** + * Initialise the XRDP library + * + * @param id Channel ID (xrdp_process* as integer type) + * @param trans Transport object to use for this instance + * @param xrdp_ini Path to xrdp.ini config file, or NULL for default + * @return an allocated xrdp_session object + */ struct xrdp_session * -libxrdp_init(tbus id, struct trans *trans); +libxrdp_init(tbus id, struct trans *trans, const char *xrdp_ini); int libxrdp_exit(struct xrdp_session *session); int diff -Nru xrdp-0.9.12/libxrdp/Makefile.in xrdp-0.9.15/libxrdp/Makefile.in --- xrdp-0.9.12/libxrdp/Makefile.in 2019-12-28 12:36:38.000000000 +0000 +++ xrdp-0.9.15/libxrdp/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/libxrdp/xrdp_bitmap32_compress.c xrdp-0.9.15/libxrdp/xrdp_bitmap32_compress.c --- xrdp-0.9.12/libxrdp/xrdp_bitmap32_compress.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/libxrdp/xrdp_bitmap32_compress.c 2020-12-28 14:03:43.000000000 +0000 @@ -33,11 +33,7 @@ #define FLAGS_RLE 0x10 #define FLAGS_NOALPHA 0x20 -#define LLOG_LEVEL 1 -#define LLOGLN(_level, _args) \ - do { if (_level < LLOG_LEVEL) { g_writeln _args ; } } while (0) -#define LHEXDUMP(_level, _args) \ - do { if (_level < LLOG_LEVEL) { g_hexdump _args ; } } while (0) + /*****************************************************************************/ /* split RGB */ @@ -85,9 +81,9 @@ rp |= (pixel << 8) & 0xff000000; gp |= (pixel << 16) & 0xff000000; bp |= (pixel << 24) & 0xff000000; - *((int*)(r_data + out_index)) = rp; - *((int*)(g_data + out_index)) = gp; - *((int*)(b_data + out_index)) = bp; + *((int *)(r_data + out_index)) = rp; + *((int *)(g_data + out_index)) = gp; + *((int *)(b_data + out_index)) = bp; out_index += 4; index += 4; } @@ -170,10 +166,10 @@ rp |= (pixel << 8) & 0xff000000; gp |= (pixel << 16) & 0xff000000; bp |= (pixel << 24) & 0xff000000; - *((int*)(a_data + out_index)) = ap; - *((int*)(r_data + out_index)) = rp; - *((int*)(g_data + out_index)) = gp; - *((int*)(b_data + out_index)) = bp; + *((int *)(a_data + out_index)) = ap; + *((int *)(r_data + out_index)) = rp; + *((int *)(g_data + out_index)) = gp; + *((int *)(b_data + out_index)) = bp; out_index += 4; index += 4; } @@ -209,13 +205,13 @@ /*****************************************************************************/ #define DELTA_ONE \ -do { \ - delta = src8[cx] - src8[0]; \ - is_neg = (delta >> 7) & 1; \ - dst8[cx] = (((delta ^ -is_neg) + is_neg) << 1) - is_neg; \ - src8++; \ - dst8++; \ -} while (0) + do { \ + delta = src8[cx] - src8[0]; \ + is_neg = (delta >> 7) & 1; \ + dst8[cx] = (((delta ^ -is_neg) + is_neg) << 1) - is_neg; \ + src8++; \ + dst8++; \ + } while (0) /*****************************************************************************/ static int @@ -258,7 +254,7 @@ int lreplen; int cont; - LLOGLN(10, ("fout: collen %d replen %d", collen, replen)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "fout: collen %d replen %d", collen, replen); cont = collen > 13; while (cont) { @@ -285,7 +281,7 @@ { lreplen = 47; } - LLOGLN(10, ("fout: big run lreplen %d", lreplen)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "fout: big run lreplen %d", lreplen); replen -= lreplen; code = ((lreplen & 0xF) << 4) | ((lreplen & 0xF0) >> 4); out_uint8(s, code); @@ -326,13 +322,13 @@ int collen; int replen; - LLOGLN(10, ("fpack:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "fpack:"); holdp = s->p; for (jndex = 0; jndex < cy; jndex++) { - LLOGLN(10, ("line start line %d cx %d cy %d", jndex, cx, cy)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "line start line %d cx %d cy %d", jndex, cx, cy); ptr8 = plane + jndex * cx; - LHEXDUMP(10, (ptr8, cx)); + LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "line content", ptr8, cx); lend = ptr8 + (cx - 1); colptr = ptr8; if (colptr[0] == 0) @@ -437,7 +433,7 @@ int total_bytes; int header; - LLOGLN(10, ("xrdp_bitmap32_compress:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_bitmap32_compress:"); max_bytes = 4 * 1024; /* need max 8, 4K planes for work */ if (max_bytes * 8 > temp_s->size) diff -Nru xrdp-0.9.12/libxrdp/xrdp_caps.c xrdp-0.9.15/libxrdp/xrdp_caps.c --- xrdp-0.9.12/libxrdp/xrdp_caps.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/libxrdp/xrdp_caps.c 2020-12-28 14:03:43.000000000 +0000 @@ -24,6 +24,8 @@ #endif #include "libxrdp.h" +#include "ms-rdpbcgr.h" +#include "ms-rdperp.h" /*****************************************************************************/ static int @@ -75,7 +77,7 @@ if (len < 10 + 2) { - g_writeln("xrdp_caps_process_general: error"); + LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_general: error"); return 1; } @@ -110,10 +112,10 @@ int ex_flags; int cap_flags; - DEBUG(("order capabilities")); + LOG_DEVEL(LOG_LEVEL_TRACE, "order capabilities"); if (len < 20 + 2 + 2 + 2 + 2 + 2 + 2 + 32 + 2 + 2 + 4 + 4 + 4 + 4) { - g_writeln("xrdp_caps_process_order: error"); + LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_order: error"); return 1; } in_uint8s(s, 20); /* Terminal desc, pad */ @@ -125,25 +127,23 @@ in_uint16_le(s, cap_flags); /* Capability flags */ in_uint8a(s, order_caps, 32); /* Orders supported */ g_memcpy(self->client_info.orders, order_caps, 32); - DEBUG(("dest blt-0 %d", order_caps[0])); - DEBUG(("pat blt-1 %d", order_caps[1])); - DEBUG(("screen blt-2 %d", order_caps[2])); - DEBUG(("memblt-3-13 %d %d", order_caps[3], order_caps[13])); - DEBUG(("triblt-4-14 %d %d", order_caps[4], order_caps[14])); - DEBUG(("line-8 %d", order_caps[8])); - DEBUG(("line-9 %d", order_caps[9])); - DEBUG(("rect-10 %d", order_caps[10])); - DEBUG(("desksave-11 %d", order_caps[11])); - DEBUG(("polygon-20 %d", order_caps[20])); - DEBUG(("polygon2-21 %d", order_caps[21])); - DEBUG(("polyline-22 %d", order_caps[22])); - DEBUG(("ellipse-25 %d", order_caps[25])); - DEBUG(("ellipse2-26 %d", order_caps[26])); - DEBUG(("text2-27 %d", order_caps[27])); - DEBUG(("order_caps dump")); -#if defined(XRDP_DEBUG) - g_hexdump(order_caps, 32); -#endif + LOG_DEVEL(LOG_LEVEL_TRACE, "dest blt-0 %d", order_caps[0]); + LOG_DEVEL(LOG_LEVEL_TRACE, "pat blt-1 %d", order_caps[1]); + LOG_DEVEL(LOG_LEVEL_TRACE, "screen blt-2 %d", order_caps[2]); + LOG_DEVEL(LOG_LEVEL_TRACE, "memblt-3-13 %d %d", order_caps[3], order_caps[13]); + LOG_DEVEL(LOG_LEVEL_TRACE, "triblt-4-14 %d %d", order_caps[4], order_caps[14]); + LOG_DEVEL(LOG_LEVEL_TRACE, "line-8 %d", order_caps[8]); + LOG_DEVEL(LOG_LEVEL_TRACE, "line-9 %d", order_caps[9]); + LOG_DEVEL(LOG_LEVEL_TRACE, "rect-10 %d", order_caps[10]); + LOG_DEVEL(LOG_LEVEL_TRACE, "desksave-11 %d", order_caps[11]); + LOG_DEVEL(LOG_LEVEL_TRACE, "polygon-20 %d", order_caps[20]); + LOG_DEVEL(LOG_LEVEL_TRACE, "polygon2-21 %d", order_caps[21]); + LOG_DEVEL(LOG_LEVEL_TRACE, "polyline-22 %d", order_caps[22]); + LOG_DEVEL(LOG_LEVEL_TRACE, "ellipse-25 %d", order_caps[25]); + LOG_DEVEL(LOG_LEVEL_TRACE, "ellipse2-26 %d", order_caps[26]); + LOG_DEVEL(LOG_LEVEL_TRACE, "text2-27 %d", order_caps[27]); + LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "order_caps dump", order_caps, 32); + in_uint8s(s, 2); /* Text capability flags */ /* read extended order support flags */ in_uint16_le(s, ex_flags); /* Ex flags */ @@ -153,7 +153,7 @@ self->client_info.order_flags_ex = ex_flags; if (ex_flags & XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT) { - g_writeln("xrdp_caps_process_order: bitmap cache v3 supported"); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_process_order: bitmap cache v3 supported"); self->client_info.bitmap_cache_version |= 4; } } @@ -161,15 +161,15 @@ in_uint32_le(s, i); /* desktop cache size, usually 0x38400 */ self->client_info.desktop_cache = i; - DEBUG(("desktop cache size %d", i)); + LOG_DEVEL(LOG_LEVEL_TRACE, "desktop cache size %d", i); in_uint8s(s, 4); /* Unknown */ in_uint8s(s, 4); /* Unknown */ /* check if libpainter should be used for drawing, instead of orders */ if (!(order_caps[TS_NEG_DSTBLT_INDEX] && order_caps[TS_NEG_PATBLT_INDEX] && - order_caps[TS_NEG_SCRBLT_INDEX] && order_caps[TS_NEG_MEMBLT_INDEX])) + order_caps[TS_NEG_SCRBLT_INDEX] && order_caps[TS_NEG_MEMBLT_INDEX])) { - g_writeln("xrdp_caps_process_order: not enough orders supported by client, using painter."); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_process_order: not enough orders supported by client, using painter."); self->client_info.no_orders_supported = 1; } @@ -186,7 +186,7 @@ if (len < 24 + 2 + 2 + 2 + 2 + 2 + 2) { - g_writeln("xrdp_caps_process_bmpcache: error"); + LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_bmpcache: error"); return 1; } self->client_info.bitmap_cache_version |= 1; @@ -209,12 +209,12 @@ i = MAX(i, 0); self->client_info.cache3_entries = i; in_uint16_le(s, self->client_info.cache3_size); - DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries, - self->client_info.cache1_size)); - DEBUG(("cache2 entries %d size %d", self->client_info.cache2_entries, - self->client_info.cache2_size)); - DEBUG(("cache3 entries %d size %d", self->client_info.cache3_entries, - self->client_info.cache3_size)); + LOG_DEVEL(LOG_LEVEL_TRACE, "cache1 entries %d size %d", self->client_info.cache1_entries, + self->client_info.cache1_size); + LOG_DEVEL(LOG_LEVEL_TRACE, "cache2 entries %d size %d", self->client_info.cache2_entries, + self->client_info.cache2_size); + LOG_DEVEL(LOG_LEVEL_TRACE, "cache3 entries %d size %d", self->client_info.cache3_entries, + self->client_info.cache3_size); return 0; } @@ -229,7 +229,7 @@ if (len < 2 + 2 + 4 + 4 + 4) { - g_writeln("xrdp_caps_process_bmpcache2: error"); + LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_bmpcache2: error"); return 1; } self->client_info.bitmap_cache_version |= 2; @@ -253,12 +253,12 @@ i = MAX(i, 0); self->client_info.cache3_entries = i; self->client_info.cache3_size = 4096 * Bpp; - DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries, - self->client_info.cache1_size)); - DEBUG(("cache2 entries %d size %d", self->client_info.cache2_entries, - self->client_info.cache2_size)); - DEBUG(("cache3 entries %d size %d", self->client_info.cache3_entries, - self->client_info.cache3_size)); + LOG_DEVEL(LOG_LEVEL_TRACE, "cache1 entries %d size %d", self->client_info.cache1_entries, + self->client_info.cache1_size); + LOG_DEVEL(LOG_LEVEL_TRACE, "cache2 entries %d size %d", self->client_info.cache2_entries, + self->client_info.cache2_size); + LOG_DEVEL(LOG_LEVEL_TRACE, "cache3 entries %d size %d", self->client_info.cache3_entries, + self->client_info.cache3_size); return 0; } @@ -271,11 +271,11 @@ if (len < 1) { - g_writeln("xrdp_caps_process_cache_v3_codec_id: error"); + LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_cache_v3_codec_id: error"); return 1; } in_uint8(s, codec_id); - g_writeln("xrdp_caps_process_cache_v3_codec_id: cache_v3_codec_id %d", + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_process_cache_v3_codec_id: cache_v3_codec_id %d", codec_id); self->client_info.v3_codec_id = codec_id; return 0; @@ -293,7 +293,7 @@ if (len < 2 + 2 + 2) { - g_writeln("xrdp_caps_process_pointer: error"); + LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_pointer: error"); return 1; } no_new_cursor = self->client_info.pointer_flags & 2; @@ -304,21 +304,21 @@ self->client_info.pointer_cache_entries = i; if (colorPointerFlag & 1) { - g_writeln("xrdp_caps_process_pointer: client supports " - "new(color) cursor"); + LOG(LOG_LEVEL_INFO, "xrdp_caps_process_pointer: client supports " + "new(color) cursor"); in_uint16_le(s, i); i = MIN(i, 32); self->client_info.pointer_cache_entries = i; } else { - g_writeln("xrdp_caps_process_pointer: client does not support " - "new(color) cursor"); + LOG(LOG_LEVEL_INFO, "xrdp_caps_process_pointer: client does not support " + "new(color) cursor"); } if (no_new_cursor) { - g_writeln("xrdp_caps_process_pointer: new(color) cursor is " - "disabled by config"); + LOG(LOG_LEVEL_INFO, "xrdp_caps_process_pointer: new(color) cursor is " + "disabled by config"); self->client_info.pointer_flags = 0; } return 0; @@ -352,7 +352,7 @@ if (len < 4) { - g_writeln("xrdp_caps_process_brushcache: error"); + LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_brushcache: error"); return 1; } in_uint32_le(s, code); @@ -369,7 +369,7 @@ if (len < 40 + 4 + 2 + 2) /* MS-RDPBCGR 2.2.7.1.8 */ { - g_writeln("xrdp_caps_process_glyphcache: error"); + LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_glyphcache: error"); return 1; } @@ -382,7 +382,7 @@ { self->client_info.use_cache_glyph_v2 = 1; } - g_writeln("xrdp_caps_process_glyphcache: support level %d ", + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_process_glyphcache: support level %d ", glyph_support_level); return 0; } @@ -396,7 +396,7 @@ if (len < 4 + 2 + 2) { - g_writeln("xrdp_caps_process_offscreen_bmpcache: error"); + LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_offscreen_bmpcache: error"); return 1; } in_uint32_le(s, i32); @@ -405,11 +405,11 @@ self->client_info.offscreen_cache_size = i32 * 1024; in_uint16_le(s, i32); self->client_info.offscreen_cache_entries = i32; - g_writeln("xrdp_process_offscreen_bmpcache: support level %d " - "cache size %d MB cache entries %d", - self->client_info.offscreen_support_level, - self->client_info.offscreen_cache_size, - self->client_info.offscreen_cache_entries); + LOG(LOG_LEVEL_INFO, "xrdp_process_offscreen_bmpcache: support level %d " + "cache size %d MB cache entries %d", + self->client_info.offscreen_support_level, + self->client_info.offscreen_cache_size, + self->client_info.offscreen_cache_entries); return 0; } @@ -421,13 +421,13 @@ if (len < 4) { - g_writeln("xrdp_caps_process_rail: error"); + LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_rail: error"); return 1; } in_uint32_le(s, i32); self->client_info.rail_support_level = i32; - g_writeln("xrdp_process_capset_rail: rail_support_level %d", - self->client_info.rail_support_level); + LOG(LOG_LEVEL_INFO, "xrdp_process_capset_rail: rail_support_level %d", + self->client_info.rail_support_level); return 0; } @@ -439,7 +439,7 @@ if (len < 4 + 1 + 2) { - g_writeln("xrdp_caps_process_window: error"); + LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_window: error"); return 1; } in_uint32_le(s, i32); @@ -448,11 +448,11 @@ self->client_info.wnd_num_icon_caches = i32; in_uint16_le(s, i32); self->client_info.wnd_num_icon_cache_entries = i32; - g_writeln("xrdp_process_capset_window wnd_support_level %d " - "wnd_num_icon_caches %d wnd_num_icon_cache_entries %d", - self->client_info.wnd_support_level, - self->client_info.wnd_num_icon_caches, - self->client_info.wnd_num_icon_cache_entries); + LOG(LOG_LEVEL_INFO, "xrdp_process_capset_window wnd_support_level %d " + "wnd_num_icon_caches %d wnd_num_icon_cache_entries %d", + self->client_info.wnd_support_level, + self->client_info.wnd_num_icon_caches, + self->client_info.wnd_num_icon_cache_entries); return 0; } @@ -470,7 +470,7 @@ if (len < 1) { - g_writeln("xrdp_caps_process_codecs: error"); + LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_codecs: error"); return 1; } in_uint8(s, codec_count); @@ -481,7 +481,7 @@ codec_guid = s->p; if (len < 16 + 1 + 2) { - g_writeln("xrdp_caps_process_codecs: error"); + LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_codecs: error"); return 1; } in_uint8s(s, 16); @@ -490,7 +490,7 @@ len -= 16 + 1 + 2; if (len < codec_properties_length) { - g_writeln("xrdp_caps_process_codecs: error"); + LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_codecs: error"); return 1; } len -= codec_properties_length; @@ -498,8 +498,8 @@ if (g_memcmp(codec_guid, XR_CODEC_GUID_NSCODEC, 16) == 0) { - g_writeln("xrdp_caps_process_codecs: nscodec, codec id %d, properties len %d", - codec_id, codec_properties_length); + LOG(LOG_LEVEL_INFO, "xrdp_caps_process_codecs: nscodec, codec id %d, properties len %d", + codec_id, codec_properties_length); self->client_info.ns_codec_id = codec_id; i1 = MIN(64, codec_properties_length); g_memcpy(self->client_info.ns_prop, s->p, i1); @@ -507,8 +507,8 @@ } else if (g_memcmp(codec_guid, XR_CODEC_GUID_REMOTEFX, 16) == 0) { - g_writeln("xrdp_caps_process_codecs: RemoteFX, codec id %d, properties len %d", - codec_id, codec_properties_length); + LOG(LOG_LEVEL_INFO, "xrdp_caps_process_codecs: RemoteFX, codec id %d, properties len %d", + codec_id, codec_properties_length); self->client_info.rfx_codec_id = codec_id; i1 = MIN(64, codec_properties_length); g_memcpy(self->client_info.rfx_prop, s->p, i1); @@ -516,8 +516,8 @@ } else if (g_memcmp(codec_guid, XR_CODEC_GUID_JPEG, 16) == 0) { - g_writeln("xrdp_caps_process_codecs: jpeg, codec id %d, properties len %d", - codec_id, codec_properties_length); + LOG(LOG_LEVEL_INFO, "xrdp_caps_process_codecs: jpeg, codec id %d, properties len %d", + codec_id, codec_properties_length); self->client_info.jpeg_codec_id = codec_id; i1 = MIN(64, codec_properties_length); g_memcpy(self->client_info.jpeg_prop, s->p, i1); @@ -525,16 +525,16 @@ /* make sure that requested quality is between 0 to 100 */ if (self->client_info.jpeg_prop[0] < 0 || self->client_info.jpeg_prop[0] > 100) { - g_writeln(" Warning: the requested jpeg quality (%d) is invalid," - " falling back to default", self->client_info.jpeg_prop[0]); + LOG(LOG_LEVEL_WARNING, " Warning: the requested jpeg quality (%d) is invalid, " + "falling back to default", self->client_info.jpeg_prop[0]); self->client_info.jpeg_prop[0] = 75; /* use default */ } - g_writeln(" jpeg quality set to %d", self->client_info.jpeg_prop[0]); + LOG(LOG_LEVEL_INFO, " jpeg quality set to %d", self->client_info.jpeg_prop[0]); } else if (g_memcmp(codec_guid, XR_CODEC_GUID_H264, 16) == 0) { - g_writeln("xrdp_caps_process_codecs: h264, codec id %d, properties len %d", - codec_id, codec_properties_length); + LOG(LOG_LEVEL_INFO, "xrdp_caps_process_codecs: h264, codec id %d, properties len %d", + codec_id, codec_properties_length); self->client_info.h264_codec_id = codec_id; i1 = MIN(64, codec_properties_length); g_memcpy(self->client_info.h264_prop, s->p, i1); @@ -542,7 +542,7 @@ } else { - g_writeln("xrdp_caps_process_codecs: unknown codec id %d", codec_id); + LOG(LOG_LEVEL_WARNING, "xrdp_caps_process_codecs: unknown codec id %d", codec_id); } s->p = next_guid; @@ -559,24 +559,27 @@ 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; } - /*****************************************************************************/ +/*****************************************************************************/ static int xrdp_caps_process_frame_ack(struct xrdp_rdp *self, struct stream *s, int len) { - g_writeln("xrdp_caps_process_frame_ack:"); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_process_frame_ack:"); self->client_info.use_frame_acks = 1; in_uint32_le(s, self->client_info.max_unacknowledged_frame_count); if (self->client_info.max_unacknowledged_frame_count < 0) { - g_writeln(" invalid max_unacknowledged_frame_count value (%d), setting to 0", - self->client_info.max_unacknowledged_frame_count); + LOG(LOG_LEVEL_WARNING, " invalid max_unacknowledged_frame_count value (%d), setting to 0", + self->client_info.max_unacknowledged_frame_count); self->client_info.max_unacknowledged_frame_count = 0; } - g_writeln(" max_unacknowledged_frame_count %d", self->client_info.max_unacknowledged_frame_count); + LOG_DEVEL(LOG_LEVEL_TRACE, " max_unacknowledged_frame_count %d", self->client_info.max_unacknowledged_frame_count); return 0; } @@ -585,10 +588,15 @@ xrdp_caps_process_surface_cmds(struct xrdp_rdp *self, struct stream *s, int len) { int cmdFlags; - g_writeln("xrdp_caps_process_surface_cmds:"); +#ifndef XRDP_DEBUG + /* TODO: remove UNUSED_VAR once the `cmdFlags` variable is used for more than + logging in debug mode */ + UNUSED_VAR(cmdFlags); +#endif + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_process_surface_cmds:"); in_uint32_le(s, cmdFlags); in_uint8s(s, 4); /* reserved */ - g_writeln(" cmdFlags 0x%08x", cmdFlags); + LOG_DEVEL(LOG_LEVEL_TRACE, " cmdFlags 0x%08x", cmdFlags); return 0; } @@ -604,7 +612,7 @@ int len; char *p; - DEBUG(("in xrdp_caps_process_confirm_active")); + LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_caps_process_confirm_active"); in_uint8s(s, 4); /* rdp_shareid */ in_uint8s(s, 2); /* userid */ in_uint16_le(s, source_len); /* sizeof RDP_SOURCE */ @@ -623,86 +631,86 @@ p = s->p; if (!s_check_rem(s, 4)) { - g_writeln("xrdp_caps_process_confirm_active: error 1"); + LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_confirm_active: error 1"); return 1; } in_uint16_le(s, type); in_uint16_le(s, len); if ((len < 4) || !s_check_rem(s, len - 4)) { - g_writeln("xrdp_caps_process_confirm_active: error: len %d, " - "remaining %d", len, (int) (s->end - s->p)); + LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_confirm_active: error: len %d, " + "remaining %d", len, (int) (s->end - s->p)); return 1; } len -= 4; switch (type) { case CAPSTYPE_GENERAL: - DEBUG(("CAPSTYPE_GENERAL")); + LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_GENERAL"); xrdp_caps_process_general(self, s, len); break; case CAPSTYPE_BITMAP: - DEBUG(("CAPSTYPE_BITMAP")); + LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_BITMAP"); break; case CAPSTYPE_ORDER: - DEBUG(("CAPSTYPE_ORDER")); + LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_ORDER"); xrdp_caps_process_order(self, s, len); break; case CAPSTYPE_BITMAPCACHE: - DEBUG(("CAPSTYPE_BMPCACHE")); + LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_BMPCACHE"); xrdp_caps_process_bmpcache(self, s, len); break; case CAPSTYPE_CONTROL: - DEBUG(("CAPSTYPE_CONTROL")); + LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_CONTROL"); break; case 6: xrdp_caps_process_cache_v3_codec_id(self, s, len); break; case CAPSTYPE_ACTIVATION: - DEBUG(("CAPSTYPE_ACTIVAION")); + LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_ACTIVAION"); break; case CAPSTYPE_POINTER: - DEBUG(("CAPSTYPE_POINTER")); + LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_POINTER"); xrdp_caps_process_pointer(self, s, len); break; case CAPSTYPE_SHARE: - DEBUG(("CAPSTYPE_SHARE")); + LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_SHARE"); break; case CAPSTYPE_COLORCACHE: - DEBUG(("CAPSTYPE_COLORCACHE")); + LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_COLORCACHE"); break; case CAPSTYPE_SOUND: - DEBUG(("CAPSTYPE_SOUND")); + LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_SOUND"); break; case CAPSTYPE_INPUT: xrdp_caps_process_input(self, s, len); break; case CAPSTYPE_FONT: - DEBUG(("CAPSTYPE_FONT")); + LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_FONT"); break; case CAPSTYPE_BRUSH: xrdp_caps_process_brushcache(self, s, len); break; case CAPSTYPE_GLYPHCACHE: - DEBUG(("CAPSTYPE_GLYPHCACHE")); + LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_GLYPHCACHE"); xrdp_caps_process_glyphcache(self, s, len); break; case CAPSTYPE_OFFSCREENCACHE: - DEBUG(("CAPSTYPE_OFFSCREENCACHE")); + LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_OFFSCREENCACHE"); xrdp_caps_process_offscreen_bmpcache(self, s, len); break; case CAPSTYPE_BITMAPCACHE_REV2: - DEBUG(("CAPSTYPE_BITMAPCACHE_REV2")); + LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_BITMAPCACHE_REV2"); xrdp_caps_process_bmpcache2(self, s, len); break; case CAPSTYPE_VIRTUALCHANNEL: - DEBUG(("CAPSTYPE_VIRTUALCHANNEL")); + LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_VIRTUALCHANNEL"); break; case CAPSTYPE_DRAWNINGRIDCACHE: - DEBUG(("CAPSTYPE_DRAWNINGRIDCACHE")); + LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_DRAWNINGRIDCACHE"); break; case CAPSTYPE_DRAWGDIPLUS: - DEBUG(("CAPSTYPE_DRAWGDIPLUS")); + LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_DRAWGDIPLUS"); break; case CAPSTYPE_RAIL: xrdp_caps_process_rail(self, s, len); @@ -723,7 +731,7 @@ xrdp_caps_process_frame_ack(self, s, len); break; default: - g_writeln("unknown in xrdp_caps_process_confirm_active %d", type); + LOG(LOG_LEVEL_WARNING, "unknown in xrdp_caps_process_confirm_active %d", type); break; } @@ -731,17 +739,17 @@ } if (self->client_info.no_orders_supported && - (self->client_info.offscreen_support_level != 0)) + (self->client_info.offscreen_support_level != 0)) { - g_writeln("xrdp_caps_process_confirm_active: not enough orders " - "supported by client, client wants off screen bitmap but " - "offscreen bitmaps disabled"); + LOG(LOG_LEVEL_WARNING, "xrdp_caps_process_confirm_active: not enough orders " + "supported by client, client wants off screen bitmap but " + "offscreen bitmaps disabled"); self->client_info.offscreen_support_level = 0; self->client_info.offscreen_cache_size = 0; self->client_info.offscreen_cache_entries = 0; } - DEBUG(("out xrdp_caps_process_confirm_active")); + LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_caps_process_confirm_active"); return 0; } /*****************************************************************************/ @@ -763,7 +771,7 @@ make_stream(s); init_stream(s, 8192); - DEBUG(("in xrdp_caps_send_demand_active")); + LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_caps_send_demand_active"); if (xrdp_rdp_init(self, s) != 0) { @@ -1030,16 +1038,16 @@ free_stream(s); return 1; } - DEBUG(("out (1) xrdp_caps_send_demand_active")); + LOG_DEVEL(LOG_LEVEL_TRACE, "out (1) xrdp_caps_send_demand_active"); /* send Monitor Layout PDU for dual monitor */ if (self->client_info.monitorCount > 0 && - self->client_info.multimon == 1) + self->client_info.multimon == 1) { - DEBUG(("xrdp_caps_send_demand_active: sending monitor layout pdu")); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: sending monitor layout pdu"); if (xrdp_caps_send_monitorlayout(self) != 0) { - g_writeln("xrdp_caps_send_demand_active: error sending monitor layout pdu"); + LOG(LOG_LEVEL_ERROR, "xrdp_caps_send_demand_active: error sending monitor layout pdu"); } } diff -Nru xrdp-0.9.12/libxrdp/xrdp_channel.c xrdp-0.9.15/libxrdp/xrdp_channel.c --- xrdp-0.9.12/libxrdp/xrdp_channel.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/libxrdp/xrdp_channel.c 2020-12-28 14:03:43.000000000 +0000 @@ -23,6 +23,7 @@ #endif #include "libxrdp.h" +#include "string_calls.h" /* todo, move these to constants.h */ //#define CHANNEL_CHUNK_LENGTH 1600 /* todo, why is this so small? */ @@ -51,7 +52,7 @@ if (self->mcs_layer->channel_list == NULL) { - g_writeln("xrdp_channel_get_item - No channel initialized"); + LOG(LOG_LEVEL_ERROR, "xrdp_channel_get_item - No channel initialized"); return NULL ; } @@ -114,13 +115,13 @@ if (channel == NULL) { - g_writeln("xrdp_channel_send - no such channel"); + LOG(LOG_LEVEL_ERROR, "xrdp_channel_send - no such channel"); return 1; } if (channel->disabled) { - g_writeln("xrdp_channel_send, channel disabled"); + LOG(LOG_LEVEL_WARNING, "xrdp_channel_send, channel disabled"); return 0; /* not an error */ } @@ -138,16 +139,16 @@ * * That's flag makes MSTSC crash when using RAIL channel. */ -// if (channel->flags & XR_CHANNEL_OPTION_SHOW_PROTOCOL) -// { -// flags |= CHANNEL_FLAG_SHOW_PROTOCOL; -// } + // if (channel->flags & XR_CHANNEL_OPTION_SHOW_PROTOCOL) + // { + // flags |= CHANNEL_FLAG_SHOW_PROTOCOL; + // } out_uint32_le(s, flags); if (xrdp_sec_send(self->sec_layer, s, channel->chanid) != 0) { - g_writeln("xrdp_channel_send - failure sending data"); + LOG(LOG_LEVEL_ERROR, "xrdp_channel_send - failure sending data"); return 1; } @@ -182,12 +183,12 @@ } else { - g_writeln("in xrdp_channel_call_callback, session->callback is nil"); + LOG(LOG_LEVEL_TRACE, "in xrdp_channel_call_callback, session->callback is nil"); } } else { - g_writeln("in xrdp_channel_call_callback, session is nil"); + LOG(LOG_LEVEL_TRACE, "in xrdp_channel_call_callback, session is nil"); } return rv; @@ -269,12 +270,12 @@ in_uint16_le(s, cap_version); if ((cap_version != 2) && (cap_version != 3)) { - g_writeln("drdynvc_process_capability_response: incompatible DVC " - "version %d detected", cap_version); + LOG(LOG_LEVEL_ERROR, "drdynvc_process_capability_response: incompatible DVC " + "version %d detected", cap_version); return 1; } - g_writeln("drdynvc_process_capability_response: DVC version %d selected", - cap_version); + LOG(LOG_LEVEL_INFO, "drdynvc_process_capability_response: DVC version %d selected", + cap_version); self->drdynvc_state = 1; session = self->sec_layer->rdp_layer->session; rv = session->callback(session->id, 0x5558, 0, 0, 0, 0); @@ -300,8 +301,8 @@ return 1; } in_uint32_le(s, creation_status); - //g_writeln("drdynvc_process_open_channel_response: chan_id 0x%x " - // "creation_status %d", chan_id, creation_status); + LOG_DEVEL(LOG_LEVEL_TRACE, "drdynvc_process_open_channel_response: chan_id 0x%x " + "creation_status %d", chan_id, creation_status); session = self->sec_layer->rdp_layer->session; if (chan_id > 255) { @@ -336,7 +337,7 @@ { return 1; } - //g_writeln("drdynvc_process_close_channel_response: chan_id 0x%x", chan_id); + LOG_DEVEL(LOG_LEVEL_TRACE, "drdynvc_process_close_channel_response: chan_id 0x%x", chan_id); session = self->sec_layer->rdp_layer->session; if (chan_id > 255) { @@ -393,7 +394,7 @@ in_uint32_le(s, total_bytes); } bytes = (int) (s->end - s->p); - //g_writeln("drdynvc_process_data_first: bytes %d total_bytes %d", bytes, total_bytes); + LOG_DEVEL(LOG_LEVEL_TRACE, "drdynvc_process_data_first: bytes %d total_bytes %d", bytes, total_bytes); session = self->sec_layer->rdp_layer->session; if (chan_id > 255) { @@ -423,7 +424,7 @@ return 1; } bytes = (int) (s->end - s->p); - //g_writeln("drdynvc_process_data: bytes %d", bytes); + LOG_DEVEL(LOG_LEVEL_TRACE, "drdynvc_process_data: bytes %d", bytes); session = self->sec_layer->rdp_layer->session; if (chan_id > 255) { @@ -456,13 +457,17 @@ } in_uint32_le(s, total_length); in_uint32_le(s, flags); - //g_writeln("xrdp_channel_process_drdynvc: total_length %d flags 0x%8.8x", - // total_length, flags); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_channel_process_drdynvc: total_length %d flags 0x%8.8x", + total_length, flags); ls = NULL; switch (flags & 3) { case 0: length = (int) (s->end - s->p); + if (!s_check_rem_out(self->s, length)) + { + return 1; + } out_uint8a(self->s, s->p, length); in_uint8s(s, length); return 0; @@ -471,11 +476,19 @@ make_stream(self->s); init_stream(self->s, total_length); length = (int) (s->end - s->p); + if (!s_check_rem_out(self->s, length)) + { + return 1; + } out_uint8a(self->s, s->p, length); in_uint8s(s, length); return 0; case 2: length = (int) (s->end - s->p); + if (!s_check_rem_out(self->s, length)) + { + return 1; + } out_uint8a(self->s, s->p, length); in_uint8s(s, length); ls = self->s; @@ -484,7 +497,7 @@ ls = s; break; default: - g_writeln("xrdp_channel_process_drdynvc: error"); + LOG(LOG_LEVEL_ERROR, "xrdp_channel_process_drdynvc: error"); return 1; } if (ls == NULL) @@ -492,7 +505,7 @@ return 1; } in_uint8(ls, cmd); /* read command */ - //g_writeln("xrdp_channel_process_drdynvc: cmd 0x%x", cmd); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_channel_process_drdynvc: cmd 0x%x", cmd); rv = 1; switch (cmd & 0xf0) { @@ -512,11 +525,11 @@ rv = drdynvc_process_data(self, cmd, s); break; default: - g_writeln("xrdp_channel_process_drdynvc: got unknown " + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_channel_process_drdynvc: got unknown " "command 0x%x", cmd); break; } - //g_writeln("xrdp_channel_process_drdynvc: rv %d", rv); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_channel_process_drdynvc: rv %d", rv); return rv; } @@ -544,12 +557,12 @@ channel = xrdp_channel_get_item(self, channel_id); if (channel == NULL) { - g_writeln("xrdp_channel_process, channel not found"); + LOG(LOG_LEVEL_ERROR, "xrdp_channel_process, channel not found"); return 1; } if (channel->disabled) { - g_writeln("xrdp_channel_process, channel disabled"); + LOG(LOG_LEVEL_WARNING, "xrdp_channel_process, channel disabled"); return 0; /* not an error */ } if (channel_id == self->drdynvc_channel_id) @@ -614,7 +627,7 @@ struct mcs_channel_item *ci; struct mcs_channel_item *dci; - g_writeln("xrdp_channel_drdynvc_start:"); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_channel_drdynvc_start:"); dci = NULL; count = self->mcs_layer->channel_list->count; for (index = 0; index < count; index++) @@ -714,7 +727,7 @@ return 1; } if ((self->drdynvcs[chan_id].status != XRDP_DRDYNVC_STATUS_OPEN) && - (self->drdynvcs[chan_id].status != XRDP_DRDYNVC_STATUS_OPEN_SENT)) + (self->drdynvcs[chan_id].status != XRDP_DRDYNVC_STATUS_OPEN_SENT)) { /* not open */ return 1; diff -Nru xrdp-0.9.12/libxrdp/xrdp_fastpath.c xrdp-0.9.15/libxrdp/xrdp_fastpath.c --- xrdp-0.9.12/libxrdp/xrdp_fastpath.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/libxrdp/xrdp_fastpath.c 2020-12-28 14:03:43.000000000 +0000 @@ -22,6 +22,7 @@ #endif #include "libxrdp.h" +#include "ms-rdpbcgr.h" /*****************************************************************************/ struct xrdp_fastpath * @@ -29,12 +30,12 @@ { struct xrdp_fastpath *self; - DEBUG((" in xrdp_fastpath_create")); + LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_fastpath_create"); self = (struct xrdp_fastpath *)g_malloc(sizeof(struct xrdp_fastpath), 1); self->sec_layer = owner; self->trans = trans; self->session = owner->rdp_layer->session; - DEBUG((" out xrdp_fastpath_create")); + LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_fastpath_create"); return self; } @@ -66,7 +67,7 @@ int byte; char *holdp; - DEBUG((" in xrdp_fastpath_recv")); + LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_fastpath_recv"); holdp = s->p; if (!s_check_rem(s, 2)) { @@ -96,7 +97,7 @@ len = byte; } s->next_packet = holdp + len; - DEBUG((" out xrdp_fastpath_recv")); + LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_fastpath_recv"); return 0; } @@ -145,7 +146,10 @@ { 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; } @@ -175,7 +179,9 @@ } if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_EXTENDED)) + { flags |= KBD_FLAG_EXT; + } xrdp_fastpath_session_callback(self, RDP_INPUT_SCANCODE, code, 0, flags, 0); @@ -249,13 +255,13 @@ xrdp_fastpath_process_EVENT_SYNC(struct xrdp_fastpath *self, int eventFlags, struct stream *s) { - /* - * The eventCode bitfield (3 bits in size) MUST be set to - * FASTPATH_INPUT_EVENT_SYNC (3). - * The eventFlags bitfield (5 bits in size) contains flags - * indicating the "on" - * status of the keyboard toggle keys. - */ + /* + * The eventCode bitfield (3 bits in size) MUST be set to + * FASTPATH_INPUT_EVENT_SYNC (3). + * The eventFlags bitfield (5 bits in size) contains flags + * indicating the "on" + * status of the keyboard toggle keys. + */ xrdp_fastpath_session_callback(self, RDP_INPUT_SYNCHRONIZE, eventFlags, 0, 0, 0); @@ -322,8 +328,8 @@ { case FASTPATH_INPUT_EVENT_SCANCODE: if (xrdp_fastpath_process_EVENT_SCANCODE(self, - eventFlags, - s) != 0) + eventFlags, + s) != 0) { return 1; } @@ -361,8 +367,8 @@ } break; default: - g_writeln("xrdp_fastpath_process_input_event: unknown " - "eventCode %d", eventCode); + LOG(LOG_LEVEL_WARNING, "xrdp_fastpath_process_input_event: unknown " + "eventCode %d", eventCode); break; } } diff -Nru xrdp-0.9.12/libxrdp/xrdp_iso.c xrdp-0.9.15/libxrdp/xrdp_iso.c --- xrdp-0.9.12/libxrdp/xrdp_iso.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/libxrdp/xrdp_iso.c 2020-12-28 14:03:43.000000000 +0000 @@ -24,15 +24,10 @@ #endif #include "libxrdp.h" +#include "ms-rdpbcgr.h" #include "log.h" -#define LOG_LEVEL 1 -#define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0) -#define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0) -#define LHEXDUMP(_level, _args) \ - do { if (_level < LOG_LEVEL) { g_hexdump _args ; } } while (0) + /*****************************************************************************/ @@ -41,11 +36,11 @@ { struct xrdp_iso *self; - LLOGLN(10, (" in xrdp_iso_create")); + LOG_DEVEL(LOG_LEVEL_DEBUG, " in xrdp_iso_create"); self = (struct xrdp_iso *) g_malloc(sizeof(struct xrdp_iso), 1); self->mcs_layer = owner; self->trans = trans; - LLOGLN(10, (" out xrdp_iso_create")); + LOG_DEVEL(LOG_LEVEL_DEBUG, " out xrdp_iso_create"); return self; } @@ -79,11 +74,11 @@ if (self->requestedProtocol & PROTOCOL_SSL) { if (!g_file_readable(client_info->certificate) || - !g_file_readable(client_info->key_file)) + !g_file_readable(client_info->key_file)) { /* certificate or privkey is not readable */ - log_message(LOG_LEVEL_DEBUG, "No readable certificates or " - "private keys, cannot accept TLS connections"); + LOG(LOG_LEVEL_WARNING, "No readable certificates or " + "private keys, cannot accept TLS connections"); self->failureCode = SSL_CERT_NOT_ON_SERVER; rv = 1; /* error */ } @@ -102,8 +97,8 @@ case PROTOCOL_HYBRID_EX: default: if ((self->requestedProtocol & PROTOCOL_SSL) && - g_file_readable(client_info->certificate) && - g_file_readable(client_info->key_file)) + g_file_readable(client_info->certificate) && + g_file_readable(client_info->key_file)) { /* that's a patch since we don't support CredSSP for now */ self->selectedProtocol = PROTOCOL_SSL; @@ -115,8 +110,8 @@ break; } - log_message(LOG_LEVEL_DEBUG, "Security layer: requested %d, selected %d", - self->requestedProtocol, self->selectedProtocol); + LOG(LOG_LEVEL_DEBUG, "Security layer: requested %d, selected %d", + self->requestedProtocol, self->selectedProtocol); return rv; } @@ -128,73 +123,90 @@ int flags; int len; + if (!s_check_rem(s, 7)) + { + LOG(LOG_LEVEL_ERROR, "xrdp_iso_process_rdpNegReq: unexpected end-of-record"); + return 1; + } + in_uint8(s, flags); if (flags != 0x0 && flags != 0x8 && flags != 0x1) { - LLOGLN(10, ("xrdp_iso_process_rdpNegReq: error, flags: %x",flags)); + LOG(LOG_LEVEL_ERROR, "xrdp_iso_process_rdpNegReq: error, flags: %x", flags); return 1; } in_uint16_le(s, len); if (len != 8) { - LLOGLN(10, ("xrdp_iso_process_rdpNegReq: error, length: %x",len)); + LOG(LOG_LEVEL_ERROR, "xrdp_iso_process_rdpNegReq: error, length: %x", len); return 1; } in_uint32_le(s, self->requestedProtocol); if (self->requestedProtocol > 0xb) { - LLOGLN(10, ("xrdp_iso_process_rdpNegReq: error, requestedProtocol: %x", - self->requestedProtocol)); + LOG(LOG_LEVEL_ERROR, "xrdp_iso_process_rdpNegReq: error, requestedProtocol: %x", + self->requestedProtocol); return 1; } 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; if (s != self->trans->in_s) { - LLOGLN(10, ("xrdp_iso_recv_msg error logic")); + LOG(LOG_LEVEL_WARNING, "xrdp_iso_recv_msg error logic"); } - in_uint8(s, ver); - - if (ver != 3) + /* TPKT header is 4 bytes, then first 2 bytes of the X.224 CR-TPDU */ + if (!s_check_rem(s, 6)) { - LLOGLN(10, ("xrdp_iso_recv_msg: bad ver")); - LHEXDUMP(10, (s->data, 4)); return 1; } - in_uint8s(s, 1); - in_uint16_be(s, plen); + in_uint8(s, ver); + in_uint8s(s, 3); /* Skip reserved field, plus length */ + in_uint8(s, *len); + in_uint8(s, *code); - if (plen < 4) + if (ver != 3) { + LOG(LOG_LEVEL_ERROR, "xrdp_iso_recv_msg: bad ver"); + LOG_DEVEL_HEXDUMP(LOG_LEVEL_ERROR, "header", s->data, 4); return 1; } - if (!s_check_rem(s, 2)) + if (*len == 255) { + /* X.224 13.2.1 - reserved value */ + LOG(LOG_LEVEL_ERROR, "xrdp_iso_recv_msg: reserved length encountered"); + LOG_DEVEL_HEXDUMP(LOG_LEVEL_ERROR, "header", s->data, 4); 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; @@ -203,6 +215,7 @@ } else { + /* Other supported PDUs : X.224 13.x */ if (!s_check_rem(s, 5)) { return 1; @@ -221,21 +234,21 @@ int code; int len; - LLOGLN(10, (" in xrdp_iso_recv")); + LOG_DEVEL(LOG_LEVEL_DEBUG, " in xrdp_iso_recv"); if (xrdp_iso_recv_msg(self, s, &code, &len) != 0) { - LLOGLN(10, (" out xrdp_iso_recv xrdp_iso_recv_msg return non zero")); + LOG(LOG_LEVEL_ERROR, " out xrdp_iso_recv xrdp_iso_recv_msg return non zero"); return 1; } if (code != ISO_PDU_DT || len != 2) { - LLOGLN(10, (" out xrdp_iso_recv code != ISO_PDU_DT or length != 2")); + LOG(LOG_LEVEL_ERROR, " out xrdp_iso_recv code != ISO_PDU_DT or length != 2"); return 1; } - LLOGLN(10, (" out xrdp_iso_recv")); + LOG_DEVEL(LOG_LEVEL_DEBUG, " out xrdp_iso_recv"); return 0; } /*****************************************************************************/ @@ -301,7 +314,20 @@ 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) @@ -309,35 +335,47 @@ 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")); + LOG_DEVEL(LOG_LEVEL_DEBUG, " in xrdp_iso_incoming"); s = libxrdp_force_read(self->trans); - if (s == 0) + if (s == NULL) { return 1; } if (xrdp_iso_recv_msg(self, s, &code, &len) != 0) { - LLOGLN(0, ("xrdp_iso_incoming: xrdp_iso_recv_msg returned non zero")); + LOG(LOG_LEVEL_ERROR, "xrdp_iso_incoming: xrdp_iso_recv_msg returned non zero"); + return 1; + } + + if (code != ISO_PDU_CR) + { return 1; } - if ((code != ISO_PDU_CR) || (len < 6)) + /* + * 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) { + LOG(LOG_LEVEL_ERROR, "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) @@ -348,34 +386,36 @@ self->rdpNegData = 1; if (xrdp_iso_process_rdp_neg_req(self, s) != 0) { - LLOGLN(0, ("xrdp_iso_incoming: xrdp_iso_process_rdpNegReq returned non zero")); + LOG(LOG_LEVEL_ERROR, "xrdp_iso_incoming: xrdp_iso_process_rdpNegReq returned non zero"); return 1; } break; case RDP_CORRELATION_INFO: /* rdpCorrelationInfo 6 */ // TODO + if (!s_check_rem(s, 1 + 2 + 16 + 16)) + { + LOG(LOG_LEVEL_ERROR, "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_uint8(s, cc_type); + if (cc_type == 0x0D && s_check_rem(s, 1)) { - in_uint8s(s, 2); - text[cookie_index] = 0; - cookie_index = 0; - if (g_strlen(text) > 0) + in_uint8(s, cc_type); + if (cc_type == 0x0A) { + break; } - break; } - in_uint8(s, cc_type); } break; } @@ -387,11 +427,11 @@ /* send connection confirm back to client */ if (xrdp_iso_send_cc(self) != 0) { - LLOGLN(0, ("xrdp_iso_incoming: xrdp_iso_send_cc returned non zero")); + LOG(LOG_LEVEL_ERROR, "xrdp_iso_incoming: xrdp_iso_send_cc returned non zero"); return 1; } - LLOGLN(10, (" out xrdp_iso_incoming")); + LOG_DEVEL(LOG_LEVEL_DEBUG, " out xrdp_iso_incoming"); return rv; } @@ -412,7 +452,7 @@ { int len; - LLOGLN(10, (" in xrdp_iso_send")); + LOG_DEVEL(LOG_LEVEL_DEBUG, " in xrdp_iso_send"); s_pop_layer(s, iso_hdr); len = (int) (s->end - s->p); out_uint8(s, 3); @@ -427,6 +467,6 @@ return 1; } - LLOGLN(10, (" out xrdp_iso_send")); + LOG_DEVEL(LOG_LEVEL_DEBUG, " out xrdp_iso_send"); return 0; } diff -Nru xrdp-0.9.12/libxrdp/xrdp_jpeg_compress.c xrdp-0.9.15/libxrdp/xrdp_jpeg_compress.c --- xrdp-0.9.12/libxrdp/xrdp_jpeg_compress.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/libxrdp/xrdp_jpeg_compress.c 2020-12-28 14:03:43.000000000 +0000 @@ -55,12 +55,12 @@ if (bpp != 24) { - g_writeln("xrdp_jpeg_compress: bpp wrong %d", bpp); + LOG(LOG_LEVEL_WARNING, "xrdp_jpeg_compress: bpp wrong %d", bpp); return height; } if (handle == 0) { - g_writeln("xrdp_jpeg_compress: handle is nil"); + LOG(LOG_LEVEL_WARNING, "xrdp_jpeg_compress: handle is nil"); return height; } tj_han = (tjhandle) handle; @@ -70,7 +70,7 @@ temp_buf = 0; if (e == 0) { - src_buf = (unsigned char*)in_data; + src_buf = (unsigned char *)in_data; } else { @@ -97,15 +97,15 @@ } src_buf = (unsigned char *) temp_buf; } - dst_buf = (unsigned char*)(s->p); + dst_buf = (unsigned char *)(s->p); error = tjCompress(tj_han, src_buf, width + e, (width + e) * 4, height, TJPF_XBGR, dst_buf, &cdata_bytes, TJSAMP_420, quality, 0); if (error != 0) { - log_message(LOG_LEVEL_ERROR, - "xrdp_jpeg_compress: tjCompress error: %s", - tjGetErrorStr()); + LOG(LOG_LEVEL_ERROR, + "xrdp_jpeg_compress: tjCompress error: %s", + tjGetErrorStr()); } s->p += cdata_bytes; @@ -132,8 +132,8 @@ int quality, /* higher numbers compress less */ char *out_data, /* dest for jpg image */ int *io_len /* length of out_data and on return */ - /* len of compressed data */ - ) + /* len of compressed data */ + ) { tjhandle tj_han; int error; @@ -147,7 +147,7 @@ if (handle == 0) { - g_writeln("xrdp_codec_jpeg_compress: handle is nil"); + LOG(LOG_LEVEL_WARNING, "xrdp_codec_jpeg_compress: handle is nil"); return height; } @@ -185,12 +185,12 @@ TJSAMP_420, /* jpeg sub sample */ quality, /* jpeg quality */ 0 /* flags */ - ); + ); if (error != 0) { - log_message(LOG_LEVEL_ERROR, - "xrdp_codec_jpeg_compress: tjCompress error: %s", - tjGetErrorStr()); + LOG(LOG_LEVEL_ERROR, + "xrdp_codec_jpeg_compress: tjCompress error: %s", + tjGetErrorStr()); } *io_len = lio_len; @@ -303,7 +303,7 @@ jpeg_create_compress(&cinfo); memset(&md, 0, sizeof(md)); md.cb = comp_data, - md.cb_bytes = *comp_data_bytes; + md.cb_bytes = *comp_data_bytes; cinfo.client_data = &md; memset(&dst_mgr, 0, sizeof(dst_mgr)); dst_mgr.init_destination = my_init_destination; @@ -400,7 +400,7 @@ } else { - g_writeln("bpp wrong %d", bpp); + LOG(LOG_LEVEL_WARNING, "bpp wrong %d", bpp); } cdata_bytes = byte_limit; diff -Nru xrdp-0.9.12/libxrdp/xrdp_mcs.c xrdp-0.9.15/libxrdp/xrdp_mcs.c --- xrdp-0.9.12/libxrdp/xrdp_mcs.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/libxrdp/xrdp_mcs.c 2020-12-28 14:03:43.000000000 +0000 @@ -23,6 +23,7 @@ #endif #include "libxrdp.h" +#include "ms-rdpbcgr.h" #include "log.h" /*****************************************************************************/ @@ -33,7 +34,7 @@ { struct xrdp_mcs *self; - DEBUG((" in xrdp_mcs_create")); + LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_create"); self = (struct xrdp_mcs *)g_malloc(sizeof(struct xrdp_mcs), 1); self->sec_layer = owner; self->userid = 1; @@ -42,7 +43,7 @@ self->server_mcs_data = server_mcs_data; self->iso_layer = xrdp_iso_create(self, trans); self->channel_list = list_create(); - DEBUG((" out xrdp_mcs_create")); + LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_create"); return self; } @@ -73,7 +74,7 @@ xrdp_iso_delete(self->iso_layer); /* make sure we get null pointer exception if struct is used again. */ - DEBUG(("xrdp_mcs_delete processed")) + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mcs_delete processed"); g_memset(self, 0, sizeof(struct xrdp_mcs)) ; g_free(self); } @@ -86,14 +87,14 @@ { struct stream *s; - DEBUG((" in xrdp_mcs_send_cjcf")); + LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_send_cjcf"); make_stream(s); init_stream(s, 8192); if (xrdp_iso_init(self->iso_layer, s) != 0) { free_stream(s); - DEBUG((" out xrdp_mcs_send_cjcf error")); + LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send_cjcf error"); return 1; } @@ -107,12 +108,12 @@ if (xrdp_iso_send(self->iso_layer, s) != 0) { free_stream(s); - DEBUG((" out xrdp_mcs_send_cjcf error")); + LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send_cjcf error"); return 1; } free_stream(s); - DEBUG((" out xrdp_mcs_send_cjcf")); + LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_send_cjcf"); return 0; } @@ -126,14 +127,14 @@ int len; int userid; int chanid; - DEBUG((" in xrdp_mcs_recv")); + LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_recv"); while (1) { if (xrdp_iso_recv(self->iso_layer, s) != 0) { - DEBUG((" out xrdp_mcs_recv, xrdp_iso_recv return non zero")); - g_writeln("xrdp_mcs_recv: xrdp_iso_recv failed"); + LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_recv, xrdp_iso_recv return non zero"); + LOG(LOG_LEVEL_ERROR, "xrdp_mcs_recv: xrdp_iso_recv failed"); return 1; } @@ -147,8 +148,8 @@ if (appid == MCS_DPUM) /* Disconnect Provider Ultimatum */ { - g_writeln("received Disconnect Provider Ultimatum"); - DEBUG((" out xrdp_mcs_recv appid != MCS_DPUM")); + LOG(LOG_LEVEL_ERROR, "received Disconnect Provider Ultimatum"); + LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_recv appid != MCS_DPUM"); return 1; } @@ -163,18 +164,18 @@ in_uint16_be(s, userid); in_uint16_be(s, chanid); - log_message(LOG_LEVEL_DEBUG,"MCS_CJRQ - channel join request received"); - DEBUG(("xrdp_mcs_recv adding channel %4.4x", chanid)); + LOG(LOG_LEVEL_DEBUG, "MCS_CJRQ - channel join request received"); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mcs_recv adding channel %4.4x", chanid); if (xrdp_mcs_send_cjcf(self, userid, chanid) != 0) { - log_message(LOG_LEVEL_ERROR,"Non handled error from xrdp_mcs_send_cjcf") ; + LOG(LOG_LEVEL_ERROR, "Non handled error from xrdp_mcs_send_cjcf") ; } s = libxrdp_force_read(self->iso_layer->trans); if (s == 0) { - g_writeln("xrdp_mcs_recv: libxrdp_force_read failed"); + LOG(LOG_LEVEL_ERROR, "xrdp_mcs_recv: libxrdp_force_read failed"); return 1; } @@ -187,7 +188,7 @@ } else { - log_message(LOG_LEVEL_DEBUG,"Received an unhandled appid:%d",appid); + LOG(LOG_LEVEL_DEBUG, "Received an unhandled appid:%d", appid); } break; @@ -195,7 +196,7 @@ if (appid != MCS_SDRQ) { - DEBUG((" out xrdp_mcs_recv err got 0x%x need MCS_SDRQ", appid)); + LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_recv err got 0x%x need MCS_SDRQ", appid); return 1; } @@ -218,7 +219,7 @@ in_uint8s(s, 1); } - DEBUG((" out xrdp_mcs_recv")); + LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_recv"); return 0; } @@ -436,7 +437,7 @@ int opcode; struct stream *s; - DEBUG((" in xrdp_mcs_recv_edrq")); + LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_recv_edrq"); s = libxrdp_force_read(self->iso_layer->trans); if (s == 0) @@ -483,7 +484,7 @@ return 1; } - DEBUG((" out xrdp_mcs_recv_edrq")); + LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_recv_edrq"); return 0; } @@ -495,7 +496,7 @@ int opcode; struct stream *s; - DEBUG((" in xrdp_mcs_recv_aurq")); + LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_recv_aurq"); s = libxrdp_force_read(self->iso_layer->trans); if (s == 0) @@ -534,7 +535,7 @@ return 1; } - DEBUG((" out xrdp_mcs_recv_aurq")); + LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_recv_aurq"); return 0; } @@ -545,14 +546,14 @@ { struct stream *s; - DEBUG((" in xrdp_mcs_send_aucf")); + LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_send_aucf"); make_stream(s); init_stream(s, 8192); if (xrdp_iso_init(self->iso_layer, s) != 0) { free_stream(s); - DEBUG((" out xrdp_mcs_send_aucf error")); + LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send_aucf error"); return 1; } @@ -564,12 +565,12 @@ if (xrdp_iso_send(self->iso_layer, s) != 0) { free_stream(s); - DEBUG((" out xrdp_mcs_send_aucf error")); + LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send_aucf error"); return 1; } free_stream(s); - DEBUG((" out xrdp_mcs_send_aucf")); + LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_send_aucf"); return 0; } @@ -721,8 +722,8 @@ int index; int channel; int gcc_size; - char* gcc_size_ptr; - char* ud_ptr; + char *gcc_size_ptr; + char *ud_ptr; num_channels = self->mcs_layer->channel_list->count; num_channels_even = num_channels + (num_channels & 1); @@ -765,7 +766,7 @@ out_uint8(s, 0); if (self->mcs_layer->iso_layer->rdpNegData) { - /* RequestedProtocol */ + /* RequestedProtocol */ out_uint32_le(s, self->mcs_layer->iso_layer->requestedProtocol); } out_uint16_le(s, SEC_TAG_SRV_CHANNELS); @@ -788,7 +789,7 @@ if (self->rsa_key_bytes == 64) { - g_writeln("xrdp_sec_out_mcs_data: using 512 bit RSA key"); + LOG(LOG_LEVEL_DEBUG, "xrdp_sec_out_mcs_data: using 512 bit RSA key"); out_uint16_le(s, SEC_TAG_SRV_CRYPT); out_uint16_le(s, 0x00ec); /* len is 236 */ out_uint32_le(s, self->crypt_method); @@ -818,7 +819,7 @@ } else if (self->rsa_key_bytes == 256) { - g_writeln("xrdp_sec_out_mcs_data: using 2048 bit RSA key"); + LOG(LOG_LEVEL_DEBUG, "xrdp_sec_out_mcs_data: using 2048 bit RSA key"); out_uint16_le(s, SEC_TAG_SRV_CRYPT); out_uint16_le(s, 0x01ac); /* len is 428 */ out_uint32_le(s, self->crypt_method); @@ -848,7 +849,7 @@ } else if (self->rsa_key_bytes == 0) /* no security */ { - g_writeln("xrdp_sec_out_mcs_data: using no security"); + LOG(LOG_LEVEL_DEBUG, "xrdp_sec_out_mcs_data: using no security"); out_uint16_le(s, SEC_TAG_SRV_CRYPT); out_uint16_le(s, 12); /* len is 12 */ out_uint32_le(s, self->crypt_method); @@ -856,7 +857,7 @@ } else { - g_writeln("xrdp_sec_out_mcs_data: error"); + LOG(LOG_LEVEL_ERROR, "xrdp_sec_out_mcs_data: error"); } /* end certificate */ s_mark_end(s); @@ -875,14 +876,14 @@ int data_len; struct stream *s; - DEBUG((" in xrdp_mcs_send_connect_response")); + LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_send_connect_response"); make_stream(s); init_stream(s, 8192); data_len = (int) (self->server_mcs_data->end - self->server_mcs_data->data); xrdp_iso_init(self->iso_layer, s); //TODO: we should calculate the whole length include MCS_CONNECT_RESPONSE xrdp_mcs_ber_out_header(self, s, MCS_CONNECT_RESPONSE, - data_len > 0x80 ? data_len + 38 : data_len + 36); + data_len > 0x80 ? data_len + 38 : data_len + 36); xrdp_mcs_ber_out_header(self, s, BER_TAG_RESULT, 1); out_uint8(s, 0); xrdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 1); @@ -896,12 +897,12 @@ if (xrdp_iso_send(self->iso_layer, s) != 0) { free_stream(s); - DEBUG((" out xrdp_mcs_send_connect_response error")); + LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send_connect_response error"); return 1; } free_stream(s); - DEBUG((" out xrdp_mcs_send_connect_response")); + LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_send_connect_response"); return 0; } @@ -912,7 +913,7 @@ { int index; - DEBUG((" in xrdp_mcs_incoming")); + LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_incoming"); if (xrdp_mcs_recv_connect_initial(self) != 0) { @@ -958,13 +959,13 @@ } if (xrdp_mcs_send_cjcf(self, self->userid, - self->userid + MCS_USERCHANNEL_BASE + index) != 0) + self->userid + MCS_USERCHANNEL_BASE + index) != 0) { return 1; } } - DEBUG((" out xrdp_mcs_incoming")); + LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_incoming"); return 0; } @@ -996,17 +997,20 @@ { 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 { - g_writeln("in xrdp_mcs_send, session->callback is nil"); + LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_mcs_send, session->callback is nil"); } } else { - g_writeln("in xrdp_mcs_send, session is nil"); + LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_mcs_send, session is nil"); } return rv; @@ -1021,13 +1025,13 @@ char *lp; //static int max_len = 0; - DEBUG((" in xrdp_mcs_send")); + LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_send"); s_pop_layer(s, mcs_hdr); len = (s->end - s->p) - 8; if (len > 8192 * 2) { - g_writeln("error in xrdp_mcs_send, size too big: %d bytes", len); + LOG(LOG_LEVEL_WARNING, "error in xrdp_mcs_send, size too big: %d bytes", len); } //if (len > max_len) @@ -1064,7 +1068,7 @@ if (xrdp_iso_send(self->iso_layer, s) != 0) { - DEBUG((" out xrdp_mcs_send error")); + LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send error"); return 1; } @@ -1075,7 +1079,7 @@ xrdp_mcs_call_callback(self); } - DEBUG((" out xrdp_mcs_send")); + LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_send"); return 0; } @@ -1093,11 +1097,11 @@ trans_shutdown_tls_mode(self->iso_layer->trans); g_tcp_close(self->iso_layer->trans->sck); self->iso_layer->trans->sck = 0 ; - g_writeln("xrdp_mcs_disconnect - socket closed"); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mcs_disconnect - socket closed"); return; } } - g_writeln("Failed to close socket"); + LOG_DEVEL(LOG_LEVEL_TRACE, "Failed to close socket"); } /*****************************************************************************/ @@ -1107,7 +1111,7 @@ { struct stream *s; - DEBUG((" in xrdp_mcs_disconnect")); + LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_disconnect"); make_stream(s); init_stream(s, 8192); @@ -1115,7 +1119,7 @@ { free_stream(s); close_rdp_socket(self); - DEBUG((" out xrdp_mcs_disconnect error - 1")); + LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_disconnect error - 1"); return 1; } @@ -1127,12 +1131,12 @@ { free_stream(s); close_rdp_socket(self); - DEBUG((" out xrdp_mcs_disconnect error - 2")); + LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_disconnect error - 2"); return 1; } free_stream(s); close_rdp_socket(self); - DEBUG(("xrdp_mcs_disconnect - close sent")); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mcs_disconnect - close sent"); return 0; } diff -Nru xrdp-0.9.12/libxrdp/xrdp_mppc_enc.c xrdp-0.9.15/libxrdp/xrdp_mppc_enc.c --- xrdp-0.9.12/libxrdp/xrdp_mppc_enc.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/libxrdp/xrdp_mppc_enc.c 2020-12-28 14:03:43.000000000 +0000 @@ -24,14 +24,6 @@ #include "libxrdp.h" -#define MPPC_ENC_DEBUG 0 - -#if MPPC_ENC_DEBUG -#define DLOG(_args) g_printf _args -#else -#define DLOG(_args) do { } while (0) -#endif - /* local defines */ #define RDP_40_HIST_BUF_LEN (1024 * 8) /* RDP 4.0 uses 8K history buf */ @@ -49,7 +41,7 @@ #define CRC_INIT 0xFFFF #define CRC(_crcval, _newchar) _crcval = \ - ((_crcval) >> 8) ^ g_crc_table[((_crcval) ^ (_newchar)) & 0x00ff] + ((_crcval) >> 8) ^ g_crc_table[((_crcval) ^ (_newchar)) & 0x00ff] /* CRC16 defs */ static const tui16 g_crc_table[256] = @@ -92,336 +84,336 @@ insert 2 bits into outputBuffer ******************************************************************************/ #define insert_2_bits(_data) \ -do \ -{ \ - if ((bits_left >= 3) && (bits_left <= 8)) \ - { \ - i = bits_left - 2; \ - outputBuffer[opb_index] |= _data << i; \ - bits_left = i; \ - } \ - else \ + do \ { \ - i = 2 - bits_left; \ - j = 8 - i; \ - outputBuffer[opb_index++] |= _data >> i; \ - outputBuffer[opb_index] |= _data << j; \ - bits_left = j; \ - } \ -} while (0) + if ((bits_left >= 3) && (bits_left <= 8)) \ + { \ + i = bits_left - 2; \ + outputBuffer[opb_index] |= _data << i; \ + bits_left = i; \ + } \ + else \ + { \ + i = 2 - bits_left; \ + j = 8 - i; \ + outputBuffer[opb_index++] |= _data >> i; \ + outputBuffer[opb_index] |= _data << j; \ + bits_left = j; \ + } \ + } while (0) /***************************************************************************** insert 3 bits into outputBuffer ******************************************************************************/ #define insert_3_bits(_data) \ -do \ -{ \ - if ((bits_left >= 4) && (bits_left <= 8)) \ - { \ - i = bits_left - 3; \ - outputBuffer[opb_index] |= _data << i; \ - bits_left = i; \ - } \ - else \ + do \ { \ - i = 3 - bits_left; \ - j = 8 - i; \ - outputBuffer[opb_index++] |= _data >> i; \ - outputBuffer[opb_index] |= _data << j; \ - bits_left = j; \ - } \ -} while (0) + if ((bits_left >= 4) && (bits_left <= 8)) \ + { \ + i = bits_left - 3; \ + outputBuffer[opb_index] |= _data << i; \ + bits_left = i; \ + } \ + else \ + { \ + i = 3 - bits_left; \ + j = 8 - i; \ + outputBuffer[opb_index++] |= _data >> i; \ + outputBuffer[opb_index] |= _data << j; \ + bits_left = j; \ + } \ + } while (0) /***************************************************************************** insert 4 bits into outputBuffer ******************************************************************************/ #define insert_4_bits(_data) \ -do \ -{ \ - if ((bits_left >= 5) && (bits_left <= 8)) \ - { \ - i = bits_left - 4; \ - outputBuffer[opb_index] |= _data << i; \ - bits_left = i; \ - } \ - else \ + do \ { \ - i = 4 - bits_left; \ - j = 8 - i; \ - outputBuffer[opb_index++] |= _data >> i; \ - outputBuffer[opb_index] |= _data << j; \ - bits_left = j; \ - } \ -} while (0) + if ((bits_left >= 5) && (bits_left <= 8)) \ + { \ + i = bits_left - 4; \ + outputBuffer[opb_index] |= _data << i; \ + bits_left = i; \ + } \ + else \ + { \ + i = 4 - bits_left; \ + j = 8 - i; \ + outputBuffer[opb_index++] |= _data >> i; \ + outputBuffer[opb_index] |= _data << j; \ + bits_left = j; \ + } \ + } while (0) /***************************************************************************** insert 5 bits into outputBuffer ******************************************************************************/ #define insert_5_bits(_data) \ -do \ -{ \ - if ((bits_left >= 6) && (bits_left <= 8)) \ - { \ - i = bits_left - 5; \ - outputBuffer[opb_index] |= _data << i; \ - bits_left = i; \ - } \ - else \ + do \ { \ - i = 5 - bits_left; \ - j = 8 - i; \ - outputBuffer[opb_index++] |= _data >> i; \ - outputBuffer[opb_index] |= _data << j; \ - bits_left = j; \ - } \ -} while (0) + if ((bits_left >= 6) && (bits_left <= 8)) \ + { \ + i = bits_left - 5; \ + outputBuffer[opb_index] |= _data << i; \ + bits_left = i; \ + } \ + else \ + { \ + i = 5 - bits_left; \ + j = 8 - i; \ + outputBuffer[opb_index++] |= _data >> i; \ + outputBuffer[opb_index] |= _data << j; \ + bits_left = j; \ + } \ + } while (0) /***************************************************************************** insert 6 bits into outputBuffer ******************************************************************************/ #define insert_6_bits(_data) \ -do \ -{ \ - if ((bits_left >= 7) && (bits_left <= 8)) \ - { \ - i = bits_left - 6; \ - outputBuffer[opb_index] |= (_data << i); \ - bits_left = i; \ - } \ - else \ + do \ { \ - i = 6 - bits_left; \ - j = 8 - i; \ - outputBuffer[opb_index++] |= (_data >> i); \ - outputBuffer[opb_index] |= (_data << j); \ - bits_left = j; \ - } \ -} while (0) + if ((bits_left >= 7) && (bits_left <= 8)) \ + { \ + i = bits_left - 6; \ + outputBuffer[opb_index] |= (_data << i); \ + bits_left = i; \ + } \ + else \ + { \ + i = 6 - bits_left; \ + j = 8 - i; \ + outputBuffer[opb_index++] |= (_data >> i); \ + outputBuffer[opb_index] |= (_data << j); \ + bits_left = j; \ + } \ + } while (0) /***************************************************************************** insert 7 bits into outputBuffer ******************************************************************************/ #define insert_7_bits(_data) \ -do \ -{ \ - if (bits_left == 8) \ - { \ - outputBuffer[opb_index] |= _data << 1; \ - bits_left = 1; \ - } \ - else \ + do \ { \ - i = 7 - bits_left; \ - j = 8 - i; \ - outputBuffer[opb_index++] |= _data >> i; \ - outputBuffer[opb_index] |= _data << j; \ - bits_left = j; \ - } \ -} while (0) + if (bits_left == 8) \ + { \ + outputBuffer[opb_index] |= _data << 1; \ + bits_left = 1; \ + } \ + else \ + { \ + i = 7 - bits_left; \ + j = 8 - i; \ + outputBuffer[opb_index++] |= _data >> i; \ + outputBuffer[opb_index] |= _data << j; \ + bits_left = j; \ + } \ + } while (0) /***************************************************************************** insert 8 bits into outputBuffer ******************************************************************************/ #define insert_8_bits(_data) \ -do \ -{ \ - if (bits_left == 8) \ - { \ - outputBuffer[opb_index++] |= _data; \ - bits_left = 8; \ - } \ - else \ + do \ { \ - i = 8 - bits_left; \ - j = 8 - i; \ - outputBuffer[opb_index++] |= _data >> i; \ - outputBuffer[opb_index] |= _data << j; \ - bits_left = j; \ - } \ -} while (0) + if (bits_left == 8) \ + { \ + outputBuffer[opb_index++] |= _data; \ + bits_left = 8; \ + } \ + else \ + { \ + i = 8 - bits_left; \ + j = 8 - i; \ + outputBuffer[opb_index++] |= _data >> i; \ + outputBuffer[opb_index] |= _data << j; \ + bits_left = j; \ + } \ + } while (0) /***************************************************************************** insert 9 bits into outputBuffer ******************************************************************************/ #define insert_9_bits(_data16) \ -do \ -{ \ - i = 9 - bits_left; \ - j = 8 - i; \ - outputBuffer[opb_index++] |= (char) (_data16 >> i); \ - outputBuffer[opb_index] |= (char) (_data16 << j); \ - bits_left = j; \ - if (bits_left == 0) \ - { \ - opb_index++; \ - bits_left = 8; \ - } \ -} while (0) - -/***************************************************************************** - insert 10 bits into outputBuffer -******************************************************************************/ -#define insert_10_bits(_data16) \ -do \ -{ \ - i = 10 - bits_left; \ - if ((bits_left >= 3) && (bits_left <= 8)) \ + do \ { \ + i = 9 - bits_left; \ j = 8 - i; \ outputBuffer[opb_index++] |= (char) (_data16 >> i); \ outputBuffer[opb_index] |= (char) (_data16 << j); \ bits_left = j; \ - } \ - else \ + if (bits_left == 0) \ + { \ + opb_index++; \ + bits_left = 8; \ + } \ + } while (0) + +/***************************************************************************** + insert 10 bits into outputBuffer +******************************************************************************/ +#define insert_10_bits(_data16) \ + do \ { \ - j = i - 8; \ - k = 8 - j; \ - outputBuffer[opb_index++] |= (char) (_data16 >> i); \ - outputBuffer[opb_index++] |= (char) (_data16 >> j); \ - outputBuffer[opb_index] |= (char) (_data16 << k); \ - bits_left = k; \ - } \ -} while (0) + i = 10 - bits_left; \ + if ((bits_left >= 3) && (bits_left <= 8)) \ + { \ + j = 8 - i; \ + outputBuffer[opb_index++] |= (char) (_data16 >> i); \ + outputBuffer[opb_index] |= (char) (_data16 << j); \ + bits_left = j; \ + } \ + else \ + { \ + j = i - 8; \ + k = 8 - j; \ + outputBuffer[opb_index++] |= (char) (_data16 >> i); \ + outputBuffer[opb_index++] |= (char) (_data16 >> j); \ + outputBuffer[opb_index] |= (char) (_data16 << k); \ + bits_left = k; \ + } \ + } while (0) /***************************************************************************** insert 11 bits into outputBuffer ******************************************************************************/ #define insert_11_bits(_data16) \ -do \ -{ \ - i = 11 - bits_left; \ - if ((bits_left >= 4) && (bits_left <= 8)) \ - { \ - j = 8 - i; \ - outputBuffer[opb_index++] |= (char) (_data16 >> i); \ - outputBuffer[opb_index] |= (char) (_data16 << j); \ - bits_left = j; \ - } \ - else \ + do \ { \ - j = i - 8; \ - k = 8 - j; \ - outputBuffer[opb_index++] |= (char) (_data16 >> i); \ - outputBuffer[opb_index++] |= (char) (_data16 >> j); \ - outputBuffer[opb_index] |= (char) (_data16 << k); \ - bits_left = k; \ - } \ -} while (0) + i = 11 - bits_left; \ + if ((bits_left >= 4) && (bits_left <= 8)) \ + { \ + j = 8 - i; \ + outputBuffer[opb_index++] |= (char) (_data16 >> i); \ + outputBuffer[opb_index] |= (char) (_data16 << j); \ + bits_left = j; \ + } \ + else \ + { \ + j = i - 8; \ + k = 8 - j; \ + outputBuffer[opb_index++] |= (char) (_data16 >> i); \ + outputBuffer[opb_index++] |= (char) (_data16 >> j); \ + outputBuffer[opb_index] |= (char) (_data16 << k); \ + bits_left = k; \ + } \ + } while (0) /***************************************************************************** insert 12 bits into outputBuffer ******************************************************************************/ #define insert_12_bits(_data16) \ -do \ -{ \ - i = 12 - bits_left; \ - if ((bits_left >= 5) && (bits_left <= 8)) \ + do \ { \ - j = 8 - i; \ - outputBuffer[opb_index++] |= (char) (_data16 >> i); \ - outputBuffer[opb_index] |= (char) (_data16 << j); \ - bits_left = j; \ - } \ - else \ - { \ - j = i - 8; \ - k = 8 - j; \ - outputBuffer[opb_index++] |= (char) (_data16 >> i); \ - outputBuffer[opb_index++] |= (char) (_data16 >> j); \ - outputBuffer[opb_index] |= (char) (_data16 << k); \ - bits_left = k; \ - } \ -} while (0) + i = 12 - bits_left; \ + if ((bits_left >= 5) && (bits_left <= 8)) \ + { \ + j = 8 - i; \ + outputBuffer[opb_index++] |= (char) (_data16 >> i); \ + outputBuffer[opb_index] |= (char) (_data16 << j); \ + bits_left = j; \ + } \ + else \ + { \ + j = i - 8; \ + k = 8 - j; \ + outputBuffer[opb_index++] |= (char) (_data16 >> i); \ + outputBuffer[opb_index++] |= (char) (_data16 >> j); \ + outputBuffer[opb_index] |= (char) (_data16 << k); \ + bits_left = k; \ + } \ + } while (0) /***************************************************************************** insert 13 bits into outputBuffer ******************************************************************************/ #define insert_13_bits(_data16) \ -do \ -{ \ - i = 13 - bits_left; \ - if ((bits_left >= 6) && (bits_left <= 8)) \ - { \ - j = 8 - i; \ - outputBuffer[opb_index++] |= (char) (_data16 >> i); \ - outputBuffer[opb_index] |= (char) (_data16 << j); \ - bits_left = j; \ - } \ - else \ + do \ { \ - j = i - 8; \ - k = 8 - j; \ - outputBuffer[opb_index++] |= (char) (_data16 >> i); \ - outputBuffer[opb_index++] |= (char) (_data16 >> j); \ - outputBuffer[opb_index] |= (char) (_data16 << k); \ - bits_left = k; \ - } \ -} while (0) + i = 13 - bits_left; \ + if ((bits_left >= 6) && (bits_left <= 8)) \ + { \ + j = 8 - i; \ + outputBuffer[opb_index++] |= (char) (_data16 >> i); \ + outputBuffer[opb_index] |= (char) (_data16 << j); \ + bits_left = j; \ + } \ + else \ + { \ + j = i - 8; \ + k = 8 - j; \ + outputBuffer[opb_index++] |= (char) (_data16 >> i); \ + outputBuffer[opb_index++] |= (char) (_data16 >> j); \ + outputBuffer[opb_index] |= (char) (_data16 << k); \ + bits_left = k; \ + } \ + } while (0) /***************************************************************************** insert 14 bits into outputBuffer ******************************************************************************/ #define insert_14_bits(_data16) \ -do \ -{ \ - i = 14 - bits_left; \ - if ((bits_left >= 7) && (bits_left <= 8)) \ - { \ - j = 8 - i; \ - outputBuffer[opb_index++] |= (char) (_data16 >> i); \ - outputBuffer[opb_index] |= (char) (_data16 << j); \ - bits_left = j; \ - } \ - else \ + do \ { \ - j = i - 8; \ - k = 8 - j; \ - outputBuffer[opb_index++] |= (char) (_data16 >> i); \ - outputBuffer[opb_index++] |= (char) (_data16 >> j); \ - outputBuffer[opb_index] |= (char) (_data16 << k); \ - bits_left = k; \ - } \ -} while (0) + i = 14 - bits_left; \ + if ((bits_left >= 7) && (bits_left <= 8)) \ + { \ + j = 8 - i; \ + outputBuffer[opb_index++] |= (char) (_data16 >> i); \ + outputBuffer[opb_index] |= (char) (_data16 << j); \ + bits_left = j; \ + } \ + else \ + { \ + j = i - 8; \ + k = 8 - j; \ + outputBuffer[opb_index++] |= (char) (_data16 >> i); \ + outputBuffer[opb_index++] |= (char) (_data16 >> j); \ + outputBuffer[opb_index] |= (char) (_data16 << k); \ + bits_left = k; \ + } \ + } while (0) /***************************************************************************** insert 15 bits into outputBuffer ******************************************************************************/ #define insert_15_bits(_data16) \ -do \ -{ \ - i = 15 - bits_left; \ - if (bits_left == 8) \ + do \ { \ - j = 8 - i; \ - outputBuffer[opb_index++] |= (char) (_data16 >> i); \ - outputBuffer[opb_index] |= (char) (_data16 << j); \ - bits_left = j; \ - } \ - else \ + i = 15 - bits_left; \ + if (bits_left == 8) \ + { \ + j = 8 - i; \ + outputBuffer[opb_index++] |= (char) (_data16 >> i); \ + outputBuffer[opb_index] |= (char) (_data16 << j); \ + bits_left = j; \ + } \ + else \ + { \ + j = i - 8; \ + k = 8 - j; \ + outputBuffer[opb_index++] |= (char) (_data16 >> i); \ + outputBuffer[opb_index++] |= (char) (_data16 >> j); \ + outputBuffer[opb_index] |= (char) (_data16 << k); \ + bits_left = k; \ + } \ + } while (0) + +/***************************************************************************** + insert 16 bits into outputBuffer +******************************************************************************/ +#define insert_16_bits(_data16) \ + do \ { \ + i = 16 - bits_left; \ j = i - 8; \ k = 8 - j; \ outputBuffer[opb_index++] |= (char) (_data16 >> i); \ outputBuffer[opb_index++] |= (char) (_data16 >> j); \ outputBuffer[opb_index] |= (char) (_data16 << k); \ bits_left = k; \ - } \ -} while (0) - -/***************************************************************************** - insert 16 bits into outputBuffer -******************************************************************************/ -#define insert_16_bits(_data16) \ -do \ -{ \ - i = 16 - bits_left; \ - j = i - 8; \ - k = 8 - j; \ - outputBuffer[opb_index++] |= (char) (_data16 >> i); \ - outputBuffer[opb_index++] |= (char) (_data16 >> j); \ - outputBuffer[opb_index] |= (char) (_data16 << k); \ - bits_left = k; \ -} while (0) + } while (0) /** * Initialize mppc_enc structure @@ -606,7 +598,7 @@ for (x = 0; x < 2; x++) { data = *(historyPointer + x); - DLOG(("%.2x ", (tui8) data)); + LOG_DEVEL(LOG_LEVEL_TRACE, "%.2x ", (tui8) data); if (data & 0x80) { /* insert encoded literal */ @@ -678,13 +670,13 @@ /* double check that we have a pattern match */ if ((*cptr1 != *cptr2) || - (*(cptr1 + 1) != *(cptr2 + 1)) || - (*(cptr1 + 2) != *(cptr2 + 2))) + (*(cptr1 + 1) != *(cptr2 + 1)) || + (*(cptr1 + 2) != *(cptr2 + 2))) { /* no match found; encode literal byte */ data = *cptr1; - DLOG(("%.2x ", data)); + LOG_DEVEL(LOG_LEVEL_TRACE, "%.2x ", data); if (data < 0x80) { /* literal byte < 0x80 */ @@ -710,8 +702,8 @@ lom++; } saved_ctr = ctr + lom; - DLOG(("<%d: %ld,%d> ", (historyPointer + ctr) - hbuf_start, - copy_offset, lom)); + LOG_DEVEL(LOG_LEVEL_TRACE, "<%ld: %u,%d> ", (historyPointer + ctr) - hbuf_start, + copy_offset, lom); /* compute CRC for matching segment and store in hash table */ @@ -951,7 +943,7 @@ while (len - ctr > 0) { data = srcData[ctr]; - DLOG(("%.2x ", data)); + LOG_DEVEL(LOG_LEVEL_TRACE, "%.2x ", data); if (data < 0x80) { /* literal byte < 0x80 */ @@ -990,9 +982,9 @@ enc->flags |= enc->flagsHold; enc->flagsHold = 0; - DLOG(("\n")); + LOG_DEVEL(LOG_LEVEL_TRACE, "\n"); - //g_writeln("compression ratio: %f", (float) len / (float) enc->bytes_in_opb); + LOG_DEVEL(LOG_LEVEL_TRACE, "compression ratio: %f", (float) len / (float) enc->bytes_in_opb); return 1; } diff -Nru xrdp-0.9.12/libxrdp/xrdp_orders.c xrdp-0.9.15/libxrdp/xrdp_orders.c --- xrdp-0.9.12/libxrdp/xrdp_orders.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/libxrdp/xrdp_orders.c 2020-12-28 14:03:43.000000000 +0000 @@ -23,20 +23,14 @@ #endif #include "libxrdp.h" +#include "ms-rdpbcgr.h" +#include "ms-rdpegdi.h" #if defined(XRDP_NEUTRINORDP) #include #endif -#define LLOG_LEVEL 2 -#define LLOGLN(_log_level, _params) \ - { \ - if (_log_level < LLOG_LEVEL) \ - { \ - g_write("xrdp_orders.c [%10.10u]: ", g_time3()); \ - g_writeln _params ; \ - } \ - } + #define MAX_ORDERS_SIZE(_client_info) \ (MAX((_client_info)->max_fastpath_frag_bytes, 16 * 1024) - 256); @@ -112,7 +106,7 @@ self->order_count = 0; if (self->rdp_layer->client_info.use_fast_path & 1) { - LLOGLN(10, ("xrdp_orders_init: fastpath")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_orders_init: fastpath"); if (xrdp_rdp_init_fastpath(self->rdp_layer, self->out_s) != 0) { return 1; @@ -122,7 +116,7 @@ } else { - LLOGLN(10, ("xrdp_orders_init: slowpath")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_orders_init: slowpath"); if (xrdp_rdp_init_data(self->rdp_layer, self->out_s) != 0) { return 1; @@ -151,7 +145,7 @@ if ((self->order_level == 0) && (self->order_count > 0)) { s_mark_end(self->out_s); - DEBUG(("xrdp_orders_send sending %d orders", self->order_count)); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_orders_send sending %d orders", self->order_count); self->order_count_ptr[0] = self->order_count; self->order_count_ptr[1] = self->order_count >> 8; self->order_count = 0; @@ -188,7 +182,7 @@ if ((self->order_level > 0) && (self->order_count > 0)) { s_mark_end(self->out_s); - DEBUG(("xrdp_orders_force_send sending %d orders", self->order_count)); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_orders_force_send sending %d orders", self->order_count); self->order_count_ptr[0] = self->order_count; self->order_count_ptr[1] = self->order_count >> 8; if (self->rdp_layer->client_info.use_fast_path & 1) @@ -243,7 +237,7 @@ size = (int)(self->out_s->p - self->order_count_ptr); if (size < 0) { - g_writeln("error in xrdp_orders_check, size too small: %d bytes", size); + LOG(LOG_LEVEL_ERROR, "error in xrdp_orders_check, size too small: %d bytes", size); return 1; } if (size > max_order_size) @@ -251,7 +245,7 @@ /* this suggests someone calls this function without passing the correct max_size so we end up putting more into the buffer than we indicate we can */ - g_writeln("error in xrdp_orders_check, size too big: %d bytes", size); + LOG(LOG_LEVEL_WARNING, "error in xrdp_orders_check, size too big: %d bytes", size); /* We where getting called with size already greater than max_order_size Which I suspect was because the sending of text did not include @@ -1646,20 +1640,20 @@ /*****************************************************************************/ /* returns error */ int -xrdp_orders_composite_blt(struct xrdp_orders* self, int srcidx, int srcformat, - int srcwidth, int srcrepeat, int* srctransform, +xrdp_orders_composite_blt(struct xrdp_orders *self, int srcidx, int srcformat, + int srcwidth, int srcrepeat, int *srctransform, int mskflags, int mskidx, int mskformat, int mskwidth, int mskrepeat, int op, int srcx, int srcy, int mskx, int msky, int dstx, int dsty, int width, int height, int dstformat, - struct xrdp_rect* rect) + struct xrdp_rect *rect) { int order_flags; int vals[20]; int present; - char* present_ptr; - char* order_flags_ptr; + char *present_ptr; + char *order_flags_ptr; if (xrdp_orders_check(self, 80) != 0) { @@ -1676,7 +1670,7 @@ { /* if clip is present, still check if it's needed */ if (dstx < rect->left || dsty < rect->top || - dstx + width > rect->right || dsty + height > rect->bottom) + dstx + width > rect->right || dsty + height > rect->bottom) { order_flags |= TS_BOUNDS; if (xrdp_orders_last_bounds(self, rect)) @@ -1723,7 +1717,7 @@ present_ptr = self->out_s->p; out_uint8s(self->out_s, 3); if ((order_flags & TS_BOUNDS) && - !(order_flags & TS_ZERO_BOUNDS_DELTAS)) + !(order_flags & TS_ZERO_BOUNDS_DELTAS)) { xrdp_orders_out_bounds(self, rect); } @@ -2225,13 +2219,13 @@ if (width > 64) { - g_writeln("error, width > 64"); + LOG(LOG_LEVEL_ERROR, "error, width > 64"); return 1; } if (height > 64) { - g_writeln("error, height > 64"); + LOG(LOG_LEVEL_ERROR, "error, height > 64"); return 1; } @@ -2351,13 +2345,13 @@ if (width > 64) { - g_writeln("error, width > 64"); + LOG(LOG_LEVEL_ERROR, "error, width > 64"); return 1; } if (height > 64) { - g_writeln("error, height > 64"); + LOG(LOG_LEVEL_ERROR, "error, height > 64"); return 1; } @@ -2488,7 +2482,7 @@ /*****************************************************************************/ /* returns error */ -static int write_2byte_signed(struct stream * s, int value) +static int write_2byte_signed(struct stream *s, int value) { unsigned char byte; int negative = 0; @@ -2534,7 +2528,7 @@ /*****************************************************************************/ /* returns error */ -static int write_2byte_unsigned(struct stream * s, unsigned int value) +static int write_2byte_unsigned(struct stream *s, unsigned int value) { unsigned char byte; @@ -2600,9 +2594,9 @@ out_uint8(self->out_s, char_index); if (write_2byte_signed(self->out_s, font_char->offset) || - write_2byte_signed(self->out_s, font_char->baseline) || - write_2byte_unsigned(self->out_s, font_char->width) || - write_2byte_unsigned(self->out_s, font_char->height)) + write_2byte_signed(self->out_s, font_char->baseline) || + write_2byte_unsigned(self->out_s, font_char->width) || + write_2byte_unsigned(self->out_s, font_char->height)) { return 1; } @@ -2651,13 +2645,13 @@ if (width > 64) { - g_writeln("error, width > 64"); + LOG(LOG_LEVEL_ERROR, "error, width > 64"); return 1; } if (height > 64) { - g_writeln("error, height > 64"); + LOG(LOG_LEVEL_ERROR, "error, height > 64"); return 1; } @@ -2779,13 +2773,13 @@ if (width > 64) { - g_writeln("error, width > 64"); + LOG(LOG_LEVEL_ERROR, "error, width > 64"); return 1; } if (height > 64) { - g_writeln("error, height > 64"); + LOG(LOG_LEVEL_ERROR, "error, height > 64"); return 1; } @@ -2892,8 +2886,8 @@ return 0; } - LLOGLN(10, ("width %d height %d rfx_min_pixel %d", width, height, - self->rfx_min_pixel)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "width %d height %d rfx_min_pixel %d", width, height, + self->rfx_min_pixel); if (width * height < self->rfx_min_pixel) { return 0; @@ -2985,7 +2979,7 @@ return 2; } - LLOGLN(10, ("xrdp_orders_send_bitmap3: rfx")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_orders_send_bitmap3: rfx"); context = (RFX_CONTEXT *)(self->rdp_layer->rfx_enc); make_stream(xr_s); init_stream(xr_s, 16384); @@ -3014,11 +3008,11 @@ if (!xrdp_orders_send_as_jpeg(self, width, height, bpp, hints)) { - LLOGLN(10, ("xrdp_orders_send_bitmap3: jpeg skipped")); + LOG(LOG_LEVEL_ERROR, "xrdp_orders_send_bitmap3: jpeg skipped"); return 2; } - LLOGLN(10, ("xrdp_orders_send_bitmap3: jpeg")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_orders_send_bitmap3: jpeg"); e = width % 4; if (e != 0) @@ -3046,7 +3040,7 @@ } else { - g_writeln("xrdp_orders_send_bitmap3: todo unknown codec"); + LOG(LOG_LEVEL_ERROR, "xrdp_orders_send_bitmap3: todo unknown codec"); return 1; } @@ -3117,7 +3111,7 @@ order_flags |= 1 << 2; /* type RDP_ORDER_ALTSEC_CREATE_OFFSCR_BITMAP */ out_uint8(self->out_s, order_flags); cache_id = id & 0x7fff; - LLOGLN(10, ("xrdp_orders_send_create_os_surface: cache_id %d", cache_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_orders_send_create_os_surface: cache_id %d", cache_id); flags = cache_id; if (num_del_list > 0) diff -Nru xrdp-0.9.12/libxrdp/xrdp_orders_rail.c xrdp-0.9.15/libxrdp/xrdp_orders_rail.c --- xrdp-0.9.12/libxrdp/xrdp_orders_rail.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/libxrdp/xrdp_orders_rail.c 2020-12-28 14:03:43.000000000 +0000 @@ -21,7 +21,9 @@ #endif #include "libxrdp.h" +#include "ms-rdpegdi.h" #include "xrdp_rail.h" +#include "string_calls.h" /* [MS-RDPERP]: Remote Desktop Protocol: Remote Programs Virtual Channel Extension diff -Nru xrdp-0.9.12/libxrdp/xrdp_rdp.c xrdp-0.9.15/libxrdp/xrdp_rdp.c --- xrdp-0.9.12/libxrdp/xrdp_rdp.c 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/libxrdp/xrdp_rdp.c 2020-12-28 14:03:43.000000000 +0000 @@ -23,52 +23,46 @@ #endif #include "libxrdp.h" +#include "ms-rdpbcgr.h" #include "log.h" #include "ssl_calls.h" +#include "string_calls.h" #if defined(XRDP_NEUTRINORDP) #include #include #endif -#define LOG_LEVEL 1 -#define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0) -#define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0) + #define FASTPATH_FRAG_SIZE (16 * 1024 - 128) /*****************************************************************************/ static int -xrdp_rdp_read_config(struct xrdp_client_info *client_info) +xrdp_rdp_read_config(const char *xrdp_ini, struct xrdp_client_info *client_info) { int index = 0; struct list *items = (struct list *)NULL; struct list *values = (struct list *)NULL; char *item = NULL; char *value = NULL; - char cfg_file[256]; int pos; char *tmp = NULL; int tmp_length = 0; /* initialize (zero out) local variables: */ - g_memset(cfg_file, 0, sizeof(char) * 256); - items = list_create(); items->auto_free = 1; values = list_create(); values->auto_free = 1; - g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); - DEBUG(("cfg_file %s", cfg_file)); - file_by_name_read_section(cfg_file, "globals", items, values); + LOG_DEVEL(LOG_LEVEL_TRACE, "cfg_file %s", xrdp_ini); + file_by_name_read_section(xrdp_ini, "globals", items, values); for (index = 0; index < items->count; index++) { item = (char *)list_get_item(items, index); value = (char *)list_get_item(values, index); - DEBUG(("item %s value %s", item, value)); + LOG_DEVEL(LOG_LEVEL_TRACE, "item %s value %s", item, value); if (g_strcasecmp(item, "bitmap_cache") == 0) { @@ -106,8 +100,8 @@ } else { - log_message(LOG_LEVEL_ALWAYS,"Warning: Your configured crypt level is " - "undefined, 'high' will be used"); + LOG(LOG_LEVEL_ALWAYS, "Warning: Your configured crypt level is " + "undefined, 'high' will be used"); client_info->crypt_level = 3; } } @@ -116,17 +110,17 @@ client_info->channels_allowed = g_text2bool(value); if (client_info->channels_allowed == 0) { - log_message(LOG_LEVEL_DEBUG,"Info - All channels are disabled"); + LOG(LOG_LEVEL_DEBUG, "Info - All channels are disabled"); } } else if (g_strcasecmp(item, "allow_multimon") == 0) - { - client_info->multimon = g_text2bool(value); - if (client_info->multimon == 0) - { - log_message(LOG_LEVEL_DEBUG,"Info - Multi monitor server support disabled"); - } - } + { + client_info->multimon = g_text2bool(value); + if (client_info->multimon == 0) + { + LOG(LOG_LEVEL_DEBUG, "Info - Multi monitor server support disabled"); + } + } else if (g_strcasecmp(item, "max_bpp") == 0) { client_info->max_bpp = g_atoi(value); @@ -143,6 +137,10 @@ { client_info->require_credentials = g_text2bool(value); } + else if (g_strcasecmp(item, "enable_token_login") == 0) + { + client_info->enable_token_login = g_text2bool(value); + } else if (g_strcasecmp(item, "use_fastpath") == 0) { if (g_strcasecmp(value, "output") == 0) @@ -163,8 +161,8 @@ } else { - log_message(LOG_LEVEL_ALWAYS,"Warning: Your configured fastpath level is " - "undefined, fastpath will not be used"); + LOG(LOG_LEVEL_ALWAYS, "Warning: Your configured fastpath level is " + "undefined, fastpath will not be used"); client_info->use_fast_path = 0; } } @@ -207,9 +205,9 @@ } else { - log_message(LOG_LEVEL_ERROR, "security_layer=%s is not " - "recognized, will use security_layer=negotiate", - value); + LOG(LOG_LEVEL_ERROR, "security_layer=%s is not " + "recognized, will use security_layer=negotiate", + value); client_info->security_layer = PROTOCOL_SSL | PROTOCOL_HYBRID | PROTOCOL_HYBRID_EX; } } @@ -220,18 +218,18 @@ { /* default certificate path */ g_snprintf(client_info->certificate, 1023, "%s/cert.pem", XRDP_CFG_PATH); - log_message(LOG_LEVEL_INFO, - "Using default X.509 certificate: %s", - client_info->certificate); + LOG(LOG_LEVEL_INFO, + "Using default X.509 certificate: %s", + client_info->certificate); } else if (value[0] != '/') { /* default certificate path */ g_snprintf(client_info->certificate, 1023, "%s/cert.pem", XRDP_CFG_PATH); - log_message(LOG_LEVEL_WARNING, - "X.509 certificate should use absolute path, using " - "default instead: %s", client_info->certificate); + LOG(LOG_LEVEL_WARNING, + "X.509 certificate should use absolute path, using " + "default instead: %s", client_info->certificate); } else { @@ -239,10 +237,10 @@ g_strncpy(client_info->certificate, value, 1023); } - if (!g_file_readable(client_info->certificate)) + if (!g_file_readable(client_info->certificate)) { - log_message(LOG_LEVEL_ERROR, "Cannot read certificate file %s: %s", - client_info->certificate, g_get_strerror()); + LOG(LOG_LEVEL_ERROR, "Cannot read certificate file %s: %s", + client_info->certificate, g_get_strerror()); } } else if (g_strcasecmp(item, "key_file") == 0) @@ -252,16 +250,16 @@ { /* default key_file path */ g_snprintf(client_info->key_file, 1023, "%s/key.pem", XRDP_CFG_PATH); - log_message(LOG_LEVEL_INFO, "Using default X.509 key file: %s", - client_info->key_file); + LOG(LOG_LEVEL_INFO, "Using default X.509 key file: %s", + client_info->key_file); } else if (value[0] != '/') { /* default key_file path */ g_snprintf(client_info->key_file, 1023, "%s/key.pem", XRDP_CFG_PATH); - log_message(LOG_LEVEL_WARNING, - "X.509 key file should use absolute path, using " - "default instead: %s", client_info->key_file); + LOG(LOG_LEVEL_WARNING, + "X.509 key file should use absolute path, using " + "default instead: %s", client_info->key_file); } else { @@ -271,11 +269,15 @@ if (!g_file_readable(client_info->key_file)) { - log_message(LOG_LEVEL_ERROR, "Cannot read private key file %s: %s", - client_info->key_file, g_get_strerror()); + LOG(LOG_LEVEL_ERROR, "Cannot read private key file %s: %s", + client_info->key_file, g_get_strerror()); } } - + else if (g_strcasecmp(item, "domain_user_separator") == 0 + && g_strlen(value) > 0) + { + g_strncpy(client_info->domain_user_separator, value, sizeof(client_info->domain_user_separator) - 1); + } } list_delete(items); @@ -303,9 +305,9 @@ "cpuid;" "xchg %%rbx, %%rsi;" #endif - : "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx) - : "0" (info) - ); + : "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx) + : "0" (info) + ); #endif #endif } @@ -329,7 +331,7 @@ if (edx & (1 << 26)) { - DEBUG(("SSE2 detected")); + LOG_DEVEL(LOG_LEVEL_TRACE, "SSE2 detected"); cpu_opt |= CPU_SSE2; } @@ -344,12 +346,12 @@ struct xrdp_rdp *self = (struct xrdp_rdp *)NULL; int bytes; - DEBUG(("in xrdp_rdp_create")); + LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_create"); self = (struct xrdp_rdp *)g_malloc(sizeof(struct xrdp_rdp), 1); self->session = session; self->share_id = 66538; /* read ini settings */ - xrdp_rdp_read_config(&self->client_info); + xrdp_rdp_read_config(session->xrdp_ini, &self->client_info); /* create sec layer */ self->sec_layer = xrdp_sec_create(self, trans); /* default 8 bit v1 color bitmap cache entries and size */ @@ -368,7 +370,7 @@ rfx_context_set_cpu_opt(self->rfx_enc, xrdp_rdp_detect_cpu()); #endif self->client_info.size = sizeof(self->client_info); - DEBUG(("out xrdp_rdp_create")); + LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_create"); return self; } @@ -427,7 +429,7 @@ int chan = 0; const tui8 *header; - DEBUG(("in xrdp_rdp_recv")); + LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_recv"); if (s->next_packet == 0 || s->next_packet >= s->end) { /* check for fastpath first */ @@ -440,7 +442,7 @@ } /* next_packet gets set in xrdp_sec_recv_fastpath */ *code = 2; // special code for fastpath input - DEBUG(("out (fastpath) xrdp_rdp_recv")); + LOG_DEVEL(LOG_LEVEL_TRACE, "out (fastpath) xrdp_rdp_recv"); return 0; } @@ -452,14 +454,13 @@ { s->next_packet = 0; *code = -1; - DEBUG(("out (1) xrdp_rdp_recv")); + LOG_DEVEL(LOG_LEVEL_TRACE, "out (1) xrdp_rdp_recv"); return 0; } if (error != 0) { - DEBUG(("out xrdp_rdp_recv error")); - g_writeln("xrdp_rdp_recv: xrdp_sec_recv failed"); + LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_recv error"); return 1; } @@ -469,20 +470,20 @@ { if (xrdp_channel_process(self->sec_layer->chan_layer, s, chan) != 0) { - g_writeln("xrdp_channel_process returned unhandled error") ; + LOG(LOG_LEVEL_ERROR, "xrdp_channel_process returned unhandled error") ; } } else { if (chan != 1) { - g_writeln("Wrong channel Id to be handled by xrdp_channel_process %d", chan); + LOG(LOG_LEVEL_ERROR, "Wrong channel Id to be handled by xrdp_channel_process %d", chan); } } s->next_packet = 0; *code = 0; - DEBUG(("out (2) xrdp_rdp_recv")); + LOG_DEVEL(LOG_LEVEL_TRACE, "out (2) xrdp_rdp_recv"); return 0; } @@ -490,7 +491,7 @@ } else { - DEBUG(("xrdp_rdp_recv stream not touched")) + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_recv stream not touched"); s->p = s->next_packet; } @@ -498,20 +499,19 @@ { s->next_packet = 0; *code = 0; - DEBUG(("out (3) xrdp_rdp_recv")); len = (int)(s->end - s->p); - g_writeln("xrdp_rdp_recv: bad RDP packet, length [%d]", len); + LOG_DEVEL(LOG_LEVEL_TRACE, "out (3) xrdp_rdp_recv: bad RDP packet, length [%d]", len); return 0; } else { in_uint16_le(s, len); - /*g_writeln("New len received : %d next packet: %d s_end: %d",len,s->next_packet,s->end); */ + /*LOG_DEVEL(LOG_LEVEL_TRACE, "New len received : %d next packet: %d s_end: %d",len,s->next_packet,s->end); */ in_uint16_le(s, pdu_code); *code = pdu_code & 0xf; in_uint8s(s, 2); /* mcs user id */ s->next_packet += len; - DEBUG(("out (4) xrdp_rdp_recv")); + LOG_DEVEL(LOG_LEVEL_TRACE, "out (4) xrdp_rdp_recv"); return 0; } } @@ -522,7 +522,7 @@ { int len = 0; - DEBUG(("in xrdp_rdp_send")); + LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_send"); s_pop_layer(s, rdp_hdr); len = s->end - s->p; out_uint16_le(s, len); @@ -531,11 +531,11 @@ if (xrdp_sec_send(self->sec_layer, s, MCS_GLOBAL_CHANNEL) != 0) { - DEBUG(("out xrdp_rdp_send error")); + LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send error"); return 1; } - DEBUG(("out xrdp_rdp_send")); + LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_send"); return 0; } @@ -558,7 +558,7 @@ struct stream ls; struct xrdp_mppc_enc *mppc_enc; - DEBUG(("in xrdp_rdp_send_data")); + LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_send_data"); s_pop_layer(s, rdp_hdr); len = (int)(s->end - s->p); pdutype = 0x10 | PDUTYPE_DATAPDU; @@ -573,9 +573,9 @@ mppc_enc = self->mppc_enc; if (compress_rdp(mppc_enc, (tui8 *)(s->p + 18), tocomplen)) { - DEBUG(("mppc_encode ok flags 0x%x bytes_in_opb %d historyOffset %d " - "tocomplen %d", mppc_enc->flags, mppc_enc->bytes_in_opb, - mppc_enc->historyOffset, tocomplen)); + LOG_DEVEL(LOG_LEVEL_TRACE, "mppc_encode ok flags 0x%x bytes_in_opb %d historyOffset %d " + "tocomplen %d", mppc_enc->flags, mppc_enc->bytes_in_opb, + mppc_enc->historyOffset, tocomplen); clen = mppc_enc->bytes_in_opb + 18; pdulen = clen; @@ -600,9 +600,9 @@ } else { - LLOGLN(10, ("xrdp_rdp_send_data: mppc_encode not ok " - "type %d flags %d", mppc_enc->protocol_type, - mppc_enc->flags)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_data: mppc_encode not ok " + "type %d flags %d", mppc_enc->protocol_type, + mppc_enc->flags); } } @@ -619,11 +619,11 @@ if (xrdp_sec_send(self->sec_layer, s, MCS_GLOBAL_CHANNEL) != 0) { - DEBUG(("out xrdp_rdp_send_data error")); + LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send_data error"); return 1; } - DEBUG(("out xrdp_rdp_send_data")); + LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_send_data"); return 0; } @@ -685,7 +685,7 @@ struct stream send_s; struct xrdp_mppc_enc *mppc_enc; - LLOGLN(10, ("xrdp_rdp_send_fastpath:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_fastpath:"); s_pop_layer(s, rdp_hdr); updateCode = data_pdu_type; if (self->client_info.rdp_compression) @@ -729,8 +729,8 @@ } } send_len = no_comp_len; - LLOGLN(10, ("xrdp_rdp_send_fastpath: no_comp_len %d fragmentation %d", - no_comp_len, fragmentation)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_fastpath: no_comp_len %d fragmentation %d", + no_comp_len, fragmentation); if ((compression != 0) && (no_comp_len > header_bytes + 16)) { to_comp_len = no_comp_len - header_bytes; @@ -739,14 +739,14 @@ to_comp_len)) { comp_len = mppc_enc->bytes_in_opb + header_bytes; - LLOGLN(10, ("xrdp_rdp_send_fastpath: no_comp_len %d " - "comp_len %d", no_comp_len, comp_len)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_fastpath: no_comp_len %d " + "comp_len %d", no_comp_len, comp_len); send_len = comp_len; comp_type = mppc_enc->flags; /* outputBuffer has 64 bytes preceding it */ g_memset(&comp_s, 0, sizeof(comp_s)); comp_s.data = mppc_enc->outputBuffer - - (rdp_offset + header_bytes); + (rdp_offset + header_bytes); comp_s.p = comp_s.data + rdp_offset; comp_s.end = comp_s.p + send_len; comp_s.size = send_len; @@ -756,14 +756,14 @@ } else { - LLOGLN(10, ("xrdp_rdp_send_fastpath: mppc_encode not ok " - "type %d flags %d", mppc_enc->protocol_type, - mppc_enc->flags)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_fastpath: mppc_encode not ok " + "type %d flags %d", mppc_enc->protocol_type, + mppc_enc->flags); } } updateHeader = (updateCode & 15) | - ((fragmentation & 3) << 4) | - ((compression & 3) << 6); + ((fragmentation & 3) << 4) | + ((compression & 3) << 6); out_uint8(&send_s, updateHeader); if (compression != 0) { @@ -774,7 +774,7 @@ send_s.end = send_s.p + send_len; if (xrdp_sec_send_fastpath(self->sec_layer, &send_s) != 0) { - LLOGLN(0, ("xrdp_rdp_send_fastpath: xrdp_fastpath_send failed")); + LOG(LOG_LEVEL_ERROR, "xrdp_rdp_send_fastpath: xrdp_fastpath_send failed"); return 1; } frag_s.p += no_comp_len; @@ -794,11 +794,11 @@ make_stream(s); init_stream(s, 8192); - DEBUG(("in xrdp_rdp_send_data_update_sync")); + LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_send_data_update_sync"); if (self->client_info.use_fast_path & 1) /* fastpath output supported */ { - LLOGLN(10, ("xrdp_rdp_send_data_update_sync: fastpath")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_data_update_sync: fastpath"); if (xrdp_rdp_init_fastpath(self, s) != 0) { free_stream(s); @@ -809,7 +809,7 @@ { if (xrdp_rdp_init_data(self, s) != 0) { - DEBUG(("out xrdp_rdp_send_data_update_sync error")); + LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send_data_update_sync error"); free_stream(s); return 1; } @@ -832,14 +832,14 @@ { if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_UPDATE) != 0) { - DEBUG(("out xrdp_rdp_send_data_update_sync error")); + LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send_data_update_sync error"); free_stream(s); return 1; } } - DEBUG(("out xrdp_rdp_send_data_update_sync")); + LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_send_data_update_sync"); free_stream(s); return 0; } @@ -851,7 +851,7 @@ struct xrdp_iso *iso; iso = self->sec_layer->mcs_layer->iso_layer; - DEBUG(("in xrdp_rdp_incoming")); + LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_incoming"); if (xrdp_sec_incoming(self->sec_layer) != 0) { @@ -859,7 +859,7 @@ } self->mcs_channel = self->sec_layer->mcs_layer->userid + MCS_USERCHANNEL_BASE; - DEBUG(("out xrdp_rdp_incoming mcs channel %d", self->mcs_channel)); + LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_incoming mcs channel %d", self->mcs_channel); g_strncpy(self->client_info.client_addr, iso->trans->addr, sizeof(self->client_info.client_addr) - 1); g_strncpy(self->client_info.client_port, iso->trans->port, @@ -868,21 +868,21 @@ /* log TLS version and cipher of TLS connections */ if (iso->selectedProtocol > PROTOCOL_RDP) { - log_message(LOG_LEVEL_INFO, - "TLS connection established from %s port %s: %s with cipher %s", - self->client_info.client_addr, - self->client_info.client_port, - iso->trans->ssl_protocol, - iso->trans->cipher_name); + LOG(LOG_LEVEL_INFO, + "TLS connection established from %s port %s: %s with cipher %s", + self->client_info.client_addr, + self->client_info.client_port, + iso->trans->ssl_protocol, + iso->trans->cipher_name); } /* log non-TLS connections */ else { - log_message(LOG_LEVEL_INFO, - "Non-TLS connection established from %s port %s: " - "encrypted with standard RDP security", - self->client_info.client_addr, - self->client_info.client_port); + LOG(LOG_LEVEL_INFO, + "Non-TLS connection established from %s port %s: " + "encrypted with standard RDP security", + self->client_info.client_addr, + self->client_info.client_port); } return 0; @@ -914,7 +914,7 @@ } in_uint16_le(s, num_events); in_uint8s(s, 2); /* pad */ - DEBUG(("in xrdp_rdp_process_data_input %d events", num_events)); + LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_process_data_input %d events", num_events); for (index = 0; index < num_events; index++) { @@ -927,8 +927,8 @@ in_uint16_le(s, device_flags); in_sint16_le(s, param1); in_sint16_le(s, param2); - DEBUG(("xrdp_rdp_process_data_input event %4.4x flags %4.4x param1 %d " - "param2 %d time %d", msg_type, device_flags, param1, param2, time)); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_input event %4.4x flags %4.4x param1 %d " + "param2 %d time %d", msg_type, device_flags, param1, param2, time); if (self->session->callback != 0) { @@ -943,7 +943,7 @@ } } - DEBUG(("out xrdp_rdp_process_data_input")); + LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_process_data_input"); return 0; } @@ -1012,24 +1012,24 @@ { int action; - DEBUG(("xrdp_rdp_process_data_control")); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control"); in_uint16_le(s, action); in_uint8s(s, 2); /* user id */ in_uint8s(s, 4); /* control id */ if (action == RDP_CTL_REQUEST_CONTROL) { - DEBUG(("xrdp_rdp_process_data_control got RDP_CTL_REQUEST_CONTROL")); - DEBUG(("xrdp_rdp_process_data_control calling xrdp_rdp_send_synchronise")); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control got RDP_CTL_REQUEST_CONTROL"); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control calling xrdp_rdp_send_synchronise"); xrdp_rdp_send_synchronise(self); - DEBUG(("xrdp_rdp_process_data_control sending RDP_CTL_COOPERATE")); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control sending RDP_CTL_COOPERATE"); xrdp_rdp_send_control(self, RDP_CTL_COOPERATE); - DEBUG(("xrdp_rdp_process_data_control sending RDP_CTL_GRANT_CONTROL")); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control sending RDP_CTL_GRANT_CONTROL"); xrdp_rdp_send_control(self, RDP_CTL_GRANT_CONTROL); } else { - DEBUG(("xrdp_rdp_process_data_control unknown action")); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control unknown action"); } return 0; @@ -1039,7 +1039,7 @@ static int xrdp_rdp_process_data_sync(struct xrdp_rdp *self) { - DEBUG(("xrdp_rdp_process_data_sync")); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_sync"); return 0; } @@ -1063,7 +1063,7 @@ } in_uint8(s, num_rects); in_uint8s(s, 3); /* pad */ - g_writeln("xrdp_rdp_process_screen_update: num_rects %d", num_rects); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_screen_update: num_rects %d", num_rects); for (index = 0; index < num_rects; index++) { if (!s_check_rem(s, 8)) @@ -1075,7 +1075,7 @@ in_uint16_le(s, top); in_uint16_le(s, right); in_uint16_le(s, bottom); - g_writeln(" left %d top %d right %d bottom %d", + LOG_DEVEL(LOG_LEVEL_TRACE, " left %d top %d right %d bottom %d", left, top, right, bottom); cx = (right - left) + 1; cy = (bottom - top) + 1; @@ -1126,7 +1126,7 @@ { int seq; - DEBUG(("in xrdp_rdp_process_data_font")); + LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_process_data_font"); in_uint8s(s, 2); /* NumberFonts: 0x0, SHOULD be set to 0 */ in_uint8s(s, 2); /* TotalNumberFonts: 0x0, SHOULD be set to 0 */ in_uint16_le(s, seq); /* ListFlags */ @@ -1136,17 +1136,17 @@ if (seq == 2 || seq == 3) /* after second font message, we are up and */ { /* running */ - DEBUG(("sending fontmap")); + LOG_DEVEL(LOG_LEVEL_TRACE, "sending fontmap"); xrdp_rdp_send_fontmap(self); self->session->up_and_running = 1; - g_writeln("yeah, up_and_running"); - DEBUG(("up_and_running set")); + LOG_DEVEL(LOG_LEVEL_TRACE, "yeah, up_and_running"); + LOG_DEVEL(LOG_LEVEL_TRACE, "up_and_running set"); xrdp_rdp_send_data_update_sync(self); xrdp_channel_drdynvc_start(self->sec_layer->chan_layer); } - DEBUG(("out xrdp_rdp_process_data_font")); + LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_process_data_font"); return 0; } @@ -1215,9 +1215,9 @@ { int frame_id; - //g_writeln("xrdp_rdp_process_frame_ack:"); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_frame_ack:"); in_uint32_le(s, frame_id); - //g_writeln(" frame_id %d", frame_id); + LOG_DEVEL(LOG_LEVEL_TRACE, " frame_id %d", frame_id); if (self->session->callback != 0) { /* call to xrdp_wm.c : callback */ @@ -1242,13 +1242,13 @@ return 1; } in_uint8(s, allowDisplayUpdates); - g_writeln("xrdp_rdp_process_suppress: allowDisplayUpdates %d bytes " + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_suppress: allowDisplayUpdates %d bytes " "left %d", allowDisplayUpdates, (int) (s->end - s->p)); switch (allowDisplayUpdates) { case 0: /* SUPPRESS_DISPLAY_UPDATES */ self->client_info.suppress_output = 1; - g_writeln("xrdp_rdp_process_suppress: suppress_output %d", + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_suppress: suppress_output %d", self->client_info.suppress_output); if (self->session->callback != 0) { @@ -1267,7 +1267,7 @@ in_uint16_le(s, top); in_uint16_le(s, right); in_uint16_le(s, bottom); - g_writeln("xrdp_rdp_process_suppress: suppress_output %d " + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_suppress: suppress_output %d " "left %d top %d right %d bottom %d", self->client_info.suppress_output, left, top, right, bottom); @@ -1310,7 +1310,7 @@ { return 1; } - DEBUG(("xrdp_rdp_process_data pduType2 %d", pduType2)); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data pduType2 %d", pduType2); switch (pduType2) { case RDP_DATA_PDU_POINTER: /* 27(0x1b) */ @@ -1344,7 +1344,7 @@ xrdp_rdp_process_frame_ack(self, s); break; default: - g_writeln("unknown in xrdp_rdp_process_data pduType2 %d", pduType2); + LOG_DEVEL(LOG_LEVEL_TRACE, "unknown in xrdp_rdp_process_data pduType2 %d", pduType2); break; } return 0; @@ -1355,9 +1355,9 @@ { int rv; - DEBUG(("in xrdp_rdp_disconnect")); + LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_disconnect"); rv = xrdp_sec_disconnect(self->sec_layer); - DEBUG(("out xrdp_rdp_disconnect")); + LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_disconnect"); return rv; } @@ -1367,14 +1367,14 @@ { struct stream *s; - DEBUG(("in xrdp_rdp_send_deactivate")); + LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_send_deactivate"); make_stream(s); init_stream(s, 8192); if (xrdp_rdp_init(self, s) != 0) { free_stream(s); - DEBUG(("out xrdp_rdp_send_deactivate error")); + LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send_deactivate error"); return 1; } @@ -1383,12 +1383,12 @@ if (xrdp_rdp_send(self, s, PDUTYPE_DEACTIVATEALLPDU) != 0) { free_stream(s); - DEBUG(("out xrdp_rdp_send_deactivate error")); + LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send_deactivate error"); return 1; } free_stream(s); - DEBUG(("out xrdp_rdp_send_deactivate")); + LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_send_deactivate"); return 0; } @@ -1399,7 +1399,7 @@ { struct stream *s; - LLOGLN(0, ("xrdp_rdp_send_session_info: data_bytes %d", data_bytes)); + LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_rdp_send_session_info: data_bytes %d", data_bytes); make_stream(s); init_stream(s, 8192); @@ -1411,7 +1411,7 @@ if (s_check_rem_out(s, data_bytes)) { - out_uint8a(s, data, data_bytes); + out_uint8a(s, data, data_bytes); } else { diff -Nru xrdp-0.9.12/libxrdp/xrdp_sec.c xrdp-0.9.15/libxrdp/xrdp_sec.c --- xrdp-0.9.12/libxrdp/xrdp_sec.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/libxrdp/xrdp_sec.c 2020-12-28 14:03:43.000000000 +0000 @@ -23,15 +23,11 @@ #endif #include "libxrdp.h" +#include "ms-rdpbcgr.h" #include "log.h" +#include "string_calls.h" + -#define LOG_LEVEL 1 -#define LLOG(_level, _args) \ - do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0) -#define LLOGLN(_level, _args) \ - do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0) -#define LHEXDUMP(_level, _args) \ - do { if (_level < LOG_LEVEL) { g_hexdump _args ; } } while (0) /* some compilers need unsigned char to avoid warnings */ static tui8 g_pad_54[40] = @@ -240,8 +236,8 @@ char keyboard_cfg_file[256] = { 0 }; char rdp_layout[256] = { 0 }; - LLOGLN(0, ("xrdp_load_keyboard_layout: keyboard_type [%d] keyboard_subtype [%d]", - client_info->keyboard_type, client_info->keyboard_subtype)); + LOG(LOG_LEVEL_INFO, "xrdp_load_keyboard_layout: keyboard_type [%d] keyboard_subtype [%d]", + client_info->keyboard_type, client_info->keyboard_subtype); /* infer model/variant */ /* TODO specify different X11 keyboard models/variants */ @@ -261,7 +257,7 @@ } g_snprintf(keyboard_cfg_file, 255, "%s/xrdp_keyboard.ini", XRDP_CFG_PATH); - LLOGLN(10, ("keyboard_cfg_file %s", keyboard_cfg_file)); + LOG(LOG_LEVEL_DEBUG, "keyboard_cfg_file %s", keyboard_cfg_file); fd = g_file_open(keyboard_cfg_file); @@ -292,8 +288,8 @@ { item = (char *)list_get_item(items, i); value = (char *)list_get_item(values, i); - LLOGLN(10, ("xrdp_load_keyboard_layout: item %s value %s", - item, value)); + LOG(LOG_LEVEL_DEBUG, "xrdp_load_keyboard_layout: item %s value %s", + item, value); if (g_strcasecmp(item, "keyboard_type") == 0) { int v = g_atoi(value); @@ -306,7 +302,7 @@ { int v = g_atoi(value); if (v != client_info->keyboard_subtype && - section_found == index) + section_found == index) { section_found = -1; break; @@ -359,9 +355,9 @@ * mixing items from different sections will result in * skipping over current section. */ - LLOGLN(10, ("xrdp_load_keyboard_layout: skipping " - "configuration item - %s, continuing to next " - "section", item)); + LOG(LOG_LEVEL_DEBUG, "xrdp_load_keyboard_layout: skipping " + "configuration item - %s, continuing to next " + "section", item); break; } } @@ -427,15 +423,15 @@ list_delete(items); list_delete(values); - LLOGLN(0, ("xrdp_load_keyboard_layout: model [%s] variant [%s] " - "layout [%s] options [%s]", client_info->model, - client_info->variant, client_info->layout, client_info->options)); + LOG(LOG_LEVEL_INFO, "xrdp_load_keyboard_layout: model [%s] variant [%s] " + "layout [%s] options [%s]", client_info->model, + client_info->variant, client_info->layout, client_info->options); g_file_close(fd); } else { - LLOGLN(0, ("xrdp_load_keyboard_layout: error opening %s", - keyboard_cfg_file)); + LOG(LOG_LEVEL_ERROR, "xrdp_load_keyboard_layout: error opening %s", + keyboard_cfg_file); } } @@ -445,7 +441,7 @@ { struct xrdp_sec *self; - DEBUG((" in xrdp_sec_create")); + LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_create"); self = (struct xrdp_sec *) g_malloc(sizeof(struct xrdp_sec), 1); self->rdp_layer = owner; self->crypt_method = CRYPT_METHOD_NONE; /* set later */ @@ -455,7 +451,7 @@ self->fastpath_layer = xrdp_fastpath_create(self, trans); self->chan_layer = xrdp_channel_create(self, self->mcs_layer); self->is_security_header_present = 1; - DEBUG((" out xrdp_sec_create")); + LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_create"); return self; } @@ -466,7 +462,7 @@ { if (self == 0) { - g_writeln("xrdp_sec_delete: self is null"); + LOG(LOG_LEVEL_ERROR, "xrdp_sec_delete: self is null"); return; } @@ -566,7 +562,7 @@ static void xrdp_sec_fips_decrypt(struct xrdp_sec *self, char *data, int len) { - LLOGLN(10, ("xrdp_sec_fips_decrypt:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_fips_decrypt:"); ssl_des3_decrypt(self->decrypt_fips_info, len, data, data); self->decrypt_use_count++; } @@ -575,7 +571,7 @@ static void xrdp_sec_decrypt(struct xrdp_sec *self, char *data, int len) { - LLOGLN(10, ("xrdp_sec_decrypt:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_decrypt:"); if (self->decrypt_use_count == 4096) { xrdp_sec_update(self->decrypt_key, self->decrypt_update_key, @@ -592,7 +588,7 @@ static void xrdp_sec_fips_encrypt(struct xrdp_sec *self, char *data, int len) { - LLOGLN(10, ("xrdp_sec_fips_encrypt:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_fips_encrypt:"); ssl_des3_encrypt(self->encrypt_fips_info, len, data, data); self->encrypt_use_count++; } @@ -601,7 +597,7 @@ static void xrdp_sec_encrypt(struct xrdp_sec *self, char *data, int len) { - LLOGLN(10, ("xrdp_sec_encrypt:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_encrypt:"); if (self->encrypt_use_count == 4096) { xrdp_sec_update(self->encrypt_key, self->encrypt_update_key, @@ -627,7 +623,7 @@ int i; int bytes; - LLOGLN(10, ("unicode_utf16_in: uni_len %d, dst_len %d", src_bytes, dst_len)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "unicode_utf16_in: uni_len %d, dst_len %d", src_bytes, dst_len); if (src_bytes == 0) { if (!s_check_rem(s, 2)) @@ -654,7 +650,7 @@ { g_memset(dst, '\0', dst_len); } - LLOGLN(10, ("unicode_utf16_in: num_chars %d, dst %s", num_chars, dst)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "unicode_utf16_in: num_chars %d, dst %s", num_chars, dst); g_free(src); return 0; @@ -674,6 +670,7 @@ int len_ip = 0; int len_dll = 0; char tmpdata[256]; + const char *sep; /* initialize (zero out) local variables */ g_memset(tmpdata, 0, sizeof(char) * 256); @@ -683,48 +680,47 @@ } in_uint8s(s, 4); in_uint32_le(s, flags); - DEBUG(("in xrdp_sec_process_logon_info flags $%x", flags)); + LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_sec_process_logon_info flags $%x", flags); /* this is the first test that the decrypt is working */ if ((flags & RDP_LOGON_NORMAL) != RDP_LOGON_NORMAL) /* 0x33 */ { /* must be or error */ - DEBUG(("xrdp_sec_process_logon_info: flags wrong, major error")); - LLOGLN(0, ("xrdp_sec_process_logon_info: flags wrong, likely decrypt " - "not working")); + LOG(LOG_LEVEL_ERROR, "xrdp_sec_process_logon_info: flags wrong, likely decrypt " + "not working"); return 1; } if (flags & RDP_LOGON_LEAVE_AUDIO) { self->rdp_layer->client_info.sound_code = 1; - DEBUG(("flag RDP_LOGON_LEAVE_AUDIO found")); + LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_LOGON_LEAVE_AUDIO found"); } if (flags & RDP_LOGON_RAIL) { self->rdp_layer->client_info.rail_enable = 1; - DEBUG(("flag RDP_LOGON_RAIL found")); + LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_LOGON_RAIL found"); } if ((flags & RDP_LOGON_AUTO) && (!self->rdp_layer->client_info.is_mce)) /* todo, for now not allowing autologon and mce both */ { self->rdp_layer->client_info.rdp_autologin = 1; - DEBUG(("flag RDP_LOGON_AUTO found")); + LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_LOGON_AUTO found"); } if (flags & RDP_COMPRESSION) { - DEBUG(("flag RDP_COMPRESSION found")); + LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_COMPRESSION found"); if (self->rdp_layer->client_info.use_bulk_comp) { - DEBUG(("flag RDP_COMPRESSION set")); + LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_COMPRESSION set"); self->rdp_layer->client_info.rdp_compression = 1; } else { - DEBUG(("flag RDP_COMPRESSION not set")); + LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_COMPRESSION not set"); } } @@ -734,9 +730,9 @@ } 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")); + LOG(LOG_LEVEL_ERROR, "ERROR [xrdp_sec_process_logon_info()]: len_domain >= %d", INFO_CLIENT_MAX_CB_LEN); return 1; } @@ -756,9 +752,9 @@ 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")); + LOG(LOG_LEVEL_ERROR, "ERROR [xrdp_sec_process_logon_info()]: len_user >= %d", INFO_CLIENT_MAX_CB_LEN); return 1; } @@ -768,9 +764,9 @@ } 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")); + LOG(LOG_LEVEL_ERROR, "ERROR [xrdp_sec_process_logon_info()]: len_password >= %d", INFO_CLIENT_MAX_CB_LEN); return 1; } @@ -780,9 +776,9 @@ } 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")); + LOG(LOG_LEVEL_ERROR, "ERROR [xrdp_sec_process_logon_info()]: len_program >= %d", INFO_CLIENT_MAX_CB_LEN); return 1; } @@ -792,9 +788,9 @@ } 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")); + LOG(LOG_LEVEL_ERROR, "ERROR [xrdp_sec_process_logon_info()]: len_directory >= %d", INFO_CLIENT_MAX_CB_LEN); return 1; } @@ -802,12 +798,12 @@ { return 1; } - DEBUG(("domain %s", self->rdp_layer->client_info.domain)); + LOG_DEVEL(LOG_LEVEL_TRACE, "domain %s", self->rdp_layer->client_info.domain); if (unicode_utf16_in(s, len_user, self->rdp_layer->client_info.username, sizeof(self->rdp_layer->client_info.username) - 1) != 0) { return 1; } - DEBUG(("username %s", self->rdp_layer->client_info.username)); + if (flags & RDP_LOGON_AUTO) { @@ -815,7 +811,18 @@ { return 1; } - DEBUG(("flag RDP_LOGON_AUTO found")); + LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_LOGON_AUTO found"); + } + else if (self->rdp_layer->client_info.enable_token_login + && len_user > 0 + && len_password == 0 + && (sep = g_strchr(self->rdp_layer->client_info.username, '\x1f')) != NULL) + { + LOG_DEVEL(LOG_LEVEL_TRACE, "Logon token detected"); + g_strncpy(self->rdp_layer->client_info.password, sep + 1, + sizeof(self->rdp_layer->client_info.password) - 1); + self->rdp_layer->client_info.username[sep - self->rdp_layer->client_info.username] = '\0'; + self->rdp_layer->client_info.rdp_autologin = 1; } else { @@ -826,21 +833,29 @@ in_uint8s(s, len_password + 2); if (self->rdp_layer->client_info.require_credentials) { - g_writeln("xrdp_sec_process_logon_info: credentials on cmd line is mandatory"); + LOG(LOG_LEVEL_ERROR, "xrdp_sec_process_logon_info: credentials on cmd line is mandatory"); return 1; /* credentials on cmd line is mandatory */ } } + if (self->rdp_layer->client_info.domain_user_separator[0] != '\0' + && self->rdp_layer->client_info.domain[0] != '\0') + { + int size = sizeof(self->rdp_layer->client_info.username); + g_strncat(self->rdp_layer->client_info.username, self->rdp_layer->client_info.domain_user_separator, size - 1 - g_strlen(self->rdp_layer->client_info.domain_user_separator)); + g_strncat(self->rdp_layer->client_info.username, self->rdp_layer->client_info.domain, size - 1 - g_strlen(self->rdp_layer->client_info.domain)); + } + LOG_DEVEL(LOG_LEVEL_TRACE, "username %s", self->rdp_layer->client_info.username); if (unicode_utf16_in(s, len_program, self->rdp_layer->client_info.program, sizeof(self->rdp_layer->client_info.program) - 1) != 0) { return 1; } - DEBUG(("program %s", self->rdp_layer->client_info.program)); + LOG_DEVEL(LOG_LEVEL_TRACE, "program %s", self->rdp_layer->client_info.program); if (unicode_utf16_in(s, len_directory, self->rdp_layer->client_info.directory, sizeof(self->rdp_layer->client_info.directory) - 1) != 0) { return 1; } - DEBUG(("directory %s", self->rdp_layer->client_info.directory)); + LOG_DEVEL(LOG_LEVEL_TRACE, "directory %s", self->rdp_layer->client_info.directory); if (flags & RDP_LOGON_BLOB) { @@ -875,7 +890,7 @@ in_uint32_le(s, self->rdp_layer->client_info.rdp5_performanceflags); } - DEBUG(("out xrdp_sec_process_logon_info")); + LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_sec_process_logon_info"); return 0; } @@ -886,7 +901,7 @@ { struct stream *s; - LLOGLN(10, ("xrdp_sec_send_lic_initial:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_lic_initial:"); make_stream(s); init_stream(s, 8192); @@ -1079,7 +1094,7 @@ const char *fips_ivec; void *sha1; - LLOGLN(0, ("xrdp_sec_fips_establish_keys:")); + LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_sec_fips_establish_keys:"); sha1 = ssl_sha1_info_create(); ssl_sha1_clear(sha1); @@ -1109,9 +1124,9 @@ fips_ivec = (const char *) g_fips_ivec; self->encrypt_fips_info = - ssl_des3_encrypt_info_create(self->fips_encrypt_key, fips_ivec); + ssl_des3_encrypt_info_create(self->fips_encrypt_key, fips_ivec); self->decrypt_fips_info = - ssl_des3_decrypt_info_create(self->fips_decrypt_key, fips_ivec); + ssl_des3_decrypt_info_create(self->fips_decrypt_key, fips_ivec); self->sign_fips_info = ssl_hmac_info_create(); } @@ -1123,7 +1138,7 @@ char temp_hash[48]; char input[48]; - LLOGLN(0, ("xrdp_sec_establish_keys:")); + LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_sec_establish_keys:"); g_memcpy(input, self->client_random, 24); g_memcpy(input + 24, self->server_random, 24); @@ -1164,7 +1179,13 @@ int len; int pad; - LLOGLN(10, ("xrdp_sec_recv_fastpath:")); +#ifndef XRDP_DEBUG + /* TODO: remove UNUSED_VAR once the `var` variable is used for more than + logging in debug mode */ + UNUSED_VAR(ver); +#endif + + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv_fastpath:"); if (xrdp_fastpath_recv(self->fastpath_layer, s) != 0) { return 1; @@ -1185,9 +1206,9 @@ return 1; } in_uint8(s, pad); - LLOGLN(10, ("xrdp_sec_recv_fastpath: len %d ver %d pad %d", len, ver, pad)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv_fastpath: len %d ver %d pad %d", len, ver, pad); in_uint8s(s, 8); /* dataSignature (8 bytes), skip for now */ - LLOGLN(10, ("xrdp_sec_recv_fastpath: data len %d", (int)(s->end - s->p))); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv_fastpath: data len %d", (int)(s->end - s->p)); xrdp_sec_fips_decrypt(self, s->p, (int)(s->end - s->p)); s->end -= pad; } @@ -1227,12 +1248,11 @@ int ver; int pad; - DEBUG((" in xrdp_sec_recv")); + LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_recv"); if (xrdp_mcs_recv(self->mcs_layer, s, chan) != 0) { - DEBUG((" out xrdp_sec_recv : error")); - g_writeln("xrdp_sec_recv: xrdp_mcs_recv failed"); + LOG(LOG_LEVEL_ERROR, " out xrdp_sec_recv : error"); return 1; } @@ -1248,7 +1268,7 @@ } in_uint32_le(s, flags); - DEBUG((" in xrdp_sec_recv flags $%x", flags)); + LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_recv flags $%x", flags); if (flags & SEC_ENCRYPT) /* 0x08 */ { @@ -1265,9 +1285,9 @@ return 1; } in_uint8(s, pad); - LLOGLN(10, ("xrdp_sec_recv: len %d ver %d pad %d", len, ver, pad)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv: len %d ver %d pad %d", len, ver, pad); in_uint8s(s, 8); /* signature(8) */ - LLOGLN(10, ("xrdp_sec_recv: data len %d", (int)(s->end - s->p))); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv: data len %d", (int)(s->end - s->p)); xrdp_sec_fips_decrypt(self, s->p, (int)(s->end - s->p)); s->end -= pad; } @@ -1301,9 +1321,9 @@ in_uint8a(s, self->client_crypt_random, len - 8); xrdp_sec_rsa_op(self, self->client_random, self->client_crypt_random, len - 8, self->pub_mod, self->pri_exp); - LLOGLN(10, ("xrdp_sec_recv: client random - len %d", len)); - LHEXDUMP(10, (self->client_random, 256)); - LHEXDUMP(10, (self->client_crypt_random, len - 8)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv: client random - len %d", len); + LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "client random", self->client_random, 256); + LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "client crypt random", self->client_crypt_random, len - 8); if (self->crypt_level == CRYPT_LEVEL_FIPS) { xrdp_sec_fips_establish_keys(self); @@ -1313,7 +1333,7 @@ xrdp_sec_establish_keys(self); } *chan = 1; /* just set a non existing channel and exit */ - DEBUG((" out xrdp_sec_recv")); + LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_recv"); return 0; } @@ -1321,7 +1341,7 @@ { if (xrdp_sec_process_logon_info(self, s) != 0) { - DEBUG((" out xrdp_sec_recv error")); + LOG(LOG_LEVEL_ERROR, " out xrdp_sec_recv error"); return 1; } @@ -1329,22 +1349,22 @@ { if (xrdp_sec_send_media_lic_response(self) != 0) { - DEBUG((" out xrdp_sec_recv error")); + LOG(LOG_LEVEL_ERROR, " out xrdp_sec_recv error"); return 1; } - DEBUG((" out xrdp_sec_recv")); + LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_recv"); return -1; /* special error that means send demand active */ } if (xrdp_sec_send_lic_initial(self) != 0) { - DEBUG((" out xrdp_sec_recv error")); + LOG(LOG_LEVEL_ERROR, " out xrdp_sec_recv error"); return 1; } *chan = 1; /* just set a non existing channel and exit */ - DEBUG((" out xrdp_sec_recv")); + LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_recv"); return 0; } @@ -1352,7 +1372,7 @@ { if (xrdp_sec_send_lic_response(self) != 0) { - DEBUG((" out xrdp_sec_recv error")); + LOG(LOG_LEVEL_ERROR, " out xrdp_sec_recv error"); return 1; } @@ -1363,11 +1383,11 @@ self->is_security_header_present = 0; } - DEBUG((" out xrdp_sec_recv")); + LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_recv"); return -1; /* special error that means send demand active */ } - DEBUG((" out xrdp_sec_recv")); + LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_recv"); return 0; } @@ -1438,15 +1458,15 @@ int datalen; int pad; - LLOGLN(10, ("xrdp_sec_send:")); - DEBUG((" in xrdp_sec_send")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send:"); + LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_send"); s_pop_layer(s, sec_hdr); if (self->crypt_level > CRYPT_LEVEL_NONE) { if (self->crypt_level == CRYPT_LEVEL_FIPS) { - LLOGLN(10, ("xrdp_sec_send: fips")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send: fips"); out_uint32_le(s, SEC_ENCRYPT); datalen = (int)((s->end - s->p) - 12); out_uint16_le(s, 16); /* crypto header size */ @@ -1476,7 +1496,7 @@ return 1; } - DEBUG((" out xrdp_sec_send")); + LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_send"); return 0; } @@ -1535,12 +1555,12 @@ int error; char save[8]; - LLOGLN(10, ("xrdp_sec_send_fastpath:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_fastpath:"); error = 0; s_pop_layer(s, sec_hdr); if (self->crypt_level == CRYPT_LEVEL_FIPS) { - LLOGLN(10, ("xrdp_sec_send_fastpath: fips")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_fastpath: fips"); pdulen = (int)(s->end - s->p); datalen = pdulen - 15; pad = (8 - (datalen % 8)) & 7; @@ -1563,7 +1583,7 @@ } else if (self->crypt_level > CRYPT_LEVEL_LOW) { - LLOGLN(10, ("xrdp_sec_send_fastpath: crypt")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_fastpath: crypt"); pdulen = (int)(s->end - s->p); datalen = pdulen - 11; secFlags = 0x2; @@ -1577,9 +1597,9 @@ } else { - LLOGLN(10, ("xrdp_sec_send_fastpath: no crypt")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_fastpath: no crypt"); pdulen = (int)(s->end - s->p); - LLOGLN(10, ("xrdp_sec_send_fastpath: pdulen %d", pdulen)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_fastpath: pdulen %d", pdulen); secFlags = 0x0; fpOutputHeader = secFlags << 6; out_uint8(s, fpOutputHeader); @@ -1598,7 +1618,7 @@ /* http://msdn.microsoft.com/en-us/library/cc240510.aspx 2.2.1.3.2 Client Core Data (TS_UD_CS_CORE) */ static int -xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec* self, struct stream* s) +xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s) { int colorDepth; int postBeta2ColorDepth; @@ -1611,7 +1631,7 @@ in_uint16_le(s, self->rdp_layer->client_info.width); in_uint16_le(s, self->rdp_layer->client_info.height); in_uint16_le(s, colorDepth); - g_writeln("colorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp)", colorDepth); + LOG_DEVEL(LOG_LEVEL_TRACE, "colorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp)", colorDepth); switch (colorDepth) { case RNS_UD_COLOR_4BPP: @@ -1625,13 +1645,13 @@ in_uint8s(s, 4); /* keyboardLayout */ in_uint8s(s, 4); /* clientBuild */ unicode_utf16_in(s, INFO_CLIENT_NAME_BYTES - 2, clientName, sizeof(clientName) - 1); /* clientName */ - log_message(LOG_LEVEL_INFO, "connected client computer name: %s", clientName); + LOG(LOG_LEVEL_INFO, "connected client computer name: %s", clientName); in_uint8s(s, 4); /* keyboardType */ in_uint8s(s, 4); /* keyboardSubType */ in_uint8s(s, 4); /* keyboardFunctionKey */ in_uint8s(s, 64); /* imeFileName */ in_uint16_le(s, postBeta2ColorDepth); - g_writeln("postBeta2ColorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp " + LOG_DEVEL(LOG_LEVEL_TRACE, "postBeta2ColorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp " "0xca02 15bpp 0xca03 16bpp 0xca04 24bpp)", postBeta2ColorDepth); switch (postBeta2ColorDepth) @@ -1669,7 +1689,7 @@ return 0; } in_uint16_le(s, highColorDepth); - g_writeln("highColorDepth 0x%4.4x (0x0004 4bpp 0x0008 8bpp 0x000f 15bpp " + LOG_DEVEL(LOG_LEVEL_TRACE, "highColorDepth 0x%4.4x (0x0004 4bpp 0x0008 8bpp 0x000f 15bpp " "0x0010 16 bpp 0x0018 24bpp)", highColorDepth); self->rdp_layer->client_info.bpp = highColorDepth; @@ -1678,7 +1698,7 @@ return 0; } in_uint16_le(s, supportedColorDepths); - g_writeln("supportedColorDepths 0x%4.4x (0x0001 24bpp 0x0002 16bpp " + LOG_DEVEL(LOG_LEVEL_TRACE, "supportedColorDepths 0x%4.4x (0x0001 24bpp 0x0002 16bpp " "0x0004 15bpp 0x0008 32bpp)", supportedColorDepths); if (!s_check_rem(s, 2)) @@ -1687,7 +1707,7 @@ } in_uint16_le(s, earlyCapabilityFlags); self->rdp_layer->client_info.mcs_early_capability_flags = earlyCapabilityFlags; - g_writeln("earlyCapabilityFlags 0x%4.4x (0x0002 want32)", + LOG_DEVEL(LOG_LEVEL_TRACE, "earlyCapabilityFlags 0x%4.4x (0x0002 want32)", earlyCapabilityFlags); if ((earlyCapabilityFlags & 0x0002) && (supportedColorDepths & 0x0008)) { @@ -1705,7 +1725,7 @@ return 0; } in_uint8(s, self->rdp_layer->client_info.mcs_connection_type); /* connectionType */ - g_writeln("got client client connection type 0x%8.8x", + LOG_DEVEL(LOG_LEVEL_TRACE, "got client client connection type 0x%8.8x", self->rdp_layer->client_info.mcs_connection_type); if (!s_check_rem(s, 1)) @@ -1743,98 +1763,98 @@ /*****************************************************************************/ static int -xrdp_sec_process_mcs_data_CS_SECURITY(struct xrdp_sec *self, struct stream* s) +xrdp_sec_process_mcs_data_CS_SECURITY(struct xrdp_sec *self, struct stream *s) { int crypt_method; int found; - g_writeln("xrdp_sec_process_mcs_data_CS_SECURITY:"); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_process_mcs_data_CS_SECURITY:"); in_uint32_le(s, crypt_method); if (crypt_method & CRYPT_METHOD_40BIT) { - g_writeln(" client supports 40 bit encryption"); + LOG(LOG_LEVEL_INFO, " client supports 40 bit encryption"); } if (crypt_method & CRYPT_METHOD_128BIT) { - g_writeln(" client supports 128 bit encryption"); + LOG(LOG_LEVEL_INFO, " client supports 128 bit encryption"); } if (crypt_method & CRYPT_METHOD_56BIT) { - g_writeln(" client supports 56 bit encryption"); + LOG(LOG_LEVEL_INFO, " client supports 56 bit encryption"); } if (crypt_method & CRYPT_METHOD_FIPS) { - g_writeln(" client supports fips encryption"); + LOG(LOG_LEVEL_INFO, " client supports fips encryption"); } found = 0; if ((found == 0) && - (self->crypt_method & CRYPT_METHOD_FIPS) && - (self->crypt_level == CRYPT_LEVEL_FIPS)) + (self->crypt_method & CRYPT_METHOD_FIPS) && + (self->crypt_level == CRYPT_LEVEL_FIPS)) { if (crypt_method & CRYPT_METHOD_FIPS) { - g_writeln(" client and server support fips, using fips"); + LOG(LOG_LEVEL_INFO, " client and server support fips, using fips"); self->crypt_method = CRYPT_METHOD_FIPS; self->crypt_level = CRYPT_LEVEL_FIPS; found = 1; } } if ((found == 0) && - (self->crypt_method & CRYPT_METHOD_128BIT) && - (self->crypt_level == CRYPT_LEVEL_HIGH)) + (self->crypt_method & CRYPT_METHOD_128BIT) && + (self->crypt_level == CRYPT_LEVEL_HIGH)) { if (crypt_method & CRYPT_METHOD_128BIT) { - g_writeln(" client and server support high crypt, using " - "high crypt"); + LOG(LOG_LEVEL_INFO, " client and server support high crypt, using " + "high crypt"); self->crypt_method = CRYPT_METHOD_128BIT; self->crypt_level = CRYPT_LEVEL_HIGH; found = 1; } } if ((found == 0) && - (self->crypt_method & CRYPT_METHOD_40BIT) && - (self->crypt_level == CRYPT_LEVEL_CLIENT_COMPATIBLE)) + (self->crypt_method & CRYPT_METHOD_40BIT) && + (self->crypt_level == CRYPT_LEVEL_CLIENT_COMPATIBLE)) { if (crypt_method & CRYPT_METHOD_40BIT) { - g_writeln(" client and server support medium crypt, using " - "medium crypt"); + LOG(LOG_LEVEL_INFO, " client and server support medium crypt, using " + "medium crypt"); self->crypt_method = CRYPT_METHOD_40BIT; self->crypt_level = CRYPT_LEVEL_CLIENT_COMPATIBLE; found = 1; } } if ((found == 0) && - (self->crypt_method & CRYPT_METHOD_40BIT) && - (self->crypt_level == CRYPT_LEVEL_LOW)) + (self->crypt_method & CRYPT_METHOD_40BIT) && + (self->crypt_level == CRYPT_LEVEL_LOW)) { if (crypt_method & CRYPT_METHOD_40BIT) { - g_writeln(" client and server support low crypt, using " - "low crypt"); + LOG(LOG_LEVEL_INFO, " client and server support low crypt, using " + "low crypt"); self->crypt_method = CRYPT_METHOD_40BIT; self->crypt_level = CRYPT_LEVEL_LOW; found = 1; } } if ((found == 0) && - (self->crypt_level == CRYPT_LEVEL_NONE)) + (self->crypt_level == CRYPT_LEVEL_NONE)) { if (crypt_method == CRYPT_METHOD_NONE) { - g_writeln(" client and server support none crypt, using " - "none crypt"); + LOG(LOG_LEVEL_INFO, " client and server support none crypt, using " + "none crypt"); self->crypt_method = CRYPT_METHOD_NONE; self->crypt_level = CRYPT_LEVEL_NONE; found = 1; } } -// if (found == 0) -// { -// g_writeln(" can not find client / server agreed encryption method"); -// return 1; -// } + // if (found == 0) + // { + // LOG_DEVEL(LOG_LEVEL_TRACE, " can not find client / server agreed encryption method"); + // return 1; + // } return 0; } @@ -1850,13 +1870,13 @@ struct mcs_channel_item *channel_item; client_info = &(self->rdp_layer->client_info); - DEBUG(("processing channels, channels_allowed is %d", - client_info->channels_allowed)); + LOG_DEVEL(LOG_LEVEL_TRACE, "processing channels, channels_allowed is %d", + client_info->channels_allowed); /* this is an option set in xrdp.ini */ if (client_info->channels_allowed == 0) /* are channels on? */ { - log_message(LOG_LEVEL_INFO, "all channels are disabled by " - "configuration"); + LOG(LOG_LEVEL_INFO, "all channels are disabled by " + "configuration"); return 0; } if (!s_check_rem(s, 4)) @@ -1881,13 +1901,13 @@ if (g_strlen(channel_item->name) > 0) { channel_item->chanid = MCS_GLOBAL_CHANNEL + (index + 1); - log_message(LOG_LEVEL_INFO, "adding channel item name %s chan_id " - "%d flags 0x%8.8x", channel_item->name, - channel_item->chanid, channel_item->flags); + LOG(LOG_LEVEL_INFO, "adding channel item name %s chan_id " + "%d flags 0x%8.8x", channel_item->name, + channel_item->chanid, channel_item->flags); list_add_item(self->mcs_layer->channel_list, (intptr_t) channel_item); - DEBUG(("got channel flags %8.8x name %s", channel_item->flags, - channel_item->name)); + LOG_DEVEL(LOG_LEVEL_TRACE, "got channel flags %8.8x name %s", channel_item->flags, + channel_item->name); } else { @@ -1914,32 +1934,32 @@ client_info = &(self->rdp_layer->client_info); - LLOGLN(10, ("xrdp_sec_process_mcs_data_monitors: processing monitors data, allow_multimon is %d", client_info->multimon)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_process_mcs_data_monitors: processing monitors data, allow_multimon is %d", client_info->multimon); /* this is an option set in xrdp.ini */ if (client_info->multimon != 1) /* are multi-monitors allowed ? */ { - LLOGLN(0, ("[INFO] xrdp_sec_process_mcs_data_monitors: multimon is not " - "allowed, skipping")); + LOG_DEVEL(LOG_LEVEL_INFO, "[INFO] xrdp_sec_process_mcs_data_monitors: multimon is not " + "allowed, skipping"); return 0; } in_uint32_le(s, flags); /* flags */ //verify flags - must be 0x0 if (flags != 0) { - LLOGLN(0, ("[ERROR] xrdp_sec_process_mcs_data_monitors: flags MUST be " - "zero, detected: %d", flags)); + LOG(LOG_LEVEL_ERROR, "[ERROR] xrdp_sec_process_mcs_data_monitors: flags MUST be " + "zero, detected: %d", flags); return 1; } in_uint32_le(s, monitorCount); //verify monitorCount - max 16 if (monitorCount > 16) { - LLOGLN(0, ("[ERROR] xrdp_sec_process_mcs_data_monitors: max allowed " - "monitors is 16, detected: %d", monitorCount)); + LOG(LOG_LEVEL_ERROR, "[ERROR] xrdp_sec_process_mcs_data_monitors: max allowed " + "monitors is 16, detected: %d", monitorCount); return 1; } - LLOGLN(10, ("xrdp_sec_process_mcs_data_monitors: monitorCount= %d", monitorCount)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_process_mcs_data_monitors: monitorCount= %d", monitorCount); client_info->monitorCount = monitorCount; @@ -1976,13 +1996,13 @@ got_primary = 1; } - LLOGLN(10, ("xrdp_sec_process_mcs_data_monitors: got a monitor [%d]: left= %d, top= %d, right= %d, bottom= %d, is_primary?= %d", - index, - client_info->minfo[index].left, - client_info->minfo[index].top, - client_info->minfo[index].right, - client_info->minfo[index].bottom, - client_info->minfo[index].is_primary)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_process_mcs_data_monitors: got a monitor [%d]: left= %d, top= %d, right= %d, bottom= %d, is_primary?= %d", + index, + client_info->minfo[index].left, + client_info->minfo[index].top, + client_info->minfo[index].right, + client_info->minfo[index].bottom, + client_info->minfo[index].is_primary); } if (!got_primary) @@ -2007,9 +2027,9 @@ } /* make sure virtual desktop size is ok */ if (client_info->width > 0x7FFE || client_info->width < 0xC8 || - client_info->height > 0x7FFE || client_info->height < 0xC8) + client_info->height > 0x7FFE || client_info->height < 0xC8) { - LLOGLN(0, ("[ERROR] xrdp_sec_process_mcs_data_monitors: error, virtual desktop width / height is too large")); + LOG(LOG_LEVEL_ERROR, "[ERROR] xrdp_sec_process_mcs_data_monitors: error, virtual desktop width / height is too large"); return 1; /* error */ } @@ -2055,12 +2075,12 @@ if ((size < 4) || (!s_check_rem(s, size - 4))) { - LLOGLN(0, ("error in xrdp_sec_process_mcs_data tag %d size %d", - tag, size)); + LOG(LOG_LEVEL_ERROR, "error in xrdp_sec_process_mcs_data tag %d size %d", + tag, size); break; } - LLOGLN(10, ("xrdp_sec_process_mcs_data: 0x%8.8x", tag)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_process_mcs_data: 0x%8.8x", tag); switch (tag) { case SEC_TAG_CLI_INFO: /* CS_CORE 0xC001 */ @@ -2089,17 +2109,17 @@ return 1; } break; - /* CS_MCS_MSGCHANNEL 0xC006 - CS_MONITOR_EX 0xC008 - CS_MULTITRANSPORT 0xC00A - SC_CORE 0x0C01 - SC_SECURITY 0x0C02 - SC_NET 0x0C03 - SC_MCS_MSGCHANNEL 0x0C04 - SC_MULTITRANSPORT 0x0C08 */ + /* CS_MCS_MSGCHANNEL 0xC006 + CS_MONITOR_EX 0xC008 + CS_MULTITRANSPORT 0xC00A + SC_CORE 0x0C01 + SC_SECURITY 0x0C02 + SC_NET 0x0C03 + SC_MCS_MSGCHANNEL 0x0C04 + SC_MULTITRANSPORT 0x0C08 */ default: - LLOGLN(0, ("error unknown xrdp_sec_process_mcs_data " - "tag 0x%4.4x size %d", tag, size)); + LOG(LOG_LEVEL_ERROR, "error unknown xrdp_sec_process_mcs_data " + "tag 0x%4.4x size %d", tag, size); break; } @@ -2109,14 +2129,14 @@ if (self->rdp_layer->client_info.max_bpp > 0) { if (self->rdp_layer->client_info.bpp > - self->rdp_layer->client_info.max_bpp) + self->rdp_layer->client_info.max_bpp) { - LLOGLN(0, ("xrdp_rdp_parse_client_mcs_data: client asked " - "for %dbpp connection but configuration is limited " - "to %dbpp", self->rdp_layer->client_info.bpp, - self->rdp_layer->client_info.max_bpp)); + LOG(LOG_LEVEL_INFO, "xrdp_rdp_parse_client_mcs_data: client asked " + "for %dbpp connection but configuration is limited " + "to %dbpp", self->rdp_layer->client_info.bpp, + self->rdp_layer->client_info.max_bpp); self->rdp_layer->client_info.bpp = - self->rdp_layer->client_info.max_bpp; + self->rdp_layer->client_info.max_bpp; } } @@ -2217,13 +2237,13 @@ self->crypt_level = CRYPT_LEVEL_FIPS; break; default: - g_writeln("Fatal : Illegal crypt_level"); + LOG_DEVEL(LOG_LEVEL_TRACE, "Fatal : Illegal crypt_level"); break ; } if (self->decrypt_rc4_info != NULL) { - g_writeln("xrdp_sec_init_rdp_security: decrypt_rc4_info already created !!!"); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_init_rdp_security: decrypt_rc4_info already created !!!"); } else { @@ -2232,7 +2252,7 @@ if (self->encrypt_rc4_info != NULL) { - g_writeln("xrdp_sec_init_rdp_security: encrypt_rc4_info already created !!!"); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_init_rdp_security: encrypt_rc4_info already created !!!"); } else { @@ -2254,13 +2274,13 @@ char *value = NULL; char key_file[256]; - DEBUG((" in xrdp_sec_incoming:")); + LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_incoming:"); iso = self->mcs_layer->iso_layer; /* negotiate security layer */ if (xrdp_iso_incoming(iso) != 0) { - DEBUG(("xrdp_sec_incoming: xrdp_iso_incoming failed")); + LOG(LOG_LEVEL_ERROR, "xrdp_sec_incoming: xrdp_iso_incoming failed"); return 1; } @@ -2268,15 +2288,15 @@ if (iso->selectedProtocol > PROTOCOL_RDP) { /* init tls security */ - DEBUG((" in xrdp_sec_incoming: init tls security")); + LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_incoming: init tls security"); if (trans_set_tls_mode(self->mcs_layer->iso_layer->trans, - self->rdp_layer->client_info.key_file, - self->rdp_layer->client_info.certificate, - self->rdp_layer->client_info.ssl_protocols, - self->rdp_layer->client_info.tls_ciphers) != 0) + self->rdp_layer->client_info.key_file, + self->rdp_layer->client_info.certificate, + self->rdp_layer->client_info.ssl_protocols, + self->rdp_layer->client_info.tls_ciphers) != 0) { - g_writeln("xrdp_sec_incoming: trans_set_tls_mode failed"); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_incoming: trans_set_tls_mode failed"); return 1; } @@ -2288,10 +2308,10 @@ else { /* init rdp security */ - DEBUG((" in xrdp_sec_incoming: init rdp security")); + LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_incoming: init rdp security"); if (xrdp_sec_init_rdp_security(self) != 0) { - DEBUG(("xrdp_sec_incoming: xrdp_sec_init_rdp_security failed")); + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_incoming: xrdp_sec_init_rdp_security failed"); return 1; } if (self->crypt_method != CRYPT_METHOD_NONE) @@ -2307,8 +2327,8 @@ if (file_by_name_read_section(key_file, "keys", items, values) != 0) { /* this is a show stopper */ - log_message(LOG_LEVEL_ALWAYS, "XRDP cannot read file: %s " - "(check permissions)", key_file); + LOG(LOG_LEVEL_ALWAYS, "XRDP cannot read file: %s " + "(check permissions)", key_file); list_delete(items); list_delete(values); return 1; @@ -2326,7 +2346,7 @@ else if (g_strcasecmp(item, "pub_mod") == 0) { self->rsa_key_bytes = (g_strlen(value) + 1) / 5; - g_writeln("pub_mod bytes %d", self->rsa_key_bytes); + LOG_DEVEL(LOG_LEVEL_TRACE, "pub_mod bytes %d", self->rsa_key_bytes); hex_str_to_bin(value, self->pub_mod, self->rsa_key_bytes); } else if (g_strcasecmp(item, "pub_sig") == 0) @@ -2336,17 +2356,17 @@ else if (g_strcasecmp(item, "pri_exp") == 0) { self->rsa_key_bytes = (g_strlen(value) + 1) / 5; - g_writeln("pri_exp %d", self->rsa_key_bytes); + LOG_DEVEL(LOG_LEVEL_TRACE, "pri_exp %d", self->rsa_key_bytes); hex_str_to_bin(value, self->pri_exp, self->rsa_key_bytes); } } if (self->rsa_key_bytes <= 64) { - g_writeln("warning, RSA key len 512 " + LOG_DEVEL(LOG_LEVEL_TRACE, "warning, RSA key len 512 " "bits or less, consider creating a 2048 bit key"); - log_message(LOG_LEVEL_WARNING, "warning, RSA key len 512 " - "bits or less, consider creating a 2048 bit key"); + LOG(LOG_LEVEL_WARNING, "warning, RSA key len 512 " + "bits or less, consider creating a 2048 bit key"); } list_delete(items); @@ -2360,21 +2380,17 @@ return 1; } -#ifdef XRDP_DEBUG - g_writeln("client mcs data received"); - g_hexdump(self->client_mcs_data.data, - (int)(self->client_mcs_data.end - self->client_mcs_data.data)); - g_writeln("server mcs data sent"); - g_hexdump(self->server_mcs_data.data, - (int)(self->server_mcs_data.end - self->server_mcs_data.data)); -#endif - DEBUG((" out xrdp_sec_incoming")); + LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "client mcs data received", self->client_mcs_data.data, + (int)(self->client_mcs_data.end - self->client_mcs_data.data)); + LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "server mcs data sent", self->server_mcs_data.data, + (int)(self->server_mcs_data.end - self->server_mcs_data.data)); + LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_incoming"); if (xrdp_sec_in_mcs_data(self) != 0) { return 1; } - LLOGLN(10, ("xrdp_sec_incoming: out")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_incoming: out"); return 0; } @@ -2384,8 +2400,8 @@ { int rv; - DEBUG((" in xrdp_sec_disconnect")); + LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_disconnect"); rv = xrdp_mcs_disconnect(self->mcs_layer); - DEBUG((" out xrdp_sec_disconnect")); + LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_disconnect"); return rv; } diff -Nru xrdp-0.9.12/libxrdp/xrdp_surface.c xrdp-0.9.15/libxrdp/xrdp_surface.c --- xrdp-0.9.12/libxrdp/xrdp_surface.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/libxrdp/xrdp_surface.c 2020-12-28 14:03:43.000000000 +0000 @@ -111,7 +111,7 @@ } else { - g_writeln("bpp = %d is not supported\n", bpp); + LOG(LOG_LEVEL_ERROR, "bpp = %d is not supported\n", bpp); return 1; } diff -Nru xrdp-0.9.12/Makefile.in xrdp-0.9.15/Makefile.in --- xrdp-0.9.12/Makefile.in 2019-12-28 12:36:37.000000000 +0000 +++ xrdp-0.9.15/Makefile.in 2020-12-28 14:06:38.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -145,8 +145,8 @@ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir distdir-am dist dist-all distcheck -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ - $(LISP)config_ac-h.in +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ + config_ac-h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. @@ -210,6 +210,8 @@ DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip +# Exists only to be overridden by the user if desired. +AM_DISTCHECK_DVI_TARGET = dvi distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' @@ -660,6 +662,10 @@ tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) +dist-zstd: distdir + tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst + $(am__post_remove_distdir) + dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @@ -702,6 +708,8 @@ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ + *.tar.zst*) \ + zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) @@ -717,7 +725,7 @@ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ @@ -879,18 +887,18 @@ am--refresh check check-am clean clean-cscope clean-generic \ clean-libtool cscope cscopelist-am ctags ctags-am dist \ dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ - dist-xz dist-zip distcheck distclean distclean-generic \ - distclean-hdr distclean-libtool distclean-local distclean-tags \ - distcleancheck distdir distuninstallcheck dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs installdirs-am maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am + dist-xz dist-zip dist-zstd distcheck distclean \ + distclean-generic distclean-hdr distclean-libtool \ + distclean-local distclean-tags distcleancheck distdir \ + distuninstallcheck dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am .PRECIOUS: Makefile diff -Nru xrdp-0.9.12/mc/Makefile.in xrdp-0.9.15/mc/Makefile.in --- xrdp-0.9.12/mc/Makefile.in 2019-12-28 12:36:38.000000000 +0000 +++ xrdp-0.9.15/mc/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/mc/mc.h xrdp-0.9.15/mc/mc.h --- xrdp-0.9.12/mc/mc.h 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/mc/mc.h 2020-12-28 14:03:43.000000000 +0000 @@ -26,6 +26,8 @@ #define CURRENT_MOD_VER 3 +struct source_info; + struct mod { int size; /* size of this struct */ @@ -54,7 +56,7 @@ 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); @@ -91,7 +93,7 @@ tintptr handle; /* pointer to self as long */ tintptr wm; tintptr painter; - tintptr si; + struct source_info *si; /* mod data */ int sck; int width; diff -Nru xrdp-0.9.12/missing xrdp-0.9.15/missing --- xrdp-0.9.12/missing 2019-12-28 12:36:37.000000000 +0000 +++ xrdp-0.9.15/missing 2020-12-28 14:06:38.000000000 +0000 @@ -3,7 +3,7 @@ scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify diff -Nru xrdp-0.9.12/neutrinordp/Makefile.in xrdp-0.9.15/neutrinordp/Makefile.in --- xrdp-0.9.12/neutrinordp/Makefile.in 2019-12-28 12:36:38.000000000 +0000 +++ xrdp-0.9.15/neutrinordp/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/neutrinordp/xrdp-neutrinordp.c xrdp-0.9.15/neutrinordp/xrdp-neutrinordp.c --- xrdp-0.9.12/neutrinordp/xrdp-neutrinordp.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/neutrinordp/xrdp-neutrinordp.c 2020-12-28 14:03:43.000000000 +0000 @@ -24,7 +24,9 @@ #include "xrdp-neutrinordp.h" #include "xrdp-color.h" #include "xrdp_rail.h" +#include "trans.h" #include "log.h" +#include "string_calls.h" #include #if defined(VERSION_STRUCT_RDP_FREERDP) @@ -39,6 +41,9 @@ #define LOG_LEVEL 1 #endif +/* Max amount of buffered output data before we stop generating more */ +#define MAX_QUEUED_MODULE_OUTPUT_DATA 50000 + #define LLOG(_level, _args) \ do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0) #define LLOGLN(_level, _args) \ @@ -69,6 +74,13 @@ } /*****************************************************************************/ +static int +get_queued_module_output_data(struct mod *mod) +{ + return (mod->si != NULL) ? mod->si->source[XRDP_SOURCE_MOD] : 0; +} + +/*****************************************************************************/ /* return error */ static int lxrdp_start(struct mod *mod, int w, int h, int bpp) @@ -516,14 +528,26 @@ boolean ok; LLOGLN(12, ("lxrdp_get_wait_objs:")); - rfds = (void **)read_objs; - wfds = (void **)write_objs; - ok = freerdp_get_fds(mod->inst, rfds, rcount, wfds, wcount); - - if (!ok) + /* + * Don't check this module for activity if our queued output data + * has already reached the limit + */ + if (get_queued_module_output_data(mod) > MAX_QUEUED_MODULE_OUTPUT_DATA) { - LLOGLN(0, ("lxrdp_get_wait_objs: freerdp_get_fds failed")); - return 1; + *rcount = 0; + *wcount = 0; + } + else + { + rfds = (void **)read_objs; + wfds = (void **)write_objs; + ok = freerdp_get_fds(mod->inst, rfds, rcount, wfds, wcount); + + if (!ok) + { + LLOGLN(0, ("lxrdp_get_wait_objs: freerdp_get_fds failed")); + return 1; + } } return 0; @@ -536,12 +560,32 @@ boolean ok; LLOGLN(12, ("lxrdp_check_wait_objs:")); - ok = freerdp_check_fds(mod->inst); + /* + * Only process the freerdp file descriptors if our queued output data + * has not reached the limit + */ + if (get_queued_module_output_data(mod) <= MAX_QUEUED_MODULE_OUTPUT_DATA) + { + /* + * Before checking the file descriptors, set the source info + * current source, so any data queued on output trans objects + * gets attributed to this module + */ + if (mod->si) + { + mod->si->cur_source = XRDP_SOURCE_MOD; + } + ok = freerdp_check_fds(mod->inst); + if (mod->si) + { + mod->si->cur_source = XRDP_SOURCE_NONE; + } - if (!ok) - { - LLOGLN(0, ("lxrdp_check_wait_objs: freerdp_check_fds failed")); - return 1; + if (!ok) + { + LLOGLN(0, ("lxrdp_check_wait_objs: freerdp_check_fds failed")); + return 1; + } } return 0; @@ -1394,7 +1438,7 @@ lfreerdp_polygon_sc(rdpContext *context, POLYGON_SC_ORDER *polygon_sc) { struct mod *mod; - int i, npoints; + int i; struct { short x, y; } points[4]; @@ -1448,8 +1492,11 @@ static void lfreerdp_synchronize(rdpContext *context) { + /* Uncomment these two lines when needed */ +#if 0 struct mod *mod; mod = ((struct mod_context *)context)->modi; +#endif LLOGLN(12, ("lfreerdp_synchronize received - not handled")); } diff -Nru xrdp-0.9.12/neutrinordp/xrdp-neutrinordp.h xrdp-0.9.15/neutrinordp/xrdp-neutrinordp.h --- xrdp-0.9.12/neutrinordp/xrdp-neutrinordp.h 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/neutrinordp/xrdp-neutrinordp.h 2020-12-28 14:03:43.000000000 +0000 @@ -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 @@ -60,6 +61,8 @@ #define CURRENT_MOD_VER 4 +struct source_info; + struct mod { int size; /* size of this struct */ @@ -182,7 +185,7 @@ tintptr handle; /* pointer to self as long */ tintptr wm; tintptr painter; - tintptr si; + struct source_info *si; /* mod data */ int sck; @@ -196,9 +199,9 @@ 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 */ diff -Nru xrdp-0.9.12/NEWS.md xrdp-0.9.15/NEWS.md --- xrdp-0.9.12/NEWS.md 2019-12-28 12:30:26.000000000 +0000 +++ xrdp-0.9.15/NEWS.md 2020-12-28 14:03:43.000000000 +0000 @@ -1,3 +1,110 @@ +# Release notes for xrdp v0.9.15 (2020/12/28) + +## New features +* Allow token sign in without autologon for SSO (#1667 #1668) +* Norwegian keyboard support (#1675) +* Improved config support for chansrv (#1635) +* Unified chansrv, sesman and libxrdp logging (#1633 #1708 #1738) - thanks to @aquesnel +* Support SUSE move to /usr/etc (#1702) +* Parameters may now be specified for user-specified shell (#1270 #1695) +* xrdp executables now allow alternative config files to be specified with -c (#1588 #1650 #1651) +* sesrun improvements (#1741) +* Drive redirection location can now be specified (#1048) +* Now compiles on RISC-V (#1761) + +## Bug fixes +* Additional buffer overflow checks (#1662) +* FUSE support now builds on 32-bit platforms (#1682) +* genkeymap array size conflict fixed (#1691) +* Buffering issue with neutrinordp over a slow link fixed (#1608 1634) +* Various documentation fixes (#1704 #1741 #1755 #1759) +* Prevent PAM info message from causing authentication failure (#1727) +* Cosmetic fixes for minor issues (#1751 #1755 #1749) +* Try harder to clean up socket files on session exit (#1740 #1756) +* xrdp-chansrv become defunct in docker while file copy (#1658) + +## Internal changes +* Compilation warnings with newer compilers (#1659 #1680) +* Continuation Integration checks on 32-bit platforms now include FUSE support (#1682) +* Continuation Integration builds now default to the Ubuntu Focal platform (#1666) +* FUSE type tidy-ups (#1686) +* Switch from Travis CI to GitHub Actions (#1728 #1732) +* Easier to set up console logging for utilities (#1711) + +----------------------- + +# 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. + +* [CVE-2022-4044: Local users can perform a buffer overflow attack against the xrdp-sesman service and then impersonate it](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-4044) + +This update is recommended for all xrdp users. + +## Special thanks + +Thanks to [Ashley Newson](https://github.com/ashleynewson) reporting the vulnerability and reviewing fix. + +----------------------- + +# Release notes for xrdp v0.9.13 (2020/03/11) + +This release is an intermediate bugfix release. The previous version v0.9.12 has some regressions on drive redirection. + +## Bug fixes (drive redirection related) +* Fix chansrv crashes with segmentation fault (regression in #1449) #1487 +* Drive redirection now supports Guacamole client #1505 #1507 +* Prevent a coredump in the event of a corrupted file system #1507 +* Resolve double-free in `chansrv_fuse` #1469 + +## Bug fixes (other) +* Fix the issue `xrdp --version | less` will show empty output #1471 #1472 +* Fix some warnings found by cppcheck #1479 #1481 #1484 #1485 + +## Other changes +* Add FreeBSD CI test #1466 +* Move Microsoft-defined constants into separate includes #1470 +* Perform cppcheck during CI test #1493 +* Support mousex button 8/9 #1478 + +## 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.12 (2019/12/28) ## Bug fixes @@ -84,7 +191,7 @@ ----------------------- -## Release notes for xrdp v0.9.9 (2018/12/25) +# Release notes for xrdp v0.9.9 (2018/12/25) ## Release cycle From the next release, release cycle will be changed from quarterly to every diff -Nru xrdp-0.9.12/pkgconfig/Makefile.in xrdp-0.9.15/pkgconfig/Makefile.in --- xrdp-0.9.12/pkgconfig/Makefile.in 2019-12-28 12:36:38.000000000 +0000 +++ xrdp-0.9.15/pkgconfig/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/README.md xrdp-0.9.15/README.md --- xrdp-0.9.12/README.md 2019-12-28 12:30:26.000000000 +0000 +++ xrdp-0.9.15/README.md 2020-12-28 14:03:43.000000000 +0000 @@ -1,8 +1,8 @@ [![Build Status](https://travis-ci.org/neutrinolabs/xrdp.svg?branch=devel)](https://travis-ci.org/neutrinolabs/xrdp) -[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/neutrinolabs/xrdp) +[![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.12 +*Current Version:* 0.9.15 # xrdp - an open source RDP server diff -Nru xrdp-0.9.12/sesman/access.c xrdp-0.9.15/sesman/access.c --- xrdp-0.9.12/sesman/access.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/access.c 2020-12-28 14:03:43.000000000 +0000 @@ -29,6 +29,7 @@ #endif #include "sesman.h" +#include "string_calls.h" extern struct config_sesman *g_cfg; /* in sesman.c */ @@ -41,33 +42,32 @@ if ((0 == g_strncmp(user, "root", 5)) && (0 == g_cfg->sec.allow_root)) { - log_message(LOG_LEVEL_WARNING, - "ROOT login attempted, but root login is disabled"); + LOG(LOG_LEVEL_WARNING, + "ROOT login attempted, but root login is disabled"); return 0; } - if ((0 == g_cfg->sec.ts_users_enable) && (0==g_cfg->sec.ts_always_group_check)) + 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(LOG_LEVEL_INFO, "Terminal Server Users group is disabled, allowing authentication"); return 1; } if (0 != g_getuser_info(user, &gid, 0, 0, 0, 0)) { - log_message(LOG_LEVEL_ERROR, "Cannot read user info! - login denied"); + LOG(LOG_LEVEL_ERROR, "Cannot read user info! - login denied"); return 0; } if (g_cfg->sec.ts_users == gid) { - log_message(LOG_LEVEL_DEBUG,"ts_users is user's primary group"); + LOG(LOG_LEVEL_DEBUG, "ts_users is user's primary group"); return 1; } if (0 != g_check_user_in_group(user, g_cfg->sec.ts_users, &ok)) { - log_message(LOG_LEVEL_ERROR, "Cannot read group info! - login denied"); + LOG(LOG_LEVEL_ERROR, "Cannot read group info! - login denied"); return 0; } @@ -76,7 +76,7 @@ return 1; } - log_message(LOG_LEVEL_INFO, "login denied for user %s", user); + LOG(LOG_LEVEL_INFO, "login denied for user %s", user); return 0; } @@ -90,33 +90,33 @@ if ((0 == g_strncmp(user, "root", 5)) && (0 == g_cfg->sec.allow_root)) { - log_message(LOG_LEVEL_WARNING, - "[MNG] ROOT login attempted, but root login is disabled"); + LOG(LOG_LEVEL_WARNING, + "[MNG] ROOT login attempted, but root login is disabled"); return 0; } if (0 == g_cfg->sec.ts_admins_enable) { - LOG_DBG("[MNG] Terminal Server Admin group is disabled, " - "allowing authentication", 1); + LOG(LOG_LEVEL_INFO, "[MNG] Terminal Server Admin group is disabled, " + "allowing authentication"); return 1; } if (0 != g_getuser_info(user, &gid, 0, 0, 0, 0)) { - log_message(LOG_LEVEL_ERROR, "[MNG] Cannot read user info! - login denied"); + LOG(LOG_LEVEL_ERROR, "[MNG] Cannot read user info! - login denied"); return 0; } if (g_cfg->sec.ts_admins == gid) { - LOG_DBG("[MNG] ts_users is user's primary group"); + LOG(LOG_LEVEL_INFO, "[MNG] ts_users is user's primary group"); return 1; } if (0 != g_check_user_in_group(user, g_cfg->sec.ts_admins, &ok)) { - log_message(LOG_LEVEL_ERROR, "[MNG] Cannot read group info! - login denied"); + LOG(LOG_LEVEL_ERROR, "[MNG] Cannot read group info! - login denied"); return 0; } @@ -125,7 +125,7 @@ return 1; } - log_message(LOG_LEVEL_INFO, "[MNG] login denied for user %s", user); + LOG(LOG_LEVEL_INFO, "[MNG] login denied for user %s", user); return 0; } diff -Nru xrdp-0.9.12/sesman/chansrv/audin.c xrdp-0.9.15/sesman/chansrv/audin.c --- xrdp-0.9.12/sesman/chansrv/audin.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/audin.c 2020-12-28 14:03:43.000000000 +0000 @@ -118,7 +118,7 @@ int bytes; struct stream *s; - LOG(0, ("audin_send_version:")); + LOG_DEVEL(LOG_LEVEL_INFO, "audin_send_version:"); make_stream(s); init_stream(s, 32); out_uint8(s, MSG_SNDIN_VERSION); @@ -141,7 +141,7 @@ struct stream *s; struct xr_wave_format_ex *wf; - LOG(0, ("audin_send_formats:")); + LOG_DEVEL(LOG_LEVEL_INFO, "audin_send_formats:"); num_formats = sizeof(g_server_formats) / sizeof(g_server_formats[0]) - 1; make_stream(s); @@ -152,9 +152,9 @@ for (index = 0; index < num_formats; index++) { wf = g_server_formats[index]; - LOG(0, ("audin_send_formats: sending format wFormatTag 0x%4.4x " - "nChannels %d nSamplesPerSec %d", - wf->wFormatTag, wf->nChannels, wf->nSamplesPerSec)); + LOG_DEVEL(LOG_LEVEL_INFO, "audin_send_formats: sending format wFormatTag 0x%4.4x " + "nChannels %d nSamplesPerSec %d", + wf->wFormatTag, wf->nChannels, wf->nSamplesPerSec); out_uint16_le(s, wf->wFormatTag); out_uint16_le(s, wf->nChannels); out_uint32_le(s, wf->nSamplesPerSec); @@ -183,7 +183,7 @@ struct stream *s; struct xr_wave_format_ex *wf; - LOG(0, ("audin_send_open:")); + LOG_DEVEL(LOG_LEVEL_INFO, "audin_send_open:"); make_stream(s); init_stream(s, 8192); out_uint8(s, MSG_SNDIN_OPEN); @@ -215,14 +215,14 @@ { int version; - LOG(0, ("audin_process_version:")); + LOG_DEVEL(LOG_LEVEL_INFO, "audin_process_version:"); if (!s_check_rem(s, 4)) { - LOG(0, ("audin_process_version: parse error")); + LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_version: parse error"); return 1; } in_uint32_le(s, version); - LOG(0, ("audin_process_version: version %d", version)); + LOG(LOG_LEVEL_INFO, "audin_process_version: version %d", version); return audin_send_formats(chan_id); } @@ -234,11 +234,11 @@ int num_formats; struct xr_wave_format_ex *wf; - LOG(0, ("audin_process_formats:")); + LOG_DEVEL(LOG_LEVEL_INFO, "audin_process_formats:"); cleanup_client_formats(); if (!s_check_rem(s, 8)) { - LOG(0, ("audin_process_formats: parse error")); + LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_formats: parse error"); return 1; } in_uint32_le(s, num_formats); @@ -248,7 +248,7 @@ { if (!s_check_rem(s, 18)) { - LOG(0, ("audin_process_formats: parse error")); + LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_formats: parse error"); return 1; } wf = g_new0(struct xr_wave_format_ex, 1); @@ -260,14 +260,14 @@ in_uint16_le(s, wf->nBlockAlign); in_uint16_le(s, wf->wBitsPerSample); in_uint16_le(s, wf->cbSize); - LOG(0, ("audin_process_formats: recved format wFormatTag 0x%4.4x " - "nChannels %d nSamplesPerSec %d", - wf->wFormatTag, wf->nChannels, wf->nSamplesPerSec)); + LOG_DEVEL(LOG_LEVEL_INFO, "audin_process_formats: recved format wFormatTag 0x%4.4x " + "nChannels %d nSamplesPerSec %d", + wf->wFormatTag, wf->nChannels, wf->nSamplesPerSec); if (wf->cbSize > 0) { if (!s_check_rem(s, wf->cbSize)) { - LOG(0, ("audin_process_formats: parse error")); + LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_formats: parse error"); return 1; } wf->data = g_new0(uint8_t, wf->cbSize); @@ -286,11 +286,11 @@ if (!s_check_rem(s, 4)) { - LOG(0, ("audin_process_open_reply: parse error")); + LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_open_reply: parse error"); return 1; } in_uint32_le(s, result); - LOG(0, ("audin_process_open_reply: result 0x%8.8x", result)); + LOG(LOG_LEVEL_INFO, "audin_process_open_reply: result 0x%8.8x", result); return 0; } @@ -298,7 +298,7 @@ static int audin_process_incoming_data(int chan_id, struct stream *s) { - LOG(10, ("audin_process_incoming_data:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "audin_process_incoming_data:"); return 0; } @@ -310,7 +310,7 @@ struct stream *ls; data_bytes = (int) (s->end - s->p); - LOG(10, ("audin_process_data: data_bytes %d", data_bytes)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "audin_process_data: data_bytes %d", data_bytes); xstream_new(ls, data_bytes); g_memcpy(ls->data, s->p, data_bytes); @@ -326,15 +326,15 @@ static int audin_process_format_change(int chan_id, struct stream *s) { - LOG(0, ("audin_process_format_change:")); + LOG_DEVEL(LOG_LEVEL_INFO, "audin_process_format_change:"); if (!s_check_rem(s, 4)) { - LOG(0, ("audin_process_format_change: parse error")); + LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_format_change: parse error"); return 1; } in_uint32_le(s, g_current_format); - LOG(0, ("audin_process_format_change: g_current_format %d", - g_current_format)); + LOG_DEVEL(LOG_LEVEL_INFO, "audin_process_format_change: g_current_format %d", + g_current_format); return 0; } @@ -344,14 +344,14 @@ { int code; - LOG(10, ("audin_process_msg:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "audin_process_msg:"); if (!s_check_rem(s, 1)) { - LOG(0, ("audin_process_msg: parse error")); + LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_msg: parse error"); return 1; } in_uint8(s, code); - LOG(10, ("audin_process_msg: code %d", code)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "audin_process_msg: code %d", code); switch (code) { case MSG_SNDIN_VERSION: @@ -367,7 +367,7 @@ case MSG_SNDIN_FORMATCHANGE: return audin_process_format_change(chan_id, s); default: - LOG(0, ("audin_process_msg: unprocessed code %d", code)); + LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_msg: unprocessed code %d", code); break; } return 0; @@ -377,7 +377,7 @@ static int audin_open_response(int chan_id, int creation_status) { - LOG(0, ("audin_open_response: creation_status 0x%8.8x", creation_status)); + LOG_DEVEL(LOG_LEVEL_INFO, "audin_open_response: creation_status 0x%8.8x", creation_status); if (creation_status == 0) { return audin_send_version(chan_id); @@ -389,7 +389,7 @@ static int audin_close_response(int chan_id) { - LOG(0, ("audin_close_response:")); + LOG_DEVEL(LOG_LEVEL_INFO, "audin_close_response:"); g_audin_chanid = 0; cleanup_client_formats(); free_stream(g_in_s); @@ -402,13 +402,12 @@ audin_data_fragment(int chan_id, char *data, int bytes) { int rv; - int left; - LOG(10, ("audin_data_fragment:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "audin_data_fragment:"); if (!s_check_rem(g_in_s, bytes)) { - left = (int) (g_in_s->end - g_in_s->p); - LOG(0, ("audin_data_fragment: error bytes %d left %d", bytes, left)); + LOG_DEVEL(LOG_LEVEL_ERROR, "audin_data_fragment: error bytes %d left %d", + bytes, (int) (g_in_s->end - g_in_s->p)); return 1; } out_uint8a(g_in_s, data, bytes); @@ -427,10 +426,10 @@ static int audin_data_first(int chan_id, char *data, int bytes, int total_bytes) { - LOG(10, ("audin_data_first:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "audin_data_first:"); if (g_in_s != NULL) { - LOG(0, ("audin_data_first: warning g_in_s is not nil")); + LOG_DEVEL(LOG_LEVEL_ERROR, "audin_data_first: warning g_in_s is not nil"); free_stream(g_in_s); } make_stream(g_in_s); @@ -445,8 +444,7 @@ { struct stream ls; - LOG(10, ("audin_data:")); - //g_hexdump(data, bytes); + LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "audin_data:", data, bytes); if (g_in_s == NULL) { g_memset(&ls, 0, sizeof(ls)); @@ -462,7 +460,7 @@ int audin_init(void) { - LOG(0, ("audin_init:")); + LOG_DEVEL(LOG_LEVEL_INFO, "audin_init:"); g_memset(&g_audin_info, 0, sizeof(g_audin_info)); g_audin_info.open_response = audin_open_response; g_audin_info.close_response = audin_close_response; @@ -477,7 +475,7 @@ int audin_deinit(void) { - LOG(0, ("audin_deinit:")); + LOG_DEVEL(LOG_LEVEL_INFO, "audin_deinit:"); return 0; } @@ -486,9 +484,9 @@ audin_start(void) { int error; - struct stream* s; + struct stream *s; - LOG(0, ("audin_start:")); + LOG_DEVEL(LOG_LEVEL_INFO, "audin_start:"); if (g_audin_chanid != 0) { return 1; @@ -504,7 +502,7 @@ error = chansrv_drdynvc_open(AUDIN_NAME, AUDIN_FLAGS, &g_audin_info, /* callback functions */ &g_audin_chanid); /* chansrv chan_id */ - LOG(0, ("audin_start: error %d g_audin_chanid %d", error, g_audin_chanid)); + LOG_DEVEL(LOG_LEVEL_ERROR, "audin_start: error %d g_audin_chanid %d", error, g_audin_chanid); return error; } @@ -512,7 +510,7 @@ int audin_stop(void) { - LOG(0, ("audin_stop:")); + LOG_DEVEL(LOG_LEVEL_INFO, "audin_stop:"); chansrv_drdynvc_close(g_audin_chanid); return 0; } diff -Nru xrdp-0.9.12/sesman/chansrv/chansrv.c xrdp-0.9.15/sesman/chansrv/chansrv.c --- xrdp-0.9.12/sesman/chansrv/chansrv.c 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/chansrv.c 2020-12-28 14:03:43.000000000 +0000 @@ -23,6 +23,7 @@ #include "arch.h" #include "os_calls.h" +#include "string_calls.h" #include "thread_calls.h" #include "trans.h" #include "chansrv.h" @@ -36,9 +37,14 @@ #include "rail.h" #include "xcommon.h" #include "chansrv_fuse.h" +#include "chansrv_config.h" #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; @@ -53,17 +59,16 @@ static tbus g_term_event = 0; static tbus g_thread_done_event = 0; -static int g_use_unix_socket = 0; +struct config_chansrv *g_cfg = NULL; int g_display_num = 0; int g_cliprdr_chan_id = -1; /* cliprdr */ int g_rdpsnd_chan_id = -1; /* rdpsnd */ int g_rdpdr_chan_id = -1; /* rdpdr */ int g_rail_chan_id = -1; /* rail */ -int g_restrict_outbound_clipboard = 0; char *g_exec_name; -tbus g_exec_event; +tbus g_exec_event = 0; tbus g_exec_mutex; tbus g_exec_sem; int g_exec_pid = 0; @@ -118,7 +123,7 @@ struct timeout_obj *tobj; tui32 now; - LOG(10, ("add_timeout:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "add_timeout:"); now = g_time3(); tobj = g_new0(struct timeout_obj, 1); tobj->mstime = now + msoffset; @@ -145,7 +150,7 @@ tui32 now; int ltimeout; - LOG(10, ("get_timeout:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "get_timeout:"); ltimeout = *timeout; if (ltimeout < 1) { @@ -157,7 +162,7 @@ now = g_time3(); while (tobj != 0) { - LOG(10, (" now %u tobj->mstime %u", now, tobj->mstime)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " now %u tobj->mstime %u", now, tobj->mstime); if (now < tobj->mstime) { ltimeout = tobj->mstime - now; @@ -167,7 +172,7 @@ } if (ltimeout > 0) { - LOG(10, (" ltimeout %d", ltimeout)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " ltimeout %d", ltimeout); if (*timeout < 1) { *timeout = ltimeout; @@ -193,7 +198,7 @@ int count; tui32 now; - LOG(10, ("check_timeout:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "check_timeout:"); count = 0; tobj = g_timeout_head; if (tobj != 0) @@ -233,7 +238,7 @@ } } } - LOG(10, (" count %d", count)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " count %d", count); return 0; } @@ -259,8 +264,8 @@ struct stream *s; if ((chan_id < 0) || (chan_id > 31) || - (data == NULL) || - (size < 1) || (size > MAX_CHANNEL_BYTES)) + (data == NULL) || + (size < 1) || (size > MAX_CHANNEL_BYTES)) { /* bad param */ return 1; @@ -304,11 +309,11 @@ /*****************************************************************************/ /* returns error */ int -send_rail_drawing_orders(char* data, int size) +send_rail_drawing_orders(char *data, int size) { - LOGM((LOG_LEVEL_DEBUG, "chansrv::send_rail_drawing_orders: size %d", size)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::send_rail_drawing_orders: size %d", size); - struct stream* s; + struct stream *s; int error; s = trans_get_out_s(g_con_trans, 8192); @@ -345,10 +350,10 @@ g_rdpsnd_chan_id = -1; g_rdpdr_chan_id = -1; g_rail_chan_id = -1; - LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "process_message_channel_setup:"); in_uint16_le(s, num_chans); - LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup: num_chans %d", - num_chans)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "process_message_channel_setup: num_chans %d", + num_chans); for (index = 0; index < num_chans; index++) { @@ -357,10 +362,7 @@ in_uint8a(s, ci->name, 8); in_uint16_le(s, ci->id); in_uint16_le(s, ci->flags); - LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup: chan name '%s' " - "id %d flags %8.8x", ci->name, ci->id, ci->flags)); - - g_writeln("process_message_channel_setup: chan name '%s' " + LOG_DEVEL(LOG_LEVEL_DEBUG, "process_message_channel_setup: chan name '%s' " "id %d flags %8.8x", ci->name, ci->id, ci->flags); if (g_strcasecmp(ci->name, "cliprdr") == 0) @@ -386,7 +388,7 @@ } else { - LOG(10, ("other %s", ci->name)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "other %s", ci->name); } g_num_chan_items++; @@ -441,9 +443,8 @@ in_uint16_le(s, chan_flags); in_uint16_le(s, length); in_uint32_le(s, total_length); - LOGM((LOG_LEVEL_DEBUG, "process_message_channel_data: chan_id %d " - "chan_flags %d", chan_id, chan_flags)); - LOG(10, ("process_message_channel_data")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "process_message_channel_data: chan_id %d " + "chan_flags %d", chan_id, chan_flags); rv = 0; if (rv == 0) @@ -496,7 +497,7 @@ } if (found == 0) { - LOG(0, ("process_message_channel_data: not found channel %d", chan_id)); + LOG_DEVEL(LOG_LEVEL_INFO, "process_message_channel_data: not found channel %d", chan_id); } } @@ -514,7 +515,7 @@ int chan_id; int creation_status; - LOG(10, ("process_message_drdynvc_open_response:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "process_message_drdynvc_open_response:"); if (!s_check_rem(s, 8)) { return 1; @@ -528,7 +529,7 @@ drdynvc = g_drdynvcs + chan_id; if (drdynvc->status != CHANSRV_DRDYNVC_STATUS_OPEN_SENT) { - g_writeln("process_message_drdynvc_open_response: status not right"); + LOG_DEVEL(LOG_LEVEL_ERROR, "process_message_drdynvc_open_response: status not right"); return 1; } if (creation_status == 0) @@ -558,7 +559,7 @@ struct chansrv_drdynvc *drdynvc; int chan_id; - LOG(10, ("process_message_drdynvc_close_response:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "process_message_drdynvc_close_response:"); if (!s_check_rem(s, 4)) { return 1; @@ -571,7 +572,7 @@ drdynvc = g_drdynvcs + chan_id; if (drdynvc->status != CHANSRV_DRDYNVC_STATUS_CLOSE_SENT) { - g_writeln("process_message_drdynvc_close_response: status not right"); + LOG_DEVEL(LOG_LEVEL_ERROR, "process_message_drdynvc_close_response: status not right"); return 0; } drdynvc->status = CHANSRV_DRDYNVC_STATUS_CLOSED; @@ -597,7 +598,7 @@ int total_bytes; char *data; - LOG(10, ("process_message_drdynvc_data_first:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "process_message_drdynvc_data_first:"); if (!s_check_rem(s, 12)) { return 1; @@ -636,7 +637,7 @@ int bytes; char *data; - LOG(10, ("process_message_drdynvc_data:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "process_message_drdynvc_data:"); if (!s_check_rem(s, 8)) { return 1; @@ -743,7 +744,7 @@ struct stream *s; int error; - //g_writeln("chansrv_drdynvc_data_first: data_bytes %d total_data_bytes %d", + //LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv_drdynvc_data_first: data_bytes %d total_data_bytes %d", // data_bytes, total_data_bytes); s = trans_get_out_s(g_con_trans, 8192); if (s == NULL) @@ -770,7 +771,7 @@ struct stream *s; int error; - //g_writeln("chansrv_drdynvc_data: data_bytes %d", data_bytes); + // LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv_drdynvc_data: data_bytes %d", data_bytes); s = trans_get_out_s(g_con_trans, 8192); if (s == NULL) { @@ -794,7 +795,7 @@ { int this_send_bytes; - //g_writeln("chansrv_drdynvc_send_data: data_bytes %d", data_bytes); + // LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv_drdynvc_send_data: data_bytes %d", data_bytes); if (data_bytes > 1590) { if (chansrv_drdynvc_data_first(chan_id, data, 1590, data_bytes) != 0) @@ -870,7 +871,7 @@ rv = process_message_drdynvc_data(s); break; default: - LOGM((LOG_LEVEL_ERROR, "process_message: unknown msg %d", id)); + LOG_DEVEL(LOG_LEVEL_ERROR, "process_message: unknown msg %d", id); break; } @@ -905,7 +906,7 @@ return 1; } - LOGM((LOG_LEVEL_DEBUG, "my_trans_data_in:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "my_trans_data_in:"); s = trans_get_in_s(trans); in_uint8s(s, 4); /* id */ in_uint32_le(s, size); @@ -1042,11 +1043,15 @@ 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); + //LOG_DEVEL(LOG_LEVEL_DEBUG, "my_api_trans_data_in: extra_flags %d", trans->extra_flags); rv = 0; ad = (struct xrdp_api_data *) (trans->callback_data); s = trans_get_in_s(trans); @@ -1054,7 +1059,7 @@ { in_uint32_le(s, bytes); in_uint32_le(s, ver); - //g_writeln("my_api_trans_data_in: bytes %d ver %d", bytes, ver); + //LOG_DEVEL(LOG_LEVEL_DEBUG, "my_api_trans_data_in: bytes %d ver %d", bytes, ver); if (ver != 0) { return 1; @@ -1066,15 +1071,16 @@ { 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) + //LOG_DEVEL(LOG_LEVEL_DEBUG, "my_api_trans_data_in: channel_name_bytes %d", channel_name_bytes); + 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); + //LOG_DEVEL(LOG_LEVEL_DEBUG, "my_api_trans_data_in: chan_name %s chan_flags 0x%8.8x", chan_name, ad->chan_flags); if (ad->chan_flags == 0) { /* SVC */ @@ -1128,11 +1134,10 @@ procs.data = my_api_data; rv = chansrv_drdynvc_open(chan_name, ad->chan_flags, &procs, &(ad->chan_id)); - //g_writeln("my_api_trans_data_in: chansrv_drdynvc_open rv %d " + //LOG_DEVEL(LOG_LEVEL_DEBUG, "my_api_trans_data_in: chansrv_drdynvc_open rv %d " // "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; @@ -1142,7 +1147,7 @@ bytes = g_sck_recv(trans->sck, s->data, s->size, 0); if (bytes < 1) { - //g_writeln("my_api_trans_data_in: disconnect"); + //LOG_DEVEL(LOG_LEVEL_DEBUG, "my_api_trans_data_in: disconnect"); return 1; } if (ad->chan_flags == 0) @@ -1153,7 +1158,7 @@ else { /* DVS */ - //g_writeln("my_api_trans_data_in: s->size %d bytes %d", s->size, bytes); + //LOG_DEVEL(LOG_LEVEL_DEBUG, "my_api_trans_data_in: s->size %d bytes %d", s->size, bytes); rv = chansrv_drdynvc_send_data(ad->chan_id, s->data, bytes); } init_stream(s, 0); @@ -1185,7 +1190,7 @@ return 1; } - LOGM((LOG_LEVEL_DEBUG, "my_trans_conn_in:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "my_trans_conn_in:"); g_con_trans = new_trans; g_con_trans->trans_data_in = my_trans_data_in; g_con_trans->header_size = 8; @@ -1204,10 +1209,10 @@ { struct xrdp_api_data *ad; - //g_writeln("my_api_trans_conn_in:"); + //LOG_DEVEL(LOG_LEVEL_DEBUG, "my_api_trans_conn_in:"); if ((trans == NULL) || (trans != g_api_lis_trans) || (new_trans == NULL)) { - g_writeln("my_api_trans_conn_in: error"); + LOG_DEVEL(LOG_LEVEL_ERROR, "my_api_trans_conn_in: error"); return 1; } new_trans->trans_data_in = my_api_trans_data_in; @@ -1216,7 +1221,7 @@ ad = g_new0(struct xrdp_api_data, 1); if (ad == NULL) { - g_writeln("my_api_trans_conn_in: error"); + LOG_DEVEL(LOG_LEVEL_ERROR, "my_api_trans_conn_in: error"); return 1; } new_trans->callback_data = ad; @@ -1236,7 +1241,7 @@ trans_delete(g_lis_trans); } - if (g_use_unix_socket) + if (g_cfg->use_unix_socket) { g_lis_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192); g_lis_trans->is_term = g_is_term; @@ -1254,8 +1259,8 @@ if (error != 0) { - LOGM((LOG_LEVEL_ERROR, "setup_listen: trans_listen failed for port %s", - port)); + LOG_DEVEL(LOG_LEVEL_ERROR, "setup_listen: trans_listen failed for port %s", + port); return 1; } @@ -1277,8 +1282,8 @@ if (error != 0) { - LOGM((LOG_LEVEL_ERROR, "setup_api_listen: trans_listen failed for port %s", - port)); + LOG_DEVEL(LOG_LEVEL_ERROR, "setup_api_listen: trans_listen failed for port %s", + port); return 1; } @@ -1295,11 +1300,11 @@ struct trans *ltran; for (api_con_index = g_api_con_trans_list->count - 1; - api_con_index >= 0; - api_con_index--) + api_con_index >= 0; + api_con_index--) { ltran = (struct trans *) - list_get_item(g_api_con_trans_list, api_con_index); + list_get_item(g_api_con_trans_list, api_con_index); if (ltran != NULL) { trans_get_wait_objs_rw(ltran, robjs, rcount, wobjs, wcount, @@ -1319,11 +1324,11 @@ struct xrdp_api_data *ad; for (api_con_index = g_api_con_trans_list->count - 1; - api_con_index >= 0; - api_con_index--) + api_con_index >= 0; + api_con_index--) { ltran = (struct trans *) - list_get_item(g_api_con_trans_list, api_con_index); + list_get_item(g_api_con_trans_list, api_con_index); if (ltran != NULL) { if (trans_check_wait_objs(ltran) != 0) @@ -1336,8 +1341,8 @@ chansrv_drdynvc_close(ad->chan_id); } for (drdynvc_index = 0; - drdynvc_index < (int) ARRAYSIZE(g_drdynvcs); - drdynvc_index++) + drdynvc_index < (int) ARRAYSIZE(g_drdynvcs); + drdynvc_index++) { if (g_drdynvcs[drdynvc_index].xrdp_api_trans == ltran) { @@ -1360,11 +1365,11 @@ struct trans *ltran; for (api_con_index = g_api_con_trans_list->count - 1; - api_con_index >= 0; - api_con_index--) + api_con_index >= 0; + api_con_index--) { ltran = (struct trans *) - list_get_item(g_api_con_trans_list, api_con_index); + list_get_item(g_api_con_trans_list, api_con_index); if (ltran != NULL) { list_remove_item(g_api_con_trans_list, api_con_index); @@ -1387,7 +1392,7 @@ int error; THREAD_RV rv; - LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread start")); + LOG_DEVEL(LOG_LEVEL_INFO, "channel_thread_loop: thread start"); rv = 0; g_api_con_trans_list = list_create(); setup_api_listen(); @@ -1409,7 +1414,7 @@ check_timeout(); if (g_is_wait_obj_set(g_term_event)) { - LOGM((LOG_LEVEL_INFO, "channel_thread_loop: g_term_event set")); + LOG_DEVEL(LOG_LEVEL_INFO, "channel_thread_loop: g_term_event set"); clipboard_deinit(); sound_deinit(); devredir_deinit(); @@ -1421,8 +1426,8 @@ { if (trans_check_wait_objs(g_lis_trans) != 0) { - LOGM((LOG_LEVEL_INFO, "channel_thread_loop: " - "trans_check_wait_objs error")); + LOG_DEVEL(LOG_LEVEL_INFO, "channel_thread_loop: " + "trans_check_wait_objs error"); } } @@ -1430,8 +1435,8 @@ { if (trans_check_wait_objs(g_con_trans) != 0) { - LOGM((LOG_LEVEL_INFO, "channel_thread_loop: " - "trans_check_wait_objs error resetting")); + LOG_DEVEL(LOG_LEVEL_INFO, "channel_thread_loop: " + "trans_check_wait_objs error resetting"); clipboard_deinit(); sound_deinit(); devredir_deinit(); @@ -1453,7 +1458,7 @@ { if (trans_check_wait_objs(g_api_lis_trans) != 0) { - LOG(0, ("channel_thread_loop: trans_check_wait_objs failed")); + LOG_DEVEL(LOG_LEVEL_ERROR, "channel_thread_loop: trans_check_wait_objs failed"); } } /* check the wait_objs in g_api_con_trans_list */ @@ -1493,7 +1498,7 @@ g_api_lis_trans = 0; api_con_trans_list_remove_all(); list_delete(g_api_con_trans_list); - LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread stop")); + LOG_DEVEL(LOG_LEVEL_INFO, "channel_thread_loop: thread stop"); g_set_wait_obj(g_thread_done_event); return rv; } @@ -1502,7 +1507,7 @@ void term_signal_handler(int sig) { - LOGM((LOG_LEVEL_INFO, "term_signal_handler: got signal %d", sig)); + LOG_DEVEL(LOG_LEVEL_INFO, "term_signal_handler: got signal %d", sig); g_set_wait_obj(g_term_event); } @@ -1510,7 +1515,7 @@ void nil_signal_handler(int sig) { - LOGM((LOG_LEVEL_INFO, "nil_signal_handler: got signal %d", sig)); + LOG_DEVEL(LOG_LEVEL_INFO, "nil_signal_handler: got signal %d", sig); } /*****************************************************************************/ @@ -1519,14 +1524,14 @@ { int pid; - LOG(0, ("child_signal_handler:")); + LOG_DEVEL(LOG_LEVEL_INFO, "child_signal_handler:"); do { pid = g_waitchild(); - LOG(0, ("child_signal_handler: child pid %d", pid)); + LOG_DEVEL(LOG_LEVEL_INFO, "child_signal_handler: child pid %d", pid); if ((pid == g_exec_pid) && (pid > 0)) { - LOG(0, ("child_signal_handler: found pid %d", pid)); + LOG_DEVEL(LOG_LEVEL_INFO, "child_signal_handler: found pid %d", pid); //shutdownx(); } } @@ -1537,7 +1542,7 @@ void segfault_signal_handler(int sig) { - LOG(0, ("segfault_signal_handler: entered.......")); + LOG_DEVEL(LOG_LEVEL_ERROR, "segfault_signal_handler: entered......."); xfuse_deinit(); exit(0); } @@ -1546,7 +1551,7 @@ static void x_server_fatal_handler(void) { - LOGM((LOG_LEVEL_INFO, "xserver_fatal_handler: entered.......")); + LOG_DEVEL(LOG_LEVEL_INFO, "xserver_fatal_handler: entered......."); /* At this point the X server has gone away. Dont make any X calls. */ xfuse_deinit(); exit(0); @@ -1615,52 +1620,23 @@ int main_cleanup(void) { - g_delete_wait_obj(g_term_event); - g_delete_wait_obj(g_thread_done_event); - g_delete_wait_obj(g_exec_event); - tc_mutex_delete(g_exec_mutex); - g_deinit(); /* os_calls */ - return 0; -} - -/*****************************************************************************/ -static int -read_ini(void) -{ - char filename[256]; - struct list *names; - struct list *values; - char *name; - char *value; - int index; - - g_memset(filename, 0, (sizeof(char) * 256)); - names = list_create(); - names->auto_free = 1; - values = list_create(); - values->auto_free = 1; - g_use_unix_socket = 0; - g_snprintf(filename, 255, "%s/sesman.ini", XRDP_CFG_PATH); - - if (file_by_name_read_section(filename, "Globals", names, values) == 0) + if (g_term_event != 0) { - for (index = 0; index < names->count; index++) - { - name = (char *)list_get_item(names, index); - value = (char *)list_get_item(values, index); - - if (g_strcasecmp(name, "ListenAddress") == 0) - { - if (g_strcasecmp(value, "127.0.0.1") == 0) - { - g_use_unix_socket = 1; - } - } - } + g_delete_wait_obj(g_term_event); } - - list_delete(names); - list_delete(values); + if (g_thread_done_event != 0) + { + g_delete_wait_obj(g_thread_done_event); + } + if (g_exec_event != 0) + { + g_delete_wait_obj(g_exec_event); + tc_mutex_delete(g_exec_mutex); + tc_sem_delete(g_exec_sem); + } + log_end(); + config_free(g_cfg); + g_deinit(); /* os_calls */ return 0; } @@ -1668,7 +1644,7 @@ static int get_log_path(char *path, int bytes) { - char* log_path; + char *log_path; int rv; rv = 1; @@ -1717,40 +1693,12 @@ } /*****************************************************************************/ -static enum logLevels -get_log_level(const char* level_str, enum logLevels default_level) -{ - static const char* levels[] = { - "LOG_LEVEL_ALWAYS", - "LOG_LEVEL_ERROR", - "LOG_LEVEL_WARNING", - "LOG_LEVEL_INFO", - "LOG_LEVEL_DEBUG", - "LOG_LEVEL_TRACE" - }; - unsigned int i; - - if (level_str == NULL || level_str[0] == 0) - { - return default_level; - } - for (i = 0; i < ARRAYSIZE(levels); ++i) - { - if (g_strcasecmp(levels[i], level_str) == 0) - { - return (enum logLevels) i; - } - } - return default_level; -} - -/*****************************************************************************/ static int run_exec(void) { int pid; - LOG(10, ("run_exec:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "run_exec:"); pid = g_fork(); if (pid == 0) @@ -1778,60 +1726,59 @@ tbus waiters[4]; int pid = 0; char text[256]; + const char *config_path; char log_path[256]; char *display_text; char log_file[256]; enum logReturns error; - struct log_config logconfig; - enum logLevels log_level; - char *restrict_outbound_clipboard_env; + struct log_config *logconfig; g_init("xrdp-chansrv"); /* os_calls */ + g_memset(g_drdynvcs, 0, sizeof(g_drdynvcs)); log_path[255] = 0; if (get_log_path(log_path, 255) != 0) { g_writeln("error reading CHANSRV_LOG_PATH and HOME environment variable"); - g_deinit(); + main_cleanup(); return 1; } - restrict_outbound_clipboard_env = g_getenv("CHANSRV_RESTRICT_OUTBOUND_CLIPBOARD"); - if (restrict_outbound_clipboard_env != 0) + /* + * The user is unable at present to override the sysadmin-provided + * sesman.ini location */ + config_path = XRDP_CFG_PATH "/sesman.ini"; + if ((g_cfg = config_read(0, config_path)) == NULL) { - if (g_strcmp(restrict_outbound_clipboard_env, "1") == 0) - { - g_restrict_outbound_clipboard = 1; - } + main_cleanup(); + return 1; } + config_dump(g_cfg); - read_ini(); pid = g_getpid(); display_text = g_getenv("DISPLAY"); - - if (display_text) + if (display_text != NULL) + { get_display_num_from_display(display_text); - - log_level = get_log_level(g_getenv("CHANSRV_LOG_LEVEL"), LOG_LEVEL_INFO); + } /* starting logging subsystem */ - g_memset(&logconfig, 0, sizeof(struct log_config)); - logconfig.program_name = "xrdp-chansrv"; g_snprintf(log_file, 255, "%s/xrdp-chansrv.%d.log", log_path, g_display_num); g_writeln("chansrv::main: using log file [%s]", log_file); - if (g_file_exist(log_file)) { g_file_delete(log_file); } - g_memset(g_drdynvcs, 0, sizeof(g_drdynvcs)); - - logconfig.log_file = log_file; - logconfig.fd = -1; - logconfig.log_level = log_level; - logconfig.enable_syslog = 0; - logconfig.syslog_level = LOG_LEVEL_ALWAYS; - error = log_start_from_param(&logconfig); + logconfig = log_config_init_from_config(config_path, "xrdp-chansrv", "Chansrv"); + if (logconfig->log_file != NULL) + { + g_free(logconfig->log_file); + } + logconfig->log_file = log_file; + error = log_start_from_param(logconfig); + logconfig->log_file = NULL; + log_config_free(logconfig); + logconfig = NULL; if (error != LOG_STARTUP_OK) { @@ -1849,11 +1796,11 @@ break; } - g_deinit(); + main_cleanup(); return 1; } - LOGM((LOG_LEVEL_ALWAYS, "main: app started pid %d(0x%8.8x)", pid, pid)); + LOG_DEVEL(LOG_LEVEL_INFO, "main: app started pid %d(0x%8.8x)", pid, pid); /* set up signal handler */ g_signal_terminate(term_signal_handler); /* SIGTERM */ g_signal_user_interrupt(term_signal_handler); /* SIGINT */ @@ -1864,16 +1811,16 @@ /* Cater for the X server exiting unexpectedly */ xcommon_set_x_server_fatal_handler(x_server_fatal_handler); - LOGM((LOG_LEVEL_INFO, "main: DISPLAY env var set to %s", display_text)); + LOG_DEVEL(LOG_LEVEL_INFO, "main: DISPLAY env var set to %s", display_text); if (g_display_num == 0) { - LOGM((LOG_LEVEL_ERROR, "main: error, display is zero")); - g_deinit(); + LOG_DEVEL(LOG_LEVEL_ERROR, "main: error, display is zero"); + main_cleanup(); return 1; } - LOGM((LOG_LEVEL_INFO, "main: using DISPLAY %d", g_display_num)); + LOG_DEVEL(LOG_LEVEL_INFO, "main: using DISPLAY %d", g_display_num); g_snprintf(text, 255, "xrdp_chansrv_%8.8x_main_term", pid); g_term_event = g_create_wait_obj(text); g_snprintf(text, 255, "xrdp_chansrv_%8.8x_thread_done", pid); @@ -1891,7 +1838,7 @@ if (g_obj_wait(waiters, 2, 0, 0, 0) != 0) { - LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed")); + LOG_DEVEL(LOG_LEVEL_ERROR, "main: error, g_obj_wait failed"); break; } @@ -1912,15 +1859,14 @@ /* wait for thread to exit */ if (g_obj_wait(&g_thread_done_event, 1, 0, 0, 0) != 0) { - LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed")); + LOG_DEVEL(LOG_LEVEL_ERROR, "main: error, g_obj_wait failed"); break; } } /* cleanup */ main_cleanup(); - LOGM((LOG_LEVEL_INFO, "main: app exiting pid %d(0x%8.8x)", pid, pid)); - g_deinit(); + LOG_DEVEL(LOG_LEVEL_INFO, "main: app exiting pid %d(0x%8.8x)", pid, pid); return 0; } diff -Nru xrdp-0.9.12/sesman/chansrv/chansrv_config.c xrdp-0.9.15/sesman/chansrv/chansrv_config.c --- xrdp-0.9.12/sesman/chansrv/chansrv_config.c 1970-01-01 00:00:00.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/chansrv_config.c 2020-12-28 14:03:43.000000000 +0000 @@ -0,0 +1,304 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file implements the interface in chansrv_config.h + */ +#if defined(HAVE_CONFIG_H) +#include +#endif + +#include +#include +#include + +#include "arch.h" + +#include "list.h" +#include "log.h" +#include "file.h" +#include "os_calls.h" + +#include "chansrv_config.h" +#include "string_calls.h" + +/* Default settings */ +#define DEFAULT_USE_UNIX_SOCKET 0 +#define DEFAULT_RESTRICT_OUTBOUND_CLIPBOARD 0 +#define DEFAULT_ENABLE_FUSE_MOUNT 1 +#define DEFAULT_FUSE_MOUNT_NAME "xrdp-client" +#define DEFAULT_FILE_UMASK 077 + +/** + * Type used for passing a logging function about + */ +typedef +printflike(2, 3) +enum logReturns (*log_func_t)(const enum logLevels lvl, + const char *msg, ...); + +/***************************************************************************//** + * @brief Error logging function to use to log to stdout + * + * Has the same signature as the log_message() function + */ +static enum logReturns +log_to_stdout(const enum logLevels lvl, const char *msg, ...) +{ + char buff[256]; + va_list ap; + + va_start(ap, msg); + vsnprintf(buff, sizeof(buff), msg, ap); + va_end(ap); + g_writeln("%s", buff); + + return LOG_STARTUP_OK; +} + +/***************************************************************************//** + * Reads the config values we need from the [Globals] section + * + * @param logmsg Function to use to log messages + * @param names List of definitions in the section + * @params values List of corresponding values for the names + * @params cfg Pointer to structure we're filling in + * + * @return 0 for success + */ +static int +read_config_globals(log_func_t logmsg, + struct list *names, struct list *values, + struct config_chansrv *cfg) +{ + int error = 0; + int index; + + for (index = 0; index < names->count; ++index) + { + const char *name = (const char *)list_get_item(names, index); + const char *value = (const char *)list_get_item(values, index); + + if (g_strcasecmp(name, "ListenAddress") == 0) + { + if (g_strcasecmp(value, "127.0.0.1") == 0) + { + cfg->use_unix_socket = 1; + } + } + } + + return error; +} + +/***************************************************************************//** + * Reads the config values we need from the [Security] section + * + * @param logmsg Function to use to log messages + * @param names List of definitions in the section + * @params values List of corresponding values for the names + * @params cfg Pointer to structure we're filling in + * + * @return 0 for success + */ +static int +read_config_security(log_func_t logmsg, + struct list *names, struct list *values, + struct config_chansrv *cfg) +{ + int error = 0; + int index; + + for (index = 0; index < names->count; ++index) + { + const char *name = (const char *)list_get_item(names, index); + const char *value = (const char *)list_get_item(values, index); + + if (g_strcasecmp(name, "RestrictOutboundClipboard") == 0) + { + cfg->restrict_outbound_clipboard = g_text2bool(value); + } + } + + return error; +} + +/***************************************************************************//** + * Reads the config values we need from the [Chansrv] section + * + * @param logmsg Function to use to log messages + * @param names List of definitions in the section + * @params values List of corresponding values for the names + * @params cfg Pointer to structure we're filling in + * + * @return 0 for success + */ +static int +read_config_chansrv(log_func_t logmsg, + struct list *names, struct list *values, + struct config_chansrv *cfg) +{ + int error = 0; + int index; + + for (index = 0; index < names->count; ++index) + { + const char *name = (const char *)list_get_item(names, index); + const char *value = (const char *)list_get_item(values, index); + + if (g_strcasecmp(name, "EnableFuseMount") == 0) + { + cfg->enable_fuse_mount = g_text2bool(value); + } + if (g_strcasecmp(name, "FuseMountName") == 0) + { + g_free(cfg->fuse_mount_name); + cfg->fuse_mount_name = g_strdup(value); + if (cfg->fuse_mount_name == NULL) + { + logmsg(LOG_LEVEL_ERROR, "Can't alloc FuseMountName"); + error = 1; + break; + } + } + else if (g_strcasecmp(name, "FileUmask") == 0) + { + cfg->file_umask = strtol(value, NULL, 0); + } + } + + return error; +} + +/***************************************************************************//** + * @brief returns a config block with default values + * + * @return Block, or NULL for no memory + */ +static struct config_chansrv * +new_config(void) +{ + /* Do all the allocations at the beginning, then check them together */ + struct config_chansrv *cfg = g_new0(struct config_chansrv, 1); + char *fuse_mount_name = g_strdup(DEFAULT_FUSE_MOUNT_NAME); + if (cfg == NULL || fuse_mount_name == NULL) + { + /* At least one memory allocation failed */ + g_free(fuse_mount_name); + g_free(cfg); + cfg = NULL; + } + else + { + cfg->use_unix_socket = DEFAULT_USE_UNIX_SOCKET; + cfg->enable_fuse_mount = DEFAULT_ENABLE_FUSE_MOUNT; + cfg->restrict_outbound_clipboard = DEFAULT_RESTRICT_OUTBOUND_CLIPBOARD; + cfg->fuse_mount_name = fuse_mount_name; + cfg->file_umask = DEFAULT_FILE_UMASK; + } + + return cfg; +} + +/******************************************************************************/ +struct config_chansrv * +config_read(int use_logger, const char *sesman_ini) +{ + int error = 0; + struct config_chansrv *cfg = NULL; + log_func_t logmsg = (use_logger) ? log_message : log_to_stdout; + int fd; + + fd = g_file_open_ex(sesman_ini, 1, 0, 0, 0); + if (fd < 0) + { + logmsg(LOG_LEVEL_ERROR, "Can't open config file %s", sesman_ini); + error = 1; + } + else + { + if ((cfg = new_config()) == NULL) + { + logmsg(LOG_LEVEL_ERROR, "Can't alloc config block"); + error = 1; + } + else + { + struct list *names = list_create(); + struct list *values = list_create(); + + names->auto_free = 1; + values->auto_free = 1; + + if (!error && file_read_section(fd, "Globals", names, values) == 0) + { + error = read_config_globals(logmsg, names, values, cfg); + } + + + if (!error && file_read_section(fd, "Security", names, values) == 0) + { + error = read_config_security(logmsg, names, values, cfg); + } + + if (!error && file_read_section(fd, "Chansrv", names, values) == 0) + { + error = read_config_chansrv(logmsg, names, values, cfg); + } + + list_delete(names); + list_delete(values); + } + + g_file_close(fd); + } + + if (error) + { + config_free(cfg); + cfg = NULL; + } + + return cfg; +} + +/******************************************************************************/ +void +config_dump(struct config_chansrv *config) +{ + g_writeln("Global configuration:"); + g_writeln(" UseUnixSocket (derived): %s", + g_bool2text(config->use_unix_socket)); + + g_writeln("\nSecurity configuration:"); + g_writeln(" RestrictOutboundClipboard: %s", + g_bool2text(config->restrict_outbound_clipboard)); + + g_writeln("\nChansrv configuration:"); + g_writeln(" EnableFuseMount %s", + g_bool2text(config->enable_fuse_mount)); + g_writeln(" FuseMountName: %s", config->fuse_mount_name); + g_writeln(" FileMask: 0%o", config->file_umask); +} + +/******************************************************************************/ +void +config_free(struct config_chansrv *cc) +{ + if (cc != NULL) + { + g_free(cc->fuse_mount_name); + g_free(cc); + } +} diff -Nru xrdp-0.9.12/sesman/chansrv/chansrv_config.h xrdp-0.9.15/sesman/chansrv/chansrv_config.h --- xrdp-0.9.12/sesman/chansrv/chansrv_config.h 1970-01-01 00:00:00.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/chansrv_config.h 2020-12-28 14:03:43.000000000 +0000 @@ -0,0 +1,75 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file contains the chansrv configuration parameters from sesman.ini + */ + +#ifndef _CHANSRV_CONFIG +#define _CHANSRV_CONFIG + +#include + +struct config_chansrv +{ + /** Whether to use a UNIX socket for chansrv */ + int use_unix_socket; + + /** Whether the FUSE mount is enabled or not */ + int enable_fuse_mount; + + /** RestrictOutboundClipboard setting from sesman.ini */ + int restrict_outbound_clipboard; + + /** * FuseMountName from sesman.ini */ + char *fuse_mount_name; + /** FileUmask from sesman.ini */ + mode_t file_umask; +}; + + +/** + * + * @brief Reads sesman configuration + * @param use_logger Use logger to log errors (otherwise stdout) + * @param sesman_ini Name of configuration file to read + * + * @return configuration on success, NULL on failure + * + * @pre logging is assumed to be active + * @post pass return value to config_free() to prevent memory leaks + * + */ +struct config_chansrv * +config_read(int use_logger, const char *sesman_ini); + +/** + * + * @brief Dumps configuration to stdout + * @param pointer to a config_chansrv struct + * + */ +void +config_dump(struct config_chansrv *config); + +/** + * + * @brief Frees configuration allocated by config_read() + * @param pointer to a config_chansrv struct (may be NULL) + * + */ +void +config_free(struct config_chansrv *cs); + +#endif /* _CHANSRV_CONFIG */ diff -Nru xrdp-0.9.12/sesman/chansrv/chansrv_fuse.c xrdp-0.9.15/sesman/chansrv/chansrv_fuse.c --- xrdp-0.9.12/sesman/chansrv/chansrv_fuse.c 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/chansrv_fuse.c 2020-12-28 14:03:43.000000000 +0000 @@ -41,59 +41,86 @@ #include "chansrv_xfs.h" /* dummy calls when XRDP_FUSE is not defined */ -int xfuse_init(void) { return 0; } -int xfuse_deinit(void) { return 0; } -int xfuse_check_wait_objs(void) { return 0; } -int xfuse_get_wait_objs(tbus *objs, int *count, int *timeout) { return 0; } -int xfuse_create_share(tui32 device_id, const char *dirname) { return 0; } +int xfuse_init(void) +{ + return 0; +} +int xfuse_deinit(void) +{ + return 0; +} +int xfuse_check_wait_objs(void) +{ + return 0; +} +int xfuse_get_wait_objs(tbus *objs, int *count, int *timeout) +{ + return 0; +} +int xfuse_create_share(tui32 device_id, const char *dirname) +{ + return 0; +} void xfuse_delete_share(tui32 share_id) {} -int xfuse_clear_clip_dir(void) { return 0; } -int xfuse_file_contents_range(int stream_id, const char *data, int data_bytes) { return 0; } +int xfuse_clear_clip_dir(void) +{ + return 0; +} +int xfuse_file_contents_range(int stream_id, const char *data, int data_bytes) +{ + return 0; +} int xfuse_file_contents_size(int stream_id, int file_size) - { return 0; } +{ + return 0; +} int xfuse_add_clip_dir_item(const char *filename, - int flags, int size, int lindex) { return 0; } + int flags, int size, int lindex) +{ + return 0; +} void xfuse_devredir_cb_enum_dir_add_entry( - struct state_dirscan *fip, - const char *name, - const struct file_attr *fattr) - {} + struct state_dirscan *fip, + const char *name, + const struct file_attr *fattr) +{} void xfuse_devredir_cb_enum_dir_done(struct state_dirscan *fip, enum NTSTATUS IoStatus) - {} +{} void xfuse_devredir_cb_lookup_entry(struct state_lookup *fip, enum NTSTATUS IoStatus, const struct file_attr *file_info) - {} +{} void xfuse_devredir_cb_setattr(struct state_setattr *fip, enum NTSTATUS IoStatus) - {} +{} void xfuse_devredir_cb_create_file(struct state_create *fip, enum NTSTATUS IoStatus, tui32 DeviceId, tui32 FileId) - {} +{} void xfuse_devredir_cb_open_file(struct state_open *fip, enum NTSTATUS IoStatus, tui32 DeviceId, tui32 FileId) - {} +{} void xfuse_devredir_cb_read_file(struct state_read *fip, + enum NTSTATUS IoStatus, const char *buf, size_t length) - {} +{} void xfuse_devredir_cb_write_file( - struct state_write *fip, - enum NTSTATUS IoStatus, - off_t offset, - size_t length) - {} + struct state_write *fip, + enum NTSTATUS IoStatus, + off_t offset, + size_t length) +{} void xfuse_devredir_cb_rmdir_or_file(struct state_remove *fip, enum NTSTATUS IoStatus) - {} +{} void xfuse_devredir_cb_rename_file(struct state_rename *fip, enum NTSTATUS IoStatus) - {} +{} void xfuse_devredir_cb_file_close(struct state_close *fip) - {} +{} #else @@ -117,9 +144,12 @@ #include "arch.h" #include "os_calls.h" +#include "string_calls.h" #include "clipboard_file.h" #include "chansrv_fuse.h" #include "chansrv_xfs.h" +#include "chansrv.h" +#include "chansrv_config.h" #include "devredir.h" #include "list.h" #include "file.h" @@ -131,48 +161,6 @@ #define XFUSE_ATTR_TIMEOUT 5.0 #define XFUSE_ENTRY_TIMEOUT 5.0 -/* module based logging */ -#define LOG_ERROR 0 -#define LOG_INFO 1 -#define LOG_DEBUG 2 -#ifndef LOG_LEVEL -#define LOG_LEVEL LOG_ERROR -#endif - -#define log_error(_params...) \ -{ \ - g_write("[%10.10u]: FUSE %s: %d : ERROR: ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ -} - -#define log_always(_params...) \ -{ \ - g_write("[%10.10u]: FUSE %s: %d : ALWAYS: ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ -} - -#define log_info(_params...) \ -{ \ - if (LOG_INFO <= LOG_LEVEL) \ - { \ - g_write("[%10.10u]: FUSE %s: %d : ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ - } \ -} - -#define log_debug(_params...) \ -{ \ - if (LOG_DEBUG <= LOG_LEVEL) \ - { \ - g_write("[%10.10u]: FUSE %s: %d : ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ - } \ -} - /* Type of buffer used for fuse_add_direntry() calls */ struct dirbuf1 @@ -200,11 +188,11 @@ fuse_req_t req; /* Original FUSE request from lookup */ fuse_ino_t pinum; /* inum of parent directory */ char name[XFS_MAXFILENAMELEN]; - /* Name to look up */ + /* Name to look up */ fuse_ino_t existing_inum; - /* inum of an existing entry */ + /* inum of an existing entry */ tui32 existing_generation; - /* generation of the above */ + /* generation of the above */ }; /* @@ -239,7 +227,7 @@ struct fuse_file_info fi; /* File info struct passed to open */ fuse_ino_t pinum; /* inum of parent directory */ char name[XFS_MAXFILENAMELEN]; - /* Name of file in parent directory */ + /* Name of file in parent directory */ mode_t mode; /* Mode of file to create */ }; @@ -278,7 +266,7 @@ fuse_ino_t pinum; /* inum of parent of file */ fuse_ino_t new_pinum; /* inum of new parent of file */ char name[XFS_MAXFILENAMELEN]; - /* New name of file in new parent dir */ + /* New name of file in new parent dir */ }; /* @@ -296,6 +284,14 @@ tui32 DeviceId; tui32 FileId; int is_loc_resource; /* this is not a redirected resource */ + + /* a directory handle, if this xfuse_handle represents a directory. + * NULL, if this xfuse_handle represents a file. + * + * Note: when this xfuse_handle represents a directory, then the other + * fields of this structure contain invalid values. + */ + struct xfs_dir_handle *dir_handle; }; typedef struct xfuse_handle XFUSE_HANDLE; @@ -309,8 +305,7 @@ int size; }; -static char g_fuse_mount_name[256] = "xrdp_client"; -static mode_t g_umask = 077; /* Umask for files in fs */ +extern struct config_chansrv *g_cfg; /* in chansrv.c */ static struct list *g_req_list = 0; static struct xfs_fs *g_xfs; /* an inst of xrdp file system */ @@ -391,50 +386,60 @@ /* miscellaneous functions */ static void xfs_inode_to_fuse_entry_param(const XFS_INODE *xinode, - struct fuse_entry_param *e); + struct fuse_entry_param *e); static void make_fuse_entry_reply(fuse_req_t req, const XFS_INODE *xinode); static void make_fuse_attr_reply(fuse_req_t req, const XFS_INODE *xinode); static const char *filename_on_device(const char *full_path); static void update_inode_file_attributes(const struct file_attr *fattr, - tui32 change_mask, XFS_INODE *xinode); + tui32 change_mask, XFS_INODE *xinode); static char *get_name_for_entry_in_parent(fuse_ino_t parent, const char *name); +static unsigned int format_user_info(char *dest, unsigned int len, + const char *format); /*****************************************************************************/ int load_fuse_config(void) { - int index; - char cfg_file[256]; - struct list *items; - struct list *values; - char *item; - char *value; - - items = list_create(); - items->auto_free = 1; - values = list_create(); - values->auto_free = 1; - g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); - file_by_name_read_section(cfg_file, "Chansrv", items, values); - for (index = 0; index < items->count; index++) - { - item = (char *)list_get_item(items, index); - value = (char *)list_get_item(values, index); - if (g_strcasecmp(item, "FuseMountName") == 0) - { - g_strncpy(g_fuse_mount_name, value, 255); - } - else if (g_strcasecmp(item, "FileUmask") == 0) - { - g_umask = strtol(value, NULL, 0); - log_info("g_umask set to 0%o", g_umask); - } - } - list_delete(items); - list_delete(values); return 0; } +/*****************************************************************************/ +XFUSE_HANDLE * +xfuse_handle_create() +{ + return g_new0(XFUSE_HANDLE, 1); +} + +/*****************************************************************************/ +void +xfuse_handle_delete(XFUSE_HANDLE *self) +{ + if (self == NULL) + { + return; + } + + if (self->dir_handle != NULL) + { + free(self->dir_handle); + } + free(self); +} + +/*****************************************************************************/ +uint64_t +xfuse_handle_to_fuse_handle(XFUSE_HANDLE *self) +{ + return (uint64_t) (tintptr) self; +} + +/*****************************************************************************/ +XFUSE_HANDLE * +xfuse_handle_from_fuse_handle(uint64_t handle) +{ + return (XFUSE_HANDLE *) (tintptr) handle; +} + /***************************************************************************** ** ** ** public functions - can be called from any code path ** @@ -444,7 +449,7 @@ /** * Initialize FUSE subsystem * - * @return 0 on success, -1 on failure + * @return 0 on success, -1 on failure, 1 for feature disabled *****************************************************************************/ int @@ -455,28 +460,57 @@ /* if already inited, just return */ if (g_xfuse_inited) { - log_debug("already inited"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "already inited"); + return 0; + } + + /* This feature may be disabled */ + if (!g_cfg->enable_fuse_mount) + { + /* + * Only log the 'disabled mounts' message one time + */ + static int disabled_mounts_msg_shown = 0; + if (!disabled_mounts_msg_shown) + { + LOG(LOG_LEVEL_INFO, "FUSE mounts are disabled by config"); + disabled_mounts_msg_shown = 1; + } return 1; } if (g_ch != 0) { - log_error("g_ch is not zero"); + LOG_DEVEL(LOG_LEVEL_ERROR, "g_ch is not zero"); return -1; } load_fuse_config(); - /* define FUSE mount point to ~/xrdp_client, ~/thinclient_drives */ - g_snprintf(g_fuse_root_path, 255, "%s/%s", g_getenv("HOME"), g_fuse_mount_name); + /* define FUSE mount point */ + if (g_cfg->fuse_mount_name[0] == '/') + { + /* String is an absolute path to the mount point containing + * %u or %U characters */ + format_user_info(g_fuse_root_path, sizeof(g_fuse_root_path), + g_cfg->fuse_mount_name); + } + else + { + /* mount_name is relative to $HOME, e.g. ~/xrdp_client, + * or ~/thinclient_drives */ + g_snprintf(g_fuse_root_path, sizeof(g_fuse_root_path), "%s/%s", + g_getenv("HOME"), g_cfg->fuse_mount_name); + } g_snprintf(g_fuse_clipboard_path, 255, "%s/.clipboard", g_fuse_root_path); /* if FUSE mount point does not exist, create it */ if (!g_directory_exist(g_fuse_root_path)) { + (void)g_create_path(g_fuse_root_path); if (!g_create_dir(g_fuse_root_path)) { - log_error("mkdir %s failed. If %s is already mounted, you must " + LOG_DEVEL(LOG_LEVEL_ERROR, "mkdir %s failed. If %s is already mounted, you must " "first unmount it", g_fuse_root_path, g_fuse_root_path); return -1; } @@ -484,7 +518,9 @@ /* setup xrdp file system */ if (xfuse_init_xrdp_fs()) + { return -1; + } /* setup FUSE callbacks */ g_memset(&g_xfuse_ops, 0, sizeof(g_xfuse_ops)); @@ -571,7 +607,9 @@ int rval; if (g_ch == 0) + { return 0; + } if (g_tcp_select(g_fd, 0) & 1) { @@ -579,13 +617,19 @@ rval = fuse_chan_recv(&tmpch, g_buffer, g_bufsize); if (rval == -EINTR) + { return -1; + } if (rval == -ENODEV) + { return -1; + } if (rval <= 0) + { return -1; + } fuse_session_process(g_se, g_buffer, rval, tmpch); } @@ -604,7 +648,9 @@ int lcount; if (g_ch == 0) + { return 0; + } lcount = *count; objs[lcount] = g_fd; @@ -628,15 +674,16 @@ XFS_INODE *xinode; if (dirname != NULL && strlen(dirname) > 0 && - xfuse_init_xrdp_fs() == 0) + xfuse_init_xrdp_fs() == 0) { xinode = xfs_add_entry(g_xfs, FUSE_ROOT_ID, dirname, (0777 | S_IFDIR)); if (xinode == NULL) { - log_debug("xfs_add_entry() failed"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xfs_add_entry() failed"); } else { + xinode->is_redirected = 1; xinode->device_id = device_id; result = 0; } @@ -653,7 +700,7 @@ void xfuse_delete_share(tui32 device_id) { - xfs_delete_entries_with_device_id(g_xfs, device_id); + xfs_delete_redirected_entries_with_device_id(g_xfs, device_id); } /** @@ -685,24 +732,24 @@ int xfuse_file_contents_range(int stream_id, const char *data, int data_bytes) { - log_debug("entered: stream_id=%d data_bytes=%d", stream_id, data_bytes); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: stream_id=%d data_bytes=%d", stream_id, data_bytes); struct req_list_item *rli; if ((rli = (struct req_list_item *) list_get_item(g_req_list, 0)) == NULL) { - log_error("range error!"); + LOG_DEVEL(LOG_LEVEL_ERROR, "range error!"); return -1; } - log_debug("lindex=%d off=%d size=%d", rli->lindex, rli->off, rli->size); + LOG_DEVEL(LOG_LEVEL_DEBUG, "lindex=%d off=%d size=%d", rli->lindex, rli->off, rli->size); fuse_reply_buf(rli->req, data, data_bytes); list_remove_item(g_req_list, 0); if (g_req_list->count <= 0) { - log_debug("completed all requests"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "completed all requests"); return 0; } @@ -710,14 +757,14 @@ rli = (struct req_list_item *) list_get_item(g_req_list, 0); if (rli == NULL) { - log_error("range error!"); + LOG_DEVEL(LOG_LEVEL_ERROR, "range error!"); return -1; } - log_debug("requesting clipboard file data"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "requesting clipboard file data"); clipboard_request_file_data(rli->stream_id, rli->lindex, - rli->off, rli->size); + rli->off, rli->size); return 0; } @@ -733,23 +780,38 @@ int xfuse_add_clip_dir_item(const char *filename, int flags, int size, int lindex) { - log_debug("entered: filename=%s flags=%d size=%d lindex=%d", + LOG_DEVEL(LOG_LEVEL_DEBUG, + "entered: filename=%s flags=%d size=%d lindex=%d", filename, flags, size, lindex); - /* add entry to xrdp_fs */ - XFS_INODE *xinode = xfs_add_entry( g_xfs, - g_clipboard_inum, /* parent inode */ - filename, - (0666 | S_IFREG)); - if (xinode == NULL) + int result = -1; + + if (g_xfs == NULL) { - log_debug("failed to create file in xrdp filesystem"); - return -1; + LOG_DEVEL(LOG_LEVEL_ERROR, + "xfuse_add_clip_dir_item() called with no filesystem") + } + else + { + /* add entry to xrdp_fs */ + XFS_INODE *xinode = xfs_add_entry( g_xfs, + g_clipboard_inum, /* parent inode */ + filename, + (0666 | S_IFREG)); + if (xinode == NULL) + { + LOG(LOG_LEVEL_INFO, + "failed to create file %s in xrdp filesystem", filename); + } + else + { + xinode->size = size; + xinode->lindex = lindex; + result = 0; + } } - xinode->size = size; - xinode->lindex = lindex; - return 0; + return result; } /** @@ -760,7 +822,7 @@ int xfuse_file_contents_size(int stream_id, int file_size) { - log_debug("entered: stream_id=%d file_size=%d", stream_id, file_size); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: stream_id=%d file_size=%d", stream_id, file_size); return 0; } @@ -780,14 +842,14 @@ { if (fuse_parse_cmdline(args, &g_mount_point, 0, 0) < 0) { - log_error("fuse_parse_cmdline() failed"); + LOG_DEVEL(LOG_LEVEL_ERROR, "fuse_parse_cmdline() failed"); fuse_opt_free_args(args); return -1; } if ((g_ch = fuse_mount(g_mount_point, args)) == 0) { - log_error("fuse_mount() failed"); + LOG_DEVEL(LOG_LEVEL_ERROR, "fuse_mount() failed"); fuse_opt_free_args(args); return -1; } @@ -795,7 +857,7 @@ g_se = fuse_lowlevel_new(args, &g_xfuse_ops, sizeof(g_xfuse_ops), 0); if (g_se == 0) { - log_error("fuse_lowlevel_new() failed"); + LOG_DEVEL(LOG_LEVEL_ERROR, "fuse_lowlevel_new() failed"); fuse_unmount(g_mount_point, g_ch); g_ch = 0; fuse_opt_free_args(args); @@ -834,7 +896,7 @@ } else if ((g_xfs = xfs_create_xfs_fs(0, g_getuid(), g_getgid())) == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); } else { @@ -843,7 +905,7 @@ (0777 | S_IFDIR)); if (xino == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); xfs_delete_xfs_fs(g_xfs); g_xfs = NULL; } @@ -851,7 +913,7 @@ { g_clipboard_inum = xino->inum; result = 0; - } + } } return result; } @@ -886,15 +948,15 @@ *****************************************************************************/ void xfuse_devredir_cb_enum_dir_add_entry( - struct state_dirscan *fip, - const char *name, - const struct file_attr *fattr) + struct state_dirscan *fip, + const char *name, + const struct file_attr *fattr) { XFS_INODE *xinode = NULL; if (!xfs_get(g_xfs, fip->pinum)) { - log_error("inode %ld is not valid", fip->pinum); + LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is not valid", fip->pinum); } else if ((strcmp(name, ".") == 0) || (strcmp(name, "..") == 0)) @@ -903,7 +965,7 @@ } else { - log_debug("parent_inode=%ld name=%s", fip->pinum, name); + LOG_DEVEL(LOG_LEVEL_DEBUG, "parent_inode=%ld name=%s", fip->pinum, name); /* Does the file already exist ? If it does it's important we * don't mess with it, as we're only enumerating the directory, and @@ -913,12 +975,12 @@ if (xinode == NULL) { /* Add a new node to the file system */ - log_debug("Creating name=%s in parent=%ld in xrdp_fs", + LOG_DEVEL(LOG_LEVEL_DEBUG, "Creating name=%s in parent=%ld in xrdp_fs", name, fip->pinum); xinode = xfs_add_entry(g_xfs, fip->pinum, name, fattr->mode); if (xinode == NULL) { - log_error("xfs_add_entry() failed"); + LOG_DEVEL(LOG_LEVEL_ERROR, "xfs_add_entry() failed"); } else { @@ -943,17 +1005,17 @@ void xfuse_devredir_cb_enum_dir_done(struct state_dirscan *fip, enum NTSTATUS IoStatus) { - log_debug("fip=%p IoStatus=0x%x", fip, IoStatus); + LOG_DEVEL(LOG_LEVEL_DEBUG, "fip=%p IoStatus=0x%x", fip, IoStatus); /* - * NT_STATUS_NO_SUCH_FILE is returned for empty directories + * STATUS_NO_SUCH_FILE is returned for empty directories */ - if (IoStatus != NT_STATUS_SUCCESS && IoStatus != NT_STATUS_NO_SUCH_FILE) + if (IoStatus != STATUS_SUCCESS && IoStatus != STATUS_NO_SUCH_FILE) { int status; switch (IoStatus) { - case NT_STATUS_ACCESS_DENIED: + case STATUS_ACCESS_DENIED: status = EACCES; break; default: @@ -963,19 +1025,23 @@ } else if (!xfs_get(g_xfs, fip->pinum)) { - log_error("inode %ld is not valid", fip->pinum); + LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is not valid", fip->pinum); fuse_reply_err(fip->req, ENOENT); } else { struct fuse_file_info *fi = &fip->fi; + XFUSE_HANDLE *xhandle = xfuse_handle_create(); - if ((fi->fh = (tintptr) xfs_opendir(g_xfs, fip->pinum)) == 0) + if (xhandle == NULL + || (xhandle->dir_handle = xfs_opendir(g_xfs, fip->pinum)) == NULL) { + xfuse_handle_delete(xhandle); fuse_reply_err(fip->req, ENOMEM); } else { + fi->fh = xfuse_handle_to_fuse_handle(xhandle); fuse_reply_open(fip->req, &fip->fi); } } @@ -984,7 +1050,7 @@ } /** - * This routine is caused as a result of a devredir remote lookup + * This routine is caused as a result of a devredir remote lookup * instigated by xfuse_cb_lookup() *****************************************************************************/ @@ -994,48 +1060,48 @@ { XFS_INODE *xinode = NULL; - if (IoStatus != NT_STATUS_SUCCESS) + if (IoStatus != STATUS_SUCCESS) { switch (IoStatus) { - case NT_STATUS_SHARING_VIOLATION: - /* This can happen when trying to read the attributes of - * some system files (e.g. pagefile.sys) */ - case NT_STATUS_ACCESS_DENIED: + case STATUS_SHARING_VIOLATION: + /* This can happen when trying to read the attributes of + * some system files (e.g. pagefile.sys) */ + case STATUS_ACCESS_DENIED: fuse_reply_err(fip->req, EACCES); break; - case NT_STATUS_UNSUCCESSFUL: + case STATUS_UNSUCCESSFUL: /* Happens if we try to lookup an illegal filename (e.g. * one with a '*' in it) */ fuse_reply_err(fip->req, ENOENT); break; - case NT_STATUS_NO_SUCH_FILE: + case STATUS_NO_SUCH_FILE: /* Remove our copy, if any */ - if (fip->existing_inum && - (xinode = xfs_get(g_xfs, fip->existing_inum)) != NULL && - xinode->generation == fip->existing_generation) - { + if (fip->existing_inum && + (xinode = xfs_get(g_xfs, fip->existing_inum)) != NULL && + xinode->generation == fip->existing_generation) + { xfs_remove_entry(g_xfs, fip->existing_inum); } fuse_reply_err(fip->req, ENOENT); break; default: - log_info("Error code %08x - fallthrough", (int) IoStatus); + LOG_DEVEL(LOG_LEVEL_INFO, "Error code %08x - fallthrough", (int) IoStatus); fuse_reply_err(fip->req, EIO); break; } } else if (!xfs_get(g_xfs, fip->pinum)) { - log_error("parent inode %ld is not valid", fip->pinum); + LOG_DEVEL(LOG_LEVEL_ERROR, "parent inode %ld is not valid", fip->pinum); fuse_reply_err(fip->req, ENOENT); } else { - log_debug("parent_inode=%ld name=%s", fip->pinum, fip->name); + LOG_DEVEL(LOG_LEVEL_DEBUG, "parent_inode=%ld name=%s", fip->pinum, fip->name); /* Does the file already exist ? */ xinode = xfs_lookup_in_dir(g_xfs, fip->pinum, fip->name); @@ -1043,9 +1109,9 @@ { /* Is the existing file the same type ? */ if ((xinode->mode & (S_IFREG | S_IFDIR)) == - (file_info->mode & (S_IFREG | S_IFDIR))) + (file_info->mode & (S_IFREG | S_IFDIR))) { - log_debug("inode=%ld name=%s already exists in xrdp_fs as %ld", + LOG_DEVEL(LOG_LEVEL_DEBUG, "inode=%ld name=%s already exists in xrdp_fs as %ld", fip->pinum, fip->name, xinode->inum); if (xfs_get_file_open_count(g_xfs, xinode->inum) > 0) { @@ -1055,19 +1121,19 @@ * would be truncating a file we're currently writing * to, as the lookup value for the size is stale. */ - log_debug("inode=%ld is open - " + LOG_DEVEL(LOG_LEVEL_DEBUG, "inode=%ld is open - " "preferring local attributes", xinode->inum); } else { - log_debug("Updating attributes of inode=%ld", xinode->inum); + LOG_DEVEL(LOG_LEVEL_DEBUG, "Updating attributes of inode=%ld", xinode->inum); update_inode_file_attributes(file_info, TO_SET_ALL, xinode); } } else { /* Type has changed from file to directory, or vice-versa */ - log_debug("inode=%ld name=%s of different type in xrdp_fs" + LOG_DEVEL(LOG_LEVEL_DEBUG, "inode=%ld name=%s of different type in xrdp_fs" " - removing", fip->pinum, xinode->name); xfs_remove_entry(g_xfs, xinode->inum); @@ -1078,13 +1144,13 @@ if (xinode == NULL) { /* Add a new node to the file system */ - log_debug("Creating name=%s in parent=%ld in xrdp_fs", + LOG_DEVEL(LOG_LEVEL_DEBUG, "Creating name=%s in parent=%ld in xrdp_fs", fip->name, fip->pinum); xinode = xfs_add_entry(g_xfs, fip->pinum, fip->name, file_info->mode); if (xinode == NULL) { - log_debug("xfs_add_entry() failed"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xfs_add_entry() failed"); } else { @@ -1119,25 +1185,25 @@ { XFS_INODE *xinode; - if (IoStatus != NT_STATUS_SUCCESS) + if (IoStatus != STATUS_SUCCESS) { switch (IoStatus) { - case NT_STATUS_SHARING_VIOLATION: - /* This can happen when trying to read the attributes of - * some system files (e.g. pagefile.sys) */ - case NT_STATUS_ACCESS_DENIED: + case STATUS_SHARING_VIOLATION: + /* This can happen when trying to read the attributes of + * some system files (e.g. pagefile.sys) */ + case STATUS_ACCESS_DENIED: fuse_reply_err(fip->req, EACCES); break; - case NT_STATUS_UNSUCCESSFUL: - /* Happens if we try to lookup an illegal filename */ - case NT_STATUS_NO_SUCH_FILE: + case STATUS_UNSUCCESSFUL: + /* Happens if we try to lookup an illegal filename */ + case STATUS_NO_SUCH_FILE: fuse_reply_err(fip->req, ENOENT); break; default: - log_info("Error code %08x - fallthrough", (int) IoStatus); + LOG_DEVEL(LOG_LEVEL_INFO, "Error code %08x - fallthrough", (int) IoStatus); fuse_reply_err(fip->req, EIO); break; } @@ -1167,18 +1233,18 @@ { switch (IoStatus) { - case NT_STATUS_ACCESS_DENIED: - fuse_reply_err(fip->req, EACCES); - break; + case STATUS_ACCESS_DENIED: + fuse_reply_err(fip->req, EACCES); + break; - case NT_STATUS_OBJECT_NAME_INVALID: - case NT_STATUS_OBJECT_NAME_NOT_FOUND: - fuse_reply_err(fip->req, ENOENT); - break; + case STATUS_OBJECT_NAME_INVALID: + case STATUS_OBJECT_NAME_NOT_FOUND: + fuse_reply_err(fip->req, ENOENT); + break; - default: - fuse_reply_err(fip->req, EIO); - break; + default: + fuse_reply_err(fip->req, EIO); + break; } } else @@ -1187,20 +1253,20 @@ { /* We've created a regular file */ /* Allocate an XFUSE_HANDLE for future file operations */ - if ((fh = g_new0(XFUSE_HANDLE, 1)) != NULL) + if ((fh = xfuse_handle_create()) != NULL) { /* save file handle for later use */ fh->DeviceId = DeviceId; fh->FileId = FileId; - fip->fi.fh = (tintptr) fh; + fip->fi.fh = xfuse_handle_to_fuse_handle(fh); } } if ((fip->mode & S_IFREG) != 0 && fh == NULL) { /* We failed to allocate a file handle */ - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); fuse_reply_err(fip->req, ENOMEM); } else @@ -1231,7 +1297,7 @@ if (xinode == NULL) { - log_error("Out of memory!"); + LOG_DEVEL(LOG_LEVEL_ERROR, "Out of memory!"); fuse_reply_err(fip->req, ENOMEM); } else @@ -1250,6 +1316,7 @@ } } } + } free(fip); @@ -1268,26 +1335,26 @@ { switch (IoStatus) { - case NT_STATUS_ACCESS_DENIED: - fuse_reply_err(fip->req, EACCES); - break; + case STATUS_ACCESS_DENIED: + fuse_reply_err(fip->req, EACCES); + break; - case NT_STATUS_OBJECT_NAME_INVALID: - case NT_STATUS_OBJECT_NAME_NOT_FOUND: - fuse_reply_err(fip->req, ENOENT); - break; + case STATUS_OBJECT_NAME_INVALID: + case STATUS_OBJECT_NAME_NOT_FOUND: + fuse_reply_err(fip->req, ENOENT); + break; - default: - fuse_reply_err(fip->req, EIO); - break; + default: + fuse_reply_err(fip->req, EIO); + break; } } else { /* Allocate an XFUSE_HANDLE for future file operations */ - if ((fh = g_new0(XFUSE_HANDLE, 1)) == NULL) + if ((fh = xfuse_handle_create()) == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); fuse_reply_err(fip->req, ENOMEM); } else @@ -1296,9 +1363,9 @@ fh->DeviceId = DeviceId; fh->FileId = FileId; - fip->fi.fh = (tintptr) fh; + fip->fi.fh = xfuse_handle_to_fuse_handle(fh); - log_debug("sending fuse_reply_open(); " + LOG_DEVEL(LOG_LEVEL_DEBUG, "sending fuse_reply_open(); " "DeviceId=%d FileId=%d req=%p", fh->DeviceId, fh->FileId, fip->req); @@ -1313,23 +1380,32 @@ } void xfuse_devredir_cb_read_file(struct state_read *fip, + enum NTSTATUS IoStatus, const char *buf, size_t length) { - fuse_reply_buf(fip->req, buf, length); + if (IoStatus != STATUS_SUCCESS) + { + LOG_DEVEL(LOG_LEVEL_ERROR, "Read NTSTATUS is %d", (int) IoStatus); + fuse_reply_err(fip->req, EIO); + } + else + { + fuse_reply_buf(fip->req, buf, length); + } free(fip); } void xfuse_devredir_cb_write_file( - struct state_write *fip, - enum NTSTATUS IoStatus, - off_t offset, - size_t length) + struct state_write *fip, + enum NTSTATUS IoStatus, + off_t offset, + size_t length) { XFS_INODE *xinode; - if (IoStatus != NT_STATUS_SUCCESS) + if (IoStatus != STATUS_SUCCESS) { - log_error("Write NTSTATUS is %d", (int) IoStatus); + LOG_DEVEL(LOG_LEVEL_ERROR, "Write NTSTATUS is %d", (int) IoStatus); fuse_reply_err(fip->req, EIO); } else @@ -1347,7 +1423,7 @@ } else { - log_error("inode %ld is invalid", fip->inum); + LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is invalid", fip->inum); } } @@ -1361,19 +1437,19 @@ switch (IoStatus) { - case NT_STATUS_SUCCESS: - case NT_STATUS_NO_SUCH_FILE: + case STATUS_SUCCESS: + case STATUS_NO_SUCH_FILE: xfs_remove_entry(g_xfs, xinode->inum); /* Remove local copy */ fuse_reply_err(fip->req, 0); break; - case NT_STATUS_SHARING_VIOLATION: - case NT_STATUS_ACCESS_DENIED: + case STATUS_SHARING_VIOLATION: + case STATUS_ACCESS_DENIED: fuse_reply_err(fip->req, EACCES); break; default: - log_info("Error code %08x - fallthrough", (int) IoStatus); + LOG_DEVEL(LOG_LEVEL_INFO, "Error code %08x - fallthrough", (int) IoStatus); fuse_reply_err(fip->req, EBADF); break; } @@ -1385,12 +1461,12 @@ { int status; - if (IoStatus != NT_STATUS_SUCCESS) + if (IoStatus != STATUS_SUCCESS) { status = - (IoStatus == NT_STATUS_SHARING_VIOLATION) ? EBUSY : - (IoStatus == NT_STATUS_ACCESS_DENIED) ? EACCES : - /* default */ EEXIST ; + (IoStatus == STATUS_SHARING_VIOLATION) ? EBUSY : + (IoStatus == STATUS_ACCESS_DENIED) ? EACCES : + /* default */ EEXIST ; } else { @@ -1425,7 +1501,7 @@ XFS_INODE *parent_xinode; XFS_INODE *xinode = NULL; - log_debug("looking for parent=%ld name=%s", parent, name); + LOG_DEVEL(LOG_LEVEL_DEBUG, "looking for parent=%ld name=%s", parent, name); if (strlen(name) > XFS_MAXFILENAMELEN) { @@ -1433,17 +1509,17 @@ } else if ((parent_xinode = xfs_get(g_xfs, parent)) == NULL) { - log_error("inode %ld is not valid", parent); + LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is not valid", parent); fuse_reply_err(req, ENOENT); } else { - if (parent_xinode->device_id == 0) + if (!parent_xinode->is_redirected) { /* File cannot be remote - we either know about it or we don't */ if ((xinode = xfs_lookup_in_dir(g_xfs, parent, name)) != NULL) { - log_debug("found entry for parent=%ld name=%s", + LOG_DEVEL(LOG_LEVEL_DEBUG, "found entry for parent=%ld name=%s", parent, name); make_fuse_entry_reply(req, xinode); } @@ -1463,7 +1539,7 @@ if (fip == NULL || full_path == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); fuse_reply_err(req, ENOMEM); free(fip); free(full_path); @@ -1488,15 +1564,15 @@ fip->existing_inum = xinode->inum; fip->existing_generation = xinode->generation; } - log_debug("Looking up %s in %s on %d", name, cptr, - parent_xinode->device_id); + LOG_DEVEL(LOG_LEVEL_DEBUG, "Looking up %s in %s on %d", name, cptr, + parent_xinode->device_id); /* * If this call succeeds, further request processing happens in * xfuse_devredir_cb_lookup_entry() */ if (devredir_lookup_entry(fip, parent_xinode->device_id, cptr)) { - log_error("failed to send devredir_lookup_entry() cmd"); + LOG_DEVEL(LOG_LEVEL_ERROR, "failed to send devredir_lookup_entry() cmd"); fuse_reply_err(req, EREMOTEIO); free(fip); } @@ -1514,16 +1590,16 @@ *****************************************************************************/ static void xfuse_cb_getattr(fuse_req_t req, fuse_ino_t ino, - struct fuse_file_info *fi) + struct fuse_file_info *fi) { XFS_INODE *xino; - log_debug("req=%p ino=%ld", req, ino); + LOG_DEVEL(LOG_LEVEL_DEBUG, "req=%p ino=%ld", req, ino); /* if ino is not valid, just return */ if ((xino = xfs_get(g_xfs, ino)) == NULL) { - log_error("inode %ld is not valid", ino); + LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is not valid", ino); fuse_reply_err(req, ENOENT); } else @@ -1550,7 +1626,7 @@ memset(&stbuf, 0, sizeof(stbuf)); stbuf.st_ino = xinode->inum; - stbuf.st_mode = xinode->mode & ~g_umask; + stbuf.st_mode = xinode->mode & ~g_cfg->file_umask; /* * Try to add the entry. From the docs for fuse_add_direntry():- @@ -1559,12 +1635,12 @@ * still returned." */ len = fuse_add_direntry(req, - &b->buf[b->len], /* index where new entry will be added to buf */ - sizeof(b->buf) - b->len, /* Space left */ - xinode->name, /* name of entry */ - &stbuf, /* file attributes */ - offset /* offset of next entry */ - ); + &b->buf[b->len], /* index where new entry will be added to buf */ + sizeof(b->buf) - b->len, /* Space left */ + xinode->name, /* name of entry */ + &stbuf, /* file attributes */ + offset /* offset of next entry */ + ); if (len + b->len <= sizeof(b->buf)) { /* Entry fitted in OK */ @@ -1585,18 +1661,20 @@ off_t off, struct fuse_file_info *fi) { XFS_INODE *xinode; + XFUSE_HANDLE *xhandle; struct xfs_dir_handle *dh; struct dirbuf1 b; - log_debug("req=%p inode=%ld size=%zd offset=%lld", req, ino, size, (long long) off); + LOG_DEVEL(LOG_LEVEL_DEBUG, "req=%p inode=%ld size=%zd offset=%lld", req, ino, size, (long long) off); /* On the first call, check the inode is valid */ if (off == 0 && !xfs_get(g_xfs, ino)) { - log_error("inode %ld is not valid", ino); + LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is not valid", ino); fuse_reply_err(req, ENOENT); } - else if ((dh = (struct xfs_dir_handle *) fi->fh) == NULL) + else if ((xhandle = xfuse_handle_from_fuse_handle(fi->fh)) == NULL + || (dh = xhandle->dir_handle) == NULL) { /* something seriously wrong somewhere! */ fuse_reply_buf(req, 0, 0); @@ -1630,7 +1708,7 @@ { XFS_INODE *xinode; - log_debug("entered: parent_inode=%ld name=%s", parent, name); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: parent_inode=%ld name=%s", parent, name); if ((xinode = xfs_lookup_in_dir(g_xfs, parent, name)) != NULL) { @@ -1654,7 +1732,7 @@ { XFS_INODE *xinode; - log_debug("entered: parent=%ld name=%s", parent, name); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: parent=%ld name=%s", parent, name); if (strlen(name) > XFS_MAXFILENAMELEN) { @@ -1662,24 +1740,24 @@ } else if ((xinode = xfs_lookup_in_dir(g_xfs, parent, name)) == NULL) { - log_error("did not find file with pinode=%ld name=%s", parent, name); + LOG_DEVEL(LOG_LEVEL_ERROR, "did not find file with pinode=%ld name=%s", parent, name); fuse_reply_err(req, ENOENT); } else if ((xinode->mode & S_IFDIR) != 0 && !xfs_is_dir_empty(g_xfs, xinode->inum)) { - log_debug("cannot rmdir; directory is not empty"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "cannot rmdir; directory is not empty"); fuse_reply_err(req, ENOTEMPTY); } - else if (xinode->device_id == 0) + else if (!xinode->is_redirected) { /* specified file is a local resource */ //XFUSE_HANDLE *fh; - log_debug("LK_TODO: this is still a TODO"); - fuse_reply_err(req, EINVAL); + LOG_DEVEL(LOG_LEVEL_DEBUG, "LK_TODO: this is still a TODO"); + fuse_reply_err(req, EROFS); } else { @@ -1688,10 +1766,9 @@ char *full_path = xfs_get_full_path(g_xfs, xinode->inum); if (!full_path || !fip) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); fuse_reply_err(req, ENOMEM); free(fip); - free(full_path); } else { @@ -1710,7 +1787,7 @@ */ if (devredir_rmdir_or_file(fip, xinode->device_id, cptr)) { - log_error("failed to send devredir_rmdir_or_file() cmd"); + LOG_DEVEL(LOG_LEVEL_ERROR, "failed to send devredir_rmdir_or_file() cmd"); fuse_reply_err(req, EREMOTEIO); free(fip); } @@ -1727,44 +1804,45 @@ XFS_INODE *old_xinode; XFS_INODE *new_parent_xinode; - log_debug("entered: old_parent=%ld old_name=%s new_parent=%ld new_name=%s", + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: old_parent=%ld old_name=%s new_parent=%ld new_name=%s", old_parent, old_name, new_parent, new_name); if (strlen(old_name) > XFS_MAXFILENAMELEN || - strlen(new_name) > XFS_MAXFILENAMELEN) + strlen(new_name) > XFS_MAXFILENAMELEN) { fuse_reply_err(req, ENAMETOOLONG); } else if (!(old_xinode = xfs_lookup_in_dir(g_xfs, old_parent, old_name))) { - log_error("did not find file with pinode=%ld name=%s", + LOG_DEVEL(LOG_LEVEL_ERROR, "did not find file with pinode=%ld name=%s", old_parent, old_name); fuse_reply_err(req, ENOENT); } else if (!(new_parent_xinode = xfs_get(g_xfs, new_parent))) { - log_error("inode %ld is not valid", new_parent); - fuse_reply_err(req, EINVAL); + LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is not valid", new_parent); + fuse_reply_err(req, ENOENT); } else if (!xfs_check_move_entry(g_xfs, old_xinode->inum, new_parent, new_name)) { + /* Catchall -see rename(2). Fix when logging is improved */ fuse_reply_err(req, EINVAL); } - else if (new_parent_xinode->device_id != old_xinode->device_id) + else if (new_parent_xinode->is_redirected != old_xinode->is_redirected || + new_parent_xinode->device_id != old_xinode->device_id) { - log_error("rename across file systems not supported"); - fuse_reply_err(req, EINVAL); + fuse_reply_err(req, EXDEV); } - else if (old_xinode->device_id == 0) + else if (!old_xinode->is_redirected) { /* specified file is a local resource */ - log_debug("LK_TODO: this is still a TODO"); - fuse_reply_err(req, EINVAL); + LOG_DEVEL(LOG_LEVEL_DEBUG, "LK_TODO: this is still a TODO"); + fuse_reply_err(req, EROFS); } else @@ -1773,11 +1851,11 @@ struct state_rename *fip = g_new0(struct state_rename, 1); char *old_full_path = xfs_get_full_path(g_xfs, old_xinode->inum); char *new_full_path = get_name_for_entry_in_parent(new_parent, - new_name); + new_name); if (!old_full_path || !new_full_path || !fip) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); fuse_reply_err(req, ENOMEM); free(fip); free(old_full_path); @@ -1803,7 +1881,7 @@ */ if (devredir_file_rename(fip, old_xinode->device_id, cptr, cp)) { - log_error("failed to send devredir_file_rename() cmd"); + LOG_DEVEL(LOG_LEVEL_ERROR, "failed to send devredir_file_rename() cmd"); fuse_reply_err(req, EREMOTEIO); free(fip); } @@ -1830,7 +1908,7 @@ { XFS_INODE *xinode; - log_debug("entered: parent_ino=%ld name=%s mode=%o type=%s", + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: parent_ino=%ld name=%s mode=%o type=%s", parent, name, mode, (mode & S_IFDIR) ? "dir" : "file"); /* name must be valid */ @@ -1854,20 +1932,25 @@ } /* is parent inode valid? */ - if (parent == FUSE_ROOT_ID || - (xinode = xfs_get(g_xfs, parent)) == NULL || - (xinode->mode & S_IFDIR) == 0) + if (parent == FUSE_ROOT_ID) + { + fuse_reply_err(req, EROFS); + } + else if ((xinode = xfs_get(g_xfs, parent)) == NULL) { - log_error("inode %ld is not valid", parent); fuse_reply_err(req, ENOENT); } - else if (xinode->device_id == 0) + else if ((xinode->mode & S_IFDIR) == 0) + { + fuse_reply_err(req, ENOTDIR); + } + else if (!xinode->is_redirected) { /* specified file is a local resource */ //XFUSE_HANDLE *fh; - log_debug("LK_TODO: this is still a TODO"); - fuse_reply_err(req, EINVAL); + LOG_DEVEL(LOG_LEVEL_DEBUG, "LK_TODO: this is still a TODO"); + fuse_reply_err(req, EROFS); } else { @@ -1876,7 +1959,7 @@ if (full_path == NULL || fip == NULL) { - log_error("Out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "Out of memory"); fuse_reply_err(req, ENOMEM); free(fip); free(full_path); @@ -1903,7 +1986,7 @@ */ if (devredir_file_create(fip, xinode->device_id, cptr, mode)) { - log_error("failed to send devredir_file_create() cmd"); + LOG_DEVEL(LOG_LEVEL_ERROR, "failed to send devredir_file_create() cmd"); fuse_reply_err(req, EREMOTEIO); free(fip); } @@ -1926,33 +2009,40 @@ { XFS_INODE *xinode; - log_debug("entered: ino=%ld", ino); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: ino=%ld", ino); if (!(xinode = xfs_get(g_xfs, ino))) { - log_error("inode %ld is not valid", ino); + LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is not valid", ino); fuse_reply_err(req, ENOENT); } else if (xinode->mode & S_IFDIR) { /* Can't open directories like this */ - log_debug("reading/writing a dir not allowed!"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "reading/writing a dir not allowed!"); fuse_reply_err(req, EISDIR); } else if ((fi->flags & O_ACCMODE) != O_RDONLY && (fi->flags & O_ACCMODE) != O_WRONLY && (fi->flags & O_ACCMODE) != O_RDWR) { - log_debug("Invalid access mode specified"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "Invalid access mode specified"); fuse_reply_err(req, EINVAL); } - else if (xinode->device_id == 0) + else if (!xinode->is_redirected) { /* specified file is a local resource */ - XFUSE_HANDLE *fh = g_new0(XFUSE_HANDLE, 1); - fh->is_loc_resource = 1; - fi->fh = (tintptr) fh; - fuse_reply_open(req, fi); + if ((fi->flags & O_ACCMODE) != O_RDONLY) + { + fuse_reply_err(req, EROFS); + } + else + { + XFUSE_HANDLE *fh = xfuse_handle_create(); + fh->is_loc_resource = 1; + fi->fh = xfuse_handle_to_fuse_handle(fh); + fuse_reply_open(req, fi); + } } else { @@ -1962,10 +2052,10 @@ if (!full_path || !fip) { - log_error("system out of memory"); - fuse_reply_err(req, ENOMEM); - free(fip); - free(full_path); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); + fuse_reply_err(req, ENOMEM); + free(fip); + free(full_path); } else { @@ -1989,7 +2079,7 @@ */ if (devredir_file_open(fip, xinode->device_id, cptr, fi->flags)) { - log_error("failed to send devredir_file_open() cmd"); + LOG_DEVEL(LOG_LEVEL_ERROR, "failed to send devredir_file_open() cmd"); fuse_reply_err(req, EREMOTEIO); free(fip); } @@ -2008,17 +2098,17 @@ { XFS_INODE *xinode; - XFUSE_HANDLE *handle = (XFUSE_HANDLE *) (tintptr) (fi->fh); + XFUSE_HANDLE *handle = xfuse_handle_from_fuse_handle(fi->fh); - log_debug("entered: ino=%ld fi=%p fi->fh=0x%llx", ino, fi, + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: ino=%ld fi=%p fi->fh=0x%llx", ino, fi, (long long) fi->fh); if ((xinode = xfs_get(g_xfs, ino)) == NULL) { - log_error("inode %ld is not valid", ino); + LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is not valid", ino); fuse_reply_err(req, ENOENT); } - else if (xinode->device_id == 0) + else if (!xinode->is_redirected) { /* specified file is a local resource */ fuse_reply_err(req, 0); @@ -2030,7 +2120,7 @@ struct state_close *fip = g_new0(struct state_close, 1); if (fip == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); fuse_reply_err(req, ENOMEM); return; } @@ -2039,7 +2129,7 @@ fip->inum = ino; fip->fi = *fi; - fi->fh = 0; + fi->fh = xfuse_handle_to_fuse_handle(NULL); /* * If this call succeeds, further request processing happens in @@ -2047,12 +2137,12 @@ */ if (devredir_file_close(fip, xinode->device_id, handle->FileId)) { - log_error("failed to send devredir_close_file() cmd"); + LOG_DEVEL(LOG_LEVEL_ERROR, "failed to send devredir_close_file() cmd"); fuse_reply_err(req, EREMOTEIO); free(fip); } - free(handle); + xfuse_handle_delete(handle); } } @@ -2070,9 +2160,9 @@ XFS_INODE *xinode; struct req_list_item *rli; - log_debug("want_bytes %zd bytes at off %lld", size, (long long) off); + LOG_DEVEL(LOG_LEVEL_DEBUG, "want_bytes %zd bytes at off %lld", size, (long long) off); - if ((fh = (XFUSE_HANDLE *)fi->fh) == NULL) + if ((fh = xfuse_handle_from_fuse_handle(fi->fh)) == NULL) { fuse_reply_err(req, EINVAL); } @@ -2080,11 +2170,11 @@ { /* target file is in .clipboard dir */ - log_debug("target file is in .clipboard dir"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "target file is in .clipboard dir"); if ((xinode = xfs_get(g_xfs, ino)) == NULL) { - log_error("ino does not exist in xrdp_fs"); + LOG_DEVEL(LOG_LEVEL_ERROR, "ino does not exist in xrdp_fs"); fuse_reply_buf(req, 0, 0); return; } @@ -2100,7 +2190,7 @@ if (g_req_list->count == 1) { - log_debug("requesting clipboard file data lindex = %d off = %lld size = %zd", + LOG_DEVEL(LOG_LEVEL_DEBUG, "requesting clipboard file data lindex = %d off = %lld size = %zd", rli->lindex, (long long) off, size); clipboard_request_file_data(rli->stream_id, rli->lindex, @@ -2114,7 +2204,7 @@ fusep = g_new0(struct state_read, 1); if (fusep == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); fuse_reply_err(req, ENOMEM); } else @@ -2142,19 +2232,19 @@ XFUSE_HANDLE *fh; struct state_write *fusep; - log_debug("write %zd bytes at off %lld to inode=%ld", + LOG_DEVEL(LOG_LEVEL_DEBUG, "write %zd bytes at off %lld to inode=%ld", size, (long long) off, ino); - if ((fh = (XFUSE_HANDLE *)fi->fh) == NULL) + if ((fh = xfuse_handle_from_fuse_handle(fi->fh)) == NULL) { - log_error("file handle fi->fh is NULL"); + LOG_DEVEL(LOG_LEVEL_ERROR, "file handle fi->fh is NULL"); fuse_reply_err(req, EINVAL); } else if (fh->is_loc_resource) { /* target file is in .clipboard dir */ - log_debug("THIS IS STILL A TODO!"); - fuse_reply_err(req, EINVAL); + LOG_DEVEL(LOG_LEVEL_DEBUG, "THIS IS STILL A TODO!"); + fuse_reply_err(req, EROFS); } else { @@ -2163,7 +2253,7 @@ fusep = g_new0(struct state_write, 1); if (fusep == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); fuse_reply_err(req, ENOMEM); } else @@ -2193,10 +2283,10 @@ const char *name, mode_t mode, struct fuse_file_info *fi) { - log_debug("entered: parent_inode=%ld, name=%s fi=%p", + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: parent_inode=%ld, name=%s fi=%p", parent, name, fi); - xfuse_create_dir_or_file(req, parent, name, mode & ~S_IFDIR , fi); + xfuse_create_dir_or_file(req, parent, name, mode & ~S_IFDIR, fi); } /** @@ -2206,8 +2296,8 @@ static void xfuse_cb_fsync(fuse_req_t req, fuse_ino_t ino, int datasync, struct fuse_file_info *fi) { - log_debug("#################### entered: ino=%ld datasync=%d", ino, datasync); - log_debug("function not required"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "#################### entered: ino=%ld datasync=%d", ino, datasync); + LOG_DEVEL(LOG_LEVEL_DEBUG, "function not required"); fuse_reply_err(req, EINVAL); } #endif @@ -2230,11 +2320,11 @@ { XFS_INODE *xinode; - log_debug("entered to_set=0x%x", to_set); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered to_set=0x%x", to_set); if ((xinode = xfs_get(g_xfs, ino)) == NULL) { - log_error("inode %ld is not valid", ino); + LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is not valid", ino); fuse_reply_err(req, ENOENT); } else if (((to_set & FUSE_SET_ATTR_UID) && attr->st_uid != xinode->uid) || @@ -2244,13 +2334,13 @@ fuse_reply_err(req, EPERM); } else if ((to_set & FUSE_SET_ATTR_MODE) && - (attr->st_mode & ~(0777 | S_IFDIR | S_IFREG)) != 0) + (attr->st_mode & ~(0777 | S_IFDIR | S_IFREG)) != 0) { /* We only support standard mode bits and S_IFDIR / S_IFREG */ - log_error("Asking for invalid mode bits 0%o to be set", attr->st_mode); + LOG_DEVEL(LOG_LEVEL_ERROR, "Asking for invalid mode bits 0%o to be set", attr->st_mode); fuse_reply_err(req, EINVAL); } - else + else { struct file_attr attrs = {0}; tui32 change_mask = 0; @@ -2284,7 +2374,7 @@ /* No changes have been made */ make_fuse_attr_reply(req, xinode); } - else if (xinode->device_id == 0) + else if (!xinode->is_redirected) { /* Update the local fs */ update_inode_file_attributes(&attrs, change_mask, xinode); @@ -2296,7 +2386,7 @@ char *full_path = xfs_get_full_path(g_xfs, ino); if (!full_path || !fip) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); fuse_reply_err(req, ENOMEM); free(fip); free(full_path); @@ -2339,31 +2429,41 @@ * to reply to FUSE immediately *****************************************************************************/ static void xfuse_cb_opendir(fuse_req_t req, fuse_ino_t ino, - struct fuse_file_info *fi) + struct fuse_file_info *fi) { XFS_INODE *xinode; + XFUSE_HANDLE *xhandle; - log_debug("inode=%ld", ino); + LOG_DEVEL(LOG_LEVEL_DEBUG, "inode=%ld", ino); if ((xinode = xfs_get(g_xfs, ino)) == NULL) { - log_error("inode %ld is not valid", ino); + LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is not valid", ino); fuse_reply_err(req, ENOENT); } - else if (xinode->device_id == 0) + else if (!xinode->is_redirected) { - if ((fi->fh = (tintptr) xfs_opendir(g_xfs, ino)) == 0) + if ((xhandle = xfuse_handle_create()) == NULL) { fuse_reply_err(req, ENOMEM); } else { - fuse_reply_open(req, fi); + if ((xhandle->dir_handle = xfs_opendir(g_xfs, ino)) == NULL) + { + xfuse_handle_delete(xhandle); + fuse_reply_err(req, ENOMEM); + } + else + { + fi->fh = xfuse_handle_to_fuse_handle(xhandle); + fuse_reply_open(req, fi); + } } } else { - log_debug("did not find entry; redirecting call to devredir"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "did not find entry; redirecting call to devredir"); struct state_dirscan *fip = g_new0(struct state_dirscan, 1); char *full_path = xfs_get_full_path(g_xfs, ino); @@ -2376,7 +2476,7 @@ else { const char *cptr; - log_debug("dev_id=%d ino=%ld full_path=%s", + LOG_DEVEL(LOG_LEVEL_DEBUG, "dev_id=%d ino=%ld full_path=%s", xinode->device_id, ino, full_path); fip->req = req; @@ -2395,7 +2495,7 @@ */ if (devredir_get_dir_listing(fip, xinode->device_id, cptr)) { - log_error("failed to send devredir_get_dir_listing() cmd"); + LOG_DEVEL(LOG_LEVEL_ERROR, "failed to send devredir_get_dir_listing() cmd"); fuse_reply_buf(req, NULL, 0); free(fip); } @@ -2413,8 +2513,10 @@ static void xfuse_cb_releasedir(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) { - struct xfs_dir_handle *dh = (struct xfs_dir_handle *) fi->fh; - xfs_closedir(g_xfs, dh); + XFUSE_HANDLE *xhandle = xfuse_handle_from_fuse_handle(fi->fh); + xfs_closedir(g_xfs, xhandle->dir_handle); + xhandle->dir_handle = NULL; + xfuse_handle_delete(xhandle); fuse_reply_err(req, 0); } @@ -2423,14 +2525,14 @@ *****************************************************************************/ static void xfs_inode_to_fuse_entry_param(const XFS_INODE *xinode, - struct fuse_entry_param *e) + struct fuse_entry_param *e) { memset(e, 0, sizeof(*e)); e->ino = xinode->inum; e->attr_timeout = XFUSE_ATTR_TIMEOUT; e->entry_timeout = XFUSE_ENTRY_TIMEOUT; e->attr.st_ino = xinode->inum; - e->attr.st_mode = xinode->mode & ~g_umask; + e->attr.st_mode = xinode->mode & ~g_cfg->file_umask; e->attr.st_nlink = 1; e->attr.st_uid = xinode->uid; e->attr.st_gid = xinode->gid; @@ -2454,7 +2556,7 @@ memset(&st, 0, sizeof(st)); st.st_ino = xinode->inum; - st.st_mode = xinode->mode & ~g_umask; + st.st_mode = xinode->mode & ~g_cfg->file_umask; st.st_nlink = 1; st.st_uid = xinode->uid; st.st_gid = xinode->gid; @@ -2491,7 +2593,7 @@ * setattr devredir call */ static void update_inode_file_attributes(const struct file_attr *fattr, - tui32 change_mask, XFS_INODE *xinode) + tui32 change_mask, XFS_INODE *xinode) { int updated = 0; @@ -2534,10 +2636,12 @@ if ((result = xfs_get_full_path(g_xfs, parent)) != NULL) { - char * p = (char *) realloc(result, - strlen(result) + 1 + strlen(name) + 1); + char *p = (char *) realloc(result, + strlen(result) + 1 + strlen(name) + 1); if (p == NULL) { + /* See cppcheck trac #9292 and #9437 */ + /* cppcheck-suppress doubleFree symbolName=result */ free(result); result = NULL; } @@ -2552,4 +2656,30 @@ return result; } +/* + * Scans a user-provided string substituting %u/%U for UID/username + */ +static unsigned int format_user_info(char *dest, unsigned int len, + const char *format) +{ + char uidstr[64]; + char username[64]; + const struct info_string_tag map[] = + { + {'u', uidstr}, + {'U', username}, + INFO_STRING_END_OF_LIST + }; + + int uid = g_getuid(); + g_snprintf(uidstr, sizeof(uidstr), "%d", uid); + if (g_getlogin(username, sizeof(username)) != 0) + { + /* Fall back to UID */ + g_strncpy(username, uidstr, sizeof(username) - 1); + } + + return g_format_info_string(dest, len, format, map); +} + #endif /* end else #ifndef XRDP_FUSE */ diff -Nru xrdp-0.9.12/sesman/chansrv/chansrv_fuse.h xrdp-0.9.15/sesman/chansrv/chansrv_fuse.h --- xrdp-0.9.12/sesman/chansrv/chansrv_fuse.h 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/chansrv_fuse.h 2020-12-28 13:47:13.000000000 +0000 @@ -98,6 +98,7 @@ tui32 DeviceId, tui32 FileId); void xfuse_devredir_cb_read_file(struct state_read *fip, + enum NTSTATUS IoStatus, const char *buf, size_t length); void xfuse_devredir_cb_write_file( struct state_write *fip, diff -Nru xrdp-0.9.12/sesman/chansrv/chansrv.h xrdp-0.9.15/sesman/chansrv/chansrv.h --- xrdp-0.9.12/sesman/chansrv/chansrv.h 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/chansrv.h 2020-12-28 14:03:43.000000000 +0000 @@ -39,19 +39,6 @@ int main_cleanup(void); int add_timeout(int msoffset, void (*callback)(void* data), void* data); -#define LOG_LEVEL 5 - -#define LOG(_a, _params) \ - { \ - if (_a < LOG_LEVEL) \ - { \ - g_write("xrdp-chansrv [%10.10u]: ", g_time3()); \ - g_writeln _params ; \ - } \ - } - -#define LOGM(_args) do { log_message _args ; } while (0) - #ifndef GSET_UINT8 #define GSET_UINT8(_ptr, _offset, _data) \ *((unsigned char*) (((unsigned char*)(_ptr)) + (_offset))) = (unsigned char)(_data) diff -Nru xrdp-0.9.12/sesman/chansrv/chansrv_xfs.c xrdp-0.9.15/sesman/chansrv/chansrv_xfs.c --- xrdp-0.9.12/sesman/chansrv/chansrv_xfs.c 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/chansrv_xfs.c 2020-12-28 14:03:43.000000000 +0000 @@ -27,6 +27,7 @@ #endif #include "os_calls.h" +#include "log.h" #include "chansrv_xfs.h" @@ -113,47 +114,6 @@ tui32 generation; }; -/* module based logging */ -#define LOG_ERROR 0 -#define LOG_INFO 1 -#define LOG_DEBUG 2 -#ifndef LOG_LEVEL -#define LOG_LEVEL LOG_ERROR -#endif - -#define log_error(_params...) \ - { \ - g_write("[%10.10u]: XFS %s: %d : ERROR: ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ - } - -#define log_always(_params...) \ - { \ - g_write("[%10.10u]: XFS %s: %d : ALWAYS: ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ - } - -#define log_info(_params...) \ - { \ - if (LOG_INFO <= LOG_LEVEL) \ - { \ - g_write("[%10.10u]: XFS %s: %d : ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ - } \ - } - -#define log_debug(_params...) \ - { \ - if (LOG_DEBUG <= LOG_LEVEL) \ - { \ - g_write("[%10.10u]: XFS %s: %d : ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ - } \ - } /* ------------------------------------------------------------------------ */ static int @@ -344,6 +304,7 @@ xino1->pub.ctime = xino1->pub.atime; strcpy(xino1->pub.name, "."); xino1->pub.generation = xfs->generation; + xino1->pub.is_redirected = 0; xino1->pub.device_id = 0; /* @@ -365,6 +326,7 @@ xino2->pub.ctime = xino2->pub.atime; strcpy(xino2->pub.name, ".delete-pending"); xino2->pub.generation = xfs->generation; + xino2->pub.is_redirected = 0; xino2->pub.device_id = 0; xino2->parent = NULL; @@ -387,7 +349,12 @@ void xfs_delete_xfs_fs(struct xfs_fs *xfs) { - if (xfs != NULL && xfs->inode_table != NULL) + if (xfs == NULL) + { + return; + } + + if (xfs->inode_table != NULL) { size_t i; for (i = 0 ; i < xfs->inode_count; ++i) @@ -443,7 +410,7 @@ fuse_ino_t inum = xfs->free_list[--xfs->free_count]; if (xfs->inode_table[inum] != NULL) { - log_error("Unexpected non-NULL value in inode table " + LOG_DEVEL(LOG_LEVEL_ERROR, "Unexpected non-NULL value in inode table " "entry %ld", inum); } xfs->inode_table[inum] = xino; @@ -464,6 +431,7 @@ xino->pub.ctime = xino->pub.atime; strcpy(xino->pub.name, name); xino->pub.generation = xfs->generation; + xino->pub.is_redirected = parent->pub.is_redirected; xino->pub.device_id = parent->pub.device_id; xino->pub.lindex = 0; @@ -560,7 +528,7 @@ */ size_t len = 0; XFS_INODE_ALL *p; - for (p = xino ; p->pub.inum != FUSE_ROOT_ID ; p = p->parent) + for (p = xino ; p && p->pub.inum != FUSE_ROOT_ID ; p = p->parent) { len += strlen(p->pub.name); ++len; /* Allow for '/' prefix */ @@ -573,7 +541,7 @@ char *end = result + len; *end = '\0'; - for (p = xino ; p->pub.inum != FUSE_ROOT_ID ; p = p->parent) + for (p = xino ; p && p->pub.inum != FUSE_ROOT_ID ; p = p->parent) { len = strlen(p->pub.name); end -= (len + 1); @@ -811,35 +779,35 @@ /* ------------------------------------------------------------------------ */ void -xfs_delete_entries_with_device_id(struct xfs_fs *xfs, tui32 device_id) +xfs_delete_redirected_entries_with_device_id(struct xfs_fs *xfs, + tui32 device_id) { fuse_ino_t inum; XFS_INODE_ALL *xino; - if (device_id != 0) + /* Using xfs_remove_entry() is convenient, but it recurses + * in to directories. To make sure all entries are removed, set the + * open_count of all affected files to 0 first + */ + for (inum = FUSE_ROOT_ID; inum < xfs->inode_count; ++inum) { - /* Using xfs_remove_entry() is convenient, but it recurses - * in to directories. To make sure all entries are removed, set the - * open_count of all affected files to 0 first - */ - for (inum = FUSE_ROOT_ID; inum < xfs->inode_count; ++inum) - { - if ((xino = xfs->inode_table[inum]) != NULL && - xino->pub.device_id == device_id && - (xino->pub.mode & S_IFREG) != 0) - { - xino->open_count = 0; - } + if ((xino = xfs->inode_table[inum]) != NULL && + xino->pub.is_redirected != 0 && + xino->pub.device_id == device_id && + (xino->pub.mode & S_IFREG) != 0) + { + xino->open_count = 0; } + } - /* Now we can be sure everything will be deleted correctly */ - for (inum = FUSE_ROOT_ID; inum < xfs->inode_count; ++inum) + /* Now we can be sure everything will be deleted correctly */ + for (inum = FUSE_ROOT_ID; inum < xfs->inode_count; ++inum) + { + if ((xino = xfs->inode_table[inum]) != NULL && + xino->pub.is_redirected != 0 && + xino->pub.device_id == device_id) { - if ((xino = xfs->inode_table[inum]) != NULL && - xino->pub.device_id == device_id) - { - xfs_remove_entry(xfs, xino->pub.inum); - } + xfs_remove_entry(xfs, xino->pub.inum); } } } diff -Nru xrdp-0.9.12/sesman/chansrv/chansrv_xfs.h xrdp-0.9.15/sesman/chansrv/chansrv_xfs.h --- xrdp-0.9.12/sesman/chansrv/chansrv_xfs.h 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/chansrv_xfs.h 2020-12-28 13:47:13.000000000 +0000 @@ -49,9 +49,8 @@ time_t ctime; /* Time of last status change. */ char name[XFS_MAXFILENAMELEN + 1]; /* Short name */ tui32 generation; /* Changes if inode is reused */ - tui32 device_id; /* for file system redirection - * Non-redirected devices are guaranteed - * to have a device_id or zero */ + char is_redirected; /* file is on redirected device */ + tui32 device_id; /* device ID of redirected device */ int lindex; /* used in clipboard operations */ } XFS_INODE; @@ -271,17 +270,15 @@ xfs_get_file_open_count(struct xfs_fs *xfs, fuse_ino_t inum); /* - * Deletes all entries with the matching device id + * Deletes all redirected entries with the matching device id * * Files are deleted even if they are open * - * The specified device_id must be non-zero so that the root - * filesystem is not deleted! - * * @param device_id Device ID */ void -xfs_delete_entries_with_device_id(struct xfs_fs *xfs, tui32 device_id); +xfs_delete_redirected_entries_with_device_id(struct xfs_fs *xfs, + tui32 device_id); /* * Check an entry move will be successful diff -Nru xrdp-0.9.12/sesman/chansrv/clipboard.c xrdp-0.9.15/sesman/chansrv/clipboard.c --- xrdp-0.9.12/sesman/chansrv/clipboard.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/clipboard.c 2020-12-28 14:03:43.000000000 +0000 @@ -169,54 +169,15 @@ #include "arch.h" #include "parse.h" #include "os_calls.h" +#include "string_calls.h" #include "chansrv.h" +#include "chansrv_config.h" #include "clipboard.h" #include "clipboard_file.h" #include "clipboard_common.h" #include "xcommon.h" #include "chansrv_fuse.h" -/* module based logging */ -#define LOG_ERROR 0 -#define LOG_INFO 1 -#define LOG_DEBUG 2 - -#undef LOG_LEVEL -#define LOG_LEVEL LOG_ERROR - -#define log_error(_params...) \ - { \ - g_write("[%10.10u]: CLIPBOARD %s: %d : ERROR: ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ - } - -#define log_always(_params...) \ - { \ - g_write("[%10.10u]: CLIPBOARD %s: %d : ALWAYS: ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ - } - -#define log_info(_params...) \ - { \ - if (LOG_INFO <= LOG_LEVEL) \ - { \ - g_write("[%10.10u]: CLIPBOARD %s: %d : ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ - } \ - } - -#define log_debug(_params...) \ - { \ - if (LOG_DEBUG <= LOG_LEVEL) \ - { \ - g_write("[%10.10u]: CLIPBOARD %s: %d : ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ - } \ - } static char g_bmp_image_header[] = { @@ -235,7 +196,7 @@ extern Screen *g_screen; /* in xcommon.c */ extern int g_screen_num; /* in xcommon.c */ -extern int g_restrict_outbound_clipboard; /* in chansrv.c */ +extern struct config_chansrv *g_cfg; /* in chansrv.c */ int g_clip_up = 0; @@ -371,7 +332,7 @@ int ver_min; Status st; - LOG(0, ("clipboard_init:")); + LOG_DEVEL(LOG_LEVEL_INFO, "clipboard_init:"); if (g_clip_up) { @@ -390,7 +351,7 @@ if (g_clipboard_atom == None) { - log_error("clipboard_init: XInternAtom failed"); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_init: XInternAtom failed"); rv = 3; } } @@ -399,18 +360,18 @@ { if (!XFixesQueryExtension(g_display, &g_xfixes_event_base, &dummy)) { - log_error("clipboard_init: no xfixes"); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_init: no xfixes"); rv = 5; } } if (rv == 0) { - log_debug("clipboard_init: g_xfixes_event_base %d", + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_init: g_xfixes_event_base %d", g_xfixes_event_base); st = XFixesQueryVersion(g_display, &ver_maj, &ver_min); - log_debug("clipboard_init st %d, maj %d min %d", st, - ver_maj, ver_min); + LOG(LOG_LEVEL_DEBUG, "clipboard_init st %d, maj %d min %d", st, + ver_maj, ver_min); g_clip_property_atom = XInternAtom(g_display, "XRDP_CLIP_PROPERTY_ATOM", False); g_get_time_atom = XInternAtom(g_display, "XRDP_GET_TIME_ATOM", @@ -429,7 +390,7 @@ if (g_image_bmp_atom == None) { - log_error("clipboard_init: g_image_bmp_atom was " + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_init: g_image_bmp_atom was " "not allocated"); } @@ -464,12 +425,12 @@ out_uint32_le(s, 0); /* extra 4 bytes ? */ s_mark_end(s); size = (int)(s->end - s->data); - log_debug("clipboard_init: data out, sending " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_init: data out, sending " "CB_CLIP_CAPS (clip_msg_id = 1)"); rv = send_channel_data(g_cliprdr_chan_id, s->data, size); if (rv != 0) { - log_error("clipboard_init: send_channel_data failed " + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_init: send_channel_data failed " "rv = %d", rv); rv = 4; } @@ -485,12 +446,12 @@ out_uint32_le(s, 0); /* extra 4 bytes ? */ s_mark_end(s); size = (int)(s->end - s->data); - log_debug("clipboard_init: data out, sending " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_init: data out, sending " "CB_MONITOR_READY (clip_msg_id = 1)"); rv = send_channel_data(g_cliprdr_chan_id, s->data, size); if (rv != 0) { - log_error("clipboard_init: send_channel_data failed " + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_init: send_channel_data failed " "rv = %d", rv); rv = 4; } @@ -505,7 +466,7 @@ } else { - log_error("xrdp-chansrv: clipboard_init: error on exit"); + LOG_DEVEL(LOG_LEVEL_ERROR, "xrdp-chansrv: clipboard_init: error on exit"); } return rv; @@ -515,7 +476,7 @@ int clipboard_deinit(void) { - LOG(0, ("clipboard_deinit:")); + LOG_DEVEL(LOG_LEVEL_INFO, "clipboard_deinit:"); if (g_wnd != 0) { XDestroyWindow(g_display, g_wnd); @@ -543,8 +504,8 @@ int size; int rv; - log_debug("clipboard_send_data_request:"); - log_debug("clipboard_send_data_request: %d", format_id); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_data_request:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_data_request: %d", format_id); g_clip_c2s.in_request = 1; make_stream(s); init_stream(s, 8192); @@ -555,7 +516,7 @@ out_uint32_le(s, 0); s_mark_end(s); size = (int)(s->end - s->data); - log_debug("clipboard_send_data_request: data out, sending " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_data_request: data out, sending " "CLIPRDR_DATA_REQUEST (clip_msg_id = 4)"); rv = send_channel_data(g_cliprdr_chan_id, s->data, size); free_stream(s); @@ -578,7 +539,7 @@ out_uint32_le(s, 0); /* extra 4 bytes */ s_mark_end(s); size = (int)(s->end - s->data); - log_debug("clipboard_send_format_ack: data out, sending " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_ack: data out, sending " "CLIPRDR_FORMAT_ACK (clip_msg_id = 3)"); rv = send_channel_data(g_cliprdr_chan_id, s->data, size); free_stream(s); @@ -670,7 +631,7 @@ int rv; char *holdp; - log_debug("clipboard_send_format_announce:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce:"); make_stream(s); init_stream(s, 8192); out_uint16_le(s, CB_FORMAT_LIST); /* 2 CLIPRDR_FORMAT_ANNOUNCE */ @@ -682,7 +643,7 @@ switch (xrdp_clip_type) { case XRDP_CB_FILE: - log_debug("clipboard_send_format_announce: XRDP_CB_FILE"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce: XRDP_CB_FILE"); /* canned response for "file" */ out_uint32_le(s, 0x0000c0bc); clipboard_out_unicode(s, "FileGroupDescriptorW", 21); @@ -692,7 +653,7 @@ clipboard_out_unicode(s, "DropEffect", 11); break; case XRDP_CB_BITMAP: - log_debug("clipboard_send_format_announce: XRDP_CB_BITMAP"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce: XRDP_CB_BITMAP"); /* canned response for "bitmap" */ out_uint32_le(s, 0x0000c004); clipboard_out_unicode(s, "Native", 7); @@ -704,7 +665,7 @@ clipboard_out_unicode(s, "", 1); break; case XRDP_CB_TEXT: - log_debug("clipboard_send_format_announce: XRDP_CB_TEXT"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce: XRDP_CB_TEXT"); /* canned response for "bitmap" */ out_uint32_le(s, 0x0000000d); clipboard_out_unicode(s, "", 1); @@ -716,7 +677,7 @@ clipboard_out_unicode(s, "", 1); break; default: - log_debug("clipboard_send_format_announce: unknown " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce: unknown " "xrdp_clip_type %d", xrdp_clip_type); break; } @@ -726,7 +687,7 @@ switch (xrdp_clip_type) { case XRDP_CB_FILE: - log_debug("clipboard_send_format_announce: XRDP_CB_FILE"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce: XRDP_CB_FILE"); /* canned response for "file" */ out_uint32_le(s, 0x0000c0bc); out_uint8p(s, windows_native_format, sizeof(windows_native_format)); @@ -736,7 +697,7 @@ out_uint8p(s, windows_native_format, sizeof(windows_native_format)); break; case XRDP_CB_BITMAP: - log_debug("clipboard_send_format_announce: XRDP_CB_BITMAP"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce: XRDP_CB_BITMAP"); /* canned response for "bitmap" */ out_uint32_le(s, 0x0000c004); out_uint8p(s, windows_native_format, sizeof(windows_native_format)); @@ -748,7 +709,7 @@ out_uint8p(s, windows_native_format, sizeof(windows_native_format)); break; case XRDP_CB_TEXT: - log_debug("clipboard_send_format_announce: XRDP_CB_TEXT"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce: XRDP_CB_TEXT"); /* canned response for "bitmap" */ out_uint32_le(s, 0x0000000d); out_uint8p(s, windows_native_format, sizeof(windows_native_format)); @@ -760,7 +721,7 @@ out_uint8p(s, windows_native_format, sizeof(windows_native_format)); break; default: - log_debug("clipboard_send_format_announce: unknown " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce: unknown " "xrdp_clip_type %d", xrdp_clip_type); break; } @@ -774,8 +735,8 @@ out_uint32_le(s, 0); s_mark_end(s); size = (int)(s->end - s->data); - //g_hexdump(s->data, size); - log_debug("clipboard_send_format_announce: data out, sending " + LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "clipboard data:", s->data, size); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce: data out, sending " "CLIPRDR_FORMAT_ANNOUNCE (clip_msg_id = 2)"); rv = send_channel_data(g_cliprdr_chan_id, s->data, size); free_stream(s); @@ -790,7 +751,7 @@ int size; int rv; - log_debug("clipboard_send_data_response_for_image: data_size %d", + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_data_response_for_image: data_size %d", data_size); make_stream(s); init_stream(s, 64 + data_size); @@ -815,17 +776,17 @@ int rv; int num_chars; - log_debug("clipboard_send_data_response_for_text: data_size %d", + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_data_response_for_text: data_size %d", data_size); - //g_hexdump(data, data_size); + LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "clipboard send data response:", data, data_size); num_chars = g_mbstowcs(0, data, 0); if (num_chars < 0) { - log_error("clipboard_send_data_response_for_text: " + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_data_response_for_text: " "bad string"); num_chars = 0; } - log_debug("clipboard_send_data_response_for_text: data_size %d " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_data_response_for_text: data_size %d " "num_chars %d", data_size, num_chars); make_stream(s); init_stream(s, 64 + num_chars * 2); @@ -834,14 +795,14 @@ out_uint32_le(s, num_chars * 2 + 2); /* length */ if (clipboard_out_unicode(s, data, num_chars) != num_chars * 2) { - log_error("clipboard_send_data_response_for_text: error " + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_data_response_for_text: error " "clipboard_out_unicode didn't write right number of bytes"); } out_uint16_le(s, 0); /* nil for string */ out_uint32_le(s, 0); s_mark_end(s); size = (int)(s->end - s->data); - log_debug("clipboard_send_data_response_for_text: data out, " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_data_response_for_text: data out, " "sending CLIPRDR_DATA_RESPONSE (clip_msg_id = 5) size %d " "num_chars %d", size, num_chars); rv = send_channel_data(g_cliprdr_chan_id, s->data, size); @@ -853,7 +814,7 @@ static int clipboard_send_data_response(int xrdp_clip_type, const char *data, int data_size) { - log_debug("clipboard_send_data_response:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_data_response:"); if (data != 0) { if (xrdp_clip_type == XRDP_CB_FILE) @@ -870,13 +831,13 @@ } else { - log_debug("clipboard_send_data_response: unknown " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_data_response: unknown " "xrdp_clip_type %d", xrdp_clip_type); } } else { - log_error("clipboard_send_data_response: data is nil"); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_data_response: data is nil"); } return 0; } @@ -887,7 +848,7 @@ { Window owner; - log_debug("clipboard_set_selection_owner:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_set_selection_owner:"); g_selection_time = clipboard_get_server_time(); XSetSelectionOwner(g_display, g_clipboard_atom, g_wnd, g_selection_time); owner = XGetSelectionOwner(g_display, g_clipboard_atom); @@ -909,7 +870,7 @@ XEvent xev; long val1[2]; - log_debug("clipboard_provide_selection_c2s: bytes %d", + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_provide_selection_c2s: bytes %d", g_clip_c2s.total_bytes); if (g_clip_c2s.total_bytes < g_incr_max_req_size) { @@ -935,7 +896,7 @@ g_clip_c2s.type = type; g_clip_c2s.property = req->property; g_clip_c2s.window = req->requestor; - log_debug("clipboard_provide_selection_c2s: start INCR property %s " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_provide_selection_c2s: start INCR property %s " "type %s", get_atom_text(req->property), get_atom_text(type)); val1[0] = g_clip_c2s.total_bytes; @@ -968,7 +929,7 @@ bytes = FORMAT_TO_BYTES(format); bytes *= length; - log_debug("clipboard_provide_selection: bytes %d", bytes); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_provide_selection: bytes %d", bytes); if (bytes < g_incr_max_req_size) { XChangeProperty(g_display, req->requestor, req->property, @@ -1021,9 +982,9 @@ char desc[256]; char *holdp; - log_debug("clipboard_process_format_announce: " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_format_announce: " "CLIPRDR_FORMAT_ANNOUNCE"); - log_debug("clipboard_process_format_announce %d", clip_msg_len); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_format_announce %d", clip_msg_len); clipboard_send_format_ack(); xfuse_clear_clip_dir(); @@ -1053,7 +1014,7 @@ desc[15] = 0; clip_msg_len -= 32; } - log_debug("clipboard_process_format_announce: formatId 0x%8.8x " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_format_announce: formatId 0x%8.8x " "wszFormatName [%s] clip_msg_len %d", formatId, desc, clip_msg_len); if (g_num_formatIds <= 15) @@ -1063,7 +1024,7 @@ } if (g_num_formatIds > 15) { - log_debug("clipboard_process_format_announce: max formats"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_format_announce: max formats"); } /* format id for file copy copy seems to keep changing */ @@ -1080,7 +1041,7 @@ { if (clipboard_set_selection_owner() != 0) { - log_error("clipboard_process_format_announce: " + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_process_format_announce: " "XSetSelectionOwner failed"); } } @@ -1095,8 +1056,8 @@ clipboard_process_format_ack(struct stream *s, int clip_msg_status, int clip_msg_len) { - log_debug("clipboard_process_format_ack: CLIPRDR_FORMAT_ACK"); - log_debug("clipboard_process_format_ack:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_format_ack: CLIPRDR_FORMAT_ACK"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_format_ack:"); return 0; } @@ -1108,7 +1069,7 @@ int size; int rv; - log_error("clipboard_send_data_response_failed:"); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_data_response_failed:"); make_stream(s); init_stream(s, 64); out_uint16_le(s, CB_FORMAT_DATA_RESPONSE); /* 5 CLIPRDR_DATA_RESPONSE */ @@ -1131,23 +1092,23 @@ { int requestedFormatId; - log_debug("clipboard_process_data_request: " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: " "CLIPRDR_DATA_REQUEST"); - log_debug("clipboard_process_data_request:"); - log_debug(" %d", g_clip_s2c.xrdp_clip_type); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, " %d", g_clip_s2c.xrdp_clip_type); in_uint32_le(s, requestedFormatId); switch (requestedFormatId) { case CB_FORMAT_FILE: /* 0xC0BC */ if ((g_clip_s2c.xrdp_clip_type == XRDP_CB_FILE) && g_clip_s2c.converted) { - log_debug("clipboard_process_data_request: CB_FORMAT_FILE"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: CB_FORMAT_FILE"); clipboard_send_data_response(XRDP_CB_FILE, g_clip_s2c.data, g_clip_s2c.total_bytes); } else { - log_debug("clipboard_process_data_request: CB_FORMAT_FILE, " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: CB_FORMAT_FILE, " "calling XConvertSelection to g_utf8_atom"); g_clip_s2c.xrdp_clip_type = XRDP_CB_FILE; XConvertSelection(g_display, g_clipboard_atom, g_clip_s2c.type, @@ -1157,13 +1118,13 @@ case CB_FORMAT_DIB: /* 0x0008 */ if ((g_clip_s2c.xrdp_clip_type == XRDP_CB_BITMAP) && g_clip_s2c.converted) { - log_debug("clipboard_process_data_request: CB_FORMAT_DIB"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: CB_FORMAT_DIB"); clipboard_send_data_response(XRDP_CB_BITMAP, g_clip_s2c.data, g_clip_s2c.total_bytes); } else { - log_debug("clipboard_process_data_request: CB_FORMAT_DIB, " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: CB_FORMAT_DIB, " "calling XConvertSelection to g_image_bmp_atom"); g_clip_s2c.xrdp_clip_type = XRDP_CB_BITMAP; XConvertSelection(g_display, g_clipboard_atom, g_image_bmp_atom, @@ -1173,13 +1134,13 @@ case CB_FORMAT_UNICODETEXT: /* 0x000D */ if ((g_clip_s2c.xrdp_clip_type == XRDP_CB_TEXT) && g_clip_s2c.converted) { - log_debug("clipboard_process_data_request: CB_FORMAT_UNICODETEXT"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: CB_FORMAT_UNICODETEXT"); clipboard_send_data_response(XRDP_CB_TEXT, g_clip_s2c.data, g_clip_s2c.total_bytes); } else { - log_debug("clipboard_process_data_request: CB_FORMAT_UNICODETEXT, " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: CB_FORMAT_UNICODETEXT, " "calling XConvertSelection to g_utf8_atom"); g_clip_s2c.xrdp_clip_type = XRDP_CB_TEXT; XConvertSelection(g_display, g_clipboard_atom, g_utf8_atom, @@ -1187,7 +1148,7 @@ } break; default: - log_debug("clipboard_process_data_request: unknown type %d", + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: unknown type %d", requestedFormatId); clipboard_send_data_response_failed(); break; @@ -1209,7 +1170,7 @@ XSelectionRequestEvent *lxev; int len; - log_debug("clipboard_process_data_response_for_image: " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_response_for_image: " "CLIPRDR_DATA_RESPONSE_FOR_IMAGE"); lxev = &g_saved_selection_req_event; len = (int)(s->end - s->p); @@ -1232,7 +1193,7 @@ g_clip_c2s.read_bytes_done = g_clip_c2s.total_bytes; g_memcpy(g_clip_c2s.data, g_bmp_image_header, 14); in_uint8a(s, g_clip_c2s.data + 14, len); - log_debug("clipboard_process_data_response_for_image: calling " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_response_for_image: calling " "clipboard_provide_selection_c2s"); clipboard_provide_selection_c2s(lxev, lxev->target); return 0; @@ -1255,7 +1216,7 @@ int len; int index; - log_debug("clipboard_process_data_response:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_response:"); lxev = &g_saved_selection_req_event; g_clip_c2s.in_request = 0; if (g_clip_c2s.xrdp_clip_type == XRDP_CB_BITMAP) @@ -1281,14 +1242,14 @@ } else { - log_error("clipboard_process_data_response: error"); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_process_data_response: error"); } g_clip_c2s.total_bytes = g_strlen(g_clip_c2s.data); g_clip_c2s.read_bytes_done = g_clip_c2s.total_bytes; clipboard_provide_selection_c2s(lxev, lxev->target); return 0; } - log_debug("clipboard_process_data_response: " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_response: " "CLIPRDR_DATA_RESPONSE"); len = (int)(s->end - s->p); if (len < 1) @@ -1349,8 +1310,8 @@ int flags; char *holdp; - log_debug("clipboard_process_clip_caps:"); - //g_hexdump(s->p, s->end - s->p); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_clip_caps:"); + //LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", s->p, s->end - s->p); in_uint16_le(s, cCapabilitiesSets); in_uint8s(s, 2); /* pad */ for (index = 0; index < cCapabilitiesSets; index++) @@ -1363,7 +1324,7 @@ case CB_CAPSTYPE_GENERAL: in_uint32_le(s, version); /* version */ in_uint32_le(s, flags); /* generalFlags */ - log_debug("clipboard_process_clip_caps: " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_clip_caps: " "g_cliprdr_version %d version %d " "g_cliprdr_flags 0x%x flags 0x%x", g_cliprdr_version, version, @@ -1375,7 +1336,7 @@ g_cliprdr_flags &= flags; break; default: - log_debug("clipboard_process_clip_caps: unknown " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_clip_caps: unknown " "capabilitySetType %d", capabilitySetType); break; } @@ -1391,7 +1352,7 @@ int index; char *text; - log_debug("ss_part: data_bytes %d read_bytes_done %d " + LOG_DEVEL(LOG_LEVEL_DEBUG, "ss_part: data_bytes %d read_bytes_done %d " "incr_bytes_done %d", data_bytes, g_clip_c2s.read_bytes_done, g_clip_c2s.incr_bytes_done); @@ -1419,12 +1380,12 @@ } if (g_clip_c2s.incr_in_progress) { - log_debug("ss_part: incr_in_progress set"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "ss_part: incr_in_progress set"); return 0; } if (g_clip_c2s.read_bytes_done <= g_clip_c2s.incr_bytes_done) { - log_debug("ss_part: read_bytes_done < incr_bytes_done"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "ss_part: read_bytes_done < incr_bytes_done"); return 0; } data = g_clip_c2s.data + g_clip_c2s.incr_bytes_done; @@ -1448,18 +1409,18 @@ char *data; int data_bytes; - log_debug("ss_end:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "ss_end:"); g_clip_c2s.doing_response_ss = 0; g_clip_c2s.in_request = 0; if (g_clip_c2s.incr_in_progress) { - log_debug("ss_end: incr_in_progress set"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "ss_end: incr_in_progress set"); return 0; } if (g_clip_c2s.read_bytes_done <= g_clip_c2s.incr_bytes_done) { - log_debug("ss_end: read_bytes_done < incr_bytes_done"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "ss_end: read_bytes_done < incr_bytes_done"); return 0; } data = g_clip_c2s.data + g_clip_c2s.incr_bytes_done; @@ -1485,7 +1446,7 @@ long val1[2]; int incr_bytes; - log_debug("ss_start: data_bytes %d total_bytes %d", + LOG_DEVEL(LOG_LEVEL_DEBUG, "ss_start: data_bytes %d total_bytes %d", data_bytes, total_bytes); req = &g_saved_selection_req_event; @@ -1553,13 +1514,13 @@ if (!g_clip_up) { - log_error("aborting clipboard_data_in - clipboard has not " + LOG_DEVEL(LOG_LEVEL_ERROR, "aborting clipboard_data_in - clipboard has not " "been initialized"); /* we return 0 here to indicate no protocol problem occurred */ return 0; } - log_debug("clipboard_data_in: chan_id %d " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_data_in: chan_id %d " "chan_flags 0x%x length %d total_length %d " "in_request %d g_ins->size %d", chan_id, chan_flags, length, total_length, @@ -1570,7 +1531,7 @@ ss_part(s->p, length); if ((chan_flags & 3) == 2) { - log_debug("clipboard_data_in: calling ss_end"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_data_in: calling ss_end"); ss_end(); } return 0; @@ -1622,12 +1583,12 @@ in_uint16_le(ls, clip_msg_status); in_uint32_le(ls, clip_msg_len); - log_debug("clipboard_data_in: clip_msg_id %d " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_data_in: clip_msg_id %d " "clip_msg_status %d clip_msg_len %d", clip_msg_id, clip_msg_status, clip_msg_len); rv = 0; - log_debug("clipboard_data_in: %d", clip_msg_id); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_data_in: %d", clip_msg_id); switch (clip_msg_id) { /* sent by client or server when its local system clipboard is */ @@ -1671,9 +1632,7 @@ clip_msg_len); break; default: - log_debug("clipboard_data_in: unknown clip_msg_id %d", clip_msg_id); - log_error("clipboard_data_in: unknown clip_msg_id %d", - clip_msg_id); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_data_in: unknown clip_msg_id %d", clip_msg_id); break; } @@ -1703,15 +1662,15 @@ XFixesSelectionNotifyEvent *lxevent; lxevent = (XFixesSelectionNotifyEvent *)xevent; - log_debug("clipboard_event_selection_owner_notify: 0x%lx", lxevent->owner); - log_debug("clipboard_event_selection_owner_notify: " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_owner_notify: 0x%lx", lxevent->owner); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_owner_notify: " "window %ld subtype %d owner %ld g_wnd %ld", lxevent->window, lxevent->subtype, lxevent->owner, g_wnd); if (lxevent->owner == g_wnd) { - log_debug("clipboard_event_selection_owner_notify: matches g_wnd"); - log_debug("clipboard_event_selection_owner_notify: skipping, " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_owner_notify: matches g_wnd"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_owner_notify: skipping, " "owner == g_wnd"); g_got_selection = 1; return 0; @@ -1741,8 +1700,8 @@ tui8 *lxdata; Atom ltype; - log_debug("clipboard_get_window_property:"); - log_debug(" prop %ld name %s", prop, get_atom_text(prop)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_get_window_property:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, " prop %ld name %s", prop, get_atom_text(prop)); lxdata = 0; ltype = 0; XGetWindowProperty(g_display, wnd, prop, 0, 0, 0, @@ -1857,7 +1816,7 @@ Atom *atoms; Atom type; - log_debug("clipboard_event_selection_notify:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_notify:"); data_size = 0; n_items = 0; fmt = 0; @@ -1873,14 +1832,14 @@ if (lxevent->property == None) { - log_error("clipboard_event_selection_notify: clip could " + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_event_selection_notify: clip could " "not be converted"); rv = 1; } if (rv == 0) { - log_debug("clipboard_event_selection_notify: wnd 0x%lx prop %s", + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: wnd 0x%lx prop %s", lxevent->requestor, get_atom_text(lxevent->property)); rv = clipboard_get_window_property(lxevent->requestor, lxevent->property, @@ -1888,17 +1847,17 @@ &n_items, &data, &data_size); if (rv != 0) { - log_error("clipboard_event_selection_notify: " + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_event_selection_notify: " "clipboard_get_window_property failed error %d", rv); return 0; } - //g_hexdump(data, data_size); + //LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", data, data_size); XDeleteProperty(g_display, lxevent->requestor, lxevent->property); if (type == g_incr_atom) { /* nothing more to do here, the data is coming in through PropertyNotify */ - log_debug("clipboard_event_selection_notify: type is INCR " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: type is INCR " "data_size %d property name %s type %s", data_size, get_atom_text(lxevent->property), get_atom_text(lxevent->type)); @@ -1908,7 +1867,7 @@ g_clip_s2c.total_bytes = 0; g_free(g_clip_s2c.data); g_clip_s2c.data = 0; - //g_hexdump(data, sizeof(long)); + //LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", data, sizeof(long)); g_free(data); return 0; } @@ -1927,10 +1886,10 @@ for (index = 0; index < n_items; index++) { atom = atoms[index]; - LOGM((LOG_LEVEL_DEBUG, - "clipboard_event_selection_notify: 0x%lx %s 0x%lx", - atom, get_atom_text(atom), XA_STRING)); - log_debug("clipboard_event_selection_notify: 0x%lx %s", + LOG_DEVEL(LOG_LEVEL_DEBUG, + "clipboard_event_selection_notify: 0x%lx %s 0x%lx", + atom, get_atom_text(atom), XA_STRING); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: 0x%lx %s", atom, get_atom_text(atom)); if (atom == g_utf8_atom) { @@ -1946,27 +1905,25 @@ } else if ((atom == g_file_atom1) || (atom == g_file_atom2)) { - log_debug("clipboard_event_selection_notify: file"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: file"); got_file_atom = atom; } else { - log_error("clipboard_event_selection_notify: unknown atom 0x%lx", atom); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_event_selection_notify: unknown atom 0x%lx", atom); } } } else { - log_error("clipboard_event_selection_notify: error, " + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_event_selection_notify: error, " "target is 'TARGETS' and type[%ld] or fmt[%d] not right, " "should be type[%ld], fmt[%d]", type, fmt, XA_ATOM, 32); } } else if (lxevent->target == g_utf8_atom) { - log_debug("clipboard_event_selection_notify: UTF8_STRING " - "data_size %d", data_size); - log_debug("clipboard_event_selection_notify: UTF8_STRING " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: UTF8_STRING " "data_size %d", data_size); if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0)) { @@ -1989,9 +1946,7 @@ } else if (lxevent->target == XA_STRING) { - log_debug("clipboard_event_selection_notify: XA_STRING " - "data_size %d", data_size); - log_debug("clipboard_event_selection_notify: XA_STRING " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: XA_STRING " "data_size %d", data_size); if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0)) { @@ -2006,9 +1961,7 @@ } else if (lxevent->target == g_image_bmp_atom) { - log_debug("clipboard_event_selection_notify: image/bmp " - "data_size %d", data_size); - log_debug("clipboard_event_selection_notify: image/bmp " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: image/bmp " "data_size %d", data_size); if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 14)) { @@ -2022,9 +1975,7 @@ } else if (lxevent->target == g_file_atom1) { - log_debug("clipboard_event_selection_notify: text/uri-list " - "data_size %d", data_size); - log_debug("clipboard_event_selection_notify: text/uri-list " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: text/uri-list " "data_size %d", data_size); if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0)) { @@ -2039,9 +1990,7 @@ } else if (lxevent->target == g_file_atom2) { - log_debug("clipboard_event_selection_notify: text/uri-list " - "data_size %d", data_size); - log_debug("clipboard_event_selection_notify: text/uri-list " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: text/uri-list " "data_size %d", data_size); if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0)) { @@ -2056,13 +2005,13 @@ } else { - log_error("clipboard_event_selection_notify: " + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_event_selection_notify: " "unknown target"); } } else { - log_error("clipboard_event_selection_notify: " + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_event_selection_notify: " "unknown selection"); } } @@ -2146,8 +2095,8 @@ char *xdata; lxev = (XSelectionRequestEvent *)xevent; - log_debug("clipboard_event_selection_request: 0x%lx", lxev->property); - log_debug("clipboard_event_selection_request: g_wnd %ld, " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: 0x%lx", lxev->property); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_wnd %ld, " ".requestor %ld .owner %ld .selection %ld '%s' .target %ld .property %ld", g_wnd, lxev->requestor, lxev->owner, lxev->selection, get_atom_text(lxev->selection), @@ -2155,16 +2104,14 @@ if (lxev->property == None) { - log_debug("clipboard_event_selection_request: lxev->property " - "is None"); - log_debug("clipboard_event_selection_request: " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " "lxev->property is None"); } else if (lxev->target == g_targets_atom) { - log_debug("clipboard_event_selection_request: g_targets_atom"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_targets_atom"); /* requestor is asking what the selection can be converted to */ - log_debug("clipboard_event_selection_request: " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " "g_targets_atom"); atom_buf[0] = g_targets_atom; atom_buf[1] = g_timestamp_atom; @@ -2174,28 +2121,28 @@ atom_count = 5; if (clipboard_find_format_id(CB_FORMAT_DIB) >= 0) { - log_debug(" reporting image/bmp"); + LOG_DEVEL(LOG_LEVEL_DEBUG, " reporting image/bmp"); atom_buf[atom_count] = g_image_bmp_atom; atom_count++; } if (clipboard_find_format_id(g_file_format_id) >= 0) { - log_debug(" reporting text/uri-list"); + LOG_DEVEL(LOG_LEVEL_DEBUG, " reporting text/uri-list"); atom_buf[atom_count] = g_file_atom1; atom_count++; - log_debug(" reporting x-special/gnome-copied-files"); + LOG_DEVEL(LOG_LEVEL_DEBUG, " reporting x-special/gnome-copied-files"); atom_buf[atom_count] = g_file_atom2; atom_count++; } atom_buf[atom_count] = 0; - log_debug(" reporting %d formats", atom_count); + LOG_DEVEL(LOG_LEVEL_DEBUG, " reporting %d formats", atom_count); return clipboard_provide_selection(lxev, XA_ATOM, 32, (char *)atom_buf, atom_count); } else if (lxev->target == g_timestamp_atom) { /* requestor is asking the time I got the selection */ - log_debug("clipboard_event_selection_request: " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " "g_timestamp_atom"); atom_buf[0] = g_selection_time; atom_buf[1] = 0; @@ -2205,7 +2152,7 @@ else if (lxev->target == g_multiple_atom) { /* target, property pairs */ - log_debug("clipboard_event_selection_request: " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: " "g_multiple_atom"); xdata = 0; @@ -2213,7 +2160,7 @@ &type, &fmt, &n_items, &xdata, &xdata_size) == 0) { - log_debug("clipboard_event_selection_request: g_multiple_atom " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_multiple_atom " "n_items %d", n_items); /* todo */ g_free(xdata); @@ -2230,10 +2177,10 @@ } else if (lxev->target == g_image_bmp_atom) { - log_debug("clipboard_event_selection_request: image/bmp"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: image/bmp"); if ((g_clip_c2s.type == lxev->target) && g_clip_c2s.converted) { - log_debug("clipboard_event_selection_request: -------------------------------------------"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: -------------------------------------------"); clipboard_provide_selection_c2s(lxev, lxev->target); return 0; } @@ -2246,10 +2193,10 @@ } else if (lxev->target == g_file_atom1) { - log_debug("clipboard_event_selection_request: g_file_atom1"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_file_atom1"); if ((g_clip_c2s.type == lxev->target) && g_clip_c2s.converted) { - log_debug("clipboard_event_selection_request: -------------------------------------------"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: -------------------------------------------"); clipboard_provide_selection_c2s(lxev, lxev->target); return 0; } @@ -2262,10 +2209,10 @@ } else if (lxev->target == g_file_atom2) { - log_debug("clipboard_event_selection_request: g_file_atom2"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_file_atom2"); if ((g_clip_c2s.type == lxev->target) && g_clip_c2s.converted) { - log_debug("clipboard_event_selection_request: -------------------------------------------"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: -------------------------------------------"); clipboard_provide_selection_c2s(lxev, lxev->target); return 0; } @@ -2278,10 +2225,8 @@ } else { - log_debug("clipboard_event_selection_request: unknown " - "target %s", get_atom_text(lxev->target)); - LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_request: unknown " - "target %s", get_atom_text(lxev->target))); + LOG(LOG_LEVEL_ERROR, "clipboard_event_selection_request: unknown " + "target %s", get_atom_text(lxev->target)); } clipboard_refuse_selection(lxev); @@ -2303,7 +2248,7 @@ static int clipboard_event_selection_clear(XEvent *xevent) { - log_debug("clipboard_event_selection_clear:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_clear:"); return 0; } @@ -2333,8 +2278,7 @@ int data_bytes; char *cptr; - log_debug("clipboard_event_property_notify:"); - log_debug("clipboard_event_property_notify: PropertyNotify .window %ld " + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_property_notify: PropertyNotify .window %ld " ".state %d .atom %ld %s", xevent->xproperty.window, xevent->xproperty.state, xevent->xproperty.atom, get_atom_text(xevent->xproperty.atom)); @@ -2344,13 +2288,13 @@ (xevent->xproperty.atom == g_clip_c2s.property) && (xevent->xproperty.state == PropertyDelete)) { - log_debug("clipboard_event_property_notify: INCR PropertyDelete"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR PropertyDelete"); /* this is used for when copying a large clipboard to the other app, it will delete the property so we know to send the next one */ if ((g_clip_c2s.data == 0) || (g_clip_c2s.total_bytes < 1)) { - log_debug("clipboard_event_property_notify: INCR error"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR error"); return 0; } data = (tui8 *)(g_clip_c2s.data + g_clip_c2s.incr_bytes_done); @@ -2366,13 +2310,13 @@ data_bytes = g_incr_max_req_size; } g_clip_c2s.incr_bytes_done += data_bytes; - log_debug("clipboard_event_property_notify: data_bytes %d", data_bytes); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_property_notify: data_bytes %d", data_bytes); XChangeProperty(xevent->xproperty.display, xevent->xproperty.window, xevent->xproperty.atom, g_clip_c2s.type, 8, PropModeReplace, data, data_bytes); if (data_bytes < 1) { - log_debug("clipboard_event_property_notify: INCR done"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR done"); g_clip_c2s.incr_in_progress = 0; /* we no longer need property notify */ XSelectInput(xevent->xproperty.display, xevent->xproperty.window, @@ -2385,7 +2329,7 @@ (xevent->xproperty.atom == g_clip_s2c.property) && (xevent->xproperty.state == PropertyNewValue)) { - log_debug("clipboard_event_property_notify: INCR PropertyNewValue"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR PropertyNewValue"); rv = XGetWindowProperty(g_display, g_wnd, g_clip_s2c.property, 0, 0, 0, AnyPropertyType, &actual_type_return, &actual_format_return, &nitems_returned, &bytes_left, &data); @@ -2403,13 +2347,13 @@ if (bytes_left <= 0) { - log_debug("clipboard_event_property_notify: INCR done"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR done"); /* clipboard INCR cycle has completed */ g_clip_s2c.incr_in_progress = 0; if (g_clip_s2c.type == g_image_bmp_atom) { g_clip_s2c.xrdp_clip_type = XRDP_CB_BITMAP; - //g_hexdump(g_last_clip_data, 64); + //LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", g_last_clip_data, 64); /* skip header */ clipboard_send_data_response(g_clip_s2c.xrdp_clip_type, g_clip_s2c.data + 14, @@ -2425,7 +2369,7 @@ } else { - log_error("clipboard_event_property_notify: error unknown type %ld", + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_event_property_notify: error unknown type %ld", g_clip_s2c.type); clipboard_send_data_response_failed(); } @@ -2463,7 +2407,7 @@ return 0; } - log_debug("clipboard_event_property_notify: new_data_len %d", new_data_len); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_property_notify: new_data_len %d", new_data_len); g_clip_s2c.data = cptr; g_memcpy(g_clip_s2c.data + g_clip_s2c.total_bytes, data, new_data_len); g_clip_s2c.total_bytes += new_data_len; @@ -2487,7 +2431,7 @@ { XEvent *lxevent; - log_debug("clipboard_xevent: event detected"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_xevent: event detected"); if (!g_clip_up) { @@ -2499,13 +2443,13 @@ switch (lxevent->type) { case SelectionNotify: - if (g_restrict_outbound_clipboard == 0) + if (g_cfg->restrict_outbound_clipboard == 0) { clipboard_event_selection_notify(lxevent); } else { - log_debug("outbound clipboard is restricted because of config"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "outbound clipboard is restricted because of config"); return 1; } break; @@ -2521,30 +2465,30 @@ clipboard_event_property_notify(lxevent); break; case UnmapNotify: - log_debug("chansrv::clipboard_xevent: got UnmapNotify"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::clipboard_xevent: got UnmapNotify"); break; case ClientMessage: - log_debug("chansrv::clipboard_xevent: got ClientMessage"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::clipboard_xevent: got ClientMessage"); break; default: if (lxevent->type == g_xfixes_event_base + XFixesSetSelectionOwnerNotify) { - log_debug("clipboard_xevent: got XFixesSetSelectionOwnerNotify"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_xevent: got XFixesSetSelectionOwnerNotify"); clipboard_event_selection_owner_notify(lxevent); break; } if (lxevent->type == g_xfixes_event_base + XFixesSelectionWindowDestroyNotify) { - log_debug("clipboard_xevent: got XFixesSelectionWindowDestroyNotify"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_xevent: got XFixesSelectionWindowDestroyNotify"); break; } if (lxevent->type == g_xfixes_event_base + XFixesSelectionClientCloseNotify) { - log_debug("clipboard_xevent: got XFixesSelectionClientCloseNotify"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_xevent: got XFixesSelectionClientCloseNotify"); break; } diff -Nru xrdp-0.9.12/sesman/chansrv/clipboard_file.c xrdp-0.9.15/sesman/chansrv/clipboard_file.c --- xrdp-0.9.12/sesman/chansrv/clipboard_file.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/clipboard_file.c 2020-12-28 14:03:43.000000000 +0000 @@ -33,6 +33,7 @@ #include "arch.h" #include "parse.h" #include "os_calls.h" +#include "string_calls.h" #include "list.h" #include "chansrv.h" #include "clipboard.h" @@ -41,46 +42,6 @@ #include "xcommon.h" #include "chansrv_fuse.h" -/* module based logging */ -#define LOG_ERROR 0 -#define LOG_INFO 1 -#define LOG_DEBUG 2 -#define LOG_LVL LOG_ERROR - -#define log_error(_params...) \ -{ \ - g_write("[%10.10u]: CLIPFILE %s: %d : ERROR: ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ -} - -#define log_always(_params...) \ -{ \ - g_write("[%10.10u]: CLIPFILE %s: %d : ALWAYS: ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ -} - -#define log_info(_params...) \ -{ \ - if (LOG_INFO <= LOG_LVL) \ - { \ - g_write("[%10.10u]: CLIPFILE %s: %d : ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ - } \ -} - -#define log_debug(_params...) \ -{ \ - if (LOG_DEBUG <= LOG_LVL) \ - { \ - g_write("[%10.10u]: CLIPFILE %s: %d : ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ - } \ -} - extern int g_cliprdr_chan_id; /* in chansrv.c */ extern struct clip_s2c g_clip_s2c; /* in clipboard.c */ @@ -152,7 +113,7 @@ index++; } } - log_debug("[%s] [%s]", filename, lfilename); + LOG_DEVEL(LOG_LEVEL_DEBUG, "[%s] [%s]", filename, lfilename); g_strcpy(filename, lfilename); return 0; } @@ -209,28 +170,28 @@ g_snprintf(full_fn, 255, "%s/%s", pathname, filename); if (g_directory_exist(full_fn)) { - log_error("clipboard_get_file: file [%s] is a directory, " - "not supported", full_fn); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_get_file: file [%s] is a directory, " + "not supported", full_fn); flags |= CB_FILE_ATTRIBUTE_DIRECTORY; return 1; } if (!g_file_exist(full_fn)) { - log_error("clipboard_get_file: file [%s] does not exist", - full_fn); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_get_file: file [%s] does not exist", + full_fn); return 1; } else { - cfi = (struct cb_file_info*)g_malloc(sizeof(struct cb_file_info), 1); + cfi = (struct cb_file_info *)g_malloc(sizeof(struct cb_file_info), 1); list_add_item(g_files_list, (tintptr)cfi); g_strcpy(cfi->filename, filename); g_strcpy(cfi->pathname, pathname); cfi->size = g_file_get_size(full_fn); cfi->flags = flags; cfi->time = (g_time1() + CB_EPOCH_DIFF) * 10000000LL; - log_debug("ok filename [%s] pathname [%s] size [%d]", - cfi->filename, cfi->pathname, cfi->size); + LOG_DEVEL(LOG_LEVEL_DEBUG, "ok filename [%s] pathname [%s] size [%d]", + cfi->filename, cfi->pathname, cfi->size); } return 0; } @@ -292,9 +253,9 @@ char fn[256]; struct cb_file_info *cfi; - log_debug("clipboard_send_data_response_for_file: data_size %d", - data_size); - //g_hexdump(data, data_size); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_data_response_for_file: data_size %d", + data_size); + LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", data, data_size); if (g_files_list == 0) { g_files_list = list_create(); @@ -355,18 +316,18 @@ if (g_files_list == 0) { - log_error("clipboard_send_file_size: error g_files_list is nil"); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_file_size: error g_files_list is nil"); return 1; } cfi = (struct cb_file_info *)list_get_item(g_files_list, lindex); if (cfi == 0) { - log_error("clipboard_send_file_size: error cfi is nil"); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_file_size: error cfi is nil"); return 1; } file_size = cfi->size; - log_debug("clipboard_send_file_size: streamId %d file_size %d", - streamId, file_size); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_file_size: streamId %d file_size %d", + streamId, file_size); make_stream(s); init_stream(s, 8192); out_uint16_le(s, CB_FILECONTENTS_RESPONSE); /* 9 */ @@ -392,11 +353,11 @@ int size; int rv; - log_debug("clipboard_request_file_size:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_request_file_size:"); if (g_file_request_sent_type != 0) { - log_error("clipboard_request_file_size: warning, still waiting " - "for CB_FILECONTENTS_RESPONSE"); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_request_file_size: warning, still waiting " + "for CB_FILECONTENTS_RESPONSE"); } make_stream(s); init_stream(s, 8192); @@ -434,30 +395,30 @@ if (g_files_list == 0) { - log_error("clipboard_send_file_data: error g_files_list is nil"); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_file_data: error g_files_list is nil"); return 1; } cfi = (struct cb_file_info *)list_get_item(g_files_list, lindex); if (cfi == 0) { - log_error("clipboard_send_file_data: error cfi is nil"); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_file_data: error cfi is nil"); return 1; } - log_debug("clipboard_send_file_data: streamId %d lindex %d " - "nPositionLow %d cbRequested %d", streamId, lindex, - nPositionLow, cbRequested); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_file_data: streamId %d lindex %d " + "nPositionLow %d cbRequested %d", streamId, lindex, + nPositionLow, cbRequested); g_snprintf(full_fn, 255, "%s/%s", cfi->pathname, cfi->filename); fd = g_file_open_ex(full_fn, 1, 0, 0, 0); if (fd == -1) { - log_error("clipboard_send_file_data: file open [%s] failed", - full_fn); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_file_data: file open [%s] failed", + full_fn); return 1; } if (g_file_seek(fd, nPositionLow) < 0) { - log_message(LOG_LEVEL_ERROR, "clipboard_send_file_data: seek error " - "in file: %s", full_fn); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_file_data: seek error " + "in file: %s", full_fn); g_file_close(fd); return 1; } @@ -466,8 +427,8 @@ size = g_file_read(fd, s->data + 12, cbRequested); if (size < 1) { - log_error("clipboard_send_file_data: read error, want %d got %d", - cbRequested, size); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_file_data: read error, want %d got %d", + cbRequested, size); free_stream(s); g_file_close(fd); return 1; @@ -496,13 +457,13 @@ int size; int rv; - log_debug("clipboard_request_file_data: stream_id=%d lindex=%d off=%d request_bytes=%d", - stream_id, lindex, offset, request_bytes); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_request_file_data: stream_id=%d lindex=%d off=%d request_bytes=%d", + stream_id, lindex, offset, request_bytes); if (g_file_request_sent_type != 0) { - log_error("clipboard_request_file_data: warning, still waiting " - "for CB_FILECONTENTS_RESPONSE"); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_request_file_data: warning, still waiting " + "for CB_FILECONTENTS_RESPONSE"); } make_stream(s); init_stream(s, 8192); @@ -539,8 +500,8 @@ int cbRequested; //int clipDataId; - log_debug("clipboard_process_file_request:"); - //g_hexdump(s->p, clip_msg_len); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_file_request:"); + LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", s->p, clip_msg_len); in_uint32_le(s, streamId); in_uint32_le(s, lindex); in_uint32_le(s, dwFlags); @@ -569,14 +530,14 @@ int streamId; int file_size; - log_debug("clipboard_process_file_response:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_file_response:"); if (g_file_request_sent_type == CB_FILECONTENTS_SIZE) { g_file_request_sent_type = 0; in_uint32_le(s, streamId); in_uint32_le(s, file_size); - log_debug("clipboard_process_file_response: streamId %d " - "file_size %d", streamId, file_size); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_file_response: streamId %d " + "file_size %d", streamId, file_size); xfuse_file_contents_size(streamId, file_size); } else if (g_file_request_sent_type == CB_FILECONTENTS_RANGE) @@ -587,7 +548,7 @@ } else { - log_error("clipboard_process_file_response: error"); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_process_file_response: error"); g_file_request_sent_type = 0; } return 0; @@ -615,14 +576,14 @@ ex_bytes -= 2; in_uint8s(s, ex_bytes); in_uint8s(s, 8); /* pad */ - log_debug("clipboard_c2s_in_file_info:"); - log_debug(" flags 0x%8.8x", cfd->flags); - log_debug(" fileAttributes 0x%8.8x", cfd->fileAttributes); - log_debug(" lastWriteTime 0x%8.8x%8.8x", cfd->lastWriteTimeHigh, - cfd->lastWriteTimeLow); - log_debug(" fileSize 0x%8.8x%8.8x", cfd->fileSizeHigh, - cfd->fileSizeLow); - log_debug(" num_chars %d cFileName [%s]", num_chars, cfd->cFileName); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_c2s_in_file_info:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, " flags 0x%8.8x", cfd->flags); + LOG_DEVEL(LOG_LEVEL_DEBUG, " fileAttributes 0x%8.8x", cfd->fileAttributes); + LOG_DEVEL(LOG_LEVEL_DEBUG, " lastWriteTime 0x%8.8x%8.8x", cfd->lastWriteTimeHigh, + cfd->lastWriteTimeLow); + LOG_DEVEL(LOG_LEVEL_DEBUG, " fileSize 0x%8.8x%8.8x", cfd->fileSizeHigh, + cfd->fileSizeLow); + LOG_DEVEL(LOG_LEVEL_DEBUG, " num_chars %d cFileName [%s]", num_chars, cfd->cFileName); return 0; } @@ -639,17 +600,17 @@ if (!s_check_rem(s, 4)) { - log_error("clipboard_c2s_in_files: parse error"); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_c2s_in_files: parse error"); return 1; } in_uint32_le(s, cItems); if (cItems > 64 * 1024) /* sanity check */ { - log_error("clipboard_c2s_in_files: error cItems %d too big", cItems); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_c2s_in_files: error cItems %d too big", cItems); return 1; } xfuse_clear_clip_dir(); - log_debug("clipboard_c2s_in_files: cItems %d", cItems); + LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_c2s_in_files: cItems %d", cItems); cfd = (struct clip_file_desc *) g_malloc(sizeof(struct clip_file_desc), 0); file_count = 0; @@ -659,15 +620,15 @@ g_memset(cfd, 0, sizeof(struct clip_file_desc)); clipboard_c2s_in_file_info(s, cfd); if ((g_pos(cfd->cFileName, "\\") >= 0) || - (cfd->fileAttributes & CB_FILE_ATTRIBUTE_DIRECTORY)) + (cfd->fileAttributes & CB_FILE_ATTRIBUTE_DIRECTORY)) { - log_error("clipboard_c2s_in_files: skipping directory not " - "supported [%s]", cfd->cFileName); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_c2s_in_files: skipping directory not " + "supported [%s]", cfd->cFileName); continue; } if (xfuse_add_clip_dir_item(cfd->cFileName, 0, cfd->fileSizeLow, lindex) == -1) { - log_error("clipboard_c2s_in_files: failed to add clip dir item"); + LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_c2s_in_files: failed to add clip dir item"); continue; } diff -Nru xrdp-0.9.12/sesman/chansrv/devredir.c xrdp-0.9.15/sesman/chansrv/devredir.c --- xrdp-0.9.12/sesman/chansrv/devredir.c 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/devredir.c 2020-12-28 14:03:43.000000000 +0000 @@ -49,6 +49,7 @@ #include "arch.h" #include "parse.h" #include "os_calls.h" +#include "string_calls.h" #include "log.h" #include "chansrv.h" #include "chansrv_fuse.h" @@ -59,40 +60,6 @@ #include "ms-fscc.h" #include "ms-erref.h" -/* module based logging */ -#define LOG_ERROR 0 -#define LOG_INFO 1 -#define LOG_DEBUG 2 - -#undef LOG_LEVEL -#define LOG_LEVEL LOG_ERROR - -#define log_error(_params...) \ -{ \ - g_write("[%10.10u]: DEV_REDIR %s: %d : ERROR: ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ -} - -#define log_info(_params...) \ -{ \ - if (LOG_INFO <= LOG_LEVEL) \ - { \ - g_write("[%10.10u]: DEV_REDIR %s: %d : ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ - } \ -} - -#define log_debug(_params...) \ -{ \ - if (LOG_DEBUG <= LOG_LEVEL) \ - { \ - g_write("[%10.10u]: DEV_REDIR %s: %d : ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ - } \ -} /* client minor versions */ #define RDP_CLIENT_50 0x0002 @@ -149,10 +116,10 @@ */ static void devredir_proc_cid_rmdir_or_file(IRP *irp, enum NTSTATUS IoStatus); static void devredir_proc_cid_rmdir_or_file_resp(IRP *irp, - enum NTSTATUS IoStatus); + enum NTSTATUS IoStatus); static void devredir_proc_cid_rename_file(IRP *irp, enum NTSTATUS IoStatus); static void devredir_proc_cid_rename_file_resp(IRP *irp, - enum NTSTATUS IoStatus); + enum NTSTATUS IoStatus); static void devredir_proc_cid_lookup( IRP *irp, struct stream *s_in, enum NTSTATUS IoStatus); @@ -169,10 +136,10 @@ static void devredir_proc_client_devlist_remove_req(struct stream *s); static void devredir_proc_device_iocompletion(struct stream *s); static void devredir_proc_query_dir_response(IRP *irp, - struct stream *s_in, - tui32 DeviceId, - tui32 CompletionId, - enum NTSTATUS IoStatus); + struct stream *s_in, + tui32 DeviceId, + tui32 CompletionId, + enum NTSTATUS IoStatus); static void devredir_cvt_slash(char *path); static void devredir_cvt_to_unicode(char *unicode, const char *path); @@ -185,28 +152,10 @@ { struct stream *s; int bytes; - int fd; - - union _u - { - tui32 clientID; - char buf[4]; - } u; + tui32 clientID; /* get a random number that will act as a unique clientID */ - if ((fd = open("/dev/urandom", O_RDONLY)) != -1) - { - if (read(fd, u.buf, 4) != 4) - { - } - close(fd); - } - else - { - /* /dev/urandom did not work - use address of struct s */ - tui64 u64 = (tui64) (tintptr) &s; - u.clientID = (tui32) u64; - } + g_random((char *) &clientID, sizeof(clientID)); /* setup stream */ xstream_new(s, 1024); @@ -216,7 +165,7 @@ xstream_wr_u16_le(s, PAKID_CORE_SERVER_ANNOUNCE); xstream_wr_u16_le(s, 0x0001); /* server major ver */ xstream_wr_u16_le(s, 0x000C); /* server minor ver - pretend 2 b Win 7 */ - xstream_wr_u32_le(s, u.clientID); /* unique ClientID */ + xstream_wr_u32_le(s, clientID); /* unique ClientID */ /* send data to client */ bytes = xstream_len(s); @@ -241,21 +190,21 @@ */ const char *completion_type_to_str(enum COMPLETION_TYPE cid) { - return - (cid == CID_CREATE_DIR_REQ) ? "CID_CREATE_DIR_REQ" : - (cid == CID_DIRECTORY_CONTROL) ? "CID_DIRECTORY_CONTROL" : - (cid == CID_CREATE_REQ) ? "CID_CREATE_REQ" : - (cid == CID_OPEN_REQ) ? "CID_OPEN_REQ" : - (cid == CID_READ) ? "CID_READ" : - (cid == CID_WRITE) ? "CID_WRITE" : - (cid == CID_CLOSE) ? "CID_CLOSE" : - (cid == CID_FILE_CLOSE) ? "CID_FILE_CLOSE" : - (cid == CID_RMDIR_OR_FILE) ? "CID_RMDIR_OR_FILE" : - (cid == CID_RMDIR_OR_FILE_RESP) ? "CID_RMDIR_OR_FILE_RESP" : - (cid == CID_RENAME_FILE) ? "CID_RENAME_FILE" : - (cid == CID_RENAME_FILE_RESP) ? "CID_RENAME_FILE_RESP" : - (cid == CID_LOOKUP) ? "CID_LOOKUP" : - (cid == CID_SETATTR) ? "CID_SETATTR" : + return + (cid == CID_CREATE_DIR_REQ) ? "CID_CREATE_DIR_REQ" : + (cid == CID_DIRECTORY_CONTROL) ? "CID_DIRECTORY_CONTROL" : + (cid == CID_CREATE_REQ) ? "CID_CREATE_REQ" : + (cid == CID_OPEN_REQ) ? "CID_OPEN_REQ" : + (cid == CID_READ) ? "CID_READ" : + (cid == CID_WRITE) ? "CID_WRITE" : + (cid == CID_CLOSE) ? "CID_CLOSE" : + (cid == CID_FILE_CLOSE) ? "CID_FILE_CLOSE" : + (cid == CID_RMDIR_OR_FILE) ? "CID_RMDIR_OR_FILE" : + (cid == CID_RMDIR_OR_FILE_RESP) ? "CID_RMDIR_OR_FILE_RESP" : + (cid == CID_RENAME_FILE) ? "CID_RENAME_FILE" : + (cid == CID_RENAME_FILE_RESP) ? "CID_RENAME_FILE_RESP" : + (cid == CID_LOOKUP) ? "CID_LOOKUP" : + (cid == CID_SETATTR) ? "CID_SETATTR" : /* default */ ""; }; @@ -279,10 +228,16 @@ else { result = S_IFREG | 0444; /* files are always readable */ - if (wperm & W_FILE_ATTRIBUTE_SYSTEM) result |= 0111; /* Executable */ + if (wperm & W_FILE_ATTRIBUTE_SYSTEM) + { + result |= 0111; /* Executable */ + } } - if ((wperm & W_FILE_ATTRIBUTE_READONLY) == 0) result |= 0222; + if ((wperm & W_FILE_ATTRIBUTE_READONLY) == 0) + { + result |= 0222; + } return result; } @@ -350,13 +305,17 @@ { /* is this is the first packet? */ if (chan_flags & 1) + { xstream_new(g_input_stream, total_length); + } xstream_copyin(g_input_stream, s->p, length); /* in last packet, chan_flags & 0x02 will be true */ if ((chan_flags & 2) == 0) + { return 0; + } g_input_stream->p = g_input_stream->data; ls = g_input_stream; @@ -369,7 +328,7 @@ /* for now we only handle core type, not printers */ if (comp_type != RDPDR_CTYP_CORE) { - log_error("invalid component type in response; expected 0x%x got 0x%x", + LOG_DEVEL(LOG_LEVEL_ERROR, "invalid component type in response; expected 0x%x got 0x%x", RDPDR_CTYP_CORE, comp_type); rv = -1; @@ -434,7 +393,7 @@ break; default: - log_error("got unknown response 0x%x", pktID); + LOG_DEVEL(LOG_LEVEL_ERROR, "got unknown response 0x%x", pktID); break; } @@ -493,8 +452,8 @@ /* setup general capability */ xstream_wr_u16_le(s, CAP_GENERAL_TYPE); /* CapabilityType */ xstream_wr_u16_le(s, 44); /* CapabilityLength - len of this */ - /* CAPABILITY_SET in bytes, inc */ - /* the header */ + /* CAPABILITY_SET in bytes, inc */ + /* the header */ xstream_wr_u32_le(s, 2); /* Version */ xstream_wr_u32_le(s, 2); /* O.S type */ xstream_wr_u32_le(s, 0); /* O.S version */ @@ -520,8 +479,8 @@ /* setup file system capability */ xstream_wr_u16_le(s, CAP_DRIVE_TYPE); /* CapabilityType */ xstream_wr_u16_le(s, 8); /* CapabilityLength - len of this */ - /* CAPABILITY_SET in bytes, inc */ - /* the header */ + /* CAPABILITY_SET in bytes, inc */ + /* the header */ xstream_wr_u32_le(s, 2); /* Version */ /* setup smart card capability */ @@ -578,7 +537,8 @@ } static void -devredir_send_server_device_announce_resp(tui32 device_id) +devredir_send_server_device_announce_resp(tui32 device_id, + enum NTSTATUS result_code) { struct stream *s; int bytes; @@ -589,7 +549,7 @@ xstream_wr_u16_le(s, RDPDR_CTYP_CORE); xstream_wr_u16_le(s, PAKID_CORE_DEVICE_REPLY); xstream_wr_u32_le(s, device_id); - xstream_wr_u32_le(s, 0); /* ResultCode */ + xstream_wr_u32_le(s, (tui32)result_code); /* send to client */ bytes = xstream_len(s); @@ -616,7 +576,7 @@ int len; tui32 SharedAccess; - log_debug("device_id=%d path=\"%s\"" + LOG_DEVEL(LOG_LEVEL_DEBUG, "device_id=%d path=\"%s\"" " DesiredAccess=0x%x CreateDisposition=0x%x" " FileAttributes=0x%x CreateOptions=0x%x" " CompletionId=%d", @@ -683,14 +643,16 @@ MajorFunction, MinorFunc); if (pad_len) + { xstream_seek(s, pad_len); + } /* send to client */ bytes = xstream_len(s); send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); - log_debug("sent close request; expect CID_FILE_CLOSE"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sent close request; expect CID_FILE_CLOSE"); return 0; } @@ -773,7 +735,7 @@ tui16 cap_type; tui16 cap_len; tui32 cap_version; - char* holdp; + char *holdp; xstream_rd_u16_le(s, num_caps); xstream_seek(s, 2); /* padding */ @@ -788,21 +750,21 @@ switch (cap_type) { case CAP_GENERAL_TYPE: - log_debug("got CAP_GENERAL_TYPE"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "got CAP_GENERAL_TYPE"); break; case CAP_PRINTER_TYPE: - log_debug("got CAP_PRINTER_TYPE"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "got CAP_PRINTER_TYPE"); g_is_printer_redir_supported = 1; break; case CAP_PORT_TYPE: - log_debug("got CAP_PORT_TYPE"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "got CAP_PORT_TYPE"); g_is_port_redir_supported = 1; break; case CAP_DRIVE_TYPE: - log_debug("got CAP_DRIVE_TYPE"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "got CAP_DRIVE_TYPE"); g_is_drive_redir_supported = 1; if (cap_version == 2) { @@ -811,7 +773,7 @@ break; case CAP_SMARTCARD_TYPE: - log_debug("got CAP_SMARTCARD_TYPE"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "got CAP_SMARTCARD_TYPE"); g_is_smartcard_redir_supported = 1; scard_init(); break; @@ -829,43 +791,45 @@ tui32 device_type; tui32 device_data_len; char preferred_dos_name[9]; + enum NTSTATUS response_status; /* get number of devices being announced */ xstream_rd_u32_le(s, device_count); - log_debug("num of devices announced: %d", device_count); + LOG_DEVEL(LOG_LEVEL_DEBUG, "num of devices announced: %d", device_count); for (i = 0; i < device_count; i++) { xstream_rd_u32_le(s, device_type); xstream_rd_u32_le(s, g_device_id); + /* get preferred DOS name + * DOS names that are 8 chars long are not NULL terminated */ + for (j = 0; j < 8; j++) + { + preferred_dos_name[j] = *s->p++; + } + preferred_dos_name[8] = 0; + + /* Assume this device isn't supported by us */ + response_status = STATUS_NOT_SUPPORTED; switch (device_type) { case RDPDR_DTYP_FILESYSTEM: - /* get preferred DOS name */ - for (j = 0; j < 8; j++) - { - preferred_dos_name[j] = *s->p++; - } - - /* DOS names that are 8 chars long are not NULL terminated */ - preferred_dos_name[8] = 0; - /* get device data len */ xstream_rd_u32_le(s, device_data_len); if (device_data_len) { xstream_rd_string(g_full_name_for_filesystem, s, - device_data_len); + device_data_len); } - log_debug("device_type=FILE_SYSTEM device_id=0x%x dosname=%s " + LOG_DEVEL(LOG_LEVEL_DEBUG, "device_type=FILE_SYSTEM device_id=0x%x dosname=%s " "device_data_len=%d full_name=%s", g_device_id, preferred_dos_name, device_data_len, g_full_name_for_filesystem); - devredir_send_server_device_announce_resp(g_device_id); + response_status = STATUS_SUCCESS; /* create share directory in xrdp file system; */ /* think of this as the mount point for this share */ @@ -873,31 +837,44 @@ break; case RDPDR_DTYP_SMARTCARD: - /* get preferred DOS name */ - for (j = 0; j < 8; j++) - { - preferred_dos_name[j] = *s->p++; - } - - /* DOS names that are 8 chars long are not NULL terminated */ - preferred_dos_name[8] = 0; - /* for smart cards, device data len always 0 */ - log_debug("device_type=SMARTCARD device_id=0x%x dosname=%s", + LOG_DEVEL(LOG_LEVEL_DEBUG, "device_type=SMARTCARD device_id=0x%x dosname=%s", g_device_id, preferred_dos_name); - devredir_send_server_device_announce_resp(g_device_id); + response_status = STATUS_SUCCESS; + scard_device_announce(g_device_id); break; - /* we don't yet support these devices */ case RDPDR_DTYP_SERIAL: + LOG_DEVEL(LOG_LEVEL_DEBUG, + "device_type=SERIAL device_id=0x%x dosname=%s", + g_device_id, preferred_dos_name); + break; + case RDPDR_DTYP_PARALLEL: + LOG_DEVEL(LOG_LEVEL_DEBUG, + "device_type=PARALLEL device_id=0x%x dosname=%s", + g_device_id, preferred_dos_name); + break; + case RDPDR_DTYP_PRINT: - log_debug("unsupported dev: 0x%x", device_type); + LOG_DEVEL(LOG_LEVEL_DEBUG, + "device_type=PRINT device_id=0x%x dosname=%s", + g_device_id, preferred_dos_name); + break; + + default: + LOG_DEVEL(LOG_LEVEL_DEBUG, + "device_type=UNKNOWN device_id=0x%x dosname=%s", + g_device_id, preferred_dos_name); break; } + + /* Tell the client wheth or not we're supporting this one */ + devredir_send_server_device_announce_resp(g_device_id, + response_status); } } @@ -911,7 +888,7 @@ /* get number of devices being announced */ xstream_rd_u32_le(s, device_count); - log_debug("num of devices removed: %d", device_count); + LOG_DEVEL(LOG_LEVEL_DEBUG, "num of devices removed: %d", device_count); { for (i = 0; i < device_count; i++) { @@ -939,10 +916,9 @@ if ((irp = devredir_irp_find(CompletionId)) == NULL) { - log_error("IRP with completion ID %d not found", CompletionId); + LOG_DEVEL(LOG_LEVEL_ERROR, "IRP with completion ID %d not found", CompletionId); } - else - if (irp->callback) + else if (irp->callback) { /* Callback has been set - call it */ (*irp->callback)(s, irp, DeviceId, CompletionId, IoStatus); @@ -951,123 +927,123 @@ { comp_type = (enum COMPLETION_TYPE) irp->completion_type; /* Log something about the IRP */ - if (IoStatus == NT_STATUS_SUCCESS || - IoStatus == NT_STATUS_NO_MORE_FILES || - (IoStatus == NT_STATUS_NO_SUCH_FILE && comp_type == CID_LOOKUP)) + if (IoStatus == STATUS_SUCCESS || + IoStatus == STATUS_NO_MORE_FILES || + (IoStatus == STATUS_NO_SUCH_FILE && comp_type == CID_LOOKUP)) { /* Successes or common occurrences - debug logging only */ - log_debug("got %s", completion_type_to_str(comp_type)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "got %s", completion_type_to_str(comp_type)); } else { - const char *pathname = (irp->pathname) ? irp->pathname : ""; - log_error("CompletionType = %s, IoStatus=%08x " + LOG_DEVEL(LOG_LEVEL_ERROR, "CompletionType = %s, IoStatus=%08x " "Pathname = %s", completion_type_to_str(comp_type), IoStatus, - pathname); + (irp->pathname) ? irp->pathname : ""); } switch (comp_type) { - case CID_CREATE_DIR_REQ: - if (IoStatus != NT_STATUS_SUCCESS) - { - xfuse_devredir_cb_enum_dir_done( - (struct state_dirscan *) irp->fuse_info, IoStatus); - devredir_irp_delete(irp); - } - else - { + case CID_CREATE_DIR_REQ: + if (IoStatus != STATUS_SUCCESS) + { + xfuse_devredir_cb_enum_dir_done( + (struct state_dirscan *) irp->fuse_info, IoStatus); + devredir_irp_delete(irp); + } + else + { + xstream_rd_u32_le(s, irp->FileId); + devredir_send_drive_dir_request(irp, DeviceId, + 1, irp->pathname); + } + break; + + case CID_CREATE_REQ: xstream_rd_u32_le(s, irp->FileId); - devredir_send_drive_dir_request(irp, DeviceId, - 1, irp->pathname); - } - break; - case CID_CREATE_REQ: - xstream_rd_u32_le(s, irp->FileId); + xfuse_devredir_cb_create_file( + (struct state_create *) irp->fuse_info, + IoStatus, DeviceId, irp->FileId); + if (irp->gen.create.creating_dir || IoStatus != STATUS_SUCCESS) + { + devredir_irp_delete(irp); + } + break; - xfuse_devredir_cb_create_file( - (struct state_create *) irp->fuse_info, - IoStatus, DeviceId, irp->FileId); - if (irp->gen.create.creating_dir || IoStatus != NT_STATUS_SUCCESS) - { - devredir_irp_delete(irp); - } - break; + case CID_OPEN_REQ: + xstream_rd_u32_le(s, irp->FileId); - case CID_OPEN_REQ: - xstream_rd_u32_le(s, irp->FileId); + xfuse_devredir_cb_open_file((struct state_open *) irp->fuse_info, + IoStatus, DeviceId, irp->FileId); + if (IoStatus != STATUS_SUCCESS) + { + devredir_irp_delete(irp); + } + break; - xfuse_devredir_cb_open_file((struct state_open *) irp->fuse_info, - IoStatus, DeviceId, irp->FileId); - if (IoStatus != NT_STATUS_SUCCESS) - { + case CID_READ: + xstream_rd_u32_le(s, Length); + xfuse_devredir_cb_read_file((struct state_read *) irp->fuse_info, + IoStatus, + s->p, Length); devredir_irp_delete(irp); - } - break; - - case CID_READ: - xstream_rd_u32_le(s, Length); - xfuse_devredir_cb_read_file((struct state_read *) irp->fuse_info, - s->p, Length); - devredir_irp_delete(irp); - break; + break; - case CID_WRITE: - xstream_rd_u32_le(s, Length); - xfuse_devredir_cb_write_file((struct state_write *) irp->fuse_info, - IoStatus, - irp->gen.write.offset, Length); - devredir_irp_delete(irp); - break; + case CID_WRITE: + xstream_rd_u32_le(s, Length); + xfuse_devredir_cb_write_file((struct state_write *) irp->fuse_info, + IoStatus, + irp->gen.write.offset, Length); + devredir_irp_delete(irp); + break; - case CID_CLOSE: - devredir_irp_delete(irp); - break; + case CID_CLOSE: + devredir_irp_delete(irp); + break; - case CID_FILE_CLOSE: - xfuse_devredir_cb_file_close((struct state_close *) irp->fuse_info); - devredir_irp_delete(irp); - break; + case CID_FILE_CLOSE: + xfuse_devredir_cb_file_close((struct state_close *) irp->fuse_info); + devredir_irp_delete(irp); + break; - case CID_DIRECTORY_CONTROL: - devredir_proc_query_dir_response(irp, s, DeviceId, - CompletionId, IoStatus); - break; + case CID_DIRECTORY_CONTROL: + devredir_proc_query_dir_response(irp, s, DeviceId, + CompletionId, IoStatus); + break; - case CID_RMDIR_OR_FILE: - xstream_rd_u32_le(s, irp->FileId); - devredir_proc_cid_rmdir_or_file(irp, IoStatus); - break; + case CID_RMDIR_OR_FILE: + xstream_rd_u32_le(s, irp->FileId); + devredir_proc_cid_rmdir_or_file(irp, IoStatus); + break; - case CID_RMDIR_OR_FILE_RESP: - devredir_proc_cid_rmdir_or_file_resp(irp, IoStatus); - break; + case CID_RMDIR_OR_FILE_RESP: + devredir_proc_cid_rmdir_or_file_resp(irp, IoStatus); + break; - case CID_RENAME_FILE: - xstream_rd_u32_le(s, irp->FileId); - devredir_proc_cid_rename_file(irp, IoStatus); - break; + case CID_RENAME_FILE: + xstream_rd_u32_le(s, irp->FileId); + devredir_proc_cid_rename_file(irp, IoStatus); + break; - case CID_RENAME_FILE_RESP: - devredir_proc_cid_rename_file_resp(irp, IoStatus); - break; + case CID_RENAME_FILE_RESP: + devredir_proc_cid_rename_file_resp(irp, IoStatus); + break; - case CID_LOOKUP: - devredir_proc_cid_lookup(irp, s, IoStatus); - break; + case CID_LOOKUP: + devredir_proc_cid_lookup(irp, s, IoStatus); + break; - case CID_SETATTR: - devredir_proc_cid_setattr(irp, s, IoStatus); - break; + case CID_SETATTR: + devredir_proc_cid_setattr(irp, s, IoStatus); + break; - default: - log_error("got unknown CompletionID: DeviceId=0x%x " - "CompletionId=0x%x IoStatus=0x%x", - DeviceId, CompletionId, IoStatus); - break; + default: + LOG_DEVEL(LOG_LEVEL_ERROR, "got unknown CompletionID: DeviceId=0x%x " + "CompletionId=0x%x IoStatus=0x%x", + DeviceId, CompletionId, IoStatus); + break; } } } @@ -1082,7 +1058,7 @@ tui32 Length; xstream_rd_u32_le(s_in, Length); - if (IoStatus == NT_STATUS_SUCCESS) + if (IoStatus == STATUS_SUCCESS) { unsigned int i; /* process FILE_DIRECTORY_INFORMATION structures */ @@ -1111,12 +1087,12 @@ i += 64 + FileNameLength; - //log_debug("LastAccessTime: 0x%llx", LastAccessTime); - //log_debug("LastWriteTime: 0x%llx", LastWriteTime); - //log_debug("EndOfFile: %lld", EndOfFile); - //log_debug("FileAttributes: 0x%x", FileAttributes); - //log_debug("FileNameLength: %d", FileNameLength); - log_debug("FileName: %s", filename); + //LOG_DEVEL(LOG_LEVEL_DEBUG, "LastAccessTime: 0x%llx", LastAccessTime); + //LOG_DEVEL(LOG_LEVEL_DEBUG, "LastWriteTime: 0x%llx", LastWriteTime); + //LOG_DEVEL(LOG_LEVEL_DEBUG, "EndOfFile: %lld", EndOfFile); + //LOG_DEVEL(LOG_LEVEL_DEBUG, "FileAttributes: 0x%x", FileAttributes); + //LOG_DEVEL(LOG_LEVEL_DEBUG, "FileNameLength: %d", FileNameLength); + LOG_DEVEL(LOG_LEVEL_DEBUG, "FileName: %s", filename); fattr.mode = WindowsToLinuxFilePerm(FileAttributes); fattr.size = (size_t) EndOfFile; @@ -1125,8 +1101,8 @@ /* add this entry to xrdp file system */ xfuse_devredir_cb_enum_dir_add_entry( - (struct state_dirscan *) irp->fuse_info, - filename, &fattr); + (struct state_dirscan *) irp->fuse_info, + filename, &fattr); } /* Ask for more directory entries */ @@ -1134,9 +1110,9 @@ } else { - if (IoStatus == NT_STATUS_NO_MORE_FILES) + if (IoStatus == STATUS_NO_MORE_FILES) { - IoStatus = NT_STATUS_SUCCESS; + IoStatus = STATUS_SUCCESS; } xfuse_devredir_cb_enum_dir_done((struct state_dirscan *)irp->fuse_info, IoStatus); @@ -1191,13 +1167,13 @@ CreateDisposition = CD_FILE_OPEN; rval = devredir_send_drive_create_request(device_id, irp->pathname, - DesiredAccess, CreateOptions, - 0, CreateDisposition, - irp->CompletionId); + DesiredAccess, CreateOptions, + 0, CreateDisposition, + irp->CompletionId); - log_debug("looking for device_id=%d path=%s", device_id, irp->pathname); + LOG_DEVEL(LOG_LEVEL_DEBUG, "looking for device_id=%d path=%s", device_id, irp->pathname); - /* when we get a response to devredir_send_drive_create_request(), we + /* when we get a response to devredir_send_drive_create_request(), we * call devredir_send_drive_dir_request(), which needs the following * at the end of the path argument */ if (devredir_string_ends_with(irp->pathname, '\\')) @@ -1233,7 +1209,7 @@ int rval = -1; IRP *irp; - log_debug("fusep=%p", fusep); + LOG_DEVEL(LOG_LEVEL_DEBUG, "fusep=%p", fusep); if ((irp = devredir_irp_with_pathname_new(path)) != NULL) { @@ -1254,14 +1230,14 @@ CreateOptions = 0; CreateDisposition = CD_FILE_OPEN; - log_debug("lookup for device_id=%d path=%s CompletionId=%d", + LOG_DEVEL(LOG_LEVEL_DEBUG, "lookup for device_id=%d path=%s CompletionId=%d", device_id, irp->pathname, irp->CompletionId); rval = devredir_send_drive_create_request(device_id, - irp->pathname, - DesiredAccess, CreateOptions, - 0, CreateDisposition, - irp->CompletionId); + irp->pathname, + DesiredAccess, CreateOptions, + 0, CreateDisposition, + irp->CompletionId); } return rval; @@ -1291,7 +1267,7 @@ int rval = -1; IRP *irp; - log_debug("fusep=%p", fusep); + LOG_DEVEL(LOG_LEVEL_DEBUG, "fusep=%p", fusep); if ((irp = devredir_irp_with_pathname_new(filename)) != NULL) { @@ -1323,14 +1299,14 @@ CreateOptions = 0; CreateDisposition = CD_FILE_OPEN; - log_debug("lookup for device_id=%d path=%s", + LOG_DEVEL(LOG_LEVEL_DEBUG, "lookup for device_id=%d path=%s", device_id, irp->pathname); rval = devredir_send_drive_create_request(device_id, - irp->pathname, - DesiredAccess, CreateOptions, - 0, CreateDisposition, - irp->CompletionId); + irp->pathname, + DesiredAccess, CreateOptions, + 0, CreateDisposition, + irp->CompletionId); } return rval; @@ -1347,7 +1323,7 @@ int rval = -1; IRP *irp; - log_debug("device_id=%d path=%s mode=0%o", device_id, path, mode); + LOG_DEVEL(LOG_LEVEL_DEBUG, "device_id=%d path=%s mode=0%o", device_id, path, mode); if ((irp = devredir_irp_with_pathname_new(path)) != NULL) { @@ -1359,17 +1335,18 @@ irp->DeviceId = device_id; irp->fuse_info = fusep; + DesiredAccess = 0x0016019f; /* got this value from windows */ FileAttributes = LinuxToWindowsFilePerm(mode); if (mode & S_IFDIR) { - log_debug("creating dir"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "creating dir"); CreateOptions = CO_FILE_DIRECTORY_FILE | CO_FILE_SYNCHRONOUS_IO_NONALERT; irp->gen.create.creating_dir = 1; } else { - log_debug("creating file"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "creating file"); CreateOptions = 0x44; /* got this value from windows */ irp->gen.create.creating_dir = 0; } @@ -1378,10 +1355,10 @@ CreateDisposition = 0x02; /* got this value from windows */ rval = devredir_send_drive_create_request(device_id, path, - DesiredAccess, CreateOptions, - FileAttributes, - CreateDisposition, - irp->CompletionId); + DesiredAccess, CreateOptions, + FileAttributes, + CreateDisposition, + irp->CompletionId); } return rval; @@ -1398,7 +1375,7 @@ int rval = -1; IRP *irp; - log_debug("device_id=%d path=%s flags=0%x", + LOG_DEVEL(LOG_LEVEL_DEBUG, "device_id=%d path=%s flags=0%x", device_id, path, flags); if ((irp = devredir_irp_with_pathname_new(path)) != NULL) @@ -1412,15 +1389,15 @@ irp->fuse_info = fusep; - switch(flags & O_ACCMODE) + switch (flags & O_ACCMODE) { case O_RDONLY: - log_debug("open file in O_RDONLY"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "open file in O_RDONLY"); DesiredAccess = DA_FILE_READ_DATA | DA_SYNCHRONIZE; break; case O_WRONLY: - log_debug("open file in O_WRONLY"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "open file in O_WRONLY"); DesiredAccess = DA_FILE_WRITE_DATA | DA_SYNCHRONIZE; break; @@ -1429,10 +1406,10 @@ * The access mode could conceivably be invalid here, * but we assume this has been checked by the caller */ - log_debug("open file in O_RDWR"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "open file in O_RDWR"); /* without the 0x00000010 rdesktop opens files in */ /* O_RDONLY instead of O_RDWR mode */ - DesiredAccess = DA_FILE_READ_DATA | DA_FILE_WRITE_DATA | + DesiredAccess = DA_FILE_READ_DATA | DA_FILE_WRITE_DATA | DA_SYNCHRONIZE | 0x00000010; } @@ -1440,10 +1417,10 @@ CreateDisposition = CD_FILE_OPEN; // WAS 1 rval = devredir_send_drive_create_request(device_id, path, - DesiredAccess, CreateOptions, - FileAttributes, - CreateDisposition, - irp->CompletionId); + DesiredAccess, CreateOptions, + FileAttributes, + CreateDisposition, + irp->CompletionId); } return rval; @@ -1454,18 +1431,20 @@ { IRP *irp; - log_debug("entered: fusep=%p device_id=%d FileId=%d", + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: fusep=%p device_id=%d FileId=%d", fusep, device_id, FileId); #if 0 if ((irp = devredir_irp_new()) == NULL) + { return -1; + } irp->CompletionId = g_completion_id++; #else if ((irp = devredir_irp_find_by_fileid(FileId)) == NULL) { - log_error("no IRP found with FileId = %d", FileId); + LOG_DEVEL(LOG_LEVEL_ERROR, "no IRP found with FileId = %d", FileId); return -1; } #endif @@ -1474,12 +1453,12 @@ irp->fuse_info = fusep; return devredir_send_drive_close_request(RDPDR_CTYP_CORE, - PAKID_CORE_DEVICE_IOREQUEST, - device_id, - FileId, - irp->CompletionId, - IRP_MJ_CLOSE, - IRP_MN_NONE, 32); + PAKID_CORE_DEVICE_IOREQUEST, + device_id, + FileId, + irp->CompletionId, + IRP_MJ_CLOSE, + IRP_MN_NONE, 32); } /** @@ -1518,9 +1497,9 @@ CreateDisposition = 0x01; /* got this value from windows */ rval = devredir_send_drive_create_request(device_id, path, - DesiredAccess, CreateOptions, - 0, CreateDisposition, - irp->CompletionId); + DesiredAccess, CreateOptions, + 0, CreateDisposition, + irp->CompletionId); } return rval; @@ -1529,10 +1508,10 @@ /** * Read data from previously opened file * - * @return 0 on success, -1 on failure + * Errors are reported via xfuse_devredir_cb_read_file() *****************************************************************************/ -int +void devredir_file_read(struct state_read *fusep, tui32 DeviceId, tui32 FileId, tui32 Length, tui64 Offset) { @@ -1540,22 +1519,21 @@ IRP *irp; IRP *new_irp; int bytes; - int rval = -1; xstream_new(s, 1024); /* Check we've got an open IRP for this file already */ if ((irp = devredir_irp_find_by_fileid(FileId)) == NULL) { - log_error("no IRP found with FileId = %d", FileId); - xfuse_devredir_cb_read_file(fusep, NULL, 0); + LOG_DEVEL(LOG_LEVEL_ERROR, "no IRP found with FileId = %d", FileId); + xfuse_devredir_cb_read_file(fusep, STATUS_UNSUCCESSFUL, NULL, 0); xstream_free(s); } /* create a new IRP for this request */ else if ((new_irp = devredir_irp_new()) == NULL) { /* system out of memory */ - xfuse_devredir_cb_read_file(fusep, NULL, 0); + xfuse_devredir_cb_read_file(fusep, STATUS_UNSUCCESSFUL, NULL, 0); xstream_free(s); } else @@ -1581,13 +1559,16 @@ bytes = xstream_len(s); send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); - rval = 0; } - - return rval; } -int +/** + * Read data from previously opened file + * + * Errors are reported via xfuse_devredir_cb_write_file() + *****************************************************************************/ + +void devredir_file_write(struct state_write *fusep, tui32 DeviceId, tui32 FileId, const char *buf, int Length, tui64 Offset) { @@ -1595,24 +1576,23 @@ IRP *irp; IRP *new_irp; int bytes; - int rval = -1; - log_debug("DeviceId=%d FileId=%d Length=%d Offset=%lld", + LOG_DEVEL(LOG_LEVEL_DEBUG, "DeviceId=%d FileId=%d Length=%d Offset=%lld", DeviceId, FileId, Length, (long long)Offset); xstream_new(s, 1024 + Length); if ((irp = devredir_irp_find_by_fileid(FileId)) == NULL) { - log_error("no IRP found with FileId = %d", FileId); - xfuse_devredir_cb_write_file(fusep, NT_STATUS_UNSUCCESSFUL, 0, 0); + LOG_DEVEL(LOG_LEVEL_ERROR, "no IRP found with FileId = %d", FileId); + xfuse_devredir_cb_write_file(fusep, STATUS_UNSUCCESSFUL, 0, 0); xstream_free(s); } /* create a new IRP for this request */ else if ((new_irp = devredir_irp_new()) == NULL) { /* system out of memory */ - xfuse_devredir_cb_write_file(fusep, NT_STATUS_UNSUCCESSFUL, 0, 0); + xfuse_devredir_cb_write_file(fusep, STATUS_UNSUCCESSFUL, 0, 0); xstream_free(s); } else @@ -1643,10 +1623,8 @@ bytes = xstream_len(s); send_channel_data(g_rdpdr_chan_id, s->data, bytes); xstream_free(s); - rval = 0; } - return rval; } @@ -1661,8 +1639,8 @@ int rval = -1; IRP *irp; unsigned int len; - - log_debug("device_id=%d old_name=%s new_name=%s", + + LOG_DEVEL(LOG_LEVEL_DEBUG, "device_id=%d old_name=%s new_name=%s", device_id, old_name, new_name); /* @@ -1697,10 +1675,10 @@ CreateDisposition = CD_FILE_OPEN; // WAS 1 rval = devredir_send_drive_create_request(device_id, old_name, - DesiredAccess, CreateOptions, - FileAttributes, - CreateDisposition, - irp->CompletionId); + DesiredAccess, CreateOptions, + FileAttributes, + CreateDisposition, + irp->CompletionId); } return rval; @@ -1741,7 +1719,9 @@ while (*cptr != 0) { if (*cptr == '/') + { *cptr = '\\'; + } cptr++; } } @@ -1824,10 +1804,10 @@ struct stream *s; int bytes; - if (IoStatus != NT_STATUS_SUCCESS) + if (IoStatus != STATUS_SUCCESS) { xfuse_devredir_cb_rmdir_or_file((struct state_remove *) irp->fuse_info, - IoStatus); + IoStatus); devredir_irp_delete(irp); return; } @@ -1857,7 +1837,7 @@ xfuse_devredir_cb_rmdir_or_file((struct state_remove *)irp->fuse_info, IoStatus); - if (IoStatus != NT_STATUS_SUCCESS) + if (IoStatus != STATUS_SUCCESS) { devredir_irp_delete(irp); return; @@ -1881,9 +1861,9 @@ int flen; /* FileNameLength */ - if (IoStatus != NT_STATUS_SUCCESS) + if (IoStatus != STATUS_SUCCESS) { - log_debug("rename returned with IoStatus=0x%x", IoStatus); + LOG_DEVEL(LOG_LEVEL_DEBUG, "rename returned with IoStatus=0x%x", IoStatus); xfuse_devredir_cb_rename_file((struct state_rename *)irp->fuse_info, IoStatus); @@ -1893,7 +1873,7 @@ /* Path in unicode needs this much space */ flen = ((g_mbstowcs(NULL, irp->gen.rename.new_name, 0) - * sizeof(twchar)) / 2) + 2; + * sizeof(twchar)) / 2) + 2; sblen = 6 + flen; xstream_new(s, 1024 + flen); @@ -1925,12 +1905,10 @@ static void devredir_proc_cid_rename_file_resp(IRP *irp, enum NTSTATUS IoStatus) { - log_debug("entered"); - xfuse_devredir_cb_rename_file((struct state_rename *)irp->fuse_info, IoStatus); - if (IoStatus != NT_STATUS_SUCCESS) + if (IoStatus != STATUS_SUCCESS) { devredir_irp_delete(irp); return; @@ -1938,11 +1916,11 @@ irp->completion_type = CID_CLOSE; devredir_send_drive_close_request(RDPDR_CTYP_CORE, - PAKID_CORE_DEVICE_IOREQUEST, - irp->DeviceId, - irp->FileId, - irp->CompletionId, - IRP_MJ_CLOSE, IRP_MN_NONE, 32); + PAKID_CORE_DEVICE_IOREQUEST, + irp->DeviceId, + irp->FileId, + irp->CompletionId, + IRP_MJ_CLOSE, IRP_MN_NONE, 32); } @@ -1986,7 +1964,7 @@ tui64 LastWriteTime; tui32 FileAttributes; - log_debug("processing FILE_BASIC_INFORMATION"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "processing FILE_BASIC_INFORMATION"); xstream_seek(s_in, 8); /* CreationTime */ xstream_rd_u64_le(s_in, LastAccessTime); @@ -1994,13 +1972,13 @@ xstream_seek(s_in, 8); /* ChangeTime */ xstream_rd_u32_le(s_in, FileAttributes); - //log_debug("LastAccessTime: 0x%llx", + //LOG_DEVEL(LOG_LEVEL_DEBUG, "LastAccessTime: 0x%llx", // (unsigned long long)LastAccessTime); - //log_debug("LastWriteTime: 0x%llx", + //LOG_DEVEL(LOG_LEVEL_DEBUG, "LastWriteTime: 0x%llx", // (unsigned long long)LastWriteTime); - //log_debug("ChangeTime: 0x%llx", + //LOG_DEVEL(LOG_LEVEL_DEBUG, "ChangeTime: 0x%llx", // (unsigned long long)ChangeTime); - //log_debug("FileAttributes: 0x%x", (unsigned int)FileAttributes); + //LOG_DEVEL(LOG_LEVEL_DEBUG, "FileAttributes: 0x%x", (unsigned int)FileAttributes); /* Save the basic attributes in the IRP */ irp->gen.lookup.fattr.mode = WindowsToLinuxFilePerm(FileAttributes); @@ -2014,10 +1992,10 @@ static void lookup_read_standard_attributes(IRP *irp, struct stream *s_in) { tui64 EndOfFile; - log_debug("processing FILE_STD_INFORMATION"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "processing FILE_STD_INFORMATION"); xstream_seek(s_in, 8); /* AllocationSize */ xstream_rd_u64_le(s_in, EndOfFile); - //log_debug("EndOfFile: %lld", + //LOG_DEVEL(LOG_LEVEL_DEBUG, "EndOfFile: %lld", // (unsigned long long)EndOfFile); irp->gen.lookup.fattr.size = EndOfFile; @@ -2026,12 +2004,12 @@ /* * Completes a lookup request and returns status to the caller. * - * Unless IoStatus is NT_STATUS_SUCCESS, the lookup has failed. + * Unless IoStatus is STATUS_SUCCESS, the lookup has failed. *****************************************************************************/ static void lookup_done(IRP *irp, enum NTSTATUS IoStatus) { - log_debug("Lookup with completion_id=%d returning 0x%x", - irp->CompletionId, IoStatus); + LOG_DEVEL(LOG_LEVEL_DEBUG, "Lookup with completion_id=%d returning 0x%x", + irp->CompletionId, IoStatus); xfuse_devredir_cb_lookup_entry((struct state_lookup *)irp->fuse_info, IoStatus, &irp->gen.lookup.fattr); @@ -2046,11 +2024,11 @@ /* Close the file handle */ irp->completion_type = CID_CLOSE; devredir_send_drive_close_request(RDPDR_CTYP_CORE, - PAKID_CORE_DEVICE_IOREQUEST, - irp->DeviceId, - irp->FileId, - irp->CompletionId, - IRP_MJ_CLOSE, IRP_MN_NONE, 32); + PAKID_CORE_DEVICE_IOREQUEST, + irp->DeviceId, + irp->FileId, + irp->CompletionId, + IRP_MJ_CLOSE, IRP_MN_NONE, 32); } } @@ -2066,17 +2044,17 @@ { tui32 Length; - log_debug("entry state is %d",irp->gen.lookup.state); - if (IoStatus != NT_STATUS_SUCCESS) + LOG_DEVEL(LOG_LEVEL_DEBUG, "entry state is %d", irp->gen.lookup.state); + if (IoStatus != STATUS_SUCCESS) { /* This is common to all setattr states */ - log_debug("last lookup returned with IoStatus=0x%08x", IoStatus); + LOG_DEVEL(LOG_LEVEL_DEBUG, "last lookup returned with IoStatus=0x%08x", IoStatus); lookup_done(irp, IoStatus); } else { /* Read and validate any data we've got queued up */ - switch(irp->gen.lookup.state) + switch (irp->gen.lookup.state) { case E_LOOKUP_GET_FH: /* We've been sent the file ID */ @@ -2090,10 +2068,10 @@ xstream_rd_u32_le(s_in, Length); if (Length != FILE_BASIC_INFORMATION_SIZE) { - log_error("Expected FILE_BASIC_INFORMATION length" + LOG_DEVEL(LOG_LEVEL_ERROR, "Expected FILE_BASIC_INFORMATION length" "%d, got len=%d", FILE_BASIC_INFORMATION_SIZE, Length); - IoStatus = NT_STATUS_UNSUCCESSFUL; + IoStatus = STATUS_UNSUCCESSFUL; lookup_done(irp, IoStatus); } else @@ -2109,10 +2087,10 @@ xstream_rd_u32_le(s_in, Length); if (Length != FILE_STD_INFORMATION_SIZE) { - log_error("Expected FILE_STD_INFORMATION length" + LOG_DEVEL(LOG_LEVEL_ERROR, "Expected FILE_STD_INFORMATION length" "%d, got len=%d", FILE_STD_INFORMATION_SIZE, Length); - IoStatus = NT_STATUS_UNSUCCESSFUL; + IoStatus = STATUS_UNSUCCESSFUL; } else { @@ -2161,7 +2139,7 @@ xstream_wr_u32_le(s, FileBasicInformation); xstream_wr_u32_le(s, FILE_BASIC_INFORMATION_SIZE); - /* buffer length */ + /* buffer length */ xstream_seek(s, 24); /* padding */ xstream_wr_u64_le(s, 0LL); /* CreationTime */ @@ -2194,10 +2172,10 @@ xstream_wr_u32_le(s, FileEndOfFileInformation); xstream_wr_u32_le(s, FILE_END_OF_FILE_INFORMATION_SIZE); - /* buffer length */ + /* buffer length */ xstream_seek(s, 24); /* padding */ xstream_wr_u64_le(s, (tui64)irp->gen.setattr.fattr.size); - /* File size */ + /* File size */ /* send to client */ bytes = xstream_len(s); send_channel_data(g_rdpdr_chan_id, s->data, bytes); @@ -2222,11 +2200,11 @@ /* Close the file handle */ irp->completion_type = CID_CLOSE; devredir_send_drive_close_request(RDPDR_CTYP_CORE, - PAKID_CORE_DEVICE_IOREQUEST, - irp->DeviceId, - irp->FileId, - irp->CompletionId, - IRP_MJ_CLOSE, IRP_MN_NONE, 32); + PAKID_CORE_DEVICE_IOREQUEST, + irp->DeviceId, + irp->FileId, + irp->CompletionId, + IRP_MJ_CLOSE, IRP_MN_NONE, 32); } } @@ -2244,17 +2222,17 @@ TO_SET_ATIME | TO_SET_MTIME) tui32 Length; - log_debug("entry state is %d",irp->gen.setattr.state); - if (IoStatus != NT_STATUS_SUCCESS) + LOG_DEVEL(LOG_LEVEL_DEBUG, "entry state is %d", irp->gen.setattr.state); + if (IoStatus != STATUS_SUCCESS) { /* This is common to all setattr states */ - log_debug("last setattr returned with IoStatus=0x%08x", IoStatus); + LOG_DEVEL(LOG_LEVEL_DEBUG, "last setattr returned with IoStatus=0x%08x", IoStatus); setattr_done(irp, IoStatus); } else { /* Read and validate any data we've got queued up */ - switch(irp->gen.setattr.state) + switch (irp->gen.setattr.state) { case E_SETATTR_GET_FH: /* We've been sent the file ID */ @@ -2266,7 +2244,7 @@ xstream_rd_u32_le(s_in, Length); if (Length != FILE_BASIC_INFORMATION_SIZE) { - log_error("Expected FILE_BASIC_INFORMATION length" + LOG_DEVEL(LOG_LEVEL_ERROR, "Expected FILE_BASIC_INFORMATION length" "%d, got len=%d", FILE_BASIC_INFORMATION_SIZE, Length); } @@ -2280,7 +2258,7 @@ xstream_rd_u32_le(s_in, Length); if (Length != FILE_END_OF_FILE_INFORMATION_SIZE) { - log_error("Expected FILE_END_OF_FILE_INFORMATION length" + LOG_DEVEL(LOG_LEVEL_ERROR, "Expected FILE_END_OF_FILE_INFORMATION length" "%d, got len=%d", FILE_END_OF_FILE_INFORMATION_SIZE, Length); } diff -Nru xrdp-0.9.12/sesman/chansrv/devredir.h xrdp-0.9.15/sesman/chansrv/devredir.h --- xrdp-0.9.12/sesman/chansrv/devredir.h 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/devredir.h 2020-12-28 13:47:13.000000000 +0000 @@ -78,12 +78,13 @@ int devredir_file_close(struct state_close *fusep, tui32 device_id, tui32 file_id); -int devredir_file_read(struct state_read *fusep, tui32 device_id, tui32 FileId, - tui32 Length, tui64 Offset); +void +devredir_file_read(struct state_read *fusep, tui32 device_id, tui32 FileId, + tui32 Length, tui64 Offset); -int +void devredir_file_write(struct state_write *fusep, tui32 DeviceId, tui32 FileId, - const char *buf, int Length, tui64 Offset); + const char *buf, int Length, tui64 Offset); int devredir_file_rename( struct state_rename *fusep, tui32 device_id, diff -Nru xrdp-0.9.12/sesman/chansrv/fifo.c xrdp-0.9.15/sesman/chansrv/fifo.c --- xrdp-0.9.12/sesman/chansrv/fifo.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/fifo.c 2020-12-28 14:03:43.000000000 +0000 @@ -16,7 +16,7 @@ * limitations under the License. */ - /* FIFO implementation to store a pointer to a user struct */ +/* FIFO implementation to store a pointer to a user struct */ /* module based logging */ #if defined(HAVE_CONFIG_H) @@ -26,8 +26,8 @@ #define MODULE_NAME "FIFO " #define LOCAL_DEBUG +#include "chansrv.h" #include "fifo.h" -#include "mlog.h" #include "os_calls.h" /** @@ -39,19 +39,21 @@ * @return 0 on success, -1 on failure *****************************************************************************/ int -fifo_init(FIFO* fp, int num_entries) +fifo_init(FIFO *fp, int num_entries) { - log_debug_high("entered"); + LOG_DEVEL(LOG_LEVEL_TRACE, "entered"); /* validate params */ if (!fp) { - log_debug_high("invalid parameters"); + LOG_DEVEL(LOG_LEVEL_TRACE, "invalid parameters"); return -1; } if (num_entries < 1) + { num_entries = 10; + } fp->rd_ptr = 0; fp->wr_ptr = 0; @@ -60,13 +62,13 @@ if (fp->user_data) { fp->entries = num_entries; - log_debug_low("FIFO created; rd_ptr=%d wr_ptr=%d entries=%d", - fp->rd_ptr, fp->wr_ptr, fp->entries); + LOG_DEVEL(LOG_LEVEL_DEBUG, "FIFO created; rd_ptr=%d wr_ptr=%d entries=%d", + fp->rd_ptr, fp->wr_ptr, fp->entries); return 0; } else { - log_error("FIFO create error; system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "FIFO create error; system out of memory"); fp->entries = 0; return -1; } @@ -80,13 +82,13 @@ * @return 0 on success, -1 on error *****************************************************************************/ int -fifo_deinit(FIFO* fp) +fifo_deinit(FIFO *fp) { - log_debug_high("entered"); + LOG_DEVEL(LOG_LEVEL_TRACE, "entered"); if (!fp) { - log_debug_high("FIFO is null"); + LOG_DEVEL(LOG_LEVEL_TRACE, "FIFO is null"); return -1; } @@ -110,13 +112,13 @@ * @return 1 if FIFO is empty, 0 otherwise *****************************************************************************/ int -fifo_is_empty(FIFO* fp) +fifo_is_empty(FIFO *fp) { - log_debug_high("entered"); + LOG_DEVEL(LOG_LEVEL_TRACE, "entered"); if (!fp) { - log_debug_high("FIFO is null"); + LOG_DEVEL(LOG_LEVEL_TRACE, "FIFO is null"); return 0; } @@ -133,23 +135,25 @@ *****************************************************************************/ int -fifo_insert(FIFO* fp, void* data) +fifo_insert(FIFO *fp, void *data) { - long* lp; + long *lp; int next_val; /* next value for wr_ptr */ int i; - log_debug_high("entered"); + LOG_DEVEL(LOG_LEVEL_TRACE, "entered"); if (!fp) { - log_debug_high("FIFO is null"); + LOG_DEVEL(LOG_LEVEL_TRACE, "FIFO is null"); return -1; } next_val = fp->wr_ptr + 1; if (next_val >= fp->entries) + { next_val = 0; + } if (next_val == fp->rd_ptr) { @@ -157,18 +161,20 @@ lp = (long *) g_malloc(sizeof(long) * (fp->entries + 10), 1); if (!lp) { - log_debug_low("FIFO full; cannot expand, no memory"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "FIFO full; cannot expand, no memory"); return -1; } - log_debug_low("FIFO full, expanding by 10 entries"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "FIFO full, expanding by 10 entries"); /* copy old data new location */ for (i = 0; i < (fp->entries - 1); i++) { lp[i] = fp->user_data[fp->rd_ptr++]; if (fp->rd_ptr >= fp->entries) + { fp->rd_ptr = 0; + } } /* update pointers */ @@ -182,7 +188,7 @@ fp->user_data = lp; } - log_debug_low("inserting data at index %d", fp->wr_ptr); + LOG_DEVEL(LOG_LEVEL_DEBUG, "inserting data at index %d", fp->wr_ptr); fp->user_data[fp->wr_ptr] = (long) data; fp->wr_ptr = next_val; @@ -197,32 +203,32 @@ * * @param data on success, NULL on error *****************************************************************************/ -void* -fifo_remove(FIFO* fp) +void * +fifo_remove(FIFO *fp) { long data; - log_debug_high("entered"); + LOG_DEVEL(LOG_LEVEL_TRACE, "entered"); if (!fp) { - log_debug_high("FIFO is null"); + LOG_DEVEL(LOG_LEVEL_TRACE, "FIFO is null"); return 0; } if (fp->rd_ptr == fp->wr_ptr) { - log_debug_high("FIFO is empty"); + LOG_DEVEL(LOG_LEVEL_TRACE, "FIFO is empty"); return 0; } - log_debug_low("removing data at index %d", fp->rd_ptr); + LOG_DEVEL(LOG_LEVEL_DEBUG, "removing data at index %d", fp->rd_ptr); data = fp->user_data[fp->rd_ptr++]; if (fp->rd_ptr >= fp->entries) { - log_debug_high("FIFO rd_ptr wrapped around"); + LOG_DEVEL(LOG_LEVEL_TRACE, "FIFO rd_ptr wrapped around"); fp->rd_ptr = 0; } @@ -236,24 +242,24 @@ * * @param data on success, NULL on error *****************************************************************************/ -void* -fifo_peek(FIFO* fp) +void * +fifo_peek(FIFO *fp) { - log_debug_high("entered"); + LOG_DEVEL(LOG_LEVEL_TRACE, "entered"); if (!fp) { - log_debug_high("FIFO is null"); + LOG_DEVEL(LOG_LEVEL_TRACE, "FIFO is null"); return 0; } if (fp->rd_ptr == fp->wr_ptr) { - log_debug_high("FIFO is empty"); + LOG_DEVEL(LOG_LEVEL_TRACE, "FIFO is empty"); return 0; } - log_debug_low("peeking data at index %d", fp->rd_ptr); + LOG_DEVEL(LOG_LEVEL_DEBUG, "peeking data at index %d", fp->rd_ptr); return (void *) fp->user_data[fp->rd_ptr]; } diff -Nru xrdp-0.9.12/sesman/chansrv/irp.c xrdp-0.9.15/sesman/chansrv/irp.c --- xrdp-0.9.12/sesman/chansrv/irp.c 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/irp.c 2020-12-28 14:03:43.000000000 +0000 @@ -25,46 +25,12 @@ #include #endif +#include "chansrv.h" #include "parse.h" #include "os_calls.h" +#include "string_calls.h" #include "irp.h" -/* module based logging */ -#define LOG_ERROR 0 -#define LOG_INFO 1 -#define LOG_DEBUG 2 - -#ifndef LOG_LEVEL -#define LOG_LEVEL LOG_ERROR -#endif - -#define log_error(_params...) \ -{ \ - g_write("[%10.10u]: IRP %s: %d : ERROR: ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ -} - -#define log_info(_params...) \ -{ \ - if (LOG_INFO <= LOG_LEVEL) \ - { \ - g_write("[%10.10u]: IRP %s: %d : ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ - } \ -} - -#define log_debug(_params...) \ -{ \ - if (LOG_DEBUG <= LOG_LEVEL) \ - { \ - g_write("[%10.10u]: IRP %s: %d : ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ - } \ -} - IRP *g_irp_head = NULL; /** @@ -73,18 +39,18 @@ * @return new IRP or NULL on error *****************************************************************************/ -IRP * devredir_irp_new(void) +IRP *devredir_irp_new(void) { IRP *irp; IRP *irp_last; - log_debug("entered"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered"); /* create new IRP */ irp = g_new0(IRP, 1); if (irp == NULL) { - log_error("system out of memory!"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory!"); return NULL; } @@ -100,7 +66,7 @@ irp->prev = irp_last; } - log_debug("new IRP=%p", irp); + LOG_DEVEL(LOG_LEVEL_DEBUG, "new IRP=%p", irp); return irp; } @@ -113,10 +79,10 @@ * @return new IRP or NULL on error *****************************************************************************/ -IRP * devredir_irp_with_pathname_new(const char *pathname) +IRP *devredir_irp_with_pathname_new(const char *pathname) { unsigned int len = g_strlen(pathname); - IRP * irp = devredir_irp_with_pathnamelen_new(len); + IRP *irp = devredir_irp_with_pathnamelen_new(len); if (irp != NULL) { g_strcpy(irp->pathname, pathname); @@ -135,18 +101,18 @@ * @return new IRP or NULL on error *****************************************************************************/ -IRP * devredir_irp_with_pathnamelen_new(unsigned int pathnamelen) +IRP *devredir_irp_with_pathnamelen_new(unsigned int pathnamelen) { IRP *irp; IRP *irp_last; - log_debug("entered"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered"); /* create new IRP with space on end for the pathname and a terminator */ irp = (IRP *)g_malloc(sizeof(IRP) + (pathnamelen + 1), 1); if (irp == NULL) { - log_error("system out of memory!"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory!"); return NULL; } @@ -164,7 +130,7 @@ irp->prev = irp_last; } - log_debug("new IRP=%p", irp); + LOG_DEVEL(LOG_LEVEL_DEBUG, "new IRP=%p", irp); return irp; } @@ -179,9 +145,11 @@ IRP *lirp = g_irp_head; if ((irp == NULL) || (lirp == NULL)) + { return -1; + } - log_debug("irp=%p completion_id=%d type=%d", + LOG_DEVEL(LOG_LEVEL_DEBUG, "irp=%p completion_id=%d type=%d", irp, irp->CompletionId, irp->completion_type); devredir_irp_dump(); // LK_TODO @@ -189,13 +157,17 @@ while (lirp) { if (lirp == irp) + { break; + } lirp = lirp->next; } if (lirp == NULL) - return -1; /* did not find specified irp */ + { + return -1; /* did not find specified irp */ + } if (lirp->prev == NULL) { @@ -244,18 +216,18 @@ { if (irp->CompletionId == completion_id) { - log_debug("returning irp=%p", irp); + LOG_DEVEL(LOG_LEVEL_DEBUG, "returning irp=%p", irp); return irp; } irp = irp->next; } - log_debug("returning irp=NULL"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "returning irp=NULL"); return NULL; } -IRP * devredir_irp_find_by_fileid(tui32 FileId) +IRP *devredir_irp_find_by_fileid(tui32 FileId) { IRP *irp = g_irp_head; @@ -263,14 +235,14 @@ { if (irp->FileId == FileId) { - log_debug("returning irp=%p", irp); + LOG_DEVEL(LOG_LEVEL_DEBUG, "returning irp=%p", irp); return irp; } irp = irp->next; } - log_debug("returning irp=NULL"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "returning irp=NULL"); return NULL; } @@ -278,19 +250,21 @@ * Return last IRP in linked list *****************************************************************************/ -IRP * devredir_irp_get_last(void) +IRP *devredir_irp_get_last(void) { IRP *irp = g_irp_head; while (irp) { if (irp->next == NULL) + { break; + } irp = irp->next; } - log_debug("returning irp=%p", irp); + LOG_DEVEL(LOG_LEVEL_DEBUG, "returning irp=%p", irp); return irp; } @@ -298,13 +272,13 @@ { IRP *irp = g_irp_head; - log_debug("------- dumping IRPs --------"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "------- dumping IRPs --------"); while (irp) { - log_debug(" completion_id=%d\tcompletion_type=%d\tFileId=%d", + LOG_DEVEL(LOG_LEVEL_DEBUG, " completion_id=%d\tcompletion_type=%d\tFileId=%d", irp->CompletionId, irp->completion_type, irp->FileId); irp = irp->next; } - log_debug("------- dumping IRPs done ---"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "------- dumping IRPs done ---"); } diff -Nru xrdp-0.9.12/sesman/chansrv/Makefile.am xrdp-0.9.15/sesman/chansrv/Makefile.am --- xrdp-0.9.12/sesman/chansrv/Makefile.am 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/Makefile.am 2020-12-28 14:03:43.000000000 +0000 @@ -51,6 +51,8 @@ chansrv.h \ chansrv_common.c \ chansrv_common.h \ + chansrv_config.c \ + chansrv_config.h \ chansrv_fuse.c \ chansrv_fuse.h \ chansrv_xfs.c \ @@ -66,11 +68,6 @@ fifo.h \ irp.c \ irp.h \ - mlog.h \ - ms-erref.h \ - ms-fscc.h \ - ms-rdpefs.h \ - ms-smb2.h \ rail.c \ rail.h \ smartcard.c \ diff -Nru xrdp-0.9.12/sesman/chansrv/Makefile.in xrdp-0.9.15/sesman/chansrv/Makefile.in --- xrdp-0.9.12/sesman/chansrv/Makefile.in 2019-12-28 12:36:38.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -122,11 +122,12 @@ am__installdirs = "$(DESTDIR)$(sbindir)" PROGRAMS = $(sbin_PROGRAMS) am_xrdp_chansrv_OBJECTS = chansrv.$(OBJEXT) chansrv_common.$(OBJEXT) \ - chansrv_fuse.$(OBJEXT) chansrv_xfs.$(OBJEXT) \ - clipboard.$(OBJEXT) clipboard_file.$(OBJEXT) \ - devredir.$(OBJEXT) fifo.$(OBJEXT) irp.$(OBJEXT) rail.$(OBJEXT) \ - smartcard.$(OBJEXT) smartcard_pcsc.$(OBJEXT) sound.$(OBJEXT) \ - xcommon.$(OBJEXT) audin.$(OBJEXT) + chansrv_config.$(OBJEXT) chansrv_fuse.$(OBJEXT) \ + chansrv_xfs.$(OBJEXT) clipboard.$(OBJEXT) \ + clipboard_file.$(OBJEXT) devredir.$(OBJEXT) fifo.$(OBJEXT) \ + irp.$(OBJEXT) rail.$(OBJEXT) smartcard.$(OBJEXT) \ + smartcard_pcsc.$(OBJEXT) sound.$(OBJEXT) xcommon.$(OBJEXT) \ + audin.$(OBJEXT) xrdp_chansrv_OBJECTS = $(am_xrdp_chansrv_OBJECTS) am__DEPENDENCIES_1 = @XRDP_FUSE_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) @@ -159,12 +160,13 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/audin.Po ./$(DEPDIR)/chansrv.Po \ - ./$(DEPDIR)/chansrv_common.Po ./$(DEPDIR)/chansrv_fuse.Po \ - ./$(DEPDIR)/chansrv_xfs.Po ./$(DEPDIR)/clipboard.Po \ - ./$(DEPDIR)/clipboard_file.Po ./$(DEPDIR)/devredir.Po \ - ./$(DEPDIR)/fifo.Po ./$(DEPDIR)/irp.Po ./$(DEPDIR)/rail.Po \ - ./$(DEPDIR)/smartcard.Po ./$(DEPDIR)/smartcard_pcsc.Po \ - ./$(DEPDIR)/sound.Po ./$(DEPDIR)/xcommon.Po + ./$(DEPDIR)/chansrv_common.Po ./$(DEPDIR)/chansrv_config.Po \ + ./$(DEPDIR)/chansrv_fuse.Po ./$(DEPDIR)/chansrv_xfs.Po \ + ./$(DEPDIR)/clipboard.Po ./$(DEPDIR)/clipboard_file.Po \ + ./$(DEPDIR)/devredir.Po ./$(DEPDIR)/fifo.Po ./$(DEPDIR)/irp.Po \ + ./$(DEPDIR)/rail.Po ./$(DEPDIR)/smartcard.Po \ + ./$(DEPDIR)/smartcard_pcsc.Po ./$(DEPDIR)/sound.Po \ + ./$(DEPDIR)/xcommon.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -375,6 +377,8 @@ chansrv.h \ chansrv_common.c \ chansrv_common.h \ + chansrv_config.c \ + chansrv_config.h \ chansrv_fuse.c \ chansrv_fuse.h \ chansrv_xfs.c \ @@ -390,11 +394,6 @@ fifo.h \ irp.c \ irp.h \ - mlog.h \ - ms-erref.h \ - ms-fscc.h \ - ms-rdpefs.h \ - ms-smb2.h \ rail.c \ rail.h \ smartcard.c \ @@ -512,6 +511,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audin.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chansrv.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chansrv_common.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chansrv_config.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chansrv_fuse.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chansrv_xfs.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clipboard.Po@am__quote@ # am--include-marker @@ -689,6 +689,7 @@ -rm -f ./$(DEPDIR)/audin.Po -rm -f ./$(DEPDIR)/chansrv.Po -rm -f ./$(DEPDIR)/chansrv_common.Po + -rm -f ./$(DEPDIR)/chansrv_config.Po -rm -f ./$(DEPDIR)/chansrv_fuse.Po -rm -f ./$(DEPDIR)/chansrv_xfs.Po -rm -f ./$(DEPDIR)/clipboard.Po @@ -749,6 +750,7 @@ -rm -f ./$(DEPDIR)/audin.Po -rm -f ./$(DEPDIR)/chansrv.Po -rm -f ./$(DEPDIR)/chansrv_common.Po + -rm -f ./$(DEPDIR)/chansrv_config.Po -rm -f ./$(DEPDIR)/chansrv_fuse.Po -rm -f ./$(DEPDIR)/chansrv_xfs.Po -rm -f ./$(DEPDIR)/clipboard.Po diff -Nru xrdp-0.9.12/sesman/chansrv/mlog.h xrdp-0.9.15/sesman/chansrv/mlog.h --- xrdp-0.9.12/sesman/chansrv/mlog.h 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/mlog.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,112 +0,0 @@ -/** - * xrdp: A Remote Desktop Protocol server. - * - * Copyright (C) Laxmikant Rashinkar 2013 LK.Rashinkar@gmail.com - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - /* module based logging */ - -#ifndef _MLOG_H -#define _MLOG_H - -/* - * Note1: to enable debug messages, in your .c file, #define LOCAL_DEBUG - * BEFORE including this file - * - * Note2: in your .c file, #define MODULE_NAME, 8 chars long, to print each - * log entry with your module name - */ - -#define LOG_ERROR 0 -#define LOG_INFO 1 -#define LOG_DEBUG_LOW 2 -#define LOG_DEBUG_HIGH 3 -#define LOG_LEVEL LOG_ERROR - -/* - * print always - */ - -#define log_error(_params...) \ -do \ -{ \ - g_write("[%10.10u]: %s %s: %d: ERROR: ", g_time3(), \ - MODULE_NAME, __func__, __LINE__); \ - g_writeln (_params); \ -} \ -while(0) - -#define log_always(_params...) \ -do \ -{ \ - g_write("[%10.10u]: %s %s: %d: ALWAYS: ", g_time3(), \ - MODULE_NAME, __func__, __LINE__); \ - g_writeln (_params); \ -} \ -while(0) - -/* - * print conditionally - */ - -#ifdef LOCAL_DEBUG -#define log_info(_params...) \ -do \ -{ \ - if (LOG_INFO <= LOG_LEVEL) \ - { \ - g_write("[%10.10u]: %s %s: %d: INFO: ", g_time3(), \ - MODULE_NAME, __func__, __LINE__); \ - g_writeln (_params); \ - } \ -} \ -while(0) -#else -#define log_info(_params...) -#endif - -#ifdef LOCAL_DEBUG -#define log_debug_low(_params...) \ -do \ -{ \ - if (LOG_DEBUG_LOW <= LOG_LEVEL) \ - { \ - g_write("[%10.10u]: %s %s: %d: DEBUG: ", g_time3(), \ - MODULE_NAME, __func__, __LINE__); \ - g_writeln (_params); \ - } \ -} \ -while(0) -#else -#define log_debug_low(_params...) -#endif - -#ifdef LOCAL_DEBUG -#define log_debug_high(_params...) \ -do \ -{ \ - if (LOG_DEBUG_HIGH <= LOG_LEVEL) \ - { \ - g_write("[%10.10u]: %s %s: %d: DEBUG: ", g_time3(), \ - MODULE_NAME, __func__, __LINE__); \ - g_writeln (_params); \ - } \ -} \ -while(0) -#else -#define log_debug_high(_params...) -#endif - -#endif /* #ifndef _MLOG_H */ diff -Nru xrdp-0.9.12/sesman/chansrv/ms-erref.h xrdp-0.9.15/sesman/chansrv/ms-erref.h --- xrdp-0.9.12/sesman/chansrv/ms-erref.h 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/ms-erref.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +0,0 @@ -/** - * xrdp: A Remote Desktop Protocol server. - * - * MS-ERREF : Definitions from [MS-ERREF] - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * References to MS-ERREF are currently correct for v20180912 of that - * document - */ - -#if !defined(MS_ERREF_H) -#define MS_ERREF_H - -/* - * NTSTATUS codes (section 2.3) - */ -enum NTSTATUS -{ - NT_STATUS_SUCCESS = 0x00000000, - NT_STATUS_UNSUCCESSFUL = 0xC0000001, - NT_STATUS_NO_SUCH_FILE = 0xC000000F, - NT_STATUS_ACCESS_DENIED = 0xC0000022, - NT_STATUS_OBJECT_NAME_INVALID = 0xC0000033, - NT_STATUS_OBJECT_NAME_NOT_FOUND = 0xC0000034, - NT_STATUS_SHARING_VIOLATION = 0xC0000043, - NT_STATUS_NO_MORE_FILES = 0x80000006 -}; - -#endif /* MS_ERREF_H */ - - - - diff -Nru xrdp-0.9.12/sesman/chansrv/ms-fscc.h xrdp-0.9.15/sesman/chansrv/ms-fscc.h --- xrdp-0.9.12/sesman/chansrv/ms-fscc.h 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/ms-fscc.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,64 +0,0 @@ -/** - * xrdp: A Remote Desktop Protocol server. - * - * MS-FSCC : Definitions from [MS-FSCC] - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * References to MS-FSCC are currently correct for v20190923 of that - * document - */ - -#if !defined(MS_FSCC_H) -#define MS_FSCC_H - -/* - * File system ioctl codes (section 2.3) - */ -#define FSCTL_DELETE_OBJECT_ID 0x900a0 - -/* - * File information classes (section 2.4) - */ -enum FS_INFORMATION_CLASS -{ - FileAllocationInformation = 19, /* Set */ - FileBasicInformation = 4, /* Query, Set */ - FileBothDirectoryInformation = 3, /* Query */ - FileDirectoryInformation = 1, /* Query */ - FileDispositionInformation = 13, /* Set */ - FileEndOfFileInformation = 20, /* Set */ - FileFullDirectoryInformation = 2, /* Query */ - FileNamesInformation = 12, /* Query */ - FileRenameInformation = 10, /* Set */ - FileStandardInformation = 5 /* Query */ -}; - -/* - * Size of structs above without trailing RESERVED fields (MS-RDPEFS - * 2.2.3.3.8) - */ -#define FILE_BASIC_INFORMATION_SIZE 36 -#define FILE_STD_INFORMATION_SIZE 22 -#define FILE_END_OF_FILE_INFORMATION_SIZE 8 - -/* Windows file attributes (section 2.6) */ -#define W_FILE_ATTRIBUTE_DIRECTORY 0x00000010 -#define W_FILE_ATTRIBUTE_READONLY 0x00000001 -#define W_FILE_ATTRIBUTE_SYSTEM 0x00000004 -#define W_FILE_ATTRIBUTE_NORMAL 0x00000080 - -#endif /* MS_FSCC_H */ - - - diff -Nru xrdp-0.9.12/sesman/chansrv/ms-rdpefs.h xrdp-0.9.15/sesman/chansrv/ms-rdpefs.h --- xrdp-0.9.12/sesman/chansrv/ms-rdpefs.h 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/ms-rdpefs.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,125 +0,0 @@ -/** - * xrdp: A Remote Desktop Protocol server. - * - * MS-RDPEFS : Definitions from [MS-RDPEFS] - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * References to MS-RDPEFS are currently correct for v20180912 of that - * document - */ - -#if !defined(MS_RDPEFS_H) -#define MS_RDPEFS_H - -/* - * RDPDR_HEADER definitions (2.2.1.1) - */ - -/* device redirector core component; most of the packets in this protocol */ -/* are sent under this component ID */ -#define RDPDR_CTYP_CORE 0x4472 - -/* printing component. the packets that use this ID are typically about */ -/* printer cache management and identifying XPS printers */ -#define RDPDR_CTYP_PRN 0x5052 - -/* Server Announce Request, as specified in section 2.2.2.2 */ -#define PAKID_CORE_SERVER_ANNOUNCE 0x496E - -/* Client Announce Reply and Server Client ID Confirm, as specified in */ -/* sections 2.2.2.3 and 2.2.2.6. */ -#define PAKID_CORE_CLIENTID_CONFIRM 0x4343 - -/* Client Name Request, as specified in section 2.2.2.4 */ -#define PAKID_CORE_CLIENT_NAME 0x434E - -/* Client Device List Announce Request, as specified in section 2.2.2.9 */ -#define PAKID_CORE_DEVICELIST_ANNOUNCE 0x4441 - -/* Server Device Announce Response, as specified in section 2.2.2.1 */ -#define PAKID_CORE_DEVICE_REPLY 0x6472 - -/* Device I/O Request, as specified in section 2.2.1.4 */ -#define PAKID_CORE_DEVICE_IOREQUEST 0x4952 - -/* Device I/O Response, as specified in section 2.2.1.5 */ -#define PAKID_CORE_DEVICE_IOCOMPLETION 0x4943 - -/* Server Core Capability Request, as specified in section 2.2.2.7 */ -#define PAKID_CORE_SERVER_CAPABILITY 0x5350 - -/* Client Core Capability Response, as specified in section 2.2.2.8 */ -#define PAKID_CORE_CLIENT_CAPABILITY 0x4350 - -/* Client Drive Device List Remove, as specified in section 2.2.3.2 */ -#define PAKID_CORE_DEVICELIST_REMOVE 0x444D - -/* Add Printer Cachedata, as specified in [MS-RDPEPC] section 2.2.2.3 */ -#define PAKID_PRN_CACHE_DATA 0x5043 - -/* Server User Logged On, as specified in section 2.2.2.5 */ -#define PAKID_CORE_USER_LOGGEDON 0x554C - -/* Server Printer Set XPS Mode, as specified in [MS-RDPEPC] section 2.2.2.2 */ -#define PAKID_PRN_USING_XPS 0x5543 - -/* - * Capability header definitions (2.2.1.2) - */ - -#define CAP_GENERAL_TYPE 0x0001 /* General cap set - GENERAL_CAPS_SET */ -#define CAP_PRINTER_TYPE 0x0002 /* Print cap set - PRINTER_CAPS_SET */ -#define CAP_PORT_TYPE 0x0003 /* Port cap set - PORT_CAPS_SET */ -#define CAP_DRIVE_TYPE 0x0004 /* Drive cap set - DRIVE_CAPS_SET */ -#define CAP_SMARTCARD_TYPE 0x0005 /* Smart card cap set - SMARTCARD_CAPS_SET */ - -/* - * Device announce header (2.2.1.3) - */ -#define RDPDR_DTYP_SERIAL 0x0001 -#define RDPDR_DTYP_PARALLEL 0x0002 -#define RDPDR_DTYP_PRINT 0x0004 -#define RDPDR_DTYP_FILESYSTEM 0x0008 -#define RDPDR_DTYP_SMARTCARD 0x0020 - -/* Device I/O Request definitions (2.2.1.4) */ -/* MajorFunction */ -enum IRP_MJ -{ - IRP_MJ_CREATE = 0x00000000, - IRP_MJ_CLOSE = 0x00000002, - IRP_MJ_READ = 0x00000003, - IRP_MJ_WRITE = 0x00000004, - IRP_MJ_DEVICE_CONTROL = 0x0000000E, - IRP_MJ_QUERY_VOLUME_INFORMATION = 0x0000000A, - IRP_MJ_SET_VOLUME_INFORMATION = 0x0000000B, - IRP_MJ_QUERY_INFORMATION = 0x00000005, - IRP_MJ_SET_INFORMATION = 0x00000006, - IRP_MJ_DIRECTORY_CONTROL = 0x0000000C, - IRP_MJ_LOCK_CONTROL = 0x00000011 -}; - -/* MinorFunction */ -/* Set to zero unless MajorFunction code == IRP_MJ_DIRECTORY_CONTROL */ -enum IRP_MN -{ - IRP_MN_NONE = 0x00000000, /* Name not in MS docs */ - IRP_MN_QUERY_DIRECTORY = 0x00000001, - IRP_MN_NOTIFY_CHANGE_DIRECTORY = 0x00000002 -}; - - -#endif /* MS_RDPEFS_H */ - - diff -Nru xrdp-0.9.12/sesman/chansrv/ms-smb2.h xrdp-0.9.15/sesman/chansrv/ms-smb2.h --- xrdp-0.9.12/sesman/chansrv/ms-smb2.h 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/ms-smb2.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,79 +0,0 @@ -/** - * xrdp: A Remote Desktop Protocol server. - * - * MS-SMB2 : Definitions from [MS-SMB2] - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * References to MS-SMB2 are currently correct for v20190923 of that - * document - */ - -#if !defined(MS_SMB2_H) -#define MS_SMB2_H - -/* SMB2 CREATE request values (section 2.2.13) */ - -/* - * ShareAccess Mask. Currently, this is referred - * to in MS-RDPEFS 2.2.1.4.1 as 'SharedAccess' rather than 'ShareAccess'. - */ -#define SA_FILE_SHARE_READ 0x00000001 -#define SA_FILE_SHARE_WRITE 0x00000002 -#define SA_FILE_SHARE_DELETE 0x00000004 - -/* CreateDisposition Mask */ -#define CD_FILE_SUPERSEDE 0x00000000 -#define CD_FILE_OPEN 0x00000001 -#define CD_FILE_CREATE 0x00000002 -#define CD_FILE_OPEN_IF 0x00000003 -#define CD_FILE_OVERWRITE 0x00000004 -#define CD_FILE_OVERWRITE_IF 0x00000005 - -/* CreateOptions Mask */ -enum CREATE_OPTIONS -{ - CO_FILE_DIRECTORY_FILE = 0x00000001, - CO_FILE_WRITE_THROUGH = 0x00000002, - CO_FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020, - CO_FILE_DELETE_ON_CLOSE = 0x00001000 -}; - -/* - * DesiredAccess Mask (section 2.2.13.1.1) - */ - -#define DA_FILE_READ_DATA 0x00000001 -#define DA_FILE_WRITE_DATA 0x00000002 -#define DA_FILE_APPEND_DATA 0x00000004 -#define DA_FILE_READ_EA 0x00000008 /* rd extended attributes */ -#define DA_FILE_WRITE_EA 0x00000010 /* wr extended attributes */ -#define DA_FILE_EXECUTE 0x00000020 -#define DA_FILE_READ_ATTRIBUTES 0x00000080 -#define DA_FILE_WRITE_ATTRIBUTES 0x00000100 -#define DA_DELETE 0x00010000 -#define DA_READ_CONTROL 0x00020000 /* rd security descriptor */ -#define DA_WRITE_DAC 0x00040000 -#define DA_WRITE_OWNER 0x00080000 -#define DA_SYNCHRONIZE 0x00100000 -#define DA_ACCESS_SYSTEM_SECURITY 0x01000000 -#define DA_MAXIMUM_ALLOWED 0x02000000 -#define DA_GENERIC_ALL 0x10000000 -#define DA_GENERIC_EXECUTE 0x20000000 -#define DA_GENERIC_WRITE 0x40000000 -#define DA_GENERIC_READ 0x80000000 - -#endif /* MS_SMB2_H */ - - - diff -Nru xrdp-0.9.12/sesman/chansrv/pcsc/wrapper/winscard.c xrdp-0.9.15/sesman/chansrv/pcsc/wrapper/winscard.c --- xrdp-0.9.12/sesman/chansrv/pcsc/wrapper/winscard.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/pcsc/wrapper/winscard.c 2020-12-28 14:03:43.000000000 +0000 @@ -73,7 +73,7 @@ /*****************************************************************************/ static int -writeln(const char* format, ...) +writeln(const char *format, ...) { va_list ap; char text[256]; @@ -86,13 +86,13 @@ } #define LLOAD(_func, _type, _name) \ -do { \ - _func = (_type) GetProcAddress(lib, _name); \ - if (_func == 0) \ - { \ - writeln("LLOAD error %s", _name); \ - } \ -} while (0) + do { \ + _func = (_type) GetProcAddress(lib, _name); \ + if (_func == 0) \ + { \ + writeln("LLOAD error %s", _name); \ + } \ + } while (0) static int g_funcs_loaded = 0; diff -Nru xrdp-0.9.12/sesman/chansrv/pcsc/xrdp_pcsc.c xrdp-0.9.15/sesman/chansrv/pcsc/xrdp_pcsc.c --- xrdp-0.9.12/sesman/chansrv/pcsc/xrdp_pcsc.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/pcsc/xrdp_pcsc.c 2020-12-28 14:03:43.000000000 +0000 @@ -63,9 +63,9 @@ #define LLOG_LEVEL 5 #define LLOGLN(_level, _args) \ - do { if (_level < LLOG_LEVEL) { printf _args ; printf("\n"); } } while (0) + do { if (_level < LLOG_LEVEL) { printf _args ; printf("\n"); } } while (0) #define LHEXDUMP(_level, _args) \ - do { if (_level < LLOG_LEVEL) { lhexdump _args ; } } while (0) + do { if (_level < LLOG_LEVEL) { lhexdump _args ; } } while (0) #define SCARD_ESTABLISH_CONTEXT 0x01 #define SCARD_RELEASE_CONTEXT 0x02 @@ -88,16 +88,16 @@ #define SCARD_F_INTERNAL_ERROR ((LONG)0x80100001) #define SET_UINT32(_data, _offset, _val) do { \ - (((BYTE*)(_data)) + (_offset))[0] = ((_val) >> 0) & 0xff; \ - (((BYTE*)(_data)) + (_offset))[1] = ((_val) >> 8) & 0xff; \ - (((BYTE*)(_data)) + (_offset))[2] = ((_val) >> 16) & 0xff; \ - (((BYTE*)(_data)) + (_offset))[3] = ((_val) >> 24) & 0xff; } while (0) + (((BYTE*)(_data)) + (_offset))[0] = ((_val) >> 0) & 0xff; \ + (((BYTE*)(_data)) + (_offset))[1] = ((_val) >> 8) & 0xff; \ + (((BYTE*)(_data)) + (_offset))[2] = ((_val) >> 16) & 0xff; \ + (((BYTE*)(_data)) + (_offset))[3] = ((_val) >> 24) & 0xff; } while (0) #define GET_UINT32(_data, _offset) \ - ((((BYTE*)(_data)) + (_offset))[0] << 0) | \ - ((((BYTE*)(_data)) + (_offset))[1] << 8) | \ - ((((BYTE*)(_data)) + (_offset))[2] << 16) | \ - ((((BYTE*)(_data)) + (_offset))[3] << 24) + ((((BYTE*)(_data)) + (_offset))[0] << 0) | \ + ((((BYTE*)(_data)) + (_offset))[1] << 8) | \ + ((((BYTE*)(_data)) + (_offset))[2] << 16) | \ + ((((BYTE*)(_data)) + (_offset))[3] << 24) #define LMIN(_val1, _val2) (_val1) < (_val2) ? (_val1) : (_val2) #define LMAX(_val1, _val2) (_val1) > (_val2) ? (_val1) : (_val2) @@ -208,7 +208,7 @@ disp[disp_index] = 0; scre[scre_index] = 0; LLOGLN(10, ("get_display_num_from_display: host [%s] disp [%s] scre [%s]", - host, disp, scre)); + host, disp, scre)); rv = atoi(disp); return rv; } @@ -359,7 +359,7 @@ else { LLOGLN(10, ("get_message: lcode %d *code %d", - lcode, *code)); + lcode, *code)); } } else if (recv_rv == 0) @@ -421,7 +421,7 @@ if (connect_to_chansrv() != 0) { LLOGLN(0, ("SCardEstablishContext: error, can not connect " - "to chansrv")); + "to chansrv")); return SCARD_F_INTERNAL_ERROR; } } @@ -515,8 +515,8 @@ LLOGLN(10, ("SCardConnect:")); LLOGLN(10, ("SCardConnect: hContext 0x%8.8x szReader %s dwShareMode %d " - "dwPreferredProtocols %d", - (int)hContext, szReader, (int)dwShareMode, (int)dwPreferredProtocols)); + "dwPreferredProtocols %d", + (int)hContext, szReader, (int)dwShareMode, (int)dwPreferredProtocols)); if (g_sck == -1) { LLOGLN(0, ("SCardConnect: error, not connected")); @@ -559,8 +559,8 @@ *pdwActiveProtocol = GET_UINT32(msg, 4); status = GET_UINT32(msg, 8); LLOGLN(10, ("SCardConnect: got status 0x%8.8x hCard 0x%8.8x " - "dwActiveProtocol %d", - status, (int)*phCard, (int)*pdwActiveProtocol)); + "dwActiveProtocol %d", + status, (int)*phCard, (int)*pdwActiveProtocol)); return status; } @@ -589,7 +589,7 @@ int status; LLOGLN(10, ("SCardDisconnect: hCard 0x%8.8x dwDisposition %d", - (int)hCard, (int)dwDisposition)); + (int)hCard, (int)dwDisposition)); if (g_sck == -1) { LLOGLN(0, ("SCardDisconnect: error, not connected")); @@ -1051,10 +1051,10 @@ offset += 4; SET_UINT32(msg, offset, pioSendPci->dwProtocol); offset += 4; -/* SET_UINT32(msg, offset, pioSendPci->cbPciLength); */ + /* SET_UINT32(msg, offset, pioSendPci->cbPciLength); */ SET_UINT32(msg, offset, 8); offset += 4; -/* extra_len = pioSendPci->cbPciLength - 8; */ + /* extra_len = pioSendPci->cbPciLength - 8; */ extra_len = 0; SET_UINT32(msg, offset, extra_len); offset += 4; @@ -1064,10 +1064,11 @@ offset += 4; memcpy(msg + offset, pbSendBuffer, cbSendLength); offset += cbSendLength; + got_recv_pci = (pioRecvPci != NULL) && (pioRecvPci->cbPciLength >= 8); // TODO figure out why recv pci does not work - if (1 || (pioRecvPci == 0) || (pioRecvPci->cbPciLength < 8)) + got_recv_pci = 0; + if (got_recv_pci == 0) { - got_recv_pci = 0; SET_UINT32(msg, offset, 0); /* dwProtocol */ offset += 4; SET_UINT32(msg, offset, 0); /* cbPciLength */ @@ -1077,7 +1078,6 @@ } else { - got_recv_pci = 1; SET_UINT32(msg, offset, pioRecvPci->dwProtocol); offset += 4; SET_UINT32(msg, offset, pioRecvPci->cbPciLength); @@ -1158,8 +1158,8 @@ SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders, LPDWORD pcchReaders) { - char* msg; - char* reader_names; + char *msg; + char *reader_names; int reader_names_index; int code; int bytes; @@ -1167,7 +1167,6 @@ int status; int offset; int index; - int bytes_groups; int val; int llen; char reader[100]; @@ -1188,15 +1187,19 @@ offset = 0; SET_UINT32(msg, offset, hContext); offset += 4; - bytes_groups = 0; if (mszGroups != 0) { - bytes_groups = strlen(mszGroups); + unsigned int bytes_groups = strlen(mszGroups); + SET_UINT32(msg, offset, bytes_groups); + offset += 4; + memcpy(msg + offset, mszGroups, bytes_groups); + offset += bytes_groups; + } + else + { + SET_UINT32(msg, offset, 0); + offset += 4; } - SET_UINT32(msg, offset, bytes_groups); - offset += 4; - memcpy(msg + offset, mszGroups, bytes_groups); - offset += bytes_groups; val = *pcchReaders; SET_UINT32(msg, offset, val); offset += 4; @@ -1226,7 +1229,7 @@ num_readers = GET_UINT32(msg, offset); offset += 4; LLOGLN(10, ("SCardListReaders: mszReaders %p pcchReaders %p num_readers %d", - mszReaders, pcchReaders, num_readers)); + mszReaders, pcchReaders, num_readers)); reader_names = (char *) malloc(8192); reader_names_index = 0; for (index = 0; index < num_readers; index++) diff -Nru xrdp-0.9.12/sesman/chansrv/rail.c xrdp-0.9.15/sesman/chansrv/rail.c --- xrdp-0.9.12/sesman/chansrv/rail.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/rail.c 2020-12-28 14:03:43.000000000 +0000 @@ -39,6 +39,7 @@ #include "xcommon.h" #include "log.h" #include "os_calls.h" +#include "string_calls.h" #include "thread_calls.h" #include "list.h" @@ -65,7 +66,7 @@ /* for rail_is_another_wm_running */ static int g_rail_running = 1; /* list of valid rail windows */ -static struct list* g_window_list = 0; +static struct list *g_window_list = 0; static int g_got_focus = 0; static int g_focus_counter = 0; @@ -185,7 +186,7 @@ } /*****************************************************************************/ -static struct rail_window_data* +static struct rail_window_data * rail_get_window_data(Window window) { unsigned int bytes; @@ -193,10 +194,10 @@ int actual_format_return; unsigned long nitems_return; unsigned long bytes_after_return; - unsigned char* prop_return; - struct rail_window_data* rv; + unsigned char *prop_return; + struct rail_window_data *rv; - LOG(10, ("chansrv::rail_get_window_data:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_get_window_data:"); rv = 0; actual_type_return = 0; actual_format_return = 0; @@ -213,29 +214,29 @@ } if (nitems_return == bytes) { - rv = (struct rail_window_data*)prop_return; + rv = (struct rail_window_data *)prop_return; } return rv; } /*****************************************************************************/ static int -rail_set_window_data(Window window, struct rail_window_data* rwd) +rail_set_window_data(Window window, struct rail_window_data *rwd) { int bytes; bytes = sizeof(struct rail_window_data); XChangeProperty(g_display, window, g_rwd_atom, XA_STRING, 8, - PropModeReplace, (unsigned char*)rwd, bytes); + PropModeReplace, (unsigned char *)rwd, bytes); return 0; } /*****************************************************************************/ /* get the rail window data, if not exist, try to create it and return */ -static struct rail_window_data* +static struct rail_window_data * rail_get_window_data_safe(Window window) { - struct rail_window_data* rv; + struct rail_window_data *rv; rv = rail_get_window_data(window); if (rv != 0) @@ -283,7 +284,7 @@ int bytes; char *size_ptr; - LOG(10, ("chansrv::rail_send_init:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_send_init:"); make_stream(s); init_stream(s, 8182); out_uint16_le(s, TS_RAIL_ORDER_HANDSHAKE); @@ -337,7 +338,7 @@ int rail_init(void) { - LOG(10, ("chansrv::rail_init:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_init:"); xcommon_init(); return 0; @@ -369,8 +370,8 @@ if (rail_is_another_wm_running()) { - log_message(LOG_LEVEL_ERROR, "rail_init: another window manager " - "is running"); + LOG(LOG_LEVEL_ERROR, "rail_init: another window manager " + "is running"); } list_delete(g_window_list); @@ -382,16 +383,16 @@ if (!XRRQueryExtension(g_display, &g_xrr_event_base, &dummy)) { g_xrr_event_base = 0; - log_message(LOG_LEVEL_ERROR, "rail_init: RandR extension not found"); + LOG(LOG_LEVEL_ERROR, "rail_init: RandR extension not found"); } if (g_xrr_event_base > 0) { - LOG(0, ("rail_init: found RandR extension")); + LOG_DEVEL(LOG_LEVEL_INFO, "rail_init: found RandR extension"); st = XRRQueryVersion(g_display, &ver_maj, &ver_min); if (st) { - LOG(0, ("rail_init: RandR version major %d minor %d", ver_maj, ver_min)); + LOG_DEVEL(LOG_LEVEL_INFO, "rail_init: RandR version major %d minor %d", ver_maj, ver_min); } XRRSelectInput(g_display, g_root_window, RRScreenChangeNotifyMask); } @@ -453,7 +454,7 @@ char *WorkingDir; char *Arguments; - LOG(0, ("chansrv::rail_process_exec:")); + LOG_DEVEL(LOG_LEVEL_INFO, "chansrv::rail_process_exec:"); in_uint16_le(s, flags); in_uint16_le(s, ExeOrFileLength); in_uint16_le(s, WorkingDirLength); @@ -461,23 +462,23 @@ ExeOrFile = read_uni(s, ExeOrFileLength); WorkingDir = read_uni(s, WorkingDirLength); Arguments = read_uni(s, ArgumentsLen); - LOG(10, (" flags 0x%8.8x ExeOrFileLength %d WorkingDirLength %d " - "ArgumentsLen %d ExeOrFile [%s] WorkingDir [%s] " - "Arguments [%s]", flags, ExeOrFileLength, WorkingDirLength, - ArgumentsLen, ExeOrFile, WorkingDir, Arguments)); + LOG(LOG_LEVEL_DEBUG, " flags 0x%8.8x ExeOrFileLength %d WorkingDirLength %d " + "ArgumentsLen %d ExeOrFile [%s] WorkingDir [%s] " + "Arguments [%s]", flags, ExeOrFileLength, WorkingDirLength, + ArgumentsLen, ExeOrFile, WorkingDir, Arguments); if (g_strlen(ExeOrFile) > 0) { rail_startup(); - LOG(10, ("rail_process_exec: pre")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "rail_process_exec: pre"); /* ask main thread to fork */ tc_mutex_lock(g_exec_mutex); g_exec_name = ExeOrFile; g_set_wait_obj(g_exec_event); tc_sem_dec(g_exec_sem); tc_mutex_unlock(g_exec_mutex); - LOG(10, ("rail_process_exec: post")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "rail_process_exec: post"); } g_free(ExeOrFile); @@ -495,7 +496,7 @@ unsigned int nchild; Window r; Window p; - Window* children; + Window *children; XWindowAttributes window_attributes; /* @@ -509,10 +510,10 @@ { XGetWindowAttributes(g_display, children[i], &window_attributes); if (window_attributes.override_redirect && - window_attributes.map_state == IsViewable && - list_index_of(g_window_list, children[i]) >= 0) + window_attributes.map_state == IsViewable && + list_index_of(g_window_list, children[i]) >= 0) { - LOG(10, (" dismiss pop up 0x%8.8lx", children[i])); + LOG_DEVEL(LOG_LEVEL_DEBUG, " dismiss pop up 0x%8.8lx", children[i]); rail_send_key_esc(children[i]); rv = 1; } @@ -528,7 +529,7 @@ { XEvent ce; - LOG(0, ("chansrv::rail_close_window:")); + LOG_DEVEL(LOG_LEVEL_INFO, "chansrv::rail_close_window:"); rail_win_popdown(); @@ -547,12 +548,12 @@ /*****************************************************************************/ void -my_timeout(void* data) +my_timeout(void *data) { - LOG(10, ("my_timeout: g_got_focus %d", g_got_focus)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "my_timeout: g_got_focus %d", g_got_focus); if (g_focus_counter == (int)(long)data) { - LOG(10, ("my_timeout: g_focus_counter %d", g_focus_counter)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "my_timeout: g_focus_counter %d", g_focus_counter); rail_win_popdown(); } } @@ -567,21 +568,21 @@ XWindowAttributes window_attributes; Window transient_for = 0; - LOG(10, ("chansrv::rail_process_activate:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_activate:"); in_uint32_le(s, window_id); in_uint8(s, enabled); index = list_index_of(g_window_list, window_id); if (index < 0) { - LOG(10, ("chansrv::rail_process_activate: window 0x%8.8x not in list", - window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_activate: window 0x%8.8x not in list", + window_id); return 0; } g_focus_counter++; g_got_focus = enabled; - LOG(10, (" window_id 0x%8.8x enabled %d", window_id, enabled)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x enabled %d", window_id, enabled); XGetWindowAttributes(g_display, window_id, &window_attributes); @@ -606,19 +607,21 @@ /* Owner window should be raised up as well */ XRaiseWindow(g_display, transient_for); } - LOG(10, ("chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id); XRaiseWindow(g_display, window_id); - LOG(10, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id); XSetInputFocus(g_display, window_id, RevertToParent, CurrentTime); } - LOG(10, ("chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id); XRaiseWindow(g_display, window_id); - LOG(10, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id); XSetInputFocus(g_display, window_id, RevertToParent, CurrentTime); - } else { - LOG(10, (" window attributes: override_redirect %d", - window_attributes.override_redirect)); - add_timeout(200, my_timeout, (void*)(long)g_focus_counter); + } + else + { + LOG_DEVEL(LOG_LEVEL_DEBUG, " window attributes: override_redirect %d", + window_attributes.override_redirect); + add_timeout(200, my_timeout, (void *)(long)g_focus_counter); } return 0; } @@ -643,7 +646,7 @@ unsigned int nchild; Window r; Window p; - Window* children; + Window *children; XQueryTree(g_display, g_root_window, &r, &p, &children, &nchild); for (i = 0; i < nchild; i++) @@ -672,9 +675,9 @@ { int system_param; - LOG(10, ("chansrv::rail_process_system_param:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_system_param:"); in_uint32_le(s, system_param); - LOG(10, (" system_param 0x%8.8x", system_param)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " system_param 0x%8.8x", system_param); /* * Ask client to re-create the existing rail windows. This is supposed * to be done after handshake and client is initialised properly, we @@ -682,7 +685,7 @@ */ if (system_param == 0x0000002F) /*SPI_SET_WORK_AREA*/ { - LOG(10, (" restore rail windows")); + LOG_DEVEL(LOG_LEVEL_DEBUG, " restore rail windows"); rail_restore_windows(); } return 0; @@ -690,13 +693,13 @@ /*****************************************************************************/ static int -rail_get_property(Display* display, Window target, Atom type, Atom property, - unsigned char** data, unsigned long* count) +rail_get_property(Display *display, Window target, Atom type, Atom property, + unsigned char **data, unsigned long *count) { Atom atom_return; int size; unsigned long nitems, bytes_left; - char* prop_name; + char *prop_name; int ret = XGetWindowProperty(display, target, property, 0l, 1l, False, @@ -705,7 +708,7 @@ if ((ret != Success || nitems < 1) && atom_return == None) { prop_name = XGetAtomName(g_display, property); - LOG(10, (" rail_get_property %s: failed", prop_name)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " rail_get_property %s: failed", prop_name); XFree(prop_name); return 1; } @@ -734,7 +737,7 @@ { unsigned long nitems = 0; int rv = -1; - char* data = 0; + char *data = 0; rail_get_property(g_display, win, g_wm_state, g_wm_state, (unsigned char **)&data, @@ -744,7 +747,7 @@ { rv = *(unsigned long *)data; XFree(data); - LOG(10, (" rail_win_get_state: %d", rv)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " rail_win_get_state: %d", rv); } return rv; @@ -757,7 +760,7 @@ int old_state; unsigned long data[2] = { state, None }; - LOG(10, (" rail_win_set_state: %ld", state)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " rail_win_set_state: %ld", state); /* check whether WM_STATE exists */ old_state = rail_win_get_state(win); if (old_state == -1) @@ -765,7 +768,7 @@ /* create WM_STATE property */ XChangeProperty(g_display, win, g_wm_state, g_wm_state, 32, PropModeAppend, (unsigned char *)data, 2); - LOG(10, (" rail_win_set_state: create WM_STATE property")); + LOG_DEVEL(LOG_LEVEL_DEBUG, " rail_win_set_state: create WM_STATE property"); } else { @@ -819,11 +822,13 @@ static int rail_minmax_window(int window_id, int max) { - LOG(10, ("chansrv::rail_minmax_window 0x%8.8x:", window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_minmax_window 0x%8.8x:", window_id); if (max) { - } else { + } + else + { XUnmapWindow(g_display, window_id); /* change window state to IconicState (3) */ rail_win_set_state(window_id, 0x3); @@ -840,15 +845,15 @@ { XWindowAttributes window_attributes; - LOG(10, ("chansrv::rail_restore_window 0x%8.8x:", window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_restore_window 0x%8.8x:", window_id); XGetWindowAttributes(g_display, window_id, &window_attributes); if (window_attributes.map_state != IsViewable) { XMapWindow(g_display, window_id); } - LOG(10, ("chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id); XRaiseWindow(g_display, window_id); - LOG(10, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id); XSetInputFocus(g_display, window_id, RevertToParent, CurrentTime); return 0; @@ -862,50 +867,50 @@ int command; int index; - LOG(10, ("chansrv::rail_process_system_command:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_system_command:"); in_uint32_le(s, window_id); in_uint16_le(s, command); index = list_index_of(g_window_list, window_id); if (index < 0) { - LOG(10, ("chansrv::rail_process_system_command: window 0x%8.8x not in list", - window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_system_command: window 0x%8.8x not in list", + window_id); return 0; } switch (command) { case SC_SIZE: - LOG(10, (" window_id 0x%8.8x SC_SIZE", window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x SC_SIZE", window_id); break; case SC_MOVE: - LOG(10, (" window_id 0x%8.8x SC_MOVE", window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x SC_MOVE", window_id); break; case SC_MINIMIZE: - LOG(10, (" window_id 0x%8.8x SC_MINIMIZE", window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x SC_MINIMIZE", window_id); rail_minmax_window(window_id, 0); break; case SC_MAXIMIZE: - LOG(10, (" window_id 0x%8.8x SC_MAXIMIZE", window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x SC_MAXIMIZE", window_id); break; case SC_CLOSE: - LOG(10, (" window_id 0x%8.8x SC_CLOSE", window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x SC_CLOSE", window_id); rail_close_window(window_id); break; case SC_KEYMENU: - LOG(10, (" window_id 0x%8.8x SC_KEYMENU", window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x SC_KEYMENU", window_id); break; case SC_RESTORE: - LOG(10, (" window_id 0x%8.8x SC_RESTORE", window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x SC_RESTORE", window_id); rail_restore_window(window_id); break; case SC_DEFAULT: - LOG(10, (" window_id 0x%8.8x SC_DEFAULT", window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x SC_DEFAULT", window_id); break; default: - LOG(10, (" window_id 0x%8.8x unknown command command %d", - window_id, command)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x unknown command command %d", + window_id, command); break; } @@ -918,9 +923,9 @@ { int build_number; - LOG(10, ("chansrv::rail_process_handshake:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_handshake:"); in_uint32_le(s, build_number); - LOG(10, (" build_number 0x%8.8x", build_number)); + LOG(LOG_LEVEL_DEBUG, " build_number 0x%8.8x", build_number); return 0; } @@ -932,12 +937,12 @@ int notify_id; int message; - LOG(10, ("chansrv::rail_process_notify_event:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_notify_event:"); in_uint32_le(s, window_id); in_uint32_le(s, notify_id); in_uint32_le(s, message); - LOG(10, (" window_id 0x%8.8x notify_id 0x%8.8x message 0x%8.8x", - window_id, notify_id, message)); + LOG(LOG_LEVEL_DEBUG, " window_id 0x%8.8x notify_id 0x%8.8x message 0x%8.8x", + window_id, notify_id, message); return 0; } @@ -951,9 +956,9 @@ int right; int bottom; tsi16 si16; - struct rail_window_data* rwd; + struct rail_window_data *rwd; - LOG(10, ("chansrv::rail_process_window_move:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_window_move:"); in_uint32_le(s, window_id); in_uint16_le(s, si16); left = si16; @@ -963,11 +968,11 @@ right = si16; in_uint16_le(s, si16); bottom = si16; - LOG(10, (" window_id 0x%8.8x left %d top %d right %d bottom %d width %d height %d", - window_id, left, top, right, bottom, right - left, bottom - top)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x left %d top %d right %d bottom %d width %d height %d", + window_id, left, top, right, bottom, right - left, bottom - top); XMoveResizeWindow(g_display, window_id, left, top, right - left, bottom - top); - rwd = (struct rail_window_data*) - g_malloc(sizeof(struct rail_window_data), 1); + rwd = (struct rail_window_data *) + g_malloc(sizeof(struct rail_window_data), 1); rwd->x = left; rwd->y = top; rwd->width = right - left; @@ -988,7 +993,7 @@ int pos_y; tsi16 si16; - LOG(10, ("chansrv::rail_process_local_move_size:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_local_move_size:"); in_uint32_le(s, window_id); in_uint16_le(s, is_move_size_start); in_uint16_le(s, move_size_type); @@ -996,9 +1001,9 @@ pos_x = si16; in_uint16_le(s, si16); pos_y = si16; - LOG(10, (" window_id 0x%8.8x is_move_size_start %d move_size_type %d " - "pos_x %d pos_y %d", window_id, is_move_size_start, move_size_type, - pos_x, pos_y)); + LOG(LOG_LEVEL_DEBUG, " window_id 0x%8.8x is_move_size_start %d move_size_type %d " + "pos_x %d pos_y %d", window_id, is_move_size_start, move_size_type, + pos_x, pos_y); return 0; } @@ -1007,7 +1012,7 @@ static int rail_process_min_max_info(struct stream *s, int size) { - LOG(10, ("chansrv::rail_process_min_max_info:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_min_max_info:"); return 0; } @@ -1017,9 +1022,9 @@ { int flags; - LOG(10, ("chansrv::rail_process_client_status:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_client_status:"); in_uint32_le(s, flags); - LOG(10, (" flags 0x%8.8x", flags)); + LOG(LOG_LEVEL_DEBUG, " flags 0x%8.8x", flags); return 0; } @@ -1032,13 +1037,13 @@ int top; tsi16 si16; - LOG(10, ("chansrv::rail_process_sys_menu:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_sys_menu:"); in_uint32_le(s, window_id); in_uint16_le(s, si16); left = si16; in_uint16_le(s, si16); top = si16; - LOG(10, (" window_id 0x%8.8x left %d top %d", window_id, left, top)); + LOG(LOG_LEVEL_DEBUG, " window_id 0x%8.8x left %d top %d", window_id, left, top); return 0; } @@ -1048,9 +1053,9 @@ { int language_bar_status; - LOG(10, ("chansrv::rail_process_lang_bar_info:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_lang_bar_info:"); in_uint32_le(s, language_bar_status); - LOG(10, (" language_bar_status 0x%8.8x", language_bar_status)); + LOG(LOG_LEVEL_DEBUG, " language_bar_status 0x%8.8x", language_bar_status); return 0; } @@ -1058,7 +1063,7 @@ static int rail_process_appid_req(struct stream *s, int size) { - LOG(10, ("chansrv::rail_process_appid_req:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_appid_req:"); return 0; } @@ -1066,7 +1071,7 @@ static int rail_process_appid_resp(struct stream *s, int size) { - LOG(10, ("chansrv::rail_process_appid_resp:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_appid_resp:"); return 0; } @@ -1075,7 +1080,7 @@ static int rail_process_exec_result(struct stream *s, int size) { - LOG(10, ("chansrv::rail_process_exec_result:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_exec_result:"); return 0; } @@ -1088,7 +1093,7 @@ int code; int size; - LOG(10, ("chansrv::rail_data_in:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_data_in:"); in_uint8(s, code); in_uint8s(s, 1); in_uint16_le(s, size); @@ -1141,7 +1146,7 @@ rail_process_exec_result(s, size); break; default: - LOG(10, ("rail_data_in: unknown code %d size %d", code, size)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "rail_data_in: unknown code %d size %d", code, size); break; } @@ -1199,12 +1204,12 @@ #define CRC_START(in_crc) (in_crc) = g_crc_seed #define CRC_PASS(in_pixel, in_crc) \ - (in_crc) = g_crc_table[((in_crc) ^ (in_pixel)) & 0xff] ^ ((in_crc) >> 8) + (in_crc) = g_crc_table[((in_crc) ^ (in_pixel)) & 0xff] ^ ((in_crc) >> 8) #define CRC_END(in_crc) (in_crc) = ((in_crc) ^ g_crc_seed) /*****************************************************************************/ static int -get_string_crc(const char* text) +get_string_crc(const char *text) { int index; int crc; @@ -1225,14 +1230,14 @@ static int rail_win_send_text(Window win) { - char* data = 0; - struct stream* s; + char *data = 0; + struct stream *s; int len = 0; int flags; int crc; - struct rail_window_data* rwd; + struct rail_window_data *rwd; - LOG(10, ("chansrv::rail_win_send_text:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_win_send_text:"); len = rail_win_get_text(win, &data); rwd = rail_get_window_data_safe(win); if (rwd != 0) @@ -1244,7 +1249,7 @@ crc = get_string_crc(data); if (rwd->title_crc == crc) { - LOG(10, ("chansrv::rail_win_send_text: skipping, title not changed")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_win_send_text: skipping, title not changed"); g_free(data); XFree(rwd); return 0; @@ -1254,14 +1259,14 @@ } else { - LOG(0, ("chansrv::rail_win_send_text: error rail_get_window_data_safe failed")); + LOG_DEVEL(LOG_LEVEL_ERROR, "chansrv::rail_win_send_text: error rail_get_window_data_safe failed"); g_free(data); return 1; } if (data && len > 0) { - LOG(10, ("chansrv::rail_win_send_text: 0x%8.8lx text %s length %d", - win, data, len)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_win_send_text: 0x%8.8lx text %s length %d", + win, data, len); make_stream(s); init_stream(s, len + 1024); flags = WINDOW_ORDER_TYPE_WINDOW | WINDOW_ORDER_FIELD_TITLE; @@ -1290,7 +1295,7 @@ { struct stream *s; - LOG(10, ("chansrv::rail_destroy_window 0x%8.8lx", window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_destroy_window 0x%8.8lx", window_id); make_stream(s); init_stream(s, 1024); @@ -1308,9 +1313,9 @@ rail_show_window(Window window_id, int show_state) { int flags; - struct stream* s; + struct stream *s; - LOG(10, ("chansrv::rail_show_window 0x%8.8lx 0x%x", window_id, show_state)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_show_window 0x%8.8lx 0x%x", window_id, show_state); make_stream(s); init_stream(s, 1024); @@ -1336,7 +1341,7 @@ tui32 border; Window root; tui32 depth; - char* title_bytes = 0; + char *title_bytes = 0; int title_size = 0; XWindowAttributes attributes; int style; @@ -1349,34 +1354,34 @@ int index; int crc; Window transient_for = 0; - struct rail_window_data* rwd; - struct stream* s; + struct rail_window_data *rwd; + struct stream *s; - LOG(10, ("chansrv::rail_create_window 0x%8.8lx", window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_create_window 0x%8.8lx", window_id); rwd = rail_get_window_data_safe(window_id); if (rwd == 0) { - LOG(0, ("chansrv::rail_create_window: error rail_get_window_data_safe failed")); + LOG_DEVEL(LOG_LEVEL_ERROR, "chansrv::rail_create_window: error rail_get_window_data_safe failed"); return 0; } XGetGeometry(g_display, window_id, &root, &x, &y, &width, &height, &border, &depth); XGetWindowAttributes(g_display, window_id, &attributes); - LOG(10, (" x %d y %d width %d height %d border_width %d", x, y, width, - height, border)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " x %d y %d width %d height %d border_width %d", x, y, width, + height, border); index = list_index_of(g_window_list, window_id); if (index == -1) { - LOG(10, (" create new window")); + LOG_DEVEL(LOG_LEVEL_DEBUG, " create new window"); flags = WINDOW_ORDER_TYPE_WINDOW | WINDOW_ORDER_STATE_NEW; list_add_item(g_window_list, window_id); } else { - LOG(10, (" update existing window")); + LOG_DEVEL(LOG_LEVEL_DEBUG, " update existing window"); flags = WINDOW_ORDER_TYPE_WINDOW; } @@ -1416,7 +1421,7 @@ out_uint32_le(s, ext_style); /* extended_style */ flags |= WINDOW_ORDER_FIELD_STYLE; out_uint32_le(s, 0x05); /* show_state */ - LOG(10, (" title %s", title_bytes)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " title %s", title_bytes); flags |= WINDOW_ORDER_FIELD_SHOW; if (title_size > 0) { @@ -1433,7 +1438,7 @@ rwd->valid |= RWD_TITLE; rwd->title_crc = 0; } - LOG(10, (" set title info %d", title_size)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " set title info %d", title_size); flags |= WINDOW_ORDER_FIELD_TITLE; out_uint32_le(s, 0); /* client_offset_x */ out_uint32_le(s, 0); /* client_offset_y */ @@ -1488,7 +1493,7 @@ /*****************************************************************************/ /* returns 0, event handled, 1 unhandled */ int -rail_configure_request_window(XConfigureRequestEvent* config) +rail_configure_request_window(XConfigureRequestEvent *config) { int num_window_rects = 1; int num_visibility_rects = 1; @@ -1498,21 +1503,21 @@ int window_id; int mask; int resized = 0; - struct rail_window_data* rwd; + struct rail_window_data *rwd; - struct stream* s; + struct stream *s; window_id = config->window; mask = config->value_mask; - LOG(10, ("chansrv::rail_configure_request_window: mask %d", mask)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_configure_request_window: mask %d", mask); if (mask & CWStackMode) { - LOG(10, ("chansrv::rail_configure_request_window: CWStackMode " - "detail 0x%8.8x above 0x%8.8lx", config->detail, config->above)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_configure_request_window: CWStackMode " + "detail 0x%8.8x above 0x%8.8lx", config->detail, config->above); if (config->detail == Above) { - LOG(10, ("chansrv::rail_configure_request_window: bring to front " - "window_id 0x%8.8x", window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_configure_request_window: bring to front " + "window_id 0x%8.8x", window_id); /* 0x05 - Show the window in its current size and position. */ rail_show_window(window_id, 5); } @@ -1520,7 +1525,7 @@ rwd = rail_get_window_data(window_id); if (rwd == 0) { - rwd = (struct rail_window_data*)g_malloc(sizeof(struct rail_window_data), 1); + rwd = (struct rail_window_data *)g_malloc(sizeof(struct rail_window_data), 1); rwd->x = config->x; rwd->y = config->y; rwd->width = config->width; @@ -1621,17 +1626,17 @@ return 0; } - LOG(10, ("chansrv::rail_configure_request_window: 0x%8.8x", window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_configure_request_window: 0x%8.8x", window_id); - LOG(10, (" x %d y %d width %d height %d border_width %d", config->x, - config->y, config->width, config->height, config->border_width)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " x %d y %d width %d height %d border_width %d", config->x, + config->y, config->width, config->height, config->border_width); index = list_index_of(g_window_list, window_id); if (index == -1) { /* window isn't mapped yet */ - LOG(0, ("chansrv::rail_configure_request_window: window not mapped")); + LOG_DEVEL(LOG_LEVEL_ERROR, "chansrv::rail_configure_request_window: window not mapped"); return 0; } @@ -1702,15 +1707,15 @@ int index; int window_id; - struct stream* s; + struct stream *s; window_id = config->window; - LOG(10, ("chansrv::rail_configure_window 0x%8.8x", window_id)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_configure_window 0x%8.8x", window_id); - LOG(10, (" x %d y %d width %d height %d border_width %d", config->x, - config->y, config->width, config->height, config->border_width)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " x %d y %d width %d height %d border_width %d", config->x, + config->y, config->width, config->height, config->border_width); index = list_index_of(g_window_list, window_id); if (index == -1) @@ -1778,7 +1783,7 @@ static int rail_desktop_resize(XEvent *lxevent) { - LOG(0, ("rail_desktop_resize:")); + LOG_DEVEL(LOG_LEVEL_INFO, "rail_desktop_resize:"); return 0; } @@ -1793,9 +1798,9 @@ int rv; int index; XWindowAttributes wnd_attributes; - char* prop_name; + char *prop_name; - LOG(10, ("chansrv::rail_xevent:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_xevent:"); if (!g_rail_up) { @@ -1809,9 +1814,9 @@ { case PropertyNotify: prop_name = XGetAtomName(g_display, lxevent->xproperty.atom); - LOG(10, (" got PropertyNotify window_id 0x%8.8lx %s state new %d", - lxevent->xproperty.window, prop_name, - lxevent->xproperty.state == PropertyNewValue)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " got PropertyNotify window_id 0x%8.8lx %s state new %d", + lxevent->xproperty.window, prop_name, + lxevent->xproperty.state == PropertyNewValue); if (list_index_of(g_window_list, lxevent->xproperty.window) < 0) { @@ -1819,7 +1824,7 @@ } if (g_strcmp(prop_name, "WM_NAME") == 0 || - g_strcmp(prop_name, "_NET_WM_NAME") == 0) + g_strcmp(prop_name, "_NET_WM_NAME") == 0) { XGetWindowAttributes(g_display, lxevent->xproperty.window, &wnd_attributes); if (wnd_attributes.map_state == IsViewable) @@ -1832,7 +1837,7 @@ break; case ConfigureRequest: - LOG(10, (" got ConfigureRequest window_id 0x%8.8lx", lxevent->xconfigurerequest.window)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " got ConfigureRequest window_id 0x%8.8lx", lxevent->xconfigurerequest.window); g_memset(&xwc, 0, sizeof(xwc)); xwc.x = lxevent->xconfigurerequest.x; xwc.y = lxevent->xconfigurerequest.y; @@ -1850,14 +1855,14 @@ break; case CreateNotify: - LOG(10, (" got CreateNotify window 0x%8.8lx parent 0x%8.8lx", - lxevent->xcreatewindow.window, lxevent->xcreatewindow.parent)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " got CreateNotify window 0x%8.8lx parent 0x%8.8lx", + lxevent->xcreatewindow.window, lxevent->xcreatewindow.parent); rail_select_input(lxevent->xcreatewindow.window); break; case DestroyNotify: - LOG(10, (" got DestroyNotify window 0x%8.8lx event 0x%8.8lx", - lxevent->xdestroywindow.window, lxevent->xdestroywindow.event)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " got DestroyNotify window 0x%8.8lx event 0x%8.8lx", + lxevent->xdestroywindow.window, lxevent->xdestroywindow.event); if (lxevent->xdestroywindow.window != lxevent->xdestroywindow.event) { break; @@ -1872,13 +1877,13 @@ break; case MapRequest: - LOG(10, (" got MapRequest window 0x%8.8lx", lxevent->xmaprequest.window)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " got MapRequest window 0x%8.8lx", lxevent->xmaprequest.window); XMapWindow(g_display, lxevent->xmaprequest.window); break; case MapNotify: - LOG(10, (" got MapNotify window 0x%8.8lx event 0x%8.8lx", - lxevent->xmap.window, lxevent->xmap.event)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " got MapNotify window 0x%8.8lx event 0x%8.8lx", + lxevent->xmap.window, lxevent->xmap.event); if (lxevent->xmap.window != lxevent->xmap.event) { break; @@ -1903,7 +1908,7 @@ break; case UnmapNotify: - LOG(10, (" got UnmapNotify 0x%8.8lx", lxevent->xunmap.event)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " got UnmapNotify 0x%8.8lx", lxevent->xunmap.event); if (lxevent->xunmap.window != lxevent->xunmap.event) { break; @@ -1911,7 +1916,7 @@ if (is_window_valid_child_of_root(lxevent->xunmap.window)) { index = list_index_of(g_window_list, lxevent->xunmap.window); - LOG(10, (" window 0x%8.8lx is unmapped", lxevent->xunmap.window)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " window 0x%8.8lx is unmapped", lxevent->xunmap.window); if (index >= 0) { XGetWindowAttributes(g_display, lxevent->xunmap.window, &wnd_attributes); @@ -1920,8 +1925,10 @@ // remove popups rail_destroy_window(lxevent->xunmap.window); list_remove_item(g_window_list, index); - } else { - rail_show_window(lxevent->xunmap.window, 0x0); + } + else + { + rail_show_window(lxevent->xunmap.window, 0x0); } rv = 0; @@ -1930,11 +1937,11 @@ break; case ConfigureNotify: - LOG(10, (" got ConfigureNotify 0x%8.8lx event 0x%8.8lx", lxevent->xconfigure.window, - lxevent->xconfigure.event)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " got ConfigureNotify 0x%8.8lx event 0x%8.8lx", lxevent->xconfigure.window, + lxevent->xconfigure.event); rv = 0; if (lxevent->xconfigure.event != lxevent->xconfigure.window || - lxevent->xconfigure.override_redirect) + lxevent->xconfigure.override_redirect) { break; } @@ -1944,7 +1951,7 @@ ConfigureNotify, &lastevent)) { if (lastevent.xconfigure.event == lastevent.xconfigure.window && - lxevent->xconfigure.override_redirect == 0) + lxevent->xconfigure.override_redirect == 0) { lxevent = &lastevent; } @@ -1955,32 +1962,32 @@ break; case FocusIn: - LOG(10, (" got FocusIn")); + LOG_DEVEL(LOG_LEVEL_DEBUG, " got FocusIn"); g_focus_win = lxevent->xfocus.window; break; case FocusOut: - LOG(10, (" got FocusOut")); + LOG_DEVEL(LOG_LEVEL_DEBUG, " got FocusOut"); break; case ButtonPress: - LOG(10, (" got ButtonPress")); + LOG_DEVEL(LOG_LEVEL_DEBUG, " got ButtonPress"); break; case EnterNotify: - LOG(10, (" got EnterNotify")); + LOG_DEVEL(LOG_LEVEL_DEBUG, " got EnterNotify"); break; case LeaveNotify: - LOG(10, (" got LeaveNotify")); + LOG_DEVEL(LOG_LEVEL_DEBUG, " got LeaveNotify"); break; case ReparentNotify: - LOG(10, (" got ReparentNotify window 0x%8.8lx parent 0x%8.8lx " - "event 0x%8.8lx x %d y %d override redirect %d", - lxevent->xreparent.window, lxevent->xreparent.parent, - lxevent->xreparent.event, lxevent->xreparent.x, - lxevent->xreparent.y, lxevent->xreparent.override_redirect)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " got ReparentNotify window 0x%8.8lx parent 0x%8.8lx " + "event 0x%8.8lx x %d y %d override redirect %d", + lxevent->xreparent.window, lxevent->xreparent.parent, + lxevent->xreparent.event, lxevent->xreparent.x, + lxevent->xreparent.y, lxevent->xreparent.override_redirect); if (lxevent->xreparent.window != lxevent->xreparent.event) { diff -Nru xrdp-0.9.12/sesman/chansrv/smartcard.c xrdp-0.9.15/sesman/chansrv/smartcard.c --- xrdp-0.9.12/sesman/chansrv/smartcard.c 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/smartcard.c 2020-12-28 14:03:43.000000000 +0000 @@ -28,6 +28,7 @@ #include #include "os_calls.h" +#include "string_calls.h" #include "smartcard.h" #include "log.h" #include "irp.h" @@ -59,45 +60,6 @@ * if TS Client's build number is >= 4,034 use SCREDIR_VERSION_LONGHORN */ -/* module based logging */ -#define LOG_ERROR 0 -#define LOG_INFO 1 -#define LOG_DEBUG 2 - -#undef LOG_LEVEL -#define LOG_LEVEL LOG_INFO - -#define log_error(_params...) \ -do \ -{ \ - g_write("[%10.10u]: SMART_CARD %s: %d : ERROR: ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ -} while (0) - -#define log_info(_params...) \ -do \ -{ \ - if (LOG_INFO <= LOG_LEVEL) \ - { \ - g_write("[%10.10u]: SMART_CARD %s: %d : ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ - } \ -} while (0) - -#define log_debug(_params...) \ -do \ -{ \ - if (LOG_DEBUG <= LOG_LEVEL) \ - if (2 <= 1) \ - { \ - g_write("[%10.10u]: SMART_CARD %s: %d : ", \ - g_time3(), __func__, __LINE__); \ - g_writeln (_params); \ - } \ -} while (0) - /* [MS-RDPESC] 3.1.4 */ #define SCARD_IOCTL_ESTABLISH_CONTEXT 0x00090014 /* EstablishContext */ #define SCARD_IOCTL_RELEASE_CONTEXT 0x00090018 /* ReleaseContext */ @@ -150,7 +112,7 @@ } SMARTCARD; /* globals */ -SMARTCARD* smartcards[MAX_SMARTCARDS]; +SMARTCARD *smartcards[MAX_SMARTCARDS]; int g_smartcards_inited = 0; static tui32 g_device_id = 0; static int g_scard_index = 0; @@ -163,132 +125,132 @@ /****************************************************************************** ** static functions local to this file ** ******************************************************************************/ -static struct stream * scard_make_new_ioctl(IRP *irp, tui32 ioctl); +static struct stream *scard_make_new_ioctl(IRP *irp, tui32 ioctl); static int scard_add_new_device(tui32 device_id); static int scard_get_free_slot(void); static void scard_release_resources(void); static void scard_send_EstablishContext(IRP *irp, int scope); static void scard_send_ReleaseContext(IRP *irp, - char *context, int context_bytes); -static void scard_send_IsContextValid(IRP* irp, - char *context, int context_bytes); + char *context, int context_bytes); +static void scard_send_IsContextValid(IRP *irp, + char *context, int context_bytes); static void scard_send_ListReaders(IRP *irp, - char *context, int context_bytes, - char *groups, int cchReaders, - int wide); + char *context, int context_bytes, + char *groups, int cchReaders, + int wide); static void scard_send_GetStatusChange(IRP *irp, - char *context, int context_bytes, - int wide, - tui32 timeout, tui32 num_readers, - READER_STATE *rsa); + char *context, int context_bytes, + int wide, + tui32 timeout, tui32 num_readers, + READER_STATE *rsa); static void scard_send_Connect(IRP *irp, - char *context, int context_bytes, - int wide, - READER_STATE *rs); + char *context, int context_bytes, + int wide, + READER_STATE *rs); static void scard_send_Reconnect(IRP *irp, - char *context, int context_bytes, - char *card, int card_bytes, - READER_STATE *rs); + char *context, int context_bytes, + char *card, int card_bytes, + READER_STATE *rs); static void scard_send_BeginTransaction(IRP *irp, - char *context, int context_bytes, - char *card, int card_bytes); + char *context, int context_bytes, + char *card, int card_bytes); static void scard_send_EndTransaction(IRP *irp, - char *context, int context_bytes, - char *card, int card_bytes, - tui32 dwDisposition); + char *context, int context_bytes, + char *card, int card_bytes, + tui32 dwDisposition); static void scard_send_Status(IRP *irp, int wide, - char *context, int context_bytes, - char *card, int card_bytes, - int cchReaderLen, int cbAtrLen); + char *context, int context_bytes, + char *card, int card_bytes, + int cchReaderLen, int cbAtrLen); static void scard_send_Disconnect(IRP *irp, - char *context, int context_bytes, - char *card, int card_bytes, - int dwDisposition); + char *context, int context_bytes, + char *card, int card_bytes, + int dwDisposition); static int scard_send_Transmit(IRP *irp, - char *context, int context_byte, - char *card, int card_bytes, - char *send_data, int send_bytes, - int recv_bytes, - struct xrdp_scard_io_request *send_ior, - struct xrdp_scard_io_request *recv_ior); -static int scard_send_Control(IRP* irp, char *context, int context_bytes, - char *card, int card_bytes, - char *send_data, int send_bytes, - int recv_bytes, int control_code); + char *context, int context_byte, + char *card, int card_bytes, + char *send_data, int send_bytes, + int recv_bytes, + struct xrdp_scard_io_request *send_ior, + struct xrdp_scard_io_request *recv_ior); +static int scard_send_Control(IRP *irp, char *context, int context_bytes, + char *card, int card_bytes, + char *send_data, int send_bytes, + int recv_bytes, int control_code); static int scard_send_Cancel(IRP *irp, char *context, int context_bytes); static int scard_send_GetAttrib(IRP *irp, char *card, int card_bytes, - READER_STATE *rs); + READER_STATE *rs); /****************************************************************************** ** local callbacks into this module ** ******************************************************************************/ static void scard_handle_EstablishContext_Return(struct stream *s, IRP *irp, - tui32 DeviceId, tui32 CompletionId, - tui32 IoStatus); + tui32 DeviceId, tui32 CompletionId, + tui32 IoStatus); static void scard_handle_ReleaseContext_Return(struct stream *s, IRP *irp, - tui32 DeviceId, tui32 CompletionId, - tui32 IoStatus); + tui32 DeviceId, tui32 CompletionId, + tui32 IoStatus); static void scard_handle_IsContextValid_Return(struct stream *s, IRP *irp, - tui32 DeviceId, tui32 CompletionId, - tui32 IoStatus); + tui32 DeviceId, tui32 CompletionId, + tui32 IoStatus); static void scard_handle_ListReaders_Return(struct stream *s, IRP *irp, - tui32 DeviceId, tui32 CompletionId, - tui32 IoStatus); + tui32 DeviceId, tui32 CompletionId, + tui32 IoStatus); static void scard_handle_GetStatusChange_Return(struct stream *s, IRP *irp, - tui32 DeviceId, tui32 CompletionId, - tui32 IoStatus); + tui32 DeviceId, tui32 CompletionId, + tui32 IoStatus); static void scard_handle_Connect_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId, tui32 IoStatus); static void scard_handle_Reconnect_Return(struct stream *s, IRP *irp, - tui32 DeviceId, tui32 CompletionId, - tui32 IoStatus); + tui32 DeviceId, tui32 CompletionId, + tui32 IoStatus); static void scard_handle_BeginTransaction_Return(struct stream *s, IRP *irp, - tui32 DeviceId, tui32 CompletionId, - tui32 IoStatus); + tui32 DeviceId, tui32 CompletionId, + tui32 IoStatus); static void scard_handle_EndTransaction_Return(struct stream *s, IRP *irp, - tui32 DeviceId, - tui32 CompletionId, - tui32 IoStatus); + tui32 DeviceId, + tui32 CompletionId, + tui32 IoStatus); static void scard_handle_Status_Return(struct stream *s, IRP *irp, tui32 DeviceId, tui32 CompletionId, tui32 IoStatus); static void scard_handle_Disconnect_Return(struct stream *s, IRP *irp, - tui32 DeviceId, tui32 CompletionId, - tui32 IoStatus); + tui32 DeviceId, tui32 CompletionId, + tui32 IoStatus); static void scard_handle_Transmit_Return(struct stream *s, IRP *irp, - tui32 DeviceId, - tui32 CompletionId, - tui32 IoStatus); + tui32 DeviceId, + tui32 CompletionId, + tui32 IoStatus); static void scard_handle_Control_Return(struct stream *s, IRP *irp, - tui32 DeviceId, - tui32 CompletionId, - tui32 IoStatus); + tui32 DeviceId, + tui32 CompletionId, + tui32 IoStatus); static void scard_handle_Cancel_Return(struct stream *s, IRP *irp, - tui32 DeviceId, - tui32 CompletionId, - tui32 IoStatus); + tui32 DeviceId, + tui32 CompletionId, + tui32 IoStatus); static void scard_handle_GetAttrib_Return(struct stream *s, IRP *irp, - tui32 DeviceId, - tui32 CompletionId, - tui32 IoStatus); + tui32 DeviceId, + tui32 CompletionId, + tui32 IoStatus); /****************************************************************************** ** ** @@ -301,11 +263,11 @@ void scard_device_announce(tui32 device_id) { - log_debug("entered: device_id=%d", device_id); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: device_id=%d", device_id); if (g_smartcards_inited) { - log_error("already init"); + LOG_DEVEL(LOG_LEVEL_ERROR, "already init"); return; } @@ -315,9 +277,13 @@ g_scard_index = scard_add_new_device(device_id); if (g_scard_index < 0) - log_debug("scard_add_new_device failed with DeviceId=%d", g_device_id); + { + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_add_new_device failed with DeviceId=%d", g_device_id); + } else - log_debug("added smartcard with DeviceId=%d to list", g_device_id); + { + LOG_DEVEL(LOG_LEVEL_DEBUG, "added smartcard with DeviceId=%d to list", g_device_id); + } } /** @@ -344,7 +310,7 @@ int scard_init(void) { - LOG(0, ("scard_init:")); + LOG_DEVEL(LOG_LEVEL_INFO, "scard_init:"); return scard_pcsc_init(); } @@ -354,7 +320,7 @@ int scard_deinit(void) { - LOG(0, ("scard_deinit:")); + LOG_DEVEL(LOG_LEVEL_INFO, "scard_deinit:"); scard_pcsc_deinit(); scard_release_resources(); g_smartcards_inited = 0; @@ -372,7 +338,7 @@ /* setup up IRP */ if ((irp = devredir_irp_new()) == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); return 1; } @@ -400,7 +366,7 @@ /* setup up IRP */ if ((irp = devredir_irp_new()) == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); return 1; } @@ -427,7 +393,7 @@ /* setup up IRP */ if ((irp = devredir_irp_new()) == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); return 1; } @@ -455,7 +421,7 @@ /* setup up IRP */ if ((irp = devredir_irp_new()) == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); return 1; } irp->scard_index = g_scard_index; @@ -483,14 +449,14 @@ int scard_send_get_status_change(void *user_data, char *context, int context_bytes, int wide, tui32 timeout, tui32 num_readers, - READER_STATE* rsa) + READER_STATE *rsa) { IRP *irp; /* setup up IRP */ if ((irp = devredir_irp_new()) == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); return 1; } @@ -515,14 +481,14 @@ *****************************************************************************/ int scard_send_connect(void *user_data, char *context, int context_bytes, - int wide, READER_STATE* rs) + int wide, READER_STATE *rs) { IRP *irp; /* setup up IRP */ if ((irp = devredir_irp_new()) == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); return 1; } @@ -551,14 +517,14 @@ *****************************************************************************/ int scard_send_reconnect(void *user_data, char *context, int context_bytes, - char *card, int card_bytes, READER_STATE* rs) + char *card, int card_bytes, READER_STATE *rs) { IRP *irp; /* setup up IRP */ if ((irp = devredir_irp_new()) == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); return 1; } @@ -582,14 +548,14 @@ *****************************************************************************/ int scard_send_begin_transaction(void *user_data, char *context, int context_bytes, - char *card, int card_bytes) + char *card, int card_bytes) { IRP *irp; /* setup up IRP */ if ((irp = devredir_irp_new()) == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); return 1; } @@ -622,7 +588,7 @@ /* setup up IRP */ if ((irp = devredir_irp_new()) == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); return 1; } @@ -655,7 +621,7 @@ /* setup up IRP */ if ((irp = devredir_irp_new()) == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); return 1; } @@ -687,7 +653,7 @@ /* setup up IRP */ if ((irp = devredir_irp_new()) == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); return 1; } @@ -720,7 +686,7 @@ /* setup up IRP */ if ((irp = devredir_irp_new()) == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); return 1; } @@ -742,7 +708,7 @@ * Communicate directly with the smart card reader *****************************************************************************/ int -scard_send_control(void *user_data, char* context, int context_bytes, +scard_send_control(void *user_data, char *context, int context_bytes, char *card, int card_bytes, char *send_data, int send_bytes, int recv_bytes, int control_code) @@ -752,7 +718,7 @@ /* setup up IRP */ if ((irp = devredir_irp_new()) == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); return 1; } @@ -782,7 +748,7 @@ /* setup up IRP */ if ((irp = devredir_irp_new()) == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); return 1; } @@ -803,14 +769,14 @@ *****************************************************************************/ int scard_send_get_attrib(void *user_data, char *card, int card_bytes, - READER_STATE* rs) + READER_STATE *rs) { IRP *irp; /* setup up IRP */ if ((irp = devredir_irp_new()) == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); return 1; } @@ -900,14 +866,14 @@ if ((index = scard_get_free_slot()) < 0) { - log_error("scard_get_free_slot failed"); + LOG_DEVEL(LOG_LEVEL_ERROR, "scard_get_free_slot failed"); return -1; } sc = g_new0(SMARTCARD, 1); if (sc == NULL) { - log_error("system out of memory"); + LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory"); return -1; } @@ -932,12 +898,12 @@ { if (smartcards[i] == NULL) { - log_debug("found free slot at index %d", i); + LOG_DEVEL(LOG_LEVEL_DEBUG, "found free slot at index %d", i); return i; } } - log_error("too many smart card devices; rejecting this one"); + LOG_DEVEL(LOG_LEVEL_ERROR, "too many smart card devices; rejecting this one"); return -1; } @@ -970,7 +936,7 @@ if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_ESTABLISH_CONTEXT)) == NULL) { - log_error("scard_make_new_ioctl failed"); + LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl failed"); return; } @@ -1013,13 +979,13 @@ if ((sc = smartcards[irp->scard_index]) == NULL) { - log_error("smartcards[%d] is NULL", irp->scard_index); + LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index); return; } if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_RELEASE_CONTEXT)) == NULL) { - log_error("scard_make_new_ioctl failed"); + LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl failed"); return; } @@ -1064,13 +1030,13 @@ if ((sc = smartcards[irp->scard_index]) == NULL) { - log_error("smartcards[%d] is NULL", irp->scard_index); + LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index); return; } if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_IS_VALID_CONTEXT)) == NULL) { - log_error("scard_make_new_ioctl failed"); + LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl failed"); return; } @@ -1134,16 +1100,16 @@ if ((sc = smartcards[irp->scard_index]) == NULL) { - log_error("smartcards[%d] is NULL", irp->scard_index); + LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index); return; } ioctl = (wide) ? SCARD_IOCTL_LIST_READERS_W : - SCARD_IOCTL_LIST_READERS_A; + SCARD_IOCTL_LIST_READERS_A; if ((s = scard_make_new_ioctl(irp, ioctl)) == NULL) { - log_error("scard_make_new_ioctl failed"); + LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl failed"); return; } @@ -1215,10 +1181,7 @@ /* send to client */ send_channel_data(g_rdpdr_chan_id, s->data, bytes); -#if 0 - g_writeln("scard_send_ListReaders:"); - g_hexdump(s->data, bytes); -#endif + LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "scard_send_ListReaders:", s->data, bytes); free_stream(s); } @@ -1248,9 +1211,9 @@ * @param rsa array of READER_STATEs *****************************************************************************/ static void -scard_send_GetStatusChange(IRP* irp, char *context, int context_bytes, +scard_send_GetStatusChange(IRP *irp, char *context, int context_bytes, int wide, tui32 timeout, - tui32 num_readers, READER_STATE* rsa) + tui32 num_readers, READER_STATE *rsa) { /* see [MS-RDPESC] 2.2.2.11 for ASCII */ /* see [MS-RDPESC] 2.2.2.12 for Wide char */ @@ -1267,16 +1230,16 @@ if ((sc = smartcards[irp->scard_index]) == NULL) { - log_error("smartcards[%d] is NULL", irp->scard_index); + LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index); return; } ioctl = (wide) ? SCARD_IOCTL_GET_STATUS_CHANGE_W : - SCARD_IOCTL_GET_STATUS_CHANGE_A; + SCARD_IOCTL_GET_STATUS_CHANGE_A; if ((s = scard_make_new_ioctl(irp, ioctl)) == NULL) { - log_error("scard_make_new_ioctl failed"); + LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl failed"); return; } @@ -1363,10 +1326,7 @@ /* send to client */ send_channel_data(g_rdpdr_chan_id, s->data, bytes); -#if 0 - g_writeln("scard_send_GetStatusChange:"); - g_hexdump(s->data, bytes); -#endif + LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "scard_send_GetStatusChange:", s->data, bytes); free_stream(s); } @@ -1379,14 +1339,14 @@ * @param rs reader state *****************************************************************************/ static void -scard_send_Connect(IRP* irp, char *context, int context_bytes, - int wide, READER_STATE* rs) +scard_send_Connect(IRP *irp, char *context, int context_bytes, + int wide, READER_STATE *rs) { /* see [MS-RDPESC] 2.2.2.13 for ASCII */ /* see [MS-RDPESC] 2.2.2.14 for Wide char */ - SMARTCARD* sc; - struct stream* s; + SMARTCARD *sc; + struct stream *s; tui32 ioctl; int bytes; int num_chars; @@ -1395,16 +1355,16 @@ if ((sc = smartcards[irp->scard_index]) == NULL) { - log_error("smartcards[%d] is NULL", irp->scard_index); + LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index); return; } ioctl = (wide) ? SCARD_IOCTL_CONNECT_W : - SCARD_IOCTL_CONNECT_A; + SCARD_IOCTL_CONNECT_A; if ((s = scard_make_new_ioctl(irp, ioctl)) == NULL) { - log_error("scard_make_new_ioctl failed"); + LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl failed"); return; } @@ -1488,13 +1448,13 @@ if ((sc = smartcards[irp->scard_index]) == NULL) { - log_error("smartcards[%d] is NULL", irp->scard_index); + LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index); return; } if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_RECONNECT)) == NULL) { - log_error("scard_make_new_ioctl failed"); + LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl failed"); return; } @@ -1558,13 +1518,13 @@ if ((sc = smartcards[irp->scard_index]) == NULL) { - log_error("smartcards[%d] is NULL", irp->scard_index); + LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index); return; } if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_BEGIN_TRANSACTION)) == NULL) { - log_error("scard_make_new_ioctl failed"); + LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl failed"); return; } @@ -1626,13 +1586,13 @@ if ((sc = smartcards[irp->scard_index]) == NULL) { - log_error("smartcards[%d] is NULL", irp->scard_index); + LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index); return; } if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_END_TRANSACTION)) == NULL) { - log_error("scard_make_new_ioctl failed"); + LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl failed"); return; } @@ -1694,17 +1654,17 @@ if ((sc = smartcards[irp->scard_index]) == NULL) { - log_error("smartcards[%d] is NULL", irp->scard_index); + LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index); return; } ioctl = wide ? SCARD_IOCTL_STATUS_W : SCARD_IOCTL_STATUS_A; if ((s = scard_make_new_ioctl(irp, ioctl)) == NULL) { - log_error("scard_make_new_ioctl"); + LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl"); return; } -/* + /* 30 00 00 00 00 00 00 00 04 00 00 00 @@ -1719,7 +1679,7 @@ 04 00 00 00 09 00 00 00 hCard 00 00 00 00 -*/ + */ s_push_layer(s, mcs_hdr, 4); /* bytes, set later */ out_uint32_le(s, 0x00000000); out_uint32_le(s, context_bytes); @@ -1754,7 +1714,7 @@ bytes = (int) (s->end - s->data); - //g_hexdump(s->data, bytes); + LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", s->data, bytes); /* send to client */ send_channel_data(g_rdpdr_chan_id, s->data, bytes); @@ -1780,13 +1740,13 @@ if ((sc = smartcards[irp->scard_index]) == NULL) { - log_error("smartcards[%d] is NULL", irp->scard_index); + LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index); return; } if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_DISCONNECT)) == NULL) { - log_error("scard_make_new_ioctl failed"); + LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl failed"); return; } @@ -1848,17 +1808,17 @@ if ((sc = smartcards[irp->scard_index]) == NULL) { - log_error("smartcards[%d] is NULL", irp->scard_index); + LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index); return 1; } if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_TRANSMIT)) == NULL) { - log_error("scard_make_new_ioctl"); + LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl"); return 1; } - log_debug("send_bytes %d recv_bytes %d send dwProtocol %d cbPciLength %d " + LOG_DEVEL(LOG_LEVEL_DEBUG, "send_bytes %d recv_bytes %d send dwProtocol %d cbPciLength %d " "extra_bytes %d recv dwProtocol %d cbPciLength %d extra_bytes %d", send_bytes, recv_bytes, send_ior->dwProtocol, send_ior->cbPciLength, send_ior->extra_bytes, recv_ior->dwProtocol, recv_ior->cbPciLength, @@ -2013,10 +1973,7 @@ /* send to client */ send_channel_data(g_rdpdr_chan_id, s->data, bytes); -#if 0 - g_writeln("scard_send_Transmit:"); - g_hexdump(s->data, bytes); -#endif + LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "scard_send_Transmit:", s->data, bytes); free_stream(s); return 0; @@ -2039,13 +1996,13 @@ if ((sc = smartcards[irp->scard_index]) == NULL) { - log_error("smartcards[%d] is NULL", irp->scard_index); + LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index); return 1; } if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_CONTROL)) == NULL) { - log_error("scard_make_new_ioctl"); + LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl"); return 1; } @@ -2089,7 +2046,7 @@ bytes = (int) (s->end - s->data); - //g_hexdump(s->data, bytes); + LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", s->data, bytes); /* send to client */ send_channel_data(g_rdpdr_chan_id, s->data, bytes); @@ -2112,13 +2069,13 @@ if ((sc = smartcards[irp->scard_index]) == NULL) { - log_error("smartcards[%d] is NULL", irp->scard_index); + LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index); return 1; } if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_CANCEL)) == NULL) { - log_error("scard_make_new_ioctl"); + LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl"); return 1; } @@ -2164,13 +2121,13 @@ if ((sc = smartcards[irp->scard_index]) == NULL) { - log_error("smartcards[%d] is NULL", irp->scard_index); + LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index); return 1; } if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_GETATTRIB)) == NULL) { - log_error("scard_make_new_ioctl"); + LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl"); return 1; } @@ -2230,18 +2187,18 @@ { tui32 len; - log_debug("entered"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered"); /* sanity check */ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) { - log_error("DeviceId/CompletionId do not match those in IRP"); + LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP"); return; } /* get OutputBufferLen */ xstream_rd_u32_le(s, len); scard_function_establish_context_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); - log_debug("leaving"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving"); } /** @@ -2254,18 +2211,18 @@ { tui32 len; - log_debug("entered"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered"); /* sanity check */ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) { - log_error("DeviceId/CompletionId do not match those in IRP"); + LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP"); return; } /* get OutputBufferLen */ xstream_rd_u32_le(s, len); scard_function_release_context_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); - log_debug("leaving"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving"); } /** @@ -2278,12 +2235,12 @@ { tui32 len; - log_debug("entered"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered"); /* sanity check */ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) { - log_error("DeviceId/CompletionId do not match those in IRP"); + LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP"); return; } @@ -2291,7 +2248,7 @@ xstream_rd_u32_le(s, len); scard_function_is_context_valid_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); - log_debug("leaving"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving"); } /** @@ -2304,18 +2261,18 @@ { tui32 len; - log_debug("entered"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered"); /* sanity check */ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) { - log_error("DeviceId/CompletionId do not match those in IRP"); + LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP"); return; } /* get OutputBufferLen */ xstream_rd_u32_le(s, len); scard_function_list_readers_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); - log_debug("leaving"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving"); } /** @@ -2328,18 +2285,18 @@ { tui32 len; - log_debug("entered"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered"); /* sanity check */ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) { - log_error("DeviceId/CompletionId do not match those in IRP"); + LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP"); return; } /* get OutputBufferLen */ xstream_rd_u32_le(s, len); scard_function_get_status_change_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); - log_debug("leaving"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving"); } /** @@ -2352,12 +2309,12 @@ { tui32 len; - log_debug("entered"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered"); /* sanity check */ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) { - log_error("DeviceId/CompletionId do not match those in IRP"); + LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP"); return; } @@ -2367,7 +2324,7 @@ scard_function_connect_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); - log_debug("leaving"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving"); } /** @@ -2380,12 +2337,12 @@ { tui32 len; - log_debug("entered"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered"); /* sanity check */ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) { - log_error("DeviceId/CompletionId do not match those in IRP"); + LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP"); return; } @@ -2393,7 +2350,7 @@ xstream_rd_u32_le(s, len); scard_function_reconnect_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); - log_debug("leaving"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving"); } /** @@ -2406,12 +2363,12 @@ { tui32 len; - log_debug("entered"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered"); /* sanity check */ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) { - log_error("DeviceId/CompletionId do not match those in IRP"); + LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP"); return; } @@ -2419,7 +2376,7 @@ xstream_rd_u32_le(s, len); scard_function_begin_transaction_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); - log_debug("leaving"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving"); } /** @@ -2432,12 +2389,12 @@ { tui32 len; - log_debug("entered"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered"); /* sanity check */ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) { - log_error("DeviceId/CompletionId do not match those in IRP"); + LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP"); return; } @@ -2445,7 +2402,7 @@ xstream_rd_u32_le(s, len); scard_function_end_transaction_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); - log_debug("leaving"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving"); } /** @@ -2458,12 +2415,12 @@ { tui32 len; - log_debug("entered"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered"); /* sanity check */ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) { - log_error("DeviceId/CompletionId do not match those in IRP"); + LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP"); return; } @@ -2471,7 +2428,7 @@ xstream_rd_u32_le(s, len); scard_function_status_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); - log_debug("leaving"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving"); } /** @@ -2484,12 +2441,12 @@ { tui32 len; - log_debug("entered"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered"); /* sanity check */ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) { - log_error("DeviceId/CompletionId do not match those in IRP"); + LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP"); return; } @@ -2497,7 +2454,7 @@ xstream_rd_u32_le(s, len); scard_function_disconnect_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); - log_debug("leaving"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving"); } /** @@ -2509,12 +2466,12 @@ { tui32 len; - log_debug("entered"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered"); /* sanity check */ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) { - log_error("DeviceId/CompletionId do not match those in IRP"); + LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP"); return; } @@ -2522,7 +2479,7 @@ xstream_rd_u32_le(s, len); scard_function_transmit_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); - log_debug("leaving"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving"); } /** @@ -2530,16 +2487,16 @@ *****************************************************************************/ static void scard_handle_Control_Return(struct stream *s, IRP *irp, tui32 DeviceId, - tui32 CompletionId,tui32 IoStatus) + tui32 CompletionId, tui32 IoStatus) { tui32 len; - log_debug("entered"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered"); /* sanity check */ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) { - log_error("DeviceId/CompletionId do not match those in IRP"); + LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP"); return; } @@ -2547,7 +2504,7 @@ xstream_rd_u32_le(s, len); scard_function_control_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); - log_debug("leaving"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving"); } /** @@ -2559,12 +2516,12 @@ { tui32 len; - log_debug("entered"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered"); /* sanity check */ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) { - log_error("DeviceId/CompletionId do not match those in IRP"); + LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP"); return; } @@ -2572,7 +2529,7 @@ xstream_rd_u32_le(s, len); scard_function_cancel_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); - log_debug("leaving"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving"); } /** @@ -2584,12 +2541,12 @@ { tui32 len; - log_debug("entered"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "entered"); /* sanity check */ if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId)) { - log_error("DeviceId/CompletionId do not match those in IRP"); + LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP"); return; } @@ -2597,5 +2554,5 @@ xstream_rd_u32_le(s, len); scard_function_get_attrib_return(irp->user_data, s, len, IoStatus); devredir_irp_delete(irp); - log_debug("leaving"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving"); } diff -Nru xrdp-0.9.12/sesman/chansrv/smartcard_pcsc.c xrdp-0.9.15/sesman/chansrv/smartcard_pcsc.c --- xrdp-0.9.12/sesman/chansrv/smartcard_pcsc.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/smartcard_pcsc.c 2020-12-28 14:03:43.000000000 +0000 @@ -33,6 +33,7 @@ #define PCSC_STANDIN 1 #include "os_calls.h" +#include "string_calls.h" #include "smartcard.h" #include "log.h" #include "irp.h" @@ -43,17 +44,6 @@ #if PCSC_STANDIN -#define LLOG_LEVEL 1 -#define LLOGLN(_level, _args) \ - do \ - { \ - if (_level < LLOG_LEVEL) \ - { \ - g_write("chansrv:smartcard_pcsc [%10.10u]: ", g_time3()); \ - g_writeln _args ; \ - } \ - } \ - while (0) extern int g_display_num; /* in chansrv.c */ @@ -96,7 +86,7 @@ { struct pcsc_uds_client *uds_client; - LLOGLN(10, ("create_uds_client:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "create_uds_client:"); if (con == 0) { return 0; @@ -120,18 +110,18 @@ struct pcsc_uds_client *uds_client; int index; - LLOGLN(10, ("get_uds_client_by_id:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "get_uds_client_by_id:"); if (uds_client_id == 0) { - LLOGLN(10, ("get_uds_client_by_id: uds_client_id zero")); + LOG(LOG_LEVEL_ERROR, "get_uds_client_by_id: uds_client_id is zero"); return 0; } if (g_uds_clients == 0) { - LLOGLN(10, ("get_uds_client_by_id: g_uds_clients is nil")); + LOG(LOG_LEVEL_ERROR, "get_uds_client_by_id: g_uds_clients is nil"); return 0; } - LLOGLN(10, (" count %d", g_uds_clients->count)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " count %d", g_uds_clients->count); for (index = 0; index < g_uds_clients->count; index++) { uds_client = (struct pcsc_uds_client *) @@ -141,8 +131,8 @@ return uds_client; } } - LLOGLN(10, ("get_uds_client_by_id: can't find uds_client_id %d", - uds_client_id)); + LOG(LOG_LEVEL_ERROR, "get_uds_client_by_id: can't find uds_client_id %d", + uds_client_id); return 0; } @@ -184,16 +174,16 @@ int index; int index1; - LLOGLN(10, ("get_pcsc_card_by_app_card:")); - LLOGLN(10, (" app_card %d", app_card)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "get_pcsc_card_by_app_card: app_card %d", + app_card); if (uds_client == 0) { - LLOGLN(0, ("get_pcsc_card_by_app_card: error")); + LOG(LOG_LEVEL_ERROR, "get_pcsc_card_by_app_card: uds_client is null"); return 0; } if (uds_client->contexts == 0) { - LLOGLN(0, ("get_pcsc_card_by_app_card: error")); + LOG(LOG_LEVEL_ERROR, "get_pcsc_card_by_app_card: uds_client->contexts is null"); return 0; } for (index = 0; index < uds_client->contexts->count; index++) @@ -223,7 +213,8 @@ } } } - LLOGLN(0, ("get_pcsc_card_by_app_card: error")); + LOG(LOG_LEVEL_ERROR, "get_pcsc_card_by_app_card: app_card %d " + "not found in uds_client->contexts->cards", app_card); return 0; } @@ -236,7 +227,7 @@ struct pcsc_context *context; struct pcsc_card *card; - LLOGLN(10, ("free_uds_client:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "free_uds_client:"); if (uds_client == 0) { return 0; @@ -263,7 +254,7 @@ } list_delete(context->cards); } - LLOGLN(10, (" left over context %p", context->context)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " left over context %p", context->context); scard_send_cancel(0, context->context, context->context_bytes); scard_send_release_context(0, context->context, context->context_bytes); @@ -284,12 +275,13 @@ { struct pcsc_context *pcscContext; - LLOGLN(10, ("uds_client_add_context:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "uds_client_add_context:"); pcscContext = (struct pcsc_context *) g_malloc(sizeof(struct pcsc_context), 1); if (pcscContext == 0) { - LLOGLN(0, ("uds_client_add_context: error")); + LOG(LOG_LEVEL_ERROR, + "uds_client_add_context: failed to allocate memory for pcsc_context"); return 0; } g_autoinc++; @@ -301,7 +293,9 @@ uds_client->contexts = list_create(); if (uds_client->contexts == 0) { - LLOGLN(0, ("uds_client_add_context: error")); + LOG(LOG_LEVEL_ERROR, + "uds_client_add_context: failed to allocate memory for " + "uds_client->contexts"); return 0; } } @@ -318,13 +312,15 @@ if (uds_client->contexts == 0) { - LLOGLN(0, ("uds_client_remove_context: error")); + LOG(LOG_LEVEL_ERROR, + "uds_client_remove_context: uds_client->contexts is null"); return 1; } index = list_index_of(uds_client->contexts, (tintptr) acontext); if (index < 0) { - LLOGLN(0, ("uds_client_remove_context: error")); + LOG(LOG_LEVEL_ERROR, + "uds_client_remove_context: pcsc_context not found in uds_client->contexts"); return 1; } list_remove_item(uds_client->contexts, index); @@ -340,12 +336,13 @@ { struct pcsc_card *pcscCard; - LLOGLN(10, ("context_add_card: card_bytes %d", card_bytes)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "context_add_card: card_bytes %d", card_bytes); pcscCard = (struct pcsc_card *) g_malloc(sizeof(struct pcsc_card), 1); if (pcscCard == 0) { - LLOGLN(0, ("context_add_card: error")); + LOG(LOG_LEVEL_ERROR, + "context_add_card: failed to allocate memmory for pcsc_card"); return 0; } g_autoinc++; @@ -357,12 +354,13 @@ acontext->cards = list_create(); if (acontext->cards == 0) { - LLOGLN(0, ("context_add_card: error")); + LOG(LOG_LEVEL_ERROR, "context_add_card: failed to allocate " + "memmory for uds_client->contexts->cards"); return 0; } } list_add_item(acontext->cards, (tintptr) pcscCard); - LLOGLN(10, (" new app_card %d", pcscCard->app_card)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " new app_card %d", pcscCard->app_card); return pcscCard; } @@ -373,7 +371,7 @@ struct pcsc_uds_client *uds_client; int index; - LLOGLN(10, ("scard_pcsc_get_wait_objs:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_pcsc_get_wait_objs:"); if (g_lis != 0) { trans_get_wait_objs(g_lis, objs, count); @@ -400,12 +398,13 @@ struct pcsc_uds_client *uds_client; int index; - LLOGLN(10, ("scard_pcsc_check_wait_objs:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_pcsc_check_wait_objs:"); if (g_lis != 0) { if (trans_check_wait_objs(g_lis) != 0) { - LLOGLN(0, ("scard_pcsc_check_wait_objs: g_lis trans_check_wait_objs error")); + LOG(LOG_LEVEL_ERROR, + "scard_pcsc_check_wait_objs: g_lis trans_check_wait_objs error"); } } if (g_uds_clients != 0) @@ -439,10 +438,10 @@ struct pcsc_uds_client *uds_client; void *user_data; - LLOGLN(10, ("scard_process_establish_context:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_establish_context:"); uds_client = (struct pcsc_uds_client *) (con->callback_data); in_uint32_le(in_s, dwScope); - LLOGLN(10, ("scard_process_establish_context: dwScope 0x%8.8x", dwScope)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_establish_context: dwScope 0x%8.8x", dwScope); user_data = (void *) (tintptr) (uds_client->uds_client_id); scard_send_establish_context(user_data, dwScope); return 0; @@ -465,15 +464,16 @@ struct trans *con; struct pcsc_context *lcontext; - LLOGLN(10, ("scard_function_establish_context_return:")); - LLOGLN(10, (" status 0x%8.8x", status)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_establish_context_return:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status); uds_client_id = (int) (tintptr) user_data; uds_client = (struct pcsc_uds_client *) get_uds_client_by_id(uds_client_id); if (uds_client == 0) { - LLOGLN(0, ("scard_function_establish_context_return: " - "get_uds_client_by_id failed")); + LOG(LOG_LEVEL_ERROR, "scard_function_establish_context_return: " + "get_uds_client_by_id failed to find uds_client_id %d", + uds_client_id); return 1; } con = uds_client->con; @@ -486,16 +486,16 @@ in_uint32_le(in_s, context_bytes); if (context_bytes > 16) { - LLOGLN(0, ("scard_function_establish_context_return: opps " - "context_bytes %d", context_bytes)); - g_hexdump(in_s->p, context_bytes); + LOG(LOG_LEVEL_ERROR, "scard_function_establish_context_return: opps " + "context_bytes %d", context_bytes); + LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", in_s->p, context_bytes); return 1; } in_uint8a(in_s, context, context_bytes); lcontext = uds_client_add_context(uds_client, context, context_bytes); app_context = lcontext->app_context; - LLOGLN(10, ("scard_function_establish_context_return: " - "app_context %d", app_context)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_establish_context_return: " + "app_context %d", app_context); } out_s = trans_get_out_s(con, 8192); s_push_layer(out_s, iso_hdr, 8); @@ -519,16 +519,16 @@ struct pcsc_context *lcontext; void *user_data; - LLOGLN(10, ("scard_process_release_context:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_release_context:"); uds_client = (struct pcsc_uds_client *) (con->callback_data); in_uint32_le(in_s, hContext); - LLOGLN(10, ("scard_process_release_context: hContext 0x%8.8x", hContext)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_release_context: hContext 0x%8.8x", hContext); user_data = (void *) (tintptr) (uds_client->uds_client_id); lcontext = get_pcsc_context_by_app_context(uds_client, hContext); if (lcontext == 0) { - LLOGLN(0, ("scard_process_release_context: " - "get_pcsc_context_by_app_context failed")); + LOG(LOG_LEVEL_ERROR, "scard_process_release_context: " + "get_pcsc_context_by_app_context failed"); return 1; } scard_send_release_context(user_data, lcontext->context, @@ -550,15 +550,16 @@ struct pcsc_uds_client *uds_client; struct trans *con; - LLOGLN(10, ("scard_function_release_context_return:")); - LLOGLN(10, (" status 0x%8.8x", status)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_release_context_return:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status); uds_client_id = (int) (tintptr) user_data; uds_client = (struct pcsc_uds_client *) get_uds_client_by_id(uds_client_id); if (uds_client == 0) { - LLOGLN(0, ("scard_function_release_context_return: " - "get_uds_client_by_id failed")); + LOG(LOG_LEVEL_ERROR, "scard_function_release_context_return: " + "get_uds_client_by_id failed to find uds_client_id %d", + uds_client_id); return 1; } con = uds_client->con; @@ -586,27 +587,42 @@ 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; - LLOGLN(10, ("scard_process_list_readers:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_list_readers:"); 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)) + { + LOG(LOG_LEVEL_ERROR, "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)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_list_readers: hContext 0x%8.8x cchReaders %d", + hContext, cchReaders); lcontext = get_pcsc_context_by_app_context(uds_client, hContext); if (lcontext == 0) { - LLOGLN(0, ("scard_process_list_readers: " - "get_pcsc_context_by_app_context failed")); + LOG(LOG_LEVEL_ERROR, "scard_process_list_readers: " + "get_pcsc_context_by_app_context failed"); g_free(groups); return 1; } @@ -615,7 +631,6 @@ pcscListReaders->cchReaders = cchReaders; scard_send_list_readers(pcscListReaders, lcontext->context, lcontext->context_bytes, groups, cchReaders, 1); - g_free(groups); return 0; } @@ -640,13 +655,13 @@ struct trans *con; struct pcsc_list_readers *pcscListReaders; - LLOGLN(10, ("scard_function_list_readers_return:")); - LLOGLN(10, (" status 0x%8.8x", status)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_list_readers_return:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status); pcscListReaders = (struct pcsc_list_readers *) user_data; if (pcscListReaders == 0) { - LLOGLN(0, ("scard_function_list_readers_return: " - "pcscListReaders is nil")); + LOG(LOG_LEVEL_ERROR, "scard_function_list_readers_return: " + "pcscListReaders is nil"); return 1; } uds_client_id = pcscListReaders->uds_client_id; @@ -656,9 +671,9 @@ get_uds_client_by_id(uds_client_id); if (uds_client == 0) { - LLOGLN(0, ("scard_function_list_readers_return: " - "get_uds_client_by_id failed, could not find id %d", - uds_client_id)); + LOG(LOG_LEVEL_ERROR, "scard_function_list_readers_return: " + "get_uds_client_by_id failed, could not find id %d", + uds_client_id); return 1; } con = uds_client->con; @@ -735,22 +750,22 @@ void *user_data; struct pcsc_context *lcontext; - LLOGLN(10, ("scard_process_connect:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_connect:"); uds_client = (struct pcsc_uds_client *) (con->callback_data); g_memset(&rs, 0, sizeof(rs)); in_uint32_le(in_s, hContext); in_uint8a(in_s, rs.reader_name, 100); in_uint32_le(in_s, rs.dwShareMode); in_uint32_le(in_s, rs.dwPreferredProtocols); - LLOGLN(10, ("scard_process_connect: rs.reader_name %s dwShareMode 0x%8.8x " - "dwPreferredProtocols 0x%8.8x", rs.reader_name, rs.dwShareMode, - rs.dwPreferredProtocols)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_connect: rs.reader_name %s dwShareMode 0x%8.8x " + "dwPreferredProtocols 0x%8.8x", rs.reader_name, rs.dwShareMode, + rs.dwPreferredProtocols); user_data = (void *) (tintptr) (uds_client->uds_client_id); lcontext = get_pcsc_context_by_app_context(uds_client, hContext); if (lcontext == 0) { - LLOGLN(0, ("scard_process_connect: " - "get_pcsc_context_by_app_context failed")); + LOG(LOG_LEVEL_ERROR, "scard_process_connect: " + "get_pcsc_context_by_app_context failed"); return 1; } uds_client->connect_context = lcontext; @@ -776,15 +791,16 @@ int card_bytes; struct pcsc_card *lcard; - LLOGLN(10, ("scard_function_connect_return:")); - LLOGLN(10, (" status 0x%8.8x", status)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_connect_return:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status); uds_client_id = (int) (tintptr) user_data; uds_client = (struct pcsc_uds_client *) get_uds_client_by_id(uds_client_id); if (uds_client == 0) { - LLOGLN(0, ("scard_function_connect_return: " - "get_uds_client_by_id failed")); + LOG(LOG_LEVEL_ERROR, "scard_function_connect_return: " + "get_uds_client_by_id failed to find uds_client_id %d", + uds_client_id); return 1; } con = uds_client->con; @@ -801,8 +817,8 @@ lcard = context_add_card(uds_client, uds_client->connect_context, card, card_bytes); hCard = lcard->app_card; - LLOGLN(10, (" hCard %d dwActiveProtocol %d", hCard, - dwActiveProtocol)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " hCard %d dwActiveProtocol %d", hCard, + dwActiveProtocol); } else { @@ -834,7 +850,7 @@ struct pcsc_context *lcontext; struct pcsc_card *lcard; - LLOGLN(10, ("scard_process_disconnect:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_disconnect:"); uds_client = (struct pcsc_uds_client *) (con->callback_data); in_uint32_le(in_s, hCard); in_uint32_le(in_s, dwDisposition); @@ -842,8 +858,8 @@ lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext); if ((lcontext == 0) || (lcard == 0)) { - LLOGLN(0, ("scard_process_disconnect: " - "get_pcsc_card_by_app_card failed")); + LOG(LOG_LEVEL_ERROR, "scard_process_disconnect: " + "get_pcsc_card_by_app_card failed"); return 1; } scard_send_disconnect(user_data, @@ -864,15 +880,16 @@ struct pcsc_uds_client *uds_client; struct trans *con; - LLOGLN(10, ("scard_function_disconnect_return:")); - LLOGLN(10, (" status 0x%8.8x", status)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_disconnect_return:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status); uds_client_id = (int) (tintptr) user_data; uds_client = (struct pcsc_uds_client *) get_uds_client_by_id(uds_client_id); if (uds_client == 0) { - LLOGLN(0, ("scard_function_disconnect_return: " - "get_uds_client_by_id failed")); + LOG(LOG_LEVEL_ERROR, "scard_function_disconnect_return: " + "get_uds_client_by_id failed to find uds_client_id %d", + uds_client_id); return 1; } con = uds_client->con; @@ -898,16 +915,16 @@ struct pcsc_card *lcard; struct pcsc_context *lcontext; - LLOGLN(10, ("scard_process_begin_transaction:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_begin_transaction:"); uds_client = (struct pcsc_uds_client *) (con->callback_data); in_uint32_le(in_s, hCard); - LLOGLN(10, ("scard_process_begin_transaction: hCard 0x%8.8x", hCard)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_begin_transaction: hCard 0x%8.8x", hCard); user_data = (void *) (tintptr) (uds_client->uds_client_id); lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext); if ((lcard == 0) || (lcontext == 0)) { - LLOGLN(0, ("scard_process_begin_transaction: " - "get_pcsc_card_by_app_card failed")); + LOG(LOG_LEVEL_ERROR, "scard_process_begin_transaction: " + "get_pcsc_card_by_app_card failed"); return 1; } scard_send_begin_transaction(user_data, @@ -929,15 +946,16 @@ struct pcsc_uds_client *uds_client; struct trans *con; - LLOGLN(10, ("scard_function_begin_transaction_return:")); - LLOGLN(10, (" status 0x%8.8x", status)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_begin_transaction_return:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status); uds_client_id = (int) (tintptr) user_data; uds_client = (struct pcsc_uds_client *) get_uds_client_by_id(uds_client_id); if (uds_client == 0) { - LLOGLN(0, ("scard_function_begin_transaction_return: " - "get_uds_client_by_id failed")); + LOG(LOG_LEVEL_ERROR, "scard_function_begin_transaction_return: " + "get_uds_client_by_id failed to find uds_client_id %d", + uds_client_id); return 1; } con = uds_client->con; @@ -964,17 +982,17 @@ struct pcsc_card *lcard; struct pcsc_context *lcontext; - LLOGLN(10, ("scard_process_end_transaction:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_end_transaction:"); uds_client = (struct pcsc_uds_client *) (con->callback_data); in_uint32_le(in_s, hCard); in_uint32_le(in_s, dwDisposition); - LLOGLN(10, ("scard_process_end_transaction: hCard 0x%8.8x", hCard)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_end_transaction: hCard 0x%8.8x", hCard); user_data = (void *) (tintptr) (uds_client->uds_client_id); lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext); if ((lcard == 0) || (lcontext == 0)) { - LLOGLN(0, ("scard_process_end_transaction: " - "get_pcsc_card_by_app_card failed")); + LOG(LOG_LEVEL_ERROR, "scard_process_end_transaction: " + "get_pcsc_card_by_app_card failed"); return 1; } scard_send_end_transaction(user_data, @@ -997,15 +1015,16 @@ struct pcsc_uds_client *uds_client; struct trans *con; - LLOGLN(10, ("scard_function_end_transaction_return:")); - LLOGLN(10, (" status 0x%8.8x", status)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_end_transaction_return:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status); uds_client_id = (int) (tintptr) user_data; uds_client = (struct pcsc_uds_client *) get_uds_client_by_id(uds_client_id); if (uds_client == 0) { - LLOGLN(0, ("scard_function_end_transaction_return: " - "get_uds_client_by_id failed")); + LOG(LOG_LEVEL_ERROR, "scard_function_end_transaction_return: " + "get_uds_client_by_id failed to find uds_client_id %d", + uds_client_id); return 1; } con = uds_client->con; @@ -1055,9 +1074,9 @@ struct pcsc_context *lcontext; struct pcsc_transmit *pcscTransmit; - LLOGLN(10, ("scard_process_transmit:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_transmit:"); uds_client = (struct pcsc_uds_client *) (con->callback_data); - LLOGLN(10, ("scard_process_transmit:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_transmit:"); in_uint32_le(in_s, hCard); in_uint32_le(in_s, send_ior.dwProtocol); in_uint32_le(in_s, send_ior.cbPciLength); @@ -1070,16 +1089,16 @@ in_uint32_le(in_s, recv_ior.extra_bytes); in_uint8p(in_s, recv_ior.extra_data, recv_ior.extra_bytes); in_uint32_le(in_s, recv_bytes); - LLOGLN(10, ("scard_process_transmit: send dwProtocol %d cbPciLength %d " - "recv dwProtocol %d cbPciLength %d send_bytes %d ", - send_ior.dwProtocol, send_ior.cbPciLength, recv_ior.dwProtocol, - recv_ior.cbPciLength, send_bytes)); - LLOGLN(10, ("scard_process_transmit: recv_bytes %d", recv_bytes)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_transmit: send dwProtocol %d cbPciLength %d " + "recv dwProtocol %d cbPciLength %d send_bytes %d ", + send_ior.dwProtocol, send_ior.cbPciLength, recv_ior.dwProtocol, + recv_ior.cbPciLength, send_bytes); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_transmit: recv_bytes %d", recv_bytes); lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext); if ((lcard == 0) || (lcontext == 0)) { - LLOGLN(0, ("scard_process_transmit: " - "get_pcsc_card_by_app_card failed")); + LOG(LOG_LEVEL_ERROR, "scard_process_transmit: " + "get_pcsc_card_by_app_card failed"); return 1; } @@ -1114,8 +1133,8 @@ struct trans *con; struct pcsc_transmit *pcscTransmit; - LLOGLN(10, ("scard_function_transmit_return:")); - LLOGLN(10, (" status 0x%8.8x", status)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_transmit_return:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status); pcscTransmit = (struct pcsc_transmit *) user_data; recv_ior = pcscTransmit->recv_ior; uds_client = (struct pcsc_uds_client *) @@ -1124,8 +1143,8 @@ if (uds_client == 0) { - LLOGLN(0, ("scard_function_transmit_return: " - "get_uds_client_by_id failed")); + LOG(LOG_LEVEL_ERROR, "scard_function_transmit_return: " + "get_uds_client_by_id failed"); return 1; } con = uds_client->con; @@ -1158,7 +1177,7 @@ } } - LLOGLN(10, ("scard_function_transmit_return: cbRecvLength %d", cbRecvLength)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_transmit_return: cbRecvLength %d", cbRecvLength); out_s = trans_get_out_s(con, 8192); s_push_layer(out_s, iso_hdr, 8); out_uint32_le(out_s, recv_ior.dwProtocol); @@ -1191,9 +1210,9 @@ struct pcsc_context *lcontext; struct pcsc_card *lcard; - LLOGLN(10, ("scard_process_control:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_control:"); uds_client = (struct pcsc_uds_client *) (con->callback_data); - LLOGLN(10, ("scard_process_control:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_control:"); in_uint32_le(in_s, hCard); in_uint32_le(in_s, control_code); @@ -1205,8 +1224,8 @@ lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext); if ((lcard == 0) || (lcontext == 0)) { - LLOGLN(0, ("scard_process_control: " - "get_pcsc_card_by_app_card failed")); + LOG(LOG_LEVEL_ERROR, "scard_process_control: " + "get_pcsc_card_by_app_card failed"); return 1; } scard_send_control(user_data, lcontext->context, lcontext->context_bytes, @@ -1232,15 +1251,16 @@ struct pcsc_uds_client *uds_client; struct trans *con; - LLOGLN(10, ("scard_function_control_return:")); - LLOGLN(10, (" status 0x%8.8x", status)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_control_return:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status); uds_client_id = (int) (tintptr) user_data; uds_client = (struct pcsc_uds_client *) get_uds_client_by_id(uds_client_id); if (uds_client == 0) { - LLOGLN(0, ("scard_function_control_return: " - "get_uds_client_by_id failed")); + LOG(LOG_LEVEL_ERROR, "scard_function_control_return: " + "get_uds_client_by_id failed to find uds_client_id %d", + uds_client_id); return 1; } con = uds_client->con; @@ -1252,7 +1272,7 @@ in_uint32_le(in_s, cbRecvLength); in_uint8p(in_s, recvBuf, cbRecvLength); } - LLOGLN(10, ("scard_function_control_return: cbRecvLength %d", cbRecvLength)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_control_return: cbRecvLength %d", cbRecvLength); out_s = trans_get_out_s(con, 8192); s_push_layer(out_s, iso_hdr, 8); out_uint32_le(out_s, cbRecvLength); @@ -1286,20 +1306,20 @@ struct pcsc_context *lcontext; struct pcsc_status *pcscStatus; - LLOGLN(10, ("scard_process_status:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_status:"); uds_client = (struct pcsc_uds_client *) (con->callback_data); in_uint32_le(in_s, hCard); in_uint32_le(in_s, cchReaderLen); in_uint32_le(in_s, cbAtrLen); - LLOGLN(10, ("scard_process_status: hCard 0x%8.8x cchReaderLen %d " - "cbAtrLen %d", hCard, cchReaderLen, cbAtrLen)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_status: hCard 0x%8.8x cchReaderLen %d " + "cbAtrLen %d", hCard, cchReaderLen, cbAtrLen); lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext); if ((lcard == 0) || (lcontext == 0)) { - LLOGLN(0, ("scard_process_status: " - "get_pcsc_card_by_app_card failed")); + LOG(LOG_LEVEL_ERROR, "scard_process_status: " + "get_pcsc_card_by_app_card failed"); return 1; } pcscStatus = (struct pcsc_status *) g_malloc(sizeof(struct pcsc_status), 1); @@ -1332,7 +1352,8 @@ static int g_ms2pc[] = { PC_SCARD_UNKNOWN, PC_SCARD_ABSENT, PC_SCARD_PRESENT, PC_SCARD_SWALLOWED, PC_SCARD_POWERED, PC_SCARD_NEGOTIABLE, - PC_SCARD_SPECIFIC }; + PC_SCARD_SPECIFIC + }; /*****************************************************************************/ /* returns error */ @@ -1356,13 +1377,13 @@ struct trans *con; struct pcsc_status *pcscStatus; - LLOGLN(10, ("scard_function_status_return:")); - LLOGLN(10, (" status 0x%8.8x", status)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_status_return:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status); pcscStatus = (struct pcsc_status *) user_data; if (pcscStatus == 0) { - LLOGLN(0, ("scard_function_status_return: pcscStatus is nil")); + LOG(LOG_LEVEL_ERROR, "scard_function_status_return: pcscStatus is nil"); return 1; } @@ -1371,8 +1392,9 @@ get_uds_client_by_id(uds_client_id); if (uds_client == 0) { - LLOGLN(0, ("scard_function_status_return: " - "get_uds_client_by_id failed")); + LOG(LOG_LEVEL_ERROR, "scard_function_status_return: " + "get_uds_client_by_id failed to find uds_client_id %d", + uds_client_id); g_free(pcscStatus); return 1; } @@ -1404,13 +1426,13 @@ } if (dwReaderLen < 1) { - LLOGLN(0, ("scard_function_status_return: dwReaderLen < 1")); + LOG(LOG_LEVEL_ERROR, "scard_function_status_return: dwReaderLen < 1"); dwReaderLen = 1; } if (dwReaderLen > 99) { - LLOGLN(0, ("scard_function_status_return: dwReaderLen too big " - "0x%8.8x", dwReaderLen)); + LOG_DEVEL(LOG_LEVEL_WARNING, "scard_function_status_return: dwReaderLen too big " + "0x%8.8x", dwReaderLen); dwReaderLen = 99; } g_memset(reader_name, 0, sizeof(reader_name)); @@ -1421,9 +1443,9 @@ } g_wcstombs(lreader_name, reader_name, 99); } - LLOGLN(10, ("scard_function_status_return: dwAtrLen %d dwReaderLen %d " - "dwProtocol %d dwState %d name %s", - dwAtrLen, dwReaderLen, dwProtocol, dwState, lreader_name)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_status_return: dwAtrLen %d dwReaderLen %d " + "dwProtocol %d dwState %d name %s", + dwAtrLen, dwReaderLen, dwProtocol, dwState, lreader_name); out_s = trans_get_out_s(con, 8192); s_push_layer(out_s, iso_hdr, 8); dwReaderLen = g_strlen(lreader_name); @@ -1456,14 +1478,14 @@ void *user_data; struct pcsc_context *lcontext; - LLOGLN(10, ("scard_process_get_status_change:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_get_status_change:"); uds_client = (struct pcsc_uds_client *) (con->callback_data); in_uint32_le(in_s, hContext); in_uint32_le(in_s, dwTimeout); in_uint32_le(in_s, cReaders); if ((cReaders < 0) || (cReaders > 16)) { - LLOGLN(0, ("scard_process_get_status_change: bad cReaders %d", cReaders)); + LOG(LOG_LEVEL_ERROR, "scard_process_get_status_change: bad cReaders %d", cReaders); return 1; } rsa = (READER_STATE *) g_malloc(sizeof(READER_STATE) * cReaders, 1); @@ -1471,29 +1493,29 @@ for (index = 0; index < cReaders; index++) { in_uint8a(in_s, rsa[index].reader_name, 100); - LLOGLN(10, ("scard_process_get_status_change: reader_name %s", - rsa[index].reader_name)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_get_status_change: reader_name %s", + rsa[index].reader_name); in_uint32_le(in_s, rsa[index].current_state); - LLOGLN(10, ("scard_process_get_status_change: current_state %d", - rsa[index].current_state)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_get_status_change: current_state %d", + rsa[index].current_state); in_uint32_le(in_s, rsa[index].event_state); - LLOGLN(10, ("scard_process_get_status_change: event_state %d", - rsa[index].event_state)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_get_status_change: event_state %d", + rsa[index].event_state); in_uint32_le(in_s, rsa[index].atr_len); - LLOGLN(10, ("scard_process_get_status_change: atr_len %d", - rsa[index].atr_len)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_get_status_change: atr_len %d", + rsa[index].atr_len); in_uint8a(in_s, rsa[index].atr, 36); } - LLOGLN(10, ("scard_process_get_status_change: hContext 0x%8.8x dwTimeout " - "%d cReaders %d", hContext, dwTimeout, cReaders)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_get_status_change: hContext 0x%8.8x dwTimeout " + "%d cReaders %d", hContext, dwTimeout, cReaders); user_data = (void *) (tintptr) (uds_client->uds_client_id); lcontext = get_pcsc_context_by_app_context(uds_client, hContext); if (lcontext == 0) { - LLOGLN(0, ("scard_process_get_status_change: " - "get_pcsc_context_by_app_context failed")); + LOG(LOG_LEVEL_ERROR, "scard_process_get_status_change: " + "get_pcsc_context_by_app_context failed"); g_free(rsa); return 1; } @@ -1523,15 +1545,16 @@ struct pcsc_uds_client *uds_client; struct trans *con; - LLOGLN(10, ("scard_function_get_status_change_return:")); - LLOGLN(10, (" status 0x%8.8x", status)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_get_status_change_return:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status); uds_client_id = (int) (tintptr) user_data; uds_client = (struct pcsc_uds_client *) get_uds_client_by_id(uds_client_id); if (uds_client == 0) { - LLOGLN(0, ("scard_function_get_status_change_return: " - "get_uds_client_by_id failed")); + LOG(LOG_LEVEL_ERROR, "scard_function_get_status_change_return: " + "get_uds_client_by_id failed to find uds_client_id %d", + uds_client_id); return 1; } con = uds_client->con; @@ -1547,7 +1570,7 @@ { in_uint8s(in_s, 28); in_uint32_le(in_s, cReaders); - LLOGLN(10, (" cReaders %d", cReaders)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " cReaders %d", cReaders); out_uint32_le(out_s, cReaders); if (cReaders > 0) { @@ -1584,16 +1607,16 @@ void *user_data; struct pcsc_context *lcontext; - LLOGLN(10, ("scard_process_cancel:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_cancel:"); uds_client = (struct pcsc_uds_client *) (con->callback_data); in_uint32_le(in_s, hContext); - LLOGLN(10, ("scard_process_cancel: hContext 0x%8.8x", hContext)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_cancel: hContext 0x%8.8x", hContext); user_data = (void *) (tintptr) (uds_client->uds_client_id); lcontext = get_pcsc_context_by_app_context(uds_client, hContext); if (lcontext == 0) { - LLOGLN(0, ("scard_process_cancel: " - "get_pcsc_context_by_app_context failed")); + LOG(LOG_LEVEL_ERROR, "scard_process_cancel: " + "get_pcsc_context_by_app_context failed"); return 1; } scard_send_cancel(user_data, lcontext->context, lcontext->context_bytes); @@ -1613,15 +1636,16 @@ struct pcsc_uds_client *uds_client; struct trans *con; - LLOGLN(10, ("scard_function_cancel_return:")); - LLOGLN(10, (" status 0x%8.8x", status)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_cancel_return:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status); uds_client_id = (int) (tintptr) user_data; uds_client = (struct pcsc_uds_client *) get_uds_client_by_id(uds_client_id); if (uds_client == 0) { - LLOGLN(0, ("scard_function_cancel_return: " - "get_uds_client_by_id failed")); + LOG(LOG_LEVEL_ERROR, "scard_function_cancel_return: " + "get_uds_client_by_id failed to find uds_client_id %d", + uds_client_id); return 1; } con = uds_client->con; @@ -1649,8 +1673,8 @@ /*****************************************************************************/ /* returns error */ int scard_function_reconnect_return(void *user_data, - struct stream *in_s, - int len, int status) + struct stream *in_s, + int len, int status) { return 0; } @@ -1662,87 +1686,87 @@ { int rv; - LLOGLN(10, ("scard_process_msg: command 0x%4.4x", command)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_msg: command 0x%4.4x", command); rv = 0; switch (command) { case 0x01: /* SCARD_ESTABLISH_CONTEXT */ - LLOGLN(10, ("scard_process_msg: SCARD_ESTABLISH_CONTEXT")); + LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_ESTABLISH_CONTEXT"); rv = scard_process_establish_context(con, in_s); break; case 0x02: /* SCARD_RELEASE_CONTEXT */ - LLOGLN(10, ("scard_process_msg: SCARD_RELEASE_CONTEXT")); + LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_RELEASE_CONTEXT"); rv = scard_process_release_context(con, in_s); break; case 0x03: /* SCARD_LIST_READERS */ - LLOGLN(10, ("scard_process_msg: SCARD_LIST_READERS")); + LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_LIST_READERS"); rv = scard_process_list_readers(con, in_s); break; case 0x04: /* SCARD_CONNECT */ - LLOGLN(10, ("scard_process_msg: SCARD_CONNECT")); + LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_CONNECT"); rv = scard_process_connect(con, in_s); break; case 0x05: /* SCARD_RECONNECT */ - LLOGLN(0, ("scard_process_msg: SCARD_RECONNECT")); + LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_RECONNECT"); break; case 0x06: /* SCARD_DISCONNECT */ - LLOGLN(10, ("scard_process_msg: SCARD_DISCONNECT")); + LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_DISCONNECT"); rv = scard_process_disconnect(con, in_s); break; case 0x07: /* SCARD_BEGIN_TRANSACTION */ - LLOGLN(10, ("scard_process_msg: SCARD_BEGIN_TRANSACTION")); + LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_BEGIN_TRANSACTION"); rv = scard_process_begin_transaction(con, in_s); break; case 0x08: /* SCARD_END_TRANSACTION */ - LLOGLN(10, ("scard_process_msg: SCARD_END_TRANSACTION")); + LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_END_TRANSACTION"); rv = scard_process_end_transaction(con, in_s); break; case 0x09: /* SCARD_TRANSMIT */ - LLOGLN(10, ("scard_process_msg: SCARD_TRANSMIT")); + LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_TRANSMIT"); rv = scard_process_transmit(con, in_s); break; case 0x0A: /* SCARD_CONTROL */ - LLOGLN(10, ("scard_process_msg: SCARD_CONTROL")); + LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_CONTROL"); rv = scard_process_control(con, in_s); break; case 0x0B: /* SCARD_STATUS */ - LLOGLN(10, ("scard_process_msg: SCARD_STATUS")); + LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_STATUS"); rv = scard_process_status(con, in_s); break; case 0x0C: /* SCARD_GET_STATUS_CHANGE */ - LLOGLN(10, ("scard_process_msg: SCARD_GET_STATUS_CHANGE")); + LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_GET_STATUS_CHANGE"); rv = scard_process_get_status_change(con, in_s); break; case 0x0D: /* SCARD_CANCEL */ - LLOGLN(10, ("scard_process_msg: SCARD_CANCEL")); + LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_CANCEL"); rv = scard_process_cancel(con, in_s); break; case 0x0E: /* SCARD_CANCEL_TRANSACTION */ - LLOGLN(0, ("scard_process_msg: SCARD_CANCEL_TRANSACTION")); + LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_CANCEL_TRANSACTION"); break; case 0x0F: /* SCARD_GET_ATTRIB */ - LLOGLN(0, ("scard_process_msg: SCARD_GET_ATTRIB")); + LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_GET_ATTRIB"); break; case 0x10: /* SCARD_SET_ATTRIB */ - LLOGLN(0, ("scard_process_msg: SCARD_SET_ATTRIB")); + LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_SET_ATTRIB"); break; default: - LLOGLN(0, ("scard_process_msg: unknown mtype 0x%4.4x", command)); + LOG_DEVEL(LOG_LEVEL_WARNING, "scard_process_msg: unknown mtype 0x%4.4x", command); rv = 1; break; } @@ -1759,7 +1783,7 @@ int command; int error; - LLOGLN(10, ("my_pcsc_trans_data_in:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "my_pcsc_trans_data_in:"); if (trans == 0) { return 0; @@ -1767,7 +1791,7 @@ s = trans_get_in_s(trans); in_uint32_le(s, size); in_uint32_le(s, command); - LLOGLN(10, ("my_pcsc_trans_data_in: size %d command %d", size, command)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "my_pcsc_trans_data_in: size %d command %d", size, command); error = trans_force_read(trans, size); if (error == 0) { @@ -1783,7 +1807,7 @@ { struct pcsc_uds_client *uds_client; - LLOGLN(10, ("my_pcsc_trans_conn_in:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "my_pcsc_trans_conn_in:"); if (trans == 0) { @@ -1825,7 +1849,7 @@ int disp; int error; - LLOGLN(0, ("scard_pcsc_init:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_pcsc_init:"); if (g_lis == 0) { g_lis = trans_create(2, 8192, 8192); @@ -1837,7 +1861,7 @@ { if (!g_remove_dir(g_pcsclite_ipc_dir)) { - LLOGLN(0, ("scard_pcsc_init: g_remove_dir failed")); + LOG_DEVEL(LOG_LEVEL_WARNING, "scard_pcsc_init: g_remove_dir failed"); } } if (!g_directory_exist(g_pcsclite_ipc_dir)) @@ -1846,7 +1870,7 @@ { if (!g_directory_exist(g_pcsclite_ipc_dir)) { - LLOGLN(0, ("scard_pcsc_init: g_create_dir failed")); + LOG_DEVEL(LOG_LEVEL_WARNING, "scard_pcsc_init: g_create_dir failed"); } } } @@ -1856,8 +1880,8 @@ error = trans_listen(g_lis, g_pcsclite_ipc_file); if (error != 0) { - LLOGLN(0, ("scard_pcsc_init: trans_listen failed for port %s", - g_pcsclite_ipc_file)); + LOG(LOG_LEVEL_ERROR, "scard_pcsc_init: trans_listen failed for port %s", + g_pcsclite_ipc_file); return 1; } } @@ -1868,7 +1892,7 @@ int scard_pcsc_deinit(void) { - LLOGLN(0, ("scard_pcsc_deinit:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_pcsc_deinit:"); if (g_lis != 0) { @@ -1881,7 +1905,7 @@ g_file_delete(g_pcsclite_ipc_file); if (!g_remove_dir(g_pcsclite_ipc_dir)) { - LLOGLN(0, ("scard_pcsc_deinit: g_remove_dir failed")); + LOG_DEVEL(LOG_LEVEL_WARNING, "scard_pcsc_deinit: g_remove_dir failed"); } g_pcsclite_ipc_dir[0] = 0; } diff -Nru xrdp-0.9.12/sesman/chansrv/sound.c xrdp-0.9.15/sesman/chansrv/sound.c --- xrdp-0.9.12/sesman/chansrv/sound.c 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/sound.c 2020-12-28 14:03:43.000000000 +0000 @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include @@ -43,9 +43,9 @@ #define AACENCODER_LIB_VER_GTEQ(vl0, vl1, vl2) \ (defined(AACENCODER_LIB_VL0) && \ - ((AACENCODER_LIB_VL0 > vl0) || \ - (AACENCODER_LIB_VL0 == vl0 && AACENCODER_LIB_VL1 >= vl1) || \ - (AACENCODER_LIB_VL0 == vl0 && AACENCODER_LIB_VL1 == vl1 && AACENCODER_LIB_VL2 > vl2))) + ((AACENCODER_LIB_VL0 > vl0) || \ + (AACENCODER_LIB_VL0 == vl0 && AACENCODER_LIB_VL1 >= vl1) || \ + (AACENCODER_LIB_VL0 == vl0 && AACENCODER_LIB_VL1 == vl1 && AACENCODER_LIB_VL2 > vl2))) #endif #if defined(XRDP_OPUS) @@ -249,9 +249,9 @@ /* microphone related */ static int sound_send_server_input_formats(void); static int sound_process_input_format(int aindex, int wFormatTag, - int nChannels, int nSamplesPerSec, - int nAvgBytesPerSec, int nBlockAlign, - int wBitsPerSample, int cbSize, char *data); + int nChannels, int nSamplesPerSec, + int nAvgBytesPerSec, int nBlockAlign, + int wBitsPerSample, int cbSize, char *data); static int sound_process_input_formats(struct stream *s, int size); static int sound_input_start_recording(void); static int sound_input_stop_recording(void); @@ -272,7 +272,7 @@ num_formats = sizeof(g_wave_outp_formats) / sizeof(g_wave_outp_formats[0]) - 1; - LOG(10, ("sound_send_server_output_formats: num_formats %d", num_formats)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_send_server_output_formats: num_formats %d", num_formats); make_stream(s); init_stream(s, 8182); @@ -369,24 +369,24 @@ int nBlockAlign, int wBitsPerSample, int cbSize, char *data) { - LOG(1, ("sound_process_output_format:")); - LOG(1, (" wFormatTag %d", wFormatTag)); - LOG(1, (" nChannels %d", nChannels)); - LOG(1, (" nSamplesPerSec %d", nSamplesPerSec)); - LOG(1, (" nAvgBytesPerSec %d", nAvgBytesPerSec)); - LOG(1, (" nBlockAlign %d", nBlockAlign)); - LOG(1, (" wBitsPerSample %d", wBitsPerSample)); - LOG(1, (" cbSize %d", cbSize)); + LOG_DEVEL(LOG_LEVEL_INFO, "sound_process_output_format:"); + LOG_DEVEL(LOG_LEVEL_INFO, " wFormatTag %d", wFormatTag); + LOG_DEVEL(LOG_LEVEL_INFO, " nChannels %d", nChannels); + LOG_DEVEL(LOG_LEVEL_INFO, " nSamplesPerSec %d", nSamplesPerSec); + LOG_DEVEL(LOG_LEVEL_INFO, " nAvgBytesPerSec %d", nAvgBytesPerSec); + LOG_DEVEL(LOG_LEVEL_INFO, " nBlockAlign %d", nBlockAlign); + LOG_DEVEL(LOG_LEVEL_INFO, " wBitsPerSample %d", wBitsPerSample); + LOG_DEVEL(LOG_LEVEL_INFO, " cbSize %d", cbSize); - g_hexdump(data, cbSize); + LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", data, cbSize); /* select CD quality audio */ if (wFormatTag == g_pcm_44100.wFormatTag && - nChannels == g_pcm_44100.nChannels && - nSamplesPerSec == g_pcm_44100.nSamplesPerSec && - nAvgBytesPerSec == g_pcm_44100.nAvgBytesPerSec && - nBlockAlign == g_pcm_44100.nBlockAlign && - wBitsPerSample == g_pcm_44100.wBitsPerSample) + nChannels == g_pcm_44100.nChannels && + nSamplesPerSec == g_pcm_44100.nSamplesPerSec && + nAvgBytesPerSec == g_pcm_44100.nAvgBytesPerSec && + nBlockAlign == g_pcm_44100.nBlockAlign && + wBitsPerSample == g_pcm_44100.wBitsPerSample) { g_current_client_format_index = aindex; g_current_server_format_index = 0; @@ -395,11 +395,11 @@ for (lindex = 0; lindex < NUM_BUILT_IN; lindex++) { if (wFormatTag == g_wave_formats[lindex]->wFormatTag && - nChannels == g_wave_formats[lindex]->nChannels && - nSamplesPerSec == g_wave_formats[lindex]->nSamplesPerSec && - nAvgBytesPerSec == g_wave_formats[lindex]->nAvgBytesPerSec && - nBlockAlign == g_wave_formats[lindex]->nBlockAlign && - wBitsPerSample == g_wave_formats[lindex]->wBitsPerSample) + nChannels == g_wave_formats[lindex]->nChannels && + nSamplesPerSec == g_wave_formats[lindex]->nSamplesPerSec && + nAvgBytesPerSec == g_wave_formats[lindex]->nAvgBytesPerSec && + nBlockAlign == g_wave_formats[lindex]->nBlockAlign && + wBitsPerSample == g_wave_formats[lindex]->wBitsPerSample) { g_current_client_format_index = aindex; g_current_server_format_index = lindex; @@ -407,20 +407,20 @@ } #endif - switch(wFormatTag) + switch (wFormatTag) { case WAVE_FORMAT_AAC: - LOG(0, ("wFormatTag, fdk aac")); + LOG_DEVEL(LOG_LEVEL_INFO, "wFormatTag, fdk aac"); g_client_does_fdk_aac = 1; g_client_fdk_aac_index = aindex; break; case WAVE_FORMAT_MPEGLAYER3: - LOG(0, ("wFormatTag, mp3")); + LOG_DEVEL(LOG_LEVEL_INFO, "wFormatTag, mp3"); g_client_does_mp3lame = 1; g_client_mp3lame_index = aindex; break; case WAVE_FORMAT_OPUS: - LOG(0, ("wFormatTag, opus")); + LOG_DEVEL(LOG_LEVEL_INFO, "wFormatTag, opus"); g_client_does_opus = 1; g_client_opus_index = aindex; break; @@ -451,7 +451,9 @@ char *data; if (size < 16) + { return 1; + } in_uint8s(s, 14); in_uint16_le(s, num_formats); @@ -520,12 +522,12 @@ if (g_fdk_aac_encoder == 0) { /* init fdk aac encoder */ - LOG(0, ("sound_wave_compress_fdk_aac: using fdk aac")); + LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac: using fdk aac"); error = aacEncOpen(&g_fdk_aac_encoder, 0, 2); if (error != AACENC_OK) { - LOG(0, ("sound_wave_compress_fdk_aac: aacEncOpen() failed")); + LOG_DEVEL(LOG_LEVEL_ERROR, "sound_wave_compress_fdk_aac: aacEncOpen() failed"); return rv; } @@ -533,8 +535,8 @@ error = aacEncoder_SetParam(g_fdk_aac_encoder, AACENC_AOT, aot); if (error != AACENC_OK) { - LOG(0, ("sound_wave_compress_fdk_aac: aacEncoder_SetParam() " - "AACENC_AOT failed")); + LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac: aacEncoder_SetParam() " + "AACENC_AOT failed"); } sample_rate = g_fdk_aac_44100.nSamplesPerSec; @@ -542,8 +544,8 @@ sample_rate); if (error != AACENC_OK) { - LOG(0, ("sound_wave_compress_fdk_aac: aacEncoder_SetParam() " - "AACENC_SAMPLERATE failed")); + LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac: aacEncoder_SetParam() " + "AACENC_SAMPLERATE failed"); } mode = MODE_2; @@ -551,8 +553,8 @@ AACENC_CHANNELMODE, mode); if (error != AACENC_OK) { - LOG(0, ("sound_wave_compress_fdk_aac: aacEncoder_SetParam() " - "AACENC_CHANNELMODE failed")); + LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac: aacEncoder_SetParam() " + "AACENC_CHANNELMODE failed"); } channel_order = 1; /* WAVE file format channel ordering */ @@ -560,8 +562,8 @@ channel_order); if (error != AACENC_OK) { - LOG(0, ("sound_wave_compress_fdk_aac: aacEncoder_SetParam() " - "AACENC_CHANNELORDER failed")); + LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac: aacEncoder_SetParam() " + "AACENC_CHANNELORDER failed"); } /* bytes rate to bit rate */ @@ -570,15 +572,15 @@ bitrate); if (error != AACENC_OK) { - LOG(0, ("sound_wave_compress_fdk_aac: aacEncoder_SetParam() " - "AACENC_BITRATE failed")); + LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac: aacEncoder_SetParam() " + "AACENC_BITRATE failed"); } error = aacEncoder_SetParam(g_fdk_aac_encoder, AACENC_TRANSMUX, 0); if (error != AACENC_OK) { - LOG(0, ("sound_wave_compress_fdk_aac: aacEncoder_SetParam() " - "AACENC_TRANSMUX failed")); + LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac: aacEncoder_SetParam() " + "AACENC_TRANSMUX failed"); } afterburner = 1; @@ -586,39 +588,39 @@ afterburner); if (error != AACENC_OK) { - LOG(0, ("sound_wave_compress_fdk_aac: aacEncoder_SetParam() " - "AACENC_AFTERBURNER failed")); + LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac: aacEncoder_SetParam() " + "AACENC_AFTERBURNER failed"); } error = aacEncEncode(g_fdk_aac_encoder, NULL, NULL, NULL, NULL); if (error != AACENC_OK) { - LOG(0, ("sound_wave_compress_fdk_aac: Unable to initialize " - "the encoder")); + LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac: Unable to initialize " + "the encoder"); } g_memset(&info, 0, sizeof(info)); error = aacEncInfo(g_fdk_aac_encoder, &info); if (error != AACENC_OK) { - LOG(0, ("sound_wave_compress_fdk_aac: aacEncInfo failed")); + LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac: aacEncInfo failed"); } - LOG(0, ("sound_wave_compress_fdk_aac:")); - LOG(0, (" AACENC_InfoStruct")); - LOG(0, (" maxOutBufBytes %d", info.maxOutBufBytes)); - LOG(0, (" maxAncBytes %d", info.maxAncBytes)); - LOG(0, (" inBufFillLevel %d", info.inBufFillLevel)); - LOG(0, (" inputChannels %d", info.inputChannels)); - LOG(0, (" frameLength %d", info.frameLength)); + LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac:"); + LOG_DEVEL(LOG_LEVEL_INFO, " AACENC_InfoStruct"); + LOG_DEVEL(LOG_LEVEL_INFO, " maxOutBufBytes %d", info.maxOutBufBytes); + LOG_DEVEL(LOG_LEVEL_INFO, " maxAncBytes %d", info.maxAncBytes); + LOG_DEVEL(LOG_LEVEL_INFO, " inBufFillLevel %d", info.inBufFillLevel); + LOG_DEVEL(LOG_LEVEL_INFO, " inputChannels %d", info.inputChannels); + LOG_DEVEL(LOG_LEVEL_INFO, " frameLength %d", info.frameLength); #if AACENCODER_LIB_VER_GTEQ(4, 0, 0) - LOG(0, (" nDelay %d", info.nDelay)); - LOG(0, (" nDelayCore %d", info.nDelayCore)); + LOG_DEVEL(LOG_LEVEL_INFO, " nDelay %d", info.nDelay); + LOG_DEVEL(LOG_LEVEL_INFO, " nDelayCore %d", info.nDelayCore); #else - LOG(0, (" encoderDelay %d", info.encoderDelay)); + LOG_DEVEL(LOG_LEVEL_INFO, " encoderDelay %d", info.encoderDelay); #endif - LOG(0, (" confBuf")); - LOG(0, (" confSize %d", info.confSize)); + LOG_DEVEL(LOG_LEVEL_INFO, " confBuf"); + LOG_DEVEL(LOG_LEVEL_INFO, " confSize %d", info.confSize); } rv = data_bytes; @@ -662,15 +664,15 @@ if (error == AACENC_OK) { cdata_bytes = out_args.numOutBytes; - LOG(10, ("sound_wave_compress_fdk_aac: aacEncEncode ok " - "cdata_bytes %d", cdata_bytes)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_wave_compress_fdk_aac: aacEncEncode ok " + "cdata_bytes %d", cdata_bytes); *format_index = g_client_fdk_aac_index; g_memcpy(data, cdata, cdata_bytes); rv = cdata_bytes; } else { - LOG(0, ("sound_wave_compress_fdk_aac: aacEncEncode failed")); + LOG_DEVEL(LOG_LEVEL_ERROR, "sound_wave_compress_fdk_aac: aacEncEncode failed"); } g_free(cdata); @@ -717,7 +719,7 @@ &error); if (g_opus_encoder == 0) { - LOG(0, ("sound_wave_compress_opus: opus_encoder_create failed")); + LOG_DEVEL(LOG_LEVEL_ERROR, "sound_wave_compress_opus: opus_encoder_create failed"); return data_bytes; } } @@ -783,29 +785,31 @@ if (g_lame_encoder == 0) { /* init mp3 lame encoder */ - LOG(0, ("sound_wave_compress_mp3lame: using mp3lame")); + LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_mp3lame: using mp3lame"); g_lame_encoder = lame_init(); if (g_lame_encoder == 0) { - LOG(0, ("sound_wave_compress_mp3lame: lame_init() failed")); + LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_mp3lame: lame_init() failed"); return rv; } lame_set_num_channels(g_lame_encoder, g_mp3lame_44100.nChannels); lame_set_in_samplerate(g_lame_encoder, g_mp3lame_44100.nSamplesPerSec); + //lame_set_brate(g_lame_encoder, 64); + lame_set_quality(g_lame_encoder, 7); if (lame_init_params(g_lame_encoder) == -1) { - LOG(0, ("sound_wave_compress_mp3lame: lame_init_params() failed")); + LOG_DEVEL(LOG_LEVEL_ERROR, "sound_wave_compress_mp3lame: lame_init_params() failed"); return rv; } - LOG(0, ("sound_wave_compress_mp3lame: lame config:")); - LOG(0, (" brate : %d", lame_get_brate(g_lame_encoder))); - LOG(0, (" compression ratio: %f", lame_get_compression_ratio(g_lame_encoder))); - LOG(0, (" encoder delay : %d", lame_get_encoder_delay(g_lame_encoder))); - LOG(0, (" frame size : %d", lame_get_framesize(g_lame_encoder))); - LOG(0, (" encoder padding : %d", lame_get_encoder_padding(g_lame_encoder))); - LOG(0, (" mode : %d", lame_get_mode(g_lame_encoder))); + LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_mp3lame: lame config:"); + LOG_DEVEL(LOG_LEVEL_INFO, " brate : %d", lame_get_brate(g_lame_encoder)); + LOG_DEVEL(LOG_LEVEL_INFO, " compression ratio: %f", lame_get_compression_ratio(g_lame_encoder)); + LOG_DEVEL(LOG_LEVEL_INFO, " encoder delay : %d", lame_get_encoder_delay(g_lame_encoder)); + LOG_DEVEL(LOG_LEVEL_INFO, " frame size : %d", lame_get_framesize(g_lame_encoder)); + LOG_DEVEL(LOG_LEVEL_INFO, " encoder padding : %d", lame_get_encoder_padding(g_lame_encoder)); + LOG_DEVEL(LOG_LEVEL_INFO, " mode : %d", lame_get_mode(g_lame_encoder)); } odata_bytes = data_bytes; @@ -817,14 +821,14 @@ data_bytes = g_bbuf_size; } cdata_bytes = lame_encode_buffer_interleaved(g_lame_encoder, - (short int *) data, - data_bytes / 4, - cdata, - cdata_bytes); + (short int *) data, + data_bytes / 4, + cdata, + cdata_bytes); if (cdata_bytes < 0) { - LOG(0, ("sound_wave_compress: lame_encode_buffer_interleaved() " - "failed, error %d", cdata_bytes)); + LOG_DEVEL(LOG_LEVEL_ERROR, "sound_wave_compress: lame_encode_buffer_interleaved() " + "failed, error %d", cdata_bytes); return rv; } if ((cdata_bytes > 0) && (cdata_bytes < odata_bytes)) @@ -882,11 +886,11 @@ int format_index; char *size_ptr; - LOG(10, ("sound_send_wave_data_chunk: data_bytes %d", data_bytes)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_send_wave_data_chunk: data_bytes %d", data_bytes); if ((data_bytes < 4) || (data_bytes > 128 * 1024)) { - LOG(0, ("sound_send_wave_data_chunk: bad data_bytes %d", data_bytes)); + LOG_DEVEL(LOG_LEVEL_ERROR, "sound_send_wave_data_chunk: bad data_bytes %d", data_bytes); return 1; } @@ -896,7 +900,7 @@ /* part one of 2 PDU wave info */ - LOG(10, ("sound_send_wave_data_chunk: sending %d bytes", data_bytes)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_send_wave_data_chunk: sending %d bytes", data_bytes); make_stream(s); init_stream(s, 16 + data_bytes); /* some extra space */ @@ -910,8 +914,8 @@ out_uint8(s, g_cBlockNo); g_sent_time[g_cBlockNo & 0xff] = time; - LOG(10, ("sound_send_wave_data_chunk: sending time %d, g_cBlockNo %d", - time & 0xffff, g_cBlockNo & 0xff)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_send_wave_data_chunk: sending time %d, g_cBlockNo %d", + time & 0xffff, g_cBlockNo & 0xff); out_uint8s(s, 3); out_uint8a(s, data, 4); @@ -948,7 +952,7 @@ int error; int res; - LOG(10, ("sound_send_wave_data: sending %d bytes", data_bytes)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_send_wave_data: sending %d bytes", data_bytes); if (g_time_diff > g_best_time_diff + 250) { data_bytes = data_bytes / 4; @@ -964,7 +968,7 @@ chunk_bytes = MIN(space_left, data_bytes); if (chunk_bytes < 1) { - LOG(10, ("sound_send_wave_data: error")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_send_wave_data: error"); error = 1; break; } @@ -977,12 +981,12 @@ if (res == 2) { /* don't need to error on this */ - LOG(0, ("sound_send_wave_data: dropped, no room")); + LOG_DEVEL(LOG_LEVEL_ERROR, "sound_send_wave_data: dropped, no room"); break; } else if (res != 0) { - LOG(10, ("sound_send_wave_data: error")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_send_wave_data: error"); error = 1; break; } @@ -1003,7 +1007,7 @@ int bytes; char *size_ptr; - LOG(10, ("sound_send_close:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_send_close:"); g_best_time_diff = 0; g_buf_index = 0; @@ -1032,7 +1036,7 @@ int time_diff; time_diff = g_time3() - g_training_sent_time; - LOG(0, ("sound_process_training: round trip time %u", time_diff)); + LOG(LOG_LEVEL_INFO, "sound_process_training: round trip time %u", time_diff); return 0; } @@ -1053,9 +1057,9 @@ in_uint8(s, cConfirmedBlockNo); time_diff = time - g_sent_time[cConfirmedBlockNo & 0xff]; - LOG(10, ("sound_process_wave_confirm: wTimeStamp %d, " + LOG(LOG_LEVEL_DEBUG, "sound_process_wave_confirm: wTimeStamp %d, " "cConfirmedBlockNo %d time diff %d", - wTimeStamp, cConfirmedBlockNo, time_diff)); + wTimeStamp, cConfirmedBlockNo, time_diff); acc = 0; list_add_item(g_ack_time_diff, time_diff); @@ -1094,7 +1098,7 @@ return sound_send_close(); break; default: - LOG(10, ("process_pcm_message: unknown id %d", id)); + LOG_DEVEL(LOG_LEVEL_ERROR, "process_pcm_message: unknown id %d", id); break; } return 1; @@ -1113,10 +1117,14 @@ int error; if (trans == 0) + { return 0; + } if (trans != g_audio_c_trans_out) + { return 1; + } s = trans_get_in_s(trans); in_uint32_le(s, id); @@ -1124,11 +1132,11 @@ if ((id & ~3) || (size > 128 * 1024 + 8) || (size < 8)) { - LOG(0, ("sound_sndsrvr_sink_data_in: bad message id %d size %d", id, size)); + LOG_DEVEL(LOG_LEVEL_ERROR, "sound_sndsrvr_sink_data_in: bad message id %d size %d", id, size); return 1; } - LOG(10, ("sound_sndsrvr_sink_data_in: good message id %d size %d", id, size)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_sndsrvr_sink_data_in: good message id %d size %d", id, size); error = trans_force_read(trans, size - 8); @@ -1148,19 +1156,27 @@ static int sound_sndsrvr_sink_conn_in(struct trans *trans, struct trans *new_trans) { - LOG(0, ("sound_sndsrvr_sink_conn_in:")); + LOG_DEVEL(LOG_LEVEL_INFO, "sound_sndsrvr_sink_conn_in:"); if (trans == 0) + { return 1; + } if (trans != g_audio_l_trans_out) + { return 1; + } if (g_audio_c_trans_out != 0) /* if already set, error */ + { return 1; + } if (new_trans == 0) + { return 1; + } g_audio_c_trans_out = new_trans; g_audio_c_trans_out->trans_data_in = sound_sndsrvr_sink_data_in; @@ -1178,19 +1194,27 @@ static int sound_sndsrvr_source_conn_in(struct trans *trans, struct trans *new_trans) { - LOG(0, ("sound_sndsrvr_source_conn_in: client connected")); + LOG_DEVEL(LOG_LEVEL_INFO, "sound_sndsrvr_source_conn_in: client connected"); if (trans == 0) + { return 1; + } if (trans != g_audio_l_trans_in) + { return 1; + } if (g_audio_c_trans_in != 0) /* if already set, error */ + { return 1; + } if (new_trans == 0) + { return 1; + } g_audio_c_trans_in = new_trans; g_audio_c_trans_in->trans_data_in = sound_sndsrvr_source_data_in; @@ -1205,7 +1229,7 @@ int sound_init(void) { - LOG(0, ("sound_init:")); + LOG_DEVEL(LOG_LEVEL_INFO, "sound_init:"); g_stream_incoming_packet = NULL; @@ -1242,7 +1266,7 @@ int sound_deinit(void) { - LOG(10, ("sound_deinit:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_deinit:"); if (g_audio_l_trans_out != 0) { trans_delete(g_audio_l_trans_out); @@ -1327,7 +1351,7 @@ break; default: - LOG(10, ("sound_data_in: unknown code %d size %d", code, size)); + LOG_DEVEL(LOG_LEVEL_ERROR, "sound_data_in: unknown code %d size %d", code, size); break; } @@ -1384,7 +1408,7 @@ { if (trans_check_wait_objs(g_audio_l_trans_out) != 0) { - LOG(10, ("sound_check_wait_objs: g_audio_l_trans_out returned non-zero")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_check_wait_objs: g_audio_l_trans_out returned non-zero"); trans_delete(g_audio_l_trans_out); g_audio_l_trans_out = 0; } @@ -1394,7 +1418,7 @@ { if (trans_check_wait_objs(g_audio_c_trans_out) != 0) { - LOG(10, ("sound_check_wait_objs: g_audio_c_trans_out returned non-zero")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_check_wait_objs: g_audio_c_trans_out returned non-zero"); trans_delete(g_audio_c_trans_out); g_audio_c_trans_out = 0; sound_start_sink_listener(); @@ -1405,7 +1429,7 @@ { if (trans_check_wait_objs(g_audio_l_trans_in) != 0) { - LOG(10, ("sound_check_wait_objs: g_audio_l_trans_in returned non-zero")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_check_wait_objs: g_audio_l_trans_in returned non-zero"); trans_delete(g_audio_l_trans_in); g_audio_l_trans_in = 0; } @@ -1415,7 +1439,7 @@ { if (trans_check_wait_objs(g_audio_c_trans_in) != 0) { - LOG(10, ("sound_check_wait_objs: g_audio_c_trans_in returned non-zero")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_check_wait_objs: g_audio_c_trans_in returned non-zero"); trans_delete(g_audio_c_trans_in); g_audio_c_trans_in = 0; sound_start_source_listener(); @@ -1447,7 +1471,7 @@ num_formats = sizeof(g_wave_inp_formats) / sizeof(g_wave_inp_formats[0]) - 1; - LOG(10, ("sound_send_server_input_formats: num_formats %d", num_formats)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_send_server_input_formats: num_formats %d", num_formats); make_stream(s); init_stream(s, 8182); @@ -1510,23 +1534,23 @@ int nBlockAlign, int wBitsPerSample, int cbSize, char *data) { - LOG(10, ("sound_process_input_format:")); - LOG(10, (" wFormatTag %d", wFormatTag)); - LOG(10, (" nChannels %d", nChannels)); - LOG(10, (" nSamplesPerSec %d", nSamplesPerSec)); - LOG(10, (" nAvgBytesPerSec %d", nAvgBytesPerSec)); - LOG(10, (" nBlockAlign %d", nBlockAlign)); - LOG(10, (" wBitsPerSample %d", wBitsPerSample)); - LOG(10, (" cbSize %d", cbSize)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_process_input_format:"); + LOG_DEVEL(LOG_LEVEL_DEBUG, " wFormatTag %d", wFormatTag); + LOG_DEVEL(LOG_LEVEL_DEBUG, " nChannels %d", nChannels); + LOG_DEVEL(LOG_LEVEL_DEBUG, " nSamplesPerSec %d", nSamplesPerSec); + LOG_DEVEL(LOG_LEVEL_DEBUG, " nAvgBytesPerSec %d", nAvgBytesPerSec); + LOG_DEVEL(LOG_LEVEL_DEBUG, " nBlockAlign %d", nBlockAlign); + LOG_DEVEL(LOG_LEVEL_DEBUG, " wBitsPerSample %d", wBitsPerSample); + LOG_DEVEL(LOG_LEVEL_DEBUG, " cbSize %d", cbSize); #if 1 /* select CD quality audio */ if (wFormatTag == g_pcm_inp_44100.wFormatTag && - nChannels == g_pcm_inp_44100.nChannels && - nSamplesPerSec == g_pcm_inp_44100.nSamplesPerSec && - nAvgBytesPerSec == g_pcm_inp_44100.nAvgBytesPerSec && - nBlockAlign == g_pcm_inp_44100.nBlockAlign && - wBitsPerSample == g_pcm_inp_44100.wBitsPerSample) + nChannels == g_pcm_inp_44100.nChannels && + nSamplesPerSec == g_pcm_inp_44100.nSamplesPerSec && + nAvgBytesPerSec == g_pcm_inp_44100.nAvgBytesPerSec && + nBlockAlign == g_pcm_inp_44100.nBlockAlign && + wBitsPerSample == g_pcm_inp_44100.wBitsPerSample) { g_client_input_format_index = aindex; g_server_input_format_index = 0; @@ -1534,11 +1558,11 @@ #else /* select half of CD quality audio */ if (wFormatTag == g_pcm_inp_22050.wFormatTag && - nChannels == g_pcm_inp_22050.nChannels && - nSamplesPerSec == g_pcm_inp_22050.nSamplesPerSec && - nAvgBytesPerSec == g_pcm_inp_22050.nAvgBytesPerSec && - nBlockAlign == g_pcm_inp_22050.nBlockAlign && - wBitsPerSample == g_pcm_inp_22050.wBitsPerSample) + nChannels == g_pcm_inp_22050.nChannels && + nSamplesPerSec == g_pcm_inp_22050.nSamplesPerSec && + nAvgBytesPerSec == g_pcm_inp_22050.nAvgBytesPerSec && + nBlockAlign == g_pcm_inp_22050.nBlockAlign && + wBitsPerSample == g_pcm_inp_22050.wBitsPerSample) { g_client_input_format_index = aindex; g_server_input_format_index = 0; @@ -1566,7 +1590,7 @@ int cbSize; char *data; - LOG(10, ("sound_process_input_formats: size=%d", size)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_process_input_formats: size=%d", size); if (g_getenv("XRDP_NO_RDPSND_REC") == NULL) { @@ -1604,9 +1628,9 @@ static int sound_input_start_recording(void) { - struct stream* s; + struct stream *s; - LOG(10, ("sound_input_start_recording:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_input_start_recording:"); /* if there is any data in FIFO, discard it */ while ((s = (struct stream *) fifo_remove(&g_in_fifo)) != NULL) @@ -1643,9 +1667,9 @@ static int sound_input_stop_recording(void) { - struct stream* s; + struct stream *s; - LOG(10, ("sound_input_stop_recording:")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_input_stop_recording:"); xstream_new(s, 1024); @@ -1675,8 +1699,8 @@ { struct stream *ls; - LOG(10, ("sound_process_input_data: bytes %d g_bytes_in_fifo %d", - bytes, g_bytes_in_fifo)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_process_input_data: bytes %d g_bytes_in_fifo %d", + bytes, g_bytes_in_fifo); #if 0 /* no need to cap anymore */ /* cap data in fifo */ if (g_bytes_in_fifo > 8 * 1024) @@ -1710,19 +1734,25 @@ int i; if (trans == 0) + { return 0; + } if (trans != g_audio_c_trans_in) + { return 1; + } ts = trans_get_in_s(trans); if (trans_force_read(trans, 3)) - log_message(LOG_LEVEL_ERROR, "sound.c: error reading from transport"); + { + LOG(LOG_LEVEL_ERROR, "sound.c: error reading from transport"); + } ts->p = ts->data + 8; in_uint8(ts, cmd); in_uint16_le(ts, bytes_req); - LOG(10, ("sound_sndsrvr_source_data_in: bytes_req %d", bytes_req)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_sndsrvr_source_data_in: bytes_req %d", bytes_req); xstream_new(s, bytes_req + 2); @@ -1739,7 +1769,7 @@ if (g_stream_inp != NULL) { g_bytes_in_fifo -= g_stream_inp->size; - LOG(10, (" g_bytes_in_fifo %d", g_bytes_in_fifo)); + LOG_DEVEL(LOG_LEVEL_DEBUG, " g_bytes_in_fifo %d", g_bytes_in_fifo); } } @@ -1751,7 +1781,9 @@ else { if (g_bytes_in_stream == 0) + { g_bytes_in_stream = g_stream_inp->size; + } i = bytes_req - bytes_read; @@ -1823,7 +1855,9 @@ g_snprintf(port, 255, CHANSRV_PORT_IN_STR, g_display_num); g_audio_l_trans_in->trans_conn_in = sound_sndsrvr_source_conn_in; if (trans_listen(g_audio_l_trans_in, port) != 0) - LOG(0, ("trans_listen failed")); + { + LOG_DEVEL(LOG_LEVEL_ERROR, "trans_listen failed"); + } return 0; } @@ -1840,7 +1874,9 @@ g_snprintf(port, 255, CHANSRV_PORT_OUT_STR, g_display_num); g_audio_l_trans_out->trans_conn_in = sound_sndsrvr_sink_conn_in; if (trans_listen(g_audio_l_trans_out, port) != 0) - LOG(0, ("trans_listen failed")); + { + LOG_DEVEL(LOG_LEVEL_ERROR, "trans_listen failed"); + } return 0; } diff -Nru xrdp-0.9.12/sesman/chansrv/xcommon.c xrdp-0.9.15/sesman/chansrv/xcommon.c --- xrdp-0.9.12/sesman/chansrv/xcommon.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/chansrv/xcommon.c 2020-12-28 14:03:43.000000000 +0000 @@ -30,11 +30,6 @@ #include "rail.h" #include "xcommon.h" -/* -#undef LOG_LEVEL -#define LOG_LEVEL 11 -*/ - extern int g_clip_up; /* in clipboard.c */ extern int g_rail_up; /* in rail.c */ @@ -61,9 +56,9 @@ char text[256]; XGetErrorText(dis, xer->error_code, text, 255); - LOGM((LOG_LEVEL_ERROR, "X error [%s](%d) opcodes %d/%d " - "resource 0x%lx", text, xer->error_code, - xer->request_code, xer->minor_code, xer->resourceid)); + LOG_DEVEL(LOG_LEVEL_ERROR, "X error [%s](%d) opcodes %d/%d " + "resource 0x%lx", text, xer->error_code, + xer->request_code, xer->minor_code, xer->resourceid); return 0; } @@ -108,7 +103,7 @@ { if (g_display != 0) { - LOG(10, ("xcommon_init: xcommon_init already called")); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xcommon_init: xcommon_init already called"); return 0; } @@ -116,11 +111,11 @@ if (g_display == 0) { - LOGM((LOG_LEVEL_ERROR, "xcommon_init: error, XOpenDisplay failed")); + LOG_DEVEL(LOG_LEVEL_ERROR, "xcommon_init: error, XOpenDisplay failed"); return 1; } - LOG(0, ("xcommon_init: connected to display ok")); + LOG_DEVEL(LOG_LEVEL_INFO, "xcommon_init: connected to display ok"); /* setting the error handlers can cause problem when shutting down chansrv on some xlibs */ @@ -131,7 +126,7 @@ if (g_x_socket == 0) { - LOGM((LOG_LEVEL_ERROR, "xcommon_init: XConnectionNumber failed")); + LOG_DEVEL(LOG_LEVEL_ERROR, "xcommon_init: XConnectionNumber failed"); return 1; } @@ -146,7 +141,7 @@ g_utf8_string = XInternAtom(g_display, "UTF8_STRING", 0); g_net_wm_name = XInternAtom(g_display, "_NET_WM_NAME", 0); g_wm_state = XInternAtom(g_display, "WM_STATE", 0); - + return 0; } @@ -190,8 +185,8 @@ rail_rv = rail_xevent(&xevent); if ((clip_rv == 1) && (rail_rv == 1)) { - LOG(10, ("xcommon_check_wait_objs unknown xevent type %d", - xevent.type)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "xcommon_check_wait_objs unknown xevent type %d", + xevent.type); } } return 0; diff -Nru xrdp-0.9.12/sesman/config.c xrdp-0.9.15/sesman/config.c --- xrdp-0.9.12/sesman/config.c 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/sesman/config.c 2020-12-28 14:03:43.000000000 +0000 @@ -33,62 +33,19 @@ #include "file.h" #include "sesman.h" #include "log.h" +#include "string_calls.h" - - -/******************************************************************************/ -int -config_read(struct config_sesman *cfg) -{ - int fd; - struct list *sec; - struct list *param_n; - struct list *param_v; - char cfg_file[256]; - - g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); - fd = g_file_open(cfg_file); - - if (-1 == fd) - { - return 1; - } - - g_memset(cfg, 0, sizeof(struct config_sesman)); - sec = list_create(); - sec->auto_free = 1; - file_read_sections(fd, sec); - param_n = list_create(); - param_n->auto_free = 1; - param_v = list_create(); - param_v->auto_free = 1; - - /* read global config */ - config_read_globals(fd, cfg, param_n, param_v); - - /* read Xvnc/X11rdp/Xorg parameter list */ - config_read_vnc_params(fd, cfg, param_n, param_v); - config_read_rdp_params(fd, cfg, param_n, param_v); - config_read_xorg_params(fd, cfg, param_n, param_v); - - /* read security config */ - config_read_security(fd, &(cfg->sec), param_n, param_v); - - /* read session config */ - config_read_sessions(fd, &(cfg->sess), param_n, param_v); - - config_read_session_variables(fd, cfg, param_n, param_v); - - /* cleanup */ - list_delete(sec); - list_delete(param_v); - list_delete(param_n); - g_file_close(fd); - return 0; -} - -/******************************************************************************/ -int +/***************************************************************************//** + * + * @brief Reads sesman [global] configuration section + * @param file configuration file descriptor + * @param cf pointer to a config struct + * @param param_n parameter name list + * @param param_v parameter value list + * @return 0 on success, 1 on failure + * + */ +static int config_read_globals(int file, struct config_sesman *cf, struct list *param_n, struct list *param_v) { @@ -205,8 +162,17 @@ return 0; } -/******************************************************************************/ -int +/***************************************************************************//** + * + * @brief Reads sesman [Security] configuration section + * @param file configuration file descriptor + * @param sc pointer to a config_security struct + * @param param_n parameter name list + * @param param_v parameter value list + * @return 0 on success, 1 on failure + * + */ +static int config_read_security(int file, struct config_security *sc, struct list *param_n, struct list *param_v) @@ -273,8 +239,17 @@ return 0; } -/******************************************************************************/ -int +/***************************************************************************//** + * + * @brief Reads sesman [Sessions] configuration section + * @param file configuration file descriptor + * @param ss pointer to a config_sessions struct + * @param param_n parameter name list + * @param param_v parameter value list + * @return 0 on success, 1 on failure + * + */ +static int config_read_sessions(int file, struct config_sessions *se, struct list *param_n, struct list *param_v) { @@ -360,8 +335,17 @@ return 0; } -/******************************************************************************/ -int +/***************************************************************************//** + * + * @brief Reads sesman [X11rdp] configuration section + * @param file configuration file descriptor + * @param cs pointer to a config_sesman struct + * @param param_n parameter name list + * @param param_v parameter value list + * @return 0 on success, 1 on failure + * + */ +static int config_read_rdp_params(int file, struct config_sesman *cs, struct list *param_n, struct list *param_v) { @@ -383,8 +367,17 @@ return 0; } -/******************************************************************************/ -int +/***************************************************************************//** + * + * @brief Reads sesman [Xorg] configuration section + * @param file configuration file descriptor + * @param cs pointer to a config_sesman struct + * @param param_n parameter name list + * @param param_v parameter value list + * @return 0 on success, 1 on failure + * + */ +static int config_read_xorg_params(int file, struct config_sesman *cs, struct list *param_n, struct list *param_v) { @@ -407,8 +400,17 @@ return 0; } -/******************************************************************************/ -int +/***************************************************************************//** + * + * @brief Reads sesman [Xvnc] configuration section + * @param file configuration file descriptor + * @param cs pointer to a config_sesman struct + * @param param_n parameter name list + * @param param_v parameter value list + * @return 0 on success, 1 on failure + * + */ +static int config_read_vnc_params(int file, struct config_sesman *cs, struct list *param_n, struct list *param_v) { @@ -431,7 +433,7 @@ } /******************************************************************************/ -int +static int config_read_session_variables(int file, struct config_sesman *cs, struct list *param_n, struct list *param_v) { @@ -458,6 +460,67 @@ return 0; } +/******************************************************************************/ +struct config_sesman * +config_read(const char *sesman_ini) +{ + struct config_sesman *cfg; + int all_ok = 0; + + if ((cfg = g_new0(struct config_sesman, 1)) != NULL) + { + if ((cfg->sesman_ini = g_strdup(sesman_ini)) != NULL) + { + int fd; + if ((fd = g_file_open_ex(cfg->sesman_ini, 1, 0, 0, 0)) != -1) + { + struct list *sec; + struct list *param_n; + struct list *param_v; + sec = list_create(); + sec->auto_free = 1; + file_read_sections(fd, sec); + param_n = list_create(); + param_n->auto_free = 1; + param_v = list_create(); + param_v->auto_free = 1; + + /* read global config */ + config_read_globals(fd, cfg, param_n, param_v); + + /* read Xvnc/X11rdp/Xorg parameter list */ + config_read_vnc_params(fd, cfg, param_n, param_v); + config_read_rdp_params(fd, cfg, param_n, param_v); + config_read_xorg_params(fd, cfg, param_n, param_v); + + /* read security config */ + config_read_security(fd, &(cfg->sec), param_n, param_v); + + /* read session config */ + config_read_sessions(fd, &(cfg->sess), param_n, param_v); + + config_read_session_variables(fd, cfg, param_n, param_v); + + /* cleanup */ + list_delete(sec); + list_delete(param_v); + list_delete(param_n); + g_file_close(fd); + all_ok = 1; + } + } + } + + if (!all_ok) + { + config_free(cfg); + cfg = NULL; + } + + return cfg; +} + +/******************************************************************************/ void config_dump(struct config_sesman *config) { @@ -468,6 +531,7 @@ sc = &(config->sec); /* Global sesman configuration */ + g_writeln("Filename: %s", config->sesman_ini); g_writeln("Global configuration:"); g_writeln(" ListenAddress: %s", config->listen_address); g_writeln(" ListenPort: %s", config->listen_port); @@ -567,16 +631,21 @@ } } +/******************************************************************************/ void config_free(struct config_sesman *cs) { - g_free(cs->default_wm); - g_free(cs->reconnect_sh); - g_free(cs->auth_file_path); - list_delete(cs->rdp_params); - list_delete(cs->vnc_params); - list_delete(cs->xorg_params); - list_delete(cs->env_names); - list_delete(cs->env_values); - g_free(cs); + if (cs != NULL) + { + g_free(cs->sesman_ini); + g_free(cs->default_wm); + g_free(cs->reconnect_sh); + g_free(cs->auth_file_path); + list_delete(cs->rdp_params); + list_delete(cs->vnc_params); + list_delete(cs->xorg_params); + list_delete(cs->env_names); + list_delete(cs->env_values); + g_free(cs); + } } diff -Nru xrdp-0.9.12/sesman/config.h xrdp-0.9.15/sesman/config.h --- xrdp-0.9.12/sesman/config.h 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/config.h 2020-12-28 14:03:43.000000000 +0000 @@ -187,6 +187,12 @@ struct config_sesman { /** + * @var sesman_ini + * @brief File that these parameters are read from + */ + char *sesman_ini; + + /** * @var listen_address * @brief Listening address */ @@ -267,102 +273,17 @@ /** * * @brief Reads sesman configuration - * @param cfg pointer to configuration object to be replaced - * @return 0 on success, 1 on failure - * - */ -int -config_read(struct config_sesman* cfg); - -/** - * - * @brief Reads sesman [global] configuration section - * @param file configuration file descriptor - * @param cf pointer to a config struct - * @param param_n parameter name list - * @param param_v parameter value list - * @return 0 on success, 1 on failure - * - */ -int -config_read_globals(int file, struct config_sesman* cf, - struct list* param_n, struct list* param_v); - -/** + * @param sesman_ini Name of configuration file to read + * @return configuration on success, NULL on failure * - * @brief Reads sesman [Security] configuration section - * @param file configuration file descriptor - * @param sc pointer to a config_security struct - * @param param_n parameter name list - * @param param_v parameter value list - * @return 0 on success, 1 on failure + * @post pass return value to config_free() to prevent memory leaks * */ -int -config_read_security(int file, struct config_security* sc, - struct list* param_n, struct list* param_v); +struct config_sesman* +config_read(const char *sesman_ini); /** * - * @brief Reads sesman [Sessions] configuration section - * @param file configuration file descriptor - * @param ss pointer to a config_sessions struct - * @param param_n parameter name list - * @param param_v parameter value list - * @return 0 on success, 1 on failure - * - */ -int -config_read_sessions(int file, struct config_sessions* ss, - struct list* param_n, struct list* param_v); - -/** - * - * @brief Reads sesman [X11rdp] configuration section - * @param file configuration file descriptor - * @param cs pointer to a config_sesman struct - * @param param_n parameter name list - * @param param_v parameter value list - * @return 0 on success, 1 on failure - * - */ -int -config_read_rdp_params(int file, struct config_sesman* cs, struct list* param_n, - struct list* param_v); - -/** - * - * @brief Reads sesman [Xorg] configuration section - * @param file configuration file descriptor - * @param cs pointer to a config_sesman struct - * @param param_n parameter name list - * @param param_v parameter value list - * @return 0 on success, 1 on failure - * - */ -int -config_read_xorg_params(int file, struct config_sesman* cs, struct list* param_n, - struct list* param_v); - -/** - * - * @brief Reads sesman [Xvnc] configuration section - * @param file configuration file descriptor - * @param cs pointer to a config_sesman struct - * @param param_n parameter name list - * @param param_v parameter value list - * @return 0 on success, 1 on failure - * - */ -int -config_read_vnc_params(int file, struct config_sesman* cs, struct list* param_n, - struct list* param_v); - -int -config_read_session_variables(int file, struct config_sesman *cs, - struct list *param_n, struct list *param_v); -/** - * * @brief Dumps configuration * @param pointer to a config_sesman struct * @@ -370,6 +291,12 @@ void config_dump(struct config_sesman *config); +/** + * + * @brief Frees configuration allocated by config_read() + * @param pointer to a config_sesman struct (may be NULL) + * + */ void config_free(struct config_sesman *cs); diff -Nru xrdp-0.9.12/sesman/env.c xrdp-0.9.15/sesman/env.c --- xrdp-0.9.12/sesman/env.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/env.c 2020-12-28 14:03:43.000000000 +0000 @@ -34,6 +34,7 @@ #include "list.h" #include "sesman.h" #include "ssl_calls.h" +#include "string_calls.h" extern unsigned char g_fixedkey[8]; /* in sesman.c */ extern struct config_sesman *g_cfg; /* in sesman.c */ @@ -76,9 +77,9 @@ fd = g_file_open_ex(filename, 0, 1, 1, 1); if (fd == -1) { - log_message(LOG_LEVEL_WARNING, - "Cannot write VNC password hash to file %s: %s", - filename, g_get_strerror()); + LOG(LOG_LEVEL_WARNING, + "Cannot write VNC password hash to file %s: %s", + filename, g_get_strerror()); return 1; } g_file_write(fd, encryptedPasswd, 8); @@ -151,7 +152,7 @@ g_snprintf(text, sizeof(text) - 1, CHANSRV_PORT_IN_BASE_STR, display); g_setenv("XRDP_PULSE_SOURCE_SOCKET", text, 1); if ((env_names != 0) && (env_values != 0) && - (env_names->count == env_values->count)) + (env_names->count == env_values->count)) { for (index = 0; index < env_names->count; index++) { @@ -172,9 +173,9 @@ { if (g_mkdir(".vnc") < 0) { - log_message(LOG_LEVEL_ERROR, - "Error creating .vnc directory: %s", - g_get_strerror()); + LOG(LOG_LEVEL_ERROR, + "Error creating .vnc directory: %s", + g_get_strerror()); } } @@ -189,16 +190,16 @@ pw_dir, username, display); if (g_file_exist(*passwd_file)) { - log_message(LOG_LEVEL_WARNING, "Removing old " - "password file %s", *passwd_file); + LOG(LOG_LEVEL_WARNING, "Removing old " + "password file %s", *passwd_file); g_file_delete(*passwd_file); } g_sprintf(*passwd_file, "%s/.vnc/sesman_%s_passwd", pw_dir, username); if (g_file_exist(*passwd_file)) { - log_message(LOG_LEVEL_WARNING, "Removing insecure " - "password file %s", *passwd_file); + LOG(LOG_LEVEL_WARNING, "Removing insecure " + "password file %s", *passwd_file); g_file_delete(*passwd_file); } g_sprintf(*passwd_file, "%s/.vnc/sesman_passwd-%s@%s:%d", @@ -219,7 +220,7 @@ if (*passwd_file != NULL) { - LOG_DBG("pass file: %s", *passwd_file); + LOG_DEVEL(LOG_LEVEL_DEBUG, "pass file: %s", *passwd_file); } } @@ -229,9 +230,9 @@ } else { - log_message(LOG_LEVEL_ERROR, - "error getting user info for user %s", - username); + LOG(LOG_LEVEL_ERROR, + "error getting user info for user %s", + username); } return error; diff -Nru xrdp-0.9.12/sesman/libscp/libscp_connection.c xrdp-0.9.15/sesman/libscp/libscp_connection.c --- xrdp-0.9.12/sesman/libscp/libscp_connection.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/libscp/libscp_connection.c 2020-12-28 14:03:43.000000000 +0000 @@ -41,7 +41,7 @@ if (0 == conn) { - log_message(LOG_LEVEL_ERROR, "[connection:%d] connection create: malloc error", __LINE__); + LOG(LOG_LEVEL_ERROR, "[connection:%d] connection create: malloc error", __LINE__); return 0; } diff -Nru xrdp-0.9.12/sesman/libscp/libscp_init.c xrdp-0.9.15/sesman/libscp/libscp_init.c --- xrdp-0.9.12/sesman/libscp/libscp_init.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/libscp/libscp_init.c 2020-12-28 14:03:43.000000000 +0000 @@ -47,7 +47,7 @@ scp_lock_init(); - log_message(LOG_LEVEL_DEBUG, "libscp initialized"); + LOG(LOG_LEVEL_DEBUG, "libscp initialized"); return 0; } diff -Nru xrdp-0.9.12/sesman/libscp/libscp_lock.c xrdp-0.9.15/sesman/libscp/libscp_lock.c --- xrdp-0.9.12/sesman/libscp/libscp_lock.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/libscp/libscp_lock.c 2020-12-28 14:03:43.000000000 +0000 @@ -98,7 +98,7 @@ void scp_lock_fork_critical_section_end(int blocking) { - //LOG_DBG("lock_fork_critical_section_end()",0); + //LOG_DEVEL(LOG_LEVEL_DEBUG, "lock_fork_critical_section_end()",0); /* lock mutex */ pthread_mutex_lock(&lock_fork); @@ -121,7 +121,7 @@ int scp_lock_fork_critical_section_start(void) { - //LOG_DBG("lock_fork_critical_section_start()",0); + //LOG_DEVEL(LOG_LEVEL_DEBUG, "lock_fork_critical_section_start()",0); do { pthread_mutex_lock(&lock_fork); diff -Nru xrdp-0.9.12/sesman/libscp/libscp_session.c xrdp-0.9.15/sesman/libscp/libscp_session.c --- xrdp-0.9.12/sesman/libscp/libscp_session.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/libscp/libscp_session.c 2020-12-28 14:03:43.000000000 +0000 @@ -29,6 +29,7 @@ #endif #include "libscp_session.h" +#include "string_calls.h" #include #include @@ -46,7 +47,7 @@ if (0 == s) { - log_message(LOG_LEVEL_ERROR, "[session:%d] session create: malloc error", __LINE__); + LOG(LOG_LEVEL_ERROR, "[session:%d] session create: malloc error", __LINE__); return 0; } @@ -81,14 +82,14 @@ if (NULL == s->mng) { - log_message(LOG_LEVEL_ERROR, "[session:%d] set_type: internal error", __LINE__); + LOG(LOG_LEVEL_ERROR, "[session:%d] set_type: internal error", __LINE__); return 1; } break; default: - log_message(LOG_LEVEL_WARNING, "[session:%d] set_type: unknown type", __LINE__); + LOG(LOG_LEVEL_WARNING, "[session:%d] set_type: unknown type", __LINE__); return 1; } @@ -108,7 +109,7 @@ s->version = 1; break; default: - log_message(LOG_LEVEL_WARNING, "[session:%d] set_version: unknown version", __LINE__); + LOG(LOG_LEVEL_WARNING, "[session:%d] set_version: unknown version", __LINE__); return 1; } @@ -172,7 +173,7 @@ { if (0 == str) { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_locale: null locale", __LINE__); + LOG(LOG_LEVEL_WARNING, "[session:%d] set_locale: null locale", __LINE__); s->locale[0] = '\0'; return 1; } @@ -188,7 +189,7 @@ { if (0 == str) { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_username: null username", __LINE__); + LOG(LOG_LEVEL_WARNING, "[session:%d] set_username: null username", __LINE__); return 1; } @@ -201,7 +202,7 @@ if (0 == s->username) { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_username: strdup error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[session:%d] set_username: strdup error", __LINE__); return 1; } @@ -214,7 +215,7 @@ { if (0 == str) { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_password: null password", __LINE__); + LOG(LOG_LEVEL_WARNING, "[session:%d] set_password: null password", __LINE__); return 1; } @@ -227,7 +228,7 @@ if (0 == s->password) { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_password: strdup error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[session:%d] set_password: strdup error", __LINE__); return 1; } @@ -240,7 +241,7 @@ { if (0 == str) { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_domain: null domain", __LINE__); + LOG(LOG_LEVEL_WARNING, "[session:%d] set_domain: null domain", __LINE__); return 1; } @@ -253,7 +254,7 @@ if (0 == s->domain) { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_domain: strdup error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[session:%d] set_domain: strdup error", __LINE__); return 1; } @@ -266,7 +267,7 @@ { if (0 == str) { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_program: null program", __LINE__); + LOG(LOG_LEVEL_WARNING, "[session:%d] set_program: null program", __LINE__); return 1; } @@ -279,7 +280,7 @@ if (0 == s->program) { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_program: strdup error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[session:%d] set_program: strdup error", __LINE__); return 1; } @@ -292,7 +293,7 @@ { if (0 == str) { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_directory: null directory", __LINE__); + LOG(LOG_LEVEL_WARNING, "[session:%d] set_directory: null directory", __LINE__); return 1; } @@ -305,7 +306,7 @@ if (0 == s->directory) { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_directory: strdup error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[session:%d] set_directory: strdup error", __LINE__); return 1; } @@ -318,7 +319,7 @@ { if (0 == str) { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: null ip", __LINE__); + LOG(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: null ip", __LINE__); return 1; } @@ -331,7 +332,7 @@ if (0 == s->client_ip) { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: strdup error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: strdup error", __LINE__); return 1; } @@ -344,7 +345,7 @@ { if (0 == str) { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_hostname: null hostname", __LINE__); + LOG(LOG_LEVEL_WARNING, "[session:%d] set_hostname: null hostname", __LINE__); return 1; } @@ -357,7 +358,7 @@ if (0 == s->hostname) { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_hostname: strdup error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[session:%d] set_hostname: strdup error", __LINE__); return 1; } @@ -370,7 +371,7 @@ { if (0 == str) { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_errstr: null string", __LINE__); + LOG(LOG_LEVEL_WARNING, "[session:%d] set_errstr: null string", __LINE__); return 1; } @@ -383,7 +384,7 @@ if (0 == s->errstr) { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_errstr: strdup error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[session:%d] set_errstr: strdup error", __LINE__); return 1; } @@ -425,7 +426,7 @@ { if (0 == guid) { - log_message(LOG_LEVEL_WARNING, "[session:%d] set_guid: null guid", __LINE__); + LOG(LOG_LEVEL_WARNING, "[session:%d] set_guid: null guid", __LINE__); return 1; } diff -Nru xrdp-0.9.12/sesman/libscp/libscp_tcp.c xrdp-0.9.15/sesman/libscp/libscp_tcp.c --- xrdp-0.9.12/sesman/libscp/libscp_tcp.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/libscp/libscp_tcp.c 2020-12-28 14:03:43.000000000 +0000 @@ -39,7 +39,7 @@ int rcvd; int block; - LOG_DBG("scp_tcp_force_recv()"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scp_tcp_force_recv()"); block = scp_lock_fork_critical_section_start(); while (len > 0) @@ -82,7 +82,7 @@ int sent; int block; - LOG_DBG("scp_tcp_force_send()"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "scp_tcp_force_send()"); block = scp_lock_fork_critical_section_start(); while (len > 0) diff -Nru xrdp-0.9.12/sesman/libscp/libscp_types.h xrdp-0.9.15/sesman/libscp/libscp_types.h --- xrdp-0.9.12/sesman/libscp/libscp_types.h 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/libscp/libscp_types.h 2020-12-28 13:47:14.000000000 +0000 @@ -59,6 +59,10 @@ #include "libscp_types_mng.h" +/* Max server incoming and outgoing message size, used to stop memory + exhaustion attempts (CVE-2020-4044) */ +#define SCP_MAX_MESSAGE_SIZE 8192 + struct SCP_CONNECTION { int in_sck; diff -Nru xrdp-0.9.12/sesman/libscp/libscp_v0.c xrdp-0.9.15/sesman/libscp/libscp_v0.c --- xrdp-0.9.12/sesman/libscp/libscp_v0.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/libscp/libscp_v0.c 2020-12-28 14:03:43.000000000 +0000 @@ -31,22 +31,76 @@ #include "libscp_v0.h" #include "os_calls.h" +#include "string_calls.h" extern struct log_config *s_log; +/** Maximum length of a string (two bytes + len), excluding the terminator + * + * Practially this is limited by [MS-RDPBCGR] TS_INFO_PACKET + * */ +#define STRING16_MAX_LEN 512 + +/** + * Reads a big-endian uint16 followed by a string into a buffer + * + * Buffer is null-terminated on success + * + * @param s Input stream + * @param [out] Output buffer (must be >= (STRING16_MAX_LEN+1) chars) + * @param param Parameter we're reading + * @return != 0 if string read OK + */ +static +int in_string16(struct stream *s, char str[], const char *param) +{ + int result; + + if (!s_check_rem(s, 2)) + { + LOG(LOG_LEVEL_WARNING, "connection aborted: %s len missing", param); + result = 0; + } + else + { + unsigned int sz; + + in_uint16_be(s, sz); + if (sz > STRING16_MAX_LEN) + { + LOG(LOG_LEVEL_WARNING, + "connection aborted: %s too long (%u chars)", param, sz); + result = 0; + } + else + { + result = s_check_rem(s, sz); + if (!result) + { + LOG(LOG_LEVEL_WARNING, "connection aborted: %s data missing", param); + } + else + { + in_uint8a(s, str, sz); + str[sz] = '\0'; + } + } + } + return result; +} /* client API */ /******************************************************************************/ enum SCP_CLIENT_STATES_E scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { tui32 version; - tui32 size; + int size; tui16 sz; init_stream(c->in_s, c->in_s->size); init_stream(c->out_s, c->in_s->size); - LOG_DBG("[v0:%d] starting connection", __LINE__); + LOG_DEVEL(LOG_LEVEL_DEBUG, "starting connection"); g_tcp_set_non_blocking(c->in_sck); g_tcp_set_no_delay(c->in_sck); s_push_layer(c->out_s, channel_hdr, 8); @@ -66,15 +120,25 @@ } else { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "connection aborted: network error"); return SCP_CLIENT_STATE_INTERNAL_ERR; } sz = g_strlen(s->username); + if (sz > STRING16_MAX_LEN) + { + LOG(LOG_LEVEL_WARNING, "connection aborted: username too long"); + return SCP_CLIENT_STATE_SIZE_ERR; + } out_uint16_be(c->out_s, sz); out_uint8a(c->out_s, s->username, sz); sz = g_strlen(s->password); + if (sz > STRING16_MAX_LEN) + { + LOG(LOG_LEVEL_WARNING, "connection aborted: password too long"); + return SCP_CLIENT_STATE_SIZE_ERR; + } out_uint16_be(c->out_s, sz); out_uint8a(c->out_s, s->password, sz); out_uint16_be(c->out_s, s->width); @@ -91,13 +155,13 @@ if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data)) { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "connection aborted: network error"); return SCP_CLIENT_STATE_NETWORK_ERR; } if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "connection aborted: network error"); return SCP_CLIENT_STATE_NETWORK_ERR; } @@ -105,33 +169,35 @@ if (0 != version) { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__); + LOG(LOG_LEVEL_WARNING, "connection aborted: version error"); return SCP_CLIENT_STATE_VERSION_ERR; } in_uint32_be(c->in_s, size); - if (size < 14) + if (size < (8 + 2 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE) { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: packet size error", __LINE__); + LOG(LOG_LEVEL_WARNING, "connection aborted: msg size = %d", size); return SCP_CLIENT_STATE_SIZE_ERR; } /* getting payload */ - init_stream(c->in_s, c->in_s->size); + init_stream(c->in_s, size - 8); if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "connection aborted: network error"); return SCP_CLIENT_STATE_NETWORK_ERR; } + c->in_s->end = c->in_s->data + (size - 8); + /* check code */ in_uint16_be(c->in_s, sz); if (3 != sz) { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__); + LOG(LOG_LEVEL_WARNING, "connection aborted: sequence error"); return SCP_CLIENT_STATE_SEQUENCE_ERR; } @@ -140,58 +206,51 @@ if (1 != sz) { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: connection denied", __LINE__); + LOG(LOG_LEVEL_WARNING, "connection aborted: connection denied"); return SCP_CLIENT_STATE_CONNECTION_DENIED; } in_uint16_be(c->in_s, sz); s->display = sz; - LOG_DBG("[v0:%d] connection terminated", __LINE__); + LOG_DEVEL(LOG_LEVEL_DEBUG, "connection terminated"); return SCP_CLIENT_STATE_END; } -/* server API */ -/******************************************************************************/ -enum SCP_SERVER_STATES_E -scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk) +/** + * Initialises a V0 session object + * + * At the time of the call, the version has been read from the connection + * + * @param c Connection + * @param [out] session pre-allocated session object + * @return SCP_SERVER_STATE_OK for success + */ +static enum SCP_SERVER_STATES_E +scp_v0s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session) { - tui32 version = 0; - tui32 size; - struct SCP_SESSION *session = 0; - tui16 sz; + int size; + tui16 height; + tui16 width; + tui16 bpp; tui32 code = 0; - char *buf = 0; - - if (!skipVchk) - { - LOG_DBG("[v0:%d] starting connection", __LINE__); + char buf[STRING16_MAX_LEN + 1]; - if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) - { - c->in_s->end = c->in_s->data + 8; - in_uint32_be(c->in_s, version); - - if (version != 0) - { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__); - return SCP_SERVER_STATE_VERSION_ERR; - } - } - else - { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_NETWORK_ERR; - } - } + scp_session_set_version(session, 0); + /* Check for a header and a code value in the length */ in_uint32_be(c->in_s, size); + if (size < (8 + 2) || size > SCP_MAX_MESSAGE_SIZE) + { + LOG(LOG_LEVEL_WARNING, "connection aborted: msg size = %d", size); + return SCP_SERVER_STATE_SIZE_ERR; + } - init_stream(c->in_s, 8196); + init_stream(c->in_s, size - 8); if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "connection aborted: network error"); return SCP_SERVER_STATE_NETWORK_ERR; } @@ -201,16 +260,6 @@ if (code == 0 || code == 10 || code == 20) { - session = scp_session_create(); - - if (0 == session) - { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - scp_session_set_version(session, version); - if (code == 0) { scp_session_set_type(session, SCP_SESSION_TYPE_XVNC); @@ -225,165 +274,193 @@ } /* reading username */ - in_uint16_be(c->in_s, sz); - buf = g_new0(char, sz + 1); - in_uint8a(c->in_s, buf, sz); - buf[sz] = '\0'; + if (!in_string16(c->in_s, buf, "username")) + { + return SCP_SERVER_STATE_SIZE_ERR; + } if (0 != scp_session_set_username(session, buf)) { - scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__); - g_free(buf); + LOG(LOG_LEVEL_WARNING, "connection aborted: error setting username"); return SCP_SERVER_STATE_INTERNAL_ERR; } - g_free(buf); /* reading password */ - in_uint16_be(c->in_s, sz); - buf = g_new0(char, sz + 1); - in_uint8a(c->in_s, buf, sz); - buf[sz] = '\0'; + if (!in_string16(c->in_s, buf, "passwd")) + { + return SCP_SERVER_STATE_SIZE_ERR; + } if (0 != scp_session_set_password(session, buf)) { - scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__); - g_free(buf); + LOG(LOG_LEVEL_WARNING, "connection aborted: error setting password"); return SCP_SERVER_STATE_INTERNAL_ERR; } - g_free(buf); - /* width */ - in_uint16_be(c->in_s, sz); - scp_session_set_width(session, sz); - /* height */ - in_uint16_be(c->in_s, sz); - scp_session_set_height(session, sz); - /* bpp */ - in_uint16_be(c->in_s, sz); - if (0 != scp_session_set_bpp(session, (tui8)sz)) - { - scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, - "[v0:%d] connection aborted: unsupported bpp: %d", - __LINE__, (tui8)sz); + /* width + height + bpp */ + if (!s_check_rem(c->in_s, 2 + 2 + 2)) + { + LOG(LOG_LEVEL_WARNING, "connection aborted: width+height+bpp missing"); + return SCP_SERVER_STATE_SIZE_ERR; + } + in_uint16_be(c->in_s, width); + scp_session_set_width(session, width); + in_uint16_be(c->in_s, height); + scp_session_set_height(session, height); + in_uint16_be(c->in_s, bpp); + if (0 != scp_session_set_bpp(session, (tui8)bpp)) + { + LOG(LOG_LEVEL_WARNING, + "connection aborted: unsupported bpp: %d", (tui8)bpp); return SCP_SERVER_STATE_INTERNAL_ERR; } if (s_check_rem(c->in_s, 2)) { /* reading domain */ - in_uint16_be(c->in_s, sz); - - if (sz > 0) + if (!in_string16(c->in_s, buf, "domain")) + { + return SCP_SERVER_STATE_SIZE_ERR; + } + if (buf[0] != '\0') { - buf = g_new0(char, sz + 1); - in_uint8a(c->in_s, buf, sz); - buf[sz] = '\0'; scp_session_set_domain(session, buf); - g_free(buf); } } if (s_check_rem(c->in_s, 2)) { /* reading program */ - in_uint16_be(c->in_s, sz); + if (!in_string16(c->in_s, buf, "program")) + { + return SCP_SERVER_STATE_SIZE_ERR; + } - if (sz > 0) + if (buf[0] != '\0') { - buf = g_new0(char, sz + 1); - in_uint8a(c->in_s, buf, sz); - buf[sz] = '\0'; scp_session_set_program(session, buf); - g_free(buf); } } if (s_check_rem(c->in_s, 2)) { /* reading directory */ - in_uint16_be(c->in_s, sz); + if (!in_string16(c->in_s, buf, "directory")) + { + return SCP_SERVER_STATE_SIZE_ERR; + } - if (sz > 0) + if (buf[0] != '\0') { - buf = g_new0(char, sz + 1); - in_uint8a(c->in_s, buf, sz); - buf[sz] = '\0'; scp_session_set_directory(session, buf); - g_free(buf); } } if (s_check_rem(c->in_s, 2)) { /* reading client IP address */ - in_uint16_be(c->in_s, sz); - - if (sz > 0) + if (!in_string16(c->in_s, buf, "client IP")) + { + return SCP_SERVER_STATE_SIZE_ERR; + } + if (buf[0] != '\0') { - buf = g_new0(char, sz + 1); - in_uint8a(c->in_s, buf, sz); - buf[sz] = '\0'; scp_session_set_client_ip(session, buf); - g_free(buf); } } } else if (code == SCP_GW_AUTHENTICATION) { - /* g_writeln("Command is SCP_GW_AUTHENTICATION"); */ - session = scp_session_create(); - - if (0 == session) - { - /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);*/ - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - scp_session_set_version(session, version); scp_session_set_type(session, SCP_GW_AUTHENTICATION); /* reading username */ - in_uint16_be(c->in_s, sz); - buf = g_new0(char, sz + 1); - in_uint8a(c->in_s, buf, sz); - buf[sz] = '\0'; + if (!in_string16(c->in_s, buf, "username")) + { + return SCP_SERVER_STATE_SIZE_ERR; + } /* g_writeln("Received user name: %s",buf); */ if (0 != scp_session_set_username(session, buf)) { - scp_session_destroy(session); - /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__);*/ - g_free(buf); + LOG(LOG_LEVEL_WARNING, "connection aborted: error setting username"); return SCP_SERVER_STATE_INTERNAL_ERR; } - g_free(buf); /* reading password */ - in_uint16_be(c->in_s, sz); - buf = g_new0(char, sz + 1); - in_uint8a(c->in_s, buf, sz); - buf[sz] = '\0'; + if (!in_string16(c->in_s, buf, "passwd")) + { + return SCP_SERVER_STATE_SIZE_ERR; + } /* g_writeln("Received password: %s",buf); */ if (0 != scp_session_set_password(session, buf)) { - scp_session_destroy(session); - /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__); */ - g_free(buf); + LOG(LOG_LEVEL_WARNING, "connection aborted: error setting password"); return SCP_SERVER_STATE_INTERNAL_ERR; } - g_free(buf); } else { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__); + LOG(LOG_LEVEL_WARNING, "connection aborted: sequence error"); return SCP_SERVER_STATE_SEQUENCE_ERR; } - (*s) = session; return SCP_SERVER_STATE_OK; } + +/* server API */ +/******************************************************************************/ +enum SCP_SERVER_STATES_E +scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk) +{ + enum SCP_SERVER_STATES_E result = SCP_SERVER_STATE_OK; + struct SCP_SESSION *session = NULL; + tui32 version = 0; + + if (!skipVchk) + { + LOG_DEVEL(LOG_LEVEL_DEBUG, "starting connection"); + + if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) + { + c->in_s->end = c->in_s->data + 8; + in_uint32_be(c->in_s, version); + + if (version != 0) + { + LOG(LOG_LEVEL_WARNING, "connection aborted: version error"); + result = SCP_SERVER_STATE_VERSION_ERR; + } + } + else + { + LOG(LOG_LEVEL_WARNING, "connection aborted: network error"); + result = SCP_SERVER_STATE_NETWORK_ERR; + } + } + + if (result == SCP_SERVER_STATE_OK) + { + session = scp_session_create(); + if (NULL == session) + { + LOG(LOG_LEVEL_WARNING, "connection aborted: no memory"); + result = SCP_SERVER_STATE_INTERNAL_ERR; + } + else + { + result = scp_v0s_init_session(c, session); + if (result != SCP_SERVER_STATE_OK) + { + scp_session_destroy(session); + session = NULL; + } + } + } + + (*s) = session; + + return result; +} + /******************************************************************************/ enum SCP_SERVER_STATES_E scp_v0s_allow_connection(struct SCP_CONNECTION *c, SCP_DISPLAY d, const tui8 *guid) @@ -404,11 +481,11 @@ if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data)) { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "connection aborted: network error"); return SCP_SERVER_STATE_NETWORK_ERR; } - LOG_DBG("[v0:%d] connection terminated (allowed)", __LINE__); + LOG_DEVEL(LOG_LEVEL_DEBUG, "connection terminated (allowed)"); return SCP_SERVER_STATE_OK; } @@ -425,11 +502,11 @@ if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data)) { - log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "connection aborted: network error"); return SCP_SERVER_STATE_NETWORK_ERR; } - LOG_DBG("[v0:%d] connection terminated (denied)", __LINE__); + LOG_DEVEL(LOG_LEVEL_DEBUG, "connection terminated (denied)"); return SCP_SERVER_STATE_OK; } @@ -448,10 +525,10 @@ /* g_writeln("Total number of bytes that will be sent %d",c->out_s->end - c->out_s->data);*/ if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data)) { - /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); */ + LOG(LOG_LEVEL_WARNING, "connection aborted: network error"); return SCP_SERVER_STATE_NETWORK_ERR; } - /* until syslog merge LOG_DBG(s_log, "[v0:%d] connection terminated (scp_v0s_deny_authentication)", __LINE__);*/ + LOG_DEVEL(LOG_LEVEL_DEBUG, "connection terminated (scp_v0s_deny_authentication)"); return SCP_SERVER_STATE_OK; } diff -Nru xrdp-0.9.12/sesman/libscp/libscp_v1c.c xrdp-0.9.15/sesman/libscp/libscp_v1c.c --- xrdp-0.9.12/sesman/libscp/libscp_v1c.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/libscp/libscp_v1c.c 2020-12-28 14:03:43.000000000 +0000 @@ -29,6 +29,7 @@ #endif #include "libscp_v1c.h" +#include "string_calls.h" #include #include @@ -47,8 +48,8 @@ init_stream(c->out_s, c->out_s->size); init_stream(c->in_s, c->in_s->size); - size = 19 + 17 + 4 + g_strlen(s->hostname) + g_strlen(s->username) + - g_strlen(s->password); + size = (19 + 17 + 4 + g_strlen(s->hostname) + g_strlen(s->username) + + g_strlen(s->password)); if (s->addr_type == SCP_ADDRESS_TYPE_IPV4) { diff -Nru xrdp-0.9.12/sesman/libscp/libscp_v1c_mng.c xrdp-0.9.15/sesman/libscp/libscp_v1c_mng.c --- xrdp-0.9.12/sesman/libscp/libscp_v1c_mng.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/libscp/libscp_v1c_mng.c 2020-12-28 14:03:43.000000000 +0000 @@ -29,6 +29,7 @@ #endif #include "libscp_v1c_mng.h" +#include "string_calls.h" #include #include @@ -49,8 +50,8 @@ init_stream(c->out_s, c->out_s->size); init_stream(c->in_s, c->in_s->size); - size = 12 + 4 + g_strlen(s->hostname) + g_strlen(s->username) + - g_strlen(s->password); + size = (12 + 4 + g_strlen(s->hostname) + g_strlen(s->username) + + g_strlen(s->password)); if (s->addr_type == SCP_ADDRESS_TYPE_IPV4) { @@ -96,7 +97,7 @@ if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); return SCP_CLIENT_STATE_NETWORK_ERR; } @@ -132,7 +133,7 @@ if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); return SCP_CLIENT_STATE_NETWORK_ERR; } @@ -143,7 +144,7 @@ if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); g_free(ds); return SCP_CLIENT_STATE_NETWORK_ERR; } @@ -152,7 +153,7 @@ if (version != 1) { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__); g_free(ds); return SCP_CLIENT_STATE_VERSION_ERR; } @@ -161,7 +162,7 @@ if (size < 12) { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: size error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: size error", __LINE__); g_free(ds); return SCP_CLIENT_STATE_SIZE_ERR; } @@ -170,7 +171,7 @@ if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); g_free(ds); return SCP_CLIENT_STATE_NETWORK_ERR; } @@ -179,7 +180,7 @@ if (cmd != SCP_COMMAND_SET_MANAGE) { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__); g_free(ds); return SCP_CLIENT_STATE_SEQUENCE_ERR; } @@ -188,7 +189,7 @@ if (cmd != SCP_CMD_MNG_LIST) /* session list */ { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__); g_free(ds); return SCP_CLIENT_STATE_SEQUENCE_ERR; } @@ -205,7 +206,7 @@ (*scount) = sescnt; (*s) = NULL; - LOG_DBG("[v1c_mng] end list - no session on TS"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "[v1c_mng] end list - no session on TS"); return SCP_CLIENT_STATE_LIST_OK; } @@ -213,7 +214,7 @@ if (ds == 0) { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: internal error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: internal error", __LINE__); return SCP_CLIENT_STATE_INTERNAL_ERR; } } @@ -262,7 +263,7 @@ (*scount) = sescnt; (*s) = ds; - LOG_DBG("[v1c_mng] end list"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "[v1c_mng] end list"); return SCP_CLIENT_STATE_LIST_OK; } @@ -373,7 +374,7 @@ if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); return SCP_CLIENT_STATE_NETWORK_ERR; } @@ -381,7 +382,7 @@ if (version != 1) { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__); return SCP_CLIENT_STATE_VERSION_ERR; } @@ -392,7 +393,7 @@ /* read the rest of the packet */ if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); return SCP_CLIENT_STATE_NETWORK_ERR; } @@ -400,7 +401,7 @@ if (cmd != SCP_COMMAND_SET_MANAGE) { - log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__); return SCP_CLIENT_STATE_SEQUENCE_ERR; } @@ -408,7 +409,7 @@ if (cmd == SCP_CMD_MNG_LOGIN_ALLOW) /* connection ok */ { - log_message(LOG_LEVEL_INFO, "[v1c_mng:%d] connection ok", __LINE__); + LOG(LOG_LEVEL_INFO, "[v1c_mng:%d] connection ok", __LINE__); return SCP_CLIENT_STATE_OK; } else if (cmd == SCP_CMD_MNG_LOGIN_DENY) /* connection denied */ @@ -418,10 +419,10 @@ in_uint8a(c->in_s, buf, dim); scp_session_set_errstr(s, buf); - log_message(LOG_LEVEL_INFO, "[v1c_mng:%d] connection denied: %s", __LINE__ , s->errstr); + LOG(LOG_LEVEL_INFO, "[v1c_mng:%d] connection denied: %s", __LINE__, s->errstr); return SCP_CLIENT_STATE_CONNECTION_DENIED; } - log_message(LOG_LEVEL_WARNING, "[v1c-mng:%d] connection aborted: sequence error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1c-mng:%d] connection aborted: sequence error", __LINE__); return SCP_CLIENT_STATE_SEQUENCE_ERR; } diff -Nru xrdp-0.9.12/sesman/libscp/libscp_v1s.c xrdp-0.9.15/sesman/libscp/libscp_v1s.c --- xrdp-0.9.12/sesman/libscp/libscp_v1s.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/libscp/libscp_v1s.c 2020-12-28 14:03:43.000000000 +0000 @@ -32,19 +32,198 @@ #define LIBSCP_V1S_C #include "libscp_v1s.h" +#include "string_calls.h" //extern struct log_config* s_log; +/** + * Reads a uint8 followed by a string into a buffer + * + * Buffer is null-terminated on success + * + * @param s Input stream + * @param [out] Output buffer (must be >= 256 chars) + * @param param Parameter we're reading + * @param line Line number reference + * @return != 0 if string read OK + * + * @todo + * This needs to be merged with the func of the same name in + * libscp_v1s_mng.c + */ +static +int in_string8(struct stream *s, char str[], const char *param, int line) +{ + int result; + + if (!s_check_rem(s, 1)) + { + LOG(LOG_LEVEL_WARNING, + "[v1s:%d] connection aborted: %s len missing", + line, param); + result = 0; + } + else + { + unsigned int sz; + + in_uint8(s, sz); + result = s_check_rem(s, sz); + if (!result) + { + LOG(LOG_LEVEL_WARNING, + "[v1s:%d] connection aborted: %s data missing", + line, param); + } + else + { + in_uint8a(s, str, sz); + str[sz] = '\0'; + } + } + return result; +} +/* server API */ + +/** + * Initialises a V1 session object + * + * This is called after the V1 header, command set and command have been read + * + * @param c Connection + * @param [out] session pre-allocated session object + * @return SCP_SERVER_STATE_OK for success + */ +static enum SCP_SERVER_STATES_E +scp_v1s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session) +{ + tui8 type; + tui16 height; + tui16 width; + tui8 bpp; + tui8 sz; + char buf[256]; + + scp_session_set_version(session, 1); + + /* Check there's data for the session type, the height, the width, the + * bpp, the resource sharing indicator and the locale */ + if (!s_check_rem(c->in_s, 1 + 2 + 2 + 1 + 1 + 17)) + { + LOG(LOG_LEVEL_WARNING, + "[v1s:%d] connection aborted: short packet", + __LINE__); + return SCP_SERVER_STATE_SIZE_ERR; + } + + in_uint8(c->in_s, type); + + if ((type != SCP_SESSION_TYPE_XVNC) && (type != SCP_SESSION_TYPE_XRDP)) + { + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: unknown session type", __LINE__); + return SCP_SERVER_STATE_SESSION_TYPE_ERR; + } + + scp_session_set_type(session, type); + + in_uint16_be(c->in_s, height); + scp_session_set_height(session, height); + in_uint16_be(c->in_s, width); + scp_session_set_width(session, width); + in_uint8(c->in_s, bpp); + if (0 != scp_session_set_bpp(session, bpp)) + { + LOG(LOG_LEVEL_WARNING, + "[v1s:%d] connection aborted: unsupported bpp: %d", + __LINE__, bpp); + return SCP_SERVER_STATE_INTERNAL_ERR; + } + in_uint8(c->in_s, sz); + scp_session_set_rsr(session, sz); + in_uint8a(c->in_s, buf, 17); + buf[17] = '\0'; + scp_session_set_locale(session, buf); + + /* Check there's enough data left for at least an IPv4 address (+len) */ + if (!s_check_rem(c->in_s, 1 + 4)) + { + LOG(LOG_LEVEL_WARNING, + "[v1s:%d] connection aborted: IP addr len missing", + __LINE__); + return SCP_SERVER_STATE_SIZE_ERR; + } + + in_uint8(c->in_s, sz); + + if (sz == SCP_ADDRESS_TYPE_IPV4) + { + tui32 ipv4; + in_uint32_be(c->in_s, ipv4); + scp_session_set_addr(session, sz, &ipv4); + } + else if (sz == SCP_ADDRESS_TYPE_IPV6) + { + if (!s_check_rem(c->in_s, 16)) + { + LOG(LOG_LEVEL_WARNING, + "[v1s:%d] connection aborted: IP addr missing", + __LINE__); + return SCP_SERVER_STATE_SIZE_ERR; + } + in_uint8a(c->in_s, buf, 16); + scp_session_set_addr(session, sz, buf); + } + + /* reading hostname */ + if (!in_string8(c->in_s, buf, "hostname", __LINE__)) + { + return SCP_SERVER_STATE_SIZE_ERR; + } + + if (0 != scp_session_set_hostname(session, buf)) + { + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + /* reading username */ + if (!in_string8(c->in_s, buf, "username", __LINE__)) + { + return SCP_SERVER_STATE_SIZE_ERR; + } + + if (0 != scp_session_set_username(session, buf)) + { + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + /* reading password */ + if (!in_string8(c->in_s, buf, "passwd", __LINE__)) + { + return SCP_SERVER_STATE_SIZE_ERR; + } + + if (0 != scp_session_set_password(session, buf)) + { + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + return SCP_SERVER_STATE_OK; +} + /* server API */ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk) { + enum SCP_SERVER_STATES_E result; struct SCP_SESSION *session; tui32 version; - tui32 size; + int size; tui16 cmdset; tui16 cmd; - tui8 sz; - char buf[257]; + + (*s) = NULL; if (!skipVchk) { @@ -55,40 +234,44 @@ if (version != 1) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); return SCP_SERVER_STATE_VERSION_ERR; } } else { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } } in_uint32_be(c->in_s, size); - if (size < 12) + /* Check the message is big enough for the header, the command set, and + * the command (but not too big) */ + if (size < (8 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); return SCP_SERVER_STATE_SIZE_ERR; } - init_stream(c->in_s, c->in_s->size); + init_stream(c->in_s, size - 8); if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size - 8))) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } + c->in_s->end = c->in_s->data + (size - 8); + /* reading command set */ in_uint16_be(c->in_s, cmdset); /* if we are starting a management session */ if (cmdset == SCP_COMMAND_SET_MANAGE) { - log_message(LOG_LEVEL_DEBUG, "[v1s:%d] requested management connection", __LINE__); + LOG(LOG_LEVEL_DEBUG, "[v1s:%d] requested management connection", __LINE__); /* should return SCP_SERVER_STATE_START_MANAGE */ return scp_v1s_mng_accept(c, s); } @@ -96,7 +279,7 @@ /* if we started with resource sharing... */ if (cmdset == SCP_COMMAND_SET_RSR) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; } @@ -105,104 +288,33 @@ if (cmd != 1) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; } session = scp_session_create(); - if (0 == session) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (malloc returned NULL)", __LINE__); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - scp_session_set_version(session, 1); - - in_uint8(c->in_s, sz); - - if ((sz != SCP_SESSION_TYPE_XVNC) && (sz != SCP_SESSION_TYPE_XRDP)) - { - scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: unknown session type", __LINE__); - return SCP_SERVER_STATE_SESSION_TYPE_ERR; - } - - scp_session_set_type(session, sz); - - in_uint16_be(c->in_s, cmd); - scp_session_set_height(session, cmd); - in_uint16_be(c->in_s, cmd); - scp_session_set_width(session, cmd); - in_uint8(c->in_s, sz); - if (0 != scp_session_set_bpp(session, sz)) - { - scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, - "[v1s:%d] connection aborted: unsupported bpp: %d", - __LINE__, sz); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - in_uint8(c->in_s, sz); - scp_session_set_rsr(session, sz); - in_uint8a(c->in_s, buf, 17); - buf[17] = '\0'; - scp_session_set_locale(session, buf); - - in_uint8(c->in_s, sz); - - if (sz == SCP_ADDRESS_TYPE_IPV4) - { - in_uint32_be(c->in_s, size); - scp_session_set_addr(session, sz, &size); - } - else if (sz == SCP_ADDRESS_TYPE_IPV6) - { - in_uint8a(c->in_s, buf, 16); - scp_session_set_addr(session, sz, buf); - } - - buf[256] = '\0'; - /* reading hostname */ - in_uint8(c->in_s, sz); - buf[sz] = '\0'; - in_uint8a(c->in_s, buf, sz); - - if (0 != scp_session_set_hostname(session, buf)) + if (NULL == session) { - scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); - return SCP_SERVER_STATE_INTERNAL_ERR; + LOG(LOG_LEVEL_WARNING, + "[v1s:%d] connection aborted: internal error " + "(malloc returned NULL)", __LINE__); + result = SCP_SERVER_STATE_INTERNAL_ERR; } - - /* reading username */ - in_uint8(c->in_s, sz); - buf[sz] = '\0'; - in_uint8a(c->in_s, buf, sz); - - if (0 != scp_session_set_username(session, buf)) - { - scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); - return SCP_SERVER_STATE_INTERNAL_ERR; - } - - /* reading password */ - in_uint8(c->in_s, sz); - buf[sz] = '\0'; - in_uint8a(c->in_s, buf, sz); - - if (0 != scp_session_set_password(session, buf)) + else { - scp_session_destroy(session); - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); - return SCP_SERVER_STATE_INTERNAL_ERR; + result = scp_v1s_init_session(c, session); + if (result != SCP_SERVER_STATE_OK) + { + scp_session_destroy(session); + session = NULL; + } } /* returning the struct */ (*s) = session; - return SCP_SERVER_STATE_OK; + return result; } enum SCP_SERVER_STATES_E @@ -231,7 +343,7 @@ if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, rlen + 14)) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } @@ -242,13 +354,12 @@ scp_v1s_request_password(struct SCP_CONNECTION *c, struct SCP_SESSION *s, const char *reason) { - tui8 sz; tui32 version; - tui32 size; + int size; tui16 cmdset; tui16 cmd; int rlen; - char buf[257]; + char buf[256]; init_stream(c->in_s, c->in_s->size); init_stream(c->out_s, c->out_s->size); @@ -275,14 +386,14 @@ if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, 14 + rlen)) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } /* receive password & username */ if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } @@ -290,31 +401,37 @@ if (version != 1) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); return SCP_SERVER_STATE_VERSION_ERR; } in_uint32_be(c->in_s, size); - if (size < 12) - { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); + /* Check the message is big enough for the header, the command set, and + * the command (but not too big) */ + if (size < (8 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE) + { + LOG(LOG_LEVEL_WARNING, + "[v1s:%d] connection aborted: size error", + __LINE__); return SCP_SERVER_STATE_SIZE_ERR; } - init_stream(c->in_s, c->in_s->size); + init_stream(c->in_s, size - 8); if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size - 8))) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } + c->in_s->end = c->in_s->data + (size - 8); + in_uint16_be(c->in_s, cmdset); if (cmdset != SCP_COMMAND_SET_DEFAULT) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; } @@ -322,30 +439,31 @@ if (cmd != 4) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; } - buf[256] = '\0'; /* reading username */ - in_uint8(c->in_s, sz); - buf[sz] = '\0'; - in_uint8a(c->in_s, buf, sz); + if (!in_string8(c->in_s, buf, "username", __LINE__)) + { + return SCP_SERVER_STATE_SIZE_ERR; + } if (0 != scp_session_set_username(s, buf)) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); return SCP_SERVER_STATE_INTERNAL_ERR; } /* reading password */ - in_uint8(c->in_s, sz); - buf[sz] = '\0'; - in_uint8a(c->in_s, buf, sz); + if (!in_string8(c->in_s, buf, "passwd", __LINE__)) + { + return SCP_SERVER_STATE_SIZE_ERR; + } if (0 != scp_session_set_password(s, buf)) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__); return SCP_SERVER_STATE_INTERNAL_ERR; } @@ -386,7 +504,7 @@ if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, 14)) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } @@ -422,7 +540,7 @@ scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNECTED_SESSION *ds, SCP_SID *sid) { tui32 version = 1; - tui32 size = 12; + int size = 12; tui16 cmd = 40; int pktcnt; int idx; @@ -440,7 +558,7 @@ if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } @@ -454,7 +572,7 @@ if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } @@ -462,31 +580,35 @@ if (version != 1) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); return SCP_SERVER_STATE_VERSION_ERR; } in_uint32_be(c->in_s, size); - if (size < 12) + /* Check the message is big enough for the header, the command set, and + * the command (but not too big) */ + if (size < (8 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); return SCP_SERVER_STATE_SIZE_ERR; } - init_stream(c->in_s, c->in_s->size); + init_stream(c->in_s, size - 8); if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size - 8))) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } + c->in_s->end = c->in_s->data + (size - 8); + in_uint16_be(c->in_s, cmd); if (cmd != SCP_COMMAND_SET_DEFAULT) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; } @@ -494,7 +616,7 @@ if (cmd != 41) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; } @@ -582,7 +704,7 @@ if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } } @@ -592,7 +714,7 @@ if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (8))) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } @@ -600,32 +722,36 @@ if (version != 1) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__); return SCP_SERVER_STATE_VERSION_ERR; } in_uint32_be(c->in_s, size); - if (size < 12) + /* Check the message is big enough for the header, the command set, and + * the command (but not too big) */ + if (size < (8 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__); return SCP_SERVER_STATE_SIZE_ERR; } /* rest of the packet */ - init_stream(c->in_s, c->in_s->size); + init_stream(c->in_s, size - 8); if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size - 8))) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } + c->in_s->end = c->in_s->data + (size - 8); + in_uint16_be(c->in_s, cmd); if (cmd != SCP_COMMAND_SET_DEFAULT) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; } @@ -633,6 +759,11 @@ if (cmd == 43) { + if (!s_check_rem(c->in_s, 4)) + { + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: missing session", __LINE__); + return SCP_SERVER_STATE_SIZE_ERR; + } /* select session */ in_uint32_be(c->in_s, (*sid)); @@ -649,7 +780,7 @@ /* if we got here, the requested sid wasn't one from the list we sent */ /* we should kill the connection */ - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (no such session in list)", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (no such session in list)", __LINE__); return SCP_SERVER_STATE_INTERNAL_ERR; } else if (cmd == 44) @@ -665,7 +796,7 @@ else { /* wrong response */ - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; } @@ -702,7 +833,7 @@ if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) { - log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } diff -Nru xrdp-0.9.12/sesman/libscp/libscp_v1s_mng.c xrdp-0.9.15/sesman/libscp/libscp_v1s_mng.c --- xrdp-0.9.12/sesman/libscp/libscp_v1s_mng.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/libscp/libscp_v1s_mng.c 2020-12-28 14:03:43.000000000 +0000 @@ -32,23 +32,86 @@ #define LIBSCP_V1S_MNG_C #include "libscp_v1s_mng.h" +#include "string_calls.h" //extern struct log_config* s_log; static enum SCP_SERVER_STATES_E _scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s); -/* server API */ -enum SCP_SERVER_STATES_E -scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s) +/** + * Reads a uint8 followed by a string into a buffer + * + * Buffer is null-terminated on success + * + * @param s Input stream + * @param [out] Output buffer (must be >= 256 chars) + * @param param Parameter we're reading + * @param line Line number reference + * @return != 0 if string read OK + * + * @todo + * This needs to be merged with the func of the same name in + * libscp_v1s.c + */ +static +int in_string8(struct stream *s, char str[], const char *param, int line) +{ + int result; + + if (!s_check_rem(s, 1)) + { + LOG(LOG_LEVEL_WARNING, + "[v1s_mng:%d] connection aborted: %s len missing", + line, param); + result = 0; + } + else + { + unsigned int sz; + + in_uint8(s, sz); + result = s_check_rem(s, sz); + if (!result) + { + LOG(LOG_LEVEL_WARNING, + "[v1s_mng:%d] connection aborted: %s data missing", + line, param); + } + else + { + in_uint8a(s, str, sz); + str[sz] = '\0'; + } + } + return result; +} +/** + * Initialises a V1 management session object + * + * At call time, the command set value has been read from the wire, and + * the command still needs to be processed. + * + * @param c Connection + * @param [out] session pre-allocated session object + * @return SCP_SERVER_STATE_START_MANAGE for success + */ +static enum SCP_SERVER_STATES_E +scp_v1s_mng_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session) { - struct SCP_SESSION *session; tui32 ipaddr; tui16 cmd; tui8 sz; - char buf[257]; + char buf[256]; + + scp_session_set_version(session, 1); /* reading command */ + if (!s_check_rem(c->in_s, 2)) + { + /* Caller should have checked this */ + return SCP_SERVER_STATE_SIZE_ERR; + } in_uint16_be(c->in_s, cmd); if (cmd != 1) /* manager login */ @@ -56,41 +119,39 @@ return SCP_SERVER_STATE_SEQUENCE_ERR; } - session = scp_session_create(); - - if (0 == session) + /* reading username */ + if (!in_string8(c->in_s, buf, "username", __LINE__)) { - return SCP_SERVER_STATE_INTERNAL_ERR; + return SCP_SERVER_STATE_SIZE_ERR; } - scp_session_set_version(session, 1); - scp_session_set_type(session, SCP_SESSION_TYPE_MANAGE); - - /* reading username */ - in_uint8(c->in_s, sz); - buf[sz] = '\0'; - in_uint8a(c->in_s, buf, sz); - if (0 != scp_session_set_username(session, buf)) { - scp_session_destroy(session); return SCP_SERVER_STATE_INTERNAL_ERR; } /* reading password */ - in_uint8(c->in_s, sz); - buf[sz] = '\0'; - in_uint8a(c->in_s, buf, sz); + if (!in_string8(c->in_s, buf, "passwd", __LINE__)) + { + return SCP_SERVER_STATE_SIZE_ERR; + } if (0 != scp_session_set_password(session, buf)) { - scp_session_destroy(session); return SCP_SERVER_STATE_INTERNAL_ERR; } - /* reading remote address */ - in_uint8(c->in_s, sz); + /* reading remote address + * Check there's enough data left for at least an IPv4 address (+len) */ + if (!s_check_rem(c->in_s, 1 + 4)) + { + LOG(LOG_LEVEL_WARNING, + "[v1s_mng:%d] connection aborted: IP addr len missing", + __LINE__); + return SCP_SERVER_STATE_SIZE_ERR; + } + in_uint8(c->in_s, sz); if (sz == SCP_ADDRESS_TYPE_IPV4) { in_uint32_be(c->in_s, ipaddr); @@ -98,25 +159,57 @@ } else if (sz == SCP_ADDRESS_TYPE_IPV6) { + if (!s_check_rem(c->in_s, 16)) + { + LOG(LOG_LEVEL_WARNING, + "[v1s_mng:%d] connection aborted: IP addr missing", + __LINE__); + return SCP_SERVER_STATE_SIZE_ERR; + } in_uint8a(c->in_s, buf, 16); scp_session_set_addr(session, sz, buf); } /* reading hostname */ - in_uint8(c->in_s, sz); - buf[sz] = '\0'; - in_uint8a(c->in_s, buf, sz); + if (!in_string8(c->in_s, buf, "hostname", __LINE__)) + { + return SCP_SERVER_STATE_SIZE_ERR; + } if (0 != scp_session_set_hostname(session, buf)) { - scp_session_destroy(session); return SCP_SERVER_STATE_INTERNAL_ERR; } - /* returning the struct */ + return SCP_SERVER_STATE_START_MANAGE; +} + +enum SCP_SERVER_STATES_E +scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s) +{ + enum SCP_SERVER_STATES_E result; + struct SCP_SESSION *session; + + session = scp_session_create(); + if (NULL == session) + { + result = SCP_SERVER_STATE_INTERNAL_ERR; + } + else + { + scp_session_set_type(session, SCP_SESSION_TYPE_MANAGE); + + result = scp_v1s_mng_init_session(c, session); + if (result != SCP_SERVER_STATE_START_MANAGE) + { + scp_session_destroy(session); + session = NULL; + } + } + (*s) = session; - return SCP_SERVER_STATE_START_MANAGE; + return result; } /* 002 */ @@ -190,16 +283,16 @@ /* calculating the number of packets to send */ if (sescnt == 0) { - pktcnt = 1; + pktcnt = 1; } else { - pktcnt = sescnt / SCP_SERVER_MAX_LIST_SIZE; + pktcnt = sescnt / SCP_SERVER_MAX_LIST_SIZE; - if ((sescnt % SCP_SERVER_MAX_LIST_SIZE) != 0) - { - pktcnt++; - } + if ((sescnt % SCP_SERVER_MAX_LIST_SIZE) != 0) + { + pktcnt++; + } } for (idx = 0; idx < pktcnt; idx++) @@ -277,7 +370,7 @@ if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size)) { - log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } } @@ -289,7 +382,7 @@ _scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s) { tui32 version; - tui32 size; + int size; tui16 cmd; // tui8 dim; // char buf[257]; @@ -298,7 +391,7 @@ if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) { - log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } @@ -306,26 +399,36 @@ if (version != 1) { - log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: version error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: version error", __LINE__); return SCP_SERVER_STATE_VERSION_ERR; } in_uint32_be(c->in_s, size); - init_stream(c->in_s, c->in_s->size); + /* Check the message is big enough for the header, the command set, and + * the command (but not too big) */ + if (size < (8 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE) + { + LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: size error", __LINE__); + return SCP_SERVER_STATE_SIZE_ERR; + } + + init_stream(c->in_s, size - 8); /* read the rest of the packet */ if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) { - log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__); return SCP_SERVER_STATE_NETWORK_ERR; } + c->in_s->end = c->in_s->data + (size - 8); + in_uint16_be(c->in_s, cmd); if (cmd != SCP_COMMAND_SET_MANAGE) { - log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; } @@ -333,7 +436,7 @@ if (cmd == SCP_CMD_MNG_LIST_REQ) /* request session list */ { - log_message(LOG_LEVEL_INFO, "[v1s_mng:%d] request session list", __LINE__); + LOG(LOG_LEVEL_INFO, "[v1s_mng:%d] request session list", __LINE__); return SCP_SERVER_STATE_MNG_LISTREQ; } else if (cmd == SCP_CMD_MNG_ACTION) /* execute an action */ @@ -343,7 +446,7 @@ in_uint8a(c->in_s, buf, dim); scp_session_set_errstr(s, buf);*/ - log_message(LOG_LEVEL_INFO, "[v1s_mng:%d] action request", __LINE__); + LOG(LOG_LEVEL_INFO, "[v1s_mng:%d] action request", __LINE__); return SCP_SERVER_STATE_MNG_ACTION; } @@ -358,7 +461,7 @@ return SCP_SERVER_STATE_SESSION_LIST; }*/ - log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__); + LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__); return SCP_SERVER_STATE_SEQUENCE_ERR; } diff -Nru xrdp-0.9.12/sesman/libscp/Makefile.in xrdp-0.9.15/sesman/libscp/Makefile.in --- xrdp-0.9.12/sesman/libscp/Makefile.in 2019-12-28 12:36:38.000000000 +0000 +++ xrdp-0.9.15/sesman/libscp/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/sesman/Makefile.in xrdp-0.9.15/sesman/Makefile.in --- xrdp-0.9.12/sesman/Makefile.in 2019-12-28 12:36:38.000000000 +0000 +++ xrdp-0.9.15/sesman/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/sesman/scp.c xrdp-0.9.15/sesman/scp.c --- xrdp-0.9.12/sesman/scp.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/scp.c 2020-12-28 14:03:43.000000000 +0000 @@ -43,13 +43,13 @@ struct SCP_SESSION *sdata = NULL; scon.in_sck = (int)(tintptr)sck; - LOG_DBG("started scp thread on socket %d", scon.in_sck); + LOG_DEVEL(LOG_LEVEL_DEBUG, "started scp thread on socket %d", scon.in_sck); make_stream(scon.in_s); make_stream(scon.out_s); - init_stream(scon.in_s, 8192); - init_stream(scon.out_s, 8192); + init_stream(scon.in_s, SCP_MAX_MESSAGE_SIZE); + init_stream(scon.out_s, SCP_MAX_MESSAGE_SIZE); switch (scp_vXs_accept(&scon, &(sdata))) { @@ -58,41 +58,43 @@ if (sdata->version == 0) { /* starts processing an scp v0 connection */ - LOG_DBG("accept ok, go on with scp v0"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "accept ok, go on with scp v0"); scp_v0_process(&scon, sdata); } else { - LOG_DBG("accept ok, go on with scp v1"); - /*LOG_DBG("user: %s\npass: %s",sdata->username, sdata->password);*/ + LOG_DEVEL(LOG_LEVEL_DEBUG, "accept ok, go on with scp v1"); + /*LOG_DEVEL(LOG_LEVEL_DEBUG, "user: %s\npass: %s",sdata->username, sdata->password);*/ scp_v1_process(&scon, sdata); } break; case SCP_SERVER_STATE_START_MANAGE: /* starting a management session */ - log_message(LOG_LEVEL_WARNING, - "starting a sesman management session..."); + LOG(LOG_LEVEL_WARNING, + "starting a sesman management session..."); scp_v1_mng_process(&scon, sdata); break; case SCP_SERVER_STATE_VERSION_ERR: - /* an unknown scp version was requested, so we shut down the */ - /* connection (and log the fact) */ - log_message(LOG_LEVEL_WARNING, - "unknown protocol version specified. connection refused."); + case SCP_SERVER_STATE_SIZE_ERR: + /* an unknown scp version was requested, or the message sizes + are inconsistent. Shut down the connection and log the + fact */ + LOG(LOG_LEVEL_WARNING, + "protocol violation. connection refused."); break; case SCP_SERVER_STATE_NETWORK_ERR: - log_message(LOG_LEVEL_WARNING, "libscp network error."); + LOG(LOG_LEVEL_WARNING, "libscp network error."); break; case SCP_SERVER_STATE_SEQUENCE_ERR: - log_message(LOG_LEVEL_WARNING, "libscp sequence error."); + LOG(LOG_LEVEL_WARNING, "libscp sequence error."); break; case SCP_SERVER_STATE_INTERNAL_ERR: /* internal error occurred (eg. malloc() error, ecc.) */ - log_message(LOG_LEVEL_ERROR, "libscp internal error occurred."); + LOG(LOG_LEVEL_ERROR, "libscp internal error occurred."); break; default: - log_message(LOG_LEVEL_ALWAYS, "unknown return from scp_vXs_accept()"); + LOG(LOG_LEVEL_ALWAYS, "unknown return from scp_vXs_accept()"); break; } diff -Nru xrdp-0.9.12/sesman/scp_v0.c xrdp-0.9.15/sesman/scp_v0.c --- xrdp-0.9.12/sesman/scp_v0.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/scp_v0.c 2020-12-28 14:03:43.000000000 +0000 @@ -54,23 +54,23 @@ { /* the user is member of the correct groups. */ scp_v0s_replyauthentication(c, errorcode); - log_message(LOG_LEVEL_INFO, "Access permitted for user: %s", - s->username); + LOG(LOG_LEVEL_INFO, "Access permitted for user: %s", + s->username); /* g_writeln("Connection allowed"); */ } else { scp_v0s_replyauthentication(c, 32 + 3); /* all first 32 are reserved for PAM errors */ - log_message(LOG_LEVEL_INFO, "Username okey but group problem for " - "user: %s", s->username); + LOG(LOG_LEVEL_INFO, "Username okey but group problem for " + "user: %s", s->username); /* g_writeln("user password ok, but group problem"); */ } } else { /* g_writeln("username or password error"); */ - log_message(LOG_LEVEL_INFO, "Username or password error for user: %s", - s->username); + LOG(LOG_LEVEL_INFO, "Username or password error for user: %s", + s->username); scp_v0s_replyauthentication(c, errorcode); } } @@ -85,55 +85,55 @@ g_memcpy(s->guid, s_item->guid, 16); if (0 != s->client_ip) { - log_message( LOG_LEVEL_INFO, "++ reconnected session: username %s, " - "display :%d.0, session_pid %d, ip %s", - s->username, display, s_item->pid, s->client_ip); + LOG( LOG_LEVEL_INFO, "++ reconnected session: username %s, " + "display :%d.0, session_pid %d, ip %s", + s->username, display, s_item->pid, s->client_ip); } else { - log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, " - "display :%d.0, session_pid %d", s->username, display, - s_item->pid); + LOG(LOG_LEVEL_INFO, "++ reconnected session: username %s, " + "display :%d.0, session_pid %d", s->username, display, + s_item->pid); } session_reconnect(display, s->username, data); } else { - LOG_DBG("pre auth"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "pre auth"); if (1 == access_login_allowed(s->username)) { tui8 guid[16]; - g_random((char*)guid, 16); + g_random((char *)guid, 16); scp_session_set_guid(s, guid); if (0 != s->client_ip) { - log_message(LOG_LEVEL_INFO, "++ created session (access granted): " - "username %s, ip %s", s->username, s->client_ip); + LOG(LOG_LEVEL_INFO, "++ created session (access granted): " + "username %s, ip %s", s->username, s->client_ip); } else { - log_message(LOG_LEVEL_INFO, "++ created session (access granted): " - "username %s", s->username); + LOG(LOG_LEVEL_INFO, "++ created session (access granted): " + "username %s", s->username); } if (SCP_SESSION_TYPE_XVNC == s->type) { - log_message( LOG_LEVEL_INFO, "starting Xvnc session..."); + LOG( LOG_LEVEL_INFO, "starting Xvnc session..."); display = session_start(data, SESMAN_SESSION_TYPE_XVNC, c, s); } else if (SCP_SESSION_TYPE_XRDP == s->type) { - log_message(LOG_LEVEL_INFO, "starting X11rdp session..."); + LOG(LOG_LEVEL_INFO, "starting X11rdp session..."); display = session_start(data, SESMAN_SESSION_TYPE_XRDP, c, s); } else if (SCP_SESSION_TYPE_XORG == s->type) { /* type is SCP_SESSION_TYPE_XORG */ - log_message(LOG_LEVEL_INFO, "starting Xorg session..."); + LOG(LOG_LEVEL_INFO, "starting Xorg session..."); display = session_start(data, SESMAN_SESSION_TYPE_XORG, c, s); } /* if the session started up ok, auth_end will be called on diff -Nru xrdp-0.9.12/sesman/scp_v1.c xrdp-0.9.15/sesman/scp_v1.c --- xrdp-0.9.12/sesman/scp_v1.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/scp_v1.c 2020-12-28 14:03:43.000000000 +0000 @@ -55,14 +55,14 @@ retries = g_cfg->sec.login_retry; current_try = retries; - data = auth_userpass(s->username, s->password,NULL); - /*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/ + data = auth_userpass(s->username, s->password, NULL); + /*LOG_DEVEL(LOG_LEVEL_DEBUG, "user: %s\npass: %s", s->username, s->password);*/ while ((!data) && ((retries == 0) || (current_try > 0))) { - LOG_DBG("data %d - retry %d - currenttry %d - expr %d", - data, retries, current_try, - ((!data) && ((retries == 0) || (current_try > 0)))); + LOG_DEVEL(LOG_LEVEL_DEBUG, "data %ld - retry %d - currenttry %d - expr %d", + data, retries, current_try, + ((!data) && ((retries == 0) || (current_try > 0)))); e = scp_v1s_request_password(c, s, "Wrong username and/or password"); @@ -70,7 +70,7 @@ { case SCP_SERVER_STATE_OK: /* all ok, we got new username and password */ - data = auth_userpass(s->username, s->password,NULL); + data = auth_userpass(s->username, s->password, NULL); /* one try less */ if (current_try > 0) @@ -90,8 +90,8 @@ if (!data) { scp_v1s_deny_connection(c, "Login failed"); - log_message( LOG_LEVEL_INFO, - "Login failed for user %s. Connection terminated", s->username); + LOG( LOG_LEVEL_INFO, + "Login failed for user %s. Connection terminated", s->username); return; } @@ -99,8 +99,8 @@ if (0 == access_login_allowed(s->username)) { scp_v1s_deny_connection(c, "Access to Terminal Server not allowed."); - log_message(LOG_LEVEL_INFO, - "User %s not allowed on TS. Connection terminated", s->username); + LOG(LOG_LEVEL_INFO, + "User %s not allowed on TS. Connection terminated", s->username); return; } @@ -112,31 +112,31 @@ if (scount == 0) { /* no disconnected sessions - start a new one */ - log_message(LOG_LEVEL_DEBUG, "No disconnected sessions for this user " - "- we create a new one"); + LOG(LOG_LEVEL_DEBUG, "No disconnected sessions for this user " + "- we create a new one"); if (0 != s->client_ip) { - log_message(LOG_LEVEL_INFO, "++ created session (access granted): username %s, ip %s", s->username, s->client_ip); + LOG(LOG_LEVEL_INFO, "++ created session (access granted): username %s, ip %s", s->username, s->client_ip); } else { - log_message(LOG_LEVEL_INFO, "++ created session (access granted): username %s", s->username); + LOG(LOG_LEVEL_INFO, "++ created session (access granted): username %s", s->username); } if (SCP_SESSION_TYPE_XVNC == s->type) { - log_message(LOG_LEVEL_INFO, "starting Xvnc session..."); + LOG(LOG_LEVEL_INFO, "starting Xvnc session..."); display = session_start(data, SESMAN_SESSION_TYPE_XVNC, c, s); } else if (SCP_SESSION_TYPE_XRDP == s->type) { - log_message(LOG_LEVEL_INFO, "starting X11rdp session..."); + LOG(LOG_LEVEL_INFO, "starting X11rdp session..."); display = session_start(data, SESMAN_SESSION_TYPE_XRDP, c, s); } else if (SCP_SESSION_TYPE_XORG == s->type) { - log_message(LOG_LEVEL_INFO, "starting Xorg session..."); + LOG(LOG_LEVEL_INFO, "starting Xorg session..."); display = session_start(data, SESMAN_SESSION_TYPE_XORG, c, s); } /* if the session started up ok, auth_end will be called on @@ -161,10 +161,10 @@ switch (e) { - /*case SCP_SERVER_STATE_FORCE_NEW:*/ - /* we should check for MaxSessions */ + /*case SCP_SERVER_STATE_FORCE_NEW:*/ + /* we should check for MaxSessions */ case SCP_SERVER_STATE_SELECTION_CANCEL: - log_message( LOG_LEVEL_INFO, "Connection cancelled after session listing"); + LOG( LOG_LEVEL_INFO, "Connection cancelled after session listing"); break; case SCP_SERVER_STATE_OK: /* ok, reconnecting... */ @@ -173,7 +173,7 @@ if (0 == sitem) { e = scp_v1s_connection_error(c, "Internal error"); - log_message(LOG_LEVEL_INFO, "Cannot find session item on the chain"); + LOG(LOG_LEVEL_INFO, "Cannot find session item on the chain"); } else { @@ -183,11 +183,11 @@ if (0 != s->client_ip) { - log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d, ip %s", s->username, display, sitem->pid, s->client_ip); + LOG(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d, ip %s", s->username, display, sitem->pid, s->client_ip); } else { - log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d", s->username, display, sitem->pid); + LOG(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d", s->username, display, sitem->pid); } g_free(sitem); @@ -220,27 +220,27 @@ switch (e) { case SCP_SERVER_STATE_VERSION_ERR: - LOG_DBG("version error") + LOG(LOG_LEVEL_WARNING, "version error"); case SCP_SERVER_STATE_SIZE_ERR: /* an unknown scp version was requested, so we shut down the */ /* connection (and log the fact) */ - log_message(LOG_LEVEL_WARNING, - "protocol violation. connection closed."); + LOG(LOG_LEVEL_WARNING, + "protocol violation. connection closed."); break; case SCP_SERVER_STATE_NETWORK_ERR: - log_message(LOG_LEVEL_WARNING, "libscp network error."); + LOG(LOG_LEVEL_WARNING, "libscp network error."); break; case SCP_SERVER_STATE_SEQUENCE_ERR: - log_message(LOG_LEVEL_WARNING, "libscp sequence error."); + LOG(LOG_LEVEL_WARNING, "libscp sequence error."); break; case SCP_SERVER_STATE_INTERNAL_ERR: /* internal error occurred (eg. malloc() error, ecc.) */ - log_message(LOG_LEVEL_ERROR, "libscp internal error occurred."); + LOG(LOG_LEVEL_ERROR, "libscp internal error occurred."); break; default: /* dummy: scp_v1s_request_password won't generate any other */ /* error other than the ones before */ - log_message(LOG_LEVEL_ALWAYS, "unknown return from %s", f); + LOG(LOG_LEVEL_ALWAYS, "unknown return from %s", f); break; } } diff -Nru xrdp-0.9.12/sesman/scp_v1_mng.c xrdp-0.9.15/sesman/scp_v1_mng.c --- xrdp-0.9.12/sesman/scp_v1_mng.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/scp_v1_mng.c 2020-12-28 14:03:43.000000000 +0000 @@ -46,14 +46,14 @@ int scount; int end = 0; - data = auth_userpass(s->username, s->password,NULL); - /*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/ + data = auth_userpass(s->username, s->password, NULL); + /*LOG_DEVEL(LOG_LEVEL_DEBUG, "user: %s\npass: %s", s->username, s->password);*/ if (!data) { scp_v1s_mng_deny_connection(c, "Login failed"); - log_message(LOG_LEVEL_INFO, - "[MNG] Login failed for user %s. Connection terminated", s->username); + LOG(LOG_LEVEL_INFO, + "[MNG] Login failed for user %s. Connection terminated", s->username); auth_end(data); return; } @@ -62,8 +62,8 @@ if (0 == access_login_mng_allowed(s->username)) { scp_v1s_mng_deny_connection(c, "Access to Terminal Server not allowed."); - log_message(LOG_LEVEL_INFO, - "[MNG] User %s not allowed on TS. Connection terminated", s->username); + LOG(LOG_LEVEL_INFO, + "[MNG] User %s not allowed on TS. Connection terminated", s->username); auth_end(data); return; } @@ -77,16 +77,16 @@ switch (e) { case SCP_SERVER_STATE_MNG_ACTION: - log_message(LOG_LEVEL_INFO, "Connection cancelled after session listing"); + LOG(LOG_LEVEL_INFO, "Connection cancelled after session listing"); break; 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_DEVEL(LOG_LEVEL_DEBUG, "sessions on TS: %d (slist: %p)", scount, slist); if (0 == slist) { - log_message(LOG_LEVEL_INFO, "No sessions on Terminal Server"); + LOG(LOG_LEVEL_INFO, "No sessions on Terminal Server"); } e = scp_v1s_mng_list_sessions(c, s, scount, slist); @@ -109,27 +109,27 @@ switch (e) { case SCP_SERVER_STATE_VERSION_ERR: - LOG_DBG("version error") + LOG(LOG_LEVEL_WARNING, "version error"); case SCP_SERVER_STATE_SIZE_ERR: /* an unknown scp version was requested, so we shut down the */ /* connection (and log the fact) */ - log_message(LOG_LEVEL_WARNING, - "protocol violation. connection closed."); + LOG(LOG_LEVEL_WARNING, + "protocol violation. connection closed."); break; case SCP_SERVER_STATE_NETWORK_ERR: - log_message(LOG_LEVEL_WARNING, "libscp network error."); + LOG(LOG_LEVEL_WARNING, "libscp network error."); break; case SCP_SERVER_STATE_SEQUENCE_ERR: - log_message(LOG_LEVEL_WARNING, "libscp sequence error."); + LOG(LOG_LEVEL_WARNING, "libscp sequence error."); break; case SCP_SERVER_STATE_INTERNAL_ERR: /* internal error occurred (eg. malloc() error, ecc.) */ - log_message(LOG_LEVEL_ERROR, "libscp internal error occurred."); + LOG(LOG_LEVEL_ERROR, "libscp internal error occurred."); break; default: /* dummy: scp_v1s_request_password won't generate any other */ /* error other than the ones before */ - log_message(LOG_LEVEL_ALWAYS, "unknown return from %s", f); + LOG(LOG_LEVEL_ALWAYS, "unknown return from %s", f); break; } } diff -Nru xrdp-0.9.12/sesman/sesman.c xrdp-0.9.15/sesman/sesman.c --- xrdp-0.9.12/sesman/sesman.c 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/sesman/sesman.c 2020-12-28 14:03:43.000000000 +0000 @@ -28,7 +28,20 @@ #include #endif +#include + #include "sesman.h" +#include "xrdp_configure_options.h" +#include "string_calls.h" + +struct sesman_startup_params +{ + const char *sesman_ini; + int kill; + int no_daemon; + int help; + int version; +}; int g_sck; int g_pid; @@ -37,8 +50,101 @@ tintptr g_term_event = 0; +/*****************************************************************************/ +/** + * @brief looks for a case-insensitive match of a string in a list + * @param candidate String to match + * @param ... NULL-terminated list of strings to compare the candidate with + * @return !=0 if the candidate is found in the list + */ +static int nocase_matches(const char *candidate, ...) +{ + va_list vl; + const char *member; + int result = 0; + + va_start(vl, candidate); + while ((member = va_arg(vl, const char *)) != NULL) + { + if (g_strcasecmp(candidate, member) == 0) + { + result = 1; + break; + } + } + + va_end(vl); + return result; +} + +/*****************************************************************************/ +/** + * + * @brief Command line argument parser + * @param[in] argc number of command line arguments + * @param[in] argv pointer array of commandline arguments + * @param[out] sesman_startup_params Returned startup parameters + * @return 0 on success, n on nth argument is unknown + * + */ +static int +sesman_process_params(int argc, char **argv, + struct sesman_startup_params *startup_params) +{ + int index; + const char *option; + const char *value; + + index = 1; + + while (index < argc) + { + option = argv[index]; + + if (index + 1 < argc) + { + value = argv[index + 1]; + } + else + { + value = ""; + } + + if (nocase_matches(option, "-help", "--help", "-h", NULL)) + { + startup_params->help = 1; + } + else if (nocase_matches(option, "-kill", "--kill", "-k", NULL)) + { + startup_params->kill = 1; + } + else if (nocase_matches(option, "-nodaemon", "--nodaemon", "-n", + "-nd", "--nd", "-ns", "--ns", NULL)) + { + startup_params->no_daemon = 1; + } + else if (nocase_matches(option, "-v", "--version", NULL)) + { + startup_params->version = 1; + } + else if (nocase_matches(option, "-c", "--config", NULL)) + { + index++; + startup_params->sesman_ini = value; + } + else /* unknown option */ + { + return index; + } + + index++; + } + + return 0; +} + /******************************************************************************/ -int sesman_listen_test(struct config_sesman *cfg) +static int sesman_listen_test(struct config_sesman *cfg) { int error; int sck; @@ -50,8 +156,8 @@ return 1; } - log_message(LOG_LEVEL_DEBUG, "Testing if xrdp-sesman can listen on %s port %s.", - cfg->listen_address, cfg->listen_port); + LOG(LOG_LEVEL_DEBUG, "Testing if xrdp-sesman can listen on %s port %s.", + cfg->listen_address, cfg->listen_port); g_tcp_set_non_blocking(sck); error = scp_tcp_bind(sck, cfg->listen_address, cfg->listen_port); if (error == 0) @@ -82,7 +188,7 @@ * @brief Starts sesman main loop * */ -int +static int sesman_main_loop(void) { int in_sck; @@ -96,7 +202,7 @@ g_sck = g_tcp_socket(); if (g_sck < 0) { - log_message(LOG_LEVEL_ERROR, "error opening socket, g_tcp_socket() failed..."); + LOG(LOG_LEVEL_ERROR, "error opening socket, g_tcp_socket() failed..."); return 1; } @@ -109,8 +215,8 @@ if (error == 0) { - log_message(LOG_LEVEL_INFO, "listening to port %s on %s", - g_cfg->listen_port, g_cfg->listen_address); + LOG(LOG_LEVEL_INFO, "listening to port %s on %s", + g_cfg->listen_port, g_cfg->listen_address); sck_obj = g_create_wait_obj_from_socket(g_sck, 0); cont = 1; @@ -150,8 +256,8 @@ else { /* we've got a connection, so we pass it to scp code */ - LOG_DBG("new connection"); - scp_process_start((void*)(tintptr)in_sck); + LOG_DEVEL(LOG_LEVEL_DEBUG, "new connection"); + scp_process_start((void *)(tintptr)in_sck); g_sck_close(in_sck); } } @@ -161,126 +267,158 @@ } else { - log_message(LOG_LEVEL_ERROR, "listen error %d (%s)", - g_get_errno(), g_get_strerror()); + LOG(LOG_LEVEL_ERROR, "listen error %d (%s)", + g_get_errno(), g_get_strerror()); rv = 1; } } else { - log_message(LOG_LEVEL_ERROR, "bind error on " - "port '%s': %d (%s)", g_cfg->listen_port, - g_get_errno(), g_get_strerror()); + LOG(LOG_LEVEL_ERROR, "bind error on " + "port '%s': %d (%s)", g_cfg->listen_port, + g_get_errno(), g_get_strerror()); rv = 1; } g_tcp_close(g_sck); return rv; } +/*****************************************************************************/ +static void +print_version(void) +{ + g_writeln("xrdp-sesman %s", PACKAGE_VERSION); + g_writeln(" The xrdp session manager"); + g_writeln(" Copyright (C) 2004-2020 Jay Sorg, " + "Neutrino Labs, and all contributors."); + g_writeln(" See https://github.com/neutrinolabs/xrdp for more information."); + g_writeln("%s", ""); + +#if defined(XRDP_CONFIGURE_OPTIONS) + g_writeln(" Configure options:"); + g_writeln("%s", XRDP_CONFIGURE_OPTIONS); +#endif +} + /******************************************************************************/ -void -print_usage(int retcode) +static void +print_help(void) { - g_printf("xrdp-sesman - xrdp session manager\n\n"); g_printf("Usage: xrdp-sesman [options]\n"); - g_printf(" -n, --nodaemon run as foreground process\n"); - g_printf(" -k, --kill kill running xrdp-sesman\n"); - g_printf(" -h, --help show this help\n"); + g_printf(" -k, --kill shut down xrdp-sesman\n"); + g_printf(" -h, --help show help\n"); + g_printf(" -v, --version show version\n"); + g_printf(" -n, --nodaemon don't fork into background\n"); + g_printf(" -c, --config specify new path to sesman.ini\n"); g_deinit(); - g_exit(retcode); } /******************************************************************************/ -int -main(int argc, char **argv) +static int +kill_running_sesman(const char *pid_file) { - int fd; - enum logReturns log_error; int error; - int daemon = 1; + int fd; int pid; - char pid_s[32]; - char text[256]; - char pid_file[256]; - char cfg_file[256]; + char pid_s[32] = {0}; - g_init("xrdp-sesman"); - g_snprintf(pid_file, 255, "%s/xrdp-sesman.pid", XRDP_PID_PATH); + /* check if sesman is running */ + if (!g_file_exist(pid_file)) + { + g_printf("sesman is not running (pid file not found - %s)\n", pid_file); + g_deinit(); + return 1; + } - if (1 == argc) + fd = g_file_open(pid_file); + + if (-1 == fd) { - /* start in daemon mode if no cli options */ - daemon = 1; + g_printf("error opening pid file[%s]: %s\n", pid_file, g_get_strerror()); + return 1; } - else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--nodaemon")) || - (0 == g_strcasecmp(argv[1], "-nodaemon")) || - (0 == g_strcasecmp(argv[1], "-n")) || - (0 == g_strcasecmp(argv[1], "-ns")))) + + error = g_file_read(fd, pid_s, sizeof(pid_s) - 1); + + if (-1 == error) { - /* starts sesman not daemonized */ - g_printf("starting sesman in foreground...\n"); - daemon = 0; + g_printf("error reading pid file: %s\n", g_get_strerror()); + g_file_close(fd); + g_deinit(); + return 1; } - else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--help")) || - (0 == g_strcasecmp(argv[1], "-help")) || - (0 == g_strcasecmp(argv[1], "-h")))) + + g_file_close(fd); + pid = g_atoi(pid_s); + + error = g_sigterm(pid); + + if (0 != error) { - print_usage(0); + g_printf("error killing sesman: %s\n", g_get_strerror()); } - else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--kill")) || - (0 == g_strcasecmp(argv[1], "-kill")) || - (0 == g_strcasecmp(argv[1], "-k")))) + else { - /* killing running sesman */ - /* check if sesman is running */ - if (!g_file_exist(pid_file)) - { - g_printf("sesman is not running (pid file not found - %s)\n", pid_file); - g_deinit(); - g_exit(1); - } + g_file_delete(pid_file); + } - fd = g_file_open(pid_file); + g_deinit(); + return error; +} +/******************************************************************************/ +int +main(int argc, char **argv) +{ + int error; + enum logReturns log_error; + char text[256]; + char pid_file[256]; + char default_sesman_ini[256]; + struct sesman_startup_params startup_params = {0}; + int errored_argc; + int daemon; - if (-1 == fd) - { - g_printf("error opening pid file[%s]: %s\n", pid_file, g_get_strerror()); - return 1; - } + g_init("xrdp-sesman"); + g_snprintf(pid_file, 255, "%s/xrdp-sesman.pid", XRDP_PID_PATH); + g_snprintf(default_sesman_ini, 255, "%s/sesman.ini", XRDP_CFG_PATH); - g_memset(pid_s, 0, sizeof(pid_s)); - error = g_file_read(fd, pid_s, 31); + startup_params.sesman_ini = default_sesman_ini; - if (-1 == error) - { - g_printf("error reading pid file: %s\n", g_get_strerror()); - g_file_close(fd); - g_deinit(); - g_exit(error); - } + errored_argc = sesman_process_params(argc, argv, &startup_params); + if (errored_argc > 0) + { + print_version(); + g_writeln("%s", ""); + print_help(); + g_writeln("%s", ""); - g_file_close(fd); - pid = g_atoi(pid_s); + g_writeln("Unknown option: %s", argv[errored_argc]); + g_deinit(); + g_exit(1); + } - error = g_sigterm(pid); + if (startup_params.help) + { + print_help(); + g_exit(0); + } - if (0 != error) - { - g_printf("error killing sesman: %s\n", g_get_strerror()); - } - else - { - g_file_delete(pid_file); - } + if (startup_params.version) + { + print_version(); + g_exit(0); + } - g_deinit(); - g_exit(error); + + if (startup_params.kill) + { + g_exit(kill_running_sesman(pid_file)); } - else + + daemon = !startup_params.no_daemon; + if (!daemon) { - /* there's something strange on the command line */ - g_printf("Error: invalid command line arguments\n\n"); - print_usage(1); + g_printf("starting sesman in foreground...\n"); } if (g_file_exist(pid_file)) @@ -294,33 +432,23 @@ } /* reading config */ - g_cfg = g_new0(struct config_sesman, 1); - - if (0 == g_cfg) - { - g_printf("error creating config: quitting.\n"); - g_deinit(); - g_exit(1); - } - - //g_cfg->log.fd = -1; /* don't use logging before reading its config */ - if (0 != config_read(g_cfg)) + if ((g_cfg = config_read(startup_params.sesman_ini)) == NULL) { - g_printf("error reading config: %s\nquitting.\n", g_get_strerror()); + g_printf("error reading config %s: %s\nquitting.\n", + startup_params.sesman_ini, g_get_strerror()); g_deinit(); g_exit(1); } - /* not to spit on the console, show config summary only when running in foreground */ + /* not to spit on the console, show config summary only when running + * in foreground */ if (!daemon) { config_dump(g_cfg); } - g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); - /* starting logging subsystem */ - log_error = log_start(cfg_file, "xrdp-sesman"); + log_error = log_start(startup_params.sesman_ini, "xrdp-sesman"); if (log_error != LOG_STARTUP_OK) { @@ -338,18 +466,20 @@ break; } + config_free(g_cfg); g_deinit(); g_exit(1); } - log_message(LOG_LEVEL_TRACE, "config loaded in %s at %s:%d", __func__, __FILE__, __LINE__); - log_message(LOG_LEVEL_TRACE, " listen_address = %s", g_cfg->listen_address); - log_message(LOG_LEVEL_TRACE, " listen_port = %s", g_cfg->listen_port); - log_message(LOG_LEVEL_TRACE, " enable_user_wm = %d", g_cfg->enable_user_wm); - log_message(LOG_LEVEL_TRACE, " default_wm = %s", g_cfg->default_wm); - log_message(LOG_LEVEL_TRACE, " user_wm = %s", g_cfg->user_wm); - log_message(LOG_LEVEL_TRACE, " reconnect_sh = %s", g_cfg->reconnect_sh); - log_message(LOG_LEVEL_TRACE, " auth_file_path = %s", g_cfg->auth_file_path); + LOG(LOG_LEVEL_TRACE, "config loaded in %s at %s:%d", __func__, __FILE__, __LINE__); + LOG(LOG_LEVEL_TRACE, " sesman_ini = %s", g_cfg->sesman_ini); + LOG(LOG_LEVEL_TRACE, " listen_address = %s", g_cfg->listen_address); + LOG(LOG_LEVEL_TRACE, " listen_port = %s", g_cfg->listen_port); + LOG(LOG_LEVEL_TRACE, " enable_user_wm = %d", g_cfg->enable_user_wm); + LOG(LOG_LEVEL_TRACE, " default_wm = %s", g_cfg->default_wm); + LOG(LOG_LEVEL_TRACE, " user_wm = %s", g_cfg->user_wm); + LOG(LOG_LEVEL_TRACE, " reconnect_sh = %s", g_cfg->reconnect_sh); + LOG(LOG_LEVEL_TRACE, " auth_file_path = %s", g_cfg->auth_file_path); if (daemon) { @@ -380,15 +510,16 @@ /* start of daemonizing code */ if (sesman_listen_test(g_cfg) != 0) { - - log_message(LOG_LEVEL_ERROR, "Failed to start xrdp-sesman daemon, " - "possibly address already in use."); + LOG(LOG_LEVEL_ERROR, "Failed to start xrdp-sesman daemon, " + "possibly address already in use."); + config_free(g_cfg); g_deinit(); g_exit(1); } if (0 != g_fork()) { + config_free(g_cfg); g_deinit(); g_exit(0); } @@ -415,14 +546,16 @@ if (daemon) { /* writing pid file */ - fd = g_file_open(pid_file); + char pid_s[32]; + int fd = g_file_open(pid_file); if (-1 == fd) { - log_message(LOG_LEVEL_ERROR, - "error opening pid file[%s]: %s", - pid_file, g_get_strerror()); + LOG(LOG_LEVEL_ERROR, + "error opening pid file[%s]: %s", + pid_file, g_get_strerror()); log_end(); + config_free(g_cfg); g_deinit(); g_exit(1); } @@ -433,8 +566,8 @@ } /* start program main loop */ - log_message(LOG_LEVEL_INFO, - "starting xrdp-sesman with pid %d", g_pid); + LOG(LOG_LEVEL_INFO, + "starting xrdp-sesman with pid %d", g_pid); /* make sure the socket directory exists */ g_mk_socket_path("xrdp-sesman"); @@ -444,7 +577,7 @@ { if (!g_create_dir("/tmp/.X11-unix")) { - log_message(LOG_LEVEL_ERROR, + LOG(LOG_LEVEL_ERROR, "sesman.c: error creating dir /tmp/.X11-unix"); } g_chmod_hex("/tmp/.X11-unix", 0x1777); @@ -468,6 +601,7 @@ log_end(); } + config_free(g_cfg); g_deinit(); g_exit(error); return 0; diff -Nru xrdp-0.9.12/sesman/sesman.ini xrdp-0.9.15/sesman/sesman.ini --- xrdp-0.9.12/sesman/sesman.ini 2019-12-28 12:36:44.000000000 +0000 +++ xrdp-0.9.15/sesman/sesman.ini 2020-12-28 14:06:46.000000000 +0000 @@ -37,17 +37,17 @@ ;; KillDisconnected - kill disconnected sessions ; Type: boolean ; Default: false -; if 1, true, or yes, kill session after 60 seconds +; if 1, true, or yes, every session will be killed within DisconnectedTimeLimit +; seconds after the user disconnects KillDisconnected=false -;; DisconnectedTimeLimit - when to kill idle sessions +;; DisconnectedTimeLimit (seconds) - wait before kill disconnected sessions ; Type: integer ; Default: 0 -; if not zero, the seconds before a disconnected session is killed -; min 60 seconds +; if KillDisconnected is set to false, this value is ignored DisconnectedTimeLimit=0 -;; IdleTimeLimit (specify in second) - wait before disconnect idle sessions +;; IdleTimeLimit (seconds) - wait before disconnect idle sessions ; Type: integer ; Default: 0 ; Set to 0 to disable idle disconnection. @@ -55,7 +55,7 @@ ;; Policy - session allocation policy ; Type: enum [ "Default" | "UBD" | "UBI" | "UBC" | "UBDI" | "UBDC" ] -; Default: Xrdp: and Xvnc: +; "Default" session per ; "UBD" session per ; "UBI" session per ; "UBC" session per @@ -64,10 +64,19 @@ Policy=Default [Logging] +; Note: Log levels can be any of: core, error, warning, info, debug, or trace LogFile=xrdp-sesman.log -LogLevel=DEBUG -EnableSyslog=1 -SyslogLevel=DEBUG +LogLevel=INFO +EnableSyslog=true +#SyslogLevel=INFO +#EnableConsole=false +#ConsoleLevel=INFO +#EnableProcessId=false + +[LoggingPerLogger] +; Note: per logger configuration is only used in XRDP_DEBUG builds of XRDP. +#sesman.c=INFO +#main()=INFO ; ; Session definitions - startup command-line parameters for each session type @@ -75,13 +84,15 @@ [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. @@ -103,11 +114,34 @@ param=96 [Chansrv] -; drive redirection, defaults to xrdp_client if not set +; drive redirection +; See sesman.ini(5) for the format of this parameter +#FuseMountName=/run/user/%u/thinclient_drives +#FuseMountName=/media/thinclient_drives/%U/thinclient_drives FuseMountName=thinclient_drives ; this value allows only the user to acess their own mapped drives. ; Make this more permissive (e.g. 022) if required. FileUmask=077 +; Can be used to disable FUSE functionality - see sesman.ini(5) +#EnableFuseMount=false + +[ChansrvLogging] +; Note: one log file is created per display and the LogFile config value +; is ignored. The channel server log file names follow the naming convention: +; xrdp-chansrv.${DISPLAY}.log +; +; Note: Log levels can be any of: core, error, warning, info, debug, or trace +LogLevel=INFO +EnableSyslog=true +#SyslogLevel=INFO +#EnableConsole=false +#ConsoleLevel=INFO +#EnableProcessId=false + +[ChansrvLoggingPerLogger] +; Note: per logger configuration is only used in XRDP_DEBUG builds of XRDP. +#chansrv.c=INFO +#main()=INFO [SessionVariables] PULSE_SCRIPT=/etc/xrdp/pulse/default.pa diff -Nru xrdp-0.9.12/sesman/session.c xrdp-0.9.15/sesman/session.c --- xrdp-0.9.12/sesman/session.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/session.c 2020-12-28 14:03:43.000000000 +0000 @@ -41,12 +41,12 @@ #include "libscp_types.h" #include "xauth.h" #include "xrdp_sockets.h" +#include "string_calls.h" #ifndef PR_SET_NO_NEW_PRIVS #define PR_SET_NO_NEW_PRIVS 38 #endif - extern unsigned char g_fixedkey[8]; extern struct config_sesman *g_cfg; /* in sesman.c */ extern int g_sck; /* in sesman.c */ @@ -71,7 +71,7 @@ g_memset(outstr, 0, len); if (self->count == 0) { - g_writeln("List is empty"); + LOG_DEVEL(LOG_LEVEL_TRACE, "List is empty"); } for (index = 0; index < self->count; index++) @@ -105,9 +105,6 @@ { 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 */ @@ -120,15 +117,15 @@ } #if 0 - log_message(LOG_LEVEL_INFO, - "session_get_bydata: search policy %d U %s W %d H %d bpp %d T %d IP %s", - policy, name, width, height, bpp, type, client_ip); + LOG(LOG_LEVEL_INFO, + "session_get_bydata: search policy %d U %s W %d H %d bpp %d T %d IP %s", + policy, name, width, height, bpp, type, client_ip); #endif while (tmp != 0) { #if 0 - log_message(LOG_LEVEL_INFO, + LOG(LOG_LEVEL_INFO, "session_get_bydata: try %p U %s W %d H %d bpp %d T %d IP %s", tmp->item, tmp->item->name, @@ -138,14 +135,14 @@ #endif if (g_strncmp(name, tmp->item->name, 255) == 0 && - (!(policy & SESMAN_CFG_SESS_POLICY_D) || - (tmp->item->width == width && tmp->item->height == height)) && - (!(policy & SESMAN_CFG_SESS_POLICY_I) || - (g_strncmp_d(client_ip, tmp->item->client_ip, ':', 255) == 0)) && - (!(policy & SESMAN_CFG_SESS_POLICY_C) || - (g_strncmp(client_ip, tmp->item->client_ip, 255) == 0)) && - tmp->item->bpp == bpp && - tmp->item->type == type) + (!(policy & SESMAN_CFG_SESS_POLICY_D) || + (tmp->item->width == width && tmp->item->height == height)) && + (!(policy & SESMAN_CFG_SESS_POLICY_I) || + (g_strncmp_d(client_ip, tmp->item->client_ip, ':', 255) == 0)) && + (!(policy & SESMAN_CFG_SESS_POLICY_C) || + (g_strncmp(client_ip, tmp->item->client_ip, 255) == 0)) && + tmp->item->bpp == bpp && + tmp->item->type == type) { return tmp->item; } @@ -317,7 +314,7 @@ display++; } - log_message(LOG_LEVEL_ERROR, "X server -- no display in range is available"); + LOG(LOG_LEVEL_ERROR, "X server -- no display in range is available"); return 0; } @@ -337,9 +334,9 @@ if (i > 40) { - log_message(LOG_LEVEL_ERROR, - "X server for display %d startup timeout", - display); + LOG(LOG_LEVEL_ERROR, + "X server for display %d startup timeout", + display); break; } @@ -374,16 +371,11 @@ g_cfg->env_names, g_cfg->env_values); - if (g_cfg->sec.restrict_outbound_clipboard == 1) - { - g_setenv("CHANSRV_RESTRICT_OUTBOUND_CLIPBOARD", "1", 1); - } - /* executing chansrv */ g_execvp(exe_path, (char **) (chansrv_params->items)); /* should not get here */ - log_message(LOG_LEVEL_ALWAYS, "error starting chansrv " - "- user %s - pid %d", username, g_getpid()); + LOG(LOG_LEVEL_ALWAYS, "error starting chansrv " + "- user %s - pid %d", username, g_getpid()); list_delete(chansrv_params); g_exit(1); } @@ -429,8 +421,8 @@ /* check to limit concurrent sessions */ if (g_session_count >= g_cfg->sess.max_sessions) { - log_message(LOG_LEVEL_INFO, "max concurrent session limit " - "exceeded. login for user %s denied", s->username); + LOG(LOG_LEVEL_INFO, "max concurrent session limit " + "exceeded. login for user %s denied", s->username); return 0; } @@ -438,8 +430,8 @@ if (temp == 0) { - log_message(LOG_LEVEL_ERROR, "cannot create new chain " - "element - user %s", s->username); + LOG(LOG_LEVEL_ERROR, "cannot create new chain " + "element - user %s", s->username); return 0; } @@ -448,8 +440,8 @@ if (temp->item == 0) { g_free(temp); - log_message(LOG_LEVEL_ERROR, "cannot create new session " - "item - user %s", s->username); + LOG(LOG_LEVEL_ERROR, "cannot create new session " + "item - user %s", s->username); return 0; } @@ -470,8 +462,8 @@ } else if (pid == 0) { - log_message(LOG_LEVEL_INFO, "calling auth_start_session from pid %d", - g_getpid()); + LOG(LOG_LEVEL_INFO, "calling auth_start_session from pid %d", + g_getpid()); auth_start_session(data, display); g_delete_wait_obj(g_term_event); g_tcp_close(g_sck); @@ -502,15 +494,15 @@ */ if (g_setsid() < 0) { - log_message(LOG_LEVEL_ERROR, - "setsid failed - pid %d", g_getpid()); + LOG(LOG_LEVEL_ERROR, + "setsid failed - pid %d", g_getpid()); } if (g_setlogin(s->username) < 0) { - log_message(LOG_LEVEL_ERROR, - "setlogin failed for user %s - pid %d", s->username, - g_getpid()); + LOG(LOG_LEVEL_ERROR, + "setlogin failed for user %s - pid %d", s->username, + g_getpid()); } } @@ -552,10 +544,21 @@ { if (s->program[0] != 0) { - g_execlp3(s->program, s->program, 0); - log_message(LOG_LEVEL_ALWAYS, - "error starting program %s for user %s - pid %d", - s->program, s->username, g_getpid()); + LOG(LOG_LEVEL_DEBUG, + "starting program with parameters: %s ", + s->program); + if (g_strchr(s->program, ' ') != 0 || g_strchr(s->program, '\t') != 0) + { + const char *params[] = {"sh", "-c", s->program, NULL}; + g_execvp("/bin/sh", (char **)params); + } + else + { + g_execlp3(s->program, s->program, 0); + } + LOG(LOG_LEVEL_ALWAYS, + "error starting program %s for user %s - pid %d", + s->program, s->username, g_getpid()); } } /* try to execute user window manager if enabled */ @@ -565,51 +568,51 @@ if (g_file_exist(text)) { g_execlp3(text, g_cfg->user_wm, 0); - log_message(LOG_LEVEL_ALWAYS, "error starting user " - "wm for user %s - pid %d", s->username, g_getpid()); + LOG(LOG_LEVEL_ALWAYS, "error starting user " + "wm for user %s - pid %d", s->username, g_getpid()); /* logging parameters */ - log_message(LOG_LEVEL_DEBUG, "errno: %d, " - "description: %s", g_get_errno(), g_get_strerror()); - log_message(LOG_LEVEL_DEBUG, "execlp3 parameter " - "list:"); - log_message(LOG_LEVEL_DEBUG, " argv[0] = %s", - text); - log_message(LOG_LEVEL_DEBUG, " argv[1] = %s", - g_cfg->user_wm); + LOG(LOG_LEVEL_DEBUG, "errno: %d, " + "description: %s", g_get_errno(), g_get_strerror()); + LOG(LOG_LEVEL_DEBUG, "execlp3 parameter " + "list:"); + LOG(LOG_LEVEL_DEBUG, " argv[0] = %s", + text); + LOG(LOG_LEVEL_DEBUG, " argv[1] = %s", + g_cfg->user_wm); } } /* if we're here something happened to g_execlp3 so we try running the default window manager */ g_execlp3(g_cfg->default_wm, g_cfg->default_wm, 0); - log_message(LOG_LEVEL_ALWAYS, "error starting default " - "wm for user %s - pid %d", s->username, g_getpid()); + LOG(LOG_LEVEL_ALWAYS, "error starting default " + "wm for user %s - pid %d", s->username, g_getpid()); /* logging parameters */ - log_message(LOG_LEVEL_DEBUG, "errno: %d, description: " - "%s", g_get_errno(), g_get_strerror()); - log_message(LOG_LEVEL_DEBUG, "execlp3 parameter list:"); - log_message(LOG_LEVEL_DEBUG, " argv[0] = %s", - g_cfg->default_wm); - log_message(LOG_LEVEL_DEBUG, " argv[1] = %s", - g_cfg->default_wm); + LOG(LOG_LEVEL_DEBUG, "errno: %d, description: " + "%s", g_get_errno(), g_get_strerror()); + LOG(LOG_LEVEL_DEBUG, "execlp3 parameter list:"); + LOG(LOG_LEVEL_DEBUG, " argv[0] = %s", + g_cfg->default_wm); + LOG(LOG_LEVEL_DEBUG, " argv[1] = %s", + g_cfg->default_wm); /* still a problem starting window manager just start xterm */ g_execlp3("xterm", "xterm", 0); /* should not get here */ - log_message(LOG_LEVEL_ALWAYS, "error starting xterm " - "for user %s - pid %d", s->username, g_getpid()); + LOG(LOG_LEVEL_ALWAYS, "error starting xterm " + "for user %s - pid %d", s->username, g_getpid()); /* logging parameters */ - log_message(LOG_LEVEL_DEBUG, "errno: %d, description: " - "%s", g_get_errno(), g_get_strerror()); + LOG(LOG_LEVEL_DEBUG, "errno: %d, description: " + "%s", g_get_errno(), g_get_strerror()); } else { - log_message(LOG_LEVEL_ERROR, "another Xserver might " - "already be active on display %d - see log", display); + LOG(LOG_LEVEL_ERROR, "another Xserver might " + "already be active on display %d - see log", display); } - log_message(LOG_LEVEL_DEBUG, "aborting connection..."); + LOG(LOG_LEVEL_DEBUG, "aborting connection..."); g_exit(0); } else @@ -674,9 +677,9 @@ */ if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) { - log_message(LOG_LEVEL_WARNING, - "Failed to disable setuid on X server: %s", - g_get_strerror()); + LOG(LOG_LEVEL_WARNING, + "Failed to disable setuid on X server: %s", + g_get_strerror()); } #endif @@ -700,7 +703,7 @@ pp1 = (char **) xserver_params->items; - log_message(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048)); + LOG(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048)); /* some args are passed via env vars */ g_sprintf(geometry, "%d", s->width); @@ -745,7 +748,7 @@ /* make sure it ends with a zero */ list_add_item(xserver_params, 0); pp1 = (char **)xserver_params->items; - log_message(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048)); + LOG(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048)); g_execvp(xserver, pp1); } else if (type == SESMAN_SESSION_TYPE_XRDP) @@ -774,30 +777,30 @@ /* make sure it ends with a zero */ list_add_item(xserver_params, 0); pp1 = (char **)xserver_params->items; - log_message(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048)); + LOG(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048)); g_execvp(xserver, pp1); } else { - log_message(LOG_LEVEL_ALWAYS, "bad session type - " - "user %s - pid %d", s->username, g_getpid()); + LOG(LOG_LEVEL_ALWAYS, "bad session type - " + "user %s - pid %d", s->username, g_getpid()); g_exit(1); } /* should not get here */ - log_message(LOG_LEVEL_ALWAYS, "error starting X server " - "- user %s - pid %d", s->username, g_getpid()); + LOG(LOG_LEVEL_ALWAYS, "error starting X server " + "- user %s - pid %d", s->username, g_getpid()); /* logging parameters */ - log_message(LOG_LEVEL_DEBUG, "errno: %d, description: " - "%s", g_get_errno(), g_get_strerror()); - log_message(LOG_LEVEL_DEBUG, "execve parameter list size: " - "%d", (xserver_params)->count); + LOG(LOG_LEVEL_DEBUG, "errno: %d, description: " + "%s", g_get_errno(), g_get_strerror()); + LOG(LOG_LEVEL_DEBUG, "execve parameter list size: " + "%d", (xserver_params)->count); for (i = 0; i < (xserver_params->count); i++) { - log_message(LOG_LEVEL_DEBUG, " argv[%d] = %s", - i, (char *)list_get_item(xserver_params, i)); + LOG(LOG_LEVEL_DEBUG, " argv[%d] = %s", + i, (char *)list_get_item(xserver_params, i)); } list_delete(xserver_params); @@ -805,19 +808,42 @@ } else { + int wm_wait_time; wait_for_xserver(display); chansrv_pid = session_start_chansrv(s->username, display); - log_message(LOG_LEVEL_ALWAYS, "waiting for window manager " - "(pid %d) to exit", window_manager_pid); + + /* Monitor the amount of time we wait for the + * window manager. This is approximately how long the window + * manager was running for */ + LOG(LOG_LEVEL_INFO, "waiting for window manager " + "(pid %d) to exit", window_manager_pid); + wm_wait_time = g_time1(); g_waitpid(window_manager_pid); - log_message(LOG_LEVEL_ALWAYS, "window manager (pid %d) did " - "exit, cleaning up session", window_manager_pid); - log_message(LOG_LEVEL_INFO, "calling auth_stop_session and " - "auth_end from pid %d", g_getpid()); + wm_wait_time = g_time1() - wm_wait_time; + if (wm_wait_time < 10) + { + /* This could be a config issue. Log a significant error */ + LOG(LOG_LEVEL_ALWAYS, "window manager exited quickly " + "(%d secs). Window manager config problem?", + wm_wait_time); + } + else + { + LOG(LOG_LEVEL_INFO, "window manager (pid %d) was running " + "for approximately %d seconds.", + window_manager_pid, wm_wait_time); + } + LOG(LOG_LEVEL_INFO, "Cleaning up session. Calling " + "auth_stop_session and auth_end from pid %d", g_getpid()); auth_stop_session(data); auth_end(data); g_sigterm(display_pid); g_sigterm(chansrv_pid); + + /* make sure socket cleanup happen after child process exit */ + g_waitpid(display_pid); + g_waitpid(chansrv_pid); + cleanup_sockets(display); g_deinit(); g_exit(0); @@ -926,8 +952,8 @@ { if (tmp->item == 0) { - log_message(LOG_LEVEL_ERROR, "session descriptor for " - "pid %d is null!", pid); + LOG(LOG_LEVEL_ERROR, "session descriptor for " + "pid %d is null!", pid); if (prev == 0) { @@ -946,7 +972,7 @@ if (tmp->item->pid == pid) { /* deleting the session */ - log_message(LOG_LEVEL_INFO, "++ terminated session: username %s, display :%d.0, session_pid %d, ip %s", tmp->item->name, tmp->item->display, tmp->item->pid, tmp->item->client_ip); + LOG(LOG_LEVEL_INFO, "++ terminated session: username %s, display :%d.0, session_pid %d, ip %s", tmp->item->name, tmp->item->display, tmp->item->pid, tmp->item->client_ip); g_free(tmp->item); if (prev == 0) @@ -985,8 +1011,8 @@ { if (tmp->item == 0) { - log_message(LOG_LEVEL_ERROR, "found null session " - "descriptor!"); + LOG(LOG_LEVEL_ERROR, "found null session " + "descriptor!"); } else { @@ -1009,7 +1035,7 @@ if (0 == dummy) { - log_message(LOG_LEVEL_ERROR, "session_get_bypid: out of memory"); + LOG(LOG_LEVEL_ERROR, "session_get_bypid: out of memory"); return 0; } @@ -1019,8 +1045,8 @@ { if (tmp->item == 0) { - log_message(LOG_LEVEL_ERROR, "session descriptor for " - "pid %d is null!", pid); + LOG(LOG_LEVEL_ERROR, "session descriptor for " + "pid %d is null!", pid); g_free(dummy); return 0; } @@ -1054,13 +1080,13 @@ while (tmp != 0) { - LOG_DBG("user: %s", user); + LOG_DEVEL(LOG_LEVEL_DEBUG, "user: %s", user); if ((NULL == user) || (!g_strncasecmp(user, tmp->item->name, 256))) { - LOG_DBG("session_get_byuser: status=%d, flags=%d, " - "result=%d", (tmp->item->status), flags, - ((tmp->item->status) & flags)); + LOG_DEVEL(LOG_LEVEL_DEBUG, "session_get_byuser: status=%d, flags=%d, " + "result=%d", (tmp->item->status), flags, + ((tmp->item->status) & flags)); if ((tmp->item->status) & flags) { @@ -1092,7 +1118,7 @@ while (tmp != 0) { -/* #warning FIXME: we should get only disconnected sessions! */ + /* #warning FIXME: we should get only disconnected sessions! */ if ((NULL == user) || (!g_strncasecmp(user, tmp->item->name, 256))) { if ((tmp->item->status) & flags) @@ -1102,7 +1128,7 @@ (sess[index]).height = tmp->item->height; (sess[index]).width = tmp->item->width; (sess[index]).bpp = tmp->item->bpp; -/* #warning FIXME: setting idle times and such */ + /* #warning FIXME: setting idle times and such */ /*(sess[index]).connect_time.year = tmp->item->connect_time.year; (sess[index]).connect_time.month = tmp->item->connect_time.month; (sess[index]).connect_time.day = tmp->item->connect_time.day; @@ -1143,7 +1169,7 @@ int cleanup_sockets(int display) { - log_message(LOG_LEVEL_DEBUG, "cleanup_sockets:"); + LOG(LOG_LEVEL_DEBUG, "cleanup_sockets:"); char file[256]; int error; @@ -1152,11 +1178,12 @@ g_snprintf(file, 255, CHANSRV_PORT_OUT_STR, display); if (g_file_exist(file)) { - log_message(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file); + LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file); if (g_file_delete(file) == 0) { - log_message(LOG_LEVEL_DEBUG, - "cleanup_sockets: failed to delete %s", file); + LOG(LOG_LEVEL_WARNING, + "cleanup_sockets: failed to delete %s (%s)", + file, g_get_strerror()); error++; } } @@ -1164,11 +1191,12 @@ g_snprintf(file, 255, CHANSRV_PORT_IN_STR, display); if (g_file_exist(file)) { - log_message(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file); + LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file); if (g_file_delete(file) == 0) { - log_message(LOG_LEVEL_DEBUG, - "cleanup_sockets: failed to delete %s", file); + LOG(LOG_LEVEL_WARNING, + "cleanup_sockets: failed to delete %s (%s)", + file, g_get_strerror()); error++; } } @@ -1176,11 +1204,12 @@ g_snprintf(file, 255, XRDP_CHANSRV_STR, display); if (g_file_exist(file)) { - log_message(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file); + LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file); if (g_file_delete(file) == 0) { - log_message(LOG_LEVEL_DEBUG, - "cleanup_sockets: failed to delete %s", file); + LOG(LOG_LEVEL_WARNING, + "cleanup_sockets: failed to delete %s (%s)", + file, g_get_strerror()); error++; } } @@ -1188,11 +1217,41 @@ g_snprintf(file, 255, CHANSRV_API_STR, display); if (g_file_exist(file)) { - log_message(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file); + LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file); + if (g_file_delete(file) == 0) + { + LOG(LOG_LEVEL_WARNING, + "cleanup_sockets: failed to delete %s (%s)", + file, g_get_strerror()); + error++; + } + } + + /* the following files should be deleted by xorgxrdp + * but just in case the deletion failed */ + + g_snprintf(file, 255, XRDP_X11RDP_STR, display); + if (g_file_exist(file)) + { + LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file); + if (g_file_delete(file) == 0) + { + LOG(LOG_LEVEL_WARNING, + "cleanup_sockets: failed to delete %s (%s)", + file, g_get_strerror()); + error++; + } + } + + g_snprintf(file, 255, XRDP_DISCONNECT_STR, display); + if (g_file_exist(file)) + { + LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file); if (g_file_delete(file) == 0) { - log_message(LOG_LEVEL_DEBUG, - "cleanup_sockets: failed to delete %s", file); + LOG(LOG_LEVEL_WARNING, + "cleanup_sockets: failed to delete %s (%s)", + file, g_get_strerror()); error++; } } diff -Nru xrdp-0.9.12/sesman/sig.c xrdp-0.9.15/sesman/sig.c --- xrdp-0.9.12/sesman/sig.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/sig.c 2020-12-28 14:03:43.000000000 +0000 @@ -43,15 +43,15 @@ { char pid_file[256]; - log_message(LOG_LEVEL_INFO, "shutting down sesman %d", 1); + LOG(LOG_LEVEL_INFO, "shutting down sesman %d", 1); if (g_getpid() != g_pid) { - LOG_DBG("g_getpid() [%d] differs from g_pid [%d]", (g_getpid()), g_pid); + LOG_DEVEL(LOG_LEVEL_DEBUG, "g_getpid() [%d] differs from g_pid [%d]", (g_getpid()), g_pid); return; } - LOG_DBG(" - getting signal %d pid %d", sig, g_getpid()); + LOG_DEVEL(LOG_LEVEL_DEBUG, " - getting signal %d pid %d", sig, g_getpid()); g_set_wait_obj(g_term_event); @@ -67,28 +67,18 @@ { int error; struct config_sesman *cfg; - char cfg_file[256]; - log_message(LOG_LEVEL_WARNING, "receiving SIGHUP %d", 1); + LOG(LOG_LEVEL_WARNING, "receiving SIGHUP %d", 1); if (g_getpid() != g_pid) { - LOG_DBG("g_getpid() [%d] differs from g_pid [%d]", g_getpid(), g_pid); + LOG_DEVEL(LOG_LEVEL_DEBUG, "g_getpid() [%d] differs from g_pid [%d]", g_getpid(), g_pid); return; } - cfg = g_new0(struct config_sesman, 1); - - if (0 == cfg) - { - log_message(LOG_LEVEL_ERROR, "error creating new config: - keeping old cfg"); - return; - } - - if (config_read(cfg) != 0) + if ((cfg = config_read(g_cfg->sesman_ini)) == NULL) { - log_message(LOG_LEVEL_ERROR, "error reading config - keeping old cfg"); - g_free(cfg); + LOG(LOG_LEVEL_ERROR, "error reading config - keeping old cfg"); return; } @@ -101,10 +91,8 @@ /* replace old config with newly read one */ g_cfg = cfg; - g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); - /* start again logging subsystem */ - error = log_start(cfg_file, "xrdp-sesman"); + error = log_start(g_cfg->sesman_ini, "xrdp-sesman"); if (error != LOG_STARTUP_OK) { @@ -121,7 +109,7 @@ } } - log_message(LOG_LEVEL_INFO, "configuration reloaded, log subsystem restarted"); + LOG(LOG_LEVEL_INFO, "configuration reloaded, log subsystem restarted"); } /******************************************************************************/ @@ -171,7 +159,7 @@ do { - LOG_DBG("calling sigwait()"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "calling sigwait()"); sigwait(&waitmask, &recv_signal); switch (recv_signal) @@ -179,22 +167,22 @@ case SIGHUP: //reload cfg //we must stop & restart logging, or copy logging cfg!!!! - LOG_DBG("sesman received SIGHUP"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sesman received SIGHUP"); //return 0; break; case SIGCHLD: /* a session died */ - LOG_DBG("sesman received SIGCHLD"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sesman received SIGCHLD"); sig_sesman_session_end(SIGCHLD); break; case SIGINT: /* we die */ - LOG_DBG("sesman received SIGINT"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sesman received SIGINT"); sig_sesman_shutdown(recv_signal); break; case SIGTERM: /* we die */ - LOG_DBG("sesman received SIGTERM"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "sesman received SIGTERM"); sig_sesman_shutdown(recv_signal); break; } diff -Nru xrdp-0.9.12/sesman/startwm.sh xrdp-0.9.15/sesman/startwm.sh --- xrdp-0.9.12/sesman/startwm.sh 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/startwm.sh 2020-12-28 14:03:43.000000000 +0000 @@ -85,6 +85,9 @@ # do not execute the pseudo login shell scripts . /etc/X11/xdm/Xsession exit 0 + elif [ -r /usr/etc/X11/xdm/Xsession ]; then + . /usr/etc/X11/xdm/Xsession + exit 0 fi pre_start diff -Nru xrdp-0.9.12/sesman/tools/Makefile.in xrdp-0.9.15/sesman/tools/Makefile.in --- xrdp-0.9.12/sesman/tools/Makefile.in 2019-12-28 12:36:38.000000000 +0000 +++ xrdp-0.9.15/sesman/tools/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/sesman/tools/sesadmin.c xrdp-0.9.15/sesman/tools/sesadmin.c --- xrdp-0.9.12/sesman/tools/sesadmin.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/tools/sesadmin.c 2020-12-28 14:03:43.000000000 +0000 @@ -27,6 +27,7 @@ #include "parse.h" #include "log.h" #include "libscp.h" +#include "string_calls.h" #include #include @@ -37,8 +38,6 @@ char serv[257]; char port[257]; -struct log_config logging; - void cmndList(struct SCP_CONNECTION *c); void cmndKill(struct SCP_CONNECTION *c, struct SCP_SESSION *s); void cmndHelp(void); @@ -56,6 +55,7 @@ //int sel; int sock; char *pwd; + struct log_config *logging; user[0] = '\0'; pass[0] = '\0'; @@ -63,11 +63,9 @@ serv[0] = '\0'; port[0] = '\0'; - logging.program_name = "sesadmin"; - logging.log_file = g_strdup("xrdp-sesadmin.log"); - logging.log_level = LOG_LEVEL_DEBUG; - logging.enable_syslog = 0; - log_start_from_param(&logging); + logging = log_config_init_for_console(LOG_LEVEL_INFO, NULL); + log_start_from_param(logging); + log_config_free(logging); for (idx = 0; idx < argc; idx++) { @@ -133,18 +131,18 @@ sock = g_tcp_socket(); if (sock < 0) { - LOG_DBG("Socket open error, g_tcp_socket() failed"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "Socket open error, g_tcp_socket() failed"); return 1; } s = scp_session_create(); c = scp_connection_create(sock); - LOG_DBG("Connecting to %s:%s with user %s (%s)", serv, port, user, pass); + LOG_DEVEL(LOG_LEVEL_DEBUG, "Connecting to %s:%s with user %s (%s)", serv, port, user, pass); if (0 != g_tcp_connect(sock, serv, port)) { - LOG_DBG("g_tcp_connect() error"); + LOG_DEVEL(LOG_LEVEL_DEBUG, "g_tcp_connect() error"); return 1; } @@ -157,7 +155,7 @@ if (SCP_CLIENT_STATE_OK != e) { - LOG_DBG("libscp error connecting: %s %d", s->errstr, (int)e); + LOG_DEVEL(LOG_LEVEL_DEBUG, "libscp error connecting: %s %d", s->errstr, (int)e); } if (0 == g_strncmp(cmnd, "list", 5)) diff -Nru xrdp-0.9.12/sesman/tools/sesrun.c xrdp-0.9.15/sesman/tools/sesrun.c --- xrdp-0.9.12/sesman/tools/sesrun.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/tools/sesrun.c 2020-12-28 14:03:43.000000000 +0000 @@ -28,111 +28,588 @@ #include #endif -#include "sesman.h" +#include +#include +#include + +#include "parse.h" +#include "os_calls.h" +#include "config.h" +#include "log.h" #include "tcp.h" +#include "string_calls.h" -struct config_sesman g_cfg; /* config.h */ +#if !defined(PACKAGE_VERSION) +#define PACKAGE_VERSION "???" +#endif -/******************************************************************************/ -int -main(int argc, char **argv) +#ifndef MAX_PASSWORD_LEN +# define MAX_PASSWORD_LEN 512 +#endif + +#ifndef DEFAULT_WIDTH +# define DEFAULT_WIDTH 1280 +#endif + +#ifndef DEFAULT_HEIGHT +# define DEFAULT_HEIGHT 1024 +#endif + +/* Default setting used by Windows 10 mstsc.exe */ +#ifndef DEFAULT_BPP +# define DEFAULT_BPP 32 +#endif + +#ifndef DEFAULT_SERVER +# define DEFAULT_SERVER "localhost" +#endif + +#ifndef DEFAULT_TYPE +# define DEFAULT_TYPE "Xorg" +#endif + +/** + * Maps session type strings to internal code numbers + */ +static struct { - int sck; + const char *name; int code; - int i; - int size; - int version; +} type_map[] = +{ + { "Xvnc", 0}, + { "X11rdp", 10}, + { "Xorg", 20}, + { NULL, -1} +}; + +/** + * Parameters needed for a session + */ +struct session_params +{ int width; int height; int bpp; - int display; int session_code; - struct stream *in_s; - struct stream *out_s; - char *username; - char *password; - long data; - - if (0 != config_read(&g_cfg)) - { - g_printf("sesrun: error reading config. quitting.\n"); - return 1; - } - - if (argc == 1) - { - g_printf("xrdp session starter v0.1\n"); - g_printf("\nusage:\n"); - g_printf("sesrun \n"); - g_printf("session code 0 for Xvnc, 10 for X11RDP, 20 for Xorg\n"); - } - else if (argc == 8) - { - username = argv[2]; - password = argv[3]; - width = g_atoi(argv[4]); - height = g_atoi(argv[5]); - bpp = g_atoi(argv[6]); - session_code = g_atoi(argv[7]); - make_stream(in_s); - init_stream(in_s, 8192); - make_stream(out_s); - init_stream(out_s, 8192); + const char *server; - sck = g_tcp_socket(); - if (sck < 0) - return 1; + const char *domain; /* Currently unused by sesman */ + const char *directory; + const char *shell; + const char *client_ip; + + const char *username; + char password[MAX_PASSWORD_LEN + 1]; +}; + +/**************************************************************************//** + * Maps a string to a session code + * + * @param t session type + * @return session code, or -1 if not found + */ +static +int get_session_type_code(const char *t) +{ + unsigned int i; + for (i = 0 ; type_map[i].name != NULL; ++i) + { + if (g_strcasecmp(type_map[i].name, t) == 0) + { + return type_map[i].code; + } + } - if (g_tcp_connect(sck, argv[1], g_cfg.listen_port) == 0) + return -1; +} + +/**************************************************************************//** + * Returns a list of supported session types + * + * Caller supplies a buffer. Buffer handling and buffer overflow detection are + * the same as snprint() + * + * @param buff area for result + * @param bufflen Size of result + * @return number of characters for the output string + */ +static +unsigned int get_session_type_list(char *buff, unsigned int bufflen) +{ + unsigned int i; + unsigned int ret = 0; + const char *sep = ""; + + for (i = 0 ; type_map[i].name != NULL; ++i) + { + if (ret < bufflen) { - s_push_layer(out_s, channel_hdr, 8); - out_uint16_be(out_s, session_code); /* code */ - i = g_strlen(username); - out_uint16_be(out_s, i); - out_uint8a(out_s, username, i); - i = g_strlen(password); - out_uint16_be(out_s, i); - out_uint8a(out_s, password, i); - out_uint16_be(out_s, width); - out_uint16_be(out_s, height); - out_uint16_be(out_s, bpp); - s_mark_end(out_s); - s_pop_layer(out_s, channel_hdr); - out_uint32_be(out_s, 0); /* version */ - out_uint32_be(out_s, out_s->end - out_s->data); /* size */ - tcp_force_send(sck, out_s->data, out_s->end - out_s->data); + ret += g_snprintf(buff + ret, bufflen - ret, + "%s%s", sep, type_map[i].name); + sep = ", "; + } + } + + return ret; +} + +/**************************************************************************//** + * Prints a brief summary of options and defaults + */ +static void +usage(void) +{ + char sesstype_list[64]; - if (tcp_force_recv(sck, in_s->data, 8) == 0) + (void)get_session_type_list(sesstype_list, sizeof(sesstype_list)); + + g_printf("xrdp session starter v" PACKAGE_VERSION "\n"); + g_printf("\nusage:\n"); + g_printf("sesrun [options] username\n\n"); + g_printf("options:\n"); + g_printf(" -g Default:%dx%d\n", + DEFAULT_WIDTH, DEFAULT_HEIGHT); + g_printf(" -b Default:%d\n", DEFAULT_BPP); + /* Don't encourage use of this one - we need to move to local sockets */ + g_printf(" -s Default:%s (Deprecated)\n", + DEFAULT_SERVER); + g_printf(" -t Default:%s\n", DEFAULT_TYPE); + g_printf(" -D Default: $HOME\n" + " -S Default: Defined window manager\n" + " -p TESTING ONLY - DO NOT USE IN PRODUCTION\n" + " -F Read password from this file descriptor\n" + " -c Alternative sesman.ini file\n"); + g_printf("Supported types are %s or use int for internal code\n", + sesstype_list); + g_printf("Password is prompted if -p or -F are not specified\n"); +} + + +/**************************************************************************//** + * Parses a string x + * + * @param geom_str Input string + * @param sp Session parameter structure for resulting width and height + * @return !=0 for success + */ +static int +parse_geometry_string(const char *geom_str, struct session_params *sp) +{ + int result = 0; + unsigned int sep_count = 0; /* Count of 'x' separators */ + unsigned int other_count = 0; /* Count of non-digits and non separators */ + const char *sepp = NULL; /* Pointer to the 'x' */ + const char *p = geom_str; + + while (*p != '\0') + { + if (!isdigit(*p)) + { + if (*p == 'x' || *p == 'X') { - in_uint32_be(in_s, version); - in_uint32_be(in_s, size); - init_stream(in_s, 8192); + ++sep_count; + sepp = p; + } + else + { + ++other_count; + } + } + ++p; + } + + if (sep_count != 1 || other_count > 0 || + sepp == geom_str || /* Separator at start of string */ + sepp == (p - 1) ) /* Separator at end of string */ + { + LOG(LOG_LEVEL_ERROR, "Invalid geometry string '%s'", geom_str); + } + else + { + sp->width = atoi(geom_str); + sp->height = atoi(sepp + 1); + result = 1; + } + + return result; +} + + +/**************************************************************************//** + * Read a password from a file descriptor + * + * @param fd_str string representing file descriptor + * @param sp Session parameter structure for resulting password + * @return !=0 for success + */ +static int +read_password_from_fd(const char *fd_str, struct session_params *sp) +{ + int result = 0; + int s = g_file_read(atoi(fd_str), sp->password, sizeof (sp->password) - 1); + if (s < 0) + { + LOG(LOG_LEVEL_ERROR, "Can't read password from fd %s - %s", + fd_str, g_get_strerror()); + sp->password[0] = '\0'; + } + else + { + sp->password[s] = '\0'; + if (s > 0 && sp->password[s - 1] == '\n') + { + sp->password[s - 1] = '\0'; + } + result = 1; + } + return result; +} + +/**************************************************************************//** + * Parses the program args + * + * @param argc Passed to main + * @param @argv Passed to main + * @param sp Session parameter structure for resulting values + * @param sesman_ini Pointer to an alternative config file if one is specified + * @return !=0 for success + */ +static int +parse_program_args(int argc, char *argv[], struct session_params *sp, + const char **sesman_ini) +{ + int params_ok = 1; + int opt; + bool_t password_set = 0; + + sp->width = DEFAULT_WIDTH; + sp->height = DEFAULT_HEIGHT; + sp->bpp = DEFAULT_BPP; + sp->session_code = get_session_type_code(DEFAULT_TYPE); + sp->server = DEFAULT_SERVER; + + sp->domain = ""; + sp->directory = ""; + sp->shell = ""; + sp->client_ip = ""; - if (tcp_force_recv(sck, in_s->data, size - 8) == 0) + sp->username = NULL; + sp->password[0] = '\0'; + + while ((opt = getopt(argc, argv, "g:b:s:t:D:S:p:F:c:")) != -1) + { + switch (opt) + { + case 'g': + if (!parse_geometry_string(optarg, sp)) { - if (version == 0) + params_ok = 0; + } + break; + + case 'b': + sp->bpp = atoi(optarg); + break; + + case 's': + LOG(LOG_LEVEL_WARNING, "Using deprecated option '-s'"); + sp->server = optarg; + break; + + case 't': + if (isdigit(optarg[0])) + { + sp->session_code = atoi(optarg); + } + else + { + sp->session_code = get_session_type_code(optarg); + if (sp->session_code < 0) { - in_uint16_be(in_s, code); + LOG(LOG_LEVEL_ERROR, "Unrecognised session type '%s'", + optarg); + params_ok = 0; + } + } + break; + + case 'D': + sp->directory = optarg; + break; + + case 'S': + sp->shell = optarg; + break; - if (code == 3) + case 'p': + if (password_set) + { + LOG(LOG_LEVEL_WARNING, + "Ignoring option '%c' - password already set ", + (char)opt); + } + else + { + g_strncpy(sp->password, optarg, sizeof(sp->password) - 1); + password_set = 1; + } + break; + + case 'F': + if (password_set) + { + LOG(LOG_LEVEL_WARNING, + "Ignoring option '%c' - password already set ", + (char)opt); + } + else + { + if (read_password_from_fd(optarg, sp)) + { + password_set = 1; + } + else + { + params_ok = 0; + } + } + break; + + case 'c': + *sesman_ini = optarg; + break; + + default: + LOG(LOG_LEVEL_ERROR, "Unrecognised switch '%c'", (char)opt); + params_ok = 0; + } + } + + if (argc <= optind) + { + LOG(LOG_LEVEL_ERROR, "No user name speciified"); + params_ok = 0; + } + else if ((argc - optind) > 1) + { + LOG(LOG_LEVEL_ERROR, "Unexpected arguments after username"); + params_ok = 0; + } + else + { + sp->username = argv[optind]; + } + + if (params_ok && !password_set) + { + const char *p = getpass("Password: "); + if (p != NULL) + { + g_strcpy(sp->password, p); + } + } + + return params_ok; +} + +/**************************************************************************//** + * Helper function for send_scpv0_auth_request() + * + * @param s Output string + * @param str String to write to s + */ +static void +out_string16(struct stream *s, const char *str) +{ + int i = g_strlen(str); + out_uint16_be(s, i); + out_uint8a(s, str, i); +} + +/**************************************************************************//** + * Sends an SCP V0 authorization request + * + * @param sck file descriptor to send request on + * @param sp Data for request + * + * @todo This code duplicates functionality in the XRDP function + * xrdp_mm_send_login(). When SCP is reworked, a common library + * function should be used + */ +static void +send_scpv0_auth_request(int sck, const struct session_params *sp) +{ + struct stream *out_s; + + LOG(LOG_LEVEL_DEBUG, + "width:%d height:%d bpp:%d code:%d\n" + "server:\"%s\" domain:\"%s\" directory:\"%s\"\n" + "shell:\"%s\" client_ip:\"%s\"", + sp->width, sp->height, sp->bpp, sp->session_code, + sp->server, sp->domain, sp->directory, + sp->shell, sp->client_ip); + /* Only log the password in development builds */ + LOG_DEVEL(LOG_LEVEL_DEBUG, "password:\"%s\"", sp->password); + + make_stream(out_s); + init_stream(out_s, 8192); + + s_push_layer(out_s, channel_hdr, 8); + out_uint16_be(out_s, sp->session_code); + out_string16(out_s, sp->username); + out_string16(out_s, sp->password); + out_uint16_be(out_s, sp->width); + out_uint16_be(out_s, sp->height); + out_uint16_be(out_s, sp->bpp); + out_string16(out_s, sp->domain); + out_string16(out_s, sp->shell); + out_string16(out_s, sp->directory); + out_string16(out_s, sp->client_ip); + s_mark_end(out_s); + + s_pop_layer(out_s, channel_hdr); + out_uint32_be(out_s, 0); /* version */ + out_uint32_be(out_s, out_s->end - out_s->data); /* size */ + tcp_force_send(sck, out_s->data, out_s->end - out_s->data); + + free_stream(out_s); +} + +/**************************************************************************//** + * Receives an SCP V0 authorization reply + * + * @param sck file descriptor to receive reply on + * + * @todo This code duplicates functionality in the XRDP function + * xrdp_mm_process_login_response(). When SCP is reworked, a + * common library function should be used + */ +static int +handle_scpv0_auth_reply(int sck) +{ + int result = 1; + int packet_ok = 0; + + struct stream *in_s; + + make_stream(in_s); + init_stream(in_s, 8192); + + if (tcp_force_recv(sck, in_s->data, 8) == 0) + { + int version; + int size; + int code; + int data; + int display; + + in_uint32_be(in_s, version); + in_uint32_be(in_s, size); + if (version == 0 && size >= 14) + { + init_stream(in_s, 8192); + if (tcp_force_recv(sck, in_s->data, size - 8) == 0) + { + in_s->end = in_s->data + (size - 8); + + in_uint16_be(in_s, code); + in_uint16_be(in_s, data); + in_uint16_be(in_s, display); + + if (code == 3) + { + packet_ok = 1; + + if (data == 0) + { + g_printf("Connection denied (authentication error)\n"); + } + else + { + char guid[16]; + char guid_str[64]; + if (s_check_rem(in_s, 16) != 0) { - in_uint16_be(in_s, data); - in_uint16_be(in_s, display); - g_printf("ok %d display %d\n", (int)data, display); + in_uint8a(in_s, guid, 16); + g_bytes_to_hexstr(guid, 16, guid_str, 64); } + else + { + g_strcpy(guid_str, ""); + } + + g_printf("ok data=%d display=:%d GUID=%s\n", + (int)data, display, guid_str); + result = 0; } } } } + } + + if (!packet_ok) + { + LOG(LOG_LEVEL_ERROR, "Corrupt reply packet"); + } + free_stream(in_s); + + return result; +} + +/******************************************************************************/ +int +main(int argc, char **argv) +{ + const char *sesman_ini = XRDP_CFG_PATH "/sesman.ini"; + struct config_sesman *cfg = NULL; + + int sck = -1; + struct session_params sp; + + struct log_config *logging; + int status = 1; + + logging = log_config_init_for_console(LOG_LEVEL_WARNING, + g_getenv("SESRUN_LOG_LEVEL")); + log_start_from_param(logging); + log_config_free(logging); + + if (!parse_program_args(argc, argv, &sp, &sesman_ini)) + { + usage(); + } + else if ((cfg = config_read(sesman_ini)) == NULL) + { + LOG(LOG_LEVEL_ERROR, "error reading config file %s : %s", + sesman_ini, g_get_strerror()); + } + else + { + sck = g_tcp_socket(); + if (sck < 0) + { + LOG(LOG_LEVEL_ERROR, "socket error - %s", g_get_strerror()); + } + else if (g_tcp_connect(sck, sp.server, cfg->listen_port) != 0) + { + LOG(LOG_LEVEL_ERROR, "connect error - %s", g_get_strerror()); + } else { - g_printf("connect error\n"); + send_scpv0_auth_request(sck, &sp); + status = handle_scpv0_auth_reply(sck); } + } + if (sck >= 0) + { g_tcp_close(sck); - free_stream(in_s); - free_stream(out_s); } - return 0; + g_memset(sp.password, '\0', sizeof(sp.password)); + config_free(cfg); + log_end(); + + return status; } diff -Nru xrdp-0.9.12/sesman/tools/sestest.c xrdp-0.9.15/sesman/tools/sestest.c --- xrdp-0.9.12/sesman/tools/sestest.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/tools/sestest.c 2020-12-28 14:03:43.000000000 +0000 @@ -26,6 +26,7 @@ #include "libscp.h" #include "parse.h" #include "log.h" +#include "string_calls.h" #include @@ -56,7 +57,9 @@ sock = g_tcp_socket(); if (sock < 0) + { return 1; + } s = scp_session_create(); c = scp_connection_create(sock); diff -Nru xrdp-0.9.12/sesman/verify_user_bsd.c xrdp-0.9.15/sesman/verify_user_bsd.c --- xrdp-0.9.12/sesman/verify_user_bsd.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/verify_user_bsd.c 2020-12-28 14:03:43.000000000 +0000 @@ -43,7 +43,7 @@ #define SECS_PER_DAY (24L*3600L) #endif -extern struct config_sesman* g_cfg; /* in sesman.c */ +extern struct config_sesman *g_cfg; /* in sesman.c */ /******************************************************************************/ /* returns boolean */ @@ -116,7 +116,7 @@ * */ static int -auth_account_disabled(struct spwd* stp) +auth_account_disabled(struct spwd *stp) { return 0; } diff -Nru xrdp-0.9.12/sesman/verify_user.c xrdp-0.9.15/sesman/verify_user.c --- xrdp-0.9.12/sesman/verify_user.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/verify_user.c 2020-12-28 14:03:43.000000000 +0000 @@ -78,7 +78,7 @@ if (1 == auth_account_disabled(stp)) { - log_message(LOG_LEVEL_INFO, "account %s is disabled", user); + LOG(LOG_LEVEL_INFO, "account %s is disabled", user); return 0; } @@ -312,13 +312,13 @@ today = g_time1() / SECS_PER_DAY; - LOG_DBG("last %d", stp->sp_lstchg); - LOG_DBG("min %d", stp->sp_min); - LOG_DBG("max %d", stp->sp_max); - LOG_DBG("inact %d", stp->sp_inact); - LOG_DBG("warn %d", stp->sp_warn); - LOG_DBG("expire %d", stp->sp_expire); - LOG_DBG("today %d", today); + LOG_DEVEL(LOG_LEVEL_DEBUG, "last %ld", stp->sp_lstchg); + LOG_DEVEL(LOG_LEVEL_DEBUG, "min %ld", stp->sp_min); + LOG_DEVEL(LOG_LEVEL_DEBUG, "max %ld", stp->sp_max); + LOG_DEVEL(LOG_LEVEL_DEBUG, "inact %ld", stp->sp_inact); + LOG_DEVEL(LOG_LEVEL_DEBUG, "warn %ld", stp->sp_warn); + LOG_DEVEL(LOG_LEVEL_DEBUG, "expire %ld", stp->sp_expire); + LOG_DEVEL(LOG_LEVEL_DEBUG, "today %d", today); if ((stp->sp_expire != -1) && (today >= stp->sp_expire)) { @@ -326,9 +326,9 @@ } if ((stp->sp_max >= 0) && - (stp->sp_inact >= 0) && - (stp->sp_lstchg > 0) && - (today >= (stp->sp_lstchg + stp->sp_max + stp->sp_inact))) + (stp->sp_inact >= 0) && + (stp->sp_lstchg > 0) && + (today >= (stp->sp_lstchg + stp->sp_max + stp->sp_inact))) { return 1; } diff -Nru xrdp-0.9.12/sesman/verify_user_pam.c xrdp-0.9.15/sesman/verify_user_pam.c --- xrdp-0.9.12/sesman/verify_user_pam.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/verify_user_pam.c 2020-12-28 14:03:43.000000000 +0000 @@ -30,14 +30,18 @@ #include "arch.h" #include "os_calls.h" +#include "string_calls.h" #include #include +/* 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 @@ -74,6 +78,9 @@ reply[i].resp = g_strdup(user_pass->pass); reply[i].resp_retcode = PAM_SUCCESS; break; + case PAM_TEXT_INFO: + g_memset(&reply[i], 0, sizeof(struct pam_response)); + break; default: g_printf("unknown in verify_pam_conv\r\n"); g_free(reply); @@ -92,7 +99,7 @@ service_name[0] = 0; if (g_file_exist("/etc/pam.d/xrdp-sesman") || - g_file_exist(XRDP_SYSCONF_PATH "/pam.d/xrdp-sesman")) + g_file_exist(XRDP_SYSCONF_PATH "/pam.d/xrdp-sesman")) { g_strncpy(service_name, "xrdp-sesman", 255); } @@ -115,8 +122,8 @@ 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)); diff -Nru xrdp-0.9.12/sesman/xauth.c xrdp-0.9.15/sesman/xauth.c --- xrdp-0.9.12/sesman/xauth.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/sesman/xauth.c 2020-12-28 14:03:43.000000000 +0000 @@ -30,6 +30,7 @@ #include #include "log.h" #include "os_calls.h" +#include "string_calls.h" /******************************************************************************/ @@ -46,19 +47,19 @@ g_bytes_to_hexstr(cookie_bin, 16, cookie_str, 33); g_sprintf(xauth_str, "xauth -q -f %s add :%d . %s", - file, display, cookie_str); + file, display, cookie_str); dp = popen(xauth_str, "r"); if (dp == NULL) { - log_message(LOG_LEVEL_ERROR, "Unable to launch xauth"); + LOG(LOG_LEVEL_ERROR, "Unable to launch xauth"); return 1; } ret = pclose(dp); if (ret < 0) { - log_message(LOG_LEVEL_ERROR, "An error occurred while running xauth"); + LOG(LOG_LEVEL_ERROR, "An error occurred while running xauth"); return 1; } diff -Nru xrdp-0.9.12/tests/tcp_proxy/main.c xrdp-0.9.15/tests/tcp_proxy/main.c --- xrdp-0.9.12/tests/tcp_proxy/main.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/tests/tcp_proxy/main.c 2020-12-28 13:47:15.000000000 +0000 @@ -37,8 +37,6 @@ static int g_terminated = 0; static char g_buf[1024 * 32]; -#define -#define typedef unsigned short tui16; diff -Nru xrdp-0.9.12/vnc/Makefile.in xrdp-0.9.15/vnc/Makefile.in --- xrdp-0.9.12/vnc/Makefile.in 2019-12-28 12:36:38.000000000 +0000 +++ xrdp-0.9.15/vnc/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/vnc/vnc.c xrdp-0.9.15/vnc/vnc.c --- xrdp-0.9.12/vnc/vnc.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/vnc/vnc.c 2020-12-28 14:03:43.000000000 +0000 @@ -16,6 +16,14 @@ * limitations under the License. * * libvnc + * + * The message definitions used in this source file can be found mostly + * in RFC6143 - "The Remote Framebuffer Protocol". + * + * The ExtendedDesktopSize encoding is reserved in RFC6143, but not + * documented there. It is documented by the RFB protocol community + * wiki currently held at https://github.com/rfbproto/rfbroto. This is + * referred to below as the "RFB community wiki" */ #if defined(HAVE_CONFIG_H) @@ -26,21 +34,78 @@ #include "log.h" #include "trans.h" #include "ssl_calls.h" +#include "string_calls.h" +#include "xrdp_client_info.h" #define LLOG_LEVEL 1 #define LLOGLN(_level, _args) \ - do \ - { \ - if (_level < LLOG_LEVEL) \ + do \ { \ - g_write("xrdp:vnc [%10.10u]: ", g_time3()); \ - g_writeln _args ; \ + if (_level < LLOG_LEVEL) \ + { \ + g_write("xrdp:vnc [%10.10u]: ", g_time3()); \ + g_writeln _args ; \ + } \ } \ - } \ - while (0) + while (0) #define AS_LOG_MESSAGE log_message +/* Client-to-server messages */ +enum c2s +{ + C2S_SET_PIXEL_FORMAT = 0, + C2S_SET_ENCODINGS = 2, + C2S_FRAMEBUFFER_UPDATE_REQUEST = 3, + C2S_KEY_EVENT = 4, + C2S_POINTER_EVENT = 5, + C2S_CLIENT_CUT_TEXT = 6, +}; + +/* Server to client messages */ +enum s2c +{ + S2C_FRAMEBUFFER_UPDATE = 0, + S2C_SET_COLOUR_MAP_ENTRIES = 1, + S2C_BELL = 2, + S2C_SERVER_CUT_TEXT = 3 +}; + +/* Encodings and pseudo-encodings + * + * The RFC uses a signed type for these. We use an unsigned type as the + * binary representation for the negative values is standardised in C + * (which it wouldn't be for an enum value) + */ + +typedef uint32_t encoding_type; + +#define ENC_RAW (encoding_type)0 +#define ENC_COPY_RECT (encoding_type)1 +#define ENC_CURSOR (encoding_type)-239 +#define ENC_DESKTOP_SIZE (encoding_type)-223 +#define ENC_EXTENDED_DESKTOP_SIZE (encoding_type)-308 + +/* Messages for ExtendedDesktopSize status code */ +static const char *eds_status_msg[] = +{ + /* 0 */ "No error", + /* 1 */ "Resize is administratively prohibited", + /* 2 */ "Out of resources", + /* 3 */ "Invalid screen layout", + /* others */ "Unknown code" +}; + +/* elements in above list */ +#define EDS_STATUS_MSG_COUNT \ + (sizeof(eds_status_msg) / sizeof(eds_status_msg[0])) + +/* Used by enabled_encodings_mask */ +enum +{ + MSK_EXTENDED_DESKTOP_SIZE = (1 << 0) +}; + static int lib_mod_process_message(struct vnc *v, struct stream *s); @@ -223,7 +288,7 @@ make_stream(out_s); // Send the RFB message type (CLIENT_CUT_TEXT) to the vnc server. init_stream(out_s, clip_bytes + 1 + 3 + 4 + 16); - out_uint8(out_s, 6); // RFB msg type: CLIENT_CUT_TEXT + out_uint8(out_s, C2S_CLIENT_CUT_TEXT); out_uint8s(out_s, 3); // padding // Send the length of the cut-text to the vnc server. out_uint32_be(out_s, clip_bytes); @@ -255,7 +320,365 @@ return 0; } -/******************************************************************************/ +/**************************************************************************//** + * Logs a debug message containing a screen layout + * + * @param lvl Level to log at + * @param source Where the layout came from + * @param layout Layout to log + */ +static void +log_screen_layout(const enum logLevels lvl, const char *source, + const struct vnc_screen_layout *layout) +{ + unsigned int i; + char text[256]; + size_t pos; + int res; + + pos = 0; + res = g_snprintf(text, sizeof(text) - pos, + "Layout from %s (geom=%dx%d #screens=%u) :", + source, layout->total_width, layout->total_height, + layout->count); + + i = 0; + while (res > 0 && (size_t)res < sizeof(text) - pos && i < layout->count) + { + pos += res; + res = g_snprintf(&text[pos], sizeof(text) - pos, + " %d:(%dx%d+%d+%d)", + layout->s[i].id, + layout->s[i].width, layout->s[i].height, + layout->s[i].x, layout->s[i].y); + ++i; + } + log_message(lvl, "%s", text); +} + +/**************************************************************************//** + * Compares two vnc_screen structures + * + * @param a First structure + * @param b Second structure + * + * @return Suitable for sorting structures with ID as the primary key + */ +static int cmp_vnc_screen(const struct vnc_screen *a, + const struct vnc_screen *b) +{ + int result = 0; + if (a->id != b->id) + { + result = a->id - b->id; + } + else if (a->x != b->x) + { + result = a->x - b->x; + } + else if (a->y != b->y) + { + result = a->y - b->y; + } + else if (a->width != b->width) + { + result = a->width - b->width; + } + else if (a->height != b->height) + { + result = a->height - b->height; + } + + return result; +} + +/**************************************************************************//** + * Compares two vnc_screen_layout structures for equality + * @param a First layout + * @param b First layout + * @return != 0 if structures are equal + */ +static int vnc_screen_layouts_equal(const struct vnc_screen_layout *a, + const struct vnc_screen_layout *b) +{ + unsigned int i; + int result = (a->total_width == b->total_width && + a->total_height == b->total_height && + a->count == b->count); + if (result) + { + for (i = 0 ; result && i < a->count ; ++i) + { + result = (cmp_vnc_screen(&a->s[i], &b->s[i]) == 0); + } + } + + return result; +} + +/**************************************************************************//** + * Reads an extended desktop size rectangle from the VNC server + * + * @param v VNC object + * @param [out] layout Desired layout for server + * @return != 0 for error + * + * @pre The next octet read from v->trans is the number of screens + * @pre layout is not already allocated + * + * @post if call is successful, layout->s must be freed after use. + * @post Returned structure is in increasing ID order + * @post layout->total_width is untouched + * @post layout->total_height is untouched + */ +static int +read_extended_desktop_size_rect(struct vnc *v, + struct vnc_screen_layout *layout) +{ + struct stream *s; + int error; + unsigned int count; + struct vnc_screen *screens; + + layout->count = 0; + layout->s = NULL; + + make_stream(s); + init_stream(s, 8192); + + /* Read in the current screen config */ + error = trans_force_read_s(v->trans, s, 4); + if (error == 0) + { + /* Get the number of screens */ + in_uint8(s, count); + in_uint8s(s, 3); + + error = trans_force_read_s(v->trans, s, 16 * count); + if (error == 0) + { + screens = g_new(struct vnc_screen, count); + if (screens == NULL) + { + log_message(LOG_LEVEL_ERROR, + "VNC : Can't alloc for %d screens", count); + error = 1; + } + else + { + unsigned int i; + for (i = 0 ; i < count ; ++i) + { + in_uint32_be(s, screens[i].id); + in_uint16_be(s, screens[i].x); + in_uint16_be(s, screens[i].y); + in_uint16_be(s, screens[i].width); + in_uint16_be(s, screens[i].height); + in_uint32_be(s, screens[i].flags); + } + + /* sort monitors in increasing ID order */ + qsort(screens, count, sizeof(screens[0]), + (int (*)(const void *, const void *))cmp_vnc_screen); + } + } + } + + free_stream(s); + + if (error == 0) + { + layout->count = count; + layout->s = screens; + } + + return error; +} + +/**************************************************************************//** + * Sends a SetDesktopSize message + * + * @param v VNC object + * @param layout Desired layout for server + * @return != 0 for error + * + * The SetDesktopSize message is documented in the RFB community wiki + * "SetDesktopSize" section. + */ +static int +send_set_desktop_size(struct vnc *v, const struct vnc_screen_layout *layout) +{ + unsigned int i; + struct stream *s; + int error; + + make_stream(s); + init_stream(s, 8192); + out_uint8(s, 251); + out_uint8(s, 0); + out_uint16_be(s, layout->total_width); + out_uint16_be(s, layout->total_height); + + out_uint8(s, layout->count); + out_uint8(s, 0); + for (i = 0 ; i < layout->count ; ++i) + { + out_uint32_be(s, layout->s[i].id); + out_uint16_be(s, layout->s[i].x); + out_uint16_be(s, layout->s[i].y); + out_uint16_be(s, layout->s[i].width); + out_uint16_be(s, layout->s[i].height); + out_uint32_be(s, layout->s[i].flags); + } + s_mark_end(s); + log_message(LOG_LEVEL_DEBUG, "VNC Sending SetDesktopSize"); + error = lib_send_copy(v, s); + free_stream(s); + + return error; +} + +/**************************************************************************//** + * Sets up a single-screen vnc_screen_layout structure + * + * @param layout Structure to set up + * @param width New client width + * @param height New client height + * + * @pre layout->count must be valid + * @pre layout->s must be valid + */ +static void +set_single_screen_layout(struct vnc_screen_layout *layout, + int width, int height) +{ + int id = 0; + int flags = 0; + + layout->total_width = width; + layout->total_height = height; + + if (layout->count == 0) + { + /* No previous layout */ + layout->s = g_new(struct vnc_screen, 1); + } + else + { + /* Keep the ID and flags from the previous first screen */ + id = layout->s[0].id; + flags = layout->s[0].flags; + + if (layout->count > 1) + { + g_free(layout->s); + layout->s = g_new(struct vnc_screen, 1); + } + } + layout->count = 1; + layout->s[0].id = id; + layout->s[0].x = 0; + layout->s[0].y = 0; + layout->s[0].width = width; + layout->s[0].height = height; + layout->s[0].flags = flags; +} + +/**************************************************************************//** + * Resize the client as a single screen + * + * @param v VNC object + * @param update_in_progress True if there's a painter update in progress + * @param width New client width + * @param height New client height + * @return != 0 for error + * + * The new client layout is recorded in v->client_layout. If the client was + * multi-screen before this call, it won't be afterwards. + */ +static int +resize_client(struct vnc *v, int update_in_progress, int width, int height) +{ + int error = 0; + + if (v->client_layout.count != 1 || + v->client_layout.total_width != width || + v->client_layout.total_height != height) + { + if (update_in_progress) + { + error = v->server_end_update(v); + } + + if (error == 0) + { + error = v->server_reset(v, width, height, v->server_bpp); + if (error == 0) + { + set_single_screen_layout(&v->client_layout, width, height); + if (update_in_progress) + { + error = v->server_begin_update(v); + } + } + } + } + + return error; +} + + +/**************************************************************************//** + * Resize the attached client from a layout + * + * @param v VNC object + * @param update_in_progress True if there's a painter update in progress + * @param layout Desired layout from server + * @return != 0 for error + * + * This has some limitations. We have no way to move multiple screens about + * on a connected client, and so we are not able to change the client unless + * we're changing to a single screeen layout. + */ +static int +resize_client_from_layout(struct vnc *v, + int update_in_progress, + const struct vnc_screen_layout *layout) +{ + int error = 0; + + if (!vnc_screen_layouts_equal(&v->client_layout, layout)) + { + /* + * we don't have the capability to resize to anything other + * than a single screen. + */ + if (layout->count != 1) + { + log_message(LOG_LEVEL_ERROR, + "VNC Resize to %d screen(s) from %d screen(s) " + "not implemented", + v->client_layout.count, layout->count); + + /* Dump some useful info, in case we get here when we don't + * need to */ + log_screen_layout(LOG_LEVEL_ERROR, "OldLayout", &v->client_layout); + log_screen_layout(LOG_LEVEL_ERROR, "NewLayout", layout); + error = 1; + } + else + { + error = resize_client(v, + update_in_progress, + layout->total_width, + layout->total_height); + } + } + + return error; +} + +/*****************************************************************************/ int lib_mod_event(struct vnc *v, int msg, long param1, long param2, long param3, long param4) @@ -309,7 +732,7 @@ { /* fix for mstsc sending left control down with altgr */ init_stream(s, 8192); - out_uint8(s, 4); + out_uint8(s, C2S_KEY_EVENT); out_uint8(s, 0); /* down flag */ out_uint8s(s, 2); out_uint32_be(s, 65507); /* left control */ @@ -319,7 +742,7 @@ } init_stream(s, 8192); - out_uint8(s, 4); + out_uint8(s, C2S_KEY_EVENT); out_uint8(s, msg == 15); /* down flag */ out_uint8s(s, 2); out_uint32_be(s, key); @@ -371,7 +794,7 @@ } init_stream(s, 8192); - out_uint8(s, 5); + out_uint8(s, C2S_POINTER_EVENT); out_uint8(s, v->mod_mouse_state); out_uint16_be(s, param1); out_uint16_be(s, param2); @@ -382,10 +805,9 @@ { if (v->suppress_output == 0) { - /* FramebufferUpdateRequest */ init_stream(s, 8192); - out_uint8(s, 3); - out_uint8(s, 0); + out_uint8(s, C2S_FRAMEBUFFER_UPDATE_REQUEST); + out_uint8(s, 0); /* incremental == 0 : Full contents */ x = (param1 >> 16) & 0xffff; out_uint16_be(s, x); y = param1 & 0xffff; @@ -586,6 +1008,463 @@ return 0; } +/** + * Converts a bits-per-pixel value to bytes-per-pixel + */ +static int +get_bytes_per_pixel(int bpp) +{ + int result = (bpp + 7) / 8; + + if (result == 3) + { + result = 4; + } + + return result; +} + + +/**************************************************************************//** + * Skips the specified number of bytes from the transport + * + * @param transport Transport to read + * @param bytes Bytes to skip + * @return != 0 for error + */ +static int +skip_trans_bytes(struct trans *trans, int bytes) +{ + struct stream *s; + int error; + + make_stream(s); + init_stream(s, bytes); + error = trans_force_read_s(trans, s, bytes); + free_stream(s); + + return error; +} + +/**************************************************************************//** + * Reads an encoding from the input stream and discards it + * + * @param v VNC object + * @param x Encoding X value + * @param y Encoding Y value + * @param cx Encoding CX value + * @param cy Encoding CY value + * @param encoding Code for encoding + * @return != 0 for error + * + * @pre On entry the input stream is positioned after the encoding header + */ +static int +skip_encoding(struct vnc *v, int x, int y, int cx, int cy, + encoding_type encoding) +{ + char text[256]; + int error = 0; + + switch (encoding) + { + case ENC_RAW: + { + int need_size = cx * cy * get_bytes_per_pixel(v->server_bpp); + log_message(LOG_LEVEL_DEBUG, "Skipping ENC_RAW encoding"); + error = skip_trans_bytes(v->trans, need_size); + } + break; + + case ENC_COPY_RECT: + { + log_message(LOG_LEVEL_DEBUG, "Skipping ENC_COPY_RECT encoding"); + error = skip_trans_bytes(v->trans, 4); + } + break; + + case ENC_CURSOR: + { + int j = cx * cy * get_bytes_per_pixel(v->server_bpp); + int k = ((cx + 7) / 8) * cy; + + log_message(LOG_LEVEL_DEBUG, "Skipping ENC_CURSOR encoding"); + error = skip_trans_bytes(v->trans, j + k); + } + break; + + case ENC_DESKTOP_SIZE: + log_message(LOG_LEVEL_DEBUG, "Skipping ENC_DESKTOP_SIZE encoding"); + break; + + case ENC_EXTENDED_DESKTOP_SIZE: + { + struct vnc_screen_layout layout = {0}; + log_message(LOG_LEVEL_DEBUG, + "Skipping ENC_EXTENDED_DESKTOP_SIZE encoding " + "x=%d, y=%d geom=%dx%d", + x, y, cx, cy); + error = read_extended_desktop_size_rect(v, &layout); + g_free(layout.s); + } + break; + + default: + g_sprintf(text, "VNC error in skip_encoding " + "encoding = %8.8x", encoding); + v->server_msg(v, text, 1); + } + + return error; +} + +/**************************************************************************//** + * Parses an entire framebuffer update message from the wire, and returns the + * first matching ExtendedDesktopSize encoding if found. + * + * Caller can check for a match by examining match_layout.s after the call + * + * @param v VNC object + * @param match Function to call to check for a match + * @param [out] match_x Matching x parameter for an encoding (if needed) + * @param [out] match_y Matching y parameter for an encoding (if needed) + * @param [out] match_layout Returned layout for the encoding + * @return != 0 for error + * + * @post After a successful call, match_layout.s must be free'd + */ +static int +find_matching_extended_rect(struct vnc *v, + int (*match)(int x, int y, int cx, int cy), + int *match_x, + int *match_y, + struct vnc_screen_layout *match_layout) +{ + int error; + struct stream *s; + unsigned int num_rects; + unsigned int i; + int x; + int y; + int cx; + int cy; + encoding_type encoding; + + match_layout->s = NULL; + + make_stream(s); + init_stream(s, 8192); + error = trans_force_read_s(v->trans, s, 3); + + if (error == 0) + { + in_uint8s(s, 1); + in_uint16_be(s, num_rects); + + for (i = 0; i < num_rects; ++i) + { + if (error != 0) + { + break; + } + + init_stream(s, 8192); + error = trans_force_read_s(v->trans, s, 12); + + if (error == 0) + { + in_uint16_be(s, x); + in_uint16_be(s, y); + in_uint16_be(s, cx); + in_uint16_be(s, cy); + in_uint32_be(s, encoding); + + if (encoding == ENC_EXTENDED_DESKTOP_SIZE && + match_layout->s == NULL && + match(x, y, cx, cy)) + { + log_message(LOG_LEVEL_DEBUG, + "VNC matched ExtendedDesktopSize rectangle " + "x=%d, y=%d geom=%dx%d", + x, y, cx, cy); + + error = read_extended_desktop_size_rect(v, match_layout); + if (match_x) + { + *match_x = x; + } + if (match_y) + { + *match_y = y; + } + match_layout->total_width = cx; + match_layout->total_height = cy; + } + else + { + error = skip_encoding(v, x, y, cx, cy, encoding); + } + } + } + } + + return error; +} + +/**************************************************************************//** + * Sends a FramebufferUpdateRequest for the resize status state machine + * + * The state machine is used at the start of the connection to negotiate + * a common geometry between the client and the server. + * + * The RFB community wiki contains the following paragraph not present + * in RFC6143:- + * + * Note that an empty area can still solicit a FramebufferUpdate + * even though that update will only contain pseudo-encodings + * + * This doesn't seem to be as widely supported as we would like at + * present. We will always request at least a single pixel update to + * avoid confusing the server. + * + * @param v VNC object + * @return != 0 for error + */ +static int +send_update_request_for_resize_status(struct vnc *v) +{ + int error = 0; + struct stream *s; + make_stream(s); + init_stream(s, 8192); + + switch (v->initial_resize_status) + { + case VRS_WAITING_FOR_FIRST_UPDATE: + /* + * Ask for an immediate, minimal update. + */ + out_uint8(s, C2S_FRAMEBUFFER_UPDATE_REQUEST); + out_uint8(s, 0); /* incremental == 0 : Full update */ + out_uint16_be(s, 0); + out_uint16_be(s, 0); + out_uint16_be(s, 1); + out_uint16_be(s, 1); + s_mark_end(s); + error = lib_send_copy(v, s); + break; + + case VRS_WAITING_FOR_RESIZE_CONFIRM: + /* + * Ask for a deferred minimal update. + */ + out_uint8(s, C2S_FRAMEBUFFER_UPDATE_REQUEST); + out_uint8(s, 1); /* incremental == 1 : Changes only */ + out_uint16_be(s, 0); + out_uint16_be(s, 0); + out_uint16_be(s, 1); + out_uint16_be(s, 1); + s_mark_end(s); + error = lib_send_copy(v, s); + break; + + default: + /* + * Ask for a full update from the server + */ + if (v->suppress_output == 0) + { + out_uint8(s, C2S_FRAMEBUFFER_UPDATE_REQUEST); + out_uint8(s, 0); /* incremental == 0 : Full update */ + out_uint16_be(s, 0); + out_uint16_be(s, 0); + out_uint16_be(s, v->server_width); + out_uint16_be(s, v->server_height); + s_mark_end(s); + error = lib_send_copy(v, s); + } + break; + } + + free_stream(s); + + return error; +} + +/**************************************************************************//** + * Tests if extended desktop size rect is an initial geometry specification + * + * This should be x == 0, but the specification says to treat undefined + * values as 0 also */ +static int +rect_is_initial_geometry(int x, int y, int cx, int cy) +{ + return (x != 1 && x != 2); +} + +/**************************************************************************//** + * Tests if extended desktop size rect is a reply to a request from us + */ +static int +rect_is_reply_to_us(int x, int y, int cx, int cy) +{ + return (x == 1); +} + +/**************************************************************************//** + * Returns an error string for an ExtendedDesktopSize status code + */ +static const char * +get_eds_status_msg(unsigned int response_code) +{ + if (response_code >= EDS_STATUS_MSG_COUNT) + { + response_code = EDS_STATUS_MSG_COUNT - 1; + } + + return eds_status_msg[response_code]; +} + +/**************************************************************************//** + * Handles the first framebuffer update from the server + * + * This is used to determine if the server supports resizes from + * us. See The RFB community wiki for details. + * + * If the server does support resizing, we send our client geometry over. + * + * @param v VNC object + * @return != 0 for error + */ +static int +lib_framebuffer_first_update(struct vnc *v) +{ + int error; + struct vnc_screen_layout layout = {0}; + + error = find_matching_extended_rect(v, + rect_is_initial_geometry, + NULL, + NULL, + &layout); + if (error == 0) + { + if (layout.s != NULL) + { + log_message(LOG_LEVEL_DEBUG, "VNC server supports resizing"); + + /* Force the client geometry over to the server */ + log_screen_layout(LOG_LEVEL_INFO, "OldLayout", &layout); + + /* + * If we've only got one screen, and the other side has + * only got one screen, we will preserve their screen ID + * and any flags. This may prevent us sending an unwanted + * SetDesktopSize message if the screen dimensions are + * a match. We can't do this with more than one screen, + * as we have no way to map different IDs + */ + if (layout.count == 1 && v->client_layout.count == 1) + { + log_message(LOG_LEVEL_DEBUG, "VNC " + "setting screen id to %d from server", + layout.s[0].id); + + v->client_layout.s[0].id = layout.s[0].id; + v->client_layout.s[0].flags = layout.s[0].flags; + } + + if (vnc_screen_layouts_equal(&layout, &v->client_layout)) + { + log_message(LOG_LEVEL_DEBUG, "Server layout is the same " + "as the client layout"); + v->initial_resize_status = VRS_DONE; + } + else + { + log_message(LOG_LEVEL_DEBUG, "Server layout differs from " + "the client layout. Changing server layout"); + error = send_set_desktop_size(v, &v->client_layout); + v->initial_resize_status = VRS_WAITING_FOR_RESIZE_CONFIRM; + } + } + else + { + log_message(LOG_LEVEL_DEBUG, "VNC server does not support resizing"); + + /* Force client to same size as server */ + log_message(LOG_LEVEL_DEBUG, "Resizing client to server %dx%d", + v->server_width, v->server_height); + error = resize_client(v, 0, v->server_width, v->server_height); + v->initial_resize_status = VRS_DONE; + } + + g_free(layout.s); + } + + if (error == 0) + { + error = send_update_request_for_resize_status(v); + } + + return error; +} + +/**************************************************************************//** + * Looks for a resize confirm in a framebuffer update request + * + * If the server supports resizes from us, this is used to find the + * reply to our initial resize request. See The RFB community wiki for details. + * + * @param v VNC object + * @return != 0 for error + */ +static int +lib_framebuffer_waiting_for_resize_confirm(struct vnc *v) +{ + int error; + struct vnc_screen_layout layout = {0}; + int response_code; + + error = find_matching_extended_rect(v, + rect_is_reply_to_us, + NULL, + &response_code, + &layout); + if (error == 0) + { + if (layout.s != NULL) + { + if (response_code == 0) + { + log_message(LOG_LEVEL_DEBUG, "VNC server successfully resized"); + log_screen_layout(LOG_LEVEL_INFO, "NewLayout", &layout); + } + else + { + log_message(LOG_LEVEL_ERROR, + "VNC server resize failed - error code %d [%s]", + response_code, + get_eds_status_msg(response_code)); + /* Force client to same size as server */ + log_message(LOG_LEVEL_DEBUG, "Resizing client to server %dx%d", + v->server_width, v->server_height); + error = resize_client(v, 0, v->server_width, v->server_height); + } + v->initial_resize_status = VRS_DONE; + } + + g_free(layout.s); + } + + if (error == 0) + { + error = send_update_request_for_resize_status(v); + } + + return error; +} + /******************************************************************************/ int lib_framebuffer_update(struct vnc *v) @@ -606,7 +1485,6 @@ int srcx; int srcy; unsigned int encoding; - int Bpp; int pixel; int r; int g; @@ -615,14 +1493,9 @@ int need_size; struct stream *s; struct stream *pixel_s; + struct vnc_screen_layout layout = { 0 }; num_recs = 0; - Bpp = (v->mod_bpp + 7) / 8; - - if (Bpp == 3) - { - Bpp = 4; - } make_stream(pixel_s); @@ -655,9 +1528,9 @@ in_uint16_be(s, cy); in_uint32_be(s, encoding); - if (encoding == 0) /* raw */ + if (encoding == ENC_RAW) { - need_size = cx * cy * Bpp; + need_size = cx * cy * get_bytes_per_pixel(v->server_bpp); init_stream(pixel_s, need_size); error = trans_force_read_s(v->trans, pixel_s, need_size); @@ -666,7 +1539,7 @@ error = v->server_paint_rect(v, x, y, cx, cy, pixel_s->data, cx, cy, 0, 0); } } - else if (encoding == 1) /* copy rect */ + else if (encoding == ENC_COPY_RECT) { init_stream(s, 8192); error = trans_force_read_s(v->trans, s, 4); @@ -678,11 +1551,11 @@ error = v->server_screen_blt(v, x, y, cx, cy, srcx, srcy); } } - else if (encoding == 0xffffff11) /* cursor */ + else if (encoding == ENC_CURSOR) { g_memset(cursor_data, 0, 32 * (32 * 3)); g_memset(cursor_mask, 0, 32 * (32 / 8)); - j = cx * cy * Bpp; + j = cx * cy * get_bytes_per_pixel(v->server_bpp); k = ((cx + 7) / 8) * cy; init_stream(s, j + k); error = trans_force_read_s(v->trans, s, j + k); @@ -701,8 +1574,8 @@ if (pixel) { - pixel = get_pixel_safe(d1, k, 31 - j, cx, cy, v->mod_bpp); - split_color(pixel, &r, &g, &b, v->mod_bpp, v->palette); + pixel = get_pixel_safe(d1, k, 31 - j, cx, cy, v->server_bpp); + split_color(pixel, &r, &g, &b, v->server_bpp, v->palette); pixel = make_color(r, g, b, 24); set_pixel_safe(cursor_data, k, j, 32, 32, 24, pixel); } @@ -723,11 +1596,26 @@ error = v->server_set_cursor(v, x, y, cursor_data, cursor_mask); } } - else if (encoding == 0xffffff21) /* desktop size */ + else if (encoding == ENC_DESKTOP_SIZE) { - v->mod_width = cx; - v->mod_height = cy; - error = v->server_reset(v, cx, cy, v->mod_bpp); + /* Server end has resized */ + v->server_width = cx; + v->server_height = cy; + error = resize_client(v, 1, cx, cy); + } + else if (encoding == ENC_EXTENDED_DESKTOP_SIZE) + { + layout.total_width = cx; + layout.total_height = cy; + error = read_extended_desktop_size_rect(v, &layout); + /* If this is a reply to a request from us, x == 1 */ + if (error == 0 && x != 1) + { + v->server_width = layout.total_width; + v->server_height = layout.total_height; + error = resize_client_from_layout(v, 1, &layout); + } + g_free(layout.s); } else { @@ -747,14 +1635,13 @@ { if (v->suppress_output == 0) { - /* FramebufferUpdateRequest */ init_stream(s, 8192); - out_uint8(s, 3); - out_uint8(s, 1); + out_uint8(s, C2S_FRAMEBUFFER_UPDATE_REQUEST); + out_uint8(s, 1); /* incremental == 1 : Changes only */ out_uint16_be(s, 0); out_uint16_be(s, 0); - out_uint16_be(s, v->mod_width); - out_uint16_be(s, v->mod_height); + out_uint16_be(s, v->server_width); + out_uint16_be(s, v->server_height); s_mark_end(s); error = lib_send_copy(v, s); } @@ -903,19 +1790,31 @@ error = 0; if (error == 0) { - if (type == 0) /* framebuffer update */ + if (type == S2C_FRAMEBUFFER_UPDATE) { - error = lib_framebuffer_update(v); + switch (v->initial_resize_status) + { + case VRS_WAITING_FOR_FIRST_UPDATE: + error = lib_framebuffer_first_update(v); + break; + + case VRS_WAITING_FOR_RESIZE_CONFIRM: + error = lib_framebuffer_waiting_for_resize_confirm(v); + break; + + default: + error = lib_framebuffer_update(v); + } } - else if (type == 1) /* palette */ + else if (type == S2C_SET_COLOUR_MAP_ENTRIES) { error = lib_palette_update(v); } - else if (type == 2) /* bell */ + else if (type == S2C_BELL) { error = lib_bell_trigger(v); } - else if (type == 3) /* clipboard */ + else if (type == S2C_SERVER_CUT_TEXT) /* clipboard */ { log_message(LOG_LEVEL_DEBUG, "VNC got clip data"); error = lib_clip_data(v); @@ -938,8 +1837,6 @@ v->server_set_fgcolor(v, 0); v->server_fill_rect(v, 0, 0, w, h); v->server_end_update(v); - v->server_width = w; - v->server_height = h; v->server_bpp = bpp; return 0; } @@ -1009,7 +1906,6 @@ int error; int i; int check_sec_result; - struct source_info *si; v->server_msg(v, "VNC started connecting", 0); check_sec_result = 1; @@ -1026,7 +1922,7 @@ default: v->server_msg(v, "VNC error - only supporting 8, 15, 16, 24 and 32 " "bpp rdp connections", 0); - return 1; + return 1; } if (g_strcmp(v->ip, "") == 0) @@ -1055,12 +1951,11 @@ v->server_msg(v, text, 0); g_sleep(v->delay_ms); } - + g_sprintf(text, "VNC connecting to %s %s", v->ip, con_port); v->server_msg(v, text, 0); - si = (struct source_info *) (v->si); - v->trans->si = si; + v->trans->si = v->si; v->trans->my_source = XRDP_SOURCE_MOD; error = trans_connect(v->trans, v->ip, con_port, 3000); @@ -1188,8 +2083,9 @@ if (error == 0) { - in_uint16_be(s, v->mod_width); - in_uint16_be(s, v->mod_height); + in_uint16_be(s, v->server_width); + in_uint16_be(s, v->server_height); + init_stream(pixel_format, 8192); v->server_msg(v, "VNC receiving pixel format", 0); error = trans_force_read_s(v->trans, pixel_format, 16); @@ -1201,7 +2097,6 @@ if (error == 0) { - v->mod_bpp = v->server_bpp; init_stream(s, 8192); v->server_msg(v, "VNC receiving name length", 0); error = trans_force_read_s(v->trans, s, 4); /* name len */ @@ -1236,15 +2131,14 @@ /* should be connected */ if (error == 0) { - /* SetPixelFormat */ init_stream(s, 8192); - out_uint8(s, 0); + out_uint8(s, C2S_SET_PIXEL_FORMAT); out_uint8(s, 0); out_uint8(s, 0); out_uint8(s, 0); init_stream(pixel_format, 8192); - if (v->mod_bpp == 8) + if (v->server_bpp == 8) { out_uint8(pixel_format, 8); /* bits per pixel */ out_uint8(pixel_format, 8); /* depth */ @@ -1262,7 +2156,7 @@ out_uint8(pixel_format, 0); /* blue shift */ out_uint8s(pixel_format, 3); /* pad */ } - else if (v->mod_bpp == 15) + else if (v->server_bpp == 15) { out_uint8(pixel_format, 16); /* bits per pixel */ out_uint8(pixel_format, 15); /* depth */ @@ -1280,7 +2174,7 @@ out_uint8(pixel_format, 0); /* blue shift */ out_uint8s(pixel_format, 3); /* pad */ } - else if (v->mod_bpp == 16) + else if (v->server_bpp == 16) { out_uint8(pixel_format, 16); /* bits per pixel */ out_uint8(pixel_format, 16); /* depth */ @@ -1298,7 +2192,7 @@ out_uint8(pixel_format, 0); /* blue shift */ out_uint8s(pixel_format, 3); /* pad */ } - else if (v->mod_bpp == 24 || v->mod_bpp == 32) + else if (v->server_bpp == 24 || v->server_bpp == 32) { out_uint8(pixel_format, 32); /* bits per pixel */ out_uint8(pixel_format, 24); /* depth */ @@ -1325,50 +2219,41 @@ if (error == 0) { - /* SetEncodings */ + encoding_type e[10]; + unsigned int n = 0; + unsigned int i; + + /* These encodings are always supported */ + e[n++] = ENC_RAW; + e[n++] = ENC_COPY_RECT; + e[n++] = ENC_CURSOR; + e[n++] = ENC_DESKTOP_SIZE; + if (v->enabled_encodings_mask & MSK_EXTENDED_DESKTOP_SIZE) + { + e[n++] = ENC_EXTENDED_DESKTOP_SIZE; + } + else + { + log_message(LOG_LEVEL_INFO, + "VNC User disabled EXTENDED_DESKTOP_SIZE"); + } + init_stream(s, 8192); - out_uint8(s, 2); + out_uint8(s, C2S_SET_ENCODINGS); out_uint8(s, 0); - out_uint16_be(s, 4); - out_uint32_be(s, 0); /* raw */ - out_uint32_be(s, 1); /* copy rect */ - out_uint32_be(s, 0xffffff11); /* cursor */ - out_uint32_be(s, 0xffffff21); /* desktop size */ - v->server_msg(v, "VNC sending encodings", 0); - s_mark_end(s); - error = trans_force_write_s(v->trans, s); - } - - if (error == 0) - { - error = v->server_reset(v, v->mod_width, v->mod_height, v->mod_bpp); - } - - if (error == 0) - { - if (v->suppress_output == 0) + out_uint16_be(s, n); /* Number of encodings following */ + for (i = 0 ; i < n; ++i) { - /* FramebufferUpdateRequest */ - init_stream(s, 8192); - out_uint8(s, 3); - out_uint8(s, 0); - out_uint16_be(s, 0); - out_uint16_be(s, 0); - out_uint16_be(s, v->mod_width); - out_uint16_be(s, v->mod_height); - v->server_msg(v, "VNC sending framebuffer update request", 0); - s_mark_end(s); - error = trans_force_write_s(v->trans, s); + out_uint32_be(s, e[i]); } + s_mark_end(s); + error = trans_force_write_s(v->trans, s); } if (error == 0) { - if (v->server_bpp != v->mod_bpp) - { - v->server_msg(v, "VNC error - server bpp and client bpp do not match", 0); - error = 1; - } + v->initial_resize_status = VRS_WAITING_FOR_FIRST_UPDATE; + error = send_update_request_for_resize_status(v); } if (error == 0) @@ -1426,6 +2311,39 @@ return 0; } +/**************************************************************************//** + * Initialises the client layout from the Windows monitor definition. + * + * @param [out] layout Our layout + * @param [in] client_info WM info + */ +static void +init_client_layout(struct vnc_screen_layout *layout, + const struct xrdp_client_info *client_info) +{ + int i; + + layout->total_width = client_info->width; + layout->total_height = client_info->height; + + layout->count = client_info->monitorCount; + layout->s = g_new(struct vnc_screen, layout->count); + + for (i = 0 ; i < client_info->monitorCount ; ++i) + { + /* Use minfo_wm, as this is normalised for a top-left of (0,0) + * as required by RFC6143 */ + layout->s[i].id = i; + layout->s[i].x = client_info->minfo_wm[i].left; + layout->s[i].y = client_info->minfo_wm[i].top; + layout->s[i].width = client_info->minfo_wm[i].right - + client_info->minfo_wm[i].left + 1; + layout->s[i].height = client_info->minfo_wm[i].bottom - + client_info->minfo_wm[i].top + 1; + layout->s[i].flags = 0; + } +} + /******************************************************************************/ int lib_mod_set_param(struct vnc *v, const char *name, const char *value) @@ -1459,6 +2377,31 @@ v->got_guid = 1; g_memcpy(v->guid, value, 16); } + else if (g_strcasecmp(name, "disabled_encodings_mask") == 0) + { + v->enabled_encodings_mask = ~g_atoi(value); + } + else if (g_strcasecmp(name, "client_info") == 0) + { + const struct xrdp_client_info *client_info = + (const struct xrdp_client_info *) value; + + g_free(v->client_layout.s); + + /* Save monitor information from the client */ + if (!client_info->multimon || client_info->monitorCount < 1) + { + set_single_screen_layout(&v->client_layout, + client_info->width, + client_info->height); + } + else + { + init_client_layout(&v->client_layout, client_info); + } + log_screen_layout(LOG_LEVEL_DEBUG, "client_info", &v->client_layout); + } + return 0; } @@ -1504,7 +2447,7 @@ /******************************************************************************/ /* return error */ int -lib_mod_frame_ack(struct vnc* v, int flags, int frame_id) +lib_mod_frame_ack(struct vnc *v, int flags, int frame_id) { return 0; } @@ -1512,7 +2455,7 @@ /******************************************************************************/ /* return error */ int -lib_mod_suppress_output(struct vnc* v, int suppress, +lib_mod_suppress_output(struct vnc *v, int suppress, int left, int top, int right, int bottom) { int error; @@ -1522,15 +2465,14 @@ v->suppress_output = suppress; if (suppress == 0) { - /* FramebufferUpdateRequest */ make_stream(s); init_stream(s, 8192); - out_uint8(s, 3); - out_uint8(s, 0); + out_uint8(s, C2S_FRAMEBUFFER_UPDATE_REQUEST); + out_uint8(s, 0); /* incremental == 0 : Full contents */ out_uint16_be(s, 0); out_uint16_be(s, 0); - out_uint16_be(s, v->mod_width); - out_uint16_be(s, v->mod_height); + out_uint16_be(s, v->server_width); + out_uint16_be(s, v->server_height); s_mark_end(s); error = lib_send_copy(v, s); free_stream(s); @@ -1559,6 +2501,9 @@ v->mod_check_wait_objs = lib_mod_check_wait_objs; v->mod_frame_ack = lib_mod_frame_ack; v->mod_suppress_output = lib_mod_suppress_output; + + /* Member variables */ + v->enabled_encodings_mask = -1; return (tintptr) v; } @@ -1574,6 +2519,7 @@ return 0; } trans_delete(v->trans); + g_free(v->client_layout.s); g_free(v); return 0; } diff -Nru xrdp-0.9.12/vnc/vnc.h xrdp-0.9.15/vnc/vnc.h --- xrdp-0.9.12/vnc/vnc.h 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/vnc/vnc.h 2020-12-28 14:03:43.000000000 +0000 @@ -26,98 +26,131 @@ #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 source_info; + 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; + struct source_info *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; }; diff -Nru xrdp-0.9.12/vrplayer/decoderthread.cpp xrdp-0.9.15/vrplayer/decoderthread.cpp --- xrdp-0.9.12/vrplayer/decoderthread.cpp 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/vrplayer/decoderthread.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,266 +0,0 @@ - - -// not used - - - - - - - - - - - - - - - - - -#include "decoderthread.h" - -/* - * TODO: - * o need to maintain aspect ratio while resizing - * o clicking in the middle of the slider bar should move the slider to the middle - * o need to be able to rewind the move when it is done playing - * o need to be able to load another move and play it w/o restarting player - * o pause button needs to work - * o need images for btns - */ - -DecoderThread::DecoderThread() -{ - channel = NULL; - geometry.setX(0); - geometry.setY(0); - geometry.setWidth(0); - geometry.setHeight(0); - stream_id = 101; - elapsedTime = 0; - la_seekPos = -1; - videoTimer = NULL; - audioTimer = NULL; -} - -void DecoderThread::run() -{ - /* need a media file */ - if (filename.length() == 0) - { - emit on_decoderErrorMsg("No media file", - "Please select a media file to play"); - return; - } -} - -void DecoderThread::startMediaPlay() -{ - MediaPacket *mediaPkt; - int is_video_frame; - int rv; - - /* setup video timer; each time this timer fires, it sends */ - /* one video pkt to the client then resets the callback duration */ - videoTimer = new QTimer; - connect(videoTimer, SIGNAL(timeout()), this, SLOT(videoTimerCallback())); - //videoTimer->start(1500); - - /* setup audio timer; does the same as above, but with audio pkts */ - audioTimer = new QTimer; - connect(audioTimer, SIGNAL(timeout()), this, SLOT(audioTimerCallback())); - //audioTimer->start(500); - - /* setup pktTimer; each time this timer fires, it reads AVPackets */ - /* and puts them into audio/video Queues */ - pktTimer = new QTimer; - connect(pktTimer, SIGNAL(timeout()), this, SLOT(pktTimerCallback())); - - while (1) - { - /* fill the audio/video queues with initial data; thereafter */ - /* data will be filled by pktTimerCallback() */ - if ((audioQueue.count() >= 3000) || (videoQueue.count() >= 3000)) - { - //pktTimer->start(50); - - //videoTimer->start(1500); - //audioTimer->start(500); - - playVideo = new PlayVideo(NULL, &videoQueue, channel, 101); - playVideoThread = new QThread(this); - connect(playVideoThread, SIGNAL(started()), playVideo, SLOT(play())); - playVideo->moveToThread(playVideoThread); - playVideoThread->start(); - - playAudio = new PlayAudio(NULL, &audioQueue, channel, 101); - playAudioThread = new QThread(this); - connect(playAudioThread, SIGNAL(started()), playAudio, SLOT(play())); - playAudio->moveToThread(playAudioThread); - playAudioThread->start(); - - return; - } - - mediaPkt = new MediaPacket; - rv = xrdpvr_get_frame(&mediaPkt->av_pkt, - &is_video_frame, - &mediaPkt->delay_in_us); - if (rv < 0) - { - /* looks like we reached end of file */ - break; - } - - if (is_video_frame) - videoQueue.enqueue(mediaPkt); - else - audioQueue.enqueue(mediaPkt); - - } /* end while (1) */ -} - -void DecoderThread::on_mediaSeek(int value) -{ - mutex.lock(); - la_seekPos = value; - mutex.unlock(); - - qDebug() << "media seek value=" << value; - - /* pktTimer stops at end of media; need to restart it */ - if (!pktTimer->isActive()) - { - updateSlider(); - pktTimer->start(100); - } -} - -void DecoderThread::setFilename(QString filename) -{ - this->filename = filename; -} - -void DecoderThread::stopPlayer() -{ - pktTimer->stop(); - audioQueue.clear(); - videoQueue.clear(); -} - -void DecoderThread::pausePlayer() -{ - pktTimer->stop(); -} - -void DecoderThread::resumePlayer() -{ - pktTimer->start(100); -} - -void DecoderThread::close() -{ -} - -void DecoderThread::audioTimerCallback() -{ - MediaPacket *pkt; - int delayInMs; - - if (audioQueue.isEmpty()) - { - qDebug() << "audioTimerCallback: got empty"; - audioTimer->setInterval(100); - return; - } - - pkt = audioQueue.dequeue(); - delayInMs = (int) ((float) pkt->delay_in_us / 1000.0); - send_audio_pkt(channel, 101, pkt->av_pkt); - delete pkt; - - //qDebug() << "audioTimerCallback: delay :" << delayInMs; - - audioTimer->setInterval(delayInMs); -} - -void DecoderThread::videoTimerCallback() -{ - MediaPacket *pkt; - int delayInMs; - - if (videoQueue.isEmpty()) - { - qDebug() << "videoTimerCallback: GOT EMPTY"; - videoTimer->setInterval(100); - return; - } - - pkt = videoQueue.dequeue(); - delayInMs = (int) 10; // ((float) pkt->delay_in_us / 1000.0); - send_video_pkt(channel, 101, pkt->av_pkt); - delete pkt; - updateSlider(); - //qDebug() << "videoTimerCallback: delay :" << delayInMs; - videoTimer->setInterval(delayInMs); -} - -void DecoderThread::pktTimerCallback() -{ - MediaPacket *mediaPkt; - int is_video_frame; - int rv; - - while (1) - { - qDebug() << "pktTimerCallback: audioCount=" << audioQueue.count() << "videoCount=" << videoQueue.count(); -#if 1 - if ((audioQueue.count() >= 20) || (videoQueue.count() >= 20)) - return; -#else - if (videoQueue.count() >= 60) - return; -#endif - mediaPkt = new MediaPacket; - rv = xrdpvr_get_frame(&mediaPkt->av_pkt, - &is_video_frame, - &mediaPkt->delay_in_us); - if (rv < 0) - { - /* looks like we reached end of file */ - qDebug() << "###### looks like we reached EOF"; - pktTimer->stop(); - // LK_TODO set some flag so audio/video timer also stop when q is empty - return; - } - - if (is_video_frame) - videoQueue.enqueue(mediaPkt); - else - audioQueue.enqueue(mediaPkt); - } -} - -void DecoderThread::updateSlider() -{ - if (elapsedTime == 0) - elapsedTime = av_gettime(); - - /* time elapsed in 1/100th sec units since play started */ - emit on_elapsedtime((av_gettime() - elapsedTime) / 10000); - - mutex.lock(); - if (la_seekPos >= 0) - { - qDebug() << "seeking to" << la_seekPos; - //audioTimer->stop(); - //videoTimer->stop(); - xrdpvr_seek_media(la_seekPos, 0); - elapsedTime = av_gettime() - la_seekPos * 1000000; - //audioTimer->start(10); - //videoTimer->start(10); - la_seekPos = -1; - } - mutex.unlock(); -} diff -Nru xrdp-0.9.12/vrplayer/decoderthread.h xrdp-0.9.15/vrplayer/decoderthread.h --- xrdp-0.9.12/vrplayer/decoderthread.h 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/vrplayer/decoderthread.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,95 +0,0 @@ -#ifndef DECODERTHREAD_H -#define DECODERTHREAD_H - -#ifdef __cplusplus -#define __STDC_CONSTANT_MACROS -#ifdef _STDINT_H -#undef _STDINT_H -#endif -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/* ffmpeg related stuff */ -extern "C" -{ - #include - #include -} - -class DecoderThread : public QObject -{ - Q_OBJECT - -public: - /* public methods */ - DecoderThread(); - - void setFilename(QString filename); - void stopPlayer(); - void pausePlayer(); - void resumePlayer(); - void oneTimeDeinit(); - void close(); - void run(); - void startMediaPlay(); - -public slots: - void on_mediaSeek(int value); - -private: - /* private variables */ - QQueue audioQueue; - QQueue videoQueue; - - QTimer *videoTimer; - QTimer *audioTimer; - QTimer *pktTimer; - QString filename; - void *channel; - int stream_id; - QRect geometry; - int64_t elapsedTime; /* elapsed time in usecs since play started */ - QMutex mutex; - int64_t la_seekPos; /* locked access; must hold mutex */ - - PlayVideo *playVideo; - QThread *playVideoThread; - PlayAudio *playAudio; - QThread *playAudioThread; - - /* private functions */ - int sendMetadataFile(); - int sendAudioFormat(); - int sendVideoFormat(); - int sendGeometry(); - void updateSlider(); - -private slots: - /* private slots */ - void audioTimerCallback(); - void videoTimerCallback(); - void pktTimerCallback(); - -signals: - /* private signals */ - void on_progressUpdate(int percent); - void on_decoderErrorMsg(QString title, QString msg); - void on_mediaDurationInSeconds(int duration); - void on_elapsedtime(int val); /* in hundredth of a sec */ -}; - -#endif // DECODERTHREAD_H diff -Nru xrdp-0.9.12/vrplayer/ourinterface.cpp xrdp-0.9.15/vrplayer/ourinterface.cpp --- xrdp-0.9.12/vrplayer/ourinterface.cpp 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/vrplayer/ourinterface.cpp 2020-12-28 13:47:15.000000000 +0000 @@ -11,6 +11,7 @@ savedGeometry.setHeight(0); stream_id = 101; demuxMedia = 0; + demuxMediaThread = NULL; //elapsedTime = 0; } diff -Nru xrdp-0.9.12/xrdp/funcs.c xrdp-0.9.15/xrdp/funcs.c --- xrdp-0.9.12/xrdp/funcs.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/xrdp/funcs.c 2020-12-28 14:03:43.000000000 +0000 @@ -23,6 +23,7 @@ #endif #include "xrdp.h" +#include "string_calls.h" /*****************************************************************************/ /* returns boolean */ diff -Nru xrdp-0.9.12/xrdp/lang.c xrdp-0.9.15/xrdp/lang.c --- xrdp-0.9.12/xrdp/lang.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/xrdp/lang.c 2020-12-28 14:03:43.000000000 +0000 @@ -24,7 +24,9 @@ #endif #include "xrdp.h" +#include "ms-rdpbcgr.h" #include "log.h" +#include "string_calls.h" /* map for rdp to x11 scancodes code1 is regular scancode, code2 is extended scancode */ diff -Nru xrdp-0.9.12/xrdp/Makefile.in xrdp-0.9.15/xrdp/Makefile.in --- xrdp-0.9.12/xrdp/Makefile.in 2019-12-28 12:36:38.000000000 +0000 +++ xrdp-0.9.15/xrdp/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/xrdp/xrdp_bitmap.c xrdp-0.9.15/xrdp/xrdp_bitmap.c --- xrdp-0.9.12/xrdp/xrdp_bitmap.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/xrdp/xrdp_bitmap.c 2020-12-28 14:03:43.000000000 +0000 @@ -25,8 +25,11 @@ #include #endif +#include + #include "xrdp.h" #include "log.h" +#include "string_calls.h" #define LLOG_LEVEL 1 #define LLOGLN(_level, _args) \ @@ -94,6 +97,30 @@ #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, int type, struct xrdp_wm *wm) @@ -123,14 +150,28 @@ 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 diff -Nru xrdp-0.9.12/xrdp/xrdp.c xrdp-0.9.15/xrdp/xrdp.c --- xrdp-0.9.12/xrdp/xrdp.c 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/xrdp/xrdp.c 2020-12-28 14:03:43.000000000 +0000 @@ -22,9 +22,12 @@ #include #endif +#include + #include "xrdp.h" #include "log.h" #include "xrdp_configure_options.h" +#include "string_calls.h" #if !defined(PACKAGE_VERSION) #define PACKAGE_VERSION "???" @@ -47,13 +50,13 @@ static long (*g_sync_func)(long param1, long param2); /*****************************************************************************/ -void +static void print_version(void) { g_writeln("xrdp %s", PACKAGE_VERSION); g_writeln(" A Remote Desktop Protocol Server."); - g_writeln(" Copyright (C) 2004-2018 Jay Sorg, " - "Neutrino Labs, and all contributors."); + g_writeln(" Copyright (C) 2004-2020 Jay Sorg, " + "Neutrino Labs, and all contributors."); g_writeln(" See https://github.com/neutrinolabs/xrdp for more information."); g_writeln("%s", ""); @@ -67,15 +70,17 @@ } /*****************************************************************************/ -void +static void print_help(void) { g_writeln("Usage: xrdp [options]"); + g_writeln(" -k, --kill shut down xrdp"); g_writeln(" -h, --help show help"); + g_writeln(" -v, --version show version"); g_writeln(" -n, --nodaemon don't fork into background"); - g_writeln(" -k, --kill shut down xrdp"); g_writeln(" -p, --port tcp listen port"); g_writeln(" -f, --fork fork on new connection"); + g_writeln(" -c, --config Specify new path to xrdp.ini"); } /*****************************************************************************/ @@ -137,7 +142,7 @@ } /*****************************************************************************/ -void +static void xrdp_shutdown(int sig) { tbus threadid; @@ -153,7 +158,7 @@ } /*****************************************************************************/ -void +static void xrdp_child(int sig) { int safety; @@ -164,7 +169,7 @@ } /*****************************************************************************/ -void +static void xrdp_hang_up(int sig) { log_message(LOG_LEVEL_INFO, "caught SIGHUP, noop..."); @@ -225,7 +230,7 @@ } /*****************************************************************************/ -void +static void pipe_sig(int sig_num) { /* do nothing */ @@ -258,68 +263,87 @@ /*****************************************************************************/ /** + * @brief looks for a case-insensitive match of a string in a list + * @param candidate String to match + * @param ... NULL-terminated list of strings to compare the candidate with + * @return !=0 if the candidate is found in the list + */ +static int nocase_matches(const char *candidate, ...) +{ + va_list vl; + const char *member; + int result = 0; + + va_start(vl, candidate); + while ((member = va_arg(vl, const char *)) != NULL) + { + if (g_strcasecmp(candidate, member) == 0) + { + result = 1; + break; + } + } + + va_end(vl); + return result; +} + + +/*****************************************************************************/ +/** * * @brief Command line argument parser * @param number of command line arguments * @param pointer array of commandline arguments + * @param [out] Returned startup parameters * @return 0 on success, n on nth argument is unknown * */ -int +static int xrdp_process_params(int argc, char **argv, struct xrdp_startup_params *startup_params) { int index; - char option[128]; - char value[128]; + const char *option; + const char *value; index = 1; while (index < argc) { - g_strncpy(option, argv[index], 127); + option = argv[index]; if (index + 1 < argc) { - g_strncpy(value, argv[index + 1], 127); + value = argv[index + 1]; } else { - value[0] = 0; + value = ""; } - if ((g_strncasecmp(option, "-help", 255)) == 0 || - (g_strncasecmp(option, "--help", 255)) == 0 || - (g_strncasecmp(option, "-h", 255)) == 0) + if (nocase_matches(option, "-help", "--help", "-h", NULL)) { startup_params->help = 1; } - else if ((g_strncasecmp(option, "-kill", 255) == 0) || - (g_strncasecmp(option, "--kill", 255) == 0) || - (g_strncasecmp(option, "-k", 255) == 0)) + else if (nocase_matches(option, "-kill", "--kill", "-k", NULL)) { startup_params->kill = 1; } - else if ((g_strncasecmp(option, "-nodaemon", 255) == 0) || - (g_strncasecmp(option, "--nodaemon", 255) == 0) || - (g_strncasecmp(option, "-n", 255) == 0) || - (g_strncasecmp(option, "-nd", 255) == 0) || - (g_strncasecmp(option, "--nd", 255) == 0) || - (g_strncasecmp(option, "-ns", 255) == 0) || - (g_strncasecmp(option, "--ns", 255) == 0)) + else if (nocase_matches(option, "-nodaemon", "--nodaemon", "-n", + "-nd", "--nd", "-ns", "--ns", NULL)) { startup_params->no_daemon = 1; } - else if ((g_strncasecmp(option, "-v", 255) == 0) || - (g_strncasecmp(option, "--version", 255) == 0)) + else if (nocase_matches(option, "-v", "--version", NULL)) { startup_params->version = 1; } - else if ((g_strncasecmp(option, "-p", 255) == 0) || - (g_strncasecmp(option, "--port", 255) == 0)) + else if (nocase_matches(option, "-p", "--port", NULL)) { index++; - g_strncpy(startup_params->port, value, 127); + g_strncpy(startup_params->port, value, + sizeof(startup_params->port) - 1); if (g_strlen(startup_params->port) < 1) { @@ -332,12 +356,16 @@ startup_params->port); } } - else if ((g_strncasecmp(option, "-f", 255) == 0) || - (g_strncasecmp(option, "--fork", 255) == 0)) + else if (nocase_matches(option, "-f", "--fork", NULL)) { startup_params->fork = 1; g_writeln("--fork parameter found, ini override"); } + else if (nocase_matches(option, "-c", "--config", NULL)) + { + index++; + startup_params->xrdp_ini = value; + } else /* unknown option */ { return index; @@ -351,12 +379,12 @@ /*****************************************************************************/ /* Basic sanity checks before any forking */ -int +static int xrdp_sanity_check(void) { int intval = 1; int host_be; - char key_file[256]; + const char *key_file = XRDP_CFG_PATH "/rsakeys.ini"; /* check compiled endian with actual endian */ host_be = !((int)(*(unsigned char *)(&intval))); @@ -401,7 +429,6 @@ return 1; } - g_snprintf(key_file, 255, "%s/rsakeys.ini", XRDP_CFG_PATH); if (!g_file_exist(key_file)) { g_writeln("File %s is missing, create it using xrdp-keygen", key_file); @@ -417,14 +444,14 @@ { int exit_status = 0; int test; - char cfg_file[256]; enum logReturns error; - struct xrdp_startup_params *startup_params; + struct xrdp_startup_params startup_params = {0}; int pid; int fd; - int no_daemon; + int daemon; char text[256]; - char pid_file[256]; + const char *pid_file = XRDP_PID_PATH "/xrdp.pid"; + int errored_argc; g_init("xrdp"); @@ -435,12 +462,9 @@ DEBUG(("Argument %i - %s", test, argv[test])); } - g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); + startup_params.xrdp_ini = XRDP_CFG_PATH "/xrdp.ini"; - startup_params = (struct xrdp_startup_params *) - g_malloc(sizeof(struct xrdp_startup_params), 1); - - errored_argc = xrdp_process_params(argc, argv, startup_params); + errored_argc = xrdp_process_params(argc, argv, &startup_params); if (errored_argc > 0) { print_version(); @@ -453,10 +477,7 @@ g_exit(1); } - g_snprintf(pid_file, 255, "%s/xrdp.pid", XRDP_PID_PATH); - no_daemon = 0; - - if (startup_params->help) + if (startup_params.help) { print_version(); g_writeln("%s", ""); @@ -466,7 +487,7 @@ g_exit(0); } - if (startup_params->version) + if (startup_params.version) { print_version(); g_deinit(); @@ -480,7 +501,7 @@ g_exit(1); } - if (startup_params->kill) + if (startup_params.kill) { g_writeln("stopping xrdp"); /* read the xrdp.pid file */ @@ -515,22 +536,26 @@ } /* starting logging subsystem */ - error = log_start(cfg_file, "xrdp"); + error = log_start(startup_params.xrdp_ini, "xrdp"); if (error != LOG_STARTUP_OK) { switch (error) { - case LOG_ERROR_MALLOC: - g_writeln("error on malloc. cannot start logging. quitting."); - break; - case LOG_ERROR_FILE_OPEN: - g_writeln("error opening log file [%s]. quitting.", - getLogFile(text, 255)); - break; - default: - g_writeln("log_start error"); - break; + case LOG_ERROR_MALLOC: + g_writeln("error on malloc. cannot start logging. quitting."); + break; + case LOG_ERROR_FILE_OPEN: + g_writeln("error opening log file [%s]. quitting.", + getLogFile(text, 255)); + break; + case LOG_ERROR_NO_CFG: + g_writeln("config file %s unreadable or missing", + startup_params.xrdp_ini); + break; + default: + g_writeln("log_start error"); + break; } g_deinit(); @@ -547,13 +572,10 @@ g_exit(0); } - if (startup_params->no_daemon) - { - no_daemon = 1; - } + daemon = !startup_params.no_daemon; - if (!no_daemon) + if (daemon) { /* make sure containing directory exists */ @@ -580,13 +602,13 @@ g_file_delete(pid_file); } - if (!no_daemon) + if (daemon) { /* if can't listen, exit with failure status */ - if (xrdp_listen_test(startup_params) != 0) + if (xrdp_listen_test(&startup_params) != 0) { log_message(LOG_LEVEL_ERROR, "Failed to start xrdp daemon, " - "possibly address already in use."); + "possibly address already in use."); g_deinit(); /* must exit with failure status, or systemd cannot detect xrdp daemon couldn't start properly */ @@ -675,7 +697,7 @@ g_writeln("error creating g_sync_event"); } - g_listen->startup_params = startup_params; + g_listen->startup_params = &startup_params; exit_status = xrdp_listen_main_loop(g_listen); xrdp_listen_delete(g_listen); tc_mutex_delete(g_sync_mutex); @@ -684,13 +706,12 @@ g_delete_wait_obj(g_sync_event); /* only main process should delete pid file */ - if ((!no_daemon) && (pid == g_getpid())) + if (daemon && (pid == g_getpid())) { /* delete the xrdp.pid file */ g_file_delete(pid_file); } - g_free(startup_params); log_end(); g_deinit(); diff -Nru xrdp-0.9.12/xrdp/xrdp_cache.c xrdp-0.9.15/xrdp/xrdp_cache.c --- xrdp-0.9.12/xrdp/xrdp_cache.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/xrdp/xrdp_cache.c 2020-12-28 13:47:15.000000000 +0000 @@ -231,7 +231,7 @@ } #define COMPARE_WITH_CRC32(_b1, _b2) \ - ((_b1 != 0) && (_b2 != 0) && (_b1->crc32 == _b2->crc32) && \ + ((_b1->crc32 == _b2->crc32) && \ (_b1->bpp == _b2->bpp) && \ (_b1->width == _b2->width) && (_b1->height == _b2->height)) @@ -368,8 +368,8 @@ for (jndex = 0; jndex < ll->count; jndex++) { cache_idx = list16_get_item(ll, jndex); - if (COMPARE_WITH_CRC32 - (self->bitmap_items[cache_id][cache_idx].bitmap, bitmap)) + lbm = self->bitmap_items[cache_id][cache_idx].bitmap; + if ((lbm != NULL) && COMPARE_WITH_CRC32(lbm, bitmap)) { LLOGLN(10, ("found bitmap at %d %d", index, jndex)); found = 1; diff -Nru xrdp-0.9.12/xrdp/xrdp_encoder.c xrdp-0.9.15/xrdp/xrdp_encoder.c --- xrdp-0.9.12/xrdp/xrdp_encoder.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/xrdp/xrdp_encoder.c 2020-12-28 13:47:15.000000000 +0000 @@ -24,6 +24,7 @@ #include "xrdp_encoder.h" #include "xrdp.h" +#include "ms-rdpbcgr.h" #include "thread_calls.h" #include "fifo.h" diff -Nru xrdp-0.9.12/xrdp/xrdp.h xrdp-0.9.15/xrdp/xrdp.h --- xrdp-0.9.12/xrdp/xrdp.h 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/xrdp/xrdp.h 2020-12-28 14:03:43.000000000 +0000 @@ -40,6 +40,8 @@ g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1, long sync_param2); int +xrdp_child_fork(void); +int g_is_term(void); void g_set_term(int in_val); @@ -49,10 +51,6 @@ g_get_sync_event(void); void g_process_waiting_function(void); -void -print_version(void); -void -print_help(void); /* xrdp_cache.c */ struct xrdp_cache* @@ -359,7 +357,7 @@ int xrdp_login_wnd_create(struct xrdp_wm* self); int -load_xrdp_config(struct xrdp_config *config, int bpp); +load_xrdp_config(struct xrdp_config *config, const char *xrdp_ini, int bpp); /* xrdp_bitmap_compress.c */ int @@ -435,8 +433,6 @@ int server_is_term(struct xrdp_mod* mod); int -xrdp_child_fork(void); -int server_set_clip(struct xrdp_mod* mod, int x, int y, int cx, int cy); int server_reset_clip(struct xrdp_mod* mod); diff -Nru xrdp-0.9.12/xrdp/xrdp.ini xrdp-0.9.15/xrdp/xrdp.ini --- xrdp-0.9.12/xrdp/xrdp.ini 2019-12-28 12:36:44.000000000 +0000 +++ xrdp-0.9.15/xrdp/xrdp.ini 2020-12-28 14:06:46.000000000 +0000 @@ -8,6 +8,7 @@ ; ports to listen on, number alone means listen on all interfaces ; 0.0.0.0 or :: if ipv6 is configured ; space between multiple occurrences +; ALL specified interfaces must be UP when xrdp starts, otherwise xrdp will fail to start ; ; Examples: ; port=3389 @@ -58,6 +59,10 @@ ; set TLS cipher suites #tls_ciphers=HIGH +; concats the domain name to the user if set for authentication with the separator +; for example when the server is multi homed with SSSd +#domain_user_separator=@ + ; Section name to use for automatic login if the client sends username ; and password. If empty, the domain name sent by the client is used. ; If empty and no domain name is given, the first suitable section in @@ -76,6 +81,8 @@ use_fastpath=both ; when true, userid/password *must* be passed on cmd line #require_credentials=true +; when true, the userid will be used to try to authenticate +#enable_token_login=true ; You can set the PAM error text in a gateway setup (MAX 256 chars) #pamerrortxt=change your password according to policy at http://url @@ -143,11 +150,19 @@ ls_btn_cancel_height=30 [Logging] +; Note: Log levels can be any of: core, error, warning, info, debug, or trace LogFile=xrdp.log -LogLevel=DEBUG +LogLevel=INFO EnableSyslog=true -SyslogLevel=DEBUG -; LogLevel and SysLogLevel could by any of: core, error, warning, info or debug +#SyslogLevel=INFO +#EnableConsole=false +#ConsoleLevel=INFO +#EnableProcessId=false + +[LoggingPerLogger] +; Note: per logger configuration is only used in XRDP_DEBUG builds of XRDP. +#xrdp.c=INFO +#main()=INFO [Channels] ; Channel names not listed here will be blocked by XRDP. @@ -196,6 +211,10 @@ 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 diff -Nru xrdp-0.9.12/xrdp/xrdp_keyboard.ini xrdp-0.9.15/xrdp/xrdp_keyboard.ini --- xrdp-0.9.12/xrdp/xrdp_keyboard.ini 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/xrdp/xrdp_keyboard.ini 2020-12-28 14:03:43.000000000 +0000 @@ -59,6 +59,7 @@ [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 @@ -70,6 +71,7 @@ rdp_layout_jp=0xe0200411 rdp_layout_jp=0xe0210411 rdp_layout_kr=0x00000412 +rdp_layout_no=0x00000414 rdp_layout_pl=0x00000415 rdp_layout_br=0x00000416 rdp_layout_ru=0x00000419 @@ -85,6 +87,7 @@ [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 @@ -93,6 +96,7 @@ rdp_layout_it=it rdp_layout_jp=jp rdp_layout_kr=kr +rdp_layout_no=no rdp_layout_pl=pl rdp_layout_br=br(abnt2) rdp_layout_ru=ru @@ -122,6 +126,7 @@ [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 diff -Nru xrdp-0.9.12/xrdp/xrdp_listen.c xrdp-0.9.15/xrdp/xrdp_listen.c --- xrdp-0.9.12/xrdp/xrdp_listen.c 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/xrdp/xrdp_listen.c 2020-12-28 14:03:43.000000000 +0000 @@ -24,6 +24,7 @@ #include "xrdp.h" #include "log.h" +#include "string_calls.h" /* 'g_process' is protected by the semaphore 'g_process_sem'. One thread sets g_process and waits for the other to process it */ @@ -164,14 +165,12 @@ char *val; struct list *names; struct list *values; - char cfg_file[256]; struct xrdp_startup_params *startup_params; startup_params = self->startup_params; port_override = startup_params->port[0] != 0; fork_override = startup_params->fork; - g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); - fd = g_file_open(cfg_file); + fd = g_file_open(startup_params->xrdp_ini); if (fd != -1) { names = list_create(); diff -Nru xrdp-0.9.12/xrdp/xrdp_login_wnd.c xrdp-0.9.15/xrdp/xrdp_login_wnd.c --- xrdp-0.9.12/xrdp/xrdp_login_wnd.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/xrdp/xrdp_login_wnd.c 2020-12-28 14:03:43.000000000 +0000 @@ -25,6 +25,7 @@ #include "base64.h" #include "xrdp.h" #include "log.h" +#include "string_calls.h" #define ASK "ask" #define ASK_LEN g_strlen(ASK) @@ -559,8 +560,8 @@ char *q; char *r; char name[256]; - char cfg_file[256]; struct xrdp_mod_data *mod_data; + const char *xrdp_ini = self->session->xrdp_ini; sections = list_create(); sections->auto_free = 1; @@ -568,12 +569,12 @@ section_names->auto_free = 1; section_values = list_create(); section_values->auto_free = 1; - g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); - fd = g_file_open(cfg_file); /* xrdp.ini */ + fd = g_file_open(xrdp_ini); if (fd < 0) { - log_message(LOG_LEVEL_ERROR, "Could not read xrdp ini file %s", cfg_file); + log_message(LOG_LEVEL_ERROR, "Could not read xrdp ini file %s", + xrdp_ini); list_delete(sections); list_delete(section_names); list_delete(section_values); @@ -589,7 +590,8 @@ if ((g_strncasecmp(p, "globals", 255) == 0) || (g_strncasecmp(p, "channels", 255) == 0) - || (g_strncasecmp(p, "Logging", 255) == 0)) + || (g_strncasecmp(p, "Logging", 255) == 0) + || (g_strncasecmp(p, "LoggingPerLogger", 255) == 0)) { } else @@ -829,10 +831,14 @@ /** * Load configuration from xrdp.ini file * + * @param config XRDP configuration to initialise + * @param xrdp_ini Path to xrdp.ini + * @param bpp bits-per-pixel for this connection + * * @return 0 on success, -1 on failure *****************************************************************************/ int -load_xrdp_config(struct xrdp_config *config, int bpp) +load_xrdp_config(struct xrdp_config *config, const char *xrdp_ini, int bpp) { struct xrdp_cfg_globals *globals; @@ -841,7 +847,6 @@ char *n; char *v; - char buf[256]; int fd; int i; @@ -873,11 +878,10 @@ globals->ls_btn_cancel_height = 30; /* open xrdp.ini file */ - g_snprintf(buf, 255, "%s/xrdp.ini", XRDP_CFG_PATH); - if ((fd = g_file_open(buf)) < 0) + if ((fd = g_file_open(xrdp_ini)) < 0) { log_message(LOG_LEVEL_ERROR,"load_config: Could not read " - "xrdp.ini file %s", buf); + "xrdp.ini file %s", xrdp_ini); return -1; } @@ -893,7 +897,7 @@ list_delete(values); g_file_close(fd); log_message(LOG_LEVEL_ERROR,"load_config: Could not read globals " - "section from xrdp.ini file %s", buf); + "section from xrdp.ini file %s", xrdp_ini); return -1; } @@ -1001,6 +1005,11 @@ else if (g_strncmp(n, "allow_multimon", 64) == 0) globals->allow_multimon = g_text2bool(v); + else if (g_strncmp(n, "enable_token_login", 64) == 0) { + log_message(LOG_LEVEL_DEBUG, "Token login detection enabled x"); + globals->enable_token_login = g_text2bool(v); + } + /* login screen values */ else if (g_strncmp(n, "ls_top_window_bg_color", 64) == 0) globals->ls_top_window_bg_color = HCOLOR(bpp, xrdp_wm_htoi(v)); @@ -1109,12 +1118,13 @@ g_writeln("new_cursors: %d", globals->new_cursors); g_writeln("nego_sec_layer: %d", globals->nego_sec_layer); g_writeln("allow_multimon: %d", globals->allow_multimon); + g_writeln("enable_token_login: %d", globals->enable_token_login) g_writeln("ls_top_window_bg_color: %x", globals->ls_top_window_bg_color); g_writeln("ls_width: %d", globals->ls_width); g_writeln("ls_height: %d", globals->ls_height); g_writeln("ls_bg_color: %x", globals->ls_bg_color); - g_writeln("ls_title: %s", globals->ls_title); + g_writeln("ls_title: %s", globals->ls_title); g_writeln("ls_logo_filename: %s", globals->ls_logo_filename); g_writeln("ls_logo_x_pos: %d", globals->ls_logo_x_pos); g_writeln("ls_logo_y_pos: %d", globals->ls_logo_y_pos); diff -Nru xrdp-0.9.12/xrdp/xrdp_mm.c xrdp-0.9.15/xrdp/xrdp_mm.c --- xrdp-0.9.12/xrdp/xrdp_mm.c 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/xrdp/xrdp_mm.c 2020-12-28 14:03:43.000000000 +0000 @@ -23,6 +23,7 @@ #endif #include "xrdp.h" #include "log.h" +#include "string_calls.h" #ifndef USE_NOPAM #if defined(HAVE__PAM_TYPES_H) @@ -161,6 +162,9 @@ /*****************************************************************************/ /* Send login information to sesman */ +/* FIXME : This code duplicates functionality in the sesman tools sesrun.c. + * When SCP is reworked, a common library function should be used */ + static int xrdp_mm_send_login(struct xrdp_mm *self) { @@ -471,7 +475,7 @@ self->mod->server_composite = server_composite; self->mod->server_paint_rects = server_paint_rects; self->mod->server_session_info = server_session_info; - self->mod->si = (tintptr) &(self->wm->session->si); + self->mod->si = &(self->wm->session->si); } } @@ -1553,6 +1557,8 @@ } /*****************************************************************************/ +/* FIXME : This code duplicates functionality in the sesman tools sesrun.c. + * When SCP is reworked, a common library function should be used */ static int xrdp_mm_process_login_response(struct xrdp_mm *self, struct stream *s) { @@ -3261,6 +3267,9 @@ } /*****************************************************************************/ + +/* 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 +3288,11 @@ 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; } diff -Nru xrdp-0.9.12/xrdp/xrdp_painter.c xrdp-0.9.15/xrdp/xrdp_painter.c --- xrdp-0.9.12/xrdp/xrdp_painter.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/xrdp/xrdp_painter.c 2020-12-28 14:03:43.000000000 +0000 @@ -23,6 +23,7 @@ #endif #include "xrdp.h" +#include "string_calls.h" #if defined(XRDP_PAINTER) #include /* libpainter */ diff -Nru xrdp-0.9.12/xrdp/xrdp_process.c xrdp-0.9.15/xrdp/xrdp_process.c --- xrdp-0.9.12/xrdp/xrdp_process.c 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/xrdp/xrdp_process.c 2020-12-28 14:03:43.000000000 +0000 @@ -235,7 +235,8 @@ self->server_trans->trans_data_in = xrdp_process_data_in; self->server_trans->callback_data = self; init_stream(self->server_trans->in_s, 8192 * 4); - self->session = libxrdp_init((tbus)self, self->server_trans); + self->session = libxrdp_init((tbus)self, self->server_trans, + self->lis_layer->startup_params->xrdp_ini); self->server_trans->si = &(self->session->si); self->server_trans->my_source = XRDP_SOURCE_CLIENT; /* this callback function is in xrdp_wm.c */ diff -Nru xrdp-0.9.12/xrdp/xrdp_types.h xrdp-0.9.15/xrdp/xrdp_types.h --- xrdp-0.9.12/xrdp/xrdp_types.h 2019-10-01 11:38:59.000000000 +0000 +++ xrdp-0.9.15/xrdp/xrdp_types.h 2020-12-28 14:03:43.000000000 +0000 @@ -30,6 +30,9 @@ #define MAX_NR_CHANNELS 16 #define MAX_CHANNEL_NAME 16 + +struct source_info; + /* lib */ struct xrdp_mod { @@ -156,7 +159,7 @@ tintptr handle; /* pointer to self as int */ tintptr wm; /* struct xrdp_wm* */ tintptr painter; - tintptr si; + struct source_info *si; }; /* header for bmp file */ @@ -528,6 +531,8 @@ struct xrdp_startup_params { + /* xrdp_ini is not malloc'd and has at least the same lifetime as main() */ + const char *xrdp_ini; char port[1024]; int kill; int no_daemon; @@ -566,6 +571,7 @@ int new_cursors; int nego_sec_layer; int allow_multimon; + int enable_token_login; /* colors */ diff -Nru xrdp-0.9.12/xrdp/xrdp_wm.c xrdp-0.9.15/xrdp/xrdp_wm.c --- xrdp-0.9.12/xrdp/xrdp_wm.c 2019-10-01 11:39:00.000000000 +0000 +++ xrdp-0.9.15/xrdp/xrdp_wm.c 2020-12-28 14:03:43.000000000 +0000 @@ -25,7 +25,9 @@ #include #include #include "xrdp.h" +#include "ms-rdpbcgr.h" #include "log.h" +#include "string_calls.h" #define LLOG_LEVEL 1 #define LLOGLN(_level, _args) \ @@ -395,7 +397,6 @@ char *val; struct list *names; struct list *values; - char cfg_file[256]; if (autorun_name != 0) { @@ -414,8 +415,7 @@ self->background = HCOLOR(self->screen->bpp, 0x000000); /* now load them from the globals in xrdp.ini if defined */ - g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); - fd = g_file_open(cfg_file); + fd = g_file_open(self->session->xrdp_ini); if (fd >= 0) { @@ -506,7 +506,7 @@ } else { - log_message(LOG_LEVEL_ERROR,"xrdp_wm_load_static_colors: Could not read xrdp.ini file %s", cfg_file); + log_message(LOG_LEVEL_ERROR,"xrdp_wm_load_static_colors: Could not read xrdp.ini file %s", self->session->xrdp_ini); } if (self->screen->bpp == 8) @@ -568,20 +568,20 @@ char param[256]; char default_section_name[256]; char section_name[256]; - char cfg_file[256]; char autorun_name[256]; g_writeln("in xrdp_wm_init: "); - load_xrdp_config(self->xrdp_config, self->screen->bpp); + load_xrdp_config(self->xrdp_config, self->session->xrdp_ini, + self->screen->bpp); /* global channels allow */ names = list_create(); names->auto_free = 1; values = list_create(); values->auto_free = 1; - g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); - if (file_by_name_read_section(cfg_file, "Channels", names, values) == 0) + if (file_by_name_read_section(self->session->xrdp_ini, + "Channels", names, values) == 0) { int error; int ii; @@ -648,8 +648,7 @@ * NOTE: this should eventually be accessed from self->xrdp_config */ - g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); - fd = g_file_open(cfg_file); /* xrdp.ini */ + fd = g_file_open(self->session->xrdp_ini); if (fd != -1) { names = list_create(); @@ -666,6 +665,7 @@ q = (char *)list_get_item(names, index); if ((g_strncasecmp("globals", q, 8) != 0) && (g_strncasecmp("Logging", q, 8) != 0) && + (g_strncasecmp("LoggingPerLogger", q, 17) != 0) && (g_strncasecmp("channels", q, 9) != 0)) { g_strncpy(default_section_name, q, 255); @@ -789,7 +789,9 @@ } else { - log_message(LOG_LEVEL_ERROR,"xrdp_wm_init: Could not read xrdp.ini file %s", cfg_file); + log_message(LOG_LEVEL_ERROR, + "xrdp_wm_init: Could not read xrdp.ini file %s", + self->session->xrdp_ini); } } else @@ -912,7 +914,7 @@ 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; @@ -1339,6 +1341,22 @@ self->mm->mod->mod_event(self->mm->mod, WM_BUTTON3UP, x, y, 0, 0); } + if (but == 8 && down) + { + self->mm->mod->mod_event(self->mm->mod, WM_BUTTON8DOWN, x, y, 0, 0); + } + else if (but == 8 && !down) + { + self->mm->mod->mod_event(self->mm->mod, WM_BUTTON8UP, x, y, 0, 0); + } + if (but == 9 && down) + { + self->mm->mod->mod_event(self->mm->mod, WM_BUTTON9DOWN, x, y, 0, 0); + } + else if (but == 9 && !down) + { + self->mm->mod->mod_event(self->mm->mod, WM_BUTTON9UP, x, y, 0, 0); + } /* vertical scroll */ if (but == 4) @@ -1515,6 +1533,12 @@ 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; @@ -1801,22 +1825,22 @@ { if (device_flags & PTRXFLAGS_BUTTON1) { - xrdp_wm_mouse_click(self, x, y, 6, 1); + xrdp_wm_mouse_click(self, x, y, 8, 1); } else if (device_flags & PTRXFLAGS_BUTTON2) { - xrdp_wm_mouse_click(self, x, y, 7, 1); + xrdp_wm_mouse_click(self, x, y, 9, 1); } } else { if (device_flags & PTRXFLAGS_BUTTON1) { - xrdp_wm_mouse_click(self, x, y, 6, 0); + xrdp_wm_mouse_click(self, x, y, 8, 0); } else if (device_flags & PTRXFLAGS_BUTTON2) { - xrdp_wm_mouse_click(self, x, y, 7, 0); + xrdp_wm_mouse_click(self, x, y, 9, 0); } } return 0; diff -Nru xrdp-0.9.12/xrdpapi/Makefile.in xrdp-0.9.15/xrdpapi/Makefile.in --- xrdp-0.9.12/xrdpapi/Makefile.in 2019-12-28 12:36:38.000000000 +0000 +++ xrdp-0.9.15/xrdpapi/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/xrdpvr/Makefile.in xrdp-0.9.15/xrdpvr/Makefile.in --- xrdp-0.9.12/xrdpvr/Makefile.in 2019-12-28 12:36:38.000000000 +0000 +++ xrdp-0.9.15/xrdpvr/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/xrdpvr/xrdpvr.c xrdp-0.9.15/xrdpvr/xrdpvr.c --- xrdp-0.9.12/xrdpvr/xrdpvr.c 2019-10-01 11:39:00.000000000 +0000 +++ xrdp-0.9.15/xrdpvr/xrdpvr.c 2020-12-28 13:47:15.000000000 +0000 @@ -923,11 +923,6 @@ index += bytes_written; bytes_to_send -= bytes_written; - if ((rv == 0) && (bytes_to_send == 0)) - { - return 0; - } - usleep(1000 * 3); } } diff -Nru xrdp-0.9.12/xup/Makefile.in xrdp-0.9.15/xup/Makefile.in --- xrdp-0.9.12/xup/Makefile.in 2019-12-28 12:36:38.000000000 +0000 +++ xrdp-0.9.15/xup/Makefile.in 2020-12-28 14:06:39.000000000 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.1 from Makefile.am. +# Makefile.in generated by automake 1.16.3 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2018 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff -Nru xrdp-0.9.12/xup/xup.c xrdp-0.9.15/xup/xup.c --- xrdp-0.9.12/xup/xup.c 2019-12-28 12:16:25.000000000 +0000 +++ xrdp-0.9.15/xup/xup.c 2020-12-28 14:03:43.000000000 +0000 @@ -25,6 +25,7 @@ #include "xup.h" #include "log.h" #include "trans.h" +#include "string_calls.h" #define LOG_LEVEL 1 #define LLOG(_level, _args) \ @@ -149,7 +150,6 @@ int use_uds; struct stream *s; char con_port[256]; - struct source_info *si; LIB_DEBUG(mod, "in lib_mod_connect"); @@ -203,8 +203,7 @@ } } - si = (struct source_info *) (mod->si); - mod->trans->si = si; + mod->trans->si = mod->si; mod->trans->my_source = XRDP_SOURCE_MOD; while (1) @@ -1546,11 +1545,11 @@ { 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) { diff -Nru xrdp-0.9.12/xup/xup.h xrdp-0.9.15/xup/xup.h --- xrdp-0.9.12/xup/xup.h 2019-10-01 11:39:00.000000000 +0000 +++ xrdp-0.9.15/xup/xup.h 2020-12-28 14:03:43.000000000 +0000 @@ -24,10 +24,13 @@ #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 +struct source_info; + struct mod { int size; /* size of this struct */ @@ -148,14 +151,14 @@ tintptr handle; /* pointer to self as long */ tintptr wm; tintptr painter; - tintptr si; + struct source_info *si; /* mod data */ int width; 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;