From c0a35265907533be10ca151ac797f34ae0d68969 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 22 Oct 2018 11:22:50 +1100 Subject: fix compile for openssl 1.0.x w/ --with-ssl-engine bz#2921, patch from cotequeiroz --- openbsd-compat/openssl-compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'openbsd-compat') diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c index 8b4a36274..590b66d16 100644 --- a/openbsd-compat/openssl-compat.c +++ b/openbsd-compat/openssl-compat.c @@ -76,7 +76,7 @@ ssh_OpenSSL_add_all_algorithms(void) ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); -#if OPENSSL_VERSION_NUMBER < 0x10001000L +#if OPENSSL_VERSION_NUMBER < 0x10100000L OPENSSL_config(NULL); #else OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS | -- cgit v1.2.3 From 406a24b25d6a2bdd70cacd16de7e899dcb2a8829 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 26 Oct 2018 13:43:28 +1100 Subject: fix builds on OpenSSL <= 1.0.x I thought OpenSSL 1.0.x offered the new-style OpenSSL_version_num() API to obtain version number, but they don't. --- configure.ac | 9 ++++++++- openbsd-compat/openssl-compat.h | 6 ++++++ 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'openbsd-compat') diff --git a/configure.ac b/configure.ac index 0d55bece5..a4109effc 100644 --- a/configure.ac +++ b/configure.ac @@ -2601,7 +2601,11 @@ if test "x$openssl" = "xyes" ; then fd = fopen(DATA,"w"); if(fd == NULL) exit(1); - +#if OPENSSL_VERSION_NUMBER < 0x10100000L +# define OpenSSL_version_num SSLeay +# define OpenSSL_version SSLeay_version +# define OPENSSL_VERSION SSLEAY_VERSION +#endif if ((rc = fprintf(fd, "%08lx (%s)\n", (unsigned long)OpenSSL_version_num(), OpenSSL_version(OPENSSL_VERSION))) < 0) @@ -2646,6 +2650,9 @@ if test "x$openssl" = "xyes" ; then #include #include ]], [[ +#if OPENSSL_VERSION_NUMBER < 0x10100000L +# define OpenSSL_version_num SSLeay +#endif exit(OpenSSL_version_num() == OPENSSL_VERSION_NUMBER ? 0 : 1); ]])], [ diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h index 9e0264c04..0fbf60df4 100644 --- a/openbsd-compat/openssl-compat.h +++ b/openbsd-compat/openssl-compat.h @@ -33,6 +33,12 @@ int ssh_compatible_openssl(long, long); # error OpenSSL 0.9.8f or greater is required #endif +#if OPENSSL_VERSION_NUMBER < 0x10100000L +# define OpenSSL_version_num SSLeay +# define OpenSSL_version SSLeay_version +# define OPENSSL_VERSION SSLEAY_VERSION +#endif + #if OPENSSL_VERSION_NUMBER < 0x10000001L # define LIBCRYPTO_EVP_INL_TYPE unsigned int #else -- cgit v1.2.3 From c801b0e38eae99427f37869370151b78f8e15c5d Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 28 Oct 2018 14:34:12 +1100 Subject: Use detected version functions in openssl compat. Use detected functions in compat layer instead of guessing based on versions. Really fixes builds with LibreSSL, not just configure. --- openbsd-compat/openssl-compat.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'openbsd-compat') diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h index 0fbf60df4..28e4fc360 100644 --- a/openbsd-compat/openssl-compat.h +++ b/openbsd-compat/openssl-compat.h @@ -21,6 +21,7 @@ #ifdef WITH_OPENSSL #include +#include #include #include #include @@ -33,12 +34,18 @@ int ssh_compatible_openssl(long, long); # error OpenSSL 0.9.8f or greater is required #endif -#if OPENSSL_VERSION_NUMBER < 0x10100000L -# define OpenSSL_version_num SSLeay -# define OpenSSL_version SSLeay_version +#ifndef OPENSSL_VERSION # define OPENSSL_VERSION SSLEAY_VERSION #endif +#ifndef HAVE_OPENSSL_VERSION +# define OpenSSL_version(x) SSLeay_version(x) +#endif + +#ifndef HAVE_OPENSSL_VERSION_NUM +# define OpenSSL_version_num SSLeay +#endif + #if OPENSSL_VERSION_NUMBER < 0x10000001L # define LIBCRYPTO_EVP_INL_TYPE unsigned int #else -- cgit v1.2.3 From 595605d4abede475339d6a1f07a8cc674c11d1c3 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 28 Oct 2018 15:18:13 +1100 Subject: Update check for minimum OpenSSL version. --- openbsd-compat/openssl-compat.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'openbsd-compat') diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h index 28e4fc360..94c750b7f 100644 --- a/openbsd-compat/openssl-compat.h +++ b/openbsd-compat/openssl-compat.h @@ -30,8 +30,8 @@ int ssh_compatible_openssl(long, long); -#if (OPENSSL_VERSION_NUMBER <= 0x0090805fL) -# error OpenSSL 0.9.8f or greater is required +#if (OPENSSL_VERSION_NUMBER <= 0x1000100fL) +# error OpenSSL 1.0.1 or greater is required #endif #ifndef OPENSSL_VERSION -- cgit v1.2.3 From 624d19ac2d56fa86a22417c35536caceb3be346f Mon Sep 17 00:00:00 2001 From: Eneas U de Queiroz Date: Tue, 9 Oct 2018 16:17:42 -0300 Subject: fix compilation with openssl built without ECC ECDSA code in openssh-compat.h and libressl-api-compat.c needs to be guarded by OPENSSL_HAS_ECC Signed-off-by: Eneas U de Queiroz --- openbsd-compat/libressl-api-compat.c | 4 ++++ openbsd-compat/openssl-compat.h | 4 ++++ 2 files changed, 8 insertions(+) (limited to 'openbsd-compat') diff --git a/openbsd-compat/libressl-api-compat.c b/openbsd-compat/libressl-api-compat.c index de3e64a63..ae00ff593 100644 --- a/openbsd-compat/libressl-api-compat.c +++ b/openbsd-compat/libressl-api-compat.c @@ -152,7 +152,9 @@ #include #include #include +#ifdef OPENSSL_HAS_ECC #include +#endif #include #ifndef HAVE_DSA_GET0_PQG @@ -417,6 +419,7 @@ DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) } #endif /* HAVE_DSA_SIG_SET0 */ +#ifdef OPENSSL_HAS_ECC #ifndef HAVE_ECDSA_SIG_GET0 void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) @@ -442,6 +445,7 @@ ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) return 1; } #endif /* HAVE_ECDSA_SIG_SET0 */ +#endif /* OPENSSL_HAS_ECC */ #ifndef HAVE_DH_GET0_PQG void diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h index 94c750b7f..1ae0fce29 100644 --- a/openbsd-compat/openssl-compat.h +++ b/openbsd-compat/openssl-compat.h @@ -25,7 +25,9 @@ #include #include #include +#ifdef OPENSSL_HAS_ECC #include +#endif #include int ssh_compatible_openssl(long, long); @@ -174,6 +176,7 @@ void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s); #endif /* DSA_SIG_SET0 */ +#ifdef OPENSSL_HAS_ECC #ifndef HAVE_ECDSA_SIG_GET0 void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); #endif /* HAVE_ECDSA_SIG_GET0 */ @@ -181,6 +184,7 @@ void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); #ifndef HAVE_ECDSA_SIG_SET0 int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s); #endif /* HAVE_ECDSA_SIG_SET0 */ +#endif /* OPENSSL_HAS_ECC */ #ifndef HAVE_DH_GET0_PQG void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, -- cgit v1.2.3 From ce93472134fb22eff73edbcd173a21ae38889331 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 16 Nov 2018 12:44:01 +1100 Subject: Fix check for OpenSSL 1.0.1 exactly. Both INSTALL and configure.ac claim OpenSSL >= 1.0.1 is supported; fix compile-time check for 1.0.1 to match. --- openbsd-compat/openssl-compat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'openbsd-compat') diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h index 1ae0fce29..b87ce59e7 100644 --- a/openbsd-compat/openssl-compat.h +++ b/openbsd-compat/openssl-compat.h @@ -32,7 +32,7 @@ int ssh_compatible_openssl(long, long); -#if (OPENSSL_VERSION_NUMBER <= 0x1000100fL) +#if (OPENSSL_VERSION_NUMBER < 0x1000100fL) # error OpenSSL 1.0.1 or greater is required #endif -- cgit v1.2.3 From d0d1dfa55be1c5c0d77ab3096b198a64235f936d Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 16 Nov 2018 14:11:44 +1100 Subject: Test for OPENSSL_init_crypto before using. Check for the presence of OPENSSL_init_crypto and all the flags we want before trying to use it (bz#2931). --- configure.ac | 1 + openbsd-compat/openssl-compat.c | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'openbsd-compat') diff --git a/configure.ac b/configure.ac index 53a16c39a..3f7fe2cd0 100644 --- a/configure.ac +++ b/configure.ac @@ -2710,6 +2710,7 @@ if test "x$openssl" = "xyes" ; then ]) # LibreSSL/OpenSSL 1.1x API AC_CHECK_FUNCS([ \ + OPENSSL_init_crypto \ DH_get0_key \ DH_get0_pqg \ DH_set0_key \ diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c index 590b66d16..5ade8f0ba 100644 --- a/openbsd-compat/openssl-compat.c +++ b/openbsd-compat/openssl-compat.c @@ -76,11 +76,14 @@ ssh_OpenSSL_add_all_algorithms(void) ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); -#if OPENSSL_VERSION_NUMBER < 0x10100000L - OPENSSL_config(NULL); -#else +#if defined(HAVE_OPENSSL_INIT_CRYPTO) && \ + defined(OPENSSL_INIT_ADD_ALL_CIPHERS) && \ + defined(OPENSSL_INIT_ADD_ALL_DIGESTS) && \ + defined(OPENSSL_INIT_LOAD_CONFIG) OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS | OPENSSL_INIT_LOAD_CONFIG, NULL); +#else + OPENSSL_config(NULL); #endif } #endif -- cgit v1.2.3 From 42c5ec4b97b6a1bae70f323952d0646af16ce710 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 23 Nov 2018 10:40:06 +1100 Subject: refactor libcrypto initialisation Don't call OpenSSL_add_all_algorithms() unless OpenSSL actually supports it. Move all libcrypto initialisation to a single function, and call that from seed_rng() that is called early in each tool's main(). Prompted by patch from Rosen Penev --- configure.ac | 15 +++++++------ entropy.c | 35 ++++++++++++++++++----------- openbsd-compat/openssl-compat.c | 23 +++++++++++-------- openbsd-compat/openssl-compat.h | 22 +----------------- regress/unittests/sshkey/tests.c | 5 ----- regress/unittests/test_helper/test_helper.c | 5 +++++ scp.c | 2 ++ sftp-server-main.c | 2 ++ sftp.c | 2 ++ ssh-add.c | 4 ---- ssh-agent.c | 4 ---- ssh-keygen.c | 7 ++---- ssh-keysign.c | 9 -------- ssh.c | 9 ++------ ssh_api.c | 4 +--- sshd.c | 8 ++----- 16 files changed, 63 insertions(+), 93 deletions(-) (limited to 'openbsd-compat') diff --git a/configure.ac b/configure.ac index 3f7fe2cd0..5a9b3ff11 100644 --- a/configure.ac +++ b/configure.ac @@ -2671,8 +2671,8 @@ if test "x$openssl" = "xyes" ; then AC_MSG_CHECKING([if programs using OpenSSL functions will link]) AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[ #include ]], - [[ OpenSSL_add_all_algorithms(); ]])], + [AC_LANG_PROGRAM([[ #include ]], + [[ ERR_load_crypto_strings(); ]])], [ AC_MSG_RESULT([yes]) ], @@ -2682,8 +2682,8 @@ if test "x$openssl" = "xyes" ; then LIBS="$LIBS -ldl" AC_MSG_CHECKING([if programs using OpenSSL need -ldl]) AC_LINK_IFELSE( - [AC_LANG_PROGRAM([[ #include ]], - [[ OpenSSL_add_all_algorithms(); ]])], + [AC_LANG_PROGRAM([[ #include ]], + [[ ERR_load_crypto_strings(); ]])], [ AC_MSG_RESULT([yes]) ], @@ -2698,15 +2698,16 @@ if test "x$openssl" = "xyes" ; then AC_CHECK_FUNCS([ \ BN_is_prime_ex \ DSA_generate_parameters_ex \ - EVP_DigestInit_ex \ + EVP_CIPHER_CTX_ctrl \ EVP_DigestFinal_ex \ - EVP_MD_CTX_init \ + EVP_DigestInit_ex \ EVP_MD_CTX_cleanup \ EVP_MD_CTX_copy_ex \ + EVP_MD_CTX_init \ HMAC_CTX_init \ + OpenSSL_add_all_algorithms \ RSA_generate_key_ex \ RSA_get_default_method \ - EVP_CIPHER_CTX_ctrl \ ]) # LibreSSL/OpenSSL 1.1x API AC_CHECK_FUNCS([ \ diff --git a/entropy.c b/entropy.c index fc710ec23..97e836087 100644 --- a/entropy.c +++ b/entropy.c @@ -56,6 +56,8 @@ #include "sshbuf.h" #include "ssherr.h" +#define RANDOM_SEED_SIZE 48 + /* * Portable OpenSSH PRNG seeding: * If OpenSSL has not "internally seeded" itself (e.g. pulled data from @@ -64,8 +66,6 @@ */ #ifndef OPENSSL_PRNG_ONLY -#define RANDOM_SEED_SIZE 48 - /* * Collect 'len' bytes of entropy into 'buf' from PRNGD/EGD daemon * listening either on 'tcp_port', or via Unix domain socket at * @@ -216,9 +216,11 @@ rexec_recv_rng_seed(struct sshbuf *m) void seed_rng(void) { -#ifndef OPENSSL_PRNG_ONLY unsigned char buf[RANDOM_SEED_SIZE]; -#endif + + /* Initialise libcrypto */ + ssh_libcrypto_init(); + if (!ssh_compatible_openssl(OPENSSL_VERSION_NUMBER, OpenSSL_version_num())) fatal("OpenSSL version mismatch. Built against %lx, you " @@ -226,27 +228,34 @@ seed_rng(void) OpenSSL_version_num()); #ifndef OPENSSL_PRNG_ONLY - if (RAND_status() == 1) { + if (RAND_status() == 1) debug3("RNG is ready, skipping seeding"); - return; + else { + if (seed_from_prngd(buf, sizeof(buf)) == -1) + fatal("Could not obtain seed from PRNGd"); + RAND_add(buf, sizeof(buf), sizeof(buf)); } - - if (seed_from_prngd(buf, sizeof(buf)) == -1) - fatal("Could not obtain seed from PRNGd"); - RAND_add(buf, sizeof(buf), sizeof(buf)); - memset(buf, '\0', sizeof(buf)); - #endif /* OPENSSL_PRNG_ONLY */ + if (RAND_status() != 1) fatal("PRNG is not seeded"); + + /* Ensure arc4random() is primed */ + arc4random_buf(buf, sizeof(buf)); + explicit_bzero(buf, sizeof(buf)); } #else /* WITH_OPENSSL */ -/* Handled in arc4random() */ +/* Acutal initialisation is handled in arc4random() */ void seed_rng(void) { + unsigned char buf[RANDOM_SEED_SIZE]; + + /* Ensure arc4random() is primed */ + arc4random_buf(buf, sizeof(buf)); + explicit_bzero(buf, sizeof(buf)); } #endif /* WITH_OPENSSL */ diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c index 5ade8f0ba..d8c00ebcb 100644 --- a/openbsd-compat/openssl-compat.c +++ b/openbsd-compat/openssl-compat.c @@ -66,26 +66,31 @@ ssh_compatible_openssl(long headerver, long libver) return 0; } -#ifdef USE_OPENSSL_ENGINE void -ssh_OpenSSL_add_all_algorithms(void) +ssh_libcrypto_init(void) { +#if defined(HAVE_OPENSSL_ADD_ALL_ALGORITHMS) OpenSSL_add_all_algorithms(); +#elif defined(HAVE_OPENSSL_INIT_CRYPTO) && \ + defined(OPENSSL_INIT_ADD_ALL_CIPHERS) && \ + defined(OPENSSL_INIT_ADD_ALL_DIGESTS) + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS | + OPENSSL_INIT_ADD_ALL_DIGESTS, NULL); +#endif +#ifdef USE_OPENSSL_ENGINE /* Enable use of crypto hardware */ ENGINE_load_builtin_engines(); ENGINE_register_all_complete(); -#if defined(HAVE_OPENSSL_INIT_CRYPTO) && \ - defined(OPENSSL_INIT_ADD_ALL_CIPHERS) && \ - defined(OPENSSL_INIT_ADD_ALL_DIGESTS) && \ - defined(OPENSSL_INIT_LOAD_CONFIG) + /* Load the libcrypto config file to pick up engines defined there */ +# if defined(HAVE_OPENSSL_INIT_CRYPTO) && defined(OPENSSL_INIT_LOAD_CONFIG) OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS | OPENSSL_INIT_LOAD_CONFIG, NULL); -#else +# else OPENSSL_config(NULL); -#endif +# endif +#endif /* USE_OPENSSL_ENGINE */ } -#endif #endif /* WITH_OPENSSL */ diff --git a/openbsd-compat/openssl-compat.h b/openbsd-compat/openssl-compat.h index b87ce59e7..917bc6f7c 100644 --- a/openbsd-compat/openssl-compat.h +++ b/openbsd-compat/openssl-compat.h @@ -31,6 +31,7 @@ #include int ssh_compatible_openssl(long, long); +void ssh_libcrypto_init(void); #if (OPENSSL_VERSION_NUMBER < 0x1000100fL) # error OpenSSL 1.0.1 or greater is required @@ -92,27 +93,6 @@ void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, size_t); # endif #endif -/* - * We overload some of the OpenSSL crypto functions with ssh_* equivalents - * to automatically handle OpenSSL engine initialisation. - * - * In order for the compat library to call the real functions, it must - * define SSH_DONT_OVERLOAD_OPENSSL_FUNCS before including this file and - * implement the ssh_* equivalents. - */ -#ifndef SSH_DONT_OVERLOAD_OPENSSL_FUNCS - -# ifdef USE_OPENSSL_ENGINE -# ifdef OpenSSL_add_all_algorithms -# undef OpenSSL_add_all_algorithms -# endif -# define OpenSSL_add_all_algorithms() ssh_OpenSSL_add_all_algorithms() -# endif - -void ssh_OpenSSL_add_all_algorithms(void); - -#endif /* SSH_DONT_OVERLOAD_OPENSSL_FUNCS */ - /* LibreSSL/OpenSSL 1.1x API compat */ #ifndef HAVE_DSA_GET0_PQG void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, diff --git a/regress/unittests/sshkey/tests.c b/regress/unittests/sshkey/tests.c index 13f265cdb..78aa9223d 100644 --- a/regress/unittests/sshkey/tests.c +++ b/regress/unittests/sshkey/tests.c @@ -7,8 +7,6 @@ #include "includes.h" -#include - #include "../test_helper/test_helper.h" void sshkey_tests(void); @@ -18,9 +16,6 @@ void sshkey_fuzz_tests(void); void tests(void) { - OpenSSL_add_all_algorithms(); - ERR_load_CRYPTO_strings(); - sshkey_tests(); sshkey_file_tests(); sshkey_fuzz_tests(); diff --git a/regress/unittests/test_helper/test_helper.c b/regress/unittests/test_helper/test_helper.c index cd08b5778..6b4f343a8 100644 --- a/regress/unittests/test_helper/test_helper.c +++ b/regress/unittests/test_helper/test_helper.c @@ -35,11 +35,13 @@ #include #include +#include #if defined(HAVE_STRNVIS) && defined(HAVE_VIS_H) && !defined(BROKEN_STRNVIS) # include #endif +#include "entropy.h" #include "test_helper.h" #include "atomicio.h" @@ -123,6 +125,9 @@ main(int argc, char **argv) { int ch; + seed_rng(); + ERR_load_CRYPTO_strings(); + /* Handle systems without __progname */ if (__progname == NULL) { __progname = strrchr(argv[0], '/'); diff --git a/scp.c b/scp.c index 4f3fdcd3d..eb17c3416 100644 --- a/scp.c +++ b/scp.c @@ -400,6 +400,8 @@ main(int argc, char **argv) /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); + seed_rng(); + msetlocale(); /* Copy argv, because we modify it */ diff --git a/sftp-server-main.c b/sftp-server-main.c index c6ccd623e..6230d897d 100644 --- a/sftp-server-main.c +++ b/sftp-server-main.c @@ -43,6 +43,8 @@ main(int argc, char **argv) /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); + seed_rng(); + if ((user_pw = getpwuid(getuid())) == NULL) { fprintf(stderr, "No user found for uid %lu\n", (u_long)getuid()); diff --git a/sftp.c b/sftp.c index ed95cf817..f886b330b 100644 --- a/sftp.c +++ b/sftp.c @@ -2367,6 +2367,8 @@ main(int argc, char **argv) sanitise_stdfd(); msetlocale(); + seed_rng(); + __progname = ssh_get_progname(argv[0]); memset(&args, '\0', sizeof(args)); args.list = NULL; diff --git a/ssh-add.c b/ssh-add.c index 627c02983..50165e7d6 100644 --- a/ssh-add.c +++ b/ssh-add.c @@ -544,10 +544,6 @@ main(int argc, char **argv) __progname = ssh_get_progname(argv[0]); seed_rng(); -#ifdef WITH_OPENSSL - OpenSSL_add_all_algorithms(); -#endif - setvbuf(stdout, NULL, _IOLBF, 0); /* First, get a connection to the authentication agent. */ diff --git a/ssh-agent.c b/ssh-agent.c index cb552462a..6baebc313 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1095,10 +1095,6 @@ main(int ac, char **av) if (getrlimit(RLIMIT_NOFILE, &rlim) == -1) fatal("%s: getrlimit: %s", __progname, strerror(errno)); -#ifdef WITH_OPENSSL - OpenSSL_add_all_algorithms(); -#endif - __progname = ssh_get_progname(av[0]); seed_rng(); diff --git a/ssh-keygen.c b/ssh-keygen.c index 416d25be0..a67737350 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -2459,13 +2459,10 @@ main(int argc, char **argv) __progname = ssh_get_progname(argv[0]); -#ifdef WITH_OPENSSL - OpenSSL_add_all_algorithms(); -#endif - log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); - seed_rng(); + log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1); + msetlocale(); /* we need this for the home * directory. */ diff --git a/ssh-keysign.c b/ssh-keysign.c index bcd1508c0..8f487b8c5 100644 --- a/ssh-keysign.c +++ b/ssh-keysign.c @@ -174,9 +174,6 @@ main(int argc, char **argv) u_char *signature, *data, rver; char *host, *fp; size_t slen, dlen; -#ifdef WITH_OPENSSL - u_int32_t rnd[256]; -#endif ssh_malloc_init(); /* must be called before any mallocs */ if (pledge("stdio rpath getpw dns id", NULL) != 0) @@ -224,12 +221,6 @@ main(int argc, char **argv) if (found == 0) fatal("could not open any host key"); -#ifdef WITH_OPENSSL - OpenSSL_add_all_algorithms(); - arc4random_buf(rnd, sizeof(rnd)); - RAND_seed(rnd, sizeof(rnd)); -#endif - found = 0; for (i = 0; i < NUM_KEYTYPES; i++) { keys[i] = NULL; diff --git a/ssh.c b/ssh.c index 1e471f5c4..1ac903d16 100644 --- a/ssh.c +++ b/ssh.c @@ -610,6 +610,8 @@ main(int ac, char **av) av = saved_av; #endif + seed_rng(); + /* * Discard other fds that are hanging around. These can cause problem * with backgrounded ssh processes started by ControlPersist. @@ -1036,11 +1038,6 @@ main(int ac, char **av) host_arg = xstrdup(host); -#ifdef WITH_OPENSSL - OpenSSL_add_all_algorithms(); - ERR_load_crypto_strings(); -#endif - /* Initialize the command to execute on remote host. */ if ((command = sshbuf_new()) == NULL) fatal("sshbuf_new failed"); @@ -1264,8 +1261,6 @@ main(int ac, char **av) tty_flag = 0; } - seed_rng(); - if (options.user == NULL) options.user = xstrdup(pw->pw_name); diff --git a/ssh_api.c b/ssh_api.c index e727c0d69..53bbc9b49 100644 --- a/ssh_api.c +++ b/ssh_api.c @@ -81,9 +81,7 @@ ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params) int r; if (!called) { -#ifdef WITH_OPENSSL - OpenSSL_add_all_algorithms(); -#endif /* WITH_OPENSSL */ + seed_rng(); called = 1; } diff --git a/sshd.c b/sshd.c index afd959329..fb9d9b60f 100644 --- a/sshd.c +++ b/sshd.c @@ -1510,6 +1510,8 @@ main(int ac, char **av) /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ sanitise_stdfd(); + seed_rng(); + /* Initialize configuration options to their default values. */ initialize_server_options(&options); @@ -1631,10 +1633,6 @@ main(int ac, char **av) else closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); -#ifdef WITH_OPENSSL - OpenSSL_add_all_algorithms(); -#endif - /* If requested, redirect the logs to the specified logfile. */ if (logfile != NULL) log_redirect_stderr_to(logfile); @@ -1677,8 +1675,6 @@ main(int ac, char **av) parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, cfg, NULL); - seed_rng(); - /* Fill in default values for those options not explicitly set. */ fill_default_server_options(&options); -- cgit v1.2.3 From 16fb23f25454991272bfe4598cc05d20fcd25116 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 25 Nov 2018 14:05:57 +1100 Subject: Reverse order of OpenSSL init functions. Try the new init function (OPENSSL_init_crypto) before falling back to the old one (OpenSSL_add_all_algorithms). --- openbsd-compat/openssl-compat.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'openbsd-compat') diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c index d8c00ebcb..a37ca61bf 100644 --- a/openbsd-compat/openssl-compat.c +++ b/openbsd-compat/openssl-compat.c @@ -69,13 +69,13 @@ ssh_compatible_openssl(long headerver, long libver) void ssh_libcrypto_init(void) { -#if defined(HAVE_OPENSSL_ADD_ALL_ALGORITHMS) - OpenSSL_add_all_algorithms(); -#elif defined(HAVE_OPENSSL_INIT_CRYPTO) && \ +#if defined(HAVE_OPENSSL_INIT_CRYPTO) && \ defined(OPENSSL_INIT_ADD_ALL_CIPHERS) && \ defined(OPENSSL_INIT_ADD_ALL_DIGESTS) OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL); +#elif defined(HAVE_OPENSSL_ADD_ALL_ALGORITHMS) + OpenSSL_add_all_algorithms(); #endif #ifdef USE_OPENSSL_ENGINE -- cgit v1.2.3 From 8a85f5458d1c802471ca899c97f89946f6666e61 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Sun, 25 Nov 2018 21:44:05 +1100 Subject: Include stdio.h for FILE if needed. --- openbsd-compat/openbsd-compat.h | 1 + 1 file changed, 1 insertion(+) (limited to 'openbsd-compat') diff --git a/openbsd-compat/openbsd-compat.h b/openbsd-compat/openbsd-compat.h index f5c833bf2..865aaee53 100644 --- a/openbsd-compat/openbsd-compat.h +++ b/openbsd-compat/openbsd-compat.h @@ -61,6 +61,7 @@ void closefrom(int); #endif #ifndef HAVE_GETLINE +#include ssize_t getline(char **, size_t *, FILE *); #endif -- cgit v1.2.3 From 091093d25802b87d3b2b09f2c88d9f33e1ae5562 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 18 Jan 2019 12:11:42 +1300 Subject: Add a minimal implementation of utimensat(). Some systems (eg older OS X) do not have utimensat, so provide minimal implementation in compat layer. Fixes build on at least El Capitan. --- configure.ac | 1 + openbsd-compat/bsd-misc.c | 37 +++++++++++++ openbsd-compat/bsd-misc.h | 8 +++ openbsd-compat/regress/Makefile.in | 2 +- openbsd-compat/regress/utimensattest.c | 97 ++++++++++++++++++++++++++++++++++ 5 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 openbsd-compat/regress/utimensattest.c (limited to 'openbsd-compat') diff --git a/configure.ac b/configure.ac index c1427247e..2d1dafdee 100644 --- a/configure.ac +++ b/configure.ac @@ -1812,6 +1812,7 @@ AC_CHECK_FUNCS([ \ truncate \ unsetenv \ updwtmpx \ + utimensat \ user_from_uid \ usleep \ vasprintf \ diff --git a/openbsd-compat/bsd-misc.c b/openbsd-compat/bsd-misc.c index 5d7540a70..4bae96548 100644 --- a/openbsd-compat/bsd-misc.c +++ b/openbsd-compat/bsd-misc.c @@ -25,6 +25,7 @@ # include #endif +#include #include #include #include @@ -117,6 +118,42 @@ int utimes(char *filename, struct timeval *tvp) } #endif +#ifndef HAVE_UTIMENSAT +/* + * A limited implementation of utimensat() that only implements the + * functionality used by OpenSSH, currently only AT_FDCWD and + * AT_SYMLINK_NOFOLLOW. + */ +int +utimensat(int fd, const char *path, const struct timespec times[2], + int flag) +{ + struct timeval tv[2]; + int ret, oflags = O_WRONLY; + + tv[0].tv_sec = times[0].tv_sec; + tv[0].tv_usec = times[0].tv_nsec / 1000; + tv[1].tv_sec = times[1].tv_sec; + tv[1].tv_usec = times[1].tv_nsec / 1000; + + if (fd != AT_FDCWD) { + errno = ENOSYS; + return -1; + } +# ifndef HAVE_FUTIMES + return utimes(path, tv); +# else + if (flag & AT_SYMLINK_NOFOLLOW) + oflags |= O_NOFOLLOW; + if ((fd = open(path, oflags)) == -1) + return -1; + ret = futimes(fd, tv); + close(fd); + return ret; +# endif +} +#endif + #ifndef HAVE_TRUNCATE int truncate(const char *path, off_t length) { diff --git a/openbsd-compat/bsd-misc.h b/openbsd-compat/bsd-misc.h index 52ec52853..584c2b5ef 100644 --- a/openbsd-compat/bsd-misc.h +++ b/openbsd-compat/bsd-misc.h @@ -64,6 +64,14 @@ struct timeval { int utimes(char *, struct timeval *); #endif /* HAVE_UTIMES */ +#ifndef HAVE_UTIMENSAT +/* start with the high bits and work down to minimise risk of overlap */ +# ifndef AT_SYMLINK_NOFOLLOW +# define AT_SYMLINK_NOFOLLOW 0x80000000 +# endif +int utimensat(int, const char *, const struct timespec[2], int); +#endif + #ifndef HAVE_TRUNCATE int truncate (const char *, off_t); #endif /* HAVE_TRUNCATE */ diff --git a/openbsd-compat/regress/Makefile.in b/openbsd-compat/regress/Makefile.in index 529331be5..c5aae61e2 100644 --- a/openbsd-compat/regress/Makefile.in +++ b/openbsd-compat/regress/Makefile.in @@ -14,7 +14,7 @@ LIBS=@LIBS@ LDFLAGS=@LDFLAGS@ $(LIBCOMPAT) TESTPROGS=closefromtest$(EXEEXT) snprintftest$(EXEEXT) strduptest$(EXEEXT) \ - strtonumtest$(EXEEXT) opensslvertest$(EXEEXT) + strtonumtest$(EXEEXT) opensslvertest$(EXEEXT) utimensattest$(EXEEXT) all: t-exec ${OTHERTESTS} diff --git a/openbsd-compat/regress/utimensattest.c b/openbsd-compat/regress/utimensattest.c new file mode 100644 index 000000000..a7bc7634b --- /dev/null +++ b/openbsd-compat/regress/utimensattest.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2019 Darren Tucker + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#define TMPFILE "utimensat.tmp" +#define TMPFILE2 "utimensat.tmp2" + +#ifndef AT_SYMLINK_NOFOLLOW +# define AT_SYMLINK_NOFOLLOW 0x80000000 +#endif + +int utimensat(int, const char *, const struct timespec[2], int); + +void +fail(char *msg, long expect, long got) +{ + int saved_errno = errno; + + if (expect == got && got == 0) + fprintf(stderr, "utimensat: %s: %s\n", msg, + strerror(saved_errno)); + else + fprintf(stderr, "utimensat: %s: expected %ld got %ld\n", + msg, expect, got); + exit(1); +} + +int +main(void) +{ + int fd; + struct stat sb; + struct timespec ts[2]; + + if ((fd = open(TMPFILE, O_CREAT, 0600)) == -1) + fail("open", 0, 0); + close(fd); + + ts[0].tv_sec = 12345678; + ts[0].tv_nsec = 23456789; + ts[1].tv_sec = 34567890; + ts[1].tv_nsec = 45678901; + if (utimensat(AT_FDCWD, TMPFILE, ts, AT_SYMLINK_NOFOLLOW) == -1) + fail("utimensat", 0, 0); + + if (stat(TMPFILE, &sb) == -1) + fail("stat", 0, 0 ); + if (sb.st_atime != 12345678) + fail("st_atime", 0, 0 ); + if (sb.st_mtime != 34567890) + fail("st_mtime", 0, 0 ); +#if 0 + /* + * Results expected to be rounded to the nearest microsecond. + * Depends on timestamp precision in kernel and filesystem so + * disabled by default. + */ + if (sb.st_atim.tv_nsec != 23456000) + fail("atim.tv_nsec", 23456000, sb.st_atim.tv_nsec); + if (sb.st_mtim.tv_nsec != 45678000) + fail("mtim.tv_nsec", 45678000, sb.st_mtim.tv_nsec); +#endif + + if (rename(TMPFILE, TMPFILE2) == -1) + fail("rename", 0, 0); + if (symlink(TMPFILE2, TMPFILE) == -1) + fail("symlink", 0, 0); + + if (utimensat(AT_FDCWD, TMPFILE, ts, AT_SYMLINK_NOFOLLOW) != -1) + fail("utimensat followed symlink", 0, 0); + + if (!(unlink(TMPFILE) == 0 && unlink(TMPFILE2) == 0)) + fail("unlink", 0, 0); + exit(0); +} -- cgit v1.2.3 From a6258e5dc314c7d504ac9f0fbc3be96475581dbe Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 18 Jan 2019 11:09:01 +1100 Subject: Add minimal fchownat and fchmodat implementations. Fixes builds on at least OS X Lion, NetBSD 6 and Solaris 10. --- configure.ac | 2 ++ openbsd-compat/bsd-misc.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++ openbsd-compat/bsd-misc.h | 12 ++++++++++ 3 files changed, 72 insertions(+) (limited to 'openbsd-compat') diff --git a/configure.ac b/configure.ac index 2d1dafdee..8e92d1599 100644 --- a/configure.ac +++ b/configure.ac @@ -1719,7 +1719,9 @@ AC_CHECK_FUNCS([ \ errx \ explicit_bzero \ fchmod \ + fchmodat \ fchown \ + fchownat \ flock \ freeaddrinfo \ freezero \ diff --git a/openbsd-compat/bsd-misc.c b/openbsd-compat/bsd-misc.c index 4bae96548..d3a41df50 100644 --- a/openbsd-compat/bsd-misc.c +++ b/openbsd-compat/bsd-misc.c @@ -154,6 +154,64 @@ utimensat(int fd, const char *path, const struct timespec times[2], } #endif +#ifndef HAVE_FCHOWNAT +/* + * A limited implementation of fchownat() that only implements the + * functionality used by OpenSSH, currently only AT_FDCWD and + * AT_SYMLINK_NOFOLLOW. + */ +int +fchownat(int fd, const char *path, uid_t owner, gid_t group, int flag) +{ + int ret, oflags = O_WRONLY; + + if (fd != AT_FDCWD) { + errno = ENOSYS; + return -1; + } +# ifndef HAVE_FCHOWN + return chown(pathname, owner, group); +# else + if (flag & AT_SYMLINK_NOFOLLOW) + oflags |= O_NOFOLLOW; + if ((fd = open(path, oflags)) == -1) + return -1; + ret = fchown(fd, owner, group); + close(fd); + return ret; +# endif +} +#endif + +#ifndef HAVE_FCHMODAT +/* + * A limited implementation of fchmodat() that only implements the + * functionality used by OpenSSH, currently only AT_FDCWD and + * AT_SYMLINK_NOFOLLOW. + */ +int +fchmodat(int fd, const char *path, mode_t mode, int flag) +{ + int ret, oflags = O_WRONLY; + + if (fd != AT_FDCWD) { + errno = ENOSYS; + return -1; + } +# ifndef HAVE_FCHMOD + return chown(pathname, owner, group); +# else + if (flag & AT_SYMLINK_NOFOLLOW) + oflags |= O_NOFOLLOW; + if ((fd = open(path, oflags)) == -1) + return -1; + ret = fchmod(fd, mode); + close(fd); + return ret; +# endif +} +#endif + #ifndef HAVE_TRUNCATE int truncate(const char *path, off_t length) { diff --git a/openbsd-compat/bsd-misc.h b/openbsd-compat/bsd-misc.h index 584c2b5ef..cb158cd5c 100644 --- a/openbsd-compat/bsd-misc.h +++ b/openbsd-compat/bsd-misc.h @@ -72,6 +72,18 @@ int utimes(char *, struct timeval *); int utimensat(int, const char *, const struct timespec[2], int); #endif +#ifndef AT_FDCWD +# define AT_FDCWD (-2) +#endif + +#ifndef HAVE_FCHMODAT +int fchmodat(int, const char *, mode_t, int); +#endif + +#ifndef HAVE_FCHOWNAT +int fchownat(int, const char *, uid_t, gid_t, int); +#endif + #ifndef HAVE_TRUNCATE int truncate (const char *, off_t); #endif /* HAVE_TRUNCATE */ -- cgit v1.2.3 From 08f66d9f17e12c1140d1f1cf5c4dce67e915d3cc Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sun, 20 Jan 2019 09:58:45 +1100 Subject: remove vestiges of old packet API from loginrec.c --- auth.c | 6 +++--- auth2.c | 5 ++++- loginrec.c | 6 +++--- loginrec.h | 5 ++++- openbsd-compat/port-aix.c | 4 ++-- openbsd-compat/port-aix.h | 3 ++- 6 files changed, 18 insertions(+), 11 deletions(-) (limited to 'openbsd-compat') diff --git a/auth.c b/auth.c index fea2c650f..a4c1dece5 100644 --- a/auth.c +++ b/auth.c @@ -356,11 +356,11 @@ auth_log(struct ssh *ssh, int authenticated, int partial, (strcmp(method, "password") == 0 || strncmp(method, "keyboard-interactive", 20) == 0 || strcmp(method, "challenge-response") == 0)) - record_failed_login(authctxt->user, + record_failed_login(ssh, authctxt->user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); # ifdef WITH_AIXAUTHENTICATE if (authenticated) - sys_auth_record_login(authctxt->user, + sys_auth_record_login(ssh, authctxt->user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh", loginmsg); # endif @@ -601,7 +601,7 @@ getpwnamallow(struct ssh *ssh, const char *user) logit("Invalid user %.100s from %.100s port %d", user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); #ifdef CUSTOM_FAILED_LOGIN - record_failed_login(user, + record_failed_login(ssh, user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); #endif #ifdef SSH_AUDIT_EVENTS diff --git a/auth2.c b/auth2.c index 1f023e8b1..2e996fa59 100644 --- a/auth2.c +++ b/auth2.c @@ -401,7 +401,10 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method, fatal("%s: buffer error: %s", __func__, ssh_err(r)); userauth_send_banner(ssh, sshbuf_ptr(loginmsg)); - packet_write_wait(); + if ((r = ssh_packet_write_wait(ssh)) != 0) { + sshpkt_fatal(ssh, r, + "%s: send PAM banner", __func__); + } } fatal("Access denied for user %s by PAM account " "configuration", authctxt->user); diff --git a/loginrec.c b/loginrec.c index 08fc73758..5f2a47797 100644 --- a/loginrec.c +++ b/loginrec.c @@ -1653,7 +1653,7 @@ utmpx_get_entry(struct logininfo *li) */ void -record_failed_login(const char *username, const char *hostname, +record_failed_login(struct ssh *ssh, const char *username, const char *hostname, const char *ttyn) { int fd; @@ -1696,8 +1696,8 @@ record_failed_login(const char *username, const char *hostname, /* strncpy because we don't necessarily want nul termination */ strncpy(ut.ut_host, hostname, sizeof(ut.ut_host)); - if (packet_connection_is_on_socket() && - getpeername(packet_get_connection_in(), + if (ssh_packet_connection_is_on_socket(ssh) && + getpeername(ssh_packet_get_connection_in(ssh), (struct sockaddr *)&from, &fromlen) == 0) { ipv64_normalise_mapped(&from, &fromlen); if (from.ss_family == AF_INET) { diff --git a/loginrec.h b/loginrec.h index 28923e781..62cc0e78c 100644 --- a/loginrec.h +++ b/loginrec.h @@ -31,6 +31,8 @@ #include "includes.h" +struct ssh; + /** ** you should use the login_* calls to work around platform dependencies **/ @@ -126,6 +128,7 @@ char *line_fullname(char *dst, const char *src, u_int dstsize); char *line_stripname(char *dst, const char *src, int dstsize); char *line_abbrevname(char *dst, const char *src, int dstsize); -void record_failed_login(const char *, const char *, const char *); +void record_failed_login(struct ssh *, const char *, const char *, + const char *); #endif /* _HAVE_LOGINREC_H_ */ diff --git a/openbsd-compat/port-aix.c b/openbsd-compat/port-aix.c index 943177c70..52698050c 100644 --- a/openbsd-compat/port-aix.c +++ b/openbsd-compat/port-aix.c @@ -280,8 +280,8 @@ sys_auth_allowed_user(struct passwd *pw, struct sshbuf *loginmsg) } int -sys_auth_record_login(const char *user, const char *host, const char *ttynm, - struct sshbuf *loginmsg) +sys_auth_record_login(struct ssh *ssh, const char *user, const char *host, + const char *ttynm, struct sshbuf *loginmsg) { char *msg = NULL; int success = 0; diff --git a/openbsd-compat/port-aix.h b/openbsd-compat/port-aix.h index 748c0e4e3..4702e3bf1 100644 --- a/openbsd-compat/port-aix.h +++ b/openbsd-compat/port-aix.h @@ -30,6 +30,7 @@ # include #endif +struct ssh; struct sshbuf; /* These should be in the system headers but are not. */ @@ -89,7 +90,7 @@ void aix_usrinfo(struct passwd *); # define CUSTOM_SYS_AUTH_ALLOWED_USER 1 int sys_auth_allowed_user(struct passwd *, struct sshbuf *); # define CUSTOM_SYS_AUTH_RECORD_LOGIN 1 -int sys_auth_record_login(const char *, const char *, +int sys_auth_record_login(struct ssh *, const char *, const char *, const char *, struct sshbuf *); # define CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG char *sys_auth_get_lastlogin_msg(const char *, uid_t); -- cgit v1.2.3 From f236ca2741f29b5c443c0b2db3aa9afb9ad9befe Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Thu, 24 Jan 2019 09:50:58 +1100 Subject: Also undef SIMPLEQ_FOREACH_SAFE. Prevents macro redefinition warning on at least NetBSD 6.1. --- openbsd-compat/sys-queue.h | 1 + 1 file changed, 1 insertion(+) (limited to 'openbsd-compat') diff --git a/openbsd-compat/sys-queue.h b/openbsd-compat/sys-queue.h index af93d6814..5108f394c 100644 --- a/openbsd-compat/sys-queue.h +++ b/openbsd-compat/sys-queue.h @@ -81,6 +81,7 @@ #undef SIMPLEQ_EMPTY #undef SIMPLEQ_NEXT #undef SIMPLEQ_FOREACH +#undef SIMPLEQ_FOREACH_SAFE #undef SIMPLEQ_INIT #undef SIMPLEQ_INSERT_HEAD #undef SIMPLEQ_INSERT_TAIL -- cgit v1.2.3 From f02afa350afac1b2f2d1413259a27a4ba1e2ca24 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 20 Feb 2019 13:41:24 +0100 Subject: Revert "[auth.c] On Cygwin, refuse usernames that have differences in case" This reverts commit acc9b29486dfd649dfda474e5c1a03b317449f1c. Signed-off-by: Corinna Vinschen --- auth.c | 13 ---- groupaccess.c | 4 ++ match.c | 4 ++ openbsd-compat/bsd-cygwin_util.c | 146 +++++++++++++++++++++++++++++++++++++++ servconf.c | 4 ++ 5 files changed, 158 insertions(+), 13 deletions(-) (limited to 'openbsd-compat') diff --git a/auth.c b/auth.c index 62c58e72f..332b6220c 100644 --- a/auth.c +++ b/auth.c @@ -583,19 +583,6 @@ getpwnamallow(struct ssh *ssh, const char *user) #if defined(_AIX) && defined(HAVE_SETAUTHDB) aix_restoreauthdb(); -#endif -#ifdef HAVE_CYGWIN - /* - * Windows usernames are case-insensitive. To avoid later problems - * when trying to match the username, the user is only allowed to - * login if the username is given in the same case as stored in the - * user database. - */ - if (pw != NULL && strcmp(user, pw->pw_name) != 0) { - logit("Login name %.100s does not match stored username %.100s", - user, pw->pw_name); - pw = NULL; - } #endif if (pw == NULL) { logit("Invalid user %.100s from %.100s port %d", diff --git a/groupaccess.c b/groupaccess.c index 9e4d25521..43367990d 100644 --- a/groupaccess.c +++ b/groupaccess.c @@ -103,7 +103,11 @@ ga_match_pattern_list(const char *group_pattern) int i, found = 0; for (i = 0; i < ngroups; i++) { +#ifndef HAVE_CYGWIN switch (match_pattern_list(groups_byname[i], group_pattern, 0)) { +#else + switch (match_pattern_list(groups_byname[i], group_pattern, 1)) { +#endif case -1: return 0; /* Negated match wins */ case 0: diff --git a/match.c b/match.c index bb3e95f67..b50ae4057 100644 --- a/match.c +++ b/match.c @@ -111,6 +111,8 @@ match_pattern(const char *s, const char *pattern) /* NOTREACHED */ } +#ifndef HAVE_CYGWIN /* Cygwin version in openbsd-compat/bsd-cygwin_util.c */ + /* * Tries to match the string against the * comma-separated sequence of subpatterns (each possibly preceded by ! to @@ -170,6 +172,8 @@ match_pattern_list(const char *string, const char *pattern, int dolower) return got_positive; } +#endif + /* * Tries to match the host name (which must be in all lowercase) against the * comma-separated sequence of subpatterns (each possibly preceded by ! to diff --git a/openbsd-compat/bsd-cygwin_util.c b/openbsd-compat/bsd-cygwin_util.c index fb49e30f5..f721fca9d 100644 --- a/openbsd-compat/bsd-cygwin_util.c +++ b/openbsd-compat/bsd-cygwin_util.c @@ -37,6 +37,8 @@ #include #include #include +#include +#include #include "xmalloc.h" @@ -117,4 +119,148 @@ free_windows_environment(char **p) free(p); } +/* + * Returns true if the given string matches the pattern (which may contain ? + * and * as wildcards), and zero if it does not match. + * + * The Cygwin version of this function must be case-insensitive and take + * Unicode characters into account. + */ + +static int +__match_pattern (const wchar_t *s, const wchar_t *pattern, int caseinsensitive) +{ + for (;;) { + /* If at end of pattern, accept if also at end of string. */ + if (!*pattern) + return !*s; + + if (*pattern == '*') { + /* Skip the asterisk. */ + pattern++; + + /* If at end of pattern, accept immediately. */ + if (!*pattern) + return 1; + + /* If next character in pattern is known, optimize. */ + if (*pattern != '?' && *pattern != '*') { + /* + * Look instances of the next character in + * pattern, and try to match starting from + * those. + */ + for (; *s; s++) + if (*s == *pattern && + __match_pattern(s + 1, pattern + 1, + caseinsensitive)) + return 1; + /* Failed. */ + return 0; + } + /* + * Move ahead one character at a time and try to + * match at each position. + */ + for (; *s; s++) + if (__match_pattern(s, pattern, caseinsensitive)) + return 1; + /* Failed. */ + return 0; + } + /* + * There must be at least one more character in the string. + * If we are at the end, fail. + */ + if (!*s) + return 0; + + /* Check if the next character of the string is acceptable. */ + if (*pattern != '?' && (*pattern != *s && + (!caseinsensitive || towlower(*pattern) != towlower(*s)))) + return 0; + + /* Move to the next character, both in string and in pattern. */ + s++; + pattern++; + } + /* NOTREACHED */ +} + +static int +_match_pattern(const char *s, const char *pattern, int caseinsensitive) +{ + wchar_t *ws; + wchar_t *wpattern; + size_t len; + + if ((len = mbstowcs(NULL, s, 0)) < 0) + return 0; + ws = (wchar_t *) alloca((len + 1) * sizeof (wchar_t)); + mbstowcs(ws, s, len + 1); + if ((len = mbstowcs(NULL, pattern, 0)) < 0) + return 0; + wpattern = (wchar_t *) alloca((len + 1) * sizeof (wchar_t)); + mbstowcs(wpattern, pattern, len + 1); + return __match_pattern (ws, wpattern, caseinsensitive); +} + +/* + * Tries to match the string against the + * comma-separated sequence of subpatterns (each possibly preceded by ! to + * indicate negation). Returns -1 if negation matches, 1 if there is + * a positive match, 0 if there is no match at all. + */ +int +match_pattern_list(const char *string, const char *pattern, int caseinsensitive) +{ + char sub[1024]; + int negated; + int got_positive; + u_int i, subi, len = strlen(pattern); + + got_positive = 0; + for (i = 0; i < len;) { + /* Check if the subpattern is negated. */ + if (pattern[i] == '!') { + negated = 1; + i++; + } else + negated = 0; + + /* + * Extract the subpattern up to a comma or end. Convert the + * subpattern to lowercase. + */ + for (subi = 0; + i < len && subi < sizeof(sub) - 1 && pattern[i] != ','; + subi++, i++) + sub[subi] = pattern[i]; + /* If subpattern too long, return failure (no match). */ + if (subi >= sizeof(sub) - 1) + return 0; + + /* If the subpattern was terminated by a comma, then skip it. */ + if (i < len && pattern[i] == ',') + i++; + + /* Null-terminate the subpattern. */ + sub[subi] = '\0'; + + /* Try to match the subpattern against the string. */ + if (_match_pattern(string, sub, caseinsensitive)) { + if (negated) + return -1; /* Negative */ + else + got_positive = 1; /* Positive */ + } + } + + /* + * Return success if got a positive match. If there was a negative + * match, we have already returned -1 and never get here. + */ + return got_positive; +} + #endif /* HAVE_CYGWIN */ diff --git a/servconf.c b/servconf.c index d9680aba1..4fa896fd4 100644 --- a/servconf.c +++ b/servconf.c @@ -1049,7 +1049,11 @@ match_cfg_line(char **condition, int line, struct connection_info *ci) } if (ci->user == NULL) match_test_missing_fatal("User", "user"); +#ifndef HAVE_CYGWIN if (match_pattern_list(ci->user, arg, 0) != 1) +#else + if (match_pattern_list(ci->user, arg, 1) != 1) +#endif result = 0; else debug("user %.100s matched 'User %.100s' at " -- cgit v1.2.3 From bed1d43698807a07bb4ddb93a46b0bd84b9970b3 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Fri, 22 Feb 2019 15:21:21 +1100 Subject: Revert unintended parts of previous commit. --- groupaccess.c | 4 -- match.c | 4 -- openbsd-compat/bsd-cygwin_util.c | 146 --------------------------------------- servconf.c | 4 -- 4 files changed, 158 deletions(-) (limited to 'openbsd-compat') diff --git a/groupaccess.c b/groupaccess.c index 43367990d..9e4d25521 100644 --- a/groupaccess.c +++ b/groupaccess.c @@ -103,11 +103,7 @@ ga_match_pattern_list(const char *group_pattern) int i, found = 0; for (i = 0; i < ngroups; i++) { -#ifndef HAVE_CYGWIN switch (match_pattern_list(groups_byname[i], group_pattern, 0)) { -#else - switch (match_pattern_list(groups_byname[i], group_pattern, 1)) { -#endif case -1: return 0; /* Negated match wins */ case 0: diff --git a/match.c b/match.c index b50ae4057..bb3e95f67 100644 --- a/match.c +++ b/match.c @@ -111,8 +111,6 @@ match_pattern(const char *s, const char *pattern) /* NOTREACHED */ } -#ifndef HAVE_CYGWIN /* Cygwin version in openbsd-compat/bsd-cygwin_util.c */ - /* * Tries to match the string against the * comma-separated sequence of subpatterns (each possibly preceded by ! to @@ -172,8 +170,6 @@ match_pattern_list(const char *string, const char *pattern, int dolower) return got_positive; } -#endif - /* * Tries to match the host name (which must be in all lowercase) against the * comma-separated sequence of subpatterns (each possibly preceded by ! to diff --git a/openbsd-compat/bsd-cygwin_util.c b/openbsd-compat/bsd-cygwin_util.c index f721fca9d..fb49e30f5 100644 --- a/openbsd-compat/bsd-cygwin_util.c +++ b/openbsd-compat/bsd-cygwin_util.c @@ -37,8 +37,6 @@ #include #include #include -#include -#include #include "xmalloc.h" @@ -119,148 +117,4 @@ free_windows_environment(char **p) free(p); } -/* - * Returns true if the given string matches the pattern (which may contain ? - * and * as wildcards), and zero if it does not match. - * - * The Cygwin version of this function must be case-insensitive and take - * Unicode characters into account. - */ - -static int -__match_pattern (const wchar_t *s, const wchar_t *pattern, int caseinsensitive) -{ - for (;;) { - /* If at end of pattern, accept if also at end of string. */ - if (!*pattern) - return !*s; - - if (*pattern == '*') { - /* Skip the asterisk. */ - pattern++; - - /* If at end of pattern, accept immediately. */ - if (!*pattern) - return 1; - - /* If next character in pattern is known, optimize. */ - if (*pattern != '?' && *pattern != '*') { - /* - * Look instances of the next character in - * pattern, and try to match starting from - * those. - */ - for (; *s; s++) - if (*s == *pattern && - __match_pattern(s + 1, pattern + 1, - caseinsensitive)) - return 1; - /* Failed. */ - return 0; - } - /* - * Move ahead one character at a time and try to - * match at each position. - */ - for (; *s; s++) - if (__match_pattern(s, pattern, caseinsensitive)) - return 1; - /* Failed. */ - return 0; - } - /* - * There must be at least one more character in the string. - * If we are at the end, fail. - */ - if (!*s) - return 0; - - /* Check if the next character of the string is acceptable. */ - if (*pattern != '?' && (*pattern != *s && - (!caseinsensitive || towlower(*pattern) != towlower(*s)))) - return 0; - - /* Move to the next character, both in string and in pattern. */ - s++; - pattern++; - } - /* NOTREACHED */ -} - -static int -_match_pattern(const char *s, const char *pattern, int caseinsensitive) -{ - wchar_t *ws; - wchar_t *wpattern; - size_t len; - - if ((len = mbstowcs(NULL, s, 0)) < 0) - return 0; - ws = (wchar_t *) alloca((len + 1) * sizeof (wchar_t)); - mbstowcs(ws, s, len + 1); - if ((len = mbstowcs(NULL, pattern, 0)) < 0) - return 0; - wpattern = (wchar_t *) alloca((len + 1) * sizeof (wchar_t)); - mbstowcs(wpattern, pattern, len + 1); - return __match_pattern (ws, wpattern, caseinsensitive); -} - -/* - * Tries to match the string against the - * comma-separated sequence of subpatterns (each possibly preceded by ! to - * indicate negation). Returns -1 if negation matches, 1 if there is - * a positive match, 0 if there is no match at all. - */ -int -match_pattern_list(const char *string, const char *pattern, int caseinsensitive) -{ - char sub[1024]; - int negated; - int got_positive; - u_int i, subi, len = strlen(pattern); - - got_positive = 0; - for (i = 0; i < len;) { - /* Check if the subpattern is negated. */ - if (pattern[i] == '!') { - negated = 1; - i++; - } else - negated = 0; - - /* - * Extract the subpattern up to a comma or end. Convert the - * subpattern to lowercase. - */ - for (subi = 0; - i < len && subi < sizeof(sub) - 1 && pattern[i] != ','; - subi++, i++) - sub[subi] = pattern[i]; - /* If subpattern too long, return failure (no match). */ - if (subi >= sizeof(sub) - 1) - return 0; - - /* If the subpattern was terminated by a comma, then skip it. */ - if (i < len && pattern[i] == ',') - i++; - - /* Null-terminate the subpattern. */ - sub[subi] = '\0'; - - /* Try to match the subpattern against the string. */ - if (_match_pattern(string, sub, caseinsensitive)) { - if (negated) - return -1; /* Negative */ - else - got_positive = 1; /* Positive */ - } - } - - /* - * Return success if got a positive match. If there was a negative - * match, we have already returned -1 and never get here. - */ - return got_positive; -} - #endif /* HAVE_CYGWIN */ diff --git a/servconf.c b/servconf.c index 4fa896fd4..d9680aba1 100644 --- a/servconf.c +++ b/servconf.c @@ -1049,11 +1049,7 @@ match_cfg_line(char **condition, int line, struct connection_info *ci) } if (ci->user == NULL) match_test_missing_fatal("User", "user"); -#ifndef HAVE_CYGWIN if (match_pattern_list(ci->user, arg, 0) != 1) -#else - if (match_pattern_list(ci->user, arg, 1) != 1) -#endif result = 0; else debug("user %.100s matched 'User %.100s' at " -- cgit v1.2.3 From 37638c752041d591371900df820f070037878a2d Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Wed, 20 Feb 2019 13:41:25 +0100 Subject: Cygwin: implement case-insensitive Unicode user and group name matching The previous revert enabled case-insensitive user names again. This patch implements the case-insensitive user and group name matching. To allow Unicode chars, implement the matcher using wchar_t chars in Cygwin-specific code. Keep the generic code changes as small as possible. Cygwin: implement case-insensitive Unicode user and group name matching Signed-off-by: Corinna Vinschen --- groupaccess.c | 4 ++ match.c | 4 ++ openbsd-compat/bsd-cygwin_util.c | 146 +++++++++++++++++++++++++++++++++++++++ servconf.c | 4 ++ 4 files changed, 158 insertions(+) (limited to 'openbsd-compat') diff --git a/groupaccess.c b/groupaccess.c index 9e4d25521..43367990d 100644 --- a/groupaccess.c +++ b/groupaccess.c @@ -103,7 +103,11 @@ ga_match_pattern_list(const char *group_pattern) int i, found = 0; for (i = 0; i < ngroups; i++) { +#ifndef HAVE_CYGWIN switch (match_pattern_list(groups_byname[i], group_pattern, 0)) { +#else + switch (match_pattern_list(groups_byname[i], group_pattern, 1)) { +#endif case -1: return 0; /* Negated match wins */ case 0: diff --git a/match.c b/match.c index bb3e95f67..b50ae4057 100644 --- a/match.c +++ b/match.c @@ -111,6 +111,8 @@ match_pattern(const char *s, const char *pattern) /* NOTREACHED */ } +#ifndef HAVE_CYGWIN /* Cygwin version in openbsd-compat/bsd-cygwin_util.c */ + /* * Tries to match the string against the * comma-separated sequence of subpatterns (each possibly preceded by ! to @@ -170,6 +172,8 @@ match_pattern_list(const char *string, const char *pattern, int dolower) return got_positive; } +#endif + /* * Tries to match the host name (which must be in all lowercase) against the * comma-separated sequence of subpatterns (each possibly preceded by ! to diff --git a/openbsd-compat/bsd-cygwin_util.c b/openbsd-compat/bsd-cygwin_util.c index fb49e30f5..f721fca9d 100644 --- a/openbsd-compat/bsd-cygwin_util.c +++ b/openbsd-compat/bsd-cygwin_util.c @@ -37,6 +37,8 @@ #include #include #include +#include +#include #include "xmalloc.h" @@ -117,4 +119,148 @@ free_windows_environment(char **p) free(p); } +/* + * Returns true if the given string matches the pattern (which may contain ? + * and * as wildcards), and zero if it does not match. + * + * The Cygwin version of this function must be case-insensitive and take + * Unicode characters into account. + */ + +static int +__match_pattern (const wchar_t *s, const wchar_t *pattern, int caseinsensitive) +{ + for (;;) { + /* If at end of pattern, accept if also at end of string. */ + if (!*pattern) + return !*s; + + if (*pattern == '*') { + /* Skip the asterisk. */ + pattern++; + + /* If at end of pattern, accept immediately. */ + if (!*pattern) + return 1; + + /* If next character in pattern is known, optimize. */ + if (*pattern != '?' && *pattern != '*') { + /* + * Look instances of the next character in + * pattern, and try to match starting from + * those. + */ + for (; *s; s++) + if (*s == *pattern && + __match_pattern(s + 1, pattern + 1, + caseinsensitive)) + return 1; + /* Failed. */ + return 0; + } + /* + * Move ahead one character at a time and try to + * match at each position. + */ + for (; *s; s++) + if (__match_pattern(s, pattern, caseinsensitive)) + return 1; + /* Failed. */ + return 0; + } + /* + * There must be at least one more character in the string. + * If we are at the end, fail. + */ + if (!*s) + return 0; + + /* Check if the next character of the string is acceptable. */ + if (*pattern != '?' && (*pattern != *s && + (!caseinsensitive || towlower(*pattern) != towlower(*s)))) + return 0; + + /* Move to the next character, both in string and in pattern. */ + s++; + pattern++; + } + /* NOTREACHED */ +} + +static int +_match_pattern(const char *s, const char *pattern, int caseinsensitive) +{ + wchar_t *ws; + wchar_t *wpattern; + size_t len; + + if ((len = mbstowcs(NULL, s, 0)) < 0) + return 0; + ws = (wchar_t *) alloca((len + 1) * sizeof (wchar_t)); + mbstowcs(ws, s, len + 1); + if ((len = mbstowcs(NULL, pattern, 0)) < 0) + return 0; + wpattern = (wchar_t *) alloca((len + 1) * sizeof (wchar_t)); + mbstowcs(wpattern, pattern, len + 1); + return __match_pattern (ws, wpattern, caseinsensitive); +} + +/* + * Tries to match the string against the + * comma-separated sequence of subpatterns (each possibly preceded by ! to + * indicate negation). Returns -1 if negation matches, 1 if there is + * a positive match, 0 if there is no match at all. + */ +int +match_pattern_list(const char *string, const char *pattern, int caseinsensitive) +{ + char sub[1024]; + int negated; + int got_positive; + u_int i, subi, len = strlen(pattern); + + got_positive = 0; + for (i = 0; i < len;) { + /* Check if the subpattern is negated. */ + if (pattern[i] == '!') { + negated = 1; + i++; + } else + negated = 0; + + /* + * Extract the subpattern up to a comma or end. Convert the + * subpattern to lowercase. + */ + for (subi = 0; + i < len && subi < sizeof(sub) - 1 && pattern[i] != ','; + subi++, i++) + sub[subi] = pattern[i]; + /* If subpattern too long, return failure (no match). */ + if (subi >= sizeof(sub) - 1) + return 0; + + /* If the subpattern was terminated by a comma, then skip it. */ + if (i < len && pattern[i] == ',') + i++; + + /* Null-terminate the subpattern. */ + sub[subi] = '\0'; + + /* Try to match the subpattern against the string. */ + if (_match_pattern(string, sub, caseinsensitive)) { + if (negated) + return -1; /* Negative */ + else + got_positive = 1; /* Positive */ + } + } + + /* + * Return success if got a positive match. If there was a negative + * match, we have already returned -1 and never get here. + */ + return got_positive; +} + #endif /* HAVE_CYGWIN */ diff --git a/servconf.c b/servconf.c index d9680aba1..4fa896fd4 100644 --- a/servconf.c +++ b/servconf.c @@ -1049,7 +1049,11 @@ match_cfg_line(char **condition, int line, struct connection_info *ci) } if (ci->user == NULL) match_test_missing_fatal("User", "user"); +#ifndef HAVE_CYGWIN if (match_pattern_list(ci->user, arg, 0) != 1) +#else + if (match_pattern_list(ci->user, arg, 1) != 1) +#endif result = 0; else debug("user %.100s matched 'User %.100s' at " -- cgit v1.2.3 From daa7505aadca68ba1a2c70cbdfce423208eb91ee Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Tue, 12 Mar 2019 09:19:19 +1100 Subject: Use Cygwin-specific matching only for users+groups. Patch from vinschen at redhat.com, updated a little by me. --- match.c | 12 ++++-------- openbsd-compat/bsd-cygwin_util.c | 18 ++++++++---------- openbsd-compat/bsd-cygwin_util.h | 1 + 3 files changed, 13 insertions(+), 18 deletions(-) (limited to 'openbsd-compat') diff --git a/match.c b/match.c index ff0815ef9..fcf69596d 100644 --- a/match.c +++ b/match.c @@ -111,8 +111,6 @@ match_pattern(const char *s, const char *pattern) /* NOTREACHED */ } -#ifndef HAVE_CYGWIN /* Cygwin version in openbsd-compat/bsd-cygwin_util.c */ - /* * Tries to match the string against the * comma-separated sequence of subpatterns (each possibly preceded by ! to @@ -172,18 +170,16 @@ match_pattern_list(const char *string, const char *pattern, int dolower) return got_positive; } -#endif - /* Match a list representing users or groups. */ int match_usergroup_pattern_list(const char *string, const char *pattern) { -#ifndef HAVE_CYGWIN - /* Case sensitive match */ - return match_pattern_list(string, pattern, 0); +#ifdef HAVE_CYGWIN + /* Windows usernames may be Unicode and are not case sensitive */ + return cygwin_ug_match_pattern_list(string, pattern); #else /* Case insensitive match */ - return match_pattern_list(string, pattern, 1); + return match_pattern_list(string, pattern, 0); #endif } diff --git a/openbsd-compat/bsd-cygwin_util.c b/openbsd-compat/bsd-cygwin_util.c index f721fca9d..1e4cdc928 100644 --- a/openbsd-compat/bsd-cygwin_util.c +++ b/openbsd-compat/bsd-cygwin_util.c @@ -128,7 +128,7 @@ free_windows_environment(char **p) */ static int -__match_pattern (const wchar_t *s, const wchar_t *pattern, int caseinsensitive) +__match_pattern (const wchar_t *s, const wchar_t *pattern) { for (;;) { /* If at end of pattern, accept if also at end of string. */ @@ -152,8 +152,7 @@ __match_pattern (const wchar_t *s, const wchar_t *pattern, int caseinsensitive) */ for (; *s; s++) if (*s == *pattern && - __match_pattern(s + 1, pattern + 1, - caseinsensitive)) + __match_pattern(s + 1, pattern + 1)) return 1; /* Failed. */ return 0; @@ -163,7 +162,7 @@ __match_pattern (const wchar_t *s, const wchar_t *pattern, int caseinsensitive) * match at each position. */ for (; *s; s++) - if (__match_pattern(s, pattern, caseinsensitive)) + if (__match_pattern(s, pattern)) return 1; /* Failed. */ return 0; @@ -176,8 +175,7 @@ __match_pattern (const wchar_t *s, const wchar_t *pattern, int caseinsensitive) return 0; /* Check if the next character of the string is acceptable. */ - if (*pattern != '?' && (*pattern != *s && - (!caseinsensitive || towlower(*pattern) != towlower(*s)))) + if (*pattern != '?' && towlower(*pattern) != towlower(*s)) return 0; /* Move to the next character, both in string and in pattern. */ @@ -188,7 +186,7 @@ __match_pattern (const wchar_t *s, const wchar_t *pattern, int caseinsensitive) } static int -_match_pattern(const char *s, const char *pattern, int caseinsensitive) +_match_pattern(const char *s, const char *pattern) { wchar_t *ws; wchar_t *wpattern; @@ -202,7 +200,7 @@ _match_pattern(const char *s, const char *pattern, int caseinsensitive) return 0; wpattern = (wchar_t *) alloca((len + 1) * sizeof (wchar_t)); mbstowcs(wpattern, pattern, len + 1); - return __match_pattern (ws, wpattern, caseinsensitive); + return __match_pattern (ws, wpattern); } /* @@ -212,7 +210,7 @@ _match_pattern(const char *s, const char *pattern, int caseinsensitive) * a positive match, 0 if there is no match at all. */ int -match_pattern_list(const char *string, const char *pattern, int caseinsensitive) +cygwin_ug_match_pattern_list(const char *string, const char *pattern) { char sub[1024]; int negated; @@ -248,7 +246,7 @@ match_pattern_list(const char *string, const char *pattern, int caseinsensitive) sub[subi] = '\0'; /* Try to match the subpattern against the string. */ - if (_match_pattern(string, sub, caseinsensitive)) { + if (_match_pattern(string, sub)) { if (negated) return -1; /* Negative */ else diff --git a/openbsd-compat/bsd-cygwin_util.h b/openbsd-compat/bsd-cygwin_util.h index 202c055db..55c5a5b81 100644 --- a/openbsd-compat/bsd-cygwin_util.h +++ b/openbsd-compat/bsd-cygwin_util.h @@ -55,6 +55,7 @@ int binary_open(const char *, int , ...); int check_ntsec(const char *); char **fetch_windows_environment(void); void free_windows_environment(char **); +int cygwin_ug_match_pattern_list(const char *, const char *); #ifndef NO_BINARY_OPEN #define open binary_open -- cgit v1.2.3 From a212107bfdf4d3e870ab7a443e4d906e5b9578c3 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 13 Mar 2019 10:49:16 +1100 Subject: Replace alloca with xcalloc. The latter checks for memory exhaustion and integer overflow and may be at a less predictable place. Sanity check by vinschen at redhat.com, ok djm@ --- openbsd-compat/bsd-cygwin_util.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'openbsd-compat') diff --git a/openbsd-compat/bsd-cygwin_util.c b/openbsd-compat/bsd-cygwin_util.c index 1e4cdc928..54628e260 100644 --- a/openbsd-compat/bsd-cygwin_util.c +++ b/openbsd-compat/bsd-cygwin_util.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -191,16 +192,20 @@ _match_pattern(const char *s, const char *pattern) wchar_t *ws; wchar_t *wpattern; size_t len; + int ret; if ((len = mbstowcs(NULL, s, 0)) < 0) return 0; - ws = (wchar_t *) alloca((len + 1) * sizeof (wchar_t)); + ws = (wchar_t *) xcalloc(len + 1, sizeof (wchar_t)); mbstowcs(ws, s, len + 1); if ((len = mbstowcs(NULL, pattern, 0)) < 0) return 0; - wpattern = (wchar_t *) alloca((len + 1) * sizeof (wchar_t)); + wpattern = (wchar_t *) xcalloc(len + 1, sizeof (wchar_t)); mbstowcs(wpattern, pattern, len + 1); - return __match_pattern (ws, wpattern); + ret = __match_pattern (ws, wpattern); + free(ws); + free(wpattern); + return ret; } /* -- cgit v1.2.3 From f5abb05f8c7358dacdcb866fe2813f6d8efd5830 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Thu, 28 Mar 2019 09:26:14 +1100 Subject: Only use O_NOFOLLOW in utimensat if defined. Fixes build on systems that don't have it (Solaris <=9) Found by Tom G. Christensen. --- openbsd-compat/bsd-misc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'openbsd-compat') diff --git a/openbsd-compat/bsd-misc.c b/openbsd-compat/bsd-misc.c index d3a41df50..3c85a12a6 100644 --- a/openbsd-compat/bsd-misc.c +++ b/openbsd-compat/bsd-misc.c @@ -143,8 +143,10 @@ utimensat(int fd, const char *path, const struct timespec times[2], # ifndef HAVE_FUTIMES return utimes(path, tv); # else +# ifdef O_NOFOLLOW if (flag & AT_SYMLINK_NOFOLLOW) oflags |= O_NOFOLLOW; +# endif /* O_NOFOLLOW */ if ((fd = open(path, oflags)) == -1) return -1; ret = futimes(fd, tv); -- cgit v1.2.3 From 43f47ebbdd4037b569c23b8f4f7981f53b567f1d Mon Sep 17 00:00:00 2001 From: Tim Rice Date: Sun, 31 Mar 2019 19:22:19 -0700 Subject: Only use O_NOFOLLOW in fchownat and fchmodat if defined --- openbsd-compat/bsd-misc.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'openbsd-compat') diff --git a/openbsd-compat/bsd-misc.c b/openbsd-compat/bsd-misc.c index 3c85a12a6..aa1c7d7a3 100644 --- a/openbsd-compat/bsd-misc.c +++ b/openbsd-compat/bsd-misc.c @@ -174,8 +174,10 @@ fchownat(int fd, const char *path, uid_t owner, gid_t group, int flag) # ifndef HAVE_FCHOWN return chown(pathname, owner, group); # else +# ifdef O_NOFOLLOW if (flag & AT_SYMLINK_NOFOLLOW) oflags |= O_NOFOLLOW; +# endif /* O_NOFOLLOW */ if ((fd = open(path, oflags)) == -1) return -1; ret = fchown(fd, owner, group); @@ -203,8 +205,10 @@ fchmodat(int fd, const char *path, mode_t mode, int flag) # ifndef HAVE_FCHMOD return chown(pathname, owner, group); # else +# ifdef O_NOFOLLOW if (flag & AT_SYMLINK_NOFOLLOW) oflags |= O_NOFOLLOW; +# endif /* O_NOFOLLOW */ if ((fd = open(path, oflags)) == -1) return -1; ret = fchmod(fd, mode); -- cgit v1.2.3 From 138c0d52cdc90f9895333b82fc57d81cce7a3d90 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Tue, 2 Apr 2019 18:21:35 +1100 Subject: Adapt custom_failed_login to new prototype. Spotted by Kevin Brott. --- openbsd-compat/port-aix.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'openbsd-compat') diff --git a/openbsd-compat/port-aix.c b/openbsd-compat/port-aix.c index 52698050c..b61018b56 100644 --- a/openbsd-compat/port-aix.c +++ b/openbsd-compat/port-aix.c @@ -313,7 +313,8 @@ sys_auth_get_lastlogin_msg(const char *user, uid_t uid) * record_failed_login: generic "login failed" interface function */ void -record_failed_login(const char *user, const char *hostname, const char *ttyname) +record_failed_login(struct ssh *ssh, const char *user, const char *hostname, + const char *ttyname) { if (geteuid() != 0) return; -- cgit v1.2.3 From 79a87d32783d6c9db40af8f35e091d9d30365ae7 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Wed, 3 Apr 2019 06:27:45 +1100 Subject: Remove "struct ssh" from sys_auth_record_login. It's not needed, and is not available from the call site in loginrec.c Should only affect AIX, spotted by Kevin Brott. --- auth.c | 2 +- openbsd-compat/port-aix.c | 4 ++-- openbsd-compat/port-aix.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'openbsd-compat') diff --git a/auth.c b/auth.c index 332b6220c..8696f258e 100644 --- a/auth.c +++ b/auth.c @@ -360,7 +360,7 @@ auth_log(struct ssh *ssh, int authenticated, int partial, auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); # ifdef WITH_AIXAUTHENTICATE if (authenticated) - sys_auth_record_login(ssh, authctxt->user, + sys_auth_record_login(authctxt->user, auth_get_canonical_hostname(ssh, options.use_dns), "ssh", loginmsg); # endif diff --git a/openbsd-compat/port-aix.c b/openbsd-compat/port-aix.c index b61018b56..fc80dc39f 100644 --- a/openbsd-compat/port-aix.c +++ b/openbsd-compat/port-aix.c @@ -280,8 +280,8 @@ sys_auth_allowed_user(struct passwd *pw, struct sshbuf *loginmsg) } int -sys_auth_record_login(struct ssh *ssh, const char *user, const char *host, - const char *ttynm, struct sshbuf *loginmsg) +sys_auth_record_login(const char *user, const char *host, const char *ttynm, + struct sshbuf *loginmsg) { char *msg = NULL; int success = 0; diff --git a/openbsd-compat/port-aix.h b/openbsd-compat/port-aix.h index 4702e3bf1..904de3096 100644 --- a/openbsd-compat/port-aix.h +++ b/openbsd-compat/port-aix.h @@ -90,8 +90,8 @@ void aix_usrinfo(struct passwd *); # define CUSTOM_SYS_AUTH_ALLOWED_USER 1 int sys_auth_allowed_user(struct passwd *, struct sshbuf *); # define CUSTOM_SYS_AUTH_RECORD_LOGIN 1 -int sys_auth_record_login(struct ssh *, const char *, const char *, - const char *, struct sshbuf *); +int sys_auth_record_login(const char *, const char *, const char *, + struct sshbuf *); # define CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG char *sys_auth_get_lastlogin_msg(const char *, uid_t); # define CUSTOM_FAILED_LOGIN 1 -- cgit v1.2.3 From 21e3ff3ab4791d3c94bd775da66cde29797fcb36 Mon Sep 17 00:00:00 2001 From: Manoj Srivastava Date: Sun, 9 Feb 2014 16:09:49 +0000 Subject: Handle SELinux authorisation roles Rejected upstream due to discomfort with magic usernames; a better approach will need an SSH protocol change. In the meantime, this came from Debian's SELinux maintainer, so we'll keep it until we have something better. Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1641 Bug-Debian: http://bugs.debian.org/394795 Last-Update: 2019-06-05 Patch-Name: selinux-role.patch --- auth.h | 1 + auth2.c | 10 ++++++++-- monitor.c | 37 +++++++++++++++++++++++++++++++++---- monitor.h | 2 ++ monitor_wrap.c | 27 ++++++++++++++++++++++++--- monitor_wrap.h | 3 ++- openbsd-compat/port-linux.c | 21 ++++++++++++++------- openbsd-compat/port-linux.h | 4 ++-- platform.c | 4 ++-- platform.h | 2 +- session.c | 10 +++++----- session.h | 2 +- sshd.c | 2 +- sshpty.c | 4 ++-- sshpty.h | 2 +- 15 files changed, 99 insertions(+), 32 deletions(-) (limited to 'openbsd-compat') diff --git a/auth.h b/auth.h index bf393e755..8f13bdf48 100644 --- a/auth.h +++ b/auth.h @@ -65,6 +65,7 @@ struct Authctxt { char *service; struct passwd *pw; /* set if 'valid' */ char *style; + char *role; /* Method lists for multiple authentication */ char **auth_methods; /* modified from server config */ diff --git a/auth2.c b/auth2.c index 7417eafa4..d60e7f1f2 100644 --- a/auth2.c +++ b/auth2.c @@ -267,7 +267,7 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) { Authctxt *authctxt = ssh->authctxt; Authmethod *m = NULL; - char *user = NULL, *service = NULL, *method = NULL, *style = NULL; + char *user = NULL, *service = NULL, *method = NULL, *style = NULL, *role = NULL; int r, authenticated = 0; double tstart = monotime_double(); @@ -281,8 +281,13 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) debug("userauth-request for user %s service %s method %s", user, service, method); debug("attempt %d failures %d", authctxt->attempt, authctxt->failures); + if ((role = strchr(user, '/')) != NULL) + *role++ = 0; + if ((style = strchr(user, ':')) != NULL) *style++ = 0; + else if (role && (style = strchr(role, ':')) != NULL) + *style++ = '\0'; if (authctxt->attempt++ == 0) { /* setup auth context */ @@ -309,8 +314,9 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) use_privsep ? " [net]" : ""); authctxt->service = xstrdup(service); authctxt->style = style ? xstrdup(style) : NULL; + authctxt->role = role ? xstrdup(role) : NULL; if (use_privsep) - mm_inform_authserv(service, style); + mm_inform_authserv(service, style, role); userauth_banner(ssh); if (auth2_setup_methods_lists(authctxt) != 0) ssh_packet_disconnect(ssh, diff --git a/monitor.c b/monitor.c index 0766d6ef5..5f84e880d 100644 --- a/monitor.c +++ b/monitor.c @@ -117,6 +117,7 @@ int mm_answer_sign(struct ssh *, int, struct sshbuf *); int mm_answer_pwnamallow(struct ssh *, int, struct sshbuf *); int mm_answer_auth2_read_banner(struct ssh *, int, struct sshbuf *); int mm_answer_authserv(struct ssh *, int, struct sshbuf *); +int mm_answer_authrole(struct ssh *, int, struct sshbuf *); int mm_answer_authpassword(struct ssh *, int, struct sshbuf *); int mm_answer_bsdauthquery(struct ssh *, int, struct sshbuf *); int mm_answer_bsdauthrespond(struct ssh *, int, struct sshbuf *); @@ -197,6 +198,7 @@ struct mon_table mon_dispatch_proto20[] = { {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, + {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole}, {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, #ifdef USE_PAM @@ -819,6 +821,7 @@ mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m) /* Allow service/style information on the auth context */ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); + monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1); monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); #ifdef USE_PAM @@ -852,16 +855,42 @@ mm_answer_authserv(struct ssh *ssh, int sock, struct sshbuf *m) monitor_permit_authentications(1); if ((r = sshbuf_get_cstring(m, &authctxt->service, NULL)) != 0 || - (r = sshbuf_get_cstring(m, &authctxt->style, NULL)) != 0) + (r = sshbuf_get_cstring(m, &authctxt->style, NULL)) != 0 || + (r = sshbuf_get_cstring(m, &authctxt->role, NULL)) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); - debug3("%s: service=%s, style=%s", - __func__, authctxt->service, authctxt->style); + debug3("%s: service=%s, style=%s, role=%s", + __func__, authctxt->service, authctxt->style, authctxt->role); if (strlen(authctxt->style) == 0) { free(authctxt->style); authctxt->style = NULL; } + if (strlen(authctxt->role) == 0) { + free(authctxt->role); + authctxt->role = NULL; + } + + return (0); +} + +int +mm_answer_authrole(struct ssh *ssh, int sock, struct sshbuf *m) +{ + int r; + + monitor_permit_authentications(1); + + if ((r = sshbuf_get_cstring(m, &authctxt->role, NULL)) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + debug3("%s: role=%s", + __func__, authctxt->role); + + if (strlen(authctxt->role) == 0) { + free(authctxt->role); + authctxt->role = NULL; + } + return (0); } @@ -1528,7 +1557,7 @@ mm_answer_pty(struct ssh *ssh, int sock, struct sshbuf *m) res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); if (res == 0) goto error; - pty_setowner(authctxt->pw, s->tty); + pty_setowner(authctxt->pw, s->tty, authctxt->role); if ((r = sshbuf_put_u32(m, 1)) != 0 || (r = sshbuf_put_cstring(m, s->tty)) != 0) diff --git a/monitor.h b/monitor.h index 2b1a2d590..4d87284aa 100644 --- a/monitor.h +++ b/monitor.h @@ -65,6 +65,8 @@ enum monitor_reqtype { MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151, MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153, + + MONITOR_REQ_AUTHROLE = 154, }; struct ssh; diff --git a/monitor_wrap.c b/monitor_wrap.c index 8e4c1c1f8..6b3a6251c 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -364,10 +364,10 @@ mm_auth2_read_banner(void) return (banner); } -/* Inform the privileged process about service and style */ +/* Inform the privileged process about service, style, and role */ void -mm_inform_authserv(char *service, char *style) +mm_inform_authserv(char *service, char *style, char *role) { struct sshbuf *m; int r; @@ -377,7 +377,8 @@ mm_inform_authserv(char *service, char *style) if ((m = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); if ((r = sshbuf_put_cstring(m, service)) != 0 || - (r = sshbuf_put_cstring(m, style ? style : "")) != 0) + (r = sshbuf_put_cstring(m, style ? style : "")) != 0 || + (r = sshbuf_put_cstring(m, role ? role : "")) != 0) fatal("%s: buffer error: %s", __func__, ssh_err(r)); mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, m); @@ -385,6 +386,26 @@ mm_inform_authserv(char *service, char *style) sshbuf_free(m); } +/* Inform the privileged process about role */ + +void +mm_inform_authrole(char *role) +{ + struct sshbuf *m; + int r; + + debug3("%s entering", __func__); + + if ((m = sshbuf_new()) == NULL) + fatal("%s: sshbuf_new failed", __func__); + if ((r = sshbuf_put_cstring(m, role ? role : "")) != 0) + fatal("%s: buffer error: %s", __func__, ssh_err(r)); + + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, m); + + sshbuf_free(m); +} + /* Do the password authentication */ int mm_auth_password(struct ssh *ssh, char *password) diff --git a/monitor_wrap.h b/monitor_wrap.h index 69164a8c0..3d0e32d48 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h @@ -44,7 +44,8 @@ int mm_is_monitor(void); DH *mm_choose_dh(int, int, int); int mm_sshkey_sign(struct ssh *, struct sshkey *, u_char **, size_t *, const u_char *, size_t, const char *, u_int compat); -void mm_inform_authserv(char *, char *); +void mm_inform_authserv(char *, char *, char *); +void mm_inform_authrole(char *); struct passwd *mm_getpwnamallow(struct ssh *, const char *); char *mm_auth2_read_banner(void); int mm_auth_password(struct ssh *, char *); diff --git a/openbsd-compat/port-linux.c b/openbsd-compat/port-linux.c index 622988822..3e6e07670 100644 --- a/openbsd-compat/port-linux.c +++ b/openbsd-compat/port-linux.c @@ -56,7 +56,7 @@ ssh_selinux_enabled(void) /* Return the default security context for the given username */ static security_context_t -ssh_selinux_getctxbyname(char *pwname) +ssh_selinux_getctxbyname(char *pwname, const char *role) { security_context_t sc = NULL; char *sename = NULL, *lvl = NULL; @@ -71,9 +71,16 @@ ssh_selinux_getctxbyname(char *pwname) #endif #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL - r = get_default_context_with_level(sename, lvl, NULL, &sc); + if (role != NULL && role[0]) + r = get_default_context_with_rolelevel(sename, role, lvl, NULL, + &sc); + else + r = get_default_context_with_level(sename, lvl, NULL, &sc); #else - r = get_default_context(sename, NULL, &sc); + if (role != NULL && role[0]) + r = get_default_context_with_role(sename, role, NULL, &sc); + else + r = get_default_context(sename, NULL, &sc); #endif if (r != 0) { @@ -103,7 +110,7 @@ ssh_selinux_getctxbyname(char *pwname) /* Set the execution context to the default for the specified user */ void -ssh_selinux_setup_exec_context(char *pwname) +ssh_selinux_setup_exec_context(char *pwname, const char *role) { security_context_t user_ctx = NULL; @@ -112,7 +119,7 @@ ssh_selinux_setup_exec_context(char *pwname) debug3("%s: setting execution context", __func__); - user_ctx = ssh_selinux_getctxbyname(pwname); + user_ctx = ssh_selinux_getctxbyname(pwname, role); if (setexeccon(user_ctx) != 0) { switch (security_getenforce()) { case -1: @@ -134,7 +141,7 @@ ssh_selinux_setup_exec_context(char *pwname) /* Set the TTY context for the specified user */ void -ssh_selinux_setup_pty(char *pwname, const char *tty) +ssh_selinux_setup_pty(char *pwname, const char *tty, const char *role) { security_context_t new_tty_ctx = NULL; security_context_t user_ctx = NULL; @@ -146,7 +153,7 @@ ssh_selinux_setup_pty(char *pwname, const char *tty) debug3("%s: setting TTY context on %s", __func__, tty); - user_ctx = ssh_selinux_getctxbyname(pwname); + user_ctx = ssh_selinux_getctxbyname(pwname, role); /* XXX: should these calls fatal() upon failure in enforcing mode? */ diff --git a/openbsd-compat/port-linux.h b/openbsd-compat/port-linux.h index 3c22a854d..c88129428 100644 --- a/openbsd-compat/port-linux.h +++ b/openbsd-compat/port-linux.h @@ -19,8 +19,8 @@ #ifdef WITH_SELINUX int ssh_selinux_enabled(void); -void ssh_selinux_setup_pty(char *, const char *); -void ssh_selinux_setup_exec_context(char *); +void ssh_selinux_setup_pty(char *, const char *, const char *); +void ssh_selinux_setup_exec_context(char *, const char *); void ssh_selinux_change_context(const char *); void ssh_selinux_setfscreatecon(const char *); #endif diff --git a/platform.c b/platform.c index 41acc9370..35654ea51 100644 --- a/platform.c +++ b/platform.c @@ -142,7 +142,7 @@ platform_setusercontext(struct passwd *pw) * called if sshd is running as root. */ void -platform_setusercontext_post_groups(struct passwd *pw) +platform_setusercontext_post_groups(struct passwd *pw, const char *role) { #if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM) /* @@ -183,7 +183,7 @@ platform_setusercontext_post_groups(struct passwd *pw) } #endif /* HAVE_SETPCRED */ #ifdef WITH_SELINUX - ssh_selinux_setup_exec_context(pw->pw_name); + ssh_selinux_setup_exec_context(pw->pw_name, role); #endif } diff --git a/platform.h b/platform.h index ea4f9c584..60d72ffe7 100644 --- a/platform.h +++ b/platform.h @@ -25,7 +25,7 @@ void platform_post_fork_parent(pid_t child_pid); void platform_post_fork_child(void); int platform_privileged_uidswap(void); void platform_setusercontext(struct passwd *); -void platform_setusercontext_post_groups(struct passwd *); +void platform_setusercontext_post_groups(struct passwd *, const char *); char *platform_get_krb5_client(const char *); char *platform_krb5_get_principal_name(const char *); int platform_sys_dir_uid(uid_t); diff --git a/session.c b/session.c index ac3d9d19d..d87ea4d44 100644 --- a/session.c +++ b/session.c @@ -1356,7 +1356,7 @@ safely_chroot(const char *path, uid_t uid) /* Set login name, uid, gid, and groups. */ void -do_setusercontext(struct passwd *pw) +do_setusercontext(struct passwd *pw, const char *role) { char uidstr[32], *chroot_path, *tmp; @@ -1384,7 +1384,7 @@ do_setusercontext(struct passwd *pw) endgrent(); #endif - platform_setusercontext_post_groups(pw); + platform_setusercontext_post_groups(pw, role); if (!in_chroot && options.chroot_directory != NULL && strcasecmp(options.chroot_directory, "none") != 0) { @@ -1525,7 +1525,7 @@ do_child(struct ssh *ssh, Session *s, const char *command) /* Force a password change */ if (s->authctxt->force_pwchange) { - do_setusercontext(pw); + do_setusercontext(pw, s->authctxt->role); child_close_fds(ssh); do_pwchange(s); exit(1); @@ -1543,7 +1543,7 @@ do_child(struct ssh *ssh, Session *s, const char *command) /* When PAM is enabled we rely on it to do the nologin check */ if (!options.use_pam) do_nologin(pw); - do_setusercontext(pw); + do_setusercontext(pw, s->authctxt->role); /* * PAM session modules in do_setusercontext may have * generated messages, so if this in an interactive @@ -1942,7 +1942,7 @@ session_pty_req(struct ssh *ssh, Session *s) sshpkt_fatal(ssh, r, "%s: parse packet", __func__); if (!use_privsep) - pty_setowner(s->pw, s->tty); + pty_setowner(s->pw, s->tty, s->authctxt->role); /* Set window size from the packet. */ pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); diff --git a/session.h b/session.h index ce59dabd9..675c91146 100644 --- a/session.h +++ b/session.h @@ -77,7 +77,7 @@ void session_pty_cleanup2(Session *); Session *session_new(void); Session *session_by_tty(char *); void session_close(struct ssh *, Session *); -void do_setusercontext(struct passwd *); +void do_setusercontext(struct passwd *, const char *); const char *session_get_remote_name_or_ip(struct ssh *, u_int, int); diff --git a/sshd.c b/sshd.c index 46870d3b5..e3e96426e 100644 --- a/sshd.c +++ b/sshd.c @@ -594,7 +594,7 @@ privsep_postauth(struct ssh *ssh, Authctxt *authctxt) reseed_prngs(); /* Drop privileges */ - do_setusercontext(authctxt->pw); + do_setusercontext(authctxt->pw, authctxt->role); skip: /* It is safe now to apply the key state */ diff --git a/sshpty.c b/sshpty.c index 4da84d05f..676ade50e 100644 --- a/sshpty.c +++ b/sshpty.c @@ -162,7 +162,7 @@ pty_change_window_size(int ptyfd, u_int row, u_int col, } void -pty_setowner(struct passwd *pw, const char *tty) +pty_setowner(struct passwd *pw, const char *tty, const char *role) { struct group *grp; gid_t gid; @@ -184,7 +184,7 @@ pty_setowner(struct passwd *pw, const char *tty) strerror(errno)); #ifdef WITH_SELINUX - ssh_selinux_setup_pty(pw->pw_name, tty); + ssh_selinux_setup_pty(pw->pw_name, tty, role); #endif if (st.st_uid != pw->pw_uid || st.st_gid != gid) { diff --git a/sshpty.h b/sshpty.h index 9ec7e9a15..de7e000ae 100644 --- a/sshpty.h +++ b/sshpty.h @@ -24,5 +24,5 @@ int pty_allocate(int *, int *, char *, size_t); void pty_release(const char *); void pty_make_controlling_tty(int *, const char *); void pty_change_window_size(int, u_int, u_int, u_int, u_int); -void pty_setowner(struct passwd *, const char *); +void pty_setowner(struct passwd *, const char *, const char *); void disconnect_controlling_tty(void); -- cgit v1.2.3 From 13a16baaf467fae5d507cdb17e3bc753639bca4f Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Sun, 9 Feb 2014 16:10:01 +0000 Subject: Force use of DNSSEC even if "options edns0" isn't in resolv.conf This allows SSHFP DNS records to be verified if glibc 2.11 is installed. Origin: vendor, https://cvs.fedoraproject.org/viewvc/F-12/openssh/openssh-5.2p1-edns.patch?revision=1.1&view=markup Bug: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=572049 Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=572049 Last-Update: 2010-04-06 Patch-Name: dnssec-sshfp.patch --- dns.c | 14 +++++++++++++- openbsd-compat/getrrsetbyname.c | 10 +++++----- openbsd-compat/getrrsetbyname.h | 3 +++ 3 files changed, 21 insertions(+), 6 deletions(-) (limited to 'openbsd-compat') diff --git a/dns.c b/dns.c index ff1a2c41c..82ec97199 100644 --- a/dns.c +++ b/dns.c @@ -211,6 +211,7 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, { u_int counter; int result; + unsigned int rrset_flags = 0; struct rrsetinfo *fingerprints = NULL; u_int8_t hostkey_algorithm; @@ -234,8 +235,19 @@ verify_host_key_dns(const char *hostname, struct sockaddr *address, return -1; } + /* + * Original getrrsetbyname function, found on OpenBSD for example, + * doesn't accept any flag and prerequisite for obtaining AD bit in + * DNS response is set by "options edns0" in resolv.conf. + * + * Our version is more clever and use RRSET_FORCE_EDNS0 flag. + */ +#ifndef HAVE_GETRRSETBYNAME + rrset_flags |= RRSET_FORCE_EDNS0; +#endif result = getrrsetbyname(hostname, DNS_RDATACLASS_IN, - DNS_RDATATYPE_SSHFP, 0, &fingerprints); + DNS_RDATATYPE_SSHFP, rrset_flags, &fingerprints); + if (result) { verbose("DNS lookup error: %s", dns_result_totext(result)); return -1; diff --git a/openbsd-compat/getrrsetbyname.c b/openbsd-compat/getrrsetbyname.c index dc6fe0533..e061a290a 100644 --- a/openbsd-compat/getrrsetbyname.c +++ b/openbsd-compat/getrrsetbyname.c @@ -209,8 +209,8 @@ getrrsetbyname(const char *hostname, unsigned int rdclass, goto fail; } - /* don't allow flags yet, unimplemented */ - if (flags) { + /* Allow RRSET_FORCE_EDNS0 flag only. */ + if ((flags & !RRSET_FORCE_EDNS0) != 0) { result = ERRSET_INVAL; goto fail; } @@ -226,9 +226,9 @@ getrrsetbyname(const char *hostname, unsigned int rdclass, #endif /* DEBUG */ #ifdef RES_USE_DNSSEC - /* turn on DNSSEC if EDNS0 is configured */ - if (_resp->options & RES_USE_EDNS0) - _resp->options |= RES_USE_DNSSEC; + /* turn on DNSSEC if required */ + if (flags & RRSET_FORCE_EDNS0) + _resp->options |= (RES_USE_EDNS0|RES_USE_DNSSEC); #endif /* RES_USE_DNSEC */ /* make query */ diff --git a/openbsd-compat/getrrsetbyname.h b/openbsd-compat/getrrsetbyname.h index 1283f5506..dbbc85a2a 100644 --- a/openbsd-compat/getrrsetbyname.h +++ b/openbsd-compat/getrrsetbyname.h @@ -72,6 +72,9 @@ #ifndef RRSET_VALIDATED # define RRSET_VALIDATED 1 #endif +#ifndef RRSET_FORCE_EDNS0 +# define RRSET_FORCE_EDNS0 0x0001 +#endif /* * Return codes for getrrsetbyname() -- cgit v1.2.3 From 1f61e987ccec2a2af15044196c1a6730959ead98 Mon Sep 17 00:00:00 2001 From: Kurt Roeckx Date: Sun, 9 Feb 2014 16:10:14 +0000 Subject: Don't check the status field of the OpenSSL version There is no reason to check the version of OpenSSL (in Debian). If it's not compatible the soname will change. OpenSSH seems to want to do a check for the soname based on the version number, but wants to keep the status of the release the same. Remove that check on the status since it doesn't tell you anything about how compatible that version is. Author: Colin Watson Bug-Debian: https://bugs.debian.org/93581 Bug-Debian: https://bugs.debian.org/664383 Bug-Debian: https://bugs.debian.org/732940 Forwarded: not-needed Last-Update: 2014-10-07 Patch-Name: no-openssl-version-status.patch --- openbsd-compat/openssl-compat.c | 6 +++--- openbsd-compat/regress/opensslvertest.c | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'openbsd-compat') diff --git a/openbsd-compat/openssl-compat.c b/openbsd-compat/openssl-compat.c index a37ca61bf..c1749210d 100644 --- a/openbsd-compat/openssl-compat.c +++ b/openbsd-compat/openssl-compat.c @@ -34,7 +34,7 @@ /* * OpenSSL version numbers: MNNFFPPS: major minor fix patch status * We match major, minor, fix and status (not patch) for <1.0.0. - * After that, we acceptable compatible fix versions (so we + * After that, we accept compatible fix and status versions (so we * allow 1.0.1 to work with 1.0.0). Going backwards is only allowed * within a patch series. */ @@ -55,10 +55,10 @@ ssh_compatible_openssl(long headerver, long libver) } /* - * For versions >= 1.0.0, major,minor,status must match and library + * For versions >= 1.0.0, major,minor must match and library * fix version must be equal to or newer than the header. */ - mask = 0xfff0000fL; /* major,minor,status */ + mask = 0xfff00000L; /* major,minor */ hfix = (headerver & 0x000ff000) >> 12; lfix = (libver & 0x000ff000) >> 12; if ( (headerver & mask) == (libver & mask) && lfix >= hfix) diff --git a/openbsd-compat/regress/opensslvertest.c b/openbsd-compat/regress/opensslvertest.c index 5d019b598..58474873d 100644 --- a/openbsd-compat/regress/opensslvertest.c +++ b/openbsd-compat/regress/opensslvertest.c @@ -35,6 +35,7 @@ struct version_test { /* built with 1.0.1b release headers */ { 0x1000101fL, 0x1000101fL, 1},/* exact match */ + { 0x1000101fL, 0x10001010L, 1}, /* different status: ok */ { 0x1000101fL, 0x1000102fL, 1}, /* newer library patch version: ok */ { 0x1000101fL, 0x1000100fL, 1}, /* older library patch version: ok */ { 0x1000101fL, 0x1000201fL, 1}, /* newer library fix version: ok */ -- cgit v1.2.3