From c2faa4a504188d8fdf27467fca136f69e451fc27 Mon Sep 17 00:00:00 2001 From: Ben Lindstrom Date: Sat, 9 Nov 2002 15:50:03 +0000 Subject: - markus@cvs.openbsd.org 2002/11/07 16:28:47 [sshd.c] log to stderr if -ie is given, bug #414, prj@po.cwru.edu --- sshd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sshd.c') diff --git a/sshd.c b/sshd.c index f8bd7ce54..8bf1557a2 100644 --- a/sshd.c +++ b/sshd.c @@ -42,7 +42,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.260 2002/09/27 10:42:09 mickey Exp $"); +RCSID("$OpenBSD: sshd.c,v 1.261 2002/11/07 16:28:47 markus Exp $"); #include #include @@ -944,7 +944,7 @@ main(int ac, char **av) SYSLOG_LEVEL_INFO : options.log_level, options.log_facility == SYSLOG_FACILITY_NOT_SET ? SYSLOG_FACILITY_AUTH : options.log_facility, - !inetd_flag); + log_stderr || !inetd_flag); #ifdef _UNICOS /* Cray can define user privs drop all prives now! -- cgit v1.2.3 From a8ed44b79e6dd78d7871b0fb8149951b54662ef5 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Fri, 10 Jan 2003 09:53:12 +1100 Subject: - (djm) Enable new setproctitle emulation for Linux, AIX and HP/UX. More systems may be added later. --- ChangeLog | 6 +- TODO | 4 +- configure.ac | 6 +- openbsd-compat/bsd-misc.c | 12 +- openbsd-compat/setproctitle.c | 288 ++++++++++++++++++++++++++++++++---------- openbsd-compat/setproctitle.h | 3 +- session.c | 11 +- sshd.c | 10 +- 8 files changed, 258 insertions(+), 82 deletions(-) (limited to 'sshd.c') diff --git a/ChangeLog b/ChangeLog index 6b3409317..492eadab3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +20030110 + - (djm) Enable new setproctitle emulation for Linux, AIX and HP/UX. More + systems may be added later. + 20030108 - (djm) Sync openbsd-compat/ with OpenBSD -current - (djm) Avoid redundant xstrdup/xfree in auth2-pam.c. From Solar via markus@ @@ -965,4 +969,4 @@ save auth method before monitor_reset_key_state(); bugzilla bug #284; ok provos@ -$Id: ChangeLog,v 1.2557 2003/01/09 04:09:30 tim Exp $ +$Id: ChangeLog,v 1.2558 2003/01/09 22:53:12 djm Exp $ diff --git a/TODO b/TODO index f667d59d6..d3246144e 100644 --- a/TODO +++ b/TODO @@ -13,7 +13,7 @@ Programming: - Write a test program that calls stat() to search for EGD/PRNGd socket rather than use the (non-portable) "test -S". -- Replacement for setproctitle() - HP-UX support only currently +- More platforms for for setproctitle() emulation (testing needed) - Handle changing passwords for the non-PAM expired password case @@ -133,4 +133,4 @@ PrivSep Issues: - Cygwin + Privsep for Pre-auth only (no fd passing) -$Id: TODO,v 1.51 2002/09/05 06:32:03 djm Exp $ +$Id: TODO,v 1.52 2003/01/09 22:53:12 djm Exp $ diff --git a/configure.ac b/configure.ac index d384f7dd7..e64a0dd83 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.97 2003/01/09 01:22:59 tim Exp $ +# $Id: configure.ac,v 1.98 2003/01/09 22:53:12 djm Exp $ AC_INIT AC_CONFIG_SRCDIR([ssh.c]) @@ -380,7 +380,7 @@ AC_CHECK_HEADERS(bstring.h crypt.h endian.h floatingpoint.h \ netinet/in_systm.h paths.h pty.h readpassphrase.h \ rpc/types.h security/pam_appl.h shadow.h stddef.h stdint.h \ strings.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h \ - sys/mman.h sys/select.h sys/stat.h \ + sys/mman.h sys/pstat.h sys/select.h sys/stat.h \ sys/stropts.h sys/sysmacros.h sys/time.h \ sys/un.h time.h tmpdir.h ttyent.h usersec.h \ util.h utime.h utmp.h utmpx.h) @@ -598,7 +598,7 @@ AC_CHECK_FUNCS(arc4random b64_ntop bcopy bindresvport_sa \ getaddrinfo getcwd getgrouplist getnameinfo getopt getpeereid\ getrlimit getrusage getttyent glob inet_aton inet_ntoa \ inet_ntop innetgr login_getcapbool md5_crypt memmove \ - mkdtemp mmap ngetaddrinfo openpty ogetaddrinfo readpassphrase \ + mkdtemp mmap ngetaddrinfo openpty ogetaddrinfo pstat readpassphrase \ realpath recvmsg rresvport_af sendmsg setdtablesize setegid \ setenv seteuid setgroups setlogin setproctitle setresgid setreuid \ setrlimit setsid setpcred setvbuf sigaction sigvec snprintf \ diff --git a/openbsd-compat/bsd-misc.c b/openbsd-compat/bsd-misc.c index 1c1e43a52..d7180d424 100644 --- a/openbsd-compat/bsd-misc.c +++ b/openbsd-compat/bsd-misc.c @@ -23,15 +23,20 @@ */ #include "includes.h" +#include "xmalloc.h" -RCSID("$Id: bsd-misc.c,v 1.10 2002/07/08 21:09:41 mouring Exp $"); +RCSID("$Id: bsd-misc.c,v 1.11 2003/01/09 22:53:13 djm Exp $"); +/* + * NB. duplicate __progname in case it is an alias for argv[0] + * Otherwise it may get clobbered by setproctitle() + */ char *get_progname(char *argv0) { #ifdef HAVE___PROGNAME extern char *__progname; - return __progname; + return xstrdup(__progname); #else char *p; @@ -42,7 +47,8 @@ char *get_progname(char *argv0) p = argv0; else p++; - return p; + + return xstrdup(p); #endif } diff --git a/openbsd-compat/setproctitle.c b/openbsd-compat/setproctitle.c index e165dd13c..5439bd07e 100644 --- a/openbsd-compat/setproctitle.c +++ b/openbsd-compat/setproctitle.c @@ -1,102 +1,250 @@ /* - * Modified for OpenSSH by Kevin Steves - * October 2000 + * Based on src/backend/utils/misc/pg_status.c from + * PostgreSQL Database Management System + * + * Portions Copyright (c) 1996-2001, The PostgreSQL Global Development Group + * + * Portions Copyright (c) 1994, The Regents of the University of California + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without a written agreement + * is hereby granted, provided that the above copyright notice and this + * paragraph and the following two paragraphs appear in all copies. + * + * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING + * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS + * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ -/* - * Copyright (c) 1994, 1995 Christopher G. Demetriou - * All rights reserved. +/*-------------------------------------------------------------------- + * ps_status.c + * + * Routines to support changing the ps display of PostgreSQL backends + * to contain some useful information. Mechanism differs wildly across + * platforms. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Christopher G. Demetriou - * for the NetBSD Project. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission + * $Header: /var/cvs/openssh/openbsd-compat/setproctitle.c,v 1.3 2003/01/09 22:53:13 djm Exp $ * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * Copyright 2000 by PostgreSQL Global Development Group + * various details abducted from various places + *-------------------------------------------------------------------- */ -#if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: setproctitle.c,v 1.8 2001/11/06 19:21:40 art Exp $"; -#endif /* LIBC_SCCS and not lint */ - #include "includes.h" #ifndef HAVE_SETPROCTITLE -#define SPT_NONE 0 -#define SPT_PSTAT 1 +#include +#ifdef HAVE_SYS_PSTAT_H +#include /* for HP-UX */ +#endif +#ifdef HAVE_PS_STRINGS +#include /* for old BSD */ +#include +#endif + +extern char **environ; -#ifndef SPT_TYPE -#define SPT_TYPE SPT_NONE +/*------ + * Alternative ways of updating ps display: + * + * PS_USE_PSTAT + * use the pstat(PSTAT_SETCMD, ) + * (HPUX) + * PS_USE_PS_STRINGS + * assign PS_STRINGS->ps_argvstr = "string" + * (some BSD systems) + * PS_USE_CHANGE_ARGV + * assign argv[0] = "string" + * (some other BSD systems) + * PS_USE_CLOBBER_ARGV + * write over the argv and environment area + * (most SysV-like systems) + * PS_USE_NONE + * don't update ps display + * (This is the default, as it is safest.) + */ +#if defined(HAVE_PSTAT) && defined(PSTAT_SETCMD) +#define PS_USE_PSTAT +#elif defined(HAVE_PS_STRINGS) +#define PS_USE_PS_STRINGS +#elif defined(BSD) || defined(__bsdi__) || defined(__hurd__) +#define PS_USE_CHANGE_ARGV +#elif defined(__linux__) || defined(_AIX) +#define PS_USE_CLOBBER_ARGV +#else +#define PS_USE_NONE #endif -#if SPT_TYPE == SPT_PSTAT -#include -#include -#endif /* SPT_TYPE == SPT_PSTAT */ +/* Different systems want the buffer padded differently */ +#if defined(_AIX) || defined(__linux__) || defined(__QNX__) || defined(__svr4__) +#define PS_PADDING '\0' +#else +#define PS_PADDING ' ' +#endif -#define MAX_PROCTITLE 2048 +/* + * argv clobbering uses existing argv space, all other methods need a buffer + */ +#ifndef PS_USE_CLOBBER_ARGV +static char ps_buffer[256]; +static const size_t ps_buffer_size = sizeof(ps_buffer); +#else /* PS_USE_CLOBBER_ARGV */ +static char *ps_buffer; /* will point to argv area */ +static size_t ps_buffer_size; /* space determined at run time */ +#endif /* PS_USE_CLOBBER_ARGV */ + +/* save the original argv[] location here */ +static int save_argc; +static char **save_argv; extern char *__progname; /* - * Set Process Title (SPT) defines. Modeled after sendmail's - * SPT type definition strategy. - * - * SPT_TYPE: - * - * SPT_NONE: Don't set the process title. Default. - * SPT_PSTAT: Use pstat(PSTAT_SETCMD). HP-UX specific. + * Call this to update the ps status display to a fixed prefix plus an + * indication of what you're currently doing passed in the argument. */ - void setproctitle(const char *fmt, ...) { -#if SPT_TYPE != SPT_NONE +#ifdef PS_USE_PSTAT + union pstun pst; +#endif +#ifndef PS_USE_NONE + ssize_t used; va_list ap; - - char buf[MAX_PROCTITLE]; - size_t used; -#if SPT_TYPE == SPT_PSTAT - union pstun pst; -#endif /* SPT_TYPE == SPT_PSTAT */ + /* no ps display if you didn't call save_ps_display_args() */ + if (save_argv == NULL) + return; +#ifdef PS_USE_CLOBBER_ARGV + /* If ps_buffer is a pointer, it might still be null */ + if (ps_buffer == NULL) + return; +#endif /* PS_USE_CLOBBER_ARGV */ + + /* + * Overwrite argv[] to point at appropriate space, if needed + */ +#ifdef PS_USE_CHANGE_ARGV + save_argv[0] = ps_buffer; + save_argv[1] = NULL; +#endif /* PS_USE_CHANGE_ARGV */ + +#ifdef PS_USE_CLOBBER_ARGV + save_argv[1] = NULL; +#endif /* PS_USE_CLOBBER_ARGV */ + + /* + * Make fixed prefix of ps display. + */ va_start(ap, fmt); - if (fmt != NULL) { - used = snprintf(buf, MAX_PROCTITLE, "%s: ", __progname); - if (used >= MAX_PROCTITLE) - used = MAX_PROCTITLE - 1; - (void)vsnprintf(buf + used, MAX_PROCTITLE - used, fmt, ap); - } else - (void)snprintf(buf, MAX_PROCTITLE, "%s", __progname); + if (fmt == NULL) + snprintf(ps_buffer, ps_buffer_size, "%s", __progname); + else { + used = snprintf(ps_buffer, ps_buffer_size, "%s: ", __progname); + if (used == -1 || used >= ps_buffer_size) + used = ps_buffer_size; + vsnprintf(ps_buffer + used, ps_buffer_size - used, fmt, ap); + } va_end(ap); - used = strlen(buf); -#if SPT_TYPE == SPT_PSTAT - pst.pst_command = buf; - pstat(PSTAT_SETCMD, pst, used, 0, 0); -#endif /* SPT_TYPE == SPT_PSTAT */ +#if 0 + error("XXXXXXXXX %s", __progname); + error("XXXXXXXXX %d", ps_buffer_size); + error("XXXXXXXXX %s", ps_buffer); +#endif + +#ifdef PS_USE_PSTAT + pst.pst_command = ps_buffer; + pstat(PSTAT_SETCMD, pst, strlen(ps_buffer), 0, 0); +#endif /* PS_USE_PSTAT */ + +#ifdef PS_USE_PS_STRINGS + PS_STRINGS->ps_nargvstr = 1; + PS_STRINGS->ps_argvstr = ps_buffer; +#endif /* PS_USE_PS_STRINGS */ -#endif /* SPT_TYPE != SPT_NONE */ +#ifdef PS_USE_CLOBBER_ARGV + /* pad unused memory */ + used = strlen(ps_buffer); + memset(ps_buffer + used, PS_PADDING, ps_buffer_size - used); +#endif /* PS_USE_CLOBBER_ARGV */ + +#endif /* PS_USE_NONE */ } + #endif /* HAVE_SETPROCTITLE */ + +/* + * Call this early in startup to save the original argc/argv values. + * + * argv[] will not be overwritten by this routine, but may be overwritten + * during setproctitle. Also, the physical location of the environment + * strings may be moved, so this should be called before any code that + * might try to hang onto a getenv() result. + */ +void +compat_init_setproctitle(int argc, char *argv[]) +{ +#ifdef PS_USE_CLOBBER_ARGV + char *end_of_area = NULL; + char **new_environ; + int i; +#endif + + save_argc = argc; + save_argv = argv; + +#ifdef PS_USE_CLOBBER_ARGV + /* + * If we're going to overwrite the argv area, count the available + * space. Also move the environment to make additional room. + */ + + /* + * check for contiguous argv strings + */ + for (i = 0; i < argc; i++) { + if (i == 0 || end_of_area + 1 == argv[i]) + end_of_area = argv[i] + strlen(argv[i]); + } + + /* probably can't happen? */ + if (end_of_area == NULL) { + ps_buffer = NULL; + ps_buffer_size = 0; + return; + } + + /* + * check for contiguous environ strings following argv + */ + for (i = 0; environ[i] != NULL; i++) { + if (end_of_area + 1 == environ[i]) + end_of_area = environ[i] + strlen(environ[i]); + } + + ps_buffer = argv[0]; + ps_buffer_size = end_of_area - argv[0] - 1; + + /* + * Duplicate and move the environment out of the way + */ + new_environ = malloc(sizeof(char *) * (i + 1)); + for (i = 0; environ[i] != NULL; i++) + new_environ[i] = strdup(environ[i]); + new_environ[i] = NULL; + environ = new_environ; +#endif /* PS_USE_CLOBBER_ARGV */ +} + diff --git a/openbsd-compat/setproctitle.h b/openbsd-compat/setproctitle.h index 8261bd0ee..48d26c6ea 100644 --- a/openbsd-compat/setproctitle.h +++ b/openbsd-compat/setproctitle.h @@ -1,4 +1,4 @@ -/* $Id: setproctitle.h,v 1.2 2001/02/09 01:55:36 djm Exp $ */ +/* $Id: setproctitle.h,v 1.3 2003/01/09 22:53:13 djm Exp $ */ #ifndef _BSD_SETPROCTITLE_H #define _BSD_SETPROCTITLE_H @@ -7,6 +7,7 @@ #ifndef HAVE_SETPROCTITLE void setproctitle(const char *fmt, ...); +void compat_init_setproctitle(int argc, char *argv[]); #endif #endif /* _BSD_SETPROCTITLE_H */ diff --git a/session.c b/session.c index c16cdcc13..812681d0f 100644 --- a/session.c +++ b/session.c @@ -2002,13 +2002,22 @@ session_tty_list(void) { static char buf[1024]; int i; + char *cp; + buf[0] = '\0'; for (i = 0; i < MAX_SESSIONS; i++) { Session *s = &sessions[i]; if (s->used && s->ttyfd != -1) { + + if (strncmp(s->tty, "/dev/", 5) != 0) { + cp = strrchr(s->tty, '/'); + cp = (cp == NULL) ? s->tty : cp + 1; + } else + cp = s->tty + 5; + if (buf[0] != '\0') strlcat(buf, ",", sizeof buf); - strlcat(buf, strrchr(s->tty, '/') + 1, sizeof buf); + strlcat(buf, cp, sizeof buf); } } if (buf[0] == '\0') diff --git a/sshd.c b/sshd.c index 8bf1557a2..8a7ec6b8e 100644 --- a/sshd.c +++ b/sshd.c @@ -827,9 +827,17 @@ main(int ac, char **av) __progname = get_progname(av[0]); init_rng(); - /* Save argv. */ + /* Save argv. Duplicate so setproctitle emulation doesn't clobber it */ saved_argc = ac; saved_argv = av; + saved_argv = xmalloc(sizeof(*saved_argv) * ac); + for (i = 0; i < ac; i++) + saved_argv[i] = xstrdup(av[i]); + +#ifndef HAVE_SETPROCTITLE + /* Prepare for later setproctitle emulation */ + compat_init_setproctitle(ac, av); +#endif /* Initialize configuration options to their default values. */ initialize_server_options(&options); -- cgit v1.2.3 From 180fc5b23682ec39964b70dc3a43f9658b7c4acb Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 24 Feb 2003 11:50:18 +1100 Subject: - (djm) OpenBSD CVS Sync - markus@cvs.openbsd.org 2003/01/27 17:06:31 [sshd.c] more specific error message when /var/empty has wrong permissions; bug #46, map@appgate.com; ok henning@, provos@, stevesk@ --- ChangeLog | 7 ++++++- sshd.c | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'sshd.c') diff --git a/ChangeLog b/ChangeLog index 00a854fc2..7f4f4e766 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,11 @@ dragging a window) - Perform server grab after we have the keyboard and/or pointer to avoid races. + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2003/01/27 17:06:31 + [sshd.c] + more specific error message when /var/empty has wrong permissions; + bug #46, map@appgate.com; ok henning@, provos@, stevesk@ 20030211 - (djm) Cygwin needs libcrypt too. Patch from vinschen@redhat.com @@ -1105,4 +1110,4 @@ save auth method before monitor_reset_key_state(); bugzilla bug #284; ok provos@ -$Id: ChangeLog,v 1.2594 2003/02/24 00:48:22 djm Exp $ +$Id: ChangeLog,v 1.2595 2003/02/24 00:50:18 djm Exp $ diff --git a/sshd.c b/sshd.c index 8a7ec6b8e..ca2d4d1bc 100644 --- a/sshd.c +++ b/sshd.c @@ -42,7 +42,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.261 2002/11/07 16:28:47 markus Exp $"); +RCSID("$OpenBSD: sshd.c,v 1.262 2003/01/27 17:06:31 markus Exp $"); #include #include @@ -1066,8 +1066,8 @@ main(int ac, char **av) #else if (st.st_uid != 0 || (st.st_mode & (S_IWGRP|S_IWOTH)) != 0) #endif - fatal("Bad owner or mode for %s", - _PATH_PRIVSEP_CHROOT_DIR); + fatal("%s must be owned by root and not group or " + "world-writable.", _PATH_PRIVSEP_CHROOT_DIR); } /* Configuration looks good, so exit if in test mode. */ -- cgit v1.2.3 From 8e7fb335235bd6a7f8387a40bf71eaf9798f6f7e Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 24 Feb 2003 12:03:03 +1100 Subject: - markus@cvs.openbsd.org 2003/02/16 17:09:57 [kex.c kexdh.c kexgex.c kex.h sshconnect2.c sshd.c ssh-keyscan.c] split kex into client and server code, no need to link server code into the client; ok provos@ --- ChangeLog | 6 +- kex.c | 23 ++-- kex.h | 23 ++-- kexdh.c | 234 +---------------------------------------- kexdhc.c | 137 ++++++++++++++++++++++++ kexdhs.c | 138 ++++++++++++++++++++++++ kexgex.c | 328 +--------------------------------------------------------- kexgexc.c | 189 +++++++++++++++++++++++++++++++++ kexgexs.c | 186 +++++++++++++++++++++++++++++++++ ssh-keyscan.c | 4 +- sshconnect2.c | 4 +- sshd.c | 8 +- 12 files changed, 697 insertions(+), 583 deletions(-) create mode 100644 kexdhc.c create mode 100644 kexdhs.c create mode 100644 kexgexc.c create mode 100644 kexgexs.c (limited to 'sshd.c') diff --git a/ChangeLog b/ChangeLog index 586c10b5b..2fdcb2782 100644 --- a/ChangeLog +++ b/ChangeLog @@ -63,6 +63,10 @@ - markus@cvs.openbsd.org 2003/02/12 21:39:50 [crc32.c crc32.h] replace crc32.c with a BSD licensed version; noted by David Turner + - markus@cvs.openbsd.org 2003/02/16 17:09:57 + [kex.c kexdh.c kexgex.c kex.h sshconnect2.c sshd.c ssh-keyscan.c] + split kex into client and server code, no need to link + server code into the client; ok provos@ 20030211 - (djm) Cygwin needs libcrypt too. Patch from vinschen@redhat.com @@ -1163,4 +1167,4 @@ save auth method before monitor_reset_key_state(); bugzilla bug #284; ok provos@ -$Id: ChangeLog,v 1.2611 2003/02/24 01:02:12 djm Exp $ +$Id: ChangeLog,v 1.2612 2003/02/24 01:03:03 djm Exp $ diff --git a/kex.c b/kex.c index 0a861fb97..2c1cacfec 100644 --- a/kex.c +++ b/kex.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: kex.c,v 1.53 2003/02/02 10:56:08 markus Exp $"); +RCSID("$OpenBSD: kex.c,v 1.54 2003/02/16 17:09:57 markus Exp $"); #include @@ -44,11 +44,6 @@ RCSID("$OpenBSD: kex.c,v 1.53 2003/02/02 10:56:08 markus Exp $"); #define KEX_COOKIE_LEN 16 -/* Use privilege separation for sshd */ -int use_privsep; -struct monitor *pmonitor; - - /* prototype */ static void kex_kexinit_finish(Kex *); static void kex_choose_conf(Kex *); @@ -237,14 +232,10 @@ kex_kexinit_finish(Kex *kex) kex_choose_conf(kex); - switch (kex->kex_type) { - case DH_GRP1_SHA1: - kexdh(kex); - break; - case DH_GEX_SHA1: - kexgex(kex); - break; - default: + if (kex->kex_type >= 0 && kex->kex_type < KEX_MAX && + kex->kex[kex->kex_type] != NULL) { + (kex->kex[kex->kex_type])(kex); + } else { fatal("Unsupported key exchange %d", kex->kex_type); } } @@ -301,9 +292,9 @@ choose_kex(Kex *k, char *client, char *server) if (k->name == NULL) fatal("no kex alg"); if (strcmp(k->name, KEX_DH1) == 0) { - k->kex_type = DH_GRP1_SHA1; + k->kex_type = KEX_DH_GRP1_SHA1; } else if (strcmp(k->name, KEX_DHGEX) == 0) { - k->kex_type = DH_GEX_SHA1; + k->kex_type = KEX_DH_GEX_SHA1; } else fatal("bad kex alg %s", k->name); } diff --git a/kex.h b/kex.h index 93a529e12..52d442e9a 100644 --- a/kex.h +++ b/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.32 2002/09/09 14:54:14 markus Exp $ */ +/* $OpenBSD: kex.h,v 1.33 2003/02/16 17:09:57 markus Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -55,8 +55,9 @@ enum kex_modes { }; enum kex_exchange { - DH_GRP1_SHA1, - DH_GEX_SHA1 + KEX_DH_GRP1_SHA1, + KEX_DH_GEX_SHA1, + KEX_MAX }; #define KEX_INIT_SENT 0x0001 @@ -112,6 +113,7 @@ struct Kex { int (*verify_host_key)(Key *); Key *(*load_host_key)(int); int (*host_key_index)(Key *); + void (*kex[KEX_MAX])(Kex *); }; Kex *kex_setup(char *[PROPOSAL_MAX]); @@ -121,11 +123,20 @@ void kex_send_kexinit(Kex *); void kex_input_kexinit(int, u_int32_t, void *); void kex_derive_keys(Kex *, u_char *, BIGNUM *); -void kexdh(Kex *); -void kexgex(Kex *); - Newkeys *kex_get_newkeys(int); +void kexdh_client(Kex *); +void kexdh_server(Kex *); +void kexgex_client(Kex *); +void kexgex_server(Kex *); + +u_char * +kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int, + BIGNUM *, BIGNUM *, BIGNUM *); +u_char * +kexgex_hash(char *, char *, char *, int, char *, int, u_char *, int, + int, int, int, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *); + #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) void dump_digest(char *, u_char *, int); #endif diff --git a/kexdh.c b/kexdh.c index 1e91e2550..4bbb7d1db 100644 --- a/kexdh.c +++ b/kexdh.c @@ -23,23 +23,16 @@ */ #include "includes.h" -RCSID("$OpenBSD: kexdh.c,v 1.18 2002/03/18 17:50:31 provos Exp $"); +RCSID("$OpenBSD: kexdh.c,v 1.19 2003/02/16 17:09:57 markus Exp $"); -#include -#include +#include -#include "xmalloc.h" #include "buffer.h" #include "bufaux.h" -#include "key.h" -#include "kex.h" -#include "log.h" -#include "packet.h" -#include "dh.h" #include "ssh2.h" -#include "monitor_wrap.h" +#include "kex.h" -static u_char * +u_char * kex_dh_hash( char *client_version_string, char *server_version_string, @@ -86,222 +79,3 @@ kex_dh_hash( #endif return digest; } - -/* client */ - -static void -kexdh_client(Kex *kex) -{ - BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; - DH *dh; - Key *server_host_key; - u_char *server_host_key_blob = NULL, *signature = NULL; - u_char *kbuf, *hash; - u_int klen, kout, slen, sbloblen; - - /* generate and send 'e', client DH public key */ - dh = dh_new_group1(); - dh_gen_key(dh, kex->we_need * 8); - packet_start(SSH2_MSG_KEXDH_INIT); - packet_put_bignum2(dh->pub_key); - packet_send(); - - debug("sending SSH2_MSG_KEXDH_INIT"); -#ifdef DEBUG_KEXDH - DHparams_print_fp(stderr, dh); - fprintf(stderr, "pub= "); - BN_print_fp(stderr, dh->pub_key); - fprintf(stderr, "\n"); -#endif - - debug("expecting SSH2_MSG_KEXDH_REPLY"); - packet_read_expect(SSH2_MSG_KEXDH_REPLY); - - /* key, cert */ - server_host_key_blob = packet_get_string(&sbloblen); - server_host_key = key_from_blob(server_host_key_blob, sbloblen); - if (server_host_key == NULL) - fatal("cannot decode server_host_key_blob"); - if (server_host_key->type != kex->hostkey_type) - fatal("type mismatch for decoded server_host_key_blob"); - if (kex->verify_host_key == NULL) - fatal("cannot verify server_host_key"); - if (kex->verify_host_key(server_host_key) == -1) - fatal("server_host_key verification failed"); - - /* DH paramter f, server public DH key */ - if ((dh_server_pub = BN_new()) == NULL) - fatal("dh_server_pub == NULL"); - packet_get_bignum2(dh_server_pub); - -#ifdef DEBUG_KEXDH - fprintf(stderr, "dh_server_pub= "); - BN_print_fp(stderr, dh_server_pub); - fprintf(stderr, "\n"); - debug("bits %d", BN_num_bits(dh_server_pub)); -#endif - - /* signed H */ - signature = packet_get_string(&slen); - packet_check_eom(); - - if (!dh_pub_is_valid(dh, dh_server_pub)) - packet_disconnect("bad server public DH value"); - - klen = DH_size(dh); - kbuf = xmalloc(klen); - kout = DH_compute_key(kbuf, dh_server_pub, dh); -#ifdef DEBUG_KEXDH - dump_digest("shared secret", kbuf, kout); -#endif - if ((shared_secret = BN_new()) == NULL) - fatal("kexdh_client: BN_new failed"); - BN_bin2bn(kbuf, kout, shared_secret); - memset(kbuf, 0, klen); - xfree(kbuf); - - /* calc and verify H */ - hash = kex_dh_hash( - kex->client_version_string, - kex->server_version_string, - buffer_ptr(&kex->my), buffer_len(&kex->my), - buffer_ptr(&kex->peer), buffer_len(&kex->peer), - server_host_key_blob, sbloblen, - dh->pub_key, - dh_server_pub, - shared_secret - ); - xfree(server_host_key_blob); - BN_clear_free(dh_server_pub); - DH_free(dh); - - if (key_verify(server_host_key, signature, slen, hash, 20) != 1) - fatal("key_verify failed for server_host_key"); - key_free(server_host_key); - xfree(signature); - - /* save session id */ - if (kex->session_id == NULL) { - kex->session_id_len = 20; - kex->session_id = xmalloc(kex->session_id_len); - memcpy(kex->session_id, hash, kex->session_id_len); - } - - kex_derive_keys(kex, hash, shared_secret); - BN_clear_free(shared_secret); - kex_finish(kex); -} - -/* server */ - -static void -kexdh_server(Kex *kex) -{ - BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; - DH *dh; - Key *server_host_key; - u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; - u_int sbloblen, klen, kout; - u_int slen; - - /* generate server DH public key */ - dh = dh_new_group1(); - dh_gen_key(dh, kex->we_need * 8); - - debug("expecting SSH2_MSG_KEXDH_INIT"); - packet_read_expect(SSH2_MSG_KEXDH_INIT); - - if (kex->load_host_key == NULL) - fatal("Cannot load hostkey"); - server_host_key = kex->load_host_key(kex->hostkey_type); - if (server_host_key == NULL) - fatal("Unsupported hostkey type %d", kex->hostkey_type); - - /* key, cert */ - if ((dh_client_pub = BN_new()) == NULL) - fatal("dh_client_pub == NULL"); - packet_get_bignum2(dh_client_pub); - packet_check_eom(); - -#ifdef DEBUG_KEXDH - fprintf(stderr, "dh_client_pub= "); - BN_print_fp(stderr, dh_client_pub); - fprintf(stderr, "\n"); - debug("bits %d", BN_num_bits(dh_client_pub)); -#endif - -#ifdef DEBUG_KEXDH - DHparams_print_fp(stderr, dh); - fprintf(stderr, "pub= "); - BN_print_fp(stderr, dh->pub_key); - fprintf(stderr, "\n"); -#endif - if (!dh_pub_is_valid(dh, dh_client_pub)) - packet_disconnect("bad client public DH value"); - - klen = DH_size(dh); - kbuf = xmalloc(klen); - kout = DH_compute_key(kbuf, dh_client_pub, dh); -#ifdef DEBUG_KEXDH - dump_digest("shared secret", kbuf, kout); -#endif - if ((shared_secret = BN_new()) == NULL) - fatal("kexdh_server: BN_new failed"); - BN_bin2bn(kbuf, kout, shared_secret); - memset(kbuf, 0, klen); - xfree(kbuf); - - key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); - - /* calc H */ - hash = kex_dh_hash( - kex->client_version_string, - kex->server_version_string, - buffer_ptr(&kex->peer), buffer_len(&kex->peer), - buffer_ptr(&kex->my), buffer_len(&kex->my), - server_host_key_blob, sbloblen, - dh_client_pub, - dh->pub_key, - shared_secret - ); - BN_clear_free(dh_client_pub); - - /* save session id := H */ - /* XXX hashlen depends on KEX */ - if (kex->session_id == NULL) { - kex->session_id_len = 20; - kex->session_id = xmalloc(kex->session_id_len); - memcpy(kex->session_id, hash, kex->session_id_len); - } - - /* sign H */ - /* XXX hashlen depends on KEX */ - PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20)); - - /* destroy_sensitive_data(); */ - - /* send server hostkey, DH pubkey 'f' and singed H */ - packet_start(SSH2_MSG_KEXDH_REPLY); - packet_put_string(server_host_key_blob, sbloblen); - packet_put_bignum2(dh->pub_key); /* f */ - packet_put_string(signature, slen); - packet_send(); - - xfree(signature); - xfree(server_host_key_blob); - /* have keys, free DH */ - DH_free(dh); - - kex_derive_keys(kex, hash, shared_secret); - BN_clear_free(shared_secret); - kex_finish(kex); -} - -void -kexdh(Kex *kex) -{ - if (kex->server) - kexdh_server(kex); - else - kexdh_client(kex); -} diff --git a/kexdhc.c b/kexdhc.c new file mode 100644 index 000000000..fe6dc53f8 --- /dev/null +++ b/kexdhc.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2001 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" +RCSID("$OpenBSD: kexdhc.c,v 1.1 2003/02/16 17:09:57 markus Exp $"); + +#include "xmalloc.h" +#include "key.h" +#include "kex.h" +#include "log.h" +#include "packet.h" +#include "dh.h" +#include "ssh2.h" + +void +kexdh_client(Kex *kex) +{ + BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; + DH *dh; + Key *server_host_key; + u_char *server_host_key_blob = NULL, *signature = NULL; + u_char *kbuf, *hash; + u_int klen, kout, slen, sbloblen; + + /* generate and send 'e', client DH public key */ + dh = dh_new_group1(); + dh_gen_key(dh, kex->we_need * 8); + packet_start(SSH2_MSG_KEXDH_INIT); + packet_put_bignum2(dh->pub_key); + packet_send(); + + debug("sending SSH2_MSG_KEXDH_INIT"); +#ifdef DEBUG_KEXDH + DHparams_print_fp(stderr, dh); + fprintf(stderr, "pub= "); + BN_print_fp(stderr, dh->pub_key); + fprintf(stderr, "\n"); +#endif + + debug("expecting SSH2_MSG_KEXDH_REPLY"); + packet_read_expect(SSH2_MSG_KEXDH_REPLY); + + /* key, cert */ + server_host_key_blob = packet_get_string(&sbloblen); + server_host_key = key_from_blob(server_host_key_blob, sbloblen); + if (server_host_key == NULL) + fatal("cannot decode server_host_key_blob"); + if (server_host_key->type != kex->hostkey_type) + fatal("type mismatch for decoded server_host_key_blob"); + if (kex->verify_host_key == NULL) + fatal("cannot verify server_host_key"); + if (kex->verify_host_key(server_host_key) == -1) + fatal("server_host_key verification failed"); + + /* DH paramter f, server public DH key */ + if ((dh_server_pub = BN_new()) == NULL) + fatal("dh_server_pub == NULL"); + packet_get_bignum2(dh_server_pub); + +#ifdef DEBUG_KEXDH + fprintf(stderr, "dh_server_pub= "); + BN_print_fp(stderr, dh_server_pub); + fprintf(stderr, "\n"); + debug("bits %d", BN_num_bits(dh_server_pub)); +#endif + + /* signed H */ + signature = packet_get_string(&slen); + packet_check_eom(); + + if (!dh_pub_is_valid(dh, dh_server_pub)) + packet_disconnect("bad server public DH value"); + + klen = DH_size(dh); + kbuf = xmalloc(klen); + kout = DH_compute_key(kbuf, dh_server_pub, dh); +#ifdef DEBUG_KEXDH + dump_digest("shared secret", kbuf, kout); +#endif + if ((shared_secret = BN_new()) == NULL) + fatal("kexdh_client: BN_new failed"); + BN_bin2bn(kbuf, kout, shared_secret); + memset(kbuf, 0, klen); + xfree(kbuf); + + /* calc and verify H */ + hash = kex_dh_hash( + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->my), buffer_len(&kex->my), + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + server_host_key_blob, sbloblen, + dh->pub_key, + dh_server_pub, + shared_secret + ); + xfree(server_host_key_blob); + BN_clear_free(dh_server_pub); + DH_free(dh); + + if (key_verify(server_host_key, signature, slen, hash, 20) != 1) + fatal("key_verify failed for server_host_key"); + key_free(server_host_key); + xfree(signature); + + /* save session id */ + if (kex->session_id == NULL) { + kex->session_id_len = 20; + kex->session_id = xmalloc(kex->session_id_len); + memcpy(kex->session_id, hash, kex->session_id_len); + } + + kex_derive_keys(kex, hash, shared_secret); + BN_clear_free(shared_secret); + kex_finish(kex); +} diff --git a/kexdhs.c b/kexdhs.c new file mode 100644 index 000000000..f04bce825 --- /dev/null +++ b/kexdhs.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2001 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" +RCSID("$OpenBSD: kexdhs.c,v 1.1 2003/02/16 17:09:57 markus Exp $"); + +#include "xmalloc.h" +#include "key.h" +#include "kex.h" +#include "log.h" +#include "packet.h" +#include "dh.h" +#include "ssh2.h" +#include "monitor_wrap.h" + +void +kexdh_server(Kex *kex) +{ + BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; + DH *dh; + Key *server_host_key; + u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; + u_int sbloblen, klen, kout; + u_int slen; + + /* generate server DH public key */ + dh = dh_new_group1(); + dh_gen_key(dh, kex->we_need * 8); + + debug("expecting SSH2_MSG_KEXDH_INIT"); + packet_read_expect(SSH2_MSG_KEXDH_INIT); + + if (kex->load_host_key == NULL) + fatal("Cannot load hostkey"); + server_host_key = kex->load_host_key(kex->hostkey_type); + if (server_host_key == NULL) + fatal("Unsupported hostkey type %d", kex->hostkey_type); + + /* key, cert */ + if ((dh_client_pub = BN_new()) == NULL) + fatal("dh_client_pub == NULL"); + packet_get_bignum2(dh_client_pub); + packet_check_eom(); + +#ifdef DEBUG_KEXDH + fprintf(stderr, "dh_client_pub= "); + BN_print_fp(stderr, dh_client_pub); + fprintf(stderr, "\n"); + debug("bits %d", BN_num_bits(dh_client_pub)); +#endif + +#ifdef DEBUG_KEXDH + DHparams_print_fp(stderr, dh); + fprintf(stderr, "pub= "); + BN_print_fp(stderr, dh->pub_key); + fprintf(stderr, "\n"); +#endif + if (!dh_pub_is_valid(dh, dh_client_pub)) + packet_disconnect("bad client public DH value"); + + klen = DH_size(dh); + kbuf = xmalloc(klen); + kout = DH_compute_key(kbuf, dh_client_pub, dh); +#ifdef DEBUG_KEXDH + dump_digest("shared secret", kbuf, kout); +#endif + if ((shared_secret = BN_new()) == NULL) + fatal("kexdh_server: BN_new failed"); + BN_bin2bn(kbuf, kout, shared_secret); + memset(kbuf, 0, klen); + xfree(kbuf); + + key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); + + /* calc H */ + hash = kex_dh_hash( + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + buffer_ptr(&kex->my), buffer_len(&kex->my), + server_host_key_blob, sbloblen, + dh_client_pub, + dh->pub_key, + shared_secret + ); + BN_clear_free(dh_client_pub); + + /* save session id := H */ + /* XXX hashlen depends on KEX */ + if (kex->session_id == NULL) { + kex->session_id_len = 20; + kex->session_id = xmalloc(kex->session_id_len); + memcpy(kex->session_id, hash, kex->session_id_len); + } + + /* sign H */ + /* XXX hashlen depends on KEX */ + PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20)); + + /* destroy_sensitive_data(); */ + + /* send server hostkey, DH pubkey 'f' and singed H */ + packet_start(SSH2_MSG_KEXDH_REPLY); + packet_put_string(server_host_key_blob, sbloblen); + packet_put_bignum2(dh->pub_key); /* f */ + packet_put_string(signature, slen); + packet_send(); + + xfree(signature); + xfree(server_host_key_blob); + /* have keys, free DH */ + DH_free(dh); + + kex_derive_keys(kex, hash, shared_secret); + BN_clear_free(shared_secret); + kex_finish(kex); +} diff --git a/kexgex.c b/kexgex.c index 2d4a58153..b0c39c8cb 100644 --- a/kexgex.c +++ b/kexgex.c @@ -24,23 +24,16 @@ */ #include "includes.h" -RCSID("$OpenBSD: kexgex.c,v 1.22 2002/03/24 17:27:03 stevesk Exp $"); +RCSID("$OpenBSD: kexgex.c,v 1.23 2003/02/16 17:09:57 markus Exp $"); -#include +#include -#include "xmalloc.h" #include "buffer.h" #include "bufaux.h" -#include "key.h" #include "kex.h" -#include "log.h" -#include "packet.h" -#include "dh.h" #include "ssh2.h" -#include "compat.h" -#include "monitor_wrap.h" -static u_char * +u_char * kexgex_hash( char *client_version_string, char *server_version_string, @@ -97,318 +90,3 @@ kexgex_hash( #endif return digest; } - -/* client */ - -static void -kexgex_client(Kex *kex) -{ - BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; - BIGNUM *p = NULL, *g = NULL; - Key *server_host_key; - u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; - u_int klen, kout, slen, sbloblen; - int min, max, nbits; - DH *dh; - - nbits = dh_estimate(kex->we_need * 8); - - if (datafellows & SSH_OLD_DHGEX) { - debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD sent"); - - /* Old GEX request */ - packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD); - packet_put_int(nbits); - min = DH_GRP_MIN; - max = DH_GRP_MAX; - } else { - debug("SSH2_MSG_KEX_DH_GEX_REQUEST sent"); - - /* New GEX request */ - min = DH_GRP_MIN; - max = DH_GRP_MAX; - packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST); - packet_put_int(min); - packet_put_int(nbits); - packet_put_int(max); - } -#ifdef DEBUG_KEXDH - fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n", - min, nbits, max); -#endif - packet_send(); - - debug("expecting SSH2_MSG_KEX_DH_GEX_GROUP"); - packet_read_expect(SSH2_MSG_KEX_DH_GEX_GROUP); - - if ((p = BN_new()) == NULL) - fatal("BN_new"); - packet_get_bignum2(p); - if ((g = BN_new()) == NULL) - fatal("BN_new"); - packet_get_bignum2(g); - packet_check_eom(); - - if (BN_num_bits(p) < min || BN_num_bits(p) > max) - fatal("DH_GEX group out of range: %d !< %d !< %d", - min, BN_num_bits(p), max); - - dh = dh_new_group(g, p); - dh_gen_key(dh, kex->we_need * 8); - -#ifdef DEBUG_KEXDH - DHparams_print_fp(stderr, dh); - fprintf(stderr, "pub= "); - BN_print_fp(stderr, dh->pub_key); - fprintf(stderr, "\n"); -#endif - - debug("SSH2_MSG_KEX_DH_GEX_INIT sent"); - /* generate and send 'e', client DH public key */ - packet_start(SSH2_MSG_KEX_DH_GEX_INIT); - packet_put_bignum2(dh->pub_key); - packet_send(); - - debug("expecting SSH2_MSG_KEX_DH_GEX_REPLY"); - packet_read_expect(SSH2_MSG_KEX_DH_GEX_REPLY); - - /* key, cert */ - server_host_key_blob = packet_get_string(&sbloblen); - server_host_key = key_from_blob(server_host_key_blob, sbloblen); - if (server_host_key == NULL) - fatal("cannot decode server_host_key_blob"); - if (server_host_key->type != kex->hostkey_type) - fatal("type mismatch for decoded server_host_key_blob"); - if (kex->verify_host_key == NULL) - fatal("cannot verify server_host_key"); - if (kex->verify_host_key(server_host_key) == -1) - fatal("server_host_key verification failed"); - - /* DH paramter f, server public DH key */ - if ((dh_server_pub = BN_new()) == NULL) - fatal("dh_server_pub == NULL"); - packet_get_bignum2(dh_server_pub); - -#ifdef DEBUG_KEXDH - fprintf(stderr, "dh_server_pub= "); - BN_print_fp(stderr, dh_server_pub); - fprintf(stderr, "\n"); - debug("bits %d", BN_num_bits(dh_server_pub)); -#endif - - /* signed H */ - signature = packet_get_string(&slen); - packet_check_eom(); - - if (!dh_pub_is_valid(dh, dh_server_pub)) - packet_disconnect("bad server public DH value"); - - klen = DH_size(dh); - kbuf = xmalloc(klen); - kout = DH_compute_key(kbuf, dh_server_pub, dh); -#ifdef DEBUG_KEXDH - dump_digest("shared secret", kbuf, kout); -#endif - if ((shared_secret = BN_new()) == NULL) - fatal("kexgex_client: BN_new failed"); - BN_bin2bn(kbuf, kout, shared_secret); - memset(kbuf, 0, klen); - xfree(kbuf); - - if (datafellows & SSH_OLD_DHGEX) - min = max = -1; - - /* calc and verify H */ - hash = kexgex_hash( - kex->client_version_string, - kex->server_version_string, - buffer_ptr(&kex->my), buffer_len(&kex->my), - buffer_ptr(&kex->peer), buffer_len(&kex->peer), - server_host_key_blob, sbloblen, - min, nbits, max, - dh->p, dh->g, - dh->pub_key, - dh_server_pub, - shared_secret - ); - /* have keys, free DH */ - DH_free(dh); - xfree(server_host_key_blob); - BN_clear_free(dh_server_pub); - - if (key_verify(server_host_key, signature, slen, hash, 20) != 1) - fatal("key_verify failed for server_host_key"); - key_free(server_host_key); - xfree(signature); - - /* save session id */ - if (kex->session_id == NULL) { - kex->session_id_len = 20; - kex->session_id = xmalloc(kex->session_id_len); - memcpy(kex->session_id, hash, kex->session_id_len); - } - kex_derive_keys(kex, hash, shared_secret); - BN_clear_free(shared_secret); - - kex_finish(kex); -} - -/* server */ - -static void -kexgex_server(Kex *kex) -{ - BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; - Key *server_host_key; - DH *dh; - u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; - u_int sbloblen, klen, kout, slen; - int min = -1, max = -1, nbits = -1, type; - - if (kex->load_host_key == NULL) - fatal("Cannot load hostkey"); - server_host_key = kex->load_host_key(kex->hostkey_type); - if (server_host_key == NULL) - fatal("Unsupported hostkey type %d", kex->hostkey_type); - - type = packet_read(); - switch (type) { - case SSH2_MSG_KEX_DH_GEX_REQUEST: - debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); - min = packet_get_int(); - nbits = packet_get_int(); - max = packet_get_int(); - min = MAX(DH_GRP_MIN, min); - max = MIN(DH_GRP_MAX, max); - break; - case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: - debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received"); - nbits = packet_get_int(); - min = DH_GRP_MIN; - max = DH_GRP_MAX; - /* unused for old GEX */ - break; - default: - fatal("protocol error during kex, no DH_GEX_REQUEST: %d", type); - } - packet_check_eom(); - - if (max < min || nbits < min || max < nbits) - fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d", - min, nbits, max); - - /* Contact privileged parent */ - dh = PRIVSEP(choose_dh(min, nbits, max)); - if (dh == NULL) - packet_disconnect("Protocol error: no matching DH grp found"); - - debug("SSH2_MSG_KEX_DH_GEX_GROUP sent"); - packet_start(SSH2_MSG_KEX_DH_GEX_GROUP); - packet_put_bignum2(dh->p); - packet_put_bignum2(dh->g); - packet_send(); - - /* flush */ - packet_write_wait(); - - /* Compute our exchange value in parallel with the client */ - dh_gen_key(dh, kex->we_need * 8); - - debug("expecting SSH2_MSG_KEX_DH_GEX_INIT"); - packet_read_expect(SSH2_MSG_KEX_DH_GEX_INIT); - - /* key, cert */ - if ((dh_client_pub = BN_new()) == NULL) - fatal("dh_client_pub == NULL"); - packet_get_bignum2(dh_client_pub); - packet_check_eom(); - -#ifdef DEBUG_KEXDH - fprintf(stderr, "dh_client_pub= "); - BN_print_fp(stderr, dh_client_pub); - fprintf(stderr, "\n"); - debug("bits %d", BN_num_bits(dh_client_pub)); -#endif - -#ifdef DEBUG_KEXDH - DHparams_print_fp(stderr, dh); - fprintf(stderr, "pub= "); - BN_print_fp(stderr, dh->pub_key); - fprintf(stderr, "\n"); -#endif - if (!dh_pub_is_valid(dh, dh_client_pub)) - packet_disconnect("bad client public DH value"); - - klen = DH_size(dh); - kbuf = xmalloc(klen); - kout = DH_compute_key(kbuf, dh_client_pub, dh); -#ifdef DEBUG_KEXDH - dump_digest("shared secret", kbuf, kout); -#endif - if ((shared_secret = BN_new()) == NULL) - fatal("kexgex_server: BN_new failed"); - BN_bin2bn(kbuf, kout, shared_secret); - memset(kbuf, 0, klen); - xfree(kbuf); - - key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); - - if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD) - min = max = -1; - - /* calc H */ /* XXX depends on 'kex' */ - hash = kexgex_hash( - kex->client_version_string, - kex->server_version_string, - buffer_ptr(&kex->peer), buffer_len(&kex->peer), - buffer_ptr(&kex->my), buffer_len(&kex->my), - server_host_key_blob, sbloblen, - min, nbits, max, - dh->p, dh->g, - dh_client_pub, - dh->pub_key, - shared_secret - ); - BN_clear_free(dh_client_pub); - - /* save session id := H */ - /* XXX hashlen depends on KEX */ - if (kex->session_id == NULL) { - kex->session_id_len = 20; - kex->session_id = xmalloc(kex->session_id_len); - memcpy(kex->session_id, hash, kex->session_id_len); - } - - /* sign H */ - /* XXX hashlen depends on KEX */ - PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20)); - - /* destroy_sensitive_data(); */ - - /* send server hostkey, DH pubkey 'f' and singed H */ - debug("SSH2_MSG_KEX_DH_GEX_REPLY sent"); - packet_start(SSH2_MSG_KEX_DH_GEX_REPLY); - packet_put_string(server_host_key_blob, sbloblen); - packet_put_bignum2(dh->pub_key); /* f */ - packet_put_string(signature, slen); - packet_send(); - - xfree(signature); - xfree(server_host_key_blob); - /* have keys, free DH */ - DH_free(dh); - - kex_derive_keys(kex, hash, shared_secret); - BN_clear_free(shared_secret); - - kex_finish(kex); -} - -void -kexgex(Kex *kex) -{ - if (kex->server) - kexgex_server(kex); - else - kexgex_client(kex); -} diff --git a/kexgexc.c b/kexgexc.c new file mode 100644 index 000000000..f14ac44ca --- /dev/null +++ b/kexgexc.c @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2000 Niels Provos. All rights reserved. + * Copyright (c) 2001 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" +RCSID("$OpenBSD: kexgexc.c,v 1.1 2003/02/16 17:09:57 markus Exp $"); + +#include "xmalloc.h" +#include "key.h" +#include "kex.h" +#include "log.h" +#include "packet.h" +#include "dh.h" +#include "ssh2.h" +#include "compat.h" + +void +kexgex_client(Kex *kex) +{ + BIGNUM *dh_server_pub = NULL, *shared_secret = NULL; + BIGNUM *p = NULL, *g = NULL; + Key *server_host_key; + u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; + u_int klen, kout, slen, sbloblen; + int min, max, nbits; + DH *dh; + + nbits = dh_estimate(kex->we_need * 8); + + if (datafellows & SSH_OLD_DHGEX) { + debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD sent"); + + /* Old GEX request */ + packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST_OLD); + packet_put_int(nbits); + min = DH_GRP_MIN; + max = DH_GRP_MAX; + } else { + debug("SSH2_MSG_KEX_DH_GEX_REQUEST sent"); + + /* New GEX request */ + min = DH_GRP_MIN; + max = DH_GRP_MAX; + packet_start(SSH2_MSG_KEX_DH_GEX_REQUEST); + packet_put_int(min); + packet_put_int(nbits); + packet_put_int(max); + } +#ifdef DEBUG_KEXDH + fprintf(stderr, "\nmin = %d, nbits = %d, max = %d\n", + min, nbits, max); +#endif + packet_send(); + + debug("expecting SSH2_MSG_KEX_DH_GEX_GROUP"); + packet_read_expect(SSH2_MSG_KEX_DH_GEX_GROUP); + + if ((p = BN_new()) == NULL) + fatal("BN_new"); + packet_get_bignum2(p); + if ((g = BN_new()) == NULL) + fatal("BN_new"); + packet_get_bignum2(g); + packet_check_eom(); + + if (BN_num_bits(p) < min || BN_num_bits(p) > max) + fatal("DH_GEX group out of range: %d !< %d !< %d", + min, BN_num_bits(p), max); + + dh = dh_new_group(g, p); + dh_gen_key(dh, kex->we_need * 8); + +#ifdef DEBUG_KEXDH + DHparams_print_fp(stderr, dh); + fprintf(stderr, "pub= "); + BN_print_fp(stderr, dh->pub_key); + fprintf(stderr, "\n"); +#endif + + debug("SSH2_MSG_KEX_DH_GEX_INIT sent"); + /* generate and send 'e', client DH public key */ + packet_start(SSH2_MSG_KEX_DH_GEX_INIT); + packet_put_bignum2(dh->pub_key); + packet_send(); + + debug("expecting SSH2_MSG_KEX_DH_GEX_REPLY"); + packet_read_expect(SSH2_MSG_KEX_DH_GEX_REPLY); + + /* key, cert */ + server_host_key_blob = packet_get_string(&sbloblen); + server_host_key = key_from_blob(server_host_key_blob, sbloblen); + if (server_host_key == NULL) + fatal("cannot decode server_host_key_blob"); + if (server_host_key->type != kex->hostkey_type) + fatal("type mismatch for decoded server_host_key_blob"); + if (kex->verify_host_key == NULL) + fatal("cannot verify server_host_key"); + if (kex->verify_host_key(server_host_key) == -1) + fatal("server_host_key verification failed"); + + /* DH paramter f, server public DH key */ + if ((dh_server_pub = BN_new()) == NULL) + fatal("dh_server_pub == NULL"); + packet_get_bignum2(dh_server_pub); + +#ifdef DEBUG_KEXDH + fprintf(stderr, "dh_server_pub= "); + BN_print_fp(stderr, dh_server_pub); + fprintf(stderr, "\n"); + debug("bits %d", BN_num_bits(dh_server_pub)); +#endif + + /* signed H */ + signature = packet_get_string(&slen); + packet_check_eom(); + + if (!dh_pub_is_valid(dh, dh_server_pub)) + packet_disconnect("bad server public DH value"); + + klen = DH_size(dh); + kbuf = xmalloc(klen); + kout = DH_compute_key(kbuf, dh_server_pub, dh); +#ifdef DEBUG_KEXDH + dump_digest("shared secret", kbuf, kout); +#endif + if ((shared_secret = BN_new()) == NULL) + fatal("kexgex_client: BN_new failed"); + BN_bin2bn(kbuf, kout, shared_secret); + memset(kbuf, 0, klen); + xfree(kbuf); + + if (datafellows & SSH_OLD_DHGEX) + min = max = -1; + + /* calc and verify H */ + hash = kexgex_hash( + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->my), buffer_len(&kex->my), + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + server_host_key_blob, sbloblen, + min, nbits, max, + dh->p, dh->g, + dh->pub_key, + dh_server_pub, + shared_secret + ); + /* have keys, free DH */ + DH_free(dh); + xfree(server_host_key_blob); + BN_clear_free(dh_server_pub); + + if (key_verify(server_host_key, signature, slen, hash, 20) != 1) + fatal("key_verify failed for server_host_key"); + key_free(server_host_key); + xfree(signature); + + /* save session id */ + if (kex->session_id == NULL) { + kex->session_id_len = 20; + kex->session_id = xmalloc(kex->session_id_len); + memcpy(kex->session_id, hash, kex->session_id_len); + } + kex_derive_keys(kex, hash, shared_secret); + BN_clear_free(shared_secret); + + kex_finish(kex); +} diff --git a/kexgexs.c b/kexgexs.c new file mode 100644 index 000000000..baebfcfb0 --- /dev/null +++ b/kexgexs.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2000 Niels Provos. All rights reserved. + * Copyright (c) 2001 Markus Friedl. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" +RCSID("$OpenBSD: kexgexs.c,v 1.1 2003/02/16 17:09:57 markus Exp $"); + +#include "xmalloc.h" +#include "key.h" +#include "kex.h" +#include "log.h" +#include "packet.h" +#include "dh.h" +#include "ssh2.h" +#include "compat.h" +#include "monitor_wrap.h" + +void +kexgex_server(Kex *kex) +{ + BIGNUM *shared_secret = NULL, *dh_client_pub = NULL; + Key *server_host_key; + DH *dh; + u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; + u_int sbloblen, klen, kout, slen; + int min = -1, max = -1, nbits = -1, type; + + if (kex->load_host_key == NULL) + fatal("Cannot load hostkey"); + server_host_key = kex->load_host_key(kex->hostkey_type); + if (server_host_key == NULL) + fatal("Unsupported hostkey type %d", kex->hostkey_type); + + type = packet_read(); + switch (type) { + case SSH2_MSG_KEX_DH_GEX_REQUEST: + debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); + min = packet_get_int(); + nbits = packet_get_int(); + max = packet_get_int(); + min = MAX(DH_GRP_MIN, min); + max = MIN(DH_GRP_MAX, max); + break; + case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: + debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received"); + nbits = packet_get_int(); + min = DH_GRP_MIN; + max = DH_GRP_MAX; + /* unused for old GEX */ + break; + default: + fatal("protocol error during kex, no DH_GEX_REQUEST: %d", type); + } + packet_check_eom(); + + if (max < min || nbits < min || max < nbits) + fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d", + min, nbits, max); + + /* Contact privileged parent */ + dh = PRIVSEP(choose_dh(min, nbits, max)); + if (dh == NULL) + packet_disconnect("Protocol error: no matching DH grp found"); + + debug("SSH2_MSG_KEX_DH_GEX_GROUP sent"); + packet_start(SSH2_MSG_KEX_DH_GEX_GROUP); + packet_put_bignum2(dh->p); + packet_put_bignum2(dh->g); + packet_send(); + + /* flush */ + packet_write_wait(); + + /* Compute our exchange value in parallel with the client */ + dh_gen_key(dh, kex->we_need * 8); + + debug("expecting SSH2_MSG_KEX_DH_GEX_INIT"); + packet_read_expect(SSH2_MSG_KEX_DH_GEX_INIT); + + /* key, cert */ + if ((dh_client_pub = BN_new()) == NULL) + fatal("dh_client_pub == NULL"); + packet_get_bignum2(dh_client_pub); + packet_check_eom(); + +#ifdef DEBUG_KEXDH + fprintf(stderr, "dh_client_pub= "); + BN_print_fp(stderr, dh_client_pub); + fprintf(stderr, "\n"); + debug("bits %d", BN_num_bits(dh_client_pub)); +#endif + +#ifdef DEBUG_KEXDH + DHparams_print_fp(stderr, dh); + fprintf(stderr, "pub= "); + BN_print_fp(stderr, dh->pub_key); + fprintf(stderr, "\n"); +#endif + if (!dh_pub_is_valid(dh, dh_client_pub)) + packet_disconnect("bad client public DH value"); + + klen = DH_size(dh); + kbuf = xmalloc(klen); + kout = DH_compute_key(kbuf, dh_client_pub, dh); +#ifdef DEBUG_KEXDH + dump_digest("shared secret", kbuf, kout); +#endif + if ((shared_secret = BN_new()) == NULL) + fatal("kexgex_server: BN_new failed"); + BN_bin2bn(kbuf, kout, shared_secret); + memset(kbuf, 0, klen); + xfree(kbuf); + + key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); + + if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD) + min = max = -1; + + /* calc H */ /* XXX depends on 'kex' */ + hash = kexgex_hash( + kex->client_version_string, + kex->server_version_string, + buffer_ptr(&kex->peer), buffer_len(&kex->peer), + buffer_ptr(&kex->my), buffer_len(&kex->my), + server_host_key_blob, sbloblen, + min, nbits, max, + dh->p, dh->g, + dh_client_pub, + dh->pub_key, + shared_secret + ); + BN_clear_free(dh_client_pub); + + /* save session id := H */ + /* XXX hashlen depends on KEX */ + if (kex->session_id == NULL) { + kex->session_id_len = 20; + kex->session_id = xmalloc(kex->session_id_len); + memcpy(kex->session_id, hash, kex->session_id_len); + } + + /* sign H */ + /* XXX hashlen depends on KEX */ + PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20)); + + /* destroy_sensitive_data(); */ + + /* send server hostkey, DH pubkey 'f' and singed H */ + debug("SSH2_MSG_KEX_DH_GEX_REPLY sent"); + packet_start(SSH2_MSG_KEX_DH_GEX_REPLY); + packet_put_string(server_host_key_blob, sbloblen); + packet_put_bignum2(dh->pub_key); /* f */ + packet_put_string(signature, slen); + packet_send(); + + xfree(signature); + xfree(server_host_key_blob); + /* have keys, free DH */ + DH_free(dh); + + kex_derive_keys(kex, hash, shared_secret); + BN_clear_free(shared_secret); + + kex_finish(kex); +} diff --git a/ssh-keyscan.c b/ssh-keyscan.c index 8c14d6d26..5b4eb82d1 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -7,7 +7,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh-keyscan.c,v 1.40 2002/07/06 17:47:58 stevesk Exp $"); +RCSID("$OpenBSD: ssh-keyscan.c,v 1.41 2003/02/16 17:09:57 markus Exp $"); #include "openbsd-compat/sys-queue.h" @@ -354,6 +354,8 @@ keygrab_ssh2(con *c) myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = c->c_keytype == KT_DSA? "ssh-dss": "ssh-rsa"; c->c_kex = kex_setup(myproposal); + c->c_kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; + c->c_kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; c->c_kex->verify_host_key = hostjump; if (!(j = setjmp(kexjmp))) { diff --git a/sshconnect2.c b/sshconnect2.c index de33e142b..81d1b91c7 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.110 2002/12/19 00:07:02 djm Exp $"); +RCSID("$OpenBSD: sshconnect2.c,v 1.111 2003/02/16 17:09:57 markus Exp $"); #include "ssh.h" #include "ssh2.h" @@ -110,6 +110,8 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) /* start key exchange */ kex = kex_setup(myproposal); + kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; + kex->kex[KEX_DH_GEX_SHA1] = kexgex_client; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; kex->verify_host_key=&verify_host_key_callback; diff --git a/sshd.c b/sshd.c index ca2d4d1bc..86441cff1 100644 --- a/sshd.c +++ b/sshd.c @@ -42,7 +42,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.262 2003/01/27 17:06:31 markus Exp $"); +RCSID("$OpenBSD: sshd.c,v 1.263 2003/02/16 17:09:57 markus Exp $"); #include #include @@ -202,8 +202,8 @@ int *startup_pipes = NULL; int startup_pipe; /* in child */ /* variables used for privilege separation */ -extern struct monitor *pmonitor; -extern int use_privsep; +int use_privsep; +struct monitor *pmonitor; /* Prototypes for various functions defined later in this file. */ void destroy_sensitive_data(void); @@ -1814,6 +1814,8 @@ do_ssh2_kex(void) /* start key exchange */ kex = kex_setup(myproposal); + kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server; + kex->kex[KEX_DH_GEX_SHA1] = kexgex_server; kex->server = 1; kex->client_version_string=client_version_string; kex->server_version_string=server_version_string; -- cgit v1.2.3 From 933cc8fb9cd3e34b9b656f73ad8b661c08551875 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Mon, 10 Mar 2003 11:38:10 +1100 Subject: - (djm) Bug #245: TTY problems on Solaris. Fix by stevesk@ and dtucker@zip.com.au --- ChangeLog | 4 +++- acconfig.h | 5 ++++- configure.ac | 3 ++- sshd.c | 8 ++++++-- 4 files changed, 15 insertions(+), 5 deletions(-) (limited to 'sshd.c') diff --git a/ChangeLog b/ChangeLog index d060257e9..37a51edaa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,8 @@ fix memory leaks; from dlheine@suif.Stanford.EDU/CLOUSEAU; ok djm@ - (djm) One more portable-specific one from dlheine@suif.Stanford.EDU/ CLOUSEAU + - (djm) Bug #245: TTY problems on Solaris. Fix by stevesk@ and + dtucker@zip.com.au 20030225 - (djm) Fix some compile errors spotted by dtucker and his fabulous @@ -1200,4 +1202,4 @@ save auth method before monitor_reset_key_state(); bugzilla bug #284; ok provos@ -$Id: ChangeLog,v 1.2624 2003/03/10 00:23:06 djm Exp $ +$Id: ChangeLog,v 1.2625 2003/03/10 00:38:10 djm Exp $ diff --git a/acconfig.h b/acconfig.h index b28966084..b6e4b37cc 100644 --- a/acconfig.h +++ b/acconfig.h @@ -1,4 +1,4 @@ -/* $Id: acconfig.h,v 1.148 2003/01/28 00:33:44 djm Exp $ */ +/* $Id: acconfig.h,v 1.149 2003/03/10 00:38:10 djm Exp $ */ #ifndef _CONFIG_H #define _CONFIG_H @@ -374,6 +374,9 @@ /* Some systems put this outside of libc */ #undef HAVE_NANOSLEEP +/* Pushing STREAMS modules incorrectly acquires a controlling TTY */ +#undef STREAMS_PUSH_ACQUIRES_CTTY + @BOTTOM@ /* ******************* Shouldn't need to edit below this line ************** */ diff --git a/configure.ac b/configure.ac index bdf80288e..3469af2f4 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.109 2003/02/24 04:45:43 djm Exp $ +# $Id: configure.ac,v 1.110 2003/03/10 00:38:10 djm Exp $ AC_INIT AC_CONFIG_SRCDIR([ssh.c]) @@ -216,6 +216,7 @@ mips-sony-bsd|mips-sony-newsos4) AC_DEFINE(LOGIN_NEEDS_UTMPX) AC_DEFINE(LOGIN_NEEDS_TERM) AC_DEFINE(PAM_TTY_KLUDGE) + AC_DEFINE(STREAMS_PUSH_ACQUIRES_CTTY) # hardwire lastlog location (can't detect it on some versions) conf_lastlog_location="/var/adm/lastlog" AC_MSG_CHECKING(for obsolete utmp and wtmp in solaris2.x) diff --git a/sshd.c b/sshd.c index 86441cff1..0f2b2a3ce 100644 --- a/sshd.c +++ b/sshd.c @@ -1400,8 +1400,12 @@ main(int ac, char **av) * setlogin() affects the entire process group. We don't * want the child to be able to affect the parent. */ -#if 0 - /* XXX: this breaks Solaris */ +#if !defined(STREAMS_PUSH_ACQUIRES_CTTY) + /* + * If setsid is called on Solaris, sshd will acquire the controlling + * terminal while pushing STREAMS modules. This will prevent the + * shell from acquiring it later. + */ if (!debug_flag && !inetd_flag && setsid() < 0) error("setsid: %.100s", strerror(errno)); #endif -- cgit v1.2.3