Compare commits

...

245 Commits

Author SHA1 Message Date
matt335672
42150c5c4f
Merge pull request #1793 from aquesnel/send_bell_fix
Fixing TS_PLAY_SOUND_PDU_DATA to set the correct frequency and duration
2021-01-25 09:12:34 +00:00
Alexandre Quesnel
87c89f0aa2 Fixing TS_PLAY_SOUND_PDU_DATA to set the correct frequency and duration 2021-01-23 22:57:15 +00:00
matt335672
43945e2d4b
Merge pull request #1787 from matt335672/minor-man-fixes
Minor manpage fixes
2021-01-21 10:14:12 +00:00
matt335672
9d229d2318 Minor manpage fixes 2021-01-20 12:55:35 +00:00
matt335672
b9c5c00d7c
Merge pull request #1765 from matt335672/issue1762
Remove output on stdout by default on daemon startup (#1762)
2021-01-07 11:05:27 +00:00
matt335672
1e13533048 Remove output on stdout by default on daemon startuip 2021-01-07 10:50:16 +00:00
matt335672
cca057908c
Merge pull request #1778 from matt335672/ec-crypto
Support EC cryptographic keys for TLS
2021-01-07 10:47:42 +00:00
matt335672
ea582429e1 Load any private key type, not just RSA (#1776)
Fix missing SSL logging and reformat with astyle
2021-01-07 10:34:39 +00:00
matt335672
c76c580441
Merge pull request #1771 from matt335672/cppcheck-new
Bump cppcheck version to 2.3
2020-12-31 12:46:02 +00:00
matt335672
8ab3a2e9f8 Bumped cppcheck version to 2.3
addressed resulting warnings
2020-12-31 11:27:14 +00:00
matt335672
d8998a0a19
Merge pull request #1769 from matt335672/issue1768
Fix regressions in auth modules
2020-12-29 10:44:10 +00:00
matt335672
8205559959 Fix regressions in auth modules 2020-12-29 09:48:01 +00:00
metalefty
f24b7b7988
Merge pull request #1766 from metalefty/release
Release v0.9.15
2020-12-28 22:59:00 +09:00
Koichiro IWAO
114fc6eeaa
bump version to v0.9.15 2020-12-28 22:52:10 +09:00
Koichiro IWAO
11875fca2b
Update NEWS for v0.9.15 2020-12-28 22:51:12 +09:00
metalefty
a033cf0ea4
Merge pull request #1753 from aquesnel/fix_location_logging
Fixing code location log level filtering
2020-12-23 21:39:39 +09:00
matt335672
83b256294f
Merge pull request #1761 from kraj/riscv
riscv doesn't require pointers to be aligned
2020-12-23 09:40:39 +00:00
Khem Raj
9cd4acad49 riscv doesn't require pointers to be aligned
Signed-off-by: Khem Raj <raj.khem@gmail.com>
2020-12-22 23:12:06 -08:00
Khem Raj
d4e9b0f637 correct the location of errno.h
Fixes build on musl

Signed-off-by: Khem Raj <raj.khem@gmail.com>
2020-12-22 23:11:50 -08:00
Alexandre Quesnel
a4f3471707 Fixing code location log level filtering 2020-12-23 03:56:23 +00:00
metalefty
bba65b3592
Merge pull request #1738 from aquesnel/unify_logging_libxrdp
Unify logging in libxrdp
2020-12-23 09:59:21 +09:00
matt335672
aa5c5daf7e
Merge pull request #1703 from matt335672/issue1048-2
Allow FuseMountName for chansrv to be absolute path (#1048)
Move string funcs from os_calls.h to string_calls.h
2020-12-22 12:10:43 +00:00
matt335672
0a1a8f40e5 Moved a lot of string funcs to string_calls module 2020-12-22 11:57:24 +00:00
metalefty
183abaeb26
Merge pull request #1759 from aquesnel/patch-1
Fix typo in sesman.ini man page
2020-12-22 15:19:37 +09:00
aquesnel
4f4458c3a9
Fix typo in sesman.ini man page
The ChansrvLogging section name was added and changed in #1633 but this documentation line was missed when renaming the section name.
2020-12-21 11:43:24 -05:00
matt335672
5523847540 Allow FuseMountName for chansrv to be absolute path 2020-12-21 12:36:31 +00:00
metalefty
785db575ca
Merge pull request #1751 from matt335672/address-minor-user-comments
Cosmetic fixes for minor issues
2020-12-21 16:12:58 +09:00
metalefty
61fd63f028
Merge pull request #1756 from metalefty/delete-socket-files
sesman: address the issue of socket file leftovers
2020-12-21 13:49:20 +09:00
metalefty
835536b406
Merge pull request #1741 from matt335672/sesrun-improvements
sesrun improvements and doc fixes
2020-12-21 13:45:57 +09:00
Koichiro IWAO
31214f15a6
sesman: reflect review suggestions on cleanup_sockets
* Use LOG_LEVEL_WARNING for the deletion failure
* Log the error condition when the deletion failed
2020-12-21 13:28:53 +09:00
metalefty
5b73fb9c31
Merge pull request #1755 from metalefty/man
man page fixes after neutrinolabs/xorgxrdp#175
2020-12-19 14:03:49 +09:00
Koichiro IWAO
5114d1ee64 sesman: address the issue of socket file leftovers
There are two points.

Make sure cleanup files happen after chansrv and Xserver exit. If these
child processes lock socket files, the deletion might fail.

Usually, cleanup of xorgxrdp related socket files is handled by
xorgxrdp. Just in case it failed, perform cleanup also in sesman.

Fixes #1740. Thanks to @matt335672.

Sponsored by:   Cybertrust Japan
Sponsored by:   HAW International
2020-12-18 18:30:49 +09:00
Koichiro IWAO
6562c9d958 man page fixes after neutrinolabs/xorgxrdp#175 2020-12-18 15:21:21 +09:00
metalefty
87d710e89b
Merge pull request #1727 from RisingWater/devel
Update verify_user_pam.c
2020-12-17 16:15:43 +09:00
matt335672
c69a26e9b4 Addressed review comments 2020-12-15 10:55:26 +00:00
matt335672
7ddc43aeea Cosmetic fixes for minor issues 2020-12-14 11:35:31 +00:00
Alexandre Quesnel
121c17e818 Removing duplicate logging statements 2020-12-12 17:05:09 +00:00
matt335672
633716bbad sesrun improvements and doc fixes 2020-12-09 11:44:17 +00:00
matt335672
bfe76e0499
Merge pull request #1650 from matt335672/minus-c-option-sesman
Add -c/--config option to sesman
2020-12-09 10:31:11 +00:00
matt335672
e6c1df64d3 Added --config/-c to sesman 2020-12-09 10:19:14 +00:00
Alexandre Quesnel
a82ee03d4d Changing LOG_DEVEL to LOG to avoid silent failures. 2020-12-05 19:22:50 +00:00
matt335672
dd9f7c6092
Merge pull request #1711 from matt335672/standalone-logger
Add log_config_init_for_console() for utilities
2020-12-01 09:31:11 +00:00
matt335672
8d994a547d Add log_config_init_for_console() for utilities 2020-11-30 11:04:21 +00:00
Alexandre Quesnel
2d6d249f76 Fixing code formatting with astyle 2020-11-30 05:04:11 +00:00
Alexandre Quesnel
51905d765a Migrating logging to LOG() and LOG_DEVEL() in libxrdp/* 2020-11-30 05:04:10 +00:00
metalefty
28c35f962d
Merge pull request #1708 from aquesnel/unify_sesman_logging
Unify logging in sesman
2020-11-30 11:47:18 +09:00
Alexandre Quesnel
0c61a15fc5 Migrating logging to LOG() and LOG_DEVEL() in sesman/* 2020-11-30 00:36:20 +00:00
matt335672
19260cc90c
Merge pull request #1732 from aquesnel/gha_cache_cppcheck
Add caching of cppcheck to github action CI builds
2020-11-23 08:55:34 +00:00
Alexandre Quesnel
70ddd5074e Add caching of cppcheck to github action CI builds 2020-11-23 05:38:21 +00:00
metalefty
0d8e4146a2
Merge pull request #1728 from aquesnel/add_github_actions
Add GitHub actions
2020-11-20 14:11:23 +09:00
Alexandre Quesnel
a4cc8471ec Removing TravisCI builds 2020-11-19 15:21:42 +00:00
RisingWater
9efdd92c2a
Update verify_user_pam.c
change to g_memset
2020-11-19 11:03:43 +08:00
matt335672
d78d46187f
Merge pull request #1706 from matt335672/neutrinordp-flow-control2
Fix neutrinordp buffering. Addresses #1634 and #1608
2020-11-17 09:31:13 +00:00
Alexandre Quesnel
353e11caba Adding CI build using github actions 2020-11-17 05:49:39 +00:00
Alexandre Quesnel
9cb6bfc3a4 Fix SSL compiler warning 2020-11-17 05:46:36 +00:00
RisingWater
5d8f451a41
Update verify_user_pam.c
when a system give a tip message in function verify_pam_conv, authenticate will fail.
so it need skip this message to make sure authenticate success.
2020-11-17 11:48:26 +08:00
metalefty
f46e60b142
Merge pull request #1722 from jsorg71/build_old_gcc
build fix for older gcc
2020-11-17 09:04:24 +09:00
Jay Sorg
f3b47b33cd build fix for older gcc 2020-11-12 23:22:23 -08:00
D.V.Yacenko
a6a785d7a4
Allow parameters for XRDP run bash script
Allows run bash script with parameters on xrdp. For example rdesktop -s "myscript.sh params"
2020-10-22 16:12:55 +01:00
matt335672
0d00693e54
Merge pull request #1704 from robertoetcheverryr/devel
Updated man and .ini file regarding address:port parameters.
2020-10-21 09:28:27 +01:00
robertoetcheverryr
8270331646 Updated man and .ini file regarding address:port parameters. 2020-10-20 23:25:13 -03:00
Matt Burt
1f8bb57fd6 Improve source_info commenting and fix neutrino slow link 2020-10-20 09:55:17 +01:00
metalefty
176b4b15a2
Merge pull request #1702 from yifanjiang/devel
startwm.sh: Additionally support /usr/etc/X11/xdm/Xsession
2020-10-19 14:33:53 +09:00
metalefty
ddd14e05fb
Merge pull request #1633 from aquesnel/unify_chanserv_logging
Unify chanserv logging (2020-07)
2020-10-19 14:28:52 +09:00
Alexandre Quesnel
a9ec1ebd99 Unifying logging in chanserv
This commit adds:
* replace multiple logging macros with LOG and LOG_DEVEL
* logging configuration for chanserv
* logging configuration for console output
* logging configuration for per file or method log level filtering for
debug builds
* file, line, and method name in log message for debug builds
2020-10-19 05:10:47 +00:00
Yifan J
31a910a275 startwm.sh: Additionally support /usr/etc/X11/xdm/Xsession in SUSE
distributions

https://lists.opensuse.org/opensuse-factory/2019-08/msg00113.html
2020-10-19 09:35:03 +08:00
matt335672
19504da100
Merge pull request #1651 from matt335672/minus-c-option
Added -c /--config option to xrdp
2020-10-16 11:31:56 +01:00
matt335672
ebc21fe180 Added -c / --config to xrdp 2020-10-16 10:55:23 +01:00
matt335672
62befaa803
Merge pull request #1691 from FelixZhang/devel
genkeymap: Fix an array declaration conflict
2020-09-18 10:28:08 +01:00
Felix Zhang
b8d9c2ec50 genkeymap: Fix an array declaration conflict
The conflict on the size of xfree86_to_evdev between genkeymap.c and
evdev-map.c is causing build failures in openSUSE builds
2020-09-18 12:17:00 +08:00
matt335672
a70e4bc33f
Merge pull request #1686 from aquesnel/fuse_type_fix
Use a single type for the fuse file handle callback context
2020-09-16 11:07:01 +01:00
Alexandre Quesnel
12a0266f1e Use a single type for the fuse file handle callback context 2020-09-15 15:37:56 +00:00
metalefty
2e78a9d8a5
Merge pull request #1666 from aquesnel/build_ubuntu_focal
Adding a Travis CI build using Ubuntu Focal
2020-09-10 09:05:24 +09:00
matt335672
68f0fa7e4d
Merge pull request #1668 from bolkedebruin/enable_token_sso
Add support for token authentication
2020-09-09 10:10:13 +01:00
matt335672
79b88d7f30
Merge pull request #1635 from matt335672/minus-c-option-chansrv
chansrv improved config support
2020-09-09 09:59:43 +01:00
matt335672
60a2beb435
Merge pull request #1682 from aquesnel/issue1678
Fix warnings in chansrv_fuse.c on 32-bit platforms
2020-09-09 09:51:24 +01:00
Bolke de Bruin
0b82f19318 Improve documentation 2020-09-09 09:13:37 +02:00
Alexandre Quesnel
2e4a0bdddc Upgrading the OS for CI builds from Ubuntu 16.04 to 20.04 2020-09-09 02:11:22 +00:00
Alexandre Quesnel
840c0b8bcf Adding a Travis CI build using the Ubuntu Focal 2020-09-09 00:38:51 +00:00
Alexandre Quesnel
a7462404d5 Adding casts for narrowing to pointer width for issue #1678 2020-09-08 21:04:02 +00:00
Alexandre Quesnel
ec53a0398d Enabling fuse for 32-bit CI builds 2020-09-08 17:16:09 +00:00
matt335672
edda1b064d chansrv improved config support 2020-09-08 16:58:03 +01:00
matt335672
f2dda1e0bd
Merge pull request #1680 from matt335672/issue1679
Fix compilation warnings/errors in xrdp-neutrinordp.c
2020-09-07 10:01:35 +01:00
matt335672
23b58aeb70 Fix compilation warnings/errors in xrdp-neutrinordp.c 2020-09-07 09:38:23 +01:00
metalefty
f2d0a57a6b
Merge pull request #1675 from per-ok/patch-1
Update xrdp_keyboard.ini for Norwegian keyboards
2020-09-03 08:56:52 +09:00
Per Olav Kroka
f6a957851d
Update xrdp_keyboard.ini for Norwegian keyboards 2020-09-02 13:05:31 +02:00
matt335672
8b54de320c
Merge pull request #1659 from matt335672/issue1658
Fixed compiler warnings/errors about snprintf truncations in log.c
2020-09-02 10:44:29 +01:00
matt335672
61b9a42fc5 Fixed compiler warnings about snprintf truncations 2020-09-02 10:32:38 +01:00
metalefty
8822771169
Merge pull request #1662 from aquesnel/fix_chunk_assembly
Adding checks to prevent buffer overruns during data chunk re-assembly
2020-09-01 08:37:11 +09:00
metalefty
1469d659db
Merge pull request #1671 from metalefty/release
Bump version to v0.9.14
2020-08-31 15:02:51 +09:00
Koichiro IWAO
9ec6162a54
bump version to v0.9.14 2020-08-31 14:24:54 +09:00
Koichiro IWAO
b4ca302c05
Update NEWS for v0.9.14 2020-08-31 14:15:12 +09:00
Bolke de Bruin
a6a0e5e004 Allow domain name to be concatenated to username
If a server is multihomed (i.e. mutiple domains) the
users are identified by their domain name. This change
allows to concat the domain name to the username with
a specific separator.
2020-08-30 21:56:16 +02:00
Bolke de Bruin
b0bca1363e Add support for token authentication
This feature allows to embed a token in the username field. Tokens
are separated from the username by the ASCII field separator character
0x1F (unicode 0x001F).
2020-08-29 10:40:22 +02:00
Koichiro IWAO
d364e76ae8 Update NEWS for v0.9.13.1 2020-08-28 10:52:15 +09:00
metalefty
5dd0bb6cac
Merge pull request #1663 from RolKau/1663-dvp
Detect and setup Programmer Dvorak keyboard layout
2020-08-28 10:51:39 +09:00
Roland Kaufmann
a9eb5a17d2 Detect and setup Programmer Dvorak keyboard layout
This patch will add the keyboard layout identifier for the Programmer
Dvorak keyboard layout, so that if a Windows client has that layout
active, it will be mapped to the corresponding xkeyboard-config layout
in the X server.

An XFreeRDP client knows about this layout too, and will correspondingly
map it to the identifier given here, making the layout propagate
correctly through X-to-X connections as well.

To replicate the full Windows keyboard layout several options have to
be set as well as the main layout. To avoid having these options spill
over to other layouts that are dumped, the old settings are stored
before the dump and then restored afterwards.
2020-08-26 17:55:25 +02:00
matt335672
5835aefa1f
Merge pull request #1664 from matt335672/sesman-ini-comment-fix
Updated sesman.ini comment for Policy= in line with the manpage
2020-08-26 10:30:48 +01:00
matt335672
8bd7309d72 Updated sesman.ini comment for Policy= in line with the manpage 2020-08-26 10:04:33 +01:00
metalefty
76ac0600e4
Merge pull request #1653 from bolkedebruin/devel
Fix buffer len for client info
2020-08-24 13:15:01 +09:00
Alexandre Quesnel
33d9e1d5d7 Adding checks to prevent buffer overruns during data chunk re-assembly 2020-08-24 00:03:08 +00:00
Bolke de Bruin
e89f124afe Ensure copying of the whole username/password 2020-08-21 14:29:01 +02:00
Bolke de Bruin
4d7b916faf Improve description 2020-08-21 09:19:49 +02:00
Bolke de Bruin
47e1c5d359 Add description 2020-08-19 12:50:01 +02:00
bolkedebruin
5cd36c511c Set max character buffer len to 512 per MS specification
The MS specs determine that the character buffer lenngths
for usernames, domains, passwords, alternate shells, etc
can be up to 512 characters including the mandatory null
terminator.
2020-08-17 10:35:35 +02:00
metalefty
f3e42fc209
Merge pull request #1640 from aquesnel/build_debug_werror
Fixing the build with --enable-xrdpdebug and CFLAGS=-Werror -Wall
2020-08-11 14:01:52 +09:00
metalefty
5da9d70317
Merge pull request #1645 from aquesnel/compile_faq
Adding an FAQ entry for configuring Travis CI and Cirrus CI for a fork
2020-08-07 21:58:26 +09:00
metalefty
33ebd639b5
Merge pull request #1647 from metalefty/sesman
sesman.ini: Update Xorg path for CentOS 8
2020-08-03 13:49:16 +09:00
Koichiro IWAO
00dca40bf8
sesman.ini: Update Xorg path for CentOS 8
Closes #1646.
2020-08-03 10:39:04 +09:00
Alexandre Quesnel
b2fea42acf Adding an FAQ entry for configuring Travis CI and Cirrus CI for a fork 2020-08-01 04:32:29 +00:00
Alexandre Quesnel
7e58209b19 Fixing the build with --enable-xrdpdebug and CFLAGS=-Werror -Wall 2020-07-25 23:53:26 +00:00
metalefty
396b8ce890
Merge pull request #1623 from matt335672/travis-ci-errs
Fixed CVE-2020-4044 CI errors
2020-06-29 22:58:51 +09:00
matt335672
7384f6e574 Fixed CVE-2020-4044 CI errors 2020-06-29 11:38:24 +01:00
metalefty
0c791d073d
Merge pull request from GHSA-j9fv-6fwf-p3g4
Fix for CVE-2020-4044
2020-06-26 20:09:03 +09:00
matt335672
e593f58a82 Fix for CVE-2020-4044
Reported by: Ashley Newson
2020-06-26 20:06:02 +09:00
metalefty
dda748de8a
Merge pull request #1619 from neutrinolabs/security-policy
Create SECURITY.md
2020-06-25 17:48:52 +09:00
metalefty
0505d28138
Create SECURITY.md 2020-06-25 17:18:15 +09:00
metalefty
e679890083
Merge pull request #1613 from matt335672/cppcheck-2-1
Cppcheck 2.1
2020-06-22 20:42:57 +09:00
matt335672
27653f97f2 Code changes for cppcheck 2.1 warnings 2020-06-19 11:07:23 +01:00
matt335672
a57c68f55e Implement changes to support cppcheck 2.x 2020-06-19 11:06:41 +01:00
matt335672
3de8550f40
Merge pull request #1611 from matt335672/minor-man-fixes
Minor manpage fixes
2020-06-18 13:36:01 +01:00
matt335672
a2ca01fdf5 Minor manpage fixes 2020-06-18 12:23:32 +01:00
matt335672
f37d1ba46e
Merge pull request #1343 from matt335672/extended-vnc
Add resizeable backend VNC support
2020-06-04 15:36:00 +01:00
matt335672
3c4b42b1aa Implemented resize and multimon support for VNC backend 2020-06-04 15:10:35 +01:00
matt335672
1c99d0a366
Merge pull request #1595 from matt335672/reset-improvements
Prevent chansrv input channels being scanned during a server reset
2020-06-03 12:15:07 +01:00
matt335672
81e037e964 Prevent chansrv input channels being scanned during a server reset 2020-06-03 11:57:25 +01:00
matt335672
358f07d1c7
Merge pull request #1593 from matt335672/issue1569
Ignore TS_MULTIFRAGMENTUPDATE_CAPABILITYSET from client if fp disabled
2020-05-27 08:03:00 +01:00
matt335672
bfffc40cba Ignore TS_MULTIFRAGMENTUPDATE_CAPABILITYSET from client if fp disabled 2020-05-26 12:02:11 +01:00
metalefty
a618a67d4a
Merge pull request #1520 from qarmin/small_fixes
Small fixes found by static analyzers.
2020-05-08 15:27:18 +09:00
metalefty
cc384de392
Merge pull request #1549 from matt335672/hac425-1
Address possible memory out-of-bounds accesses on connect requests
2020-05-08 15:17:55 +09:00
metalefty
30248303a8
Merge pull request #1557 from matt335672/hac425-2
Check for overflow before g_malloc() calls
2020-05-05 02:49:57 +09:00
metalefty
2e9e7bae75
Merge pull request #1560 from matt335672/slack-support
Support Slackware with pam
2020-04-28 09:26:53 +09:00
matt335672
aa0dbbae15 Added CHANNEL_NAME_LEN to ms-rdpbcgr.h 2020-04-27 15:01:56 +01:00
matt335672
2ec9720612 mkpamrules now supports Slackware 2020-04-26 17:27:19 +01:00
matt335672
617283eb34 Remove unnecessary g_malloc() call 2020-04-24 11:27:36 +01:00
matt335672
7ef01f7b0c Address memory allocation overflow security issues 2020-04-23 17:29:06 +01:00
metalefty
21a4118c0b
Merge pull request #1522 from okhowang/odd-shift
workaround odd shift behaviour
2020-04-21 11:40:38 +09:00
matt335672
da3114007c Address possible memory out-of-bounds accesses 2020-04-15 09:57:05 +01:00
okhowang(王沛文)
f5164e8ff7 workaround odd shift behaviour 2020-04-07 14:10:37 +08:00
metalefty
1c4e14415d
Merge pull request #1529 from metalefty/xorg-path
Fix Xorg path for Arch Linux
2020-04-03 09:43:24 +09:00
Koichiro IWAO
1adb3c7b33
Fix Xorg path for Arch Linux
It has been moved: https://www.archlinux.org/packages/extra/x86_64/xorg-server/

Fixes: #1448
2020-04-02 16:18:06 +09:00
Rafał Mikrut
12c46664a2 Small fixes found by static analyzers. 2020-03-20 11:21:34 +01:00
metalefty
0a669c5b06
Merge pull request #1509 from metalefty/prepare-release
Prepare release
2020-03-11 13:28:54 +09:00
Koichiro IWAO
b3b1fff833
bump version to v0.9.13 2020-03-11 13:04:35 +09:00
Koichiro IWAO
6e7a539933
Update NEWS for v0.9.13 2020-03-11 12:58:01 +09:00
Koichiro IWAO
96cbde725d
README: gitter badge refer to xrdp-questions room 2020-03-11 10:38:20 +09:00
metalefty
a57e77753f
Merge pull request #1507 from matt335672/drive-redirect-fixes
Drive redirect fixes, including Guacamole
2020-03-11 09:33:24 +09:00
metalefty
d88dcee5bc
Merge pull request #1493 from matt335672/cppcheck-ci
Add cppcheck to travis-ci
2020-03-09 13:27:16 +09:00
matt335672
a2266f23f6 Allow a redirected drive device_id to be zero (Guacamole support) 2020-03-03 16:16:09 +00:00
matt335672
a3d429b4f7 Minor fixes to drive redirection 2020-03-03 16:14:24 +00:00
matt335672
2faf98ca61 Add cppcheck to travis-ci 2020-03-03 10:33:17 +00:00
metalefty
dc9a06f6ce
Merge pull request #1485 from matt335672/cppc-misc
misc: Fix cppcheck 1.82 + 1.90 warnings
2020-02-18 21:46:26 +09:00
metalefty
b859457187
Merge pull request #1481 from matt335672/cppc-chansrv-fuse
chansrv-fuse Fix cppcheck 1.89+1.90 warnings
2020-02-18 21:46:12 +09:00
matt335672
77686bf832 Fix cppcheck 1.89+1.90 warnings 2020-01-30 10:36:23 +00:00
metalefty
6d7cce3d34
Merge pull request #1484 from matt335672/cppc-chansrv-pcsc
xrdp_pcsc: Fix cppcheck 1.82 + 1.90 warnings
2020-01-30 10:28:36 +09:00
metalefty
f46034326a
Merge pull request #1487 from derekschrock/devel
Use g_free for xfs/g_xfs in xfs_delete_xfs_fs
2020-01-30 10:11:50 +09:00
Derek Schrock
72bece526b return from xfs_delete_xfs_fs if NULL 2020-01-27 21:15:09 -05:00
matt335672
5aca3aa847 Fix cppcheck warnings in vrplayer/ourinterface.cpp 2020-01-21 10:19:41 +00:00
metalefty
e37fdd8c6e
Merge pull request #1479 from matt335672/cppc-xrdp-cache
xrdp_cache: Fix cppcheck 1.89+1.90 warnings
2020-01-20 09:09:42 +09:00
matt335672
16c20dc6e3 misc: Fix cppcheck 1.82 + 1.90 warnings 2020-01-19 14:13:47 +00:00
matt335672
70d78dfb6f Fix cppcheck 1.82 + 1.90 warnings 2020-01-17 11:18:46 +00:00
metalefty
627da8da3e
Merge pull request #1470 from matt335672/rename-includes
Move MS-defined constants into separate includes
2020-01-16 15:01:18 +09:00
metalefty
7ac90b77aa
Merge pull request #1478 from okhowang/devel
support mousex button 8/9
2020-01-16 09:29:10 +09:00
matt335672
c954bfe9e3 Fix cppcheck 1.89+1.90 warnings 2020-01-15 12:57:33 +00:00
okhowang(王沛文)
32ef6ea3dd support mousex button 8/9 2020-01-14 18:04:06 +08:00
metalefty
ce3633b807
Merge pull request #1474 from metalefty/cirrus
FreeBSD CI: simplify CI test for a while
2020-01-08 16:33:41 +09:00
Koichiro IWAO
c99e54cbcb
FreeBSD CI: simplify CI test for a while
some tests are failing due to FreeBSD OpenSSL version change.
2020-01-08 09:49:24 +09:00
metalefty
e3e8ed0758
Merge pull request #1472 from metalefty/fflush
common: flush stream in g_deinit()
2020-01-08 09:34:31 +09:00
Koichiro IWAO
e8c845e78b
common: switch _exit to exit
mentioned in #1472.
2020-01-08 09:21:39 +09:00
metalefty
c766be4be4
Merge pull request #1469 from chipitsine/devel
sesman/chansrv/chansrv_fuse.c: resolve double free found by cppcheck
2020-01-07 19:53:11 +09:00
Koichiro IWAO
e928d8baf2
common: flush stream in g_deinit()
unless flushing stream before exitting, `xrdp --version | cat` will
show empty output.

Fixes #1471.
2020-01-07 19:24:17 +09:00
matt335672
6f881d47d3 Rationalise ms- constants
Constants from MS documents (MS-RDPBCGR etc) moved out of
common/xrdp_constants.h into includes named after the documents.

Similar includes moved from sesman/chansrv to the common area.
2020-01-06 15:46:37 +00:00
Ilya Shipitsin
00f17c3ffc sesman/chansrv/chansrv_fuse.c: resolve double free found by cppcheck
sesman/chansrv/chansrv_fuse.c:1719:9: error: Memory pointed to by 'full_path' is freed twice. [doubleFree]
2020-01-06 13:38:02 +05:00
metalefty
677056e3c2
Merge pull request #1464 from chipitsine/devel
xrdpvr/xrdpvr.c: remove redundant condition
2020-01-06 12:35:04 +09:00
metalefty
b4d51bc4f1
Merge pull request #1466 from metalefty/cirrus
Introduce FreeBSD CI
2020-01-04 14:39:08 +09:00
Koichiro IWAO
1c5a5e32a0
FreeBSD CI: switch to image_family, build with multiple SSL library 2020-01-02 22:39:12 +09:00
Koichiro IWAO
24ee0cfd78
FreeBSD CI: use security/openssl after recent ports update
See ports/UPDATING 20200101:
https://svnweb.freebsd.org/ports/head/UPDATING?view=markup
2020-01-02 22:27:24 +09:00
Koichiro IWAO
f11987ac04
FreeBSD CI: use pkg install -y instead of ASSUME_YES 2020-01-02 22:11:28 +09:00
metalefty
1ce50849ea
Merge pull request #1465 from metalefty/release
Release v0.9.12
2019-12-28 21:14:54 +09:00
Koichiro IWAO
dd047bb181
bump version to v0.9.12 2019-12-28 21:07:35 +09:00
Koichiro IWAO
dfac42b273
Update NEWS for v0.9.12 2019-12-28 21:07:13 +09:00
Ilya Shipitsin
7c959156a9 xrdpvr/xrdpvr.c: remove redundant condition
[xrdpvr/xrdpvr.c:918] -> [xrdpvr/xrdpvr.c:926]: (warning) Identical condition 'rv==0', second condition is always false
2019-12-27 19:02:28 +05:00
Koichiro IWAO
43f2b2290e
FreeBSD CI: perform CI test on 12 and 11 2019-12-24 13:17:50 +09:00
Koichiro IWAO
f9a1e617f4
Add FreeBSD CI by Cirrus CI 2019-12-24 13:17:47 +09:00
metalefty
de5a23325f
Merge pull request #1462 from matt335672/catalina-compile
Include file tidy-up
2019-12-23 23:00:42 +09:00
matt335672
3820d279e2 Added includes for C/POSIX types referenced in chansrv_fuse.h to chansrv_fuse.h 2019-12-22 12:37:38 +00:00
metalefty
93da7c0d3c
Merge pull request #1449 from matt335672/filesys-reimplement
Significant remote file system improvements
2019-12-13 14:11:38 +09:00
metalefty
e08890ddde
Merge pull request #1457 from metalefty/xrdpsh
remove unmaintained xrdp.sh
2019-12-12 15:04:34 +09:00
Koichiro IWAO
a20f99d3d1
Remove xrdp.sh from Makefile and document as well 2019-12-11 17:09:08 +09:00
Koichiro IWAO
5fc804c67d
remove unmaintained xrdp.sh
It is not maintained since it is added and outdated now.
2019-12-11 09:46:18 +09:00
matt335672
3ef2e7ce49 CI Fixes 2019-12-05 16:44:52 +00:00
matt335672
4d8f2b5a31 Significant remote file system improvements
- Reimplemented inode store in separate module chansrv_xfs.[hc]
- Allowed atimes and mtimes to be written to Windows side
- Mapped file user write bit to (inverted) Windows FILE_ATTRIBUTE_READONLY bit
- Mapped file user execute bit to Windows FILE_ATTRIBUTE_SYSTEM bit
- Implemented improved security for remotely mounted drives
- Implemented USB device removal, allowing hot-plug/remove of memory sticks
- Fixed pagefile.sys breaking Ubuntu file browser
- Fixed write offset bug
- Allowed renaming of open files
- Improved reported error codes
- Fixed various memory leaks
- Addressed valgrind errors related to struct fuse_file_info pointers.
2019-12-05 11:41:32 +00:00
metalefty
352107fc5f
Merge pull request #1319 from metalefty/sighup
xrdp: do not exit when caught SIGHUP
2019-11-21 18:42:52 +09:00
jsorg71
36fc802bd9
Merge pull request #1441 from Belinsky-L-V/accept-neg1-cid
make vsock config accept -1 for cid and port
2019-11-14 01:20:51 -08:00
metalefty
2b614d275e
Merge pull request #1442 from yifanjiang/devel
mkpamrules: Support openSUSE's usage of /usr/etc/pam.d to contain the pam configuration files.
2019-11-13 13:30:31 +09:00
Yifan J
732d663c70 mkpamrules: Support openSUSE's usage of /usr/etc/pam.d
to contain the pam configuration files:

https://lists.opensuse.org/opensuse-factory/2019-08/msg00113.html
2019-11-13 11:13:07 +08:00
Belinsky-L-V
a2fd7c09fa make vsock config accept -1 for cid and port
linux/vm_sockets.h defines VMADDR_CID_ANY and VMADDR_PORT_ANY (both
equal to -1U) for vsock cid and port respectively. This change aims to
add the capability to parse negative cid and port numbers for vsock from
the config and pass them to the kernel.

Allows for valid configurations such as "port=vsock://-1:3389" to be
correctly processed, but will parse port and cid inputs like "---1" to
"-", which should currently get silently turned into 0 by atoi inside
g_sck_vsock_bind_address. Inputs that do not contain "-" get parsed as
by xrdp_listen_parse_integer.
2019-11-12 23:59:49 +03:00
jsorg71
8e10f0820c
Merge pull request #1439 from jsorg71/xup_shm_fix
xup: fix for when shmem_id changes
2019-11-08 23:49:09 -08:00
Jay Sorg
e52a4fd0ae xup: fix for when shmem_id changes 2019-11-07 23:28:07 -08:00
jsorg71
8853809310
Merge pull request #1437 from jsorg71/refresh_rect
cleanup refresh rect and check stream bounds
2019-11-07 21:47:36 -08:00
Jay Sorg
0fbbc47092 cleanup refresh rect and check stream bounds 2019-11-07 02:03:57 +00:00
metalefty
c57e867a3b
Merge pull request #1393 from metalefty/chansrv-channels-not-allowed
xrdp: skip connecting to chansrv when no channels enabled
2019-11-06 15:58:37 +09:00
metalefty
1897f8159f
Merge pull request #1427 from jsorg71/rdpsnd_audin_off
default rdpsnd audin off, can enable with --enable-rdpsndaudin
2019-10-24 13:02:42 +09:00
Jay Sorg
d7b1f12d9b default rdpsnd audin off, can enable with --enable-rdpsndaudin 2019-10-22 22:48:15 -07:00
jsorg71
04f885189a
Merge pull request #1425 from jsorg71/sesman-startup
sesman: fix for sesman startup without startup script
2019-10-17 20:54:22 -07:00
Jay Sorg
351c92dfba sesman: fix for sesman startup without startup script 2019-10-16 13:53:22 -07:00
Koichiro IWAO
f37faca65b
xrdp: skip connecting to chansrv when no channels enabled 2019-08-22 17:20:19 +09:00
metalefty
1e4b03eb3c
Merge pull request #1390 from metalefty/rfxcodec
update rfxcodec to the latest release
2019-08-20 00:34:10 +09:00
metalefty
deebc30f58
Merge pull request #1389 from metalefty/prepare-release
NEWS: fix typo in version s/v1.9.11/v0.9.11/
2019-08-20 00:31:55 +09:00
Koichiro IWAO
f097b8028d
update submodule to the latest release 2019-08-20 00:25:07 +09:00
Koichiro IWAO
471d7f0b24
NEWS: fix typo in version s/v1.9.11/v0.9.11/ 2019-08-19 17:16:10 +09:00
metalefty
2999b694e6
Merge pull request #1388 from metalefty/prepare-release
Prepare release
2019-08-19 16:16:59 +09:00
Koichiro IWAO
a350292628
bump version to v0.9.11 2019-08-19 16:00:33 +09:00
Koichiro IWAO
6928caa3bd
Update NEWS for v0.9.11 release 2019-08-19 15:58:36 +09:00
metalefty
6b826d03c8
Merge pull request #1386 from metalefty/xrdp-ini
xrdp: reformat comments/descriptions in xrdp.ini
2019-08-19 15:38:58 +09:00
metalefty
5e6e5bd869
Merge pull request #1387 from metalefty/travis
travis: unbreak the build, libxfixed-dev is required at minimum
2019-08-19 15:33:23 +09:00
Koichiro IWAO
a49edd03aa
travis: unbreak the build, libxfixed-dev is required at minimum 2019-08-19 15:20:14 +09:00
Koichiro IWAO
bcb281707b
xrdp: reformat comments/descriptions in xrdp.ini 2019-08-19 14:20:32 +09:00
jsorg71
d977e7caaa
Merge pull request #1372 from jsorg71/check_term_xup
xup: check term event for more responsive shutdown
2019-07-11 21:04:19 -07:00
Jay Sorg
313abde4ea xup: check term event for more responsive shutdown 2019-07-10 20:52:57 -07:00
jsorg71
cc2f918cd4
Merge pull request #1369 from jsorg71/mic-drdynvc
implement [MS-RDPEAI], mstsc compatible audio input
2019-07-10 11:49:38 -07:00
Jay Sorg
cf67dd56bf chansrv: no logic change, fix typo 2019-07-10 11:18:07 -07:00
Jay Sorg
417bb71abf chansrv: env var to disable rdpsnd record 2019-07-08 22:45:58 -07:00
Jay Sorg
933394c6be chansrv: remove excessive logging 2019-07-08 22:40:31 -07:00
Jay Sorg
8aedd31762 chansrv: use rdpsnd record if supported, else try AUDIO_INPUT(MS-RDPEAI) 2019-07-08 22:03:27 -07:00
Jay Sorg
c5798df0bd chansrv: hook up audin 2019-07-08 18:25:59 -07:00
Jay Sorg
ae40ff27c8 chansrv: audin close should chose channel 2019-07-07 22:05:46 -07:00
Jay Sorg
a9a823b0da chansrv: audio in partial working 2019-07-04 23:52:18 -07:00
Jay Sorg
3c9241022a chansrv: add audin.c/h 2019-07-03 21:31:52 -07:00
jsorg71
f627b29633
Merge pull request #1366 from jsorg71/listen-list
Listen list
2019-07-02 23:58:23 -07:00
Jay Sorg
1ef47cbf0b xrdp: fix seg fault when fork on connect and disconnect 2019-07-02 21:02:09 -07:00
Jay Sorg
37ade1cb25 remove unused variable 2019-07-01 18:07:36 -07:00
Jay Sorg
ee65ccb31d use address for tcp:// and tcp6:// and vsock:// 2019-07-01 17:56:50 -07:00
Jay Sorg
f42e38125e xrdp: enable listen_test, other parameter fixes about listen_test 2019-07-01 00:53:11 -07:00
Jay Sorg
0bc7803eaa add TCP V4 and V6 only socket functions 2019-06-29 23:59:18 -07:00
Jay Sorg
d7bd6f726b xrdp: support old xrdp.ini port, use_vsock style 2019-06-27 09:09:34 -07:00
Jay Sorg
216ba3b4d4 xrdp: update xrdp.ini.in 2019-06-26 22:16:44 -07:00
Jay Sorg
e3f41da2cc xrdp: parsing for listeners 2019-06-26 22:16:43 -07:00
Jay Sorg
c236f665d2 xrdp: parsing for listeners 2019-06-26 22:16:43 -07:00
Jay Sorg
d6229df5a1 xrdp: work on trans list 2019-06-26 22:16:43 -07:00
Jay Sorg
bacd76f9a2 xrdp: change listen to list 2019-06-26 22:16:43 -07:00
jsorg71
054991dde2
Merge pull request #1363 from jsorg71/audio_behind
chansrv: don't let audio fall behind
2019-06-24 22:46:34 -07:00
Jay Sorg
e14ea4ff2e chansrv: drop g_sent_flag, not very useful and some clients skip acks 2019-06-23 20:52:55 -07:00
Jay Sorg
4ad9e48ff5 chansrv: don't let audio fall behind 2019-06-22 23:01:13 -07:00
Koichiro IWAO
fff61cbeca
xrdp: do not exit when caught SIGHUP 2019-03-29 09:27:29 +09:00
165 changed files with 17474 additions and 10258 deletions

19
.cirrus.yml Normal file
View 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
View 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

View File

@ -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
View File

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

View File

@ -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
View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,6 +24,7 @@
#include "arch.h"
#include "os_calls.h"
#include "string_calls.h"
#include "list.h"
#include "file.h"
#include "parse.h"

View File

@ -24,6 +24,7 @@
#include "arch.h"
#include "os_calls.h"
#include "string_calls.h"
#include "list.h"
/*****************************************************************************/

View File

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

View File

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

View File

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

View File

@ -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) \

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
# Process this file with autoconf to produce a configure script
AC_PREREQ(2.65)
AC_INIT([xrdp], [0.9.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

View File

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

View File

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

View File

@ -7,10 +7,11 @@
.SH "DESCRIPTION"
\fBxrdp\-chansrv\fR is the \fBxrdp\fR(8) channel server, which manages the Remote Desktop Protocol (RDP) sub-channels.
.PP
This program is only forked internally by \fBxrdp\-sesman\fP(8).
.br
.PP
Currently \fBxrdp\-chansrv\fP knows about the following channels:
.RE 8
.RS 8
.TP
.B cliprdr
Clipboard Redirection
@ -26,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

View File

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

View File

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

View File

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

View File

@ -4,7 +4,16 @@ xrdp\-sesman \- \fBxrdp\fR(8) session manager
.SH "SYNTAX"
.B xrdp\-sesman
.RB [ \-\-nodaemon | \-\-kill | \-\-help ]
\-\-kill
.br
.B xrdp\-sesman
\-\-help
.br
.B xrdp\-sesman
\-\-version
.br
.B xrdp\-sesman
[\-\-nodaemon] [\-\-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

View File

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

View File

@ -3,7 +3,17 @@
\fBxrdp\fR \- a Remote Desktop Protocol (RDP) server
.SH "SYNTAX"
xrdp [ \-\-nodaemon | \-\-kill | \-\-help ]
.B xrdp
\-\-kill
.br
.B xrdp
\-\-help
.br
.B xrdp
\-\-version
.br
.B xrdp
[\-\-nodaemon] [\-\-port port] [\-\-fork] [\-\-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

View File

@ -23,10 +23,6 @@ All options and values (except for file names and paths) are case insensitive, a
.SH "GLOBALS"
The options to be specified in the \fB[Globals]\fR section are the following:
.TP
\fBaddress\fP=\fIip address\fP
Specify xrdp listening address. If not specified, defaults to 0.0.0.0 (all interfaces).
.TP
\fBautorun\fP=\fIsession_name\fP
Section name for automatic login. If set and the client supplies valid
@ -115,11 +111,26 @@ Specify text passed to PAM when authentication failed. The maximum length is \fB
.TP
\fBport\fP=\fIport\fP
Specify TCP port to listen on for incoming connections.
The default for RDP is \fB3389\fP.
Specify TCP port and interface to listen on for incoming connections.
Specifying only the port means that xrdp will listen on all interfaces.
The default port for RDP is \fB3389\fP.
Multiple address:port instances must be separated by spaces or commas. Check the .ini file for examples.
Specifying interfaces requires said interfaces to be UP before xrdp starts.
.TP
\fBrequire_credentials\fP=\fI[true|false]\fP
If set to \fB1\fP, \fBtrue\fP or \fByes\fP, \fBxrdp\fP will scan the user name provided by the
client for the ASCII field separator character (0x1F). It will then copy over what is after the
separator as the password supplied by the user and treats it as autologon. If not specified,
defaults to \fBfalse\fP.
.TP
\domain_user_separator\fP=\separator\fP
If specified the domain name supplied by the client is appended to the username separated
by \fBseparator\fP.
.TP
\enable_token_login\fP=\fI[true|false]\fP
If set to \fB1\fP, \fBtrue\fP or \fByes\fP, \fBxrdp\fP requires clients to include username and
password initial connection phase. In other words, xrdp doesn't allow clients to show login
screen if set to true. If not specified, defaults to \fBfalse\fP.
@ -231,6 +242,18 @@ If set to \fB1\fR, \fBtrue\fR or \fByes\fR this option enables logging to syslog
\fBSyslogLevel\fR=\fIlevel\fR
This option sets the logging level for syslog. It can have the same values of \fBLogLevel\fR. If \fBSyslogLevel\fR is greater than \fBLogLevel\fR, its value is lowered to that of \fBLogLevel\fR.
.TP
\fBEnableConsole\fR=\fI[true|false]\fR
If set to \fB1\fR, \fBtrue\fR or \fByes\fR, this option enables logging to the console (ie. stdout).
.TP
\fBConsoleLevel\fR=\fIlevel\fR
Logging level for the console. It can have the same values as \fBLogLevel\fR. Defaults to \fBDEBUG\fR.
.TP
\fBEnableProcessId\fR=\fI[true|false]\fR
If set to \fB1\fR, \fBtrue\fR or \fByes\fR, this option enables logging the process id in all log messages. Defaults to \fBfalse\fR.
.SH "CHANNELS"
The Remote Desktop Protocol supports several channels, which are used to transfer additional data like sound, clipboard data and others.
Channel names not listed here will be blocked by \fBxrdp\fP.
@ -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

View File

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

View File

@ -30,7 +30,6 @@ default build will install the following
startwm.sh
xrdp.ini
xrdp_keyboard.ini
xrdp.sh
/etc/xrdp/pulse
default.pa

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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");
}
}

View File

@ -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++)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,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"));
}

View File

@ -24,6 +24,7 @@
#include "defines.h"
#include "xrdp_rail.h"
#include "xrdp_client_info.h"
#include "xrdp_constants.h"
/* this is the freerdp main header */
#include <freerdp/freerdp.h>
@ -60,6 +61,8 @@ struct pointer_item
#define CURRENT_MOD_VER 4
struct source_info;
struct mod
{
int size; /* size of this struct */
@ -182,7 +185,7 @@ struct mod
tintptr handle; /* pointer to self as long */
tintptr wm;
tintptr painter;
tintptr si;
struct source_info *si;
/* mod data */
int sck;
@ -196,9 +199,9 @@ struct mod
int vmaj;
int vmin;
int vrev;
char username[256];
char password[256];
char domain[256];
char username[INFO_CLIENT_MAX_CB_LEN];
char password[INFO_CLIENT_MAX_CB_LEN];
char domain[INFO_CLIENT_MAX_CB_LEN];
int bool_keyBoardSynced ; /* Numlock can be out of sync, we hold state here to resolve */
int keyBoardLockInfo ; /* Holds initial numlock capslock state */

159
scripts/install_cppcheck.sh Executable file
View 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

View File

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

View File

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

58
scripts/run_cppcheck.sh Executable file
View 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 "$@"
}

View File

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

View File

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

View File

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

View File

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

View File

@ -39,19 +39,6 @@ int send_rail_drawing_orders(char* data, int size);
int main_cleanup(void);
int add_timeout(int msoffset, void (*callback)(void* data), void* data);
#define LOG_LEVEL 5
#define LOG(_a, _params) \
{ \
if (_a < LOG_LEVEL) \
{ \
g_write("xrdp-chansrv [%10.10u]: ", g_time3()); \
g_writeln _params ; \
} \
}
#define LOGM(_args) do { log_message _args ; } while (0)
#ifndef GSET_UINT8
#define GSET_UINT8(_ptr, _offset, _data) \
*((unsigned char*) (((unsigned char*)(_ptr)) + (_offset))) = (unsigned char)(_data)

View File

@ -0,0 +1,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);
}
}

View 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

View File

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

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

View 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

View File

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

View File

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

View File

@ -16,7 +16,7 @@
* limitations under the License.
*/
/* FIFO implementation to store a pointer to a user struct */
/* FIFO implementation to store a pointer to a user struct */
/* module based logging */
#if defined(HAVE_CONFIG_H)
@ -26,8 +26,8 @@
#define MODULE_NAME "FIFO "
#define LOCAL_DEBUG
#include "chansrv.h"
#include "fifo.h"
#include "mlog.h"
#include "os_calls.h"
/**
@ -39,19 +39,21 @@
* @return 0 on success, -1 on failure
*****************************************************************************/
int
fifo_init(FIFO* fp, int num_entries)
fifo_init(FIFO *fp, int num_entries)
{
log_debug_high("entered");
LOG_DEVEL(LOG_LEVEL_TRACE, "entered");
/* validate params */
if (!fp)
{
log_debug_high("invalid parameters");
LOG_DEVEL(LOG_LEVEL_TRACE, "invalid parameters");
return -1;
}
if (num_entries < 1)
{
num_entries = 10;
}
fp->rd_ptr = 0;
fp->wr_ptr = 0;
@ -60,13 +62,13 @@ fifo_init(FIFO* fp, int num_entries)
if (fp->user_data)
{
fp->entries = num_entries;
log_debug_low("FIFO created; rd_ptr=%d wr_ptr=%d entries=%d",
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];
}

View File

@ -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 ---");
}

View File

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

View File

@ -1,112 +0,0 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Laxmikant Rashinkar 2013 LK.Rashinkar@gmail.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* module based logging */
#ifndef _MLOG_H
#define _MLOG_H
/*
* Note1: to enable debug messages, in your .c file, #define LOCAL_DEBUG
* BEFORE including this file
*
* Note2: in your .c file, #define MODULE_NAME, 8 chars long, to print each
* log entry with your module name
*/
#define LOG_ERROR 0
#define LOG_INFO 1
#define LOG_DEBUG_LOW 2
#define LOG_DEBUG_HIGH 3
#define LOG_LEVEL LOG_ERROR
/*
* print always
*/
#define log_error(_params...) \
do \
{ \
g_write("[%10.10u]: %s %s: %d: ERROR: ", g_time3(), \
MODULE_NAME, __func__, __LINE__); \
g_writeln (_params); \
} \
while(0)
#define log_always(_params...) \
do \
{ \
g_write("[%10.10u]: %s %s: %d: ALWAYS: ", g_time3(), \
MODULE_NAME, __func__, __LINE__); \
g_writeln (_params); \
} \
while(0)
/*
* print conditionally
*/
#ifdef LOCAL_DEBUG
#define log_info(_params...) \
do \
{ \
if (LOG_INFO <= LOG_LEVEL) \
{ \
g_write("[%10.10u]: %s %s: %d: INFO: ", g_time3(), \
MODULE_NAME, __func__, __LINE__); \
g_writeln (_params); \
} \
} \
while(0)
#else
#define log_info(_params...)
#endif
#ifdef LOCAL_DEBUG
#define log_debug_low(_params...) \
do \
{ \
if (LOG_DEBUG_LOW <= LOG_LEVEL) \
{ \
g_write("[%10.10u]: %s %s: %d: DEBUG: ", g_time3(), \
MODULE_NAME, __func__, __LINE__); \
g_writeln (_params); \
} \
} \
while(0)
#else
#define log_debug_low(_params...)
#endif
#ifdef LOCAL_DEBUG
#define log_debug_high(_params...) \
do \
{ \
if (LOG_DEBUG_HIGH <= LOG_LEVEL) \
{ \
g_write("[%10.10u]: %s %s: %d: DEBUG: ", g_time3(), \
MODULE_NAME, __func__, __LINE__); \
g_writeln (_params); \
} \
} \
while(0)
#else
#define log_debug_high(_params...)
#endif
#endif /* #ifndef _MLOG_H */

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