diff --git a/.gitignore b/.gitignore index 473d203..d48d90b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/tigervnc-1.10.1.tar.gz +SOURCES/tigervnc-1.11.0.tar.gz diff --git a/.tigervnc.metadata b/.tigervnc.metadata index 957f8a1..c7c0b3c 100644 --- a/.tigervnc.metadata +++ b/.tigervnc.metadata @@ -1 +1 @@ -34efc6e2e67be672dca38c10ce064bcb08adee9f SOURCES/tigervnc-1.10.1.tar.gz +6f6b621a76b734888748de10c32c2b5b59d40b19 SOURCES/tigervnc-1.11.0.tar.gz diff --git a/SOURCES/0001-rpath-hack.patch b/SOURCES/0001-rpath-hack.patch index 689de34..4e438dd 100644 --- a/SOURCES/0001-rpath-hack.patch +++ b/SOURCES/0001-rpath-hack.patch @@ -15,14 +15,10 @@ diff --git a/configure.ac b/configure.ac index fa15a2d..a5af1e0 100644 --- a/configure.ac +++ b/configure.ac -@@ -1357,6 +1357,7 @@ else - fi - AM_CONDITIONAL(GLX, test "x$GLX" = xyes) - +@@ -1261,6 +1261,7 @@ AM_CONDITIONAL(GLX, test "x$GLX" = xyes) + + AM_CONDITIONAL(HASHTABLE, test "x$HASHTABLE" = xyes) + +GLX_SYS_LIBS="$GLX_SYS_LIBS -Wl,-rpath=\$(libdir)" AC_SUBST([GLX_DEFINES]) AC_SUBST([GLX_SYS_LIBS]) - --- -2.5.0 - diff --git a/SOURCES/0001-xserver-add-no-op-input-thread-init-function.patch b/SOURCES/0001-xserver-add-no-op-input-thread-init-function.patch deleted file mode 100644 index b67127b..0000000 --- a/SOURCES/0001-xserver-add-no-op-input-thread-init-function.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 920d9c4d6562ecabf79497bc901d50522d4bc661 Mon Sep 17 00:00:00 2001 -From: Linus Heckemann -Date: Sat, 1 Feb 2020 11:08:26 +0100 -Subject: [PATCH] xserver: add no-op input thread init function - -This allows Xvnc to build with xorg-server 1.20.7, which requires OS -layers to implement a ddxInputThreadInit function when configured with ---enable-input-thread (the default). - -relevant xorg-server commit: e3f26605d85d987da434640f52646d728f1fe919 ---- - unix/xserver/hw/vnc/Input.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/unix/xserver/hw/vnc/Input.c b/unix/xserver/hw/vnc/Input.c -index 534e435e..b342d4d6 100644 ---- a/unix/xserver/hw/vnc/Input.c -+++ b/unix/xserver/hw/vnc/Input.c -@@ -711,3 +711,12 @@ static void vncKeysymKeyboardEvent(KeySym keysym, int down) - */ - mieqProcessInputEvents(); - } -+ -+#if INPUTTHREAD -+/** This function is called in Xserver/os/inputthread.c when starting -+ the input thread. */ -+void -+ddxInputThreadInit(void) -+{ -+} -+#endif --- -2.24.1 - diff --git a/SOURCES/tigervnc-correctly-start-vncsession-as-daemon.patch b/SOURCES/tigervnc-correctly-start-vncsession-as-daemon.patch new file mode 100644 index 0000000..af5e7f2 --- /dev/null +++ b/SOURCES/tigervnc-correctly-start-vncsession-as-daemon.patch @@ -0,0 +1,13 @@ +diff --git a/unix/vncserver/vncsession.c b/unix/vncserver/vncsession.c +index 2b47f5f5..f78c096f 100644 +--- a/unix/vncserver/vncsession.c ++++ b/unix/vncserver/vncsession.c +@@ -99,7 +99,7 @@ begin_daemon(void) + return -1; + } + +- if (pid == 0) ++ if (pid != 0) + _exit(0); + + /* Send all stdio to /dev/null */ diff --git a/SOURCES/tigervnc-provide-correct-dimensions-for-xshm-setup.patch b/SOURCES/tigervnc-provide-correct-dimensions-for-xshm-setup.patch deleted file mode 100644 index cefc769..0000000 --- a/SOURCES/tigervnc-provide-correct-dimensions-for-xshm-setup.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 0f1ded057dbf875e69a0d72418d95610db8fa6a3 Mon Sep 17 00:00:00 2001 -From: Pierre Ossman -Date: Mon, 30 Dec 2019 10:50:52 +0100 -Subject: [PATCH] Provide correct dimensions for XShm setup - -Since 53f913a we initialize the underlying PixelBuffer with 0x0 -dimensions, which means we need to keep more explicit track of what -we are trying to allocate in the setup methods. ---- - vncviewer/PlatformPixelBuffer.cxx | 6 +++--- - vncviewer/PlatformPixelBuffer.h | 2 +- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/vncviewer/PlatformPixelBuffer.cxx b/vncviewer/PlatformPixelBuffer.cxx -index 61f7b743b..59e51d596 100644 ---- a/vncviewer/PlatformPixelBuffer.cxx -+++ b/vncviewer/PlatformPixelBuffer.cxx -@@ -43,7 +43,7 @@ PlatformPixelBuffer::PlatformPixelBuffer(int width, int height) : - #endif - { - #if !defined(WIN32) && !defined(__APPLE__) -- if (!setupShm()) { -+ if (!setupShm(width, height)) { - xim = XCreateImage(fl_display, CopyFromParent, 32, - ZPixmap, 0, 0, width, height, 32, 0); - if (!xim) -@@ -136,7 +136,7 @@ static int XShmAttachErrorHandler(Display *dpy, XErrorEvent *error) - return 0; - } - --bool PlatformPixelBuffer::setupShm() -+bool PlatformPixelBuffer::setupShm(int width, int height) - { - int major, minor; - Bool pixmaps; -@@ -153,7 +153,7 @@ bool PlatformPixelBuffer::setupShm() - shminfo = new XShmSegmentInfo; - - xim = XShmCreateImage(fl_display, CopyFromParent, 32, -- ZPixmap, 0, shminfo, width(), height()); -+ ZPixmap, 0, shminfo, width, height); - if (!xim) - goto free_shminfo; - -diff --git a/vncviewer/PlatformPixelBuffer.h b/vncviewer/PlatformPixelBuffer.h -index f9038cd9c..ec439f64f 100644 ---- a/vncviewer/PlatformPixelBuffer.h -+++ b/vncviewer/PlatformPixelBuffer.h -@@ -53,7 +53,7 @@ class PlatformPixelBuffer: public rfb::FullFramePixelBuffer, public Surface { - - #if !defined(WIN32) && !defined(__APPLE__) - protected: -- bool setupShm(); -+ bool setupShm(int width, int height); - - protected: - XShmSegmentInfo *shminfo; diff --git a/SOURCES/tigervnc-remove-trailing-spaces-in-user-name.patch b/SOURCES/tigervnc-remove-trailing-spaces-in-user-name.patch deleted file mode 100644 index da47b03..0000000 --- a/SOURCES/tigervnc-remove-trailing-spaces-in-user-name.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 989491eb4b325f980e94d27e0ad1a7bee63b6ebd Mon Sep 17 00:00:00 2001 -From: Jan Grulich -Date: Fri, 3 Jul 2020 13:56:35 +0200 -Subject: [PATCH] Remove trailing spaces in user name - -It's quite easy to make a mistake and add an additional space when configuring -users in the vncserver.users config file. You will then get an error that the -user doesn't exist and it's hard to spot the mistake. Same applies for a space -before the display number. ---- - unix/vncserver/vncsession-start.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/unix/vncserver/vncsession-start.in b/unix/vncserver/vncsession-start.in -index b20fcdd97..65ee0a81c 100644 ---- a/unix/vncserver/vncsession-start.in -+++ b/unix/vncserver/vncsession-start.in -@@ -33,7 +33,7 @@ fi - - DISPLAY="$1" - --USER=`grep "^${DISPLAY}=" "${USERSFILE}" 2>/dev/null | head -1 | cut -d = -f 2-` -+USER=`grep "^ *${DISPLAY}=" "${USERSFILE}" 2>/dev/null | head -1 | cut -d = -f 2- | sed 's/ *$//g'` - - if [ -z "${USER}" ]; then - echo "No user configured for display ${DISPLAY}" >&2 diff --git a/SOURCES/tigervnc-systemd-service.patch b/SOURCES/tigervnc-systemd-service.patch new file mode 100644 index 0000000..846a34b --- /dev/null +++ b/SOURCES/tigervnc-systemd-service.patch @@ -0,0 +1,47 @@ +From 40f104ffe1e36df9613f8d316f616fb2b089cc86 Mon Sep 17 00:00:00 2001 +From: Jan Grulich +Date: Tue, 29 Sep 2020 13:37:16 +0200 +Subject: [PATCH] Use /run instead of /var/run which is just a symlink + +--- + unix/vncserver/selinux/vncsession.fc | 2 +- + unix/vncserver/vncserver@.service.in | 2 +- + unix/vncserver/vncsession.c | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/unix/vncserver/selinux/vncsession.fc b/unix/vncserver/selinux/vncsession.fc +index 121cdd237..ae768baa4 100644 +--- a/unix/vncserver/selinux/vncsession.fc ++++ b/unix/vncserver/selinux/vncsession.fc +@@ -23,4 +23,4 @@ HOME_ROOT/\.vnc(/.*)? gen_context(system_u:object_r:xdm_home_t,s0) + /usr/sbin/vncsession -- gen_context(system_u:object_r:vnc_session_exec_t,s0) + /usr/libexec/vncsession-start -- gen_context(system_u:object_r:vnc_session_exec_t,s0) + +-/var/run/vncsession-:[0-9]*\.pid -- gen_context(system_u:object_r:vnc_session_var_run_t,s0) ++/run/vncsession-:[0-9]*\.pid -- gen_context(system_u:object_r:vnc_session_var_run_t,s0) +diff --git a/unix/vncserver/vncserver@.service.in b/unix/vncserver/vncserver@.service.in +index 584ecf4b1..5624dff76 100644 +--- a/unix/vncserver/vncserver@.service.in ++++ b/unix/vncserver/vncserver@.service.in +@@ -36,7 +36,7 @@ After=syslog.target network.target + [Service] + Type=forking + ExecStart=@CMAKE_INSTALL_FULL_LIBEXECDIR@/vncsession-start %i +-PIDFile=/var/run/vncsession-%i.pid ++PIDFile=/run/vncsession-%i.pid + SELinuxContext=system_u:system_r:vnc_session_t:s0 + + [Install] +diff --git a/unix/vncserver/vncsession.c b/unix/vncserver/vncsession.c +index 3e0c98f0f..2b47f5f55 100644 +--- a/unix/vncserver/vncsession.c ++++ b/unix/vncserver/vncsession.c +@@ -543,7 +543,7 @@ main(int argc, char **argv) + } + + snprintf(pid_file, sizeof(pid_file), +- "/var/run/vncsession-%s.pid", display); ++ "/run/vncsession-%s.pid", display); + f = fopen(pid_file, "w"); + if (f == NULL) { + syslog(LOG_ERR, "Failure creating pid file \"%s\": %s", diff --git a/SOURCES/tigervnc-systemd-support.patch b/SOURCES/tigervnc-systemd-support.patch deleted file mode 100644 index 3b56cd8..0000000 --- a/SOURCES/tigervnc-systemd-support.patch +++ /dev/null @@ -1,2176 +0,0 @@ -From 8f09de712b53e54d15d2bd5367c10a61c57cda23 Mon Sep 17 00:00:00 2001 -From: Jan Grulich -Date: Wed, 6 May 2020 10:37:21 +0200 -Subject: Foo - - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 2d19b72..78eb93d 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -7,6 +7,10 @@ if(POLICY CMP0022) - cmake_policy(SET CMP0022 OLD) - endif() - -+if(${CMAKE_VERSION} VERSION_LESS "3.4.0") -+ message(WARNING "CMake 3.4.0 or newer is required to get correct default installation paths") -+endif() -+ - # Internal cmake modules - set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules) - -@@ -27,17 +31,16 @@ set(VERSION 1.10.1) - set(RCVERSION 1,10,1,0) - - # Installation paths --set(BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin") --set(DATA_DIR "${CMAKE_INSTALL_PREFIX}/share") --set(MAN_DIR "${DATA_DIR}/man") --set(LOCALE_DIR "${DATA_DIR}/locale") --set(DOC_DIR "${CMAKE_INSTALL_PREFIX}/share/doc/${CMAKE_PROJECT_NAME}-${VERSION}") -- --if(WIN32) --set(BIN_DIR "${CMAKE_INSTALL_PREFIX}") --set(DOC_DIR "${CMAKE_INSTALL_PREFIX}") -+include(GNUInstallDirs) -+set(CMAKE_INSTALL_UNITDIR "lib/systemd/system" CACHE PATH "systemd unit files (lib/systemd/system)") -+if(IS_ABSOLUTE "${CMAKE_INSTALL_UNITDIR}") -+ set(CMAKE_INSTALL_FULL_UNITDIR "${CMAKE_INSTALL_UNITDIR}") -+else() -+ set(CMAKE_INSTALL_FULL_UNITDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_UNITDIR}") - endif() - -+option(INSTALL_SYSTEMD_UNITS "Install TigerVNC systemd units" ON) -+ - if(MSVC) - message(FATAL_ERROR "TigerVNC cannot be built with Visual Studio. Please use MinGW") - endif() -@@ -259,8 +262,7 @@ if(ENABLE_GNUTLS) - endif() - - # Check for PAM library --option(ENABLE_PAM "Enable PAM authentication support" ON) --if(ENABLE_PAM) -+if(UNIX AND NOT APPLE) - check_include_files(security/pam_appl.h HAVE_PAM_H) - set(CMAKE_REQUIRED_LIBRARIES -lpam) - check_function_exists(pam_start HAVE_PAM_START) -@@ -268,10 +270,9 @@ if(ENABLE_PAM) - if(HAVE_PAM_H AND HAVE_PAM_START) - set(PAM_LIBS pam) - else() -- set(ENABLE_PAM 0) -+ message(FATAL_ERROR "Could not find PAM development files") - endif() - endif() --set(HAVE_PAM ${ENABLE_PAM}) - - # Generate config.h and make sure the source finds it - configure_file(config.h.in config.h) -diff --git a/cmake/BuildPackages.cmake b/cmake/BuildPackages.cmake -index ec96318..1f25192 100644 ---- a/cmake/BuildPackages.cmake -+++ b/cmake/BuildPackages.cmake -@@ -86,5 +86,5 @@ endif() #UNIX - # Common - # - --install(FILES ${CMAKE_SOURCE_DIR}/LICENCE.TXT DESTINATION ${DOC_DIR}) --install(FILES ${CMAKE_SOURCE_DIR}/README.rst DESTINATION ${DOC_DIR}) -+install(FILES ${CMAKE_SOURCE_DIR}/LICENCE.TXT DESTINATION ${CMAKE_INSTALL_FULL_DOCDIR}) -+install(FILES ${CMAKE_SOURCE_DIR}/README.rst DESTINATION ${CMAKE_INSTALL_FULL_DOCDIR}) -diff --git a/cmake/StaticBuild.cmake b/cmake/StaticBuild.cmake -index e539619..793b190 100644 ---- a/cmake/StaticBuild.cmake -+++ b/cmake/StaticBuild.cmake -@@ -115,7 +115,7 @@ endif() - if(BUILD_STATIC_GCC) - # This ensures that we don't depend on libstdc++ or libgcc_s - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -nodefaultlibs") -- set(STATIC_BASE_LIBRARIES "-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic") -+ set(STATIC_BASE_LIBRARIES "") - if(ENABLE_ASAN AND NOT WIN32 AND NOT APPLE) - set(STATIC_BASE_LIBRARIES "${STATIC_BASE_LIBRARIES} -Wl,-Bstatic -lasan -Wl,-Bdynamic -ldl -lm -lpthread") - endif() -@@ -135,5 +135,6 @@ if(BUILD_STATIC_GCC) - else() - set(STATIC_BASE_LIBRARIES "${STATIC_BASE_LIBRARIES} -lgcc -lgcc_eh -lc") - endif() -- set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} ${STATIC_BASE_LIBRARIES}") -+ set(CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_LINK_EXECUTABLE} ${STATIC_BASE_LIBRARIES}") -+ set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic ${STATIC_BASE_LIBRARIES}") - endif() -diff --git a/common/rfb/CMakeLists.txt b/common/rfb/CMakeLists.txt -index 8e532a2..689cdcc 100644 ---- a/common/rfb/CMakeLists.txt -+++ b/common/rfb/CMakeLists.txt -@@ -75,7 +75,7 @@ endif(WIN32) - - set(RFB_LIBRARIES ${JPEG_LIBRARIES} os rdr Xregion) - --if(HAVE_PAM) -+if(UNIX AND NOT APPLE) - set(RFB_SOURCES ${RFB_SOURCES} UnixPasswordValidator.cxx - UnixPasswordValidator.h pam.c pam.h) - set(RFB_LIBRARIES ${RFB_LIBRARIES} ${PAM_LIBS}) -diff --git a/common/rfb/SSecurityPlain.cxx b/common/rfb/SSecurityPlain.cxx -index 6f72432..f577c0d 100644 ---- a/common/rfb/SSecurityPlain.cxx -+++ b/common/rfb/SSecurityPlain.cxx -@@ -25,10 +25,10 @@ - #include - #include - #include --#ifdef HAVE_PAM -+#if !defined(WIN32) && !defined(__APPLE__) - #include - #endif --#ifdef BUILD_WIN -+#ifdef WIN32 - #include - #endif - -@@ -62,10 +62,10 @@ bool PasswordValidator::validUser(const char* username) - - SSecurityPlain::SSecurityPlain(SConnection* sc) : SSecurity(sc) - { --#ifdef HAVE_PAM -- valid = new UnixPasswordValidator(); --#elif BUILD_WIN -+#ifdef WIN32 - valid = new WinPasswdValidator(); -+#elif !defined(__APPLE__) -+ valid = new UnixPasswordValidator(); - #else - valid = NULL; - #endif -diff --git a/common/rfb/UnixPasswordValidator.cxx b/common/rfb/UnixPasswordValidator.cxx -index d096079..ee7bc0d 100644 ---- a/common/rfb/UnixPasswordValidator.cxx -+++ b/common/rfb/UnixPasswordValidator.cxx -@@ -25,9 +25,7 @@ - #include - #include - #include --#ifdef HAVE_PAM - #include --#endif - - using namespace rfb; - -@@ -43,10 +41,6 @@ bool UnixPasswordValidator::validateInternal(SConnection * sc, - const char *username, - const char *password) - { --#ifdef HAVE_PAM - CharArray service(strDup(pamService.getData())); - return do_pam_auth(service.buf, username, password); --#else -- throw AuthFailureException("PAM not supported"); --#endif - } -diff --git a/common/rfb/pam.c b/common/rfb/pam.c -index cb067fd..acac0f4 100644 ---- a/common/rfb/pam.c -+++ b/common/rfb/pam.c -@@ -22,9 +22,6 @@ - #include - #endif - --#ifndef HAVE_PAM --#error "This source should not be compiled when PAM is unsupported" --#endif - - #include - #include -diff --git a/common/rfb/pam.h b/common/rfb/pam.h -index 2688f21..d378d19 100644 ---- a/common/rfb/pam.h -+++ b/common/rfb/pam.h -@@ -21,14 +21,6 @@ - #ifndef __RFB_PAM_H__ - #define __RFB_PAM_H__ - --#ifdef HAVE_CONFIG_H --#include --#endif -- --#ifndef HAVE_PAM --#error "This header should not be included when PAM is unsupported" --#endif -- - #ifdef __cplusplus - extern "C" { - #endif -diff --git a/config.h.in b/config.h.in -index 2d6db9c..2d7a741 100644 ---- a/config.h.in -+++ b/config.h.in -@@ -4,10 +4,10 @@ - #cmakedefine HAVE_ACTIVE_DESKTOP_H - #cmakedefine HAVE_ACTIVE_DESKTOP_L - #cmakedefine ENABLE_NLS 1 --#cmakedefine HAVE_PAM - --#cmakedefine DATA_DIR "@DATA_DIR@" --#cmakedefine LOCALE_DIR "@LOCALE_DIR@" -+#cmakedefine CMAKE_INSTALL_FULL_LIBEXECDIR "@CMAKE_INSTALL_FULL_LIBEXECDIR@" -+#cmakedefine CMAKE_INSTALL_FULL_DATADIR "@CMAKE_INSTALL_FULL_DATADIR@" -+#cmakedefine CMAKE_INSTALL_FULL_LOCALEDIR "@CMAKE_INSTALL_FULL_LOCALEDIR@" - - /* MS Visual Studio 2008 and newer doesn't know ssize_t */ - #if defined(HAVE_GNUTLS) && defined(WIN32) && !defined(__MINGW32__) -diff --git a/java/CMakeLists.txt b/java/CMakeLists.txt -index f61e355..77ec21b 100644 ---- a/java/CMakeLists.txt -+++ b/java/CMakeLists.txt -@@ -7,8 +7,6 @@ endif() - - find_package(Java) - --set(DATA_DIR "${CMAKE_INSTALL_PREFIX}/share") -- - set(DEFAULT_JAVACFLAGS "-source 8 -target 8 -encoding UTF-8 -Xlint:all,-serial,-cast,-unchecked,-fallthrough,-dep-ann,-deprecation,-rawtypes") - set(JAVACFLAGS ${DEFAULT_JAVACFLAGS} CACHE STRING - "Java compiler flags (Default: ${DEFAULT_JAVACFLAGS})") -diff --git a/media/CMakeLists.txt b/media/CMakeLists.txt -index 256d435..088c72f 100644 ---- a/media/CMakeLists.txt -+++ b/media/CMakeLists.txt -@@ -13,11 +13,11 @@ if(CONVERT_EXECUTABLE) - if(UNIX AND NOT APPLE) - foreach(SIZE 16 22 24 32 48) - install(FILES icons/tigervnc_${SIZE}.png -- DESTINATION ${DATA_DIR}/icons/hicolor/${SIZE}x${SIZE}/apps -+ DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/icons/hicolor/${SIZE}x${SIZE}/apps - RENAME tigervnc.png) - endforeach() - install(FILES icons/tigervnc.svg -- DESTINATION ${DATA_DIR}/icons/hicolor/scalable/apps) -+ DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/icons/hicolor/scalable/apps) - endif() - endif() - -diff --git a/po/CMakeLists.txt b/po/CMakeLists.txt -index 9c8ddef..2eb10e7 100644 ---- a/po/CMakeLists.txt -+++ b/po/CMakeLists.txt -@@ -46,7 +46,7 @@ foreach(lang ${po_FILES}) - ) - - install(FILES ${mo} -- DESTINATION "${LOCALE_DIR}/${lang}/LC_MESSAGES" -+ DESTINATION "${CMAKE_INSTALL_FULL_LOCALEDIR}/${lang}/LC_MESSAGES" - RENAME tigervnc.mo - ) - -diff --git a/unix/CMakeLists.txt b/unix/CMakeLists.txt -index 7a1457d..5456e00 100644 ---- a/unix/CMakeLists.txt -+++ b/unix/CMakeLists.txt -@@ -2,7 +2,5 @@ add_subdirectory(tx) - add_subdirectory(common) - add_subdirectory(vncconfig) - add_subdirectory(vncpasswd) -+add_subdirectory(vncserver) - add_subdirectory(x0vncserver) -- --install(PROGRAMS vncserver DESTINATION ${BIN_DIR}) --install(FILES vncserver.man DESTINATION ${MAN_DIR}/man1 RENAME vncserver.1) -diff --git a/unix/vncconfig/CMakeLists.txt b/unix/vncconfig/CMakeLists.txt -index 959681f..c3823ab 100644 ---- a/unix/vncconfig/CMakeLists.txt -+++ b/unix/vncconfig/CMakeLists.txt -@@ -11,5 +11,5 @@ add_executable(vncconfig - - target_link_libraries(vncconfig tx rfb network rdr ${X11_LIBRARIES}) - --install(TARGETS vncconfig DESTINATION ${BIN_DIR}) --install(FILES vncconfig.man DESTINATION ${MAN_DIR}/man1 RENAME vncconfig.1) -+install(TARGETS vncconfig DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}) -+install(FILES vncconfig.man DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man1 RENAME vncconfig.1) -diff --git a/unix/vncconfig/vncconfig.man b/unix/vncconfig/vncconfig.man -index b685a46..ed9ddda 100644 ---- a/unix/vncconfig/vncconfig.man -+++ b/unix/vncconfig/vncconfig.man -@@ -111,8 +111,8 @@ When run as a "helper" app, make the window iconified at startup. - .SH SEE ALSO - .BR vncpasswd (1), - .BR vncviewer (1), --.BR vncserver (1), --.BR Xvnc (1) -+.BR Xvnc (1), -+.BR vncsession (8) - .br - https://www.tigervnc.org - -diff --git a/unix/vncpasswd/CMakeLists.txt b/unix/vncpasswd/CMakeLists.txt -index a04ed0b..9f716fa 100644 ---- a/unix/vncpasswd/CMakeLists.txt -+++ b/unix/vncpasswd/CMakeLists.txt -@@ -5,5 +5,5 @@ add_executable(vncpasswd - - target_link_libraries(vncpasswd tx rfb os) - --install(TARGETS vncpasswd DESTINATION ${BIN_DIR}) --install(FILES vncpasswd.man DESTINATION ${MAN_DIR}/man1 RENAME vncpasswd.1) -+install(TARGETS vncpasswd DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}) -+install(FILES vncpasswd.man DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man1 RENAME vncpasswd.1) -diff --git a/unix/vncpasswd/vncpasswd.man b/unix/vncpasswd/vncpasswd.man -index 9e68181..c70a425 100644 ---- a/unix/vncpasswd/vncpasswd.man -+++ b/unix/vncpasswd/vncpasswd.man -@@ -43,9 +43,9 @@ Default location of the VNC password file. - - .SH SEE ALSO - .BR vncviewer (1), --.BR vncserver (1), - .BR Xvnc (1) - .BR vncconfig (1), -+.BR vncsession (8) - .br - https://www.tigervnc.org - -diff --git a/unix/vncserver.man b/unix/vncserver.man -deleted file mode 100644 -index 95f7960..0000000 ---- a/unix/vncserver.man -+++ /dev/null -@@ -1,204 +0,0 @@ --.TH vncserver 1 "" "TigerVNC" "Virtual Network Computing" --.SH NAME --vncserver \- start or stop a VNC server --.SH SYNOPSIS --.B vncserver --.RI [: display# ] --.RB [ \-name --.IR desktop-name ] --.RB [ \-geometry --.IR width x height ] --.RB [ \-depth --.IR depth ] --.RB [ \-pixelformat --.IR format ] --.RB [ \-fp --.IR font-path ] --.RB [ \-fg ] --.RB [ \-autokill ] --.RB [ \-noxstartup ] --.RB [ \-xstartup --.IR script ] --.RI [ Xvnc-options... ] --.br --.BI "vncserver \-kill :" display# --.br --.BI "vncserver \-list" --.SH DESCRIPTION --.B vncserver --is used to start a VNC (Virtual Network Computing) desktop. --.B vncserver --is a Perl script which simplifies the process of starting an Xvnc server. It --runs Xvnc with appropriate options and starts a window manager on the VNC --desktop. -- --.B vncserver --can be run with no options at all. In this case it will choose the first --available display number (usually :1), start Xvnc with that display number, --and start the default window manager in the Xvnc session. You can also --specify the display number, in which case vncserver will attempt to start --Xvnc with that display number and exit if the display number is not --available. For example: -- --.RS --vncserver :13 --.RE -- --Editing the file $HOME/.vnc/xstartup allows you to change the applications run --at startup (but note that this will not affect an existing VNC session.) -- --.SH OPTIONS --You can get a list of options by passing \fB\-h\fP as an option to vncserver. --In addition to the options listed below, any unrecognised options will be --passed to Xvnc - see the Xvnc man page, or "Xvnc \-help", for details. -- --.TP --.B \-name \fIdesktop-name\fP --Each VNC desktop has a name which may be displayed by the viewer. The desktop --name defaults to "\fIhost\fP:\fIdisplay#\fP (\fIusername\fP)", but you can --change it with this option. The desktop name option is passed to the xstartup --script via the $VNCDESKTOP environment variable, which allows you to run a --different set of applications depending on the name of the desktop. --. --.TP --.B \-geometry \fIwidth\fPx\fIheight\fP --Specify the size of the VNC desktop to be created. Default is 1024x768. --. --.TP --.B \-depth \fIdepth\fP --Specify the pixel depth (in bits) of the VNC desktop to be created. Default is --24. Other possible values are 8, 15 and 16 - anything else is likely to cause --strange behaviour by applications. --. --.TP --.B \-pixelformat \fIformat\fP --Specify pixel format for Xvnc to use (BGRnnn or RGBnnn). The default for --depth 8 is BGR233 (meaning the most significant two bits represent blue, the --next three green, and the least significant three represent red), the default --for depth 16 is RGB565, and the default for depth 24 is RGB888. --. --.TP --.B \-cc 3 --As an alternative to the default TrueColor visual, this allows you to run an --Xvnc server with a PseudoColor visual (i.e. one which uses a color map or --palette), which can be useful for running some old X applications which only --work on such a display. Values other than 3 (PseudoColor) and 4 (TrueColor) --for the \-cc option may result in strange behaviour, and PseudoColor desktops --must have an 8-bit depth. --. --.TP --.B \-kill :\fIdisplay#\fP --This kills a VNC desktop previously started with vncserver. It does this by --killing the Xvnc process, whose process ID is stored in the file --"$HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.pid". The --.B \-kill --option ignores anything preceding the first colon (":") in the display --argument. Thus, you can invoke "vncserver \-kill $DISPLAY", for example at the --end of your xstartup file after a particular application exits. --. --.TP --.B \-fp \fIfont-path\fP --If the vncserver script detects that the X Font Server (XFS) is running, it --will attempt to start Xvnc and configure Xvnc to use XFS for font handling. --Otherwise, if XFS is not running, the vncserver script will attempt to start --Xvnc and allow Xvnc to use its own preferred method of font handling (which may --be a hard-coded font path or, on more recent systems, a font catalog.) In --any case, if Xvnc fails to start, the vncserver script will then attempt to --determine an appropriate X font path for this system and start Xvnc using --that font path. -- --The --.B \-fp --argument allows you to override the above fallback logic and specify a font --path for Xvnc to use. --. --.TP --.B \-fg --Runs Xvnc as a foreground process. This has two effects: (1) The VNC server --can be aborted with CTRL-C, and (2) the VNC server will exit as soon as the --user logs out of the window manager in the VNC session. This may be necessary --when launching TigerVNC from within certain grid computing environments. --. --.TP --.B \-autokill --Automatically kill Xvnc whenever the xstartup script exits. In most cases, --this has the effect of terminating Xvnc when the user logs out of the window --manager. --. --.TP --.B \-noxstartup --Do not run the %HOME/.vnc/xstartup script after launching Xvnc. This --option allows you to manually start a window manager in your TigerVNC session. --. --.TP --.B \-xstartup \fIscript\fP --Run a custom startup script, instead of %HOME/.vnc/xstartup, after launching --Xvnc. This is useful to run full-screen applications. --. --.TP --.B \-list --Lists all VNC desktops started by vncserver. -- --.SH FILES --Several VNC-related files are found in the directory $HOME/.vnc: --.TP --$HOME/.vnc/xstartup --A shell script specifying X applications to be run when a VNC desktop is --started. If this file does not exist, then vncserver will create a default --xstartup script which attempts to launch your chosen window manager. --.TP --/etc/tigervnc/vncserver-config-defaults --The optional system-wide equivalent of $HOME/.vnc/config. If this file exists --and defines options to be passed to Xvnc, they will be used as defaults for --users. The user's $HOME/.vnc/config overrides settings configured in this file. --The overall configuration file load order is: this file, $HOME/.vnc/config, --and then /etc/tigervnc/vncserver-config-mandatory. None are required to exist. --.TP --/etc/tigervnc/vncserver-config-mandatory --The optional system-wide equivalent of $HOME/.vnc/config. If this file exists --and defines options to be passed to Xvnc, they will override any of the same --options defined in a user's $HOME/.vnc/config. This file offers a mechanism --to establish some basic form of system-wide policy. WARNING! There is --nothing stopping users from constructing their own vncserver-like script --that calls Xvnc directly to bypass any options defined in --/etc/tigervnc/vncserver-config-mandatory. Likewise, any CLI arguments passed --to vncserver will override ANY config file setting of the same name. The --overall configuration file load order is: --/etc/tigervnc/vncserver-config-defaults, $HOME/.vnc/config, and then this file. --None are required to exist. --.TP --$HOME/.vnc/config --An optional server config file wherein options to be passed to Xvnc are listed --to avoid hard-coding them to the physical invocation. List options in this file --one per line. For those requiring an argument, simply separate the option from --the argument with an equal sign, for example: "geometry=2000x1200" or --"securitytypes=vncauth,tlsvnc". Options without an argument are simply listed --as a single word, for example: "localhost" or "alwaysshared". --.TP --$HOME/.vnc/passwd --The VNC password file. --.TP --$HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.log --The log file for Xvnc and applications started in xstartup. --.TP --$HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.pid --Identifies the Xvnc process ID, used by the --.B \-kill --option. -- --.SH SEE ALSO --.BR vncviewer (1), --.BR vncpasswd (1), --.BR vncconfig (1), --.BR Xvnc (1) --.br --https://www.tigervnc.org -- --.SH AUTHOR --Tristan Richardson, RealVNC Ltd., D. R. Commander and others. -- --VNC was originally developed by the RealVNC team while at Olivetti --Research Ltd / AT&T Laboratories Cambridge. TightVNC additions were --implemented by Constantin Kaplinsky. Many other people have since --participated in development, testing and support. This manual is part --of the TigerVNC software suite. -diff --git a/unix/vncserver/CMakeLists.txt b/unix/vncserver/CMakeLists.txt -new file mode 100644 -index 0000000..eeb4b7b ---- /dev/null -+++ b/unix/vncserver/CMakeLists.txt -@@ -0,0 +1,20 @@ -+add_executable(vncsession vncsession.c) -+target_link_libraries(vncsession ${PAM_LIBS}) -+ -+configure_file(vncserver@.service.in vncserver@.service @ONLY) -+configure_file(vncsession-start.in vncsession-start @ONLY) -+configure_file(vncserver.in vncserver @ONLY) -+ -+install(TARGETS vncsession DESTINATION ${CMAKE_INSTALL_FULL_SBINDIR}) -+install(FILES tigervnc.pam DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/pam.d RENAME tigervnc) -+install(FILES vncsession.man DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man8 RENAME vncsession.8) -+install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/vncserver DESTINATION ${CMAKE_INSTALL_FULL_LIBEXECDIR}) -+install(FILES vncserver.man DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man8 RENAME vncserver.8) -+install(FILES vncserver-config-defaults vncserver-config-mandatory DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/tigervnc) -+ -+install(FILES vncserver.users DESTINATION ${CMAKE_INSTALL_FULL_SYSCONFDIR}/tigervnc) -+ -+if(INSTALL_SYSTEMD_UNITS) -+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/vncserver@.service DESTINATION ${CMAKE_INSTALL_FULL_UNITDIR}) -+ install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/vncsession-start DESTINATION ${CMAKE_INSTALL_FULL_LIBEXECDIR}) -+endif() -diff --git a/unix/vncserver/selinux/Makefile b/unix/vncserver/selinux/Makefile -new file mode 100644 -index 0000000..904a2d5 ---- /dev/null -+++ b/unix/vncserver/selinux/Makefile -@@ -0,0 +1,24 @@ -+# SELinux module for TigerVNC's vncsession -+# -+# This will install the policy module, but not load it. To apply -+# it you should also run: -+# -+# sudo semodule -i /usr/share/selinux/packages/vncsession.pp -+# sudo restorecon /usr/sbin/vncsession /usr/libexec/vncsession-start -+# -+ -+PREFIX=/usr -+DATADIR=$(PREFIX)/share -+ -+all: vncsession.pp -+ -+%.pp: %.te -+ make -f $(DATADIR)/selinux/devel/Makefile $@ -+ -+clean: -+ rm -f *.pp -+ rm -rf tmp -+ -+install: vncsession.pp -+ mkdir -p $(DESTDIR)$(DATADIR)/selinux/packages -+ install vncsession.pp $(DESTDIR)$(DATADIR)/selinux/packages/vncsession.pp -diff --git a/unix/vncserver/selinux/vncsession.fc b/unix/vncserver/selinux/vncsession.fc -new file mode 100644 -index 0000000..121cdd2 ---- /dev/null -+++ b/unix/vncserver/selinux/vncsession.fc -@@ -0,0 +1,26 @@ -+# -+# Copyright 2018 Pierre Ossman for Cendio AB -+# -+# This is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This software is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this software; if not, write to the Free Software -+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -+# USA. -+# -+ -+HOME_DIR/\.vnc(/.*)? gen_context(system_u:object_r:xdm_home_t,s0) -+HOME_ROOT/\.vnc(/.*)? gen_context(system_u:object_r:xdm_home_t,s0) -+ -+/usr/sbin/vncsession -- gen_context(system_u:object_r:vnc_session_exec_t,s0) -+/usr/libexec/vncsession-start -- gen_context(system_u:object_r:vnc_session_exec_t,s0) -+ -+/var/run/vncsession-:[0-9]*\.pid -- gen_context(system_u:object_r:vnc_session_var_run_t,s0) -diff --git a/unix/vncserver/selinux/vncsession.if b/unix/vncserver/selinux/vncsession.if -new file mode 100644 -index 0000000..3eb6a30 ---- /dev/null -+++ b/unix/vncserver/selinux/vncsession.if -@@ -0,0 +1 @@ -+## -diff --git a/unix/vncserver/selinux/vncsession.te b/unix/vncserver/selinux/vncsession.te -new file mode 100644 -index 0000000..941f28d ---- /dev/null -+++ b/unix/vncserver/selinux/vncsession.te -@@ -0,0 +1,67 @@ -+# -+# Copyright 2018-2020 Pierre Ossman for Cendio AB -+# -+# This is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This software is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this software; if not, write to the Free Software -+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -+# USA. -+# -+ -+policy_module(vncsession, 1.0.0); -+ -+gen_require(` -+ type unconfined_t; -+ type xdm_home_t; -+') -+ -+type vnc_session_exec_t; -+corecmd_executable_file(vnc_session_exec_t) -+type vnc_session_t; -+init_daemon_domain(vnc_session_t, vnc_session_exec_t) -+auth_login_pgm_domain(vnc_session_t) -+ -+type vnc_session_var_run_t; -+files_pid_file(vnc_session_var_run_t) -+allow vnc_session_t vnc_session_var_run_t:file manage_file_perms; -+files_pid_filetrans(vnc_session_t, vnc_session_var_run_t, file) -+ -+auth_write_login_records(vnc_session_t) -+ -+can_exec(vnc_session_t, vnc_session_exec_t) -+ -+userdom_spec_domtrans_all_users(vnc_session_t) -+userdom_signal_all_users(vnc_session_t) -+ -+allow vnc_session_t self:capability { kill chown dac_override dac_read_search fowner setgid setuid sys_resource }; -+allow vnc_session_t self:process { getcap setsched setexec setrlimit }; -+allow vnc_session_t self:fifo_file rw_fifo_file_perms; -+ -+manage_files_pattern(vnc_session_t, xdm_home_t, xdm_home_t) -+manage_fifo_files_pattern(vnc_session_t, xdm_home_t, xdm_home_t) -+manage_sock_files_pattern(vnc_session_t, xdm_home_t, xdm_home_t) -+manage_lnk_files_pattern(vnc_session_t, xdm_home_t, xdm_home_t) -+ -+userdom_user_home_dir_filetrans(unconfined_t, xdm_home_t, dir, ".vnc") -+userdom_user_home_dir_filetrans(vnc_session_t, xdm_home_t, dir, ".vnc") -+ -+userdom_admin_home_dir_filetrans(vnc_session_t, xdm_home_t, dir, ".vnc") -+userdom_admin_home_dir_filetrans(unconfined_t, xdm_home_t, dir, ".vnc") -+ -+miscfiles_read_localization(vnc_session_t) -+ -+kernel_read_kernel_sysctls(vnc_session_t) -+ -+logging_append_all_logs(vnc_session_t) -+ -+mcs_process_set_categories(vnc_session_t) -+mcs_killall(vnc_session_t) -diff --git a/unix/vncserver/tigervnc.pam b/unix/vncserver/tigervnc.pam -new file mode 100644 -index 0000000..0f4cb3a ---- /dev/null -+++ b/unix/vncserver/tigervnc.pam -@@ -0,0 +1,11 @@ -+#%PAM-1.0 -+# pam_selinux.so close should be the first session rule -+-session required pam_selinux.so close -+session required pam_loginuid.so -+-session required pam_selinux.so open -+session required pam_namespace.so -+session optional pam_keyinit.so force revoke -+session required pam_limits.so -+-session optional pam_systemd.so -+session required pam_unix.so -+-session optional pam_reauthorize.so prepare -diff --git a/unix/vncserver/vncserver-config-defaults b/unix/vncserver/vncserver-config-defaults -new file mode 100644 -index 0000000..0c217bf ---- /dev/null -+++ b/unix/vncserver/vncserver-config-defaults -@@ -0,0 +1,15 @@ -+## Default settings for VNC servers started by the vncserver service -+# -+# Any settings given here will override the builtin defaults, but can -+# also be overriden by ~/.vnc/config and vncserver-config-mandatory. -+# -+# See the following manpages for more details: vncserver(1) Xvnc(1) -+# -+# Several common settings are shown below. Uncomment and modify to your -+# liking. -+ -+# securitytypes=vncauth,tlsvnc -+# desktop=sandbox -+# geometry=2000x1200 -+# localhost -+# alwaysshared -diff --git a/unix/vncserver/vncserver-config-mandatory b/unix/vncserver/vncserver-config-mandatory -new file mode 100644 -index 0000000..98c32f6 ---- /dev/null -+++ b/unix/vncserver/vncserver-config-mandatory -@@ -0,0 +1,15 @@ -+## Mandatory settings for VNC servers started by the vncserver service -+# -+# Any settings given here will override the builtin defaults and -+# settings specified in ~/.vnc/config or vnc-config-defaults. -+# -+# See the following manpages for more details: vncserver(1) Xvnc(1) -+# -+# Several common settings are shown below. Uncomment and modify to your -+# liking. -+ -+# securitytypes=vncauth,tlsvnc -+# desktop=sandbox -+# geometry=2000x1200 -+# localhost -+# alwaysshared -diff --git a/unix/vncserver/vncserver.in b/unix/vncserver/vncserver.in -new file mode 100755 -index 0000000..8e05b72 ---- /dev/null -+++ b/unix/vncserver/vncserver.in -@@ -0,0 +1,485 @@ -+#!/usr/bin/perl -+# -+# Copyright (C) 2015-2019 Pierre Ossman for Cendio AB -+# Copyright (C) 2009-2010 D. R. Commander. All Rights Reserved. -+# Copyright (C) 2005-2006 Sun Microsystems, Inc. All Rights Reserved. -+# Copyright (C) 2002-2003 Constantin Kaplinsky. All Rights Reserved. -+# Copyright (C) 2002-2005 RealVNC Ltd. -+# Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. -+# -+# This is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This software is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this software; if not, write to the Free Software -+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -+# USA. -+# -+ -+# -+# vncserver - wrapper script to start an X VNC server. -+# -+ -+&SanityCheck(); -+ -+# -+# Global variables. You may want to configure some of these for -+# your site -+# -+ -+$vncUserDir = "$ENV{HOME}/.vnc"; -+$vncUserConfig = "$vncUserDir/config"; -+ -+$vncSystemConfigDir = "/etc/tigervnc"; -+$vncSystemConfigDefaultsFile = "$vncSystemConfigDir/vncserver-config-defaults"; -+$vncSystemConfigMandatoryFile = "$vncSystemConfigDir/vncserver-config-mandatory"; -+ -+$xauthorityFile = "$ENV{XAUTHORITY}" || "$ENV{HOME}/.Xauthority"; -+ -+chop($host = `uname -n`); -+ -+if (-d "/etc/X11/fontpath.d") { -+ $fontPath = "catalogue:/etc/X11/fontpath.d"; -+} -+ -+@fontpaths = ('/usr/share/X11/fonts', '/usr/share/fonts', '/usr/share/fonts/X11/'); -+if (! -l "/usr/lib/X11") {push(@fontpaths, '/usr/lib/X11/fonts');} -+if (! -l "/usr/X11") {push(@fontpaths, '/usr/X11/lib/X11/fonts');} -+if (! -l "/usr/X11R6") {push(@fontpaths, '/usr/X11R6/lib/X11/fonts');} -+push(@fontpaths, '/usr/share/fonts/default'); -+ -+@fonttypes = ('misc', -+ '75dpi', -+ '100dpi', -+ 'Speedo', -+ 'Type1'); -+ -+foreach $_fpath (@fontpaths) { -+ foreach $_ftype (@fonttypes) { -+ if (-f "$_fpath/$_ftype/fonts.dir") { -+ if (! -l "$_fpath/$_ftype") { -+ $defFontPath .= "$_fpath/$_ftype,"; -+ } -+ } -+ } -+} -+ -+if ($defFontPath) { -+ if (substr($defFontPath, -1, 1) == ',') { -+ chop $defFontPath; -+ } -+} -+ -+if ($fontPath eq "") { -+ $fontPath = $defFontPath; -+} -+ -+# Find display number. -+if ((@ARGV == 1) && ($ARGV[0] =~ /^:(\d+)$/)) { -+ $displayNumber = $1; -+ if (!&CheckDisplayNumber($displayNumber)) { -+ die "A VNC server is already running as :$displayNumber\n"; -+ } -+} else { -+ &Usage(); -+} -+ -+$vncPort = 5900 + $displayNumber; -+ -+$desktopName = "$host:$displayNumber ($ENV{USER})"; -+ -+my %default_opts; -+my %config; -+ -+# We set some reasonable defaults. Config file settings -+# override these where present. -+$default_opts{desktop} = $desktopName; -+$default_opts{auth} = $xauthorityFile; -+$default_opts{rfbwait} = 30000; -+$default_opts{rfbauth} = "$vncUserDir/passwd"; -+$default_opts{rfbport} = $vncPort; -+$default_opts{fp} = $fontPath if ($fontPath); -+$default_opts{pn} = ""; -+ -+# Load user-overrideable system defaults -+LoadConfig($vncSystemConfigDefaultsFile); -+ -+# Then the user's settings -+LoadConfig($vncUserConfig); -+ -+# And then override anything set above if mandatory settings exist. -+# WARNING: "Mandatory" is used loosely here! As the man page says, -+# there is nothing stopping someone from EASILY subverting the -+# settings in $vncSystemConfigMandatoryFile by simply passing -+# CLI args to vncserver, which trump config files! To properly -+# hard force policy in a non-subvertible way would require major -+# development work that touches Xvnc itself. -+LoadConfig($vncSystemConfigMandatoryFile, 1); -+ -+# -+# Check whether VNC authentication is enabled, and if so, check that -+# a VNC password has been created. -+# -+ -+$securityTypeArgSpecified = 0; -+$vncAuthEnabled = 0; -+$passwordArgSpecified = 0; -+@vncAuthStrings = ("vncauth", "tlsvnc", "x509vnc"); -+ -+# ...first we check our configuration files' settings -+if ($config{'securitytypes'}) { -+ $securityTypeArgSpecified = 1; -+ foreach $arg2 (split(',', $config{'securitytypes'})) { -+ if (grep {$_ eq lc($arg2)} @vncAuthStrings) { -+ $vncAuthEnabled = 1; -+ } -+ } -+} -+ -+if ($config{'password'} || -+ $config{'passwordfile'} || -+ $config{'rfbauth'}) { -+ $passwordArgSpecified = 1; -+} -+ -+if ((!$securityTypeArgSpecified || $vncAuthEnabled) && !$passwordArgSpecified) { -+ ($z,$z,$mode) = stat("$vncUserDir/passwd"); -+ if (!(-e "$vncUserDir/passwd") || ($mode & 077)) { -+ die "VNC authentication enabled, but no password file created.\n"; -+ } -+} -+ -+# -+# Find a desktop session to run -+# -+ -+my $sessionname; -+my %session; -+ -+$sessionname = delete $config{'session'}; -+ -+if ($sessionname) { -+ %session = LoadXSession($sessionname); -+ if (!%session) { -+ warn "Could not load configured desktop session $sessionname\n"; -+ $sessionname = undef; -+ } -+} -+ -+if (!$sessionname) { -+ foreach $file (glob("/usr/share/xsessions/*.desktop")) { -+ ($name) = $file =~ /^.*\/(.*)[.]desktop$/; -+ %session = LoadXSession($name); -+ if (%session) { -+ $sessionname = $name; -+ last; -+ } -+ } -+} -+ -+if (!$sessionname) { -+ die "Could not find a desktop session to run\n"; -+} -+ -+warn "Using desktop session $sessionname\n"; -+ -+if (!$session{'Exec'}) { -+ die "No command specified for desktop session\n"; -+} -+ -+$ENV{GDMSESSION} = $sessionname; -+$ENV{DESKTOP_SESSION} = $sessionname; -+$ENV{XDG_SESSION_DESKTOP} = $sessionname; -+ -+if ($session{'DesktopNames'}) { -+ $ENV{XDG_DESKTOP_NAMES} = $session{'DesktopNames'} =~ s/;/:/gr; -+} -+ -+ -+# Make an X server cookie and set up the Xauthority file -+# mcookie is a part of util-linux, usually only GNU/Linux systems have it. -+$cookie = `mcookie`; -+# Fallback for non GNU/Linux OS - use /dev/urandom on systems that have it, -+# otherwise use perl's random number generator, seeded with the sum -+# of the current time, our PID and part of the encrypted form of the password. -+if ($cookie eq "" && open(URANDOM, '<', '/dev/urandom')) { -+ my $randata; -+ if (sysread(URANDOM, $randata, 16) == 16) { -+ $cookie = unpack 'h*', $randata; -+ } -+ close(URANDOM); -+} -+if ($cookie eq "") { -+ srand(time+$$+unpack("L",`cat $vncUserDir/passwd`)); -+ for (1..16) { -+ $cookie .= sprintf("%02x", int(rand(256)) % 256); -+ } -+} -+ -+open(XAUTH, "|xauth -f $xauthorityFile source -"); -+print XAUTH "add $host:$displayNumber . $cookie\n"; -+print XAUTH "add $host/unix:$displayNumber . $cookie\n"; -+close(XAUTH); -+ -+$ENV{XAUTHORITY} = $xauthorityFile; -+ -+# Now start the X VNC Server -+ -+@cmd = ("xinit"); -+ -+push(@cmd, $Xsession, $session{'Exec'}); -+ -+push(@cmd, '--'); -+ -+ -+# We build up our Xvnc command with options -+push(@cmd, "@CMAKE_INSTALL_FULL_BINDIR@/Xvnc", ":$displayNumber"); -+ -+foreach my $k (sort keys %config) { -+ push(@cmd, "-$k"); -+ push(@cmd, $config{$k}) if $config{$k}; -+ delete $default_opts{$k}; # file options take precedence -+} -+ -+foreach my $k (sort keys %default_opts) { -+ push(@cmd, "-$k"); -+ push(@cmd, $default_opts{$k}) if $default_opts{$k}; -+} -+ -+warn "\nNew '$desktopName' desktop is $host:$displayNumber\n\n"; -+ -+warn "Starting desktop session $sessionname\n"; -+ -+exec(@cmd); -+ -+die "Failed to start session.\n"; -+ -+############################################################################### -+# Functions -+############################################################################### -+ -+# -+# Populate the global %config hash with settings from a specified -+# vncserver configuration file if it exists -+# -+# Args: 1. file path -+# 2. optional boolean flag to enable warning when a previously -+# set configuration setting is being overridden -+# -+sub LoadConfig { -+ local ($configFile, $warnoverride) = @_; -+ local ($toggle) = undef; -+ -+ if (stat($configFile)) { -+ if (open(IN, $configFile)) { -+ while () { -+ next if /^#/; -+ if (my ($k, $v) = /^\s*(\w+)\s*=\s*(.+)$/) { -+ $k = lc($k); # must normalize key case -+ if ($warnoverride && $config{$k}) { -+ print("Warning: $configFile is overriding previously defined '$k' to be '$v'\n"); -+ } -+ $config{$k} = $v; -+ } elsif ($_ =~ m/^\s*(\S+)/) { -+ # We can't reasonably warn on override of toggles (e.g. AlwaysShared) -+ # because it would get crazy to do so. We'd have to check if the -+ # current config file being loaded defined the logical opposite setting -+ # (NeverShared vs. AlwaysShared, etc etc). -+ $toggle = lc($1); # must normalize key case -+ $config{$toggle} = $k; -+ } -+ } -+ close(IN); -+ } -+ } -+} -+ -+ -+# -+# Load a session desktop file -+# -+sub LoadXSession { -+ local ($name) = @_; -+ my $file, $found_group, %session; -+ -+ $file = "/usr/share/xsessions/$name.desktop"; -+ -+ if (!stat($file)) { -+ warn "Could not find session desktop file $file"; -+ return; -+ } -+ -+ if (!open(IN, $file)) { -+ warn "Could not open session desktop file $file"; -+ return; -+ } -+ -+ $found_group = 0; -+ while (my $line = ) { -+ next if $line =~ /^#/; -+ next if $line =~ /^\s*$/; -+ -+ if (!$found_group) { -+ next if $line != "[Desktop Entry]"; -+ $found_group = 1; -+ next; -+ } else { -+ last if $line =~ /^\[/; -+ } -+ -+ my ($key, $value) = $line =~ /^\s*([]A-Za-z0-9_@\-\[]+)\s*=\s*(.*)$/; -+ if (!$key) { -+ warn "Invalid session desktop file $file"; -+ close(IN); -+ return; -+ } -+ -+ $value =~ s/\\s/ /g; -+ $value =~ s/\\n/\n/g; -+ $value =~ s/\\t/\t/g; -+ $value =~ s/\\r/\r/g; -+ $value =~ s/\\\\/\\/g; -+ -+ $session{$key} = $value; -+ } -+ -+ close(IN); -+ -+ return %session; -+} -+ -+ -+# -+# CheckDisplayNumber checks if the given display number is available. A -+# display number n is taken if something is listening on the VNC server port -+# (5900+n) or the X server port (6000+n). -+# -+ -+sub CheckDisplayNumber -+{ -+ local ($n) = @_; -+ -+ socket(S, $AF_INET, $SOCK_STREAM, 0) || die "$prog: socket failed: $!\n"; -+ eval 'setsockopt(S, &SOL_SOCKET, &SO_REUSEADDR, pack("l", 1))'; -+ if (!bind(S, pack('S n x12', $AF_INET, 6000 + $n))) { -+ close(S); -+ return 0; -+ } -+ close(S); -+ -+ socket(S, $AF_INET, $SOCK_STREAM, 0) || die "$prog: socket failed: $!\n"; -+ eval 'setsockopt(S, &SOL_SOCKET, &SO_REUSEADDR, pack("l", 1))'; -+ if (!bind(S, pack('S n x12', $AF_INET, 5900 + $n))) { -+ close(S); -+ return 0; -+ } -+ close(S); -+ -+ if (-e "/tmp/.X$n-lock") { -+ warn "\nWarning: $host:$n is taken because of /tmp/.X$n-lock\n"; -+ warn "Remove this file if there is no X server $host:$n\n"; -+ return 0; -+ } -+ -+ if (-e "/tmp/.X11-unix/X$n") { -+ warn "\nWarning: $host:$n is taken because of /tmp/.X11-unix/X$n\n"; -+ warn "Remove this file if there is no X server $host:$n\n"; -+ return 0; -+ } -+ -+ if (-e "/usr/spool/sockets/X11/$n") { -+ warn("\nWarning: $host:$n is taken because of ". -+ "/usr/spool/sockets/X11/$n\n"); -+ warn "Remove this file if there is no X server $host:$n\n"; -+ return 0; -+ } -+ -+ return 1; -+} -+ -+# -+# Usage -+# -+ -+sub Usage -+{ -+ die("\nusage: $prog \n\n"); -+} -+ -+ -+# Routine to make sure we're operating in a sane environment. -+sub SanityCheck -+{ -+ local ($cmd); -+ -+ # Get the program name -+ ($prog) = ($0 =~ m|([^/]+)$|); -+ -+ # -+ # Check we have all the commands we'll need on the path. -+ # -+ -+ cmd: -+ foreach $cmd ("uname","xauth","xinit") { -+ for (split(/:/,$ENV{PATH})) { -+ if (-x "$_/$cmd") { -+ next cmd; -+ } -+ } -+ die "$prog: couldn't find \"$cmd\" on your PATH.\n"; -+ } -+ -+ foreach $cmd ("/etc/X11/xinit/Xsession", "/etc/X11/Xsession") { -+ if (-x "$cmd") { -+ $Xsession = $cmd; -+ last; -+ } -+ } -+ if (not defined $Xsession) { -+ die "$prog: Couldn't find suitable Xsession.\n"; -+ } -+ -+ -+ if (!defined($ENV{HOME})) { -+ die "$prog: The HOME environment variable is not set.\n"; -+ } -+ -+ # -+ # Find socket constants. 'use Socket' is a perl5-ism, so we wrap it in an -+ # eval, and if it fails we try 'require "sys/socket.ph"'. If this fails, -+ # we just guess at the values. If you find perl moaning here, just -+ # hard-code the values of AF_INET and SOCK_STREAM. You can find these out -+ # for your platform by looking in /usr/include/sys/socket.h and related -+ # files. -+ # -+ -+ chop($os = `uname`); -+ chop($osrev = `uname -r`); -+ -+ eval 'use Socket'; -+ if ($@) { -+ eval 'require "sys/socket.ph"'; -+ if ($@) { -+ if (($os eq "SunOS") && ($osrev !~ /^4/)) { -+ $AF_INET = 2; -+ $SOCK_STREAM = 2; -+ } else { -+ $AF_INET = 2; -+ $SOCK_STREAM = 1; -+ } -+ } else { -+ $AF_INET = &AF_INET; -+ $SOCK_STREAM = &SOCK_STREAM; -+ } -+ } else { -+ $AF_INET = &AF_INET; -+ $SOCK_STREAM = &SOCK_STREAM; -+ } -+} -diff --git a/unix/vncserver/vncserver.man b/unix/vncserver/vncserver.man -new file mode 100644 -index 0000000..f1017be ---- /dev/null -+++ b/unix/vncserver/vncserver.man -@@ -0,0 +1 @@ -+.so man8/vncsession.8 -diff --git a/unix/vncserver/vncserver.users b/unix/vncserver/vncserver.users -new file mode 100644 -index 0000000..24875c8 ---- /dev/null -+++ b/unix/vncserver/vncserver.users -@@ -0,0 +1,8 @@ -+# TigerVNC User assignment -+# -+# This file assigns users to specific VNC display numbers. -+# The syntax is =. E.g.: -+# -+# :2=andrew -+# :3=lisa -+ -diff --git a/unix/vncserver/vncserver@.service.in b/unix/vncserver/vncserver@.service.in -new file mode 100644 -index 0000000..584ecf4 ---- /dev/null -+++ b/unix/vncserver/vncserver@.service.in -@@ -0,0 +1,43 @@ -+# The vncserver service unit file -+# -+# Quick HowTo: -+# 1. Add a user mapping to /etc/tigervnc/vncserver.users. -+# 2. Adjust the global or user configuration. See the -+# vncsession(8) manpage for details. (OPTIONAL) -+# 3. Run `systemctl enable vncserver@:.service` -+# 4. Run `systemctl start vncserver@:.service` -+# -+# DO NOT RUN THIS SERVICE if your local area network is -+# untrusted! For a secure way of using VNC, you should -+# limit connections to the local host and then tunnel from -+# the machine you want to view VNC on (host A) to the machine -+# whose VNC output you want to view (host B) -+# -+# [user@hostA ~]$ ssh -v -C -L 590N:localhost:590M hostB -+# -+# this will open a connection on port 590N of your hostA to hostB's port 590M -+# (in fact, it ssh-connects to hostB and then connects to localhost (on hostB). -+# See the ssh man page for details on port forwarding) -+# -+# You can then point a VNC client on hostA at vncdisplay N of localhost and with -+# the help of ssh, you end up seeing what hostB makes available on port 590M -+# -+# Use "nolisten=tcp" to prevent X connections to your VNC server via TCP. -+# -+# Use "localhost" to prevent remote VNC clients connecting except when -+# doing so through a secure tunnel. See the "-via" option in the -+# `man vncviewer' manual page. -+ -+ -+[Unit] -+Description=Remote desktop service (VNC) -+After=syslog.target network.target -+ -+[Service] -+Type=forking -+ExecStart=@CMAKE_INSTALL_FULL_LIBEXECDIR@/vncsession-start %i -+PIDFile=/var/run/vncsession-%i.pid -+SELinuxContext=system_u:system_r:vnc_session_t:s0 -+ -+[Install] -+WantedBy=multi-user.target -diff --git a/unix/vncserver/vncsession-start.in b/unix/vncserver/vncsession-start.in -new file mode 100644 -index 0000000..b20fcdd ---- /dev/null -+++ b/unix/vncserver/vncsession-start.in -@@ -0,0 +1,43 @@ -+#!/bin/bash -+# -+# Copyright 2019 Pierre Ossman for Cendio AB -+# -+# This is free software; you can redistribute it and/or modify -+# it under the terms of the GNU General Public License as published by -+# the Free Software Foundation; either version 2 of the License, or -+# (at your option) any later version. -+# -+# This software is distributed in the hope that it will be useful, -+# but WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+# GNU General Public License for more details. -+# -+# You should have received a copy of the GNU General Public License -+# along with this software; if not, write to the Free Software -+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -+# USA. -+# -+ -+USERSFILE="@CMAKE_INSTALL_FULL_SYSCONFDIR@/tigervnc/vncserver.users" -+ -+if [ $# -ne 1 ]; then -+ echo "Syntax:" >&2 -+ echo " $0 " >&2 -+ exit 1 -+fi -+ -+if [ ! -f "${USERSFILE}" ]; then -+ echo "Users file ${USERSFILE} missing" >&2 -+ exit 1 -+fi -+ -+DISPLAY="$1" -+ -+USER=`grep "^${DISPLAY}=" "${USERSFILE}" 2>/dev/null | head -1 | cut -d = -f 2-` -+ -+if [ -z "${USER}" ]; then -+ echo "No user configured for display ${DISPLAY}" >&2 -+ exit 1 -+fi -+ -+exec "@CMAKE_INSTALL_FULL_SBINDIR@/vncsession" "${USER}" "${DISPLAY}" -diff --git a/unix/vncserver/vncsession.c b/unix/vncserver/vncsession.c -new file mode 100644 -index 0000000..21a40f6 ---- /dev/null -+++ b/unix/vncserver/vncsession.c -@@ -0,0 +1,592 @@ -+/* -+ * Copyright 2018 Pierre Ossman for Cendio AB -+ * -+ * This is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This software is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this software; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -+ * USA. -+ */ -+ -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+extern char **environ; -+ -+// PAM service name -+const char *SERVICE_NAME = "tigervnc"; -+ -+// Main script PID -+volatile static pid_t script = -1; -+ -+// Daemon completion pipe -+int daemon_pipe_fd = -1; -+ -+static int -+begin_daemon(void) -+{ -+ int devnull, fds[2]; -+ pid_t pid; -+ -+ /* Pipe to report startup success */ -+ if (pipe(fds) < 0) { -+ perror("pipe"); -+ return -1; -+ } -+ -+ /* First fork */ -+ pid = fork(); -+ if (pid < 0) { -+ perror("fork"); -+ return -1; -+ } -+ -+ if (pid != 0) { -+ ssize_t len; -+ char buf[1]; -+ -+ close(fds[1]); -+ -+ /* Wait for child to finish startup */ -+ len = read(fds[0], buf, 1); -+ if (len != 1) { -+ fprintf(stderr, "Failure daemonizing\n"); -+ _exit(EX_OSERR); -+ } -+ -+ _exit(0); -+ } -+ -+ close(fds[0]); -+ daemon_pipe_fd = fds[1]; -+ -+ /* Detach from terminal */ -+ if (setsid() < 0) { -+ perror("setsid"); -+ return -1; -+ } -+ -+ /* Another fork required to fully detach */ -+ pid = fork(); -+ if (pid < 0) { -+ perror("fork"); -+ return -1; -+ } -+ -+ if (pid == 0) -+ _exit(0); -+ -+ /* Send all stdio to /dev/null */ -+ devnull = open("/dev/null", O_RDWR); -+ if (devnull < 0) { -+ fprintf(stderr, "Failed to open /dev/null: %s\n", strerror(errno)); -+ return -1; -+ } -+ if ((dup2(devnull, 0) < 0) || -+ (dup2(devnull, 1) < 0) || -+ (dup2(devnull, 2) < 0)) { -+ perror("dup2"); -+ return -1; -+ } -+ if (devnull > 2) -+ close(devnull); -+ -+ /* Full control of access bits */ -+ umask(0); -+ -+ /* A safe working directory */ -+ if (chdir("/") < 0) { -+ perror("chdir"); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+static void -+finish_daemon(void) -+{ -+ write(daemon_pipe_fd, "+", 1); -+ close(daemon_pipe_fd); -+ daemon_pipe_fd = -1; -+} -+ -+static void -+sighandler(int sig) -+{ -+ if (script > 0) { -+ kill(script, SIGTERM); -+ } -+} -+ -+static void -+setup_signals(void) -+{ -+ struct sigaction act; -+ -+ memset(&act, 0, sizeof(act)); -+ act.sa_handler = sighandler; -+ sigemptyset(&act.sa_mask); -+ act.sa_flags = 0; -+ -+ sigaction(SIGHUP, &act, NULL); -+ sigaction(SIGINT, &act, NULL); -+ sigaction(SIGTERM, &act, NULL); -+ sigaction(SIGQUIT, &act, NULL); -+ sigaction(SIGPIPE, &act, NULL); -+} -+ -+static int -+conv(int num_msg, -+ const struct pam_message **msg, -+ struct pam_response **resp, void *appdata_ptr) -+{ -+ /* Opening a session should not require a conversation */ -+ return PAM_CONV_ERR; -+} -+ -+static pam_handle_t * -+run_pam(int *pamret, const char *username, const char *display) -+{ -+ pam_handle_t *pamh; -+ -+ /* Say hello to PAM */ -+ struct pam_conv pconv; -+ pconv.conv = conv; -+ pconv.appdata_ptr = NULL; -+ *pamret = pam_start(SERVICE_NAME, username, &pconv, &pamh); -+ if (*pamret != PAM_SUCCESS) { -+ /* pam_strerror requires a pamh argument, but if pam_start -+ fails, pamh is invalid. In practice, at least the Linux -+ implementation of pam_strerror does not use the pamh -+ argument, but let's take care - avoid pam_strerror here. */ -+ syslog(LOG_CRIT, "pam_start failed: %d", *pamret); -+ return NULL; -+ } -+ -+ /* ConsoleKit and systemd (and possibly others) uses this to -+ determine if the session is local or not. It needs to be set to -+ something that can't be interpreted as localhost. We don't know -+ what the client's address is though, and that might change on -+ reconnects. We also don't want to set it to some text string as -+ that results in a DNS lookup with e.g. libaudit. Let's use a -+ fake IPv4 address from the documentation range. */ -+ /* FIXME: This might throw an error on a IPv6-only host */ -+ *pamret = pam_set_item(pamh, PAM_RHOST, "203.0.113.20"); -+ if (*pamret != PAM_SUCCESS) { -+ syslog(LOG_CRIT, "pam_set_item(PAM_RHOST) failed: %d (%s)", -+ *pamret, pam_strerror(pamh, *pamret)); -+ return pamh; -+ } -+ -+#ifdef PAM_XDISPLAY -+ /* Let PAM modules use this to tag the session as a graphical one */ -+ *pamret = pam_set_item(pamh, PAM_XDISPLAY, display); -+ /* Note: PAM_XDISPLAY is only supported by modern versions of PAM */ -+ if (*pamret != PAM_BAD_ITEM && *pamret != PAM_SUCCESS) { -+ syslog(LOG_CRIT, "pam_set_item(PAM_XDISPLAY) failed: %d (%s)", -+ *pamret, pam_strerror(pamh, *pamret)); -+ return pamh; -+ } -+#endif -+ -+ /* Open session */ -+ *pamret = pam_open_session(pamh, PAM_SILENT); -+ if (*pamret != PAM_SUCCESS) { -+ syslog(LOG_CRIT, "pam_open_session failed: %d (%s)", -+ *pamret, pam_strerror(pamh, *pamret)); -+ return pamh; -+ } -+ -+ return pamh; -+} -+ -+static int -+stop_pam(pam_handle_t * pamh, int pamret) -+{ -+ /* Close session */ -+ if (pamret == PAM_SUCCESS) { -+ pamret = pam_close_session(pamh, PAM_SILENT); -+ if (pamret != PAM_SUCCESS) { -+ syslog(LOG_ERR, "pam_close_session failed: %d (%s)", -+ pamret, pam_strerror(pamh, pamret)); -+ } -+ } -+ -+ /* If PAM was OK and we are running on a SELinux system, new -+ processes images will be executed in the root context. */ -+ -+ /* Say goodbye */ -+ pamret = pam_end(pamh, pamret); -+ if (pamret != PAM_SUCCESS) { -+ /* avoid pam_strerror - we have no pamh. */ -+ syslog(LOG_ERR, "pam_end failed: %d", pamret); -+ return EX_OSERR; -+ } -+ return pamret; -+} -+ -+static char ** -+prepare_environ(pam_handle_t * pamh) -+{ -+ char **pam_env, **child_env, **entry; -+ int orig_count, pam_count; -+ -+ /* This function merges the normal environment with PAM's changes */ -+ -+ pam_env = pam_getenvlist(pamh); -+ if (pam_env == NULL) -+ return NULL; -+ -+ /* -+ * Worst case scenario is that PAM only adds variables, so allocate -+ * based on that assumption. -+ */ -+ orig_count = 0; -+ for (entry = environ; *entry != NULL; entry++) -+ orig_count++; -+ pam_count = 0; -+ for (entry = pam_env; *entry != NULL; entry++) -+ pam_count++; -+ -+ child_env = calloc(orig_count + pam_count + 1, sizeof(char *)); -+ if (child_env == NULL) -+ return NULL; -+ -+ memcpy(child_env, environ, sizeof(char *) * orig_count); -+ for (entry = child_env; *entry != NULL; entry++) { -+ *entry = strdup(*entry); -+ if (*entry == NULL) // FIXME: cleanup -+ return NULL; -+ } -+ -+ for (entry = pam_env; *entry != NULL; entry++) { -+ size_t varlen; -+ char **orig_entry; -+ -+ varlen = strcspn(*entry, "=") + 1; -+ -+ /* Check for overwrite */ -+ for (orig_entry = child_env; *orig_entry != NULL; orig_entry++) { -+ if (strncmp(*entry, *orig_entry, varlen) != 0) -+ continue; -+ -+ free(*orig_entry); -+ *orig_entry = *entry; -+ break; -+ } -+ -+ /* New variable? */ -+ if (*orig_entry == NULL) { -+ /* -+ * orig_entry will be pointing at the terminating entry, -+ * so we can just tack it on here. The new NULL was already -+ * prepared by calloc(). -+ */ -+ *orig_entry = *entry; -+ } -+ } -+ -+ return child_env; -+} -+ -+static void -+switch_user(const char *username, uid_t uid, gid_t gid) -+{ -+ // We must change group stuff first, because only root can do that. -+ if (setgid(gid) < 0) { -+ perror(": setgid"); -+ _exit(EX_OSERR); -+ } -+ -+ // Supplementary groups. -+ if (initgroups(username, gid) < 0) { -+ perror("initgroups"); -+ _exit(EX_OSERR); -+ } -+ -+ // Set euid, ruid and suid -+ if (setuid(uid) < 0) { -+ perror("setuid"); -+ _exit(EX_OSERR); -+ } -+} -+ -+static void -+redir_stdio(const char *homedir, const char *display) -+{ -+ int fd; -+ char hostname[HOST_NAME_MAX+1]; -+ char logfile[PATH_MAX]; -+ -+ fd = open("/dev/null", O_RDONLY); -+ if (fd == -1) { -+ perror("open"); -+ _exit(EX_OSERR); -+ } -+ if (dup2(fd, 0) == -1) { -+ perror("dup2"); -+ _exit(EX_OSERR); -+ } -+ close(fd); -+ -+ snprintf(logfile, sizeof(logfile), "%s/.vnc", homedir); -+ if (mkdir(logfile, 0755) == -1) { -+ if (errno != EEXIST) { -+ perror("mkdir"); -+ _exit(EX_OSERR); -+ } -+ } -+ -+ if (gethostname(hostname, sizeof(hostname)) == -1) { -+ perror("gethostname"); -+ _exit(EX_OSERR); -+ } -+ -+ snprintf(logfile, sizeof(logfile), "%s/.vnc/%s%s.log", -+ homedir, hostname, display); -+ fd = open(logfile, O_CREAT | O_WRONLY | O_TRUNC, 0644); -+ if (fd == -1) { -+ perror("open"); -+ _exit(EX_OSERR); -+ } -+ if ((dup2(fd, 1) == -1) || (dup2(fd, 2) == -1)) { -+ perror("dup2"); -+ _exit(EX_OSERR); -+ } -+ close(fd); -+} -+ -+static void -+close_fds(void) -+{ -+ DIR *dir; -+ struct dirent *entry; -+ -+ dir = opendir("/proc/self/fd"); -+ if (dir == NULL) { -+ perror("opendir"); -+ _exit(EX_OSERR); -+ } -+ -+ while ((entry = readdir(dir)) != NULL) { -+ int fd; -+ fd = atoi(entry->d_name); -+ if (fd < 3) -+ continue; -+ close(fd); -+ } -+ -+ closedir(dir); -+} -+ -+static pid_t -+run_script(const char *username, const char *display, char **envp) -+{ -+ struct passwd *pwent; -+ pid_t pid; -+ const char *child_argv[3]; -+ -+ pwent = getpwnam(username); -+ if (pwent == NULL) { -+ syslog(LOG_CRIT, "getpwnam: %s", strerror(errno)); -+ return -1; -+ } -+ -+ pid = fork(); -+ if (pid < 0) { -+ syslog(LOG_CRIT, "fork: %s", strerror(errno)); -+ return pid; -+ } -+ -+ /* two processes now */ -+ -+ if (pid > 0) -+ return pid; -+ -+ /* child */ -+ -+ switch_user(pwent->pw_name, pwent->pw_uid, pwent->pw_gid); -+ -+ close_fds(); -+ -+ redir_stdio(pwent->pw_dir, display); -+ -+ // execvpe() is not POSIX and is missing from older glibc -+ // First clear out everything -+ while ((environ != NULL) && (*environ != NULL)) { -+ char *var, *eq; -+ var = strdup(*environ); -+ eq = strchr(var, '='); -+ if (eq) -+ *eq = '\0'; -+ unsetenv(var); -+ free(var); -+ } -+ -+ // Then copy over the desired environment -+ for (; *envp != NULL; envp++) -+ putenv(*envp); -+ -+ // Set up some basic environment for the script -+ setenv("HOME", pwent->pw_dir, 1); -+ setenv("SHELL", pwent->pw_shell, 1); -+ setenv("LOGNAME", pwent->pw_name, 1); -+ setenv("USER", pwent->pw_name, 1); -+ setenv("USERNAME", pwent->pw_name, 1); -+ -+ child_argv[0] = CMAKE_INSTALL_FULL_LIBEXECDIR "/vncserver"; -+ child_argv[1] = display; -+ child_argv[2] = NULL; -+ -+ execvp(child_argv[0], (char*const*)child_argv); -+ -+ // execvp failed -+ perror("execvp"); -+ -+ _exit(EX_OSERR); -+} -+ -+int -+main(int argc, char **argv) -+{ -+ char pid_file[PATH_MAX]; -+ FILE *f; -+ -+ const char *username, *display; -+ -+ if ((argc != 3) || (argv[2][0] != ':')) { -+ fprintf(stderr, "Syntax:\n"); -+ fprintf(stderr, " %s \n", argv[0]); -+ return EX_USAGE; -+ } -+ -+ username = argv[1]; -+ display = argv[2]; -+ -+ if (geteuid() != 0) { -+ fprintf(stderr, "This program needs to be run as root!\n"); -+ return EX_USAGE; -+ } -+ -+ if (getpwnam(username) == NULL) { -+ if (errno == 0) -+ fprintf(stderr, "User \"%s\" does not exist\n", username); -+ else -+ fprintf(stderr, "Cannot look up user \"%s\": %s\n", -+ username, strerror(errno)); -+ return EX_OSERR; -+ } -+ -+ if (begin_daemon() == -1) -+ return EX_OSERR; -+ -+ openlog("vncsession", LOG_PID, LOG_AUTH); -+ -+ /* Indicate that this is a graphical user session. We need to do -+ this here before PAM as pam_systemd.so looks at these. */ -+ if ((putenv("XDG_SESSION_CLASS=user") < 0) || -+ (putenv("XDG_SESSION_TYPE=x11") < 0)) { -+ syslog(LOG_CRIT, "putenv: %s", strerror(errno)); -+ return EX_OSERR; -+ } -+ -+ /* Init PAM */ -+ int pamret; -+ pam_handle_t *pamh = run_pam(&pamret, username, display); -+ if (!pamh) { -+ return EX_OSERR; -+ } -+ if (pamret != PAM_SUCCESS) { -+ stop_pam(pamh, pamret); -+ return EX_OSERR; -+ } -+ -+ char **child_env; -+ child_env = prepare_environ(pamh); -+ if (child_env == NULL) { -+ syslog(LOG_CRIT, "Failure creating child process environment"); -+ stop_pam(pamh, pamret); -+ return EX_OSERR; -+ } -+ -+ setup_signals(); -+ -+ script = run_script(username, display, child_env); -+ if (script == -1) { -+ syslog(LOG_CRIT, "Failure starting vncserver script"); -+ stop_pam(pamh, pamret); -+ return EX_OSERR; -+ } -+ -+ snprintf(pid_file, sizeof(pid_file), -+ "/var/run/vncsession-%s.pid", display); -+ f = fopen(pid_file, "w"); -+ if (f == NULL) { -+ syslog(LOG_ERR, "Failure creating pid file \"%s\": %s", -+ pid_file, strerror(errno)); -+ } else { -+ fprintf(f, "%ld\n", (long)getpid()); -+ fclose(f); -+ } -+ -+ finish_daemon(); -+ -+ while (1) { -+ int status; -+ pid_t gotpid = waitpid(script, &status, 0); -+ if (gotpid < 0) { -+ if (errno != EINTR) { -+ syslog(LOG_CRIT, "waitpid: %s", strerror(errno)); -+ exit(EXIT_FAILURE); -+ } -+ continue; -+ } -+ if (WIFEXITED(status)) { -+ if (WEXITSTATUS(status) != 0) { -+ syslog(LOG_WARNING, -+ "vncsession: vncserver exited with status=%d", -+ WEXITSTATUS(status)); -+ } -+ break; -+ } -+ else if (WIFSIGNALED(status)) { -+ syslog(LOG_WARNING, -+ "vncsession: vncserver was terminated by signal %d", -+ WTERMSIG(status)); -+ break; -+ } -+ } -+ -+ unlink(pid_file); -+ -+ stop_pam(pamh, pamret); -+ -+ return 0; -+} -diff --git a/unix/vncserver/vncsession.man b/unix/vncserver/vncsession.man -new file mode 100644 -index 0000000..2138209 ---- /dev/null -+++ b/unix/vncserver/vncsession.man -@@ -0,0 +1,75 @@ -+.TH vncsession 8 "" "TigerVNC" "Virtual Network Computing" -+.SH NAME -+vncsession \- start a VNC server -+.SH SYNOPSIS -+.B vncsession -+.RI < username > -+.RI <: display# > -+.SH DESCRIPTION -+.B vncsession -+is used to start a VNC (Virtual Network Computing) desktop. -+.B vncsession -+performs all the necessary steps to create a new user session, run Xvnc with -+appropriate options and starts a window manager on the VNC desktop. -+ -+.B vncsession -+is rarely called directly and is normally started by the system service -+manager. -+ -+.SH FILES -+Several VNC-related files are found in the directory $HOME/.vnc: -+.TP -+/etc/tigervnc/vncserver-config-defaults -+The optional system-wide equivalent of $HOME/.vnc/config. If this file exists -+and defines options to be passed to Xvnc, they will be used as defaults for -+users. The user's $HOME/.vnc/config overrides settings configured in this file. -+The overall configuration file load order is: this file, $HOME/.vnc/config, -+and then /etc/tigervnc/vncserver-config-mandatory. None are required to exist. -+.TP -+/etc/tigervnc/vncserver-config-mandatory -+The optional system-wide equivalent of $HOME/.vnc/config. If this file exists -+and defines options to be passed to Xvnc, they will override any of the same -+options defined in a user's $HOME/.vnc/config. This file offers a mechanism -+to establish some basic form of system-wide policy. WARNING! There is -+nothing stopping users from constructing their own vncsession-like script -+that calls Xvnc directly to bypass any options defined in -+/etc/tigervnc/vncserver-config-mandatory. The overall configuration file load -+order is: /etc/tigervnc/vncserver-config-defaults, $HOME/.vnc/config, and then -+this file. None are required to exist. -+.TP -+$HOME/.vnc/config -+An optional server config file wherein options to be passed to Xvnc are listed -+to avoid hard-coding them to the physical invocation. List options in this file -+one per line. For those requiring an argument, simply separate the option from -+the argument with an equal sign, for example: "geometry=2000x1200" or -+"securitytypes=vncauth,tlsvnc". Options without an argument are simply listed -+as a single word, for example: "localhost" or "alwaysshared". -+ -+The special option -+.B session -+can be used to control which session type will be started. This should match -+one of the files in \fI/usr/share/xsessions\fP. E.g. if there is a file called -+"gnome.desktop", then "session=gnome" would be set to use that session type. -+.TP -+$HOME/.vnc/passwd -+The VNC password file. -+.TP -+$HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.log -+The log file for Xvnc and the session. -+ -+.SH SEE ALSO -+.BR vncviewer (1), -+.BR vncpasswd (1), -+.BR vncconfig (1), -+.BR Xvnc (1) -+.br -+https://www.tigervnc.org -+ -+.SH AUTHOR -+Tristan Richardson, RealVNC Ltd., D. R. Commander and others. -+ -+VNC was originally developed by the RealVNC team while at Olivetti -+Research Ltd / AT&T Laboratories Cambridge. TightVNC additions were -+implemented by Constantin Kaplinsky. Many other people have since -+participated in development, testing and support. This manual is part -+of the TigerVNC software suite. -diff --git a/unix/x0vncserver/CMakeLists.txt b/unix/x0vncserver/CMakeLists.txt -index 8beade7..af82415 100644 ---- a/unix/x0vncserver/CMakeLists.txt -+++ b/unix/x0vncserver/CMakeLists.txt -@@ -52,5 +52,5 @@ endif() - - target_link_libraries(x0vncserver ${X11_LIBRARIES}) - --install(TARGETS x0vncserver DESTINATION ${BIN_DIR}) --install(FILES x0vncserver.man DESTINATION ${MAN_DIR}/man1 RENAME x0vncserver.1) -+install(TARGETS x0vncserver DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}) -+install(FILES x0vncserver.man DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man1 RENAME x0vncserver.1) -diff --git a/unix/xserver/hw/vnc/Xvnc.man b/unix/xserver/hw/vnc/Xvnc.man -index 9c8a889..9559179 100644 ---- a/unix/xserver/hw/vnc/Xvnc.man -+++ b/unix/xserver/hw/vnc/Xvnc.man -@@ -18,9 +18,9 @@ that the VNC server display number will be the same as the X server display - number, which means you can use eg. snoopy:2 to refer to display 2 on machine - "snoopy" in both the X world and the VNC world. - --The best way of starting \fBXvnc\fP is via the \fBvncserver\fP script. This --sets up the environment appropriately and runs some X applications to get you --going. See the manual page for \fBvncserver\fP(1) for more information. -+The best way of starting \fBXvnc\fP is via \fBvncsession\fP. This sets up the -+environment appropriately and starts a desktop environment. See the manual -+page for \fBvncsession\fP(8) for more information. - - .SH OPTIONS - .B Xvnc -@@ -383,8 +383,8 @@ created automatically the next time he connects. - .SH SEE ALSO - .BR vncconfig (1), - .BR vncpasswd (1), --.BR vncserver (1), - .BR vncviewer (1), -+.BR vncsession (8), - .BR Xserver (1), - .BR inetd (1) - .br -diff --git a/vncviewer/CMakeLists.txt b/vncviewer/CMakeLists.txt -index 3c18646..7e25d45 100644 ---- a/vncviewer/CMakeLists.txt -+++ b/vncviewer/CMakeLists.txt -@@ -60,9 +60,9 @@ if(APPLE) - target_link_libraries(vncviewer "-framework IOKit") - endif() - --install(TARGETS vncviewer DESTINATION ${BIN_DIR}) -+install(TARGETS vncviewer DESTINATION ${CMAKE_INSTALL_FULL_BINDIR}) - if(UNIX) -- install(FILES vncviewer.man DESTINATION ${MAN_DIR}/man1 RENAME vncviewer.1) -+ install(FILES vncviewer.man DESTINATION ${CMAKE_INSTALL_FULL_MANDIR}/man1 RENAME vncviewer.1) - - configure_file(vncviewer.desktop.in.in vncviewer.desktop.in) - find_program(INTLTOOL_MERGE_EXECUTABLE intltool-merge) -@@ -91,10 +91,10 @@ if(UNIX) - ) - endif() - add_custom_target(desktop ALL DEPENDS vncviewer.desktop) -- install(FILES ${CMAKE_CURRENT_BINARY_DIR}/vncviewer.desktop DESTINATION ${DATA_DIR}/applications) -+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/vncviewer.desktop DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/applications) - - foreach(res 16 22 24 32 48) -- install(FILES ../media/icons/tigervnc_${res}.png DESTINATION ${DATA_DIR}/icons/hicolor/${res}x${res}/apps RENAME tigervnc.png) -+ install(FILES ../media/icons/tigervnc_${res}.png DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/icons/hicolor/${res}x${res}/apps RENAME tigervnc.png) - endforeach() -- install(FILES ../media/icons/tigervnc.svg DESTINATION ${DATA_DIR}/icons/hicolor/scalable/apps) -+ install(FILES ../media/icons/tigervnc.svg DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/icons/hicolor/scalable/apps) - endif() -diff --git a/vncviewer/vncviewer.cxx b/vncviewer/vncviewer.cxx -index 4a8370b..ae4cb6f 100644 ---- a/vncviewer/vncviewer.cxx -+++ b/vncviewer/vncviewer.cxx -@@ -227,7 +227,7 @@ static void init_fltk() - bool exists; - - sprintf(icon_path, "%s/icons/hicolor/%dx%d/apps/tigervnc.png", -- DATA_DIR, icon_sizes[i], icon_sizes[i]); -+ CMAKE_INSTALL_FULL_DATADIR, icon_sizes[i], icon_sizes[i]); - - #ifndef WIN32 - struct stat st; -@@ -505,7 +505,7 @@ int main(int argc, char** argv) - argv0 = argv[0]; - - setlocale(LC_ALL, ""); -- bindtextdomain(PACKAGE_NAME, LOCALE_DIR); -+ bindtextdomain(PACKAGE_NAME, CMAKE_INSTALL_FULL_LOCALEDIR); - textdomain(PACKAGE_NAME); - - rfb::SecurityClient::setDefaults(); -diff --git a/vncviewer/vncviewer.desktop.in.in b/vncviewer/vncviewer.desktop.in.in -index d775dde..9d658e4 100644 ---- a/vncviewer/vncviewer.desktop.in.in -+++ b/vncviewer/vncviewer.desktop.in.in -@@ -2,7 +2,7 @@ - Name=TigerVNC Viewer - GenericName=Remote Desktop Viewer - Comment=Connect to VNC server and display remote desktop --Exec=@BIN_DIR@/vncviewer -+Exec=@CMAKE_INSTALL_FULL_BINDIR@/vncviewer - Icon=tigervnc - Terminal=false - Type=Application -diff --git a/vncviewer/vncviewer.man b/vncviewer/vncviewer.man -index f93e096..a8d8c77 100644 ---- a/vncviewer/vncviewer.man -+++ b/vncviewer/vncviewer.man -@@ -327,7 +327,7 @@ Default certificate revocation list. - .BR Xvnc (1), - .BR vncpasswd (1), - .BR vncconfig (1), --.BR vncserver (1) -+.BR vncsession (8) - .br - https://www.tigervnc.org - diff --git a/SOURCES/tigervnc-use-gnome-as-default-session.patch b/SOURCES/tigervnc-use-gnome-as-default-session.patch new file mode 100644 index 0000000..a767c40 --- /dev/null +++ b/SOURCES/tigervnc-use-gnome-as-default-session.patch @@ -0,0 +1,12 @@ +diff --git a/unix/vncserver/vncserver-config-defaults b/unix/vncserver/vncserver-config-defaults +index 0c217bf..2889347 100644 +--- a/unix/vncserver/vncserver-config-defaults ++++ b/unix/vncserver/vncserver-config-defaults +@@ -13,3 +13,7 @@ + # geometry=2000x1200 + # localhost + # alwaysshared ++ ++# Default to GNOME session ++# Note: change this only when you know what are you doing ++session=gnome diff --git a/SOURCES/vncserver b/SOURCES/vncserver new file mode 100644 index 0000000..bd2f422 --- /dev/null +++ b/SOURCES/vncserver @@ -0,0 +1,890 @@ +#!/usr/bin/perl +# +# Copyright (C) 2009-2010 D. R. Commander. All Rights Reserved. +# Copyright (C) 2005-2006 Sun Microsystems, Inc. All Rights Reserved. +# Copyright (C) 2002-2003 Constantin Kaplinsky. All Rights Reserved. +# Copyright (C) 2002-2005 RealVNC Ltd. +# Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +# +# This is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This software is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this software; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. +# + +# +# vncserver - wrapper script to start an X VNC server. +# + +# First make sure we're operating in a sane environment. +$exedir = ""; +$slashndx = rindex($0, "/"); +if($slashndx>=0) { + $exedir = substr($0, 0, $slashndx+1); +} + +&SanityCheck(); + +&NotifyAboutDeprecation(); + +# +# Global variables. You may want to configure some of these for +# your site +# + +$geometry = "1024x768"; +#$depth = 16; + +$vncUserDir = "$ENV{HOME}/.vnc"; +$vncUserConfig = "$vncUserDir/config"; + +$vncSystemConfigDir = "/etc/tigervnc"; +$vncSystemConfigDefaultsFile = "$vncSystemConfigDir/vncserver-config-defaults"; +$vncSystemConfigMandatoryFile = "$vncSystemConfigDir/vncserver-config-mandatory"; + +$skipxstartup = 0; +$xauthorityFile = "$ENV{XAUTHORITY}" || "$ENV{HOME}/.Xauthority"; + +$xstartupFile = $vncUserDir . "/xstartup"; +$defaultXStartup + = ("#!/bin/sh\n\n". + "unset SESSION_MANAGER\n". + "unset DBUS_SESSION_BUS_ADDRESS\n". + "exec /etc/X11/xinit/xinitrc\n"); + +$defaultConfig + = ("## Supported server options to pass to vncserver upon invocation can be listed\n". + "## in this file. See the following manpages for more: vncserver(1) Xvnc(1).\n". + "## Several common ones are shown below. Uncomment and modify to your liking.\n". + "##\n". + "# securitytypes=vncauth,tlsvnc\n". + "# desktop=sandbox\n". + "# geometry=2000x1200\n". + "# localhost\n". + "# alwaysshared\n"); + +chop($host = `uname -n`); + +if (-d "/etc/X11/fontpath.d") { + $fontPath = "catalogue:/etc/X11/fontpath.d"; +} + +@fontpaths = ('/usr/share/X11/fonts', '/usr/share/fonts', '/usr/share/fonts/X11/'); +if (! -l "/usr/lib/X11") {push(@fontpaths, '/usr/lib/X11/fonts');} +if (! -l "/usr/X11") {push(@fontpaths, '/usr/X11/lib/X11/fonts');} +if (! -l "/usr/X11R6") {push(@fontpaths, '/usr/X11R6/lib/X11/fonts');} +push(@fontpaths, '/usr/share/fonts/default'); + +@fonttypes = ('misc', + '75dpi', + '100dpi', + 'Speedo', + 'Type1'); + +foreach $_fpath (@fontpaths) { + foreach $_ftype (@fonttypes) { + if (-f "$_fpath/$_ftype/fonts.dir") { + if (! -l "$_fpath/$_ftype") { + $defFontPath .= "$_fpath/$_ftype,"; + } + } + } +} + +if ($defFontPath) { + if (substr($defFontPath, -1, 1) == ',') { + chop $defFontPath; + } +} + +if ($fontPath eq "") { + $fontPath = $defFontPath; +} + +# Check command line options + +&ParseOptions("-geometry",1,"-depth",1,"-pixelformat",1,"-name",1,"-kill",1, + "-help",0,"-h",0,"--help",0,"-fp",1,"-list",0,"-fg",0,"-autokill",0,"-noxstartup",0,"-xstartup",1); + +&Usage() if ($opt{'-help'} || $opt{'-h'} || $opt{'--help'}); + +&Kill() if ($opt{'-kill'}); + +&List() if ($opt{'-list'}); + +# Uncomment this line if you want default geometry, depth and pixelformat +# to match the current X display: +# &GetXDisplayDefaults(); + +if ($opt{'-geometry'}) { + $geometry = $opt{'-geometry'}; +} +if ($opt{'-depth'}) { + $depth = $opt{'-depth'}; + $pixelformat = ""; +} +if ($opt{'-pixelformat'}) { + $pixelformat = $opt{'-pixelformat'}; +} +if ($opt{'-noxstartup'}) { + $skipxstartup = 1; +} +if ($opt{'-xstartup'}) { + $xstartupFile = $opt{'-xstartup'}; +} +if ($opt{'-fp'}) { + $fontPath = $opt{'-fp'}; + $fpArgSpecified = 1; +} + +&CheckGeometryAndDepth(); + +# Create the user's vnc directory if necessary. +if (!(-e $vncUserDir)) { + if (!mkdir($vncUserDir,0755)) { + die "$prog: Could not create $vncUserDir.\n"; + } +} + +# Find display number. +if ((@ARGV > 0) && ($ARGV[0] =~ /^:(\d+)$/)) { + $displayNumber = $1; + shift(@ARGV); + if (!&CheckDisplayNumber($displayNumber)) { + die "A VNC server is already running as :$displayNumber\n"; + } +} elsif ((@ARGV > 0) && ($ARGV[0] !~ /^-/) && ($ARGV[0] !~ /^\+/)) { + &Usage(); +} else { + $displayNumber = &GetDisplayNumber(); +} + +$vncPort = 5900 + $displayNumber; + +if ($opt{'-name'}) { + $desktopName = $opt{'-name'}; +} else { + $desktopName = "$host:$displayNumber ($ENV{USER})"; +} + +my %default_opts; +my %config; + +# We set some reasonable defaults. Config file settings +# override these where present. +$default_opts{desktop} = "edString($desktopName); +$default_opts{auth} = "edString($xauthorityFile); +$default_opts{geometry} = $geometry if ($geometry); +$default_opts{depth} = $depth if ($depth); +$default_opts{pixelformat} = $pixelformat if ($pixelformat); +$default_opts{rfbwait} = 30000; +$default_opts{rfbauth} = "$vncUserDir/passwd"; +$default_opts{rfbport} = $vncPort; +$default_opts{fp} = $fontPath if ($fontPath); +$default_opts{pn} = ""; + +# Load user-overrideable system defaults +LoadConfig($vncSystemConfigDefaultsFile); + +# Then the user's settings +LoadConfig($vncUserConfig); + +# And then override anything set above if mandatory settings exist. +# WARNING: "Mandatory" is used loosely here! As the man page says, +# there is nothing stopping someone from EASILY subverting the +# settings in $vncSystemConfigMandatoryFile by simply passing +# CLI args to vncserver, which trump config files! To properly +# hard force policy in a non-subvertible way would require major +# development work that touches Xvnc itself. +LoadConfig($vncSystemConfigMandatoryFile, 1); + +# +# Check whether VNC authentication is enabled, and if so, prompt the user to +# create a VNC password if they don't already have one. +# + +$securityTypeArgSpecified = 0; +$vncAuthEnabled = 0; +$passwordArgSpecified = 0; +@vncAuthStrings = ("vncauth", "tlsvnc", "x509vnc"); + +# ...first we check our configuration files' settings +if ($config{'securitytypes'}) { + $securityTypeArgSpecified = 1; + foreach $arg2 (split(',', $config{'securitytypes'})) { + if (grep {$_ eq lc($arg2)} @vncAuthStrings) { + $vncAuthEnabled = 1; + } + } +} + +# ...and finally we check CLI args, which in the case of the topic at +# hand (VNC auth or not), override anything found in configuration files +# (even so-called "mandatory" settings). +for ($i = 0; $i < @ARGV; ++$i) { + # -SecurityTypes can be followed by a space or "=" + my @splitargs = split('=', $ARGV[$i]); + if (@splitargs <= 1 && $i < @ARGV - 1) { + push(@splitargs, $ARGV[$i + 1]); + } + if (lc(@splitargs[0]) eq "-securitytypes") { + if (@splitargs > 1) { + $securityTypeArgSpecified = 1; + } + foreach $arg2 (split(',', @splitargs[1])) { + if (grep {$_ eq lc($arg2)} @vncAuthStrings) { + $vncAuthEnabled = 1; + } + } + } + if ((lc(@splitargs[0]) eq "-password") + || (lc(@splitargs[0]) eq "-passwordfile" + || (lc(@splitargs[0]) eq "-rfbauth"))) { + $passwordArgSpecified = 1; + } +} + +if ((!$securityTypeArgSpecified || $vncAuthEnabled) && !$passwordArgSpecified) { + ($z,$z,$mode) = stat("$vncUserDir/passwd"); + if (!(-e "$vncUserDir/passwd") || ($mode & 077)) { + warn "\nYou will require a password to access your desktops.\n\n"; + system($exedir."vncpasswd -q $vncUserDir/passwd"); + if (($? >> 8) != 0) { + exit 1; + } + } +} + +$desktopLog = "$vncUserDir/$host:$displayNumber.log"; +unlink($desktopLog); + +# Make an X server cookie and set up the Xauthority file +# mcookie is a part of util-linux, usually only GNU/Linux systems have it. +$cookie = `mcookie`; +# Fallback for non GNU/Linux OS - use /dev/urandom on systems that have it, +# otherwise use perl's random number generator, seeded with the sum +# of the current time, our PID and part of the encrypted form of the password. +if ($cookie eq "" && open(URANDOM, '<', '/dev/urandom')) { + my $randata; + if (sysread(URANDOM, $randata, 16) == 16) { + $cookie = unpack 'h*', $randata; + } + close(URANDOM); +} +if ($cookie eq "") { + srand(time+$$+unpack("L",`cat $vncUserDir/passwd`)); + for (1..16) { + $cookie .= sprintf("%02x", int(rand(256)) % 256); + } +} + +open(XAUTH, "|xauth -f $xauthorityFile source -"); +print XAUTH "add $host:$displayNumber . $cookie\n"; +print XAUTH "add $host/unix:$displayNumber . $cookie\n"; +close(XAUTH); + +# Now start the X VNC Server + +# We build up our Xvnc command with options +$cmd = $exedir."Xvnc :$displayNumber"; + +foreach my $k (sort keys %config) { + $cmd .= " -$k $config{$k}"; + delete $default_opts{$k}; # file options take precedence +} + +foreach my $k (sort keys %default_opts) { + $cmd .= " -$k $default_opts{$k}"; +} + +# Add color database stuff here, e.g.: +# $cmd .= " -co /usr/lib/X11/rgb"; + +foreach $arg (@ARGV) { + $cmd .= " " . "edString($arg); +} +$cmd .= " >> " . "edString($desktopLog) . " 2>&1"; + +# Run $cmd and record the process ID. +$pidFile = "$vncUserDir/$host:$displayNumber.pid"; +system("$cmd & echo \$! >$pidFile"); + +# Give Xvnc a chance to start up + +sleep(3); +if ($fontPath ne $defFontPath) { + unless (kill 0, `cat $pidFile`) { + if ($fpArgSpecified) { + warn "\nWARNING: The first attempt to start Xvnc failed, probably because the font\n"; + warn "path you specified using the -fp argument is incorrect. Attempting to\n"; + warn "determine an appropriate font path for this system and restart Xvnc using\n"; + warn "that font path ...\n"; + } else { + warn "\nWARNING: The first attempt to start Xvnc failed, possibly because the font\n"; + warn "catalog is not properly configured. Attempting to determine an appropriate\n"; + warn "font path for this system and restart Xvnc using that font path ...\n"; + } + $cmd =~ s@-fp [^ ]+@@; + $cmd .= " -fp $defFontPath" if ($defFontPath); + system("$cmd & echo \$! >$pidFile"); + sleep(3); + } +} +unless (kill 0, `cat $pidFile`) { + warn "Could not start Xvnc.\n\n"; + unlink $pidFile; + open(LOG, "<$desktopLog"); + while () { print; } + close(LOG); + die "\n"; +} + +warn "\nNew '$desktopName' desktop is $host:$displayNumber\n\n"; + +# Create the user's xstartup script if necessary. +if (! $skipxstartup) { + if (!(-e "$xstartupFile")) { + warn "Creating default startup script $xstartupFile\n"; + open(XSTARTUP, ">$xstartupFile"); + print XSTARTUP $defaultXStartup; + close(XSTARTUP); + chmod 0755, "$xstartupFile"; + } +} + +# Create the user's config file if necessary. +if (!(-e "$vncUserDir/config")) { + warn "Creating default config $vncUserDir/config\n"; + open(VNCUSERCONFIG, ">$vncUserDir/config"); + print VNCUSERCONFIG $defaultConfig; + close(VNCUSERCONFIG); + chmod 0644, "$vncUserDir/config"; +} + +# Run the X startup script. +if (! $skipxstartup) { + warn "Starting applications specified in $xstartupFile\n"; +} +warn "Log file is $desktopLog\n\n"; + +# If the unix domain socket exists then use that (DISPLAY=:n) otherwise use +# TCP (DISPLAY=host:n) + +if (-e "/tmp/.X11-unix/X$displayNumber" || + -e "/usr/spool/sockets/X11/$displayNumber") +{ + $ENV{DISPLAY}= ":$displayNumber"; +} else { + $ENV{DISPLAY}= "$host:$displayNumber"; +} +$ENV{VNCDESKTOP}= $desktopName; + +if ($opt{'-fg'}) { + if (! $skipxstartup) { + system("$xstartupFile >> " . "edString($desktopLog) . " 2>&1"); + } + if (kill 0, `cat $pidFile`) { + $opt{'-kill'} = ':'.$displayNumber; + &Kill(); + } +} else { + if ($opt{'-autokill'}) { + if (! $skipxstartup) { + system("($xstartupFile; $0 -kill :$displayNumber) >> " + . "edString($desktopLog) . " 2>&1 &"); + } + } else { + if (! $skipxstartup) { + system("$xstartupFile >> " . "edString($desktopLog) + . " 2>&1 &"); + } + } +} + +exit; + +############################################################################### +# Functions +############################################################################### + +# +# Populate the global %config hash with settings from a specified +# vncserver configuration file if it exists +# +# Args: 1. file path +# 2. optional boolean flag to enable warning when a previously +# set configuration setting is being overridden +# +sub LoadConfig { + local ($configFile, $warnoverride) = @_; + local ($toggle) = undef; + + if (stat($configFile)) { + if (open(IN, $configFile)) { + while () { + next if /^#/; + if (my ($k, $v) = /^\s*(\w+)\s*=\s*(.+)$/) { + $k = lc($k); # must normalize key case + if ($k eq "session") { + next; + } + if ($warnoverride && $config{$k}) { + print("Warning: $configFile is overriding previously defined '$k' to be '$v'\n"); + } + $config{$k} = $v; + } elsif ($_ =~ m/^\s*(\S+)/) { + # We can't reasonably warn on override of toggles (e.g. AlwaysShared) + # because it would get crazy to do so. We'd have to check if the + # current config file being loaded defined the logical opposite setting + # (NeverShared vs. AlwaysShared, etc etc). + $toggle = lc($1); # must normalize key case + $config{$toggle} = $k; + } + } + close(IN); + } + } +} + +# +# CheckGeometryAndDepth simply makes sure that the geometry and depth values +# are sensible. +# + +sub CheckGeometryAndDepth +{ + if ($geometry =~ /^(\d+)x(\d+)$/) { + $width = $1; $height = $2; + + if (($width<1) || ($height<1)) { + die "$prog: geometry $geometry is invalid\n"; + } + + $geometry = "${width}x$height"; + } else { + die "$prog: geometry $geometry is invalid\n"; + } + + if ($depth && (($depth < 8) || ($depth > 32))) { + die "Depth must be between 8 and 32\n"; + } +} + + +# +# GetDisplayNumber gets the lowest available display number. A display number +# n is taken if something is listening on the VNC server port (5900+n) or the +# X server port (6000+n). +# + +sub GetDisplayNumber +{ + foreach $n (1..99) { + if (&CheckDisplayNumber($n)) { + return $n+0; # Bruce Mah's workaround for bug in perl 5.005_02 + } + } + + die "$prog: no free display number on $host.\n"; +} + + +# +# CheckDisplayNumber checks if the given display number is available. A +# display number n is taken if something is listening on the VNC server port +# (5900+n) or the X server port (6000+n). +# + +sub CheckDisplayNumber +{ + local ($n) = @_; + + socket(S, $AF_INET, $SOCK_STREAM, 0) || die "$prog: socket failed: $!\n"; + eval 'setsockopt(S, &SOL_SOCKET, &SO_REUSEADDR, pack("l", 1))'; + if (!bind(S, pack('S n x12', $AF_INET, 6000 + $n))) { + close(S); + return 0; + } + close(S); + + socket(S, $AF_INET, $SOCK_STREAM, 0) || die "$prog: socket failed: $!\n"; + eval 'setsockopt(S, &SOL_SOCKET, &SO_REUSEADDR, pack("l", 1))'; + if (!bind(S, pack('S n x12', $AF_INET, 5900 + $n))) { + close(S); + return 0; + } + close(S); + + if (-e "/tmp/.X$n-lock") { + warn "\nWarning: $host:$n is taken because of /tmp/.X$n-lock\n"; + warn "Remove this file if there is no X server $host:$n\n"; + return 0; + } + + if (-e "/tmp/.X11-unix/X$n") { + warn "\nWarning: $host:$n is taken because of /tmp/.X11-unix/X$n\n"; + warn "Remove this file if there is no X server $host:$n\n"; + return 0; + } + + if (-e "/usr/spool/sockets/X11/$n") { + warn("\nWarning: $host:$n is taken because of ". + "/usr/spool/sockets/X11/$n\n"); + warn "Remove this file if there is no X server $host:$n\n"; + return 0; + } + + return 1; +} + + +# +# GetXDisplayDefaults uses xdpyinfo to find out the geometry, depth and pixel +# format of the current X display being used. If successful, it sets the +# options as appropriate so that the X VNC server will use the same settings +# (minus an allowance for window manager decorations on the geometry). Using +# the same depth and pixel format means that the VNC server won't have to +# translate pixels when the desktop is being viewed on this X display (for +# TrueColor displays anyway). +# + +sub GetXDisplayDefaults +{ + local (@lines, @matchlines, $width, $height, $defaultVisualId, $i, + $red, $green, $blue); + + $wmDecorationWidth = 4; # a guess at typical size for window manager + $wmDecorationHeight = 24; # decoration size + + return if (!defined($ENV{DISPLAY})); + + @lines = `xdpyinfo 2>/dev/null`; + + return if ($? != 0); + + @matchlines = grep(/dimensions/, @lines); + if (@matchlines) { + ($width, $height) = ($matchlines[0] =~ /(\d+)x(\d+) pixels/); + + $width -= $wmDecorationWidth; + $height -= $wmDecorationHeight; + + $geometry = "${width}x$height"; + } + + @matchlines = grep(/default visual id/, @lines); + if (@matchlines) { + ($defaultVisualId) = ($matchlines[0] =~ /id:\s+(\S+)/); + + for ($i = 0; $i < @lines; $i++) { + if ($lines[$i] =~ /^\s*visual id:\s+$defaultVisualId$/) { + if (($lines[$i+1] !~ /TrueColor/) || + ($lines[$i+2] !~ /depth/) || + ($lines[$i+4] !~ /red, green, blue masks/)) + { + return; + } + last; + } + } + + return if ($i >= @lines); + + ($depth) = ($lines[$i+2] =~ /depth:\s+(\d+)/); + ($red,$green,$blue) + = ($lines[$i+4] + =~ /masks:\s+0x([0-9a-f]+), 0x([0-9a-f]+), 0x([0-9a-f]+)/); + + $red = hex($red); + $green = hex($green); + $blue = hex($blue); + + if ($red > $blue) { + $red = int(log($red) / log(2)) - int(log($green) / log(2)); + $green = int(log($green) / log(2)) - int(log($blue) / log(2)); + $blue = int(log($blue) / log(2)) + 1; + $pixelformat = "rgb$red$green$blue"; + } else { + $blue = int(log($blue) / log(2)) - int(log($green) / log(2)); + $green = int(log($green) / log(2)) - int(log($red) / log(2)); + $red = int(log($red) / log(2)) + 1; + $pixelformat = "bgr$blue$green$red"; + } + } +} + + +# +# quotedString returns a string which yields the original string when parsed +# by a shell. +# + +sub quotedString +{ + local ($in) = @_; + + $in =~ s/\'/\'\"\'\"\'/g; + + return "'$in'"; +} + + +# +# removeSlashes turns slashes into underscores for use as a file name. +# + +sub removeSlashes +{ + local ($in) = @_; + + $in =~ s|/|_|g; + + return "$in"; +} + + +# +# Usage +# + +sub Usage +{ + die("\nusage: $prog [:] [-name ] [-depth ]\n". + " [-geometry x]\n". + " [-pixelformat rgbNNN|bgrNNN]\n". + " [-fp ]\n". + " [-cc ]\n". + " [-fg]\n". + " [-autokill]\n". + " [-noxstartup]\n". + " [-xstartup ]\n". + " ...\n\n". + " $prog -kill \n\n". + " $prog -list\n\n"); +} + + +# +# List +# + +sub List +{ + opendir(dir, $vncUserDir); + my @filelist = readdir(dir); + closedir(dir); + print "\nTigerVNC server sessions:\n\n"; + print "X DISPLAY #\tPROCESS ID\n"; + foreach my $file (@filelist) { + if ($file =~ /$host:(\d+)$\.pid/) { + chop($tmp_pid = `cat $vncUserDir/$file`); + if (kill 0, $tmp_pid) { + print ":".$1."\t\t".`cat $vncUserDir/$file`; + } else { + unlink ($vncUserDir . "/" . $file); + } + } + } + exit; +} + + +# +# Kill +# + +sub Kill +{ + $opt{'-kill'} =~ s/(:\d+)\.\d+$/$1/; # e.g. turn :1.0 into :1 + + if ($opt{'-kill'} =~ /^:\d+$/) { + $pidFile = "$vncUserDir/$host$opt{'-kill'}.pid"; + } else { + if ($opt{'-kill'} !~ /^$host:/) { + die "\nCan't tell if $opt{'-kill'} is on $host\n". + "Use -kill : instead\n\n"; + } + $pidFile = "$vncUserDir/$opt{'-kill'}.pid"; + } + + if (! -r $pidFile) { + die "\nCan't find file $pidFile\n". + "You'll have to kill the Xvnc process manually\n\n"; + } + + $SIG{'HUP'} = 'IGNORE'; + chop($pid = `cat $pidFile`); + warn "Killing Xvnc process ID $pid\n"; + + if (kill 0, $pid) { + system("kill $pid"); + sleep(1); + if (kill 0, $pid) { + print "Xvnc seems to be deadlocked. Kill the process manually and then re-run\n"; + print " ".$0." -kill ".$opt{'-kill'}."\n"; + print "to clean up the socket files.\n"; + exit + } + + } else { + warn "Xvnc process ID $pid already killed\n"; + $opt{'-kill'} =~ s/://; + + if (-e "/tmp/.X11-unix/X$opt{'-kill'}") { + print "Xvnc did not appear to shut down cleanly."; + print " Removing /tmp/.X11-unix/X$opt{'-kill'}\n"; + unlink "/tmp/.X11-unix/X$opt{'-kill'}"; + } + if (-e "/tmp/.X$opt{'-kill'}-lock") { + print "Xvnc did not appear to shut down cleanly."; + print " Removing /tmp/.X$opt{'-kill'}-lock\n"; + unlink "/tmp/.X$opt{'-kill'}-lock"; + } + } + + unlink $pidFile; + exit; +} + + +# +# ParseOptions takes a list of possible options and a boolean indicating +# whether the option has a value following, and sets up an associative array +# %opt of the values of the options given on the command line. It removes all +# the arguments it uses from @ARGV and returns them in @optArgs. +# + +sub ParseOptions +{ + local (@optval) = @_; + local ($opt, @opts, %valFollows, @newargs); + + while (@optval) { + $opt = shift(@optval); + push(@opts,$opt); + $valFollows{$opt} = shift(@optval); + } + + @optArgs = (); + %opt = (); + + arg: while (defined($arg = shift(@ARGV))) { + foreach $opt (@opts) { + if ($arg eq $opt) { + push(@optArgs, $arg); + if ($valFollows{$opt}) { + if (@ARGV == 0) { + &Usage(); + } + $opt{$opt} = shift(@ARGV); + push(@optArgs, $opt{$opt}); + } else { + $opt{$opt} = 1; + } + next arg; + } + } + push(@newargs,$arg); + } + + @ARGV = @newargs; +} + + +# Routine to make sure we're operating in a sane environment. +sub SanityCheck +{ + local ($cmd); + + # Get the program name + ($prog) = ($0 =~ m|([^/]+)$|); + + # + # Check we have all the commands we'll need on the path. + # + + cmd: + foreach $cmd ("uname","xauth") { + for (split(/:/,$ENV{PATH})) { + if (-x "$_/$cmd") { + next cmd; + } + } + die "$prog: couldn't find \"$cmd\" on your PATH.\n"; + } + + if($exedir eq "") { + cmd2: + foreach $cmd ("Xvnc","vncpasswd") { + for (split(/:/,$ENV{PATH})) { + if (-x "$_/$cmd") { + next cmd2; + } + } + die "$prog: couldn't find \"$cmd\" on your PATH.\n"; + } + } + else { + cmd3: + foreach $cmd ($exedir."Xvnc",$exedir."vncpasswd") { + for (split(/:/,$ENV{PATH})) { + if (-x "$cmd") { + next cmd3; + } + } + die "$prog: couldn't find \"$cmd\".\n"; + } + } + + if (!defined($ENV{HOME})) { + die "$prog: The HOME environment variable is not set.\n"; + } + + # + # Find socket constants. 'use Socket' is a perl5-ism, so we wrap it in an + # eval, and if it fails we try 'require "sys/socket.ph"'. If this fails, + # we just guess at the values. If you find perl moaning here, just + # hard-code the values of AF_INET and SOCK_STREAM. You can find these out + # for your platform by looking in /usr/include/sys/socket.h and related + # files. + # + + chop($os = `uname`); + chop($osrev = `uname -r`); + + eval 'use Socket'; + if ($@) { + eval 'require "sys/socket.ph"'; + if ($@) { + if (($os eq "SunOS") && ($osrev !~ /^4/)) { + $AF_INET = 2; + $SOCK_STREAM = 2; + } else { + $AF_INET = 2; + $SOCK_STREAM = 1; + } + } else { + $AF_INET = &AF_INET; + $SOCK_STREAM = &SOCK_STREAM; + } + } else { + $AF_INET = &AF_INET; + $SOCK_STREAM = &SOCK_STREAM; + } +} + +sub NotifyAboutDeprecation +{ + warn "\nWARNING: vncserver has been replaced by a systemd unit and is about to be removed in future releases.\n"; + warn "Please read /usr/share/doc/tigervnc/HOWTO.md for more information.\n"; +} diff --git a/SOURCES/vncserver.man b/SOURCES/vncserver.man new file mode 100644 index 0000000..2641ed1 --- /dev/null +++ b/SOURCES/vncserver.man @@ -0,0 +1,204 @@ +.TH vncserver 1 "" "TigerVNC" "Virtual Network Computing" +.SH NAME +vncserver \- start or stop a VNC server +.SH SYNOPSIS +.B vncserver +.RI [: display# ] +.RB [ \-name +.IR desktop-name ] +.RB [ \-geometry +.IR width x height ] +.RB [ \-depth +.IR depth ] +.RB [ \-pixelformat +.IR format ] +.RB [ \-fp +.IR font-path ] +.RB [ \-fg ] +.RB [ \-autokill ] +.RB [ \-noxstartup ] +.RB [ \-xstartup +.IR script ] +.RI [ Xvnc-options... ] +.br +.BI "vncserver \-kill :" display# +.br +.BI "vncserver \-list" +.SH DESCRIPTION +.B vncserver +is used to start a VNC (Virtual Network Computing) desktop. +.B vncserver +is a Perl script which simplifies the process of starting an Xvnc server. It +runs Xvnc with appropriate options and starts a window manager on the VNC +desktop. + +.B vncserver +can be run with no options at all. In this case it will choose the first +available display number (usually :1), start Xvnc with that display number, +and start the default window manager in the Xvnc session. You can also +specify the display number, in which case vncserver will attempt to start +Xvnc with that display number and exit if the display number is not +available. For example: + +.RS +vncserver :13 +.RE + +Editing the file $HOME/.vnc/xstartup allows you to change the applications run +at startup (but note that this will not affect an existing VNC session.) + +.SH OPTIONS +You can get a list of options by passing \fB\-h\fP as an option to vncserver. +In addition to the options listed below, any unrecognised options will be +passed to Xvnc - see the Xvnc man page, or "Xvnc \-help", for details. + +.TP +.B \-name \fIdesktop-name\fP +Each VNC desktop has a name which may be displayed by the viewer. The desktop +name defaults to "\fIhost\fP:\fIdisplay#\fP (\fIusername\fP)", but you can +change it with this option. The desktop name option is passed to the xstartup +script via the $VNCDESKTOP environment variable, which allows you to run a +different set of applications depending on the name of the desktop. +. +.TP +.B \-geometry \fIwidth\fPx\fIheight\fP +Specify the size of the VNC desktop to be created. Default is 1024x768. +. +.TP +.B \-depth \fIdepth\fP +Specify the pixel depth (in bits) of the VNC desktop to be created. Default is +24. Other possible values are 8, 15 and 16 - anything else is likely to cause +strange behaviour by applications. +. +.TP +.B \-pixelformat \fIformat\fP +Specify pixel format for Xvnc to use (BGRnnn or RGBnnn). The default for +depth 8 is BGR233 (meaning the most significant two bits represent blue, the +next three green, and the least significant three represent red), the default +for depth 16 is RGB565, and the default for depth 24 is RGB888. +. +.TP +.B \-cc 3 +As an alternative to the default TrueColor visual, this allows you to run an +Xvnc server with a PseudoColor visual (i.e. one which uses a color map or +palette), which can be useful for running some old X applications which only +work on such a display. Values other than 3 (PseudoColor) and 4 (TrueColor) +for the \-cc option may result in strange behaviour, and PseudoColor desktops +must have an 8-bit depth. +. +.TP +.B \-kill :\fIdisplay#\fP +This kills a VNC desktop previously started with vncserver. It does this by +killing the Xvnc process, whose process ID is stored in the file +"$HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.pid". The +.B \-kill +option ignores anything preceding the first colon (":") in the display +argument. Thus, you can invoke "vncserver \-kill $DISPLAY", for example at the +end of your xstartup file after a particular application exits. +. +.TP +.B \-fp \fIfont-path\fP +If the vncserver script detects that the X Font Server (XFS) is running, it +will attempt to start Xvnc and configure Xvnc to use XFS for font handling. +Otherwise, if XFS is not running, the vncserver script will attempt to start +Xvnc and allow Xvnc to use its own preferred method of font handling (which may +be a hard-coded font path or, on more recent systems, a font catalog.) In +any case, if Xvnc fails to start, the vncserver script will then attempt to +determine an appropriate X font path for this system and start Xvnc using +that font path. + +The +.B \-fp +argument allows you to override the above fallback logic and specify a font +path for Xvnc to use. +. +.TP +.B \-fg +Runs Xvnc as a foreground process. This has two effects: (1) The VNC server +can be aborted with CTRL-C, and (2) the VNC server will exit as soon as the +user logs out of the window manager in the VNC session. This may be necessary +when launching TigerVNC from within certain grid computing environments. +. +.TP +.B \-autokill +Automatically kill Xvnc whenever the xstartup script exits. In most cases, +this has the effect of terminating Xvnc when the user logs out of the window +manager. +. +.TP +.B \-noxstartup +Do not run the %HOME/.vnc/xstartup script after launching Xvnc. This +option allows you to manually start a window manager in your TigerVNC session. +. +.TP +.B \-xstartup \fIscript\fP +Run a custom startup script, instead of %HOME/.vnc/xstartup, after launching +Xvnc. This is useful to run full-screen applications. +. +.TP +.B \-list +Lists all VNC desktops started by vncserver. + +.SH FILES +Several VNC-related files are found in the directory $HOME/.vnc: +.TP +$HOME/.vnc/xstartup +A shell script specifying X applications to be run when a VNC desktop is +started. If this file does not exist, then vncserver will create a default +xstartup script which attempts to launch your chosen window manager. +.TP +/etc/tigervnc/vncserver-config-defaults +The optional system-wide equivalent of $HOME/.vnc/config. If this file exists +and defines options to be passed to Xvnc, they will be used as defaults for +users. The user's $HOME/.vnc/config overrides settings configured in this file. +The overall configuration file load order is: this file, $HOME/.vnc/config, +and then /etc/tigervnc/vncserver-config-mandatory. None are required to exist. +.TP +/etc/tigervnc/vncserver-config-mandatory +The optional system-wide equivalent of $HOME/.vnc/config. If this file exists +and defines options to be passed to Xvnc, they will override any of the same +options defined in a user's $HOME/.vnc/config. This file offers a mechanism +to establish some basic form of system-wide policy. WARNING! There is +nothing stopping users from constructing their own vncserver-like script +that calls Xvnc directly to bypass any options defined in +/etc/tigervnc/vncserver-config-mandatory. Likewise, any CLI arguments passed +to vncserver will override ANY config file setting of the same name. The +overall configuration file load order is: +/etc/tigervnc/vncserver-config-defaults, $HOME/.vnc/config, and then this file. +None are required to exist. +.TP +$HOME/.vnc/config +An optional server config file wherein options to be passed to Xvnc are listed +to avoid hard-coding them to the physical invocation. List options in this file +one per line. For those requiring an argument, simply separate the option from +the argument with an equal sign, for example: "geometry=2000x1200" or +"securitytypes=vncauth,tlsvnc". Options without an argument are simply listed +as a single word, for example: "localhost" or "alwaysshared". +.TP +$HOME/.vnc/passwd +The VNC password file. +.TP +$HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.log +The log file for Xvnc and applications started in xstartup. +.TP +$HOME/.vnc/\fIhost\fP:\fIdisplay#\fP.pid +Identifies the Xvnc process ID, used by the +.B \-kill +option. + +.SH SEE ALSO +.BR vncviewer (1), +.BR vncpasswd (1), +.BR vncconfig (1), +.BR Xvnc (1) +.br +https://www.tigervnc.org + +.SH AUTHOR +Tristan Richardson, RealVNC Ltd., D. R. Commander and others. + +VNC was originally developed by the RealVNC team while at Olivetti +Research Ltd / AT&T Laboratories Cambridge. TightVNC additions were +implemented by Constantin Kaplinsky. Many other people have since +participated in development, testing and support. This manual is part +of the TigerVNC software suite. diff --git a/SOURCES/xvnc.service b/SOURCES/xvnc.service index 3471e1f..9ee468c 100644 --- a/SOURCES/xvnc.service +++ b/SOURCES/xvnc.service @@ -32,7 +32,7 @@ Description=XVNC Per-Connection Daemon [Service] -ExecStart=-/usr/bin/Xvnc -inetd -query localhost -geometry 1024x768 -depth 24 -once -SecurityTypes=None +ExecStart=-/usr/bin/Xvnc -inetd -query localhost -geometry 1024x768 -depth 24 -once -SecurityTypes=None -Log *:syslog:30 User=nobody StandardInput=socket StandardError=syslog diff --git a/SPECS/tigervnc.spec b/SPECS/tigervnc.spec index 820d7f7..4aedc07 100644 --- a/SPECS/tigervnc.spec +++ b/SPECS/tigervnc.spec @@ -1,6 +1,6 @@ Name: tigervnc -Version: 1.10.1 -Release: 9%{?dist} +Version: 1.11.0 +Release: 6%{?dist} Summary: A TigerVNC remote display system %global _hardened_build 1 @@ -14,6 +14,10 @@ Source2: xvnc.socket Source3: 10-libvnc.conf Source4: HOWTO.md +# Backwards compatibility +Source5: vncserver +Source6: vncserver.man + Patch2: tigervnc-getmaster.patch Patch5: tigervnc-cursor.patch Patch6: tigervnc-1.3.1-CVE-2014-8240.patch @@ -21,13 +25,12 @@ Patch8: tigervnc-let-user-know-about-not-using-view-only-password.patch Patch9: tigervnc-working-tls-on-fips-systems.patch Patch11: tigervnc-utilize-system-crypto-policies.patch Patch12: tigervnc-passwd-crash-with-malloc-checks.patch -Patch13: 0001-xserver-add-no-op-input-thread-init-function.patch -Patch14: tigervnc-provide-correct-dimensions-for-xshm-setup.patch +Patch13: tigervnc-use-gnome-as-default-session.patch # Upstream patches -Patch50: tigervnc-systemd-support.patch -Patch51: tigervnc-remove-trailing-spaces-in-user-name.patch -Patch52: tigervnc-tolerate-specifying-boolparam.patch +Patch50: tigervnc-tolerate-specifying-boolparam.patch +Patch51: tigervnc-systemd-service.patch +Patch52: tigervnc-correctly-start-vncsession-as-daemon.patch # This is tigervnc-%%{version}/unix/xserver116.patch rebased on the latest xorg Patch100: tigervnc-xserver120.patch @@ -170,22 +173,12 @@ popd %patch11 -p1 -b .utilize-system-crypto-policies.patch %patch12 -p1 -b .passwd-crash-with-malloc-checks +%patch13 -p1 -b .use-gnome-as-default-session -%patch13 -p1 -b .xserver-add-no-op-input-thread-init-function. - -%patch14 -p1 -b .provide-correct-dimensions-for-xshm-setup - -# HACK make sure we are able to successfuly apply a patch. This is because we will -# be creating a directory under name which already exists as a file and it also seems -# to be not possible to create a directory with a patch -pushd unix -rm vncserver -mkdir vncserver -popd - -%patch50 -p1 -b .tigervnc-systemd-support -%patch51 -p1 -b .remove-trailing-spaces-in-user-name -%patch52 -p1 -b .tolerate-specifying-boolparam +# Upstream patches +%patch50 -p1 -b .tolerate-specifying-boolparam +%patch51 -p1 -b .systemd-service +%patch52 -p1 -b .correctly-start-vncsession-as-daemon %build %ifarch sparcv9 sparc64 s390 s390x @@ -256,14 +249,10 @@ install -m644 tigervnc_$s.png %{buildroot}%{_datadir}/icons/hicolor/${s}x$s/apps done popd -# Install a replacement for /usr/bin/vncserver which will tell the user to read the -# HOWTO.md file -cat < %{buildroot}/%{_bindir}/vncserver -#!/bin/bash -echo "vncserver has been replaced by a systemd unit." -echo "Please read /usr/share/doc/tigervnc/HOWTO.md for more information." -EOF -chmod +x %{buildroot}/%{_bindir}/vncserver +rm -f %{buildroot}/%{_mandir}/man8/vncserver.8 + +install -m 755 %{SOURCE5} %{buildroot}/%{_bindir}/vncserver +install -m 644 %{SOURCE6} %{buildroot}/%{_mandir}/man8/vncserver.8 %find_lang %{name} %{name}.lang @@ -351,13 +340,37 @@ fi %changelog -* Tue Oct 6 2020 Jan Grulich - 1.10.1-9 -- Bump build for gating issue - Resolves: bz#1883432 +* Tue Dec 15 2020 Jan Grulich - 1.11.0-6 +- Use GNOME as default session + Resolves: bz#1853608 + +* Thu Dec 03 2020 Jan Grulich - 1.11.0-5 +- Make sure we log properly output to journal (actually log to syslog) + Resolves: bz#1841537 + +* Thu Dec 03 2020 Jan Grulich - 1.11.0-4 +- Make sure we log properly output to journal + Resolves: bz#1841537 + +* Wed Nov 18 2020 Jan Grulich - 1.11.0-3 +- vncserver: ignore new "session" parameter from the new systemd support + Resolves: bz#1897504 + +* Wed Nov 18 2020 Jan Grulich - 1.11.0-2 +- Revert removal of vncserver + Resolves: bz#1897504 +- Correctly start vncsession as a daemon + Resolves: bz#1897498 + +* Tue Oct 20 2020 Jan Grulich - 1.11.0-1 +- Update to 1.11.0 + Resolves: bz#1880985 +- Backport fix to allow Tigervnc use boolean values in config files + Resolves: bz#1883415 * Wed Sep 30 2020 Jan Grulich - 1.10.1-8 - Tolerate specifying -BoolParam 0 and similar - Resolves: bz#1883432 + Resolves: bz#1883415 * Wed Jul 08 2020 Jan Grulich - 1.10.1-7 - Enable server module on s390x