From 31b49525168245abe16ad49d7b7f519786b53a38 Mon Sep 17 00:00:00 2001 From: Darren Tucker Date: Mon, 22 Oct 2018 20:05:18 +1100 Subject: Include openssl compatibility. Patch from rosenp at gmail.com via openssh-unix-dev. --- ssh-keysign.c | 1 + 1 file changed, 1 insertion(+) (limited to 'ssh-keysign.c') diff --git a/ssh-keysign.c b/ssh-keysign.c index 744ecb4f9..bcd1508c0 100644 --- a/ssh-keysign.c +++ b/ssh-keysign.c @@ -40,6 +40,7 @@ #include #include #include +#include "openbsd-compat/openssl-compat.h" #endif #include "xmalloc.h" -- 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 'ssh-keysign.c') 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 9e34e0c59ab04514f9de9934a772283f7f372afe Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Fri, 23 Nov 2018 05:08:07 +0000 Subject: upstream: add a ssh_config "Match final" predicate Matches in same pass as "Match canonical" but doesn't require hostname canonicalisation be enabled. bz#2906 ok markus OpenBSD-Commit-ID: fba1dfe9f6e0cabcd0e2b3be13f7a434199beffa --- readconf.c | 44 ++++++++++++++++++++++++++++---------------- readconf.h | 6 +++--- ssh-keysign.c | 5 +++-- ssh.c | 31 ++++++++++++++++++++----------- ssh_config.5 | 26 ++++++++++++++++++++++---- 5 files changed, 76 insertions(+), 36 deletions(-) (limited to 'ssh-keysign.c') diff --git a/readconf.c b/readconf.c index 7850f2f59..7331ef5ad 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.301 2018/11/16 03:26:01 djm Exp $ */ +/* $OpenBSD: readconf.c,v 1.302 2018/11/23 05:08:07 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -133,10 +133,11 @@ static int read_config_file_depth(const char *filename, struct passwd *pw, const char *host, const char *original_host, Options *options, - int flags, int *activep, int depth); + int flags, int *activep, int *want_final_pass, int depth); static int process_config_line_depth(Options *options, struct passwd *pw, const char *host, const char *original_host, char *line, - const char *filename, int linenum, int *activep, int flags, int depth); + const char *filename, int linenum, int *activep, int flags, + int *want_final_pass, int depth); /* Keyword tokens. */ @@ -539,8 +540,8 @@ execute_in_shell(const char *cmd) */ static int match_cfg_line(Options *options, char **condition, struct passwd *pw, - const char *host_arg, const char *original_host, int post_canon, - const char *filename, int linenum) + const char *host_arg, const char *original_host, int final_pass, + int *want_final_pass, const char *filename, int linenum) { char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria; const char *ruser; @@ -554,7 +555,7 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, */ port = options->port <= 0 ? default_ssh_port() : options->port; ruser = options->user == NULL ? pw->pw_name : options->user; - if (post_canon) { + if (final_pass) { host = xstrdup(options->hostname); } else if (options->hostname != NULL) { /* NB. Please keep in sync with ssh.c:main() */ @@ -586,8 +587,16 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw, goto out; } attributes++; - if (strcasecmp(attrib, "canonical") == 0) { - r = !!post_canon; /* force bitmask member to boolean */ + if (strcasecmp(attrib, "canonical") == 0 || + strcasecmp(attrib, "final") == 0) { + /* + * If the config requests "Match final" then remember + * this so we can perform a second pass later. + */ + if (strcasecmp(attrib, "final") == 0 && + want_final_pass != NULL) + *want_final_pass = 1; + r = !!final_pass; /* force bitmask member to boolean */ if (r == (negate ? 1 : 0)) this_result = result = 0; debug3("%.200s line %d: %smatched '%s'", @@ -824,14 +833,14 @@ process_config_line(Options *options, struct passwd *pw, const char *host, int linenum, int *activep, int flags) { return process_config_line_depth(options, pw, host, original_host, - line, filename, linenum, activep, flags, 0); + line, filename, linenum, activep, flags, NULL, 0); } #define WHITESPACE " \t\r\n" static int process_config_line_depth(Options *options, struct passwd *pw, const char *host, const char *original_host, char *line, const char *filename, - int linenum, int *activep, int flags, int depth) + int linenum, int *activep, int flags, int *want_final_pass, int depth) { char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; char **cpptr, fwdarg[256]; @@ -1339,7 +1348,8 @@ parse_keytypes: fatal("Host directive not supported as a command-line " "option"); value = match_cfg_line(options, &s, pw, host, original_host, - flags & SSHCONF_POSTCANON, filename, linenum); + flags & SSHCONF_FINAL, want_final_pass, + filename, linenum); if (value < 0) fatal("%.200s line %d: Bad Match condition", filename, linenum); @@ -1548,7 +1558,7 @@ parse_keytypes: pw, host, original_host, options, flags | SSHCONF_CHECKPERM | (oactive ? 0 : SSHCONF_NEVERMATCH), - activep, depth + 1); + activep, want_final_pass, depth + 1); if (r != 1 && errno != ENOENT) { fatal("Can't open user config file " "%.100s: %.100s", gl.gl_pathv[i], @@ -1751,19 +1761,20 @@ parse_keytypes: */ int read_config_file(const char *filename, struct passwd *pw, const char *host, - const char *original_host, Options *options, int flags) + const char *original_host, Options *options, int flags, + int *want_final_pass) { int active = 1; return read_config_file_depth(filename, pw, host, original_host, - options, flags, &active, 0); + options, flags, &active, want_final_pass, 0); } #define READCONF_MAX_DEPTH 16 static int read_config_file_depth(const char *filename, struct passwd *pw, const char *host, const char *original_host, Options *options, - int flags, int *activep, int depth) + int flags, int *activep, int *want_final_pass, int depth) { FILE *f; char *line = NULL; @@ -1798,7 +1809,8 @@ read_config_file_depth(const char *filename, struct passwd *pw, /* Update line number counter. */ linenum++; if (process_config_line_depth(options, pw, host, original_host, - line, filename, linenum, activep, flags, depth) != 0) + line, filename, linenum, activep, flags, want_final_pass, + depth) != 0) bad_options++; } free(line); diff --git a/readconf.h b/readconf.h index fc7e38251..8e36bf32a 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.128 2018/09/20 03:30:44 djm Exp $ */ +/* $OpenBSD: readconf.h,v 1.129 2018/11/23 05:08:07 djm Exp $ */ /* * Author: Tatu Ylonen @@ -185,7 +185,7 @@ typedef struct { #define SSHCONF_CHECKPERM 1 /* check permissions on config file */ #define SSHCONF_USERCONF 2 /* user provided config file not system */ -#define SSHCONF_POSTCANON 4 /* After hostname canonicalisation */ +#define SSHCONF_FINAL 4 /* Final pass over config, after canon. */ #define SSHCONF_NEVERMATCH 8 /* Match/Host never matches; internal only */ #define SSH_UPDATE_HOSTKEYS_NO 0 @@ -203,7 +203,7 @@ void fill_default_options_for_canonicalization(Options *); int process_config_line(Options *, struct passwd *, const char *, const char *, char *, const char *, int, int *, int); int read_config_file(const char *, struct passwd *, const char *, - const char *, Options *, int); + const char *, Options *, int, int *); int parse_forward(struct Forward *, const char *, int, int); int parse_jump(const char *, Options *, int); int parse_ssh_uri(const char *, char **, char **, int *); diff --git a/ssh-keysign.c b/ssh-keysign.c index 8f487b8c5..7ea5ad0e9 100644 --- a/ssh-keysign.c +++ b/ssh-keysign.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keysign.c,v 1.55 2018/07/27 05:34:42 dtucker Exp $ */ +/* $OpenBSD: ssh-keysign.c,v 1.56 2018/11/23 05:08:07 djm Exp $ */ /* * Copyright (c) 2002 Markus Friedl. All rights reserved. * @@ -208,7 +208,8 @@ main(int argc, char **argv) /* verify that ssh-keysign is enabled by the admin */ initialize_options(&options); - (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "", &options, 0); + (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, "", "", + &options, 0, NULL); fill_default_options(&options); if (options.enable_ssh_keysign != 1) fatal("ssh-keysign not enabled in %s", diff --git a/ssh.c b/ssh.c index 1ac903d16..c6cb7847d 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.495 2018/10/23 05:56:35 djm Exp $ */ +/* $OpenBSD: ssh.c,v 1.496 2018/11/23 05:08:07 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -527,7 +527,8 @@ check_load(int r, const char *path, const char *message) * file if the user specifies a config file on the command line. */ static void -process_config_files(const char *host_name, struct passwd *pw, int post_canon) +process_config_files(const char *host_name, struct passwd *pw, int final_pass, + int *want_final_pass) { char buf[PATH_MAX]; int r; @@ -535,7 +536,8 @@ process_config_files(const char *host_name, struct passwd *pw, int post_canon) if (config != NULL) { if (strcasecmp(config, "none") != 0 && !read_config_file(config, pw, host, host_name, &options, - SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0))) + SSHCONF_USERCONF | (final_pass ? SSHCONF_FINAL : 0), + want_final_pass)) fatal("Can't open user config file %.100s: " "%.100s", config, strerror(errno)); } else { @@ -544,12 +546,12 @@ process_config_files(const char *host_name, struct passwd *pw, int post_canon) if (r > 0 && (size_t)r < sizeof(buf)) (void)read_config_file(buf, pw, host, host_name, &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | - (post_canon ? SSHCONF_POSTCANON : 0)); + (final_pass ? SSHCONF_FINAL : 0), want_final_pass); /* Read systemwide configuration file after user config. */ (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, host, host_name, &options, - post_canon ? SSHCONF_POSTCANON : 0); + final_pass ? SSHCONF_FINAL : 0, want_final_pass); } } @@ -581,7 +583,7 @@ main(int ac, char **av) { struct ssh *ssh = NULL; int i, r, opt, exit_status, use_syslog, direct, timeout_ms; - int was_addr, config_test = 0, opt_terminated = 0; + int was_addr, config_test = 0, opt_terminated = 0, want_final_pass = 0; char *p, *cp, *line, *argv0, buf[PATH_MAX], *logfile; char cname[NI_MAXHOST]; struct stat st; @@ -1089,7 +1091,9 @@ main(int ac, char **av) ); /* Parse the configuration files */ - process_config_files(host_arg, pw, 0); + process_config_files(host_arg, pw, 0, &want_final_pass); + if (want_final_pass) + debug("configuration requests final Match pass"); /* Hostname canonicalisation needs a few options filled. */ fill_default_options_for_canonicalization(&options); @@ -1146,12 +1150,17 @@ main(int ac, char **av) * If canonicalisation is enabled then re-parse the configuration * files as new stanzas may match. */ - if (options.canonicalize_hostname != 0) { - debug("Re-reading configuration after hostname " - "canonicalisation"); + if (options.canonicalize_hostname != 0 && !want_final_pass) { + debug("hostname canonicalisation enabled, " + "will re-parse configuration"); + want_final_pass = 1; + } + + if (want_final_pass) { + debug("re-parsing configuration"); free(options.hostname); options.hostname = xstrdup(host); - process_config_files(host_arg, pw, 1); + process_config_files(host_arg, pw, 1, NULL); /* * Address resolution happens early with canonicalisation * enabled and the port number may have changed since, so diff --git a/ssh_config.5 b/ssh_config.5 index 4d5b01d3e..58a5fa1c8 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -33,8 +33,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.286 2018/10/03 06:38:35 djm Exp $ -.Dd $Mdocdate: October 3 2018 $ +.\" $OpenBSD: ssh_config.5,v 1.287 2018/11/23 05:08:07 djm Exp $ +.Dd $Mdocdate: November 23 2018 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -139,6 +139,7 @@ or the single token which always matches. The available criteria keywords are: .Cm canonical , +.Cm final , .Cm exec , .Cm host , .Cm originalhost , @@ -148,12 +149,15 @@ and The .Cm all criteria must appear alone or immediately after -.Cm canonical . +.Cm canonical +or +.Cm final . Other criteria may be combined arbitrarily. All criteria but .Cm all -and .Cm canonical +and +.Cm final require an argument. Criteria may be negated by prepending an exclamation mark .Pq Sq !\& . @@ -166,6 +170,20 @@ after hostname canonicalization (see the option.) This may be useful to specify conditions that work with canonical host names only. +.Pp +The +.Cm final +keyword requests that the configuration be re-parsed (regardless of whether +.Cm CanonicalizeHostname +is enabled), and matches only during this final pass. +If +.Cm CanonicalizeHostname +is enabled, then +.Cm canonical +and +.Cm final +match during the same pass. +.Pp The .Cm exec keyword executes the specified command under the user's shell. -- cgit v1.2.3 From 9b655dc9c9a353f0a527f0c6c43a5e35653c9503 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Sun, 20 Jan 2019 14:55:27 +1100 Subject: last bits of old packet API / active_state global --- audit-bsm.c | 2 +- audit-linux.c | 4 +--- audit.c | 2 +- audit.h | 4 +++- auth.c | 4 ++-- auth2.c | 6 +++--- monitor.c | 2 +- monitor_wrap.c | 2 +- monitor_wrap.h | 2 +- regress/misc/kexfuzz/kexfuzz.c | 2 -- regress/unittests/kex/test_kex.c | 2 -- session.c | 32 -------------------------------- ssh-keyscan.c | 2 -- ssh-keysign.c | 2 -- sshd.c | 8 ++++---- 15 files changed, 18 insertions(+), 58 deletions(-) (limited to 'ssh-keysign.c') diff --git a/audit-bsm.c b/audit-bsm.c index 1409f69ae..0ba16c72c 100644 --- a/audit-bsm.c +++ b/audit-bsm.c @@ -391,7 +391,7 @@ audit_session_close(struct logininfo *li) } void -audit_event(ssh_audit_event_t event) +audit_event(struct ssh *ssh, ssh_audit_event_t event) { char textbuf[BSM_TEXTBUFSZ]; static int logged_in = 0; diff --git a/audit-linux.c b/audit-linux.c index 136ed76bb..3fcbe5c53 100644 --- a/audit-linux.c +++ b/audit-linux.c @@ -97,10 +97,8 @@ audit_session_close(struct logininfo *li) } void -audit_event(ssh_audit_event_t event) +audit_event(struct ssh *ssh, ssh_audit_event_t event) { - struct ssh *ssh = active_state; /* XXX */ - switch(event) { case SSH_AUTH_SUCCESS: case SSH_CONNECTION_CLOSE: diff --git a/audit.c b/audit.c index 33a04376d..dd2f03558 100644 --- a/audit.c +++ b/audit.c @@ -131,7 +131,7 @@ audit_connection_from(const char *host, int port) * events and what they mean). */ void -audit_event(ssh_audit_event_t event) +audit_event(struct ssh *ssh, ssh_audit_event_t event) { debug("audit event euid %d user %s event %d (%s)", geteuid(), audit_username(), event, audit_event_lookup(event)); diff --git a/audit.h b/audit.h index 0b593666d..38cb5ad31 100644 --- a/audit.h +++ b/audit.h @@ -27,6 +27,8 @@ #include "loginrec.h" +struct ssh; + enum ssh_audit_event_type { SSH_LOGIN_EXCEED_MAXTRIES, SSH_LOGIN_ROOT_DENIED, @@ -46,7 +48,7 @@ enum ssh_audit_event_type { typedef enum ssh_audit_event_type ssh_audit_event_t; void audit_connection_from(const char *, int); -void audit_event(ssh_audit_event_t); +void audit_event(struct ssh *, ssh_audit_event_t); void audit_session_open(struct logininfo *); void audit_session_close(struct logininfo *); void audit_run_command(const char *); diff --git a/auth.c b/auth.c index a4c1dece5..62c58e72f 100644 --- a/auth.c +++ b/auth.c @@ -367,7 +367,7 @@ auth_log(struct ssh *ssh, int authenticated, int partial, #endif #ifdef SSH_AUDIT_EVENTS if (authenticated == 0 && !authctxt->postponed) - audit_event(audit_classify_auth(method)); + audit_event(ssh, audit_classify_auth(method)); #endif } @@ -605,7 +605,7 @@ getpwnamallow(struct ssh *ssh, const char *user) auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); #endif #ifdef SSH_AUDIT_EVENTS - audit_event(SSH_INVALID_USER); + audit_event(ssh, SSH_INVALID_USER); #endif /* SSH_AUDIT_EVENTS */ return (NULL); } diff --git a/auth2.c b/auth2.c index a80b3f872..e43350c36 100644 --- a/auth2.c +++ b/auth2.c @@ -294,7 +294,7 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh) /* Invalid user, fake password information */ authctxt->pw = fakepw(); #ifdef SSH_AUDIT_EVENTS - PRIVSEP(audit_event(SSH_INVALID_USER)); + PRIVSEP(audit_event(ssh, SSH_INVALID_USER)); #endif } #ifdef USE_PAM @@ -369,7 +369,7 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method, !auth_root_allowed(ssh, method)) { authenticated = 0; #ifdef SSH_AUDIT_EVENTS - PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED)); + PRIVSEP(audit_event(ssh, SSH_LOGIN_ROOT_DENIED)); #endif } @@ -430,7 +430,7 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *method, authctxt->failures++; if (authctxt->failures >= options.max_authtries) { #ifdef SSH_AUDIT_EVENTS - PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES)); + PRIVSEP(audit_event(ssh, SSH_LOGIN_EXCEED_MAXTRIES)); #endif auth_maxtries_exceeded(ssh); } diff --git a/monitor.c b/monitor.c index 5fa30b2a8..a9546dad2 100644 --- a/monitor.c +++ b/monitor.c @@ -1628,7 +1628,7 @@ mm_answer_audit_event(struct ssh *ssh, int socket, struct sshbuf *m) case SSH_LOGIN_ROOT_DENIED: case SSH_CONNECTION_CLOSE: case SSH_INVALID_USER: - audit_event(event); + audit_event(ssh, event); break; default: fatal("Audit event type %d not permitted", event); diff --git a/monitor_wrap.c b/monitor_wrap.c index f52b9c88c..9e3c7cd17 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -867,7 +867,7 @@ mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses) #ifdef SSH_AUDIT_EVENTS void -mm_audit_event(ssh_audit_event_t event) +mm_audit_event(struct ssh *ssh, ssh_audit_event_t event) { struct sshbuf *m; int r; diff --git a/monitor_wrap.h b/monitor_wrap.h index c7e0c91dd..fdebb3aa4 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h @@ -76,7 +76,7 @@ void mm_sshpam_free_ctx(void *); #ifdef SSH_AUDIT_EVENTS #include "audit.h" -void mm_audit_event(ssh_audit_event_t); +void mm_audit_event(struct ssh *, ssh_audit_event_t); void mm_audit_run_command(const char *); #endif diff --git a/regress/misc/kexfuzz/kexfuzz.c b/regress/misc/kexfuzz/kexfuzz.c index 3e2c48160..61cae042f 100644 --- a/regress/misc/kexfuzz/kexfuzz.c +++ b/regress/misc/kexfuzz/kexfuzz.c @@ -29,8 +29,6 @@ #include "authfile.h" #include "log.h" -struct ssh *active_state = NULL; /* XXX - needed for linking */ - void kex_tests(void); static int do_debug = 0; diff --git a/regress/unittests/kex/test_kex.c b/regress/unittests/kex/test_kex.c index 90f1ebf45..112bc5499 100644 --- a/regress/unittests/kex/test_kex.c +++ b/regress/unittests/kex/test_kex.c @@ -24,8 +24,6 @@ #include "packet.h" #include "myproposal.h" -struct ssh *active_state = NULL; /* XXX - needed for linking */ - void kex_tests(void); static int do_debug = 0; diff --git a/session.c b/session.c index b5a382473..4862e5d63 100644 --- a/session.c +++ b/session.c @@ -123,9 +123,6 @@ int do_exec_no_pty(struct ssh *, Session *, const char *); int do_exec(struct ssh *, Session *, const char *); void do_login(struct ssh *, Session *, const char *); void do_child(struct ssh *, Session *, const char *); -#ifdef LOGIN_NEEDS_UTMPX -static void do_pre_login(Session *s); -#endif void do_motd(void); int check_quietlogin(Session *, const char *); @@ -656,35 +653,6 @@ do_exec_pty(struct ssh *ssh, Session *s, const char *command) return 0; } -#ifdef LOGIN_NEEDS_UTMPX -static void -do_pre_login(Session *s) -{ - struct ssh *ssh = active_state; /* XXX */ - socklen_t fromlen; - struct sockaddr_storage from; - pid_t pid = getpid(); - - /* - * Get IP address of client. If the connection is not a socket, let - * the address be 0.0.0.0. - */ - memset(&from, 0, sizeof(from)); - fromlen = sizeof(from); - if (packet_connection_is_on_socket()) { - if (getpeername(packet_get_connection_in(), - (struct sockaddr *)&from, &fromlen) < 0) { - debug("getpeername: %.100s", strerror(errno)); - cleanup_exit(255); - } - } - - record_utmp_only(pid, s->tty, s->pw->pw_name, - session_get_remote_name_or_ip(ssh, utmp_len, options.use_dns), - (struct sockaddr *)&from, fromlen); -} -#endif - /* * This is called to fork and execute a command. If another command is * to be forced, execute that instead. diff --git a/ssh-keyscan.c b/ssh-keyscan.c index 38b1c548b..88449f672 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -83,8 +83,6 @@ fd_set *read_wait; size_t read_wait_nfdset; int ncon; -struct ssh *active_state = NULL; /* XXX needed for linking */ - /* * Keep a connection structure for each file descriptor. The state * associated with file descriptor n is held in fdcon[n]. diff --git a/ssh-keysign.c b/ssh-keysign.c index 7ea5ad0e9..601f6ca72 100644 --- a/ssh-keysign.c +++ b/ssh-keysign.c @@ -59,8 +59,6 @@ #include "sshkey.h" #include "ssherr.h" -struct ssh *active_state = NULL; /* XXX needed for linking */ - extern char *__progname; static int diff --git a/sshd.c b/sshd.c index 58d17e546..f6927672e 100644 --- a/sshd.c +++ b/sshd.c @@ -2080,7 +2080,7 @@ main(int ac, char **av) } #ifdef SSH_AUDIT_EVENTS - audit_event(SSH_AUTH_SUCCESS); + audit_event(ssh, SSH_AUTH_SUCCESS); #endif #ifdef GSSAPI @@ -2128,7 +2128,7 @@ main(int ac, char **av) #endif /* USE_PAM */ #ifdef SSH_AUDIT_EVENTS - PRIVSEP(audit_event(SSH_CONNECTION_CLOSE)); + PRIVSEP(audit_event(ssh, SSH_CONNECTION_CLOSE)); #endif ssh_packet_close(ssh); @@ -2256,8 +2256,8 @@ cleanup_exit(int i) } #ifdef SSH_AUDIT_EVENTS /* done after do_cleanup so it can cancel the PAM auth 'thread' */ - if (!use_privsep || mm_is_monitor()) - audit_event(SSH_CONNECTION_ABANDON); + if (the_active_state != NULL && (!use_privsep || mm_is_monitor())) + audit_event(the_active_state, SSH_CONNECTION_ABANDON); #endif _exit(i); } -- cgit v1.2.3