Codebase list xrdp / 3bc5e34
Update upstream source from tag 'upstream/0.9.15' Update to upstream version '0.9.15' with Debian dir e4b748da60966f90924fa8e5387c0cab489cd69d Dominik George 3 years ago
214 changed file(s) with 13538 addition(s) and 8548 deletion(s). Raw diff Collapse all Expand all
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
144144 $(am__extra_recursive_targets)
145145 AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
146146 cscope distdir distdir-am dist dist-all distcheck
147 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
148 $(LISP)config_ac-h.in
147 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
148 config_ac-h.in
149149 # Read a list of newline-separated strings from the standard input,
150150 # and print each of them once, without duplicates. Input order is
151151 # *not* preserved.
209209 DIST_ARCHIVES = $(distdir).tar.gz
210210 GZIP_ENV = --best
211211 DIST_TARGETS = dist-gzip
212 # Exists only to be overridden by the user if desired.
213 AM_DISTCHECK_DVI_TARGET = dvi
212214 distuninstallcheck_listfiles = find . -type f -print
213215 am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
214216 | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
659661 tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
660662 $(am__post_remove_distdir)
661663
664 dist-zstd: distdir
665 tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
666 $(am__post_remove_distdir)
667
662668 dist-tarZ: distdir
663669 @echo WARNING: "Support for distribution archives compressed with" \
664670 "legacy program 'compress' is deprecated." >&2
701707 eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
702708 *.zip*) \
703709 unzip $(distdir).zip ;;\
710 *.tar.zst*) \
711 zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
704712 esac
705713 chmod -R a-w $(distdir)
706714 chmod u+w $(distdir)
716724 $(DISTCHECK_CONFIGURE_FLAGS) \
717725 --srcdir=../.. --prefix="$$dc_install_base" \
718726 && $(MAKE) $(AM_MAKEFLAGS) \
719 && $(MAKE) $(AM_MAKEFLAGS) dvi \
727 && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
720728 && $(MAKE) $(AM_MAKEFLAGS) check \
721729 && $(MAKE) $(AM_MAKEFLAGS) install \
722730 && $(MAKE) $(AM_MAKEFLAGS) installcheck \
878886 am--refresh check check-am clean clean-cscope clean-generic \
879887 clean-libtool cscope cscopelist-am ctags ctags-am dist \
880888 dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
881 dist-xz dist-zip distcheck distclean distclean-generic \
882 distclean-hdr distclean-libtool distclean-local distclean-tags \
883 distcleancheck distdir distuninstallcheck dvi dvi-am html \
884 html-am info info-am install install-am install-data \
885 install-data-am install-dvi install-dvi-am install-exec \
886 install-exec-am install-html install-html-am install-info \
887 install-info-am install-man install-pdf install-pdf-am \
888 install-ps install-ps-am install-strip installcheck \
889 installcheck-am installdirs installdirs-am maintainer-clean \
890 maintainer-clean-generic mostlyclean mostlyclean-generic \
891 mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
892 uninstall-am
889 dist-xz dist-zip dist-zstd distcheck distclean \
890 distclean-generic distclean-hdr distclean-libtool \
891 distclean-local distclean-tags distcleancheck distdir \
892 distuninstallcheck dvi dvi-am html html-am info info-am \
893 install install-am install-data install-data-am install-dvi \
894 install-dvi-am install-exec install-exec-am install-html \
895 install-html-am install-info install-info-am install-man \
896 install-pdf install-pdf-am install-ps install-ps-am \
897 install-strip installcheck installcheck-am installdirs \
898 installdirs-am maintainer-clean maintainer-clean-generic \
899 mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
900 ps ps-am tags tags-am uninstall uninstall-am
893901
894902 .PRECIOUS: Makefile
895903
0 # Release notes for xrdp v0.9.15 (2020/12/28)
1
2 ## New features
3 * Allow token sign in without autologon for SSO (#1667 #1668)
4 * Norwegian keyboard support (#1675)
5 * Improved config support for chansrv (#1635)
6 * Unified chansrv, sesman and libxrdp logging (#1633 #1708 #1738) - thanks to @aquesnel
7 * Support SUSE move to /usr/etc (#1702)
8 * Parameters may now be specified for user-specified shell (#1270 #1695)
9 * xrdp executables now allow alternative config files to be specified with -c (#1588 #1650 #1651)
10 * sesrun improvements (#1741)
11 * Drive redirection location can now be specified (#1048)
12 * Now compiles on RISC-V (#1761)
13
14 ## Bug fixes
15 * Additional buffer overflow checks (#1662)
16 * FUSE support now builds on 32-bit platforms (#1682)
17 * genkeymap array size conflict fixed (#1691)
18 * Buffering issue with neutrinordp over a slow link fixed (#1608 1634)
19 * Various documentation fixes (#1704 #1741 #1755 #1759)
20 * Prevent PAM info message from causing authentication failure (#1727)
21 * Cosmetic fixes for minor issues (#1751 #1755 #1749)
22 * Try harder to clean up socket files on session exit (#1740 #1756)
23 * xrdp-chansrv become defunct in docker while file copy (#1658)
24
25 ## Internal changes
26 * Compilation warnings with newer compilers (#1659 #1680)
27 * Continuation Integration checks on 32-bit platforms now include FUSE support (#1682)
28 * Continuation Integration builds now default to the Ubuntu Focal platform (#1666)
29 * FUSE type tidy-ups (#1686)
30 * Switch from Travis CI to GitHub Actions (#1728 #1732)
31 * Easier to set up console logging for utilities (#1711)
32
33 -----------------------
34
35 # Release notes for xrdp v0.9.14 (2020/08/31)
36
37 ## New features
38 * VNC multi-monitor support if you are using a suitable Xvnc server #1343
39 * VNC sessions now resize by default on reconnection if you are using a suitable Xvnc server #1343
40 * Support Slackware for PAM #1558 #1560
41 * Support Programmer Dvorak Keyboard #1663
42
43 **[HEADS UP]** The VNC changes are significant. They described in more detail on the following wiki page.
44 * [Xvnc backend : Multi monitor and resize support](https://github.com/neutrinolabs/xrdp/wiki/Xvnc-backend-:-Multi-monitor-and-resize-support)
45
46 ## Bug fixes
47 * Fix odd shift key behavior (workaround) #397 #1522
48 * Fix Xorg path in the document for Arch Linux #1448 #1529
49 * Fix Xorg path in the document for CentOS 8 #1646 #1647
50 * Fix internal username/password buffer is smaller than RDP protocol specification #1648 #1653
51 * Fix possible memory out-of-bounds accesses #1549
52 * Fix memory allocation overflow #1557
53 * Prevent chansrv input channels being scanned during a server reset #1595
54 * Ignore TS_MULTIFRAGMENTUPDATE_CAPABILITYSET from client if fp disabled #1593
55 * Minor manpage fixes #1611
56
57 ## Other changes
58 * CI error fixes
59 * Introduce cppcheck
60
61 ## Known issues
62 * FreeRDP 2.0.0-rc4 or later might not able to connect to xrdp due to
63 xrdp's bad-mannered behaviour, add `+glyph-cache` option to FreeRDP to connect #1266
64 * Audio redirection by MP3 codec doesn't sound with some client, use AAC instead #965
65
66 # Release notes for xrdp v0.9.13.1 (2020/06/30)
67
68 This is a security fix release that includes fixes for the following local buffer overflow vulnerability.
69
70 * [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)
71
72 This update is recommended for all xrdp users.
73
74 ## Special thanks
75
76 Thanks to [Ashley Newson](https://github.com/ashleynewson) reporting the vulnerability and reviewing fix.
77
78 -----------------------
79
80 # Release notes for xrdp v0.9.13 (2020/03/11)
81
82 This release is an intermediate bugfix release. The previous version v0.9.12 has some regressions on drive redirection.
83
84 ## Bug fixes (drive redirection related)
85 * Fix chansrv crashes with segmentation fault (regression in #1449) #1487
86 * Drive redirection now supports Guacamole client #1505 #1507
87 * Prevent a coredump in the event of a corrupted file system #1507
88 * Resolve double-free in `chansrv_fuse` #1469
89
90 ## Bug fixes (other)
91 * Fix the issue `xrdp --version | less` will show empty output #1471 #1472
92 * Fix some warnings found by cppcheck #1479 #1481 #1484 #1485
93
94 ## Other changes
95 * Add FreeBSD CI test #1466
96 * Move Microsoft-defined constants into separate includes #1470
97 * Perform cppcheck during CI test #1493
98 * Support mousex button 8/9 #1478
99
100 ## Known issues
101 * FreeRDP 2.0.0-rc4 or later might not able to connect to xrdp due to
102 xrdp's bad-mannered behaviour, add `+glyph-cache` option to FreeRDP to connect #1266
103 * Audio redirection by MP3 codec doesn't sound with some client, use AAC instead #965
104
105 -----------------------
106
0107 # Release notes for xrdp v0.9.12 (2019/12/28)
1108
2109 ## Bug fixes
83190
84191 -----------------------
85192
86 ## Release notes for xrdp v0.9.9 (2018/12/25)
193 # Release notes for xrdp v0.9.9 (2018/12/25)
87194
88195 ## Release cycle
89196 From the next release, release cycle will be changed from quarterly to every
00 [![Build Status](https://travis-ci.org/neutrinolabs/xrdp.svg?branch=devel)](https://travis-ci.org/neutrinolabs/xrdp)
1 [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/neutrinolabs/xrdp)
1 [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/neutrinolabs/xrdp-questions)
22 ![Apache-License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)
33
4 *Current Version:* 0.9.12
4 *Current Version:* 0.9.15
55
66 # xrdp - an open source RDP server
77
0 # generated automatically by aclocal 1.16.1 -*- Autoconf -*-
1
2 # Copyright (C) 1996-2018 Free Software Foundation, Inc.
0 # generated automatically by aclocal 1.16.3 -*- Autoconf -*-
1
2 # Copyright (C) 1996-2020 Free Software Foundation, Inc.
33
44 # This file is free software; the Free Software Foundation
55 # gives unlimited permission to copy and/or distribute it,
1919 If you have problems, you may need to regenerate the build system entirely.
2020 To do so, use the procedure documented by the package, typically 'autoreconf'.])])
2121
22 # Copyright (C) 2002-2018 Free Software Foundation, Inc.
22 # Copyright (C) 2002-2020 Free Software Foundation, Inc.
2323 #
2424 # This file is free software; the Free Software Foundation
2525 # gives unlimited permission to copy and/or distribute it,
3434 [am__api_version='1.16'
3535 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
3636 dnl require some minimum version. Point them to the right macro.
37 m4_if([$1], [1.16.1], [],
37 m4_if([$1], [1.16.3], [],
3838 [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
3939 ])
4040
5050 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
5151 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
5252 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
53 [AM_AUTOMAKE_VERSION([1.16.1])dnl
53 [AM_AUTOMAKE_VERSION([1.16.3])dnl
5454 m4_ifndef([AC_AUTOCONF_VERSION],
5555 [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
5656 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
5757
5858 # AM_AUX_DIR_EXPAND -*- Autoconf -*-
5959
60 # Copyright (C) 2001-2018 Free Software Foundation, Inc.
60 # Copyright (C) 2001-2020 Free Software Foundation, Inc.
6161 #
6262 # This file is free software; the Free Software Foundation
6363 # gives unlimited permission to copy and/or distribute it,
107107 am_aux_dir=`cd "$ac_aux_dir" && pwd`
108108 ])
109109
110 # AM_COND_IF -*- Autoconf -*-
111
112 # Copyright (C) 2008-2020 Free Software Foundation, Inc.
113 #
114 # This file is free software; the Free Software Foundation
115 # gives unlimited permission to copy and/or distribute it,
116 # with or without modifications, as long as this notice is preserved.
117
118 # _AM_COND_IF
119 # _AM_COND_ELSE
120 # _AM_COND_ENDIF
121 # --------------
122 # These macros are only used for tracing.
123 m4_define([_AM_COND_IF])
124 m4_define([_AM_COND_ELSE])
125 m4_define([_AM_COND_ENDIF])
126
127 # AM_COND_IF(COND, [IF-TRUE], [IF-FALSE])
128 # ---------------------------------------
129 # If the shell condition COND is true, execute IF-TRUE, otherwise execute
130 # IF-FALSE. Allow automake to learn about conditional instantiating macros
131 # (the AC_CONFIG_FOOS).
132 AC_DEFUN([AM_COND_IF],
133 [m4_ifndef([_AM_COND_VALUE_$1],
134 [m4_fatal([$0: no such condition "$1"])])dnl
135 _AM_COND_IF([$1])dnl
136 if test -z "$$1_TRUE"; then :
137 m4_n([$2])[]dnl
138 m4_ifval([$3],
139 [_AM_COND_ELSE([$1])dnl
140 else
141 $3
142 ])dnl
143 _AM_COND_ENDIF([$1])dnl
144 fi[]dnl
145 ])
146
110147 # AM_CONDITIONAL -*- Autoconf -*-
111148
112 # Copyright (C) 1997-2018 Free Software Foundation, Inc.
149 # Copyright (C) 1997-2020 Free Software Foundation, Inc.
113150 #
114151 # This file is free software; the Free Software Foundation
115152 # gives unlimited permission to copy and/or distribute it,
140177 Usually this means the macro was only invoked conditionally.]])
141178 fi])])
142179
143 # Copyright (C) 1999-2018 Free Software Foundation, Inc.
180 # Copyright (C) 1999-2020 Free Software Foundation, Inc.
144181 #
145182 # This file is free software; the Free Software Foundation
146183 # gives unlimited permission to copy and/or distribute it,
331368
332369 # Generate code to set up dependency tracking. -*- Autoconf -*-
333370
334 # Copyright (C) 1999-2018 Free Software Foundation, Inc.
371 # Copyright (C) 1999-2020 Free Software Foundation, Inc.
335372 #
336373 # This file is free software; the Free Software Foundation
337374 # gives unlimited permission to copy and/or distribute it,
370407 done
371408 if test $am_rc -ne 0; then
372409 AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
373 for automatic dependency tracking. Try re-running configure with the
410 for automatic dependency tracking. If GNU make was not used, consider
411 re-running the configure script with MAKE="gmake" (or whatever is
412 necessary). You can also try re-running configure with the
374413 '--disable-dependency-tracking' option to at least be able to build
375414 the package (albeit without support for automatic dependency tracking).])
376415 fi
397436
398437 # Do all the work for Automake. -*- Autoconf -*-
399438
400 # Copyright (C) 1996-2018 Free Software Foundation, Inc.
439 # Copyright (C) 1996-2020 Free Software Foundation, Inc.
401440 #
402441 # This file is free software; the Free Software Foundation
403442 # gives unlimited permission to copy and/or distribute it,
594633 done
595634 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
596635
597 # Copyright (C) 2001-2018 Free Software Foundation, Inc.
636 # Copyright (C) 2001-2020 Free Software Foundation, Inc.
598637 #
599638 # This file is free software; the Free Software Foundation
600639 # gives unlimited permission to copy and/or distribute it,
615654 fi
616655 AC_SUBST([install_sh])])
617656
618 # Copyright (C) 2003-2018 Free Software Foundation, Inc.
657 # Copyright (C) 2003-2020 Free Software Foundation, Inc.
619658 #
620659 # This file is free software; the Free Software Foundation
621660 # gives unlimited permission to copy and/or distribute it,
636675
637676 # Check to see how 'make' treats includes. -*- Autoconf -*-
638677
639 # Copyright (C) 2001-2018 Free Software Foundation, Inc.
678 # Copyright (C) 2001-2020 Free Software Foundation, Inc.
640679 #
641680 # This file is free software; the Free Software Foundation
642681 # gives unlimited permission to copy and/or distribute it,
679718
680719 # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
681720
682 # Copyright (C) 1997-2018 Free Software Foundation, Inc.
721 # Copyright (C) 1997-2020 Free Software Foundation, Inc.
683722 #
684723 # This file is free software; the Free Software Foundation
685724 # gives unlimited permission to copy and/or distribute it,
700739 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
701740 AC_REQUIRE_AUX_FILE([missing])dnl
702741 if test x"${MISSING+set}" != xset; then
703 case $am_aux_dir in
704 *\ * | *\ *)
705 MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
706 *)
707 MISSING="\${SHELL} $am_aux_dir/missing" ;;
708 esac
742 MISSING="\${SHELL} '$am_aux_dir/missing'"
709743 fi
710744 # Use eval to expand $SHELL
711745 if eval "$MISSING --is-lightweight"; then
718752
719753 # Helper functions for option handling. -*- Autoconf -*-
720754
721 # Copyright (C) 2001-2018 Free Software Foundation, Inc.
755 # Copyright (C) 2001-2020 Free Software Foundation, Inc.
722756 #
723757 # This file is free software; the Free Software Foundation
724758 # gives unlimited permission to copy and/or distribute it,
747781 AC_DEFUN([_AM_IF_OPTION],
748782 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
749783
750 # Copyright (C) 1999-2018 Free Software Foundation, Inc.
784 # Copyright (C) 1999-2020 Free Software Foundation, Inc.
751785 #
752786 # This file is free software; the Free Software Foundation
753787 # gives unlimited permission to copy and/or distribute it,
794828 # For backward compatibility.
795829 AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
796830
797 # Copyright (C) 2001-2018 Free Software Foundation, Inc.
831 # Copyright (C) 2001-2020 Free Software Foundation, Inc.
798832 #
799833 # This file is free software; the Free Software Foundation
800834 # gives unlimited permission to copy and/or distribute it,
813847
814848 # Check to make sure that the build environment is sane. -*- Autoconf -*-
815849
816 # Copyright (C) 1996-2018 Free Software Foundation, Inc.
850 # Copyright (C) 1996-2020 Free Software Foundation, Inc.
817851 #
818852 # This file is free software; the Free Software Foundation
819853 # gives unlimited permission to copy and/or distribute it,
894928 rm -f conftest.file
895929 ])
896930
897 # Copyright (C) 2009-2018 Free Software Foundation, Inc.
931 # Copyright (C) 2009-2020 Free Software Foundation, Inc.
898932 #
899933 # This file is free software; the Free Software Foundation
900934 # gives unlimited permission to copy and/or distribute it,
954988 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
955989 ])
956990
957 # Copyright (C) 2001-2018 Free Software Foundation, Inc.
991 # Copyright (C) 2001-2020 Free Software Foundation, Inc.
958992 #
959993 # This file is free software; the Free Software Foundation
960994 # gives unlimited permission to copy and/or distribute it,
9821016 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
9831017 AC_SUBST([INSTALL_STRIP_PROGRAM])])
9841018
985 # Copyright (C) 2006-2018 Free Software Foundation, Inc.
1019 # Copyright (C) 2006-2020 Free Software Foundation, Inc.
9861020 #
9871021 # This file is free software; the Free Software Foundation
9881022 # gives unlimited permission to copy and/or distribute it,
10011035
10021036 # Check how to create a tarball. -*- Autoconf -*-
10031037
1004 # Copyright (C) 2004-2018 Free Software Foundation, Inc.
1038 # Copyright (C) 2004-2020 Free Software Foundation, Inc.
10051039 #
10061040 # This file is free software; the Free Software Foundation
10071041 # gives unlimited permission to copy and/or distribute it,
66 EXTRA_DIST = pixman-region.c
77
88 include_HEADERS = \
9 ms-erref.h \
10 ms-fscc.h \
11 ms-rdpbcgr.h \
12 ms-rdpefs.h \
13 ms-rdpegdi.h \
14 ms-rdpele.h \
15 ms-rdperp.h \
16 ms-smb2.h \
917 xrdp_client_info.h \
1018 xrdp_constants.h \
1119 xrdp_rail.h \
4553 log.h \
4654 os_calls.c \
4755 os_calls.h \
48 os_calls.h \
4956 parse.h \
5057 rail.h \
5158 ssl_calls.c \
5259 ssl_calls.h \
60 string_calls.c \
61 string_calls.h \
5362 thread_calls.c \
5463 thread_calls.h \
5564 trans.c \
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
145145 am__libcommon_la_SOURCES_DIST = arch.h base64.h base64.c defines.h \
146146 fifo.c fifo.h file.c file.h list.c list.h list16.c list16.h \
147147 log.c log.h os_calls.c os_calls.h parse.h rail.h ssl_calls.c \
148 ssl_calls.h thread_calls.c thread_calls.h trans.c trans.h \
149 pixman-region16.c pixman-region.h
148 ssl_calls.h string_calls.c string_calls.h thread_calls.c \
149 thread_calls.h trans.c trans.h pixman-region16.c \
150 pixman-region.h
150151 @XRDP_PIXMAN_FALSE@am__objects_1 = pixman-region16.lo
151152 am_libcommon_la_OBJECTS = base64.lo fifo.lo file.lo list.lo list16.lo \
152 log.lo os_calls.lo ssl_calls.lo thread_calls.lo trans.lo \
153 $(am__objects_1)
153 log.lo os_calls.lo ssl_calls.lo string_calls.lo \
154 thread_calls.lo trans.lo $(am__objects_1)
154155 libcommon_la_OBJECTS = $(am_libcommon_la_OBJECTS)
155156 AM_V_lt = $(am__v_lt_@AM_V@)
156157 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
175176 ./$(DEPDIR)/file.Plo ./$(DEPDIR)/list.Plo \
176177 ./$(DEPDIR)/list16.Plo ./$(DEPDIR)/log.Plo \
177178 ./$(DEPDIR)/os_calls.Plo ./$(DEPDIR)/pixman-region16.Plo \
178 ./$(DEPDIR)/ssl_calls.Plo ./$(DEPDIR)/thread_calls.Plo \
179 ./$(DEPDIR)/trans.Plo
179 ./$(DEPDIR)/ssl_calls.Plo ./$(DEPDIR)/string_calls.Plo \
180 ./$(DEPDIR)/thread_calls.Plo ./$(DEPDIR)/trans.Plo
180181 am__mv = mv -f
181182 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
182183 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
372373 @XRDP_PIXMAN_TRUE@PIXMAN_SOURCES =
373374 EXTRA_DIST = pixman-region.c
374375 include_HEADERS = \
376 ms-erref.h \
377 ms-fscc.h \
378 ms-rdpbcgr.h \
379 ms-rdpefs.h \
380 ms-rdpegdi.h \
381 ms-rdpele.h \
382 ms-rdperp.h \
383 ms-smb2.h \
375384 xrdp_client_info.h \
376385 xrdp_constants.h \
377386 xrdp_rail.h \
404413 log.h \
405414 os_calls.c \
406415 os_calls.h \
407 os_calls.h \
408416 parse.h \
409417 rail.h \
410418 ssl_calls.c \
411419 ssl_calls.h \
420 string_calls.c \
421 string_calls.h \
412422 thread_calls.c \
413423 thread_calls.h \
414424 trans.c \
507517 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os_calls.Plo@am__quote@ # am--include-marker
508518 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pixman-region16.Plo@am__quote@ # am--include-marker
509519 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_calls.Plo@am__quote@ # am--include-marker
520 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string_calls.Plo@am__quote@ # am--include-marker
510521 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/thread_calls.Plo@am__quote@ # am--include-marker
511522 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trans.Plo@am__quote@ # am--include-marker
512523
701712 -rm -f ./$(DEPDIR)/os_calls.Plo
702713 -rm -f ./$(DEPDIR)/pixman-region16.Plo
703714 -rm -f ./$(DEPDIR)/ssl_calls.Plo
715 -rm -f ./$(DEPDIR)/string_calls.Plo
704716 -rm -f ./$(DEPDIR)/thread_calls.Plo
705717 -rm -f ./$(DEPDIR)/trans.Plo
706718 -rm -f Makefile
757769 -rm -f ./$(DEPDIR)/os_calls.Plo
758770 -rm -f ./$(DEPDIR)/pixman-region16.Plo
759771 -rm -f ./$(DEPDIR)/ssl_calls.Plo
772 -rm -f ./$(DEPDIR)/string_calls.Plo
760773 -rm -f ./$(DEPDIR)/thread_calls.Plo
761774 -rm -f ./$(DEPDIR)/trans.Plo
762775 -rm -f Makefile
8383 #define NEED_ALIGN
8484 #elif defined(__x86__) || defined(__x86_64__) || \
8585 defined(__AMD64__) || defined(_M_IX86) || defined (_M_AMD64) || \
86 defined(__i386__) || defined(__aarch64__)
86 defined(__i386__) || defined(__aarch64__) || \
87 defined(__riscv)
8788 #define NO_NEED_ALIGN
8889 #else
8990 #warning unknown arch
2121 #include <config_ac.h>
2222 #endif
2323
24 #include "os_calls.h"
24 #include "string_calls.h"
2525
2626 #include <openssl/bio.h>
2727 #include <openssl/evp.h>
3939 #define LOWORD(in) ((in) & 0x0000ffff)
4040 #undef MAKELONG
4141 #define MAKELONG(lo, hi) ((((hi) & 0xffff) << 16) | ((lo) & 0xffff))
42 #define UNUSED_VAR(x) ((void) (x))
43
44 /* graphics macros */
4245 #define MAKERECT(r, x, y, cx, cy) \
4346 { (r).left = x; (r).top = y; (r).right = (x) + (cx); (r).bottom = (y) + (cy); }
4447 #define ISRECTEMPTY(r) (((r).right <= (r).left) || ((r).bottom <= (r).top))
2323
2424 #include "arch.h"
2525 #include "os_calls.h"
26 #include "string_calls.h"
2627 #include "list.h"
2728 #include "file.h"
2829 #include "parse.h"
2323
2424 #include "arch.h"
2525 #include "os_calls.h"
26 #include "string_calls.h"
2627 #include "list.h"
2728
2829 /*****************************************************************************/
3030 #include "file.h"
3131 #include "os_calls.h"
3232 #include "thread_calls.h"
33 #include "string_calls.h"
3334
3435 /* Add a define here so that the log.h will hold more information
3536 * when compiled from this C file.
6566 #ifdef FD_CLOEXEC
6667 if (ret != -1)
6768 {
68 fcntl(ret, F_SETFD, FD_CLOEXEC);
69 fcntl(ret, F_SETFD, FD_CLOEXEC);
6970 }
7071 #endif
7172
149150 return ret;
150151 }
151152
152 /* if logfile is NULL, we return error */
153 if (0 == l_cfg->log_file)
154 {
155 g_writeln("log_file not properly assigned");
156 return ret;
157 }
158
159153 /* if progname is NULL, we return error */
160154 if (0 == l_cfg->program_name)
161155 {
163157 return ret;
164158 }
165159
160 if (l_cfg->dump_on_start)
161 {
162 internal_log_config_dump(l_cfg);
163 }
164
166165 /* open file */
167 l_cfg->fd = internal_log_file_open(l_cfg->log_file);
168
169 if (-1 == l_cfg->fd)
170 {
171 return LOG_ERROR_FILE_OPEN;
166 if (l_cfg->log_file != NULL)
167 {
168 l_cfg->fd = internal_log_file_open(l_cfg->log_file);
169
170 if (-1 == l_cfg->fd)
171 {
172 return LOG_ERROR_FILE_OPEN;
173 }
172174 }
173175
174176 /* if syslog is enabled, open it */
264266 return LOG_LEVEL_DEBUG;
265267 }
266268
267 enum logReturns
268 internalReadConfiguration(const char *inFilename, const char *applicationName)
269 {
270 int fd;
271 enum logReturns ret = LOG_GENERAL_ERROR;
269 /******************************************************************************/
270 struct log_config *
271 internal_config_read_logging(int file,
272 const char *applicationName,
273 const char *section_prefix)
274 {
275 int i;
276 char *buf;
277 char *temp_buf;
278 char section_name[512];
279 struct log_config *lc;
272280 struct list *param_n;
273281 struct list *param_v;
274282
275 if (inFilename == NULL)
276 {
277 g_writeln("The inifile is null to readConfiguration!");
278 return ret;
279 }
280
281 fd = g_file_open(inFilename);
282
283 if (-1 == fd)
284 {
285 ret = LOG_ERROR_NO_CFG;
286 g_writeln("We could not open the configuration file to read log parameters");
287 return ret;
288 }
289
290 /* we initialize the memory for the configuration and set all content
291 to zero. */
292 ret = internalInitAndAllocStruct();
293
294 if (ret != LOG_STARTUP_OK)
295 {
296 g_file_close(fd);
297 return ret;
283 lc = internalInitAndAllocStruct();
284 if (lc == NULL)
285 {
286 return NULL;
298287 }
299288
300289 param_n = list_create();
302291 param_v = list_create();
303292 param_v->auto_free = 1;
304293
305 /* read logging config */
306 ret = internal_config_read_logging(fd, g_staticLogConfig, param_n,
307 param_v, applicationName);
308
309 /* cleanup */
310 list_delete(param_v);
311 list_delete(param_n);
312 g_file_close(fd);
313 return ret;
314 }
315
316 /******************************************************************************/
317 enum logReturns
318 internal_config_read_logging(int file, struct log_config *lc,
319 struct list *param_n,
320 struct list *param_v,
321 const char *applicationName)
322 {
323 int i;
324 char *buf;
325 char *temp_buf;
326
327294 list_clear(param_v);
328295 list_clear(param_n);
329296
331298 lc->program_name = applicationName;
332299 lc->log_file = 0;
333300 lc->fd = -1;
334 lc->log_level = LOG_LEVEL_DEBUG;
301 lc->log_level = LOG_LEVEL_INFO;
302 lc->enable_console = 0;
303 lc->console_level = LOG_LEVEL_INFO;
335304 lc->enable_syslog = 0;
336 lc->syslog_level = LOG_LEVEL_DEBUG;
337
338 file_read_section(file, SESMAN_CFG_LOGGING, param_n, param_v);
305 lc->syslog_level = LOG_LEVEL_INFO;
306 lc->dump_on_start = 1;
307 lc->enable_pid = 0;
308
309 g_snprintf(section_name, 511, "%s%s", section_prefix, SESMAN_CFG_LOGGING);
310 file_read_section(file, section_name, param_n, param_v);
339311
340312 for (i = 0; i < param_n->count; i++)
341313 {
371343 {
372344 lc->syslog_level = internal_log_text2level((char *)list_get_item(param_v, i));
373345 }
346
347 if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_ENABLE_CONSOLE))
348 {
349 lc->enable_console = g_text2bool((char *)list_get_item(param_v, i));
350 }
351
352 if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_CONSOLE_LEVEL))
353 {
354 lc->console_level = internal_log_text2level((char *)list_get_item(param_v, i));
355 }
356
357 if (0 == g_strcasecmp(buf, SESMAN_CFG_LOG_ENABLE_PID))
358 {
359 lc->enable_pid = g_text2bool((char *)list_get_item(param_v, i));
360 }
374361 }
375362
376363 if (0 == lc->log_file)
381368 /* try to create path if not exist */
382369 g_create_path(lc->log_file);
383370
371 #ifdef LOG_PER_LOGGER_LEVEL
372 int len;
373 struct log_logger_level *logger;
374
375 list_clear(param_v);
376 list_clear(param_n);
377 g_snprintf(section_name, 511, "%s%s", section_prefix, SESMAN_CFG_LOGGING_LOGGER);
378 file_read_section(file, section_name, param_n, param_v);
379 for (i = 0; i < param_n->count; i++)
380 {
381 logger = (struct log_logger_level *)g_malloc(sizeof(struct log_logger_level), 1);
382 list_add_item(lc->per_logger_level, (tbus) logger);
383 logger->log_level = internal_log_text2level((char *)list_get_item(param_v, i));
384
385 g_strncpy(logger->logger_name, (char *)list_get_item(param_n, i), LOGGER_NAME_SIZE);
386 logger->logger_name[LOGGER_NAME_SIZE] = '\0';
387 len = g_strlen(logger->logger_name);
388 if (len >= 2
389 && logger->logger_name[len - 2] == '('
390 && logger->logger_name[len - 1] == ')' )
391 {
392 logger->logger_type = LOG_TYPE_FUNCTION;
393 logger->logger_name[len - 2] = '\0';
394 }
395 else
396 {
397 logger->logger_type = LOG_TYPE_FILE;
398 }
399 }
400 #endif
401
402 list_delete(param_v);
403 list_delete(param_n);
404 return lc;
405 }
406
407 void
408 internal_log_config_dump(struct log_config *config)
409 {
410 char str_level[20];
411 #ifdef LOG_PER_LOGGER_LEVEL
412 struct log_logger_level *logger;
413 int i;
414 #endif
415
384416 g_printf("logging configuration:\r\n");
385 g_printf("\tLogFile: %s\r\n", lc->log_file);
386 g_printf("\tLogLevel: %i\r\n", lc->log_level);
387 g_printf("\tEnableSyslog: %i\r\n", lc->enable_syslog);
388 g_printf("\tSyslogLevel: %i\r\n", lc->syslog_level);
389 return LOG_STARTUP_OK;
390 }
391
392 enum logReturns
417 if (config->log_file)
418 {
419 internal_log_lvl2str(config->log_level, str_level);
420 g_printf("\tLogFile: %s\r\n", config->log_file);
421 g_printf("\tLogLevel: %s\r\n", str_level);
422 }
423 else
424 {
425 g_printf("\tLogFile: %s\r\n", "<disabled>");
426 }
427
428 if (config->enable_console)
429 {
430 internal_log_lvl2str(config->console_level, str_level);
431 }
432 else
433 {
434 g_strcpy(str_level, "<disabled>");
435 }
436 g_printf("\tConsoleLevel: %s\r\n", str_level);
437
438 if (config->enable_syslog)
439 {
440 internal_log_lvl2str(config->syslog_level, str_level);
441 }
442 else
443 {
444 g_strcpy(str_level, "<disabled>");
445 }
446 g_printf("\tSyslogLevel: %s\r\n", str_level);
447
448 #ifdef LOG_PER_LOGGER_LEVEL
449 g_printf("per logger configuration:\r\n");
450 for (i = 0; i < config->per_logger_level->count; i++)
451 {
452 logger = (struct log_logger_level *)list_get_item(config->per_logger_level, i);
453 internal_log_lvl2str(logger->log_level, str_level);
454 g_printf("\t%-*s: %s\r\n", LOGGER_NAME_SIZE, logger->logger_name, str_level);
455 }
456 if (config->per_logger_level->count == 0)
457 {
458 g_printf("\tNone\r\n");
459 }
460 #endif
461 }
462
463 struct log_config *
393464 internalInitAndAllocStruct(void)
394465 {
395 enum logReturns ret = LOG_GENERAL_ERROR;
396 g_staticLogConfig = g_new0(struct log_config, 1);
397
398 if (g_staticLogConfig != NULL)
399 {
400 g_staticLogConfig->fd = -1;
401 g_staticLogConfig->enable_syslog = 0;
402 ret = LOG_STARTUP_OK;
466 struct log_config *ret = g_new0(struct log_config, 1);
467
468 if (ret != NULL)
469 {
470 ret->fd = -1;
471 ret->enable_syslog = 0;
472 ret->per_logger_level = list_create();
473 if (ret->per_logger_level != NULL)
474 {
475 ret->per_logger_level->auto_free = 1;
476 }
477 else
478 {
479 g_writeln("could not allocate memory for log struct");
480 g_free(ret);
481 ret = NULL;
482 }
403483 }
404484 else
405485 {
406486 g_writeln("could not allocate memory for log struct");
407 ret = LOG_ERROR_MALLOC;
408487 }
409488
410489 return ret;
490 }
491
492 void
493 internal_log_config_copy(struct log_config *dest, const struct log_config *src)
494 {
495 int i;
496
497 dest->enable_syslog = src->enable_syslog;
498 dest->fd = src->fd;
499 dest->log_file = g_strdup(src->log_file);
500 dest->log_level = src->log_level;
501 dest->log_lock = src->log_lock;
502 dest->log_lock_attr = src->log_lock_attr;
503 dest->program_name = src->program_name;
504 dest->enable_syslog = src->enable_syslog;
505 dest->syslog_level = src->syslog_level;
506 dest->enable_console = src->enable_console;
507 dest->console_level = src->console_level;
508 dest->enable_pid = src->enable_pid;
509 dest->dump_on_start = src->dump_on_start;
510 for (i = 0; i < src->per_logger_level->count; ++i)
511 {
512 struct log_logger_level *dst_logger =
513 (struct log_logger_level *)g_malloc(sizeof(struct log_logger_level), 1);
514
515 g_memcpy(dst_logger,
516 (struct log_logger_level *) list_get_item(src->per_logger_level, i),
517 sizeof(struct log_logger_level));
518
519 list_add_item(dest->per_logger_level, (tbus) dst_logger);
520 }
521 }
522
523 bool_t
524 internal_log_is_enabled_for_level(const enum logLevels log_level,
525 const bool_t override_destination_level,
526 const enum logLevels override_log_level)
527 {
528 /* Is log initialized? */
529 if (g_staticLogConfig == NULL)
530 {
531 return 0;
532 }
533 else if (g_staticLogConfig->fd < 0
534 && !g_staticLogConfig->enable_syslog
535 && !g_staticLogConfig->enable_console)
536 {
537 /* all logging outputs are disabled */
538 return 0;
539 }
540 else if (override_destination_level)
541 {
542 /* Override is enabled - should the message should be logged? */
543 return log_level <= override_log_level;
544 }
545 /* Override is disabled - Is there at least one log destination
546 * which will accept the message based on the log level? */
547 else if (g_staticLogConfig->fd >= 0
548 && log_level <= g_staticLogConfig->log_level)
549 {
550 return 1;
551 }
552 else if (g_staticLogConfig->enable_syslog
553 && log_level <= g_staticLogConfig->syslog_level)
554 {
555 return 1;
556 }
557 else if (g_staticLogConfig->enable_console
558 && log_level <= g_staticLogConfig->console_level)
559 {
560 return 1;
561 }
562 else
563 {
564 return 0;
565 }
566 }
567
568 bool_t
569 internal_log_location_overrides_level(const char *function_name,
570 const char *file_name,
571 enum logLevels *log_level_return)
572 {
573 struct log_logger_level *logger = NULL;
574 int i;
575
576 if (g_staticLogConfig == NULL)
577 {
578 return 0;
579 }
580 for (i = 0; i < g_staticLogConfig->per_logger_level->count; i++)
581 {
582 logger = (struct log_logger_level *)list_get_item(g_staticLogConfig->per_logger_level, i);
583
584 if ((logger->logger_type == LOG_TYPE_FILE
585 && 0 == g_strncmp(logger->logger_name, file_name, LOGGER_NAME_SIZE))
586 || (logger->logger_type == LOG_TYPE_FUNCTION
587 && 0 == g_strncmp(logger->logger_name, function_name, LOGGER_NAME_SIZE)))
588 {
589 *log_level_return = logger->log_level;
590 return 1;
591 }
592 }
593
594 return 0;
411595 }
412596
413597 /*
414598 * Here below the public functions
415599 */
416600
601 struct log_config *
602 log_config_init_for_console(enum logLevels lvl, const char *override_name)
603 {
604 struct log_config *config = internalInitAndAllocStruct();
605
606 if (config != NULL)
607 {
608 config->program_name = "<null>";
609 config->enable_console = 1;
610 if (override_name != NULL && override_name[0] != '\0')
611 {
612 config->console_level = internal_log_text2level(override_name);
613 }
614 else
615 {
616 config->console_level = lvl;
617 }
618 config->dump_on_start = 0; /* Don't need dump for console only */
619 }
620 return config;
621 }
622
623
624 struct log_config *
625 log_config_init_from_config(const char *iniFilename,
626 const char *applicationName,
627 const char *section_prefix)
628 {
629 int fd;
630 struct log_config *config;
631
632 if (applicationName == NULL)
633 {
634 g_writeln("Programming error your application name cannot be null");
635 return NULL;
636 }
637
638 if (iniFilename == NULL)
639 {
640 g_writeln("The inifile is null to log_config_init_from_config!");
641 return NULL;
642 }
643
644 fd = g_file_open_ex(iniFilename, 1, 0, 0, 0);
645
646 if (-1 == fd)
647 {
648 g_writeln("We could not open the configuration file to read log parameters");
649 return NULL;
650 }
651
652 /* read logging config */
653 config = internal_config_read_logging(fd, applicationName, section_prefix);
654
655 /* cleanup */
656 g_file_close(fd);
657 return config;
658 }
659
417660 enum logReturns
418 log_start_from_param(const struct log_config *iniParams)
661 log_config_free(struct log_config *config)
662 {
663 if (config != NULL)
664 {
665 if (config->per_logger_level != NULL)
666 {
667 list_delete(config->per_logger_level);
668 config->per_logger_level = NULL;
669 }
670 g_free(config);
671 }
672
673 return LOG_STARTUP_OK;
674 }
675
676 enum logReturns
677 log_start_from_param(const struct log_config *src_log_config)
419678 {
420679 enum logReturns ret = LOG_GENERAL_ERROR;
421680
425684 return ret;
426685 }
427686
428 if (iniParams == NULL)
429 {
430 g_writeln("inparam to log_start_from_param is NULL");
687 if (src_log_config == NULL)
688 {
689 g_writeln("src_log_config to log_start_from_param is NULL");
431690 return ret;
432691 }
433692 else
434693 {
435 /*Copy the struct information*/
436 ret = internalInitAndAllocStruct();
437
694 g_staticLogConfig = internalInitAndAllocStruct();
695 if (g_staticLogConfig == NULL)
696 {
697 g_writeln("internalInitAndAllocStruct failed");
698 return LOG_ERROR_MALLOC;
699 }
700 internal_log_config_copy(g_staticLogConfig, src_log_config);
701
702 ret = internal_log_start(g_staticLogConfig);
438703 if (ret != LOG_STARTUP_OK)
439704 {
440 g_writeln("internalInitAndAllocStruct failed");
441 return ret;
442 }
443
444 g_staticLogConfig->enable_syslog = iniParams->enable_syslog;
445 g_staticLogConfig->fd = iniParams->fd;
446 g_staticLogConfig->log_file = g_strdup(iniParams->log_file);
447 g_staticLogConfig->log_level = iniParams->log_level;
448 g_staticLogConfig->log_lock = iniParams->log_lock;
449 g_staticLogConfig->log_lock_attr = iniParams->log_lock_attr;
450 g_staticLogConfig->program_name = iniParams->program_name;
451 g_staticLogConfig->syslog_level = iniParams->syslog_level;
452 ret = internal_log_start(g_staticLogConfig);
453
454 if (ret != LOG_STARTUP_OK)
455 {
456705 g_writeln("Could not start log");
457706
458 if (g_staticLogConfig != NULL)
459 {
460 g_free(g_staticLogConfig);
461 g_staticLogConfig = NULL;
462 }
707 log_config_free(g_staticLogConfig);
708 g_staticLogConfig = NULL;
463709 }
464710 }
465711
477723 log_start(const char *iniFile, const char *applicationName)
478724 {
479725 enum logReturns ret = LOG_GENERAL_ERROR;
480
481 if (applicationName == NULL)
482 {
483 g_writeln("Programming error your application name cannot be null");
484 return ret;
485 }
486
487 ret = internalReadConfiguration(iniFile, applicationName);
488
489 if (ret == LOG_STARTUP_OK)
490 {
491 ret = internal_log_start(g_staticLogConfig);
726 struct log_config *config;
727
728 config = log_config_init_from_config(iniFile, applicationName, "");
729
730 if (config != NULL)
731 {
732 ret = log_start_from_param(config);
733 log_config_free(config);
492734
493735 if (ret != LOG_STARTUP_OK)
494736 {
495737 g_writeln("Could not start log");
496
497 if (g_staticLogConfig != NULL)
498 {
499 g_free(g_staticLogConfig);
500 g_staticLogConfig = NULL;
501 }
502738 }
503739 }
504740 else
519755 {
520756 enum logReturns ret = LOG_GENERAL_ERROR;
521757 ret = internal_log_end(g_staticLogConfig);
522
523 if (g_staticLogConfig != NULL)
524 {
525 g_free(g_staticLogConfig);
526 g_staticLogConfig = NULL;
527 }
758 log_config_free(g_staticLogConfig);
759 g_staticLogConfig = NULL;
528760
529761 return ret;
762 }
763
764 /*****************************************************************************/
765 /* produce a hex dump */
766 enum logReturns
767 log_hexdump_with_location(const char *function_name,
768 const char *file_name,
769 const int line_number,
770 const enum logLevels log_level,
771 const char *message,
772 const char *src,
773 int len)
774 {
775 unsigned char *line;
776 int i;
777 int dump_number_lines;
778 int dump_line_length;
779 int dump_length;
780 int dump_offset;
781 int thisline;
782 int offset;
783 char *dump_buffer;
784 enum logReturns rv;
785 enum logLevels override_log_level;
786 bool_t override_destination_level = 0;
787
788 /* Start the dump on a new line so that the first line of the dump is
789 aligned to the first column instead of to after the log message
790 preamble (eg. time, log level, ...)
791 */
792 #define HEX_DUMP_SOURCE_BYTES_PER_LINE (16)
793 #ifdef _WIN32
794 #define HEX_DUMP_HEADER ("%s Hex Dump:\r\n")
795 #define HEX_DUMP_NEWLINE_SIZE (2)
796 #else
797 #ifdef _MACOS
798 #define HEX_DUMP_HEADER ("%s Hex Dump:\r")
799 #define HEX_DUMP_NEWLINE_SIZE (1)
800 #else
801 #define HEX_DUMP_HEADER ("%s Hex Dump:\n")
802 #define HEX_DUMP_NEWLINE_SIZE (1)
803 #endif
804 #endif
805 #define HEX_DUMP_HEADER_SIZE (sizeof(HEX_DUMP_HEADER) - 1)
806
807 override_destination_level = internal_log_location_overrides_level(
808 function_name,
809 file_name,
810 &override_log_level);
811 if (!internal_log_is_enabled_for_level(log_level, override_destination_level, override_log_level))
812 {
813 return LOG_STARTUP_OK;
814 }
815
816 dump_line_length = (4 + 3 /* = 4 offset + 3 space */
817 + ((2 + 1) * HEX_DUMP_SOURCE_BYTES_PER_LINE) /* + (2 hex char + 1 space) per source byte */
818 + 2 /* + 2 space */
819 + HEX_DUMP_SOURCE_BYTES_PER_LINE
820 + HEX_DUMP_NEWLINE_SIZE);
821
822 dump_number_lines = (len / HEX_DUMP_SOURCE_BYTES_PER_LINE) + 1; /* +1 to round up */
823 dump_length = (dump_number_lines *dump_line_length /* hex dump lines */
824 + HEX_DUMP_HEADER_SIZE
825 + 1); /* terminating NULL */
826 dump_buffer = (char *)g_malloc(dump_length, 1);
827 if (dump_buffer == NULL)
828 {
829 LOG_DEVEL(LOG_LEVEL_WARNING,
830 "Failed to allocate buffer for hex dump of size %d",
831 dump_length);
832 return LOG_ERROR_MALLOC;
833 }
834
835 line = (unsigned char *)src;
836 offset = 0;
837
838 g_memcpy(dump_buffer, HEX_DUMP_HEADER, HEX_DUMP_HEADER_SIZE);
839 dump_offset = HEX_DUMP_HEADER_SIZE;
840
841 while (offset < len)
842 {
843 g_sprintf(dump_buffer + dump_offset, "%04x ", offset);
844 dump_offset += 7;
845 thisline = len - offset;
846
847 if (thisline > HEX_DUMP_SOURCE_BYTES_PER_LINE)
848 {
849 thisline = HEX_DUMP_SOURCE_BYTES_PER_LINE;
850 }
851
852 for (i = 0; i < thisline; i++)
853 {
854 g_sprintf(dump_buffer + dump_offset, "%02x ", line[i]);
855 dump_offset += 3;
856 }
857
858 for (; i < HEX_DUMP_SOURCE_BYTES_PER_LINE; i++)
859 {
860 dump_buffer[dump_offset++] = ' ';
861 dump_buffer[dump_offset++] = ' ';
862 dump_buffer[dump_offset++] = ' ';
863 }
864
865 dump_buffer[dump_offset++] = ' ';
866 dump_buffer[dump_offset++] = ' ';
867
868 for (i = 0; i < thisline; i++)
869 {
870 dump_buffer[dump_offset++] = (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.';
871 }
872
873 for (; i < HEX_DUMP_SOURCE_BYTES_PER_LINE; i++)
874 {
875 dump_buffer[dump_offset++] = ' ';
876 }
877
878 #ifdef _WIN32
879 dump_buffer[dump_offset++] = '\r';
880 dump_buffer[dump_offset++] = '\n';
881 #else
882 #ifdef _MACOS
883 dump_buffer[dump_offset++] = '\r';
884 #else
885 dump_buffer[dump_offset++] = '\n';
886 #endif
887 #endif
888 offset += thisline;
889 line += thisline;
890
891
892 if ((dump_offset - HEX_DUMP_HEADER_SIZE) % dump_line_length != 0)
893 {
894 LOG_DEVEL(LOG_LEVEL_ERROR,
895 "BUG: dump_offset (%d) at the end of a line is not a "
896 "multiple of the line length (%d)",
897 dump_offset, dump_line_length);
898 }
899
900 }
901 if (dump_offset > dump_length)
902 {
903 LOG_DEVEL(LOG_LEVEL_ERROR,
904 "BUG: dump_offset (%d) is larger than the dump_buffer length (%d)",
905 dump_offset, dump_length);
906 g_free(dump_buffer);
907 return LOG_GENERAL_ERROR;
908 }
909
910 /* replace the last new line with the end of the string since log_message
911 will add a new line */
912 dump_buffer[dump_offset - HEX_DUMP_NEWLINE_SIZE] = '\0';
913
914 rv = log_message_with_location(function_name, file_name, line_number,
915 log_level, dump_buffer, message);
916 g_free(dump_buffer);
917 return rv;
918 }
919
920 enum logReturns
921 log_message_with_location(const char *function_name,
922 const char *file_name,
923 const int line_number,
924 const enum logLevels level,
925 const char *msg,
926 ...)
927 {
928 va_list ap;
929 enum logReturns rv;
930 char buff[LOG_BUFFER_SIZE];
931 enum logLevels override_log_level = LOG_LEVEL_NEVER;
932 bool_t override_destination_level = 0;
933
934 if (g_staticLogConfig == NULL)
935 {
936 g_writeln("The log reference is NULL - log not initialized properly "
937 "when called from [%s(%s:%d)]",
938 (function_name != NULL ? function_name : "unknown_function"),
939 (file_name != NULL ? file_name : "unknown_file"),
940 line_number);
941 return LOG_ERROR_NO_CFG;
942 }
943
944 override_destination_level = internal_log_location_overrides_level(
945 function_name,
946 file_name,
947 &override_log_level);
948 if (!internal_log_is_enabled_for_level(level, override_destination_level, override_log_level))
949 {
950 return LOG_STARTUP_OK;
951 }
952
953 g_snprintf(buff, LOG_BUFFER_SIZE, "[%s(%s:%d)] %s",
954 function_name, file_name, line_number, msg);
955
956 va_start(ap, msg);
957 rv = internal_log_message(level, override_destination_level, override_log_level, buff, ap);
958 va_end(ap);
959 return rv;
530960 }
531961
532962 enum logReturns
533963 log_message(const enum logLevels lvl, const char *msg, ...)
534964 {
965 va_list ap;
966 enum logReturns rv;
967
968 va_start(ap, msg);
969 rv = internal_log_message(lvl, 0, LOG_LEVEL_NEVER, msg, ap);
970 va_end(ap);
971 return rv;
972 }
973
974 enum logReturns
975 internal_log_message(const enum logLevels lvl,
976 const bool_t override_destination_level,
977 const enum logLevels override_log_level,
978 const char *msg,
979 va_list ap)
980 {
535981 char buff[LOG_BUFFER_SIZE + 31]; /* 19 (datetime) 4 (space+cr+lf+\0) */
536 va_list ap;
537982 int len = 0;
538983 enum logReturns rv = LOG_STARTUP_OK;
539984 int writereply = 0;
546991 return LOG_ERROR_NO_CFG;
547992 }
548993
549 if (0 > g_staticLogConfig->fd && g_staticLogConfig->enable_syslog == 0)
994 if (0 > g_staticLogConfig->fd
995 && g_staticLogConfig->enable_syslog == 0
996 && g_staticLogConfig->enable_console == 0)
550997 {
551998 return LOG_ERROR_FILE_NOT_OPEN;
999 }
1000
1001 if (!internal_log_is_enabled_for_level(lvl, override_destination_level, override_log_level))
1002 {
1003 return LOG_STARTUP_OK;
5521004 }
5531005
5541006 now_t = time(&now_t);
5551007 now = localtime(&now_t);
5561008
557 snprintf(buff, 21, "[%.4d%.2d%.2d-%.2d:%.2d:%.2d] ", now->tm_year + 1900,
558 now->tm_mon + 1, now->tm_mday, now->tm_hour, now->tm_min,
559 now->tm_sec);
1009 strftime(buff, 21, "[%Y%m%d-%H:%M:%S] ", now);
5601010
5611011 internal_log_lvl2str(lvl, buff + 20);
5621012
563 va_start(ap, msg);
564 len = vsnprintf(buff + 28, LOG_BUFFER_SIZE, msg, ap);
565 va_end(ap);
1013 if (g_staticLogConfig->enable_pid)
1014 {
1015 g_snprintf(buff + 28, LOG_BUFFER_SIZE, "[pid:%d tid:%lld] ",
1016 g_getpid(), (long long) tc_get_threadid());
1017 len = g_strlen(buff + 28);
1018 }
1019 len += vsnprintf(buff + 28 + len, LOG_BUFFER_SIZE - len, msg, ap);
5661020
5671021 /* checking for truncated messages */
5681022 if (len > LOG_BUFFER_SIZE)
5691023 {
5701024 log_message(LOG_LEVEL_WARNING, "next message will be truncated");
1025 len = LOG_BUFFER_SIZE;
5711026 }
5721027
5731028 /* forcing the end of message string */
5851040 #endif
5861041 #endif
5871042
588 if (g_staticLogConfig->enable_syslog && (lvl <= g_staticLogConfig->syslog_level))
1043 if (g_staticLogConfig->enable_syslog
1044 && ((override_destination_level && lvl <= override_log_level)
1045 || (!override_destination_level && lvl <= g_staticLogConfig->syslog_level)))
5891046 {
5901047 /* log to syslog*/
5911048 /* %s fix compiler warning 'not a string literal' */
592 syslog(internal_log_xrdp2syslog(lvl), "(%d)(%lld)%s", g_getpid(),
593 (long long) tc_get_threadid(), buff + 20);
594 }
595
596 if (lvl <= g_staticLogConfig->log_level)
1049 syslog(internal_log_xrdp2syslog(lvl), "%s", buff + 20);
1050 }
1051
1052 if (g_staticLogConfig->enable_console
1053 && ((override_destination_level && lvl <= override_log_level)
1054 || (!override_destination_level && lvl <= g_staticLogConfig->console_level)))
5971055 {
5981056 /* log to console */
5991057 g_printf("%s", buff);
600
1058 }
1059
1060 if ((override_destination_level && lvl <= override_log_level)
1061 || (!override_destination_level && lvl <= g_staticLogConfig->log_level))
1062 {
6011063 /* log to application logfile */
1064 if (g_staticLogConfig->fd >= 0)
1065 {
6021066 #ifdef LOG_ENABLE_THREAD
603 pthread_mutex_lock(&(g_staticLogConfig->log_lock));
604 #endif
605
606 if (g_staticLogConfig->fd >= 0)
607 {
1067 pthread_mutex_lock(&(g_staticLogConfig->log_lock));
1068 #endif
1069
6081070 writereply = g_file_write(g_staticLogConfig->fd, buff, g_strlen(buff));
6091071
6101072 if (writereply <= 0)
6111073 {
6121074 rv = LOG_ERROR_NULL_FILE;
6131075 }
614 }
6151076
6161077 #ifdef LOG_ENABLE_THREAD
617 pthread_mutex_unlock(&(g_staticLogConfig->log_lock));
618 #endif
1078 pthread_mutex_unlock(&(g_staticLogConfig->log_lock));
1079 #endif
1080 }
6191081 }
6201082
6211083 return rv;
2121 #include <pthread.h>
2222
2323 #include "arch.h"
24 #include "list.h"
2425
2526 /* logging buffer size */
26 #define LOG_BUFFER_SIZE 1024
27 #define LOG_BUFFER_SIZE 8192
28 #define LOGGER_NAME_SIZE 50
2729
2830 /* logging levels */
2931 enum logLevels
3032 {
3133 LOG_LEVEL_ALWAYS = 0,
32 LOG_LEVEL_ERROR,
33 LOG_LEVEL_WARNING,
34 LOG_LEVEL_INFO,
35 LOG_LEVEL_DEBUG,
36 LOG_LEVEL_TRACE
34 LOG_LEVEL_ERROR, /* for describing non-recoverable error states in a request or method */
35 LOG_LEVEL_WARNING, /* for describing recoverable error states in a request or method */
36 LOG_LEVEL_INFO, /* for low verbosity and high level descriptions of normal operations */
37 LOG_LEVEL_DEBUG, /* for medium verbosity and low level descriptions of normal operations */
38 LOG_LEVEL_TRACE, /* for high verbosity and low level descriptions of normal operations (eg. method or wire tracing) */
39 LOG_LEVEL_NEVER,
3740 };
3841
3942 /* startup return values */
4851 LOG_GENERAL_ERROR
4952 };
5053
51 #define SESMAN_CFG_LOGGING "Logging"
52 #define SESMAN_CFG_LOG_FILE "LogFile"
53 #define SESMAN_CFG_LOG_LEVEL "LogLevel"
54 #define SESMAN_CFG_LOG_ENABLE_SYSLOG "EnableSyslog"
55 #define SESMAN_CFG_LOG_SYSLOG_LEVEL "SyslogLevel"
54 #define SESMAN_CFG_LOGGING "Logging"
55 #define SESMAN_CFG_LOGGING_LOGGER "LoggingPerLogger"
56 #define SESMAN_CFG_LOG_FILE "LogFile"
57 #define SESMAN_CFG_LOG_LEVEL "LogLevel"
58 #define SESMAN_CFG_LOG_ENABLE_CONSOLE "EnableConsole"
59 #define SESMAN_CFG_LOG_CONSOLE_LEVEL "ConsoleLevel"
60 #define SESMAN_CFG_LOG_ENABLE_SYSLOG "EnableSyslog"
61 #define SESMAN_CFG_LOG_SYSLOG_LEVEL "SyslogLevel"
62 #define SESMAN_CFG_LOG_ENABLE_PID "EnableProcessId"
5663
5764 /* enable threading */
5865 /*#define LOG_ENABLE_THREAD*/
5966
6067 #ifdef XRDP_DEBUG
61 #define LOG_DBG(args...) log_message(LOG_LEVEL_DEBUG, args);
68
69 #define LOG_PER_LOGGER_LEVEL
70
71 /**
72 * @brief Logging macro for messages that are for an XRDP developer to
73 * understand and debug XRDP code.
74 *
75 * Note: all log levels are relavant to help a developer understand XRDP at
76 * different levels of granularity.
77 *
78 * Note: the logging function calls are removed when XRDP_DEBUG is NOT defined.
79 *
80 * Note: when the build is configured with --enable-xrdpdebug, then
81 * the log level can be configured per the source file name or method name
82 * (with the suffix "()") in the [LoggingPerLogger]
83 * section of the configuration file.
84 *
85 * For example:
86 * ```
87 * [LoggingPerLogger]
88 * xrdp.c=DEBUG
89 * main()=WARNING
90 * ```
91 *
92 * @param lvl, the log level
93 * @param msg, the log text as a printf format c-string
94 * @param ... the arguments for the printf format c-string
95 */
96 #define LOG_DEVEL(log_level, args...) \
97 log_message_with_location(__func__, __FILE__, __LINE__, log_level, args);
98
99 /**
100 * @brief Logging macro for messages that are for a systeam administrator to
101 * configure and run XRDP on their machine.
102 *
103 * Note: the logging function calls contain additional code location info when
104 * XRDP_DEBUG is defined.
105 *
106 * @param lvl, the log level
107 * @param msg, the log text as a printf format c-string
108 * @param ... the arguments for the printf format c-string
109 */
110 #define LOG(log_level, args...) \
111 log_message_with_location(__func__, __FILE__, __LINE__, log_level, args);
112
113 /**
114 * @brief Logging macro for logging the contents of a byte array using a hex
115 * dump format.
116 *
117 * Note: the logging function calls are removed when XRDP_DEBUG is NOT defined.
118 *
119 * @param log_level, the log level
120 * @param message, a message prefix for the hex dump. Note: no printf like
121 * formatting is done to this message.
122 * @param buffer, a pointer to the byte array to log as a hex dump
123 * @param length, the length of the byte array to log
124 */
125 #define LOG_DEVEL_HEXDUMP(log_level, message, buffer, length) \
126 log_hexdump_with_location(__func__, __FILE__, __LINE__, log_level, message, buffer, length);
127
62128 #else
63 #define LOG_DBG(args...)
129 #define LOG_DEVEL(log_level, args...)
130 #define LOG(log_level, args...) log_message(log_level, args);
131 #define LOG_DEVEL_HEXDUMP(log_level, message, buffer, length)
132
64133 #endif
134
135 enum log_logger_type
136 {
137 LOG_TYPE_FILE = 0,
138 LOG_TYPE_FUNCTION,
139 };
140
141 struct log_logger_level
142 {
143 enum logLevels log_level;
144 enum log_logger_type logger_type;
145 char logger_name[LOGGER_NAME_SIZE + 1];
146 };
65147
66148 struct log_config
67149 {
69151 char *log_file;
70152 int fd;
71153 enum logLevels log_level;
154 int enable_console;
155 enum logLevels console_level;
72156 int enable_syslog;
73157 enum logLevels syslog_level;
158 struct list *per_logger_level;
159 int dump_on_start;
160 int enable_pid;
74161 pthread_mutex_t log_lock;
75162 pthread_mutexattr_t log_lock_attr;
76163 };
113200 *
114201 */
115202 enum logLevels
116 internal_log_text2level(const char *s);
203 internal_log_text2level(const char *buf);
117204
118205 /**
119206 * A function that init our struct that holds all state and
120207 * also init its content.
121208 * @return LOG_STARTUP_OK or LOG_ERROR_MALLOC
122209 */
123 enum logReturns
210 struct log_config *
124211 internalInitAndAllocStruct(void);
125212
126213 /**
127 * Read configuration from a file and store the values in lists.
128 * @param file
129 * @param lc
130 * @param param_n
131 * @param param_v
132 * @param applicationName, the application name used in the log events.
133 * @return
134 */
135 enum logReturns
136 internal_config_read_logging(int file, struct log_config *lc,
137 struct list *param_n,
138 struct list *param_v,
139 const char *applicationName);
214 * Print the contents of the logging config to stdout.
215 */
216 void
217 internal_log_config_dump(struct log_config *config);
218
219 /**
220 * the log function that all files use to log an event.
221 * @param lvl, the loglevel
222 * @param override_destination_level, if true then the destination log level is not used
223 * @param override_log_level, the loglevel instead of the destination log level if override_destination_level is true
224 * @param msg, the logtext.
225 * @param ap, the values for the message format arguments
226 * @return
227 */
228 enum logReturns
229 internal_log_message(const enum logLevels lvl,
230 const bool_t override_destination_level,
231 const enum logLevels override_log_level,
232 const char *msg,
233 va_list ap);
234
235 /**
236 * @param log_level, the log level
237 * @param override_destination_level, if true then the destination log level is ignored.
238 * @param override_log_level, the log level to use instead of the destination log level
239 * if override_destination_level is true
240 * @return true if at least one log destination will accept a message logged at the given level.
241 */
242 bool_t
243 internal_log_is_enabled_for_level(const enum logLevels log_level,
244 const bool_t override_destination_level,
245 const enum logLevels override_log_level);
246
247 /**
248 * @param function_name, the function name (typicaly the __func__ macro)
249 * @param file_name, the file name (typicaly the __FILE__ macro)
250 * @param[out] log_level_return, the log level to use instead of the destination log level
251 * @return true if the logger location overrides the destination log levels
252 */
253 bool_t
254 internal_log_location_overrides_level(const char *function_name,
255 const char *file_name,
256 enum logLevels *log_level_return);
257
140258 /*End of internal functions*/
141259 #endif
260
142261 /**
143262 * This function initialize the log facilities according to the configuration
144263 * file, that is described by the in parameter.
151270
152271 /**
153272 * An alternative log_start where the caller gives the params directly.
154 * @param iniParams
155 * @return
156 */
157 enum logReturns
158 log_start_from_param(const struct log_config *iniParams);
273 * @param config
274 * @return
275 *
276 * @post to avoid memory leaks, the config argument must be free'ed using
277 * `log_config_free()`
278 */
279 enum logReturns
280 log_start_from_param(const struct log_config *src_log_config);
281
282 /**
283 * Sets up a suitable log config for writing to the console only
284 * (i.e. for a utility)
285 *
286 * The config can be customised by the caller before calling
287 * log_start_from_param()
288 *
289 * @param Default log level
290 * @param Log level name, or NULL. This can be used to provide an
291 * override to the default log level, by environment variable or
292 * argument.
293 *
294 * @return pointer to struct log_config.
295 */
296 struct log_config *
297 log_config_init_for_console(enum logLevels lvl, const char *override_name);
298
299 /**
300 * Read configuration from a file and store the values in the returned
301 * log_config.
302 * @param file
303 * @param applicationName, the application name used in the log events.
304 * @param section_prefix, prefix for the logging sections to parse
305 * @return
306 */
307 struct log_config *
308 log_config_init_from_config(const char *iniFilename,
309 const char *applicationName,
310 const char *section_prefix);
311
312 /**
313 * Free the memory for the log_config struct.
314 */
315 enum logReturns
316 log_config_free(struct log_config *config);
317
159318 /**
160319 * Function that terminates all logging
161320 * @return
165324
166325 /**
167326 * the log function that all files use to log an event.
327 *
328 * Please prefer to use the LOG and LOG_DEVEL macros instead of this function directly.
329 *
168330 * @param lvl, the loglevel
169331 * @param msg, the logtext.
170332 * @param ...
174336 log_message(const enum logLevels lvl, const char *msg, ...) printflike(2, 3);
175337
176338 /**
339 * the log function that all files use to log an event,
340 * with the function name and file line.
341 *
342 * Please prefer to use the LOG and LOG_DEVEL macros instead of this function directly.
343 *
344 * @param function_name, the function name (typicaly the __func__ macro)
345 * @param file_name, the file name (typicaly the __FILE__ macro)
346 * @param line_number, the line number in the file (typicaly the __LINE__ macro)
347 * @param lvl, the loglevel
348 * @param msg, the logtext.
349 * @param ...
350 * @return
351 */
352 enum logReturns
353 log_message_with_location(const char *function_name,
354 const char *file_name,
355 const int line_number,
356 const enum logLevels lvl,
357 const char *msg,
358 ...) printflike(5, 6);
359
360 enum logReturns
361 log_hexdump_with_location(const char *function_name,
362 const char *file_name,
363 const int line_number,
364 const enum logLevels log_level,
365 const char *msg,
366 const char *p,
367 int len);
368
369 /**
177370 * This function returns the configured file name for the logfile
178371 * @param replybuf the buffer where the reply is stored
179372 * @param bufsize how big is the reply buffer.
0 /**
1 * xrdp: A Remote Desktop Protocol server.
2 *
3 * MS-ERREF : Definitions from [MS-ERREF]
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * References to MS-ERREF are currently correct for v20180912 of that
18 * document
19 */
20
21 #if !defined(MS_ERREF_H)
22 #define MS_ERREF_H
23
24 /*
25 * NTSTATUS codes (section 2.3)
26 */
27 enum NTSTATUS
28 {
29 STATUS_SUCCESS = 0x00000000,
30
31 STATUS_NO_MORE_FILES = 0x80000006,
32
33 STATUS_UNSUCCESSFUL = 0xc0000001,
34 STATUS_NO_SUCH_FILE = 0xc000000f,
35 STATUS_ACCESS_DENIED = 0xc0000022,
36 STATUS_OBJECT_NAME_INVALID = 0xc0000033,
37 STATUS_OBJECT_NAME_NOT_FOUND = 0xc0000034,
38 STATUS_SHARING_VIOLATION = 0xc0000043,
39 STATUS_NOT_SUPPORTED = 0xc00000bb
40 };
41
42 #endif /* MS_ERREF_H */
0 /**
1 * xrdp: A Remote Desktop Protocol server.
2 *
3 * MS-FSCC : Definitions from [MS-FSCC]
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * References to MS-FSCC are currently correct for v20190923 of that
18 * document
19 */
20
21 #if !defined(MS_FSCC_H)
22 #define MS_FSCC_H
23
24 /*
25 * File system ioctl codes (section 2.3)
26 */
27 #define FSCTL_DELETE_OBJECT_ID 0x900a0
28
29 /*
30 * File information classes (section 2.4)
31 */
32 enum FS_INFORMATION_CLASS
33 {
34 FileAllocationInformation = 19, /* Set */
35 FileBasicInformation = 4, /* Query, Set */
36 FileBothDirectoryInformation = 3, /* Query */
37 FileDirectoryInformation = 1, /* Query */
38 FileDispositionInformation = 13, /* Set */
39 FileEndOfFileInformation = 20, /* Set */
40 FileFullDirectoryInformation = 2, /* Query */
41 FileNamesInformation = 12, /* Query */
42 FileRenameInformation = 10, /* Set */
43 FileStandardInformation = 5 /* Query */
44 };
45
46 /*
47 * Size of structs above without trailing RESERVED fields (MS-RDPEFS
48 * 2.2.3.3.8)
49 */
50 #define FILE_BASIC_INFORMATION_SIZE 36
51 #define FILE_STD_INFORMATION_SIZE 22
52 #define FILE_END_OF_FILE_INFORMATION_SIZE 8
53
54 /* Windows file attributes (section 2.6) */
55 #define W_FILE_ATTRIBUTE_DIRECTORY 0x00000010
56 #define W_FILE_ATTRIBUTE_READONLY 0x00000001
57 #define W_FILE_ATTRIBUTE_SYSTEM 0x00000004
58 #define W_FILE_ATTRIBUTE_NORMAL 0x00000080
59
60 #endif /* MS_FSCC_H */
61
62
63
0 /**
1 * xrdp: A Remote Desktop Protocol server.
2 *
3 * MS-RDPBCGR : Definitions from [MS-RDPBCGR]
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * References to MS-RDPBCGR are currently correct for v20190923 of that
18 * document
19 */
20
21 #if !defined(MS_RDPBCGR_H)
22 #define MS_RDPBCGR_H
23
24 /* RDP Security Negotiation codes */
25 #define RDP_NEG_REQ 0x01 /* MS-RDPBCGR 2.2.1.1.1 */
26 #define RDP_NEG_RSP 0x02 /* MS-RDPBCGR 2.2.1.2.1 */
27 #define RDP_NEG_FAILURE 0x03 /* MS-RDPBCGR 2.2.1.2.2 */
28 #define RDP_CORRELATION_INFO 0x06 /* MS-RDPBCGR 2.2.1.1.2 */
29
30 /* Protocol types codes (2.2.1.1.1, 2.2.1.2.1) */
31 #define PROTOCOL_RDP 0x00000000
32 #define PROTOCOL_SSL 0x00000001
33 #define PROTOCOL_HYBRID 0x00000002
34 #define PROTOCOL_RDSTLS 0x00000004
35 #define PROTOCOL_HYBRID_EX 0x00000008
36
37 /* Negotiation packet flags (2.2.1.2.1) */
38 #define EXTENDED_CLIENT_DATA_SUPPORTED 0x01
39 #define DYNVC_GFX_PROTOCOL_SUPPORTED 0x02
40 #define NEGRSP_RESERVED 0x04
41 #define RESTRICTED_ADMIN_MODE_SUPPORTED 0x08
42 #define REDIRECTED_AUTHENTICATION_MODE_SUPPORTED 0x10
43
44 /* RDP Negotiation Failure Codes (2.2.1.2.2) */
45 #define SSL_REQUIRED_BY_SERVER 0x00000001
46 #define SSL_NOT_ALLOWED_BY_SERVER 0x00000002
47 #define SSL_CERT_NOT_ON_SERVER 0x00000003
48 #define INCONSISTENT_FLAGS 0x00000004
49 #define HYBRID_REQUIRED_BY_SERVER 0x00000005
50 #define SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER 0x00000006
51
52 /* TS_UD_HEADER: type ((2.2.1.3.1) */
53 /* TODO: to be renamed */
54 #define SEC_TAG_CLI_INFO 0xc001 /* CS_CORE? */
55 #define SEC_TAG_CLI_CRYPT 0xc002 /* CS_SECURITY? */
56 #define SEC_TAG_CLI_CHANNELS 0xc003 /* CS_CHANNELS? */
57 #define SEC_TAG_CLI_4 0xc004 /* CS_CLUSTER? */
58 #define SEC_TAG_CLI_MONITOR 0xc005 /* CS_MONITOR */
59
60 /* Client Core Data: colorDepth, postBeta2ColorDepth (2.2.1.3.2) */
61 #define RNS_UD_COLOR_4BPP 0xCA00
62 #define RNS_UD_COLOR_8BPP 0xCA01
63 #define RNS_UD_COLOR_16BPP_555 0xCA02
64 #define RNS_UD_COLOR_16BPP_565 0xCA03
65 #define RNS_UD_COLOR_24BPP 0xCA04
66
67 /* Client Core Data: connectionType (2.2.1.3.2) */
68 #define CONNECTION_TYPE_MODEM 0x01
69 #define CONNECTION_TYPE_BROADBAND_LOW 0x02
70 #define CONNECTION_TYPE_SATELLITE 0x03
71 #define CONNECTION_TYPE_BROADBAND_HIGH 0x04
72 #define CONNECTION_TYPE_WAN 0x05
73 #define CONNECTION_TYPE_LAN 0x06
74 #define CONNECTION_TYPE_AUTODETECT 0x07
75
76 /* Channel definition structure CHANNEL_DEF (2.2.1.3.4.1) */
77 /* This isn't explicitly named in MS-RDPBCGR */
78 #define CHANNEL_NAME_LEN 7
79
80 /* Oprions field */
81 /* NOTE: XR_ prefixed to avoid conflict with FreeRDP */
82 #define XR_CHANNEL_OPTION_INITIALIZED 0x80000000
83 #define XR_CHANNEL_OPTION_ENCRYPT_RDP 0x40000000
84 #define XR_CHANNEL_OPTION_ENCRYPT_SC 0x20000000
85 #define XR_CHANNEL_OPTION_ENCRYPT_CS 0x10000000
86 #define XR_CHANNEL_OPTION_PRI_HIGH 0x08000000
87 #define XR_CHANNEL_OPTION_PRI_MED 0x04000000
88 #define XR_CHANNEL_OPTION_PRI_LOW 0x02000000
89 #define XR_CHANNEL_OPTION_COMPRESS_RDP 0x00800000
90 #define XR_CHANNEL_OPTION_COMPRESS 0x00400000
91 #define XR_CHANNEL_OPTION_SHOW_PROTOCOL 0x00200000
92 #define REMOTE_CONTROL_PERSISTENT 0x00100000
93
94 /* Server Proprietary Certificate (2.2.1.4.3.1.1) */
95 /* TODO: to be renamed */
96 #define SEC_TAG_PUBKEY 0x0006 /* BB_RSA_KEY_BLOB */
97 #define SEC_TAG_KEYSIG 0x0008 /* BB_SIGNATURE_KEY_BLOB */
98
99 /* Info Packet (TS_INFO_PACKET): flags (2.2.1.11.1.1) */
100 /* TODO: to be renamed */
101 #define RDP_LOGON_AUTO 0x0008
102 #define RDP_LOGON_NORMAL 0x0033
103 #define RDP_COMPRESSION 0x0080
104 #define RDP_LOGON_BLOB 0x0100
105 #define RDP_LOGON_LEAVE_AUDIO 0x2000
106 #define RDP_LOGON_RAIL 0x8000
107
108 /* Extended Info Packet: performanceFlags (2.2.1.11.1.1.1) */
109 /* TODO: to be renamed */
110 #define RDP5_DISABLE_NOTHING 0x00
111 #define RDP5_NO_WALLPAPER 0x01
112 #define RDP5_NO_FULLWINDOWDRAG 0x02
113 #define RDP5_NO_MENUANIMATIONS 0x04
114 #define RDP5_NO_THEMING 0x08
115 #define RDP5_NO_CURSOR_SHADOW 0x20
116 #define RDP5_NO_CURSORSETTINGS 0x40 /* disables cursor blinking */
117
118 /* LICENSE_BINARY_BLOB (2.2.1.12.1.2) */
119 #define LICENCE_TAG_USER 0x000f /* BB_CLIENT_USER_NAME_BLOB */
120 #define LICENCE_TAG_HOST 0x0010 /* BB_CLIENT_MACHINE_NAME_BLOB */
121
122 /* Maps to generalCapabilitySet in T.128 page 138 */
123
124 /* Capability Set: capabilitySetType (2.2.1.13.1.1.1) */
125 #define CAPSTYPE_GENERAL 0x0001
126 #define CAPSTYPE_GENERAL_LEN 0x18
127
128 #define CAPSTYPE_BITMAP 0x0002
129 #define CAPSTYPE_BITMAP_LEN 0x1C
130
131 #define CAPSTYPE_ORDER 0x0003
132 #define CAPSTYPE_ORDER_LEN 0x58
133 #define ORDER_CAP_NEGOTIATE 2 /* NEGOTIATEORDERSUPPORT? not used */
134 #define ORDER_CAP_NOSUPPORT 4 /* not used */
135
136 #define CAPSTYPE_BITMAPCACHE 0x0004
137 #define CAPSTYPE_BITMAPCACHE_LEN 0x28
138
139 #define CAPSTYPE_CONTROL 0x0005
140 #define CAPSTYPE_CONTROL_LEN 0x0C
141
142 #define CAPSTYPE_ACTIVATION 0x0007
143 #define CAPSTYPE_ACTIVATION_LEN 0x0C
144
145 #define CAPSTYPE_POINTER 0x0008
146 #define CAPSTYPE_POINTER_LEN 0x0a
147 #define CAPSTYPE_POINTER_MONO_LEN 0x08
148
149 #define CAPSTYPE_SHARE 0x0009
150 #define CAPSTYPE_SHARE_LEN 0x08
151
152 #define CAPSTYPE_COLORCACHE 0x000A
153 #define CAPSTYPE_COLORCACHE_LEN 0x08
154
155 #define CAPSTYPE_SOUND 0x000C
156
157 #define CAPSTYPE_INPUT 0x000D
158 #define CAPSTYPE_INPUT_LEN 0x58
159
160 #define CAPSTYPE_FONT 0x000E
161 #define CAPSTYPE_FONT_LEN 0x04
162
163 #define CAPSTYPE_BRUSH 0x000F
164 #define CAPSTYPE_BRUSH_LEN 0x08
165
166 #define CAPSTYPE_GLYPHCACHE 0x0010
167 #define CAPSTYPE_OFFSCREENCACHE 0x0011
168
169 #define CAPSTYPE_BITMAPCACHE_HOSTSUPPORT 0x0012
170 #define CAPSTYPE_BITMAPCACHE_HOSTSUPPORT_LEN 0x08
171
172 #define CAPSTYPE_BITMAPCACHE_REV2 0x0013
173 #define CAPSTYPE_BITMAPCACHE_REV2_LEN 0x28
174 #define BMPCACHE2_FLAG_PERSIST ((long)1<<31)
175
176 #define CAPSTYPE_VIRTUALCHANNEL 0x0014
177 #define CAPSTYPE_VIRTUALCHANNEL_LEN 0x08
178
179 #define CAPSTYPE_DRAWNINGRIDCACHE 0x0015
180 #define CAPSTYPE_DRAWGDIPLUS 0x0016
181 #define CAPSTYPE_RAIL 0x0017
182 #define CAPSTYPE_WINDOW 0x0018
183
184 #define CAPSSETTYPE_COMPDESK 0x0019
185 #define CAPSSETTYPE_COMPDESK_LEN 0x06
186
187 #define CAPSSETTYPE_MULTIFRAGMENTUPDATE 0x001A
188 #define CAPSSETTYPE_MULTIFRAGMENTUPDATE_LEN 0x08
189
190 #define CAPSETTYPE_LARGE_POINTER 0x001B
191 #define CAPSETTYPE_LARGE_POINTER_LEN 0x06
192
193 #define CAPSETTYPE_SURFACE_COMMANDS 0x001C
194 #define CAPSETTYPE_SURFACE_COMMANDS_LEN 0x0C
195
196 #define CAPSSETTYPE_BITMAP_CODECS 0x001D
197 #define CAPSSETTYPE_BITMAP_CODECS_LEN 0x1C
198
199 #define CAPSTYPE_FRAME_ACKNOWLEDGE 0x001E
200 #define CAPSTYPE_FRAME_ACKNOWLEDGE_LEN 0x08
201
202 /* Control PDU Data: action (2.2.1.15.1) */
203 /* TODO: to be renamed */
204 #define RDP_CTL_REQUEST_CONTROL 1 /* CTRLACTION_REQUEST_CONTROL */
205 #define RDP_CTL_GRANT_CONTROL 2
206 #define RDP_CTL_DETACH 3
207 #define RDP_CTL_COOPERATE 4
208
209 /* RDP5 disconnect PDU */
210 /* Set Error Info PDU Data: errorInfo (2.2.5.1.1) */
211 /* TODO: to be renamed */
212 #define exDiscReasonNoInfo 0x0000
213 #define exDiscReasonAPIInitiatedDisconnect 0x0001
214 #define exDiscReasonAPIInitiatedLogoff 0x0002
215 #define exDiscReasonServerIdleTimeout 0x0003
216 #define exDiscReasonServerLogonTimeout 0x0004
217 #define exDiscReasonReplacedByOtherConnection 0x0005
218 #define exDiscReasonOutOfMemory 0x0006
219 #define exDiscReasonServerDeniedConnection 0x0007
220 #define exDiscReasonServerDeniedConnectionFips 0x0008
221 #define exDiscReasonLicenseInternal 0x0100
222 #define exDiscReasonLicenseNoLicenseServer 0x0101
223 #define exDiscReasonLicenseNoLicense 0x0102
224 #define exDiscReasonLicenseErrClientMsg 0x0103
225 #define exDiscReasonLicenseHwidDoesntMatchLicense 0x0104
226 #define exDiscReasonLicenseErrClientLicense 0x0105
227 #define exDiscReasonLicenseCantFinishProtocol 0x0106
228 #define exDiscReasonLicenseClientEndedProtocol 0x0107
229 #define exDiscReasonLicenseErrClientEncryption 0x0108
230 #define exDiscReasonLicenseCantUpgradeLicense 0x0109
231 #define exDiscReasonLicenseNoRemoteConnections 0x010a
232
233 /* General Capability Set: osMajorType (2.2.7.1.1) */
234 #define OSMAJORTYPE_UNSPECIFIED 0x0000
235 #define OSMAJORTYPE_WINDOWS 0x0001
236 #define OSMAJORTYPE_OS2 0x0002
237 #define OSMAJORTYPE_MACINTOSH 0x0003
238 #define OSMAJORTYPE_UNIX 0x0004
239 #define OSMAJORTYPE_IOS 0x0005
240 #define OSMAJORTYPE_OSX 0x0006
241 #define OSMAJORTYPE_ANDROID 0x0007
242 #define OSMAJORTYPE_CHROME_OS 0x0008
243
244 /* General Capability Set: osMinorType (2.2.7.1.1) */
245 #define OSMINORTYPE_UNSPECIFIED 0x0000
246 #define OSMINORTYPE_WINDOWS_31X 0x0001
247 #define OSMINORTYPE_WINDOWS_95 0x0002
248 #define OSMINORTYPE_WINDOWS_NT 0x0003
249 #define OSMINORTYPE_OS2_V21 0x0004
250 #define OSMINORTYPE_POWER_PC 0x0005
251 #define OSMINORTYPE_MACINTOSH 0x0006
252 #define OSMINORTYPE_NATIVE_XSERVER 0x0007
253 #define OSMINORTYPE_PSEUDO_XSERVER 0x0008
254 #define OSMINORTYPE_WINDOWS_RT 0x0009
255
256 /* General Capability Set: protocolVersion (2.2.7.1.1) */
257 #define TS_CAPS_PROTOCOLVERSION 0x0200
258
259 /* General Capability Set: extraFlags (2.2.7.1.1) */
260 #define FASTPATH_OUTPUT_SUPPORTED 0x0001
261 #define NO_BITMAP_COMPRESSION_HDR 0x0400
262 #define LONG_CREDENTIALS_SUPPORTED 0x0004
263 #define AUTORECONNECT_SUPPORTED 0x0008
264 #define ENC_SALTED_CHECKSUM 0x0010
265
266 /* Order Capability Set: orderSupportExFlags (2.2.7.1.3) */
267 /* NOTE: XR_ prefixed to avoid conflict with FreeRDP */
268 #define XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT 0x0002
269 #define XR_ORDERFLAGS_EX_ALTSEC_FRAME_MARKER_SUPPORT 0x0004
270
271 /* Order Capability Set: orderFlags (2.2.7.1.3) */
272 #define NEGOTIATEORDERSUPPORT 0x0002
273 #define ZEROBOUNDSDELTASUPPORT 0x0008
274 #define COLORINDEXSUPPORT 0x0020
275 #define SOLIDPATTERNBRUSHONLY 0x0040
276 #define ORDERFLAGS_EXTRA_FLAGS 0x0080
277
278 /* Order Capability Set: orderSupport (2.2.7.1.3) */
279 #define TS_NEG_DSTBLT_INDEX 0x00
280 #define TS_NEG_PATBLT_INDEX 0x01
281 #define TS_NEG_SCRBLT_INDEX 0x02
282 #define TS_NEG_MEMBLT_INDEX 0x03
283 #define TS_NEG_MEM3BLT_INDEX 0x04
284 /* 0x05 */
285 /* 0x06 */
286 #define TS_NEG_DRAWNINEGRID_INDEX 0x07
287 #define TS_NEG_LINETO_INDEX 0x08
288 #define TS_NEG_MULTI_DRAWNINEGRID_INDEX 0x09
289 /* 0x0A */
290 #define TS_NEG_SAVEBITMAP_INDEX 0x0B
291 /* 0x0C */
292 /* 0x0D */
293 /* 0x0E */
294 #define TS_NEG_MULTIDSTBLT_INDEX 0x0F
295 #define TS_NEG_MULTIPATBLT_INDEX 0x10
296 #define TS_NEG_MULTISCRBLT_INDEX 0x11
297 #define TS_NEG_MULTIOPAQUERECT_INDEX 0x12
298 #define TS_NEG_FAST_INDEX_INDEX 0x13
299 #define TS_NEG_POLYGON_SC_INDEX 0x14
300 #define TS_NEG_POLYGON_CB_INDEX 0x15
301 #define TS_NEG_POLYLINE_INDEX 0x16
302 /* 0x17 */
303 #define TS_NEG_FAST_GLYPH_INDEX 0x18
304 #define TS_NEG_ELLIPSE_SC_INDEX 0x19
305 #define TS_NEG_ELLIPSE_CB_INDEX 0x1A
306 #define TS_NEG_INDEX_INDEX 0x1B
307 /* 0x1C */
308 /* 0x1D */
309 /* 0x1E */
310 /* 0x1F */
311
312 /* Input Capability Set: inputFlags (2.2.7.1.6) */
313 #define INPUT_FLAG_SCANCODES 0x0001
314 #define INPUT_FLAG_MOUSEX 0x0004
315 #define INPUT_FLAG_FASTPATH_INPUT 0x0008
316 #define INPUT_FLAG_UNICODE 0x0010
317 #define INPUT_FLAG_FASTPATH_INPUT2 0x0020
318 #define INPUT_FLAG_UNUSED1 0x0040
319 #define INPUT_FLAG_UNUSED2 0x0080
320 #define TS_INPUT_FLAG_MOUSE_HWHEEL 0x0100
321 #define TS_INPUT_FLAG_QOE_TIMESTAMPS 0x0200
322
323 /* Glyph Cache Capability Set: GlyphSupportLevel (2.2.7.1.8) */
324 #define GLYPH_SUPPORT_NONE 0x0000
325 #define GLYPH_SUPPORT_PARTIAL 0x0001
326 #define GLYPH_SUPPORT_FULL 0x0002
327 #define GLYPH_SUPPORT_ENCODE 0x0003
328
329 /* Desktop Composition Capability Set: CompDeskSupportLevel (2.2.7.2.8) */
330 #define COMPDESK_NOT_SUPPORTED 0x0000
331 #define COMPDESK_SUPPORTED 0x0001
332
333 /* Surface Commands Capability Set: cmdFlags (2.2.7.2.9) */
334 #define SURFCMDS_SETSURFACEBITS 0x00000002
335 #define SURFCMDS_FRAMEMARKER 0x00000010
336 #define SURFCMDS_STREAMSUFRACEBITS 0x00000040
337
338 /* Bitmap Codec: codecGUID (2.2.7.2.10.1.1) */
339
340 /* CODEC_GUID_NSCODEC CA8D1BB9-000F-154F-589FAE2D1A87E2D6 */
341 #define XR_CODEC_GUID_NSCODEC \
342 "\xb9\x1b\x8d\xca\x0f\x00\x4f\x15\x58\x9f\xae\x2d\x1a\x87\xe2\xd6"
343
344 /* CODEC_GUID_REMOTEFX 76772F12-BD72-4463-AFB3B73C9C6F7886 */
345 #define XR_CODEC_GUID_REMOTEFX \
346 "\x12\x2F\x77\x76\x72\xBD\x63\x44\xAF\xB3\xB7\x3C\x9C\x6F\x78\x86"
347
348 /* CODEC_GUID_IMAGE_REMOTEFX 2744CCD4-9D8A-4E74-803C-0ECBEEA19C54 */
349 #define XR_CODEC_GUID_IMAGE_REMOTEFX \
350 "\xD4\xCC\x44\x27\x8A\x9D\x74\x4E\x80\x3C\x0E\xCB\xEE\xA1\x9C\x54"
351
352 /* MFVideoFormat_H264 0x34363248-0000-0010-800000AA00389B71 */
353 #define XR_CODEC_GUID_H264 \
354 "\x48\x32\x36\x34\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71"
355
356 /* CODEC_GUID_JPEG 1BAF4CE6-9EED-430C-869ACB8B37B66237 */
357 #define XR_CODEC_GUID_JPEG \
358 "\xE6\x4C\xAF\x1B\xED\x9E\x0C\x43\x86\x9A\xCB\x8B\x37\xB6\x62\x37"
359
360 /* CODEC_GUID_PNG 0E0C858D-28E0-45DB-ADAA0F83E57CC560 */
361 #define XR_CODEC_GUID_PNG \
362 "\x8D\x85\x0C\x0E\xE0\x28\xDB\x45\xAD\xAA\x0F\x83\xE5\x7C\xC5\x60"
363
364 /* PDU Types (2.2.8.1.1.1.1) */
365 #define PDUTYPE_DEMANDACTIVEPDU 0x1
366 #define PDUTYPE_CONFIRMACTIVEPDU 0x3
367 #define PDUTYPE_DEACTIVATEALLPDU 0x6
368 #define PDUTYPE_DATAPDU 0x7
369 #define PDUTYPE_SERVER_REDIR_PKT 0xA
370
371 /* Share Data Header: pduType2 (2.2.8.1.1.1.2) */
372 /* TODO: to be renamed */
373 #define RDP_DATA_PDU_UPDATE 2 /* PDUTYPE2_UPDATE */
374 #define RDP_DATA_PDU_CONTROL 20
375 #define RDP_DATA_PDU_POINTER 27
376 #define RDP_DATA_PDU_INPUT 28
377 #define RDP_DATA_PDU_SYNCHRONISE 31
378 #define PDUTYPE2_REFRESH_RECT 33
379 #define RDP_DATA_PDU_PLAY_SOUND 34
380 #define RDP_DATA_PDU_LOGON 38
381 #define RDP_DATA_PDU_FONT2 39
382 #define RDP_DATA_PDU_DISCONNECT 47
383
384 /* TS_SECURITY_HEADER: flags (2.2.8.1.1.2.1) */
385 /* TODO: to be renamed */
386 #define SEC_CLIENT_RANDOM 0x0001 /* SEC_EXCHANGE_PKT? */
387 #define SEC_ENCRYPT 0x0008
388 #define SEC_LOGON_INFO 0x0040 /* SEC_INFO_PKT */
389 #define SEC_LICENCE_NEG 0x0080 /* SEC_LICENSE_PKT */
390
391 #define SEC_TAG_SRV_INFO 0x0c01 /* SC_CORE */
392 #define SEC_TAG_SRV_CRYPT 0x0c02 /* SC_SECURITY */
393 #define SEC_TAG_SRV_CHANNELS 0x0c03 /* SC_NET? */
394
395 /* Slow-Path Input Event: messageType (2.2.8.1.1.3.1.1) */
396 /* TODO: to be renamed */
397 #define RDP_INPUT_SYNCHRONIZE 0
398 #define RDP_INPUT_CODEPOINT 1
399 #define RDP_INPUT_VIRTKEY 2
400 #define RDP_INPUT_SCANCODE 4
401 #define RDP_INPUT_UNICODE 5
402 #define RDP_INPUT_MOUSE 0x8001
403 #define RDP_INPUT_MOUSEX 0x8002
404
405 /* Keyboard Event: keyboardFlags (2.2.8.1.1.3.1.1.1) */
406 /* TODO: to be renamed */
407 #define KBD_FLAG_RIGHT 0x0001
408 #define KBD_FLAG_EXT 0x0100 /* KBDFLAGS_EXTENDED */
409 #define KBD_FLAG_QUIET 0x1000
410 #define KBD_FLAG_DOWN 0x4000
411 #define KBD_FLAG_UP 0x8000
412
413 /* Mouse Event: pointerFlags (2.2.8.1.1.3.1.1.3) */
414 #define PTRFLAGS_HWHEEL 0x0400
415 #define PTRFLAGS_WHEEL 0x0200
416 #define PTRFLAGS_WHEEL_NEGATIVE 0x0100
417 #define WheelRotationMask 0x01FF
418 #define PTRFLAGS_MOVE 0x0800
419 #define PTRFLAGS_DOWN 0x8000
420 #define PTRFLAGS_BUTTON1 0x1000
421 #define PTRFLAGS_BUTTON2 0x2000
422 #define PTRFLAGS_BUTTON3 0x4000
423
424 /* Extended Mouse Event: pointerFlags (2.2.8.1.1.3.1.1.4) */
425 #define PTRXFLAGS_DOWN 0x8000
426 #define PTRXFLAGS_BUTTON1 0x0001
427 #define PTRXFLAGS_BUTTON2 0x0002
428
429 /* Synchronize Event: toggleFlags (2.2.8.1.1.3.1.1.5) */
430 /* TODO: to be renamed */
431 #define KBD_FLAG_SCROLL 0x0001 /* TS_SYNC_SCROLL_LOCK */
432 #define KBD_FLAG_NUMLOCK 0x0002
433 #define KBD_FLAG_CAPITAL 0x0004
434 #define TS_SYNC_KANA_LOCK 0x0008
435
436 /* Client Fast-Path Input Event PDU 2.2.8.1.2 */
437 #define FASTPATH_INPUT_ENCRYPTED 0x2
438
439 /* Fast-Path Input Event: eventCode (2.2.8.1.2.2) */
440 #define FASTPATH_INPUT_EVENT_SCANCODE 0x0
441 #define FASTPATH_INPUT_EVENT_MOUSE 0x1
442 #define FASTPATH_INPUT_EVENT_MOUSEX 0x2
443 #define FASTPATH_INPUT_EVENT_SYNC 0x3
444 #define FASTPATH_INPUT_EVENT_UNICODE 0x4
445 #define FASTPATH_INPUT_EVENT_QOE_TIMESTAMP 0x6
446
447 /* Fast-Path Keyboard Event: eventHeader (2.2.8.1.2.2.1) */
448 #define FASTPATH_INPUT_KBDFLAGS_RELEASE 0x01
449 #define FASTPATH_INPUT_KBDFLAGS_EXTENDED 0x02
450 #define FASTPATH_INPUT_KBDFLAGS_EXTENDED1 0x04
451
452 /* Slow-Path Graphics Update: updateType (2.2.9.1.1.3.1) */
453 /* TODO: to be renamed */
454 #define RDP_UPDATE_ORDERS 0
455 #define RDP_UPDATE_BITMAP 1
456 #define RDP_UPDATE_PALETTE 2
457 #define RDP_UPDATE_SYNCHRONIZE 3
458
459 /* Server Pointer Update PDU: messageType (2.2.9.1.1.4) */
460 /* TODO: to be renamed */
461 #define RDP_POINTER_SYSTEM 1 /* TS_PTRMSGTYPE_SYSTEM */
462 #define RDP_POINTER_MOVE 3
463 #define RDP_POINTER_COLOR 6
464 #define RDP_POINTER_CACHED 7
465 #define RDP_POINTER_POINTER 8
466
467 /* System Pointer Update: systemPointerType (2.2.9.1.1.4.3) */
468 #define RDP_NULL_POINTER 0
469 #define RDP_DEFAULT_POINTER 0x7F00
470
471 /* Server Fast-Path Update PDU: action (2.2.9.1.2) */
472 #define FASTPATH_OUTPUT_ACTION_FASTPATH 0x0
473 #define FASTPATH_OUTPUT_ACTION_X224 0x3
474
475 /* Server Fast-Path Update PDU: flags (2.2.9.1.2) */
476 #define FASTPATH_OUTPUT_SECURE_CHECKSUM 0x1
477 #define FASTPATH_OUTPUT_ENCRYPTED 0x2
478
479 /* Fast-Path Update: updateCode (2.2.9.1.2.1) */
480 #define FASTPATH_UPDATETYPE_ORDERS 0x0
481 #define FASTPATH_UPDATETYPE_BITMAP 0x1
482 #define FASTPATH_UPDATETYPE_PALETTE 0x2
483 #define FASTPATH_UPDATETYPE_SYNCHRONIZE 0x3
484 #define FASTPATH_UPDATETYPE_SURFCMDS 0x4
485 #define FASTPATH_UPDATETYPE_PTR_NULL 0x5
486 #define FASTPATH_UPDATETYPE_PTR_DEFAULT 0x6
487 #define FASTPATH_UPDATETYPE_PTR_POSITION 0x8
488 #define FASTPATH_UPDATETYPE_COLOR 0x9
489 #define FASTPATH_UPDATETYPE_CACHED 0xA
490 #define FASTPATH_UPDATETYPE_POINTER 0xB
491
492 /* Fast-Path Update: fragmentation (2.2.9.1.2.1) */
493 #define FASTPATH_FRAGMENT_SINGLE 0x0
494 #define FASTPATH_FRAGMENT_LAST 0x1
495 #define FASTPATH_FRAGMENT_FIRST 0x2
496 #define FASTPATH_FRAGMENT_NEXT 0x3
497 #define FASTPATH_OUTPUT_COMPRESSION_USED 0x2
498
499 /* Surface Command Type (2.2.9.1.2.1.10.1) */
500 #define CMDTYPE_SET_SURFACE_BITS 0x0001
501 #define CMDTYPE_FRAME_MARKER 0x0004
502 #define CMDTYPE_STREAM_SURFACE_BITS 0x0006
503
504 /* Compression Flags (3.1.8.2.1) */
505 /* TODO: to be renamed, not used anywhere */
506 #define RDP_MPPC_COMPRESSED 0x20
507 #define RDP_MPPC_RESET 0x40
508 #define RDP_MPPC_FLUSH 0x80
509 #define RDP_MPPC_DICT_SIZE 8192 /* RDP 4.0 | MS-RDPBCGR 3.1.8 */
510
511 #endif /* MS_RDPBCGR_H */
0 /**
1 * xrdp: A Remote Desktop Protocol server.
2 *
3 * MS-RDPEFS : Definitions from [MS-RDPEFS]
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * References to MS-RDPEFS are currently correct for v20180912 of that
18 * document
19 */
20
21 #if !defined(MS_RDPEFS_H)
22 #define MS_RDPEFS_H
23
24 /*
25 * RDPDR_HEADER definitions (2.2.1.1)
26 */
27
28 /* device redirector core component; most of the packets in this protocol */
29 /* are sent under this component ID */
30 #define RDPDR_CTYP_CORE 0x4472
31
32 /* printing component. the packets that use this ID are typically about */
33 /* printer cache management and identifying XPS printers */
34 #define RDPDR_CTYP_PRN 0x5052
35
36 /* Server Announce Request, as specified in section 2.2.2.2 */
37 #define PAKID_CORE_SERVER_ANNOUNCE 0x496E
38
39 /* Client Announce Reply and Server Client ID Confirm, as specified in */
40 /* sections 2.2.2.3 and 2.2.2.6. */
41 #define PAKID_CORE_CLIENTID_CONFIRM 0x4343
42
43 /* Client Name Request, as specified in section 2.2.2.4 */
44 #define PAKID_CORE_CLIENT_NAME 0x434E
45
46 /* Client Device List Announce Request, as specified in section 2.2.2.9 */
47 #define PAKID_CORE_DEVICELIST_ANNOUNCE 0x4441
48
49 /* Server Device Announce Response, as specified in section 2.2.2.1 */
50 #define PAKID_CORE_DEVICE_REPLY 0x6472
51
52 /* Device I/O Request, as specified in section 2.2.1.4 */
53 #define PAKID_CORE_DEVICE_IOREQUEST 0x4952
54
55 /* Device I/O Response, as specified in section 2.2.1.5 */
56 #define PAKID_CORE_DEVICE_IOCOMPLETION 0x4943
57
58 /* Server Core Capability Request, as specified in section 2.2.2.7 */
59 #define PAKID_CORE_SERVER_CAPABILITY 0x5350
60
61 /* Client Core Capability Response, as specified in section 2.2.2.8 */
62 #define PAKID_CORE_CLIENT_CAPABILITY 0x4350
63
64 /* Client Drive Device List Remove, as specified in section 2.2.3.2 */
65 #define PAKID_CORE_DEVICELIST_REMOVE 0x444D
66
67 /* Add Printer Cachedata, as specified in [MS-RDPEPC] section 2.2.2.3 */
68 #define PAKID_PRN_CACHE_DATA 0x5043
69
70 /* Server User Logged On, as specified in section 2.2.2.5 */
71 #define PAKID_CORE_USER_LOGGEDON 0x554C
72
73 /* Server Printer Set XPS Mode, as specified in [MS-RDPEPC] section 2.2.2.2 */
74 #define PAKID_PRN_USING_XPS 0x5543
75
76 /*
77 * Capability header definitions (2.2.1.2)
78 */
79
80 #define CAP_GENERAL_TYPE 0x0001 /* General cap set - GENERAL_CAPS_SET */
81 #define CAP_PRINTER_TYPE 0x0002 /* Print cap set - PRINTER_CAPS_SET */
82 #define CAP_PORT_TYPE 0x0003 /* Port cap set - PORT_CAPS_SET */
83 #define CAP_DRIVE_TYPE 0x0004 /* Drive cap set - DRIVE_CAPS_SET */
84 #define CAP_SMARTCARD_TYPE 0x0005 /* Smart card cap set - SMARTCARD_CAPS_SET */
85
86 /*
87 * Device announce header (2.2.1.3)
88 */
89 #define RDPDR_DTYP_SERIAL 0x0001
90 #define RDPDR_DTYP_PARALLEL 0x0002
91 #define RDPDR_DTYP_PRINT 0x0004
92 #define RDPDR_DTYP_FILESYSTEM 0x0008
93 #define RDPDR_DTYP_SMARTCARD 0x0020
94
95 /* Device I/O Request definitions (2.2.1.4) */
96 /* MajorFunction */
97 enum IRP_MJ
98 {
99 IRP_MJ_CREATE = 0x00000000,
100 IRP_MJ_CLOSE = 0x00000002,
101 IRP_MJ_READ = 0x00000003,
102 IRP_MJ_WRITE = 0x00000004,
103 IRP_MJ_DEVICE_CONTROL = 0x0000000E,
104 IRP_MJ_QUERY_VOLUME_INFORMATION = 0x0000000A,
105 IRP_MJ_SET_VOLUME_INFORMATION = 0x0000000B,
106 IRP_MJ_QUERY_INFORMATION = 0x00000005,
107 IRP_MJ_SET_INFORMATION = 0x00000006,
108 IRP_MJ_DIRECTORY_CONTROL = 0x0000000C,
109 IRP_MJ_LOCK_CONTROL = 0x00000011
110 };
111
112 /* MinorFunction */
113 /* Set to zero unless MajorFunction code == IRP_MJ_DIRECTORY_CONTROL */
114 enum IRP_MN
115 {
116 IRP_MN_NONE = 0x00000000, /* Name not in MS docs */
117 IRP_MN_QUERY_DIRECTORY = 0x00000001,
118 IRP_MN_NOTIFY_CHANGE_DIRECTORY = 0x00000002
119 };
120
121
122 #endif /* MS_RDPEFS_H */
0 /**
1 * xrdp: A Remote Desktop Protocol server.
2 *
3 * MS-RDPEGDI : Definitions from [MS-RDPEGDI]
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * References to MS-RDPEGDI are currently correct for v20180912 of that
18 * document
19 */
20
21 #if !defined(MS_RDPEGDI_H)
22 #define MS_RDPEGDI_H
23
24 /* Drawing Order: controlFlags (2.2.2.2.1, 2.2.2.2.1.1.2) */
25 #define TS_STANDARD 0x01
26 #define TS_SECONDARY 0x02
27 #define TS_BOUNDS 0x04
28 #define TS_TYPE_CHANGE 0x08
29 #define TS_DELTA_COORDINATES 0x10
30 #define TS_ZERO_BOUNDS_DELTAS 0x20
31 #define TS_ZERO_FIELD_BYTE_BIT0 0x40
32 #define TS_ZERO_FIELD_BYTE_BIT1 0x80
33
34 /* Drawing Order: orderType (2.2.2.2.1.1.2) */
35 /* Should be renamed */
36 #define RDP_ORDER_DESTBLT 0 /* TS_ENC_DSTBLT_ORDER */
37 #define RDP_ORDER_PATBLT 1
38 #define RDP_ORDER_SCREENBLT 2
39 #define RDP_ORDER_LINE 9
40 #define RDP_ORDER_RECT 10
41 #define RDP_ORDER_DESKSAVE 11
42 #define RDP_ORDER_MEMBLT 13
43 #define RDP_ORDER_TRIBLT 14
44 #define RDP_ORDER_POLYLINE 22
45 #define RDP_ORDER_TEXT2 27
46 #define RDP_ORDER_COMPOSITE 37 /* 0x25 - not defined in RDPEGDI */
47
48 /* Secondary Drawing Order Header: orderType (2.2.2.2.1.2.1.1) */
49 #define TS_CACHE_BITMAP_UNCOMPRESSED 0x00
50 #define TS_CACHE_COLOR_TABLE 0x01
51 #define TS_CACHE_BITMAP_COMPRESSED 0x02
52 #define TS_CACHE_GLYPH 0x03
53 #define TS_CACHE_BITMAP_UNCOMPRESSED_REV2 0x04
54 #define TS_CACHE_BITMAP_COMPRESSED_REV2 0x05
55 #define TS_CACHE_BRUSH 0x07
56 #define TS_CACHE_BITMAP_COMPRESSED_REV3 0x08
57
58 #endif /* MS_RDPEGDI_H */
0 /**
1 * xrdp: A Remote Desktop Protocol server.
2 *
3 * MS-RDPELE : Definitions from [MS-RDPELE]
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * References to MS-RDPELE are currently correct for v20180912 of that
18 * document
19 */
20
21 #if !defined(MS_RDPELE_H)
22 #define MS_RDPELE_H
23
24 /* LicensingMessage (MS-RDPELE 2.2.2) */
25 /* TODO: to be renamed */
26 #define LICENCE_TAG_DEMAND 0x01 /* LICNSE_REQUEST */
27 #define LICENCE_TAG_AUTHREQ 0x02 /* PLATFORM_CHALLENGE */
28 #define LICENCE_TAG_ISSUE 0x03 /* NEW_LICENSE */
29 #define LICENCE_TAG_REISSUE 0x04 /* UPGRADE_LICENSE */
30 #define LICENCE_TAG_PRESENT 0x12 /* LICENSE_INFO */
31 #define LICENCE_TAG_REQUEST 0x13 /* NEW_LICENSE_REQUEST */
32 #define LICENCE_TAG_AUTHRESP 0x15 /* PLATFORM_CHALLENGE_RESPONSE */
33 #define LICENCE_TAG_RESULT 0xff
34
35 #endif /* MS_RDPELE_H */
0 /**
1 * xrdp: A Remote Desktop Protocol server.
2 *
3 * MS-RDPERP : Definitions from [MS-RDPERP]
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * References to MS-RDPERP are currently correct for v20190923 of that
18 * document
19 */
20
21 #if !defined(MS_RDPERP_H)
22 #define MS_RDPERP_H
23
24 /* Window List Capability Set: WndSupportLevel (2.2.1.1.2) */
25 #define TS_WINDOW_LEVEL_NOT_SUPPORTED 0x00000000
26 #define TS_WINDOW_LEVEL_SUPPORTED 0x00000001
27 #define TS_WINDOW_LEVEL_SUPPORTED_EX 0x00000002
28
29
30 #endif /* MS_RDPERP_H */
0 /**
1 * xrdp: A Remote Desktop Protocol server.
2 *
3 * MS-SMB2 : Definitions from [MS-SMB2]
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * References to MS-SMB2 are currently correct for v20190923 of that
18 * document
19 */
20
21 #if !defined(MS_SMB2_H)
22 #define MS_SMB2_H
23
24 /* SMB2 CREATE request values (section 2.2.13) */
25
26 /*
27 * ShareAccess Mask. Currently, this is referred
28 * to in MS-RDPEFS 2.2.1.4.1 as 'SharedAccess' rather than 'ShareAccess'.
29 */
30 #define SA_FILE_SHARE_READ 0x00000001
31 #define SA_FILE_SHARE_WRITE 0x00000002
32 #define SA_FILE_SHARE_DELETE 0x00000004
33
34 /* CreateDisposition Mask */
35 #define CD_FILE_SUPERSEDE 0x00000000
36 #define CD_FILE_OPEN 0x00000001
37 #define CD_FILE_CREATE 0x00000002
38 #define CD_FILE_OPEN_IF 0x00000003
39 #define CD_FILE_OVERWRITE 0x00000004
40 #define CD_FILE_OVERWRITE_IF 0x00000005
41
42 /* CreateOptions Mask */
43 enum CREATE_OPTIONS
44 {
45 CO_FILE_DIRECTORY_FILE = 0x00000001,
46 CO_FILE_WRITE_THROUGH = 0x00000002,
47 CO_FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020,
48 CO_FILE_DELETE_ON_CLOSE = 0x00001000
49 };
50
51 /*
52 * DesiredAccess Mask (section 2.2.13.1.1)
53 */
54
55 #define DA_FILE_READ_DATA 0x00000001
56 #define DA_FILE_WRITE_DATA 0x00000002
57 #define DA_FILE_APPEND_DATA 0x00000004
58 #define DA_FILE_READ_EA 0x00000008 /* rd extended attributes */
59 #define DA_FILE_WRITE_EA 0x00000010 /* wr extended attributes */
60 #define DA_FILE_EXECUTE 0x00000020
61 #define DA_FILE_READ_ATTRIBUTES 0x00000080
62 #define DA_FILE_WRITE_ATTRIBUTES 0x00000100
63 #define DA_DELETE 0x00010000
64 #define DA_READ_CONTROL 0x00020000 /* rd security descriptor */
65 #define DA_WRITE_DAC 0x00040000
66 #define DA_WRITE_OWNER 0x00080000
67 #define DA_SYNCHRONIZE 0x00100000
68 #define DA_ACCESS_SYSTEM_SECURITY 0x01000000
69 #define DA_MAXIMUM_ALLOWED 0x02000000
70 #define DA_GENERIC_ALL 0x10000000
71 #define DA_GENERIC_EXECUTE 0x20000000
72 #define DA_GENERIC_WRITE 0x40000000
73 #define DA_GENERIC_READ 0x80000000
74
75 #endif /* MS_SMB2_H */
76
77
78
7575 #endif
7676
7777 #include "os_calls.h"
78 #include "arch.h"
78 #include "string_calls.h"
7979 #include "log.h"
8080
8181 /* for clearenv() */
165165 #if defined(_WIN32)
166166 WSACleanup();
167167 #endif
168 fflush(stdout);
169 fflush(stderr);
168170 g_rm_temp_dir();
169171 }
170172
25072509 }
25082510
25092511 /*****************************************************************************/
2510 /* returns length of text */
2511 int
2512 g_strlen(const char *text)
2513 {
2514 if (text == NULL)
2515 {
2516 return 0;
2517 }
2518
2519 return strlen(text);
2520 }
2521
2522 /*****************************************************************************/
2523 /* locates char in text */
2524 const char *
2525 g_strchr(const char* text, int c)
2526 {
2527 if (text == NULL)
2528 {
2529 return 0;
2530 }
2531
2532 return strchr(text,c);
2533 }
2534
2535 /*****************************************************************************/
2536 /* returns dest */
2537 char *
2538 g_strcpy(char *dest, const char *src)
2539 {
2540 if (src == 0 && dest != 0)
2541 {
2542 dest[0] = 0;
2543 return dest;
2544 }
2545
2546 if (dest == 0 || src == 0)
2547 {
2548 return 0;
2549 }
2550
2551 return strcpy(dest, src);
2552 }
2553
2554 /*****************************************************************************/
2555 /* returns dest */
2556 char *
2557 g_strncpy(char *dest, const char *src, int len)
2558 {
2559 char *rv;
2560
2561 if (src == 0 && dest != 0)
2562 {
2563 dest[0] = 0;
2564 return dest;
2565 }
2566
2567 if (dest == 0 || src == 0)
2568 {
2569 return 0;
2570 }
2571
2572 rv = strncpy(dest, src, len);
2573 dest[len] = 0;
2574 return rv;
2575 }
2576
2577 /*****************************************************************************/
2578 /* returns dest */
2579 char *
2580 g_strcat(char *dest, const char *src)
2581 {
2582 if (dest == 0 || src == 0)
2583 {
2584 return dest;
2585 }
2586
2587 return strcat(dest, src);
2588 }
2589
2590 /*****************************************************************************/
2591 /* if in = 0, return 0 else return newly alloced copy of in */
2592 char *
2593 g_strdup(const char *in)
2594 {
2595 int len;
2596 char *p;
2597
2598 if (in == 0)
2599 {
2600 return 0;
2601 }
2602
2603 len = g_strlen(in);
2604 p = (char *)g_malloc(len + 1, 0);
2605
2606 if (p != NULL)
2607 {
2608 g_strcpy(p, in);
2609 }
2610
2611 return p;
2612 }
2613
2614 /*****************************************************************************/
2615 /* if in = 0, return 0 else return newly alloced copy of input string
2616 * if the input string is larger than maxlen the returned string will be
2617 * truncated. All strings returned will include null termination*/
2618 char *
2619 g_strndup(const char *in, const unsigned int maxlen)
2620 {
2621 unsigned int len;
2622 char *p;
2623
2624 if (in == 0)
2625 {
2626 return 0;
2627 }
2628
2629 len = g_strlen(in);
2630
2631 if (len > maxlen)
2632 {
2633 len = maxlen - 1;
2634 }
2635
2636 p = (char *)g_malloc(len + 2, 0);
2637
2638 if (p != NULL)
2639 {
2640 g_strncpy(p, in, len + 1);
2641 }
2642
2643 return p;
2644 }
2645
2646 /*****************************************************************************/
2647 int
2648 g_strcmp(const char *c1, const char *c2)
2649 {
2650 return strcmp(c1, c2);
2651 }
2652
2653 /*****************************************************************************/
2654 int
2655 g_strncmp(const char *c1, const char *c2, int len)
2656 {
2657 return strncmp(c1, c2, len);
2658 }
2659
2660 /*****************************************************************************/
2661 /* compare up to delim */
2662 int
2663 g_strncmp_d(const char *s1, const char *s2, const char delim, int n)
2664 {
2665 char c1;
2666 char c2;
2667
2668 c1 = 0;
2669 c2 = 0;
2670 while (n > 0)
2671 {
2672 c1 = *(s1++);
2673 c2 = *(s2++);
2674 if ((c1 == 0) || (c1 != c2) || (c1 == delim) || (c2 == delim))
2675 {
2676 return c1 - c2;
2677 }
2678 n--;
2679 }
2680 return c1 - c2;
2681 }
2682
2683 /*****************************************************************************/
2684 int
2685 g_strcasecmp(const char *c1, const char *c2)
2686 {
2687 #if defined(_WIN32)
2688 return stricmp(c1, c2);
2689 #else
2690 return strcasecmp(c1, c2);
2691 #endif
2692 }
2693
2694 /*****************************************************************************/
2695 int
2696 g_strncasecmp(const char *c1, const char *c2, int len)
2697 {
2698 #if defined(_WIN32)
2699 return strnicmp(c1, c2, len);
2700 #else
2701 return strncasecmp(c1, c2, len);
2702 #endif
2703 }
2704
2705 /*****************************************************************************/
2706 int
2707 g_atoi(const char *str)
2708 {
2709 if (str == 0)
2710 {
2711 return 0;
2712 }
2713
2714 return atoi(str);
2715 }
2716
2717 /*****************************************************************************/
2718 int
2719 g_htoi(char *str)
2720 {
2721 int len;
2722 int index;
2723 int rv;
2724 int val;
2725 int shift;
2726
2727 rv = 0;
2728 len = strlen(str);
2729 index = len - 1;
2730 shift = 0;
2731
2732 while (index >= 0)
2733 {
2734 val = 0;
2735
2736 switch (str[index])
2737 {
2738 case '1':
2739 val = 1;
2740 break;
2741 case '2':
2742 val = 2;
2743 break;
2744 case '3':
2745 val = 3;
2746 break;
2747 case '4':
2748 val = 4;
2749 break;
2750 case '5':
2751 val = 5;
2752 break;
2753 case '6':
2754 val = 6;
2755 break;
2756 case '7':
2757 val = 7;
2758 break;
2759 case '8':
2760 val = 8;
2761 break;
2762 case '9':
2763 val = 9;
2764 break;
2765 case 'a':
2766 case 'A':
2767 val = 10;
2768 break;
2769 case 'b':
2770 case 'B':
2771 val = 11;
2772 break;
2773 case 'c':
2774 case 'C':
2775 val = 12;
2776 break;
2777 case 'd':
2778 case 'D':
2779 val = 13;
2780 break;
2781 case 'e':
2782 case 'E':
2783 val = 14;
2784 break;
2785 case 'f':
2786 case 'F':
2787 val = 15;
2788 break;
2789 }
2790
2791 rv = rv | (val << shift);
2792 index--;
2793 shift += 4;
2794 }
2795
2796 return rv;
2797 }
2798
2799 /*****************************************************************************/
2800 /* returns number of bytes copied into out_str */
2801 int
2802 g_bytes_to_hexstr(const void *bytes, int num_bytes, char *out_str,
2803 int bytes_out_str)
2804 {
2805 int rv;
2806 int index;
2807 char *lout_str;
2808 const tui8 *lbytes;
2809
2810 rv = 0;
2811 lbytes = (const tui8 *) bytes;
2812 lout_str = out_str;
2813 for (index = 0; index < num_bytes; index++)
2814 {
2815 if (bytes_out_str < 3)
2816 {
2817 break;
2818 }
2819 g_snprintf(lout_str, bytes_out_str, "%2.2x", lbytes[index]);
2820 lout_str += 2;
2821 bytes_out_str -= 2;
2822 rv += 2;
2823 }
2824 return rv;
2825 }
2826
2827 /*****************************************************************************/
2828 int
2829 g_pos(const char *str, const char *to_find)
2830 {
2831 const char *pp;
2832
2833 pp = strstr(str, to_find);
2834
2835 if (pp == 0)
2836 {
2837 return -1;
2838 }
2839
2840 return (pp - str);
2841 }
2842
2843 /*****************************************************************************/
2844 int
2845 g_mbstowcs(twchar *dest, const char *src, int n)
2846 {
2847 wchar_t *ldest;
2848 int rv;
2849
2850 ldest = (wchar_t *)dest;
2851 rv = mbstowcs(ldest, src, n);
2852 return rv;
2853 }
2854
2855 /*****************************************************************************/
2856 int
2857 g_wcstombs(char *dest, const twchar *src, int n)
2858 {
2859 const wchar_t *lsrc;
2860 int rv;
2861
2862 lsrc = (const wchar_t *)src;
2863 rv = wcstombs(dest, lsrc, n);
2864 return rv;
2865 }
2866
2867 /*****************************************************************************/
2868 /* returns error */
2869 /* trim spaces and tabs, anything <= space */
2870 /* trim_flags 1 trim left, 2 trim right, 3 trim both, 4 trim through */
2871 /* this will always shorten the string or not change it */
2872 int
2873 g_strtrim(char *str, int trim_flags)
2874 {
2875 int index;
2876 int len;
2877 int text1_index;
2878 int got_char;
2879 wchar_t *text;
2880 wchar_t *text1;
2881
2882 len = mbstowcs(0, str, 0);
2883
2884 if (len < 1)
2885 {
2886 return 0;
2887 }
2888
2889 if ((trim_flags < 1) || (trim_flags > 4))
2890 {
2891 return 1;
2892 }
2893
2894 text = (wchar_t *)malloc(len * sizeof(wchar_t) + 8);
2895 text1 = (wchar_t *)malloc(len * sizeof(wchar_t) + 8);
2896 text1_index = 0;
2897 mbstowcs(text, str, len + 1);
2898
2899 switch (trim_flags)
2900 {
2901 case 4: /* trim through */
2902
2903 for (index = 0; index < len; index++)
2904 {
2905 if (text[index] > 32)
2906 {
2907 text1[text1_index] = text[index];
2908 text1_index++;
2909 }
2910 }
2911
2912 text1[text1_index] = 0;
2913 break;
2914 case 3: /* trim both */
2915 got_char = 0;
2916
2917 for (index = 0; index < len; index++)
2918 {
2919 if (got_char)
2920 {
2921 text1[text1_index] = text[index];
2922 text1_index++;
2923 }
2924 else
2925 {
2926 if (text[index] > 32)
2927 {
2928 text1[text1_index] = text[index];
2929 text1_index++;
2930 got_char = 1;
2931 }
2932 }
2933 }
2934
2935 text1[text1_index] = 0;
2936 len = text1_index;
2937
2938 /* trim right */
2939 for (index = len - 1; index >= 0; index--)
2940 {
2941 if (text1[index] > 32)
2942 {
2943 break;
2944 }
2945 }
2946
2947 text1_index = index + 1;
2948 text1[text1_index] = 0;
2949 break;
2950 case 2: /* trim right */
2951
2952 /* copy it */
2953 for (index = 0; index < len; index++)
2954 {
2955 text1[text1_index] = text[index];
2956 text1_index++;
2957 }
2958
2959 /* trim right */
2960 for (index = len - 1; index >= 0; index--)
2961 {
2962 if (text1[index] > 32)
2963 {
2964 break;
2965 }
2966 }
2967
2968 text1_index = index + 1;
2969 text1[text1_index] = 0;
2970 break;
2971 case 1: /* trim left */
2972 got_char = 0;
2973
2974 for (index = 0; index < len; index++)
2975 {
2976 if (got_char)
2977 {
2978 text1[text1_index] = text[index];
2979 text1_index++;
2980 }
2981 else
2982 {
2983 if (text[index] > 32)
2984 {
2985 text1[text1_index] = text[index];
2986 text1_index++;
2987 got_char = 1;
2988 }
2989 }
2990 }
2991
2992 text1[text1_index] = 0;
2993 break;
2994 }
2995
2996 wcstombs(str, text1, text1_index + 1);
2997 free(text);
2998 free(text1);
2999 return 0;
3000 }
3001
3002 /*****************************************************************************/
30032512 long
30042513 g_load_library(char *in)
30052514 {
32872796
32882797 /*****************************************************************************/
32892798 int
2799 g_getlogin(char *name, unsigned int len)
2800 {
2801 #if defined(_WIN32)
2802 return -1;
2803 #else
2804 return getlogin_r(name, len);
2805 #endif
2806 }
2807
2808 /*****************************************************************************/
2809 int
32902810 g_setlogin(const char *name)
32912811 {
32922812 #ifdef BSD
33972917 int
33982918 g_exit(int exit_code)
33992919 {
3400 _exit(exit_code);
2920 exit(exit_code);
34012921 return 0;
34022922 }
34032923
37353255 g_writeln("g_save_to_bpp: unimp");
37363256 }
37373257 close(fd);
3738 return 0;
3739 }
3740
3741 /*****************************************************************************/
3742 /* returns boolean */
3743 int
3744 g_text2bool(const char *s)
3745 {
3746 if ( (g_atoi(s) != 0) ||
3747 (0 == g_strcasecmp(s, "true")) ||
3748 (0 == g_strcasecmp(s, "on")) ||
3749 (0 == g_strcasecmp(s, "yes")))
3750 {
3751 return 1;
3752 }
37533258 return 0;
37543259 }
37553260
118118 int g_remove_dir(const char* dirname);
119119 int g_file_delete(const char* filename);
120120 int g_file_get_size(const char* filename);
121 int g_strlen(const char* text);
122 const char *g_strchr(const char *text, int c);
123 char* g_strcpy(char* dest, const char* src);
124 char* g_strncpy(char* dest, const char* src, int len);
125 char* g_strcat(char* dest, const char* src);
126 char* g_strdup(const char* in);
127 char* g_strndup(const char* in, const unsigned int maxlen);
128 int g_strcmp(const char* c1, const char* c2);
129 int g_strncmp(const char* c1, const char* c2, int len);
130 int g_strncmp_d(const char* c1, const char* c2, const char delim, int len);
131 int g_strcasecmp(const char* c1, const char* c2);
132 int g_strncasecmp(const char* c1, const char* c2, int len);
133 int g_atoi(const char* str);
134 int g_htoi(char* str);
135 int g_bytes_to_hexstr(const void *bytes, int num_bytes, char *out_str,
136 int bytes_out_str);
137 int g_pos(const char* str, const char* to_find);
138 int g_mbstowcs(twchar* dest, const char* src, int n);
139 int g_wcstombs(char* dest, const twchar* src, int n);
140 int g_strtrim(char* str, int trim_flags);
141121 long g_load_library(char* in);
142122 int g_free_library(long lib);
143123 void* g_get_proc_address(long lib, const char* name);
160140 int g_getgid(void);
161141 int g_setuid(int pid);
162142 int g_setsid(void);
143 int g_getlogin(char *name, unsigned int len);
163144 int g_setlogin(const char *name);
164145 int g_waitchild(void);
165146 int g_waitpid(int pid);
178159 int g_time3(void);
179160 int g_save_to_bmp(const char* filename, char* data, int stride_bytes,
180161 int width, int height, int depth, int bits_per_pixel);
181 int g_text2bool(const char *s);
182162 void * g_shmat(int shmid);
183163 int g_shmdt(const void *shmaddr);
184164 int g_gethostname(char *name, int len);
8282 #define GOOD_RECT(rect) ((rect)->x1 < (rect)->x2 && (rect)->y1 < (rect)->y2)
8383 #define BAD_RECT(rect) ((rect)->x1 > (rect)->x2 || (rect)->y1 > (rect)->y2)
8484
85 /* This file is included by pixman-region16.c which defines PREFIX(x).
86 * This check allows cppcheck 2.x to scan this file separately */
87 #ifndef PREFIX
88 #define PREFIX(x) pixman_region##x
89 #endif
90
8591 #ifdef XRDP_DEBUG
92
93 pixman_bool_t PREFIX(_selfcheck) (region_type_t *reg);
8694
8795 #define GOOD(reg) \
8896 do \
3535 #include <openssl/crypto.h>
3636
3737 #include "os_calls.h"
38 #include "string_calls.h"
3839 #include "arch.h"
3940 #include "ssl_calls.h"
4041 #include "trans.h"
719720 DH_free(dh); // ok to free, copied into ctx by SSL_CTX_set_tmp_dh()
720721
721722 #if defined(SSL_CTX_set_ecdh_auto)
722 SSL_CTX_set_ecdh_auto(self->ctx, 1);
723 if(!SSL_CTX_set_ecdh_auto(self->ctx, 1))
724 {
725 LOG(LOG_LEVEL_WARNING, "TLS ecdh auto failed to be enabled");
726 }
723727 #endif
724728
725729 if (g_strlen(tls_ciphers) > 1)
0 /**
1 * xrdp: A Remote Desktop Protocol server.
2 *
3 * Copyright (C) Jay Sorg 2004-2020
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * generic string handling calls
18 */
19
20 #if defined(HAVE_CONFIG_H)
21 #include "config_ac.h"
22 #endif
23 #include <string.h>
24 #include <strings.h>
25 #include <stdlib.h>
26
27 #include "string_calls.h"
28 #include "os_calls.h"
29
30 unsigned int
31 g_format_info_string(char *dest, unsigned int len,
32 const char *format,
33 const struct info_string_tag map[])
34 {
35 unsigned int result = 0;
36 const char *copy_from; /* Data to add to output */
37 unsigned int copy_len; /* Length of above */
38 unsigned int skip; /* Date to skip over in format string */
39 const char *p;
40 const struct info_string_tag *m;
41
42 for ( ; *format != '\0'; format += skip)
43 {
44 if (*format == '%')
45 {
46 char ch = *(format + 1);
47 if (ch == '%')
48 {
49 /* '%%' in format - replace with single '%' */
50 copy_from = format;
51 copy_len = 1;
52 skip = 2;
53 }
54 else if (ch == '\0')
55 {
56 /* Percent at end of string - ignore */
57 copy_from = NULL;
58 copy_len = 0;
59 skip = 1;
60 }
61 else
62 {
63 /* Look up the character in the map, assuming failure */
64 copy_from = NULL;
65 copy_len = 0;
66 skip = 2;
67
68 for (m = map ; m->ch != '\0' ; ++m)
69 {
70 if (ch == m->ch)
71 {
72 copy_from = m->val;
73 copy_len = strlen(copy_from);
74 break;
75 }
76 }
77 }
78 }
79 else if ((p = strchr(format, '%')) != NULL)
80 {
81 /* Copy up to the next '%' */
82 copy_from = format;
83 copy_len = p - format;
84 skip = copy_len;
85 }
86 else
87 {
88 /* Copy the rest of the format string */
89 copy_from = format;
90 copy_len = strlen(format);
91 skip = copy_len;
92 }
93
94 /* Update the result before any truncation */
95 result += copy_len;
96
97 /* Do we have room in the output buffer for any more data? We
98 * must always write a terminator if possible */
99 if (len > 1)
100 {
101 if (copy_len > (len - 1))
102 {
103 copy_len = len - 1;
104 }
105 memcpy(dest, copy_from, copy_len);
106 dest += copy_len;
107 len -= copy_len;
108 }
109 }
110
111 /* Room for a terminator? */
112 if (len > 0)
113 {
114 *dest = '\0';
115 }
116
117 return result;
118 }
119
120 /******************************************************************************/
121 const char *
122 g_bool2text(int value)
123 {
124 return value ? "true" : "false";
125 }
126
127 /*****************************************************************************/
128 int
129 g_text2bool(const char *s)
130 {
131 if ( (g_atoi(s) != 0) ||
132 (0 == g_strcasecmp(s, "true")) ||
133 (0 == g_strcasecmp(s, "on")) ||
134 (0 == g_strcasecmp(s, "yes")))
135 {
136 return 1;
137 }
138 return 0;
139 }
140
141 /*****************************************************************************/
142 /* returns length of text */
143 int
144 g_strlen(const char *text)
145 {
146 if (text == NULL)
147 {
148 return 0;
149 }
150
151 return strlen(text);
152 }
153
154 /*****************************************************************************/
155 /* locates char in text */
156 const char *
157 g_strchr(const char *text, int c)
158 {
159 if (text == NULL)
160 {
161 return 0;
162 }
163
164 return strchr(text, c);
165 }
166
167 /*****************************************************************************/
168 /* returns dest */
169 char *
170 g_strcpy(char *dest, const char *src)
171 {
172 if (src == 0 && dest != 0)
173 {
174 dest[0] = 0;
175 return dest;
176 }
177
178 if (dest == 0 || src == 0)
179 {
180 return 0;
181 }
182
183 return strcpy(dest, src);
184 }
185
186 /*****************************************************************************/
187 /* returns dest */
188 char *
189 g_strncpy(char *dest, const char *src, int len)
190 {
191 char *rv;
192
193 if (src == 0 && dest != 0)
194 {
195 dest[0] = 0;
196 return dest;
197 }
198
199 if (dest == 0 || src == 0)
200 {
201 return 0;
202 }
203
204 rv = strncpy(dest, src, len);
205 dest[len] = 0;
206 return rv;
207 }
208
209 /*****************************************************************************/
210 /* returns dest */
211 char *
212 g_strcat(char *dest, const char *src)
213 {
214 if (dest == 0 || src == 0)
215 {
216 return dest;
217 }
218
219 return strcat(dest, src);
220 }
221
222 /*****************************************************************************/
223 /* returns dest */
224 char *
225 g_strncat(char *dest, const char *src, int len)
226 {
227 if (dest == 0 || src == 0)
228 {
229 return dest;
230 }
231
232 return strncat(dest, src, len);
233 }
234
235 /*****************************************************************************/
236 /* if in = 0, return 0 else return newly alloced copy of in */
237 char *
238 g_strdup(const char *in)
239 {
240 int len;
241 char *p;
242
243 if (in == 0)
244 {
245 return 0;
246 }
247
248 len = g_strlen(in);
249 p = (char *)g_malloc(len + 1, 0);
250
251 if (p != NULL)
252 {
253 g_strcpy(p, in);
254 }
255
256 return p;
257 }
258
259 /*****************************************************************************/
260 /* if in = 0, return 0 else return newly alloced copy of input string
261 * if the input string is larger than maxlen the returned string will be
262 * truncated. All strings returned will include null termination*/
263 char *
264 g_strndup(const char *in, const unsigned int maxlen)
265 {
266 unsigned int len;
267 char *p;
268
269 if (in == 0)
270 {
271 return 0;
272 }
273
274 len = g_strlen(in);
275
276 if (len > maxlen)
277 {
278 len = maxlen - 1;
279 }
280
281 p = (char *)g_malloc(len + 2, 0);
282
283 if (p != NULL)
284 {
285 g_strncpy(p, in, len + 1);
286 }
287
288 return p;
289 }
290
291 /*****************************************************************************/
292 int
293 g_strcmp(const char *c1, const char *c2)
294 {
295 return strcmp(c1, c2);
296 }
297
298 /*****************************************************************************/
299 int
300 g_strncmp(const char *c1, const char *c2, int len)
301 {
302 return strncmp(c1, c2, len);
303 }
304
305 /*****************************************************************************/
306 /* compare up to delim */
307 int
308 g_strncmp_d(const char *s1, const char *s2, const char delim, int n)
309 {
310 char c1;
311 char c2;
312
313 c1 = 0;
314 c2 = 0;
315 while (n > 0)
316 {
317 c1 = *(s1++);
318 c2 = *(s2++);
319 if ((c1 == 0) || (c1 != c2) || (c1 == delim) || (c2 == delim))
320 {
321 return c1 - c2;
322 }
323 n--;
324 }
325 return c1 - c2;
326 }
327
328 /*****************************************************************************/
329 int
330 g_strcasecmp(const char *c1, const char *c2)
331 {
332 #if defined(_WIN32)
333 return stricmp(c1, c2);
334 #else
335 return strcasecmp(c1, c2);
336 #endif
337 }
338
339 /*****************************************************************************/
340 int
341 g_strncasecmp(const char *c1, const char *c2, int len)
342 {
343 #if defined(_WIN32)
344 return strnicmp(c1, c2, len);
345 #else
346 return strncasecmp(c1, c2, len);
347 #endif
348 }
349
350 /*****************************************************************************/
351 int
352 g_atoi(const char *str)
353 {
354 if (str == 0)
355 {
356 return 0;
357 }
358
359 return atoi(str);
360 }
361
362 /*****************************************************************************/
363 int
364 g_htoi(char *str)
365 {
366 int len;
367 int index;
368 int rv;
369 int val;
370 int shift;
371
372 rv = 0;
373 len = strlen(str);
374 index = len - 1;
375 shift = 0;
376
377 while (index >= 0)
378 {
379 val = 0;
380
381 switch (str[index])
382 {
383 case '1':
384 val = 1;
385 break;
386 case '2':
387 val = 2;
388 break;
389 case '3':
390 val = 3;
391 break;
392 case '4':
393 val = 4;
394 break;
395 case '5':
396 val = 5;
397 break;
398 case '6':
399 val = 6;
400 break;
401 case '7':
402 val = 7;
403 break;
404 case '8':
405 val = 8;
406 break;
407 case '9':
408 val = 9;
409 break;
410 case 'a':
411 case 'A':
412 val = 10;
413 break;
414 case 'b':
415 case 'B':
416 val = 11;
417 break;
418 case 'c':
419 case 'C':
420 val = 12;
421 break;
422 case 'd':
423 case 'D':
424 val = 13;
425 break;
426 case 'e':
427 case 'E':
428 val = 14;
429 break;
430 case 'f':
431 case 'F':
432 val = 15;
433 break;
434 }
435
436 rv = rv | (val << shift);
437 index--;
438 shift += 4;
439 }
440
441 return rv;
442 }
443
444 /*****************************************************************************/
445 /* returns number of bytes copied into out_str */
446 int
447 g_bytes_to_hexstr(const void *bytes, int num_bytes, char *out_str,
448 int bytes_out_str)
449 {
450 int rv;
451 int index;
452 char *lout_str;
453 const tui8 *lbytes;
454
455 rv = 0;
456 lbytes = (const tui8 *) bytes;
457 lout_str = out_str;
458 for (index = 0; index < num_bytes; index++)
459 {
460 if (bytes_out_str < 3)
461 {
462 break;
463 }
464 g_snprintf(lout_str, bytes_out_str, "%2.2x", lbytes[index]);
465 lout_str += 2;
466 bytes_out_str -= 2;
467 rv += 2;
468 }
469 return rv;
470 }
471
472 /*****************************************************************************/
473 int
474 g_pos(const char *str, const char *to_find)
475 {
476 const char *pp;
477
478 pp = strstr(str, to_find);
479
480 if (pp == 0)
481 {
482 return -1;
483 }
484
485 return (pp - str);
486 }
487
488 /*****************************************************************************/
489 int
490 g_mbstowcs(twchar *dest, const char *src, int n)
491 {
492 wchar_t *ldest;
493 int rv;
494
495 ldest = (wchar_t *)dest;
496 rv = mbstowcs(ldest, src, n);
497 return rv;
498 }
499
500 /*****************************************************************************/
501 int
502 g_wcstombs(char *dest, const twchar *src, int n)
503 {
504 const wchar_t *lsrc;
505 int rv;
506
507 lsrc = (const wchar_t *)src;
508 rv = wcstombs(dest, lsrc, n);
509 return rv;
510 }
511
512 /*****************************************************************************/
513 /* returns error */
514 /* trim spaces and tabs, anything <= space */
515 /* trim_flags 1 trim left, 2 trim right, 3 trim both, 4 trim through */
516 /* this will always shorten the string or not change it */
517 int
518 g_strtrim(char *str, int trim_flags)
519 {
520 int index;
521 int len;
522 int text1_index;
523 int got_char;
524 wchar_t *text;
525 wchar_t *text1;
526
527 len = mbstowcs(0, str, 0);
528
529 if (len < 1)
530 {
531 return 0;
532 }
533
534 if ((trim_flags < 1) || (trim_flags > 4))
535 {
536 return 1;
537 }
538
539 text = (wchar_t *)malloc(len * sizeof(wchar_t) + 8);
540 text1 = (wchar_t *)malloc(len * sizeof(wchar_t) + 8);
541 if (text == NULL || text1 == NULL)
542 {
543 free(text);
544 free(text1);
545 return 1;
546 }
547 text1_index = 0;
548 mbstowcs(text, str, len + 1);
549
550 switch (trim_flags)
551 {
552 case 4: /* trim through */
553
554 for (index = 0; index < len; index++)
555 {
556 if (text[index] > 32)
557 {
558 text1[text1_index] = text[index];
559 text1_index++;
560 }
561 }
562
563 text1[text1_index] = 0;
564 break;
565 case 3: /* trim both */
566 got_char = 0;
567
568 for (index = 0; index < len; index++)
569 {
570 if (got_char)
571 {
572 text1[text1_index] = text[index];
573 text1_index++;
574 }
575 else
576 {
577 if (text[index] > 32)
578 {
579 text1[text1_index] = text[index];
580 text1_index++;
581 got_char = 1;
582 }
583 }
584 }
585
586 text1[text1_index] = 0;
587 len = text1_index;
588
589 /* trim right */
590 for (index = len - 1; index >= 0; index--)
591 {
592 if (text1[index] > 32)
593 {
594 break;
595 }
596 }
597
598 text1_index = index + 1;
599 text1[text1_index] = 0;
600 break;
601 case 2: /* trim right */
602
603 /* copy it */
604 for (index = 0; index < len; index++)
605 {
606 text1[text1_index] = text[index];
607 text1_index++;
608 }
609
610 /* trim right */
611 for (index = len - 1; index >= 0; index--)
612 {
613 if (text1[index] > 32)
614 {
615 break;
616 }
617 }
618
619 text1_index = index + 1;
620 text1[text1_index] = 0;
621 break;
622 case 1: /* trim left */
623 got_char = 0;
624
625 for (index = 0; index < len; index++)
626 {
627 if (got_char)
628 {
629 text1[text1_index] = text[index];
630 text1_index++;
631 }
632 else
633 {
634 if (text[index] > 32)
635 {
636 text1[text1_index] = text[index];
637 text1_index++;
638 got_char = 1;
639 }
640 }
641 }
642
643 text1[text1_index] = 0;
644 break;
645 }
646
647 wcstombs(str, text1, text1_index + 1);
648 free(text);
649 free(text1);
650 return 0;
651 }
652
0 /**
1 * xrdp: A Remote Desktop Protocol server.
2 *
3 * Copyright (C) Jay Sorg 2004-2020
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * generic string handling calls
18 */
19
20 #if !defined(STRING_CALLS_H)
21 #define STRING_CALLS_H
22
23 #include "arch.h"
24
25 /**
26 * Map a character to a string value
27 *
28 * This structure is used by g_format_info_string() to specify the
29 * string which chould be output for %'ch', where ch is a character
30 */
31 struct info_string_tag
32 {
33 char ch;
34 const char *val;
35 };
36
37 #define INFO_STRING_END_OF_LIST { '\0', NULL }
38
39 /**
40 * Processes a format string for general info
41 *
42 * @param[out] dest Destination buffer
43 * @param[in] len Length of buffer, including space for a terminator
44 * @param[in] format Format string to process
45 * @param[in] map Array of struct info_string_tag.
46 *
47 * Where a '%<ch>' is encountered in the format string, the map is scanned
48 * and the corresponding string is copied instead of '%<ch>'.
49 *
50 * '%%' is always replaced with a single '%' in the output. %<ch> strings
51 * not present in the map are ignored.
52 *
53 * The map is terminated with INFO_STRING_END_OF_LIST
54 *
55 * Caller can check for buffer truncation by comparing the result with
56 * the buffer length (as in snprintf())
57 */
58 unsigned int
59 g_format_info_string(char *dest, unsigned int len,
60 const char *format,
61 const struct info_string_tag map[]);
62
63
64 /**
65 * Converts a boolean to a string for output
66 *
67 * @param[in] value Value to convert
68 * @return String representation
69 */
70 const char *
71 g_bool2text(int value);
72
73 /**
74 * Converts a string to a boolean value
75 *
76 * @param[in] s String to convert
77 * @return machine representation
78 */
79 int
80 g_text2bool(const char *s);
81
82 int g_strlen(const char *text);
83 const char *g_strchr(const char *text, int c);
84 char *g_strcpy(char *dest, const char *src);
85 char *g_strncpy(char *dest, const char *src, int len);
86 char *g_strcat(char *dest, const char *src);
87 char *g_strncat(char *dest, const char *src, int len);
88 char *g_strdup(const char *in);
89 char *g_strndup(const char *in, const unsigned int maxlen);
90 int g_strcmp(const char *c1, const char *c2);
91 int g_strncmp(const char *c1, const char *c2, int len);
92 int g_strncmp_d(const char *c1, const char *c2, const char delim, int len);
93 int g_strcasecmp(const char *c1, const char *c2);
94 int g_strncasecmp(const char *c1, const char *c2, int len);
95 int g_atoi(const char *str);
96 int g_htoi(char *str);
97 int g_bytes_to_hexstr(const void *bytes, int num_bytes, char *out_str,
98 int bytes_out_str);
99 int g_pos(const char *str, const char *to_find);
100 int g_mbstowcs(twchar *dest, const char *src, int n);
101 int g_wcstombs(char *dest, const twchar *src, int n);
102 int g_strtrim(char *str, int trim_flags);
103 #endif
2222 #endif
2323
2424 #include "os_calls.h"
25 #include "string_calls.h"
2526 #include "trans.h"
2627 #include "arch.h"
2728 #include "parse.h"
301302 int to_read = 0;
302303 int read_so_far = 0;
303304 int rv = 0;
304 int cur_source;
305 enum xrdp_source cur_source;
305306
306307 if (self == 0)
307308 {
370371 }
371372 else if (self->trans_can_recv(self, self->sck, 0))
372373 {
373 cur_source = 0;
374 cur_source = XRDP_SOURCE_NONE;
374375 if (self->si != 0)
375376 {
376377 cur_source = self->si->cur_source;
451452 {
452453 int rcvd;
453454
454 if (self->status != TRANS_STATUS_UP)
455 {
456 return 1;
457 }
455 if (self->status != TRANS_STATUS_UP ||
456 size < 0 || !s_check_rem_out(in_s, size))
457 {
458 return 1;
459 }
460
458461 while (size > 0)
459462 {
460 /* make sure stream has room */
461 if ((in_s->end + size) > (in_s->data + in_s->size))
462 {
463 return 1;
464 }
465463 rcvd = self->trans_recv(self, in_s->end, size);
466464 if (rcvd == -1)
467465 {
635633 init_stream(wait_s, size);
636634 if (self->si != 0)
637635 {
638 if ((self->si->cur_source != 0) &&
636 if ((self->si->cur_source != XRDP_SOURCE_NONE) &&
639637 (self->si->cur_source != self->my_source))
640638 {
641639 self->si->source[self->si->cur_source] += size;
4949
5050 /* optional source info */
5151
52 #define XRDP_SOURCE_NONE 0
53 #define XRDP_SOURCE_CLIENT 1
54 #define XRDP_SOURCE_SESMAN 2
55 #define XRDP_SOURCE_CHANSRV 3
56 #define XRDP_SOURCE_MOD 4
52 enum xrdp_source
53 {
54 XRDP_SOURCE_NONE = 0,
55 XRDP_SOURCE_CLIENT,
56 XRDP_SOURCE_SESMAN,
57 XRDP_SOURCE_CHANSRV,
58 XRDP_SOURCE_MOD,
5759
60 XRDP_SOURCE_MAX_COUNT
61 };
62
63 /*
64 * @brief Provide flow control mechanism for (primarily) xrdp
65 *
66 * There is one of these data structures per-program.
67 *
68 * While input is being read from a 'struct trans' and processed, the
69 * cur_source member is set to the my_source member from the transport.
70 * During this processing, trans_write_copy() may be called to send output
71 * on another struct trans. If this happens, and the ouput needs to be
72 * buffered, trans_write_copy() can add the number of bytes generated by
73 * the input trans to the source field for the cur_source. This allows us to
74 * see how much output has been buffered for each input source.
75 *
76 * When the program assembles 'struct trans' objects to scan for input
77 * (normally in trans_get_wait_objs()), it is able to see how much buffered
78 * output is registered for each input. Inputs which have too much buffered
79 * output owing are skipped, and not considered for input.
80 *
81 * This provides a simple means of providing back-pressure on an input
82 * where the data it is providing is being processed and then sent out on
83 * a much slower link.
84 */
5885 struct source_info
5986 {
60 int cur_source;
61 int source[7];
87 enum xrdp_source cur_source;
88 int source[XRDP_SOURCE_MAX_COUNT];
6289 };
6390
6491 struct trans
87114 trans_send_proc trans_send;
88115 trans_can_recv_proc trans_can_recv;
89116 struct source_info *si;
90 int my_source;
117 enum xrdp_source my_source;
91118 };
92119
93120 struct trans*
1616 *
1717 * xrdp / xserver info / caps
1818 */
19
20 #include "xrdp_constants.h"
1921
2022 #if !defined(XRDP_CLIENT_INFO_H)
2123 #define XRDP_CLIENT_INFO_H
5658 char hostname[32];
5759 int build;
5860 int keylayout;
59 char username[256];
60 char password[256];
61 char domain[256];
62 char program[256];
63 char directory[256];
61 char username[INFO_CLIENT_MAX_CB_LEN];
62 char password[INFO_CLIENT_MAX_CB_LEN];
63 char domain[INFO_CLIENT_MAX_CB_LEN];
64 char program[INFO_CLIENT_MAX_CB_LEN];
65 char directory[INFO_CLIENT_MAX_CB_LEN];
6466 int rdp_compression;
6567 int rdp_autologin;
6668 int crypt_level; /* 1, 2, 3 = low, medium, high */
156158 int use_cache_glyph_v2;
157159 int rail_enable;
158160 int suppress_output;
161
162 int enable_token_login;
163 char domain_user_separator[16];
159164 };
160165
161166 #endif
2828 *
2929 * xrdp constants
3030 *
31 * Constants defined in publically available Microsoft documents are not
32 * stored here, but are stored in the include files ms-*.h, where the name
33 * of the file is the name of the document defining the constant.
34 *
35 * So for example, NTSTATUS values found in [MS-ERREF] are found in
36 * ms-erref.h
3137 ******************************************************************************/
3238
3339 #define INFO_CLIENT_NAME_BYTES 32
40 /**
41 * Maximum length of a string including the mandatory null terminator
42 * [MS-RDPBCGR] TS_INFO_PACKET(2.2.1.11.1.1)
43 */
44 #define INFO_CLIENT_MAX_CB_LEN 512
3445
3546 #define XRDP_MAX_BITMAP_CACHE_ID 3
3647 #define XRDP_MAX_BITMAP_CACHE_IDX 2000
5970 #define MCS_SDRQ 25 /* Send Data Request */
6071 #define MCS_SDIN 26 /* Send Data Indication */
6172
62 /*
63 * Constants come from Remote Desktop Protocol
64 */
65
66 /* RDP Security Negotiation codes */
67 #define RDP_NEG_REQ 0x01 /* MS-RDPBCGR 2.2.1.1.1 */
68 #define RDP_NEG_RSP 0x02 /* MS-RDPBCGR 2.2.1.2.1 */
69 #define RDP_NEG_FAILURE 0x03 /* MS-RDPBCGR 2.2.1.2.2 */
70 #define RDP_CORRELATION_INFO 0x06 /* MS-RDPBCGR 2.2.1.1.2 */
71
72 /* Protocol types codes (MS-RDPBCGR 2.2.1.1.1) */
73 #define PROTOCOL_RDP 0x00000000
74 #define PROTOCOL_SSL 0x00000001
75 #define PROTOCOL_HYBRID 0x00000002
76 #define PROTOCOL_RDSTLS 0x00000004
77 #define PROTOCOL_HYBRID_EX 0x00000008
78
79 /* Negotiation packet flags (MS-RDPBCGR 2.2.1.2.1) */
80 #define EXTENDED_CLIENT_DATA_SUPPORTED 0x01
81 #define DYNVC_GFX_PROTOCOL_SUPPORTED 0x02
82 #define NEGRSP_RESERVED 0x04
83 #define RESTRICTED_ADMIN_MODE_SUPPORTED 0x08
84 #define REDIRECTED_AUTHENTICATION_MODE_SUPPORTED 0x10
85
86 /* RDP Negotiation Failure Codes (MS-RDPBCGR 2.2.1.2.2) */
87 #define SSL_REQUIRED_BY_SERVER 0x00000001
88 #define SSL_NOT_ALLOWED_BY_SERVER 0x00000002
89 #define SSL_CERT_NOT_ON_SERVER 0x00000003
90 #define INCONSISTENT_FLAGS 0x00000004
91 #define HYBRID_REQUIRED_BY_SERVER 0x00000005
92 #define SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER 0x00000006
93
94 /* Client Core Data: connectionType (MS-RDPBCGR 2.2.1.3.2) */
95 #define CONNECTION_TYPE_MODEM 0x01
96 #define CONNECTION_TYPE_BROADBAND_LOW 0x02
97 #define CONNECTION_TYPE_SATELLITE 0x03
98 #define CONNECTION_TYPE_BROADBAND_HIGH 0x04
99 #define CONNECTION_TYPE_WAN 0x05
100 #define CONNECTION_TYPE_LAN 0x06
101 #define CONNECTION_TYPE_AUTODETECT 0x07
102
103 /* Client Core Data: colorDepth, postBeta2ColorDepth (MS-RDPBCGR 2.2.1.3.2) */
104 #define RNS_UD_COLOR_4BPP 0xCA00
105 #define RNS_UD_COLOR_8BPP 0xCA01
106 #define RNS_UD_COLOR_16BPP_555 0xCA02
107 #define RNS_UD_COLOR_16BPP_565 0xCA03
108 #define RNS_UD_COLOR_24BPP 0xCA04
109
110 /* Slow-Path Input Event: messageType (MS-RDPBCGR 2.2.8.1.1.3.1.1) */
111 /* TODO: to be renamed */
112 #define RDP_INPUT_SYNCHRONIZE 0
113 #define RDP_INPUT_CODEPOINT 1
114 #define RDP_INPUT_VIRTKEY 2
115 #define RDP_INPUT_SCANCODE 4
116 #define RDP_INPUT_UNICODE 5
117 #define RDP_INPUT_MOUSE 0x8001
118 #define RDP_INPUT_MOUSEX 0x8002
119
120 #define FASTPATH_INPUT_ENCRYPTED 0x2
121
122 /* Fast-Path Input Event: eventCode (MS-RDPBCGR 2.2.8.1.2.2) */
123 #define FASTPATH_INPUT_EVENT_SCANCODE 0x0
124 #define FASTPATH_INPUT_EVENT_MOUSE 0x1
125 #define FASTPATH_INPUT_EVENT_MOUSEX 0x2
126 #define FASTPATH_INPUT_EVENT_SYNC 0x3
127 #define FASTPATH_INPUT_EVENT_UNICODE 0x4
128 #define FASTPATH_INPUT_EVENT_QOE_TIMESTAMP 0x6
129
130 /* Fast-Path Keyboard Event: eventHeader (MS-RDPBCGR 2.2.8.2.2.1) */
131 #define FASTPATH_INPUT_KBDFLAGS_RELEASE 0x01
132 #define FASTPATH_INPUT_KBDFLAGS_EXTENDED 0x02
133 #define FASTPATH_INPUT_KBDFLAGS_EXTENDED1 0x04
134
135 /* Server Fast-Path Update PDU: action (MS-RDPBCGR 2.2.0.1.2) */
136 #define FASTPATH_OUTPUT_ACTION_FASTPATH 0x0
137 #define FASTPATH_OUTPUT_ACTION_X224 0x3
138
139 /* Server Fast-Path Update PDU: flags (MS-RDPBCGR 2.2.0.1.2) */
140 #define FASTPATH_OUTPUT_ACTION_FASTPATH 0x0
141 #define FASTPATH_OUTPUT_SECURE_CHECKSUM 0x1
142 #define FASTPATH_OUTPUT_ENCRYPTED 0x2
143
144 /* Fast-Path Update: updateCode (MS-RDPBCGR 2.2.9.1.2.1) */
145 #define FASTPATH_UPDATETYPE_ORDERS 0x0
146 #define FASTPATH_UPDATETYPE_BITMAP 0x1
147 #define FASTPATH_UPDATETYPE_PALETTE 0x2
148 #define FASTPATH_UPDATETYPE_SYNCHRONIZE 0x3
149 #define FASTPATH_UPDATETYPE_SURFCMDS 0x4
150 #define FASTPATH_UPDATETYPE_PTR_NULL 0x5
151 #define FASTPATH_UPDATETYPE_PTR_DEFAULT 0x6
152 #define FASTPATH_UPDATETYPE_PTR_POSITION 0x8
153 #define FASTPATH_UPDATETYPE_COLOR 0x9
154 #define FASTPATH_UPDATETYPE_CACHED 0xA
155 #define FASTPATH_UPDATETYPE_POINTER 0xB
156
157 /* Fast-Path Update: fragmentation (MS-RDPBCGR 2.2.9.1.2.1) */
158 #define FASTPATH_FRAGMENT_SINGLE 0x0
159 #define FASTPATH_FRAGMENT_LAST 0x1
160 #define FASTPATH_FRAGMENT_FIRST 0x2
161 #define FASTPATH_FRAGMENT_NEXT 0x3
162 #define FASTPATH_OUTPUT_COMPRESSION_USED 0x2
163
164 /* Mouse Event: pointerFlags (MS-RDPBCGR 2.2.8.1.1.3.1.1.3) */
165 #define PTRFLAGS_HWHEEL 0x0400
166 #define PTRFLAGS_WHEEL 0x0200
167 #define PTRFLAGS_WHEEL_NEGATIVE 0x0100
168 #define WheelRotationMask 0x01FF
169 #define PTRFLAGS_MOVE 0x0800
170 #define PTRFLAGS_DOWN 0x8000
171 #define PTRFLAGS_BUTTON1 0x1000
172 #define PTRFLAGS_BUTTON2 0x2000
173 #define PTRFLAGS_BUTTON3 0x4000
174
175 /* Extended Mouse Event: pointerFlags (MS-RDPBCGR 2.2.8.1.1.3.1.1.4) */
176 #define PTRXFLAGS_DOWN 0x8000
177 #define PTRXFLAGS_BUTTON1 0x0001
178 #define PTRXFLAGS_BUTTON2 0x0002
179
180 /* General Capability Set: osMajorType (MS-RDPBCGR 2.2.7.1.1) */
181 #define OSMAJORTYPE_UNSPECIFIED 0x0000
182 #define OSMAJORTYPE_WINDOWS 0x0001
183 #define OSMAJORTYPE_OS2 0x0002
184 #define OSMAJORTYPE_MACINTOSH 0x0003
185 #define OSMAJORTYPE_UNIX 0x0004
186 #define OSMAJORTYPE_IOS 0x0005
187 #define OSMAJORTYPE_OSX 0x0006
188 #define OSMAJORTYPE_ANDROID 0x0007
189 #define OSMAJORTYPE_CHROME_OS 0x0008
190
191 /* General Capability Set: osMinorType (MS-RDPBCGR 2.2.7.1.1) */
192 #define OSMINORTYPE_UNSPECIFIED 0x0000
193 #define OSMINORTYPE_WINDOWS_31X 0x0001
194 #define OSMINORTYPE_WINDOWS_95 0x0002
195 #define OSMINORTYPE_WINDOWS_NT 0x0003
196 #define OSMINORTYPE_OS2_V21 0x0004
197 #define OSMINORTYPE_POWER_PC 0x0005
198 #define OSMINORTYPE_MACINTOSH 0x0006
199 #define OSMINORTYPE_NATIVE_XSERVER 0x0007
200 #define OSMINORTYPE_PSEUDO_XSERVER 0x0008
201 #define OSMINORTYPE_WINDOWS_RT 0x0009
202
203 /* Window List Capability Set: WndSupportLevel (MS-RDPERP 2.2.1.1.2) */
204 #define TS_WINDOW_LEVEL_NOT_SUPPORTED 0x00000000
205 #define TS_WINDOW_LEVEL_SUPPORTED 0x00000001
206 #define TS_WINDOW_LEVEL_SUPPORTED_EX 0x00000002
207
208 /* Extended Info Packet: performanceFlags (MS-RDPBCGR 2.2.1.11.1.1.1) */
209 /* TODO: to be renamed */
210 #define RDP5_DISABLE_NOTHING 0x00
211 #define RDP5_NO_WALLPAPER 0x01
212 #define RDP5_NO_FULLWINDOWDRAG 0x02
213 #define RDP5_NO_MENUANIMATIONS 0x04
214 #define RDP5_NO_THEMING 0x08
215 #define RDP5_NO_CURSOR_SHADOW 0x20
216 #define RDP5_NO_CURSORSETTINGS 0x40 /* disables cursor blinking */
217
218 /* Virtual channel options */
219 /* Channel Definition Structure: options (MS-RDPBCGR 2.2.1.3.4.1) */
220 #define REMOTE_CONTROL_PERSISTENT 0x00100000
221 /* NOTE: XR_ prefixed to avoid conflict with FreeRDP */
222 #define XR_CHANNEL_OPTION_SHOW_PROTOCOL 0x00200000
223 #define XR_CHANNEL_OPTION_COMPRESS 0x00400000
224 #define XR_CHANNEL_OPTION_COMPRESS_RDP 0x00800000
225 #define XR_CHANNEL_OPTION_PRI_LOW 0x02000000
226 #define XR_CHANNEL_OPTION_PRI_MED 0x04000000
227 #define XR_CHANNEL_OPTION_PRI_HIGH 0x08000000
228 #define XR_CHANNEL_OPTION_ENCRYPT_CS 0x10000000
229 #define XR_CHANNEL_OPTION_ENCRYPT_SC 0x20000000
230 #define XR_CHANNEL_OPTION_ENCRYPT_RDP 0x40000000
231 #define XR_CHANNEL_OPTION_INITIALIZED 0x80000000
232
233 /* RDPDR: Device Announce Header: DeviceType (MS-RDPEFS 2.2.1.3) */
234 /* TODO: to be renamed */
235 #define DEVICE_TYPE_SERIAL 0x01
236 #define DEVICE_TYPE_PARALLEL 0x02
237 #define DEVICE_TYPE_PRINTER 0x04
238 #define DEVICE_TYPE_DISK 0x08
239 #define DEVICE_TYPE_SCARD 0x20
240
241 /* Order Capability Set: orderSupportExFlags (MS-RDPBCGR 2.2.7.1.3) */
242 #define XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT 0x0002
243 #define XR_ORDERFLAGS_EX_ALTSEC_FRAME_MARKER_SUPPORT 0x0004
244 #define XR_ORDERFLAGS_EX_OFFSCREEN_COMPOSITE_SUPPORT 0x0100
245
246 /* Order Capability Set: orderSupport (MS-RDPBCGR 2.2.7.1.3) */
247 #define TS_NEG_DSTBLT_INDEX 0x00
248 #define TS_NEG_PATBLT_INDEX 0x01
249 #define TS_NEG_SCRBLT_INDEX 0x02
250 #define TS_NEG_MEMBLT_INDEX 0x03
251 #define TS_NEG_MEM3BLT_INDEX 0x04
252 /* 0x05 */
253 /* 0x06 */
254 #define TS_NEG_DRAWNINEGRID_INDEX 0x07
255 #define TS_NEG_LINETO_INDEX 0x08
256 #define TS_NEG_MULTI_DRAWNINEGRID_INDEX 0x09
257 /* 0x0A */
258 #define TS_NEG_SAVEBITMAP_INDEX 0x0B
259 /* 0x0C */
260 /* 0x0D */
261 /* 0x0E */
262 #define TS_NEG_MULTIDSTBLT_INDEX 0x0F
263 #define TS_NEG_MULTIPATBLT_INDEX 0x10
264 #define TS_NEG_MULTISCRBLT_INDEX 0x11
265 #define TS_NEG_MULTIOPAQUERECT_INDEX 0x12
266 #define TS_NEG_FAST_INDEX_INDEX 0x13
267 #define TS_NEG_POLYGON_SC_INDEX 0x14
268 #define TS_NEG_POLYGON_CB_INDEX 0x15
269 #define TS_NEG_POLYLINE_INDEX 0x16
270 /* 0x17 */
271 #define TS_NEG_FAST_GLYPH_INDEX 0x18
272 #define TS_NEG_ELLIPSE_SC_INDEX 0x19
273 #define TS_NEG_ELLIPSE_CB_INDEX 0x1A
274 #define TS_NEG_INDEX_INDEX 0x1B
275 /* 0x1C */
276 /* 0x1D */
277 /* 0x1E */
278 /* 0x1F */
279
280 /* General Capability Set: extraFlags (MS-RDPBCGR 2.2.7.1.1) */
281 #define TS_CAPS_PROTOCOLVERSION 0x0200
282 #define FASTPATH_OUTPUT_SUPPORTED 0x0001
283 #define NO_BITMAP_COMPRESSION_HDR 0x0400
284 #define LONG_CREDENTIALS_SUPPORTED 0x0004
285 #define AUTORECONNECT_SUPPORTED 0x0008
286 #define ENC_SALTED_CHECKSUM 0x0010
287
288 /* Order Capability Set: orderFlags (MS-RDPBCGR 2.2.7.1.3) */
289 #define NEGOTIATEORDERSUPPORT 0x0002
290 #define ZEROBOUNDSDELTASUPPORT 0x0008
291 #define COLORINDEXSUPPORT 0x0020
292 #define SOLIDPATTERNBRUSHONLY 0x0040
293 #define ORDERFLAGS_EXTRA_FLAGS 0x0080
294
295 /* Input Capability Set: inputFlags (MS-RDPBCGR 2.2.7.1.6) */
296 #define INPUT_FLAG_SCANCODES 0x0001
297 #define INPUT_FLAG_MOUSEX 0x0004
298 #define INPUT_FLAG_FASTPATH_INPUT 0x0008
299 #define INPUT_FLAG_UNICODE 0x0010
300 #define INPUT_FLAG_FASTPATH_INPUT2 0x0020
301 #define INPUT_FLAG_UNUSED1 0x0040
302 #define INPUT_FLAG_UNUSED2 0x0080
303 #define TS_INPUT_FLAG_MOUSE_HWHEEL 0x0100
304 #define TS_INPUT_FLAG_QOE_TIMESTAMPS 0x0200
305
306 /* Desktop Composition Capability Set: CompDeskSupportLevel (MS-RDPBCGR 2.2.7.2.8) */
307 #define COMPDESK_NOT_SUPPORTED 0x0000
308 #define COMPDESK_SUPPORTED 0x0001
309
310 /* Surface Commands Capability Set: cmdFlags (MS-RDPBCGR 2.2.7.2.9) */
311 #define SURFCMDS_SETSURFACEBITS 0x00000002
312 #define SURFCMDS_FRAMEMARKER 0x00000010
313 #define SURFCMDS_STREAMSUFRACEBITS 0x00000040
314
315 /* Bitmap Codec: codecGUID (MS-RDPBCGR 2.2.7.2.10.1.1) */
316
317 /* CODEC_GUID_NSCODEC CA8D1BB9-000F-154F-589FAE2D1A87E2D6 */
318 #define XR_CODEC_GUID_NSCODEC \
319 "\xb9\x1b\x8d\xca\x0f\x00\x4f\x15\x58\x9f\xae\x2d\x1a\x87\xe2\xd6"
320
321 /* CODEC_GUID_REMOTEFX 76772F12-BD72-4463-AFB3B73C9C6F7886 */
322 #define XR_CODEC_GUID_REMOTEFX \
323 "\x12\x2F\x77\x76\x72\xBD\x63\x44\xAF\xB3\xB7\x3C\x9C\x6F\x78\x86"
324
325 /* CODEC_GUID_IMAGE_REMOTEFX 2744CCD4-9D8A-4E74-803C-0ECBEEA19C54 */
326 #define XR_CODEC_GUID_IMAGE_REMOTEFX \
327 "\xD4\xCC\x44\x27\x8A\x9D\x74\x4E\x80\x3C\x0E\xCB\xEE\xA1\x9C\x54"
328
329 /* MFVideoFormat_H264 0x34363248-0000-0010-800000AA00389B71 */
330 #define XR_CODEC_GUID_H264 \
331 "\x48\x32\x36\x34\x00\x00\x10\x00\x80\x00\x00\xAA\x00\x38\x9B\x71"
332
333 /* CODEC_GUID_JPEG 1BAF4CE6-9EED-430C-869ACB8B37B66237 */
334 #define XR_CODEC_GUID_JPEG \
335 "\xE6\x4C\xAF\x1B\xED\x9E\x0C\x43\x86\x9A\xCB\x8B\x37\xB6\x62\x37"
336
337 /* CODEC_GUID_PNG 0E0C858D-28E0-45DB-ADAA0F83E57CC560 */
338 #define XR_CODEC_GUID_PNG \
339 "\x8D\x85\x0C\x0E\xE0\x28\xDB\x45\xAD\xAA\x0F\x83\xE5\x7C\xC5\x60"
340
341 /* Surface Command Type (MS-RDPBCGR 2.2.9.1.2.1.10.1) */
342 #define CMDTYPE_SET_SURFACE_BITS 0x0001
343 #define CMDTYPE_FRAME_MARKER 0x0004
344 #define CMDTYPE_STREAM_SURFACE_BITS 0x0006
345
346 /* RDP5 disconnect PDU */
347 /* Set Error Info PDU Data: errorInfo (MS-RDPBCGR 2.2.5.1.1) */
348 /* TODO: to be renamed */
349 #define exDiscReasonNoInfo 0x0000
350 #define exDiscReasonAPIInitiatedDisconnect 0x0001
351 #define exDiscReasonAPIInitiatedLogoff 0x0002
352 #define exDiscReasonServerIdleTimeout 0x0003
353 #define exDiscReasonServerLogonTimeout 0x0004
354 #define exDiscReasonReplacedByOtherConnection 0x0005
355 #define exDiscReasonOutOfMemory 0x0006
356 #define exDiscReasonServerDeniedConnection 0x0007
357 #define exDiscReasonServerDeniedConnectionFips 0x0008
358 #define exDiscReasonLicenseInternal 0x0100
359 #define exDiscReasonLicenseNoLicenseServer 0x0101
360 #define exDiscReasonLicenseNoLicense 0x0102
361 #define exDiscReasonLicenseErrClientMsg 0x0103
362 #define exDiscReasonLicenseHwidDoesntMatchLicense 0x0104
363 #define exDiscReasonLicenseErrClientLicense 0x0105
364 #define exDiscReasonLicenseCantFinishProtocol 0x0106
365 #define exDiscReasonLicenseClientEndedProtocol 0x0107
366 #define exDiscReasonLicenseErrClientEncryption 0x0108
367 #define exDiscReasonLicenseCantUpgradeLicense 0x0109
368 #define exDiscReasonLicenseNoRemoteConnections 0x010a
369
370 /* Info Packet (TS_INFO_PACKET): flags (MS-RDPBCGR 2.2.1.11.1.1) */
371 /* TODO: to be renamed */
372 #define RDP_LOGON_AUTO 0x0008
373 #define RDP_LOGON_NORMAL 0x0033
374 #define RDP_COMPRESSION 0x0080
375 #define RDP_LOGON_BLOB 0x0100
376 #define RDP_LOGON_LEAVE_AUDIO 0x2000
377 #define RDP_LOGON_RAIL 0x8000
378
379 /* Compression Flags (MS-RDPBCGR 3.1.8.2.1) */
380 /* TODO: to be renamed, not used anywhere */
381 #define RDP_MPPC_COMPRESSED 0x20
382 #define RDP_MPPC_RESET 0x40
383 #define RDP_MPPC_FLUSH 0x80
384 #define RDP_MPPC_DICT_SIZE 8192 /* RDP 4.0 | MS-RDPBCGR 3.1.8 */
385
386 /* Drawing Order: controlFlags (MS-RDPEGDI 2.2.2.2.1, ) */
387 #define TS_STANDARD 0x01
388 #define TS_SECONDARY 0x02
389 #define TS_BOUNDS 0x04
390 #define TS_TYPE_CHANGE 0x08
391 #define TS_DELTA_COORDINATES 0x10
392 #define TS_ZERO_BOUNDS_DELTAS 0x20
393 #define TS_ZERO_FIELD_BYTE_BIT0 0x40
394 #define TS_ZERO_FIELD_BYTE_BIT1 0x80
395
396 /* Drawing Order: orderType (MS-RDPEGDI 2.2.2.2.1.1.2) ? */
397 #define RDP_ORDER_DESTBLT 0
398 #define RDP_ORDER_PATBLT 1
399 #define RDP_ORDER_SCREENBLT 2
400 #define RDP_ORDER_LINE 9
401 #define RDP_ORDER_RECT 10
402 #define RDP_ORDER_DESKSAVE 11
403 #define RDP_ORDER_MEMBLT 13
404 #define RDP_ORDER_TRIBLT 14
405 #define RDP_ORDER_POLYLINE 22
406 #define RDP_ORDER_TEXT2 27
407 #define RDP_ORDER_COMPOSITE 37 /* 0x25 */
408
409 /* Secondary Drawing Order Header: orderType (MS-RDPEGDI 2.2.2.2.1.2.1.1) */
410 #define TS_CACHE_BITMAP_UNCOMPRESSED 0x00
411 #define TS_CACHE_COLOR_TABLE 0x01
412 #define TS_CACHE_BITMAP_COMPRESSED 0x02
413 #define TS_CACHE_GLYPH 0x03
414 #define TS_CACHE_BITMAP_UNCOMPRESSED_REV2 0x04
415 #define TS_CACHE_BITMAP_COMPRESSED_REV2 0x05
416 #define TS_CACHE_BRUSH 0x07
417 #define TS_CACHE_BITMAP_COMPRESSED_REV3 0x08
418
419 /* Maps to generalCapabilitySet in T.128 page 138 */
420
421 /* Capability Set: capabilitySetType (MS-RDPBCGR 2.2.1.13.1.1.1) */
422 #define CAPSTYPE_GENERAL 0x0001
423 #define CAPSTYPE_GENERAL_LEN 0x18
424
425 #define CAPSTYPE_BITMAP 0x0002
426 #define CAPSTYPE_BITMAP_LEN 0x1C
427
428 #define CAPSTYPE_ORDER 0x0003
429 #define CAPSTYPE_ORDER_LEN 0x58
430 #define ORDER_CAP_NEGOTIATE 2 /* NEGOTIATEORDERSUPPORT? not used */
431 #define ORDER_CAP_NOSUPPORT 4 /* not used */
432
433 #define CAPSTYPE_BITMAPCACHE 0x0004
434 #define CAPSTYPE_BITMAPCACHE_LEN 0x28
435
436 #define CAPSTYPE_CONTROL 0x0005
437 #define CAPSTYPE_CONTROL_LEN 0x0C
438
439 #define CAPSTYPE_ACTIVATION 0x0007
440 #define CAPSTYPE_ACTIVATION_LEN 0x0C
441
442 #define CAPSTYPE_POINTER 0x0008
443 #define CAPSTYPE_POINTER_LEN 0x0a
444 #define CAPSTYPE_POINTER_MONO_LEN 0x08
445
446 #define CAPSTYPE_SHARE 0x0009
447 #define CAPSTYPE_SHARE_LEN 0x08
448
449 #define CAPSTYPE_COLORCACHE 0x000A
450 #define CAPSTYPE_COLORCACHE_LEN 0x08
451
452 #define CAPSTYPE_SOUND 0x000C
453
454 #define CAPSTYPE_INPUT 0x000D
455 #define CAPSTYPE_INPUT_LEN 0x58
456
457 #define CAPSTYPE_FONT 0x000E
458 #define CAPSTYPE_FONT_LEN 0x04
459
460 #define CAPSTYPE_BRUSH 0x000F
461 #define CAPSTYPE_BRUSH_LEN 0x08
462
463 #define CAPSTYPE_GLYPHCACHE 0x0010
464 #define CAPSTYPE_OFFSCREENCACHE 0x0011
465
466 #define CAPSTYPE_BITMAPCACHE_HOSTSUPPORT 0x0012
467 #define CAPSTYPE_BITMAPCACHE_HOSTSUPPORT_LEN 0x08
468
469 #define CAPSTYPE_BITMAPCACHE_REV2 0x0013
470 #define CAPSTYPE_BITMAPCACHE_REV2_LEN 0x28
471 #define BMPCACHE2_FLAG_PERSIST ((long)1<<31)
472
473 #define CAPSTYPE_VIRTUALCHANNEL 0x0014
474 #define CAPSTYPE_VIRTUALCHANNEL_LEN 0x08
475
476 #define CAPSTYPE_DRAWNINGRIDCACHE 0x0015
477 #define CAPSTYPE_DRAWGDIPLUS 0x0016
478 #define CAPSTYPE_RAIL 0x0017
479 #define CAPSTYPE_WINDOW 0x0018
480
481 #define CAPSSETTYPE_COMPDESK 0x0019
482 #define CAPSSETTYPE_COMPDESK_LEN 0x06
483
484 #define CAPSSETTYPE_MULTIFRAGMENTUPDATE 0x001A
485 #define CAPSSETTYPE_MULTIFRAGMENTUPDATE_LEN 0x08
486
487 #define CAPSETTYPE_LARGE_POINTER 0x001B
488 #define CAPSETTYPE_LARGE_POINTER_LEN 0x06
489
490 #define CAPSETTYPE_SURFACE_COMMANDS 0x001C
491 #define CAPSETTYPE_SURFACE_COMMANDS_LEN 0x0C
492
493 #define CAPSSETTYPE_BITMAP_CODECS 0x001D
494 #define CAPSSETTYPE_BITMAP_CODECS_LEN 0x1C
495
496 #define CAPSTYPE_FRAME_ACKNOWLEDGE 0x001E
497 #define CAPSTYPE_FRAME_ACKNOWLEDGE_LEN 0x08
498
499 /* TS_SECURITY_HEADER: flags (MS-RDPBCGR 2.2.8.1.1.2.1) */
500 /* TODO: to be renamed */
501 #define SEC_CLIENT_RANDOM 0x0001 /* SEC_EXCHANGE_PKT? */
502 #define SEC_ENCRYPT 0x0008
503 #define SEC_LOGON_INFO 0x0040 /* SEC_INFO_PKT */
504 #define SEC_LICENCE_NEG 0x0080 /* SEC_LICENSE_PKT */
505
506 #define SEC_TAG_SRV_INFO 0x0c01 /* SC_CORE */
507 #define SEC_TAG_SRV_CRYPT 0x0c02 /* SC_SECURITY */
508 #define SEC_TAG_SRV_CHANNELS 0x0c03 /* SC_NET? */
509
510 /* TS_UD_HEADER: type (MS-RDPBCGR (2.2.1.3.1) */
511 /* TODO: to be renamed */
512 #define SEC_TAG_CLI_INFO 0xc001 /* CS_CORE? */
513 #define SEC_TAG_CLI_CRYPT 0xc002 /* CS_SECURITY? */
514 #define SEC_TAG_CLI_CHANNELS 0xc003 /* CS_CHANNELS? */
515 #define SEC_TAG_CLI_4 0xc004 /* CS_CLUSTER? */
516 #define SEC_TAG_CLI_MONITOR 0xc005 /* CS_MONITOR */
517
518 /* Server Proprietary Certificate (MS-RDPBCGR 2.2.1.4.3.1.1) */
519 /* TODO: to be renamed */
520 #define SEC_TAG_PUBKEY 0x0006 /* BB_RSA_KEY_BLOB */
521 #define SEC_TAG_KEYSIG 0x0008 /* BB_SIGNATURE_KEY_BLOB */
522
523 /* LicensingMessage (MS-RDPELE 2.2.2) */
524 /* TODO: to be renamed */
525 #define LICENCE_TAG_DEMAND 0x01 /* LICNSE_REQUEST */
526 #define LICENCE_TAG_AUTHREQ 0x02 /* PLATFORM_CHALLENGE */
527 #define LICENCE_TAG_ISSUE 0x03 /* NEW_LICENSE */
528 #define LICENCE_TAG_REISSUE 0x04 /* UPGRADE_LICENSE */
529 #define LICENCE_TAG_PRESENT 0x12 /* LICENSE_INFO */
530 #define LICENCE_TAG_REQUEST 0x13 /* NEW_LICENSE_REQUEST */
531 #define LICENCE_TAG_AUTHRESP 0x15 /* PLATFORM_CHALLENGE_RESPONSE */
532 #define LICENCE_TAG_RESULT 0xff
533
534 /* LICENSE_BINARY_BLOB (MS-RDPBCGR 2.2.1.12.1.2) */
535 #define LICENCE_TAG_USER 0x000f /* BB_CLIENT_USER_NAME_BLOB */
536 #define LICENCE_TAG_HOST 0x0010 /* BB_CLIENT_MACHINE_NAME_BLOB */
537
538 /* Share Data Header: pduType2 (MS-RDPBCGR 2.2.8.1.1.1.2) */
539 /* TODO: to be renamed */
540 #define RDP_DATA_PDU_UPDATE 2 /* PDUTYPE2_UPDATE */
541 #define RDP_DATA_PDU_CONTROL 20
542 #define RDP_DATA_PDU_POINTER 27
543 #define RDP_DATA_PDU_INPUT 28
544 #define RDP_DATA_PDU_SYNCHRONISE 31
545 #define PDUTYPE2_REFRESH_RECT 33
546 #define RDP_DATA_PDU_PLAY_SOUND 34
547 #define RDP_DATA_PDU_LOGON 38
548 #define RDP_DATA_PDU_FONT2 39
549 #define RDP_DATA_PDU_DISCONNECT 47
550
551 /* Control PDU Data: action (MS-RDPBCGR 2.2.1.15.1) */
552 /* TODO: to be renamed */
553 #define RDP_CTL_REQUEST_CONTROL 1 /* CTRLACTION_REQUEST_CONTROL */
554 #define RDP_CTL_GRANT_CONTROL 2
555 #define RDP_CTL_DETACH 3
556 #define RDP_CTL_COOPERATE 4
557
558 /* Slow-Path Graphics Update: updateType (MS-RDPBCGR 2.2.9.1.1.3.1) */
559 /* TODO: to be renamed */
560 #define RDP_UPDATE_ORDERS 0
561 #define RDP_UPDATE_BITMAP 1
562 #define RDP_UPDATE_PALETTE 2
563 #define RDP_UPDATE_SYNCHRONIZE 3
564
565 /* Server Pointer Update PDU: messageType (MS-RDPBCGR 2.2.9.1.1.4) */
566 /* TODO: to be renamed */
567 #define RDP_POINTER_SYSTEM 1 /* TS_PTRMSGTYPE_SYSTEM */
568 #define RDP_POINTER_MOVE 3
569 #define RDP_POINTER_COLOR 6
570 #define RDP_POINTER_CACHED 7
571 #define RDP_POINTER_POINTER 8
572
573 /* System Pointer Update: systemPointerType (MS-RDPBCGR 2.2.9.1.1.4.3) */
574 #define RDP_NULL_POINTER 0
575 #define RDP_DEFAULT_POINTER 0x7F00
576
577 /* Keyboard Event: keyboardFlags (MS-RDPBCGR 2.2.8.1.1.3.1.1.1) */
578 /* TODO: to be renamed */
579 #define KBD_FLAG_RIGHT 0x0001
580 #define KBD_FLAG_EXT 0x0100 /* KBDFLAGS_EXTENDED */
581 #define KBD_FLAG_QUIET 0x1000
582 #define KBD_FLAG_DOWN 0x4000
583 #define KBD_FLAG_UP 0x8000
584
585 /* Synchronize Event: toggleFlags (MS-RDPBCGR 2.2.8.1.1.3.1.1.5) */
586 /* TODO: to be renamed */
587 #define KBD_FLAG_SCROLL 0x0001 /* TS_SYNC_SCROLL_LOCK */
588 #define KBD_FLAG_NUMLOCK 0x0002
589 #define KBD_FLAG_CAPITAL 0x0004
590 #define TS_SYNC_KANA_LOCK 0x0008
591
592 /* Glyph Cache Capability Set: GlyphSupportLevel (MS-RDPBCGR 2.2.7.1.8) */
593 #define GLYPH_SUPPORT_NONE 0x0000
594 #define GLYPH_SUPPORT_PARTIAL 0x0001
595 #define GLYPH_SUPPORT_FULL 0x0002
596 #define GLYPH_SUPPORT_ENCODE 0x0003
597
59873 /******************************************************************************
59974 *
60075 * Constants come from other Microsoft products
61590
61691 /* NTSTATUS Values (MS-ERREF 2.3.1) */
61792 /* used for RDPDR */
618 #define STATUS_SUCCESS 0x00000000
619 #define STATUS_PENDING 0x00000103
620
621 #define STATUS_NO_MORE_FILES 0x80000006
622 #define STATUS_DEVICE_PAPER_EMPTY 0x8000000e
623 #define STATUS_DEVICE_POWERED_OFF 0x8000000f
624 #define STATUS_DEVICE_OFF_LINE 0x80000010
625 #define STATUS_DEVICE_BUSY 0x80000011
626
627 #define STATUS_INVALID_HANDLE 0xc0000008
628 #define STATUS_INVALID_PARAMETER 0xc000000d
629 #define STATUS_NO_SUCH_FILE 0xc000000f
630 #define STATUS_INVALID_DEVICE_REQUEST 0xc0000010
631 #define STATUS_ACCESS_DENIED 0xc0000022
632 #define STATUS_OBJECT_NAME_COLLISION 0xc0000035
633 #define STATUS_DISK_FULL 0xc000007f
634 #define STATUS_FILE_IS_A_DIRECTORY 0xc00000ba
635 #define STATUS_NOT_SUPPORTED 0xc00000bb
636 #define STATUS_TIMEOUT 0xc0000102
637 #define STATUS_CANCELLED 0xc0000120
638
639 /* MS-SMB2 2.2.13 */
640 /* TODO: not used anywhere */
641 #define FILE_DIRECTORY_FILE 0x00000001
642 #define FILE_NON_DIRECTORY_FILE 0x00000040
643 #define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000
644
64593 /*
64694 * not yet sorted out
64795 */
670118 #define LICENCE_HWID_SIZE 20
671119 #define LICENCE_SIGNATURE_SIZE 16
672120
673
674 /* PDU Types (MS-RDPBCGR 2.2.8.1.1.1.1) */
675 #define PDUTYPE_DEMANDACTIVEPDU 0x1
676 #define PDUTYPE_CONFIRMACTIVEPDU 0x3
677 #define PDUTYPE_DEACTIVATEALLPDU 0x6
678 #define PDUTYPE_DATAPDU 0x7
679 #define PDUTYPE_SERVER_REDIR_PKT 0xA
680121
681122 /* See T.128 */
682123 /* not used anywhere */
809250 #define WM_BUTTON6DOWN 112
810251 #define WM_BUTTON7UP 113
811252 #define WM_BUTTON7DOWN 114
253 #define WM_BUTTON8UP 115
254 #define WM_BUTTON8DOWN 116
255 #define WM_BUTTON9UP 117
256 #define WM_BUTTON9DOWN 118
812257 #define WM_INVALIDATE 200
813258
814259 #define CB_ITEMCHANGE 300
22
33 scriptversion=2018-03-07.03; # UTC
44
5 # Copyright (C) 1999-2018 Free Software Foundation, Inc.
5 # Copyright (C) 1999-2020 Free Software Foundation, Inc.
66 # Written by Tom Tromey <tromey@cygnus.com>.
77 #
88 # This program is free software; you can redistribute it and/or modify
5252 MINGW*)
5353 file_conv=mingw
5454 ;;
55 CYGWIN*)
55 CYGWIN* | MSYS*)
5656 file_conv=cygwin
5757 ;;
5858 *)
6666 mingw/*)
6767 file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
6868 ;;
69 cygwin/*)
69 cygwin/* | msys/*)
7070 file=`cygpath -m "$file" || echo "$file"`
7171 ;;
7272 wine/*)
00 #! /bin/sh
11 # Guess values for system-dependent variables and create Makefiles.
2 # Generated by GNU Autoconf 2.69 for xrdp 0.9.12.
2 # Generated by GNU Autoconf 2.69 for xrdp 0.9.15.
33 #
44 # Report bugs to <xrdp-devel@googlegroups.com>.
55 #
589589 # Identity of this package.
590590 PACKAGE_NAME='xrdp'
591591 PACKAGE_TARNAME='xrdp'
592 PACKAGE_VERSION='0.9.12'
593 PACKAGE_STRING='xrdp 0.9.12'
592 PACKAGE_VERSION='0.9.15'
593 PACKAGE_STRING='xrdp 0.9.15'
594594 PACKAGE_BUGREPORT='xrdp-devel@googlegroups.com'
595595 PACKAGE_URL=''
596596
14261426 # Omit some internal or obsolete options to make the list less imposing.
14271427 # This message is too long to be a string in the A/UX 3.1 sh.
14281428 cat <<_ACEOF
1429 \`configure' configures xrdp 0.9.12 to adapt to many kinds of systems.
1429 \`configure' configures xrdp 0.9.15 to adapt to many kinds of systems.
14301430
14311431 Usage: $0 [OPTION]... [VAR=VALUE]...
14321432
15001500
15011501 if test -n "$ac_init_help"; then
15021502 case $ac_init_help in
1503 short | recursive ) echo "Configuration of xrdp 0.9.12:";;
1503 short | recursive ) echo "Configuration of xrdp 0.9.15:";;
15041504 esac
15051505 cat <<\_ACEOF
15061506
15191519 --enable-fast-install[=PKGS]
15201520 optimize for fast installation [default=yes]
15211521 --disable-libtool-lock avoid locking (might break parallel builds)
1522 --disable-pam Build PAM support (default: yes)
1522 --enable-pam Build PAM support (default: yes)
15231523 --enable-vsock Build AF_VSOCK support (default: no)
15241524 --enable-ipv6 Build IPv6 support (default: no, experimental)
15251525 --enable-ipv6only Build IPv6-only (default: no)
1526 --enable-kerberos Build kerberos support (default: no)
1526 --enable-kerberos Build kerberos support (prefer --enable-pam if
1527 available) (default: no)
15271528 --enable-bsd Build BSD auth support (default: no)
1528 --enable-pamuserpass Build pam userpass support (default: no)
1529 --enable-pamuserpass Build PAM userpass support (default: no)
15291530 --enable-pam-config=CONF
15301531 Select PAM config to install: arch, debian, redhat,
15311532 suse, freebsd, macos, unix (default: autodetect)
16661667 test -n "$ac_init_help" && exit $ac_status
16671668 if $ac_init_version; then
16681669 cat <<\_ACEOF
1669 xrdp configure 0.9.12
1670 xrdp configure 0.9.15
16701671 generated by GNU Autoconf 2.69
16711672
16721673 Copyright (C) 2012 Free Software Foundation, Inc.
20352036 This file contains any messages produced by compilers while
20362037 running configure, to aid debugging if configure makes a mistake.
20372038
2038 It was created by xrdp $as_me 0.9.12, which was
2039 It was created by xrdp $as_me 0.9.15, which was
20392040 generated by GNU Autoconf 2.69. Invocation command line was
20402041
20412042 $ $0 $@
25902591 am_aux_dir=`cd "$ac_aux_dir" && pwd`
25912592
25922593 if test x"${MISSING+set}" != xset; then
2593 case $am_aux_dir in
2594 *\ * | *\ *)
2595 MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
2596 *)
2597 MISSING="\${SHELL} $am_aux_dir/missing" ;;
2598 esac
2594 MISSING="\${SHELL} '$am_aux_dir/missing'"
25992595 fi
26002596 # Use eval to expand $SHELL
26012597 if eval "$MISSING --is-lightweight"; then
29002896
29012897 # Define the identity of the package.
29022898 PACKAGE='xrdp'
2903 VERSION='0.9.12'
2899 VERSION='0.9.15'
29042900
29052901
29062902 cat >>confdefs.h <<_ACEOF
1235412350 AM_BACKSLASH='\'
1235512351
1235612352
12357 ac_ext=c
12358 ac_cpp='$CPP $CPPFLAGS'
12359 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
12360 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
12361 ac_compiler_gnu=$ac_cv_c_compiler_gnu
12362
12363 { $as_echo "$as_me:${as_lineno-$LINENO}: checking CFLAGS for maximum warnings" >&5
12364 $as_echo_n "checking CFLAGS for maximum warnings... " >&6; }
12365 if ${ac_cv_cflags_warn_all+:} false; then :
12366 $as_echo_n "(cached) " >&6
12367 else
12368 ac_cv_cflags_warn_all="no, unknown"
12369 ac_save_CFLAGS="$CFLAGS"
12370 for ac_arg in "-warn all % -warn all" "-pedantic % -Wall" "-xstrconst % -v" "-std1 % -verbose -w0 -warnprotos" "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" "-ansi -ansiE % -fullwarn" "+ESlit % +w1" "-Xc % -pvctl,fullmsg" "-h conform % -h msglevel 2" #
12371 do CFLAGS="$ac_save_CFLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
12372 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
12373 /* end confdefs.h. */
12374
12375 int
12376 main ()
12377 {
12378
12379 ;
12380 return 0;
12381 }
12382 _ACEOF
12383 if ac_fn_c_try_compile "$LINENO"; then :
12384 ac_cv_cflags_warn_all=`echo $ac_arg | sed -e 's,.*% *,,'` ; break
12385 fi
12386 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
12387 done
12388 CFLAGS="$ac_save_CFLAGS"
12389
12390 fi
12391 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cflags_warn_all" >&5
12392 $as_echo "$ac_cv_cflags_warn_all" >&6; }
12393
12394
12395 case ".$ac_cv_cflags_warn_all" in
12396 .ok|.ok,*) ;;
12397 .|.no|.no,*) ;;
12398 *)
12399 if ${CFLAGS+:} false; then :
12400
12401 case " $CFLAGS " in #(
12402 *" $ac_cv_cflags_warn_all "*) :
12403 { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$ac_cv_cflags_warn_all"; } >&5
12404 (: CFLAGS already contains $ac_cv_cflags_warn_all) 2>&5
12405 ac_status=$?
12406 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
12407 test $ac_status = 0; } ;; #(
12408 *) :
12409
12410 as_fn_append CFLAGS " $ac_cv_cflags_warn_all"
12411 { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5
12412 (: CFLAGS="$CFLAGS") 2>&5
12413 ac_status=$?
12414 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
12415 test $ac_status = 0; }
12416 ;;
12417 esac
12418
12419 else
12420
12421 CFLAGS=$ac_cv_cflags_warn_all
12422 { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5
12423 (: CFLAGS="$CFLAGS") 2>&5
12424 ac_status=$?
12425 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
12426 test $ac_status = 0; }
12427
12428 fi
12429 ;;
12430 esac
12431
12432 ac_ext=c
12433 ac_cpp='$CPP $CPPFLAGS'
12434 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
12435 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
12436 ac_compiler_gnu=$ac_cv_c_compiler_gnu
12437
12438
12439
12440
12441
12442
12443 for flag in -Wwrite-strings; do
12444 as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
12445 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
12446 $as_echo_n "checking whether C compiler accepts $flag... " >&6; }
12447 if eval \${$as_CACHEVAR+:} false; then :
12448 $as_echo_n "(cached) " >&6
12449 else
12450
12451 ax_check_save_flags=$CFLAGS
12452 CFLAGS="$CFLAGS $flag"
12453 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
12454 /* end confdefs.h. */
12455
12456 int
12457 main ()
12458 {
12459
12460 ;
12461 return 0;
12462 }
12463 _ACEOF
12464 if ac_fn_c_try_compile "$LINENO"; then :
12465 eval "$as_CACHEVAR=yes"
12466 else
12467 eval "$as_CACHEVAR=no"
12468 fi
12469 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
12470 CFLAGS=$ax_check_save_flags
12471 fi
12472 eval ac_res=\$$as_CACHEVAR
12473 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
12474 $as_echo "$ac_res" >&6; }
12475 if eval test \"x\$"$as_CACHEVAR"\" = x"yes"; then :
12476
12477 if ${CFLAGS+:} false; then :
12478
12479 case " $CFLAGS " in #(
12480 *" $flag "*) :
12481 { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
12482 (: CFLAGS already contains $flag) 2>&5
12483 ac_status=$?
12484 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
12485 test $ac_status = 0; } ;; #(
12486 *) :
12487
12488 as_fn_append CFLAGS " $flag"
12489 { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5
12490 (: CFLAGS="$CFLAGS") 2>&5
12491 ac_status=$?
12492 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
12493 test $ac_status = 0; }
12494 ;;
12495 esac
12496
12497 else
12498
12499 CFLAGS=$flag
12500 { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5
12501 (: CFLAGS="$CFLAGS") 2>&5
12502 ac_status=$?
12503 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
12504 test $ac_status = 0; }
12505
12506 fi
12507
12508 else
12509 :
12510 fi
12511
12512 done
12513
12514
12515
12516
12517 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __attribute__((format))" >&5
12518 $as_echo_n "checking for __attribute__((format))... " >&6; }
12519 if ${ax_cv_have_func_attribute_format+:} false; then :
12520 $as_echo_n "(cached) " >&6
12521 else
12522
12523 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
12524 /* end confdefs.h. */
12525
12526
12527 int foo(const char *p, ...) __attribute__((format(printf, 1, 2)));
12528
12529 int
12530 main ()
12531 {
12532
12533 ;
12534 return 0;
12535 }
12536
12537 _ACEOF
12538 if ac_fn_c_try_link "$LINENO"; then :
12539 if test -s conftest.err; then :
12540 ax_cv_have_func_attribute_format=no
12541 else
12542 ax_cv_have_func_attribute_format=yes
12543 fi
12544 else
12545 ax_cv_have_func_attribute_format=no
12546 fi
12547 rm -f core conftest.err conftest.$ac_objext \
12548 conftest$ac_exeext conftest.$ac_ext
12549
12550 fi
12551 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_have_func_attribute_format" >&5
12552 $as_echo "$ax_cv_have_func_attribute_format" >&6; }
12553
12554 if test yes = $ax_cv_have_func_attribute_format; then :
12555
12556 cat >>confdefs.h <<_ACEOF
12557 #define HAVE_FUNC_ATTRIBUTE_FORMAT 1
12558 _ACEOF
12559
12560 fi
12561
12562
12563
12564 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t" >&5
12565 $as_echo_n "checking for socklen_t... " >&6; }
12566 if ${ac_cv_ax_type_socklen_t+:} false; then :
12567 $as_echo_n "(cached) " >&6
12568 else
12569
12570 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
12571 /* end confdefs.h. */
12572 #include <sys/types.h>
12573 #include <sys/socket.h>
12574 int
12575 main ()
12576 {
12577 socklen_t len = (socklen_t) 42; return (!len);
12578 ;
12579 return 0;
12580 }
12581 _ACEOF
12582 if ac_fn_c_try_compile "$LINENO"; then :
12583 ac_cv_ax_type_socklen_t=yes
12584 else
12585 ac_cv_ax_type_socklen_t=no
12586 fi
12587 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
12588
12589 fi
12590 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_ax_type_socklen_t" >&5
12591 $as_echo "$ac_cv_ax_type_socklen_t" >&6; }
12592 if test $ac_cv_ax_type_socklen_t != yes; then
12593
12594 $as_echo "#define socklen_t int" >>confdefs.h
12595
12596 fi
12597
12598
1259912353 case $host_os in
1260012354 *linux*)
1260112355 linux=yes
1298112735 fi
1298212736
1298312737
12738 # configure compiler options and CFLAGS
12739
12740
12741
12742 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __attribute__((format))" >&5
12743 $as_echo_n "checking for __attribute__((format))... " >&6; }
12744 if ${ax_cv_have_func_attribute_format+:} false; then :
12745 $as_echo_n "(cached) " >&6
12746 else
12747
12748 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
12749 /* end confdefs.h. */
12750
12751
12752 int foo(const char *p, ...) __attribute__((format(printf, 1, 2)));
12753
12754 int
12755 main ()
12756 {
12757
12758 ;
12759 return 0;
12760 }
12761
12762 _ACEOF
12763 if ac_fn_c_try_link "$LINENO"; then :
12764 if test -s conftest.err; then :
12765 ax_cv_have_func_attribute_format=no
12766 else
12767 ax_cv_have_func_attribute_format=yes
12768 fi
12769 else
12770 ax_cv_have_func_attribute_format=no
12771 fi
12772 rm -f core conftest.err conftest.$ac_objext \
12773 conftest$ac_exeext conftest.$ac_ext
12774
12775 fi
12776 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_have_func_attribute_format" >&5
12777 $as_echo "$ax_cv_have_func_attribute_format" >&6; }
12778
12779 if test yes = $ax_cv_have_func_attribute_format; then :
12780
12781 cat >>confdefs.h <<_ACEOF
12782 #define HAVE_FUNC_ATTRIBUTE_FORMAT 1
12783 _ACEOF
12784
12785 fi
12786
12787
12788
12789 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t" >&5
12790 $as_echo_n "checking for socklen_t... " >&6; }
12791 if ${ac_cv_ax_type_socklen_t+:} false; then :
12792 $as_echo_n "(cached) " >&6
12793 else
12794
12795 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
12796 /* end confdefs.h. */
12797 #include <sys/types.h>
12798 #include <sys/socket.h>
12799 int
12800 main ()
12801 {
12802 socklen_t len = (socklen_t) 42; return (!len);
12803 ;
12804 return 0;
12805 }
12806 _ACEOF
12807 if ac_fn_c_try_compile "$LINENO"; then :
12808 ac_cv_ax_type_socklen_t=yes
12809 else
12810 ac_cv_ax_type_socklen_t=no
12811 fi
12812 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
12813
12814 fi
12815 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_ax_type_socklen_t" >&5
12816 $as_echo "$ac_cv_ax_type_socklen_t" >&6; }
12817 if test $ac_cv_ax_type_socklen_t != yes; then
12818
12819 $as_echo "#define socklen_t int" >>confdefs.h
12820
12821 fi
12822
12823 ac_ext=c
12824 ac_cpp='$CPP $CPPFLAGS'
12825 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
12826 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
12827 ac_compiler_gnu=$ac_cv_c_compiler_gnu
12828
12829 { $as_echo "$as_me:${as_lineno-$LINENO}: checking CFLAGS for maximum warnings" >&5
12830 $as_echo_n "checking CFLAGS for maximum warnings... " >&6; }
12831 if ${ac_cv_cflags_warn_all+:} false; then :
12832 $as_echo_n "(cached) " >&6
12833 else
12834 ac_cv_cflags_warn_all="no, unknown"
12835 ac_save_CFLAGS="$CFLAGS"
12836 for ac_arg in "-warn all % -warn all" "-pedantic % -Wall" "-xstrconst % -v" "-std1 % -verbose -w0 -warnprotos" "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" "-ansi -ansiE % -fullwarn" "+ESlit % +w1" "-Xc % -pvctl,fullmsg" "-h conform % -h msglevel 2" #
12837 do CFLAGS="$ac_save_CFLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
12838 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
12839 /* end confdefs.h. */
12840
12841 int
12842 main ()
12843 {
12844
12845 ;
12846 return 0;
12847 }
12848 _ACEOF
12849 if ac_fn_c_try_compile "$LINENO"; then :
12850 ac_cv_cflags_warn_all=`echo $ac_arg | sed -e 's,.*% *,,'` ; break
12851 fi
12852 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
12853 done
12854 CFLAGS="$ac_save_CFLAGS"
12855
12856 fi
12857 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cflags_warn_all" >&5
12858 $as_echo "$ac_cv_cflags_warn_all" >&6; }
12859
12860
12861 case ".$ac_cv_cflags_warn_all" in
12862 .ok|.ok,*) ;;
12863 .|.no|.no,*) ;;
12864 *)
12865 if ${CFLAGS+:} false; then :
12866
12867 case " $CFLAGS " in #(
12868 *" $ac_cv_cflags_warn_all "*) :
12869 { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$ac_cv_cflags_warn_all"; } >&5
12870 (: CFLAGS already contains $ac_cv_cflags_warn_all) 2>&5
12871 ac_status=$?
12872 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
12873 test $ac_status = 0; } ;; #(
12874 *) :
12875
12876 as_fn_append CFLAGS " $ac_cv_cflags_warn_all"
12877 { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5
12878 (: CFLAGS="$CFLAGS") 2>&5
12879 ac_status=$?
12880 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
12881 test $ac_status = 0; }
12882 ;;
12883 esac
12884
12885 else
12886
12887 CFLAGS=$ac_cv_cflags_warn_all
12888 { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5
12889 (: CFLAGS="$CFLAGS") 2>&5
12890 ac_status=$?
12891 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
12892 test $ac_status = 0; }
12893
12894 fi
12895 ;;
12896 esac
12897
12898 ac_ext=c
12899 ac_cpp='$CPP $CPPFLAGS'
12900 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
12901 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
12902 ac_compiler_gnu=$ac_cv_c_compiler_gnu
12903
12904
12905
12906
12907
12908
12909 for flag in -Wwrite-strings; do
12910 as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
12911 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
12912 $as_echo_n "checking whether C compiler accepts $flag... " >&6; }
12913 if eval \${$as_CACHEVAR+:} false; then :
12914 $as_echo_n "(cached) " >&6
12915 else
12916
12917 ax_check_save_flags=$CFLAGS
12918 CFLAGS="$CFLAGS $flag"
12919 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
12920 /* end confdefs.h. */
12921
12922 int
12923 main ()
12924 {
12925
12926 ;
12927 return 0;
12928 }
12929 _ACEOF
12930 if ac_fn_c_try_compile "$LINENO"; then :
12931 eval "$as_CACHEVAR=yes"
12932 else
12933 eval "$as_CACHEVAR=no"
12934 fi
12935 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
12936 CFLAGS=$ax_check_save_flags
12937 fi
12938 eval ac_res=\$$as_CACHEVAR
12939 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
12940 $as_echo "$ac_res" >&6; }
12941 if eval test \"x\$"$as_CACHEVAR"\" = x"yes"; then :
12942
12943 if ${CFLAGS+:} false; then :
12944
12945 case " $CFLAGS " in #(
12946 *" $flag "*) :
12947 { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
12948 (: CFLAGS already contains $flag) 2>&5
12949 ac_status=$?
12950 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
12951 test $ac_status = 0; } ;; #(
12952 *) :
12953
12954 as_fn_append CFLAGS " $flag"
12955 { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5
12956 (: CFLAGS="$CFLAGS") 2>&5
12957 ac_status=$?
12958 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
12959 test $ac_status = 0; }
12960 ;;
12961 esac
12962
12963 else
12964
12965 CFLAGS=$flag
12966 { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5
12967 (: CFLAGS="$CFLAGS") 2>&5
12968 ac_status=$?
12969 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
12970 test $ac_status = 0; }
12971
12972 fi
12973
12974 else
12975 :
12976 fi
12977
12978 done
12979
12980
12981 if test -z "$LINUX_TRUE"; then :
12982
12983
12984
12985
12986 for flag in -Werror; do
12987 as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
12988 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
12989 $as_echo_n "checking whether C compiler accepts $flag... " >&6; }
12990 if eval \${$as_CACHEVAR+:} false; then :
12991 $as_echo_n "(cached) " >&6
12992 else
12993
12994 ax_check_save_flags=$CFLAGS
12995 CFLAGS="$CFLAGS $flag"
12996 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
12997 /* end confdefs.h. */
12998
12999 int
13000 main ()
13001 {
13002
13003 ;
13004 return 0;
13005 }
13006 _ACEOF
13007 if ac_fn_c_try_compile "$LINENO"; then :
13008 eval "$as_CACHEVAR=yes"
13009 else
13010 eval "$as_CACHEVAR=no"
13011 fi
13012 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
13013 CFLAGS=$ax_check_save_flags
13014 fi
13015 eval ac_res=\$$as_CACHEVAR
13016 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
13017 $as_echo "$ac_res" >&6; }
13018 if eval test \"x\$"$as_CACHEVAR"\" = x"yes"; then :
13019
13020 if ${CFLAGS+:} false; then :
13021
13022 case " $CFLAGS " in #(
13023 *" $flag "*) :
13024 { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
13025 (: CFLAGS already contains $flag) 2>&5
13026 ac_status=$?
13027 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
13028 test $ac_status = 0; } ;; #(
13029 *) :
13030
13031 as_fn_append CFLAGS " $flag"
13032 { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5
13033 (: CFLAGS="$CFLAGS") 2>&5
13034 ac_status=$?
13035 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
13036 test $ac_status = 0; }
13037 ;;
13038 esac
13039
13040 else
13041
13042 CFLAGS=$flag
13043 { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5
13044 (: CFLAGS="$CFLAGS") 2>&5
13045 ac_status=$?
13046 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
13047 test $ac_status = 0; }
13048
13049 fi
13050
13051 else
13052 :
13053 fi
13054
13055 done
13056
13057 fi # bsd has warnings that have not been fixed yet
13058
13059 if test -z "$XRDP_DEBUG_TRUE"; then :
13060
13061
13062
13063
13064 for flag in -g -O0; do
13065 as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
13066 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
13067 $as_echo_n "checking whether C compiler accepts $flag... " >&6; }
13068 if eval \${$as_CACHEVAR+:} false; then :
13069 $as_echo_n "(cached) " >&6
13070 else
13071
13072 ax_check_save_flags=$CFLAGS
13073 CFLAGS="$CFLAGS $flag"
13074 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
13075 /* end confdefs.h. */
13076
13077 int
13078 main ()
13079 {
13080
13081 ;
13082 return 0;
13083 }
13084 _ACEOF
13085 if ac_fn_c_try_compile "$LINENO"; then :
13086 eval "$as_CACHEVAR=yes"
13087 else
13088 eval "$as_CACHEVAR=no"
13089 fi
13090 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
13091 CFLAGS=$ax_check_save_flags
13092 fi
13093 eval ac_res=\$$as_CACHEVAR
13094 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
13095 $as_echo "$ac_res" >&6; }
13096 if eval test \"x\$"$as_CACHEVAR"\" = x"yes"; then :
13097
13098 if ${CFLAGS+:} false; then :
13099
13100 case " $CFLAGS " in #(
13101 *" $flag "*) :
13102 { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
13103 (: CFLAGS already contains $flag) 2>&5
13104 ac_status=$?
13105 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
13106 test $ac_status = 0; } ;; #(
13107 *) :
13108
13109 as_fn_append CFLAGS " $flag"
13110 { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5
13111 (: CFLAGS="$CFLAGS") 2>&5
13112 ac_status=$?
13113 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
13114 test $ac_status = 0; }
13115 ;;
13116 esac
13117
13118 else
13119
13120 CFLAGS=$flag
13121 { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5
13122 (: CFLAGS="$CFLAGS") 2>&5
13123 ac_status=$?
13124 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
13125 test $ac_status = 0; }
13126
13127 fi
13128
13129 else
13130 :
13131 fi
13132
13133 done
13134
13135 else
13136
13137
13138
13139
13140 for flag in -O2; do
13141 as_CACHEVAR=`$as_echo "ax_cv_check_cflags__$flag" | $as_tr_sh`
13142 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts $flag" >&5
13143 $as_echo_n "checking whether C compiler accepts $flag... " >&6; }
13144 if eval \${$as_CACHEVAR+:} false; then :
13145 $as_echo_n "(cached) " >&6
13146 else
13147
13148 ax_check_save_flags=$CFLAGS
13149 CFLAGS="$CFLAGS $flag"
13150 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
13151 /* end confdefs.h. */
13152
13153 int
13154 main ()
13155 {
13156
13157 ;
13158 return 0;
13159 }
13160 _ACEOF
13161 if ac_fn_c_try_compile "$LINENO"; then :
13162 eval "$as_CACHEVAR=yes"
13163 else
13164 eval "$as_CACHEVAR=no"
13165 fi
13166 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
13167 CFLAGS=$ax_check_save_flags
13168 fi
13169 eval ac_res=\$$as_CACHEVAR
13170 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
13171 $as_echo "$ac_res" >&6; }
13172 if eval test \"x\$"$as_CACHEVAR"\" = x"yes"; then :
13173
13174 if ${CFLAGS+:} false; then :
13175
13176 case " $CFLAGS " in #(
13177 *" $flag "*) :
13178 { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains \$flag"; } >&5
13179 (: CFLAGS already contains $flag) 2>&5
13180 ac_status=$?
13181 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
13182 test $ac_status = 0; } ;; #(
13183 *) :
13184
13185 as_fn_append CFLAGS " $flag"
13186 { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5
13187 (: CFLAGS="$CFLAGS") 2>&5
13188 ac_status=$?
13189 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
13190 test $ac_status = 0; }
13191 ;;
13192 esac
13193
13194 else
13195
13196 CFLAGS=$flag
13197 { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS\""; } >&5
13198 (: CFLAGS="$CFLAGS") 2>&5
13199 ac_status=$?
13200 $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
13201 test $ac_status = 0; }
13202
13203 fi
13204
13205 else
13206 :
13207 fi
13208
13209 done
13210
13211 fi
13212
1298413213 # Don't fail without working nasm if rfxcodec is not enabled
1298513214 if test "x$enable_rfxcodec" != xyes; then
1298613215 with_simd=no
1316013389 test -n "$OPENSSL" || OPENSSL=":"
1316113390
1316213391
13163 # checking for pam variation
13392 # checking for PAM variation
1316413393 # Linux-PAM is used in Linux systems
1316513394 # OpenPAM is used by FreeBSD, NetBSD, DragonFly BSD and OS X
1316613395 # OpenBSD uses BSD Authentication rather than both PAMs
1318113410
1318213411
1318313412
13413 # Check only one auth mechanism is specified, and give it a name
13414 auth_cnt=0
13415 auth_mech="Builtin"
13416 if test x$enable_pam = xyes
13417 then
13418 auth_cnt=`expr $auth_cnt + 1`
13419 auth_mech="PAM"
13420 fi
13421 if test x$bsd = xtrue
13422 then
13423 auth_cnt=`expr $auth_cnt + 1`
13424 auth_mech="BSD"
13425 fi
13426 if test x$enable_kerberos = xyes
13427 then
13428 auth_cnt=`expr $auth_cnt + 1`
13429 auth_mech="Kerberos"
13430 fi
13431 if test x$enable_pamuserpass = xyes
13432 then
13433 auth_cnt=`expr $auth_cnt + 1`
13434 auth_mech="PAM userpass"
13435 fi
13436
13437 if test $auth_cnt -gt 1
13438 then
13439 as_fn_error $? "--enable-pam, --enable-bsd, --enable-pamuserpass and --enable-kerberos are mutually exclusive" "$LINENO" 5
13440 fi
13441
1318413442 # checking if pam should be autodetected.
1318513443 if test "x$enable_pam" = "xyes"
1318613444 then
13187 if test "x$enable_kerberos" != "xyes"
13445 if test -z "$enable_bsd"
1318813446 then
13189 if test -z "$enable_bsd"
13190 then
13191 ac_fn_c_check_header_mongrel "$LINENO" "security/pam_appl.h" "ac_cv_header_security_pam_appl_h" "$ac_includes_default"
13447 ac_fn_c_check_header_mongrel "$LINENO" "security/pam_appl.h" "ac_cv_header_security_pam_appl_h" "$ac_includes_default"
1319213448 if test "x$ac_cv_header_security_pam_appl_h" = xyes; then :
1319313449
1319413450 else
1319613452 fi
1319713453
1319813454
13199 fi
1320013455 fi
1320113456 if test "x$enable_pam_config" = "x"; then
1320213457 PAM_RULES="auto"
1324813503
1324913504 fi
1325013505
13251 if test "x$enable_pam" != "xyes" || test "x$bsd" = "xtrue"
13506 if test "x$enable_pam" != "xyes"
1325213507 then
1325313508
1325413509 $as_echo "#define USE_NOPAM 1" >>confdefs.h
1336013615 fi
1336113616
1336213617
13363 fi
13364
13365 if test "x$enable_xrdpdebug" = "xyes"
13366 then
13367 CFLAGS="-g -O0"
1336813618 fi
1336913619
1337013620 # checking for fuse
1507415324 # report actual input values of CONFIG_FILES etc. instead of their
1507515325 # values after options handling.
1507615326 ac_log="
15077 This file was extended by xrdp $as_me 0.9.12, which was
15327 This file was extended by xrdp $as_me 0.9.15, which was
1507815328 generated by GNU Autoconf 2.69. Invocation command line was
1507915329
1508015330 CONFIG_FILES = $CONFIG_FILES
1514015390 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
1514115391 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
1514215392 ac_cs_version="\\
15143 xrdp config.status 0.9.12
15393 xrdp config.status 0.9.15
1514415394 configured by $0, generated by GNU Autoconf 2.69,
1514515395 with options \\"\$ac_cs_config\\"
1514615396
1625916509 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
1626016510 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
1626116511 as_fn_error $? "Something went wrong bootstrapping makefile fragments
16262 for automatic dependency tracking. Try re-running configure with the
16512 for automatic dependency tracking. If GNU make was not used, consider
16513 re-running the configure script with MAKE=\"gmake\" (or whatever is
16514 necessary). You can also try re-running configure with the
1626316515 '--disable-dependency-tracking' option to at least be able to build
1626416516 the package (albeit without support for automatic dependency tracking).
1626516517 See \`config.log' for more details" "$LINENO" 5; }
1701317265 echo " ipv6 $enable_ipv6"
1701417266 echo " ipv6only $enable_ipv6only"
1701517267 echo " vsock $enable_vsock"
17016 echo " pam $enable_pam"
17017 echo " kerberos $enable_kerberos"
17268 echo " auth mechanism $auth_mech"
1701817269 echo " debug $enable_xrdpdebug"
1701917270 echo " rdpsndaudin $enable_rdpsndaudin"
1702017271 echo ""
1702417275 echo " libdir $libdir"
1702517276 echo " bindir $bindir"
1702617277 echo " sysconfdir $sysconfdir"
17278 echo ""
17279 echo " CFLAGS = $CFLAGS"
17280 echo " LDFLAGS = $LDFLAGS"
1702717281
1702817282 # xrdp_configure_options.h will be written to the build directory, not the source directory
1702917283 echo '#define XRDP_CONFIGURE_OPTIONS \' > ./xrdp_configure_options.h
00 # Process this file with autoconf to produce a configure script
11
22 AC_PREREQ(2.65)
3 AC_INIT([xrdp], [0.9.12], [xrdp-devel@googlegroups.com])
3 AC_INIT([xrdp], [0.9.15], [xrdp-devel@googlegroups.com])
44 AC_CONFIG_HEADERS(config_ac.h:config_ac-h.in)
55 AM_INIT_AUTOMAKE([1.7.2 foreign])
66 AC_CONFIG_MACRO_DIR([m4])
1818 # Use silent rules by default if supported by Automake
1919 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
2020
21 AX_CFLAGS_WARN_ALL
22 AX_APPEND_COMPILE_FLAGS([-Wwrite-strings])
23 AX_GCC_FUNC_ATTRIBUTE([format])
24 AX_TYPE_SOCKLEN_T
25
2621 case $host_os in
2722 *linux*)
2823 linux=yes
6964 fi
7065 AM_CONDITIONAL(HAVE_SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ])
7166
72 AC_ARG_ENABLE(pam, AS_HELP_STRING([--disable-pam],
67 AC_ARG_ENABLE(pam, AS_HELP_STRING([--enable-pam],
7368 [Build PAM support (default: yes)]),
7469 [], [enable_pam=yes])
7570 AM_CONDITIONAL(SESMAN_NOPAM, [test x$enable_pam != xyes])
8378 [Build IPv6-only (default: no)]),
8479 [], [enable_ipv6only=no])
8580 AC_ARG_ENABLE(kerberos, AS_HELP_STRING([--enable-kerberos],
86 [Build kerberos support (default: no)]),
81 [Build kerberos support (prefer --enable-pam if available) (default: no)]),
8782 [], [enable_kerberos=no])
8883 AC_ARG_ENABLE(bsd, AS_HELP_STRING([--enable-bsd],
8984 [Build BSD auth support (default: no)]),
9186 AM_CONDITIONAL(SESMAN_BSD, [test x$bsd = xtrue])
9287 AM_CONDITIONAL(SESMAN_KERBEROS, [test x$enable_kerberos = xyes])
9388 AC_ARG_ENABLE(pamuserpass, AS_HELP_STRING([--enable-pamuserpass],
94 [Build pam userpass support (default: no)]),
89 [Build PAM userpass support (default: no)]),
9590 [], [enable_pamuserpass=no])
9691 AM_CONDITIONAL(SESMAN_PAMUSERPASS, [test x$enable_pamuserpass = xyes])
9792 AC_ARG_ENABLE(pam-config, AS_HELP_STRING([--enable-pam-config=CONF],
154149 [], [enable_rdpsndaudin=no])
155150 AM_CONDITIONAL(XRDP_RDPSNDAUDIN, [test x$enable_rdpsndaudin = xyes])
156151
152 # configure compiler options and CFLAGS
153 AX_GCC_FUNC_ATTRIBUTE([format])
154 AX_TYPE_SOCKLEN_T
155 AX_CFLAGS_WARN_ALL
156 AX_APPEND_COMPILE_FLAGS([-Wwrite-strings])
157
158 AM_COND_IF([LINUX],
159 [AX_APPEND_COMPILE_FLAGS([-Werror])]) # bsd has warnings that have not been fixed yet
160
161 AM_COND_IF([XRDP_DEBUG],
162 [AX_APPEND_COMPILE_FLAGS([-g -O0])],
163 [AX_APPEND_COMPILE_FLAGS([-O2])])
164
157165 # Don't fail without working nasm if rfxcodec is not enabled
158166 if test "x$enable_rfxcodec" != xyes; then
159167 with_simd=no
174182 OPENSSL_BIN=`$PKG_CONFIG --variable=exec_prefix openssl`/bin
175183 AC_PATH_PROGS([OPENSSL], [openssl], [:], [$OPENSSL_BIN:$PATH])
176184
177 # checking for pam variation
185 # checking for PAM variation
178186 # Linux-PAM is used in Linux systems
179187 # OpenPAM is used by FreeBSD, NetBSD, DragonFly BSD and OS X
180188 # OpenBSD uses BSD Authentication rather than both PAMs
183191 AC_CHECK_HEADER([security/pam_constants.h],
184192 [AC_DEFINE([HAVE_PAM_CONSTANTS_H], 1, [Using OpenPAM], [])])
185193
194 # Check only one auth mechanism is specified, and give it a name
195 auth_cnt=0
196 auth_mech="Builtin"
197 if test x$enable_pam = xyes
198 then
199 auth_cnt=`expr $auth_cnt + 1`
200 auth_mech="PAM"
201 fi
202 if test x$bsd = xtrue
203 then
204 auth_cnt=`expr $auth_cnt + 1`
205 auth_mech="BSD"
206 fi
207 if test x$enable_kerberos = xyes
208 then
209 auth_cnt=`expr $auth_cnt + 1`
210 auth_mech="Kerberos"
211 fi
212 if test x$enable_pamuserpass = xyes
213 then
214 auth_cnt=`expr $auth_cnt + 1`
215 auth_mech="PAM userpass"
216 fi
217
218 if test $auth_cnt -gt 1
219 then
220 AC_MSG_ERROR([--enable-pam, --enable-bsd, --enable-pamuserpass and --enable-kerberos are mutually exclusive])
221 fi
222
186223 # checking if pam should be autodetected.
187224 if test "x$enable_pam" = "xyes"
188225 then
189 if test "x$enable_kerberos" != "xyes"
226 if test -z "$enable_bsd"
190227 then
191 if test -z "$enable_bsd"
192 then
193 AC_CHECK_HEADER([security/pam_appl.h], [],
194 [AC_MSG_ERROR([please install libpam0g-dev or pam-devel])])
195 fi
228 AC_CHECK_HEADER([security/pam_appl.h], [],
229 [AC_MSG_ERROR([please install libpam0g-dev or pam-devel])])
196230 fi
197231 if test "x$enable_pam_config" = "x"; then
198232 PAM_RULES="auto"
228262 AC_DEFINE([XRDP_ENABLE_IPV6],1,[Enable IPv6])
229263 fi
230264
231 if test "x$enable_pam" != "xyes" || test "x$bsd" = "xtrue"
265 if test "x$enable_pam" != "xyes"
232266 then
233267 AC_DEFINE([USE_NOPAM],1,[Disable PAM])
234268 fi
240274 then
241275 AC_CHECK_HEADER([jpeglib.h], [],
242276 [AC_MSG_ERROR([please install libjpeg-dev or libjpeg-devel])])
243 fi
244
245 if test "x$enable_xrdpdebug" = "xyes"
246 then
247 CFLAGS="-g -O0"
248277 fi
249278
250279 # checking for fuse
391420 echo " ipv6 $enable_ipv6"
392421 echo " ipv6only $enable_ipv6only"
393422 echo " vsock $enable_vsock"
394 echo " pam $enable_pam"
395 echo " kerberos $enable_kerberos"
423 echo " auth mechanism $auth_mech"
396424 echo " debug $enable_xrdpdebug"
397425 echo " rdpsndaudin $enable_rdpsndaudin"
398426 echo ""
402430 echo " libdir $libdir"
403431 echo " bindir $bindir"
404432 echo " sysconfdir $sysconfdir"
433 echo ""
434 echo " CFLAGS = $CFLAGS"
435 echo " LDFLAGS = $LDFLAGS"
405436
406437 # xrdp_configure_options.h will be written to the build directory, not the source directory
407438 echo '#define XRDP_CONFIGURE_OPTIONS \' > ./xrdp_configure_options.h
22
33 scriptversion=2018-03-07.03; # UTC
44
5 # Copyright (C) 1999-2018 Free Software Foundation, Inc.
5 # Copyright (C) 1999-2020 Free Software Foundation, Inc.
66
77 # This program is free software; you can redistribute it and/or modify
88 # it under the terms of the GNU General Public License as published by
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
3030 .TP
3131 \fB[Chansrv]\fR
3232 Settings for xrdp-chansrv(8)
33
34 .TP
35 \fB[ChansrvLogging]\fR
36 Logging settings for xrdp-chansrv(8)
3337
3438 .TP
3539 \fB[SessionVariables]\fR
8084 \fI@xrdpconfdir@/reconnectwm.sh\fR.
8185
8286 .SH "LOGGING"
83 Following parameters can be used in the \fB[Logging]\fR section.
87 Following parameters can be used in the \fB[Logging]\fR and \fB[ChansrvLogging]\fR
88 sections.
8489
8590 .TP
8691 \fBLogFile\fR=\fIfilename\fR
8792 Log file path. It can be either absolute or relative. If not specified,
88 defaults to \fI./sesman.log\fR
93 defaults to \fI./sesman.log\fR It is ignored in the [ChansrvLogging] section
94 since the channel server creates one log file per display and instead uses the
95 following log file naming convention \fIxrdp-chansrv.${DISPLAY}.log\fR
8996
9097 .TP
9198 \fBLogLevel\fR=\fIlevel\fR
111118 .TP
112119 \fBSyslogLevel\fR=\fIlevel\fR
113120 Logging level for syslog. It can have the same values as \fBLogLevel\fR.
114 If \fBSyslogLevel\fR and \fBLogLevel\fR differ, the least verbose setting
115 takes effect for syslog.
121 Defaults to \fBDEBUG\fR.
122
123 .TP
124 \fBEnableConsole\fR=\fI[true|false]\fR
125 If set to \fB1\fR, \fBtrue\fR or \fByes\fR, this option enables logging to
126 the console (ie. stdout).
127
128 .TP
129 \fBConsoleLevel\fR=\fIlevel\fR
130 Logging level for the console. It can have the same values as \fBLogLevel\fR.
131 Defaults to \fBDEBUG\fR.
132
133 .TP
134 \fBEnableProcessId\fR=\fI[true|false]\fR
135 If set to \fB1\fR, \fBtrue\fR or \fByes\fR, this option enables logging the
136 process id in all log messages. Defaults to \fBfalse\fR.
116137
117138 .SH "SESSIONS"
118139 Following parameters can be used in the \fB[Sessions]\fR section.
131152 .TP
132153 \fBKillDisconnected\fR=\fI[true|false]\fR
133154 If set to \fB1\fR, \fBtrue\fR or \fByes\fR, every session will be killed
134 within 60 seconds after the user disconnects.
155 within \fBDisconnectedTimeLimit\fR seconds after the user disconnects.
156 This setting currently only works with xorgxrdp sessions.
135157
136158 .TP
137159 \fBDisconnectedTimeLimit\fR=\fInumber\fR
138 Sets the time limit (in seconds) before a disconnected session is killed.
139 If set to \fI0\fR, automatic killing is disabled.
160 Sets the time limit for \fBKillDisconnected\fR to a value greater than 60.
161 Values less than 60 are to be overridden with 60.
162 This setting currently only works with xorgxrdp sessions.
140163
141164 .TP
142165 \fBIdleTimeLimit\fR=\fInumber\fR
143166 Sets the time limit (in seconds) before an idle session is disconnected.
144167 Idle means no keyboard inputs and no mouse moves/clicks here.
145168 If set to \fI0\fR, idle sessions will never be disconnected by timeout.
146 This works only with xorgxrdp session. Moreover, xorgxrdp must be v0.2.9 or later.
169 This works only with xorgxrdp sessions. Moreover, xorgxrdp must be v0.2.9 or later.
147170
148171 .TP
149172 \fBPolicy\fR=\fI[Default|UBD|UBI|UBC|UBDI|UBDC]\fR
150 Session allocation policy. By default, a new session is created
151 for the combination <User,BitPerPixel> when using Xrdp, and
152 for the combination <User,BitPerPixel,DisplaySize> when using Xvnc.
153 This behavior can be changed by setting session policy to:
154 .br
155
173 Session allocation policy. Used to decide when to allocate a
174 new session. Set to one of the following values:
175 .br
176
177 .br
178 \fBDefault\fR - session per <User,BitPerPixel>
156179 .br
157180 \fBUBD\fR - session per <User,BitPerPixel,DisplaySize>
158181 .br
167190
168191 .br
169192 Note that the \fBUser\fR and \fBBitPerPixel\fR criteria cannot be turned
170 off. For Xvnc connections, \fBDisplaySize\fR is always enabled as well.
193 off. \fBDisplaySize\fR refers to the initial geometry of a connection,
194 as actual display sizes can change dynamically.
171195 .br
172196
173197 .SH "SECURITY"
221245
222246 .TP
223247 \fBFuseMountName\fR=\fIstring\fR
224 Directory for drive redirection, relative to the user home directory.
248 Directory for drive redirection.
225249 Created if it doesn't exist. If not specified, defaults to \fIxrdp_client\fR.
250 If first character is not a '/', this is relative to $HOME.
251 .P
252 .RS
253 If first character is a '/' this is an absolute path. The following
254 substitutions are made in this string:-
255 %U - Username
256 %u - Numeric UID
257 %% - Percent character
258 .P
259 If this format is used:-
260 .HP 3
261 1) The directory path permissions MUST be configured correctly by
262 the system administrator or the system itself - xrdp-chansrv will not
263 do this for you (although it will create the final directories owned by
264 the user).
265 .HP 3
266 2) The desktop may not automatically display a link for the redirected
267 drive. To fix this, consult the docs for your chosen desktop.
268 .RE
226269
227270 .TP
228271 \fBFileUmask\fR=\fImode\fR
232275 environents, and so you can change this value to allow other users to
233276 access your remote files if required.
234277
278 .TP
279 \fBEnableFuseMount\fR=\fI[true|false]\fR
280 Defaults to \fItrue\fR.
281 Set to \fIfalse\fR to disable xrdp-chansrv's use of the FUSE system
282 feature, even if it has been built with this feature enabled.
283 .P
284 .RS
285 Setting this value to \fIfalse\fR will disable the following application
286 features:-
287 .P
288 - drive redirection
289 .P
290 - copying-and-pasting of files
291 .RE
292
235293 .SH "SESSIONS VARIABLES"
236294 All entries in the \fB[SessionVariables]\fR section are set as
237295 environment variables in the user's session.
66
77 .SH "DESCRIPTION"
88 \fBxrdp\-chansrv\fR is the \fBxrdp\fR(8) channel server, which manages the Remote Desktop Protocol (RDP) sub-channels.
9 .PP
910 This program is only forked internally by \fBxrdp\-sesman\fP(8).
10 .br
11 .PP
1112 Currently \fBxrdp\-chansrv\fP knows about the following channels:
12 .RE 8
13 .RS 8
1314 .TP
1415 .B cliprdr
1516 Clipboard Redirection
2526 .TP
2627 .B drdynvc
2728 Dynamic Virtual Channel
28 .RS
29 .RE
30
31 .SH ENVIRONMENT
32 .TP
33 .I CHANSRV_LOG_PATH
34 Path to the location where the log file is stored. If not specified,
35 $\fBXDG_DATA_HOME/xrdp\fP or \fB$HOME/.local/share/xrdp\fP is used instead.
36 .TP
37 .I DISPLAY
38 X11 display number. Must be specified.
2939
3040 .SH FILES
41 .TP
42 .I @sysconfdir@/xrdp/sesman.ini
43 Contains some settings for this program.
3144 .TP
3245 .I @socketdir@/xrdp_chansrv_socket_*
3346 UNIX socket used by external programs to implement channels.
3548 .I @socketdir@/xrdp_api_*
3649 UNIX socket used by \fBxrdp\-chansrv\fP to communicate with \fBxrdp\-sesman\fP.
3750 .TP
38 .I $XDG_DATA_HOME/xrdp/xrdp-chansrv.%s.log
39 Log file used by \fBxrdp\-chansrv\fP(8). \fB%s\fP is display number.
51 .I xrdp-chansrv.%s.log
52 Log file used by \fBxrdp\-chansrv\fP(8). \fB%s\fP is display number. See the
53 description of \fBCHANSRV_LOG_PATH\fP above for the file's location.
4054
4155 .SH "SEE ALSO"
4256 .BR xrdp\-sesman (8),
1616 .SH FILES
1717 .TP
1818 .I @socketdir@/xrdp_disconnect_display_*
19 UNIX socket used to communicate with the \fBxrdp\fP(8) session manager.
19 UNIX socket used to communicate the disconnect request to xorgxrdp.
2020
2121 .SH KNOWN ISSUES
2222 .TP
23 This utility doesn't support disconnecting xorgxrdp sessions so far.
23 This utility doesn't support disconnecting Xvnc sessions so far.
2424
2525 .SH SEE ALSO
2626 .BR xrdp (8).
33
44 .SH "SYNTAX"
55 .B xrdp\-sesman
6 .RB [ \-\-nodaemon | \-\-kill | \-\-help ]
6 \-\-kill
7 .br
8 .B xrdp\-sesman
9 \-\-help
10 .br
11 .B xrdp\-sesman
12 \-\-version
13 .br
14 .B xrdp\-sesman
15 [ \-\-nodaemon ] [ --config /path/to/sesman.ini ]
716
817 .SH "DESCRIPTION"
918 \fBxrdp\-sesman\fR is \fBxrdp\fR(8) session manager.
1221
1322 .SH "OPTIONS"
1423 .TP
15 \fB\-n\fR, \fB\-\-nodaemon\fR
16 Starts \fBxrdp\-sesman\fR in foreground instead of starting it as a daemon.
17 .TP
1824 \fB\-k\fR, \fB\-\-kill\fR
1925 Kills running \fBxrdp\-sesman\fR daemon.
2026 .TP
2127 \fB\-h\fR, \fB\-\-help\fR
2228 Output help information and exit.
23
29 .TP
30 \fB\-v\fR, \fB\-\-version\fR
31 Output version information and exit.
32 .TP
33 \fB\-n\fR, \fB\-\-nodaemon\fR
34 Starts \fBxrdp\-sesman\fR in foreground instead of starting it as a daemon.
35 .TP
36 \fB\-c\fR, \fB\-\-config\fR
37 Specify a path to a different \fIsesman.ini\fR file. This option is intended
38 to be used primarily for testing or for unusual configurations.
39 .P
40 .RS
41 If you use this option, be aware that you will have to have a
42 \fB@sysconfdir@/xrdp/sesman.ini\fR in place too, as a few elements of
43 the system (notably \fBxrdp(8)\fR and \fBxrdp\-chansrv(8)\fR) will want
44 to read it.
45 .RE
2446 .SH "FILES"
2547 @bindir@/xrdp\-sesman
2648 .br
00 .TH "xrdp\-sesrun" "8" "@PACKAGE_VERSION@" "xrdp team" ""
11 .SH "NAME"
2 xrdp\-sesrun \- \fBsesman\fR(8) session launcher
2 \fBxrdp\-sesrun\fR \- \fBxrdp\-sesman\fR(8) session launcher
33
44 .SH "SYNTAX"
55 .B xrdp\-sesrun
6 .I server username password width height bpp
6 .I [ options ] username
77
88 .SH "DESCRIPTION"
99 \fBxrdp\-sesrun\fR starts a session using \fBxrdp\-sesman\fR(8).
1010 .br
11 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.
11 This is a tool useful for testing, it simply behaves like xrdp when some
12 user logs in a new session and authenticates, thus starting a new session.
13
14 Default values for the options are set at compile-time. Run the utility without
15 a username to see what the defaults are for your installation.
16
17 The utility prompts for a password if neither \fB-p\fR or \fB-F\fR is used.
1218
1319 .SH "OPTIONS"
1420 .TP
15 .I server
16 Server on which sesman is running
21 .B -g <width>x<height>
22 Set session geometry.
23 .br
24 Note that most configurations will resize the session on connection, so this
25 option may not do what you expect.
1726 .TP
18 .I username
19 user name of the session being started
27 .B -b <bits-per-pixel>
28 Set session bits-per-pixel (colour depth). Some session types (i.e. Xorg)
29 will ignore this setting.
2030 .TP
21 .I password
22 user password
31 .B -s <server>
32 Server on which sesman is running (probably 'localhost').
33 .br
34 Use of this option is discouraged as it will be removed in the future.
2335 .TP
24 .I width
25 Screen width
36 .B -t <session-type>
37 Session type - one of Xorg, Xvnc or X11rdp. Alternatively, for testing
38 only, use the numeric session code.
2639 .TP
27 .I height
28 Screen height
40 .B -D <directory>
41 Directory to run the new session in. Defaults to $HOME for the specified user.
2942 .TP
30 .I bpp
31 Session color depth
43 .B -S <shell>
44 Specify an alternate shell to run, instead of the default window manager.
45 .TP
46 .B -p <password>
47 Password for user. USE FOR TESTING ONLY - the password will be visible
48 in the output of the \fBps\fR command.
49 .TP
50 .B -F <file-descriptor>
51 Specify a file descriptor (normally 0) to read the password in from. This
52 is a secure way to pass the password in to the utility.
53 .TP
54 .B -c <sesman-ini>
55 Specify a different sesman.ini file. This file is used to find out how to
56 connect to \fBxrdp\-sesman\fR.
57
58 .SH "ENVIRONMENT"
59 .TP
60 .I SESRUN_LOG_LEVEL
61 Override the default logging level. One of "error", "warn", "info",
62 "debug", "trace" or a number 1-5.
63
64 .SH "EXAMPLES"
65 .TP
66 .B
67 xrdp-sesrun -F 0 user1 <passwd.txt
68 Create a default session for user \fBuser1\fR with a password from
69 a file
70 .TP
71 .B
72 xrdp-sesrun -t Xvnc -S /usr/bin/xterm user1
73 Create an extremely minimal Xvnc session for user \fBuser1\fR. This
74 could be useful for debugging why the standard session is not starting
75 properly. Note you would need to install the \fBxterm\fR utility
76 first. The \fBgnome\-terminal\fR utility probably won't work here.
3277
3378 .SH "FILES"
3479 @bindir@/xrdp\-sesman
3580 .br
3681 @bindir@/xrdp\-sesrun
82 .br
83 @sysconfdir@/xrdp/sesman.ini
3784
3885 .SH "AUTHORS"
3986 Jay Sorg <jsorg71@users.sourceforge.net>
22 \fBxrdp\fR \- a Remote Desktop Protocol (RDP) server
33
44 .SH "SYNTAX"
5 xrdp [ \-\-nodaemon | \-\-kill | \-\-help ]
5 .B xrdp
6 \-\-kill
7 .br
8 .B xrdp
9 \-\-help
10 .br
11 .B xrdp
12 \-\-version
13 .br
14 .B xrdp
15 [ \-\-nodaemon ] [ --port port ] [ --fork ] [ --config /path/to/xrdp.ini ]
616
717 .SH "DESCRIPTION"
818 \fBxrdp\fR is a Remote Desktop Protocol (RDP) Server.
1323
1424 .SH "OPTIONS"
1525 .TP
16 \fB\-n\fR, \fB\-\-nodaemon\fR
17 Start \fBxrdp\fR in foreground instead of starting it as a daemon.
18 .TP
1926 \fB\-k\fR, \fB\-\-kill\fR
2027 Kill running \fBxrdp\fR daemon.
2128 .TP
2229 \fB\-h\fR, \fB\-\-help\fR
2330 Output help information and exit.
31 .TP
32 \fB\-v\fR, \fB\-\-version\fR
33 Output version information and exit.
34 .TP
35 \fB\-n\fR, \fB\-\-nodaemon\fR
36 Start \fBxrdp\fR in foreground instead of starting it as a daemon.
2437 .TP
2538 \fB\-p\fR, \fB\-\-port\fR
2639 Specify TCP port to listen to. This overrides \fIport\fR setting in
3043 Fork a new process on a new connection. If not enabled, use a new thread
3144 for every connection. This overrides \fIfork\fR setting in
3245 \fIxrdp.ini\fR file.
46 .TP
47 \fB\-c\fR, \fB\-\-config\fR
48 Specify a path to a different \fIxrdp.ini\fR file. This option is intended
49 to be used primarily for testing or for unusual configurations.
50
3351
3452 .SH "FILES"
3553 @bindir@/xrdp
2121
2222 .SH "GLOBALS"
2323 The options to be specified in the \fB[Globals]\fR section are the following:
24
25 .TP
26 \fBaddress\fP=\fIip address\fP
27 Specify xrdp listening address. If not specified, defaults to 0.0.0.0 (all interfaces).
2824
2925 .TP
3026 \fBautorun\fP=\fIsession_name\fP
114110
115111 .TP
116112 \fBport\fP=\fIport\fP
117 Specify TCP port to listen on for incoming connections.
118 The default for RDP is \fB3389\fP.
113 Specify TCP port and interface to listen on for incoming connections.
114 Specifying only the port means that xrdp will listen on all interfaces.
115 The default port for RDP is \fB3389\fP.
116 Multiple address:port instances must be separated by spaces or commas. Check the .ini file for examples.
117 Specifying interfaces requires said interfaces to be UP before xrdp starts.
119118
120119 .TP
121120 \fBrequire_credentials\fP=\fI[true|false]\fP
121 If set to \fB1\fP, \fBtrue\fP or \fByes\fP, \fBxrdp\fP will scan the user name provided by the
122 client for the ASCII field separator character (0x1F). It will then copy over what is after the
123 separator as the password supplied by the user and treats it as autologon. If not specified,
124 defaults to \fBfalse\fP.
125
126 .TP
127 \domain_user_separator\fP=\separator\fP
128 If specified the domain name supplied by the client is appended to the username separated
129 by \fBseparator\fP.
130
131 .TP
132 \enable_token_login\fP=\fI[true|false]\fP
122133 If set to \fB1\fP, \fBtrue\fP or \fByes\fP, \fBxrdp\fP requires clients to include username and
123134 password initial connection phase. In other words, xrdp doesn't allow clients to show login
124135 screen if set to true. If not specified, defaults to \fBfalse\fP.
229240 .TP
230241 \fBSyslogLevel\fR=\fIlevel\fR
231242 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.
243
244 .TP
245 \fBEnableConsole\fR=\fI[true|false]\fR
246 If set to \fB1\fR, \fBtrue\fR or \fByes\fR, this option enables logging to the console (ie. stdout).
247
248 .TP
249 \fBConsoleLevel\fR=\fIlevel\fR
250 Logging level for the console. It can have the same values as \fBLogLevel\fR. Defaults to \fBDEBUG\fR.
251
252 .TP
253 \fBEnableProcessId\fR=\fI[true|false]\fR
254 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.
232255
233256 .SH "CHANNELS"
234257 The Remote Desktop Protocol supports several channels, which are used to transfer additional data like sound, clipboard data and others.
300323 Specifies color depth of the backend X server. The default is the color
301324 depth of the client. Only Xvnc and X11rdp use that setting. Xorg runs at
302325 \fI24\fR bpp.
326
327 .TP
328 \fBdisabled_encodings_mask\fR=\fI<number>\fR
329 Set this bitmask to a non-zero value to prevent \fBxrdp\fR(8) requesting
330 some features from the Xvnc server. You should only need to set this
331 to a non-zero value to work around bugs in your Xvnc server. The bit
332 values supported for a particular release of \fBxrdp\fR(8) are documented in
333 \fBxrdp.ini\fR.
303334
304335 .TP
305336 \fBcode\fR=\fI<number>\fR|\fI0\fR
3131 A. You need to install the Xrandr development package.
3232 For Debian / Ubuntu this package is called libxrandr-dev.
3333 For SUSE / openSUSE this package is called libXrandr-devel.
34
35 Q. How do I configure the same continuous integration bulids for my XRDP fork as the official XRDP repository?
36
37 A. The XRDP project uses both Travis-CI.org and Cirrus-CI.com for continuous integration.
38 Both of these services are free for open source projects (both the official
39 repository and forks), and these services integrate with Github to build any
40 changes pushed to public Github repositories.
41
42 To configure Travis CI for your XRDP fork on github:
43 1. Follow Travis CI instructions for connecting your github account to Travis CI
44 https://docs.travis-ci.com/user/tutorial/#to-get-started-with-travis-ci-using-github
45 2. In the Travis CI dashboard setting page select your XRDP fork repository for building pushed branches.
46 3. Push a commit to a branch in your XRDP fork on github and Travis CI should
47 start building the branch because the XRDP repository already contain a .travis.yml file.
48
49 To configure Cirrus CI for your XRDP fork on github:
50 1. Follow Cirrus CI instructions for connecting your github account to Cirrus CI
51 https://cirrus-ci.org/guide/quick-start/
52 2. In the Github setting page for the Cirrus CI application, enable Cirrus CI
53 access to your XRDP fork repository.
54 3. Push a commit to a branch in your XRDP fork on github and Cirrus CI should
55 start building the branch because the XRDP repository already contain a .cirrus.yml file.
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
1313 # English - US 'dvorak' 0x00010409
1414 setxkbmap -model pc104 -layout dvorak
1515 ./xrdp-genkeymap ../instfiles/km-00010409.ini
16
17 # English - US 'dvp' 0x19360409
18 OLD_SETTINGS=$(setxkbmap -query -verbose 4 | sed "s/^\([a-z]\+\):\s*\(.*\)$/-\1 \2/;s/^-options/-option \"\" -option/;s/,/ -option /g" | xargs -d \\n)
19 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
20 ./xrdp-genkeymap ../instfiles/km-19360409.ini
21 setxkbmap ${OLD_SETTINGS}
1622
1723 # English - UK 'en-GB' 0x00000809
1824 setxkbmap -model pc105 -layout gb
4343 #include <X11/XKBlib.h>
4444 #include <locale.h>
4545
46 extern int xfree86_to_evdev[137-8];
46 extern int xfree86_to_evdev[137-8+1];
4747
4848 int main(int argc, char **argv)
4949 {
135135 fprintf(outf, "[%s]\n", sections[idx]);
136136 e.state = states[idx];
137137
138 for (i = 8; i <= 137; i++) /* Keycodes */
138 for (i = 8; i < 137; i++) /* Keycodes */
139139 {
140140 if (is_evdev)
141141 e.keycode = xfree86_to_evdev[i-8];
00 #!/bin/sh
11 # install - install a program, script, or datafile
22
3 scriptversion=2018-03-11.20; # UTC
3 scriptversion=2020-11-14.01; # UTC
44
55 # This originates from X11R5 (mit/util/scripts/install.sh), which was
66 # later released in X11R6 (xc/config/util/install.sh) with the
6868 # Desired mode of installed file.
6969 mode=0755
7070
71 # Create dirs (including intermediate dirs) using mode 755.
72 # This is like GNU 'install' as of coreutils 8.32 (2020).
73 mkdir_umask=22
74
75 backupsuffix=
7176 chgrpcmd=
7277 chmodcmd=$chmodprog
7378 chowncmd=
98103 --version display version info and exit.
99104
100105 -c (ignored)
101 -C install only if different (preserve the last data modification time)
106 -C install only if different (preserve data modification time)
102107 -d create directories instead of installing files.
103108 -g GROUP $chgrpprog installed files to GROUP.
104109 -m MODE $chmodprog installed files to MODE.
105110 -o USER $chownprog installed files to USER.
111 -p pass -p to $cpprog.
106112 -s $stripprog installed files.
113 -S SUFFIX attempt to back up existing files, with suffix SUFFIX.
107114 -t DIRECTORY install into DIRECTORY.
108115 -T report an error if DSTFILE is a directory.
109116
110117 Environment variables override the default commands:
111118 CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
112119 RMPROG STRIPPROG
120
121 By default, rm is invoked with -f; when overridden with RMPROG,
122 it's up to you to specify -f if you want it.
123
124 If -S is not specified, no backups are attempted.
125
126 Email bug reports to bug-automake@gnu.org.
127 Automake home page: https://www.gnu.org/software/automake/
113128 "
114129
115130 while test $# -ne 0; do
136151 -o) chowncmd="$chownprog $2"
137152 shift;;
138153
154 -p) cpprog="$cpprog -p";;
155
139156 -s) stripcmd=$stripprog;;
157
158 -S) backupsuffix="$2"
159 shift;;
140160
141161 -t)
142162 is_target_a_directory=always
254274 dstdir=$dst
255275 test -d "$dstdir"
256276 dstdir_status=$?
277 # Don't chown directories that already exist.
278 if test $dstdir_status = 0; then
279 chowncmd=""
280 fi
257281 else
258282
259283 # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
300324 if test $dstdir_status != 0; then
301325 case $posix_mkdir in
302326 '')
303 # Create intermediate dirs using mode 755 as modified by the umask.
304 # This is like FreeBSD 'install' as of 1997-10-28.
305 umask=`umask`
306 case $stripcmd.$umask in
307 # Optimize common cases.
308 *[2367][2367]) mkdir_umask=$umask;;
309 .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
310
311 *[0-7])
312 mkdir_umask=`expr $umask + 22 \
313 - $umask % 100 % 40 + $umask % 20 \
314 - $umask % 10 % 4 + $umask % 2
315 `;;
316 *) mkdir_umask=$umask,go-w;;
317 esac
318
319327 # With -d, create the new directory with the user-specified mode.
320328 # Otherwise, rely on $mkdir_umask.
321329 if test -n "$dir_arg"; then
325333 fi
326334
327335 posix_mkdir=false
328 case $umask in
329 *[123567][0-7][0-7])
330 # POSIX mkdir -p sets u+wx bits regardless of umask, which
331 # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
332 ;;
333 *)
334 # Note that $RANDOM variable is not portable (e.g. dash); Use it
335 # here however when possible just to lower collision chance.
336 tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
337
338 trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
339
340 # Because "mkdir -p" follows existing symlinks and we likely work
341 # directly in world-writeable /tmp, make sure that the '$tmpdir'
342 # directory is successfully created first before we actually test
343 # 'mkdir -p' feature.
344 if (umask $mkdir_umask &&
345 $mkdirprog $mkdir_mode "$tmpdir" &&
346 exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
347 then
348 if test -z "$dir_arg" || {
349 # Check for POSIX incompatibilities with -m.
350 # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
351 # other-writable bit of parent directory when it shouldn't.
352 # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
353 test_tmpdir="$tmpdir/a"
354 ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
355 case $ls_ld_tmpdir in
356 d????-?r-*) different_mode=700;;
357 d????-?--*) different_mode=755;;
358 *) false;;
359 esac &&
360 $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
361 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
362 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
363 }
364 }
365 then posix_mkdir=:
366 fi
367 rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
368 else
369 # Remove any dirs left behind by ancient mkdir implementations.
370 rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
371 fi
372 trap '' 0;;
373 esac;;
336 # The $RANDOM variable is not portable (e.g., dash). Use it
337 # here however when possible just to lower collision chance.
338 tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
339
340 trap '
341 ret=$?
342 rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
343 exit $ret
344 ' 0
345
346 # Because "mkdir -p" follows existing symlinks and we likely work
347 # directly in world-writeable /tmp, make sure that the '$tmpdir'
348 # directory is successfully created first before we actually test
349 # 'mkdir -p'.
350 if (umask $mkdir_umask &&
351 $mkdirprog $mkdir_mode "$tmpdir" &&
352 exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
353 then
354 if test -z "$dir_arg" || {
355 # Check for POSIX incompatibilities with -m.
356 # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
357 # other-writable bit of parent directory when it shouldn't.
358 # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
359 test_tmpdir="$tmpdir/a"
360 ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
361 case $ls_ld_tmpdir in
362 d????-?r-*) different_mode=700;;
363 d????-?--*) different_mode=755;;
364 *) false;;
365 esac &&
366 $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
367 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
368 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
369 }
370 }
371 then posix_mkdir=:
372 fi
373 rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
374 else
375 # Remove any dirs left behind by ancient mkdir implementations.
376 rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
377 fi
378 trap '' 0;;
374379 esac
375380
376381 if
381386 then :
382387 else
383388
384 # The umask is ridiculous, or mkdir does not conform to POSIX,
389 # mkdir does not conform to POSIX,
385390 # or it failed possibly due to a race condition. Create the
386391 # directory the slow way, step by step, checking for races as we go.
387392
410415 prefixes=
411416 else
412417 if $posix_mkdir; then
413 (umask=$mkdir_umask &&
418 (umask $mkdir_umask &&
414419 $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
415420 # Don't fail if two instances are running concurrently.
416421 test -d "$prefix" || exit 1
450455 trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
451456
452457 # Copy the file name to the temp name.
453 (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
458 (umask $cp_umask &&
459 { test -z "$stripcmd" || {
460 # Create $dsttmp read-write so that cp doesn't create it read-only,
461 # which would cause strip to fail.
462 if test -z "$doit"; then
463 : >"$dsttmp" # No need to fork-exec 'touch'.
464 else
465 $doit touch "$dsttmp"
466 fi
467 }
468 } &&
469 $doit_exec $cpprog "$src" "$dsttmp") &&
454470
455471 # and set any options; do chmod last to preserve setuid bits.
456472 #
476492 then
477493 rm -f "$dsttmp"
478494 else
495 # If $backupsuffix is set, and the file being installed
496 # already exists, attempt a backup. Don't worry if it fails,
497 # e.g., if mv doesn't support -f.
498 if test -n "$backupsuffix" && test -f "$dst"; then
499 $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
500 fi
501
479502 # Rename the file to the real destination.
480503 $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
481504
490513 # file should still install successfully.
491514 {
492515 test ! -f "$dst" ||
493 $doit $rmcmd -f "$dst" 2>/dev/null ||
516 $doit $rmcmd "$dst" 2>/dev/null ||
494517 { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
495 { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
518 { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
496519 } ||
497520 { echo "$0: cannot unlink or rename $dst" >&2
498521 (exit 1); exit 1
4949 km-00000813.ini \
5050 km-00000816.ini \
5151 km-0000100c.ini \
52 km-00010409.ini
52 km-00010409.ini \
53 km-19360409.ini
5354
5455 #
5556 # platform specific files
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
426426 km-00000813.ini \
427427 km-00000816.ini \
428428 km-0000100c.ini \
429 km-00010409.ini
429 km-00010409.ini \
430 km-19360409.ini
430431
431432
432433 #
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
0 [noshift]
1 Key8=65406:0
2 Key9=65307:27
3 Key10=38:38
4 Key11=91:91
5 Key12=123:123
6 Key13=125:125
7 Key14=40:40
8 Key15=61:61
9 Key16=42:42
10 Key17=41:41
11 Key18=43:43
12 Key19=93:93
13 Key20=33:33
14 Key21=35:35
15 Key22=65288:8
16 Key23=65289:9
17 Key24=59:59
18 Key25=44:44
19 Key26=46:46
20 Key27=112:112
21 Key28=121:121
22 Key29=102:102
23 Key30=103:103
24 Key31=99:99
25 Key32=114:114
26 Key33=108:108
27 Key34=47:47
28 Key35=64:64
29 Key36=65293:13
30 Key37=65507:0
31 Key38=97:97
32 Key39=111:111
33 Key40=101:101
34 Key41=117:117
35 Key42=105:105
36 Key43=100:100
37 Key44=104:104
38 Key45=116:116
39 Key46=110:110
40 Key47=115:115
41 Key48=45:45
42 Key49=36:36
43 Key50=65505:0
44 Key51=92:92
45 Key52=39:39
46 Key53=113:113
47 Key54=106:106
48 Key55=107:107
49 Key56=120:120
50 Key57=98:98
51 Key58=109:109
52 Key59=119:119
53 Key60=118:118
54 Key61=122:122
55 Key62=65506:0
56 Key63=65450:42
57 Key64=65513:0
58 Key65=32:32
59 Key66=65509:0
60 Key67=65470:0
61 Key68=65471:0
62 Key69=65472:0
63 Key70=65473:0
64 Key71=65474:0
65 Key72=65475:0
66 Key73=65476:0
67 Key74=65477:0
68 Key75=65478:0
69 Key76=65479:0
70 Key77=65407:0
71 Key78=65300:0
72 Key79=65429:0
73 Key80=65431:0
74 Key81=65434:0
75 Key82=65453:45
76 Key83=65430:0
77 Key84=65437:0
78 Key85=65432:0
79 Key86=65451:43
80 Key87=65436:0
81 Key88=65433:0
82 Key89=65435:0
83 Key90=65438:0
84 Key91=65439:0
85 Key92=0:0
86 Key93=0:0
87 Key94=65312:0
88 Key95=65480:0
89 Key96=65481:0
90 Key97=65360:0
91 Key98=65362:0
92 Key99=65365:0
93 Key100=65361:0
94 Key101=0:0
95 Key102=65363:0
96 Key103=65367:0
97 Key104=65364:0
98 Key105=65366:0
99 Key106=65379:0
100 Key107=65535:127
101 Key108=65421:13
102 Key109=65508:0
103 Key110=65299:0
104 Key111=65377:0
105 Key112=65455:47
106 Key113=65514:0
107 Key114=0:0
108 Key115=65515:0
109 Key116=65516:0
110 Key117=65383:0
111 Key118=0:0
112 Key119=0:0
113 Key120=0:0
114 Key121=0:0
115 Key122=0:0
116 Key123=0:0
117 Key124=65027:0
118 Key125=0:0
119 Key126=65469:61
120 Key127=0:0
121 Key128=0:0
122 Key129=0:0
123 Key130=0:0
124 Key131=0:0
125 Key132=0:0
126 Key133=0:0
127 Key134=65454:46
128 Key135=0:0
129 Key136=0:0
130
131 [shift]
132 Key8=65406:0
133 Key9=65307:27
134 Key10=37:37
135 Key11=55:55
136 Key12=53:53
137 Key13=51:51
138 Key14=49:49
139 Key15=57:57
140 Key16=48:48
141 Key17=50:50
142 Key18=52:52
143 Key19=54:54
144 Key20=56:56
145 Key21=96:96
146 Key22=65288:8
147 Key23=65056:0
148 Key24=58:58
149 Key25=60:60
150 Key26=62:62
151 Key27=80:80
152 Key28=89:89
153 Key29=70:70
154 Key30=71:71
155 Key31=67:67
156 Key32=82:82
157 Key33=76:76
158 Key34=63:63
159 Key35=94:94
160 Key36=65293:13
161 Key37=65507:0
162 Key38=65:65
163 Key39=79:79
164 Key40=69:69
165 Key41=85:85
166 Key42=73:73
167 Key43=68:68
168 Key44=72:72
169 Key45=84:84
170 Key46=78:78
171 Key47=83:83
172 Key48=95:95
173 Key49=126:126
174 Key50=65505:0
175 Key51=124:124
176 Key52=34:34
177 Key53=81:81
178 Key54=74:74
179 Key55=75:75
180 Key56=88:88
181 Key57=66:66
182 Key58=77:77
183 Key59=87:87
184 Key60=86:86
185 Key61=90:90
186 Key62=65506:0
187 Key63=65450:42
188 Key64=65511:0
189 Key65=32:32
190 Key66=65509:0
191 Key67=65470:0
192 Key68=65471:0
193 Key69=65472:0
194 Key70=65473:0
195 Key71=65474:0
196 Key72=65475:0
197 Key73=65476:0
198 Key74=65477:0
199 Key75=65478:0
200 Key76=65479:0
201 Key77=65407:0
202 Key78=65300:0
203 Key79=65429:0
204 Key80=65431:0
205 Key81=65434:0
206 Key82=65453:45
207 Key83=65430:0
208 Key84=65437:0
209 Key85=65432:0
210 Key86=65451:43
211 Key87=65436:0
212 Key88=65433:0
213 Key89=65435:0
214 Key90=65438:0
215 Key91=65439:0
216 Key92=0:0
217 Key93=0:0
218 Key94=65312:0
219 Key95=65480:0
220 Key96=65481:0
221 Key97=65360:0
222 Key98=65362:0
223 Key99=65365:0
224 Key100=65361:0
225 Key101=0:0
226 Key102=65363:0
227 Key103=65367:0
228 Key104=65364:0
229 Key105=65366:0
230 Key106=65379:0
231 Key107=65535:127
232 Key108=65421:13
233 Key109=65508:0
234 Key110=65299:0
235 Key111=65377:0
236 Key112=65455:47
237 Key113=65512:0
238 Key114=0:0
239 Key115=65515:0
240 Key116=65516:0
241 Key117=65383:0
242 Key118=0:0
243 Key119=0:0
244 Key120=0:0
245 Key121=0:0
246 Key122=0:0
247 Key123=0:0
248 Key124=65027:0
249 Key125=65513:0
250 Key126=61:61
251 Key127=65515:0
252 Key128=65517:0
253 Key129=0:0
254 Key130=0:0
255 Key131=0:0
256 Key132=0:0
257 Key133=0:0
258 Key134=65454:46
259 Key135=0:0
260 Key136=0:0
261
262 [altgr]
263 Key8=65406:0
264 Key9=65307:27
265 Key10=38:38
266 Key11=164:164
267 Key12=162:162
268 Key13=165:165
269 Key14=8364:8364
270 Key15=163:163
271 Key16=0:0
272 Key17=189:189
273 Key18=65104:96
274 Key19=0:0
275 Key20=161:161
276 Key21=65104:96
277 Key22=65288:8
278 Key23=65289:9
279 Key24=65111:168
280 Key25=171:171
281 Key26=187:187
282 Key27=182:182
283 Key28=252:252
284 Key29=102:102
285 Key30=103:103
286 Key31=231:231
287 Key32=174:174
288 Key33=108:108
289 Key34=191:191
290 Key35=65106:94
291 Key36=65293:13
292 Key37=65507:0
293 Key38=229:229
294 Key39=248:248
295 Key40=230:230
296 Key41=233:233
297 Key42=105:105
298 Key43=240:240
299 Key44=65105:180
300 Key45=254:254
301 Key46=241:241
302 Key47=223:223
303 Key48=173:173
304 Key49=65107:126
305 Key50=65505:0
306 Key51=92:92
307 Key52=65105:180
308 Key53=113:113
309 Key54=106:106
310 Key55=107:107
311 Key56=120:120
312 Key57=98:98
313 Key58=109:109
314 Key59=119:119
315 Key60=118:118
316 Key61=122:122
317 Key62=65506:0
318 Key63=65450:42
319 Key64=65513:0
320 Key65=32:32
321 Key66=65509:0
322 Key67=65470:0
323 Key68=65471:0
324 Key69=65472:0
325 Key70=65473:0
326 Key71=65474:0
327 Key72=65475:0
328 Key73=65476:0
329 Key74=65477:0
330 Key75=65478:0
331 Key76=65479:0
332 Key77=65407:0
333 Key78=65300:0
334 Key79=65429:0
335 Key80=65431:0
336 Key81=65434:0
337 Key82=65453:45
338 Key83=65430:0
339 Key84=65437:0
340 Key85=65432:0
341 Key86=65451:43
342 Key87=65436:0
343 Key88=65433:0
344 Key89=65435:0
345 Key90=65438:0
346 Key91=65439:0
347 Key92=0:0
348 Key93=0:0
349 Key94=65312:0
350 Key95=65480:0
351 Key96=65481:0
352 Key97=65360:0
353 Key98=65362:0
354 Key99=65365:0
355 Key100=65361:0
356 Key101=0:0
357 Key102=65363:0
358 Key103=65367:0
359 Key104=65364:0
360 Key105=65366:0
361 Key106=65379:0
362 Key107=65535:127
363 Key108=65421:13
364 Key109=65508:0
365 Key110=65299:0
366 Key111=65377:0
367 Key112=65455:47
368 Key113=65514:0
369 Key114=0:0
370 Key115=65515:0
371 Key116=65516:0
372 Key117=65383:0
373 Key118=0:0
374 Key119=0:0
375 Key120=0:0
376 Key121=0:0
377 Key122=0:0
378 Key123=0:0
379 Key124=65027:0
380 Key125=0:0
381 Key126=65469:61
382 Key127=0:0
383 Key128=0:0
384 Key129=0:0
385 Key130=0:0
386 Key131=0:0
387 Key132=0:0
388 Key133=0:0
389 Key134=65454:46
390 Key135=0:0
391 Key136=0:0
392
393 [shiftaltgr]
394 Key8=65406:0
395 Key9=65307:27
396 Key10=37:37
397 Key11=0:0
398 Key12=0:0
399 Key13=0:0
400 Key14=0:0
401 Key15=65106:94
402 Key16=0:0
403 Key17=0:0
404 Key18=0:0
405 Key19=0:0
406 Key20=16789016:11800
407 Key21=0:0
408 Key22=65288:8
409 Key23=65056:0
410 Key24=65111:168
411 Key25=16785436:8220
412 Key26=16785437:8221
413 Key27=167:167
414 Key28=220:220
415 Key29=70:70
416 Key30=71:71
417 Key31=199:199
418 Key32=2761:8482
419 Key33=76:76
420 Key34=16785469:8253
421 Key35=65114:711
422 Key36=65293:13
423 Key37=65507:0
424 Key38=197:197
425 Key39=216:216
426 Key40=198:198
427 Key41=201:201
428 Key42=73:73
429 Key43=208:208
430 Key44=0:0
431 Key45=222:222
432 Key46=209:209
433 Key47=0:0
434 Key48=2730:8211
435 Key49=65107:126
436 Key50=65505:0
437 Key51=124:124
438 Key52=65113:733
439 Key53=81:81
440 Key54=74:74
441 Key55=75:75
442 Key56=88:88
443 Key57=66:66
444 Key58=77:77
445 Key59=87:87
446 Key60=86:86
447 Key61=90:90
448 Key62=65506:0
449 Key63=65450:42
450 Key64=65511:0
451 Key65=32:32
452 Key66=65509:0
453 Key67=65470:0
454 Key68=65471:0
455 Key69=65472:0
456 Key70=65473:0
457 Key71=65474:0
458 Key72=65475:0
459 Key73=65476:0
460 Key74=65477:0
461 Key75=65478:0
462 Key76=65479:0
463 Key77=65407:0
464 Key78=65300:0
465 Key79=65429:0
466 Key80=65431:0
467 Key81=65434:0
468 Key82=65453:45
469 Key83=65430:0
470 Key84=65437:0
471 Key85=65432:0
472 Key86=65451:43
473 Key87=65436:0
474 Key88=65433:0
475 Key89=65435:0
476 Key90=65438:0
477 Key91=65439:0
478 Key92=0:0
479 Key93=0:0
480 Key94=65312:0
481 Key95=65480:0
482 Key96=65481:0
483 Key97=65360:0
484 Key98=65362:0
485 Key99=65365:0
486 Key100=65361:0
487 Key101=0:0
488 Key102=65363:0
489 Key103=65367:0
490 Key104=65364:0
491 Key105=65366:0
492 Key106=65379:0
493 Key107=65535:127
494 Key108=65421:13
495 Key109=65508:0
496 Key110=65299:0
497 Key111=65377:0
498 Key112=65455:47
499 Key113=65512:0
500 Key114=0:0
501 Key115=65515:0
502 Key116=65516:0
503 Key117=65383:0
504 Key118=0:0
505 Key119=0:0
506 Key120=0:0
507 Key121=0:0
508 Key122=0:0
509 Key123=0:0
510 Key124=65027:0
511 Key125=65513:0
512 Key126=61:61
513 Key127=65515:0
514 Key128=65517:0
515 Key129=0:0
516 Key130=0:0
517 Key131=0:0
518 Key132=0:0
519 Key133=0:0
520 Key134=65454:46
521 Key135=0:0
522 Key136=0:0
523
524 [capslock]
525 Key8=65406:0
526 Key9=65307:27
527 Key10=38:38
528 Key11=55:55
529 Key12=53:53
530 Key13=51:51
531 Key14=49:49
532 Key15=57:57
533 Key16=48:48
534 Key17=50:50
535 Key18=52:52
536 Key19=54:54
537 Key20=56:56
538 Key21=35:35
539 Key22=65288:8
540 Key23=65289:9
541 Key24=59:59
542 Key25=44:44
543 Key26=46:46
544 Key27=80:80
545 Key28=89:89
546 Key29=70:70
547 Key30=71:71
548 Key31=67:67
549 Key32=82:82
550 Key33=76:76
551 Key34=47:47
552 Key35=64:64
553 Key36=65293:13
554 Key37=65507:0
555 Key38=65:65
556 Key39=79:79
557 Key40=69:69
558 Key41=85:85
559 Key42=73:73
560 Key43=68:68
561 Key44=72:72
562 Key45=84:84
563 Key46=78:78
564 Key47=83:83
565 Key48=95:95
566 Key49=36:36
567 Key50=65505:0
568 Key51=92:92
569 Key52=39:39
570 Key53=81:81
571 Key54=74:74
572 Key55=75:75
573 Key56=88:88
574 Key57=66:66
575 Key58=77:77
576 Key59=87:87
577 Key60=86:86
578 Key61=90:90
579 Key62=65506:0
580 Key63=65450:42
581 Key64=65513:0
582 Key65=32:32
583 Key66=65509:0
584 Key67=65470:0
585 Key68=65471:0
586 Key69=65472:0
587 Key70=65473:0
588 Key71=65474:0
589 Key72=65475:0
590 Key73=65476:0
591 Key74=65477:0
592 Key75=65478:0
593 Key76=65479:0
594 Key77=65407:0
595 Key78=65300:0
596 Key79=65429:0
597 Key80=65431:0
598 Key81=65434:0
599 Key82=65453:45
600 Key83=65430:0
601 Key84=65437:0
602 Key85=65432:0
603 Key86=65451:43
604 Key87=65436:0
605 Key88=65433:0
606 Key89=65435:0
607 Key90=65438:0
608 Key91=65439:0
609 Key92=0:0
610 Key93=0:0
611 Key94=65312:0
612 Key95=65480:0
613 Key96=65481:0
614 Key97=65360:0
615 Key98=65362:0
616 Key99=65365:0
617 Key100=65361:0
618 Key101=0:0
619 Key102=65363:0
620 Key103=65367:0
621 Key104=65364:0
622 Key105=65366:0
623 Key106=65379:0
624 Key107=65535:127
625 Key108=65421:13
626 Key109=65508:0
627 Key110=65299:0
628 Key111=65377:0
629 Key112=65455:47
630 Key113=65514:0
631 Key114=0:0
632 Key115=65515:0
633 Key116=65516:0
634 Key117=65383:0
635 Key118=0:0
636 Key119=0:0
637 Key120=0:0
638 Key121=0:0
639 Key122=0:0
640 Key123=0:0
641 Key124=65027:0
642 Key125=0:0
643 Key126=65469:61
644 Key127=0:0
645 Key128=0:0
646 Key129=0:0
647 Key130=0:0
648 Key131=0:0
649 Key132=0:0
650 Key133=0:0
651 Key134=65454:46
652 Key135=0:0
653 Key136=0:0
654
655 [capslockaltgr]
656 Key8=65406:0
657 Key9=65307:27
658 Key10=38:38
659 Key11=0:0
660 Key12=0:0
661 Key13=0:0
662 Key14=0:0
663 Key15=65106:94
664 Key16=0:0
665 Key17=0:0
666 Key18=0:0
667 Key19=0:0
668 Key20=16789016:11800
669 Key21=65104:96
670 Key22=65288:8
671 Key23=65289:9
672 Key24=65111:168
673 Key25=171:171
674 Key26=187:187
675 Key27=182:182
676 Key28=220:220
677 Key29=70:70
678 Key30=71:71
679 Key31=199:199
680 Key32=174:174
681 Key33=76:76
682 Key34=191:191
683 Key35=65106:94
684 Key36=65293:13
685 Key37=65507:0
686 Key38=197:197
687 Key39=216:216
688 Key40=198:198
689 Key41=201:201
690 Key42=73:73
691 Key43=208:208
692 Key44=65105:180
693 Key45=222:222
694 Key46=209:209
695 Key47=223:223
696 Key48=2730:8211
697 Key49=65107:126
698 Key50=65505:0
699 Key51=92:92
700 Key52=65105:180
701 Key53=81:81
702 Key54=74:74
703 Key55=75:75
704 Key56=88:88
705 Key57=66:66
706 Key58=77:77
707 Key59=87:87
708 Key60=86:86
709 Key61=90:90
710 Key62=65506:0
711 Key63=65450:42
712 Key64=65513:0
713 Key65=32:32
714 Key66=65509:0
715 Key67=65470:0
716 Key68=65471:0
717 Key69=65472:0
718 Key70=65473:0
719 Key71=65474:0
720 Key72=65475:0
721 Key73=65476:0
722 Key74=65477:0
723 Key75=65478:0
724 Key76=65479:0
725 Key77=65407:0
726 Key78=65300:0
727 Key79=65429:0
728 Key80=65431:0
729 Key81=65434:0
730 Key82=65453:45
731 Key83=65430:0
732 Key84=65437:0
733 Key85=65432:0
734 Key86=65451:43
735 Key87=65436:0
736 Key88=65433:0
737 Key89=65435:0
738 Key90=65438:0
739 Key91=65439:0
740 Key92=0:0
741 Key93=0:0
742 Key94=65312:0
743 Key95=65480:0
744 Key96=65481:0
745 Key97=65360:0
746 Key98=65362:0
747 Key99=65365:0
748 Key100=65361:0
749 Key101=0:0
750 Key102=65363:0
751 Key103=65367:0
752 Key104=65364:0
753 Key105=65366:0
754 Key106=65379:0
755 Key107=65535:127
756 Key108=65421:13
757 Key109=65508:0
758 Key110=65299:0
759 Key111=65377:0
760 Key112=65455:47
761 Key113=65514:0
762 Key114=0:0
763 Key115=65515:0
764 Key116=65516:0
765 Key117=65383:0
766 Key118=0:0
767 Key119=0:0
768 Key120=0:0
769 Key121=0:0
770 Key122=0:0
771 Key123=0:0
772 Key124=65027:0
773 Key125=0:0
774 Key126=65469:61
775 Key127=0:0
776 Key128=0:0
777 Key129=0:0
778 Key130=0:0
779 Key131=0:0
780 Key132=0:0
781 Key133=0:0
782 Key134=65454:46
783 Key135=0:0
784 Key136=0:0
785
786 [shiftcapslock]
787 Key8=65406:0
788 Key9=65307:27
789 Key10=37:37
790 Key11=91:91
791 Key12=123:123
792 Key13=125:125
793 Key14=40:40
794 Key15=61:61
795 Key16=42:42
796 Key17=41:41
797 Key18=43:43
798 Key19=93:93
799 Key20=33:33
800 Key21=96:96
801 Key22=65288:8
802 Key23=65056:0
803 Key24=58:58
804 Key25=60:60
805 Key26=62:62
806 Key27=112:112
807 Key28=121:121
808 Key29=102:102
809 Key30=103:103
810 Key31=99:99
811 Key32=114:114
812 Key33=108:108
813 Key34=63:63
814 Key35=94:94
815 Key36=65293:13
816 Key37=65507:0
817 Key38=97:97
818 Key39=111:111
819 Key40=101:101
820 Key41=117:117
821 Key42=105:105
822 Key43=100:100
823 Key44=104:104
824 Key45=116:116
825 Key46=110:110
826 Key47=115:115
827 Key48=45:45
828 Key49=126:126
829 Key50=65505:0
830 Key51=124:124
831 Key52=34:34
832 Key53=113:113
833 Key54=106:106
834 Key55=107:107
835 Key56=120:120
836 Key57=98:98
837 Key58=109:109
838 Key59=119:119
839 Key60=118:118
840 Key61=122:122
841 Key62=65506:0
842 Key63=65450:42
843 Key64=65511:0
844 Key65=32:32
845 Key66=65509:0
846 Key67=65470:0
847 Key68=65471:0
848 Key69=65472:0
849 Key70=65473:0
850 Key71=65474:0
851 Key72=65475:0
852 Key73=65476:0
853 Key74=65477:0
854 Key75=65478:0
855 Key76=65479:0
856 Key77=65407:0
857 Key78=65300:0
858 Key79=65429:0
859 Key80=65431:0
860 Key81=65434:0
861 Key82=65453:45
862 Key83=65430:0
863 Key84=65437:0
864 Key85=65432:0
865 Key86=65451:43
866 Key87=65436:0
867 Key88=65433:0
868 Key89=65435:0
869 Key90=65438:0
870 Key91=65439:0
871 Key92=0:0
872 Key93=0:0
873 Key94=65312:0
874 Key95=65480:0
875 Key96=65481:0
876 Key97=65360:0
877 Key98=65362:0
878 Key99=65365:0
879 Key100=65361:0
880 Key101=0:0
881 Key102=65363:0
882 Key103=65367:0
883 Key104=65364:0
884 Key105=65366:0
885 Key106=65379:0
886 Key107=65535:127
887 Key108=65421:13
888 Key109=65508:0
889 Key110=65299:0
890 Key111=65377:0
891 Key112=65455:47
892 Key113=65512:0
893 Key114=0:0
894 Key115=65515:0
895 Key116=65516:0
896 Key117=65383:0
897 Key118=0:0
898 Key119=0:0
899 Key120=0:0
900 Key121=0:0
901 Key122=0:0
902 Key123=0:0
903 Key124=65027:0
904 Key125=65513:0
905 Key126=61:61
906 Key127=65515:0
907 Key128=65517:0
908 Key129=0:0
909 Key130=0:0
910 Key131=0:0
911 Key132=0:0
912 Key133=0:0
913 Key134=65454:46
914 Key135=0:0
915 Key136=0:0
916
917 [shiftcapslockaltgr]
918 Key8=65406:0
919 Key9=65307:27
920 Key10=37:37
921 Key11=164:164
922 Key12=162:162
923 Key13=165:165
924 Key14=8364:8364
925 Key15=163:163
926 Key16=0:0
927 Key17=189:189
928 Key18=65104:96
929 Key19=0:0
930 Key20=161:161
931 Key21=0:0
932 Key22=65288:8
933 Key23=65056:0
934 Key24=65111:168
935 Key25=16785436:8220
936 Key26=16785437:8221
937 Key27=167:167
938 Key28=252:252
939 Key29=102:102
940 Key30=103:103
941 Key31=231:231
942 Key32=2761:8482
943 Key33=108:108
944 Key34=16785469:8253
945 Key35=65114:711
946 Key36=65293:13
947 Key37=65507:0
948 Key38=229:229
949 Key39=248:248
950 Key40=230:230
951 Key41=233:233
952 Key42=105:105
953 Key43=240:240
954 Key44=0:0
955 Key45=254:254
956 Key46=241:241
957 Key47=0:0
958 Key48=173:173
959 Key49=65107:126
960 Key50=65505:0
961 Key51=124:124
962 Key52=65113:733
963 Key53=113:113
964 Key54=106:106
965 Key55=107:107
966 Key56=120:120
967 Key57=98:98
968 Key58=109:109
969 Key59=119:119
970 Key60=118:118
971 Key61=122:122
972 Key62=65506:0
973 Key63=65450:42
974 Key64=65511:0
975 Key65=32:32
976 Key66=65509:0
977 Key67=65470:0
978 Key68=65471:0
979 Key69=65472:0
980 Key70=65473:0
981 Key71=65474:0
982 Key72=65475:0
983 Key73=65476:0
984 Key74=65477:0
985 Key75=65478:0
986 Key76=65479:0
987 Key77=65407:0
988 Key78=65300:0
989 Key79=65429:0
990 Key80=65431:0
991 Key81=65434:0
992 Key82=65453:45
993 Key83=65430:0
994 Key84=65437:0
995 Key85=65432:0
996 Key86=65451:43
997 Key87=65436:0
998 Key88=65433:0
999 Key89=65435:0
1000 Key90=65438:0
1001 Key91=65439:0
1002 Key92=0:0
1003 Key93=0:0
1004 Key94=65312:0
1005 Key95=65480:0
1006 Key96=65481:0
1007 Key97=65360:0
1008 Key98=65362:0
1009 Key99=65365:0
1010 Key100=65361:0
1011 Key101=0:0
1012 Key102=65363:0
1013 Key103=65367:0
1014 Key104=65364:0
1015 Key105=65366:0
1016 Key106=65379:0
1017 Key107=65535:127
1018 Key108=65421:13
1019 Key109=65508:0
1020 Key110=65299:0
1021 Key111=65377:0
1022 Key112=65455:47
1023 Key113=65512:0
1024 Key114=0:0
1025 Key115=65515:0
1026 Key116=65516:0
1027 Key117=65383:0
1028 Key118=0:0
1029 Key119=0:0
1030 Key120=0:0
1031 Key121=0:0
1032 Key122=0:0
1033 Key123=0:0
1034 Key124=65027:0
1035 Key125=65513:0
1036 Key126=61:61
1037 Key127=65515:0
1038 Key128=65517:0
1039 Key129=0:0
1040 Key130=0:0
1041 Key131=0:0
1042 Key132=0:0
1043 Key133=0:0
1044 Key134=65454:46
1045 Key135=0:0
1046 Key136=0:0
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
99 pamdir="/etc/pam.d"
1010 pamdir_suse="/usr/etc/pam.d"
1111
12 # Modules needed by xrdp-sesman.unix, if we get to that
13 unix_modules_needed="pam_unix.so pam_env.so pam_nologin.so"
14
15 # Directories where pam modules might be installed
16 # Add to this list as platforms are added
17 pam_module_dir_searchpath="/lib*/security /usr/lib*/security /lib/*/security /usr/lib/*/security"
18
19 find_pam_module_dir()
20 {
21 # Looks for the pam security module directory
22 set -- $pam_module_dir_searchpath
23 for d in "$@"; do
24 if [ -s $d/pam_unix.so ]; then
25 echo $d
26 break
27 fi
28 done
29 }
30
31 can_apply_unix_config()
32 {
33 result=0
34 module_dir="$1"
35 for m in $unix_modules_needed; do
36 if [ ! -s $module_dir/$m ]; then
37 echo " ** $m not found" >&2
38 result=1
39 fi
40 done
41
42 return $result
43 }
44
1245 guess_rules ()
1346 {
14 if test -s "$pamdir/password-auth"; then
47 rules=
48 if [ -s "$pamdir/password-auth" ]; then
1549 rules="redhat"
16 return
17 fi
1850
19 if test -s "$pamdir_suse/common-account"; then
51 elif [ -s "$pamdir_suse/common-account" ]; then
2052 rules="suse"
21 return
22 fi
2353
24 if test -s "$pamdir/common-account"; then
54 elif [ -s "$pamdir/common-account" ]; then
2555 if grep "^@include" "$pamdir/passwd" >/dev/null 2>&1; then
2656 rules="debian"
2757 else
2858 rules="suse"
2959 fi
30 return
60
61 elif [ ! -f "$pamdir/system-auth" -a -s "$pamdir/system" ]; then
62 rules="freebsd"
63
64 elif [ -s "$pamdir/authorization" ]; then
65 rules="macos"
66
67 elif [ -s "$pamdir/system-remote-login" ]; then
68 rules="arch"
69
70 elif [ -s "$pamdir/system-auth" ]; then
71 rules="system"
72
73 else
74 module_dir=`find_pam_module_dir`
75 if [ -d "$module_dir" ]; then
76 #echo "- Found pam modules in $module_dir" >&2
77 if can_apply_unix_config "$module_dir" ; then
78 rules="unix"
79 fi
80 fi
3181 fi
32
33 if test ! -f "$pamdir/system-auth" -a -s "$pamdir/system"; then
34 rules="freebsd"
35 return
36 fi
37
38 if test -s "$pamdir/authorization"; then
39 rules="macos"
40 return
41 fi
42
43 if test -s "$pamdir/system-remote-login"; then
44 rules="arch"
45 return
46 fi
47
48 rules="unix"
49 return
5082 }
5183
52 if test "$rules" = "auto"; then
84 if [ "$rules" = "auto" ]; then
5385 guess_rules
86 if [ -z "$rules" ]; then
87 echo "** Can't guess PAM rules for this system"
88 exit 1
89 fi
5490 fi
5591
56 if test -s "$srcdir/$service.$rules"; then
92 if [ -s "$srcdir/$service.$rules" ]; then
5793 ln -nsf "$srcdir/$service.$rules" "$outfile"
5894 else
5995 echo "Cannot find $srcdir/$service.$rules"
00 #%PAM-1.0
1 auth include system-auth
2 account include system-auth
3 password include system-auth
4 session include system-auth
1 #
2 # Really basic authentication set when nothing else is available
3 #
4 # You may need to edit this to suit your system depending on the
5 # required functionality.
6 #
7 auth required pam_unix.so shadow
8 auth required pam_env.so
9
10 password required pam_unix.so
11
12 account required pam_unix.so
13 account required pam_nologin.so
14
15 session required pam_unix.so
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
2929 #endif
3030
3131 #include "os_calls.h"
32 #include "string_calls.h"
3233 #include "ssl_calls.h"
3334 #include "arch.h"
3435 #include "list.h"
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
143143 $(am__extra_recursive_targets)
144144 AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
145145 cscope distdir distdir-am dist dist-all distcheck
146 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
147 $(LISP)config_ac-h.in
146 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
147 config_ac-h.in
148148 # Read a list of newline-separated strings from the standard input,
149149 # and print each of them once, without duplicates. Input order is
150150 # *not* preserved.
206206 DIST_ARCHIVES = $(distdir).tar.gz
207207 GZIP_ENV = --best
208208 DIST_TARGETS = dist-gzip
209 # Exists only to be overridden by the user if desired.
210 AM_DISTCHECK_DVI_TARGET = dvi
209211 distuninstallcheck_listfiles = find . -type f -print
210212 am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
211213 | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
586588 tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
587589 $(am__post_remove_distdir)
588590
591 dist-zstd: distdir
592 tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
593 $(am__post_remove_distdir)
594
589595 dist-tarZ: distdir
590596 @echo WARNING: "Support for distribution archives compressed with" \
591597 "legacy program 'compress' is deprecated." >&2
628634 eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
629635 *.zip*) \
630636 unzip $(distdir).zip ;;\
637 *.tar.zst*) \
638 zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
631639 esac
632640 chmod -R a-w $(distdir)
633641 chmod u+w $(distdir)
643651 $(DISTCHECK_CONFIGURE_FLAGS) \
644652 --srcdir=../.. --prefix="$$dc_install_base" \
645653 && $(MAKE) $(AM_MAKEFLAGS) \
646 && $(MAKE) $(AM_MAKEFLAGS) dvi \
654 && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
647655 && $(MAKE) $(AM_MAKEFLAGS) check \
648656 && $(MAKE) $(AM_MAKEFLAGS) install \
649657 && $(MAKE) $(AM_MAKEFLAGS) installcheck \
805813 am--refresh check check-am clean clean-cscope clean-generic \
806814 clean-libtool cscope cscopelist-am ctags ctags-am dist \
807815 dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
808 dist-xz dist-zip distcheck distclean distclean-generic \
809 distclean-hdr distclean-libtool distclean-tags distcleancheck \
810 distdir distuninstallcheck dvi dvi-am html html-am info \
811 info-am install install-am install-data install-data-am \
812 install-dvi install-dvi-am install-exec install-exec-am \
813 install-html install-html-am install-info install-info-am \
814 install-man install-pdf install-pdf-am install-ps \
815 install-ps-am install-strip installcheck installcheck-am \
816 installdirs installdirs-am maintainer-clean \
817 maintainer-clean-generic mostlyclean mostlyclean-generic \
818 mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
819 uninstall-am
816 dist-xz dist-zip dist-zstd distcheck distclean \
817 distclean-generic distclean-hdr distclean-libtool \
818 distclean-tags distcleancheck distdir distuninstallcheck dvi \
819 dvi-am html html-am info info-am install install-am \
820 install-data install-data-am install-dvi install-dvi-am \
821 install-exec install-exec-am install-html install-html-am \
822 install-info install-info-am install-man install-pdf \
823 install-pdf-am install-ps install-ps-am install-strip \
824 installcheck installcheck-am installdirs installdirs-am \
825 maintainer-clean maintainer-clean-generic mostlyclean \
826 mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
827 tags tags-am uninstall uninstall-am
820828
821829 .PRECIOUS: Makefile
822830
0 # generated automatically by aclocal 1.16.1 -*- Autoconf -*-
1
2 # Copyright (C) 1996-2018 Free Software Foundation, Inc.
0 # generated automatically by aclocal 1.16.3 -*- Autoconf -*-
1
2 # Copyright (C) 1996-2020 Free Software Foundation, Inc.
33
44 # This file is free software; the Free Software Foundation
55 # gives unlimited permission to copy and/or distribute it,
1919 If you have problems, you may need to regenerate the build system entirely.
2020 To do so, use the procedure documented by the package, typically 'autoreconf'.])])
2121
22 # Copyright (C) 2002-2018 Free Software Foundation, Inc.
22 # Copyright (C) 2002-2020 Free Software Foundation, Inc.
2323 #
2424 # This file is free software; the Free Software Foundation
2525 # gives unlimited permission to copy and/or distribute it,
3434 [am__api_version='1.16'
3535 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
3636 dnl require some minimum version. Point them to the right macro.
37 m4_if([$1], [1.16.1], [],
37 m4_if([$1], [1.16.3], [],
3838 [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
3939 ])
4040
5050 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
5151 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
5252 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
53 [AM_AUTOMAKE_VERSION([1.16.1])dnl
53 [AM_AUTOMAKE_VERSION([1.16.3])dnl
5454 m4_ifndef([AC_AUTOCONF_VERSION],
5555 [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
5656 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
5757
5858 # AM_AUX_DIR_EXPAND -*- Autoconf -*-
5959
60 # Copyright (C) 2001-2018 Free Software Foundation, Inc.
60 # Copyright (C) 2001-2020 Free Software Foundation, Inc.
6161 #
6262 # This file is free software; the Free Software Foundation
6363 # gives unlimited permission to copy and/or distribute it,
109109
110110 # AM_CONDITIONAL -*- Autoconf -*-
111111
112 # Copyright (C) 1997-2018 Free Software Foundation, Inc.
112 # Copyright (C) 1997-2020 Free Software Foundation, Inc.
113113 #
114114 # This file is free software; the Free Software Foundation
115115 # gives unlimited permission to copy and/or distribute it,
140140 Usually this means the macro was only invoked conditionally.]])
141141 fi])])
142142
143 # Copyright (C) 1999-2018 Free Software Foundation, Inc.
143 # Copyright (C) 1999-2020 Free Software Foundation, Inc.
144144 #
145145 # This file is free software; the Free Software Foundation
146146 # gives unlimited permission to copy and/or distribute it,
331331
332332 # Generate code to set up dependency tracking. -*- Autoconf -*-
333333
334 # Copyright (C) 1999-2018 Free Software Foundation, Inc.
334 # Copyright (C) 1999-2020 Free Software Foundation, Inc.
335335 #
336336 # This file is free software; the Free Software Foundation
337337 # gives unlimited permission to copy and/or distribute it,
370370 done
371371 if test $am_rc -ne 0; then
372372 AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
373 for automatic dependency tracking. Try re-running configure with the
373 for automatic dependency tracking. If GNU make was not used, consider
374 re-running the configure script with MAKE="gmake" (or whatever is
375 necessary). You can also try re-running configure with the
374376 '--disable-dependency-tracking' option to at least be able to build
375377 the package (albeit without support for automatic dependency tracking).])
376378 fi
397399
398400 # Do all the work for Automake. -*- Autoconf -*-
399401
400 # Copyright (C) 1996-2018 Free Software Foundation, Inc.
402 # Copyright (C) 1996-2020 Free Software Foundation, Inc.
401403 #
402404 # This file is free software; the Free Software Foundation
403405 # gives unlimited permission to copy and/or distribute it,
594596 done
595597 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
596598
597 # Copyright (C) 2001-2018 Free Software Foundation, Inc.
599 # Copyright (C) 2001-2020 Free Software Foundation, Inc.
598600 #
599601 # This file is free software; the Free Software Foundation
600602 # gives unlimited permission to copy and/or distribute it,
615617 fi
616618 AC_SUBST([install_sh])])
617619
618 # Copyright (C) 2003-2018 Free Software Foundation, Inc.
620 # Copyright (C) 2003-2020 Free Software Foundation, Inc.
619621 #
620622 # This file is free software; the Free Software Foundation
621623 # gives unlimited permission to copy and/or distribute it,
636638
637639 # Check to see how 'make' treats includes. -*- Autoconf -*-
638640
639 # Copyright (C) 2001-2018 Free Software Foundation, Inc.
641 # Copyright (C) 2001-2020 Free Software Foundation, Inc.
640642 #
641643 # This file is free software; the Free Software Foundation
642644 # gives unlimited permission to copy and/or distribute it,
679681
680682 # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
681683
682 # Copyright (C) 1997-2018 Free Software Foundation, Inc.
684 # Copyright (C) 1997-2020 Free Software Foundation, Inc.
683685 #
684686 # This file is free software; the Free Software Foundation
685687 # gives unlimited permission to copy and/or distribute it,
700702 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
701703 AC_REQUIRE_AUX_FILE([missing])dnl
702704 if test x"${MISSING+set}" != xset; then
703 case $am_aux_dir in
704 *\ * | *\ *)
705 MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
706 *)
707 MISSING="\${SHELL} $am_aux_dir/missing" ;;
708 esac
705 MISSING="\${SHELL} '$am_aux_dir/missing'"
709706 fi
710707 # Use eval to expand $SHELL
711708 if eval "$MISSING --is-lightweight"; then
718715
719716 # Helper functions for option handling. -*- Autoconf -*-
720717
721 # Copyright (C) 2001-2018 Free Software Foundation, Inc.
718 # Copyright (C) 2001-2020 Free Software Foundation, Inc.
722719 #
723720 # This file is free software; the Free Software Foundation
724721 # gives unlimited permission to copy and/or distribute it,
747744 AC_DEFUN([_AM_IF_OPTION],
748745 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
749746
750 # Copyright (C) 1999-2018 Free Software Foundation, Inc.
747 # Copyright (C) 1999-2020 Free Software Foundation, Inc.
751748 #
752749 # This file is free software; the Free Software Foundation
753750 # gives unlimited permission to copy and/or distribute it,
794791 # For backward compatibility.
795792 AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
796793
797 # Copyright (C) 2001-2018 Free Software Foundation, Inc.
794 # Copyright (C) 2001-2020 Free Software Foundation, Inc.
798795 #
799796 # This file is free software; the Free Software Foundation
800797 # gives unlimited permission to copy and/or distribute it,
813810
814811 # Check to make sure that the build environment is sane. -*- Autoconf -*-
815812
816 # Copyright (C) 1996-2018 Free Software Foundation, Inc.
813 # Copyright (C) 1996-2020 Free Software Foundation, Inc.
817814 #
818815 # This file is free software; the Free Software Foundation
819816 # gives unlimited permission to copy and/or distribute it,
894891 rm -f conftest.file
895892 ])
896893
897 # Copyright (C) 2009-2018 Free Software Foundation, Inc.
894 # Copyright (C) 2009-2020 Free Software Foundation, Inc.
898895 #
899896 # This file is free software; the Free Software Foundation
900897 # gives unlimited permission to copy and/or distribute it,
954951 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
955952 ])
956953
957 # Copyright (C) 2001-2018 Free Software Foundation, Inc.
954 # Copyright (C) 2001-2020 Free Software Foundation, Inc.
958955 #
959956 # This file is free software; the Free Software Foundation
960957 # gives unlimited permission to copy and/or distribute it,
982979 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
983980 AC_SUBST([INSTALL_STRIP_PROGRAM])])
984981
985 # Copyright (C) 2006-2018 Free Software Foundation, Inc.
982 # Copyright (C) 2006-2020 Free Software Foundation, Inc.
986983 #
987984 # This file is free software; the Free Software Foundation
988985 # gives unlimited permission to copy and/or distribute it,
1001998
1002999 # Check how to create a tarball. -*- Autoconf -*-
10031000
1004 # Copyright (C) 2004-2018 Free Software Foundation, Inc.
1001 # Copyright (C) 2004-2020 Free Software Foundation, Inc.
10051002 #
10061003 # This file is free software; the Free Software Foundation
10071004 # gives unlimited permission to copy and/or distribute it,
22
33 scriptversion=2018-03-07.03; # UTC
44
5 # Copyright (C) 1999-2018 Free Software Foundation, Inc.
5 # Copyright (C) 1999-2020 Free Software Foundation, Inc.
66 # Written by Tom Tromey <tromey@cygnus.com>.
77 #
88 # This program is free software; you can redistribute it and/or modify
5252 MINGW*)
5353 file_conv=mingw
5454 ;;
55 CYGWIN*)
55 CYGWIN* | MSYS*)
5656 file_conv=cygwin
5757 ;;
5858 *)
6666 mingw/*)
6767 file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
6868 ;;
69 cygwin/*)
69 cygwin/* | msys/*)
7070 file=`cygpath -m "$file" || echo "$file"`
7171 ;;
7272 wine/*)
23322332 am_aux_dir=`cd "$ac_aux_dir" && pwd`
23332333
23342334 if test x"${MISSING+set}" != xset; then
2335 case $am_aux_dir in
2336 *\ * | *\ *)
2337 MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
2338 *)
2339 MISSING="\${SHELL} $am_aux_dir/missing" ;;
2340 esac
2335 MISSING="\${SHELL} '$am_aux_dir/missing'"
23412336 fi
23422337 # Use eval to expand $SHELL
23432338 if eval "$MISSING --is-lightweight"; then
1385813853 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
1385913854 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
1386013855 as_fn_error $? "Something went wrong bootstrapping makefile fragments
13861 for automatic dependency tracking. Try re-running configure with the
13856 for automatic dependency tracking. If GNU make was not used, consider
13857 re-running the configure script with MAKE=\"gmake\" (or whatever is
13858 necessary). You can also try re-running configure with the
1386213859 '--disable-dependency-tracking' option to at least be able to build
1386313860 the package (albeit without support for automatic dependency tracking).
1386413861 See \`config.log' for more details" "$LINENO" 5; }
22
33 scriptversion=2018-03-07.03; # UTC
44
5 # Copyright (C) 1999-2018 Free Software Foundation, Inc.
5 # Copyright (C) 1999-2020 Free Software Foundation, Inc.
66
77 # This program is free software; you can redistribute it and/or modify
88 # it under the terms of the GNU General Public License as published by
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
2323 #define LIBPAINTER_VERSION_MICRO 0
2424
2525 #define PT_FORMAT_a8b8g8r8 \
26 ((32 << 24) | (3 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8)
26 ((32 << 24) | (3 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8)
2727 #define PT_FORMAT_a8r8g8b8 \
28 ((32 << 24) | (2 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8)
28 ((32 << 24) | (2 << 16) | (8 << 12) | (8 << 8) | (8 << 4) | 8)
2929 #define PT_FORMAT_r5g6b5 \
30 ((16 << 24) | (2 << 16) | (0 << 12) | (5 << 8) | (6 << 4) | 5)
30 ((16 << 24) | (2 << 16) | (0 << 12) | (5 << 8) | (6 << 4) | 5)
3131 #define PT_FORMAT_a1r5g5b5 \
32 ((16 << 24) | (2 << 16) | (1 << 12) | (5 << 8) | (5 << 4) | 5)
32 ((16 << 24) | (2 << 16) | (1 << 12) | (5 << 8) | (5 << 4) | 5)
3333 #define PT_FORMAT_r3g3b2 \
34 ((8 << 24) | (2 << 16) | (0 << 12) | (3 << 8) | (3 << 4) | 2)
34 ((8 << 24) | (2 << 16) | (0 << 12) | (3 << 8) | (3 << 4) | 2)
3535
3636 #define PT_FORMAT_c1 \
37 ((1 << 24) | (4 << 16) | (0 << 12) | (0 << 8) | (0 << 4) | 0)
37 ((1 << 24) | (4 << 16) | (0 << 12) | (0 << 8) | (0 << 4) | 0)
3838 #define PT_FORMAT_c8 \
39 ((8 << 24) | (4 << 16) | (0 << 12) | (0 << 8) | (0 << 4) | 0)
39 ((8 << 24) | (4 << 16) | (0 << 12) | (0 << 8) | (0 << 4) | 0)
4040
4141 struct painter_bitmap
4242 {
5757
5858 #define PT_LINE_FLAGS_NONE 0
5959
60 /* reverse Windows X11 */
61 /* polish */
60 /* reverse Windows X11 */
61 /* polish */
6262 #define PT_ROP_0 0x00 /* 0 BLACKNESS GXclear */
6363 #define PT_ROP_DSon 0x11 /* DSon NOTSRCERASE GXnor */
6464 #define PT_ROP_DSna 0x22 /* DSna GXandInverted */
00 #!/bin/sh
11 # install - install a program, script, or datafile
22
3 scriptversion=2018-03-11.20; # UTC
3 scriptversion=2020-11-14.01; # UTC
44
55 # This originates from X11R5 (mit/util/scripts/install.sh), which was
66 # later released in X11R6 (xc/config/util/install.sh) with the
6868 # Desired mode of installed file.
6969 mode=0755
7070
71 # Create dirs (including intermediate dirs) using mode 755.
72 # This is like GNU 'install' as of coreutils 8.32 (2020).
73 mkdir_umask=22
74
75 backupsuffix=
7176 chgrpcmd=
7277 chmodcmd=$chmodprog
7378 chowncmd=
98103 --version display version info and exit.
99104
100105 -c (ignored)
101 -C install only if different (preserve the last data modification time)
106 -C install only if different (preserve data modification time)
102107 -d create directories instead of installing files.
103108 -g GROUP $chgrpprog installed files to GROUP.
104109 -m MODE $chmodprog installed files to MODE.
105110 -o USER $chownprog installed files to USER.
111 -p pass -p to $cpprog.
106112 -s $stripprog installed files.
113 -S SUFFIX attempt to back up existing files, with suffix SUFFIX.
107114 -t DIRECTORY install into DIRECTORY.
108115 -T report an error if DSTFILE is a directory.
109116
110117 Environment variables override the default commands:
111118 CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
112119 RMPROG STRIPPROG
120
121 By default, rm is invoked with -f; when overridden with RMPROG,
122 it's up to you to specify -f if you want it.
123
124 If -S is not specified, no backups are attempted.
125
126 Email bug reports to bug-automake@gnu.org.
127 Automake home page: https://www.gnu.org/software/automake/
113128 "
114129
115130 while test $# -ne 0; do
136151 -o) chowncmd="$chownprog $2"
137152 shift;;
138153
154 -p) cpprog="$cpprog -p";;
155
139156 -s) stripcmd=$stripprog;;
157
158 -S) backupsuffix="$2"
159 shift;;
140160
141161 -t)
142162 is_target_a_directory=always
254274 dstdir=$dst
255275 test -d "$dstdir"
256276 dstdir_status=$?
277 # Don't chown directories that already exist.
278 if test $dstdir_status = 0; then
279 chowncmd=""
280 fi
257281 else
258282
259283 # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
300324 if test $dstdir_status != 0; then
301325 case $posix_mkdir in
302326 '')
303 # Create intermediate dirs using mode 755 as modified by the umask.
304 # This is like FreeBSD 'install' as of 1997-10-28.
305 umask=`umask`
306 case $stripcmd.$umask in
307 # Optimize common cases.
308 *[2367][2367]) mkdir_umask=$umask;;
309 .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
310
311 *[0-7])
312 mkdir_umask=`expr $umask + 22 \
313 - $umask % 100 % 40 + $umask % 20 \
314 - $umask % 10 % 4 + $umask % 2
315 `;;
316 *) mkdir_umask=$umask,go-w;;
317 esac
318
319327 # With -d, create the new directory with the user-specified mode.
320328 # Otherwise, rely on $mkdir_umask.
321329 if test -n "$dir_arg"; then
325333 fi
326334
327335 posix_mkdir=false
328 case $umask in
329 *[123567][0-7][0-7])
330 # POSIX mkdir -p sets u+wx bits regardless of umask, which
331 # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
332 ;;
333 *)
334 # Note that $RANDOM variable is not portable (e.g. dash); Use it
335 # here however when possible just to lower collision chance.
336 tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
337
338 trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
339
340 # Because "mkdir -p" follows existing symlinks and we likely work
341 # directly in world-writeable /tmp, make sure that the '$tmpdir'
342 # directory is successfully created first before we actually test
343 # 'mkdir -p' feature.
344 if (umask $mkdir_umask &&
345 $mkdirprog $mkdir_mode "$tmpdir" &&
346 exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
347 then
348 if test -z "$dir_arg" || {
349 # Check for POSIX incompatibilities with -m.
350 # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
351 # other-writable bit of parent directory when it shouldn't.
352 # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
353 test_tmpdir="$tmpdir/a"
354 ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
355 case $ls_ld_tmpdir in
356 d????-?r-*) different_mode=700;;
357 d????-?--*) different_mode=755;;
358 *) false;;
359 esac &&
360 $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
361 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
362 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
363 }
364 }
365 then posix_mkdir=:
366 fi
367 rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
368 else
369 # Remove any dirs left behind by ancient mkdir implementations.
370 rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
371 fi
372 trap '' 0;;
373 esac;;
336 # The $RANDOM variable is not portable (e.g., dash). Use it
337 # here however when possible just to lower collision chance.
338 tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
339
340 trap '
341 ret=$?
342 rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
343 exit $ret
344 ' 0
345
346 # Because "mkdir -p" follows existing symlinks and we likely work
347 # directly in world-writeable /tmp, make sure that the '$tmpdir'
348 # directory is successfully created first before we actually test
349 # 'mkdir -p'.
350 if (umask $mkdir_umask &&
351 $mkdirprog $mkdir_mode "$tmpdir" &&
352 exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
353 then
354 if test -z "$dir_arg" || {
355 # Check for POSIX incompatibilities with -m.
356 # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
357 # other-writable bit of parent directory when it shouldn't.
358 # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
359 test_tmpdir="$tmpdir/a"
360 ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
361 case $ls_ld_tmpdir in
362 d????-?r-*) different_mode=700;;
363 d????-?--*) different_mode=755;;
364 *) false;;
365 esac &&
366 $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
367 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
368 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
369 }
370 }
371 then posix_mkdir=:
372 fi
373 rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
374 else
375 # Remove any dirs left behind by ancient mkdir implementations.
376 rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
377 fi
378 trap '' 0;;
374379 esac
375380
376381 if
381386 then :
382387 else
383388
384 # The umask is ridiculous, or mkdir does not conform to POSIX,
389 # mkdir does not conform to POSIX,
385390 # or it failed possibly due to a race condition. Create the
386391 # directory the slow way, step by step, checking for races as we go.
387392
410415 prefixes=
411416 else
412417 if $posix_mkdir; then
413 (umask=$mkdir_umask &&
418 (umask $mkdir_umask &&
414419 $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
415420 # Don't fail if two instances are running concurrently.
416421 test -d "$prefix" || exit 1
450455 trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
451456
452457 # Copy the file name to the temp name.
453 (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
458 (umask $cp_umask &&
459 { test -z "$stripcmd" || {
460 # Create $dsttmp read-write so that cp doesn't create it read-only,
461 # which would cause strip to fail.
462 if test -z "$doit"; then
463 : >"$dsttmp" # No need to fork-exec 'touch'.
464 else
465 $doit touch "$dsttmp"
466 fi
467 }
468 } &&
469 $doit_exec $cpprog "$src" "$dsttmp") &&
454470
455471 # and set any options; do chmod last to preserve setuid bits.
456472 #
476492 then
477493 rm -f "$dsttmp"
478494 else
495 # If $backupsuffix is set, and the file being installed
496 # already exists, attempt a backup. Don't worry if it fails,
497 # e.g., if mv doesn't support -f.
498 if test -n "$backupsuffix" && test -f "$dst"; then
499 $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
500 fi
501
479502 # Rename the file to the real destination.
480503 $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
481504
490513 # file should still install successfully.
491514 {
492515 test ! -f "$dst" ||
493 $doit $rmcmd -f "$dst" 2>/dev/null ||
516 $doit $rmcmd "$dst" 2>/dev/null ||
494517 { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
495 { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
518 { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
496519 } ||
497520 { echo "$0: cannot unlink or rename $dst" >&2
498521 (exit 1); exit 1
22
33 scriptversion=2018-03-07.03; # UTC
44
5 # Copyright (C) 1996-2018 Free Software Foundation, Inc.
5 # Copyright (C) 1996-2020 Free Software Foundation, Inc.
66 # Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
77
88 # This program is free software; you can redistribute it and/or modify
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
3333 {
3434 switch (rop)
3535 {
36 case PT_ROP_0: return 0;
37 case PT_ROP_DSon: return ~(src | dst);
38 case PT_ROP_DSna: return (~src) & dst;
39 case PT_ROP_Sn: return ~src;
40 case PT_ROP_SDna: return src & (~dst);
41 case PT_ROP_Dn: return ~(dst);
42 case PT_ROP_DSx: return src ^ dst;
43 case PT_ROP_DSan: return ~(src & dst);
44 case PT_ROP_DSa: return src & dst;
45 case PT_ROP_DSxn: return ~(src) ^ dst;
46 case PT_ROP_D: return dst;
47 case PT_ROP_DSno: return (~src) | dst;
48 case PT_ROP_S: return src;
49 case PT_ROP_SDno: return src | (~dst);
50 case PT_ROP_DSo: return src | dst;
51 case PT_ROP_1: return ~0;
36 case PT_ROP_0:
37 return 0;
38 case PT_ROP_DSon:
39 return ~(src | dst);
40 case PT_ROP_DSna:
41 return (~src) & dst;
42 case PT_ROP_Sn:
43 return ~src;
44 case PT_ROP_SDna:
45 return src & (~dst);
46 case PT_ROP_Dn:
47 return ~(dst);
48 case PT_ROP_DSx:
49 return src ^ dst;
50 case PT_ROP_DSan:
51 return ~(src & dst);
52 case PT_ROP_DSa:
53 return src & dst;
54 case PT_ROP_DSxn:
55 return ~(src) ^ dst;
56 case PT_ROP_D:
57 return dst;
58 case PT_ROP_DSno:
59 return (~src) | dst;
60 case PT_ROP_S:
61 return src;
62 case PT_ROP_SDno:
63 return src | (~dst);
64 case PT_ROP_DSo:
65 return src | dst;
66 case PT_ROP_1:
67 return ~0;
5268 }
5369 return dst;
5470 }
6278 int Bpp;
6379
6480 if ((x >= 0) && (x < bitmap->width) &&
65 (y >= 0) && (y < bitmap->height))
81 (y >= 0) && (y < bitmap->height))
6682 {
6783 bpp = bitmap->format >> 24;
6884 if (bpp < 8)
238254 int x, int y, int pixel, int pixel_format)
239255 {
240256 if ((painter->clip_valid == 0) ||
241 ((x >= painter->clip.x1) && (x < painter->clip.x2) &&
242 (y >= painter->clip.y1) && (y < painter->clip.y2)))
257 ((x >= painter->clip.x1) && (x < painter->clip.x2) &&
258 (y >= painter->clip.y1) && (y < painter->clip.y2)))
243259 {
244260 if ((x >= 0) && (x < bitmap->width) &&
245 (y >= 0) && (y < bitmap->height))
261 (y >= 0) && (y < bitmap->height))
246262 {
247263 pixel = pixel_convert(pixel, pixel_format, bitmap->format,
248264 painter->palette);
1919 #define __PAINTER_UTILS_H
2020
2121 #define SPLIT_a8r8g8b8(_c, _a, _r, _g, _b) \
22 do { \
23 _a = ((_c) & 0xff000000) >> 24; \
24 _r = ((_c) & 0x00ff0000) >> 16; \
25 _g = ((_c) & 0x0000ff00) >> 8; \
26 _b = ((_c) & 0x000000ff) >> 0; \
27 } while (0)
22 do { \
23 _a = ((_c) & 0xff000000) >> 24; \
24 _r = ((_c) & 0x00ff0000) >> 16; \
25 _g = ((_c) & 0x0000ff00) >> 8; \
26 _b = ((_c) & 0x000000ff) >> 0; \
27 } while (0)
2828
2929 #define SPLIT_a8b8g8r8(_c, _a, _r, _g, _b) \
30 do { \
31 _a = ((_c) & 0xff000000) >> 24; \
32 _b = ((_c) & 0x00ff0000) >> 16; \
33 _g = ((_c) & 0x0000ff00) >> 8; \
34 _r = ((_c) & 0x000000ff) >> 0; \
35 } while (0)
30 do { \
31 _a = ((_c) & 0xff000000) >> 24; \
32 _b = ((_c) & 0x00ff0000) >> 16; \
33 _g = ((_c) & 0x0000ff00) >> 8; \
34 _r = ((_c) & 0x000000ff) >> 0; \
35 } while (0)
3636
3737 #define SPLIT_a1r5g5b5(_c, _a, _r, _g, _b) \
38 do { \
39 _a = (((_c) >> 15) & 1) * 0xff; \
40 _r = (((_c) >> 7) & 0xf8) | (((_c) >> 12) & 0x7); \
41 _g = (((_c) >> 2) & 0xf8) | (((_c) >> 8) & 0x7); \
42 _b = (((_c) << 3) & 0xf8) | (((_c) >> 2) & 0x7); \
43 } while (0)
38 do { \
39 _a = (((_c) >> 15) & 1) * 0xff; \
40 _r = (((_c) >> 7) & 0xf8) | (((_c) >> 12) & 0x7); \
41 _g = (((_c) >> 2) & 0xf8) | (((_c) >> 8) & 0x7); \
42 _b = (((_c) << 3) & 0xf8) | (((_c) >> 2) & 0x7); \
43 } while (0)
4444
4545 #define SPLIT_r5g6b5(_c, _a, _r, _g, _b) \
46 do { \
47 _a = 0xff; \
48 _r = (((_c) >> 8) & 0xf8) | (((_c) >> 13) & 0x7); \
49 _g = (((_c) >> 3) & 0xfc) | (((_c) >> 9) & 0x3); \
50 _b = (((_c) << 3) & 0xf8) | (((_c) >> 2) & 0x7); \
51 } while (0)
46 do { \
47 _a = 0xff; \
48 _r = (((_c) >> 8) & 0xf8) | (((_c) >> 13) & 0x7); \
49 _g = (((_c) >> 3) & 0xfc) | (((_c) >> 9) & 0x3); \
50 _b = (((_c) << 3) & 0xf8) | (((_c) >> 2) & 0x7); \
51 } while (0)
5252
5353 #define SPLIT_r3g3b2(_c, _a, _r, _g, _b) \
54 do { \
55 _a = 0xff; \
56 _r = 0; \
57 _g = 0; \
58 _b = 0; \
59 } while (0)
54 do { \
55 _a = 0xff; \
56 _r = 0; \
57 _g = 0; \
58 _b = 0; \
59 } while (0)
6060
6161 #define MAKE_a1r5g5b5(_c, _a, _r, _g, _b) \
62 do { \
63 _c = (((_a) & 0xff) >> 7) << 15 | \
64 (((_r) & 0xff) >> 3) << 10 | \
65 (((_g) & 0xff) >> 3) << 5 | \
66 (((_b) & 0xff) >> 3) << 0; \
67 } while (0)
62 do { \
63 _c = (((_a) & 0xff) >> 7) << 15 | \
64 (((_r) & 0xff) >> 3) << 10 | \
65 (((_g) & 0xff) >> 3) << 5 | \
66 (((_b) & 0xff) >> 3) << 0; \
67 } while (0)
6868
6969 #define MAKE_r5g6b5(_c, _a, _r, _g, _b) \
70 do { \
71 _c = \
72 (((_r) & 0xff) >> 3) << 11 | \
73 (((_g) & 0xff) >> 2) << 5 | \
74 (((_b) & 0xff) >> 3) << 0; \
75 } while (0)
70 do { \
71 _c = \
72 (((_r) & 0xff) >> 3) << 11 | \
73 (((_g) & 0xff) >> 2) << 5 | \
74 (((_b) & 0xff) >> 3) << 0; \
75 } while (0)
7676
7777 #define MAKE_a8r8g8b8(_c, _a, _r, _g, _b) \
78 do { \
79 _c = ((_a) & 0xff) << 24 | \
80 ((_r) & 0xff) << 16 | \
81 ((_g) & 0xff) << 8 | \
82 ((_b) & 0xff) << 0; \
83 } while (0)
78 do { \
79 _c = ((_a) & 0xff) << 24 | \
80 ((_r) & 0xff) << 16 | \
81 ((_g) & 0xff) << 8 | \
82 ((_b) & 0xff) << 0; \
83 } while (0)
8484
8585 #define MAKE_a8b8g8r8(_c, _a, _r, _g, _b) \
86 do { \
87 _c = ((_a) & 0xff) << 24 | \
88 ((_b) & 0xff) << 16 | \
89 ((_g) & 0xff) << 8 | \
90 ((_r) & 0xff) << 0; \
91 } while (0)
86 do { \
87 _c = ((_a) & 0xff) << 24 | \
88 ((_b) & 0xff) << 16 | \
89 ((_g) & 0xff) << 8 | \
90 ((_r) & 0xff) << 0; \
91 } while (0)
9292
9393 struct painter_rect
9494 {
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
172172 $(am__extra_recursive_targets)
173173 AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
174174 cscope distdir distdir-am dist dist-all distcheck
175 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
176 $(LISP)config_ac-h.in
175 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
176 config_ac-h.in
177177 # Read a list of newline-separated strings from the standard input,
178178 # and print each of them once, without duplicates. Input order is
179179 # *not* preserved.
235235 DIST_ARCHIVES = $(distdir).tar.gz
236236 GZIP_ENV = --best
237237 DIST_TARGETS = dist-gzip
238 # Exists only to be overridden by the user if desired.
239 AM_DISTCHECK_DVI_TARGET = dvi
238240 distuninstallcheck_listfiles = find . -type f -print
239241 am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
240242 | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
641643 tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
642644 $(am__post_remove_distdir)
643645
646 dist-zstd: distdir
647 tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
648 $(am__post_remove_distdir)
649
644650 dist-tarZ: distdir
645651 @echo WARNING: "Support for distribution archives compressed with" \
646652 "legacy program 'compress' is deprecated." >&2
683689 eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
684690 *.zip*) \
685691 unzip $(distdir).zip ;;\
692 *.tar.zst*) \
693 zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
686694 esac
687695 chmod -R a-w $(distdir)
688696 chmod u+w $(distdir)
698706 $(DISTCHECK_CONFIGURE_FLAGS) \
699707 --srcdir=../.. --prefix="$$dc_install_base" \
700708 && $(MAKE) $(AM_MAKEFLAGS) \
701 && $(MAKE) $(AM_MAKEFLAGS) dvi \
709 && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
702710 && $(MAKE) $(AM_MAKEFLAGS) check \
703711 && $(MAKE) $(AM_MAKEFLAGS) install \
704712 && $(MAKE) $(AM_MAKEFLAGS) installcheck \
863871 am--refresh check check-am clean clean-cscope clean-generic \
864872 clean-libtool cscope cscopelist-am ctags ctags-am dist \
865873 dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
866 dist-xz dist-zip distcheck distclean distclean-generic \
867 distclean-hdr distclean-libtool distclean-tags distcleancheck \
868 distdir distuninstallcheck dvi dvi-am html html-am info \
869 info-am install install-am install-data install-data-am \
870 install-dvi install-dvi-am install-exec install-exec-am \
871 install-html install-html-am install-info install-info-am \
872 install-man install-pdf install-pdf-am install-pkgconfigDATA \
873 install-ps install-ps-am install-strip installcheck \
874 installcheck-am installdirs installdirs-am maintainer-clean \
875 maintainer-clean-generic mostlyclean mostlyclean-generic \
876 mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
877 uninstall-am uninstall-pkgconfigDATA
874 dist-xz dist-zip dist-zstd distcheck distclean \
875 distclean-generic distclean-hdr distclean-libtool \
876 distclean-tags distcleancheck distdir distuninstallcheck dvi \
877 dvi-am html html-am info info-am install install-am \
878 install-data install-data-am install-dvi install-dvi-am \
879 install-exec install-exec-am install-html install-html-am \
880 install-info install-info-am install-man install-pdf \
881 install-pdf-am install-pkgconfigDATA install-ps install-ps-am \
882 install-strip installcheck installcheck-am installdirs \
883 installdirs-am maintainer-clean maintainer-clean-generic \
884 mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
885 ps ps-am tags tags-am uninstall uninstall-am \
886 uninstall-pkgconfigDATA
878887
879888 .PRECIOUS: Makefile
880889
0 # generated automatically by aclocal 1.16.1 -*- Autoconf -*-
1
2 # Copyright (C) 1996-2018 Free Software Foundation, Inc.
0 # generated automatically by aclocal 1.16.3 -*- Autoconf -*-
1
2 # Copyright (C) 1996-2020 Free Software Foundation, Inc.
33
44 # This file is free software; the Free Software Foundation
55 # gives unlimited permission to copy and/or distribute it,
1919 If you have problems, you may need to regenerate the build system entirely.
2020 To do so, use the procedure documented by the package, typically 'autoreconf'.])])
2121
22 # Copyright (C) 2002-2018 Free Software Foundation, Inc.
22 # Copyright (C) 2002-2020 Free Software Foundation, Inc.
2323 #
2424 # This file is free software; the Free Software Foundation
2525 # gives unlimited permission to copy and/or distribute it,
3434 [am__api_version='1.16'
3535 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
3636 dnl require some minimum version. Point them to the right macro.
37 m4_if([$1], [1.16.1], [],
37 m4_if([$1], [1.16.3], [],
3838 [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
3939 ])
4040
5050 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
5151 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
5252 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
53 [AM_AUTOMAKE_VERSION([1.16.1])dnl
53 [AM_AUTOMAKE_VERSION([1.16.3])dnl
5454 m4_ifndef([AC_AUTOCONF_VERSION],
5555 [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
5656 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
5757
5858 # AM_AUX_DIR_EXPAND -*- Autoconf -*-
5959
60 # Copyright (C) 2001-2018 Free Software Foundation, Inc.
60 # Copyright (C) 2001-2020 Free Software Foundation, Inc.
6161 #
6262 # This file is free software; the Free Software Foundation
6363 # gives unlimited permission to copy and/or distribute it,
109109
110110 # AM_CONDITIONAL -*- Autoconf -*-
111111
112 # Copyright (C) 1997-2018 Free Software Foundation, Inc.
112 # Copyright (C) 1997-2020 Free Software Foundation, Inc.
113113 #
114114 # This file is free software; the Free Software Foundation
115115 # gives unlimited permission to copy and/or distribute it,
140140 Usually this means the macro was only invoked conditionally.]])
141141 fi])])
142142
143 # Copyright (C) 1999-2018 Free Software Foundation, Inc.
143 # Copyright (C) 1999-2020 Free Software Foundation, Inc.
144144 #
145145 # This file is free software; the Free Software Foundation
146146 # gives unlimited permission to copy and/or distribute it,
331331
332332 # Generate code to set up dependency tracking. -*- Autoconf -*-
333333
334 # Copyright (C) 1999-2018 Free Software Foundation, Inc.
334 # Copyright (C) 1999-2020 Free Software Foundation, Inc.
335335 #
336336 # This file is free software; the Free Software Foundation
337337 # gives unlimited permission to copy and/or distribute it,
370370 done
371371 if test $am_rc -ne 0; then
372372 AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
373 for automatic dependency tracking. Try re-running configure with the
373 for automatic dependency tracking. If GNU make was not used, consider
374 re-running the configure script with MAKE="gmake" (or whatever is
375 necessary). You can also try re-running configure with the
374376 '--disable-dependency-tracking' option to at least be able to build
375377 the package (albeit without support for automatic dependency tracking).])
376378 fi
397399
398400 # Do all the work for Automake. -*- Autoconf -*-
399401
400 # Copyright (C) 1996-2018 Free Software Foundation, Inc.
402 # Copyright (C) 1996-2020 Free Software Foundation, Inc.
401403 #
402404 # This file is free software; the Free Software Foundation
403405 # gives unlimited permission to copy and/or distribute it,
594596 done
595597 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
596598
597 # Copyright (C) 2001-2018 Free Software Foundation, Inc.
599 # Copyright (C) 2001-2020 Free Software Foundation, Inc.
598600 #
599601 # This file is free software; the Free Software Foundation
600602 # gives unlimited permission to copy and/or distribute it,
615617 fi
616618 AC_SUBST([install_sh])])
617619
618 # Copyright (C) 2003-2018 Free Software Foundation, Inc.
620 # Copyright (C) 2003-2020 Free Software Foundation, Inc.
619621 #
620622 # This file is free software; the Free Software Foundation
621623 # gives unlimited permission to copy and/or distribute it,
636638
637639 # Check to see how 'make' treats includes. -*- Autoconf -*-
638640
639 # Copyright (C) 2001-2018 Free Software Foundation, Inc.
641 # Copyright (C) 2001-2020 Free Software Foundation, Inc.
640642 #
641643 # This file is free software; the Free Software Foundation
642644 # gives unlimited permission to copy and/or distribute it,
679681
680682 # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
681683
682 # Copyright (C) 1997-2018 Free Software Foundation, Inc.
684 # Copyright (C) 1997-2020 Free Software Foundation, Inc.
683685 #
684686 # This file is free software; the Free Software Foundation
685687 # gives unlimited permission to copy and/or distribute it,
700702 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
701703 AC_REQUIRE_AUX_FILE([missing])dnl
702704 if test x"${MISSING+set}" != xset; then
703 case $am_aux_dir in
704 *\ * | *\ *)
705 MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
706 *)
707 MISSING="\${SHELL} $am_aux_dir/missing" ;;
708 esac
705 MISSING="\${SHELL} '$am_aux_dir/missing'"
709706 fi
710707 # Use eval to expand $SHELL
711708 if eval "$MISSING --is-lightweight"; then
718715
719716 # Helper functions for option handling. -*- Autoconf -*-
720717
721 # Copyright (C) 2001-2018 Free Software Foundation, Inc.
718 # Copyright (C) 2001-2020 Free Software Foundation, Inc.
722719 #
723720 # This file is free software; the Free Software Foundation
724721 # gives unlimited permission to copy and/or distribute it,
747744 AC_DEFUN([_AM_IF_OPTION],
748745 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
749746
750 # Copyright (C) 1999-2018 Free Software Foundation, Inc.
747 # Copyright (C) 1999-2020 Free Software Foundation, Inc.
751748 #
752749 # This file is free software; the Free Software Foundation
753750 # gives unlimited permission to copy and/or distribute it,
794791 # For backward compatibility.
795792 AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
796793
797 # Copyright (C) 2001-2018 Free Software Foundation, Inc.
794 # Copyright (C) 2001-2020 Free Software Foundation, Inc.
798795 #
799796 # This file is free software; the Free Software Foundation
800797 # gives unlimited permission to copy and/or distribute it,
813810
814811 # Check to make sure that the build environment is sane. -*- Autoconf -*-
815812
816 # Copyright (C) 1996-2018 Free Software Foundation, Inc.
813 # Copyright (C) 1996-2020 Free Software Foundation, Inc.
817814 #
818815 # This file is free software; the Free Software Foundation
819816 # gives unlimited permission to copy and/or distribute it,
894891 rm -f conftest.file
895892 ])
896893
897 # Copyright (C) 2009-2018 Free Software Foundation, Inc.
894 # Copyright (C) 2009-2020 Free Software Foundation, Inc.
898895 #
899896 # This file is free software; the Free Software Foundation
900897 # gives unlimited permission to copy and/or distribute it,
954951 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
955952 ])
956953
957 # Copyright (C) 2001-2018 Free Software Foundation, Inc.
954 # Copyright (C) 2001-2020 Free Software Foundation, Inc.
958955 #
959956 # This file is free software; the Free Software Foundation
960957 # gives unlimited permission to copy and/or distribute it,
982979 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
983980 AC_SUBST([INSTALL_STRIP_PROGRAM])])
984981
985 # Copyright (C) 2006-2018 Free Software Foundation, Inc.
982 # Copyright (C) 2006-2020 Free Software Foundation, Inc.
986983 #
987984 # This file is free software; the Free Software Foundation
988985 # gives unlimited permission to copy and/or distribute it,
1001998
1002999 # Check how to create a tarball. -*- Autoconf -*-
10031000
1004 # Copyright (C) 2004-2018 Free Software Foundation, Inc.
1001 # Copyright (C) 2004-2020 Free Software Foundation, Inc.
10051002 #
10061003 # This file is free software; the Free Software Foundation
10071004 # gives unlimited permission to copy and/or distribute it,
22
33 scriptversion=2018-03-07.03; # UTC
44
5 # Copyright (C) 1999-2018 Free Software Foundation, Inc.
5 # Copyright (C) 1999-2020 Free Software Foundation, Inc.
66 # Written by Tom Tromey <tromey@cygnus.com>.
77 #
88 # This program is free software; you can redistribute it and/or modify
5252 MINGW*)
5353 file_conv=mingw
5454 ;;
55 CYGWIN*)
55 CYGWIN* | MSYS*)
5656 file_conv=cygwin
5757 ;;
5858 *)
6666 mingw/*)
6767 file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
6868 ;;
69 cygwin/*)
69 cygwin/* | msys/*)
7070 file=`cygpath -m "$file" || echo "$file"`
7171 ;;
7272 wine/*)
23362336 am_aux_dir=`cd "$ac_aux_dir" && pwd`
23372337
23382338 if test x"${MISSING+set}" != xset; then
2339 case $am_aux_dir in
2340 *\ * | *\ *)
2341 MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
2342 *)
2343 MISSING="\${SHELL} $am_aux_dir/missing" ;;
2344 esac
2339 MISSING="\${SHELL} '$am_aux_dir/missing'"
23452340 fi
23462341 # Use eval to expand $SHELL
23472342 if eval "$MISSING --is-lightweight"; then
1230712302 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the assembler ($NASM $NAFLAGS) works" >&5
1230812303 $as_echo_n "checking whether the assembler ($NASM $NAFLAGS) works... " >&6; }
1230912304 cat > conftest.asm <<EOF
12310 %line 12311 "configure"
12305 %line 12306 "configure"
1231112306 section .text
1231212307 global _nasmfunc, nasmfunc
1231312308 _nasmfunc:
1252612521 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the assembler ($NASM $NAFLAGS) works" >&5
1252712522 $as_echo_n "checking whether the assembler ($NASM $NAFLAGS) works... " >&6; }
1252812523 cat > conftest.asm <<EOF
12529 %line 12530 "configure"
12524 %line 12525 "configure"
1253012525 section .text
1253112526 global _nasmfunc, nasmfunc
1253212527 _nasmfunc:
1432514320 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
1432614321 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
1432714322 as_fn_error $? "Something went wrong bootstrapping makefile fragments
14328 for automatic dependency tracking. Try re-running configure with the
14323 for automatic dependency tracking. If GNU make was not used, consider
14324 re-running the configure script with MAKE=\"gmake\" (or whatever is
14325 necessary). You can also try re-running configure with the
1432914326 '--disable-dependency-tracking' option to at least be able to build
1433014327 the package (albeit without support for automatic dependency tracking).
1433114328 See \`config.log' for more details" "$LINENO" 5; }
22
33 scriptversion=2018-03-07.03; # UTC
44
5 # Copyright (C) 1999-2018 Free Software Foundation, Inc.
5 # Copyright (C) 1999-2020 Free Software Foundation, Inc.
66
77 # This program is free software; you can redistribute it and/or modify
88 # it under the terms of the GNU General Public License as published by
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
00 #!/bin/sh
11 # install - install a program, script, or datafile
22
3 scriptversion=2018-03-11.20; # UTC
3 scriptversion=2020-11-14.01; # UTC
44
55 # This originates from X11R5 (mit/util/scripts/install.sh), which was
66 # later released in X11R6 (xc/config/util/install.sh) with the
6868 # Desired mode of installed file.
6969 mode=0755
7070
71 # Create dirs (including intermediate dirs) using mode 755.
72 # This is like GNU 'install' as of coreutils 8.32 (2020).
73 mkdir_umask=22
74
75 backupsuffix=
7176 chgrpcmd=
7277 chmodcmd=$chmodprog
7378 chowncmd=
98103 --version display version info and exit.
99104
100105 -c (ignored)
101 -C install only if different (preserve the last data modification time)
106 -C install only if different (preserve data modification time)
102107 -d create directories instead of installing files.
103108 -g GROUP $chgrpprog installed files to GROUP.
104109 -m MODE $chmodprog installed files to MODE.
105110 -o USER $chownprog installed files to USER.
111 -p pass -p to $cpprog.
106112 -s $stripprog installed files.
113 -S SUFFIX attempt to back up existing files, with suffix SUFFIX.
107114 -t DIRECTORY install into DIRECTORY.
108115 -T report an error if DSTFILE is a directory.
109116
110117 Environment variables override the default commands:
111118 CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
112119 RMPROG STRIPPROG
120
121 By default, rm is invoked with -f; when overridden with RMPROG,
122 it's up to you to specify -f if you want it.
123
124 If -S is not specified, no backups are attempted.
125
126 Email bug reports to bug-automake@gnu.org.
127 Automake home page: https://www.gnu.org/software/automake/
113128 "
114129
115130 while test $# -ne 0; do
136151 -o) chowncmd="$chownprog $2"
137152 shift;;
138153
154 -p) cpprog="$cpprog -p";;
155
139156 -s) stripcmd=$stripprog;;
157
158 -S) backupsuffix="$2"
159 shift;;
140160
141161 -t)
142162 is_target_a_directory=always
254274 dstdir=$dst
255275 test -d "$dstdir"
256276 dstdir_status=$?
277 # Don't chown directories that already exist.
278 if test $dstdir_status = 0; then
279 chowncmd=""
280 fi
257281 else
258282
259283 # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
300324 if test $dstdir_status != 0; then
301325 case $posix_mkdir in
302326 '')
303 # Create intermediate dirs using mode 755 as modified by the umask.
304 # This is like FreeBSD 'install' as of 1997-10-28.
305 umask=`umask`
306 case $stripcmd.$umask in
307 # Optimize common cases.
308 *[2367][2367]) mkdir_umask=$umask;;
309 .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
310
311 *[0-7])
312 mkdir_umask=`expr $umask + 22 \
313 - $umask % 100 % 40 + $umask % 20 \
314 - $umask % 10 % 4 + $umask % 2
315 `;;
316 *) mkdir_umask=$umask,go-w;;
317 esac
318
319327 # With -d, create the new directory with the user-specified mode.
320328 # Otherwise, rely on $mkdir_umask.
321329 if test -n "$dir_arg"; then
325333 fi
326334
327335 posix_mkdir=false
328 case $umask in
329 *[123567][0-7][0-7])
330 # POSIX mkdir -p sets u+wx bits regardless of umask, which
331 # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
332 ;;
333 *)
334 # Note that $RANDOM variable is not portable (e.g. dash); Use it
335 # here however when possible just to lower collision chance.
336 tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
337
338 trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
339
340 # Because "mkdir -p" follows existing symlinks and we likely work
341 # directly in world-writeable /tmp, make sure that the '$tmpdir'
342 # directory is successfully created first before we actually test
343 # 'mkdir -p' feature.
344 if (umask $mkdir_umask &&
345 $mkdirprog $mkdir_mode "$tmpdir" &&
346 exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
347 then
348 if test -z "$dir_arg" || {
349 # Check for POSIX incompatibilities with -m.
350 # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
351 # other-writable bit of parent directory when it shouldn't.
352 # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
353 test_tmpdir="$tmpdir/a"
354 ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
355 case $ls_ld_tmpdir in
356 d????-?r-*) different_mode=700;;
357 d????-?--*) different_mode=755;;
358 *) false;;
359 esac &&
360 $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
361 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
362 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
363 }
364 }
365 then posix_mkdir=:
366 fi
367 rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
368 else
369 # Remove any dirs left behind by ancient mkdir implementations.
370 rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
371 fi
372 trap '' 0;;
373 esac;;
336 # The $RANDOM variable is not portable (e.g., dash). Use it
337 # here however when possible just to lower collision chance.
338 tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
339
340 trap '
341 ret=$?
342 rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
343 exit $ret
344 ' 0
345
346 # Because "mkdir -p" follows existing symlinks and we likely work
347 # directly in world-writeable /tmp, make sure that the '$tmpdir'
348 # directory is successfully created first before we actually test
349 # 'mkdir -p'.
350 if (umask $mkdir_umask &&
351 $mkdirprog $mkdir_mode "$tmpdir" &&
352 exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
353 then
354 if test -z "$dir_arg" || {
355 # Check for POSIX incompatibilities with -m.
356 # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
357 # other-writable bit of parent directory when it shouldn't.
358 # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
359 test_tmpdir="$tmpdir/a"
360 ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
361 case $ls_ld_tmpdir in
362 d????-?r-*) different_mode=700;;
363 d????-?--*) different_mode=755;;
364 *) false;;
365 esac &&
366 $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
367 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
368 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
369 }
370 }
371 then posix_mkdir=:
372 fi
373 rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
374 else
375 # Remove any dirs left behind by ancient mkdir implementations.
376 rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
377 fi
378 trap '' 0;;
374379 esac
375380
376381 if
381386 then :
382387 else
383388
384 # The umask is ridiculous, or mkdir does not conform to POSIX,
389 # mkdir does not conform to POSIX,
385390 # or it failed possibly due to a race condition. Create the
386391 # directory the slow way, step by step, checking for races as we go.
387392
410415 prefixes=
411416 else
412417 if $posix_mkdir; then
413 (umask=$mkdir_umask &&
418 (umask $mkdir_umask &&
414419 $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
415420 # Don't fail if two instances are running concurrently.
416421 test -d "$prefix" || exit 1
450455 trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
451456
452457 # Copy the file name to the temp name.
453 (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
458 (umask $cp_umask &&
459 { test -z "$stripcmd" || {
460 # Create $dsttmp read-write so that cp doesn't create it read-only,
461 # which would cause strip to fail.
462 if test -z "$doit"; then
463 : >"$dsttmp" # No need to fork-exec 'touch'.
464 else
465 $doit touch "$dsttmp"
466 fi
467 }
468 } &&
469 $doit_exec $cpprog "$src" "$dsttmp") &&
454470
455471 # and set any options; do chmod last to preserve setuid bits.
456472 #
476492 then
477493 rm -f "$dsttmp"
478494 else
495 # If $backupsuffix is set, and the file being installed
496 # already exists, attempt a backup. Don't worry if it fails,
497 # e.g., if mv doesn't support -f.
498 if test -n "$backupsuffix" && test -f "$dst"; then
499 $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
500 fi
501
479502 # Rename the file to the real destination.
480503 $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
481504
490513 # file should still install successfully.
491514 {
492515 test ! -f "$dst" ||
493 $doit $rmcmd -f "$dst" 2>/dev/null ||
516 $doit $rmcmd "$dst" 2>/dev/null ||
494517 { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
495 { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
518 { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
496519 } ||
497520 { echo "$0: cannot unlink or rename $dst" >&2
498521 (exit 1); exit 1
22
33 scriptversion=2018-03-07.03; # UTC
44
5 # Copyright (C) 1996-2018 Free Software Foundation, Inc.
5 # Copyright (C) 1996-2020 Free Software Foundation, Inc.
66 # Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
77
88 # This program is free software; you can redistribute it and/or modify
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
4848 {
4949 LLOGLN(10, ("rfx_encode_component_rlgr1_amd64_sse2:"));
5050 if (rfxcodec_encode_dwt_shift_amd64_sse2(qtable, data, enc->dwt_buffer1,
51 enc->dwt_buffer) != 0)
51 enc->dwt_buffer) != 0)
5252 {
5353 return 1;
5454 }
6464 {
6565 LLOGLN(10, ("rfx_encode_component_rlgr3_amd64_sse2:"));
6666 if (rfxcodec_encode_dwt_shift_amd64_sse2(qtable, data, enc->dwt_buffer1,
67 enc->dwt_buffer) != 0)
67 enc->dwt_buffer) != 0)
6868 {
6969 return 1;
7070 }
8080 {
8181 LLOGLN(10, ("rfx_encode_component_rlgr1_amd64_sse41:"));
8282 if (rfxcodec_encode_dwt_shift_amd64_sse41(qtable, data, enc->dwt_buffer1,
83 enc->dwt_buffer) != 0)
83 enc->dwt_buffer) != 0)
8484 {
8585 return 1;
8686 }
9696 {
9797 LLOGLN(10, ("rfx_encode_component_rlgr3_amd64_sse41:"));
9898 if (rfxcodec_encode_dwt_shift_amd64_sse41(qtable, data, enc->dwt_buffer1,
99 enc->dwt_buffer) != 0)
99 enc->dwt_buffer) != 0)
100100 {
101101 return 1;
102102 }
3131 typedef struct _RFX_BITSTREAM RFX_BITSTREAM;
3232
3333 #define rfx_bitstream_attach(bs, _buffer, _nbytes) do { \
34 bs.buffer = (uint8 *) (_buffer); \
35 bs.nbytes = (_nbytes); \
36 bs.byte_pos = 0; \
37 bs.bits_left = 8; } while (0)
34 bs.buffer = (uint8 *) (_buffer); \
35 bs.nbytes = (_nbytes); \
36 bs.byte_pos = 0; \
37 bs.bits_left = 8; } while (0)
3838
3939 #define rfx_bitstream_get_bits(bs, _nbits, _r) do { \
40 int nbits = _nbits; \
41 int b; \
42 uint16 n = 0; \
43 while (bs.byte_pos < bs.nbytes && nbits > 0) \
44 { \
45 b = nbits; \
46 if (b > bs.bits_left) \
47 b = bs.bits_left; \
48 if (n) \
49 n <<= b; \
50 n |= (bs.buffer[bs.byte_pos] >> (bs.bits_left - b)) & ((1 << b) - 1); \
51 bs.bits_left -= b; \
52 nbits -= b; \
53 if (bs.bits_left == 0) \
40 int nbits = _nbits; \
41 int b; \
42 uint16 n = 0; \
43 while (bs.byte_pos < bs.nbytes && nbits > 0) \
5444 { \
55 bs.bits_left = 8; \
56 bs.byte_pos++; \
45 b = nbits; \
46 if (b > bs.bits_left) \
47 b = bs.bits_left; \
48 if (n) \
49 n <<= b; \
50 n |= (bs.buffer[bs.byte_pos] >> (bs.bits_left - b)) & ((1 << b) - 1); \
51 bs.bits_left -= b; \
52 nbits -= b; \
53 if (bs.bits_left == 0) \
54 { \
55 bs.bits_left = 8; \
56 bs.byte_pos++; \
57 } \
5758 } \
58 } \
59 _r = n; } while (0)
59 _r = n; } while (0)
6060
6161 #define rfx_bitstream_put_bits(bs, _bits, _nbits) do { \
62 uint16 bits = (_bits); \
63 int nbits = (_nbits); \
64 int b; \
65 while (bs.byte_pos < bs.nbytes && nbits > 0) \
66 { \
67 b = nbits; \
68 if (b > bs.bits_left) \
69 b = bs.bits_left; \
70 bs.buffer[bs.byte_pos] &= ~((1 << bs.bits_left) - 1); \
71 bs.buffer[bs.byte_pos] |= ((bits >> (nbits - b)) & ((1 << b) - 1)) << (bs.bits_left - b); \
72 bs.bits_left -= b; \
73 nbits -= b; \
74 if (bs.bits_left == 0) \
62 uint16 bits = (_bits); \
63 int nbits = (_nbits); \
64 int b; \
65 while (bs.byte_pos < bs.nbytes && nbits > 0) \
7566 { \
76 bs.bits_left = 8; \
77 bs.byte_pos++; \
78 } \
79 } } while (0)
67 b = nbits; \
68 if (b > bs.bits_left) \
69 b = bs.bits_left; \
70 bs.buffer[bs.byte_pos] &= ~((1 << bs.bits_left) - 1); \
71 bs.buffer[bs.byte_pos] |= ((bits >> (nbits - b)) & ((1 << b) - 1)) << (bs.bits_left - b); \
72 bs.bits_left -= b; \
73 nbits -= b; \
74 if (bs.bits_left == 0) \
75 { \
76 bs.bits_left = 8; \
77 bs.byte_pos++; \
78 } \
79 } } while (0)
8080
8181 #define rfx_bitstream_eos(_bs) ((_bs).byte_pos >= (_bs).nbytes)
8282 #define rfx_bitstream_left(_bs) ((_bs).byte_pos >= (_bs).nbytes ? 0 : ((_bs).nbytes - (_bs).byte_pos - 1) * 8 + (_bs)->bits_left)
5050 #define stream_write_uint32(_s, _v) do { ((uint32 *) ((_s)->p))[0] = _v; (_s)->p += 4; } while (0)
5151 #else
5252 #define stream_read_uint8(_s, _v) do { \
53 _v = ((uint8 *) ((_s)->p))[0]; \
54 (_s)->p += 1; \
55 } while (0)
53 _v = ((uint8 *) ((_s)->p))[0]; \
54 (_s)->p += 1; \
55 } while (0)
5656 #define stream_read_uint16(_s, _v) do { \
57 _v = (((uint8 *) ((_s)->p))[0]) | \
58 ((((uint8 *) ((_s)->p))[1]) << 8); \
59 (_s)->p += 2; \
60 } while (0)
57 _v = (((uint8 *) ((_s)->p))[0]) | \
58 ((((uint8 *) ((_s)->p))[1]) << 8); \
59 (_s)->p += 2; \
60 } while (0)
6161 #define stream_read_uint32(_s, _v) do { \
62 _v = (((uint8 *) ((_s)->p))[0]) | \
63 ((((uint8 *) ((_s)->p))[1]) << 8) | \
64 ((((uint8 *) ((_s)->p))[2]) << 16) | \
65 ((((uint8 *) ((_s)->p))[3]) << 24); \
66 (_s)->p += 4; \
67 } while (0)
62 _v = (((uint8 *) ((_s)->p))[0]) | \
63 ((((uint8 *) ((_s)->p))[1]) << 8) | \
64 ((((uint8 *) ((_s)->p))[2]) << 16) | \
65 ((((uint8 *) ((_s)->p))[3]) << 24); \
66 (_s)->p += 4; \
67 } while (0)
6868 #define stream_write_uint8(_s, _v) do { \
69 ((uint8 *) ((_s)->p))[0] = _v; \
70 (_s)->p += 1; \
71 } while (0)
69 ((uint8 *) ((_s)->p))[0] = _v; \
70 (_s)->p += 1; \
71 } while (0)
7272 #define stream_write_uint16(_s, _v) do { \
73 ((uint8 *) ((_s)->p))[0] = (uint8) (_v); \
74 ((uint8 *) ((_s)->p))[1] = (uint8) ((_v) >> 8); \
75 (_s)->p += 2; \
76 } while (0)
73 ((uint8 *) ((_s)->p))[0] = (uint8) (_v); \
74 ((uint8 *) ((_s)->p))[1] = (uint8) ((_v) >> 8); \
75 (_s)->p += 2; \
76 } while (0)
7777 #define stream_write_uint32(_s, _v) do { \
78 ((uint8 *) ((_s)->p))[0] = (uint8) (_v); \
79 ((uint8 *) ((_s)->p))[1] = (uint8) ((_v) >> 8); \
80 ((uint8 *) ((_s)->p))[2] = (uint8) ((_v) >> 16); \
81 ((uint8 *) ((_s)->p))[3] = (uint8) ((_v) >> 24); \
82 (_s)->p += 4; \
83 } while (0)
78 ((uint8 *) ((_s)->p))[0] = (uint8) (_v); \
79 ((uint8 *) ((_s)->p))[1] = (uint8) ((_v) >> 8); \
80 ((uint8 *) ((_s)->p))[2] = (uint8) ((_v) >> 16); \
81 ((uint8 *) ((_s)->p))[3] = (uint8) ((_v) >> 24); \
82 (_s)->p += 4; \
83 } while (0)
8484 #endif
8585
8686 #define stream_seek(_s, _n) (_s)->p += _n
105105 */
106106 #if defined(__GNUC__)
107107 #define GBSR(_in, _r) do { \
108 _r = __builtin_clz(_in) ^ 31; \
109 } while (0)
108 _r = __builtin_clz(_in) ^ 31; \
109 } while (0)
110110 #elif defined(_MSC_VER) && (_MSC_VER > 1000)
111111 #define GBSR(_in, _r) do { \
112 unsigned long rv = 0; \
113 _BitScanReverse(&rv, _in); \
114 _r = rv; \
115 } while (0)
112 unsigned long rv = 0; \
113 _BitScanReverse(&rv, _in); \
114 _r = rv; \
115 } while (0)
116116 #else
117117 #define GBSR(_in, _r) do { \
118 int rv = -1; \
119 int x = _in; \
120 while (x != 0) \
121 { \
122 rv++; \
123 x = x >> 1; \
124 } \
125 _r = rv; \
126 } while (0)
118 int rv = -1; \
119 int x = _in; \
120 while (x != 0) \
121 { \
122 rv++; \
123 x = x >> 1; \
124 } \
125 _r = rv; \
126 } while (0)
127127 #endif
128128
129129 #endif
2121 struct rfxencode;
2222
2323 typedef int (*rfx_encode_rgb_to_yuv_proc)(struct rfxencode *enc,
24 const char *rgb_data,
25 int width, int height,
26 int stride_bytes);
24 const char *rgb_data,
25 int width, int height,
26 int stride_bytes);
2727 typedef int (*rfx_encode_argb_to_yuva_proc)(struct rfxencode *enc,
28 const char *argb_data,
29 int width, int height,
30 int stride_bytes);
28 const char *argb_data,
29 int width, int height,
30 int stride_bytes);
3131 typedef int (*rfx_encode_proc)(struct rfxencode *enc, const char *qtable,
3232 const uint8 *data,
3333 uint8 *buffer, int buffer_size, int *size);
7474 #if 0
7575 /*****************************************************************************/
7676 #define DELTA_ONE \
77 do { \
78 delta = src8[cx] - src8[0]; \
79 is_neg = (delta >> 7) & 1; \
80 dst8[cx] = (((delta ^ -is_neg) + is_neg) << 1) - is_neg; \
81 src8++; \
82 dst8++; \
83 } while (0)
77 do { \
78 delta = src8[cx] - src8[0]; \
79 is_neg = (delta >> 7) & 1; \
80 dst8[cx] = (((delta ^ -is_neg) + is_neg) << 1) - is_neg; \
81 src8++; \
82 dst8++; \
83 } while (0)
8484
8585 /*****************************************************************************/
8686 static int
4343 #define DQ_GR (3) /* decrease in kp after zero symbol in GR mode */
4444
4545 #define GetNextInput do { \
46 input = *coef; \
47 coef++; \
48 coef_size--; \
49 } while (0)
46 input = *coef; \
47 coef++; \
48 coef_size--; \
49 } while (0)
5050
5151 #define CheckWrite do { \
52 while (bit_count >= 8) \
53 { \
54 bit_count -= 8; \
55 *cdata = bits >> bit_count; \
56 cdata++; \
57 } \
58 } while (0)
52 while (bit_count >= 8) \
53 { \
54 bit_count -= 8; \
55 *cdata = bits >> bit_count; \
56 cdata++; \
57 } \
58 } while (0)
5959
6060 /* output GR code for (mag - 1) */
6161 #define CodeGR(_krp, _lmag) do { \
62 int lkr = _krp >> LSGR; \
63 /* unary part of GR code */ \
64 int lvk = _lmag >> lkr; \
65 int llvk = lvk; \
66 while (llvk >= 8) \
67 { \
68 bits <<= 8; \
69 bits |= 0xFF; \
70 llvk -= 8; \
71 *cdata = bits >> bit_count; \
72 cdata++; \
73 } \
74 bits <<= llvk; \
75 bits |= (1 << llvk) - 1; \
76 bit_count += llvk; \
77 bits <<= 1; \
78 bit_count++; \
79 CheckWrite; \
80 /* remainder part of GR code, if needed */ \
81 if (lkr) \
82 { \
83 bits <<= lkr; \
84 bits |= _lmag & ((1 << lkr) - 1); \
85 bit_count += lkr; \
86 } \
87 /* update _krp, only if it is not equal to 1 */ \
88 if (lvk == 0) \
89 { \
90 _krp = MAX(0, _krp - 2); \
91 } \
92 else if (lvk > 1) \
93 { \
94 _krp = MIN(KPMAX, _krp + lvk); \
95 } \
96 } while (0)
62 int lkr = _krp >> LSGR; \
63 /* unary part of GR code */ \
64 int lvk = _lmag >> lkr; \
65 int llvk = lvk; \
66 while (llvk >= 8) \
67 { \
68 bits <<= 8; \
69 bits |= 0xFF; \
70 llvk -= 8; \
71 *cdata = bits >> bit_count; \
72 cdata++; \
73 } \
74 bits <<= llvk; \
75 bits |= (1 << llvk) - 1; \
76 bit_count += llvk; \
77 bits <<= 1; \
78 bit_count++; \
79 CheckWrite; \
80 /* remainder part of GR code, if needed */ \
81 if (lkr) \
82 { \
83 bits <<= lkr; \
84 bits |= _lmag & ((1 << lkr) - 1); \
85 bit_count += lkr; \
86 } \
87 /* update _krp, only if it is not equal to 1 */ \
88 if (lvk == 0) \
89 { \
90 _krp = MAX(0, _krp - 2); \
91 } \
92 else if (lvk > 1) \
93 { \
94 _krp = MIN(KPMAX, _krp + lvk); \
95 } \
96 } while (0)
9797
9898 int
9999 rfx_encode_diff_rlgr1(sint16 *coef, uint8 *cdata, int cdata_size)
4343 #define DQ_GR (3) /* decrease in kp after zero symbol in GR mode */
4444
4545 #define GetNextInput do { \
46 input = *coef; \
47 coef++; \
48 coef_size--; \
49 } while (0)
46 input = *coef; \
47 coef++; \
48 coef_size--; \
49 } while (0)
5050
5151 #define CheckWrite do { \
52 while (bit_count >= 8) \
53 { \
54 bit_count -= 8; \
55 *cdata = bits >> bit_count; \
56 cdata++; \
57 } \
58 } while (0)
52 while (bit_count >= 8) \
53 { \
54 bit_count -= 8; \
55 *cdata = bits >> bit_count; \
56 cdata++; \
57 } \
58 } while (0)
5959
6060 /* output GR code for (mag - 1) */
6161 #define CodeGR(_krp, _lmag) do { \
62 int lkr = _krp >> LSGR; \
63 /* unary part of GR code */ \
64 int lvk = _lmag >> lkr; \
65 int llvk = lvk; \
66 while (llvk >= 8) \
67 { \
68 bits <<= 8; \
69 bits |= 0xFF; \
70 llvk -= 8; \
71 *cdata = bits >> bit_count; \
72 cdata++; \
73 } \
74 bits <<= llvk; \
75 bits |= (1 << llvk) - 1; \
76 bit_count += llvk; \
77 bits <<= 1; \
78 bit_count++; \
79 CheckWrite; \
80 /* remainder part of GR code, if needed */ \
81 if (lkr) \
82 { \
83 bits <<= lkr; \
84 bits |= _lmag & ((1 << lkr) - 1); \
85 bit_count += lkr; \
86 } \
87 /* update _krp, only if it is not equal to 1 */ \
88 if (lvk == 0) \
89 { \
90 _krp = MAX(0, _krp - 2); \
91 } \
92 else if (lvk > 1) \
93 { \
94 _krp = MIN(KPMAX, _krp + lvk); \
95 } \
96 } while (0)
62 int lkr = _krp >> LSGR; \
63 /* unary part of GR code */ \
64 int lvk = _lmag >> lkr; \
65 int llvk = lvk; \
66 while (llvk >= 8) \
67 { \
68 bits <<= 8; \
69 bits |= 0xFF; \
70 llvk -= 8; \
71 *cdata = bits >> bit_count; \
72 cdata++; \
73 } \
74 bits <<= llvk; \
75 bits |= (1 << llvk) - 1; \
76 bit_count += llvk; \
77 bits <<= 1; \
78 bit_count++; \
79 CheckWrite; \
80 /* remainder part of GR code, if needed */ \
81 if (lkr) \
82 { \
83 bits <<= lkr; \
84 bits |= _lmag & ((1 << lkr) - 1); \
85 bit_count += lkr; \
86 } \
87 /* update _krp, only if it is not equal to 1 */ \
88 if (lvk == 0) \
89 { \
90 _krp = MAX(0, _krp - 2); \
91 } \
92 else if (lvk > 1) \
93 { \
94 _krp = MIN(KPMAX, _krp + lvk); \
95 } \
96 } while (0)
9797
9898 int
9999 rfx_encode_diff_rlgr3(sint16 *coef, uint8 *cdata, int cdata_size)
4949 #if 0
5050 #define DIVROUND(_d1, _d2) \
5151 (_d1) < 0 ? \
52 ((_d1) - ((_d2) / 2)) / (_d2) : \
53 ((_d1) + ((_d2) / 2)) / (_d2)
52 ((_d1) - ((_d2) / 2)) / (_d2) : \
53 ((_d1) + ((_d2) / 2)) / (_d2)
5454
5555 /******************************************************************************/
5656 static int
4141
4242 /* Returns the least number of bits required to represent a given value */
4343 #define GetMinBits(_val, _nbits) \
44 do { \
45 uint32 _v = _val; \
46 _nbits = 0; \
47 while (_v) \
48 { \
49 _v >>= 1; \
50 _nbits++; \
51 } \
52 } while (0)
44 do { \
45 uint32 _v = _val; \
46 _nbits = 0; \
47 while (_v) \
48 { \
49 _v >>= 1; \
50 _nbits++; \
51 } \
52 } while (0)
5353
5454 /*
5555 * Update the passed parameter and clamp it to the range [0, KPMAX]
5656 * Return the value of parameter right-shifted by LSGR
5757 */
5858 #define UpdateParam(_param, _deltaP, _k) \
59 do { \
60 _param += _deltaP; \
61 if (_param > KPMAX) \
62 { \
63 _param = KPMAX; \
64 } \
65 if (_param < 0) \
66 { \
67 _param = 0; \
68 } \
69 _k = (_param >> LSGR); \
70 } while (0)
59 do { \
60 _param += _deltaP; \
61 if (_param > KPMAX) \
62 { \
63 _param = KPMAX; \
64 } \
65 if (_param < 0) \
66 { \
67 _param = 0; \
68 } \
69 _k = (_param >> LSGR); \
70 } while (0)
7171
7272 /* Returns the next coefficient (a signed int) to encode, from the input stream */
7373 #define GetNextInput(_n) \
74 do { \
75 if (data_size > 0) \
76 { \
77 _n = *data++; \
78 data_size--; \
79 } \
80 else \
81 { \
82 _n = 0; \
83 } \
84 } while (0)
74 do { \
75 if (data_size > 0) \
76 { \
77 _n = *data++; \
78 data_size--; \
79 } \
80 else \
81 { \
82 _n = 0; \
83 } \
84 } while (0)
8585
8686 /* Emit bitPattern to the output bitstream */
8787 #define OutputBits(_numBits, _bitPattern) rfx_bitstream_put_bits(bs, _bitPattern, _numBits)
8888
8989 /* Emit a bit (0 or 1), count number of times, to the output bitstream */
9090 #define OutputBit(_count, _bit) \
91 do \
92 { \
93 uint16 b = (_bit ? 0xFFFF : 0); \
94 int c = _count; \
95 for (; c > 0; c -= 16) \
96 { \
97 rfx_bitstream_put_bits(bs, b, (c > 16 ? 16 : c)); \
98 } \
99 } while (0)
91 do \
92 { \
93 uint16 b = (_bit ? 0xFFFF : 0); \
94 int c = _count; \
95 for (; c > 0; c -= 16) \
96 { \
97 rfx_bitstream_put_bits(bs, b, (c > 16 ? 16 : c)); \
98 } \
99 } while (0)
100100
101101 /* Converts the input value to (2 * abs(input) - sign(input)), where sign(input) = (input < 0 ? 1 : 0) and returns it */
102102 #define Get2MagSign(_input) ((_input) >= 0 ? 2 * (_input) : -2 * (_input) - 1)
103103
104104 /* Outputs the Golomb/Rice encoding of a non-negative integer */
105105 #define CodeGR(_krp, _val) \
106 do { \
107 int lkr = (_krp) >> LSGR; \
108 int lval = _val; \
109 /* unary part of GR code */ \
110 uint32 lvk = lval >> lkr; \
111 OutputBit(lvk, 1); \
112 OutputBit(1, 0); \
113 /* remainder part of GR code, if needed */ \
114 if (lkr) \
115 { \
116 OutputBits(lkr, lval & ((1 << lkr) - 1)); \
117 } \
118 /* update krp, only if it is not equal to 1 */ \
119 if (lvk == 0) \
120 { \
121 UpdateParam(_krp, -2, lkr); \
122 } \
123 else if (lvk > 1) \
124 { \
125 UpdateParam(_krp, lvk, lkr); \
126 } \
127 } while (0)
106 do { \
107 int lkr = (_krp) >> LSGR; \
108 int lval = _val; \
109 /* unary part of GR code */ \
110 uint32 lvk = lval >> lkr; \
111 OutputBit(lvk, 1); \
112 OutputBit(1, 0); \
113 /* remainder part of GR code, if needed */ \
114 if (lkr) \
115 { \
116 OutputBits(lkr, lval & ((1 << lkr) - 1)); \
117 } \
118 /* update krp, only if it is not equal to 1 */ \
119 if (lvk == 0) \
120 { \
121 UpdateParam(_krp, -2, lkr); \
122 } \
123 else if (lvk > 1) \
124 { \
125 UpdateParam(_krp, lvk, lkr); \
126 } \
127 } while (0)
128128
129129 int
130130 rfx_rlgr1_encode(const sint16 *data, uint8 *buffer, int buffer_size)
4141
4242 /* Returns the least number of bits required to represent a given value */
4343 #define GetMinBits(_val, _nbits) \
44 do { \
45 uint32 _v = _val; \
46 _nbits = 0; \
47 while (_v) \
48 { \
49 _v >>= 1; \
50 _nbits++; \
51 } \
52 } while (0)
44 do { \
45 uint32 _v = _val; \
46 _nbits = 0; \
47 while (_v) \
48 { \
49 _v >>= 1; \
50 _nbits++; \
51 } \
52 } while (0)
5353
5454 /*
5555 * Update the passed parameter and clamp it to the range [0, KPMAX]
5656 * Return the value of parameter right-shifted by LSGR
5757 */
5858 #define UpdateParam(_param, _deltaP, _k) \
59 do { \
60 _param += _deltaP; \
61 if (_param > KPMAX) \
62 { \
63 _param = KPMAX; \
64 } \
65 if (_param < 0) \
66 { \
67 _param = 0; \
68 } \
69 _k = (_param >> LSGR); \
70 } while (0)
59 do { \
60 _param += _deltaP; \
61 if (_param > KPMAX) \
62 { \
63 _param = KPMAX; \
64 } \
65 if (_param < 0) \
66 { \
67 _param = 0; \
68 } \
69 _k = (_param >> LSGR); \
70 } while (0)
7171
7272 /* Returns the next coefficient (a signed int) to encode, from the input stream */
7373 #define GetNextInput(_n) \
74 do { \
75 if (data_size > 0) \
76 { \
77 _n = *data++; \
78 data_size--; \
79 } \
80 else \
81 { \
82 _n = 0; \
83 } \
84 } while (0)
74 do { \
75 if (data_size > 0) \
76 { \
77 _n = *data++; \
78 data_size--; \
79 } \
80 else \
81 { \
82 _n = 0; \
83 } \
84 } while (0)
8585
8686 /* Emit bitPattern to the output bitstream */
8787 #define OutputBits(_numBits, _bitPattern) rfx_bitstream_put_bits(bs, _bitPattern, _numBits)
8888
8989 /* Emit a bit (0 or 1), count number of times, to the output bitstream */
9090 #define OutputBit(_count, _bit) \
91 do \
92 { \
93 uint16 b = (_bit ? 0xFFFF : 0); \
94 int c = _count; \
95 for (; c > 0; c -= 16) \
96 { \
97 rfx_bitstream_put_bits(bs, b, (c > 16 ? 16 : c)); \
98 } \
99 } while (0)
91 do \
92 { \
93 uint16 b = (_bit ? 0xFFFF : 0); \
94 int c = _count; \
95 for (; c > 0; c -= 16) \
96 { \
97 rfx_bitstream_put_bits(bs, b, (c > 16 ? 16 : c)); \
98 } \
99 } while (0)
100100
101101 /* Converts the input value to (2 * abs(input) - sign(input)), where sign(input) = (input < 0 ? 1 : 0) and returns it */
102102 #define Get2MagSign(_input) ((_input) >= 0 ? 2 * (_input) : -2 * (_input) - 1)
103103
104104 /* Outputs the Golomb/Rice encoding of a non-negative integer */
105105 #define CodeGR(_krp, _val) \
106 do { \
107 int lkr = (_krp) >> LSGR; \
108 int lval = _val; \
109 /* unary part of GR code */ \
110 uint32 lvk = lval >> lkr; \
111 OutputBit(lvk, 1); \
112 OutputBit(1, 0); \
113 /* remainder part of GR code, if needed */ \
114 if (lkr) \
115 { \
116 OutputBits(lkr, lval & ((1 << lkr) - 1)); \
117 } \
118 /* update krp, only if it is not equal to 1 */ \
119 if (lvk == 0) \
120 { \
121 UpdateParam(_krp, -2, lkr); \
122 } \
123 else if (lvk > 1) \
124 { \
125 UpdateParam(_krp, lvk, lkr); \
126 } \
127 } while (0)
106 do { \
107 int lkr = (_krp) >> LSGR; \
108 int lval = _val; \
109 /* unary part of GR code */ \
110 uint32 lvk = lval >> lkr; \
111 OutputBit(lvk, 1); \
112 OutputBit(1, 0); \
113 /* remainder part of GR code, if needed */ \
114 if (lkr) \
115 { \
116 OutputBits(lkr, lval & ((1 << lkr) - 1)); \
117 } \
118 /* update krp, only if it is not equal to 1 */ \
119 if (lvk == 0) \
120 { \
121 UpdateParam(_krp, -2, lkr); \
122 } \
123 else if (lvk > 1) \
124 { \
125 UpdateParam(_krp, lvk, lkr); \
126 } \
127 } while (0)
128128
129129 int
130130 rfx_rlgr3_encode(const sint16 *data, uint8 *buffer, int buffer_size)
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
2222 #endif
2323
2424 #include "libxrdp.h"
25 #include "string_calls.h"
2526 #include "xrdp_orders_rail.h"
2627
27 #define LOG_LEVEL 1
28 #define LLOG(_level, _args) \
29 do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
30 #define LLOGLN(_level, _args) \
31 do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
28 #include "ms-rdpbcgr.h"
29
30
3231
3332 #define MAX_BITMAP_BUF_SIZE (16 * 1024) /* 16K */
3433
3534 /******************************************************************************/
3635 struct xrdp_session *EXPORT_CC
37 libxrdp_init(tbus id, struct trans *trans)
36 libxrdp_init(tbus id, struct trans *trans, const char *xrdp_ini)
3837 {
3938 struct xrdp_session *session;
4039
4140 session = (struct xrdp_session *)g_malloc(sizeof(struct xrdp_session), 1);
4241 session->id = id;
4342 session->trans = trans;
43 if (xrdp_ini != NULL)
44 {
45 session->xrdp_ini = g_strdup(xrdp_ini);
46 }
47 else
48 {
49 session->xrdp_ini = g_strdup(XRDP_CFG_PATH "/xrdp.ini");
50 }
4451 session->rdp = xrdp_rdp_create(session, trans);
4552 session->orders = xrdp_orders_create(session, (struct xrdp_rdp *)session->rdp);
4653 session->client_info = &(((struct xrdp_rdp *)session->rdp)->client_info);
54 session->check_for_app_input = 1;
4755 return session;
4856 }
4957
5866
5967 xrdp_orders_delete((struct xrdp_orders *)session->orders);
6068 xrdp_rdp_delete((struct xrdp_rdp *)session->rdp);
69 g_free(session->xrdp_ini);
6170 g_free(session);
6271 return 0;
6372 }
112121 /******************************************************************************/
113122 /* only used during connection */
114123 struct stream *
115 libxrdp_force_read(struct trans* trans)
124 libxrdp_force_read(struct trans *trans)
116125 {
117126 int bytes;
118127 struct stream *s;
122131
123132 if (trans_force_read(trans, 4) != 0)
124133 {
125 g_writeln("libxrdp_force_read: error");
134 LOG(LOG_LEVEL_WARNING, "libxrdp_force_read: header read error");
126135 return 0;
127136 }
128137 bytes = libxrdp_get_pdu_bytes(s->data);
129 if (bytes < 1)
130 {
131 g_writeln("libxrdp_force_read: error");
138 if (bytes < 4 || bytes > s->size)
139 {
140 LOG(LOG_LEVEL_WARNING, "libxrdp_force_read: bad header length %d", bytes);
132141 return 0;
133142 }
134 if (bytes > 32 * 1024)
135 {
136 g_writeln("libxrdp_force_read: error");
137 return 0;
138 }
139
140143 if (trans_force_read(trans, bytes - 4) != 0)
141144 {
142 g_writeln("libxrdp_force_read: error");
145 LOG(LOG_LEVEL_WARNING, "libxrdp_force_read: Can't read PDU");
143146 return 0;
144147 }
145148 return s;
160163 do_read = s == 0;
161164 if (do_read && session->up_and_running)
162165 {
163 g_writeln("libxrdp_process_data: error logic");
166 LOG(LOG_LEVEL_ERROR, "libxrdp_process_data: error logic");
164167 return 1;
165168 }
166169 if (session->in_process_data != 0)
167170 {
168 g_writeln("libxrdp_process_data: error reentry");
171 LOG(LOG_LEVEL_ERROR, "libxrdp_process_data: error reentry");
169172 return 1;
170173 }
171174 session->in_process_data++;
205208 }
206209 if (s == 0)
207210 {
208 g_writeln("libxrdp_process_data: libxrdp_force_read failed");
211 LOG(LOG_LEVEL_ERROR, "libxrdp_process_data: libxrdp_force_read failed");
209212 rv = 1;
210213 break;
211214 }
213216
214217 if (xrdp_rdp_recv(rdp, s, &code) != 0)
215218 {
216 g_writeln("libxrdp_process_data: xrdp_rdp_recv failed");
219 LOG(LOG_LEVEL_ERROR, "libxrdp_process_data: xrdp_rdp_recv failed");
217220 rv = 1;
218221 break;
219222 }
220223
221 DEBUG(("libxrdp_process_data code %d", code));
224 LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_process_data code %d", code);
222225
223226 switch (code)
224227 {
235238 case PDUTYPE_DATAPDU:
236239 if (xrdp_rdp_process_data(rdp, s) != 0)
237240 {
238 DEBUG(("libxrdp_process_data returned non zero"));
241 LOG(LOG_LEVEL_ERROR, "libxrdp_process_data returned non zero");
239242 cont = 0;
240243 term = 1;
241244 }
243246 case 2: /* FASTPATH_INPUT_EVENT */
244247 if (xrdp_fastpath_process_input_event(rdp->sec_layer->fastpath_layer, s) != 0)
245248 {
246 DEBUG(("libxrdp_process_data returned non zero"));
247 cont = 0;
248 term = 1;
249 LOG(LOG_LEVEL_ERROR, "libxrdp_process_data returned non zero");
250 cont = 0;
251 term = 1;
249252 }
250253 break;
251254 default:
252 g_writeln("unknown in libxrdp_process_data: code= %d", code);
255 LOG(LOG_LEVEL_ERROR, "unknown in libxrdp_process_data: code= %d", code);
253256 dead_lock_counter++;
254257 break;
255258 }
258261 {
259262 /*This situation can happen and this is a workaround*/
260263 cont = 0;
261 g_writeln("Serious programming error: we were locked in a deadly loop");
262 g_writeln("Remaining: %d", (int) (s->end - s->next_packet));
264 LOG(LOG_LEVEL_ERROR, "Serious programming error: we were locked in a deadly loop");
265 LOG(LOG_LEVEL_ERROR, "Remaining: %d", (int) (s->end - s->next_packet));
263266 s->next_packet = 0;
264267 }
265268
288291 return 0;
289292 }
290293
291 DEBUG(("libxrdp_send_palette sending palette"));
294 LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_send_palette sending palette");
292295
293296 /* clear orders */
294297 libxrdp_orders_force_send(session);
297300
298301 if (session->client_info->use_fast_path & 1) /* fastpath output supported */
299302 {
300 LLOGLN(10, ("libxrdp_send_palette: fastpath"));
303 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_palette: fastpath");
301304 if (xrdp_rdp_init_fastpath((struct xrdp_rdp *)session->rdp, s) != 0)
302305 {
303306 free_stream(s);
304307 return 1;
305308 }
306309 }
307 else {
308 LLOGLN(10, ("libxrdp_send_palette: slowpath"));
310 else
311 {
312 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_palette: slowpath");
309313 xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
310314 }
311315
326330 s_mark_end(s);
327331 if (session->client_info->use_fast_path & 1) /* fastpath output supported */
328332 {
329 if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s,
333 if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s,
330334 FASTPATH_UPDATETYPE_PALETTE) != 0)
331 {
332 free_stream(s);
333 return 1;
334 }
335 {
336 free_stream(s);
337 return 1;
338 }
335339 }
336340 else
337341 {
338 xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s,
342 xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s,
339343 RDP_DATA_PDU_UPDATE);
340344 }
341345 free_stream(s);
359363 {
360364 struct stream *s = (struct stream *)NULL;
361365
362 DEBUG(("libxrdp_send_bell sending bell signal"));
366 LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_send_bell sending bell signal");
363367 /* see MS documentation: Server play sound PDU, TS_PLAY_SOUND_PDU_DATA */
364368
365369 make_stream(s);
410414 struct stream *temp_s = (struct stream *)NULL;
411415 tui32 pixel;
412416
413 LLOGLN(10, ("libxrdp_send_bitmap: sending bitmap"));
417 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: sending bitmap");
414418 Bpp = (bpp + 7) / 8;
415419 e = (4 - width) & 3;
416420 switch (bpp)
430434 line_bytes = width * Bpp;
431435 line_pad_bytes = line_bytes + e * Bpp;
432436
433 LLOGLN(10, ("libxrdp_send_bitmap: bpp %d Bpp %d line_bytes %d "
434 "server_line_bytes %d", bpp, Bpp, line_bytes, server_line_bytes));
437 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: bpp %d Bpp %d line_bytes %d "
438 "server_line_bytes %d", bpp, Bpp, line_bytes, server_line_bytes);
435439 make_stream(s);
436440 init_stream(s, MAX_BITMAP_BUF_SIZE);
437441
438442 if (session->client_info->use_bitmap_comp)
439443 {
440 LLOGLN(10, ("libxrdp_send_bitmap: compression"));
444 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: compression");
441445 make_stream(temp_s);
442446 init_stream(temp_s, 65536);
443447 i = 0;
449453
450454 while (i > 0)
451455 {
452 LLOGLN(10, ("libxrdp_send_bitmap: i %d", i));
456 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: i %d", i);
453457
454458 total_bufsize = 0;
455459 num_updates = 0;
473477
474478 if (bpp > 24)
475479 {
476 LLOGLN(10, ("libxrdp_send_bitmap: 32 bpp"));
480 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: 32 bpp");
477481 lines_sending = xrdp_bitmap32_compress(data, width, height,
478482 s, 32,
479 (MAX_BITMAP_BUF_SIZE - 100) - total_bufsize,
483 (MAX_BITMAP_BUF_SIZE - 100) - total_bufsize,
480484 i - 1, temp_s, e, 0x10);
481 LLOGLN(10, ("libxrdp_send_bitmap: i %d lines_sending %d",
482 i, lines_sending));
485 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: i %d lines_sending %d",
486 i, lines_sending);
483487 }
484488 else
485489 {
486490 lines_sending = xrdp_bitmap_compress(data, width, height,
487491 s, bpp,
488 (MAX_BITMAP_BUF_SIZE - 100) - total_bufsize,
492 (MAX_BITMAP_BUF_SIZE - 100) - total_bufsize,
489493 i - 1, temp_s, e);
490 LLOGLN(10, ("libxrdp_send_bitmap: i %d lines_sending %d",
491 i, lines_sending));
494 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: i %d lines_sending %d",
495 i, lines_sending);
492496 }
493497
494498 if (lines_sending == 0)
531535 total_bufsize += 26; /* bytes since pop layer */
532536 }
533537
534 LLOGLN(10, ("libxrdp_send_bitmap: decompressed pixels %d "
535 "decompressed bytes %d compressed bytes %d",
536 lines_sending * (width + e),
537 line_pad_bytes * lines_sending, bufsize));
538 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: decompressed pixels %d "
539 "decompressed bytes %d compressed bytes %d",
540 lines_sending * (width + e),
541 line_pad_bytes * lines_sending, bufsize);
538542
539543 if (j > MAX_BITMAP_BUF_SIZE)
540544 {
541 LLOGLN(0, ("libxrdp_send_bitmap: error, decompressed "
542 "size too big: %d bytes", j));
545 LOG(LOG_LEVEL_WARNING, "libxrdp_send_bitmap: error, decompressed "
546 "size too big: %d bytes", j);
543547 }
544548
545549 if (bufsize > MAX_BITMAP_BUF_SIZE)
546550 {
547 LLOGLN(0, ("libxrdp_send_bitmap: error, compressed size "
548 "too big: %d bytes", bufsize));
551 LOG(LOG_LEVEL_WARNING, "libxrdp_send_bitmap: error, compressed size "
552 "too big: %d bytes", bufsize);
549553 }
550554
551555 s->p = s->end;
552556 }
553557 while (total_bufsize < MAX_BITMAP_BUF_SIZE && i > 0);
554558
555 LLOGLN(10, ("libxrdp_send_bitmap: num_updates %d total_bufsize %d",
556 num_updates, total_bufsize));
559 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: num_updates %d total_bufsize %d",
560 num_updates, total_bufsize);
557561
558562 p_num_updates[0] = num_updates;
559563 p_num_updates[1] = num_updates >> 8;
562566
563567 if (total_bufsize > MAX_BITMAP_BUF_SIZE)
564568 {
565 LLOGLN(0, ("libxrdp_send_bitmap: error, total compressed "
566 "size too big: %d bytes", total_bufsize));
569 LOG(LOG_LEVEL_WARNING, "libxrdp_send_bitmap: error, total compressed "
570 "size too big: %d bytes", total_bufsize);
567571 }
568572 }
569573
571575 }
572576 else
573577 {
574 LLOGLN(10, ("libxrdp_send_bitmap: no compression"));
578 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: no compression");
575579 total_lines = height;
576580 i = 0;
577581 p = data;
590594
591595 if (lines_sending == 0)
592596 {
593 LLOGLN(0, ("libxrdp_send_bitmap: error, lines_sending == zero"));
597 LOG(LOG_LEVEL_WARNING, "libxrdp_send_bitmap: error, lines_sending == zero");
594598 break;
595599 }
596600
626630 q = q - server_line_bytes;
627631 for (k = 0; k < width; k++)
628632 {
629 pixel = *((tui16*)(q + k * 2));
633 pixel = *((tui16 *)(q + k * 2));
630634 out_uint16_le(s, pixel);
631635 }
632636 out_uint8s(s, e * 2);
638642 q = q - server_line_bytes;
639643 for (k = 0; k < width; k++)
640644 {
641 pixel = *((tui32*)(q + k * 4));
645 pixel = *((tui32 *)(q + k * 4));
642646 out_uint8(s, pixel);
643647 out_uint8(s, pixel >> 8);
644648 out_uint8(s, pixel >> 16);
652656 q = q - server_line_bytes;
653657 for (k = 0; k < width; k++)
654658 {
655 pixel = *((int*)(q + k * 4));
659 pixel = *((int *)(q + k * 4));
656660 out_uint32_le(s, pixel);
657661 }
658662 out_uint8s(s, e * 4);
685689 int j;
686690 int data_bytes;
687691
688 DEBUG(("libxrdp_send_pointer sending cursor"));
692 LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_send_pointer sending cursor");
689693 if (bpp == 0)
690694 {
691695 bpp = 24;
695699 {
696700 if (bpp != 24)
697701 {
698 g_writeln("libxrdp_send_pointer: error client does not support "
699 "new cursors and bpp is %d", bpp);
702 LOG(LOG_LEVEL_ERROR, "libxrdp_send_pointer: error client does not support "
703 "new cursors and bpp is %d", bpp);
700704 return 1;
701705 }
702706 }
703707 if ((bpp == 15) && (bpp != 16) && (bpp != 24) && (bpp != 32))
704708 {
705 g_writeln("libxrdp_send_pointer: error");
709 LOG(LOG_LEVEL_ERROR, "libxrdp_send_pointer: error");
706710 return 1;
707711 }
708712 make_stream(s);
710714
711715 if (session->client_info->use_fast_path & 1) /* fastpath output supported */
712716 {
713 LLOGLN(10, ("libxrdp_send_pointer: fastpath"));
717 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_pointer: fastpath");
714718 if (xrdp_rdp_init_fastpath((struct xrdp_rdp *)session->rdp, s) != 0)
715719 {
716720 free_stream(s);
729733 }
730734 else /* slowpath */
731735 {
732 LLOGLN(10, ("libxrdp_send_pointer: slowpath"));
736 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_pointer: slowpath");
733737 xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
734738 if ((session->client_info->pointer_flags & 1) == 0)
735 {
736 out_uint16_le(s, RDP_POINTER_COLOR);
737 out_uint16_le(s, 0); /* pad */
738 data_bytes = 3072;
739 }
740 else
741 {
742 out_uint16_le(s, RDP_POINTER_POINTER);
743 out_uint16_le(s, 0); /* pad */
744 out_uint16_le(s, bpp);
745 data_bytes = ((bpp + 7) / 8) * 32 * 32;
746 }
739 {
740 out_uint16_le(s, RDP_POINTER_COLOR);
741 out_uint16_le(s, 0); /* pad */
742 data_bytes = 3072;
743 }
744 else
745 {
746 out_uint16_le(s, RDP_POINTER_POINTER);
747 out_uint16_le(s, 0); /* pad */
748 out_uint16_le(s, bpp);
749 data_bytes = ((bpp + 7) / 8) * 32 * 32;
750 }
747751 }
748752
749753
805809 if ((session->client_info->pointer_flags & 1) == 0)
806810 {
807811 if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s,
808 FASTPATH_UPDATETYPE_COLOR) != 0)
812 FASTPATH_UPDATETYPE_COLOR) != 0)
809813 {
810814 free_stream(s);
811815 return 1;
814818 else
815819 {
816820 if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s,
817 FASTPATH_UPDATETYPE_POINTER) != 0)
821 FASTPATH_UPDATETYPE_POINTER) != 0)
818822 {
819823 free_stream(s);
820824 return 1;
824828 else
825829 {
826830 xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s,
827 RDP_DATA_PDU_POINTER);
831 RDP_DATA_PDU_POINTER);
828832 }
829833 free_stream(s);
830834 return 0;
836840 {
837841 struct stream *s;
838842
839 DEBUG(("libxrdp_set_pointer sending cursor index"));
843 LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_set_pointer sending cursor index");
840844 make_stream(s);
841845 init_stream(s, 8192);
842846
843847
844848 if (session->client_info->use_fast_path & 1) /* fastpath output supported */
845849 {
846 LLOGLN(10, ("libxrdp_send_pointer: fastpath"));
850 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_pointer: fastpath");
847851 if (xrdp_rdp_init_fastpath((struct xrdp_rdp *)session->rdp, s) != 0)
848852 {
849853 free_stream(s);
852856 }
853857 else
854858 {
855 LLOGLN(10, ("libxrdp_send_pointer: slowpath"));
859 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_pointer: slowpath");
856860 xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
857861 out_uint16_le(s, RDP_POINTER_CACHED);
858862 out_uint16_le(s, 0); /* pad */
864868 if (session->client_info->use_fast_path & 1) /* fastpath output supported */
865869 {
866870 if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s,
867 FASTPATH_UPDATETYPE_CACHED) != 0)
871 FASTPATH_UPDATETYPE_CACHED) != 0)
868872 {
869873 free_stream(s);
870874 return 1;
873877 else
874878 {
875879 xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s,
876 RDP_DATA_PDU_POINTER);
880 RDP_DATA_PDU_POINTER);
877881 }
878882 free_stream(s);
879883 return 0;
968972
969973 /******************************************************************************/
970974 int
971 libxrdp_orders_composite_blt(struct xrdp_session* session, int srcidx,
975 libxrdp_orders_composite_blt(struct xrdp_session *session, int srcidx,
972976 int srcformat, int srcwidth, int srcrepeat,
973 int* srctransform, int mskflags,
977 int *srctransform, int mskflags,
974978 int mskidx, int mskformat, int mskwidth,
975979 int mskrepeat, int op, int srcx, int srcy,
976980 int mskx, int msky, int dstx, int dsty,
977981 int width, int height, int dstformat,
978 struct xrdp_rect* rect)
979 {
980 return xrdp_orders_composite_blt((struct xrdp_orders*)session->orders,
981 srcidx, srcformat, srcwidth, srcrepeat,
982 srctransform, mskflags,
983 mskidx, mskformat, mskwidth, mskrepeat,
984 op, srcx, srcy, mskx, msky, dstx, dsty,
985 width, height, dstformat, rect);
982 struct xrdp_rect *rect)
983 {
984 return xrdp_orders_composite_blt((struct xrdp_orders *)session->orders,
985 srcidx, srcformat, srcwidth, srcrepeat,
986 srctransform, mskflags,
987 mskidx, mskformat, mskwidth, mskrepeat,
988 op, srcx, srcy, mskx, msky, dstx, dsty,
989 width, height, dstformat, rect);
986990 }
987991
988992 /******************************************************************************/
10461050 }
10471051
10481052 /*****************************************************************************/
1053 /* Note : if this is called on a multimon setup, the client is resized
1054 * to a single monitor */
10491055 int EXPORT_CC
10501056 libxrdp_reset(struct xrdp_session *session,
10511057 int width, int height, int bpp)
10521058 {
10531059 if (session->client_info != 0)
10541060 {
1061 struct xrdp_client_info *client_info = session->client_info;
1062
10551063 /* older client can't resize */
1056 if (session->client_info->build <= 419)
1064 if (client_info->build <= 419)
10571065 {
10581066 return 0;
10591067 }
10601068
1061 /* if same, don't need to do anything */
1062 if (session->client_info->width == width &&
1063 session->client_info->height == height &&
1064 session->client_info->bpp == bpp)
1069 /* if same (and only one monitor on client) don't need to do anything */
1070 if (client_info->width == width &&
1071 client_info->height == height &&
1072 client_info->bpp == bpp &&
1073 (client_info->monitorCount == 0 || client_info->multimon == 0))
10651074 {
10661075 return 0;
10671076 }
10681077
1069 session->client_info->width = width;
1070 session->client_info->height = height;
1071 session->client_info->bpp = bpp;
1078 client_info->width = width;
1079 client_info->height = height;
1080 client_info->bpp = bpp;
1081 client_info->monitorCount = 0;
1082 client_info->multimon = 0;
10721083 }
10731084 else
10741085 {
10811092 return 1;
10821093 }
10831094
1084 /* shut down the rdp client */
1095 /* shut down the rdp client
1096 *
1097 * When resetting the lib, disable application input checks, as
1098 * otherwise we can send a channel message to the other end while
1099 * the channels are inactive ([MS-RDPBCGR] 3.2.5.5.1 */
1100 session->check_for_app_input = 0;
10851101 if (xrdp_rdp_send_deactivate((struct xrdp_rdp *)session->rdp) != 0)
10861102 {
10871103 return 1;
10921108 {
10931109 return 1;
10941110 }
1111
1112 /* Re-enable application input checks */
1113 session->check_for_app_input = 1;
10951114
10961115 return 0;
10971116 }
11481167
11491168 if (mcs->channel_list == NULL)
11501169 {
1151 g_writeln("libxrdp_query_channel - No channel initialized");
1170 LOG(LOG_LEVEL_ERROR, "libxrdp_query_channel - No channel initialized");
11521171 return 1 ;
11531172 }
11541173
11561175
11571176 if (index < 0 || index >= count)
11581177 {
1159 DEBUG(("libxrdp_query_channel - Channel out of range %d", index));
1178 LOG(LOG_LEVEL_ERROR, "libxrdp_query_channel - Channel out of range %d", index);
11601179 return 1;
11611180 }
11621181
11661185 if (channel_item == 0)
11671186 {
11681187 /* this should not happen */
1169 g_writeln("libxrdp_query_channel - channel item is 0");
1188 LOG(LOG_LEVEL_ERROR, "libxrdp_query_channel - channel item is 0");
11701189 return 1;
11711190 }
11721191
11731192 if (channel_name != 0)
11741193 {
11751194 g_strncpy(channel_name, channel_item->name, 8);
1176 DEBUG(("libxrdp_query_channel - Channel %d name %s", index, channel_name));
1195 LOG(LOG_LEVEL_ERROR, "libxrdp_query_channel - Channel %d name %s", index, channel_name);
11771196 }
11781197
11791198 if (channel_flags != 0)
12011220
12021221 if (mcs->channel_list == NULL)
12031222 {
1204 g_writeln("libxrdp_get_channel_id No channel initialized");
1223 LOG(LOG_LEVEL_ERROR, "libxrdp_get_channel_id No channel initialized");
12051224 return -1 ;
12061225 }
12071226
12531272
12541273 if (xrdp_channel_send(chan, s, channel_id, total_data_len, flags) != 0)
12551274 {
1256 g_writeln("libxrdp_send_to_channel: error, server channel data NOT sent to client channel");
1275 LOG(LOG_LEVEL_ERROR, "libxrdp_send_to_channel: error, server channel data NOT sent to client channel");
12571276 free_stream(s);
12581277 return 1;
12591278 }
14751494 char *out_data, int *io_len)
14761495 {
14771496 struct xrdp_orders *orders;
1478 void* jpeg_han;
1497 void *jpeg_han;
14791498
14801499 orders = (struct xrdp_orders *)(session->orders);
14811500 jpeg_han = orders->jpeg_han;
14871506 /*****************************************************************************/
14881507 int EXPORT_CC
14891508 libxrdp_fastpath_send_surface(struct xrdp_session *session,
1490 char* data_pad, int pad_bytes,
1509 char *data_pad, int pad_bytes,
14911510 int data_bytes,
14921511 int destLeft, int destTop,
14931512 int destRight, int destBottom, int bpp,
15011520 int max_bytes;
15021521 int cmd_bytes;
15031522
1504 LLOGLN(10, ("libxrdp_fastpath_send_surface:"));
1523 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_fastpath_send_surface:");
15051524 if ((session->client_info->use_fast_path & 1) == 0)
15061525 {
15071526 return 1;
15601579 struct stream *s;
15611580 struct xrdp_rdp *rdp;
15621581
1563 LLOGLN(10, ("libxrdp_fastpath_send_frame_marker:"));
1582 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_fastpath_send_frame_marker:");
15641583 if ((session->client_info->use_fast_path & 1) == 0)
15651584 {
15661585 return 1;
15941613 {
15951614 struct xrdp_rdp *rdp;
15961615
1597 LLOGLN(10, ("libxrdp_send_session_info:"));
1616 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_session_info:");
15981617 rdp = (struct xrdp_rdp *) (session->rdp);
15991618 return xrdp_rdp_send_session_info(rdp, data, data_bytes);
16001619 }
2828 #include "os_calls.h"
2929 #include "ssl_calls.h"
3030 #include "list.h"
31 #include "log.h"
3132 #include "file.h"
3233 #include "libxrdpinc.h"
3334 #include "xrdp_client_info.h"
6565 struct trans *trans;
6666 int (*callback)(intptr_t id, int msg, intptr_t param1, intptr_t param2,
6767 intptr_t param3, intptr_t param4);
68 int check_for_app_input;
6869 void *rdp;
6970 void *orders;
7071 struct xrdp_client_info *client_info;
7374 int in_process_data; /* inc / dec libxrdp_process_data calls */
7475
7576 struct source_info si;
77 char *xrdp_ini; /* path to xrdp.ini */
7678 };
7779
7880 struct xrdp_drdynvc_procs
8385 int (*data)(intptr_t id, int chan_id, char *data, int bytes);
8486 };
8587
88 /***
89 * Initialise the XRDP library
90 *
91 * @param id Channel ID (xrdp_process* as integer type)
92 * @param trans Transport object to use for this instance
93 * @param xrdp_ini Path to xrdp.ini config file, or NULL for default
94 * @return an allocated xrdp_session object
95 */
8696 struct xrdp_session *
87 libxrdp_init(tbus id, struct trans *trans);
97 libxrdp_init(tbus id, struct trans *trans, const char *xrdp_ini);
8898 int
8999 libxrdp_exit(struct xrdp_session *session);
90100 int
3232 #define FLAGS_RLE 0x10
3333 #define FLAGS_NOALPHA 0x20
3434
35 #define LLOG_LEVEL 1
36 #define LLOGLN(_level, _args) \
37 do { if (_level < LLOG_LEVEL) { g_writeln _args ; } } while (0)
38 #define LHEXDUMP(_level, _args) \
39 do { if (_level < LLOG_LEVEL) { g_hexdump _args ; } } while (0)
35
4036
4137 /*****************************************************************************/
4238 /* split RGB */
8480 rp |= (pixel << 8) & 0xff000000;
8581 gp |= (pixel << 16) & 0xff000000;
8682 bp |= (pixel << 24) & 0xff000000;
87 *((int*)(r_data + out_index)) = rp;
88 *((int*)(g_data + out_index)) = gp;
89 *((int*)(b_data + out_index)) = bp;
83 *((int *)(r_data + out_index)) = rp;
84 *((int *)(g_data + out_index)) = gp;
85 *((int *)(b_data + out_index)) = bp;
9086 out_index += 4;
9187 index += 4;
9288 }
169165 rp |= (pixel << 8) & 0xff000000;
170166 gp |= (pixel << 16) & 0xff000000;
171167 bp |= (pixel << 24) & 0xff000000;
172 *((int*)(a_data + out_index)) = ap;
173 *((int*)(r_data + out_index)) = rp;
174 *((int*)(g_data + out_index)) = gp;
175 *((int*)(b_data + out_index)) = bp;
168 *((int *)(a_data + out_index)) = ap;
169 *((int *)(r_data + out_index)) = rp;
170 *((int *)(g_data + out_index)) = gp;
171 *((int *)(b_data + out_index)) = bp;
176172 out_index += 4;
177173 index += 4;
178174 }
208204
209205 /*****************************************************************************/
210206 #define DELTA_ONE \
211 do { \
212 delta = src8[cx] - src8[0]; \
213 is_neg = (delta >> 7) & 1; \
214 dst8[cx] = (((delta ^ -is_neg) + is_neg) << 1) - is_neg; \
215 src8++; \
216 dst8++; \
217 } while (0)
207 do { \
208 delta = src8[cx] - src8[0]; \
209 is_neg = (delta >> 7) & 1; \
210 dst8[cx] = (((delta ^ -is_neg) + is_neg) << 1) - is_neg; \
211 src8++; \
212 dst8++; \
213 } while (0)
218214
219215 /*****************************************************************************/
220216 static int
257253 int lreplen;
258254 int cont;
259255
260 LLOGLN(10, ("fout: collen %d replen %d", collen, replen));
256 LOG_DEVEL(LOG_LEVEL_DEBUG, "fout: collen %d replen %d", collen, replen);
261257 cont = collen > 13;
262258 while (cont)
263259 {
284280 {
285281 lreplen = 47;
286282 }
287 LLOGLN(10, ("fout: big run lreplen %d", lreplen));
283 LOG_DEVEL(LOG_LEVEL_DEBUG, "fout: big run lreplen %d", lreplen);
288284 replen -= lreplen;
289285 code = ((lreplen & 0xF) << 4) | ((lreplen & 0xF0) >> 4);
290286 out_uint8(s, code);
325321 int collen;
326322 int replen;
327323
328 LLOGLN(10, ("fpack:"));
324 LOG_DEVEL(LOG_LEVEL_DEBUG, "fpack:");
329325 holdp = s->p;
330326 for (jndex = 0; jndex < cy; jndex++)
331327 {
332 LLOGLN(10, ("line start line %d cx %d cy %d", jndex, cx, cy));
328 LOG_DEVEL(LOG_LEVEL_DEBUG, "line start line %d cx %d cy %d", jndex, cx, cy);
333329 ptr8 = plane + jndex * cx;
334 LHEXDUMP(10, (ptr8, cx));
330 LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "line content", ptr8, cx);
335331 lend = ptr8 + (cx - 1);
336332 colptr = ptr8;
337333 if (colptr[0] == 0)
436432 int total_bytes;
437433 int header;
438434
439 LLOGLN(10, ("xrdp_bitmap32_compress:"));
435 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_bitmap32_compress:");
440436 max_bytes = 4 * 1024;
441437 /* need max 8, 4K planes for work */
442438 if (max_bytes * 8 > temp_s->size)
2323 #endif
2424
2525 #include "libxrdp.h"
26 #include "ms-rdpbcgr.h"
27 #include "ms-rdperp.h"
2628
2729 /*****************************************************************************/
2830 static int
7476
7577 if (len < 10 + 2)
7678 {
77 g_writeln("xrdp_caps_process_general: error");
79 LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_general: error");
7880 return 1;
7981 }
8082
109111 int ex_flags;
110112 int cap_flags;
111113
112 DEBUG(("order capabilities"));
114 LOG_DEVEL(LOG_LEVEL_TRACE, "order capabilities");
113115 if (len < 20 + 2 + 2 + 2 + 2 + 2 + 2 + 32 + 2 + 2 + 4 + 4 + 4 + 4)
114116 {
115 g_writeln("xrdp_caps_process_order: error");
117 LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_order: error");
116118 return 1;
117119 }
118120 in_uint8s(s, 20); /* Terminal desc, pad */
124126 in_uint16_le(s, cap_flags); /* Capability flags */
125127 in_uint8a(s, order_caps, 32); /* Orders supported */
126128 g_memcpy(self->client_info.orders, order_caps, 32);
127 DEBUG(("dest blt-0 %d", order_caps[0]));
128 DEBUG(("pat blt-1 %d", order_caps[1]));
129 DEBUG(("screen blt-2 %d", order_caps[2]));
130 DEBUG(("memblt-3-13 %d %d", order_caps[3], order_caps[13]));
131 DEBUG(("triblt-4-14 %d %d", order_caps[4], order_caps[14]));
132 DEBUG(("line-8 %d", order_caps[8]));
133 DEBUG(("line-9 %d", order_caps[9]));
134 DEBUG(("rect-10 %d", order_caps[10]));
135 DEBUG(("desksave-11 %d", order_caps[11]));
136 DEBUG(("polygon-20 %d", order_caps[20]));
137 DEBUG(("polygon2-21 %d", order_caps[21]));
138 DEBUG(("polyline-22 %d", order_caps[22]));
139 DEBUG(("ellipse-25 %d", order_caps[25]));
140 DEBUG(("ellipse2-26 %d", order_caps[26]));
141 DEBUG(("text2-27 %d", order_caps[27]));
142 DEBUG(("order_caps dump"));
143 #if defined(XRDP_DEBUG)
144 g_hexdump(order_caps, 32);
145 #endif
129 LOG_DEVEL(LOG_LEVEL_TRACE, "dest blt-0 %d", order_caps[0]);
130 LOG_DEVEL(LOG_LEVEL_TRACE, "pat blt-1 %d", order_caps[1]);
131 LOG_DEVEL(LOG_LEVEL_TRACE, "screen blt-2 %d", order_caps[2]);
132 LOG_DEVEL(LOG_LEVEL_TRACE, "memblt-3-13 %d %d", order_caps[3], order_caps[13]);
133 LOG_DEVEL(LOG_LEVEL_TRACE, "triblt-4-14 %d %d", order_caps[4], order_caps[14]);
134 LOG_DEVEL(LOG_LEVEL_TRACE, "line-8 %d", order_caps[8]);
135 LOG_DEVEL(LOG_LEVEL_TRACE, "line-9 %d", order_caps[9]);
136 LOG_DEVEL(LOG_LEVEL_TRACE, "rect-10 %d", order_caps[10]);
137 LOG_DEVEL(LOG_LEVEL_TRACE, "desksave-11 %d", order_caps[11]);
138 LOG_DEVEL(LOG_LEVEL_TRACE, "polygon-20 %d", order_caps[20]);
139 LOG_DEVEL(LOG_LEVEL_TRACE, "polygon2-21 %d", order_caps[21]);
140 LOG_DEVEL(LOG_LEVEL_TRACE, "polyline-22 %d", order_caps[22]);
141 LOG_DEVEL(LOG_LEVEL_TRACE, "ellipse-25 %d", order_caps[25]);
142 LOG_DEVEL(LOG_LEVEL_TRACE, "ellipse2-26 %d", order_caps[26]);
143 LOG_DEVEL(LOG_LEVEL_TRACE, "text2-27 %d", order_caps[27]);
144 LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "order_caps dump", order_caps, 32);
145
146146 in_uint8s(s, 2); /* Text capability flags */
147147 /* read extended order support flags */
148148 in_uint16_le(s, ex_flags); /* Ex flags */
152152 self->client_info.order_flags_ex = ex_flags;
153153 if (ex_flags & XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT)
154154 {
155 g_writeln("xrdp_caps_process_order: bitmap cache v3 supported");
155 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_process_order: bitmap cache v3 supported");
156156 self->client_info.bitmap_cache_version |= 4;
157157 }
158158 }
160160
161161 in_uint32_le(s, i); /* desktop cache size, usually 0x38400 */
162162 self->client_info.desktop_cache = i;
163 DEBUG(("desktop cache size %d", i));
163 LOG_DEVEL(LOG_LEVEL_TRACE, "desktop cache size %d", i);
164164 in_uint8s(s, 4); /* Unknown */
165165 in_uint8s(s, 4); /* Unknown */
166166
167167 /* check if libpainter should be used for drawing, instead of orders */
168168 if (!(order_caps[TS_NEG_DSTBLT_INDEX] && order_caps[TS_NEG_PATBLT_INDEX] &&
169 order_caps[TS_NEG_SCRBLT_INDEX] && order_caps[TS_NEG_MEMBLT_INDEX]))
170 {
171 g_writeln("xrdp_caps_process_order: not enough orders supported by client, using painter.");
169 order_caps[TS_NEG_SCRBLT_INDEX] && order_caps[TS_NEG_MEMBLT_INDEX]))
170 {
171 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_process_order: not enough orders supported by client, using painter.");
172172 self->client_info.no_orders_supported = 1;
173173 }
174174
185185
186186 if (len < 24 + 2 + 2 + 2 + 2 + 2 + 2)
187187 {
188 g_writeln("xrdp_caps_process_bmpcache: error");
188 LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_bmpcache: error");
189189 return 1;
190190 }
191191 self->client_info.bitmap_cache_version |= 1;
208208 i = MAX(i, 0);
209209 self->client_info.cache3_entries = i;
210210 in_uint16_le(s, self->client_info.cache3_size);
211 DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries,
212 self->client_info.cache1_size));
213 DEBUG(("cache2 entries %d size %d", self->client_info.cache2_entries,
214 self->client_info.cache2_size));
215 DEBUG(("cache3 entries %d size %d", self->client_info.cache3_entries,
216 self->client_info.cache3_size));
211 LOG_DEVEL(LOG_LEVEL_TRACE, "cache1 entries %d size %d", self->client_info.cache1_entries,
212 self->client_info.cache1_size);
213 LOG_DEVEL(LOG_LEVEL_TRACE, "cache2 entries %d size %d", self->client_info.cache2_entries,
214 self->client_info.cache2_size);
215 LOG_DEVEL(LOG_LEVEL_TRACE, "cache3 entries %d size %d", self->client_info.cache3_entries,
216 self->client_info.cache3_size);
217217 return 0;
218218 }
219219
228228
229229 if (len < 2 + 2 + 4 + 4 + 4)
230230 {
231 g_writeln("xrdp_caps_process_bmpcache2: error");
231 LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_bmpcache2: error");
232232 return 1;
233233 }
234234 self->client_info.bitmap_cache_version |= 2;
252252 i = MAX(i, 0);
253253 self->client_info.cache3_entries = i;
254254 self->client_info.cache3_size = 4096 * Bpp;
255 DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries,
256 self->client_info.cache1_size));
257 DEBUG(("cache2 entries %d size %d", self->client_info.cache2_entries,
258 self->client_info.cache2_size));
259 DEBUG(("cache3 entries %d size %d", self->client_info.cache3_entries,
260 self->client_info.cache3_size));
255 LOG_DEVEL(LOG_LEVEL_TRACE, "cache1 entries %d size %d", self->client_info.cache1_entries,
256 self->client_info.cache1_size);
257 LOG_DEVEL(LOG_LEVEL_TRACE, "cache2 entries %d size %d", self->client_info.cache2_entries,
258 self->client_info.cache2_size);
259 LOG_DEVEL(LOG_LEVEL_TRACE, "cache3 entries %d size %d", self->client_info.cache3_entries,
260 self->client_info.cache3_size);
261261 return 0;
262262 }
263263
270270
271271 if (len < 1)
272272 {
273 g_writeln("xrdp_caps_process_cache_v3_codec_id: error");
273 LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_cache_v3_codec_id: error");
274274 return 1;
275275 }
276276 in_uint8(s, codec_id);
277 g_writeln("xrdp_caps_process_cache_v3_codec_id: cache_v3_codec_id %d",
277 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_process_cache_v3_codec_id: cache_v3_codec_id %d",
278278 codec_id);
279279 self->client_info.v3_codec_id = codec_id;
280280 return 0;
292292
293293 if (len < 2 + 2 + 2)
294294 {
295 g_writeln("xrdp_caps_process_pointer: error");
295 LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_pointer: error");
296296 return 1;
297297 }
298298 no_new_cursor = self->client_info.pointer_flags & 2;
303303 self->client_info.pointer_cache_entries = i;
304304 if (colorPointerFlag & 1)
305305 {
306 g_writeln("xrdp_caps_process_pointer: client supports "
307 "new(color) cursor");
306 LOG(LOG_LEVEL_INFO, "xrdp_caps_process_pointer: client supports "
307 "new(color) cursor");
308308 in_uint16_le(s, i);
309309 i = MIN(i, 32);
310310 self->client_info.pointer_cache_entries = i;
311311 }
312312 else
313313 {
314 g_writeln("xrdp_caps_process_pointer: client does not support "
315 "new(color) cursor");
314 LOG(LOG_LEVEL_INFO, "xrdp_caps_process_pointer: client does not support "
315 "new(color) cursor");
316316 }
317317 if (no_new_cursor)
318318 {
319 g_writeln("xrdp_caps_process_pointer: new(color) cursor is "
320 "disabled by config");
319 LOG(LOG_LEVEL_INFO, "xrdp_caps_process_pointer: new(color) cursor is "
320 "disabled by config");
321321 self->client_info.pointer_flags = 0;
322322 }
323323 return 0;
351351
352352 if (len < 4)
353353 {
354 g_writeln("xrdp_caps_process_brushcache: error");
354 LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_brushcache: error");
355355 return 1;
356356 }
357357 in_uint32_le(s, code);
368368
369369 if (len < 40 + 4 + 2 + 2) /* MS-RDPBCGR 2.2.7.1.8 */
370370 {
371 g_writeln("xrdp_caps_process_glyphcache: error");
371 LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_glyphcache: error");
372372 return 1;
373373 }
374374
381381 {
382382 self->client_info.use_cache_glyph_v2 = 1;
383383 }
384 g_writeln("xrdp_caps_process_glyphcache: support level %d ",
384 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_process_glyphcache: support level %d ",
385385 glyph_support_level);
386386 return 0;
387387 }
395395
396396 if (len < 4 + 2 + 2)
397397 {
398 g_writeln("xrdp_caps_process_offscreen_bmpcache: error");
398 LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_offscreen_bmpcache: error");
399399 return 1;
400400 }
401401 in_uint32_le(s, i32);
404404 self->client_info.offscreen_cache_size = i32 * 1024;
405405 in_uint16_le(s, i32);
406406 self->client_info.offscreen_cache_entries = i32;
407 g_writeln("xrdp_process_offscreen_bmpcache: support level %d "
408 "cache size %d MB cache entries %d",
409 self->client_info.offscreen_support_level,
410 self->client_info.offscreen_cache_size,
411 self->client_info.offscreen_cache_entries);
407 LOG(LOG_LEVEL_INFO, "xrdp_process_offscreen_bmpcache: support level %d "
408 "cache size %d MB cache entries %d",
409 self->client_info.offscreen_support_level,
410 self->client_info.offscreen_cache_size,
411 self->client_info.offscreen_cache_entries);
412412 return 0;
413413 }
414414
420420
421421 if (len < 4)
422422 {
423 g_writeln("xrdp_caps_process_rail: error");
423 LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_rail: error");
424424 return 1;
425425 }
426426 in_uint32_le(s, i32);
427427 self->client_info.rail_support_level = i32;
428 g_writeln("xrdp_process_capset_rail: rail_support_level %d",
429 self->client_info.rail_support_level);
428 LOG(LOG_LEVEL_INFO, "xrdp_process_capset_rail: rail_support_level %d",
429 self->client_info.rail_support_level);
430430 return 0;
431431 }
432432
438438
439439 if (len < 4 + 1 + 2)
440440 {
441 g_writeln("xrdp_caps_process_window: error");
441 LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_window: error");
442442 return 1;
443443 }
444444 in_uint32_le(s, i32);
447447 self->client_info.wnd_num_icon_caches = i32;
448448 in_uint16_le(s, i32);
449449 self->client_info.wnd_num_icon_cache_entries = i32;
450 g_writeln("xrdp_process_capset_window wnd_support_level %d "
451 "wnd_num_icon_caches %d wnd_num_icon_cache_entries %d",
452 self->client_info.wnd_support_level,
453 self->client_info.wnd_num_icon_caches,
454 self->client_info.wnd_num_icon_cache_entries);
450 LOG(LOG_LEVEL_INFO, "xrdp_process_capset_window wnd_support_level %d "
451 "wnd_num_icon_caches %d wnd_num_icon_cache_entries %d",
452 self->client_info.wnd_support_level,
453 self->client_info.wnd_num_icon_caches,
454 self->client_info.wnd_num_icon_cache_entries);
455455 return 0;
456456 }
457457
469469
470470 if (len < 1)
471471 {
472 g_writeln("xrdp_caps_process_codecs: error");
472 LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_codecs: error");
473473 return 1;
474474 }
475475 in_uint8(s, codec_count);
480480 codec_guid = s->p;
481481 if (len < 16 + 1 + 2)
482482 {
483 g_writeln("xrdp_caps_process_codecs: error");
483 LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_codecs: error");
484484 return 1;
485485 }
486486 in_uint8s(s, 16);
489489 len -= 16 + 1 + 2;
490490 if (len < codec_properties_length)
491491 {
492 g_writeln("xrdp_caps_process_codecs: error");
492 LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_codecs: error");
493493 return 1;
494494 }
495495 len -= codec_properties_length;
497497
498498 if (g_memcmp(codec_guid, XR_CODEC_GUID_NSCODEC, 16) == 0)
499499 {
500 g_writeln("xrdp_caps_process_codecs: nscodec, codec id %d, properties len %d",
501 codec_id, codec_properties_length);
500 LOG(LOG_LEVEL_INFO, "xrdp_caps_process_codecs: nscodec, codec id %d, properties len %d",
501 codec_id, codec_properties_length);
502502 self->client_info.ns_codec_id = codec_id;
503503 i1 = MIN(64, codec_properties_length);
504504 g_memcpy(self->client_info.ns_prop, s->p, i1);
506506 }
507507 else if (g_memcmp(codec_guid, XR_CODEC_GUID_REMOTEFX, 16) == 0)
508508 {
509 g_writeln("xrdp_caps_process_codecs: RemoteFX, codec id %d, properties len %d",
510 codec_id, codec_properties_length);
509 LOG(LOG_LEVEL_INFO, "xrdp_caps_process_codecs: RemoteFX, codec id %d, properties len %d",
510 codec_id, codec_properties_length);
511511 self->client_info.rfx_codec_id = codec_id;
512512 i1 = MIN(64, codec_properties_length);
513513 g_memcpy(self->client_info.rfx_prop, s->p, i1);
515515 }
516516 else if (g_memcmp(codec_guid, XR_CODEC_GUID_JPEG, 16) == 0)
517517 {
518 g_writeln("xrdp_caps_process_codecs: jpeg, codec id %d, properties len %d",
519 codec_id, codec_properties_length);
518 LOG(LOG_LEVEL_INFO, "xrdp_caps_process_codecs: jpeg, codec id %d, properties len %d",
519 codec_id, codec_properties_length);
520520 self->client_info.jpeg_codec_id = codec_id;
521521 i1 = MIN(64, codec_properties_length);
522522 g_memcpy(self->client_info.jpeg_prop, s->p, i1);
524524 /* make sure that requested quality is between 0 to 100 */
525525 if (self->client_info.jpeg_prop[0] < 0 || self->client_info.jpeg_prop[0] > 100)
526526 {
527 g_writeln(" Warning: the requested jpeg quality (%d) is invalid,"
528 " falling back to default", self->client_info.jpeg_prop[0]);
527 LOG(LOG_LEVEL_WARNING, " Warning: the requested jpeg quality (%d) is invalid, "
528 "falling back to default", self->client_info.jpeg_prop[0]);
529529 self->client_info.jpeg_prop[0] = 75; /* use default */
530530 }
531 g_writeln(" jpeg quality set to %d", self->client_info.jpeg_prop[0]);
531 LOG(LOG_LEVEL_INFO, " jpeg quality set to %d", self->client_info.jpeg_prop[0]);
532532 }
533533 else if (g_memcmp(codec_guid, XR_CODEC_GUID_H264, 16) == 0)
534534 {
535 g_writeln("xrdp_caps_process_codecs: h264, codec id %d, properties len %d",
536 codec_id, codec_properties_length);
535 LOG(LOG_LEVEL_INFO, "xrdp_caps_process_codecs: h264, codec id %d, properties len %d",
536 codec_id, codec_properties_length);
537537 self->client_info.h264_codec_id = codec_id;
538538 i1 = MIN(64, codec_properties_length);
539539 g_memcpy(self->client_info.h264_prop, s->p, i1);
541541 }
542542 else
543543 {
544 g_writeln("xrdp_caps_process_codecs: unknown codec id %d", codec_id);
544 LOG(LOG_LEVEL_WARNING, "xrdp_caps_process_codecs: unknown codec id %d", codec_id);
545545 }
546546
547547 s->p = next_guid;
558558 int MaxRequestSize;
559559
560560 in_uint32_le(s, MaxRequestSize);
561 self->client_info.max_fastpath_frag_bytes = MaxRequestSize;
562 return 0;
563 }
564
565 /*****************************************************************************/
561 if (self->client_info.use_fast_path & 1)
562 {
563 self->client_info.max_fastpath_frag_bytes = MaxRequestSize;
564 }
565 return 0;
566 }
567
568 /*****************************************************************************/
566569 static int
567570 xrdp_caps_process_frame_ack(struct xrdp_rdp *self, struct stream *s, int len)
568571 {
569 g_writeln("xrdp_caps_process_frame_ack:");
572 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_process_frame_ack:");
570573 self->client_info.use_frame_acks = 1;
571574 in_uint32_le(s, self->client_info.max_unacknowledged_frame_count);
572575 if (self->client_info.max_unacknowledged_frame_count < 0)
573576 {
574 g_writeln(" invalid max_unacknowledged_frame_count value (%d), setting to 0",
575 self->client_info.max_unacknowledged_frame_count);
577 LOG(LOG_LEVEL_WARNING, " invalid max_unacknowledged_frame_count value (%d), setting to 0",
578 self->client_info.max_unacknowledged_frame_count);
576579 self->client_info.max_unacknowledged_frame_count = 0;
577580 }
578 g_writeln(" max_unacknowledged_frame_count %d", self->client_info.max_unacknowledged_frame_count);
581 LOG_DEVEL(LOG_LEVEL_TRACE, " max_unacknowledged_frame_count %d", self->client_info.max_unacknowledged_frame_count);
579582 return 0;
580583 }
581584
584587 xrdp_caps_process_surface_cmds(struct xrdp_rdp *self, struct stream *s, int len)
585588 {
586589 int cmdFlags;
587 g_writeln("xrdp_caps_process_surface_cmds:");
590 #ifndef XRDP_DEBUG
591 /* TODO: remove UNUSED_VAR once the `cmdFlags` variable is used for more than
592 logging in debug mode */
593 UNUSED_VAR(cmdFlags);
594 #endif
595 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_process_surface_cmds:");
588596 in_uint32_le(s, cmdFlags);
589597 in_uint8s(s, 4); /* reserved */
590 g_writeln(" cmdFlags 0x%08x", cmdFlags);
598 LOG_DEVEL(LOG_LEVEL_TRACE, " cmdFlags 0x%08x", cmdFlags);
591599 return 0;
592600 }
593601
603611 int len;
604612 char *p;
605613
606 DEBUG(("in xrdp_caps_process_confirm_active"));
614 LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_caps_process_confirm_active");
607615 in_uint8s(s, 4); /* rdp_shareid */
608616 in_uint8s(s, 2); /* userid */
609617 in_uint16_le(s, source_len); /* sizeof RDP_SOURCE */
622630 p = s->p;
623631 if (!s_check_rem(s, 4))
624632 {
625 g_writeln("xrdp_caps_process_confirm_active: error 1");
633 LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_confirm_active: error 1");
626634 return 1;
627635 }
628636 in_uint16_le(s, type);
629637 in_uint16_le(s, len);
630638 if ((len < 4) || !s_check_rem(s, len - 4))
631639 {
632 g_writeln("xrdp_caps_process_confirm_active: error: len %d, "
633 "remaining %d", len, (int) (s->end - s->p));
640 LOG(LOG_LEVEL_ERROR, "xrdp_caps_process_confirm_active: error: len %d, "
641 "remaining %d", len, (int) (s->end - s->p));
634642 return 1;
635643 }
636644 len -= 4;
637645 switch (type)
638646 {
639647 case CAPSTYPE_GENERAL:
640 DEBUG(("CAPSTYPE_GENERAL"));
648 LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_GENERAL");
641649 xrdp_caps_process_general(self, s, len);
642650 break;
643651 case CAPSTYPE_BITMAP:
644 DEBUG(("CAPSTYPE_BITMAP"));
652 LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_BITMAP");
645653 break;
646654 case CAPSTYPE_ORDER:
647 DEBUG(("CAPSTYPE_ORDER"));
655 LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_ORDER");
648656 xrdp_caps_process_order(self, s, len);
649657 break;
650658 case CAPSTYPE_BITMAPCACHE:
651 DEBUG(("CAPSTYPE_BMPCACHE"));
659 LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_BMPCACHE");
652660 xrdp_caps_process_bmpcache(self, s, len);
653661 break;
654662 case CAPSTYPE_CONTROL:
655 DEBUG(("CAPSTYPE_CONTROL"));
663 LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_CONTROL");
656664 break;
657665 case 6:
658666 xrdp_caps_process_cache_v3_codec_id(self, s, len);
659667 break;
660668 case CAPSTYPE_ACTIVATION:
661 DEBUG(("CAPSTYPE_ACTIVAION"));
669 LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_ACTIVAION");
662670 break;
663671 case CAPSTYPE_POINTER:
664 DEBUG(("CAPSTYPE_POINTER"));
672 LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_POINTER");
665673 xrdp_caps_process_pointer(self, s, len);
666674 break;
667675 case CAPSTYPE_SHARE:
668 DEBUG(("CAPSTYPE_SHARE"));
676 LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_SHARE");
669677 break;
670678 case CAPSTYPE_COLORCACHE:
671 DEBUG(("CAPSTYPE_COLORCACHE"));
679 LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_COLORCACHE");
672680 break;
673681 case CAPSTYPE_SOUND:
674 DEBUG(("CAPSTYPE_SOUND"));
682 LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_SOUND");
675683 break;
676684 case CAPSTYPE_INPUT:
677685 xrdp_caps_process_input(self, s, len);
678686 break;
679687 case CAPSTYPE_FONT:
680 DEBUG(("CAPSTYPE_FONT"));
688 LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_FONT");
681689 break;
682690 case CAPSTYPE_BRUSH:
683691 xrdp_caps_process_brushcache(self, s, len);
684692 break;
685693 case CAPSTYPE_GLYPHCACHE:
686 DEBUG(("CAPSTYPE_GLYPHCACHE"));
694 LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_GLYPHCACHE");
687695 xrdp_caps_process_glyphcache(self, s, len);
688696 break;
689697 case CAPSTYPE_OFFSCREENCACHE:
690 DEBUG(("CAPSTYPE_OFFSCREENCACHE"));
698 LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_OFFSCREENCACHE");
691699 xrdp_caps_process_offscreen_bmpcache(self, s, len);
692700 break;
693701 case CAPSTYPE_BITMAPCACHE_REV2:
694 DEBUG(("CAPSTYPE_BITMAPCACHE_REV2"));
702 LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_BITMAPCACHE_REV2");
695703 xrdp_caps_process_bmpcache2(self, s, len);
696704 break;
697705 case CAPSTYPE_VIRTUALCHANNEL:
698 DEBUG(("CAPSTYPE_VIRTUALCHANNEL"));
706 LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_VIRTUALCHANNEL");
699707 break;
700708 case CAPSTYPE_DRAWNINGRIDCACHE:
701 DEBUG(("CAPSTYPE_DRAWNINGRIDCACHE"));
709 LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_DRAWNINGRIDCACHE");
702710 break;
703711 case CAPSTYPE_DRAWGDIPLUS:
704 DEBUG(("CAPSTYPE_DRAWGDIPLUS"));
712 LOG_DEVEL(LOG_LEVEL_TRACE, "CAPSTYPE_DRAWGDIPLUS");
705713 break;
706714 case CAPSTYPE_RAIL:
707715 xrdp_caps_process_rail(self, s, len);
722730 xrdp_caps_process_frame_ack(self, s, len);
723731 break;
724732 default:
725 g_writeln("unknown in xrdp_caps_process_confirm_active %d", type);
733 LOG(LOG_LEVEL_WARNING, "unknown in xrdp_caps_process_confirm_active %d", type);
726734 break;
727735 }
728736
730738 }
731739
732740 if (self->client_info.no_orders_supported &&
733 (self->client_info.offscreen_support_level != 0))
734 {
735 g_writeln("xrdp_caps_process_confirm_active: not enough orders "
736 "supported by client, client wants off screen bitmap but "
737 "offscreen bitmaps disabled");
741 (self->client_info.offscreen_support_level != 0))
742 {
743 LOG(LOG_LEVEL_WARNING, "xrdp_caps_process_confirm_active: not enough orders "
744 "supported by client, client wants off screen bitmap but "
745 "offscreen bitmaps disabled");
738746 self->client_info.offscreen_support_level = 0;
739747 self->client_info.offscreen_cache_size = 0;
740748 self->client_info.offscreen_cache_entries = 0;
741749 }
742750
743 DEBUG(("out xrdp_caps_process_confirm_active"));
751 LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_caps_process_confirm_active");
744752 return 0;
745753 }
746754 /*****************************************************************************/
762770 make_stream(s);
763771 init_stream(s, 8192);
764772
765 DEBUG(("in xrdp_caps_send_demand_active"));
773 LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_caps_send_demand_active");
766774
767775 if (xrdp_rdp_init(self, s) != 0)
768776 {
10291037 free_stream(s);
10301038 return 1;
10311039 }
1032 DEBUG(("out (1) xrdp_caps_send_demand_active"));
1040 LOG_DEVEL(LOG_LEVEL_TRACE, "out (1) xrdp_caps_send_demand_active");
10331041
10341042 /* send Monitor Layout PDU for dual monitor */
10351043 if (self->client_info.monitorCount > 0 &&
1036 self->client_info.multimon == 1)
1037 {
1038 DEBUG(("xrdp_caps_send_demand_active: sending monitor layout pdu"));
1044 self->client_info.multimon == 1)
1045 {
1046 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: sending monitor layout pdu");
10391047 if (xrdp_caps_send_monitorlayout(self) != 0)
10401048 {
1041 g_writeln("xrdp_caps_send_demand_active: error sending monitor layout pdu");
1049 LOG(LOG_LEVEL_ERROR, "xrdp_caps_send_demand_active: error sending monitor layout pdu");
10421050 }
10431051 }
10441052
2222 #endif
2323
2424 #include "libxrdp.h"
25 #include "string_calls.h"
2526
2627 /* todo, move these to constants.h */
2728 //#define CHANNEL_CHUNK_LENGTH 1600 /* todo, why is this so small? */
5051
5152 if (self->mcs_layer->channel_list == NULL)
5253 {
53 g_writeln("xrdp_channel_get_item - No channel initialized");
54 LOG(LOG_LEVEL_ERROR, "xrdp_channel_get_item - No channel initialized");
5455 return NULL ;
5556 }
5657
113114
114115 if (channel == NULL)
115116 {
116 g_writeln("xrdp_channel_send - no such channel");
117 LOG(LOG_LEVEL_ERROR, "xrdp_channel_send - no such channel");
117118 return 1;
118119 }
119120
120121 if (channel->disabled)
121122 {
122 g_writeln("xrdp_channel_send, channel disabled");
123 LOG(LOG_LEVEL_WARNING, "xrdp_channel_send, channel disabled");
123124 return 0; /* not an error */
124125 }
125126
137138 *
138139 * That's flag makes MSTSC crash when using RAIL channel.
139140 */
140 // if (channel->flags & XR_CHANNEL_OPTION_SHOW_PROTOCOL)
141 // {
142 // flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
143 // }
141 // if (channel->flags & XR_CHANNEL_OPTION_SHOW_PROTOCOL)
142 // {
143 // flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
144 // }
144145
145146 out_uint32_le(s, flags);
146147
147148 if (xrdp_sec_send(self->sec_layer, s, channel->chanid) != 0)
148149 {
149 g_writeln("xrdp_channel_send - failure sending data");
150 LOG(LOG_LEVEL_ERROR, "xrdp_channel_send - failure sending data");
150151 return 1;
151152 }
152153
181182 }
182183 else
183184 {
184 g_writeln("in xrdp_channel_call_callback, session->callback is nil");
185 LOG(LOG_LEVEL_TRACE, "in xrdp_channel_call_callback, session->callback is nil");
185186 }
186187 }
187188 else
188189 {
189 g_writeln("in xrdp_channel_call_callback, session is nil");
190 LOG(LOG_LEVEL_TRACE, "in xrdp_channel_call_callback, session is nil");
190191 }
191192
192193 return rv;
268269 in_uint16_le(s, cap_version);
269270 if ((cap_version != 2) && (cap_version != 3))
270271 {
271 g_writeln("drdynvc_process_capability_response: incompatible DVC "
272 "version %d detected", cap_version);
273 return 1;
274 }
275 g_writeln("drdynvc_process_capability_response: DVC version %d selected",
276 cap_version);
272 LOG(LOG_LEVEL_ERROR, "drdynvc_process_capability_response: incompatible DVC "
273 "version %d detected", cap_version);
274 return 1;
275 }
276 LOG(LOG_LEVEL_INFO, "drdynvc_process_capability_response: DVC version %d selected",
277 cap_version);
277278 self->drdynvc_state = 1;
278279 session = self->sec_layer->rdp_layer->session;
279280 rv = session->callback(session->id, 0x5558, 0, 0, 0, 0);
299300 return 1;
300301 }
301302 in_uint32_le(s, creation_status);
302 //g_writeln("drdynvc_process_open_channel_response: chan_id 0x%x "
303 // "creation_status %d", chan_id, creation_status);
303 LOG_DEVEL(LOG_LEVEL_TRACE, "drdynvc_process_open_channel_response: chan_id 0x%x "
304 "creation_status %d", chan_id, creation_status);
304305 session = self->sec_layer->rdp_layer->session;
305306 if (chan_id > 255)
306307 {
335336 {
336337 return 1;
337338 }
338 //g_writeln("drdynvc_process_close_channel_response: chan_id 0x%x", chan_id);
339 LOG_DEVEL(LOG_LEVEL_TRACE, "drdynvc_process_close_channel_response: chan_id 0x%x", chan_id);
339340 session = self->sec_layer->rdp_layer->session;
340341 if (chan_id > 255)
341342 {
392393 in_uint32_le(s, total_bytes);
393394 }
394395 bytes = (int) (s->end - s->p);
395 //g_writeln("drdynvc_process_data_first: bytes %d total_bytes %d", bytes, total_bytes);
396 LOG_DEVEL(LOG_LEVEL_TRACE, "drdynvc_process_data_first: bytes %d total_bytes %d", bytes, total_bytes);
396397 session = self->sec_layer->rdp_layer->session;
397398 if (chan_id > 255)
398399 {
422423 return 1;
423424 }
424425 bytes = (int) (s->end - s->p);
425 //g_writeln("drdynvc_process_data: bytes %d", bytes);
426 LOG_DEVEL(LOG_LEVEL_TRACE, "drdynvc_process_data: bytes %d", bytes);
426427 session = self->sec_layer->rdp_layer->session;
427428 if (chan_id > 255)
428429 {
455456 }
456457 in_uint32_le(s, total_length);
457458 in_uint32_le(s, flags);
458 //g_writeln("xrdp_channel_process_drdynvc: total_length %d flags 0x%8.8x",
459 // total_length, flags);
459 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_channel_process_drdynvc: total_length %d flags 0x%8.8x",
460 total_length, flags);
460461 ls = NULL;
461462 switch (flags & 3)
462463 {
463464 case 0:
464465 length = (int) (s->end - s->p);
466 if (!s_check_rem_out(self->s, length))
467 {
468 return 1;
469 }
465470 out_uint8a(self->s, s->p, length);
466471 in_uint8s(s, length);
467472 return 0;
470475 make_stream(self->s);
471476 init_stream(self->s, total_length);
472477 length = (int) (s->end - s->p);
478 if (!s_check_rem_out(self->s, length))
479 {
480 return 1;
481 }
473482 out_uint8a(self->s, s->p, length);
474483 in_uint8s(s, length);
475484 return 0;
476485 case 2:
477486 length = (int) (s->end - s->p);
487 if (!s_check_rem_out(self->s, length))
488 {
489 return 1;
490 }
478491 out_uint8a(self->s, s->p, length);
479492 in_uint8s(s, length);
480493 ls = self->s;
483496 ls = s;
484497 break;
485498 default:
486 g_writeln("xrdp_channel_process_drdynvc: error");
499 LOG(LOG_LEVEL_ERROR, "xrdp_channel_process_drdynvc: error");
487500 return 1;
488501 }
489502 if (ls == NULL)
491504 return 1;
492505 }
493506 in_uint8(ls, cmd); /* read command */
494 //g_writeln("xrdp_channel_process_drdynvc: cmd 0x%x", cmd);
507 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_channel_process_drdynvc: cmd 0x%x", cmd);
495508 rv = 1;
496509 switch (cmd & 0xf0)
497510 {
511524 rv = drdynvc_process_data(self, cmd, s);
512525 break;
513526 default:
514 g_writeln("xrdp_channel_process_drdynvc: got unknown "
527 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_channel_process_drdynvc: got unknown "
515528 "command 0x%x", cmd);
516529 break;
517530 }
518 //g_writeln("xrdp_channel_process_drdynvc: rv %d", rv);
531 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_channel_process_drdynvc: rv %d", rv);
519532 return rv;
520533 }
521534
543556 channel = xrdp_channel_get_item(self, channel_id);
544557 if (channel == NULL)
545558 {
546 g_writeln("xrdp_channel_process, channel not found");
559 LOG(LOG_LEVEL_ERROR, "xrdp_channel_process, channel not found");
547560 return 1;
548561 }
549562 if (channel->disabled)
550563 {
551 g_writeln("xrdp_channel_process, channel disabled");
564 LOG(LOG_LEVEL_WARNING, "xrdp_channel_process, channel disabled");
552565 return 0; /* not an error */
553566 }
554567 if (channel_id == self->drdynvc_channel_id)
613626 struct mcs_channel_item *ci;
614627 struct mcs_channel_item *dci;
615628
616 g_writeln("xrdp_channel_drdynvc_start:");
629 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_channel_drdynvc_start:");
617630 dci = NULL;
618631 count = self->mcs_layer->channel_list->count;
619632 for (index = 0; index < count; index++)
713726 return 1;
714727 }
715728 if ((self->drdynvcs[chan_id].status != XRDP_DRDYNVC_STATUS_OPEN) &&
716 (self->drdynvcs[chan_id].status != XRDP_DRDYNVC_STATUS_OPEN_SENT))
729 (self->drdynvcs[chan_id].status != XRDP_DRDYNVC_STATUS_OPEN_SENT))
717730 {
718731 /* not open */
719732 return 1;
2121 #endif
2222
2323 #include "libxrdp.h"
24 #include "ms-rdpbcgr.h"
2425
2526 /*****************************************************************************/
2627 struct xrdp_fastpath *
2829 {
2930 struct xrdp_fastpath *self;
3031
31 DEBUG((" in xrdp_fastpath_create"));
32 LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_fastpath_create");
3233 self = (struct xrdp_fastpath *)g_malloc(sizeof(struct xrdp_fastpath), 1);
3334 self->sec_layer = owner;
3435 self->trans = trans;
3536 self->session = owner->rdp_layer->session;
36 DEBUG((" out xrdp_fastpath_create"));
37 LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_fastpath_create");
3738 return self;
3839 }
3940
6566 int byte;
6667 char *holdp;
6768
68 DEBUG((" in xrdp_fastpath_recv"));
69 LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_fastpath_recv");
6970 holdp = s->p;
7071 if (!s_check_rem(s, 2))
7172 {
9596 len = byte;
9697 }
9798 s->next_packet = holdp + len;
98 DEBUG((" out xrdp_fastpath_recv"));
99 LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_fastpath_recv");
99100 return 0;
100101 }
101102
144145 {
145146 return 1;
146147 }
147 xrdp_fastpath_session_callback(self, 0x5556, 0, 0, 0, 0);
148 if (self->session->check_for_app_input)
149 {
150 xrdp_fastpath_session_callback(self, 0x5556, 0, 0, 0, 0);
151 }
148152 return 0;
149153 }
150154
174178 }
175179
176180 if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_EXTENDED))
181 {
177182 flags |= KBD_FLAG_EXT;
183 }
178184
179185 xrdp_fastpath_session_callback(self, RDP_INPUT_SCANCODE,
180186 code, 0, flags, 0);
248254 xrdp_fastpath_process_EVENT_SYNC(struct xrdp_fastpath *self,
249255 int eventFlags, struct stream *s)
250256 {
251 /*
252 * The eventCode bitfield (3 bits in size) MUST be set to
253 * FASTPATH_INPUT_EVENT_SYNC (3).
254 * The eventFlags bitfield (5 bits in size) contains flags
255 * indicating the "on"
256 * status of the keyboard toggle keys.
257 */
257 /*
258 * The eventCode bitfield (3 bits in size) MUST be set to
259 * FASTPATH_INPUT_EVENT_SYNC (3).
260 * The eventFlags bitfield (5 bits in size) contains flags
261 * indicating the "on"
262 * status of the keyboard toggle keys.
263 */
258264
259265 xrdp_fastpath_session_callback(self, RDP_INPUT_SYNCHRONIZE,
260266 eventFlags, 0, 0, 0);
321327 {
322328 case FASTPATH_INPUT_EVENT_SCANCODE:
323329 if (xrdp_fastpath_process_EVENT_SCANCODE(self,
324 eventFlags,
325 s) != 0)
330 eventFlags,
331 s) != 0)
326332 {
327333 return 1;
328334 }
360366 }
361367 break;
362368 default:
363 g_writeln("xrdp_fastpath_process_input_event: unknown "
364 "eventCode %d", eventCode);
369 LOG(LOG_LEVEL_WARNING, "xrdp_fastpath_process_input_event: unknown "
370 "eventCode %d", eventCode);
365371 break;
366372 }
367373 }
2323 #endif
2424
2525 #include "libxrdp.h"
26 #include "ms-rdpbcgr.h"
2627 #include "log.h"
2728
28 #define LOG_LEVEL 1
29 #define LLOG(_level, _args) \
30 do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
31 #define LLOGLN(_level, _args) \
32 do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
33 #define LHEXDUMP(_level, _args) \
34 do { if (_level < LOG_LEVEL) { g_hexdump _args ; } } while (0)
29
3530
3631
3732 /*****************************************************************************/
4035 {
4136 struct xrdp_iso *self;
4237
43 LLOGLN(10, (" in xrdp_iso_create"));
38 LOG_DEVEL(LOG_LEVEL_DEBUG, " in xrdp_iso_create");
4439 self = (struct xrdp_iso *) g_malloc(sizeof(struct xrdp_iso), 1);
4540 self->mcs_layer = owner;
4641 self->trans = trans;
47 LLOGLN(10, (" out xrdp_iso_create"));
42 LOG_DEVEL(LOG_LEVEL_DEBUG, " out xrdp_iso_create");
4843 return self;
4944 }
5045
7873 if (self->requestedProtocol & PROTOCOL_SSL)
7974 {
8075 if (!g_file_readable(client_info->certificate) ||
81 !g_file_readable(client_info->key_file))
76 !g_file_readable(client_info->key_file))
8277 {
8378 /* certificate or privkey is not readable */
84 log_message(LOG_LEVEL_DEBUG, "No readable certificates or "
85 "private keys, cannot accept TLS connections");
79 LOG(LOG_LEVEL_WARNING, "No readable certificates or "
80 "private keys, cannot accept TLS connections");
8681 self->failureCode = SSL_CERT_NOT_ON_SERVER;
8782 rv = 1; /* error */
8883 }
10196 case PROTOCOL_HYBRID_EX:
10297 default:
10398 if ((self->requestedProtocol & PROTOCOL_SSL) &&
104 g_file_readable(client_info->certificate) &&
105 g_file_readable(client_info->key_file))
99 g_file_readable(client_info->certificate) &&
100 g_file_readable(client_info->key_file))
106101 {
107102 /* that's a patch since we don't support CredSSP for now */
108103 self->selectedProtocol = PROTOCOL_SSL;
114109 break;
115110 }
116111
117 log_message(LOG_LEVEL_DEBUG, "Security layer: requested %d, selected %d",
118 self->requestedProtocol, self->selectedProtocol);
112 LOG(LOG_LEVEL_DEBUG, "Security layer: requested %d, selected %d",
113 self->requestedProtocol, self->selectedProtocol);
119114 return rv;
120115 }
121116
127122 int flags;
128123 int len;
129124
125 if (!s_check_rem(s, 7))
126 {
127 LOG(LOG_LEVEL_ERROR, "xrdp_iso_process_rdpNegReq: unexpected end-of-record");
128 return 1;
129 }
130
130131 in_uint8(s, flags);
131132 if (flags != 0x0 && flags != 0x8 && flags != 0x1)
132133 {
133 LLOGLN(10, ("xrdp_iso_process_rdpNegReq: error, flags: %x",flags));
134 LOG(LOG_LEVEL_ERROR, "xrdp_iso_process_rdpNegReq: error, flags: %x", flags);
134135 return 1;
135136 }
136137
137138 in_uint16_le(s, len);
138139 if (len != 8)
139140 {
140 LLOGLN(10, ("xrdp_iso_process_rdpNegReq: error, length: %x",len));
141 LOG(LOG_LEVEL_ERROR, "xrdp_iso_process_rdpNegReq: error, length: %x", len);
141142 return 1;
142143 }
143144
144145 in_uint32_le(s, self->requestedProtocol);
145146 if (self->requestedProtocol > 0xb)
146147 {
147 LLOGLN(10, ("xrdp_iso_process_rdpNegReq: error, requestedProtocol: %x",
148 self->requestedProtocol));
149 return 1;
150 }
151
152 return 0;
153 }
154 /*****************************************************************************/
155 /* returns error */
148 LOG(LOG_LEVEL_ERROR, "xrdp_iso_process_rdpNegReq: error, requestedProtocol: %x",
149 self->requestedProtocol);
150 return 1;
151 }
152
153 return 0;
154 }
155 /*****************************************************************************
156 * Reads an X.224 PDU (X.224 section 13) preceded by a T.123 TPKT
157 * header (T.123 section 8)
158 *
159 * On entry, the TPKT header length field will have been inspected and used to
160 * set up the input stream.
161 *
162 * On exit, the TPKT header and the fixed part of the PDU header will have been
163 * removed from the stream.
164 *
165 * Returns error
166 *****************************************************************************/
156167 static int
157168 xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len)
158169 {
159170 int ver;
160 int plen;
161171
162172 *code = 0;
163173 *len = 0;
164174
165175 if (s != self->trans->in_s)
166176 {
167 LLOGLN(10, ("xrdp_iso_recv_msg error logic"));
177 LOG(LOG_LEVEL_WARNING, "xrdp_iso_recv_msg error logic");
178 }
179
180 /* TPKT header is 4 bytes, then first 2 bytes of the X.224 CR-TPDU */
181 if (!s_check_rem(s, 6))
182 {
183 return 1;
168184 }
169185
170186 in_uint8(s, ver);
171
172 if (ver != 3)
173 {
174 LLOGLN(10, ("xrdp_iso_recv_msg: bad ver"));
175 LHEXDUMP(10, (s->data, 4));
176 return 1;
177 }
178
179 in_uint8s(s, 1);
180 in_uint16_be(s, plen);
181
182 if (plen < 4)
183 {
184 return 1;
185 }
186
187 if (!s_check_rem(s, 2))
188 {
189 return 1;
190 }
191
187 in_uint8s(s, 3); /* Skip reserved field, plus length */
192188 in_uint8(s, *len);
193189 in_uint8(s, *code);
194190
191 if (ver != 3)
192 {
193 LOG(LOG_LEVEL_ERROR, "xrdp_iso_recv_msg: bad ver");
194 LOG_DEVEL_HEXDUMP(LOG_LEVEL_ERROR, "header", s->data, 4);
195 return 1;
196 }
197
198 if (*len == 255)
199 {
200 /* X.224 13.2.1 - reserved value */
201 LOG(LOG_LEVEL_ERROR, "xrdp_iso_recv_msg: reserved length encountered");
202 LOG_DEVEL_HEXDUMP(LOG_LEVEL_ERROR, "header", s->data, 4);
203 return 1;
204 }
205
195206 if (*code == ISO_PDU_DT)
196207 {
208 /* Data PDU : X.224 13.7 */
197209 if (!s_check_rem(s, 1))
198210 {
199211 return 1;
202214 }
203215 else
204216 {
217 /* Other supported PDUs : X.224 13.x */
205218 if (!s_check_rem(s, 5))
206219 {
207220 return 1;
220233 int code;
221234 int len;
222235
223 LLOGLN(10, (" in xrdp_iso_recv"));
236 LOG_DEVEL(LOG_LEVEL_DEBUG, " in xrdp_iso_recv");
224237
225238 if (xrdp_iso_recv_msg(self, s, &code, &len) != 0)
226239 {
227 LLOGLN(10, (" out xrdp_iso_recv xrdp_iso_recv_msg return non zero"));
240 LOG(LOG_LEVEL_ERROR, " out xrdp_iso_recv xrdp_iso_recv_msg return non zero");
228241 return 1;
229242 }
230243
231244 if (code != ISO_PDU_DT || len != 2)
232245 {
233 LLOGLN(10, (" out xrdp_iso_recv code != ISO_PDU_DT or length != 2"));
234 return 1;
235 }
236
237 LLOGLN(10, (" out xrdp_iso_recv"));
246 LOG(LOG_LEVEL_ERROR, " out xrdp_iso_recv code != ISO_PDU_DT or length != 2");
247 return 1;
248 }
249
250 LOG_DEVEL(LOG_LEVEL_DEBUG, " out xrdp_iso_recv");
238251 return 0;
239252 }
240253 /*****************************************************************************/
300313 free_stream(s);
301314 return 0;
302315 }
303 /*****************************************************************************/
316 /*****************************************************************************
317 * Process an X.224 connection request PDU
318 *
319 * See MS-RDPCGR v20190923 sections 2.2.1.1 and 3.3.5.3.1.
320 *
321 * From the latter, in particular:-
322 * - The length embedded in the TPKT header MUST be examined for
323 * consistency with the received data. If there is a discrepancy, the
324 * connection SHOULD be dropped
325 * - If the optional routingToken field exists it MUST be ignored.
326 * - If the optional cookie field is present it MUST be ignored.
327 * - If both the routingToken and cookie fields are present, the server
328 * SHOULD continue with the connection.
329 *****************************************************************************/
304330 /* returns error */
305331 int
306332 xrdp_iso_incoming(struct xrdp_iso *self)
308334 int rv = 0;
309335 int code;
310336 int len;
311 int cookie_index;
312337 int cc_type;
313 char text[256];
314 char *pend;
315338 struct stream *s;
316
317 LLOGLN(10, (" in xrdp_iso_incoming"));
339 int expected_pdu_len;
340
341 LOG_DEVEL(LOG_LEVEL_DEBUG, " in xrdp_iso_incoming");
318342
319343 s = libxrdp_force_read(self->trans);
320 if (s == 0)
344 if (s == NULL)
321345 {
322346 return 1;
323347 }
324348
325349 if (xrdp_iso_recv_msg(self, s, &code, &len) != 0)
326350 {
327 LLOGLN(0, ("xrdp_iso_incoming: xrdp_iso_recv_msg returned non zero"));
328 return 1;
329 }
330
331 if ((code != ISO_PDU_CR) || (len < 6))
332 {
351 LOG(LOG_LEVEL_ERROR, "xrdp_iso_incoming: xrdp_iso_recv_msg returned non zero");
352 return 1;
353 }
354
355 if (code != ISO_PDU_CR)
356 {
357 return 1;
358 }
359
360 /*
361 * Make sure the length indicator field extracted from the X.224
362 * connection request TPDU corresponds to the length in the TPKT header.
363 *
364 * We do this by seeing how the indicator field minus the counted
365 * octets in the TPDU header (6) compares with the space left in
366 * the stream.
367 */
368 expected_pdu_len = (s->end - s->p) + 6;
369 if (len != expected_pdu_len)
370 {
371 LOG(LOG_LEVEL_ERROR, "xrdp_iso_incoming: X.224 CR-TPDU length exp %d got %d",
372 expected_pdu_len, len);
333373 return 1;
334374 }
335375
336376 /* process connection request */
337 pend = s->p + (len - 6);
338 cookie_index = 0;
339 while (s->p < pend)
377 while (s_check_rem(s, 1))
340378 {
341379 in_uint8(s, cc_type);
342380 switch (cc_type)
347385 self->rdpNegData = 1;
348386 if (xrdp_iso_process_rdp_neg_req(self, s) != 0)
349387 {
350 LLOGLN(0, ("xrdp_iso_incoming: xrdp_iso_process_rdpNegReq returned non zero"));
388 LOG(LOG_LEVEL_ERROR, "xrdp_iso_incoming: xrdp_iso_process_rdpNegReq returned non zero");
351389 return 1;
352390 }
353391 break;
354392 case RDP_CORRELATION_INFO: /* rdpCorrelationInfo 6 */
355393 // TODO
394 if (!s_check_rem(s, 1 + 2 + 16 + 16))
395 {
396 LOG(LOG_LEVEL_ERROR, "xrdp_iso_incoming: short correlation info");
397 return 1;
398 }
399
356400 in_uint8s(s, 1 + 2 + 16 + 16);
357401 break;
358 case 'C': /* Cookie routingToken */
359 while (s->p < pend)
402 case 'C': /* Cookie */
403 /* The routingToken and cookie fields are both ASCII
404 * strings starting with the word 'Cookie: ' and
405 * ending with CR+LF. We ignore both, so we do
406 * not need to distinguish them */
407 while (s_check_rem(s, 1))
360408 {
361 text[cookie_index] = cc_type;
362 cookie_index++;
363 if (cookie_index > 255)
409 in_uint8(s, cc_type);
410 if (cc_type == 0x0D && s_check_rem(s, 1))
364411 {
365 cookie_index = 255;
412 in_uint8(s, cc_type);
413 if (cc_type == 0x0A)
414 {
415 break;
416 }
366417 }
367 if ((s->p[0] == 0x0D) && (s->p[1] == 0x0A))
368 {
369 in_uint8s(s, 2);
370 text[cookie_index] = 0;
371 cookie_index = 0;
372 if (g_strlen(text) > 0)
373 {
374 }
375 break;
376 }
377 in_uint8(s, cc_type);
378418 }
379419 break;
380420 }
386426 /* send connection confirm back to client */
387427 if (xrdp_iso_send_cc(self) != 0)
388428 {
389 LLOGLN(0, ("xrdp_iso_incoming: xrdp_iso_send_cc returned non zero"));
390 return 1;
391 }
392
393 LLOGLN(10, (" out xrdp_iso_incoming"));
429 LOG(LOG_LEVEL_ERROR, "xrdp_iso_incoming: xrdp_iso_send_cc returned non zero");
430 return 1;
431 }
432
433 LOG_DEVEL(LOG_LEVEL_DEBUG, " out xrdp_iso_incoming");
394434 return rv;
395435 }
396436
411451 {
412452 int len;
413453
414 LLOGLN(10, (" in xrdp_iso_send"));
454 LOG_DEVEL(LOG_LEVEL_DEBUG, " in xrdp_iso_send");
415455 s_pop_layer(s, iso_hdr);
416456 len = (int) (s->end - s->p);
417457 out_uint8(s, 3);
426466 return 1;
427467 }
428468
429 LLOGLN(10, (" out xrdp_iso_send"));
430 return 0;
431 }
469 LOG_DEVEL(LOG_LEVEL_DEBUG, " out xrdp_iso_send");
470 return 0;
471 }
5454
5555 if (bpp != 24)
5656 {
57 g_writeln("xrdp_jpeg_compress: bpp wrong %d", bpp);
57 LOG(LOG_LEVEL_WARNING, "xrdp_jpeg_compress: bpp wrong %d", bpp);
5858 return height;
5959 }
6060 if (handle == 0)
6161 {
62 g_writeln("xrdp_jpeg_compress: handle is nil");
62 LOG(LOG_LEVEL_WARNING, "xrdp_jpeg_compress: handle is nil");
6363 return height;
6464 }
6565 tj_han = (tjhandle) handle;
6969 temp_buf = 0;
7070 if (e == 0)
7171 {
72 src_buf = (unsigned char*)in_data;
72 src_buf = (unsigned char *)in_data;
7373 }
7474 else
7575 {
9696 }
9797 src_buf = (unsigned char *) temp_buf;
9898 }
99 dst_buf = (unsigned char*)(s->p);
99 dst_buf = (unsigned char *)(s->p);
100100 error = tjCompress(tj_han, src_buf, width + e, (width + e) * 4, height,
101101 TJPF_XBGR, dst_buf, &cdata_bytes,
102102 TJSAMP_420, quality, 0);
103103 if (error != 0)
104104 {
105 log_message(LOG_LEVEL_ERROR,
106 "xrdp_jpeg_compress: tjCompress error: %s",
107 tjGetErrorStr());
105 LOG(LOG_LEVEL_ERROR,
106 "xrdp_jpeg_compress: tjCompress error: %s",
107 tjGetErrorStr());
108108 }
109109
110110 s->p += cdata_bytes;
131131 int quality, /* higher numbers compress less */
132132 char *out_data, /* dest for jpg image */
133133 int *io_len /* length of out_data and on return */
134 /* len of compressed data */
135 )
134 /* len of compressed data */
135 )
136136 {
137137 tjhandle tj_han;
138138 int error;
146146
147147 if (handle == 0)
148148 {
149 g_writeln("xrdp_codec_jpeg_compress: handle is nil");
149 LOG(LOG_LEVEL_WARNING, "xrdp_codec_jpeg_compress: handle is nil");
150150 return height;
151151 }
152152
184184 TJSAMP_420, /* jpeg sub sample */
185185 quality, /* jpeg quality */
186186 0 /* flags */
187 );
187 );
188188 if (error != 0)
189189 {
190 log_message(LOG_LEVEL_ERROR,
191 "xrdp_codec_jpeg_compress: tjCompress error: %s",
192 tjGetErrorStr());
190 LOG(LOG_LEVEL_ERROR,
191 "xrdp_codec_jpeg_compress: tjCompress error: %s",
192 tjGetErrorStr());
193193 }
194194
195195 *io_len = lio_len;
302302 jpeg_create_compress(&cinfo);
303303 memset(&md, 0, sizeof(md));
304304 md.cb = comp_data,
305 md.cb_bytes = *comp_data_bytes;
305 md.cb_bytes = *comp_data_bytes;
306306 cinfo.client_data = &md;
307307 memset(&dst_mgr, 0, sizeof(dst_mgr));
308308 dst_mgr.init_destination = my_init_destination;
399399 }
400400 else
401401 {
402 g_writeln("bpp wrong %d", bpp);
402 LOG(LOG_LEVEL_WARNING, "bpp wrong %d", bpp);
403403 }
404404
405405 cdata_bytes = byte_limit;
2222 #endif
2323
2424 #include "libxrdp.h"
25 #include "ms-rdpbcgr.h"
2526 #include "log.h"
2627
2728 /*****************************************************************************/
3233 {
3334 struct xrdp_mcs *self;
3435
35 DEBUG((" in xrdp_mcs_create"));
36 LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_create");
3637 self = (struct xrdp_mcs *)g_malloc(sizeof(struct xrdp_mcs), 1);
3738 self->sec_layer = owner;
3839 self->userid = 1;
4142 self->server_mcs_data = server_mcs_data;
4243 self->iso_layer = xrdp_iso_create(self, trans);
4344 self->channel_list = list_create();
44 DEBUG((" out xrdp_mcs_create"));
45 LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_create");
4546 return self;
4647 }
4748
7273
7374 xrdp_iso_delete(self->iso_layer);
7475 /* make sure we get null pointer exception if struct is used again. */
75 DEBUG(("xrdp_mcs_delete processed"))
76 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mcs_delete processed");
7677 g_memset(self, 0, sizeof(struct xrdp_mcs)) ;
7778 g_free(self);
7879 }
8586 {
8687 struct stream *s;
8788
88 DEBUG((" in xrdp_mcs_send_cjcf"));
89 LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_send_cjcf");
8990 make_stream(s);
9091 init_stream(s, 8192);
9192
9293 if (xrdp_iso_init(self->iso_layer, s) != 0)
9394 {
9495 free_stream(s);
95 DEBUG((" out xrdp_mcs_send_cjcf error"));
96 LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send_cjcf error");
9697 return 1;
9798 }
9899
106107 if (xrdp_iso_send(self->iso_layer, s) != 0)
107108 {
108109 free_stream(s);
109 DEBUG((" out xrdp_mcs_send_cjcf error"));
110 LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send_cjcf error");
110111 return 1;
111112 }
112113
113114 free_stream(s);
114 DEBUG((" out xrdp_mcs_send_cjcf"));
115 LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_send_cjcf");
115116 return 0;
116117 }
117118
125126 int len;
126127 int userid;
127128 int chanid;
128 DEBUG((" in xrdp_mcs_recv"));
129 LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_recv");
129130
130131 while (1)
131132 {
132133 if (xrdp_iso_recv(self->iso_layer, s) != 0)
133134 {
134 DEBUG((" out xrdp_mcs_recv, xrdp_iso_recv return non zero"));
135 g_writeln("xrdp_mcs_recv: xrdp_iso_recv failed");
135 LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_recv, xrdp_iso_recv return non zero");
136 LOG(LOG_LEVEL_ERROR, "xrdp_mcs_recv: xrdp_iso_recv failed");
136137 return 1;
137138 }
138139
146147
147148 if (appid == MCS_DPUM) /* Disconnect Provider Ultimatum */
148149 {
149 g_writeln("received Disconnect Provider Ultimatum");
150 DEBUG((" out xrdp_mcs_recv appid != MCS_DPUM"));
150 LOG(LOG_LEVEL_ERROR, "received Disconnect Provider Ultimatum");
151 LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_recv appid != MCS_DPUM");
151152 return 1;
152153 }
153154
162163
163164 in_uint16_be(s, userid);
164165 in_uint16_be(s, chanid);
165 log_message(LOG_LEVEL_DEBUG,"MCS_CJRQ - channel join request received");
166 DEBUG(("xrdp_mcs_recv adding channel %4.4x", chanid));
166 LOG(LOG_LEVEL_DEBUG, "MCS_CJRQ - channel join request received");
167 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mcs_recv adding channel %4.4x", chanid);
167168
168169 if (xrdp_mcs_send_cjcf(self, userid, chanid) != 0)
169170 {
170 log_message(LOG_LEVEL_ERROR,"Non handled error from xrdp_mcs_send_cjcf") ;
171 LOG(LOG_LEVEL_ERROR, "Non handled error from xrdp_mcs_send_cjcf") ;
171172 }
172173
173174 s = libxrdp_force_read(self->iso_layer->trans);
174175 if (s == 0)
175176 {
176 g_writeln("xrdp_mcs_recv: libxrdp_force_read failed");
177 LOG(LOG_LEVEL_ERROR, "xrdp_mcs_recv: libxrdp_force_read failed");
177178 return 1;
178179 }
179180
186187 }
187188 else
188189 {
189 log_message(LOG_LEVEL_DEBUG,"Received an unhandled appid:%d",appid);
190 LOG(LOG_LEVEL_DEBUG, "Received an unhandled appid:%d", appid);
190191 }
191192
192193 break;
194195
195196 if (appid != MCS_SDRQ)
196197 {
197 DEBUG((" out xrdp_mcs_recv err got 0x%x need MCS_SDRQ", appid));
198 LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_recv err got 0x%x need MCS_SDRQ", appid);
198199 return 1;
199200 }
200201
217218 in_uint8s(s, 1);
218219 }
219220
220 DEBUG((" out xrdp_mcs_recv"));
221 LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_recv");
221222 return 0;
222223 }
223224
435436 int opcode;
436437 struct stream *s;
437438
438 DEBUG((" in xrdp_mcs_recv_edrq"));
439 LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_recv_edrq");
439440
440441 s = libxrdp_force_read(self->iso_layer->trans);
441442 if (s == 0)
482483 return 1;
483484 }
484485
485 DEBUG((" out xrdp_mcs_recv_edrq"));
486 LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_recv_edrq");
486487 return 0;
487488 }
488489
494495 int opcode;
495496 struct stream *s;
496497
497 DEBUG((" in xrdp_mcs_recv_aurq"));
498 LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_recv_aurq");
498499
499500 s = libxrdp_force_read(self->iso_layer->trans);
500501 if (s == 0)
533534 return 1;
534535 }
535536
536 DEBUG((" out xrdp_mcs_recv_aurq"));
537 LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_recv_aurq");
537538 return 0;
538539 }
539540
544545 {
545546 struct stream *s;
546547
547 DEBUG((" in xrdp_mcs_send_aucf"));
548 LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_send_aucf");
548549 make_stream(s);
549550 init_stream(s, 8192);
550551
551552 if (xrdp_iso_init(self->iso_layer, s) != 0)
552553 {
553554 free_stream(s);
554 DEBUG((" out xrdp_mcs_send_aucf error"));
555 LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send_aucf error");
555556 return 1;
556557 }
557558
563564 if (xrdp_iso_send(self->iso_layer, s) != 0)
564565 {
565566 free_stream(s);
566 DEBUG((" out xrdp_mcs_send_aucf error"));
567 LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send_aucf error");
567568 return 1;
568569 }
569570
570571 free_stream(s);
571 DEBUG((" out xrdp_mcs_send_aucf"));
572 LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_send_aucf");
572573 return 0;
573574 }
574575
720721 int index;
721722 int channel;
722723 int gcc_size;
723 char* gcc_size_ptr;
724 char* ud_ptr;
724 char *gcc_size_ptr;
725 char *ud_ptr;
725726
726727 num_channels = self->mcs_layer->channel_list->count;
727728 num_channels_even = num_channels + (num_channels & 1);
764765 out_uint8(s, 0);
765766 if (self->mcs_layer->iso_layer->rdpNegData)
766767 {
767 /* RequestedProtocol */
768 /* RequestedProtocol */
768769 out_uint32_le(s, self->mcs_layer->iso_layer->requestedProtocol);
769770 }
770771 out_uint16_le(s, SEC_TAG_SRV_CHANNELS);
787788
788789 if (self->rsa_key_bytes == 64)
789790 {
790 g_writeln("xrdp_sec_out_mcs_data: using 512 bit RSA key");
791 LOG(LOG_LEVEL_DEBUG, "xrdp_sec_out_mcs_data: using 512 bit RSA key");
791792 out_uint16_le(s, SEC_TAG_SRV_CRYPT);
792793 out_uint16_le(s, 0x00ec); /* len is 236 */
793794 out_uint32_le(s, self->crypt_method);
817818 }
818819 else if (self->rsa_key_bytes == 256)
819820 {
820 g_writeln("xrdp_sec_out_mcs_data: using 2048 bit RSA key");
821 LOG(LOG_LEVEL_DEBUG, "xrdp_sec_out_mcs_data: using 2048 bit RSA key");
821822 out_uint16_le(s, SEC_TAG_SRV_CRYPT);
822823 out_uint16_le(s, 0x01ac); /* len is 428 */
823824 out_uint32_le(s, self->crypt_method);
847848 }
848849 else if (self->rsa_key_bytes == 0) /* no security */
849850 {
850 g_writeln("xrdp_sec_out_mcs_data: using no security");
851 LOG(LOG_LEVEL_DEBUG, "xrdp_sec_out_mcs_data: using no security");
851852 out_uint16_le(s, SEC_TAG_SRV_CRYPT);
852853 out_uint16_le(s, 12); /* len is 12 */
853854 out_uint32_le(s, self->crypt_method);
855856 }
856857 else
857858 {
858 g_writeln("xrdp_sec_out_mcs_data: error");
859 LOG(LOG_LEVEL_ERROR, "xrdp_sec_out_mcs_data: error");
859860 }
860861 /* end certificate */
861862 s_mark_end(s);
874875 int data_len;
875876 struct stream *s;
876877
877 DEBUG((" in xrdp_mcs_send_connect_response"));
878 LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_send_connect_response");
878879 make_stream(s);
879880 init_stream(s, 8192);
880881 data_len = (int) (self->server_mcs_data->end - self->server_mcs_data->data);
881882 xrdp_iso_init(self->iso_layer, s);
882883 //TODO: we should calculate the whole length include MCS_CONNECT_RESPONSE
883884 xrdp_mcs_ber_out_header(self, s, MCS_CONNECT_RESPONSE,
884 data_len > 0x80 ? data_len + 38 : data_len + 36);
885 data_len > 0x80 ? data_len + 38 : data_len + 36);
885886 xrdp_mcs_ber_out_header(self, s, BER_TAG_RESULT, 1);
886887 out_uint8(s, 0);
887888 xrdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 1);
895896 if (xrdp_iso_send(self->iso_layer, s) != 0)
896897 {
897898 free_stream(s);
898 DEBUG((" out xrdp_mcs_send_connect_response error"));
899 LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send_connect_response error");
899900 return 1;
900901 }
901902
902903 free_stream(s);
903 DEBUG((" out xrdp_mcs_send_connect_response"));
904 LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_send_connect_response");
904905 return 0;
905906 }
906907
911912 {
912913 int index;
913914
914 DEBUG((" in xrdp_mcs_incoming"));
915 LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_incoming");
915916
916917 if (xrdp_mcs_recv_connect_initial(self) != 0)
917918 {
957958 }
958959
959960 if (xrdp_mcs_send_cjcf(self, self->userid,
960 self->userid + MCS_USERCHANNEL_BASE + index) != 0)
961 self->userid + MCS_USERCHANNEL_BASE + index) != 0)
961962 {
962963 return 1;
963964 }
964965 }
965966
966 DEBUG((" out xrdp_mcs_incoming"));
967 LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_incoming");
967968 return 0;
968969 }
969970
995996 {
996997 if (session->callback != 0)
997998 {
998 /* in xrdp_wm.c */
999 rv = session->callback(session->id, 0x5556, 0, 0, 0, 0);
999 if (session->check_for_app_input)
1000 {
1001 /* in xrdp_wm.c */
1002 rv = session->callback(session->id, 0x5556, 0, 0, 0, 0);
1003 }
10001004 }
10011005 else
10021006 {
1003 g_writeln("in xrdp_mcs_send, session->callback is nil");
1007 LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_mcs_send, session->callback is nil");
10041008 }
10051009 }
10061010 else
10071011 {
1008 g_writeln("in xrdp_mcs_send, session is nil");
1012 LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_mcs_send, session is nil");
10091013 }
10101014
10111015 return rv;
10201024 char *lp;
10211025 //static int max_len = 0;
10221026
1023 DEBUG((" in xrdp_mcs_send"));
1027 LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_send");
10241028 s_pop_layer(s, mcs_hdr);
10251029 len = (s->end - s->p) - 8;
10261030
10271031 if (len > 8192 * 2)
10281032 {
1029 g_writeln("error in xrdp_mcs_send, size too big: %d bytes", len);
1033 LOG(LOG_LEVEL_WARNING, "error in xrdp_mcs_send, size too big: %d bytes", len);
10301034 }
10311035
10321036 //if (len > max_len)
10631067
10641068 if (xrdp_iso_send(self->iso_layer, s) != 0)
10651069 {
1066 DEBUG((" out xrdp_mcs_send error"));
1070 LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_send error");
10671071 return 1;
10681072 }
10691073
10741078 xrdp_mcs_call_callback(self);
10751079 }
10761080
1077 DEBUG((" out xrdp_mcs_send"));
1081 LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_mcs_send");
10781082 return 0;
10791083 }
10801084
10921096 trans_shutdown_tls_mode(self->iso_layer->trans);
10931097 g_tcp_close(self->iso_layer->trans->sck);
10941098 self->iso_layer->trans->sck = 0 ;
1095 g_writeln("xrdp_mcs_disconnect - socket closed");
1099 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mcs_disconnect - socket closed");
10961100 return;
10971101 }
10981102 }
1099 g_writeln("Failed to close socket");
1103 LOG_DEVEL(LOG_LEVEL_TRACE, "Failed to close socket");
11001104 }
11011105
11021106 /*****************************************************************************/
11061110 {
11071111 struct stream *s;
11081112
1109 DEBUG((" in xrdp_mcs_disconnect"));
1113 LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_mcs_disconnect");
11101114 make_stream(s);
11111115 init_stream(s, 8192);
11121116
11141118 {
11151119 free_stream(s);
11161120 close_rdp_socket(self);
1117 DEBUG((" out xrdp_mcs_disconnect error - 1"));
1121 LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_disconnect error - 1");
11181122 return 1;
11191123 }
11201124
11261130 {
11271131 free_stream(s);
11281132 close_rdp_socket(self);
1129 DEBUG((" out xrdp_mcs_disconnect error - 2"));
1133 LOG(LOG_LEVEL_ERROR, " out xrdp_mcs_disconnect error - 2");
11301134 return 1;
11311135 }
11321136
11331137 free_stream(s);
11341138 close_rdp_socket(self);
1135 DEBUG(("xrdp_mcs_disconnect - close sent"));
1136 return 0;
1137 }
1139 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_mcs_disconnect - close sent");
1140 return 0;
1141 }
2222 #endif
2323
2424 #include "libxrdp.h"
25
26 #define MPPC_ENC_DEBUG 0
27
28 #if MPPC_ENC_DEBUG
29 #define DLOG(_args) g_printf _args
30 #else
31 #define DLOG(_args) do { } while (0)
32 #endif
3325
3426 /* local defines */
3527
4840
4941 #define CRC_INIT 0xFFFF
5042 #define CRC(_crcval, _newchar) _crcval = \
51 ((_crcval) >> 8) ^ g_crc_table[((_crcval) ^ (_newchar)) & 0x00ff]
43 ((_crcval) >> 8) ^ g_crc_table[((_crcval) ^ (_newchar)) & 0x00ff]
5244
5345 /* CRC16 defs */
5446 static const tui16 g_crc_table[256] =
9183 insert 2 bits into outputBuffer
9284 ******************************************************************************/
9385 #define insert_2_bits(_data) \
94 do \
95 { \
96 if ((bits_left >= 3) && (bits_left <= 8)) \
97 { \
98 i = bits_left - 2; \
99 outputBuffer[opb_index] |= _data << i; \
100 bits_left = i; \
101 } \
102 else \
103 { \
104 i = 2 - bits_left; \
105 j = 8 - i; \
106 outputBuffer[opb_index++] |= _data >> i; \
107 outputBuffer[opb_index] |= _data << j; \
108 bits_left = j; \
109 } \
110 } while (0)
86 do \
87 { \
88 if ((bits_left >= 3) && (bits_left <= 8)) \
89 { \
90 i = bits_left - 2; \
91 outputBuffer[opb_index] |= _data << i; \
92 bits_left = i; \
93 } \
94 else \
95 { \
96 i = 2 - bits_left; \
97 j = 8 - i; \
98 outputBuffer[opb_index++] |= _data >> i; \
99 outputBuffer[opb_index] |= _data << j; \
100 bits_left = j; \
101 } \
102 } while (0)
111103
112104 /*****************************************************************************
113105 insert 3 bits into outputBuffer
114106 ******************************************************************************/
115107 #define insert_3_bits(_data) \
116 do \
117 { \
118 if ((bits_left >= 4) && (bits_left <= 8)) \
119 { \
120 i = bits_left - 3; \
121 outputBuffer[opb_index] |= _data << i; \
122 bits_left = i; \
123 } \
124 else \
125 { \
126 i = 3 - bits_left; \
127 j = 8 - i; \
128 outputBuffer[opb_index++] |= _data >> i; \
129 outputBuffer[opb_index] |= _data << j; \
130 bits_left = j; \
131 } \
132 } while (0)
108 do \
109 { \
110 if ((bits_left >= 4) && (bits_left <= 8)) \
111 { \
112 i = bits_left - 3; \
113 outputBuffer[opb_index] |= _data << i; \
114 bits_left = i; \
115 } \
116 else \
117 { \
118 i = 3 - bits_left; \
119 j = 8 - i; \
120 outputBuffer[opb_index++] |= _data >> i; \
121 outputBuffer[opb_index] |= _data << j; \
122 bits_left = j; \
123 } \
124 } while (0)
133125
134126 /*****************************************************************************
135127 insert 4 bits into outputBuffer
136128 ******************************************************************************/
137129 #define insert_4_bits(_data) \
138 do \
139 { \
140 if ((bits_left >= 5) && (bits_left <= 8)) \
141 { \
142 i = bits_left - 4; \
143 outputBuffer[opb_index] |= _data << i; \
144 bits_left = i; \
145 } \
146 else \
147 { \
148 i = 4 - bits_left; \
149 j = 8 - i; \
150 outputBuffer[opb_index++] |= _data >> i; \
151 outputBuffer[opb_index] |= _data << j; \
152 bits_left = j; \
153 } \
154 } while (0)
130 do \
131 { \
132 if ((bits_left >= 5) && (bits_left <= 8)) \
133 { \
134 i = bits_left - 4; \
135 outputBuffer[opb_index] |= _data << i; \
136 bits_left = i; \
137 } \
138 else \
139 { \
140 i = 4 - bits_left; \
141 j = 8 - i; \
142 outputBuffer[opb_index++] |= _data >> i; \
143 outputBuffer[opb_index] |= _data << j; \
144 bits_left = j; \
145 } \
146 } while (0)
155147
156148 /*****************************************************************************
157149 insert 5 bits into outputBuffer
158150 ******************************************************************************/
159151 #define insert_5_bits(_data) \
160 do \
161 { \
162 if ((bits_left >= 6) && (bits_left <= 8)) \
163 { \
164 i = bits_left - 5; \
165 outputBuffer[opb_index] |= _data << i; \
166 bits_left = i; \
167 } \
168 else \
169 { \
170 i = 5 - bits_left; \
171 j = 8 - i; \
172 outputBuffer[opb_index++] |= _data >> i; \
173 outputBuffer[opb_index] |= _data << j; \
174 bits_left = j; \
175 } \
176 } while (0)
152 do \
153 { \
154 if ((bits_left >= 6) && (bits_left <= 8)) \
155 { \
156 i = bits_left - 5; \
157 outputBuffer[opb_index] |= _data << i; \
158 bits_left = i; \
159 } \
160 else \
161 { \
162 i = 5 - bits_left; \
163 j = 8 - i; \
164 outputBuffer[opb_index++] |= _data >> i; \
165 outputBuffer[opb_index] |= _data << j; \
166 bits_left = j; \
167 } \
168 } while (0)
177169
178170 /*****************************************************************************
179171 insert 6 bits into outputBuffer
180172 ******************************************************************************/
181173 #define insert_6_bits(_data) \
182 do \
183 { \
184 if ((bits_left >= 7) && (bits_left <= 8)) \
185 { \
186 i = bits_left - 6; \
187 outputBuffer[opb_index] |= (_data << i); \
188 bits_left = i; \
189 } \
190 else \
191 { \
192 i = 6 - bits_left; \
193 j = 8 - i; \
194 outputBuffer[opb_index++] |= (_data >> i); \
195 outputBuffer[opb_index] |= (_data << j); \
196 bits_left = j; \
197 } \
198 } while (0)
174 do \
175 { \
176 if ((bits_left >= 7) && (bits_left <= 8)) \
177 { \
178 i = bits_left - 6; \
179 outputBuffer[opb_index] |= (_data << i); \
180 bits_left = i; \
181 } \
182 else \
183 { \
184 i = 6 - bits_left; \
185 j = 8 - i; \
186 outputBuffer[opb_index++] |= (_data >> i); \
187 outputBuffer[opb_index] |= (_data << j); \
188 bits_left = j; \
189 } \
190 } while (0)
199191
200192 /*****************************************************************************
201193 insert 7 bits into outputBuffer
202194 ******************************************************************************/
203195 #define insert_7_bits(_data) \
204 do \
205 { \
206 if (bits_left == 8) \
207 { \
208 outputBuffer[opb_index] |= _data << 1; \
209 bits_left = 1; \
210 } \
211 else \
212 { \
213 i = 7 - bits_left; \
214 j = 8 - i; \
215 outputBuffer[opb_index++] |= _data >> i; \
216 outputBuffer[opb_index] |= _data << j; \
217 bits_left = j; \
218 } \
219 } while (0)
196 do \
197 { \
198 if (bits_left == 8) \
199 { \
200 outputBuffer[opb_index] |= _data << 1; \
201 bits_left = 1; \
202 } \
203 else \
204 { \
205 i = 7 - bits_left; \
206 j = 8 - i; \
207 outputBuffer[opb_index++] |= _data >> i; \
208 outputBuffer[opb_index] |= _data << j; \
209 bits_left = j; \
210 } \
211 } while (0)
220212
221213 /*****************************************************************************
222214 insert 8 bits into outputBuffer
223215 ******************************************************************************/
224216 #define insert_8_bits(_data) \
225 do \
226 { \
227 if (bits_left == 8) \
228 { \
229 outputBuffer[opb_index++] |= _data; \
230 bits_left = 8; \
231 } \
232 else \
233 { \
234 i = 8 - bits_left; \
235 j = 8 - i; \
236 outputBuffer[opb_index++] |= _data >> i; \
237 outputBuffer[opb_index] |= _data << j; \
238 bits_left = j; \
239 } \
240 } while (0)
217 do \
218 { \
219 if (bits_left == 8) \
220 { \
221 outputBuffer[opb_index++] |= _data; \
222 bits_left = 8; \
223 } \
224 else \
225 { \
226 i = 8 - bits_left; \
227 j = 8 - i; \
228 outputBuffer[opb_index++] |= _data >> i; \
229 outputBuffer[opb_index] |= _data << j; \
230 bits_left = j; \
231 } \
232 } while (0)
241233
242234 /*****************************************************************************
243235 insert 9 bits into outputBuffer
244236 ******************************************************************************/
245237 #define insert_9_bits(_data16) \
246 do \
247 { \
248 i = 9 - bits_left; \
249 j = 8 - i; \
250 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
251 outputBuffer[opb_index] |= (char) (_data16 << j); \
252 bits_left = j; \
253 if (bits_left == 0) \
254 { \
255 opb_index++; \
256 bits_left = 8; \
257 } \
258 } while (0)
259
260 /*****************************************************************************
261 insert 10 bits into outputBuffer
262 ******************************************************************************/
263 #define insert_10_bits(_data16) \
264 do \
265 { \
266 i = 10 - bits_left; \
267 if ((bits_left >= 3) && (bits_left <= 8)) \
268 { \
238 do \
239 { \
240 i = 9 - bits_left; \
269241 j = 8 - i; \
270242 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
271243 outputBuffer[opb_index] |= (char) (_data16 << j); \
272244 bits_left = j; \
273 } \
274 else \
275 { \
245 if (bits_left == 0) \
246 { \
247 opb_index++; \
248 bits_left = 8; \
249 } \
250 } while (0)
251
252 /*****************************************************************************
253 insert 10 bits into outputBuffer
254 ******************************************************************************/
255 #define insert_10_bits(_data16) \
256 do \
257 { \
258 i = 10 - bits_left; \
259 if ((bits_left >= 3) && (bits_left <= 8)) \
260 { \
261 j = 8 - i; \
262 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
263 outputBuffer[opb_index] |= (char) (_data16 << j); \
264 bits_left = j; \
265 } \
266 else \
267 { \
268 j = i - 8; \
269 k = 8 - j; \
270 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
271 outputBuffer[opb_index++] |= (char) (_data16 >> j); \
272 outputBuffer[opb_index] |= (char) (_data16 << k); \
273 bits_left = k; \
274 } \
275 } while (0)
276
277 /*****************************************************************************
278 insert 11 bits into outputBuffer
279 ******************************************************************************/
280 #define insert_11_bits(_data16) \
281 do \
282 { \
283 i = 11 - bits_left; \
284 if ((bits_left >= 4) && (bits_left <= 8)) \
285 { \
286 j = 8 - i; \
287 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
288 outputBuffer[opb_index] |= (char) (_data16 << j); \
289 bits_left = j; \
290 } \
291 else \
292 { \
293 j = i - 8; \
294 k = 8 - j; \
295 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
296 outputBuffer[opb_index++] |= (char) (_data16 >> j); \
297 outputBuffer[opb_index] |= (char) (_data16 << k); \
298 bits_left = k; \
299 } \
300 } while (0)
301
302 /*****************************************************************************
303 insert 12 bits into outputBuffer
304 ******************************************************************************/
305 #define insert_12_bits(_data16) \
306 do \
307 { \
308 i = 12 - bits_left; \
309 if ((bits_left >= 5) && (bits_left <= 8)) \
310 { \
311 j = 8 - i; \
312 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
313 outputBuffer[opb_index] |= (char) (_data16 << j); \
314 bits_left = j; \
315 } \
316 else \
317 { \
318 j = i - 8; \
319 k = 8 - j; \
320 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
321 outputBuffer[opb_index++] |= (char) (_data16 >> j); \
322 outputBuffer[opb_index] |= (char) (_data16 << k); \
323 bits_left = k; \
324 } \
325 } while (0)
326
327 /*****************************************************************************
328 insert 13 bits into outputBuffer
329 ******************************************************************************/
330 #define insert_13_bits(_data16) \
331 do \
332 { \
333 i = 13 - bits_left; \
334 if ((bits_left >= 6) && (bits_left <= 8)) \
335 { \
336 j = 8 - i; \
337 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
338 outputBuffer[opb_index] |= (char) (_data16 << j); \
339 bits_left = j; \
340 } \
341 else \
342 { \
343 j = i - 8; \
344 k = 8 - j; \
345 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
346 outputBuffer[opb_index++] |= (char) (_data16 >> j); \
347 outputBuffer[opb_index] |= (char) (_data16 << k); \
348 bits_left = k; \
349 } \
350 } while (0)
351
352 /*****************************************************************************
353 insert 14 bits into outputBuffer
354 ******************************************************************************/
355 #define insert_14_bits(_data16) \
356 do \
357 { \
358 i = 14 - bits_left; \
359 if ((bits_left >= 7) && (bits_left <= 8)) \
360 { \
361 j = 8 - i; \
362 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
363 outputBuffer[opb_index] |= (char) (_data16 << j); \
364 bits_left = j; \
365 } \
366 else \
367 { \
368 j = i - 8; \
369 k = 8 - j; \
370 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
371 outputBuffer[opb_index++] |= (char) (_data16 >> j); \
372 outputBuffer[opb_index] |= (char) (_data16 << k); \
373 bits_left = k; \
374 } \
375 } while (0)
376
377 /*****************************************************************************
378 insert 15 bits into outputBuffer
379 ******************************************************************************/
380 #define insert_15_bits(_data16) \
381 do \
382 { \
383 i = 15 - bits_left; \
384 if (bits_left == 8) \
385 { \
386 j = 8 - i; \
387 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
388 outputBuffer[opb_index] |= (char) (_data16 << j); \
389 bits_left = j; \
390 } \
391 else \
392 { \
393 j = i - 8; \
394 k = 8 - j; \
395 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
396 outputBuffer[opb_index++] |= (char) (_data16 >> j); \
397 outputBuffer[opb_index] |= (char) (_data16 << k); \
398 bits_left = k; \
399 } \
400 } while (0)
401
402 /*****************************************************************************
403 insert 16 bits into outputBuffer
404 ******************************************************************************/
405 #define insert_16_bits(_data16) \
406 do \
407 { \
408 i = 16 - bits_left; \
276409 j = i - 8; \
277410 k = 8 - j; \
278411 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
279412 outputBuffer[opb_index++] |= (char) (_data16 >> j); \
280413 outputBuffer[opb_index] |= (char) (_data16 << k); \
281414 bits_left = k; \
282 } \
283 } while (0)
284
285 /*****************************************************************************
286 insert 11 bits into outputBuffer
287 ******************************************************************************/
288 #define insert_11_bits(_data16) \
289 do \
290 { \
291 i = 11 - bits_left; \
292 if ((bits_left >= 4) && (bits_left <= 8)) \
293 { \
294 j = 8 - i; \
295 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
296 outputBuffer[opb_index] |= (char) (_data16 << j); \
297 bits_left = j; \
298 } \
299 else \
300 { \
301 j = i - 8; \
302 k = 8 - j; \
303 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
304 outputBuffer[opb_index++] |= (char) (_data16 >> j); \
305 outputBuffer[opb_index] |= (char) (_data16 << k); \
306 bits_left = k; \
307 } \
308 } while (0)
309
310 /*****************************************************************************
311 insert 12 bits into outputBuffer
312 ******************************************************************************/
313 #define insert_12_bits(_data16) \
314 do \
315 { \
316 i = 12 - bits_left; \
317 if ((bits_left >= 5) && (bits_left <= 8)) \
318 { \
319 j = 8 - i; \
320 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
321 outputBuffer[opb_index] |= (char) (_data16 << j); \
322 bits_left = j; \
323 } \
324 else \
325 { \
326 j = i - 8; \
327 k = 8 - j; \
328 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
329 outputBuffer[opb_index++] |= (char) (_data16 >> j); \
330 outputBuffer[opb_index] |= (char) (_data16 << k); \
331 bits_left = k; \
332 } \
333 } while (0)
334
335 /*****************************************************************************
336 insert 13 bits into outputBuffer
337 ******************************************************************************/
338 #define insert_13_bits(_data16) \
339 do \
340 { \
341 i = 13 - bits_left; \
342 if ((bits_left >= 6) && (bits_left <= 8)) \
343 { \
344 j = 8 - i; \
345 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
346 outputBuffer[opb_index] |= (char) (_data16 << j); \
347 bits_left = j; \
348 } \
349 else \
350 { \
351 j = i - 8; \
352 k = 8 - j; \
353 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
354 outputBuffer[opb_index++] |= (char) (_data16 >> j); \
355 outputBuffer[opb_index] |= (char) (_data16 << k); \
356 bits_left = k; \
357 } \
358 } while (0)
359
360 /*****************************************************************************
361 insert 14 bits into outputBuffer
362 ******************************************************************************/
363 #define insert_14_bits(_data16) \
364 do \
365 { \
366 i = 14 - bits_left; \
367 if ((bits_left >= 7) && (bits_left <= 8)) \
368 { \
369 j = 8 - i; \
370 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
371 outputBuffer[opb_index] |= (char) (_data16 << j); \
372 bits_left = j; \
373 } \
374 else \
375 { \
376 j = i - 8; \
377 k = 8 - j; \
378 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
379 outputBuffer[opb_index++] |= (char) (_data16 >> j); \
380 outputBuffer[opb_index] |= (char) (_data16 << k); \
381 bits_left = k; \
382 } \
383 } while (0)
384
385 /*****************************************************************************
386 insert 15 bits into outputBuffer
387 ******************************************************************************/
388 #define insert_15_bits(_data16) \
389 do \
390 { \
391 i = 15 - bits_left; \
392 if (bits_left == 8) \
393 { \
394 j = 8 - i; \
395 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
396 outputBuffer[opb_index] |= (char) (_data16 << j); \
397 bits_left = j; \
398 } \
399 else \
400 { \
401 j = i - 8; \
402 k = 8 - j; \
403 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
404 outputBuffer[opb_index++] |= (char) (_data16 >> j); \
405 outputBuffer[opb_index] |= (char) (_data16 << k); \
406 bits_left = k; \
407 } \
408 } while (0)
409
410 /*****************************************************************************
411 insert 16 bits into outputBuffer
412 ******************************************************************************/
413 #define insert_16_bits(_data16) \
414 do \
415 { \
416 i = 16 - bits_left; \
417 j = i - 8; \
418 k = 8 - j; \
419 outputBuffer[opb_index++] |= (char) (_data16 >> i); \
420 outputBuffer[opb_index++] |= (char) (_data16 >> j); \
421 outputBuffer[opb_index] |= (char) (_data16 << k); \
422 bits_left = k; \
423 } while (0)
415 } while (0)
424416
425417 /**
426418 * Initialize mppc_enc structure
605597 for (x = 0; x < 2; x++)
606598 {
607599 data = *(historyPointer + x);
608 DLOG(("%.2x ", (tui8) data));
600 LOG_DEVEL(LOG_LEVEL_TRACE, "%.2x ", (tui8) data);
609601 if (data & 0x80)
610602 {
611603 /* insert encoded literal */
677669
678670 /* double check that we have a pattern match */
679671 if ((*cptr1 != *cptr2) ||
680 (*(cptr1 + 1) != *(cptr2 + 1)) ||
681 (*(cptr1 + 2) != *(cptr2 + 2)))
672 (*(cptr1 + 1) != *(cptr2 + 1)) ||
673 (*(cptr1 + 2) != *(cptr2 + 2)))
682674 {
683675 /* no match found; encode literal byte */
684676 data = *cptr1;
685677
686 DLOG(("%.2x ", data));
678 LOG_DEVEL(LOG_LEVEL_TRACE, "%.2x ", data);
687679 if (data < 0x80)
688680 {
689681 /* literal byte < 0x80 */
709701 lom++;
710702 }
711703 saved_ctr = ctr + lom;
712 DLOG(("<%d: %ld,%d> ", (historyPointer + ctr) - hbuf_start,
713 copy_offset, lom));
704 LOG_DEVEL(LOG_LEVEL_TRACE, "<%ld: %u,%d> ", (historyPointer + ctr) - hbuf_start,
705 copy_offset, lom);
714706
715707 /* compute CRC for matching segment and store in hash table */
716708
950942 while (len - ctr > 0)
951943 {
952944 data = srcData[ctr];
953 DLOG(("%.2x ", data));
945 LOG_DEVEL(LOG_LEVEL_TRACE, "%.2x ", data);
954946 if (data < 0x80)
955947 {
956948 /* literal byte < 0x80 */
989981 enc->flags |= enc->flagsHold;
990982 enc->flagsHold = 0;
991983
992 DLOG(("\n"));
993
994 //g_writeln("compression ratio: %f", (float) len / (float) enc->bytes_in_opb);
984 LOG_DEVEL(LOG_LEVEL_TRACE, "\n");
985
986 LOG_DEVEL(LOG_LEVEL_TRACE, "compression ratio: %f", (float) len / (float) enc->bytes_in_opb);
995987
996988 return 1;
997989 }
2222 #endif
2323
2424 #include "libxrdp.h"
25 #include "ms-rdpbcgr.h"
26 #include "ms-rdpegdi.h"
2527
2628 #if defined(XRDP_NEUTRINORDP)
2729 #include <freerdp/codec/rfx.h>
2830 #endif
2931
30 #define LLOG_LEVEL 2
31 #define LLOGLN(_log_level, _params) \
32 { \
33 if (_log_level < LLOG_LEVEL) \
34 { \
35 g_write("xrdp_orders.c [%10.10u]: ", g_time3()); \
36 g_writeln _params ; \
37 } \
38 }
32
3933
4034 #define MAX_ORDERS_SIZE(_client_info) \
4135 (MAX((_client_info)->max_fastpath_frag_bytes, 16 * 1024) - 256);
111105 self->order_count = 0;
112106 if (self->rdp_layer->client_info.use_fast_path & 1)
113107 {
114 LLOGLN(10, ("xrdp_orders_init: fastpath"));
108 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_orders_init: fastpath");
115109 if (xrdp_rdp_init_fastpath(self->rdp_layer, self->out_s) != 0)
116110 {
117111 return 1;
121115 }
122116 else
123117 {
124 LLOGLN(10, ("xrdp_orders_init: slowpath"));
118 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_orders_init: slowpath");
125119 if (xrdp_rdp_init_data(self->rdp_layer, self->out_s) != 0)
126120 {
127121 return 1;
150144 if ((self->order_level == 0) && (self->order_count > 0))
151145 {
152146 s_mark_end(self->out_s);
153 DEBUG(("xrdp_orders_send sending %d orders", self->order_count));
147 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_orders_send sending %d orders", self->order_count);
154148 self->order_count_ptr[0] = self->order_count;
155149 self->order_count_ptr[1] = self->order_count >> 8;
156150 self->order_count = 0;
187181 if ((self->order_level > 0) && (self->order_count > 0))
188182 {
189183 s_mark_end(self->out_s);
190 DEBUG(("xrdp_orders_force_send sending %d orders", self->order_count));
184 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_orders_force_send sending %d orders", self->order_count);
191185 self->order_count_ptr[0] = self->order_count;
192186 self->order_count_ptr[1] = self->order_count >> 8;
193187 if (self->rdp_layer->client_info.use_fast_path & 1)
242236 size = (int)(self->out_s->p - self->order_count_ptr);
243237 if (size < 0)
244238 {
245 g_writeln("error in xrdp_orders_check, size too small: %d bytes", size);
239 LOG(LOG_LEVEL_ERROR, "error in xrdp_orders_check, size too small: %d bytes", size);
246240 return 1;
247241 }
248242 if (size > max_order_size)
250244 /* this suggests someone calls this function without passing the
251245 correct max_size so we end up putting more into the buffer
252246 than we indicate we can */
253 g_writeln("error in xrdp_orders_check, size too big: %d bytes", size);
247 LOG(LOG_LEVEL_WARNING, "error in xrdp_orders_check, size too big: %d bytes", size);
254248 /* We where getting called with size already greater than
255249 max_order_size
256250 Which I suspect was because the sending of text did not include
16451639 /*****************************************************************************/
16461640 /* returns error */
16471641 int
1648 xrdp_orders_composite_blt(struct xrdp_orders* self, int srcidx, int srcformat,
1649 int srcwidth, int srcrepeat, int* srctransform,
1642 xrdp_orders_composite_blt(struct xrdp_orders *self, int srcidx, int srcformat,
1643 int srcwidth, int srcrepeat, int *srctransform,
16501644 int mskflags, int mskidx, int mskformat,
16511645 int mskwidth, int mskrepeat, int op,
16521646 int srcx, int srcy, int mskx, int msky,
16531647 int dstx, int dsty, int width, int height,
16541648 int dstformat,
1655 struct xrdp_rect* rect)
1649 struct xrdp_rect *rect)
16561650 {
16571651 int order_flags;
16581652 int vals[20];
16591653 int present;
1660 char* present_ptr;
1661 char* order_flags_ptr;
1654 char *present_ptr;
1655 char *order_flags_ptr;
16621656
16631657 if (xrdp_orders_check(self, 80) != 0)
16641658 {
16751669 {
16761670 /* if clip is present, still check if it's needed */
16771671 if (dstx < rect->left || dsty < rect->top ||
1678 dstx + width > rect->right || dsty + height > rect->bottom)
1672 dstx + width > rect->right || dsty + height > rect->bottom)
16791673 {
16801674 order_flags |= TS_BOUNDS;
16811675 if (xrdp_orders_last_bounds(self, rect))
17221716 present_ptr = self->out_s->p;
17231717 out_uint8s(self->out_s, 3);
17241718 if ((order_flags & TS_BOUNDS) &&
1725 !(order_flags & TS_ZERO_BOUNDS_DELTAS))
1719 !(order_flags & TS_ZERO_BOUNDS_DELTAS))
17261720 {
17271721 xrdp_orders_out_bounds(self, rect);
17281722 }
22242218
22252219 if (width > 64)
22262220 {
2227 g_writeln("error, width > 64");
2221 LOG(LOG_LEVEL_ERROR, "error, width > 64");
22282222 return 1;
22292223 }
22302224
22312225 if (height > 64)
22322226 {
2233 g_writeln("error, height > 64");
2227 LOG(LOG_LEVEL_ERROR, "error, height > 64");
22342228 return 1;
22352229 }
22362230
23502344
23512345 if (width > 64)
23522346 {
2353 g_writeln("error, width > 64");
2347 LOG(LOG_LEVEL_ERROR, "error, width > 64");
23542348 return 1;
23552349 }
23562350
23572351 if (height > 64)
23582352 {
2359 g_writeln("error, height > 64");
2353 LOG(LOG_LEVEL_ERROR, "error, height > 64");
23602354 return 1;
23612355 }
23622356
24872481
24882482 /*****************************************************************************/
24892483 /* returns error */
2490 static int write_2byte_signed(struct stream * s, int value)
2484 static int write_2byte_signed(struct stream *s, int value)
24912485 {
24922486 unsigned char byte;
24932487 int negative = 0;
25332527
25342528 /*****************************************************************************/
25352529 /* returns error */
2536 static int write_2byte_unsigned(struct stream * s, unsigned int value)
2530 static int write_2byte_unsigned(struct stream *s, unsigned int value)
25372531 {
25382532 unsigned char byte;
25392533
25992593
26002594 out_uint8(self->out_s, char_index);
26012595 if (write_2byte_signed(self->out_s, font_char->offset) ||
2602 write_2byte_signed(self->out_s, font_char->baseline) ||
2603 write_2byte_unsigned(self->out_s, font_char->width) ||
2604 write_2byte_unsigned(self->out_s, font_char->height))
2596 write_2byte_signed(self->out_s, font_char->baseline) ||
2597 write_2byte_unsigned(self->out_s, font_char->width) ||
2598 write_2byte_unsigned(self->out_s, font_char->height))
26052599 {
26062600 return 1;
26072601 }
26502644
26512645 if (width > 64)
26522646 {
2653 g_writeln("error, width > 64");
2647 LOG(LOG_LEVEL_ERROR, "error, width > 64");
26542648 return 1;
26552649 }
26562650
26572651 if (height > 64)
26582652 {
2659 g_writeln("error, height > 64");
2653 LOG(LOG_LEVEL_ERROR, "error, height > 64");
26602654 return 1;
26612655 }
26622656
27782772
27792773 if (width > 64)
27802774 {
2781 g_writeln("error, width > 64");
2775 LOG(LOG_LEVEL_ERROR, "error, width > 64");
27822776 return 1;
27832777 }
27842778
27852779 if (height > 64)
27862780 {
2787 g_writeln("error, height > 64");
2781 LOG(LOG_LEVEL_ERROR, "error, height > 64");
27882782 return 1;
27892783 }
27902784
28912885 return 0;
28922886 }
28932887
2894 LLOGLN(10, ("width %d height %d rfx_min_pixel %d", width, height,
2895 self->rfx_min_pixel));
2888 LOG_DEVEL(LOG_LEVEL_DEBUG, "width %d height %d rfx_min_pixel %d", width, height,
2889 self->rfx_min_pixel);
28962890 if (width * height < self->rfx_min_pixel)
28972891 {
28982892 return 0;
29842978 return 2;
29852979 }
29862980
2987 LLOGLN(10, ("xrdp_orders_send_bitmap3: rfx"));
2981 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_orders_send_bitmap3: rfx");
29882982 context = (RFX_CONTEXT *)(self->rdp_layer->rfx_enc);
29892983 make_stream(xr_s);
29902984 init_stream(xr_s, 16384);
30133007
30143008 if (!xrdp_orders_send_as_jpeg(self, width, height, bpp, hints))
30153009 {
3016 LLOGLN(10, ("xrdp_orders_send_bitmap3: jpeg skipped"));
3010 LOG(LOG_LEVEL_ERROR, "xrdp_orders_send_bitmap3: jpeg skipped");
30173011 return 2;
30183012 }
30193013
3020 LLOGLN(10, ("xrdp_orders_send_bitmap3: jpeg"));
3014 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_orders_send_bitmap3: jpeg");
30213015 e = width % 4;
30223016
30233017 if (e != 0)
30453039 }
30463040 else
30473041 {
3048 g_writeln("xrdp_orders_send_bitmap3: todo unknown codec");
3042 LOG(LOG_LEVEL_ERROR, "xrdp_orders_send_bitmap3: todo unknown codec");
30493043 return 1;
30503044 }
30513045
31163110 order_flags |= 1 << 2; /* type RDP_ORDER_ALTSEC_CREATE_OFFSCR_BITMAP */
31173111 out_uint8(self->out_s, order_flags);
31183112 cache_id = id & 0x7fff;
3119 LLOGLN(10, ("xrdp_orders_send_create_os_surface: cache_id %d", cache_id));
3113 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_orders_send_create_os_surface: cache_id %d", cache_id);
31203114 flags = cache_id;
31213115
31223116 if (num_del_list > 0)
2020 #endif
2121
2222 #include "libxrdp.h"
23 #include "ms-rdpegdi.h"
2324 #include "xrdp_rail.h"
25 #include "string_calls.h"
2426
2527 /* [MS-RDPERP]: Remote Desktop Protocol:
2628 Remote Programs Virtual Channel Extension
2222 #endif
2323
2424 #include "libxrdp.h"
25 #include "ms-rdpbcgr.h"
2526 #include "log.h"
2627 #include "ssl_calls.h"
28 #include "string_calls.h"
2729
2830 #if defined(XRDP_NEUTRINORDP)
2931 #include <freerdp/codec/rfx.h>
3032 #include <freerdp/constants.h>
3133 #endif
3234
33 #define LOG_LEVEL 1
34 #define LLOG(_level, _args) \
35 do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
36 #define LLOGLN(_level, _args) \
37 do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
35
3836
3937 #define FASTPATH_FRAG_SIZE (16 * 1024 - 128)
4038
4139 /*****************************************************************************/
4240 static int
43 xrdp_rdp_read_config(struct xrdp_client_info *client_info)
41 xrdp_rdp_read_config(const char *xrdp_ini, struct xrdp_client_info *client_info)
4442 {
4543 int index = 0;
4644 struct list *items = (struct list *)NULL;
4745 struct list *values = (struct list *)NULL;
4846 char *item = NULL;
4947 char *value = NULL;
50 char cfg_file[256];
5148 int pos;
5249 char *tmp = NULL;
5350 int tmp_length = 0;
5451
5552 /* initialize (zero out) local variables: */
56 g_memset(cfg_file, 0, sizeof(char) * 256);
57
5853 items = list_create();
5954 items->auto_free = 1;
6055 values = list_create();
6156 values->auto_free = 1;
62 g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
63 DEBUG(("cfg_file %s", cfg_file));
64 file_by_name_read_section(cfg_file, "globals", items, values);
57 LOG_DEVEL(LOG_LEVEL_TRACE, "cfg_file %s", xrdp_ini);
58 file_by_name_read_section(xrdp_ini, "globals", items, values);
6559
6660 for (index = 0; index < items->count; index++)
6761 {
6862 item = (char *)list_get_item(items, index);
6963 value = (char *)list_get_item(values, index);
70 DEBUG(("item %s value %s", item, value));
64 LOG_DEVEL(LOG_LEVEL_TRACE, "item %s value %s", item, value);
7165
7266 if (g_strcasecmp(item, "bitmap_cache") == 0)
7367 {
10599 }
106100 else
107101 {
108 log_message(LOG_LEVEL_ALWAYS,"Warning: Your configured crypt level is "
109 "undefined, 'high' will be used");
102 LOG(LOG_LEVEL_ALWAYS, "Warning: Your configured crypt level is "
103 "undefined, 'high' will be used");
110104 client_info->crypt_level = 3;
111105 }
112106 }
115109 client_info->channels_allowed = g_text2bool(value);
116110 if (client_info->channels_allowed == 0)
117111 {
118 log_message(LOG_LEVEL_DEBUG,"Info - All channels are disabled");
112 LOG(LOG_LEVEL_DEBUG, "Info - All channels are disabled");
119113 }
120114 }
121115 else if (g_strcasecmp(item, "allow_multimon") == 0)
122 {
123 client_info->multimon = g_text2bool(value);
124 if (client_info->multimon == 0)
125 {
126 log_message(LOG_LEVEL_DEBUG,"Info - Multi monitor server support disabled");
127 }
128 }
116 {
117 client_info->multimon = g_text2bool(value);
118 if (client_info->multimon == 0)
119 {
120 LOG(LOG_LEVEL_DEBUG, "Info - Multi monitor server support disabled");
121 }
122 }
129123 else if (g_strcasecmp(item, "max_bpp") == 0)
130124 {
131125 client_info->max_bpp = g_atoi(value);
142136 {
143137 client_info->require_credentials = g_text2bool(value);
144138 }
139 else if (g_strcasecmp(item, "enable_token_login") == 0)
140 {
141 client_info->enable_token_login = g_text2bool(value);
142 }
145143 else if (g_strcasecmp(item, "use_fastpath") == 0)
146144 {
147145 if (g_strcasecmp(value, "output") == 0)
162160 }
163161 else
164162 {
165 log_message(LOG_LEVEL_ALWAYS,"Warning: Your configured fastpath level is "
166 "undefined, fastpath will not be used");
163 LOG(LOG_LEVEL_ALWAYS, "Warning: Your configured fastpath level is "
164 "undefined, fastpath will not be used");
167165 client_info->use_fast_path = 0;
168166 }
169167 }
206204 }
207205 else
208206 {
209 log_message(LOG_LEVEL_ERROR, "security_layer=%s is not "
210 "recognized, will use security_layer=negotiate",
211 value);
207 LOG(LOG_LEVEL_ERROR, "security_layer=%s is not "
208 "recognized, will use security_layer=negotiate",
209 value);
212210 client_info->security_layer = PROTOCOL_SSL | PROTOCOL_HYBRID | PROTOCOL_HYBRID_EX;
213211 }
214212 }
219217 {
220218 /* default certificate path */
221219 g_snprintf(client_info->certificate, 1023, "%s/cert.pem", XRDP_CFG_PATH);
222 log_message(LOG_LEVEL_INFO,
223 "Using default X.509 certificate: %s",
224 client_info->certificate);
220 LOG(LOG_LEVEL_INFO,
221 "Using default X.509 certificate: %s",
222 client_info->certificate);
225223
226224 }
227225 else if (value[0] != '/')
228226 {
229227 /* default certificate path */
230228 g_snprintf(client_info->certificate, 1023, "%s/cert.pem", XRDP_CFG_PATH);
231 log_message(LOG_LEVEL_WARNING,
232 "X.509 certificate should use absolute path, using "
233 "default instead: %s", client_info->certificate);
229 LOG(LOG_LEVEL_WARNING,
230 "X.509 certificate should use absolute path, using "
231 "default instead: %s", client_info->certificate);
234232 }
235233 else
236234 {
238236 g_strncpy(client_info->certificate, value, 1023);
239237 }
240238
241 if (!g_file_readable(client_info->certificate))
242 {
243 log_message(LOG_LEVEL_ERROR, "Cannot read certificate file %s: %s",
244 client_info->certificate, g_get_strerror());
239 if (!g_file_readable(client_info->certificate))
240 {
241 LOG(LOG_LEVEL_ERROR, "Cannot read certificate file %s: %s",
242 client_info->certificate, g_get_strerror());
245243 }
246244 }
247245 else if (g_strcasecmp(item, "key_file") == 0)
251249 {
252250 /* default key_file path */
253251 g_snprintf(client_info->key_file, 1023, "%s/key.pem", XRDP_CFG_PATH);
254 log_message(LOG_LEVEL_INFO, "Using default X.509 key file: %s",
255 client_info->key_file);
252 LOG(LOG_LEVEL_INFO, "Using default X.509 key file: %s",
253 client_info->key_file);
256254 }
257255 else if (value[0] != '/')
258256 {
259257 /* default key_file path */
260258 g_snprintf(client_info->key_file, 1023, "%s/key.pem", XRDP_CFG_PATH);
261 log_message(LOG_LEVEL_WARNING,
262 "X.509 key file should use absolute path, using "
263 "default instead: %s", client_info->key_file);
259 LOG(LOG_LEVEL_WARNING,
260 "X.509 key file should use absolute path, using "
261 "default instead: %s", client_info->key_file);
264262 }
265263 else
266264 {
270268
271269 if (!g_file_readable(client_info->key_file))
272270 {
273 log_message(LOG_LEVEL_ERROR, "Cannot read private key file %s: %s",
274 client_info->key_file, g_get_strerror());
275 }
276 }
277
271 LOG(LOG_LEVEL_ERROR, "Cannot read private key file %s: %s",
272 client_info->key_file, g_get_strerror());
273 }
274 }
275 else if (g_strcasecmp(item, "domain_user_separator") == 0
276 && g_strlen(value) > 0)
277 {
278 g_strncpy(client_info->domain_user_separator, value, sizeof(client_info->domain_user_separator) - 1);
279 }
278280 }
279281
280282 list_delete(items);
302304 "cpuid;"
303305 "xchg %%rbx, %%rsi;"
304306 #endif
305 : "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx)
306 : "0" (info)
307 );
307 : "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx)
308 : "0" (info)
309 );
308310 #endif
309311 #endif
310312 }
328330
329331 if (edx & (1 << 26))
330332 {
331 DEBUG(("SSE2 detected"));
333 LOG_DEVEL(LOG_LEVEL_TRACE, "SSE2 detected");
332334 cpu_opt |= CPU_SSE2;
333335 }
334336
343345 struct xrdp_rdp *self = (struct xrdp_rdp *)NULL;
344346 int bytes;
345347
346 DEBUG(("in xrdp_rdp_create"));
348 LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_create");
347349 self = (struct xrdp_rdp *)g_malloc(sizeof(struct xrdp_rdp), 1);
348350 self->session = session;
349351 self->share_id = 66538;
350352 /* read ini settings */
351 xrdp_rdp_read_config(&self->client_info);
353 xrdp_rdp_read_config(session->xrdp_ini, &self->client_info);
352354 /* create sec layer */
353355 self->sec_layer = xrdp_sec_create(self, trans);
354356 /* default 8 bit v1 color bitmap cache entries and size */
367369 rfx_context_set_cpu_opt(self->rfx_enc, xrdp_rdp_detect_cpu());
368370 #endif
369371 self->client_info.size = sizeof(self->client_info);
370 DEBUG(("out xrdp_rdp_create"));
372 LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_create");
371373 return self;
372374 }
373375
426428 int chan = 0;
427429 const tui8 *header;
428430
429 DEBUG(("in xrdp_rdp_recv"));
431 LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_recv");
430432 if (s->next_packet == 0 || s->next_packet >= s->end)
431433 {
432434 /* check for fastpath first */
439441 }
440442 /* next_packet gets set in xrdp_sec_recv_fastpath */
441443 *code = 2; // special code for fastpath input
442 DEBUG(("out (fastpath) xrdp_rdp_recv"));
444 LOG_DEVEL(LOG_LEVEL_TRACE, "out (fastpath) xrdp_rdp_recv");
443445 return 0;
444446 }
445447
451453 {
452454 s->next_packet = 0;
453455 *code = -1;
454 DEBUG(("out (1) xrdp_rdp_recv"));
456 LOG_DEVEL(LOG_LEVEL_TRACE, "out (1) xrdp_rdp_recv");
455457 return 0;
456458 }
457459
458460 if (error != 0)
459461 {
460 DEBUG(("out xrdp_rdp_recv error"));
461 g_writeln("xrdp_rdp_recv: xrdp_sec_recv failed");
462 LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_recv error");
462463 return 1;
463464 }
464465
468469 {
469470 if (xrdp_channel_process(self->sec_layer->chan_layer, s, chan) != 0)
470471 {
471 g_writeln("xrdp_channel_process returned unhandled error") ;
472 LOG(LOG_LEVEL_ERROR, "xrdp_channel_process returned unhandled error") ;
472473 }
473474 }
474475 else
475476 {
476477 if (chan != 1)
477478 {
478 g_writeln("Wrong channel Id to be handled by xrdp_channel_process %d", chan);
479 LOG(LOG_LEVEL_ERROR, "Wrong channel Id to be handled by xrdp_channel_process %d", chan);
479480 }
480481 }
481482
482483 s->next_packet = 0;
483484 *code = 0;
484 DEBUG(("out (2) xrdp_rdp_recv"));
485 LOG_DEVEL(LOG_LEVEL_TRACE, "out (2) xrdp_rdp_recv");
485486 return 0;
486487 }
487488
489490 }
490491 else
491492 {
492 DEBUG(("xrdp_rdp_recv stream not touched"))
493 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_recv stream not touched");
493494 s->p = s->next_packet;
494495 }
495496
497498 {
498499 s->next_packet = 0;
499500 *code = 0;
500 DEBUG(("out (3) xrdp_rdp_recv"));
501501 len = (int)(s->end - s->p);
502 g_writeln("xrdp_rdp_recv: bad RDP packet, length [%d]", len);
502 LOG_DEVEL(LOG_LEVEL_TRACE, "out (3) xrdp_rdp_recv: bad RDP packet, length [%d]", len);
503503 return 0;
504504 }
505505 else
506506 {
507507 in_uint16_le(s, len);
508 /*g_writeln("New len received : %d next packet: %d s_end: %d",len,s->next_packet,s->end); */
508 /*LOG_DEVEL(LOG_LEVEL_TRACE, "New len received : %d next packet: %d s_end: %d",len,s->next_packet,s->end); */
509509 in_uint16_le(s, pdu_code);
510510 *code = pdu_code & 0xf;
511511 in_uint8s(s, 2); /* mcs user id */
512512 s->next_packet += len;
513 DEBUG(("out (4) xrdp_rdp_recv"));
513 LOG_DEVEL(LOG_LEVEL_TRACE, "out (4) xrdp_rdp_recv");
514514 return 0;
515515 }
516516 }
521521 {
522522 int len = 0;
523523
524 DEBUG(("in xrdp_rdp_send"));
524 LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_send");
525525 s_pop_layer(s, rdp_hdr);
526526 len = s->end - s->p;
527527 out_uint16_le(s, len);
530530
531531 if (xrdp_sec_send(self->sec_layer, s, MCS_GLOBAL_CHANNEL) != 0)
532532 {
533 DEBUG(("out xrdp_rdp_send error"));
534 return 1;
535 }
536
537 DEBUG(("out xrdp_rdp_send"));
533 LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send error");
534 return 1;
535 }
536
537 LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_send");
538538 return 0;
539539 }
540540
557557 struct stream ls;
558558 struct xrdp_mppc_enc *mppc_enc;
559559
560 DEBUG(("in xrdp_rdp_send_data"));
560 LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_send_data");
561561 s_pop_layer(s, rdp_hdr);
562562 len = (int)(s->end - s->p);
563563 pdutype = 0x10 | PDUTYPE_DATAPDU;
572572 mppc_enc = self->mppc_enc;
573573 if (compress_rdp(mppc_enc, (tui8 *)(s->p + 18), tocomplen))
574574 {
575 DEBUG(("mppc_encode ok flags 0x%x bytes_in_opb %d historyOffset %d "
576 "tocomplen %d", mppc_enc->flags, mppc_enc->bytes_in_opb,
577 mppc_enc->historyOffset, tocomplen));
575 LOG_DEVEL(LOG_LEVEL_TRACE, "mppc_encode ok flags 0x%x bytes_in_opb %d historyOffset %d "
576 "tocomplen %d", mppc_enc->flags, mppc_enc->bytes_in_opb,
577 mppc_enc->historyOffset, tocomplen);
578578
579579 clen = mppc_enc->bytes_in_opb + 18;
580580 pdulen = clen;
599599 }
600600 else
601601 {
602 LLOGLN(10, ("xrdp_rdp_send_data: mppc_encode not ok "
603 "type %d flags %d", mppc_enc->protocol_type,
604 mppc_enc->flags));
602 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_data: mppc_encode not ok "
603 "type %d flags %d", mppc_enc->protocol_type,
604 mppc_enc->flags);
605605 }
606606 }
607607
618618
619619 if (xrdp_sec_send(self->sec_layer, s, MCS_GLOBAL_CHANNEL) != 0)
620620 {
621 DEBUG(("out xrdp_rdp_send_data error"));
622 return 1;
623 }
624
625 DEBUG(("out xrdp_rdp_send_data"));
621 LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send_data error");
622 return 1;
623 }
624
625 LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_send_data");
626626 return 0;
627627 }
628628
684684 struct stream send_s;
685685 struct xrdp_mppc_enc *mppc_enc;
686686
687 LLOGLN(10, ("xrdp_rdp_send_fastpath:"));
687 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_fastpath:");
688688 s_pop_layer(s, rdp_hdr);
689689 updateCode = data_pdu_type;
690690 if (self->client_info.rdp_compression)
728728 }
729729 }
730730 send_len = no_comp_len;
731 LLOGLN(10, ("xrdp_rdp_send_fastpath: no_comp_len %d fragmentation %d",
732 no_comp_len, fragmentation));
731 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_fastpath: no_comp_len %d fragmentation %d",
732 no_comp_len, fragmentation);
733733 if ((compression != 0) && (no_comp_len > header_bytes + 16))
734734 {
735735 to_comp_len = no_comp_len - header_bytes;
738738 to_comp_len))
739739 {
740740 comp_len = mppc_enc->bytes_in_opb + header_bytes;
741 LLOGLN(10, ("xrdp_rdp_send_fastpath: no_comp_len %d "
742 "comp_len %d", no_comp_len, comp_len));
741 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_fastpath: no_comp_len %d "
742 "comp_len %d", no_comp_len, comp_len);
743743 send_len = comp_len;
744744 comp_type = mppc_enc->flags;
745745 /* outputBuffer has 64 bytes preceding it */
746746 g_memset(&comp_s, 0, sizeof(comp_s));
747747 comp_s.data = mppc_enc->outputBuffer -
748 (rdp_offset + header_bytes);
748 (rdp_offset + header_bytes);
749749 comp_s.p = comp_s.data + rdp_offset;
750750 comp_s.end = comp_s.p + send_len;
751751 comp_s.size = send_len;
755755 }
756756 else
757757 {
758 LLOGLN(10, ("xrdp_rdp_send_fastpath: mppc_encode not ok "
759 "type %d flags %d", mppc_enc->protocol_type,
760 mppc_enc->flags));
758 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_fastpath: mppc_encode not ok "
759 "type %d flags %d", mppc_enc->protocol_type,
760 mppc_enc->flags);
761761 }
762762 }
763763 updateHeader = (updateCode & 15) |
764 ((fragmentation & 3) << 4) |
765 ((compression & 3) << 6);
764 ((fragmentation & 3) << 4) |
765 ((compression & 3) << 6);
766766 out_uint8(&send_s, updateHeader);
767767 if (compression != 0)
768768 {
773773 send_s.end = send_s.p + send_len;
774774 if (xrdp_sec_send_fastpath(self->sec_layer, &send_s) != 0)
775775 {
776 LLOGLN(0, ("xrdp_rdp_send_fastpath: xrdp_fastpath_send failed"));
776 LOG(LOG_LEVEL_ERROR, "xrdp_rdp_send_fastpath: xrdp_fastpath_send failed");
777777 return 1;
778778 }
779779 frag_s.p += no_comp_len;
793793
794794 make_stream(s);
795795 init_stream(s, 8192);
796 DEBUG(("in xrdp_rdp_send_data_update_sync"));
796 LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_send_data_update_sync");
797797
798798 if (self->client_info.use_fast_path & 1) /* fastpath output supported */
799799 {
800 LLOGLN(10, ("xrdp_rdp_send_data_update_sync: fastpath"));
800 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_rdp_send_data_update_sync: fastpath");
801801 if (xrdp_rdp_init_fastpath(self, s) != 0)
802802 {
803803 free_stream(s);
808808 {
809809 if (xrdp_rdp_init_data(self, s) != 0)
810810 {
811 DEBUG(("out xrdp_rdp_send_data_update_sync error"));
811 LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send_data_update_sync error");
812812 free_stream(s);
813813 return 1;
814814 }
831831 {
832832 if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_UPDATE) != 0)
833833 {
834 DEBUG(("out xrdp_rdp_send_data_update_sync error"));
834 LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send_data_update_sync error");
835835 free_stream(s);
836836 return 1;
837837 }
838838 }
839839
840840
841 DEBUG(("out xrdp_rdp_send_data_update_sync"));
841 LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_send_data_update_sync");
842842 free_stream(s);
843843 return 0;
844844 }
850850 struct xrdp_iso *iso;
851851 iso = self->sec_layer->mcs_layer->iso_layer;
852852
853 DEBUG(("in xrdp_rdp_incoming"));
853 LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_incoming");
854854
855855 if (xrdp_sec_incoming(self->sec_layer) != 0)
856856 {
858858 }
859859 self->mcs_channel = self->sec_layer->mcs_layer->userid +
860860 MCS_USERCHANNEL_BASE;
861 DEBUG(("out xrdp_rdp_incoming mcs channel %d", self->mcs_channel));
861 LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_incoming mcs channel %d", self->mcs_channel);
862862 g_strncpy(self->client_info.client_addr, iso->trans->addr,
863863 sizeof(self->client_info.client_addr) - 1);
864864 g_strncpy(self->client_info.client_port, iso->trans->port,
867867 /* log TLS version and cipher of TLS connections */
868868 if (iso->selectedProtocol > PROTOCOL_RDP)
869869 {
870 log_message(LOG_LEVEL_INFO,
871 "TLS connection established from %s port %s: %s with cipher %s",
872 self->client_info.client_addr,
873 self->client_info.client_port,
874 iso->trans->ssl_protocol,
875 iso->trans->cipher_name);
870 LOG(LOG_LEVEL_INFO,
871 "TLS connection established from %s port %s: %s with cipher %s",
872 self->client_info.client_addr,
873 self->client_info.client_port,
874 iso->trans->ssl_protocol,
875 iso->trans->cipher_name);
876876 }
877877 /* log non-TLS connections */
878878 else
879879 {
880 log_message(LOG_LEVEL_INFO,
881 "Non-TLS connection established from %s port %s: "
882 "encrypted with standard RDP security",
883 self->client_info.client_addr,
884 self->client_info.client_port);
880 LOG(LOG_LEVEL_INFO,
881 "Non-TLS connection established from %s port %s: "
882 "encrypted with standard RDP security",
883 self->client_info.client_addr,
884 self->client_info.client_port);
885885 }
886886
887887 return 0;
913913 }
914914 in_uint16_le(s, num_events);
915915 in_uint8s(s, 2); /* pad */
916 DEBUG(("in xrdp_rdp_process_data_input %d events", num_events));
916 LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_process_data_input %d events", num_events);
917917
918918 for (index = 0; index < num_events; index++)
919919 {
926926 in_uint16_le(s, device_flags);
927927 in_sint16_le(s, param1);
928928 in_sint16_le(s, param2);
929 DEBUG(("xrdp_rdp_process_data_input event %4.4x flags %4.4x param1 %d "
930 "param2 %d time %d", msg_type, device_flags, param1, param2, time));
929 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_input event %4.4x flags %4.4x param1 %d "
930 "param2 %d time %d", msg_type, device_flags, param1, param2, time);
931931
932932 if (self->session->callback != 0)
933933 {
942942 }
943943 }
944944
945 DEBUG(("out xrdp_rdp_process_data_input"));
945 LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_process_data_input");
946946 return 0;
947947 }
948948
10111011 {
10121012 int action;
10131013
1014 DEBUG(("xrdp_rdp_process_data_control"));
1014 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control");
10151015 in_uint16_le(s, action);
10161016 in_uint8s(s, 2); /* user id */
10171017 in_uint8s(s, 4); /* control id */
10181018
10191019 if (action == RDP_CTL_REQUEST_CONTROL)
10201020 {
1021 DEBUG(("xrdp_rdp_process_data_control got RDP_CTL_REQUEST_CONTROL"));
1022 DEBUG(("xrdp_rdp_process_data_control calling xrdp_rdp_send_synchronise"));
1021 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control got RDP_CTL_REQUEST_CONTROL");
1022 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control calling xrdp_rdp_send_synchronise");
10231023 xrdp_rdp_send_synchronise(self);
1024 DEBUG(("xrdp_rdp_process_data_control sending RDP_CTL_COOPERATE"));
1024 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control sending RDP_CTL_COOPERATE");
10251025 xrdp_rdp_send_control(self, RDP_CTL_COOPERATE);
1026 DEBUG(("xrdp_rdp_process_data_control sending RDP_CTL_GRANT_CONTROL"));
1026 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control sending RDP_CTL_GRANT_CONTROL");
10271027 xrdp_rdp_send_control(self, RDP_CTL_GRANT_CONTROL);
10281028 }
10291029 else
10301030 {
1031 DEBUG(("xrdp_rdp_process_data_control unknown action"));
1031 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_control unknown action");
10321032 }
10331033
10341034 return 0;
10381038 static int
10391039 xrdp_rdp_process_data_sync(struct xrdp_rdp *self)
10401040 {
1041 DEBUG(("xrdp_rdp_process_data_sync"));
1041 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data_sync");
10421042 return 0;
10431043 }
10441044
10621062 }
10631063 in_uint8(s, num_rects);
10641064 in_uint8s(s, 3); /* pad */
1065 g_writeln("xrdp_rdp_process_screen_update: num_rects %d", num_rects);
1065 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_screen_update: num_rects %d", num_rects);
10661066 for (index = 0; index < num_rects; index++)
10671067 {
10681068 if (!s_check_rem(s, 8))
10741074 in_uint16_le(s, top);
10751075 in_uint16_le(s, right);
10761076 in_uint16_le(s, bottom);
1077 g_writeln(" left %d top %d right %d bottom %d",
1077 LOG_DEVEL(LOG_LEVEL_TRACE, " left %d top %d right %d bottom %d",
10781078 left, top, right, bottom);
10791079 cx = (right - left) + 1;
10801080 cy = (bottom - top) + 1;
11251125 {
11261126 int seq;
11271127
1128 DEBUG(("in xrdp_rdp_process_data_font"));
1128 LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_process_data_font");
11291129 in_uint8s(s, 2); /* NumberFonts: 0x0, SHOULD be set to 0 */
11301130 in_uint8s(s, 2); /* TotalNumberFonts: 0x0, SHOULD be set to 0 */
11311131 in_uint16_le(s, seq); /* ListFlags */
11351135 if (seq == 2 || seq == 3) /* after second font message, we are up and */
11361136 {
11371137 /* running */
1138 DEBUG(("sending fontmap"));
1138 LOG_DEVEL(LOG_LEVEL_TRACE, "sending fontmap");
11391139 xrdp_rdp_send_fontmap(self);
11401140
11411141 self->session->up_and_running = 1;
1142 g_writeln("yeah, up_and_running");
1143 DEBUG(("up_and_running set"));
1142 LOG_DEVEL(LOG_LEVEL_TRACE, "yeah, up_and_running");
1143 LOG_DEVEL(LOG_LEVEL_TRACE, "up_and_running set");
11441144 xrdp_rdp_send_data_update_sync(self);
11451145 xrdp_channel_drdynvc_start(self->sec_layer->chan_layer);
11461146 }
11471147
1148 DEBUG(("out xrdp_rdp_process_data_font"));
1148 LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_process_data_font");
11491149 return 0;
11501150 }
11511151
12141214 {
12151215 int frame_id;
12161216
1217 //g_writeln("xrdp_rdp_process_frame_ack:");
1217 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_frame_ack:");
12181218 in_uint32_le(s, frame_id);
1219 //g_writeln(" frame_id %d", frame_id);
1219 LOG_DEVEL(LOG_LEVEL_TRACE, " frame_id %d", frame_id);
12201220 if (self->session->callback != 0)
12211221 {
12221222 /* call to xrdp_wm.c : callback */
12411241 return 1;
12421242 }
12431243 in_uint8(s, allowDisplayUpdates);
1244 g_writeln("xrdp_rdp_process_suppress: allowDisplayUpdates %d bytes "
1244 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_suppress: allowDisplayUpdates %d bytes "
12451245 "left %d", allowDisplayUpdates, (int) (s->end - s->p));
12461246 switch (allowDisplayUpdates)
12471247 {
12481248 case 0: /* SUPPRESS_DISPLAY_UPDATES */
12491249 self->client_info.suppress_output = 1;
1250 g_writeln("xrdp_rdp_process_suppress: suppress_output %d",
1250 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_suppress: suppress_output %d",
12511251 self->client_info.suppress_output);
12521252 if (self->session->callback != 0)
12531253 {
12661266 in_uint16_le(s, top);
12671267 in_uint16_le(s, right);
12681268 in_uint16_le(s, bottom);
1269 g_writeln("xrdp_rdp_process_suppress: suppress_output %d "
1269 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_suppress: suppress_output %d "
12701270 "left %d top %d right %d bottom %d",
12711271 self->client_info.suppress_output,
12721272 left, top, right, bottom);
13091309 {
13101310 return 1;
13111311 }
1312 DEBUG(("xrdp_rdp_process_data pduType2 %d", pduType2));
1312 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_rdp_process_data pduType2 %d", pduType2);
13131313 switch (pduType2)
13141314 {
13151315 case RDP_DATA_PDU_POINTER: /* 27(0x1b) */
13431343 xrdp_rdp_process_frame_ack(self, s);
13441344 break;
13451345 default:
1346 g_writeln("unknown in xrdp_rdp_process_data pduType2 %d", pduType2);
1346 LOG_DEVEL(LOG_LEVEL_TRACE, "unknown in xrdp_rdp_process_data pduType2 %d", pduType2);
13471347 break;
13481348 }
13491349 return 0;
13541354 {
13551355 int rv;
13561356
1357 DEBUG(("in xrdp_rdp_disconnect"));
1357 LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_disconnect");
13581358 rv = xrdp_sec_disconnect(self->sec_layer);
1359 DEBUG(("out xrdp_rdp_disconnect"));
1359 LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_disconnect");
13601360 return rv;
13611361 }
13621362
13661366 {
13671367 struct stream *s;
13681368
1369 DEBUG(("in xrdp_rdp_send_deactivate"));
1369 LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_rdp_send_deactivate");
13701370 make_stream(s);
13711371 init_stream(s, 8192);
13721372
13731373 if (xrdp_rdp_init(self, s) != 0)
13741374 {
13751375 free_stream(s);
1376 DEBUG(("out xrdp_rdp_send_deactivate error"));
1376 LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send_deactivate error");
13771377 return 1;
13781378 }
13791379
13821382 if (xrdp_rdp_send(self, s, PDUTYPE_DEACTIVATEALLPDU) != 0)
13831383 {
13841384 free_stream(s);
1385 DEBUG(("out xrdp_rdp_send_deactivate error"));
1385 LOG(LOG_LEVEL_ERROR, "out xrdp_rdp_send_deactivate error");
13861386 return 1;
13871387 }
13881388
13891389 free_stream(s);
1390 DEBUG(("out xrdp_rdp_send_deactivate"));
1390 LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_rdp_send_deactivate");
13911391 return 0;
13921392 }
13931393
13981398 {
13991399 struct stream *s;
14001400
1401 LLOGLN(0, ("xrdp_rdp_send_session_info: data_bytes %d", data_bytes));
1401 LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_rdp_send_session_info: data_bytes %d", data_bytes);
14021402 make_stream(s);
14031403 init_stream(s, 8192);
14041404
14101410
14111411 if (s_check_rem_out(s, data_bytes))
14121412 {
1413 out_uint8a(s, data, data_bytes);
1413 out_uint8a(s, data, data_bytes);
14141414 }
14151415 else
14161416 {
2222 #endif
2323
2424 #include "libxrdp.h"
25 #include "ms-rdpbcgr.h"
2526 #include "log.h"
26
27 #define LOG_LEVEL 1
28 #define LLOG(_level, _args) \
29 do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
30 #define LLOGLN(_level, _args) \
31 do { if (_level < LOG_LEVEL) { g_writeln _args ; } } while (0)
32 #define LHEXDUMP(_level, _args) \
33 do { if (_level < LOG_LEVEL) { g_hexdump _args ; } } while (0)
27 #include "string_calls.h"
28
29
3430
3531 /* some compilers need unsigned char to avoid warnings */
3632 static tui8 g_pad_54[40] =
239235 char keyboard_cfg_file[256] = { 0 };
240236 char rdp_layout[256] = { 0 };
241237
242 LLOGLN(0, ("xrdp_load_keyboard_layout: keyboard_type [%d] keyboard_subtype [%d]",
243 client_info->keyboard_type, client_info->keyboard_subtype));
238 LOG(LOG_LEVEL_INFO, "xrdp_load_keyboard_layout: keyboard_type [%d] keyboard_subtype [%d]",
239 client_info->keyboard_type, client_info->keyboard_subtype);
244240
245241 /* infer model/variant */
246242 /* TODO specify different X11 keyboard models/variants */
260256 }
261257
262258 g_snprintf(keyboard_cfg_file, 255, "%s/xrdp_keyboard.ini", XRDP_CFG_PATH);
263 LLOGLN(10, ("keyboard_cfg_file %s", keyboard_cfg_file));
259 LOG(LOG_LEVEL_DEBUG, "keyboard_cfg_file %s", keyboard_cfg_file);
264260
265261 fd = g_file_open(keyboard_cfg_file);
266262
291287 {
292288 item = (char *)list_get_item(items, i);
293289 value = (char *)list_get_item(values, i);
294 LLOGLN(10, ("xrdp_load_keyboard_layout: item %s value %s",
295 item, value));
290 LOG(LOG_LEVEL_DEBUG, "xrdp_load_keyboard_layout: item %s value %s",
291 item, value);
296292 if (g_strcasecmp(item, "keyboard_type") == 0)
297293 {
298294 int v = g_atoi(value);
305301 {
306302 int v = g_atoi(value);
307303 if (v != client_info->keyboard_subtype &&
308 section_found == index)
304 section_found == index)
309305 {
310306 section_found = -1;
311307 break;
358354 * mixing items from different sections will result in
359355 * skipping over current section.
360356 */
361 LLOGLN(10, ("xrdp_load_keyboard_layout: skipping "
362 "configuration item - %s, continuing to next "
363 "section", item));
357 LOG(LOG_LEVEL_DEBUG, "xrdp_load_keyboard_layout: skipping "
358 "configuration item - %s, continuing to next "
359 "section", item);
364360 break;
365361 }
366362 }
426422 list_delete(items);
427423 list_delete(values);
428424
429 LLOGLN(0, ("xrdp_load_keyboard_layout: model [%s] variant [%s] "
430 "layout [%s] options [%s]", client_info->model,
431 client_info->variant, client_info->layout, client_info->options));
425 LOG(LOG_LEVEL_INFO, "xrdp_load_keyboard_layout: model [%s] variant [%s] "
426 "layout [%s] options [%s]", client_info->model,
427 client_info->variant, client_info->layout, client_info->options);
432428 g_file_close(fd);
433429 }
434430 else
435431 {
436 LLOGLN(0, ("xrdp_load_keyboard_layout: error opening %s",
437 keyboard_cfg_file));
432 LOG(LOG_LEVEL_ERROR, "xrdp_load_keyboard_layout: error opening %s",
433 keyboard_cfg_file);
438434 }
439435 }
440436
444440 {
445441 struct xrdp_sec *self;
446442
447 DEBUG((" in xrdp_sec_create"));
443 LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_create");
448444 self = (struct xrdp_sec *) g_malloc(sizeof(struct xrdp_sec), 1);
449445 self->rdp_layer = owner;
450446 self->crypt_method = CRYPT_METHOD_NONE; /* set later */
454450 self->fastpath_layer = xrdp_fastpath_create(self, trans);
455451 self->chan_layer = xrdp_channel_create(self, self->mcs_layer);
456452 self->is_security_header_present = 1;
457 DEBUG((" out xrdp_sec_create"));
453 LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_create");
458454
459455 return self;
460456 }
465461 {
466462 if (self == 0)
467463 {
468 g_writeln("xrdp_sec_delete: self is null");
464 LOG(LOG_LEVEL_ERROR, "xrdp_sec_delete: self is null");
469465 return;
470466 }
471467
565561 static void
566562 xrdp_sec_fips_decrypt(struct xrdp_sec *self, char *data, int len)
567563 {
568 LLOGLN(10, ("xrdp_sec_fips_decrypt:"));
564 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_fips_decrypt:");
569565 ssl_des3_decrypt(self->decrypt_fips_info, len, data, data);
570566 self->decrypt_use_count++;
571567 }
574570 static void
575571 xrdp_sec_decrypt(struct xrdp_sec *self, char *data, int len)
576572 {
577 LLOGLN(10, ("xrdp_sec_decrypt:"));
573 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_decrypt:");
578574 if (self->decrypt_use_count == 4096)
579575 {
580576 xrdp_sec_update(self->decrypt_key, self->decrypt_update_key,
591587 static void
592588 xrdp_sec_fips_encrypt(struct xrdp_sec *self, char *data, int len)
593589 {
594 LLOGLN(10, ("xrdp_sec_fips_encrypt:"));
590 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_fips_encrypt:");
595591 ssl_des3_encrypt(self->encrypt_fips_info, len, data, data);
596592 self->encrypt_use_count++;
597593 }
600596 static void
601597 xrdp_sec_encrypt(struct xrdp_sec *self, char *data, int len)
602598 {
603 LLOGLN(10, ("xrdp_sec_encrypt:"));
599 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_encrypt:");
604600 if (self->encrypt_use_count == 4096)
605601 {
606602 xrdp_sec_update(self->encrypt_key, self->encrypt_update_key,
626622 int i;
627623 int bytes;
628624
629 LLOGLN(10, ("unicode_utf16_in: uni_len %d, dst_len %d", src_bytes, dst_len));
625 LOG_DEVEL(LOG_LEVEL_DEBUG, "unicode_utf16_in: uni_len %d, dst_len %d", src_bytes, dst_len);
630626 if (src_bytes == 0)
631627 {
632628 if (!s_check_rem(s, 2))
653649 {
654650 g_memset(dst, '\0', dst_len);
655651 }
656 LLOGLN(10, ("unicode_utf16_in: num_chars %d, dst %s", num_chars, dst));
652 LOG_DEVEL(LOG_LEVEL_DEBUG, "unicode_utf16_in: num_chars %d, dst %s", num_chars, dst);
657653 g_free(src);
658654
659655 return 0;
673669 int len_ip = 0;
674670 int len_dll = 0;
675671 char tmpdata[256];
672 const char *sep;
676673
677674 /* initialize (zero out) local variables */
678675 g_memset(tmpdata, 0, sizeof(char) * 256);
682679 }
683680 in_uint8s(s, 4);
684681 in_uint32_le(s, flags);
685 DEBUG(("in xrdp_sec_process_logon_info flags $%x", flags));
682 LOG_DEVEL(LOG_LEVEL_TRACE, "in xrdp_sec_process_logon_info flags $%x", flags);
686683
687684 /* this is the first test that the decrypt is working */
688685 if ((flags & RDP_LOGON_NORMAL) != RDP_LOGON_NORMAL) /* 0x33 */
689686 {
690687 /* must be or error */
691 DEBUG(("xrdp_sec_process_logon_info: flags wrong, major error"));
692 LLOGLN(0, ("xrdp_sec_process_logon_info: flags wrong, likely decrypt "
693 "not working"));
688 LOG(LOG_LEVEL_ERROR, "xrdp_sec_process_logon_info: flags wrong, likely decrypt "
689 "not working");
694690 return 1;
695691 }
696692
697693 if (flags & RDP_LOGON_LEAVE_AUDIO)
698694 {
699695 self->rdp_layer->client_info.sound_code = 1;
700 DEBUG(("flag RDP_LOGON_LEAVE_AUDIO found"));
696 LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_LOGON_LEAVE_AUDIO found");
701697 }
702698
703699 if (flags & RDP_LOGON_RAIL)
704700 {
705701 self->rdp_layer->client_info.rail_enable = 1;
706 DEBUG(("flag RDP_LOGON_RAIL found"));
702 LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_LOGON_RAIL found");
707703 }
708704
709705 if ((flags & RDP_LOGON_AUTO) && (!self->rdp_layer->client_info.is_mce))
710706 /* todo, for now not allowing autologon and mce both */
711707 {
712708 self->rdp_layer->client_info.rdp_autologin = 1;
713 DEBUG(("flag RDP_LOGON_AUTO found"));
709 LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_LOGON_AUTO found");
714710 }
715711
716712 if (flags & RDP_COMPRESSION)
717713 {
718 DEBUG(("flag RDP_COMPRESSION found"));
714 LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_COMPRESSION found");
719715 if (self->rdp_layer->client_info.use_bulk_comp)
720716 {
721 DEBUG(("flag RDP_COMPRESSION set"));
717 LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_COMPRESSION set");
722718 self->rdp_layer->client_info.rdp_compression = 1;
723719 }
724720 else
725721 {
726 DEBUG(("flag RDP_COMPRESSION not set"));
722 LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_COMPRESSION not set");
727723 }
728724 }
729725
733729 }
734730 in_uint16_le(s, len_domain);
735731
736 if (len_domain > 511)
737 {
738 DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_domain > 511"));
732 if (len_domain >= INFO_CLIENT_MAX_CB_LEN)
733 {
734 LOG(LOG_LEVEL_ERROR, "ERROR [xrdp_sec_process_logon_info()]: len_domain >= %d", INFO_CLIENT_MAX_CB_LEN);
739735 return 1;
740736 }
741737
755751 self->rdp_layer->client_info.rdp_autologin = 0;
756752 }
757753
758 if (len_user > 511)
759 {
760 DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_user > 511"));
754 if (len_user >= INFO_CLIENT_MAX_CB_LEN)
755 {
756 LOG(LOG_LEVEL_ERROR, "ERROR [xrdp_sec_process_logon_info()]: len_user >= %d", INFO_CLIENT_MAX_CB_LEN);
761757 return 1;
762758 }
763759
767763 }
768764 in_uint16_le(s, len_password);
769765
770 if (len_password > 511)
771 {
772 DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_password > 511"));
766 if (len_password >= INFO_CLIENT_MAX_CB_LEN)
767 {
768 LOG(LOG_LEVEL_ERROR, "ERROR [xrdp_sec_process_logon_info()]: len_password >= %d", INFO_CLIENT_MAX_CB_LEN);
773769 return 1;
774770 }
775771
779775 }
780776 in_uint16_le(s, len_program);
781777
782 if (len_program > 511)
783 {
784 DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_program > 511"));
778 if (len_program >= INFO_CLIENT_MAX_CB_LEN)
779 {
780 LOG(LOG_LEVEL_ERROR, "ERROR [xrdp_sec_process_logon_info()]: len_program >= %d", INFO_CLIENT_MAX_CB_LEN);
785781 return 1;
786782 }
787783
791787 }
792788 in_uint16_le(s, len_directory);
793789
794 if (len_directory > 511)
795 {
796 DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_directory > 511"));
790 if (len_directory >= INFO_CLIENT_MAX_CB_LEN)
791 {
792 LOG(LOG_LEVEL_ERROR, "ERROR [xrdp_sec_process_logon_info()]: len_directory >= %d", INFO_CLIENT_MAX_CB_LEN);
797793 return 1;
798794 }
799795
801797 {
802798 return 1;
803799 }
804 DEBUG(("domain %s", self->rdp_layer->client_info.domain));
800 LOG_DEVEL(LOG_LEVEL_TRACE, "domain %s", self->rdp_layer->client_info.domain);
805801 if (unicode_utf16_in(s, len_user, self->rdp_layer->client_info.username, sizeof(self->rdp_layer->client_info.username) - 1) != 0)
806802 {
807803 return 1;
808804 }
809 DEBUG(("username %s", self->rdp_layer->client_info.username));
805
810806
811807 if (flags & RDP_LOGON_AUTO)
812808 {
814810 {
815811 return 1;
816812 }
817 DEBUG(("flag RDP_LOGON_AUTO found"));
813 LOG_DEVEL(LOG_LEVEL_TRACE, "flag RDP_LOGON_AUTO found");
814 }
815 else if (self->rdp_layer->client_info.enable_token_login
816 && len_user > 0
817 && len_password == 0
818 && (sep = g_strchr(self->rdp_layer->client_info.username, '\x1f')) != NULL)
819 {
820 LOG_DEVEL(LOG_LEVEL_TRACE, "Logon token detected");
821 g_strncpy(self->rdp_layer->client_info.password, sep + 1,
822 sizeof(self->rdp_layer->client_info.password) - 1);
823 self->rdp_layer->client_info.username[sep - self->rdp_layer->client_info.username] = '\0';
824 self->rdp_layer->client_info.rdp_autologin = 1;
818825 }
819826 else
820827 {
825832 in_uint8s(s, len_password + 2);
826833 if (self->rdp_layer->client_info.require_credentials)
827834 {
828 g_writeln("xrdp_sec_process_logon_info: credentials on cmd line is mandatory");
835 LOG(LOG_LEVEL_ERROR, "xrdp_sec_process_logon_info: credentials on cmd line is mandatory");
829836 return 1; /* credentials on cmd line is mandatory */
830837 }
831838 }
839 if (self->rdp_layer->client_info.domain_user_separator[0] != '\0'
840 && self->rdp_layer->client_info.domain[0] != '\0')
841 {
842 int size = sizeof(self->rdp_layer->client_info.username);
843 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));
844 g_strncat(self->rdp_layer->client_info.username, self->rdp_layer->client_info.domain, size - 1 - g_strlen(self->rdp_layer->client_info.domain));
845 }
846 LOG_DEVEL(LOG_LEVEL_TRACE, "username %s", self->rdp_layer->client_info.username);
832847
833848 if (unicode_utf16_in(s, len_program, self->rdp_layer->client_info.program, sizeof(self->rdp_layer->client_info.program) - 1) != 0)
834849 {
835850 return 1;
836851 }
837 DEBUG(("program %s", self->rdp_layer->client_info.program));
852 LOG_DEVEL(LOG_LEVEL_TRACE, "program %s", self->rdp_layer->client_info.program);
838853 if (unicode_utf16_in(s, len_directory, self->rdp_layer->client_info.directory, sizeof(self->rdp_layer->client_info.directory) - 1) != 0)
839854 {
840855 return 1;
841856 }
842 DEBUG(("directory %s", self->rdp_layer->client_info.directory));
857 LOG_DEVEL(LOG_LEVEL_TRACE, "directory %s", self->rdp_layer->client_info.directory);
843858
844859 if (flags & RDP_LOGON_BLOB)
845860 {
874889 in_uint32_le(s, self->rdp_layer->client_info.rdp5_performanceflags);
875890 }
876891
877 DEBUG(("out xrdp_sec_process_logon_info"));
892 LOG_DEVEL(LOG_LEVEL_TRACE, "out xrdp_sec_process_logon_info");
878893 return 0;
879894 }
880895
885900 {
886901 struct stream *s;
887902
888 LLOGLN(10, ("xrdp_sec_send_lic_initial:"));
903 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_lic_initial:");
889904 make_stream(s);
890905 init_stream(s, 8192);
891906
10781093 const char *fips_ivec;
10791094 void *sha1;
10801095
1081 LLOGLN(0, ("xrdp_sec_fips_establish_keys:"));
1096 LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_sec_fips_establish_keys:");
10821097
10831098 sha1 = ssl_sha1_info_create();
10841099 ssl_sha1_clear(sha1);
11081123
11091124 fips_ivec = (const char *) g_fips_ivec;
11101125 self->encrypt_fips_info =
1111 ssl_des3_encrypt_info_create(self->fips_encrypt_key, fips_ivec);
1126 ssl_des3_encrypt_info_create(self->fips_encrypt_key, fips_ivec);
11121127 self->decrypt_fips_info =
1113 ssl_des3_decrypt_info_create(self->fips_decrypt_key, fips_ivec);
1128 ssl_des3_decrypt_info_create(self->fips_decrypt_key, fips_ivec);
11141129 self->sign_fips_info = ssl_hmac_info_create();
11151130 }
11161131
11221137 char temp_hash[48];
11231138 char input[48];
11241139
1125 LLOGLN(0, ("xrdp_sec_establish_keys:"));
1140 LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_sec_establish_keys:");
11261141
11271142 g_memcpy(input, self->client_random, 24);
11281143 g_memcpy(input + 24, self->server_random, 24);
11631178 int len;
11641179 int pad;
11651180
1166 LLOGLN(10, ("xrdp_sec_recv_fastpath:"));
1181 #ifndef XRDP_DEBUG
1182 /* TODO: remove UNUSED_VAR once the `var` variable is used for more than
1183 logging in debug mode */
1184 UNUSED_VAR(ver);
1185 #endif
1186
1187 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv_fastpath:");
11671188 if (xrdp_fastpath_recv(self->fastpath_layer, s) != 0)
11681189 {
11691190 return 1;
11841205 return 1;
11851206 }
11861207 in_uint8(s, pad);
1187 LLOGLN(10, ("xrdp_sec_recv_fastpath: len %d ver %d pad %d", len, ver, pad));
1208 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv_fastpath: len %d ver %d pad %d", len, ver, pad);
11881209 in_uint8s(s, 8); /* dataSignature (8 bytes), skip for now */
1189 LLOGLN(10, ("xrdp_sec_recv_fastpath: data len %d", (int)(s->end - s->p)));
1210 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv_fastpath: data len %d", (int)(s->end - s->p));
11901211 xrdp_sec_fips_decrypt(self, s->p, (int)(s->end - s->p));
11911212 s->end -= pad;
11921213 }
12261247 int ver;
12271248 int pad;
12281249
1229 DEBUG((" in xrdp_sec_recv"));
1250 LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_recv");
12301251
12311252 if (xrdp_mcs_recv(self->mcs_layer, s, chan) != 0)
12321253 {
1233 DEBUG((" out xrdp_sec_recv : error"));
1234 g_writeln("xrdp_sec_recv: xrdp_mcs_recv failed");
1254 LOG(LOG_LEVEL_ERROR, " out xrdp_sec_recv : error");
12351255 return 1;
12361256 }
12371257
12471267 }
12481268
12491269 in_uint32_le(s, flags);
1250 DEBUG((" in xrdp_sec_recv flags $%x", flags));
1270 LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_recv flags $%x", flags);
12511271
12521272 if (flags & SEC_ENCRYPT) /* 0x08 */
12531273 {
12641284 return 1;
12651285 }
12661286 in_uint8(s, pad);
1267 LLOGLN(10, ("xrdp_sec_recv: len %d ver %d pad %d", len, ver, pad));
1287 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv: len %d ver %d pad %d", len, ver, pad);
12681288 in_uint8s(s, 8); /* signature(8) */
1269 LLOGLN(10, ("xrdp_sec_recv: data len %d", (int)(s->end - s->p)));
1289 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv: data len %d", (int)(s->end - s->p));
12701290 xrdp_sec_fips_decrypt(self, s->p, (int)(s->end - s->p));
12711291 s->end -= pad;
12721292 }
13001320 in_uint8a(s, self->client_crypt_random, len - 8);
13011321 xrdp_sec_rsa_op(self, self->client_random, self->client_crypt_random,
13021322 len - 8, self->pub_mod, self->pri_exp);
1303 LLOGLN(10, ("xrdp_sec_recv: client random - len %d", len));
1304 LHEXDUMP(10, (self->client_random, 256));
1305 LHEXDUMP(10, (self->client_crypt_random, len - 8));
1323 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_recv: client random - len %d", len);
1324 LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "client random", self->client_random, 256);
1325 LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "client crypt random", self->client_crypt_random, len - 8);
13061326 if (self->crypt_level == CRYPT_LEVEL_FIPS)
13071327 {
13081328 xrdp_sec_fips_establish_keys(self);
13121332 xrdp_sec_establish_keys(self);
13131333 }
13141334 *chan = 1; /* just set a non existing channel and exit */
1315 DEBUG((" out xrdp_sec_recv"));
1335 LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_recv");
13161336 return 0;
13171337 }
13181338
13201340 {
13211341 if (xrdp_sec_process_logon_info(self, s) != 0)
13221342 {
1323 DEBUG((" out xrdp_sec_recv error"));
1343 LOG(LOG_LEVEL_ERROR, " out xrdp_sec_recv error");
13241344 return 1;
13251345 }
13261346
13281348 {
13291349 if (xrdp_sec_send_media_lic_response(self) != 0)
13301350 {
1331 DEBUG((" out xrdp_sec_recv error"));
1351 LOG(LOG_LEVEL_ERROR, " out xrdp_sec_recv error");
13321352 return 1;
13331353 }
13341354
1335 DEBUG((" out xrdp_sec_recv"));
1355 LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_recv");
13361356 return -1; /* special error that means send demand active */
13371357 }
13381358
13391359 if (xrdp_sec_send_lic_initial(self) != 0)
13401360 {
1341 DEBUG((" out xrdp_sec_recv error"));
1361 LOG(LOG_LEVEL_ERROR, " out xrdp_sec_recv error");
13421362 return 1;
13431363 }
13441364
13451365 *chan = 1; /* just set a non existing channel and exit */
1346 DEBUG((" out xrdp_sec_recv"));
1366 LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_recv");
13471367 return 0;
13481368 }
13491369
13511371 {
13521372 if (xrdp_sec_send_lic_response(self) != 0)
13531373 {
1354 DEBUG((" out xrdp_sec_recv error"));
1374 LOG(LOG_LEVEL_ERROR, " out xrdp_sec_recv error");
13551375 return 1;
13561376 }
13571377
13621382 self->is_security_header_present = 0;
13631383 }
13641384
1365 DEBUG((" out xrdp_sec_recv"));
1385 LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_recv");
13661386 return -1; /* special error that means send demand active */
13671387 }
13681388
1369 DEBUG((" out xrdp_sec_recv"));
1389 LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_recv");
13701390 return 0;
13711391 }
13721392
14371457 int datalen;
14381458 int pad;
14391459
1440 LLOGLN(10, ("xrdp_sec_send:"));
1441 DEBUG((" in xrdp_sec_send"));
1460 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send:");
1461 LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_send");
14421462 s_pop_layer(s, sec_hdr);
14431463
14441464 if (self->crypt_level > CRYPT_LEVEL_NONE)
14451465 {
14461466 if (self->crypt_level == CRYPT_LEVEL_FIPS)
14471467 {
1448 LLOGLN(10, ("xrdp_sec_send: fips"));
1468 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send: fips");
14491469 out_uint32_le(s, SEC_ENCRYPT);
14501470 datalen = (int)((s->end - s->p) - 12);
14511471 out_uint16_le(s, 16); /* crypto header size */
14751495 return 1;
14761496 }
14771497
1478 DEBUG((" out xrdp_sec_send"));
1498 LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_send");
14791499 return 0;
14801500 }
14811501
15341554 int error;
15351555 char save[8];
15361556
1537 LLOGLN(10, ("xrdp_sec_send_fastpath:"));
1557 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_fastpath:");
15381558 error = 0;
15391559 s_pop_layer(s, sec_hdr);
15401560 if (self->crypt_level == CRYPT_LEVEL_FIPS)
15411561 {
1542 LLOGLN(10, ("xrdp_sec_send_fastpath: fips"));
1562 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_fastpath: fips");
15431563 pdulen = (int)(s->end - s->p);
15441564 datalen = pdulen - 15;
15451565 pad = (8 - (datalen % 8)) & 7;
15621582 }
15631583 else if (self->crypt_level > CRYPT_LEVEL_LOW)
15641584 {
1565 LLOGLN(10, ("xrdp_sec_send_fastpath: crypt"));
1585 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_fastpath: crypt");
15661586 pdulen = (int)(s->end - s->p);
15671587 datalen = pdulen - 11;
15681588 secFlags = 0x2;
15761596 }
15771597 else
15781598 {
1579 LLOGLN(10, ("xrdp_sec_send_fastpath: no crypt"));
1599 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_fastpath: no crypt");
15801600 pdulen = (int)(s->end - s->p);
1581 LLOGLN(10, ("xrdp_sec_send_fastpath: pdulen %d", pdulen));
1601 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_send_fastpath: pdulen %d", pdulen);
15821602 secFlags = 0x0;
15831603 fpOutputHeader = secFlags << 6;
15841604 out_uint8(s, fpOutputHeader);
15971617 /* http://msdn.microsoft.com/en-us/library/cc240510.aspx
15981618 2.2.1.3.2 Client Core Data (TS_UD_CS_CORE) */
15991619 static int
1600 xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec* self, struct stream* s)
1620 xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s)
16011621 {
16021622 int colorDepth;
16031623 int postBeta2ColorDepth;
16101630 in_uint16_le(s, self->rdp_layer->client_info.width);
16111631 in_uint16_le(s, self->rdp_layer->client_info.height);
16121632 in_uint16_le(s, colorDepth);
1613 g_writeln("colorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp)", colorDepth);
1633 LOG_DEVEL(LOG_LEVEL_TRACE, "colorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp)", colorDepth);
16141634 switch (colorDepth)
16151635 {
16161636 case RNS_UD_COLOR_4BPP:
16241644 in_uint8s(s, 4); /* keyboardLayout */
16251645 in_uint8s(s, 4); /* clientBuild */
16261646 unicode_utf16_in(s, INFO_CLIENT_NAME_BYTES - 2, clientName, sizeof(clientName) - 1); /* clientName */
1627 log_message(LOG_LEVEL_INFO, "connected client computer name: %s", clientName);
1647 LOG(LOG_LEVEL_INFO, "connected client computer name: %s", clientName);
16281648 in_uint8s(s, 4); /* keyboardType */
16291649 in_uint8s(s, 4); /* keyboardSubType */
16301650 in_uint8s(s, 4); /* keyboardFunctionKey */
16311651 in_uint8s(s, 64); /* imeFileName */
16321652 in_uint16_le(s, postBeta2ColorDepth);
1633 g_writeln("postBeta2ColorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp "
1653 LOG_DEVEL(LOG_LEVEL_TRACE, "postBeta2ColorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp "
16341654 "0xca02 15bpp 0xca03 16bpp 0xca04 24bpp)", postBeta2ColorDepth);
16351655
16361656 switch (postBeta2ColorDepth)
16681688 return 0;
16691689 }
16701690 in_uint16_le(s, highColorDepth);
1671 g_writeln("highColorDepth 0x%4.4x (0x0004 4bpp 0x0008 8bpp 0x000f 15bpp "
1691 LOG_DEVEL(LOG_LEVEL_TRACE, "highColorDepth 0x%4.4x (0x0004 4bpp 0x0008 8bpp 0x000f 15bpp "
16721692 "0x0010 16 bpp 0x0018 24bpp)", highColorDepth);
16731693 self->rdp_layer->client_info.bpp = highColorDepth;
16741694
16771697 return 0;
16781698 }
16791699 in_uint16_le(s, supportedColorDepths);
1680 g_writeln("supportedColorDepths 0x%4.4x (0x0001 24bpp 0x0002 16bpp "
1700 LOG_DEVEL(LOG_LEVEL_TRACE, "supportedColorDepths 0x%4.4x (0x0001 24bpp 0x0002 16bpp "
16811701 "0x0004 15bpp 0x0008 32bpp)", supportedColorDepths);
16821702
16831703 if (!s_check_rem(s, 2))
16861706 }
16871707 in_uint16_le(s, earlyCapabilityFlags);
16881708 self->rdp_layer->client_info.mcs_early_capability_flags = earlyCapabilityFlags;
1689 g_writeln("earlyCapabilityFlags 0x%4.4x (0x0002 want32)",
1709 LOG_DEVEL(LOG_LEVEL_TRACE, "earlyCapabilityFlags 0x%4.4x (0x0002 want32)",
16901710 earlyCapabilityFlags);
16911711 if ((earlyCapabilityFlags & 0x0002) && (supportedColorDepths & 0x0008))
16921712 {
17041724 return 0;
17051725 }
17061726 in_uint8(s, self->rdp_layer->client_info.mcs_connection_type); /* connectionType */
1707 g_writeln("got client client connection type 0x%8.8x",
1727 LOG_DEVEL(LOG_LEVEL_TRACE, "got client client connection type 0x%8.8x",
17081728 self->rdp_layer->client_info.mcs_connection_type);
17091729
17101730 if (!s_check_rem(s, 1))
17421762
17431763 /*****************************************************************************/
17441764 static int
1745 xrdp_sec_process_mcs_data_CS_SECURITY(struct xrdp_sec *self, struct stream* s)
1765 xrdp_sec_process_mcs_data_CS_SECURITY(struct xrdp_sec *self, struct stream *s)
17461766 {
17471767 int crypt_method;
17481768 int found;
17491769
1750 g_writeln("xrdp_sec_process_mcs_data_CS_SECURITY:");
1770 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_process_mcs_data_CS_SECURITY:");
17511771 in_uint32_le(s, crypt_method);
17521772 if (crypt_method & CRYPT_METHOD_40BIT)
17531773 {
1754 g_writeln(" client supports 40 bit encryption");
1774 LOG(LOG_LEVEL_INFO, " client supports 40 bit encryption");
17551775 }
17561776 if (crypt_method & CRYPT_METHOD_128BIT)
17571777 {
1758 g_writeln(" client supports 128 bit encryption");
1778 LOG(LOG_LEVEL_INFO, " client supports 128 bit encryption");
17591779 }
17601780 if (crypt_method & CRYPT_METHOD_56BIT)
17611781 {
1762 g_writeln(" client supports 56 bit encryption");
1782 LOG(LOG_LEVEL_INFO, " client supports 56 bit encryption");
17631783 }
17641784 if (crypt_method & CRYPT_METHOD_FIPS)
17651785 {
1766 g_writeln(" client supports fips encryption");
1786 LOG(LOG_LEVEL_INFO, " client supports fips encryption");
17671787 }
17681788 found = 0;
17691789 if ((found == 0) &&
1770 (self->crypt_method & CRYPT_METHOD_FIPS) &&
1771 (self->crypt_level == CRYPT_LEVEL_FIPS))
1790 (self->crypt_method & CRYPT_METHOD_FIPS) &&
1791 (self->crypt_level == CRYPT_LEVEL_FIPS))
17721792 {
17731793 if (crypt_method & CRYPT_METHOD_FIPS)
17741794 {
1775 g_writeln(" client and server support fips, using fips");
1795 LOG(LOG_LEVEL_INFO, " client and server support fips, using fips");
17761796 self->crypt_method = CRYPT_METHOD_FIPS;
17771797 self->crypt_level = CRYPT_LEVEL_FIPS;
17781798 found = 1;
17791799 }
17801800 }
17811801 if ((found == 0) &&
1782 (self->crypt_method & CRYPT_METHOD_128BIT) &&
1783 (self->crypt_level == CRYPT_LEVEL_HIGH))
1802 (self->crypt_method & CRYPT_METHOD_128BIT) &&
1803 (self->crypt_level == CRYPT_LEVEL_HIGH))
17841804 {
17851805 if (crypt_method & CRYPT_METHOD_128BIT)
17861806 {
1787 g_writeln(" client and server support high crypt, using "
1788 "high crypt");
1807 LOG(LOG_LEVEL_INFO, " client and server support high crypt, using "
1808 "high crypt");
17891809 self->crypt_method = CRYPT_METHOD_128BIT;
17901810 self->crypt_level = CRYPT_LEVEL_HIGH;
17911811 found = 1;
17921812 }
17931813 }
17941814 if ((found == 0) &&
1795 (self->crypt_method & CRYPT_METHOD_40BIT) &&
1796 (self->crypt_level == CRYPT_LEVEL_CLIENT_COMPATIBLE))
1815 (self->crypt_method & CRYPT_METHOD_40BIT) &&
1816 (self->crypt_level == CRYPT_LEVEL_CLIENT_COMPATIBLE))
17971817 {
17981818 if (crypt_method & CRYPT_METHOD_40BIT)
17991819 {
1800 g_writeln(" client and server support medium crypt, using "
1801 "medium crypt");
1820 LOG(LOG_LEVEL_INFO, " client and server support medium crypt, using "
1821 "medium crypt");
18021822 self->crypt_method = CRYPT_METHOD_40BIT;
18031823 self->crypt_level = CRYPT_LEVEL_CLIENT_COMPATIBLE;
18041824 found = 1;
18051825 }
18061826 }
18071827 if ((found == 0) &&
1808 (self->crypt_method & CRYPT_METHOD_40BIT) &&
1809 (self->crypt_level == CRYPT_LEVEL_LOW))
1828 (self->crypt_method & CRYPT_METHOD_40BIT) &&
1829 (self->crypt_level == CRYPT_LEVEL_LOW))
18101830 {
18111831 if (crypt_method & CRYPT_METHOD_40BIT)
18121832 {
1813 g_writeln(" client and server support low crypt, using "
1814 "low crypt");
1833 LOG(LOG_LEVEL_INFO, " client and server support low crypt, using "
1834 "low crypt");
18151835 self->crypt_method = CRYPT_METHOD_40BIT;
18161836 self->crypt_level = CRYPT_LEVEL_LOW;
18171837 found = 1;
18181838 }
18191839 }
18201840 if ((found == 0) &&
1821 (self->crypt_level == CRYPT_LEVEL_NONE))
1841 (self->crypt_level == CRYPT_LEVEL_NONE))
18221842 {
18231843 if (crypt_method == CRYPT_METHOD_NONE)
18241844 {
1825 g_writeln(" client and server support none crypt, using "
1826 "none crypt");
1845 LOG(LOG_LEVEL_INFO, " client and server support none crypt, using "
1846 "none crypt");
18271847 self->crypt_method = CRYPT_METHOD_NONE;
18281848 self->crypt_level = CRYPT_LEVEL_NONE;
18291849 found = 1;
18301850 }
18311851 }
1832 // if (found == 0)
1833 // {
1834 // g_writeln(" can not find client / server agreed encryption method");
1835 // return 1;
1836 // }
1852 // if (found == 0)
1853 // {
1854 // LOG_DEVEL(LOG_LEVEL_TRACE, " can not find client / server agreed encryption method");
1855 // return 1;
1856 // }
18371857 return 0;
18381858 }
18391859
18491869 struct mcs_channel_item *channel_item;
18501870
18511871 client_info = &(self->rdp_layer->client_info);
1852 DEBUG(("processing channels, channels_allowed is %d",
1853 client_info->channels_allowed));
1872 LOG_DEVEL(LOG_LEVEL_TRACE, "processing channels, channels_allowed is %d",
1873 client_info->channels_allowed);
18541874 /* this is an option set in xrdp.ini */
18551875 if (client_info->channels_allowed == 0) /* are channels on? */
18561876 {
1857 log_message(LOG_LEVEL_INFO, "all channels are disabled by "
1858 "configuration");
1877 LOG(LOG_LEVEL_INFO, "all channels are disabled by "
1878 "configuration");
18591879 return 0;
18601880 }
18611881 if (!s_check_rem(s, 4))
18801900 if (g_strlen(channel_item->name) > 0)
18811901 {
18821902 channel_item->chanid = MCS_GLOBAL_CHANNEL + (index + 1);
1883 log_message(LOG_LEVEL_INFO, "adding channel item name %s chan_id "
1884 "%d flags 0x%8.8x", channel_item->name,
1885 channel_item->chanid, channel_item->flags);
1903 LOG(LOG_LEVEL_INFO, "adding channel item name %s chan_id "
1904 "%d flags 0x%8.8x", channel_item->name,
1905 channel_item->chanid, channel_item->flags);
18861906 list_add_item(self->mcs_layer->channel_list,
18871907 (intptr_t) channel_item);
1888 DEBUG(("got channel flags %8.8x name %s", channel_item->flags,
1889 channel_item->name));
1908 LOG_DEVEL(LOG_LEVEL_TRACE, "got channel flags %8.8x name %s", channel_item->flags,
1909 channel_item->name);
18901910 }
18911911 else
18921912 {
19131933
19141934 client_info = &(self->rdp_layer->client_info);
19151935
1916 LLOGLN(10, ("xrdp_sec_process_mcs_data_monitors: processing monitors data, allow_multimon is %d", client_info->multimon));
1936 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_process_mcs_data_monitors: processing monitors data, allow_multimon is %d", client_info->multimon);
19171937 /* this is an option set in xrdp.ini */
19181938 if (client_info->multimon != 1) /* are multi-monitors allowed ? */
19191939 {
1920 LLOGLN(0, ("[INFO] xrdp_sec_process_mcs_data_monitors: multimon is not "
1921 "allowed, skipping"));
1940 LOG_DEVEL(LOG_LEVEL_INFO, "[INFO] xrdp_sec_process_mcs_data_monitors: multimon is not "
1941 "allowed, skipping");
19221942 return 0;
19231943 }
19241944 in_uint32_le(s, flags); /* flags */
19251945 //verify flags - must be 0x0
19261946 if (flags != 0)
19271947 {
1928 LLOGLN(0, ("[ERROR] xrdp_sec_process_mcs_data_monitors: flags MUST be "
1929 "zero, detected: %d", flags));
1948 LOG(LOG_LEVEL_ERROR, "[ERROR] xrdp_sec_process_mcs_data_monitors: flags MUST be "
1949 "zero, detected: %d", flags);
19301950 return 1;
19311951 }
19321952 in_uint32_le(s, monitorCount);
19331953 //verify monitorCount - max 16
19341954 if (monitorCount > 16)
19351955 {
1936 LLOGLN(0, ("[ERROR] xrdp_sec_process_mcs_data_monitors: max allowed "
1937 "monitors is 16, detected: %d", monitorCount));
1938 return 1;
1939 }
1940
1941 LLOGLN(10, ("xrdp_sec_process_mcs_data_monitors: monitorCount= %d", monitorCount));
1956 LOG(LOG_LEVEL_ERROR, "[ERROR] xrdp_sec_process_mcs_data_monitors: max allowed "
1957 "monitors is 16, detected: %d", monitorCount);
1958 return 1;
1959 }
1960
1961 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_process_mcs_data_monitors: monitorCount= %d", monitorCount);
19421962
19431963 client_info->monitorCount = monitorCount;
19441964
19751995 got_primary = 1;
19761996 }
19771997
1978 LLOGLN(10, ("xrdp_sec_process_mcs_data_monitors: got a monitor [%d]: left= %d, top= %d, right= %d, bottom= %d, is_primary?= %d",
1979 index,
1980 client_info->minfo[index].left,
1981 client_info->minfo[index].top,
1982 client_info->minfo[index].right,
1983 client_info->minfo[index].bottom,
1984 client_info->minfo[index].is_primary));
1998 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",
1999 index,
2000 client_info->minfo[index].left,
2001 client_info->minfo[index].top,
2002 client_info->minfo[index].right,
2003 client_info->minfo[index].bottom,
2004 client_info->minfo[index].is_primary);
19852005 }
19862006
19872007 if (!got_primary)
20062026 }
20072027 /* make sure virtual desktop size is ok */
20082028 if (client_info->width > 0x7FFE || client_info->width < 0xC8 ||
2009 client_info->height > 0x7FFE || client_info->height < 0xC8)
2010 {
2011 LLOGLN(0, ("[ERROR] xrdp_sec_process_mcs_data_monitors: error, virtual desktop width / height is too large"));
2029 client_info->height > 0x7FFE || client_info->height < 0xC8)
2030 {
2031 LOG(LOG_LEVEL_ERROR, "[ERROR] xrdp_sec_process_mcs_data_monitors: error, virtual desktop width / height is too large");
20122032 return 1; /* error */
20132033 }
20142034
20542074
20552075 if ((size < 4) || (!s_check_rem(s, size - 4)))
20562076 {
2057 LLOGLN(0, ("error in xrdp_sec_process_mcs_data tag %d size %d",
2058 tag, size));
2077 LOG(LOG_LEVEL_ERROR, "error in xrdp_sec_process_mcs_data tag %d size %d",
2078 tag, size);
20592079 break;
20602080 }
20612081
2062 LLOGLN(10, ("xrdp_sec_process_mcs_data: 0x%8.8x", tag));
2082 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_process_mcs_data: 0x%8.8x", tag);
20632083 switch (tag)
20642084 {
20652085 case SEC_TAG_CLI_INFO: /* CS_CORE 0xC001 */
20882108 return 1;
20892109 }
20902110 break;
2091 /* CS_MCS_MSGCHANNEL 0xC006
2092 CS_MONITOR_EX 0xC008
2093 CS_MULTITRANSPORT 0xC00A
2094 SC_CORE 0x0C01
2095 SC_SECURITY 0x0C02
2096 SC_NET 0x0C03
2097 SC_MCS_MSGCHANNEL 0x0C04
2098 SC_MULTITRANSPORT 0x0C08 */
2111 /* CS_MCS_MSGCHANNEL 0xC006
2112 CS_MONITOR_EX 0xC008
2113 CS_MULTITRANSPORT 0xC00A
2114 SC_CORE 0x0C01
2115 SC_SECURITY 0x0C02
2116 SC_NET 0x0C03
2117 SC_MCS_MSGCHANNEL 0x0C04
2118 SC_MULTITRANSPORT 0x0C08 */
20992119 default:
2100 LLOGLN(0, ("error unknown xrdp_sec_process_mcs_data "
2101 "tag 0x%4.4x size %d", tag, size));
2120 LOG(LOG_LEVEL_ERROR, "error unknown xrdp_sec_process_mcs_data "
2121 "tag 0x%4.4x size %d", tag, size);
21022122 break;
21032123 }
21042124
21082128 if (self->rdp_layer->client_info.max_bpp > 0)
21092129 {
21102130 if (self->rdp_layer->client_info.bpp >
2111 self->rdp_layer->client_info.max_bpp)
2112 {
2113 LLOGLN(0, ("xrdp_rdp_parse_client_mcs_data: client asked "
2114 "for %dbpp connection but configuration is limited "
2115 "to %dbpp", self->rdp_layer->client_info.bpp,
2116 self->rdp_layer->client_info.max_bpp));
2131 self->rdp_layer->client_info.max_bpp)
2132 {
2133 LOG(LOG_LEVEL_INFO, "xrdp_rdp_parse_client_mcs_data: client asked "
2134 "for %dbpp connection but configuration is limited "
2135 "to %dbpp", self->rdp_layer->client_info.bpp,
2136 self->rdp_layer->client_info.max_bpp);
21172137 self->rdp_layer->client_info.bpp =
2118 self->rdp_layer->client_info.max_bpp;
2138 self->rdp_layer->client_info.max_bpp;
21192139 }
21202140 }
21212141
22162236 self->crypt_level = CRYPT_LEVEL_FIPS;
22172237 break;
22182238 default:
2219 g_writeln("Fatal : Illegal crypt_level");
2239 LOG_DEVEL(LOG_LEVEL_TRACE, "Fatal : Illegal crypt_level");
22202240 break ;
22212241 }
22222242
22232243 if (self->decrypt_rc4_info != NULL)
22242244 {
2225 g_writeln("xrdp_sec_init_rdp_security: decrypt_rc4_info already created !!!");
2245 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_init_rdp_security: decrypt_rc4_info already created !!!");
22262246 }
22272247 else
22282248 {
22312251
22322252 if (self->encrypt_rc4_info != NULL)
22332253 {
2234 g_writeln("xrdp_sec_init_rdp_security: encrypt_rc4_info already created !!!");
2254 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_init_rdp_security: encrypt_rc4_info already created !!!");
22352255 }
22362256 else
22372257 {
22532273 char *value = NULL;
22542274 char key_file[256];
22552275
2256 DEBUG((" in xrdp_sec_incoming:"));
2276 LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_incoming:");
22572277 iso = self->mcs_layer->iso_layer;
22582278
22592279 /* negotiate security layer */
22602280 if (xrdp_iso_incoming(iso) != 0)
22612281 {
2262 DEBUG(("xrdp_sec_incoming: xrdp_iso_incoming failed"));
2282 LOG(LOG_LEVEL_ERROR, "xrdp_sec_incoming: xrdp_iso_incoming failed");
22632283 return 1;
22642284 }
22652285
22672287 if (iso->selectedProtocol > PROTOCOL_RDP)
22682288 {
22692289 /* init tls security */
2270 DEBUG((" in xrdp_sec_incoming: init tls security"));
2290 LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_incoming: init tls security");
22712291
22722292 if (trans_set_tls_mode(self->mcs_layer->iso_layer->trans,
2273 self->rdp_layer->client_info.key_file,
2274 self->rdp_layer->client_info.certificate,
2275 self->rdp_layer->client_info.ssl_protocols,
2276 self->rdp_layer->client_info.tls_ciphers) != 0)
2277 {
2278 g_writeln("xrdp_sec_incoming: trans_set_tls_mode failed");
2293 self->rdp_layer->client_info.key_file,
2294 self->rdp_layer->client_info.certificate,
2295 self->rdp_layer->client_info.ssl_protocols,
2296 self->rdp_layer->client_info.tls_ciphers) != 0)
2297 {
2298 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_incoming: trans_set_tls_mode failed");
22792299 return 1;
22802300 }
22812301
22872307 else
22882308 {
22892309 /* init rdp security */
2290 DEBUG((" in xrdp_sec_incoming: init rdp security"));
2310 LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_incoming: init rdp security");
22912311 if (xrdp_sec_init_rdp_security(self) != 0)
22922312 {
2293 DEBUG(("xrdp_sec_incoming: xrdp_sec_init_rdp_security failed"));
2313 LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_incoming: xrdp_sec_init_rdp_security failed");
22942314 return 1;
22952315 }
22962316 if (self->crypt_method != CRYPT_METHOD_NONE)
23062326 if (file_by_name_read_section(key_file, "keys", items, values) != 0)
23072327 {
23082328 /* this is a show stopper */
2309 log_message(LOG_LEVEL_ALWAYS, "XRDP cannot read file: %s "
2310 "(check permissions)", key_file);
2329 LOG(LOG_LEVEL_ALWAYS, "XRDP cannot read file: %s "
2330 "(check permissions)", key_file);
23112331 list_delete(items);
23122332 list_delete(values);
23132333 return 1;
23252345 else if (g_strcasecmp(item, "pub_mod") == 0)
23262346 {
23272347 self->rsa_key_bytes = (g_strlen(value) + 1) / 5;
2328 g_writeln("pub_mod bytes %d", self->rsa_key_bytes);
2348 LOG_DEVEL(LOG_LEVEL_TRACE, "pub_mod bytes %d", self->rsa_key_bytes);
23292349 hex_str_to_bin(value, self->pub_mod, self->rsa_key_bytes);
23302350 }
23312351 else if (g_strcasecmp(item, "pub_sig") == 0)
23352355 else if (g_strcasecmp(item, "pri_exp") == 0)
23362356 {
23372357 self->rsa_key_bytes = (g_strlen(value) + 1) / 5;
2338 g_writeln("pri_exp %d", self->rsa_key_bytes);
2358 LOG_DEVEL(LOG_LEVEL_TRACE, "pri_exp %d", self->rsa_key_bytes);
23392359 hex_str_to_bin(value, self->pri_exp, self->rsa_key_bytes);
23402360 }
23412361 }
23422362
23432363 if (self->rsa_key_bytes <= 64)
23442364 {
2345 g_writeln("warning, RSA key len 512 "
2365 LOG_DEVEL(LOG_LEVEL_TRACE, "warning, RSA key len 512 "
23462366 "bits or less, consider creating a 2048 bit key");
2347 log_message(LOG_LEVEL_WARNING, "warning, RSA key len 512 "
2348 "bits or less, consider creating a 2048 bit key");
2367 LOG(LOG_LEVEL_WARNING, "warning, RSA key len 512 "
2368 "bits or less, consider creating a 2048 bit key");
23492369 }
23502370
23512371 list_delete(items);
23592379 return 1;
23602380 }
23612381
2362 #ifdef XRDP_DEBUG
2363 g_writeln("client mcs data received");
2364 g_hexdump(self->client_mcs_data.data,
2365 (int)(self->client_mcs_data.end - self->client_mcs_data.data));
2366 g_writeln("server mcs data sent");
2367 g_hexdump(self->server_mcs_data.data,
2368 (int)(self->server_mcs_data.end - self->server_mcs_data.data));
2369 #endif
2370 DEBUG((" out xrdp_sec_incoming"));
2382 LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "client mcs data received", self->client_mcs_data.data,
2383 (int)(self->client_mcs_data.end - self->client_mcs_data.data));
2384 LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "server mcs data sent", self->server_mcs_data.data,
2385 (int)(self->server_mcs_data.end - self->server_mcs_data.data));
2386 LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_incoming");
23712387 if (xrdp_sec_in_mcs_data(self) != 0)
23722388 {
23732389 return 1;
23742390 }
23752391
2376 LLOGLN(10, ("xrdp_sec_incoming: out"));
2392 LOG_DEVEL(LOG_LEVEL_DEBUG, "xrdp_sec_incoming: out");
23772393 return 0;
23782394 }
23792395
23832399 {
23842400 int rv;
23852401
2386 DEBUG((" in xrdp_sec_disconnect"));
2402 LOG_DEVEL(LOG_LEVEL_TRACE, " in xrdp_sec_disconnect");
23872403 rv = xrdp_mcs_disconnect(self->mcs_layer);
2388 DEBUG((" out xrdp_sec_disconnect"));
2404 LOG_DEVEL(LOG_LEVEL_TRACE, " out xrdp_sec_disconnect");
23892405 return rv;
23902406 }
110110 }
111111 else
112112 {
113 g_writeln("bpp = %d is not supported\n", bpp);
113 LOG(LOG_LEVEL_ERROR, "bpp = %d is not supported\n", bpp);
114114 return 1;
115115 }
116116
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
2424 #include "defines.h"
2525
2626 #define CURRENT_MOD_VER 3
27
28 struct source_info;
2729
2830 struct mod
2931 {
5355 char* data, int width, int height, int srcx, int srcy);
5456 int (*server_set_cursor)(struct mod* v, int x, int y, char* data, char* mask);
5557 int (*server_palette)(struct mod* v, int* palette);
56 int (*server_msg)(struct mod* v, char* msg, int code);
58 int (*server_msg)(struct mod* v, const char* msg, int code);
5759 int (*server_is_term)(struct mod* v);
5860 int (*server_set_clip)(struct mod* v, int x, int y, int cx, int cy);
5961 int (*server_reset_clip)(struct mod* v);
9092 tintptr handle; /* pointer to self as long */
9193 tintptr wm;
9294 tintptr painter;
93 tintptr si;
95 struct source_info *si;
9496 /* mod data */
9597 int sck;
9698 int width;
22
33 scriptversion=2018-03-07.03; # UTC
44
5 # Copyright (C) 1996-2018 Free Software Foundation, Inc.
5 # Copyright (C) 1996-2020 Free Software Foundation, Inc.
66 # Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
77
88 # This program is free software; you can redistribute it and/or modify
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
2323 #include "xrdp-neutrinordp.h"
2424 #include "xrdp-color.h"
2525 #include "xrdp_rail.h"
26 #include "trans.h"
2627 #include "log.h"
28 #include "string_calls.h"
2729 #include <freerdp/settings.h>
2830
2931 #if defined(VERSION_STRUCT_RDP_FREERDP)
3840 #define LOG_LEVEL 1
3941 #endif
4042
43 /* Max amount of buffered output data before we stop generating more */
44 #define MAX_QUEUED_MODULE_OUTPUT_DATA 50000
45
4146 #define LLOG(_level, _args) \
4247 do { if (_level < LOG_LEVEL) { g_write _args ; } } while (0)
4348 #define LLOGLN(_level, _args) \
6570 }
6671
6772 LLOGLN(0, ("The colormap is all NULL"));
73 }
74
75 /*****************************************************************************/
76 static int
77 get_queued_module_output_data(struct mod *mod)
78 {
79 return (mod->si != NULL) ? mod->si->source[XRDP_SOURCE_MOD] : 0;
6880 }
6981
7082 /*****************************************************************************/
515527 boolean ok;
516528
517529 LLOGLN(12, ("lxrdp_get_wait_objs:"));
518 rfds = (void **)read_objs;
519 wfds = (void **)write_objs;
520 ok = freerdp_get_fds(mod->inst, rfds, rcount, wfds, wcount);
521
522 if (!ok)
523 {
524 LLOGLN(0, ("lxrdp_get_wait_objs: freerdp_get_fds failed"));
525 return 1;
530 /*
531 * Don't check this module for activity if our queued output data
532 * has already reached the limit
533 */
534 if (get_queued_module_output_data(mod) > MAX_QUEUED_MODULE_OUTPUT_DATA)
535 {
536 *rcount = 0;
537 *wcount = 0;
538 }
539 else
540 {
541 rfds = (void **)read_objs;
542 wfds = (void **)write_objs;
543 ok = freerdp_get_fds(mod->inst, rfds, rcount, wfds, wcount);
544
545 if (!ok)
546 {
547 LLOGLN(0, ("lxrdp_get_wait_objs: freerdp_get_fds failed"));
548 return 1;
549 }
526550 }
527551
528552 return 0;
535559 boolean ok;
536560
537561 LLOGLN(12, ("lxrdp_check_wait_objs:"));
538 ok = freerdp_check_fds(mod->inst);
539
540 if (!ok)
541 {
542 LLOGLN(0, ("lxrdp_check_wait_objs: freerdp_check_fds failed"));
543 return 1;
562 /*
563 * Only process the freerdp file descriptors if our queued output data
564 * has not reached the limit
565 */
566 if (get_queued_module_output_data(mod) <= MAX_QUEUED_MODULE_OUTPUT_DATA)
567 {
568 /*
569 * Before checking the file descriptors, set the source info
570 * current source, so any data queued on output trans objects
571 * gets attributed to this module
572 */
573 if (mod->si)
574 {
575 mod->si->cur_source = XRDP_SOURCE_MOD;
576 }
577 ok = freerdp_check_fds(mod->inst);
578 if (mod->si)
579 {
580 mod->si->cur_source = XRDP_SOURCE_NONE;
581 }
582
583 if (!ok)
584 {
585 LLOGLN(0, ("lxrdp_check_wait_objs: freerdp_check_fds failed"));
586 return 1;
587 }
544588 }
545589
546590 return 0;
13931437 lfreerdp_polygon_sc(rdpContext *context, POLYGON_SC_ORDER *polygon_sc)
13941438 {
13951439 struct mod *mod;
1396 int i, npoints;
1440 int i;
13971441 struct {
13981442 short x, y;
13991443 } points[4];
14471491 static void
14481492 lfreerdp_synchronize(rdpContext *context)
14491493 {
1450 struct mod *mod;
1451 mod = ((struct mod_context *)context)->modi;
1494 /* Uncomment these two lines when needed */
1495 #if 0
1496 struct mod *mod;
1497 mod = ((struct mod_context *)context)->modi;
1498 #endif
14521499 LLOGLN(12, ("lfreerdp_synchronize received - not handled"));
14531500 }
14541501
2323 #include "defines.h"
2424 #include "xrdp_rail.h"
2525 #include "xrdp_client_info.h"
26 #include "xrdp_constants.h"
2627
2728 /* this is the freerdp main header */
2829 #include <freerdp/freerdp.h>
5859 };
5960
6061 #define CURRENT_MOD_VER 4
62
63 struct source_info;
6164
6265 struct mod
6366 {
181184 tintptr handle; /* pointer to self as long */
182185 tintptr wm;
183186 tintptr painter;
184 tintptr si;
187 struct source_info *si;
185188
186189 /* mod data */
187190 int sck;
195198 int vmaj;
196199 int vmin;
197200 int vrev;
198 char username[256];
199 char password[256];
200 char domain[256];
201 char username[INFO_CLIENT_MAX_CB_LEN];
202 char password[INFO_CLIENT_MAX_CB_LEN];
203 char domain[INFO_CLIENT_MAX_CB_LEN];
201204 int bool_keyBoardSynced ; /* Numlock can be out of sync, we hold state here to resolve */
202205 int keyBoardLockInfo ; /* Holds initial numlock capslock state */
203206
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
2828 #endif
2929
3030 #include "sesman.h"
31 #include "string_calls.h"
3132
3233 extern struct config_sesman *g_cfg; /* in sesman.c */
3334
4041
4142 if ((0 == g_strncmp(user, "root", 5)) && (0 == g_cfg->sec.allow_root))
4243 {
43 log_message(LOG_LEVEL_WARNING,
44 "ROOT login attempted, but root login is disabled");
44 LOG(LOG_LEVEL_WARNING,
45 "ROOT login attempted, but root login is disabled");
4546 return 0;
4647 }
4748
48 if ((0 == g_cfg->sec.ts_users_enable) && (0==g_cfg->sec.ts_always_group_check))
49 if ((0 == g_cfg->sec.ts_users_enable) && (0 == g_cfg->sec.ts_always_group_check))
4950 {
50 LOG_DBG("Terminal Server Users group is disabled, allowing authentication",
51 1);
51 LOG(LOG_LEVEL_INFO, "Terminal Server Users group is disabled, allowing authentication");
5252 return 1;
5353 }
5454
5555 if (0 != g_getuser_info(user, &gid, 0, 0, 0, 0))
5656 {
57 log_message(LOG_LEVEL_ERROR, "Cannot read user info! - login denied");
57 LOG(LOG_LEVEL_ERROR, "Cannot read user info! - login denied");
5858 return 0;
5959 }
6060
6161 if (g_cfg->sec.ts_users == gid)
6262 {
63 log_message(LOG_LEVEL_DEBUG,"ts_users is user's primary group");
63 LOG(LOG_LEVEL_DEBUG, "ts_users is user's primary group");
6464 return 1;
6565 }
6666
6767 if (0 != g_check_user_in_group(user, g_cfg->sec.ts_users, &ok))
6868 {
69 log_message(LOG_LEVEL_ERROR, "Cannot read group info! - login denied");
69 LOG(LOG_LEVEL_ERROR, "Cannot read group info! - login denied");
7070 return 0;
7171 }
7272
7575 return 1;
7676 }
7777
78 log_message(LOG_LEVEL_INFO, "login denied for user %s", user);
78 LOG(LOG_LEVEL_INFO, "login denied for user %s", user);
7979
8080 return 0;
8181 }
8989
9090 if ((0 == g_strncmp(user, "root", 5)) && (0 == g_cfg->sec.allow_root))
9191 {
92 log_message(LOG_LEVEL_WARNING,
93 "[MNG] ROOT login attempted, but root login is disabled");
92 LOG(LOG_LEVEL_WARNING,
93 "[MNG] ROOT login attempted, but root login is disabled");
9494 return 0;
9595 }
9696
9797 if (0 == g_cfg->sec.ts_admins_enable)
9898 {
99 LOG_DBG("[MNG] Terminal Server Admin group is disabled, "
100 "allowing authentication", 1);
99 LOG(LOG_LEVEL_INFO, "[MNG] Terminal Server Admin group is disabled, "
100 "allowing authentication");
101101 return 1;
102102 }
103103
104104 if (0 != g_getuser_info(user, &gid, 0, 0, 0, 0))
105105 {
106 log_message(LOG_LEVEL_ERROR, "[MNG] Cannot read user info! - login denied");
106 LOG(LOG_LEVEL_ERROR, "[MNG] Cannot read user info! - login denied");
107107 return 0;
108108 }
109109
110110 if (g_cfg->sec.ts_admins == gid)
111111 {
112 LOG_DBG("[MNG] ts_users is user's primary group");
112 LOG(LOG_LEVEL_INFO, "[MNG] ts_users is user's primary group");
113113 return 1;
114114 }
115115
116116 if (0 != g_check_user_in_group(user, g_cfg->sec.ts_admins, &ok))
117117 {
118 log_message(LOG_LEVEL_ERROR, "[MNG] Cannot read group info! - login denied");
118 LOG(LOG_LEVEL_ERROR, "[MNG] Cannot read group info! - login denied");
119119 return 0;
120120 }
121121
124124 return 1;
125125 }
126126
127 log_message(LOG_LEVEL_INFO, "[MNG] login denied for user %s", user);
127 LOG(LOG_LEVEL_INFO, "[MNG] login denied for user %s", user);
128128
129129 return 0;
130130 }
5050 chansrv.h \
5151 chansrv_common.c \
5252 chansrv_common.h \
53 chansrv_config.c \
54 chansrv_config.h \
5355 chansrv_fuse.c \
5456 chansrv_fuse.h \
5557 chansrv_xfs.c \
6567 fifo.h \
6668 irp.c \
6769 irp.h \
68 mlog.h \
69 ms-erref.h \
70 ms-fscc.h \
71 ms-rdpefs.h \
72 ms-smb2.h \
7370 rail.c \
7471 rail.h \
7572 smartcard.c \
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
121121 am__installdirs = "$(DESTDIR)$(sbindir)"
122122 PROGRAMS = $(sbin_PROGRAMS)
123123 am_xrdp_chansrv_OBJECTS = chansrv.$(OBJEXT) chansrv_common.$(OBJEXT) \
124 chansrv_fuse.$(OBJEXT) chansrv_xfs.$(OBJEXT) \
125 clipboard.$(OBJEXT) clipboard_file.$(OBJEXT) \
126 devredir.$(OBJEXT) fifo.$(OBJEXT) irp.$(OBJEXT) rail.$(OBJEXT) \
127 smartcard.$(OBJEXT) smartcard_pcsc.$(OBJEXT) sound.$(OBJEXT) \
128 xcommon.$(OBJEXT) audin.$(OBJEXT)
124 chansrv_config.$(OBJEXT) chansrv_fuse.$(OBJEXT) \
125 chansrv_xfs.$(OBJEXT) clipboard.$(OBJEXT) \
126 clipboard_file.$(OBJEXT) devredir.$(OBJEXT) fifo.$(OBJEXT) \
127 irp.$(OBJEXT) rail.$(OBJEXT) smartcard.$(OBJEXT) \
128 smartcard_pcsc.$(OBJEXT) sound.$(OBJEXT) xcommon.$(OBJEXT) \
129 audin.$(OBJEXT)
129130 xrdp_chansrv_OBJECTS = $(am_xrdp_chansrv_OBJECTS)
130131 am__DEPENDENCIES_1 =
131132 @XRDP_FUSE_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
158159 depcomp = $(SHELL) $(top_srcdir)/depcomp
159160 am__maybe_remake_depfiles = depfiles
160161 am__depfiles_remade = ./$(DEPDIR)/audin.Po ./$(DEPDIR)/chansrv.Po \
161 ./$(DEPDIR)/chansrv_common.Po ./$(DEPDIR)/chansrv_fuse.Po \
162 ./$(DEPDIR)/chansrv_xfs.Po ./$(DEPDIR)/clipboard.Po \
163 ./$(DEPDIR)/clipboard_file.Po ./$(DEPDIR)/devredir.Po \
164 ./$(DEPDIR)/fifo.Po ./$(DEPDIR)/irp.Po ./$(DEPDIR)/rail.Po \
165 ./$(DEPDIR)/smartcard.Po ./$(DEPDIR)/smartcard_pcsc.Po \
166 ./$(DEPDIR)/sound.Po ./$(DEPDIR)/xcommon.Po
162 ./$(DEPDIR)/chansrv_common.Po ./$(DEPDIR)/chansrv_config.Po \
163 ./$(DEPDIR)/chansrv_fuse.Po ./$(DEPDIR)/chansrv_xfs.Po \
164 ./$(DEPDIR)/clipboard.Po ./$(DEPDIR)/clipboard_file.Po \
165 ./$(DEPDIR)/devredir.Po ./$(DEPDIR)/fifo.Po ./$(DEPDIR)/irp.Po \
166 ./$(DEPDIR)/rail.Po ./$(DEPDIR)/smartcard.Po \
167 ./$(DEPDIR)/smartcard_pcsc.Po ./$(DEPDIR)/sound.Po \
168 ./$(DEPDIR)/xcommon.Po
167169 am__mv = mv -f
168170 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
169171 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
374376 chansrv.h \
375377 chansrv_common.c \
376378 chansrv_common.h \
379 chansrv_config.c \
380 chansrv_config.h \
377381 chansrv_fuse.c \
378382 chansrv_fuse.h \
379383 chansrv_xfs.c \
389393 fifo.h \
390394 irp.c \
391395 irp.h \
392 mlog.h \
393 ms-erref.h \
394 ms-fscc.h \
395 ms-rdpefs.h \
396 ms-smb2.h \
397396 rail.c \
398397 rail.h \
399398 smartcard.c \
511510 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audin.Po@am__quote@ # am--include-marker
512511 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chansrv.Po@am__quote@ # am--include-marker
513512 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chansrv_common.Po@am__quote@ # am--include-marker
513 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chansrv_config.Po@am__quote@ # am--include-marker
514514 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chansrv_fuse.Po@am__quote@ # am--include-marker
515515 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chansrv_xfs.Po@am__quote@ # am--include-marker
516516 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clipboard.Po@am__quote@ # am--include-marker
688688 -rm -f ./$(DEPDIR)/audin.Po
689689 -rm -f ./$(DEPDIR)/chansrv.Po
690690 -rm -f ./$(DEPDIR)/chansrv_common.Po
691 -rm -f ./$(DEPDIR)/chansrv_config.Po
691692 -rm -f ./$(DEPDIR)/chansrv_fuse.Po
692693 -rm -f ./$(DEPDIR)/chansrv_xfs.Po
693694 -rm -f ./$(DEPDIR)/clipboard.Po
748749 -rm -f ./$(DEPDIR)/audin.Po
749750 -rm -f ./$(DEPDIR)/chansrv.Po
750751 -rm -f ./$(DEPDIR)/chansrv_common.Po
752 -rm -f ./$(DEPDIR)/chansrv_config.Po
751753 -rm -f ./$(DEPDIR)/chansrv_fuse.Po
752754 -rm -f ./$(DEPDIR)/chansrv_xfs.Po
753755 -rm -f ./$(DEPDIR)/clipboard.Po
117117 int bytes;
118118 struct stream *s;
119119
120 LOG(0, ("audin_send_version:"));
120 LOG_DEVEL(LOG_LEVEL_INFO, "audin_send_version:");
121121 make_stream(s);
122122 init_stream(s, 32);
123123 out_uint8(s, MSG_SNDIN_VERSION);
140140 struct stream *s;
141141 struct xr_wave_format_ex *wf;
142142
143 LOG(0, ("audin_send_formats:"));
143 LOG_DEVEL(LOG_LEVEL_INFO, "audin_send_formats:");
144144 num_formats = sizeof(g_server_formats) /
145145 sizeof(g_server_formats[0]) - 1;
146146 make_stream(s);
151151 for (index = 0; index < num_formats; index++)
152152 {
153153 wf = g_server_formats[index];
154 LOG(0, ("audin_send_formats: sending format wFormatTag 0x%4.4x "
155 "nChannels %d nSamplesPerSec %d",
156 wf->wFormatTag, wf->nChannels, wf->nSamplesPerSec));
154 LOG_DEVEL(LOG_LEVEL_INFO, "audin_send_formats: sending format wFormatTag 0x%4.4x "
155 "nChannels %d nSamplesPerSec %d",
156 wf->wFormatTag, wf->nChannels, wf->nSamplesPerSec);
157157 out_uint16_le(s, wf->wFormatTag);
158158 out_uint16_le(s, wf->nChannels);
159159 out_uint32_le(s, wf->nSamplesPerSec);
182182 struct stream *s;
183183 struct xr_wave_format_ex *wf;
184184
185 LOG(0, ("audin_send_open:"));
185 LOG_DEVEL(LOG_LEVEL_INFO, "audin_send_open:");
186186 make_stream(s);
187187 init_stream(s, 8192);
188188 out_uint8(s, MSG_SNDIN_OPEN);
214214 {
215215 int version;
216216
217 LOG(0, ("audin_process_version:"));
217 LOG_DEVEL(LOG_LEVEL_INFO, "audin_process_version:");
218218 if (!s_check_rem(s, 4))
219219 {
220 LOG(0, ("audin_process_version: parse error"));
220 LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_version: parse error");
221221 return 1;
222222 }
223223 in_uint32_le(s, version);
224 LOG(0, ("audin_process_version: version %d", version));
224 LOG(LOG_LEVEL_INFO, "audin_process_version: version %d", version);
225225 return audin_send_formats(chan_id);
226226 }
227227
233233 int num_formats;
234234 struct xr_wave_format_ex *wf;
235235
236 LOG(0, ("audin_process_formats:"));
236 LOG_DEVEL(LOG_LEVEL_INFO, "audin_process_formats:");
237237 cleanup_client_formats();
238238 if (!s_check_rem(s, 8))
239239 {
240 LOG(0, ("audin_process_formats: parse error"));
240 LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_formats: parse error");
241241 return 1;
242242 }
243243 in_uint32_le(s, num_formats);
247247 {
248248 if (!s_check_rem(s, 18))
249249 {
250 LOG(0, ("audin_process_formats: parse error"));
250 LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_formats: parse error");
251251 return 1;
252252 }
253253 wf = g_new0(struct xr_wave_format_ex, 1);
259259 in_uint16_le(s, wf->nBlockAlign);
260260 in_uint16_le(s, wf->wBitsPerSample);
261261 in_uint16_le(s, wf->cbSize);
262 LOG(0, ("audin_process_formats: recved format wFormatTag 0x%4.4x "
263 "nChannels %d nSamplesPerSec %d",
264 wf->wFormatTag, wf->nChannels, wf->nSamplesPerSec));
262 LOG_DEVEL(LOG_LEVEL_INFO, "audin_process_formats: recved format wFormatTag 0x%4.4x "
263 "nChannels %d nSamplesPerSec %d",
264 wf->wFormatTag, wf->nChannels, wf->nSamplesPerSec);
265265 if (wf->cbSize > 0)
266266 {
267267 if (!s_check_rem(s, wf->cbSize))
268268 {
269 LOG(0, ("audin_process_formats: parse error"));
269 LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_formats: parse error");
270270 return 1;
271271 }
272272 wf->data = g_new0(uint8_t, wf->cbSize);
285285
286286 if (!s_check_rem(s, 4))
287287 {
288 LOG(0, ("audin_process_open_reply: parse error"));
288 LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_open_reply: parse error");
289289 return 1;
290290 }
291291 in_uint32_le(s, result);
292 LOG(0, ("audin_process_open_reply: result 0x%8.8x", result));
292 LOG(LOG_LEVEL_INFO, "audin_process_open_reply: result 0x%8.8x", result);
293293 return 0;
294294 }
295295
297297 static int
298298 audin_process_incoming_data(int chan_id, struct stream *s)
299299 {
300 LOG(10, ("audin_process_incoming_data:"));
300 LOG_DEVEL(LOG_LEVEL_DEBUG, "audin_process_incoming_data:");
301301 return 0;
302302 }
303303
309309 struct stream *ls;
310310
311311 data_bytes = (int) (s->end - s->p);
312 LOG(10, ("audin_process_data: data_bytes %d", data_bytes));
312 LOG_DEVEL(LOG_LEVEL_DEBUG, "audin_process_data: data_bytes %d", data_bytes);
313313
314314 xstream_new(ls, data_bytes);
315315 g_memcpy(ls->data, s->p, data_bytes);
325325 static int
326326 audin_process_format_change(int chan_id, struct stream *s)
327327 {
328 LOG(0, ("audin_process_format_change:"));
328 LOG_DEVEL(LOG_LEVEL_INFO, "audin_process_format_change:");
329329 if (!s_check_rem(s, 4))
330330 {
331 LOG(0, ("audin_process_format_change: parse error"));
331 LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_format_change: parse error");
332332 return 1;
333333 }
334334 in_uint32_le(s, g_current_format);
335 LOG(0, ("audin_process_format_change: g_current_format %d",
336 g_current_format));
335 LOG_DEVEL(LOG_LEVEL_INFO, "audin_process_format_change: g_current_format %d",
336 g_current_format);
337337 return 0;
338338 }
339339
343343 {
344344 int code;
345345
346 LOG(10, ("audin_process_msg:"));
346 LOG_DEVEL(LOG_LEVEL_DEBUG, "audin_process_msg:");
347347 if (!s_check_rem(s, 1))
348348 {
349 LOG(0, ("audin_process_msg: parse error"));
349 LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_msg: parse error");
350350 return 1;
351351 }
352352 in_uint8(s, code);
353 LOG(10, ("audin_process_msg: code %d", code));
353 LOG_DEVEL(LOG_LEVEL_DEBUG, "audin_process_msg: code %d", code);
354354 switch (code)
355355 {
356356 case MSG_SNDIN_VERSION:
366366 case MSG_SNDIN_FORMATCHANGE:
367367 return audin_process_format_change(chan_id, s);
368368 default:
369 LOG(0, ("audin_process_msg: unprocessed code %d", code));
369 LOG_DEVEL(LOG_LEVEL_ERROR, "audin_process_msg: unprocessed code %d", code);
370370 break;
371371 }
372372 return 0;
376376 static int
377377 audin_open_response(int chan_id, int creation_status)
378378 {
379 LOG(0, ("audin_open_response: creation_status 0x%8.8x", creation_status));
379 LOG_DEVEL(LOG_LEVEL_INFO, "audin_open_response: creation_status 0x%8.8x", creation_status);
380380 if (creation_status == 0)
381381 {
382382 return audin_send_version(chan_id);
388388 static int
389389 audin_close_response(int chan_id)
390390 {
391 LOG(0, ("audin_close_response:"));
391 LOG_DEVEL(LOG_LEVEL_INFO, "audin_close_response:");
392392 g_audin_chanid = 0;
393393 cleanup_client_formats();
394394 free_stream(g_in_s);
401401 audin_data_fragment(int chan_id, char *data, int bytes)
402402 {
403403 int rv;
404 int left;
405
406 LOG(10, ("audin_data_fragment:"));
404
405 LOG_DEVEL(LOG_LEVEL_DEBUG, "audin_data_fragment:");
407406 if (!s_check_rem(g_in_s, bytes))
408407 {
409 left = (int) (g_in_s->end - g_in_s->p);
410 LOG(0, ("audin_data_fragment: error bytes %d left %d", bytes, left));
408 LOG_DEVEL(LOG_LEVEL_ERROR, "audin_data_fragment: error bytes %d left %d",
409 bytes, (int) (g_in_s->end - g_in_s->p));
411410 return 1;
412411 }
413412 out_uint8a(g_in_s, data, bytes);
426425 static int
427426 audin_data_first(int chan_id, char *data, int bytes, int total_bytes)
428427 {
429 LOG(10, ("audin_data_first:"));
428 LOG_DEVEL(LOG_LEVEL_DEBUG, "audin_data_first:");
430429 if (g_in_s != NULL)
431430 {
432 LOG(0, ("audin_data_first: warning g_in_s is not nil"));
431 LOG_DEVEL(LOG_LEVEL_ERROR, "audin_data_first: warning g_in_s is not nil");
433432 free_stream(g_in_s);
434433 }
435434 make_stream(g_in_s);
444443 {
445444 struct stream ls;
446445
447 LOG(10, ("audin_data:"));
448 //g_hexdump(data, bytes);
446 LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "audin_data:", data, bytes);
449447 if (g_in_s == NULL)
450448 {
451449 g_memset(&ls, 0, sizeof(ls));
461459 int
462460 audin_init(void)
463461 {
464 LOG(0, ("audin_init:"));
462 LOG_DEVEL(LOG_LEVEL_INFO, "audin_init:");
465463 g_memset(&g_audin_info, 0, sizeof(g_audin_info));
466464 g_audin_info.open_response = audin_open_response;
467465 g_audin_info.close_response = audin_close_response;
476474 int
477475 audin_deinit(void)
478476 {
479 LOG(0, ("audin_deinit:"));
477 LOG_DEVEL(LOG_LEVEL_INFO, "audin_deinit:");
480478 return 0;
481479 }
482480
485483 audin_start(void)
486484 {
487485 int error;
488 struct stream* s;
489
490 LOG(0, ("audin_start:"));
486 struct stream *s;
487
488 LOG_DEVEL(LOG_LEVEL_INFO, "audin_start:");
491489 if (g_audin_chanid != 0)
492490 {
493491 return 1;
503501 error = chansrv_drdynvc_open(AUDIN_NAME, AUDIN_FLAGS,
504502 &g_audin_info, /* callback functions */
505503 &g_audin_chanid); /* chansrv chan_id */
506 LOG(0, ("audin_start: error %d g_audin_chanid %d", error, g_audin_chanid));
504 LOG_DEVEL(LOG_LEVEL_ERROR, "audin_start: error %d g_audin_chanid %d", error, g_audin_chanid);
507505 return error;
508506 }
509507
511509 int
512510 audin_stop(void)
513511 {
514 LOG(0, ("audin_stop:"));
512 LOG_DEVEL(LOG_LEVEL_INFO, "audin_stop:");
515513 chansrv_drdynvc_close(g_audin_chanid);
516514 return 0;
517515 }
2222
2323 #include "arch.h"
2424 #include "os_calls.h"
25 #include "string_calls.h"
2526 #include "thread_calls.h"
2627 #include "trans.h"
2728 #include "chansrv.h"
3536 #include "rail.h"
3637 #include "xcommon.h"
3738 #include "chansrv_fuse.h"
39 #include "chansrv_config.h"
3840 #include "xrdp_sockets.h"
3941 #include "audin.h"
42
43 #include "ms-rdpbcgr.h"
44
45 #define MAX_PATH 260
4046
4147 static struct trans *g_lis_trans = 0;
4248 static struct trans *g_con_trans = 0;
5258 static tbus g_term_event = 0;
5359 static tbus g_thread_done_event = 0;
5460
55 static int g_use_unix_socket = 0;
61 struct config_chansrv *g_cfg = NULL;
5662
5763 int g_display_num = 0;
5864 int g_cliprdr_chan_id = -1; /* cliprdr */
5965 int g_rdpsnd_chan_id = -1; /* rdpsnd */
6066 int g_rdpdr_chan_id = -1; /* rdpdr */
6167 int g_rail_chan_id = -1; /* rail */
62 int g_restrict_outbound_clipboard = 0;
6368
6469 char *g_exec_name;
65 tbus g_exec_event;
70 tbus g_exec_event = 0;
6671 tbus g_exec_mutex;
6772 tbus g_exec_sem;
6873 int g_exec_pid = 0;
117122 struct timeout_obj *tobj;
118123 tui32 now;
119124
120 LOG(10, ("add_timeout:"));
125 LOG_DEVEL(LOG_LEVEL_DEBUG, "add_timeout:");
121126 now = g_time3();
122127 tobj = g_new0(struct timeout_obj, 1);
123128 tobj->mstime = now + msoffset;
144149 tui32 now;
145150 int ltimeout;
146151
147 LOG(10, ("get_timeout:"));
152 LOG_DEVEL(LOG_LEVEL_DEBUG, "get_timeout:");
148153 ltimeout = *timeout;
149154 if (ltimeout < 1)
150155 {
156161 now = g_time3();
157162 while (tobj != 0)
158163 {
159 LOG(10, (" now %u tobj->mstime %u", now, tobj->mstime));
164 LOG_DEVEL(LOG_LEVEL_DEBUG, " now %u tobj->mstime %u", now, tobj->mstime);
160165 if (now < tobj->mstime)
161166 {
162167 ltimeout = tobj->mstime - now;
166171 }
167172 if (ltimeout > 0)
168173 {
169 LOG(10, (" ltimeout %d", ltimeout));
174 LOG_DEVEL(LOG_LEVEL_DEBUG, " ltimeout %d", ltimeout);
170175 if (*timeout < 1)
171176 {
172177 *timeout = ltimeout;
192197 int count;
193198 tui32 now;
194199
195 LOG(10, ("check_timeout:"));
200 LOG_DEVEL(LOG_LEVEL_DEBUG, "check_timeout:");
196201 count = 0;
197202 tobj = g_timeout_head;
198203 if (tobj != 0)
232237 }
233238 }
234239 }
235 LOG(10, (" count %d", count));
240 LOG_DEVEL(LOG_LEVEL_DEBUG, " count %d", count);
236241 return 0;
237242 }
238243
258263 struct stream *s;
259264
260265 if ((chan_id < 0) || (chan_id > 31) ||
261 (data == NULL) ||
262 (size < 1) || (size > MAX_CHANNEL_BYTES))
266 (data == NULL) ||
267 (size < 1) || (size > MAX_CHANNEL_BYTES))
263268 {
264269 /* bad param */
265270 return 1;
303308 /*****************************************************************************/
304309 /* returns error */
305310 int
306 send_rail_drawing_orders(char* data, int size)
307 {
308 LOGM((LOG_LEVEL_DEBUG, "chansrv::send_rail_drawing_orders: size %d", size));
309
310 struct stream* s;
311 send_rail_drawing_orders(char *data, int size)
312 {
313 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::send_rail_drawing_orders: size %d", size);
314
315 struct stream *s;
311316 int error;
312317
313318 s = trans_get_out_s(g_con_trans, 8192);
344349 g_rdpsnd_chan_id = -1;
345350 g_rdpdr_chan_id = -1;
346351 g_rail_chan_id = -1;
347 LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup:"));
352 LOG_DEVEL(LOG_LEVEL_DEBUG, "process_message_channel_setup:");
348353 in_uint16_le(s, num_chans);
349 LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup: num_chans %d",
350 num_chans));
354 LOG_DEVEL(LOG_LEVEL_DEBUG, "process_message_channel_setup: num_chans %d",
355 num_chans);
351356
352357 for (index = 0; index < num_chans; index++)
353358 {
356361 in_uint8a(s, ci->name, 8);
357362 in_uint16_le(s, ci->id);
358363 in_uint16_le(s, ci->flags);
359 LOGM((LOG_LEVEL_DEBUG, "process_message_channel_setup: chan name '%s' "
360 "id %d flags %8.8x", ci->name, ci->id, ci->flags));
361
362 g_writeln("process_message_channel_setup: chan name '%s' "
364 LOG_DEVEL(LOG_LEVEL_DEBUG, "process_message_channel_setup: chan name '%s' "
363365 "id %d flags %8.8x", ci->name, ci->id, ci->flags);
364366
365367 if (g_strcasecmp(ci->name, "cliprdr") == 0)
385387 }
386388 else
387389 {
388 LOG(10, ("other %s", ci->name));
390 LOG_DEVEL(LOG_LEVEL_DEBUG, "other %s", ci->name);
389391 }
390392
391393 g_num_chan_items++;
440442 in_uint16_le(s, chan_flags);
441443 in_uint16_le(s, length);
442444 in_uint32_le(s, total_length);
443 LOGM((LOG_LEVEL_DEBUG, "process_message_channel_data: chan_id %d "
444 "chan_flags %d", chan_id, chan_flags));
445 LOG(10, ("process_message_channel_data"));
445 LOG_DEVEL(LOG_LEVEL_DEBUG, "process_message_channel_data: chan_id %d "
446 "chan_flags %d", chan_id, chan_flags);
446447 rv = 0;
447448
448449 if (rv == 0)
495496 }
496497 if (found == 0)
497498 {
498 LOG(0, ("process_message_channel_data: not found channel %d", chan_id));
499 LOG_DEVEL(LOG_LEVEL_INFO, "process_message_channel_data: not found channel %d", chan_id);
499500 }
500501 }
501502
513514 int chan_id;
514515 int creation_status;
515516
516 LOG(10, ("process_message_drdynvc_open_response:"));
517 LOG_DEVEL(LOG_LEVEL_DEBUG, "process_message_drdynvc_open_response:");
517518 if (!s_check_rem(s, 8))
518519 {
519520 return 1;
527528 drdynvc = g_drdynvcs + chan_id;
528529 if (drdynvc->status != CHANSRV_DRDYNVC_STATUS_OPEN_SENT)
529530 {
530 g_writeln("process_message_drdynvc_open_response: status not right");
531 LOG_DEVEL(LOG_LEVEL_ERROR, "process_message_drdynvc_open_response: status not right");
531532 return 1;
532533 }
533534 if (creation_status == 0)
557558 struct chansrv_drdynvc *drdynvc;
558559 int chan_id;
559560
560 LOG(10, ("process_message_drdynvc_close_response:"));
561 LOG_DEVEL(LOG_LEVEL_DEBUG, "process_message_drdynvc_close_response:");
561562 if (!s_check_rem(s, 4))
562563 {
563564 return 1;
570571 drdynvc = g_drdynvcs + chan_id;
571572 if (drdynvc->status != CHANSRV_DRDYNVC_STATUS_CLOSE_SENT)
572573 {
573 g_writeln("process_message_drdynvc_close_response: status not right");
574 LOG_DEVEL(LOG_LEVEL_ERROR, "process_message_drdynvc_close_response: status not right");
574575 return 0;
575576 }
576577 drdynvc->status = CHANSRV_DRDYNVC_STATUS_CLOSED;
596597 int total_bytes;
597598 char *data;
598599
599 LOG(10, ("process_message_drdynvc_data_first:"));
600 LOG_DEVEL(LOG_LEVEL_DEBUG, "process_message_drdynvc_data_first:");
600601 if (!s_check_rem(s, 12))
601602 {
602603 return 1;
635636 int bytes;
636637 char *data;
637638
638 LOG(10, ("process_message_drdynvc_data:"));
639 LOG_DEVEL(LOG_LEVEL_DEBUG, "process_message_drdynvc_data:");
639640 if (!s_check_rem(s, 8))
640641 {
641642 return 1;
742743 struct stream *s;
743744 int error;
744745
745 //g_writeln("chansrv_drdynvc_data_first: data_bytes %d total_data_bytes %d",
746 //LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv_drdynvc_data_first: data_bytes %d total_data_bytes %d",
746747 // data_bytes, total_data_bytes);
747748 s = trans_get_out_s(g_con_trans, 8192);
748749 if (s == NULL)
769770 struct stream *s;
770771 int error;
771772
772 //g_writeln("chansrv_drdynvc_data: data_bytes %d", data_bytes);
773 // LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv_drdynvc_data: data_bytes %d", data_bytes);
773774 s = trans_get_out_s(g_con_trans, 8192);
774775 if (s == NULL)
775776 {
793794 {
794795 int this_send_bytes;
795796
796 //g_writeln("chansrv_drdynvc_send_data: data_bytes %d", data_bytes);
797 // LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv_drdynvc_send_data: data_bytes %d", data_bytes);
797798 if (data_bytes > 1590)
798799 {
799800 if (chansrv_drdynvc_data_first(chan_id, data, 1590, data_bytes) != 0)
869870 rv = process_message_drdynvc_data(s);
870871 break;
871872 default:
872 LOGM((LOG_LEVEL_ERROR, "process_message: unknown msg %d", id));
873 LOG_DEVEL(LOG_LEVEL_ERROR, "process_message: unknown msg %d", id);
873874 break;
874875 }
875876
904905 return 1;
905906 }
906907
907 LOGM((LOG_LEVEL_DEBUG, "my_trans_data_in:"));
908 LOG_DEVEL(LOG_LEVEL_DEBUG, "my_trans_data_in:");
908909 s = trans_get_in_s(trans);
909910 in_uint8s(s, 4); /* id */
910911 in_uint32_le(s, size);
10411042 int rv;
10421043 int bytes;
10431044 int ver;
1044 int channel_name_bytes;
10451045 struct chansrv_drdynvc_procs procs;
1046 char *chan_name;
1047
1048 //g_writeln("my_api_trans_data_in: extra_flags %d", trans->extra_flags);
1046 /*
1047 * Name is limited to CHANNEL_NAME_LEN for an SVC, or MAX_PATH
1048 * bytes for a DVC
1049 */
1050 char chan_name[MAX(CHANNEL_NAME_LEN, MAX_PATH) + 1];
1051 unsigned int channel_name_bytes;
1052
1053 //LOG_DEVEL(LOG_LEVEL_DEBUG, "my_api_trans_data_in: extra_flags %d", trans->extra_flags);
10491054 rv = 0;
10501055 ad = (struct xrdp_api_data *) (trans->callback_data);
10511056 s = trans_get_in_s(trans);
10531058 {
10541059 in_uint32_le(s, bytes);
10551060 in_uint32_le(s, ver);
1056 //g_writeln("my_api_trans_data_in: bytes %d ver %d", bytes, ver);
1061 //LOG_DEVEL(LOG_LEVEL_DEBUG, "my_api_trans_data_in: bytes %d ver %d", bytes, ver);
10571062 if (ver != 0)
10581063 {
10591064 return 1;
10651070 {
10661071 rv = 1;
10671072 in_uint32_le(s, channel_name_bytes);
1068 //g_writeln("my_api_trans_data_in: channel_name_bytes %d", channel_name_bytes);
1069 chan_name = g_new0(char, channel_name_bytes + 1);
1070 if (chan_name == NULL)
1073 //LOG_DEVEL(LOG_LEVEL_DEBUG, "my_api_trans_data_in: channel_name_bytes %d", channel_name_bytes);
1074 if (channel_name_bytes > (sizeof(chan_name) - 1))
10711075 {
10721076 return 1;
10731077 }
10741078 in_uint8a(s, chan_name, channel_name_bytes);
1079 chan_name[channel_name_bytes] = '\0';
1080
10751081 in_uint32_le(s, ad->chan_flags);
1076 //g_writeln("my_api_trans_data_in: chan_name %s chan_flags 0x%8.8x", chan_name, ad->chan_flags);
1082 //LOG_DEVEL(LOG_LEVEL_DEBUG, "my_api_trans_data_in: chan_name %s chan_flags 0x%8.8x", chan_name, ad->chan_flags);
10771083 if (ad->chan_flags == 0)
10781084 {
10791085 /* SVC */
11271133 procs.data = my_api_data;
11281134 rv = chansrv_drdynvc_open(chan_name, ad->chan_flags,
11291135 &procs, &(ad->chan_id));
1130 //g_writeln("my_api_trans_data_in: chansrv_drdynvc_open rv %d "
1136 //LOG_DEVEL(LOG_LEVEL_DEBUG, "my_api_trans_data_in: chansrv_drdynvc_open rv %d "
11311137 // "chan_id %d", rv, ad->chan_id);
11321138 g_drdynvcs[ad->chan_id].xrdp_api_trans = trans;
11331139 }
1134 g_free(chan_name);
11351140 init_stream(s, 0);
11361141 trans->extra_flags = 2;
11371142 trans->header_size = 0;
11411146 bytes = g_sck_recv(trans->sck, s->data, s->size, 0);
11421147 if (bytes < 1)
11431148 {
1144 //g_writeln("my_api_trans_data_in: disconnect");
1149 //LOG_DEVEL(LOG_LEVEL_DEBUG, "my_api_trans_data_in: disconnect");
11451150 return 1;
11461151 }
11471152 if (ad->chan_flags == 0)
11521157 else
11531158 {
11541159 /* DVS */
1155 //g_writeln("my_api_trans_data_in: s->size %d bytes %d", s->size, bytes);
1160 //LOG_DEVEL(LOG_LEVEL_DEBUG, "my_api_trans_data_in: s->size %d bytes %d", s->size, bytes);
11561161 rv = chansrv_drdynvc_send_data(ad->chan_id, s->data, bytes);
11571162 }
11581163 init_stream(s, 0);
11841189 return 1;
11851190 }
11861191
1187 LOGM((LOG_LEVEL_DEBUG, "my_trans_conn_in:"));
1192 LOG_DEVEL(LOG_LEVEL_DEBUG, "my_trans_conn_in:");
11881193 g_con_trans = new_trans;
11891194 g_con_trans->trans_data_in = my_trans_data_in;
11901195 g_con_trans->header_size = 8;
12031208 {
12041209 struct xrdp_api_data *ad;
12051210
1206 //g_writeln("my_api_trans_conn_in:");
1211 //LOG_DEVEL(LOG_LEVEL_DEBUG, "my_api_trans_conn_in:");
12071212 if ((trans == NULL) || (trans != g_api_lis_trans) || (new_trans == NULL))
12081213 {
1209 g_writeln("my_api_trans_conn_in: error");
1214 LOG_DEVEL(LOG_LEVEL_ERROR, "my_api_trans_conn_in: error");
12101215 return 1;
12111216 }
12121217 new_trans->trans_data_in = my_api_trans_data_in;
12151220 ad = g_new0(struct xrdp_api_data, 1);
12161221 if (ad == NULL)
12171222 {
1218 g_writeln("my_api_trans_conn_in: error");
1223 LOG_DEVEL(LOG_LEVEL_ERROR, "my_api_trans_conn_in: error");
12191224 return 1;
12201225 }
12211226 new_trans->callback_data = ad;
12351240 trans_delete(g_lis_trans);
12361241 }
12371242
1238 if (g_use_unix_socket)
1243 if (g_cfg->use_unix_socket)
12391244 {
12401245 g_lis_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
12411246 g_lis_trans->is_term = g_is_term;
12531258
12541259 if (error != 0)
12551260 {
1256 LOGM((LOG_LEVEL_ERROR, "setup_listen: trans_listen failed for port %s",
1257 port));
1261 LOG_DEVEL(LOG_LEVEL_ERROR, "setup_listen: trans_listen failed for port %s",
1262 port);
12581263 return 1;
12591264 }
12601265
12761281
12771282 if (error != 0)
12781283 {
1279 LOGM((LOG_LEVEL_ERROR, "setup_api_listen: trans_listen failed for port %s",
1280 port));
1284 LOG_DEVEL(LOG_LEVEL_ERROR, "setup_api_listen: trans_listen failed for port %s",
1285 port);
12811286 return 1;
12821287 }
12831288
12941299 struct trans *ltran;
12951300
12961301 for (api_con_index = g_api_con_trans_list->count - 1;
1297 api_con_index >= 0;
1298 api_con_index--)
1302 api_con_index >= 0;
1303 api_con_index--)
12991304 {
13001305 ltran = (struct trans *)
1301 list_get_item(g_api_con_trans_list, api_con_index);
1306 list_get_item(g_api_con_trans_list, api_con_index);
13021307 if (ltran != NULL)
13031308 {
13041309 trans_get_wait_objs_rw(ltran, robjs, rcount, wobjs, wcount,
13181323 struct xrdp_api_data *ad;
13191324
13201325 for (api_con_index = g_api_con_trans_list->count - 1;
1321 api_con_index >= 0;
1322 api_con_index--)
1326 api_con_index >= 0;
1327 api_con_index--)
13231328 {
13241329 ltran = (struct trans *)
1325 list_get_item(g_api_con_trans_list, api_con_index);
1330 list_get_item(g_api_con_trans_list, api_con_index);
13261331 if (ltran != NULL)
13271332 {
13281333 if (trans_check_wait_objs(ltran) != 0)
13351340 chansrv_drdynvc_close(ad->chan_id);
13361341 }
13371342 for (drdynvc_index = 0;
1338 drdynvc_index < (int) ARRAYSIZE(g_drdynvcs);
1339 drdynvc_index++)
1343 drdynvc_index < (int) ARRAYSIZE(g_drdynvcs);
1344 drdynvc_index++)
13401345 {
13411346 if (g_drdynvcs[drdynvc_index].xrdp_api_trans == ltran)
13421347 {
13591364 struct trans *ltran;
13601365
13611366 for (api_con_index = g_api_con_trans_list->count - 1;
1362 api_con_index >= 0;
1363 api_con_index--)
1367 api_con_index >= 0;
1368 api_con_index--)
13641369 {
13651370 ltran = (struct trans *)
1366 list_get_item(g_api_con_trans_list, api_con_index);
1371 list_get_item(g_api_con_trans_list, api_con_index);
13671372 if (ltran != NULL)
13681373 {
13691374 list_remove_item(g_api_con_trans_list, api_con_index);
13861391 int error;
13871392 THREAD_RV rv;
13881393
1389 LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread start"));
1394 LOG_DEVEL(LOG_LEVEL_INFO, "channel_thread_loop: thread start");
13901395 rv = 0;
13911396 g_api_con_trans_list = list_create();
13921397 setup_api_listen();
14081413 check_timeout();
14091414 if (g_is_wait_obj_set(g_term_event))
14101415 {
1411 LOGM((LOG_LEVEL_INFO, "channel_thread_loop: g_term_event set"));
1416 LOG_DEVEL(LOG_LEVEL_INFO, "channel_thread_loop: g_term_event set");
14121417 clipboard_deinit();
14131418 sound_deinit();
14141419 devredir_deinit();
14201425 {
14211426 if (trans_check_wait_objs(g_lis_trans) != 0)
14221427 {
1423 LOGM((LOG_LEVEL_INFO, "channel_thread_loop: "
1424 "trans_check_wait_objs error"));
1428 LOG_DEVEL(LOG_LEVEL_INFO, "channel_thread_loop: "
1429 "trans_check_wait_objs error");
14251430 }
14261431 }
14271432
14291434 {
14301435 if (trans_check_wait_objs(g_con_trans) != 0)
14311436 {
1432 LOGM((LOG_LEVEL_INFO, "channel_thread_loop: "
1433 "trans_check_wait_objs error resetting"));
1437 LOG_DEVEL(LOG_LEVEL_INFO, "channel_thread_loop: "
1438 "trans_check_wait_objs error resetting");
14341439 clipboard_deinit();
14351440 sound_deinit();
14361441 devredir_deinit();
14521457 {
14531458 if (trans_check_wait_objs(g_api_lis_trans) != 0)
14541459 {
1455 LOG(0, ("channel_thread_loop: trans_check_wait_objs failed"));
1460 LOG_DEVEL(LOG_LEVEL_ERROR, "channel_thread_loop: trans_check_wait_objs failed");
14561461 }
14571462 }
14581463 /* check the wait_objs in g_api_con_trans_list */
14921497 g_api_lis_trans = 0;
14931498 api_con_trans_list_remove_all();
14941499 list_delete(g_api_con_trans_list);
1495 LOGM((LOG_LEVEL_INFO, "channel_thread_loop: thread stop"));
1500 LOG_DEVEL(LOG_LEVEL_INFO, "channel_thread_loop: thread stop");
14961501 g_set_wait_obj(g_thread_done_event);
14971502 return rv;
14981503 }
15011506 void
15021507 term_signal_handler(int sig)
15031508 {
1504 LOGM((LOG_LEVEL_INFO, "term_signal_handler: got signal %d", sig));
1509 LOG_DEVEL(LOG_LEVEL_INFO, "term_signal_handler: got signal %d", sig);
15051510 g_set_wait_obj(g_term_event);
15061511 }
15071512
15091514 void
15101515 nil_signal_handler(int sig)
15111516 {
1512 LOGM((LOG_LEVEL_INFO, "nil_signal_handler: got signal %d", sig));
1517 LOG_DEVEL(LOG_LEVEL_INFO, "nil_signal_handler: got signal %d", sig);
15131518 }
15141519
15151520 /*****************************************************************************/
15181523 {
15191524 int pid;
15201525
1521 LOG(0, ("child_signal_handler:"));
1526 LOG_DEVEL(LOG_LEVEL_INFO, "child_signal_handler:");
15221527 do
15231528 {
15241529 pid = g_waitchild();
1525 LOG(0, ("child_signal_handler: child pid %d", pid));
1530 LOG_DEVEL(LOG_LEVEL_INFO, "child_signal_handler: child pid %d", pid);
15261531 if ((pid == g_exec_pid) && (pid > 0))
15271532 {
1528 LOG(0, ("child_signal_handler: found pid %d", pid));
1533 LOG_DEVEL(LOG_LEVEL_INFO, "child_signal_handler: found pid %d", pid);
15291534 //shutdownx();
15301535 }
15311536 }
15361541 void
15371542 segfault_signal_handler(int sig)
15381543 {
1539 LOG(0, ("segfault_signal_handler: entered......."));
1544 LOG_DEVEL(LOG_LEVEL_ERROR, "segfault_signal_handler: entered.......");
15401545 xfuse_deinit();
15411546 exit(0);
15421547 }
15451550 static void
15461551 x_server_fatal_handler(void)
15471552 {
1548 LOGM((LOG_LEVEL_INFO, "xserver_fatal_handler: entered......."));
1553 LOG_DEVEL(LOG_LEVEL_INFO, "xserver_fatal_handler: entered.......");
15491554 /* At this point the X server has gone away. Dont make any X calls. */
15501555 xfuse_deinit();
15511556 exit(0);
16141619 int
16151620 main_cleanup(void)
16161621 {
1617 g_delete_wait_obj(g_term_event);
1618 g_delete_wait_obj(g_thread_done_event);
1619 g_delete_wait_obj(g_exec_event);
1620 tc_mutex_delete(g_exec_mutex);
1622 if (g_term_event != 0)
1623 {
1624 g_delete_wait_obj(g_term_event);
1625 }
1626 if (g_thread_done_event != 0)
1627 {
1628 g_delete_wait_obj(g_thread_done_event);
1629 }
1630 if (g_exec_event != 0)
1631 {
1632 g_delete_wait_obj(g_exec_event);
1633 tc_mutex_delete(g_exec_mutex);
1634 tc_sem_delete(g_exec_sem);
1635 }
1636 log_end();
1637 config_free(g_cfg);
16211638 g_deinit(); /* os_calls */
16221639 return 0;
16231640 }
16241641
16251642 /*****************************************************************************/
16261643 static int
1627 read_ini(void)
1628 {
1629 char filename[256];
1630 struct list *names;
1631 struct list *values;
1632 char *name;
1633 char *value;
1634 int index;
1635
1636 g_memset(filename, 0, (sizeof(char) * 256));
1637 names = list_create();
1638 names->auto_free = 1;
1639 values = list_create();
1640 values->auto_free = 1;
1641 g_use_unix_socket = 0;
1642 g_snprintf(filename, 255, "%s/sesman.ini", XRDP_CFG_PATH);
1643
1644 if (file_by_name_read_section(filename, "Globals", names, values) == 0)
1645 {
1646 for (index = 0; index < names->count; index++)
1647 {
1648 name = (char *)list_get_item(names, index);
1649 value = (char *)list_get_item(values, index);
1650
1651 if (g_strcasecmp(name, "ListenAddress") == 0)
1652 {
1653 if (g_strcasecmp(value, "127.0.0.1") == 0)
1654 {
1655 g_use_unix_socket = 1;
1656 }
1657 }
1658 }
1659 }
1660
1661 list_delete(names);
1662 list_delete(values);
1663 return 0;
1664 }
1665
1666 /*****************************************************************************/
1667 static int
16681644 get_log_path(char *path, int bytes)
16691645 {
1670 char* log_path;
1646 char *log_path;
16711647 int rv;
16721648
16731649 rv = 1;
17161692 }
17171693
17181694 /*****************************************************************************/
1719 static enum logLevels
1720 get_log_level(const char* level_str, enum logLevels default_level)
1721 {
1722 static const char* levels[] = {
1723 "LOG_LEVEL_ALWAYS",
1724 "LOG_LEVEL_ERROR",
1725 "LOG_LEVEL_WARNING",
1726 "LOG_LEVEL_INFO",
1727 "LOG_LEVEL_DEBUG",
1728 "LOG_LEVEL_TRACE"
1729 };
1730 unsigned int i;
1731
1732 if (level_str == NULL || level_str[0] == 0)
1733 {
1734 return default_level;
1735 }
1736 for (i = 0; i < ARRAYSIZE(levels); ++i)
1737 {
1738 if (g_strcasecmp(levels[i], level_str) == 0)
1739 {
1740 return (enum logLevels) i;
1741 }
1742 }
1743 return default_level;
1744 }
1745
1746 /*****************************************************************************/
17471695 static int
17481696 run_exec(void)
17491697 {
17501698 int pid;
17511699
1752 LOG(10, ("run_exec:"));
1700 LOG_DEVEL(LOG_LEVEL_DEBUG, "run_exec:");
17531701 pid = g_fork();
17541702
17551703 if (pid == 0)
17771725 tbus waiters[4];
17781726 int pid = 0;
17791727 char text[256];
1728 const char *config_path;
17801729 char log_path[256];
17811730 char *display_text;
17821731 char log_file[256];
17831732 enum logReturns error;
1784 struct log_config logconfig;
1785 enum logLevels log_level;
1786 char *restrict_outbound_clipboard_env;
1733 struct log_config *logconfig;
17871734 g_init("xrdp-chansrv"); /* os_calls */
1735 g_memset(g_drdynvcs, 0, sizeof(g_drdynvcs));
17881736
17891737 log_path[255] = 0;
17901738 if (get_log_path(log_path, 255) != 0)
17911739 {
17921740 g_writeln("error reading CHANSRV_LOG_PATH and HOME environment variable");
1793 g_deinit();
1794 return 1;
1795 }
1796
1797 restrict_outbound_clipboard_env = g_getenv("CHANSRV_RESTRICT_OUTBOUND_CLIPBOARD");
1798 if (restrict_outbound_clipboard_env != 0)
1799 {
1800 if (g_strcmp(restrict_outbound_clipboard_env, "1") == 0)
1801 {
1802 g_restrict_outbound_clipboard = 1;
1803 }
1804 }
1805
1806 read_ini();
1741 main_cleanup();
1742 return 1;
1743 }
1744
1745 /*
1746 * The user is unable at present to override the sysadmin-provided
1747 * sesman.ini location */
1748 config_path = XRDP_CFG_PATH "/sesman.ini";
1749 if ((g_cfg = config_read(0, config_path)) == NULL)
1750 {
1751 main_cleanup();
1752 return 1;
1753 }
1754 config_dump(g_cfg);
1755
18071756 pid = g_getpid();
18081757 display_text = g_getenv("DISPLAY");
1809
1810 if (display_text)
1758 if (display_text != NULL)
1759 {
18111760 get_display_num_from_display(display_text);
1812
1813 log_level = get_log_level(g_getenv("CHANSRV_LOG_LEVEL"), LOG_LEVEL_INFO);
1761 }
18141762
18151763 /* starting logging subsystem */
1816 g_memset(&logconfig, 0, sizeof(struct log_config));
1817 logconfig.program_name = "xrdp-chansrv";
18181764 g_snprintf(log_file, 255, "%s/xrdp-chansrv.%d.log", log_path, g_display_num);
18191765 g_writeln("chansrv::main: using log file [%s]", log_file);
1820
18211766 if (g_file_exist(log_file))
18221767 {
18231768 g_file_delete(log_file);
18241769 }
18251770
1826 g_memset(g_drdynvcs, 0, sizeof(g_drdynvcs));
1827
1828 logconfig.log_file = log_file;
1829 logconfig.fd = -1;
1830 logconfig.log_level = log_level;
1831 logconfig.enable_syslog = 0;
1832 logconfig.syslog_level = LOG_LEVEL_ALWAYS;
1833 error = log_start_from_param(&logconfig);
1771 logconfig = log_config_init_from_config(config_path, "xrdp-chansrv", "Chansrv");
1772 if (logconfig->log_file != NULL)
1773 {
1774 g_free(logconfig->log_file);
1775 }
1776 logconfig->log_file = log_file;
1777 error = log_start_from_param(logconfig);
1778 logconfig->log_file = NULL;
1779 log_config_free(logconfig);
1780 logconfig = NULL;
18341781
18351782 if (error != LOG_STARTUP_OK)
18361783 {
18481795 break;
18491796 }
18501797
1851 g_deinit();
1852 return 1;
1853 }
1854
1855 LOGM((LOG_LEVEL_ALWAYS, "main: app started pid %d(0x%8.8x)", pid, pid));
1798 main_cleanup();
1799 return 1;
1800 }
1801
1802 LOG_DEVEL(LOG_LEVEL_INFO, "main: app started pid %d(0x%8.8x)", pid, pid);
18561803 /* set up signal handler */
18571804 g_signal_terminate(term_signal_handler); /* SIGTERM */
18581805 g_signal_user_interrupt(term_signal_handler); /* SIGINT */
18631810 /* Cater for the X server exiting unexpectedly */
18641811 xcommon_set_x_server_fatal_handler(x_server_fatal_handler);
18651812
1866 LOGM((LOG_LEVEL_INFO, "main: DISPLAY env var set to %s", display_text));
1813 LOG_DEVEL(LOG_LEVEL_INFO, "main: DISPLAY env var set to %s", display_text);
18671814
18681815 if (g_display_num == 0)
18691816 {
1870 LOGM((LOG_LEVEL_ERROR, "main: error, display is zero"));
1871 g_deinit();
1872 return 1;
1873 }
1874
1875 LOGM((LOG_LEVEL_INFO, "main: using DISPLAY %d", g_display_num));
1817 LOG_DEVEL(LOG_LEVEL_ERROR, "main: error, display is zero");
1818 main_cleanup();
1819 return 1;
1820 }
1821
1822 LOG_DEVEL(LOG_LEVEL_INFO, "main: using DISPLAY %d", g_display_num);
18761823 g_snprintf(text, 255, "xrdp_chansrv_%8.8x_main_term", pid);
18771824 g_term_event = g_create_wait_obj(text);
18781825 g_snprintf(text, 255, "xrdp_chansrv_%8.8x_thread_done", pid);
18901837
18911838 if (g_obj_wait(waiters, 2, 0, 0, 0) != 0)
18921839 {
1893 LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed"));
1840 LOG_DEVEL(LOG_LEVEL_ERROR, "main: error, g_obj_wait failed");
18941841 break;
18951842 }
18961843
19111858 /* wait for thread to exit */
19121859 if (g_obj_wait(&g_thread_done_event, 1, 0, 0, 0) != 0)
19131860 {
1914 LOGM((LOG_LEVEL_ERROR, "main: error, g_obj_wait failed"));
1861 LOG_DEVEL(LOG_LEVEL_ERROR, "main: error, g_obj_wait failed");
19151862 break;
19161863 }
19171864 }
19181865
19191866 /* cleanup */
19201867 main_cleanup();
1921 LOGM((LOG_LEVEL_INFO, "main: app exiting pid %d(0x%8.8x)", pid, pid));
1922 g_deinit();
1923 return 0;
1924 }
1925
1868 LOG_DEVEL(LOG_LEVEL_INFO, "main: app exiting pid %d(0x%8.8x)", pid, pid);
1869 return 0;
1870 }
1871
3737 int send_rail_drawing_orders(char* data, int size);
3838 int main_cleanup(void);
3939 int add_timeout(int msoffset, void (*callback)(void* data), void* data);
40
41 #define LOG_LEVEL 5
42
43 #define LOG(_a, _params) \
44 { \
45 if (_a < LOG_LEVEL) \
46 { \
47 g_write("xrdp-chansrv [%10.10u]: ", g_time3()); \
48 g_writeln _params ; \
49 } \
50 }
51
52 #define LOGM(_args) do { log_message _args ; } while (0)
5340
5441 #ifndef GSET_UINT8
5542 #define GSET_UINT8(_ptr, _offset, _data) \
0 /**
1 * xrdp: A Remote Desktop Protocol server.
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 *
15 * This file implements the interface in chansrv_config.h
16 */
17 #if defined(HAVE_CONFIG_H)
18 #include <config_ac.h>
19 #endif
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdarg.h>
24
25 #include "arch.h"
26
27 #include "list.h"
28 #include "log.h"
29 #include "file.h"
30 #include "os_calls.h"
31
32 #include "chansrv_config.h"
33 #include "string_calls.h"
34
35 /* Default settings */
36 #define DEFAULT_USE_UNIX_SOCKET 0
37 #define DEFAULT_RESTRICT_OUTBOUND_CLIPBOARD 0
38 #define DEFAULT_ENABLE_FUSE_MOUNT 1
39 #define DEFAULT_FUSE_MOUNT_NAME "xrdp-client"
40 #define DEFAULT_FILE_UMASK 077
41
42 /**
43 * Type used for passing a logging function about
44 */
45 typedef
46 printflike(2, 3)
47 enum logReturns (*log_func_t)(const enum logLevels lvl,
48 const char *msg, ...);
49
50 /***************************************************************************//**
51 * @brief Error logging function to use to log to stdout
52 *
53 * Has the same signature as the log_message() function
54 */
55 static enum logReturns
56 log_to_stdout(const enum logLevels lvl, const char *msg, ...)
57 {
58 char buff[256];
59 va_list ap;
60
61 va_start(ap, msg);
62 vsnprintf(buff, sizeof(buff), msg, ap);
63 va_end(ap);
64 g_writeln("%s", buff);
65
66 return LOG_STARTUP_OK;
67 }
68
69 /***************************************************************************//**
70 * Reads the config values we need from the [Globals] section
71 *
72 * @param logmsg Function to use to log messages
73 * @param names List of definitions in the section
74 * @params values List of corresponding values for the names
75 * @params cfg Pointer to structure we're filling in
76 *
77 * @return 0 for success
78 */
79 static int
80 read_config_globals(log_func_t logmsg,
81 struct list *names, struct list *values,
82 struct config_chansrv *cfg)
83 {
84 int error = 0;
85 int index;
86
87 for (index = 0; index < names->count; ++index)
88 {
89 const char *name = (const char *)list_get_item(names, index);
90 const char *value = (const char *)list_get_item(values, index);
91
92 if (g_strcasecmp(name, "ListenAddress") == 0)
93 {
94 if (g_strcasecmp(value, "127.0.0.1") == 0)
95 {
96 cfg->use_unix_socket = 1;
97 }
98 }
99 }
100
101 return error;
102 }
103
104 /***************************************************************************//**
105 * Reads the config values we need from the [Security] section
106 *
107 * @param logmsg Function to use to log messages
108 * @param names List of definitions in the section
109 * @params values List of corresponding values for the names
110 * @params cfg Pointer to structure we're filling in
111 *
112 * @return 0 for success
113 */
114 static int
115 read_config_security(log_func_t logmsg,
116 struct list *names, struct list *values,
117 struct config_chansrv *cfg)
118 {
119 int error = 0;
120 int index;
121
122 for (index = 0; index < names->count; ++index)
123 {
124 const char *name = (const char *)list_get_item(names, index);
125 const char *value = (const char *)list_get_item(values, index);
126
127 if (g_strcasecmp(name, "RestrictOutboundClipboard") == 0)
128 {
129 cfg->restrict_outbound_clipboard = g_text2bool(value);
130 }
131 }
132
133 return error;
134 }
135
136 /***************************************************************************//**
137 * Reads the config values we need from the [Chansrv] section
138 *
139 * @param logmsg Function to use to log messages
140 * @param names List of definitions in the section
141 * @params values List of corresponding values for the names
142 * @params cfg Pointer to structure we're filling in
143 *
144 * @return 0 for success
145 */
146 static int
147 read_config_chansrv(log_func_t logmsg,
148 struct list *names, struct list *values,
149 struct config_chansrv *cfg)
150 {
151 int error = 0;
152 int index;
153
154 for (index = 0; index < names->count; ++index)
155 {
156 const char *name = (const char *)list_get_item(names, index);
157 const char *value = (const char *)list_get_item(values, index);
158
159 if (g_strcasecmp(name, "EnableFuseMount") == 0)
160 {
161 cfg->enable_fuse_mount = g_text2bool(value);
162 }
163 if (g_strcasecmp(name, "FuseMountName") == 0)
164 {
165 g_free(cfg->fuse_mount_name);
166 cfg->fuse_mount_name = g_strdup(value);
167 if (cfg->fuse_mount_name == NULL)
168 {
169 logmsg(LOG_LEVEL_ERROR, "Can't alloc FuseMountName");
170 error = 1;
171 break;
172 }
173 }
174 else if (g_strcasecmp(name, "FileUmask") == 0)
175 {
176 cfg->file_umask = strtol(value, NULL, 0);
177 }
178 }
179
180 return error;
181 }
182
183 /***************************************************************************//**
184 * @brief returns a config block with default values
185 *
186 * @return Block, or NULL for no memory
187 */
188 static struct config_chansrv *
189 new_config(void)
190 {
191 /* Do all the allocations at the beginning, then check them together */
192 struct config_chansrv *cfg = g_new0(struct config_chansrv, 1);
193 char *fuse_mount_name = g_strdup(DEFAULT_FUSE_MOUNT_NAME);
194 if (cfg == NULL || fuse_mount_name == NULL)
195 {
196 /* At least one memory allocation failed */
197 g_free(fuse_mount_name);
198 g_free(cfg);
199 cfg = NULL;
200 }
201 else
202 {
203 cfg->use_unix_socket = DEFAULT_USE_UNIX_SOCKET;
204 cfg->enable_fuse_mount = DEFAULT_ENABLE_FUSE_MOUNT;
205 cfg->restrict_outbound_clipboard = DEFAULT_RESTRICT_OUTBOUND_CLIPBOARD;
206 cfg->fuse_mount_name = fuse_mount_name;
207 cfg->file_umask = DEFAULT_FILE_UMASK;
208 }
209
210 return cfg;
211 }
212
213 /******************************************************************************/
214 struct config_chansrv *
215 config_read(int use_logger, const char *sesman_ini)
216 {
217 int error = 0;
218 struct config_chansrv *cfg = NULL;
219 log_func_t logmsg = (use_logger) ? log_message : log_to_stdout;
220 int fd;
221
222 fd = g_file_open_ex(sesman_ini, 1, 0, 0, 0);
223 if (fd < 0)
224 {
225 logmsg(LOG_LEVEL_ERROR, "Can't open config file %s", sesman_ini);
226 error = 1;
227 }
228 else
229 {
230 if ((cfg = new_config()) == NULL)
231 {
232 logmsg(LOG_LEVEL_ERROR, "Can't alloc config block");
233 error = 1;
234 }
235 else
236 {
237 struct list *names = list_create();
238 struct list *values = list_create();
239
240 names->auto_free = 1;
241 values->auto_free = 1;
242
243 if (!error && file_read_section(fd, "Globals", names, values) == 0)
244 {
245 error = read_config_globals(logmsg, names, values, cfg);
246 }
247
248
249 if (!error && file_read_section(fd, "Security", names, values) == 0)
250 {
251 error = read_config_security(logmsg, names, values, cfg);
252 }
253
254 if (!error && file_read_section(fd, "Chansrv", names, values) == 0)
255 {
256 error = read_config_chansrv(logmsg, names, values, cfg);
257 }
258
259 list_delete(names);
260 list_delete(values);
261 }
262
263 g_file_close(fd);
264 }
265
266 if (error)
267 {
268 config_free(cfg);
269 cfg = NULL;
270 }
271
272 return cfg;
273 }
274
275 /******************************************************************************/
276 void
277 config_dump(struct config_chansrv *config)
278 {
279 g_writeln("Global configuration:");
280 g_writeln(" UseUnixSocket (derived): %s",
281 g_bool2text(config->use_unix_socket));
282
283 g_writeln("\nSecurity configuration:");
284 g_writeln(" RestrictOutboundClipboard: %s",
285 g_bool2text(config->restrict_outbound_clipboard));
286
287 g_writeln("\nChansrv configuration:");
288 g_writeln(" EnableFuseMount %s",
289 g_bool2text(config->enable_fuse_mount));
290 g_writeln(" FuseMountName: %s", config->fuse_mount_name);
291 g_writeln(" FileMask: 0%o", config->file_umask);
292 }
293
294 /******************************************************************************/
295 void
296 config_free(struct config_chansrv *cc)
297 {
298 if (cc != NULL)
299 {
300 g_free(cc->fuse_mount_name);
301 g_free(cc);
302 }
303 }
0 /**
1 * xrdp: A Remote Desktop Protocol server.
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 *
15 * This file contains the chansrv configuration parameters from sesman.ini
16 */
17
18 #ifndef _CHANSRV_CONFIG
19 #define _CHANSRV_CONFIG
20
21 #include <sys/stat.h>
22
23 struct config_chansrv
24 {
25 /** Whether to use a UNIX socket for chansrv */
26 int use_unix_socket;
27
28 /** Whether the FUSE mount is enabled or not */
29 int enable_fuse_mount;
30
31 /** RestrictOutboundClipboard setting from sesman.ini */
32 int restrict_outbound_clipboard;
33
34 /** * FuseMountName from sesman.ini */
35 char *fuse_mount_name;
36 /** FileUmask from sesman.ini */
37 mode_t file_umask;
38 };
39
40
41 /**
42 *
43 * @brief Reads sesman configuration
44 * @param use_logger Use logger to log errors (otherwise stdout)
45 * @param sesman_ini Name of configuration file to read
46 *
47 * @return configuration on success, NULL on failure
48 *
49 * @pre logging is assumed to be active
50 * @post pass return value to config_free() to prevent memory leaks
51 *
52 */
53 struct config_chansrv *
54 config_read(int use_logger, const char *sesman_ini);
55
56 /**
57 *
58 * @brief Dumps configuration to stdout
59 * @param pointer to a config_chansrv struct
60 *
61 */
62 void
63 config_dump(struct config_chansrv *config);
64
65 /**
66 *
67 * @brief Frees configuration allocated by config_read()
68 * @param pointer to a config_chansrv struct (may be NULL)
69 *
70 */
71 void
72 config_free(struct config_chansrv *cs);
73
74 #endif /* _CHANSRV_CONFIG */
4040 #include "chansrv_xfs.h"
4141
4242 /* dummy calls when XRDP_FUSE is not defined */
43 int xfuse_init(void) { return 0; }
44 int xfuse_deinit(void) { return 0; }
45 int xfuse_check_wait_objs(void) { return 0; }
46 int xfuse_get_wait_objs(tbus *objs, int *count, int *timeout) { return 0; }
47 int xfuse_create_share(tui32 device_id, const char *dirname) { return 0; }
43 int xfuse_init(void)
44 {
45 return 0;
46 }
47 int xfuse_deinit(void)
48 {
49 return 0;
50 }
51 int xfuse_check_wait_objs(void)
52 {
53 return 0;
54 }
55 int xfuse_get_wait_objs(tbus *objs, int *count, int *timeout)
56 {
57 return 0;
58 }
59 int xfuse_create_share(tui32 device_id, const char *dirname)
60 {
61 return 0;
62 }
4863 void xfuse_delete_share(tui32 share_id) {}
49 int xfuse_clear_clip_dir(void) { return 0; }
50 int xfuse_file_contents_range(int stream_id, const char *data, int data_bytes) { return 0; }
64 int xfuse_clear_clip_dir(void)
65 {
66 return 0;
67 }
68 int xfuse_file_contents_range(int stream_id, const char *data, int data_bytes)
69 {
70 return 0;
71 }
5172 int xfuse_file_contents_size(int stream_id, int file_size)
52 { return 0; }
73 {
74 return 0;
75 }
5376 int xfuse_add_clip_dir_item(const char *filename,
54 int flags, int size, int lindex) { return 0; }
77 int flags, int size, int lindex)
78 {
79 return 0;
80 }
5581
5682 void xfuse_devredir_cb_enum_dir_add_entry(
57 struct state_dirscan *fip,
58 const char *name,
59 const struct file_attr *fattr)
60 {}
83 struct state_dirscan *fip,
84 const char *name,
85 const struct file_attr *fattr)
86 {}
6187 void xfuse_devredir_cb_enum_dir_done(struct state_dirscan *fip,
6288 enum NTSTATUS IoStatus)
63 {}
89 {}
6490 void xfuse_devredir_cb_lookup_entry(struct state_lookup *fip,
6591 enum NTSTATUS IoStatus,
6692 const struct file_attr *file_info)
67 {}
93 {}
6894 void xfuse_devredir_cb_setattr(struct state_setattr *fip,
6995 enum NTSTATUS IoStatus)
70 {}
96 {}
7197 void xfuse_devredir_cb_create_file(struct state_create *fip,
7298 enum NTSTATUS IoStatus,
7399 tui32 DeviceId, tui32 FileId)
74 {}
100 {}
75101 void xfuse_devredir_cb_open_file(struct state_open *fip,
76102 enum NTSTATUS IoStatus,
77103 tui32 DeviceId, tui32 FileId)
78 {}
104 {}
79105 void xfuse_devredir_cb_read_file(struct state_read *fip,
106 enum NTSTATUS IoStatus,
80107 const char *buf, size_t length)
81 {}
108 {}
82109 void xfuse_devredir_cb_write_file(
83 struct state_write *fip,
84 enum NTSTATUS IoStatus,
85 off_t offset,
86 size_t length)
87 {}
110 struct state_write *fip,
111 enum NTSTATUS IoStatus,
112 off_t offset,
113 size_t length)
114 {}
88115 void xfuse_devredir_cb_rmdir_or_file(struct state_remove *fip,
89116 enum NTSTATUS IoStatus)
90 {}
117 {}
91118 void xfuse_devredir_cb_rename_file(struct state_rename *fip,
92119 enum NTSTATUS IoStatus)
93 {}
120 {}
94121 void xfuse_devredir_cb_file_close(struct state_close *fip)
95 {}
122 {}
96123
97124 #else
98125
116143
117144 #include "arch.h"
118145 #include "os_calls.h"
146 #include "string_calls.h"
119147 #include "clipboard_file.h"
120148 #include "chansrv_fuse.h"
121149 #include "chansrv_xfs.h"
150 #include "chansrv.h"
151 #include "chansrv_config.h"
122152 #include "devredir.h"
123153 #include "list.h"
124154 #include "file.h"
129159
130160 #define XFUSE_ATTR_TIMEOUT 5.0
131161 #define XFUSE_ENTRY_TIMEOUT 5.0
132
133 /* module based logging */
134 #define LOG_ERROR 0
135 #define LOG_INFO 1
136 #define LOG_DEBUG 2
137 #ifndef LOG_LEVEL
138 #define LOG_LEVEL LOG_ERROR
139 #endif
140
141 #define log_error(_params...) \
142 { \
143 g_write("[%10.10u]: FUSE %s: %d : ERROR: ", \
144 g_time3(), __func__, __LINE__); \
145 g_writeln (_params); \
146 }
147
148 #define log_always(_params...) \
149 { \
150 g_write("[%10.10u]: FUSE %s: %d : ALWAYS: ", \
151 g_time3(), __func__, __LINE__); \
152 g_writeln (_params); \
153 }
154
155 #define log_info(_params...) \
156 { \
157 if (LOG_INFO <= LOG_LEVEL) \
158 { \
159 g_write("[%10.10u]: FUSE %s: %d : ", \
160 g_time3(), __func__, __LINE__); \
161 g_writeln (_params); \
162 } \
163 }
164
165 #define log_debug(_params...) \
166 { \
167 if (LOG_DEBUG <= LOG_LEVEL) \
168 { \
169 g_write("[%10.10u]: FUSE %s: %d : ", \
170 g_time3(), __func__, __LINE__); \
171 g_writeln (_params); \
172 } \
173 }
174162
175163
176164 /* Type of buffer used for fuse_add_direntry() calls */
199187 fuse_req_t req; /* Original FUSE request from lookup */
200188 fuse_ino_t pinum; /* inum of parent directory */
201189 char name[XFS_MAXFILENAMELEN];
202 /* Name to look up */
190 /* Name to look up */
203191 fuse_ino_t existing_inum;
204 /* inum of an existing entry */
192 /* inum of an existing entry */
205193 tui32 existing_generation;
206 /* generation of the above */
194 /* generation of the above */
207195 };
208196
209197 /*
238226 struct fuse_file_info fi; /* File info struct passed to open */
239227 fuse_ino_t pinum; /* inum of parent directory */
240228 char name[XFS_MAXFILENAMELEN];
241 /* Name of file in parent directory */
229 /* Name of file in parent directory */
242230 mode_t mode; /* Mode of file to create */
243231 };
244232
277265 fuse_ino_t pinum; /* inum of parent of file */
278266 fuse_ino_t new_pinum; /* inum of new parent of file */
279267 char name[XFS_MAXFILENAMELEN];
280 /* New name of file in new parent dir */
268 /* New name of file in new parent dir */
281269 };
282270
283271 /*
295283 tui32 DeviceId;
296284 tui32 FileId;
297285 int is_loc_resource; /* this is not a redirected resource */
286
287 /* a directory handle, if this xfuse_handle represents a directory.
288 * NULL, if this xfuse_handle represents a file.
289 *
290 * Note: when this xfuse_handle represents a directory, then the other
291 * fields of this structure contain invalid values.
292 */
293 struct xfs_dir_handle *dir_handle;
298294 };
299295 typedef struct xfuse_handle XFUSE_HANDLE;
300296
308304 int size;
309305 };
310306
311 static char g_fuse_mount_name[256] = "xrdp_client";
312 static mode_t g_umask = 077; /* Umask for files in fs */
307 extern struct config_chansrv *g_cfg; /* in chansrv.c */
313308
314309 static struct list *g_req_list = 0;
315310 static struct xfs_fs *g_xfs; /* an inst of xrdp file system */
390385
391386 /* miscellaneous functions */
392387 static void xfs_inode_to_fuse_entry_param(const XFS_INODE *xinode,
393 struct fuse_entry_param *e);
388 struct fuse_entry_param *e);
394389 static void make_fuse_entry_reply(fuse_req_t req, const XFS_INODE *xinode);
395390 static void make_fuse_attr_reply(fuse_req_t req, const XFS_INODE *xinode);
396391 static const char *filename_on_device(const char *full_path);
397392 static void update_inode_file_attributes(const struct file_attr *fattr,
398 tui32 change_mask, XFS_INODE *xinode);
393 tui32 change_mask, XFS_INODE *xinode);
399394 static char *get_name_for_entry_in_parent(fuse_ino_t parent, const char *name);
395 static unsigned int format_user_info(char *dest, unsigned int len,
396 const char *format);
400397
401398 /*****************************************************************************/
402399 int
403400 load_fuse_config(void)
404401 {
405 int index;
406 char cfg_file[256];
407 struct list *items;
408 struct list *values;
409 char *item;
410 char *value;
411
412 items = list_create();
413 items->auto_free = 1;
414 values = list_create();
415 values->auto_free = 1;
416 g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH);
417 file_by_name_read_section(cfg_file, "Chansrv", items, values);
418 for (index = 0; index < items->count; index++)
419 {
420 item = (char *)list_get_item(items, index);
421 value = (char *)list_get_item(values, index);
422 if (g_strcasecmp(item, "FuseMountName") == 0)
423 {
424 g_strncpy(g_fuse_mount_name, value, 255);
425 }
426 else if (g_strcasecmp(item, "FileUmask") == 0)
427 {
428 g_umask = strtol(value, NULL, 0);
429 log_info("g_umask set to 0%o", g_umask);
430 }
431 }
432 list_delete(items);
433 list_delete(values);
434402 return 0;
403 }
404
405 /*****************************************************************************/
406 XFUSE_HANDLE *
407 xfuse_handle_create()
408 {
409 return g_new0(XFUSE_HANDLE, 1);
410 }
411
412 /*****************************************************************************/
413 void
414 xfuse_handle_delete(XFUSE_HANDLE *self)
415 {
416 if (self == NULL)
417 {
418 return;
419 }
420
421 if (self->dir_handle != NULL)
422 {
423 free(self->dir_handle);
424 }
425 free(self);
426 }
427
428 /*****************************************************************************/
429 uint64_t
430 xfuse_handle_to_fuse_handle(XFUSE_HANDLE *self)
431 {
432 return (uint64_t) (tintptr) self;
433 }
434
435 /*****************************************************************************/
436 XFUSE_HANDLE *
437 xfuse_handle_from_fuse_handle(uint64_t handle)
438 {
439 return (XFUSE_HANDLE *) (tintptr) handle;
435440 }
436441
437442 /*****************************************************************************
443448 /**
444449 * Initialize FUSE subsystem
445450 *
446 * @return 0 on success, -1 on failure
451 * @return 0 on success, -1 on failure, 1 for feature disabled
447452 *****************************************************************************/
448453
449454 int
454459 /* if already inited, just return */
455460 if (g_xfuse_inited)
456461 {
457 log_debug("already inited");
462 LOG_DEVEL(LOG_LEVEL_DEBUG, "already inited");
463 return 0;
464 }
465
466 /* This feature may be disabled */
467 if (!g_cfg->enable_fuse_mount)
468 {
469 /*
470 * Only log the 'disabled mounts' message one time
471 */
472 static int disabled_mounts_msg_shown = 0;
473 if (!disabled_mounts_msg_shown)
474 {
475 LOG(LOG_LEVEL_INFO, "FUSE mounts are disabled by config");
476 disabled_mounts_msg_shown = 1;
477 }
458478 return 1;
459479 }
460480
461481 if (g_ch != 0)
462482 {
463 log_error("g_ch is not zero");
483 LOG_DEVEL(LOG_LEVEL_ERROR, "g_ch is not zero");
464484 return -1;
465485 }
466486
467487 load_fuse_config();
468488
469 /* define FUSE mount point to ~/xrdp_client, ~/thinclient_drives */
470 g_snprintf(g_fuse_root_path, 255, "%s/%s", g_getenv("HOME"), g_fuse_mount_name);
489 /* define FUSE mount point */
490 if (g_cfg->fuse_mount_name[0] == '/')
491 {
492 /* String is an absolute path to the mount point containing
493 * %u or %U characters */
494 format_user_info(g_fuse_root_path, sizeof(g_fuse_root_path),
495 g_cfg->fuse_mount_name);
496 }
497 else
498 {
499 /* mount_name is relative to $HOME, e.g. ~/xrdp_client,
500 * or ~/thinclient_drives */
501 g_snprintf(g_fuse_root_path, sizeof(g_fuse_root_path), "%s/%s",
502 g_getenv("HOME"), g_cfg->fuse_mount_name);
503 }
471504 g_snprintf(g_fuse_clipboard_path, 255, "%s/.clipboard", g_fuse_root_path);
472505
473506 /* if FUSE mount point does not exist, create it */
474507 if (!g_directory_exist(g_fuse_root_path))
475508 {
509 (void)g_create_path(g_fuse_root_path);
476510 if (!g_create_dir(g_fuse_root_path))
477511 {
478 log_error("mkdir %s failed. If %s is already mounted, you must "
512 LOG_DEVEL(LOG_LEVEL_ERROR, "mkdir %s failed. If %s is already mounted, you must "
479513 "first unmount it", g_fuse_root_path, g_fuse_root_path);
480514 return -1;
481515 }
483517
484518 /* setup xrdp file system */
485519 if (xfuse_init_xrdp_fs())
520 {
486521 return -1;
522 }
487523
488524 /* setup FUSE callbacks */
489525 g_memset(&g_xfuse_ops, 0, sizeof(g_xfuse_ops));
570606 int rval;
571607
572608 if (g_ch == 0)
609 {
573610 return 0;
611 }
574612
575613 if (g_tcp_select(g_fd, 0) & 1)
576614 {
578616
579617 rval = fuse_chan_recv(&tmpch, g_buffer, g_bufsize);
580618 if (rval == -EINTR)
619 {
581620 return -1;
621 }
582622
583623 if (rval == -ENODEV)
624 {
584625 return -1;
626 }
585627
586628 if (rval <= 0)
629 {
587630 return -1;
631 }
588632
589633 fuse_session_process(g_se, g_buffer, rval, tmpch);
590634 }
603647 int lcount;
604648
605649 if (g_ch == 0)
650 {
606651 return 0;
652 }
607653
608654 lcount = *count;
609655 objs[lcount] = g_fd;
627673 XFS_INODE *xinode;
628674
629675 if (dirname != NULL && strlen(dirname) > 0 &&
630 xfuse_init_xrdp_fs() == 0)
676 xfuse_init_xrdp_fs() == 0)
631677 {
632678 xinode = xfs_add_entry(g_xfs, FUSE_ROOT_ID, dirname, (0777 | S_IFDIR));
633679 if (xinode == NULL)
634680 {
635 log_debug("xfs_add_entry() failed");
681 LOG_DEVEL(LOG_LEVEL_DEBUG, "xfs_add_entry() failed");
636682 }
637683 else
638684 {
685 xinode->is_redirected = 1;
639686 xinode->device_id = device_id;
640687 result = 0;
641688 }
652699
653700 void xfuse_delete_share(tui32 device_id)
654701 {
655 xfs_delete_entries_with_device_id(g_xfs, device_id);
702 xfs_delete_redirected_entries_with_device_id(g_xfs, device_id);
656703 }
657704
658705 /**
684731 int
685732 xfuse_file_contents_range(int stream_id, const char *data, int data_bytes)
686733 {
687 log_debug("entered: stream_id=%d data_bytes=%d", stream_id, data_bytes);
734 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: stream_id=%d data_bytes=%d", stream_id, data_bytes);
688735
689736 struct req_list_item *rli;
690737
691738 if ((rli = (struct req_list_item *) list_get_item(g_req_list, 0)) == NULL)
692739 {
693 log_error("range error!");
740 LOG_DEVEL(LOG_LEVEL_ERROR, "range error!");
694741 return -1;
695742 }
696743
697 log_debug("lindex=%d off=%d size=%d", rli->lindex, rli->off, rli->size);
744 LOG_DEVEL(LOG_LEVEL_DEBUG, "lindex=%d off=%d size=%d", rli->lindex, rli->off, rli->size);
698745
699746 fuse_reply_buf(rli->req, data, data_bytes);
700747
701748 list_remove_item(g_req_list, 0);
702749 if (g_req_list->count <= 0)
703750 {
704 log_debug("completed all requests");
751 LOG_DEVEL(LOG_LEVEL_DEBUG, "completed all requests");
705752 return 0;
706753 }
707754
709756 rli = (struct req_list_item *) list_get_item(g_req_list, 0);
710757 if (rli == NULL)
711758 {
712 log_error("range error!");
759 LOG_DEVEL(LOG_LEVEL_ERROR, "range error!");
713760 return -1;
714761 }
715762
716 log_debug("requesting clipboard file data");
763 LOG_DEVEL(LOG_LEVEL_DEBUG, "requesting clipboard file data");
717764
718765 clipboard_request_file_data(rli->stream_id, rli->lindex,
719 rli->off, rli->size);
766 rli->off, rli->size);
720767
721768 return 0;
722769 }
732779 int
733780 xfuse_add_clip_dir_item(const char *filename, int flags, int size, int lindex)
734781 {
735 log_debug("entered: filename=%s flags=%d size=%d lindex=%d",
782 LOG_DEVEL(LOG_LEVEL_DEBUG,
783 "entered: filename=%s flags=%d size=%d lindex=%d",
736784 filename, flags, size, lindex);
737785
738 /* add entry to xrdp_fs */
739 XFS_INODE *xinode = xfs_add_entry( g_xfs,
740 g_clipboard_inum, /* parent inode */
741 filename,
742 (0666 | S_IFREG));
743 if (xinode == NULL)
744 {
745 log_debug("failed to create file in xrdp filesystem");
746 return -1;
747 }
748 xinode->size = size;
749 xinode->lindex = lindex;
750
751 return 0;
786 int result = -1;
787
788 if (g_xfs == NULL)
789 {
790 LOG_DEVEL(LOG_LEVEL_ERROR,
791 "xfuse_add_clip_dir_item() called with no filesystem")
792 }
793 else
794 {
795 /* add entry to xrdp_fs */
796 XFS_INODE *xinode = xfs_add_entry( g_xfs,
797 g_clipboard_inum, /* parent inode */
798 filename,
799 (0666 | S_IFREG));
800 if (xinode == NULL)
801 {
802 LOG(LOG_LEVEL_INFO,
803 "failed to create file %s in xrdp filesystem", filename);
804 }
805 else
806 {
807 xinode->size = size;
808 xinode->lindex = lindex;
809 result = 0;
810 }
811 }
812
813 return result;
752814 }
753815
754816 /**
759821
760822 int xfuse_file_contents_size(int stream_id, int file_size)
761823 {
762 log_debug("entered: stream_id=%d file_size=%d", stream_id, file_size);
824 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: stream_id=%d file_size=%d", stream_id, file_size);
763825 return 0;
764826 }
765827
779841 {
780842 if (fuse_parse_cmdline(args, &g_mount_point, 0, 0) < 0)
781843 {
782 log_error("fuse_parse_cmdline() failed");
844 LOG_DEVEL(LOG_LEVEL_ERROR, "fuse_parse_cmdline() failed");
783845 fuse_opt_free_args(args);
784846 return -1;
785847 }
786848
787849 if ((g_ch = fuse_mount(g_mount_point, args)) == 0)
788850 {
789 log_error("fuse_mount() failed");
851 LOG_DEVEL(LOG_LEVEL_ERROR, "fuse_mount() failed");
790852 fuse_opt_free_args(args);
791853 return -1;
792854 }
794856 g_se = fuse_lowlevel_new(args, &g_xfuse_ops, sizeof(g_xfuse_ops), 0);
795857 if (g_se == 0)
796858 {
797 log_error("fuse_lowlevel_new() failed");
859 LOG_DEVEL(LOG_LEVEL_ERROR, "fuse_lowlevel_new() failed");
798860 fuse_unmount(g_mount_point, g_ch);
799861 g_ch = 0;
800862 fuse_opt_free_args(args);
833895 }
834896 else if ((g_xfs = xfs_create_xfs_fs(0, g_getuid(), g_getgid())) == NULL)
835897 {
836 log_error("system out of memory");
898 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
837899 }
838900 else
839901 {
842904 (0777 | S_IFDIR));
843905 if (xino == NULL)
844906 {
845 log_error("system out of memory");
907 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
846908 xfs_delete_xfs_fs(g_xfs);
847909 g_xfs = NULL;
848910 }
850912 {
851913 g_clipboard_inum = xino->inum;
852914 result = 0;
853 }
915 }
854916 }
855917 return result;
856918 }
885947 *****************************************************************************/
886948
887949 void xfuse_devredir_cb_enum_dir_add_entry(
888 struct state_dirscan *fip,
889 const char *name,
890 const struct file_attr *fattr)
950 struct state_dirscan *fip,
951 const char *name,
952 const struct file_attr *fattr)
891953 {
892954 XFS_INODE *xinode = NULL;
893955
894956 if (!xfs_get(g_xfs, fip->pinum))
895957 {
896 log_error("inode %ld is not valid", fip->pinum);
958 LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is not valid", fip->pinum);
897959 }
898960 else if ((strcmp(name, ".") == 0) ||
899961 (strcmp(name, "..") == 0))
902964 }
903965 else
904966 {
905 log_debug("parent_inode=%ld name=%s", fip->pinum, name);
967 LOG_DEVEL(LOG_LEVEL_DEBUG, "parent_inode=%ld name=%s", fip->pinum, name);
906968
907969 /* Does the file already exist ? If it does it's important we
908970 * don't mess with it, as we're only enumerating the directory, and
912974 if (xinode == NULL)
913975 {
914976 /* Add a new node to the file system */
915 log_debug("Creating name=%s in parent=%ld in xrdp_fs",
977 LOG_DEVEL(LOG_LEVEL_DEBUG, "Creating name=%s in parent=%ld in xrdp_fs",
916978 name, fip->pinum);
917979 xinode = xfs_add_entry(g_xfs, fip->pinum, name, fattr->mode);
918980 if (xinode == NULL)
919981 {
920 log_error("xfs_add_entry() failed");
982 LOG_DEVEL(LOG_LEVEL_ERROR, "xfs_add_entry() failed");
921983 }
922984 else
923985 {
9421004 void xfuse_devredir_cb_enum_dir_done(struct state_dirscan *fip,
9431005 enum NTSTATUS IoStatus)
9441006 {
945 log_debug("fip=%p IoStatus=0x%x", fip, IoStatus);
1007 LOG_DEVEL(LOG_LEVEL_DEBUG, "fip=%p IoStatus=0x%x", fip, IoStatus);
9461008
9471009 /*
948 * NT_STATUS_NO_SUCH_FILE is returned for empty directories
1010 * STATUS_NO_SUCH_FILE is returned for empty directories
9491011 */
950 if (IoStatus != NT_STATUS_SUCCESS && IoStatus != NT_STATUS_NO_SUCH_FILE)
1012 if (IoStatus != STATUS_SUCCESS && IoStatus != STATUS_NO_SUCH_FILE)
9511013 {
9521014 int status;
9531015 switch (IoStatus)
9541016 {
955 case NT_STATUS_ACCESS_DENIED:
1017 case STATUS_ACCESS_DENIED:
9561018 status = EACCES;
9571019 break;
9581020 default:
9621024 }
9631025 else if (!xfs_get(g_xfs, fip->pinum))
9641026 {
965 log_error("inode %ld is not valid", fip->pinum);
1027 LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is not valid", fip->pinum);
9661028 fuse_reply_err(fip->req, ENOENT);
9671029 }
9681030 else
9691031 {
9701032 struct fuse_file_info *fi = &fip->fi;
971
972 if ((fi->fh = (tintptr) xfs_opendir(g_xfs, fip->pinum)) == 0)
973 {
1033 XFUSE_HANDLE *xhandle = xfuse_handle_create();
1034
1035 if (xhandle == NULL
1036 || (xhandle->dir_handle = xfs_opendir(g_xfs, fip->pinum)) == NULL)
1037 {
1038 xfuse_handle_delete(xhandle);
9741039 fuse_reply_err(fip->req, ENOMEM);
9751040 }
9761041 else
9771042 {
1043 fi->fh = xfuse_handle_to_fuse_handle(xhandle);
9781044 fuse_reply_open(fip->req, &fip->fi);
9791045 }
9801046 }
9831049 }
9841050
9851051 /**
986 * This routine is caused as a result of a devredir remote lookup
1052 * This routine is caused as a result of a devredir remote lookup
9871053 * instigated by xfuse_cb_lookup()
9881054 *****************************************************************************/
9891055
9931059 {
9941060 XFS_INODE *xinode = NULL;
9951061
996 if (IoStatus != NT_STATUS_SUCCESS)
1062 if (IoStatus != STATUS_SUCCESS)
9971063 {
9981064 switch (IoStatus)
9991065 {
1000 case NT_STATUS_SHARING_VIOLATION:
1001 /* This can happen when trying to read the attributes of
1002 * some system files (e.g. pagefile.sys) */
1003 case NT_STATUS_ACCESS_DENIED:
1066 case STATUS_SHARING_VIOLATION:
1067 /* This can happen when trying to read the attributes of
1068 * some system files (e.g. pagefile.sys) */
1069 case STATUS_ACCESS_DENIED:
10041070 fuse_reply_err(fip->req, EACCES);
10051071 break;
10061072
1007 case NT_STATUS_UNSUCCESSFUL:
1073 case STATUS_UNSUCCESSFUL:
10081074 /* Happens if we try to lookup an illegal filename (e.g.
10091075 * one with a '*' in it) */
10101076 fuse_reply_err(fip->req, ENOENT);
10111077 break;
10121078
1013 case NT_STATUS_NO_SUCH_FILE:
1079 case STATUS_NO_SUCH_FILE:
10141080 /* Remove our copy, if any */
1015 if (fip->existing_inum &&
1016 (xinode = xfs_get(g_xfs, fip->existing_inum)) != NULL &&
1017 xinode->generation == fip->existing_generation)
1018 {
1081 if (fip->existing_inum &&
1082 (xinode = xfs_get(g_xfs, fip->existing_inum)) != NULL &&
1083 xinode->generation == fip->existing_generation)
1084 {
10191085 xfs_remove_entry(g_xfs, fip->existing_inum);
10201086 }
10211087 fuse_reply_err(fip->req, ENOENT);
10221088 break;
10231089
10241090 default:
1025 log_info("Error code %08x - fallthrough", (int) IoStatus);
1091 LOG_DEVEL(LOG_LEVEL_INFO, "Error code %08x - fallthrough", (int) IoStatus);
10261092 fuse_reply_err(fip->req, EIO);
10271093 break;
10281094 }
10291095 }
10301096 else if (!xfs_get(g_xfs, fip->pinum))
10311097 {
1032 log_error("parent inode %ld is not valid", fip->pinum);
1098 LOG_DEVEL(LOG_LEVEL_ERROR, "parent inode %ld is not valid", fip->pinum);
10331099 fuse_reply_err(fip->req, ENOENT);
10341100 }
10351101 else
10361102 {
1037 log_debug("parent_inode=%ld name=%s", fip->pinum, fip->name);
1103 LOG_DEVEL(LOG_LEVEL_DEBUG, "parent_inode=%ld name=%s", fip->pinum, fip->name);
10381104
10391105 /* Does the file already exist ? */
10401106 xinode = xfs_lookup_in_dir(g_xfs, fip->pinum, fip->name);
10421108 {
10431109 /* Is the existing file the same type ? */
10441110 if ((xinode->mode & (S_IFREG | S_IFDIR)) ==
1045 (file_info->mode & (S_IFREG | S_IFDIR)))
1111 (file_info->mode & (S_IFREG | S_IFDIR)))
10461112 {
1047 log_debug("inode=%ld name=%s already exists in xrdp_fs as %ld",
1113 LOG_DEVEL(LOG_LEVEL_DEBUG, "inode=%ld name=%s already exists in xrdp_fs as %ld",
10481114 fip->pinum, fip->name, xinode->inum);
10491115 if (xfs_get_file_open_count(g_xfs, xinode->inum) > 0)
10501116 {
10541120 * would be truncating a file we're currently writing
10551121 * to, as the lookup value for the size is stale.
10561122 */
1057 log_debug("inode=%ld is open - "
1123 LOG_DEVEL(LOG_LEVEL_DEBUG, "inode=%ld is open - "
10581124 "preferring local attributes", xinode->inum);
10591125 }
10601126 else
10611127 {
1062 log_debug("Updating attributes of inode=%ld", xinode->inum);
1128 LOG_DEVEL(LOG_LEVEL_DEBUG, "Updating attributes of inode=%ld", xinode->inum);
10631129 update_inode_file_attributes(file_info, TO_SET_ALL, xinode);
10641130 }
10651131 }
10661132 else
10671133 {
10681134 /* Type has changed from file to directory, or vice-versa */
1069 log_debug("inode=%ld name=%s of different type in xrdp_fs"
1135 LOG_DEVEL(LOG_LEVEL_DEBUG, "inode=%ld name=%s of different type in xrdp_fs"
10701136 " - removing",
10711137 fip->pinum, xinode->name);
10721138 xfs_remove_entry(g_xfs, xinode->inum);
10771143 if (xinode == NULL)
10781144 {
10791145 /* Add a new node to the file system */
1080 log_debug("Creating name=%s in parent=%ld in xrdp_fs",
1146 LOG_DEVEL(LOG_LEVEL_DEBUG, "Creating name=%s in parent=%ld in xrdp_fs",
10811147 fip->name, fip->pinum);
10821148 xinode = xfs_add_entry(g_xfs, fip->pinum, fip->name,
10831149 file_info->mode);
10841150 if (xinode == NULL)
10851151 {
1086 log_debug("xfs_add_entry() failed");
1152 LOG_DEVEL(LOG_LEVEL_DEBUG, "xfs_add_entry() failed");
10871153 }
10881154 else
10891155 {
11181184 {
11191185 XFS_INODE *xinode;
11201186
1121 if (IoStatus != NT_STATUS_SUCCESS)
1187 if (IoStatus != STATUS_SUCCESS)
11221188 {
11231189 switch (IoStatus)
11241190 {
1125 case NT_STATUS_SHARING_VIOLATION:
1126 /* This can happen when trying to read the attributes of
1127 * some system files (e.g. pagefile.sys) */
1128 case NT_STATUS_ACCESS_DENIED:
1191 case STATUS_SHARING_VIOLATION:
1192 /* This can happen when trying to read the attributes of
1193 * some system files (e.g. pagefile.sys) */
1194 case STATUS_ACCESS_DENIED:
11291195 fuse_reply_err(fip->req, EACCES);
11301196 break;
11311197
1132 case NT_STATUS_UNSUCCESSFUL:
1133 /* Happens if we try to lookup an illegal filename */
1134 case NT_STATUS_NO_SUCH_FILE:
1198 case STATUS_UNSUCCESSFUL:
1199 /* Happens if we try to lookup an illegal filename */
1200 case STATUS_NO_SUCH_FILE:
11351201 fuse_reply_err(fip->req, ENOENT);
11361202 break;
11371203
11381204 default:
1139 log_info("Error code %08x - fallthrough", (int) IoStatus);
1205 LOG_DEVEL(LOG_LEVEL_INFO, "Error code %08x - fallthrough", (int) IoStatus);
11401206 fuse_reply_err(fip->req, EIO);
11411207 break;
11421208 }
11661232 {
11671233 switch (IoStatus)
11681234 {
1169 case NT_STATUS_ACCESS_DENIED:
1170 fuse_reply_err(fip->req, EACCES);
1171 break;
1172
1173 case NT_STATUS_OBJECT_NAME_INVALID:
1174 case NT_STATUS_OBJECT_NAME_NOT_FOUND:
1175 fuse_reply_err(fip->req, ENOENT);
1176 break;
1177
1178 default:
1179 fuse_reply_err(fip->req, EIO);
1180 break;
1235 case STATUS_ACCESS_DENIED:
1236 fuse_reply_err(fip->req, EACCES);
1237 break;
1238
1239 case STATUS_OBJECT_NAME_INVALID:
1240 case STATUS_OBJECT_NAME_NOT_FOUND:
1241 fuse_reply_err(fip->req, ENOENT);
1242 break;
1243
1244 default:
1245 fuse_reply_err(fip->req, EIO);
1246 break;
11811247 }
11821248 }
11831249 else
11861252 {
11871253 /* We've created a regular file */
11881254 /* Allocate an XFUSE_HANDLE for future file operations */
1189 if ((fh = g_new0(XFUSE_HANDLE, 1)) != NULL)
1255 if ((fh = xfuse_handle_create()) != NULL)
11901256 {
11911257 /* save file handle for later use */
11921258 fh->DeviceId = DeviceId;
11931259 fh->FileId = FileId;
11941260
1195 fip->fi.fh = (tintptr) fh;
1261 fip->fi.fh = xfuse_handle_to_fuse_handle(fh);
11961262 }
11971263 }
11981264
11991265 if ((fip->mode & S_IFREG) != 0 && fh == NULL)
12001266 {
12011267 /* We failed to allocate a file handle */
1202 log_error("system out of memory");
1268 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
12031269 fuse_reply_err(fip->req, ENOMEM);
12041270 }
12051271 else
12301296
12311297 if (xinode == NULL)
12321298 {
1233 log_error("Out of memory!");
1299 LOG_DEVEL(LOG_LEVEL_ERROR, "Out of memory!");
12341300 fuse_reply_err(fip->req, ENOMEM);
12351301 }
12361302 else
12491315 }
12501316 }
12511317 }
1318
12521319 }
12531320
12541321 free(fip);
12671334 {
12681335 switch (IoStatus)
12691336 {
1270 case NT_STATUS_ACCESS_DENIED:
1271 fuse_reply_err(fip->req, EACCES);
1272 break;
1273
1274 case NT_STATUS_OBJECT_NAME_INVALID:
1275 case NT_STATUS_OBJECT_NAME_NOT_FOUND:
1276 fuse_reply_err(fip->req, ENOENT);
1277 break;
1278
1279 default:
1280 fuse_reply_err(fip->req, EIO);
1281 break;
1337 case STATUS_ACCESS_DENIED:
1338 fuse_reply_err(fip->req, EACCES);
1339 break;
1340
1341 case STATUS_OBJECT_NAME_INVALID:
1342 case STATUS_OBJECT_NAME_NOT_FOUND:
1343 fuse_reply_err(fip->req, ENOENT);
1344 break;
1345
1346 default:
1347 fuse_reply_err(fip->req, EIO);
1348 break;
12821349 }
12831350 }
12841351 else
12851352 {
12861353 /* Allocate an XFUSE_HANDLE for future file operations */
1287 if ((fh = g_new0(XFUSE_HANDLE, 1)) == NULL)
1288 {
1289 log_error("system out of memory");
1354 if ((fh = xfuse_handle_create()) == NULL)
1355 {
1356 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
12901357 fuse_reply_err(fip->req, ENOMEM);
12911358 }
12921359 else
12951362 fh->DeviceId = DeviceId;
12961363 fh->FileId = FileId;
12971364
1298 fip->fi.fh = (tintptr) fh;
1299
1300 log_debug("sending fuse_reply_open(); "
1365 fip->fi.fh = xfuse_handle_to_fuse_handle(fh);
1366
1367 LOG_DEVEL(LOG_LEVEL_DEBUG, "sending fuse_reply_open(); "
13011368 "DeviceId=%d FileId=%d req=%p",
13021369 fh->DeviceId, fh->FileId, fip->req);
13031370
13121379 }
13131380
13141381 void xfuse_devredir_cb_read_file(struct state_read *fip,
1382 enum NTSTATUS IoStatus,
13151383 const char *buf, size_t length)
13161384 {
1317 fuse_reply_buf(fip->req, buf, length);
1385 if (IoStatus != STATUS_SUCCESS)
1386 {
1387 LOG_DEVEL(LOG_LEVEL_ERROR, "Read NTSTATUS is %d", (int) IoStatus);
1388 fuse_reply_err(fip->req, EIO);
1389 }
1390 else
1391 {
1392 fuse_reply_buf(fip->req, buf, length);
1393 }
13181394 free(fip);
13191395 }
13201396
13211397 void xfuse_devredir_cb_write_file(
1322 struct state_write *fip,
1323 enum NTSTATUS IoStatus,
1324 off_t offset,
1325 size_t length)
1398 struct state_write *fip,
1399 enum NTSTATUS IoStatus,
1400 off_t offset,
1401 size_t length)
13261402 {
13271403 XFS_INODE *xinode;
13281404
1329 if (IoStatus != NT_STATUS_SUCCESS)
1330 {
1331 log_error("Write NTSTATUS is %d", (int) IoStatus);
1405 if (IoStatus != STATUS_SUCCESS)
1406 {
1407 LOG_DEVEL(LOG_LEVEL_ERROR, "Write NTSTATUS is %d", (int) IoStatus);
13321408 fuse_reply_err(fip->req, EIO);
13331409 }
13341410 else
13461422 }
13471423 else
13481424 {
1349 log_error("inode %ld is invalid", fip->inum);
1425 LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is invalid", fip->inum);
13501426 }
13511427 }
13521428
13601436
13611437 switch (IoStatus)
13621438 {
1363 case NT_STATUS_SUCCESS:
1364 case NT_STATUS_NO_SUCH_FILE:
1439 case STATUS_SUCCESS:
1440 case STATUS_NO_SUCH_FILE:
13651441 xfs_remove_entry(g_xfs, xinode->inum); /* Remove local copy */
13661442 fuse_reply_err(fip->req, 0);
13671443 break;
13681444
1369 case NT_STATUS_SHARING_VIOLATION:
1370 case NT_STATUS_ACCESS_DENIED:
1445 case STATUS_SHARING_VIOLATION:
1446 case STATUS_ACCESS_DENIED:
13711447 fuse_reply_err(fip->req, EACCES);
13721448 break;
13731449
13741450 default:
1375 log_info("Error code %08x - fallthrough", (int) IoStatus);
1451 LOG_DEVEL(LOG_LEVEL_INFO, "Error code %08x - fallthrough", (int) IoStatus);
13761452 fuse_reply_err(fip->req, EBADF);
13771453 break;
13781454 }
13841460 {
13851461 int status;
13861462
1387 if (IoStatus != NT_STATUS_SUCCESS)
1463 if (IoStatus != STATUS_SUCCESS)
13881464 {
13891465 status =
1390 (IoStatus == NT_STATUS_SHARING_VIOLATION) ? EBUSY :
1391 (IoStatus == NT_STATUS_ACCESS_DENIED) ? EACCES :
1392 /* default */ EEXIST ;
1466 (IoStatus == STATUS_SHARING_VIOLATION) ? EBUSY :
1467 (IoStatus == STATUS_ACCESS_DENIED) ? EACCES :
1468 /* default */ EEXIST ;
13931469 }
13941470 else
13951471 {
14241500 XFS_INODE *parent_xinode;
14251501 XFS_INODE *xinode = NULL;
14261502
1427 log_debug("looking for parent=%ld name=%s", parent, name);
1503 LOG_DEVEL(LOG_LEVEL_DEBUG, "looking for parent=%ld name=%s", parent, name);
14281504
14291505 if (strlen(name) > XFS_MAXFILENAMELEN)
14301506 {
14321508 }
14331509 else if ((parent_xinode = xfs_get(g_xfs, parent)) == NULL)
14341510 {
1435 log_error("inode %ld is not valid", parent);
1511 LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is not valid", parent);
14361512 fuse_reply_err(req, ENOENT);
14371513 }
14381514 else
14391515 {
1440 if (parent_xinode->device_id == 0)
1516 if (!parent_xinode->is_redirected)
14411517 {
14421518 /* File cannot be remote - we either know about it or we don't */
14431519 if ((xinode = xfs_lookup_in_dir(g_xfs, parent, name)) != NULL)
14441520 {
1445 log_debug("found entry for parent=%ld name=%s",
1521 LOG_DEVEL(LOG_LEVEL_DEBUG, "found entry for parent=%ld name=%s",
14461522 parent, name);
14471523 make_fuse_entry_reply(req, xinode);
14481524 }
14621538
14631539 if (fip == NULL || full_path == NULL)
14641540 {
1465 log_error("system out of memory");
1541 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
14661542 fuse_reply_err(req, ENOMEM);
14671543 free(fip);
14681544 free(full_path);
14871563 fip->existing_inum = xinode->inum;
14881564 fip->existing_generation = xinode->generation;
14891565 }
1490 log_debug("Looking up %s in %s on %d", name, cptr,
1491 parent_xinode->device_id);
1566 LOG_DEVEL(LOG_LEVEL_DEBUG, "Looking up %s in %s on %d", name, cptr,
1567 parent_xinode->device_id);
14921568 /*
14931569 * If this call succeeds, further request processing happens in
14941570 * xfuse_devredir_cb_lookup_entry()
14951571 */
14961572 if (devredir_lookup_entry(fip, parent_xinode->device_id, cptr))
14971573 {
1498 log_error("failed to send devredir_lookup_entry() cmd");
1574 LOG_DEVEL(LOG_LEVEL_ERROR, "failed to send devredir_lookup_entry() cmd");
14991575 fuse_reply_err(req, EREMOTEIO);
15001576 free(fip);
15011577 }
15131589 *****************************************************************************/
15141590
15151591 static void xfuse_cb_getattr(fuse_req_t req, fuse_ino_t ino,
1516 struct fuse_file_info *fi)
1592 struct fuse_file_info *fi)
15171593 {
15181594 XFS_INODE *xino;
15191595
1520 log_debug("req=%p ino=%ld", req, ino);
1596 LOG_DEVEL(LOG_LEVEL_DEBUG, "req=%p ino=%ld", req, ino);
15211597
15221598 /* if ino is not valid, just return */
15231599 if ((xino = xfs_get(g_xfs, ino)) == NULL)
15241600 {
1525 log_error("inode %ld is not valid", ino);
1601 LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is not valid", ino);
15261602 fuse_reply_err(req, ENOENT);
15271603 }
15281604 else
15491625
15501626 memset(&stbuf, 0, sizeof(stbuf));
15511627 stbuf.st_ino = xinode->inum;
1552 stbuf.st_mode = xinode->mode & ~g_umask;
1628 stbuf.st_mode = xinode->mode & ~g_cfg->file_umask;
15531629
15541630 /*
15551631 * Try to add the entry. From the docs for fuse_add_direntry():-
15581634 * still returned."
15591635 */
15601636 len = fuse_add_direntry(req,
1561 &b->buf[b->len], /* index where new entry will be added to buf */
1562 sizeof(b->buf) - b->len, /* Space left */
1563 xinode->name, /* name of entry */
1564 &stbuf, /* file attributes */
1565 offset /* offset of next entry */
1566 );
1637 &b->buf[b->len], /* index where new entry will be added to buf */
1638 sizeof(b->buf) - b->len, /* Space left */
1639 xinode->name, /* name of entry */
1640 &stbuf, /* file attributes */
1641 offset /* offset of next entry */
1642 );
15671643 if (len + b->len <= sizeof(b->buf))
15681644 {
15691645 /* Entry fitted in OK */
15841660 off_t off, struct fuse_file_info *fi)
15851661 {
15861662 XFS_INODE *xinode;
1663 XFUSE_HANDLE *xhandle;
15871664 struct xfs_dir_handle *dh;
15881665 struct dirbuf1 b;
15891666
1590 log_debug("req=%p inode=%ld size=%zd offset=%lld", req, ino, size, (long long) off);
1667 LOG_DEVEL(LOG_LEVEL_DEBUG, "req=%p inode=%ld size=%zd offset=%lld", req, ino, size, (long long) off);
15911668
15921669 /* On the first call, check the inode is valid */
15931670 if (off == 0 && !xfs_get(g_xfs, ino))
15941671 {
1595 log_error("inode %ld is not valid", ino);
1672 LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is not valid", ino);
15961673 fuse_reply_err(req, ENOENT);
15971674 }
1598 else if ((dh = (struct xfs_dir_handle *) fi->fh) == NULL)
1675 else if ((xhandle = xfuse_handle_from_fuse_handle(fi->fh)) == NULL
1676 || (dh = xhandle->dir_handle) == NULL)
15991677 {
16001678 /* something seriously wrong somewhere! */
16011679 fuse_reply_buf(req, 0, 0);
16291707 {
16301708 XFS_INODE *xinode;
16311709
1632 log_debug("entered: parent_inode=%ld name=%s", parent, name);
1710 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: parent_inode=%ld name=%s", parent, name);
16331711
16341712 if ((xinode = xfs_lookup_in_dir(g_xfs, parent, name)) != NULL)
16351713 {
16531731 {
16541732 XFS_INODE *xinode;
16551733
1656 log_debug("entered: parent=%ld name=%s", parent, name);
1734 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: parent=%ld name=%s", parent, name);
16571735
16581736 if (strlen(name) > XFS_MAXFILENAMELEN)
16591737 {
16611739 }
16621740 else if ((xinode = xfs_lookup_in_dir(g_xfs, parent, name)) == NULL)
16631741 {
1664 log_error("did not find file with pinode=%ld name=%s", parent, name);
1742 LOG_DEVEL(LOG_LEVEL_ERROR, "did not find file with pinode=%ld name=%s", parent, name);
16651743 fuse_reply_err(req, ENOENT);
16661744 }
16671745
16681746 else if ((xinode->mode & S_IFDIR) != 0 &&
16691747 !xfs_is_dir_empty(g_xfs, xinode->inum))
16701748 {
1671 log_debug("cannot rmdir; directory is not empty");
1749 LOG_DEVEL(LOG_LEVEL_DEBUG, "cannot rmdir; directory is not empty");
16721750 fuse_reply_err(req, ENOTEMPTY);
16731751 }
16741752
1675 else if (xinode->device_id == 0)
1753 else if (!xinode->is_redirected)
16761754 {
16771755 /* specified file is a local resource */
16781756 //XFUSE_HANDLE *fh;
16791757
1680 log_debug("LK_TODO: this is still a TODO");
1681 fuse_reply_err(req, EINVAL);
1758 LOG_DEVEL(LOG_LEVEL_DEBUG, "LK_TODO: this is still a TODO");
1759 fuse_reply_err(req, EROFS);
16821760 }
16831761 else
16841762 {
16871765 char *full_path = xfs_get_full_path(g_xfs, xinode->inum);
16881766 if (!full_path || !fip)
16891767 {
1690 log_error("system out of memory");
1768 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
16911769 fuse_reply_err(req, ENOMEM);
16921770 free(fip);
1693 free(full_path);
16941771 }
16951772 else
16961773 {
17091786 */
17101787 if (devredir_rmdir_or_file(fip, xinode->device_id, cptr))
17111788 {
1712 log_error("failed to send devredir_rmdir_or_file() cmd");
1789 LOG_DEVEL(LOG_LEVEL_ERROR, "failed to send devredir_rmdir_or_file() cmd");
17131790 fuse_reply_err(req, EREMOTEIO);
17141791 free(fip);
17151792 }
17261803 XFS_INODE *old_xinode;
17271804 XFS_INODE *new_parent_xinode;
17281805
1729 log_debug("entered: old_parent=%ld old_name=%s new_parent=%ld new_name=%s",
1806 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: old_parent=%ld old_name=%s new_parent=%ld new_name=%s",
17301807 old_parent, old_name, new_parent, new_name);
17311808
17321809 if (strlen(old_name) > XFS_MAXFILENAMELEN ||
1733 strlen(new_name) > XFS_MAXFILENAMELEN)
1810 strlen(new_name) > XFS_MAXFILENAMELEN)
17341811 {
17351812 fuse_reply_err(req, ENAMETOOLONG);
17361813 }
17371814 else if (!(old_xinode = xfs_lookup_in_dir(g_xfs, old_parent, old_name)))
17381815 {
1739 log_error("did not find file with pinode=%ld name=%s",
1816 LOG_DEVEL(LOG_LEVEL_ERROR, "did not find file with pinode=%ld name=%s",
17401817 old_parent, old_name);
17411818 fuse_reply_err(req, ENOENT);
17421819 }
17431820
17441821 else if (!(new_parent_xinode = xfs_get(g_xfs, new_parent)))
17451822 {
1746 log_error("inode %ld is not valid", new_parent);
1747 fuse_reply_err(req, EINVAL);
1823 LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is not valid", new_parent);
1824 fuse_reply_err(req, ENOENT);
17481825 }
17491826
17501827 else if (!xfs_check_move_entry(g_xfs, old_xinode->inum,
17511828 new_parent, new_name))
17521829 {
1830 /* Catchall -see rename(2). Fix when logging is improved */
17531831 fuse_reply_err(req, EINVAL);
17541832 }
17551833
1756 else if (new_parent_xinode->device_id != old_xinode->device_id)
1757 {
1758 log_error("rename across file systems not supported");
1759 fuse_reply_err(req, EINVAL);
1760 }
1761
1762 else if (old_xinode->device_id == 0)
1834 else if (new_parent_xinode->is_redirected != old_xinode->is_redirected ||
1835 new_parent_xinode->device_id != old_xinode->device_id)
1836 {
1837 fuse_reply_err(req, EXDEV);
1838 }
1839
1840 else if (!old_xinode->is_redirected)
17631841 {
17641842 /* specified file is a local resource */
1765 log_debug("LK_TODO: this is still a TODO");
1766 fuse_reply_err(req, EINVAL);
1843 LOG_DEVEL(LOG_LEVEL_DEBUG, "LK_TODO: this is still a TODO");
1844 fuse_reply_err(req, EROFS);
17671845 }
17681846
17691847 else
17721850 struct state_rename *fip = g_new0(struct state_rename, 1);
17731851 char *old_full_path = xfs_get_full_path(g_xfs, old_xinode->inum);
17741852 char *new_full_path = get_name_for_entry_in_parent(new_parent,
1775 new_name);
1853 new_name);
17761854
17771855 if (!old_full_path || !new_full_path || !fip)
17781856 {
1779 log_error("system out of memory");
1857 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
17801858 fuse_reply_err(req, ENOMEM);
17811859 free(fip);
17821860 free(old_full_path);
18021880 */
18031881 if (devredir_file_rename(fip, old_xinode->device_id, cptr, cp))
18041882 {
1805 log_error("failed to send devredir_file_rename() cmd");
1883 LOG_DEVEL(LOG_LEVEL_ERROR, "failed to send devredir_file_rename() cmd");
18061884 fuse_reply_err(req, EREMOTEIO);
18071885 free(fip);
18081886 }
18291907 {
18301908 XFS_INODE *xinode;
18311909
1832 log_debug("entered: parent_ino=%ld name=%s mode=%o type=%s",
1910 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: parent_ino=%ld name=%s mode=%o type=%s",
18331911 parent, name, mode, (mode & S_IFDIR) ? "dir" : "file");
18341912
18351913 /* name must be valid */
18531931 }
18541932
18551933 /* is parent inode valid? */
1856 if (parent == FUSE_ROOT_ID ||
1857 (xinode = xfs_get(g_xfs, parent)) == NULL ||
1858 (xinode->mode & S_IFDIR) == 0)
1859 {
1860 log_error("inode %ld is not valid", parent);
1934 if (parent == FUSE_ROOT_ID)
1935 {
1936 fuse_reply_err(req, EROFS);
1937 }
1938 else if ((xinode = xfs_get(g_xfs, parent)) == NULL)
1939 {
18611940 fuse_reply_err(req, ENOENT);
18621941 }
1863 else if (xinode->device_id == 0)
1942 else if ((xinode->mode & S_IFDIR) == 0)
1943 {
1944 fuse_reply_err(req, ENOTDIR);
1945 }
1946 else if (!xinode->is_redirected)
18641947 {
18651948 /* specified file is a local resource */
18661949 //XFUSE_HANDLE *fh;
18671950
1868 log_debug("LK_TODO: this is still a TODO");
1869 fuse_reply_err(req, EINVAL);
1951 LOG_DEVEL(LOG_LEVEL_DEBUG, "LK_TODO: this is still a TODO");
1952 fuse_reply_err(req, EROFS);
18701953 }
18711954 else
18721955 {
18751958
18761959 if (full_path == NULL || fip == NULL)
18771960 {
1878 log_error("Out of memory");
1961 LOG_DEVEL(LOG_LEVEL_ERROR, "Out of memory");
18791962 fuse_reply_err(req, ENOMEM);
18801963 free(fip);
18811964 free(full_path);
19021985 */
19031986 if (devredir_file_create(fip, xinode->device_id, cptr, mode))
19041987 {
1905 log_error("failed to send devredir_file_create() cmd");
1988 LOG_DEVEL(LOG_LEVEL_ERROR, "failed to send devredir_file_create() cmd");
19061989 fuse_reply_err(req, EREMOTEIO);
19071990 free(fip);
19081991 }
19252008 {
19262009 XFS_INODE *xinode;
19272010
1928 log_debug("entered: ino=%ld", ino);
2011 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: ino=%ld", ino);
19292012
19302013 if (!(xinode = xfs_get(g_xfs, ino)))
19312014 {
1932 log_error("inode %ld is not valid", ino);
2015 LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is not valid", ino);
19332016 fuse_reply_err(req, ENOENT);
19342017 }
19352018 else if (xinode->mode & S_IFDIR)
19362019 {
19372020 /* Can't open directories like this */
1938 log_debug("reading/writing a dir not allowed!");
2021 LOG_DEVEL(LOG_LEVEL_DEBUG, "reading/writing a dir not allowed!");
19392022 fuse_reply_err(req, EISDIR);
19402023 }
19412024 else if ((fi->flags & O_ACCMODE) != O_RDONLY &&
19422025 (fi->flags & O_ACCMODE) != O_WRONLY &&
19432026 (fi->flags & O_ACCMODE) != O_RDWR)
19442027 {
1945 log_debug("Invalid access mode specified");
2028 LOG_DEVEL(LOG_LEVEL_DEBUG, "Invalid access mode specified");
19462029 fuse_reply_err(req, EINVAL);
19472030 }
1948 else if (xinode->device_id == 0)
2031 else if (!xinode->is_redirected)
19492032 {
19502033 /* specified file is a local resource */
1951 XFUSE_HANDLE *fh = g_new0(XFUSE_HANDLE, 1);
1952 fh->is_loc_resource = 1;
1953 fi->fh = (tintptr) fh;
1954 fuse_reply_open(req, fi);
2034 if ((fi->flags & O_ACCMODE) != O_RDONLY)
2035 {
2036 fuse_reply_err(req, EROFS);
2037 }
2038 else
2039 {
2040 XFUSE_HANDLE *fh = xfuse_handle_create();
2041 fh->is_loc_resource = 1;
2042 fi->fh = xfuse_handle_to_fuse_handle(fh);
2043 fuse_reply_open(req, fi);
2044 }
19552045 }
19562046 else
19572047 {
19612051
19622052 if (!full_path || !fip)
19632053 {
1964 log_error("system out of memory");
1965 fuse_reply_err(req, ENOMEM);
1966 free(fip);
1967 free(full_path);
2054 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
2055 fuse_reply_err(req, ENOMEM);
2056 free(fip);
2057 free(full_path);
19682058 }
19692059 else
19702060 {
19882078 */
19892079 if (devredir_file_open(fip, xinode->device_id, cptr, fi->flags))
19902080 {
1991 log_error("failed to send devredir_file_open() cmd");
2081 LOG_DEVEL(LOG_LEVEL_ERROR, "failed to send devredir_file_open() cmd");
19922082 fuse_reply_err(req, EREMOTEIO);
19932083 free(fip);
19942084 }
20072097 {
20082098 XFS_INODE *xinode;
20092099
2010 XFUSE_HANDLE *handle = (XFUSE_HANDLE *) (tintptr) (fi->fh);
2011
2012 log_debug("entered: ino=%ld fi=%p fi->fh=0x%llx", ino, fi,
2100 XFUSE_HANDLE *handle = xfuse_handle_from_fuse_handle(fi->fh);
2101
2102 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: ino=%ld fi=%p fi->fh=0x%llx", ino, fi,
20132103 (long long) fi->fh);
20142104
20152105 if ((xinode = xfs_get(g_xfs, ino)) == NULL)
20162106 {
2017 log_error("inode %ld is not valid", ino);
2107 LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is not valid", ino);
20182108 fuse_reply_err(req, ENOENT);
20192109 }
2020 else if (xinode->device_id == 0)
2110 else if (!xinode->is_redirected)
20212111 {
20222112 /* specified file is a local resource */
20232113 fuse_reply_err(req, 0);
20292119 struct state_close *fip = g_new0(struct state_close, 1);
20302120 if (fip == NULL)
20312121 {
2032 log_error("system out of memory");
2122 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
20332123 fuse_reply_err(req, ENOMEM);
20342124 return;
20352125 }
20382128 fip->inum = ino;
20392129 fip->fi = *fi;
20402130
2041 fi->fh = 0;
2131 fi->fh = xfuse_handle_to_fuse_handle(NULL);
20422132
20432133 /*
20442134 * If this call succeeds, further request processing happens in
20462136 */
20472137 if (devredir_file_close(fip, xinode->device_id, handle->FileId))
20482138 {
2049 log_error("failed to send devredir_close_file() cmd");
2139 LOG_DEVEL(LOG_LEVEL_ERROR, "failed to send devredir_close_file() cmd");
20502140 fuse_reply_err(req, EREMOTEIO);
20512141 free(fip);
20522142 }
20532143
2054 free(handle);
2144 xfuse_handle_delete(handle);
20552145 }
20562146 }
20572147
20692159 XFS_INODE *xinode;
20702160 struct req_list_item *rli;
20712161
2072 log_debug("want_bytes %zd bytes at off %lld", size, (long long) off);
2073
2074 if ((fh = (XFUSE_HANDLE *)fi->fh) == NULL)
2162 LOG_DEVEL(LOG_LEVEL_DEBUG, "want_bytes %zd bytes at off %lld", size, (long long) off);
2163
2164 if ((fh = xfuse_handle_from_fuse_handle(fi->fh)) == NULL)
20752165 {
20762166 fuse_reply_err(req, EINVAL);
20772167 }
20792169 {
20802170 /* target file is in .clipboard dir */
20812171
2082 log_debug("target file is in .clipboard dir");
2172 LOG_DEVEL(LOG_LEVEL_DEBUG, "target file is in .clipboard dir");
20832173
20842174 if ((xinode = xfs_get(g_xfs, ino)) == NULL)
20852175 {
2086 log_error("ino does not exist in xrdp_fs");
2176 LOG_DEVEL(LOG_LEVEL_ERROR, "ino does not exist in xrdp_fs");
20872177 fuse_reply_buf(req, 0, 0);
20882178 return;
20892179 }
20992189
21002190 if (g_req_list->count == 1)
21012191 {
2102 log_debug("requesting clipboard file data lindex = %d off = %lld size = %zd",
2192 LOG_DEVEL(LOG_LEVEL_DEBUG, "requesting clipboard file data lindex = %d off = %lld size = %zd",
21032193 rli->lindex, (long long) off, size);
21042194
21052195 clipboard_request_file_data(rli->stream_id, rli->lindex,
21132203 fusep = g_new0(struct state_read, 1);
21142204 if (fusep == NULL)
21152205 {
2116 log_error("system out of memory");
2206 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
21172207 fuse_reply_err(req, ENOMEM);
21182208 }
21192209 else
21412231 XFUSE_HANDLE *fh;
21422232 struct state_write *fusep;
21432233
2144 log_debug("write %zd bytes at off %lld to inode=%ld",
2234 LOG_DEVEL(LOG_LEVEL_DEBUG, "write %zd bytes at off %lld to inode=%ld",
21452235 size, (long long) off, ino);
21462236
2147 if ((fh = (XFUSE_HANDLE *)fi->fh) == NULL)
2148 {
2149 log_error("file handle fi->fh is NULL");
2237 if ((fh = xfuse_handle_from_fuse_handle(fi->fh)) == NULL)
2238 {
2239 LOG_DEVEL(LOG_LEVEL_ERROR, "file handle fi->fh is NULL");
21502240 fuse_reply_err(req, EINVAL);
21512241 }
21522242 else if (fh->is_loc_resource)
21532243 {
21542244 /* target file is in .clipboard dir */
2155 log_debug("THIS IS STILL A TODO!");
2156 fuse_reply_err(req, EINVAL);
2245 LOG_DEVEL(LOG_LEVEL_DEBUG, "THIS IS STILL A TODO!");
2246 fuse_reply_err(req, EROFS);
21572247 }
21582248 else
21592249 {
21622252 fusep = g_new0(struct state_write, 1);
21632253 if (fusep == NULL)
21642254 {
2165 log_error("system out of memory");
2255 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
21662256 fuse_reply_err(req, ENOMEM);
21672257 }
21682258 else
21922282 const char *name, mode_t mode,
21932283 struct fuse_file_info *fi)
21942284 {
2195 log_debug("entered: parent_inode=%ld, name=%s fi=%p",
2285 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: parent_inode=%ld, name=%s fi=%p",
21962286 parent, name, fi);
21972287
2198 xfuse_create_dir_or_file(req, parent, name, mode & ~S_IFDIR , fi);
2288 xfuse_create_dir_or_file(req, parent, name, mode & ~S_IFDIR, fi);
21992289 }
22002290
22012291 /**
22052295 static void xfuse_cb_fsync(fuse_req_t req, fuse_ino_t ino, int datasync,
22062296 struct fuse_file_info *fi)
22072297 {
2208 log_debug("#################### entered: ino=%ld datasync=%d", ino, datasync);
2209 log_debug("function not required");
2298 LOG_DEVEL(LOG_LEVEL_DEBUG, "#################### entered: ino=%ld datasync=%d", ino, datasync);
2299 LOG_DEVEL(LOG_LEVEL_DEBUG, "function not required");
22102300 fuse_reply_err(req, EINVAL);
22112301 }
22122302 #endif
22292319 {
22302320 XFS_INODE *xinode;
22312321
2232 log_debug("entered to_set=0x%x", to_set);
2322 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered to_set=0x%x", to_set);
22332323
22342324 if ((xinode = xfs_get(g_xfs, ino)) == NULL)
22352325 {
2236 log_error("inode %ld is not valid", ino);
2326 LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is not valid", ino);
22372327 fuse_reply_err(req, ENOENT);
22382328 }
22392329 else if (((to_set & FUSE_SET_ATTR_UID) && attr->st_uid != xinode->uid) ||
22432333 fuse_reply_err(req, EPERM);
22442334 }
22452335 else if ((to_set & FUSE_SET_ATTR_MODE) &&
2246 (attr->st_mode & ~(0777 | S_IFDIR | S_IFREG)) != 0)
2336 (attr->st_mode & ~(0777 | S_IFDIR | S_IFREG)) != 0)
22472337 {
22482338 /* We only support standard mode bits and S_IFDIR / S_IFREG */
2249 log_error("Asking for invalid mode bits 0%o to be set", attr->st_mode);
2339 LOG_DEVEL(LOG_LEVEL_ERROR, "Asking for invalid mode bits 0%o to be set", attr->st_mode);
22502340 fuse_reply_err(req, EINVAL);
22512341 }
2252 else
2342 else
22532343 {
22542344 struct file_attr attrs = {0};
22552345 tui32 change_mask = 0;
22832373 /* No changes have been made */
22842374 make_fuse_attr_reply(req, xinode);
22852375 }
2286 else if (xinode->device_id == 0)
2376 else if (!xinode->is_redirected)
22872377 {
22882378 /* Update the local fs */
22892379 update_inode_file_attributes(&attrs, change_mask, xinode);
22952385 char *full_path = xfs_get_full_path(g_xfs, ino);
22962386 if (!full_path || !fip)
22972387 {
2298 log_error("system out of memory");
2388 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
22992389 fuse_reply_err(req, ENOMEM);
23002390 free(fip);
23012391 free(full_path);
23382428 * to reply to FUSE immediately
23392429 *****************************************************************************/
23402430 static void xfuse_cb_opendir(fuse_req_t req, fuse_ino_t ino,
2341 struct fuse_file_info *fi)
2431 struct fuse_file_info *fi)
23422432 {
23432433 XFS_INODE *xinode;
2344
2345 log_debug("inode=%ld", ino);
2434 XFUSE_HANDLE *xhandle;
2435
2436 LOG_DEVEL(LOG_LEVEL_DEBUG, "inode=%ld", ino);
23462437
23472438 if ((xinode = xfs_get(g_xfs, ino)) == NULL)
23482439 {
2349 log_error("inode %ld is not valid", ino);
2440 LOG_DEVEL(LOG_LEVEL_ERROR, "inode %ld is not valid", ino);
23502441 fuse_reply_err(req, ENOENT);
23512442 }
2352 else if (xinode->device_id == 0)
2353 {
2354 if ((fi->fh = (tintptr) xfs_opendir(g_xfs, ino)) == 0)
2443 else if (!xinode->is_redirected)
2444 {
2445 if ((xhandle = xfuse_handle_create()) == NULL)
23552446 {
23562447 fuse_reply_err(req, ENOMEM);
23572448 }
23582449 else
23592450 {
2360 fuse_reply_open(req, fi);
2451 if ((xhandle->dir_handle = xfs_opendir(g_xfs, ino)) == NULL)
2452 {
2453 xfuse_handle_delete(xhandle);
2454 fuse_reply_err(req, ENOMEM);
2455 }
2456 else
2457 {
2458 fi->fh = xfuse_handle_to_fuse_handle(xhandle);
2459 fuse_reply_open(req, fi);
2460 }
23612461 }
23622462 }
23632463 else
23642464 {
2365 log_debug("did not find entry; redirecting call to devredir");
2465 LOG_DEVEL(LOG_LEVEL_DEBUG, "did not find entry; redirecting call to devredir");
23662466 struct state_dirscan *fip = g_new0(struct state_dirscan, 1);
23672467 char *full_path = xfs_get_full_path(g_xfs, ino);
23682468
23752475 else
23762476 {
23772477 const char *cptr;
2378 log_debug("dev_id=%d ino=%ld full_path=%s",
2478 LOG_DEVEL(LOG_LEVEL_DEBUG, "dev_id=%d ino=%ld full_path=%s",
23792479 xinode->device_id, ino, full_path);
23802480
23812481 fip->req = req;
23942494 */
23952495 if (devredir_get_dir_listing(fip, xinode->device_id, cptr))
23962496 {
2397 log_error("failed to send devredir_get_dir_listing() cmd");
2497 LOG_DEVEL(LOG_LEVEL_ERROR, "failed to send devredir_get_dir_listing() cmd");
23982498 fuse_reply_buf(req, NULL, 0);
23992499 free(fip);
24002500 }
24122512 static void xfuse_cb_releasedir(fuse_req_t req, fuse_ino_t ino,
24132513 struct fuse_file_info *fi)
24142514 {
2415 struct xfs_dir_handle *dh = (struct xfs_dir_handle *) fi->fh;
2416 xfs_closedir(g_xfs, dh);
2515 XFUSE_HANDLE *xhandle = xfuse_handle_from_fuse_handle(fi->fh);
2516 xfs_closedir(g_xfs, xhandle->dir_handle);
2517 xhandle->dir_handle = NULL;
2518 xfuse_handle_delete(xhandle);
24172519 fuse_reply_err(req, 0);
24182520 }
24192521
24222524 *****************************************************************************/
24232525
24242526 static void xfs_inode_to_fuse_entry_param(const XFS_INODE *xinode,
2425 struct fuse_entry_param *e)
2527 struct fuse_entry_param *e)
24262528 {
24272529 memset(e, 0, sizeof(*e));
24282530 e->ino = xinode->inum;
24292531 e->attr_timeout = XFUSE_ATTR_TIMEOUT;
24302532 e->entry_timeout = XFUSE_ENTRY_TIMEOUT;
24312533 e->attr.st_ino = xinode->inum;
2432 e->attr.st_mode = xinode->mode & ~g_umask;
2534 e->attr.st_mode = xinode->mode & ~g_cfg->file_umask;
24332535 e->attr.st_nlink = 1;
24342536 e->attr.st_uid = xinode->uid;
24352537 e->attr.st_gid = xinode->gid;
24532555
24542556 memset(&st, 0, sizeof(st));
24552557 st.st_ino = xinode->inum;
2456 st.st_mode = xinode->mode & ~g_umask;
2558 st.st_mode = xinode->mode & ~g_cfg->file_umask;
24572559 st.st_nlink = 1;
24582560 st.st_uid = xinode->uid;
24592561 st.st_gid = xinode->gid;
24902592 * setattr devredir call
24912593 */
24922594 static void update_inode_file_attributes(const struct file_attr *fattr,
2493 tui32 change_mask, XFS_INODE *xinode)
2595 tui32 change_mask, XFS_INODE *xinode)
24942596 {
24952597 int updated = 0;
24962598
25332635
25342636 if ((result = xfs_get_full_path(g_xfs, parent)) != NULL)
25352637 {
2536 char * p = (char *) realloc(result,
2537 strlen(result) + 1 + strlen(name) + 1);
2638 char *p = (char *) realloc(result,
2639 strlen(result) + 1 + strlen(name) + 1);
25382640 if (p == NULL)
25392641 {
2642 /* See cppcheck trac #9292 and #9437 */
2643 /* cppcheck-suppress doubleFree symbolName=result */
25402644 free(result);
25412645 result = NULL;
25422646 }
25512655 return result;
25522656 }
25532657
2658 /*
2659 * Scans a user-provided string substituting %u/%U for UID/username
2660 */
2661 static unsigned int format_user_info(char *dest, unsigned int len,
2662 const char *format)
2663 {
2664 char uidstr[64];
2665 char username[64];
2666 const struct info_string_tag map[] =
2667 {
2668 {'u', uidstr},
2669 {'U', username},
2670 INFO_STRING_END_OF_LIST
2671 };
2672
2673 int uid = g_getuid();
2674 g_snprintf(uidstr, sizeof(uidstr), "%d", uid);
2675 if (g_getlogin(username, sizeof(username)) != 0)
2676 {
2677 /* Fall back to UID */
2678 g_strncpy(username, uidstr, sizeof(username) - 1);
2679 }
2680
2681 return g_format_info_string(dest, len, format, map);
2682 }
2683
25542684 #endif /* end else #ifndef XRDP_FUSE */
9797 tui32 DeviceId, tui32 FileId);
9898
9999 void xfuse_devredir_cb_read_file(struct state_read *fip,
100 enum NTSTATUS IoStatus,
100101 const char *buf, size_t length);
101102 void xfuse_devredir_cb_write_file(
102103 struct state_write *fip,
2626 #endif
2727
2828 #include "os_calls.h"
29 #include "log.h"
2930
3031 #include "chansrv_xfs.h"
3132
112113 tui32 generation;
113114 };
114115
115 /* module based logging */
116 #define LOG_ERROR 0
117 #define LOG_INFO 1
118 #define LOG_DEBUG 2
119 #ifndef LOG_LEVEL
120 #define LOG_LEVEL LOG_ERROR
121 #endif
122
123 #define log_error(_params...) \
124 { \
125 g_write("[%10.10u]: XFS %s: %d : ERROR: ", \
126 g_time3(), __func__, __LINE__); \
127 g_writeln (_params); \
128 }
129
130 #define log_always(_params...) \
131 { \
132 g_write("[%10.10u]: XFS %s: %d : ALWAYS: ", \
133 g_time3(), __func__, __LINE__); \
134 g_writeln (_params); \
135 }
136
137 #define log_info(_params...) \
138 { \
139 if (LOG_INFO <= LOG_LEVEL) \
140 { \
141 g_write("[%10.10u]: XFS %s: %d : ", \
142 g_time3(), __func__, __LINE__); \
143 g_writeln (_params); \
144 } \
145 }
146
147 #define log_debug(_params...) \
148 { \
149 if (LOG_DEBUG <= LOG_LEVEL) \
150 { \
151 g_write("[%10.10u]: XFS %s: %d : ", \
152 g_time3(), __func__, __LINE__); \
153 g_writeln (_params); \
154 } \
155 }
156116
157117 /* ------------------------------------------------------------------------ */
158118 static int
343303 xino1->pub.ctime = xino1->pub.atime;
344304 strcpy(xino1->pub.name, ".");
345305 xino1->pub.generation = xfs->generation;
306 xino1->pub.is_redirected = 0;
346307 xino1->pub.device_id = 0;
347308
348309 /*
364325 xino2->pub.ctime = xino2->pub.atime;
365326 strcpy(xino2->pub.name, ".delete-pending");
366327 xino2->pub.generation = xfs->generation;
328 xino2->pub.is_redirected = 0;
367329 xino2->pub.device_id = 0;
368330
369331 xino2->parent = NULL;
386348 void
387349 xfs_delete_xfs_fs(struct xfs_fs *xfs)
388350 {
389 if (xfs != NULL && xfs->inode_table != NULL)
351 if (xfs == NULL)
352 {
353 return;
354 }
355
356 if (xfs->inode_table != NULL)
390357 {
391358 size_t i;
392359 for (i = 0 ; i < xfs->inode_count; ++i)
442409 fuse_ino_t inum = xfs->free_list[--xfs->free_count];
443410 if (xfs->inode_table[inum] != NULL)
444411 {
445 log_error("Unexpected non-NULL value in inode table "
412 LOG_DEVEL(LOG_LEVEL_ERROR, "Unexpected non-NULL value in inode table "
446413 "entry %ld", inum);
447414 }
448415 xfs->inode_table[inum] = xino;
463430 xino->pub.ctime = xino->pub.atime;
464431 strcpy(xino->pub.name, name);
465432 xino->pub.generation = xfs->generation;
433 xino->pub.is_redirected = parent->pub.is_redirected;
466434 xino->pub.device_id = parent->pub.device_id;
467435 xino->pub.lindex = 0;
468436
559527 */
560528 size_t len = 0;
561529 XFS_INODE_ALL *p;
562 for (p = xino ; p->pub.inum != FUSE_ROOT_ID ; p = p->parent)
530 for (p = xino ; p && p->pub.inum != FUSE_ROOT_ID ; p = p->parent)
563531 {
564532 len += strlen(p->pub.name);
565533 ++len; /* Allow for '/' prefix */
572540 char *end = result + len;
573541 *end = '\0';
574542
575 for (p = xino ; p->pub.inum != FUSE_ROOT_ID ; p = p->parent)
543 for (p = xino ; p && p->pub.inum != FUSE_ROOT_ID ; p = p->parent)
576544 {
577545 len = strlen(p->pub.name);
578546 end -= (len + 1);
810778
811779 /* ------------------------------------------------------------------------ */
812780 void
813 xfs_delete_entries_with_device_id(struct xfs_fs *xfs, tui32 device_id)
781 xfs_delete_redirected_entries_with_device_id(struct xfs_fs *xfs,
782 tui32 device_id)
814783 {
815784 fuse_ino_t inum;
816785 XFS_INODE_ALL *xino;
817786
818 if (device_id != 0)
819 {
820 /* Using xfs_remove_entry() is convenient, but it recurses
821 * in to directories. To make sure all entries are removed, set the
822 * open_count of all affected files to 0 first
823 */
824 for (inum = FUSE_ROOT_ID; inum < xfs->inode_count; ++inum)
825 {
826 if ((xino = xfs->inode_table[inum]) != NULL &&
827 xino->pub.device_id == device_id &&
828 (xino->pub.mode & S_IFREG) != 0)
829 {
830 xino->open_count = 0;
831 }
832 }
833
834 /* Now we can be sure everything will be deleted correctly */
835 for (inum = FUSE_ROOT_ID; inum < xfs->inode_count; ++inum)
836 {
837 if ((xino = xfs->inode_table[inum]) != NULL &&
838 xino->pub.device_id == device_id)
839 {
840 xfs_remove_entry(xfs, xino->pub.inum);
841 }
787 /* Using xfs_remove_entry() is convenient, but it recurses
788 * in to directories. To make sure all entries are removed, set the
789 * open_count of all affected files to 0 first
790 */
791 for (inum = FUSE_ROOT_ID; inum < xfs->inode_count; ++inum)
792 {
793 if ((xino = xfs->inode_table[inum]) != NULL &&
794 xino->pub.is_redirected != 0 &&
795 xino->pub.device_id == device_id &&
796 (xino->pub.mode & S_IFREG) != 0)
797 {
798 xino->open_count = 0;
799 }
800 }
801
802 /* Now we can be sure everything will be deleted correctly */
803 for (inum = FUSE_ROOT_ID; inum < xfs->inode_count; ++inum)
804 {
805 if ((xino = xfs->inode_table[inum]) != NULL &&
806 xino->pub.is_redirected != 0 &&
807 xino->pub.device_id == device_id)
808 {
809 xfs_remove_entry(xfs, xino->pub.inum);
842810 }
843811 }
844812 }
4848 time_t ctime; /* Time of last status change. */
4949 char name[XFS_MAXFILENAMELEN + 1]; /* Short name */
5050 tui32 generation; /* Changes if inode is reused */
51 tui32 device_id; /* for file system redirection
52 * Non-redirected devices are guaranteed
53 * to have a device_id or zero */
51 char is_redirected; /* file is on redirected device */
52 tui32 device_id; /* device ID of redirected device */
5453 int lindex; /* used in clipboard operations */
5554 } XFS_INODE;
5655
270269 xfs_get_file_open_count(struct xfs_fs *xfs, fuse_ino_t inum);
271270
272271 /*
273 * Deletes all entries with the matching device id
272 * Deletes all redirected entries with the matching device id
274273 *
275274 * Files are deleted even if they are open
276275 *
277 * The specified device_id must be non-zero so that the root
278 * filesystem is not deleted!
279 *
280276 * @param device_id Device ID
281277 */
282278 void
283 xfs_delete_entries_with_device_id(struct xfs_fs *xfs, tui32 device_id);
279 xfs_delete_redirected_entries_with_device_id(struct xfs_fs *xfs,
280 tui32 device_id);
284281
285282 /*
286283 * Check an entry move will be successful
168168 #include "arch.h"
169169 #include "parse.h"
170170 #include "os_calls.h"
171 #include "string_calls.h"
171172 #include "chansrv.h"
173 #include "chansrv_config.h"
172174 #include "clipboard.h"
173175 #include "clipboard_file.h"
174176 #include "clipboard_common.h"
175177 #include "xcommon.h"
176178 #include "chansrv_fuse.h"
177179
178 /* module based logging */
179 #define LOG_ERROR 0
180 #define LOG_INFO 1
181 #define LOG_DEBUG 2
182
183 #undef LOG_LEVEL
184 #define LOG_LEVEL LOG_ERROR
185
186 #define log_error(_params...) \
187 { \
188 g_write("[%10.10u]: CLIPBOARD %s: %d : ERROR: ", \
189 g_time3(), __func__, __LINE__); \
190 g_writeln (_params); \
191 }
192
193 #define log_always(_params...) \
194 { \
195 g_write("[%10.10u]: CLIPBOARD %s: %d : ALWAYS: ", \
196 g_time3(), __func__, __LINE__); \
197 g_writeln (_params); \
198 }
199
200 #define log_info(_params...) \
201 { \
202 if (LOG_INFO <= LOG_LEVEL) \
203 { \
204 g_write("[%10.10u]: CLIPBOARD %s: %d : ", \
205 g_time3(), __func__, __LINE__); \
206 g_writeln (_params); \
207 } \
208 }
209
210 #define log_debug(_params...) \
211 { \
212 if (LOG_DEBUG <= LOG_LEVEL) \
213 { \
214 g_write("[%10.10u]: CLIPBOARD %s: %d : ", \
215 g_time3(), __func__, __LINE__); \
216 g_writeln (_params); \
217 } \
218 }
219180
220181 static char g_bmp_image_header[] =
221182 {
234195 extern Screen *g_screen; /* in xcommon.c */
235196 extern int g_screen_num; /* in xcommon.c */
236197
237 extern int g_restrict_outbound_clipboard; /* in chansrv.c */
198 extern struct config_chansrv *g_cfg; /* in chansrv.c */
238199
239200 int g_clip_up = 0;
240201
370331 int ver_min;
371332 Status st;
372333
373 LOG(0, ("clipboard_init:"));
334 LOG_DEVEL(LOG_LEVEL_INFO, "clipboard_init:");
374335
375336 if (g_clip_up)
376337 {
389350
390351 if (g_clipboard_atom == None)
391352 {
392 log_error("clipboard_init: XInternAtom failed");
353 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_init: XInternAtom failed");
393354 rv = 3;
394355 }
395356 }
398359 {
399360 if (!XFixesQueryExtension(g_display, &g_xfixes_event_base, &dummy))
400361 {
401 log_error("clipboard_init: no xfixes");
362 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_init: no xfixes");
402363 rv = 5;
403364 }
404365 }
405366
406367 if (rv == 0)
407368 {
408 log_debug("clipboard_init: g_xfixes_event_base %d",
369 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_init: g_xfixes_event_base %d",
409370 g_xfixes_event_base);
410371 st = XFixesQueryVersion(g_display, &ver_maj, &ver_min);
411 log_debug("clipboard_init st %d, maj %d min %d", st,
412 ver_maj, ver_min);
372 LOG(LOG_LEVEL_DEBUG, "clipboard_init st %d, maj %d min %d", st,
373 ver_maj, ver_min);
413374 g_clip_property_atom = XInternAtom(g_display, "XRDP_CLIP_PROPERTY_ATOM",
414375 False);
415376 g_get_time_atom = XInternAtom(g_display, "XRDP_GET_TIME_ATOM",
428389
429390 if (g_image_bmp_atom == None)
430391 {
431 log_error("clipboard_init: g_image_bmp_atom was "
392 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_init: g_image_bmp_atom was "
432393 "not allocated");
433394 }
434395
463424 out_uint32_le(s, 0); /* extra 4 bytes ? */
464425 s_mark_end(s);
465426 size = (int)(s->end - s->data);
466 log_debug("clipboard_init: data out, sending "
427 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_init: data out, sending "
467428 "CB_CLIP_CAPS (clip_msg_id = 1)");
468429 rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
469430 if (rv != 0)
470431 {
471 log_error("clipboard_init: send_channel_data failed "
432 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_init: send_channel_data failed "
472433 "rv = %d", rv);
473434 rv = 4;
474435 }
484445 out_uint32_le(s, 0); /* extra 4 bytes ? */
485446 s_mark_end(s);
486447 size = (int)(s->end - s->data);
487 log_debug("clipboard_init: data out, sending "
448 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_init: data out, sending "
488449 "CB_MONITOR_READY (clip_msg_id = 1)");
489450 rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
490451 if (rv != 0)
491452 {
492 log_error("clipboard_init: send_channel_data failed "
453 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_init: send_channel_data failed "
493454 "rv = %d", rv);
494455 rv = 4;
495456 }
504465 }
505466 else
506467 {
507 log_error("xrdp-chansrv: clipboard_init: error on exit");
468 LOG_DEVEL(LOG_LEVEL_ERROR, "xrdp-chansrv: clipboard_init: error on exit");
508469 }
509470
510471 return rv;
514475 int
515476 clipboard_deinit(void)
516477 {
517 LOG(0, ("clipboard_deinit:"));
478 LOG_DEVEL(LOG_LEVEL_INFO, "clipboard_deinit:");
518479 if (g_wnd != 0)
519480 {
520481 XDestroyWindow(g_display, g_wnd);
542503 int size;
543504 int rv;
544505
545 log_debug("clipboard_send_data_request:");
546 log_debug("clipboard_send_data_request: %d", format_id);
506 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_data_request:");
507 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_data_request: %d", format_id);
547508 g_clip_c2s.in_request = 1;
548509 make_stream(s);
549510 init_stream(s, 8192);
554515 out_uint32_le(s, 0);
555516 s_mark_end(s);
556517 size = (int)(s->end - s->data);
557 log_debug("clipboard_send_data_request: data out, sending "
518 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_data_request: data out, sending "
558519 "CLIPRDR_DATA_REQUEST (clip_msg_id = 4)");
559520 rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
560521 free_stream(s);
577538 out_uint32_le(s, 0); /* extra 4 bytes */
578539 s_mark_end(s);
579540 size = (int)(s->end - s->data);
580 log_debug("clipboard_send_format_ack: data out, sending "
541 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_ack: data out, sending "
581542 "CLIPRDR_FORMAT_ACK (clip_msg_id = 3)");
582543 rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
583544 free_stream(s);
669630 int rv;
670631 char *holdp;
671632
672 log_debug("clipboard_send_format_announce:");
633 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce:");
673634 make_stream(s);
674635 init_stream(s, 8192);
675636 out_uint16_le(s, CB_FORMAT_LIST); /* 2 CLIPRDR_FORMAT_ANNOUNCE */
681642 switch (xrdp_clip_type)
682643 {
683644 case XRDP_CB_FILE:
684 log_debug("clipboard_send_format_announce: XRDP_CB_FILE");
645 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce: XRDP_CB_FILE");
685646 /* canned response for "file" */
686647 out_uint32_le(s, 0x0000c0bc);
687648 clipboard_out_unicode(s, "FileGroupDescriptorW", 21);
691652 clipboard_out_unicode(s, "DropEffect", 11);
692653 break;
693654 case XRDP_CB_BITMAP:
694 log_debug("clipboard_send_format_announce: XRDP_CB_BITMAP");
655 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce: XRDP_CB_BITMAP");
695656 /* canned response for "bitmap" */
696657 out_uint32_le(s, 0x0000c004);
697658 clipboard_out_unicode(s, "Native", 7);
703664 clipboard_out_unicode(s, "", 1);
704665 break;
705666 case XRDP_CB_TEXT:
706 log_debug("clipboard_send_format_announce: XRDP_CB_TEXT");
667 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce: XRDP_CB_TEXT");
707668 /* canned response for "bitmap" */
708669 out_uint32_le(s, 0x0000000d);
709670 clipboard_out_unicode(s, "", 1);
715676 clipboard_out_unicode(s, "", 1);
716677 break;
717678 default:
718 log_debug("clipboard_send_format_announce: unknown "
679 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce: unknown "
719680 "xrdp_clip_type %d", xrdp_clip_type);
720681 break;
721682 }
725686 switch (xrdp_clip_type)
726687 {
727688 case XRDP_CB_FILE:
728 log_debug("clipboard_send_format_announce: XRDP_CB_FILE");
689 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce: XRDP_CB_FILE");
729690 /* canned response for "file" */
730691 out_uint32_le(s, 0x0000c0bc);
731692 out_uint8p(s, windows_native_format, sizeof(windows_native_format));
735696 out_uint8p(s, windows_native_format, sizeof(windows_native_format));
736697 break;
737698 case XRDP_CB_BITMAP:
738 log_debug("clipboard_send_format_announce: XRDP_CB_BITMAP");
699 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce: XRDP_CB_BITMAP");
739700 /* canned response for "bitmap" */
740701 out_uint32_le(s, 0x0000c004);
741702 out_uint8p(s, windows_native_format, sizeof(windows_native_format));
747708 out_uint8p(s, windows_native_format, sizeof(windows_native_format));
748709 break;
749710 case XRDP_CB_TEXT:
750 log_debug("clipboard_send_format_announce: XRDP_CB_TEXT");
711 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce: XRDP_CB_TEXT");
751712 /* canned response for "bitmap" */
752713 out_uint32_le(s, 0x0000000d);
753714 out_uint8p(s, windows_native_format, sizeof(windows_native_format));
759720 out_uint8p(s, windows_native_format, sizeof(windows_native_format));
760721 break;
761722 default:
762 log_debug("clipboard_send_format_announce: unknown "
723 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce: unknown "
763724 "xrdp_clip_type %d", xrdp_clip_type);
764725 break;
765726 }
773734 out_uint32_le(s, 0);
774735 s_mark_end(s);
775736 size = (int)(s->end - s->data);
776 //g_hexdump(s->data, size);
777 log_debug("clipboard_send_format_announce: data out, sending "
737 LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "clipboard data:", s->data, size);
738 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_format_announce: data out, sending "
778739 "CLIPRDR_FORMAT_ANNOUNCE (clip_msg_id = 2)");
779740 rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
780741 free_stream(s);
789750 int size;
790751 int rv;
791752
792 log_debug("clipboard_send_data_response_for_image: data_size %d",
753 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_data_response_for_image: data_size %d",
793754 data_size);
794755 make_stream(s);
795756 init_stream(s, 64 + data_size);
814775 int rv;
815776 int num_chars;
816777
817 log_debug("clipboard_send_data_response_for_text: data_size %d",
778 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_data_response_for_text: data_size %d",
818779 data_size);
819 //g_hexdump(data, data_size);
780 LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "clipboard send data response:", data, data_size);
820781 num_chars = g_mbstowcs(0, data, 0);
821782 if (num_chars < 0)
822783 {
823 log_error("clipboard_send_data_response_for_text: "
784 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_data_response_for_text: "
824785 "bad string");
825786 num_chars = 0;
826787 }
827 log_debug("clipboard_send_data_response_for_text: data_size %d "
788 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_data_response_for_text: data_size %d "
828789 "num_chars %d", data_size, num_chars);
829790 make_stream(s);
830791 init_stream(s, 64 + num_chars * 2);
833794 out_uint32_le(s, num_chars * 2 + 2); /* length */
834795 if (clipboard_out_unicode(s, data, num_chars) != num_chars * 2)
835796 {
836 log_error("clipboard_send_data_response_for_text: error "
797 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_data_response_for_text: error "
837798 "clipboard_out_unicode didn't write right number of bytes");
838799 }
839800 out_uint16_le(s, 0); /* nil for string */
840801 out_uint32_le(s, 0);
841802 s_mark_end(s);
842803 size = (int)(s->end - s->data);
843 log_debug("clipboard_send_data_response_for_text: data out, "
804 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_data_response_for_text: data out, "
844805 "sending CLIPRDR_DATA_RESPONSE (clip_msg_id = 5) size %d "
845806 "num_chars %d", size, num_chars);
846807 rv = send_channel_data(g_cliprdr_chan_id, s->data, size);
852813 static int
853814 clipboard_send_data_response(int xrdp_clip_type, const char *data, int data_size)
854815 {
855 log_debug("clipboard_send_data_response:");
816 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_data_response:");
856817 if (data != 0)
857818 {
858819 if (xrdp_clip_type == XRDP_CB_FILE)
869830 }
870831 else
871832 {
872 log_debug("clipboard_send_data_response: unknown "
833 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_data_response: unknown "
873834 "xrdp_clip_type %d", xrdp_clip_type);
874835 }
875836 }
876837 else
877838 {
878 log_error("clipboard_send_data_response: data is nil");
839 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_data_response: data is nil");
879840 }
880841 return 0;
881842 }
886847 {
887848 Window owner;
888849
889 log_debug("clipboard_set_selection_owner:");
850 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_set_selection_owner:");
890851 g_selection_time = clipboard_get_server_time();
891852 XSetSelectionOwner(g_display, g_clipboard_atom, g_wnd, g_selection_time);
892853 owner = XGetSelectionOwner(g_display, g_clipboard_atom);
908869 XEvent xev;
909870 long val1[2];
910871
911 log_debug("clipboard_provide_selection_c2s: bytes %d",
872 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_provide_selection_c2s: bytes %d",
912873 g_clip_c2s.total_bytes);
913874 if (g_clip_c2s.total_bytes < g_incr_max_req_size)
914875 {
934895 g_clip_c2s.type = type;
935896 g_clip_c2s.property = req->property;
936897 g_clip_c2s.window = req->requestor;
937 log_debug("clipboard_provide_selection_c2s: start INCR property %s "
898 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_provide_selection_c2s: start INCR property %s "
938899 "type %s", get_atom_text(req->property),
939900 get_atom_text(type));
940901 val1[0] = g_clip_c2s.total_bytes;
967928
968929 bytes = FORMAT_TO_BYTES(format);
969930 bytes *= length;
970 log_debug("clipboard_provide_selection: bytes %d", bytes);
931 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_provide_selection: bytes %d", bytes);
971932 if (bytes < g_incr_max_req_size)
972933 {
973934 XChangeProperty(g_display, req->requestor, req->property,
1020981 char desc[256];
1021982 char *holdp;
1022983
1023 log_debug("clipboard_process_format_announce: "
984 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_format_announce: "
1024985 "CLIPRDR_FORMAT_ANNOUNCE");
1025 log_debug("clipboard_process_format_announce %d", clip_msg_len);
986 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_format_announce %d", clip_msg_len);
1026987 clipboard_send_format_ack();
1027988
1028989 xfuse_clear_clip_dir();
10521013 desc[15] = 0;
10531014 clip_msg_len -= 32;
10541015 }
1055 log_debug("clipboard_process_format_announce: formatId 0x%8.8x "
1016 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_format_announce: formatId 0x%8.8x "
10561017 "wszFormatName [%s] clip_msg_len %d", formatId, desc,
10571018 clip_msg_len);
10581019 if (g_num_formatIds <= 15)
10621023 }
10631024 if (g_num_formatIds > 15)
10641025 {
1065 log_debug("clipboard_process_format_announce: max formats");
1026 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_format_announce: max formats");
10661027 }
10671028
10681029 /* format id for file copy copy seems to keep changing */
10791040 {
10801041 if (clipboard_set_selection_owner() != 0)
10811042 {
1082 log_error("clipboard_process_format_announce: "
1043 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_process_format_announce: "
10831044 "XSetSelectionOwner failed");
10841045 }
10851046 }
10941055 clipboard_process_format_ack(struct stream *s, int clip_msg_status,
10951056 int clip_msg_len)
10961057 {
1097 log_debug("clipboard_process_format_ack: CLIPRDR_FORMAT_ACK");
1098 log_debug("clipboard_process_format_ack:");
1058 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_format_ack: CLIPRDR_FORMAT_ACK");
1059 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_format_ack:");
10991060 return 0;
11001061 }
11011062
11071068 int size;
11081069 int rv;
11091070
1110 log_error("clipboard_send_data_response_failed:");
1071 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_data_response_failed:");
11111072 make_stream(s);
11121073 init_stream(s, 64);
11131074 out_uint16_le(s, CB_FORMAT_DATA_RESPONSE); /* 5 CLIPRDR_DATA_RESPONSE */
11301091 {
11311092 int requestedFormatId;
11321093
1133 log_debug("clipboard_process_data_request: "
1094 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: "
11341095 "CLIPRDR_DATA_REQUEST");
1135 log_debug("clipboard_process_data_request:");
1136 log_debug(" %d", g_clip_s2c.xrdp_clip_type);
1096 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request:");
1097 LOG_DEVEL(LOG_LEVEL_DEBUG, " %d", g_clip_s2c.xrdp_clip_type);
11371098 in_uint32_le(s, requestedFormatId);
11381099 switch (requestedFormatId)
11391100 {
11401101 case CB_FORMAT_FILE: /* 0xC0BC */
11411102 if ((g_clip_s2c.xrdp_clip_type == XRDP_CB_FILE) && g_clip_s2c.converted)
11421103 {
1143 log_debug("clipboard_process_data_request: CB_FORMAT_FILE");
1104 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: CB_FORMAT_FILE");
11441105 clipboard_send_data_response(XRDP_CB_FILE, g_clip_s2c.data,
11451106 g_clip_s2c.total_bytes);
11461107 }
11471108 else
11481109 {
1149 log_debug("clipboard_process_data_request: CB_FORMAT_FILE, "
1110 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: CB_FORMAT_FILE, "
11501111 "calling XConvertSelection to g_utf8_atom");
11511112 g_clip_s2c.xrdp_clip_type = XRDP_CB_FILE;
11521113 XConvertSelection(g_display, g_clipboard_atom, g_clip_s2c.type,
11561117 case CB_FORMAT_DIB: /* 0x0008 */
11571118 if ((g_clip_s2c.xrdp_clip_type == XRDP_CB_BITMAP) && g_clip_s2c.converted)
11581119 {
1159 log_debug("clipboard_process_data_request: CB_FORMAT_DIB");
1120 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: CB_FORMAT_DIB");
11601121 clipboard_send_data_response(XRDP_CB_BITMAP, g_clip_s2c.data,
11611122 g_clip_s2c.total_bytes);
11621123 }
11631124 else
11641125 {
1165 log_debug("clipboard_process_data_request: CB_FORMAT_DIB, "
1126 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: CB_FORMAT_DIB, "
11661127 "calling XConvertSelection to g_image_bmp_atom");
11671128 g_clip_s2c.xrdp_clip_type = XRDP_CB_BITMAP;
11681129 XConvertSelection(g_display, g_clipboard_atom, g_image_bmp_atom,
11721133 case CB_FORMAT_UNICODETEXT: /* 0x000D */
11731134 if ((g_clip_s2c.xrdp_clip_type == XRDP_CB_TEXT) && g_clip_s2c.converted)
11741135 {
1175 log_debug("clipboard_process_data_request: CB_FORMAT_UNICODETEXT");
1136 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: CB_FORMAT_UNICODETEXT");
11761137 clipboard_send_data_response(XRDP_CB_TEXT, g_clip_s2c.data,
11771138 g_clip_s2c.total_bytes);
11781139 }
11791140 else
11801141 {
1181 log_debug("clipboard_process_data_request: CB_FORMAT_UNICODETEXT, "
1142 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: CB_FORMAT_UNICODETEXT, "
11821143 "calling XConvertSelection to g_utf8_atom");
11831144 g_clip_s2c.xrdp_clip_type = XRDP_CB_TEXT;
11841145 XConvertSelection(g_display, g_clipboard_atom, g_utf8_atom,
11861147 }
11871148 break;
11881149 default:
1189 log_debug("clipboard_process_data_request: unknown type %d",
1150 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_request: unknown type %d",
11901151 requestedFormatId);
11911152 clipboard_send_data_response_failed();
11921153 break;
12081169 XSelectionRequestEvent *lxev;
12091170 int len;
12101171
1211 log_debug("clipboard_process_data_response_for_image: "
1172 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_response_for_image: "
12121173 "CLIPRDR_DATA_RESPONSE_FOR_IMAGE");
12131174 lxev = &g_saved_selection_req_event;
12141175 len = (int)(s->end - s->p);
12311192 g_clip_c2s.read_bytes_done = g_clip_c2s.total_bytes;
12321193 g_memcpy(g_clip_c2s.data, g_bmp_image_header, 14);
12331194 in_uint8a(s, g_clip_c2s.data + 14, len);
1234 log_debug("clipboard_process_data_response_for_image: calling "
1195 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_response_for_image: calling "
12351196 "clipboard_provide_selection_c2s");
12361197 clipboard_provide_selection_c2s(lxev, lxev->target);
12371198 return 0;
12541215 int len;
12551216 int index;
12561217
1257 log_debug("clipboard_process_data_response:");
1218 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_response:");
12581219 lxev = &g_saved_selection_req_event;
12591220 g_clip_c2s.in_request = 0;
12601221 if (g_clip_c2s.xrdp_clip_type == XRDP_CB_BITMAP)
12801241 }
12811242 else
12821243 {
1283 log_error("clipboard_process_data_response: error");
1244 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_process_data_response: error");
12841245 }
12851246 g_clip_c2s.total_bytes = g_strlen(g_clip_c2s.data);
12861247 g_clip_c2s.read_bytes_done = g_clip_c2s.total_bytes;
12871248 clipboard_provide_selection_c2s(lxev, lxev->target);
12881249 return 0;
12891250 }
1290 log_debug("clipboard_process_data_response: "
1251 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_data_response: "
12911252 "CLIPRDR_DATA_RESPONSE");
12921253 len = (int)(s->end - s->p);
12931254 if (len < 1)
13481309 int flags;
13491310 char *holdp;
13501311
1351 log_debug("clipboard_process_clip_caps:");
1352 //g_hexdump(s->p, s->end - s->p);
1312 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_clip_caps:");
1313 //LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", s->p, s->end - s->p);
13531314 in_uint16_le(s, cCapabilitiesSets);
13541315 in_uint8s(s, 2); /* pad */
13551316 for (index = 0; index < cCapabilitiesSets; index++)
13621323 case CB_CAPSTYPE_GENERAL:
13631324 in_uint32_le(s, version); /* version */
13641325 in_uint32_le(s, flags); /* generalFlags */
1365 log_debug("clipboard_process_clip_caps: "
1326 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_clip_caps: "
13661327 "g_cliprdr_version %d version %d "
13671328 "g_cliprdr_flags 0x%x flags 0x%x",
13681329 g_cliprdr_version, version,
13741335 g_cliprdr_flags &= flags;
13751336 break;
13761337 default:
1377 log_debug("clipboard_process_clip_caps: unknown "
1338 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_clip_caps: unknown "
13781339 "capabilitySetType %d", capabilitySetType);
13791340 break;
13801341 }
13901351 int index;
13911352 char *text;
13921353
1393 log_debug("ss_part: data_bytes %d read_bytes_done %d "
1354 LOG_DEVEL(LOG_LEVEL_DEBUG, "ss_part: data_bytes %d read_bytes_done %d "
13941355 "incr_bytes_done %d", data_bytes,
13951356 g_clip_c2s.read_bytes_done,
13961357 g_clip_c2s.incr_bytes_done);
14181379 }
14191380 if (g_clip_c2s.incr_in_progress)
14201381 {
1421 log_debug("ss_part: incr_in_progress set");
1382 LOG_DEVEL(LOG_LEVEL_DEBUG, "ss_part: incr_in_progress set");
14221383 return 0;
14231384 }
14241385 if (g_clip_c2s.read_bytes_done <= g_clip_c2s.incr_bytes_done)
14251386 {
1426 log_debug("ss_part: read_bytes_done < incr_bytes_done");
1387 LOG_DEVEL(LOG_LEVEL_DEBUG, "ss_part: read_bytes_done < incr_bytes_done");
14271388 return 0;
14281389 }
14291390 data = g_clip_c2s.data + g_clip_c2s.incr_bytes_done;
14471408 char *data;
14481409 int data_bytes;
14491410
1450 log_debug("ss_end:");
1411 LOG_DEVEL(LOG_LEVEL_DEBUG, "ss_end:");
14511412 g_clip_c2s.doing_response_ss = 0;
14521413 g_clip_c2s.in_request = 0;
14531414
14541415 if (g_clip_c2s.incr_in_progress)
14551416 {
1456 log_debug("ss_end: incr_in_progress set");
1417 LOG_DEVEL(LOG_LEVEL_DEBUG, "ss_end: incr_in_progress set");
14571418 return 0;
14581419 }
14591420 if (g_clip_c2s.read_bytes_done <= g_clip_c2s.incr_bytes_done)
14601421 {
1461 log_debug("ss_end: read_bytes_done < incr_bytes_done");
1422 LOG_DEVEL(LOG_LEVEL_DEBUG, "ss_end: read_bytes_done < incr_bytes_done");
14621423 return 0;
14631424 }
14641425 data = g_clip_c2s.data + g_clip_c2s.incr_bytes_done;
14841445 long val1[2];
14851446 int incr_bytes;
14861447
1487 log_debug("ss_start: data_bytes %d total_bytes %d",
1448 LOG_DEVEL(LOG_LEVEL_DEBUG, "ss_start: data_bytes %d total_bytes %d",
14881449 data_bytes, total_bytes);
14891450 req = &g_saved_selection_req_event;
14901451
15521513
15531514 if (!g_clip_up)
15541515 {
1555 log_error("aborting clipboard_data_in - clipboard has not "
1516 LOG_DEVEL(LOG_LEVEL_ERROR, "aborting clipboard_data_in - clipboard has not "
15561517 "been initialized");
15571518 /* we return 0 here to indicate no protocol problem occurred */
15581519 return 0;
15591520 }
15601521
1561 log_debug("clipboard_data_in: chan_id %d "
1522 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_data_in: chan_id %d "
15621523 "chan_flags 0x%x length %d total_length %d "
15631524 "in_request %d g_ins->size %d",
15641525 chan_id, chan_flags, length, total_length,
15691530 ss_part(s->p, length);
15701531 if ((chan_flags & 3) == 2)
15711532 {
1572 log_debug("clipboard_data_in: calling ss_end");
1533 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_data_in: calling ss_end");
15731534 ss_end();
15741535 }
15751536 return 0;
16211582 in_uint16_le(ls, clip_msg_status);
16221583 in_uint32_le(ls, clip_msg_len);
16231584
1624 log_debug("clipboard_data_in: clip_msg_id %d "
1585 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_data_in: clip_msg_id %d "
16251586 "clip_msg_status %d clip_msg_len %d",
16261587 clip_msg_id, clip_msg_status, clip_msg_len);
16271588 rv = 0;
16281589
1629 log_debug("clipboard_data_in: %d", clip_msg_id);
1590 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_data_in: %d", clip_msg_id);
16301591 switch (clip_msg_id)
16311592 {
16321593 /* sent by client or server when its local system clipboard is */
16701631 clip_msg_len);
16711632 break;
16721633 default:
1673 log_debug("clipboard_data_in: unknown clip_msg_id %d", clip_msg_id);
1674 log_error("clipboard_data_in: unknown clip_msg_id %d",
1675 clip_msg_id);
1634 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_data_in: unknown clip_msg_id %d", clip_msg_id);
16761635 break;
16771636 }
16781637
17021661 XFixesSelectionNotifyEvent *lxevent;
17031662
17041663 lxevent = (XFixesSelectionNotifyEvent *)xevent;
1705 log_debug("clipboard_event_selection_owner_notify: 0x%lx", lxevent->owner);
1706 log_debug("clipboard_event_selection_owner_notify: "
1664 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_owner_notify: 0x%lx", lxevent->owner);
1665 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_owner_notify: "
17071666 "window %ld subtype %d owner %ld g_wnd %ld",
17081667 lxevent->window, lxevent->subtype, lxevent->owner, g_wnd);
17091668
17101669 if (lxevent->owner == g_wnd)
17111670 {
1712 log_debug("clipboard_event_selection_owner_notify: matches g_wnd");
1713 log_debug("clipboard_event_selection_owner_notify: skipping, "
1671 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_owner_notify: matches g_wnd");
1672 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_owner_notify: skipping, "
17141673 "owner == g_wnd");
17151674 g_got_selection = 1;
17161675 return 0;
17401699 tui8 *lxdata;
17411700 Atom ltype;
17421701
1743 log_debug("clipboard_get_window_property:");
1744 log_debug(" prop %ld name %s", prop, get_atom_text(prop));
1702 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_get_window_property:");
1703 LOG_DEVEL(LOG_LEVEL_DEBUG, " prop %ld name %s", prop, get_atom_text(prop));
17451704 lxdata = 0;
17461705 ltype = 0;
17471706 XGetWindowProperty(g_display, wnd, prop, 0, 0, 0,
18561815 Atom *atoms;
18571816 Atom type;
18581817
1859 log_debug("clipboard_event_selection_notify:");
1818 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_notify:");
18601819 data_size = 0;
18611820 n_items = 0;
18621821 fmt = 0;
18721831
18731832 if (lxevent->property == None)
18741833 {
1875 log_error("clipboard_event_selection_notify: clip could "
1834 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_event_selection_notify: clip could "
18761835 "not be converted");
18771836 rv = 1;
18781837 }
18791838
18801839 if (rv == 0)
18811840 {
1882 log_debug("clipboard_event_selection_notify: wnd 0x%lx prop %s",
1841 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: wnd 0x%lx prop %s",
18831842 lxevent->requestor,
18841843 get_atom_text(lxevent->property));
18851844 rv = clipboard_get_window_property(lxevent->requestor, lxevent->property,
18871846 &n_items, &data, &data_size);
18881847 if (rv != 0)
18891848 {
1890 log_error("clipboard_event_selection_notify: "
1849 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_event_selection_notify: "
18911850 "clipboard_get_window_property failed error %d", rv);
18921851 return 0;
18931852 }
1894 //g_hexdump(data, data_size);
1853 //LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", data, data_size);
18951854 XDeleteProperty(g_display, lxevent->requestor, lxevent->property);
18961855 if (type == g_incr_atom)
18971856 {
18981857 /* nothing more to do here, the data is coming in through
18991858 PropertyNotify */
1900 log_debug("clipboard_event_selection_notify: type is INCR "
1859 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: type is INCR "
19011860 "data_size %d property name %s type %s", data_size,
19021861 get_atom_text(lxevent->property),
19031862 get_atom_text(lxevent->type));
19071866 g_clip_s2c.total_bytes = 0;
19081867 g_free(g_clip_s2c.data);
19091868 g_clip_s2c.data = 0;
1910 //g_hexdump(data, sizeof(long));
1869 //LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", data, sizeof(long));
19111870 g_free(data);
19121871 return 0;
19131872 }
19261885 for (index = 0; index < n_items; index++)
19271886 {
19281887 atom = atoms[index];
1929 LOGM((LOG_LEVEL_DEBUG,
1930 "clipboard_event_selection_notify: 0x%lx %s 0x%lx",
1931 atom, get_atom_text(atom), XA_STRING));
1932 log_debug("clipboard_event_selection_notify: 0x%lx %s",
1888 LOG_DEVEL(LOG_LEVEL_DEBUG,
1889 "clipboard_event_selection_notify: 0x%lx %s 0x%lx",
1890 atom, get_atom_text(atom), XA_STRING);
1891 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: 0x%lx %s",
19331892 atom, get_atom_text(atom));
19341893 if (atom == g_utf8_atom)
19351894 {
19451904 }
19461905 else if ((atom == g_file_atom1) || (atom == g_file_atom2))
19471906 {
1948 log_debug("clipboard_event_selection_notify: file");
1907 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: file");
19491908 got_file_atom = atom;
19501909 }
19511910 else
19521911 {
1953 log_error("clipboard_event_selection_notify: unknown atom 0x%lx", atom);
1912 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_event_selection_notify: unknown atom 0x%lx", atom);
19541913 }
19551914 }
19561915 }
19571916 else
19581917 {
1959 log_error("clipboard_event_selection_notify: error, "
1918 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_event_selection_notify: error, "
19601919 "target is 'TARGETS' and type[%ld] or fmt[%d] not right, "
19611920 "should be type[%ld], fmt[%d]", type, fmt, XA_ATOM, 32);
19621921 }
19631922 }
19641923 else if (lxevent->target == g_utf8_atom)
19651924 {
1966 log_debug("clipboard_event_selection_notify: UTF8_STRING "
1967 "data_size %d", data_size);
1968 log_debug("clipboard_event_selection_notify: UTF8_STRING "
1925 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: UTF8_STRING "
19691926 "data_size %d", data_size);
19701927 if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0))
19711928 {
19881945 }
19891946 else if (lxevent->target == XA_STRING)
19901947 {
1991 log_debug("clipboard_event_selection_notify: XA_STRING "
1992 "data_size %d", data_size);
1993 log_debug("clipboard_event_selection_notify: XA_STRING "
1948 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: XA_STRING "
19941949 "data_size %d", data_size);
19951950 if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0))
19961951 {
20051960 }
20061961 else if (lxevent->target == g_image_bmp_atom)
20071962 {
2008 log_debug("clipboard_event_selection_notify: image/bmp "
2009 "data_size %d", data_size);
2010 log_debug("clipboard_event_selection_notify: image/bmp "
1963 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: image/bmp "
20111964 "data_size %d", data_size);
20121965 if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 14))
20131966 {
20211974 }
20221975 else if (lxevent->target == g_file_atom1)
20231976 {
2024 log_debug("clipboard_event_selection_notify: text/uri-list "
2025 "data_size %d", data_size);
2026 log_debug("clipboard_event_selection_notify: text/uri-list "
1977 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: text/uri-list "
20271978 "data_size %d", data_size);
20281979 if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0))
20291980 {
20381989 }
20391990 else if (lxevent->target == g_file_atom2)
20401991 {
2041 log_debug("clipboard_event_selection_notify: text/uri-list "
2042 "data_size %d", data_size);
2043 log_debug("clipboard_event_selection_notify: text/uri-list "
1992 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_notify: text/uri-list "
20441993 "data_size %d", data_size);
20451994 if ((g_clip_s2c.incr_in_progress == 0) && (data_size > 0))
20461995 {
20552004 }
20562005 else
20572006 {
2058 log_error("clipboard_event_selection_notify: "
2007 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_event_selection_notify: "
20592008 "unknown target");
20602009 }
20612010 }
20622011 else
20632012 {
2064 log_error("clipboard_event_selection_notify: "
2013 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_event_selection_notify: "
20652014 "unknown selection");
20662015 }
20672016 }
21452094 char *xdata;
21462095
21472096 lxev = (XSelectionRequestEvent *)xevent;
2148 log_debug("clipboard_event_selection_request: 0x%lx", lxev->property);
2149 log_debug("clipboard_event_selection_request: g_wnd %ld, "
2097 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: 0x%lx", lxev->property);
2098 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_wnd %ld, "
21502099 ".requestor %ld .owner %ld .selection %ld '%s' .target %ld .property %ld",
21512100 g_wnd, lxev->requestor, lxev->owner, lxev->selection,
21522101 get_atom_text(lxev->selection),
21542103
21552104 if (lxev->property == None)
21562105 {
2157 log_debug("clipboard_event_selection_request: lxev->property "
2158 "is None");
2159 log_debug("clipboard_event_selection_request: "
2106 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: "
21602107 "lxev->property is None");
21612108 }
21622109 else if (lxev->target == g_targets_atom)
21632110 {
2164 log_debug("clipboard_event_selection_request: g_targets_atom");
2111 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_targets_atom");
21652112 /* requestor is asking what the selection can be converted to */
2166 log_debug("clipboard_event_selection_request: "
2113 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: "
21672114 "g_targets_atom");
21682115 atom_buf[0] = g_targets_atom;
21692116 atom_buf[1] = g_timestamp_atom;
21732120 atom_count = 5;
21742121 if (clipboard_find_format_id(CB_FORMAT_DIB) >= 0)
21752122 {
2176 log_debug(" reporting image/bmp");
2123 LOG_DEVEL(LOG_LEVEL_DEBUG, " reporting image/bmp");
21772124 atom_buf[atom_count] = g_image_bmp_atom;
21782125 atom_count++;
21792126 }
21802127 if (clipboard_find_format_id(g_file_format_id) >= 0)
21812128 {
2182 log_debug(" reporting text/uri-list");
2129 LOG_DEVEL(LOG_LEVEL_DEBUG, " reporting text/uri-list");
21832130 atom_buf[atom_count] = g_file_atom1;
21842131 atom_count++;
2185 log_debug(" reporting x-special/gnome-copied-files");
2132 LOG_DEVEL(LOG_LEVEL_DEBUG, " reporting x-special/gnome-copied-files");
21862133 atom_buf[atom_count] = g_file_atom2;
21872134 atom_count++;
21882135 }
21892136 atom_buf[atom_count] = 0;
2190 log_debug(" reporting %d formats", atom_count);
2137 LOG_DEVEL(LOG_LEVEL_DEBUG, " reporting %d formats", atom_count);
21912138 return clipboard_provide_selection(lxev, XA_ATOM, 32,
21922139 (char *)atom_buf, atom_count);
21932140 }
21942141 else if (lxev->target == g_timestamp_atom)
21952142 {
21962143 /* requestor is asking the time I got the selection */
2197 log_debug("clipboard_event_selection_request: "
2144 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: "
21982145 "g_timestamp_atom");
21992146 atom_buf[0] = g_selection_time;
22002147 atom_buf[1] = 0;
22042151 else if (lxev->target == g_multiple_atom)
22052152 {
22062153 /* target, property pairs */
2207 log_debug("clipboard_event_selection_request: "
2154 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: "
22082155 "g_multiple_atom");
22092156
22102157 xdata = 0;
22122159 &type, &fmt, &n_items, &xdata,
22132160 &xdata_size) == 0)
22142161 {
2215 log_debug("clipboard_event_selection_request: g_multiple_atom "
2162 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_multiple_atom "
22162163 "n_items %d", n_items);
22172164 /* todo */
22182165 g_free(xdata);
22292176 }
22302177 else if (lxev->target == g_image_bmp_atom)
22312178 {
2232 log_debug("clipboard_event_selection_request: image/bmp");
2179 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: image/bmp");
22332180 if ((g_clip_c2s.type == lxev->target) && g_clip_c2s.converted)
22342181 {
2235 log_debug("clipboard_event_selection_request: -------------------------------------------");
2182 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: -------------------------------------------");
22362183 clipboard_provide_selection_c2s(lxev, lxev->target);
22372184 return 0;
22382185 }
22452192 }
22462193 else if (lxev->target == g_file_atom1)
22472194 {
2248 log_debug("clipboard_event_selection_request: g_file_atom1");
2195 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_file_atom1");
22492196 if ((g_clip_c2s.type == lxev->target) && g_clip_c2s.converted)
22502197 {
2251 log_debug("clipboard_event_selection_request: -------------------------------------------");
2198 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: -------------------------------------------");
22522199 clipboard_provide_selection_c2s(lxev, lxev->target);
22532200 return 0;
22542201 }
22612208 }
22622209 else if (lxev->target == g_file_atom2)
22632210 {
2264 log_debug("clipboard_event_selection_request: g_file_atom2");
2211 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: g_file_atom2");
22652212 if ((g_clip_c2s.type == lxev->target) && g_clip_c2s.converted)
22662213 {
2267 log_debug("clipboard_event_selection_request: -------------------------------------------");
2214 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_request: -------------------------------------------");
22682215 clipboard_provide_selection_c2s(lxev, lxev->target);
22692216 return 0;
22702217 }
22772224 }
22782225 else
22792226 {
2280 log_debug("clipboard_event_selection_request: unknown "
2281 "target %s", get_atom_text(lxev->target));
2282 LOGM((LOG_LEVEL_ERROR, "clipboard_event_selection_request: unknown "
2283 "target %s", get_atom_text(lxev->target)));
2227 LOG(LOG_LEVEL_ERROR, "clipboard_event_selection_request: unknown "
2228 "target %s", get_atom_text(lxev->target));
22842229 }
22852230
22862231 clipboard_refuse_selection(lxev);
23022247 static int
23032248 clipboard_event_selection_clear(XEvent *xevent)
23042249 {
2305 log_debug("clipboard_event_selection_clear:");
2250 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_selection_clear:");
23062251 return 0;
23072252 }
23082253
23322277 int data_bytes;
23332278 char *cptr;
23342279
2335 log_debug("clipboard_event_property_notify:");
2336 log_debug("clipboard_event_property_notify: PropertyNotify .window %ld "
2280 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_property_notify: PropertyNotify .window %ld "
23372281 ".state %d .atom %ld %s", xevent->xproperty.window,
23382282 xevent->xproperty.state, xevent->xproperty.atom,
23392283 get_atom_text(xevent->xproperty.atom));
23432287 (xevent->xproperty.atom == g_clip_c2s.property) &&
23442288 (xevent->xproperty.state == PropertyDelete))
23452289 {
2346 log_debug("clipboard_event_property_notify: INCR PropertyDelete");
2290 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR PropertyDelete");
23472291 /* this is used for when copying a large clipboard to the other app,
23482292 it will delete the property so we know to send the next one */
23492293
23502294 if ((g_clip_c2s.data == 0) || (g_clip_c2s.total_bytes < 1))
23512295 {
2352 log_debug("clipboard_event_property_notify: INCR error");
2296 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR error");
23532297 return 0;
23542298 }
23552299 data = (tui8 *)(g_clip_c2s.data + g_clip_c2s.incr_bytes_done);
23652309 data_bytes = g_incr_max_req_size;
23662310 }
23672311 g_clip_c2s.incr_bytes_done += data_bytes;
2368 log_debug("clipboard_event_property_notify: data_bytes %d", data_bytes);
2312 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_property_notify: data_bytes %d", data_bytes);
23692313 XChangeProperty(xevent->xproperty.display, xevent->xproperty.window,
23702314 xevent->xproperty.atom, g_clip_c2s.type, 8,
23712315 PropModeReplace, data, data_bytes);
23722316 if (data_bytes < 1)
23732317 {
2374 log_debug("clipboard_event_property_notify: INCR done");
2318 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR done");
23752319 g_clip_c2s.incr_in_progress = 0;
23762320 /* we no longer need property notify */
23772321 XSelectInput(xevent->xproperty.display, xevent->xproperty.window,
23842328 (xevent->xproperty.atom == g_clip_s2c.property) &&
23852329 (xevent->xproperty.state == PropertyNewValue))
23862330 {
2387 log_debug("clipboard_event_property_notify: INCR PropertyNewValue");
2331 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR PropertyNewValue");
23882332 rv = XGetWindowProperty(g_display, g_wnd, g_clip_s2c.property, 0, 0, 0,
23892333 AnyPropertyType, &actual_type_return, &actual_format_return,
23902334 &nitems_returned, &bytes_left, &data);
24022346
24032347 if (bytes_left <= 0)
24042348 {
2405 log_debug("clipboard_event_property_notify: INCR done");
2349 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_property_notify: INCR done");
24062350 /* clipboard INCR cycle has completed */
24072351 g_clip_s2c.incr_in_progress = 0;
24082352 if (g_clip_s2c.type == g_image_bmp_atom)
24092353 {
24102354 g_clip_s2c.xrdp_clip_type = XRDP_CB_BITMAP;
2411 //g_hexdump(g_last_clip_data, 64);
2355 //LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", g_last_clip_data, 64);
24122356 /* skip header */
24132357 clipboard_send_data_response(g_clip_s2c.xrdp_clip_type,
24142358 g_clip_s2c.data + 14,
24242368 }
24252369 else
24262370 {
2427 log_error("clipboard_event_property_notify: error unknown type %ld",
2371 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_event_property_notify: error unknown type %ld",
24282372 g_clip_s2c.type);
24292373 clipboard_send_data_response_failed();
24302374 }
24622406 return 0;
24632407 }
24642408
2465 log_debug("clipboard_event_property_notify: new_data_len %d", new_data_len);
2409 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_event_property_notify: new_data_len %d", new_data_len);
24662410 g_clip_s2c.data = cptr;
24672411 g_memcpy(g_clip_s2c.data + g_clip_s2c.total_bytes, data, new_data_len);
24682412 g_clip_s2c.total_bytes += new_data_len;
24862430 {
24872431 XEvent *lxevent;
24882432
2489 log_debug("clipboard_xevent: event detected");
2433 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_xevent: event detected");
24902434
24912435 if (!g_clip_up)
24922436 {
24982442 switch (lxevent->type)
24992443 {
25002444 case SelectionNotify:
2501 if (g_restrict_outbound_clipboard == 0)
2445 if (g_cfg->restrict_outbound_clipboard == 0)
25022446 {
25032447 clipboard_event_selection_notify(lxevent);
25042448 }
25052449 else
25062450 {
2507 log_debug("outbound clipboard is restricted because of config");
2451 LOG_DEVEL(LOG_LEVEL_DEBUG, "outbound clipboard is restricted because of config");
25082452 return 1;
25092453 }
25102454 break;
25202464 clipboard_event_property_notify(lxevent);
25212465 break;
25222466 case UnmapNotify:
2523 log_debug("chansrv::clipboard_xevent: got UnmapNotify");
2467 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::clipboard_xevent: got UnmapNotify");
25242468 break;
25252469 case ClientMessage:
2526 log_debug("chansrv::clipboard_xevent: got ClientMessage");
2470 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::clipboard_xevent: got ClientMessage");
25272471 break;
25282472 default:
25292473
25302474 if (lxevent->type == g_xfixes_event_base +
25312475 XFixesSetSelectionOwnerNotify)
25322476 {
2533 log_debug("clipboard_xevent: got XFixesSetSelectionOwnerNotify");
2477 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_xevent: got XFixesSetSelectionOwnerNotify");
25342478 clipboard_event_selection_owner_notify(lxevent);
25352479 break;
25362480 }
25372481 if (lxevent->type == g_xfixes_event_base +
25382482 XFixesSelectionWindowDestroyNotify)
25392483 {
2540 log_debug("clipboard_xevent: got XFixesSelectionWindowDestroyNotify");
2484 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_xevent: got XFixesSelectionWindowDestroyNotify");
25412485 break;
25422486 }
25432487 if (lxevent->type == g_xfixes_event_base +
25442488 XFixesSelectionClientCloseNotify)
25452489 {
2546 log_debug("clipboard_xevent: got XFixesSelectionClientCloseNotify");
2490 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_xevent: got XFixesSelectionClientCloseNotify");
25472491 break;
25482492 }
25492493
3232 #include "arch.h"
3333 #include "parse.h"
3434 #include "os_calls.h"
35 #include "string_calls.h"
3536 #include "list.h"
3637 #include "chansrv.h"
3738 #include "clipboard.h"
4041 #include "xcommon.h"
4142 #include "chansrv_fuse.h"
4243
43 /* module based logging */
44 #define LOG_ERROR 0
45 #define LOG_INFO 1
46 #define LOG_DEBUG 2
47 #define LOG_LVL LOG_ERROR
48
49 #define log_error(_params...) \
50 { \
51 g_write("[%10.10u]: CLIPFILE %s: %d : ERROR: ", \
52 g_time3(), __func__, __LINE__); \
53 g_writeln (_params); \
54 }
55
56 #define log_always(_params...) \
57 { \
58 g_write("[%10.10u]: CLIPFILE %s: %d : ALWAYS: ", \
59 g_time3(), __func__, __LINE__); \
60 g_writeln (_params); \
61 }
62
63 #define log_info(_params...) \
64 { \
65 if (LOG_INFO <= LOG_LVL) \
66 { \
67 g_write("[%10.10u]: CLIPFILE %s: %d : ", \
68 g_time3(), __func__, __LINE__); \
69 g_writeln (_params); \
70 } \
71 }
72
73 #define log_debug(_params...) \
74 { \
75 if (LOG_DEBUG <= LOG_LVL) \
76 { \
77 g_write("[%10.10u]: CLIPFILE %s: %d : ", \
78 g_time3(), __func__, __LINE__); \
79 g_writeln (_params); \
80 } \
81 }
82
8344 extern int g_cliprdr_chan_id; /* in chansrv.c */
8445
8546 extern struct clip_s2c g_clip_s2c; /* in clipboard.c */
151112 index++;
152113 }
153114 }
154 log_debug("[%s] [%s]", filename, lfilename);
115 LOG_DEVEL(LOG_LEVEL_DEBUG, "[%s] [%s]", filename, lfilename);
155116 g_strcpy(filename, lfilename);
156117 return 0;
157118 }
208169 g_snprintf(full_fn, 255, "%s/%s", pathname, filename);
209170 if (g_directory_exist(full_fn))
210171 {
211 log_error("clipboard_get_file: file [%s] is a directory, "
212 "not supported", full_fn);
172 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_get_file: file [%s] is a directory, "
173 "not supported", full_fn);
213174 flags |= CB_FILE_ATTRIBUTE_DIRECTORY;
214175 return 1;
215176 }
216177 if (!g_file_exist(full_fn))
217178 {
218 log_error("clipboard_get_file: file [%s] does not exist",
219 full_fn);
179 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_get_file: file [%s] does not exist",
180 full_fn);
220181 return 1;
221182 }
222183 else
223184 {
224 cfi = (struct cb_file_info*)g_malloc(sizeof(struct cb_file_info), 1);
185 cfi = (struct cb_file_info *)g_malloc(sizeof(struct cb_file_info), 1);
225186 list_add_item(g_files_list, (tintptr)cfi);
226187 g_strcpy(cfi->filename, filename);
227188 g_strcpy(cfi->pathname, pathname);
228189 cfi->size = g_file_get_size(full_fn);
229190 cfi->flags = flags;
230191 cfi->time = (g_time1() + CB_EPOCH_DIFF) * 10000000LL;
231 log_debug("ok filename [%s] pathname [%s] size [%d]",
232 cfi->filename, cfi->pathname, cfi->size);
192 LOG_DEVEL(LOG_LEVEL_DEBUG, "ok filename [%s] pathname [%s] size [%d]",
193 cfi->filename, cfi->pathname, cfi->size);
233194 }
234195 return 0;
235196 }
291252 char fn[256];
292253 struct cb_file_info *cfi;
293254
294 log_debug("clipboard_send_data_response_for_file: data_size %d",
295 data_size);
296 //g_hexdump(data, data_size);
255 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_data_response_for_file: data_size %d",
256 data_size);
257 LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", data, data_size);
297258 if (g_files_list == 0)
298259 {
299260 g_files_list = list_create();
354315
355316 if (g_files_list == 0)
356317 {
357 log_error("clipboard_send_file_size: error g_files_list is nil");
318 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_file_size: error g_files_list is nil");
358319 return 1;
359320 }
360321 cfi = (struct cb_file_info *)list_get_item(g_files_list, lindex);
361322 if (cfi == 0)
362323 {
363 log_error("clipboard_send_file_size: error cfi is nil");
324 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_file_size: error cfi is nil");
364325 return 1;
365326 }
366327 file_size = cfi->size;
367 log_debug("clipboard_send_file_size: streamId %d file_size %d",
368 streamId, file_size);
328 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_file_size: streamId %d file_size %d",
329 streamId, file_size);
369330 make_stream(s);
370331 init_stream(s, 8192);
371332 out_uint16_le(s, CB_FILECONTENTS_RESPONSE); /* 9 */
391352 int size;
392353 int rv;
393354
394 log_debug("clipboard_request_file_size:");
355 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_request_file_size:");
395356 if (g_file_request_sent_type != 0)
396357 {
397 log_error("clipboard_request_file_size: warning, still waiting "
398 "for CB_FILECONTENTS_RESPONSE");
358 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_request_file_size: warning, still waiting "
359 "for CB_FILECONTENTS_RESPONSE");
399360 }
400361 make_stream(s);
401362 init_stream(s, 8192);
433394
434395 if (g_files_list == 0)
435396 {
436 log_error("clipboard_send_file_data: error g_files_list is nil");
397 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_file_data: error g_files_list is nil");
437398 return 1;
438399 }
439400 cfi = (struct cb_file_info *)list_get_item(g_files_list, lindex);
440401 if (cfi == 0)
441402 {
442 log_error("clipboard_send_file_data: error cfi is nil");
443 return 1;
444 }
445 log_debug("clipboard_send_file_data: streamId %d lindex %d "
446 "nPositionLow %d cbRequested %d", streamId, lindex,
447 nPositionLow, cbRequested);
403 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_file_data: error cfi is nil");
404 return 1;
405 }
406 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_send_file_data: streamId %d lindex %d "
407 "nPositionLow %d cbRequested %d", streamId, lindex,
408 nPositionLow, cbRequested);
448409 g_snprintf(full_fn, 255, "%s/%s", cfi->pathname, cfi->filename);
449410 fd = g_file_open_ex(full_fn, 1, 0, 0, 0);
450411 if (fd == -1)
451412 {
452 log_error("clipboard_send_file_data: file open [%s] failed",
453 full_fn);
413 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_file_data: file open [%s] failed",
414 full_fn);
454415 return 1;
455416 }
456417 if (g_file_seek(fd, nPositionLow) < 0)
457418 {
458 log_message(LOG_LEVEL_ERROR, "clipboard_send_file_data: seek error "
459 "in file: %s", full_fn);
419 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_file_data: seek error "
420 "in file: %s", full_fn);
460421 g_file_close(fd);
461422 return 1;
462423 }
465426 size = g_file_read(fd, s->data + 12, cbRequested);
466427 if (size < 1)
467428 {
468 log_error("clipboard_send_file_data: read error, want %d got %d",
469 cbRequested, size);
429 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_send_file_data: read error, want %d got %d",
430 cbRequested, size);
470431 free_stream(s);
471432 g_file_close(fd);
472433 return 1;
495456 int size;
496457 int rv;
497458
498 log_debug("clipboard_request_file_data: stream_id=%d lindex=%d off=%d request_bytes=%d",
499 stream_id, lindex, offset, request_bytes);
459 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_request_file_data: stream_id=%d lindex=%d off=%d request_bytes=%d",
460 stream_id, lindex, offset, request_bytes);
500461
501462 if (g_file_request_sent_type != 0)
502463 {
503 log_error("clipboard_request_file_data: warning, still waiting "
504 "for CB_FILECONTENTS_RESPONSE");
464 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_request_file_data: warning, still waiting "
465 "for CB_FILECONTENTS_RESPONSE");
505466 }
506467 make_stream(s);
507468 init_stream(s, 8192);
538499 int cbRequested;
539500 //int clipDataId;
540501
541 log_debug("clipboard_process_file_request:");
542 //g_hexdump(s->p, clip_msg_len);
502 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_file_request:");
503 LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", s->p, clip_msg_len);
543504 in_uint32_le(s, streamId);
544505 in_uint32_le(s, lindex);
545506 in_uint32_le(s, dwFlags);
568529 int streamId;
569530 int file_size;
570531
571 log_debug("clipboard_process_file_response:");
532 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_file_response:");
572533 if (g_file_request_sent_type == CB_FILECONTENTS_SIZE)
573534 {
574535 g_file_request_sent_type = 0;
575536 in_uint32_le(s, streamId);
576537 in_uint32_le(s, file_size);
577 log_debug("clipboard_process_file_response: streamId %d "
578 "file_size %d", streamId, file_size);
538 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_process_file_response: streamId %d "
539 "file_size %d", streamId, file_size);
579540 xfuse_file_contents_size(streamId, file_size);
580541 }
581542 else if (g_file_request_sent_type == CB_FILECONTENTS_RANGE)
586547 }
587548 else
588549 {
589 log_error("clipboard_process_file_response: error");
550 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_process_file_response: error");
590551 g_file_request_sent_type = 0;
591552 }
592553 return 0;
614575 ex_bytes -= 2;
615576 in_uint8s(s, ex_bytes);
616577 in_uint8s(s, 8); /* pad */
617 log_debug("clipboard_c2s_in_file_info:");
618 log_debug(" flags 0x%8.8x", cfd->flags);
619 log_debug(" fileAttributes 0x%8.8x", cfd->fileAttributes);
620 log_debug(" lastWriteTime 0x%8.8x%8.8x", cfd->lastWriteTimeHigh,
621 cfd->lastWriteTimeLow);
622 log_debug(" fileSize 0x%8.8x%8.8x", cfd->fileSizeHigh,
623 cfd->fileSizeLow);
624 log_debug(" num_chars %d cFileName [%s]", num_chars, cfd->cFileName);
578 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_c2s_in_file_info:");
579 LOG_DEVEL(LOG_LEVEL_DEBUG, " flags 0x%8.8x", cfd->flags);
580 LOG_DEVEL(LOG_LEVEL_DEBUG, " fileAttributes 0x%8.8x", cfd->fileAttributes);
581 LOG_DEVEL(LOG_LEVEL_DEBUG, " lastWriteTime 0x%8.8x%8.8x", cfd->lastWriteTimeHigh,
582 cfd->lastWriteTimeLow);
583 LOG_DEVEL(LOG_LEVEL_DEBUG, " fileSize 0x%8.8x%8.8x", cfd->fileSizeHigh,
584 cfd->fileSizeLow);
585 LOG_DEVEL(LOG_LEVEL_DEBUG, " num_chars %d cFileName [%s]", num_chars, cfd->cFileName);
625586 return 0;
626587 }
627588
638599
639600 if (!s_check_rem(s, 4))
640601 {
641 log_error("clipboard_c2s_in_files: parse error");
602 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_c2s_in_files: parse error");
642603 return 1;
643604 }
644605 in_uint32_le(s, cItems);
645606 if (cItems > 64 * 1024) /* sanity check */
646607 {
647 log_error("clipboard_c2s_in_files: error cItems %d too big", cItems);
608 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_c2s_in_files: error cItems %d too big", cItems);
648609 return 1;
649610 }
650611 xfuse_clear_clip_dir();
651 log_debug("clipboard_c2s_in_files: cItems %d", cItems);
612 LOG_DEVEL(LOG_LEVEL_DEBUG, "clipboard_c2s_in_files: cItems %d", cItems);
652613 cfd = (struct clip_file_desc *)
653614 g_malloc(sizeof(struct clip_file_desc), 0);
654615 file_count = 0;
658619 g_memset(cfd, 0, sizeof(struct clip_file_desc));
659620 clipboard_c2s_in_file_info(s, cfd);
660621 if ((g_pos(cfd->cFileName, "\\") >= 0) ||
661 (cfd->fileAttributes & CB_FILE_ATTRIBUTE_DIRECTORY))
662 {
663 log_error("clipboard_c2s_in_files: skipping directory not "
664 "supported [%s]", cfd->cFileName);
622 (cfd->fileAttributes & CB_FILE_ATTRIBUTE_DIRECTORY))
623 {
624 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_c2s_in_files: skipping directory not "
625 "supported [%s]", cfd->cFileName);
665626 continue;
666627 }
667628 if (xfuse_add_clip_dir_item(cfd->cFileName, 0, cfd->fileSizeLow, lindex) == -1)
668629 {
669 log_error("clipboard_c2s_in_files: failed to add clip dir item");
630 LOG_DEVEL(LOG_LEVEL_ERROR, "clipboard_c2s_in_files: failed to add clip dir item");
670631 continue;
671632 }
672633
4848 #include "arch.h"
4949 #include "parse.h"
5050 #include "os_calls.h"
51 #include "string_calls.h"
5152 #include "log.h"
5253 #include "chansrv.h"
5354 #include "chansrv_fuse.h"
5859 #include "ms-fscc.h"
5960 #include "ms-erref.h"
6061
61 /* module based logging */
62 #define LOG_ERROR 0
63 #define LOG_INFO 1
64 #define LOG_DEBUG 2
65
66 #undef LOG_LEVEL
67 #define LOG_LEVEL LOG_ERROR
68
69 #define log_error(_params...) \
70 { \
71 g_write("[%10.10u]: DEV_REDIR %s: %d : ERROR: ", \
72 g_time3(), __func__, __LINE__); \
73 g_writeln (_params); \
74 }
75
76 #define log_info(_params...) \
77 { \
78 if (LOG_INFO <= LOG_LEVEL) \
79 { \
80 g_write("[%10.10u]: DEV_REDIR %s: %d : ", \
81 g_time3(), __func__, __LINE__); \
82 g_writeln (_params); \
83 } \
84 }
85
86 #define log_debug(_params...) \
87 { \
88 if (LOG_DEBUG <= LOG_LEVEL) \
89 { \
90 g_write("[%10.10u]: DEV_REDIR %s: %d : ", \
91 g_time3(), __func__, __LINE__); \
92 g_writeln (_params); \
93 } \
94 }
9562
9663 /* client minor versions */
9764 #define RDP_CLIENT_50 0x0002
148115 */
149116 static void devredir_proc_cid_rmdir_or_file(IRP *irp, enum NTSTATUS IoStatus);
150117 static void devredir_proc_cid_rmdir_or_file_resp(IRP *irp,
151 enum NTSTATUS IoStatus);
118 enum NTSTATUS IoStatus);
152119 static void devredir_proc_cid_rename_file(IRP *irp, enum NTSTATUS IoStatus);
153120 static void devredir_proc_cid_rename_file_resp(IRP *irp,
154 enum NTSTATUS IoStatus);
121 enum NTSTATUS IoStatus);
155122 static void devredir_proc_cid_lookup( IRP *irp,
156123 struct stream *s_in,
157124 enum NTSTATUS IoStatus);
168135 static void devredir_proc_client_devlist_remove_req(struct stream *s);
169136 static void devredir_proc_device_iocompletion(struct stream *s);
170137 static void devredir_proc_query_dir_response(IRP *irp,
171 struct stream *s_in,
172 tui32 DeviceId,
173 tui32 CompletionId,
174 enum NTSTATUS IoStatus);
138 struct stream *s_in,
139 tui32 DeviceId,
140 tui32 CompletionId,
141 enum NTSTATUS IoStatus);
175142
176143 static void devredir_cvt_slash(char *path);
177144 static void devredir_cvt_to_unicode(char *unicode, const char *path);
184151 {
185152 struct stream *s;
186153 int bytes;
187 int fd;
188
189 union _u
190 {
191 tui32 clientID;
192 char buf[4];
193 } u;
154 tui32 clientID;
194155
195156 /* get a random number that will act as a unique clientID */
196 if ((fd = open("/dev/urandom", O_RDONLY)) != -1)
197 {
198 if (read(fd, u.buf, 4) != 4)
199 {
200 }
201 close(fd);
202 }
203 else
204 {
205 /* /dev/urandom did not work - use address of struct s */
206 tui64 u64 = (tui64) (tintptr) &s;
207 u.clientID = (tui32) u64;
208 }
157 g_random((char *) &clientID, sizeof(clientID));
209158
210159 /* setup stream */
211160 xstream_new(s, 1024);
215164 xstream_wr_u16_le(s, PAKID_CORE_SERVER_ANNOUNCE);
216165 xstream_wr_u16_le(s, 0x0001); /* server major ver */
217166 xstream_wr_u16_le(s, 0x000C); /* server minor ver - pretend 2 b Win 7 */
218 xstream_wr_u32_le(s, u.clientID); /* unique ClientID */
167 xstream_wr_u32_le(s, clientID); /* unique ClientID */
219168
220169 /* send data to client */
221170 bytes = xstream_len(s);
240189 */
241190 const char *completion_type_to_str(enum COMPLETION_TYPE cid)
242191 {
243 return
244 (cid == CID_CREATE_DIR_REQ) ? "CID_CREATE_DIR_REQ" :
245 (cid == CID_DIRECTORY_CONTROL) ? "CID_DIRECTORY_CONTROL" :
246 (cid == CID_CREATE_REQ) ? "CID_CREATE_REQ" :
247 (cid == CID_OPEN_REQ) ? "CID_OPEN_REQ" :
248 (cid == CID_READ) ? "CID_READ" :
249 (cid == CID_WRITE) ? "CID_WRITE" :
250 (cid == CID_CLOSE) ? "CID_CLOSE" :
251 (cid == CID_FILE_CLOSE) ? "CID_FILE_CLOSE" :
252 (cid == CID_RMDIR_OR_FILE) ? "CID_RMDIR_OR_FILE" :
253 (cid == CID_RMDIR_OR_FILE_RESP) ? "CID_RMDIR_OR_FILE_RESP" :
254 (cid == CID_RENAME_FILE) ? "CID_RENAME_FILE" :
255 (cid == CID_RENAME_FILE_RESP) ? "CID_RENAME_FILE_RESP" :
256 (cid == CID_LOOKUP) ? "CID_LOOKUP" :
257 (cid == CID_SETATTR) ? "CID_SETATTR" :
192 return
193 (cid == CID_CREATE_DIR_REQ) ? "CID_CREATE_DIR_REQ" :
194 (cid == CID_DIRECTORY_CONTROL) ? "CID_DIRECTORY_CONTROL" :
195 (cid == CID_CREATE_REQ) ? "CID_CREATE_REQ" :
196 (cid == CID_OPEN_REQ) ? "CID_OPEN_REQ" :
197 (cid == CID_READ) ? "CID_READ" :
198 (cid == CID_WRITE) ? "CID_WRITE" :
199 (cid == CID_CLOSE) ? "CID_CLOSE" :
200 (cid == CID_FILE_CLOSE) ? "CID_FILE_CLOSE" :
201 (cid == CID_RMDIR_OR_FILE) ? "CID_RMDIR_OR_FILE" :
202 (cid == CID_RMDIR_OR_FILE_RESP) ? "CID_RMDIR_OR_FILE_RESP" :
203 (cid == CID_RENAME_FILE) ? "CID_RENAME_FILE" :
204 (cid == CID_RENAME_FILE_RESP) ? "CID_RENAME_FILE_RESP" :
205 (cid == CID_LOOKUP) ? "CID_LOOKUP" :
206 (cid == CID_SETATTR) ? "CID_SETATTR" :
258207 /* default */ "<unknown>";
259208 };
260209
278227 else
279228 {
280229 result = S_IFREG | 0444; /* files are always readable */
281 if (wperm & W_FILE_ATTRIBUTE_SYSTEM) result |= 0111; /* Executable */
282 }
283
284 if ((wperm & W_FILE_ATTRIBUTE_READONLY) == 0) result |= 0222;
230 if (wperm & W_FILE_ATTRIBUTE_SYSTEM)
231 {
232 result |= 0111; /* Executable */
233 }
234 }
235
236 if ((wperm & W_FILE_ATTRIBUTE_READONLY) == 0)
237 {
238 result |= 0222;
239 }
285240
286241 return result;
287242 }
349304 {
350305 /* is this is the first packet? */
351306 if (chan_flags & 1)
307 {
352308 xstream_new(g_input_stream, total_length);
309 }
353310
354311 xstream_copyin(g_input_stream, s->p, length);
355312
356313 /* in last packet, chan_flags & 0x02 will be true */
357314 if ((chan_flags & 2) == 0)
315 {
358316 return 0;
317 }
359318
360319 g_input_stream->p = g_input_stream->data;
361320 ls = g_input_stream;
368327 /* for now we only handle core type, not printers */
369328 if (comp_type != RDPDR_CTYP_CORE)
370329 {
371 log_error("invalid component type in response; expected 0x%x got 0x%x",
330 LOG_DEVEL(LOG_LEVEL_ERROR, "invalid component type in response; expected 0x%x got 0x%x",
372331 RDPDR_CTYP_CORE, comp_type);
373332
374333 rv = -1;
433392 break;
434393
435394 default:
436 log_error("got unknown response 0x%x", pktID);
395 LOG_DEVEL(LOG_LEVEL_ERROR, "got unknown response 0x%x", pktID);
437396 break;
438397 }
439398
492451 /* setup general capability */
493452 xstream_wr_u16_le(s, CAP_GENERAL_TYPE); /* CapabilityType */
494453 xstream_wr_u16_le(s, 44); /* CapabilityLength - len of this */
495 /* CAPABILITY_SET in bytes, inc */
496 /* the header */
454 /* CAPABILITY_SET in bytes, inc */
455 /* the header */
497456 xstream_wr_u32_le(s, 2); /* Version */
498457 xstream_wr_u32_le(s, 2); /* O.S type */
499458 xstream_wr_u32_le(s, 0); /* O.S version */
519478 /* setup file system capability */
520479 xstream_wr_u16_le(s, CAP_DRIVE_TYPE); /* CapabilityType */
521480 xstream_wr_u16_le(s, 8); /* CapabilityLength - len of this */
522 /* CAPABILITY_SET in bytes, inc */
523 /* the header */
481 /* CAPABILITY_SET in bytes, inc */
482 /* the header */
524483 xstream_wr_u32_le(s, 2); /* Version */
525484
526485 /* setup smart card capability */
577536 }
578537
579538 static void
580 devredir_send_server_device_announce_resp(tui32 device_id)
539 devredir_send_server_device_announce_resp(tui32 device_id,
540 enum NTSTATUS result_code)
581541 {
582542 struct stream *s;
583543 int bytes;
588548 xstream_wr_u16_le(s, RDPDR_CTYP_CORE);
589549 xstream_wr_u16_le(s, PAKID_CORE_DEVICE_REPLY);
590550 xstream_wr_u32_le(s, device_id);
591 xstream_wr_u32_le(s, 0); /* ResultCode */
551 xstream_wr_u32_le(s, (tui32)result_code);
592552
593553 /* send to client */
594554 bytes = xstream_len(s);
615575 int len;
616576 tui32 SharedAccess;
617577
618 log_debug("device_id=%d path=\"%s\""
578 LOG_DEVEL(LOG_LEVEL_DEBUG, "device_id=%d path=\"%s\""
619579 " DesiredAccess=0x%x CreateDisposition=0x%x"
620580 " FileAttributes=0x%x CreateOptions=0x%x"
621581 " CompletionId=%d",
682642 MajorFunction, MinorFunc);
683643
684644 if (pad_len)
645 {
685646 xstream_seek(s, pad_len);
647 }
686648
687649 /* send to client */
688650 bytes = xstream_len(s);
689651 send_channel_data(g_rdpdr_chan_id, s->data, bytes);
690652
691653 xstream_free(s);
692 log_debug("sent close request; expect CID_FILE_CLOSE");
654 LOG_DEVEL(LOG_LEVEL_DEBUG, "sent close request; expect CID_FILE_CLOSE");
693655 return 0;
694656 }
695657
772734 tui16 cap_type;
773735 tui16 cap_len;
774736 tui32 cap_version;
775 char* holdp;
737 char *holdp;
776738
777739 xstream_rd_u16_le(s, num_caps);
778740 xstream_seek(s, 2); /* padding */
787749 switch (cap_type)
788750 {
789751 case CAP_GENERAL_TYPE:
790 log_debug("got CAP_GENERAL_TYPE");
752 LOG_DEVEL(LOG_LEVEL_DEBUG, "got CAP_GENERAL_TYPE");
791753 break;
792754
793755 case CAP_PRINTER_TYPE:
794 log_debug("got CAP_PRINTER_TYPE");
756 LOG_DEVEL(LOG_LEVEL_DEBUG, "got CAP_PRINTER_TYPE");
795757 g_is_printer_redir_supported = 1;
796758 break;
797759
798760 case CAP_PORT_TYPE:
799 log_debug("got CAP_PORT_TYPE");
761 LOG_DEVEL(LOG_LEVEL_DEBUG, "got CAP_PORT_TYPE");
800762 g_is_port_redir_supported = 1;
801763 break;
802764
803765 case CAP_DRIVE_TYPE:
804 log_debug("got CAP_DRIVE_TYPE");
766 LOG_DEVEL(LOG_LEVEL_DEBUG, "got CAP_DRIVE_TYPE");
805767 g_is_drive_redir_supported = 1;
806768 if (cap_version == 2)
807769 {
810772 break;
811773
812774 case CAP_SMARTCARD_TYPE:
813 log_debug("got CAP_SMARTCARD_TYPE");
775 LOG_DEVEL(LOG_LEVEL_DEBUG, "got CAP_SMARTCARD_TYPE");
814776 g_is_smartcard_redir_supported = 1;
815777 scard_init();
816778 break;
828790 tui32 device_type;
829791 tui32 device_data_len;
830792 char preferred_dos_name[9];
793 enum NTSTATUS response_status;
831794
832795 /* get number of devices being announced */
833796 xstream_rd_u32_le(s, device_count);
834797
835 log_debug("num of devices announced: %d", device_count);
798 LOG_DEVEL(LOG_LEVEL_DEBUG, "num of devices announced: %d", device_count);
836799
837800 for (i = 0; i < device_count; i++)
838801 {
839802 xstream_rd_u32_le(s, device_type);
840803 xstream_rd_u32_le(s, g_device_id);
804 /* get preferred DOS name
805 * DOS names that are 8 chars long are not NULL terminated */
806 for (j = 0; j < 8; j++)
807 {
808 preferred_dos_name[j] = *s->p++;
809 }
810 preferred_dos_name[8] = 0;
811
812 /* Assume this device isn't supported by us */
813 response_status = STATUS_NOT_SUPPORTED;
841814
842815 switch (device_type)
843816 {
844817 case RDPDR_DTYP_FILESYSTEM:
845 /* get preferred DOS name */
846 for (j = 0; j < 8; j++)
847 {
848 preferred_dos_name[j] = *s->p++;
849 }
850
851 /* DOS names that are 8 chars long are not NULL terminated */
852 preferred_dos_name[8] = 0;
853
854818 /* get device data len */
855819 xstream_rd_u32_le(s, device_data_len);
856820 if (device_data_len)
857821 {
858822 xstream_rd_string(g_full_name_for_filesystem, s,
859 device_data_len);
823 device_data_len);
860824 }
861825
862 log_debug("device_type=FILE_SYSTEM device_id=0x%x dosname=%s "
826 LOG_DEVEL(LOG_LEVEL_DEBUG, "device_type=FILE_SYSTEM device_id=0x%x dosname=%s "
863827 "device_data_len=%d full_name=%s", g_device_id,
864828 preferred_dos_name,
865829 device_data_len, g_full_name_for_filesystem);
866830
867 devredir_send_server_device_announce_resp(g_device_id);
831 response_status = STATUS_SUCCESS;
868832
869833 /* create share directory in xrdp file system; */
870834 /* think of this as the mount point for this share */
872836 break;
873837
874838 case RDPDR_DTYP_SMARTCARD:
875 /* get preferred DOS name */
876 for (j = 0; j < 8; j++)
877 {
878 preferred_dos_name[j] = *s->p++;
879 }
880
881 /* DOS names that are 8 chars long are not NULL terminated */
882 preferred_dos_name[8] = 0;
883
884839 /* for smart cards, device data len always 0 */
885840
886 log_debug("device_type=SMARTCARD device_id=0x%x dosname=%s",
841 LOG_DEVEL(LOG_LEVEL_DEBUG, "device_type=SMARTCARD device_id=0x%x dosname=%s",
887842 g_device_id, preferred_dos_name);
888843
889 devredir_send_server_device_announce_resp(g_device_id);
844 response_status = STATUS_SUCCESS;
845
890846 scard_device_announce(g_device_id);
891847 break;
892848
893 /* we don't yet support these devices */
894849 case RDPDR_DTYP_SERIAL:
850 LOG_DEVEL(LOG_LEVEL_DEBUG,
851 "device_type=SERIAL device_id=0x%x dosname=%s",
852 g_device_id, preferred_dos_name);
853 break;
854
895855 case RDPDR_DTYP_PARALLEL:
856 LOG_DEVEL(LOG_LEVEL_DEBUG,
857 "device_type=PARALLEL device_id=0x%x dosname=%s",
858 g_device_id, preferred_dos_name);
859 break;
860
896861 case RDPDR_DTYP_PRINT:
897 log_debug("unsupported dev: 0x%x", device_type);
898 break;
899 }
862 LOG_DEVEL(LOG_LEVEL_DEBUG,
863 "device_type=PRINT device_id=0x%x dosname=%s",
864 g_device_id, preferred_dos_name);
865 break;
866
867 default:
868 LOG_DEVEL(LOG_LEVEL_DEBUG,
869 "device_type=UNKNOWN device_id=0x%x dosname=%s",
870 g_device_id, preferred_dos_name);
871 break;
872 }
873
874 /* Tell the client wheth or not we're supporting this one */
875 devredir_send_server_device_announce_resp(g_device_id,
876 response_status);
900877 }
901878 }
902879
910887 /* get number of devices being announced */
911888 xstream_rd_u32_le(s, device_count);
912889
913 log_debug("num of devices removed: %d", device_count);
890 LOG_DEVEL(LOG_LEVEL_DEBUG, "num of devices removed: %d", device_count);
914891 {
915892 for (i = 0; i < device_count; i++)
916893 {
938915
939916 if ((irp = devredir_irp_find(CompletionId)) == NULL)
940917 {
941 log_error("IRP with completion ID %d not found", CompletionId);
942 }
943 else
944 if (irp->callback)
918 LOG_DEVEL(LOG_LEVEL_ERROR, "IRP with completion ID %d not found", CompletionId);
919 }
920 else if (irp->callback)
945921 {
946922 /* Callback has been set - call it */
947923 (*irp->callback)(s, irp, DeviceId, CompletionId, IoStatus);
950926 {
951927 comp_type = (enum COMPLETION_TYPE) irp->completion_type;
952928 /* Log something about the IRP */
953 if (IoStatus == NT_STATUS_SUCCESS ||
954 IoStatus == NT_STATUS_NO_MORE_FILES ||
955 (IoStatus == NT_STATUS_NO_SUCH_FILE && comp_type == CID_LOOKUP))
929 if (IoStatus == STATUS_SUCCESS ||
930 IoStatus == STATUS_NO_MORE_FILES ||
931 (IoStatus == STATUS_NO_SUCH_FILE && comp_type == CID_LOOKUP))
956932 {
957933 /* Successes or common occurrences - debug logging only */
958 log_debug("got %s", completion_type_to_str(comp_type));
934 LOG_DEVEL(LOG_LEVEL_DEBUG, "got %s", completion_type_to_str(comp_type));
959935 }
960936 else
961937 {
962 const char *pathname = (irp->pathname) ? irp->pathname : "<none>";
963 log_error("CompletionType = %s, IoStatus=%08x "
938 LOG_DEVEL(LOG_LEVEL_ERROR, "CompletionType = %s, IoStatus=%08x "
964939 "Pathname = %s",
965940 completion_type_to_str(comp_type),
966941 IoStatus,
967 pathname);
942 (irp->pathname) ? irp->pathname : "<none>");
968943 }
969944
970945 switch (comp_type)
971946 {
972 case CID_CREATE_DIR_REQ:
973 if (IoStatus != NT_STATUS_SUCCESS)
974 {
975 xfuse_devredir_cb_enum_dir_done(
976 (struct state_dirscan *) irp->fuse_info, IoStatus);
947 case CID_CREATE_DIR_REQ:
948 if (IoStatus != STATUS_SUCCESS)
949 {
950 xfuse_devredir_cb_enum_dir_done(
951 (struct state_dirscan *) irp->fuse_info, IoStatus);
952 devredir_irp_delete(irp);
953 }
954 else
955 {
956 xstream_rd_u32_le(s, irp->FileId);
957 devredir_send_drive_dir_request(irp, DeviceId,
958 1, irp->pathname);
959 }
960 break;
961
962 case CID_CREATE_REQ:
963 xstream_rd_u32_le(s, irp->FileId);
964
965 xfuse_devredir_cb_create_file(
966 (struct state_create *) irp->fuse_info,
967 IoStatus, DeviceId, irp->FileId);
968 if (irp->gen.create.creating_dir || IoStatus != STATUS_SUCCESS)
969 {
970 devredir_irp_delete(irp);
971 }
972 break;
973
974 case CID_OPEN_REQ:
975 xstream_rd_u32_le(s, irp->FileId);
976
977 xfuse_devredir_cb_open_file((struct state_open *) irp->fuse_info,
978 IoStatus, DeviceId, irp->FileId);
979 if (IoStatus != STATUS_SUCCESS)
980 {
981 devredir_irp_delete(irp);
982 }
983 break;
984
985 case CID_READ:
986 xstream_rd_u32_le(s, Length);
987 xfuse_devredir_cb_read_file((struct state_read *) irp->fuse_info,
988 IoStatus,
989 s->p, Length);
977990 devredir_irp_delete(irp);
978 }
979 else
980 {
991 break;
992
993 case CID_WRITE:
994 xstream_rd_u32_le(s, Length);
995 xfuse_devredir_cb_write_file((struct state_write *) irp->fuse_info,
996 IoStatus,
997 irp->gen.write.offset, Length);
998 devredir_irp_delete(irp);
999 break;
1000
1001 case CID_CLOSE:
1002 devredir_irp_delete(irp);
1003 break;
1004
1005 case CID_FILE_CLOSE:
1006 xfuse_devredir_cb_file_close((struct state_close *) irp->fuse_info);
1007 devredir_irp_delete(irp);
1008 break;
1009
1010 case CID_DIRECTORY_CONTROL:
1011 devredir_proc_query_dir_response(irp, s, DeviceId,
1012 CompletionId, IoStatus);
1013 break;
1014
1015 case CID_RMDIR_OR_FILE:
9811016 xstream_rd_u32_le(s, irp->FileId);
982 devredir_send_drive_dir_request(irp, DeviceId,
983 1, irp->pathname);
984 }
985 break;
986
987 case CID_CREATE_REQ:
988 xstream_rd_u32_le(s, irp->FileId);
989
990 xfuse_devredir_cb_create_file(
991 (struct state_create *) irp->fuse_info,
992 IoStatus, DeviceId, irp->FileId);
993 if (irp->gen.create.creating_dir || IoStatus != NT_STATUS_SUCCESS)
994 {
995 devredir_irp_delete(irp);
996 }
997 break;
998
999 case CID_OPEN_REQ:
1000 xstream_rd_u32_le(s, irp->FileId);
1001
1002 xfuse_devredir_cb_open_file((struct state_open *) irp->fuse_info,
1003 IoStatus, DeviceId, irp->FileId);
1004 if (IoStatus != NT_STATUS_SUCCESS)
1005 {
1006 devredir_irp_delete(irp);
1007 }
1008 break;
1009
1010 case CID_READ:
1011 xstream_rd_u32_le(s, Length);
1012 xfuse_devredir_cb_read_file((struct state_read *) irp->fuse_info,
1013 s->p, Length);
1014 devredir_irp_delete(irp);
1015 break;
1016
1017 case CID_WRITE:
1018 xstream_rd_u32_le(s, Length);
1019 xfuse_devredir_cb_write_file((struct state_write *) irp->fuse_info,
1020 IoStatus,
1021 irp->gen.write.offset, Length);
1022 devredir_irp_delete(irp);
1023 break;
1024
1025 case CID_CLOSE:
1026 devredir_irp_delete(irp);
1027 break;
1028
1029 case CID_FILE_CLOSE:
1030 xfuse_devredir_cb_file_close((struct state_close *) irp->fuse_info);
1031 devredir_irp_delete(irp);
1032 break;
1033
1034 case CID_DIRECTORY_CONTROL:
1035 devredir_proc_query_dir_response(irp, s, DeviceId,
1036 CompletionId, IoStatus);
1037 break;
1038
1039 case CID_RMDIR_OR_FILE:
1040 xstream_rd_u32_le(s, irp->FileId);
1041 devredir_proc_cid_rmdir_or_file(irp, IoStatus);
1042 break;
1043
1044 case CID_RMDIR_OR_FILE_RESP:
1045 devredir_proc_cid_rmdir_or_file_resp(irp, IoStatus);
1046 break;
1047
1048 case CID_RENAME_FILE:
1049 xstream_rd_u32_le(s, irp->FileId);
1050 devredir_proc_cid_rename_file(irp, IoStatus);
1051 break;
1052
1053 case CID_RENAME_FILE_RESP:
1054 devredir_proc_cid_rename_file_resp(irp, IoStatus);
1055 break;
1056
1057 case CID_LOOKUP:
1058 devredir_proc_cid_lookup(irp, s, IoStatus);
1059 break;
1060
1061 case CID_SETATTR:
1062 devredir_proc_cid_setattr(irp, s, IoStatus);
1063 break;
1064
1065 default:
1066 log_error("got unknown CompletionID: DeviceId=0x%x "
1067 "CompletionId=0x%x IoStatus=0x%x",
1068 DeviceId, CompletionId, IoStatus);
1069 break;
1017 devredir_proc_cid_rmdir_or_file(irp, IoStatus);
1018 break;
1019
1020 case CID_RMDIR_OR_FILE_RESP:
1021 devredir_proc_cid_rmdir_or_file_resp(irp, IoStatus);
1022 break;
1023
1024 case CID_RENAME_FILE:
1025 xstream_rd_u32_le(s, irp->FileId);
1026 devredir_proc_cid_rename_file(irp, IoStatus);
1027 break;
1028
1029 case CID_RENAME_FILE_RESP:
1030 devredir_proc_cid_rename_file_resp(irp, IoStatus);
1031 break;
1032
1033 case CID_LOOKUP:
1034 devredir_proc_cid_lookup(irp, s, IoStatus);
1035 break;
1036
1037 case CID_SETATTR:
1038 devredir_proc_cid_setattr(irp, s, IoStatus);
1039 break;
1040
1041 default:
1042 LOG_DEVEL(LOG_LEVEL_ERROR, "got unknown CompletionID: DeviceId=0x%x "
1043 "CompletionId=0x%x IoStatus=0x%x",
1044 DeviceId, CompletionId, IoStatus);
1045 break;
10701046 }
10711047 }
10721048 }
10811057 tui32 Length;
10821058 xstream_rd_u32_le(s_in, Length);
10831059
1084 if (IoStatus == NT_STATUS_SUCCESS)
1060 if (IoStatus == STATUS_SUCCESS)
10851061 {
10861062 unsigned int i;
10871063 /* process FILE_DIRECTORY_INFORMATION structures */
11101086
11111087 i += 64 + FileNameLength;
11121088
1113 //log_debug("LastAccessTime: 0x%llx", LastAccessTime);
1114 //log_debug("LastWriteTime: 0x%llx", LastWriteTime);
1115 //log_debug("EndOfFile: %lld", EndOfFile);
1116 //log_debug("FileAttributes: 0x%x", FileAttributes);
1117 //log_debug("FileNameLength: %d", FileNameLength);
1118 log_debug("FileName: %s", filename);
1089 //LOG_DEVEL(LOG_LEVEL_DEBUG, "LastAccessTime: 0x%llx", LastAccessTime);
1090 //LOG_DEVEL(LOG_LEVEL_DEBUG, "LastWriteTime: 0x%llx", LastWriteTime);
1091 //LOG_DEVEL(LOG_LEVEL_DEBUG, "EndOfFile: %lld", EndOfFile);
1092 //LOG_DEVEL(LOG_LEVEL_DEBUG, "FileAttributes: 0x%x", FileAttributes);
1093 //LOG_DEVEL(LOG_LEVEL_DEBUG, "FileNameLength: %d", FileNameLength);
1094 LOG_DEVEL(LOG_LEVEL_DEBUG, "FileName: %s", filename);
11191095
11201096 fattr.mode = WindowsToLinuxFilePerm(FileAttributes);
11211097 fattr.size = (size_t) EndOfFile;
11241100
11251101 /* add this entry to xrdp file system */
11261102 xfuse_devredir_cb_enum_dir_add_entry(
1127 (struct state_dirscan *) irp->fuse_info,
1128 filename, &fattr);
1103 (struct state_dirscan *) irp->fuse_info,
1104 filename, &fattr);
11291105 }
11301106
11311107 /* Ask for more directory entries */
11331109 }
11341110 else
11351111 {
1136 if (IoStatus == NT_STATUS_NO_MORE_FILES)
1137 {
1138 IoStatus = NT_STATUS_SUCCESS;
1112 if (IoStatus == STATUS_NO_MORE_FILES)
1113 {
1114 IoStatus = STATUS_SUCCESS;
11391115 }
11401116 xfuse_devredir_cb_enum_dir_done((struct state_dirscan *)irp->fuse_info,
11411117 IoStatus);
11901166 CreateDisposition = CD_FILE_OPEN;
11911167
11921168 rval = devredir_send_drive_create_request(device_id, irp->pathname,
1193 DesiredAccess, CreateOptions,
1194 0, CreateDisposition,
1195 irp->CompletionId);
1196
1197 log_debug("looking for device_id=%d path=%s", device_id, irp->pathname);
1198
1199 /* when we get a response to devredir_send_drive_create_request(), we
1169 DesiredAccess, CreateOptions,
1170 0, CreateDisposition,
1171 irp->CompletionId);
1172
1173 LOG_DEVEL(LOG_LEVEL_DEBUG, "looking for device_id=%d path=%s", device_id, irp->pathname);
1174
1175 /* when we get a response to devredir_send_drive_create_request(), we
12001176 * call devredir_send_drive_dir_request(), which needs the following
12011177 * at the end of the path argument */
12021178 if (devredir_string_ends_with(irp->pathname, '\\'))
12321208 int rval = -1;
12331209 IRP *irp;
12341210
1235 log_debug("fusep=%p", fusep);
1211 LOG_DEVEL(LOG_LEVEL_DEBUG, "fusep=%p", fusep);
12361212
12371213 if ((irp = devredir_irp_with_pathname_new(path)) != NULL)
12381214 {
12531229 CreateOptions = 0;
12541230 CreateDisposition = CD_FILE_OPEN;
12551231
1256 log_debug("lookup for device_id=%d path=%s CompletionId=%d",
1232 LOG_DEVEL(LOG_LEVEL_DEBUG, "lookup for device_id=%d path=%s CompletionId=%d",
12571233 device_id, irp->pathname, irp->CompletionId);
12581234
12591235 rval = devredir_send_drive_create_request(device_id,
1260 irp->pathname,
1261 DesiredAccess, CreateOptions,
1262 0, CreateDisposition,
1263 irp->CompletionId);
1236 irp->pathname,
1237 DesiredAccess, CreateOptions,
1238 0, CreateDisposition,
1239 irp->CompletionId);
12641240 }
12651241
12661242 return rval;
12901266 int rval = -1;
12911267 IRP *irp;
12921268
1293 log_debug("fusep=%p", fusep);
1269 LOG_DEVEL(LOG_LEVEL_DEBUG, "fusep=%p", fusep);
12941270
12951271 if ((irp = devredir_irp_with_pathname_new(filename)) != NULL)
12961272 {
13221298 CreateOptions = 0;
13231299 CreateDisposition = CD_FILE_OPEN;
13241300
1325 log_debug("lookup for device_id=%d path=%s",
1301 LOG_DEVEL(LOG_LEVEL_DEBUG, "lookup for device_id=%d path=%s",
13261302 device_id, irp->pathname);
13271303
13281304 rval = devredir_send_drive_create_request(device_id,
1329 irp->pathname,
1330 DesiredAccess, CreateOptions,
1331 0, CreateDisposition,
1332 irp->CompletionId);
1305 irp->pathname,
1306 DesiredAccess, CreateOptions,
1307 0, CreateDisposition,
1308 irp->CompletionId);
13331309 }
13341310
13351311 return rval;
13461322 int rval = -1;
13471323 IRP *irp;
13481324
1349 log_debug("device_id=%d path=%s mode=0%o", device_id, path, mode);
1325 LOG_DEVEL(LOG_LEVEL_DEBUG, "device_id=%d path=%s mode=0%o", device_id, path, mode);
13501326
13511327 if ((irp = devredir_irp_with_pathname_new(path)) != NULL)
13521328 {
13581334 irp->DeviceId = device_id;
13591335 irp->fuse_info = fusep;
13601336
1337
13611338 DesiredAccess = 0x0016019f; /* got this value from windows */
13621339 FileAttributes = LinuxToWindowsFilePerm(mode);
13631340 if (mode & S_IFDIR)
13641341 {
1365 log_debug("creating dir");
1342 LOG_DEVEL(LOG_LEVEL_DEBUG, "creating dir");
13661343 CreateOptions = CO_FILE_DIRECTORY_FILE | CO_FILE_SYNCHRONOUS_IO_NONALERT;
13671344 irp->gen.create.creating_dir = 1;
13681345 }
13691346 else
13701347 {
1371 log_debug("creating file");
1348 LOG_DEVEL(LOG_LEVEL_DEBUG, "creating file");
13721349 CreateOptions = 0x44; /* got this value from windows */
13731350 irp->gen.create.creating_dir = 0;
13741351 }
13771354 CreateDisposition = 0x02; /* got this value from windows */
13781355
13791356 rval = devredir_send_drive_create_request(device_id, path,
1380 DesiredAccess, CreateOptions,
1381 FileAttributes,
1382 CreateDisposition,
1383 irp->CompletionId);
1357 DesiredAccess, CreateOptions,
1358 FileAttributes,
1359 CreateDisposition,
1360 irp->CompletionId);
13841361 }
13851362
13861363 return rval;
13971374 int rval = -1;
13981375 IRP *irp;
13991376
1400 log_debug("device_id=%d path=%s flags=0%x",
1377 LOG_DEVEL(LOG_LEVEL_DEBUG, "device_id=%d path=%s flags=0%x",
14011378 device_id, path, flags);
14021379
14031380 if ((irp = devredir_irp_with_pathname_new(path)) != NULL)
14111388
14121389 irp->fuse_info = fusep;
14131390
1414 switch(flags & O_ACCMODE)
1391 switch (flags & O_ACCMODE)
14151392 {
14161393 case O_RDONLY:
1417 log_debug("open file in O_RDONLY");
1394 LOG_DEVEL(LOG_LEVEL_DEBUG, "open file in O_RDONLY");
14181395 DesiredAccess = DA_FILE_READ_DATA | DA_SYNCHRONIZE;
14191396 break;
14201397
14211398 case O_WRONLY:
1422 log_debug("open file in O_WRONLY");
1399 LOG_DEVEL(LOG_LEVEL_DEBUG, "open file in O_WRONLY");
14231400 DesiredAccess = DA_FILE_WRITE_DATA | DA_SYNCHRONIZE;
14241401 break;
14251402
14281405 * The access mode could conceivably be invalid here,
14291406 * but we assume this has been checked by the caller
14301407 */
1431 log_debug("open file in O_RDWR");
1408 LOG_DEVEL(LOG_LEVEL_DEBUG, "open file in O_RDWR");
14321409 /* without the 0x00000010 rdesktop opens files in */
14331410 /* O_RDONLY instead of O_RDWR mode */
1434 DesiredAccess = DA_FILE_READ_DATA | DA_FILE_WRITE_DATA |
1411 DesiredAccess = DA_FILE_READ_DATA | DA_FILE_WRITE_DATA |
14351412 DA_SYNCHRONIZE | 0x00000010;
14361413 }
14371414
14391416 CreateDisposition = CD_FILE_OPEN; // WAS 1
14401417
14411418 rval = devredir_send_drive_create_request(device_id, path,
1442 DesiredAccess, CreateOptions,
1443 FileAttributes,
1444 CreateDisposition,
1445 irp->CompletionId);
1419 DesiredAccess, CreateOptions,
1420 FileAttributes,
1421 CreateDisposition,
1422 irp->CompletionId);
14461423 }
14471424
14481425 return rval;
14531430 {
14541431 IRP *irp;
14551432
1456 log_debug("entered: fusep=%p device_id=%d FileId=%d",
1433 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: fusep=%p device_id=%d FileId=%d",
14571434 fusep, device_id, FileId);
14581435
14591436 #if 0
14601437 if ((irp = devredir_irp_new()) == NULL)
1438 {
14611439 return -1;
1440 }
14621441
14631442 irp->CompletionId = g_completion_id++;
14641443 #else
14651444 if ((irp = devredir_irp_find_by_fileid(FileId)) == NULL)
14661445 {
1467 log_error("no IRP found with FileId = %d", FileId);
1446 LOG_DEVEL(LOG_LEVEL_ERROR, "no IRP found with FileId = %d", FileId);
14681447 return -1;
14691448 }
14701449 #endif
14731452 irp->fuse_info = fusep;
14741453
14751454 return devredir_send_drive_close_request(RDPDR_CTYP_CORE,
1476 PAKID_CORE_DEVICE_IOREQUEST,
1477 device_id,
1478 FileId,
1479 irp->CompletionId,
1480 IRP_MJ_CLOSE,
1481 IRP_MN_NONE, 32);
1455 PAKID_CORE_DEVICE_IOREQUEST,
1456 device_id,
1457 FileId,
1458 irp->CompletionId,
1459 IRP_MJ_CLOSE,
1460 IRP_MN_NONE, 32);
14821461 }
14831462
14841463 /**
15171496 CreateDisposition = 0x01; /* got this value from windows */
15181497
15191498 rval = devredir_send_drive_create_request(device_id, path,
1520 DesiredAccess, CreateOptions,
1521 0, CreateDisposition,
1522 irp->CompletionId);
1499 DesiredAccess, CreateOptions,
1500 0, CreateDisposition,
1501 irp->CompletionId);
15231502 }
15241503
15251504 return rval;
15281507 /**
15291508 * Read data from previously opened file
15301509 *
1531 * @return 0 on success, -1 on failure
1510 * Errors are reported via xfuse_devredir_cb_read_file()
15321511 *****************************************************************************/
15331512
1534 int
1513 void
15351514 devredir_file_read(struct state_read *fusep, tui32 DeviceId, tui32 FileId,
15361515 tui32 Length, tui64 Offset)
15371516 {
15391518 IRP *irp;
15401519 IRP *new_irp;
15411520 int bytes;
1542 int rval = -1;
15431521
15441522 xstream_new(s, 1024);
15451523
15461524 /* Check we've got an open IRP for this file already */
15471525 if ((irp = devredir_irp_find_by_fileid(FileId)) == NULL)
15481526 {
1549 log_error("no IRP found with FileId = %d", FileId);
1550 xfuse_devredir_cb_read_file(fusep, NULL, 0);
1527 LOG_DEVEL(LOG_LEVEL_ERROR, "no IRP found with FileId = %d", FileId);
1528 xfuse_devredir_cb_read_file(fusep, STATUS_UNSUCCESSFUL, NULL, 0);
15511529 xstream_free(s);
15521530 }
15531531 /* create a new IRP for this request */
15541532 else if ((new_irp = devredir_irp_new()) == NULL)
15551533 {
15561534 /* system out of memory */
1557 xfuse_devredir_cb_read_file(fusep, NULL, 0);
1535 xfuse_devredir_cb_read_file(fusep, STATUS_UNSUCCESSFUL, NULL, 0);
15581536 xstream_free(s);
15591537 }
15601538 else
15801558 bytes = xstream_len(s);
15811559 send_channel_data(g_rdpdr_chan_id, s->data, bytes);
15821560 xstream_free(s);
1583 rval = 0;
1584 }
1585
1586 return rval;
1587 }
1588
1589 int
1561 }
1562 }
1563
1564 /**
1565 * Read data from previously opened file
1566 *
1567 * Errors are reported via xfuse_devredir_cb_write_file()
1568 *****************************************************************************/
1569
1570 void
15901571 devredir_file_write(struct state_write *fusep, tui32 DeviceId, tui32 FileId,
15911572 const char *buf, int Length, tui64 Offset)
15921573 {
15941575 IRP *irp;
15951576 IRP *new_irp;
15961577 int bytes;
1597 int rval = -1;
1598
1599 log_debug("DeviceId=%d FileId=%d Length=%d Offset=%lld",
1578
1579 LOG_DEVEL(LOG_LEVEL_DEBUG, "DeviceId=%d FileId=%d Length=%d Offset=%lld",
16001580 DeviceId, FileId, Length, (long long)Offset);
16011581
16021582 xstream_new(s, 1024 + Length);
16031583
16041584 if ((irp = devredir_irp_find_by_fileid(FileId)) == NULL)
16051585 {
1606 log_error("no IRP found with FileId = %d", FileId);
1607 xfuse_devredir_cb_write_file(fusep, NT_STATUS_UNSUCCESSFUL, 0, 0);
1586 LOG_DEVEL(LOG_LEVEL_ERROR, "no IRP found with FileId = %d", FileId);
1587 xfuse_devredir_cb_write_file(fusep, STATUS_UNSUCCESSFUL, 0, 0);
16081588 xstream_free(s);
16091589 }
16101590 /* create a new IRP for this request */
16111591 else if ((new_irp = devredir_irp_new()) == NULL)
16121592 {
16131593 /* system out of memory */
1614 xfuse_devredir_cb_write_file(fusep, NT_STATUS_UNSUCCESSFUL, 0, 0);
1594 xfuse_devredir_cb_write_file(fusep, STATUS_UNSUCCESSFUL, 0, 0);
16151595 xstream_free(s);
16161596 }
16171597 else
16421622 bytes = xstream_len(s);
16431623 send_channel_data(g_rdpdr_chan_id, s->data, bytes);
16441624 xstream_free(s);
1645 rval = 0;
1646 }
1647
1648 return rval;
1625 }
1626
16491627 }
16501628
16511629
16601638 int rval = -1;
16611639 IRP *irp;
16621640 unsigned int len;
1663
1664 log_debug("device_id=%d old_name=%s new_name=%s",
1641
1642 LOG_DEVEL(LOG_LEVEL_DEBUG, "device_id=%d old_name=%s new_name=%s",
16651643 device_id, old_name, new_name);
16661644
16671645 /*
16961674 CreateDisposition = CD_FILE_OPEN; // WAS 1
16971675
16981676 rval = devredir_send_drive_create_request(device_id, old_name,
1699 DesiredAccess, CreateOptions,
1700 FileAttributes,
1701 CreateDisposition,
1702 irp->CompletionId);
1677 DesiredAccess, CreateOptions,
1678 FileAttributes,
1679 CreateDisposition,
1680 irp->CompletionId);
17031681 }
17041682
17051683 return rval;
17401718 while (*cptr != 0)
17411719 {
17421720 if (*cptr == '/')
1721 {
17431722 *cptr = '\\';
1723 }
17441724 cptr++;
17451725 }
17461726 }
18231803 struct stream *s;
18241804 int bytes;
18251805
1826 if (IoStatus != NT_STATUS_SUCCESS)
1806 if (IoStatus != STATUS_SUCCESS)
18271807 {
18281808 xfuse_devredir_cb_rmdir_or_file((struct state_remove *) irp->fuse_info,
1829 IoStatus);
1809 IoStatus);
18301810 devredir_irp_delete(irp);
18311811 return;
18321812 }
18561836 xfuse_devredir_cb_rmdir_or_file((struct state_remove *)irp->fuse_info,
18571837 IoStatus);
18581838
1859 if (IoStatus != NT_STATUS_SUCCESS)
1839 if (IoStatus != STATUS_SUCCESS)
18601840 {
18611841 devredir_irp_delete(irp);
18621842 return;
18801860 int flen; /* FileNameLength */
18811861
18821862
1883 if (IoStatus != NT_STATUS_SUCCESS)
1884 {
1885 log_debug("rename returned with IoStatus=0x%x", IoStatus);
1863 if (IoStatus != STATUS_SUCCESS)
1864 {
1865 LOG_DEVEL(LOG_LEVEL_DEBUG, "rename returned with IoStatus=0x%x", IoStatus);
18861866
18871867 xfuse_devredir_cb_rename_file((struct state_rename *)irp->fuse_info,
18881868 IoStatus);
18921872
18931873 /* Path in unicode needs this much space */
18941874 flen = ((g_mbstowcs(NULL, irp->gen.rename.new_name, 0)
1895 * sizeof(twchar)) / 2) + 2;
1875 * sizeof(twchar)) / 2) + 2;
18961876 sblen = 6 + flen;
18971877
18981878 xstream_new(s, 1024 + flen);
19241904 static void
19251905 devredir_proc_cid_rename_file_resp(IRP *irp, enum NTSTATUS IoStatus)
19261906 {
1927 log_debug("entered");
1928
19291907 xfuse_devredir_cb_rename_file((struct state_rename *)irp->fuse_info,
19301908 IoStatus);
19311909
1932 if (IoStatus != NT_STATUS_SUCCESS)
1910 if (IoStatus != STATUS_SUCCESS)
19331911 {
19341912 devredir_irp_delete(irp);
19351913 return;
19371915
19381916 irp->completion_type = CID_CLOSE;
19391917 devredir_send_drive_close_request(RDPDR_CTYP_CORE,
1940 PAKID_CORE_DEVICE_IOREQUEST,
1941 irp->DeviceId,
1942 irp->FileId,
1943 irp->CompletionId,
1944 IRP_MJ_CLOSE, IRP_MN_NONE, 32);
1918 PAKID_CORE_DEVICE_IOREQUEST,
1919 irp->DeviceId,
1920 irp->FileId,
1921 irp->CompletionId,
1922 IRP_MJ_CLOSE, IRP_MN_NONE, 32);
19451923 }
19461924
19471925
19851963 tui64 LastWriteTime;
19861964 tui32 FileAttributes;
19871965
1988 log_debug("processing FILE_BASIC_INFORMATION");
1966 LOG_DEVEL(LOG_LEVEL_DEBUG, "processing FILE_BASIC_INFORMATION");
19891967
19901968 xstream_seek(s_in, 8); /* CreationTime */
19911969 xstream_rd_u64_le(s_in, LastAccessTime);
19931971 xstream_seek(s_in, 8); /* ChangeTime */
19941972 xstream_rd_u32_le(s_in, FileAttributes);
19951973
1996 //log_debug("LastAccessTime: 0x%llx",
1974 //LOG_DEVEL(LOG_LEVEL_DEBUG, "LastAccessTime: 0x%llx",
19971975 // (unsigned long long)LastAccessTime);
1998 //log_debug("LastWriteTime: 0x%llx",
1976 //LOG_DEVEL(LOG_LEVEL_DEBUG, "LastWriteTime: 0x%llx",
19991977 // (unsigned long long)LastWriteTime);
2000 //log_debug("ChangeTime: 0x%llx",
1978 //LOG_DEVEL(LOG_LEVEL_DEBUG, "ChangeTime: 0x%llx",
20011979 // (unsigned long long)ChangeTime);
2002 //log_debug("FileAttributes: 0x%x", (unsigned int)FileAttributes);
1980 //LOG_DEVEL(LOG_LEVEL_DEBUG, "FileAttributes: 0x%x", (unsigned int)FileAttributes);
20031981
20041982 /* Save the basic attributes in the IRP */
20051983 irp->gen.lookup.fattr.mode = WindowsToLinuxFilePerm(FileAttributes);
20131991 static void lookup_read_standard_attributes(IRP *irp, struct stream *s_in)
20141992 {
20151993 tui64 EndOfFile;
2016 log_debug("processing FILE_STD_INFORMATION");
1994 LOG_DEVEL(LOG_LEVEL_DEBUG, "processing FILE_STD_INFORMATION");
20171995 xstream_seek(s_in, 8); /* AllocationSize */
20181996 xstream_rd_u64_le(s_in, EndOfFile);
2019 //log_debug("EndOfFile: %lld",
1997 //LOG_DEVEL(LOG_LEVEL_DEBUG, "EndOfFile: %lld",
20201998 // (unsigned long long)EndOfFile);
20211999
20222000 irp->gen.lookup.fattr.size = EndOfFile;
20252003 /*
20262004 * Completes a lookup request and returns status to the caller.
20272005 *
2028 * Unless IoStatus is NT_STATUS_SUCCESS, the lookup has failed.
2006 * Unless IoStatus is STATUS_SUCCESS, the lookup has failed.
20292007 *****************************************************************************/
20302008 static void lookup_done(IRP *irp, enum NTSTATUS IoStatus)
20312009 {
2032 log_debug("Lookup with completion_id=%d returning 0x%x",
2033 irp->CompletionId, IoStatus);
2010 LOG_DEVEL(LOG_LEVEL_DEBUG, "Lookup with completion_id=%d returning 0x%x",
2011 irp->CompletionId, IoStatus);
20342012 xfuse_devredir_cb_lookup_entry((struct state_lookup *)irp->fuse_info,
20352013 IoStatus,
20362014 &irp->gen.lookup.fattr);
20452023 /* Close the file handle */
20462024 irp->completion_type = CID_CLOSE;
20472025 devredir_send_drive_close_request(RDPDR_CTYP_CORE,
2048 PAKID_CORE_DEVICE_IOREQUEST,
2049 irp->DeviceId,
2050 irp->FileId,
2051 irp->CompletionId,
2052 IRP_MJ_CLOSE, IRP_MN_NONE, 32);
2026 PAKID_CORE_DEVICE_IOREQUEST,
2027 irp->DeviceId,
2028 irp->FileId,
2029 irp->CompletionId,
2030 IRP_MJ_CLOSE, IRP_MN_NONE, 32);
20532031 }
20542032 }
20552033
20652043 {
20662044 tui32 Length;
20672045
2068 log_debug("entry state is %d",irp->gen.lookup.state);
2069 if (IoStatus != NT_STATUS_SUCCESS)
2046 LOG_DEVEL(LOG_LEVEL_DEBUG, "entry state is %d", irp->gen.lookup.state);
2047 if (IoStatus != STATUS_SUCCESS)
20702048 {
20712049 /* This is common to all setattr states */
2072 log_debug("last lookup returned with IoStatus=0x%08x", IoStatus);
2050 LOG_DEVEL(LOG_LEVEL_DEBUG, "last lookup returned with IoStatus=0x%08x", IoStatus);
20732051 lookup_done(irp, IoStatus);
20742052 }
20752053 else
20762054 {
20772055 /* Read and validate any data we've got queued up */
2078 switch(irp->gen.lookup.state)
2056 switch (irp->gen.lookup.state)
20792057 {
20802058 case E_LOOKUP_GET_FH:
20812059 /* We've been sent the file ID */
20892067 xstream_rd_u32_le(s_in, Length);
20902068 if (Length != FILE_BASIC_INFORMATION_SIZE)
20912069 {
2092 log_error("Expected FILE_BASIC_INFORMATION length"
2070 LOG_DEVEL(LOG_LEVEL_ERROR, "Expected FILE_BASIC_INFORMATION length"
20932071 "%d, got len=%d",
20942072 FILE_BASIC_INFORMATION_SIZE, Length);
2095 IoStatus = NT_STATUS_UNSUCCESSFUL;
2073 IoStatus = STATUS_UNSUCCESSFUL;
20962074 lookup_done(irp, IoStatus);
20972075 }
20982076 else
21082086 xstream_rd_u32_le(s_in, Length);
21092087 if (Length != FILE_STD_INFORMATION_SIZE)
21102088 {
2111 log_error("Expected FILE_STD_INFORMATION length"
2089 LOG_DEVEL(LOG_LEVEL_ERROR, "Expected FILE_STD_INFORMATION length"
21122090 "%d, got len=%d",
21132091 FILE_STD_INFORMATION_SIZE, Length);
2114 IoStatus = NT_STATUS_UNSUCCESSFUL;
2092 IoStatus = STATUS_UNSUCCESSFUL;
21152093 }
21162094 else
21172095 {
21602138
21612139 xstream_wr_u32_le(s, FileBasicInformation);
21622140 xstream_wr_u32_le(s, FILE_BASIC_INFORMATION_SIZE);
2163 /* buffer length */
2141 /* buffer length */
21642142 xstream_seek(s, 24); /* padding */
21652143
21662144 xstream_wr_u64_le(s, 0LL); /* CreationTime */
21932171
21942172 xstream_wr_u32_le(s, FileEndOfFileInformation);
21952173 xstream_wr_u32_le(s, FILE_END_OF_FILE_INFORMATION_SIZE);
2196 /* buffer length */
2174 /* buffer length */
21972175 xstream_seek(s, 24); /* padding */
21982176 xstream_wr_u64_le(s, (tui64)irp->gen.setattr.fattr.size);
2199 /* File size */
2177 /* File size */
22002178 /* send to client */
22012179 bytes = xstream_len(s);
22022180 send_channel_data(g_rdpdr_chan_id, s->data, bytes);
22212199 /* Close the file handle */
22222200 irp->completion_type = CID_CLOSE;
22232201 devredir_send_drive_close_request(RDPDR_CTYP_CORE,
2224 PAKID_CORE_DEVICE_IOREQUEST,
2225 irp->DeviceId,
2226 irp->FileId,
2227 irp->CompletionId,
2228 IRP_MJ_CLOSE, IRP_MN_NONE, 32);
2202 PAKID_CORE_DEVICE_IOREQUEST,
2203 irp->DeviceId,
2204 irp->FileId,
2205 irp->CompletionId,
2206 IRP_MJ_CLOSE, IRP_MN_NONE, 32);
22292207 }
22302208 }
22312209
22432221 TO_SET_ATIME | TO_SET_MTIME)
22442222 tui32 Length;
22452223
2246 log_debug("entry state is %d",irp->gen.setattr.state);
2247 if (IoStatus != NT_STATUS_SUCCESS)
2224 LOG_DEVEL(LOG_LEVEL_DEBUG, "entry state is %d", irp->gen.setattr.state);
2225 if (IoStatus != STATUS_SUCCESS)
22482226 {
22492227 /* This is common to all setattr states */
2250 log_debug("last setattr returned with IoStatus=0x%08x", IoStatus);
2228 LOG_DEVEL(LOG_LEVEL_DEBUG, "last setattr returned with IoStatus=0x%08x", IoStatus);
22512229 setattr_done(irp, IoStatus);
22522230 }
22532231 else
22542232 {
22552233 /* Read and validate any data we've got queued up */
2256 switch(irp->gen.setattr.state)
2234 switch (irp->gen.setattr.state)
22572235 {
22582236 case E_SETATTR_GET_FH:
22592237 /* We've been sent the file ID */
22652243 xstream_rd_u32_le(s_in, Length);
22662244 if (Length != FILE_BASIC_INFORMATION_SIZE)
22672245 {
2268 log_error("Expected FILE_BASIC_INFORMATION length"
2246 LOG_DEVEL(LOG_LEVEL_ERROR, "Expected FILE_BASIC_INFORMATION length"
22692247 "%d, got len=%d",
22702248 FILE_BASIC_INFORMATION_SIZE, Length);
22712249 }
22792257 xstream_rd_u32_le(s_in, Length);
22802258 if (Length != FILE_END_OF_FILE_INFORMATION_SIZE)
22812259 {
2282 log_error("Expected FILE_END_OF_FILE_INFORMATION length"
2260 LOG_DEVEL(LOG_LEVEL_ERROR, "Expected FILE_END_OF_FILE_INFORMATION length"
22832261 "%d, got len=%d",
22842262 FILE_END_OF_FILE_INFORMATION_SIZE, Length);
22852263 }
7777 int devredir_file_close(struct state_close *fusep, tui32 device_id,
7878 tui32 file_id);
7979
80 int devredir_file_read(struct state_read *fusep, tui32 device_id, tui32 FileId,
81 tui32 Length, tui64 Offset);
80 void
81 devredir_file_read(struct state_read *fusep, tui32 device_id, tui32 FileId,
82 tui32 Length, tui64 Offset);
8283
83 int
84 void
8485 devredir_file_write(struct state_write *fusep, tui32 DeviceId, tui32 FileId,
85 const char *buf, int Length, tui64 Offset);
86 const char *buf, int Length, tui64 Offset);
8687
8788 int devredir_file_rename(
8889 struct state_rename *fusep, tui32 device_id,
1515 * limitations under the License.
1616 */
1717
18 /* FIFO implementation to store a pointer to a user struct */
18 /* FIFO implementation to store a pointer to a user struct */
1919
2020 /* module based logging */
2121 #if defined(HAVE_CONFIG_H)
2525 #define MODULE_NAME "FIFO "
2626 #define LOCAL_DEBUG
2727
28 #include "chansrv.h"
2829 #include "fifo.h"
29 #include "mlog.h"
3030 #include "os_calls.h"
3131
3232 /**
3838 * @return 0 on success, -1 on failure
3939 *****************************************************************************/
4040 int
41 fifo_init(FIFO* fp, int num_entries)
42 {
43 log_debug_high("entered");
41 fifo_init(FIFO *fp, int num_entries)
42 {
43 LOG_DEVEL(LOG_LEVEL_TRACE, "entered");
4444
4545 /* validate params */
4646 if (!fp)
4747 {
48 log_debug_high("invalid parameters");
48 LOG_DEVEL(LOG_LEVEL_TRACE, "invalid parameters");
4949 return -1;
5050 }
5151
5252 if (num_entries < 1)
53 {
5354 num_entries = 10;
55 }
5456
5557 fp->rd_ptr = 0;
5658 fp->wr_ptr = 0;
5961 if (fp->user_data)
6062 {
6163 fp->entries = num_entries;
62 log_debug_low("FIFO created; rd_ptr=%d wr_ptr=%d entries=%d",
63 fp->rd_ptr, fp->wr_ptr, fp->entries);
64 LOG_DEVEL(LOG_LEVEL_DEBUG, "FIFO created; rd_ptr=%d wr_ptr=%d entries=%d",
65 fp->rd_ptr, fp->wr_ptr, fp->entries);
6466 return 0;
6567 }
6668 else
6769 {
68 log_error("FIFO create error; system out of memory");
70 LOG_DEVEL(LOG_LEVEL_ERROR, "FIFO create error; system out of memory");
6971 fp->entries = 0;
7072 return -1;
7173 }
7981 * @return 0 on success, -1 on error
8082 *****************************************************************************/
8183 int
82 fifo_deinit(FIFO* fp)
83 {
84 log_debug_high("entered");
85
86 if (!fp)
87 {
88 log_debug_high("FIFO is null");
84 fifo_deinit(FIFO *fp)
85 {
86 LOG_DEVEL(LOG_LEVEL_TRACE, "entered");
87
88 if (!fp)
89 {
90 LOG_DEVEL(LOG_LEVEL_TRACE, "FIFO is null");
8991 return -1;
9092 }
9193
109111 * @return 1 if FIFO is empty, 0 otherwise
110112 *****************************************************************************/
111113 int
112 fifo_is_empty(FIFO* fp)
113 {
114 log_debug_high("entered");
115
116 if (!fp)
117 {
118 log_debug_high("FIFO is null");
114 fifo_is_empty(FIFO *fp)
115 {
116 LOG_DEVEL(LOG_LEVEL_TRACE, "entered");
117
118 if (!fp)
119 {
120 LOG_DEVEL(LOG_LEVEL_TRACE, "FIFO is null");
119121 return 0;
120122 }
121123
132134 *****************************************************************************/
133135
134136 int
135 fifo_insert(FIFO* fp, void* data)
136 {
137 long* lp;
137 fifo_insert(FIFO *fp, void *data)
138 {
139 long *lp;
138140 int next_val; /* next value for wr_ptr */
139141 int i;
140142
141 log_debug_high("entered");
142
143 if (!fp)
144 {
145 log_debug_high("FIFO is null");
143 LOG_DEVEL(LOG_LEVEL_TRACE, "entered");
144
145 if (!fp)
146 {
147 LOG_DEVEL(LOG_LEVEL_TRACE, "FIFO is null");
146148 return -1;
147149 }
148150
149151 next_val = fp->wr_ptr + 1;
150152 if (next_val >= fp->entries)
153 {
151154 next_val = 0;
155 }
152156
153157 if (next_val == fp->rd_ptr)
154158 {
156160 lp = (long *) g_malloc(sizeof(long) * (fp->entries + 10), 1);
157161 if (!lp)
158162 {
159 log_debug_low("FIFO full; cannot expand, no memory");
163 LOG_DEVEL(LOG_LEVEL_DEBUG, "FIFO full; cannot expand, no memory");
160164 return -1;
161165 }
162166
163 log_debug_low("FIFO full, expanding by 10 entries");
167 LOG_DEVEL(LOG_LEVEL_DEBUG, "FIFO full, expanding by 10 entries");
164168
165169 /* copy old data new location */
166170 for (i = 0; i < (fp->entries - 1); i++)
167171 {
168172 lp[i] = fp->user_data[fp->rd_ptr++];
169173 if (fp->rd_ptr >= fp->entries)
174 {
170175 fp->rd_ptr = 0;
176 }
171177 }
172178
173179 /* update pointers */
181187 fp->user_data = lp;
182188 }
183189
184 log_debug_low("inserting data at index %d", fp->wr_ptr);
190 LOG_DEVEL(LOG_LEVEL_DEBUG, "inserting data at index %d", fp->wr_ptr);
185191
186192 fp->user_data[fp->wr_ptr] = (long) data;
187193 fp->wr_ptr = next_val;
196202 *
197203 * @param data on success, NULL on error
198204 *****************************************************************************/
199 void*
200 fifo_remove(FIFO* fp)
205 void *
206 fifo_remove(FIFO *fp)
201207 {
202208 long data;
203209
204 log_debug_high("entered");
205
206 if (!fp)
207 {
208 log_debug_high("FIFO is null");
210 LOG_DEVEL(LOG_LEVEL_TRACE, "entered");
211
212 if (!fp)
213 {
214 LOG_DEVEL(LOG_LEVEL_TRACE, "FIFO is null");
209215 return 0;
210216 }
211217
212218 if (fp->rd_ptr == fp->wr_ptr)
213219 {
214 log_debug_high("FIFO is empty");
215 return 0;
216 }
217
218 log_debug_low("removing data at index %d", fp->rd_ptr);
220 LOG_DEVEL(LOG_LEVEL_TRACE, "FIFO is empty");
221 return 0;
222 }
223
224 LOG_DEVEL(LOG_LEVEL_DEBUG, "removing data at index %d", fp->rd_ptr);
219225
220226 data = fp->user_data[fp->rd_ptr++];
221227
222228 if (fp->rd_ptr >= fp->entries)
223229 {
224 log_debug_high("FIFO rd_ptr wrapped around");
230 LOG_DEVEL(LOG_LEVEL_TRACE, "FIFO rd_ptr wrapped around");
225231 fp->rd_ptr = 0;
226232 }
227233
235241 *
236242 * @param data on success, NULL on error
237243 *****************************************************************************/
238 void*
239 fifo_peek(FIFO* fp)
240 {
241 log_debug_high("entered");
242
243 if (!fp)
244 {
245 log_debug_high("FIFO is null");
244 void *
245 fifo_peek(FIFO *fp)
246 {
247 LOG_DEVEL(LOG_LEVEL_TRACE, "entered");
248
249 if (!fp)
250 {
251 LOG_DEVEL(LOG_LEVEL_TRACE, "FIFO is null");
246252 return 0;
247253 }
248254
249255 if (fp->rd_ptr == fp->wr_ptr)
250256 {
251 log_debug_high("FIFO is empty");
252 return 0;
253 }
254
255 log_debug_low("peeking data at index %d", fp->rd_ptr);
257 LOG_DEVEL(LOG_LEVEL_TRACE, "FIFO is empty");
258 return 0;
259 }
260
261 LOG_DEVEL(LOG_LEVEL_DEBUG, "peeking data at index %d", fp->rd_ptr);
256262
257263 return (void *) fp->user_data[fp->rd_ptr];
258264 }
2424 #include <config_ac.h>
2525 #endif
2626
27 #include "chansrv.h"
2728 #include "parse.h"
2829 #include "os_calls.h"
30 #include "string_calls.h"
2931 #include "irp.h"
3032
31 /* module based logging */
32 #define LOG_ERROR 0
33 #define LOG_INFO 1
34 #define LOG_DEBUG 2
35
36 #ifndef LOG_LEVEL
37 #define LOG_LEVEL LOG_ERROR
38 #endif
39
40 #define log_error(_params...) \
41 { \
42 g_write("[%10.10u]: IRP %s: %d : ERROR: ", \
43 g_time3(), __func__, __LINE__); \
44 g_writeln (_params); \
45 }
46
47 #define log_info(_params...) \
48 { \
49 if (LOG_INFO <= LOG_LEVEL) \
50 { \
51 g_write("[%10.10u]: IRP %s: %d : ", \
52 g_time3(), __func__, __LINE__); \
53 g_writeln (_params); \
54 } \
55 }
56
57 #define log_debug(_params...) \
58 { \
59 if (LOG_DEBUG <= LOG_LEVEL) \
60 { \
61 g_write("[%10.10u]: IRP %s: %d : ", \
62 g_time3(), __func__, __LINE__); \
63 g_writeln (_params); \
64 } \
65 }
66
6733 IRP *g_irp_head = NULL;
6834
6935 /**
7238 * @return new IRP or NULL on error
7339 *****************************************************************************/
7440
75 IRP * devredir_irp_new(void)
41 IRP *devredir_irp_new(void)
7642 {
7743 IRP *irp;
7844 IRP *irp_last;
7945
80 log_debug("entered");
46 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered");
8147
8248 /* create new IRP */
8349 irp = g_new0(IRP, 1);
8450 if (irp == NULL)
8551 {
86 log_error("system out of memory!");
52 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory!");
8753 return NULL;
8854 }
8955
9965 irp->prev = irp_last;
10066 }
10167
102 log_debug("new IRP=%p", irp);
68 LOG_DEVEL(LOG_LEVEL_DEBUG, "new IRP=%p", irp);
10369 return irp;
10470 }
10571
11278 * @return new IRP or NULL on error
11379 *****************************************************************************/
11480
115 IRP * devredir_irp_with_pathname_new(const char *pathname)
81 IRP *devredir_irp_with_pathname_new(const char *pathname)
11682 {
11783 unsigned int len = g_strlen(pathname);
118 IRP * irp = devredir_irp_with_pathnamelen_new(len);
84 IRP *irp = devredir_irp_with_pathnamelen_new(len);
11985 if (irp != NULL)
12086 {
12187 g_strcpy(irp->pathname, pathname);
134100 * @return new IRP or NULL on error
135101 *****************************************************************************/
136102
137 IRP * devredir_irp_with_pathnamelen_new(unsigned int pathnamelen)
103 IRP *devredir_irp_with_pathnamelen_new(unsigned int pathnamelen)
138104 {
139105 IRP *irp;
140106 IRP *irp_last;
141107
142 log_debug("entered");
108 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered");
143109
144110 /* create new IRP with space on end for the pathname and a terminator */
145111 irp = (IRP *)g_malloc(sizeof(IRP) + (pathnamelen + 1), 1);
146112 if (irp == NULL)
147113 {
148 log_error("system out of memory!");
114 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory!");
149115 return NULL;
150116 }
151117
163129 irp->prev = irp_last;
164130 }
165131
166 log_debug("new IRP=%p", irp);
132 LOG_DEVEL(LOG_LEVEL_DEBUG, "new IRP=%p", irp);
167133 return irp;
168134 }
169135
178144 IRP *lirp = g_irp_head;
179145
180146 if ((irp == NULL) || (lirp == NULL))
147 {
181148 return -1;
182
183 log_debug("irp=%p completion_id=%d type=%d",
149 }
150
151 LOG_DEVEL(LOG_LEVEL_DEBUG, "irp=%p completion_id=%d type=%d",
184152 irp, irp->CompletionId, irp->completion_type);
185153
186154 devredir_irp_dump(); // LK_TODO
188156 while (lirp)
189157 {
190158 if (lirp == irp)
159 {
191160 break;
161 }
192162
193163 lirp = lirp->next;
194164 }
195165
196166 if (lirp == NULL)
197 return -1; /* did not find specified irp */
167 {
168 return -1; /* did not find specified irp */
169 }
198170
199171 if (lirp->prev == NULL)
200172 {
243215 {
244216 if (irp->CompletionId == completion_id)
245217 {
246 log_debug("returning irp=%p", irp);
218 LOG_DEVEL(LOG_LEVEL_DEBUG, "returning irp=%p", irp);
247219 return irp;
248220 }
249221
250222 irp = irp->next;
251223 }
252224
253 log_debug("returning irp=NULL");
225 LOG_DEVEL(LOG_LEVEL_DEBUG, "returning irp=NULL");
254226 return NULL;
255227 }
256228
257 IRP * devredir_irp_find_by_fileid(tui32 FileId)
229 IRP *devredir_irp_find_by_fileid(tui32 FileId)
258230 {
259231 IRP *irp = g_irp_head;
260232
262234 {
263235 if (irp->FileId == FileId)
264236 {
265 log_debug("returning irp=%p", irp);
237 LOG_DEVEL(LOG_LEVEL_DEBUG, "returning irp=%p", irp);
266238 return irp;
267239 }
268240
269241 irp = irp->next;
270242 }
271243
272 log_debug("returning irp=NULL");
244 LOG_DEVEL(LOG_LEVEL_DEBUG, "returning irp=NULL");
273245 return NULL;
274246 }
275247
277249 * Return last IRP in linked list
278250 *****************************************************************************/
279251
280 IRP * devredir_irp_get_last(void)
252 IRP *devredir_irp_get_last(void)
281253 {
282254 IRP *irp = g_irp_head;
283255
284256 while (irp)
285257 {
286258 if (irp->next == NULL)
259 {
287260 break;
288
289 irp = irp->next;
290 }
291
292 log_debug("returning irp=%p", irp);
261 }
262
263 irp = irp->next;
264 }
265
266 LOG_DEVEL(LOG_LEVEL_DEBUG, "returning irp=%p", irp);
293267 return irp;
294268 }
295269
297271 {
298272 IRP *irp = g_irp_head;
299273
300 log_debug("------- dumping IRPs --------");
301 while (irp)
302 {
303 log_debug(" completion_id=%d\tcompletion_type=%d\tFileId=%d",
274 LOG_DEVEL(LOG_LEVEL_DEBUG, "------- dumping IRPs --------");
275 while (irp)
276 {
277 LOG_DEVEL(LOG_LEVEL_DEBUG, " completion_id=%d\tcompletion_type=%d\tFileId=%d",
304278 irp->CompletionId, irp->completion_type, irp->FileId);
305279
306280 irp = irp->next;
307281 }
308 log_debug("------- dumping IRPs done ---");
309 }
282 LOG_DEVEL(LOG_LEVEL_DEBUG, "------- dumping IRPs done ---");
283 }
+0
-112
sesman/chansrv/mlog.h less more
0 /**
1 * xrdp: A Remote Desktop Protocol server.
2 *
3 * Copyright (C) Laxmikant Rashinkar 2013 LK.Rashinkar@gmail.com
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 /* module based logging */
19
20 #ifndef _MLOG_H
21 #define _MLOG_H
22
23 /*
24 * Note1: to enable debug messages, in your .c file, #define LOCAL_DEBUG
25 * BEFORE including this file
26 *
27 * Note2: in your .c file, #define MODULE_NAME, 8 chars long, to print each
28 * log entry with your module name
29 */
30
31 #define LOG_ERROR 0
32 #define LOG_INFO 1
33 #define LOG_DEBUG_LOW 2
34 #define LOG_DEBUG_HIGH 3
35 #define LOG_LEVEL LOG_ERROR
36
37 /*
38 * print always
39 */
40
41 #define log_error(_params...) \
42 do \
43 { \
44 g_write("[%10.10u]: %s %s: %d: ERROR: ", g_time3(), \
45 MODULE_NAME, __func__, __LINE__); \
46 g_writeln (_params); \
47 } \
48 while(0)
49
50 #define log_always(_params...) \
51 do \
52 { \
53 g_write("[%10.10u]: %s %s: %d: ALWAYS: ", g_time3(), \
54 MODULE_NAME, __func__, __LINE__); \
55 g_writeln (_params); \
56 } \
57 while(0)
58
59 /*
60 * print conditionally
61 */
62
63 #ifdef LOCAL_DEBUG
64 #define log_info(_params...) \
65 do \
66 { \
67 if (LOG_INFO <= LOG_LEVEL) \
68 { \
69 g_write("[%10.10u]: %s %s: %d: INFO: ", g_time3(), \
70 MODULE_NAME, __func__, __LINE__); \
71 g_writeln (_params); \
72 } \
73 } \
74 while(0)
75 #else
76 #define log_info(_params...)
77 #endif
78
79 #ifdef LOCAL_DEBUG
80 #define log_debug_low(_params...) \
81 do \
82 { \
83 if (LOG_DEBUG_LOW <= LOG_LEVEL) \
84 { \
85 g_write("[%10.10u]: %s %s: %d: DEBUG: ", g_time3(), \
86 MODULE_NAME, __func__, __LINE__); \
87 g_writeln (_params); \
88 } \
89 } \
90 while(0)
91 #else
92 #define log_debug_low(_params...)
93 #endif
94
95 #ifdef LOCAL_DEBUG
96 #define log_debug_high(_params...) \
97 do \
98 { \
99 if (LOG_DEBUG_HIGH <= LOG_LEVEL) \
100 { \
101 g_write("[%10.10u]: %s %s: %d: DEBUG: ", g_time3(), \
102 MODULE_NAME, __func__, __LINE__); \
103 g_writeln (_params); \
104 } \
105 } \
106 while(0)
107 #else
108 #define log_debug_high(_params...)
109 #endif
110
111 #endif /* #ifndef _MLOG_H */
+0
-44
sesman/chansrv/ms-erref.h less more
0 /**
1 * xrdp: A Remote Desktop Protocol server.
2 *
3 * MS-ERREF : Definitions from [MS-ERREF]
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * References to MS-ERREF are currently correct for v20180912 of that
18 * document
19 */
20
21 #if !defined(MS_ERREF_H)
22 #define MS_ERREF_H
23
24 /*
25 * NTSTATUS codes (section 2.3)
26 */
27 enum NTSTATUS
28 {
29 NT_STATUS_SUCCESS = 0x00000000,
30 NT_STATUS_UNSUCCESSFUL = 0xC0000001,
31 NT_STATUS_NO_SUCH_FILE = 0xC000000F,
32 NT_STATUS_ACCESS_DENIED = 0xC0000022,
33 NT_STATUS_OBJECT_NAME_INVALID = 0xC0000033,
34 NT_STATUS_OBJECT_NAME_NOT_FOUND = 0xC0000034,
35 NT_STATUS_SHARING_VIOLATION = 0xC0000043,
36 NT_STATUS_NO_MORE_FILES = 0x80000006
37 };
38
39 #endif /* MS_ERREF_H */
40
41
42
43
+0
-64
sesman/chansrv/ms-fscc.h less more
0 /**
1 * xrdp: A Remote Desktop Protocol server.
2 *
3 * MS-FSCC : Definitions from [MS-FSCC]
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * References to MS-FSCC are currently correct for v20190923 of that
18 * document
19 */
20
21 #if !defined(MS_FSCC_H)
22 #define MS_FSCC_H
23
24 /*
25 * File system ioctl codes (section 2.3)
26 */
27 #define FSCTL_DELETE_OBJECT_ID 0x900a0
28
29 /*
30 * File information classes (section 2.4)
31 */
32 enum FS_INFORMATION_CLASS
33 {
34 FileAllocationInformation = 19, /* Set */
35 FileBasicInformation = 4, /* Query, Set */
36 FileBothDirectoryInformation = 3, /* Query */
37 FileDirectoryInformation = 1, /* Query */
38 FileDispositionInformation = 13, /* Set */
39 FileEndOfFileInformation = 20, /* Set */
40 FileFullDirectoryInformation = 2, /* Query */
41 FileNamesInformation = 12, /* Query */
42 FileRenameInformation = 10, /* Set */
43 FileStandardInformation = 5 /* Query */
44 };
45
46 /*
47 * Size of structs above without trailing RESERVED fields (MS-RDPEFS
48 * 2.2.3.3.8)
49 */
50 #define FILE_BASIC_INFORMATION_SIZE 36
51 #define FILE_STD_INFORMATION_SIZE 22
52 #define FILE_END_OF_FILE_INFORMATION_SIZE 8
53
54 /* Windows file attributes (section 2.6) */
55 #define W_FILE_ATTRIBUTE_DIRECTORY 0x00000010
56 #define W_FILE_ATTRIBUTE_READONLY 0x00000001
57 #define W_FILE_ATTRIBUTE_SYSTEM 0x00000004
58 #define W_FILE_ATTRIBUTE_NORMAL 0x00000080
59
60 #endif /* MS_FSCC_H */
61
62
63
+0
-125
sesman/chansrv/ms-rdpefs.h less more
0 /**
1 * xrdp: A Remote Desktop Protocol server.
2 *
3 * MS-RDPEFS : Definitions from [MS-RDPEFS]
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * References to MS-RDPEFS are currently correct for v20180912 of that
18 * document
19 */
20
21 #if !defined(MS_RDPEFS_H)
22 #define MS_RDPEFS_H
23
24 /*
25 * RDPDR_HEADER definitions (2.2.1.1)
26 */
27
28 /* device redirector core component; most of the packets in this protocol */
29 /* are sent under this component ID */
30 #define RDPDR_CTYP_CORE 0x4472
31
32 /* printing component. the packets that use this ID are typically about */
33 /* printer cache management and identifying XPS printers */
34 #define RDPDR_CTYP_PRN 0x5052
35
36 /* Server Announce Request, as specified in section 2.2.2.2 */
37 #define PAKID_CORE_SERVER_ANNOUNCE 0x496E
38
39 /* Client Announce Reply and Server Client ID Confirm, as specified in */
40 /* sections 2.2.2.3 and 2.2.2.6. */
41 #define PAKID_CORE_CLIENTID_CONFIRM 0x4343
42
43 /* Client Name Request, as specified in section 2.2.2.4 */
44 #define PAKID_CORE_CLIENT_NAME 0x434E
45
46 /* Client Device List Announce Request, as specified in section 2.2.2.9 */
47 #define PAKID_CORE_DEVICELIST_ANNOUNCE 0x4441
48
49 /* Server Device Announce Response, as specified in section 2.2.2.1 */
50 #define PAKID_CORE_DEVICE_REPLY 0x6472
51
52 /* Device I/O Request, as specified in section 2.2.1.4 */
53 #define PAKID_CORE_DEVICE_IOREQUEST 0x4952
54
55 /* Device I/O Response, as specified in section 2.2.1.5 */
56 #define PAKID_CORE_DEVICE_IOCOMPLETION 0x4943
57
58 /* Server Core Capability Request, as specified in section 2.2.2.7 */
59 #define PAKID_CORE_SERVER_CAPABILITY 0x5350
60
61 /* Client Core Capability Response, as specified in section 2.2.2.8 */
62 #define PAKID_CORE_CLIENT_CAPABILITY 0x4350
63
64 /* Client Drive Device List Remove, as specified in section 2.2.3.2 */
65 #define PAKID_CORE_DEVICELIST_REMOVE 0x444D
66
67 /* Add Printer Cachedata, as specified in [MS-RDPEPC] section 2.2.2.3 */
68 #define PAKID_PRN_CACHE_DATA 0x5043
69
70 /* Server User Logged On, as specified in section 2.2.2.5 */
71 #define PAKID_CORE_USER_LOGGEDON 0x554C
72
73 /* Server Printer Set XPS Mode, as specified in [MS-RDPEPC] section 2.2.2.2 */
74 #define PAKID_PRN_USING_XPS 0x5543
75
76 /*
77 * Capability header definitions (2.2.1.2)
78 */
79
80 #define CAP_GENERAL_TYPE 0x0001 /* General cap set - GENERAL_CAPS_SET */
81 #define CAP_PRINTER_TYPE 0x0002 /* Print cap set - PRINTER_CAPS_SET */
82 #define CAP_PORT_TYPE 0x0003 /* Port cap set - PORT_CAPS_SET */
83 #define CAP_DRIVE_TYPE 0x0004 /* Drive cap set - DRIVE_CAPS_SET */
84 #define CAP_SMARTCARD_TYPE 0x0005 /* Smart card cap set - SMARTCARD_CAPS_SET */
85
86 /*
87 * Device announce header (2.2.1.3)
88 */
89 #define RDPDR_DTYP_SERIAL 0x0001
90 #define RDPDR_DTYP_PARALLEL 0x0002
91 #define RDPDR_DTYP_PRINT 0x0004
92 #define RDPDR_DTYP_FILESYSTEM 0x0008
93 #define RDPDR_DTYP_SMARTCARD 0x0020
94
95 /* Device I/O Request definitions (2.2.1.4) */
96 /* MajorFunction */
97 enum IRP_MJ
98 {
99 IRP_MJ_CREATE = 0x00000000,
100 IRP_MJ_CLOSE = 0x00000002,
101 IRP_MJ_READ = 0x00000003,
102 IRP_MJ_WRITE = 0x00000004,
103 IRP_MJ_DEVICE_CONTROL = 0x0000000E,
104 IRP_MJ_QUERY_VOLUME_INFORMATION = 0x0000000A,
105 IRP_MJ_SET_VOLUME_INFORMATION = 0x0000000B,
106 IRP_MJ_QUERY_INFORMATION = 0x00000005,
107 IRP_MJ_SET_INFORMATION = 0x00000006,
108 IRP_MJ_DIRECTORY_CONTROL = 0x0000000C,
109 IRP_MJ_LOCK_CONTROL = 0x00000011
110 };
111
112 /* MinorFunction */
113 /* Set to zero unless MajorFunction code == IRP_MJ_DIRECTORY_CONTROL */
114 enum IRP_MN
115 {
116 IRP_MN_NONE = 0x00000000, /* Name not in MS docs */
117 IRP_MN_QUERY_DIRECTORY = 0x00000001,
118 IRP_MN_NOTIFY_CHANGE_DIRECTORY = 0x00000002
119 };
120
121
122 #endif /* MS_RDPEFS_H */
123
124
+0
-79
sesman/chansrv/ms-smb2.h less more
0 /**
1 * xrdp: A Remote Desktop Protocol server.
2 *
3 * MS-SMB2 : Definitions from [MS-SMB2]
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * References to MS-SMB2 are currently correct for v20190923 of that
18 * document
19 */
20
21 #if !defined(MS_SMB2_H)
22 #define MS_SMB2_H
23
24 /* SMB2 CREATE request values (section 2.2.13) */
25
26 /*
27 * ShareAccess Mask. Currently, this is referred
28 * to in MS-RDPEFS 2.2.1.4.1 as 'SharedAccess' rather than 'ShareAccess'.
29 */
30 #define SA_FILE_SHARE_READ 0x00000001
31 #define SA_FILE_SHARE_WRITE 0x00000002
32 #define SA_FILE_SHARE_DELETE 0x00000004
33
34 /* CreateDisposition Mask */
35 #define CD_FILE_SUPERSEDE 0x00000000
36 #define CD_FILE_OPEN 0x00000001
37 #define CD_FILE_CREATE 0x00000002
38 #define CD_FILE_OPEN_IF 0x00000003
39 #define CD_FILE_OVERWRITE 0x00000004
40 #define CD_FILE_OVERWRITE_IF 0x00000005
41
42 /* CreateOptions Mask */
43 enum CREATE_OPTIONS
44 {
45 CO_FILE_DIRECTORY_FILE = 0x00000001,
46 CO_FILE_WRITE_THROUGH = 0x00000002,
47 CO_FILE_SYNCHRONOUS_IO_NONALERT = 0x00000020,
48 CO_FILE_DELETE_ON_CLOSE = 0x00001000
49 };
50
51 /*
52 * DesiredAccess Mask (section 2.2.13.1.1)
53 */
54
55 #define DA_FILE_READ_DATA 0x00000001
56 #define DA_FILE_WRITE_DATA 0x00000002
57 #define DA_FILE_APPEND_DATA 0x00000004
58 #define DA_FILE_READ_EA 0x00000008 /* rd extended attributes */
59 #define DA_FILE_WRITE_EA 0x00000010 /* wr extended attributes */
60 #define DA_FILE_EXECUTE 0x00000020
61 #define DA_FILE_READ_ATTRIBUTES 0x00000080
62 #define DA_FILE_WRITE_ATTRIBUTES 0x00000100
63 #define DA_DELETE 0x00010000
64 #define DA_READ_CONTROL 0x00020000 /* rd security descriptor */
65 #define DA_WRITE_DAC 0x00040000
66 #define DA_WRITE_OWNER 0x00080000
67 #define DA_SYNCHRONIZE 0x00100000
68 #define DA_ACCESS_SYSTEM_SECURITY 0x01000000
69 #define DA_MAXIMUM_ALLOWED 0x02000000
70 #define DA_GENERIC_ALL 0x10000000
71 #define DA_GENERIC_EXECUTE 0x20000000
72 #define DA_GENERIC_WRITE 0x40000000
73 #define DA_GENERIC_READ 0x80000000
74
75 #endif /* MS_SMB2_H */
76
77
78
7272
7373 /*****************************************************************************/
7474 static int
75 writeln(const char* format, ...)
75 writeln(const char *format, ...)
7676 {
7777 va_list ap;
7878 char text[256];
8585 }
8686
8787 #define LLOAD(_func, _type, _name) \
88 do { \
89 _func = (_type) GetProcAddress(lib, _name); \
90 if (_func == 0) \
91 { \
92 writeln("LLOAD error %s", _name); \
93 } \
94 } while (0)
88 do { \
89 _func = (_type) GetProcAddress(lib, _name); \
90 if (_func == 0) \
91 { \
92 writeln("LLOAD error %s", _name); \
93 } \
94 } while (0)
9595
9696 static int g_funcs_loaded = 0;
9797
6262
6363 #define LLOG_LEVEL 5
6464 #define LLOGLN(_level, _args) \
65 do { if (_level < LLOG_LEVEL) { printf _args ; printf("\n"); } } while (0)
65 do { if (_level < LLOG_LEVEL) { printf _args ; printf("\n"); } } while (0)
6666 #define LHEXDUMP(_level, _args) \
67 do { if (_level < LLOG_LEVEL) { lhexdump _args ; } } while (0)
67 do { if (_level < LLOG_LEVEL) { lhexdump _args ; } } while (0)
6868
6969 #define SCARD_ESTABLISH_CONTEXT 0x01
7070 #define SCARD_RELEASE_CONTEXT 0x02
8787 #define SCARD_F_INTERNAL_ERROR ((LONG)0x80100001)
8888
8989 #define SET_UINT32(_data, _offset, _val) do { \
90 (((BYTE*)(_data)) + (_offset))[0] = ((_val) >> 0) & 0xff; \
91 (((BYTE*)(_data)) + (_offset))[1] = ((_val) >> 8) & 0xff; \
92 (((BYTE*)(_data)) + (_offset))[2] = ((_val) >> 16) & 0xff; \
93 (((BYTE*)(_data)) + (_offset))[3] = ((_val) >> 24) & 0xff; } while (0)
90 (((BYTE*)(_data)) + (_offset))[0] = ((_val) >> 0) & 0xff; \
91 (((BYTE*)(_data)) + (_offset))[1] = ((_val) >> 8) & 0xff; \
92 (((BYTE*)(_data)) + (_offset))[2] = ((_val) >> 16) & 0xff; \
93 (((BYTE*)(_data)) + (_offset))[3] = ((_val) >> 24) & 0xff; } while (0)
9494
9595 #define GET_UINT32(_data, _offset) \
96 ((((BYTE*)(_data)) + (_offset))[0] << 0) | \
97 ((((BYTE*)(_data)) + (_offset))[1] << 8) | \
98 ((((BYTE*)(_data)) + (_offset))[2] << 16) | \
99 ((((BYTE*)(_data)) + (_offset))[3] << 24)
96 ((((BYTE*)(_data)) + (_offset))[0] << 0) | \
97 ((((BYTE*)(_data)) + (_offset))[1] << 8) | \
98 ((((BYTE*)(_data)) + (_offset))[2] << 16) | \
99 ((((BYTE*)(_data)) + (_offset))[3] << 24)
100100
101101 #define LMIN(_val1, _val2) (_val1) < (_val2) ? (_val1) : (_val2)
102102 #define LMAX(_val1, _val2) (_val1) > (_val2) ? (_val1) : (_val2)
207207 disp[disp_index] = 0;
208208 scre[scre_index] = 0;
209209 LLOGLN(10, ("get_display_num_from_display: host [%s] disp [%s] scre [%s]",
210 host, disp, scre));
210 host, disp, scre));
211211 rv = atoi(disp);
212212 return rv;
213213 }
358358 else
359359 {
360360 LLOGLN(10, ("get_message: lcode %d *code %d",
361 lcode, *code));
361 lcode, *code));
362362 }
363363 }
364364 else if (recv_rv == 0)
420420 if (connect_to_chansrv() != 0)
421421 {
422422 LLOGLN(0, ("SCardEstablishContext: error, can not connect "
423 "to chansrv"));
423 "to chansrv"));
424424 return SCARD_F_INTERNAL_ERROR;
425425 }
426426 }
514514
515515 LLOGLN(10, ("SCardConnect:"));
516516 LLOGLN(10, ("SCardConnect: hContext 0x%8.8x szReader %s dwShareMode %d "
517 "dwPreferredProtocols %d",
518 (int)hContext, szReader, (int)dwShareMode, (int)dwPreferredProtocols));
517 "dwPreferredProtocols %d",
518 (int)hContext, szReader, (int)dwShareMode, (int)dwPreferredProtocols));
519519 if (g_sck == -1)
520520 {
521521 LLOGLN(0, ("SCardConnect: error, not connected"));
558558 *pdwActiveProtocol = GET_UINT32(msg, 4);
559559 status = GET_UINT32(msg, 8);
560560 LLOGLN(10, ("SCardConnect: got status 0x%8.8x hCard 0x%8.8x "
561 "dwActiveProtocol %d",
562 status, (int)*phCard, (int)*pdwActiveProtocol));
561 "dwActiveProtocol %d",
562 status, (int)*phCard, (int)*pdwActiveProtocol));
563563 return status;
564564 }
565565
588588 int status;
589589
590590 LLOGLN(10, ("SCardDisconnect: hCard 0x%8.8x dwDisposition %d",
591 (int)hCard, (int)dwDisposition));
591 (int)hCard, (int)dwDisposition));
592592 if (g_sck == -1)
593593 {
594594 LLOGLN(0, ("SCardDisconnect: error, not connected"));
10501050 offset += 4;
10511051 SET_UINT32(msg, offset, pioSendPci->dwProtocol);
10521052 offset += 4;
1053 /* SET_UINT32(msg, offset, pioSendPci->cbPciLength); */
1053 /* SET_UINT32(msg, offset, pioSendPci->cbPciLength); */
10541054 SET_UINT32(msg, offset, 8);
10551055 offset += 4;
1056 /* extra_len = pioSendPci->cbPciLength - 8; */
1056 /* extra_len = pioSendPci->cbPciLength - 8; */
10571057 extra_len = 0;
10581058 SET_UINT32(msg, offset, extra_len);
10591059 offset += 4;
10631063 offset += 4;
10641064 memcpy(msg + offset, pbSendBuffer, cbSendLength);
10651065 offset += cbSendLength;
1066 got_recv_pci = (pioRecvPci != NULL) && (pioRecvPci->cbPciLength >= 8);
10661067 // TODO figure out why recv pci does not work
1067 if (1 || (pioRecvPci == 0) || (pioRecvPci->cbPciLength < 8))
1068 {
1069 got_recv_pci = 0;
1068 got_recv_pci = 0;
1069 if (got_recv_pci == 0)
1070 {
10701071 SET_UINT32(msg, offset, 0); /* dwProtocol */
10711072 offset += 4;
10721073 SET_UINT32(msg, offset, 0); /* cbPciLength */
10761077 }
10771078 else
10781079 {
1079 got_recv_pci = 1;
10801080 SET_UINT32(msg, offset, pioRecvPci->dwProtocol);
10811081 offset += 4;
10821082 SET_UINT32(msg, offset, pioRecvPci->cbPciLength);
11571157 SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups, LPSTR mszReaders,
11581158 LPDWORD pcchReaders)
11591159 {
1160 char* msg;
1161 char* reader_names;
1160 char *msg;
1161 char *reader_names;
11621162 int reader_names_index;
11631163 int code;
11641164 int bytes;
11661166 int status;
11671167 int offset;
11681168 int index;
1169 int bytes_groups;
11701169 int val;
11711170 int llen;
11721171 char reader[100];
11871186 offset = 0;
11881187 SET_UINT32(msg, offset, hContext);
11891188 offset += 4;
1190 bytes_groups = 0;
11911189 if (mszGroups != 0)
11921190 {
1193 bytes_groups = strlen(mszGroups);
1194 }
1195 SET_UINT32(msg, offset, bytes_groups);
1196 offset += 4;
1197 memcpy(msg + offset, mszGroups, bytes_groups);
1198 offset += bytes_groups;
1191 unsigned int bytes_groups = strlen(mszGroups);
1192 SET_UINT32(msg, offset, bytes_groups);
1193 offset += 4;
1194 memcpy(msg + offset, mszGroups, bytes_groups);
1195 offset += bytes_groups;
1196 }
1197 else
1198 {
1199 SET_UINT32(msg, offset, 0);
1200 offset += 4;
1201 }
11991202 val = *pcchReaders;
12001203 SET_UINT32(msg, offset, val);
12011204 offset += 4;
12251228 num_readers = GET_UINT32(msg, offset);
12261229 offset += 4;
12271230 LLOGLN(10, ("SCardListReaders: mszReaders %p pcchReaders %p num_readers %d",
1228 mszReaders, pcchReaders, num_readers));
1231 mszReaders, pcchReaders, num_readers));
12291232 reader_names = (char *) malloc(8192);
12301233 reader_names_index = 0;
12311234 for (index = 0; index < num_readers; index++)
3838 #include "xcommon.h"
3939 #include "log.h"
4040 #include "os_calls.h"
41 #include "string_calls.h"
4142 #include "thread_calls.h"
4243 #include "list.h"
4344
6465 /* for rail_is_another_wm_running */
6566 static int g_rail_running = 1;
6667 /* list of valid rail windows */
67 static struct list* g_window_list = 0;
68 static struct list *g_window_list = 0;
6869
6970 static int g_got_focus = 0;
7071 static int g_focus_counter = 0;
184185 }
185186
186187 /*****************************************************************************/
187 static struct rail_window_data*
188 static struct rail_window_data *
188189 rail_get_window_data(Window window)
189190 {
190191 unsigned int bytes;
192193 int actual_format_return;
193194 unsigned long nitems_return;
194195 unsigned long bytes_after_return;
195 unsigned char* prop_return;
196 struct rail_window_data* rv;
197
198 LOG(10, ("chansrv::rail_get_window_data:"));
196 unsigned char *prop_return;
197 struct rail_window_data *rv;
198
199 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_get_window_data:");
199200 rv = 0;
200201 actual_type_return = 0;
201202 actual_format_return = 0;
212213 }
213214 if (nitems_return == bytes)
214215 {
215 rv = (struct rail_window_data*)prop_return;
216 rv = (struct rail_window_data *)prop_return;
216217 }
217218 return rv;
218219 }
219220
220221 /*****************************************************************************/
221222 static int
222 rail_set_window_data(Window window, struct rail_window_data* rwd)
223 rail_set_window_data(Window window, struct rail_window_data *rwd)
223224 {
224225 int bytes;
225226
226227 bytes = sizeof(struct rail_window_data);
227228 XChangeProperty(g_display, window, g_rwd_atom, XA_STRING, 8,
228 PropModeReplace, (unsigned char*)rwd, bytes);
229 PropModeReplace, (unsigned char *)rwd, bytes);
229230 return 0;
230231 }
231232
232233 /*****************************************************************************/
233234 /* get the rail window data, if not exist, try to create it and return */
234 static struct rail_window_data*
235 static struct rail_window_data *
235236 rail_get_window_data_safe(Window window)
236237 {
237 struct rail_window_data* rv;
238 struct rail_window_data *rv;
238239
239240 rv = rail_get_window_data(window);
240241 if (rv != 0)
282283 int bytes;
283284 char *size_ptr;
284285
285 LOG(10, ("chansrv::rail_send_init:"));
286 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_send_init:");
286287 make_stream(s);
287288 init_stream(s, 8182);
288289 out_uint16_le(s, TS_RAIL_ORDER_HANDSHAKE);
336337 int
337338 rail_init(void)
338339 {
339 LOG(10, ("chansrv::rail_init:"));
340 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_init:");
340341 xcommon_init();
341342
342343 return 0;
368369
369370 if (rail_is_another_wm_running())
370371 {
371 log_message(LOG_LEVEL_ERROR, "rail_init: another window manager "
372 "is running");
372 LOG(LOG_LEVEL_ERROR, "rail_init: another window manager "
373 "is running");
373374 }
374375
375376 list_delete(g_window_list);
381382 if (!XRRQueryExtension(g_display, &g_xrr_event_base, &dummy))
382383 {
383384 g_xrr_event_base = 0;
384 log_message(LOG_LEVEL_ERROR, "rail_init: RandR extension not found");
385 LOG(LOG_LEVEL_ERROR, "rail_init: RandR extension not found");
385386 }
386387
387388 if (g_xrr_event_base > 0)
388389 {
389 LOG(0, ("rail_init: found RandR extension"));
390 LOG_DEVEL(LOG_LEVEL_INFO, "rail_init: found RandR extension");
390391 st = XRRQueryVersion(g_display, &ver_maj, &ver_min);
391392 if (st)
392393 {
393 LOG(0, ("rail_init: RandR version major %d minor %d", ver_maj, ver_min));
394 LOG_DEVEL(LOG_LEVEL_INFO, "rail_init: RandR version major %d minor %d", ver_maj, ver_min);
394395 }
395396 XRRSelectInput(g_display, g_root_window, RRScreenChangeNotifyMask);
396397 }
452453 char *WorkingDir;
453454 char *Arguments;
454455
455 LOG(0, ("chansrv::rail_process_exec:"));
456 LOG_DEVEL(LOG_LEVEL_INFO, "chansrv::rail_process_exec:");
456457 in_uint16_le(s, flags);
457458 in_uint16_le(s, ExeOrFileLength);
458459 in_uint16_le(s, WorkingDirLength);
460461 ExeOrFile = read_uni(s, ExeOrFileLength);
461462 WorkingDir = read_uni(s, WorkingDirLength);
462463 Arguments = read_uni(s, ArgumentsLen);
463 LOG(10, (" flags 0x%8.8x ExeOrFileLength %d WorkingDirLength %d "
464 "ArgumentsLen %d ExeOrFile [%s] WorkingDir [%s] "
465 "Arguments [%s]", flags, ExeOrFileLength, WorkingDirLength,
466 ArgumentsLen, ExeOrFile, WorkingDir, Arguments));
464 LOG(LOG_LEVEL_DEBUG, " flags 0x%8.8x ExeOrFileLength %d WorkingDirLength %d "
465 "ArgumentsLen %d ExeOrFile [%s] WorkingDir [%s] "
466 "Arguments [%s]", flags, ExeOrFileLength, WorkingDirLength,
467 ArgumentsLen, ExeOrFile, WorkingDir, Arguments);
467468
468469 if (g_strlen(ExeOrFile) > 0)
469470 {
470471 rail_startup();
471472
472 LOG(10, ("rail_process_exec: pre"));
473 LOG_DEVEL(LOG_LEVEL_DEBUG, "rail_process_exec: pre");
473474 /* ask main thread to fork */
474475 tc_mutex_lock(g_exec_mutex);
475476 g_exec_name = ExeOrFile;
476477 g_set_wait_obj(g_exec_event);
477478 tc_sem_dec(g_exec_sem);
478479 tc_mutex_unlock(g_exec_mutex);
479 LOG(10, ("rail_process_exec: post"));
480 LOG_DEVEL(LOG_LEVEL_DEBUG, "rail_process_exec: post");
480481 }
481482
482483 g_free(ExeOrFile);
494495 unsigned int nchild;
495496 Window r;
496497 Window p;
497 Window* children;
498 Window *children;
498499 XWindowAttributes window_attributes;
499500
500501 /*
508509 {
509510 XGetWindowAttributes(g_display, children[i], &window_attributes);
510511 if (window_attributes.override_redirect &&
511 window_attributes.map_state == IsViewable &&
512 list_index_of(g_window_list, children[i]) >= 0)
512 window_attributes.map_state == IsViewable &&
513 list_index_of(g_window_list, children[i]) >= 0)
513514 {
514 LOG(10, (" dismiss pop up 0x%8.8lx", children[i]));
515 LOG_DEVEL(LOG_LEVEL_DEBUG, " dismiss pop up 0x%8.8lx", children[i]);
515516 rail_send_key_esc(children[i]);
516517 rv = 1;
517518 }
527528 {
528529 XEvent ce;
529530
530 LOG(0, ("chansrv::rail_close_window:"));
531 LOG_DEVEL(LOG_LEVEL_INFO, "chansrv::rail_close_window:");
531532
532533 rail_win_popdown();
533534
546547
547548 /*****************************************************************************/
548549 void
549 my_timeout(void* data)
550 {
551 LOG(10, ("my_timeout: g_got_focus %d", g_got_focus));
550 my_timeout(void *data)
551 {
552 LOG_DEVEL(LOG_LEVEL_DEBUG, "my_timeout: g_got_focus %d", g_got_focus);
552553 if (g_focus_counter == (int)(long)data)
553554 {
554 LOG(10, ("my_timeout: g_focus_counter %d", g_focus_counter));
555 LOG_DEVEL(LOG_LEVEL_DEBUG, "my_timeout: g_focus_counter %d", g_focus_counter);
555556 rail_win_popdown();
556557 }
557558 }
566567 XWindowAttributes window_attributes;
567568 Window transient_for = 0;
568569
569 LOG(10, ("chansrv::rail_process_activate:"));
570 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_activate:");
570571 in_uint32_le(s, window_id);
571572 in_uint8(s, enabled);
572573
573574 index = list_index_of(g_window_list, window_id);
574575 if (index < 0)
575576 {
576 LOG(10, ("chansrv::rail_process_activate: window 0x%8.8x not in list",
577 window_id));
577 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_activate: window 0x%8.8x not in list",
578 window_id);
578579 return 0;
579580 }
580581
581582 g_focus_counter++;
582583 g_got_focus = enabled;
583 LOG(10, (" window_id 0x%8.8x enabled %d", window_id, enabled));
584 LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x enabled %d", window_id, enabled);
584585
585586 XGetWindowAttributes(g_display, window_id, &window_attributes);
586587
605606 /* Owner window should be raised up as well */
606607 XRaiseWindow(g_display, transient_for);
607608 }
608 LOG(10, ("chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id));
609 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id);
609610 XRaiseWindow(g_display, window_id);
610 LOG(10, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id));
611 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id);
611612 XSetInputFocus(g_display, window_id, RevertToParent, CurrentTime);
612613 }
613 LOG(10, ("chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id));
614 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id);
614615 XRaiseWindow(g_display, window_id);
615 LOG(10, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id));
616 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id);
616617 XSetInputFocus(g_display, window_id, RevertToParent, CurrentTime);
617 } else {
618 LOG(10, (" window attributes: override_redirect %d",
619 window_attributes.override_redirect));
620 add_timeout(200, my_timeout, (void*)(long)g_focus_counter);
618 }
619 else
620 {
621 LOG_DEVEL(LOG_LEVEL_DEBUG, " window attributes: override_redirect %d",
622 window_attributes.override_redirect);
623 add_timeout(200, my_timeout, (void *)(long)g_focus_counter);
621624 }
622625 return 0;
623626 }
642645 unsigned int nchild;
643646 Window r;
644647 Window p;
645 Window* children;
648 Window *children;
646649
647650 XQueryTree(g_display, g_root_window, &r, &p, &children, &nchild);
648651 for (i = 0; i < nchild; i++)
671674 {
672675 int system_param;
673676
674 LOG(10, ("chansrv::rail_process_system_param:"));
677 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_system_param:");
675678 in_uint32_le(s, system_param);
676 LOG(10, (" system_param 0x%8.8x", system_param));
679 LOG_DEVEL(LOG_LEVEL_DEBUG, " system_param 0x%8.8x", system_param);
677680 /*
678681 * Ask client to re-create the existing rail windows. This is supposed
679682 * to be done after handshake and client is initialised properly, we
681684 */
682685 if (system_param == 0x0000002F) /*SPI_SET_WORK_AREA*/
683686 {
684 LOG(10, (" restore rail windows"));
687 LOG_DEVEL(LOG_LEVEL_DEBUG, " restore rail windows");
685688 rail_restore_windows();
686689 }
687690 return 0;
689692
690693 /*****************************************************************************/
691694 static int
692 rail_get_property(Display* display, Window target, Atom type, Atom property,
693 unsigned char** data, unsigned long* count)
695 rail_get_property(Display *display, Window target, Atom type, Atom property,
696 unsigned char **data, unsigned long *count)
694697 {
695698 Atom atom_return;
696699 int size;
697700 unsigned long nitems, bytes_left;
698 char* prop_name;
701 char *prop_name;
699702
700703 int ret = XGetWindowProperty(display, target, property,
701704 0l, 1l, False,
704707 if ((ret != Success || nitems < 1) && atom_return == None)
705708 {
706709 prop_name = XGetAtomName(g_display, property);
707 LOG(10, (" rail_get_property %s: failed", prop_name));
710 LOG_DEVEL(LOG_LEVEL_DEBUG, " rail_get_property %s: failed", prop_name);
708711 XFree(prop_name);
709712 return 1;
710713 }
733736 {
734737 unsigned long nitems = 0;
735738 int rv = -1;
736 char* data = 0;
739 char *data = 0;
737740
738741 rail_get_property(g_display, win, g_wm_state, g_wm_state,
739742 (unsigned char **)&data,
743746 {
744747 rv = *(unsigned long *)data;
745748 XFree(data);
746 LOG(10, (" rail_win_get_state: %d", rv));
749 LOG_DEVEL(LOG_LEVEL_DEBUG, " rail_win_get_state: %d", rv);
747750 }
748751
749752 return rv;
756759 int old_state;
757760 unsigned long data[2] = { state, None };
758761
759 LOG(10, (" rail_win_set_state: %ld", state));
762 LOG_DEVEL(LOG_LEVEL_DEBUG, " rail_win_set_state: %ld", state);
760763 /* check whether WM_STATE exists */
761764 old_state = rail_win_get_state(win);
762765 if (old_state == -1)
764767 /* create WM_STATE property */
765768 XChangeProperty(g_display, win, g_wm_state, g_wm_state, 32, PropModeAppend,
766769 (unsigned char *)data, 2);
767 LOG(10, (" rail_win_set_state: create WM_STATE property"));
770 LOG_DEVEL(LOG_LEVEL_DEBUG, " rail_win_set_state: create WM_STATE property");
768771 }
769772 else
770773 {
818821 static int
819822 rail_minmax_window(int window_id, int max)
820823 {
821 LOG(10, ("chansrv::rail_minmax_window 0x%8.8x:", window_id));
824 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_minmax_window 0x%8.8x:", window_id);
822825 if (max)
823826 {
824827
825 } else {
828 }
829 else
830 {
826831 XUnmapWindow(g_display, window_id);
827832 /* change window state to IconicState (3) */
828833 rail_win_set_state(window_id, 0x3);
839844 {
840845 XWindowAttributes window_attributes;
841846
842 LOG(10, ("chansrv::rail_restore_window 0x%8.8x:", window_id));
847 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_restore_window 0x%8.8x:", window_id);
843848 XGetWindowAttributes(g_display, window_id, &window_attributes);
844849 if (window_attributes.map_state != IsViewable)
845850 {
846851 XMapWindow(g_display, window_id);
847852 }
848 LOG(10, ("chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id));
853 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_activate: calling XRaiseWindow 0x%8.8x", window_id);
849854 XRaiseWindow(g_display, window_id);
850 LOG(10, ("chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id));
855 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_activate: calling XSetInputFocus 0x%8.8x", window_id);
851856 XSetInputFocus(g_display, window_id, RevertToParent, CurrentTime);
852857
853858 return 0;
861866 int command;
862867 int index;
863868
864 LOG(10, ("chansrv::rail_process_system_command:"));
869 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_system_command:");
865870 in_uint32_le(s, window_id);
866871 in_uint16_le(s, command);
867872
868873 index = list_index_of(g_window_list, window_id);
869874 if (index < 0)
870875 {
871 LOG(10, ("chansrv::rail_process_system_command: window 0x%8.8x not in list",
872 window_id));
876 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_system_command: window 0x%8.8x not in list",
877 window_id);
873878 return 0;
874879 }
875880
876881 switch (command)
877882 {
878883 case SC_SIZE:
879 LOG(10, (" window_id 0x%8.8x SC_SIZE", window_id));
884 LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x SC_SIZE", window_id);
880885 break;
881886 case SC_MOVE:
882 LOG(10, (" window_id 0x%8.8x SC_MOVE", window_id));
887 LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x SC_MOVE", window_id);
883888 break;
884889 case SC_MINIMIZE:
885 LOG(10, (" window_id 0x%8.8x SC_MINIMIZE", window_id));
890 LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x SC_MINIMIZE", window_id);
886891 rail_minmax_window(window_id, 0);
887892 break;
888893 case SC_MAXIMIZE:
889 LOG(10, (" window_id 0x%8.8x SC_MAXIMIZE", window_id));
894 LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x SC_MAXIMIZE", window_id);
890895 break;
891896 case SC_CLOSE:
892 LOG(10, (" window_id 0x%8.8x SC_CLOSE", window_id));
897 LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x SC_CLOSE", window_id);
893898 rail_close_window(window_id);
894899 break;
895900 case SC_KEYMENU:
896 LOG(10, (" window_id 0x%8.8x SC_KEYMENU", window_id));
901 LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x SC_KEYMENU", window_id);
897902 break;
898903 case SC_RESTORE:
899 LOG(10, (" window_id 0x%8.8x SC_RESTORE", window_id));
904 LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x SC_RESTORE", window_id);
900905 rail_restore_window(window_id);
901906 break;
902907 case SC_DEFAULT:
903 LOG(10, (" window_id 0x%8.8x SC_DEFAULT", window_id));
908 LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x SC_DEFAULT", window_id);
904909 break;
905910 default:
906 LOG(10, (" window_id 0x%8.8x unknown command command %d",
907 window_id, command));
911 LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x unknown command command %d",
912 window_id, command);
908913 break;
909914 }
910915
917922 {
918923 int build_number;
919924
920 LOG(10, ("chansrv::rail_process_handshake:"));
925 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_handshake:");
921926 in_uint32_le(s, build_number);
922 LOG(10, (" build_number 0x%8.8x", build_number));
927 LOG(LOG_LEVEL_DEBUG, " build_number 0x%8.8x", build_number);
923928 return 0;
924929 }
925930
931936 int notify_id;
932937 int message;
933938
934 LOG(10, ("chansrv::rail_process_notify_event:"));
939 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_notify_event:");
935940 in_uint32_le(s, window_id);
936941 in_uint32_le(s, notify_id);
937942 in_uint32_le(s, message);
938 LOG(10, (" window_id 0x%8.8x notify_id 0x%8.8x message 0x%8.8x",
939 window_id, notify_id, message));
943 LOG(LOG_LEVEL_DEBUG, " window_id 0x%8.8x notify_id 0x%8.8x message 0x%8.8x",
944 window_id, notify_id, message);
940945 return 0;
941946 }
942947
950955 int right;
951956 int bottom;
952957 tsi16 si16;
953 struct rail_window_data* rwd;
954
955 LOG(10, ("chansrv::rail_process_window_move:"));
958 struct rail_window_data *rwd;
959
960 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_window_move:");
956961 in_uint32_le(s, window_id);
957962 in_uint16_le(s, si16);
958963 left = si16;
962967 right = si16;
963968 in_uint16_le(s, si16);
964969 bottom = si16;
965 LOG(10, (" window_id 0x%8.8x left %d top %d right %d bottom %d width %d height %d",
966 window_id, left, top, right, bottom, right - left, bottom - top));
970 LOG_DEVEL(LOG_LEVEL_DEBUG, " window_id 0x%8.8x left %d top %d right %d bottom %d width %d height %d",
971 window_id, left, top, right, bottom, right - left, bottom - top);
967972 XMoveResizeWindow(g_display, window_id, left, top, right - left, bottom - top);
968 rwd = (struct rail_window_data*)
969 g_malloc(sizeof(struct rail_window_data), 1);
973 rwd = (struct rail_window_data *)
974 g_malloc(sizeof(struct rail_window_data), 1);
970975 rwd->x = left;
971976 rwd->y = top;
972977 rwd->width = right - left;
987992 int pos_y;
988993 tsi16 si16;
989994
990 LOG(10, ("chansrv::rail_process_local_move_size:"));
995 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_local_move_size:");
991996 in_uint32_le(s, window_id);
992997 in_uint16_le(s, is_move_size_start);
993998 in_uint16_le(s, move_size_type);
9951000 pos_x = si16;
9961001 in_uint16_le(s, si16);
9971002 pos_y = si16;
998 LOG(10, (" window_id 0x%8.8x is_move_size_start %d move_size_type %d "
999 "pos_x %d pos_y %d", window_id, is_move_size_start, move_size_type,
1000 pos_x, pos_y));
1003 LOG(LOG_LEVEL_DEBUG, " window_id 0x%8.8x is_move_size_start %d move_size_type %d "
1004 "pos_x %d pos_y %d", window_id, is_move_size_start, move_size_type,
1005 pos_x, pos_y);
10011006 return 0;
10021007 }
10031008
10061011 static int
10071012 rail_process_min_max_info(struct stream *s, int size)
10081013 {
1009 LOG(10, ("chansrv::rail_process_min_max_info:"));
1014 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_min_max_info:");
10101015 return 0;
10111016 }
10121017
10161021 {
10171022 int flags;
10181023
1019 LOG(10, ("chansrv::rail_process_client_status:"));
1024 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_client_status:");
10201025 in_uint32_le(s, flags);
1021 LOG(10, (" flags 0x%8.8x", flags));
1026 LOG(LOG_LEVEL_DEBUG, " flags 0x%8.8x", flags);
10221027 return 0;
10231028 }
10241029
10311036 int top;
10321037 tsi16 si16;
10331038
1034 LOG(10, ("chansrv::rail_process_sys_menu:"));
1039 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_sys_menu:");
10351040 in_uint32_le(s, window_id);
10361041 in_uint16_le(s, si16);
10371042 left = si16;
10381043 in_uint16_le(s, si16);
10391044 top = si16;
1040 LOG(10, (" window_id 0x%8.8x left %d top %d", window_id, left, top));
1045 LOG(LOG_LEVEL_DEBUG, " window_id 0x%8.8x left %d top %d", window_id, left, top);
10411046 return 0;
10421047 }
10431048
10471052 {
10481053 int language_bar_status;
10491054
1050 LOG(10, ("chansrv::rail_process_lang_bar_info:"));
1055 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_lang_bar_info:");
10511056 in_uint32_le(s, language_bar_status);
1052 LOG(10, (" language_bar_status 0x%8.8x", language_bar_status));
1057 LOG(LOG_LEVEL_DEBUG, " language_bar_status 0x%8.8x", language_bar_status);
10531058 return 0;
10541059 }
10551060
10571062 static int
10581063 rail_process_appid_req(struct stream *s, int size)
10591064 {
1060 LOG(10, ("chansrv::rail_process_appid_req:"));
1065 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_appid_req:");
10611066 return 0;
10621067 }
10631068
10651070 static int
10661071 rail_process_appid_resp(struct stream *s, int size)
10671072 {
1068 LOG(10, ("chansrv::rail_process_appid_resp:"));
1073 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_appid_resp:");
10691074 return 0;
10701075 }
10711076
10741079 static int
10751080 rail_process_exec_result(struct stream *s, int size)
10761081 {
1077 LOG(10, ("chansrv::rail_process_exec_result:"));
1082 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_process_exec_result:");
10781083 return 0;
10791084 }
10801085
10871092 int code;
10881093 int size;
10891094
1090 LOG(10, ("chansrv::rail_data_in:"));
1095 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_data_in:");
10911096 in_uint8(s, code);
10921097 in_uint8s(s, 1);
10931098 in_uint16_le(s, size);
11401145 rail_process_exec_result(s, size);
11411146 break;
11421147 default:
1143 LOG(10, ("rail_data_in: unknown code %d size %d", code, size));
1148 LOG_DEVEL(LOG_LEVEL_DEBUG, "rail_data_in: unknown code %d size %d", code, size);
11441149 break;
11451150 }
11461151
11981203
11991204 #define CRC_START(in_crc) (in_crc) = g_crc_seed
12001205 #define CRC_PASS(in_pixel, in_crc) \
1201 (in_crc) = g_crc_table[((in_crc) ^ (in_pixel)) & 0xff] ^ ((in_crc) >> 8)
1206 (in_crc) = g_crc_table[((in_crc) ^ (in_pixel)) & 0xff] ^ ((in_crc) >> 8)
12021207 #define CRC_END(in_crc) (in_crc) = ((in_crc) ^ g_crc_seed)
12031208
12041209 /*****************************************************************************/
12051210 static int
1206 get_string_crc(const char* text)
1211 get_string_crc(const char *text)
12071212 {
12081213 int index;
12091214 int crc;
12241229 static int
12251230 rail_win_send_text(Window win)
12261231 {
1227 char* data = 0;
1228 struct stream* s;
1232 char *data = 0;
1233 struct stream *s;
12291234 int len = 0;
12301235 int flags;
12311236 int crc;
1232 struct rail_window_data* rwd;
1233
1234 LOG(10, ("chansrv::rail_win_send_text:"));
1237 struct rail_window_data *rwd;
1238
1239 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_win_send_text:");
12351240 len = rail_win_get_text(win, &data);
12361241 rwd = rail_get_window_data_safe(win);
12371242 if (rwd != 0)
12431248 crc = get_string_crc(data);
12441249 if (rwd->title_crc == crc)
12451250 {
1246 LOG(10, ("chansrv::rail_win_send_text: skipping, title not changed"));
1251 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_win_send_text: skipping, title not changed");
12471252 g_free(data);
12481253 XFree(rwd);
12491254 return 0;
12531258 }
12541259 else
12551260 {
1256 LOG(0, ("chansrv::rail_win_send_text: error rail_get_window_data_safe failed"));
1261 LOG_DEVEL(LOG_LEVEL_ERROR, "chansrv::rail_win_send_text: error rail_get_window_data_safe failed");
12571262 g_free(data);
12581263 return 1;
12591264 }
12601265 if (data && len > 0)
12611266 {
1262 LOG(10, ("chansrv::rail_win_send_text: 0x%8.8lx text %s length %d",
1263 win, data, len));
1267 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_win_send_text: 0x%8.8lx text %s length %d",
1268 win, data, len);
12641269 make_stream(s);
12651270 init_stream(s, len + 1024);
12661271 flags = WINDOW_ORDER_TYPE_WINDOW | WINDOW_ORDER_FIELD_TITLE;
12891294 {
12901295 struct stream *s;
12911296
1292 LOG(10, ("chansrv::rail_destroy_window 0x%8.8lx", window_id));
1297 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_destroy_window 0x%8.8lx", window_id);
12931298 make_stream(s);
12941299 init_stream(s, 1024);
12951300
13071312 rail_show_window(Window window_id, int show_state)
13081313 {
13091314 int flags;
1310 struct stream* s;
1311
1312 LOG(10, ("chansrv::rail_show_window 0x%8.8lx 0x%x", window_id, show_state));
1315 struct stream *s;
1316
1317 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_show_window 0x%8.8lx 0x%x", window_id, show_state);
13131318 make_stream(s);
13141319 init_stream(s, 1024);
13151320
13351340 tui32 border;
13361341 Window root;
13371342 tui32 depth;
1338 char* title_bytes = 0;
1343 char *title_bytes = 0;
13391344 int title_size = 0;
13401345 XWindowAttributes attributes;
13411346 int style;
13481353 int index;
13491354 int crc;
13501355 Window transient_for = 0;
1351 struct rail_window_data* rwd;
1352 struct stream* s;
1353
1354 LOG(10, ("chansrv::rail_create_window 0x%8.8lx", window_id));
1356 struct rail_window_data *rwd;
1357 struct stream *s;
1358
1359 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_create_window 0x%8.8lx", window_id);
13551360
13561361 rwd = rail_get_window_data_safe(window_id);
13571362 if (rwd == 0)
13581363 {
1359 LOG(0, ("chansrv::rail_create_window: error rail_get_window_data_safe failed"));
1364 LOG_DEVEL(LOG_LEVEL_ERROR, "chansrv::rail_create_window: error rail_get_window_data_safe failed");
13601365 return 0;
13611366 }
13621367 XGetGeometry(g_display, window_id, &root, &x, &y, &width, &height,
13631368 &border, &depth);
13641369 XGetWindowAttributes(g_display, window_id, &attributes);
13651370
1366 LOG(10, (" x %d y %d width %d height %d border_width %d", x, y, width,
1367 height, border));
1371 LOG_DEVEL(LOG_LEVEL_DEBUG, " x %d y %d width %d height %d border_width %d", x, y, width,
1372 height, border);
13681373
13691374 index = list_index_of(g_window_list, window_id);
13701375 if (index == -1)
13711376 {
1372 LOG(10, (" create new window"));
1377 LOG_DEVEL(LOG_LEVEL_DEBUG, " create new window");
13731378 flags = WINDOW_ORDER_TYPE_WINDOW | WINDOW_ORDER_STATE_NEW;
13741379 list_add_item(g_window_list, window_id);
13751380 }
13761381 else
13771382 {
1378 LOG(10, (" update existing window"));
1383 LOG_DEVEL(LOG_LEVEL_DEBUG, " update existing window");
13791384 flags = WINDOW_ORDER_TYPE_WINDOW;
13801385 }
13811386
14151420 out_uint32_le(s, ext_style); /* extended_style */
14161421 flags |= WINDOW_ORDER_FIELD_STYLE;
14171422 out_uint32_le(s, 0x05); /* show_state */
1418 LOG(10, (" title %s", title_bytes));
1423 LOG_DEVEL(LOG_LEVEL_DEBUG, " title %s", title_bytes);
14191424 flags |= WINDOW_ORDER_FIELD_SHOW;
14201425 if (title_size > 0)
14211426 {
14321437 rwd->valid |= RWD_TITLE;
14331438 rwd->title_crc = 0;
14341439 }
1435 LOG(10, (" set title info %d", title_size));
1440 LOG_DEVEL(LOG_LEVEL_DEBUG, " set title info %d", title_size);
14361441 flags |= WINDOW_ORDER_FIELD_TITLE;
14371442 out_uint32_le(s, 0); /* client_offset_x */
14381443 out_uint32_le(s, 0); /* client_offset_y */
14871492 /*****************************************************************************/
14881493 /* returns 0, event handled, 1 unhandled */
14891494 int
1490 rail_configure_request_window(XConfigureRequestEvent* config)
1495 rail_configure_request_window(XConfigureRequestEvent *config)
14911496 {
14921497 int num_window_rects = 1;
14931498 int num_visibility_rects = 1;
14971502 int window_id;
14981503 int mask;
14991504 int resized = 0;
1500 struct rail_window_data* rwd;
1501
1502 struct stream* s;
1505 struct rail_window_data *rwd;
1506
1507 struct stream *s;
15031508
15041509 window_id = config->window;
15051510 mask = config->value_mask;
1506 LOG(10, ("chansrv::rail_configure_request_window: mask %d", mask));
1511 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_configure_request_window: mask %d", mask);
15071512 if (mask & CWStackMode)
15081513 {
1509 LOG(10, ("chansrv::rail_configure_request_window: CWStackMode "
1510 "detail 0x%8.8x above 0x%8.8lx", config->detail, config->above));
1514 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_configure_request_window: CWStackMode "
1515 "detail 0x%8.8x above 0x%8.8lx", config->detail, config->above);
15111516 if (config->detail == Above)
15121517 {
1513 LOG(10, ("chansrv::rail_configure_request_window: bring to front "
1514 "window_id 0x%8.8x", window_id));
1518 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_configure_request_window: bring to front "
1519 "window_id 0x%8.8x", window_id);
15151520 /* 0x05 - Show the window in its current size and position. */
15161521 rail_show_window(window_id, 5);
15171522 }
15191524 rwd = rail_get_window_data(window_id);
15201525 if (rwd == 0)
15211526 {
1522 rwd = (struct rail_window_data*)g_malloc(sizeof(struct rail_window_data), 1);
1527 rwd = (struct rail_window_data *)g_malloc(sizeof(struct rail_window_data), 1);
15231528 rwd->x = config->x;
15241529 rwd->y = config->y;
15251530 rwd->width = config->width;
16201625 return 0;
16211626 }
16221627
1623 LOG(10, ("chansrv::rail_configure_request_window: 0x%8.8x", window_id));
1624
1625
1626 LOG(10, (" x %d y %d width %d height %d border_width %d", config->x,
1627 config->y, config->width, config->height, config->border_width));
1628 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_configure_request_window: 0x%8.8x", window_id);
1629
1630
1631 LOG_DEVEL(LOG_LEVEL_DEBUG, " x %d y %d width %d height %d border_width %d", config->x,
1632 config->y, config->width, config->height, config->border_width);
16281633
16291634 index = list_index_of(g_window_list, window_id);
16301635 if (index == -1)
16311636 {
16321637 /* window isn't mapped yet */
1633 LOG(0, ("chansrv::rail_configure_request_window: window not mapped"));
1638 LOG_DEVEL(LOG_LEVEL_ERROR, "chansrv::rail_configure_request_window: window not mapped");
16341639 return 0;
16351640 }
16361641
17011706 int index;
17021707 int window_id;
17031708
1704 struct stream* s;
1709 struct stream *s;
17051710
17061711 window_id = config->window;
17071712
1708 LOG(10, ("chansrv::rail_configure_window 0x%8.8x", window_id));
1709
1710
1711 LOG(10, (" x %d y %d width %d height %d border_width %d", config->x,
1712 config->y, config->width, config->height, config->border_width));
1713 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_configure_window 0x%8.8x", window_id);
1714
1715
1716 LOG_DEVEL(LOG_LEVEL_DEBUG, " x %d y %d width %d height %d border_width %d", config->x,
1717 config->y, config->width, config->height, config->border_width);
17131718
17141719 index = list_index_of(g_window_list, window_id);
17151720 if (index == -1)
17771782 static int
17781783 rail_desktop_resize(XEvent *lxevent)
17791784 {
1780 LOG(0, ("rail_desktop_resize:"));
1785 LOG_DEVEL(LOG_LEVEL_INFO, "rail_desktop_resize:");
17811786 return 0;
17821787 }
17831788
17921797 int rv;
17931798 int index;
17941799 XWindowAttributes wnd_attributes;
1795 char* prop_name;
1796
1797 LOG(10, ("chansrv::rail_xevent:"));
1800 char *prop_name;
1801
1802 LOG_DEVEL(LOG_LEVEL_DEBUG, "chansrv::rail_xevent:");
17981803
17991804 if (!g_rail_up)
18001805 {
18081813 {
18091814 case PropertyNotify:
18101815 prop_name = XGetAtomName(g_display, lxevent->xproperty.atom);
1811 LOG(10, (" got PropertyNotify window_id 0x%8.8lx %s state new %d",
1812 lxevent->xproperty.window, prop_name,
1813 lxevent->xproperty.state == PropertyNewValue));
1816 LOG_DEVEL(LOG_LEVEL_DEBUG, " got PropertyNotify window_id 0x%8.8lx %s state new %d",
1817 lxevent->xproperty.window, prop_name,
1818 lxevent->xproperty.state == PropertyNewValue);
18141819
18151820 if (list_index_of(g_window_list, lxevent->xproperty.window) < 0)
18161821 {
18181823 }
18191824
18201825 if (g_strcmp(prop_name, "WM_NAME") == 0 ||
1821 g_strcmp(prop_name, "_NET_WM_NAME") == 0)
1826 g_strcmp(prop_name, "_NET_WM_NAME") == 0)
18221827 {
18231828 XGetWindowAttributes(g_display, lxevent->xproperty.window, &wnd_attributes);
18241829 if (wnd_attributes.map_state == IsViewable)
18311836 break;
18321837
18331838 case ConfigureRequest:
1834 LOG(10, (" got ConfigureRequest window_id 0x%8.8lx", lxevent->xconfigurerequest.window));
1839 LOG_DEVEL(LOG_LEVEL_DEBUG, " got ConfigureRequest window_id 0x%8.8lx", lxevent->xconfigurerequest.window);
18351840 g_memset(&xwc, 0, sizeof(xwc));
18361841 xwc.x = lxevent->xconfigurerequest.x;
18371842 xwc.y = lxevent->xconfigurerequest.y;
18491854 break;
18501855
18511856 case CreateNotify:
1852 LOG(10, (" got CreateNotify window 0x%8.8lx parent 0x%8.8lx",
1853 lxevent->xcreatewindow.window, lxevent->xcreatewindow.parent));
1857 LOG_DEVEL(LOG_LEVEL_DEBUG, " got CreateNotify window 0x%8.8lx parent 0x%8.8lx",
1858 lxevent->xcreatewindow.window, lxevent->xcreatewindow.parent);
18541859 rail_select_input(lxevent->xcreatewindow.window);
18551860 break;
18561861
18571862 case DestroyNotify:
1858 LOG(10, (" got DestroyNotify window 0x%8.8lx event 0x%8.8lx",
1859 lxevent->xdestroywindow.window, lxevent->xdestroywindow.event));
1863 LOG_DEVEL(LOG_LEVEL_DEBUG, " got DestroyNotify window 0x%8.8lx event 0x%8.8lx",
1864 lxevent->xdestroywindow.window, lxevent->xdestroywindow.event);
18601865 if (lxevent->xdestroywindow.window != lxevent->xdestroywindow.event)
18611866 {
18621867 break;
18711876 break;
18721877
18731878 case MapRequest:
1874 LOG(10, (" got MapRequest window 0x%8.8lx", lxevent->xmaprequest.window));
1879 LOG_DEVEL(LOG_LEVEL_DEBUG, " got MapRequest window 0x%8.8lx", lxevent->xmaprequest.window);
18751880 XMapWindow(g_display, lxevent->xmaprequest.window);
18761881 break;
18771882
18781883 case MapNotify:
1879 LOG(10, (" got MapNotify window 0x%8.8lx event 0x%8.8lx",
1880 lxevent->xmap.window, lxevent->xmap.event));
1884 LOG_DEVEL(LOG_LEVEL_DEBUG, " got MapNotify window 0x%8.8lx event 0x%8.8lx",
1885 lxevent->xmap.window, lxevent->xmap.event);
18811886 if (lxevent->xmap.window != lxevent->xmap.event)
18821887 {
18831888 break;
19021907 break;
19031908
19041909 case UnmapNotify:
1905 LOG(10, (" got UnmapNotify 0x%8.8lx", lxevent->xunmap.event));
1910 LOG_DEVEL(LOG_LEVEL_DEBUG, " got UnmapNotify 0x%8.8lx", lxevent->xunmap.event);
19061911 if (lxevent->xunmap.window != lxevent->xunmap.event)
19071912 {
19081913 break;
19101915 if (is_window_valid_child_of_root(lxevent->xunmap.window))
19111916 {
19121917 index = list_index_of(g_window_list, lxevent->xunmap.window);
1913 LOG(10, (" window 0x%8.8lx is unmapped", lxevent->xunmap.window));
1918 LOG_DEVEL(LOG_LEVEL_DEBUG, " window 0x%8.8lx is unmapped", lxevent->xunmap.window);
19141919 if (index >= 0)
19151920 {
19161921 XGetWindowAttributes(g_display, lxevent->xunmap.window, &wnd_attributes);
19191924 // remove popups
19201925 rail_destroy_window(lxevent->xunmap.window);
19211926 list_remove_item(g_window_list, index);
1922 } else {
1923 rail_show_window(lxevent->xunmap.window, 0x0);
1927 }
1928 else
1929 {
1930 rail_show_window(lxevent->xunmap.window, 0x0);
19241931 }
19251932
19261933 rv = 0;
19291936 break;
19301937
19311938 case ConfigureNotify:
1932 LOG(10, (" got ConfigureNotify 0x%8.8lx event 0x%8.8lx", lxevent->xconfigure.window,
1933 lxevent->xconfigure.event));
1939 LOG_DEVEL(LOG_LEVEL_DEBUG, " got ConfigureNotify 0x%8.8lx event 0x%8.8lx", lxevent->xconfigure.window,
1940 lxevent->xconfigure.event);
19341941 rv = 0;
19351942 if (lxevent->xconfigure.event != lxevent->xconfigure.window ||
1936 lxevent->xconfigure.override_redirect)
1943 lxevent->xconfigure.override_redirect)
19371944 {
19381945 break;
19391946 }
19431950 ConfigureNotify, &lastevent))
19441951 {
19451952 if (lastevent.xconfigure.event == lastevent.xconfigure.window &&
1946 lxevent->xconfigure.override_redirect == 0)
1953 lxevent->xconfigure.override_redirect == 0)
19471954 {
19481955 lxevent = &lastevent;
19491956 }
19541961 break;
19551962
19561963 case FocusIn:
1957 LOG(10, (" got FocusIn"));
1964 LOG_DEVEL(LOG_LEVEL_DEBUG, " got FocusIn");
19581965 g_focus_win = lxevent->xfocus.window;
19591966 break;
19601967
19611968 case FocusOut:
1962 LOG(10, (" got FocusOut"));
1969 LOG_DEVEL(LOG_LEVEL_DEBUG, " got FocusOut");
19631970 break;
19641971
19651972 case ButtonPress:
1966 LOG(10, (" got ButtonPress"));
1973 LOG_DEVEL(LOG_LEVEL_DEBUG, " got ButtonPress");
19671974 break;
19681975
19691976 case EnterNotify:
1970 LOG(10, (" got EnterNotify"));
1977 LOG_DEVEL(LOG_LEVEL_DEBUG, " got EnterNotify");
19711978 break;
19721979
19731980 case LeaveNotify:
1974 LOG(10, (" got LeaveNotify"));
1981 LOG_DEVEL(LOG_LEVEL_DEBUG, " got LeaveNotify");
19751982 break;
19761983
19771984 case ReparentNotify:
1978 LOG(10, (" got ReparentNotify window 0x%8.8lx parent 0x%8.8lx "
1979 "event 0x%8.8lx x %d y %d override redirect %d",
1980 lxevent->xreparent.window, lxevent->xreparent.parent,
1981 lxevent->xreparent.event, lxevent->xreparent.x,
1982 lxevent->xreparent.y, lxevent->xreparent.override_redirect));
1985 LOG_DEVEL(LOG_LEVEL_DEBUG, " got ReparentNotify window 0x%8.8lx parent 0x%8.8lx "
1986 "event 0x%8.8lx x %d y %d override redirect %d",
1987 lxevent->xreparent.window, lxevent->xreparent.parent,
1988 lxevent->xreparent.event, lxevent->xreparent.x,
1989 lxevent->xreparent.y, lxevent->xreparent.override_redirect);
19831990
19841991 if (lxevent->xreparent.window != lxevent->xreparent.event)
19851992 {
2727
2828 #include <string.h>
2929 #include "os_calls.h"
30 #include "string_calls.h"
3031 #include "smartcard.h"
3132 #include "log.h"
3233 #include "irp.h"
5758 * Vista and Server 2008 use version SCREDIR_VERSION_LONGHORN functions 5 - 64
5859 * if TS Client's build number is >= 4,034 use SCREDIR_VERSION_LONGHORN
5960 */
60
61 /* module based logging */
62 #define LOG_ERROR 0
63 #define LOG_INFO 1
64 #define LOG_DEBUG 2
65
66 #undef LOG_LEVEL
67 #define LOG_LEVEL LOG_INFO
68
69 #define log_error(_params...) \
70 do \
71 { \
72 g_write("[%10.10u]: SMART_CARD %s: %d : ERROR: ", \
73 g_time3(), __func__, __LINE__); \
74 g_writeln (_params); \
75 } while (0)
76
77 #define log_info(_params...) \
78 do \
79 { \
80 if (LOG_INFO <= LOG_LEVEL) \
81 { \
82 g_write("[%10.10u]: SMART_CARD %s: %d : ", \
83 g_time3(), __func__, __LINE__); \
84 g_writeln (_params); \
85 } \
86 } while (0)
87
88 #define log_debug(_params...) \
89 do \
90 { \
91 if (LOG_DEBUG <= LOG_LEVEL) \
92 if (2 <= 1) \
93 { \
94 g_write("[%10.10u]: SMART_CARD %s: %d : ", \
95 g_time3(), __func__, __LINE__); \
96 g_writeln (_params); \
97 } \
98 } while (0)
9961
10062 /* [MS-RDPESC] 3.1.4 */
10163 #define SCARD_IOCTL_ESTABLISH_CONTEXT 0x00090014 /* EstablishContext */
149111 } SMARTCARD;
150112
151113 /* globals */
152 SMARTCARD* smartcards[MAX_SMARTCARDS];
114 SMARTCARD *smartcards[MAX_SMARTCARDS];
153115 int g_smartcards_inited = 0;
154116 static tui32 g_device_id = 0;
155117 static int g_scard_index = 0;
162124 /******************************************************************************
163125 ** static functions local to this file **
164126 ******************************************************************************/
165 static struct stream * scard_make_new_ioctl(IRP *irp, tui32 ioctl);
127 static struct stream *scard_make_new_ioctl(IRP *irp, tui32 ioctl);
166128 static int scard_add_new_device(tui32 device_id);
167129 static int scard_get_free_slot(void);
168130 static void scard_release_resources(void);
169131 static void scard_send_EstablishContext(IRP *irp, int scope);
170132 static void scard_send_ReleaseContext(IRP *irp,
171 char *context, int context_bytes);
172 static void scard_send_IsContextValid(IRP* irp,
173 char *context, int context_bytes);
133 char *context, int context_bytes);
134 static void scard_send_IsContextValid(IRP *irp,
135 char *context, int context_bytes);
174136 static void scard_send_ListReaders(IRP *irp,
175 char *context, int context_bytes,
176 char *groups, int cchReaders,
177 int wide);
137 char *context, int context_bytes,
138 char *groups, int cchReaders,
139 int wide);
178140 static void scard_send_GetStatusChange(IRP *irp,
179 char *context, int context_bytes,
180 int wide,
181 tui32 timeout, tui32 num_readers,
182 READER_STATE *rsa);
141 char *context, int context_bytes,
142 int wide,
143 tui32 timeout, tui32 num_readers,
144 READER_STATE *rsa);
183145 static void scard_send_Connect(IRP *irp,
146 char *context, int context_bytes,
147 int wide,
148 READER_STATE *rs);
149 static void scard_send_Reconnect(IRP *irp,
150 char *context, int context_bytes,
151 char *card, int card_bytes,
152 READER_STATE *rs);
153 static void scard_send_BeginTransaction(IRP *irp,
154 char *context, int context_bytes,
155 char *card, int card_bytes);
156 static void scard_send_EndTransaction(IRP *irp,
184157 char *context, int context_bytes,
185 int wide,
186 READER_STATE *rs);
187 static void scard_send_Reconnect(IRP *irp,
188 char *context, int context_bytes,
189 char *card, int card_bytes,
190 READER_STATE *rs);
191 static void scard_send_BeginTransaction(IRP *irp,
192 char *context, int context_bytes,
193 char *card, int card_bytes);
194 static void scard_send_EndTransaction(IRP *irp,
195 char *context, int context_bytes,
196 char *card, int card_bytes,
197 tui32 dwDisposition);
158 char *card, int card_bytes,
159 tui32 dwDisposition);
198160 static void scard_send_Status(IRP *irp, int wide,
199 char *context, int context_bytes,
200 char *card, int card_bytes,
201 int cchReaderLen, int cbAtrLen);
161 char *context, int context_bytes,
162 char *card, int card_bytes,
163 int cchReaderLen, int cbAtrLen);
202164 static void scard_send_Disconnect(IRP *irp,
203 char *context, int context_bytes,
204 char *card, int card_bytes,
205 int dwDisposition);
165 char *context, int context_bytes,
166 char *card, int card_bytes,
167 int dwDisposition);
206168 static int scard_send_Transmit(IRP *irp,
207 char *context, int context_byte,
208 char *card, int card_bytes,
209 char *send_data, int send_bytes,
210 int recv_bytes,
211 struct xrdp_scard_io_request *send_ior,
212 struct xrdp_scard_io_request *recv_ior);
213 static int scard_send_Control(IRP* irp, char *context, int context_bytes,
214 char *card, int card_bytes,
215 char *send_data, int send_bytes,
216 int recv_bytes, int control_code);
169 char *context, int context_byte,
170 char *card, int card_bytes,
171 char *send_data, int send_bytes,
172 int recv_bytes,
173 struct xrdp_scard_io_request *send_ior,
174 struct xrdp_scard_io_request *recv_ior);
175 static int scard_send_Control(IRP *irp, char *context, int context_bytes,
176 char *card, int card_bytes,
177 char *send_data, int send_bytes,
178 int recv_bytes, int control_code);
217179 static int scard_send_Cancel(IRP *irp, char *context, int context_bytes);
218180 static int scard_send_GetAttrib(IRP *irp, char *card, int card_bytes,
219 READER_STATE *rs);
181 READER_STATE *rs);
220182
221183 /******************************************************************************
222184 ** local callbacks into this module **
223185 ******************************************************************************/
224186
225187 static void scard_handle_EstablishContext_Return(struct stream *s, IRP *irp,
226 tui32 DeviceId, tui32 CompletionId,
227 tui32 IoStatus);
188 tui32 DeviceId, tui32 CompletionId,
189 tui32 IoStatus);
228190
229191 static void scard_handle_ReleaseContext_Return(struct stream *s, IRP *irp,
230 tui32 DeviceId, tui32 CompletionId,
231 tui32 IoStatus);
192 tui32 DeviceId, tui32 CompletionId,
193 tui32 IoStatus);
232194
233195
234196 static void scard_handle_IsContextValid_Return(struct stream *s, IRP *irp,
235 tui32 DeviceId, tui32 CompletionId,
236 tui32 IoStatus);
197 tui32 DeviceId, tui32 CompletionId,
198 tui32 IoStatus);
237199
238200 static void scard_handle_ListReaders_Return(struct stream *s, IRP *irp,
239 tui32 DeviceId, tui32 CompletionId,
240 tui32 IoStatus);
201 tui32 DeviceId, tui32 CompletionId,
202 tui32 IoStatus);
241203
242204 static void scard_handle_GetStatusChange_Return(struct stream *s, IRP *irp,
243 tui32 DeviceId, tui32 CompletionId,
244 tui32 IoStatus);
205 tui32 DeviceId, tui32 CompletionId,
206 tui32 IoStatus);
245207
246208 static void scard_handle_Connect_Return(struct stream *s, IRP *irp,
247209 tui32 DeviceId, tui32 CompletionId,
248210 tui32 IoStatus);
249211
250212 static void scard_handle_Reconnect_Return(struct stream *s, IRP *irp,
251 tui32 DeviceId, tui32 CompletionId,
252 tui32 IoStatus);
213 tui32 DeviceId, tui32 CompletionId,
214 tui32 IoStatus);
253215
254216 static void scard_handle_BeginTransaction_Return(struct stream *s, IRP *irp,
255 tui32 DeviceId, tui32 CompletionId,
256 tui32 IoStatus);
217 tui32 DeviceId, tui32 CompletionId,
218 tui32 IoStatus);
257219
258220 static void scard_handle_EndTransaction_Return(struct stream *s, IRP *irp,
259 tui32 DeviceId,
260 tui32 CompletionId,
261 tui32 IoStatus);
221 tui32 DeviceId,
222 tui32 CompletionId,
223 tui32 IoStatus);
262224
263225 static void scard_handle_Status_Return(struct stream *s, IRP *irp,
264226 tui32 DeviceId, tui32 CompletionId,
265227 tui32 IoStatus);
266228
267229 static void scard_handle_Disconnect_Return(struct stream *s, IRP *irp,
268 tui32 DeviceId, tui32 CompletionId,
269 tui32 IoStatus);
230 tui32 DeviceId, tui32 CompletionId,
231 tui32 IoStatus);
270232
271233
272234 static void scard_handle_Transmit_Return(struct stream *s, IRP *irp,
273 tui32 DeviceId,
274 tui32 CompletionId,
275 tui32 IoStatus);
235 tui32 DeviceId,
236 tui32 CompletionId,
237 tui32 IoStatus);
276238
277239 static void scard_handle_Control_Return(struct stream *s, IRP *irp,
278 tui32 DeviceId,
279 tui32 CompletionId,
280 tui32 IoStatus);
240 tui32 DeviceId,
241 tui32 CompletionId,
242 tui32 IoStatus);
281243
282244 static void scard_handle_Cancel_Return(struct stream *s, IRP *irp,
283 tui32 DeviceId,
284 tui32 CompletionId,
285 tui32 IoStatus);
245 tui32 DeviceId,
246 tui32 CompletionId,
247 tui32 IoStatus);
286248
287249 static void scard_handle_GetAttrib_Return(struct stream *s, IRP *irp,
288 tui32 DeviceId,
289 tui32 CompletionId,
290 tui32 IoStatus);
250 tui32 DeviceId,
251 tui32 CompletionId,
252 tui32 IoStatus);
291253
292254 /******************************************************************************
293255 ** **
300262 void
301263 scard_device_announce(tui32 device_id)
302264 {
303 log_debug("entered: device_id=%d", device_id);
265 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered: device_id=%d", device_id);
304266
305267 if (g_smartcards_inited)
306268 {
307 log_error("already init");
269 LOG_DEVEL(LOG_LEVEL_ERROR, "already init");
308270 return;
309271 }
310272
314276 g_scard_index = scard_add_new_device(device_id);
315277
316278 if (g_scard_index < 0)
317 log_debug("scard_add_new_device failed with DeviceId=%d", g_device_id);
279 {
280 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_add_new_device failed with DeviceId=%d", g_device_id);
281 }
318282 else
319 log_debug("added smartcard with DeviceId=%d to list", g_device_id);
283 {
284 LOG_DEVEL(LOG_LEVEL_DEBUG, "added smartcard with DeviceId=%d to list", g_device_id);
285 }
320286 }
321287
322288 /**
343309 int
344310 scard_init(void)
345311 {
346 LOG(0, ("scard_init:"));
312 LOG_DEVEL(LOG_LEVEL_INFO, "scard_init:");
347313 return scard_pcsc_init();
348314 }
349315
353319 int
354320 scard_deinit(void)
355321 {
356 LOG(0, ("scard_deinit:"));
322 LOG_DEVEL(LOG_LEVEL_INFO, "scard_deinit:");
357323 scard_pcsc_deinit();
358324 scard_release_resources();
359325 g_smartcards_inited = 0;
371337 /* setup up IRP */
372338 if ((irp = devredir_irp_new()) == NULL)
373339 {
374 log_error("system out of memory");
340 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
375341 return 1;
376342 }
377343
399365 /* setup up IRP */
400366 if ((irp = devredir_irp_new()) == NULL)
401367 {
402 log_error("system out of memory");
368 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
403369 return 1;
404370 }
405371
426392 /* setup up IRP */
427393 if ((irp = devredir_irp_new()) == NULL)
428394 {
429 log_error("system out of memory");
395 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
430396 return 1;
431397 }
432398
454420 /* setup up IRP */
455421 if ((irp = devredir_irp_new()) == NULL)
456422 {
457 log_error("system out of memory");
423 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
458424 return 1;
459425 }
460426 irp->scard_index = g_scard_index;
482448 int
483449 scard_send_get_status_change(void *user_data, char *context, int context_bytes,
484450 int wide, tui32 timeout, tui32 num_readers,
485 READER_STATE* rsa)
451 READER_STATE *rsa)
486452 {
487453 IRP *irp;
488454
489455 /* setup up IRP */
490456 if ((irp = devredir_irp_new()) == NULL)
491457 {
492 log_error("system out of memory");
458 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
493459 return 1;
494460 }
495461
514480 *****************************************************************************/
515481 int
516482 scard_send_connect(void *user_data, char *context, int context_bytes,
517 int wide, READER_STATE* rs)
483 int wide, READER_STATE *rs)
518484 {
519485 IRP *irp;
520486
521487 /* setup up IRP */
522488 if ((irp = devredir_irp_new()) == NULL)
523489 {
524 log_error("system out of memory");
490 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
525491 return 1;
526492 }
527493
550516 *****************************************************************************/
551517 int
552518 scard_send_reconnect(void *user_data, char *context, int context_bytes,
553 char *card, int card_bytes, READER_STATE* rs)
519 char *card, int card_bytes, READER_STATE *rs)
554520 {
555521 IRP *irp;
556522
557523 /* setup up IRP */
558524 if ((irp = devredir_irp_new()) == NULL)
559525 {
560 log_error("system out of memory");
526 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
561527 return 1;
562528 }
563529
581547 *****************************************************************************/
582548 int
583549 scard_send_begin_transaction(void *user_data, char *context, int context_bytes,
584 char *card, int card_bytes)
550 char *card, int card_bytes)
585551 {
586552 IRP *irp;
587553
588554 /* setup up IRP */
589555 if ((irp = devredir_irp_new()) == NULL)
590556 {
591 log_error("system out of memory");
557 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
592558 return 1;
593559 }
594560
621587 /* setup up IRP */
622588 if ((irp = devredir_irp_new()) == NULL)
623589 {
624 log_error("system out of memory");
590 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
625591 return 1;
626592 }
627593
654620 /* setup up IRP */
655621 if ((irp = devredir_irp_new()) == NULL)
656622 {
657 log_error("system out of memory");
623 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
658624 return 1;
659625 }
660626
686652 /* setup up IRP */
687653 if ((irp = devredir_irp_new()) == NULL)
688654 {
689 log_error("system out of memory");
655 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
690656 return 1;
691657 }
692658
719685 /* setup up IRP */
720686 if ((irp = devredir_irp_new()) == NULL)
721687 {
722 log_error("system out of memory");
688 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
723689 return 1;
724690 }
725691
741707 * Communicate directly with the smart card reader
742708 *****************************************************************************/
743709 int
744 scard_send_control(void *user_data, char* context, int context_bytes,
710 scard_send_control(void *user_data, char *context, int context_bytes,
745711 char *card, int card_bytes,
746712 char *send_data, int send_bytes,
747713 int recv_bytes, int control_code)
751717 /* setup up IRP */
752718 if ((irp = devredir_irp_new()) == NULL)
753719 {
754 log_error("system out of memory");
720 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
755721 return 1;
756722 }
757723
781747 /* setup up IRP */
782748 if ((irp = devredir_irp_new()) == NULL)
783749 {
784 log_error("system out of memory");
750 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
785751 return 1;
786752 }
787753
802768 *****************************************************************************/
803769 int
804770 scard_send_get_attrib(void *user_data, char *card, int card_bytes,
805 READER_STATE* rs)
771 READER_STATE *rs)
806772 {
807773 IRP *irp;
808774
809775 /* setup up IRP */
810776 if ((irp = devredir_irp_new()) == NULL)
811777 {
812 log_error("system out of memory");
778 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
813779 return 1;
814780 }
815781
899865
900866 if ((index = scard_get_free_slot()) < 0)
901867 {
902 log_error("scard_get_free_slot failed");
868 LOG_DEVEL(LOG_LEVEL_ERROR, "scard_get_free_slot failed");
903869 return -1;
904870 }
905871
906872 sc = g_new0(SMARTCARD, 1);
907873 if (sc == NULL)
908874 {
909 log_error("system out of memory");
875 LOG_DEVEL(LOG_LEVEL_ERROR, "system out of memory");
910876 return -1;
911877 }
912878
931897 {
932898 if (smartcards[i] == NULL)
933899 {
934 log_debug("found free slot at index %d", i);
900 LOG_DEVEL(LOG_LEVEL_DEBUG, "found free slot at index %d", i);
935901 return i;
936902 }
937903 }
938904
939 log_error("too many smart card devices; rejecting this one");
905 LOG_DEVEL(LOG_LEVEL_ERROR, "too many smart card devices; rejecting this one");
940906 return -1;
941907 }
942908
969935
970936 if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_ESTABLISH_CONTEXT)) == NULL)
971937 {
972 log_error("scard_make_new_ioctl failed");
938 LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl failed");
973939 return;
974940 }
975941
1012978
1013979 if ((sc = smartcards[irp->scard_index]) == NULL)
1014980 {
1015 log_error("smartcards[%d] is NULL", irp->scard_index);
981 LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index);
1016982 return;
1017983 }
1018984
1019985 if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_RELEASE_CONTEXT)) == NULL)
1020986 {
1021 log_error("scard_make_new_ioctl failed");
987 LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl failed");
1022988 return;
1023989 }
1024990
10631029
10641030 if ((sc = smartcards[irp->scard_index]) == NULL)
10651031 {
1066 log_error("smartcards[%d] is NULL", irp->scard_index);
1032 LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index);
10671033 return;
10681034 }
10691035
10701036 if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_IS_VALID_CONTEXT)) == NULL)
10711037 {
1072 log_error("scard_make_new_ioctl failed");
1038 LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl failed");
10731039 return;
10741040 }
10751041
11331099
11341100 if ((sc = smartcards[irp->scard_index]) == NULL)
11351101 {
1136 log_error("smartcards[%d] is NULL", irp->scard_index);
1102 LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index);
11371103 return;
11381104 }
11391105
11401106 ioctl = (wide) ? SCARD_IOCTL_LIST_READERS_W :
1141 SCARD_IOCTL_LIST_READERS_A;
1107 SCARD_IOCTL_LIST_READERS_A;
11421108
11431109 if ((s = scard_make_new_ioctl(irp, ioctl)) == NULL)
11441110 {
1145 log_error("scard_make_new_ioctl failed");
1111 LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl failed");
11461112 return;
11471113 }
11481114
12141180 /* send to client */
12151181 send_channel_data(g_rdpdr_chan_id, s->data, bytes);
12161182
1217 #if 0
1218 g_writeln("scard_send_ListReaders:");
1219 g_hexdump(s->data, bytes);
1220 #endif
1183 LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "scard_send_ListReaders:", s->data, bytes);
12211184
12221185 free_stream(s);
12231186 }
12471210 * @param rsa array of READER_STATEs
12481211 *****************************************************************************/
12491212 static void
1250 scard_send_GetStatusChange(IRP* irp, char *context, int context_bytes,
1213 scard_send_GetStatusChange(IRP *irp, char *context, int context_bytes,
12511214 int wide, tui32 timeout,
1252 tui32 num_readers, READER_STATE* rsa)
1215 tui32 num_readers, READER_STATE *rsa)
12531216 {
12541217 /* see [MS-RDPESC] 2.2.2.11 for ASCII */
12551218 /* see [MS-RDPESC] 2.2.2.12 for Wide char */
12661229
12671230 if ((sc = smartcards[irp->scard_index]) == NULL)
12681231 {
1269 log_error("smartcards[%d] is NULL", irp->scard_index);
1232 LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index);
12701233 return;
12711234 }
12721235
12731236 ioctl = (wide) ? SCARD_IOCTL_GET_STATUS_CHANGE_W :
1274 SCARD_IOCTL_GET_STATUS_CHANGE_A;
1237 SCARD_IOCTL_GET_STATUS_CHANGE_A;
12751238
12761239 if ((s = scard_make_new_ioctl(irp, ioctl)) == NULL)
12771240 {
1278 log_error("scard_make_new_ioctl failed");
1241 LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl failed");
12791242 return;
12801243 }
12811244
13621325 /* send to client */
13631326 send_channel_data(g_rdpdr_chan_id, s->data, bytes);
13641327
1365 #if 0
1366 g_writeln("scard_send_GetStatusChange:");
1367 g_hexdump(s->data, bytes);
1368 #endif
1328 LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "scard_send_GetStatusChange:", s->data, bytes);
13691329
13701330 free_stream(s);
13711331 }
13781338 * @param rs reader state
13791339 *****************************************************************************/
13801340 static void
1381 scard_send_Connect(IRP* irp, char *context, int context_bytes,
1382 int wide, READER_STATE* rs)
1341 scard_send_Connect(IRP *irp, char *context, int context_bytes,
1342 int wide, READER_STATE *rs)
13831343 {
13841344 /* see [MS-RDPESC] 2.2.2.13 for ASCII */
13851345 /* see [MS-RDPESC] 2.2.2.14 for Wide char */
13861346
1387 SMARTCARD* sc;
1388 struct stream* s;
1347 SMARTCARD *sc;
1348 struct stream *s;
13891349 tui32 ioctl;
13901350 int bytes;
13911351 int num_chars;
13941354
13951355 if ((sc = smartcards[irp->scard_index]) == NULL)
13961356 {
1397 log_error("smartcards[%d] is NULL", irp->scard_index);
1357 LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index);
13981358 return;
13991359 }
14001360
14011361 ioctl = (wide) ? SCARD_IOCTL_CONNECT_W :
1402 SCARD_IOCTL_CONNECT_A;
1362 SCARD_IOCTL_CONNECT_A;
14031363
14041364 if ((s = scard_make_new_ioctl(irp, ioctl)) == NULL)
14051365 {
1406 log_error("scard_make_new_ioctl failed");
1366 LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl failed");
14071367 return;
14081368 }
14091369
14871447
14881448 if ((sc = smartcards[irp->scard_index]) == NULL)
14891449 {
1490 log_error("smartcards[%d] is NULL", irp->scard_index);
1450 LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index);
14911451 return;
14921452 }
14931453
14941454 if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_RECONNECT)) == NULL)
14951455 {
1496 log_error("scard_make_new_ioctl failed");
1456 LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl failed");
14971457 return;
14981458 }
14991459
15571517
15581518 if ((sc = smartcards[irp->scard_index]) == NULL)
15591519 {
1560 log_error("smartcards[%d] is NULL", irp->scard_index);
1520 LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index);
15611521 return;
15621522 }
15631523
15641524 if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_BEGIN_TRANSACTION)) == NULL)
15651525 {
1566 log_error("scard_make_new_ioctl failed");
1526 LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl failed");
15671527 return;
15681528 }
15691529
16251585
16261586 if ((sc = smartcards[irp->scard_index]) == NULL)
16271587 {
1628 log_error("smartcards[%d] is NULL", irp->scard_index);
1588 LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index);
16291589 return;
16301590 }
16311591
16321592 if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_END_TRANSACTION)) == NULL)
16331593 {
1634 log_error("scard_make_new_ioctl failed");
1594 LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl failed");
16351595 return;
16361596 }
16371597
16931653
16941654 if ((sc = smartcards[irp->scard_index]) == NULL)
16951655 {
1696 log_error("smartcards[%d] is NULL", irp->scard_index);
1656 LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index);
16971657 return;
16981658 }
16991659
17001660 ioctl = wide ? SCARD_IOCTL_STATUS_W : SCARD_IOCTL_STATUS_A;
17011661 if ((s = scard_make_new_ioctl(irp, ioctl)) == NULL)
17021662 {
1703 log_error("scard_make_new_ioctl");
1704 return;
1705 }
1706 /*
1663 LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl");
1664 return;
1665 }
1666 /*
17071667 30 00 00 00
17081668 00 00 00 00
17091669 04 00 00 00
17181678 04 00 00 00
17191679 09 00 00 00 hCard
17201680 00 00 00 00
1721 */
1681 */
17221682 s_push_layer(s, mcs_hdr, 4); /* bytes, set later */
17231683 out_uint32_le(s, 0x00000000);
17241684 out_uint32_le(s, context_bytes);
17531713
17541714 bytes = (int) (s->end - s->data);
17551715
1756 //g_hexdump(s->data, bytes);
1716 LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", s->data, bytes);
17571717
17581718 /* send to client */
17591719 send_channel_data(g_rdpdr_chan_id, s->data, bytes);
17791739
17801740 if ((sc = smartcards[irp->scard_index]) == NULL)
17811741 {
1782 log_error("smartcards[%d] is NULL", irp->scard_index);
1742 LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index);
17831743 return;
17841744 }
17851745
17861746 if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_DISCONNECT)) == NULL)
17871747 {
1788 log_error("scard_make_new_ioctl failed");
1748 LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl failed");
17891749 return;
17901750 }
17911751
18471807
18481808 if ((sc = smartcards[irp->scard_index]) == NULL)
18491809 {
1850 log_error("smartcards[%d] is NULL", irp->scard_index);
1810 LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index);
18511811 return 1;
18521812 }
18531813
18541814 if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_TRANSMIT)) == NULL)
18551815 {
1856 log_error("scard_make_new_ioctl");
1816 LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl");
18571817 return 1;
18581818 }
18591819
1860 log_debug("send_bytes %d recv_bytes %d send dwProtocol %d cbPciLength %d "
1820 LOG_DEVEL(LOG_LEVEL_DEBUG, "send_bytes %d recv_bytes %d send dwProtocol %d cbPciLength %d "
18611821 "extra_bytes %d recv dwProtocol %d cbPciLength %d extra_bytes %d",
18621822 send_bytes, recv_bytes, send_ior->dwProtocol, send_ior->cbPciLength,
18631823 send_ior->extra_bytes, recv_ior->dwProtocol, recv_ior->cbPciLength,
20121972 /* send to client */
20131973 send_channel_data(g_rdpdr_chan_id, s->data, bytes);
20141974
2015 #if 0
2016 g_writeln("scard_send_Transmit:");
2017 g_hexdump(s->data, bytes);
2018 #endif
1975 LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "scard_send_Transmit:", s->data, bytes);
20191976
20201977 free_stream(s);
20211978 return 0;
20381995
20391996 if ((sc = smartcards[irp->scard_index]) == NULL)
20401997 {
2041 log_error("smartcards[%d] is NULL", irp->scard_index);
1998 LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index);
20421999 return 1;
20432000 }
20442001
20452002 if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_CONTROL)) == NULL)
20462003 {
2047 log_error("scard_make_new_ioctl");
2004 LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl");
20482005 return 1;
20492006 }
20502007
20882045
20892046 bytes = (int) (s->end - s->data);
20902047
2091 //g_hexdump(s->data, bytes);
2048 LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", s->data, bytes);
20922049
20932050 /* send to client */
20942051 send_channel_data(g_rdpdr_chan_id, s->data, bytes);
21112068
21122069 if ((sc = smartcards[irp->scard_index]) == NULL)
21132070 {
2114 log_error("smartcards[%d] is NULL", irp->scard_index);
2071 LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index);
21152072 return 1;
21162073 }
21172074
21182075 if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_CANCEL)) == NULL)
21192076 {
2120 log_error("scard_make_new_ioctl");
2077 LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl");
21212078 return 1;
21222079 }
21232080
21632120
21642121 if ((sc = smartcards[irp->scard_index]) == NULL)
21652122 {
2166 log_error("smartcards[%d] is NULL", irp->scard_index);
2123 LOG_DEVEL(LOG_LEVEL_ERROR, "smartcards[%d] is NULL", irp->scard_index);
21672124 return 1;
21682125 }
21692126
21702127 if ((s = scard_make_new_ioctl(irp, SCARD_IOCTL_GETATTRIB)) == NULL)
21712128 {
2172 log_error("scard_make_new_ioctl");
2129 LOG_DEVEL(LOG_LEVEL_ERROR, "scard_make_new_ioctl");
21732130 return 1;
21742131 }
21752132
22292186 {
22302187 tui32 len;
22312188
2232 log_debug("entered");
2189 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered");
22332190 /* sanity check */
22342191 if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
22352192 {
2236 log_error("DeviceId/CompletionId do not match those in IRP");
2193 LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP");
22372194 return;
22382195 }
22392196 /* get OutputBufferLen */
22402197 xstream_rd_u32_le(s, len);
22412198 scard_function_establish_context_return(irp->user_data, s, len, IoStatus);
22422199 devredir_irp_delete(irp);
2243 log_debug("leaving");
2200 LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving");
22442201 }
22452202
22462203 /**
22532210 {
22542211 tui32 len;
22552212
2256 log_debug("entered");
2213 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered");
22572214 /* sanity check */
22582215 if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
22592216 {
2260 log_error("DeviceId/CompletionId do not match those in IRP");
2217 LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP");
22612218 return;
22622219 }
22632220 /* get OutputBufferLen */
22642221 xstream_rd_u32_le(s, len);
22652222 scard_function_release_context_return(irp->user_data, s, len, IoStatus);
22662223 devredir_irp_delete(irp);
2267 log_debug("leaving");
2224 LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving");
22682225 }
22692226
22702227 /**
22772234 {
22782235 tui32 len;
22792236
2280 log_debug("entered");
2237 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered");
22812238
22822239 /* sanity check */
22832240 if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
22842241 {
2285 log_error("DeviceId/CompletionId do not match those in IRP");
2242 LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP");
22862243 return;
22872244 }
22882245
22902247 xstream_rd_u32_le(s, len);
22912248 scard_function_is_context_valid_return(irp->user_data, s, len, IoStatus);
22922249 devredir_irp_delete(irp);
2293 log_debug("leaving");
2250 LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving");
22942251 }
22952252
22962253 /**
23032260 {
23042261 tui32 len;
23052262
2306 log_debug("entered");
2263 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered");
23072264 /* sanity check */
23082265 if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
23092266 {
2310 log_error("DeviceId/CompletionId do not match those in IRP");
2267 LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP");
23112268 return;
23122269 }
23132270 /* get OutputBufferLen */
23142271 xstream_rd_u32_le(s, len);
23152272 scard_function_list_readers_return(irp->user_data, s, len, IoStatus);
23162273 devredir_irp_delete(irp);
2317 log_debug("leaving");
2274 LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving");
23182275 }
23192276
23202277 /**
23272284 {
23282285 tui32 len;
23292286
2330 log_debug("entered");
2287 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered");
23312288 /* sanity check */
23322289 if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
23332290 {
2334 log_error("DeviceId/CompletionId do not match those in IRP");
2291 LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP");
23352292 return;
23362293 }
23372294 /* get OutputBufferLen */
23382295 xstream_rd_u32_le(s, len);
23392296 scard_function_get_status_change_return(irp->user_data, s, len, IoStatus);
23402297 devredir_irp_delete(irp);
2341 log_debug("leaving");
2298 LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving");
23422299 }
23432300
23442301 /**
23512308 {
23522309 tui32 len;
23532310
2354 log_debug("entered");
2311 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered");
23552312
23562313 /* sanity check */
23572314 if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
23582315 {
2359 log_error("DeviceId/CompletionId do not match those in IRP");
2316 LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP");
23602317 return;
23612318 }
23622319
23662323 scard_function_connect_return(irp->user_data, s, len, IoStatus);
23672324 devredir_irp_delete(irp);
23682325
2369 log_debug("leaving");
2326 LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving");
23702327 }
23712328
23722329 /**
23792336 {
23802337 tui32 len;
23812338
2382 log_debug("entered");
2339 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered");
23832340
23842341 /* sanity check */
23852342 if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
23862343 {
2387 log_error("DeviceId/CompletionId do not match those in IRP");
2344 LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP");
23882345 return;
23892346 }
23902347
23922349 xstream_rd_u32_le(s, len);
23932350 scard_function_reconnect_return(irp->user_data, s, len, IoStatus);
23942351 devredir_irp_delete(irp);
2395 log_debug("leaving");
2352 LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving");
23962353 }
23972354
23982355 /**
24052362 {
24062363 tui32 len;
24072364
2408 log_debug("entered");
2365 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered");
24092366
24102367 /* sanity check */
24112368 if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
24122369 {
2413 log_error("DeviceId/CompletionId do not match those in IRP");
2370 LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP");
24142371 return;
24152372 }
24162373
24182375 xstream_rd_u32_le(s, len);
24192376 scard_function_begin_transaction_return(irp->user_data, s, len, IoStatus);
24202377 devredir_irp_delete(irp);
2421 log_debug("leaving");
2378 LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving");
24222379 }
24232380
24242381 /**
24312388 {
24322389 tui32 len;
24332390
2434 log_debug("entered");
2391 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered");
24352392
24362393 /* sanity check */
24372394 if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
24382395 {
2439 log_error("DeviceId/CompletionId do not match those in IRP");
2396 LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP");
24402397 return;
24412398 }
24422399
24442401 xstream_rd_u32_le(s, len);
24452402 scard_function_end_transaction_return(irp->user_data, s, len, IoStatus);
24462403 devredir_irp_delete(irp);
2447 log_debug("leaving");
2404 LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving");
24482405 }
24492406
24502407 /**
24572414 {
24582415 tui32 len;
24592416
2460 log_debug("entered");
2417 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered");
24612418
24622419 /* sanity check */
24632420 if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
24642421 {
2465 log_error("DeviceId/CompletionId do not match those in IRP");
2422 LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP");
24662423 return;
24672424 }
24682425
24702427 xstream_rd_u32_le(s, len);
24712428 scard_function_status_return(irp->user_data, s, len, IoStatus);
24722429 devredir_irp_delete(irp);
2473 log_debug("leaving");
2430 LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving");
24742431 }
24752432
24762433 /**
24832440 {
24842441 tui32 len;
24852442
2486 log_debug("entered");
2443 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered");
24872444
24882445 /* sanity check */
24892446 if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
24902447 {
2491 log_error("DeviceId/CompletionId do not match those in IRP");
2448 LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP");
24922449 return;
24932450 }
24942451
24962453 xstream_rd_u32_le(s, len);
24972454 scard_function_disconnect_return(irp->user_data, s, len, IoStatus);
24982455 devredir_irp_delete(irp);
2499 log_debug("leaving");
2456 LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving");
25002457 }
25012458
25022459 /**
25082465 {
25092466 tui32 len;
25102467
2511 log_debug("entered");
2468 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered");
25122469
25132470 /* sanity check */
25142471 if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
25152472 {
2516 log_error("DeviceId/CompletionId do not match those in IRP");
2473 LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP");
25172474 return;
25182475 }
25192476
25212478 xstream_rd_u32_le(s, len);
25222479 scard_function_transmit_return(irp->user_data, s, len, IoStatus);
25232480 devredir_irp_delete(irp);
2524 log_debug("leaving");
2481 LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving");
25252482 }
25262483
25272484 /**
25292486 *****************************************************************************/
25302487 static void
25312488 scard_handle_Control_Return(struct stream *s, IRP *irp, tui32 DeviceId,
2532 tui32 CompletionId,tui32 IoStatus)
2489 tui32 CompletionId, tui32 IoStatus)
25332490 {
25342491 tui32 len;
25352492
2536 log_debug("entered");
2493 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered");
25372494
25382495 /* sanity check */
25392496 if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
25402497 {
2541 log_error("DeviceId/CompletionId do not match those in IRP");
2498 LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP");
25422499 return;
25432500 }
25442501
25462503 xstream_rd_u32_le(s, len);
25472504 scard_function_control_return(irp->user_data, s, len, IoStatus);
25482505 devredir_irp_delete(irp);
2549 log_debug("leaving");
2506 LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving");
25502507 }
25512508
25522509 /**
25582515 {
25592516 tui32 len;
25602517
2561 log_debug("entered");
2518 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered");
25622519
25632520 /* sanity check */
25642521 if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
25652522 {
2566 log_error("DeviceId/CompletionId do not match those in IRP");
2523 LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP");
25672524 return;
25682525 }
25692526
25712528 xstream_rd_u32_le(s, len);
25722529 scard_function_cancel_return(irp->user_data, s, len, IoStatus);
25732530 devredir_irp_delete(irp);
2574 log_debug("leaving");
2531 LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving");
25752532 }
25762533
25772534 /**
25832540 {
25842541 tui32 len;
25852542
2586 log_debug("entered");
2543 LOG_DEVEL(LOG_LEVEL_DEBUG, "entered");
25872544
25882545 /* sanity check */
25892546 if ((DeviceId != irp->DeviceId) || (CompletionId != irp->CompletionId))
25902547 {
2591 log_error("DeviceId/CompletionId do not match those in IRP");
2548 LOG_DEVEL(LOG_LEVEL_ERROR, "DeviceId/CompletionId do not match those in IRP");
25922549 return;
25932550 }
25942551
25962553 xstream_rd_u32_le(s, len);
25972554 scard_function_get_attrib_return(irp->user_data, s, len, IoStatus);
25982555 devredir_irp_delete(irp);
2599 log_debug("leaving");
2600 }
2556 LOG_DEVEL(LOG_LEVEL_DEBUG, "leaving");
2557 }
3232 #define PCSC_STANDIN 1
3333
3434 #include "os_calls.h"
35 #include "string_calls.h"
3536 #include "smartcard.h"
3637 #include "log.h"
3738 #include "irp.h"
4243
4344 #if PCSC_STANDIN
4445
45 #define LLOG_LEVEL 1
46 #define LLOGLN(_level, _args) \
47 do \
48 { \
49 if (_level < LLOG_LEVEL) \
50 { \
51 g_write("chansrv:smartcard_pcsc [%10.10u]: ", g_time3()); \
52 g_writeln _args ; \
53 } \
54 } \
55 while (0)
5646
5747 extern int g_display_num; /* in chansrv.c */
5848
9585 {
9686 struct pcsc_uds_client *uds_client;
9787
98 LLOGLN(10, ("create_uds_client:"));
88 LOG_DEVEL(LOG_LEVEL_DEBUG, "create_uds_client:");
9989 if (con == 0)
10090 {
10191 return 0;
119109 struct pcsc_uds_client *uds_client;
120110 int index;
121111
122 LLOGLN(10, ("get_uds_client_by_id:"));
112 LOG_DEVEL(LOG_LEVEL_DEBUG, "get_uds_client_by_id:");
123113 if (uds_client_id == 0)
124114 {
125 LLOGLN(10, ("get_uds_client_by_id: uds_client_id zero"));
115 LOG(LOG_LEVEL_ERROR, "get_uds_client_by_id: uds_client_id is zero");
126116 return 0;
127117 }
128118 if (g_uds_clients == 0)
129119 {
130 LLOGLN(10, ("get_uds_client_by_id: g_uds_clients is nil"));
120 LOG(LOG_LEVEL_ERROR, "get_uds_client_by_id: g_uds_clients is nil");
131121 return 0;
132122 }
133 LLOGLN(10, (" count %d", g_uds_clients->count));
123 LOG_DEVEL(LOG_LEVEL_DEBUG, " count %d", g_uds_clients->count);
134124 for (index = 0; index < g_uds_clients->count; index++)
135125 {
136126 uds_client = (struct pcsc_uds_client *)
140130 return uds_client;
141131 }
142132 }
143 LLOGLN(10, ("get_uds_client_by_id: can't find uds_client_id %d",
144 uds_client_id));
133 LOG(LOG_LEVEL_ERROR, "get_uds_client_by_id: can't find uds_client_id %d",
134 uds_client_id);
145135 return 0;
146136 }
147137
183173 int index;
184174 int index1;
185175
186 LLOGLN(10, ("get_pcsc_card_by_app_card:"));
187 LLOGLN(10, (" app_card %d", app_card));
176 LOG_DEVEL(LOG_LEVEL_DEBUG, "get_pcsc_card_by_app_card: app_card %d",
177 app_card);
188178 if (uds_client == 0)
189179 {
190 LLOGLN(0, ("get_pcsc_card_by_app_card: error"));
180 LOG(LOG_LEVEL_ERROR, "get_pcsc_card_by_app_card: uds_client is null");
191181 return 0;
192182 }
193183 if (uds_client->contexts == 0)
194184 {
195 LLOGLN(0, ("get_pcsc_card_by_app_card: error"));
185 LOG(LOG_LEVEL_ERROR, "get_pcsc_card_by_app_card: uds_client->contexts is null");
196186 return 0;
197187 }
198188 for (index = 0; index < uds_client->contexts->count; index++)
222212 }
223213 }
224214 }
225 LLOGLN(0, ("get_pcsc_card_by_app_card: error"));
215 LOG(LOG_LEVEL_ERROR, "get_pcsc_card_by_app_card: app_card %d "
216 "not found in uds_client->contexts->cards", app_card);
226217 return 0;
227218 }
228219
235226 struct pcsc_context *context;
236227 struct pcsc_card *card;
237228
238 LLOGLN(10, ("free_uds_client:"));
229 LOG_DEVEL(LOG_LEVEL_DEBUG, "free_uds_client:");
239230 if (uds_client == 0)
240231 {
241232 return 0;
262253 }
263254 list_delete(context->cards);
264255 }
265 LLOGLN(10, (" left over context %p", context->context));
256 LOG_DEVEL(LOG_LEVEL_DEBUG, " left over context %p", context->context);
266257 scard_send_cancel(0, context->context, context->context_bytes);
267258 scard_send_release_context(0, context->context,
268259 context->context_bytes);
283274 {
284275 struct pcsc_context *pcscContext;
285276
286 LLOGLN(10, ("uds_client_add_context:"));
277 LOG_DEVEL(LOG_LEVEL_DEBUG, "uds_client_add_context:");
287278 pcscContext = (struct pcsc_context *)
288279 g_malloc(sizeof(struct pcsc_context), 1);
289280 if (pcscContext == 0)
290281 {
291 LLOGLN(0, ("uds_client_add_context: error"));
282 LOG(LOG_LEVEL_ERROR,
283 "uds_client_add_context: failed to allocate memory for pcsc_context");
292284 return 0;
293285 }
294286 g_autoinc++;
300292 uds_client->contexts = list_create();
301293 if (uds_client->contexts == 0)
302294 {
303 LLOGLN(0, ("uds_client_add_context: error"));
295 LOG(LOG_LEVEL_ERROR,
296 "uds_client_add_context: failed to allocate memory for "
297 "uds_client->contexts");
304298 return 0;
305299 }
306300 }
317311
318312 if (uds_client->contexts == 0)
319313 {
320 LLOGLN(0, ("uds_client_remove_context: error"));
314 LOG(LOG_LEVEL_ERROR,
315 "uds_client_remove_context: uds_client->contexts is null");
321316 return 1;
322317 }
323318 index = list_index_of(uds_client->contexts, (tintptr) acontext);
324319 if (index < 0)
325320 {
326 LLOGLN(0, ("uds_client_remove_context: error"));
321 LOG(LOG_LEVEL_ERROR,
322 "uds_client_remove_context: pcsc_context not found in uds_client->contexts");
327323 return 1;
328324 }
329325 list_remove_item(uds_client->contexts, index);
339335 {
340336 struct pcsc_card *pcscCard;
341337
342 LLOGLN(10, ("context_add_card: card_bytes %d", card_bytes));
338 LOG_DEVEL(LOG_LEVEL_DEBUG, "context_add_card: card_bytes %d", card_bytes);
343339 pcscCard = (struct pcsc_card *)
344340 g_malloc(sizeof(struct pcsc_card), 1);
345341 if (pcscCard == 0)
346342 {
347 LLOGLN(0, ("context_add_card: error"));
343 LOG(LOG_LEVEL_ERROR,
344 "context_add_card: failed to allocate memmory for pcsc_card");
348345 return 0;
349346 }
350347 g_autoinc++;
356353 acontext->cards = list_create();
357354 if (acontext->cards == 0)
358355 {
359 LLOGLN(0, ("context_add_card: error"));
356 LOG(LOG_LEVEL_ERROR, "context_add_card: failed to allocate "
357 "memmory for uds_client->contexts->cards");
360358 return 0;
361359 }
362360 }
363361 list_add_item(acontext->cards, (tintptr) pcscCard);
364 LLOGLN(10, (" new app_card %d", pcscCard->app_card));
362 LOG_DEVEL(LOG_LEVEL_DEBUG, " new app_card %d", pcscCard->app_card);
365363 return pcscCard;
366364 }
367365
372370 struct pcsc_uds_client *uds_client;
373371 int index;
374372
375 LLOGLN(10, ("scard_pcsc_get_wait_objs:"));
373 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_pcsc_get_wait_objs:");
376374 if (g_lis != 0)
377375 {
378376 trans_get_wait_objs(g_lis, objs, count);
399397 struct pcsc_uds_client *uds_client;
400398 int index;
401399
402 LLOGLN(10, ("scard_pcsc_check_wait_objs:"));
400 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_pcsc_check_wait_objs:");
403401 if (g_lis != 0)
404402 {
405403 if (trans_check_wait_objs(g_lis) != 0)
406404 {
407 LLOGLN(0, ("scard_pcsc_check_wait_objs: g_lis trans_check_wait_objs error"));
405 LOG(LOG_LEVEL_ERROR,
406 "scard_pcsc_check_wait_objs: g_lis trans_check_wait_objs error");
408407 }
409408 }
410409 if (g_uds_clients != 0)
438437 struct pcsc_uds_client *uds_client;
439438 void *user_data;
440439
441 LLOGLN(10, ("scard_process_establish_context:"));
440 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_establish_context:");
442441 uds_client = (struct pcsc_uds_client *) (con->callback_data);
443442 in_uint32_le(in_s, dwScope);
444 LLOGLN(10, ("scard_process_establish_context: dwScope 0x%8.8x", dwScope));
443 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_establish_context: dwScope 0x%8.8x", dwScope);
445444 user_data = (void *) (tintptr) (uds_client->uds_client_id);
446445 scard_send_establish_context(user_data, dwScope);
447446 return 0;
464463 struct trans *con;
465464 struct pcsc_context *lcontext;
466465
467 LLOGLN(10, ("scard_function_establish_context_return:"));
468 LLOGLN(10, (" status 0x%8.8x", status));
466 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_establish_context_return:");
467 LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status);
469468 uds_client_id = (int) (tintptr) user_data;
470469 uds_client = (struct pcsc_uds_client *)
471470 get_uds_client_by_id(uds_client_id);
472471 if (uds_client == 0)
473472 {
474 LLOGLN(0, ("scard_function_establish_context_return: "
475 "get_uds_client_by_id failed"));
473 LOG(LOG_LEVEL_ERROR, "scard_function_establish_context_return: "
474 "get_uds_client_by_id failed to find uds_client_id %d",
475 uds_client_id);
476476 return 1;
477477 }
478478 con = uds_client->con;
485485 in_uint32_le(in_s, context_bytes);
486486 if (context_bytes > 16)
487487 {
488 LLOGLN(0, ("scard_function_establish_context_return: opps "
489 "context_bytes %d", context_bytes));
490 g_hexdump(in_s->p, context_bytes);
488 LOG(LOG_LEVEL_ERROR, "scard_function_establish_context_return: opps "
489 "context_bytes %d", context_bytes);
490 LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", in_s->p, context_bytes);
491491 return 1;
492492 }
493493 in_uint8a(in_s, context, context_bytes);
494494 lcontext = uds_client_add_context(uds_client, context, context_bytes);
495495 app_context = lcontext->app_context;
496 LLOGLN(10, ("scard_function_establish_context_return: "
497 "app_context %d", app_context));
496 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_establish_context_return: "
497 "app_context %d", app_context);
498498 }
499499 out_s = trans_get_out_s(con, 8192);
500500 s_push_layer(out_s, iso_hdr, 8);
518518 struct pcsc_context *lcontext;
519519 void *user_data;
520520
521 LLOGLN(10, ("scard_process_release_context:"));
521 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_release_context:");
522522 uds_client = (struct pcsc_uds_client *) (con->callback_data);
523523 in_uint32_le(in_s, hContext);
524 LLOGLN(10, ("scard_process_release_context: hContext 0x%8.8x", hContext));
524 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_release_context: hContext 0x%8.8x", hContext);
525525 user_data = (void *) (tintptr) (uds_client->uds_client_id);
526526 lcontext = get_pcsc_context_by_app_context(uds_client, hContext);
527527 if (lcontext == 0)
528528 {
529 LLOGLN(0, ("scard_process_release_context: "
530 "get_pcsc_context_by_app_context failed"));
529 LOG(LOG_LEVEL_ERROR, "scard_process_release_context: "
530 "get_pcsc_context_by_app_context failed");
531531 return 1;
532532 }
533533 scard_send_release_context(user_data, lcontext->context,
549549 struct pcsc_uds_client *uds_client;
550550 struct trans *con;
551551
552 LLOGLN(10, ("scard_function_release_context_return:"));
553 LLOGLN(10, (" status 0x%8.8x", status));
552 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_release_context_return:");
553 LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status);
554554 uds_client_id = (int) (tintptr) user_data;
555555 uds_client = (struct pcsc_uds_client *)
556556 get_uds_client_by_id(uds_client_id);
557557 if (uds_client == 0)
558558 {
559 LLOGLN(0, ("scard_function_release_context_return: "
560 "get_uds_client_by_id failed"));
559 LOG(LOG_LEVEL_ERROR, "scard_function_release_context_return: "
560 "get_uds_client_by_id failed to find uds_client_id %d",
561 uds_client_id);
561562 return 1;
562563 }
563564 con = uds_client->con;
585586 scard_process_list_readers(struct trans *con, struct stream *in_s)
586587 {
587588 int hContext;
588 int bytes_groups;
589 unsigned int bytes_groups;
589590 int cchReaders;
590 char *groups;
591 /*
592 * At the time of writing, the groups strings which can be sent
593 * over this interface are all small:-
594 *
595 * "SCard$AllReaders", "SCard$DefaultReaders", "SCard$LocalReaders" and
596 * "SCard$SystemReaders"
597 *
598 * We'll allow a bit extra in case the interface changes
599 */
600 char groups[256];
591601 struct pcsc_uds_client *uds_client;
592602 struct pcsc_context *lcontext;
593603 struct pcsc_list_readers *pcscListReaders;
594604
595 LLOGLN(10, ("scard_process_list_readers:"));
605 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_list_readers:");
596606 uds_client = (struct pcsc_uds_client *) (con->callback_data);
597607 in_uint32_le(in_s, hContext);
598608 in_uint32_le(in_s, bytes_groups);
599 groups = (char *) g_malloc(bytes_groups + 1, 1);
609 if (bytes_groups > (sizeof(groups) - 1))
610 {
611 LOG(LOG_LEVEL_ERROR, "scard_process_list_readers: Unreasonable string length %u",
612 bytes_groups);
613 return 1;
614 }
600615 in_uint8a(in_s, groups, bytes_groups);
616 groups[bytes_groups] = '\0';
601617 in_uint32_le(in_s, cchReaders);
602 LLOGLN(10, ("scard_process_list_readers: hContext 0x%8.8x cchReaders %d",
603 hContext, cchReaders));
618 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_list_readers: hContext 0x%8.8x cchReaders %d",
619 hContext, cchReaders);
604620 lcontext = get_pcsc_context_by_app_context(uds_client, hContext);
605621 if (lcontext == 0)
606622 {
607 LLOGLN(0, ("scard_process_list_readers: "
608 "get_pcsc_context_by_app_context failed"));
623 LOG(LOG_LEVEL_ERROR, "scard_process_list_readers: "
624 "get_pcsc_context_by_app_context failed");
609625 g_free(groups);
610626 return 1;
611627 }
614630 pcscListReaders->cchReaders = cchReaders;
615631 scard_send_list_readers(pcscListReaders, lcontext->context,
616632 lcontext->context_bytes, groups, cchReaders, 1);
617 g_free(groups);
618633 return 0;
619634 }
620635
639654 struct trans *con;
640655 struct pcsc_list_readers *pcscListReaders;
641656
642 LLOGLN(10, ("scard_function_list_readers_return:"));
643 LLOGLN(10, (" status 0x%8.8x", status));
657 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_list_readers_return:");
658 LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status);
644659 pcscListReaders = (struct pcsc_list_readers *) user_data;
645660 if (pcscListReaders == 0)
646661 {
647 LLOGLN(0, ("scard_function_list_readers_return: "
648 "pcscListReaders is nil"));
662 LOG(LOG_LEVEL_ERROR, "scard_function_list_readers_return: "
663 "pcscListReaders is nil");
649664 return 1;
650665 }
651666 uds_client_id = pcscListReaders->uds_client_id;
655670 get_uds_client_by_id(uds_client_id);
656671 if (uds_client == 0)
657672 {
658 LLOGLN(0, ("scard_function_list_readers_return: "
659 "get_uds_client_by_id failed, could not find id %d",
660 uds_client_id));
673 LOG(LOG_LEVEL_ERROR, "scard_function_list_readers_return: "
674 "get_uds_client_by_id failed, could not find id %d",
675 uds_client_id);
661676 return 1;
662677 }
663678 con = uds_client->con;
734749 void *user_data;
735750 struct pcsc_context *lcontext;
736751
737 LLOGLN(10, ("scard_process_connect:"));
752 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_connect:");
738753 uds_client = (struct pcsc_uds_client *) (con->callback_data);
739754 g_memset(&rs, 0, sizeof(rs));
740755 in_uint32_le(in_s, hContext);
741756 in_uint8a(in_s, rs.reader_name, 100);
742757 in_uint32_le(in_s, rs.dwShareMode);
743758 in_uint32_le(in_s, rs.dwPreferredProtocols);
744 LLOGLN(10, ("scard_process_connect: rs.reader_name %s dwShareMode 0x%8.8x "
745 "dwPreferredProtocols 0x%8.8x", rs.reader_name, rs.dwShareMode,
746 rs.dwPreferredProtocols));
759 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_connect: rs.reader_name %s dwShareMode 0x%8.8x "
760 "dwPreferredProtocols 0x%8.8x", rs.reader_name, rs.dwShareMode,
761 rs.dwPreferredProtocols);
747762 user_data = (void *) (tintptr) (uds_client->uds_client_id);
748763 lcontext = get_pcsc_context_by_app_context(uds_client, hContext);
749764 if (lcontext == 0)
750765 {
751 LLOGLN(0, ("scard_process_connect: "
752 "get_pcsc_context_by_app_context failed"));
766 LOG(LOG_LEVEL_ERROR, "scard_process_connect: "
767 "get_pcsc_context_by_app_context failed");
753768 return 1;
754769 }
755770 uds_client->connect_context = lcontext;
775790 int card_bytes;
776791 struct pcsc_card *lcard;
777792
778 LLOGLN(10, ("scard_function_connect_return:"));
779 LLOGLN(10, (" status 0x%8.8x", status));
793 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_connect_return:");
794 LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status);
780795 uds_client_id = (int) (tintptr) user_data;
781796 uds_client = (struct pcsc_uds_client *)
782797 get_uds_client_by_id(uds_client_id);
783798 if (uds_client == 0)
784799 {
785 LLOGLN(0, ("scard_function_connect_return: "
786 "get_uds_client_by_id failed"));
800 LOG(LOG_LEVEL_ERROR, "scard_function_connect_return: "
801 "get_uds_client_by_id failed to find uds_client_id %d",
802 uds_client_id);
787803 return 1;
788804 }
789805 con = uds_client->con;
800816 lcard = context_add_card(uds_client, uds_client->connect_context,
801817 card, card_bytes);
802818 hCard = lcard->app_card;
803 LLOGLN(10, (" hCard %d dwActiveProtocol %d", hCard,
804 dwActiveProtocol));
819 LOG_DEVEL(LOG_LEVEL_DEBUG, " hCard %d dwActiveProtocol %d", hCard,
820 dwActiveProtocol);
805821 }
806822 else
807823 {
833849 struct pcsc_context *lcontext;
834850 struct pcsc_card *lcard;
835851
836 LLOGLN(10, ("scard_process_disconnect:"));
852 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_disconnect:");
837853 uds_client = (struct pcsc_uds_client *) (con->callback_data);
838854 in_uint32_le(in_s, hCard);
839855 in_uint32_le(in_s, dwDisposition);
841857 lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext);
842858 if ((lcontext == 0) || (lcard == 0))
843859 {
844 LLOGLN(0, ("scard_process_disconnect: "
845 "get_pcsc_card_by_app_card failed"));
860 LOG(LOG_LEVEL_ERROR, "scard_process_disconnect: "
861 "get_pcsc_card_by_app_card failed");
846862 return 1;
847863 }
848864 scard_send_disconnect(user_data,
863879 struct pcsc_uds_client *uds_client;
864880 struct trans *con;
865881
866 LLOGLN(10, ("scard_function_disconnect_return:"));
867 LLOGLN(10, (" status 0x%8.8x", status));
882 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_disconnect_return:");
883 LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status);
868884 uds_client_id = (int) (tintptr) user_data;
869885 uds_client = (struct pcsc_uds_client *)
870886 get_uds_client_by_id(uds_client_id);
871887 if (uds_client == 0)
872888 {
873 LLOGLN(0, ("scard_function_disconnect_return: "
874 "get_uds_client_by_id failed"));
889 LOG(LOG_LEVEL_ERROR, "scard_function_disconnect_return: "
890 "get_uds_client_by_id failed to find uds_client_id %d",
891 uds_client_id);
875892 return 1;
876893 }
877894 con = uds_client->con;
897914 struct pcsc_card *lcard;
898915 struct pcsc_context *lcontext;
899916
900 LLOGLN(10, ("scard_process_begin_transaction:"));
917 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_begin_transaction:");
901918 uds_client = (struct pcsc_uds_client *) (con->callback_data);
902919 in_uint32_le(in_s, hCard);
903 LLOGLN(10, ("scard_process_begin_transaction: hCard 0x%8.8x", hCard));
920 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_begin_transaction: hCard 0x%8.8x", hCard);
904921 user_data = (void *) (tintptr) (uds_client->uds_client_id);
905922 lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext);
906923 if ((lcard == 0) || (lcontext == 0))
907924 {
908 LLOGLN(0, ("scard_process_begin_transaction: "
909 "get_pcsc_card_by_app_card failed"));
925 LOG(LOG_LEVEL_ERROR, "scard_process_begin_transaction: "
926 "get_pcsc_card_by_app_card failed");
910927 return 1;
911928 }
912929 scard_send_begin_transaction(user_data,
928945 struct pcsc_uds_client *uds_client;
929946 struct trans *con;
930947
931 LLOGLN(10, ("scard_function_begin_transaction_return:"));
932 LLOGLN(10, (" status 0x%8.8x", status));
948 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_begin_transaction_return:");
949 LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status);
933950 uds_client_id = (int) (tintptr) user_data;
934951 uds_client = (struct pcsc_uds_client *)
935952 get_uds_client_by_id(uds_client_id);
936953 if (uds_client == 0)
937954 {
938 LLOGLN(0, ("scard_function_begin_transaction_return: "
939 "get_uds_client_by_id failed"));
955 LOG(LOG_LEVEL_ERROR, "scard_function_begin_transaction_return: "
956 "get_uds_client_by_id failed to find uds_client_id %d",
957 uds_client_id);
940958 return 1;
941959 }
942960 con = uds_client->con;
963981 struct pcsc_card *lcard;
964982 struct pcsc_context *lcontext;
965983
966 LLOGLN(10, ("scard_process_end_transaction:"));
984 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_end_transaction:");
967985 uds_client = (struct pcsc_uds_client *) (con->callback_data);
968986 in_uint32_le(in_s, hCard);
969987 in_uint32_le(in_s, dwDisposition);
970 LLOGLN(10, ("scard_process_end_transaction: hCard 0x%8.8x", hCard));
988 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_end_transaction: hCard 0x%8.8x", hCard);
971989 user_data = (void *) (tintptr) (uds_client->uds_client_id);
972990 lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext);
973991 if ((lcard == 0) || (lcontext == 0))
974992 {
975 LLOGLN(0, ("scard_process_end_transaction: "
976 "get_pcsc_card_by_app_card failed"));
993 LOG(LOG_LEVEL_ERROR, "scard_process_end_transaction: "
994 "get_pcsc_card_by_app_card failed");
977995 return 1;
978996 }
979997 scard_send_end_transaction(user_data,
9961014 struct pcsc_uds_client *uds_client;
9971015 struct trans *con;
9981016
999 LLOGLN(10, ("scard_function_end_transaction_return:"));
1000 LLOGLN(10, (" status 0x%8.8x", status));
1017 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_end_transaction_return:");
1018 LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status);
10011019 uds_client_id = (int) (tintptr) user_data;
10021020 uds_client = (struct pcsc_uds_client *)
10031021 get_uds_client_by_id(uds_client_id);
10041022 if (uds_client == 0)
10051023 {
1006 LLOGLN(0, ("scard_function_end_transaction_return: "
1007 "get_uds_client_by_id failed"));
1024 LOG(LOG_LEVEL_ERROR, "scard_function_end_transaction_return: "
1025 "get_uds_client_by_id failed to find uds_client_id %d",
1026 uds_client_id);
10081027 return 1;
10091028 }
10101029 con = uds_client->con;
10541073 struct pcsc_context *lcontext;
10551074 struct pcsc_transmit *pcscTransmit;
10561075
1057 LLOGLN(10, ("scard_process_transmit:"));
1076 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_transmit:");
10581077 uds_client = (struct pcsc_uds_client *) (con->callback_data);
1059 LLOGLN(10, ("scard_process_transmit:"));
1078 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_transmit:");
10601079 in_uint32_le(in_s, hCard);
10611080 in_uint32_le(in_s, send_ior.dwProtocol);
10621081 in_uint32_le(in_s, send_ior.cbPciLength);
10691088 in_uint32_le(in_s, recv_ior.extra_bytes);
10701089 in_uint8p(in_s, recv_ior.extra_data, recv_ior.extra_bytes);
10711090 in_uint32_le(in_s, recv_bytes);
1072 LLOGLN(10, ("scard_process_transmit: send dwProtocol %d cbPciLength %d "
1073 "recv dwProtocol %d cbPciLength %d send_bytes %d ",
1074 send_ior.dwProtocol, send_ior.cbPciLength, recv_ior.dwProtocol,
1075 recv_ior.cbPciLength, send_bytes));
1076 LLOGLN(10, ("scard_process_transmit: recv_bytes %d", recv_bytes));
1091 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_transmit: send dwProtocol %d cbPciLength %d "
1092 "recv dwProtocol %d cbPciLength %d send_bytes %d ",
1093 send_ior.dwProtocol, send_ior.cbPciLength, recv_ior.dwProtocol,
1094 recv_ior.cbPciLength, send_bytes);
1095 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_transmit: recv_bytes %d", recv_bytes);
10771096 lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext);
10781097 if ((lcard == 0) || (lcontext == 0))
10791098 {
1080 LLOGLN(0, ("scard_process_transmit: "
1081 "get_pcsc_card_by_app_card failed"));
1099 LOG(LOG_LEVEL_ERROR, "scard_process_transmit: "
1100 "get_pcsc_card_by_app_card failed");
10821101 return 1;
10831102 }
10841103
11131132 struct trans *con;
11141133 struct pcsc_transmit *pcscTransmit;
11151134
1116 LLOGLN(10, ("scard_function_transmit_return:"));
1117 LLOGLN(10, (" status 0x%8.8x", status));
1135 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_transmit_return:");
1136 LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status);
11181137 pcscTransmit = (struct pcsc_transmit *) user_data;
11191138 recv_ior = pcscTransmit->recv_ior;
11201139 uds_client = (struct pcsc_uds_client *)
11231142
11241143 if (uds_client == 0)
11251144 {
1126 LLOGLN(0, ("scard_function_transmit_return: "
1127 "get_uds_client_by_id failed"));
1145 LOG(LOG_LEVEL_ERROR, "scard_function_transmit_return: "
1146 "get_uds_client_by_id failed");
11281147 return 1;
11291148 }
11301149 con = uds_client->con;
11571176 }
11581177
11591178 }
1160 LLOGLN(10, ("scard_function_transmit_return: cbRecvLength %d", cbRecvLength));
1179 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_transmit_return: cbRecvLength %d", cbRecvLength);
11611180 out_s = trans_get_out_s(con, 8192);
11621181 s_push_layer(out_s, iso_hdr, 8);
11631182 out_uint32_le(out_s, recv_ior.dwProtocol);
11901209 struct pcsc_context *lcontext;
11911210 struct pcsc_card *lcard;
11921211
1193 LLOGLN(10, ("scard_process_control:"));
1212 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_control:");
11941213 uds_client = (struct pcsc_uds_client *) (con->callback_data);
1195 LLOGLN(10, ("scard_process_control:"));
1214 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_control:");
11961215
11971216 in_uint32_le(in_s, hCard);
11981217 in_uint32_le(in_s, control_code);
12041223 lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext);
12051224 if ((lcard == 0) || (lcontext == 0))
12061225 {
1207 LLOGLN(0, ("scard_process_control: "
1208 "get_pcsc_card_by_app_card failed"));
1226 LOG(LOG_LEVEL_ERROR, "scard_process_control: "
1227 "get_pcsc_card_by_app_card failed");
12091228 return 1;
12101229 }
12111230 scard_send_control(user_data, lcontext->context, lcontext->context_bytes,
12311250 struct pcsc_uds_client *uds_client;
12321251 struct trans *con;
12331252
1234 LLOGLN(10, ("scard_function_control_return:"));
1235 LLOGLN(10, (" status 0x%8.8x", status));
1253 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_control_return:");
1254 LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status);
12361255 uds_client_id = (int) (tintptr) user_data;
12371256 uds_client = (struct pcsc_uds_client *)
12381257 get_uds_client_by_id(uds_client_id);
12391258 if (uds_client == 0)
12401259 {
1241 LLOGLN(0, ("scard_function_control_return: "
1242 "get_uds_client_by_id failed"));
1260 LOG(LOG_LEVEL_ERROR, "scard_function_control_return: "
1261 "get_uds_client_by_id failed to find uds_client_id %d",
1262 uds_client_id);
12431263 return 1;
12441264 }
12451265 con = uds_client->con;
12511271 in_uint32_le(in_s, cbRecvLength);
12521272 in_uint8p(in_s, recvBuf, cbRecvLength);
12531273 }
1254 LLOGLN(10, ("scard_function_control_return: cbRecvLength %d", cbRecvLength));
1274 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_control_return: cbRecvLength %d", cbRecvLength);
12551275 out_s = trans_get_out_s(con, 8192);
12561276 s_push_layer(out_s, iso_hdr, 8);
12571277 out_uint32_le(out_s, cbRecvLength);
12851305 struct pcsc_context *lcontext;
12861306 struct pcsc_status *pcscStatus;
12871307
1288 LLOGLN(10, ("scard_process_status:"));
1308 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_status:");
12891309 uds_client = (struct pcsc_uds_client *) (con->callback_data);
12901310
12911311 in_uint32_le(in_s, hCard);
12921312 in_uint32_le(in_s, cchReaderLen);
12931313 in_uint32_le(in_s, cbAtrLen);
1294 LLOGLN(10, ("scard_process_status: hCard 0x%8.8x cchReaderLen %d "
1295 "cbAtrLen %d", hCard, cchReaderLen, cbAtrLen));
1314 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_status: hCard 0x%8.8x cchReaderLen %d "
1315 "cbAtrLen %d", hCard, cchReaderLen, cbAtrLen);
12961316
12971317 lcard = get_pcsc_card_by_app_card(uds_client, hCard, &lcontext);
12981318 if ((lcard == 0) || (lcontext == 0))
12991319 {
1300 LLOGLN(0, ("scard_process_status: "
1301 "get_pcsc_card_by_app_card failed"));
1320 LOG(LOG_LEVEL_ERROR, "scard_process_status: "
1321 "get_pcsc_card_by_app_card failed");
13021322 return 1;
13031323 }
13041324 pcscStatus = (struct pcsc_status *) g_malloc(sizeof(struct pcsc_status), 1);
13311351 static int g_ms2pc[] = { PC_SCARD_UNKNOWN, PC_SCARD_ABSENT,
13321352 PC_SCARD_PRESENT, PC_SCARD_SWALLOWED,
13331353 PC_SCARD_POWERED, PC_SCARD_NEGOTIABLE,
1334 PC_SCARD_SPECIFIC };
1354 PC_SCARD_SPECIFIC
1355 };
13351356
13361357 /*****************************************************************************/
13371358 /* returns error */
13551376 struct trans *con;
13561377 struct pcsc_status *pcscStatus;
13571378
1358 LLOGLN(10, ("scard_function_status_return:"));
1359 LLOGLN(10, (" status 0x%8.8x", status));
1379 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_status_return:");
1380 LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status);
13601381
13611382 pcscStatus = (struct pcsc_status *) user_data;
13621383 if (pcscStatus == 0)
13631384 {
1364 LLOGLN(0, ("scard_function_status_return: pcscStatus is nil"));
1385 LOG(LOG_LEVEL_ERROR, "scard_function_status_return: pcscStatus is nil");
13651386 return 1;
13661387 }
13671388
13701391 get_uds_client_by_id(uds_client_id);
13711392 if (uds_client == 0)
13721393 {
1373 LLOGLN(0, ("scard_function_status_return: "
1374 "get_uds_client_by_id failed"));
1394 LOG(LOG_LEVEL_ERROR, "scard_function_status_return: "
1395 "get_uds_client_by_id failed to find uds_client_id %d",
1396 uds_client_id);
13751397 g_free(pcscStatus);
13761398 return 1;
13771399 }
14031425 }
14041426 if (dwReaderLen < 1)
14051427 {
1406 LLOGLN(0, ("scard_function_status_return: dwReaderLen < 1"));
1428 LOG(LOG_LEVEL_ERROR, "scard_function_status_return: dwReaderLen < 1");
14071429 dwReaderLen = 1;
14081430 }
14091431 if (dwReaderLen > 99)
14101432 {
1411 LLOGLN(0, ("scard_function_status_return: dwReaderLen too big "
1412 "0x%8.8x", dwReaderLen));
1433 LOG_DEVEL(LOG_LEVEL_WARNING, "scard_function_status_return: dwReaderLen too big "
1434 "0x%8.8x", dwReaderLen);
14131435 dwReaderLen = 99;
14141436 }
14151437 g_memset(reader_name, 0, sizeof(reader_name));
14201442 }
14211443 g_wcstombs(lreader_name, reader_name, 99);
14221444 }
1423 LLOGLN(10, ("scard_function_status_return: dwAtrLen %d dwReaderLen %d "
1424 "dwProtocol %d dwState %d name %s",
1425 dwAtrLen, dwReaderLen, dwProtocol, dwState, lreader_name));
1445 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_status_return: dwAtrLen %d dwReaderLen %d "
1446 "dwProtocol %d dwState %d name %s",
1447 dwAtrLen, dwReaderLen, dwProtocol, dwState, lreader_name);
14261448 out_s = trans_get_out_s(con, 8192);
14271449 s_push_layer(out_s, iso_hdr, 8);
14281450 dwReaderLen = g_strlen(lreader_name);
14551477 void *user_data;
14561478 struct pcsc_context *lcontext;
14571479
1458 LLOGLN(10, ("scard_process_get_status_change:"));
1480 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_get_status_change:");
14591481 uds_client = (struct pcsc_uds_client *) (con->callback_data);
14601482 in_uint32_le(in_s, hContext);
14611483 in_uint32_le(in_s, dwTimeout);
14621484 in_uint32_le(in_s, cReaders);
14631485 if ((cReaders < 0) || (cReaders > 16))
14641486 {
1465 LLOGLN(0, ("scard_process_get_status_change: bad cReaders %d", cReaders));
1487 LOG(LOG_LEVEL_ERROR, "scard_process_get_status_change: bad cReaders %d", cReaders);
14661488 return 1;
14671489 }
14681490 rsa = (READER_STATE *) g_malloc(sizeof(READER_STATE) * cReaders, 1);
14701492 for (index = 0; index < cReaders; index++)
14711493 {
14721494 in_uint8a(in_s, rsa[index].reader_name, 100);
1473 LLOGLN(10, ("scard_process_get_status_change: reader_name %s",
1474 rsa[index].reader_name));
1495 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_get_status_change: reader_name %s",
1496 rsa[index].reader_name);
14751497 in_uint32_le(in_s, rsa[index].current_state);
1476 LLOGLN(10, ("scard_process_get_status_change: current_state %d",
1477 rsa[index].current_state));
1498 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_get_status_change: current_state %d",
1499 rsa[index].current_state);
14781500 in_uint32_le(in_s, rsa[index].event_state);
1479 LLOGLN(10, ("scard_process_get_status_change: event_state %d",
1480 rsa[index].event_state));
1501 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_get_status_change: event_state %d",
1502 rsa[index].event_state);
14811503 in_uint32_le(in_s, rsa[index].atr_len);
1482 LLOGLN(10, ("scard_process_get_status_change: atr_len %d",
1483 rsa[index].atr_len));
1504 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_get_status_change: atr_len %d",
1505 rsa[index].atr_len);
14841506 in_uint8a(in_s, rsa[index].atr, 36);
14851507 }
14861508
1487 LLOGLN(10, ("scard_process_get_status_change: hContext 0x%8.8x dwTimeout "
1488 "%d cReaders %d", hContext, dwTimeout, cReaders));
1509 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_get_status_change: hContext 0x%8.8x dwTimeout "
1510 "%d cReaders %d", hContext, dwTimeout, cReaders);
14891511
14901512 user_data = (void *) (tintptr) (uds_client->uds_client_id);
14911513 lcontext = get_pcsc_context_by_app_context(uds_client, hContext);
14921514 if (lcontext == 0)
14931515 {
1494 LLOGLN(0, ("scard_process_get_status_change: "
1495 "get_pcsc_context_by_app_context failed"));
1516 LOG(LOG_LEVEL_ERROR, "scard_process_get_status_change: "
1517 "get_pcsc_context_by_app_context failed");
14961518 g_free(rsa);
14971519 return 1;
14981520 }
15221544 struct pcsc_uds_client *uds_client;
15231545 struct trans *con;
15241546
1525 LLOGLN(10, ("scard_function_get_status_change_return:"));
1526 LLOGLN(10, (" status 0x%8.8x", status));
1547 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_get_status_change_return:");
1548 LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status);
15271549 uds_client_id = (int) (tintptr) user_data;
15281550 uds_client = (struct pcsc_uds_client *)
15291551 get_uds_client_by_id(uds_client_id);
15301552 if (uds_client == 0)
15311553 {
1532 LLOGLN(0, ("scard_function_get_status_change_return: "
1533 "get_uds_client_by_id failed"));
1554 LOG(LOG_LEVEL_ERROR, "scard_function_get_status_change_return: "
1555 "get_uds_client_by_id failed to find uds_client_id %d",
1556 uds_client_id);
15341557 return 1;
15351558 }
15361559 con = uds_client->con;
15461569 {
15471570 in_uint8s(in_s, 28);
15481571 in_uint32_le(in_s, cReaders);
1549 LLOGLN(10, (" cReaders %d", cReaders));
1572 LOG_DEVEL(LOG_LEVEL_DEBUG, " cReaders %d", cReaders);
15501573 out_uint32_le(out_s, cReaders);
15511574 if (cReaders > 0)
15521575 {
15831606 void *user_data;
15841607 struct pcsc_context *lcontext;
15851608
1586 LLOGLN(10, ("scard_process_cancel:"));
1609 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_cancel:");
15871610 uds_client = (struct pcsc_uds_client *) (con->callback_data);
15881611 in_uint32_le(in_s, hContext);
1589 LLOGLN(10, ("scard_process_cancel: hContext 0x%8.8x", hContext));
1612 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_cancel: hContext 0x%8.8x", hContext);
15901613 user_data = (void *) (tintptr) (uds_client->uds_client_id);
15911614 lcontext = get_pcsc_context_by_app_context(uds_client, hContext);
15921615 if (lcontext == 0)
15931616 {
1594 LLOGLN(0, ("scard_process_cancel: "
1595 "get_pcsc_context_by_app_context failed"));
1617 LOG(LOG_LEVEL_ERROR, "scard_process_cancel: "
1618 "get_pcsc_context_by_app_context failed");
15961619 return 1;
15971620 }
15981621 scard_send_cancel(user_data, lcontext->context, lcontext->context_bytes);
16121635 struct pcsc_uds_client *uds_client;
16131636 struct trans *con;
16141637
1615 LLOGLN(10, ("scard_function_cancel_return:"));
1616 LLOGLN(10, (" status 0x%8.8x", status));
1638 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_function_cancel_return:");
1639 LOG_DEVEL(LOG_LEVEL_DEBUG, " status 0x%8.8x", status);
16171640 uds_client_id = (int) (tintptr) user_data;
16181641 uds_client = (struct pcsc_uds_client *)
16191642 get_uds_client_by_id(uds_client_id);
16201643 if (uds_client == 0)
16211644 {
1622 LLOGLN(0, ("scard_function_cancel_return: "
1623 "get_uds_client_by_id failed"));
1645 LOG(LOG_LEVEL_ERROR, "scard_function_cancel_return: "
1646 "get_uds_client_by_id failed to find uds_client_id %d",
1647 uds_client_id);
16241648 return 1;
16251649 }
16261650 con = uds_client->con;
16481672 /*****************************************************************************/
16491673 /* returns error */
16501674 int scard_function_reconnect_return(void *user_data,
1651 struct stream *in_s,
1652 int len, int status)
1675 struct stream *in_s,
1676 int len, int status)
16531677 {
16541678 return 0;
16551679 }
16611685 {
16621686 int rv;
16631687
1664 LLOGLN(10, ("scard_process_msg: command 0x%4.4x", command));
1688 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_process_msg: command 0x%4.4x", command);
16651689 rv = 0;
16661690 switch (command)
16671691 {
16681692 case 0x01: /* SCARD_ESTABLISH_CONTEXT */
1669 LLOGLN(10, ("scard_process_msg: SCARD_ESTABLISH_CONTEXT"));
1693 LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_ESTABLISH_CONTEXT");
16701694 rv = scard_process_establish_context(con, in_s);
16711695 break;
16721696 case 0x02: /* SCARD_RELEASE_CONTEXT */
1673 LLOGLN(10, ("scard_process_msg: SCARD_RELEASE_CONTEXT"));
1697 LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_RELEASE_CONTEXT");
16741698 rv = scard_process_release_context(con, in_s);
16751699 break;
16761700
16771701 case 0x03: /* SCARD_LIST_READERS */
1678 LLOGLN(10, ("scard_process_msg: SCARD_LIST_READERS"));
1702 LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_LIST_READERS");
16791703 rv = scard_process_list_readers(con, in_s);
16801704 break;
16811705
16821706 case 0x04: /* SCARD_CONNECT */
1683 LLOGLN(10, ("scard_process_msg: SCARD_CONNECT"));
1707 LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_CONNECT");
16841708 rv = scard_process_connect(con, in_s);
16851709 break;
16861710
16871711 case 0x05: /* SCARD_RECONNECT */
1688 LLOGLN(0, ("scard_process_msg: SCARD_RECONNECT"));
1712 LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_RECONNECT");
16891713 break;
16901714
16911715 case 0x06: /* SCARD_DISCONNECT */
1692 LLOGLN(10, ("scard_process_msg: SCARD_DISCONNECT"));
1716 LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_DISCONNECT");
16931717 rv = scard_process_disconnect(con, in_s);
16941718 break;
16951719
16961720 case 0x07: /* SCARD_BEGIN_TRANSACTION */
1697 LLOGLN(10, ("scard_process_msg: SCARD_BEGIN_TRANSACTION"));
1721 LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_BEGIN_TRANSACTION");
16981722 rv = scard_process_begin_transaction(con, in_s);
16991723 break;
17001724
17011725 case 0x08: /* SCARD_END_TRANSACTION */
1702 LLOGLN(10, ("scard_process_msg: SCARD_END_TRANSACTION"));
1726 LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_END_TRANSACTION");
17031727 rv = scard_process_end_transaction(con, in_s);
17041728 break;
17051729
17061730 case 0x09: /* SCARD_TRANSMIT */
1707 LLOGLN(10, ("scard_process_msg: SCARD_TRANSMIT"));
1731 LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_TRANSMIT");
17081732 rv = scard_process_transmit(con, in_s);
17091733 break;
17101734
17111735 case 0x0A: /* SCARD_CONTROL */
1712 LLOGLN(10, ("scard_process_msg: SCARD_CONTROL"));
1736 LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_CONTROL");
17131737 rv = scard_process_control(con, in_s);
17141738 break;
17151739
17161740 case 0x0B: /* SCARD_STATUS */
1717 LLOGLN(10, ("scard_process_msg: SCARD_STATUS"));
1741 LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_STATUS");
17181742 rv = scard_process_status(con, in_s);
17191743 break;
17201744
17211745 case 0x0C: /* SCARD_GET_STATUS_CHANGE */
1722 LLOGLN(10, ("scard_process_msg: SCARD_GET_STATUS_CHANGE"));
1746 LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_GET_STATUS_CHANGE");
17231747 rv = scard_process_get_status_change(con, in_s);
17241748 break;
17251749
17261750 case 0x0D: /* SCARD_CANCEL */
1727 LLOGLN(10, ("scard_process_msg: SCARD_CANCEL"));
1751 LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_CANCEL");
17281752 rv = scard_process_cancel(con, in_s);
17291753 break;
17301754
17311755 case 0x0E: /* SCARD_CANCEL_TRANSACTION */
1732 LLOGLN(0, ("scard_process_msg: SCARD_CANCEL_TRANSACTION"));
1756 LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_CANCEL_TRANSACTION");
17331757 break;
17341758
17351759 case 0x0F: /* SCARD_GET_ATTRIB */
1736 LLOGLN(0, ("scard_process_msg: SCARD_GET_ATTRIB"));
1760 LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_GET_ATTRIB");
17371761 break;
17381762
17391763 case 0x10: /* SCARD_SET_ATTRIB */
1740 LLOGLN(0, ("scard_process_msg: SCARD_SET_ATTRIB"));
1764 LOG_DEVEL(LOG_LEVEL_INFO, "scard_process_msg: SCARD_SET_ATTRIB");
17411765 break;
17421766
17431767 default:
1744 LLOGLN(0, ("scard_process_msg: unknown mtype 0x%4.4x", command));
1768 LOG_DEVEL(LOG_LEVEL_WARNING, "scard_process_msg: unknown mtype 0x%4.4x", command);
17451769 rv = 1;
17461770 break;
17471771 }
17581782 int command;
17591783 int error;
17601784
1761 LLOGLN(10, ("my_pcsc_trans_data_in:"));
1785 LOG_DEVEL(LOG_LEVEL_DEBUG, "my_pcsc_trans_data_in:");
17621786 if (trans == 0)
17631787 {
17641788 return 0;
17661790 s = trans_get_in_s(trans);
17671791 in_uint32_le(s, size);
17681792 in_uint32_le(s, command);
1769 LLOGLN(10, ("my_pcsc_trans_data_in: size %d command %d", size, command));
1793 LOG_DEVEL(LOG_LEVEL_DEBUG, "my_pcsc_trans_data_in: size %d command %d", size, command);
17701794 error = trans_force_read(trans, size);
17711795 if (error == 0)
17721796 {
17821806 {
17831807 struct pcsc_uds_client *uds_client;
17841808
1785 LLOGLN(10, ("my_pcsc_trans_conn_in:"));
1809 LOG_DEVEL(LOG_LEVEL_DEBUG, "my_pcsc_trans_conn_in:");
17861810
17871811 if (trans == 0)
17881812 {
18241848 int disp;
18251849 int error;
18261850
1827 LLOGLN(0, ("scard_pcsc_init:"));
1851 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_pcsc_init:");
18281852 if (g_lis == 0)
18291853 {
18301854 g_lis = trans_create(2, 8192, 8192);
18361860 {
18371861 if (!g_remove_dir(g_pcsclite_ipc_dir))
18381862 {
1839 LLOGLN(0, ("scard_pcsc_init: g_remove_dir failed"));
1863 LOG_DEVEL(LOG_LEVEL_WARNING, "scard_pcsc_init: g_remove_dir failed");
18401864 }
18411865 }
18421866 if (!g_directory_exist(g_pcsclite_ipc_dir))
18451869 {
18461870 if (!g_directory_exist(g_pcsclite_ipc_dir))
18471871 {
1848 LLOGLN(0, ("scard_pcsc_init: g_create_dir failed"));
1872 LOG_DEVEL(LOG_LEVEL_WARNING, "scard_pcsc_init: g_create_dir failed");
18491873 }
18501874 }
18511875 }
18551879 error = trans_listen(g_lis, g_pcsclite_ipc_file);
18561880 if (error != 0)
18571881 {
1858 LLOGLN(0, ("scard_pcsc_init: trans_listen failed for port %s",
1859 g_pcsclite_ipc_file));
1882 LOG(LOG_LEVEL_ERROR, "scard_pcsc_init: trans_listen failed for port %s",
1883 g_pcsclite_ipc_file);
18601884 return 1;
18611885 }
18621886 }
18671891 int
18681892 scard_pcsc_deinit(void)
18691893 {
1870 LLOGLN(0, ("scard_pcsc_deinit:"));
1894 LOG_DEVEL(LOG_LEVEL_DEBUG, "scard_pcsc_deinit:");
18711895
18721896 if (g_lis != 0)
18731897 {
18801904 g_file_delete(g_pcsclite_ipc_file);
18811905 if (!g_remove_dir(g_pcsclite_ipc_dir))
18821906 {
1883 LLOGLN(0, ("scard_pcsc_deinit: g_remove_dir failed"));
1907 LOG_DEVEL(LOG_LEVEL_WARNING, "scard_pcsc_deinit: g_remove_dir failed");
18841908 }
18851909 g_pcsclite_ipc_dir[0] = 0;
18861910 }
2222 #include <stdio.h>
2323 #include <sys/types.h>
2424 #include <sys/socket.h>
25 #include <sys/errno.h>
25 #include <errno.h>
2626 #include <signal.h>
2727 #include <sys/un.h>
2828
4242
4343 #define AACENCODER_LIB_VER_GTEQ(vl0, vl1, vl2) \
4444 (defined(AACENCODER_LIB_VL0) && \
45 ((AACENCODER_LIB_VL0 > vl0) || \
46 (AACENCODER_LIB_VL0 == vl0 && AACENCODER_LIB_VL1 >= vl1) || \
47 (AACENCODER_LIB_VL0 == vl0 && AACENCODER_LIB_VL1 == vl1 && AACENCODER_LIB_VL2 > vl2)))
45 ((AACENCODER_LIB_VL0 > vl0) || \
46 (AACENCODER_LIB_VL0 == vl0 && AACENCODER_LIB_VL1 >= vl1) || \
47 (AACENCODER_LIB_VL0 == vl0 && AACENCODER_LIB_VL1 == vl1 && AACENCODER_LIB_VL2 > vl2)))
4848 #endif
4949
5050 #if defined(XRDP_OPUS)
248248 /* microphone related */
249249 static int sound_send_server_input_formats(void);
250250 static int sound_process_input_format(int aindex, int wFormatTag,
251 int nChannels, int nSamplesPerSec,
252 int nAvgBytesPerSec, int nBlockAlign,
253 int wBitsPerSample, int cbSize, char *data);
251 int nChannels, int nSamplesPerSec,
252 int nAvgBytesPerSec, int nBlockAlign,
253 int wBitsPerSample, int cbSize, char *data);
254254 static int sound_process_input_formats(struct stream *s, int size);
255255 static int sound_input_start_recording(void);
256256 static int sound_input_stop_recording(void);
271271
272272 num_formats = sizeof(g_wave_outp_formats) /
273273 sizeof(g_wave_outp_formats[0]) - 1;
274 LOG(10, ("sound_send_server_output_formats: num_formats %d", num_formats));
274 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_send_server_output_formats: num_formats %d", num_formats);
275275
276276 make_stream(s);
277277 init_stream(s, 8182);
368368 int nBlockAlign, int wBitsPerSample,
369369 int cbSize, char *data)
370370 {
371 LOG(1, ("sound_process_output_format:"));
372 LOG(1, (" wFormatTag %d", wFormatTag));
373 LOG(1, (" nChannels %d", nChannels));
374 LOG(1, (" nSamplesPerSec %d", nSamplesPerSec));
375 LOG(1, (" nAvgBytesPerSec %d", nAvgBytesPerSec));
376 LOG(1, (" nBlockAlign %d", nBlockAlign));
377 LOG(1, (" wBitsPerSample %d", wBitsPerSample));
378 LOG(1, (" cbSize %d", cbSize));
379
380 g_hexdump(data, cbSize);
371 LOG_DEVEL(LOG_LEVEL_INFO, "sound_process_output_format:");
372 LOG_DEVEL(LOG_LEVEL_INFO, " wFormatTag %d", wFormatTag);
373 LOG_DEVEL(LOG_LEVEL_INFO, " nChannels %d", nChannels);
374 LOG_DEVEL(LOG_LEVEL_INFO, " nSamplesPerSec %d", nSamplesPerSec);
375 LOG_DEVEL(LOG_LEVEL_INFO, " nAvgBytesPerSec %d", nAvgBytesPerSec);
376 LOG_DEVEL(LOG_LEVEL_INFO, " nBlockAlign %d", nBlockAlign);
377 LOG_DEVEL(LOG_LEVEL_INFO, " wBitsPerSample %d", wBitsPerSample);
378 LOG_DEVEL(LOG_LEVEL_INFO, " cbSize %d", cbSize);
379
380 LOG_DEVEL_HEXDUMP(LOG_LEVEL_TRACE, "", data, cbSize);
381381
382382 /* select CD quality audio */
383383 if (wFormatTag == g_pcm_44100.wFormatTag &&
384 nChannels == g_pcm_44100.nChannels &&
385 nSamplesPerSec == g_pcm_44100.nSamplesPerSec &&
386 nAvgBytesPerSec == g_pcm_44100.nAvgBytesPerSec &&
387 nBlockAlign == g_pcm_44100.nBlockAlign &&
388 wBitsPerSample == g_pcm_44100.wBitsPerSample)
384 nChannels == g_pcm_44100.nChannels &&
385 nSamplesPerSec == g_pcm_44100.nSamplesPerSec &&
386 nAvgBytesPerSec == g_pcm_44100.nAvgBytesPerSec &&
387 nBlockAlign == g_pcm_44100.nBlockAlign &&
388 wBitsPerSample == g_pcm_44100.wBitsPerSample)
389389 {
390390 g_current_client_format_index = aindex;
391391 g_current_server_format_index = 0;
394394 for (lindex = 0; lindex < NUM_BUILT_IN; lindex++)
395395 {
396396 if (wFormatTag == g_wave_formats[lindex]->wFormatTag &&
397 nChannels == g_wave_formats[lindex]->nChannels &&
398 nSamplesPerSec == g_wave_formats[lindex]->nSamplesPerSec &&
399 nAvgBytesPerSec == g_wave_formats[lindex]->nAvgBytesPerSec &&
400 nBlockAlign == g_wave_formats[lindex]->nBlockAlign &&
401 wBitsPerSample == g_wave_formats[lindex]->wBitsPerSample)
397 nChannels == g_wave_formats[lindex]->nChannels &&
398 nSamplesPerSec == g_wave_formats[lindex]->nSamplesPerSec &&
399 nAvgBytesPerSec == g_wave_formats[lindex]->nAvgBytesPerSec &&
400 nBlockAlign == g_wave_formats[lindex]->nBlockAlign &&
401 wBitsPerSample == g_wave_formats[lindex]->wBitsPerSample)
402402 {
403403 g_current_client_format_index = aindex;
404404 g_current_server_format_index = lindex;
406406 }
407407 #endif
408408
409 switch(wFormatTag)
409 switch (wFormatTag)
410410 {
411411 case WAVE_FORMAT_AAC:
412 LOG(0, ("wFormatTag, fdk aac"));
412 LOG_DEVEL(LOG_LEVEL_INFO, "wFormatTag, fdk aac");
413413 g_client_does_fdk_aac = 1;
414414 g_client_fdk_aac_index = aindex;
415415 break;
416416 case WAVE_FORMAT_MPEGLAYER3:
417 LOG(0, ("wFormatTag, mp3"));
417 LOG_DEVEL(LOG_LEVEL_INFO, "wFormatTag, mp3");
418418 g_client_does_mp3lame = 1;
419419 g_client_mp3lame_index = aindex;
420420 break;
421421 case WAVE_FORMAT_OPUS:
422 LOG(0, ("wFormatTag, opus"));
422 LOG_DEVEL(LOG_LEVEL_INFO, "wFormatTag, opus");
423423 g_client_does_opus = 1;
424424 g_client_opus_index = aindex;
425425 break;
450450 char *data;
451451
452452 if (size < 16)
453 {
453454 return 1;
455 }
454456
455457 in_uint8s(s, 14);
456458 in_uint16_le(s, num_formats);
519521 if (g_fdk_aac_encoder == 0)
520522 {
521523 /* init fdk aac encoder */
522 LOG(0, ("sound_wave_compress_fdk_aac: using fdk aac"));
524 LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac: using fdk aac");
523525
524526 error = aacEncOpen(&g_fdk_aac_encoder, 0, 2);
525527 if (error != AACENC_OK)
526528 {
527 LOG(0, ("sound_wave_compress_fdk_aac: aacEncOpen() failed"));
529 LOG_DEVEL(LOG_LEVEL_ERROR, "sound_wave_compress_fdk_aac: aacEncOpen() failed");
528530 return rv;
529531 }
530532
532534 error = aacEncoder_SetParam(g_fdk_aac_encoder, AACENC_AOT, aot);
533535 if (error != AACENC_OK)
534536 {
535 LOG(0, ("sound_wave_compress_fdk_aac: aacEncoder_SetParam() "
536 "AACENC_AOT failed"));
537 LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac: aacEncoder_SetParam() "
538 "AACENC_AOT failed");
537539 }
538540
539541 sample_rate = g_fdk_aac_44100.nSamplesPerSec;
541543 sample_rate);
542544 if (error != AACENC_OK)
543545 {
544 LOG(0, ("sound_wave_compress_fdk_aac: aacEncoder_SetParam() "
545 "AACENC_SAMPLERATE failed"));
546 LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac: aacEncoder_SetParam() "
547 "AACENC_SAMPLERATE failed");
546548 }
547549
548550 mode = MODE_2;
550552 AACENC_CHANNELMODE, mode);
551553 if (error != AACENC_OK)
552554 {
553 LOG(0, ("sound_wave_compress_fdk_aac: aacEncoder_SetParam() "
554 "AACENC_CHANNELMODE failed"));
555 LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac: aacEncoder_SetParam() "
556 "AACENC_CHANNELMODE failed");
555557 }
556558
557559 channel_order = 1; /* WAVE file format channel ordering */
559561 channel_order);
560562 if (error != AACENC_OK)
561563 {
562 LOG(0, ("sound_wave_compress_fdk_aac: aacEncoder_SetParam() "
563 "AACENC_CHANNELORDER failed"));
564 LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac: aacEncoder_SetParam() "
565 "AACENC_CHANNELORDER failed");
564566 }
565567
566568 /* bytes rate to bit rate */
569571 bitrate);
570572 if (error != AACENC_OK)
571573 {
572 LOG(0, ("sound_wave_compress_fdk_aac: aacEncoder_SetParam() "
573 "AACENC_BITRATE failed"));
574 LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac: aacEncoder_SetParam() "
575 "AACENC_BITRATE failed");
574576 }
575577
576578 error = aacEncoder_SetParam(g_fdk_aac_encoder, AACENC_TRANSMUX, 0);
577579 if (error != AACENC_OK)
578580 {
579 LOG(0, ("sound_wave_compress_fdk_aac: aacEncoder_SetParam() "
580 "AACENC_TRANSMUX failed"));
581 LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac: aacEncoder_SetParam() "
582 "AACENC_TRANSMUX failed");
581583 }
582584
583585 afterburner = 1;
585587 afterburner);
586588 if (error != AACENC_OK)
587589 {
588 LOG(0, ("sound_wave_compress_fdk_aac: aacEncoder_SetParam() "
589 "AACENC_AFTERBURNER failed"));
590 LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac: aacEncoder_SetParam() "
591 "AACENC_AFTERBURNER failed");
590592 }
591593
592594 error = aacEncEncode(g_fdk_aac_encoder, NULL, NULL, NULL, NULL);
593595 if (error != AACENC_OK)
594596 {
595 LOG(0, ("sound_wave_compress_fdk_aac: Unable to initialize "
596 "the encoder"));
597 LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac: Unable to initialize "
598 "the encoder");
597599 }
598600
599601 g_memset(&info, 0, sizeof(info));
600602 error = aacEncInfo(g_fdk_aac_encoder, &info);
601603 if (error != AACENC_OK)
602604 {
603 LOG(0, ("sound_wave_compress_fdk_aac: aacEncInfo failed"));
604 }
605
606 LOG(0, ("sound_wave_compress_fdk_aac:"));
607 LOG(0, (" AACENC_InfoStruct"));
608 LOG(0, (" maxOutBufBytes %d", info.maxOutBufBytes));
609 LOG(0, (" maxAncBytes %d", info.maxAncBytes));
610 LOG(0, (" inBufFillLevel %d", info.inBufFillLevel));
611 LOG(0, (" inputChannels %d", info.inputChannels));
612 LOG(0, (" frameLength %d", info.frameLength));
605 LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac: aacEncInfo failed");
606 }
607
608 LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_fdk_aac:");
609 LOG_DEVEL(LOG_LEVEL_INFO, " AACENC_InfoStruct");
610 LOG_DEVEL(LOG_LEVEL_INFO, " maxOutBufBytes %d", info.maxOutBufBytes);
611 LOG_DEVEL(LOG_LEVEL_INFO, " maxAncBytes %d", info.maxAncBytes);
612 LOG_DEVEL(LOG_LEVEL_INFO, " inBufFillLevel %d", info.inBufFillLevel);
613 LOG_DEVEL(LOG_LEVEL_INFO, " inputChannels %d", info.inputChannels);
614 LOG_DEVEL(LOG_LEVEL_INFO, " frameLength %d", info.frameLength);
613615 #if AACENCODER_LIB_VER_GTEQ(4, 0, 0)
614 LOG(0, (" nDelay %d", info.nDelay));
615 LOG(0, (" nDelayCore %d", info.nDelayCore));
616 LOG_DEVEL(LOG_LEVEL_INFO, " nDelay %d", info.nDelay);
617 LOG_DEVEL(LOG_LEVEL_INFO, " nDelayCore %d", info.nDelayCore);
616618 #else
617 LOG(0, (" encoderDelay %d", info.encoderDelay));
619 LOG_DEVEL(LOG_LEVEL_INFO, " encoderDelay %d", info.encoderDelay);
618620 #endif
619 LOG(0, (" confBuf"));
620 LOG(0, (" confSize %d", info.confSize));
621 LOG_DEVEL(LOG_LEVEL_INFO, " confBuf");
622 LOG_DEVEL(LOG_LEVEL_INFO, " confSize %d", info.confSize);
621623 }
622624
623625 rv = data_bytes;
661663 if (error == AACENC_OK)
662664 {
663665 cdata_bytes = out_args.numOutBytes;
664 LOG(10, ("sound_wave_compress_fdk_aac: aacEncEncode ok "
665 "cdata_bytes %d", cdata_bytes));
666 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_wave_compress_fdk_aac: aacEncEncode ok "
667 "cdata_bytes %d", cdata_bytes);
666668 *format_index = g_client_fdk_aac_index;
667669 g_memcpy(data, cdata, cdata_bytes);
668670 rv = cdata_bytes;
669671 }
670672 else
671673 {
672 LOG(0, ("sound_wave_compress_fdk_aac: aacEncEncode failed"));
674 LOG_DEVEL(LOG_LEVEL_ERROR, "sound_wave_compress_fdk_aac: aacEncEncode failed");
673675 }
674676 g_free(cdata);
675677
716718 &error);
717719 if (g_opus_encoder == 0)
718720 {
719 LOG(0, ("sound_wave_compress_opus: opus_encoder_create failed"));
721 LOG_DEVEL(LOG_LEVEL_ERROR, "sound_wave_compress_opus: opus_encoder_create failed");
720722 return data_bytes;
721723 }
722724 }
782784 if (g_lame_encoder == 0)
783785 {
784786 /* init mp3 lame encoder */
785 LOG(0, ("sound_wave_compress_mp3lame: using mp3lame"));
787 LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_mp3lame: using mp3lame");
786788
787789 g_lame_encoder = lame_init();
788790 if (g_lame_encoder == 0)
789791 {
790 LOG(0, ("sound_wave_compress_mp3lame: lame_init() failed"));
792 LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_mp3lame: lame_init() failed");
791793 return rv;
792794 }
793795 lame_set_num_channels(g_lame_encoder, g_mp3lame_44100.nChannels);
794796 lame_set_in_samplerate(g_lame_encoder, g_mp3lame_44100.nSamplesPerSec);
797 //lame_set_brate(g_lame_encoder, 64);
798 lame_set_quality(g_lame_encoder, 7);
795799 if (lame_init_params(g_lame_encoder) == -1)
796800 {
797 LOG(0, ("sound_wave_compress_mp3lame: lame_init_params() failed"));
801 LOG_DEVEL(LOG_LEVEL_ERROR, "sound_wave_compress_mp3lame: lame_init_params() failed");
798802 return rv;
799803 }
800804
801 LOG(0, ("sound_wave_compress_mp3lame: lame config:"));
802 LOG(0, (" brate : %d", lame_get_brate(g_lame_encoder)));
803 LOG(0, (" compression ratio: %f", lame_get_compression_ratio(g_lame_encoder)));
804 LOG(0, (" encoder delay : %d", lame_get_encoder_delay(g_lame_encoder)));
805 LOG(0, (" frame size : %d", lame_get_framesize(g_lame_encoder)));
806 LOG(0, (" encoder padding : %d", lame_get_encoder_padding(g_lame_encoder)));
807 LOG(0, (" mode : %d", lame_get_mode(g_lame_encoder)));
805 LOG_DEVEL(LOG_LEVEL_INFO, "sound_wave_compress_mp3lame: lame config:");
806 LOG_DEVEL(LOG_LEVEL_INFO, " brate : %d", lame_get_brate(g_lame_encoder));
807 LOG_DEVEL(LOG_LEVEL_INFO, " compression ratio: %f", lame_get_compression_ratio(g_lame_encoder));
808 LOG_DEVEL(LOG_LEVEL_INFO, " encoder delay : %d", lame_get_encoder_delay(g_lame_encoder));
809 LOG_DEVEL(LOG_LEVEL_INFO, " frame size : %d", lame_get_framesize(g_lame_encoder));
810 LOG_DEVEL(LOG_LEVEL_INFO, " encoder padding : %d", lame_get_encoder_padding(g_lame_encoder));
811 LOG_DEVEL(LOG_LEVEL_INFO, " mode : %d", lame_get_mode(g_lame_encoder));
808812 }
809813
810814 odata_bytes = data_bytes;
816820 data_bytes = g_bbuf_size;
817821 }
818822 cdata_bytes = lame_encode_buffer_interleaved(g_lame_encoder,
819 (short int *) data,
820 data_bytes / 4,
821 cdata,
822 cdata_bytes);
823 (short int *) data,
824 data_bytes / 4,
825 cdata,
826 cdata_bytes);
823827 if (cdata_bytes < 0)
824828 {
825 LOG(0, ("sound_wave_compress: lame_encode_buffer_interleaved() "
826 "failed, error %d", cdata_bytes));
829 LOG_DEVEL(LOG_LEVEL_ERROR, "sound_wave_compress: lame_encode_buffer_interleaved() "
830 "failed, error %d", cdata_bytes);
827831 return rv;
828832 }
829833 if ((cdata_bytes > 0) && (cdata_bytes < odata_bytes))
881885 int format_index;
882886 char *size_ptr;
883887
884 LOG(10, ("sound_send_wave_data_chunk: data_bytes %d", data_bytes));
888 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_send_wave_data_chunk: data_bytes %d", data_bytes);
885889
886890 if ((data_bytes < 4) || (data_bytes > 128 * 1024))
887891 {
888 LOG(0, ("sound_send_wave_data_chunk: bad data_bytes %d", data_bytes));
892 LOG_DEVEL(LOG_LEVEL_ERROR, "sound_send_wave_data_chunk: bad data_bytes %d", data_bytes);
889893 return 1;
890894 }
891895
895899
896900 /* part one of 2 PDU wave info */
897901
898 LOG(10, ("sound_send_wave_data_chunk: sending %d bytes", data_bytes));
902 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_send_wave_data_chunk: sending %d bytes", data_bytes);
899903
900904 make_stream(s);
901905 init_stream(s, 16 + data_bytes); /* some extra space */
909913 out_uint8(s, g_cBlockNo);
910914 g_sent_time[g_cBlockNo & 0xff] = time;
911915
912 LOG(10, ("sound_send_wave_data_chunk: sending time %d, g_cBlockNo %d",
913 time & 0xffff, g_cBlockNo & 0xff));
916 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_send_wave_data_chunk: sending time %d, g_cBlockNo %d",
917 time & 0xffff, g_cBlockNo & 0xff);
914918
915919 out_uint8s(s, 3);
916920 out_uint8a(s, data, 4);
947951 int error;
948952 int res;
949953
950 LOG(10, ("sound_send_wave_data: sending %d bytes", data_bytes));
954 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_send_wave_data: sending %d bytes", data_bytes);
951955 if (g_time_diff > g_best_time_diff + 250)
952956 {
953957 data_bytes = data_bytes / 4;
963967 chunk_bytes = MIN(space_left, data_bytes);
964968 if (chunk_bytes < 1)
965969 {
966 LOG(10, ("sound_send_wave_data: error"));
970 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_send_wave_data: error");
967971 error = 1;
968972 break;
969973 }
976980 if (res == 2)
977981 {
978982 /* don't need to error on this */
979 LOG(0, ("sound_send_wave_data: dropped, no room"));
983 LOG_DEVEL(LOG_LEVEL_ERROR, "sound_send_wave_data: dropped, no room");
980984 break;
981985 }
982986 else if (res != 0)
983987 {
984 LOG(10, ("sound_send_wave_data: error"));
988 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_send_wave_data: error");
985989 error = 1;
986990 break;
987991 }
10021006 int bytes;
10031007 char *size_ptr;
10041008
1005 LOG(10, ("sound_send_close:"));
1009 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_send_close:");
10061010
10071011 g_best_time_diff = 0;
10081012 g_buf_index = 0;
10311035 int time_diff;
10321036
10331037 time_diff = g_time3() - g_training_sent_time;
1034 LOG(0, ("sound_process_training: round trip time %u", time_diff));
1038 LOG(LOG_LEVEL_INFO, "sound_process_training: round trip time %u", time_diff);
10351039 return 0;
10361040 }
10371041
10521056 in_uint8(s, cConfirmedBlockNo);
10531057 time_diff = time - g_sent_time[cConfirmedBlockNo & 0xff];
10541058
1055 LOG(10, ("sound_process_wave_confirm: wTimeStamp %d, "
1059 LOG(LOG_LEVEL_DEBUG, "sound_process_wave_confirm: wTimeStamp %d, "
10561060 "cConfirmedBlockNo %d time diff %d",
1057 wTimeStamp, cConfirmedBlockNo, time_diff));
1061 wTimeStamp, cConfirmedBlockNo, time_diff);
10581062
10591063 acc = 0;
10601064 list_add_item(g_ack_time_diff, time_diff);
10931097 return sound_send_close();
10941098 break;
10951099 default:
1096 LOG(10, ("process_pcm_message: unknown id %d", id));
1100 LOG_DEVEL(LOG_LEVEL_ERROR, "process_pcm_message: unknown id %d", id);
10971101 break;
10981102 }
10991103 return 1;
11121116 int error;
11131117
11141118 if (trans == 0)
1119 {
11151120 return 0;
1121 }
11161122
11171123 if (trans != g_audio_c_trans_out)
1124 {
11181125 return 1;
1126 }
11191127
11201128 s = trans_get_in_s(trans);
11211129 in_uint32_le(s, id);
11231131
11241132 if ((id & ~3) || (size > 128 * 1024 + 8) || (size < 8))
11251133 {
1126 LOG(0, ("sound_sndsrvr_sink_data_in: bad message id %d size %d", id, size));
1134 LOG_DEVEL(LOG_LEVEL_ERROR, "sound_sndsrvr_sink_data_in: bad message id %d size %d", id, size);
11271135 return 1;
11281136 }
11291137
1130 LOG(10, ("sound_sndsrvr_sink_data_in: good message id %d size %d", id, size));
1138 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_sndsrvr_sink_data_in: good message id %d size %d", id, size);
11311139
11321140 error = trans_force_read(trans, size - 8);
11331141
11471155 static int
11481156 sound_sndsrvr_sink_conn_in(struct trans *trans, struct trans *new_trans)
11491157 {
1150 LOG(0, ("sound_sndsrvr_sink_conn_in:"));
1158 LOG_DEVEL(LOG_LEVEL_INFO, "sound_sndsrvr_sink_conn_in:");
11511159
11521160 if (trans == 0)
1161 {
11531162 return 1;
1163 }
11541164
11551165 if (trans != g_audio_l_trans_out)
1166 {
11561167 return 1;
1168 }
11571169
11581170 if (g_audio_c_trans_out != 0) /* if already set, error */
1171 {
11591172 return 1;
1173 }
11601174
11611175 if (new_trans == 0)
1176 {
11621177 return 1;
1178 }
11631179
11641180 g_audio_c_trans_out = new_trans;
11651181 g_audio_c_trans_out->trans_data_in = sound_sndsrvr_sink_data_in;
11771193 static int
11781194 sound_sndsrvr_source_conn_in(struct trans *trans, struct trans *new_trans)
11791195 {
1180 LOG(0, ("sound_sndsrvr_source_conn_in: client connected"));
1196 LOG_DEVEL(LOG_LEVEL_INFO, "sound_sndsrvr_source_conn_in: client connected");
11811197
11821198 if (trans == 0)
1199 {
11831200 return 1;
1201 }
11841202
11851203 if (trans != g_audio_l_trans_in)
1204 {
11861205 return 1;
1206 }
11871207
11881208 if (g_audio_c_trans_in != 0) /* if already set, error */
1209 {
11891210 return 1;
1211 }
11901212
11911213 if (new_trans == 0)
1214 {
11921215 return 1;
1216 }
11931217
11941218 g_audio_c_trans_in = new_trans;
11951219 g_audio_c_trans_in->trans_data_in = sound_sndsrvr_source_data_in;
12041228 int
12051229 sound_init(void)
12061230 {
1207 LOG(0, ("sound_init:"));
1231 LOG_DEVEL(LOG_LEVEL_INFO, "sound_init:");
12081232
12091233 g_stream_incoming_packet = NULL;
12101234
12411265 int
12421266 sound_deinit(void)
12431267 {
1244 LOG(10, ("sound_deinit:"));
1268 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_deinit:");
12451269 if (g_audio_l_trans_out != 0)
12461270 {
12471271 trans_delete(g_audio_l_trans_out);
13261350 break;
13271351
13281352 default:
1329 LOG(10, ("sound_data_in: unknown code %d size %d", code, size));
1353 LOG_DEVEL(LOG_LEVEL_ERROR, "sound_data_in: unknown code %d size %d", code, size);
13301354 break;
13311355 }
13321356
13831407 {
13841408 if (trans_check_wait_objs(g_audio_l_trans_out) != 0)
13851409 {
1386 LOG(10, ("sound_check_wait_objs: g_audio_l_trans_out returned non-zero"));
1410 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_check_wait_objs: g_audio_l_trans_out returned non-zero");
13871411 trans_delete(g_audio_l_trans_out);
13881412 g_audio_l_trans_out = 0;
13891413 }
13931417 {
13941418 if (trans_check_wait_objs(g_audio_c_trans_out) != 0)
13951419 {
1396 LOG(10, ("sound_check_wait_objs: g_audio_c_trans_out returned non-zero"));
1420 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_check_wait_objs: g_audio_c_trans_out returned non-zero");
13971421 trans_delete(g_audio_c_trans_out);
13981422 g_audio_c_trans_out = 0;
13991423 sound_start_sink_listener();
14041428 {
14051429 if (trans_check_wait_objs(g_audio_l_trans_in) != 0)
14061430 {
1407 LOG(10, ("sound_check_wait_objs: g_audio_l_trans_in returned non-zero"));
1431 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_check_wait_objs: g_audio_l_trans_in returned non-zero");
14081432 trans_delete(g_audio_l_trans_in);
14091433 g_audio_l_trans_in = 0;
14101434 }
14141438 {
14151439 if (trans_check_wait_objs(g_audio_c_trans_in) != 0)
14161440 {
1417 LOG(10, ("sound_check_wait_objs: g_audio_c_trans_in returned non-zero"));
1441 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_check_wait_objs: g_audio_c_trans_in returned non-zero");
14181442 trans_delete(g_audio_c_trans_in);
14191443 g_audio_c_trans_in = 0;
14201444 sound_start_source_listener();
14461470
14471471 num_formats = sizeof(g_wave_inp_formats) /
14481472 sizeof(g_wave_inp_formats[0]) - 1;
1449 LOG(10, ("sound_send_server_input_formats: num_formats %d", num_formats));
1473 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_send_server_input_formats: num_formats %d", num_formats);
14501474
14511475 make_stream(s);
14521476 init_stream(s, 8182);
15091533 int nBlockAlign, int wBitsPerSample,
15101534 int cbSize, char *data)
15111535 {
1512 LOG(10, ("sound_process_input_format:"));
1513 LOG(10, (" wFormatTag %d", wFormatTag));
1514 LOG(10, (" nChannels %d", nChannels));
1515 LOG(10, (" nSamplesPerSec %d", nSamplesPerSec));
1516 LOG(10, (" nAvgBytesPerSec %d", nAvgBytesPerSec));
1517 LOG(10, (" nBlockAlign %d", nBlockAlign));
1518 LOG(10, (" wBitsPerSample %d", wBitsPerSample));
1519 LOG(10, (" cbSize %d", cbSize));
1536 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_process_input_format:");
1537 LOG_DEVEL(LOG_LEVEL_DEBUG, " wFormatTag %d", wFormatTag);
1538 LOG_DEVEL(LOG_LEVEL_DEBUG, " nChannels %d", nChannels);
1539 LOG_DEVEL(LOG_LEVEL_DEBUG, " nSamplesPerSec %d", nSamplesPerSec);
1540 LOG_DEVEL(LOG_LEVEL_DEBUG, " nAvgBytesPerSec %d", nAvgBytesPerSec);
1541 LOG_DEVEL(LOG_LEVEL_DEBUG, " nBlockAlign %d", nBlockAlign);
1542 LOG_DEVEL(LOG_LEVEL_DEBUG, " wBitsPerSample %d", wBitsPerSample);
1543 LOG_DEVEL(LOG_LEVEL_DEBUG, " cbSize %d", cbSize);
15201544
15211545 #if 1
15221546 /* select CD quality audio */
15231547 if (wFormatTag == g_pcm_inp_44100.wFormatTag &&
1524 nChannels == g_pcm_inp_44100.nChannels &&
1525 nSamplesPerSec == g_pcm_inp_44100.nSamplesPerSec &&
1526 nAvgBytesPerSec == g_pcm_inp_44100.nAvgBytesPerSec &&
1527 nBlockAlign == g_pcm_inp_44100.nBlockAlign &&
1528 wBitsPerSample == g_pcm_inp_44100.wBitsPerSample)
1548 nChannels == g_pcm_inp_44100.nChannels &&
1549 nSamplesPerSec == g_pcm_inp_44100.nSamplesPerSec &&
1550 nAvgBytesPerSec == g_pcm_inp_44100.nAvgBytesPerSec &&
1551 nBlockAlign == g_pcm_inp_44100.nBlockAlign &&
1552 wBitsPerSample == g_pcm_inp_44100.wBitsPerSample)
15291553 {
15301554 g_client_input_format_index = aindex;
15311555 g_server_input_format_index = 0;
15331557 #else
15341558 /* select half of CD quality audio */
15351559 if (wFormatTag == g_pcm_inp_22050.wFormatTag &&
1536 nChannels == g_pcm_inp_22050.nChannels &&
1537 nSamplesPerSec == g_pcm_inp_22050.nSamplesPerSec &&
1538 nAvgBytesPerSec == g_pcm_inp_22050.nAvgBytesPerSec &&
1539 nBlockAlign == g_pcm_inp_22050.nBlockAlign &&
1540 wBitsPerSample == g_pcm_inp_22050.wBitsPerSample)
1560 nChannels == g_pcm_inp_22050.nChannels &&
1561 nSamplesPerSec == g_pcm_inp_22050.nSamplesPerSec &&
1562 nAvgBytesPerSec == g_pcm_inp_22050.nAvgBytesPerSec &&
1563 nBlockAlign == g_pcm_inp_22050.nBlockAlign &&
1564 wBitsPerSample == g_pcm_inp_22050.wBitsPerSample)
15411565 {
15421566 g_client_input_format_index = aindex;
15431567 g_server_input_format_index = 0;
15651589 int cbSize;
15661590 char *data;
15671591
1568 LOG(10, ("sound_process_input_formats: size=%d", size));
1592 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_process_input_formats: size=%d", size);
15691593
15701594 if (g_getenv("XRDP_NO_RDPSND_REC") == NULL)
15711595 {
16031627 static int
16041628 sound_input_start_recording(void)
16051629 {
1606 struct stream* s;
1607
1608 LOG(10, ("sound_input_start_recording:"));
1630 struct stream *s;
1631
1632 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_input_start_recording:");
16091633
16101634 /* if there is any data in FIFO, discard it */
16111635 while ((s = (struct stream *) fifo_remove(&g_in_fifo)) != NULL)
16421666 static int
16431667 sound_input_stop_recording(void)
16441668 {
1645 struct stream* s;
1646
1647 LOG(10, ("sound_input_stop_recording:"));
1669 struct stream *s;
1670
1671 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_input_stop_recording:");
16481672
16491673 xstream_new(s, 1024);
16501674
16741698 {
16751699 struct stream *ls;
16761700
1677 LOG(10, ("sound_process_input_data: bytes %d g_bytes_in_fifo %d",
1678 bytes, g_bytes_in_fifo));
1701 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_process_input_data: bytes %d g_bytes_in_fifo %d",
1702 bytes, g_bytes_in_fifo);
16791703 #if 0 /* no need to cap anymore */
16801704 /* cap data in fifo */
16811705 if (g_bytes_in_fifo > 8 * 1024)
17091733 int i;
17101734
17111735 if (trans == 0)
1736 {
17121737 return 0;
1738 }
17131739
17141740 if (trans != g_audio_c_trans_in)
1741 {
17151742 return 1;
1743 }
17161744
17171745 ts = trans_get_in_s(trans);
17181746 if (trans_force_read(trans, 3))
1719 log_message(LOG_LEVEL_ERROR, "sound.c: error reading from transport");
1747 {
1748 LOG(LOG_LEVEL_ERROR, "sound.c: error reading from transport");
1749 }
17201750
17211751 ts->p = ts->data + 8;
17221752 in_uint8(ts, cmd);
17231753 in_uint16_le(ts, bytes_req);
1724 LOG(10, ("sound_sndsrvr_source_data_in: bytes_req %d", bytes_req));
1754 LOG_DEVEL(LOG_LEVEL_DEBUG, "sound_sndsrvr_source_data_in: bytes_req %d", bytes_req);
17251755
17261756 xstream_new(s, bytes_req + 2);
17271757
17381768 if (g_stream_inp != NULL)
17391769 {
17401770 g_bytes_in_fifo -= g_stream_inp->size;
1741 LOG(10, (" g_bytes_in_fifo %d", g_bytes_in_fifo));
1771 LOG_DEVEL(LOG_LEVEL_DEBUG, " g_bytes_in_fifo %d", g_bytes_in_fifo);
17421772 }
17431773 }
17441774
17501780 else
17511781 {
17521782 if (g_bytes_in_stream == 0)
1783 {
17531784 g_bytes_in_stream = g_stream_inp->size;
1785 }
17541786
17551787 i = bytes_req - bytes_read;
17561788
18221854 g_snprintf(port, 255, CHANSRV_PORT_IN_STR, g_display_num);
18231855 g_audio_l_trans_in->trans_conn_in = sound_sndsrvr_source_conn_in;
18241856 if (trans_listen(g_audio_l_trans_in, port) != 0)
1825 LOG(0, ("trans_listen failed"));
1857 {
1858 LOG_DEVEL(LOG_LEVEL_ERROR, "trans_listen failed");
1859 }
18261860 return 0;
18271861 }
18281862
18391873 g_snprintf(port, 255, CHANSRV_PORT_OUT_STR, g_display_num);
18401874 g_audio_l_trans_out->trans_conn_in = sound_sndsrvr_sink_conn_in;
18411875 if (trans_listen(g_audio_l_trans_out, port) != 0)
1842 LOG(0, ("trans_listen failed"));
1843 return 0;
1844 }
1845
1876 {
1877 LOG_DEVEL(LOG_LEVEL_ERROR, "trans_listen failed");
1878 }
1879 return 0;
1880 }
1881
2929 #include "rail.h"
3030 #include "xcommon.h"
3131
32 /*
33 #undef LOG_LEVEL
34 #define LOG_LEVEL 11
35 */
36
3732 extern int g_clip_up; /* in clipboard.c */
3833
3934 extern int g_rail_up; /* in rail.c */
6055 char text[256];
6156
6257 XGetErrorText(dis, xer->error_code, text, 255);
63 LOGM((LOG_LEVEL_ERROR, "X error [%s](%d) opcodes %d/%d "
64 "resource 0x%lx", text, xer->error_code,
65 xer->request_code, xer->minor_code, xer->resourceid));
58 LOG_DEVEL(LOG_LEVEL_ERROR, "X error [%s](%d) opcodes %d/%d "
59 "resource 0x%lx", text, xer->error_code,
60 xer->request_code, xer->minor_code, xer->resourceid);
6661 return 0;
6762 }
6863
107102 {
108103 if (g_display != 0)
109104 {
110 LOG(10, ("xcommon_init: xcommon_init already called"));
105 LOG_DEVEL(LOG_LEVEL_DEBUG, "xcommon_init: xcommon_init already called");
111106 return 0;
112107 }
113108
115110
116111 if (g_display == 0)
117112 {
118 LOGM((LOG_LEVEL_ERROR, "xcommon_init: error, XOpenDisplay failed"));
113 LOG_DEVEL(LOG_LEVEL_ERROR, "xcommon_init: error, XOpenDisplay failed");
119114 return 1;
120115 }
121116
122 LOG(0, ("xcommon_init: connected to display ok"));
117 LOG_DEVEL(LOG_LEVEL_INFO, "xcommon_init: connected to display ok");
123118
124119 /* setting the error handlers can cause problem when shutting down
125120 chansrv on some xlibs */
130125
131126 if (g_x_socket == 0)
132127 {
133 LOGM((LOG_LEVEL_ERROR, "xcommon_init: XConnectionNumber failed"));
128 LOG_DEVEL(LOG_LEVEL_ERROR, "xcommon_init: XConnectionNumber failed");
134129 return 1;
135130 }
136131
145140 g_utf8_string = XInternAtom(g_display, "UTF8_STRING", 0);
146141 g_net_wm_name = XInternAtom(g_display, "_NET_WM_NAME", 0);
147142 g_wm_state = XInternAtom(g_display, "WM_STATE", 0);
148
143
149144 return 0;
150145 }
151146
189184 rail_rv = rail_xevent(&xevent);
190185 if ((clip_rv == 1) && (rail_rv == 1))
191186 {
192 LOG(10, ("xcommon_check_wait_objs unknown xevent type %d",
193 xevent.type));
187 LOG_DEVEL(LOG_LEVEL_DEBUG, "xcommon_check_wait_objs unknown xevent type %d",
188 xevent.type);
194189 }
195190 }
196191 return 0;
3232 #include "file.h"
3333 #include "sesman.h"
3434 #include "log.h"
35
36
37
38 /******************************************************************************/
39 int
40 config_read(struct config_sesman *cfg)
41 {
42 int fd;
43 struct list *sec;
44 struct list *param_n;
45 struct list *param_v;
46 char cfg_file[256];
47
48 g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH);
49 fd = g_file_open(cfg_file);
50
51 if (-1 == fd)
52 {
53 return 1;
54 }
55
56 g_memset(cfg, 0, sizeof(struct config_sesman));
57 sec = list_create();
58 sec->auto_free = 1;
59 file_read_sections(fd, sec);
60 param_n = list_create();
61 param_n->auto_free = 1;
62 param_v = list_create();
63 param_v->auto_free = 1;
64
65 /* read global config */
66 config_read_globals(fd, cfg, param_n, param_v);
67
68 /* read Xvnc/X11rdp/Xorg parameter list */
69 config_read_vnc_params(fd, cfg, param_n, param_v);
70 config_read_rdp_params(fd, cfg, param_n, param_v);
71 config_read_xorg_params(fd, cfg, param_n, param_v);
72
73 /* read security config */
74 config_read_security(fd, &(cfg->sec), param_n, param_v);
75
76 /* read session config */
77 config_read_sessions(fd, &(cfg->sess), param_n, param_v);
78
79 config_read_session_variables(fd, cfg, param_n, param_v);
80
81 /* cleanup */
82 list_delete(sec);
83 list_delete(param_v);
84 list_delete(param_n);
85 g_file_close(fd);
86 return 0;
87 }
88
89 /******************************************************************************/
90 int
35 #include "string_calls.h"
36
37 /***************************************************************************//**
38 *
39 * @brief Reads sesman [global] configuration section
40 * @param file configuration file descriptor
41 * @param cf pointer to a config struct
42 * @param param_n parameter name list
43 * @param param_v parameter value list
44 * @return 0 on success, 1 on failure
45 *
46 */
47 static int
9148 config_read_globals(int file, struct config_sesman *cf, struct list *param_n,
9249 struct list *param_v)
9350 {
204161 return 0;
205162 }
206163
207 /******************************************************************************/
208 int
164 /***************************************************************************//**
165 *
166 * @brief Reads sesman [Security] configuration section
167 * @param file configuration file descriptor
168 * @param sc pointer to a config_security struct
169 * @param param_n parameter name list
170 * @param param_v parameter value list
171 * @return 0 on success, 1 on failure
172 *
173 */
174 static int
209175 config_read_security(int file, struct config_security *sc,
210176 struct list *param_n,
211177 struct list *param_v)
272238 return 0;
273239 }
274240
275 /******************************************************************************/
276 int
241 /***************************************************************************//**
242 *
243 * @brief Reads sesman [Sessions] configuration section
244 * @param file configuration file descriptor
245 * @param ss pointer to a config_sessions struct
246 * @param param_n parameter name list
247 * @param param_v parameter value list
248 * @return 0 on success, 1 on failure
249 *
250 */
251 static int
277252 config_read_sessions(int file, struct config_sessions *se, struct list *param_n,
278253 struct list *param_v)
279254 {
359334 return 0;
360335 }
361336
362 /******************************************************************************/
363 int
337 /***************************************************************************//**
338 *
339 * @brief Reads sesman [X11rdp] configuration section
340 * @param file configuration file descriptor
341 * @param cs pointer to a config_sesman struct
342 * @param param_n parameter name list
343 * @param param_v parameter value list
344 * @return 0 on success, 1 on failure
345 *
346 */
347 static int
364348 config_read_rdp_params(int file, struct config_sesman *cs, struct list *param_n,
365349 struct list *param_v)
366350 {
382366 return 0;
383367 }
384368
385 /******************************************************************************/
386 int
369 /***************************************************************************//**
370 *
371 * @brief Reads sesman [Xorg] configuration section
372 * @param file configuration file descriptor
373 * @param cs pointer to a config_sesman struct
374 * @param param_n parameter name list
375 * @param param_v parameter value list
376 * @return 0 on success, 1 on failure
377 *
378 */
379 static int
387380 config_read_xorg_params(int file, struct config_sesman *cs,
388381 struct list *param_n, struct list *param_v)
389382 {
406399 return 0;
407400 }
408401
409 /******************************************************************************/
410 int
402 /***************************************************************************//**
403 *
404 * @brief Reads sesman [Xvnc] configuration section
405 * @param file configuration file descriptor
406 * @param cs pointer to a config_sesman struct
407 * @param param_n parameter name list
408 * @param param_v parameter value list
409 * @return 0 on success, 1 on failure
410 *
411 */
412 static int
411413 config_read_vnc_params(int file, struct config_sesman *cs, struct list *param_n,
412414 struct list *param_v)
413415 {
430432 }
431433
432434 /******************************************************************************/
433 int
435 static int
434436 config_read_session_variables(int file, struct config_sesman *cs,
435437 struct list *param_n, struct list *param_v)
436438 {
457459 return 0;
458460 }
459461
462 /******************************************************************************/
463 struct config_sesman *
464 config_read(const char *sesman_ini)
465 {
466 struct config_sesman *cfg;
467 int all_ok = 0;
468
469 if ((cfg = g_new0(struct config_sesman, 1)) != NULL)
470 {
471 if ((cfg->sesman_ini = g_strdup(sesman_ini)) != NULL)
472 {
473 int fd;
474 if ((fd = g_file_open_ex(cfg->sesman_ini, 1, 0, 0, 0)) != -1)
475 {
476 struct list *sec;
477 struct list *param_n;
478 struct list *param_v;
479 sec = list_create();
480 sec->auto_free = 1;
481 file_read_sections(fd, sec);
482 param_n = list_create();
483 param_n->auto_free = 1;
484 param_v = list_create();
485 param_v->auto_free = 1;
486
487 /* read global config */
488 config_read_globals(fd, cfg, param_n, param_v);
489
490 /* read Xvnc/X11rdp/Xorg parameter list */
491 config_read_vnc_params(fd, cfg, param_n, param_v);
492 config_read_rdp_params(fd, cfg, param_n, param_v);
493 config_read_xorg_params(fd, cfg, param_n, param_v);
494
495 /* read security config */
496 config_read_security(fd, &(cfg->sec), param_n, param_v);
497
498 /* read session config */
499 config_read_sessions(fd, &(cfg->sess), param_n, param_v);
500
501 config_read_session_variables(fd, cfg, param_n, param_v);
502
503 /* cleanup */
504 list_delete(sec);
505 list_delete(param_v);
506 list_delete(param_n);
507 g_file_close(fd);
508 all_ok = 1;
509 }
510 }
511 }
512
513 if (!all_ok)
514 {
515 config_free(cfg);
516 cfg = NULL;
517 }
518
519 return cfg;
520 }
521
522 /******************************************************************************/
460523 void
461524 config_dump(struct config_sesman *config)
462525 {
467530 sc = &(config->sec);
468531
469532 /* Global sesman configuration */
533 g_writeln("Filename: %s", config->sesman_ini);
470534 g_writeln("Global configuration:");
471535 g_writeln(" ListenAddress: %s", config->listen_address);
472536 g_writeln(" ListenPort: %s", config->listen_port);
566630 }
567631 }
568632
633 /******************************************************************************/
569634 void
570635 config_free(struct config_sesman *cs)
571636 {
572 g_free(cs->default_wm);
573 g_free(cs->reconnect_sh);
574 g_free(cs->auth_file_path);
575 list_delete(cs->rdp_params);
576 list_delete(cs->vnc_params);
577 list_delete(cs->xorg_params);
578 list_delete(cs->env_names);
579 list_delete(cs->env_values);
580 g_free(cs);
581 }
637 if (cs != NULL)
638 {
639 g_free(cs->sesman_ini);
640 g_free(cs->default_wm);
641 g_free(cs->reconnect_sh);
642 g_free(cs->auth_file_path);
643 list_delete(cs->rdp_params);
644 list_delete(cs->vnc_params);
645 list_delete(cs->xorg_params);
646 list_delete(cs->env_names);
647 list_delete(cs->env_values);
648 g_free(cs);
649 }
650 }
186186 struct config_sesman
187187 {
188188 /**
189 * @var sesman_ini
190 * @brief File that these parameters are read from
191 */
192 char *sesman_ini;
193
194 /**
189195 * @var listen_address
190196 * @brief Listening address
191197 */
266272 /**
267273 *
268274 * @brief Reads sesman configuration
269 * @param cfg pointer to configuration object to be replaced
270 * @return 0 on success, 1 on failure
271 *
272 */
273 int
274 config_read(struct config_sesman* cfg);
275
276 /**
277 *
278 * @brief Reads sesman [global] configuration section
279 * @param file configuration file descriptor
280 * @param cf pointer to a config struct
281 * @param param_n parameter name list
282 * @param param_v parameter value list
283 * @return 0 on success, 1 on failure
284 *
285 */
286 int
287 config_read_globals(int file, struct config_sesman* cf,
288 struct list* param_n, struct list* param_v);
289
290 /**
291 *
292 * @brief Reads sesman [Security] configuration section
293 * @param file configuration file descriptor
294 * @param sc pointer to a config_security struct
295 * @param param_n parameter name list
296 * @param param_v parameter value list
297 * @return 0 on success, 1 on failure
298 *
299 */
300 int
301 config_read_security(int file, struct config_security* sc,
302 struct list* param_n, struct list* param_v);
303
304 /**
305 *
306 * @brief Reads sesman [Sessions] configuration section
307 * @param file configuration file descriptor
308 * @param ss pointer to a config_sessions struct
309 * @param param_n parameter name list
310 * @param param_v parameter value list
311 * @return 0 on success, 1 on failure
312 *
313 */
314 int
315 config_read_sessions(int file, struct config_sessions* ss,
316 struct list* param_n, struct list* param_v);
317
318 /**
319 *
320 * @brief Reads sesman [X11rdp] configuration section
321 * @param file configuration file descriptor
322 * @param cs pointer to a config_sesman struct
323 * @param param_n parameter name list
324 * @param param_v parameter value list
325 * @return 0 on success, 1 on failure
326 *
327 */
328 int
329 config_read_rdp_params(int file, struct config_sesman* cs, struct list* param_n,
330 struct list* param_v);
331
332 /**
333 *
334 * @brief Reads sesman [Xorg] configuration section
335 * @param file configuration file descriptor
336 * @param cs pointer to a config_sesman struct
337 * @param param_n parameter name list
338 * @param param_v parameter value list
339 * @return 0 on success, 1 on failure
340 *
341 */
342 int
343 config_read_xorg_params(int file, struct config_sesman* cs, struct list* param_n,
344 struct list* param_v);
345
346 /**
347 *
348 * @brief Reads sesman [Xvnc] configuration section
349 * @param file configuration file descriptor
350 * @param cs pointer to a config_sesman struct
351 * @param param_n parameter name list
352 * @param param_v parameter value list
353 * @return 0 on success, 1 on failure
354 *
355 */
356 int
357 config_read_vnc_params(int file, struct config_sesman* cs, struct list* param_n,
358 struct list* param_v);
359
360 int
361 config_read_session_variables(int file, struct config_sesman *cs,
362 struct list *param_n, struct list *param_v);
275 * @param sesman_ini Name of configuration file to read
276 * @return configuration on success, NULL on failure
277 *
278 * @post pass return value to config_free() to prevent memory leaks
279 *
280 */
281 struct config_sesman*
282 config_read(const char *sesman_ini);
283
363284 /**
364285 *
365286 * @brief Dumps configuration
369290 void
370291 config_dump(struct config_sesman *config);
371292
293 /**
294 *
295 * @brief Frees configuration allocated by config_read()
296 * @param pointer to a config_sesman struct (may be NULL)
297 *
298 */
372299 void
373300 config_free(struct config_sesman *cs);
374301
3333 #include "list.h"
3434 #include "sesman.h"
3535 #include "ssl_calls.h"
36 #include "string_calls.h"
3637
3738 extern unsigned char g_fixedkey[8]; /* in sesman.c */
3839 extern struct config_sesman *g_cfg; /* in sesman.c */
7576 fd = g_file_open_ex(filename, 0, 1, 1, 1);
7677 if (fd == -1)
7778 {
78 log_message(LOG_LEVEL_WARNING,
79 "Cannot write VNC password hash to file %s: %s",
80 filename, g_get_strerror());
79 LOG(LOG_LEVEL_WARNING,
80 "Cannot write VNC password hash to file %s: %s",
81 filename, g_get_strerror());
8182 return 1;
8283 }
8384 g_file_write(fd, encryptedPasswd, 8);
150151 g_snprintf(text, sizeof(text) - 1, CHANSRV_PORT_IN_BASE_STR, display);
151152 g_setenv("XRDP_PULSE_SOURCE_SOCKET", text, 1);
152153 if ((env_names != 0) && (env_values != 0) &&
153 (env_names->count == env_values->count))
154 (env_names->count == env_values->count))
154155 {
155156 for (index = 0; index < env_names->count; index++)
156157 {
171172 {
172173 if (g_mkdir(".vnc") < 0)
173174 {
174 log_message(LOG_LEVEL_ERROR,
175 "Error creating .vnc directory: %s",
176 g_get_strerror());
175 LOG(LOG_LEVEL_ERROR,
176 "Error creating .vnc directory: %s",
177 g_get_strerror());
177178 }
178179 }
179180
188189 pw_dir, username, display);
189190 if (g_file_exist(*passwd_file))
190191 {
191 log_message(LOG_LEVEL_WARNING, "Removing old "
192 "password file %s", *passwd_file);
192 LOG(LOG_LEVEL_WARNING, "Removing old "
193 "password file %s", *passwd_file);
193194 g_file_delete(*passwd_file);
194195 }
195196 g_sprintf(*passwd_file, "%s/.vnc/sesman_%s_passwd",
196197 pw_dir, username);
197198 if (g_file_exist(*passwd_file))
198199 {
199 log_message(LOG_LEVEL_WARNING, "Removing insecure "
200 "password file %s", *passwd_file);
200 LOG(LOG_LEVEL_WARNING, "Removing insecure "
201 "password file %s", *passwd_file);
201202 g_file_delete(*passwd_file);
202203 }
203204 g_sprintf(*passwd_file, "%s/.vnc/sesman_passwd-%s@%s:%d",
218219
219220 if (*passwd_file != NULL)
220221 {
221 LOG_DBG("pass file: %s", *passwd_file);
222 LOG_DEVEL(LOG_LEVEL_DEBUG, "pass file: %s", *passwd_file);
222223 }
223224 }
224225
228229 }
229230 else
230231 {
231 log_message(LOG_LEVEL_ERROR,
232 "error getting user info for user %s",
233 username);
232 LOG(LOG_LEVEL_ERROR,
233 "error getting user info for user %s",
234 username);
234235 }
235236
236237 return error;
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
4040
4141 if (0 == conn)
4242 {
43 log_message(LOG_LEVEL_ERROR, "[connection:%d] connection create: malloc error", __LINE__);
43 LOG(LOG_LEVEL_ERROR, "[connection:%d] connection create: malloc error", __LINE__);
4444 return 0;
4545 }
4646
4646
4747 scp_lock_init();
4848
49 log_message(LOG_LEVEL_DEBUG, "libscp initialized");
49 LOG(LOG_LEVEL_DEBUG, "libscp initialized");
5050
5151 return 0;
5252 }
9797 void
9898 scp_lock_fork_critical_section_end(int blocking)
9999 {
100 //LOG_DBG("lock_fork_critical_section_end()",0);
100 //LOG_DEVEL(LOG_LEVEL_DEBUG, "lock_fork_critical_section_end()",0);
101101 /* lock mutex */
102102 pthread_mutex_lock(&lock_fork);
103103
120120 int
121121 scp_lock_fork_critical_section_start(void)
122122 {
123 //LOG_DBG("lock_fork_critical_section_start()",0);
123 //LOG_DEVEL(LOG_LEVEL_DEBUG, "lock_fork_critical_section_start()",0);
124124 do
125125 {
126126 pthread_mutex_lock(&lock_fork);
2828 #endif
2929
3030 #include "libscp_session.h"
31 #include "string_calls.h"
3132
3233 #include <sys/types.h>
3334 #include <sys/socket.h>
4546
4647 if (0 == s)
4748 {
48 log_message(LOG_LEVEL_ERROR, "[session:%d] session create: malloc error", __LINE__);
49 LOG(LOG_LEVEL_ERROR, "[session:%d] session create: malloc error", __LINE__);
4950 return 0;
5051 }
5152
8081
8182 if (NULL == s->mng)
8283 {
83 log_message(LOG_LEVEL_ERROR, "[session:%d] set_type: internal error", __LINE__);
84 LOG(LOG_LEVEL_ERROR, "[session:%d] set_type: internal error", __LINE__);
8485 return 1;
8586 }
8687
8788 break;
8889
8990 default:
90 log_message(LOG_LEVEL_WARNING, "[session:%d] set_type: unknown type", __LINE__);
91 LOG(LOG_LEVEL_WARNING, "[session:%d] set_type: unknown type", __LINE__);
9192 return 1;
9293 }
9394
107108 s->version = 1;
108109 break;
109110 default:
110 log_message(LOG_LEVEL_WARNING, "[session:%d] set_version: unknown version", __LINE__);
111 LOG(LOG_LEVEL_WARNING, "[session:%d] set_version: unknown version", __LINE__);
111112 return 1;
112113 }
113114
171172 {
172173 if (0 == str)
173174 {
174 log_message(LOG_LEVEL_WARNING, "[session:%d] set_locale: null locale", __LINE__);
175 LOG(LOG_LEVEL_WARNING, "[session:%d] set_locale: null locale", __LINE__);
175176 s->locale[0] = '\0';
176177 return 1;
177178 }
187188 {
188189 if (0 == str)
189190 {
190 log_message(LOG_LEVEL_WARNING, "[session:%d] set_username: null username", __LINE__);
191 LOG(LOG_LEVEL_WARNING, "[session:%d] set_username: null username", __LINE__);
191192 return 1;
192193 }
193194
200201
201202 if (0 == s->username)
202203 {
203 log_message(LOG_LEVEL_WARNING, "[session:%d] set_username: strdup error", __LINE__);
204 LOG(LOG_LEVEL_WARNING, "[session:%d] set_username: strdup error", __LINE__);
204205 return 1;
205206 }
206207
213214 {
214215 if (0 == str)
215216 {
216 log_message(LOG_LEVEL_WARNING, "[session:%d] set_password: null password", __LINE__);
217 LOG(LOG_LEVEL_WARNING, "[session:%d] set_password: null password", __LINE__);
217218 return 1;
218219 }
219220
226227
227228 if (0 == s->password)
228229 {
229 log_message(LOG_LEVEL_WARNING, "[session:%d] set_password: strdup error", __LINE__);
230 LOG(LOG_LEVEL_WARNING, "[session:%d] set_password: strdup error", __LINE__);
230231 return 1;
231232 }
232233
239240 {
240241 if (0 == str)
241242 {
242 log_message(LOG_LEVEL_WARNING, "[session:%d] set_domain: null domain", __LINE__);
243 LOG(LOG_LEVEL_WARNING, "[session:%d] set_domain: null domain", __LINE__);
243244 return 1;
244245 }
245246
252253
253254 if (0 == s->domain)
254255 {
255 log_message(LOG_LEVEL_WARNING, "[session:%d] set_domain: strdup error", __LINE__);
256 LOG(LOG_LEVEL_WARNING, "[session:%d] set_domain: strdup error", __LINE__);
256257 return 1;
257258 }
258259
265266 {
266267 if (0 == str)
267268 {
268 log_message(LOG_LEVEL_WARNING, "[session:%d] set_program: null program", __LINE__);
269 LOG(LOG_LEVEL_WARNING, "[session:%d] set_program: null program", __LINE__);
269270 return 1;
270271 }
271272
278279
279280 if (0 == s->program)
280281 {
281 log_message(LOG_LEVEL_WARNING, "[session:%d] set_program: strdup error", __LINE__);
282 LOG(LOG_LEVEL_WARNING, "[session:%d] set_program: strdup error", __LINE__);
282283 return 1;
283284 }
284285
291292 {
292293 if (0 == str)
293294 {
294 log_message(LOG_LEVEL_WARNING, "[session:%d] set_directory: null directory", __LINE__);
295 LOG(LOG_LEVEL_WARNING, "[session:%d] set_directory: null directory", __LINE__);
295296 return 1;
296297 }
297298
304305
305306 if (0 == s->directory)
306307 {
307 log_message(LOG_LEVEL_WARNING, "[session:%d] set_directory: strdup error", __LINE__);
308 LOG(LOG_LEVEL_WARNING, "[session:%d] set_directory: strdup error", __LINE__);
308309 return 1;
309310 }
310311
317318 {
318319 if (0 == str)
319320 {
320 log_message(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: null ip", __LINE__);
321 LOG(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: null ip", __LINE__);
321322 return 1;
322323 }
323324
330331
331332 if (0 == s->client_ip)
332333 {
333 log_message(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: strdup error", __LINE__);
334 LOG(LOG_LEVEL_WARNING, "[session:%d] set_client_ip: strdup error", __LINE__);
334335 return 1;
335336 }
336337
343344 {
344345 if (0 == str)
345346 {
346 log_message(LOG_LEVEL_WARNING, "[session:%d] set_hostname: null hostname", __LINE__);
347 LOG(LOG_LEVEL_WARNING, "[session:%d] set_hostname: null hostname", __LINE__);
347348 return 1;
348349 }
349350
356357
357358 if (0 == s->hostname)
358359 {
359 log_message(LOG_LEVEL_WARNING, "[session:%d] set_hostname: strdup error", __LINE__);
360 LOG(LOG_LEVEL_WARNING, "[session:%d] set_hostname: strdup error", __LINE__);
360361 return 1;
361362 }
362363
369370 {
370371 if (0 == str)
371372 {
372 log_message(LOG_LEVEL_WARNING, "[session:%d] set_errstr: null string", __LINE__);
373 LOG(LOG_LEVEL_WARNING, "[session:%d] set_errstr: null string", __LINE__);
373374 return 1;
374375 }
375376
382383
383384 if (0 == s->errstr)
384385 {
385 log_message(LOG_LEVEL_WARNING, "[session:%d] set_errstr: strdup error", __LINE__);
386 LOG(LOG_LEVEL_WARNING, "[session:%d] set_errstr: strdup error", __LINE__);
386387 return 1;
387388 }
388389
424425 {
425426 if (0 == guid)
426427 {
427 log_message(LOG_LEVEL_WARNING, "[session:%d] set_guid: null guid", __LINE__);
428 LOG(LOG_LEVEL_WARNING, "[session:%d] set_guid: null guid", __LINE__);
428429 return 1;
429430 }
430431
3838 int rcvd;
3939 int block;
4040
41 LOG_DBG("scp_tcp_force_recv()");
41 LOG_DEVEL(LOG_LEVEL_DEBUG, "scp_tcp_force_recv()");
4242 block = scp_lock_fork_critical_section_start();
4343
4444 while (len > 0)
8181 int sent;
8282 int block;
8383
84 LOG_DBG("scp_tcp_force_send()");
84 LOG_DEVEL(LOG_LEVEL_DEBUG, "scp_tcp_force_send()");
8585 block = scp_lock_fork_critical_section_start();
8686
8787 while (len > 0)
5757 #define SCP_SERVER_MAX_LIST_SIZE 100
5858
5959 #include "libscp_types_mng.h"
60
61 /* Max server incoming and outgoing message size, used to stop memory
62 exhaustion attempts (CVE-2020-4044) */
63 #define SCP_MAX_MESSAGE_SIZE 8192
6064
6165 struct SCP_CONNECTION
6266 {
3030 #include "libscp_v0.h"
3131
3232 #include "os_calls.h"
33 #include "string_calls.h"
3334
3435 extern struct log_config *s_log;
3536
37 /** Maximum length of a string (two bytes + len), excluding the terminator
38 *
39 * Practially this is limited by [MS-RDPBCGR] TS_INFO_PACKET
40 * */
41 #define STRING16_MAX_LEN 512
42
43 /**
44 * Reads a big-endian uint16 followed by a string into a buffer
45 *
46 * Buffer is null-terminated on success
47 *
48 * @param s Input stream
49 * @param [out] Output buffer (must be >= (STRING16_MAX_LEN+1) chars)
50 * @param param Parameter we're reading
51 * @return != 0 if string read OK
52 */
53 static
54 int in_string16(struct stream *s, char str[], const char *param)
55 {
56 int result;
57
58 if (!s_check_rem(s, 2))
59 {
60 LOG(LOG_LEVEL_WARNING, "connection aborted: %s len missing", param);
61 result = 0;
62 }
63 else
64 {
65 unsigned int sz;
66
67 in_uint16_be(s, sz);
68 if (sz > STRING16_MAX_LEN)
69 {
70 LOG(LOG_LEVEL_WARNING,
71 "connection aborted: %s too long (%u chars)", param, sz);
72 result = 0;
73 }
74 else
75 {
76 result = s_check_rem(s, sz);
77 if (!result)
78 {
79 LOG(LOG_LEVEL_WARNING, "connection aborted: %s data missing", param);
80 }
81 else
82 {
83 in_uint8a(s, str, sz);
84 str[sz] = '\0';
85 }
86 }
87 }
88 return result;
89 }
3690 /* client API */
3791 /******************************************************************************/
3892 enum SCP_CLIENT_STATES_E
3993 scp_v0c_connect(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
4094 {
4195 tui32 version;
42 tui32 size;
96 int size;
4397 tui16 sz;
4498
4599 init_stream(c->in_s, c->in_s->size);
46100 init_stream(c->out_s, c->in_s->size);
47101
48 LOG_DBG("[v0:%d] starting connection", __LINE__);
102 LOG_DEVEL(LOG_LEVEL_DEBUG, "starting connection");
49103 g_tcp_set_non_blocking(c->in_sck);
50104 g_tcp_set_no_delay(c->in_sck);
51105 s_push_layer(c->out_s, channel_hdr, 8);
65119 }
66120 else
67121 {
68 log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
122 LOG(LOG_LEVEL_WARNING, "connection aborted: network error");
69123 return SCP_CLIENT_STATE_INTERNAL_ERR;
70124 }
71125
72126 sz = g_strlen(s->username);
127 if (sz > STRING16_MAX_LEN)
128 {
129 LOG(LOG_LEVEL_WARNING, "connection aborted: username too long");
130 return SCP_CLIENT_STATE_SIZE_ERR;
131 }
73132 out_uint16_be(c->out_s, sz);
74133 out_uint8a(c->out_s, s->username, sz);
75134
76135 sz = g_strlen(s->password);
136 if (sz > STRING16_MAX_LEN)
137 {
138 LOG(LOG_LEVEL_WARNING, "connection aborted: password too long");
139 return SCP_CLIENT_STATE_SIZE_ERR;
140 }
77141 out_uint16_be(c->out_s, sz);
78142 out_uint8a(c->out_s, s->password, sz);
79143 out_uint16_be(c->out_s, s->width);
90154
91155 if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data))
92156 {
93 log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
157 LOG(LOG_LEVEL_WARNING, "connection aborted: network error");
94158 return SCP_CLIENT_STATE_NETWORK_ERR;
95159 }
96160
97161 if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
98162 {
99 log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
163 LOG(LOG_LEVEL_WARNING, "connection aborted: network error");
100164 return SCP_CLIENT_STATE_NETWORK_ERR;
101165 }
102166
104168
105169 if (0 != version)
106170 {
107 log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__);
171 LOG(LOG_LEVEL_WARNING, "connection aborted: version error");
108172 return SCP_CLIENT_STATE_VERSION_ERR;
109173 }
110174
111175 in_uint32_be(c->in_s, size);
112176
113 if (size < 14)
114 {
115 log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: packet size error", __LINE__);
177 if (size < (8 + 2 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE)
178 {
179 LOG(LOG_LEVEL_WARNING, "connection aborted: msg size = %d", size);
116180 return SCP_CLIENT_STATE_SIZE_ERR;
117181 }
118182
119183 /* getting payload */
120 init_stream(c->in_s, c->in_s->size);
184 init_stream(c->in_s, size - 8);
121185
122186 if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
123187 {
124 log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
188 LOG(LOG_LEVEL_WARNING, "connection aborted: network error");
125189 return SCP_CLIENT_STATE_NETWORK_ERR;
126190 }
191
192 c->in_s->end = c->in_s->data + (size - 8);
127193
128194 /* check code */
129195 in_uint16_be(c->in_s, sz);
130196
131197 if (3 != sz)
132198 {
133 log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__);
199 LOG(LOG_LEVEL_WARNING, "connection aborted: sequence error");
134200 return SCP_CLIENT_STATE_SEQUENCE_ERR;
135201 }
136202
139205
140206 if (1 != sz)
141207 {
142 log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: connection denied", __LINE__);
208 LOG(LOG_LEVEL_WARNING, "connection aborted: connection denied");
143209 return SCP_CLIENT_STATE_CONNECTION_DENIED;
144210 }
145211
146212 in_uint16_be(c->in_s, sz);
147213 s->display = sz;
148214
149 LOG_DBG("[v0:%d] connection terminated", __LINE__);
215 LOG_DEVEL(LOG_LEVEL_DEBUG, "connection terminated");
150216 return SCP_CLIENT_STATE_END;
151217 }
218
219 /**
220 * Initialises a V0 session object
221 *
222 * At the time of the call, the version has been read from the connection
223 *
224 * @param c Connection
225 * @param [out] session pre-allocated session object
226 * @return SCP_SERVER_STATE_OK for success
227 */
228 static enum SCP_SERVER_STATES_E
229 scp_v0s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
230 {
231 int size;
232 tui16 height;
233 tui16 width;
234 tui16 bpp;
235 tui32 code = 0;
236 char buf[STRING16_MAX_LEN + 1];
237
238 scp_session_set_version(session, 0);
239
240 /* Check for a header and a code value in the length */
241 in_uint32_be(c->in_s, size);
242 if (size < (8 + 2) || size > SCP_MAX_MESSAGE_SIZE)
243 {
244 LOG(LOG_LEVEL_WARNING, "connection aborted: msg size = %d", size);
245 return SCP_SERVER_STATE_SIZE_ERR;
246 }
247
248 init_stream(c->in_s, size - 8);
249
250 if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
251 {
252 LOG(LOG_LEVEL_WARNING, "connection aborted: network error");
253 return SCP_SERVER_STATE_NETWORK_ERR;
254 }
255
256 c->in_s->end = c->in_s->data + (size - 8);
257
258 in_uint16_be(c->in_s, code);
259
260 if (code == 0 || code == 10 || code == 20)
261 {
262 if (code == 0)
263 {
264 scp_session_set_type(session, SCP_SESSION_TYPE_XVNC);
265 }
266 else if (code == 10)
267 {
268 scp_session_set_type(session, SCP_SESSION_TYPE_XRDP);
269 }
270 else if (code == 20)
271 {
272 scp_session_set_type(session, SCP_SESSION_TYPE_XORG);
273 }
274
275 /* reading username */
276 if (!in_string16(c->in_s, buf, "username"))
277 {
278 return SCP_SERVER_STATE_SIZE_ERR;
279 }
280 if (0 != scp_session_set_username(session, buf))
281 {
282 LOG(LOG_LEVEL_WARNING, "connection aborted: error setting username");
283 return SCP_SERVER_STATE_INTERNAL_ERR;
284 }
285
286 /* reading password */
287 if (!in_string16(c->in_s, buf, "passwd"))
288 {
289 return SCP_SERVER_STATE_SIZE_ERR;
290 }
291 if (0 != scp_session_set_password(session, buf))
292 {
293 LOG(LOG_LEVEL_WARNING, "connection aborted: error setting password");
294 return SCP_SERVER_STATE_INTERNAL_ERR;
295 }
296
297 /* width + height + bpp */
298 if (!s_check_rem(c->in_s, 2 + 2 + 2))
299 {
300 LOG(LOG_LEVEL_WARNING, "connection aborted: width+height+bpp missing");
301 return SCP_SERVER_STATE_SIZE_ERR;
302 }
303 in_uint16_be(c->in_s, width);
304 scp_session_set_width(session, width);
305 in_uint16_be(c->in_s, height);
306 scp_session_set_height(session, height);
307 in_uint16_be(c->in_s, bpp);
308 if (0 != scp_session_set_bpp(session, (tui8)bpp))
309 {
310 LOG(LOG_LEVEL_WARNING,
311 "connection aborted: unsupported bpp: %d", (tui8)bpp);
312 return SCP_SERVER_STATE_INTERNAL_ERR;
313 }
314
315 if (s_check_rem(c->in_s, 2))
316 {
317 /* reading domain */
318 if (!in_string16(c->in_s, buf, "domain"))
319 {
320 return SCP_SERVER_STATE_SIZE_ERR;
321 }
322 if (buf[0] != '\0')
323 {
324 scp_session_set_domain(session, buf);
325 }
326 }
327
328 if (s_check_rem(c->in_s, 2))
329 {
330 /* reading program */
331 if (!in_string16(c->in_s, buf, "program"))
332 {
333 return SCP_SERVER_STATE_SIZE_ERR;
334 }
335
336 if (buf[0] != '\0')
337 {
338 scp_session_set_program(session, buf);
339 }
340 }
341
342 if (s_check_rem(c->in_s, 2))
343 {
344 /* reading directory */
345 if (!in_string16(c->in_s, buf, "directory"))
346 {
347 return SCP_SERVER_STATE_SIZE_ERR;
348 }
349
350 if (buf[0] != '\0')
351 {
352 scp_session_set_directory(session, buf);
353 }
354 }
355
356 if (s_check_rem(c->in_s, 2))
357 {
358 /* reading client IP address */
359 if (!in_string16(c->in_s, buf, "client IP"))
360 {
361 return SCP_SERVER_STATE_SIZE_ERR;
362 }
363 if (buf[0] != '\0')
364 {
365 scp_session_set_client_ip(session, buf);
366 }
367 }
368 }
369 else if (code == SCP_GW_AUTHENTICATION)
370 {
371 scp_session_set_type(session, SCP_GW_AUTHENTICATION);
372 /* reading username */
373 if (!in_string16(c->in_s, buf, "username"))
374 {
375 return SCP_SERVER_STATE_SIZE_ERR;
376 }
377
378 /* g_writeln("Received user name: %s",buf); */
379 if (0 != scp_session_set_username(session, buf))
380 {
381 LOG(LOG_LEVEL_WARNING, "connection aborted: error setting username");
382 return SCP_SERVER_STATE_INTERNAL_ERR;
383 }
384
385 /* reading password */
386 if (!in_string16(c->in_s, buf, "passwd"))
387 {
388 return SCP_SERVER_STATE_SIZE_ERR;
389 }
390
391 /* g_writeln("Received password: %s",buf); */
392 if (0 != scp_session_set_password(session, buf))
393 {
394 LOG(LOG_LEVEL_WARNING, "connection aborted: error setting password");
395 return SCP_SERVER_STATE_INTERNAL_ERR;
396 }
397 }
398 else
399 {
400 LOG(LOG_LEVEL_WARNING, "connection aborted: sequence error");
401 return SCP_SERVER_STATE_SEQUENCE_ERR;
402 }
403
404 return SCP_SERVER_STATE_OK;
405 }
406
152407
153408 /* server API */
154409 /******************************************************************************/
155410 enum SCP_SERVER_STATES_E
156411 scp_v0s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk)
157412 {
413 enum SCP_SERVER_STATES_E result = SCP_SERVER_STATE_OK;
414 struct SCP_SESSION *session = NULL;
158415 tui32 version = 0;
159 tui32 size;
160 struct SCP_SESSION *session = 0;
161 tui16 sz;
162 tui32 code = 0;
163 char *buf = 0;
164416
165417 if (!skipVchk)
166418 {
167 LOG_DBG("[v0:%d] starting connection", __LINE__);
419 LOG_DEVEL(LOG_LEVEL_DEBUG, "starting connection");
168420
169421 if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
170422 {
173425
174426 if (version != 0)
175427 {
176 log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: version error", __LINE__);
177 return SCP_SERVER_STATE_VERSION_ERR;
428 LOG(LOG_LEVEL_WARNING, "connection aborted: version error");
429 result = SCP_SERVER_STATE_VERSION_ERR;
178430 }
179431 }
180432 else
181433 {
182 log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
183 return SCP_SERVER_STATE_NETWORK_ERR;
184 }
185 }
186
187 in_uint32_be(c->in_s, size);
188
189 init_stream(c->in_s, 8196);
190
191 if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
192 {
193 log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
194 return SCP_SERVER_STATE_NETWORK_ERR;
195 }
196
197 c->in_s->end = c->in_s->data + (size - 8);
198
199 in_uint16_be(c->in_s, code);
200
201 if (code == 0 || code == 10 || code == 20)
434 LOG(LOG_LEVEL_WARNING, "connection aborted: network error");
435 result = SCP_SERVER_STATE_NETWORK_ERR;
436 }
437 }
438
439 if (result == SCP_SERVER_STATE_OK)
202440 {
203441 session = scp_session_create();
204
205 if (0 == session)
206 {
207 log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
208 return SCP_SERVER_STATE_INTERNAL_ERR;
209 }
210
211 scp_session_set_version(session, version);
212
213 if (code == 0)
214 {
215 scp_session_set_type(session, SCP_SESSION_TYPE_XVNC);
216 }
217 else if (code == 10)
218 {
219 scp_session_set_type(session, SCP_SESSION_TYPE_XRDP);
220 }
221 else if (code == 20)
222 {
223 scp_session_set_type(session, SCP_SESSION_TYPE_XORG);
224 }
225
226 /* reading username */
227 in_uint16_be(c->in_s, sz);
228 buf = g_new0(char, sz + 1);
229 in_uint8a(c->in_s, buf, sz);
230 buf[sz] = '\0';
231 if (0 != scp_session_set_username(session, buf))
232 {
233 scp_session_destroy(session);
234 log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__);
235 g_free(buf);
236 return SCP_SERVER_STATE_INTERNAL_ERR;
237 }
238 g_free(buf);
239
240 /* reading password */
241 in_uint16_be(c->in_s, sz);
242 buf = g_new0(char, sz + 1);
243 in_uint8a(c->in_s, buf, sz);
244 buf[sz] = '\0';
245 if (0 != scp_session_set_password(session, buf))
246 {
247 scp_session_destroy(session);
248 log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__);
249 g_free(buf);
250 return SCP_SERVER_STATE_INTERNAL_ERR;
251 }
252 g_free(buf);
253
254 /* width */
255 in_uint16_be(c->in_s, sz);
256 scp_session_set_width(session, sz);
257 /* height */
258 in_uint16_be(c->in_s, sz);
259 scp_session_set_height(session, sz);
260 /* bpp */
261 in_uint16_be(c->in_s, sz);
262 if (0 != scp_session_set_bpp(session, (tui8)sz))
263 {
264 scp_session_destroy(session);
265 log_message(LOG_LEVEL_WARNING,
266 "[v0:%d] connection aborted: unsupported bpp: %d",
267 __LINE__, (tui8)sz);
268 return SCP_SERVER_STATE_INTERNAL_ERR;
269 }
270
271 if (s_check_rem(c->in_s, 2))
272 {
273 /* reading domain */
274 in_uint16_be(c->in_s, sz);
275
276 if (sz > 0)
277 {
278 buf = g_new0(char, sz + 1);
279 in_uint8a(c->in_s, buf, sz);
280 buf[sz] = '\0';
281 scp_session_set_domain(session, buf);
282 g_free(buf);
283 }
284 }
285
286 if (s_check_rem(c->in_s, 2))
287 {
288 /* reading program */
289 in_uint16_be(c->in_s, sz);
290
291 if (sz > 0)
292 {
293 buf = g_new0(char, sz + 1);
294 in_uint8a(c->in_s, buf, sz);
295 buf[sz] = '\0';
296 scp_session_set_program(session, buf);
297 g_free(buf);
298 }
299 }
300
301 if (s_check_rem(c->in_s, 2))
302 {
303 /* reading directory */
304 in_uint16_be(c->in_s, sz);
305
306 if (sz > 0)
307 {
308 buf = g_new0(char, sz + 1);
309 in_uint8a(c->in_s, buf, sz);
310 buf[sz] = '\0';
311 scp_session_set_directory(session, buf);
312 g_free(buf);
313 }
314 }
315
316 if (s_check_rem(c->in_s, 2))
317 {
318 /* reading client IP address */
319 in_uint16_be(c->in_s, sz);
320
321 if (sz > 0)
322 {
323 buf = g_new0(char, sz + 1);
324 in_uint8a(c->in_s, buf, sz);
325 buf[sz] = '\0';
326 scp_session_set_client_ip(session, buf);
327 g_free(buf);
328 }
329 }
330 }
331 else if (code == SCP_GW_AUTHENTICATION)
332 {
333 /* g_writeln("Command is SCP_GW_AUTHENTICATION"); */
334 session = scp_session_create();
335
336 if (0 == session)
337 {
338 /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);*/
339 return SCP_SERVER_STATE_INTERNAL_ERR;
340 }
341
342 scp_session_set_version(session, version);
343 scp_session_set_type(session, SCP_GW_AUTHENTICATION);
344 /* reading username */
345 in_uint16_be(c->in_s, sz);
346 buf = g_new0(char, sz + 1);
347 in_uint8a(c->in_s, buf, sz);
348 buf[sz] = '\0';
349
350 /* g_writeln("Received user name: %s",buf); */
351 if (0 != scp_session_set_username(session, buf))
352 {
353 scp_session_destroy(session);
354 /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__);*/
355 g_free(buf);
356 return SCP_SERVER_STATE_INTERNAL_ERR;
357 }
358 g_free(buf);
359
360 /* reading password */
361 in_uint16_be(c->in_s, sz);
362 buf = g_new0(char, sz + 1);
363 in_uint8a(c->in_s, buf, sz);
364 buf[sz] = '\0';
365
366 /* g_writeln("Received password: %s",buf); */
367 if (0 != scp_session_set_password(session, buf))
368 {
369 scp_session_destroy(session);
370 /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__); */
371 g_free(buf);
372 return SCP_SERVER_STATE_INTERNAL_ERR;
373 }
374 g_free(buf);
375 }
376 else
377 {
378 log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__);
379 return SCP_SERVER_STATE_SEQUENCE_ERR;
442 if (NULL == session)
443 {
444 LOG(LOG_LEVEL_WARNING, "connection aborted: no memory");
445 result = SCP_SERVER_STATE_INTERNAL_ERR;
446 }
447 else
448 {
449 result = scp_v0s_init_session(c, session);
450 if (result != SCP_SERVER_STATE_OK)
451 {
452 scp_session_destroy(session);
453 session = NULL;
454 }
455 }
380456 }
381457
382458 (*s) = session;
383 return SCP_SERVER_STATE_OK;
459
460 return result;
384461 }
385462
386463 /******************************************************************************/
403480
404481 if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data))
405482 {
406 log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
483 LOG(LOG_LEVEL_WARNING, "connection aborted: network error");
407484 return SCP_SERVER_STATE_NETWORK_ERR;
408485 }
409486
410 LOG_DBG("[v0:%d] connection terminated (allowed)", __LINE__);
487 LOG_DEVEL(LOG_LEVEL_DEBUG, "connection terminated (allowed)");
411488 return SCP_SERVER_STATE_OK;
412489 }
413490
424501
425502 if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data))
426503 {
427 log_message(LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);
504 LOG(LOG_LEVEL_WARNING, "connection aborted: network error");
428505 return SCP_SERVER_STATE_NETWORK_ERR;
429506 }
430507
431 LOG_DBG("[v0:%d] connection terminated (denied)", __LINE__);
508 LOG_DEVEL(LOG_LEVEL_DEBUG, "connection terminated (denied)");
432509 return SCP_SERVER_STATE_OK;
433510 }
434511
447524 /* g_writeln("Total number of bytes that will be sent %d",c->out_s->end - c->out_s->data);*/
448525 if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data))
449526 {
450 /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); */
527 LOG(LOG_LEVEL_WARNING, "connection aborted: network error");
451528 return SCP_SERVER_STATE_NETWORK_ERR;
452529 }
453530
454 /* until syslog merge LOG_DBG(s_log, "[v0:%d] connection terminated (scp_v0s_deny_authentication)", __LINE__);*/
531 LOG_DEVEL(LOG_LEVEL_DEBUG, "connection terminated (scp_v0s_deny_authentication)");
455532 return SCP_SERVER_STATE_OK;
456533 }
2828 #endif
2929
3030 #include "libscp_v1c.h"
31 #include "string_calls.h"
3132
3233 #include <stdlib.h>
3334 #include <stdio.h>
4647 init_stream(c->out_s, c->out_s->size);
4748 init_stream(c->in_s, c->in_s->size);
4849
49 size = 19 + 17 + 4 + g_strlen(s->hostname) + g_strlen(s->username) +
50 g_strlen(s->password);
50 size = (19 + 17 + 4 + g_strlen(s->hostname) + g_strlen(s->username) +
51 g_strlen(s->password));
5152
5253 if (s->addr_type == SCP_ADDRESS_TYPE_IPV4)
5354 {
2828 #endif
2929
3030 #include "libscp_v1c_mng.h"
31 #include "string_calls.h"
3132
3233 #include <stdlib.h>
3334 #include <stdio.h>
4849 init_stream(c->out_s, c->out_s->size);
4950 init_stream(c->in_s, c->in_s->size);
5051
51 size = 12 + 4 + g_strlen(s->hostname) + g_strlen(s->username) +
52 g_strlen(s->password);
52 size = (12 + 4 + g_strlen(s->hostname) + g_strlen(s->username) +
53 g_strlen(s->password));
5354
5455 if (s->addr_type == SCP_ADDRESS_TYPE_IPV4)
5556 {
9596
9697 if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
9798 {
98 log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
99 LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
99100 return SCP_CLIENT_STATE_NETWORK_ERR;
100101 }
101102
131132
132133 if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
133134 {
134 log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
135 LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
135136 return SCP_CLIENT_STATE_NETWORK_ERR;
136137 }
137138
142143
143144 if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
144145 {
145 log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
146 LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
146147 g_free(ds);
147148 return SCP_CLIENT_STATE_NETWORK_ERR;
148149 }
151152
152153 if (version != 1)
153154 {
154 log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__);
155 LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__);
155156 g_free(ds);
156157 return SCP_CLIENT_STATE_VERSION_ERR;
157158 }
160161
161162 if (size < 12)
162163 {
163 log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: size error", __LINE__);
164 LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: size error", __LINE__);
164165 g_free(ds);
165166 return SCP_CLIENT_STATE_SIZE_ERR;
166167 }
169170
170171 if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
171172 {
172 log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
173 LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
173174 g_free(ds);
174175 return SCP_CLIENT_STATE_NETWORK_ERR;
175176 }
178179
179180 if (cmd != SCP_COMMAND_SET_MANAGE)
180181 {
181 log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
182 LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
182183 g_free(ds);
183184 return SCP_CLIENT_STATE_SEQUENCE_ERR;
184185 }
187188
188189 if (cmd != SCP_CMD_MNG_LIST) /* session list */
189190 {
190 log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
191 LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
191192 g_free(ds);
192193 return SCP_CLIENT_STATE_SEQUENCE_ERR;
193194 }
204205 (*scount) = sescnt;
205206 (*s) = NULL;
206207
207 LOG_DBG("[v1c_mng] end list - no session on TS");
208 LOG_DEVEL(LOG_LEVEL_DEBUG, "[v1c_mng] end list - no session on TS");
208209 return SCP_CLIENT_STATE_LIST_OK;
209210 }
210211
212213
213214 if (ds == 0)
214215 {
215 log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: internal error", __LINE__);
216 LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: internal error", __LINE__);
216217 return SCP_CLIENT_STATE_INTERNAL_ERR;
217218 }
218219 }
261262 (*scount) = sescnt;
262263 (*s) = ds;
263264
264 LOG_DBG("[v1c_mng] end list");
265 LOG_DEVEL(LOG_LEVEL_DEBUG, "[v1c_mng] end list");
265266 return SCP_CLIENT_STATE_LIST_OK;
266267 }
267268
372373
373374 if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
374375 {
375 log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
376 LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
376377 return SCP_CLIENT_STATE_NETWORK_ERR;
377378 }
378379
380381
381382 if (version != 1)
382383 {
383 log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__);
384 LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__);
384385 return SCP_CLIENT_STATE_VERSION_ERR;
385386 }
386387
391392 /* read the rest of the packet */
392393 if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
393394 {
394 log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
395 LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__);
395396 return SCP_CLIENT_STATE_NETWORK_ERR;
396397 }
397398
399400
400401 if (cmd != SCP_COMMAND_SET_MANAGE)
401402 {
402 log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
403 LOG(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__);
403404 return SCP_CLIENT_STATE_SEQUENCE_ERR;
404405 }
405406
407408
408409 if (cmd == SCP_CMD_MNG_LOGIN_ALLOW) /* connection ok */
409410 {
410 log_message(LOG_LEVEL_INFO, "[v1c_mng:%d] connection ok", __LINE__);
411 LOG(LOG_LEVEL_INFO, "[v1c_mng:%d] connection ok", __LINE__);
411412 return SCP_CLIENT_STATE_OK;
412413 }
413414 else if (cmd == SCP_CMD_MNG_LOGIN_DENY) /* connection denied */
417418 in_uint8a(c->in_s, buf, dim);
418419 scp_session_set_errstr(s, buf);
419420
420 log_message(LOG_LEVEL_INFO, "[v1c_mng:%d] connection denied: %s", __LINE__ , s->errstr);
421 LOG(LOG_LEVEL_INFO, "[v1c_mng:%d] connection denied: %s", __LINE__, s->errstr);
421422 return SCP_CLIENT_STATE_CONNECTION_DENIED;
422423 }
423424
424 log_message(LOG_LEVEL_WARNING, "[v1c-mng:%d] connection aborted: sequence error", __LINE__);
425 LOG(LOG_LEVEL_WARNING, "[v1c-mng:%d] connection aborted: sequence error", __LINE__);
425426 return SCP_CLIENT_STATE_SEQUENCE_ERR;
426427 }
3131 #define LIBSCP_V1S_C
3232
3333 #include "libscp_v1s.h"
34 #include "string_calls.h"
3435
3536 //extern struct log_config* s_log;
3637
38 /**
39 * Reads a uint8 followed by a string into a buffer
40 *
41 * Buffer is null-terminated on success
42 *
43 * @param s Input stream
44 * @param [out] Output buffer (must be >= 256 chars)
45 * @param param Parameter we're reading
46 * @param line Line number reference
47 * @return != 0 if string read OK
48 *
49 * @todo
50 * This needs to be merged with the func of the same name in
51 * libscp_v1s_mng.c
52 */
53 static
54 int in_string8(struct stream *s, char str[], const char *param, int line)
55 {
56 int result;
57
58 if (!s_check_rem(s, 1))
59 {
60 LOG(LOG_LEVEL_WARNING,
61 "[v1s:%d] connection aborted: %s len missing",
62 line, param);
63 result = 0;
64 }
65 else
66 {
67 unsigned int sz;
68
69 in_uint8(s, sz);
70 result = s_check_rem(s, sz);
71 if (!result)
72 {
73 LOG(LOG_LEVEL_WARNING,
74 "[v1s:%d] connection aborted: %s data missing",
75 line, param);
76 }
77 else
78 {
79 in_uint8a(s, str, sz);
80 str[sz] = '\0';
81 }
82 }
83 return result;
84 }
3785 /* server API */
38 enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk)
39 {
40 struct SCP_SESSION *session;
41 tui32 version;
42 tui32 size;
43 tui16 cmdset;
44 tui16 cmd;
86
87 /**
88 * Initialises a V1 session object
89 *
90 * This is called after the V1 header, command set and command have been read
91 *
92 * @param c Connection
93 * @param [out] session pre-allocated session object
94 * @return SCP_SERVER_STATE_OK for success
95 */
96 static enum SCP_SERVER_STATES_E
97 scp_v1s_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
98 {
99 tui8 type;
100 tui16 height;
101 tui16 width;
102 tui8 bpp;
45103 tui8 sz;
46 char buf[257];
47
48 if (!skipVchk)
49 {
50
51 if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
52 {
53 in_uint32_be(c->in_s, version);
54
55 if (version != 1)
56 {
57 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
58 return SCP_SERVER_STATE_VERSION_ERR;
59 }
60 }
61 else
62 {
63 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
64 return SCP_SERVER_STATE_NETWORK_ERR;
65 }
66 }
67
68 in_uint32_be(c->in_s, size);
69
70 if (size < 12)
71 {
72 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
73 return SCP_SERVER_STATE_SIZE_ERR;
74 }
75
76 init_stream(c->in_s, c->in_s->size);
77
78 if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size - 8)))
79 {
80 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
81 return SCP_SERVER_STATE_NETWORK_ERR;
82 }
83
84 /* reading command set */
85 in_uint16_be(c->in_s, cmdset);
86
87 /* if we are starting a management session */
88 if (cmdset == SCP_COMMAND_SET_MANAGE)
89 {
90 log_message(LOG_LEVEL_DEBUG, "[v1s:%d] requested management connection", __LINE__);
91 /* should return SCP_SERVER_STATE_START_MANAGE */
92 return scp_v1s_mng_accept(c, s);
93 }
94
95 /* if we started with resource sharing... */
96 if (cmdset == SCP_COMMAND_SET_RSR)
97 {
98 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
99 return SCP_SERVER_STATE_SEQUENCE_ERR;
100 }
101
102 /* reading command */
103 in_uint16_be(c->in_s, cmd);
104
105 if (cmd != 1)
106 {
107 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
108 return SCP_SERVER_STATE_SEQUENCE_ERR;
109 }
110
111 session = scp_session_create();
112
113 if (0 == session)
114 {
115 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (malloc returned NULL)", __LINE__);
116 return SCP_SERVER_STATE_INTERNAL_ERR;
117 }
104 char buf[256];
118105
119106 scp_session_set_version(session, 1);
120107
121 in_uint8(c->in_s, sz);
122
123 if ((sz != SCP_SESSION_TYPE_XVNC) && (sz != SCP_SESSION_TYPE_XRDP))
124 {
125 scp_session_destroy(session);
126 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: unknown session type", __LINE__);
108 /* Check there's data for the session type, the height, the width, the
109 * bpp, the resource sharing indicator and the locale */
110 if (!s_check_rem(c->in_s, 1 + 2 + 2 + 1 + 1 + 17))
111 {
112 LOG(LOG_LEVEL_WARNING,
113 "[v1s:%d] connection aborted: short packet",
114 __LINE__);
115 return SCP_SERVER_STATE_SIZE_ERR;
116 }
117
118 in_uint8(c->in_s, type);
119
120 if ((type != SCP_SESSION_TYPE_XVNC) && (type != SCP_SESSION_TYPE_XRDP))
121 {
122 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: unknown session type", __LINE__);
127123 return SCP_SERVER_STATE_SESSION_TYPE_ERR;
128124 }
129125
130 scp_session_set_type(session, sz);
131
132 in_uint16_be(c->in_s, cmd);
133 scp_session_set_height(session, cmd);
134 in_uint16_be(c->in_s, cmd);
135 scp_session_set_width(session, cmd);
136 in_uint8(c->in_s, sz);
137 if (0 != scp_session_set_bpp(session, sz))
138 {
139 scp_session_destroy(session);
140 log_message(LOG_LEVEL_WARNING,
141 "[v1s:%d] connection aborted: unsupported bpp: %d",
142 __LINE__, sz);
126 scp_session_set_type(session, type);
127
128 in_uint16_be(c->in_s, height);
129 scp_session_set_height(session, height);
130 in_uint16_be(c->in_s, width);
131 scp_session_set_width(session, width);
132 in_uint8(c->in_s, bpp);
133 if (0 != scp_session_set_bpp(session, bpp))
134 {
135 LOG(LOG_LEVEL_WARNING,
136 "[v1s:%d] connection aborted: unsupported bpp: %d",
137 __LINE__, bpp);
143138 return SCP_SERVER_STATE_INTERNAL_ERR;
144139 }
145140 in_uint8(c->in_s, sz);
148143 buf[17] = '\0';
149144 scp_session_set_locale(session, buf);
150145
146 /* Check there's enough data left for at least an IPv4 address (+len) */
147 if (!s_check_rem(c->in_s, 1 + 4))
148 {
149 LOG(LOG_LEVEL_WARNING,
150 "[v1s:%d] connection aborted: IP addr len missing",
151 __LINE__);
152 return SCP_SERVER_STATE_SIZE_ERR;
153 }
154
151155 in_uint8(c->in_s, sz);
152156
153157 if (sz == SCP_ADDRESS_TYPE_IPV4)
154158 {
155 in_uint32_be(c->in_s, size);
156 scp_session_set_addr(session, sz, &size);
159 tui32 ipv4;
160 in_uint32_be(c->in_s, ipv4);
161 scp_session_set_addr(session, sz, &ipv4);
157162 }
158163 else if (sz == SCP_ADDRESS_TYPE_IPV6)
159164 {
165 if (!s_check_rem(c->in_s, 16))
166 {
167 LOG(LOG_LEVEL_WARNING,
168 "[v1s:%d] connection aborted: IP addr missing",
169 __LINE__);
170 return SCP_SERVER_STATE_SIZE_ERR;
171 }
160172 in_uint8a(c->in_s, buf, 16);
161173 scp_session_set_addr(session, sz, buf);
162174 }
163175
164 buf[256] = '\0';
165176 /* reading hostname */
166 in_uint8(c->in_s, sz);
167 buf[sz] = '\0';
168 in_uint8a(c->in_s, buf, sz);
177 if (!in_string8(c->in_s, buf, "hostname", __LINE__))
178 {
179 return SCP_SERVER_STATE_SIZE_ERR;
180 }
169181
170182 if (0 != scp_session_set_hostname(session, buf))
171183 {
172 scp_session_destroy(session);
173 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
184 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
174185 return SCP_SERVER_STATE_INTERNAL_ERR;
175186 }
176187
177188 /* reading username */
178 in_uint8(c->in_s, sz);
179 buf[sz] = '\0';
180 in_uint8a(c->in_s, buf, sz);
189 if (!in_string8(c->in_s, buf, "username", __LINE__))
190 {
191 return SCP_SERVER_STATE_SIZE_ERR;
192 }
181193
182194 if (0 != scp_session_set_username(session, buf))
183195 {
184 scp_session_destroy(session);
185 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
196 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
186197 return SCP_SERVER_STATE_INTERNAL_ERR;
187198 }
188199
189200 /* reading password */
190 in_uint8(c->in_s, sz);
191 buf[sz] = '\0';
192 in_uint8a(c->in_s, buf, sz);
201 if (!in_string8(c->in_s, buf, "passwd", __LINE__))
202 {
203 return SCP_SERVER_STATE_SIZE_ERR;
204 }
193205
194206 if (0 != scp_session_set_password(session, buf))
195207 {
196 scp_session_destroy(session);
197 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
208 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
198209 return SCP_SERVER_STATE_INTERNAL_ERR;
210 }
211
212 return SCP_SERVER_STATE_OK;
213 }
214
215 /* server API */
216 enum SCP_SERVER_STATES_E scp_v1s_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s, int skipVchk)
217 {
218 enum SCP_SERVER_STATES_E result;
219 struct SCP_SESSION *session;
220 tui32 version;
221 int size;
222 tui16 cmdset;
223 tui16 cmd;
224
225 (*s) = NULL;
226
227 if (!skipVchk)
228 {
229
230 if (0 == scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
231 {
232 in_uint32_be(c->in_s, version);
233
234 if (version != 1)
235 {
236 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
237 return SCP_SERVER_STATE_VERSION_ERR;
238 }
239 }
240 else
241 {
242 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
243 return SCP_SERVER_STATE_NETWORK_ERR;
244 }
245 }
246
247 in_uint32_be(c->in_s, size);
248
249 /* Check the message is big enough for the header, the command set, and
250 * the command (but not too big) */
251 if (size < (8 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE)
252 {
253 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
254 return SCP_SERVER_STATE_SIZE_ERR;
255 }
256
257 init_stream(c->in_s, size - 8);
258
259 if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size - 8)))
260 {
261 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
262 return SCP_SERVER_STATE_NETWORK_ERR;
263 }
264
265 c->in_s->end = c->in_s->data + (size - 8);
266
267 /* reading command set */
268 in_uint16_be(c->in_s, cmdset);
269
270 /* if we are starting a management session */
271 if (cmdset == SCP_COMMAND_SET_MANAGE)
272 {
273 LOG(LOG_LEVEL_DEBUG, "[v1s:%d] requested management connection", __LINE__);
274 /* should return SCP_SERVER_STATE_START_MANAGE */
275 return scp_v1s_mng_accept(c, s);
276 }
277
278 /* if we started with resource sharing... */
279 if (cmdset == SCP_COMMAND_SET_RSR)
280 {
281 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
282 return SCP_SERVER_STATE_SEQUENCE_ERR;
283 }
284
285 /* reading command */
286 in_uint16_be(c->in_s, cmd);
287
288 if (cmd != 1)
289 {
290 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
291 return SCP_SERVER_STATE_SEQUENCE_ERR;
292 }
293
294 session = scp_session_create();
295
296 if (NULL == session)
297 {
298 LOG(LOG_LEVEL_WARNING,
299 "[v1s:%d] connection aborted: internal error "
300 "(malloc returned NULL)", __LINE__);
301 result = SCP_SERVER_STATE_INTERNAL_ERR;
302 }
303 else
304 {
305 result = scp_v1s_init_session(c, session);
306 if (result != SCP_SERVER_STATE_OK)
307 {
308 scp_session_destroy(session);
309 session = NULL;
310 }
199311 }
200312
201313 /* returning the struct */
202314 (*s) = session;
203315
204 return SCP_SERVER_STATE_OK;
316 return result;
205317 }
206318
207319 enum SCP_SERVER_STATES_E
230342
231343 if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, rlen + 14))
232344 {
233 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
345 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
234346 return SCP_SERVER_STATE_NETWORK_ERR;
235347 }
236348
241353 scp_v1s_request_password(struct SCP_CONNECTION *c, struct SCP_SESSION *s,
242354 const char *reason)
243355 {
244 tui8 sz;
245356 tui32 version;
246 tui32 size;
357 int size;
247358 tui16 cmdset;
248359 tui16 cmd;
249360 int rlen;
250 char buf[257];
361 char buf[256];
251362
252363 init_stream(c->in_s, c->in_s->size);
253364 init_stream(c->out_s, c->out_s->size);
274385
275386 if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, 14 + rlen))
276387 {
277 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
388 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
278389 return SCP_SERVER_STATE_NETWORK_ERR;
279390 }
280391
281392 /* receive password & username */
282393 if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
283394 {
284 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
395 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
285396 return SCP_SERVER_STATE_NETWORK_ERR;
286397 }
287398
289400
290401 if (version != 1)
291402 {
292 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
403 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
293404 return SCP_SERVER_STATE_VERSION_ERR;
294405 }
295406
296407 in_uint32_be(c->in_s, size);
297408
298 if (size < 12)
299 {
300 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
301 return SCP_SERVER_STATE_SIZE_ERR;
302 }
303
304 init_stream(c->in_s, c->in_s->size);
409 /* Check the message is big enough for the header, the command set, and
410 * the command (but not too big) */
411 if (size < (8 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE)
412 {
413 LOG(LOG_LEVEL_WARNING,
414 "[v1s:%d] connection aborted: size error",
415 __LINE__);
416 return SCP_SERVER_STATE_SIZE_ERR;
417 }
418
419 init_stream(c->in_s, size - 8);
305420
306421 if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size - 8)))
307422 {
308 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
309 return SCP_SERVER_STATE_NETWORK_ERR;
310 }
423 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
424 return SCP_SERVER_STATE_NETWORK_ERR;
425 }
426
427 c->in_s->end = c->in_s->data + (size - 8);
311428
312429 in_uint16_be(c->in_s, cmdset);
313430
314431 if (cmdset != SCP_COMMAND_SET_DEFAULT)
315432 {
316 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
433 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
317434 return SCP_SERVER_STATE_SEQUENCE_ERR;
318435 }
319436
321438
322439 if (cmd != 4)
323440 {
324 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
441 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
325442 return SCP_SERVER_STATE_SEQUENCE_ERR;
326443 }
327444
328 buf[256] = '\0';
329445 /* reading username */
330 in_uint8(c->in_s, sz);
331 buf[sz] = '\0';
332 in_uint8a(c->in_s, buf, sz);
446 if (!in_string8(c->in_s, buf, "username", __LINE__))
447 {
448 return SCP_SERVER_STATE_SIZE_ERR;
449 }
333450
334451 if (0 != scp_session_set_username(s, buf))
335452 {
336 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
453 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
337454 return SCP_SERVER_STATE_INTERNAL_ERR;
338455 }
339456
340457 /* reading password */
341 in_uint8(c->in_s, sz);
342 buf[sz] = '\0';
343 in_uint8a(c->in_s, buf, sz);
458 if (!in_string8(c->in_s, buf, "passwd", __LINE__))
459 {
460 return SCP_SERVER_STATE_SIZE_ERR;
461 }
344462
345463 if (0 != scp_session_set_password(s, buf))
346464 {
347 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
465 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error", __LINE__);
348466 return SCP_SERVER_STATE_INTERNAL_ERR;
349467 }
350468
385503
386504 if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, 14))
387505 {
388 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
506 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
389507 return SCP_SERVER_STATE_NETWORK_ERR;
390508 }
391509
421539 scp_v1s_list_sessions(struct SCP_CONNECTION *c, int sescnt, struct SCP_DISCONNECTED_SESSION *ds, SCP_SID *sid)
422540 {
423541 tui32 version = 1;
424 tui32 size = 12;
542 int size = 12;
425543 tui16 cmd = 40;
426544 int pktcnt;
427545 int idx;
439557
440558 if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
441559 {
442 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
560 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
443561 return SCP_SERVER_STATE_NETWORK_ERR;
444562 }
445563
453571
454572 if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
455573 {
456 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
574 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
457575 return SCP_SERVER_STATE_NETWORK_ERR;
458576 }
459577
461579
462580 if (version != 1)
463581 {
464 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
582 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
465583 return SCP_SERVER_STATE_VERSION_ERR;
466584 }
467585
468586 in_uint32_be(c->in_s, size);
469587
470 if (size < 12)
471 {
472 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
473 return SCP_SERVER_STATE_SIZE_ERR;
474 }
475
476 init_stream(c->in_s, c->in_s->size);
588 /* Check the message is big enough for the header, the command set, and
589 * the command (but not too big) */
590 if (size < (8 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE)
591 {
592 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
593 return SCP_SERVER_STATE_SIZE_ERR;
594 }
595
596 init_stream(c->in_s, size - 8);
477597
478598 if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size - 8)))
479599 {
480 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
481 return SCP_SERVER_STATE_NETWORK_ERR;
482 }
600 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
601 return SCP_SERVER_STATE_NETWORK_ERR;
602 }
603
604 c->in_s->end = c->in_s->data + (size - 8);
483605
484606 in_uint16_be(c->in_s, cmd);
485607
486608 if (cmd != SCP_COMMAND_SET_DEFAULT)
487609 {
488 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
610 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
489611 return SCP_SERVER_STATE_SEQUENCE_ERR;
490612 }
491613
493615
494616 if (cmd != 41)
495617 {
496 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
618 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
497619 return SCP_SERVER_STATE_SEQUENCE_ERR;
498620 }
499621
581703
582704 if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
583705 {
584 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
706 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
585707 return SCP_SERVER_STATE_NETWORK_ERR;
586708 }
587709 }
591713
592714 if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (8)))
593715 {
594 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
716 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
595717 return SCP_SERVER_STATE_NETWORK_ERR;
596718 }
597719
599721
600722 if (version != 1)
601723 {
602 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
724 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: version error", __LINE__);
603725 return SCP_SERVER_STATE_VERSION_ERR;
604726 }
605727
606728 in_uint32_be(c->in_s, size);
607729
608 if (size < 12)
609 {
610 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
730 /* Check the message is big enough for the header, the command set, and
731 * the command (but not too big) */
732 if (size < (8 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE)
733 {
734 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: size error", __LINE__);
611735 return SCP_SERVER_STATE_SIZE_ERR;
612736 }
613737
614738 /* rest of the packet */
615 init_stream(c->in_s, c->in_s->size);
739 init_stream(c->in_s, size - 8);
616740
617741 if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, (size - 8)))
618742 {
619 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
620 return SCP_SERVER_STATE_NETWORK_ERR;
621 }
743 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
744 return SCP_SERVER_STATE_NETWORK_ERR;
745 }
746
747 c->in_s->end = c->in_s->data + (size - 8);
622748
623749 in_uint16_be(c->in_s, cmd);
624750
625751 if (cmd != SCP_COMMAND_SET_DEFAULT)
626752 {
627 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
753 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
628754 return SCP_SERVER_STATE_SEQUENCE_ERR;
629755 }
630756
632758
633759 if (cmd == 43)
634760 {
761 if (!s_check_rem(c->in_s, 4))
762 {
763 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: missing session", __LINE__);
764 return SCP_SERVER_STATE_SIZE_ERR;
765 }
635766 /* select session */
636767 in_uint32_be(c->in_s, (*sid));
637768
648779
649780 /* if we got here, the requested sid wasn't one from the list we sent */
650781 /* we should kill the connection */
651 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (no such session in list)", __LINE__);
782 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: internal error (no such session in list)", __LINE__);
652783 return SCP_SERVER_STATE_INTERNAL_ERR;
653784 }
654785 else if (cmd == 44)
664795 else
665796 {
666797 /* wrong response */
667 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
798 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: sequence error", __LINE__);
668799 return SCP_SERVER_STATE_SEQUENCE_ERR;
669800 }
670801
701832
702833 if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
703834 {
704 log_message(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
835 LOG(LOG_LEVEL_WARNING, "[v1s:%d] connection aborted: network error", __LINE__);
705836 return SCP_SERVER_STATE_NETWORK_ERR;
706837 }
707838
3131 #define LIBSCP_V1S_MNG_C
3232
3333 #include "libscp_v1s_mng.h"
34 #include "string_calls.h"
3435
3536 //extern struct log_config* s_log;
3637
3738 static enum SCP_SERVER_STATES_E
3839 _scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s);
3940
40 /* server API */
41 enum SCP_SERVER_STATES_E
42 scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s)
43 {
44 struct SCP_SESSION *session;
41 /**
42 * Reads a uint8 followed by a string into a buffer
43 *
44 * Buffer is null-terminated on success
45 *
46 * @param s Input stream
47 * @param [out] Output buffer (must be >= 256 chars)
48 * @param param Parameter we're reading
49 * @param line Line number reference
50 * @return != 0 if string read OK
51 *
52 * @todo
53 * This needs to be merged with the func of the same name in
54 * libscp_v1s.c
55 */
56 static
57 int in_string8(struct stream *s, char str[], const char *param, int line)
58 {
59 int result;
60
61 if (!s_check_rem(s, 1))
62 {
63 LOG(LOG_LEVEL_WARNING,
64 "[v1s_mng:%d] connection aborted: %s len missing",
65 line, param);
66 result = 0;
67 }
68 else
69 {
70 unsigned int sz;
71
72 in_uint8(s, sz);
73 result = s_check_rem(s, sz);
74 if (!result)
75 {
76 LOG(LOG_LEVEL_WARNING,
77 "[v1s_mng:%d] connection aborted: %s data missing",
78 line, param);
79 }
80 else
81 {
82 in_uint8a(s, str, sz);
83 str[sz] = '\0';
84 }
85 }
86 return result;
87 }
88 /**
89 * Initialises a V1 management session object
90 *
91 * At call time, the command set value has been read from the wire, and
92 * the command still needs to be processed.
93 *
94 * @param c Connection
95 * @param [out] session pre-allocated session object
96 * @return SCP_SERVER_STATE_START_MANAGE for success
97 */
98 static enum SCP_SERVER_STATES_E
99 scp_v1s_mng_init_session(struct SCP_CONNECTION *c, struct SCP_SESSION *session)
100 {
45101 tui32 ipaddr;
46102 tui16 cmd;
47103 tui8 sz;
48 char buf[257];
104 char buf[256];
105
106 scp_session_set_version(session, 1);
49107
50108 /* reading command */
109 if (!s_check_rem(c->in_s, 2))
110 {
111 /* Caller should have checked this */
112 return SCP_SERVER_STATE_SIZE_ERR;
113 }
51114 in_uint16_be(c->in_s, cmd);
52115
53116 if (cmd != 1) /* manager login */
55118 return SCP_SERVER_STATE_SEQUENCE_ERR;
56119 }
57120
58 session = scp_session_create();
59
60 if (0 == session)
121 /* reading username */
122 if (!in_string8(c->in_s, buf, "username", __LINE__))
123 {
124 return SCP_SERVER_STATE_SIZE_ERR;
125 }
126
127 if (0 != scp_session_set_username(session, buf))
61128 {
62129 return SCP_SERVER_STATE_INTERNAL_ERR;
63130 }
64131
65 scp_session_set_version(session, 1);
66 scp_session_set_type(session, SCP_SESSION_TYPE_MANAGE);
67
68 /* reading username */
132 /* reading password */
133 if (!in_string8(c->in_s, buf, "passwd", __LINE__))
134 {
135 return SCP_SERVER_STATE_SIZE_ERR;
136 }
137
138 if (0 != scp_session_set_password(session, buf))
139 {
140 return SCP_SERVER_STATE_INTERNAL_ERR;
141 }
142
143 /* reading remote address
144 * Check there's enough data left for at least an IPv4 address (+len) */
145 if (!s_check_rem(c->in_s, 1 + 4))
146 {
147 LOG(LOG_LEVEL_WARNING,
148 "[v1s_mng:%d] connection aborted: IP addr len missing",
149 __LINE__);
150 return SCP_SERVER_STATE_SIZE_ERR;
151 }
152
69153 in_uint8(c->in_s, sz);
70 buf[sz] = '\0';
71 in_uint8a(c->in_s, buf, sz);
72
73 if (0 != scp_session_set_username(session, buf))
74 {
75 scp_session_destroy(session);
76 return SCP_SERVER_STATE_INTERNAL_ERR;
77 }
78
79 /* reading password */
80 in_uint8(c->in_s, sz);
81 buf[sz] = '\0';
82 in_uint8a(c->in_s, buf, sz);
83
84 if (0 != scp_session_set_password(session, buf))
85 {
86 scp_session_destroy(session);
87 return SCP_SERVER_STATE_INTERNAL_ERR;
88 }
89
90 /* reading remote address */
91 in_uint8(c->in_s, sz);
92
93154 if (sz == SCP_ADDRESS_TYPE_IPV4)
94155 {
95156 in_uint32_be(c->in_s, ipaddr);
97158 }
98159 else if (sz == SCP_ADDRESS_TYPE_IPV6)
99160 {
161 if (!s_check_rem(c->in_s, 16))
162 {
163 LOG(LOG_LEVEL_WARNING,
164 "[v1s_mng:%d] connection aborted: IP addr missing",
165 __LINE__);
166 return SCP_SERVER_STATE_SIZE_ERR;
167 }
100168 in_uint8a(c->in_s, buf, 16);
101169 scp_session_set_addr(session, sz, buf);
102170 }
103171
104172 /* reading hostname */
105 in_uint8(c->in_s, sz);
106 buf[sz] = '\0';
107 in_uint8a(c->in_s, buf, sz);
173 if (!in_string8(c->in_s, buf, "hostname", __LINE__))
174 {
175 return SCP_SERVER_STATE_SIZE_ERR;
176 }
108177
109178 if (0 != scp_session_set_hostname(session, buf))
110179 {
111 scp_session_destroy(session);
112180 return SCP_SERVER_STATE_INTERNAL_ERR;
113181 }
114182
115 /* returning the struct */
183 return SCP_SERVER_STATE_START_MANAGE;
184 }
185
186 enum SCP_SERVER_STATES_E
187 scp_v1s_mng_accept(struct SCP_CONNECTION *c, struct SCP_SESSION **s)
188 {
189 enum SCP_SERVER_STATES_E result;
190 struct SCP_SESSION *session;
191
192 session = scp_session_create();
193 if (NULL == session)
194 {
195 result = SCP_SERVER_STATE_INTERNAL_ERR;
196 }
197 else
198 {
199 scp_session_set_type(session, SCP_SESSION_TYPE_MANAGE);
200
201 result = scp_v1s_mng_init_session(c, session);
202 if (result != SCP_SERVER_STATE_START_MANAGE)
203 {
204 scp_session_destroy(session);
205 session = NULL;
206 }
207 }
208
116209 (*s) = session;
117210
118 return SCP_SERVER_STATE_START_MANAGE;
211 return result;
119212 }
120213
121214 /* 002 */
189282 /* calculating the number of packets to send */
190283 if (sescnt == 0)
191284 {
192 pktcnt = 1;
285 pktcnt = 1;
193286 }
194287 else
195288 {
196 pktcnt = sescnt / SCP_SERVER_MAX_LIST_SIZE;
197
198 if ((sescnt % SCP_SERVER_MAX_LIST_SIZE) != 0)
199 {
200 pktcnt++;
201 }
289 pktcnt = sescnt / SCP_SERVER_MAX_LIST_SIZE;
290
291 if ((sescnt % SCP_SERVER_MAX_LIST_SIZE) != 0)
292 {
293 pktcnt++;
294 }
202295 }
203296
204297 for (idx = 0; idx < pktcnt; idx++)
276369
277370 if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, size))
278371 {
279 log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
372 LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
280373 return SCP_SERVER_STATE_NETWORK_ERR;
281374 }
282375 }
288381 _scp_v1s_mng_check_response(struct SCP_CONNECTION *c, struct SCP_SESSION *s)
289382 {
290383 tui32 version;
291 tui32 size;
384 int size;
292385 tui16 cmd;
293386 // tui8 dim;
294387 // char buf[257];
297390
298391 if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8))
299392 {
300 log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
393 LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
301394 return SCP_SERVER_STATE_NETWORK_ERR;
302395 }
303396
305398
306399 if (version != 1)
307400 {
308 log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: version error", __LINE__);
401 LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: version error", __LINE__);
309402 return SCP_SERVER_STATE_VERSION_ERR;
310403 }
311404
312405 in_uint32_be(c->in_s, size);
313406
314 init_stream(c->in_s, c->in_s->size);
407 /* Check the message is big enough for the header, the command set, and
408 * the command (but not too big) */
409 if (size < (8 + 2 + 2) || size > SCP_MAX_MESSAGE_SIZE)
410 {
411 LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: size error", __LINE__);
412 return SCP_SERVER_STATE_SIZE_ERR;
413 }
414
415 init_stream(c->in_s, size - 8);
315416
316417 /* read the rest of the packet */
317418 if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8))
318419 {
319 log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
420 LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: network error", __LINE__);
320421 return SCP_SERVER_STATE_NETWORK_ERR;
321422 }
322423
424 c->in_s->end = c->in_s->data + (size - 8);
425
323426 in_uint16_be(c->in_s, cmd);
324427
325428 if (cmd != SCP_COMMAND_SET_MANAGE)
326429 {
327 log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__);
430 LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__);
328431 return SCP_SERVER_STATE_SEQUENCE_ERR;
329432 }
330433
332435
333436 if (cmd == SCP_CMD_MNG_LIST_REQ) /* request session list */
334437 {
335 log_message(LOG_LEVEL_INFO, "[v1s_mng:%d] request session list", __LINE__);
438 LOG(LOG_LEVEL_INFO, "[v1s_mng:%d] request session list", __LINE__);
336439 return SCP_SERVER_STATE_MNG_LISTREQ;
337440 }
338441 else if (cmd == SCP_CMD_MNG_ACTION) /* execute an action */
342445 in_uint8a(c->in_s, buf, dim);
343446 scp_session_set_errstr(s, buf);*/
344447
345 log_message(LOG_LEVEL_INFO, "[v1s_mng:%d] action request", __LINE__);
448 LOG(LOG_LEVEL_INFO, "[v1s_mng:%d] action request", __LINE__);
346449 return SCP_SERVER_STATE_MNG_ACTION;
347450 }
348451
357460 return SCP_SERVER_STATE_SESSION_LIST;
358461 }*/
359462
360 log_message(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__);
463 LOG(LOG_LEVEL_WARNING, "[v1s_mng:%d] connection aborted: sequence error", __LINE__);
361464 return SCP_SERVER_STATE_SEQUENCE_ERR;
362465 }
363466
4242 struct SCP_SESSION *sdata = NULL;
4343
4444 scon.in_sck = (int)(tintptr)sck;
45 LOG_DBG("started scp thread on socket %d", scon.in_sck);
45 LOG_DEVEL(LOG_LEVEL_DEBUG, "started scp thread on socket %d", scon.in_sck);
4646
4747 make_stream(scon.in_s);
4848 make_stream(scon.out_s);
4949
50 init_stream(scon.in_s, 8192);
51 init_stream(scon.out_s, 8192);
50 init_stream(scon.in_s, SCP_MAX_MESSAGE_SIZE);
51 init_stream(scon.out_s, SCP_MAX_MESSAGE_SIZE);
5252
5353 switch (scp_vXs_accept(&scon, &(sdata)))
5454 {
5757 if (sdata->version == 0)
5858 {
5959 /* starts processing an scp v0 connection */
60 LOG_DBG("accept ok, go on with scp v0");
60 LOG_DEVEL(LOG_LEVEL_DEBUG, "accept ok, go on with scp v0");
6161 scp_v0_process(&scon, sdata);
6262 }
6363 else
6464 {
65 LOG_DBG("accept ok, go on with scp v1");
66 /*LOG_DBG("user: %s\npass: %s",sdata->username, sdata->password);*/
65 LOG_DEVEL(LOG_LEVEL_DEBUG, "accept ok, go on with scp v1");
66 /*LOG_DEVEL(LOG_LEVEL_DEBUG, "user: %s\npass: %s",sdata->username, sdata->password);*/
6767 scp_v1_process(&scon, sdata);
6868 }
6969
7070 break;
7171 case SCP_SERVER_STATE_START_MANAGE:
7272 /* starting a management session */
73 log_message(LOG_LEVEL_WARNING,
74 "starting a sesman management session...");
73 LOG(LOG_LEVEL_WARNING,
74 "starting a sesman management session...");
7575 scp_v1_mng_process(&scon, sdata);
7676 break;
7777 case SCP_SERVER_STATE_VERSION_ERR:
78 /* an unknown scp version was requested, so we shut down the */
79 /* connection (and log the fact) */
80 log_message(LOG_LEVEL_WARNING,
81 "unknown protocol version specified. connection refused.");
78 case SCP_SERVER_STATE_SIZE_ERR:
79 /* an unknown scp version was requested, or the message sizes
80 are inconsistent. Shut down the connection and log the
81 fact */
82 LOG(LOG_LEVEL_WARNING,
83 "protocol violation. connection refused.");
8284 break;
8385 case SCP_SERVER_STATE_NETWORK_ERR:
84 log_message(LOG_LEVEL_WARNING, "libscp network error.");
86 LOG(LOG_LEVEL_WARNING, "libscp network error.");
8587 break;
8688 case SCP_SERVER_STATE_SEQUENCE_ERR:
87 log_message(LOG_LEVEL_WARNING, "libscp sequence error.");
89 LOG(LOG_LEVEL_WARNING, "libscp sequence error.");
8890 break;
8991 case SCP_SERVER_STATE_INTERNAL_ERR:
9092 /* internal error occurred (eg. malloc() error, ecc.) */
91 log_message(LOG_LEVEL_ERROR, "libscp internal error occurred.");
93 LOG(LOG_LEVEL_ERROR, "libscp internal error occurred.");
9294 break;
9395 default:
94 log_message(LOG_LEVEL_ALWAYS, "unknown return from scp_vXs_accept()");
96 LOG(LOG_LEVEL_ALWAYS, "unknown return from scp_vXs_accept()");
9597 break;
9698 }
9799
5353 {
5454 /* the user is member of the correct groups. */
5555 scp_v0s_replyauthentication(c, errorcode);
56 log_message(LOG_LEVEL_INFO, "Access permitted for user: %s",
57 s->username);
56 LOG(LOG_LEVEL_INFO, "Access permitted for user: %s",
57 s->username);
5858 /* g_writeln("Connection allowed"); */
5959 }
6060 else
6161 {
6262 scp_v0s_replyauthentication(c, 32 + 3); /* all first 32 are reserved for PAM errors */
63 log_message(LOG_LEVEL_INFO, "Username okey but group problem for "
64 "user: %s", s->username);
63 LOG(LOG_LEVEL_INFO, "Username okey but group problem for "
64 "user: %s", s->username);
6565 /* g_writeln("user password ok, but group problem"); */
6666 }
6767 }
6868 else
6969 {
7070 /* g_writeln("username or password error"); */
71 log_message(LOG_LEVEL_INFO, "Username or password error for user: %s",
72 s->username);
71 LOG(LOG_LEVEL_INFO, "Username or password error for user: %s",
72 s->username);
7373 scp_v0s_replyauthentication(c, errorcode);
7474 }
7575 }
8484 g_memcpy(s->guid, s_item->guid, 16);
8585 if (0 != s->client_ip)
8686 {
87 log_message( LOG_LEVEL_INFO, "++ reconnected session: username %s, "
88 "display :%d.0, session_pid %d, ip %s",
89 s->username, display, s_item->pid, s->client_ip);
87 LOG( LOG_LEVEL_INFO, "++ reconnected session: username %s, "
88 "display :%d.0, session_pid %d, ip %s",
89 s->username, display, s_item->pid, s->client_ip);
9090 }
9191 else
9292 {
93 log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, "
94 "display :%d.0, session_pid %d", s->username, display,
95 s_item->pid);
93 LOG(LOG_LEVEL_INFO, "++ reconnected session: username %s, "
94 "display :%d.0, session_pid %d", s->username, display,
95 s_item->pid);
9696 }
9797
9898 session_reconnect(display, s->username, data);
9999 }
100100 else
101101 {
102 LOG_DBG("pre auth");
102 LOG_DEVEL(LOG_LEVEL_DEBUG, "pre auth");
103103
104104 if (1 == access_login_allowed(s->username))
105105 {
106106 tui8 guid[16];
107107
108 g_random((char*)guid, 16);
108 g_random((char *)guid, 16);
109109 scp_session_set_guid(s, guid);
110110
111111 if (0 != s->client_ip)
112112 {
113 log_message(LOG_LEVEL_INFO, "++ created session (access granted): "
114 "username %s, ip %s", s->username, s->client_ip);
113 LOG(LOG_LEVEL_INFO, "++ created session (access granted): "
114 "username %s, ip %s", s->username, s->client_ip);
115115 }
116116 else
117117 {
118 log_message(LOG_LEVEL_INFO, "++ created session (access granted): "
119 "username %s", s->username);
118 LOG(LOG_LEVEL_INFO, "++ created session (access granted): "
119 "username %s", s->username);
120120 }
121121
122122 if (SCP_SESSION_TYPE_XVNC == s->type)
123123 {
124 log_message( LOG_LEVEL_INFO, "starting Xvnc session...");
124 LOG( LOG_LEVEL_INFO, "starting Xvnc session...");
125125 display = session_start(data, SESMAN_SESSION_TYPE_XVNC, c, s);
126126 }
127127 else if (SCP_SESSION_TYPE_XRDP == s->type)
128128 {
129 log_message(LOG_LEVEL_INFO, "starting X11rdp session...");
129 LOG(LOG_LEVEL_INFO, "starting X11rdp session...");
130130 display = session_start(data, SESMAN_SESSION_TYPE_XRDP, c, s);
131131 }
132132 else if (SCP_SESSION_TYPE_XORG == s->type)
133133 {
134134 /* type is SCP_SESSION_TYPE_XORG */
135 log_message(LOG_LEVEL_INFO, "starting Xorg session...");
135 LOG(LOG_LEVEL_INFO, "starting Xorg session...");
136136 display = session_start(data, SESMAN_SESSION_TYPE_XORG, c, s);
137137 }
138138 /* if the session started up ok, auth_end will be called on
5454 retries = g_cfg->sec.login_retry;
5555 current_try = retries;
5656
57 data = auth_userpass(s->username, s->password,NULL);
58 /*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/
57 data = auth_userpass(s->username, s->password, NULL);
58 /*LOG_DEVEL(LOG_LEVEL_DEBUG, "user: %s\npass: %s", s->username, s->password);*/
5959
6060 while ((!data) && ((retries == 0) || (current_try > 0)))
6161 {
62 LOG_DBG("data %d - retry %d - currenttry %d - expr %d",
63 data, retries, current_try,
64 ((!data) && ((retries == 0) || (current_try > 0))));
62 LOG_DEVEL(LOG_LEVEL_DEBUG, "data %ld - retry %d - currenttry %d - expr %d",
63 data, retries, current_try,
64 ((!data) && ((retries == 0) || (current_try > 0))));
6565
6666 e = scp_v1s_request_password(c, s, "Wrong username and/or password");
6767
6969 {
7070 case SCP_SERVER_STATE_OK:
7171 /* all ok, we got new username and password */
72 data = auth_userpass(s->username, s->password,NULL);
72 data = auth_userpass(s->username, s->password, NULL);
7373
7474 /* one try less */
7575 if (current_try > 0)
8989 if (!data)
9090 {
9191 scp_v1s_deny_connection(c, "Login failed");
92 log_message( LOG_LEVEL_INFO,
93 "Login failed for user %s. Connection terminated", s->username);
92 LOG( LOG_LEVEL_INFO,
93 "Login failed for user %s. Connection terminated", s->username);
9494 return;
9595 }
9696
9898 if (0 == access_login_allowed(s->username))
9999 {
100100 scp_v1s_deny_connection(c, "Access to Terminal Server not allowed.");
101 log_message(LOG_LEVEL_INFO,
102 "User %s not allowed on TS. Connection terminated", s->username);
101 LOG(LOG_LEVEL_INFO,
102 "User %s not allowed on TS. Connection terminated", s->username);
103103 return;
104104 }
105105
111111 if (scount == 0)
112112 {
113113 /* no disconnected sessions - start a new one */
114 log_message(LOG_LEVEL_DEBUG, "No disconnected sessions for this user "
115 "- we create a new one");
114 LOG(LOG_LEVEL_DEBUG, "No disconnected sessions for this user "
115 "- we create a new one");
116116
117117 if (0 != s->client_ip)
118118 {
119 log_message(LOG_LEVEL_INFO, "++ created session (access granted): username %s, ip %s", s->username, s->client_ip);
119 LOG(LOG_LEVEL_INFO, "++ created session (access granted): username %s, ip %s", s->username, s->client_ip);
120120 }
121121 else
122122 {
123 log_message(LOG_LEVEL_INFO, "++ created session (access granted): username %s", s->username);
123 LOG(LOG_LEVEL_INFO, "++ created session (access granted): username %s", s->username);
124124 }
125125
126126 if (SCP_SESSION_TYPE_XVNC == s->type)
127127 {
128 log_message(LOG_LEVEL_INFO, "starting Xvnc session...");
128 LOG(LOG_LEVEL_INFO, "starting Xvnc session...");
129129 display = session_start(data, SESMAN_SESSION_TYPE_XVNC, c, s);
130130 }
131131 else if (SCP_SESSION_TYPE_XRDP == s->type)
132132 {
133 log_message(LOG_LEVEL_INFO, "starting X11rdp session...");
133 LOG(LOG_LEVEL_INFO, "starting X11rdp session...");
134134 display = session_start(data, SESMAN_SESSION_TYPE_XRDP, c, s);
135135 }
136136 else if (SCP_SESSION_TYPE_XORG == s->type)
137137 {
138 log_message(LOG_LEVEL_INFO, "starting Xorg session...");
138 LOG(LOG_LEVEL_INFO, "starting Xorg session...");
139139 display = session_start(data, SESMAN_SESSION_TYPE_XORG, c, s);
140140 }
141141 /* if the session started up ok, auth_end will be called on
160160
161161 switch (e)
162162 {
163 /*case SCP_SERVER_STATE_FORCE_NEW:*/
164 /* we should check for MaxSessions */
163 /*case SCP_SERVER_STATE_FORCE_NEW:*/
164 /* we should check for MaxSessions */
165165 case SCP_SERVER_STATE_SELECTION_CANCEL:
166 log_message( LOG_LEVEL_INFO, "Connection cancelled after session listing");
166 LOG( LOG_LEVEL_INFO, "Connection cancelled after session listing");
167167 break;
168168 case SCP_SERVER_STATE_OK:
169169 /* ok, reconnecting... */
172172 if (0 == sitem)
173173 {
174174 e = scp_v1s_connection_error(c, "Internal error");
175 log_message(LOG_LEVEL_INFO, "Cannot find session item on the chain");
175 LOG(LOG_LEVEL_INFO, "Cannot find session item on the chain");
176176 }
177177 else
178178 {
182182
183183 if (0 != s->client_ip)
184184 {
185 log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d, ip %s", s->username, display, sitem->pid, s->client_ip);
185 LOG(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d, ip %s", s->username, display, sitem->pid, s->client_ip);
186186 }
187187 else
188188 {
189 log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d", s->username, display, sitem->pid);
189 LOG(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d", s->username, display, sitem->pid);
190190 }
191191
192192 g_free(sitem);
219219 switch (e)
220220 {
221221 case SCP_SERVER_STATE_VERSION_ERR:
222 LOG_DBG("version error")
222 LOG(LOG_LEVEL_WARNING, "version error");
223223 case SCP_SERVER_STATE_SIZE_ERR:
224224 /* an unknown scp version was requested, so we shut down the */
225225 /* connection (and log the fact) */
226 log_message(LOG_LEVEL_WARNING,
227 "protocol violation. connection closed.");
226 LOG(LOG_LEVEL_WARNING,
227 "protocol violation. connection closed.");
228228 break;
229229 case SCP_SERVER_STATE_NETWORK_ERR:
230 log_message(LOG_LEVEL_WARNING, "libscp network error.");
230 LOG(LOG_LEVEL_WARNING, "libscp network error.");
231231 break;
232232 case SCP_SERVER_STATE_SEQUENCE_ERR:
233 log_message(LOG_LEVEL_WARNING, "libscp sequence error.");
233 LOG(LOG_LEVEL_WARNING, "libscp sequence error.");
234234 break;
235235 case SCP_SERVER_STATE_INTERNAL_ERR:
236236 /* internal error occurred (eg. malloc() error, ecc.) */
237 log_message(LOG_LEVEL_ERROR, "libscp internal error occurred.");
237 LOG(LOG_LEVEL_ERROR, "libscp internal error occurred.");
238238 break;
239239 default:
240240 /* dummy: scp_v1s_request_password won't generate any other */
241241 /* error other than the ones before */
242 log_message(LOG_LEVEL_ALWAYS, "unknown return from %s", f);
242 LOG(LOG_LEVEL_ALWAYS, "unknown return from %s", f);
243243 break;
244244 }
245245 }
4545 int scount;
4646 int end = 0;
4747
48 data = auth_userpass(s->username, s->password,NULL);
49 /*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/
48 data = auth_userpass(s->username, s->password, NULL);
49 /*LOG_DEVEL(LOG_LEVEL_DEBUG, "user: %s\npass: %s", s->username, s->password);*/
5050
5151 if (!data)
5252 {
5353 scp_v1s_mng_deny_connection(c, "Login failed");
54 log_message(LOG_LEVEL_INFO,
55 "[MNG] Login failed for user %s. Connection terminated", s->username);
54 LOG(LOG_LEVEL_INFO,
55 "[MNG] Login failed for user %s. Connection terminated", s->username);
5656 auth_end(data);
5757 return;
5858 }
6161 if (0 == access_login_mng_allowed(s->username))
6262 {
6363 scp_v1s_mng_deny_connection(c, "Access to Terminal Server not allowed.");
64 log_message(LOG_LEVEL_INFO,
65 "[MNG] User %s not allowed on TS. Connection terminated", s->username);
64 LOG(LOG_LEVEL_INFO,
65 "[MNG] User %s not allowed on TS. Connection terminated", s->username);
6666 auth_end(data);
6767 return;
6868 }
7676 switch (e)
7777 {
7878 case SCP_SERVER_STATE_MNG_ACTION:
79 log_message(LOG_LEVEL_INFO, "Connection cancelled after session listing");
79 LOG(LOG_LEVEL_INFO, "Connection cancelled after session listing");
8080 break;
8181
8282 case SCP_SERVER_STATE_MNG_LISTREQ:
8383 /* list disconnected sessions */
8484 slist = session_get_byuser(NULL, &scount, SESMAN_SESSION_STATUS_ALL);
85 LOG_DBG("sessions on TS: %d (slist: %x)", scount, slist);
85 LOG_DEVEL(LOG_LEVEL_DEBUG, "sessions on TS: %d (slist: %p)", scount, slist);
8686 if (0 == slist)
8787 {
88 log_message(LOG_LEVEL_INFO, "No sessions on Terminal Server");
88 LOG(LOG_LEVEL_INFO, "No sessions on Terminal Server");
8989 }
9090
9191 e = scp_v1s_mng_list_sessions(c, s, scount, slist);
108108 switch (e)
109109 {
110110 case SCP_SERVER_STATE_VERSION_ERR:
111 LOG_DBG("version error")
111 LOG(LOG_LEVEL_WARNING, "version error");
112112 case SCP_SERVER_STATE_SIZE_ERR:
113113 /* an unknown scp version was requested, so we shut down the */
114114 /* connection (and log the fact) */
115 log_message(LOG_LEVEL_WARNING,
116 "protocol violation. connection closed.");
115 LOG(LOG_LEVEL_WARNING,
116 "protocol violation. connection closed.");
117117 break;
118118 case SCP_SERVER_STATE_NETWORK_ERR:
119 log_message(LOG_LEVEL_WARNING, "libscp network error.");
119 LOG(LOG_LEVEL_WARNING, "libscp network error.");
120120 break;
121121 case SCP_SERVER_STATE_SEQUENCE_ERR:
122 log_message(LOG_LEVEL_WARNING, "libscp sequence error.");
122 LOG(LOG_LEVEL_WARNING, "libscp sequence error.");
123123 break;
124124 case SCP_SERVER_STATE_INTERNAL_ERR:
125125 /* internal error occurred (eg. malloc() error, ecc.) */
126 log_message(LOG_LEVEL_ERROR, "libscp internal error occurred.");
126 LOG(LOG_LEVEL_ERROR, "libscp internal error occurred.");
127127 break;
128128 default:
129129 /* dummy: scp_v1s_request_password won't generate any other */
130130 /* error other than the ones before */
131 log_message(LOG_LEVEL_ALWAYS, "unknown return from %s", f);
131 LOG(LOG_LEVEL_ALWAYS, "unknown return from %s", f);
132132 break;
133133 }
134134 }
2727 #include <config_ac.h>
2828 #endif
2929
30 #include <stdarg.h>
31
3032 #include "sesman.h"
33 #include "xrdp_configure_options.h"
34 #include "string_calls.h"
35
36 struct sesman_startup_params
37 {
38 const char *sesman_ini;
39 int kill;
40 int no_daemon;
41 int help;
42 int version;
43 };
3144
3245 int g_sck;
3346 int g_pid;
3649
3750 tintptr g_term_event = 0;
3851
52 /*****************************************************************************/
53 /**
54 * @brief looks for a case-insensitive match of a string in a list
55 * @param candidate String to match
56 * @param ... NULL-terminated list of strings to compare the candidate with
57 * @return !=0 if the candidate is found in the list
58 */
59 static int nocase_matches(const char *candidate, ...)
60 {
61 va_list vl;
62 const char *member;
63 int result = 0;
64
65 va_start(vl, candidate);
66 while ((member = va_arg(vl, const char *)) != NULL)
67 {
68 if (g_strcasecmp(candidate, member) == 0)
69 {
70 result = 1;
71 break;
72 }
73 }
74
75 va_end(vl);
76 return result;
77 }
78
79 /*****************************************************************************/
80 /**
81 *
82 * @brief Command line argument parser
83 * @param[in] argc number of command line arguments
84 * @param[in] argv pointer array of commandline arguments
85 * @param[out] sesman_startup_params Returned startup parameters
86 * @return 0 on success, n on nth argument is unknown
87 *
88 */
89 static int
90 sesman_process_params(int argc, char **argv,
91 struct sesman_startup_params *startup_params)
92 {
93 int index;
94 const char *option;
95 const char *value;
96
97 index = 1;
98
99 while (index < argc)
100 {
101 option = argv[index];
102
103 if (index + 1 < argc)
104 {
105 value = argv[index + 1];
106 }
107 else
108 {
109 value = "";
110 }
111
112 if (nocase_matches(option, "-help", "--help", "-h", NULL))
113 {
114 startup_params->help = 1;
115 }
116 else if (nocase_matches(option, "-kill", "--kill", "-k", NULL))
117 {
118 startup_params->kill = 1;
119 }
120 else if (nocase_matches(option, "-nodaemon", "--nodaemon", "-n",
121 "-nd", "--nd", "-ns", "--ns", NULL))
122 {
123 startup_params->no_daemon = 1;
124 }
125 else if (nocase_matches(option, "-v", "--version", NULL))
126 {
127 startup_params->version = 1;
128 }
129 else if (nocase_matches(option, "-c", "--config", NULL))
130 {
131 index++;
132 startup_params->sesman_ini = value;
133 }
134 else /* unknown option */
135 {
136 return index;
137 }
138
139 index++;
140 }
141
142 return 0;
143 }
144
39145 /******************************************************************************/
40 int sesman_listen_test(struct config_sesman *cfg)
146 static int sesman_listen_test(struct config_sesman *cfg)
41147 {
42148 int error;
43149 int sck;
49155 return 1;
50156 }
51157
52 log_message(LOG_LEVEL_DEBUG, "Testing if xrdp-sesman can listen on %s port %s.",
53 cfg->listen_address, cfg->listen_port);
158 LOG(LOG_LEVEL_DEBUG, "Testing if xrdp-sesman can listen on %s port %s.",
159 cfg->listen_address, cfg->listen_port);
54160 g_tcp_set_non_blocking(sck);
55161 error = scp_tcp_bind(sck, cfg->listen_address, cfg->listen_port);
56162 if (error == 0)
81187 * @brief Starts sesman main loop
82188 *
83189 */
84 int
190 static int
85191 sesman_main_loop(void)
86192 {
87193 int in_sck;
95201 g_sck = g_tcp_socket();
96202 if (g_sck < 0)
97203 {
98 log_message(LOG_LEVEL_ERROR, "error opening socket, g_tcp_socket() failed...");
204 LOG(LOG_LEVEL_ERROR, "error opening socket, g_tcp_socket() failed...");
99205 return 1;
100206 }
101207
108214
109215 if (error == 0)
110216 {
111 log_message(LOG_LEVEL_INFO, "listening to port %s on %s",
112 g_cfg->listen_port, g_cfg->listen_address);
217 LOG(LOG_LEVEL_INFO, "listening to port %s on %s",
218 g_cfg->listen_port, g_cfg->listen_address);
113219 sck_obj = g_create_wait_obj_from_socket(g_sck, 0);
114220 cont = 1;
115221
149255 else
150256 {
151257 /* we've got a connection, so we pass it to scp code */
152 LOG_DBG("new connection");
153 scp_process_start((void*)(tintptr)in_sck);
258 LOG_DEVEL(LOG_LEVEL_DEBUG, "new connection");
259 scp_process_start((void *)(tintptr)in_sck);
154260 g_sck_close(in_sck);
155261 }
156262 }
160266 }
161267 else
162268 {
163 log_message(LOG_LEVEL_ERROR, "listen error %d (%s)",
164 g_get_errno(), g_get_strerror());
269 LOG(LOG_LEVEL_ERROR, "listen error %d (%s)",
270 g_get_errno(), g_get_strerror());
165271 rv = 1;
166272 }
167273 }
168274 else
169275 {
170 log_message(LOG_LEVEL_ERROR, "bind error on "
171 "port '%s': %d (%s)", g_cfg->listen_port,
172 g_get_errno(), g_get_strerror());
276 LOG(LOG_LEVEL_ERROR, "bind error on "
277 "port '%s': %d (%s)", g_cfg->listen_port,
278 g_get_errno(), g_get_strerror());
173279 rv = 1;
174280 }
175281 g_tcp_close(g_sck);
176282 return rv;
177283 }
178284
285 /*****************************************************************************/
286 static void
287 print_version(void)
288 {
289 g_writeln("xrdp-sesman %s", PACKAGE_VERSION);
290 g_writeln(" The xrdp session manager");
291 g_writeln(" Copyright (C) 2004-2020 Jay Sorg, "
292 "Neutrino Labs, and all contributors.");
293 g_writeln(" See https://github.com/neutrinolabs/xrdp for more information.");
294 g_writeln("%s", "");
295
296 #if defined(XRDP_CONFIGURE_OPTIONS)
297 g_writeln(" Configure options:");
298 g_writeln("%s", XRDP_CONFIGURE_OPTIONS);
299 #endif
300 }
301
179302 /******************************************************************************/
180 void
181 print_usage(int retcode)
182 {
183 g_printf("xrdp-sesman - xrdp session manager\n\n");
303 static void
304 print_help(void)
305 {
184306 g_printf("Usage: xrdp-sesman [options]\n");
185 g_printf(" -n, --nodaemon run as foreground process\n");
186 g_printf(" -k, --kill kill running xrdp-sesman\n");
187 g_printf(" -h, --help show this help\n");
307 g_printf(" -k, --kill shut down xrdp-sesman\n");
308 g_printf(" -h, --help show help\n");
309 g_printf(" -v, --version show version\n");
310 g_printf(" -n, --nodaemon don't fork into background\n");
311 g_printf(" -c, --config specify new path to sesman.ini\n");
188312 g_deinit();
189 g_exit(retcode);
190 }
191
313 }
314
315 /******************************************************************************/
316 static int
317 kill_running_sesman(const char *pid_file)
318 {
319 int error;
320 int fd;
321 int pid;
322 char pid_s[32] = {0};
323
324 /* check if sesman is running */
325 if (!g_file_exist(pid_file))
326 {
327 g_printf("sesman is not running (pid file not found - %s)\n", pid_file);
328 g_deinit();
329 return 1;
330 }
331
332 fd = g_file_open(pid_file);
333
334 if (-1 == fd)
335 {
336 g_printf("error opening pid file[%s]: %s\n", pid_file, g_get_strerror());
337 return 1;
338 }
339
340 error = g_file_read(fd, pid_s, sizeof(pid_s) - 1);
341
342 if (-1 == error)
343 {
344 g_printf("error reading pid file: %s\n", g_get_strerror());
345 g_file_close(fd);
346 g_deinit();
347 return 1;
348 }
349
350 g_file_close(fd);
351 pid = g_atoi(pid_s);
352
353 error = g_sigterm(pid);
354
355 if (0 != error)
356 {
357 g_printf("error killing sesman: %s\n", g_get_strerror());
358 }
359 else
360 {
361 g_file_delete(pid_file);
362 }
363
364 g_deinit();
365 return error;
366 }
192367 /******************************************************************************/
193368 int
194369 main(int argc, char **argv)
195370 {
196 int fd;
371 int error;
197372 enum logReturns log_error;
198 int error;
199 int daemon = 1;
200 int pid;
201 char pid_s[32];
202373 char text[256];
203374 char pid_file[256];
204 char cfg_file[256];
375 char default_sesman_ini[256];
376 struct sesman_startup_params startup_params = {0};
377 int errored_argc;
378 int daemon;
205379
206380 g_init("xrdp-sesman");
207381 g_snprintf(pid_file, 255, "%s/xrdp-sesman.pid", XRDP_PID_PATH);
208
209 if (1 == argc)
210 {
211 /* start in daemon mode if no cli options */
212 daemon = 1;
213 }
214 else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--nodaemon")) ||
215 (0 == g_strcasecmp(argv[1], "-nodaemon")) ||
216 (0 == g_strcasecmp(argv[1], "-n")) ||
217 (0 == g_strcasecmp(argv[1], "-ns"))))
218 {
219 /* starts sesman not daemonized */
382 g_snprintf(default_sesman_ini, 255, "%s/sesman.ini", XRDP_CFG_PATH);
383
384 startup_params.sesman_ini = default_sesman_ini;
385
386 errored_argc = sesman_process_params(argc, argv, &startup_params);
387 if (errored_argc > 0)
388 {
389 print_version();
390 g_writeln("%s", "");
391 print_help();
392 g_writeln("%s", "");
393
394 g_writeln("Unknown option: %s", argv[errored_argc]);
395 g_deinit();
396 g_exit(1);
397 }
398
399 if (startup_params.help)
400 {
401 print_help();
402 g_exit(0);
403 }
404
405 if (startup_params.version)
406 {
407 print_version();
408 g_exit(0);
409 }
410
411
412 if (startup_params.kill)
413 {
414 g_exit(kill_running_sesman(pid_file));
415 }
416
417 daemon = !startup_params.no_daemon;
418 if (!daemon)
419 {
220420 g_printf("starting sesman in foreground...\n");
221 daemon = 0;
222 }
223 else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--help")) ||
224 (0 == g_strcasecmp(argv[1], "-help")) ||
225 (0 == g_strcasecmp(argv[1], "-h"))))
226 {
227 print_usage(0);
228 }
229 else if ((2 == argc) && ((0 == g_strcasecmp(argv[1], "--kill")) ||
230 (0 == g_strcasecmp(argv[1], "-kill")) ||
231 (0 == g_strcasecmp(argv[1], "-k"))))
232 {
233 /* killing running sesman */
234 /* check if sesman is running */
235 if (!g_file_exist(pid_file))
236 {
237 g_printf("sesman is not running (pid file not found - %s)\n", pid_file);
238 g_deinit();
239 g_exit(1);
240 }
241
242 fd = g_file_open(pid_file);
243
244 if (-1 == fd)
245 {
246 g_printf("error opening pid file[%s]: %s\n", pid_file, g_get_strerror());
247 return 1;
248 }
249
250 g_memset(pid_s, 0, sizeof(pid_s));
251 error = g_file_read(fd, pid_s, 31);
252
253 if (-1 == error)
254 {
255 g_printf("error reading pid file: %s\n", g_get_strerror());
256 g_file_close(fd);
257 g_deinit();
258 g_exit(error);
259 }
260
261 g_file_close(fd);
262 pid = g_atoi(pid_s);
263
264 error = g_sigterm(pid);
265
266 if (0 != error)
267 {
268 g_printf("error killing sesman: %s\n", g_get_strerror());
269 }
270 else
271 {
272 g_file_delete(pid_file);
273 }
274
275 g_deinit();
276 g_exit(error);
277 }
278 else
279 {
280 /* there's something strange on the command line */
281 g_printf("Error: invalid command line arguments\n\n");
282 print_usage(1);
283421 }
284422
285423 if (g_file_exist(pid_file))
293431 }
294432
295433 /* reading config */
296 g_cfg = g_new0(struct config_sesman, 1);
297
298 if (0 == g_cfg)
299 {
300 g_printf("error creating config: quitting.\n");
434 if ((g_cfg = config_read(startup_params.sesman_ini)) == NULL)
435 {
436 g_printf("error reading config %s: %s\nquitting.\n",
437 startup_params.sesman_ini, g_get_strerror());
301438 g_deinit();
302439 g_exit(1);
303440 }
304441
305 //g_cfg->log.fd = -1; /* don't use logging before reading its config */
306 if (0 != config_read(g_cfg))
307 {
308 g_printf("error reading config: %s\nquitting.\n", g_get_strerror());
309 g_deinit();
310 g_exit(1);
311 }
312
313 /* not to spit on the console, show config summary only when running in foreground */
442 /* not to spit on the console, show config summary only when running
443 * in foreground */
314444 if (!daemon)
315445 {
316446 config_dump(g_cfg);
317447 }
318448
319 g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH);
320
321449 /* starting logging subsystem */
322 log_error = log_start(cfg_file, "xrdp-sesman");
450 log_error = log_start(startup_params.sesman_ini, "xrdp-sesman");
323451
324452 if (log_error != LOG_STARTUP_OK)
325453 {
337465 break;
338466 }
339467
468 config_free(g_cfg);
340469 g_deinit();
341470 g_exit(1);
342471 }
343472
344 log_message(LOG_LEVEL_TRACE, "config loaded in %s at %s:%d", __func__, __FILE__, __LINE__);
345 log_message(LOG_LEVEL_TRACE, " listen_address = %s", g_cfg->listen_address);
346 log_message(LOG_LEVEL_TRACE, " listen_port = %s", g_cfg->listen_port);
347 log_message(LOG_LEVEL_TRACE, " enable_user_wm = %d", g_cfg->enable_user_wm);
348 log_message(LOG_LEVEL_TRACE, " default_wm = %s", g_cfg->default_wm);
349 log_message(LOG_LEVEL_TRACE, " user_wm = %s", g_cfg->user_wm);
350 log_message(LOG_LEVEL_TRACE, " reconnect_sh = %s", g_cfg->reconnect_sh);
351 log_message(LOG_LEVEL_TRACE, " auth_file_path = %s", g_cfg->auth_file_path);
473 LOG(LOG_LEVEL_TRACE, "config loaded in %s at %s:%d", __func__, __FILE__, __LINE__);
474 LOG(LOG_LEVEL_TRACE, " sesman_ini = %s", g_cfg->sesman_ini);
475 LOG(LOG_LEVEL_TRACE, " listen_address = %s", g_cfg->listen_address);
476 LOG(LOG_LEVEL_TRACE, " listen_port = %s", g_cfg->listen_port);
477 LOG(LOG_LEVEL_TRACE, " enable_user_wm = %d", g_cfg->enable_user_wm);
478 LOG(LOG_LEVEL_TRACE, " default_wm = %s", g_cfg->default_wm);
479 LOG(LOG_LEVEL_TRACE, " user_wm = %s", g_cfg->user_wm);
480 LOG(LOG_LEVEL_TRACE, " reconnect_sh = %s", g_cfg->reconnect_sh);
481 LOG(LOG_LEVEL_TRACE, " auth_file_path = %s", g_cfg->auth_file_path);
352482
353483 if (daemon)
354484 {
379509 /* start of daemonizing code */
380510 if (sesman_listen_test(g_cfg) != 0)
381511 {
382
383 log_message(LOG_LEVEL_ERROR, "Failed to start xrdp-sesman daemon, "
384 "possibly address already in use.");
512 LOG(LOG_LEVEL_ERROR, "Failed to start xrdp-sesman daemon, "
513 "possibly address already in use.");
514 config_free(g_cfg);
385515 g_deinit();
386516 g_exit(1);
387517 }
388518
389519 if (0 != g_fork())
390520 {
521 config_free(g_cfg);
391522 g_deinit();
392523 g_exit(0);
393524 }
414545 if (daemon)
415546 {
416547 /* writing pid file */
417 fd = g_file_open(pid_file);
548 char pid_s[32];
549 int fd = g_file_open(pid_file);
418550
419551 if (-1 == fd)
420552 {
421 log_message(LOG_LEVEL_ERROR,
422 "error opening pid file[%s]: %s",
423 pid_file, g_get_strerror());
553 LOG(LOG_LEVEL_ERROR,
554 "error opening pid file[%s]: %s",
555 pid_file, g_get_strerror());
424556 log_end();
557 config_free(g_cfg);
425558 g_deinit();
426559 g_exit(1);
427560 }
432565 }
433566
434567 /* start program main loop */
435 log_message(LOG_LEVEL_INFO,
436 "starting xrdp-sesman with pid %d", g_pid);
568 LOG(LOG_LEVEL_INFO,
569 "starting xrdp-sesman with pid %d", g_pid);
437570
438571 /* make sure the socket directory exists */
439572 g_mk_socket_path("xrdp-sesman");
443576 {
444577 if (!g_create_dir("/tmp/.X11-unix"))
445578 {
446 log_message(LOG_LEVEL_ERROR,
579 LOG(LOG_LEVEL_ERROR,
447580 "sesman.c: error creating dir /tmp/.X11-unix");
448581 }
449582 g_chmod_hex("/tmp/.X11-unix", 0x1777);
467600 log_end();
468601 }
469602
603 config_free(g_cfg);
470604 g_deinit();
471605 g_exit(error);
472606 return 0;
3636 ;; KillDisconnected - kill disconnected sessions
3737 ; Type: boolean
3838 ; Default: false
39 ; if 1, true, or yes, kill session after 60 seconds
39 ; if 1, true, or yes, every session will be killed within DisconnectedTimeLimit
40 ; seconds after the user disconnects
4041 KillDisconnected=false
4142
42 ;; DisconnectedTimeLimit - when to kill idle sessions
43 ;; DisconnectedTimeLimit (seconds) - wait before kill disconnected sessions
4344 ; Type: integer
4445 ; Default: 0
45 ; if not zero, the seconds before a disconnected session is killed
46 ; min 60 seconds
46 ; if KillDisconnected is set to false, this value is ignored
4747 DisconnectedTimeLimit=0
4848
49 ;; IdleTimeLimit (specify in second) - wait before disconnect idle sessions
49 ;; IdleTimeLimit (seconds) - wait before disconnect idle sessions
5050 ; Type: integer
5151 ; Default: 0
5252 ; Set to 0 to disable idle disconnection.
5454
5555 ;; Policy - session allocation policy
5656 ; Type: enum [ "Default" | "UBD" | "UBI" | "UBC" | "UBDI" | "UBDC" ]
57 ; Default: Xrdp:<User,BitPerPixel> and Xvnc:<User,BitPerPixel,DisplaySize>
57 ; "Default" session per <User,BitPerPixel>
5858 ; "UBD" session per <User,BitPerPixel,DisplaySize>
5959 ; "UBI" session per <User,BitPerPixel,IPAddr>
6060 ; "UBC" session per <User,BitPerPixel,Connection>
6363 Policy=Default
6464
6565 [Logging]
66 ; Note: Log levels can be any of: core, error, warning, info, debug, or trace
6667 LogFile=xrdp-sesman.log
67 LogLevel=DEBUG
68 EnableSyslog=1
69 SyslogLevel=DEBUG
68 LogLevel=INFO
69 EnableSyslog=true
70 #SyslogLevel=INFO
71 #EnableConsole=false
72 #ConsoleLevel=INFO
73 #EnableProcessId=false
74
75 [LoggingPerLogger]
76 ; Note: per logger configuration is only used in XRDP_DEBUG builds of XRDP.
77 #sesman.c=INFO
78 #main()=INFO
7079
7180 ;
7281 ; Session definitions - startup command-line parameters for each session type
7483
7584 [Xorg]
7685 ; Specify the path of non-suid Xorg executable. It might differ depending
77 ; on your distribution and version. The typical path is shown as follows:
86 ; on your distribution and version. Find out the appropreate path for your
87 ; environment. The typical path is known as follows:
7888 ;
7989 ; Fedora 26 or later : param=/usr/libexec/Xorg
8090 ; Debian 9 or later : param=/usr/lib/xorg/Xorg
8191 ; Ubuntu 16.04 or later : param=/usr/lib/xorg/Xorg
82 ; Arch Linux : param=/usr/lib/xorg-server/Xorg
92 ; Arch Linux : param=/usr/lib/Xorg
8393 ; CentOS 7 : param=/usr/bin/Xorg or param=Xorg
94 ; CentOS 8 : param=/usr/libexec/Xorg
8495 ;
8596 param=Xorg
8697 ; Leave the rest paramaters as-is unless you understand what will happen.
102113 param=96
103114
104115 [Chansrv]
105 ; drive redirection, defaults to xrdp_client if not set
116 ; drive redirection
117 ; See sesman.ini(5) for the format of this parameter
118 #FuseMountName=/run/user/%u/thinclient_drives
119 #FuseMountName=/media/thinclient_drives/%U/thinclient_drives
106120 FuseMountName=thinclient_drives
107121 ; this value allows only the user to acess their own mapped drives.
108122 ; Make this more permissive (e.g. 022) if required.
109123 FileUmask=077
124 ; Can be used to disable FUSE functionality - see sesman.ini(5)
125 #EnableFuseMount=false
126
127 [ChansrvLogging]
128 ; Note: one log file is created per display and the LogFile config value
129 ; is ignored. The channel server log file names follow the naming convention:
130 ; xrdp-chansrv.${DISPLAY}.log
131 ;
132 ; Note: Log levels can be any of: core, error, warning, info, debug, or trace
133 LogLevel=INFO
134 EnableSyslog=true
135 #SyslogLevel=INFO
136 #EnableConsole=false
137 #ConsoleLevel=INFO
138 #EnableProcessId=false
139
140 [ChansrvLoggingPerLogger]
141 ; Note: per logger configuration is only used in XRDP_DEBUG builds of XRDP.
142 #chansrv.c=INFO
143 #main()=INFO
110144
111145 [SessionVariables]
112146 PULSE_SCRIPT=/etc/xrdp/pulse/default.pa
4040 #include "libscp_types.h"
4141 #include "xauth.h"
4242 #include "xrdp_sockets.h"
43 #include "string_calls.h"
4344
4445 #ifndef PR_SET_NO_NEW_PRIVS
4546 #define PR_SET_NO_NEW_PRIVS 38
4647 #endif
47
4848
4949 extern unsigned char g_fixedkey[8];
5050 extern struct config_sesman *g_cfg; /* in sesman.c */
7070 g_memset(outstr, 0, len);
7171 if (self->count == 0)
7272 {
73 g_writeln("List is empty");
73 LOG_DEVEL(LOG_LEVEL_TRACE, "List is empty");
7474 }
7575
7676 for (index = 0; index < self->count; index++)
104104 {
105105 case SCP_SESSION_TYPE_XVNC: /* 0 */
106106 type = SESMAN_SESSION_TYPE_XVNC; /* 2 */
107 /* Xvnc cannot resize */
108 policy = (enum SESMAN_CFG_SESS_POLICY)
109 (policy | SESMAN_CFG_SESS_POLICY_D);
110107 break;
111108 case SCP_SESSION_TYPE_XRDP: /* 1 */
112109 type = SESMAN_SESSION_TYPE_XRDP; /* 1 */
119116 }
120117
121118 #if 0
122 log_message(LOG_LEVEL_INFO,
123 "session_get_bydata: search policy %d U %s W %d H %d bpp %d T %d IP %s",
124 policy, name, width, height, bpp, type, client_ip);
119 LOG(LOG_LEVEL_INFO,
120 "session_get_bydata: search policy %d U %s W %d H %d bpp %d T %d IP %s",
121 policy, name, width, height, bpp, type, client_ip);
125122 #endif
126123
127124 while (tmp != 0)
128125 {
129126 #if 0
130 log_message(LOG_LEVEL_INFO,
127 LOG(LOG_LEVEL_INFO,
131128 "session_get_bydata: try %p U %s W %d H %d bpp %d T %d IP %s",
132129 tmp->item,
133130 tmp->item->name,
137134 #endif
138135
139136 if (g_strncmp(name, tmp->item->name, 255) == 0 &&
140 (!(policy & SESMAN_CFG_SESS_POLICY_D) ||
141 (tmp->item->width == width && tmp->item->height == height)) &&
142 (!(policy & SESMAN_CFG_SESS_POLICY_I) ||
143 (g_strncmp_d(client_ip, tmp->item->client_ip, ':', 255) == 0)) &&
144 (!(policy & SESMAN_CFG_SESS_POLICY_C) ||
145 (g_strncmp(client_ip, tmp->item->client_ip, 255) == 0)) &&
146 tmp->item->bpp == bpp &&
147 tmp->item->type == type)
137 (!(policy & SESMAN_CFG_SESS_POLICY_D) ||
138 (tmp->item->width == width && tmp->item->height == height)) &&
139 (!(policy & SESMAN_CFG_SESS_POLICY_I) ||
140 (g_strncmp_d(client_ip, tmp->item->client_ip, ':', 255) == 0)) &&
141 (!(policy & SESMAN_CFG_SESS_POLICY_C) ||
142 (g_strncmp(client_ip, tmp->item->client_ip, 255) == 0)) &&
143 tmp->item->bpp == bpp &&
144 tmp->item->type == type)
148145 {
149146 return tmp->item;
150147 }
316313 display++;
317314 }
318315
319 log_message(LOG_LEVEL_ERROR, "X server -- no display in range is available");
316 LOG(LOG_LEVEL_ERROR, "X server -- no display in range is available");
320317 return 0;
321318 }
322319
336333
337334 if (i > 40)
338335 {
339 log_message(LOG_LEVEL_ERROR,
340 "X server for display %d startup timeout",
341 display);
336 LOG(LOG_LEVEL_ERROR,
337 "X server for display %d startup timeout",
338 display);
342339 break;
343340 }
344341
373370 g_cfg->env_names,
374371 g_cfg->env_values);
375372
376 if (g_cfg->sec.restrict_outbound_clipboard == 1)
377 {
378 g_setenv("CHANSRV_RESTRICT_OUTBOUND_CLIPBOARD", "1", 1);
379 }
380
381373 /* executing chansrv */
382374 g_execvp(exe_path, (char **) (chansrv_params->items));
383375 /* should not get here */
384 log_message(LOG_LEVEL_ALWAYS, "error starting chansrv "
385 "- user %s - pid %d", username, g_getpid());
376 LOG(LOG_LEVEL_ALWAYS, "error starting chansrv "
377 "- user %s - pid %d", username, g_getpid());
386378 list_delete(chansrv_params);
387379 g_exit(1);
388380 }
428420 /* check to limit concurrent sessions */
429421 if (g_session_count >= g_cfg->sess.max_sessions)
430422 {
431 log_message(LOG_LEVEL_INFO, "max concurrent session limit "
432 "exceeded. login for user %s denied", s->username);
423 LOG(LOG_LEVEL_INFO, "max concurrent session limit "
424 "exceeded. login for user %s denied", s->username);
433425 return 0;
434426 }
435427
437429
438430 if (temp == 0)
439431 {
440 log_message(LOG_LEVEL_ERROR, "cannot create new chain "
441 "element - user %s", s->username);
432 LOG(LOG_LEVEL_ERROR, "cannot create new chain "
433 "element - user %s", s->username);
442434 return 0;
443435 }
444436
447439 if (temp->item == 0)
448440 {
449441 g_free(temp);
450 log_message(LOG_LEVEL_ERROR, "cannot create new session "
451 "item - user %s", s->username);
442 LOG(LOG_LEVEL_ERROR, "cannot create new session "
443 "item - user %s", s->username);
452444 return 0;
453445 }
454446
469461 }
470462 else if (pid == 0)
471463 {
472 log_message(LOG_LEVEL_INFO, "calling auth_start_session from pid %d",
473 g_getpid());
464 LOG(LOG_LEVEL_INFO, "calling auth_start_session from pid %d",
465 g_getpid());
474466 auth_start_session(data, display);
475467 g_delete_wait_obj(g_term_event);
476468 g_tcp_close(g_sck);
501493 */
502494 if (g_setsid() < 0)
503495 {
504 log_message(LOG_LEVEL_ERROR,
505 "setsid failed - pid %d", g_getpid());
496 LOG(LOG_LEVEL_ERROR,
497 "setsid failed - pid %d", g_getpid());
506498 }
507499
508500 if (g_setlogin(s->username) < 0)
509501 {
510 log_message(LOG_LEVEL_ERROR,
511 "setlogin failed for user %s - pid %d", s->username,
512 g_getpid());
502 LOG(LOG_LEVEL_ERROR,
503 "setlogin failed for user %s - pid %d", s->username,
504 g_getpid());
513505 }
514506 }
515507
551543 {
552544 if (s->program[0] != 0)
553545 {
554 g_execlp3(s->program, s->program, 0);
555 log_message(LOG_LEVEL_ALWAYS,
556 "error starting program %s for user %s - pid %d",
557 s->program, s->username, g_getpid());
546 LOG(LOG_LEVEL_DEBUG,
547 "starting program with parameters: %s ",
548 s->program);
549 if (g_strchr(s->program, ' ') != 0 || g_strchr(s->program, '\t') != 0)
550 {
551 const char *params[] = {"sh", "-c", s->program, NULL};
552 g_execvp("/bin/sh", (char **)params);
553 }
554 else
555 {
556 g_execlp3(s->program, s->program, 0);
557 }
558 LOG(LOG_LEVEL_ALWAYS,
559 "error starting program %s for user %s - pid %d",
560 s->program, s->username, g_getpid());
558561 }
559562 }
560563 /* try to execute user window manager if enabled */
564567 if (g_file_exist(text))
565568 {
566569 g_execlp3(text, g_cfg->user_wm, 0);
567 log_message(LOG_LEVEL_ALWAYS, "error starting user "
568 "wm for user %s - pid %d", s->username, g_getpid());
570 LOG(LOG_LEVEL_ALWAYS, "error starting user "
571 "wm for user %s - pid %d", s->username, g_getpid());
569572 /* logging parameters */
570 log_message(LOG_LEVEL_DEBUG, "errno: %d, "
571 "description: %s", g_get_errno(), g_get_strerror());
572 log_message(LOG_LEVEL_DEBUG, "execlp3 parameter "
573 "list:");
574 log_message(LOG_LEVEL_DEBUG, " argv[0] = %s",
575 text);
576 log_message(LOG_LEVEL_DEBUG, " argv[1] = %s",
577 g_cfg->user_wm);
573 LOG(LOG_LEVEL_DEBUG, "errno: %d, "
574 "description: %s", g_get_errno(), g_get_strerror());
575 LOG(LOG_LEVEL_DEBUG, "execlp3 parameter "
576 "list:");
577 LOG(LOG_LEVEL_DEBUG, " argv[0] = %s",
578 text);
579 LOG(LOG_LEVEL_DEBUG, " argv[1] = %s",
580 g_cfg->user_wm);
578581 }
579582 }
580583 /* if we're here something happened to g_execlp3
581584 so we try running the default window manager */
582585 g_execlp3(g_cfg->default_wm, g_cfg->default_wm, 0);
583586
584 log_message(LOG_LEVEL_ALWAYS, "error starting default "
585 "wm for user %s - pid %d", s->username, g_getpid());
587 LOG(LOG_LEVEL_ALWAYS, "error starting default "
588 "wm for user %s - pid %d", s->username, g_getpid());
586589 /* logging parameters */
587 log_message(LOG_LEVEL_DEBUG, "errno: %d, description: "
588 "%s", g_get_errno(), g_get_strerror());
589 log_message(LOG_LEVEL_DEBUG, "execlp3 parameter list:");
590 log_message(LOG_LEVEL_DEBUG, " argv[0] = %s",
591 g_cfg->default_wm);
592 log_message(LOG_LEVEL_DEBUG, " argv[1] = %s",
593 g_cfg->default_wm);
590 LOG(LOG_LEVEL_DEBUG, "errno: %d, description: "
591 "%s", g_get_errno(), g_get_strerror());
592 LOG(LOG_LEVEL_DEBUG, "execlp3 parameter list:");
593 LOG(LOG_LEVEL_DEBUG, " argv[0] = %s",
594 g_cfg->default_wm);
595 LOG(LOG_LEVEL_DEBUG, " argv[1] = %s",
596 g_cfg->default_wm);
594597
595598 /* still a problem starting window manager just start xterm */
596599 g_execlp3("xterm", "xterm", 0);
597600
598601 /* should not get here */
599 log_message(LOG_LEVEL_ALWAYS, "error starting xterm "
600 "for user %s - pid %d", s->username, g_getpid());
602 LOG(LOG_LEVEL_ALWAYS, "error starting xterm "
603 "for user %s - pid %d", s->username, g_getpid());
601604 /* logging parameters */
602 log_message(LOG_LEVEL_DEBUG, "errno: %d, description: "
603 "%s", g_get_errno(), g_get_strerror());
605 LOG(LOG_LEVEL_DEBUG, "errno: %d, description: "
606 "%s", g_get_errno(), g_get_strerror());
604607 }
605608 else
606609 {
607 log_message(LOG_LEVEL_ERROR, "another Xserver might "
608 "already be active on display %d - see log", display);
609 }
610
611 log_message(LOG_LEVEL_DEBUG, "aborting connection...");
610 LOG(LOG_LEVEL_ERROR, "another Xserver might "
611 "already be active on display %d - see log", display);
612 }
613
614 LOG(LOG_LEVEL_DEBUG, "aborting connection...");
612615 g_exit(0);
613616 }
614617 else
673676 */
674677 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0)
675678 {
676 log_message(LOG_LEVEL_WARNING,
677 "Failed to disable setuid on X server: %s",
678 g_get_strerror());
679 LOG(LOG_LEVEL_WARNING,
680 "Failed to disable setuid on X server: %s",
681 g_get_strerror());
679682 }
680683 #endif
681684
699702
700703 pp1 = (char **) xserver_params->items;
701704
702 log_message(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048));
705 LOG(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048));
703706
704707 /* some args are passed via env vars */
705708 g_sprintf(geometry, "%d", s->width);
744747 /* make sure it ends with a zero */
745748 list_add_item(xserver_params, 0);
746749 pp1 = (char **)xserver_params->items;
747 log_message(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048));
750 LOG(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048));
748751 g_execvp(xserver, pp1);
749752 }
750753 else if (type == SESMAN_SESSION_TYPE_XRDP)
773776 /* make sure it ends with a zero */
774777 list_add_item(xserver_params, 0);
775778 pp1 = (char **)xserver_params->items;
776 log_message(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048));
779 LOG(LOG_LEVEL_INFO, "%s", dumpItemsToString(xserver_params, execvpparams, 2048));
777780 g_execvp(xserver, pp1);
778781 }
779782 else
780783 {
781 log_message(LOG_LEVEL_ALWAYS, "bad session type - "
782 "user %s - pid %d", s->username, g_getpid());
784 LOG(LOG_LEVEL_ALWAYS, "bad session type - "
785 "user %s - pid %d", s->username, g_getpid());
783786 g_exit(1);
784787 }
785788
786789 /* should not get here */
787 log_message(LOG_LEVEL_ALWAYS, "error starting X server "
788 "- user %s - pid %d", s->username, g_getpid());
790 LOG(LOG_LEVEL_ALWAYS, "error starting X server "
791 "- user %s - pid %d", s->username, g_getpid());
789792
790793 /* logging parameters */
791 log_message(LOG_LEVEL_DEBUG, "errno: %d, description: "
792 "%s", g_get_errno(), g_get_strerror());
793 log_message(LOG_LEVEL_DEBUG, "execve parameter list size: "
794 "%d", (xserver_params)->count);
794 LOG(LOG_LEVEL_DEBUG, "errno: %d, description: "
795 "%s", g_get_errno(), g_get_strerror());
796 LOG(LOG_LEVEL_DEBUG, "execve parameter list size: "
797 "%d", (xserver_params)->count);
795798
796799 for (i = 0; i < (xserver_params->count); i++)
797800 {
798 log_message(LOG_LEVEL_DEBUG, " argv[%d] = %s",
799 i, (char *)list_get_item(xserver_params, i));
801 LOG(LOG_LEVEL_DEBUG, " argv[%d] = %s",
802 i, (char *)list_get_item(xserver_params, i));
800803 }
801804
802805 list_delete(xserver_params);
804807 }
805808 else
806809 {
810 int wm_wait_time;
807811 wait_for_xserver(display);
808812 chansrv_pid = session_start_chansrv(s->username, display);
809 log_message(LOG_LEVEL_ALWAYS, "waiting for window manager "
810 "(pid %d) to exit", window_manager_pid);
813
814 /* Monitor the amount of time we wait for the
815 * window manager. This is approximately how long the window
816 * manager was running for */
817 LOG(LOG_LEVEL_INFO, "waiting for window manager "
818 "(pid %d) to exit", window_manager_pid);
819 wm_wait_time = g_time1();
811820 g_waitpid(window_manager_pid);
812 log_message(LOG_LEVEL_ALWAYS, "window manager (pid %d) did "
813 "exit, cleaning up session", window_manager_pid);
814 log_message(LOG_LEVEL_INFO, "calling auth_stop_session and "
815 "auth_end from pid %d", g_getpid());
821 wm_wait_time = g_time1() - wm_wait_time;
822 if (wm_wait_time < 10)
823 {
824 /* This could be a config issue. Log a significant error */
825 LOG(LOG_LEVEL_ALWAYS, "window manager exited quickly "
826 "(%d secs). Window manager config problem?",
827 wm_wait_time);
828 }
829 else
830 {
831 LOG(LOG_LEVEL_INFO, "window manager (pid %d) was running "
832 "for approximately %d seconds.",
833 window_manager_pid, wm_wait_time);
834 }
835 LOG(LOG_LEVEL_INFO, "Cleaning up session. Calling "
836 "auth_stop_session and auth_end from pid %d", g_getpid());
816837 auth_stop_session(data);
817838 auth_end(data);
818839 g_sigterm(display_pid);
819840 g_sigterm(chansrv_pid);
841
842 /* make sure socket cleanup happen after child process exit */
843 g_waitpid(display_pid);
844 g_waitpid(chansrv_pid);
845
820846 cleanup_sockets(display);
821847 g_deinit();
822848 g_exit(0);
925951 {
926952 if (tmp->item == 0)
927953 {
928 log_message(LOG_LEVEL_ERROR, "session descriptor for "
929 "pid %d is null!", pid);
954 LOG(LOG_LEVEL_ERROR, "session descriptor for "
955 "pid %d is null!", pid);
930956
931957 if (prev == 0)
932958 {
945971 if (tmp->item->pid == pid)
946972 {
947973 /* deleting the session */
948 log_message(LOG_LEVEL_INFO, "++ terminated session: username %s, display :%d.0, session_pid %d, ip %s", tmp->item->name, tmp->item->display, tmp->item->pid, tmp->item->client_ip);
974 LOG(LOG_LEVEL_INFO, "++ terminated session: username %s, display :%d.0, session_pid %d, ip %s", tmp->item->name, tmp->item->display, tmp->item->pid, tmp->item->client_ip);
949975 g_free(tmp->item);
950976
951977 if (prev == 0)
9841010 {
9851011 if (tmp->item == 0)
9861012 {
987 log_message(LOG_LEVEL_ERROR, "found null session "
988 "descriptor!");
1013 LOG(LOG_LEVEL_ERROR, "found null session "
1014 "descriptor!");
9891015 }
9901016 else
9911017 {
10081034
10091035 if (0 == dummy)
10101036 {
1011 log_message(LOG_LEVEL_ERROR, "session_get_bypid: out of memory");
1037 LOG(LOG_LEVEL_ERROR, "session_get_bypid: out of memory");
10121038 return 0;
10131039 }
10141040
10181044 {
10191045 if (tmp->item == 0)
10201046 {
1021 log_message(LOG_LEVEL_ERROR, "session descriptor for "
1022 "pid %d is null!", pid);
1047 LOG(LOG_LEVEL_ERROR, "session descriptor for "
1048 "pid %d is null!", pid);
10231049 g_free(dummy);
10241050 return 0;
10251051 }
10531079
10541080 while (tmp != 0)
10551081 {
1056 LOG_DBG("user: %s", user);
1082 LOG_DEVEL(LOG_LEVEL_DEBUG, "user: %s", user);
10571083
10581084 if ((NULL == user) || (!g_strncasecmp(user, tmp->item->name, 256)))
10591085 {
1060 LOG_DBG("session_get_byuser: status=%d, flags=%d, "
1061 "result=%d", (tmp->item->status), flags,
1062 ((tmp->item->status) & flags));
1086 LOG_DEVEL(LOG_LEVEL_DEBUG, "session_get_byuser: status=%d, flags=%d, "
1087 "result=%d", (tmp->item->status), flags,
1088 ((tmp->item->status) & flags));
10631089
10641090 if ((tmp->item->status) & flags)
10651091 {
10911117
10921118 while (tmp != 0)
10931119 {
1094 /* #warning FIXME: we should get only disconnected sessions! */
1120 /* #warning FIXME: we should get only disconnected sessions! */
10951121 if ((NULL == user) || (!g_strncasecmp(user, tmp->item->name, 256)))
10961122 {
10971123 if ((tmp->item->status) & flags)
11011127 (sess[index]).height = tmp->item->height;
11021128 (sess[index]).width = tmp->item->width;
11031129 (sess[index]).bpp = tmp->item->bpp;
1104 /* #warning FIXME: setting idle times and such */
1130 /* #warning FIXME: setting idle times and such */
11051131 /*(sess[index]).connect_time.year = tmp->item->connect_time.year;
11061132 (sess[index]).connect_time.month = tmp->item->connect_time.month;
11071133 (sess[index]).connect_time.day = tmp->item->connect_time.day;
11421168 int
11431169 cleanup_sockets(int display)
11441170 {
1145 log_message(LOG_LEVEL_DEBUG, "cleanup_sockets:");
1171 LOG(LOG_LEVEL_DEBUG, "cleanup_sockets:");
11461172 char file[256];
11471173 int error;
11481174
11511177 g_snprintf(file, 255, CHANSRV_PORT_OUT_STR, display);
11521178 if (g_file_exist(file))
11531179 {
1154 log_message(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
1180 LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
11551181 if (g_file_delete(file) == 0)
11561182 {
1157 log_message(LOG_LEVEL_DEBUG,
1158 "cleanup_sockets: failed to delete %s", file);
1183 LOG(LOG_LEVEL_WARNING,
1184 "cleanup_sockets: failed to delete %s (%s)",
1185 file, g_get_strerror());
11591186 error++;
11601187 }
11611188 }
11631190 g_snprintf(file, 255, CHANSRV_PORT_IN_STR, display);
11641191 if (g_file_exist(file))
11651192 {
1166 log_message(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
1193 LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
11671194 if (g_file_delete(file) == 0)
11681195 {
1169 log_message(LOG_LEVEL_DEBUG,
1170 "cleanup_sockets: failed to delete %s", file);
1196 LOG(LOG_LEVEL_WARNING,
1197 "cleanup_sockets: failed to delete %s (%s)",
1198 file, g_get_strerror());
11711199 error++;
11721200 }
11731201 }
11751203 g_snprintf(file, 255, XRDP_CHANSRV_STR, display);
11761204 if (g_file_exist(file))
11771205 {
1178 log_message(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
1206 LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
11791207 if (g_file_delete(file) == 0)
11801208 {
1181 log_message(LOG_LEVEL_DEBUG,
1182 "cleanup_sockets: failed to delete %s", file);
1209 LOG(LOG_LEVEL_WARNING,
1210 "cleanup_sockets: failed to delete %s (%s)",
1211 file, g_get_strerror());
11831212 error++;
11841213 }
11851214 }
11871216 g_snprintf(file, 255, CHANSRV_API_STR, display);
11881217 if (g_file_exist(file))
11891218 {
1190 log_message(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
1219 LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
11911220 if (g_file_delete(file) == 0)
11921221 {
1193 log_message(LOG_LEVEL_DEBUG,
1194 "cleanup_sockets: failed to delete %s", file);
1222 LOG(LOG_LEVEL_WARNING,
1223 "cleanup_sockets: failed to delete %s (%s)",
1224 file, g_get_strerror());
11951225 error++;
11961226 }
11971227 }
11981228
1229 /* the following files should be deleted by xorgxrdp
1230 * but just in case the deletion failed */
1231
1232 g_snprintf(file, 255, XRDP_X11RDP_STR, display);
1233 if (g_file_exist(file))
1234 {
1235 LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
1236 if (g_file_delete(file) == 0)
1237 {
1238 LOG(LOG_LEVEL_WARNING,
1239 "cleanup_sockets: failed to delete %s (%s)",
1240 file, g_get_strerror());
1241 error++;
1242 }
1243 }
1244
1245 g_snprintf(file, 255, XRDP_DISCONNECT_STR, display);
1246 if (g_file_exist(file))
1247 {
1248 LOG(LOG_LEVEL_DEBUG, "cleanup_sockets: deleting %s", file);
1249 if (g_file_delete(file) == 0)
1250 {
1251 LOG(LOG_LEVEL_WARNING,
1252 "cleanup_sockets: failed to delete %s (%s)",
1253 file, g_get_strerror());
1254 error++;
1255 }
1256 }
1257
11991258 return error;
12001259
12011260 }
4242 {
4343 char pid_file[256];
4444
45 log_message(LOG_LEVEL_INFO, "shutting down sesman %d", 1);
45 LOG(LOG_LEVEL_INFO, "shutting down sesman %d", 1);
4646
4747 if (g_getpid() != g_pid)
4848 {
49 LOG_DBG("g_getpid() [%d] differs from g_pid [%d]", (g_getpid()), g_pid);
49 LOG_DEVEL(LOG_LEVEL_DEBUG, "g_getpid() [%d] differs from g_pid [%d]", (g_getpid()), g_pid);
5050 return;
5151 }
5252
53 LOG_DBG(" - getting signal %d pid %d", sig, g_getpid());
53 LOG_DEVEL(LOG_LEVEL_DEBUG, " - getting signal %d pid %d", sig, g_getpid());
5454
5555 g_set_wait_obj(g_term_event);
5656
6666 {
6767 int error;
6868 struct config_sesman *cfg;
69 char cfg_file[256];
7069
71 log_message(LOG_LEVEL_WARNING, "receiving SIGHUP %d", 1);
70 LOG(LOG_LEVEL_WARNING, "receiving SIGHUP %d", 1);
7271
7372 if (g_getpid() != g_pid)
7473 {
75 LOG_DBG("g_getpid() [%d] differs from g_pid [%d]", g_getpid(), g_pid);
74 LOG_DEVEL(LOG_LEVEL_DEBUG, "g_getpid() [%d] differs from g_pid [%d]", g_getpid(), g_pid);
7675 return;
7776 }
7877
79 cfg = g_new0(struct config_sesman, 1);
80
81 if (0 == cfg)
78 if ((cfg = config_read(g_cfg->sesman_ini)) == NULL)
8279 {
83 log_message(LOG_LEVEL_ERROR, "error creating new config: - keeping old cfg");
84 return;
85 }
86
87 if (config_read(cfg) != 0)
88 {
89 log_message(LOG_LEVEL_ERROR, "error reading config - keeping old cfg");
90 g_free(cfg);
80 LOG(LOG_LEVEL_ERROR, "error reading config - keeping old cfg");
9181 return;
9282 }
9383
10090 /* replace old config with newly read one */
10191 g_cfg = cfg;
10292
103 g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH);
104
10593 /* start again logging subsystem */
106 error = log_start(cfg_file, "xrdp-sesman");
94 error = log_start(g_cfg->sesman_ini, "xrdp-sesman");
10795
10896 if (error != LOG_STARTUP_OK)
10997 {
120108 }
121109 }
122110
123 log_message(LOG_LEVEL_INFO, "configuration reloaded, log subsystem restarted");
111 LOG(LOG_LEVEL_INFO, "configuration reloaded, log subsystem restarted");
124112 }
125113
126114 /******************************************************************************/
170158
171159 do
172160 {
173 LOG_DBG("calling sigwait()");
161 LOG_DEVEL(LOG_LEVEL_DEBUG, "calling sigwait()");
174162 sigwait(&waitmask, &recv_signal);
175163
176164 switch (recv_signal)
178166 case SIGHUP:
179167 //reload cfg
180168 //we must stop & restart logging, or copy logging cfg!!!!
181 LOG_DBG("sesman received SIGHUP");
169 LOG_DEVEL(LOG_LEVEL_DEBUG, "sesman received SIGHUP");
182170 //return 0;
183171 break;
184172 case SIGCHLD:
185173 /* a session died */
186 LOG_DBG("sesman received SIGCHLD");
174 LOG_DEVEL(LOG_LEVEL_DEBUG, "sesman received SIGCHLD");
187175 sig_sesman_session_end(SIGCHLD);
188176 break;
189177 case SIGINT:
190178 /* we die */
191 LOG_DBG("sesman received SIGINT");
179 LOG_DEVEL(LOG_LEVEL_DEBUG, "sesman received SIGINT");
192180 sig_sesman_shutdown(recv_signal);
193181 break;
194182 case SIGTERM:
195183 /* we die */
196 LOG_DBG("sesman received SIGTERM");
184 LOG_DEVEL(LOG_LEVEL_DEBUG, "sesman received SIGTERM");
197185 sig_sesman_shutdown(recv_signal);
198186 break;
199187 }
8484 # do not execute the pseudo login shell scripts
8585 . /etc/X11/xdm/Xsession
8686 exit 0
87 elif [ -r /usr/etc/X11/xdm/Xsession ]; then
88 . /usr/etc/X11/xdm/Xsession
89 exit 0
8790 fi
8891
8992 pre_start
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
2626 #include "parse.h"
2727 #include "log.h"
2828 #include "libscp.h"
29 #include "string_calls.h"
2930
3031 #include <stdio.h>
3132 #include <unistd.h>
3536 char cmnd[257];
3637 char serv[257];
3738 char port[257];
38
39 struct log_config logging;
4039
4140 void cmndList(struct SCP_CONNECTION *c);
4241 void cmndKill(struct SCP_CONNECTION *c, struct SCP_SESSION *s);
5554 //int sel;
5655 int sock;
5756 char *pwd;
57 struct log_config *logging;
5858
5959 user[0] = '\0';
6060 pass[0] = '\0';
6262 serv[0] = '\0';
6363 port[0] = '\0';
6464
65 logging.program_name = "sesadmin";
66 logging.log_file = g_strdup("xrdp-sesadmin.log");
67 logging.log_level = LOG_LEVEL_DEBUG;
68 logging.enable_syslog = 0;
69 log_start_from_param(&logging);
65 logging = log_config_init_for_console(LOG_LEVEL_INFO, NULL);
66 log_start_from_param(logging);
67 log_config_free(logging);
7068
7169 for (idx = 0; idx < argc; idx++)
7270 {
132130 sock = g_tcp_socket();
133131 if (sock < 0)
134132 {
135 LOG_DBG("Socket open error, g_tcp_socket() failed");
133 LOG_DEVEL(LOG_LEVEL_DEBUG, "Socket open error, g_tcp_socket() failed");
136134 return 1;
137135 }
138136
139137 s = scp_session_create();
140138 c = scp_connection_create(sock);
141139
142 LOG_DBG("Connecting to %s:%s with user %s (%s)", serv, port, user, pass);
140 LOG_DEVEL(LOG_LEVEL_DEBUG, "Connecting to %s:%s with user %s (%s)", serv, port, user, pass);
143141
144142 if (0 != g_tcp_connect(sock, serv, port))
145143 {
146 LOG_DBG("g_tcp_connect() error");
144 LOG_DEVEL(LOG_LEVEL_DEBUG, "g_tcp_connect() error");
147145 return 1;
148146 }
149147
156154
157155 if (SCP_CLIENT_STATE_OK != e)
158156 {
159 LOG_DBG("libscp error connecting: %s %d", s->errstr, (int)e);
157 LOG_DEVEL(LOG_LEVEL_DEBUG, "libscp error connecting: %s %d", s->errstr, (int)e);
160158 }
161159
162160 if (0 == g_strncmp(cmnd, "list", 5))
2727 #include <config_ac.h>
2828 #endif
2929
30 #include "sesman.h"
30 #include <unistd.h>
31 #include <limits.h>
32 #include <ctype.h>
33
34 #include "parse.h"
35 #include "os_calls.h"
36 #include "config.h"
37 #include "log.h"
3138 #include "tcp.h"
32
33 struct config_sesman g_cfg; /* config.h */
39 #include "string_calls.h"
40
41 #if !defined(PACKAGE_VERSION)
42 #define PACKAGE_VERSION "???"
43 #endif
44
45 #ifndef MAX_PASSWORD_LEN
46 # define MAX_PASSWORD_LEN 512
47 #endif
48
49 #ifndef DEFAULT_WIDTH
50 # define DEFAULT_WIDTH 1280
51 #endif
52
53 #ifndef DEFAULT_HEIGHT
54 # define DEFAULT_HEIGHT 1024
55 #endif
56
57 /* Default setting used by Windows 10 mstsc.exe */
58 #ifndef DEFAULT_BPP
59 # define DEFAULT_BPP 32
60 #endif
61
62 #ifndef DEFAULT_SERVER
63 # define DEFAULT_SERVER "localhost"
64 #endif
65
66 #ifndef DEFAULT_TYPE
67 # define DEFAULT_TYPE "Xorg"
68 #endif
69
70 /**
71 * Maps session type strings to internal code numbers
72 */
73 static struct
74 {
75 const char *name;
76 int code;
77 } type_map[] =
78 {
79 { "Xvnc", 0},
80 { "X11rdp", 10},
81 { "Xorg", 20},
82 { NULL, -1}
83 };
84
85 /**
86 * Parameters needed for a session
87 */
88 struct session_params
89 {
90 int width;
91 int height;
92 int bpp;
93 int session_code;
94 const char *server;
95
96 const char *domain; /* Currently unused by sesman */
97 const char *directory;
98 const char *shell;
99 const char *client_ip;
100
101 const char *username;
102 char password[MAX_PASSWORD_LEN + 1];
103 };
104
105 /**************************************************************************//**
106 * Maps a string to a session code
107 *
108 * @param t session type
109 * @return session code, or -1 if not found
110 */
111 static
112 int get_session_type_code(const char *t)
113 {
114 unsigned int i;
115 for (i = 0 ; type_map[i].name != NULL; ++i)
116 {
117 if (g_strcasecmp(type_map[i].name, t) == 0)
118 {
119 return type_map[i].code;
120 }
121 }
122
123 return -1;
124 }
125
126 /**************************************************************************//**
127 * Returns a list of supported session types
128 *
129 * Caller supplies a buffer. Buffer handling and buffer overflow detection are
130 * the same as snprint()
131 *
132 * @param buff area for result
133 * @param bufflen Size of result
134 * @return number of characters for the output string
135 */
136 static
137 unsigned int get_session_type_list(char *buff, unsigned int bufflen)
138 {
139 unsigned int i;
140 unsigned int ret = 0;
141 const char *sep = "";
142
143 for (i = 0 ; type_map[i].name != NULL; ++i)
144 {
145 if (ret < bufflen)
146 {
147 ret += g_snprintf(buff + ret, bufflen - ret,
148 "%s%s", sep, type_map[i].name);
149 sep = ", ";
150 }
151 }
152
153 return ret;
154 }
155
156 /**************************************************************************//**
157 * Prints a brief summary of options and defaults
158 */
159 static void
160 usage(void)
161 {
162 char sesstype_list[64];
163
164 (void)get_session_type_list(sesstype_list, sizeof(sesstype_list));
165
166 g_printf("xrdp session starter v" PACKAGE_VERSION "\n");
167 g_printf("\nusage:\n");
168 g_printf("sesrun [options] username\n\n");
169 g_printf("options:\n");
170 g_printf(" -g <geometry> Default:%dx%d\n",
171 DEFAULT_WIDTH, DEFAULT_HEIGHT);
172 g_printf(" -b <bits-per-pixel> Default:%d\n", DEFAULT_BPP);
173 /* Don't encourage use of this one - we need to move to local sockets */
174 g_printf(" -s <server> Default:%s (Deprecated)\n",
175 DEFAULT_SERVER);
176 g_printf(" -t <type> Default:%s\n", DEFAULT_TYPE);
177 g_printf(" -D <directory> Default: $HOME\n"
178 " -S <shell> Default: Defined window manager\n"
179 " -p <password> TESTING ONLY - DO NOT USE IN PRODUCTION\n"
180 " -F <file-descriptor> Read password from this file descriptor\n"
181 " -c <sesman_ini> Alternative sesman.ini file\n");
182 g_printf("Supported types are %s or use int for internal code\n",
183 sesstype_list);
184 g_printf("Password is prompted if -p or -F are not specified\n");
185 }
186
187
188 /**************************************************************************//**
189 * Parses a string <width>x<height>
190 *
191 * @param geom_str Input string
192 * @param sp Session parameter structure for resulting width and height
193 * @return !=0 for success
194 */
195 static int
196 parse_geometry_string(const char *geom_str, struct session_params *sp)
197 {
198 int result = 0;
199 unsigned int sep_count = 0; /* Count of 'x' separators */
200 unsigned int other_count = 0; /* Count of non-digits and non separators */
201 const char *sepp = NULL; /* Pointer to the 'x' */
202 const char *p = geom_str;
203
204 while (*p != '\0')
205 {
206 if (!isdigit(*p))
207 {
208 if (*p == 'x' || *p == 'X')
209 {
210 ++sep_count;
211 sepp = p;
212 }
213 else
214 {
215 ++other_count;
216 }
217 }
218 ++p;
219 }
220
221 if (sep_count != 1 || other_count > 0 ||
222 sepp == geom_str || /* Separator at start of string */
223 sepp == (p - 1) ) /* Separator at end of string */
224 {
225 LOG(LOG_LEVEL_ERROR, "Invalid geometry string '%s'", geom_str);
226 }
227 else
228 {
229 sp->width = atoi(geom_str);
230 sp->height = atoi(sepp + 1);
231 result = 1;
232 }
233
234 return result;
235 }
236
237
238 /**************************************************************************//**
239 * Read a password from a file descriptor
240 *
241 * @param fd_str string representing file descriptor
242 * @param sp Session parameter structure for resulting password
243 * @return !=0 for success
244 */
245 static int
246 read_password_from_fd(const char *fd_str, struct session_params *sp)
247 {
248 int result = 0;
249 int s = g_file_read(atoi(fd_str), sp->password, sizeof (sp->password) - 1);
250 if (s < 0)
251 {
252 LOG(LOG_LEVEL_ERROR, "Can't read password from fd %s - %s",
253 fd_str, g_get_strerror());
254 sp->password[0] = '\0';
255 }
256 else
257 {
258 sp->password[s] = '\0';
259 if (s > 0 && sp->password[s - 1] == '\n')
260 {
261 sp->password[s - 1] = '\0';
262 }
263 result = 1;
264 }
265 return result;
266 }
267
268 /**************************************************************************//**
269 * Parses the program args
270 *
271 * @param argc Passed to main
272 * @param @argv Passed to main
273 * @param sp Session parameter structure for resulting values
274 * @param sesman_ini Pointer to an alternative config file if one is specified
275 * @return !=0 for success
276 */
277 static int
278 parse_program_args(int argc, char *argv[], struct session_params *sp,
279 const char **sesman_ini)
280 {
281 int params_ok = 1;
282 int opt;
283 bool_t password_set = 0;
284
285 sp->width = DEFAULT_WIDTH;
286 sp->height = DEFAULT_HEIGHT;
287 sp->bpp = DEFAULT_BPP;
288 sp->session_code = get_session_type_code(DEFAULT_TYPE);
289 sp->server = DEFAULT_SERVER;
290
291 sp->domain = "";
292 sp->directory = "";
293 sp->shell = "";
294 sp->client_ip = "";
295
296 sp->username = NULL;
297 sp->password[0] = '\0';
298
299 while ((opt = getopt(argc, argv, "g:b:s:t:D:S:p:F:c:")) != -1)
300 {
301 switch (opt)
302 {
303 case 'g':
304 if (!parse_geometry_string(optarg, sp))
305 {
306 params_ok = 0;
307 }
308 break;
309
310 case 'b':
311 sp->bpp = atoi(optarg);
312 break;
313
314 case 's':
315 LOG(LOG_LEVEL_WARNING, "Using deprecated option '-s'");
316 sp->server = optarg;
317 break;
318
319 case 't':
320 if (isdigit(optarg[0]))
321 {
322 sp->session_code = atoi(optarg);
323 }
324 else
325 {
326 sp->session_code = get_session_type_code(optarg);
327 if (sp->session_code < 0)
328 {
329 LOG(LOG_LEVEL_ERROR, "Unrecognised session type '%s'",
330 optarg);
331 params_ok = 0;
332 }
333 }
334 break;
335
336 case 'D':
337 sp->directory = optarg;
338 break;
339
340 case 'S':
341 sp->shell = optarg;
342 break;
343
344 case 'p':
345 if (password_set)
346 {
347 LOG(LOG_LEVEL_WARNING,
348 "Ignoring option '%c' - password already set ",
349 (char)opt);
350 }
351 else
352 {
353 g_strncpy(sp->password, optarg, sizeof(sp->password) - 1);
354 password_set = 1;
355 }
356 break;
357
358 case 'F':
359 if (password_set)
360 {
361 LOG(LOG_LEVEL_WARNING,
362 "Ignoring option '%c' - password already set ",
363 (char)opt);
364 }
365 else
366 {
367 if (read_password_from_fd(optarg, sp))
368 {
369 password_set = 1;
370 }
371 else
372 {
373 params_ok = 0;
374 }
375 }
376 break;
377
378 case 'c':
379 *sesman_ini = optarg;
380 break;
381
382 default:
383 LOG(LOG_LEVEL_ERROR, "Unrecognised switch '%c'", (char)opt);
384 params_ok = 0;
385 }
386 }
387
388 if (argc <= optind)
389 {
390 LOG(LOG_LEVEL_ERROR, "No user name speciified");
391 params_ok = 0;
392 }
393 else if ((argc - optind) > 1)
394 {
395 LOG(LOG_LEVEL_ERROR, "Unexpected arguments after username");
396 params_ok = 0;
397 }
398 else
399 {
400 sp->username = argv[optind];
401 }
402
403 if (params_ok && !password_set)
404 {
405 const char *p = getpass("Password: ");
406 if (p != NULL)
407 {
408 g_strcpy(sp->password, p);
409 }
410 }
411
412 return params_ok;
413 }
414
415 /**************************************************************************//**
416 * Helper function for send_scpv0_auth_request()
417 *
418 * @param s Output string
419 * @param str String to write to s
420 */
421 static void
422 out_string16(struct stream *s, const char *str)
423 {
424 int i = g_strlen(str);
425 out_uint16_be(s, i);
426 out_uint8a(s, str, i);
427 }
428
429 /**************************************************************************//**
430 * Sends an SCP V0 authorization request
431 *
432 * @param sck file descriptor to send request on
433 * @param sp Data for request
434 *
435 * @todo This code duplicates functionality in the XRDP function
436 * xrdp_mm_send_login(). When SCP is reworked, a common library
437 * function should be used
438 */
439 static void
440 send_scpv0_auth_request(int sck, const struct session_params *sp)
441 {
442 struct stream *out_s;
443
444 LOG(LOG_LEVEL_DEBUG,
445 "width:%d height:%d bpp:%d code:%d\n"
446 "server:\"%s\" domain:\"%s\" directory:\"%s\"\n"
447 "shell:\"%s\" client_ip:\"%s\"",
448 sp->width, sp->height, sp->bpp, sp->session_code,
449 sp->server, sp->domain, sp->directory,
450 sp->shell, sp->client_ip);
451 /* Only log the password in development builds */
452 LOG_DEVEL(LOG_LEVEL_DEBUG, "password:\"%s\"", sp->password);
453
454 make_stream(out_s);
455 init_stream(out_s, 8192);
456
457 s_push_layer(out_s, channel_hdr, 8);
458 out_uint16_be(out_s, sp->session_code);
459 out_string16(out_s, sp->username);
460 out_string16(out_s, sp->password);
461 out_uint16_be(out_s, sp->width);
462 out_uint16_be(out_s, sp->height);
463 out_uint16_be(out_s, sp->bpp);
464 out_string16(out_s, sp->domain);
465 out_string16(out_s, sp->shell);
466 out_string16(out_s, sp->directory);
467 out_string16(out_s, sp->client_ip);
468 s_mark_end(out_s);
469
470 s_pop_layer(out_s, channel_hdr);
471 out_uint32_be(out_s, 0); /* version */
472 out_uint32_be(out_s, out_s->end - out_s->data); /* size */
473 tcp_force_send(sck, out_s->data, out_s->end - out_s->data);
474
475 free_stream(out_s);
476 }
477
478 /**************************************************************************//**
479 * Receives an SCP V0 authorization reply
480 *
481 * @param sck file descriptor to receive reply on
482 *
483 * @todo This code duplicates functionality in the XRDP function
484 * xrdp_mm_process_login_response(). When SCP is reworked, a
485 * common library function should be used
486 */
487 static int
488 handle_scpv0_auth_reply(int sck)
489 {
490 int result = 1;
491 int packet_ok = 0;
492
493 struct stream *in_s;
494
495 make_stream(in_s);
496 init_stream(in_s, 8192);
497
498 if (tcp_force_recv(sck, in_s->data, 8) == 0)
499 {
500 int version;
501 int size;
502 int code;
503 int data;
504 int display;
505
506 in_uint32_be(in_s, version);
507 in_uint32_be(in_s, size);
508 if (version == 0 && size >= 14)
509 {
510 init_stream(in_s, 8192);
511 if (tcp_force_recv(sck, in_s->data, size - 8) == 0)
512 {
513 in_s->end = in_s->data + (size - 8);
514
515 in_uint16_be(in_s, code);
516 in_uint16_be(in_s, data);
517 in_uint16_be(in_s, display);
518
519 if (code == 3)
520 {
521 packet_ok = 1;
522
523 if (data == 0)
524 {
525 g_printf("Connection denied (authentication error)\n");
526 }
527 else
528 {
529 char guid[16];
530 char guid_str[64];
531 if (s_check_rem(in_s, 16) != 0)
532 {
533 in_uint8a(in_s, guid, 16);
534 g_bytes_to_hexstr(guid, 16, guid_str, 64);
535 }
536 else
537 {
538 g_strcpy(guid_str, "<none>");
539 }
540
541 g_printf("ok data=%d display=:%d GUID=%s\n",
542 (int)data, display, guid_str);
543 result = 0;
544 }
545 }
546 }
547 }
548 }
549
550 if (!packet_ok)
551 {
552 LOG(LOG_LEVEL_ERROR, "Corrupt reply packet");
553 }
554 free_stream(in_s);
555
556 return result;
557 }
34558
35559 /******************************************************************************/
36560 int
37561 main(int argc, char **argv)
38562 {
39 int sck;
40 int code;
41 int i;
42 int size;
43 int version;
44 int width;
45 int height;
46 int bpp;
47 int display;
48 int session_code;
49 struct stream *in_s;
50 struct stream *out_s;
51 char *username;
52 char *password;
53 long data;
54
55 if (0 != config_read(&g_cfg))
56 {
57 g_printf("sesrun: error reading config. quitting.\n");
58 return 1;
59 }
60
61 if (argc == 1)
62 {
63 g_printf("xrdp session starter v0.1\n");
64 g_printf("\nusage:\n");
65 g_printf("sesrun <server> <username> <password> <width> <height> <bpp> <session_cod>\n");
66 g_printf("session code 0 for Xvnc, 10 for X11RDP, 20 for Xorg\n");
67 }
68 else if (argc == 8)
69 {
70 username = argv[2];
71 password = argv[3];
72 width = g_atoi(argv[4]);
73 height = g_atoi(argv[5]);
74 bpp = g_atoi(argv[6]);
75 session_code = g_atoi(argv[7]);
76 make_stream(in_s);
77 init_stream(in_s, 8192);
78 make_stream(out_s);
79 init_stream(out_s, 8192);
80
563 const char *sesman_ini = XRDP_CFG_PATH "/sesman.ini";
564 struct config_sesman *cfg = NULL;
565
566 int sck = -1;
567 struct session_params sp;
568
569 struct log_config *logging;
570 int status = 1;
571
572 logging = log_config_init_for_console(LOG_LEVEL_WARNING,
573 g_getenv("SESRUN_LOG_LEVEL"));
574 log_start_from_param(logging);
575 log_config_free(logging);
576
577 if (!parse_program_args(argc, argv, &sp, &sesman_ini))
578 {
579 usage();
580 }
581 else if ((cfg = config_read(sesman_ini)) == NULL)
582 {
583 LOG(LOG_LEVEL_ERROR, "error reading config file %s : %s",
584 sesman_ini, g_get_strerror());
585 }
586 else
587 {
81588 sck = g_tcp_socket();
82589 if (sck < 0)
83 return 1;
84
85 if (g_tcp_connect(sck, argv[1], g_cfg.listen_port) == 0)
86 {
87 s_push_layer(out_s, channel_hdr, 8);
88 out_uint16_be(out_s, session_code); /* code */
89 i = g_strlen(username);
90 out_uint16_be(out_s, i);
91 out_uint8a(out_s, username, i);
92 i = g_strlen(password);
93 out_uint16_be(out_s, i);
94 out_uint8a(out_s, password, i);
95 out_uint16_be(out_s, width);
96 out_uint16_be(out_s, height);
97 out_uint16_be(out_s, bpp);
98 s_mark_end(out_s);
99 s_pop_layer(out_s, channel_hdr);
100 out_uint32_be(out_s, 0); /* version */
101 out_uint32_be(out_s, out_s->end - out_s->data); /* size */
102 tcp_force_send(sck, out_s->data, out_s->end - out_s->data);
103
104 if (tcp_force_recv(sck, in_s->data, 8) == 0)
105 {
106 in_uint32_be(in_s, version);
107 in_uint32_be(in_s, size);
108 init_stream(in_s, 8192);
109
110 if (tcp_force_recv(sck, in_s->data, size - 8) == 0)
111 {
112 if (version == 0)
113 {
114 in_uint16_be(in_s, code);
115
116 if (code == 3)
117 {
118 in_uint16_be(in_s, data);
119 in_uint16_be(in_s, display);
120 g_printf("ok %d display %d\n", (int)data, display);
121 }
122 }
123 }
124 }
590 {
591 LOG(LOG_LEVEL_ERROR, "socket error - %s", g_get_strerror());
592 }
593 else if (g_tcp_connect(sck, sp.server, cfg->listen_port) != 0)
594 {
595 LOG(LOG_LEVEL_ERROR, "connect error - %s", g_get_strerror());
125596 }
126597 else
127598 {
128 g_printf("connect error\n");
129 }
130
599 send_scpv0_auth_request(sck, &sp);
600 status = handle_scpv0_auth_reply(sck);
601 }
602 }
603
604 if (sck >= 0)
605 {
131606 g_tcp_close(sck);
132 free_stream(in_s);
133 free_stream(out_s);
134 }
135
136 return 0;
137 }
607 }
608
609 g_memset(sp.password, '\0', sizeof(sp.password));
610 config_free(cfg);
611 log_end();
612
613 return status;
614 }
2525 #include "libscp.h"
2626 #include "parse.h"
2727 #include "log.h"
28 #include "string_calls.h"
2829
2930 #include <stdio.h>
3031
5556
5657 sock = g_tcp_socket();
5758 if (sock < 0)
59 {
5860 return 1;
61 }
5962
6063 s = scp_session_create();
6164 c = scp_connection_create(sock);
7777
7878 if (1 == auth_account_disabled(stp))
7979 {
80 log_message(LOG_LEVEL_INFO, "account %s is disabled", user);
80 LOG(LOG_LEVEL_INFO, "account %s is disabled", user);
8181 return 0;
8282 }
8383
311311
312312 today = g_time1() / SECS_PER_DAY;
313313
314 LOG_DBG("last %d", stp->sp_lstchg);
315 LOG_DBG("min %d", stp->sp_min);
316 LOG_DBG("max %d", stp->sp_max);
317 LOG_DBG("inact %d", stp->sp_inact);
318 LOG_DBG("warn %d", stp->sp_warn);
319 LOG_DBG("expire %d", stp->sp_expire);
320 LOG_DBG("today %d", today);
314 LOG_DEVEL(LOG_LEVEL_DEBUG, "last %ld", stp->sp_lstchg);
315 LOG_DEVEL(LOG_LEVEL_DEBUG, "min %ld", stp->sp_min);
316 LOG_DEVEL(LOG_LEVEL_DEBUG, "max %ld", stp->sp_max);
317 LOG_DEVEL(LOG_LEVEL_DEBUG, "inact %ld", stp->sp_inact);
318 LOG_DEVEL(LOG_LEVEL_DEBUG, "warn %ld", stp->sp_warn);
319 LOG_DEVEL(LOG_LEVEL_DEBUG, "expire %ld", stp->sp_expire);
320 LOG_DEVEL(LOG_LEVEL_DEBUG, "today %d", today);
321321
322322 if ((stp->sp_expire != -1) && (today >= stp->sp_expire))
323323 {
325325 }
326326
327327 if ((stp->sp_max >= 0) &&
328 (stp->sp_inact >= 0) &&
329 (stp->sp_lstchg > 0) &&
330 (today >= (stp->sp_lstchg + stp->sp_max + stp->sp_inact)))
331 {
332 return 1;
333 }
334
335 return 0;
336 }
328 (stp->sp_inact >= 0) &&
329 (stp->sp_lstchg > 0) &&
330 (today >= (stp->sp_lstchg + stp->sp_max + stp->sp_inact)))
331 {
332 return 1;
333 }
334
335 return 0;
336 }
4242 #define SECS_PER_DAY (24L*3600L)
4343 #endif
4444
45 extern struct config_sesman* g_cfg; /* in sesman.c */
45 extern struct config_sesman *g_cfg; /* in sesman.c */
4646
4747 /******************************************************************************/
4848 /* returns boolean */
115115 *
116116 */
117117 static int
118 auth_account_disabled(struct spwd* stp)
118 auth_account_disabled(struct spwd *stp)
119119 {
120120 return 0;
121121 }
2929
3030 #include "arch.h"
3131 #include "os_calls.h"
32 #include "string_calls.h"
3233
3334 #include <stdio.h>
3435 #include <security/pam_appl.h>
3536
37 /* Defines the maximum size of a username or password. With pam there is no real limit */
38 #define MAX_BUF 8192
39
3640 struct t_user_pass
3741 {
38 char user[256];
39 char pass[256];
42 char user[MAX_BUF];
43 char pass[MAX_BUF];
4044 };
4145
4246 struct t_auth_info
7377 reply[i].resp = g_strdup(user_pass->pass);
7478 reply[i].resp_retcode = PAM_SUCCESS;
7579 break;
80 case PAM_TEXT_INFO:
81 g_memset(&reply[i], 0, sizeof(struct pam_response));
82 break;
7683 default:
7784 g_printf("unknown in verify_pam_conv\r\n");
7885 g_free(reply);
9198 service_name[0] = 0;
9299
93100 if (g_file_exist("/etc/pam.d/xrdp-sesman") ||
94 g_file_exist(XRDP_SYSCONF_PATH "/pam.d/xrdp-sesman"))
101 g_file_exist(XRDP_SYSCONF_PATH "/pam.d/xrdp-sesman"))
95102 {
96103 g_strncpy(service_name, "xrdp-sesman", 255);
97104 }
114121
115122 get_service_name(service_name);
116123 auth_info = g_new0(struct t_auth_info, 1);
117 g_strncpy(auth_info->user_pass.user, user, 255);
118 g_strncpy(auth_info->user_pass.pass, pass, 255);
124 g_strncpy(auth_info->user_pass.user, user, MAX_BUF - 1);
125 g_strncpy(auth_info->user_pass.pass, pass, MAX_BUF - 1);
119126 auth_info->pamc.conv = &verify_pam_conv;
120127 auth_info->pamc.appdata_ptr = &(auth_info->user_pass);
121128 error = pam_start(service_name, 0, &(auth_info->pamc), &(auth_info->ph));
2929 #include <stdio.h>
3030 #include "log.h"
3131 #include "os_calls.h"
32 #include "string_calls.h"
3233
3334
3435 /******************************************************************************/
4546 g_bytes_to_hexstr(cookie_bin, 16, cookie_str, 33);
4647
4748 g_sprintf(xauth_str, "xauth -q -f %s add :%d . %s",
48 file, display, cookie_str);
49 file, display, cookie_str);
4950
5051 dp = popen(xauth_str, "r");
5152 if (dp == NULL)
5253 {
53 log_message(LOG_LEVEL_ERROR, "Unable to launch xauth");
54 LOG(LOG_LEVEL_ERROR, "Unable to launch xauth");
5455 return 1;
5556 }
5657
5758 ret = pclose(dp);
5859 if (ret < 0)
5960 {
60 log_message(LOG_LEVEL_ERROR, "An error occurred while running xauth");
61 LOG(LOG_LEVEL_ERROR, "An error occurred while running xauth");
6162 return 1;
6263 }
6364
3636 static int g_terminated = 0;
3737 static char g_buf[1024 * 32];
3838
39 #define
40 #define
4139
4240 typedef unsigned short tui16;
4341
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
+1052
-106
vnc/vnc.c less more
1515 * limitations under the License.
1616 *
1717 * libvnc
18 *
19 * The message definitions used in this source file can be found mostly
20 * in RFC6143 - "The Remote Framebuffer Protocol".
21 *
22 * The ExtendedDesktopSize encoding is reserved in RFC6143, but not
23 * documented there. It is documented by the RFB protocol community
24 * wiki currently held at https://github.com/rfbproto/rfbroto. This is
25 * referred to below as the "RFB community wiki"
1826 */
1927
2028 #if defined(HAVE_CONFIG_H)
2533 #include "log.h"
2634 #include "trans.h"
2735 #include "ssl_calls.h"
36 #include "string_calls.h"
37 #include "xrdp_client_info.h"
2838
2939 #define LLOG_LEVEL 1
3040 #define LLOGLN(_level, _args) \
31 do \
32 { \
33 if (_level < LLOG_LEVEL) \
41 do \
3442 { \
35 g_write("xrdp:vnc [%10.10u]: ", g_time3()); \
36 g_writeln _args ; \
43 if (_level < LLOG_LEVEL) \
44 { \
45 g_write("xrdp:vnc [%10.10u]: ", g_time3()); \
46 g_writeln _args ; \
47 } \
3748 } \
38 } \
39 while (0)
49 while (0)
4050
4151 #define AS_LOG_MESSAGE log_message
52
53 /* Client-to-server messages */
54 enum c2s
55 {
56 C2S_SET_PIXEL_FORMAT = 0,
57 C2S_SET_ENCODINGS = 2,
58 C2S_FRAMEBUFFER_UPDATE_REQUEST = 3,
59 C2S_KEY_EVENT = 4,
60 C2S_POINTER_EVENT = 5,
61 C2S_CLIENT_CUT_TEXT = 6,
62 };
63
64 /* Server to client messages */
65 enum s2c
66 {
67 S2C_FRAMEBUFFER_UPDATE = 0,
68 S2C_SET_COLOUR_MAP_ENTRIES = 1,
69 S2C_BELL = 2,
70 S2C_SERVER_CUT_TEXT = 3
71 };
72
73 /* Encodings and pseudo-encodings
74 *
75 * The RFC uses a signed type for these. We use an unsigned type as the
76 * binary representation for the negative values is standardised in C
77 * (which it wouldn't be for an enum value)
78 */
79
80 typedef uint32_t encoding_type;
81
82 #define ENC_RAW (encoding_type)0
83 #define ENC_COPY_RECT (encoding_type)1
84 #define ENC_CURSOR (encoding_type)-239
85 #define ENC_DESKTOP_SIZE (encoding_type)-223
86 #define ENC_EXTENDED_DESKTOP_SIZE (encoding_type)-308
87
88 /* Messages for ExtendedDesktopSize status code */
89 static const char *eds_status_msg[] =
90 {
91 /* 0 */ "No error",
92 /* 1 */ "Resize is administratively prohibited",
93 /* 2 */ "Out of resources",
94 /* 3 */ "Invalid screen layout",
95 /* others */ "Unknown code"
96 };
97
98 /* elements in above list */
99 #define EDS_STATUS_MSG_COUNT \
100 (sizeof(eds_status_msg) / sizeof(eds_status_msg[0]))
101
102 /* Used by enabled_encodings_mask */
103 enum
104 {
105 MSK_EXTENDED_DESKTOP_SIZE = (1 << 0)
106 };
42107
43108 static int
44109 lib_mod_process_message(struct vnc *v, struct stream *s);
222287 make_stream(out_s);
223288 // Send the RFB message type (CLIENT_CUT_TEXT) to the vnc server.
224289 init_stream(out_s, clip_bytes + 1 + 3 + 4 + 16);
225 out_uint8(out_s, 6); // RFB msg type: CLIENT_CUT_TEXT
290 out_uint8(out_s, C2S_CLIENT_CUT_TEXT);
226291 out_uint8s(out_s, 3); // padding
227292 // Send the length of the cut-text to the vnc server.
228293 out_uint32_be(out_s, clip_bytes);
254319 return 0;
255320 }
256321
257 /******************************************************************************/
322 /**************************************************************************//**
323 * Logs a debug message containing a screen layout
324 *
325 * @param lvl Level to log at
326 * @param source Where the layout came from
327 * @param layout Layout to log
328 */
329 static void
330 log_screen_layout(const enum logLevels lvl, const char *source,
331 const struct vnc_screen_layout *layout)
332 {
333 unsigned int i;
334 char text[256];
335 size_t pos;
336 int res;
337
338 pos = 0;
339 res = g_snprintf(text, sizeof(text) - pos,
340 "Layout from %s (geom=%dx%d #screens=%u) :",
341 source, layout->total_width, layout->total_height,
342 layout->count);
343
344 i = 0;
345 while (res > 0 && (size_t)res < sizeof(text) - pos && i < layout->count)
346 {
347 pos += res;
348 res = g_snprintf(&text[pos], sizeof(text) - pos,
349 " %d:(%dx%d+%d+%d)",
350 layout->s[i].id,
351 layout->s[i].width, layout->s[i].height,
352 layout->s[i].x, layout->s[i].y);
353 ++i;
354 }
355 log_message(lvl, "%s", text);
356 }
357
358 /**************************************************************************//**
359 * Compares two vnc_screen structures
360 *
361 * @param a First structure
362 * @param b Second structure
363 *
364 * @return Suitable for sorting structures with ID as the primary key
365 */
366 static int cmp_vnc_screen(const struct vnc_screen *a,
367 const struct vnc_screen *b)
368 {
369 int result = 0;
370 if (a->id != b->id)
371 {
372 result = a->id - b->id;
373 }
374 else if (a->x != b->x)
375 {
376 result = a->x - b->x;
377 }
378 else if (a->y != b->y)
379 {
380 result = a->y - b->y;
381 }
382 else if (a->width != b->width)
383 {
384 result = a->width - b->width;
385 }
386 else if (a->height != b->height)
387 {
388 result = a->height - b->height;
389 }
390
391 return result;
392 }
393
394 /**************************************************************************//**
395 * Compares two vnc_screen_layout structures for equality
396 * @param a First layout
397 * @param b First layout
398 * @return != 0 if structures are equal
399 */
400 static int vnc_screen_layouts_equal(const struct vnc_screen_layout *a,
401 const struct vnc_screen_layout *b)
402 {
403 unsigned int i;
404 int result = (a->total_width == b->total_width &&
405 a->total_height == b->total_height &&
406 a->count == b->count);
407 if (result)
408 {
409 for (i = 0 ; result && i < a->count ; ++i)
410 {
411 result = (cmp_vnc_screen(&a->s[i], &b->s[i]) == 0);
412 }
413 }
414
415 return result;
416 }
417
418 /**************************************************************************//**
419 * Reads an extended desktop size rectangle from the VNC server
420 *
421 * @param v VNC object
422 * @param [out] layout Desired layout for server
423 * @return != 0 for error
424 *
425 * @pre The next octet read from v->trans is the number of screens
426 * @pre layout is not already allocated
427 *
428 * @post if call is successful, layout->s must be freed after use.
429 * @post Returned structure is in increasing ID order
430 * @post layout->total_width is untouched
431 * @post layout->total_height is untouched
432 */
433 static int
434 read_extended_desktop_size_rect(struct vnc *v,
435 struct vnc_screen_layout *layout)
436 {
437 struct stream *s;
438 int error;
439 unsigned int count;
440 struct vnc_screen *screens;
441
442 layout->count = 0;
443 layout->s = NULL;
444
445 make_stream(s);
446 init_stream(s, 8192);
447
448 /* Read in the current screen config */
449 error = trans_force_read_s(v->trans, s, 4);
450 if (error == 0)
451 {
452 /* Get the number of screens */
453 in_uint8(s, count);
454 in_uint8s(s, 3);
455
456 error = trans_force_read_s(v->trans, s, 16 * count);
457 if (error == 0)
458 {
459 screens = g_new(struct vnc_screen, count);
460 if (screens == NULL)
461 {
462 log_message(LOG_LEVEL_ERROR,
463 "VNC : Can't alloc for %d screens", count);
464 error = 1;
465 }
466 else
467 {
468 unsigned int i;
469 for (i = 0 ; i < count ; ++i)
470 {
471 in_uint32_be(s, screens[i].id);
472 in_uint16_be(s, screens[i].x);
473 in_uint16_be(s, screens[i].y);
474 in_uint16_be(s, screens[i].width);
475 in_uint16_be(s, screens[i].height);
476 in_uint32_be(s, screens[i].flags);
477 }
478
479 /* sort monitors in increasing ID order */
480 qsort(screens, count, sizeof(screens[0]),
481 (int (*)(const void *, const void *))cmp_vnc_screen);
482 }
483 }
484 }
485
486 free_stream(s);
487
488 if (error == 0)
489 {
490 layout->count = count;
491 layout->s = screens;
492 }
493
494 return error;
495 }
496
497 /**************************************************************************//**
498 * Sends a SetDesktopSize message
499 *
500 * @param v VNC object
501 * @param layout Desired layout for server
502 * @return != 0 for error
503 *
504 * The SetDesktopSize message is documented in the RFB community wiki
505 * "SetDesktopSize" section.
506 */
507 static int
508 send_set_desktop_size(struct vnc *v, const struct vnc_screen_layout *layout)
509 {
510 unsigned int i;
511 struct stream *s;
512 int error;
513
514 make_stream(s);
515 init_stream(s, 8192);
516 out_uint8(s, 251);
517 out_uint8(s, 0);
518 out_uint16_be(s, layout->total_width);
519 out_uint16_be(s, layout->total_height);
520
521 out_uint8(s, layout->count);
522 out_uint8(s, 0);
523 for (i = 0 ; i < layout->count ; ++i)
524 {
525 out_uint32_be(s, layout->s[i].id);
526 out_uint16_be(s, layout->s[i].x);
527 out_uint16_be(s, layout->s[i].y);
528 out_uint16_be(s, layout->s[i].width);
529 out_uint16_be(s, layout->s[i].height);
530 out_uint32_be(s, layout->s[i].flags);
531 }
532 s_mark_end(s);
533 log_message(LOG_LEVEL_DEBUG, "VNC Sending SetDesktopSize");
534 error = lib_send_copy(v, s);
535 free_stream(s);
536
537 return error;
538 }
539
540 /**************************************************************************//**
541 * Sets up a single-screen vnc_screen_layout structure
542 *
543 * @param layout Structure to set up
544 * @param width New client width
545 * @param height New client height
546 *
547 * @pre layout->count must be valid
548 * @pre layout->s must be valid
549 */
550 static void
551 set_single_screen_layout(struct vnc_screen_layout *layout,
552 int width, int height)
553 {
554 int id = 0;
555 int flags = 0;
556
557 layout->total_width = width;
558 layout->total_height = height;
559
560 if (layout->count == 0)
561 {
562 /* No previous layout */
563 layout->s = g_new(struct vnc_screen, 1);
564 }
565 else
566 {
567 /* Keep the ID and flags from the previous first screen */
568 id = layout->s[0].id;
569 flags = layout->s[0].flags;
570
571 if (layout->count > 1)
572 {
573 g_free(layout->s);
574 layout->s = g_new(struct vnc_screen, 1);
575 }
576 }
577 layout->count = 1;
578 layout->s[0].id = id;
579 layout->s[0].x = 0;
580 layout->s[0].y = 0;
581 layout->s[0].width = width;
582 layout->s[0].height = height;
583 layout->s[0].flags = flags;
584 }
585
586 /**************************************************************************//**
587 * Resize the client as a single screen
588 *
589 * @param v VNC object
590 * @param update_in_progress True if there's a painter update in progress
591 * @param width New client width
592 * @param height New client height
593 * @return != 0 for error
594 *
595 * The new client layout is recorded in v->client_layout. If the client was
596 * multi-screen before this call, it won't be afterwards.
597 */
598 static int
599 resize_client(struct vnc *v, int update_in_progress, int width, int height)
600 {
601 int error = 0;
602
603 if (v->client_layout.count != 1 ||
604 v->client_layout.total_width != width ||
605 v->client_layout.total_height != height)
606 {
607 if (update_in_progress)
608 {
609 error = v->server_end_update(v);
610 }
611
612 if (error == 0)
613 {
614 error = v->server_reset(v, width, height, v->server_bpp);
615 if (error == 0)
616 {
617 set_single_screen_layout(&v->client_layout, width, height);
618 if (update_in_progress)
619 {
620 error = v->server_begin_update(v);
621 }
622 }
623 }
624 }
625
626 return error;
627 }
628
629
630 /**************************************************************************//**
631 * Resize the attached client from a layout
632 *
633 * @param v VNC object
634 * @param update_in_progress True if there's a painter update in progress
635 * @param layout Desired layout from server
636 * @return != 0 for error
637 *
638 * This has some limitations. We have no way to move multiple screens about
639 * on a connected client, and so we are not able to change the client unless
640 * we're changing to a single screeen layout.
641 */
642 static int
643 resize_client_from_layout(struct vnc *v,
644 int update_in_progress,
645 const struct vnc_screen_layout *layout)
646 {
647 int error = 0;
648
649 if (!vnc_screen_layouts_equal(&v->client_layout, layout))
650 {
651 /*
652 * we don't have the capability to resize to anything other
653 * than a single screen.
654 */
655 if (layout->count != 1)
656 {
657 log_message(LOG_LEVEL_ERROR,
658 "VNC Resize to %d screen(s) from %d screen(s) "
659 "not implemented",
660 v->client_layout.count, layout->count);
661
662 /* Dump some useful info, in case we get here when we don't
663 * need to */
664 log_screen_layout(LOG_LEVEL_ERROR, "OldLayout", &v->client_layout);
665 log_screen_layout(LOG_LEVEL_ERROR, "NewLayout", layout);
666 error = 1;
667 }
668 else
669 {
670 error = resize_client(v,
671 update_in_progress,
672 layout->total_width,
673 layout->total_height);
674 }
675 }
676
677 return error;
678 }
679
680 /*****************************************************************************/
258681 int
259682 lib_mod_event(struct vnc *v, int msg, long param1, long param2,
260683 long param3, long param4)
308731 {
309732 /* fix for mstsc sending left control down with altgr */
310733 init_stream(s, 8192);
311 out_uint8(s, 4);
734 out_uint8(s, C2S_KEY_EVENT);
312735 out_uint8(s, 0); /* down flag */
313736 out_uint8s(s, 2);
314737 out_uint32_be(s, 65507); /* left control */
318741 }
319742
320743 init_stream(s, 8192);
321 out_uint8(s, 4);
744 out_uint8(s, C2S_KEY_EVENT);
322745 out_uint8(s, msg == 15); /* down flag */
323746 out_uint8s(s, 2);
324747 out_uint32_be(s, key);
370793 }
371794
372795 init_stream(s, 8192);
373 out_uint8(s, 5);
796 out_uint8(s, C2S_POINTER_EVENT);
374797 out_uint8(s, v->mod_mouse_state);
375798 out_uint16_be(s, param1);
376799 out_uint16_be(s, param2);
381804 {
382805 if (v->suppress_output == 0)
383806 {
384 /* FramebufferUpdateRequest */
385807 init_stream(s, 8192);
386 out_uint8(s, 3);
387 out_uint8(s, 0);
808 out_uint8(s, C2S_FRAMEBUFFER_UPDATE_REQUEST);
809 out_uint8(s, 0); /* incremental == 0 : Full contents */
388810 x = (param1 >> 16) & 0xffff;
389811 out_uint16_be(s, x);
390812 y = param1 & 0xffff;
5831005 }
5841006
5851007 return 0;
1008 }
1009
1010 /**
1011 * Converts a bits-per-pixel value to bytes-per-pixel
1012 */
1013 static int
1014 get_bytes_per_pixel(int bpp)
1015 {
1016 int result = (bpp + 7) / 8;
1017
1018 if (result == 3)
1019 {
1020 result = 4;
1021 }
1022
1023 return result;
1024 }
1025
1026
1027 /**************************************************************************//**
1028 * Skips the specified number of bytes from the transport
1029 *
1030 * @param transport Transport to read
1031 * @param bytes Bytes to skip
1032 * @return != 0 for error
1033 */
1034 static int
1035 skip_trans_bytes(struct trans *trans, int bytes)
1036 {
1037 struct stream *s;
1038 int error;
1039
1040 make_stream(s);
1041 init_stream(s, bytes);
1042 error = trans_force_read_s(trans, s, bytes);
1043 free_stream(s);
1044
1045 return error;
1046 }
1047
1048 /**************************************************************************//**
1049 * Reads an encoding from the input stream and discards it
1050 *
1051 * @param v VNC object
1052 * @param x Encoding X value
1053 * @param y Encoding Y value
1054 * @param cx Encoding CX value
1055 * @param cy Encoding CY value
1056 * @param encoding Code for encoding
1057 * @return != 0 for error
1058 *
1059 * @pre On entry the input stream is positioned after the encoding header
1060 */
1061 static int
1062 skip_encoding(struct vnc *v, int x, int y, int cx, int cy,
1063 encoding_type encoding)
1064 {
1065 char text[256];
1066 int error = 0;
1067
1068 switch (encoding)
1069 {
1070 case ENC_RAW:
1071 {
1072 int need_size = cx * cy * get_bytes_per_pixel(v->server_bpp);
1073 log_message(LOG_LEVEL_DEBUG, "Skipping ENC_RAW encoding");
1074 error = skip_trans_bytes(v->trans, need_size);
1075 }
1076 break;
1077
1078 case ENC_COPY_RECT:
1079 {
1080 log_message(LOG_LEVEL_DEBUG, "Skipping ENC_COPY_RECT encoding");
1081 error = skip_trans_bytes(v->trans, 4);
1082 }
1083 break;
1084
1085 case ENC_CURSOR:
1086 {
1087 int j = cx * cy * get_bytes_per_pixel(v->server_bpp);
1088 int k = ((cx + 7) / 8) * cy;
1089
1090 log_message(LOG_LEVEL_DEBUG, "Skipping ENC_CURSOR encoding");
1091 error = skip_trans_bytes(v->trans, j + k);
1092 }
1093 break;
1094
1095 case ENC_DESKTOP_SIZE:
1096 log_message(LOG_LEVEL_DEBUG, "Skipping ENC_DESKTOP_SIZE encoding");
1097 break;
1098
1099 case ENC_EXTENDED_DESKTOP_SIZE:
1100 {
1101 struct vnc_screen_layout layout = {0};
1102 log_message(LOG_LEVEL_DEBUG,
1103 "Skipping ENC_EXTENDED_DESKTOP_SIZE encoding "
1104 "x=%d, y=%d geom=%dx%d",
1105 x, y, cx, cy);
1106 error = read_extended_desktop_size_rect(v, &layout);
1107 g_free(layout.s);
1108 }
1109 break;
1110
1111 default:
1112 g_sprintf(text, "VNC error in skip_encoding "
1113 "encoding = %8.8x", encoding);
1114 v->server_msg(v, text, 1);
1115 }
1116
1117 return error;
1118 }
1119
1120 /**************************************************************************//**
1121 * Parses an entire framebuffer update message from the wire, and returns the
1122 * first matching ExtendedDesktopSize encoding if found.
1123 *
1124 * Caller can check for a match by examining match_layout.s after the call
1125 *
1126 * @param v VNC object
1127 * @param match Function to call to check for a match
1128 * @param [out] match_x Matching x parameter for an encoding (if needed)
1129 * @param [out] match_y Matching y parameter for an encoding (if needed)
1130 * @param [out] match_layout Returned layout for the encoding
1131 * @return != 0 for error
1132 *
1133 * @post After a successful call, match_layout.s must be free'd
1134 */
1135 static int
1136 find_matching_extended_rect(struct vnc *v,
1137 int (*match)(int x, int y, int cx, int cy),
1138 int *match_x,
1139 int *match_y,
1140 struct vnc_screen_layout *match_layout)
1141 {
1142 int error;
1143 struct stream *s;
1144 unsigned int num_rects;
1145 unsigned int i;
1146 int x;
1147 int y;
1148 int cx;
1149 int cy;
1150 encoding_type encoding;
1151
1152 match_layout->s = NULL;
1153
1154 make_stream(s);
1155 init_stream(s, 8192);
1156 error = trans_force_read_s(v->trans, s, 3);
1157
1158 if (error == 0)
1159 {
1160 in_uint8s(s, 1);
1161 in_uint16_be(s, num_rects);
1162
1163 for (i = 0; i < num_rects; ++i)
1164 {
1165 if (error != 0)
1166 {
1167 break;
1168 }
1169
1170 init_stream(s, 8192);
1171 error = trans_force_read_s(v->trans, s, 12);
1172
1173 if (error == 0)
1174 {
1175 in_uint16_be(s, x);
1176 in_uint16_be(s, y);
1177 in_uint16_be(s, cx);
1178 in_uint16_be(s, cy);
1179 in_uint32_be(s, encoding);
1180
1181 if (encoding == ENC_EXTENDED_DESKTOP_SIZE &&
1182 match_layout->s == NULL &&
1183 match(x, y, cx, cy))
1184 {
1185 log_message(LOG_LEVEL_DEBUG,
1186 "VNC matched ExtendedDesktopSize rectangle "
1187 "x=%d, y=%d geom=%dx%d",
1188 x, y, cx, cy);
1189
1190 error = read_extended_desktop_size_rect(v, match_layout);
1191 if (match_x)
1192 {
1193 *match_x = x;
1194 }
1195 if (match_y)
1196 {
1197 *match_y = y;
1198 }
1199 match_layout->total_width = cx;
1200 match_layout->total_height = cy;
1201 }
1202 else
1203 {
1204 error = skip_encoding(v, x, y, cx, cy, encoding);
1205 }
1206 }
1207 }
1208 }
1209
1210 return error;
1211 }
1212
1213 /**************************************************************************//**
1214 * Sends a FramebufferUpdateRequest for the resize status state machine
1215 *
1216 * The state machine is used at the start of the connection to negotiate
1217 * a common geometry between the client and the server.
1218 *
1219 * The RFB community wiki contains the following paragraph not present
1220 * in RFC6143:-
1221 *
1222 * Note that an empty area can still solicit a FramebufferUpdate
1223 * even though that update will only contain pseudo-encodings
1224 *
1225 * This doesn't seem to be as widely supported as we would like at
1226 * present. We will always request at least a single pixel update to
1227 * avoid confusing the server.
1228 *
1229 * @param v VNC object
1230 * @return != 0 for error
1231 */
1232 static int
1233 send_update_request_for_resize_status(struct vnc *v)
1234 {
1235 int error = 0;
1236 struct stream *s;
1237 make_stream(s);
1238 init_stream(s, 8192);
1239
1240 switch (v->initial_resize_status)
1241 {
1242 case VRS_WAITING_FOR_FIRST_UPDATE:
1243 /*
1244 * Ask for an immediate, minimal update.
1245 */
1246 out_uint8(s, C2S_FRAMEBUFFER_UPDATE_REQUEST);
1247 out_uint8(s, 0); /* incremental == 0 : Full update */
1248 out_uint16_be(s, 0);
1249 out_uint16_be(s, 0);
1250 out_uint16_be(s, 1);
1251 out_uint16_be(s, 1);
1252 s_mark_end(s);
1253 error = lib_send_copy(v, s);
1254 break;
1255
1256 case VRS_WAITING_FOR_RESIZE_CONFIRM:
1257 /*
1258 * Ask for a deferred minimal update.
1259 */
1260 out_uint8(s, C2S_FRAMEBUFFER_UPDATE_REQUEST);
1261 out_uint8(s, 1); /* incremental == 1 : Changes only */
1262 out_uint16_be(s, 0);
1263 out_uint16_be(s, 0);
1264 out_uint16_be(s, 1);
1265 out_uint16_be(s, 1);
1266 s_mark_end(s);
1267 error = lib_send_copy(v, s);
1268 break;
1269
1270 default:
1271 /*
1272 * Ask for a full update from the server
1273 */
1274 if (v->suppress_output == 0)
1275 {
1276 out_uint8(s, C2S_FRAMEBUFFER_UPDATE_REQUEST);
1277 out_uint8(s, 0); /* incremental == 0 : Full update */
1278 out_uint16_be(s, 0);
1279 out_uint16_be(s, 0);
1280 out_uint16_be(s, v->server_width);
1281 out_uint16_be(s, v->server_height);
1282 s_mark_end(s);
1283 error = lib_send_copy(v, s);
1284 }
1285 break;
1286 }
1287
1288 free_stream(s);
1289
1290 return error;
1291 }
1292
1293 /**************************************************************************//**
1294 * Tests if extended desktop size rect is an initial geometry specification
1295 *
1296 * This should be x == 0, but the specification says to treat undefined
1297 * values as 0 also */
1298 static int
1299 rect_is_initial_geometry(int x, int y, int cx, int cy)
1300 {
1301 return (x != 1 && x != 2);
1302 }
1303
1304 /**************************************************************************//**
1305 * Tests if extended desktop size rect is a reply to a request from us
1306 */
1307 static int
1308 rect_is_reply_to_us(int x, int y, int cx, int cy)
1309 {
1310 return (x == 1);
1311 }
1312
1313 /**************************************************************************//**
1314 * Returns an error string for an ExtendedDesktopSize status code
1315 */
1316 static const char *
1317 get_eds_status_msg(unsigned int response_code)
1318 {
1319 if (response_code >= EDS_STATUS_MSG_COUNT)
1320 {
1321 response_code = EDS_STATUS_MSG_COUNT - 1;
1322 }
1323
1324 return eds_status_msg[response_code];
1325 }
1326
1327 /**************************************************************************//**
1328 * Handles the first framebuffer update from the server
1329 *
1330 * This is used to determine if the server supports resizes from
1331 * us. See The RFB community wiki for details.
1332 *
1333 * If the server does support resizing, we send our client geometry over.
1334 *
1335 * @param v VNC object
1336 * @return != 0 for error
1337 */
1338 static int
1339 lib_framebuffer_first_update(struct vnc *v)
1340 {
1341 int error;
1342 struct vnc_screen_layout layout = {0};
1343
1344 error = find_matching_extended_rect(v,
1345 rect_is_initial_geometry,
1346 NULL,
1347 NULL,
1348 &layout);
1349 if (error == 0)
1350 {
1351 if (layout.s != NULL)
1352 {
1353 log_message(LOG_LEVEL_DEBUG, "VNC server supports resizing");
1354
1355 /* Force the client geometry over to the server */
1356 log_screen_layout(LOG_LEVEL_INFO, "OldLayout", &layout);
1357
1358 /*
1359 * If we've only got one screen, and the other side has
1360 * only got one screen, we will preserve their screen ID
1361 * and any flags. This may prevent us sending an unwanted
1362 * SetDesktopSize message if the screen dimensions are
1363 * a match. We can't do this with more than one screen,
1364 * as we have no way to map different IDs
1365 */
1366 if (layout.count == 1 && v->client_layout.count == 1)
1367 {
1368 log_message(LOG_LEVEL_DEBUG, "VNC "
1369 "setting screen id to %d from server",
1370 layout.s[0].id);
1371
1372 v->client_layout.s[0].id = layout.s[0].id;
1373 v->client_layout.s[0].flags = layout.s[0].flags;
1374 }
1375
1376 if (vnc_screen_layouts_equal(&layout, &v->client_layout))
1377 {
1378 log_message(LOG_LEVEL_DEBUG, "Server layout is the same "
1379 "as the client layout");
1380 v->initial_resize_status = VRS_DONE;
1381 }
1382 else
1383 {
1384 log_message(LOG_LEVEL_DEBUG, "Server layout differs from "
1385 "the client layout. Changing server layout");
1386 error = send_set_desktop_size(v, &v->client_layout);
1387 v->initial_resize_status = VRS_WAITING_FOR_RESIZE_CONFIRM;
1388 }
1389 }
1390 else
1391 {
1392 log_message(LOG_LEVEL_DEBUG, "VNC server does not support resizing");
1393
1394 /* Force client to same size as server */
1395 log_message(LOG_LEVEL_DEBUG, "Resizing client to server %dx%d",
1396 v->server_width, v->server_height);
1397 error = resize_client(v, 0, v->server_width, v->server_height);
1398 v->initial_resize_status = VRS_DONE;
1399 }
1400
1401 g_free(layout.s);
1402 }
1403
1404 if (error == 0)
1405 {
1406 error = send_update_request_for_resize_status(v);
1407 }
1408
1409 return error;
1410 }
1411
1412 /**************************************************************************//**
1413 * Looks for a resize confirm in a framebuffer update request
1414 *
1415 * If the server supports resizes from us, this is used to find the
1416 * reply to our initial resize request. See The RFB community wiki for details.
1417 *
1418 * @param v VNC object
1419 * @return != 0 for error
1420 */
1421 static int
1422 lib_framebuffer_waiting_for_resize_confirm(struct vnc *v)
1423 {
1424 int error;
1425 struct vnc_screen_layout layout = {0};
1426 int response_code;
1427
1428 error = find_matching_extended_rect(v,
1429 rect_is_reply_to_us,
1430 NULL,
1431 &response_code,
1432 &layout);
1433 if (error == 0)
1434 {
1435 if (layout.s != NULL)
1436 {
1437 if (response_code == 0)
1438 {
1439 log_message(LOG_LEVEL_DEBUG, "VNC server successfully resized");
1440 log_screen_layout(LOG_LEVEL_INFO, "NewLayout", &layout);
1441 }
1442 else
1443 {
1444 log_message(LOG_LEVEL_ERROR,
1445 "VNC server resize failed - error code %d [%s]",
1446 response_code,
1447 get_eds_status_msg(response_code));
1448 /* Force client to same size as server */
1449 log_message(LOG_LEVEL_DEBUG, "Resizing client to server %dx%d",
1450 v->server_width, v->server_height);
1451 error = resize_client(v, 0, v->server_width, v->server_height);
1452 }
1453 v->initial_resize_status = VRS_DONE;
1454 }
1455
1456 g_free(layout.s);
1457 }
1458
1459 if (error == 0)
1460 {
1461 error = send_update_request_for_resize_status(v);
1462 }
1463
1464 return error;
5861465 }
5871466
5881467 /******************************************************************************/
6051484 int srcx;
6061485 int srcy;
6071486 unsigned int encoding;
608 int Bpp;
6091487 int pixel;
6101488 int r;
6111489 int g;
6141492 int need_size;
6151493 struct stream *s;
6161494 struct stream *pixel_s;
1495 struct vnc_screen_layout layout = { 0 };
6171496
6181497 num_recs = 0;
619 Bpp = (v->mod_bpp + 7) / 8;
620
621 if (Bpp == 3)
622 {
623 Bpp = 4;
624 }
6251498
6261499 make_stream(pixel_s);
6271500
6541527 in_uint16_be(s, cy);
6551528 in_uint32_be(s, encoding);
6561529
657 if (encoding == 0) /* raw */
658 {
659 need_size = cx * cy * Bpp;
1530 if (encoding == ENC_RAW)
1531 {
1532 need_size = cx * cy * get_bytes_per_pixel(v->server_bpp);
6601533 init_stream(pixel_s, need_size);
6611534 error = trans_force_read_s(v->trans, pixel_s, need_size);
6621535
6651538 error = v->server_paint_rect(v, x, y, cx, cy, pixel_s->data, cx, cy, 0, 0);
6661539 }
6671540 }
668 else if (encoding == 1) /* copy rect */
1541 else if (encoding == ENC_COPY_RECT)
6691542 {
6701543 init_stream(s, 8192);
6711544 error = trans_force_read_s(v->trans, s, 4);
6771550 error = v->server_screen_blt(v, x, y, cx, cy, srcx, srcy);
6781551 }
6791552 }
680 else if (encoding == 0xffffff11) /* cursor */
1553 else if (encoding == ENC_CURSOR)
6811554 {
6821555 g_memset(cursor_data, 0, 32 * (32 * 3));
6831556 g_memset(cursor_mask, 0, 32 * (32 / 8));
684 j = cx * cy * Bpp;
1557 j = cx * cy * get_bytes_per_pixel(v->server_bpp);
6851558 k = ((cx + 7) / 8) * cy;
6861559 init_stream(s, j + k);
6871560 error = trans_force_read_s(v->trans, s, j + k);
7001573
7011574 if (pixel)
7021575 {
703 pixel = get_pixel_safe(d1, k, 31 - j, cx, cy, v->mod_bpp);
704 split_color(pixel, &r, &g, &b, v->mod_bpp, v->palette);
1576 pixel = get_pixel_safe(d1, k, 31 - j, cx, cy, v->server_bpp);
1577 split_color(pixel, &r, &g, &b, v->server_bpp, v->palette);
7051578 pixel = make_color(r, g, b, 24);
7061579 set_pixel_safe(cursor_data, k, j, 32, 32, 24, pixel);
7071580 }
7221595 error = v->server_set_cursor(v, x, y, cursor_data, cursor_mask);
7231596 }
7241597 }
725 else if (encoding == 0xffffff21) /* desktop size */
726 {
727 v->mod_width = cx;
728 v->mod_height = cy;
729 error = v->server_reset(v, cx, cy, v->mod_bpp);
1598 else if (encoding == ENC_DESKTOP_SIZE)
1599 {
1600 /* Server end has resized */
1601 v->server_width = cx;
1602 v->server_height = cy;
1603 error = resize_client(v, 1, cx, cy);
1604 }
1605 else if (encoding == ENC_EXTENDED_DESKTOP_SIZE)
1606 {
1607 layout.total_width = cx;
1608 layout.total_height = cy;
1609 error = read_extended_desktop_size_rect(v, &layout);
1610 /* If this is a reply to a request from us, x == 1 */
1611 if (error == 0 && x != 1)
1612 {
1613 v->server_width = layout.total_width;
1614 v->server_height = layout.total_height;
1615 error = resize_client_from_layout(v, 1, &layout);
1616 }
1617 g_free(layout.s);
7301618 }
7311619 else
7321620 {
7461634 {
7471635 if (v->suppress_output == 0)
7481636 {
749 /* FramebufferUpdateRequest */
7501637 init_stream(s, 8192);
751 out_uint8(s, 3);
752 out_uint8(s, 1);
1638 out_uint8(s, C2S_FRAMEBUFFER_UPDATE_REQUEST);
1639 out_uint8(s, 1); /* incremental == 1 : Changes only */
7531640 out_uint16_be(s, 0);
7541641 out_uint16_be(s, 0);
755 out_uint16_be(s, v->mod_width);
756 out_uint16_be(s, v->mod_height);
1642 out_uint16_be(s, v->server_width);
1643 out_uint16_be(s, v->server_height);
7571644 s_mark_end(s);
7581645 error = lib_send_copy(v, s);
7591646 }
9021789 error = 0;
9031790 if (error == 0)
9041791 {
905 if (type == 0) /* framebuffer update */
906 {
907 error = lib_framebuffer_update(v);
908 }
909 else if (type == 1) /* palette */
1792 if (type == S2C_FRAMEBUFFER_UPDATE)
1793 {
1794 switch (v->initial_resize_status)
1795 {
1796 case VRS_WAITING_FOR_FIRST_UPDATE:
1797 error = lib_framebuffer_first_update(v);
1798 break;
1799
1800 case VRS_WAITING_FOR_RESIZE_CONFIRM:
1801 error = lib_framebuffer_waiting_for_resize_confirm(v);
1802 break;
1803
1804 default:
1805 error = lib_framebuffer_update(v);
1806 }
1807 }
1808 else if (type == S2C_SET_COLOUR_MAP_ENTRIES)
9101809 {
9111810 error = lib_palette_update(v);
9121811 }
913 else if (type == 2) /* bell */
1812 else if (type == S2C_BELL)
9141813 {
9151814 error = lib_bell_trigger(v);
9161815 }
917 else if (type == 3) /* clipboard */
1816 else if (type == S2C_SERVER_CUT_TEXT) /* clipboard */
9181817 {
9191818 log_message(LOG_LEVEL_DEBUG, "VNC got clip data");
9201819 error = lib_clip_data(v);
9371836 v->server_set_fgcolor(v, 0);
9381837 v->server_fill_rect(v, 0, 0, w, h);
9391838 v->server_end_update(v);
940 v->server_width = w;
941 v->server_height = h;
9421839 v->server_bpp = bpp;
9431840 return 0;
9441841 }
10081905 int error;
10091906 int i;
10101907 int check_sec_result;
1011 struct source_info *si;
10121908
10131909 v->server_msg(v, "VNC started connecting", 0);
10141910 check_sec_result = 1;
10251921 default:
10261922 v->server_msg(v, "VNC error - only supporting 8, 15, 16, 24 and 32 "
10271923 "bpp rdp connections", 0);
1028 return 1;
1924 return 1;
10291925 }
10301926
10311927 if (g_strcmp(v->ip, "") == 0)
10541950 v->server_msg(v, text, 0);
10551951 g_sleep(v->delay_ms);
10561952 }
1057
1953
10581954 g_sprintf(text, "VNC connecting to %s %s", v->ip, con_port);
10591955 v->server_msg(v, text, 0);
10601956
1061 si = (struct source_info *) (v->si);
1062 v->trans->si = si;
1957 v->trans->si = v->si;
10631958 v->trans->my_source = XRDP_SOURCE_MOD;
10641959
10651960 error = trans_connect(v->trans, v->ip, con_port, 3000);
11872082
11882083 if (error == 0)
11892084 {
1190 in_uint16_be(s, v->mod_width);
1191 in_uint16_be(s, v->mod_height);
2085 in_uint16_be(s, v->server_width);
2086 in_uint16_be(s, v->server_height);
2087
11922088 init_stream(pixel_format, 8192);
11932089 v->server_msg(v, "VNC receiving pixel format", 0);
11942090 error = trans_force_read_s(v->trans, pixel_format, 16);
12002096
12012097 if (error == 0)
12022098 {
1203 v->mod_bpp = v->server_bpp;
12042099 init_stream(s, 8192);
12052100 v->server_msg(v, "VNC receiving name length", 0);
12062101 error = trans_force_read_s(v->trans, s, 4); /* name len */
12352130 /* should be connected */
12362131 if (error == 0)
12372132 {
1238 /* SetPixelFormat */
12392133 init_stream(s, 8192);
1240 out_uint8(s, 0);
2134 out_uint8(s, C2S_SET_PIXEL_FORMAT);
12412135 out_uint8(s, 0);
12422136 out_uint8(s, 0);
12432137 out_uint8(s, 0);
12442138 init_stream(pixel_format, 8192);
12452139
1246 if (v->mod_bpp == 8)
2140 if (v->server_bpp == 8)
12472141 {
12482142 out_uint8(pixel_format, 8); /* bits per pixel */
12492143 out_uint8(pixel_format, 8); /* depth */
12612155 out_uint8(pixel_format, 0); /* blue shift */
12622156 out_uint8s(pixel_format, 3); /* pad */
12632157 }
1264 else if (v->mod_bpp == 15)
2158 else if (v->server_bpp == 15)
12652159 {
12662160 out_uint8(pixel_format, 16); /* bits per pixel */
12672161 out_uint8(pixel_format, 15); /* depth */
12792173 out_uint8(pixel_format, 0); /* blue shift */
12802174 out_uint8s(pixel_format, 3); /* pad */
12812175 }
1282 else if (v->mod_bpp == 16)
2176 else if (v->server_bpp == 16)
12832177 {
12842178 out_uint8(pixel_format, 16); /* bits per pixel */
12852179 out_uint8(pixel_format, 16); /* depth */
12972191 out_uint8(pixel_format, 0); /* blue shift */
12982192 out_uint8s(pixel_format, 3); /* pad */
12992193 }
1300 else if (v->mod_bpp == 24 || v->mod_bpp == 32)
2194 else if (v->server_bpp == 24 || v->server_bpp == 32)
13012195 {
13022196 out_uint8(pixel_format, 32); /* bits per pixel */
13032197 out_uint8(pixel_format, 24); /* depth */
13242218
13252219 if (error == 0)
13262220 {
1327 /* SetEncodings */
2221 encoding_type e[10];
2222 unsigned int n = 0;
2223 unsigned int i;
2224
2225 /* These encodings are always supported */
2226 e[n++] = ENC_RAW;
2227 e[n++] = ENC_COPY_RECT;
2228 e[n++] = ENC_CURSOR;
2229 e[n++] = ENC_DESKTOP_SIZE;
2230 if (v->enabled_encodings_mask & MSK_EXTENDED_DESKTOP_SIZE)
2231 {
2232 e[n++] = ENC_EXTENDED_DESKTOP_SIZE;
2233 }
2234 else
2235 {
2236 log_message(LOG_LEVEL_INFO,
2237 "VNC User disabled EXTENDED_DESKTOP_SIZE");
2238 }
2239
13282240 init_stream(s, 8192);
1329 out_uint8(s, 2);
2241 out_uint8(s, C2S_SET_ENCODINGS);
13302242 out_uint8(s, 0);
1331 out_uint16_be(s, 4);
1332 out_uint32_be(s, 0); /* raw */
1333 out_uint32_be(s, 1); /* copy rect */
1334 out_uint32_be(s, 0xffffff11); /* cursor */
1335 out_uint32_be(s, 0xffffff21); /* desktop size */
1336 v->server_msg(v, "VNC sending encodings", 0);
2243 out_uint16_be(s, n); /* Number of encodings following */
2244 for (i = 0 ; i < n; ++i)
2245 {
2246 out_uint32_be(s, e[i]);
2247 }
13372248 s_mark_end(s);
13382249 error = trans_force_write_s(v->trans, s);
13392250 }
13402251
13412252 if (error == 0)
13422253 {
1343 error = v->server_reset(v, v->mod_width, v->mod_height, v->mod_bpp);
1344 }
1345
1346 if (error == 0)
1347 {
1348 if (v->suppress_output == 0)
1349 {
1350 /* FramebufferUpdateRequest */
1351 init_stream(s, 8192);
1352 out_uint8(s, 3);
1353 out_uint8(s, 0);
1354 out_uint16_be(s, 0);
1355 out_uint16_be(s, 0);
1356 out_uint16_be(s, v->mod_width);
1357 out_uint16_be(s, v->mod_height);
1358 v->server_msg(v, "VNC sending framebuffer update request", 0);
1359 s_mark_end(s);
1360 error = trans_force_write_s(v->trans, s);
1361 }
1362 }
1363
1364 if (error == 0)
1365 {
1366 if (v->server_bpp != v->mod_bpp)
1367 {
1368 v->server_msg(v, "VNC error - server bpp and client bpp do not match", 0);
1369 error = 1;
1370 }
2254 v->initial_resize_status = VRS_WAITING_FOR_FIRST_UPDATE;
2255 error = send_update_request_for_resize_status(v);
13712256 }
13722257
13732258 if (error == 0)
14252310 return 0;
14262311 }
14272312
2313 /**************************************************************************//**
2314 * Initialises the client layout from the Windows monitor definition.
2315 *
2316 * @param [out] layout Our layout
2317 * @param [in] client_info WM info
2318 */
2319 static void
2320 init_client_layout(struct vnc_screen_layout *layout,
2321 const struct xrdp_client_info *client_info)
2322 {
2323 int i;
2324
2325 layout->total_width = client_info->width;
2326 layout->total_height = client_info->height;
2327
2328 layout->count = client_info->monitorCount;
2329 layout->s = g_new(struct vnc_screen, layout->count);
2330
2331 for (i = 0 ; i < client_info->monitorCount ; ++i)
2332 {
2333 /* Use minfo_wm, as this is normalised for a top-left of (0,0)
2334 * as required by RFC6143 */
2335 layout->s[i].id = i;
2336 layout->s[i].x = client_info->minfo_wm[i].left;
2337 layout->s[i].y = client_info->minfo_wm[i].top;
2338 layout->s[i].width = client_info->minfo_wm[i].right -
2339 client_info->minfo_wm[i].left + 1;
2340 layout->s[i].height = client_info->minfo_wm[i].bottom -
2341 client_info->minfo_wm[i].top + 1;
2342 layout->s[i].flags = 0;
2343 }
2344 }
2345
14282346 /******************************************************************************/
14292347 int
14302348 lib_mod_set_param(struct vnc *v, const char *name, const char *value)
14582376 v->got_guid = 1;
14592377 g_memcpy(v->guid, value, 16);
14602378 }
2379 else if (g_strcasecmp(name, "disabled_encodings_mask") == 0)
2380 {
2381 v->enabled_encodings_mask = ~g_atoi(value);
2382 }
2383 else if (g_strcasecmp(name, "client_info") == 0)
2384 {
2385 const struct xrdp_client_info *client_info =
2386 (const struct xrdp_client_info *) value;
2387
2388 g_free(v->client_layout.s);
2389
2390 /* Save monitor information from the client */
2391 if (!client_info->multimon || client_info->monitorCount < 1)
2392 {
2393 set_single_screen_layout(&v->client_layout,
2394 client_info->width,
2395 client_info->height);
2396 }
2397 else
2398 {
2399 init_client_layout(&v->client_layout, client_info);
2400 }
2401 log_screen_layout(LOG_LEVEL_DEBUG, "client_info", &v->client_layout);
2402 }
2403
14612404
14622405 return 0;
14632406 }
15032446 /******************************************************************************/
15042447 /* return error */
15052448 int
1506 lib_mod_frame_ack(struct vnc* v, int flags, int frame_id)
2449 lib_mod_frame_ack(struct vnc *v, int flags, int frame_id)
15072450 {
15082451 return 0;
15092452 }
15112454 /******************************************************************************/
15122455 /* return error */
15132456 int
1514 lib_mod_suppress_output(struct vnc* v, int suppress,
2457 lib_mod_suppress_output(struct vnc *v, int suppress,
15152458 int left, int top, int right, int bottom)
15162459 {
15172460 int error;
15212464 v->suppress_output = suppress;
15222465 if (suppress == 0)
15232466 {
1524 /* FramebufferUpdateRequest */
15252467 make_stream(s);
15262468 init_stream(s, 8192);
1527 out_uint8(s, 3);
1528 out_uint8(s, 0);
2469 out_uint8(s, C2S_FRAMEBUFFER_UPDATE_REQUEST);
2470 out_uint8(s, 0); /* incremental == 0 : Full contents */
15292471 out_uint16_be(s, 0);
15302472 out_uint16_be(s, 0);
1531 out_uint16_be(s, v->mod_width);
1532 out_uint16_be(s, v->mod_height);
2473 out_uint16_be(s, v->server_width);
2474 out_uint16_be(s, v->server_height);
15332475 s_mark_end(s);
15342476 error = lib_send_copy(v, s);
15352477 free_stream(s);
15582500 v->mod_check_wait_objs = lib_mod_check_wait_objs;
15592501 v->mod_frame_ack = lib_mod_frame_ack;
15602502 v->mod_suppress_output = lib_mod_suppress_output;
2503
2504 /* Member variables */
2505 v->enabled_encodings_mask = -1;
15612506 return (tintptr) v;
15622507 }
15632508
15732518 return 0;
15742519 }
15752520 trans_delete(v->trans);
2521 g_free(v->client_layout.s);
15762522 g_free(v);
15772523 return 0;
15782524 }
2525
2626 #define CURRENT_MOD_VER 4
2727
28 /* Screen used for ExtendedDesktopSize / Set DesktopSize */
29 struct vnc_screen
30 {
31 int id;
32 int x;
33 int y;
34 int width;
35 int height;
36 int flags;
37 };
38
39 struct vnc_screen_layout
40 {
41 int total_width;
42 int total_height;
43 unsigned int count;
44 /* For comparison, screens are sorted in increasing order of ID */
45 struct vnc_screen *s;
46 };
47
48 /**
49 * Keep track of resize status at start of connection
50 */
51 enum vnc_resize_status
52 {
53 VRS_WAITING_FOR_FIRST_UPDATE,
54 VRS_WAITING_FOR_RESIZE_CONFIRM,
55 VRS_DONE
56 };
57
58 struct source_info;
59
2860 struct vnc
2961 {
30 int size; /* size of this struct */
31 int version; /* internal version */
32 /* client functions */
33 int (*mod_start)(struct vnc* v, int w, int h, int bpp);
34 int (*mod_connect)(struct vnc* v);
35 int (*mod_event)(struct vnc* v, int msg, long param1, long param2,
36 long param3, long param4);
37 int (*mod_signal)(struct vnc* v);
38 int (*mod_end)(struct vnc* v);
39 int (*mod_set_param)(struct vnc *v, const char *name, const char *value);
40 int (*mod_session_change)(struct vnc* v, int, int);
41 int (*mod_get_wait_objs)(struct vnc* v, tbus* read_objs, int* rcount,
42 tbus* write_objs, int* wcount, int* timeout);
43 int (*mod_check_wait_objs)(struct vnc* v);
44 int (*mod_frame_ack)(struct vnc* v, int flags, int frame_id);
45 int (*mod_suppress_output)(struct vnc* v, int suppress,
46 int left, int top, int right, int bottom);
47 tintptr mod_dumby[100 - 11]; /* align, 100 minus the number of mod
62 int size; /* size of this struct */
63 int version; /* internal version */
64 /* client functions */
65 int (*mod_start)(struct vnc *v, int w, int h, int bpp);
66 int (*mod_connect)(struct vnc *v);
67 int (*mod_event)(struct vnc *v, int msg, long param1, long param2,
68 long param3, long param4);
69 int (*mod_signal)(struct vnc *v);
70 int (*mod_end)(struct vnc *v);
71 int (*mod_set_param)(struct vnc *v, const char *name, const char *value);
72 int (*mod_session_change)(struct vnc *v, int, int);
73 int (*mod_get_wait_objs)(struct vnc *v, tbus *read_objs, int *rcount,
74 tbus *write_objs, int *wcount, int *timeout);
75 int (*mod_check_wait_objs)(struct vnc *v);
76 int (*mod_frame_ack)(struct vnc *v, int flags, int frame_id);
77 int (*mod_suppress_output)(struct vnc *v, int suppress,
78 int left, int top, int right, int bottom);
79 tintptr mod_dumby[100 - 11]; /* align, 100 minus the number of mod
4880 functions above */
49 /* server functions */
50 int (*server_begin_update)(struct vnc* v);
51 int (*server_end_update)(struct vnc* v);
52 int (*server_fill_rect)(struct vnc* v, int x, int y, int cx, int cy);
53 int (*server_screen_blt)(struct vnc* v, int x, int y, int cx, int cy,
54 int srcx, int srcy);
55 int (*server_paint_rect)(struct vnc* v, int x, int y, int cx, int cy,
56 char* data, int width, int height, int srcx, int srcy);
57 int (*server_set_cursor)(struct vnc* v, int x, int y, char* data, char* mask);
58 int (*server_palette)(struct vnc* v, int* palette);
59 int (*server_msg)(struct vnc* v, const char *msg, int code);
60 int (*server_is_term)(struct vnc* v);
61 int (*server_set_clip)(struct vnc* v, int x, int y, int cx, int cy);
62 int (*server_reset_clip)(struct vnc* v);
63 int (*server_set_fgcolor)(struct vnc* v, int fgcolor);
64 int (*server_set_bgcolor)(struct vnc* v, int bgcolor);
65 int (*server_set_opcode)(struct vnc* v, int opcode);
66 int (*server_set_mixmode)(struct vnc* v, int mixmode);
67 int (*server_set_brush)(struct vnc* v, int x_origin, int y_origin,
68 int style, char* pattern);
69 int (*server_set_pen)(struct vnc* v, int style,
70 int width);
71 int (*server_draw_line)(struct vnc* v, int x1, int y1, int x2, int y2);
72 int (*server_add_char)(struct vnc* v, int font, int character,
73 int offset, int baseline,
74 int width, int height, char* data);
75 int (*server_draw_text)(struct vnc* v, int font,
76 int flags, int mixmode, int clip_left, int clip_top,
77 int clip_right, int clip_bottom,
78 int box_left, int box_top,
79 int box_right, int box_bottom,
80 int x, int y, char* data, int data_len);
81 int (*server_reset)(struct vnc* v, int width, int height, int bpp);
82 int (*server_query_channel)(struct vnc* v, int index,
83 char* channel_name,
84 int* channel_flags);
85 int (*server_get_channel_id)(struct vnc* v, const char *name);
86 int (*server_send_to_channel)(struct vnc* v, int channel_id,
87 char* data, int data_len,
88 int total_data_len, int flags);
89 int (*server_bell_trigger)(struct vnc* v);
90 tintptr server_dumby[100 - 25]; /* align, 100 minus the number of server
81 /* server functions */
82 int (*server_begin_update)(struct vnc *v);
83 int (*server_end_update)(struct vnc *v);
84 int (*server_fill_rect)(struct vnc *v, int x, int y, int cx, int cy);
85 int (*server_screen_blt)(struct vnc *v, int x, int y, int cx, int cy,
86 int srcx, int srcy);
87 int (*server_paint_rect)(struct vnc *v, int x, int y, int cx, int cy,
88 char *data, int width, int height, int srcx, int srcy);
89 int (*server_set_cursor)(struct vnc *v, int x, int y, char *data, char *mask);
90 int (*server_palette)(struct vnc *v, int *palette);
91 int (*server_msg)(struct vnc *v, const char *msg, int code);
92 int (*server_is_term)(struct vnc *v);
93 int (*server_set_clip)(struct vnc *v, int x, int y, int cx, int cy);
94 int (*server_reset_clip)(struct vnc *v);
95 int (*server_set_fgcolor)(struct vnc *v, int fgcolor);
96 int (*server_set_bgcolor)(struct vnc *v, int bgcolor);
97 int (*server_set_opcode)(struct vnc *v, int opcode);
98 int (*server_set_mixmode)(struct vnc *v, int mixmode);
99 int (*server_set_brush)(struct vnc *v, int x_origin, int y_origin,
100 int style, char *pattern);
101 int (*server_set_pen)(struct vnc *v, int style,
102 int width);
103 int (*server_draw_line)(struct vnc *v, int x1, int y1, int x2, int y2);
104 int (*server_add_char)(struct vnc *v, int font, int character,
105 int offset, int baseline,
106 int width, int height, char *data);
107 int (*server_draw_text)(struct vnc *v, int font,
108 int flags, int mixmode, int clip_left, int clip_top,
109 int clip_right, int clip_bottom,
110 int box_left, int box_top,
111 int box_right, int box_bottom,
112 int x, int y, char *data, int data_len);
113 int (*server_reset)(struct vnc *v, int width, int height, int bpp);
114 int (*server_query_channel)(struct vnc *v, int index,
115 char *channel_name,
116 int *channel_flags);
117 int (*server_get_channel_id)(struct vnc *v, const char *name);
118 int (*server_send_to_channel)(struct vnc *v, int channel_id,
119 char *data, int data_len,
120 int total_data_len, int flags);
121 int (*server_bell_trigger)(struct vnc *v);
122 tintptr server_dumby[100 - 25]; /* align, 100 minus the number of server
91123 functions above */
92 /* common */
93 tintptr handle; /* pointer to self as long */
94 tintptr wm;
95 tintptr painter;
96 tintptr si;
97 /* mod data */
98 int server_width;
99 int server_height;
100 int server_bpp;
101 int mod_width;
102 int mod_height;
103 int mod_bpp;
104 char mod_name[256];
105 int mod_mouse_state;
106 int palette[256];
107 int vnc_desktop;
108 char username[256];
109 char password[256];
110 char ip[256];
111 char port[256];
112 int sck_closed;
113 int shift_state; /* 0 up, 1 down */
114 int keylayout;
115 int clip_chanid;
116 struct stream *clip_data_s;
117 int delay_ms;
118 struct trans *trans;
119 int got_guid;
120 tui8 guid[16];
121 int suppress_output;
124 /* common */
125 tintptr handle; /* pointer to self as long */
126 tintptr wm;
127 tintptr painter;
128 struct source_info *si;
129 /* mod data */
130 int server_width;
131 int server_height;
132 int server_bpp;
133 char mod_name[256];
134 int mod_mouse_state;
135 int palette[256];
136 int vnc_desktop;
137 char username[256];
138 char password[256];
139 char ip[256];
140 char port[256];
141 int sck_closed;
142 int shift_state; /* 0 up, 1 down */
143 int keylayout;
144 int clip_chanid;
145 struct stream *clip_data_s;
146 int delay_ms;
147 struct trans *trans;
148 int got_guid;
149 tui8 guid[16];
150 int suppress_output;
151 unsigned int enabled_encodings_mask;
152 /* Resizeable support */
153 struct vnc_screen_layout client_layout;
154 enum vnc_resize_status initial_resize_status;
122155 };
+0
-266
vrplayer/decoderthread.cpp less more
0
1
2 // not used
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include "decoderthread.h"
21
22 /*
23 * TODO:
24 * o need to maintain aspect ratio while resizing
25 * o clicking in the middle of the slider bar should move the slider to the middle
26 * o need to be able to rewind the move when it is done playing
27 * o need to be able to load another move and play it w/o restarting player
28 * o pause button needs to work
29 * o need images for btns
30 */
31
32 DecoderThread::DecoderThread()
33 {
34 channel = NULL;
35 geometry.setX(0);
36 geometry.setY(0);
37 geometry.setWidth(0);
38 geometry.setHeight(0);
39 stream_id = 101;
40 elapsedTime = 0;
41 la_seekPos = -1;
42 videoTimer = NULL;
43 audioTimer = NULL;
44 }
45
46 void DecoderThread::run()
47 {
48 /* need a media file */
49 if (filename.length() == 0)
50 {
51 emit on_decoderErrorMsg("No media file",
52 "Please select a media file to play");
53 return;
54 }
55 }
56
57 void DecoderThread::startMediaPlay()
58 {
59 MediaPacket *mediaPkt;
60 int is_video_frame;
61 int rv;
62
63 /* setup video timer; each time this timer fires, it sends */
64 /* one video pkt to the client then resets the callback duration */
65 videoTimer = new QTimer;
66 connect(videoTimer, SIGNAL(timeout()), this, SLOT(videoTimerCallback()));
67 //videoTimer->start(1500);
68
69 /* setup audio timer; does the same as above, but with audio pkts */
70 audioTimer = new QTimer;
71 connect(audioTimer, SIGNAL(timeout()), this, SLOT(audioTimerCallback()));
72 //audioTimer->start(500);
73
74 /* setup pktTimer; each time this timer fires, it reads AVPackets */
75 /* and puts them into audio/video Queues */
76 pktTimer = new QTimer;
77 connect(pktTimer, SIGNAL(timeout()), this, SLOT(pktTimerCallback()));
78
79 while (1)
80 {
81 /* fill the audio/video queues with initial data; thereafter */
82 /* data will be filled by pktTimerCallback() */
83 if ((audioQueue.count() >= 3000) || (videoQueue.count() >= 3000))
84 {
85 //pktTimer->start(50);
86
87 //videoTimer->start(1500);
88 //audioTimer->start(500);
89
90 playVideo = new PlayVideo(NULL, &videoQueue, channel, 101);
91 playVideoThread = new QThread(this);
92 connect(playVideoThread, SIGNAL(started()), playVideo, SLOT(play()));
93 playVideo->moveToThread(playVideoThread);
94 playVideoThread->start();
95
96 playAudio = new PlayAudio(NULL, &audioQueue, channel, 101);
97 playAudioThread = new QThread(this);
98 connect(playAudioThread, SIGNAL(started()), playAudio, SLOT(play()));
99 playAudio->moveToThread(playAudioThread);
100 playAudioThread->start();
101
102 return;
103 }
104
105 mediaPkt = new MediaPacket;
106 rv = xrdpvr_get_frame(&mediaPkt->av_pkt,
107 &is_video_frame,
108 &mediaPkt->delay_in_us);
109 if (rv < 0)
110 {
111 /* looks like we reached end of file */
112 break;
113 }
114
115 if (is_video_frame)
116 videoQueue.enqueue(mediaPkt);
117 else
118 audioQueue.enqueue(mediaPkt);
119
120 } /* end while (1) */
121 }
122
123 void DecoderThread::on_mediaSeek(int value)
124 {
125 mutex.lock();
126 la_seekPos = value;
127 mutex.unlock();
128
129 qDebug() << "media seek value=" << value;
130
131 /* pktTimer stops at end of media; need to restart it */
132 if (!pktTimer->isActive())
133 {
134 updateSlider();
135 pktTimer->start(100);
136 }
137 }
138
139 void DecoderThread::setFilename(QString filename)
140 {
141 this->filename = filename;
142 }
143
144 void DecoderThread::stopPlayer()
145 {
146 pktTimer->stop();
147 audioQueue.clear();
148 videoQueue.clear();
149 }
150
151 void DecoderThread::pausePlayer()
152 {
153 pktTimer->stop();
154 }
155
156 void DecoderThread::resumePlayer()
157 {
158 pktTimer->start(100);
159 }
160
161 void DecoderThread::close()
162 {
163 }
164
165 void DecoderThread::audioTimerCallback()
166 {
167 MediaPacket *pkt;
168 int delayInMs;
169
170 if (audioQueue.isEmpty())
171 {
172 qDebug() << "audioTimerCallback: got empty";
173 audioTimer->setInterval(100);
174 return;
175 }
176
177 pkt = audioQueue.dequeue();
178 delayInMs = (int) ((float) pkt->delay_in_us / 1000.0);
179 send_audio_pkt(channel, 101, pkt->av_pkt);
180 delete pkt;
181
182 //qDebug() << "audioTimerCallback: delay :" << delayInMs;
183
184 audioTimer->setInterval(delayInMs);
185 }
186
187 void DecoderThread::videoTimerCallback()
188 {
189 MediaPacket *pkt;
190 int delayInMs;
191
192 if (videoQueue.isEmpty())
193 {
194 qDebug() << "videoTimerCallback: GOT EMPTY";
195 videoTimer->setInterval(100);
196 return;
197 }
198
199 pkt = videoQueue.dequeue();
200 delayInMs = (int) 10; // ((float) pkt->delay_in_us / 1000.0);
201 send_video_pkt(channel, 101, pkt->av_pkt);
202 delete pkt;
203 updateSlider();
204 //qDebug() << "videoTimerCallback: delay :" << delayInMs;
205 videoTimer->setInterval(delayInMs);
206 }
207
208 void DecoderThread::pktTimerCallback()
209 {
210 MediaPacket *mediaPkt;
211 int is_video_frame;
212 int rv;
213
214 while (1)
215 {
216 qDebug() << "pktTimerCallback: audioCount=" << audioQueue.count() << "videoCount=" << videoQueue.count();
217 #if 1
218 if ((audioQueue.count() >= 20) || (videoQueue.count() >= 20))
219 return;
220 #else
221 if (videoQueue.count() >= 60)
222 return;
223 #endif
224 mediaPkt = new MediaPacket;
225 rv = xrdpvr_get_frame(&mediaPkt->av_pkt,
226 &is_video_frame,
227 &mediaPkt->delay_in_us);
228 if (rv < 0)
229 {
230 /* looks like we reached end of file */
231 qDebug() << "###### looks like we reached EOF";
232 pktTimer->stop();
233 // LK_TODO set some flag so audio/video timer also stop when q is empty
234 return;
235 }
236
237 if (is_video_frame)
238 videoQueue.enqueue(mediaPkt);
239 else
240 audioQueue.enqueue(mediaPkt);
241 }
242 }
243
244 void DecoderThread::updateSlider()
245 {
246 if (elapsedTime == 0)
247 elapsedTime = av_gettime();
248
249 /* time elapsed in 1/100th sec units since play started */
250 emit on_elapsedtime((av_gettime() - elapsedTime) / 10000);
251
252 mutex.lock();
253 if (la_seekPos >= 0)
254 {
255 qDebug() << "seeking to" << la_seekPos;
256 //audioTimer->stop();
257 //videoTimer->stop();
258 xrdpvr_seek_media(la_seekPos, 0);
259 elapsedTime = av_gettime() - la_seekPos * 1000000;
260 //audioTimer->start(10);
261 //videoTimer->start(10);
262 la_seekPos = -1;
263 }
264 mutex.unlock();
265 }
+0
-95
vrplayer/decoderthread.h less more
0 #ifndef DECODERTHREAD_H
1 #define DECODERTHREAD_H
2
3 #ifdef __cplusplus
4 #define __STDC_CONSTANT_MACROS
5 #ifdef _STDINT_H
6 #undef _STDINT_H
7 #endif
8 #include <stdint.h>
9 #endif
10
11 #include <QThread>
12 #include <QDebug>
13 #include <QString>
14 #include <QRect>
15 #include <QMutex>
16 #include <QTimer>
17 #include <QQueue>
18
19 #include <xrdpapi.h>
20 #include <xrdpvr.h>
21 #include <mediapacket.h>
22 #include <playvideo.h>
23 #include <playaudio.h>
24
25 /* ffmpeg related stuff */
26 extern "C"
27 {
28 #include <libavformat/avformat.h>
29 #include <libavcodec/avcodec.h>
30 }
31
32 class DecoderThread : public QObject
33 {
34 Q_OBJECT
35
36 public:
37 /* public methods */
38 DecoderThread();
39
40 void setFilename(QString filename);
41 void stopPlayer();
42 void pausePlayer();
43 void resumePlayer();
44 void oneTimeDeinit();
45 void close();
46 void run();
47 void startMediaPlay();
48
49 public slots:
50 void on_mediaSeek(int value);
51
52 private:
53 /* private variables */
54 QQueue<MediaPacket *> audioQueue;
55 QQueue<MediaPacket *> videoQueue;
56
57 QTimer *videoTimer;
58 QTimer *audioTimer;
59 QTimer *pktTimer;
60 QString filename;
61 void *channel;
62 int stream_id;
63 QRect geometry;
64 int64_t elapsedTime; /* elapsed time in usecs since play started */
65 QMutex mutex;
66 int64_t la_seekPos; /* locked access; must hold mutex */
67
68 PlayVideo *playVideo;
69 QThread *playVideoThread;
70 PlayAudio *playAudio;
71 QThread *playAudioThread;
72
73 /* private functions */
74 int sendMetadataFile();
75 int sendAudioFormat();
76 int sendVideoFormat();
77 int sendGeometry();
78 void updateSlider();
79
80 private slots:
81 /* private slots */
82 void audioTimerCallback();
83 void videoTimerCallback();
84 void pktTimerCallback();
85
86 signals:
87 /* private signals */
88 void on_progressUpdate(int percent);
89 void on_decoderErrorMsg(QString title, QString msg);
90 void on_mediaDurationInSeconds(int duration);
91 void on_elapsedtime(int val); /* in hundredth of a sec */
92 };
93
94 #endif // DECODERTHREAD_H
1010 savedGeometry.setHeight(0);
1111 stream_id = 101;
1212 demuxMedia = 0;
13 demuxMediaThread = NULL;
1314 //elapsedTime = 0;
1415 }
1516
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
2222 #endif
2323
2424 #include "xrdp.h"
25 #include "string_calls.h"
2526
2627 /*****************************************************************************/
2728 /* returns boolean */
2323 #endif
2424
2525 #include "xrdp.h"
26 #include "ms-rdpbcgr.h"
2627 #include "log.h"
28 #include "string_calls.h"
2729
2830 /* map for rdp to x11 scancodes
2931 code1 is regular scancode, code2 is extended scancode */
2121 #include <config_ac.h>
2222 #endif
2323
24 #include <stdarg.h>
25
2426 #include "xrdp.h"
2527 #include "log.h"
2628 #include "xrdp_configure_options.h"
29 #include "string_calls.h"
2730
2831 #if !defined(PACKAGE_VERSION)
2932 #define PACKAGE_VERSION "???"
4649 static long (*g_sync_func)(long param1, long param2);
4750
4851 /*****************************************************************************/
49 void
52 static void
5053 print_version(void)
5154 {
5255 g_writeln("xrdp %s", PACKAGE_VERSION);
5356 g_writeln(" A Remote Desktop Protocol Server.");
54 g_writeln(" Copyright (C) 2004-2018 Jay Sorg, "
55 "Neutrino Labs, and all contributors.");
57 g_writeln(" Copyright (C) 2004-2020 Jay Sorg, "
58 "Neutrino Labs, and all contributors.");
5659 g_writeln(" See https://github.com/neutrinolabs/xrdp for more information.");
5760 g_writeln("%s", "");
5861
6669 }
6770
6871 /*****************************************************************************/
69 void
72 static void
7073 print_help(void)
7174 {
7275 g_writeln("Usage: xrdp [options]");
76 g_writeln(" -k, --kill shut down xrdp");
7377 g_writeln(" -h, --help show help");
78 g_writeln(" -v, --version show version");
7479 g_writeln(" -n, --nodaemon don't fork into background");
75 g_writeln(" -k, --kill shut down xrdp");
7680 g_writeln(" -p, --port tcp listen port");
7781 g_writeln(" -f, --fork fork on new connection");
82 g_writeln(" -c, --config Specify new path to xrdp.ini");
7883 }
7984
8085 /*****************************************************************************/
136141 }
137142
138143 /*****************************************************************************/
139 void
144 static void
140145 xrdp_shutdown(int sig)
141146 {
142147 tbus threadid;
152157 }
153158
154159 /*****************************************************************************/
155 void
160 static void
156161 xrdp_child(int sig)
157162 {
158163 int safety;
163168 }
164169
165170 /*****************************************************************************/
166 void
171 static void
167172 xrdp_hang_up(int sig)
168173 {
169174 log_message(LOG_LEVEL_INFO, "caught SIGHUP, noop...");
224229 }
225230
226231 /*****************************************************************************/
227 void
232 static void
228233 pipe_sig(int sig_num)
229234 {
230235 /* do nothing */
254259
255260 tc_mutex_unlock(g_sync_mutex);
256261 }
262
263 /*****************************************************************************/
264 /**
265 * @brief looks for a case-insensitive match of a string in a list
266 * @param candidate String to match
267 * @param ... NULL-terminated list of strings to compare the candidate with
268 * @return !=0 if the candidate is found in the list
269 */
270 static int nocase_matches(const char *candidate, ...)
271 {
272 va_list vl;
273 const char *member;
274 int result = 0;
275
276 va_start(vl, candidate);
277 while ((member = va_arg(vl, const char *)) != NULL)
278 {
279 if (g_strcasecmp(candidate, member) == 0)
280 {
281 result = 1;
282 break;
283 }
284 }
285
286 va_end(vl);
287 return result;
288 }
289
257290
258291 /*****************************************************************************/
259292 /**
261294 * @brief Command line argument parser
262295 * @param number of command line arguments
263296 * @param pointer array of commandline arguments
297 * @param [out] Returned startup parameters
264298 * @return 0 on success, n on nth argument is unknown
265299 *
266300 */
267 int
301 static int
268302 xrdp_process_params(int argc, char **argv,
269303 struct xrdp_startup_params *startup_params)
270304 {
271305 int index;
272 char option[128];
273 char value[128];
306 const char *option;
307 const char *value;
274308
275309 index = 1;
276310
277311 while (index < argc)
278312 {
279 g_strncpy(option, argv[index], 127);
313 option = argv[index];
280314
281315 if (index + 1 < argc)
282316 {
283 g_strncpy(value, argv[index + 1], 127);
317 value = argv[index + 1];
284318 }
285319 else
286320 {
287 value[0] = 0;
288 }
289
290 if ((g_strncasecmp(option, "-help", 255)) == 0 ||
291 (g_strncasecmp(option, "--help", 255)) == 0 ||
292 (g_strncasecmp(option, "-h", 255)) == 0)
321 value = "";
322 }
323
324 if (nocase_matches(option, "-help", "--help", "-h", NULL))
293325 {
294326 startup_params->help = 1;
295327 }
296 else if ((g_strncasecmp(option, "-kill", 255) == 0) ||
297 (g_strncasecmp(option, "--kill", 255) == 0) ||
298 (g_strncasecmp(option, "-k", 255) == 0))
328 else if (nocase_matches(option, "-kill", "--kill", "-k", NULL))
299329 {
300330 startup_params->kill = 1;
301331 }
302 else if ((g_strncasecmp(option, "-nodaemon", 255) == 0) ||
303 (g_strncasecmp(option, "--nodaemon", 255) == 0) ||
304 (g_strncasecmp(option, "-n", 255) == 0) ||
305 (g_strncasecmp(option, "-nd", 255) == 0) ||
306 (g_strncasecmp(option, "--nd", 255) == 0) ||
307 (g_strncasecmp(option, "-ns", 255) == 0) ||
308 (g_strncasecmp(option, "--ns", 255) == 0))
332 else if (nocase_matches(option, "-nodaemon", "--nodaemon", "-n",
333 "-nd", "--nd", "-ns", "--ns", NULL))
309334 {
310335 startup_params->no_daemon = 1;
311336 }
312 else if ((g_strncasecmp(option, "-v", 255) == 0) ||
313 (g_strncasecmp(option, "--version", 255) == 0))
337 else if (nocase_matches(option, "-v", "--version", NULL))
314338 {
315339 startup_params->version = 1;
316340 }
317 else if ((g_strncasecmp(option, "-p", 255) == 0) ||
318 (g_strncasecmp(option, "--port", 255) == 0))
341 else if (nocase_matches(option, "-p", "--port", NULL))
319342 {
320343 index++;
321 g_strncpy(startup_params->port, value, 127);
344 g_strncpy(startup_params->port, value,
345 sizeof(startup_params->port) - 1);
322346
323347 if (g_strlen(startup_params->port) < 1)
324348 {
331355 startup_params->port);
332356 }
333357 }
334 else if ((g_strncasecmp(option, "-f", 255) == 0) ||
335 (g_strncasecmp(option, "--fork", 255) == 0))
358 else if (nocase_matches(option, "-f", "--fork", NULL))
336359 {
337360 startup_params->fork = 1;
338361 g_writeln("--fork parameter found, ini override");
339362 }
363 else if (nocase_matches(option, "-c", "--config", NULL))
364 {
365 index++;
366 startup_params->xrdp_ini = value;
367 }
340368 else /* unknown option */
341369 {
342370 return index;
350378
351379 /*****************************************************************************/
352380 /* Basic sanity checks before any forking */
353 int
381 static int
354382 xrdp_sanity_check(void)
355383 {
356384 int intval = 1;
357385 int host_be;
358 char key_file[256];
386 const char *key_file = XRDP_CFG_PATH "/rsakeys.ini";
359387
360388 /* check compiled endian with actual endian */
361389 host_be = !((int)(*(unsigned char *)(&intval)));
400428 return 1;
401429 }
402430
403 g_snprintf(key_file, 255, "%s/rsakeys.ini", XRDP_CFG_PATH);
404431 if (!g_file_exist(key_file))
405432 {
406433 g_writeln("File %s is missing, create it using xrdp-keygen", key_file);
416443 {
417444 int exit_status = 0;
418445 int test;
419 char cfg_file[256];
420446 enum logReturns error;
421 struct xrdp_startup_params *startup_params;
447 struct xrdp_startup_params startup_params = {0};
422448 int pid;
423449 int fd;
424 int no_daemon;
450 int daemon;
425451 char text[256];
426 char pid_file[256];
452 const char *pid_file = XRDP_PID_PATH "/xrdp.pid";
453
427454 int errored_argc;
428455
429456 g_init("xrdp");
434461 DEBUG(("Argument %i - %s", test, argv[test]));
435462 }
436463
437 g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
438
439 startup_params = (struct xrdp_startup_params *)
440 g_malloc(sizeof(struct xrdp_startup_params), 1);
441
442 errored_argc = xrdp_process_params(argc, argv, startup_params);
464 startup_params.xrdp_ini = XRDP_CFG_PATH "/xrdp.ini";
465
466 errored_argc = xrdp_process_params(argc, argv, &startup_params);
443467 if (errored_argc > 0)
444468 {
445469 print_version();
452476 g_exit(1);
453477 }
454478
455 g_snprintf(pid_file, 255, "%s/xrdp.pid", XRDP_PID_PATH);
456 no_daemon = 0;
457
458 if (startup_params->help)
479 if (startup_params.help)
459480 {
460481 print_version();
461482 g_writeln("%s", "");
465486 g_exit(0);
466487 }
467488
468 if (startup_params->version)
489 if (startup_params.version)
469490 {
470491 print_version();
471492 g_deinit();
479500 g_exit(1);
480501 }
481502
482 if (startup_params->kill)
503 if (startup_params.kill)
483504 {
484505 g_writeln("stopping xrdp");
485506 /* read the xrdp.pid file */
514535 }
515536
516537 /* starting logging subsystem */
517 error = log_start(cfg_file, "xrdp");
538 error = log_start(startup_params.xrdp_ini, "xrdp");
518539
519540 if (error != LOG_STARTUP_OK)
520541 {
521542 switch (error)
522543 {
523 case LOG_ERROR_MALLOC:
524 g_writeln("error on malloc. cannot start logging. quitting.");
525 break;
526 case LOG_ERROR_FILE_OPEN:
527 g_writeln("error opening log file [%s]. quitting.",
528 getLogFile(text, 255));
529 break;
530 default:
531 g_writeln("log_start error");
532 break;
544 case LOG_ERROR_MALLOC:
545 g_writeln("error on malloc. cannot start logging. quitting.");
546 break;
547 case LOG_ERROR_FILE_OPEN:
548 g_writeln("error opening log file [%s]. quitting.",
549 getLogFile(text, 255));
550 break;
551 case LOG_ERROR_NO_CFG:
552 g_writeln("config file %s unreadable or missing",
553 startup_params.xrdp_ini);
554 break;
555 default:
556 g_writeln("log_start error");
557 break;
533558 }
534559
535560 g_deinit();
546571 g_exit(0);
547572 }
548573
549 if (startup_params->no_daemon)
550 {
551 no_daemon = 1;
552 }
553
554
555 if (!no_daemon)
574 daemon = !startup_params.no_daemon;
575
576
577 if (daemon)
556578 {
557579
558580 /* make sure containing directory exists */
579601 g_file_delete(pid_file);
580602 }
581603
582 if (!no_daemon)
604 if (daemon)
583605 {
584606 /* if can't listen, exit with failure status */
585 if (xrdp_listen_test(startup_params) != 0)
607 if (xrdp_listen_test(&startup_params) != 0)
586608 {
587609 log_message(LOG_LEVEL_ERROR, "Failed to start xrdp daemon, "
588 "possibly address already in use.");
610 "possibly address already in use.");
589611 g_deinit();
590612 /* must exit with failure status,
591613 or systemd cannot detect xrdp daemon couldn't start properly */
674696 g_writeln("error creating g_sync_event");
675697 }
676698
677 g_listen->startup_params = startup_params;
699 g_listen->startup_params = &startup_params;
678700 exit_status = xrdp_listen_main_loop(g_listen);
679701 xrdp_listen_delete(g_listen);
680702 tc_mutex_delete(g_sync_mutex);
683705 g_delete_wait_obj(g_sync_event);
684706
685707 /* only main process should delete pid file */
686 if ((!no_daemon) && (pid == g_getpid()))
708 if (daemon && (pid == g_getpid()))
687709 {
688710 /* delete the xrdp.pid file */
689711 g_file_delete(pid_file);
690712 }
691713
692 g_free(startup_params);
693714 log_end();
694715 g_deinit();
695716
3939 g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1,
4040 long sync_param2);
4141 int
42 xrdp_child_fork(void);
43 int
4244 g_is_term(void);
4345 void
4446 g_set_term(int in_val);
4850 g_get_sync_event(void);
4951 void
5052 g_process_waiting_function(void);
51 void
52 print_version(void);
53 void
54 print_help(void);
5553
5654 /* xrdp_cache.c */
5755 struct xrdp_cache*
358356 int
359357 xrdp_login_wnd_create(struct xrdp_wm* self);
360358 int
361 load_xrdp_config(struct xrdp_config *config, int bpp);
359 load_xrdp_config(struct xrdp_config *config, const char *xrdp_ini, int bpp);
362360
363361 /* xrdp_bitmap_compress.c */
364362 int
433431 server_msg(struct xrdp_mod* mod, char* msg, int code);
434432 int
435433 server_is_term(struct xrdp_mod* mod);
436 int
437 xrdp_child_fork(void);
438434 int
439435 server_set_clip(struct xrdp_mod* mod, int x, int y, int cx, int cy);
440436 int
77 ; ports to listen on, number alone means listen on all interfaces
88 ; 0.0.0.0 or :: if ipv6 is configured
99 ; space between multiple occurrences
10 ; ALL specified interfaces must be UP when xrdp starts, otherwise xrdp will fail to start
1011 ;
1112 ; Examples:
1213 ; port=3389
5657 ssl_protocols=TLSv1.2, TLSv1.3
5758 ; set TLS cipher suites
5859 #tls_ciphers=HIGH
60
61 ; concats the domain name to the user if set for authentication with the separator
62 ; for example when the server is multi homed with SSSd
63 #domain_user_separator=@
5964
6065 ; Section name to use for automatic login if the client sends username
6166 ; and password. If empty, the domain name sent by the client is used.
7580 use_fastpath=both
7681 ; when true, userid/password *must* be passed on cmd line
7782 #require_credentials=true
83 ; when true, the userid will be used to try to authenticate
84 #enable_token_login=true
7885 ; You can set the PAM error text in a gateway setup (MAX 256 chars)
7986 #pamerrortxt=change your password according to policy at http://url
8087
142149 ls_btn_cancel_height=30
143150
144151 [Logging]
152 ; Note: Log levels can be any of: core, error, warning, info, debug, or trace
145153 LogFile=xrdp.log
146 LogLevel=DEBUG
154 LogLevel=INFO
147155 EnableSyslog=true
148 SyslogLevel=DEBUG
149 ; LogLevel and SysLogLevel could by any of: core, error, warning, info or debug
156 #SyslogLevel=INFO
157 #EnableConsole=false
158 #ConsoleLevel=INFO
159 #EnableProcessId=false
160
161 [LoggingPerLogger]
162 ; Note: per logger configuration is only used in XRDP_DEBUG builds of XRDP.
163 #xrdp.c=INFO
164 #main()=INFO
150165
151166 [Channels]
152167 ; Channel names not listed here will be blocked by XRDP.
195210 port=-1
196211 #xserverbpp=24
197212 #delay_ms=2000
213 ; Disable requested encodings to support buggy VNC servers
214 ; (1 = ExtendedDesktopSize)
215 #disabled_encodings_mask=0
216
198217
199218 [vnc-any]
200219 name=vnc-any
2424 #include <config_ac.h>
2525 #endif
2626
27 #include <limits.h>
28
2729 #include "xrdp.h"
2830 #include "log.h"
31 #include "string_calls.h"
2932
3033 #define LLOG_LEVEL 1
3134 #define LLOGLN(_level, _args) \
9396 #define CRC_END(in_crc) (in_crc) = ((in_crc) ^ 0xFFFFFFFF)
9497
9598 /*****************************************************************************/
99 /* Allocate bitmap for specified dimensions, checking for int overflow */
100 static char *
101 alloc_bitmap_data(int width, int height, int Bpp)
102 {
103 char *result = NULL;
104 if (width > 0 && height > 0 && Bpp > 0)
105 {
106 int len = width;
107 /* g_malloc() currently takes an 'int' size */
108 if (len < INT_MAX / height)
109 {
110 len *= height;
111 if (len < INT_MAX / Bpp)
112 {
113 len *= Bpp;
114 result = (char *)malloc(len);
115 }
116 }
117 }
118
119 return result;
120 }
121
122 /*****************************************************************************/
96123 struct xrdp_bitmap *
97124 xrdp_bitmap_create(int width, int height, int bpp,
98125 int type, struct xrdp_wm *wm)
122149
123150 if (self->type == WND_TYPE_BITMAP || self->type == WND_TYPE_IMAGE)
124151 {
125 self->data = (char *)g_malloc(width * height * Bpp, 0);
152 self->data = alloc_bitmap_data(width, height, Bpp);
153 if (self->data == NULL)
154 {
155 LLOGLN(0, ("xrdp_bitmap_create: size overflow %dx%dx%d",
156 width, height, Bpp));
157 g_free(self);
158 return NULL;
159 }
126160 }
127161
128162 #if defined(XRDP_PAINTER)
129163 if (self->type == WND_TYPE_SCREEN) /* noorders */
130164 {
131165 LLOGLN(0, ("xrdp_bitmap_create: noorders"));
132 self->data = (char *) g_malloc(width * height * Bpp, 0);
166 self->data = alloc_bitmap_data(width, height, Bpp);
167 if (self->data == NULL)
168 {
169 LLOGLN(0, ("xrdp_bitmap_create: size overflow %dx%dx%d",
170 width, height, Bpp));
171 g_free(self);
172 return NULL;
173 }
133174 }
134175 #endif
135176
230230 }
231231
232232 #define COMPARE_WITH_CRC32(_b1, _b2) \
233 ((_b1 != 0) && (_b2 != 0) && (_b1->crc32 == _b2->crc32) && \
233 ((_b1->crc32 == _b2->crc32) && \
234234 (_b1->bpp == _b2->bpp) && \
235235 (_b1->width == _b2->width) && (_b1->height == _b2->height))
236236
367367 for (jndex = 0; jndex < ll->count; jndex++)
368368 {
369369 cache_idx = list16_get_item(ll, jndex);
370 if (COMPARE_WITH_CRC32
371 (self->bitmap_items[cache_id][cache_idx].bitmap, bitmap))
370 lbm = self->bitmap_items[cache_id][cache_idx].bitmap;
371 if ((lbm != NULL) && COMPARE_WITH_CRC32(lbm, bitmap))
372372 {
373373 LLOGLN(10, ("found bitmap at %d %d", index, jndex));
374374 found = 1;
2323
2424 #include "xrdp_encoder.h"
2525 #include "xrdp.h"
26 #include "ms-rdpbcgr.h"
2627 #include "thread_calls.h"
2728 #include "fifo.h"
2829
5858 [default_rdp_layouts]
5959 rdp_layout_us=0x00000409
6060 rdp_layout_us_dvorak=0x00010409
61 rdp_layout_us_dvp=0x19360409
6162 rdp_layout_dk=0x00000406
6263 rdp_layout_de=0x00000407
6364 rdp_layout_es=0x0000040A
6970 rdp_layout_jp=0xe0200411
7071 rdp_layout_jp=0xe0210411
7172 rdp_layout_kr=0x00000412
73 rdp_layout_no=0x00000414
7274 rdp_layout_pl=0x00000415
7375 rdp_layout_br=0x00000416
7476 rdp_layout_ru=0x00000419
8486 [default_layouts_map]
8587 rdp_layout_us=us
8688 rdp_layout_us_dvorak=dvorak
89 rdp_layout_us_dvp=us(dvp)
8790 rdp_layout_dk=dk
8891 rdp_layout_de=de
8992 rdp_layout_es=es
9295 rdp_layout_it=it
9396 rdp_layout_jp=jp
9497 rdp_layout_kr=kr
98 rdp_layout_no=no
9599 rdp_layout_pl=pl
96100 rdp_layout_br=br(abnt2)
97101 rdp_layout_ru=ru
121125 [rdp_layouts_map_mac]
122126 rdp_layout_us=us
123127 rdp_layout_us_dvorak=dvorak
128 rdp_layout_us_dvp=us(dvp)
124129 rdp_layout_dk=dk
125130 rdp_layout_de=de
126131 rdp_layout_es=es
2323
2424 #include "xrdp.h"
2525 #include "log.h"
26 #include "string_calls.h"
2627
2728 /* 'g_process' is protected by the semaphore 'g_process_sem'. One thread sets
2829 g_process and waits for the other to process it */
163164 char *val;
164165 struct list *names;
165166 struct list *values;
166 char cfg_file[256];
167167 struct xrdp_startup_params *startup_params;
168168
169169 startup_params = self->startup_params;
170170 port_override = startup_params->port[0] != 0;
171171 fork_override = startup_params->fork;
172 g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
173 fd = g_file_open(cfg_file);
172 fd = g_file_open(startup_params->xrdp_ini);
174173 if (fd != -1)
175174 {
176175 names = list_create();
2424 #include "base64.h"
2525 #include "xrdp.h"
2626 #include "log.h"
27 #include "string_calls.h"
2728
2829 #define ASK "ask"
2930 #define ASK_LEN g_strlen(ASK)
558559 char *q;
559560 char *r;
560561 char name[256];
561 char cfg_file[256];
562562 struct xrdp_mod_data *mod_data;
563 const char *xrdp_ini = self->session->xrdp_ini;
563564
564565 sections = list_create();
565566 sections->auto_free = 1;
567568 section_names->auto_free = 1;
568569 section_values = list_create();
569570 section_values->auto_free = 1;
570 g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
571 fd = g_file_open(cfg_file); /* xrdp.ini */
571 fd = g_file_open(xrdp_ini);
572572
573573 if (fd < 0)
574574 {
575 log_message(LOG_LEVEL_ERROR, "Could not read xrdp ini file %s", cfg_file);
575 log_message(LOG_LEVEL_ERROR, "Could not read xrdp ini file %s",
576 xrdp_ini);
576577 list_delete(sections);
577578 list_delete(section_names);
578579 list_delete(section_values);
588589
589590 if ((g_strncasecmp(p, "globals", 255) == 0)
590591 || (g_strncasecmp(p, "channels", 255) == 0)
591 || (g_strncasecmp(p, "Logging", 255) == 0))
592 || (g_strncasecmp(p, "Logging", 255) == 0)
593 || (g_strncasecmp(p, "LoggingPerLogger", 255) == 0))
592594 {
593595 }
594596 else
828830 /**
829831 * Load configuration from xrdp.ini file
830832 *
833 * @param config XRDP configuration to initialise
834 * @param xrdp_ini Path to xrdp.ini
835 * @param bpp bits-per-pixel for this connection
836 *
831837 * @return 0 on success, -1 on failure
832838 *****************************************************************************/
833839 int
834 load_xrdp_config(struct xrdp_config *config, int bpp)
840 load_xrdp_config(struct xrdp_config *config, const char *xrdp_ini, int bpp)
835841 {
836842 struct xrdp_cfg_globals *globals;
837843
840846
841847 char *n;
842848 char *v;
843 char buf[256];
844849 int fd;
845850 int i;
846851
872877 globals->ls_btn_cancel_height = 30;
873878
874879 /* open xrdp.ini file */
875 g_snprintf(buf, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
876 if ((fd = g_file_open(buf)) < 0)
880 if ((fd = g_file_open(xrdp_ini)) < 0)
877881 {
878882 log_message(LOG_LEVEL_ERROR,"load_config: Could not read "
879 "xrdp.ini file %s", buf);
883 "xrdp.ini file %s", xrdp_ini);
880884 return -1;
881885
882886 }
892896 list_delete(values);
893897 g_file_close(fd);
894898 log_message(LOG_LEVEL_ERROR,"load_config: Could not read globals "
895 "section from xrdp.ini file %s", buf);
899 "section from xrdp.ini file %s", xrdp_ini);
896900 return -1;
897901 }
898902
9991003
10001004 else if (g_strncmp(n, "allow_multimon", 64) == 0)
10011005 globals->allow_multimon = g_text2bool(v);
1006
1007 else if (g_strncmp(n, "enable_token_login", 64) == 0) {
1008 log_message(LOG_LEVEL_DEBUG, "Token login detection enabled x");
1009 globals->enable_token_login = g_text2bool(v);
1010 }
10021011
10031012 /* login screen values */
10041013 else if (g_strncmp(n, "ls_top_window_bg_color", 64) == 0)
11081117 g_writeln("new_cursors: %d", globals->new_cursors);
11091118 g_writeln("nego_sec_layer: %d", globals->nego_sec_layer);
11101119 g_writeln("allow_multimon: %d", globals->allow_multimon);
1120 g_writeln("enable_token_login: %d", globals->enable_token_login)
11111121
11121122 g_writeln("ls_top_window_bg_color: %x", globals->ls_top_window_bg_color);
11131123 g_writeln("ls_width: %d", globals->ls_width);
11141124 g_writeln("ls_height: %d", globals->ls_height);
11151125 g_writeln("ls_bg_color: %x", globals->ls_bg_color);
1116 g_writeln("ls_title: %s", globals->ls_title);
1126 g_writeln("ls_title: %s", globals->ls_title);
11171127 g_writeln("ls_logo_filename: %s", globals->ls_logo_filename);
11181128 g_writeln("ls_logo_x_pos: %d", globals->ls_logo_x_pos);
11191129 g_writeln("ls_logo_y_pos: %d", globals->ls_logo_y_pos);
2222 #endif
2323 #include "xrdp.h"
2424 #include "log.h"
25 #include "string_calls.h"
2526
2627 #ifndef USE_NOPAM
2728 #if defined(HAVE__PAM_TYPES_H)
160161
161162 /*****************************************************************************/
162163 /* Send login information to sesman */
164 /* FIXME : This code duplicates functionality in the sesman tools sesrun.c.
165 * When SCP is reworked, a common library function should be used */
166
163167 static int
164168 xrdp_mm_send_login(struct xrdp_mm *self)
165169 {
470474 self->mod->server_composite = server_composite;
471475 self->mod->server_paint_rects = server_paint_rects;
472476 self->mod->server_session_info = server_session_info;
473 self->mod->si = (tintptr) &(self->wm->session->si);
477 self->mod->si = &(self->wm->session->si);
474478 }
475479 }
476480
15521556 }
15531557
15541558 /*****************************************************************************/
1559 /* FIXME : This code duplicates functionality in the sesman tools sesrun.c.
1560 * When SCP is reworked, a common library function should be used */
15551561 static int
15561562 xrdp_mm_process_login_response(struct xrdp_mm *self, struct stream *s)
15571563 {
32603266 }
32613267
32623268 /*****************************************************************************/
3269
3270 /* Note : if this is called on a multimon setup, the client is resized
3271 * to a single monitor */
32633272 int
32643273 server_reset(struct xrdp_mod *mod, int width, int height, int bpp)
32653274 {
32783287 return 0;
32793288 }
32803289
3281 /* if same, don't need to do anything */
3290 /* if same (and only one monitor on client) don't need to do anything */
32823291 if (wm->client_info->width == width &&
3283 wm->client_info->height == height &&
3284 wm->client_info->bpp == bpp)
3292 wm->client_info->height == height &&
3293 wm->client_info->bpp == bpp &&
3294 (wm->client_info->monitorCount == 0 || wm->client_info->multimon == 0))
32853295 {
32863296 return 0;
32873297 }
2222 #endif
2323
2424 #include "xrdp.h"
25 #include "string_calls.h"
2526
2627 #if defined(XRDP_PAINTER)
2728 #include <painter.h> /* libpainter */
234234 self->server_trans->trans_data_in = xrdp_process_data_in;
235235 self->server_trans->callback_data = self;
236236 init_stream(self->server_trans->in_s, 8192 * 4);
237 self->session = libxrdp_init((tbus)self, self->server_trans);
237 self->session = libxrdp_init((tbus)self, self->server_trans,
238 self->lis_layer->startup_params->xrdp_ini);
238239 self->server_trans->si = &(self->session->si);
239240 self->server_trans->my_source = XRDP_SOURCE_CLIENT;
240241 /* this callback function is in xrdp_wm.c */
2929
3030 #define MAX_NR_CHANNELS 16
3131 #define MAX_CHANNEL_NAME 16
32
33 struct source_info;
34
3235 /* lib */
3336 struct xrdp_mod
3437 {
155158 tintptr handle; /* pointer to self as int */
156159 tintptr wm; /* struct xrdp_wm* */
157160 tintptr painter;
158 tintptr si;
161 struct source_info *si;
159162 };
160163
161164 /* header for bmp file */
527530
528531 struct xrdp_startup_params
529532 {
533 /* xrdp_ini is not malloc'd and has at least the same lifetime as main() */
534 const char *xrdp_ini;
530535 char port[1024];
531536 int kill;
532537 int no_daemon;
565570 int new_cursors;
566571 int nego_sec_layer;
567572 int allow_multimon;
573 int enable_token_login;
568574
569575 /* colors */
570576
2424 #include <stdarg.h>
2525 #include <stdio.h>
2626 #include "xrdp.h"
27 #include "ms-rdpbcgr.h"
2728 #include "log.h"
29 #include "string_calls.h"
2830
2931 #define LLOG_LEVEL 1
3032 #define LLOGLN(_level, _args) \
394396 char *val;
395397 struct list *names;
396398 struct list *values;
397 char cfg_file[256];
398399
399400 if (autorun_name != 0)
400401 {
413414 self->background = HCOLOR(self->screen->bpp, 0x000000);
414415
415416 /* now load them from the globals in xrdp.ini if defined */
416 g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
417 fd = g_file_open(cfg_file);
417 fd = g_file_open(self->session->xrdp_ini);
418418
419419 if (fd >= 0)
420420 {
505505 }
506506 else
507507 {
508 log_message(LOG_LEVEL_ERROR,"xrdp_wm_load_static_colors: Could not read xrdp.ini file %s", cfg_file);
508 log_message(LOG_LEVEL_ERROR,"xrdp_wm_load_static_colors: Could not read xrdp.ini file %s", self->session->xrdp_ini);
509509 }
510510
511511 if (self->screen->bpp == 8)
567567 char param[256];
568568 char default_section_name[256];
569569 char section_name[256];
570 char cfg_file[256];
571570 char autorun_name[256];
572571
573572 g_writeln("in xrdp_wm_init: ");
574573
575 load_xrdp_config(self->xrdp_config, self->screen->bpp);
574 load_xrdp_config(self->xrdp_config, self->session->xrdp_ini,
575 self->screen->bpp);
576576
577577 /* global channels allow */
578578 names = list_create();
579579 names->auto_free = 1;
580580 values = list_create();
581581 values->auto_free = 1;
582 g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
583 if (file_by_name_read_section(cfg_file, "Channels", names, values) == 0)
582 if (file_by_name_read_section(self->session->xrdp_ini,
583 "Channels", names, values) == 0)
584584 {
585585 int error;
586586 int ii;
647647 * NOTE: this should eventually be accessed from self->xrdp_config
648648 */
649649
650 g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH);
651 fd = g_file_open(cfg_file); /* xrdp.ini */
650 fd = g_file_open(self->session->xrdp_ini);
652651 if (fd != -1)
653652 {
654653 names = list_create();
665664 q = (char *)list_get_item(names, index);
666665 if ((g_strncasecmp("globals", q, 8) != 0) &&
667666 (g_strncasecmp("Logging", q, 8) != 0) &&
667 (g_strncasecmp("LoggingPerLogger", q, 17) != 0) &&
668668 (g_strncasecmp("channels", q, 9) != 0))
669669 {
670670 g_strncpy(default_section_name, q, 255);
788788 }
789789 else
790790 {
791 log_message(LOG_LEVEL_ERROR,"xrdp_wm_init: Could not read xrdp.ini file %s", cfg_file);
791 log_message(LOG_LEVEL_ERROR,
792 "xrdp_wm_init: Could not read xrdp.ini file %s",
793 self->session->xrdp_ini);
792794 }
793795 }
794796 else
911913 self->painter->brush.pattern[6] = 0xaa;
912914 self->painter->brush.pattern[7] = 0x55;
913915 self->painter->brush.x_origin = 0;
914 self->painter->brush.x_origin = 0;
916 self->painter->brush.y_origin = 0;
915917 self->painter->brush.style = 3;
916918 self->painter->bg_color = self->black;
917919 self->painter->fg_color = self->white;
13381340 self->mm->mod->mod_event(self->mm->mod, WM_BUTTON3UP, x, y, 0, 0);
13391341 }
13401342
1343 if (but == 8 && down)
1344 {
1345 self->mm->mod->mod_event(self->mm->mod, WM_BUTTON8DOWN, x, y, 0, 0);
1346 }
1347 else if (but == 8 && !down)
1348 {
1349 self->mm->mod->mod_event(self->mm->mod, WM_BUTTON8UP, x, y, 0, 0);
1350 }
1351 if (but == 9 && down)
1352 {
1353 self->mm->mod->mod_event(self->mm->mod, WM_BUTTON9DOWN, x, y, 0, 0);
1354 }
1355 else if (but == 9 && !down)
1356 {
1357 self->mm->mod->mod_event(self->mm->mod, WM_BUTTON9UP, x, y, 0, 0);
1358 }
13411359 /* vertical scroll */
13421360
13431361 if (but == 4)
15111529 if (self->popup_wnd != 0)
15121530 {
15131531 xrdp_wm_clear_popup(self);
1532 return 0;
1533 }
1534
1535 // workaround odd shift behavior
1536 // see https://github.com/neutrinolabs/xrdp/issues/397
1537 if (scan_code == 42 && device_flags == (KBD_FLAG_UP | KBD_FLAG_EXT)) {
15141538 return 0;
15151539 }
15161540
18001824 {
18011825 if (device_flags & PTRXFLAGS_BUTTON1)
18021826 {
1803 xrdp_wm_mouse_click(self, x, y, 6, 1);
1827 xrdp_wm_mouse_click(self, x, y, 8, 1);
18041828 }
18051829 else if (device_flags & PTRXFLAGS_BUTTON2)
18061830 {
1807 xrdp_wm_mouse_click(self, x, y, 7, 1);
1831 xrdp_wm_mouse_click(self, x, y, 9, 1);
18081832 }
18091833 }
18101834 else
18111835 {
18121836 if (device_flags & PTRXFLAGS_BUTTON1)
18131837 {
1814 xrdp_wm_mouse_click(self, x, y, 6, 0);
1838 xrdp_wm_mouse_click(self, x, y, 8, 0);
18151839 }
18161840 else if (device_flags & PTRXFLAGS_BUTTON2)
18171841 {
1818 xrdp_wm_mouse_click(self, x, y, 7, 0);
1842 xrdp_wm_mouse_click(self, x, y, 9, 0);
18191843 }
18201844 }
18211845 return 0;
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
922922 index += bytes_written;
923923 bytes_to_send -= bytes_written;
924924
925 if ((rv == 0) && (bytes_to_send == 0))
926 {
927 return 0;
928 }
929
930925 usleep(1000 * 3);
931926 }
932927 }
0 # Makefile.in generated by automake 1.16.1 from Makefile.am.
0 # Makefile.in generated by automake 1.16.3 from Makefile.am.
11 # @configure_input@
22
3 # Copyright (C) 1994-2018 Free Software Foundation, Inc.
3 # Copyright (C) 1994-2020 Free Software Foundation, Inc.
44
55 # This Makefile.in is free software; the Free Software Foundation
66 # gives unlimited permission to copy and/or distribute it,
2424 #include "xup.h"
2525 #include "log.h"
2626 #include "trans.h"
27 #include "string_calls.h"
2728
2829 #define LOG_LEVEL 1
2930 #define LLOG(_level, _args) \
148149 int use_uds;
149150 struct stream *s;
150151 char con_port[256];
151 struct source_info *si;
152152
153153 LIB_DEBUG(mod, "in lib_mod_connect");
154154
202202 }
203203 }
204204
205 si = (struct source_info *) (mod->si);
206 mod->trans->si = si;
205 mod->trans->si = mod->si;
207206 mod->trans->my_source = XRDP_SOURCE_MOD;
208207
209208 while (1)
15451544 {
15461545 if (g_strcasecmp(name, "username") == 0)
15471546 {
1548 g_strncpy(mod->username, value, 255);
1547 g_strncpy(mod->username, value, INFO_CLIENT_MAX_CB_LEN-1);
15491548 }
15501549 else if (g_strcasecmp(name, "password") == 0)
15511550 {
1552 g_strncpy(mod->password, value, 255);
1551 g_strncpy(mod->password, value, INFO_CLIENT_MAX_CB_LEN-1);
15531552 }
15541553 else if (g_strcasecmp(name, "ip") == 0)
15551554 {
2323 #include "os_calls.h"
2424 #include "defines.h"
2525 #include "xrdp_client_info.h"
26 #include "xrdp_constants.h"
2627 #include "xrdp_rail.h"
2728
2829 #define CURRENT_MOD_VER 4
30
31 struct source_info;
2932
3033 struct mod
3134 {
147150 tintptr handle; /* pointer to self as long */
148151 tintptr wm;
149152 tintptr painter;
150 tintptr si;
153 struct source_info *si;
151154 /* mod data */
152155 int width;
153156 int height;
154157 int bpp;
155158 int sck_closed;
156 char username[256];
157 char password[256];
159 char username[INFO_CLIENT_MAX_CB_LEN];
160 char password[INFO_CLIENT_MAX_CB_LEN];
158161 char ip[256];
159162 char port[256];
160163 int shift_state;