Compare commits
245 Commits
extended-v
...
devel
Author | SHA1 | Date | |
---|---|---|---|
|
42150c5c4f | ||
|
87c89f0aa2 | ||
|
43945e2d4b | ||
|
9d229d2318 | ||
|
b9c5c00d7c | ||
|
1e13533048 | ||
|
cca057908c | ||
|
ea582429e1 | ||
|
c76c580441 | ||
|
8ab3a2e9f8 | ||
|
d8998a0a19 | ||
|
8205559959 | ||
|
f24b7b7988 | ||
|
114fc6eeaa | ||
|
11875fca2b | ||
|
a033cf0ea4 | ||
|
83b256294f | ||
|
9cd4acad49 | ||
|
d4e9b0f637 | ||
|
a4f3471707 | ||
|
bba65b3592 | ||
|
aa5c5daf7e | ||
|
0a1a8f40e5 | ||
|
183abaeb26 | ||
|
4f4458c3a9 | ||
|
5523847540 | ||
|
785db575ca | ||
|
61fd63f028 | ||
|
835536b406 | ||
|
31214f15a6 | ||
|
5b73fb9c31 | ||
|
5114d1ee64 | ||
|
6562c9d958 | ||
|
87d710e89b | ||
|
c69a26e9b4 | ||
|
7ddc43aeea | ||
|
121c17e818 | ||
|
633716bbad | ||
|
bfe76e0499 | ||
|
e6c1df64d3 | ||
|
a82ee03d4d | ||
|
dd9f7c6092 | ||
|
8d994a547d | ||
|
2d6d249f76 | ||
|
51905d765a | ||
|
28c35f962d | ||
|
0c61a15fc5 | ||
|
19260cc90c | ||
|
70ddd5074e | ||
|
0d8e4146a2 | ||
|
a4cc8471ec | ||
|
9efdd92c2a | ||
|
d78d46187f | ||
|
353e11caba | ||
|
9cb6bfc3a4 | ||
|
5d8f451a41 | ||
|
f46e60b142 | ||
|
f3b47b33cd | ||
|
a6a785d7a4 | ||
|
0d00693e54 | ||
|
8270331646 | ||
|
1f8bb57fd6 | ||
|
176b4b15a2 | ||
|
ddd14e05fb | ||
|
a9ec1ebd99 | ||
|
31a910a275 | ||
|
19504da100 | ||
|
ebc21fe180 | ||
|
62befaa803 | ||
|
b8d9c2ec50 | ||
|
a70e4bc33f | ||
|
12a0266f1e | ||
|
2e78a9d8a5 | ||
|
68f0fa7e4d | ||
|
79b88d7f30 | ||
|
60a2beb435 | ||
|
0b82f19318 | ||
|
2e4a0bdddc | ||
|
840c0b8bcf | ||
|
a7462404d5 | ||
|
ec53a0398d | ||
|
edda1b064d | ||
|
f2dda1e0bd | ||
|
23b58aeb70 | ||
|
f2d0a57a6b | ||
|
f6a957851d | ||
|
8b54de320c | ||
|
61b9a42fc5 | ||
|
8822771169 | ||
|
1469d659db | ||
|
9ec6162a54 | ||
|
b4ca302c05 | ||
|
a6a0e5e004 | ||
|
b0bca1363e | ||
|
d364e76ae8 | ||
|
5dd0bb6cac | ||
|
a9eb5a17d2 | ||
|
5835aefa1f | ||
|
8bd7309d72 | ||
|
76ac0600e4 | ||
|
33d9e1d5d7 | ||
|
e89f124afe | ||
|
4d7b916faf | ||
|
47e1c5d359 | ||
|
5cd36c511c | ||
|
f3e42fc209 | ||
|
5da9d70317 | ||
|
33ebd639b5 | ||
|
00dca40bf8 | ||
|
b2fea42acf | ||
|
7e58209b19 | ||
|
396b8ce890 | ||
|
7384f6e574 | ||
|
0c791d073d | ||
|
e593f58a82 | ||
|
dda748de8a | ||
|
0505d28138 | ||
|
e679890083 | ||
|
27653f97f2 | ||
|
a57c68f55e | ||
|
3de8550f40 | ||
|
a2ca01fdf5 | ||
|
f37d1ba46e | ||
|
3c4b42b1aa | ||
|
1c99d0a366 | ||
|
81e037e964 | ||
|
358f07d1c7 | ||
|
bfffc40cba | ||
|
a618a67d4a | ||
|
cc384de392 | ||
|
30248303a8 | ||
|
2e9e7bae75 | ||
|
aa0dbbae15 | ||
|
2ec9720612 | ||
|
617283eb34 | ||
|
7ef01f7b0c | ||
|
21a4118c0b | ||
|
da3114007c | ||
|
f5164e8ff7 | ||
|
1c4e14415d | ||
|
1adb3c7b33 | ||
|
12c46664a2 | ||
|
0a669c5b06 | ||
|
b3b1fff833 | ||
|
6e7a539933 | ||
|
96cbde725d | ||
|
a57e77753f | ||
|
d88dcee5bc | ||
|
a2266f23f6 | ||
|
a3d429b4f7 | ||
|
2faf98ca61 | ||
|
dc9a06f6ce | ||
|
b859457187 | ||
|
77686bf832 | ||
|
6d7cce3d34 | ||
|
f46034326a | ||
|
72bece526b | ||
|
5aca3aa847 | ||
|
e37fdd8c6e | ||
|
16c20dc6e3 | ||
|
70d78dfb6f | ||
|
627da8da3e | ||
|
7ac90b77aa | ||
|
c954bfe9e3 | ||
|
32ef6ea3dd | ||
|
ce3633b807 | ||
|
c99e54cbcb | ||
|
e3e8ed0758 | ||
|
e8c845e78b | ||
|
c766be4be4 | ||
|
e928d8baf2 | ||
|
6f881d47d3 | ||
|
00f17c3ffc | ||
|
677056e3c2 | ||
|
b4d51bc4f1 | ||
|
1c5a5e32a0 | ||
|
24ee0cfd78 | ||
|
f11987ac04 | ||
|
1ce50849ea | ||
|
dd047bb181 | ||
|
dfac42b273 | ||
|
7c959156a9 | ||
|
43f2b2290e | ||
|
f9a1e617f4 | ||
|
de5a23325f | ||
|
3820d279e2 | ||
|
93da7c0d3c | ||
|
e08890ddde | ||
|
a20f99d3d1 | ||
|
5fc804c67d | ||
|
3ef2e7ce49 | ||
|
4d8f2b5a31 | ||
|
352107fc5f | ||
|
36fc802bd9 | ||
|
2b614d275e | ||
|
732d663c70 | ||
|
a2fd7c09fa | ||
|
8e10f0820c | ||
|
e52a4fd0ae | ||
|
8853809310 | ||
|
0fbbc47092 | ||
|
c57e867a3b | ||
|
1897f8159f | ||
|
d7b1f12d9b | ||
|
04f885189a | ||
|
351c92dfba | ||
|
f37faca65b | ||
|
1e4b03eb3c | ||
|
deebc30f58 | ||
|
f097b8028d | ||
|
471d7f0b24 | ||
|
2999b694e6 | ||
|
a350292628 | ||
|
6928caa3bd | ||
|
6b826d03c8 | ||
|
5e6e5bd869 | ||
|
a49edd03aa | ||
|
bcb281707b | ||
|
d977e7caaa | ||
|
313abde4ea | ||
|
cc2f918cd4 | ||
|
cf67dd56bf | ||
|
417bb71abf | ||
|
933394c6be | ||
|
8aedd31762 | ||
|
c5798df0bd | ||
|
ae40ff27c8 | ||
|
a9a823b0da | ||
|
3c9241022a | ||
|
f627b29633 | ||
|
1ef47cbf0b | ||
|
37ade1cb25 | ||
|
ee65ccb31d | ||
|
f42e38125e | ||
|
0bc7803eaa | ||
|
d7bd6f726b | ||
|
216ba3b4d4 | ||
|
e3f41da2cc | ||
|
c236f665d2 | ||
|
d6229df5a1 | ||
|
bacd76f9a2 | ||
|
054991dde2 | ||
|
e14ea4ff2e | ||
|
4ad9e48ff5 | ||
|
fff61cbeca |
19
.cirrus.yml
Normal file
19
.cirrus.yml
Normal file
@ -0,0 +1,19 @@
|
||||
FreeBSD_task:
|
||||
matrix:
|
||||
env:
|
||||
SSL: libressl
|
||||
matrix:
|
||||
freebsd_instance:
|
||||
image_family: freebsd-12-1
|
||||
prepare_script:
|
||||
- pkg install -y $SSL git autoconf automake libtool pkgconf opus jpeg-turbo fdk-aac pixman libX11 libXfixes libXrandr nasm
|
||||
- git submodule update --init --recursive
|
||||
configure_script:
|
||||
- ./bootstrap
|
||||
- env CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ./configure --localstatedir=/var --enable-strict-locations --with-pkgconfigdir=/usr/local/libdata/pkgconfig --enable-strict-locations --enable-ipv6 --enable-opus --enable-jpeg --enable-fdkaac --enable-painter --enable-pixman
|
||||
build_script:
|
||||
- make -j $(sysctl -n hw.ncpu || echo 4)
|
||||
install_script:
|
||||
- make install
|
||||
test_script:
|
||||
- /usr/local/sbin/xrdp -v
|
144
.github/workflows/build.yml
vendored
Normal file
144
.github/workflows/build.yml
vendored
Normal file
@ -0,0 +1,144 @@
|
||||
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
|
||||
# supplied with the operating system
|
||||
CPPCHECK_VER: 2.3
|
||||
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
|
114
.travis.yml
114
.travis.yml
@ -1,114 +0,0 @@
|
||||
sudo: false # use new container
|
||||
language: c
|
||||
|
||||
branches:
|
||||
except: /^(gh-pages|v0\.[0-8].*)/
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages: &common_deps
|
||||
- nasm
|
||||
|
||||
min_amd64_deps: &min_amd64_deps
|
||||
- *common_deps
|
||||
- libpam0g-dev
|
||||
- libssl-dev
|
||||
- libx11-dev
|
||||
- libxrandr-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
|
||||
|
||||
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
|
||||
|
||||
script:
|
||||
- ./bootstrap
|
||||
- ./configure $CONF_FLAGS
|
||||
- make CFLAGS="$CFLAGS -O2 -Wall -Wwrite-strings -Werror"
|
||||
- test -z "$DISTCHECK" || make distcheck
|
167
NEWS.md
167
NEWS.md
@ -1,3 +1,168 @@
|
||||
# Release notes for xrdp v0.9.15 (2020/12/28)
|
||||
|
||||
## New features
|
||||
* Allow token sign in without autologon for SSO (#1667 #1668)
|
||||
* Norwegian keyboard support (#1675)
|
||||
* Improved config support for chansrv (#1635)
|
||||
* Unified chansrv, sesman and libxrdp logging (#1633 #1708 #1738) - thanks to @aquesnel
|
||||
* Support SUSE move to /usr/etc (#1702)
|
||||
* Parameters may now be specified for user-specified shell (#1270 #1695)
|
||||
* xrdp executables now allow alternative config files to be specified with -c (#1588 #1650 #1651)
|
||||
* sesrun improvements (#1741)
|
||||
* Drive redirection location can now be specified (#1048)
|
||||
* Now compiles on RISC-V (#1761)
|
||||
|
||||
## Bug fixes
|
||||
* Additional buffer overflow checks (#1662)
|
||||
* FUSE support now builds on 32-bit platforms (#1682)
|
||||
* genkeymap array size conflict fixed (#1691)
|
||||
* Buffering issue with neutrinordp over a slow link fixed (#1608 1634)
|
||||
* Various documentation fixes (#1704 #1741 #1755 #1759)
|
||||
* Prevent PAM info message from causing authentication failure (#1727)
|
||||
* Cosmetic fixes for minor issues (#1751 #1755 #1749)
|
||||
* Try harder to clean up socket files on session exit (#1740 #1756)
|
||||
* xrdp-chansrv become defunct in docker while file copy (#1658)
|
||||
|
||||
## Internal changes
|
||||
* Compilation warnings with newer compilers (#1659 #1680)
|
||||
* Continuation Integration checks on 32-bit platforms now include FUSE support (#1682)
|
||||
* Continuation Integration builds now default to the Ubuntu Focal platform (#1666)
|
||||
* FUSE type tidy-ups (#1686)
|
||||
* Switch from Travis CI to GitHub Actions (#1728 #1732)
|
||||
* Easier to set up console logging for utilities (#1711)
|
||||
|
||||
-----------------------
|
||||
|
||||
# Release notes for xrdp v0.9.14 (2020/08/31)
|
||||
|
||||
## New features
|
||||
* VNC multi-monitor support if you are using a suitable Xvnc server #1343
|
||||
* VNC sessions now resize by default on reconnection if you are using a suitable Xvnc server #1343
|
||||
* Support Slackware for PAM #1558 #1560
|
||||
* Support Programmer Dvorak Keyboard #1663
|
||||
|
||||
**[HEADS UP]** The VNC changes are significant. They described in more detail on the following wiki page.
|
||||
* [Xvnc backend : Multi monitor and resize support](https://github.com/neutrinolabs/xrdp/wiki/Xvnc-backend-:-Multi-monitor-and-resize-support)
|
||||
|
||||
## Bug fixes
|
||||
* Fix odd shift key behavior (workaround) #397 #1522
|
||||
* Fix Xorg path in the document for Arch Linux #1448 #1529
|
||||
* Fix Xorg path in the document for CentOS 8 #1646 #1647
|
||||
* Fix internal username/password buffer is smaller than RDP protocol specification #1648 #1653
|
||||
* Fix possible memory out-of-bounds accesses #1549
|
||||
* Fix memory allocation overflow #1557
|
||||
* Prevent chansrv input channels being scanned during a server reset #1595
|
||||
* Ignore TS_MULTIFRAGMENTUPDATE_CAPABILITYSET from client if fp disabled #1593
|
||||
* Minor manpage fixes #1611
|
||||
|
||||
## Other changes
|
||||
* CI error fixes
|
||||
* Introduce cppcheck
|
||||
|
||||
## Known issues
|
||||
* FreeRDP 2.0.0-rc4 or later might not able to connect to xrdp due to
|
||||
xrdp's bad-mannered behaviour, add `+glyph-cache` option to FreeRDP to connect #1266
|
||||
* Audio redirection by MP3 codec doesn't sound with some client, use AAC instead #965
|
||||
|
||||
# Release notes for xrdp v0.9.13.1 (2020/06/30)
|
||||
|
||||
This is a security fix release that includes fixes for the following local buffer overflow vulnerability.
|
||||
|
||||
* [CVE-2022-4044: Local users can perform a buffer overflow attack against the xrdp-sesman service and then impersonate it](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-4044)
|
||||
|
||||
This update is recommended for all xrdp users.
|
||||
|
||||
## Special thanks
|
||||
|
||||
Thanks to [Ashley Newson](https://github.com/ashleynewson) reporting the vulnerability and reviewing fix.
|
||||
|
||||
-----------------------
|
||||
|
||||
# Release notes for xrdp v0.9.13 (2020/03/11)
|
||||
|
||||
This release is an intermediate bugfix release. The previous version v0.9.12 has some regressions on drive redirection.
|
||||
|
||||
## Bug fixes (drive redirection related)
|
||||
* Fix chansrv crashes with segmentation fault (regression in #1449) #1487
|
||||
* Drive redirection now supports Guacamole client #1505 #1507
|
||||
* Prevent a coredump in the event of a corrupted file system #1507
|
||||
* Resolve double-free in `chansrv_fuse` #1469
|
||||
|
||||
## Bug fixes (other)
|
||||
* Fix the issue `xrdp --version | less` will show empty output #1471 #1472
|
||||
* Fix some warnings found by cppcheck #1479 #1481 #1484 #1485
|
||||
|
||||
## Other changes
|
||||
* Add FreeBSD CI test #1466
|
||||
* Move Microsoft-defined constants into separate includes #1470
|
||||
* Perform cppcheck during CI test #1493
|
||||
* Support mousex button 8/9 #1478
|
||||
|
||||
## Known issues
|
||||
* FreeRDP 2.0.0-rc4 or later might not able to connect to xrdp due to
|
||||
xrdp's bad-mannered behaviour, add `+glyph-cache` option to FreeRDP to connect #1266
|
||||
* Audio redirection by MP3 codec doesn't sound with some client, use AAC instead #965
|
||||
|
||||
-----------------------
|
||||
|
||||
# Release notes for xrdp v0.9.12 (2019/12/28)
|
||||
|
||||
## Bug fixes
|
||||
* Fix "The log reference is NULL" error when sesman startup #1425
|
||||
* Fix behavior when shmem_id changes #1439
|
||||
* Make vsock config accept -1 for cid and port #1441
|
||||
* Cleanup refresh rect and check stream bounds #1437
|
||||
* Significant improvements in drive redirection #1449
|
||||
* Fix build on macOS Catalina #1462
|
||||
|
||||
## Other changes
|
||||
* Proprietary microphone redirection via rdpsnd is now default off
|
||||
RDP compatible microphone redirection is on instead #1427
|
||||
* Skip connecting to chansrv when no channels enabled #1393
|
||||
* Add openSUSE's pam rules #1442
|
||||
* Do not terminate xrdp daemon when caught SIGHUP #1319
|
||||
|
||||
## 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.11 (2019/08/19)
|
||||
|
||||
## New features
|
||||
* Suppress output (do not draw screen when client window is minimized) #1330
|
||||
* Audio input (microphone) redirection compatible with [MS-RDPEAI](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpeai/d04ffa42-5a0f-4f80-abb1-cc26f71c9452) #1369
|
||||
* Now xrdp can listen on more than one port #1124 #1366
|
||||
|
||||
## Bug fixes
|
||||
* Fix the issue audio redirection sometimes sounds with long delay #1363
|
||||
* Check term event for more responsive shutdown #1372
|
||||
|
||||
## 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.11 (2019/08/19)
|
||||
|
||||
## New features
|
||||
* Suppress output (do not draw screen when client window is minimized) #1330
|
||||
* Audio input (microphone) redirection compatible with [MS-RDPEAI](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpeai/d04ffa42-5a0f-4f80-abb1-cc26f71c9452) #1369
|
||||
* Now xrdp can listen on more than one port #1124 #1366
|
||||
|
||||
## Bug fixes
|
||||
* Fix the issue audio redirection sometimes sounds with long delay #1363
|
||||
* Check term event for more responsive shutdown #1372
|
||||
|
||||
## 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.10 (2019/04/18)
|
||||
|
||||
## Special thanks
|
||||
@ -26,7 +191,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
|
||||
|
@ -1,8 +1,8 @@
|
||||
[![Build Status](https://travis-ci.org/neutrinolabs/xrdp.svg?branch=devel)](https://travis-ci.org/neutrinolabs/xrdp)
|
||||
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/neutrinolabs/xrdp)
|
||||
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/neutrinolabs/xrdp-questions)
|
||||
![Apache-License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)
|
||||
|
||||
*Current Version:* 0.9.10
|
||||
*Current Version:* 0.9.15
|
||||
|
||||
# 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)
|
||||
|
@ -7,6 +7,14 @@ endif
|
||||
EXTRA_DIST = pixman-region.c
|
||||
|
||||
include_HEADERS = \
|
||||
ms-erref.h \
|
||||
ms-fscc.h \
|
||||
ms-rdpbcgr.h \
|
||||
ms-rdpefs.h \
|
||||
ms-rdpegdi.h \
|
||||
ms-rdpele.h \
|
||||
ms-rdperp.h \
|
||||
ms-smb2.h \
|
||||
xrdp_client_info.h \
|
||||
xrdp_constants.h \
|
||||
xrdp_rail.h \
|
||||
@ -46,11 +54,12 @@ libcommon_la_SOURCES = \
|
||||
log.h \
|
||||
os_calls.c \
|
||||
os_calls.h \
|
||||
os_calls.h \
|
||||
parse.h \
|
||||
rail.h \
|
||||
ssl_calls.c \
|
||||
ssl_calls.h \
|
||||
string_calls.c \
|
||||
string_calls.h \
|
||||
thread_calls.c \
|
||||
thread_calls.h \
|
||||
trans.c \
|
||||
|
@ -84,7 +84,8 @@ typedef int bool_t;
|
||||
#define NEED_ALIGN
|
||||
#elif defined(__x86__) || defined(__x86_64__) || \
|
||||
defined(__AMD64__) || defined(_M_IX86) || defined (_M_AMD64) || \
|
||||
defined(__i386__) || defined(__aarch64__)
|
||||
defined(__i386__) || defined(__aarch64__) || \
|
||||
defined(__riscv)
|
||||
#define NO_NEED_ALIGN
|
||||
#else
|
||||
#warning unknown arch
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <config_ac.h>
|
||||
#endif
|
||||
|
||||
#include "os_calls.h"
|
||||
#include "string_calls.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/evp.h>
|
||||
|
@ -40,6 +40,9 @@
|
||||
#define LOWORD(in) ((in) & 0x0000ffff)
|
||||
#undef MAKELONG
|
||||
#define MAKELONG(lo, hi) ((((hi) & 0xffff) << 16) | ((lo) & 0xffff))
|
||||
#define UNUSED_VAR(x) ((void) (x))
|
||||
|
||||
/* graphics macros */
|
||||
#define MAKERECT(r, x, y, cx, cy) \
|
||||
{ (r).left = x; (r).top = y; (r).right = (x) + (cx); (r).bottom = (y) + (cy); }
|
||||
#define ISRECTEMPTY(r) (((r).right <= (r).left) || ((r).bottom <= (r).top))
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "arch.h"
|
||||
#include "os_calls.h"
|
||||
#include "string_calls.h"
|
||||
#include "list.h"
|
||||
#include "file.h"
|
||||
#include "parse.h"
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "arch.h"
|
||||
#include "os_calls.h"
|
||||
#include "string_calls.h"
|
||||
#include "list.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
723
common/log.c
723
common/log.c
@ -31,6 +31,7 @@
|
||||
#include "file.h"
|
||||
#include "os_calls.h"
|
||||
#include "thread_calls.h"
|
||||
#include "string_calls.h"
|
||||
|
||||
/* Add a define here so that the log.h will hold more information
|
||||
* when compiled from this C file.
|
||||
@ -150,13 +151,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,13 +158,21 @@ internal_log_start(struct log_config *l_cfg)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (l_cfg->dump_on_start)
|
||||
{
|
||||
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 */
|
||||
if (l_cfg->enable_syslog)
|
||||
@ -265,37 +267,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 +292,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 +299,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 = 0;
|
||||
lc->enable_pid = 0;
|
||||
|
||||
file_read_section(file, SESMAN_CFG_LOGGING, param_n, param_v);
|
||||
g_snprintf(section_name, 511, "%s%s", section_prefix, SESMAN_CFG_LOGGING);
|
||||
file_read_section(file, section_name, param_n, param_v);
|
||||
|
||||
for (i = 0; i < param_n->count; i++)
|
||||
{
|
||||
@ -372,6 +344,21 @@ 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 +369,312 @@ 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,
|
||||
const enum logLevels override_log_level)
|
||||
{
|
||||
/* Is log initialized? */
|
||||
if (g_staticLogConfig == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (g_staticLogConfig->fd < 0
|
||||
&& !g_staticLogConfig->enable_syslog
|
||||
&& !g_staticLogConfig->enable_console)
|
||||
{
|
||||
/* all logging outputs are disabled */
|
||||
return 0;
|
||||
}
|
||||
else if (override_destination_level)
|
||||
{
|
||||
/* Override is enabled - should the message should be logged? */
|
||||
return log_level <= override_log_level;
|
||||
}
|
||||
/* Override is disabled - Is there at least one log destination
|
||||
* which will accept the message based on the log level? */
|
||||
else if (g_staticLogConfig->fd >= 0
|
||||
&& log_level <= g_staticLogConfig->log_level)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (g_staticLogConfig->enable_syslog
|
||||
&& log_level <= g_staticLogConfig->syslog_level)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (g_staticLogConfig->enable_console
|
||||
&& log_level <= g_staticLogConfig->console_level)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool_t
|
||||
internal_log_location_overrides_level(const char *function_name,
|
||||
const char *file_name,
|
||||
enum logLevels *log_level_return)
|
||||
{
|
||||
struct log_logger_level *logger = NULL;
|
||||
int i;
|
||||
|
||||
if (g_staticLogConfig == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < g_staticLogConfig->per_logger_level->count; i++)
|
||||
{
|
||||
logger = (struct log_logger_level *)list_get_item(g_staticLogConfig->per_logger_level, i);
|
||||
|
||||
if ((logger->logger_type == LOG_TYPE_FILE
|
||||
&& 0 == g_strncmp(logger->logger_name, file_name, LOGGER_NAME_SIZE))
|
||||
|| (logger->logger_type == LOG_TYPE_FUNCTION
|
||||
&& 0 == g_strncmp(logger->logger_name, function_name, LOGGER_NAME_SIZE)))
|
||||
{
|
||||
*log_level_return = logger->log_level;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Here below the public functions
|
||||
*/
|
||||
|
||||
struct log_config *
|
||||
log_config_init_for_console(enum logLevels lvl, const char *override_name)
|
||||
{
|
||||
struct log_config *config = internalInitAndAllocStruct();
|
||||
|
||||
if (config != NULL)
|
||||
{
|
||||
config->program_name = "<null>";
|
||||
config->enable_console = 1;
|
||||
if (override_name != NULL && override_name[0] != '\0')
|
||||
{
|
||||
config->console_level = internal_log_text2level(override_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
config->console_level = lvl;
|
||||
}
|
||||
}
|
||||
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,43 +684,30 @@ 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);
|
||||
log_config_free(g_staticLogConfig);
|
||||
g_staticLogConfig = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -475,31 +720,23 @@ log_start_from_param(const struct log_config *iniParams)
|
||||
* @return 0 on success
|
||||
*/
|
||||
enum logReturns
|
||||
log_start(const char *iniFile, const char *applicationName)
|
||||
log_start(const char *iniFile, const char *applicationName,
|
||||
bool_t dump_on_start)
|
||||
{
|
||||
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);
|
||||
config->dump_on_start = dump_on_start;
|
||||
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 +757,230 @@ log_end(void)
|
||||
{
|
||||
enum logReturns ret = LOG_GENERAL_ERROR;
|
||||
ret = internal_log_end(g_staticLogConfig);
|
||||
|
||||
if (g_staticLogConfig != NULL)
|
||||
{
|
||||
g_free(g_staticLogConfig);
|
||||
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;
|
||||
enum logLevels override_log_level;
|
||||
bool_t override_destination_level = 0;
|
||||
|
||||
/* Start the dump on a new line so that the first line of the dump is
|
||||
aligned to the first column instead of to after the log message
|
||||
preamble (eg. time, log level, ...)
|
||||
*/
|
||||
#define HEX_DUMP_SOURCE_BYTES_PER_LINE (16)
|
||||
#ifdef _WIN32
|
||||
#define HEX_DUMP_HEADER ("%s Hex Dump:\r\n")
|
||||
#define HEX_DUMP_NEWLINE_SIZE (2)
|
||||
#else
|
||||
#ifdef _MACOS
|
||||
#define HEX_DUMP_HEADER ("%s Hex Dump:\r")
|
||||
#define HEX_DUMP_NEWLINE_SIZE (1)
|
||||
#else
|
||||
#define HEX_DUMP_HEADER ("%s Hex Dump:\n")
|
||||
#define HEX_DUMP_NEWLINE_SIZE (1)
|
||||
#endif
|
||||
#endif
|
||||
#define HEX_DUMP_HEADER_SIZE (sizeof(HEX_DUMP_HEADER) - 1)
|
||||
|
||||
override_destination_level = internal_log_location_overrides_level(
|
||||
function_name,
|
||||
file_name,
|
||||
&override_log_level);
|
||||
if (!internal_log_is_enabled_for_level(log_level, override_destination_level, override_log_level))
|
||||
{
|
||||
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];
|
||||
enum logLevels override_log_level = LOG_LEVEL_NEVER;
|
||||
bool_t override_destination_level = 0;
|
||||
|
||||
if (g_staticLogConfig == NULL)
|
||||
{
|
||||
g_writeln("The log reference is NULL - log not initialized properly "
|
||||
"when called from [%s(%s:%d)]",
|
||||
(function_name != NULL ? function_name : "unknown_function"),
|
||||
(file_name != NULL ? file_name : "unknown_file"),
|
||||
line_number);
|
||||
return LOG_ERROR_NO_CFG;
|
||||
}
|
||||
|
||||
override_destination_level = internal_log_location_overrides_level(
|
||||
function_name,
|
||||
file_name,
|
||||
&override_log_level);
|
||||
if (!internal_log_is_enabled_for_level(level, override_destination_level, override_log_level))
|
||||
{
|
||||
return LOG_STARTUP_OK;
|
||||
}
|
||||
|
||||
g_snprintf(buff, LOG_BUFFER_SIZE, "[%s(%s:%d)] %s",
|
||||
function_name, file_name, line_number, msg);
|
||||
|
||||
va_start(ap, msg);
|
||||
rv = internal_log_message(level, override_destination_level, override_log_level, buff, ap);
|
||||
va_end(ap);
|
||||
return rv;
|
||||
}
|
||||
|
||||
enum logReturns
|
||||
log_message(const enum logLevels lvl, const char *msg, ...)
|
||||
{
|
||||
char buff[LOG_BUFFER_SIZE + 31]; /* 19 (datetime) 4 (space+cr+lf+\0) */
|
||||
va_list ap;
|
||||
enum logReturns rv;
|
||||
|
||||
va_start(ap, msg);
|
||||
rv = internal_log_message(lvl, 0, LOG_LEVEL_NEVER, msg, ap);
|
||||
va_end(ap);
|
||||
return rv;
|
||||
}
|
||||
|
||||
enum logReturns
|
||||
internal_log_message(const enum logLevels lvl,
|
||||
const bool_t override_destination_level,
|
||||
const enum logLevels override_log_level,
|
||||
const char *msg,
|
||||
va_list ap)
|
||||
{
|
||||
char buff[LOG_BUFFER_SIZE + 31]; /* 19 (datetime) 4 (space+cr+lf+\0) */
|
||||
int len = 0;
|
||||
enum logReturns rv = LOG_STARTUP_OK;
|
||||
int writereply = 0;
|
||||
@ -547,28 +993,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, override_log_level))
|
||||
{
|
||||
return LOG_STARTUP_OK;
|
||||
}
|
||||
|
||||
now_t = time(&now_t);
|
||||
now = localtime(&now_t);
|
||||
|
||||
snprintf(buff, 21, "[%.4d%.2d%.2d-%.2d:%.2d:%.2d] ", now->tm_year + 1900,
|
||||
now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min,
|
||||
now->tm_sec);
|
||||
strftime(buff, 21, "[%Y%m%d-%H:%M:%S] ", now);
|
||||
|
||||
internal_log_lvl2str(lvl, buff + 20);
|
||||
|
||||
va_start(ap, msg);
|
||||
len = vsnprintf(buff + 28, LOG_BUFFER_SIZE, msg, ap);
|
||||
va_end(ap);
|
||||
if (g_staticLogConfig->enable_pid)
|
||||
{
|
||||
g_snprintf(buff + 28, LOG_BUFFER_SIZE, "[pid:%d tid:%lld] ",
|
||||
g_getpid(), (long long) tc_get_threadid());
|
||||
len = g_strlen(buff + 28);
|
||||
}
|
||||
len += vsnprintf(buff + 28 + len, LOG_BUFFER_SIZE - len, msg, ap);
|
||||
|
||||
/* checking for truncated messages */
|
||||
if (len > LOG_BUFFER_SIZE)
|
||||
{
|
||||
log_message(LOG_LEVEL_WARNING, "next message will be truncated");
|
||||
len = LOG_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
/* forcing the end of message string */
|
||||
@ -586,38 +1042,45 @@ 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 <= override_log_level)
|
||||
|| (!override_destination_level && lvl <= g_staticLogConfig->syslog_level)))
|
||||
{
|
||||
/* log to syslog*/
|
||||
/* %s fix compiler warning 'not a string literal' */
|
||||
syslog(internal_log_xrdp2syslog(lvl), "(%d)(%lld)%s", g_getpid(),
|
||||
(long long) tc_get_threadid(), buff + 20);
|
||||
syslog(internal_log_xrdp2syslog(lvl), "%s", buff + 20);
|
||||
}
|
||||
|
||||
if (lvl <= g_staticLogConfig->log_level)
|
||||
if (g_staticLogConfig->enable_console
|
||||
&& ((override_destination_level && lvl <= override_log_level)
|
||||
|| (!override_destination_level && lvl <= g_staticLogConfig->console_level)))
|
||||
{
|
||||
/* log to console */
|
||||
g_printf("%s", buff);
|
||||
}
|
||||
|
||||
if ((override_destination_level && lvl <= override_log_level)
|
||||
|| (!override_destination_level && lvl <= g_staticLogConfig->log_level))
|
||||
{
|
||||
/* log to application logfile */
|
||||
if (g_staticLogConfig->fd >= 0)
|
||||
{
|
||||
#ifdef LOG_ENABLE_THREAD
|
||||
pthread_mutex_lock(&(g_staticLogConfig->log_lock));
|
||||
#endif
|
||||
|
||||
if (g_staticLogConfig->fd >= 0)
|
||||
{
|
||||
writereply = g_file_write(g_staticLogConfig->fd, buff, g_strlen(buff));
|
||||
|
||||
if (writereply <= 0)
|
||||
{
|
||||
rv = LOG_ERROR_NULL_FILE;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LOG_ENABLE_THREAD
|
||||
pthread_mutex_unlock(&(g_staticLogConfig->log_lock));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
245
common/log.h
245
common/log.h
@ -22,19 +22,22 @@
|
||||
#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) */
|
||||
LOG_LEVEL_NEVER,
|
||||
};
|
||||
|
||||
/* startup return values */
|
||||
@ -50,28 +53,112 @@ enum logReturns
|
||||
};
|
||||
|
||||
#define SESMAN_CFG_LOGGING "Logging"
|
||||
#define SESMAN_CFG_LOGGING_LOGGER "LoggingPerLogger"
|
||||
#define SESMAN_CFG_LOG_FILE "LogFile"
|
||||
#define SESMAN_CFG_LOG_LEVEL "LogLevel"
|
||||
#define SESMAN_CFG_LOG_ENABLE_CONSOLE "EnableConsole"
|
||||
#define SESMAN_CFG_LOG_CONSOLE_LEVEL "ConsoleLevel"
|
||||
#define SESMAN_CFG_LOG_ENABLE_SYSLOG "EnableSyslog"
|
||||
#define SESMAN_CFG_LOG_SYSLOG_LEVEL "SyslogLevel"
|
||||
#define SESMAN_CFG_LOG_ENABLE_PID "EnableProcessId"
|
||||
|
||||
/* enable threading */
|
||||
/*#define LOG_ENABLE_THREAD*/
|
||||
|
||||
#ifdef XRDP_DEBUG
|
||||
#define LOG_DBG(args...) log_message(LOG_LEVEL_DEBUG, args);
|
||||
|
||||
#define LOG_PER_LOGGER_LEVEL
|
||||
|
||||
/**
|
||||
* @brief Logging macro for messages that are for an XRDP developer to
|
||||
* understand and debug XRDP code.
|
||||
*
|
||||
* Note: all log levels are relavant to help a developer understand XRDP at
|
||||
* different levels of granularity.
|
||||
*
|
||||
* Note: the logging function calls are removed when XRDP_DEBUG is NOT defined.
|
||||
*
|
||||
* Note: when the build is configured with --enable-xrdpdebug, then
|
||||
* the log level can be configured per the source file name or method name
|
||||
* (with the suffix "()") in the [LoggingPerLogger]
|
||||
* section of the configuration file.
|
||||
*
|
||||
* For example:
|
||||
* ```
|
||||
* [LoggingPerLogger]
|
||||
* xrdp.c=DEBUG
|
||||
* main()=WARNING
|
||||
* ```
|
||||
*
|
||||
* @param lvl, the log level
|
||||
* @param msg, the log text as a printf format c-string
|
||||
* @param ... the arguments for the printf format c-string
|
||||
*/
|
||||
#define LOG_DEVEL(log_level, args...) \
|
||||
log_message_with_location(__func__, __FILE__, __LINE__, log_level, args);
|
||||
|
||||
/**
|
||||
* @brief Logging macro for messages that are for a systeam administrator to
|
||||
* configure and run XRDP on their machine.
|
||||
*
|
||||
* Note: the logging function calls contain additional code location info when
|
||||
* XRDP_DEBUG is defined.
|
||||
*
|
||||
* @param lvl, the log level
|
||||
* @param msg, the log text as a printf format c-string
|
||||
* @param ... the arguments for the printf format c-string
|
||||
*/
|
||||
#define LOG(log_level, args...) \
|
||||
log_message_with_location(__func__, __FILE__, __LINE__, log_level, args);
|
||||
|
||||
/**
|
||||
* @brief Logging macro for logging the contents of a byte array using a hex
|
||||
* dump format.
|
||||
*
|
||||
* Note: the logging function calls are removed when XRDP_DEBUG is NOT defined.
|
||||
*
|
||||
* @param log_level, the log level
|
||||
* @param message, a message prefix for the hex dump. Note: no printf like
|
||||
* formatting is done to this message.
|
||||
* @param buffer, a pointer to the byte array to log as a hex dump
|
||||
* @param length, the length of the byte array to log
|
||||
*/
|
||||
#define LOG_DEVEL_HEXDUMP(log_level, message, buffer, length) \
|
||||
log_hexdump_with_location(__func__, __FILE__, __LINE__, log_level, message, buffer, length);
|
||||
|
||||
#else
|
||||
#define LOG_DBG(args...)
|
||||
#define LOG_DEVEL(log_level, args...)
|
||||
#define LOG(log_level, args...) log_message(log_level, args);
|
||||
#define LOG_DEVEL_HEXDUMP(log_level, message, buffer, length)
|
||||
|
||||
#endif
|
||||
|
||||
enum log_logger_type
|
||||
{
|
||||
LOG_TYPE_FILE = 0,
|
||||
LOG_TYPE_FUNCTION,
|
||||
};
|
||||
|
||||
struct log_logger_level
|
||||
{
|
||||
enum logLevels log_level;
|
||||
enum log_logger_type logger_type;
|
||||
char logger_name[LOGGER_NAME_SIZE + 1];
|
||||
};
|
||||
|
||||
struct log_config
|
||||
{
|
||||
const char *program_name;
|
||||
char *log_file;
|
||||
int fd;
|
||||
enum logLevels log_level;
|
||||
int enable_console;
|
||||
enum logLevels console_level;
|
||||
int enable_syslog;
|
||||
enum logLevels syslog_level;
|
||||
struct list *per_logger_level;
|
||||
int dump_on_start;
|
||||
int enable_pid;
|
||||
pthread_mutex_t log_lock;
|
||||
pthread_mutexattr_t log_lock_attr;
|
||||
};
|
||||
@ -114,49 +201,125 @@ internal_log_lvl2str(const enum logLevels lvl, char *str);
|
||||
*
|
||||
*/
|
||||
enum logLevels
|
||||
internal_log_text2level(const char *s);
|
||||
internal_log_text2level(const char *buf);
|
||||
|
||||
/**
|
||||
* A function that init our struct that holds all state and
|
||||
* also init its content.
|
||||
* @return LOG_STARTUP_OK or LOG_ERROR_MALLOC
|
||||
*/
|
||||
enum logReturns
|
||||
struct log_config *
|
||||
internalInitAndAllocStruct(void);
|
||||
|
||||
/**
|
||||
* Read configuration from a file and store the values in lists.
|
||||
* @param file
|
||||
* @param lc
|
||||
* @param param_n
|
||||
* @param param_v
|
||||
* @param applicationName, the application name used in the log events.
|
||||
* Print the contents of the logging config to stdout.
|
||||
*/
|
||||
void
|
||||
internal_log_config_dump(struct log_config *config);
|
||||
|
||||
/**
|
||||
* the log function that all files use to log an event.
|
||||
* @param lvl, the loglevel
|
||||
* @param override_destination_level, if true then the destination log level is not used
|
||||
* @param override_log_level, the loglevel instead of the destination log level if override_destination_level is true
|
||||
* @param msg, the logtext.
|
||||
* @param ap, the values for the message format arguments
|
||||
* @return
|
||||
*/
|
||||
enum logReturns
|
||||
internal_config_read_logging(int file, struct log_config *lc,
|
||||
struct list *param_n,
|
||||
struct list *param_v,
|
||||
const char *applicationName);
|
||||
internal_log_message(const enum logLevels lvl,
|
||||
const bool_t override_destination_level,
|
||||
const enum logLevels override_log_level,
|
||||
const char *msg,
|
||||
va_list ap);
|
||||
|
||||
/**
|
||||
* @param log_level, the log level
|
||||
* @param override_destination_level, if true then the destination log level is ignored.
|
||||
* @param override_log_level, the log level to use instead of the destination log level
|
||||
* if override_destination_level is true
|
||||
* @return true if at least one log destination will accept a message logged at the given level.
|
||||
*/
|
||||
bool_t
|
||||
internal_log_is_enabled_for_level(const enum logLevels log_level,
|
||||
const bool_t override_destination_level,
|
||||
const enum logLevels override_log_level);
|
||||
|
||||
/**
|
||||
* @param function_name, the function name (typicaly the __func__ macro)
|
||||
* @param file_name, the file name (typicaly the __FILE__ macro)
|
||||
* @param[out] log_level_return, the log level to use instead of the destination log level
|
||||
* @return true if the logger location overrides the destination log levels
|
||||
*/
|
||||
bool_t
|
||||
internal_log_location_overrides_level(const char *function_name,
|
||||
const char *file_name,
|
||||
enum logLevels *log_level_return);
|
||||
|
||||
/*End of internal functions*/
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This function initialize the log facilities according to the configuration
|
||||
* file, that is described by the in parameter.
|
||||
* @param iniFile
|
||||
* @param applicationName, the name that is used in the log for the running application
|
||||
* @param applicationName the name that is used in the log for the running
|
||||
* application
|
||||
* @param dump_on_start Whether to dump the config on stdout before
|
||||
* logging is started
|
||||
* @return LOG_STARTUP_OK on success
|
||||
*/
|
||||
enum logReturns
|
||||
log_start(const char *iniFile, const char *applicationName);
|
||||
log_start(const char *iniFile, const char *applicationName,
|
||||
bool_t dump_on_start);
|
||||
|
||||
/**
|
||||
* An alternative log_start where the caller gives the params directly.
|
||||
* @param iniParams
|
||||
* @param config
|
||||
* @return
|
||||
*
|
||||
* @post to avoid memory leaks, the config argument must be free'ed using
|
||||
* `log_config_free()`
|
||||
*/
|
||||
enum logReturns
|
||||
log_start_from_param(const struct log_config *iniParams);
|
||||
log_start_from_param(const struct log_config *src_log_config);
|
||||
|
||||
/**
|
||||
* Sets up a suitable log config for writing to the console only
|
||||
* (i.e. for a utility)
|
||||
*
|
||||
* The config can be customised by the caller before calling
|
||||
* log_start_from_param()
|
||||
*
|
||||
* @param Default log level
|
||||
* @param Log level name, or NULL. This can be used to provide an
|
||||
* override to the default log level, by environment variable or
|
||||
* argument.
|
||||
*
|
||||
* @return pointer to struct log_config.
|
||||
*/
|
||||
struct log_config *
|
||||
log_config_init_for_console(enum logLevels lvl, const char *override_name);
|
||||
|
||||
/**
|
||||
* Read configuration from a file and store the values in the returned
|
||||
* log_config.
|
||||
* @param file
|
||||
* @param applicationName, the application name used in the log events.
|
||||
* @param section_prefix, prefix for the logging sections to parse
|
||||
* @return
|
||||
*/
|
||||
struct log_config *
|
||||
log_config_init_from_config(const char *iniFilename,
|
||||
const char *applicationName,
|
||||
const char *section_prefix);
|
||||
|
||||
/**
|
||||
* Free the memory for the log_config struct.
|
||||
*/
|
||||
enum logReturns
|
||||
log_config_free(struct log_config *config);
|
||||
|
||||
/**
|
||||
* Function that terminates all logging
|
||||
* @return
|
||||
@ -166,6 +329,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 +340,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
|
||||
|
43
common/ms-erref.h
Normal file
43
common/ms-erref.h
Normal file
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* MS-ERREF : Definitions from [MS-ERREF]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* References to MS-ERREF are currently correct for v20180912 of that
|
||||
* document
|
||||
*/
|
||||
|
||||
#if !defined(MS_ERREF_H)
|
||||
#define MS_ERREF_H
|
||||
|
||||
/*
|
||||
* NTSTATUS codes (section 2.3)
|
||||
*/
|
||||
enum NTSTATUS
|
||||
{
|
||||
STATUS_SUCCESS = 0x00000000,
|
||||
|
||||
STATUS_NO_MORE_FILES = 0x80000006,
|
||||
|
||||
STATUS_UNSUCCESSFUL = 0xc0000001,
|
||||
STATUS_NO_SUCH_FILE = 0xc000000f,
|
||||
STATUS_ACCESS_DENIED = 0xc0000022,
|
||||
STATUS_OBJECT_NAME_INVALID = 0xc0000033,
|
||||
STATUS_OBJECT_NAME_NOT_FOUND = 0xc0000034,
|
||||
STATUS_SHARING_VIOLATION = 0xc0000043,
|
||||
STATUS_NOT_SUPPORTED = 0xc00000bb
|
||||
};
|
||||
|
||||
#endif /* MS_ERREF_H */
|
64
common/ms-fscc.h
Normal file
64
common/ms-fscc.h
Normal file
@ -0,0 +1,64 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* MS-FSCC : Definitions from [MS-FSCC]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* References to MS-FSCC are currently correct for v20190923 of that
|
||||
* document
|
||||
*/
|
||||
|
||||
#if !defined(MS_FSCC_H)
|
||||
#define MS_FSCC_H
|
||||
|
||||
/*
|
||||
* File system ioctl codes (section 2.3)
|
||||
*/
|
||||
#define FSCTL_DELETE_OBJECT_ID 0x900a0
|
||||
|
||||
/*
|
||||
* File information classes (section 2.4)
|
||||
*/
|
||||
enum FS_INFORMATION_CLASS
|
||||
{
|
||||
FileAllocationInformation = 19, /* Set */
|
||||
FileBasicInformation = 4, /* Query, Set */
|
||||
FileBothDirectoryInformation = 3, /* Query */
|
||||
FileDirectoryInformation = 1, /* Query */
|
||||
FileDispositionInformation = 13, /* Set */
|
||||
FileEndOfFileInformation = 20, /* Set */
|
||||
FileFullDirectoryInformation = 2, /* Query */
|
||||
FileNamesInformation = 12, /* Query */
|
||||
FileRenameInformation = 10, /* Set */
|
||||
FileStandardInformation = 5 /* Query */
|
||||
};
|
||||
|
||||
/*
|
||||
* Size of structs above without trailing RESERVED fields (MS-RDPEFS
|
||||
* 2.2.3.3.8)
|
||||
*/
|
||||
#define FILE_BASIC_INFORMATION_SIZE 36
|
||||
#define FILE_STD_INFORMATION_SIZE 22
|
||||
#define FILE_END_OF_FILE_INFORMATION_SIZE 8
|
||||
|
||||
/* Windows file attributes (section 2.6) */
|
||||
#define W_FILE_ATTRIBUTE_DIRECTORY 0x00000010
|
||||
#define W_FILE_ATTRIBUTE_READONLY 0x00000001
|
||||
#define W_FILE_ATTRIBUTE_SYSTEM 0x00000004
|
||||
#define W_FILE_ATTRIBUTE_NORMAL 0x00000080
|
||||
|
||||
#endif /* MS_FSCC_H */
|
||||
|
||||
|
||||
|
512
common/ms-rdpbcgr.h
Normal file
512
common/ms-rdpbcgr.h
Normal file
@ -0,0 +1,512 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* MS-RDPBCGR : Definitions from [MS-RDPBCGR]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* References to MS-RDPBCGR are currently correct for v20190923 of that
|
||||
* document
|
||||
*/
|
||||
|
||||
#if !defined(MS_RDPBCGR_H)
|
||||
#define MS_RDPBCGR_H
|
||||
|
||||
/* RDP Security Negotiation codes */
|
||||
#define RDP_NEG_REQ 0x01 /* MS-RDPBCGR 2.2.1.1.1 */
|
||||
#define RDP_NEG_RSP 0x02 /* MS-RDPBCGR 2.2.1.2.1 */
|
||||
#define RDP_NEG_FAILURE 0x03 /* MS-RDPBCGR 2.2.1.2.2 */
|
||||
#define RDP_CORRELATION_INFO 0x06 /* MS-RDPBCGR 2.2.1.1.2 */
|
||||
|
||||
/* Protocol types codes (2.2.1.1.1, 2.2.1.2.1) */
|
||||
#define PROTOCOL_RDP 0x00000000
|
||||
#define PROTOCOL_SSL 0x00000001
|
||||
#define PROTOCOL_HYBRID 0x00000002
|
||||
#define PROTOCOL_RDSTLS 0x00000004
|
||||
#define PROTOCOL_HYBRID_EX 0x00000008
|
||||
|
||||
/* Negotiation packet flags (2.2.1.2.1) */
|
||||
#define EXTENDED_CLIENT_DATA_SUPPORTED 0x01
|
||||
#define DYNVC_GFX_PROTOCOL_SUPPORTED 0x02
|
||||
#define NEGRSP_RESERVED 0x04
|
||||
#define RESTRICTED_ADMIN_MODE_SUPPORTED 0x08
|
||||
#define REDIRECTED_AUTHENTICATION_MODE_SUPPORTED 0x10
|
||||
|
||||
/* RDP Negotiation Failure Codes (2.2.1.2.2) */
|
||||
#define SSL_REQUIRED_BY_SERVER 0x00000001
|
||||
#define SSL_NOT_ALLOWED_BY_SERVER 0x00000002
|
||||
#define SSL_CERT_NOT_ON_SERVER 0x00000003
|
||||
#define INCONSISTENT_FLAGS 0x00000004
|
||||
#define HYBRID_REQUIRED_BY_SERVER 0x00000005
|
||||
#define SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER 0x00000006
|
||||
|
||||
/* TS_UD_HEADER: type ((2.2.1.3.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define SEC_TAG_CLI_INFO 0xc001 /* CS_CORE? */
|
||||
#define SEC_TAG_CLI_CRYPT 0xc002 /* CS_SECURITY? */
|
||||
#define SEC_TAG_CLI_CHANNELS 0xc003 /* CS_CHANNELS? */
|
||||
#define SEC_TAG_CLI_4 0xc004 /* CS_CLUSTER? */
|
||||
#define SEC_TAG_CLI_MONITOR 0xc005 /* CS_MONITOR */
|
||||
|
||||
/* Client Core Data: colorDepth, postBeta2ColorDepth (2.2.1.3.2) */
|
||||
#define RNS_UD_COLOR_4BPP 0xCA00
|
||||
#define RNS_UD_COLOR_8BPP 0xCA01
|
||||
#define RNS_UD_COLOR_16BPP_555 0xCA02
|
||||
#define RNS_UD_COLOR_16BPP_565 0xCA03
|
||||
#define RNS_UD_COLOR_24BPP 0xCA04
|
||||
|
||||
/* Client Core Data: connectionType (2.2.1.3.2) */
|
||||
#define CONNECTION_TYPE_MODEM 0x01
|
||||
#define CONNECTION_TYPE_BROADBAND_LOW 0x02
|
||||
#define CONNECTION_TYPE_SATELLITE 0x03
|
||||
#define CONNECTION_TYPE_BROADBAND_HIGH 0x04
|
||||
#define CONNECTION_TYPE_WAN 0x05
|
||||
#define CONNECTION_TYPE_LAN 0x06
|
||||
#define CONNECTION_TYPE_AUTODETECT 0x07
|
||||
|
||||
/* Channel definition structure CHANNEL_DEF (2.2.1.3.4.1) */
|
||||
/* This isn't explicitly named in MS-RDPBCGR */
|
||||
#define CHANNEL_NAME_LEN 7
|
||||
|
||||
/* Oprions field */
|
||||
/* NOTE: XR_ prefixed to avoid conflict with FreeRDP */
|
||||
#define XR_CHANNEL_OPTION_INITIALIZED 0x80000000
|
||||
#define XR_CHANNEL_OPTION_ENCRYPT_RDP 0x40000000
|
||||
#define XR_CHANNEL_OPTION_ENCRYPT_SC 0x20000000
|
||||
#define XR_CHANNEL_OPTION_ENCRYPT_CS 0x10000000
|
||||
#define XR_CHANNEL_OPTION_PRI_HIGH 0x08000000
|
||||
#define XR_CHANNEL_OPTION_PRI_MED 0x04000000
|
||||
#define XR_CHANNEL_OPTION_PRI_LOW 0x02000000
|
||||
#define XR_CHANNEL_OPTION_COMPRESS_RDP 0x00800000
|
||||
#define XR_CHANNEL_OPTION_COMPRESS 0x00400000
|
||||
#define XR_CHANNEL_OPTION_SHOW_PROTOCOL 0x00200000
|
||||
#define REMOTE_CONTROL_PERSISTENT 0x00100000
|
||||
|
||||
/* Server Proprietary Certificate (2.2.1.4.3.1.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define SEC_TAG_PUBKEY 0x0006 /* BB_RSA_KEY_BLOB */
|
||||
#define SEC_TAG_KEYSIG 0x0008 /* BB_SIGNATURE_KEY_BLOB */
|
||||
|
||||
/* Info Packet (TS_INFO_PACKET): flags (2.2.1.11.1.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define RDP_LOGON_AUTO 0x0008
|
||||
#define RDP_LOGON_NORMAL 0x0033
|
||||
#define RDP_COMPRESSION 0x0080
|
||||
#define RDP_LOGON_BLOB 0x0100
|
||||
#define RDP_LOGON_LEAVE_AUDIO 0x2000
|
||||
#define RDP_LOGON_RAIL 0x8000
|
||||
|
||||
/* Extended Info Packet: performanceFlags (2.2.1.11.1.1.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define RDP5_DISABLE_NOTHING 0x00
|
||||
#define RDP5_NO_WALLPAPER 0x01
|
||||
#define RDP5_NO_FULLWINDOWDRAG 0x02
|
||||
#define RDP5_NO_MENUANIMATIONS 0x04
|
||||
#define RDP5_NO_THEMING 0x08
|
||||
#define RDP5_NO_CURSOR_SHADOW 0x20
|
||||
#define RDP5_NO_CURSORSETTINGS 0x40 /* disables cursor blinking */
|
||||
|
||||
/* LICENSE_BINARY_BLOB (2.2.1.12.1.2) */
|
||||
#define LICENCE_TAG_USER 0x000f /* BB_CLIENT_USER_NAME_BLOB */
|
||||
#define LICENCE_TAG_HOST 0x0010 /* BB_CLIENT_MACHINE_NAME_BLOB */
|
||||
|
||||
/* Maps to generalCapabilitySet in T.128 page 138 */
|
||||
|
||||
/* Capability Set: capabilitySetType (2.2.1.13.1.1.1) */
|
||||
#define CAPSTYPE_GENERAL 0x0001
|
||||
#define CAPSTYPE_GENERAL_LEN 0x18
|
||||
|
||||
#define CAPSTYPE_BITMAP 0x0002
|
||||
#define CAPSTYPE_BITMAP_LEN 0x1C
|
||||
|
||||
#define CAPSTYPE_ORDER 0x0003
|
||||
#define CAPSTYPE_ORDER_LEN 0x58
|
||||
#define ORDER_CAP_NEGOTIATE 2 /* NEGOTIATEORDERSUPPORT? not used */
|
||||
#define ORDER_CAP_NOSUPPORT 4 /* not used */
|
||||
|
||||
#define CAPSTYPE_BITMAPCACHE 0x0004
|
||||
#define CAPSTYPE_BITMAPCACHE_LEN 0x28
|
||||
|
||||
#define CAPSTYPE_CONTROL 0x0005
|
||||
#define CAPSTYPE_CONTROL_LEN 0x0C
|
||||
|
||||
#define CAPSTYPE_ACTIVATION 0x0007
|
||||
#define CAPSTYPE_ACTIVATION_LEN 0x0C
|
||||
|
||||
#define CAPSTYPE_POINTER 0x0008
|
||||
#define CAPSTYPE_POINTER_LEN 0x0a
|
||||
#define CAPSTYPE_POINTER_MONO_LEN 0x08
|
||||
|
||||
#define CAPSTYPE_SHARE 0x0009
|
||||
#define CAPSTYPE_SHARE_LEN 0x08
|
||||
|
||||
#define CAPSTYPE_COLORCACHE 0x000A
|
||||
#define CAPSTYPE_COLORCACHE_LEN 0x08
|
||||
|
||||
#define CAPSTYPE_SOUND 0x000C
|
||||
|
||||
#define CAPSTYPE_INPUT 0x000D
|
||||
#define CAPSTYPE_INPUT_LEN 0x58
|
||||
|
||||
#define CAPSTYPE_FONT 0x000E
|
||||
#define CAPSTYPE_FONT_LEN 0x04
|
||||
|
||||
#define CAPSTYPE_BRUSH 0x000F
|
||||
#define CAPSTYPE_BRUSH_LEN 0x08
|
||||
|
||||
#define CAPSTYPE_GLYPHCACHE 0x0010
|
||||
#define CAPSTYPE_OFFSCREENCACHE 0x0011
|
||||
|
||||
#define CAPSTYPE_BITMAPCACHE_HOSTSUPPORT 0x0012
|
||||
#define CAPSTYPE_BITMAPCACHE_HOSTSUPPORT_LEN 0x08
|
||||
|
||||
#define CAPSTYPE_BITMAPCACHE_REV2 0x0013
|
||||
#define CAPSTYPE_BITMAPCACHE_REV2_LEN 0x28
|
||||
#define BMPCACHE2_FLAG_PERSIST ((long)1<<31)
|
||||
|
||||
#define CAPSTYPE_VIRTUALCHANNEL 0x0014
|
||||
#define CAPSTYPE_VIRTUALCHANNEL_LEN 0x08
|
||||
|
||||
#define CAPSTYPE_DRAWNINGRIDCACHE 0x0015
|
||||
#define CAPSTYPE_DRAWGDIPLUS 0x0016
|
||||
#define CAPSTYPE_RAIL 0x0017
|
||||
#define CAPSTYPE_WINDOW 0x0018
|
||||
|
||||
#define CAPSSETTYPE_COMPDESK 0x0019
|
||||
#define CAPSSETTYPE_COMPDESK_LEN 0x06
|
||||
|
||||
#define CAPSSETTYPE_MULTIFRAGMENTUPDATE 0x001A
|
||||
#define CAPSSETTYPE_MULTIFRAGMENTUPDATE_LEN 0x08
|
||||
|
||||
#define CAPSETTYPE_LARGE_POINTER 0x001B
|
||||
#define CAPSETTYPE_LARGE_POINTER_LEN 0x06
|
||||
|
||||
#define CAPSETTYPE_SURFACE_COMMANDS 0x001C
|
||||
#define CAPSETTYPE_SURFACE_COMMANDS_LEN 0x0C
|
||||
|
||||
#define CAPSSETTYPE_BITMAP_CODECS 0x001D
|
||||
#define CAPSSETTYPE_BITMAP_CODECS_LEN 0x1C
|
||||
|
||||
#define CAPSTYPE_FRAME_ACKNOWLEDGE 0x001E
|
||||
#define CAPSTYPE_FRAME_ACKNOWLEDGE_LEN 0x08
|
||||
|
||||
/* Control PDU Data: action (2.2.1.15.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define RDP_CTL_REQUEST_CONTROL 1 /* CTRLACTION_REQUEST_CONTROL */
|
||||
#define RDP_CTL_GRANT_CONTROL 2
|
||||
#define RDP_CTL_DETACH 3
|
||||
#define RDP_CTL_COOPERATE 4
|
||||
|
||||
/* RDP5 disconnect PDU */
|
||||
/* Set Error Info PDU Data: errorInfo (2.2.5.1.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define exDiscReasonNoInfo 0x0000
|
||||
#define exDiscReasonAPIInitiatedDisconnect 0x0001
|
||||
#define exDiscReasonAPIInitiatedLogoff 0x0002
|
||||
#define exDiscReasonServerIdleTimeout 0x0003
|
||||
#define exDiscReasonServerLogonTimeout 0x0004
|
||||
#define exDiscReasonReplacedByOtherConnection 0x0005
|
||||
#define exDiscReasonOutOfMemory 0x0006
|
||||
#define exDiscReasonServerDeniedConnection 0x0007
|
||||
#define exDiscReasonServerDeniedConnectionFips 0x0008
|
||||
#define exDiscReasonLicenseInternal 0x0100
|
||||
#define exDiscReasonLicenseNoLicenseServer 0x0101
|
||||
#define exDiscReasonLicenseNoLicense 0x0102
|
||||
#define exDiscReasonLicenseErrClientMsg 0x0103
|
||||
#define exDiscReasonLicenseHwidDoesntMatchLicense 0x0104
|
||||
#define exDiscReasonLicenseErrClientLicense 0x0105
|
||||
#define exDiscReasonLicenseCantFinishProtocol 0x0106
|
||||
#define exDiscReasonLicenseClientEndedProtocol 0x0107
|
||||
#define exDiscReasonLicenseErrClientEncryption 0x0108
|
||||
#define exDiscReasonLicenseCantUpgradeLicense 0x0109
|
||||
#define exDiscReasonLicenseNoRemoteConnections 0x010a
|
||||
|
||||
/* General Capability Set: osMajorType (2.2.7.1.1) */
|
||||
#define OSMAJORTYPE_UNSPECIFIED 0x0000
|
||||
#define OSMAJORTYPE_WINDOWS 0x0001
|
||||
#define OSMAJORTYPE_OS2 0x0002
|
||||
#define OSMAJORTYPE_MACINTOSH 0x0003
|
||||
#define OSMAJORTYPE_UNIX 0x0004
|
||||
#define OSMAJORTYPE_IOS 0x0005
|
||||
#define OSMAJORTYPE_OSX 0x0006
|
||||
#define OSMAJORTYPE_ANDROID 0x0007
|
||||
#define OSMAJORTYPE_CHROME_OS 0x0008
|
||||
|
||||
/* General Capability Set: osMinorType (2.2.7.1.1) */
|
||||
#define OSMINORTYPE_UNSPECIFIED 0x0000
|
||||
#define OSMINORTYPE_WINDOWS_31X 0x0001
|
||||
#define OSMINORTYPE_WINDOWS_95 0x0002
|
||||
#define OSMINORTYPE_WINDOWS_NT 0x0003
|
||||
#define OSMINORTYPE_OS2_V21 0x0004
|
||||
#define OSMINORTYPE_POWER_PC 0x0005
|
||||
#define OSMINORTYPE_MACINTOSH 0x0006
|
||||
#define OSMINORTYPE_NATIVE_XSERVER 0x0007
|
||||
#define OSMINORTYPE_PSEUDO_XSERVER 0x0008
|
||||
#define OSMINORTYPE_WINDOWS_RT 0x0009
|
||||
|
||||
/* General Capability Set: protocolVersion (2.2.7.1.1) */
|
||||
#define TS_CAPS_PROTOCOLVERSION 0x0200
|
||||
|
||||
/* General Capability Set: extraFlags (2.2.7.1.1) */
|
||||
#define FASTPATH_OUTPUT_SUPPORTED 0x0001
|
||||
#define NO_BITMAP_COMPRESSION_HDR 0x0400
|
||||
#define LONG_CREDENTIALS_SUPPORTED 0x0004
|
||||
#define AUTORECONNECT_SUPPORTED 0x0008
|
||||
#define ENC_SALTED_CHECKSUM 0x0010
|
||||
|
||||
/* Order Capability Set: orderSupportExFlags (2.2.7.1.3) */
|
||||
/* NOTE: XR_ prefixed to avoid conflict with FreeRDP */
|
||||
#define XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT 0x0002
|
||||
#define XR_ORDERFLAGS_EX_ALTSEC_FRAME_MARKER_SUPPORT 0x0004
|
||||
|
||||
/* Order Capability Set: orderFlags (2.2.7.1.3) */
|
||||
#define NEGOTIATEORDERSUPPORT 0x0002
|
||||
#define ZEROBOUNDSDELTASUPPORT 0x0008
|
||||
#define COLORINDEXSUPPORT 0x0020
|
||||
#define SOLIDPATTERNBRUSHONLY 0x0040
|
||||
#define ORDERFLAGS_EXTRA_FLAGS 0x0080
|
||||
|
||||
/* Order Capability Set: orderSupport (2.2.7.1.3) */
|
||||
#define TS_NEG_DSTBLT_INDEX 0x00
|
||||
#define TS_NEG_PATBLT_INDEX 0x01
|
||||
#define TS_NEG_SCRBLT_INDEX 0x02
|
||||
#define TS_NEG_MEMBLT_INDEX 0x03
|
||||
#define TS_NEG_MEM3BLT_INDEX 0x04
|
||||
/* 0x05 */
|
||||
/* 0x06 */
|
||||
#define TS_NEG_DRAWNINEGRID_INDEX 0x07
|
||||
#define TS_NEG_LINETO_INDEX 0x08
|
||||
#define TS_NEG_MULTI_DRAWNINEGRID_INDEX 0x09
|
||||
/* 0x0A */
|
||||
#define TS_NEG_SAVEBITMAP_INDEX 0x0B
|
||||
/* 0x0C */
|
||||
/* 0x0D */
|
||||
/* 0x0E */
|
||||
#define TS_NEG_MULTIDSTBLT_INDEX 0x0F
|
||||
#define TS_NEG_MULTIPATBLT_INDEX 0x10
|
||||
#define TS_NEG_MULTISCRBLT_INDEX 0x11
|
||||
#define TS_NEG_MULTIOPAQUERECT_INDEX 0x12
|
||||
#define TS_NEG_FAST_INDEX_INDEX 0x13
|
||||
#define TS_NEG_POLYGON_SC_INDEX 0x14
|
||||
#define TS_NEG_POLYGON_CB_INDEX 0x15
|
||||
#define TS_NEG_POLYLINE_INDEX 0x16
|
||||
/* 0x17 */
|
||||
#define TS_NEG_FAST_GLYPH_INDEX 0x18
|
||||
#define TS_NEG_ELLIPSE_SC_INDEX 0x19
|
||||
#define TS_NEG_ELLIPSE_CB_INDEX 0x1A
|
||||
#define TS_NEG_INDEX_INDEX 0x1B
|
||||
/* 0x1C */
|
||||
/* 0x1D */
|
||||
/* 0x1E */
|
||||
/* 0x1F */
|
||||
|
||||
/* Input Capability Set: inputFlags (2.2.7.1.6) */
|
||||
#define INPUT_FLAG_SCANCODES 0x0001
|
||||
#define INPUT_FLAG_MOUSEX 0x0004
|
||||
#define INPUT_FLAG_FASTPATH_INPUT 0x0008
|
||||
#define INPUT_FLAG_UNICODE 0x0010
|
||||
#define INPUT_FLAG_FASTPATH_INPUT2 0x0020
|
||||
#define INPUT_FLAG_UNUSED1 0x0040
|
||||
#define INPUT_FLAG_UNUSED2 0x0080
|
||||
#define TS_INPUT_FLAG_MOUSE_HWHEEL 0x0100
|
||||
#define TS_INPUT_FLAG_QOE_TIMESTAMPS 0x0200
|
||||
|
||||
/* Glyph Cache Capability Set: GlyphSupportLevel (2.2.7.1.8) */
|
||||
#define GLYPH_SUPPORT_NONE 0x0000
|
||||
#define GLYPH_SUPPORT_PARTIAL 0x0001
|
||||
#define GLYPH_SUPPORT_FULL 0x0002
|
||||
#define GLYPH_SUPPORT_ENCODE 0x0003
|
||||
|
||||
/* Desktop Composition Capability Set: CompDeskSupportLevel (2.2.7.2.8) */
|
||||
#define COMPDESK_NOT_SUPPORTED 0x0000
|
||||
#define COMPDESK_SUPPORTED 0x0001
|
||||
|
||||
/* Surface Commands Capability Set: cmdFlags (2.2.7.2.9) */
|
||||
#define SURFCMDS_SETSURFACEBITS 0x00000002
|
||||
#define SURFCMDS_FRAMEMARKER 0x00000010
|
||||
#define SURFCMDS_STREAMSUFRACEBITS 0x00000040
|
||||
|
||||
/* Bitmap Codec: codecGUID (2.2.7.2.10.1.1) */
|
||||
|
||||
/* CODEC_GUID_NSCODEC CA8D1BB9-000F-154F-589FAE2D1A87E2D6 */
|
||||
#define XR_CODEC_GUID_NSCODEC \
|
||||
"\xb9\x1b\x8d\xca\x0f\x00\x4f\x15\x58\x9f\xae\x2d\x1a\x87\xe2\xd6"
|
||||
|
||||
/* CODEC_GUID_REMOTEFX 76772F12-BD72-4463-AFB3B73C9C6F7886 */
|
||||
#define XR_CODEC_GUID_REMOTEFX \
|
||||
"\x12\x2F\x77\x76\x72\xBD\x63\x44\xAF\xB3\xB7\x3C\x9C\x6F\x78\x86"
|
||||
|
||||
/* CODEC_GUID_IMAGE_REMOTEFX 2744CCD4-9D8A-4E74-803C-0ECBEEA19C54 */
|
||||
#define XR_CODEC_GUID_IMAGE_REMOTEFX \
|
||||
"\xD4\xCC\x44\x27\x8A\x9D\x74\x4E\x80\x3C\x0E\xCB\xEE\xA1\x9C\x54"
|
||||
|
||||
/* MFVideoFormat_H264 0x34363248-0000-0010-800000AA00389B71 */
|
||||
#define XR_CODEC_GUID_H264 \
|
||||
"\x48\x32\x36\x34\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71"
|
||||
|
||||
/* CODEC_GUID_JPEG 1BAF4CE6-9EED-430C-869ACB8B37B66237 */
|
||||
#define XR_CODEC_GUID_JPEG \
|
||||
"\xE6\x4C\xAF\x1B\xED\x9E\x0C\x43\x86\x9A\xCB\x8B\x37\xB6\x62\x37"
|
||||
|
||||
/* CODEC_GUID_PNG 0E0C858D-28E0-45DB-ADAA0F83E57CC560 */
|
||||
#define XR_CODEC_GUID_PNG \
|
||||
"\x8D\x85\x0C\x0E\xE0\x28\xDB\x45\xAD\xAA\x0F\x83\xE5\x7C\xC5\x60"
|
||||
|
||||
/* PDU Types (2.2.8.1.1.1.1) */
|
||||
#define PDUTYPE_DEMANDACTIVEPDU 0x1
|
||||
#define PDUTYPE_CONFIRMACTIVEPDU 0x3
|
||||
#define PDUTYPE_DEACTIVATEALLPDU 0x6
|
||||
#define PDUTYPE_DATAPDU 0x7
|
||||
#define PDUTYPE_SERVER_REDIR_PKT 0xA
|
||||
|
||||
/* Share Data Header: pduType2 (2.2.8.1.1.1.2) */
|
||||
/* TODO: to be renamed */
|
||||
#define RDP_DATA_PDU_UPDATE 2 /* PDUTYPE2_UPDATE */
|
||||
#define RDP_DATA_PDU_CONTROL 20
|
||||
#define RDP_DATA_PDU_POINTER 27
|
||||
#define RDP_DATA_PDU_INPUT 28
|
||||
#define RDP_DATA_PDU_SYNCHRONISE 31
|
||||
#define PDUTYPE2_REFRESH_RECT 33
|
||||
#define RDP_DATA_PDU_PLAY_SOUND 34
|
||||
#define RDP_DATA_PDU_LOGON 38
|
||||
#define RDP_DATA_PDU_FONT2 39
|
||||
#define RDP_DATA_PDU_DISCONNECT 47
|
||||
|
||||
/* TS_SECURITY_HEADER: flags (2.2.8.1.1.2.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define SEC_CLIENT_RANDOM 0x0001 /* SEC_EXCHANGE_PKT? */
|
||||
#define SEC_ENCRYPT 0x0008
|
||||
#define SEC_LOGON_INFO 0x0040 /* SEC_INFO_PKT */
|
||||
#define SEC_LICENCE_NEG 0x0080 /* SEC_LICENSE_PKT */
|
||||
|
||||
#define SEC_TAG_SRV_INFO 0x0c01 /* SC_CORE */
|
||||
#define SEC_TAG_SRV_CRYPT 0x0c02 /* SC_SECURITY */
|
||||
#define SEC_TAG_SRV_CHANNELS 0x0c03 /* SC_NET? */
|
||||
|
||||
/* Slow-Path Input Event: messageType (2.2.8.1.1.3.1.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define RDP_INPUT_SYNCHRONIZE 0
|
||||
#define RDP_INPUT_CODEPOINT 1
|
||||
#define RDP_INPUT_VIRTKEY 2
|
||||
#define RDP_INPUT_SCANCODE 4
|
||||
#define RDP_INPUT_UNICODE 5
|
||||
#define RDP_INPUT_MOUSE 0x8001
|
||||
#define RDP_INPUT_MOUSEX 0x8002
|
||||
|
||||
/* Keyboard Event: keyboardFlags (2.2.8.1.1.3.1.1.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define KBD_FLAG_RIGHT 0x0001
|
||||
#define KBD_FLAG_EXT 0x0100 /* KBDFLAGS_EXTENDED */
|
||||
#define KBD_FLAG_QUIET 0x1000
|
||||
#define KBD_FLAG_DOWN 0x4000
|
||||
#define KBD_FLAG_UP 0x8000
|
||||
|
||||
/* Mouse Event: pointerFlags (2.2.8.1.1.3.1.1.3) */
|
||||
#define PTRFLAGS_HWHEEL 0x0400
|
||||
#define PTRFLAGS_WHEEL 0x0200
|
||||
#define PTRFLAGS_WHEEL_NEGATIVE 0x0100
|
||||
#define WheelRotationMask 0x01FF
|
||||
#define PTRFLAGS_MOVE 0x0800
|
||||
#define PTRFLAGS_DOWN 0x8000
|
||||
#define PTRFLAGS_BUTTON1 0x1000
|
||||
#define PTRFLAGS_BUTTON2 0x2000
|
||||
#define PTRFLAGS_BUTTON3 0x4000
|
||||
|
||||
/* Extended Mouse Event: pointerFlags (2.2.8.1.1.3.1.1.4) */
|
||||
#define PTRXFLAGS_DOWN 0x8000
|
||||
#define PTRXFLAGS_BUTTON1 0x0001
|
||||
#define PTRXFLAGS_BUTTON2 0x0002
|
||||
|
||||
/* Synchronize Event: toggleFlags (2.2.8.1.1.3.1.1.5) */
|
||||
/* TODO: to be renamed */
|
||||
#define KBD_FLAG_SCROLL 0x0001 /* TS_SYNC_SCROLL_LOCK */
|
||||
#define KBD_FLAG_NUMLOCK 0x0002
|
||||
#define KBD_FLAG_CAPITAL 0x0004
|
||||
#define TS_SYNC_KANA_LOCK 0x0008
|
||||
|
||||
/* Client Fast-Path Input Event PDU 2.2.8.1.2 */
|
||||
#define FASTPATH_INPUT_ENCRYPTED 0x2
|
||||
|
||||
/* Fast-Path Input Event: eventCode (2.2.8.1.2.2) */
|
||||
#define FASTPATH_INPUT_EVENT_SCANCODE 0x0
|
||||
#define FASTPATH_INPUT_EVENT_MOUSE 0x1
|
||||
#define FASTPATH_INPUT_EVENT_MOUSEX 0x2
|
||||
#define FASTPATH_INPUT_EVENT_SYNC 0x3
|
||||
#define FASTPATH_INPUT_EVENT_UNICODE 0x4
|
||||
#define FASTPATH_INPUT_EVENT_QOE_TIMESTAMP 0x6
|
||||
|
||||
/* Fast-Path Keyboard Event: eventHeader (2.2.8.1.2.2.1) */
|
||||
#define FASTPATH_INPUT_KBDFLAGS_RELEASE 0x01
|
||||
#define FASTPATH_INPUT_KBDFLAGS_EXTENDED 0x02
|
||||
#define FASTPATH_INPUT_KBDFLAGS_EXTENDED1 0x04
|
||||
|
||||
/* Slow-Path Graphics Update: updateType (2.2.9.1.1.3.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define RDP_UPDATE_ORDERS 0
|
||||
#define RDP_UPDATE_BITMAP 1
|
||||
#define RDP_UPDATE_PALETTE 2
|
||||
#define RDP_UPDATE_SYNCHRONIZE 3
|
||||
|
||||
/* Server Pointer Update PDU: messageType (2.2.9.1.1.4) */
|
||||
/* TODO: to be renamed */
|
||||
#define RDP_POINTER_SYSTEM 1 /* TS_PTRMSGTYPE_SYSTEM */
|
||||
#define RDP_POINTER_MOVE 3
|
||||
#define RDP_POINTER_COLOR 6
|
||||
#define RDP_POINTER_CACHED 7
|
||||
#define RDP_POINTER_POINTER 8
|
||||
|
||||
/* System Pointer Update: systemPointerType (2.2.9.1.1.4.3) */
|
||||
#define RDP_NULL_POINTER 0
|
||||
#define RDP_DEFAULT_POINTER 0x7F00
|
||||
|
||||
/* Server Fast-Path Update PDU: action (2.2.9.1.2) */
|
||||
#define FASTPATH_OUTPUT_ACTION_FASTPATH 0x0
|
||||
#define FASTPATH_OUTPUT_ACTION_X224 0x3
|
||||
|
||||
/* Server Fast-Path Update PDU: flags (2.2.9.1.2) */
|
||||
#define FASTPATH_OUTPUT_SECURE_CHECKSUM 0x1
|
||||
#define FASTPATH_OUTPUT_ENCRYPTED 0x2
|
||||
|
||||
/* Fast-Path Update: updateCode (2.2.9.1.2.1) */
|
||||
#define FASTPATH_UPDATETYPE_ORDERS 0x0
|
||||
#define FASTPATH_UPDATETYPE_BITMAP 0x1
|
||||
#define FASTPATH_UPDATETYPE_PALETTE 0x2
|
||||
#define FASTPATH_UPDATETYPE_SYNCHRONIZE 0x3
|
||||
#define FASTPATH_UPDATETYPE_SURFCMDS 0x4
|
||||
#define FASTPATH_UPDATETYPE_PTR_NULL 0x5
|
||||
#define FASTPATH_UPDATETYPE_PTR_DEFAULT 0x6
|
||||
#define FASTPATH_UPDATETYPE_PTR_POSITION 0x8
|
||||
#define FASTPATH_UPDATETYPE_COLOR 0x9
|
||||
#define FASTPATH_UPDATETYPE_CACHED 0xA
|
||||
#define FASTPATH_UPDATETYPE_POINTER 0xB
|
||||
|
||||
/* Fast-Path Update: fragmentation (2.2.9.1.2.1) */
|
||||
#define FASTPATH_FRAGMENT_SINGLE 0x0
|
||||
#define FASTPATH_FRAGMENT_LAST 0x1
|
||||
#define FASTPATH_FRAGMENT_FIRST 0x2
|
||||
#define FASTPATH_FRAGMENT_NEXT 0x3
|
||||
#define FASTPATH_OUTPUT_COMPRESSION_USED 0x2
|
||||
|
||||
/* Surface Command Type (2.2.9.1.2.1.10.1) */
|
||||
#define CMDTYPE_SET_SURFACE_BITS 0x0001
|
||||
#define CMDTYPE_FRAME_MARKER 0x0004
|
||||
#define CMDTYPE_STREAM_SURFACE_BITS 0x0006
|
||||
|
||||
/* Compression Flags (3.1.8.2.1) */
|
||||
/* TODO: to be renamed, not used anywhere */
|
||||
#define RDP_MPPC_COMPRESSED 0x20
|
||||
#define RDP_MPPC_RESET 0x40
|
||||
#define RDP_MPPC_FLUSH 0x80
|
||||
#define RDP_MPPC_DICT_SIZE 8192 /* RDP 4.0 | MS-RDPBCGR 3.1.8 */
|
||||
|
||||
#endif /* MS_RDPBCGR_H */
|
123
common/ms-rdpefs.h
Normal file
123
common/ms-rdpefs.h
Normal file
@ -0,0 +1,123 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* MS-RDPEFS : Definitions from [MS-RDPEFS]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* References to MS-RDPEFS are currently correct for v20180912 of that
|
||||
* document
|
||||
*/
|
||||
|
||||
#if !defined(MS_RDPEFS_H)
|
||||
#define MS_RDPEFS_H
|
||||
|
||||
/*
|
||||
* RDPDR_HEADER definitions (2.2.1.1)
|
||||
*/
|
||||
|
||||
/* device redirector core component; most of the packets in this protocol */
|
||||
/* are sent under this component ID */
|
||||
#define RDPDR_CTYP_CORE 0x4472
|
||||
|
||||
/* printing component. the packets that use this ID are typically about */
|
||||
/* printer cache management and identifying XPS printers */
|
||||
#define RDPDR_CTYP_PRN 0x5052
|
||||
|
||||
/* Server Announce Request, as specified in section 2.2.2.2 */
|
||||
#define PAKID_CORE_SERVER_ANNOUNCE 0x496E
|
||||
|
||||
/* Client Announce Reply and Server Client ID Confirm, as specified in */
|
||||
/* sections 2.2.2.3 and 2.2.2.6. */
|
||||
#define PAKID_CORE_CLIENTID_CONFIRM 0x4343
|
||||
|
||||
/* Client Name Request, as specified in section 2.2.2.4 */
|
||||
#define PAKID_CORE_CLIENT_NAME 0x434E
|
||||
|
||||
/* Client Device List Announce Request, as specified in section 2.2.2.9 */
|
||||
#define PAKID_CORE_DEVICELIST_ANNOUNCE 0x4441
|
||||
|
||||
/* Server Device Announce Response, as specified in section 2.2.2.1 */
|
||||
#define PAKID_CORE_DEVICE_REPLY 0x6472
|
||||
|
||||
/* Device I/O Request, as specified in section 2.2.1.4 */
|
||||
#define PAKID_CORE_DEVICE_IOREQUEST 0x4952
|
||||
|
||||
/* Device I/O Response, as specified in section 2.2.1.5 */
|
||||
#define PAKID_CORE_DEVICE_IOCOMPLETION 0x4943
|
||||
|
||||
/* Server Core Capability Request, as specified in section 2.2.2.7 */
|
||||
#define PAKID_CORE_SERVER_CAPABILITY 0x5350
|
||||
|
||||
/* Client Core Capability Response, as specified in section 2.2.2.8 */
|
||||
#define PAKID_CORE_CLIENT_CAPABILITY 0x4350
|
||||
|
||||
/* Client Drive Device List Remove, as specified in section 2.2.3.2 */
|
||||
#define PAKID_CORE_DEVICELIST_REMOVE 0x444D
|
||||
|
||||
/* Add Printer Cachedata, as specified in [MS-RDPEPC] section 2.2.2.3 */
|
||||
#define PAKID_PRN_CACHE_DATA 0x5043
|
||||
|
||||
/* Server User Logged On, as specified in section 2.2.2.5 */
|
||||
#define PAKID_CORE_USER_LOGGEDON 0x554C
|
||||
|
||||
/* Server Printer Set XPS Mode, as specified in [MS-RDPEPC] section 2.2.2.2 */
|
||||
#define PAKID_PRN_USING_XPS 0x5543
|
||||
|
||||
/*
|
||||
* Capability header definitions (2.2.1.2)
|
||||
*/
|
||||
|
||||
#define CAP_GENERAL_TYPE 0x0001 /* General cap set - GENERAL_CAPS_SET */
|
||||
#define CAP_PRINTER_TYPE 0x0002 /* Print cap set - PRINTER_CAPS_SET */
|
||||
#define CAP_PORT_TYPE 0x0003 /* Port cap set - PORT_CAPS_SET */
|
||||
#define CAP_DRIVE_TYPE 0x0004 /* Drive cap set - DRIVE_CAPS_SET */
|
||||
#define CAP_SMARTCARD_TYPE 0x0005 /* Smart card cap set - SMARTCARD_CAPS_SET */
|
||||
|
||||
/*
|
||||
* Device announce header (2.2.1.3)
|
||||
*/
|
||||
#define RDPDR_DTYP_SERIAL 0x0001
|
||||
#define RDPDR_DTYP_PARALLEL 0x0002
|
||||
#define RDPDR_DTYP_PRINT 0x0004
|
||||
#define RDPDR_DTYP_FILESYSTEM 0x0008
|
||||
#define RDPDR_DTYP_SMARTCARD 0x0020
|
||||
|
||||
/* Device I/O Request definitions (2.2.1.4) */
|
||||
/* MajorFunction */
|
||||
enum IRP_MJ
|
||||
{
|
||||
IRP_MJ_CREATE = 0x00000000,
|
||||
IRP_MJ_CLOSE = 0x00000002,
|
||||
IRP_MJ_READ = 0x00000003,
|
||||
IRP_MJ_WRITE = 0x00000004,
|
||||
IRP_MJ_DEVICE_CONTROL = 0x0000000E,
|
||||
IRP_MJ_QUERY_VOLUME_INFORMATION = 0x0000000A,
|
||||
IRP_MJ_SET_VOLUME_INFORMATION = 0x0000000B,
|
||||
IRP_MJ_QUERY_INFORMATION = 0x00000005,
|
||||
IRP_MJ_SET_INFORMATION = 0x00000006,
|
||||
IRP_MJ_DIRECTORY_CONTROL = 0x0000000C,
|
||||
IRP_MJ_LOCK_CONTROL = 0x00000011
|
||||
};
|
||||
|
||||
/* MinorFunction */
|
||||
/* Set to zero unless MajorFunction code == IRP_MJ_DIRECTORY_CONTROL */
|
||||
enum IRP_MN
|
||||
{
|
||||
IRP_MN_NONE = 0x00000000, /* Name not in MS docs */
|
||||
IRP_MN_QUERY_DIRECTORY = 0x00000001,
|
||||
IRP_MN_NOTIFY_CHANGE_DIRECTORY = 0x00000002
|
||||
};
|
||||
|
||||
|
||||
#endif /* MS_RDPEFS_H */
|
59
common/ms-rdpegdi.h
Normal file
59
common/ms-rdpegdi.h
Normal file
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* MS-RDPEGDI : Definitions from [MS-RDPEGDI]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* References to MS-RDPEGDI are currently correct for v20180912 of that
|
||||
* document
|
||||
*/
|
||||
|
||||
#if !defined(MS_RDPEGDI_H)
|
||||
#define MS_RDPEGDI_H
|
||||
|
||||
/* Drawing Order: controlFlags (2.2.2.2.1, 2.2.2.2.1.1.2) */
|
||||
#define TS_STANDARD 0x01
|
||||
#define TS_SECONDARY 0x02
|
||||
#define TS_BOUNDS 0x04
|
||||
#define TS_TYPE_CHANGE 0x08
|
||||
#define TS_DELTA_COORDINATES 0x10
|
||||
#define TS_ZERO_BOUNDS_DELTAS 0x20
|
||||
#define TS_ZERO_FIELD_BYTE_BIT0 0x40
|
||||
#define TS_ZERO_FIELD_BYTE_BIT1 0x80
|
||||
|
||||
/* Drawing Order: orderType (2.2.2.2.1.1.2) */
|
||||
/* Should be renamed */
|
||||
#define RDP_ORDER_DESTBLT 0 /* TS_ENC_DSTBLT_ORDER */
|
||||
#define RDP_ORDER_PATBLT 1
|
||||
#define RDP_ORDER_SCREENBLT 2
|
||||
#define RDP_ORDER_LINE 9
|
||||
#define RDP_ORDER_RECT 10
|
||||
#define RDP_ORDER_DESKSAVE 11
|
||||
#define RDP_ORDER_MEMBLT 13
|
||||
#define RDP_ORDER_TRIBLT 14
|
||||
#define RDP_ORDER_POLYLINE 22
|
||||
#define RDP_ORDER_TEXT2 27
|
||||
#define RDP_ORDER_COMPOSITE 37 /* 0x25 - not defined in RDPEGDI */
|
||||
|
||||
/* Secondary Drawing Order Header: orderType (2.2.2.2.1.2.1.1) */
|
||||
#define TS_CACHE_BITMAP_UNCOMPRESSED 0x00
|
||||
#define TS_CACHE_COLOR_TABLE 0x01
|
||||
#define TS_CACHE_BITMAP_COMPRESSED 0x02
|
||||
#define TS_CACHE_GLYPH 0x03
|
||||
#define TS_CACHE_BITMAP_UNCOMPRESSED_REV2 0x04
|
||||
#define TS_CACHE_BITMAP_COMPRESSED_REV2 0x05
|
||||
#define TS_CACHE_BRUSH 0x07
|
||||
#define TS_CACHE_BITMAP_COMPRESSED_REV3 0x08
|
||||
|
||||
#endif /* MS_RDPEGDI_H */
|
36
common/ms-rdpele.h
Normal file
36
common/ms-rdpele.h
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* MS-RDPELE : Definitions from [MS-RDPELE]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* References to MS-RDPELE are currently correct for v20180912 of that
|
||||
* document
|
||||
*/
|
||||
|
||||
#if !defined(MS_RDPELE_H)
|
||||
#define MS_RDPELE_H
|
||||
|
||||
/* LicensingMessage (MS-RDPELE 2.2.2) */
|
||||
/* TODO: to be renamed */
|
||||
#define LICENCE_TAG_DEMAND 0x01 /* LICNSE_REQUEST */
|
||||
#define LICENCE_TAG_AUTHREQ 0x02 /* PLATFORM_CHALLENGE */
|
||||
#define LICENCE_TAG_ISSUE 0x03 /* NEW_LICENSE */
|
||||
#define LICENCE_TAG_REISSUE 0x04 /* UPGRADE_LICENSE */
|
||||
#define LICENCE_TAG_PRESENT 0x12 /* LICENSE_INFO */
|
||||
#define LICENCE_TAG_REQUEST 0x13 /* NEW_LICENSE_REQUEST */
|
||||
#define LICENCE_TAG_AUTHRESP 0x15 /* PLATFORM_CHALLENGE_RESPONSE */
|
||||
#define LICENCE_TAG_RESULT 0xff
|
||||
|
||||
#endif /* MS_RDPELE_H */
|
31
common/ms-rdperp.h
Normal file
31
common/ms-rdperp.h
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* MS-RDPERP : Definitions from [MS-RDPERP]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* References to MS-RDPERP are currently correct for v20190923 of that
|
||||
* document
|
||||
*/
|
||||
|
||||
#if !defined(MS_RDPERP_H)
|
||||
#define MS_RDPERP_H
|
||||
|
||||
/* Window List Capability Set: WndSupportLevel (2.2.1.1.2) */
|
||||
#define TS_WINDOW_LEVEL_NOT_SUPPORTED 0x00000000
|
||||
#define TS_WINDOW_LEVEL_SUPPORTED 0x00000001
|
||||
#define TS_WINDOW_LEVEL_SUPPORTED_EX 0x00000002
|
||||
|
||||
|
||||
#endif /* MS_RDPERP_H */
|
79
common/ms-smb2.h
Normal file
79
common/ms-smb2.h
Normal file
@ -0,0 +1,79 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* MS-SMB2 : Definitions from [MS-SMB2]
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* References to MS-SMB2 are currently correct for v20190923 of that
|
||||
* document
|
||||
*/
|
||||
|
||||
#if !defined(MS_SMB2_H)
|
||||
#define MS_SMB2_H
|
||||
|
||||
/* SMB2 CREATE request values (section 2.2.13) */
|
||||
|
||||
/*
|
||||
* ShareAccess Mask. Currently, this is referred
|
||||
* to in MS-RDPEFS 2.2.1.4.1 as 'SharedAccess' rather than 'ShareAccess'.
|
||||
*/
|
||||
#define SA_FILE_SHARE_READ 0x00000001
|
||||
#define SA_FILE_SHARE_WRITE 0x00000002
|
||||
#define SA_FILE_SHARE_DELETE 0x00000004
|
||||
|
||||
/* CreateDisposition Mask */
|
||||
#define CD_FILE_SUPERSEDE 0x00000000
|
||||
#define CD_FILE_OPEN 0x00000001
|
||||
#define CD_FILE_CREATE 0x00000002
|
||||
#define CD_FILE_OPEN_IF 0x00000003
|
||||
#define CD_FILE_OVERWRITE 0x00000004
|
||||
#define CD_FILE_OVERWRITE_IF 0x00000005
|
||||
|
||||
/* CreateOptions Mask */
|
||||
enum CREATE_OPTIONS
|
||||
{
|
||||
CO_FILE_DIRECTORY_FILE = 0x00000001,
|
||||
CO_FILE_WRITE_THROUGH = 0x00000002,
|
||||
CO_FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020,
|
||||
CO_FILE_DELETE_ON_CLOSE = 0x00001000
|
||||
};
|
||||
|
||||
/*
|
||||
* DesiredAccess Mask (section 2.2.13.1.1)
|
||||
*/
|
||||
|
||||
#define DA_FILE_READ_DATA 0x00000001
|
||||
#define DA_FILE_WRITE_DATA 0x00000002
|
||||
#define DA_FILE_APPEND_DATA 0x00000004
|
||||
#define DA_FILE_READ_EA 0x00000008 /* rd extended attributes */
|
||||
#define DA_FILE_WRITE_EA 0x00000010 /* wr extended attributes */
|
||||
#define DA_FILE_EXECUTE 0x00000020
|
||||
#define DA_FILE_READ_ATTRIBUTES 0x00000080
|
||||
#define DA_FILE_WRITE_ATTRIBUTES 0x00000100
|
||||
#define DA_DELETE 0x00010000
|
||||
#define DA_READ_CONTROL 0x00020000 /* rd security descriptor */
|
||||
#define DA_WRITE_DAC 0x00040000
|
||||
#define DA_WRITE_OWNER 0x00080000
|
||||
#define DA_SYNCHRONIZE 0x00100000
|
||||
#define DA_ACCESS_SYSTEM_SECURITY 0x01000000
|
||||
#define DA_MAXIMUM_ALLOWED 0x02000000
|
||||
#define DA_GENERIC_ALL 0x10000000
|
||||
#define DA_GENERIC_EXECUTE 0x20000000
|
||||
#define DA_GENERIC_WRITE 0x40000000
|
||||
#define DA_GENERIC_READ 0x80000000
|
||||
|
||||
#endif /* MS_SMB2_H */
|
||||
|
||||
|
||||
|
@ -76,7 +76,7 @@
|
||||
#endif
|
||||
|
||||
#include "os_calls.h"
|
||||
#include "arch.h"
|
||||
#include "string_calls.h"
|
||||
#include "log.h"
|
||||
|
||||
/* for clearenv() */
|
||||
@ -166,6 +166,8 @@ g_deinit(void)
|
||||
#if defined(_WIN32)
|
||||
WSACleanup();
|
||||
#endif
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
g_rm_temp_dir();
|
||||
}
|
||||
|
||||
@ -1041,6 +1043,25 @@ g_sck_vsock_bind(int sck, const char *port)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_sck_vsock_bind_address(int sck, const char *port, const char *address)
|
||||
{
|
||||
#if defined(XRDP_ENABLE_VSOCK)
|
||||
struct sockaddr_vm s;
|
||||
|
||||
g_memset(&s, 0, sizeof(struct sockaddr_vm));
|
||||
s.svm_family = AF_VSOCK;
|
||||
s.svm_port = atoi(port);
|
||||
s.svm_cid = atoi(address);
|
||||
|
||||
return bind(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_vm));
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if defined(XRDP_ENABLE_IPV6)
|
||||
/*****************************************************************************/
|
||||
/* Helper function for g_tcp_bind_address. */
|
||||
@ -2488,499 +2509,6 @@ g_file_get_size(const char *filename)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns length of text */
|
||||
int
|
||||
g_strlen(const char *text)
|
||||
{
|
||||
if (text == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return strlen(text);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* locates char in text */
|
||||
const char *
|
||||
g_strchr(const char* text, int c)
|
||||
{
|
||||
if (text == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return strchr(text,c);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns dest */
|
||||
char *
|
||||
g_strcpy(char *dest, const char *src)
|
||||
{
|
||||
if (src == 0 && dest != 0)
|
||||
{
|
||||
dest[0] = 0;
|
||||
return dest;
|
||||
}
|
||||
|
||||
if (dest == 0 || src == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return strcpy(dest, src);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns dest */
|
||||
char *
|
||||
g_strncpy(char *dest, const char *src, int len)
|
||||
{
|
||||
char *rv;
|
||||
|
||||
if (src == 0 && dest != 0)
|
||||
{
|
||||
dest[0] = 0;
|
||||
return dest;
|
||||
}
|
||||
|
||||
if (dest == 0 || src == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
rv = strncpy(dest, src, len);
|
||||
dest[len] = 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns dest */
|
||||
char *
|
||||
g_strcat(char *dest, const char *src)
|
||||
{
|
||||
if (dest == 0 || src == 0)
|
||||
{
|
||||
return dest;
|
||||
}
|
||||
|
||||
return strcat(dest, src);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* if in = 0, return 0 else return newly alloced copy of in */
|
||||
char *
|
||||
g_strdup(const char *in)
|
||||
{
|
||||
int len;
|
||||
char *p;
|
||||
|
||||
if (in == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = g_strlen(in);
|
||||
p = (char *)g_malloc(len + 1, 0);
|
||||
|
||||
if (p != NULL)
|
||||
{
|
||||
g_strcpy(p, in);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* if in = 0, return 0 else return newly alloced copy of input string
|
||||
* if the input string is larger than maxlen the returned string will be
|
||||
* truncated. All strings returned will include null termination*/
|
||||
char *
|
||||
g_strndup(const char *in, const unsigned int maxlen)
|
||||
{
|
||||
unsigned int len;
|
||||
char *p;
|
||||
|
||||
if (in == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = g_strlen(in);
|
||||
|
||||
if (len > maxlen)
|
||||
{
|
||||
len = maxlen - 1;
|
||||
}
|
||||
|
||||
p = (char *)g_malloc(len + 2, 0);
|
||||
|
||||
if (p != NULL)
|
||||
{
|
||||
g_strncpy(p, in, len + 1);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_strcmp(const char *c1, const char *c2)
|
||||
{
|
||||
return strcmp(c1, c2);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_strncmp(const char *c1, const char *c2, int len)
|
||||
{
|
||||
return strncmp(c1, c2, len);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* compare up to delim */
|
||||
int
|
||||
g_strncmp_d(const char *s1, const char *s2, const char delim, int n)
|
||||
{
|
||||
char c1;
|
||||
char c2;
|
||||
|
||||
c1 = 0;
|
||||
c2 = 0;
|
||||
while (n > 0)
|
||||
{
|
||||
c1 = *(s1++);
|
||||
c2 = *(s2++);
|
||||
if ((c1 == 0) || (c1 != c2) || (c1 == delim) || (c2 == delim))
|
||||
{
|
||||
return c1 - c2;
|
||||
}
|
||||
n--;
|
||||
}
|
||||
return c1 - c2;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_strcasecmp(const char *c1, const char *c2)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return stricmp(c1, c2);
|
||||
#else
|
||||
return strcasecmp(c1, c2);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_strncasecmp(const char *c1, const char *c2, int len)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return strnicmp(c1, c2, len);
|
||||
#else
|
||||
return strncasecmp(c1, c2, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_atoi(const char *str)
|
||||
{
|
||||
if (str == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return atoi(str);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_htoi(char *str)
|
||||
{
|
||||
int len;
|
||||
int index;
|
||||
int rv;
|
||||
int val;
|
||||
int shift;
|
||||
|
||||
rv = 0;
|
||||
len = strlen(str);
|
||||
index = len - 1;
|
||||
shift = 0;
|
||||
|
||||
while (index >= 0)
|
||||
{
|
||||
val = 0;
|
||||
|
||||
switch (str[index])
|
||||
{
|
||||
case '1':
|
||||
val = 1;
|
||||
break;
|
||||
case '2':
|
||||
val = 2;
|
||||
break;
|
||||
case '3':
|
||||
val = 3;
|
||||
break;
|
||||
case '4':
|
||||
val = 4;
|
||||
break;
|
||||
case '5':
|
||||
val = 5;
|
||||
break;
|
||||
case '6':
|
||||
val = 6;
|
||||
break;
|
||||
case '7':
|
||||
val = 7;
|
||||
break;
|
||||
case '8':
|
||||
val = 8;
|
||||
break;
|
||||
case '9':
|
||||
val = 9;
|
||||
break;
|
||||
case 'a':
|
||||
case 'A':
|
||||
val = 10;
|
||||
break;
|
||||
case 'b':
|
||||
case 'B':
|
||||
val = 11;
|
||||
break;
|
||||
case 'c':
|
||||
case 'C':
|
||||
val = 12;
|
||||
break;
|
||||
case 'd':
|
||||
case 'D':
|
||||
val = 13;
|
||||
break;
|
||||
case 'e':
|
||||
case 'E':
|
||||
val = 14;
|
||||
break;
|
||||
case 'f':
|
||||
case 'F':
|
||||
val = 15;
|
||||
break;
|
||||
}
|
||||
|
||||
rv = rv | (val << shift);
|
||||
index--;
|
||||
shift += 4;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns number of bytes copied into out_str */
|
||||
int
|
||||
g_bytes_to_hexstr(const void *bytes, int num_bytes, char *out_str,
|
||||
int bytes_out_str)
|
||||
{
|
||||
int rv;
|
||||
int index;
|
||||
char *lout_str;
|
||||
const tui8 *lbytes;
|
||||
|
||||
rv = 0;
|
||||
lbytes = (const tui8 *) bytes;
|
||||
lout_str = out_str;
|
||||
for (index = 0; index < num_bytes; index++)
|
||||
{
|
||||
if (bytes_out_str < 3)
|
||||
{
|
||||
break;
|
||||
}
|
||||
g_snprintf(lout_str, bytes_out_str, "%2.2x", lbytes[index]);
|
||||
lout_str += 2;
|
||||
bytes_out_str -= 2;
|
||||
rv += 2;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_pos(const char *str, const char *to_find)
|
||||
{
|
||||
const char *pp;
|
||||
|
||||
pp = strstr(str, to_find);
|
||||
|
||||
if (pp == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (pp - str);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_mbstowcs(twchar *dest, const char *src, int n)
|
||||
{
|
||||
wchar_t *ldest;
|
||||
int rv;
|
||||
|
||||
ldest = (wchar_t *)dest;
|
||||
rv = mbstowcs(ldest, src, n);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_wcstombs(char *dest, const twchar *src, int n)
|
||||
{
|
||||
const wchar_t *lsrc;
|
||||
int rv;
|
||||
|
||||
lsrc = (const wchar_t *)src;
|
||||
rv = wcstombs(dest, lsrc, n);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
/* trim spaces and tabs, anything <= space */
|
||||
/* trim_flags 1 trim left, 2 trim right, 3 trim both, 4 trim through */
|
||||
/* this will always shorten the string or not change it */
|
||||
int
|
||||
g_strtrim(char *str, int trim_flags)
|
||||
{
|
||||
int index;
|
||||
int len;
|
||||
int text1_index;
|
||||
int got_char;
|
||||
wchar_t *text;
|
||||
wchar_t *text1;
|
||||
|
||||
len = mbstowcs(0, str, 0);
|
||||
|
||||
if (len < 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((trim_flags < 1) || (trim_flags > 4))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
text = (wchar_t *)malloc(len * sizeof(wchar_t) + 8);
|
||||
text1 = (wchar_t *)malloc(len * sizeof(wchar_t) + 8);
|
||||
text1_index = 0;
|
||||
mbstowcs(text, str, len + 1);
|
||||
|
||||
switch (trim_flags)
|
||||
{
|
||||
case 4: /* trim through */
|
||||
|
||||
for (index = 0; index < len; index++)
|
||||
{
|
||||
if (text[index] > 32)
|
||||
{
|
||||
text1[text1_index] = text[index];
|
||||
text1_index++;
|
||||
}
|
||||
}
|
||||
|
||||
text1[text1_index] = 0;
|
||||
break;
|
||||
case 3: /* trim both */
|
||||
got_char = 0;
|
||||
|
||||
for (index = 0; index < len; index++)
|
||||
{
|
||||
if (got_char)
|
||||
{
|
||||
text1[text1_index] = text[index];
|
||||
text1_index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (text[index] > 32)
|
||||
{
|
||||
text1[text1_index] = text[index];
|
||||
text1_index++;
|
||||
got_char = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
text1[text1_index] = 0;
|
||||
len = text1_index;
|
||||
|
||||
/* trim right */
|
||||
for (index = len - 1; index >= 0; index--)
|
||||
{
|
||||
if (text1[index] > 32)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
text1_index = index + 1;
|
||||
text1[text1_index] = 0;
|
||||
break;
|
||||
case 2: /* trim right */
|
||||
|
||||
/* copy it */
|
||||
for (index = 0; index < len; index++)
|
||||
{
|
||||
text1[text1_index] = text[index];
|
||||
text1_index++;
|
||||
}
|
||||
|
||||
/* trim right */
|
||||
for (index = len - 1; index >= 0; index--)
|
||||
{
|
||||
if (text1[index] > 32)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
text1_index = index + 1;
|
||||
text1[text1_index] = 0;
|
||||
break;
|
||||
case 1: /* trim left */
|
||||
got_char = 0;
|
||||
|
||||
for (index = 0; index < len; index++)
|
||||
{
|
||||
if (got_char)
|
||||
{
|
||||
text1[text1_index] = text[index];
|
||||
text1_index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (text[index] > 32)
|
||||
{
|
||||
text1[text1_index] = text[index];
|
||||
text1_index++;
|
||||
got_char = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
text1[text1_index] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
wcstombs(str, text1, text1_index + 1);
|
||||
free(text);
|
||||
free(text1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
long
|
||||
g_load_library(char *in)
|
||||
@ -3267,6 +2795,17 @@ g_setsid(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_getlogin(char *name, unsigned int len)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return -1;
|
||||
#else
|
||||
return getlogin_r(name, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_setlogin(const char *name)
|
||||
@ -3379,7 +2918,7 @@ g_getenv(const char *name)
|
||||
int
|
||||
g_exit(int exit_code)
|
||||
{
|
||||
_exit(exit_code);
|
||||
exit(exit_code);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3720,21 +3259,6 @@ g_save_to_bmp(const char* filename, char* data, int stride_bytes,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns boolean */
|
||||
int
|
||||
g_text2bool(const char *s)
|
||||
{
|
||||
if ( (g_atoi(s) != 0) ||
|
||||
(0 == g_strcasecmp(s, "true")) ||
|
||||
(0 == g_strcasecmp(s, "on")) ||
|
||||
(0 == g_strcasecmp(s, "yes")))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns pointer or nil on error */
|
||||
void *
|
||||
@ -3823,3 +3347,153 @@ g_mirror_memcpy(void *dst, const void *src, int len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_tcp4_socket(void)
|
||||
{
|
||||
#if defined(XRDP_ENABLE_IPV6ONLY)
|
||||
return -1;
|
||||
#else
|
||||
int rv;
|
||||
int option_value;
|
||||
socklen_t option_len;
|
||||
|
||||
rv = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (rv < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
option_len = sizeof(option_value);
|
||||
if (getsockopt(rv, SOL_SOCKET, SO_REUSEADDR,
|
||||
(char *) &option_value, &option_len) == 0)
|
||||
{
|
||||
if (option_value == 0)
|
||||
{
|
||||
option_value = 1;
|
||||
option_len = sizeof(option_value);
|
||||
if (setsockopt(rv, SOL_SOCKET, SO_REUSEADDR,
|
||||
(char *) &option_value, option_len) < 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_tcp4_bind_address(int sck, const char *port, const char *address)
|
||||
{
|
||||
#if defined(XRDP_ENABLE_IPV6ONLY)
|
||||
return -1;
|
||||
#else
|
||||
struct sockaddr_in s;
|
||||
|
||||
memset(&s, 0, sizeof(s));
|
||||
s.sin_family = AF_INET;
|
||||
s.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
s.sin_port = htons((uint16_t) atoi(port));
|
||||
if (inet_aton(address, &s.sin_addr) < 0)
|
||||
{
|
||||
return -1; /* bad address */
|
||||
}
|
||||
if (bind(sck, (struct sockaddr*) &s, sizeof(s)) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_tcp6_socket(void)
|
||||
{
|
||||
#if defined(XRDP_ENABLE_IPV6)
|
||||
int rv;
|
||||
int option_value;
|
||||
socklen_t option_len;
|
||||
|
||||
rv = socket(AF_INET6, SOCK_STREAM, 0);
|
||||
if (rv < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
option_len = sizeof(option_value);
|
||||
if (getsockopt(rv, IPPROTO_IPV6, IPV6_V6ONLY,
|
||||
(char *) &option_value, &option_len) == 0)
|
||||
{
|
||||
#if defined(XRDP_ENABLE_IPV6ONLY)
|
||||
if (option_value == 0)
|
||||
{
|
||||
option_value = 1;
|
||||
#else
|
||||
if (option_value != 0)
|
||||
{
|
||||
option_value = 0;
|
||||
#endif
|
||||
option_len = sizeof(option_value);
|
||||
if (setsockopt(rv, IPPROTO_IPV6, IPV6_V6ONLY,
|
||||
(char *) &option_value, option_len) < 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
option_len = sizeof(option_value);
|
||||
if (getsockopt(rv, SOL_SOCKET, SO_REUSEADDR,
|
||||
(char *) &option_value, &option_len) == 0)
|
||||
{
|
||||
if (option_value == 0)
|
||||
{
|
||||
option_value = 1;
|
||||
option_len = sizeof(option_value);
|
||||
if (setsockopt(rv, SOL_SOCKET, SO_REUSEADDR,
|
||||
(char *) &option_value, option_len) < 0)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_tcp6_bind_address(int sck, const char *port, const char *address)
|
||||
{
|
||||
#if defined(XRDP_ENABLE_IPV6)
|
||||
int rv;
|
||||
int error;
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *list;
|
||||
struct addrinfo *i;
|
||||
|
||||
rv = -1;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_flags = 0;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
error = getaddrinfo(address, port, &hints, &list);
|
||||
if (error == 0)
|
||||
{
|
||||
i = list;
|
||||
while ((i != NULL) && (rv < 0))
|
||||
{
|
||||
rv = bind(sck, i->ai_addr, i->ai_addrlen);
|
||||
i = i->ai_next;
|
||||
}
|
||||
freeaddrinfo(list);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return rv;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
@ -71,6 +71,7 @@ int g_sck_set_non_blocking(int sck);
|
||||
int g_tcp_bind(int sck, const char *port);
|
||||
int g_sck_local_bind(int sck, const char* port);
|
||||
int g_sck_vsock_bind(int sck, const char* port);
|
||||
int g_sck_vsock_bind_address(int sck, const char *port, const char *address);
|
||||
int g_tcp_bind_address(int sck, const char* port, const char* address);
|
||||
int g_sck_listen(int sck);
|
||||
int g_tcp_accept(int sck);
|
||||
@ -118,26 +119,6 @@ int g_create_path(const char* path);
|
||||
int g_remove_dir(const char* dirname);
|
||||
int g_file_delete(const char* filename);
|
||||
int g_file_get_size(const char* filename);
|
||||
int g_strlen(const char* text);
|
||||
const char *g_strchr(const char *text, int c);
|
||||
char* g_strcpy(char* dest, const char* src);
|
||||
char* g_strncpy(char* dest, const char* src, int len);
|
||||
char* g_strcat(char* dest, const char* src);
|
||||
char* g_strdup(const char* in);
|
||||
char* g_strndup(const char* in, const unsigned int maxlen);
|
||||
int g_strcmp(const char* c1, const char* c2);
|
||||
int g_strncmp(const char* c1, const char* c2, int len);
|
||||
int g_strncmp_d(const char* c1, const char* c2, const char delim, int len);
|
||||
int g_strcasecmp(const char* c1, const char* c2);
|
||||
int g_strncasecmp(const char* c1, const char* c2, int len);
|
||||
int g_atoi(const char* str);
|
||||
int g_htoi(char* str);
|
||||
int g_bytes_to_hexstr(const void *bytes, int num_bytes, char *out_str,
|
||||
int bytes_out_str);
|
||||
int g_pos(const char* str, const char* to_find);
|
||||
int g_mbstowcs(twchar* dest, const char* src, int n);
|
||||
int g_wcstombs(char* dest, const twchar* src, int n);
|
||||
int g_strtrim(char* str, int trim_flags);
|
||||
long g_load_library(char* in);
|
||||
int g_free_library(long lib);
|
||||
void* g_get_proc_address(long lib, const char* name);
|
||||
@ -160,6 +141,7 @@ int g_getuid(void);
|
||||
int g_getgid(void);
|
||||
int g_setuid(int pid);
|
||||
int g_setsid(void);
|
||||
int g_getlogin(char *name, unsigned int len);
|
||||
int g_setlogin(const char *name);
|
||||
int g_waitchild(void);
|
||||
int g_waitpid(int pid);
|
||||
@ -178,11 +160,14 @@ int g_time2(void);
|
||||
int g_time3(void);
|
||||
int g_save_to_bmp(const char* filename, char* data, int stride_bytes,
|
||||
int width, int height, int depth, int bits_per_pixel);
|
||||
int g_text2bool(const char *s);
|
||||
void * g_shmat(int shmid);
|
||||
int g_shmdt(const void *shmaddr);
|
||||
int g_gethostname(char *name, int len);
|
||||
int g_mirror_memcpy(void *dst, const void *src, int len);
|
||||
int g_tcp4_socket(void);
|
||||
int g_tcp4_bind_address(int sck, const char *port, const char *address);
|
||||
int g_tcp6_socket(void);
|
||||
int g_tcp6_bind_address(int sck, const char *port, const char *address);
|
||||
|
||||
/* glib-style wrappers */
|
||||
#define g_new(struct_type, n_structs) \
|
||||
|
@ -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 \
|
||||
{ \
|
||||
@ -1791,7 +1799,10 @@ validate (region_type_t * badreg)
|
||||
*badreg = ri[0].reg;
|
||||
|
||||
if (ri != stack_regions)
|
||||
{
|
||||
/* cppcheck-suppress autovarInvalidDeallocation */
|
||||
free (ri);
|
||||
}
|
||||
|
||||
GOOD (badreg);
|
||||
return ret;
|
||||
@ -1801,7 +1812,10 @@ bail:
|
||||
FREE_DATA (&ri[i].reg);
|
||||
|
||||
if (ri != stack_regions)
|
||||
{
|
||||
/* cppcheck-suppress autovarInvalidDeallocation */
|
||||
free (ri);
|
||||
}
|
||||
|
||||
return pixman_break (badreg);
|
||||
}
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
#include "os_calls.h"
|
||||
#include "string_calls.h"
|
||||
#include "arch.h"
|
||||
#include "ssl_calls.h"
|
||||
#include "trans.h"
|
||||
@ -229,7 +230,7 @@ ssl_md5_complete(void *md5_info, char *data)
|
||||
|
||||
/*****************************************************************************/
|
||||
void *
|
||||
ssl_des3_encrypt_info_create(const char *key, const char* ivec)
|
||||
ssl_des3_encrypt_info_create(const char *key, const char *ivec)
|
||||
{
|
||||
EVP_CIPHER_CTX *des3_ctx;
|
||||
const tui8 *lkey;
|
||||
@ -245,7 +246,7 @@ ssl_des3_encrypt_info_create(const char *key, const char* ivec)
|
||||
|
||||
/*****************************************************************************/
|
||||
void *
|
||||
ssl_des3_decrypt_info_create(const char *key, const char* ivec)
|
||||
ssl_des3_decrypt_info_create(const char *key, const char *ivec)
|
||||
{
|
||||
EVP_CIPHER_CTX *des3_ctx;
|
||||
const tui8 *lkey;
|
||||
@ -347,7 +348,7 @@ ssl_hmac_transform(void *hmac, const char *data, int len)
|
||||
const tui8 *ldata;
|
||||
|
||||
hmac_ctx = (HMAC_CTX *) hmac;
|
||||
ldata = (const tui8*) data;
|
||||
ldata = (const tui8 *) data;
|
||||
HMAC_Update(hmac_ctx, ldata, len);
|
||||
}
|
||||
|
||||
@ -356,7 +357,7 @@ void
|
||||
ssl_hmac_complete(void *hmac, char *data, int len)
|
||||
{
|
||||
HMAC_CTX *hmac_ctx;
|
||||
tui8* ldata;
|
||||
tui8 *ldata;
|
||||
tui32 llen;
|
||||
|
||||
hmac_ctx = (HMAC_CTX *) hmac;
|
||||
@ -531,7 +532,8 @@ see also
|
||||
*/
|
||||
static DH *ssl_get_dh2236()
|
||||
{
|
||||
static unsigned char dh2236_p[] = {
|
||||
static unsigned char dh2236_p[] =
|
||||
{
|
||||
0x0E, 0xF8, 0x69, 0x0B, 0x35, 0x2F, 0x62, 0x59, 0xF7, 0xAF, 0x4E, 0x19,
|
||||
0xB5, 0x9B, 0xD2, 0xEB, 0x33, 0x78, 0x1D, 0x43, 0x1D, 0xB6, 0xE4, 0xA3,
|
||||
0x63, 0x47, 0x6A, 0xD4, 0xA8, 0x28, 0x11, 0x8C, 0x3F, 0xC8, 0xF1, 0x32,
|
||||
@ -557,7 +559,8 @@ static DH *ssl_get_dh2236()
|
||||
0x70, 0xAC, 0x58, 0x3A, 0x3C, 0x18, 0x15, 0x54, 0x84, 0xA8, 0xAA, 0x41,
|
||||
0x26, 0x7B, 0xE0, 0xA3,
|
||||
};
|
||||
static unsigned char dh2236_g[] = {
|
||||
static unsigned char dh2236_g[] =
|
||||
{
|
||||
0x02,
|
||||
};
|
||||
|
||||
@ -612,14 +615,13 @@ ssl_tls_create(struct trans *trans, const char *key, const char *cert)
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
ssl_tls_print_error(const char *func, SSL *connection, int value)
|
||||
static int
|
||||
ssl_tls_log_error(const char *func, SSL *connection, int value)
|
||||
{
|
||||
switch (SSL_get_error(connection, value))
|
||||
{
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
g_writeln("ssl_tls_print_error: %s: Server closed TLS connection",
|
||||
func);
|
||||
LOG(LOG_LEVEL_ERROR, "%s: Server closed TLS connection", func);
|
||||
return 1;
|
||||
|
||||
case SSL_ERROR_WANT_READ:
|
||||
@ -627,16 +629,15 @@ ssl_tls_print_error(const char *func, SSL *connection, int value)
|
||||
return 0;
|
||||
|
||||
case SSL_ERROR_SYSCALL:
|
||||
g_writeln("ssl_tls_print_error: %s: I/O error", func);
|
||||
LOG(LOG_LEVEL_ERROR, "%s: I/O error", func);
|
||||
return 1;
|
||||
|
||||
case SSL_ERROR_SSL:
|
||||
g_writeln("ssl_tls_print_error: %s: Failure in SSL library (protocol error?)",
|
||||
func);
|
||||
LOG(LOG_LEVEL_ERROR, "%s: Failure in SSL library (protocol error?)", func);
|
||||
return 1;
|
||||
|
||||
default:
|
||||
g_writeln("ssl_tls_print_error: %s: Unknown error", func);
|
||||
LOG(LOG_LEVEL_ERROR, "%s: Unknown SSL error", func);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -693,7 +694,7 @@ ssl_tls_accept(struct ssl_tls *self, long ssl_protocols,
|
||||
self->ctx = SSL_CTX_new(SSLv23_server_method());
|
||||
if (self->ctx == NULL)
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR, "ssl_tls_accept: SSL_CTX_new failed");
|
||||
LOG(LOG_LEVEL_ERROR, "Unable to negotiate a TLS connection with the client");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -707,45 +708,46 @@ ssl_tls_accept(struct ssl_tls *self, long ssl_protocols,
|
||||
DH *dh = ssl_get_dh2236();
|
||||
if (dh == NULL)
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR, "ssl_tls_accept: ssl_get_dh2236 failed");
|
||||
LOG(LOG_LEVEL_ERROR, "Unable to generate DHE parameters for TLS");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (SSL_CTX_set_tmp_dh(self->ctx, dh) != 1)
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR,
|
||||
"ssl_tls_accept: SSL_CTX_set_tmp_dh failed");
|
||||
LOG(LOG_LEVEL_ERROR, "Unable to setup DHE parameters for TLS");
|
||||
return 1;
|
||||
}
|
||||
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)
|
||||
{
|
||||
log_message(LOG_LEVEL_TRACE, "ssl_tls_accept: tls_ciphers=%s",
|
||||
tls_ciphers);
|
||||
LOG(LOG_LEVEL_TRACE, "tls_ciphers=%s", tls_ciphers);
|
||||
if (SSL_CTX_set_cipher_list(self->ctx, tls_ciphers) == 0)
|
||||
{
|
||||
g_writeln("ssl_tls_accept: invalid cipher options");
|
||||
LOG(LOG_LEVEL_ERROR, "Invalid TLS cipher options %s", tls_ciphers);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
SSL_CTX_set_read_ahead(self->ctx, 0);
|
||||
|
||||
if (SSL_CTX_use_RSAPrivateKey_file(self->ctx, self->key, SSL_FILETYPE_PEM)
|
||||
if (SSL_CTX_use_PrivateKey_file(self->ctx, self->key, SSL_FILETYPE_PEM)
|
||||
<= 0)
|
||||
{
|
||||
g_writeln("ssl_tls_accept: SSL_CTX_use_RSAPrivateKey_file failed");
|
||||
LOG(LOG_LEVEL_ERROR, "Error loading TLS private key from %s", self->key);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (SSL_CTX_use_certificate_chain_file(self->ctx, self->cert) <= 0)
|
||||
{
|
||||
g_writeln("ssl_tls_accept: SSL_CTX_use_certificate_chain_file failed");
|
||||
LOG(LOG_LEVEL_ERROR, "Error loading TLS certificate chain from %s", self->cert);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -753,22 +755,24 @@ ssl_tls_accept(struct ssl_tls *self, long ssl_protocols,
|
||||
|
||||
if (self->ssl == NULL)
|
||||
{
|
||||
g_writeln("ssl_tls_accept: SSL_new failed");
|
||||
LOG(LOG_LEVEL_ERROR, "Unable to create an SSL structure");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (SSL_set_fd(self->ssl, self->trans->sck) < 1)
|
||||
{
|
||||
g_writeln("ssl_tls_accept: SSL_set_fd failed");
|
||||
LOG(LOG_LEVEL_ERROR, "Unable to set up an SSL structure on fd %d",
|
||||
(int)self->trans->sck);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
while (1)
|
||||
{
|
||||
connection_status = SSL_accept(self->ssl);
|
||||
|
||||
if (connection_status <= 0)
|
||||
{
|
||||
if (ssl_tls_print_error("SSL_accept", self->ssl, connection_status))
|
||||
if (ssl_tls_log_error("SSL_accept", self->ssl, connection_status))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@ -793,7 +797,7 @@ ssl_tls_accept(struct ssl_tls *self, long ssl_protocols,
|
||||
}
|
||||
}
|
||||
|
||||
g_writeln("ssl_tls_accept: TLS connection accepted");
|
||||
LOG(LOG_LEVEL_TRACE, "TLS connection accepted");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -819,7 +823,7 @@ ssl_tls_disconnect(struct ssl_tls *self)
|
||||
status = SSL_shutdown(self->ssl);
|
||||
if (status <= 0)
|
||||
{
|
||||
if (ssl_tls_print_error("SSL_shutdown", self->ssl, status))
|
||||
if (ssl_tls_log_error("SSL_shutdown", self->ssl, status))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@ -840,10 +844,14 @@ ssl_tls_delete(struct ssl_tls *self)
|
||||
if (self != NULL)
|
||||
{
|
||||
if (self->ssl)
|
||||
{
|
||||
SSL_free(self->ssl);
|
||||
}
|
||||
|
||||
if (self->ctx)
|
||||
{
|
||||
SSL_CTX_free(self->ctx);
|
||||
}
|
||||
|
||||
g_delete_wait_obj(self->rwo);
|
||||
|
||||
@ -858,7 +866,8 @@ ssl_tls_read(struct ssl_tls *tls, char *data, int length)
|
||||
int status;
|
||||
int break_flag;
|
||||
|
||||
while(1) {
|
||||
while (1)
|
||||
{
|
||||
status = SSL_read(tls->ssl, data, length);
|
||||
|
||||
switch (SSL_get_error(tls->ssl, status))
|
||||
@ -884,7 +893,7 @@ ssl_tls_read(struct ssl_tls *tls, char *data, int length)
|
||||
return 0;
|
||||
|
||||
default:
|
||||
ssl_tls_print_error("SSL_read", tls->ssl, status);
|
||||
ssl_tls_log_error("SSL_read", tls->ssl, status);
|
||||
status = -1;
|
||||
break_flag = 1;
|
||||
break;
|
||||
@ -911,7 +920,8 @@ ssl_tls_write(struct ssl_tls *tls, const char *data, int length)
|
||||
int status;
|
||||
int break_flag;
|
||||
|
||||
while(1) {
|
||||
while (1)
|
||||
{
|
||||
status = SSL_write(tls->ssl, data, length);
|
||||
|
||||
switch (SSL_get_error(tls->ssl, status))
|
||||
@ -937,7 +947,7 @@ ssl_tls_write(struct ssl_tls *tls, const char *data, int length)
|
||||
return 0;
|
||||
|
||||
default:
|
||||
ssl_tls_print_error("SSL_write", tls->ssl, status);
|
||||
ssl_tls_log_error("SSL_write", tls->ssl, status);
|
||||
status = -1;
|
||||
break_flag = 1;
|
||||
break;
|
||||
@ -1012,10 +1022,10 @@ ssl_get_protocols_from_string(const char *str, long *ssl_protocols)
|
||||
if (g_pos(str, ",TLSv1.3,") >= 0)
|
||||
{
|
||||
#if defined(SSL_OP_NO_TLSv1_3)
|
||||
log_message(LOG_LEVEL_DEBUG, "TLSv1.3 enabled");
|
||||
LOG(LOG_LEVEL_DEBUG, "TLSv1.3 enabled");
|
||||
protocols &= ~SSL_OP_NO_TLSv1_3;
|
||||
#else
|
||||
log_message(LOG_LEVEL_WARNING,
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"TLSv1.3 enabled by config, "
|
||||
"but not supported by system OpenSSL");
|
||||
rv |= (1 << 6);
|
||||
@ -1024,10 +1034,10 @@ ssl_get_protocols_from_string(const char *str, long *ssl_protocols)
|
||||
if (g_pos(str, ",TLSv1.2,") >= 0)
|
||||
{
|
||||
#if defined(SSL_OP_NO_TLSv1_2)
|
||||
log_message(LOG_LEVEL_DEBUG, "TLSv1.2 enabled");
|
||||
LOG(LOG_LEVEL_DEBUG, "TLSv1.2 enabled");
|
||||
protocols &= ~SSL_OP_NO_TLSv1_2;
|
||||
#else
|
||||
log_message(LOG_LEVEL_WARNING,
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"TLSv1.2 enabled by config, "
|
||||
"but not supported by system OpenSSL");
|
||||
rv |= (1 << 1);
|
||||
@ -1036,10 +1046,10 @@ ssl_get_protocols_from_string(const char *str, long *ssl_protocols)
|
||||
if (g_pos(str, ",TLSv1.1,") >= 0)
|
||||
{
|
||||
#if defined(SSL_OP_NO_TLSv1_1)
|
||||
log_message(LOG_LEVEL_DEBUG, "TLSv1.1 enabled");
|
||||
LOG(LOG_LEVEL_DEBUG, "TLSv1.1 enabled");
|
||||
protocols &= ~SSL_OP_NO_TLSv1_1;
|
||||
#else
|
||||
log_message(LOG_LEVEL_WARNING,
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"TLSv1.1 enabled by config, "
|
||||
"but not supported by system OpenSSL");
|
||||
rv |= (1 << 2);
|
||||
@ -1048,10 +1058,10 @@ ssl_get_protocols_from_string(const char *str, long *ssl_protocols)
|
||||
if (g_pos(str, ",TLSv1,") >= 0)
|
||||
{
|
||||
#if defined(SSL_OP_NO_TLSv1)
|
||||
log_message(LOG_LEVEL_DEBUG, "TLSv1 enabled");
|
||||
LOG(LOG_LEVEL_DEBUG, "TLSv1 enabled");
|
||||
protocols &= ~SSL_OP_NO_TLSv1;
|
||||
#else
|
||||
log_message(LOG_LEVEL_WARNING,
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"TLSv1 enabled by config, "
|
||||
"but not supported by system OpenSSL");
|
||||
rv |= (1 << 3);
|
||||
@ -1060,10 +1070,10 @@ ssl_get_protocols_from_string(const char *str, long *ssl_protocols)
|
||||
if (g_pos(str, ",SSLv3,") >= 0)
|
||||
{
|
||||
#if defined(SSL_OP_NO_SSLv3)
|
||||
log_message(LOG_LEVEL_DEBUG, "SSLv3 enabled");
|
||||
LOG(LOG_LEVEL_DEBUG, "SSLv3 enabled");
|
||||
protocols &= ~SSL_OP_NO_SSLv3;
|
||||
#else
|
||||
log_message(LOG_LEVEL_WARNING,
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"SSLv3 enabled by config, "
|
||||
"but not supported by system OpenSSL");
|
||||
rv |= (1 << 4);
|
||||
@ -1071,7 +1081,7 @@ ssl_get_protocols_from_string(const char *str, long *ssl_protocols)
|
||||
}
|
||||
if (protocols == bad_protocols)
|
||||
{
|
||||
log_message(LOG_LEVEL_WARNING, "No SSL/TLS protocols enabled. "
|
||||
LOG(LOG_LEVEL_WARNING, "No SSL/TLS protocols enabled. "
|
||||
"At least one protocol should be enabled to accept "
|
||||
"TLS connections.");
|
||||
rv |= (1 << 5);
|
||||
|
@ -26,38 +26,38 @@ int
|
||||
ssl_init(void);
|
||||
int
|
||||
ssl_finish(void);
|
||||
void*
|
||||
void *
|
||||
ssl_rc4_info_create(void);
|
||||
void
|
||||
ssl_rc4_info_delete(void* rc4_info);
|
||||
ssl_rc4_info_delete(void *rc4_info);
|
||||
void
|
||||
ssl_rc4_set_key(void* rc4_info, char* key, int len);
|
||||
ssl_rc4_set_key(void *rc4_info, char *key, int len);
|
||||
void
|
||||
ssl_rc4_crypt(void* rc4_info, char* data, int len);
|
||||
void*
|
||||
ssl_rc4_crypt(void *rc4_info, char *data, int len);
|
||||
void *
|
||||
ssl_sha1_info_create(void);
|
||||
void
|
||||
ssl_sha1_info_delete(void* sha1_info);
|
||||
ssl_sha1_info_delete(void *sha1_info);
|
||||
void
|
||||
ssl_sha1_clear(void* sha1_info);
|
||||
ssl_sha1_clear(void *sha1_info);
|
||||
void
|
||||
ssl_sha1_transform(void* sha1_info, const char *data, int len);
|
||||
ssl_sha1_transform(void *sha1_info, const char *data, int len);
|
||||
void
|
||||
ssl_sha1_complete(void* sha1_info, char* data);
|
||||
void*
|
||||
ssl_sha1_complete(void *sha1_info, char *data);
|
||||
void *
|
||||
ssl_md5_info_create(void);
|
||||
void
|
||||
ssl_md5_info_delete(void* md5_info);
|
||||
ssl_md5_info_delete(void *md5_info);
|
||||
void
|
||||
ssl_md5_clear(void* md5_info);
|
||||
ssl_md5_clear(void *md5_info);
|
||||
void
|
||||
ssl_md5_transform(void* md5_info, char* data, int len);
|
||||
ssl_md5_transform(void *md5_info, char *data, int len);
|
||||
void
|
||||
ssl_md5_complete(void* md5_info, char* data);
|
||||
ssl_md5_complete(void *md5_info, char *data);
|
||||
void *
|
||||
ssl_des3_encrypt_info_create(const char *key, const char* ivec);
|
||||
ssl_des3_encrypt_info_create(const char *key, const char *ivec);
|
||||
void *
|
||||
ssl_des3_decrypt_info_create(const char *key, const char* ivec);
|
||||
ssl_des3_decrypt_info_create(const char *key, const char *ivec);
|
||||
void
|
||||
ssl_des3_info_delete(void *des3);
|
||||
int
|
||||
@ -78,8 +78,8 @@ int
|
||||
ssl_mod_exp(char *out, int out_len, const char *in, int in_len,
|
||||
const char *mod, int mod_len, const char *exp, int exp_len);
|
||||
int
|
||||
ssl_gen_key_xrdp1(int key_size_in_bits, const char* exp, int exp_len,
|
||||
char* mod, int mod_len, char* pri, int pri_len);
|
||||
ssl_gen_key_xrdp1(int key_size_in_bits, const char *exp, int exp_len,
|
||||
char *mod, int mod_len, char *pri, int pri_len);
|
||||
|
||||
/* ssl_tls */
|
||||
struct ssl_tls
|
||||
|
653
common/string_calls.c
Normal file
653
common/string_calls.c
Normal file
@ -0,0 +1,653 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Copyright (C) Jay Sorg 2004-2020
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* generic string handling calls
|
||||
*/
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include "config_ac.h"
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "string_calls.h"
|
||||
#include "os_calls.h"
|
||||
|
||||
unsigned int
|
||||
g_format_info_string(char *dest, unsigned int len,
|
||||
const char *format,
|
||||
const struct info_string_tag map[])
|
||||
{
|
||||
unsigned int result = 0;
|
||||
const char *copy_from; /* Data to add to output */
|
||||
unsigned int copy_len; /* Length of above */
|
||||
unsigned int skip; /* Date to skip over in format string */
|
||||
const char *p;
|
||||
const struct info_string_tag *m;
|
||||
|
||||
for ( ; *format != '\0'; format += skip)
|
||||
{
|
||||
if (*format == '%')
|
||||
{
|
||||
char ch = *(format + 1);
|
||||
if (ch == '%')
|
||||
{
|
||||
/* '%%' in format - replace with single '%' */
|
||||
copy_from = format;
|
||||
copy_len = 1;
|
||||
skip = 2;
|
||||
}
|
||||
else if (ch == '\0')
|
||||
{
|
||||
/* Percent at end of string - ignore */
|
||||
copy_from = NULL;
|
||||
copy_len = 0;
|
||||
skip = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Look up the character in the map, assuming failure */
|
||||
copy_from = NULL;
|
||||
copy_len = 0;
|
||||
skip = 2;
|
||||
|
||||
for (m = map ; m->ch != '\0' ; ++m)
|
||||
{
|
||||
if (ch == m->ch)
|
||||
{
|
||||
copy_from = m->val;
|
||||
copy_len = strlen(copy_from);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((p = strchr(format, '%')) != NULL)
|
||||
{
|
||||
/* Copy up to the next '%' */
|
||||
copy_from = format;
|
||||
copy_len = p - format;
|
||||
skip = copy_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy the rest of the format string */
|
||||
copy_from = format;
|
||||
copy_len = strlen(format);
|
||||
skip = copy_len;
|
||||
}
|
||||
|
||||
/* Update the result before any truncation */
|
||||
result += copy_len;
|
||||
|
||||
/* Do we have room in the output buffer for any more data? We
|
||||
* must always write a terminator if possible */
|
||||
if (len > 1)
|
||||
{
|
||||
if (copy_len > (len - 1))
|
||||
{
|
||||
copy_len = len - 1;
|
||||
}
|
||||
memcpy(dest, copy_from, copy_len);
|
||||
dest += copy_len;
|
||||
len -= copy_len;
|
||||
}
|
||||
}
|
||||
|
||||
/* Room for a terminator? */
|
||||
if (len > 0)
|
||||
{
|
||||
*dest = '\0';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
const char *
|
||||
g_bool2text(int value)
|
||||
{
|
||||
return value ? "true" : "false";
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_text2bool(const char *s)
|
||||
{
|
||||
if ( (g_atoi(s) != 0) ||
|
||||
(0 == g_strcasecmp(s, "true")) ||
|
||||
(0 == g_strcasecmp(s, "on")) ||
|
||||
(0 == g_strcasecmp(s, "yes")))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns length of text */
|
||||
int
|
||||
g_strlen(const char *text)
|
||||
{
|
||||
if (text == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return strlen(text);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* locates char in text */
|
||||
const char *
|
||||
g_strchr(const char *text, int c)
|
||||
{
|
||||
if (text == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return strchr(text, c);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns dest */
|
||||
char *
|
||||
g_strcpy(char *dest, const char *src)
|
||||
{
|
||||
if (src == 0 && dest != 0)
|
||||
{
|
||||
dest[0] = 0;
|
||||
return dest;
|
||||
}
|
||||
|
||||
if (dest == 0 || src == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return strcpy(dest, src);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns dest */
|
||||
char *
|
||||
g_strncpy(char *dest, const char *src, int len)
|
||||
{
|
||||
char *rv;
|
||||
|
||||
if (src == 0 && dest != 0)
|
||||
{
|
||||
dest[0] = 0;
|
||||
return dest;
|
||||
}
|
||||
|
||||
if (dest == 0 || src == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
rv = strncpy(dest, src, len);
|
||||
dest[len] = 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns dest */
|
||||
char *
|
||||
g_strcat(char *dest, const char *src)
|
||||
{
|
||||
if (dest == 0 || src == 0)
|
||||
{
|
||||
return dest;
|
||||
}
|
||||
|
||||
return strcat(dest, src);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns dest */
|
||||
char *
|
||||
g_strncat(char *dest, const char *src, int len)
|
||||
{
|
||||
if (dest == 0 || src == 0)
|
||||
{
|
||||
return dest;
|
||||
}
|
||||
|
||||
return strncat(dest, src, len);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* if in = 0, return 0 else return newly alloced copy of in */
|
||||
char *
|
||||
g_strdup(const char *in)
|
||||
{
|
||||
int len;
|
||||
char *p;
|
||||
|
||||
if (in == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = g_strlen(in);
|
||||
p = (char *)g_malloc(len + 1, 0);
|
||||
|
||||
if (p != NULL)
|
||||
{
|
||||
g_strcpy(p, in);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* if in = 0, return 0 else return newly alloced copy of input string
|
||||
* if the input string is larger than maxlen the returned string will be
|
||||
* truncated. All strings returned will include null termination*/
|
||||
char *
|
||||
g_strndup(const char *in, const unsigned int maxlen)
|
||||
{
|
||||
unsigned int len;
|
||||
char *p;
|
||||
|
||||
if (in == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = g_strlen(in);
|
||||
|
||||
if (len > maxlen)
|
||||
{
|
||||
len = maxlen - 1;
|
||||
}
|
||||
|
||||
p = (char *)g_malloc(len + 2, 0);
|
||||
|
||||
if (p != NULL)
|
||||
{
|
||||
g_strncpy(p, in, len + 1);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_strcmp(const char *c1, const char *c2)
|
||||
{
|
||||
return strcmp(c1, c2);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_strncmp(const char *c1, const char *c2, int len)
|
||||
{
|
||||
return strncmp(c1, c2, len);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* compare up to delim */
|
||||
int
|
||||
g_strncmp_d(const char *s1, const char *s2, const char delim, int n)
|
||||
{
|
||||
char c1;
|
||||
char c2;
|
||||
|
||||
c1 = 0;
|
||||
c2 = 0;
|
||||
while (n > 0)
|
||||
{
|
||||
c1 = *(s1++);
|
||||
c2 = *(s2++);
|
||||
if ((c1 == 0) || (c1 != c2) || (c1 == delim) || (c2 == delim))
|
||||
{
|
||||
return c1 - c2;
|
||||
}
|
||||
n--;
|
||||
}
|
||||
return c1 - c2;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_strcasecmp(const char *c1, const char *c2)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return stricmp(c1, c2);
|
||||
#else
|
||||
return strcasecmp(c1, c2);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_strncasecmp(const char *c1, const char *c2, int len)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return strnicmp(c1, c2, len);
|
||||
#else
|
||||
return strncasecmp(c1, c2, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_atoi(const char *str)
|
||||
{
|
||||
if (str == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return atoi(str);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_htoi(char *str)
|
||||
{
|
||||
int len;
|
||||
int index;
|
||||
int rv;
|
||||
int val;
|
||||
int shift;
|
||||
|
||||
rv = 0;
|
||||
len = strlen(str);
|
||||
index = len - 1;
|
||||
shift = 0;
|
||||
|
||||
while (index >= 0)
|
||||
{
|
||||
val = 0;
|
||||
|
||||
switch (str[index])
|
||||
{
|
||||
case '1':
|
||||
val = 1;
|
||||
break;
|
||||
case '2':
|
||||
val = 2;
|
||||
break;
|
||||
case '3':
|
||||
val = 3;
|
||||
break;
|
||||
case '4':
|
||||
val = 4;
|
||||
break;
|
||||
case '5':
|
||||
val = 5;
|
||||
break;
|
||||
case '6':
|
||||
val = 6;
|
||||
break;
|
||||
case '7':
|
||||
val = 7;
|
||||
break;
|
||||
case '8':
|
||||
val = 8;
|
||||
break;
|
||||
case '9':
|
||||
val = 9;
|
||||
break;
|
||||
case 'a':
|
||||
case 'A':
|
||||
val = 10;
|
||||
break;
|
||||
case 'b':
|
||||
case 'B':
|
||||
val = 11;
|
||||
break;
|
||||
case 'c':
|
||||
case 'C':
|
||||
val = 12;
|
||||
break;
|
||||
case 'd':
|
||||
case 'D':
|
||||
val = 13;
|
||||
break;
|
||||
case 'e':
|
||||
case 'E':
|
||||
val = 14;
|
||||
break;
|
||||
case 'f':
|
||||
case 'F':
|
||||
val = 15;
|
||||
break;
|
||||
}
|
||||
|
||||
rv = rv | (val << shift);
|
||||
index--;
|
||||
shift += 4;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns number of bytes copied into out_str */
|
||||
int
|
||||
g_bytes_to_hexstr(const void *bytes, int num_bytes, char *out_str,
|
||||
int bytes_out_str)
|
||||
{
|
||||
int rv;
|
||||
int index;
|
||||
char *lout_str;
|
||||
const tui8 *lbytes;
|
||||
|
||||
rv = 0;
|
||||
lbytes = (const tui8 *) bytes;
|
||||
lout_str = out_str;
|
||||
for (index = 0; index < num_bytes; index++)
|
||||
{
|
||||
if (bytes_out_str < 3)
|
||||
{
|
||||
break;
|
||||
}
|
||||
g_snprintf(lout_str, bytes_out_str, "%2.2x", lbytes[index]);
|
||||
lout_str += 2;
|
||||
bytes_out_str -= 2;
|
||||
rv += 2;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_pos(const char *str, const char *to_find)
|
||||
{
|
||||
const char *pp;
|
||||
|
||||
pp = strstr(str, to_find);
|
||||
|
||||
if (pp == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (pp - str);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_mbstowcs(twchar *dest, const char *src, int n)
|
||||
{
|
||||
wchar_t *ldest;
|
||||
int rv;
|
||||
|
||||
ldest = (wchar_t *)dest;
|
||||
rv = mbstowcs(ldest, src, n);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
g_wcstombs(char *dest, const twchar *src, int n)
|
||||
{
|
||||
const wchar_t *lsrc;
|
||||
int rv;
|
||||
|
||||
lsrc = (const wchar_t *)src;
|
||||
rv = wcstombs(dest, lsrc, n);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
/* trim spaces and tabs, anything <= space */
|
||||
/* trim_flags 1 trim left, 2 trim right, 3 trim both, 4 trim through */
|
||||
/* this will always shorten the string or not change it */
|
||||
int
|
||||
g_strtrim(char *str, int trim_flags)
|
||||
{
|
||||
int index;
|
||||
int len;
|
||||
int text1_index;
|
||||
int got_char;
|
||||
wchar_t *text;
|
||||
wchar_t *text1;
|
||||
|
||||
len = mbstowcs(0, str, 0);
|
||||
|
||||
if (len < 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((trim_flags < 1) || (trim_flags > 4))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
text = (wchar_t *)malloc(len * sizeof(wchar_t) + 8);
|
||||
text1 = (wchar_t *)malloc(len * sizeof(wchar_t) + 8);
|
||||
if (text == NULL || text1 == NULL)
|
||||
{
|
||||
free(text);
|
||||
free(text1);
|
||||
return 1;
|
||||
}
|
||||
text1_index = 0;
|
||||
mbstowcs(text, str, len + 1);
|
||||
|
||||
switch (trim_flags)
|
||||
{
|
||||
case 4: /* trim through */
|
||||
|
||||
for (index = 0; index < len; index++)
|
||||
{
|
||||
if (text[index] > 32)
|
||||
{
|
||||
text1[text1_index] = text[index];
|
||||
text1_index++;
|
||||
}
|
||||
}
|
||||
|
||||
text1[text1_index] = 0;
|
||||
break;
|
||||
case 3: /* trim both */
|
||||
got_char = 0;
|
||||
|
||||
for (index = 0; index < len; index++)
|
||||
{
|
||||
if (got_char)
|
||||
{
|
||||
text1[text1_index] = text[index];
|
||||
text1_index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (text[index] > 32)
|
||||
{
|
||||
text1[text1_index] = text[index];
|
||||
text1_index++;
|
||||
got_char = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
text1[text1_index] = 0;
|
||||
len = text1_index;
|
||||
|
||||
/* trim right */
|
||||
for (index = len - 1; index >= 0; index--)
|
||||
{
|
||||
if (text1[index] > 32)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
text1_index = index + 1;
|
||||
text1[text1_index] = 0;
|
||||
break;
|
||||
case 2: /* trim right */
|
||||
|
||||
/* copy it */
|
||||
for (index = 0; index < len; index++)
|
||||
{
|
||||
text1[text1_index] = text[index];
|
||||
text1_index++;
|
||||
}
|
||||
|
||||
/* trim right */
|
||||
for (index = len - 1; index >= 0; index--)
|
||||
{
|
||||
if (text1[index] > 32)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
text1_index = index + 1;
|
||||
text1[text1_index] = 0;
|
||||
break;
|
||||
case 1: /* trim left */
|
||||
got_char = 0;
|
||||
|
||||
for (index = 0; index < len; index++)
|
||||
{
|
||||
if (got_char)
|
||||
{
|
||||
text1[text1_index] = text[index];
|
||||
text1_index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (text[index] > 32)
|
||||
{
|
||||
text1[text1_index] = text[index];
|
||||
text1_index++;
|
||||
got_char = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
text1[text1_index] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
wcstombs(str, text1, text1_index + 1);
|
||||
free(text);
|
||||
free(text1);
|
||||
return 0;
|
||||
}
|
||||
|
104
common/string_calls.h
Normal file
104
common/string_calls.h
Normal file
@ -0,0 +1,104 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Copyright (C) Jay Sorg 2004-2020
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* generic string handling calls
|
||||
*/
|
||||
|
||||
#if !defined(STRING_CALLS_H)
|
||||
#define STRING_CALLS_H
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
/**
|
||||
* Map a character to a string value
|
||||
*
|
||||
* This structure is used by g_format_info_string() to specify the
|
||||
* string which chould be output for %'ch', where ch is a character
|
||||
*/
|
||||
struct info_string_tag
|
||||
{
|
||||
char ch;
|
||||
const char *val;
|
||||
};
|
||||
|
||||
#define INFO_STRING_END_OF_LIST { '\0', NULL }
|
||||
|
||||
/**
|
||||
* Processes a format string for general info
|
||||
*
|
||||
* @param[out] dest Destination buffer
|
||||
* @param[in] len Length of buffer, including space for a terminator
|
||||
* @param[in] format Format string to process
|
||||
* @param[in] map Array of struct info_string_tag.
|
||||
*
|
||||
* Where a '%<ch>' is encountered in the format string, the map is scanned
|
||||
* and the corresponding string is copied instead of '%<ch>'.
|
||||
*
|
||||
* '%%' is always replaced with a single '%' in the output. %<ch> strings
|
||||
* not present in the map are ignored.
|
||||
*
|
||||
* The map is terminated with INFO_STRING_END_OF_LIST
|
||||
*
|
||||
* Caller can check for buffer truncation by comparing the result with
|
||||
* the buffer length (as in snprintf())
|
||||
*/
|
||||
unsigned int
|
||||
g_format_info_string(char *dest, unsigned int len,
|
||||
const char *format,
|
||||
const struct info_string_tag map[]);
|
||||
|
||||
|
||||
/**
|
||||
* Converts a boolean to a string for output
|
||||
*
|
||||
* @param[in] value Value to convert
|
||||
* @return String representation
|
||||
*/
|
||||
const char *
|
||||
g_bool2text(int value);
|
||||
|
||||
/**
|
||||
* Converts a string to a boolean value
|
||||
*
|
||||
* @param[in] s String to convert
|
||||
* @return machine representation
|
||||
*/
|
||||
int
|
||||
g_text2bool(const char *s);
|
||||
|
||||
int g_strlen(const char *text);
|
||||
const char *g_strchr(const char *text, int c);
|
||||
char *g_strcpy(char *dest, const char *src);
|
||||
char *g_strncpy(char *dest, const char *src, int len);
|
||||
char *g_strcat(char *dest, const char *src);
|
||||
char *g_strncat(char *dest, const char *src, int len);
|
||||
char *g_strdup(const char *in);
|
||||
char *g_strndup(const char *in, const unsigned int maxlen);
|
||||
int g_strcmp(const char *c1, const char *c2);
|
||||
int g_strncmp(const char *c1, const char *c2, int len);
|
||||
int g_strncmp_d(const char *c1, const char *c2, const char delim, int len);
|
||||
int g_strcasecmp(const char *c1, const char *c2);
|
||||
int g_strncasecmp(const char *c1, const char *c2, int len);
|
||||
int g_atoi(const char *str);
|
||||
int g_htoi(char *str);
|
||||
int g_bytes_to_hexstr(const void *bytes, int num_bytes, char *out_str,
|
||||
int bytes_out_str);
|
||||
int g_pos(const char *str, const char *to_find);
|
||||
int g_mbstowcs(twchar *dest, const char *src, int n);
|
||||
int g_wcstombs(char *dest, const twchar *src, int n);
|
||||
int g_strtrim(char *str, int trim_flags);
|
||||
#endif
|
@ -23,6 +23,7 @@
|
||||
#endif
|
||||
|
||||
#include "os_calls.h"
|
||||
#include "string_calls.h"
|
||||
#include "trans.h"
|
||||
#include "arch.h"
|
||||
#include "parse.h"
|
||||
@ -302,7 +303,7 @@ 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 +372,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;
|
||||
@ -452,17 +453,14 @@ trans_force_read_s(struct trans *self, struct stream *in_s, int size)
|
||||
{
|
||||
int rcvd;
|
||||
|
||||
if (self->status != TRANS_STATUS_UP)
|
||||
if (self->status != TRANS_STATUS_UP ||
|
||||
size < 0 || !s_check_rem_out(in_s, size))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (size > 0)
|
||||
{
|
||||
/* make sure stream has room */
|
||||
if ((in_s->end + size) > (in_s->data + in_s->size))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
rcvd = self->trans_recv(self, in_s->end, size);
|
||||
if (rcvd == -1)
|
||||
{
|
||||
@ -636,7 +634,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;
|
||||
@ -875,7 +873,43 @@ trans_listen_address(struct trans *self, char *port, const char *address)
|
||||
|
||||
g_tcp_set_non_blocking(self->sck);
|
||||
|
||||
if (g_sck_vsock_bind(self->sck, port) == 0)
|
||||
if (g_sck_vsock_bind_address(self->sck, port, address) == 0)
|
||||
{
|
||||
if (g_tcp_listen(self->sck) == 0)
|
||||
{
|
||||
self->status = TRANS_STATUS_UP; /* ok */
|
||||
self->type1 = TRANS_TYPE_LISTENER; /* listener */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (self->mode == TRANS_MODE_TCP4) /* tcp4 */
|
||||
{
|
||||
self->sck = g_tcp4_socket();
|
||||
if (self->sck < 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
g_tcp_set_non_blocking(self->sck);
|
||||
if (g_tcp4_bind_address(self->sck, port, address) == 0)
|
||||
{
|
||||
if (g_tcp_listen(self->sck) == 0)
|
||||
{
|
||||
self->status = TRANS_STATUS_UP; /* ok */
|
||||
self->type1 = TRANS_TYPE_LISTENER; /* listener */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (self->mode == TRANS_MODE_TCP6) /* tcp6 */
|
||||
{
|
||||
self->sck = g_tcp6_socket();
|
||||
if (self->sck < 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
g_tcp_set_non_blocking(self->sck);
|
||||
if (g_tcp6_bind_address(self->sck, port, address) == 0)
|
||||
{
|
||||
if (g_tcp_listen(self->sck) == 0)
|
||||
{
|
||||
@ -885,7 +919,6 @@ trans_listen_address(struct trans *self, char *port, const char *address)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -24,9 +24,11 @@
|
||||
#include "arch.h"
|
||||
#include "parse.h"
|
||||
|
||||
#define TRANS_MODE_TCP 1
|
||||
#define TRANS_MODE_TCP 1 /* tcp6 if defined, else tcp4 */
|
||||
#define TRANS_MODE_UNIX 2
|
||||
#define TRANS_MODE_VSOCK 3
|
||||
#define TRANS_MODE_TCP4 4 /* tcp4 only */
|
||||
#define TRANS_MODE_TCP6 6 /* tcp6 only */
|
||||
|
||||
#define TRANS_TYPE_LISTENER 1
|
||||
#define TRANS_TYPE_SERVER 2
|
||||
@ -48,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
|
||||
@ -86,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
|
||||
|
@ -29,9 +29,20 @@
|
||||
*
|
||||
* xrdp constants
|
||||
*
|
||||
* Constants defined in publically available Microsoft documents are not
|
||||
* stored here, but are stored in the include files ms-*.h, where the name
|
||||
* of the file is the name of the document defining the constant.
|
||||
*
|
||||
* So for example, NTSTATUS values found in [MS-ERREF] are found in
|
||||
* ms-erref.h
|
||||
******************************************************************************/
|
||||
|
||||
#define INFO_CLIENT_NAME_BYTES 32
|
||||
/**
|
||||
* Maximum length of a string including the mandatory null terminator
|
||||
* [MS-RDPBCGR] TS_INFO_PACKET(2.2.1.11.1.1)
|
||||
*/
|
||||
#define INFO_CLIENT_MAX_CB_LEN 512
|
||||
|
||||
#define XRDP_MAX_BITMAP_CACHE_ID 3
|
||||
#define XRDP_MAX_BITMAP_CACHE_IDX 2000
|
||||
@ -60,541 +71,6 @@
|
||||
#define MCS_SDRQ 25 /* Send Data Request */
|
||||
#define MCS_SDIN 26 /* Send Data Indication */
|
||||
|
||||
/*
|
||||
* Constants come from Remote Desktop Protocol
|
||||
*/
|
||||
|
||||
/* RDP Security Negotiation codes */
|
||||
#define RDP_NEG_REQ 0x01 /* MS-RDPBCGR 2.2.1.1.1 */
|
||||
#define RDP_NEG_RSP 0x02 /* MS-RDPBCGR 2.2.1.2.1 */
|
||||
#define RDP_NEG_FAILURE 0x03 /* MS-RDPBCGR 2.2.1.2.2 */
|
||||
#define RDP_CORRELATION_INFO 0x06 /* MS-RDPBCGR 2.2.1.1.2 */
|
||||
|
||||
/* Protocol types codes (MS-RDPBCGR 2.2.1.1.1) */
|
||||
#define PROTOCOL_RDP 0x00000000
|
||||
#define PROTOCOL_SSL 0x00000001
|
||||
#define PROTOCOL_HYBRID 0x00000002
|
||||
#define PROTOCOL_RDSTLS 0x00000004
|
||||
#define PROTOCOL_HYBRID_EX 0x00000008
|
||||
|
||||
/* Negotiation packet flags (MS-RDPBCGR 2.2.1.2.1) */
|
||||
#define EXTENDED_CLIENT_DATA_SUPPORTED 0x01
|
||||
#define DYNVC_GFX_PROTOCOL_SUPPORTED 0x02
|
||||
#define NEGRSP_RESERVED 0x04
|
||||
#define RESTRICTED_ADMIN_MODE_SUPPORTED 0x08
|
||||
#define REDIRECTED_AUTHENTICATION_MODE_SUPPORTED 0x10
|
||||
|
||||
/* RDP Negotiation Failure Codes (MS-RDPBCGR 2.2.1.2.2) */
|
||||
#define SSL_REQUIRED_BY_SERVER 0x00000001
|
||||
#define SSL_NOT_ALLOWED_BY_SERVER 0x00000002
|
||||
#define SSL_CERT_NOT_ON_SERVER 0x00000003
|
||||
#define INCONSISTENT_FLAGS 0x00000004
|
||||
#define HYBRID_REQUIRED_BY_SERVER 0x00000005
|
||||
#define SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER 0x00000006
|
||||
|
||||
/* Client Core Data: connectionType (MS-RDPBCGR 2.2.1.3.2) */
|
||||
#define CONNECTION_TYPE_MODEM 0x01
|
||||
#define CONNECTION_TYPE_BROADBAND_LOW 0x02
|
||||
#define CONNECTION_TYPE_SATELLITE 0x03
|
||||
#define CONNECTION_TYPE_BROADBAND_HIGH 0x04
|
||||
#define CONNECTION_TYPE_WAN 0x05
|
||||
#define CONNECTION_TYPE_LAN 0x06
|
||||
#define CONNECTION_TYPE_AUTODETECT 0x07
|
||||
|
||||
/* Client Core Data: colorDepth, postBeta2ColorDepth (MS-RDPBCGR 2.2.1.3.2) */
|
||||
#define RNS_UD_COLOR_4BPP 0xCA00
|
||||
#define RNS_UD_COLOR_8BPP 0xCA01
|
||||
#define RNS_UD_COLOR_16BPP_555 0xCA02
|
||||
#define RNS_UD_COLOR_16BPP_565 0xCA03
|
||||
#define RNS_UD_COLOR_24BPP 0xCA04
|
||||
|
||||
/* Slow-Path Input Event: messageType (MS-RDPBCGR 2.2.8.1.1.3.1.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define RDP_INPUT_SYNCHRONIZE 0
|
||||
#define RDP_INPUT_CODEPOINT 1
|
||||
#define RDP_INPUT_VIRTKEY 2
|
||||
#define RDP_INPUT_SCANCODE 4
|
||||
#define RDP_INPUT_UNICODE 5
|
||||
#define RDP_INPUT_MOUSE 0x8001
|
||||
#define RDP_INPUT_MOUSEX 0x8002
|
||||
|
||||
#define FASTPATH_INPUT_ENCRYPTED 0x2
|
||||
|
||||
/* Fast-Path Input Event: eventCode (MS-RDPBCGR 2.2.8.1.2.2) */
|
||||
#define FASTPATH_INPUT_EVENT_SCANCODE 0x0
|
||||
#define FASTPATH_INPUT_EVENT_MOUSE 0x1
|
||||
#define FASTPATH_INPUT_EVENT_MOUSEX 0x2
|
||||
#define FASTPATH_INPUT_EVENT_SYNC 0x3
|
||||
#define FASTPATH_INPUT_EVENT_UNICODE 0x4
|
||||
#define FASTPATH_INPUT_EVENT_QOE_TIMESTAMP 0x6
|
||||
|
||||
/* Fast-Path Keyboard Event: eventHeader (MS-RDPBCGR 2.2.8.2.2.1) */
|
||||
#define FASTPATH_INPUT_KBDFLAGS_RELEASE 0x01
|
||||
#define FASTPATH_INPUT_KBDFLAGS_EXTENDED 0x02
|
||||
#define FASTPATH_INPUT_KBDFLAGS_EXTENDED1 0x04
|
||||
|
||||
/* Server Fast-Path Update PDU: action (MS-RDPBCGR 2.2.0.1.2) */
|
||||
#define FASTPATH_OUTPUT_ACTION_FASTPATH 0x0
|
||||
#define FASTPATH_OUTPUT_ACTION_X224 0x3
|
||||
|
||||
/* Server Fast-Path Update PDU: flags (MS-RDPBCGR 2.2.0.1.2) */
|
||||
#define FASTPATH_OUTPUT_ACTION_FASTPATH 0x0
|
||||
#define FASTPATH_OUTPUT_SECURE_CHECKSUM 0x1
|
||||
#define FASTPATH_OUTPUT_ENCRYPTED 0x2
|
||||
|
||||
/* Fast-Path Update: updateCode (MS-RDPBCGR 2.2.9.1.2.1) */
|
||||
#define FASTPATH_UPDATETYPE_ORDERS 0x0
|
||||
#define FASTPATH_UPDATETYPE_BITMAP 0x1
|
||||
#define FASTPATH_UPDATETYPE_PALETTE 0x2
|
||||
#define FASTPATH_UPDATETYPE_SYNCHRONIZE 0x3
|
||||
#define FASTPATH_UPDATETYPE_SURFCMDS 0x4
|
||||
#define FASTPATH_UPDATETYPE_PTR_NULL 0x5
|
||||
#define FASTPATH_UPDATETYPE_PTR_DEFAULT 0x6
|
||||
#define FASTPATH_UPDATETYPE_PTR_POSITION 0x8
|
||||
#define FASTPATH_UPDATETYPE_COLOR 0x9
|
||||
#define FASTPATH_UPDATETYPE_CACHED 0xA
|
||||
#define FASTPATH_UPDATETYPE_POINTER 0xB
|
||||
|
||||
/* Fast-Path Update: fragmentation (MS-RDPBCGR 2.2.9.1.2.1) */
|
||||
#define FASTPATH_FRAGMENT_SINGLE 0x0
|
||||
#define FASTPATH_FRAGMENT_LAST 0x1
|
||||
#define FASTPATH_FRAGMENT_FIRST 0x2
|
||||
#define FASTPATH_FRAGMENT_NEXT 0x3
|
||||
#define FASTPATH_OUTPUT_COMPRESSION_USED 0x2
|
||||
|
||||
/* Mouse Event: pointerFlags (MS-RDPBCGR 2.2.8.1.1.3.1.1.3) */
|
||||
#define PTRFLAGS_HWHEEL 0x0400
|
||||
#define PTRFLAGS_WHEEL 0x0200
|
||||
#define PTRFLAGS_WHEEL_NEGATIVE 0x0100
|
||||
#define WheelRotationMask 0x01FF
|
||||
#define PTRFLAGS_MOVE 0x0800
|
||||
#define PTRFLAGS_DOWN 0x8000
|
||||
#define PTRFLAGS_BUTTON1 0x1000
|
||||
#define PTRFLAGS_BUTTON2 0x2000
|
||||
#define PTRFLAGS_BUTTON3 0x4000
|
||||
|
||||
/* Extended Mouse Event: pointerFlags (MS-RDPBCGR 2.2.8.1.1.3.1.1.4) */
|
||||
#define PTRXFLAGS_DOWN 0x8000
|
||||
#define PTRXFLAGS_BUTTON1 0x0001
|
||||
#define PTRXFLAGS_BUTTON2 0x0002
|
||||
|
||||
/* General Capability Set: osMajorType (MS-RDPBCGR 2.2.7.1.1) */
|
||||
#define OSMAJORTYPE_UNSPECIFIED 0x0000
|
||||
#define OSMAJORTYPE_WINDOWS 0x0001
|
||||
#define OSMAJORTYPE_OS2 0x0002
|
||||
#define OSMAJORTYPE_MACINTOSH 0x0003
|
||||
#define OSMAJORTYPE_UNIX 0x0004
|
||||
#define OSMAJORTYPE_IOS 0x0005
|
||||
#define OSMAJORTYPE_OSX 0x0006
|
||||
#define OSMAJORTYPE_ANDROID 0x0007
|
||||
#define OSMAJORTYPE_CHROME_OS 0x0008
|
||||
|
||||
/* General Capability Set: osMinorType (MS-RDPBCGR 2.2.7.1.1) */
|
||||
#define OSMINORTYPE_UNSPECIFIED 0x0000
|
||||
#define OSMINORTYPE_WINDOWS_31X 0x0001
|
||||
#define OSMINORTYPE_WINDOWS_95 0x0002
|
||||
#define OSMINORTYPE_WINDOWS_NT 0x0003
|
||||
#define OSMINORTYPE_OS2_V21 0x0004
|
||||
#define OSMINORTYPE_POWER_PC 0x0005
|
||||
#define OSMINORTYPE_MACINTOSH 0x0006
|
||||
#define OSMINORTYPE_NATIVE_XSERVER 0x0007
|
||||
#define OSMINORTYPE_PSEUDO_XSERVER 0x0008
|
||||
#define OSMINORTYPE_WINDOWS_RT 0x0009
|
||||
|
||||
/* Window List Capability Set: WndSupportLevel (MS-RDPERP 2.2.1.1.2) */
|
||||
#define TS_WINDOW_LEVEL_NOT_SUPPORTED 0x00000000
|
||||
#define TS_WINDOW_LEVEL_SUPPORTED 0x00000001
|
||||
#define TS_WINDOW_LEVEL_SUPPORTED_EX 0x00000002
|
||||
|
||||
/* Extended Info Packet: performanceFlags (MS-RDPBCGR 2.2.1.11.1.1.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define RDP5_DISABLE_NOTHING 0x00
|
||||
#define RDP5_NO_WALLPAPER 0x01
|
||||
#define RDP5_NO_FULLWINDOWDRAG 0x02
|
||||
#define RDP5_NO_MENUANIMATIONS 0x04
|
||||
#define RDP5_NO_THEMING 0x08
|
||||
#define RDP5_NO_CURSOR_SHADOW 0x20
|
||||
#define RDP5_NO_CURSORSETTINGS 0x40 /* disables cursor blinking */
|
||||
|
||||
/* Virtual channel options */
|
||||
/* Channel Definition Structure: options (MS-RDPBCGR 2.2.1.3.4.1) */
|
||||
#define REMOTE_CONTROL_PERSISTENT 0x00100000
|
||||
/* NOTE: XR_ prefixed to avoid conflict with FreeRDP */
|
||||
#define XR_CHANNEL_OPTION_SHOW_PROTOCOL 0x00200000
|
||||
#define XR_CHANNEL_OPTION_COMPRESS 0x00400000
|
||||
#define XR_CHANNEL_OPTION_COMPRESS_RDP 0x00800000
|
||||
#define XR_CHANNEL_OPTION_PRI_LOW 0x02000000
|
||||
#define XR_CHANNEL_OPTION_PRI_MED 0x04000000
|
||||
#define XR_CHANNEL_OPTION_PRI_HIGH 0x08000000
|
||||
#define XR_CHANNEL_OPTION_ENCRYPT_CS 0x10000000
|
||||
#define XR_CHANNEL_OPTION_ENCRYPT_SC 0x20000000
|
||||
#define XR_CHANNEL_OPTION_ENCRYPT_RDP 0x40000000
|
||||
#define XR_CHANNEL_OPTION_INITIALIZED 0x80000000
|
||||
|
||||
/* RDPDR: Device Announce Header: DeviceType (MS-RDPEFS 2.2.1.3) */
|
||||
/* TODO: to be renamed */
|
||||
#define DEVICE_TYPE_SERIAL 0x01
|
||||
#define DEVICE_TYPE_PARALLEL 0x02
|
||||
#define DEVICE_TYPE_PRINTER 0x04
|
||||
#define DEVICE_TYPE_DISK 0x08
|
||||
#define DEVICE_TYPE_SCARD 0x20
|
||||
|
||||
/* Order Capability Set: orderSupportExFlags (MS-RDPBCGR 2.2.7.1.3) */
|
||||
#define XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT 0x0002
|
||||
#define XR_ORDERFLAGS_EX_ALTSEC_FRAME_MARKER_SUPPORT 0x0004
|
||||
#define XR_ORDERFLAGS_EX_OFFSCREEN_COMPOSITE_SUPPORT 0x0100
|
||||
|
||||
/* Order Capability Set: orderSupport (MS-RDPBCGR 2.2.7.1.3) */
|
||||
#define TS_NEG_DSTBLT_INDEX 0x00
|
||||
#define TS_NEG_PATBLT_INDEX 0x01
|
||||
#define TS_NEG_SCRBLT_INDEX 0x02
|
||||
#define TS_NEG_MEMBLT_INDEX 0x03
|
||||
#define TS_NEG_MEM3BLT_INDEX 0x04
|
||||
/* 0x05 */
|
||||
/* 0x06 */
|
||||
#define TS_NEG_DRAWNINEGRID_INDEX 0x07
|
||||
#define TS_NEG_LINETO_INDEX 0x08
|
||||
#define TS_NEG_MULTI_DRAWNINEGRID_INDEX 0x09
|
||||
/* 0x0A */
|
||||
#define TS_NEG_SAVEBITMAP_INDEX 0x0B
|
||||
/* 0x0C */
|
||||
/* 0x0D */
|
||||
/* 0x0E */
|
||||
#define TS_NEG_MULTIDSTBLT_INDEX 0x0F
|
||||
#define TS_NEG_MULTIPATBLT_INDEX 0x10
|
||||
#define TS_NEG_MULTISCRBLT_INDEX 0x11
|
||||
#define TS_NEG_MULTIOPAQUERECT_INDEX 0x12
|
||||
#define TS_NEG_FAST_INDEX_INDEX 0x13
|
||||
#define TS_NEG_POLYGON_SC_INDEX 0x14
|
||||
#define TS_NEG_POLYGON_CB_INDEX 0x15
|
||||
#define TS_NEG_POLYLINE_INDEX 0x16
|
||||
/* 0x17 */
|
||||
#define TS_NEG_FAST_GLYPH_INDEX 0x18
|
||||
#define TS_NEG_ELLIPSE_SC_INDEX 0x19
|
||||
#define TS_NEG_ELLIPSE_CB_INDEX 0x1A
|
||||
#define TS_NEG_INDEX_INDEX 0x1B
|
||||
/* 0x1C */
|
||||
/* 0x1D */
|
||||
/* 0x1E */
|
||||
/* 0x1F */
|
||||
|
||||
/* General Capability Set: extraFlags (MS-RDPBCGR 2.2.7.1.1) */
|
||||
#define TS_CAPS_PROTOCOLVERSION 0x0200
|
||||
#define FASTPATH_OUTPUT_SUPPORTED 0x0001
|
||||
#define NO_BITMAP_COMPRESSION_HDR 0x0400
|
||||
#define LONG_CREDENTIALS_SUPPORTED 0x0004
|
||||
#define AUTORECONNECT_SUPPORTED 0x0008
|
||||
#define ENC_SALTED_CHECKSUM 0x0010
|
||||
|
||||
/* Order Capability Set: orderFlags (MS-RDPBCGR 2.2.7.1.3) */
|
||||
#define NEGOTIATEORDERSUPPORT 0x0002
|
||||
#define ZEROBOUNDSDELTASUPPORT 0x0008
|
||||
#define COLORINDEXSUPPORT 0x0020
|
||||
#define SOLIDPATTERNBRUSHONLY 0x0040
|
||||
#define ORDERFLAGS_EXTRA_FLAGS 0x0080
|
||||
|
||||
/* Input Capability Set: inputFlags (MS-RDPBCGR 2.2.7.1.6) */
|
||||
#define INPUT_FLAG_SCANCODES 0x0001
|
||||
#define INPUT_FLAG_MOUSEX 0x0004
|
||||
#define INPUT_FLAG_FASTPATH_INPUT 0x0008
|
||||
#define INPUT_FLAG_UNICODE 0x0010
|
||||
#define INPUT_FLAG_FASTPATH_INPUT2 0x0020
|
||||
#define INPUT_FLAG_UNUSED1 0x0040
|
||||
#define INPUT_FLAG_UNUSED2 0x0080
|
||||
#define TS_INPUT_FLAG_MOUSE_HWHEEL 0x0100
|
||||
#define TS_INPUT_FLAG_QOE_TIMESTAMPS 0x0200
|
||||
|
||||
/* Desktop Composition Capability Set: CompDeskSupportLevel (MS-RDPBCGR 2.2.7.2.8) */
|
||||
#define COMPDESK_NOT_SUPPORTED 0x0000
|
||||
#define COMPDESK_SUPPORTED 0x0001
|
||||
|
||||
/* Surface Commands Capability Set: cmdFlags (MS-RDPBCGR 2.2.7.2.9) */
|
||||
#define SURFCMDS_SETSURFACEBITS 0x00000002
|
||||
#define SURFCMDS_FRAMEMARKER 0x00000010
|
||||
#define SURFCMDS_STREAMSUFRACEBITS 0x00000040
|
||||
|
||||
/* Bitmap Codec: codecGUID (MS-RDPBCGR 2.2.7.2.10.1.1) */
|
||||
|
||||
/* CODEC_GUID_NSCODEC CA8D1BB9-000F-154F-589FAE2D1A87E2D6 */
|
||||
#define XR_CODEC_GUID_NSCODEC \
|
||||
"\xb9\x1b\x8d\xca\x0f\x00\x4f\x15\x58\x9f\xae\x2d\x1a\x87\xe2\xd6"
|
||||
|
||||
/* CODEC_GUID_REMOTEFX 76772F12-BD72-4463-AFB3B73C9C6F7886 */
|
||||
#define XR_CODEC_GUID_REMOTEFX \
|
||||
"\x12\x2F\x77\x76\x72\xBD\x63\x44\xAF\xB3\xB7\x3C\x9C\x6F\x78\x86"
|
||||
|
||||
/* CODEC_GUID_IMAGE_REMOTEFX 2744CCD4-9D8A-4E74-803C-0ECBEEA19C54 */
|
||||
#define XR_CODEC_GUID_IMAGE_REMOTEFX \
|
||||
"\xD4\xCC\x44\x27\x8A\x9D\x74\x4E\x80\x3C\x0E\xCB\xEE\xA1\x9C\x54"
|
||||
|
||||
/* MFVideoFormat_H264 0x34363248-0000-0010-800000AA00389B71 */
|
||||
#define XR_CODEC_GUID_H264 \
|
||||
"\x48\x32\x36\x34\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71"
|
||||
|
||||
/* CODEC_GUID_JPEG 1BAF4CE6-9EED-430C-869ACB8B37B66237 */
|
||||
#define XR_CODEC_GUID_JPEG \
|
||||
"\xE6\x4C\xAF\x1B\xED\x9E\x0C\x43\x86\x9A\xCB\x8B\x37\xB6\x62\x37"
|
||||
|
||||
/* CODEC_GUID_PNG 0E0C858D-28E0-45DB-ADAA0F83E57CC560 */
|
||||
#define XR_CODEC_GUID_PNG \
|
||||
"\x8D\x85\x0C\x0E\xE0\x28\xDB\x45\xAD\xAA\x0F\x83\xE5\x7C\xC5\x60"
|
||||
|
||||
/* Surface Command Type (MS-RDPBCGR 2.2.9.1.2.1.10.1) */
|
||||
#define CMDTYPE_SET_SURFACE_BITS 0x0001
|
||||
#define CMDTYPE_FRAME_MARKER 0x0004
|
||||
#define CMDTYPE_STREAM_SURFACE_BITS 0x0006
|
||||
|
||||
/* RDP5 disconnect PDU */
|
||||
/* Set Error Info PDU Data: errorInfo (MS-RDPBCGR 2.2.5.1.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define exDiscReasonNoInfo 0x0000
|
||||
#define exDiscReasonAPIInitiatedDisconnect 0x0001
|
||||
#define exDiscReasonAPIInitiatedLogoff 0x0002
|
||||
#define exDiscReasonServerIdleTimeout 0x0003
|
||||
#define exDiscReasonServerLogonTimeout 0x0004
|
||||
#define exDiscReasonReplacedByOtherConnection 0x0005
|
||||
#define exDiscReasonOutOfMemory 0x0006
|
||||
#define exDiscReasonServerDeniedConnection 0x0007
|
||||
#define exDiscReasonServerDeniedConnectionFips 0x0008
|
||||
#define exDiscReasonLicenseInternal 0x0100
|
||||
#define exDiscReasonLicenseNoLicenseServer 0x0101
|
||||
#define exDiscReasonLicenseNoLicense 0x0102
|
||||
#define exDiscReasonLicenseErrClientMsg 0x0103
|
||||
#define exDiscReasonLicenseHwidDoesntMatchLicense 0x0104
|
||||
#define exDiscReasonLicenseErrClientLicense 0x0105
|
||||
#define exDiscReasonLicenseCantFinishProtocol 0x0106
|
||||
#define exDiscReasonLicenseClientEndedProtocol 0x0107
|
||||
#define exDiscReasonLicenseErrClientEncryption 0x0108
|
||||
#define exDiscReasonLicenseCantUpgradeLicense 0x0109
|
||||
#define exDiscReasonLicenseNoRemoteConnections 0x010a
|
||||
|
||||
/* Info Packet (TS_INFO_PACKET): flags (MS-RDPBCGR 2.2.1.11.1.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define RDP_LOGON_AUTO 0x0008
|
||||
#define RDP_LOGON_NORMAL 0x0033
|
||||
#define RDP_COMPRESSION 0x0080
|
||||
#define RDP_LOGON_BLOB 0x0100
|
||||
#define RDP_LOGON_LEAVE_AUDIO 0x2000
|
||||
#define RDP_LOGON_RAIL 0x8000
|
||||
|
||||
/* Compression Flags (MS-RDPBCGR 3.1.8.2.1) */
|
||||
/* TODO: to be renamed, not used anywhere */
|
||||
#define RDP_MPPC_COMPRESSED 0x20
|
||||
#define RDP_MPPC_RESET 0x40
|
||||
#define RDP_MPPC_FLUSH 0x80
|
||||
#define RDP_MPPC_DICT_SIZE 8192 /* RDP 4.0 | MS-RDPBCGR 3.1.8 */
|
||||
|
||||
/* Drawing Order: controlFlags (MS-RDPEGDI 2.2.2.2.1, ) */
|
||||
#define TS_STANDARD 0x01
|
||||
#define TS_SECONDARY 0x02
|
||||
#define TS_BOUNDS 0x04
|
||||
#define TS_TYPE_CHANGE 0x08
|
||||
#define TS_DELTA_COORDINATES 0x10
|
||||
#define TS_ZERO_BOUNDS_DELTAS 0x20
|
||||
#define TS_ZERO_FIELD_BYTE_BIT0 0x40
|
||||
#define TS_ZERO_FIELD_BYTE_BIT1 0x80
|
||||
|
||||
/* Drawing Order: orderType (MS-RDPEGDI 2.2.2.2.1.1.2) ? */
|
||||
#define RDP_ORDER_DESTBLT 0
|
||||
#define RDP_ORDER_PATBLT 1
|
||||
#define RDP_ORDER_SCREENBLT 2
|
||||
#define RDP_ORDER_LINE 9
|
||||
#define RDP_ORDER_RECT 10
|
||||
#define RDP_ORDER_DESKSAVE 11
|
||||
#define RDP_ORDER_MEMBLT 13
|
||||
#define RDP_ORDER_TRIBLT 14
|
||||
#define RDP_ORDER_POLYLINE 22
|
||||
#define RDP_ORDER_TEXT2 27
|
||||
#define RDP_ORDER_COMPOSITE 37 /* 0x25 */
|
||||
|
||||
/* Secondary Drawing Order Header: orderType (MS-RDPEGDI 2.2.2.2.1.2.1.1) */
|
||||
#define TS_CACHE_BITMAP_UNCOMPRESSED 0x00
|
||||
#define TS_CACHE_COLOR_TABLE 0x01
|
||||
#define TS_CACHE_BITMAP_COMPRESSED 0x02
|
||||
#define TS_CACHE_GLYPH 0x03
|
||||
#define TS_CACHE_BITMAP_UNCOMPRESSED_REV2 0x04
|
||||
#define TS_CACHE_BITMAP_COMPRESSED_REV2 0x05
|
||||
#define TS_CACHE_BRUSH 0x07
|
||||
#define TS_CACHE_BITMAP_COMPRESSED_REV3 0x08
|
||||
|
||||
/* Maps to generalCapabilitySet in T.128 page 138 */
|
||||
|
||||
/* Capability Set: capabilitySetType (MS-RDPBCGR 2.2.1.13.1.1.1) */
|
||||
#define CAPSTYPE_GENERAL 0x0001
|
||||
#define CAPSTYPE_GENERAL_LEN 0x18
|
||||
|
||||
#define CAPSTYPE_BITMAP 0x0002
|
||||
#define CAPSTYPE_BITMAP_LEN 0x1C
|
||||
|
||||
#define CAPSTYPE_ORDER 0x0003
|
||||
#define CAPSTYPE_ORDER_LEN 0x58
|
||||
#define ORDER_CAP_NEGOTIATE 2 /* NEGOTIATEORDERSUPPORT? not used */
|
||||
#define ORDER_CAP_NOSUPPORT 4 /* not used */
|
||||
|
||||
#define CAPSTYPE_BITMAPCACHE 0x0004
|
||||
#define CAPSTYPE_BITMAPCACHE_LEN 0x28
|
||||
|
||||
#define CAPSTYPE_CONTROL 0x0005
|
||||
#define CAPSTYPE_CONTROL_LEN 0x0C
|
||||
|
||||
#define CAPSTYPE_ACTIVATION 0x0007
|
||||
#define CAPSTYPE_ACTIVATION_LEN 0x0C
|
||||
|
||||
#define CAPSTYPE_POINTER 0x0008
|
||||
#define CAPSTYPE_POINTER_LEN 0x0a
|
||||
#define CAPSTYPE_POINTER_MONO_LEN 0x08
|
||||
|
||||
#define CAPSTYPE_SHARE 0x0009
|
||||
#define CAPSTYPE_SHARE_LEN 0x08
|
||||
|
||||
#define CAPSTYPE_COLORCACHE 0x000A
|
||||
#define CAPSTYPE_COLORCACHE_LEN 0x08
|
||||
|
||||
#define CAPSTYPE_SOUND 0x000C
|
||||
|
||||
#define CAPSTYPE_INPUT 0x000D
|
||||
#define CAPSTYPE_INPUT_LEN 0x58
|
||||
|
||||
#define CAPSTYPE_FONT 0x000E
|
||||
#define CAPSTYPE_FONT_LEN 0x04
|
||||
|
||||
#define CAPSTYPE_BRUSH 0x000F
|
||||
#define CAPSTYPE_BRUSH_LEN 0x08
|
||||
|
||||
#define CAPSTYPE_GLYPHCACHE 0x0010
|
||||
#define CAPSTYPE_OFFSCREENCACHE 0x0011
|
||||
|
||||
#define CAPSTYPE_BITMAPCACHE_HOSTSUPPORT 0x0012
|
||||
#define CAPSTYPE_BITMAPCACHE_HOSTSUPPORT_LEN 0x08
|
||||
|
||||
#define CAPSTYPE_BITMAPCACHE_REV2 0x0013
|
||||
#define CAPSTYPE_BITMAPCACHE_REV2_LEN 0x28
|
||||
#define BMPCACHE2_FLAG_PERSIST ((long)1<<31)
|
||||
|
||||
#define CAPSTYPE_VIRTUALCHANNEL 0x0014
|
||||
#define CAPSTYPE_VIRTUALCHANNEL_LEN 0x08
|
||||
|
||||
#define CAPSTYPE_DRAWNINGRIDCACHE 0x0015
|
||||
#define CAPSTYPE_DRAWGDIPLUS 0x0016
|
||||
#define CAPSTYPE_RAIL 0x0017
|
||||
#define CAPSTYPE_WINDOW 0x0018
|
||||
|
||||
#define CAPSSETTYPE_COMPDESK 0x0019
|
||||
#define CAPSSETTYPE_COMPDESK_LEN 0x06
|
||||
|
||||
#define CAPSSETTYPE_MULTIFRAGMENTUPDATE 0x001A
|
||||
#define CAPSSETTYPE_MULTIFRAGMENTUPDATE_LEN 0x08
|
||||
|
||||
#define CAPSETTYPE_LARGE_POINTER 0x001B
|
||||
#define CAPSETTYPE_LARGE_POINTER_LEN 0x06
|
||||
|
||||
#define CAPSETTYPE_SURFACE_COMMANDS 0x001C
|
||||
#define CAPSETTYPE_SURFACE_COMMANDS_LEN 0x0C
|
||||
|
||||
#define CAPSSETTYPE_BITMAP_CODECS 0x001D
|
||||
#define CAPSSETTYPE_BITMAP_CODECS_LEN 0x1C
|
||||
|
||||
#define CAPSTYPE_FRAME_ACKNOWLEDGE 0x001E
|
||||
#define CAPSTYPE_FRAME_ACKNOWLEDGE_LEN 0x08
|
||||
|
||||
/* TS_SECURITY_HEADER: flags (MS-RDPBCGR 2.2.8.1.1.2.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define SEC_CLIENT_RANDOM 0x0001 /* SEC_EXCHANGE_PKT? */
|
||||
#define SEC_ENCRYPT 0x0008
|
||||
#define SEC_LOGON_INFO 0x0040 /* SEC_INFO_PKT */
|
||||
#define SEC_LICENCE_NEG 0x0080 /* SEC_LICENSE_PKT */
|
||||
|
||||
#define SEC_TAG_SRV_INFO 0x0c01 /* SC_CORE */
|
||||
#define SEC_TAG_SRV_CRYPT 0x0c02 /* SC_SECURITY */
|
||||
#define SEC_TAG_SRV_CHANNELS 0x0c03 /* SC_NET? */
|
||||
|
||||
/* TS_UD_HEADER: type (MS-RDPBCGR (2.2.1.3.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define SEC_TAG_CLI_INFO 0xc001 /* CS_CORE? */
|
||||
#define SEC_TAG_CLI_CRYPT 0xc002 /* CS_SECURITY? */
|
||||
#define SEC_TAG_CLI_CHANNELS 0xc003 /* CS_CHANNELS? */
|
||||
#define SEC_TAG_CLI_4 0xc004 /* CS_CLUSTER? */
|
||||
#define SEC_TAG_CLI_MONITOR 0xc005 /* CS_MONITOR */
|
||||
|
||||
/* Server Proprietary Certificate (MS-RDPBCGR 2.2.1.4.3.1.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define SEC_TAG_PUBKEY 0x0006 /* BB_RSA_KEY_BLOB */
|
||||
#define SEC_TAG_KEYSIG 0x0008 /* BB_SIGNATURE_KEY_BLOB */
|
||||
|
||||
/* LicensingMessage (MS-RDPELE 2.2.2) */
|
||||
/* TODO: to be renamed */
|
||||
#define LICENCE_TAG_DEMAND 0x01 /* LICNSE_REQUEST */
|
||||
#define LICENCE_TAG_AUTHREQ 0x02 /* PLATFORM_CHALLENGE */
|
||||
#define LICENCE_TAG_ISSUE 0x03 /* NEW_LICENSE */
|
||||
#define LICENCE_TAG_REISSUE 0x04 /* UPGRADE_LICENSE */
|
||||
#define LICENCE_TAG_PRESENT 0x12 /* LICENSE_INFO */
|
||||
#define LICENCE_TAG_REQUEST 0x13 /* NEW_LICENSE_REQUEST */
|
||||
#define LICENCE_TAG_AUTHRESP 0x15 /* PLATFORM_CHALLENGE_RESPONSE */
|
||||
#define LICENCE_TAG_RESULT 0xff
|
||||
|
||||
/* LICENSE_BINARY_BLOB (MS-RDPBCGR 2.2.1.12.1.2) */
|
||||
#define LICENCE_TAG_USER 0x000f /* BB_CLIENT_USER_NAME_BLOB */
|
||||
#define LICENCE_TAG_HOST 0x0010 /* BB_CLIENT_MACHINE_NAME_BLOB */
|
||||
|
||||
/* Share Data Header: pduType2 (MS-RDPBCGR 2.2.8.1.1.1.2) */
|
||||
/* TODO: to be renamed */
|
||||
#define RDP_DATA_PDU_UPDATE 2 /* PDUTYPE2_UPDATE */
|
||||
#define RDP_DATA_PDU_CONTROL 20
|
||||
#define RDP_DATA_PDU_POINTER 27
|
||||
#define RDP_DATA_PDU_INPUT 28
|
||||
#define RDP_DATA_PDU_SYNCHRONISE 31
|
||||
#define RDP_DATA_PDU_PLAY_SOUND 34
|
||||
#define RDP_DATA_PDU_LOGON 38
|
||||
#define RDP_DATA_PDU_FONT2 39
|
||||
#define RDP_DATA_PDU_DISCONNECT 47
|
||||
|
||||
/* Control PDU Data: action (MS-RDPBCGR 2.2.1.15.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define RDP_CTL_REQUEST_CONTROL 1 /* CTRLACTION_REQUEST_CONTROL */
|
||||
#define RDP_CTL_GRANT_CONTROL 2
|
||||
#define RDP_CTL_DETACH 3
|
||||
#define RDP_CTL_COOPERATE 4
|
||||
|
||||
/* Slow-Path Graphics Update: updateType (MS-RDPBCGR 2.2.9.1.1.3.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define RDP_UPDATE_ORDERS 0
|
||||
#define RDP_UPDATE_BITMAP 1
|
||||
#define RDP_UPDATE_PALETTE 2
|
||||
#define RDP_UPDATE_SYNCHRONIZE 3
|
||||
|
||||
/* Server Pointer Update PDU: messageType (MS-RDPBCGR 2.2.9.1.1.4) */
|
||||
/* TODO: to be renamed */
|
||||
#define RDP_POINTER_SYSTEM 1 /* TS_PTRMSGTYPE_SYSTEM */
|
||||
#define RDP_POINTER_MOVE 3
|
||||
#define RDP_POINTER_COLOR 6
|
||||
#define RDP_POINTER_CACHED 7
|
||||
#define RDP_POINTER_POINTER 8
|
||||
|
||||
/* System Pointer Update: systemPointerType (MS-RDPBCGR 2.2.9.1.1.4.3) */
|
||||
#define RDP_NULL_POINTER 0
|
||||
#define RDP_DEFAULT_POINTER 0x7F00
|
||||
|
||||
/* Keyboard Event: keyboardFlags (MS-RDPBCGR 2.2.8.1.1.3.1.1.1) */
|
||||
/* TODO: to be renamed */
|
||||
#define KBD_FLAG_RIGHT 0x0001
|
||||
#define KBD_FLAG_EXT 0x0100 /* KBDFLAGS_EXTENDED */
|
||||
#define KBD_FLAG_QUIET 0x1000
|
||||
#define KBD_FLAG_DOWN 0x4000
|
||||
#define KBD_FLAG_UP 0x8000
|
||||
|
||||
/* Synchronize Event: toggleFlags (MS-RDPBCGR 2.2.8.1.1.3.1.1.5) */
|
||||
/* TODO: to be renamed */
|
||||
#define KBD_FLAG_SCROLL 0x0001 /* TS_SYNC_SCROLL_LOCK */
|
||||
#define KBD_FLAG_NUMLOCK 0x0002
|
||||
#define KBD_FLAG_CAPITAL 0x0004
|
||||
#define TS_SYNC_KANA_LOCK 0x0008
|
||||
|
||||
/* Glyph Cache Capability Set: GlyphSupportLevel (MS-RDPBCGR 2.2.7.1.8) */
|
||||
#define GLYPH_SUPPORT_NONE 0x0000
|
||||
#define GLYPH_SUPPORT_PARTIAL 0x0001
|
||||
#define GLYPH_SUPPORT_FULL 0x0002
|
||||
#define GLYPH_SUPPORT_ENCODE 0x0003
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Constants come from other Microsoft products
|
||||
@ -615,33 +91,6 @@
|
||||
|
||||
/* NTSTATUS Values (MS-ERREF 2.3.1) */
|
||||
/* used for RDPDR */
|
||||
#define STATUS_SUCCESS 0x00000000
|
||||
#define STATUS_PENDING 0x00000103
|
||||
|
||||
#define STATUS_NO_MORE_FILES 0x80000006
|
||||
#define STATUS_DEVICE_PAPER_EMPTY 0x8000000e
|
||||
#define STATUS_DEVICE_POWERED_OFF 0x8000000f
|
||||
#define STATUS_DEVICE_OFF_LINE 0x80000010
|
||||
#define STATUS_DEVICE_BUSY 0x80000011
|
||||
|
||||
#define STATUS_INVALID_HANDLE 0xc0000008
|
||||
#define STATUS_INVALID_PARAMETER 0xc000000d
|
||||
#define STATUS_NO_SUCH_FILE 0xc000000f
|
||||
#define STATUS_INVALID_DEVICE_REQUEST 0xc0000010
|
||||
#define STATUS_ACCESS_DENIED 0xc0000022
|
||||
#define STATUS_OBJECT_NAME_COLLISION 0xc0000035
|
||||
#define STATUS_DISK_FULL 0xc000007f
|
||||
#define STATUS_FILE_IS_A_DIRECTORY 0xc00000ba
|
||||
#define STATUS_NOT_SUPPORTED 0xc00000bb
|
||||
#define STATUS_TIMEOUT 0xc0000102
|
||||
#define STATUS_CANCELLED 0xc0000120
|
||||
|
||||
/* MS-SMB2 2.2.13 */
|
||||
/* TODO: not used anywhere */
|
||||
#define FILE_DIRECTORY_FILE 0x00000001
|
||||
#define FILE_NON_DIRECTORY_FILE 0x00000040
|
||||
#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000
|
||||
|
||||
/*
|
||||
* not yet sorted out
|
||||
*/
|
||||
@ -671,13 +120,6 @@
|
||||
#define LICENCE_SIGNATURE_SIZE 16
|
||||
|
||||
|
||||
/* PDU Types (MS-RDPBCGR 2.2.8.1.1.1.1) */
|
||||
#define PDUTYPE_DEMANDACTIVEPDU 0x1
|
||||
#define PDUTYPE_CONFIRMACTIVEPDU 0x3
|
||||
#define PDUTYPE_DEACTIVATEALLPDU 0x6
|
||||
#define PDUTYPE_DATAPDU 0x7
|
||||
#define PDUTYPE_SERVER_REDIR_PKT 0xA
|
||||
|
||||
/* See T.128 */
|
||||
/* not used anywhere */
|
||||
#define RDP_KEYPRESS 0
|
||||
@ -809,6 +251,10 @@
|
||||
#define WM_BUTTON6DOWN 112
|
||||
#define WM_BUTTON7UP 113
|
||||
#define WM_BUTTON7DOWN 114
|
||||
#define WM_BUTTON8UP 115
|
||||
#define WM_BUTTON8DOWN 116
|
||||
#define WM_BUTTON9UP 117
|
||||
#define WM_BUTTON9DOWN 118
|
||||
#define WM_INVALIDATE 200
|
||||
|
||||
#define CB_ITEMCHANGE 300
|
||||
|
79
configure.ac
79
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.10], [xrdp-devel@googlegroups.com])
|
||||
AC_INIT([xrdp], [0.9.15], [xrdp-devel@googlegroups.com])
|
||||
AC_CONFIG_HEADERS(config_ac.h:config_ac-h.in)
|
||||
AM_INIT_AUTOMAKE([1.7.2 foreign])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
@ -19,11 +19,6 @@ 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
|
||||
@ -70,7 +65,7 @@ if test "x$with_systemdsystemunitdir" != xno; then
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ])
|
||||
|
||||
AC_ARG_ENABLE(pam, AS_HELP_STRING([--disable-pam],
|
||||
AC_ARG_ENABLE(pam, AS_HELP_STRING([--enable-pam],
|
||||
[Build PAM support (default: yes)]),
|
||||
[], [enable_pam=yes])
|
||||
AM_CONDITIONAL(SESMAN_NOPAM, [test x$enable_pam != xyes])
|
||||
@ -84,7 +79,7 @@ AC_ARG_ENABLE(ipv6only, AS_HELP_STRING([--enable-ipv6only],
|
||||
[Build IPv6-only (default: no)]),
|
||||
[], [enable_ipv6only=no])
|
||||
AC_ARG_ENABLE(kerberos, AS_HELP_STRING([--enable-kerberos],
|
||||
[Build kerberos support (default: no)]),
|
||||
[Build kerberos support (prefer --enable-pam if available) (default: no)]),
|
||||
[], [enable_kerberos=no])
|
||||
AC_ARG_ENABLE(bsd, AS_HELP_STRING([--enable-bsd],
|
||||
[Build BSD auth support (default: no)]),
|
||||
@ -92,7 +87,7 @@ AC_ARG_ENABLE(bsd, AS_HELP_STRING([--enable-bsd],
|
||||
AM_CONDITIONAL(SESMAN_BSD, [test x$bsd = xtrue])
|
||||
AM_CONDITIONAL(SESMAN_KERBEROS, [test x$enable_kerberos = xyes])
|
||||
AC_ARG_ENABLE(pamuserpass, AS_HELP_STRING([--enable-pamuserpass],
|
||||
[Build pam userpass support (default: no)]),
|
||||
[Build PAM userpass support (default: no)]),
|
||||
[], [enable_pamuserpass=no])
|
||||
AM_CONDITIONAL(SESMAN_PAMUSERPASS, [test x$enable_pamuserpass = xyes])
|
||||
AC_ARG_ENABLE(pam-config, AS_HELP_STRING([--enable-pam-config=CONF],
|
||||
@ -150,6 +145,24 @@ AC_ARG_ENABLE(rfxcodec, AS_HELP_STRING([--disable-rfxcodec],
|
||||
[], [enable_rfxcodec=yes])
|
||||
AM_CONDITIONAL(XRDP_RFXCODEC, [test x$enable_rfxcodec = xyes])
|
||||
|
||||
AC_ARG_ENABLE(rdpsndaudin, AS_HELP_STRING([--enable-rdpsndaudin],
|
||||
[Use rdpsnd audio in (default: no)]),
|
||||
[], [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
|
||||
@ -170,7 +183,7 @@ PKG_CHECK_MODULES([OPENSSL], [openssl >= 0.9.8], [],
|
||||
OPENSSL_BIN=`$PKG_CONFIG --variable=exec_prefix openssl`/bin
|
||||
AC_PATH_PROGS([OPENSSL], [openssl], [:], [$OPENSSL_BIN:$PATH])
|
||||
|
||||
# checking for pam variation
|
||||
# checking for PAM variation
|
||||
# Linux-PAM is used in Linux systems
|
||||
# OpenPAM is used by FreeBSD, NetBSD, DragonFly BSD and OS X
|
||||
# OpenBSD uses BSD Authentication rather than both PAMs
|
||||
@ -179,17 +192,43 @@ AC_CHECK_HEADER([security/_pam_types.h],
|
||||
AC_CHECK_HEADER([security/pam_constants.h],
|
||||
[AC_DEFINE([HAVE_PAM_CONSTANTS_H], 1, [Using OpenPAM], [])])
|
||||
|
||||
# Check only one auth mechanism is specified, and give it a name
|
||||
auth_cnt=0
|
||||
auth_mech="Builtin"
|
||||
if test x$enable_pam = xyes
|
||||
then
|
||||
auth_cnt=`expr $auth_cnt + 1`
|
||||
auth_mech="PAM"
|
||||
fi
|
||||
if test x$bsd = xtrue
|
||||
then
|
||||
auth_cnt=`expr $auth_cnt + 1`
|
||||
auth_mech="BSD"
|
||||
fi
|
||||
if test x$enable_kerberos = xyes
|
||||
then
|
||||
auth_cnt=`expr $auth_cnt + 1`
|
||||
auth_mech="Kerberos"
|
||||
fi
|
||||
if test x$enable_pamuserpass = xyes
|
||||
then
|
||||
auth_cnt=`expr $auth_cnt + 1`
|
||||
auth_mech="PAM userpass"
|
||||
fi
|
||||
|
||||
if test $auth_cnt -gt 1
|
||||
then
|
||||
AC_MSG_ERROR([--enable-pam, --enable-bsd, --enable-pamuserpass and --enable-kerberos are mutually exclusive])
|
||||
fi
|
||||
|
||||
# checking if pam should be autodetected.
|
||||
if test "x$enable_pam" = "xyes"
|
||||
then
|
||||
if test "x$enable_kerberos" != "xyes"
|
||||
then
|
||||
if test -z "$enable_bsd"
|
||||
then
|
||||
AC_CHECK_HEADER([security/pam_appl.h], [],
|
||||
[AC_MSG_ERROR([please install libpam0g-dev or pam-devel])])
|
||||
fi
|
||||
fi
|
||||
if test "x$enable_pam_config" = "x"; then
|
||||
PAM_RULES="auto"
|
||||
else
|
||||
@ -224,7 +263,7 @@ then
|
||||
AC_DEFINE([XRDP_ENABLE_IPV6],1,[Enable IPv6])
|
||||
fi
|
||||
|
||||
if test "x$enable_pam" != "xyes" || test "x$bsd" = "xtrue"
|
||||
if test "x$enable_pam" != "xyes"
|
||||
then
|
||||
AC_DEFINE([USE_NOPAM],1,[Disable PAM])
|
||||
fi
|
||||
@ -238,11 +277,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
|
||||
@ -387,9 +421,9 @@ echo " fuse $enable_fuse"
|
||||
echo " ipv6 $enable_ipv6"
|
||||
echo " ipv6only $enable_ipv6only"
|
||||
echo " vsock $enable_vsock"
|
||||
echo " pam $enable_pam"
|
||||
echo " kerberos $enable_kerberos"
|
||||
echo " auth mechanism $auth_mech"
|
||||
echo " debug $enable_xrdpdebug"
|
||||
echo " rdpsndaudin $enable_rdpsndaudin"
|
||||
echo ""
|
||||
echo " strict_locations $enable_strict_locations"
|
||||
echo " prefix $prefix"
|
||||
@ -397,6 +431,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
|
||||
|
@ -15,10 +15,12 @@ EXTRA_DIST = $(man_MANS:=.in)
|
||||
SUBST_VARS = sed \
|
||||
-e 's|@PACKAGE_VERSION[@]|$(PACKAGE_VERSION)|g' \
|
||||
-e 's|@bindir[@]|$(bindir)|g' \
|
||||
-e 's|@sbindir[@]|$(sbindir)|g' \
|
||||
-e 's|@localstatedir[@]|$(localstatedir)|g' \
|
||||
-e 's|@sysconfdir[@]|$(sysconfdir)|g' \
|
||||
-e 's|@socketdir[@]|$(socketdir)|g' \
|
||||
-e 's|@xrdpconfdir[@]|$(sysconfdir)/xrdp|g'
|
||||
-e 's|@xrdpconfdir[@]|$(sysconfdir)/xrdp|g' \
|
||||
-e 's|@xrdphomeurl[@]|http://www.xrdp.org/|g'
|
||||
|
||||
subst_verbose = $(subst_verbose_@AM_V@)
|
||||
subst_verbose_ = $(subst_verbose_@AM_DEFAULT_V@)
|
||||
|
@ -32,6 +32,10 @@ X11 server settings for supported servers
|
||||
\fB[Chansrv]\fR
|
||||
Settings for xrdp-chansrv(8)
|
||||
|
||||
.TP
|
||||
\fB[ChansrvLogging]\fR
|
||||
Logging settings for xrdp-chansrv(8)
|
||||
|
||||
.TP
|
||||
\fB[SessionVariables]\fR
|
||||
Environment variables for the session
|
||||
@ -81,12 +85,15 @@ 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.
|
||||
@ -132,28 +153,30 @@ Sets the maximum number of simultaneous sessions. If not set or set to
|
||||
.TP
|
||||
\fBKillDisconnected\fR=\fI[true|false]\fR
|
||||
If set to \fB1\fR, \fBtrue\fR or \fByes\fR, every session will be killed
|
||||
within 60 seconds after the user disconnects.
|
||||
within \fBDisconnectedTimeLimit\fR seconds after the user disconnects.
|
||||
This setting currently only works with xorgxrdp sessions.
|
||||
|
||||
.TP
|
||||
\fBDisconnectedTimeLimit\fR=\fInumber\fR
|
||||
Sets the time limit (in seconds) before a disconnected session is killed.
|
||||
If set to \fI0\fR, automatic killing is disabled.
|
||||
Sets the time limit for \fBKillDisconnected\fR to a value greater than 60.
|
||||
Values less than 60 are to be overridden with 60.
|
||||
This setting currently only works with xorgxrdp sessions.
|
||||
|
||||
.TP
|
||||
\fBIdleTimeLimit\fR=\fInumber\fR
|
||||
Sets the time limit (in seconds) before an idle session is disconnected.
|
||||
Idle means no keyboard inputs and no mouse moves/clicks here.
|
||||
If set to \fI0\fR, idle sessions will never be disconnected by timeout.
|
||||
This works only with xorgxrdp session. Moreover, xorgxrdp must be v0.2.9 or later.
|
||||
This works only with xorgxrdp sessions. Moreover, xorgxrdp must be v0.2.9 or later.
|
||||
|
||||
.TP
|
||||
\fBPolicy\fR=\fI[Default|UBD|UBI|UBC|UBDI|UBDC]\fR
|
||||
Session allocation policy. By default, a new session is created
|
||||
for the combination <User,BitPerPixel> when using Xrdp, and
|
||||
for the combination <User,BitPerPixel,DisplaySize> when using Xvnc.
|
||||
This behavior can be changed by setting session policy to:
|
||||
Session allocation policy. Used to decide when to allocate a
|
||||
new session. Set to one of the following values:
|
||||
.br
|
||||
|
||||
.br
|
||||
\fBDefault\fR - session per <User,BitPerPixel>
|
||||
.br
|
||||
\fBUBD\fR - session per <User,BitPerPixel,DisplaySize>
|
||||
.br
|
||||
@ -168,7 +191,8 @@ This behavior can be changed by setting session policy to:
|
||||
|
||||
.br
|
||||
Note that the \fBUser\fR and \fBBitPerPixel\fR criteria cannot be turned
|
||||
off. For Xvnc connections, \fBDisplaySize\fR is always enabled as well.
|
||||
off. \fBDisplaySize\fR refers to the initial geometry of a connection,
|
||||
as actual display sizes can change dynamically.
|
||||
.br
|
||||
|
||||
.SH "SECURITY"
|
||||
@ -222,8 +246,50 @@ Following parameters can be used in the \fB[Chansrv]\fR section.
|
||||
|
||||
.TP
|
||||
\fBFuseMountName\fR=\fIstring\fR
|
||||
Directory for drive redirection, relative to the user home directory.
|
||||
Directory for drive redirection.
|
||||
Created if it doesn't exist. If not specified, defaults to \fIxrdp_client\fR.
|
||||
If first character is not a '/', this is relative to $HOME.
|
||||
.P
|
||||
.RS
|
||||
If first character is a '/' this is an absolute path. The following
|
||||
substitutions are made in this string:-
|
||||
%U - Username
|
||||
%u - Numeric UID
|
||||
%% - Percent character
|
||||
.P
|
||||
If this format is used:-
|
||||
.HP 3
|
||||
1) The directory path permissions MUST be configured correctly by
|
||||
the system administrator or the system itself - xrdp-chansrv will not
|
||||
do this for you (although it will create the final directories owned by
|
||||
the user).
|
||||
.HP 3
|
||||
2) The desktop may not automatically display a link for the redirected
|
||||
drive. To fix this, consult the docs for your chosen desktop.
|
||||
.RE
|
||||
|
||||
.TP
|
||||
\fBFileUmask\fR=\fImode\fR
|
||||
Additional umask to apply to files in the \fBFuseMountName\fR directory.
|
||||
The default value of 077 prevents other users on the system from reading
|
||||
files on your redirected drives. This may not be approprate for all
|
||||
environents, and so you can change this value to allow other users to
|
||||
access your remote files if required.
|
||||
|
||||
.TP
|
||||
\fBEnableFuseMount\fR=\fI[true|false]\fR
|
||||
Defaults to \fItrue\fR.
|
||||
Set to \fIfalse\fR to disable xrdp-chansrv's use of the FUSE system
|
||||
feature, even if it has been built with this feature enabled.
|
||||
.P
|
||||
.RS
|
||||
Setting this value to \fIfalse\fR will disable the following application
|
||||
features:-
|
||||
.P
|
||||
- drive redirection
|
||||
.P
|
||||
- copying-and-pasting of files
|
||||
.RE
|
||||
|
||||
.SH "SESSIONS VARIABLES"
|
||||
All entries in the \fB[SessionVariables]\fR section are set as
|
||||
@ -238,4 +304,6 @@ environment variables in the user's session.
|
||||
.BR xrdp (8),
|
||||
.BR xrdp.ini (5)
|
||||
|
||||
For more info on \fBxrdp\fR see http://www.xrdp.org/
|
||||
For more info on \fBxrdp\fR see
|
||||
.UR @xrdphomeurl@
|
||||
.UE
|
||||
|
@ -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,21 +27,36 @@ 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),
|
||||
.BR sesman.ini (5).
|
||||
|
||||
for more info on \fBxrdp\fR see http://www.xrdp.org/
|
||||
For more info on \fBxrdp\fR see
|
||||
.UR @xrdphomeurl@
|
||||
.UE
|
||||
|
@ -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).
|
||||
|
@ -61,7 +61,13 @@ Simone Fedele <ilsimo@users.sourceforge.net>
|
||||
.SH "SEE ALSO"
|
||||
.BR xrdp (8),
|
||||
.BR setxkbmap (1),
|
||||
.BR unicode (7),
|
||||
.URL "https://github.com/FreeRDP/FreeRDP/wiki/Keyboard" "Description of Keyboard Input mapping" .
|
||||
|
||||
for more info on \fBxrdp\fR see http://www.xrdp.org/
|
||||
.BR unicode (7)
|
||||
.PP
|
||||
Description of Keyboard Input mapping on the
|
||||
.UR https://github.com/FreeRDP/FreeRDP/wiki/Keyboard
|
||||
FreeRDP wiki
|
||||
.UE
|
||||
.PP
|
||||
For more info on \fBxrdp\fR see
|
||||
.UR @xrdphomeurl@
|
||||
.UE
|
||||
|
@ -55,3 +55,8 @@ xrdp\-sesadmin.log
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR xrdp (8).
|
||||
|
||||
More info on \fBxrdp\fR can be found on the
|
||||
.UR @xrdphomeurl@
|
||||
xrdp homepage
|
||||
.UE
|
||||
|
@ -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] [\-\-dump\-config] [\-\-config /path/to/sesman.ini]
|
||||
|
||||
.SH "DESCRIPTION"
|
||||
\fBxrdp\-sesman\fR is \fBxrdp\fR(8) session manager.
|
||||
@ -13,17 +22,34 @@ 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\-\-dump\-config\fR
|
||||
Print the configuration on stdout before starting the daemon.
|
||||
The default is not to do this.
|
||||
.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
|
||||
@sbindir@/xrdp\-sesman
|
||||
.br
|
||||
@bindir@/xrdp\-sesrun
|
||||
.br
|
||||
@ -44,4 +70,6 @@ Simone Fedele <ilsimo@users.sourceforge.net>
|
||||
.BR xrdp (8),
|
||||
.BR xrdp.ini (5)
|
||||
|
||||
for more info on \fBxrdp\fR see http://www.xrdp.org/
|
||||
for more info on \fBxrdp\fR see
|
||||
.UR @xrdphomeurl@
|
||||
.UE
|
||||
|
@ -1,40 +1,87 @@
|
||||
.TH "xrdp\-sesrun" "8" "@PACKAGE_VERSION@" "xrdp team" ""
|
||||
.SH "NAME"
|
||||
xrdp\-sesrun \- \fBsesman\fR(8) session launcher
|
||||
\fBxrdp\-sesrun\fR \- \fBxrdp\-sesman\fR(8) session launcher
|
||||
|
||||
.SH "SYNTAX"
|
||||
.B xrdp\-sesrun
|
||||
.I server username password width height bpp
|
||||
.I [ options ] username
|
||||
|
||||
.SH "DESCRIPTION"
|
||||
\fBxrdp\-sesrun\fR starts a session using \fBxrdp\-sesman\fR(8).
|
||||
.br
|
||||
This is a tool useful for testing, it simply behaves like xrdp when some user logs in a new session and authenticates, thus starting a new session.
|
||||
This is a tool useful for testing, it simply behaves like xrdp when some
|
||||
user logs in a new session and authenticates, thus starting a new session.
|
||||
|
||||
Default values for the options are set at compile-time. Run the utility without
|
||||
a username to see what the defaults are for your installation.
|
||||
|
||||
The utility prompts for a password if neither \fB-p\fR or \fB-F\fR is used.
|
||||
|
||||
.SH "OPTIONS"
|
||||
.TP
|
||||
.I server
|
||||
Server on which sesman is running
|
||||
.B -g <width>x<height>
|
||||
Set session geometry.
|
||||
.br
|
||||
Note that most configurations will resize the session on connection, so this
|
||||
option may not do what you expect.
|
||||
.TP
|
||||
.I username
|
||||
user name of the session being started
|
||||
.B -b <bits-per-pixel>
|
||||
Set session bits-per-pixel (colour depth). Some session types (i.e. Xorg)
|
||||
will ignore this setting.
|
||||
.TP
|
||||
.I password
|
||||
user password
|
||||
.B -s <server>
|
||||
Server on which sesman is running (probably 'localhost').
|
||||
.br
|
||||
Use of this option is discouraged as it will be removed in the future.
|
||||
.TP
|
||||
.I width
|
||||
Screen width
|
||||
.B -t <session-type>
|
||||
Session type - one of Xorg, Xvnc or X11rdp. Alternatively, for testing
|
||||
only, use the numeric session code.
|
||||
.TP
|
||||
.I height
|
||||
Screen height
|
||||
.B -D <directory>
|
||||
Directory to run the new session in. Defaults to $HOME for the specified user.
|
||||
.TP
|
||||
.I bpp
|
||||
Session color depth
|
||||
.B -S <shell>
|
||||
Specify an alternate shell to run, instead of the default window manager.
|
||||
.TP
|
||||
.B -p <password>
|
||||
Password for user. USE FOR TESTING ONLY - the password will be visible
|
||||
in the output of the \fBps\fR command.
|
||||
.TP
|
||||
.B -F <file-descriptor>
|
||||
Specify a file descriptor (normally 0) to read the password in from. This
|
||||
is a secure way to pass the password in to the utility.
|
||||
.TP
|
||||
.B -c <sesman-ini>
|
||||
Specify a different sesman.ini file. This file is used to find out how to
|
||||
connect to \fBxrdp\-sesman\fR.
|
||||
|
||||
.SH "ENVIRONMENT"
|
||||
.TP
|
||||
.I SESRUN_LOG_LEVEL
|
||||
Override the default logging level. One of "error", "warn", "info",
|
||||
"debug", "trace" or a number 1-5.
|
||||
|
||||
.SH "EXAMPLES"
|
||||
.TP
|
||||
.B
|
||||
xrdp-sesrun -F 0 user1 <passwd.txt
|
||||
Create a default session for user \fBuser1\fR with a password from
|
||||
a file
|
||||
.TP
|
||||
.B
|
||||
xrdp-sesrun -t Xvnc -S /usr/bin/xterm user1
|
||||
Create an extremely minimal Xvnc session for user \fBuser1\fR. This
|
||||
could be useful for debugging why the standard session is not starting
|
||||
properly. Note you would need to install the \fBxterm\fR utility
|
||||
first. The \fBgnome\-terminal\fR utility probably won't work here.
|
||||
|
||||
.SH "FILES"
|
||||
@bindir@/xrdp\-sesman
|
||||
@sbindir@/xrdp\-sesman
|
||||
.br
|
||||
@bindir@/xrdp\-sesrun
|
||||
.br
|
||||
@sysconfdir@/xrdp/sesman.ini
|
||||
|
||||
.SH "AUTHORS"
|
||||
Jay Sorg <jsorg71@users.sourceforge.net>
|
||||
@ -47,4 +94,6 @@ Simone Fedele <ilsimo@users.sourceforge.net>
|
||||
.BR xrdp (8),
|
||||
.BR xrdp.ini (5)
|
||||
|
||||
for more info on \fBxrdp\fR see http://www.xrdp.org/
|
||||
For more info on \fBxrdp\fR see
|
||||
.UR @xrdphomeurl@
|
||||
.UE
|
||||
|
@ -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] [\-\-dump\-config] [\-\-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,9 +44,18 @@ 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\-\-dump\-config\fR
|
||||
Print the configuration on stdout before starting the daemon.
|
||||
The default is not to do this.
|
||||
.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
|
||||
@sbindir@/xrdp
|
||||
.br
|
||||
@sysconfdir@/xrdp/xrdp.ini
|
||||
.br
|
||||
@ -52,4 +74,6 @@ Simone Fedele <ilsimo@users.sourceforge.net>
|
||||
.BR sesman.ini (5),
|
||||
.BR sesrun (8)
|
||||
|
||||
for more info on \fBxrdp\fR see http://www.xrdp.org/
|
||||
for more info on \fBxrdp\fR see
|
||||
.UR @xrdphomeurl@
|
||||
.UE
|
||||
|
@ -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.
|
||||
@ -302,6 +325,14 @@ Specifies color depth of the backend X server. The default is the color
|
||||
depth of the client. Only Xvnc and X11rdp use that setting. Xorg runs at
|
||||
\fI24\fR bpp.
|
||||
|
||||
.TP
|
||||
\fBdisabled_encodings_mask\fR=\fI<number>\fR
|
||||
Set this bitmask to a non-zero value to prevent \fBxrdp\fR(8) requesting
|
||||
some features from the Xvnc server. You should only need to set this
|
||||
to a non-zero value to work around bugs in your Xvnc server. The bit
|
||||
values supported for a particular release of \fBxrdp\fR(8) are documented in
|
||||
\fBxrdp.ini\fR.
|
||||
|
||||
.TP
|
||||
\fBcode\fR=\fI<number>\fR|\fI0\fR
|
||||
Specifies the session type. The default, \fI0\fR, is Xvnc, \fI10\fR is
|
||||
@ -342,4 +373,6 @@ password={base64}cGFzc3dvcmQhCg==
|
||||
.BR sesrun (8),
|
||||
.BR sesman.ini (5)
|
||||
|
||||
for more info on \fBxrdp\fR see http://www.xrdp.org/
|
||||
For more info on \fBxrdp\fR see
|
||||
.UR @xrdphomeurl@
|
||||
.UE
|
||||
|
@ -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.
|
||||
|
@ -30,7 +30,6 @@ default build will install the following
|
||||
startwm.sh
|
||||
xrdp.ini
|
||||
xrdp_keyboard.ini
|
||||
xrdp.sh
|
||||
|
||||
/etc/xrdp/pulse
|
||||
default.pa
|
||||
|
@ -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)
|
||||
{
|
||||
@ -136,7 +136,7 @@ int main(int argc, char **argv)
|
||||
fprintf(outf, "[%s]\n", sections[idx]);
|
||||
e.state = states[idx];
|
||||
|
||||
for (i = 8; i <= 137; i++) /* Keycodes */
|
||||
for (i = 8; i < 137; i++) /* Keycodes */
|
||||
{
|
||||
if (is_evdev)
|
||||
e.keycode = xfree86_to_evdev[i-8];
|
||||
|
@ -1,6 +1,5 @@
|
||||
EXTRA_DIST = \
|
||||
keymap-names.txt \
|
||||
xrdp.sh \
|
||||
xrdp-sesman.service.in \
|
||||
xrdp.service.in
|
||||
|
||||
@ -51,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
|
||||
@ -61,7 +61,6 @@ if LINUX
|
||||
SUBDIRS += \
|
||||
pam.d \
|
||||
pulse
|
||||
dist_startscript_SCRIPTS = xrdp.sh
|
||||
if HAVE_SYSTEMD
|
||||
systemdsystemunit_DATA = \
|
||||
xrdp-sesman.service \
|
||||
|
1047
instfiles/km-19360409.ini
Normal file
1047
instfiles/km-19360409.ini
Normal file
File diff suppressed because it is too large
Load Diff
@ -8,47 +8,89 @@ outfile="$3"
|
||||
|
||||
service="xrdp-sesman"
|
||||
pamdir="/etc/pam.d"
|
||||
pamdir_suse="/usr/etc/pam.d"
|
||||
|
||||
# Modules needed by xrdp-sesman.unix, if we get to that
|
||||
unix_modules_needed="pam_unix.so pam_env.so pam_nologin.so"
|
||||
|
||||
# Directories where pam modules might be installed
|
||||
# Add to this list as platforms are added
|
||||
pam_module_dir_searchpath="/lib*/security /usr/lib*/security /lib/*/security /usr/lib/*/security"
|
||||
|
||||
find_pam_module_dir()
|
||||
{
|
||||
# Looks for the pam security module directory
|
||||
set -- $pam_module_dir_searchpath
|
||||
for d in "$@"; do
|
||||
if [ -s $d/pam_unix.so ]; then
|
||||
echo $d
|
||||
break
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
can_apply_unix_config()
|
||||
{
|
||||
result=0
|
||||
module_dir="$1"
|
||||
for m in $unix_modules_needed; do
|
||||
if [ ! -s $module_dir/$m ]; then
|
||||
echo " ** $m not found" >&2
|
||||
result=1
|
||||
fi
|
||||
done
|
||||
|
||||
return $result
|
||||
}
|
||||
|
||||
guess_rules ()
|
||||
{
|
||||
if test -s "$pamdir/password-auth"; then
|
||||
rules=
|
||||
if [ -s "$pamdir/password-auth" ]; then
|
||||
rules="redhat"
|
||||
return
|
||||
fi
|
||||
|
||||
if test -s "$pamdir/common-account"; then
|
||||
elif [ -s "$pamdir_suse/common-account" ]; then
|
||||
rules="suse"
|
||||
|
||||
elif [ -s "$pamdir/common-account" ]; then
|
||||
if grep "^@include" "$pamdir/passwd" >/dev/null 2>&1; then
|
||||
rules="debian"
|
||||
else
|
||||
rules="suse"
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
if test ! -f "$pamdir/system-auth" -a -s "$pamdir/system"; then
|
||||
elif [ ! -f "$pamdir/system-auth" -a -s "$pamdir/system" ]; then
|
||||
rules="freebsd"
|
||||
return
|
||||
fi
|
||||
|
||||
if test -s "$pamdir/authorization"; then
|
||||
elif [ -s "$pamdir/authorization" ]; then
|
||||
rules="macos"
|
||||
return
|
||||
fi
|
||||
|
||||
if test -s "$pamdir/system-remote-login"; then
|
||||
elif [ -s "$pamdir/system-remote-login" ]; then
|
||||
rules="arch"
|
||||
return
|
||||
fi
|
||||
|
||||
elif [ -s "$pamdir/system-auth" ]; then
|
||||
rules="system"
|
||||
|
||||
else
|
||||
module_dir=`find_pam_module_dir`
|
||||
if [ -d "$module_dir" ]; then
|
||||
#echo "- Found pam modules in $module_dir" >&2
|
||||
if can_apply_unix_config "$module_dir" ; then
|
||||
rules="unix"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
if test "$rules" = "auto"; then
|
||||
if [ "$rules" = "auto" ]; then
|
||||
guess_rules
|
||||
if [ -z "$rules" ]; then
|
||||
echo "** Can't guess PAM rules for this system"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -s "$srcdir/$service.$rules"; then
|
||||
if [ -s "$srcdir/$service.$rules" ]; then
|
||||
ln -nsf "$srcdir/$service.$rules" "$outfile"
|
||||
else
|
||||
echo "Cannot find $srcdir/$service.$rules"
|
||||
|
5
instfiles/pam.d/xrdp-sesman.system
Normal file
5
instfiles/pam.d/xrdp-sesman.system
Normal file
@ -0,0 +1,5 @@
|
||||
#%PAM-1.0
|
||||
auth include system-auth
|
||||
account include system-auth
|
||||
password include system-auth
|
||||
session include system-auth
|
@ -1,5 +1,16 @@
|
||||
#%PAM-1.0
|
||||
auth include system-auth
|
||||
account include system-auth
|
||||
password include system-auth
|
||||
session include system-auth
|
||||
#
|
||||
# Really basic authentication set when nothing else is available
|
||||
#
|
||||
# You may need to edit this to suit your system depending on the
|
||||
# required functionality.
|
||||
#
|
||||
auth required pam_unix.so shadow
|
||||
auth required pam_env.so
|
||||
|
||||
password required pam_unix.so
|
||||
|
||||
account required pam_unix.so
|
||||
account required pam_nologin.so
|
||||
|
||||
session required pam_unix.so
|
||||
|
@ -1,153 +0,0 @@
|
||||
#!/bin/sh
|
||||
# xrdp control script
|
||||
# Written : 1-13-2006 - Mark Balliet - posicat@pobox.com
|
||||
# maintaned by Jay Sorg
|
||||
# chkconfig: 2345 11 89
|
||||
# description: starts xrdp
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: xrdp
|
||||
# Required-Start:
|
||||
# Required-Stop:
|
||||
# Should-Start:
|
||||
# Should-Stop:
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Start and stop xrdp
|
||||
# Description: starts xrdp
|
||||
### END INIT INFO
|
||||
|
||||
SBINDIR=/usr/local/sbin
|
||||
LOG=/dev/null
|
||||
CFGDIR=/etc/xrdp
|
||||
|
||||
if ! test -x $SBINDIR/xrdp
|
||||
then
|
||||
echo "xrdp is not executable"
|
||||
exit 0
|
||||
fi
|
||||
if ! test -x $SBINDIR/xrdp-sesman
|
||||
then
|
||||
echo "xrdp-sesman is not executable"
|
||||
exit 0
|
||||
fi
|
||||
if ! test -x $CFGDIR/startwm.sh
|
||||
then
|
||||
echo "startwm.sh is not executable"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
xrdp_start()
|
||||
{
|
||||
echo -n "Starting: xrdp and sesman . . "
|
||||
$SBINDIR/xrdp >> $LOG
|
||||
$SBINDIR/xrdp-sesman >> $LOG
|
||||
echo "."
|
||||
sleep 1
|
||||
return 0;
|
||||
}
|
||||
|
||||
xrdp_stop()
|
||||
{
|
||||
echo -n "Stopping: xrdp and sesman . . "
|
||||
$SBINDIR/xrdp-sesman --kill >> $LOG
|
||||
$SBINDIR/xrdp --kill >> $LOG
|
||||
echo "."
|
||||
return 0;
|
||||
}
|
||||
|
||||
is_xrdp_running()
|
||||
{
|
||||
ps u --noheading -C xrdp | grep -q -i xrdp
|
||||
if test $? -eq 0
|
||||
then
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
fi
|
||||
}
|
||||
|
||||
is_sesman_running()
|
||||
{
|
||||
ps u --noheading -C xrdp-sesman | grep -q -i xrdp-sesman
|
||||
if test $? -eq 0
|
||||
then
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
fi
|
||||
}
|
||||
|
||||
check_up()
|
||||
{
|
||||
# Cleanup : If sesman isn't running, but the pid exists, erase it.
|
||||
is_sesman_running
|
||||
if test $? -eq 0
|
||||
then
|
||||
if test -e /var/run/xrdp-sesman.pid
|
||||
then
|
||||
rm /var/run/xrdp-sesman.pid
|
||||
fi
|
||||
fi
|
||||
# Cleanup : If xrdp isn't running, but the pid exists, erase it.
|
||||
is_xrdp_running
|
||||
if test $? -eq 0
|
||||
then
|
||||
if test -e /var/run/xrdp.pid
|
||||
then
|
||||
rm /var/run/xrdp.pid
|
||||
fi
|
||||
fi
|
||||
return 0;
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
check_up
|
||||
is_xrdp_running
|
||||
if ! test $? -eq 0
|
||||
then
|
||||
echo "xrdp is already loaded"
|
||||
exit 1
|
||||
fi
|
||||
is_sesman_running
|
||||
if ! test $? -eq 0
|
||||
then
|
||||
echo "sesman is already loaded"
|
||||
exit 1
|
||||
fi
|
||||
xrdp_start
|
||||
;;
|
||||
stop)
|
||||
check_up
|
||||
is_xrdp_running
|
||||
if test $? -eq 0
|
||||
then
|
||||
echo "xrdp is not loaded."
|
||||
fi
|
||||
is_sesman_running
|
||||
if test $? -eq 0
|
||||
then
|
||||
echo "sesman is not loaded."
|
||||
fi
|
||||
xrdp_stop
|
||||
;;
|
||||
force-reload|restart)
|
||||
check_up
|
||||
echo "Restarting xrdp ..."
|
||||
xrdp_stop
|
||||
is_xrdp_running
|
||||
while ! test $? -eq 0
|
||||
do
|
||||
check_up
|
||||
sleep 1
|
||||
is_xrdp_running
|
||||
done
|
||||
xrdp_start
|
||||
;;
|
||||
*)
|
||||
echo "Usage: xrdp.sh {start|stop|restart|force-reload}"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
exit 0
|
@ -30,6 +30,7 @@
|
||||
#endif
|
||||
|
||||
#include "os_calls.h"
|
||||
#include "string_calls.h"
|
||||
#include "ssl_calls.h"
|
||||
#include "arch.h"
|
||||
#include "list.h"
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit ef68593b7d19c89cff2a2d27c6ab3cc5f33611da
|
||||
Subproject commit 6cb61ab7ca51520e6a5f18db47669e0f6e2ecee8
|
@ -23,28 +23,36 @@
|
||||
#endif
|
||||
|
||||
#include "libxrdp.h"
|
||||
#include "string_calls.h"
|
||||
#include "xrdp_orders_rail.h"
|
||||
|
||||
#define LOG_LEVEL 1
|
||||
#define LLOG(_level, _args) \
|
||||
do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
|
||||
#define LLOGLN(_level, _args) \
|
||||
do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
|
||||
#include "ms-rdpbcgr.h"
|
||||
|
||||
|
||||
|
||||
#define MAX_BITMAP_BUF_SIZE (16 * 1024) /* 16K */
|
||||
|
||||
/******************************************************************************/
|
||||
struct xrdp_session *EXPORT_CC
|
||||
libxrdp_init(tbus id, struct trans *trans)
|
||||
libxrdp_init(tbus id, struct trans *trans, const char *xrdp_ini)
|
||||
{
|
||||
struct xrdp_session *session;
|
||||
|
||||
session = (struct xrdp_session *)g_malloc(sizeof(struct xrdp_session), 1);
|
||||
session->id = id;
|
||||
session->trans = trans;
|
||||
if (xrdp_ini != NULL)
|
||||
{
|
||||
session->xrdp_ini = g_strdup(xrdp_ini);
|
||||
}
|
||||
else
|
||||
{
|
||||
session->xrdp_ini = g_strdup(XRDP_CFG_PATH "/xrdp.ini");
|
||||
}
|
||||
session->rdp = xrdp_rdp_create(session, trans);
|
||||
session->orders = xrdp_orders_create(session, (struct xrdp_rdp *)session->rdp);
|
||||
session->client_info = &(((struct xrdp_rdp *)session->rdp)->client_info);
|
||||
session->check_for_app_input = 1;
|
||||
return session;
|
||||
}
|
||||
|
||||
@ -59,6 +67,7 @@ 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;
|
||||
}
|
||||
@ -113,7 +122,7 @@ libxrdp_get_pdu_bytes(const char *aheader)
|
||||
/******************************************************************************/
|
||||
/* only used during connection */
|
||||
struct stream *
|
||||
libxrdp_force_read(struct trans* trans)
|
||||
libxrdp_force_read(struct trans *trans)
|
||||
{
|
||||
int bytes;
|
||||
struct stream *s;
|
||||
@ -123,24 +132,18 @@ libxrdp_force_read(struct trans* trans)
|
||||
|
||||
if (trans_force_read(trans, 4) != 0)
|
||||
{
|
||||
g_writeln("libxrdp_force_read: error");
|
||||
LOG(LOG_LEVEL_WARNING, "libxrdp_force_read: header read error");
|
||||
return 0;
|
||||
}
|
||||
bytes = libxrdp_get_pdu_bytes(s->data);
|
||||
if (bytes < 1)
|
||||
if (bytes < 4 || bytes > s->size)
|
||||
{
|
||||
g_writeln("libxrdp_force_read: error");
|
||||
LOG(LOG_LEVEL_WARNING, "libxrdp_force_read: bad header length %d", bytes);
|
||||
return 0;
|
||||
}
|
||||
if (bytes > 32 * 1024)
|
||||
{
|
||||
g_writeln("libxrdp_force_read: error");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (trans_force_read(trans, bytes - 4) != 0)
|
||||
{
|
||||
g_writeln("libxrdp_force_read: error");
|
||||
LOG(LOG_LEVEL_WARNING, "libxrdp_force_read: Can't read PDU");
|
||||
return 0;
|
||||
}
|
||||
return s;
|
||||
@ -161,12 +164,12 @@ libxrdp_process_data(struct xrdp_session *session, struct stream *s)
|
||||
do_read = s == 0;
|
||||
if (do_read && session->up_and_running)
|
||||
{
|
||||
g_writeln("libxrdp_process_data: error logic");
|
||||
LOG(LOG_LEVEL_ERROR, "libxrdp_process_data: error logic");
|
||||
return 1;
|
||||
}
|
||||
if (session->in_process_data != 0)
|
||||
{
|
||||
g_writeln("libxrdp_process_data: error reentry");
|
||||
LOG(LOG_LEVEL_ERROR, "libxrdp_process_data: error reentry");
|
||||
return 1;
|
||||
}
|
||||
session->in_process_data++;
|
||||
@ -206,7 +209,7 @@ libxrdp_process_data(struct xrdp_session *session, struct stream *s)
|
||||
}
|
||||
if (s == 0)
|
||||
{
|
||||
g_writeln("libxrdp_process_data: libxrdp_force_read failed");
|
||||
LOG(LOG_LEVEL_ERROR, "libxrdp_process_data: libxrdp_force_read failed");
|
||||
rv = 1;
|
||||
break;
|
||||
}
|
||||
@ -214,12 +217,12 @@ libxrdp_process_data(struct xrdp_session *session, struct stream *s)
|
||||
|
||||
if (xrdp_rdp_recv(rdp, s, &code) != 0)
|
||||
{
|
||||
g_writeln("libxrdp_process_data: xrdp_rdp_recv failed");
|
||||
LOG(LOG_LEVEL_ERROR, "libxrdp_process_data: xrdp_rdp_recv failed");
|
||||
rv = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUG(("libxrdp_process_data code %d", code));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_process_data code %d", code);
|
||||
|
||||
switch (code)
|
||||
{
|
||||
@ -236,7 +239,7 @@ libxrdp_process_data(struct xrdp_session *session, struct stream *s)
|
||||
case PDUTYPE_DATAPDU:
|
||||
if (xrdp_rdp_process_data(rdp, s) != 0)
|
||||
{
|
||||
DEBUG(("libxrdp_process_data returned non zero"));
|
||||
LOG(LOG_LEVEL_ERROR, "libxrdp_process_data returned non zero");
|
||||
cont = 0;
|
||||
term = 1;
|
||||
}
|
||||
@ -244,13 +247,13 @@ libxrdp_process_data(struct xrdp_session *session, struct stream *s)
|
||||
case 2: /* FASTPATH_INPUT_EVENT */
|
||||
if (xrdp_fastpath_process_input_event(rdp->sec_layer->fastpath_layer, s) != 0)
|
||||
{
|
||||
DEBUG(("libxrdp_process_data returned non zero"));
|
||||
LOG(LOG_LEVEL_ERROR, "libxrdp_process_data returned non zero");
|
||||
cont = 0;
|
||||
term = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_writeln("unknown in libxrdp_process_data: code= %d", code);
|
||||
LOG(LOG_LEVEL_ERROR, "unknown in libxrdp_process_data: code= %d", code);
|
||||
dead_lock_counter++;
|
||||
break;
|
||||
}
|
||||
@ -259,8 +262,8 @@ libxrdp_process_data(struct xrdp_session *session, struct stream *s)
|
||||
{
|
||||
/*This situation can happen and this is a workaround*/
|
||||
cont = 0;
|
||||
g_writeln("Serious programming error: we were locked in a deadly loop");
|
||||
g_writeln("Remaining: %d", (int) (s->end - s->next_packet));
|
||||
LOG(LOG_LEVEL_ERROR, "Serious programming error: we were locked in a deadly loop");
|
||||
LOG(LOG_LEVEL_ERROR, "Remaining: %d", (int) (s->end - s->next_packet));
|
||||
s->next_packet = 0;
|
||||
}
|
||||
|
||||
@ -289,7 +292,7 @@ libxrdp_send_palette(struct xrdp_session *session, int *palette)
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEBUG(("libxrdp_send_palette sending palette"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_send_palette sending palette");
|
||||
|
||||
/* clear orders */
|
||||
libxrdp_orders_force_send(session);
|
||||
@ -298,15 +301,16 @@ libxrdp_send_palette(struct xrdp_session *session, int *palette)
|
||||
|
||||
if (session->client_info->use_fast_path & 1) /* fastpath output supported */
|
||||
{
|
||||
LLOGLN(10, ("libxrdp_send_palette: fastpath"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_palette: fastpath");
|
||||
if (xrdp_rdp_init_fastpath((struct xrdp_rdp *)session->rdp, s) != 0)
|
||||
{
|
||||
free_stream(s);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
LLOGLN(10, ("libxrdp_send_palette: slowpath"));
|
||||
else
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_palette: slowpath");
|
||||
xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
|
||||
}
|
||||
|
||||
@ -360,7 +364,7 @@ libxrdp_send_bell(struct xrdp_session *session)
|
||||
{
|
||||
struct stream *s = (struct stream *)NULL;
|
||||
|
||||
DEBUG(("libxrdp_send_bell sending bell signal"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_send_bell sending bell signal");
|
||||
/* see MS documentation: Server play sound PDU, TS_PLAY_SOUND_PDU_DATA */
|
||||
|
||||
make_stream(s);
|
||||
@ -372,9 +376,11 @@ libxrdp_send_bell(struct xrdp_session *session)
|
||||
return 1;
|
||||
}
|
||||
|
||||
out_uint32_le(s, 440); /* frequency */
|
||||
out_uint32_le(s, 100); /* duration (ms) */
|
||||
out_uint32_le(s, 440); /* frequency */
|
||||
s_mark_end(s);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_PLAY_SOUND_PDU_DATA "
|
||||
"duration 100 ms, frequency 440 Hz");
|
||||
|
||||
if (xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, RDP_DATA_PDU_PLAY_SOUND) != 0)
|
||||
{
|
||||
@ -411,7 +417,7 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
|
||||
struct stream *temp_s = (struct stream *)NULL;
|
||||
tui32 pixel;
|
||||
|
||||
LLOGLN(10, ("libxrdp_send_bitmap: sending bitmap"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: sending bitmap");
|
||||
Bpp = (bpp + 7) / 8;
|
||||
e = (4 - width) & 3;
|
||||
switch (bpp)
|
||||
@ -431,14 +437,14 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
|
||||
line_bytes = width * Bpp;
|
||||
line_pad_bytes = line_bytes + e * Bpp;
|
||||
|
||||
LLOGLN(10, ("libxrdp_send_bitmap: bpp %d Bpp %d line_bytes %d "
|
||||
"server_line_bytes %d", bpp, Bpp, line_bytes, server_line_bytes));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: bpp %d Bpp %d line_bytes %d "
|
||||
"server_line_bytes %d", bpp, Bpp, line_bytes, server_line_bytes);
|
||||
make_stream(s);
|
||||
init_stream(s, MAX_BITMAP_BUF_SIZE);
|
||||
|
||||
if (session->client_info->use_bitmap_comp)
|
||||
{
|
||||
LLOGLN(10, ("libxrdp_send_bitmap: compression"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: compression");
|
||||
make_stream(temp_s);
|
||||
init_stream(temp_s, 65536);
|
||||
i = 0;
|
||||
@ -450,7 +456,7 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
|
||||
|
||||
while (i > 0)
|
||||
{
|
||||
LLOGLN(10, ("libxrdp_send_bitmap: i %d", i));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: i %d", i);
|
||||
|
||||
total_bufsize = 0;
|
||||
num_updates = 0;
|
||||
@ -474,13 +480,13 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
|
||||
|
||||
if (bpp > 24)
|
||||
{
|
||||
LLOGLN(10, ("libxrdp_send_bitmap: 32 bpp"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: 32 bpp");
|
||||
lines_sending = xrdp_bitmap32_compress(data, width, height,
|
||||
s, 32,
|
||||
(MAX_BITMAP_BUF_SIZE - 100) - total_bufsize,
|
||||
i - 1, temp_s, e, 0x10);
|
||||
LLOGLN(10, ("libxrdp_send_bitmap: i %d lines_sending %d",
|
||||
i, lines_sending));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: i %d lines_sending %d",
|
||||
i, lines_sending);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -488,8 +494,8 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
|
||||
s, bpp,
|
||||
(MAX_BITMAP_BUF_SIZE - 100) - total_bufsize,
|
||||
i - 1, temp_s, e);
|
||||
LLOGLN(10, ("libxrdp_send_bitmap: i %d lines_sending %d",
|
||||
i, lines_sending));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: i %d lines_sending %d",
|
||||
i, lines_sending);
|
||||
}
|
||||
|
||||
if (lines_sending == 0)
|
||||
@ -532,29 +538,29 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
|
||||
total_bufsize += 26; /* bytes since pop layer */
|
||||
}
|
||||
|
||||
LLOGLN(10, ("libxrdp_send_bitmap: decompressed pixels %d "
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: decompressed pixels %d "
|
||||
"decompressed bytes %d compressed bytes %d",
|
||||
lines_sending * (width + e),
|
||||
line_pad_bytes * lines_sending, bufsize));
|
||||
line_pad_bytes * lines_sending, bufsize);
|
||||
|
||||
if (j > MAX_BITMAP_BUF_SIZE)
|
||||
{
|
||||
LLOGLN(0, ("libxrdp_send_bitmap: error, decompressed "
|
||||
"size too big: %d bytes", j));
|
||||
LOG(LOG_LEVEL_WARNING, "libxrdp_send_bitmap: error, decompressed "
|
||||
"size too big: %d bytes", j);
|
||||
}
|
||||
|
||||
if (bufsize > MAX_BITMAP_BUF_SIZE)
|
||||
{
|
||||
LLOGLN(0, ("libxrdp_send_bitmap: error, compressed size "
|
||||
"too big: %d bytes", bufsize));
|
||||
LOG(LOG_LEVEL_WARNING, "libxrdp_send_bitmap: error, compressed size "
|
||||
"too big: %d bytes", bufsize);
|
||||
}
|
||||
|
||||
s->p = s->end;
|
||||
}
|
||||
while (total_bufsize < MAX_BITMAP_BUF_SIZE && i > 0);
|
||||
|
||||
LLOGLN(10, ("libxrdp_send_bitmap: num_updates %d total_bufsize %d",
|
||||
num_updates, total_bufsize));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: num_updates %d total_bufsize %d",
|
||||
num_updates, total_bufsize);
|
||||
|
||||
p_num_updates[0] = num_updates;
|
||||
p_num_updates[1] = num_updates >> 8;
|
||||
@ -563,8 +569,8 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
|
||||
|
||||
if (total_bufsize > MAX_BITMAP_BUF_SIZE)
|
||||
{
|
||||
LLOGLN(0, ("libxrdp_send_bitmap: error, total compressed "
|
||||
"size too big: %d bytes", total_bufsize));
|
||||
LOG(LOG_LEVEL_WARNING, "libxrdp_send_bitmap: error, total compressed "
|
||||
"size too big: %d bytes", total_bufsize);
|
||||
}
|
||||
}
|
||||
|
||||
@ -572,7 +578,7 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
|
||||
}
|
||||
else
|
||||
{
|
||||
LLOGLN(10, ("libxrdp_send_bitmap: no compression"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: no compression");
|
||||
total_lines = height;
|
||||
i = 0;
|
||||
p = data;
|
||||
@ -591,7 +597,7 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
|
||||
|
||||
if (lines_sending == 0)
|
||||
{
|
||||
LLOGLN(0, ("libxrdp_send_bitmap: error, lines_sending == zero"));
|
||||
LOG(LOG_LEVEL_WARNING, "libxrdp_send_bitmap: error, lines_sending == zero");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -627,7 +633,7 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
|
||||
q = q - server_line_bytes;
|
||||
for (k = 0; k < width; k++)
|
||||
{
|
||||
pixel = *((tui16*)(q + k * 2));
|
||||
pixel = *((tui16 *)(q + k * 2));
|
||||
out_uint16_le(s, pixel);
|
||||
}
|
||||
out_uint8s(s, e * 2);
|
||||
@ -639,7 +645,7 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
|
||||
q = q - server_line_bytes;
|
||||
for (k = 0; k < width; k++)
|
||||
{
|
||||
pixel = *((tui32*)(q + k * 4));
|
||||
pixel = *((tui32 *)(q + k * 4));
|
||||
out_uint8(s, pixel);
|
||||
out_uint8(s, pixel >> 8);
|
||||
out_uint8(s, pixel >> 16);
|
||||
@ -653,7 +659,7 @@ libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
|
||||
q = q - server_line_bytes;
|
||||
for (k = 0; k < width; k++)
|
||||
{
|
||||
pixel = *((int*)(q + k * 4));
|
||||
pixel = *((int *)(q + k * 4));
|
||||
out_uint32_le(s, pixel);
|
||||
}
|
||||
out_uint8s(s, e * 4);
|
||||
@ -686,7 +692,7 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
|
||||
int j;
|
||||
int data_bytes;
|
||||
|
||||
DEBUG(("libxrdp_send_pointer sending cursor"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_send_pointer sending cursor");
|
||||
if (bpp == 0)
|
||||
{
|
||||
bpp = 24;
|
||||
@ -696,14 +702,14 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
|
||||
{
|
||||
if (bpp != 24)
|
||||
{
|
||||
g_writeln("libxrdp_send_pointer: error client does not support "
|
||||
LOG(LOG_LEVEL_ERROR, "libxrdp_send_pointer: error client does not support "
|
||||
"new cursors and bpp is %d", bpp);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if ((bpp == 15) && (bpp != 16) && (bpp != 24) && (bpp != 32))
|
||||
{
|
||||
g_writeln("libxrdp_send_pointer: error");
|
||||
LOG(LOG_LEVEL_ERROR, "libxrdp_send_pointer: error");
|
||||
return 1;
|
||||
}
|
||||
make_stream(s);
|
||||
@ -711,7 +717,7 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
|
||||
|
||||
if (session->client_info->use_fast_path & 1) /* fastpath output supported */
|
||||
{
|
||||
LLOGLN(10, ("libxrdp_send_pointer: fastpath"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_pointer: fastpath");
|
||||
if (xrdp_rdp_init_fastpath((struct xrdp_rdp *)session->rdp, s) != 0)
|
||||
{
|
||||
free_stream(s);
|
||||
@ -730,7 +736,7 @@ libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
|
||||
}
|
||||
else /* slowpath */
|
||||
{
|
||||
LLOGLN(10, ("libxrdp_send_pointer: slowpath"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_pointer: slowpath");
|
||||
xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
|
||||
if ((session->client_info->pointer_flags & 1) == 0)
|
||||
{
|
||||
@ -837,14 +843,14 @@ libxrdp_set_pointer(struct xrdp_session *session, int cache_idx)
|
||||
{
|
||||
struct stream *s;
|
||||
|
||||
DEBUG(("libxrdp_set_pointer sending cursor index"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_set_pointer sending cursor index");
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
|
||||
|
||||
if (session->client_info->use_fast_path & 1) /* fastpath output supported */
|
||||
{
|
||||
LLOGLN(10, ("libxrdp_send_pointer: fastpath"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_pointer: fastpath");
|
||||
if (xrdp_rdp_init_fastpath((struct xrdp_rdp *)session->rdp, s) != 0)
|
||||
{
|
||||
free_stream(s);
|
||||
@ -853,7 +859,7 @@ libxrdp_set_pointer(struct xrdp_session *session, int cache_idx)
|
||||
}
|
||||
else
|
||||
{
|
||||
LLOGLN(10, ("libxrdp_send_pointer: slowpath"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_pointer: slowpath");
|
||||
xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
|
||||
out_uint16_le(s, RDP_POINTER_CACHED);
|
||||
out_uint16_le(s, 0); /* pad */
|
||||
@ -969,16 +975,16 @@ libxrdp_orders_mem_blt(struct xrdp_session *session, int cache_id,
|
||||
|
||||
/******************************************************************************/
|
||||
int
|
||||
libxrdp_orders_composite_blt(struct xrdp_session* session, int srcidx,
|
||||
libxrdp_orders_composite_blt(struct xrdp_session *session, int srcidx,
|
||||
int srcformat, int srcwidth, int srcrepeat,
|
||||
int* srctransform, int mskflags,
|
||||
int *srctransform, int mskflags,
|
||||
int mskidx, int mskformat, int mskwidth,
|
||||
int mskrepeat, int op, int srcx, int srcy,
|
||||
int mskx, int msky, int dstx, int dsty,
|
||||
int width, int height, int dstformat,
|
||||
struct xrdp_rect* rect)
|
||||
struct xrdp_rect *rect)
|
||||
{
|
||||
return xrdp_orders_composite_blt((struct xrdp_orders*)session->orders,
|
||||
return xrdp_orders_composite_blt((struct xrdp_orders *)session->orders,
|
||||
srcidx, srcformat, srcwidth, srcrepeat,
|
||||
srctransform, mskflags,
|
||||
mskidx, mskformat, mskwidth, mskrepeat,
|
||||
@ -1047,29 +1053,36 @@ libxrdp_orders_send_font(struct xrdp_session *session,
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Note : if this is called on a multimon setup, the client is resized
|
||||
* to a single monitor */
|
||||
int EXPORT_CC
|
||||
libxrdp_reset(struct xrdp_session *session,
|
||||
int width, int height, int bpp)
|
||||
{
|
||||
if (session->client_info != 0)
|
||||
{
|
||||
struct xrdp_client_info *client_info = session->client_info;
|
||||
|
||||
/* older client can't resize */
|
||||
if (session->client_info->build <= 419)
|
||||
if (client_info->build <= 419)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if same, don't need to do anything */
|
||||
if (session->client_info->width == width &&
|
||||
session->client_info->height == height &&
|
||||
session->client_info->bpp == bpp)
|
||||
/* if same (and only one monitor on client) don't need to do anything */
|
||||
if (client_info->width == width &&
|
||||
client_info->height == height &&
|
||||
client_info->bpp == bpp &&
|
||||
(client_info->monitorCount == 0 || client_info->multimon == 0))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
session->client_info->width = width;
|
||||
session->client_info->height = height;
|
||||
session->client_info->bpp = bpp;
|
||||
client_info->width = width;
|
||||
client_info->height = height;
|
||||
client_info->bpp = bpp;
|
||||
client_info->monitorCount = 0;
|
||||
client_info->multimon = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1082,7 +1095,12 @@ libxrdp_reset(struct xrdp_session *session,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* shut down the rdp client */
|
||||
/* shut down the rdp client
|
||||
*
|
||||
* When resetting the lib, disable application input checks, as
|
||||
* otherwise we can send a channel message to the other end while
|
||||
* the channels are inactive ([MS-RDPBCGR] 3.2.5.5.1 */
|
||||
session->check_for_app_input = 0;
|
||||
if (xrdp_rdp_send_deactivate((struct xrdp_rdp *)session->rdp) != 0)
|
||||
{
|
||||
return 1;
|
||||
@ -1094,6 +1112,9 @@ libxrdp_reset(struct xrdp_session *session,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Re-enable application input checks */
|
||||
session->check_for_app_input = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1149,7 +1170,7 @@ libxrdp_query_channel(struct xrdp_session *session, int index,
|
||||
|
||||
if (mcs->channel_list == NULL)
|
||||
{
|
||||
g_writeln("libxrdp_query_channel - No channel initialized");
|
||||
LOG(LOG_LEVEL_ERROR, "libxrdp_query_channel - No channel initialized");
|
||||
return 1 ;
|
||||
}
|
||||
|
||||
@ -1157,7 +1178,7 @@ libxrdp_query_channel(struct xrdp_session *session, int index,
|
||||
|
||||
if (index < 0 || index >= count)
|
||||
{
|
||||
DEBUG(("libxrdp_query_channel - Channel out of range %d", index));
|
||||
LOG(LOG_LEVEL_ERROR, "libxrdp_query_channel - Channel out of range %d", index);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1167,14 +1188,14 @@ libxrdp_query_channel(struct xrdp_session *session, int index,
|
||||
if (channel_item == 0)
|
||||
{
|
||||
/* this should not happen */
|
||||
g_writeln("libxrdp_query_channel - channel item is 0");
|
||||
LOG(LOG_LEVEL_ERROR, "libxrdp_query_channel - channel item is 0");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (channel_name != 0)
|
||||
{
|
||||
g_strncpy(channel_name, channel_item->name, 8);
|
||||
DEBUG(("libxrdp_query_channel - Channel %d name %s", index, channel_name));
|
||||
LOG(LOG_LEVEL_ERROR, "libxrdp_query_channel - Channel %d name %s", index, channel_name);
|
||||
}
|
||||
|
||||
if (channel_flags != 0)
|
||||
@ -1202,7 +1223,7 @@ libxrdp_get_channel_id(struct xrdp_session *session, const char *name)
|
||||
|
||||
if (mcs->channel_list == NULL)
|
||||
{
|
||||
g_writeln("libxrdp_get_channel_id No channel initialized");
|
||||
LOG(LOG_LEVEL_ERROR, "libxrdp_get_channel_id No channel initialized");
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
@ -1254,7 +1275,7 @@ libxrdp_send_to_channel(struct xrdp_session *session, int channel_id,
|
||||
|
||||
if (xrdp_channel_send(chan, s, channel_id, total_data_len, flags) != 0)
|
||||
{
|
||||
g_writeln("libxrdp_send_to_channel: error, server channel data NOT sent to client channel");
|
||||
LOG(LOG_LEVEL_ERROR, "libxrdp_send_to_channel: error, server channel data NOT sent to client channel");
|
||||
free_stream(s);
|
||||
return 1;
|
||||
}
|
||||
@ -1476,7 +1497,7 @@ libxrdp_codec_jpeg_compress(struct xrdp_session *session,
|
||||
char *out_data, int *io_len)
|
||||
{
|
||||
struct xrdp_orders *orders;
|
||||
void* jpeg_han;
|
||||
void *jpeg_han;
|
||||
|
||||
orders = (struct xrdp_orders *)(session->orders);
|
||||
jpeg_han = orders->jpeg_han;
|
||||
@ -1488,7 +1509,7 @@ libxrdp_codec_jpeg_compress(struct xrdp_session *session,
|
||||
/*****************************************************************************/
|
||||
int EXPORT_CC
|
||||
libxrdp_fastpath_send_surface(struct xrdp_session *session,
|
||||
char* data_pad, int pad_bytes,
|
||||
char *data_pad, int pad_bytes,
|
||||
int data_bytes,
|
||||
int destLeft, int destTop,
|
||||
int destRight, int destBottom, int bpp,
|
||||
@ -1502,7 +1523,7 @@ libxrdp_fastpath_send_surface(struct xrdp_session *session,
|
||||
int max_bytes;
|
||||
int cmd_bytes;
|
||||
|
||||
LLOGLN(10, ("libxrdp_fastpath_send_surface:"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_fastpath_send_surface:");
|
||||
if ((session->client_info->use_fast_path & 1) == 0)
|
||||
{
|
||||
return 1;
|
||||
@ -1561,7 +1582,7 @@ libxrdp_fastpath_send_frame_marker(struct xrdp_session *session,
|
||||
struct stream *s;
|
||||
struct xrdp_rdp *rdp;
|
||||
|
||||
LLOGLN(10, ("libxrdp_fastpath_send_frame_marker:"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_fastpath_send_frame_marker:");
|
||||
if ((session->client_info->use_fast_path & 1) == 0)
|
||||
{
|
||||
return 1;
|
||||
@ -1595,7 +1616,7 @@ libxrdp_send_session_info(struct xrdp_session *session, const char *data,
|
||||
{
|
||||
struct xrdp_rdp *rdp;
|
||||
|
||||
LLOGLN(10, ("libxrdp_send_session_info:"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_session_info:");
|
||||
rdp = (struct xrdp_rdp *) (session->rdp);
|
||||
return xrdp_rdp_send_session_info(rdp, data, data_bytes);
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "os_calls.h"
|
||||
#include "ssl_calls.h"
|
||||
#include "list.h"
|
||||
#include "log.h"
|
||||
#include "file.h"
|
||||
#include "libxrdpinc.h"
|
||||
#include "xrdp_client_info.h"
|
||||
|
@ -66,6 +66,7 @@ struct xrdp_session
|
||||
struct trans *trans;
|
||||
int (*callback)(intptr_t id, int msg, intptr_t param1, intptr_t param2,
|
||||
intptr_t param3, intptr_t param4);
|
||||
int check_for_app_input;
|
||||
void *rdp;
|
||||
void *orders;
|
||||
struct xrdp_client_info *client_info;
|
||||
@ -74,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
|
||||
@ -84,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
|
||||
|
@ -33,11 +33,7 @@ http://msdn.microsoft.com/en-us/library/cc241877.aspx
|
||||
#define FLAGS_RLE 0x10
|
||||
#define FLAGS_NOALPHA 0x20
|
||||
|
||||
#define LLOG_LEVEL 1
|
||||
#define LLOGLN(_level, _args) \
|
||||
do { if (_level < LLOG_LEVEL) { g_writeln _args ; } } while (0)
|
||||
#define LHEXDUMP(_level, _args) \
|
||||
do { if (_level < LLOG_LEVEL) { g_hexdump _args ; } } while (0)
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* split RGB */
|
||||
@ -85,9 +81,9 @@ fsplit3(char *in_data, int start_line, int width, int e,
|
||||
rp |= (pixel << 8) & 0xff000000;
|
||||
gp |= (pixel << 16) & 0xff000000;
|
||||
bp |= (pixel << 24) & 0xff000000;
|
||||
*((int*)(r_data + out_index)) = rp;
|
||||
*((int*)(g_data + out_index)) = gp;
|
||||
*((int*)(b_data + out_index)) = bp;
|
||||
*((int *)(r_data + out_index)) = rp;
|
||||
*((int *)(g_data + out_index)) = gp;
|
||||
*((int *)(b_data + out_index)) = bp;
|
||||
out_index += 4;
|
||||
index += 4;
|
||||
}
|
||||
@ -170,10 +166,10 @@ fsplit4(char *in_data, int start_line, int width, int e,
|
||||
rp |= (pixel << 8) & 0xff000000;
|
||||
gp |= (pixel << 16) & 0xff000000;
|
||||
bp |= (pixel << 24) & 0xff000000;
|
||||
*((int*)(a_data + out_index)) = ap;
|
||||
*((int*)(r_data + out_index)) = rp;
|
||||
*((int*)(g_data + out_index)) = gp;
|
||||
*((int*)(b_data + out_index)) = bp;
|
||||
*((int *)(a_data + out_index)) = ap;
|
||||
*((int *)(r_data + out_index)) = rp;
|
||||
*((int *)(g_data + out_index)) = gp;
|
||||
*((int *)(b_data + out_index)) = bp;
|
||||
out_index += 4;
|
||||
index += 4;
|
||||
}
|
||||
@ -209,13 +205,13 @@ fsplit4(char *in_data, int start_line, int width, int e,
|
||||
|
||||
/*****************************************************************************/
|
||||
#define DELTA_ONE \
|
||||
do { \
|
||||
do { \
|
||||
delta = src8[cx] - src8[0]; \
|
||||
is_neg = (delta >> 7) & 1; \
|
||||
dst8[cx] = (((delta ^ -is_neg) + is_neg) << 1) - is_neg; \
|
||||
src8++; \
|
||||
dst8++; \
|
||||
} while (0)
|
||||
} while (0)
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
@ -258,7 +254,7 @@ fout(int collen, int replen, char *colptr, struct stream *s)
|
||||
int lreplen;
|
||||
int cont;
|
||||
|
||||
LLOGLN(10, ("fout: collen %d replen %d", collen, replen));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "fout: collen %d replen %d", collen, replen);
|
||||
cont = collen > 13;
|
||||
while (cont)
|
||||
{
|
||||
@ -285,7 +281,7 @@ fout(int collen, int replen, char *colptr, struct stream *s)
|
||||
{
|
||||
lreplen = 47;
|
||||
}
|
||||
LLOGLN(10, ("fout: big run lreplen %d", lreplen));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "fout: big run lreplen %d", lreplen);
|
||||
replen -= lreplen;
|
||||
code = ((lreplen & 0xF) << 4) | ((lreplen & 0xF0) >> 4);
|
||||
out_uint8(s, code);
|
||||
@ -326,13 +322,13 @@ fpack(char *plane, int cx, int cy, struct stream *s)
|
||||
int collen;
|
||||
int replen;
|
||||
|
||||
LLOGLN(10, ("fpack:"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "fpack:");
|
||||
holdp = s->p;
|
||||
for (jndex = 0; jndex < cy; jndex++)
|
||||
{
|
||||
LLOGLN(10, ("line start line %d cx %d cy %d", jndex, cx, cy));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "line start line %d cx %d cy %d", jndex, cx, cy);
|
||||
ptr8 = plane + jndex * cx;
|
||||
LHEXDUMP(10, (ptr8, cx));
|
||||
LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "line content", ptr8, cx);
|
||||
lend = ptr8 + (cx - 1);
|
||||
colptr = ptr8;
|
||||
if (colptr[0] == 0)
|
||||
@ -437,7 +433,7 @@ xrdp_bitmap32_compress(char *in_data, int width, int height,
|
||||
int total_bytes;
|
||||
int header;
|
||||
|
||||
LLOGLN(10, ("xrdp_bitmap32_compress:"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_bitmap32_compress:");
|
||||
max_bytes = 4 * 1024;
|
||||
/* need max 8, 4K planes for work */
|
||||
if (max_bytes * 8 > temp_s->size)
|
||||
|
@ -24,6 +24,8 @@
|
||||
#endif
|
||||
|
||||
#include "libxrdp.h"
|
||||
#include "ms-rdpbcgr.h"
|
||||
#include "ms-rdperp.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
@ -75,7 +77,7 @@ xrdp_caps_process_general(struct xrdp_rdp *self, struct stream *s,
|
||||
|
||||
if (len < 10 + 2)
|
||||
{
|
||||
g_writeln("xrdp_caps_process_general: error");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_general: error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -110,10 +112,10 @@ xrdp_caps_process_order(struct xrdp_rdp *self, struct stream *s,
|
||||
int ex_flags;
|
||||
int cap_flags;
|
||||
|
||||
DEBUG(("order capabilities"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "order capabilities");
|
||||
if (len < 20 + 2 + 2 + 2 + 2 + 2 + 2 + 32 + 2 + 2 + 4 + 4 + 4 + 4)
|
||||
{
|
||||
g_writeln("xrdp_caps_process_order: error");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_order: error");
|
||||
return 1;
|
||||
}
|
||||
in_uint8s(s, 20); /* Terminal desc, pad */
|
||||
@ -125,25 +127,23 @@ xrdp_caps_process_order(struct xrdp_rdp *self, struct stream *s,
|
||||
in_uint16_le(s, cap_flags); /* Capability flags */
|
||||
in_uint8a(s, order_caps, 32); /* Orders supported */
|
||||
g_memcpy(self->client_info.orders, order_caps, 32);
|
||||
DEBUG(("dest blt-0 %d", order_caps[0]));
|
||||
DEBUG(("pat blt-1 %d", order_caps[1]));
|
||||
DEBUG(("screen blt-2 %d", order_caps[2]));
|
||||
DEBUG(("memblt-3-13 %d %d", order_caps[3], order_caps[13]));
|
||||
DEBUG(("triblt-4-14 %d %d", order_caps[4], order_caps[14]));
|
||||
DEBUG(("line-8 %d", order_caps[8]));
|
||||
DEBUG(("line-9 %d", order_caps[9]));
|
||||
DEBUG(("rect-10 %d", order_caps[10]));
|
||||
DEBUG(("desksave-11 %d", order_caps[11]));
|
||||
DEBUG(("polygon-20 %d", order_caps[20]));
|
||||
DEBUG(("polygon2-21 %d", order_caps[21]));
|
||||
DEBUG(("polyline-22 %d", order_caps[22]));
|
||||
DEBUG(("ellipse-25 %d", order_caps[25]));
|
||||
DEBUG(("ellipse2-26 %d", order_caps[26]));
|
||||
DEBUG(("text2-27 %d", order_caps[27]));
|
||||
DEBUG(("order_caps dump"));
|
||||
#if defined(XRDP_DEBUG)
|
||||
g_hexdump(order_caps, 32);
|
||||
#endif
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "dest blt-0 %d", order_caps[0]);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "pat blt-1 %d", order_caps[1]);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "screen blt-2 %d", order_caps[2]);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "memblt-3-13 %d %d", order_caps[3], order_caps[13]);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "triblt-4-14 %d %d", order_caps[4], order_caps[14]);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "line-8 %d", order_caps[8]);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "line-9 %d", order_caps[9]);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "rect-10 %d", order_caps[10]);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "desksave-11 %d", order_caps[11]);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "polygon-20 %d", order_caps[20]);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "polygon2-21 %d", order_caps[21]);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "polyline-22 %d", order_caps[22]);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "ellipse-25 %d", order_caps[25]);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "ellipse2-26 %d", order_caps[26]);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "text2-27 %d", order_caps[27]);
|
||||
LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "order_caps dump", order_caps, 32);
|
||||
|
||||
in_uint8s(s, 2); /* Text capability flags */
|
||||
/* read extended order support flags */
|
||||
in_uint16_le(s, ex_flags); /* Ex flags */
|
||||
@ -153,7 +153,7 @@ xrdp_caps_process_order(struct xrdp_rdp *self, struct stream *s,
|
||||
self->client_info.order_flags_ex = ex_flags;
|
||||
if (ex_flags & XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT)
|
||||
{
|
||||
g_writeln("xrdp_caps_process_order: bitmap cache v3 supported");
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_process_order: bitmap cache v3 supported");
|
||||
self->client_info.bitmap_cache_version |= 4;
|
||||
}
|
||||
}
|
||||
@ -161,7 +161,7 @@ xrdp_caps_process_order(struct xrdp_rdp *self, struct stream *s,
|
||||
|
||||
in_uint32_le(s, i); /* desktop cache size, usually 0x38400 */
|
||||
self->client_info.desktop_cache = i;
|
||||
DEBUG(("desktop cache size %d", i));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "desktop cache size %d", i);
|
||||
in_uint8s(s, 4); /* Unknown */
|
||||
in_uint8s(s, 4); /* Unknown */
|
||||
|
||||
@ -169,7 +169,7 @@ xrdp_caps_process_order(struct xrdp_rdp *self, struct stream *s,
|
||||
if (!(order_caps[TS_NEG_DSTBLT_INDEX] && order_caps[TS_NEG_PATBLT_INDEX] &&
|
||||
order_caps[TS_NEG_SCRBLT_INDEX] && order_caps[TS_NEG_MEMBLT_INDEX]))
|
||||
{
|
||||
g_writeln("xrdp_caps_process_order: not enough orders supported by client, using painter.");
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_process_order: not enough orders supported by client, using painter.");
|
||||
self->client_info.no_orders_supported = 1;
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@ xrdp_caps_process_bmpcache(struct xrdp_rdp *self, struct stream *s,
|
||||
|
||||
if (len < 24 + 2 + 2 + 2 + 2 + 2 + 2)
|
||||
{
|
||||
g_writeln("xrdp_caps_process_bmpcache: error");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_bmpcache: error");
|
||||
return 1;
|
||||
}
|
||||
self->client_info.bitmap_cache_version |= 1;
|
||||
@ -209,12 +209,12 @@ xrdp_caps_process_bmpcache(struct xrdp_rdp *self, struct stream *s,
|
||||
i = MAX(i, 0);
|
||||
self->client_info.cache3_entries = i;
|
||||
in_uint16_le(s, self->client_info.cache3_size);
|
||||
DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries,
|
||||
self->client_info.cache1_size));
|
||||
DEBUG(("cache2 entries %d size %d", self->client_info.cache2_entries,
|
||||
self->client_info.cache2_size));
|
||||
DEBUG(("cache3 entries %d size %d", self->client_info.cache3_entries,
|
||||
self->client_info.cache3_size));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "cache1 entries %d size %d", self->client_info.cache1_entries,
|
||||
self->client_info.cache1_size);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "cache2 entries %d size %d", self->client_info.cache2_entries,
|
||||
self->client_info.cache2_size);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "cache3 entries %d size %d", self->client_info.cache3_entries,
|
||||
self->client_info.cache3_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -229,7 +229,7 @@ xrdp_caps_process_bmpcache2(struct xrdp_rdp *self, struct stream *s,
|
||||
|
||||
if (len < 2 + 2 + 4 + 4 + 4)
|
||||
{
|
||||
g_writeln("xrdp_caps_process_bmpcache2: error");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_bmpcache2: error");
|
||||
return 1;
|
||||
}
|
||||
self->client_info.bitmap_cache_version |= 2;
|
||||
@ -253,12 +253,12 @@ xrdp_caps_process_bmpcache2(struct xrdp_rdp *self, struct stream *s,
|
||||
i = MAX(i, 0);
|
||||
self->client_info.cache3_entries = i;
|
||||
self->client_info.cache3_size = 4096 * Bpp;
|
||||
DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries,
|
||||
self->client_info.cache1_size));
|
||||
DEBUG(("cache2 entries %d size %d", self->client_info.cache2_entries,
|
||||
self->client_info.cache2_size));
|
||||
DEBUG(("cache3 entries %d size %d", self->client_info.cache3_entries,
|
||||
self->client_info.cache3_size));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "cache1 entries %d size %d", self->client_info.cache1_entries,
|
||||
self->client_info.cache1_size);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "cache2 entries %d size %d", self->client_info.cache2_entries,
|
||||
self->client_info.cache2_size);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "cache3 entries %d size %d", self->client_info.cache3_entries,
|
||||
self->client_info.cache3_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -271,11 +271,11 @@ xrdp_caps_process_cache_v3_codec_id(struct xrdp_rdp *self, struct stream *s,
|
||||
|
||||
if (len < 1)
|
||||
{
|
||||
g_writeln("xrdp_caps_process_cache_v3_codec_id: error");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_cache_v3_codec_id: error");
|
||||
return 1;
|
||||
}
|
||||
in_uint8(s, codec_id);
|
||||
g_writeln("xrdp_caps_process_cache_v3_codec_id: cache_v3_codec_id %d",
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_process_cache_v3_codec_id: cache_v3_codec_id %d",
|
||||
codec_id);
|
||||
self->client_info.v3_codec_id = codec_id;
|
||||
return 0;
|
||||
@ -293,7 +293,7 @@ xrdp_caps_process_pointer(struct xrdp_rdp *self, struct stream *s,
|
||||
|
||||
if (len < 2 + 2 + 2)
|
||||
{
|
||||
g_writeln("xrdp_caps_process_pointer: error");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_pointer: error");
|
||||
return 1;
|
||||
}
|
||||
no_new_cursor = self->client_info.pointer_flags & 2;
|
||||
@ -304,7 +304,7 @@ xrdp_caps_process_pointer(struct xrdp_rdp *self, struct stream *s,
|
||||
self->client_info.pointer_cache_entries = i;
|
||||
if (colorPointerFlag & 1)
|
||||
{
|
||||
g_writeln("xrdp_caps_process_pointer: client supports "
|
||||
LOG(LOG_LEVEL_INFO, "xrdp_caps_process_pointer: client supports "
|
||||
"new(color) cursor");
|
||||
in_uint16_le(s, i);
|
||||
i = MIN(i, 32);
|
||||
@ -312,12 +312,12 @@ xrdp_caps_process_pointer(struct xrdp_rdp *self, struct stream *s,
|
||||
}
|
||||
else
|
||||
{
|
||||
g_writeln("xrdp_caps_process_pointer: client does not support "
|
||||
LOG(LOG_LEVEL_INFO, "xrdp_caps_process_pointer: client does not support "
|
||||
"new(color) cursor");
|
||||
}
|
||||
if (no_new_cursor)
|
||||
{
|
||||
g_writeln("xrdp_caps_process_pointer: new(color) cursor is "
|
||||
LOG(LOG_LEVEL_INFO, "xrdp_caps_process_pointer: new(color) cursor is "
|
||||
"disabled by config");
|
||||
self->client_info.pointer_flags = 0;
|
||||
}
|
||||
@ -352,7 +352,7 @@ xrdp_caps_process_brushcache(struct xrdp_rdp *self, struct stream *s,
|
||||
|
||||
if (len < 4)
|
||||
{
|
||||
g_writeln("xrdp_caps_process_brushcache: error");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_brushcache: error");
|
||||
return 1;
|
||||
}
|
||||
in_uint32_le(s, code);
|
||||
@ -369,7 +369,7 @@ xrdp_caps_process_glyphcache(struct xrdp_rdp *self, struct stream *s,
|
||||
|
||||
if (len < 40 + 4 + 2 + 2) /* MS-RDPBCGR 2.2.7.1.8 */
|
||||
{
|
||||
g_writeln("xrdp_caps_process_glyphcache: error");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_glyphcache: error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -382,7 +382,7 @@ xrdp_caps_process_glyphcache(struct xrdp_rdp *self, struct stream *s,
|
||||
{
|
||||
self->client_info.use_cache_glyph_v2 = 1;
|
||||
}
|
||||
g_writeln("xrdp_caps_process_glyphcache: support level %d ",
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_process_glyphcache: support level %d ",
|
||||
glyph_support_level);
|
||||
return 0;
|
||||
}
|
||||
@ -396,7 +396,7 @@ xrdp_caps_process_offscreen_bmpcache(struct xrdp_rdp *self, struct stream *s,
|
||||
|
||||
if (len < 4 + 2 + 2)
|
||||
{
|
||||
g_writeln("xrdp_caps_process_offscreen_bmpcache: error");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_offscreen_bmpcache: error");
|
||||
return 1;
|
||||
}
|
||||
in_uint32_le(s, i32);
|
||||
@ -405,7 +405,7 @@ xrdp_caps_process_offscreen_bmpcache(struct xrdp_rdp *self, struct stream *s,
|
||||
self->client_info.offscreen_cache_size = i32 * 1024;
|
||||
in_uint16_le(s, i32);
|
||||
self->client_info.offscreen_cache_entries = i32;
|
||||
g_writeln("xrdp_process_offscreen_bmpcache: support level %d "
|
||||
LOG(LOG_LEVEL_INFO, "xrdp_process_offscreen_bmpcache: support level %d "
|
||||
"cache size %d MB cache entries %d",
|
||||
self->client_info.offscreen_support_level,
|
||||
self->client_info.offscreen_cache_size,
|
||||
@ -421,12 +421,12 @@ xrdp_caps_process_rail(struct xrdp_rdp *self, struct stream *s, int len)
|
||||
|
||||
if (len < 4)
|
||||
{
|
||||
g_writeln("xrdp_caps_process_rail: error");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_rail: error");
|
||||
return 1;
|
||||
}
|
||||
in_uint32_le(s, i32);
|
||||
self->client_info.rail_support_level = i32;
|
||||
g_writeln("xrdp_process_capset_rail: rail_support_level %d",
|
||||
LOG(LOG_LEVEL_INFO, "xrdp_process_capset_rail: rail_support_level %d",
|
||||
self->client_info.rail_support_level);
|
||||
return 0;
|
||||
}
|
||||
@ -439,7 +439,7 @@ xrdp_caps_process_window(struct xrdp_rdp *self, struct stream *s, int len)
|
||||
|
||||
if (len < 4 + 1 + 2)
|
||||
{
|
||||
g_writeln("xrdp_caps_process_window: error");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_window: error");
|
||||
return 1;
|
||||
}
|
||||
in_uint32_le(s, i32);
|
||||
@ -448,7 +448,7 @@ xrdp_caps_process_window(struct xrdp_rdp *self, struct stream *s, int len)
|
||||
self->client_info.wnd_num_icon_caches = i32;
|
||||
in_uint16_le(s, i32);
|
||||
self->client_info.wnd_num_icon_cache_entries = i32;
|
||||
g_writeln("xrdp_process_capset_window wnd_support_level %d "
|
||||
LOG(LOG_LEVEL_INFO, "xrdp_process_capset_window wnd_support_level %d "
|
||||
"wnd_num_icon_caches %d wnd_num_icon_cache_entries %d",
|
||||
self->client_info.wnd_support_level,
|
||||
self->client_info.wnd_num_icon_caches,
|
||||
@ -470,7 +470,7 @@ xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len)
|
||||
|
||||
if (len < 1)
|
||||
{
|
||||
g_writeln("xrdp_caps_process_codecs: error");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_codecs: error");
|
||||
return 1;
|
||||
}
|
||||
in_uint8(s, codec_count);
|
||||
@ -481,7 +481,7 @@ xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len)
|
||||
codec_guid = s->p;
|
||||
if (len < 16 + 1 + 2)
|
||||
{
|
||||
g_writeln("xrdp_caps_process_codecs: error");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_codecs: error");
|
||||
return 1;
|
||||
}
|
||||
in_uint8s(s, 16);
|
||||
@ -490,7 +490,7 @@ xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len)
|
||||
len -= 16 + 1 + 2;
|
||||
if (len < codec_properties_length)
|
||||
{
|
||||
g_writeln("xrdp_caps_process_codecs: error");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_codecs: error");
|
||||
return 1;
|
||||
}
|
||||
len -= codec_properties_length;
|
||||
@ -498,7 +498,7 @@ xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len)
|
||||
|
||||
if (g_memcmp(codec_guid, XR_CODEC_GUID_NSCODEC, 16) == 0)
|
||||
{
|
||||
g_writeln("xrdp_caps_process_codecs: nscodec, codec id %d, properties len %d",
|
||||
LOG(LOG_LEVEL_INFO, "xrdp_caps_process_codecs: nscodec, codec id %d, properties len %d",
|
||||
codec_id, codec_properties_length);
|
||||
self->client_info.ns_codec_id = codec_id;
|
||||
i1 = MIN(64, codec_properties_length);
|
||||
@ -507,7 +507,7 @@ xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len)
|
||||
}
|
||||
else if (g_memcmp(codec_guid, XR_CODEC_GUID_REMOTEFX, 16) == 0)
|
||||
{
|
||||
g_writeln("xrdp_caps_process_codecs: RemoteFX, codec id %d, properties len %d",
|
||||
LOG(LOG_LEVEL_INFO, "xrdp_caps_process_codecs: RemoteFX, codec id %d, properties len %d",
|
||||
codec_id, codec_properties_length);
|
||||
self->client_info.rfx_codec_id = codec_id;
|
||||
i1 = MIN(64, codec_properties_length);
|
||||
@ -516,7 +516,7 @@ xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len)
|
||||
}
|
||||
else if (g_memcmp(codec_guid, XR_CODEC_GUID_JPEG, 16) == 0)
|
||||
{
|
||||
g_writeln("xrdp_caps_process_codecs: jpeg, codec id %d, properties len %d",
|
||||
LOG(LOG_LEVEL_INFO, "xrdp_caps_process_codecs: jpeg, codec id %d, properties len %d",
|
||||
codec_id, codec_properties_length);
|
||||
self->client_info.jpeg_codec_id = codec_id;
|
||||
i1 = MIN(64, codec_properties_length);
|
||||
@ -525,15 +525,15 @@ xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len)
|
||||
/* make sure that requested quality is between 0 to 100 */
|
||||
if (self->client_info.jpeg_prop[0] < 0 || self->client_info.jpeg_prop[0] > 100)
|
||||
{
|
||||
g_writeln(" Warning: the requested jpeg quality (%d) is invalid,"
|
||||
" falling back to default", self->client_info.jpeg_prop[0]);
|
||||
LOG(LOG_LEVEL_WARNING, " Warning: the requested jpeg quality (%d) is invalid, "
|
||||
"falling back to default", self->client_info.jpeg_prop[0]);
|
||||
self->client_info.jpeg_prop[0] = 75; /* use default */
|
||||
}
|
||||
g_writeln(" jpeg quality set to %d", self->client_info.jpeg_prop[0]);
|
||||
LOG(LOG_LEVEL_INFO, " jpeg quality set to %d", self->client_info.jpeg_prop[0]);
|
||||
}
|
||||
else if (g_memcmp(codec_guid, XR_CODEC_GUID_H264, 16) == 0)
|
||||
{
|
||||
g_writeln("xrdp_caps_process_codecs: h264, codec id %d, properties len %d",
|
||||
LOG(LOG_LEVEL_INFO, "xrdp_caps_process_codecs: h264, codec id %d, properties len %d",
|
||||
codec_id, codec_properties_length);
|
||||
self->client_info.h264_codec_id = codec_id;
|
||||
i1 = MIN(64, codec_properties_length);
|
||||
@ -542,7 +542,7 @@ xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len)
|
||||
}
|
||||
else
|
||||
{
|
||||
g_writeln("xrdp_caps_process_codecs: unknown codec id %d", codec_id);
|
||||
LOG(LOG_LEVEL_WARNING, "xrdp_caps_process_codecs: unknown codec id %d", codec_id);
|
||||
}
|
||||
|
||||
s->p = next_guid;
|
||||
@ -559,24 +559,27 @@ xrdp_caps_process_multifragmentupdate(struct xrdp_rdp *self, struct stream *s,
|
||||
int MaxRequestSize;
|
||||
|
||||
in_uint32_le(s, MaxRequestSize);
|
||||
if (self->client_info.use_fast_path & 1)
|
||||
{
|
||||
self->client_info.max_fastpath_frag_bytes = MaxRequestSize;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
xrdp_caps_process_frame_ack(struct xrdp_rdp *self, struct stream *s, int len)
|
||||
{
|
||||
g_writeln("xrdp_caps_process_frame_ack:");
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_process_frame_ack:");
|
||||
self->client_info.use_frame_acks = 1;
|
||||
in_uint32_le(s, self->client_info.max_unacknowledged_frame_count);
|
||||
if (self->client_info.max_unacknowledged_frame_count < 0)
|
||||
{
|
||||
g_writeln(" invalid max_unacknowledged_frame_count value (%d), setting to 0",
|
||||
LOG(LOG_LEVEL_WARNING, " invalid max_unacknowledged_frame_count value (%d), setting to 0",
|
||||
self->client_info.max_unacknowledged_frame_count);
|
||||
self->client_info.max_unacknowledged_frame_count = 0;
|
||||
}
|
||||
g_writeln(" max_unacknowledged_frame_count %d", self->client_info.max_unacknowledged_frame_count);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " max_unacknowledged_frame_count %d", self->client_info.max_unacknowledged_frame_count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -585,10 +588,15 @@ static int
|
||||
xrdp_caps_process_surface_cmds(struct xrdp_rdp *self, struct stream *s, int len)
|
||||
{
|
||||
int cmdFlags;
|
||||
g_writeln("xrdp_caps_process_surface_cmds:");
|
||||
#ifndef XRDP_DEBUG
|
||||
/* TODO: remove UNUSED_VAR once the `cmdFlags` variable is used for more than
|
||||
logging in debug mode */
|
||||
UNUSED_VAR(cmdFlags);
|
||||
#endif
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_process_surface_cmds:");
|
||||
in_uint32_le(s, cmdFlags);
|
||||
in_uint8s(s, 4); /* reserved */
|
||||
g_writeln(" cmdFlags 0x%08x", cmdFlags);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " cmdFlags 0x%08x", cmdFlags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -604,7 +612,7 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
|
||||
int len;
|
||||
char *p;
|
||||
|
||||
DEBUG(("in xrdp_caps_process_confirm_active"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_caps_process_confirm_active");
|
||||
in_uint8s(s, 4); /* rdp_shareid */
|
||||
in_uint8s(s, 2); /* userid */
|
||||
in_uint16_le(s, source_len); /* sizeof RDP_SOURCE */
|
||||
@ -623,14 +631,14 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
|
||||
p = s->p;
|
||||
if (!s_check_rem(s, 4))
|
||||
{
|
||||
g_writeln("xrdp_caps_process_confirm_active: error 1");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_confirm_active: error 1");
|
||||
return 1;
|
||||
}
|
||||
in_uint16_le(s, type);
|
||||
in_uint16_le(s, len);
|
||||
if ((len < 4) || !s_check_rem(s, len - 4))
|
||||
{
|
||||
g_writeln("xrdp_caps_process_confirm_active: error: len %d, "
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_confirm_active: error: len %d, "
|
||||
"remaining %d", len, (int) (s->end - s->p));
|
||||
return 1;
|
||||
}
|
||||
@ -638,71 +646,71 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
|
||||
switch (type)
|
||||
{
|
||||
case CAPSTYPE_GENERAL:
|
||||
DEBUG(("CAPSTYPE_GENERAL"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_GENERAL");
|
||||
xrdp_caps_process_general(self, s, len);
|
||||
break;
|
||||
case CAPSTYPE_BITMAP:
|
||||
DEBUG(("CAPSTYPE_BITMAP"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_BITMAP");
|
||||
break;
|
||||
case CAPSTYPE_ORDER:
|
||||
DEBUG(("CAPSTYPE_ORDER"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_ORDER");
|
||||
xrdp_caps_process_order(self, s, len);
|
||||
break;
|
||||
case CAPSTYPE_BITMAPCACHE:
|
||||
DEBUG(("CAPSTYPE_BMPCACHE"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_BMPCACHE");
|
||||
xrdp_caps_process_bmpcache(self, s, len);
|
||||
break;
|
||||
case CAPSTYPE_CONTROL:
|
||||
DEBUG(("CAPSTYPE_CONTROL"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_CONTROL");
|
||||
break;
|
||||
case 6:
|
||||
xrdp_caps_process_cache_v3_codec_id(self, s, len);
|
||||
break;
|
||||
case CAPSTYPE_ACTIVATION:
|
||||
DEBUG(("CAPSTYPE_ACTIVAION"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_ACTIVAION");
|
||||
break;
|
||||
case CAPSTYPE_POINTER:
|
||||
DEBUG(("CAPSTYPE_POINTER"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_POINTER");
|
||||
xrdp_caps_process_pointer(self, s, len);
|
||||
break;
|
||||
case CAPSTYPE_SHARE:
|
||||
DEBUG(("CAPSTYPE_SHARE"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_SHARE");
|
||||
break;
|
||||
case CAPSTYPE_COLORCACHE:
|
||||
DEBUG(("CAPSTYPE_COLORCACHE"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_COLORCACHE");
|
||||
break;
|
||||
case CAPSTYPE_SOUND:
|
||||
DEBUG(("CAPSTYPE_SOUND"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_SOUND");
|
||||
break;
|
||||
case CAPSTYPE_INPUT:
|
||||
xrdp_caps_process_input(self, s, len);
|
||||
break;
|
||||
case CAPSTYPE_FONT:
|
||||
DEBUG(("CAPSTYPE_FONT"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_FONT");
|
||||
break;
|
||||
case CAPSTYPE_BRUSH:
|
||||
xrdp_caps_process_brushcache(self, s, len);
|
||||
break;
|
||||
case CAPSTYPE_GLYPHCACHE:
|
||||
DEBUG(("CAPSTYPE_GLYPHCACHE"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_GLYPHCACHE");
|
||||
xrdp_caps_process_glyphcache(self, s, len);
|
||||
break;
|
||||
case CAPSTYPE_OFFSCREENCACHE:
|
||||
DEBUG(("CAPSTYPE_OFFSCREENCACHE"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_OFFSCREENCACHE");
|
||||
xrdp_caps_process_offscreen_bmpcache(self, s, len);
|
||||
break;
|
||||
case CAPSTYPE_BITMAPCACHE_REV2:
|
||||
DEBUG(("CAPSTYPE_BITMAPCACHE_REV2"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_BITMAPCACHE_REV2");
|
||||
xrdp_caps_process_bmpcache2(self, s, len);
|
||||
break;
|
||||
case CAPSTYPE_VIRTUALCHANNEL:
|
||||
DEBUG(("CAPSTYPE_VIRTUALCHANNEL"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_VIRTUALCHANNEL");
|
||||
break;
|
||||
case CAPSTYPE_DRAWNINGRIDCACHE:
|
||||
DEBUG(("CAPSTYPE_DRAWNINGRIDCACHE"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_DRAWNINGRIDCACHE");
|
||||
break;
|
||||
case CAPSTYPE_DRAWGDIPLUS:
|
||||
DEBUG(("CAPSTYPE_DRAWGDIPLUS"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_DRAWGDIPLUS");
|
||||
break;
|
||||
case CAPSTYPE_RAIL:
|
||||
xrdp_caps_process_rail(self, s, len);
|
||||
@ -723,7 +731,7 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
|
||||
xrdp_caps_process_frame_ack(self, s, len);
|
||||
break;
|
||||
default:
|
||||
g_writeln("unknown in xrdp_caps_process_confirm_active %d", type);
|
||||
LOG(LOG_LEVEL_WARNING, "unknown in xrdp_caps_process_confirm_active %d", type);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -733,7 +741,7 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
|
||||
if (self->client_info.no_orders_supported &&
|
||||
(self->client_info.offscreen_support_level != 0))
|
||||
{
|
||||
g_writeln("xrdp_caps_process_confirm_active: not enough orders "
|
||||
LOG(LOG_LEVEL_WARNING, "xrdp_caps_process_confirm_active: not enough orders "
|
||||
"supported by client, client wants off screen bitmap but "
|
||||
"offscreen bitmaps disabled");
|
||||
self->client_info.offscreen_support_level = 0;
|
||||
@ -741,7 +749,7 @@ xrdp_caps_process_confirm_active(struct xrdp_rdp *self, struct stream *s)
|
||||
self->client_info.offscreen_cache_entries = 0;
|
||||
}
|
||||
|
||||
DEBUG(("out xrdp_caps_process_confirm_active"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_caps_process_confirm_active");
|
||||
return 0;
|
||||
}
|
||||
/*****************************************************************************/
|
||||
@ -763,7 +771,7 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
|
||||
DEBUG(("in xrdp_caps_send_demand_active"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_caps_send_demand_active");
|
||||
|
||||
if (xrdp_rdp_init(self, s) != 0)
|
||||
{
|
||||
@ -1030,16 +1038,16 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
|
||||
free_stream(s);
|
||||
return 1;
|
||||
}
|
||||
DEBUG(("out (1) xrdp_caps_send_demand_active"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "out (1) xrdp_caps_send_demand_active");
|
||||
|
||||
/* send Monitor Layout PDU for dual monitor */
|
||||
if (self->client_info.monitorCount > 0 &&
|
||||
self->client_info.multimon == 1)
|
||||
{
|
||||
DEBUG(("xrdp_caps_send_demand_active: sending monitor layout pdu"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: sending monitor layout pdu");
|
||||
if (xrdp_caps_send_monitorlayout(self) != 0)
|
||||
{
|
||||
g_writeln("xrdp_caps_send_demand_active: error sending monitor layout pdu");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_caps_send_demand_active: error sending monitor layout pdu");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#endif
|
||||
|
||||
#include "libxrdp.h"
|
||||
#include "string_calls.h"
|
||||
|
||||
/* todo, move these to constants.h */
|
||||
//#define CHANNEL_CHUNK_LENGTH 1600 /* todo, why is this so small? */
|
||||
@ -51,7 +52,7 @@ xrdp_channel_get_item(struct xrdp_channel *self, int channel_id)
|
||||
|
||||
if (self->mcs_layer->channel_list == NULL)
|
||||
{
|
||||
g_writeln("xrdp_channel_get_item - No channel initialized");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_channel_get_item - No channel initialized");
|
||||
return NULL ;
|
||||
}
|
||||
|
||||
@ -114,13 +115,13 @@ xrdp_channel_send(struct xrdp_channel *self, struct stream *s, int channel_id,
|
||||
|
||||
if (channel == NULL)
|
||||
{
|
||||
g_writeln("xrdp_channel_send - no such channel");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_channel_send - no such channel");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (channel->disabled)
|
||||
{
|
||||
g_writeln("xrdp_channel_send, channel disabled");
|
||||
LOG(LOG_LEVEL_WARNING, "xrdp_channel_send, channel disabled");
|
||||
return 0; /* not an error */
|
||||
}
|
||||
|
||||
@ -138,16 +139,16 @@ xrdp_channel_send(struct xrdp_channel *self, struct stream *s, int channel_id,
|
||||
*
|
||||
* That's flag makes MSTSC crash when using RAIL channel.
|
||||
*/
|
||||
// if (channel->flags & XR_CHANNEL_OPTION_SHOW_PROTOCOL)
|
||||
// {
|
||||
// flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
|
||||
// }
|
||||
// if (channel->flags & XR_CHANNEL_OPTION_SHOW_PROTOCOL)
|
||||
// {
|
||||
// flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
|
||||
// }
|
||||
|
||||
out_uint32_le(s, flags);
|
||||
|
||||
if (xrdp_sec_send(self->sec_layer, s, channel->chanid) != 0)
|
||||
{
|
||||
g_writeln("xrdp_channel_send - failure sending data");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_channel_send - failure sending data");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -182,12 +183,12 @@ xrdp_channel_call_callback(struct xrdp_channel *self, struct stream *s,
|
||||
}
|
||||
else
|
||||
{
|
||||
g_writeln("in xrdp_channel_call_callback, session->callback is nil");
|
||||
LOG(LOG_LEVEL_TRACE, "in xrdp_channel_call_callback, session->callback is nil");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_writeln("in xrdp_channel_call_callback, session is nil");
|
||||
LOG(LOG_LEVEL_TRACE, "in xrdp_channel_call_callback, session is nil");
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -269,11 +270,11 @@ drdynvc_process_capability_response(struct xrdp_channel *self,
|
||||
in_uint16_le(s, cap_version);
|
||||
if ((cap_version != 2) && (cap_version != 3))
|
||||
{
|
||||
g_writeln("drdynvc_process_capability_response: incompatible DVC "
|
||||
LOG(LOG_LEVEL_ERROR, "drdynvc_process_capability_response: incompatible DVC "
|
||||
"version %d detected", cap_version);
|
||||
return 1;
|
||||
}
|
||||
g_writeln("drdynvc_process_capability_response: DVC version %d selected",
|
||||
LOG(LOG_LEVEL_INFO, "drdynvc_process_capability_response: DVC version %d selected",
|
||||
cap_version);
|
||||
self->drdynvc_state = 1;
|
||||
session = self->sec_layer->rdp_layer->session;
|
||||
@ -300,8 +301,8 @@ drdynvc_process_open_channel_response(struct xrdp_channel *self,
|
||||
return 1;
|
||||
}
|
||||
in_uint32_le(s, creation_status);
|
||||
//g_writeln("drdynvc_process_open_channel_response: chan_id 0x%x "
|
||||
// "creation_status %d", chan_id, creation_status);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "drdynvc_process_open_channel_response: chan_id 0x%x "
|
||||
"creation_status %d", chan_id, creation_status);
|
||||
session = self->sec_layer->rdp_layer->session;
|
||||
if (chan_id > 255)
|
||||
{
|
||||
@ -336,7 +337,7 @@ drdynvc_process_close_channel_response(struct xrdp_channel *self,
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
//g_writeln("drdynvc_process_close_channel_response: chan_id 0x%x", chan_id);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "drdynvc_process_close_channel_response: chan_id 0x%x", chan_id);
|
||||
session = self->sec_layer->rdp_layer->session;
|
||||
if (chan_id > 255)
|
||||
{
|
||||
@ -393,7 +394,7 @@ drdynvc_process_data_first(struct xrdp_channel *self,
|
||||
in_uint32_le(s, total_bytes);
|
||||
}
|
||||
bytes = (int) (s->end - s->p);
|
||||
//g_writeln("drdynvc_process_data_first: bytes %d total_bytes %d", bytes, total_bytes);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "drdynvc_process_data_first: bytes %d total_bytes %d", bytes, total_bytes);
|
||||
session = self->sec_layer->rdp_layer->session;
|
||||
if (chan_id > 255)
|
||||
{
|
||||
@ -423,7 +424,7 @@ drdynvc_process_data(struct xrdp_channel *self,
|
||||
return 1;
|
||||
}
|
||||
bytes = (int) (s->end - s->p);
|
||||
//g_writeln("drdynvc_process_data: bytes %d", bytes);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "drdynvc_process_data: bytes %d", bytes);
|
||||
session = self->sec_layer->rdp_layer->session;
|
||||
if (chan_id > 255)
|
||||
{
|
||||
@ -456,13 +457,17 @@ xrdp_channel_process_drdynvc(struct xrdp_channel *self,
|
||||
}
|
||||
in_uint32_le(s, total_length);
|
||||
in_uint32_le(s, flags);
|
||||
//g_writeln("xrdp_channel_process_drdynvc: total_length %d flags 0x%8.8x",
|
||||
// total_length, flags);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_channel_process_drdynvc: total_length %d flags 0x%8.8x",
|
||||
total_length, flags);
|
||||
ls = NULL;
|
||||
switch (flags & 3)
|
||||
{
|
||||
case 0:
|
||||
length = (int) (s->end - s->p);
|
||||
if (!s_check_rem_out(self->s, length))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
out_uint8a(self->s, s->p, length);
|
||||
in_uint8s(s, length);
|
||||
return 0;
|
||||
@ -471,11 +476,19 @@ 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;
|
||||
@ -484,7 +497,7 @@ xrdp_channel_process_drdynvc(struct xrdp_channel *self,
|
||||
ls = s;
|
||||
break;
|
||||
default:
|
||||
g_writeln("xrdp_channel_process_drdynvc: error");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_channel_process_drdynvc: error");
|
||||
return 1;
|
||||
}
|
||||
if (ls == NULL)
|
||||
@ -492,7 +505,7 @@ xrdp_channel_process_drdynvc(struct xrdp_channel *self,
|
||||
return 1;
|
||||
}
|
||||
in_uint8(ls, cmd); /* read command */
|
||||
//g_writeln("xrdp_channel_process_drdynvc: cmd 0x%x", cmd);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_channel_process_drdynvc: cmd 0x%x", cmd);
|
||||
rv = 1;
|
||||
switch (cmd & 0xf0)
|
||||
{
|
||||
@ -512,11 +525,11 @@ xrdp_channel_process_drdynvc(struct xrdp_channel *self,
|
||||
rv = drdynvc_process_data(self, cmd, s);
|
||||
break;
|
||||
default:
|
||||
g_writeln("xrdp_channel_process_drdynvc: got unknown "
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_channel_process_drdynvc: got unknown "
|
||||
"command 0x%x", cmd);
|
||||
break;
|
||||
}
|
||||
//g_writeln("xrdp_channel_process_drdynvc: rv %d", rv);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_channel_process_drdynvc: rv %d", rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -544,12 +557,12 @@ xrdp_channel_process(struct xrdp_channel *self, struct stream *s,
|
||||
channel = xrdp_channel_get_item(self, channel_id);
|
||||
if (channel == NULL)
|
||||
{
|
||||
g_writeln("xrdp_channel_process, channel not found");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_channel_process, channel not found");
|
||||
return 1;
|
||||
}
|
||||
if (channel->disabled)
|
||||
{
|
||||
g_writeln("xrdp_channel_process, channel disabled");
|
||||
LOG(LOG_LEVEL_WARNING, "xrdp_channel_process, channel disabled");
|
||||
return 0; /* not an error */
|
||||
}
|
||||
if (channel_id == self->drdynvc_channel_id)
|
||||
@ -614,7 +627,7 @@ xrdp_channel_drdynvc_start(struct xrdp_channel *self)
|
||||
struct mcs_channel_item *ci;
|
||||
struct mcs_channel_item *dci;
|
||||
|
||||
g_writeln("xrdp_channel_drdynvc_start:");
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_channel_drdynvc_start:");
|
||||
dci = NULL;
|
||||
count = self->mcs_layer->channel_list->count;
|
||||
for (index = 0; index < count; index++)
|
||||
|
@ -22,6 +22,7 @@
|
||||
#endif
|
||||
|
||||
#include "libxrdp.h"
|
||||
#include "ms-rdpbcgr.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
struct xrdp_fastpath *
|
||||
@ -29,12 +30,12 @@ xrdp_fastpath_create(struct xrdp_sec *owner, struct trans *trans)
|
||||
{
|
||||
struct xrdp_fastpath *self;
|
||||
|
||||
DEBUG((" in xrdp_fastpath_create"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_fastpath_create");
|
||||
self = (struct xrdp_fastpath *)g_malloc(sizeof(struct xrdp_fastpath), 1);
|
||||
self->sec_layer = owner;
|
||||
self->trans = trans;
|
||||
self->session = owner->rdp_layer->session;
|
||||
DEBUG((" out xrdp_fastpath_create"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_fastpath_create");
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -66,7 +67,7 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s)
|
||||
int byte;
|
||||
char *holdp;
|
||||
|
||||
DEBUG((" in xrdp_fastpath_recv"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_fastpath_recv");
|
||||
holdp = s->p;
|
||||
if (!s_check_rem(s, 2))
|
||||
{
|
||||
@ -96,7 +97,7 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s)
|
||||
len = byte;
|
||||
}
|
||||
s->next_packet = holdp + len;
|
||||
DEBUG((" out xrdp_fastpath_recv"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_fastpath_recv");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -145,7 +146,10 @@ xrdp_fastpath_send(struct xrdp_fastpath *self, struct stream *s)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (self->session->check_for_app_input)
|
||||
{
|
||||
xrdp_fastpath_session_callback(self, 0x5556, 0, 0, 0, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -175,7 +179,9 @@ xrdp_fastpath_process_EVENT_SCANCODE(struct xrdp_fastpath *self,
|
||||
}
|
||||
|
||||
if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_EXTENDED))
|
||||
{
|
||||
flags |= KBD_FLAG_EXT;
|
||||
}
|
||||
|
||||
xrdp_fastpath_session_callback(self, RDP_INPUT_SCANCODE,
|
||||
code, 0, flags, 0);
|
||||
@ -361,7 +367,7 @@ xrdp_fastpath_process_input_event(struct xrdp_fastpath *self,
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_writeln("xrdp_fastpath_process_input_event: unknown "
|
||||
LOG(LOG_LEVEL_WARNING, "xrdp_fastpath_process_input_event: unknown "
|
||||
"eventCode %d", eventCode);
|
||||
break;
|
||||
}
|
||||
|
@ -24,15 +24,10 @@
|
||||
#endif
|
||||
|
||||
#include "libxrdp.h"
|
||||
#include "ms-rdpbcgr.h"
|
||||
#include "log.h"
|
||||
|
||||
#define LOG_LEVEL 1
|
||||
#define LLOG(_level, _args) \
|
||||
do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
|
||||
#define LLOGLN(_level, _args) \
|
||||
do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
|
||||
#define LHEXDUMP(_level, _args) \
|
||||
do { if (_level < LOG_LEVEL) { g_hexdump _args ; } } while (0)
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -41,11 +36,11 @@ xrdp_iso_create(struct xrdp_mcs *owner, struct trans *trans)
|
||||
{
|
||||
struct xrdp_iso *self;
|
||||
|
||||
LLOGLN(10, (" in xrdp_iso_create"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, " in xrdp_iso_create");
|
||||
self = (struct xrdp_iso *) g_malloc(sizeof(struct xrdp_iso), 1);
|
||||
self->mcs_layer = owner;
|
||||
self->trans = trans;
|
||||
LLOGLN(10, (" out xrdp_iso_create"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, " out xrdp_iso_create");
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -82,7 +77,7 @@ xrdp_iso_negotiate_security(struct xrdp_iso *self)
|
||||
!g_file_readable(client_info->key_file))
|
||||
{
|
||||
/* certificate or privkey is not readable */
|
||||
log_message(LOG_LEVEL_DEBUG, "No readable certificates or "
|
||||
LOG(LOG_LEVEL_WARNING, "No readable certificates or "
|
||||
"private keys, cannot accept TLS connections");
|
||||
self->failureCode = SSL_CERT_NOT_ON_SERVER;
|
||||
rv = 1; /* error */
|
||||
@ -115,7 +110,7 @@ xrdp_iso_negotiate_security(struct xrdp_iso *self)
|
||||
break;
|
||||
}
|
||||
|
||||
log_message(LOG_LEVEL_DEBUG, "Security layer: requested %d, selected %d",
|
||||
LOG(LOG_LEVEL_DEBUG, "Security layer: requested %d, selected %d",
|
||||
self->requestedProtocol, self->selectedProtocol);
|
||||
return rv;
|
||||
}
|
||||
@ -128,73 +123,90 @@ xrdp_iso_process_rdp_neg_req(struct xrdp_iso *self, struct stream *s)
|
||||
int flags;
|
||||
int len;
|
||||
|
||||
if (!s_check_rem(s, 7))
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_iso_process_rdpNegReq: unexpected end-of-record");
|
||||
return 1;
|
||||
}
|
||||
|
||||
in_uint8(s, flags);
|
||||
if (flags != 0x0 && flags != 0x8 && flags != 0x1)
|
||||
{
|
||||
LLOGLN(10, ("xrdp_iso_process_rdpNegReq: error, flags: %x",flags));
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_iso_process_rdpNegReq: error, flags: %x", flags);
|
||||
return 1;
|
||||
}
|
||||
|
||||
in_uint16_le(s, len);
|
||||
if (len != 8)
|
||||
{
|
||||
LLOGLN(10, ("xrdp_iso_process_rdpNegReq: error, length: %x",len));
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_iso_process_rdpNegReq: error, length: %x", len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
in_uint32_le(s, self->requestedProtocol);
|
||||
if (self->requestedProtocol > 0xb)
|
||||
{
|
||||
LLOGLN(10, ("xrdp_iso_process_rdpNegReq: error, requestedProtocol: %x",
|
||||
self->requestedProtocol));
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_iso_process_rdpNegReq: error, requestedProtocol: %x",
|
||||
self->requestedProtocol);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
/*****************************************************************************
|
||||
* Reads an X.224 PDU (X.224 section 13) preceded by a T.123 TPKT
|
||||
* header (T.123 section 8)
|
||||
*
|
||||
* On entry, the TPKT header length field will have been inspected and used to
|
||||
* set up the input stream.
|
||||
*
|
||||
* On exit, the TPKT header and the fixed part of the PDU header will have been
|
||||
* removed from the stream.
|
||||
*
|
||||
* Returns error
|
||||
*****************************************************************************/
|
||||
static int
|
||||
xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len)
|
||||
{
|
||||
int ver;
|
||||
int plen;
|
||||
|
||||
*code = 0;
|
||||
*len = 0;
|
||||
|
||||
if (s != self->trans->in_s)
|
||||
{
|
||||
LLOGLN(10, ("xrdp_iso_recv_msg error logic"));
|
||||
LOG(LOG_LEVEL_WARNING, "xrdp_iso_recv_msg error logic");
|
||||
}
|
||||
|
||||
/* TPKT header is 4 bytes, then first 2 bytes of the X.224 CR-TPDU */
|
||||
if (!s_check_rem(s, 6))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
in_uint8(s, ver);
|
||||
|
||||
if (ver != 3)
|
||||
{
|
||||
LLOGLN(10, ("xrdp_iso_recv_msg: bad ver"));
|
||||
LHEXDUMP(10, (s->data, 4));
|
||||
return 1;
|
||||
}
|
||||
|
||||
in_uint8s(s, 1);
|
||||
in_uint16_be(s, plen);
|
||||
|
||||
if (plen < 4)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!s_check_rem(s, 2))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
in_uint8s(s, 3); /* Skip reserved field, plus length */
|
||||
in_uint8(s, *len);
|
||||
in_uint8(s, *code);
|
||||
|
||||
if (ver != 3)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_iso_recv_msg: bad ver");
|
||||
LOG_DEVEL_HEXDUMP(LOG_LEVEL_ERROR, "header", s->data, 4);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (*len == 255)
|
||||
{
|
||||
/* X.224 13.2.1 - reserved value */
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_iso_recv_msg: reserved length encountered");
|
||||
LOG_DEVEL_HEXDUMP(LOG_LEVEL_ERROR, "header", s->data, 4);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (*code == ISO_PDU_DT)
|
||||
{
|
||||
/* Data PDU : X.224 13.7 */
|
||||
if (!s_check_rem(s, 1))
|
||||
{
|
||||
return 1;
|
||||
@ -203,6 +215,7 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Other supported PDUs : X.224 13.x */
|
||||
if (!s_check_rem(s, 5))
|
||||
{
|
||||
return 1;
|
||||
@ -221,21 +234,21 @@ xrdp_iso_recv(struct xrdp_iso *self, struct stream *s)
|
||||
int code;
|
||||
int len;
|
||||
|
||||
LLOGLN(10, (" in xrdp_iso_recv"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, " in xrdp_iso_recv");
|
||||
|
||||
if (xrdp_iso_recv_msg(self, s, &code, &len) != 0)
|
||||
{
|
||||
LLOGLN(10, (" out xrdp_iso_recv xrdp_iso_recv_msg return non zero"));
|
||||
LOG(LOG_LEVEL_ERROR, " out xrdp_iso_recv xrdp_iso_recv_msg return non zero");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (code != ISO_PDU_DT || len != 2)
|
||||
{
|
||||
LLOGLN(10, (" out xrdp_iso_recv code != ISO_PDU_DT or length != 2"));
|
||||
LOG(LOG_LEVEL_ERROR, " out xrdp_iso_recv code != ISO_PDU_DT or length != 2");
|
||||
return 1;
|
||||
}
|
||||
|
||||
LLOGLN(10, (" out xrdp_iso_recv"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, " out xrdp_iso_recv");
|
||||
return 0;
|
||||
}
|
||||
/*****************************************************************************/
|
||||
@ -301,7 +314,20 @@ xrdp_iso_send_cc(struct xrdp_iso *self)
|
||||
free_stream(s);
|
||||
return 0;
|
||||
}
|
||||
/*****************************************************************************/
|
||||
/*****************************************************************************
|
||||
* Process an X.224 connection request PDU
|
||||
*
|
||||
* See MS-RDPCGR v20190923 sections 2.2.1.1 and 3.3.5.3.1.
|
||||
*
|
||||
* From the latter, in particular:-
|
||||
* - The length embedded in the TPKT header MUST be examined for
|
||||
* consistency with the received data. If there is a discrepancy, the
|
||||
* connection SHOULD be dropped
|
||||
* - If the optional routingToken field exists it MUST be ignored.
|
||||
* - If the optional cookie field is present it MUST be ignored.
|
||||
* - If both the routingToken and cookie fields are present, the server
|
||||
* SHOULD continue with the connection.
|
||||
*****************************************************************************/
|
||||
/* returns error */
|
||||
int
|
||||
xrdp_iso_incoming(struct xrdp_iso *self)
|
||||
@ -309,35 +335,47 @@ xrdp_iso_incoming(struct xrdp_iso *self)
|
||||
int rv = 0;
|
||||
int code;
|
||||
int len;
|
||||
int cookie_index;
|
||||
int cc_type;
|
||||
char text[256];
|
||||
char *pend;
|
||||
struct stream *s;
|
||||
int expected_pdu_len;
|
||||
|
||||
LLOGLN(10, (" in xrdp_iso_incoming"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, " in xrdp_iso_incoming");
|
||||
|
||||
s = libxrdp_force_read(self->trans);
|
||||
if (s == 0)
|
||||
if (s == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (xrdp_iso_recv_msg(self, s, &code, &len) != 0)
|
||||
{
|
||||
LLOGLN(0, ("xrdp_iso_incoming: xrdp_iso_recv_msg returned non zero"));
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_iso_incoming: xrdp_iso_recv_msg returned non zero");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((code != ISO_PDU_CR) || (len < 6))
|
||||
if (code != ISO_PDU_CR)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure the length indicator field extracted from the X.224
|
||||
* connection request TPDU corresponds to the length in the TPKT header.
|
||||
*
|
||||
* We do this by seeing how the indicator field minus the counted
|
||||
* octets in the TPDU header (6) compares with the space left in
|
||||
* the stream.
|
||||
*/
|
||||
expected_pdu_len = (s->end - s->p) + 6;
|
||||
if (len != expected_pdu_len)
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_iso_incoming: X.224 CR-TPDU length exp %d got %d",
|
||||
expected_pdu_len, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* process connection request */
|
||||
pend = s->p + (len - 6);
|
||||
cookie_index = 0;
|
||||
while (s->p < pend)
|
||||
while (s_check_rem(s, 1))
|
||||
{
|
||||
in_uint8(s, cc_type);
|
||||
switch (cc_type)
|
||||
@ -348,34 +386,36 @@ xrdp_iso_incoming(struct xrdp_iso *self)
|
||||
self->rdpNegData = 1;
|
||||
if (xrdp_iso_process_rdp_neg_req(self, s) != 0)
|
||||
{
|
||||
LLOGLN(0, ("xrdp_iso_incoming: xrdp_iso_process_rdpNegReq returned non zero"));
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_iso_incoming: xrdp_iso_process_rdpNegReq returned non zero");
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case RDP_CORRELATION_INFO: /* rdpCorrelationInfo 6 */
|
||||
// TODO
|
||||
if (!s_check_rem(s, 1 + 2 + 16 + 16))
|
||||
{
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_iso_incoming: short correlation info");
|
||||
return 1;
|
||||
}
|
||||
|
||||
in_uint8s(s, 1 + 2 + 16 + 16);
|
||||
break;
|
||||
case 'C': /* Cookie routingToken */
|
||||
while (s->p < pend)
|
||||
case 'C': /* Cookie */
|
||||
/* The routingToken and cookie fields are both ASCII
|
||||
* strings starting with the word 'Cookie: ' and
|
||||
* ending with CR+LF. We ignore both, so we do
|
||||
* not need to distinguish them */
|
||||
while (s_check_rem(s, 1))
|
||||
{
|
||||
text[cookie_index] = cc_type;
|
||||
cookie_index++;
|
||||
if (cookie_index > 255)
|
||||
in_uint8(s, cc_type);
|
||||
if (cc_type == 0x0D && s_check_rem(s, 1))
|
||||
{
|
||||
cookie_index = 255;
|
||||
}
|
||||
if ((s->p[0] == 0x0D) && (s->p[1] == 0x0A))
|
||||
in_uint8(s, cc_type);
|
||||
if (cc_type == 0x0A)
|
||||
{
|
||||
in_uint8s(s, 2);
|
||||
text[cookie_index] = 0;
|
||||
cookie_index = 0;
|
||||
if (g_strlen(text) > 0)
|
||||
{
|
||||
}
|
||||
break;
|
||||
}
|
||||
in_uint8(s, cc_type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -387,11 +427,11 @@ xrdp_iso_incoming(struct xrdp_iso *self)
|
||||
/* send connection confirm back to client */
|
||||
if (xrdp_iso_send_cc(self) != 0)
|
||||
{
|
||||
LLOGLN(0, ("xrdp_iso_incoming: xrdp_iso_send_cc returned non zero"));
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_iso_incoming: xrdp_iso_send_cc returned non zero");
|
||||
return 1;
|
||||
}
|
||||
|
||||
LLOGLN(10, (" out xrdp_iso_incoming"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, " out xrdp_iso_incoming");
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -412,7 +452,7 @@ xrdp_iso_send(struct xrdp_iso *self, struct stream *s)
|
||||
{
|
||||
int len;
|
||||
|
||||
LLOGLN(10, (" in xrdp_iso_send"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, " in xrdp_iso_send");
|
||||
s_pop_layer(s, iso_hdr);
|
||||
len = (int) (s->end - s->p);
|
||||
out_uint8(s, 3);
|
||||
@ -427,6 +467,6 @@ xrdp_iso_send(struct xrdp_iso *self, struct stream *s)
|
||||
return 1;
|
||||
}
|
||||
|
||||
LLOGLN(10, (" out xrdp_iso_send"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, " out xrdp_iso_send");
|
||||
return 0;
|
||||
}
|
||||
|
@ -55,12 +55,12 @@ xrdp_jpeg_compress(void *handle, char *in_data, int width, int height,
|
||||
|
||||
if (bpp != 24)
|
||||
{
|
||||
g_writeln("xrdp_jpeg_compress: bpp wrong %d", bpp);
|
||||
LOG(LOG_LEVEL_WARNING, "xrdp_jpeg_compress: bpp wrong %d", bpp);
|
||||
return height;
|
||||
}
|
||||
if (handle == 0)
|
||||
{
|
||||
g_writeln("xrdp_jpeg_compress: handle is nil");
|
||||
LOG(LOG_LEVEL_WARNING, "xrdp_jpeg_compress: handle is nil");
|
||||
return height;
|
||||
}
|
||||
tj_han = (tjhandle) handle;
|
||||
@ -70,7 +70,7 @@ xrdp_jpeg_compress(void *handle, char *in_data, int width, int height,
|
||||
temp_buf = 0;
|
||||
if (e == 0)
|
||||
{
|
||||
src_buf = (unsigned char*)in_data;
|
||||
src_buf = (unsigned char *)in_data;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -97,13 +97,13 @@ xrdp_jpeg_compress(void *handle, char *in_data, int width, int height,
|
||||
}
|
||||
src_buf = (unsigned char *) temp_buf;
|
||||
}
|
||||
dst_buf = (unsigned char*)(s->p);
|
||||
dst_buf = (unsigned char *)(s->p);
|
||||
error = tjCompress(tj_han, src_buf, width + e, (width + e) * 4, height,
|
||||
TJPF_XBGR, dst_buf, &cdata_bytes,
|
||||
TJSAMP_420, quality, 0);
|
||||
if (error != 0)
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR,
|
||||
LOG(LOG_LEVEL_ERROR,
|
||||
"xrdp_jpeg_compress: tjCompress error: %s",
|
||||
tjGetErrorStr());
|
||||
}
|
||||
@ -147,7 +147,7 @@ xrdp_codec_jpeg_compress(void *handle,
|
||||
|
||||
if (handle == 0)
|
||||
{
|
||||
g_writeln("xrdp_codec_jpeg_compress: handle is nil");
|
||||
LOG(LOG_LEVEL_WARNING, "xrdp_codec_jpeg_compress: handle is nil");
|
||||
return height;
|
||||
}
|
||||
|
||||
@ -188,7 +188,7 @@ xrdp_codec_jpeg_compress(void *handle,
|
||||
);
|
||||
if (error != 0)
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR,
|
||||
LOG(LOG_LEVEL_ERROR,
|
||||
"xrdp_codec_jpeg_compress: tjCompress error: %s",
|
||||
tjGetErrorStr());
|
||||
}
|
||||
@ -400,7 +400,7 @@ jpeg_compress(char *in_data, int width, int height,
|
||||
}
|
||||
else
|
||||
{
|
||||
g_writeln("bpp wrong %d", bpp);
|
||||
LOG(LOG_LEVEL_WARNING, "bpp wrong %d", bpp);
|
||||
}
|
||||
|
||||
cdata_bytes = byte_limit;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#endif
|
||||
|
||||
#include "libxrdp.h"
|
||||
#include "ms-rdpbcgr.h"
|
||||
#include "log.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -33,7 +34,7 @@ xrdp_mcs_create(struct xrdp_sec *owner, struct trans *trans,
|
||||
{
|
||||
struct xrdp_mcs *self;
|
||||
|
||||
DEBUG((" in xrdp_mcs_create"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_create");
|
||||
self = (struct xrdp_mcs *)g_malloc(sizeof(struct xrdp_mcs), 1);
|
||||
self->sec_layer = owner;
|
||||
self->userid = 1;
|
||||
@ -42,7 +43,7 @@ xrdp_mcs_create(struct xrdp_sec *owner, struct trans *trans,
|
||||
self->server_mcs_data = server_mcs_data;
|
||||
self->iso_layer = xrdp_iso_create(self, trans);
|
||||
self->channel_list = list_create();
|
||||
DEBUG((" out xrdp_mcs_create"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_create");
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -73,7 +74,7 @@ xrdp_mcs_delete(struct xrdp_mcs *self)
|
||||
|
||||
xrdp_iso_delete(self->iso_layer);
|
||||
/* make sure we get null pointer exception if struct is used again. */
|
||||
DEBUG(("xrdp_mcs_delete processed"))
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mcs_delete processed");
|
||||
g_memset(self, 0, sizeof(struct xrdp_mcs)) ;
|
||||
g_free(self);
|
||||
}
|
||||
@ -86,14 +87,14 @@ xrdp_mcs_send_cjcf(struct xrdp_mcs *self, int userid, int chanid)
|
||||
{
|
||||
struct stream *s;
|
||||
|
||||
DEBUG((" in xrdp_mcs_send_cjcf"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_send_cjcf");
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
|
||||
if (xrdp_iso_init(self->iso_layer, s) != 0)
|
||||
{
|
||||
free_stream(s);
|
||||
DEBUG((" out xrdp_mcs_send_cjcf error"));
|
||||
LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send_cjcf error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -107,12 +108,12 @@ xrdp_mcs_send_cjcf(struct xrdp_mcs *self, int userid, int chanid)
|
||||
if (xrdp_iso_send(self->iso_layer, s) != 0)
|
||||
{
|
||||
free_stream(s);
|
||||
DEBUG((" out xrdp_mcs_send_cjcf error"));
|
||||
LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send_cjcf error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
free_stream(s);
|
||||
DEBUG((" out xrdp_mcs_send_cjcf"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_send_cjcf");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -126,14 +127,14 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
|
||||
int len;
|
||||
int userid;
|
||||
int chanid;
|
||||
DEBUG((" in xrdp_mcs_recv"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_recv");
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (xrdp_iso_recv(self->iso_layer, s) != 0)
|
||||
{
|
||||
DEBUG((" out xrdp_mcs_recv, xrdp_iso_recv return non zero"));
|
||||
g_writeln("xrdp_mcs_recv: xrdp_iso_recv failed");
|
||||
LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_recv, xrdp_iso_recv return non zero");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_mcs_recv: xrdp_iso_recv failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -147,8 +148,8 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
|
||||
|
||||
if (appid == MCS_DPUM) /* Disconnect Provider Ultimatum */
|
||||
{
|
||||
g_writeln("received Disconnect Provider Ultimatum");
|
||||
DEBUG((" out xrdp_mcs_recv appid != MCS_DPUM"));
|
||||
LOG(LOG_LEVEL_ERROR, "received Disconnect Provider Ultimatum");
|
||||
LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_recv appid != MCS_DPUM");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -163,18 +164,18 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
|
||||
|
||||
in_uint16_be(s, userid);
|
||||
in_uint16_be(s, chanid);
|
||||
log_message(LOG_LEVEL_DEBUG,"MCS_CJRQ - channel join request received");
|
||||
DEBUG(("xrdp_mcs_recv adding channel %4.4x", chanid));
|
||||
LOG(LOG_LEVEL_DEBUG, "MCS_CJRQ - channel join request received");
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mcs_recv adding channel %4.4x", chanid);
|
||||
|
||||
if (xrdp_mcs_send_cjcf(self, userid, chanid) != 0)
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR,"Non handled error from xrdp_mcs_send_cjcf") ;
|
||||
LOG(LOG_LEVEL_ERROR, "Non handled error from xrdp_mcs_send_cjcf") ;
|
||||
}
|
||||
|
||||
s = libxrdp_force_read(self->iso_layer->trans);
|
||||
if (s == 0)
|
||||
{
|
||||
g_writeln("xrdp_mcs_recv: libxrdp_force_read failed");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_mcs_recv: libxrdp_force_read failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -187,7 +188,7 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
|
||||
}
|
||||
else
|
||||
{
|
||||
log_message(LOG_LEVEL_DEBUG,"Received an unhandled appid:%d",appid);
|
||||
LOG(LOG_LEVEL_DEBUG, "Received an unhandled appid:%d", appid);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -195,7 +196,7 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
|
||||
|
||||
if (appid != MCS_SDRQ)
|
||||
{
|
||||
DEBUG((" out xrdp_mcs_recv err got 0x%x need MCS_SDRQ", appid));
|
||||
LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_recv err got 0x%x need MCS_SDRQ", appid);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -218,7 +219,7 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan)
|
||||
in_uint8s(s, 1);
|
||||
}
|
||||
|
||||
DEBUG((" out xrdp_mcs_recv"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_recv");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -436,7 +437,7 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self)
|
||||
int opcode;
|
||||
struct stream *s;
|
||||
|
||||
DEBUG((" in xrdp_mcs_recv_edrq"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_recv_edrq");
|
||||
|
||||
s = libxrdp_force_read(self->iso_layer->trans);
|
||||
if (s == 0)
|
||||
@ -483,7 +484,7 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self)
|
||||
return 1;
|
||||
}
|
||||
|
||||
DEBUG((" out xrdp_mcs_recv_edrq"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_recv_edrq");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -495,7 +496,7 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self)
|
||||
int opcode;
|
||||
struct stream *s;
|
||||
|
||||
DEBUG((" in xrdp_mcs_recv_aurq"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_recv_aurq");
|
||||
|
||||
s = libxrdp_force_read(self->iso_layer->trans);
|
||||
if (s == 0)
|
||||
@ -534,7 +535,7 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self)
|
||||
return 1;
|
||||
}
|
||||
|
||||
DEBUG((" out xrdp_mcs_recv_aurq"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_recv_aurq");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -545,14 +546,14 @@ xrdp_mcs_send_aucf(struct xrdp_mcs *self)
|
||||
{
|
||||
struct stream *s;
|
||||
|
||||
DEBUG((" in xrdp_mcs_send_aucf"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_send_aucf");
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
|
||||
if (xrdp_iso_init(self->iso_layer, s) != 0)
|
||||
{
|
||||
free_stream(s);
|
||||
DEBUG((" out xrdp_mcs_send_aucf error"));
|
||||
LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send_aucf error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -564,12 +565,12 @@ xrdp_mcs_send_aucf(struct xrdp_mcs *self)
|
||||
if (xrdp_iso_send(self->iso_layer, s) != 0)
|
||||
{
|
||||
free_stream(s);
|
||||
DEBUG((" out xrdp_mcs_send_aucf error"));
|
||||
LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send_aucf error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
free_stream(s);
|
||||
DEBUG((" out xrdp_mcs_send_aucf"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_send_aucf");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -721,8 +722,8 @@ xrdp_mcs_out_gcc_data(struct xrdp_sec *self)
|
||||
int index;
|
||||
int channel;
|
||||
int gcc_size;
|
||||
char* gcc_size_ptr;
|
||||
char* ud_ptr;
|
||||
char *gcc_size_ptr;
|
||||
char *ud_ptr;
|
||||
|
||||
num_channels = self->mcs_layer->channel_list->count;
|
||||
num_channels_even = num_channels + (num_channels & 1);
|
||||
@ -788,7 +789,7 @@ xrdp_mcs_out_gcc_data(struct xrdp_sec *self)
|
||||
|
||||
if (self->rsa_key_bytes == 64)
|
||||
{
|
||||
g_writeln("xrdp_sec_out_mcs_data: using 512 bit RSA key");
|
||||
LOG(LOG_LEVEL_DEBUG, "xrdp_sec_out_mcs_data: using 512 bit RSA key");
|
||||
out_uint16_le(s, SEC_TAG_SRV_CRYPT);
|
||||
out_uint16_le(s, 0x00ec); /* len is 236 */
|
||||
out_uint32_le(s, self->crypt_method);
|
||||
@ -818,7 +819,7 @@ xrdp_mcs_out_gcc_data(struct xrdp_sec *self)
|
||||
}
|
||||
else if (self->rsa_key_bytes == 256)
|
||||
{
|
||||
g_writeln("xrdp_sec_out_mcs_data: using 2048 bit RSA key");
|
||||
LOG(LOG_LEVEL_DEBUG, "xrdp_sec_out_mcs_data: using 2048 bit RSA key");
|
||||
out_uint16_le(s, SEC_TAG_SRV_CRYPT);
|
||||
out_uint16_le(s, 0x01ac); /* len is 428 */
|
||||
out_uint32_le(s, self->crypt_method);
|
||||
@ -848,7 +849,7 @@ xrdp_mcs_out_gcc_data(struct xrdp_sec *self)
|
||||
}
|
||||
else if (self->rsa_key_bytes == 0) /* no security */
|
||||
{
|
||||
g_writeln("xrdp_sec_out_mcs_data: using no security");
|
||||
LOG(LOG_LEVEL_DEBUG, "xrdp_sec_out_mcs_data: using no security");
|
||||
out_uint16_le(s, SEC_TAG_SRV_CRYPT);
|
||||
out_uint16_le(s, 12); /* len is 12 */
|
||||
out_uint32_le(s, self->crypt_method);
|
||||
@ -856,7 +857,7 @@ xrdp_mcs_out_gcc_data(struct xrdp_sec *self)
|
||||
}
|
||||
else
|
||||
{
|
||||
g_writeln("xrdp_sec_out_mcs_data: error");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_sec_out_mcs_data: error");
|
||||
}
|
||||
/* end certificate */
|
||||
s_mark_end(s);
|
||||
@ -875,7 +876,7 @@ xrdp_mcs_send_connect_response(struct xrdp_mcs *self)
|
||||
int data_len;
|
||||
struct stream *s;
|
||||
|
||||
DEBUG((" in xrdp_mcs_send_connect_response"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_send_connect_response");
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
data_len = (int) (self->server_mcs_data->end - self->server_mcs_data->data);
|
||||
@ -896,12 +897,12 @@ xrdp_mcs_send_connect_response(struct xrdp_mcs *self)
|
||||
if (xrdp_iso_send(self->iso_layer, s) != 0)
|
||||
{
|
||||
free_stream(s);
|
||||
DEBUG((" out xrdp_mcs_send_connect_response error"));
|
||||
LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send_connect_response error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
free_stream(s);
|
||||
DEBUG((" out xrdp_mcs_send_connect_response"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_send_connect_response");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -912,7 +913,7 @@ xrdp_mcs_incoming(struct xrdp_mcs *self)
|
||||
{
|
||||
int index;
|
||||
|
||||
DEBUG((" in xrdp_mcs_incoming"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_incoming");
|
||||
|
||||
if (xrdp_mcs_recv_connect_initial(self) != 0)
|
||||
{
|
||||
@ -964,7 +965,7 @@ xrdp_mcs_incoming(struct xrdp_mcs *self)
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG((" out xrdp_mcs_incoming"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_incoming");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -995,18 +996,21 @@ xrdp_mcs_call_callback(struct xrdp_mcs *self)
|
||||
if (session != 0)
|
||||
{
|
||||
if (session->callback != 0)
|
||||
{
|
||||
if (session->check_for_app_input)
|
||||
{
|
||||
/* in xrdp_wm.c */
|
||||
rv = session->callback(session->id, 0x5556, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_writeln("in xrdp_mcs_send, session->callback is nil");
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_mcs_send, session->callback is nil");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_writeln("in xrdp_mcs_send, session is nil");
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_mcs_send, session is nil");
|
||||
}
|
||||
|
||||
return rv;
|
||||
@ -1021,13 +1025,13 @@ xrdp_mcs_send(struct xrdp_mcs *self, struct stream *s, int chan)
|
||||
char *lp;
|
||||
//static int max_len = 0;
|
||||
|
||||
DEBUG((" in xrdp_mcs_send"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_send");
|
||||
s_pop_layer(s, mcs_hdr);
|
||||
len = (s->end - s->p) - 8;
|
||||
|
||||
if (len > 8192 * 2)
|
||||
{
|
||||
g_writeln("error in xrdp_mcs_send, size too big: %d bytes", len);
|
||||
LOG(LOG_LEVEL_WARNING, "error in xrdp_mcs_send, size too big: %d bytes", len);
|
||||
}
|
||||
|
||||
//if (len > max_len)
|
||||
@ -1064,7 +1068,7 @@ xrdp_mcs_send(struct xrdp_mcs *self, struct stream *s, int chan)
|
||||
|
||||
if (xrdp_iso_send(self->iso_layer, s) != 0)
|
||||
{
|
||||
DEBUG((" out xrdp_mcs_send error"));
|
||||
LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1075,7 +1079,7 @@ xrdp_mcs_send(struct xrdp_mcs *self, struct stream *s, int chan)
|
||||
xrdp_mcs_call_callback(self);
|
||||
}
|
||||
|
||||
DEBUG((" out xrdp_mcs_send"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_send");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1093,11 +1097,11 @@ close_rdp_socket(struct xrdp_mcs *self)
|
||||
trans_shutdown_tls_mode(self->iso_layer->trans);
|
||||
g_tcp_close(self->iso_layer->trans->sck);
|
||||
self->iso_layer->trans->sck = 0 ;
|
||||
g_writeln("xrdp_mcs_disconnect - socket closed");
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mcs_disconnect - socket closed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
g_writeln("Failed to close socket");
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "Failed to close socket");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -1107,7 +1111,7 @@ xrdp_mcs_disconnect(struct xrdp_mcs *self)
|
||||
{
|
||||
struct stream *s;
|
||||
|
||||
DEBUG((" in xrdp_mcs_disconnect"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_disconnect");
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
|
||||
@ -1115,7 +1119,7 @@ xrdp_mcs_disconnect(struct xrdp_mcs *self)
|
||||
{
|
||||
free_stream(s);
|
||||
close_rdp_socket(self);
|
||||
DEBUG((" out xrdp_mcs_disconnect error - 1"));
|
||||
LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_disconnect error - 1");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1127,12 +1131,12 @@ xrdp_mcs_disconnect(struct xrdp_mcs *self)
|
||||
{
|
||||
free_stream(s);
|
||||
close_rdp_socket(self);
|
||||
DEBUG((" out xrdp_mcs_disconnect error - 2"));
|
||||
LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_disconnect error - 2");
|
||||
return 1;
|
||||
}
|
||||
|
||||
free_stream(s);
|
||||
close_rdp_socket(self);
|
||||
DEBUG(("xrdp_mcs_disconnect - close sent"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mcs_disconnect - close sent");
|
||||
return 0;
|
||||
}
|
||||
|
@ -24,14 +24,6 @@
|
||||
|
||||
#include "libxrdp.h"
|
||||
|
||||
#define MPPC_ENC_DEBUG 0
|
||||
|
||||
#if MPPC_ENC_DEBUG
|
||||
#define DLOG(_args) g_printf _args
|
||||
#else
|
||||
#define DLOG(_args) do { } while (0)
|
||||
#endif
|
||||
|
||||
/* local defines */
|
||||
|
||||
#define RDP_40_HIST_BUF_LEN (1024 * 8) /* RDP 4.0 uses 8K history buf */
|
||||
@ -92,8 +84,8 @@ static const tui16 g_crc_table[256] =
|
||||
insert 2 bits into outputBuffer
|
||||
******************************************************************************/
|
||||
#define insert_2_bits(_data) \
|
||||
do \
|
||||
{ \
|
||||
do \
|
||||
{ \
|
||||
if ((bits_left >= 3) && (bits_left <= 8)) \
|
||||
{ \
|
||||
i = bits_left - 2; \
|
||||
@ -108,14 +100,14 @@ do \
|
||||
outputBuffer[opb_index] |= _data << j; \
|
||||
bits_left = j; \
|
||||
} \
|
||||
} while (0)
|
||||
} while (0)
|
||||
|
||||
/*****************************************************************************
|
||||
insert 3 bits into outputBuffer
|
||||
******************************************************************************/
|
||||
#define insert_3_bits(_data) \
|
||||
do \
|
||||
{ \
|
||||
do \
|
||||
{ \
|
||||
if ((bits_left >= 4) && (bits_left <= 8)) \
|
||||
{ \
|
||||
i = bits_left - 3; \
|
||||
@ -130,14 +122,14 @@ do \
|
||||
outputBuffer[opb_index] |= _data << j; \
|
||||
bits_left = j; \
|
||||
} \
|
||||
} while (0)
|
||||
} while (0)
|
||||
|
||||
/*****************************************************************************
|
||||
insert 4 bits into outputBuffer
|
||||
******************************************************************************/
|
||||
#define insert_4_bits(_data) \
|
||||
do \
|
||||
{ \
|
||||
do \
|
||||
{ \
|
||||
if ((bits_left >= 5) && (bits_left <= 8)) \
|
||||
{ \
|
||||
i = bits_left - 4; \
|
||||
@ -152,14 +144,14 @@ do \
|
||||
outputBuffer[opb_index] |= _data << j; \
|
||||
bits_left = j; \
|
||||
} \
|
||||
} while (0)
|
||||
} while (0)
|
||||
|
||||
/*****************************************************************************
|
||||
insert 5 bits into outputBuffer
|
||||
******************************************************************************/
|
||||
#define insert_5_bits(_data) \
|
||||
do \
|
||||
{ \
|
||||
do \
|
||||
{ \
|
||||
if ((bits_left >= 6) && (bits_left <= 8)) \
|
||||
{ \
|
||||
i = bits_left - 5; \
|
||||
@ -174,14 +166,14 @@ do \
|
||||
outputBuffer[opb_index] |= _data << j; \
|
||||
bits_left = j; \
|
||||
} \
|
||||
} while (0)
|
||||
} while (0)
|
||||
|
||||
/*****************************************************************************
|
||||
insert 6 bits into outputBuffer
|
||||
******************************************************************************/
|
||||
#define insert_6_bits(_data) \
|
||||
do \
|
||||
{ \
|
||||
do \
|
||||
{ \
|
||||
if ((bits_left >= 7) && (bits_left <= 8)) \
|
||||
{ \
|
||||
i = bits_left - 6; \
|
||||
@ -196,14 +188,14 @@ do \
|
||||
outputBuffer[opb_index] |= (_data << j); \
|
||||
bits_left = j; \
|
||||
} \
|
||||
} while (0)
|
||||
} while (0)
|
||||
|
||||
/*****************************************************************************
|
||||
insert 7 bits into outputBuffer
|
||||
******************************************************************************/
|
||||
#define insert_7_bits(_data) \
|
||||
do \
|
||||
{ \
|
||||
do \
|
||||
{ \
|
||||
if (bits_left == 8) \
|
||||
{ \
|
||||
outputBuffer[opb_index] |= _data << 1; \
|
||||
@ -217,14 +209,14 @@ do \
|
||||
outputBuffer[opb_index] |= _data << j; \
|
||||
bits_left = j; \
|
||||
} \
|
||||
} while (0)
|
||||
} while (0)
|
||||
|
||||
/*****************************************************************************
|
||||
insert 8 bits into outputBuffer
|
||||
******************************************************************************/
|
||||
#define insert_8_bits(_data) \
|
||||
do \
|
||||
{ \
|
||||
do \
|
||||
{ \
|
||||
if (bits_left == 8) \
|
||||
{ \
|
||||
outputBuffer[opb_index++] |= _data; \
|
||||
@ -238,14 +230,14 @@ do \
|
||||
outputBuffer[opb_index] |= _data << j; \
|
||||
bits_left = j; \
|
||||
} \
|
||||
} while (0)
|
||||
} while (0)
|
||||
|
||||
/*****************************************************************************
|
||||
insert 9 bits into outputBuffer
|
||||
******************************************************************************/
|
||||
#define insert_9_bits(_data16) \
|
||||
do \
|
||||
{ \
|
||||
do \
|
||||
{ \
|
||||
i = 9 - bits_left; \
|
||||
j = 8 - i; \
|
||||
outputBuffer[opb_index++] |= (char) (_data16 >> i); \
|
||||
@ -256,14 +248,14 @@ do \
|
||||
opb_index++; \
|
||||
bits_left = 8; \
|
||||
} \
|
||||
} while (0)
|
||||
} while (0)
|
||||
|
||||
/*****************************************************************************
|
||||
insert 10 bits into outputBuffer
|
||||
******************************************************************************/
|
||||
#define insert_10_bits(_data16) \
|
||||
do \
|
||||
{ \
|
||||
do \
|
||||
{ \
|
||||
i = 10 - bits_left; \
|
||||
if ((bits_left >= 3) && (bits_left <= 8)) \
|
||||
{ \
|
||||
@ -281,14 +273,14 @@ do \
|
||||
outputBuffer[opb_index] |= (char) (_data16 << k); \
|
||||
bits_left = k; \
|
||||
} \
|
||||
} while (0)
|
||||
} while (0)
|
||||
|
||||
/*****************************************************************************
|
||||
insert 11 bits into outputBuffer
|
||||
******************************************************************************/
|
||||
#define insert_11_bits(_data16) \
|
||||
do \
|
||||
{ \
|
||||
do \
|
||||
{ \
|
||||
i = 11 - bits_left; \
|
||||
if ((bits_left >= 4) && (bits_left <= 8)) \
|
||||
{ \
|
||||
@ -306,14 +298,14 @@ do \
|
||||
outputBuffer[opb_index] |= (char) (_data16 << k); \
|
||||
bits_left = k; \
|
||||
} \
|
||||
} while (0)
|
||||
} while (0)
|
||||
|
||||
/*****************************************************************************
|
||||
insert 12 bits into outputBuffer
|
||||
******************************************************************************/
|
||||
#define insert_12_bits(_data16) \
|
||||
do \
|
||||
{ \
|
||||
do \
|
||||
{ \
|
||||
i = 12 - bits_left; \
|
||||
if ((bits_left >= 5) && (bits_left <= 8)) \
|
||||
{ \
|
||||
@ -331,14 +323,14 @@ do \
|
||||
outputBuffer[opb_index] |= (char) (_data16 << k); \
|
||||
bits_left = k; \
|
||||
} \
|
||||
} while (0)
|
||||
} while (0)
|
||||
|
||||
/*****************************************************************************
|
||||
insert 13 bits into outputBuffer
|
||||
******************************************************************************/
|
||||
#define insert_13_bits(_data16) \
|
||||
do \
|
||||
{ \
|
||||
do \
|
||||
{ \
|
||||
i = 13 - bits_left; \
|
||||
if ((bits_left >= 6) && (bits_left <= 8)) \
|
||||
{ \
|
||||
@ -356,14 +348,14 @@ do \
|
||||
outputBuffer[opb_index] |= (char) (_data16 << k); \
|
||||
bits_left = k; \
|
||||
} \
|
||||
} while (0)
|
||||
} while (0)
|
||||
|
||||
/*****************************************************************************
|
||||
insert 14 bits into outputBuffer
|
||||
******************************************************************************/
|
||||
#define insert_14_bits(_data16) \
|
||||
do \
|
||||
{ \
|
||||
do \
|
||||
{ \
|
||||
i = 14 - bits_left; \
|
||||
if ((bits_left >= 7) && (bits_left <= 8)) \
|
||||
{ \
|
||||
@ -381,14 +373,14 @@ do \
|
||||
outputBuffer[opb_index] |= (char) (_data16 << k); \
|
||||
bits_left = k; \
|
||||
} \
|
||||
} while (0)
|
||||
} while (0)
|
||||
|
||||
/*****************************************************************************
|
||||
insert 15 bits into outputBuffer
|
||||
******************************************************************************/
|
||||
#define insert_15_bits(_data16) \
|
||||
do \
|
||||
{ \
|
||||
do \
|
||||
{ \
|
||||
i = 15 - bits_left; \
|
||||
if (bits_left == 8) \
|
||||
{ \
|
||||
@ -406,14 +398,14 @@ do \
|
||||
outputBuffer[opb_index] |= (char) (_data16 << k); \
|
||||
bits_left = k; \
|
||||
} \
|
||||
} while (0)
|
||||
} while (0)
|
||||
|
||||
/*****************************************************************************
|
||||
insert 16 bits into outputBuffer
|
||||
******************************************************************************/
|
||||
#define insert_16_bits(_data16) \
|
||||
do \
|
||||
{ \
|
||||
do \
|
||||
{ \
|
||||
i = 16 - bits_left; \
|
||||
j = i - 8; \
|
||||
k = 8 - j; \
|
||||
@ -421,7 +413,7 @@ do \
|
||||
outputBuffer[opb_index++] |= (char) (_data16 >> j); \
|
||||
outputBuffer[opb_index] |= (char) (_data16 << k); \
|
||||
bits_left = k; \
|
||||
} while (0)
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Initialize mppc_enc structure
|
||||
@ -606,7 +598,7 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
|
||||
for (x = 0; x < 2; x++)
|
||||
{
|
||||
data = *(historyPointer + x);
|
||||
DLOG(("%.2x ", (tui8) data));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "%.2x ", (tui8) data);
|
||||
if (data & 0x80)
|
||||
{
|
||||
/* insert encoded literal */
|
||||
@ -684,7 +676,7 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
|
||||
/* no match found; encode literal byte */
|
||||
data = *cptr1;
|
||||
|
||||
DLOG(("%.2x ", data));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "%.2x ", data);
|
||||
if (data < 0x80)
|
||||
{
|
||||
/* literal byte < 0x80 */
|
||||
@ -710,8 +702,8 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
|
||||
lom++;
|
||||
}
|
||||
saved_ctr = ctr + lom;
|
||||
DLOG(("<%d: %ld,%d> ", (historyPointer + ctr) - hbuf_start,
|
||||
copy_offset, lom));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "<%ld: %u,%d> ", (historyPointer + ctr) - hbuf_start,
|
||||
copy_offset, lom);
|
||||
|
||||
/* compute CRC for matching segment and store in hash table */
|
||||
|
||||
@ -951,7 +943,7 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
|
||||
while (len - ctr > 0)
|
||||
{
|
||||
data = srcData[ctr];
|
||||
DLOG(("%.2x ", data));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "%.2x ", data);
|
||||
if (data < 0x80)
|
||||
{
|
||||
/* literal byte < 0x80 */
|
||||
@ -990,9 +982,9 @@ compress_rdp_5(struct xrdp_mppc_enc *enc, tui8 *srcData, int len)
|
||||
enc->flags |= enc->flagsHold;
|
||||
enc->flagsHold = 0;
|
||||
|
||||
DLOG(("\n"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "\n");
|
||||
|
||||
//g_writeln("compression ratio: %f", (float) len / (float) enc->bytes_in_opb);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "compression ratio: %f", (float) len / (float) enc->bytes_in_opb);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -23,20 +23,14 @@
|
||||
#endif
|
||||
|
||||
#include "libxrdp.h"
|
||||
#include "ms-rdpbcgr.h"
|
||||
#include "ms-rdpegdi.h"
|
||||
|
||||
#if defined(XRDP_NEUTRINORDP)
|
||||
#include <freerdp/codec/rfx.h>
|
||||
#endif
|
||||
|
||||
#define LLOG_LEVEL 2
|
||||
#define LLOGLN(_log_level, _params) \
|
||||
{ \
|
||||
if (_log_level < LLOG_LEVEL) \
|
||||
{ \
|
||||
g_write("xrdp_orders.c [%10.10u]: ", g_time3()); \
|
||||
g_writeln _params ; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define MAX_ORDERS_SIZE(_client_info) \
|
||||
(MAX((_client_info)->max_fastpath_frag_bytes, 16 * 1024) - 256);
|
||||
@ -112,7 +106,7 @@ xrdp_orders_init(struct xrdp_orders *self)
|
||||
self->order_count = 0;
|
||||
if (self->rdp_layer->client_info.use_fast_path & 1)
|
||||
{
|
||||
LLOGLN(10, ("xrdp_orders_init: fastpath"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_orders_init: fastpath");
|
||||
if (xrdp_rdp_init_fastpath(self->rdp_layer, self->out_s) != 0)
|
||||
{
|
||||
return 1;
|
||||
@ -122,7 +116,7 @@ xrdp_orders_init(struct xrdp_orders *self)
|
||||
}
|
||||
else
|
||||
{
|
||||
LLOGLN(10, ("xrdp_orders_init: slowpath"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_orders_init: slowpath");
|
||||
if (xrdp_rdp_init_data(self->rdp_layer, self->out_s) != 0)
|
||||
{
|
||||
return 1;
|
||||
@ -151,7 +145,7 @@ xrdp_orders_send(struct xrdp_orders *self)
|
||||
if ((self->order_level == 0) && (self->order_count > 0))
|
||||
{
|
||||
s_mark_end(self->out_s);
|
||||
DEBUG(("xrdp_orders_send sending %d orders", self->order_count));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_orders_send sending %d orders", self->order_count);
|
||||
self->order_count_ptr[0] = self->order_count;
|
||||
self->order_count_ptr[1] = self->order_count >> 8;
|
||||
self->order_count = 0;
|
||||
@ -188,7 +182,7 @@ xrdp_orders_force_send(struct xrdp_orders *self)
|
||||
if ((self->order_level > 0) && (self->order_count > 0))
|
||||
{
|
||||
s_mark_end(self->out_s);
|
||||
DEBUG(("xrdp_orders_force_send sending %d orders", self->order_count));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_orders_force_send sending %d orders", self->order_count);
|
||||
self->order_count_ptr[0] = self->order_count;
|
||||
self->order_count_ptr[1] = self->order_count >> 8;
|
||||
if (self->rdp_layer->client_info.use_fast_path & 1)
|
||||
@ -243,7 +237,7 @@ xrdp_orders_check(struct xrdp_orders *self, int max_size)
|
||||
size = (int)(self->out_s->p - self->order_count_ptr);
|
||||
if (size < 0)
|
||||
{
|
||||
g_writeln("error in xrdp_orders_check, size too small: %d bytes", size);
|
||||
LOG(LOG_LEVEL_ERROR, "error in xrdp_orders_check, size too small: %d bytes", size);
|
||||
return 1;
|
||||
}
|
||||
if (size > max_order_size)
|
||||
@ -251,7 +245,7 @@ xrdp_orders_check(struct xrdp_orders *self, int max_size)
|
||||
/* this suggests someone calls this function without passing the
|
||||
correct max_size so we end up putting more into the buffer
|
||||
than we indicate we can */
|
||||
g_writeln("error in xrdp_orders_check, size too big: %d bytes", size);
|
||||
LOG(LOG_LEVEL_WARNING, "error in xrdp_orders_check, size too big: %d bytes", size);
|
||||
/* We where getting called with size already greater than
|
||||
max_order_size
|
||||
Which I suspect was because the sending of text did not include
|
||||
@ -1646,20 +1640,20 @@ xrdp_orders_mem_blt(struct xrdp_orders *self, int cache_id,
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
int
|
||||
xrdp_orders_composite_blt(struct xrdp_orders* self, int srcidx, int srcformat,
|
||||
int srcwidth, int srcrepeat, int* srctransform,
|
||||
xrdp_orders_composite_blt(struct xrdp_orders *self, int srcidx, int srcformat,
|
||||
int srcwidth, int srcrepeat, int *srctransform,
|
||||
int mskflags, int mskidx, int mskformat,
|
||||
int mskwidth, int mskrepeat, int op,
|
||||
int srcx, int srcy, int mskx, int msky,
|
||||
int dstx, int dsty, int width, int height,
|
||||
int dstformat,
|
||||
struct xrdp_rect* rect)
|
||||
struct xrdp_rect *rect)
|
||||
{
|
||||
int order_flags;
|
||||
int vals[20];
|
||||
int present;
|
||||
char* present_ptr;
|
||||
char* order_flags_ptr;
|
||||
char *present_ptr;
|
||||
char *order_flags_ptr;
|
||||
|
||||
if (xrdp_orders_check(self, 80) != 0)
|
||||
{
|
||||
@ -2225,13 +2219,13 @@ xrdp_orders_send_raw_bitmap(struct xrdp_orders *self,
|
||||
|
||||
if (width > 64)
|
||||
{
|
||||
g_writeln("error, width > 64");
|
||||
LOG(LOG_LEVEL_ERROR, "error, width > 64");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (height > 64)
|
||||
{
|
||||
g_writeln("error, height > 64");
|
||||
LOG(LOG_LEVEL_ERROR, "error, height > 64");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2351,13 +2345,13 @@ xrdp_orders_send_bitmap(struct xrdp_orders *self,
|
||||
|
||||
if (width > 64)
|
||||
{
|
||||
g_writeln("error, width > 64");
|
||||
LOG(LOG_LEVEL_ERROR, "error, width > 64");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (height > 64)
|
||||
{
|
||||
g_writeln("error, height > 64");
|
||||
LOG(LOG_LEVEL_ERROR, "error, height > 64");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2488,7 +2482,7 @@ xrdp_orders_cache_glyph(struct xrdp_orders *self,
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
static int write_2byte_signed(struct stream * s, int value)
|
||||
static int write_2byte_signed(struct stream *s, int value)
|
||||
{
|
||||
unsigned char byte;
|
||||
int negative = 0;
|
||||
@ -2534,7 +2528,7 @@ static int write_2byte_signed(struct stream * s, int value)
|
||||
|
||||
/*****************************************************************************/
|
||||
/* returns error */
|
||||
static int write_2byte_unsigned(struct stream * s, unsigned int value)
|
||||
static int write_2byte_unsigned(struct stream *s, unsigned int value)
|
||||
{
|
||||
unsigned char byte;
|
||||
|
||||
@ -2651,13 +2645,13 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders *self,
|
||||
|
||||
if (width > 64)
|
||||
{
|
||||
g_writeln("error, width > 64");
|
||||
LOG(LOG_LEVEL_ERROR, "error, width > 64");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (height > 64)
|
||||
{
|
||||
g_writeln("error, height > 64");
|
||||
LOG(LOG_LEVEL_ERROR, "error, height > 64");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2779,13 +2773,13 @@ xrdp_orders_send_bitmap2(struct xrdp_orders *self,
|
||||
|
||||
if (width > 64)
|
||||
{
|
||||
g_writeln("error, width > 64");
|
||||
LOG(LOG_LEVEL_ERROR, "error, width > 64");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (height > 64)
|
||||
{
|
||||
g_writeln("error, height > 64");
|
||||
LOG(LOG_LEVEL_ERROR, "error, height > 64");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2892,8 +2886,8 @@ xrdp_orders_send_as_rfx(struct xrdp_orders *self,
|
||||
return 0;
|
||||
}
|
||||
|
||||
LLOGLN(10, ("width %d height %d rfx_min_pixel %d", width, height,
|
||||
self->rfx_min_pixel));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "width %d height %d rfx_min_pixel %d", width, height,
|
||||
self->rfx_min_pixel);
|
||||
if (width * height < self->rfx_min_pixel)
|
||||
{
|
||||
return 0;
|
||||
@ -2985,7 +2979,7 @@ xrdp_orders_send_bitmap3(struct xrdp_orders *self,
|
||||
return 2;
|
||||
}
|
||||
|
||||
LLOGLN(10, ("xrdp_orders_send_bitmap3: rfx"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_orders_send_bitmap3: rfx");
|
||||
context = (RFX_CONTEXT *)(self->rdp_layer->rfx_enc);
|
||||
make_stream(xr_s);
|
||||
init_stream(xr_s, 16384);
|
||||
@ -3014,11 +3008,11 @@ xrdp_orders_send_bitmap3(struct xrdp_orders *self,
|
||||
|
||||
if (!xrdp_orders_send_as_jpeg(self, width, height, bpp, hints))
|
||||
{
|
||||
LLOGLN(10, ("xrdp_orders_send_bitmap3: jpeg skipped"));
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_orders_send_bitmap3: jpeg skipped");
|
||||
return 2;
|
||||
}
|
||||
|
||||
LLOGLN(10, ("xrdp_orders_send_bitmap3: jpeg"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_orders_send_bitmap3: jpeg");
|
||||
e = width % 4;
|
||||
|
||||
if (e != 0)
|
||||
@ -3046,7 +3040,7 @@ xrdp_orders_send_bitmap3(struct xrdp_orders *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
g_writeln("xrdp_orders_send_bitmap3: todo unknown codec");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_orders_send_bitmap3: todo unknown codec");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -3117,7 +3111,7 @@ xrdp_orders_send_create_os_surface(struct xrdp_orders *self, int id,
|
||||
order_flags |= 1 << 2; /* type RDP_ORDER_ALTSEC_CREATE_OFFSCR_BITMAP */
|
||||
out_uint8(self->out_s, order_flags);
|
||||
cache_id = id & 0x7fff;
|
||||
LLOGLN(10, ("xrdp_orders_send_create_os_surface: cache_id %d", cache_id));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_orders_send_create_os_surface: cache_id %d", cache_id);
|
||||
flags = cache_id;
|
||||
|
||||
if (num_del_list > 0)
|
||||
|
@ -21,7 +21,9 @@
|
||||
#endif
|
||||
|
||||
#include "libxrdp.h"
|
||||
#include "ms-rdpegdi.h"
|
||||
#include "xrdp_rail.h"
|
||||
#include "string_calls.h"
|
||||
|
||||
/* [MS-RDPERP]: Remote Desktop Protocol:
|
||||
Remote Programs Virtual Channel Extension
|
||||
|
@ -23,52 +23,46 @@
|
||||
#endif
|
||||
|
||||
#include "libxrdp.h"
|
||||
#include "ms-rdpbcgr.h"
|
||||
#include "log.h"
|
||||
#include "ssl_calls.h"
|
||||
#include "string_calls.h"
|
||||
|
||||
#if defined(XRDP_NEUTRINORDP)
|
||||
#include <freerdp/codec/rfx.h>
|
||||
#include <freerdp/constants.h>
|
||||
#endif
|
||||
|
||||
#define LOG_LEVEL 1
|
||||
#define LLOG(_level, _args) \
|
||||
do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
|
||||
#define LLOGLN(_level, _args) \
|
||||
do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
|
||||
|
||||
|
||||
#define FASTPATH_FRAG_SIZE (16 * 1024 - 128)
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
xrdp_rdp_read_config(struct xrdp_client_info *client_info)
|
||||
xrdp_rdp_read_config(const char *xrdp_ini, struct xrdp_client_info *client_info)
|
||||
{
|
||||
int index = 0;
|
||||
struct list *items = (struct list *)NULL;
|
||||
struct list *values = (struct list *)NULL;
|
||||
char *item = NULL;
|
||||
char *value = NULL;
|
||||
char cfg_file[256];
|
||||
int pos;
|
||||
char *tmp = NULL;
|
||||
int tmp_length = 0;
|
||||
|
||||
/* initialize (zero out) local variables: */
|
||||
g_memset(cfg_file, 0, sizeof(char) * 256);
|
||||
|
||||
items = list_create();
|
||||
items->auto_free = 1;
|
||||
values = list_create();
|
||||
values->auto_free = 1;
|
||||
g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
|
||||
DEBUG(("cfg_file %s", cfg_file));
|
||||
file_by_name_read_section(cfg_file, "globals", items, values);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "cfg_file %s", xrdp_ini);
|
||||
file_by_name_read_section(xrdp_ini, "globals", items, values);
|
||||
|
||||
for (index = 0; index < items->count; index++)
|
||||
{
|
||||
item = (char *)list_get_item(items, index);
|
||||
value = (char *)list_get_item(values, index);
|
||||
DEBUG(("item %s value %s", item, value));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "item %s value %s", item, value);
|
||||
|
||||
if (g_strcasecmp(item, "bitmap_cache") == 0)
|
||||
{
|
||||
@ -106,7 +100,7 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
|
||||
}
|
||||
else
|
||||
{
|
||||
log_message(LOG_LEVEL_ALWAYS,"Warning: Your configured crypt level is "
|
||||
LOG(LOG_LEVEL_ALWAYS, "Warning: Your configured crypt level is "
|
||||
"undefined, 'high' will be used");
|
||||
client_info->crypt_level = 3;
|
||||
}
|
||||
@ -116,7 +110,7 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
|
||||
client_info->channels_allowed = g_text2bool(value);
|
||||
if (client_info->channels_allowed == 0)
|
||||
{
|
||||
log_message(LOG_LEVEL_DEBUG,"Info - All channels are disabled");
|
||||
LOG(LOG_LEVEL_DEBUG, "Info - All channels are disabled");
|
||||
}
|
||||
}
|
||||
else if (g_strcasecmp(item, "allow_multimon") == 0)
|
||||
@ -124,7 +118,7 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
|
||||
client_info->multimon = g_text2bool(value);
|
||||
if (client_info->multimon == 0)
|
||||
{
|
||||
log_message(LOG_LEVEL_DEBUG,"Info - Multi monitor server support disabled");
|
||||
LOG(LOG_LEVEL_DEBUG, "Info - Multi monitor server support disabled");
|
||||
}
|
||||
}
|
||||
else if (g_strcasecmp(item, "max_bpp") == 0)
|
||||
@ -143,6 +137,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)
|
||||
@ -163,7 +161,7 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
|
||||
}
|
||||
else
|
||||
{
|
||||
log_message(LOG_LEVEL_ALWAYS,"Warning: Your configured fastpath level is "
|
||||
LOG(LOG_LEVEL_ALWAYS, "Warning: Your configured fastpath level is "
|
||||
"undefined, fastpath will not be used");
|
||||
client_info->use_fast_path = 0;
|
||||
}
|
||||
@ -207,7 +205,7 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
|
||||
}
|
||||
else
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR, "security_layer=%s is not "
|
||||
LOG(LOG_LEVEL_ERROR, "security_layer=%s is not "
|
||||
"recognized, will use security_layer=negotiate",
|
||||
value);
|
||||
client_info->security_layer = PROTOCOL_SSL | PROTOCOL_HYBRID | PROTOCOL_HYBRID_EX;
|
||||
@ -220,7 +218,7 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
|
||||
{
|
||||
/* default certificate path */
|
||||
g_snprintf(client_info->certificate, 1023, "%s/cert.pem", XRDP_CFG_PATH);
|
||||
log_message(LOG_LEVEL_INFO,
|
||||
LOG(LOG_LEVEL_INFO,
|
||||
"Using default X.509 certificate: %s",
|
||||
client_info->certificate);
|
||||
|
||||
@ -229,7 +227,7 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
|
||||
{
|
||||
/* default certificate path */
|
||||
g_snprintf(client_info->certificate, 1023, "%s/cert.pem", XRDP_CFG_PATH);
|
||||
log_message(LOG_LEVEL_WARNING,
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"X.509 certificate should use absolute path, using "
|
||||
"default instead: %s", client_info->certificate);
|
||||
}
|
||||
@ -241,7 +239,7 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
|
||||
|
||||
if (!g_file_readable(client_info->certificate))
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR, "Cannot read certificate file %s: %s",
|
||||
LOG(LOG_LEVEL_ERROR, "Cannot read certificate file %s: %s",
|
||||
client_info->certificate, g_get_strerror());
|
||||
}
|
||||
}
|
||||
@ -252,14 +250,14 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
|
||||
{
|
||||
/* default key_file path */
|
||||
g_snprintf(client_info->key_file, 1023, "%s/key.pem", XRDP_CFG_PATH);
|
||||
log_message(LOG_LEVEL_INFO, "Using default X.509 key file: %s",
|
||||
LOG(LOG_LEVEL_INFO, "Using default X.509 key file: %s",
|
||||
client_info->key_file);
|
||||
}
|
||||
else if (value[0] != '/')
|
||||
{
|
||||
/* default key_file path */
|
||||
g_snprintf(client_info->key_file, 1023, "%s/key.pem", XRDP_CFG_PATH);
|
||||
log_message(LOG_LEVEL_WARNING,
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"X.509 key file should use absolute path, using "
|
||||
"default instead: %s", client_info->key_file);
|
||||
}
|
||||
@ -271,11 +269,15 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info)
|
||||
|
||||
if (!g_file_readable(client_info->key_file))
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR, "Cannot read private key file %s: %s",
|
||||
LOG(LOG_LEVEL_ERROR, "Cannot read private key file %s: %s",
|
||||
client_info->key_file, g_get_strerror());
|
||||
}
|
||||
}
|
||||
|
||||
else if (g_strcasecmp(item, "domain_user_separator") == 0
|
||||
&& g_strlen(value) > 0)
|
||||
{
|
||||
g_strncpy(client_info->domain_user_separator, value, sizeof(client_info->domain_user_separator) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
list_delete(items);
|
||||
@ -329,7 +331,7 @@ xrdp_rdp_detect_cpu(void)
|
||||
|
||||
if (edx & (1 << 26))
|
||||
{
|
||||
DEBUG(("SSE2 detected"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "SSE2 detected");
|
||||
cpu_opt |= CPU_SSE2;
|
||||
}
|
||||
|
||||
@ -344,12 +346,12 @@ xrdp_rdp_create(struct xrdp_session *session, struct trans *trans)
|
||||
struct xrdp_rdp *self = (struct xrdp_rdp *)NULL;
|
||||
int bytes;
|
||||
|
||||
DEBUG(("in xrdp_rdp_create"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_create");
|
||||
self = (struct xrdp_rdp *)g_malloc(sizeof(struct xrdp_rdp), 1);
|
||||
self->session = session;
|
||||
self->share_id = 66538;
|
||||
/* read ini settings */
|
||||
xrdp_rdp_read_config(&self->client_info);
|
||||
xrdp_rdp_read_config(session->xrdp_ini, &self->client_info);
|
||||
/* create sec layer */
|
||||
self->sec_layer = xrdp_sec_create(self, trans);
|
||||
/* default 8 bit v1 color bitmap cache entries and size */
|
||||
@ -368,7 +370,7 @@ xrdp_rdp_create(struct xrdp_session *session, struct trans *trans)
|
||||
rfx_context_set_cpu_opt(self->rfx_enc, xrdp_rdp_detect_cpu());
|
||||
#endif
|
||||
self->client_info.size = sizeof(self->client_info);
|
||||
DEBUG(("out xrdp_rdp_create"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_create");
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -427,7 +429,7 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code)
|
||||
int chan = 0;
|
||||
const tui8 *header;
|
||||
|
||||
DEBUG(("in xrdp_rdp_recv"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_recv");
|
||||
if (s->next_packet == 0 || s->next_packet >= s->end)
|
||||
{
|
||||
/* check for fastpath first */
|
||||
@ -440,7 +442,7 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code)
|
||||
}
|
||||
/* next_packet gets set in xrdp_sec_recv_fastpath */
|
||||
*code = 2; // special code for fastpath input
|
||||
DEBUG(("out (fastpath) xrdp_rdp_recv"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "out (fastpath) xrdp_rdp_recv");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -452,14 +454,13 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code)
|
||||
{
|
||||
s->next_packet = 0;
|
||||
*code = -1;
|
||||
DEBUG(("out (1) xrdp_rdp_recv"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "out (1) xrdp_rdp_recv");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (error != 0)
|
||||
{
|
||||
DEBUG(("out xrdp_rdp_recv error"));
|
||||
g_writeln("xrdp_rdp_recv: xrdp_sec_recv failed");
|
||||
LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_recv error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -469,20 +470,20 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code)
|
||||
{
|
||||
if (xrdp_channel_process(self->sec_layer->chan_layer, s, chan) != 0)
|
||||
{
|
||||
g_writeln("xrdp_channel_process returned unhandled error") ;
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_channel_process returned unhandled error") ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (chan != 1)
|
||||
{
|
||||
g_writeln("Wrong channel Id to be handled by xrdp_channel_process %d", chan);
|
||||
LOG(LOG_LEVEL_ERROR, "Wrong channel Id to be handled by xrdp_channel_process %d", chan);
|
||||
}
|
||||
}
|
||||
|
||||
s->next_packet = 0;
|
||||
*code = 0;
|
||||
DEBUG(("out (2) xrdp_rdp_recv"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "out (2) xrdp_rdp_recv");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -490,7 +491,7 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code)
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG(("xrdp_rdp_recv stream not touched"))
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_recv stream not touched");
|
||||
s->p = s->next_packet;
|
||||
}
|
||||
|
||||
@ -498,20 +499,19 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code)
|
||||
{
|
||||
s->next_packet = 0;
|
||||
*code = 0;
|
||||
DEBUG(("out (3) xrdp_rdp_recv"));
|
||||
len = (int)(s->end - s->p);
|
||||
g_writeln("xrdp_rdp_recv: bad RDP packet, length [%d]", len);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "out (3) xrdp_rdp_recv: bad RDP packet, length [%d]", len);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
in_uint16_le(s, len);
|
||||
/*g_writeln("New len received : %d next packet: %d s_end: %d",len,s->next_packet,s->end); */
|
||||
/*LOG_DEVEL(LOG_LEVEL_TRACE, "New len received : %d next packet: %d s_end: %d",len,s->next_packet,s->end); */
|
||||
in_uint16_le(s, pdu_code);
|
||||
*code = pdu_code & 0xf;
|
||||
in_uint8s(s, 2); /* mcs user id */
|
||||
s->next_packet += len;
|
||||
DEBUG(("out (4) xrdp_rdp_recv"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "out (4) xrdp_rdp_recv");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -522,7 +522,7 @@ xrdp_rdp_send(struct xrdp_rdp *self, struct stream *s, int pdu_type)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
DEBUG(("in xrdp_rdp_send"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_send");
|
||||
s_pop_layer(s, rdp_hdr);
|
||||
len = s->end - s->p;
|
||||
out_uint16_le(s, len);
|
||||
@ -531,11 +531,11 @@ xrdp_rdp_send(struct xrdp_rdp *self, struct stream *s, int pdu_type)
|
||||
|
||||
if (xrdp_sec_send(self->sec_layer, s, MCS_GLOBAL_CHANNEL) != 0)
|
||||
{
|
||||
DEBUG(("out xrdp_rdp_send error"));
|
||||
LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
DEBUG(("out xrdp_rdp_send"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_send");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -558,7 +558,7 @@ xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
|
||||
struct stream ls;
|
||||
struct xrdp_mppc_enc *mppc_enc;
|
||||
|
||||
DEBUG(("in xrdp_rdp_send_data"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_send_data");
|
||||
s_pop_layer(s, rdp_hdr);
|
||||
len = (int)(s->end - s->p);
|
||||
pdutype = 0x10 | PDUTYPE_DATAPDU;
|
||||
@ -573,9 +573,9 @@ xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
|
||||
mppc_enc = self->mppc_enc;
|
||||
if (compress_rdp(mppc_enc, (tui8 *)(s->p + 18), tocomplen))
|
||||
{
|
||||
DEBUG(("mppc_encode ok flags 0x%x bytes_in_opb %d historyOffset %d "
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "mppc_encode ok flags 0x%x bytes_in_opb %d historyOffset %d "
|
||||
"tocomplen %d", mppc_enc->flags, mppc_enc->bytes_in_opb,
|
||||
mppc_enc->historyOffset, tocomplen));
|
||||
mppc_enc->historyOffset, tocomplen);
|
||||
|
||||
clen = mppc_enc->bytes_in_opb + 18;
|
||||
pdulen = clen;
|
||||
@ -600,9 +600,9 @@ xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
|
||||
}
|
||||
else
|
||||
{
|
||||
LLOGLN(10, ("xrdp_rdp_send_data: mppc_encode not ok "
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_data: mppc_encode not ok "
|
||||
"type %d flags %d", mppc_enc->protocol_type,
|
||||
mppc_enc->flags));
|
||||
mppc_enc->flags);
|
||||
}
|
||||
}
|
||||
|
||||
@ -619,11 +619,11 @@ xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
|
||||
|
||||
if (xrdp_sec_send(self->sec_layer, s, MCS_GLOBAL_CHANNEL) != 0)
|
||||
{
|
||||
DEBUG(("out xrdp_rdp_send_data error"));
|
||||
LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send_data error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
DEBUG(("out xrdp_rdp_send_data"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_send_data");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -685,7 +685,7 @@ xrdp_rdp_send_fastpath(struct xrdp_rdp *self, struct stream *s,
|
||||
struct stream send_s;
|
||||
struct xrdp_mppc_enc *mppc_enc;
|
||||
|
||||
LLOGLN(10, ("xrdp_rdp_send_fastpath:"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_fastpath:");
|
||||
s_pop_layer(s, rdp_hdr);
|
||||
updateCode = data_pdu_type;
|
||||
if (self->client_info.rdp_compression)
|
||||
@ -729,8 +729,8 @@ xrdp_rdp_send_fastpath(struct xrdp_rdp *self, struct stream *s,
|
||||
}
|
||||
}
|
||||
send_len = no_comp_len;
|
||||
LLOGLN(10, ("xrdp_rdp_send_fastpath: no_comp_len %d fragmentation %d",
|
||||
no_comp_len, fragmentation));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_fastpath: no_comp_len %d fragmentation %d",
|
||||
no_comp_len, fragmentation);
|
||||
if ((compression != 0) && (no_comp_len > header_bytes + 16))
|
||||
{
|
||||
to_comp_len = no_comp_len - header_bytes;
|
||||
@ -739,8 +739,8 @@ xrdp_rdp_send_fastpath(struct xrdp_rdp *self, struct stream *s,
|
||||
to_comp_len))
|
||||
{
|
||||
comp_len = mppc_enc->bytes_in_opb + header_bytes;
|
||||
LLOGLN(10, ("xrdp_rdp_send_fastpath: no_comp_len %d "
|
||||
"comp_len %d", no_comp_len, comp_len));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_fastpath: no_comp_len %d "
|
||||
"comp_len %d", no_comp_len, comp_len);
|
||||
send_len = comp_len;
|
||||
comp_type = mppc_enc->flags;
|
||||
/* outputBuffer has 64 bytes preceding it */
|
||||
@ -756,9 +756,9 @@ xrdp_rdp_send_fastpath(struct xrdp_rdp *self, struct stream *s,
|
||||
}
|
||||
else
|
||||
{
|
||||
LLOGLN(10, ("xrdp_rdp_send_fastpath: mppc_encode not ok "
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_fastpath: mppc_encode not ok "
|
||||
"type %d flags %d", mppc_enc->protocol_type,
|
||||
mppc_enc->flags));
|
||||
mppc_enc->flags);
|
||||
}
|
||||
}
|
||||
updateHeader = (updateCode & 15) |
|
||||
@ -774,7 +774,7 @@ xrdp_rdp_send_fastpath(struct xrdp_rdp *self, struct stream *s,
|
||||
send_s.end = send_s.p + send_len;
|
||||
if (xrdp_sec_send_fastpath(self->sec_layer, &send_s) != 0)
|
||||
{
|
||||
LLOGLN(0, ("xrdp_rdp_send_fastpath: xrdp_fastpath_send failed"));
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_rdp_send_fastpath: xrdp_fastpath_send failed");
|
||||
return 1;
|
||||
}
|
||||
frag_s.p += no_comp_len;
|
||||
@ -794,11 +794,11 @@ xrdp_rdp_send_data_update_sync(struct xrdp_rdp *self)
|
||||
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
DEBUG(("in xrdp_rdp_send_data_update_sync"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_send_data_update_sync");
|
||||
|
||||
if (self->client_info.use_fast_path & 1) /* fastpath output supported */
|
||||
{
|
||||
LLOGLN(10, ("xrdp_rdp_send_data_update_sync: fastpath"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_data_update_sync: fastpath");
|
||||
if (xrdp_rdp_init_fastpath(self, s) != 0)
|
||||
{
|
||||
free_stream(s);
|
||||
@ -809,7 +809,7 @@ xrdp_rdp_send_data_update_sync(struct xrdp_rdp *self)
|
||||
{
|
||||
if (xrdp_rdp_init_data(self, s) != 0)
|
||||
{
|
||||
DEBUG(("out xrdp_rdp_send_data_update_sync error"));
|
||||
LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send_data_update_sync error");
|
||||
free_stream(s);
|
||||
return 1;
|
||||
}
|
||||
@ -832,14 +832,14 @@ xrdp_rdp_send_data_update_sync(struct xrdp_rdp *self)
|
||||
{
|
||||
if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_UPDATE) != 0)
|
||||
{
|
||||
DEBUG(("out xrdp_rdp_send_data_update_sync error"));
|
||||
LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send_data_update_sync error");
|
||||
free_stream(s);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DEBUG(("out xrdp_rdp_send_data_update_sync"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_send_data_update_sync");
|
||||
free_stream(s);
|
||||
return 0;
|
||||
}
|
||||
@ -851,7 +851,7 @@ xrdp_rdp_incoming(struct xrdp_rdp *self)
|
||||
struct xrdp_iso *iso;
|
||||
iso = self->sec_layer->mcs_layer->iso_layer;
|
||||
|
||||
DEBUG(("in xrdp_rdp_incoming"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_incoming");
|
||||
|
||||
if (xrdp_sec_incoming(self->sec_layer) != 0)
|
||||
{
|
||||
@ -859,7 +859,7 @@ xrdp_rdp_incoming(struct xrdp_rdp *self)
|
||||
}
|
||||
self->mcs_channel = self->sec_layer->mcs_layer->userid +
|
||||
MCS_USERCHANNEL_BASE;
|
||||
DEBUG(("out xrdp_rdp_incoming mcs channel %d", self->mcs_channel));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_incoming mcs channel %d", self->mcs_channel);
|
||||
g_strncpy(self->client_info.client_addr, iso->trans->addr,
|
||||
sizeof(self->client_info.client_addr) - 1);
|
||||
g_strncpy(self->client_info.client_port, iso->trans->port,
|
||||
@ -868,7 +868,7 @@ xrdp_rdp_incoming(struct xrdp_rdp *self)
|
||||
/* log TLS version and cipher of TLS connections */
|
||||
if (iso->selectedProtocol > PROTOCOL_RDP)
|
||||
{
|
||||
log_message(LOG_LEVEL_INFO,
|
||||
LOG(LOG_LEVEL_INFO,
|
||||
"TLS connection established from %s port %s: %s with cipher %s",
|
||||
self->client_info.client_addr,
|
||||
self->client_info.client_port,
|
||||
@ -878,7 +878,7 @@ xrdp_rdp_incoming(struct xrdp_rdp *self)
|
||||
/* log non-TLS connections */
|
||||
else
|
||||
{
|
||||
log_message(LOG_LEVEL_INFO,
|
||||
LOG(LOG_LEVEL_INFO,
|
||||
"Non-TLS connection established from %s port %s: "
|
||||
"encrypted with standard RDP security",
|
||||
self->client_info.client_addr,
|
||||
@ -914,7 +914,7 @@ xrdp_rdp_process_data_input(struct xrdp_rdp *self, struct stream *s)
|
||||
}
|
||||
in_uint16_le(s, num_events);
|
||||
in_uint8s(s, 2); /* pad */
|
||||
DEBUG(("in xrdp_rdp_process_data_input %d events", num_events));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_process_data_input %d events", num_events);
|
||||
|
||||
for (index = 0; index < num_events; index++)
|
||||
{
|
||||
@ -927,8 +927,8 @@ xrdp_rdp_process_data_input(struct xrdp_rdp *self, struct stream *s)
|
||||
in_uint16_le(s, device_flags);
|
||||
in_sint16_le(s, param1);
|
||||
in_sint16_le(s, param2);
|
||||
DEBUG(("xrdp_rdp_process_data_input event %4.4x flags %4.4x param1 %d "
|
||||
"param2 %d time %d", msg_type, device_flags, param1, param2, time));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_input event %4.4x flags %4.4x param1 %d "
|
||||
"param2 %d time %d", msg_type, device_flags, param1, param2, time);
|
||||
|
||||
if (self->session->callback != 0)
|
||||
{
|
||||
@ -943,7 +943,7 @@ xrdp_rdp_process_data_input(struct xrdp_rdp *self, struct stream *s)
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(("out xrdp_rdp_process_data_input"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_process_data_input");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1012,24 +1012,24 @@ xrdp_rdp_process_data_control(struct xrdp_rdp *self, struct stream *s)
|
||||
{
|
||||
int action;
|
||||
|
||||
DEBUG(("xrdp_rdp_process_data_control"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control");
|
||||
in_uint16_le(s, action);
|
||||
in_uint8s(s, 2); /* user id */
|
||||
in_uint8s(s, 4); /* control id */
|
||||
|
||||
if (action == RDP_CTL_REQUEST_CONTROL)
|
||||
{
|
||||
DEBUG(("xrdp_rdp_process_data_control got RDP_CTL_REQUEST_CONTROL"));
|
||||
DEBUG(("xrdp_rdp_process_data_control calling xrdp_rdp_send_synchronise"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control got RDP_CTL_REQUEST_CONTROL");
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control calling xrdp_rdp_send_synchronise");
|
||||
xrdp_rdp_send_synchronise(self);
|
||||
DEBUG(("xrdp_rdp_process_data_control sending RDP_CTL_COOPERATE"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control sending RDP_CTL_COOPERATE");
|
||||
xrdp_rdp_send_control(self, RDP_CTL_COOPERATE);
|
||||
DEBUG(("xrdp_rdp_process_data_control sending RDP_CTL_GRANT_CONTROL"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control sending RDP_CTL_GRANT_CONTROL");
|
||||
xrdp_rdp_send_control(self, RDP_CTL_GRANT_CONTROL);
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG(("xrdp_rdp_process_data_control unknown action"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control unknown action");
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1039,14 +1039,17 @@ xrdp_rdp_process_data_control(struct xrdp_rdp *self, struct stream *s)
|
||||
static int
|
||||
xrdp_rdp_process_data_sync(struct xrdp_rdp *self)
|
||||
{
|
||||
DEBUG(("xrdp_rdp_process_data_sync"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_sync");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* 2.2.11.2.1 Refresh Rect PDU Data (TS_REFRESH_RECT_PDU) */
|
||||
static int
|
||||
xrdp_rdp_process_screen_update(struct xrdp_rdp *self, struct stream *s)
|
||||
{
|
||||
int index;
|
||||
int num_rects;
|
||||
int left;
|
||||
int top;
|
||||
int right;
|
||||
@ -1054,19 +1057,34 @@ xrdp_rdp_process_screen_update(struct xrdp_rdp *self, struct stream *s)
|
||||
int cx;
|
||||
int cy;
|
||||
|
||||
in_uint8s(s, 4); /* op */
|
||||
if (!s_check_rem(s, 4))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
in_uint8(s, num_rects);
|
||||
in_uint8s(s, 3); /* pad */
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_screen_update: num_rects %d", num_rects);
|
||||
for (index = 0; index < num_rects; index++)
|
||||
{
|
||||
if (!s_check_rem(s, 8))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
/* Inclusive Rectangle (TS_RECTANGLE16) */
|
||||
in_uint16_le(s, left);
|
||||
in_uint16_le(s, top);
|
||||
in_uint16_le(s, right);
|
||||
in_uint16_le(s, bottom);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " left %d top %d right %d bottom %d",
|
||||
left, top, right, bottom);
|
||||
cx = (right - left) + 1;
|
||||
cy = (bottom - top) + 1;
|
||||
|
||||
if (self->session->callback != 0)
|
||||
{
|
||||
self->session->callback(self->session->id, 0x4444, left, top, cx, cy);
|
||||
self->session->callback(self->session->id, 0x4444,
|
||||
left, top, cx, cy);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1108,7 +1126,7 @@ xrdp_rdp_process_data_font(struct xrdp_rdp *self, struct stream *s)
|
||||
{
|
||||
int seq;
|
||||
|
||||
DEBUG(("in xrdp_rdp_process_data_font"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_process_data_font");
|
||||
in_uint8s(s, 2); /* NumberFonts: 0x0, SHOULD be set to 0 */
|
||||
in_uint8s(s, 2); /* TotalNumberFonts: 0x0, SHOULD be set to 0 */
|
||||
in_uint16_le(s, seq); /* ListFlags */
|
||||
@ -1118,17 +1136,17 @@ xrdp_rdp_process_data_font(struct xrdp_rdp *self, struct stream *s)
|
||||
if (seq == 2 || seq == 3) /* after second font message, we are up and */
|
||||
{
|
||||
/* running */
|
||||
DEBUG(("sending fontmap"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "sending fontmap");
|
||||
xrdp_rdp_send_fontmap(self);
|
||||
|
||||
self->session->up_and_running = 1;
|
||||
g_writeln("yeah, up_and_running");
|
||||
DEBUG(("up_and_running set"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "yeah, up_and_running");
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "up_and_running set");
|
||||
xrdp_rdp_send_data_update_sync(self);
|
||||
xrdp_channel_drdynvc_start(self->sec_layer->chan_layer);
|
||||
}
|
||||
|
||||
DEBUG(("out xrdp_rdp_process_data_font"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_process_data_font");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1197,9 +1215,9 @@ xrdp_rdp_process_frame_ack(struct xrdp_rdp *self, struct stream *s)
|
||||
{
|
||||
int frame_id;
|
||||
|
||||
//g_writeln("xrdp_rdp_process_frame_ack:");
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_frame_ack:");
|
||||
in_uint32_le(s, frame_id);
|
||||
//g_writeln(" frame_id %d", frame_id);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " frame_id %d", frame_id);
|
||||
if (self->session->callback != 0)
|
||||
{
|
||||
/* call to xrdp_wm.c : callback */
|
||||
@ -1224,13 +1242,13 @@ xrdp_rdp_process_suppress(struct xrdp_rdp *self, struct stream *s)
|
||||
return 1;
|
||||
}
|
||||
in_uint8(s, allowDisplayUpdates);
|
||||
g_writeln("xrdp_rdp_process_suppress: allowDisplayUpdates %d bytes "
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_suppress: allowDisplayUpdates %d bytes "
|
||||
"left %d", allowDisplayUpdates, (int) (s->end - s->p));
|
||||
switch (allowDisplayUpdates)
|
||||
{
|
||||
case 0: /* SUPPRESS_DISPLAY_UPDATES */
|
||||
self->client_info.suppress_output = 1;
|
||||
g_writeln("xrdp_rdp_process_suppress: suppress_output %d",
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_suppress: suppress_output %d",
|
||||
self->client_info.suppress_output);
|
||||
if (self->session->callback != 0)
|
||||
{
|
||||
@ -1249,7 +1267,7 @@ xrdp_rdp_process_suppress(struct xrdp_rdp *self, struct stream *s)
|
||||
in_uint16_le(s, top);
|
||||
in_uint16_le(s, right);
|
||||
in_uint16_le(s, bottom);
|
||||
g_writeln("xrdp_rdp_process_suppress: suppress_output %d "
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_suppress: suppress_output %d "
|
||||
"left %d top %d right %d bottom %d",
|
||||
self->client_info.suppress_output,
|
||||
left, top, right, bottom);
|
||||
@ -1292,7 +1310,7 @@ xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
DEBUG(("xrdp_rdp_process_data pduType2 %d", pduType2));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data pduType2 %d", pduType2);
|
||||
switch (pduType2)
|
||||
{
|
||||
case RDP_DATA_PDU_POINTER: /* 27(0x1b) */
|
||||
@ -1307,7 +1325,7 @@ xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
|
||||
case RDP_DATA_PDU_SYNCHRONISE: /* 31(0x1f) */
|
||||
xrdp_rdp_process_data_sync(self);
|
||||
break;
|
||||
case 33: /* 33(0x21) ?? Invalidate an area I think */
|
||||
case PDUTYPE2_REFRESH_RECT:
|
||||
xrdp_rdp_process_screen_update(self, s);
|
||||
break;
|
||||
case 35: /* 35(0x23) PDUTYPE2_SUPPRESS_OUTPUT */
|
||||
@ -1326,7 +1344,7 @@ xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
|
||||
xrdp_rdp_process_frame_ack(self, s);
|
||||
break;
|
||||
default:
|
||||
g_writeln("unknown in xrdp_rdp_process_data pduType2 %d", pduType2);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "unknown in xrdp_rdp_process_data pduType2 %d", pduType2);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
@ -1337,9 +1355,9 @@ xrdp_rdp_disconnect(struct xrdp_rdp *self)
|
||||
{
|
||||
int rv;
|
||||
|
||||
DEBUG(("in xrdp_rdp_disconnect"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_disconnect");
|
||||
rv = xrdp_sec_disconnect(self->sec_layer);
|
||||
DEBUG(("out xrdp_rdp_disconnect"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_disconnect");
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -1349,14 +1367,14 @@ xrdp_rdp_send_deactivate(struct xrdp_rdp *self)
|
||||
{
|
||||
struct stream *s;
|
||||
|
||||
DEBUG(("in xrdp_rdp_send_deactivate"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_send_deactivate");
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
|
||||
if (xrdp_rdp_init(self, s) != 0)
|
||||
{
|
||||
free_stream(s);
|
||||
DEBUG(("out xrdp_rdp_send_deactivate error"));
|
||||
LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send_deactivate error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1365,12 +1383,12 @@ xrdp_rdp_send_deactivate(struct xrdp_rdp *self)
|
||||
if (xrdp_rdp_send(self, s, PDUTYPE_DEACTIVATEALLPDU) != 0)
|
||||
{
|
||||
free_stream(s);
|
||||
DEBUG(("out xrdp_rdp_send_deactivate error"));
|
||||
LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send_deactivate error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
free_stream(s);
|
||||
DEBUG(("out xrdp_rdp_send_deactivate"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_send_deactivate");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1381,7 +1399,7 @@ xrdp_rdp_send_session_info(struct xrdp_rdp *self, const char *data,
|
||||
{
|
||||
struct stream *s;
|
||||
|
||||
LLOGLN(0, ("xrdp_rdp_send_session_info: data_bytes %d", data_bytes));
|
||||
LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_rdp_send_session_info: data_bytes %d", data_bytes);
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
|
||||
|
@ -23,15 +23,11 @@
|
||||
#endif
|
||||
|
||||
#include "libxrdp.h"
|
||||
#include "ms-rdpbcgr.h"
|
||||
#include "log.h"
|
||||
#include "string_calls.h"
|
||||
|
||||
|
||||
#define LOG_LEVEL 1
|
||||
#define LLOG(_level, _args) \
|
||||
do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
|
||||
#define LLOGLN(_level, _args) \
|
||||
do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
|
||||
#define LHEXDUMP(_level, _args) \
|
||||
do { if (_level < LOG_LEVEL) { g_hexdump _args ; } } while (0)
|
||||
|
||||
/* some compilers need unsigned char to avoid warnings */
|
||||
static tui8 g_pad_54[40] =
|
||||
@ -240,8 +236,8 @@ xrdp_load_keyboard_layout(struct xrdp_client_info *client_info)
|
||||
char keyboard_cfg_file[256] = { 0 };
|
||||
char rdp_layout[256] = { 0 };
|
||||
|
||||
LLOGLN(0, ("xrdp_load_keyboard_layout: keyboard_type [%d] keyboard_subtype [%d]",
|
||||
client_info->keyboard_type, client_info->keyboard_subtype));
|
||||
LOG(LOG_LEVEL_INFO, "xrdp_load_keyboard_layout: keyboard_type [%d] keyboard_subtype [%d]",
|
||||
client_info->keyboard_type, client_info->keyboard_subtype);
|
||||
|
||||
/* infer model/variant */
|
||||
/* TODO specify different X11 keyboard models/variants */
|
||||
@ -261,7 +257,7 @@ xrdp_load_keyboard_layout(struct xrdp_client_info *client_info)
|
||||
}
|
||||
|
||||
g_snprintf(keyboard_cfg_file, 255, "%s/xrdp_keyboard.ini", XRDP_CFG_PATH);
|
||||
LLOGLN(10, ("keyboard_cfg_file %s", keyboard_cfg_file));
|
||||
LOG(LOG_LEVEL_DEBUG, "keyboard_cfg_file %s", keyboard_cfg_file);
|
||||
|
||||
fd = g_file_open(keyboard_cfg_file);
|
||||
|
||||
@ -292,8 +288,8 @@ xrdp_load_keyboard_layout(struct xrdp_client_info *client_info)
|
||||
{
|
||||
item = (char *)list_get_item(items, i);
|
||||
value = (char *)list_get_item(values, i);
|
||||
LLOGLN(10, ("xrdp_load_keyboard_layout: item %s value %s",
|
||||
item, value));
|
||||
LOG(LOG_LEVEL_DEBUG, "xrdp_load_keyboard_layout: item %s value %s",
|
||||
item, value);
|
||||
if (g_strcasecmp(item, "keyboard_type") == 0)
|
||||
{
|
||||
int v = g_atoi(value);
|
||||
@ -359,9 +355,9 @@ xrdp_load_keyboard_layout(struct xrdp_client_info *client_info)
|
||||
* mixing items from different sections will result in
|
||||
* skipping over current section.
|
||||
*/
|
||||
LLOGLN(10, ("xrdp_load_keyboard_layout: skipping "
|
||||
LOG(LOG_LEVEL_DEBUG, "xrdp_load_keyboard_layout: skipping "
|
||||
"configuration item - %s, continuing to next "
|
||||
"section", item));
|
||||
"section", item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -427,15 +423,15 @@ xrdp_load_keyboard_layout(struct xrdp_client_info *client_info)
|
||||
list_delete(items);
|
||||
list_delete(values);
|
||||
|
||||
LLOGLN(0, ("xrdp_load_keyboard_layout: model [%s] variant [%s] "
|
||||
LOG(LOG_LEVEL_INFO, "xrdp_load_keyboard_layout: model [%s] variant [%s] "
|
||||
"layout [%s] options [%s]", client_info->model,
|
||||
client_info->variant, client_info->layout, client_info->options));
|
||||
client_info->variant, client_info->layout, client_info->options);
|
||||
g_file_close(fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLOGLN(0, ("xrdp_load_keyboard_layout: error opening %s",
|
||||
keyboard_cfg_file));
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_load_keyboard_layout: error opening %s",
|
||||
keyboard_cfg_file);
|
||||
}
|
||||
}
|
||||
|
||||
@ -445,7 +441,7 @@ xrdp_sec_create(struct xrdp_rdp *owner, struct trans *trans)
|
||||
{
|
||||
struct xrdp_sec *self;
|
||||
|
||||
DEBUG((" in xrdp_sec_create"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_create");
|
||||
self = (struct xrdp_sec *) g_malloc(sizeof(struct xrdp_sec), 1);
|
||||
self->rdp_layer = owner;
|
||||
self->crypt_method = CRYPT_METHOD_NONE; /* set later */
|
||||
@ -455,7 +451,7 @@ xrdp_sec_create(struct xrdp_rdp *owner, struct trans *trans)
|
||||
self->fastpath_layer = xrdp_fastpath_create(self, trans);
|
||||
self->chan_layer = xrdp_channel_create(self, self->mcs_layer);
|
||||
self->is_security_header_present = 1;
|
||||
DEBUG((" out xrdp_sec_create"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_create");
|
||||
|
||||
return self;
|
||||
}
|
||||
@ -466,7 +462,7 @@ xrdp_sec_delete(struct xrdp_sec *self)
|
||||
{
|
||||
if (self == 0)
|
||||
{
|
||||
g_writeln("xrdp_sec_delete: self is null");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_sec_delete: self is null");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -566,7 +562,7 @@ xrdp_sec_update(char *key, char *update_key, int key_len)
|
||||
static void
|
||||
xrdp_sec_fips_decrypt(struct xrdp_sec *self, char *data, int len)
|
||||
{
|
||||
LLOGLN(10, ("xrdp_sec_fips_decrypt:"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_fips_decrypt:");
|
||||
ssl_des3_decrypt(self->decrypt_fips_info, len, data, data);
|
||||
self->decrypt_use_count++;
|
||||
}
|
||||
@ -575,7 +571,7 @@ xrdp_sec_fips_decrypt(struct xrdp_sec *self, char *data, int len)
|
||||
static void
|
||||
xrdp_sec_decrypt(struct xrdp_sec *self, char *data, int len)
|
||||
{
|
||||
LLOGLN(10, ("xrdp_sec_decrypt:"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_decrypt:");
|
||||
if (self->decrypt_use_count == 4096)
|
||||
{
|
||||
xrdp_sec_update(self->decrypt_key, self->decrypt_update_key,
|
||||
@ -592,7 +588,7 @@ xrdp_sec_decrypt(struct xrdp_sec *self, char *data, int len)
|
||||
static void
|
||||
xrdp_sec_fips_encrypt(struct xrdp_sec *self, char *data, int len)
|
||||
{
|
||||
LLOGLN(10, ("xrdp_sec_fips_encrypt:"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_fips_encrypt:");
|
||||
ssl_des3_encrypt(self->encrypt_fips_info, len, data, data);
|
||||
self->encrypt_use_count++;
|
||||
}
|
||||
@ -601,7 +597,7 @@ xrdp_sec_fips_encrypt(struct xrdp_sec *self, char *data, int len)
|
||||
static void
|
||||
xrdp_sec_encrypt(struct xrdp_sec *self, char *data, int len)
|
||||
{
|
||||
LLOGLN(10, ("xrdp_sec_encrypt:"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_encrypt:");
|
||||
if (self->encrypt_use_count == 4096)
|
||||
{
|
||||
xrdp_sec_update(self->encrypt_key, self->encrypt_update_key,
|
||||
@ -627,7 +623,7 @@ unicode_utf16_in(struct stream *s, int src_bytes, char *dst, int dst_len)
|
||||
int i;
|
||||
int bytes;
|
||||
|
||||
LLOGLN(10, ("unicode_utf16_in: uni_len %d, dst_len %d", src_bytes, dst_len));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "unicode_utf16_in: uni_len %d, dst_len %d", src_bytes, dst_len);
|
||||
if (src_bytes == 0)
|
||||
{
|
||||
if (!s_check_rem(s, 2))
|
||||
@ -654,7 +650,7 @@ unicode_utf16_in(struct stream *s, int src_bytes, char *dst, int dst_len)
|
||||
{
|
||||
g_memset(dst, '\0', dst_len);
|
||||
}
|
||||
LLOGLN(10, ("unicode_utf16_in: num_chars %d, dst %s", num_chars, dst));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "unicode_utf16_in: num_chars %d, dst %s", num_chars, dst);
|
||||
g_free(src);
|
||||
|
||||
return 0;
|
||||
@ -674,6 +670,7 @@ 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);
|
||||
@ -683,48 +680,47 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
|
||||
}
|
||||
in_uint8s(s, 4);
|
||||
in_uint32_le(s, flags);
|
||||
DEBUG(("in xrdp_sec_process_logon_info flags $%x", flags));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_sec_process_logon_info flags $%x", flags);
|
||||
|
||||
/* this is the first test that the decrypt is working */
|
||||
if ((flags & RDP_LOGON_NORMAL) != RDP_LOGON_NORMAL) /* 0x33 */
|
||||
{
|
||||
/* must be or error */
|
||||
DEBUG(("xrdp_sec_process_logon_info: flags wrong, major error"));
|
||||
LLOGLN(0, ("xrdp_sec_process_logon_info: flags wrong, likely decrypt "
|
||||
"not working"));
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_sec_process_logon_info: flags wrong, likely decrypt "
|
||||
"not working");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (flags & RDP_LOGON_LEAVE_AUDIO)
|
||||
{
|
||||
self->rdp_layer->client_info.sound_code = 1;
|
||||
DEBUG(("flag RDP_LOGON_LEAVE_AUDIO found"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_LOGON_LEAVE_AUDIO found");
|
||||
}
|
||||
|
||||
if (flags & RDP_LOGON_RAIL)
|
||||
{
|
||||
self->rdp_layer->client_info.rail_enable = 1;
|
||||
DEBUG(("flag RDP_LOGON_RAIL found"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_LOGON_RAIL found");
|
||||
}
|
||||
|
||||
if ((flags & RDP_LOGON_AUTO) && (!self->rdp_layer->client_info.is_mce))
|
||||
/* todo, for now not allowing autologon and mce both */
|
||||
{
|
||||
self->rdp_layer->client_info.rdp_autologin = 1;
|
||||
DEBUG(("flag RDP_LOGON_AUTO found"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_LOGON_AUTO found");
|
||||
}
|
||||
|
||||
if (flags & RDP_COMPRESSION)
|
||||
{
|
||||
DEBUG(("flag RDP_COMPRESSION found"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_COMPRESSION found");
|
||||
if (self->rdp_layer->client_info.use_bulk_comp)
|
||||
{
|
||||
DEBUG(("flag RDP_COMPRESSION set"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_COMPRESSION set");
|
||||
self->rdp_layer->client_info.rdp_compression = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG(("flag RDP_COMPRESSION not set"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_COMPRESSION not set");
|
||||
}
|
||||
}
|
||||
|
||||
@ -734,9 +730,9 @@ 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"));
|
||||
LOG(LOG_LEVEL_ERROR, "ERROR [xrdp_sec_process_logon_info()]: len_domain >= %d", INFO_CLIENT_MAX_CB_LEN);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -756,9 +752,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"));
|
||||
LOG(LOG_LEVEL_ERROR, "ERROR [xrdp_sec_process_logon_info()]: len_user >= %d", INFO_CLIENT_MAX_CB_LEN);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -768,9 +764,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"));
|
||||
LOG(LOG_LEVEL_ERROR, "ERROR [xrdp_sec_process_logon_info()]: len_password >= %d", INFO_CLIENT_MAX_CB_LEN);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -780,9 +776,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"));
|
||||
LOG(LOG_LEVEL_ERROR, "ERROR [xrdp_sec_process_logon_info()]: len_program >= %d", INFO_CLIENT_MAX_CB_LEN);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -792,9 +788,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"));
|
||||
LOG(LOG_LEVEL_ERROR, "ERROR [xrdp_sec_process_logon_info()]: len_directory >= %d", INFO_CLIENT_MAX_CB_LEN);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -802,12 +798,12 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
DEBUG(("domain %s", self->rdp_layer->client_info.domain));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "domain %s", self->rdp_layer->client_info.domain);
|
||||
if (unicode_utf16_in(s, len_user, self->rdp_layer->client_info.username, sizeof(self->rdp_layer->client_info.username) - 1) != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
DEBUG(("username %s", self->rdp_layer->client_info.username));
|
||||
|
||||
|
||||
if (flags & RDP_LOGON_AUTO)
|
||||
{
|
||||
@ -815,7 +811,18 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
DEBUG(("flag RDP_LOGON_AUTO found"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_LOGON_AUTO found");
|
||||
}
|
||||
else if (self->rdp_layer->client_info.enable_token_login
|
||||
&& len_user > 0
|
||||
&& len_password == 0
|
||||
&& (sep = g_strchr(self->rdp_layer->client_info.username, '\x1f')) != NULL)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "Logon token detected");
|
||||
g_strncpy(self->rdp_layer->client_info.password, sep + 1,
|
||||
sizeof(self->rdp_layer->client_info.password) - 1);
|
||||
self->rdp_layer->client_info.username[sep - self->rdp_layer->client_info.username] = '\0';
|
||||
self->rdp_layer->client_info.rdp_autologin = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -826,21 +833,29 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
|
||||
in_uint8s(s, len_password + 2);
|
||||
if (self->rdp_layer->client_info.require_credentials)
|
||||
{
|
||||
g_writeln("xrdp_sec_process_logon_info: credentials on cmd line is mandatory");
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_sec_process_logon_info: credentials on cmd line is mandatory");
|
||||
return 1; /* credentials on cmd line is mandatory */
|
||||
}
|
||||
}
|
||||
if (self->rdp_layer->client_info.domain_user_separator[0] != '\0'
|
||||
&& self->rdp_layer->client_info.domain[0] != '\0')
|
||||
{
|
||||
int size = sizeof(self->rdp_layer->client_info.username);
|
||||
g_strncat(self->rdp_layer->client_info.username, self->rdp_layer->client_info.domain_user_separator, size - 1 - g_strlen(self->rdp_layer->client_info.domain_user_separator));
|
||||
g_strncat(self->rdp_layer->client_info.username, self->rdp_layer->client_info.domain, size - 1 - g_strlen(self->rdp_layer->client_info.domain));
|
||||
}
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "username %s", self->rdp_layer->client_info.username);
|
||||
|
||||
if (unicode_utf16_in(s, len_program, self->rdp_layer->client_info.program, sizeof(self->rdp_layer->client_info.program) - 1) != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
DEBUG(("program %s", self->rdp_layer->client_info.program));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "program %s", self->rdp_layer->client_info.program);
|
||||
if (unicode_utf16_in(s, len_directory, self->rdp_layer->client_info.directory, sizeof(self->rdp_layer->client_info.directory) - 1) != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
DEBUG(("directory %s", self->rdp_layer->client_info.directory));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "directory %s", self->rdp_layer->client_info.directory);
|
||||
|
||||
if (flags & RDP_LOGON_BLOB)
|
||||
{
|
||||
@ -875,7 +890,7 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s)
|
||||
in_uint32_le(s, self->rdp_layer->client_info.rdp5_performanceflags);
|
||||
}
|
||||
|
||||
DEBUG(("out xrdp_sec_process_logon_info"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_sec_process_logon_info");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -886,7 +901,7 @@ xrdp_sec_send_lic_initial(struct xrdp_sec *self)
|
||||
{
|
||||
struct stream *s;
|
||||
|
||||
LLOGLN(10, ("xrdp_sec_send_lic_initial:"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_lic_initial:");
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
|
||||
@ -1079,7 +1094,7 @@ xrdp_sec_fips_establish_keys(struct xrdp_sec *self)
|
||||
const char *fips_ivec;
|
||||
void *sha1;
|
||||
|
||||
LLOGLN(0, ("xrdp_sec_fips_establish_keys:"));
|
||||
LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_sec_fips_establish_keys:");
|
||||
|
||||
sha1 = ssl_sha1_info_create();
|
||||
ssl_sha1_clear(sha1);
|
||||
@ -1123,7 +1138,7 @@ xrdp_sec_establish_keys(struct xrdp_sec *self)
|
||||
char temp_hash[48];
|
||||
char input[48];
|
||||
|
||||
LLOGLN(0, ("xrdp_sec_establish_keys:"));
|
||||
LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_sec_establish_keys:");
|
||||
|
||||
g_memcpy(input, self->client_random, 24);
|
||||
g_memcpy(input + 24, self->server_random, 24);
|
||||
@ -1164,7 +1179,13 @@ xrdp_sec_recv_fastpath(struct xrdp_sec *self, struct stream *s)
|
||||
int len;
|
||||
int pad;
|
||||
|
||||
LLOGLN(10, ("xrdp_sec_recv_fastpath:"));
|
||||
#ifndef XRDP_DEBUG
|
||||
/* TODO: remove UNUSED_VAR once the `var` variable is used for more than
|
||||
logging in debug mode */
|
||||
UNUSED_VAR(ver);
|
||||
#endif
|
||||
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv_fastpath:");
|
||||
if (xrdp_fastpath_recv(self->fastpath_layer, s) != 0)
|
||||
{
|
||||
return 1;
|
||||
@ -1185,9 +1206,9 @@ xrdp_sec_recv_fastpath(struct xrdp_sec *self, struct stream *s)
|
||||
return 1;
|
||||
}
|
||||
in_uint8(s, pad);
|
||||
LLOGLN(10, ("xrdp_sec_recv_fastpath: len %d ver %d pad %d", len, ver, pad));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv_fastpath: len %d ver %d pad %d", len, ver, pad);
|
||||
in_uint8s(s, 8); /* dataSignature (8 bytes), skip for now */
|
||||
LLOGLN(10, ("xrdp_sec_recv_fastpath: data len %d", (int)(s->end - s->p)));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv_fastpath: data len %d", (int)(s->end - s->p));
|
||||
xrdp_sec_fips_decrypt(self, s->p, (int)(s->end - s->p));
|
||||
s->end -= pad;
|
||||
}
|
||||
@ -1227,12 +1248,11 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
|
||||
int ver;
|
||||
int pad;
|
||||
|
||||
DEBUG((" in xrdp_sec_recv"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_recv");
|
||||
|
||||
if (xrdp_mcs_recv(self->mcs_layer, s, chan) != 0)
|
||||
{
|
||||
DEBUG((" out xrdp_sec_recv : error"));
|
||||
g_writeln("xrdp_sec_recv: xrdp_mcs_recv failed");
|
||||
LOG(LOG_LEVEL_ERROR, " out xrdp_sec_recv : error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1248,7 +1268,7 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
|
||||
}
|
||||
|
||||
in_uint32_le(s, flags);
|
||||
DEBUG((" in xrdp_sec_recv flags $%x", flags));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_recv flags $%x", flags);
|
||||
|
||||
if (flags & SEC_ENCRYPT) /* 0x08 */
|
||||
{
|
||||
@ -1265,9 +1285,9 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
|
||||
return 1;
|
||||
}
|
||||
in_uint8(s, pad);
|
||||
LLOGLN(10, ("xrdp_sec_recv: len %d ver %d pad %d", len, ver, pad));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv: len %d ver %d pad %d", len, ver, pad);
|
||||
in_uint8s(s, 8); /* signature(8) */
|
||||
LLOGLN(10, ("xrdp_sec_recv: data len %d", (int)(s->end - s->p)));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv: data len %d", (int)(s->end - s->p));
|
||||
xrdp_sec_fips_decrypt(self, s->p, (int)(s->end - s->p));
|
||||
s->end -= pad;
|
||||
}
|
||||
@ -1301,9 +1321,9 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
|
||||
in_uint8a(s, self->client_crypt_random, len - 8);
|
||||
xrdp_sec_rsa_op(self, self->client_random, self->client_crypt_random,
|
||||
len - 8, self->pub_mod, self->pri_exp);
|
||||
LLOGLN(10, ("xrdp_sec_recv: client random - len %d", len));
|
||||
LHEXDUMP(10, (self->client_random, 256));
|
||||
LHEXDUMP(10, (self->client_crypt_random, len - 8));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv: client random - len %d", len);
|
||||
LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "client random", self->client_random, 256);
|
||||
LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "client crypt random", self->client_crypt_random, len - 8);
|
||||
if (self->crypt_level == CRYPT_LEVEL_FIPS)
|
||||
{
|
||||
xrdp_sec_fips_establish_keys(self);
|
||||
@ -1313,7 +1333,7 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
|
||||
xrdp_sec_establish_keys(self);
|
||||
}
|
||||
*chan = 1; /* just set a non existing channel and exit */
|
||||
DEBUG((" out xrdp_sec_recv"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_recv");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1321,7 +1341,7 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
|
||||
{
|
||||
if (xrdp_sec_process_logon_info(self, s) != 0)
|
||||
{
|
||||
DEBUG((" out xrdp_sec_recv error"));
|
||||
LOG(LOG_LEVEL_ERROR, " out xrdp_sec_recv error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1329,22 +1349,22 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
|
||||
{
|
||||
if (xrdp_sec_send_media_lic_response(self) != 0)
|
||||
{
|
||||
DEBUG((" out xrdp_sec_recv error"));
|
||||
LOG(LOG_LEVEL_ERROR, " out xrdp_sec_recv error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
DEBUG((" out xrdp_sec_recv"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_recv");
|
||||
return -1; /* special error that means send demand active */
|
||||
}
|
||||
|
||||
if (xrdp_sec_send_lic_initial(self) != 0)
|
||||
{
|
||||
DEBUG((" out xrdp_sec_recv error"));
|
||||
LOG(LOG_LEVEL_ERROR, " out xrdp_sec_recv error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
*chan = 1; /* just set a non existing channel and exit */
|
||||
DEBUG((" out xrdp_sec_recv"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_recv");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1352,7 +1372,7 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
|
||||
{
|
||||
if (xrdp_sec_send_lic_response(self) != 0)
|
||||
{
|
||||
DEBUG((" out xrdp_sec_recv error"));
|
||||
LOG(LOG_LEVEL_ERROR, " out xrdp_sec_recv error");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1363,11 +1383,11 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan)
|
||||
self->is_security_header_present = 0;
|
||||
}
|
||||
|
||||
DEBUG((" out xrdp_sec_recv"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_recv");
|
||||
return -1; /* special error that means send demand active */
|
||||
}
|
||||
|
||||
DEBUG((" out xrdp_sec_recv"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_recv");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1438,15 +1458,15 @@ xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan)
|
||||
int datalen;
|
||||
int pad;
|
||||
|
||||
LLOGLN(10, ("xrdp_sec_send:"));
|
||||
DEBUG((" in xrdp_sec_send"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send:");
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_send");
|
||||
s_pop_layer(s, sec_hdr);
|
||||
|
||||
if (self->crypt_level > CRYPT_LEVEL_NONE)
|
||||
{
|
||||
if (self->crypt_level == CRYPT_LEVEL_FIPS)
|
||||
{
|
||||
LLOGLN(10, ("xrdp_sec_send: fips"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send: fips");
|
||||
out_uint32_le(s, SEC_ENCRYPT);
|
||||
datalen = (int)((s->end - s->p) - 12);
|
||||
out_uint16_le(s, 16); /* crypto header size */
|
||||
@ -1476,7 +1496,7 @@ xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan)
|
||||
return 1;
|
||||
}
|
||||
|
||||
DEBUG((" out xrdp_sec_send"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_send");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1535,12 +1555,12 @@ xrdp_sec_send_fastpath(struct xrdp_sec *self, struct stream *s)
|
||||
int error;
|
||||
char save[8];
|
||||
|
||||
LLOGLN(10, ("xrdp_sec_send_fastpath:"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_fastpath:");
|
||||
error = 0;
|
||||
s_pop_layer(s, sec_hdr);
|
||||
if (self->crypt_level == CRYPT_LEVEL_FIPS)
|
||||
{
|
||||
LLOGLN(10, ("xrdp_sec_send_fastpath: fips"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_fastpath: fips");
|
||||
pdulen = (int)(s->end - s->p);
|
||||
datalen = pdulen - 15;
|
||||
pad = (8 - (datalen % 8)) & 7;
|
||||
@ -1563,7 +1583,7 @@ xrdp_sec_send_fastpath(struct xrdp_sec *self, struct stream *s)
|
||||
}
|
||||
else if (self->crypt_level > CRYPT_LEVEL_LOW)
|
||||
{
|
||||
LLOGLN(10, ("xrdp_sec_send_fastpath: crypt"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_fastpath: crypt");
|
||||
pdulen = (int)(s->end - s->p);
|
||||
datalen = pdulen - 11;
|
||||
secFlags = 0x2;
|
||||
@ -1577,9 +1597,9 @@ xrdp_sec_send_fastpath(struct xrdp_sec *self, struct stream *s)
|
||||
}
|
||||
else
|
||||
{
|
||||
LLOGLN(10, ("xrdp_sec_send_fastpath: no crypt"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_fastpath: no crypt");
|
||||
pdulen = (int)(s->end - s->p);
|
||||
LLOGLN(10, ("xrdp_sec_send_fastpath: pdulen %d", pdulen));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_fastpath: pdulen %d", pdulen);
|
||||
secFlags = 0x0;
|
||||
fpOutputHeader = secFlags << 6;
|
||||
out_uint8(s, fpOutputHeader);
|
||||
@ -1598,7 +1618,7 @@ xrdp_sec_send_fastpath(struct xrdp_sec *self, struct stream *s)
|
||||
/* http://msdn.microsoft.com/en-us/library/cc240510.aspx
|
||||
2.2.1.3.2 Client Core Data (TS_UD_CS_CORE) */
|
||||
static int
|
||||
xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec* self, struct stream* s)
|
||||
xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s)
|
||||
{
|
||||
int colorDepth;
|
||||
int postBeta2ColorDepth;
|
||||
@ -1611,7 +1631,7 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec* self, struct stream* s)
|
||||
in_uint16_le(s, self->rdp_layer->client_info.width);
|
||||
in_uint16_le(s, self->rdp_layer->client_info.height);
|
||||
in_uint16_le(s, colorDepth);
|
||||
g_writeln("colorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp)", colorDepth);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "colorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp)", colorDepth);
|
||||
switch (colorDepth)
|
||||
{
|
||||
case RNS_UD_COLOR_4BPP:
|
||||
@ -1625,13 +1645,13 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec* self, struct stream* s)
|
||||
in_uint8s(s, 4); /* keyboardLayout */
|
||||
in_uint8s(s, 4); /* clientBuild */
|
||||
unicode_utf16_in(s, INFO_CLIENT_NAME_BYTES - 2, clientName, sizeof(clientName) - 1); /* clientName */
|
||||
log_message(LOG_LEVEL_INFO, "connected client computer name: %s", clientName);
|
||||
LOG(LOG_LEVEL_INFO, "connected client computer name: %s", clientName);
|
||||
in_uint8s(s, 4); /* keyboardType */
|
||||
in_uint8s(s, 4); /* keyboardSubType */
|
||||
in_uint8s(s, 4); /* keyboardFunctionKey */
|
||||
in_uint8s(s, 64); /* imeFileName */
|
||||
in_uint16_le(s, postBeta2ColorDepth);
|
||||
g_writeln("postBeta2ColorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp "
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "postBeta2ColorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp "
|
||||
"0xca02 15bpp 0xca03 16bpp 0xca04 24bpp)", postBeta2ColorDepth);
|
||||
|
||||
switch (postBeta2ColorDepth)
|
||||
@ -1669,7 +1689,7 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec* self, struct stream* s)
|
||||
return 0;
|
||||
}
|
||||
in_uint16_le(s, highColorDepth);
|
||||
g_writeln("highColorDepth 0x%4.4x (0x0004 4bpp 0x0008 8bpp 0x000f 15bpp "
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "highColorDepth 0x%4.4x (0x0004 4bpp 0x0008 8bpp 0x000f 15bpp "
|
||||
"0x0010 16 bpp 0x0018 24bpp)", highColorDepth);
|
||||
self->rdp_layer->client_info.bpp = highColorDepth;
|
||||
|
||||
@ -1678,7 +1698,7 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec* self, struct stream* s)
|
||||
return 0;
|
||||
}
|
||||
in_uint16_le(s, supportedColorDepths);
|
||||
g_writeln("supportedColorDepths 0x%4.4x (0x0001 24bpp 0x0002 16bpp "
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "supportedColorDepths 0x%4.4x (0x0001 24bpp 0x0002 16bpp "
|
||||
"0x0004 15bpp 0x0008 32bpp)", supportedColorDepths);
|
||||
|
||||
if (!s_check_rem(s, 2))
|
||||
@ -1687,7 +1707,7 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec* self, struct stream* s)
|
||||
}
|
||||
in_uint16_le(s, earlyCapabilityFlags);
|
||||
self->rdp_layer->client_info.mcs_early_capability_flags = earlyCapabilityFlags;
|
||||
g_writeln("earlyCapabilityFlags 0x%4.4x (0x0002 want32)",
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "earlyCapabilityFlags 0x%4.4x (0x0002 want32)",
|
||||
earlyCapabilityFlags);
|
||||
if ((earlyCapabilityFlags & 0x0002) && (supportedColorDepths & 0x0008))
|
||||
{
|
||||
@ -1705,7 +1725,7 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec* self, struct stream* s)
|
||||
return 0;
|
||||
}
|
||||
in_uint8(s, self->rdp_layer->client_info.mcs_connection_type); /* connectionType */
|
||||
g_writeln("got client client connection type 0x%8.8x",
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "got client client connection type 0x%8.8x",
|
||||
self->rdp_layer->client_info.mcs_connection_type);
|
||||
|
||||
if (!s_check_rem(s, 1))
|
||||
@ -1743,28 +1763,28 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec* self, struct stream* s)
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
xrdp_sec_process_mcs_data_CS_SECURITY(struct xrdp_sec *self, struct stream* s)
|
||||
xrdp_sec_process_mcs_data_CS_SECURITY(struct xrdp_sec *self, struct stream *s)
|
||||
{
|
||||
int crypt_method;
|
||||
int found;
|
||||
|
||||
g_writeln("xrdp_sec_process_mcs_data_CS_SECURITY:");
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_process_mcs_data_CS_SECURITY:");
|
||||
in_uint32_le(s, crypt_method);
|
||||
if (crypt_method & CRYPT_METHOD_40BIT)
|
||||
{
|
||||
g_writeln(" client supports 40 bit encryption");
|
||||
LOG(LOG_LEVEL_INFO, " client supports 40 bit encryption");
|
||||
}
|
||||
if (crypt_method & CRYPT_METHOD_128BIT)
|
||||
{
|
||||
g_writeln(" client supports 128 bit encryption");
|
||||
LOG(LOG_LEVEL_INFO, " client supports 128 bit encryption");
|
||||
}
|
||||
if (crypt_method & CRYPT_METHOD_56BIT)
|
||||
{
|
||||
g_writeln(" client supports 56 bit encryption");
|
||||
LOG(LOG_LEVEL_INFO, " client supports 56 bit encryption");
|
||||
}
|
||||
if (crypt_method & CRYPT_METHOD_FIPS)
|
||||
{
|
||||
g_writeln(" client supports fips encryption");
|
||||
LOG(LOG_LEVEL_INFO, " client supports fips encryption");
|
||||
}
|
||||
found = 0;
|
||||
if ((found == 0) &&
|
||||
@ -1773,7 +1793,7 @@ xrdp_sec_process_mcs_data_CS_SECURITY(struct xrdp_sec *self, struct stream* s)
|
||||
{
|
||||
if (crypt_method & CRYPT_METHOD_FIPS)
|
||||
{
|
||||
g_writeln(" client and server support fips, using fips");
|
||||
LOG(LOG_LEVEL_INFO, " client and server support fips, using fips");
|
||||
self->crypt_method = CRYPT_METHOD_FIPS;
|
||||
self->crypt_level = CRYPT_LEVEL_FIPS;
|
||||
found = 1;
|
||||
@ -1785,7 +1805,7 @@ xrdp_sec_process_mcs_data_CS_SECURITY(struct xrdp_sec *self, struct stream* s)
|
||||
{
|
||||
if (crypt_method & CRYPT_METHOD_128BIT)
|
||||
{
|
||||
g_writeln(" client and server support high crypt, using "
|
||||
LOG(LOG_LEVEL_INFO, " client and server support high crypt, using "
|
||||
"high crypt");
|
||||
self->crypt_method = CRYPT_METHOD_128BIT;
|
||||
self->crypt_level = CRYPT_LEVEL_HIGH;
|
||||
@ -1798,7 +1818,7 @@ xrdp_sec_process_mcs_data_CS_SECURITY(struct xrdp_sec *self, struct stream* s)
|
||||
{
|
||||
if (crypt_method & CRYPT_METHOD_40BIT)
|
||||
{
|
||||
g_writeln(" client and server support medium crypt, using "
|
||||
LOG(LOG_LEVEL_INFO, " client and server support medium crypt, using "
|
||||
"medium crypt");
|
||||
self->crypt_method = CRYPT_METHOD_40BIT;
|
||||
self->crypt_level = CRYPT_LEVEL_CLIENT_COMPATIBLE;
|
||||
@ -1811,7 +1831,7 @@ xrdp_sec_process_mcs_data_CS_SECURITY(struct xrdp_sec *self, struct stream* s)
|
||||
{
|
||||
if (crypt_method & CRYPT_METHOD_40BIT)
|
||||
{
|
||||
g_writeln(" client and server support low crypt, using "
|
||||
LOG(LOG_LEVEL_INFO, " client and server support low crypt, using "
|
||||
"low crypt");
|
||||
self->crypt_method = CRYPT_METHOD_40BIT;
|
||||
self->crypt_level = CRYPT_LEVEL_LOW;
|
||||
@ -1823,18 +1843,18 @@ xrdp_sec_process_mcs_data_CS_SECURITY(struct xrdp_sec *self, struct stream* s)
|
||||
{
|
||||
if (crypt_method == CRYPT_METHOD_NONE)
|
||||
{
|
||||
g_writeln(" client and server support none crypt, using "
|
||||
LOG(LOG_LEVEL_INFO, " client and server support none crypt, using "
|
||||
"none crypt");
|
||||
self->crypt_method = CRYPT_METHOD_NONE;
|
||||
self->crypt_level = CRYPT_LEVEL_NONE;
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
// if (found == 0)
|
||||
// {
|
||||
// g_writeln(" can not find client / server agreed encryption method");
|
||||
// return 1;
|
||||
// }
|
||||
// if (found == 0)
|
||||
// {
|
||||
// LOG_DEVEL(LOG_LEVEL_TRACE, " can not find client / server agreed encryption method");
|
||||
// return 1;
|
||||
// }
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1850,12 +1870,12 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
|
||||
struct mcs_channel_item *channel_item;
|
||||
|
||||
client_info = &(self->rdp_layer->client_info);
|
||||
DEBUG(("processing channels, channels_allowed is %d",
|
||||
client_info->channels_allowed));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "processing channels, channels_allowed is %d",
|
||||
client_info->channels_allowed);
|
||||
/* this is an option set in xrdp.ini */
|
||||
if (client_info->channels_allowed == 0) /* are channels on? */
|
||||
{
|
||||
log_message(LOG_LEVEL_INFO, "all channels are disabled by "
|
||||
LOG(LOG_LEVEL_INFO, "all channels are disabled by "
|
||||
"configuration");
|
||||
return 0;
|
||||
}
|
||||
@ -1881,13 +1901,13 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
|
||||
if (g_strlen(channel_item->name) > 0)
|
||||
{
|
||||
channel_item->chanid = MCS_GLOBAL_CHANNEL + (index + 1);
|
||||
log_message(LOG_LEVEL_INFO, "adding channel item name %s chan_id "
|
||||
LOG(LOG_LEVEL_INFO, "adding channel item name %s chan_id "
|
||||
"%d flags 0x%8.8x", channel_item->name,
|
||||
channel_item->chanid, channel_item->flags);
|
||||
list_add_item(self->mcs_layer->channel_list,
|
||||
(intptr_t) channel_item);
|
||||
DEBUG(("got channel flags %8.8x name %s", channel_item->flags,
|
||||
channel_item->name));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "got channel flags %8.8x name %s", channel_item->flags,
|
||||
channel_item->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1914,32 +1934,32 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
|
||||
|
||||
client_info = &(self->rdp_layer->client_info);
|
||||
|
||||
LLOGLN(10, ("xrdp_sec_process_mcs_data_monitors: processing monitors data, allow_multimon is %d", client_info->multimon));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_process_mcs_data_monitors: processing monitors data, allow_multimon is %d", client_info->multimon);
|
||||
/* this is an option set in xrdp.ini */
|
||||
if (client_info->multimon != 1) /* are multi-monitors allowed ? */
|
||||
{
|
||||
LLOGLN(0, ("[INFO] xrdp_sec_process_mcs_data_monitors: multimon is not "
|
||||
"allowed, skipping"));
|
||||
LOG_DEVEL(LOG_LEVEL_INFO, "[INFO] xrdp_sec_process_mcs_data_monitors: multimon is not "
|
||||
"allowed, skipping");
|
||||
return 0;
|
||||
}
|
||||
in_uint32_le(s, flags); /* flags */
|
||||
//verify flags - must be 0x0
|
||||
if (flags != 0)
|
||||
{
|
||||
LLOGLN(0, ("[ERROR] xrdp_sec_process_mcs_data_monitors: flags MUST be "
|
||||
"zero, detected: %d", flags));
|
||||
LOG(LOG_LEVEL_ERROR, "[ERROR] xrdp_sec_process_mcs_data_monitors: flags MUST be "
|
||||
"zero, detected: %d", flags);
|
||||
return 1;
|
||||
}
|
||||
in_uint32_le(s, monitorCount);
|
||||
//verify monitorCount - max 16
|
||||
if (monitorCount > 16)
|
||||
{
|
||||
LLOGLN(0, ("[ERROR] xrdp_sec_process_mcs_data_monitors: max allowed "
|
||||
"monitors is 16, detected: %d", monitorCount));
|
||||
LOG(LOG_LEVEL_ERROR, "[ERROR] xrdp_sec_process_mcs_data_monitors: max allowed "
|
||||
"monitors is 16, detected: %d", monitorCount);
|
||||
return 1;
|
||||
}
|
||||
|
||||
LLOGLN(10, ("xrdp_sec_process_mcs_data_monitors: monitorCount= %d", monitorCount));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_process_mcs_data_monitors: monitorCount= %d", monitorCount);
|
||||
|
||||
client_info->monitorCount = monitorCount;
|
||||
|
||||
@ -1976,13 +1996,13 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
|
||||
got_primary = 1;
|
||||
}
|
||||
|
||||
LLOGLN(10, ("xrdp_sec_process_mcs_data_monitors: got a monitor [%d]: left= %d, top= %d, right= %d, bottom= %d, is_primary?= %d",
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_process_mcs_data_monitors: got a monitor [%d]: left= %d, top= %d, right= %d, bottom= %d, is_primary?= %d",
|
||||
index,
|
||||
client_info->minfo[index].left,
|
||||
client_info->minfo[index].top,
|
||||
client_info->minfo[index].right,
|
||||
client_info->minfo[index].bottom,
|
||||
client_info->minfo[index].is_primary));
|
||||
client_info->minfo[index].is_primary);
|
||||
}
|
||||
|
||||
if (!got_primary)
|
||||
@ -2009,7 +2029,7 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
|
||||
if (client_info->width > 0x7FFE || client_info->width < 0xC8 ||
|
||||
client_info->height > 0x7FFE || client_info->height < 0xC8)
|
||||
{
|
||||
LLOGLN(0, ("[ERROR] xrdp_sec_process_mcs_data_monitors: error, virtual desktop width / height is too large"));
|
||||
LOG(LOG_LEVEL_ERROR, "[ERROR] xrdp_sec_process_mcs_data_monitors: error, virtual desktop width / height is too large");
|
||||
return 1; /* error */
|
||||
}
|
||||
|
||||
@ -2055,12 +2075,12 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self)
|
||||
|
||||
if ((size < 4) || (!s_check_rem(s, size - 4)))
|
||||
{
|
||||
LLOGLN(0, ("error in xrdp_sec_process_mcs_data tag %d size %d",
|
||||
tag, size));
|
||||
LOG(LOG_LEVEL_ERROR, "error in xrdp_sec_process_mcs_data tag %d size %d",
|
||||
tag, size);
|
||||
break;
|
||||
}
|
||||
|
||||
LLOGLN(10, ("xrdp_sec_process_mcs_data: 0x%8.8x", tag));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_process_mcs_data: 0x%8.8x", tag);
|
||||
switch (tag)
|
||||
{
|
||||
case SEC_TAG_CLI_INFO: /* CS_CORE 0xC001 */
|
||||
@ -2098,8 +2118,8 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self)
|
||||
SC_MCS_MSGCHANNEL 0x0C04
|
||||
SC_MULTITRANSPORT 0x0C08 */
|
||||
default:
|
||||
LLOGLN(0, ("error unknown xrdp_sec_process_mcs_data "
|
||||
"tag 0x%4.4x size %d", tag, size));
|
||||
LOG(LOG_LEVEL_ERROR, "error unknown xrdp_sec_process_mcs_data "
|
||||
"tag 0x%4.4x size %d", tag, size);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2111,10 +2131,10 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self)
|
||||
if (self->rdp_layer->client_info.bpp >
|
||||
self->rdp_layer->client_info.max_bpp)
|
||||
{
|
||||
LLOGLN(0, ("xrdp_rdp_parse_client_mcs_data: client asked "
|
||||
LOG(LOG_LEVEL_INFO, "xrdp_rdp_parse_client_mcs_data: client asked "
|
||||
"for %dbpp connection but configuration is limited "
|
||||
"to %dbpp", self->rdp_layer->client_info.bpp,
|
||||
self->rdp_layer->client_info.max_bpp));
|
||||
self->rdp_layer->client_info.max_bpp);
|
||||
self->rdp_layer->client_info.bpp =
|
||||
self->rdp_layer->client_info.max_bpp;
|
||||
}
|
||||
@ -2217,13 +2237,13 @@ xrdp_sec_init_rdp_security(struct xrdp_sec *self)
|
||||
self->crypt_level = CRYPT_LEVEL_FIPS;
|
||||
break;
|
||||
default:
|
||||
g_writeln("Fatal : Illegal crypt_level");
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "Fatal : Illegal crypt_level");
|
||||
break ;
|
||||
}
|
||||
|
||||
if (self->decrypt_rc4_info != NULL)
|
||||
{
|
||||
g_writeln("xrdp_sec_init_rdp_security: decrypt_rc4_info already created !!!");
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_init_rdp_security: decrypt_rc4_info already created !!!");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2232,7 +2252,7 @@ xrdp_sec_init_rdp_security(struct xrdp_sec *self)
|
||||
|
||||
if (self->encrypt_rc4_info != NULL)
|
||||
{
|
||||
g_writeln("xrdp_sec_init_rdp_security: encrypt_rc4_info already created !!!");
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_init_rdp_security: encrypt_rc4_info already created !!!");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2254,13 +2274,13 @@ xrdp_sec_incoming(struct xrdp_sec *self)
|
||||
char *value = NULL;
|
||||
char key_file[256];
|
||||
|
||||
DEBUG((" in xrdp_sec_incoming:"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_incoming:");
|
||||
iso = self->mcs_layer->iso_layer;
|
||||
|
||||
/* negotiate security layer */
|
||||
if (xrdp_iso_incoming(iso) != 0)
|
||||
{
|
||||
DEBUG(("xrdp_sec_incoming: xrdp_iso_incoming failed"));
|
||||
LOG(LOG_LEVEL_ERROR, "xrdp_sec_incoming: xrdp_iso_incoming failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2268,7 +2288,7 @@ xrdp_sec_incoming(struct xrdp_sec *self)
|
||||
if (iso->selectedProtocol > PROTOCOL_RDP)
|
||||
{
|
||||
/* init tls security */
|
||||
DEBUG((" in xrdp_sec_incoming: init tls security"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_incoming: init tls security");
|
||||
|
||||
if (trans_set_tls_mode(self->mcs_layer->iso_layer->trans,
|
||||
self->rdp_layer->client_info.key_file,
|
||||
@ -2276,7 +2296,7 @@ xrdp_sec_incoming(struct xrdp_sec *self)
|
||||
self->rdp_layer->client_info.ssl_protocols,
|
||||
self->rdp_layer->client_info.tls_ciphers) != 0)
|
||||
{
|
||||
g_writeln("xrdp_sec_incoming: trans_set_tls_mode failed");
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_incoming: trans_set_tls_mode failed");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2288,10 +2308,10 @@ xrdp_sec_incoming(struct xrdp_sec *self)
|
||||
else
|
||||
{
|
||||
/* init rdp security */
|
||||
DEBUG((" in xrdp_sec_incoming: init rdp security"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_incoming: init rdp security");
|
||||
if (xrdp_sec_init_rdp_security(self) != 0)
|
||||
{
|
||||
DEBUG(("xrdp_sec_incoming: xrdp_sec_init_rdp_security failed"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_incoming: xrdp_sec_init_rdp_security failed");
|
||||
return 1;
|
||||
}
|
||||
if (self->crypt_method != CRYPT_METHOD_NONE)
|
||||
@ -2307,7 +2327,7 @@ xrdp_sec_incoming(struct xrdp_sec *self)
|
||||
if (file_by_name_read_section(key_file, "keys", items, values) != 0)
|
||||
{
|
||||
/* this is a show stopper */
|
||||
log_message(LOG_LEVEL_ALWAYS, "XRDP cannot read file: %s "
|
||||
LOG(LOG_LEVEL_ALWAYS, "XRDP cannot read file: %s "
|
||||
"(check permissions)", key_file);
|
||||
list_delete(items);
|
||||
list_delete(values);
|
||||
@ -2326,7 +2346,7 @@ xrdp_sec_incoming(struct xrdp_sec *self)
|
||||
else if (g_strcasecmp(item, "pub_mod") == 0)
|
||||
{
|
||||
self->rsa_key_bytes = (g_strlen(value) + 1) / 5;
|
||||
g_writeln("pub_mod bytes %d", self->rsa_key_bytes);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "pub_mod bytes %d", self->rsa_key_bytes);
|
||||
hex_str_to_bin(value, self->pub_mod, self->rsa_key_bytes);
|
||||
}
|
||||
else if (g_strcasecmp(item, "pub_sig") == 0)
|
||||
@ -2336,16 +2356,16 @@ xrdp_sec_incoming(struct xrdp_sec *self)
|
||||
else if (g_strcasecmp(item, "pri_exp") == 0)
|
||||
{
|
||||
self->rsa_key_bytes = (g_strlen(value) + 1) / 5;
|
||||
g_writeln("pri_exp %d", self->rsa_key_bytes);
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "pri_exp %d", self->rsa_key_bytes);
|
||||
hex_str_to_bin(value, self->pri_exp, self->rsa_key_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
if (self->rsa_key_bytes <= 64)
|
||||
{
|
||||
g_writeln("warning, RSA key len 512 "
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, "warning, RSA key len 512 "
|
||||
"bits or less, consider creating a 2048 bit key");
|
||||
log_message(LOG_LEVEL_WARNING, "warning, RSA key len 512 "
|
||||
LOG(LOG_LEVEL_WARNING, "warning, RSA key len 512 "
|
||||
"bits or less, consider creating a 2048 bit key");
|
||||
}
|
||||
|
||||
@ -2360,21 +2380,17 @@ xrdp_sec_incoming(struct xrdp_sec *self)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef XRDP_DEBUG
|
||||
g_writeln("client mcs data received");
|
||||
g_hexdump(self->client_mcs_data.data,
|
||||
LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "client mcs data received", self->client_mcs_data.data,
|
||||
(int)(self->client_mcs_data.end - self->client_mcs_data.data));
|
||||
g_writeln("server mcs data sent");
|
||||
g_hexdump(self->server_mcs_data.data,
|
||||
LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "server mcs data sent", self->server_mcs_data.data,
|
||||
(int)(self->server_mcs_data.end - self->server_mcs_data.data));
|
||||
#endif
|
||||
DEBUG((" out xrdp_sec_incoming"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_incoming");
|
||||
if (xrdp_sec_in_mcs_data(self) != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
LLOGLN(10, ("xrdp_sec_incoming: out"));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_incoming: out");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2384,8 +2400,8 @@ xrdp_sec_disconnect(struct xrdp_sec *self)
|
||||
{
|
||||
int rv;
|
||||
|
||||
DEBUG((" in xrdp_sec_disconnect"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_disconnect");
|
||||
rv = xrdp_mcs_disconnect(self->mcs_layer);
|
||||
DEBUG((" out xrdp_sec_disconnect"));
|
||||
LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_disconnect");
|
||||
return rv;
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ xrdp_surface_send_surface_bits(struct xrdp_surface *self, int bpp, char *data,
|
||||
}
|
||||
else
|
||||
{
|
||||
g_writeln("bpp = %d is not supported\n", bpp);
|
||||
LOG(LOG_LEVEL_ERROR, "bpp = %d is not supported\n", bpp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
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,7 +24,9 @@
|
||||
#include "xrdp-neutrinordp.h"
|
||||
#include "xrdp-color.h"
|
||||
#include "xrdp_rail.h"
|
||||
#include "trans.h"
|
||||
#include "log.h"
|
||||
#include "string_calls.h"
|
||||
#include <freerdp/settings.h>
|
||||
|
||||
#if defined(VERSION_STRUCT_RDP_FREERDP)
|
||||
@ -39,6 +41,9 @@
|
||||
#define LOG_LEVEL 1
|
||||
#endif
|
||||
|
||||
/* Max amount of buffered output data before we stop generating more */
|
||||
#define MAX_QUEUED_MODULE_OUTPUT_DATA 50000
|
||||
|
||||
#define LLOG(_level, _args) \
|
||||
do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
|
||||
#define LLOGLN(_level, _args) \
|
||||
@ -68,6 +73,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,6 +528,17 @@ lxrdp_get_wait_objs(struct mod *mod, tbus *read_objs, int *rcount,
|
||||
boolean ok;
|
||||
|
||||
LLOGLN(12, ("lxrdp_get_wait_objs:"));
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
*rcount = 0;
|
||||
*wcount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rfds = (void **)read_objs;
|
||||
wfds = (void **)write_objs;
|
||||
ok = freerdp_get_fds(mod->inst, rfds, rcount, wfds, wcount);
|
||||
@ -525,6 +548,7 @@ lxrdp_get_wait_objs(struct mod *mod, tbus *read_objs, int *rcount,
|
||||
LLOGLN(0, ("lxrdp_get_wait_objs: freerdp_get_fds failed"));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -536,13 +560,33 @@ lxrdp_check_wait_objs(struct mod *mod)
|
||||
boolean ok;
|
||||
|
||||
LLOGLN(12, ("lxrdp_check_wait_objs:"));
|
||||
/*
|
||||
* Only process the freerdp file descriptors if our queued output data
|
||||
* has not reached the limit
|
||||
*/
|
||||
if (get_queued_module_output_data(mod) <= MAX_QUEUED_MODULE_OUTPUT_DATA)
|
||||
{
|
||||
/*
|
||||
* Before checking the file descriptors, set the source info
|
||||
* current source, so any data queued on output trans objects
|
||||
* gets attributed to this module
|
||||
*/
|
||||
if (mod->si)
|
||||
{
|
||||
mod->si->cur_source = XRDP_SOURCE_MOD;
|
||||
}
|
||||
ok = freerdp_check_fds(mod->inst);
|
||||
if (mod->si)
|
||||
{
|
||||
mod->si->cur_source = XRDP_SOURCE_NONE;
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
LLOGLN(0, ("lxrdp_check_wait_objs: freerdp_check_fds failed"));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1394,7 +1438,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 +1492,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 */
|
||||
|
||||
|
159
scripts/install_cppcheck.sh
Executable file
159
scripts/install_cppcheck.sh
Executable file
@ -0,0 +1,159 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Script to install a version of cppcheck in ~/cppcheck.local/
|
||||
#
|
||||
# Used by Travis-CI builds, until Travis supports cppcheck natively
|
||||
#
|
||||
# Currently only supports git repos as sources
|
||||
#
|
||||
# Usage: /path/to/install_cppcheck.sh <cppcheck-git-repo> <version-tag>
|
||||
|
||||
INSTALL_ROOT=~/cppcheck.local
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# U S A G E
|
||||
# ----------------------------------------------------------------------------
|
||||
usage()
|
||||
{
|
||||
echo "** Usage: $0 <git-repo URL> <version-tag>"
|
||||
echo " e.g. $0 https://github.com/danmar/cppcheck.git 1.90"
|
||||
} >&2
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# C A L L _ M A K E
|
||||
#
|
||||
# Calls make with the specified parameters, but only displays the error
|
||||
# log if it fails
|
||||
# ----------------------------------------------------------------------------
|
||||
call_make()
|
||||
{
|
||||
# Disable set -e, if active
|
||||
set_entry_opts=`set +o`
|
||||
set +e
|
||||
|
||||
status=1
|
||||
log=`mktemp /tmp/cppcheck-log.XXXXXXXXXX`
|
||||
if [ -n "$log" ]; then
|
||||
make "$@" >$log 2>&1
|
||||
status=$?
|
||||
if [ $status -ne 0 ]; then
|
||||
cat $log >&2
|
||||
fi
|
||||
rm $log
|
||||
fi
|
||||
|
||||
# Re-enable `set -e` if active before
|
||||
$set_entry_opts
|
||||
|
||||
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
|
||||
# ----------------------------------------------------------------------------
|
||||
if [ $# -ne 2 ]; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
REPO_URL="$1"
|
||||
CPPCHECK_VER="$2"
|
||||
|
||||
# Already installed?
|
||||
exe=$INSTALL_ROOT/$CPPCHECK_VER/bin/cppcheck
|
||||
if [ -x "$exe" ]; then
|
||||
echo "cppcheck version $CPPCHECK_VER is already installed at $exe" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
workdir=`mktemp -d /tmp/cppcheck.XXXXXXXXXX`
|
||||
if [ -z "$workdir" ]; then
|
||||
echo "** Unable to create temporary working directory" 2>&1
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Use a sub-process for the next bit to restrict the scope of 'set -e'
|
||||
(
|
||||
set -e ; # Exit sub-process on first error
|
||||
|
||||
# Put everything in this directory
|
||||
FILESDIR=$INSTALL_ROOT/$CPPCHECK_VER
|
||||
|
||||
# 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"
|
||||
# Check that the Z3 development files appear to be installed
|
||||
# before trying to create z3_version.h. Otherwise we may
|
||||
# mislead the user as to what needs to be done.
|
||||
if [ ! -f /usr/include/z3.h ]; then
|
||||
echo "** libz3-dev (or equivalent) does not appear to be installed" >&2
|
||||
fi
|
||||
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
|
||||
|
||||
echo "Installing cppcheck..."
|
||||
mkdir -p $FILESDIR
|
||||
call_make install $make_args
|
||||
)
|
||||
status=$?
|
||||
|
||||
if [ $status -eq 0 ]; then
|
||||
rm -rf $workdir
|
||||
else
|
||||
"** Script failed. Work dir is $workdir" >&2
|
||||
fi
|
||||
|
||||
exit $status
|
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
|
58
scripts/run_cppcheck.sh
Executable file
58
scripts/run_cppcheck.sh
Executable file
@ -0,0 +1,58 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Script to run cppcheck
|
||||
#
|
||||
# Usage: /path/to/run_cppcheck.sh [ -v CPPCHECK_VER] [<extra_opts_and_dirs>]
|
||||
#
|
||||
# - If <extra_opts_and_dirs> is missing, '.' is assumed
|
||||
# - If -v CPPCHECK_VER is specified, that version of cppcheck is run from
|
||||
# ~/cppcheck.local (whether or not it's there!). Use install_cppcheck.sh
|
||||
# to install a new version.
|
||||
#
|
||||
# Environment (all optional):-
|
||||
#
|
||||
# CPPCHECK : Override the default cppcheck command ('cppcheck').
|
||||
# Ignored if -v is specified
|
||||
# CPPCHECK_FLAGS : Override the default cppcheck flags
|
||||
|
||||
INSTALL_ROOT=~/cppcheck.local
|
||||
|
||||
# Figure out CPPCHECK setting, if any. Currently '-v' must be the first
|
||||
# argument on the command line.
|
||||
case "$1" in
|
||||
-v) # Version is separate parameter
|
||||
if [ $# -ge 2 ]; then
|
||||
CPPCHECK="$INSTALL_ROOT/$2/bin/cppcheck"
|
||||
shift 2
|
||||
else
|
||||
echo "** ignoring '-v' with no arg" >&2
|
||||
shift 1
|
||||
fi
|
||||
;;
|
||||
-v*) # Version is in same parameter
|
||||
# ${parameter#word} is not supported by classic Bourne shell,
|
||||
# but it is on bash, dash, etc. If it doesn't work on your shell,
|
||||
# don't use this form!
|
||||
CPPCHECK="$INSTALL_ROOT/${1#-v}/bin/cppcheck"
|
||||
shift 1
|
||||
esac
|
||||
if [ -z "$CPPCHECK" ]; then
|
||||
CPPCHECK=cppcheck
|
||||
fi
|
||||
|
||||
# Supply default flags passed to cppcheck if necessary
|
||||
if [ -z "$CPPCHECK_FLAGS" ]; then
|
||||
CPPCHECK_FLAGS="--quiet --force --std=c11 --std=c++11 --inline-suppr \
|
||||
--enable=warning --error-exitcode=1"
|
||||
fi
|
||||
|
||||
# Any options/directories specified?
|
||||
if [ $# -eq 0 ]; then
|
||||
set -- .
|
||||
fi
|
||||
|
||||
# Display the cppcheck version and command for debugging
|
||||
"$CPPCHECK" --version && {
|
||||
echo Command: $CPPCHECK $CPPCHECK_FLAGS "$@"
|
||||
"$CPPCHECK" $CPPCHECK_FLAGS "$@"
|
||||
}
|
@ -15,10 +15,6 @@ if XRDP_DEBUG
|
||||
AM_CPPFLAGS += -DXRDP_DEBUG
|
||||
endif
|
||||
|
||||
if SESMAN_NOPAM
|
||||
AUTH_C = verify_user.c
|
||||
AUTH_LIB = -lcrypt
|
||||
else
|
||||
if SESMAN_BSD
|
||||
AUTH_C = verify_user_bsd.c
|
||||
AUTH_LIB =
|
||||
@ -31,6 +27,10 @@ if SESMAN_KERBEROS
|
||||
AUTH_C = verify_user_kerberos.c
|
||||
AUTH_LIB = -lkrb5
|
||||
else
|
||||
if SESMAN_NOPAM
|
||||
AUTH_C = verify_user.c
|
||||
AUTH_LIB = -lcrypt
|
||||
else
|
||||
AUTH_C = verify_user_pam.c
|
||||
AUTH_LIB = -lpam
|
||||
endif
|
||||
|
@ -29,6 +29,7 @@
|
||||
#endif
|
||||
|
||||
#include "sesman.h"
|
||||
#include "string_calls.h"
|
||||
|
||||
extern struct config_sesman *g_cfg; /* in sesman.c */
|
||||
|
||||
@ -41,33 +42,32 @@ access_login_allowed(const char *user)
|
||||
|
||||
if ((0 == g_strncmp(user, "root", 5)) && (0 == g_cfg->sec.allow_root))
|
||||
{
|
||||
log_message(LOG_LEVEL_WARNING,
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"ROOT login attempted, but root login is disabled");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((0 == g_cfg->sec.ts_users_enable) && (0==g_cfg->sec.ts_always_group_check))
|
||||
if ((0 == g_cfg->sec.ts_users_enable) && (0 == g_cfg->sec.ts_always_group_check))
|
||||
{
|
||||
LOG_DBG("Terminal Server Users group is disabled, allowing authentication",
|
||||
1);
|
||||
LOG(LOG_LEVEL_INFO, "Terminal Server Users group is disabled, allowing authentication");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != g_getuser_info(user, &gid, 0, 0, 0, 0))
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR, "Cannot read user info! - login denied");
|
||||
LOG(LOG_LEVEL_ERROR, "Cannot read user info! - login denied");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (g_cfg->sec.ts_users == gid)
|
||||
{
|
||||
log_message(LOG_LEVEL_DEBUG,"ts_users is user's primary group");
|
||||
LOG(LOG_LEVEL_DEBUG, "ts_users is user's primary group");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != g_check_user_in_group(user, g_cfg->sec.ts_users, &ok))
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR, "Cannot read group info! - login denied");
|
||||
LOG(LOG_LEVEL_ERROR, "Cannot read group info! - login denied");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ 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 +90,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,
|
||||
LOG(LOG_LEVEL_WARNING,
|
||||
"[MNG] ROOT login attempted, but root login is disabled");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (0 == g_cfg->sec.ts_admins_enable)
|
||||
{
|
||||
LOG_DBG("[MNG] Terminal Server Admin group is disabled, "
|
||||
"allowing authentication", 1);
|
||||
LOG(LOG_LEVEL_INFO, "[MNG] Terminal Server Admin group is disabled, "
|
||||
"allowing authentication");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != g_getuser_info(user, &gid, 0, 0, 0, 0))
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR, "[MNG] Cannot read user info! - login denied");
|
||||
LOG(LOG_LEVEL_ERROR, "[MNG] Cannot read user info! - login denied");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (g_cfg->sec.ts_admins == gid)
|
||||
{
|
||||
LOG_DBG("[MNG] ts_users is user's primary group");
|
||||
LOG(LOG_LEVEL_INFO, "[MNG] ts_users is user's primary group");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (0 != g_check_user_in_group(user, g_cfg->sec.ts_admins, &ok))
|
||||
{
|
||||
log_message(LOG_LEVEL_ERROR, "[MNG] Cannot read group info! - login denied");
|
||||
LOG(LOG_LEVEL_ERROR, "[MNG] Cannot read group info! - login denied");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -125,7 +125,7 @@ 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;
|
||||
}
|
||||
|
@ -37,6 +37,10 @@ AM_CPPFLAGS += -DXRDP_MP3LAME
|
||||
CHANSRV_EXTRA_LIBS += -lmp3lame
|
||||
endif
|
||||
|
||||
if XRDP_RDPSNDAUDIN
|
||||
AM_CPPFLAGS += -DXRDP_RDPSNDAUDIN
|
||||
endif
|
||||
|
||||
AM_CFLAGS = $(X_CFLAGS)
|
||||
|
||||
sbin_PROGRAMS = \
|
||||
@ -47,8 +51,12 @@ 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 \
|
||||
chansrv_xfs.h \
|
||||
clipboard.c \
|
||||
clipboard.h \
|
||||
clipboard_common.h \
|
||||
@ -60,7 +68,6 @@ xrdp_chansrv_SOURCES = \
|
||||
fifo.h \
|
||||
irp.c \
|
||||
irp.h \
|
||||
mlog.h \
|
||||
rail.c \
|
||||
rail.h \
|
||||
smartcard.c \
|
||||
@ -70,7 +77,9 @@ xrdp_chansrv_SOURCES = \
|
||||
sound.c \
|
||||
sound.h \
|
||||
xcommon.c \
|
||||
xcommon.h
|
||||
xcommon.h \
|
||||
audin.c \
|
||||
audin.h
|
||||
|
||||
xrdp_chansrv_LDFLAGS = \
|
||||
$(X_LIBS)
|
||||
|
516
sesman/chansrv/audin.c
Normal file
516
sesman/chansrv/audin.c
Normal file
@ -0,0 +1,516 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Copyright (C) Jay Sorg 2019
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* MS-RDPEAI
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include <config_ac.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "os_calls.h"
|
||||
#include "chansrv.h"
|
||||
#include "log.h"
|
||||
#include "xrdp_constants.h"
|
||||
#include "fifo.h"
|
||||
|
||||
#define MSG_SNDIN_VERSION 1
|
||||
#define MSG_SNDIN_FORMATS 2
|
||||
#define MSG_SNDIN_OPEN 3
|
||||
#define MSG_SNDIN_OPEN_REPLY 4
|
||||
#define MSG_SNDIN_DATA_INCOMING 5
|
||||
#define MSG_SNDIN_DATA 6
|
||||
#define MSG_SNDIN_FORMATCHANGE 7
|
||||
|
||||
#define AUDIN_VERSION 0x00000001
|
||||
|
||||
#define AUDIN_NAME "AUDIO_INPUT"
|
||||
#define AUDIN_FLAGS 1 /* WTS_CHANNEL_OPTION_DYNAMIC */
|
||||
|
||||
extern FIFO g_in_fifo; /* in sound.c */
|
||||
extern int g_bytes_in_fifo; /* in sound.c */
|
||||
|
||||
struct xr_wave_format_ex
|
||||
{
|
||||
int wFormatTag;
|
||||
int nChannels;
|
||||
int nSamplesPerSec;
|
||||
int nAvgBytesPerSec;
|
||||
int nBlockAlign;
|
||||
int wBitsPerSample;
|
||||
int cbSize;
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
static uint8_t g_pcm_44100_data[] = { 0 };
|
||||
static struct xr_wave_format_ex g_pcm_44100 =
|
||||
{
|
||||
WAVE_FORMAT_PCM, /* wFormatTag */
|
||||
2, /* num of channels */
|
||||
44100, /* samples per sec */
|
||||
176400, /* avg bytes per sec */
|
||||
4, /* block align */
|
||||
16, /* bits per sample */
|
||||
0, /* data size */
|
||||
g_pcm_44100_data /* data */
|
||||
};
|
||||
|
||||
static struct chansrv_drdynvc_procs g_audin_info;
|
||||
static int g_audin_chanid;
|
||||
static struct stream *g_in_s;
|
||||
|
||||
static struct xr_wave_format_ex *g_server_formats[] =
|
||||
{
|
||||
&g_pcm_44100,
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct xr_wave_format_ex **g_client_formats = NULL;
|
||||
|
||||
static int g_current_format = 0; /* index in g_client_formats */
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
cleanup_client_formats(void)
|
||||
{
|
||||
int index;
|
||||
|
||||
if (g_client_formats == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
index = 0;
|
||||
while (g_client_formats[index] != NULL)
|
||||
{
|
||||
g_free(g_client_formats[index]->data);
|
||||
g_free(g_client_formats[index]);
|
||||
index++;
|
||||
}
|
||||
g_free(g_client_formats);
|
||||
g_client_formats = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
audin_send_version(int chan_id)
|
||||
{
|
||||
int error;
|
||||
int bytes;
|
||||
struct stream *s;
|
||||
|
||||
LOG_DEVEL(LOG_LEVEL_INFO, "audin_send_version:");
|
||||
make_stream(s);
|
||||
init_stream(s, 32);
|
||||
out_uint8(s, MSG_SNDIN_VERSION);
|
||||
out_uint32_le(s, AUDIN_VERSION);
|
||||
s_mark_end(s);
|
||||
bytes = (int) (s->end - s->data);
|
||||
error = chansrv_drdynvc_data(chan_id, s->data, bytes);
|
||||
free_stream(s);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
audin_send_formats(int chan_id)
|
||||
{
|
||||
int error;
|
||||
int bytes;
|
||||
int num_formats;
|
||||
int index;
|
||||
struct stream *s;
|
||||
struct xr_wave_format_ex *wf;
|
||||
|
||||
LOG_DEVEL(LOG_LEVEL_INFO, "audin_send_formats:");
|
||||
num_formats = sizeof(g_server_formats) /
|
||||
sizeof(g_server_formats[0]) - 1;
|
||||
make_stream(s);
|
||||
init_stream(s, 8192 * num_formats);
|
||||
out_uint8(s, MSG_SNDIN_FORMATS);
|
||||
out_uint32_le(s, num_formats);
|
||||
out_uint32_le(s, 0); /* cbSizeFormatsPacket */
|
||||
for (index = 0; index < num_formats; index++)
|
||||
{
|
||||
wf = g_server_formats[index];
|
||||
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);
|
||||
out_uint32_le(s, wf->nAvgBytesPerSec);
|
||||
out_uint16_le(s, wf->nBlockAlign);
|
||||
out_uint16_le(s, wf->wBitsPerSample);
|
||||
out_uint16_le(s, wf->cbSize);
|
||||
if (wf->cbSize > 0)
|
||||
{
|
||||
out_uint8p(s, wf->data, wf->cbSize);
|
||||
}
|
||||
}
|
||||
s_mark_end(s);
|
||||
bytes = (int) (s->end - s->data);
|
||||
error = chansrv_drdynvc_data(chan_id, s->data, bytes);
|
||||
free_stream(s);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
audin_send_open(int chan_id)
|
||||
{
|
||||
int error;
|
||||
int bytes;
|
||||
struct stream *s;
|
||||
struct xr_wave_format_ex *wf;
|
||||
|
||||
LOG_DEVEL(LOG_LEVEL_INFO, "audin_send_open:");
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
out_uint8(s, MSG_SNDIN_OPEN);
|
||||
out_uint32_le(s, 2048); /* FramesPerPacket */
|
||||
out_uint32_le(s, g_current_format); /* initialFormat */
|
||||
wf = g_client_formats[g_current_format];
|
||||
out_uint16_le(s, wf->wFormatTag);
|
||||
out_uint16_le(s, wf->nChannels);
|
||||
out_uint32_le(s, wf->nSamplesPerSec);
|
||||
out_uint32_le(s, wf->nAvgBytesPerSec);
|
||||
out_uint16_le(s, wf->nBlockAlign);
|
||||
out_uint16_le(s, wf->wBitsPerSample);
|
||||
bytes = wf->cbSize;
|
||||
out_uint16_le(s, bytes);
|
||||
if (bytes > 0)
|
||||
{
|
||||
out_uint8p(s, wf->data, bytes);
|
||||
}
|
||||
s_mark_end(s);
|
||||
bytes = (int) (s->end - s->data);
|
||||
error = chansrv_drdynvc_data(chan_id, s->data, bytes);
|
||||
free_stream(s);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
audin_process_version(int chan_id, struct stream *s)
|
||||
{
|
||||
int version;
|
||||
|
||||
LOG_DEVEL(LOG_LEVEL_INFO, "audin_process_version:");
|
||||
if (!s_check_rem(s, 4))
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_version: parse error");
|
||||
return 1;
|
||||
}
|
||||
in_uint32_le(s, version);
|
||||
LOG(LOG_LEVEL_INFO, "audin_process_version: version %d", version);
|
||||
return audin_send_formats(chan_id);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
audin_process_formats(int chan_id, struct stream *s)
|
||||
{
|
||||
int index;
|
||||
int num_formats;
|
||||
struct xr_wave_format_ex *wf;
|
||||
|
||||
LOG_DEVEL(LOG_LEVEL_INFO, "audin_process_formats:");
|
||||
cleanup_client_formats();
|
||||
if (!s_check_rem(s, 8))
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_formats: parse error");
|
||||
return 1;
|
||||
}
|
||||
in_uint32_le(s, num_formats);
|
||||
in_uint8s(s, 4); /* cbSizeFormatsPacket */
|
||||
g_client_formats = g_new0(struct xr_wave_format_ex *, num_formats + 1);
|
||||
for (index = 0; index < num_formats; index++)
|
||||
{
|
||||
if (!s_check_rem(s, 18))
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_formats: parse error");
|
||||
return 1;
|
||||
}
|
||||
wf = g_new0(struct xr_wave_format_ex, 1);
|
||||
g_client_formats[index] = wf;
|
||||
in_uint16_le(s, wf->wFormatTag);
|
||||
in_uint16_le(s, wf->nChannels);
|
||||
in_uint32_le(s, wf->nSamplesPerSec);
|
||||
in_uint32_le(s, wf->nAvgBytesPerSec);
|
||||
in_uint16_le(s, wf->nBlockAlign);
|
||||
in_uint16_le(s, wf->wBitsPerSample);
|
||||
in_uint16_le(s, wf->cbSize);
|
||||
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_DEVEL(LOG_LEVEL_ERROR, "audin_process_formats: parse error");
|
||||
return 1;
|
||||
}
|
||||
wf->data = g_new0(uint8_t, wf->cbSize);
|
||||
in_uint8a(s, wf->data, wf->cbSize);
|
||||
}
|
||||
}
|
||||
audin_send_open(chan_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
audin_process_open_reply(int chan_id, struct stream *s)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (!s_check_rem(s, 4))
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_open_reply: parse error");
|
||||
return 1;
|
||||
}
|
||||
in_uint32_le(s, result);
|
||||
LOG(LOG_LEVEL_INFO, "audin_process_open_reply: result 0x%8.8x", result);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
audin_process_incoming_data(int chan_id, struct stream *s)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "audin_process_incoming_data:");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
audin_process_data(int chan_id, struct stream *s)
|
||||
{
|
||||
int data_bytes;
|
||||
struct stream *ls;
|
||||
|
||||
data_bytes = (int) (s->end - s->p);
|
||||
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);
|
||||
ls->p += data_bytes;
|
||||
s_mark_end(ls);
|
||||
fifo_insert(&g_in_fifo, (void *) ls);
|
||||
g_bytes_in_fifo += data_bytes;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
audin_process_format_change(int chan_id, struct stream *s)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_INFO, "audin_process_format_change:");
|
||||
if (!s_check_rem(s, 4))
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_format_change: parse error");
|
||||
return 1;
|
||||
}
|
||||
in_uint32_le(s, g_current_format);
|
||||
LOG_DEVEL(LOG_LEVEL_INFO, "audin_process_format_change: g_current_format %d",
|
||||
g_current_format);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
audin_process_msg(int chan_id, struct stream *s)
|
||||
{
|
||||
int code;
|
||||
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "audin_process_msg:");
|
||||
if (!s_check_rem(s, 1))
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_msg: parse error");
|
||||
return 1;
|
||||
}
|
||||
in_uint8(s, code);
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "audin_process_msg: code %d", code);
|
||||
switch (code)
|
||||
{
|
||||
case MSG_SNDIN_VERSION:
|
||||
return audin_process_version(chan_id, s);
|
||||
case MSG_SNDIN_FORMATS:
|
||||
return audin_process_formats(chan_id, s);
|
||||
case MSG_SNDIN_OPEN_REPLY:
|
||||
return audin_process_open_reply(chan_id, s);
|
||||
case MSG_SNDIN_DATA_INCOMING:
|
||||
return audin_process_incoming_data(chan_id, s);
|
||||
case MSG_SNDIN_DATA:
|
||||
return audin_process_data(chan_id, s);
|
||||
case MSG_SNDIN_FORMATCHANGE:
|
||||
return audin_process_format_change(chan_id, s);
|
||||
default:
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_msg: unprocessed code %d", code);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
audin_open_response(int chan_id, int 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);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
audin_close_response(int chan_id)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_INFO, "audin_close_response:");
|
||||
g_audin_chanid = 0;
|
||||
cleanup_client_formats();
|
||||
free_stream(g_in_s);
|
||||
g_in_s = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
audin_data_fragment(int chan_id, char *data, int bytes)
|
||||
{
|
||||
int rv;
|
||||
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "audin_data_fragment:");
|
||||
if (!s_check_rem(g_in_s, bytes))
|
||||
{
|
||||
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);
|
||||
if (g_in_s->p == g_in_s->end)
|
||||
{
|
||||
g_in_s->p = g_in_s->data;
|
||||
rv = audin_process_msg(chan_id, g_in_s);
|
||||
free_stream(g_in_s);
|
||||
g_in_s = NULL;
|
||||
return rv;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
audin_data_first(int chan_id, char *data, int bytes, int total_bytes)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "audin_data_first:");
|
||||
if (g_in_s != NULL)
|
||||
{
|
||||
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);
|
||||
init_stream(g_in_s, total_bytes);
|
||||
g_in_s->end = g_in_s->data + total_bytes;
|
||||
return audin_data_fragment(chan_id, data, bytes);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
audin_data(int chan_id, char *data, int bytes)
|
||||
{
|
||||
struct stream ls;
|
||||
|
||||
LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "audin_data:", data, bytes);
|
||||
if (g_in_s == NULL)
|
||||
{
|
||||
g_memset(&ls, 0, sizeof(ls));
|
||||
ls.data = data;
|
||||
ls.p = ls.data;
|
||||
ls.end = ls.p + bytes;
|
||||
return audin_process_msg(chan_id, &ls);
|
||||
}
|
||||
return audin_data_fragment(chan_id, data, bytes);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
audin_init(void)
|
||||
{
|
||||
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;
|
||||
g_audin_info.data_first = audin_data_first;
|
||||
g_audin_info.data = audin_data;
|
||||
g_audin_chanid = 0;
|
||||
g_in_s = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
audin_deinit(void)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_INFO, "audin_deinit:");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
audin_start(void)
|
||||
{
|
||||
int error;
|
||||
struct stream *s;
|
||||
|
||||
LOG_DEVEL(LOG_LEVEL_INFO, "audin_start:");
|
||||
if (g_audin_chanid != 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* if there is any data in FIFO, discard it */
|
||||
while ((s = (struct stream *) fifo_remove(&g_in_fifo)) != NULL)
|
||||
{
|
||||
xstream_free(s);
|
||||
}
|
||||
g_bytes_in_fifo = 0;
|
||||
|
||||
error = chansrv_drdynvc_open(AUDIN_NAME, AUDIN_FLAGS,
|
||||
&g_audin_info, /* callback functions */
|
||||
&g_audin_chanid); /* chansrv chan_id */
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR, "audin_start: error %d g_audin_chanid %d", error, g_audin_chanid);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
int
|
||||
audin_stop(void)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_INFO, "audin_stop:");
|
||||
chansrv_drdynvc_close(g_audin_chanid);
|
||||
return 0;
|
||||
}
|
34
sesman/chansrv/audin.h
Normal file
34
sesman/chansrv/audin.h
Normal file
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Copyright (C) Jay Sorg 2019
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* MS-RDPEAI
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _AUDIN_H_
|
||||
#define _AUDIN_H_
|
||||
|
||||
int
|
||||
audin_init(void);
|
||||
int
|
||||
audin_deinit(void);
|
||||
int
|
||||
audin_start(void);
|
||||
int
|
||||
audin_stop(void);
|
||||
|
||||
#endif
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "arch.h"
|
||||
#include "os_calls.h"
|
||||
#include "string_calls.h"
|
||||
#include "thread_calls.h"
|
||||
#include "trans.h"
|
||||
#include "chansrv.h"
|
||||
@ -36,7 +37,13 @@
|
||||
#include "rail.h"
|
||||
#include "xcommon.h"
|
||||
#include "chansrv_fuse.h"
|
||||
#include "chansrv_config.h"
|
||||
#include "xrdp_sockets.h"
|
||||
#include "audin.h"
|
||||
|
||||
#include "ms-rdpbcgr.h"
|
||||
|
||||
#define MAX_PATH 260
|
||||
|
||||
static struct trans *g_lis_trans = 0;
|
||||
static struct trans *g_con_trans = 0;
|
||||
@ -52,17 +59,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;
|
||||
@ -117,7 +123,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;
|
||||
@ -144,7 +150,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)
|
||||
{
|
||||
@ -156,7 +162,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;
|
||||
@ -166,7 +172,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;
|
||||
@ -192,7 +198,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)
|
||||
@ -232,7 +238,7 @@ check_timeout(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG(10, (" count %d", count));
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, " count %d", count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -303,11 +309,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);
|
||||
@ -344,10 +350,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++)
|
||||
{
|
||||
@ -356,10 +362,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)
|
||||
@ -385,7 +388,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++;
|
||||
@ -406,7 +409,7 @@ process_message_channel_setup(struct stream *s)
|
||||
|
||||
if (g_rdpdr_index >= 0)
|
||||
{
|
||||
dev_redir_init();
|
||||
devredir_init();
|
||||
xfuse_init();
|
||||
}
|
||||
|
||||
@ -415,6 +418,8 @@ process_message_channel_setup(struct stream *s)
|
||||
rail_init();
|
||||
}
|
||||
|
||||
audin_init();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -438,9 +443,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)
|
||||
@ -455,7 +459,7 @@ process_message_channel_data(struct stream *s)
|
||||
}
|
||||
else if (chan_id == g_rdpdr_chan_id)
|
||||
{
|
||||
rv = dev_redir_data_in(s, chan_id, chan_flags, length, total_length);
|
||||
rv = devredir_data_in(s, chan_id, chan_flags, length, total_length);
|
||||
}
|
||||
else if (chan_id == g_rail_chan_id)
|
||||
{
|
||||
@ -493,7 +497,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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -511,7 +515,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;
|
||||
@ -525,7 +529,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)
|
||||
@ -555,7 +559,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;
|
||||
@ -568,7 +572,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;
|
||||
@ -594,7 +598,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;
|
||||
@ -633,7 +637,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;
|
||||
@ -740,7 +744,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)
|
||||
@ -767,7 +771,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)
|
||||
{
|
||||
@ -791,7 +795,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)
|
||||
@ -867,7 +871,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;
|
||||
}
|
||||
|
||||
@ -902,7 +906,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);
|
||||
@ -1039,11 +1043,15 @@ my_api_trans_data_in(struct trans *trans)
|
||||
int rv;
|
||||
int bytes;
|
||||
int ver;
|
||||
int channel_name_bytes;
|
||||
struct chansrv_drdynvc_procs procs;
|
||||
char *chan_name;
|
||||
/*
|
||||
* Name is limited to CHANNEL_NAME_LEN for an SVC, or MAX_PATH
|
||||
* bytes for a DVC
|
||||
*/
|
||||
char chan_name[MAX(CHANNEL_NAME_LEN, MAX_PATH) + 1];
|
||||
unsigned int channel_name_bytes;
|
||||
|
||||
//g_writeln("my_api_trans_data_in: extra_flags %d", trans->extra_flags);
|
||||
//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);
|
||||
@ -1051,7 +1059,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;
|
||||
@ -1063,15 +1071,16 @@ my_api_trans_data_in(struct trans *trans)
|
||||
{
|
||||
rv = 1;
|
||||
in_uint32_le(s, channel_name_bytes);
|
||||
//g_writeln("my_api_trans_data_in: channel_name_bytes %d", channel_name_bytes);
|
||||
chan_name = g_new0(char, channel_name_bytes + 1);
|
||||
if (chan_name == NULL)
|
||||
//LOG_DEVEL(LOG_LEVEL_DEBUG, "my_api_trans_data_in: channel_name_bytes %d", channel_name_bytes);
|
||||
if (channel_name_bytes > (sizeof(chan_name) - 1))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
in_uint8a(s, chan_name, channel_name_bytes);
|
||||
chan_name[channel_name_bytes] = '\0';
|
||||
|
||||
in_uint32_le(s, ad->chan_flags);
|
||||
//g_writeln("my_api_trans_data_in: chan_name %s chan_flags 0x%8.8x", chan_name, ad->chan_flags);
|
||||
//LOG_DEVEL(LOG_LEVEL_DEBUG, "my_api_trans_data_in: chan_name %s chan_flags 0x%8.8x", chan_name, ad->chan_flags);
|
||||
if (ad->chan_flags == 0)
|
||||
{
|
||||
/* SVC */
|
||||
@ -1125,11 +1134,10 @@ 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;
|
||||
}
|
||||
g_free(chan_name);
|
||||
init_stream(s, 0);
|
||||
trans->extra_flags = 2;
|
||||
trans->header_size = 0;
|
||||
@ -1139,7 +1147,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)
|
||||
@ -1150,7 +1158,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);
|
||||
@ -1182,7 +1190,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;
|
||||
@ -1201,10 +1209,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;
|
||||
@ -1213,7 +1221,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;
|
||||
@ -1233,7 +1241,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;
|
||||
@ -1251,8 +1259,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;
|
||||
}
|
||||
|
||||
@ -1274,8 +1282,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;
|
||||
}
|
||||
|
||||
@ -1384,7 +1392,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();
|
||||
@ -1406,10 +1414,10 @@ 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();
|
||||
dev_redir_deinit();
|
||||
devredir_deinit();
|
||||
rail_deinit();
|
||||
break;
|
||||
}
|
||||
@ -1418,8 +1426,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");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1427,11 +1435,11 @@ 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();
|
||||
dev_redir_deinit();
|
||||
devredir_deinit();
|
||||
rail_deinit();
|
||||
/* delete g_con_trans */
|
||||
trans_delete(g_con_trans);
|
||||
@ -1450,14 +1458,14 @@ 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 */
|
||||
api_con_trans_list_check_wait_objs();
|
||||
xcommon_check_wait_objs();
|
||||
sound_check_wait_objs();
|
||||
dev_redir_check_wait_objs();
|
||||
devredir_check_wait_objs();
|
||||
xfuse_check_wait_objs();
|
||||
timeout = -1;
|
||||
num_objs = 0;
|
||||
@ -1476,7 +1484,7 @@ channel_thread_loop(void *in_val)
|
||||
&timeout);
|
||||
xcommon_get_wait_objs(objs, &num_objs, &timeout);
|
||||
sound_get_wait_objs(objs, &num_objs, &timeout);
|
||||
dev_redir_get_wait_objs(objs, &num_objs, &timeout);
|
||||
devredir_get_wait_objs(objs, &num_objs, &timeout);
|
||||
xfuse_get_wait_objs(objs, &num_objs, &timeout);
|
||||
get_timeout(&timeout);
|
||||
} /* end while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0) */
|
||||
@ -1490,7 +1498,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;
|
||||
}
|
||||
@ -1499,7 +1507,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);
|
||||
}
|
||||
|
||||
@ -1507,7 +1515,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);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -1516,14 +1524,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();
|
||||
}
|
||||
}
|
||||
@ -1534,7 +1542,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);
|
||||
}
|
||||
@ -1543,7 +1551,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);
|
||||
@ -1612,60 +1620,31 @@ get_display_num_from_display(char *display_text)
|
||||
int
|
||||
main_cleanup(void)
|
||||
{
|
||||
if (g_term_event != 0)
|
||||
{
|
||||
g_delete_wait_obj(g_term_event);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list_delete(names);
|
||||
list_delete(values);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
static int
|
||||
get_log_path(char *path, int bytes)
|
||||
{
|
||||
char* log_path;
|
||||
char *log_path;
|
||||
int rv;
|
||||
|
||||
rv = 1;
|
||||
@ -1713,41 +1692,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)
|
||||
@ -1775,60 +1726,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)
|
||||
{
|
||||
@ -1846,11 +1796,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_INFO, "main: app started pid %d(0x%8.8x)", pid, pid);
|
||||
/* set up signal handler */
|
||||
g_signal_terminate(term_signal_handler); /* SIGTERM */
|
||||
g_signal_user_interrupt(term_signal_handler); /* SIGINT */
|
||||
@ -1861,16 +1811,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);
|
||||
@ -1888,7 +1838,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;
|
||||
}
|
||||
|
||||
@ -1909,15 +1859,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)
|
||||
|
304
sesman/chansrv/chansrv_config.c
Normal file
304
sesman/chansrv/chansrv_config.c
Normal file
@ -0,0 +1,304 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file implements the interface in chansrv_config.h
|
||||
*/
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include <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"
|
||||
#include "string_calls.h"
|
||||
|
||||
/* Default settings */
|
||||
#define DEFAULT_USE_UNIX_SOCKET 0
|
||||
#define DEFAULT_RESTRICT_OUTBOUND_CLIPBOARD 0
|
||||
#define DEFAULT_ENABLE_FUSE_MOUNT 1
|
||||
#define DEFAULT_FUSE_MOUNT_NAME "xrdp-client"
|
||||
#define DEFAULT_FILE_UMASK 077
|
||||
|
||||
/**
|
||||
* Type used for passing a logging function about
|
||||
*/
|
||||
typedef
|
||||
printflike(2, 3)
|
||||
enum logReturns (*log_func_t)(const enum logLevels lvl,
|
||||
const char *msg, ...);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Error logging function to use to log to stdout
|
||||
*
|
||||
* Has the same signature as the log_message() function
|
||||
*/
|
||||
static enum logReturns
|
||||
log_to_stdout(const enum logLevels lvl, const char *msg, ...)
|
||||
{
|
||||
char buff[256];
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, msg);
|
||||
vsnprintf(buff, sizeof(buff), msg, ap);
|
||||
va_end(ap);
|
||||
g_writeln("%s", buff);
|
||||
|
||||
return LOG_STARTUP_OK;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Reads the config values we need from the [Globals] section
|
||||
*
|
||||
* @param logmsg Function to use to log messages
|
||||
* @param names List of definitions in the section
|
||||
* @params values List of corresponding values for the names
|
||||
* @params cfg Pointer to structure we're filling in
|
||||
*
|
||||
* @return 0 for success
|
||||
*/
|
||||
static int
|
||||
read_config_globals(log_func_t logmsg,
|
||||
struct list *names, struct list *values,
|
||||
struct config_chansrv *cfg)
|
||||
{
|
||||
int error = 0;
|
||||
int index;
|
||||
|
||||
for (index = 0; index < names->count; ++index)
|
||||
{
|
||||
const char *name = (const char *)list_get_item(names, index);
|
||||
const char *value = (const char *)list_get_item(values, index);
|
||||
|
||||
if (g_strcasecmp(name, "ListenAddress") == 0)
|
||||
{
|
||||
if (g_strcasecmp(value, "127.0.0.1") == 0)
|
||||
{
|
||||
cfg->use_unix_socket = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Reads the config values we need from the [Security] section
|
||||
*
|
||||
* @param logmsg Function to use to log messages
|
||||
* @param names List of definitions in the section
|
||||
* @params values List of corresponding values for the names
|
||||
* @params cfg Pointer to structure we're filling in
|
||||
*
|
||||
* @return 0 for success
|
||||
*/
|
||||
static int
|
||||
read_config_security(log_func_t logmsg,
|
||||
struct list *names, struct list *values,
|
||||
struct config_chansrv *cfg)
|
||||
{
|
||||
int error = 0;
|
||||
int index;
|
||||
|
||||
for (index = 0; index < names->count; ++index)
|
||||
{
|
||||
const char *name = (const char *)list_get_item(names, index);
|
||||
const char *value = (const char *)list_get_item(values, index);
|
||||
|
||||
if (g_strcasecmp(name, "RestrictOutboundClipboard") == 0)
|
||||
{
|
||||
cfg->restrict_outbound_clipboard = g_text2bool(value);
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* Reads the config values we need from the [Chansrv] section
|
||||
*
|
||||
* @param logmsg Function to use to log messages
|
||||
* @param names List of definitions in the section
|
||||
* @params values List of corresponding values for the names
|
||||
* @params cfg Pointer to structure we're filling in
|
||||
*
|
||||
* @return 0 for success
|
||||
*/
|
||||
static int
|
||||
read_config_chansrv(log_func_t logmsg,
|
||||
struct list *names, struct list *values,
|
||||
struct config_chansrv *cfg)
|
||||
{
|
||||
int error = 0;
|
||||
int index;
|
||||
|
||||
for (index = 0; index < names->count; ++index)
|
||||
{
|
||||
const char *name = (const char *)list_get_item(names, index);
|
||||
const char *value = (const char *)list_get_item(values, index);
|
||||
|
||||
if (g_strcasecmp(name, "EnableFuseMount") == 0)
|
||||
{
|
||||
cfg->enable_fuse_mount = g_text2bool(value);
|
||||
}
|
||||
if (g_strcasecmp(name, "FuseMountName") == 0)
|
||||
{
|
||||
g_free(cfg->fuse_mount_name);
|
||||
cfg->fuse_mount_name = g_strdup(value);
|
||||
if (cfg->fuse_mount_name == NULL)
|
||||
{
|
||||
logmsg(LOG_LEVEL_ERROR, "Can't alloc FuseMountName");
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (g_strcasecmp(name, "FileUmask") == 0)
|
||||
{
|
||||
cfg->file_umask = strtol(value, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief returns a config block with default values
|
||||
*
|
||||
* @return Block, or NULL for no memory
|
||||
*/
|
||||
static struct config_chansrv *
|
||||
new_config(void)
|
||||
{
|
||||
/* Do all the allocations at the beginning, then check them together */
|
||||
struct config_chansrv *cfg = g_new0(struct config_chansrv, 1);
|
||||
char *fuse_mount_name = g_strdup(DEFAULT_FUSE_MOUNT_NAME);
|
||||
if (cfg == NULL || fuse_mount_name == NULL)
|
||||
{
|
||||
/* At least one memory allocation failed */
|
||||
g_free(fuse_mount_name);
|
||||
g_free(cfg);
|
||||
cfg = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
cfg->use_unix_socket = DEFAULT_USE_UNIX_SOCKET;
|
||||
cfg->enable_fuse_mount = DEFAULT_ENABLE_FUSE_MOUNT;
|
||||
cfg->restrict_outbound_clipboard = DEFAULT_RESTRICT_OUTBOUND_CLIPBOARD;
|
||||
cfg->fuse_mount_name = fuse_mount_name;
|
||||
cfg->file_umask = DEFAULT_FILE_UMASK;
|
||||
}
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
struct config_chansrv *
|
||||
config_read(int use_logger, const char *sesman_ini)
|
||||
{
|
||||
int error = 0;
|
||||
struct config_chansrv *cfg = NULL;
|
||||
log_func_t logmsg = (use_logger) ? log_message : log_to_stdout;
|
||||
int fd;
|
||||
|
||||
fd = g_file_open_ex(sesman_ini, 1, 0, 0, 0);
|
||||
if (fd < 0)
|
||||
{
|
||||
logmsg(LOG_LEVEL_ERROR, "Can't open config file %s", sesman_ini);
|
||||
error = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((cfg = new_config()) == NULL)
|
||||
{
|
||||
logmsg(LOG_LEVEL_ERROR, "Can't alloc config block");
|
||||
error = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct list *names = list_create();
|
||||
struct list *values = list_create();
|
||||
|
||||
names->auto_free = 1;
|
||||
values->auto_free = 1;
|
||||
|
||||
if (!error && file_read_section(fd, "Globals", names, values) == 0)
|
||||
{
|
||||
error = read_config_globals(logmsg, names, values, cfg);
|
||||
}
|
||||
|
||||
|
||||
if (!error && file_read_section(fd, "Security", names, values) == 0)
|
||||
{
|
||||
error = read_config_security(logmsg, names, values, cfg);
|
||||
}
|
||||
|
||||
if (!error && file_read_section(fd, "Chansrv", names, values) == 0)
|
||||
{
|
||||
error = read_config_chansrv(logmsg, names, values, cfg);
|
||||
}
|
||||
|
||||
list_delete(names);
|
||||
list_delete(values);
|
||||
}
|
||||
|
||||
g_file_close(fd);
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
config_free(cfg);
|
||||
cfg = NULL;
|
||||
}
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void
|
||||
config_dump(struct config_chansrv *config)
|
||||
{
|
||||
g_writeln("Global configuration:");
|
||||
g_writeln(" UseUnixSocket (derived): %s",
|
||||
g_bool2text(config->use_unix_socket));
|
||||
|
||||
g_writeln("\nSecurity configuration:");
|
||||
g_writeln(" RestrictOutboundClipboard: %s",
|
||||
g_bool2text(config->restrict_outbound_clipboard));
|
||||
|
||||
g_writeln("\nChansrv configuration:");
|
||||
g_writeln(" EnableFuseMount %s",
|
||||
g_bool2text(config->enable_fuse_mount));
|
||||
g_writeln(" FuseMountName: %s", config->fuse_mount_name);
|
||||
g_writeln(" FileMask: 0%o", config->file_umask);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void
|
||||
config_free(struct config_chansrv *cc)
|
||||
{
|
||||
if (cc != NULL)
|
||||
{
|
||||
g_free(cc->fuse_mount_name);
|
||||
g_free(cc);
|
||||
}
|
||||
}
|
75
sesman/chansrv/chansrv_config.h
Normal file
75
sesman/chansrv/chansrv_config.h
Normal file
@ -0,0 +1,75 @@
|
||||
/**
|
||||
* xrdp: A Remote Desktop Protocol server.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* This file contains the chansrv configuration parameters from sesman.ini
|
||||
*/
|
||||
|
||||
#ifndef _CHANSRV_CONFIG
|
||||
#define _CHANSRV_CONFIG
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
struct config_chansrv
|
||||
{
|
||||
/** Whether to use a UNIX socket for chansrv */
|
||||
int use_unix_socket;
|
||||
|
||||
/** Whether the FUSE mount is enabled or not */
|
||||
int enable_fuse_mount;
|
||||
|
||||
/** RestrictOutboundClipboard setting from sesman.ini */
|
||||
int restrict_outbound_clipboard;
|
||||
|
||||
/** * FuseMountName from sesman.ini */
|
||||
char *fuse_mount_name;
|
||||
/** FileUmask from sesman.ini */
|
||||
mode_t file_umask;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Reads sesman configuration
|
||||
* @param use_logger Use logger to log errors (otherwise stdout)
|
||||
* @param sesman_ini Name of configuration file to read
|
||||
*
|
||||
* @return configuration on success, NULL on failure
|
||||
*
|
||||
* @pre logging is assumed to be active
|
||||
* @post pass return value to config_free() to prevent memory leaks
|
||||
*
|
||||
*/
|
||||
struct config_chansrv *
|
||||
config_read(int use_logger, const char *sesman_ini);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Dumps configuration to stdout
|
||||
* @param pointer to a config_chansrv struct
|
||||
*
|
||||
*/
|
||||
void
|
||||
config_dump(struct config_chansrv *config);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Frees configuration allocated by config_read()
|
||||
* @param pointer to a config_chansrv struct (may be NULL)
|
||||
*
|
||||
*/
|
||||
void
|
||||
config_free(struct config_chansrv *cs);
|
||||
|
||||
#endif /* _CHANSRV_CONFIG */
|
File diff suppressed because it is too large
Load Diff
@ -19,55 +19,99 @@
|
||||
#ifndef _CHANSRV_FUSE_H
|
||||
#define _CHANSRV_FUSE_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "arch.h"
|
||||
#include "ms-erref.h"
|
||||
|
||||
/*
|
||||
* a file or dir entry in the xrdp file system (opaque type externally) */
|
||||
struct xrdp_inode;
|
||||
|
||||
/* Used to pass file info in to xfuse_devredir_add_file_or_dir()
|
||||
*
|
||||
* The string storage the name field points to is only valid
|
||||
* for the duration of the xfuse_devredir_add_file_or_dir()
|
||||
* call
|
||||
*/
|
||||
/* Used to pass file info back to chansrv_fuse from devredir */
|
||||
struct file_attr
|
||||
{
|
||||
const char *name; /* Name of file or directory */
|
||||
tui32 mode; /* File mode. */
|
||||
size_t size; /* Size of file, in bytes. */
|
||||
off_t size; /* Size of file, in bytes. */
|
||||
time_t atime; /* Time of last access. */
|
||||
time_t mtime; /* Time of last modification. */
|
||||
time_t ctime; /* Time of last status change. */
|
||||
};
|
||||
|
||||
/* Bitmask values used to identify individual elements in
|
||||
* struct file_attr
|
||||
*/
|
||||
#define TO_SET_MODE (1<<0)
|
||||
#define TO_SET_SIZE (1<<1)
|
||||
#define TO_SET_ATIME (1<<2)
|
||||
#define TO_SET_MTIME (1<<3)
|
||||
#define TO_SET_ALL (TO_SET_MODE | TO_SET_SIZE | TO_SET_ATIME | TO_SET_MTIME)
|
||||
|
||||
/* Private type passed into and back-from devredir */
|
||||
typedef struct xfuse_info XFUSE_INFO;
|
||||
|
||||
int xfuse_init(void);
|
||||
int xfuse_deinit(void);
|
||||
int xfuse_check_wait_objs(void);
|
||||
int xfuse_get_wait_objs(tbus *objs, int *count, int *timeout);
|
||||
int xfuse_create_share(tui32 share_id, const char *dirname);
|
||||
void xfuse_delete_share(tui32 share_id);
|
||||
|
||||
int xfuse_clear_clip_dir(void);
|
||||
int xfuse_file_contents_range(int stream_id, const char *data, int data_bytes);
|
||||
int xfuse_file_contents_size(int stream_id, int file_size);
|
||||
int xfuse_add_clip_dir_item(const char *filename, int flags, int size, int lindex);
|
||||
int xfuse_add_clip_dir_item(const char *filename,
|
||||
int flags, int size, int lindex);
|
||||
|
||||
/* State pointer types (opaque outside this module), used for
|
||||
* callback data
|
||||
*/
|
||||
struct state_dirscan;
|
||||
struct state_lookup;
|
||||
struct state_setattr;
|
||||
struct state_open;
|
||||
struct state_create;
|
||||
struct state_read;
|
||||
struct state_write;
|
||||
struct state_remove;
|
||||
struct state_rename;
|
||||
struct state_close;
|
||||
|
||||
|
||||
/* functions that are invoked from devredir */
|
||||
struct xrdp_inode *xfuse_devredir_add_file_or_dir(
|
||||
void *vp,
|
||||
void xfuse_devredir_cb_enum_dir_add_entry(
|
||||
struct state_dirscan *fip,
|
||||
const char *name,
|
||||
const struct file_attr *fattr);
|
||||
void xfuse_devredir_cb_enum_dir_done(struct state_dirscan *fip,
|
||||
enum NTSTATUS IoStatus);
|
||||
|
||||
void xfuse_devredir_cb_lookup_entry(struct state_lookup *fip,
|
||||
enum NTSTATUS IoStatus,
|
||||
const struct file_attr *file_info);
|
||||
void xfuse_devredir_cb_enum_dir_done(void *vp, tui32 IoStatus);
|
||||
void xfuse_devredir_cb_lookup_entry(void *vp, tui32 IoStatus,
|
||||
struct xrdp_inode *xinode);
|
||||
void xfuse_devredir_cb_open_file(void *vp, tui32 IoStatus, tui32 DeviceId, tui32 FileId);
|
||||
|
||||
void xfuse_devredir_cb_setattr(struct state_setattr *fip,
|
||||
enum NTSTATUS IoStatus);
|
||||
|
||||
void xfuse_devredir_cb_create_file(struct state_create *fip,
|
||||
enum NTSTATUS IoStatus,
|
||||
tui32 DeviceId, tui32 FileId);
|
||||
|
||||
void xfuse_devredir_cb_open_file(struct state_open *fip,
|
||||
enum NTSTATUS IoStatus,
|
||||
tui32 DeviceId, tui32 FileId);
|
||||
|
||||
void xfuse_devredir_cb_read_file(struct state_read *fip,
|
||||
enum NTSTATUS IoStatus,
|
||||
const char *buf, size_t length);
|
||||
void xfuse_devredir_cb_write_file(
|
||||
void *vp,
|
||||
tui32 IoStatus,
|
||||
const char *buf,
|
||||
struct state_write *fip,
|
||||
enum NTSTATUS IoStatus,
|
||||
off_t offset,
|
||||
size_t length);
|
||||
void xfuse_devredir_cb_read_file(void *vp, const char *buf, size_t length);
|
||||
void xfuse_devredir_cb_rmdir_or_file(void *vp, tui32 IoStatus);
|
||||
void xfuse_devredir_cb_rename_file(void *vp, tui32 IoStatus);
|
||||
void xfuse_devredir_cb_file_close(void *vp);
|
||||
|
||||
void xfuse_devredir_cb_rmdir_or_file(struct state_remove *fip,
|
||||
enum NTSTATUS IoStatus);
|
||||
|
||||
void xfuse_devredir_cb_rename_file(struct state_rename *fip,
|
||||
enum NTSTATUS IoStatus);
|
||||
|
||||
void xfuse_devredir_cb_file_close(struct state_close *fip);
|
||||
|
||||
#endif
|
||||
|
881
sesman/chansrv/chansrv_xfs.c
Normal file
881
sesman/chansrv/chansrv_xfs.c
Normal file
@ -0,0 +1,881 @@
|
||||
/**
|
||||
* 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_fuse_fs.h
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include <config_ac.h>
|
||||
#endif
|
||||
|
||||
#include "os_calls.h"
|
||||
#include "log.h"
|
||||
|
||||
#include "chansrv_xfs.h"
|
||||
|
||||
/*
|
||||
* Skip this module if FUSE is not supported. A standards-compliant C
|
||||
* translation unit must contain at least one declaration (C99:6.9), and we've
|
||||
* fulfilled that requirement by this stage.
|
||||
*/
|
||||
#ifdef XRDP_FUSE
|
||||
|
||||
#define INODE_TABLE_ALLOCATION_INITIAL 4096
|
||||
#define INODE_TABLE_ALLOCATION_GRANULARITY 100
|
||||
|
||||
/* inum of the delete pending directory */
|
||||
#define DELETE_PENDING_ID 2
|
||||
|
||||
/*
|
||||
* A double-linked list of inodes, sorted by inum
|
||||
*
|
||||
* The elements in the list are sorted in increasing inum order, as this
|
||||
* allows a directory enumeration to be easily resumed if elements
|
||||
* are removed or added. See xfs_readdir() for details on this.
|
||||
*/
|
||||
typedef struct xfs_inode_all XFS_INODE_ALL;
|
||||
typedef struct xfs_list
|
||||
{
|
||||
XFS_INODE_ALL *begin;
|
||||
XFS_INODE_ALL *end;
|
||||
} XFS_LIST;
|
||||
|
||||
/*
|
||||
* A complete inode, including the private elements used by the
|
||||
* implementation
|
||||
*/
|
||||
typedef struct xfs_inode_all
|
||||
{
|
||||
XFS_INODE pub; /* Public elements */
|
||||
/*
|
||||
* Directory linkage elements
|
||||
*
|
||||
* Because we don't support hard-linking, elements can be stored in
|
||||
* one and only one directory:-
|
||||
*/
|
||||
struct xfs_inode_all *parent; /* Parent inode */
|
||||
struct xfs_inode_all *next; /* Next entry in parent */
|
||||
struct xfs_inode_all *previous; /* Previous entry in parent */
|
||||
XFS_LIST dir; /* Directory only - children */
|
||||
/*
|
||||
* Other private elements
|
||||
*/
|
||||
unsigned int open_count; /* Regular files only */
|
||||
} XFS_INODE_ALL;
|
||||
|
||||
|
||||
/* the xrdp file system in memory
|
||||
*
|
||||
* inode_table allows for O(1) access to any file based on the inum.
|
||||
* Index 0 is unused, so we can use an inode of zero for
|
||||
* an invalid inode, and avoid off-by-one errors index
|
||||
* 1 is our '.' directory.
|
||||
* 2 is the delete pending directory, where we can place
|
||||
* inodes with a positive open count which are
|
||||
* deleted.
|
||||
* free_list List of free inode numbers. Allows for O(1) access to
|
||||
* a free node, provided the free list is not empty.
|
||||
*/
|
||||
struct xfs_fs
|
||||
{
|
||||
XFS_INODE_ALL **inode_table; /* a table of entries; can grow. */
|
||||
fuse_ino_t *free_list; /* Free inodes */
|
||||
unsigned int inode_count; /* Current number of inodes */
|
||||
unsigned int free_count; /* Size of free_list */
|
||||
unsigned int generation; /* Changes when an inode is deleted */
|
||||
};
|
||||
|
||||
/* A directory handle
|
||||
*
|
||||
* inum inum of the directory being scanned
|
||||
* generation Generation of the inum we opened
|
||||
*/
|
||||
struct xfs_dir_handle
|
||||
{
|
||||
fuse_ino_t inum;
|
||||
tui32 generation;
|
||||
};
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
static int
|
||||
grow_xfs(struct xfs_fs *xfs, unsigned int extra_inodes)
|
||||
{
|
||||
int result = 0;
|
||||
unsigned int new_count = xfs->inode_count + extra_inodes;
|
||||
XFS_INODE_ALL **new_table;
|
||||
fuse_ino_t *new_free_list;
|
||||
|
||||
new_table = (XFS_INODE_ALL **)
|
||||
realloc(xfs->inode_table, new_count * sizeof(new_table[0]));
|
||||
if (new_table != NULL)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = xfs->inode_count ; i < new_count ; ++i)
|
||||
{
|
||||
new_table[i] = NULL;
|
||||
}
|
||||
xfs->inode_table = new_table;
|
||||
|
||||
new_free_list = (fuse_ino_t *)
|
||||
realloc(xfs->free_list,
|
||||
new_count * sizeof(new_free_list[0]));
|
||||
if (new_free_list)
|
||||
{
|
||||
/* Add the new inodes in to the new_free_list, so the lowest
|
||||
* number is allocated first
|
||||
*/
|
||||
i = new_count;
|
||||
while (i > xfs->inode_count)
|
||||
{
|
||||
new_free_list[xfs->free_count++] = --i;
|
||||
}
|
||||
|
||||
xfs->free_list = new_free_list;
|
||||
xfs->inode_count = new_count;
|
||||
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
static void
|
||||
add_inode_to_list(XFS_LIST *list, XFS_INODE_ALL *xino)
|
||||
{
|
||||
fuse_ino_t inum = xino->pub.inum;
|
||||
|
||||
/* Find the element we need to insert after */
|
||||
XFS_INODE_ALL *predecessor = list->end;
|
||||
while (predecessor != NULL && predecessor->pub.inum > inum)
|
||||
{
|
||||
predecessor = predecessor->previous;
|
||||
}
|
||||
|
||||
if (predecessor == NULL)
|
||||
{
|
||||
/* Inserting at the beginning */
|
||||
/* Set up links in node */
|
||||
xino->next = list->begin;
|
||||
xino->previous = NULL;
|
||||
|
||||
/* Set up back-link to node */
|
||||
if (list->begin == NULL)
|
||||
{
|
||||
/* We are the last node */
|
||||
list->end = xino;
|
||||
}
|
||||
else
|
||||
{
|
||||
list->begin->previous = xino;
|
||||
}
|
||||
/* Set up forward-link to node */
|
||||
list->begin = xino;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set up links in node */
|
||||
xino->next = predecessor->next;
|
||||
xino->previous = predecessor;
|
||||
|
||||
/* Set up back-link to node */
|
||||
if (predecessor->next == NULL)
|
||||
{
|
||||
list->end = xino;
|
||||
}
|
||||
else
|
||||
{
|
||||
predecessor->next->previous = xino;
|
||||
}
|
||||
/* Set up forward-link to node */
|
||||
predecessor->next = xino;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
static void
|
||||
remove_inode_from_list(XFS_LIST *list, XFS_INODE_ALL *xino)
|
||||
{
|
||||
if (xino->previous == NULL)
|
||||
{
|
||||
/* First element */
|
||||
list->begin = xino->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
xino->previous->next = xino->next;
|
||||
}
|
||||
|
||||
if (xino->next == NULL)
|
||||
{
|
||||
/* Last element */
|
||||
list->end = xino->previous;
|
||||
}
|
||||
else
|
||||
{
|
||||
xino->next->previous = xino->previous;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
static void
|
||||
link_inode_into_directory_node(XFS_INODE_ALL *dinode, XFS_INODE_ALL *xino)
|
||||
{
|
||||
xino->parent = dinode;
|
||||
add_inode_to_list(&dinode->dir, xino);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
static void
|
||||
unlink_inode_from_parent(XFS_INODE_ALL *xino)
|
||||
{
|
||||
remove_inode_from_list(&xino->parent->dir, xino);
|
||||
|
||||
xino->next = NULL;
|
||||
xino->previous = NULL;
|
||||
xino->parent = NULL;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
struct xfs_fs *
|
||||
xfs_create_xfs_fs(mode_t umask, uid_t uid, gid_t gid)
|
||||
{
|
||||
struct xfs_fs *xfs = g_new0(struct xfs_fs, 1);
|
||||
XFS_INODE_ALL *xino1 = NULL;
|
||||
XFS_INODE_ALL *xino2 = NULL;
|
||||
|
||||
if (xfs != NULL)
|
||||
{
|
||||
xfs->inode_count = 0;
|
||||
xfs->free_count = 0;
|
||||
xfs->inode_table = NULL;
|
||||
xfs->free_list = NULL;
|
||||
xfs->generation = 1;
|
||||
|
||||
/* xfs->inode_table check should be superfluous here, but it
|
||||
* prevents cppcheck 2.2/2.3 generating a false positive nullPointer
|
||||
* report */
|
||||
if (!grow_xfs(xfs, INODE_TABLE_ALLOCATION_INITIAL) ||
|
||||
xfs->inode_table == NULL ||
|
||||
(xino1 = g_new0(XFS_INODE_ALL, 1)) == NULL ||
|
||||
(xino2 = g_new0(XFS_INODE_ALL, 1)) == NULL)
|
||||
{
|
||||
free(xino1);
|
||||
free(xino2);
|
||||
xfs_delete_xfs_fs(xfs);
|
||||
xfs = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* The use of grow_xfs to allocate the inode table will make
|
||||
* inodes 0, 1 (FUSE_ROOT_ID) and 2 (DELETE_PENDING_ID) the first
|
||||
* available free inodes. We can ignore these */
|
||||
xfs->free_count -= 3;
|
||||
|
||||
xfs->inode_table[0] = NULL;
|
||||
xfs->inode_table[FUSE_ROOT_ID] = xino1;
|
||||
xfs->inode_table[DELETE_PENDING_ID] = xino2;
|
||||
|
||||
xino1->pub.inum = FUSE_ROOT_ID;
|
||||
xino1->pub.mode = (S_IFDIR | 0777) & ~umask;
|
||||
xino1->pub.uid = uid;
|
||||
xino1->pub.gid = gid;
|
||||
xino1->pub.size = 0;
|
||||
xino1->pub.atime = time(0);
|
||||
xino1->pub.mtime = xino1->pub.atime;
|
||||
xino1->pub.ctime = xino1->pub.atime;
|
||||
strcpy(xino1->pub.name, ".");
|
||||
xino1->pub.generation = xfs->generation;
|
||||
xino1->pub.is_redirected = 0;
|
||||
xino1->pub.device_id = 0;
|
||||
|
||||
/*
|
||||
* FUSE_ROOT_ID has no parent rather than being a parent
|
||||
* of itself. This is intentional */
|
||||
xino1->parent = NULL;
|
||||
xino1->next = NULL;
|
||||
xino1->previous = NULL;
|
||||
xino1->dir.begin = NULL;
|
||||
xino1->dir.end = NULL;
|
||||
|
||||
xino2->pub.inum = DELETE_PENDING_ID;
|
||||
xino2->pub.mode = (S_IFDIR | 0777) & ~umask;
|
||||
xino2->pub.uid = uid;
|
||||
xino2->pub.gid = gid;
|
||||
xino2->pub.size = 0;
|
||||
xino2->pub.atime = time(0);
|
||||
xino2->pub.mtime = xino2->pub.atime;
|
||||
xino2->pub.ctime = xino2->pub.atime;
|
||||
strcpy(xino2->pub.name, ".delete-pending");
|
||||
xino2->pub.generation = xfs->generation;
|
||||
xino2->pub.is_redirected = 0;
|
||||
xino2->pub.device_id = 0;
|
||||
|
||||
xino2->parent = NULL;
|
||||
xino2->next = NULL;
|
||||
xino2->previous = NULL;
|
||||
xino2->dir.begin = NULL;
|
||||
xino2->dir.end = NULL;
|
||||
/*
|
||||
* Uncomment this line to make the .delete-pending
|
||||
* directory visible to the user in the root
|
||||
*/
|
||||
/* link_inode_into_directory_node(xino1, xino2); */
|
||||
}
|
||||
}
|
||||
|
||||
return xfs;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
void
|
||||
xfs_delete_xfs_fs(struct xfs_fs *xfs)
|
||||
{
|
||||
if (xfs == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (xfs->inode_table != NULL)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0 ; i < xfs->inode_count; ++i)
|
||||
{
|
||||
free(xfs->inode_table[i]);
|
||||
}
|
||||
}
|
||||
free(xfs->inode_table);
|
||||
free(xfs->free_list);
|
||||
free(xfs);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
XFS_INODE *
|
||||
xfs_add_entry(struct xfs_fs *xfs, fuse_ino_t parent_inum,
|
||||
const char *name, mode_t mode)
|
||||
{
|
||||
XFS_INODE *result = NULL;
|
||||
XFS_INODE_ALL *parent = NULL;
|
||||
|
||||
/* Checks:-
|
||||
* 1) the parent exists (and is a directory)
|
||||
* 2) the caller is not inserting into the .delete-pending directory,
|
||||
* 3) Name's not too long
|
||||
* 4) Entry does not already exist
|
||||
*/
|
||||
if (parent_inum < xfs->inode_count &&
|
||||
((parent = xfs->inode_table[parent_inum]) != NULL) &&
|
||||
(parent->pub.mode & S_IFDIR) != 0 &&
|
||||
parent_inum != DELETE_PENDING_ID &&
|
||||
strlen(name) <= XFS_MAXFILENAMELEN &&
|
||||
!xfs_lookup_in_dir(xfs, parent_inum, name))
|
||||
{
|
||||
/* Sanitise the mode so one-and-only-one of S_IFDIR and
|
||||
* S_IFREG is set */
|
||||
if ((mode & S_IFDIR) != 0)
|
||||
{
|
||||
mode = (mode & 0777) | S_IFDIR;
|
||||
}
|
||||
else
|
||||
{
|
||||
mode = (mode & 0777) | S_IFREG;
|
||||
}
|
||||
|
||||
/* Space for a new entry? */
|
||||
if (xfs->free_count > 0 ||
|
||||
grow_xfs(xfs, INODE_TABLE_ALLOCATION_GRANULARITY))
|
||||
{
|
||||
XFS_INODE_ALL *xino = NULL;
|
||||
|
||||
if ((xino = g_new0(XFS_INODE_ALL, 1)) != NULL)
|
||||
{
|
||||
fuse_ino_t inum = xfs->free_list[--xfs->free_count];
|
||||
if (xfs->inode_table[inum] != NULL)
|
||||
{
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR, "Unexpected non-NULL value in inode table "
|
||||
"entry %ld", inum);
|
||||
}
|
||||
xfs->inode_table[inum] = xino;
|
||||
xino->pub.inum = inum;
|
||||
xino->pub.mode = mode;
|
||||
xino->pub.uid = parent->pub.uid;
|
||||
xino->pub.gid = parent->pub.gid;
|
||||
if (mode & S_IFDIR)
|
||||
{
|
||||
xino->pub.size = 4096;
|
||||
}
|
||||
else
|
||||
{
|
||||
xino->pub.size = 0;
|
||||
}
|
||||
xino->pub.atime = time(0);
|
||||
xino->pub.mtime = xino->pub.atime;
|
||||
xino->pub.ctime = xino->pub.atime;
|
||||
strcpy(xino->pub.name, name);
|
||||
xino->pub.generation = xfs->generation;
|
||||
xino->pub.is_redirected = parent->pub.is_redirected;
|
||||
xino->pub.device_id = parent->pub.device_id;
|
||||
xino->pub.lindex = 0;
|
||||
|
||||
xino->parent = NULL;
|
||||
xino->next = NULL;
|
||||
xino->previous = NULL;
|
||||
link_inode_into_directory_node(parent, xino);
|
||||
result = &xino->pub;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
void
|
||||
xfs_remove_directory_contents(struct xfs_fs *xfs, fuse_ino_t inum)
|
||||
{
|
||||
XFS_INODE_ALL *xino = NULL;
|
||||
|
||||
if (inum < xfs->inode_count &&
|
||||
((xino = xfs->inode_table[inum]) != NULL) &&
|
||||
((xino->pub.mode & S_IFDIR) != 0))
|
||||
{
|
||||
XFS_INODE_ALL *e;
|
||||
while ((e = xino->dir.end) != NULL)
|
||||
{
|
||||
xfs_remove_entry(xfs, e->pub.inum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
void
|
||||
xfs_remove_entry(struct xfs_fs *xfs, fuse_ino_t inum)
|
||||
{
|
||||
XFS_INODE_ALL *xino = NULL;
|
||||
|
||||
if (inum < xfs->inode_count &&
|
||||
((xino = xfs->inode_table[inum]) != NULL))
|
||||
{
|
||||
if ((xino->pub.mode & S_IFDIR) != 0)
|
||||
{
|
||||
xfs_remove_directory_contents(xfs, inum);
|
||||
}
|
||||
|
||||
unlink_inode_from_parent(xino);
|
||||
if ((xino->pub.mode & S_IFREG) != 0 && xino->open_count > 0)
|
||||
{
|
||||
link_inode_into_directory_node(
|
||||
xfs->inode_table[DELETE_PENDING_ID], xino);
|
||||
}
|
||||
else
|
||||
{
|
||||
xfs->free_list[xfs->free_count++] = inum;
|
||||
xfs->inode_table[inum] = NULL;
|
||||
/*
|
||||
* Bump the generation when we return an inum to the free list,
|
||||
* so that the caller can distinguish re-uses of the same inum.
|
||||
*/
|
||||
++xfs->generation;
|
||||
free(xino);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
XFS_INODE *
|
||||
xfs_get(struct xfs_fs *xfs, fuse_ino_t inum)
|
||||
{
|
||||
return (inum < xfs->inode_count) ? &xfs->inode_table[inum]->pub : NULL;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
char *
|
||||
xfs_get_full_path(struct xfs_fs *xfs, fuse_ino_t inum)
|
||||
{
|
||||
char *result = NULL;
|
||||
XFS_INODE_ALL *xino = NULL;
|
||||
|
||||
if (inum < xfs->inode_count &&
|
||||
((xino = xfs->inode_table[inum]) != NULL))
|
||||
{
|
||||
if (xino->pub.inum == FUSE_ROOT_ID)
|
||||
{
|
||||
return strdup("/");
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Add up the lengths of all the names up to the root,
|
||||
* allowing one extra char for a '/' prefix for each element
|
||||
*/
|
||||
size_t len = 0;
|
||||
XFS_INODE_ALL *p;
|
||||
for (p = xino ; p && p->pub.inum != FUSE_ROOT_ID ; p = p->parent)
|
||||
{
|
||||
len += strlen(p->pub.name);
|
||||
++len; /* Allow for '/' prefix */
|
||||
}
|
||||
|
||||
result = (char *) malloc(len + 1);
|
||||
if (result != NULL)
|
||||
{
|
||||
/* Construct the path from the end */
|
||||
char *end = result + len;
|
||||
*end = '\0';
|
||||
|
||||
for (p = xino ; p && p->pub.inum != FUSE_ROOT_ID ; p = p->parent)
|
||||
{
|
||||
len = strlen(p->pub.name);
|
||||
end -= (len + 1);
|
||||
*end = '/';
|
||||
memcpy(end + 1, p->pub.name, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
XFS_INODE *
|
||||
xfs_lookup_in_dir(struct xfs_fs *xfs, fuse_ino_t inum, const char *name)
|
||||
{
|
||||
XFS_INODE_ALL *xino;
|
||||
XFS_INODE *result = NULL;
|
||||
if (inum < xfs->inode_count &&
|
||||
((xino = xfs->inode_table[inum]) != NULL) &&
|
||||
(xino->pub.mode & S_IFDIR) != 0)
|
||||
{
|
||||
XFS_INODE_ALL *p;
|
||||
for (p = xino->dir.begin ; p != NULL; p = p->next)
|
||||
{
|
||||
if (strcmp(p->pub.name, name) == 0)
|
||||
{
|
||||
result = &p->pub;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
int
|
||||
xfs_is_dir_empty(struct xfs_fs *xfs, fuse_ino_t inum)
|
||||
{
|
||||
XFS_INODE_ALL *xino = NULL;
|
||||
int result = 0;
|
||||
|
||||
if (inum < xfs->inode_count &&
|
||||
((xino = xfs->inode_table[inum]) != NULL) &&
|
||||
(xino->pub.mode & S_IFDIR) != 0)
|
||||
{
|
||||
result = (xino->dir.begin == NULL);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
unsigned int
|
||||
xfs_is_under(struct xfs_fs *xfs, fuse_ino_t dir, fuse_ino_t entry)
|
||||
{
|
||||
unsigned int result = 0;
|
||||
|
||||
XFS_INODE_ALL *dxino = NULL;
|
||||
XFS_INODE_ALL *exino = NULL;
|
||||
|
||||
if (dir < xfs->inode_count &&
|
||||
((dxino = xfs->inode_table[dir]) != NULL) &&
|
||||
(dxino->pub.mode & S_IFDIR) != 0 &&
|
||||
entry < xfs->inode_count &&
|
||||
((exino = xfs->inode_table[entry]) != NULL))
|
||||
{
|
||||
unsigned int count = 0;
|
||||
|
||||
while (exino != NULL && exino != dxino)
|
||||
{
|
||||
++count;
|
||||
exino = exino->parent;
|
||||
}
|
||||
|
||||
if (exino != NULL)
|
||||
{
|
||||
result = count;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
struct xfs_dir_handle *
|
||||
xfs_opendir(struct xfs_fs *xfs, fuse_ino_t dir)
|
||||
{
|
||||
XFS_INODE_ALL *xino = NULL;
|
||||
struct xfs_dir_handle *result = NULL;
|
||||
|
||||
if (dir < xfs->inode_count &&
|
||||
((xino = xfs->inode_table[dir]) != NULL) &&
|
||||
(xino->pub.mode & S_IFDIR) != 0)
|
||||
{
|
||||
result = g_new0(struct xfs_dir_handle, 1);
|
||||
if (result)
|
||||
{
|
||||
result->inum = xino->pub.inum;
|
||||
result->generation = xino->pub.generation;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
XFS_INODE *
|
||||
xfs_readdir(struct xfs_fs *xfs, struct xfs_dir_handle *handle, off_t *off)
|
||||
{
|
||||
XFS_INODE_ALL *result = NULL;
|
||||
XFS_INODE_ALL *dxino = NULL;
|
||||
XFS_INODE_ALL *xino = NULL;
|
||||
|
||||
/* Check the direcory is still valid */
|
||||
if (handle->inum < xfs->inode_count &&
|
||||
((dxino = xfs->inode_table[handle->inum]) != NULL) &&
|
||||
(dxino->pub.mode & S_IFDIR) != 0 &&
|
||||
handle->generation == dxino->pub.generation)
|
||||
{
|
||||
fuse_ino_t inum;
|
||||
|
||||
if (*off == (off_t) -1)
|
||||
{
|
||||
/* We're at the end already */
|
||||
}
|
||||
else if ((inum = *off) == 0)
|
||||
{
|
||||
/* First call */
|
||||
result = dxino->dir.begin;
|
||||
}
|
||||
else if (inum < xfs->inode_count &&
|
||||
(xino = xfs->inode_table[inum]) != 0 &&
|
||||
xino->parent == dxino)
|
||||
{
|
||||
/* The node we're pointing to is still valid */
|
||||
result = xino;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* The file we wanted has been pulled out from under us.
|
||||
* We will look forward in the inode table to try to
|
||||
* discover the next inode in the directory. Because
|
||||
* files are stored in inode order, this guarantees
|
||||
* we'll meet POSIX requirements.
|
||||
*/
|
||||
for (inum = inum + 1 ; inum < xfs->inode_count ; ++inum)
|
||||
{
|
||||
if ((xino = xfs->inode_table[inum]) != 0 &&
|
||||
xino->parent == dxino)
|
||||
{
|
||||
result = xino;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the offset */
|
||||
if (result == NULL || result->next == NULL)
|
||||
{
|
||||
/* We're done */
|
||||
*off = (off_t) -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*off = (off_t)result->next->pub.inum;
|
||||
}
|
||||
|
||||
/* Caller only sees public interface to the result */
|
||||
return (result) ? &result->pub : NULL;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
void
|
||||
xfs_closedir(struct xfs_fs *xfs, struct xfs_dir_handle *handle)
|
||||
{
|
||||
free(handle);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
void
|
||||
xfs_increment_file_open_count(struct xfs_fs *xfs, fuse_ino_t inum)
|
||||
{
|
||||
XFS_INODE_ALL *xino;
|
||||
if (inum < xfs->inode_count &&
|
||||
((xino = xfs->inode_table[inum]) != NULL) &&
|
||||
(xino->pub.mode & S_IFREG) != 0)
|
||||
{
|
||||
++xino->open_count;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
void
|
||||
xfs_decrement_file_open_count(struct xfs_fs *xfs, fuse_ino_t inum)
|
||||
{
|
||||
XFS_INODE_ALL *xino;
|
||||
if (inum < xfs->inode_count &&
|
||||
((xino = xfs->inode_table[inum]) != NULL) &&
|
||||
(xino->pub.mode & S_IFREG) != 0)
|
||||
{
|
||||
if (xino->open_count > 0)
|
||||
{
|
||||
--xino->open_count;
|
||||
}
|
||||
|
||||
if (xino->open_count == 0 &&
|
||||
xino->parent == xfs->inode_table[DELETE_PENDING_ID])
|
||||
{
|
||||
/* We can get rid of this one now */
|
||||
xfs_remove_entry(xfs, inum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
unsigned int
|
||||
xfs_get_file_open_count(struct xfs_fs *xfs, fuse_ino_t inum)
|
||||
{
|
||||
unsigned int result = 0;
|
||||
XFS_INODE_ALL *xino;
|
||||
if (inum < xfs->inode_count &&
|
||||
((xino = xfs->inode_table[inum]) != NULL) &&
|
||||
(xino->pub.mode & S_IFREG) != 0)
|
||||
{
|
||||
result = xino->open_count;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
void
|
||||
xfs_delete_redirected_entries_with_device_id(struct xfs_fs *xfs,
|
||||
tui32 device_id)
|
||||
{
|
||||
fuse_ino_t inum;
|
||||
XFS_INODE_ALL *xino;
|
||||
|
||||
/* Using xfs_remove_entry() is convenient, but it recurses
|
||||
* in to directories. To make sure all entries are removed, set the
|
||||
* open_count of all affected files to 0 first
|
||||
*/
|
||||
for (inum = FUSE_ROOT_ID; inum < xfs->inode_count; ++inum)
|
||||
{
|
||||
if ((xino = xfs->inode_table[inum]) != NULL &&
|
||||
xino->pub.is_redirected != 0 &&
|
||||
xino->pub.device_id == device_id &&
|
||||
(xino->pub.mode & S_IFREG) != 0)
|
||||
{
|
||||
xino->open_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we can be sure everything will be deleted correctly */
|
||||
for (inum = FUSE_ROOT_ID; inum < xfs->inode_count; ++inum)
|
||||
{
|
||||
if ((xino = xfs->inode_table[inum]) != NULL &&
|
||||
xino->pub.is_redirected != 0 &&
|
||||
xino->pub.device_id == device_id)
|
||||
{
|
||||
xfs_remove_entry(xfs, xino->pub.inum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
int
|
||||
xfs_check_move_entry(struct xfs_fs *xfs, fuse_ino_t inum,
|
||||
fuse_ino_t new_parent_inum, const char *name)
|
||||
{
|
||||
XFS_INODE_ALL *xino;
|
||||
XFS_INODE_ALL *parent;
|
||||
|
||||
return
|
||||
(strlen(name) <= XFS_MAXFILENAMELEN &&
|
||||
inum < xfs->inode_count &&
|
||||
((xino = xfs->inode_table[inum]) != NULL) &&
|
||||
new_parent_inum != DELETE_PENDING_ID &&
|
||||
new_parent_inum < xfs->inode_count &&
|
||||
((parent = xfs->inode_table[new_parent_inum]) != NULL) &&
|
||||
(parent->pub.mode & S_IFDIR) != 0 &&
|
||||
xfs_is_under(xfs, inum, new_parent_inum) == 0);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
int
|
||||
xfs_move_entry(struct xfs_fs *xfs, fuse_ino_t inum,
|
||||
fuse_ino_t new_parent_inum, const char *name)
|
||||
{
|
||||
int result = EINVAL;
|
||||
XFS_INODE_ALL *xino;
|
||||
XFS_INODE_ALL *parent;
|
||||
XFS_INODE *dest;
|
||||
|
||||
if (xfs_check_move_entry(xfs, inum, new_parent_inum, name))
|
||||
{
|
||||
xino = xfs->inode_table[inum];
|
||||
parent = xfs->inode_table[new_parent_inum];
|
||||
|
||||
if (xino->parent != parent)
|
||||
{
|
||||
/* We're moving between directories */
|
||||
|
||||
/* Does the target name already exist in the destination? */
|
||||
if ((dest = xfs_lookup_in_dir(xfs, new_parent_inum, name)) != NULL)
|
||||
{
|
||||
xfs_remove_entry(xfs, dest->inum);
|
||||
}
|
||||
|
||||
unlink_inode_from_parent(xino);
|
||||
link_inode_into_directory_node(parent, xino);
|
||||
strcpy(xino->pub.name, name);
|
||||
}
|
||||
else if (strcmp(xino->pub.name, name) != 0)
|
||||
{
|
||||
/* Same directory, but name has changed */
|
||||
if ((dest = xfs_lookup_in_dir(xfs, new_parent_inum, name)) != NULL)
|
||||
{
|
||||
xfs_remove_entry(xfs, dest->inum);
|
||||
}
|
||||
strcpy(xino->pub.name, name);
|
||||
}
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif /* XRDP_FUSE */
|
318
sesman/chansrv/chansrv_xfs.h
Normal file
318
sesman/chansrv/chansrv_xfs.h
Normal file
@ -0,0 +1,318 @@
|
||||
/**
|
||||
* 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 is the interface to the FUSE file system used by
|
||||
* chansrv
|
||||
*/
|
||||
|
||||
#ifndef _CHANSRV_XFS
|
||||
#define _CHANSRV_XFS
|
||||
|
||||
/* Skip this include if there's no FUSE */
|
||||
#ifdef XRDP_FUSE
|
||||
|
||||
#include <stddef.h>
|
||||
#include <fuse_lowlevel.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "arch.h"
|
||||
|
||||
#define XFS_MAXFILENAMELEN 255
|
||||
|
||||
/*
|
||||
* Incomplete types for the public interface
|
||||
*/
|
||||
struct xfs_fs;
|
||||
struct xfs_dir_handle;
|
||||
|
||||
typedef struct xfs_inode
|
||||
{
|
||||
fuse_ino_t inum; /* File serial number. */
|
||||
mode_t mode; /* File mode. */
|
||||
uid_t uid; /* User ID of the file's owner. */
|
||||
gid_t gid; /* Group ID of the file's group. */
|
||||
off_t size; /* Size of file, in bytes. */
|
||||
time_t atime; /* Time of last access. */
|
||||
time_t mtime; /* Time of last modification. */
|
||||
time_t ctime; /* Time of last status change. */
|
||||
char name[XFS_MAXFILENAMELEN + 1]; /* Short name */
|
||||
tui32 generation; /* Changes if inode is reused */
|
||||
char is_redirected; /* file is on redirected device */
|
||||
tui32 device_id; /* device ID of redirected device */
|
||||
int lindex; /* used in clipboard operations */
|
||||
} XFS_INODE;
|
||||
|
||||
/*
|
||||
* Create a new filesystem instance
|
||||
*
|
||||
* @param umask Umask to apply to initial data structures
|
||||
* @param uid Owner UID for initial root directory
|
||||
* @param gid Owner GID for initial root directory
|
||||
* @return Pointer to instance, or NULL if no memory
|
||||
*/
|
||||
struct xfs_fs *
|
||||
xfs_create_xfs_fs(mode_t umask, uid_t uid, gid_t gid);
|
||||
|
||||
/*
|
||||
* Delete a filesystem instance
|
||||
*
|
||||
* @param xfs Filesystem instance
|
||||
*/
|
||||
void
|
||||
xfs_delete_xfs_fs(struct xfs_fs *xfs);
|
||||
|
||||
/*
|
||||
* Add an entry to the filesystem
|
||||
*
|
||||
* The returned element has default values inherited from the parent
|
||||
*
|
||||
* The specified mode is sanitised in that:-
|
||||
* - Bits other than the lowest nine permissions bits, the directory
|
||||
* bit (S_IFDIR) and the regular bit (S_IFREG) are cleared.
|
||||
* - S_IFREG is cleared if S_IFDIR is set
|
||||
* - S_IFREG is set if neither S_IFDIR or S_IFREG is set
|
||||
*
|
||||
* NULL is returned for one of the following conditions:-
|
||||
* - the parent does not exist
|
||||
* - the parent is not a directory
|
||||
* - the name length exceeds XFS_MAXFILENAMELEN
|
||||
* - the entry already exists
|
||||
* - memory is exhausted.
|
||||
*
|
||||
* @param xfs filesystem instance
|
||||
* @param parent_inode parent inode
|
||||
* @param name Name of entry
|
||||
* @param mode Initial mode for file.
|
||||
* @return inode, or NULL
|
||||
*/
|
||||
XFS_INODE *
|
||||
xfs_add_entry(struct xfs_fs *xfs, fuse_ino_t parent_inum,
|
||||
const char *name, mode_t mode);
|
||||
|
||||
/*
|
||||
* Delete the contents of a directory
|
||||
*
|
||||
* If normal files are opened when they are deleted, the inode is not
|
||||
* released until the open count goes to zero.
|
||||
*
|
||||
* @param xfs filesystem instance
|
||||
* @param inode Reference to entry to delete
|
||||
*
|
||||
*/
|
||||
void
|
||||
xfs_remove_directory_contents(struct xfs_fs *xfs, fuse_ino_t inum);
|
||||
|
||||
/*
|
||||
* Delete an entry from the filesystem
|
||||
*
|
||||
* If normal files are opened when they are deleted, the inode is not
|
||||
* released until the open count goes to zero.
|
||||
*
|
||||
* For directories, the contents are removed first.
|
||||
*
|
||||
* @param xfs filesystem instance
|
||||
* @param inode Reference to entry to delete
|
||||
*
|
||||
*/
|
||||
void
|
||||
xfs_remove_entry(struct xfs_fs *xfs, fuse_ino_t inum);
|
||||
|
||||
/*
|
||||
* Get an XFS_INODE for an inum
|
||||
*
|
||||
* @param xfs filesystem instance
|
||||
* @param inum Inumber
|
||||
* @return Pointer to XFS_INODE
|
||||
*/
|
||||
XFS_INODE *
|
||||
xfs_get(struct xfs_fs *xfs, fuse_ino_t inum);
|
||||
|
||||
/*
|
||||
* Get the full path for an inum
|
||||
*
|
||||
* The path is dynamically allocated, and must be freed after use
|
||||
*
|
||||
* @param xfs filesystem instance
|
||||
* @param inum Inumber to get path for
|
||||
* @return Full path (free after use)
|
||||
*/
|
||||
char *
|
||||
xfs_get_full_path(struct xfs_fs *xfs, fuse_ino_t inum);
|
||||
|
||||
/*
|
||||
* Lookup a file in a directory
|
||||
*
|
||||
* @param xfs filesystem instance
|
||||
* @param inum Inumber of the directory
|
||||
* @param name Name of the file to lookup
|
||||
* @return Pointer to XFS_INODE if found
|
||||
*/
|
||||
XFS_INODE *
|
||||
xfs_lookup_in_dir(struct xfs_fs *xfs, fuse_ino_t inum, const char *name);
|
||||
|
||||
/*
|
||||
* Inquires as to whether a directory is empty.
|
||||
*
|
||||
* The caller must check that the inum is actually a directory, or
|
||||
* the result is undefined.
|
||||
*
|
||||
* @param xfs filesystem instance
|
||||
* @param inum Inumber of the directory
|
||||
* @return True if the directory is empty
|
||||
*/
|
||||
int
|
||||
xfs_is_dir_empty(struct xfs_fs *xfs, fuse_ino_t inum);
|
||||
|
||||
/*
|
||||
* Inquires as to whether an entry is under a directory.
|
||||
*
|
||||
* This can be used to check for invalid renames, where we try to
|
||||
* rename a directory into one of its sub-directories.
|
||||
*
|
||||
* Returned value means one of the following:-
|
||||
* 0 Entry is not related to the directory
|
||||
* 1 Entry is an immediate member of the directory
|
||||
* 2.. Entry is a few levels below the directory
|
||||
*
|
||||
* @param xfs filesystem instance
|
||||
* @param dir Inumber of the directory
|
||||
* @param entry Inumber of the entry
|
||||
* @return Nesting count of entry in the directory, or 0 for
|
||||
* no nesting
|
||||
*/
|
||||
unsigned int
|
||||
xfs_is_under(struct xfs_fs *xfs, fuse_ino_t dir, fuse_ino_t entry);
|
||||
|
||||
/*
|
||||
* Opens a directory for reading
|
||||
*
|
||||
* @param xfs filesystem instance
|
||||
* @param dir Inumber of the directory
|
||||
* @return handle to be passed to xfs_readdir() and xfs_closedir()
|
||||
*/
|
||||
struct xfs_dir_handle *
|
||||
xfs_opendir(struct xfs_fs *xfs, fuse_ino_t dir);
|
||||
|
||||
/*
|
||||
* Gets the next entry from a directory
|
||||
*
|
||||
* This function is safe to call while the filesystem is being modified.
|
||||
* Whether files added or removed from the directory in question are
|
||||
* returned or not is unspecified by this interface.
|
||||
*
|
||||
* @param xfs filesystem instance
|
||||
* @param handle Handle from xfs_opendir
|
||||
* @param off Offset (by reference). Pass in zero to get the first
|
||||
* entry. After the call, the offset is updated so that
|
||||
* the next call gets the next entry.
|
||||
*
|
||||
* @return pointer to details of file entry, or NULL if no more
|
||||
* entries are available.
|
||||
*/
|
||||
XFS_INODE *
|
||||
xfs_readdir(struct xfs_fs *xfs, struct xfs_dir_handle *handle, off_t *off);
|
||||
|
||||
|
||||
/*
|
||||
* Closes a directory opened for reading
|
||||
*
|
||||
* @param xfs filesystem instance
|
||||
* @param handle Earlier result of readdir() call
|
||||
*/
|
||||
void
|
||||
xfs_closedir(struct xfs_fs *xfs, struct xfs_dir_handle *handle);
|
||||
|
||||
/*
|
||||
* Increment the file open count
|
||||
*
|
||||
* The file open count is used to be sure when an entry can be deleted from
|
||||
* the data structures. It allows us to remove an entry while still retaining
|
||||
* enough state to manage the file
|
||||
*
|
||||
* This call is only necessary for regular files - not directories
|
||||
*
|
||||
* @param xfs filesystem instance
|
||||
* @param inum File to increment the count of
|
||||
*/
|
||||
void
|
||||
xfs_increment_file_open_count(struct xfs_fs *xfs, fuse_ino_t inum);
|
||||
|
||||
/*
|
||||
* Decrement the file open count
|
||||
*
|
||||
* This call will ensure that deleted inodes are cleared up at the appropriate
|
||||
* time.
|
||||
*
|
||||
* This call is only necessary for regular files - not directories
|
||||
*
|
||||
* @param xfs filesystem instance
|
||||
* @param inum File to decrement the count of
|
||||
*/
|
||||
void
|
||||
xfs_decrement_file_open_count(struct xfs_fs *xfs, fuse_ino_t inum);
|
||||
|
||||
/*
|
||||
* Return the file open count for a regular file
|
||||
*/
|
||||
unsigned int
|
||||
xfs_get_file_open_count(struct xfs_fs *xfs, fuse_ino_t inum);
|
||||
|
||||
/*
|
||||
* Deletes all redirected entries with the matching device id
|
||||
*
|
||||
* Files are deleted even if they are open
|
||||
*
|
||||
* @param device_id Device ID
|
||||
*/
|
||||
void
|
||||
xfs_delete_redirected_entries_with_device_id(struct xfs_fs *xfs,
|
||||
tui32 device_id);
|
||||
|
||||
/*
|
||||
* Check an entry move will be successful
|
||||
*
|
||||
* A move will fail if:-
|
||||
* - Any of the parameters are invalid
|
||||
* - if the entry is a directory, and the new parent is below the
|
||||
* entry in the existing hierarchy.
|
||||
*
|
||||
* @param xfs filesystem instance
|
||||
* @param inum Inumber of entry
|
||||
* @param new_parent New parent
|
||||
* @param name New name
|
||||
*
|
||||
* @result != 0 if all looks OK
|
||||
*/
|
||||
int
|
||||
xfs_check_move_entry(struct xfs_fs *xfs, fuse_ino_t inum,
|
||||
fuse_ino_t new_parent_inum, const char *name);
|
||||
|
||||
|
||||
/*
|
||||
* Move (rename) an entry
|
||||
*
|
||||
* @param xfs filesystem instance
|
||||
* @param inum Inumber of entry
|
||||
* @param new_parent New parent
|
||||
* @param name New name
|
||||
*
|
||||
* @result 0, or a suitable errno value.
|
||||
*/
|
||||
int
|
||||
xfs_move_entry(struct xfs_fs *xfs, fuse_ino_t inum,
|
||||
fuse_ino_t new_parent_inum, const char *name);
|
||||
|
||||
#endif /* XRDP_FUSE */
|
||||
#endif /* _CHANSRV_XFS */
|
File diff suppressed because it is too large
Load Diff
@ -33,6 +33,7 @@
|
||||
#include "arch.h"
|
||||
#include "parse.h"
|
||||
#include "os_calls.h"
|
||||
#include "string_calls.h"
|
||||
#include "list.h"
|
||||
#include "chansrv.h"
|
||||
#include "clipboard.h"
|
||||
@ -41,46 +42,6 @@
|
||||
#include "xcommon.h"
|
||||
#include "chansrv_fuse.h"
|
||||
|
||||
/* module based logging */
|
||||
#define LOG_ERROR 0
|
||||
#define LOG_INFO 1
|
||||
#define LOG_DEBUG 2
|
||||
#define LOG_LVL LOG_ERROR
|
||||
|
||||
#define log_error(_params...) \
|
||||
{ \
|
||||
g_write("[%10.10u]: CLIPFILE %s: %d : ERROR: ", \
|
||||
g_time3(), __func__, __LINE__); \
|
||||
g_writeln (_params); \
|
||||
}
|
||||
|
||||
#define log_always(_params...) \
|
||||
{ \
|
||||
g_write("[%10.10u]: CLIPFILE %s: %d : ALWAYS: ", \
|
||||
g_time3(), __func__, __LINE__); \
|
||||
g_writeln (_params); \
|
||||
}
|
||||
|
||||
#define log_info(_params...) \
|
||||
{ \
|
||||
if (LOG_INFO <= LOG_LVL) \
|
||||
{ \
|
||||
g_write("[%10.10u]: CLIPFILE %s: %d : ", \
|
||||
g_time3(), __func__, __LINE__); \
|
||||
g_writeln (_params); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define log_debug(_params...) \
|
||||
{ \
|
||||
if (LOG_DEBUG <= LOG_LVL) \
|
||||
{ \
|
||||
g_write("[%10.10u]: CLIPFILE %s: %d : ", \
|
||||
g_time3(), __func__, __LINE__); \
|
||||
g_writeln (_params); \
|
||||
} \
|
||||
}
|
||||
|
||||
extern int g_cliprdr_chan_id; /* in chansrv.c */
|
||||
|
||||
extern struct clip_s2c g_clip_s2c; /* in clipboard.c */
|
||||
@ -152,7 +113,7 @@ 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,27 +170,27 @@ 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, "
|
||||
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",
|
||||
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]",
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "ok filename [%s] pathname [%s] size [%d]",
|
||||
cfi->filename, cfi->pathname, cfi->size);
|
||||
}
|
||||
return 0;
|
||||
@ -292,9 +253,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",
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_data_response_for_file: data_size %d",
|
||||
data_size);
|
||||
//g_hexdump(data, data_size);
|
||||
LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", data, data_size);
|
||||
if (g_files_list == 0)
|
||||
{
|
||||
g_files_list = list_create();
|
||||
@ -355,17 +316,17 @@ 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",
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_file_size: streamId %d file_size %d",
|
||||
streamId, file_size);
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
@ -392,10 +353,10 @@ 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 "
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_request_file_size: warning, still waiting "
|
||||
"for CB_FILECONTENTS_RESPONSE");
|
||||
}
|
||||
make_stream(s);
|
||||
@ -434,29 +395,29 @@ 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 "
|
||||
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",
|
||||
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 "
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_file_data: seek error "
|
||||
"in file: %s", full_fn);
|
||||
g_file_close(fd);
|
||||
return 1;
|
||||
@ -466,7 +427,7 @@ 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",
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_file_data: read error, want %d got %d",
|
||||
cbRequested, size);
|
||||
free_stream(s);
|
||||
g_file_close(fd);
|
||||
@ -496,12 +457,12 @@ 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",
|
||||
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 "
|
||||
LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_request_file_data: warning, still waiting "
|
||||
"for CB_FILECONTENTS_RESPONSE");
|
||||
}
|
||||
make_stream(s);
|
||||
@ -539,8 +500,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,13 +530,13 @@ 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 "
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_file_response: streamId %d "
|
||||
"file_size %d", streamId, file_size);
|
||||
xfuse_file_contents_size(streamId, file_size);
|
||||
}
|
||||
@ -587,7 +548,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 +576,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,
|
||||
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_debug(" fileSize 0x%8.8x%8.8x", cfd->fileSizeHigh,
|
||||
LOG_DEVEL(LOG_LEVEL_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, " num_chars %d cFileName [%s]", num_chars, cfd->cFileName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -639,17 +600,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;
|
||||
@ -661,13 +622,13 @@ clipboard_c2s_in_files(struct stream *s, char *file_list)
|
||||
if ((g_pos(cfd->cFileName, "\\") >= 0) ||
|
||||
(cfd->fileAttributes & CB_FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
log_error("clipboard_c2s_in_files: skipping directory not "
|
||||
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
@ -18,334 +18,81 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// LK_TODO dev_redir_xxx should become devredir_xxx
|
||||
|
||||
#if !defined(DEVREDIR_H)
|
||||
#define DEVREDIR_H
|
||||
|
||||
#include "irp.h"
|
||||
#include "ms-rdpefs.h"
|
||||
|
||||
#define USE_SHORT_NAMES_IN_DIR_LISTING
|
||||
int devredir_init(void);
|
||||
int devredir_deinit(void);
|
||||
|
||||
FUSE_DATA *devredir_fuse_data_peek(IRP *irp);
|
||||
FUSE_DATA *devredir_fuse_data_dequeue(IRP *irp);
|
||||
int devredir_fuse_data_enqueue(IRP *irp, void *vp);
|
||||
|
||||
int dev_redir_init(void);
|
||||
int dev_redir_deinit(void);
|
||||
|
||||
int dev_redir_data_in(struct stream* s, int chan_id, int chan_flags,
|
||||
int devredir_data_in(struct stream* s, int chan_id, int chan_flags,
|
||||
int length, int total_length);
|
||||
|
||||
int dev_redir_get_wait_objs(tbus* objs, int* count, int* timeout);
|
||||
int dev_redir_check_wait_objs(void);
|
||||
|
||||
void dev_redir_send_server_core_cap_req(void);
|
||||
void dev_redir_send_server_clientID_confirm(void);
|
||||
void dev_redir_send_server_user_logged_on(void);
|
||||
void devredir_send_server_device_announce_resp(tui32 device_id);
|
||||
|
||||
void dev_redir_send_drive_dir_request(IRP *irp, tui32 device_id,
|
||||
tui32 InitialQuery, char *Path);
|
||||
|
||||
int dev_redir_send_drive_create_request(tui32 device_id,
|
||||
const char *path,
|
||||
tui32 DesiredAccess,
|
||||
tui32 CreateOptions,
|
||||
tui32 CreateDisposition,
|
||||
tui32 completion_id);
|
||||
|
||||
int dev_redir_send_drive_close_request(tui16 Component, tui16 PacketId,
|
||||
tui32 DeviceId,
|
||||
tui32 FileId,
|
||||
tui32 CompletionId,
|
||||
tui32 MajorFunction,
|
||||
tui32 MinorFunc,
|
||||
int pad_len);
|
||||
|
||||
void devredir_proc_client_devlist_announce_req(struct stream *s);
|
||||
void dev_redir_proc_client_core_cap_resp(struct stream *s);
|
||||
void dev_redir_proc_device_iocompletion(struct stream *s);
|
||||
|
||||
void dev_redir_proc_query_dir_response(IRP *irp,
|
||||
struct stream *s,
|
||||
tui32 DeviceId,
|
||||
tui32 CompletionId,
|
||||
tui32 IoStatus);
|
||||
int devredir_get_wait_objs(tbus* objs, int* count, int* timeout);
|
||||
int devredir_check_wait_objs(void);
|
||||
|
||||
/* misc stuff */
|
||||
void devredir_insert_DeviceIoRequest(struct stream *s,
|
||||
tui32 DeviceId,
|
||||
tui32 FileId,
|
||||
tui32 CompletionId,
|
||||
tui32 MajorFunction,
|
||||
tui32 MinorFunction);
|
||||
enum IRP_MJ MajorFunction,
|
||||
enum IRP_MN MinorFunction);
|
||||
|
||||
void devredir_cvt_slash(char *path);
|
||||
void devredir_cvt_to_unicode(char *unicode, const char *path);
|
||||
void devredir_cvt_from_unicode_len(char *path, char *unicode, int len);
|
||||
int dev_redir_string_ends_with(const char *string, char c);
|
||||
|
||||
void devredir_insert_RDPDR_header(struct stream *s, tui16 Component,
|
||||
tui16 PacketId);
|
||||
/* State pointer types (opaque outside this module), used for
|
||||
* callback data
|
||||
*/
|
||||
struct state_dirscan;
|
||||
struct state_lookup;
|
||||
struct state_setattr;
|
||||
struct state_open;
|
||||
struct state_create;
|
||||
struct state_read;
|
||||
struct state_write;
|
||||
struct state_remove;
|
||||
struct state_close;
|
||||
|
||||
/* called from FUSE module */
|
||||
int dev_redir_get_dir_listing(void *fusep, tui32 device_id, const char *path);
|
||||
|
||||
int dev_redir_lookup_entry(void *fusep, tui32 device_id, const char *dirpath,
|
||||
const char *entry);
|
||||
int devredir_get_dir_listing(struct state_dirscan *fusep, tui32 device_id,
|
||||
const char *path);
|
||||
|
||||
int dev_redir_file_open(void *fusep, tui32 device_id, const char *path,
|
||||
int mode, int type, const char *gen_buf);
|
||||
int devredir_lookup_entry(struct state_lookup *fusep, tui32 device_id,
|
||||
const char *path);
|
||||
|
||||
int devredir_file_close(void *fusep, tui32 device_id, tui32 file_id);
|
||||
int devredir_setattr_for_entry(
|
||||
struct state_setattr *fusep, tui32 device_id,
|
||||
const char *filename,
|
||||
const struct file_attr *fattr,
|
||||
tui32 to_set);
|
||||
|
||||
int devredir_file_read(void *fusep, tui32 device_id, tui32 FileId,
|
||||
int devredir_file_create(
|
||||
struct state_create *fusep, tui32 device_id,
|
||||
const char *path, int mode);
|
||||
|
||||
int devredir_file_open(struct state_open *fusep, tui32 device_id,
|
||||
const char *path, int flags);
|
||||
|
||||
int devredir_file_close(struct state_close *fusep, tui32 device_id,
|
||||
tui32 file_id);
|
||||
|
||||
void
|
||||
devredir_file_read(struct state_read *fusep, tui32 device_id, tui32 FileId,
|
||||
tui32 Length, tui64 Offset);
|
||||
|
||||
int
|
||||
dev_redir_file_write(void *fusep, tui32 DeviceId, tui32 FileId,
|
||||
void
|
||||
devredir_file_write(struct state_write *fusep, tui32 DeviceId, tui32 FileId,
|
||||
const char *buf, int Length, tui64 Offset);
|
||||
|
||||
int devredir_file_rename(
|
||||
struct state_rename *fusep, tui32 device_id,
|
||||
const char *old_name,
|
||||
const char *new_name);
|
||||
|
||||
int
|
||||
devredir_rmdir_or_file(void *fusep, tui32 device_id, const char *path, int mode);
|
||||
|
||||
/*
|
||||
* RDPDR_HEADER definitions
|
||||
*/
|
||||
|
||||
/* device redirector core component; most of the packets in this protocol */
|
||||
/* are sent under this component ID */
|
||||
#define RDPDR_CTYP_CORE 0x4472
|
||||
|
||||
/* printing component. the packets that use this ID are typically about */
|
||||
/* printer cache management and identifying XPS printers */
|
||||
#define RDPDR_CTYP_PRN 0x5052
|
||||
|
||||
/* Server Announce Request, as specified in section 2.2.2.2 */
|
||||
#define PAKID_CORE_SERVER_ANNOUNCE 0x496E
|
||||
|
||||
/* Client Announce Reply and Server Client ID Confirm, as specified in */
|
||||
/* sections 2.2.2.3 and 2.2.2.6. */
|
||||
#define PAKID_CORE_CLIENTID_CONFIRM 0x4343
|
||||
|
||||
/* Client Name Request, as specified in section 2.2.2.4 */
|
||||
#define PAKID_CORE_CLIENT_NAME 0x434E
|
||||
|
||||
/* Client Device List Announce Request, as specified in section 2.2.2.9 */
|
||||
#define PAKID_CORE_DEVICELIST_ANNOUNCE 0x4441
|
||||
|
||||
/* Server Device Announce Response, as specified in section 2.2.2.1 */
|
||||
#define PAKID_CORE_DEVICE_REPLY 0x6472
|
||||
|
||||
/* Device I/O Request, as specified in section 2.2.1.4 */
|
||||
#define PAKID_CORE_DEVICE_IOREQUEST 0x4952
|
||||
|
||||
/* Device I/O Response, as specified in section 2.2.1.5 */
|
||||
#define PAKID_CORE_DEVICE_IOCOMPLETION 0x4943
|
||||
|
||||
/* Server Core Capability Request, as specified in section 2.2.2.7 */
|
||||
#define PAKID_CORE_SERVER_CAPABILITY 0x5350
|
||||
|
||||
/* Client Core Capability Response, as specified in section 2.2.2.8 */
|
||||
#define PAKID_CORE_CLIENT_CAPABILITY 0x4350
|
||||
|
||||
/* Client Drive Device List Remove, as specified in section 2.2.3.2 */
|
||||
#define PAKID_CORE_DEVICELIST_REMOVE 0x444D
|
||||
|
||||
/* Add Printer Cachedata, as specified in [MS-RDPEPC] section 2.2.2.3 */
|
||||
#define PAKID_PRN_CACHE_DATA 0x5043
|
||||
|
||||
/* Server User Logged On, as specified in section 2.2.2.5 */
|
||||
#define PAKID_CORE_USER_LOGGEDON 0x554C
|
||||
|
||||
/* Server Printer Set XPS Mode, as specified in [MS-RDPEPC] section 2.2.2.2 */
|
||||
#define PAKID_PRN_USING_XPS 0x5543
|
||||
|
||||
/*
|
||||
* Capability header definitions
|
||||
*/
|
||||
|
||||
#define CAP_GENERAL_TYPE 0x0001 /* General cap set - GENERAL_CAPS_SET */
|
||||
#define CAP_PRINTER_TYPE 0x0002 /* Print cap set - PRINTER_CAPS_SET */
|
||||
#define CAP_PORT_TYPE 0x0003 /* Port cap set - PORT_CAPS_SET */
|
||||
#define CAP_DRIVE_TYPE 0x0004 /* Drive cap set - DRIVE_CAPS_SET */
|
||||
#define CAP_SMARTCARD_TYPE 0x0005 /* Smart card cap set - SMARTCARD_CAPS_SET */
|
||||
|
||||
/* client minor versions */
|
||||
#define RDP_CLIENT_50 0x0002
|
||||
#define RDP_CLIENT_51 0x0005
|
||||
#define RDP_CLIENT_52 0x000a
|
||||
#define RDP_CLIENT_60_61 0x000c
|
||||
|
||||
/* used in device announce list */
|
||||
#define RDPDR_DTYP_SERIAL 0x0001
|
||||
#define RDPDR_DTYP_PARALLEL 0x0002
|
||||
#define RDPDR_DTYP_PRINT 0x0004
|
||||
#define RDPDR_DTYP_FILESYSTEM 0x0008
|
||||
#define RDPDR_DTYP_SMARTCARD 0x0020
|
||||
|
||||
/*
|
||||
* DesiredAccess Mask [MS-SMB2] section 2.2.13.1.1
|
||||
*/
|
||||
|
||||
#define DA_FILE_READ_DATA 0x00000001
|
||||
#define DA_FILE_WRITE_DATA 0x00000002
|
||||
#define DA_FILE_APPEND_DATA 0x00000004
|
||||
#define DA_FILE_READ_EA 0x00000008 /* rd extended attributes */
|
||||
#define DA_FILE_WRITE_EA 0x00000010 /* wr extended attributes */
|
||||
#define DA_FILE_EXECUTE 0x00000020
|
||||
#define DA_FILE_READ_ATTRIBUTES 0x00000080
|
||||
#define DA_FILE_WRITE_ATTRIBUTES 0x00000100
|
||||
#define DA_DELETE 0x00010000
|
||||
#define DA_READ_CONTROL 0x00020000 /* rd security descriptor */
|
||||
#define DA_WRITE_DAC 0x00040000
|
||||
#define DA_WRITE_OWNER 0x00080000
|
||||
#define DA_SYNCHRONIZE 0x00100000
|
||||
#define DA_ACCESS_SYSTEM_SECURITY 0x01000000
|
||||
#define DA_MAXIMUM_ALLOWED 0x02000000
|
||||
#define DA_GENERIC_ALL 0x10000000
|
||||
#define DA_GENERIC_EXECUTE 0x20000000
|
||||
#define DA_GENERIC_WRITE 0x40000000
|
||||
#define DA_GENERIC_READ 0x80000000
|
||||
|
||||
/*
|
||||
* CreateOptions Mask [MS-SMB2] section 2.2.13 SMB2 CREATE Request
|
||||
*/
|
||||
|
||||
enum CREATE_OPTIONS
|
||||
{
|
||||
CO_FILE_DIRECTORY_FILE = 0x00000001,
|
||||
CO_FILE_WRITE_THROUGH = 0x00000002,
|
||||
CO_FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020,
|
||||
CO_FILE_DELETE_ON_CLOSE = 0x00001000
|
||||
};
|
||||
|
||||
/*
|
||||
* CreateDispositions Mask [MS-SMB2] section 2.2.13
|
||||
*/
|
||||
|
||||
#define CD_FILE_SUPERSEDE 0x00000000
|
||||
#define CD_FILE_OPEN 0x00000001
|
||||
#define CD_FILE_CREATE 0x00000002
|
||||
#define CD_FILE_OPEN_IF 0x00000003
|
||||
#define CD_FILE_OVERWRITE 0x00000004
|
||||
#define CD_FILE_OVERWRITE_IF 0x00000005
|
||||
|
||||
/*
|
||||
* Device I/O Request MajorFunction definitions
|
||||
*/
|
||||
|
||||
#define IRP_MJ_CREATE 0x00000000
|
||||
#define IRP_MJ_CLOSE 0x00000002
|
||||
#define IRP_MJ_READ 0x00000003
|
||||
#define IRP_MJ_WRITE 0x00000004
|
||||
#define IRP_MJ_DEVICE_CONTROL 0x0000000E
|
||||
#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0000000A
|
||||
#define IRP_MJ_SET_VOLUME_INFORMATION 0x0000000B
|
||||
#define IRP_MJ_QUERY_INFORMATION 0x00000005
|
||||
#define IRP_MJ_SET_INFORMATION 0x00000006
|
||||
#define IRP_MJ_DIRECTORY_CONTROL 0x0000000C
|
||||
#define IRP_MJ_LOCK_CONTROL 0x00000011
|
||||
|
||||
/*
|
||||
* Device I/O Request MinorFunction definitions
|
||||
*
|
||||
* Only valid when MajorFunction code = IRP_MJ_DIRECTORY_CONTROL
|
||||
*/
|
||||
|
||||
#define IRP_MN_QUERY_DIRECTORY 0x00000001
|
||||
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x00000002
|
||||
|
||||
/*
|
||||
* NTSTATUS codes (used by IoStatus) - see section 2.3 of MS-ERREF
|
||||
*/
|
||||
|
||||
#define NT_STATUS_SUCCESS 0x00000000
|
||||
#define NT_STATUS_UNSUCCESSFUL 0xC0000001
|
||||
#define NT_STATUS_NO_SUCH_FILE 0xC000000F
|
||||
#define NT_STATUS_ACCESS_DENIED 0xC0000022
|
||||
#define NT_STATUS_OBJECT_NAME_INVALID 0xC0000033
|
||||
#define NT_STATUS_OBJECT_NAME_NOT_FOUND 0xC0000034
|
||||
|
||||
/*
|
||||
* File system ioctl codes
|
||||
* MS-FSCC section 2.3 FSCTL Structures
|
||||
*/
|
||||
#define FSCTL_DELETE_OBJECT_ID 0x900a0
|
||||
|
||||
|
||||
/*
|
||||
* CompletionID types, used in IRPs to indicate I/O operation
|
||||
*/
|
||||
|
||||
enum COMPLETION_ID
|
||||
{
|
||||
CID_CREATE_DIR_REQ = 1,
|
||||
CID_DIRECTORY_CONTROL,
|
||||
CID_CREATE_OPEN_REQ,
|
||||
CID_READ,
|
||||
CID_WRITE,
|
||||
CID_CLOSE,
|
||||
CID_FILE_CLOSE,
|
||||
CID_RMDIR_OR_FILE,
|
||||
CID_RMDIR_OR_FILE_RESP,
|
||||
CID_RENAME_FILE,
|
||||
CID_RENAME_FILE_RESP,
|
||||
CID_LOOKUP_BASIC_ENTRY,
|
||||
CID_LOOKUP_STD_ENTRY,
|
||||
CID_LOOKUP_ENTRY_RESP
|
||||
};
|
||||
|
||||
enum FS_INFORMATION_CLASS
|
||||
{
|
||||
FileBasicInformation = 0x00000004, /* set atime, mtime, ctime etc */
|
||||
FileStandardInformation = 0x00000005, /* Alloc size, EOF #links, etc */
|
||||
FileEndOfFileInformation = 0x00000014, /* set EOF info */
|
||||
FileDispositionInformation = 0x0000000D, /* mark a file for deletion */
|
||||
FileRenameInformation = 0x0000000A, /* rename a file */
|
||||
FileAllocationInformation = 0x00000013 /* set file allocation size */
|
||||
};
|
||||
|
||||
/*
|
||||
* constants for drive dir query
|
||||
*/
|
||||
|
||||
/* Basic information about a file or directory. Basic information is */
|
||||
/* defined as the file's name, time stamp, and size, or its attributes */
|
||||
#define FileDirectoryInformation 0x00000001
|
||||
|
||||
/* Full information about a file or directory. Full information is defined */
|
||||
/* as all the basic information, plus extended attribute size. */
|
||||
#define FileFullDirectoryInformation 0x00000002
|
||||
|
||||
/* Basic information plus extended attribute size and short name */
|
||||
/* about a file or directory. */
|
||||
#define FileBothDirectoryInformation 0x00000003
|
||||
|
||||
/* Detailed information on the names of files in a directory. */
|
||||
#define FileNamesInformation 0x0000000C
|
||||
|
||||
/*
|
||||
* NTSTATUS Codes of interest to us
|
||||
*/
|
||||
|
||||
/* No more files were found which match the file specification */
|
||||
#define STATUS_NO_MORE_FILES 0x80000006
|
||||
|
||||
/* Windows file attributes */
|
||||
#define W_FILE_ATTRIBUTE_DIRECTORY 0x00000010
|
||||
#define W_FILE_ATTRIBUTE_READONLY 0x00000001
|
||||
|
||||
#define WINDOWS_TO_LINUX_FILE_PERM(_a) \
|
||||
(((_a) & W_FILE_ATTRIBUTE_DIRECTORY) ? S_IFDIR | 0100 : S_IFREG) |\
|
||||
(((_a) & W_FILE_ATTRIBUTE_READONLY) ? 0444 : 0644)
|
||||
|
||||
/* Windows time starts on Jan 1, 1601 */
|
||||
/* Linux time starts on Jan 1, 1970 */
|
||||
#define EPOCH_DIFF 11644473600LL
|
||||
#define WINDOWS_TO_LINUX_TIME(_t) ((_t) / 10000000) - EPOCH_DIFF;
|
||||
|
||||
#define OP_RENAME_FILE 0x01
|
||||
devredir_rmdir_or_file(struct state_remove *fusep, tui32 device_id,
|
||||
const char *path);
|
||||
|
||||
#endif
|
||||
|
@ -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",
|
||||
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,19 +161,21 @@ 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 */
|
||||
fp->rd_ptr = 0;
|
||||
@ -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,12 @@
|
||||
#include <config_ac.h>
|
||||
#endif
|
||||
|
||||
#include "chansrv.h"
|
||||
#include "parse.h"
|
||||
#include "os_calls.h"
|
||||
#include "string_calls.h"
|
||||
#include "irp.h"
|
||||
|
||||
/* module based logging */
|
||||
#define LOG_ERROR 0
|
||||
#define LOG_INFO 1
|
||||
#define LOG_DEBUG 2
|
||||
|
||||
#ifndef LOG_LEVEL
|
||||
#define LOG_LEVEL LOG_ERROR
|
||||
#endif
|
||||
|
||||
#define log_error(_params...) \
|
||||
{ \
|
||||
g_write("[%10.10u]: IRP %s: %d : ERROR: ", \
|
||||
g_time3(), __func__, __LINE__); \
|
||||
g_writeln (_params); \
|
||||
}
|
||||
|
||||
#define log_info(_params...) \
|
||||
{ \
|
||||
if (LOG_INFO <= LOG_LEVEL) \
|
||||
{ \
|
||||
g_write("[%10.10u]: IRP %s: %d : ", \
|
||||
g_time3(), __func__, __LINE__); \
|
||||
g_writeln (_params); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define log_debug(_params...) \
|
||||
{ \
|
||||
if (LOG_DEBUG <= LOG_LEVEL) \
|
||||
{ \
|
||||
g_write("[%10.10u]: IRP %s: %d : ", \
|
||||
g_time3(), __func__, __LINE__); \
|
||||
g_writeln (_params); \
|
||||
} \
|
||||
}
|
||||
|
||||
IRP *g_irp_head = NULL;
|
||||
|
||||
/**
|
||||
@ -73,18 +39,18 @@ 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,37 +66,72 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone specified IRP
|
||||
* Create a new IRP with a copied pathname, and append to linked list.
|
||||
*
|
||||
* Allocation is made in such a way that the IRP can be freed with a single
|
||||
* free() operation
|
||||
*
|
||||
* @return new IRP or NULL on error
|
||||
*****************************************************************************/
|
||||
|
||||
IRP * devredir_irp_clone(IRP *irp)
|
||||
IRP *devredir_irp_with_pathname_new(const char *pathname)
|
||||
{
|
||||
IRP *new_irp;
|
||||
IRP *prev;
|
||||
IRP *next;
|
||||
unsigned int len = g_strlen(pathname);
|
||||
IRP *irp = devredir_irp_with_pathnamelen_new(len);
|
||||
if (irp != NULL)
|
||||
{
|
||||
g_strcpy(irp->pathname, pathname);
|
||||
}
|
||||
|
||||
if ((new_irp = devredir_irp_new()) == NULL)
|
||||
return irp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new IRP with space allocated for a pathname, and append to
|
||||
* linked list.
|
||||
*
|
||||
* Allocation is made in such a way that the IRP can be freed with a single
|
||||
* free() operation
|
||||
*
|
||||
* @return new IRP or NULL on error
|
||||
*****************************************************************************/
|
||||
|
||||
IRP *devredir_irp_with_pathnamelen_new(unsigned int pathnamelen)
|
||||
{
|
||||
IRP *irp;
|
||||
IRP *irp_last;
|
||||
|
||||
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_DEVEL(LOG_LEVEL_ERROR, "system out of memory!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* save link pointers */
|
||||
prev = new_irp->prev;
|
||||
next = new_irp->next;
|
||||
irp->pathname = (char *)irp + sizeof(IRP); /* Initialise pathname pointer */
|
||||
|
||||
/* copy all members */
|
||||
g_memcpy(new_irp, irp, sizeof(IRP));
|
||||
/* insert at end of linked list */
|
||||
if ((irp_last = devredir_irp_get_last()) == NULL)
|
||||
{
|
||||
/* list is empty, this is the first entry */
|
||||
g_irp_head = irp;
|
||||
}
|
||||
else
|
||||
{
|
||||
irp_last->next = irp;
|
||||
irp->prev = irp_last;
|
||||
}
|
||||
|
||||
/* restore link pointers */
|
||||
new_irp->prev = prev;
|
||||
new_irp->next = next;
|
||||
|
||||
return new_irp;
|
||||
LOG_DEVEL(LOG_LEVEL_DEBUG, "new IRP=%p", irp);
|
||||
return irp;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -144,9 +145,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
|
||||
@ -154,13 +157,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 */
|
||||
}
|
||||
|
||||
if (lirp->prev == NULL)
|
||||
{
|
||||
@ -209,18 +216,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;
|
||||
|
||||
@ -228,14 +235,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;
|
||||
}
|
||||
|
||||
@ -243,19 +250,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;
|
||||
}
|
||||
|
||||
@ -263,13 +272,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 ---");
|
||||
}
|
||||
|
@ -29,11 +29,49 @@
|
||||
#endif
|
||||
#include "chansrv_fuse.h"
|
||||
|
||||
typedef struct fuse_data FUSE_DATA;
|
||||
struct fuse_data
|
||||
/* Opaque data types to us */
|
||||
typedef struct xfuse_info XFUSE_INFO;
|
||||
|
||||
enum irp_lookup_state
|
||||
{
|
||||
void *data_ptr;
|
||||
FUSE_DATA *next;
|
||||
E_LOOKUP_GET_FH = 0,
|
||||
E_LOOKUP_CHECK_BASIC,
|
||||
E_LOOKUP_CHECK_EOF
|
||||
} ;
|
||||
|
||||
enum irp_setattr_state
|
||||
{
|
||||
E_SETATTR_GET_FH = 0,
|
||||
E_SETATTR_CHECK_BASIC,
|
||||
E_SETATTR_CHECK_EOF
|
||||
} ;
|
||||
|
||||
struct irp_lookup
|
||||
{
|
||||
enum irp_lookup_state state; /* Next state to consider */
|
||||
struct file_attr fattr; /* Attributes to get */
|
||||
};
|
||||
|
||||
struct irp_setattr
|
||||
{
|
||||
enum irp_setattr_state state; /* Next state to consider */
|
||||
tui32 to_set; /* Bit mask for elements in use */
|
||||
struct file_attr fattr; /* Attributes to set */
|
||||
};
|
||||
|
||||
struct irp_write
|
||||
{
|
||||
tui64 offset; /* Offset the write was made at */
|
||||
};
|
||||
|
||||
struct irp_create
|
||||
{
|
||||
int creating_dir; /* We're creating a directory */
|
||||
};
|
||||
|
||||
struct irp_rename
|
||||
{
|
||||
char *new_name; /* New name for file */
|
||||
};
|
||||
|
||||
/* An I/O Resource Packet to track I/O calls */
|
||||
@ -46,15 +84,18 @@ struct irp
|
||||
tui32 DeviceId; /* identifies remote device */
|
||||
tui32 FileId; /* RDP client provided unique number */
|
||||
char completion_type; /* describes I/O type */
|
||||
char pathname[256]; /* absolute pathname */
|
||||
char *pathname; /* absolute pathname
|
||||
* Allocate with
|
||||
* devredir_irp_with_pathname_new() */
|
||||
union
|
||||
{
|
||||
char buf[1024]; /* General character data */
|
||||
struct file_attr fattr; /* Used to assemble file attributes */
|
||||
} gen; /* for general use */
|
||||
int type;
|
||||
FUSE_DATA *fd_head; /* point to first FUSE opaque object */
|
||||
FUSE_DATA *fd_tail; /* point to last FUSE opaque object */
|
||||
struct irp_lookup lookup; /* Used by lookup */
|
||||
struct irp_setattr setattr; /* Used by setattr */
|
||||
struct irp_write write; /* Used by write */
|
||||
struct irp_create create; /* Used by create */
|
||||
struct irp_rename rename; /* Use by rename */
|
||||
} gen; /* Additional state data for some ops */
|
||||
void *fuse_info; /* Fuse info pointer for FUSE calls */
|
||||
IRP *next; /* point to next IRP */
|
||||
IRP *prev; /* point to previous IRP */
|
||||
int scard_index; /* used to smart card to locate dev */
|
||||
@ -65,7 +106,13 @@ struct irp
|
||||
};
|
||||
|
||||
IRP * devredir_irp_new(void);
|
||||
IRP * devredir_irp_clone(IRP *irp);
|
||||
/* As above, but allocates sufficent space for the specified
|
||||
* pathname, and copies it in to the pathname field */
|
||||
IRP * devredir_irp_with_pathname_new(const char *pathname);
|
||||
/* As above, but specifies a pathname length with pathname
|
||||
* initially set to "". Use if you need to modify the pathname
|
||||
* significantly */
|
||||
IRP * devredir_irp_with_pathnamelen_new(unsigned int pathnamelen);
|
||||
int devredir_irp_delete(IRP *irp);
|
||||
IRP * devredir_irp_find(tui32 completion_id);
|
||||
IRP * devredir_irp_find_by_fileid(tui32 FileId);
|
||||
|
@ -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 */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user