Browse Source

New upstream version 0.9.15

tags/upstream/0.9.15^0
Dominik George 3 months ago
parent
commit
497e2fdc5b
100 changed files with 5550 additions and 2644 deletions
  1. +25
    -17
      Makefile.in
  2. +108
    -1
      NEWS.md
  3. +2
    -2
      README.md
  4. +63
    -29
      aclocal.m4
  5. +10
    -1
      common/Makefile.am
  6. +22
    -9
      common/Makefile.in
  7. +2
    -1
      common/arch.h
  8. +1
    -1
      common/base64.c
  9. +3
    -0
      common/defines.h
  10. +1
    -0
      common/file.c
  11. +1
    -0
      common/list.c
  12. +596
    -134
      common/log.c
  13. +220
    -27
      common/log.h
  14. +11
    -12
      common/ms-erref.h
  15. +0
    -0
      common/ms-fscc.h
  16. +512
    -0
      common/ms-rdpbcgr.h
  17. +0
    -2
      common/ms-rdpefs.h
  18. +59
    -0
      common/ms-rdpegdi.h
  19. +36
    -0
      common/ms-rdpele.h
  20. +31
    -0
      common/ms-rdperp.h
  21. +0
    -0
      common/ms-smb2.h
  22. +15
    -510
      common/os_calls.c
  23. +1
    -21
      common/os_calls.h
  24. +8
    -0
      common/pixman-region.c
  25. +5
    -1
      common/ssl_calls.c
  26. +653
    -0
      common/string_calls.c
  27. +104
    -0
      common/string_calls.h
  28. +7
    -9
      common/trans.c
  29. +35
    -8
      common/trans.h
  30. +10
    -5
      common/xrdp_client_info.h
  31. +15
    -570
      common/xrdp_constants.h
  32. +3
    -3
      compile
  33. +540
    -286
      configure
  34. +55
    -24
      configure.ac
  35. +1
    -1
      depcomp
  36. +2
    -2
      docs/Makefile.in
  37. +2
    -2
      docs/man/Makefile.in
  38. +72
    -14
      docs/man/sesman.ini.5.in
  39. +19
    -5
      docs/man/xrdp-chansrv.8.in
  40. +2
    -2
      docs/man/xrdp-dis.1.in
  41. +27
    -5
      docs/man/xrdp-sesman.8.in
  42. +62
    -15
      docs/man/xrdp-sesrun.8.in
  43. +22
    -4
      docs/man/xrdp.8.in
  44. +37
    -6
      docs/man/xrdp.ini.5.in
  45. +22
    -0
      faq-compile.txt
  46. +2
    -2
      genkeymap/Makefile.in
  47. +6
    -0
      genkeymap/dump-keymaps.sh
  48. +2
    -2
      genkeymap/genkeymap.c
  49. +92
    -69
      install-sh
  50. +2
    -1
      instfiles/Makefile.am
  51. +4
    -3
      instfiles/Makefile.in
  52. +2
    -2
      instfiles/default/Makefile.in
  53. +2
    -2
      instfiles/init.d/Makefile.in
  54. +1047
    -0
      instfiles/km-19360409.ini
  55. +2
    -2
      instfiles/pam.d/Makefile.in
  56. +58
    -22
      instfiles/pam.d/mkpamrules
  57. +15
    -4
      instfiles/pam.d/xrdp-sesman.unix
  58. +2
    -2
      instfiles/pulse/Makefile.in
  59. +2
    -2
      instfiles/rc.d/Makefile.in
  60. +2
    -2
      keygen/Makefile.in
  61. +1
    -0
      keygen/keygen.c
  62. +25
    -17
      libpainter/Makefile.in
  63. +26
    -29
      libpainter/aclocal.m4
  64. +3
    -3
      libpainter/compile
  65. +4
    -7
      libpainter/configure
  66. +1
    -1
      libpainter/depcomp
  67. +2
    -2
      libpainter/include/Makefile.in
  68. +9
    -9
      libpainter/include/painter.h
  69. +92
    -69
      libpainter/install-sh
  70. +1
    -1
      libpainter/missing
  71. +2
    -2
      libpainter/pkgconfig/Makefile.in
  72. +2
    -2
      libpainter/src/Makefile.in
  73. +36
    -20
      libpainter/src/painter_utils.c
  74. +54
    -54
      libpainter/src/painter_utils.h
  75. +2
    -2
      libpainter/tests/Makefile.in
  76. +26
    -17
      librfxcodec/Makefile.in
  77. +26
    -29
      librfxcodec/aclocal.m4
  78. +3
    -3
      librfxcodec/compile
  79. +6
    -9
      librfxcodec/configure
  80. +1
    -1
      librfxcodec/depcomp
  81. +2
    -2
      librfxcodec/include/Makefile.in
  82. +92
    -69
      librfxcodec/install-sh
  83. +1
    -1
      librfxcodec/missing
  84. +2
    -2
      librfxcodec/src/Makefile.in
  85. +2
    -2
      librfxcodec/src/amd64/Makefile.in
  86. +4
    -4
      librfxcodec/src/amd64/rfxencode_tile_amd64.c
  87. +39
    -39
      librfxcodec/src/rfx_bitstream.h
  88. +41
    -41
      librfxcodec/src/rfxcommon.h
  89. +6
    -6
      librfxcodec/src/rfxencode.h
  90. +7
    -7
      librfxcodec/src/rfxencode_alpha.c
  91. +46
    -46
      librfxcodec/src/rfxencode_diff_rlgr1.c
  92. +46
    -46
      librfxcodec/src/rfxencode_diff_rlgr3.c
  93. +2
    -2
      librfxcodec/src/rfxencode_quantization.c
  94. +63
    -63
      librfxcodec/src/rfxencode_rlgr1.c
  95. +63
    -63
      librfxcodec/src/rfxencode_rlgr3.c
  96. +2
    -2
      librfxcodec/src/x86/Makefile.in
  97. +2
    -2
      librfxcodec/tests/Makefile.in
  98. +2
    -2
      libxrdp/Makefile.in
  99. +143
    -124
      libxrdp/libxrdp.c
  100. +1
    -0
      libxrdp/libxrdp.h

+ 25
- 17
Makefile.in View File

@@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.16.1 from Makefile.am.
# Makefile.in generated by automake 1.16.3 from Makefile.am.
# @configure_input@

# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# Copyright (C) 1994-2020 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -145,8 +145,8 @@ am__recursive_targets = \
$(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
cscope distdir distdir-am dist dist-all distcheck
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
$(LISP)config_ac-h.in
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
config_ac-h.in
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
@@ -210,6 +210,8 @@ am__relativize = \
DIST_ARCHIVES = $(distdir).tar.gz
GZIP_ENV = --best
DIST_TARGETS = dist-gzip
# Exists only to be overridden by the user if desired.
AM_DISTCHECK_DVI_TARGET = dvi
distuninstallcheck_listfiles = find . -type f -print
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
@@ -660,6 +662,10 @@ dist-xz: distdir
tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
$(am__post_remove_distdir)

dist-zstd: distdir
tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
$(am__post_remove_distdir)

dist-tarZ: distdir
@echo WARNING: "Support for distribution archives compressed with" \
"legacy program 'compress' is deprecated." >&2
@@ -702,6 +708,8 @@ distcheck: dist
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
*.tar.zst*) \
zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
esac
chmod -R a-w $(distdir)
chmod u+w $(distdir)
@@ -717,7 +725,7 @@ distcheck: dist
$(DISTCHECK_CONFIGURE_FLAGS) \
--srcdir=../.. --prefix="$$dc_install_base" \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
@@ -879,18 +887,18 @@ uninstall-am:
am--refresh check check-am clean clean-cscope clean-generic \
clean-libtool cscope cscopelist-am ctags ctags-am dist \
dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
dist-xz dist-zip distcheck distclean distclean-generic \
distclean-hdr distclean-libtool distclean-local distclean-tags \
distcleancheck distdir distuninstallcheck dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs installdirs-am maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
uninstall-am
dist-xz dist-zip dist-zstd distcheck distclean \
distclean-generic distclean-hdr distclean-libtool \
distclean-local distclean-tags distcleancheck distdir \
distuninstallcheck dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
installdirs-am maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags tags-am uninstall uninstall-am

.PRECIOUS: Makefile



+ 108
- 1
NEWS.md View File

@@ -1,3 +1,110 @@
# Release notes for xrdp v0.9.15 (2020/12/28)

## New features
* Allow token sign in without autologon for SSO (#1667 #1668)
* Norwegian keyboard support (#1675)
* Improved config support for chansrv (#1635)
* Unified chansrv, sesman and libxrdp logging (#1633 #1708 #1738) - thanks to @aquesnel
* Support SUSE move to /usr/etc (#1702)
* Parameters may now be specified for user-specified shell (#1270 #1695)
* xrdp executables now allow alternative config files to be specified with -c (#1588 #1650 #1651)
* sesrun improvements (#1741)
* Drive redirection location can now be specified (#1048)
* Now compiles on RISC-V (#1761)

## Bug fixes
* Additional buffer overflow checks (#1662)
* FUSE support now builds on 32-bit platforms (#1682)
* genkeymap array size conflict fixed (#1691)
* Buffering issue with neutrinordp over a slow link fixed (#1608 1634)
* Various documentation fixes (#1704 #1741 #1755 #1759)
* Prevent PAM info message from causing authentication failure (#1727)
* Cosmetic fixes for minor issues (#1751 #1755 #1749)
* Try harder to clean up socket files on session exit (#1740 #1756)
* xrdp-chansrv become defunct in docker while file copy (#1658)

## Internal changes
* Compilation warnings with newer compilers (#1659 #1680)
* Continuation Integration checks on 32-bit platforms now include FUSE support (#1682)
* Continuation Integration builds now default to the Ubuntu Focal platform (#1666)
* FUSE type tidy-ups (#1686)
* Switch from Travis CI to GitHub Actions (#1728 #1732)
* Easier to set up console logging for utilities (#1711)

-----------------------

# Release notes for xrdp v0.9.14 (2020/08/31)

## New features
* VNC multi-monitor support if you are using a suitable Xvnc server #1343
* VNC sessions now resize by default on reconnection if you are using a suitable Xvnc server #1343
* Support Slackware for PAM #1558 #1560
* Support Programmer Dvorak Keyboard #1663

**[HEADS UP]** The VNC changes are significant. They described in more detail on the following wiki page.
* [Xvnc backend : Multi monitor and resize support](https://github.com/neutrinolabs/xrdp/wiki/Xvnc-backend-:-Multi-monitor-and-resize-support)

## Bug fixes
* Fix odd shift key behavior (workaround) #397 #1522
* Fix Xorg path in the document for Arch Linux #1448 #1529
* Fix Xorg path in the document for CentOS 8 #1646 #1647
* Fix internal username/password buffer is smaller than RDP protocol specification #1648 #1653
* Fix possible memory out-of-bounds accesses #1549
* Fix memory allocation overflow #1557
* Prevent chansrv input channels being scanned during a server reset #1595
* Ignore TS_MULTIFRAGMENTUPDATE_CAPABILITYSET from client if fp disabled #1593
* Minor manpage fixes #1611

## Other changes
* CI error fixes
* Introduce cppcheck

## Known issues
* FreeRDP 2.0.0-rc4 or later might not able to connect to xrdp due to
xrdp's bad-mannered behaviour, add `+glyph-cache` option to FreeRDP to connect #1266
* Audio redirection by MP3 codec doesn't sound with some client, use AAC instead #965

# Release notes for xrdp v0.9.13.1 (2020/06/30)

This is a security fix release that includes fixes for the following local buffer overflow vulnerability.

* [CVE-2022-4044: Local users can perform a buffer overflow attack against the xrdp-sesman service and then impersonate it](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-4044)

This update is recommended for all xrdp users.

## Special thanks

Thanks to [Ashley Newson](https://github.com/ashleynewson) reporting the vulnerability and reviewing fix.

-----------------------

# Release notes for xrdp v0.9.13 (2020/03/11)

This release is an intermediate bugfix release. The previous version v0.9.12 has some regressions on drive redirection.

## Bug fixes (drive redirection related)
* Fix chansrv crashes with segmentation fault (regression in #1449) #1487
* Drive redirection now supports Guacamole client #1505 #1507
* Prevent a coredump in the event of a corrupted file system #1507
* Resolve double-free in `chansrv_fuse` #1469

## Bug fixes (other)
* Fix the issue `xrdp --version | less` will show empty output #1471 #1472
* Fix some warnings found by cppcheck #1479 #1481 #1484 #1485

## Other changes
* Add FreeBSD CI test #1466
* Move Microsoft-defined constants into separate includes #1470
* Perform cppcheck during CI test #1493
* Support mousex button 8/9 #1478

## Known issues
* FreeRDP 2.0.0-rc4 or later might not able to connect to xrdp due to
xrdp's bad-mannered behaviour, add `+glyph-cache` option to FreeRDP to connect #1266
* Audio redirection by MP3 codec doesn't sound with some client, use AAC instead #965

-----------------------

# Release notes for xrdp v0.9.12 (2019/12/28)

## Bug fixes
@@ -84,7 +191,7 @@ Thank you for matt335672 contributing to lots of improvements in drive redirecti

-----------------------

## Release notes for xrdp v0.9.9 (2018/12/25)
# Release notes for xrdp v0.9.9 (2018/12/25)

## Release cycle
From the next release, release cycle will be changed from quarterly to every


+ 2
- 2
README.md 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.12
*Current Version:* 0.9.15

# xrdp - an open source RDP server



+ 63
- 29
aclocal.m4 View File

@@ -1,6 +1,6 @@
# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
# generated automatically by aclocal 1.16.3 -*- Autoconf -*-

# Copyright (C) 1996-2018 Free Software Foundation, Inc.
# Copyright (C) 1996-2020 Free Software Foundation, Inc.

# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically 'autoreconf'.])])

# Copyright (C) 2002-2018 Free Software Foundation, Inc.
# Copyright (C) 2002-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -35,7 +35,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.16'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
m4_if([$1], [1.16.1], [],
m4_if([$1], [1.16.3], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])

@@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.16.1])dnl
[AM_AUTOMAKE_VERSION([1.16.3])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])

# AM_AUX_DIR_EXPAND -*- Autoconf -*-

# Copyright (C) 2001-2018 Free Software Foundation, Inc.
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -108,9 +108,46 @@ AC_DEFUN([AM_AUX_DIR_EXPAND],
am_aux_dir=`cd "$ac_aux_dir" && pwd`
])

# AM_COND_IF -*- Autoconf -*-

# Copyright (C) 2008-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.

# _AM_COND_IF
# _AM_COND_ELSE
# _AM_COND_ENDIF
# --------------
# These macros are only used for tracing.
m4_define([_AM_COND_IF])
m4_define([_AM_COND_ELSE])
m4_define([_AM_COND_ENDIF])

# AM_COND_IF(COND, [IF-TRUE], [IF-FALSE])
# ---------------------------------------
# If the shell condition COND is true, execute IF-TRUE, otherwise execute
# IF-FALSE. Allow automake to learn about conditional instantiating macros
# (the AC_CONFIG_FOOS).
AC_DEFUN([AM_COND_IF],
[m4_ifndef([_AM_COND_VALUE_$1],
[m4_fatal([$0: no such condition "$1"])])dnl
_AM_COND_IF([$1])dnl
if test -z "$$1_TRUE"; then :
m4_n([$2])[]dnl
m4_ifval([$3],
[_AM_COND_ELSE([$1])dnl
else
$3
])dnl
_AM_COND_ENDIF([$1])dnl
fi[]dnl
])

# AM_CONDITIONAL -*- Autoconf -*-

# Copyright (C) 1997-2018 Free Software Foundation, Inc.
# Copyright (C) 1997-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -141,7 +178,7 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])

# Copyright (C) 1999-2018 Free Software Foundation, Inc.
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -332,7 +369,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl

# Generate code to set up dependency tracking. -*- Autoconf -*-

# Copyright (C) 1999-2018 Free Software Foundation, Inc.
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -371,7 +408,9 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
done
if test $am_rc -ne 0; then
AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
for automatic dependency tracking. Try re-running configure with the
for automatic dependency tracking. If GNU make was not used, consider
re-running the configure script with MAKE="gmake" (or whatever is
necessary). You can also try re-running configure with the
'--disable-dependency-tracking' option to at least be able to build
the package (albeit without support for automatic dependency tracking).])
fi
@@ -398,7 +437,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],

# Do all the work for Automake. -*- Autoconf -*-

# Copyright (C) 1996-2018 Free Software Foundation, Inc.
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -595,7 +634,7 @@ for _am_header in $config_headers :; do
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])

# Copyright (C) 2001-2018 Free Software Foundation, Inc.
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -616,7 +655,7 @@ if test x"${install_sh+set}" != xset; then
fi
AC_SUBST([install_sh])])

# Copyright (C) 2003-2018 Free Software Foundation, Inc.
# Copyright (C) 2003-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -637,7 +676,7 @@ AC_SUBST([am__leading_dot])])

# Check to see how 'make' treats includes. -*- Autoconf -*-

# Copyright (C) 2001-2018 Free Software Foundation, Inc.
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -680,7 +719,7 @@ AC_SUBST([am__quote])])

# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-

# Copyright (C) 1997-2018 Free Software Foundation, Inc.
# Copyright (C) 1997-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -701,12 +740,7 @@ AC_DEFUN([AM_MISSING_HAS_RUN],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
AC_REQUIRE_AUX_FILE([missing])dnl
if test x"${MISSING+set}" != xset; then
case $am_aux_dir in
*\ * | *\ *)
MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
*)
MISSING="\${SHELL} $am_aux_dir/missing" ;;
esac
MISSING="\${SHELL} '$am_aux_dir/missing'"
fi
# Use eval to expand $SHELL
if eval "$MISSING --is-lightweight"; then
@@ -719,7 +753,7 @@ fi

# Helper functions for option handling. -*- Autoconf -*-

# Copyright (C) 2001-2018 Free Software Foundation, Inc.
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -748,7 +782,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])

# Copyright (C) 1999-2018 Free Software Foundation, Inc.
# Copyright (C) 1999-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -795,7 +829,7 @@ AC_LANG_POP([C])])
# For backward compatibility.
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])

# Copyright (C) 2001-2018 Free Software Foundation, Inc.
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -814,7 +848,7 @@ AC_DEFUN([AM_RUN_LOG],

# Check to make sure that the build environment is sane. -*- Autoconf -*-

# Copyright (C) 1996-2018 Free Software Foundation, Inc.
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -895,7 +929,7 @@ AC_CONFIG_COMMANDS_PRE(
rm -f conftest.file
])

# Copyright (C) 2009-2018 Free Software Foundation, Inc.
# Copyright (C) 2009-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -955,7 +989,7 @@ AC_SUBST([AM_BACKSLASH])dnl
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
])

# Copyright (C) 2001-2018 Free Software Foundation, Inc.
# Copyright (C) 2001-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -983,7 +1017,7 @@ fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])

# Copyright (C) 2006-2018 Free Software Foundation, Inc.
# Copyright (C) 2006-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -1002,7 +1036,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])

# Check how to create a tarball. -*- Autoconf -*-

# Copyright (C) 2004-2018 Free Software Foundation, Inc.
# Copyright (C) 2004-2020 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,


+ 10
- 1
common/Makefile.am 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 \


+ 22
- 9
common/Makefile.in View File

@@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.16.1 from Makefile.am.
# Makefile.in generated by automake 1.16.3 from Makefile.am.
# @configure_input@

# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# Copyright (C) 1994-2020 Free Software Foundation, Inc.

# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -146,12 +146,13 @@ libcommon_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
am__libcommon_la_SOURCES_DIST = arch.h base64.h base64.c defines.h \
fifo.c fifo.h file.c file.h list.c list.h list16.c list16.h \
log.c log.h os_calls.c os_calls.h parse.h rail.h ssl_calls.c \
ssl_calls.h thread_calls.c thread_calls.h trans.c trans.h \
pixman-region16.c pixman-region.h
ssl_calls.h string_calls.c string_calls.h thread_calls.c \
thread_calls.h trans.c trans.h pixman-region16.c \
pixman-region.h
@XRDP_PIXMAN_FALSE@am__objects_1 = pixman-region16.lo
am_libcommon_la_OBJECTS = base64.lo fifo.lo file.lo list.lo list16.lo \
log.lo os_calls.lo ssl_calls.lo thread_calls.lo trans.lo \
$(am__objects_1)
log.lo os_calls.lo ssl_calls.lo string_calls.lo \
thread_calls.lo trans.lo $(am__objects_1)
libcommon_la_OBJECTS = $(am_libcommon_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -176,8 +177,8 @@ am__depfiles_remade = ./$(DEPDIR)/base64.Plo ./$(DEPDIR)/fifo.Plo \
./$(DEPDIR)/file.Plo ./$(DEPDIR)/list.Plo \
./$(DEPDIR)/list16.Plo ./$(DEPDIR)/log.Plo \
./$(DEPDIR)/os_calls.Plo ./$(DEPDIR)/pixman-region16.Plo \
./$(DEPDIR)/ssl_calls.Plo ./$(DEPDIR)/thread_calls.Plo \
./$(DEPDIR)/trans.Plo
./$(DEPDIR)/ssl_calls.Plo ./$(DEPDIR)/string_calls.Plo \
./$(DEPDIR)/thread_calls.Plo ./$(DEPDIR)/trans.Plo
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -373,6 +374,14 @@ top_srcdir = @top_srcdir@
@XRDP_PIXMAN_TRUE@PIXMAN_SOURCES =
EXTRA_DIST = pixman-region.c
include_HEADERS = \
ms-erref.h \
ms-fscc.h \
ms-rdpbcgr.h \
ms-rdpefs.h \
ms-rdpegdi.h \
ms-rdpele.h \
ms-rdperp.h \
ms-smb2.h \
xrdp_client_info.h \
xrdp_constants.h \
xrdp_rail.h \
@@ -405,11 +414,12 @@ 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 \
@@ -508,6 +518,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os_calls.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pixman-region16.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_calls.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string_calls.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread_calls.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trans.Plo@am__quote@ # am--include-marker

@@ -702,6 +713,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/os_calls.Plo
-rm -f ./$(DEPDIR)/pixman-region16.Plo
-rm -f ./$(DEPDIR)/ssl_calls.Plo
-rm -f ./$(DEPDIR)/string_calls.Plo
-rm -f ./$(DEPDIR)/thread_calls.Plo
-rm -f ./$(DEPDIR)/trans.Plo
-rm -f Makefile
@@ -758,6 +770,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/os_calls.Plo
-rm -f ./$(DEPDIR)/pixman-region16.Plo
-rm -f ./$(DEPDIR)/ssl_calls.Plo
-rm -f ./$(DEPDIR)/string_calls.Plo
-rm -f ./$(DEPDIR)/thread_calls.Plo
-rm -f ./$(DEPDIR)/trans.Plo
-rm -f Makefile


+ 2
- 1
common/arch.h 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


+ 1
- 1
common/base64.c 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>


+ 3
- 0
common/defines.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))


+ 1
- 0
common/file.c 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"


+ 1
- 0
common/list.c View File

@@ -24,6 +24,7 @@

#include "arch.h"
#include "os_calls.h"
#include "string_calls.h"
#include "list.h"

/*****************************************************************************/


+ 596
- 134
common/log.c 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.
@@ -66,7 +67,7 @@ internal_log_file_open(const char *fname)
#ifdef FD_CLOEXEC
if (ret != -1)
{
fcntl(ret, F_SETFD, FD_CLOEXEC);
fcntl(ret, F_SETFD, FD_CLOEXEC);
}
#endif

@@ -150,13 +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,12 +158,20 @@ internal_log_start(struct log_config *l_cfg)
return ret;
}

/* open file */
l_cfg->fd = internal_log_file_open(l_cfg->log_file);
if (l_cfg->dump_on_start)
{
internal_log_config_dump(l_cfg);
}

if (-1 == l_cfg->fd)
/* open file */
if (l_cfg->log_file != NULL)
{
return LOG_ERROR_FILE_OPEN;
l_cfg->fd = internal_log_file_open(l_cfg->log_file);

if (-1 == l_cfg->fd)
{
return LOG_ERROR_FILE_OPEN;
}
}

/* if syslog is enabled, open it */
@@ -265,37 +267,24 @@ 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 = 1;
lc->enable_pid = 0;

file_read_section(file, SESMAN_CFG_LOGGING, param_n, param_v);
g_snprintf(section_name, 511, "%s%s", section_prefix, SESMAN_CFG_LOGGING);
file_read_section(file, section_name, param_n, param_v);

for (i = 0; i < param_n->count; i++)
{
@@ -372,6 +344,21 @@ 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,313 @@ internal_config_read_logging(int file, struct log_config *lc,
/* try to create path if not exist */
g_create_path(lc->log_file);

#ifdef LOG_PER_LOGGER_LEVEL
int len;
struct log_logger_level *logger;

list_clear(param_v);
list_clear(param_n);
g_snprintf(section_name, 511, "%s%s", section_prefix, SESMAN_CFG_LOGGING_LOGGER);
file_read_section(file, section_name, param_n, param_v);
for (i = 0; i < param_n->count; i++)
{
logger = (struct log_logger_level *)g_malloc(sizeof(struct log_logger_level), 1);
list_add_item(lc->per_logger_level, (tbus) logger);
logger->log_level = internal_log_text2level((char *)list_get_item(param_v, i));

g_strncpy(logger->logger_name, (char *)list_get_item(param_n, i), LOGGER_NAME_SIZE);
logger->logger_name[LOGGER_NAME_SIZE] = '\0';
len = g_strlen(logger->logger_name);
if (len >= 2
&& logger->logger_name[len - 2] == '('
&& logger->logger_name[len - 1] == ')' )
{
logger->logger_type = LOG_TYPE_FUNCTION;
logger->logger_name[len - 2] = '\0';
}
else
{
logger->logger_type = LOG_TYPE_FILE;
}
}
#endif

list_delete(param_v);
list_delete(param_n);
return lc;
}

void
internal_log_config_dump(struct log_config *config)
{
char str_level[20];
#ifdef LOG_PER_LOGGER_LEVEL
struct log_logger_level *logger;
int i;
#endif

g_printf("logging configuration:\r\n");
g_printf("\tLogFile: %s\r\n", lc->log_file);
g_printf("\tLogLevel: %i\r\n", lc->log_level);
g_printf("\tEnableSyslog: %i\r\n", lc->enable_syslog);
g_printf("\tSyslogLevel: %i\r\n", lc->syslog_level);
return LOG_STARTUP_OK;
if (config->log_file)
{
internal_log_lvl2str(config->log_level, str_level);
g_printf("\tLogFile: %s\r\n", config->log_file);
g_printf("\tLogLevel: %s\r\n", str_level);
}
else
{
g_printf("\tLogFile: %s\r\n", "<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
}

enum logReturns
struct log_config *
internalInitAndAllocStruct(void)
{
enum logReturns ret = LOG_GENERAL_ERROR;
g_staticLogConfig = g_new0(struct log_config, 1);
struct log_config *ret = g_new0(struct log_config, 1);

if (g_staticLogConfig != NULL)
if (ret != NULL)
{
g_staticLogConfig->fd = -1;
g_staticLogConfig->enable_syslog = 0;
ret = LOG_STARTUP_OK;
ret->fd = -1;
ret->enable_syslog = 0;
ret->per_logger_level = list_create();
if (ret->per_logger_level != NULL)
{
ret->per_logger_level->auto_free = 1;
}
else
{
g_writeln("could not allocate memory for log struct");
g_free(ret);
ret = NULL;
}
}
else
{
g_writeln("could not allocate memory for log struct");
ret = LOG_ERROR_MALLOC;
}

return ret;
}

void
internal_log_config_copy(struct log_config *dest, const struct log_config *src)
{
int i;

dest->enable_syslog = src->enable_syslog;
dest->fd = src->fd;
dest->log_file = g_strdup(src->log_file);
dest->log_level = src->log_level;
dest->log_lock = src->log_lock;
dest->log_lock_attr = src->log_lock_attr;
dest->program_name = src->program_name;
dest->enable_syslog = src->enable_syslog;
dest->syslog_level = src->syslog_level;
dest->enable_console = src->enable_console;
dest->console_level = src->console_level;
dest->enable_pid = src->enable_pid;
dest->dump_on_start = src->dump_on_start;
for (i = 0; i < src->per_logger_level->count; ++i)
{
struct log_logger_level *dst_logger =
(struct log_logger_level *)g_malloc(sizeof(struct log_logger_level), 1);

g_memcpy(dst_logger,
(struct log_logger_level *) list_get_item(src->per_logger_level, i),
sizeof(struct log_logger_level));

list_add_item(dest->per_logger_level, (tbus) dst_logger);
}
}

bool_t
internal_log_is_enabled_for_level(const enum logLevels log_level,
const bool_t override_destination_level,
const enum logLevels override_log_level)
{
/* Is log initialized? */
if (g_staticLogConfig == NULL)
{
return 0;
}
else if (g_staticLogConfig->fd < 0
&& !g_staticLogConfig->enable_syslog
&& !g_staticLogConfig->enable_console)
{
/* all logging outputs are disabled */
return 0;
}
else if (override_destination_level)
{
/* Override is enabled - should the message should be logged? */
return log_level <= override_log_level;
}
/* Override is disabled - Is there at least one log destination
* which will accept the message based on the log level? */
else if (g_staticLogConfig->fd >= 0
&& log_level <= g_staticLogConfig->log_level)
{
return 1;
}
else if (g_staticLogConfig->enable_syslog
&& log_level <= g_staticLogConfig->syslog_level)
{
return 1;
}
else if (g_staticLogConfig->enable_console
&& log_level <= g_staticLogConfig->console_level)
{
return 1;
}
else
{
return 0;
}
}

bool_t
internal_log_location_overrides_level(const char *function_name,
const char *file_name,
enum logLevels *log_level_return)
{
struct log_logger_level *logger = NULL;
int i;

if (g_staticLogConfig == NULL)
{
return 0;
}
for (i = 0; i < g_staticLogConfig->per_logger_level->count; i++)
{
logger = (struct log_logger_level *)list_get_item(g_staticLogConfig->per_logger_level, i);

if ((logger->logger_type == LOG_TYPE_FILE
&& 0 == g_strncmp(logger->logger_name, file_name, LOGGER_NAME_SIZE))
|| (logger->logger_type == LOG_TYPE_FUNCTION
&& 0 == g_strncmp(logger->logger_name, function_name, LOGGER_NAME_SIZE)))
{
*log_level_return = logger->log_level;
return 1;
}
}

return 0;
}

/*
* Here below the public functions
*/

struct log_config *
log_config_init_for_console(enum logLevels lvl, const char *override_name)
{
struct log_config *config = internalInitAndAllocStruct();

if (config != NULL)
{
config->program_name = "<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;
}
config->dump_on_start = 0; /* Don't need dump for console only */
}
return config;
}


struct log_config *
log_config_init_from_config(const char *iniFilename,
const char *applicationName,
const char *section_prefix)
{
int fd;
struct log_config *config;

if (applicationName == NULL)
{
g_writeln("Programming error your application name cannot be null");
return NULL;
}

if (iniFilename == NULL)
{
g_writeln("The inifile is null to log_config_init_from_config!");
return NULL;
}

fd = g_file_open_ex(iniFilename, 1, 0, 0, 0);

if (-1 == fd)
{
g_writeln("We could not open the configuration file to read log parameters");
return NULL;
}

/* read logging config */
config = internal_config_read_logging(fd, applicationName, section_prefix);

/* cleanup */
g_file_close(fd);
return config;
}

enum logReturns
log_config_free(struct log_config *config)
{
if (config != NULL)
{
if (config->per_logger_level != NULL)
{
list_delete(config->per_logger_level);
config->per_logger_level = NULL;
}
g_free(config);
}

return LOG_STARTUP_OK;
}

enum logReturns
log_start_from_param(const struct log_config *iniParams)
log_start_from_param(const struct log_config *src_log_config)
{
enum logReturns ret = LOG_GENERAL_ERROR;

@@ -426,41 +685,28 @@ log_start_from_param(const struct log_config *iniParams)
return ret;
}

if (iniParams == NULL)
if (src_log_config == NULL)
{
g_writeln("inparam to log_start_from_param is NULL");
g_writeln("src_log_config to log_start_from_param is NULL");
return ret;
}
else
{
/*Copy the struct information*/
ret = internalInitAndAllocStruct();

if (ret != LOG_STARTUP_OK)
g_staticLogConfig = internalInitAndAllocStruct();
if (g_staticLogConfig == NULL)
{
g_writeln("internalInitAndAllocStruct failed");
return ret;
return LOG_ERROR_MALLOC;
}
internal_log_config_copy(g_staticLogConfig, src_log_config);

g_staticLogConfig->enable_syslog = iniParams->enable_syslog;
g_staticLogConfig->fd = iniParams->fd;
g_staticLogConfig->log_file = g_strdup(iniParams->log_file);
g_staticLogConfig->log_level = iniParams->log_level;
g_staticLogConfig->log_lock = iniParams->log_lock;
g_staticLogConfig->log_lock_attr = iniParams->log_lock_attr;
g_staticLogConfig->program_name = iniParams->program_name;
g_staticLogConfig->syslog_level = iniParams->syslog_level;
ret = internal_log_start(g_staticLogConfig);

if (ret != LOG_STARTUP_OK)
{
g_writeln("Could not start log");

if (g_staticLogConfig != NULL)
{
g_free(g_staticLogConfig);
g_staticLogConfig = NULL;
}
log_config_free(g_staticLogConfig);
g_staticLogConfig = NULL;
}
}

@@ -478,28 +724,18 @@ enum logReturns
log_start(const char *iniFile, const char *applicationName)
{
enum logReturns ret = LOG_GENERAL_ERROR;
struct log_config *config;

if (applicationName == NULL)
{
g_writeln("Programming error your application name cannot be null");
return ret;
}

ret = internalReadConfiguration(iniFile, applicationName);
config = log_config_init_from_config(iniFile, applicationName, "");

if (ret == LOG_STARTUP_OK)
if (config != NULL)
{
ret = internal_log_start(g_staticLogConfig);
ret = log_start_from_param(config);
log_config_free(config);

if (ret != LOG_STARTUP_OK)
{
g_writeln("Could not start log");

if (g_staticLogConfig != NULL)
{
g_free(g_staticLogConfig);
g_staticLogConfig = NULL;
}
}
}
else
@@ -520,21 +756,230 @@ log_end(void)
{
enum logReturns ret = LOG_GENERAL_ERROR;
ret = internal_log_end(g_staticLogConfig);
log_config_free(g_staticLogConfig);
g_staticLogConfig = NULL;

if (g_staticLogConfig != NULL)
return ret;
}

/*****************************************************************************/
/* produce a hex dump */
enum logReturns
log_hexdump_with_location(const char *function_name,
const char *file_name,
const int line_number,
const enum logLevels log_level,
const char *message,
const char *src,
int len)
{
unsigned char *line;
int i;
int dump_number_lines;
int dump_line_length;
int dump_length;
int dump_offset;
int thisline;
int offset;
char *dump_buffer;
enum logReturns rv;
enum logLevels override_log_level;
bool_t override_destination_level = 0;

/* Start the dump on a new line so that the first line of the dump is
aligned to the first column instead of to after the log message
preamble (eg. time, log level, ...)
*/
#define HEX_DUMP_SOURCE_BYTES_PER_LINE (16)
#ifdef _WIN32
#define HEX_DUMP_HEADER ("%s Hex Dump:\r\n")
#define HEX_DUMP_NEWLINE_SIZE (2)
#else
#ifdef _MACOS
#define HEX_DUMP_HEADER ("%s Hex Dump:\r")
#define HEX_DUMP_NEWLINE_SIZE (1)
#else
#define HEX_DUMP_HEADER ("%s Hex Dump:\n")
#define HEX_DUMP_NEWLINE_SIZE (1)
#endif
#endif
#define HEX_DUMP_HEADER_SIZE (sizeof(HEX_DUMP_HEADER) - 1)

override_destination_level = internal_log_location_overrides_level(
function_name,
file_name,
&override_log_level);
if (!internal_log_is_enabled_for_level(log_level, override_destination_level, override_log_level))
{
g_free(g_staticLogConfig);
g_staticLogConfig = NULL;
return LOG_STARTUP_OK;
}

return ret;
dump_line_length = (4 + 3 /* = 4 offset + 3 space */
+ ((2 + 1) * HEX_DUMP_SOURCE_BYTES_PER_LINE) /* + (2 hex char + 1 space) per source byte */
+ 2 /* + 2 space */
+ HEX_DUMP_SOURCE_BYTES_PER_LINE
+ HEX_DUMP_NEWLINE_SIZE);

dump_number_lines = (len / HEX_DUMP_SOURCE_BYTES_PER_LINE) + 1; /* +1 to round up */
dump_length = (dump_number_lines *dump_line_length /* hex dump lines */
+ HEX_DUMP_HEADER_SIZE
+ 1); /* terminating NULL */
dump_buffer = (char *)g_malloc(dump_length, 1);
if (dump_buffer == NULL)
{
LOG_DEVEL(LOG_LEVEL_WARNING,
"Failed to allocate buffer for hex dump of size %d",
dump_length);
return LOG_ERROR_MALLOC;
}

line = (unsigned char *)src;
offset = 0;

g_memcpy(dump_buffer, HEX_DUMP_HEADER, HEX_DUMP_HEADER_SIZE);
dump_offset = HEX_DUMP_HEADER_SIZE;

while (offset < len)
{
g_sprintf(dump_buffer + dump_offset, "%04x ", offset);
dump_offset += 7;
thisline = len - offset;

if (thisline > HEX_DUMP_SOURCE_BYTES_PER_LINE)
{
thisline = HEX_DUMP_SOURCE_BYTES_PER_LINE;
}

for (i = 0; i < thisline; i++)
{
g_sprintf(dump_buffer + dump_offset, "%02x ", line[i]);
dump_offset += 3;
}

for (; i < HEX_DUMP_SOURCE_BYTES_PER_LINE; i++)
{
dump_buffer[dump_offset++] = ' ';
dump_buffer[dump_offset++] = ' ';
dump_buffer[dump_offset++] = ' ';
}

dump_buffer[dump_offset++] = ' ';
dump_buffer[dump_offset++] = ' ';

for (i = 0; i < thisline; i++)
{
dump_buffer[dump_offset++] = (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.';
}

for (; i < HEX_DUMP_SOURCE_BYTES_PER_LINE; i++)
{
dump_buffer[dump_offset++] = ' ';
}

#ifdef _WIN32
dump_buffer[dump_offset++] = '\r';
dump_buffer[dump_offset++] = '\n';
#else
#ifdef _MACOS
dump_buffer[dump_offset++] = '\r';
#else
dump_buffer[dump_offset++] = '\n';
#endif
#endif
offset += thisline;
line += thisline;


if ((dump_offset - HEX_DUMP_HEADER_SIZE) % dump_line_length != 0)
{
LOG_DEVEL(LOG_LEVEL_ERROR,
"BUG: dump_offset (%d) at the end of a line is not a "
"multiple of the line length (%d)",
dump_offset, dump_line_length);
}

}
if (dump_offset > dump_length)
{
LOG_DEVEL(LOG_LEVEL_ERROR,
"BUG: dump_offset (%d) is larger than the dump_buffer length (%d)",
dump_offset, dump_length);
g_free(dump_buffer);
return LOG_GENERAL_ERROR;
}

/* replace the last new line with the end of the string since log_message
will add a new line */
dump_buffer[dump_offset - HEX_DUMP_NEWLINE_SIZE] = '\0';

rv = log_message_with_location(function_name, file_name, line_number,
log_level, dump_buffer, message);
g_free(dump_buffer);
return rv;
}

enum logReturns
log_message_with_location(const char *function_name,
const char *file_name,
const int line_number,
const enum logLevels level,
const char *msg,
...)
{
va_list ap;
enum logReturns rv;
char buff[LOG_BUFFER_SIZE];
enum logLevels override_log_level = LOG_LEVEL_NEVER;
bool_t override_destination_level = 0;

if (g_staticLogConfig == NULL)
{
g_writeln("The log reference is NULL - log not initialized properly "
"when called from [%s(%s:%d)]",
(function_name != NULL ? function_name : "unknown_function"),
(file_name != NULL ? file_name : "unknown_file"),
line_number);
return LOG_ERROR_NO_CFG;
}

override_destination_level = internal_log_location_overrides_level(
function_name,
file_name,
&override_log_level);
if (!internal_log_is_enabled_for_level(level, override_destination_level, override_log_level))
{
return LOG_STARTUP_OK;
}

g_snprintf(buff, LOG_BUFFER_SIZE, "[%s(%s:%d)] %s",
function_name, file_name, line_number, msg);

va_start(ap, msg);
rv = internal_log_message(level, override_destination_level, override_log_level, buff, ap);
va_end(ap);
return rv;
}

enum logReturns
log_message(const enum logLevels lvl, const char *msg, ...)
{
char buff[LOG_BUFFER_SIZE + 31]; /* 19 (datetime) 4 (space+cr+lf+\0) */
va_list ap;
enum logReturns rv;

va_start(ap, msg);
rv = internal_log_message(lvl, 0, LOG_LEVEL_NEVER, msg, ap);
va_end(ap);
return rv;
}

enum logReturns
internal_log_message(const enum logLevels lvl,
const bool_t override_destination_level,
const enum logLevels override_log_level,
const char *msg,
va_list ap)
{
char buff[LOG_BUFFER_SIZE + 31]; /* 19 (datetime) 4 (space+cr+lf+\0) */
int len = 0;
enum logReturns rv = LOG_STARTUP_OK;
int writereply = 0;
@@ -547,28 +992,38 @@ 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,37 +1041,44 @@ 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));
pthread_mutex_lock(&(g_staticLogConfig->log_lock));
#endif

if (g_staticLogConfig->fd >= 0)
{
writereply = g_file_write(g_staticLogConfig->fd, buff, g_strlen(buff));

if (writereply <= 0)
{
rv = LOG_ERROR_NULL_FILE;
}
}

#ifdef LOG_ENABLE_THREAD
pthread_mutex_unlock(&(g_staticLogConfig->log_lock));
pthread_mutex_unlock(&(g_staticLogConfig->log_lock));
#endif
}
}

return rv;


+ 220
- 27
common/log.h 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 */
@@ -49,29 +52,113 @@ enum logReturns
LOG_GENERAL_ERROR
};

#define SESMAN_CFG_LOGGING "Logging"
#define SESMAN_CFG_LOG_FILE "LogFile"
#define SESMAN_CFG_LOG_LEVEL "LogLevel"
#define SESMAN_CFG_LOG_ENABLE_SYSLOG "EnableSyslog"
#define SESMAN_CFG_LOG_SYSLOG_LEVEL "SyslogLevel"
#define SESMAN_CFG_LOGGING "Logging"
#define SESMAN_CFG_LOGGING_LOGGER "LoggingPerLogger"
#define SESMAN_CFG_LOG_FILE "LogFile"
#define SESMAN_CFG_LOG_LEVEL "LogLevel"
#define SESMAN_CFG_LOG_ENABLE_CONSOLE "EnableConsole"
#define SESMAN_CFG_LOG_CONSOLE_LEVEL "ConsoleLevel"
#define SESMAN_CFG_LOG_ENABLE_SYSLOG "EnableSyslog"
#define SESMAN_CFG_LOG_SYSLOG_LEVEL "SyslogLevel"
#define SESMAN_CFG_LOG_ENABLE_PID "EnableProcessId"

/* enable threading */
/*#define LOG_ENABLE_THREAD*/

#ifdef XRDP_DEBUG
#define LOG_DBG(args...) log_message(LOG_LEVEL_DEBUG, args);

#define LOG_PER_LOGGER_LEVEL

/**
* @brief Logging macro for messages that are for an XRDP developer to
* understand and debug XRDP code.
*
* Note: all log levels are relavant to help a developer understand XRDP at
* different levels of granularity.
*
* Note: the logging function calls are removed when XRDP_DEBUG is NOT defined.
*
* Note: when the build is configured with --enable-xrdpdebug, then
* the log level can be configured per the source file name or method name
* (with the suffix "()") in the [LoggingPerLogger]
* section of the configuration file.
*
* For example:
* ```
* [LoggingPerLogger]
* xrdp.c=DEBUG
* main()=WARNING
* ```
*
* @param lvl, the log level
* @param msg, the log text as a printf format c-string
* @param ... the arguments for the printf format c-string
*/
#define LOG_DEVEL(log_level, args...) \
log_message_with_location(__func__, __FILE__, __LINE__, log_level, args);

/**
* @brief Logging macro for messages that are for a systeam administrator to
* configure and run XRDP on their machine.
*
* Note: the logging function calls contain additional code location info when
* XRDP_DEBUG is defined.
*
* @param lvl, the log level
* @param msg, the log text as a printf format c-string
* @param ... the arguments for the printf format c-string
*/
#define LOG(log_level, args...) \
log_message_with_location(__func__, __FILE__, __LINE__, log_level, args);

/**
* @brief Logging macro for logging the contents of a byte array using a hex
* dump format.
*
* Note: the logging function calls are removed when XRDP_DEBUG is NOT defined.
*
* @param log_level, the log level
* @param message, a message prefix for the hex dump. Note: no printf like
* formatting is done to this message.
* @param buffer, a pointer to the byte array to log as a hex dump
* @param length, the length of the byte array to log
*/
#define LOG_DEVEL_HEXDUMP(log_level, message, buffer, length) \
log_hexdump_with_location(__func__, __FILE__, __LINE__, log_level, message, buffer, length);

#else
#define LOG_DBG(args...)
#define LOG_DEVEL(log_level, args...)
#define LOG(log_level, args...) log_message(log_level, args);
#define LOG_DEVEL_HEXDUMP(log_level, message, buffer, length)

#endif

enum log_logger_type
{
LOG_TYPE_FILE = 0,
LOG_TYPE_FUNCTION,
};

struct log_logger_level
{
enum logLevels log_level;
enum log_logger_type logger_type;
char logger_name[LOGGER_NAME_SIZE + 1];
};

struct log_config
{
const char *program_name;
char *log_file;
int fd;
enum logLevels log_level;
int enable_console;
enum logLevels console_level;
int enable_syslog;
enum logLevels syslog_level;
struct list *per_logger_level;
int dump_on_start;
int enable_pid;
pthread_mutex_t log_lock;
pthread_mutexattr_t log_lock_attr;
};
@@ -114,32 +201,64 @@ 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.
@@ -152,11 +271,51 @@ log_start(const char *iniFile, const char *applicationName);

/**
* An alternative log_start where the caller gives the params directly.
* @param iniParams
* @param config
* @return
*
* @post to avoid memory leaks, the config argument must be free'ed using
* `log_config_free()`
*/
enum logReturns
log_start_from_param(const struct log_config *iniParams);
log_start_from_param(const struct log_config *src_log_config);

/**
* Sets up a suitable log config for writing to the console only
* (i.e. for a utility)
*
* The config can be customised by the caller before calling
* log_start_from_param()
*
* @param Default log level
* @param Log level name, or NULL. This can be used to provide an
* override to the default log level, by environment variable or
* argument.
*
* @return pointer to struct log_config.
*/
struct log_config *
log_config_init_for_console(enum logLevels lvl, const char *override_name);

/**
* Read configuration from a file and store the values in the returned
* log_config.
* @param file
* @param applicationName, the application name used in the log events.
* @param section_prefix, prefix for the logging sections to parse
* @return
*/
struct log_config *
log_config_init_from_config(const char *iniFilename,
const char *applicationName,
const char *section_prefix);

/**
* Free the memory for the log_config struct.
*/
enum logReturns
log_config_free(struct log_config *config);

/**
* Function that terminates all logging
* @return
@@ -166,6 +325,9 @@ 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 +336,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


sesman/chansrv/ms-erref.h → common/ms-erref.h View File

@@ -27,18 +27,17 @@
*/
enum NTSTATUS
{
NT_STATUS_SUCCESS = 0x00000000,
NT_STATUS_UNSUCCESSFUL = 0xC0000001,
NT_STATUS_NO_SUCH_FILE = 0xC000000F,
NT_STATUS_ACCESS_DENIED = 0xC0000022,
NT_STATUS_OBJECT_NAME_INVALID = 0xC0000033,
NT_STATUS_OBJECT_NAME_NOT_FOUND = 0xC0000034,
NT_STATUS_SHARING_VIOLATION = 0xC0000043,
NT_STATUS_NO_MORE_FILES = 0x80000006
};

#endif /* MS_ERREF_H */