diff --git a/.gitignore b/.gitignore index a6c180ee..c3946d68 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,8 @@ sesman/tools/xrdp-sesrun sesman/tools/xrdp-sestest sesman/tools/xrdp-xcon sesman/xrdp-sesman +sesman/sesman.ini *.so stamp-h1 xrdp/xrdp +xrdp/xrdp.ini diff --git a/NEWS.md b/NEWS.md index 898f4ba2..167d8477 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,40 @@ +# Release notes for xrdp v0.9.6 (2018/03/26) + +## Compatibility notice +Exclamation mark (`!`) has been removed from comment out symbol of config files. +Use number sign (`#`) or semicolon (`;`) instead. As a result of this change, now +you can use exclamation mark as config value such as in `tls_ciphers`. + +``` +tls_ciphers=HIGH:!aNULL:!eNULL:!EXPORT:!RC4 +``` + +See also: #1033 + +## macOS supports +Please note that xrdp still doesn't support macOS officially so far. +However, a volunteer is working on macOS compatibility. + +* Generate dylibs for macOS #1015 +* Add PAM support for macOS #1021 + +## Bug fixes +* Make listen check before daemon fork #988 +* Fix xrdp sometimes become zombie processes #1000 +* Include hostname in sesman password file name #1006 #1007 #1076 +* Fix default startwm.sh to use bash explicitly #1009 #1049 +* Fix the issue FreeBSD doesn't acknowledge terminated sessions #1016 #1030 + +## Other changes +* Add Swiss French keyboard #1053 +* Improve perfect forward secrecy, explicitly enable ECDHE/DHE #1024 #1052 #1063 +* Lots of leak fixes, cleanups and refactoring + +## Known issues +* Audio redirection by MP3 codec doesn't sound with some client, use AAC instead #965 + +----------------------- + # Release notes for xrdp v0.9.5 (2017/12/27) ## Security fixes diff --git a/README.md b/README.md index f8fe462f..ff61e069 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/neutrinolabs/xrdp) ![Apache-License](https://img.shields.io/badge/License-Apache%202.0-blue.svg) -*Current Version:* 0.9.5 +*Current Version:* 0.9.6 # xrdp - an open source RDP server @@ -40,9 +40,12 @@ experience. It is recommended that xrdp depends on xorgxrdp, so it should be sufficient to install xrdp. If xorgxrdp is not provided, use Xvnc server. +xrdp listens on 3389/tcp. Make sure your firewall accepts connection to +3389/tcp from where you want to access. + ### Ubuntu / Debian ```bash -apt-get install xrdp +apt install xrdp ``` ### RedHat / CentOS / Fedora @@ -62,13 +65,6 @@ yum install xrdp `yum` is being replaced with `dnf`, so you may need to use `dnf` instead of `yum` in the above commands. -To allow outside access to the service, open port 3389 on the firewall. - -``` -firewall-cmd --permanent --zone=public --add-port=3389/tcp -firewall-cmd --reload -``` - ## Environment **xrdp** primarily targets to GNU/Linux. Tested on x86, x86_64, SPARC and @@ -80,7 +76,7 @@ SIMD instructions. FreeBSD is not a primary target of xrdp. It is working on FreeBSD except for the drive redirection feature. -Other operating systems such as Mac OS are not supported so far, but we +Other operating systems such as macOS are not supported so far, but we welcome your contributions. ## Compiling diff --git a/common/file.c b/common/file.c index 811e71fa..b796f5b0 100644 --- a/common/file.c +++ b/common/file.c @@ -138,7 +138,7 @@ file_read_ini_line(struct stream *s, char *text, int text_bytes) while (c != 10 && c != 13) { /* these mean skip the rest of the line */ - if (c == '#' || c == '!' || c == ';') + if (c == '#' || c == ';') { skip_to_end = 1; } diff --git a/common/log.c b/common/log.c index ea2af316..50a44e9e 100644 --- a/common/log.c +++ b/common/log.c @@ -270,7 +270,6 @@ internalReadConfiguration(const char *inFilename, const char *applicationName) { int fd; enum logReturns ret = LOG_GENERAL_ERROR; - struct list *sec; struct list *param_n; struct list *param_v; @@ -299,9 +298,6 @@ internalReadConfiguration(const char *inFilename, const char *applicationName) return ret; } - sec = list_create(); - sec->auto_free = 1; - file_read_sections(fd, sec); param_n = list_create(); param_n->auto_free = 1; param_v = list_create(); @@ -311,14 +307,7 @@ internalReadConfiguration(const char *inFilename, const char *applicationName) ret = internal_config_read_logging(fd, g_staticLogConfig, param_n, param_v, applicationName); - if (ret != LOG_STARTUP_OK) - { - g_file_close(fd); - return ret; - } - /* cleanup */ - list_delete(sec); list_delete(param_v); list_delete(param_n); g_file_close(fd); @@ -342,7 +331,7 @@ internal_config_read_logging(int file, struct log_config *lc, /* setting defaults */ lc->program_name = applicationName; lc->log_file = 0; - lc->fd = 0; + lc->fd = -1; lc->log_level = LOG_LEVEL_DEBUG; lc->enable_syslog = 0; lc->syslog_level = LOG_LEVEL_DEBUG; @@ -615,7 +604,7 @@ log_message(const enum logLevels lvl, const char *msg, ...) pthread_mutex_lock(&(g_staticLogConfig->log_lock)); #endif - if (g_staticLogConfig->fd > 0) + if (g_staticLogConfig->fd >= 0) { writereply = g_file_write(g_staticLogConfig->fd, buff, g_strlen(buff)); diff --git a/common/ssl_calls.c b/common/ssl_calls.c index 8eec7123..f659a196 100644 --- a/common/ssl_calls.c +++ b/common/ssl_calls.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "os_calls.h" #include "arch.h" @@ -64,6 +65,42 @@ RSA_get0_key(const RSA *key, const BIGNUM **n, const BIGNUM **e, *n = key->n; *d = key->d; } + +static inline int +DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + /* If the fields p and g in d are NULL, the corresponding input + * parameters MUST be non-NULL. q may remain NULL. + */ + if ((dh->p == NULL && p == NULL) + || (dh->g == NULL && g == NULL)) + { + return 0; + } + + if (p != NULL) + { + BN_free(dh->p); + dh->p = p; + } + if (q != NULL) + { + BN_free(dh->q); + dh->q = q; + } + if (g != NULL) + { + BN_free(dh->g); + dh->g = g; + } + + if (q != NULL) + { + dh->length = BN_num_bits(q); + } + + return 1; +} #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ @@ -485,6 +522,72 @@ ssl_gen_key_xrdp1(int key_size_in_bits, const char *exp, int exp_len, return error; } +/*****************************************************************************/ +/** static DH parameter, can be used if no custom parameter is specified +see also + * https://wiki.openssl.org/index.php/Diffie-Hellman_parameters + * https://wiki.openssl.org/index.php/Manual:SSL_CTX_set_tmp_dh_callback(3) +*/ +static DH *ssl_get_dh2236() +{ + static unsigned char dh2236_p[] = { + 0x0E, 0xF8, 0x69, 0x0B, 0x35, 0x2F, 0x62, 0x59, 0xF7, 0xAF, 0x4E, 0x19, + 0xB5, 0x9B, 0xD2, 0xEB, 0x33, 0x78, 0x1D, 0x43, 0x1D, 0xB6, 0xE4, 0xA3, + 0x63, 0x47, 0x6A, 0xD4, 0xA8, 0x28, 0x11, 0x8C, 0x3F, 0xC8, 0xF1, 0x32, + 0x2B, 0x5D, 0x9F, 0xF8, 0xA6, 0xCA, 0x21, 0x71, 0xDE, 0x30, 0xD7, 0xB5, + 0xD6, 0xA4, 0xC2, 0xEE, 0xC0, 0x49, 0x30, 0xE7, 0x8C, 0x9B, 0x1A, 0x5A, + 0x08, 0x2A, 0x11, 0x84, 0xE2, 0xC8, 0x36, 0x6C, 0xDC, 0x06, 0x79, 0x59, + 0x51, 0xA4, 0xA0, 0x8F, 0xE1, 0x20, 0x94, 0x80, 0xAC, 0x6D, 0xFD, 0x3B, + 0xA6, 0xA6, 0x70, 0x51, 0x93, 0x59, 0x28, 0x51, 0x54, 0xA3, 0xC5, 0x15, + 0x44, 0x2C, 0x12, 0xE7, 0x95, 0x62, 0x0E, 0x65, 0x2F, 0x8C, 0x0D, 0xF8, + 0x63, 0x52, 0x00, 0x2A, 0xA5, 0xD7, 0x59, 0xEF, 0x13, 0x18, 0x33, 0x25, + 0xBC, 0xAD, 0xC8, 0x0A, 0x72, 0x8D, 0x26, 0x63, 0xD5, 0xB3, 0xBC, 0x43, + 0x35, 0x0B, 0x5D, 0xC7, 0xCA, 0x45, 0x17, 0x06, 0x24, 0x71, 0xCA, 0x20, + 0x73, 0xE8, 0x18, 0xD3, 0x8E, 0xE9, 0xE9, 0x8F, 0x67, 0xC0, 0x2C, 0x14, + 0x7E, 0x41, 0x18, 0x6C, 0x74, 0x72, 0x56, 0x34, 0xC0, 0xDB, 0xDD, 0x85, + 0x8B, 0xE0, 0x99, 0xE8, 0x5E, 0xC8, 0xF7, 0xD1, 0x0C, 0xF8, 0x83, 0x34, + 0x37, 0x9E, 0x01, 0xDF, 0x1C, 0xD9, 0xE9, 0x95, 0xC1, 0x4C, 0x64, 0x37, + 0x9B, 0xF5, 0x8F, 0x99, 0x97, 0x55, 0x68, 0x2E, 0x23, 0xB0, 0x35, 0xF3, + 0xA5, 0x97, 0x92, 0xA0, 0x6D, 0xB4, 0xF8, 0xD8, 0x47, 0xCE, 0x3F, 0x0B, + 0x36, 0x0E, 0xEB, 0x13, 0x15, 0xFD, 0x4F, 0x98, 0x4F, 0x14, 0x26, 0xE2, + 0xAC, 0xD9, 0x42, 0xC6, 0x43, 0x8A, 0x95, 0x6B, 0x2B, 0x44, 0x38, 0x7F, + 0x60, 0x97, 0x77, 0xD8, 0x7C, 0x6F, 0x5D, 0x62, 0x7C, 0xE1, 0xC8, 0x83, + 0x12, 0x8B, 0x5E, 0x5E, 0xC7, 0x5E, 0xD5, 0x60, 0xF3, 0x2F, 0xFC, 0xFE, + 0x70, 0xAC, 0x58, 0x3A, 0x3C, 0x18, 0x15, 0x54, 0x84, 0xA8, 0xAA, 0x41, + 0x26, 0x7B, 0xE0, 0xA3, + }; + static unsigned char dh2236_g[] = { + 0x02, + }; + + DH *dh = DH_new(); + if (dh == NULL) + { + return NULL; + } + + BIGNUM *p = BN_bin2bn(dh2236_p, sizeof(dh2236_p), NULL); + BIGNUM *g = BN_bin2bn(dh2236_g, sizeof(dh2236_g), NULL); + if (p == NULL || g == NULL) + { + BN_free(p); + BN_free(g); + DH_free(dh); + return NULL; + } + + // p, g are freed later by DH_free() + if (0 == DH_set0_pqg(dh, p, NULL, g)) + { + BN_free(p); + BN_free(g); + DH_free(dh); + return NULL; + } + + return dh; +} + /*****************************************************************************/ struct ssl_tls * ssl_tls_create(struct trans *trans, const char *key, const char *cert) @@ -587,14 +690,42 @@ ssl_tls_accept(struct ssl_tls *self, long ssl_protocols, options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; self->ctx = SSL_CTX_new(SSLv23_server_method()); + if (self->ctx == NULL) + { + log_message(LOG_LEVEL_ERROR, "ssl_tls_accept: SSL_CTX_new failed"); + return 1; + } + /* set context options */ SSL_CTX_set_mode(self->ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE); SSL_CTX_set_options(self->ctx, options); + /* set DH parameters */ + DH *dh = ssl_get_dh2236(); + if (dh == NULL) + { + log_message(LOG_LEVEL_ERROR, "ssl_tls_accept: ssl_get_dh2236 failed"); + return 1; + } + + if (SSL_CTX_set_tmp_dh(self->ctx, dh) != 1) + { + log_message(LOG_LEVEL_ERROR, + "ssl_tls_accept: SSL_CTX_set_tmp_dh failed"); + return 1; + } + DH_free(dh); // ok to free, copied into ctx by SSL_CTX_set_tmp_dh() + +#if defined(SSL_CTX_set_ecdh_auto) + SSL_CTX_set_ecdh_auto(self->ctx, 1); +#endif + if (g_strlen(tls_ciphers) > 1) { + log_message(LOG_LEVEL_TRACE, "ssl_tls_accept: tls_ciphers=%s", + tls_ciphers); if (SSL_CTX_set_cipher_list(self->ctx, tls_ciphers) == 0) { g_writeln("ssl_tls_accept: invalid cipher options"); @@ -604,12 +735,6 @@ ssl_tls_accept(struct ssl_tls *self, long ssl_protocols, SSL_CTX_set_read_ahead(self->ctx, 1); - if (self->ctx == NULL) - { - g_writeln("ssl_tls_accept: SSL_CTX_new failed"); - return 1; - } - if (SSL_CTX_use_RSAPrivateKey_file(self->ctx, self->key, SSL_FILETYPE_PEM) <= 0) { diff --git a/configure.ac b/configure.ac index cfa2c611..4a41128a 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # Process this file with autoconf to produce a configure script AC_PREREQ(2.65) -AC_INIT([xrdp], [0.9.5], [xrdp-devel@googlegroups.com]) +AC_INIT([xrdp], [0.9.6], [xrdp-devel@googlegroups.com]) AC_CONFIG_HEADERS(config_ac.h:config_ac-h.in) AM_INIT_AUTOMAKE([1.7.2 foreign]) AC_CONFIG_MACRO_DIR([m4]) @@ -40,12 +40,16 @@ case $host_os in *openbsd*) openbsd=yes ;; + *darwin*) + macos=yes + ;; esac AM_CONDITIONAL(LINUX, [test "x$linux" = xyes]) AM_CONDITIONAL(FREEBSD, [test "x$freebsd" = xyes]) AM_CONDITIONAL(OPENBSD, [test "x$openbsd" = xyes]) AM_CONDITIONAL(NETBSD, [test "x$netbsd" = xyes]) +AM_CONDITIONAL(MACOS, [test "x$macos" = xyes]) AC_ARG_WITH([socketdir], [AS_HELP_STRING([--with-socketdir=DIR], diff --git a/instfiles/Makefile.am b/instfiles/Makefile.am index 1c1af39f..8d39af0c 100644 --- a/instfiles/Makefile.am +++ b/instfiles/Makefile.am @@ -78,6 +78,10 @@ SUBDIRS += \ pulse endif +if MACOS +SUBDIRS += pam.d +endif + # # install-data-hook for each platform # TODO: subst these directories as well as service files diff --git a/instfiles/pam.d/Makefile.am b/instfiles/pam.d/Makefile.am index 6cc6bddf..72031575 100644 --- a/instfiles/pam.d/Makefile.am +++ b/instfiles/pam.d/Makefile.am @@ -3,6 +3,7 @@ PAM_FILES = \ xrdp-sesman.redhat \ xrdp-sesman.suse \ xrdp-sesman.freebsd \ + xrdp-sesman.macos \ xrdp-sesman.unix EXTRA_DIST = $(PAM_FILES) mkpamrules diff --git a/instfiles/pam.d/mkpamrules b/instfiles/pam.d/mkpamrules index 88444205..2d268281 100755 --- a/instfiles/pam.d/mkpamrules +++ b/instfiles/pam.d/mkpamrules @@ -30,6 +30,11 @@ guess_rules () return fi + if test -s "$pamdir/authorization"; then + rules="macos" + return + fi + rules="unix" return } diff --git a/instfiles/pam.d/xrdp-sesman.macos b/instfiles/pam.d/xrdp-sesman.macos new file mode 100644 index 00000000..9eb7920e --- /dev/null +++ b/instfiles/pam.d/xrdp-sesman.macos @@ -0,0 +1,12 @@ +# xrdp-sesman: auth account password session +# based on Apple's sshd PAM configuration +auth optional pam_krb5.so use_kcminit +auth optional pam_ntlm.so try_first_pass +auth optional pam_mount.so try_first_pass +auth required pam_opendirectory.so try_first_pass +account required pam_nologin.so +account required pam_sacl.so sacl_service=ssh +account required pam_opendirectory.so +password required pam_opendirectory.so +session required pam_launchd.so +session optional pam_mount.so diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c index 41ff1472..99da37f8 100644 --- a/libxrdp/libxrdp.c +++ b/libxrdp/libxrdp.c @@ -847,6 +847,7 @@ libxrdp_set_pointer(struct xrdp_session *session, int cache_idx) LLOGLN(10, ("libxrdp_send_pointer: fastpath")); if (xrdp_rdp_init_fastpath((struct xrdp_rdp *)session->rdp, s) != 0) { + free_stream(s); return 1; } } diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 4de6c9ed..0436edf2 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -265,7 +265,7 @@ xrdp_load_keyboard_layout(struct xrdp_client_info *client_info) fd = g_file_open(keyboard_cfg_file); - if (fd > 0) + if (fd >= 0) { int section_found = -1; char section_rdp_layouts[256] = { 0 }; diff --git a/mc/Makefile.am b/mc/Makefile.am index 09d07068..130bdcfc 100644 --- a/mc/Makefile.am +++ b/mc/Makefile.am @@ -19,4 +19,6 @@ libmc_la_SOURCES = \ libmc_la_LIBADD = \ $(top_builddir)/common/libcommon.la +if !MACOS libmc_la_LDFLAGS = -avoid-version -module +endif diff --git a/sesman/Makefile.am b/sesman/Makefile.am index 193a7cce..50425e63 100644 --- a/sesman/Makefile.am +++ b/sesman/Makefile.am @@ -75,6 +75,17 @@ xrdp_sesman_LDADD = \ sesmansysconfdir=$(sysconfdir)/xrdp +SUBST_VARS = sed \ + -e 's|@sesmansysconfdir[@]|$(sesmansysconfdir)|g' + +subst_verbose = $(subst_verbose_@AM_V@) +subst_verbose_ = $(subst_verbose_@AM_DEFAULT_V@) +subst_verbose_0 = @echo " SUBST $@"; + +SUFFIXES = .in +.in: + $(subst_verbose)$(SUBST_VARS) $< > $@ + dist_sesmansysconf_DATA = \ sesman.ini diff --git a/sesman/config.c b/sesman/config.c index 794ff4c2..0363b330 100644 --- a/sesman/config.c +++ b/sesman/config.c @@ -472,29 +472,29 @@ config_read_session_variables(int file, struct config_sesman *cs, list_clear(param_v); list_clear(param_n); - cs->session_variables1 = list_create(); - cs->session_variables1->auto_free = 1; - cs->session_variables2 = list_create(); - cs->session_variables2->auto_free = 1; + cs->env_names = list_create(); + cs->env_names->auto_free = 1; + cs->env_values = list_create(); + cs->env_values->auto_free = 1; file_read_section(file, SESMAN_CFG_SESSION_VARIABLES, param_n, param_v); for (i = 0; i < param_n->count; i++) { - list_add_item(cs->session_variables1, + list_add_item(cs->env_names, (tintptr) g_strdup((char *) list_get_item(param_n, i))); - list_add_item(cs->session_variables2, + list_add_item(cs->env_values, (tintptr) g_strdup((char *) list_get_item(param_v, i))); } /* printing session variables */ g_writeln("%s parameters:", SESMAN_CFG_SESSION_VARIABLES); - for (i = 0; i < cs->session_variables1->count; i++) + for (i = 0; i < cs->env_names->count; i++) { g_writeln(" Parameter %02d %s=%s", i, - (char *) list_get_item(cs->session_variables1, i), - (char *) list_get_item(cs->session_variables2, i)); + (char *) list_get_item(cs->env_names, i), + (char *) list_get_item(cs->env_values, i)); } return 0; @@ -506,7 +506,7 @@ config_free(struct config_sesman *cs) list_delete(cs->rdp_params); list_delete(cs->vnc_params); list_delete(cs->xorg_params); - list_delete(cs->session_variables1); - list_delete(cs->session_variables2); + list_delete(cs->env_names); + list_delete(cs->env_values); g_free(cs); } diff --git a/sesman/config.h b/sesman/config.h index 87f489db..6bc10852 100644 --- a/sesman/config.h +++ b/sesman/config.h @@ -240,8 +240,16 @@ struct config_sesman */ struct config_sessions sess; - struct list* session_variables1; - struct list* session_variables2; + /** + * @var env_names + * @brief environment variable name list + */ + struct list* env_names; + /** + * @var env_values + * @brief environment variable value list + */ + struct list* env_values; }; /** diff --git a/sesman/env.c b/sesman/env.c index 29bd281d..c897f1b3 100644 --- a/sesman/env.c +++ b/sesman/env.c @@ -102,6 +102,7 @@ env_set_user(const char *username, char **passwd_file, int display, char *pw_shell; char *pw_dir; char text[256]; + char hostname[256]; pw_shell = 0; pw_dir = 0; @@ -152,13 +153,14 @@ env_set_user(const char *username, char **passwd_file, int display, g_setenv(name, value, 1); } } - + g_gethostname(hostname, 255); + hostname[255] = 0; if (passwd_file != 0) { if (0 == g_cfg->auth_file_path) { /* if no auth_file_path is set, then we go for - $HOME/.vnc/sesman_username_passwd:DISPLAY */ + $HOME/.vnc/sesman_passwd-USERNAME@HOSTNAME:DISPLAY */ if (!g_directory_exist(".vnc")) { if (g_mkdir(".vnc") < 0) @@ -169,13 +171,21 @@ env_set_user(const char *username, char **passwd_file, int display, } } - len = g_snprintf(NULL, 0, "%s/.vnc/sesman_%s_passwd:%d", - pw_dir, username, display); + len = g_snprintf(NULL, 0, "%s/.vnc/sesman_passwd-%s@%s:%d", + pw_dir, username, hostname, display); *passwd_file = (char *) g_malloc(len + 1, 1); if (*passwd_file != NULL) { - /* Try legacy name first, remove if found */ + /* Try legacy names first, remove if found */ + g_sprintf(*passwd_file, "%s/.vnc/sesman_%s_passwd:%d", + pw_dir, username, display); + if (g_file_exist(*passwd_file)) + { + log_message(LOG_LEVEL_WARNING, "Removing old " + "password file %s", *passwd_file); + g_file_delete(*passwd_file); + } g_sprintf(*passwd_file, "%s/.vnc/sesman_%s_passwd", pw_dir, username); if (g_file_exist(*passwd_file)) @@ -184,9 +194,8 @@ env_set_user(const char *username, char **passwd_file, int display, "password file %s", *passwd_file); g_file_delete(*passwd_file); } - - g_sprintf(*passwd_file, "%s/.vnc/sesman_%s_passwd:%d", - pw_dir, username, display); + g_sprintf(*passwd_file, "%s/.vnc/sesman_passwd-%s@%s:%d", + pw_dir, username, hostname, display); } } else diff --git a/sesman/libscp/libscp_v1c.c b/sesman/libscp/libscp_v1c.c index 5401dda3..dfc3754d 100644 --- a/sesman/libscp/libscp_v1c.c +++ b/sesman/libscp/libscp_v1c.c @@ -177,6 +177,7 @@ scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount, if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) { + g_free(ds); return SCP_CLIENT_STATE_NETWORK_ERR; } @@ -184,6 +185,7 @@ scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount, if (version != 1) { + g_free(ds); return SCP_CLIENT_STATE_VERSION_ERR; } @@ -191,6 +193,7 @@ scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount, if (size < 12) { + g_free(ds); return SCP_CLIENT_STATE_SIZE_ERR; } @@ -198,6 +201,7 @@ scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount, if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) { + g_free(ds); return SCP_CLIENT_STATE_NETWORK_ERR; } @@ -205,6 +209,7 @@ scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount, if (cmd != SCP_COMMAND_SET_DEFAULT) { + g_free(ds); return SCP_CLIENT_STATE_SEQUENCE_ERR; } @@ -212,6 +217,7 @@ scp_v1c_get_session_list(struct SCP_CONNECTION *c, int *scount, if (cmd != 42) { + g_free(ds); return SCP_CLIENT_STATE_SEQUENCE_ERR; } diff --git a/sesman/libscp/libscp_v1c_mng.c b/sesman/libscp/libscp_v1c_mng.c index 2ceaa95e..f1eb7cf6 100644 --- a/sesman/libscp/libscp_v1c_mng.c +++ b/sesman/libscp/libscp_v1c_mng.c @@ -144,6 +144,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount, if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, 8)) { log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); + g_free(ds); return SCP_CLIENT_STATE_NETWORK_ERR; } @@ -152,6 +153,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount, if (version != 1) { log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: version error", __LINE__); + g_free(ds); return SCP_CLIENT_STATE_VERSION_ERR; } @@ -160,6 +162,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount, if (size < 12) { log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: size error", __LINE__); + g_free(ds); return SCP_CLIENT_STATE_SIZE_ERR; } @@ -168,6 +171,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount, if (0 != scp_tcp_force_recv(c->in_sck, c->in_s->data, size - 8)) { log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: network error", __LINE__); + g_free(ds); return SCP_CLIENT_STATE_NETWORK_ERR; } @@ -176,6 +180,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount, if (cmd != SCP_COMMAND_SET_MANAGE) { log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__); + g_free(ds); return SCP_CLIENT_STATE_SEQUENCE_ERR; } @@ -184,6 +189,7 @@ scp_v1c_mng_get_session_list(struct SCP_CONNECTION *c, int *scount, if (cmd != SCP_CMD_MNG_LIST) /* session list */ { log_message(LOG_LEVEL_WARNING, "[v1c_mng:%d] connection aborted: sequence error", __LINE__); + g_free(ds); return SCP_CLIENT_STATE_SEQUENCE_ERR; } diff --git a/sesman/sesman.c b/sesman/sesman.c index fd98370c..a89d2f55 100644 --- a/sesman/sesman.c +++ b/sesman/sesman.c @@ -343,18 +343,17 @@ main(int argc, char **argv) if (daemon) { /* start of daemonizing code */ - g_pid = g_fork(); - - if (0 != g_pid) + if (sesman_listen_test(g_cfg) != 0) { - if (sesman_listen_test(g_cfg) != 0) - { - log_message(LOG_LEVEL_ERROR, "Failed to start xrdp-sesman daemon, " - "possibly address already in use."); - g_deinit(); - g_exit(1); - } + log_message(LOG_LEVEL_ERROR, "Failed to start xrdp-sesman daemon, " + "possibly address already in use."); + g_deinit(); + g_exit(1); + } + + if (0 != g_fork()) + { g_deinit(); g_exit(0); } diff --git a/sesman/sesman.ini b/sesman/sesman.ini.in similarity index 98% rename from sesman/sesman.ini rename to sesman/sesman.ini.in index 01bc8fa3..fff7b888 100644 --- a/sesman/sesman.ini +++ b/sesman/sesman.ini.in @@ -99,4 +99,4 @@ param=96 FuseMountName=thinclient_drives [SessionVariables] -PULSE_SCRIPT=/etc/xrdp/pulse/default.pa +PULSE_SCRIPT=@sesmansysconfdir@/pulse/default.pa diff --git a/sesman/session.c b/sesman/session.c index ae3194da..0a80bd8a 100644 --- a/sesman/session.c +++ b/sesman/session.c @@ -360,7 +360,7 @@ session_start_chansrv(char *username, int display) chansrv_pid = g_fork(); if (chansrv_pid == 0) { - chansrv_params = list_create(); + chansrv_params = list_create(); chansrv_params->auto_free = 1; /* building parameters */ @@ -371,8 +371,8 @@ session_start_chansrv(char *username, int display) list_add_item(chansrv_params, 0); /* mandatory */ env_set_user(username, 0, display, - g_cfg->session_variables1, - g_cfg->session_variables2); + g_cfg->env_names, + g_cfg->env_values); /* executing chansrv */ g_execvp(exe_path, (char **) (chansrv_params->items)); @@ -484,22 +484,40 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c, * $OpenBSD: session.c,v 1.252 2010/03/07 11:57:13 dtucker Exp $ * with some ideas about BSD process grouping to xrdp */ + pid_t bsdsespid = g_fork(); - /** - * Create a new session and process group since the 4.4BSD - * setlogin() affects the entire process group - */ - if (g_setsid() < 0) + if (bsdsespid == -1) { - log_message(LOG_LEVEL_ERROR, - "setsid failed - pid %d", g_getpid()); + } + else if (bsdsespid == 0) /* BSD session leader */ + { + /** + * Create a new session and process group since the 4.4BSD + * setlogin() affects the entire process group + */ + if (g_setsid() < 0) + { + log_message(LOG_LEVEL_ERROR, + "setsid failed - pid %d", g_getpid()); + } + + if (g_setlogin(s->username) < 0) + { + log_message(LOG_LEVEL_ERROR, + "setlogin failed for user %s - pid %d", s->username, + g_getpid()); + } } - if (g_setlogin(s->username) < 0) + g_waitpid(bsdsespid); + + if (bsdsespid > 0) { - log_message(LOG_LEVEL_ERROR, - "setlogin failed for user %s - pid %d", s->username, - g_getpid()); + g_exit(0); + /* + * intermediate sesman should exit here after WM exits. + * do not execure the following codes. + */ } #endif window_manager_pid = g_fork(); /* parent becomes X, @@ -513,8 +531,8 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c, env_set_user(s->username, 0, display, - g_cfg->session_variables1, - g_cfg->session_variables2); + g_cfg->env_names, + g_cfg->env_values); if (x_server_running(display)) { auth_set_env(data); @@ -604,16 +622,16 @@ session_start_fork(tbus data, tui8 type, struct SCP_CONNECTION *c, env_set_user(s->username, &passwd_file, display, - g_cfg->session_variables1, - g_cfg->session_variables2); + g_cfg->env_names, + g_cfg->env_values); } else { env_set_user(s->username, 0, display, - g_cfg->session_variables1, - g_cfg->session_variables2); + g_cfg->env_names, + g_cfg->env_values); } @@ -857,8 +875,8 @@ session_reconnect_fork(int display, char *username) env_set_user(username, 0, display, - g_cfg->session_variables1, - g_cfg->session_variables2); + g_cfg->env_names, + g_cfg->env_values); g_snprintf(text, 255, "%s/%s", XRDP_CFG_PATH, "reconnectwm.sh"); if (g_file_exist(text)) diff --git a/sesman/startwm.sh b/sesman/startwm.sh index 452917a4..ad060106 100755 --- a/sesman/startwm.sh +++ b/sesman/startwm.sh @@ -1,4 +1,11 @@ -#!/bin/sh +#!/usr/bin/env bash +# +# This script is an example. You might need to edit this script +# depending on your distro if it doesn't work for you. +# +# Uncomment the following line for debug: +# exec xterm + # Execution sequence for interactive login shell - pseudocode # diff --git a/vnc/Makefile.am b/vnc/Makefile.am index c4fcf3fc..92160771 100644 --- a/vnc/Makefile.am +++ b/vnc/Makefile.am @@ -19,4 +19,6 @@ libvnc_la_SOURCES = \ libvnc_la_LIBADD = \ $(top_builddir)/common/libcommon.la +if !MACOS libvnc_la_LDFLAGS = -avoid-version -module +endif diff --git a/xorg/X11R7.6/rdp/rdp.h b/xorg/X11R7.6/rdp/rdp.h index ceed13a9..56ee5ba8 100644 --- a/xorg/X11R7.6/rdp/rdp.h +++ b/xorg/X11R7.6/rdp/rdp.h @@ -76,7 +76,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. //#include "colormapst.h" -#define X11RDPVER "0.9.5" +#define X11RDPVER "0.9.6" #define PixelDPI 100 #define PixelToMM(_size) (((_size) * 254 + (PixelDPI) * 5) / ((PixelDPI) * 10)) diff --git a/xrdp/Makefile.am b/xrdp/Makefile.am index a259ef32..fe14d88d 100644 --- a/xrdp/Makefile.am +++ b/xrdp/Makefile.am @@ -67,6 +67,23 @@ xrdp_LDADD = \ xrdpsysconfdir=$(sysconfdir)/xrdp +if MACOS +lib_extension = dylib +else +lib_extension = so +endif + +SUBST_VARS = sed \ + -e 's|@lib_extension[@]|$(lib_extension)|g' + +subst_verbose = $(subst_verbose_@AM_V@) +subst_verbose_ = $(subst_verbose_@AM_DEFAULT_V@) +subst_verbose_0 = @echo " SUBST $@"; + +SUFFIXES = .in +.in: + $(subst_verbose)$(SUBST_VARS) $< > $@ + dist_xrdpsysconf_DATA = \ xrdp.ini \ xrdp_keyboard.ini diff --git a/xrdp/xrdp.c b/xrdp/xrdp.c index adf182b9..65bd40a0 100644 --- a/xrdp/xrdp.c +++ b/xrdp/xrdp.c @@ -123,7 +123,11 @@ xrdp_shutdown(int sig) void xrdp_child(int sig) { - g_waitchild(); + int safety; + + for (safety = 0; (g_waitchild() >= 0) && (safety <= 10); safety++) + { + } } /*****************************************************************************/ diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini.in similarity index 95% rename from xrdp/xrdp.ini rename to xrdp/xrdp.ini.in index e3ae2841..fb09bbd9 100644 --- a/xrdp/xrdp.ini +++ b/xrdp/xrdp.ini.in @@ -155,7 +155,7 @@ tcutils=true ; in sesman.ini. See and configure also sesman.ini. [Xorg] name=Xorg -lib=libxup.so +lib=libxup.@lib_extension@ username=ask password=ask ip=127.0.0.1 @@ -164,7 +164,7 @@ code=20 [X11rdp] name=X11rdp -lib=libxup.so +lib=libxup.@lib_extension@ username=ask password=ask ip=127.0.0.1 @@ -174,7 +174,7 @@ code=10 [Xvnc] name=Xvnc -lib=libvnc.so +lib=libvnc.@lib_extension@ username=ask password=ask ip=127.0.0.1 @@ -184,7 +184,7 @@ port=-1 [console] name=console -lib=libvnc.so +lib=libvnc.@lib_extension@ ip=127.0.0.1 port=5900 username=na @@ -193,7 +193,7 @@ password=ask [vnc-any] name=vnc-any -lib=libvnc.so +lib=libvnc.@lib_extension@ ip=ask port=ask5900 username=na @@ -205,7 +205,7 @@ password=ask [sesman-any] name=sesman-any -lib=libvnc.so +lib=libvnc.@lib_extension@ ip=ask port=-1 username=ask @@ -214,7 +214,7 @@ password=ask [neutrinordp-any] name=neutrinordp-any -lib=libxrdpneutrinordp.so +lib=libxrdpneutrinordp.@lib_extension@ ip=ask port=ask3389 username=ask diff --git a/xrdp/xrdp_encoder.c b/xrdp/xrdp_encoder.c index 4d80214e..5b5fc8d7 100644 --- a/xrdp/xrdp_encoder.c +++ b/xrdp/xrdp_encoder.c @@ -169,6 +169,16 @@ xrdp_encoder_delete(struct xrdp_encoder *self) /* todo delete specific encoder */ + if (self->process_enc == process_enc_jpg) + { + } +#ifdef XRDP_RFXCODEC + else if (self->process_enc == process_enc_rfx) + { + rfxcodec_encode_destroy(self->codec_handle); + } +#endif + /* destroy wait objects used for signalling */ g_delete_wait_obj(self->xrdp_encoder_event_to_proc); g_delete_wait_obj(self->xrdp_encoder_event_processed); @@ -208,6 +218,7 @@ xrdp_encoder_delete(struct xrdp_encoder *self) } fifo_delete(fifo); } + tc_mutex_delete(self->mutex); g_free(self); } diff --git a/xrdp/xrdp_keyboard.ini b/xrdp/xrdp_keyboard.ini index 07f0a1b0..dcc57b7a 100644 --- a/xrdp/xrdp_keyboard.ini +++ b/xrdp/xrdp_keyboard.ini @@ -74,6 +74,7 @@ rdp_layout_br=0x00000416 rdp_layout_ru=0x00000419 rdp_layout_se=0x0000041D rdp_layout_ch=0x00000807 +rdp_layout_ch_fr=0x0000100c rdp_layout_gb=0x00000809 rdp_layout_be=0x00000813 rdp_layout_pt=0x00000816 @@ -94,6 +95,7 @@ rdp_layout_br=br(abnt2) rdp_layout_ru=ru rdp_layout_se=se rdp_layout_ch=ch +rdp_layout_ch_fr=ch(fr) rdp_layout_gb=gb rdp_layout_be=be rdp_layout_pt=pt @@ -128,6 +130,7 @@ rdp_layout_br=br(abnt2) rdp_layout_ru=ru rdp_layout_se=se rdp_layout_ch=ch +rdp_layout_ch_fr=ch(fr) rdp_layout_gb=gb rdp_layout_be=be rdp_layout_pt=pt diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 4754ccaa..4c716d46 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -1310,7 +1310,7 @@ xrdp_mm_get_sesman_port(char *port, int port_bytes) g_snprintf(cfg_file, 255, "%s/sesman.ini", XRDP_CFG_PATH); fd = g_file_open(cfg_file); - if (fd > 0) + if (fd >= 0) { names = list_create(); names->auto_free = 1; @@ -1343,10 +1343,8 @@ xrdp_mm_get_sesman_port(char *port, int port_bytes) list_delete(names); list_delete(values); - } - - if (fd != -1) g_file_close(fd); + } return 0; } diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index 3d16fe63..8b26718d 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -405,7 +405,7 @@ xrdp_wm_load_static_colors_plus(struct xrdp_wm *self, char *autorun_name) g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); fd = g_file_open(cfg_file); - if (fd > 0) + if (fd >= 0) { names = list_create(); names->auto_free = 1; diff --git a/xup/Makefile.am b/xup/Makefile.am index 0d6434c8..1a4fc35b 100644 --- a/xup/Makefile.am +++ b/xup/Makefile.am @@ -19,4 +19,6 @@ libxup_la_SOURCES = \ libxup_la_LIBADD = \ $(top_builddir)/common/libcommon.la +if !MACOS libxup_la_LDFLAGS = -avoid-version -module +endif