Catch up with xrdp devel branch.
Merge remote-tracking branch 'upstream/devel' into remotefx_painter
This commit is contained in:
commit
8953a3322b
145
.github/workflows/build.yml
vendored
Normal file
145
.github/workflows/build.yml
vendored
Normal 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
|
||||
|
142
.travis.yml
142
.travis.yml
@ -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
47
NEWS.md
@ -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
|
||||
|
@ -2,7 +2,7 @@
|
||||
[](https://gitter.im/neutrinolabs/xrdp-questions)
|
||||

|
||||
|
||||
*Current Version:* 0.9.13
|
||||
*Current Version:* 0.9.14
|
||||
|
||||
# xrdp - an open source RDP server
|
||||
|
||||
|
16
SECURITY.md
Normal file
16
SECURITY.md
Normal 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)
|
||||
|
697
common/log.c
697
common/log.c
@ -66,7 +66,7 @@ internal_log_file_open(const char *fname)
|
||||
#ifdef FD_CLOEXEC
|
||||
if (ret != -1)
|
||||
{
|
||||
fcntl(ret, F_SETFD, FD_CLOEXEC);
|
||||
fcntl(ret, F_SETFD, FD_CLOEXEC);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -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;
|
||||
|
227
common/log.h
227
common/log.h
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 \
|
||||
{ \
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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*
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
28
configure.ac
28
configure.ac
@ -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
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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).
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
1047
instfiles/km-19360409.ini
Normal file
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
{
|
||||
|
6
mc/mc.h
6
mc/mc.h
@ -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;
|
||||
|
@ -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"));
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
6
scripts/install_cppcheck_dependencies_with_apt.sh
Executable file
6
scripts/install_cppcheck_dependencies_with_apt.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
set -eufx
|
||||
|
||||
PACKAGES="libz3-dev z3"
|
||||
|
||||
apt-get -yq --no-install-suggests --no-install-recommends install $PACKAGES
|
98
scripts/install_xrdp_build_dependencies_with_apt.sh
Executable file
98
scripts/install_xrdp_build_dependencies_with_apt.sh
Executable 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
|
@ -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;
|
||||
}
|
||||
|
@ -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 \
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
294
sesman/chansrv/chansrv_config.c
Normal file
294
sesman/chansrv/chansrv_config.c
Normal 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);
|
||||
}
|
||||
}
|
72
sesman/chansrv/chansrv_config.h
Normal file
72
sesman/chansrv/chansrv_config.h
Normal 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
@ -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
@ -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
@ -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];
|
||||
}
|
||||
|
@ -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 ---");
|
||||
}
|
||||
|
@ -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 */
|
@ -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;
|
||||
|
||||
|
@ -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++)
|
||||
|
@ -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
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
@ -146,7 +141,7 @@ xcommon_init(void)
|
||||
g_utf8_string = XInternAtom(g_display, "UTF8_STRING", 0);
|
||||
g_net_wm_name = XInternAtom(g_display, "_NET_WM_NAME", 0);
|
||||
g_wm_state = XInternAtom(g_display, "WM_STATE", 0);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -190,8 +185,8 @@ 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;
|
||||
|
218
sesman/config.c
218
sesman/config.c
@ -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);
|
||||
}
|
||||
}
|
||||
|
109
sesman/config.h
109
sesman/config.h
@ -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);
|
||||
|
||||
|
30
sesman/env.c
30
sesman/env.c
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
34
sesman/scp.c
34
sesman/scp.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
399
sesman/sesman.c
399
sesman/sesman.c
@ -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;
|
||||
|
@ -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
|
||||
|
239
sesman/session.c
239
sesman/session.c
@ -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++;
|
||||
}
|
||||
}
|
||||
|
40
sesman/sig.c
40
sesman/sig.c
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
172
xrdp/xrdp.c
172
xrdp/xrdp.c
@ -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();
|
||||
|
||||
|
10
xrdp/xrdp.h
10
xrdp/xrdp.h
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user