Catch up with xrdp devel branch.

Merge remote-tracking branch 'upstream/devel' into remotefx_painter
This commit is contained in:
jwc 2020-12-11 00:07:49 +00:00
commit 8953a3322b
105 changed files with 6458 additions and 3710 deletions

145
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,145 @@
name: build and test
on:
push:
branches-ignore:
- "gh-pages"
tags-ignore:
- "v0.[0-8]**"
pull_request:
branches-ignore:
- "gh-pages"
jobs:
build_and_test:
strategy:
fail-fast: false
matrix:
include:
# Minimal 64-bit arch builds
- CC: gcc
feature_set: min
arch: amd64
os: ubuntu-latest
- CC: g++
feature_set: min
arch: amd64
os: ubuntu-latest
- CC: clang
feature_set: min
arch: amd64
os: ubuntu-latest
# Maximal 64-bit arch builds
- CC: gcc
feature_set: max
arch: amd64
os: ubuntu-latest
DISTCHECK: true
- CC: g++
feature_set: max
arch: amd64
os: ubuntu-latest
DISTCHECK: true
- CC: clang
feature_set: max
arch: amd64
os: ubuntu-latest
DISTCHECK: true
# Maximal debug 64-bit arch builds
- CC: gcc
feature_set: max
arch: amd64
os: ubuntu-latest
name_extra: and DEBUG
CONF_FLAGS_EXTRA: "--enable-xrdpdebug"
# Maximal 32-bit arch builds
- CC: gcc
feature_set: max
arch: i386
os: ubuntu-16.04
name_extra: for 32-bit arch (legacy OS)
- CC: g++
feature_set: max
arch: i386
os: ubuntu-16.04
name_extra: for 32-bit arch (legacy OS)
- CC: clang
feature_set: max
arch: i386
os: ubuntu-16.04
name_extra: for 32-bit arch (legacy OS)
name: ${{ matrix.feature_set }} features with ${{ matrix.CC }} ${{ matrix.name_extra }}
runs-on: ${{ matrix.os }}
env:
CC: ${{ matrix.CC }}
# HACK (2020-11-16): github actions dosen't support YAML anchors/aliases to
# avoid repeating long config values. So instead the config values are defined
# as environment variables using a naming convention with fields that come from
# the job config. These environment variables are then referenced as regualr
# environment variables via the naming convention in the "define env" step to
# define the stardard environment variable used in the rest of the steps.
CONF_FLAGS_amd64_min: "--disable-ipv6 --disable-jpeg --disable-fuse --disable-mp3lame
--disable-fdkaac --disable-opus --disable-rfxcodec --disable-painter
--disable-pixman"
CONF_FLAGS_amd64_max: "--enable-ipv6 --enable-jpeg --enable-fuse --enable-mp3lame
--enable-fdkaac --enable-opus --enable-rfxcodec --enable-painter
--enable-pixman"
CONF_FLAGS_i386_max: "--enable-ipv6 --enable-jpeg --enable-fuse --enable-mp3lame
--enable-fdkaac --enable-opus --enable-rfxcodec --enable-painter
--disable-pixman --host=i686-linux"
PKG_CONFIG_PATH_i386: "/usr/lib/i386-linux-gnu/pkgconfig"
CFLAGS_i386: "-m32"
LDFLAGS_i386: "-m32"
steps:
- name: Define feature and arch dependent environment variables
# Note: any "variable=value" written to the $GITHUB_ENV file will be
# defined as an environment variable for all future steps in this job
# See: https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable
run: |
echo "CONF_FLAGS=$CONF_FLAGS_${{ matrix.arch }}_${{ matrix.feature_set }} ${{ matrix.CONF_FLAGS_EXTRA }}" >> $GITHUB_ENV
echo "PKG_CONFIG_PATH=$PKG_CONFIG_PATH_${{ matrix.arch }}" >> $GITHUB_ENV
echo "CFLAGS=$CFLAGS_${{ matrix.arch }}" >> $GITHUB_ENV
echo "LDFLAGS=$LDFLAGS_${{ matrix.arch }}" >> $GITHUB_ENV
- uses: actions/checkout@v2
- run: sudo scripts/install_xrdp_build_dependencies_with_apt.sh ${{ matrix.feature_set }} ${{ matrix.arch }} --allow-downgrades --allow-remove-essential --allow-change-held-packages
- run: ./bootstrap
- run: ./configure $CONF_FLAGS
- run: make
- if: ${{ matrix.DISTCHECK }}
run: make distcheck
cppcheck:
name: cppcheck
runs-on: ubuntu-latest
env:
CC: gcc
# This is required to use a version of cppcheck other than that
# suplied with the operating system
CPPCHECK_VER: 2.1
CPPCHECK_REPO: https://github.com/danmar/cppcheck.git
steps:
- uses: actions/checkout@v2
- name: Cache cppcheck
uses: actions/cache@v2
env:
cache-name: cache-cppcheck
with:
path: ~/cppcheck.local
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.CPPCHECK_VER }}
- run: sudo scripts/install_cppcheck_dependencies_with_apt.sh
- run: ./bootstrap
- run: scripts/install_cppcheck.sh $CPPCHECK_REPO $CPPCHECK_VER
- run: scripts/run_cppcheck.sh -v $CPPCHECK_VER

View File

@ -1,142 +0,0 @@
sudo: false # use new container
language: c
branches:
except: /^(gh-pages|v0\.[0-8].*)/
addons:
apt:
packages: &common_deps
- nasm
# This is required to use a version of cppcheck other than that
# suplied with the operating system
cppcheck_defs: &cppcheck_defs
- CPPCHECK_VER=1.90
- CPPCHECK_REPO=https://github.com/danmar/cppcheck.git
min_amd64_deps: &min_amd64_deps
- *common_deps
- libpam0g-dev
- libssl-dev
- libx11-dev
- libxrandr-dev
- libxfixes-dev
min_amd64_conf: &min_amd64_conf
env:
- CONF_FLAGS="--disable-ipv6 --disable-jpeg --disable-fuse --disable-mp3lame
--disable-fdkaac --disable-opus --disable-rfxcodec --disable-painter
--disable-pixman"
addons:
apt:
packages:
- *min_amd64_deps
max_amd64_deps: &max_amd64_deps
- *min_amd64_deps
- libfuse-dev
- libjpeg-dev
- libmp3lame-dev
- libfdk-aac-dev
- libopus-dev
- libpixman-1-dev
max_amd64_conf: &max_amd64_conf
env:
- CONF_FLAGS="--enable-ipv6 --enable-jpeg --enable-fuse --enable-mp3lame
--enable-fdkaac --enable-opus --enable-rfxcodec --enable-painter
--enable-pixman"
- DISTCHECK=1
addons:
apt:
packages:
- *max_amd64_deps
max_x86_deps: &max_x86_deps
- *common_deps
- g++-multilib
- gcc-multilib
- libgl1-mesa-dev:i386
- libglu1-mesa-dev:i386
- libjpeg-dev:i386
- libmp3lame-dev:i386
- libfdk-aac-dev:i386
- libopus-dev:i386
- libpam0g-dev:i386
- libssl-dev:i386
- libx11-dev:i386
- libxext-dev:i386
- libxfixes-dev:i386
- libxrandr-dev:i386
- libxrender-dev:i386
- openssl:i386
# No --enable-pixman to allow testing the replacement code
# No --enable-fuse due to failing libfuse-dev:i386 package install
max_x86_conf: &max_x86_conf
env:
- CONF_FLAGS="--enable-ipv6 --enable-jpeg --disable-fuse --enable-mp3lame
--enable-fdkaac --enable-opus --enable-rfxcodec --enable-painter
--disable-pixman --host=i686-linux"
- PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig
- CFLAGS=-m32
- LDFLAGS=-m32
addons:
apt:
packages:
- *max_x86_deps
# For cppcheck, we've got a custom script
cppcheck_conf: &cppcheck_conf
env:
- *cppcheck_defs
# addons:
# apt:
# packages:
# - cppcheck
script:
- ./bootstrap
- scripts/install_cppcheck.sh $CPPCHECK_REPO $CPPCHECK_VER
- scripts/run_cppcheck.sh -v $CPPCHECK_VER
matrix:
include:
# Minimal amd64 build
- compiler: gcc
<< : *min_amd64_conf
- compiler: g++
<< : *min_amd64_conf
- compiler: clang
<< : *min_amd64_conf
# Maximal amd64 build
- compiler: gcc
<< : *max_amd64_conf
- compiler: g++
<< : *max_amd64_conf
- compiler: clang
<< : *max_amd64_conf
# Maximal x86 build
- compiler: gcc
<< : *max_x86_conf
- compiler: g++
<< : *max_x86_conf
- compiler: clang
<< : *max_x86_conf
# cppcheck
- name: cppcheck
compiler: gcc
<< : *cppcheck_conf
script:
- ./bootstrap
- ./configure $CONF_FLAGS
- make CFLAGS="$CFLAGS -O2 -Wall -Wwrite-strings -Werror"
- test -z "$DISTCHECK" || make distcheck

47
NEWS.md
View File

@ -1,3 +1,48 @@
# 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.
@ -111,7 +156,7 @@ Thank you for matt335672 contributing to lots of improvements in drive redirecti
-----------------------
## 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

View File

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

16
SECURITY.md Normal file
View File

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

View File

@ -150,13 +150,6 @@ internal_log_start(struct log_config *l_cfg)
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 +157,20 @@ internal_log_start(struct log_config *l_cfg)
return ret;
}
/* open file */
l_cfg->fd = internal_log_file_open(l_cfg->log_file);
if (-1 == l_cfg->fd)
if (l_cfg->dump_on_start)
{
return LOG_ERROR_FILE_OPEN;
internal_log_config_dump(l_cfg);
}
/* open file */
if (l_cfg->log_file != NULL)
{
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 +266,24 @@ internal_log_text2level(const char *buf)
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 +291,6 @@ internalReadConfiguration(const char *inFilename, const char *applicationName)
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 +298,16 @@ internal_config_read_logging(int file, struct log_config *lc,
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 +343,21 @@ internal_config_read_logging(int file, struct log_config *lc,
{
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 +368,279 @@ internal_config_read_logging(int file, struct log_config *lc,
/* 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;
#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;
}
enum logReturns
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");
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", "<disabled>");
}
if (config->enable_console)
{
internal_log_lvl2str(config->console_level, str_level);
}
else
{
g_strcpy(str_level, "<disabled>");
}
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, "<disabled>");
}
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
}
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)
{
/* Is log initialized? */
if (g_staticLogConfig == NULL)
{
return 0;
}
/* Is there at least one log destination which will accept the message based on the log level? */
return (g_staticLogConfig->fd >= 0
&& (override_destination_level || log_level <= g_staticLogConfig->log_level))
|| (g_staticLogConfig->enable_syslog
&& (override_destination_level || log_level <= g_staticLogConfig->syslog_level))
|| (g_staticLogConfig->enable_console
&& (override_destination_level || log_level <= g_staticLogConfig->console_level));
}
bool_t
internal_log_location_overrides_level(const char *function_name,
const char *file_name,
const enum logLevels log_level)
{
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)))
{
return (log_level <= logger->log_level);
}
}
return 0;
}
/*
* Here below the public functions
*/
struct log_config *
log_config_init_for_console(enum logLevels lvl)
{
struct log_config *config = internalInitAndAllocStruct();
if (config != NULL)
{
config->program_name = "<null>";
config->enable_console = 1;
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_start_from_param(const struct log_config *iniParams)
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 *src_log_config)
{
enum logReturns ret = LOG_GENERAL_ERROR;
@ -426,41 +650,28 @@ log_start_from_param(const struct log_config *iniParams)
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 +689,18 @@ enum logReturns
log_start(const char *iniFile, const char *applicationName)
{
enum logReturns ret = LOG_GENERAL_ERROR;
struct log_config *config;
if (applicationName == NULL)
config = log_config_init_from_config(iniFile, applicationName, "");
if (config != NULL)
{
g_writeln("Programming error your application name cannot be null");
return ret;
}
ret = internalReadConfiguration(iniFile, applicationName);
if (ret == LOG_STARTUP_OK)
{
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 +721,225 @@ log_end(void)
{
enum logReturns ret = LOG_GENERAL_ERROR;
ret = internal_log_end(g_staticLogConfig);
if (g_staticLogConfig != NULL)
{
g_free(g_staticLogConfig);
g_staticLogConfig = NULL;
}
log_config_free(g_staticLogConfig);
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;
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,
log_level);
if (!internal_log_is_enabled_for_level(log_level, override_destination_level))
{
return LOG_STARTUP_OK;
}
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];
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, file_name, line_number);
return LOG_ERROR_NO_CFG;
}
override_destination_level = internal_log_location_overrides_level(
function_name,
file_name,
level);
if (!internal_log_is_enabled_for_level(level, override_destination_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, 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, msg, ap);
va_end(ap);
return rv;
}
enum logReturns
internal_log_message(const enum logLevels lvl,
bool_t override_destination_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 +952,38 @@ log_message(const enum logLevels lvl, const char *msg, ...)
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))
{
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 +1001,39 @@ log_message(const enum logLevels lvl, const char *msg, ...)
#endif
#endif
if (g_staticLogConfig->enable_syslog && (lvl <= g_staticLogConfig->syslog_level))
if (g_staticLogConfig->enable_syslog && (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 <= g_staticLogConfig->console_level))
{
/* log to console */
g_printf("%s", buff);
}
if (override_destination_level || lvl <= g_staticLogConfig->log_level)
{
/* log to application logfile */
#ifdef LOG_ENABLE_THREAD
pthread_mutex_lock(&(g_staticLogConfig->log_lock));
#endif
if (g_staticLogConfig->fd >= 0)
{
#ifdef LOG_ENABLE_THREAD
pthread_mutex_lock(&(g_staticLogConfig->log_lock));
#endif
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;

View File

@ -22,19 +22,21 @@
#include <pthread.h>
#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) */
};
/* startup return values */
@ -49,29 +51,112 @@ enum logReturns
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 developper to
* understand and debug XRDP code.
*
* Note: all log levels are relavant to help a developper 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;
};
@ -121,25 +206,48 @@ internal_log_text2level(const char *buf);
* 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 msg, the logtext.
* @param ...
* @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, bool_t force_log, const char *msg, va_list args);
/**
* @param log_level, the log level
* @param override_destination_level, if true then the destinatino log level is ignored.
* @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);
/**
* @param function_name, the function name (typicaly the __func__ macro)
* @param file_name, the file name (typicaly the __FILE__ macro)
* @param log_level, the 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,
const enum logLevels log_level);
/*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 +260,44 @@ log_start(const char *iniFile, const char *applicationName);
/**
* 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()
*/
struct log_config*
log_config_init_for_console(enum logLevels lvl);
/**
* 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 +307,9 @@ log_end(void);
/**
* 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 ...
@ -174,6 +318,37 @@ log_end(void);
enum logReturns
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

View File

@ -2590,6 +2590,19 @@ g_strcat(char *dest, const char *src)
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 *
@ -2896,6 +2909,12 @@ g_strtrim(char *str, int trim_flags)
text = (wchar_t *)malloc(len * sizeof(wchar_t) + 8);
text1 = (wchar_t *)malloc(len * sizeof(wchar_t) + 8);
if (text == NULL || text1 == NULL)
{
free(text);
free(text1);
return 1;
}
text1_index = 0;
mbstowcs(text, str, len + 1);

View File

@ -124,6 +124,7 @@ 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);

View File

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

View File

@ -720,7 +720,10 @@ ssl_tls_accept(struct ssl_tls *self, long ssl_protocols,
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)

View File

@ -302,7 +302,7 @@ trans_check_wait_objs(struct trans *self)
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 +371,7 @@ trans_check_wait_objs(struct trans *self)
}
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;
@ -633,7 +633,7 @@ trans_write_copy_s(struct trans *self, struct stream *out_s)
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;

View File

@ -50,16 +50,43 @@ typedef int (*trans_can_recv_proc) (struct trans *self, int sck, int millis);
/* 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 @@ struct trans
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*

View File

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

View File

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

View File

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

View File

@ -32,6 +32,10 @@ X11 server settings for supported servers
\fB[Chansrv]\fR
Settings for xrdp-chansrv(8)
.TP
\fB[Chansrv_Logging]\fR
Logging settings for xrdp-chansrv(8)
.TP
\fB[SessionVariables]\fR
Environment variables for the session
@ -81,12 +85,15 @@ relative path to \fI@xrdpconfdir@\fR. If not specified, defaults to
\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 @@ syslog.
.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.
@ -133,18 +154,21 @@ Sets the maximum number of simultaneous sessions. If not set or set to
\fBKillDisconnected\fR=\fI[true|false]\fR
If set to \fB1\fR, \fBtrue\fR or \fByes\fR, every session will be killed
within 60 seconds after the user disconnects.
This setting currently only works with xorgxrdp sessions.
.TP
\fBDisconnectedTimeLimit\fR=\fInumber\fR
Sets the time limit (in seconds) before a disconnected session is killed.
If set to \fI0\fR, automatic killing is disabled.
Sets the time limit for \fBKillDisconnected\fR to a value greater than 60.
Values less than 60 cannot be set. You do not actually have to specify
\fBKillDisconnected\fR if you set this value.
This setting currently only works with xorgxrdp sessions.
.TP
\fBIdleTimeLimit\fR=\fInumber\fR
Sets the time limit (in seconds) before an idle session is disconnected.
Idle means no keyboard inputs and no mouse moves/clicks here.
If set to \fI0\fR, idle sessions will never be disconnected by timeout.
This works only with xorgxrdp session. Moreover, xorgxrdp must be v0.2.9 or later.
This works only with xorgxrdp sessions. Moreover, xorgxrdp must be v0.2.9 or later.
.TP
\fBPolicy\fR=\fI[Default|UBD|UBI|UBC|UBDI|UBDC]\fR

View File

@ -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 @@ Remote Applications Integrated Locally
.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),

View File

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

View File

@ -4,7 +4,16 @@ xrdp\-sesman \- \fBxrdp\fR(8) session manager
.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 @@ It manages user sessions by authenticating the user and starting the appropriate
.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

View File

@ -1,10 +1,10 @@
.TH "xrdp\-sesrun" "8" "@PACKAGE_VERSION@" "xrdp team" ""
.SH "NAME"
xrdp\-sesrun \- \fBsesman\fR(8) session launcher
xrdp\-sesrun \- \fBxrdp-sesman\fR(8) session launcher
.SH "SYNTAX"
.B xrdp\-sesrun
.I server username password width height bpp
.I [ -C /path/to/sesman.ini ] server username password width height bpp code
.SH "DESCRIPTION"
\fBxrdp\-sesrun\fR starts a session using \fBxrdp\-sesman\fR(8).
@ -12,6 +12,10 @@ xrdp\-sesrun \- \fBsesman\fR(8) session launcher
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.
.SH "OPTIONS"
.TP
.I \-\-config
(Optional) Specify a path to a different \fIsesman.ini\fR file.
.TP
.I server
Server on which sesman is running
@ -30,11 +34,16 @@ Screen height
.TP
.I bpp
Session color depth
.TP
.I code
Session type (0 for Xvnc, 10 for X11RDP, 20 for Xorg)
.SH "FILES"
@bindir@/xrdp\-sesman
.br
@bindir@/xrdp\-sesrun
.br
@sysconfdir@/xrdp/sesman.ini
.SH "AUTHORS"
Jay Sorg <jsorg71@users.sourceforge.net>

View File

@ -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 @@ It can also be used as a VNC\->RDP bridge.
.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 @@ Specify TCP port to listen to. This overrides \fIport\fR setting in
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

View File

@ -23,10 +23,6 @@ All options and values (except for file names and paths) are case insensitive, a
.SH "GLOBALS"
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
@ -115,11 +111,26 @@ Specify text passed to PAM when authentication failed. The maximum length is \fB
.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 @@ If set to \fB1\fR, \fBtrue\fR or \fByes\fR this option enables logging to syslog
\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.

View File

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

View File

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

View File

@ -44,7 +44,7 @@
#include <X11/XKBlib.h>
#include <locale.h>
extern int xfree86_to_evdev[137-8];
extern int xfree86_to_evdev[137-8+1];
int main(int argc, char **argv)
{

View File

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

1047
instfiles/km-19360409.ini Normal file

File diff suppressed because it is too large Load Diff

View File

@ -37,13 +37,21 @@
/******************************************************************************/
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);
@ -62,6 +70,7 @@ libxrdp_exit(struct xrdp_session *session)
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;
}

View File

@ -75,6 +75,7 @@ struct xrdp_session
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
@ -85,8 +86,16 @@ struct xrdp_drdynvc_procs
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

View File

@ -463,6 +463,10 @@ xrdp_channel_process_drdynvc(struct xrdp_channel *self,
{
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 +475,19 @@ xrdp_channel_process_drdynvc(struct xrdp_channel *self,
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;

View File

@ -42,28 +42,24 @@
/*****************************************************************************/
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);
DEBUG(("xrdp_ini %s", xrdp_ini));
file_by_name_read_section(xrdp_ini, "globals", items, values);
for (index = 0; index < items->count; index++)
{
@ -144,6 +140,10 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
{
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)
@ -276,7 +276,11 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
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);
@ -350,7 +354,7 @@ xrdp_rdp_create(struct xrdp_session *session, struct trans *trans)
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 */

View File

@ -675,6 +675,7 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
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);
@ -735,9 +736,9 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
}
in_uint16_le(s, len_domain);
if (len_domain > 511)
if (len_domain >= INFO_CLIENT_MAX_CB_LEN)
{
DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_domain > 511"));
DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_domain >= %d", INFO_CLIENT_MAX_CB_LEN));
return 1;
}
@ -757,9 +758,9 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
self->rdp_layer->client_info.rdp_autologin = 0;
}
if (len_user > 511)
if (len_user >= INFO_CLIENT_MAX_CB_LEN)
{
DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_user > 511"));
DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_user >= %d", INFO_CLIENT_MAX_CB_LEN));
return 1;
}
@ -769,9 +770,9 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
}
in_uint16_le(s, len_password);
if (len_password > 511)
if (len_password >= INFO_CLIENT_MAX_CB_LEN)
{
DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_password > 511"));
DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_password >= %d", INFO_CLIENT_MAX_CB_LEN));
return 1;
}
@ -781,9 +782,9 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
}
in_uint16_le(s, len_program);
if (len_program > 511)
if (len_program >= INFO_CLIENT_MAX_CB_LEN)
{
DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_program > 511"));
DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_program >= %d", INFO_CLIENT_MAX_CB_LEN));
return 1;
}
@ -793,9 +794,9 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
}
in_uint16_le(s, len_directory);
if (len_directory > 511)
if (len_directory >= INFO_CLIENT_MAX_CB_LEN)
{
DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_directory > 511"));
DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_directory >= %d", INFO_CLIENT_MAX_CB_LEN));
return 1;
}
@ -808,7 +809,6 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
{
return 1;
}
DEBUG(("username %s", self->rdp_layer->client_info.username));
if (flags & RDP_LOGON_AUTO)
{
@ -818,6 +818,17 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
}
DEBUG(("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)
{
DEBUG(("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
{
if (!s_check_rem(s, len_password + 2))
@ -831,6 +842,14 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
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));
}
DEBUG(("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)
{

View File

@ -26,6 +26,8 @@
#define CURRENT_MOD_VER 3
struct source_info;
struct mod
{
int size; /* size of this struct */
@ -54,7 +56,7 @@ struct mod
char* data, int width, int height, int srcx, int srcy);
int (*server_set_cursor)(struct mod* v, int x, int y, char* data, char* mask);
int (*server_palette)(struct mod* v, int* palette);
int (*server_msg)(struct mod* v, char* msg, int code);
int (*server_msg)(struct mod* v, const char* msg, int code);
int (*server_is_term)(struct mod* v);
int (*server_set_clip)(struct mod* v, int x, int y, int cx, int cy);
int (*server_reset_clip)(struct mod* v);
@ -91,7 +93,7 @@ struct mod
tintptr handle; /* pointer to self as long */
tintptr wm;
tintptr painter;
tintptr si;
struct source_info *si;
/* mod data */
int sck;
int width;

View File

@ -24,6 +24,7 @@
#include "xrdp-neutrinordp.h"
#include "xrdp-color.h"
#include "xrdp_rail.h"
#include "trans.h"
#include "log.h"
#include <freerdp/settings.h>
@ -39,6 +40,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) \
@ -68,6 +72,13 @@ verifyColorMap(struct mod *mod)
LLOGLN(0, ("The colormap is all NULL"));
}
/*****************************************************************************/
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
@ -516,14 +527,26 @@ lxrdp_get_wait_objs(struct mod *mod, tbus *read_objs, int *rcount,
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 +559,32 @@ lxrdp_check_wait_objs(struct mod *mod)
boolean ok;
LLOGLN(12, ("lxrdp_check_wait_objs:"));
ok = freerdp_check_fds(mod->inst);
if (!ok)
/*
* 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)
{
LLOGLN(0, ("lxrdp_check_wait_objs: freerdp_check_fds failed"));
return 1;
/*
* 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;
}
}
return 0;
@ -1394,7 +1437,7 @@ static void
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 +1491,11 @@ lfreerdp_polygon_sc(rdpContext *context, POLYGON_SC_ORDER *polygon_sc)
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"));
}

View File

@ -24,6 +24,7 @@
#include "defines.h"
#include "xrdp_rail.h"
#include "xrdp_client_info.h"
#include "xrdp_constants.h"
/* this is the freerdp main header */
#include <freerdp/freerdp.h>
@ -60,6 +61,8 @@ struct pointer_item
#define CURRENT_MOD_VER 4
struct source_info;
struct mod
{
int size; /* size of this struct */
@ -182,7 +185,7 @@ struct mod
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 @@ struct mod
int vmaj;
int vmin;
int vrev;
char username[256];
char password[256];
char domain[256];
char username[INFO_CLIENT_MAX_CB_LEN];
char password[INFO_CLIENT_MAX_CB_LEN];
char domain[INFO_CLIENT_MAX_CB_LEN];
int bool_keyBoardSynced ; /* Numlock can be out of sync, we hold state here to resolve */
int keyBoardLockInfo ; /* Holds initial numlock capslock state */

View File

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

View File

@ -0,0 +1,6 @@
#!/bin/sh
set -eufx
PACKAGES="libz3-dev z3"
apt-get -yq --no-install-suggests --no-install-recommends install $PACKAGES

View File

@ -0,0 +1,98 @@
#!/bin/sh
set -eufx
FEATURE_SET="$1"
ARCH="$2"
shift
shift
APT_EXTRA_ARGS="$@"
if [ -z "$FEATURE_SET" ]; then
FEATURE_SET=min
fi
if [ -z "$ARCH" ]; then
ARCH=amd64
fi
# common build tools for all architectures and feature sets
PACKAGES=" \
autoconf \
automake \
clang \
gcc \
g++ \
libtool \
make \
nasm \
pkg-config\
"
case "$ARCH"
in
amd64)
PACKAGES_AMD64_MIN=" \
libpam0g-dev \
libssl-dev \
libx11-dev \
libxrandr-dev \
libxfixes-dev"
case "$FEATURE_SET"
in
min)
PACKAGES="$PACKAGES $PACKAGES_AMD64_MIN"
;;
max)
PACKAGES="$PACKAGES \
$PACKAGES_AMD64_MIN
libfuse-dev \
libjpeg-dev \
libmp3lame-dev \
libfdk-aac-dev \
libopus-dev \
libpixman-1-dev"
;;
*)
echo "unsupported feature set: $FEATURE_SET"
exit 1;
;;
esac
;;
i386)
PACKAGES="$PACKAGES \
g++-multilib \
gcc-multilib \
libgl1-mesa-dev:i386 \
libglu1-mesa-dev:i386 \
libjpeg-dev:i386 \
libmp3lame-dev:i386 \
libfdk-aac-dev:i386 \
libopus-dev:i386 \
libpam0g-dev:i386 \
libssl-dev:i386 \
libx11-dev:i386 \
libxext-dev:i386 \
libxfixes-dev:i386 \
libxrandr-dev:i386 \
libxrender-dev:i386 \
openssl:i386 \
libfuse-dev:i386"
dpkg --add-architecture i386
dpkg --print-architecture
dpkg --print-foreign-architectures
apt-get update
;;
*)
echo "unsupported architecture: $ARCH"
exit 1;
;;
esac
apt-get -yq \
--no-install-suggests \
--no-install-recommends \
$APT_EXTRA_ARGS \
install $PACKAGES

View File

@ -41,33 +41,32 @@ access_login_allowed(const char *user)
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 +75,7 @@ access_login_allowed(const char *user)
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 +89,33 @@ access_login_mng_allowed(const char *user)
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 +124,7 @@ access_login_mng_allowed(const char *user)
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;
}

View File

@ -51,6 +51,8 @@ xrdp_chansrv_SOURCES = \
chansrv.h \
chansrv_common.c \
chansrv_common.h \
chansrv_config.c \
chansrv_config.h \
chansrv_fuse.c \
chansrv_fuse.h \
chansrv_xfs.c \
@ -66,7 +68,6 @@ xrdp_chansrv_SOURCES = \
fifo.h \
irp.c \
irp.h \
mlog.h \
rail.c \
rail.h \
smartcard.c \

View File

@ -118,7 +118,7 @@ audin_send_version(int chan_id)
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 @@ audin_send_formats(int chan_id)
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 @@ audin_send_formats(int chan_id)
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 @@ audin_send_open(int chan_id)
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 @@ audin_process_version(int chan_id, struct stream *s)
{
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 @@ audin_process_formats(int chan_id, struct stream *s)
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 @@ audin_process_formats(int chan_id, struct stream *s)
{
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 @@ audin_process_formats(int chan_id, struct stream *s)
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 @@ audin_process_open_reply(int chan_id, struct stream *s)
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 @@ audin_process_open_reply(int chan_id, struct stream *s)
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 @@ audin_process_data(int chan_id, struct stream *s)
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 @@ audin_process_data(int chan_id, struct stream *s)
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 @@ audin_process_msg(int chan_id, struct stream *s)
{
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 @@ audin_process_msg(int chan_id, struct stream *s)
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 @@ audin_process_msg(int chan_id, struct stream *s)
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 @@ audin_open_response(int chan_id, int creation_status)
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 @@ static int
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 @@ audin_data_fragment(int chan_id, char *data, int bytes)
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 @@ audin_data(int chan_id, char *data, int bytes)
{
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 @@ audin_data(int chan_id, char *data, int bytes)
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 @@ audin_init(void)
int
audin_deinit(void)
{
LOG(0, ("audin_deinit:"));
LOG_DEVEL(LOG_LEVEL_INFO, "audin_deinit:");
return 0;
}
@ -486,9 +484,9 @@ int
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 @@ audin_start(void)
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 @@ audin_start(void)
int
audin_stop(void)
{
LOG(0, ("audin_stop:"));
LOG_DEVEL(LOG_LEVEL_INFO, "audin_stop:");
chansrv_drdynvc_close(g_audin_chanid);
return 0;
}

View File

@ -36,6 +36,7 @@
#include "rail.h"
#include "xcommon.h"
#include "chansrv_fuse.h"
#include "chansrv_config.h"
#include "xrdp_sockets.h"
#include "audin.h"
@ -57,17 +58,16 @@ static int g_rail_index = -1;
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;
@ -122,7 +122,7 @@ add_timeout(int msoffset, void (*callback)(void *data), void *data)
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;
@ -149,7 +149,7 @@ get_timeout(int *timeout)
tui32 now;
int ltimeout;
LOG(10, ("get_timeout:"));
LOG_DEVEL(LOG_LEVEL_DEBUG, "get_timeout:");
ltimeout = *timeout;
if (ltimeout < 1)
{
@ -161,7 +161,7 @@ get_timeout(int *timeout)
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;
@ -171,7 +171,7 @@ get_timeout(int *timeout)
}
if (ltimeout > 0)
{
LOG(10, (" ltimeout %d", ltimeout));
LOG_DEVEL(LOG_LEVEL_DEBUG, " ltimeout %d", ltimeout);
if (*timeout < 1)
{
*timeout = ltimeout;
@ -197,7 +197,7 @@ check_timeout(void)
int count;
tui32 now;
LOG(10, ("check_timeout:"));
LOG_DEVEL(LOG_LEVEL_DEBUG, "check_timeout:");
count = 0;
tobj = g_timeout_head;
if (tobj != 0)
@ -237,7 +237,7 @@ check_timeout(void)
}
}
}
LOG(10, (" count %d", count));
LOG_DEVEL(LOG_LEVEL_DEBUG, " count %d", count);
return 0;
}
@ -263,8 +263,8 @@ send_channel_data(int chan_id, const char *data, int size)
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;
@ -308,11 +308,11 @@ send_channel_data(int chan_id, const char *data, int size)
/*****************************************************************************/
/* 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);
@ -349,10 +349,10 @@ process_message_channel_setup(struct stream *s)
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++)
{
@ -361,10 +361,7 @@ process_message_channel_setup(struct stream *s)
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)
@ -390,7 +387,7 @@ process_message_channel_setup(struct stream *s)
}
else
{
LOG(10, ("other %s", ci->name));
LOG_DEVEL(LOG_LEVEL_DEBUG, "other %s", ci->name);
}
g_num_chan_items++;
@ -445,9 +442,8 @@ process_message_channel_data(struct stream *s)
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)
@ -500,7 +496,7 @@ process_message_channel_data(struct stream *s)
}
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);
}
}
@ -518,7 +514,7 @@ process_message_drdynvc_open_response(struct stream *s)
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;
@ -532,7 +528,7 @@ process_message_drdynvc_open_response(struct stream *s)
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)
@ -562,7 +558,7 @@ process_message_drdynvc_close_response(struct stream *s)
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;
@ -575,7 +571,7 @@ process_message_drdynvc_close_response(struct stream *s)
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;
@ -601,7 +597,7 @@ process_message_drdynvc_data_first(struct stream *s)
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;
@ -640,7 +636,7 @@ process_message_drdynvc_data(struct stream *s)
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;
@ -747,7 +743,7 @@ chansrv_drdynvc_data_first(int chan_id, const char *data, int data_bytes,
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)
@ -774,7 +770,7 @@ chansrv_drdynvc_data(int chan_id, const char *data, int data_bytes)
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)
{
@ -798,7 +794,7 @@ chansrv_drdynvc_send_data(int chan_id, const char *data, int data_bytes)
{
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)
@ -874,7 +870,7 @@ process_message(void)
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;
}
@ -909,7 +905,7 @@ my_trans_data_in(struct trans *trans)
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);
@ -1054,7 +1050,7 @@ my_api_trans_data_in(struct trans *trans)
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);
@ -1062,7 +1058,7 @@ my_api_trans_data_in(struct trans *trans)
{
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;
@ -1074,7 +1070,7 @@ my_api_trans_data_in(struct trans *trans)
{
rv = 1;
in_uint32_le(s, channel_name_bytes);
//g_writeln("my_api_trans_data_in: channel_name_bytes %d", channel_name_bytes);
//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;
@ -1083,7 +1079,7 @@ my_api_trans_data_in(struct trans *trans)
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 */
@ -1137,7 +1133,7 @@ my_api_trans_data_in(struct trans *trans)
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;
}
@ -1150,7 +1146,7 @@ my_api_trans_data_in(struct trans *trans)
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)
@ -1161,7 +1157,7 @@ my_api_trans_data_in(struct trans *trans)
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);
@ -1193,7 +1189,7 @@ my_trans_conn_in(struct trans *trans, struct trans *new_trans)
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;
@ -1212,10 +1208,10 @@ my_api_trans_conn_in(struct trans *trans, struct trans *new_trans)
{
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;
@ -1224,7 +1220,7 @@ my_api_trans_conn_in(struct trans *trans, struct trans *new_trans)
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;
@ -1244,7 +1240,7 @@ setup_listen(void)
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;
@ -1262,8 +1258,8 @@ setup_listen(void)
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;
}
@ -1285,8 +1281,8 @@ setup_api_listen(void)
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;
}
@ -1303,11 +1299,11 @@ api_con_trans_list_get_wait_objs_rw(intptr_t *robjs, int *rcount,
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,
@ -1327,11 +1323,11 @@ api_con_trans_list_check_wait_objs(void)
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)
@ -1344,8 +1340,8 @@ api_con_trans_list_check_wait_objs(void)
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)
{
@ -1368,11 +1364,11 @@ api_con_trans_list_remove_all(void)
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);
@ -1395,7 +1391,7 @@ channel_thread_loop(void *in_val)
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();
@ -1417,7 +1413,7 @@ channel_thread_loop(void *in_val)
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();
@ -1429,8 +1425,8 @@ channel_thread_loop(void *in_val)
{
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");
}
}
@ -1438,8 +1434,8 @@ channel_thread_loop(void *in_val)
{
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();
@ -1461,7 +1457,7 @@ channel_thread_loop(void *in_val)
{
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 */
@ -1501,7 +1497,7 @@ channel_thread_loop(void *in_val)
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;
}
@ -1510,7 +1506,7 @@ channel_thread_loop(void *in_val)
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);
}
@ -1518,7 +1514,7 @@ term_signal_handler(int sig)
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);
}
/*****************************************************************************/
@ -1527,14 +1523,14 @@ child_signal_handler(int sig)
{
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();
}
}
@ -1545,7 +1541,7 @@ child_signal_handler(int sig)
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);
}
@ -1554,7 +1550,7 @@ segfault_signal_handler(int sig)
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);
@ -1623,52 +1619,23 @@ get_display_num_from_display(char *display_text)
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;
}
@ -1676,7 +1643,7 @@ read_ini(void)
static int
get_log_path(char *path, int bytes)
{
char* log_path;
char *log_path;
int rv;
rv = 1;
@ -1724,41 +1691,13 @@ get_log_path(char *path, int bytes)
return rv;
}
/*****************************************************************************/
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)
@ -1786,60 +1725,59 @@ main(int argc, char **argv)
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)
{
@ -1857,11 +1795,11 @@ main(int argc, char **argv)
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_ALWAYS, "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 */
@ -1872,16 +1810,16 @@ main(int argc, char **argv)
/* 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);
@ -1899,7 +1837,7 @@ main(int argc, char **argv)
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;
}
@ -1920,15 +1858,14 @@ main(int argc, char **argv)
/* 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;
}

View File

@ -39,19 +39,6 @@ int send_rail_drawing_orders(char* data, int size);
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)

View File

@ -0,0 +1,294 @@
/**
* 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 <config_ac.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "arch.h"
#include "list.h"
#include "log.h"
#include "file.h"
#include "os_calls.h"
#include "chansrv_config.h"
/* Default settings */
#define DEFAULT_USE_UNIX_SOCKET 0
#define DEFAULT_RESTRICT_OUTBOUND_CLIPBOARD 0
#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, "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->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): %d", config->use_unix_socket);
g_writeln("\nSecurity configuration:");
g_writeln(" RestrictOutboundClipboard: %d",
config->restrict_outbound_clipboard);
g_writeln("\nChansrv configuration:");
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);
}
}

View File

@ -0,0 +1,72 @@
/**
* 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 <sys/stat.h>
struct config_chansrv
{
/** Whether to use a UNIX socket for chansrv */
int use_unix_socket;
/** 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 */

File diff suppressed because it is too large Load Diff

View File

@ -27,6 +27,7 @@
#endif
#include "os_calls.h"
#include "log.h"
#include "chansrv_xfs.h"
@ -113,47 +114,6 @@ struct xfs_dir_handle
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
@ -450,7 +410,7 @@ xfs_add_entry(struct xfs_fs *xfs, fuse_ino_t parent_inum,
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;
@ -820,7 +780,7 @@ xfs_get_file_open_count(struct xfs_fs *xfs, fuse_ino_t inum)
/* ------------------------------------------------------------------------ */
void
xfs_delete_redirected_entries_with_device_id(struct xfs_fs *xfs,
tui32 device_id)
tui32 device_id)
{
fuse_ino_t inum;
XFS_INODE_ALL *xino;

File diff suppressed because it is too large Load Diff

View File

@ -41,46 +41,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 +112,7 @@ clipboard_check_file(char *filename)
index++;
}
}
log_debug("[%s] [%s]", filename, lfilename);
LOG_DEVEL(LOG_LEVEL_DEBUG, "[%s] [%s]", filename, lfilename);
g_strcpy(filename, lfilename);
return 0;
}
@ -209,28 +169,28 @@ clipboard_get_file(const char *file, int bytes)
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 +252,9 @@ clipboard_send_data_response_for_file(const char *data, int data_size)
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 +315,18 @@ clipboard_send_file_size(int streamId, int lindex)
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 +352,11 @@ clipboard_request_file_size(int stream_id, int lindex)
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 +394,30 @@ clipboard_send_file_data(int streamId, int lindex,
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 +426,8 @@ clipboard_send_file_data(int streamId, int lindex,
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 +456,13 @@ clipboard_request_file_data(int stream_id, int lindex, int offset,
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 +499,8 @@ clipboard_process_file_request(struct stream *s, int clip_msg_status,
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 +529,14 @@ clipboard_process_file_response(struct stream *s, int clip_msg_status,
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 +547,7 @@ clipboard_process_file_response(struct stream *s, int clip_msg_status,
}
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 +575,14 @@ clipboard_c2s_in_file_info(struct stream *s, struct clip_file_desc *cfd)
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 +599,17 @@ clipboard_c2s_in_files(struct stream *s, char *file_list)
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 +619,15 @@ clipboard_c2s_in_files(struct stream *s, char *file_list)
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;
}

File diff suppressed because it is too large Load Diff

View File

@ -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 @@ fifo_init(FIFO* fp, int num_entries)
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 @@ fifo_init(FIFO* fp, int num_entries)
* @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 @@ fifo_deinit(FIFO* fp)
* @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 @@ fifo_is_empty(FIFO* fp)
*****************************************************************************/
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 @@ fifo_insert(FIFO* fp, void* data)
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 @@ fifo_insert(FIFO* fp, void* data)
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 @@ fifo_insert(FIFO* fp, void* data)
*
* @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 @@ fifo_remove(FIFO* fp)
*
* @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];
}

View File

@ -25,46 +25,11 @@
#include <config_ac.h>
#endif
#include "chansrv.h"
#include "parse.h"
#include "os_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 +38,18 @@ IRP *g_irp_head = NULL;
* @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 +65,7 @@ IRP * devredir_irp_new(void)
irp->prev = irp_last;
}
log_debug("new IRP=%p", irp);
LOG_DEVEL(LOG_LEVEL_DEBUG, "new IRP=%p", irp);
return irp;
}
@ -113,10 +78,10 @@ IRP * devredir_irp_new(void)
* @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 +100,18 @@ IRP * devredir_irp_with_pathname_new(const char *pathname)
* @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 +129,7 @@ IRP * devredir_irp_with_pathnamelen_new(unsigned int pathnamelen)
irp->prev = irp_last;
}
log_debug("new IRP=%p", irp);
LOG_DEVEL(LOG_LEVEL_DEBUG, "new IRP=%p", irp);
return irp;
}
@ -179,9 +144,11 @@ int devredir_irp_delete(IRP *irp)
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 +156,17 @@ int devredir_irp_delete(IRP *irp)
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 +215,18 @@ IRP *devredir_irp_find(tui32 completion_id)
{
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 +234,14 @@ IRP * devredir_irp_find_by_fileid(tui32 FileId)
{
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 +249,21 @@ IRP * devredir_irp_find_by_fileid(tui32 FileId)
* 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 +271,13 @@ void devredir_irp_dump(void)
{
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 ---");
}

View File

@ -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 */

View File

@ -73,7 +73,7 @@ static int g_true = 1;
/*****************************************************************************/
static int
writeln(const char* format, ...)
writeln(const char *format, ...)
{
va_list ap;
char text[256];
@ -86,13 +86,13 @@ writeln(const char* format, ...)
}
#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;

View File

@ -63,9 +63,9 @@ PCSC_API SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 };
#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 @@ PCSC_API SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 };
#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 @@ get_display_num_from_display(const char *display_text)
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 @@ get_message(int *code, char *data, int *bytes)
else
{
LLOGLN(10, ("get_message: lcode %d *code %d",
lcode, *code));
lcode, *code));
}
}
else if (recv_rv == 0)
@ -421,7 +421,7 @@ SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1, LPCVOID pvReserved2,
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 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
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 @@ SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader, DWORD dwShareMode,
*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 @@ SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
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 @@ SCardTransmit(SCARDHANDLE hCard, const SCARD_IO_REQUEST *pioSendPci,
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;
@ -1158,8 +1158,8 @@ PCSC_API LONG
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;
@ -1229,7 +1229,7 @@ SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders,
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++)

View File

@ -65,7 +65,7 @@ int g_rail_up = 0;
/* 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 +185,7 @@ rail_send_key_esc(int window_id)
}
/*****************************************************************************/
static struct rail_window_data*
static struct rail_window_data *
rail_get_window_data(Window window)
{
unsigned int bytes;
@ -193,10 +193,10 @@ rail_get_window_data(Window window)
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 +213,29 @@ rail_get_window_data(Window window)
}
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 +283,7 @@ rail_send_init(void)
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 +337,7 @@ rail_is_another_wm_running(void)
int
rail_init(void)
{
LOG(10, ("chansrv::rail_init:"));
LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_init:");
xcommon_init();
return 0;
@ -369,8 +369,8 @@ rail_startup(void)
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 +382,16 @@ rail_startup(void)
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 +453,7 @@ rail_process_exec(struct stream *s, int size)
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 +461,23 @@ rail_process_exec(struct stream *s, int size)
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 +495,7 @@ rail_win_popdown(void)
unsigned int nchild;
Window r;
Window p;
Window* children;
Window *children;
XWindowAttributes window_attributes;
/*
@ -509,10 +509,10 @@ rail_win_popdown(void)
{
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 +528,7 @@ rail_close_window(int window_id)
{
XEvent ce;
LOG(0, ("chansrv::rail_close_window:"));
LOG_DEVEL(LOG_LEVEL_INFO, "chansrv::rail_close_window:");
rail_win_popdown();
@ -547,12 +547,12 @@ rail_close_window(int window_id)
/*****************************************************************************/
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 +567,21 @@ rail_process_activate(struct stream *s, int size)
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 +606,21 @@ rail_process_activate(struct stream *s, int size)
/* 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 +645,7 @@ rail_restore_windows(void)
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 +674,9 @@ rail_process_system_param(struct stream *s, int size)
{
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 +684,7 @@ rail_process_system_param(struct stream *s, int size)
*/
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 +692,13 @@ rail_process_system_param(struct stream *s, int size)
/*****************************************************************************/
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 +707,7 @@ rail_get_property(Display* display, Window target, Atom type, Atom property,
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 +736,7 @@ rail_win_get_state(Window win)
{
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 +746,7 @@ rail_win_get_state(Window win)
{
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 +759,7 @@ rail_win_set_state(Window win, unsigned long state)
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 +767,7 @@ rail_win_set_state(Window win, unsigned long state)
/* 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 +821,13 @@ rail_win_get_text(Window win, char **data)
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 +844,15 @@ rail_restore_window(int window_id)
{
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 +866,50 @@ rail_process_system_command(struct stream *s, int size)
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 +922,9 @@ rail_process_handshake(struct stream *s, int size)
{
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 +936,12 @@ rail_process_notify_event(struct stream *s, int size)
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 +955,9 @@ rail_process_window_move(struct stream *s, int size)
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 +967,11 @@ rail_process_window_move(struct stream *s, int size)
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 +992,7 @@ rail_process_local_move_size(struct stream *s, int size)
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 +1000,9 @@ rail_process_local_move_size(struct stream *s, int size)
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 +1011,7 @@ rail_process_local_move_size(struct stream *s, int size)
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 +1021,9 @@ rail_process_client_status(struct stream *s, int size)
{
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 +1036,13 @@ rail_process_sys_menu(struct stream *s, int size)
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 +1052,9 @@ rail_process_lang_bar_info(struct stream *s, int size)
{
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 +1062,7 @@ rail_process_lang_bar_info(struct stream *s, int size)
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 +1070,7 @@ rail_process_appid_req(struct stream *s, int size)
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 +1079,7 @@ rail_process_appid_resp(struct stream *s, int size)
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 +1092,7 @@ rail_data_in(struct stream *s, int chan_id, int chan_flags, int length,
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 +1145,7 @@ rail_data_in(struct stream *s, int chan_id, int chan_flags, int length,
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 +1203,12 @@ static const unsigned int g_crc_table[256] =
#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 +1229,14 @@ get_string_crc(const char* text)
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 +1248,7 @@ rail_win_send_text(Window win)
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 +1258,14 @@ rail_win_send_text(Window win)
}
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 +1294,7 @@ rail_destroy_window(Window window_id)
{
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 +1312,9 @@ static int
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 +1340,7 @@ rail_create_window(Window window_id, Window owner_id)
tui32 border;
Window root;
tui32 depth;
char* title_bytes = 0;
char *title_bytes = 0;
int title_size = 0;
XWindowAttributes attributes;
int style;
@ -1349,34 +1353,34 @@ rail_create_window(Window window_id, Window owner_id)
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 +1420,7 @@ rail_create_window(Window window_id, Window owner_id)
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 +1437,7 @@ rail_create_window(Window window_id, Window owner_id)
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 +1492,7 @@ rail_create_window(Window window_id, Window owner_id)
/*****************************************************************************/
/* 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 +1502,21 @@ rail_configure_request_window(XConfigureRequestEvent* config)
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 +1524,7 @@ rail_configure_request_window(XConfigureRequestEvent* config)
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 +1625,17 @@ rail_configure_request_window(XConfigureRequestEvent* config)
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 +1706,15 @@ rail_configure_window(XConfigureEvent *config)
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 +1782,7 @@ rail_configure_window(XConfigureEvent *config)
static int
rail_desktop_resize(XEvent *lxevent)
{
LOG(0, ("rail_desktop_resize:"));
LOG_DEVEL(LOG_LEVEL_INFO, "rail_desktop_resize:");
return 0;
}
@ -1793,9 +1797,9 @@ rail_xevent(void *xevent)
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 +1813,9 @@ rail_xevent(void *xevent)
{
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 +1823,7 @@ rail_xevent(void *xevent)
}
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 +1836,7 @@ rail_xevent(void *xevent)
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 +1854,14 @@ rail_xevent(void *xevent)
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 +1876,13 @@ rail_xevent(void *xevent)
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 +1907,7 @@ rail_xevent(void *xevent)
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 +1915,7 @@ rail_xevent(void *xevent)
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 +1924,10 @@ rail_xevent(void *xevent)
// 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 +1936,11 @@ rail_xevent(void *xevent)
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 +1950,7 @@ rail_xevent(void *xevent)
ConfigureNotify, &lastevent))
{
if (lastevent.xconfigure.event == lastevent.xconfigure.window &&
lxevent->xconfigure.override_redirect == 0)
lxevent->xconfigure.override_redirect == 0)
{
lxevent = &lastevent;
}
@ -1955,32 +1961,32 @@ rail_xevent(void *xevent)
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)
{

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -43,9 +43,9 @@ static HANDLE_AACENCODER g_fdk_aac_encoder = 0;
#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 @@ static int g_server_input_format_index = 0;
/* 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 @@ sound_send_server_output_formats(void)
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 @@ sound_process_output_format(int aindex, int wFormatTag, int nChannels,
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 @@ sound_process_output_format(int aindex, int wFormatTag, int nChannels,
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 @@ sound_process_output_format(int aindex, int wFormatTag, int nChannels,
}
#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 @@ sound_process_output_formats(struct stream *s, int size)
char *data;
if (size < 16)
{
return 1;
}
in_uint8s(s, 14);
in_uint16_le(s, num_formats);
@ -520,12 +522,12 @@ sound_wave_compress_fdk_aac(char *data, int data_bytes, int *format_index)
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 @@ sound_wave_compress_fdk_aac(char *data, int data_bytes, int *format_index)
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 @@ sound_wave_compress_fdk_aac(char *data, int data_bytes, int *format_index)
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 @@ sound_wave_compress_fdk_aac(char *data, int data_bytes, int *format_index)
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 @@ sound_wave_compress_fdk_aac(char *data, int data_bytes, int *format_index)
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 @@ sound_wave_compress_fdk_aac(char *data, int data_bytes, int *format_index)
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 @@ sound_wave_compress_fdk_aac(char *data, int data_bytes, int *format_index)
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 @@ sound_wave_compress_fdk_aac(char *data, int data_bytes, int *format_index)
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 @@ sound_wave_compress_opus(char *data, int data_bytes, int *format_index)
&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 @@ sound_wave_compress_mp3lame(char *data, int data_bytes, int *format_index)
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 @@ sound_wave_compress_mp3lame(char *data, int data_bytes, int *format_index)
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 @@ sound_send_wave_data_chunk(char *data, int data_bytes)
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 @@ sound_send_wave_data_chunk(char *data, int data_bytes)
/* 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 @@ sound_send_wave_data_chunk(char *data, int data_bytes)
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 @@ sound_send_wave_data(char *data, int data_bytes)
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 @@ sound_send_wave_data(char *data, int data_bytes)
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 @@ sound_send_wave_data(char *data, int data_bytes)
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 @@ sound_send_close(void)
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 @@ sound_process_training(struct stream *s, int size)
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 @@ sound_process_wave_confirm(struct stream *s, int size)
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 @@ process_pcm_message(int id, int size, struct stream *s)
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 @@ sound_sndsrvr_sink_data_in(struct trans *trans)
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 @@ sound_sndsrvr_sink_data_in(struct trans *trans)
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 @@ sound_sndsrvr_sink_data_in(struct trans *trans)
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 @@ sound_sndsrvr_sink_conn_in(struct trans *trans, struct trans *new_trans)
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 @@ sound_sndsrvr_source_conn_in(struct trans *trans, struct trans *new_trans)
int
sound_init(void)
{
LOG(0, ("sound_init:"));
LOG_DEVEL(LOG_LEVEL_INFO, "sound_init:");
g_stream_incoming_packet = NULL;
@ -1242,7 +1266,7 @@ sound_init(void)
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 @@ sound_data_in(struct stream *s, int chan_id, int chan_flags, int length,
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 @@ sound_check_wait_objs(void)
{
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 @@ sound_check_wait_objs(void)
{
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 @@ sound_check_wait_objs(void)
{
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 @@ sound_check_wait_objs(void)
{
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 @@ sound_send_server_input_formats(void)
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 @@ sound_process_input_format(int aindex, int wFormatTag, int nChannels,
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 @@ sound_process_input_format(int aindex, int wFormatTag, int nChannels,
#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 @@ sound_process_input_formats(struct stream *s, int size)
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 @@ sound_process_input_formats(struct stream *s, int size)
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 @@ sound_input_start_recording(void)
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 @@ sound_process_input_data(struct stream *s, int bytes)
{
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 @@ sound_sndsrvr_source_data_in(struct trans *trans)
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 @@ sound_sndsrvr_source_data_in(struct trans *trans)
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 @@ sound_sndsrvr_source_data_in(struct trans *trans)
else
{
if (g_bytes_in_stream == 0)
{
g_bytes_in_stream = g_stream_inp->size;
}
i = bytes_req - bytes_read;
@ -1823,7 +1855,9 @@ sound_start_source_listener(void)
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 @@ sound_start_sink_listener(void)
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;
}

View File

@ -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 @@ xcommon_error_handler(Display *dis, XErrorEvent *xer)
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 @@ xcommon_init(void)
{
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 @@ xcommon_init(void)
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 @@ xcommon_init(void)
if (g_x_socket == 0)
{
LOGM((LOG_LEVEL_ERROR, "xcommon_init: XConnectionNumber failed"));
LOG_DEVEL(LOG_LEVEL_ERROR, "xcommon_init: XConnectionNumber failed");
return 1;
}
@ -190,8 +185,8 @@ xcommon_check_wait_objs(void)
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;

View File

@ -34,61 +34,17 @@
#include "sesman.h"
#include "log.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 +161,17 @@ config_read_globals(int file, struct config_sesman *cf, struct list *param_n,
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 +238,17 @@ config_read_security(int file, struct config_security *sc,
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 +334,17 @@ config_read_sessions(int file, struct config_sessions *se, struct list *param_n,
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 +366,17 @@ config_read_rdp_params(int file, struct config_sesman *cs, struct list *param_n,
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 +399,17 @@ config_read_xorg_params(int file, struct config_sesman *cs,
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 +432,7 @@ config_read_vnc_params(int file, struct config_sesman *cs, struct list *param_n,
}
/******************************************************************************/
int
static int
config_read_session_variables(int file, struct config_sesman *cs,
struct list *param_n, struct list *param_v)
{
@ -458,6 +459,67 @@ config_read_session_variables(int file, struct config_sesman *cs,
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(cfg->sesman_ini)) != -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 +530,7 @@ config_dump(struct config_sesman *config)
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 +630,21 @@ config_dump(struct config_sesman *config)
}
}
/******************************************************************************/
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);
}
}

View File

@ -186,6 +186,12 @@ struct config_sessions
*/
struct config_sesman
{
/**
* @var sesman_ini
* @brief File that these parameters are read from
*/
char *sesman_ini;
/**
* @var listen_address
* @brief Listening address
@ -267,100 +273,15 @@ struct config_sesman
/**
*
* @brief Reads sesman configuration
* @param cfg pointer to configuration object to be replaced
* @return 0 on success, 1 on failure
* @param sesman_ini Name of configuration file to read
* @return configuration on success, NULL on failure
*
* @post pass return value to config_free() to prevent memory leaks
*
*/
int
config_read(struct config_sesman* cfg);
struct config_sesman*
config_read(const char *sesman_ini);
/**
*
* @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);
/**
*
* @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
*
*/
int
config_read_security(int file, struct config_security* sc,
struct list* param_n, struct list* param_v);
/**
*
* @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
@ -370,6 +291,12 @@ config_read_session_variables(int file, struct config_sesman *cs,
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);

View File

@ -76,9 +76,9 @@ env_check_password_file(const char *filename, const char *passwd)
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 +151,7 @@ env_set_user(const char *username, char **passwd_file, int display,
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 +172,9 @@ env_set_user(const char *username, char **passwd_file, int display,
{
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 +189,16 @@ env_set_user(const char *username, char **passwd_file, int display,
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 +219,7 @@ env_set_user(const char *username, char **passwd_file, int display,
if (*passwd_file != NULL)
{
LOG_DBG("pass file: %s", *passwd_file);
LOG_DEVEL(LOG_LEVEL_DEBUG, "pass file: %s", *passwd_file);
}
}
@ -229,9 +229,9 @@ env_set_user(const char *username, char **passwd_file, int display,
}
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;

View File

@ -41,7 +41,7 @@ scp_connection_create(int sck)
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;
}

View File

@ -47,7 +47,7 @@ scp_init(void)
scp_lock_init();
log_message(LOG_LEVEL_DEBUG, "libscp initialized");
LOG(LOG_LEVEL_DEBUG, "libscp initialized");
return 0;
}

View File

@ -98,7 +98,7 @@ scp_lock_fork_release(void)
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 @@ scp_lock_fork_critical_section_end(int blocking)
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);

View File

@ -46,7 +46,7 @@ scp_session_create(void)
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 +81,14 @@ scp_session_set_type(struct SCP_SESSION *s, tui8 type)
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 +108,7 @@ scp_session_set_version(struct SCP_SESSION *s, tui32 version)
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 +172,7 @@ scp_session_set_locale(struct SCP_SESSION *s, const char *str)
{
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 +188,7 @@ scp_session_set_username(struct SCP_SESSION *s, const char *str)
{
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 +201,7 @@ scp_session_set_username(struct SCP_SESSION *s, const char *str)
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 +214,7 @@ scp_session_set_password(struct SCP_SESSION *s, const char *str)
{
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 +227,7 @@ scp_session_set_password(struct SCP_SESSION *s, const char *str)
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 +240,7 @@ scp_session_set_domain(struct SCP_SESSION *s, const char *str)
{
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 +253,7 @@ scp_session_set_domain(struct SCP_SESSION *s, const char *str)
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 +266,7 @@ scp_session_set_program(struct SCP_SESSION *s, const char *str)
{
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 +279,7 @@ scp_session_set_program(struct SCP_SESSION *s, const char *str)
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 +292,7 @@ scp_session_set_directory(struct SCP_SESSION *s, const char *str)
{
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 +305,7 @@ scp_session_set_directory(struct SCP_SESSION *s, const char *str)
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 +318,7 @@ scp_session_set_client_ip(struct SCP_SESSION *s, const char *str)
{
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 +331,7 @@ scp_session_set_client_ip(struct SCP_SESSION *s, const char *str)
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 +344,7 @@ scp_session_set_hostname(struct SCP_SESSION *s, const char *str)
{
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 +357,7 @@ scp_session_set_hostname(struct SCP_SESSION *s, const char *str)
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 +370,7 @@ scp_session_set_errstr(struct SCP_SESSION *s, const char *str)
{
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 +383,7 @@ scp_session_set_errstr(struct SCP_SESSION *s, const char *str)
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 +425,7 @@ scp_session_set_guid(struct SCP_SESSION *s, const tui8 *guid)
{
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;
}

View File

@ -39,7 +39,7 @@ scp_tcp_force_recv(int sck, char *data, int len)
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 @@ scp_tcp_force_send(int sck, char *data, int len)
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)

View File

@ -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;

View File

@ -34,19 +34,72 @@
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 +119,25 @@ scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
}
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 +154,13 @@ scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 +168,35 @@ scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 +205,51 @@ scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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;
char buf[STRING16_MAX_LEN + 1];
if (!skipVchk)
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_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__);
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;
}
LOG(LOG_LEVEL_WARNING, "connection aborted: msg size = %d", size);
return SCP_SERVER_STATE_SIZE_ERR;
}
in_uint32_be(c->in_s, size);
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 +259,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,165 +273,193 @@ 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"))
{
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))
/* width + height + bpp */
if (!s_check_rem(c->in_s, 2 + 2 + 2))
{
scp_session_destroy(session);
log_message(LOG_LEVEL_WARNING,
"[v0:%d] connection aborted: unsupported bpp: %d",
__LINE__, (tui8)sz);
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 (sz > 0)
if (!in_string16(c->in_s, buf, "program"))
{
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_program(session, buf);
g_free(buf);
}
}
if (s_check_rem(c->in_s, 2))
{
/* reading directory */
in_uint16_be(c->in_s, sz);
if (sz > 0)
if (!in_string16(c->in_s, buf, "directory"))
{
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_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 +480,11 @@ scp_v0s_allow_connection(struct SCP_CONNECTION *c, SCP_DISPLAY d, const tui8 *gu
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 +501,11 @@ scp_v0s_deny_connection(struct SCP_CONNECTION *c)
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 +524,10 @@ scp_v0s_replyauthentication(struct SCP_CONNECTION *c, unsigned short int value)
/* 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;
}

View File

@ -47,8 +47,8 @@ scp_v1c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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)
{

View File

@ -49,8 +49,8 @@ scp_v1c_mng_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 +96,7 @@ scp_v1c_mng_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 +132,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
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 +143,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
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 +152,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
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 +161,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
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 +170,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
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 +179,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
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 +188,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
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 +205,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
(*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 +213,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
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 +262,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount,
(*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 +373,7 @@ _scp_v1c_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 +381,7 @@ _scp_v1c_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 +392,7 @@ _scp_v1c_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
/* 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 +400,7 @@ _scp_v1c_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 +408,7 @@ _scp_v1c_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 +418,10 @@ _scp_v1c_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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;
}

View File

@ -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(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 +233,44 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SES
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 +278,7 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SES
/* 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 +287,33 @@ enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SES
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)
if (NULL == session)
{
log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (malloc returned NULL)", __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;
}
scp_session_set_version(session, 1);
in_uint8(c->in_s, sz);
if ((sz != SCP_SESSION_TYPE_XVNC) && (sz != SCP_SESSION_TYPE_XRDP))
else
{
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))
{
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))
{
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 +342,7 @@ scp_v1s_deny_connection(struct SCP_CONNECTION *c, const char *reason)
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 +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;
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 +385,14 @@ scp_v1s_request_password(struct SCP_CONNECTION *c, struct SCP_SESSION *s,
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 +400,37 @@ scp_v1s_request_password(struct SCP_CONNECTION *c, struct SCP_SESSION *s,
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, 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 +438,31 @@ scp_v1s_request_password(struct SCP_CONNECTION *c, struct SCP_SESSION *s,
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 +503,7 @@ scp_v1s_connect_new_session(struct SCP_CONNECTION *c, SCP_DISPLAY d)
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 +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;
@ -440,7 +557,7 @@ scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNEC
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 +571,7 @@ scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNEC
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 +579,35 @@ scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNEC
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 +615,7 @@ scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNEC
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 +703,7 @@ scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNEC
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 +713,7 @@ scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNEC
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 +721,36 @@ scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNEC
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 +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(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 +779,7 @@ scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNEC
/* 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 +795,7 @@ scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNEC
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 +832,7 @@ scp_v1s_reconnect_session(struct SCP_CONNECTION *c, SCP_DISPLAY d)
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;
}

View File

@ -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(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 +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)
{
return SCP_SERVER_STATE_INTERNAL_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 (!in_string8(c->in_s, buf, "username", __LINE__))
{
return SCP_SERVER_STATE_SIZE_ERR;
}
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 +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(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 +282,16 @@ scp_v1s_mng_list_sessions(struct SCP_CONNECTION *c, struct SCP_SESSION *s,
/* 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 +369,7 @@ scp_v1s_mng_list_sessions(struct SCP_CONNECTION *c, struct SCP_SESSION *s,
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 +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];
@ -298,7 +390,7 @@ _scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 +398,36 @@ _scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 +435,7 @@ _scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 +445,7 @@ _scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 +460,7 @@ _scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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;
}

View File

@ -43,13 +43,13 @@ scp_process_start(void *sck)
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 @@ scp_process_start(void *sck)
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;
}

View File

@ -54,23 +54,23 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
{
/* 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 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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

View File

@ -55,14 +55,14 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
{
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 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 @@ static void parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f)
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;
}
}

View File

@ -46,14 +46,14 @@ scp_v1_mng_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 @@ scp_v1_mng_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 @@ scp_v1_mng_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
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 @@ static void parseCommonStates(enum SCP_SERVER_STATES_E e, const char *f)
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;
}
}

View File

@ -28,7 +28,19 @@
#include <config_ac.h>
#endif
#include <stdarg.h>
#include "sesman.h"
#include "xrdp_configure_options.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 +49,101 @@ struct config_sesman *g_cfg; /* defined in config.h */
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 +155,8 @@ int sesman_listen_test(struct config_sesman *cfg)
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 +187,7 @@ int sesman_listen_test(struct config_sesman *cfg)
* @brief Starts sesman main loop
*
*/
int
static int
sesman_main_loop(void)
{
int in_sck;
@ -96,7 +201,7 @@ sesman_main_loop(void)
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 +214,8 @@ sesman_main_loop(void)
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 +255,8 @@ sesman_main_loop(void)
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 +266,158 @@ sesman_main_loop(void)
}
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;
}
/******************************************************************************/
void
print_usage(int retcode)
/*****************************************************************************/
static void
print_version(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_deinit();
g_exit(retcode);
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
}
/******************************************************************************/
static void
print_help(void)
{
g_printf("Usage: xrdp-sesman [options]\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();
}
/******************************************************************************/
static int
kill_running_sesman(const char *pid_file)
{
int error;
int fd;
int pid;
char pid_s[32] = {0};
/* 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;
}
fd = g_file_open(pid_file);
if (-1 == fd)
{
g_printf("error opening pid file[%s]: %s\n", pid_file, g_get_strerror());
return 1;
}
error = g_file_read(fd, pid_s, sizeof(pid_s) - 1);
if (-1 == error)
{
g_printf("error reading pid file: %s\n", g_get_strerror());
g_file_close(fd);
g_deinit();
return 1;
}
g_file_close(fd);
pid = g_atoi(pid_s);
error = g_sigterm(pid);
if (0 != error)
{
g_printf("error killing sesman: %s\n", g_get_strerror());
}
else
{
g_file_delete(pid_file);
}
g_deinit();
return error;
}
/******************************************************************************/
int
main(int argc, char **argv)
{
int fd;
enum logReturns log_error;
int error;
int daemon = 1;
int pid;
char pid_s[32];
enum logReturns log_error;
char text[256];
char pid_file[256];
char cfg_file[256];
char default_sesman_ini[256];
struct sesman_startup_params startup_params = {0};
int errored_argc;
int daemon;
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);
if (1 == argc)
startup_params.sesman_ini = default_sesman_ini;
errored_argc = sesman_process_params(argc, argv, &startup_params);
if (errored_argc > 0)
{
/* start in daemon mode if no cli options */
daemon = 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"))))
{
/* starts sesman not daemonized */
g_printf("starting sesman in foreground...\n");
daemon = 0;
}
else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--help")) ||
(0 == g_strcasecmp(argv[1], "-help")) ||
(0 == g_strcasecmp(argv[1], "-h"))))
{
print_usage(0);
}
else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--kill")) ||
(0 == g_strcasecmp(argv[1], "-kill")) ||
(0 == g_strcasecmp(argv[1], "-k"))))
{
/* 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);
}
fd = g_file_open(pid_file);
if (-1 == fd)
{
g_printf("error opening pid file[%s]: %s\n", pid_file, g_get_strerror());
return 1;
}
g_memset(pid_s, 0, sizeof(pid_s));
error = g_file_read(fd, pid_s, 31);
if (-1 == error)
{
g_printf("error reading pid file: %s\n", g_get_strerror());
g_file_close(fd);
g_deinit();
g_exit(error);
}
g_file_close(fd);
pid = g_atoi(pid_s);
error = g_sigterm(pid);
if (0 != error)
{
g_printf("error killing sesman: %s\n", g_get_strerror());
}
else
{
g_file_delete(pid_file);
}
print_version();
g_writeln("%s", "");
print_help();
g_writeln("%s", "");
g_writeln("Unknown option: %s", argv[errored_argc]);
g_deinit();
g_exit(error);
g_exit(1);
}
else
if (startup_params.help)
{
/* there's something strange on the command line */
g_printf("Error: invalid command line arguments\n\n");
print_usage(1);
print_help();
g_exit(0);
}
if (startup_params.version)
{
print_version();
g_exit(0);
}
if (startup_params.kill)
{
g_exit(kill_running_sesman(pid_file));
}
daemon = !startup_params.no_daemon;
if (!daemon)
{
g_printf("starting sesman in foreground...\n");
}
if (g_file_exist(pid_file))
@ -294,33 +431,23 @@ main(int argc, char **argv)
}
/* reading config */
g_cfg = g_new0(struct config_sesman, 1);
if (0 == g_cfg)
if ((g_cfg = config_read(startup_params.sesman_ini)) == NULL)
{
g_printf("error creating config: quitting.\n");
g_printf("error reading config %s: %s\nquitting.\n",
startup_params.sesman_ini, g_get_strerror());
g_deinit();
g_exit(1);
}
//g_cfg->log.fd = -1; /* don't use logging before reading its config */
if (0 != config_read(g_cfg))
{
g_printf("error reading config: %s\nquitting.\n", 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 +465,20 @@ main(int argc, char **argv)
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 +509,16 @@ main(int argc, char **argv)
/* 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 +545,16 @@ main(int argc, char **argv)
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 +565,8 @@ main(int argc, char **argv)
}
/* 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 +576,7 @@ main(int argc, char **argv)
{
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 +600,7 @@ main(int argc, char **argv)
log_end();
}
config_free(g_cfg);
g_deinit();
g_exit(error);
return 0;

View File

@ -55,7 +55,7 @@ IdleTimeLimit=0
;; Policy - session allocation policy
; Type: enum [ "Default" | "UBD" | "UBI" | "UBC" | "UBDI" | "UBDC" ]
; Default: Xrdp:<User,BitPerPixel> and Xvnc:<User,BitPerPixel,DisplaySize>
; "Default" session per <User,BitPerPixel>
; "UBD" session per <User,BitPerPixel,DisplaySize>
; "UBI" session per <User,BitPerPixel,IPAddr>
; "UBC" session per <User,BitPerPixel,Connection>
@ -64,10 +64,19 @@ IdleTimeLimit=0
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 @@ SyslogLevel=DEBUG
[Xorg]
; Specify the path of non-suid Xorg executable. It might differ depending
; on your distribution and version. The typical path is shown as follows:
; on your distribution and version. Find out the appropreate path for your
; environment. The typical path is known as follows:
;
; Fedora 26 or later : param=/usr/libexec/Xorg
; Debian 9 or later : param=/usr/lib/xorg/Xorg
; Ubuntu 16.04 or later : param=/usr/lib/xorg/Xorg
; Arch Linux : param=/usr/lib/Xorg
; 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.
@ -109,5 +120,23 @@ FuseMountName=thinclient_drives
; Make this more permissive (e.g. 022) if required.
FileUmask=077
[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=@sesmansysconfdir@/pulse/default.pa

View File

@ -46,7 +46,6 @@
#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 +70,7 @@ dumpItemsToString(struct list *self, char *outstr, int len)
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++)
@ -117,15 +116,15 @@ session_get_bydata(const char *name, int width, int height, int bpp, int type,
}
#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,
@ -135,14 +134,14 @@ session_get_bydata(const char *name, int width, int height, int bpp, int type,
#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;
}
@ -314,7 +313,7 @@ session_get_avail_display_from_chain(void)
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;
}
@ -334,9 +333,9 @@ wait_for_xserver(int display)
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;
}
@ -371,16 +370,11 @@ session_start_chansrv(char *username, int display)
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);
}
@ -426,8 +420,8 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
/* 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;
}
@ -435,8 +429,8 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
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;
}
@ -445,8 +439,8 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
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;
}
@ -467,8 +461,8 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
}
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);
@ -499,15 +493,15 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
*/
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());
}
}
@ -549,10 +543,21 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
{
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 */
@ -562,51 +567,51 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
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
@ -671,9 +676,9 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
*/
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
@ -697,7 +702,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
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);
@ -742,7 +747,7 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
/* 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)
@ -771,30 +776,30 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
/* 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);
@ -804,13 +809,13 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c,
{
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);
LOG(LOG_LEVEL_ALWAYS, "waiting for window manager "
"(pid %d) to exit", window_manager_pid);
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());
LOG(LOG_LEVEL_ALWAYS, "window manager (pid %d) did "
"exit, cleaning up session", window_manager_pid);
LOG(LOG_LEVEL_INFO, "calling auth_stop_session and "
"auth_end from pid %d", g_getpid());
auth_stop_session(data);
auth_end(data);
g_sigterm(display_pid);
@ -923,8 +928,8 @@ session_kill(int pid)
{
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)
{
@ -943,7 +948,7 @@ session_kill(int pid)
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)
@ -982,8 +987,8 @@ session_sigkill_all(void)
{
if (tmp->item == 0)
{
log_message(LOG_LEVEL_ERROR, "found null session "
"descriptor!");
LOG(LOG_LEVEL_ERROR, "found null session "
"descriptor!");
}
else
{
@ -1006,7 +1011,7 @@ session_get_bypid(int pid)
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;
}
@ -1016,8 +1021,8 @@ session_get_bypid(int pid)
{
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;
}
@ -1051,13 +1056,13 @@ session_get_byuser(const char *user, int *cnt, unsigned char flags)
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)
{
@ -1089,7 +1094,7 @@ session_get_byuser(const char *user, int *cnt, unsigned char flags)
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)
@ -1099,7 +1104,7 @@ session_get_byuser(const char *user, int *cnt, unsigned char flags)
(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;
@ -1140,7 +1145,7 @@ session_get_byuser(const char *user, int *cnt, unsigned char flags)
int
cleanup_sockets(int display)
{
log_message(LOG_LEVEL_DEBUG, "cleanup_sockets:");
LOG(LOG_LEVEL_DEBUG, "cleanup_sockets:");
char file[256];
int error;
@ -1149,11 +1154,11 @@ cleanup_sockets(int display)
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_DEBUG,
"cleanup_sockets: failed to delete %s", file);
error++;
}
}
@ -1161,11 +1166,11 @@ cleanup_sockets(int display)
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_DEBUG,
"cleanup_sockets: failed to delete %s", file);
error++;
}
}
@ -1173,11 +1178,11 @@ cleanup_sockets(int display)
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_DEBUG,
"cleanup_sockets: failed to delete %s", file);
error++;
}
}
@ -1185,11 +1190,11 @@ cleanup_sockets(int display)
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_message(LOG_LEVEL_DEBUG,
"cleanup_sockets: failed to delete %s", file);
LOG(LOG_LEVEL_DEBUG,
"cleanup_sockets: failed to delete %s", file);
error++;
}
}

View File

@ -43,15 +43,15 @@ sig_sesman_shutdown(int sig)
{
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 @@ sig_sesman_reload_cfg(int sig)
{
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)
if ((cfg = config_read(g_cfg->sesman_ini)) == NULL)
{
log_message(LOG_LEVEL_ERROR, "error creating new config: - keeping old cfg");
return;
}
if (config_read(cfg) != 0)
{
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 @@ sig_sesman_reload_cfg(int sig)
/* 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 @@ sig_sesman_reload_cfg(int sig)
}
}
log_message(LOG_LEVEL_INFO, "configuration reloaded, log subsystem restarted");
LOG(LOG_LEVEL_INFO, "configuration reloaded, log subsystem restarted");
}
/******************************************************************************/
@ -171,7 +159,7 @@ sig_handler_thread(void *arg)
do
{
LOG_DBG("calling sigwait()");
LOG_DEVEL(LOG_LEVEL_DEBUG, "calling sigwait()");
sigwait(&waitmask, &recv_signal);
switch (recv_signal)
@ -179,22 +167,22 @@ sig_handler_thread(void *arg)
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;
}

View File

@ -85,6 +85,9 @@ wm_start()
# 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

View File

@ -37,8 +37,6 @@ char cmnd[257];
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 +54,7 @@ int main(int argc, char **argv)
//int sel;
int sock;
char *pwd;
struct log_config *logging;
user[0] = '\0';
pass[0] = '\0';
@ -63,11 +62,9 @@ int main(int argc, char **argv)
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);
log_start_from_param(logging);
log_config_free(logging);
for (idx = 0; idx < argc; idx++)
{
@ -133,18 +130,18 @@ int main(int argc, char **argv)
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 +154,7 @@ int main(int argc, char **argv)
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))

View File

@ -35,13 +35,13 @@
#define PACKAGE_VERSION "???"
#endif
struct config_sesman g_cfg; /* config.h */
struct config_sesman *g_cfg; /* config.h */
/******************************************************************************/
int
main(int argc, char **argv)
{
int sck;
int sck = -1;
int code;
int i;
int size;
@ -56,21 +56,38 @@ main(int argc, char **argv)
char *username;
char *password;
long data;
const char *sesman_ini;
char default_sesman_ini[256];
int status = 1;
if (0 != config_read(&g_cfg))
/* User specified a different config file? */
if (argc > 2 && (g_strcmp(argv[1], "-C") == 0))
{
g_printf("sesrun: error reading config. quitting.\n");
return 1;
sesman_ini = argv[2];
argv += 2;
argc -= 2;
}
else
{
g_snprintf(default_sesman_ini, 255, "%s/sesman.ini", XRDP_CFG_PATH);
sesman_ini = default_sesman_ini;
}
if (argc == 1)
if (argc != 8)
{
g_printf("xrdp session starter v" PACKAGE_VERSION "\n");
g_printf("\nusage:\n");
g_printf("sesrun <server> <username> <password> <width> <height> <bpp> <session_code>\n");
g_printf("xrdp-sesrun [-C /path/to/sesman.ini] <server> "
"<username> <password> "
"<width> <height> <bpp> <session_code>\n");
g_printf("session code 0 for Xvnc, 10 for X11RDP, 20 for Xorg\n");
}
else if (argc == 8)
else if ((g_cfg = config_read(sesman_ini)) == NULL)
{
g_printf("xrdp-sesrun: error reading config %s. quitting.\n",
sesman_ini);
}
else
{
username = argv[2];
password = argv[3];
@ -85,9 +102,14 @@ main(int argc, char **argv)
sck = g_tcp_socket();
if (sck < 0)
return 1;
if (g_tcp_connect(sck, argv[1], g_cfg.listen_port) == 0)
{
g_printf("socket error\n");
}
else if (g_tcp_connect(sck, argv[1], g_cfg->listen_port) != 0)
{
g_printf("connect error\n");
}
else
{
s_push_layer(out_s, channel_hdr, 8);
out_uint16_be(out_s, session_code); /* code */
@ -123,20 +145,22 @@ main(int argc, char **argv)
in_uint16_be(in_s, data);
in_uint16_be(in_s, display);
g_printf("ok %d display %d\n", (int)data, display);
status = 0;
}
}
}
}
}
else
{
g_printf("connect error\n");
}
g_tcp_close(sck);
if (sck >= 0)
{
g_tcp_close(sck);
}
free_stream(in_s);
free_stream(out_s);
}
return 0;
config_free(g_cfg);
return status;
}

View File

@ -56,7 +56,9 @@ int main(int argc, char **argv)
sock = g_tcp_socket();
if (sock < 0)
{
return 1;
}
s = scp_session_create();
c = scp_connection_create(sock);

View File

@ -78,7 +78,7 @@ auth_userpass(const char *user, const char *pass, int *errorcode)
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 @@ auth_account_disabled(struct spwd *stp)
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 @@ auth_account_disabled(struct spwd *stp)
}
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;
}

View File

@ -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 @@ auth_crypt_pwd(const char *pwd, const char *pln, char *crp)
*
*/
static int
auth_account_disabled(struct spwd* stp)
auth_account_disabled(struct spwd *stp)
{
return 0;
}

View File

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

View File

@ -46,19 +46,19 @@ add_xauth_cookie(int display, const char *file)
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;
}

View File

@ -1905,7 +1905,6 @@ lib_mod_connect(struct vnc *v)
int error;
int i;
int check_sec_result;
struct source_info *si;
v->server_msg(v, "VNC started connecting", 0);
check_sec_result = 1;
@ -1955,8 +1954,7 @@ lib_mod_connect(struct vnc *v)
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);

View File

@ -56,6 +56,8 @@ enum vnc_resize_status
VRS_DONE
};
struct source_info;
struct vnc
{
int size; /* size of this struct */
@ -124,7 +126,7 @@ struct vnc
tintptr handle; /* pointer to self as long */
tintptr wm;
tintptr painter;
tintptr si;
struct source_info *si;
/* mod data */
int server_width;
int server_height;

View File

@ -22,6 +22,8 @@
#include <config_ac.h>
#endif
#include <stdarg.h>
#include "xrdp.h"
#include "log.h"
#include "xrdp_configure_options.h"
@ -47,13 +49,13 @@ static long g_sync_param2 = 0;
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 +69,17 @@ print_version(void)
}
/*****************************************************************************/
void
static void
print_help(void)
{
g_writeln("Usage: xrdp [options]");
g_writeln(" -h, --help show help");
g_writeln(" -n, --nodaemon don't fork into background");
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(" -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 +141,7 @@ g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1,
}
/*****************************************************************************/
void
static void
xrdp_shutdown(int sig)
{
tbus threadid;
@ -153,7 +157,7 @@ xrdp_shutdown(int sig)
}
/*****************************************************************************/
void
static void
xrdp_child(int sig)
{
int safety;
@ -164,7 +168,7 @@ xrdp_child(int sig)
}
/*****************************************************************************/
void
static void
xrdp_hang_up(int sig)
{
log_message(LOG_LEVEL_INFO, "caught SIGHUP, noop...");
@ -225,7 +229,7 @@ g_get_sync_event(void)
}
/*****************************************************************************/
void
static void
pipe_sig(int sig_num)
{
/* do nothing */
@ -256,70 +260,89 @@ g_process_waiting_function(void)
tc_mutex_unlock(g_sync_mutex);
}
/*****************************************************************************/
/**
* @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 +355,16 @@ xrdp_process_params(int argc, char **argv,
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 +378,12 @@ xrdp_process_params(int argc, char **argv,
/*****************************************************************************/
/* 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 +428,6 @@ xrdp_sanity_check(void)
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 +443,14 @@ main(int argc, char **argv)
{
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 +461,9 @@ main(int argc, char **argv)
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 +476,7 @@ main(int argc, char **argv)
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 +486,7 @@ main(int argc, char **argv)
g_exit(0);
}
if (startup_params->version)
if (startup_params.version)
{
print_version();
g_deinit();
@ -480,7 +500,7 @@ main(int argc, char **argv)
g_exit(1);
}
if (startup_params->kill)
if (startup_params.kill)
{
g_writeln("stopping xrdp");
/* read the xrdp.pid file */
@ -515,22 +535,26 @@ main(int argc, char **argv)
}
/* 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 +571,10 @@ main(int argc, char **argv)
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 +601,13 @@ main(int argc, char **argv)
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 +696,7 @@ main(int argc, char **argv)
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 +705,12 @@ main(int argc, char **argv)
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();

View File

@ -40,6 +40,8 @@ long
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 @@ tbus
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*
@ -361,7 +359,7 @@ get_keymaps(int keylayout, struct xrdp_keymap* keymap);
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
@ -437,8 +435,6 @@ server_msg(struct xrdp_mod* mod, char* msg, int code);
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);

View File

@ -8,6 +8,7 @@ fork=true
; 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 @@ ssl_protocols=TLSv1.2, TLSv1.3
; 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 @@ new_cursors=true
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_width=85
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.

View File

@ -59,6 +59,7 @@ layouts_map=default_layouts_map
[default_rdp_layouts]
rdp_layout_us=0x00000409
rdp_layout_us_dvorak=0x00010409
rdp_layout_us_dvp=0x19360409
rdp_layout_dk=0x00000406
rdp_layout_de=0x00000407
rdp_layout_es=0x0000040A
@ -70,6 +71,7 @@ rdp_layout_jp=0xe0010411
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 @@ rdp_layout_pt=0x00000816
[default_layouts_map]
rdp_layout_us=us
rdp_layout_us_dvorak=dvorak
rdp_layout_us_dvp=us(dvp)
rdp_layout_dk=dk
rdp_layout_de=de
rdp_layout_es=es
@ -93,6 +96,7 @@ rdp_layout_fr=fr
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 @@ layouts_map=default_layouts_map
[rdp_layouts_map_mac]
rdp_layout_us=us
rdp_layout_us_dvorak=dvorak
rdp_layout_us_dvp=us(dvp)
rdp_layout_dk=dk
rdp_layout_de=de
rdp_layout_es=es

View File

@ -164,14 +164,12 @@ xrdp_listen_get_startup_params(struct xrdp_listen *self)
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();

View File

@ -559,8 +559,8 @@ xrdp_wm_login_fill_in_combo(struct xrdp_wm *self, struct xrdp_bitmap *b)
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 +568,12 @@ xrdp_wm_login_fill_in_combo(struct xrdp_wm *self, struct xrdp_bitmap *b)
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 +589,8 @@ xrdp_wm_login_fill_in_combo(struct xrdp_wm *self, struct xrdp_bitmap *b)
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 +830,14 @@ xrdp_login_wnd_create(struct xrdp_wm *self)
/**
* 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 +846,6 @@ load_xrdp_config(struct xrdp_config *config, int bpp)
char *n;
char *v;
char buf[256];
int fd;
int i;
@ -873,11 +877,10 @@ load_xrdp_config(struct xrdp_config *config, int bpp)
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 +896,7 @@ load_xrdp_config(struct xrdp_config *config, int bpp)
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 +1004,11 @@ load_xrdp_config(struct xrdp_config *config, int bpp)
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 +1117,13 @@ load_xrdp_config(struct xrdp_config *config, int bpp)
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);

View File

@ -471,7 +471,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm *self)
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);
}
}

Some files were not shown because too many files have changed in this diff Show More