From 960e7c672dc106f3b759c081de3edb4d1138b36e Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Fri, 9 Nov 2018 02:57:58 +0000 Subject: upstream: typo in error message; caught by Debian lintian, via Colin Watson OpenBSD-Commit-ID: bff614c7bd1f4ca491a84e9b5999f848d0d66758 --- ssh-agent.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ssh-agent.c') diff --git a/ssh-agent.c b/ssh-agent.c index d8a8260f9..cb552462a 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.231 2018/05/11 03:38:51 djm Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.232 2018/11/09 02:57:58 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1199,7 +1199,7 @@ main(int ac, char **av) */ #define SSH_AGENT_MIN_FDS (3+1+1+1+4) if (rlim.rlim_cur < SSH_AGENT_MIN_FDS) - fatal("%s: file descriptior rlimit %lld too low (minimum %u)", + fatal("%s: file descriptor rlimit %lld too low (minimum %u)", __progname, (long long)rlim.rlim_cur, SSH_AGENT_MIN_FDS); maxfds = rlim.rlim_cur - SSH_AGENT_MIN_FDS; -- 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-agent.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 d691588b8e29622c66abf8932362b522cf7f4051 Mon Sep 17 00:00:00 2001 From: "djm@openbsd.org" Date: Tue, 22 Jan 2019 22:58:50 +0000 Subject: upstream: backoff reading messages from active connections when the input buffer is too full to read one, or if the output buffer is too full to enqueue a response; feedback & ok dtucker@ OpenBSD-Commit-ID: df3c5b6d57c968975875de40d8955cbfed05a6c8 --- ssh-agent.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'ssh-agent.c') diff --git a/ssh-agent.c b/ssh-agent.c index 6baebc313..d06ecfd98 100644 --- a/ssh-agent.c +++ b/ssh-agent.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.232 2018/11/09 02:57:58 djm Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.233 2019/01/22 22:58:50 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -96,6 +96,8 @@ /* Maximum accepted message length */ #define AGENT_MAX_LEN (256*1024) +/* Maximum bytes to read from client socket */ +#define AGENT_RBUF_LEN (4096) typedef enum { AUTH_UNUSED, @@ -839,7 +841,7 @@ handle_socket_read(u_int socknum) static int handle_conn_read(u_int socknum) { - char buf[1024]; + char buf[AGENT_RBUF_LEN]; ssize_t len; int r; @@ -946,6 +948,7 @@ prepare_poll(struct pollfd **pfdp, size_t *npfdp, int *timeoutp, u_int maxfds) struct pollfd *pfd = *pfdp; size_t i, j, npfd = 0; time_t deadline; + int r; /* Count active sockets */ for (i = 0; i < sockets_alloc; i++) { @@ -983,8 +986,19 @@ prepare_poll(struct pollfd **pfdp, size_t *npfdp, int *timeoutp, u_int maxfds) case AUTH_CONNECTION: pfd[j].fd = sockets[i].fd; pfd[j].revents = 0; - /* XXX backoff when input buffer full */ - pfd[j].events = POLLIN; + /* + * Only prepare to read if we can handle a full-size + * input read buffer and enqueue a max size reply.. + */ + if ((r = sshbuf_check_reserve(sockets[i].input, + AGENT_RBUF_LEN)) == 0 && + (r = sshbuf_check_reserve(sockets[i].output, + AGENT_MAX_LEN)) == 0) + pfd[j].events = POLLIN; + else if (r != SSH_ERR_NO_BUFFER_SPACE) { + fatal("%s: buffer error: %s", + __func__, ssh_err(r)); + } if (sshbuf_len(sockets[i].output) > 0) pfd[j].events |= POLLOUT; j++; -- cgit v1.2.3