+20090926
+ - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec]
+ [contrib/suse/openssh.spec] Update for release
+ - (djm) [README] update relnotes URL
+ - (djm) [packet.c] Restore EWOULDBLOCK handling that got lost somewhere
+ - (djm) Release 5.3p1
+
+20090911
+ - (dtucker) [configure.ac] Change the -lresolv check so it works on Mac OS X
+ 10.6 (which doesn't have BIND8_COMPAT and thus uses res_9_query). Patch
+ from jbasney at ncsa uiuc edu.
+
+20090908
+ - (djm) [serverloop.c] Fix test for server-assigned remote forwarding port
+ (-R 0:...); bz#1578, spotted and fix by gavin AT emf.net; ok dtucker@
+
+20090901
+ - (dtucker) [configure.ac] Bug #1639: use AC_PATH_PROG to search the path for
+ krb5-config if it's not in the location specified by --with-kerberos5.
+ Patch from jchadima at redhat.
+
+20090829
+ - (dtucker) [README.platform] Add text about development packages, based on
+ text from Chris Pepper in bug #1631.
+
+20090828
+ - dtucker [auth-sia.c] Roll back the change for bug #1241 as it apparently
+ causes problems in some Tru64 configurations.
+ - (djm) [sshd_config.5] downgrade mention of login.conf to be an example
+ and mention PAM as another provider for ChallengeResponseAuthentication;
+ bz#1408; ok dtucker@
+ - (djm) [sftp-server.c] bz#1535: accept ENOSYS as a fallback error when
+ attempting atomic rename(); ok dtucker@
+ - (djm) [Makefile.in] bz#1505: Solaris make(1) doesn't accept make variables
+ in argv, so pass them in the environment; ok dtucker@
+ - (dtucker) [channels.c configure.ac] Bug #1528: skip the tcgetattr call on
+ the pty master on Solaris, since it never succeeds and can hang if large
+ amounts of data is sent to the slave (eg a copy-paste). Based on a patch
+ originally from Doke Scott, ok djm@
+ - (dtucker) [clientloop.c configure.ac defines.h] Make the client's IO buffer
+ size a compile-time option and set it to 64k on Cygwin, since Corinna
+ reports that it makes a significant difference to performance. ok djm@
+ - (dtucker) [configure.ac] Fix the syntax of the Solaris tcgetattr entry.
+
+20090820
+ - (dtucker) [includes.h] Bug #1634: do not include system glob.h if we're not
+ using it since the type conflicts can cause problems on FreeBSD. Patch
+ from Jonathan Chen.
+ - (dtucker) [session.c openbsd-compat/port-aix.h] Bugs #1249 and #1567: move
+ the setpcred call on AIX to immediately before the permanently_set_uid().
+ Ensures that we still have privileges when we call chroot and
+ pam_open_sesson. Based on a patch from David Leonard.
+
+20090817
+ - (dtucker) [configure.ac] Check for headers before libraries for openssl an
+ zlib, which should make the errors slightly more meaningful on platforms
+ where there's separate "-devel" packages for those.
+ - (dtucker) [sshlogin.c openbsd-compat/port-aix.{c,h}] Bug #1595: make
+ PrintLastLog work on AIX. Based in part on a patch from Miguel Sanders.
+
+20090729
+ - (tim) [contrib/cygwin/ssh-user-config] Change script to call correct error
+ function. Patch from Corinna Vinschen.
+
+20090713
+ - (dtucker) [openbsd-compat/getrrsetbyname.c] Reduce answer buffer size so it
+ fits into 16 bits to work around a bug in glibc's resolver where it masks
+ off the buffer size at 16 bits. Patch from Hauke Lampe, ok djm jakob.
+
+20090712
+ - (dtucker) [configure.ac] Include sys/param.h for the sys/mount.h test,
+ prevents configure complaining on older BSDs.
+ - (dtucker [contrib/cygwin/ssh-{host,user}-config] Add license text. Patch
+ from Corinna Vinschen.
+ - (dtucker) [auth-pam.c] Bug #1534: move the deletion of PAM credentials on
+ logout to after the session close. Patch from Anicka Bernathova,
+ originally from Andreas Schwab via Novelll ok djm.
+
+20090707
+ - (dtucker) [contrib/cygwin/ssh-host-config] better support for automated
+ scripts and fix usage of eval. Patch from Corinna Vinschen.
+
+20090705
+ - (dtucker) OpenBSD CVS Sync
+ - andreas@cvs.openbsd.org 2009/06/27 09:29:06
+ [packet.h packet.c]
+ packet_bacup_state() and packet_restore_state() will be used to
+ temporarily save the current state ren resuming a suspended connection.
+ ok markus@
+ - andreas@cvs.openbsd.org 2009/06/27 09:32:43
+ [roaming_common.c roaming.h]
+ It may be necessary to retransmit some data when resuming, so add it
+ to a buffer when roaming is enabled.
+ Most of this code was written by Martin Forssen, maf at appgate dot com.
+ ok markus@
+ - andreas@cvs.openbsd.org 2009/06/27 09:35:06
+ [readconf.h readconf.c]
+ Add client option UseRoaming. It doesn't do anything yet but will
+ control whether the client tries to use roaming if enabled on the
+ server. From Martin Forssen.
+ ok markus@
+ - markus@cvs.openbsd.org 2009/06/30 14:54:40
+ [version.h]
+ crank version; ok deraadt
+ - dtucker@cvs.openbsd.org 2009/07/02 02:11:47
+ [ssh.c]
+ allow for long home dir paths (bz #1615). ok deraadt
+ (based in part on a patch from jchadima at redhat)
+ - stevesk@cvs.openbsd.org 2009/07/05 19:28:33
+ [clientloop.c]
+ only send SSH2_MSG_DISCONNECT if we're in compat20; from dtucker@
+ ok deraadt@ markus@
+
+20090622
+ - (dtucker) OpenBSD CVS Sync
+ - dtucker@cvs.openbsd.org 2009/06/22 05:39:28
+ [monitor_wrap.c monitor_mm.c ssh-keygen.c auth2.c gss-genr.c sftp-client.c]
+ alphabetize includes; reduces diff vs portable and style(9).
+ ok stevesk djm
+ (Id sync only; these were already in order in -portable)
+
+20090621
+ - (dtucker) OpenBSD CVS Sync
+ - markus@cvs.openbsd.org 2009/03/17 21:37:00
+ [ssh.c]
+ pass correct argv[0] to openlog(); ok djm@
+ - jmc@cvs.openbsd.org 2009/03/19 15:15:09
+ [ssh.1]
+ for "Ciphers", just point the reader to the keyword in ssh_config(5), just
+ as we do for "MACs": this stops us getting out of sync when the lists
+ change;
+ fixes documentation/6102, submitted by Peter J. Philipp
+ alternative fix proposed by djm
+ ok markus
+ - tobias@cvs.openbsd.org 2009/03/23 08:31:19
+ [ssh-agent.c]
+ Fixed a possible out-of-bounds memory access if the environment variable
+ SHELL is shorter than 3 characters.
+ with input by and ok dtucker
+ - tobias@cvs.openbsd.org 2009/03/23 19:38:04
+ [ssh-agent.c]
+ My previous commit didn't fix the problem at all, so stick at my first
+ version of the fix presented to dtucker.
+ Issue notified by Matthias Barkhoff (matthias dot barkhoff at gmx dot de).
+ ok dtucker
+ - sobrado@cvs.openbsd.org 2009/03/26 08:38:39
+ [sftp-server.8 sshd.8 ssh-agent.1]
+ fix a few typographical errors found by spell(1).
+ ok dtucker@, jmc@
+ - stevesk@cvs.openbsd.org 2009/04/13 19:07:44
+ [sshd_config.5]
+ fix possessive; ok djm@
+ - stevesk@cvs.openbsd.org 2009/04/14 16:33:42
+ [sftp-server.c]
+ remove unused option character from getopt() optstring; ok markus@
+ - jj@cvs.openbsd.org 2009/04/14 21:10:54
+ [servconf.c]
+ Fixed a few the-the misspellings in comments. Skipped a bunch in
+ binutils,gcc and so on. ok jmc@
+ - stevesk@cvs.openbsd.org 2009/04/17 19:23:06
+ [session.c]
+ use INTERNAL_SFTP_NAME for setproctitle() of in-process sftp-server;
+ ok djm@ markus@
+ - stevesk@cvs.openbsd.org 2009/04/17 19:40:17
+ [sshd_config.5]
+ clarify that even internal-sftp needs /dev/log for logging to work; ok
+ markus@
+ - jmc@cvs.openbsd.org 2009/04/18 18:39:10
+ [sshd_config.5]
+ tweak previous; ok stevesk
+ - stevesk@cvs.openbsd.org 2009/04/21 15:13:17
+ [sshd_config.5]
+ clarify we cd to user's home after chroot; ok markus@ on
+ earlier version; tweaks and ok jmc@
+ - andreas@cvs.openbsd.org 2009/05/25 06:48:01
+ [channels.c packet.c clientloop.c packet.h serverloop.c monitor_wrap.c
+ monitor.c]
+ Put the globals in packet.c into a struct and don't access it directly
+ from other files. No functional changes.
+ ok markus@ djm@
+ - andreas@cvs.openbsd.org 2009/05/27 06:31:25
+ [canohost.h canohost.c]
+ Add clear_cached_addr(), needed for upcoming changes allowing the peer
+ address to change.
+ ok markus@
+ - andreas@cvs.openbsd.org 2009/05/27 06:33:39
+ [clientloop.c]
+ Send SSH2_MSG_DISCONNECT when the client disconnects. From a larger
+ change from Martin Forssen, maf at appgate dot com.
+ ok markus@
+ - andreas@cvs.openbsd.org 2009/05/27 06:34:36
+ [kex.c kex.h]
+ Move the KEX_COOKIE_LEN define to kex.h
+ ok markus@
+ - andreas@cvs.openbsd.org 2009/05/27 06:36:07
+ [packet.h packet.c]
+ Add packet_put_int64() and packet_get_int64(), part of a larger change
+ from Martin Forssen.
+ ok markus@
+ - andreas@cvs.openbsd.org 2009/05/27 06:38:16
+ [sshconnect.h sshconnect.c]
+ Un-static ssh_exchange_identification(), part of a larger change from
+ Martin Forssen and needed for upcoming changes.
+ ok markus@
+ - andreas@cvs.openbsd.org 2009/05/28 16:50:16
+ [sshd.c packet.c serverloop.c monitor_wrap.c clientloop.c sshconnect.c
+ monitor.c Added roaming.h roaming_common.c roaming_dummy.c]
+ Keep track of number of bytes read and written. Needed for upcoming
+ changes. Most code from Martin Forssen, maf at appgate dot com.
+ ok markus@
+ Also, applied appropriate changes to Makefile.in
+ - andreas@cvs.openbsd.org 2009/06/12 20:43:22
+ [monitor.c packet.c]
+ Fix warnings found by chl@ and djm@ and change roaming_atomicio's
+ return type to match atomicio's
+ Diff from djm@, ok markus@
+ - andreas@cvs.openbsd.org 2009/06/12 20:58:32
+ [packet.c]
+ Move some more statics into session_state
+ ok markus@ djm@
+ - dtucker@cvs.openbsd.org 2009/06/21 07:37:15
+ [kexdhs.c kexgexs.c]
+ abort if key_sign fails, preventing possible null deref. Based on report
+ from Paolo Ganci, ok markus@ djm@
+ - dtucker@cvs.openbsd.org 2009/06/21 09:04:03
+ [roaming.h roaming_common.c roaming_dummy.c]
+ Add tags for the benefit of the sync scripts
+ Also: pull in the changes for 1.1->1.2 missed in the previous sync.
+ - (dtucker) [auth2-jpake.c auth2.c canohost.h session.c] Whitespace and
+ header-order changes to reduce diff vs OpenBSD.
+ - (dtucker) [servconf.c sshd.c] More whitespace sync.
+ - (dtucker) [roaming_common.c roaming_dummy.c] Wrap #include <inttypes.h> in
+ ifdef.
+
+20090616
+ - (dtucker) [configure.ac defines.h] Bug #1607: handle the case where fsid_t
+ is a struct with a __val member. Fixes build on, eg, Redhat 6.2.
+
+20090504
+ - (dtucker) [sshlogin.c] Move the NO_SSH_LASTLOG #ifndef line to include
+ variable declarations. Should prevent unused warnings anywhere it's set
+ (only Crays as far as I can tell) and be a no-op everywhere else.
+
+20090318
+ - (tim) [configure.ac] Remove setting IP_TOS_IS_BROKEN for Cygwin. The problem
+ that setsockopt(IP_TOS) doesn't work on Cygwin has been fixed since 2005.
+ Based on patch from vinschen at redhat com.
+
+20090308
+ - (dtucker) [auth-passwd.c auth1.c auth2-kbdint.c auth2-none.c auth2-passwd.c
+ auth2-pubkey.c session.c openbsd-compat/bsd-cygwin_util.{c,h}
+ openbsd-compat/daemon.c] Remove support for Windows 95/98/ME and very old
+ version of Cygwin. Patch from vinschen at redhat com.
+
+20090307
+ - (dtucker) [contrib/aix/buildbff.sh] Only try to rename ssh_prng_cmds if it
+ exists (it's not created if OpenSSL's PRNG is self-seeded, eg if the OS
+ has a /dev/random).
+ - (dtucker) [schnorr.c openbsd-compat/openssl-compat.{c,h}] Add
+ EVP_DigestUpdate to the OLD_EVP compatibility functions and tell schnorr.c
+ to use them. Allows building with older OpenSSL versions.
+ - (dtucker) [configure.ac defines.h] Check for in_port_t and typedef if needed.
+ - (dtucker) [configure.ac] Missing comma in type list.
+ - (dtucker) [configure.ac openbsd-compat/openssl-compat.{c,h}]
+ EVP_DigestUpdate does not exactly match the other OLD_EVP functions (eg
+ in openssl 0.9.6) so add an explicit test for it.
+
+20090306
+ - (djm) OpenBSD CVS Sync
+ - djm@cvs.openbsd.org 2009/03/05 07:18:19
+ [auth2-jpake.c jpake.c jpake.h monitor_wrap.c monitor_wrap.h schnorr.c]
+ [sshconnect2.c]
+ refactor the (disabled) Schnorr proof code to make it a little more
+ generally useful
+ - djm@cvs.openbsd.org 2009/03/05 11:30:50
+ [uuencode.c]
+ document what these functions do so I don't ever have to recuse into
+ b64_pton/ntop to remember their return values
+
20090223
- (djm) OpenBSD CVS Sync
- djm@cvs.openbsd.org 2009/02/22 23:50:57
entropy.o scard-opensc.o gss-genr.o umac.o jpake.o schnorr.o
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
- sshconnect.o sshconnect1.o sshconnect2.o mux.o
+ sshconnect.o sshconnect1.o sshconnect2.o mux.o \
+ roaming_common.o
SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \
sshpty.o sshlogin.o servconf.o serverloop.o \
auth-krb5.o \
auth2-gss.o gss-serv.o gss-serv-krb5.o \
loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
- audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o
+ audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o \
+ roaming_common.o
MANPAGES = moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out
MANPAGES_IN = moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5
ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o
$(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
-ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o
- $(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o roaming_dummy.o
+ $(LD) -o $@ ssh-keysign.o readconf.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
-ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o
- $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
+ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o roaming_dummy.o
+ $(LD) -o $@ ssh-keyscan.o roaming_dummy.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS)
sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o sftp-server-main.o
$(LD) -o $@ sftp-server.o sftp-common.o sftp-server-main.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
-$(DESTDIR)$(sbindir)/sshd -t -f $(DESTDIR)$(sysconfdir)/sshd_config
scard-install:
- (cd scard && $(MAKE) DESTDIR=$(DESTDIR) install)
+ (cd scard && env DESTDIR=$(DESTDIR) $(MAKE) DESTDIR=$(DESTDIR) install)
install-files: scard-install
$(srcdir)/mkinstalldirs $(DESTDIR)$(bindir)
-See http://www.openssh.com/txt/release-5.2 for the release notes.
+See http://www.openssh.com/txt/release-5.3 for the release notes.
- A Japanese translation of this document and of the OpenSSH FAQ is
- available at http://www.unixuser.org/~haruyama/security/openssh/index.html
http://www-user.rhrk.uni-kl.de/~nissler/tuntap/
+Linux
+-----
+
+Some Linux distributions (including Red Hat/Fedora/CentOS) include
+headers and library links in the -devel RPMs rather than the main
+binary RPMs. If you get an error about headers, or complaining about a
+missing prerequisite then you may need to install the equivalent
+development packages. On Redhat based distros these may be openssl-devel,
+zlib-devel and pam-devel, on Debian based distros these may be
+libssl-dev, libz-dev and libpam-dev.
+
+
Solaris
-------
If you enable BSM auditing on Solaris, you need to update audit_event(4)
return;
debug("PAM: cleanup");
pam_set_item(sshpam_handle, PAM_CONV, (const void *)&null_conv);
- if (sshpam_cred_established) {
- debug("PAM: deleting credentials");
- pam_setcred(sshpam_handle, PAM_DELETE_CRED);
- sshpam_cred_established = 0;
- }
if (sshpam_session_open) {
debug("PAM: closing session");
pam_close_session(sshpam_handle, PAM_SILENT);
sshpam_session_open = 0;
}
+ if (sshpam_cred_established) {
+ debug("PAM: deleting credentials");
+ pam_setcred(sshpam_handle, PAM_DELETE_CRED);
+ sshpam_cred_established = 0;
+ }
sshpam_authenticated = 0;
pam_end(sshpam_handle, sshpam_err);
sshpam_handle = NULL;
}
#endif
#ifdef HAVE_CYGWIN
- if (is_winnt) {
+ {
HANDLE hToken = cygwin_logon_user(pw, password);
if (hToken == INVALID_HANDLE_VALUE)
#include <unistd.h>
#include <stdarg.h>
#include <string.h>
-#include <sys/types.h>
-#include <sys/security.h>
-#include <prot.h>
-#include <time.h>
#include "ssh.h"
#include "key.h"
extern int saved_argc;
extern char **saved_argv;
-static int
-sia_password_change_required(const char *user)
-{
- struct es_passwd *acct;
- time_t pw_life;
- time_t pw_date;
-
- set_auth_parameters(saved_argc, saved_argv);
-
- if ((acct = getespwnam(user)) == NULL) {
- error("Couldn't access protected database entry for %s", user);
- endprpwent();
- return (0);
- }
-
- /* If forced password change flag is set, honor it */
- if (acct->uflg->fg_psw_chg_reqd && acct->ufld->fd_psw_chg_reqd) {
- endprpwent();
- return (1);
- }
-
- /* Obtain password lifetime; if none, it can't have expired */
- if (acct->uflg->fg_expire)
- pw_life = acct->ufld->fd_expire;
- else if (acct->sflg->fg_expire)
- pw_life = acct->sfld->fd_expire;
- else {
- endprpwent();
- return (0);
- }
-
- /* Offset from last change; if none, it must be expired */
- if (acct->uflg->fg_schange)
- pw_date = acct->ufld->fd_schange + pw_life;
- else {
- endprpwent();
- return (1);
- }
-
- endprpwent();
-
- /* If expiration date is prior to now, change password */
-
- return (pw_date <= time((time_t *) NULL));
-}
-
int
sys_auth_passwd(Authctxt *authctxt, const char *pass)
{
sia_ses_release(&ent);
- authctxt->force_pwchange = sia_password_change_required(
- authctxt->user);
-
return (1);
}
}
#endif /* _UNICOS */
-#ifdef HAVE_CYGWIN
- if (authenticated &&
- !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD,
- authctxt->pw)) {
- packet_disconnect("Authentication rejected for uid %d.",
- authctxt->pw == NULL ? -1 : authctxt->pw->pw_uid);
- authenticated = 0;
- }
-#else
+#ifndef HAVE_CYGWIN
/* Special handling for root */
if (authenticated && authctxt->pw->pw_uid == 0 &&
!auth_root_allowed(meth->name)) {
-/* $OpenBSD: auth2-jpake.c,v 1.2 2008/11/07 23:34:48 dtucker Exp $ */
+/* $OpenBSD: auth2-jpake.c,v 1.3 2009/03/05 07:18:19 djm Exp $ */
/*
* Copyright (c) 2008 Damien Miller. All rights reserved.
*
#include "ssh2.h"
#include "key.h"
#include "hostfile.h"
-#include "buffer.h"
#include "auth.h"
+#include "buffer.h"
#include "packet.h"
#include "dispatch.h"
#include "log.h"
#endif
#include "monitor_wrap.h"
+#include "schnorr.h"
#include "jpake.h"
/*
}
/*
- * Being authentication attempt.
+ * Begin authentication attempt.
* Note, sets authctxt->postponed while in subprotocol
*/
static int
xfree(devs);
xfree(lang);
-#ifdef HAVE_CYGWIN
- if (check_nt_auth(0, authctxt->pw) == 0)
- authenticated = 0;
-#endif
return authenticated;
}
{
none_enabled = 0;
packet_check_eom();
-#ifdef HAVE_CYGWIN
- if (check_nt_auth(1, authctxt->pw) == 0)
- return (0);
-#endif
if (options.password_authentication)
return (PRIVSEP(auth_password(authctxt, "")));
return (0);
logit("password change not supported");
else if (PRIVSEP(auth_password(authctxt, password)) == 1)
authenticated = 1;
-#ifdef HAVE_CYGWIN
- if (check_nt_auth(1, authctxt->pw) == 0)
- authenticated = 0;
-#endif
memset(password, 0, len);
xfree(password);
return authenticated;
key_free(key);
xfree(pkalg);
xfree(pkblob);
-#ifdef HAVE_CYGWIN
- if (check_nt_auth(0, authctxt->pw) == 0)
- authenticated = 0;
-#endif
return authenticated;
}
-/* $OpenBSD: auth2.c,v 1.120 2008/11/04 08:22:12 djm Exp $ */
+/* $OpenBSD: auth2.c,v 1.121 2009/06/22 05:39:28 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
#include <string.h>
#include <unistd.h>
-#include "xmalloc.h"
#include "atomicio.h"
+#include "xmalloc.h"
#include "ssh2.h"
#include "packet.h"
#include "log.h"
-/* $OpenBSD: canohost.c,v 1.64 2009/02/12 03:00:56 djm Exp $ */
+/* $OpenBSD: canohost.c,v 1.65 2009/05/27 06:31:25 andreas Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
#include "misc.h"
static void check_ip_options(int, char *);
+static char *canonical_host_ip = NULL;
+static int cached_port = -1;
/*
* Return the canonical name of the host at the other end of the socket. The
return get_socket_address(sock, 0, NI_NAMEREQD);
}
+void
+clear_cached_addr(void)
+{
+ if (canonical_host_ip != NULL) {
+ xfree(canonical_host_ip);
+ canonical_host_ip = NULL;
+ }
+ cached_port = -1;
+}
+
/*
* Returns the IP-address of the remote host as a string. The returned
* string must not be freed.
const char *
get_remote_ipaddr(void)
{
- static char *canonical_host_ip = NULL;
-
/* Check whether we have cached the ipaddr. */
if (canonical_host_ip == NULL) {
if (packet_connection_is_on_socket()) {
int
get_remote_port(void)
{
- static int port = -1;
-
/* Cache to avoid getpeername() on a dead connection */
- if (port == -1)
- port = get_port(0);
+ if (cached_port == -1)
+ cached_port = get_port(0);
- return port;
+ return cached_port;
}
int
-/* $OpenBSD: canohost.h,v 1.10 2009/02/12 03:00:56 djm Exp $ */
+/* $OpenBSD: canohost.h,v 1.11 2009/05/27 06:31:25 andreas Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
int get_remote_port(void);
int get_local_port(void);
int get_sock_port(int, int);
-
+void clear_cached_addr(void);
void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *);
-/* $OpenBSD: channels.c,v 1.295 2009/02/12 03:00:56 djm Exp $ */
+/* $OpenBSD: channels.c,v 1.296 2009/05/25 06:48:00 andreas Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
}
return -1;
}
+#ifndef BROKEN_TCGETATTR_ICANON
if (compat20 && c->isatty && dlen >= 1 && buf[0] != '\r') {
if (tcgetattr(c->wfd, &tio) == 0 &&
!(tio.c_lflag & ECHO) && (tio.c_lflag & ICANON)) {
packet_send();
}
}
+#endif
buffer_consume(&c->output, len);
if (compat20 && len > 0) {
c->local_consumed += len;
int id;
/* Reset keepalive timeout */
- keep_alive_timeouts = 0;
+ packet_set_alive_timeouts(0);
id = packet_get_int();
packet_check_eom();
-/* $OpenBSD: clientloop.c,v 1.209 2009/02/12 03:00:56 djm Exp $ */
+/* $OpenBSD: clientloop.c,v 1.213 2009/07/05 19:28:33 stevesk Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
#include "misc.h"
#include "match.h"
#include "msg.h"
+#include "roaming.h"
/* import options */
extern Options options;
xfree(gc);
}
- keep_alive_timeouts = 0;
+ packet_set_alive_timeouts(0);
}
static void
server_alive_check(void)
{
- if (++keep_alive_timeouts > options.server_alive_count_max) {
+ if (packet_inc_alive_timeouts() > options.server_alive_count_max) {
logit("Timeout, server not responding.");
cleanup_exit(255);
}
static void
client_process_net_input(fd_set *readset)
{
- int len;
- char buf[8192];
+ int len, cont = 0;
+ char buf[SSH_IOBUFSZ];
/*
* Read input from the server, and add any such data to the buffer of
*/
if (FD_ISSET(connection_in, readset)) {
/* Read as much as possible. */
- len = read(connection_in, buf, sizeof(buf));
- if (len == 0) {
+ len = roaming_read(connection_in, buf, sizeof(buf), &cont);
+ if (len == 0 && cont == 0) {
/*
* Received EOF. The remote host has closed the
* connection.
client_process_input(fd_set *readset)
{
int len;
- char buf[8192];
+ char buf[SSH_IOBUFSZ];
/* Read input from stdin. */
if (FD_ISSET(fileno(stdin), readset)) {
/* Stop watching for window change. */
signal(SIGWINCH, SIG_DFL);
+ if (compat20) {
+ packet_start(SSH2_MSG_DISCONNECT);
+ packet_put_int(SSH2_DISCONNECT_BY_APPLICATION);
+ packet_put_cstring("disconnected by user");
+ packet_send();
+ packet_write_wait();
+ }
+
channel_free_all();
if (have_pty)
sys/cdefs.h \
sys/dir.h \
sys/mman.h \
- sys/mount.h \
sys/ndir.h \
sys/poll.h \
sys/prctl.h \
#include <sys/types.h>
])
+# older BSDs need sys/param.h before sys/mount.h
+AC_CHECK_HEADERS(sys/mount.h, [], [], [
+#include <sys/param.h>
+])
+
# Messages for features tested for in target-specific section
SIA_MSG="no"
SPC_MSG="no"
AC_DEFINE(USE_PIPES, 1, [Use PIPES instead of a socketpair()])
AC_DEFINE(DISABLE_SHADOW, 1,
[Define if you want to disable shadow passwords])
- AC_DEFINE(IP_TOS_IS_BROKEN, 1,
- [Define if your system choked on IP TOS setting])
AC_DEFINE(NO_X11_UNIX_SOCKETS, 1,
[Define if X11 doesn't support AF_UNIX sockets on that system])
AC_DEFINE(NO_IPPORT_RESERVED_CONCEPT, 1,
AC_DEFINE(DISABLE_FD_PASSING, 1,
[Define if your platform needs to skip post auth
file descriptor passing])
+ AC_DEFINE(SSH_IOBUFSZ, 65536, [Windows is sensitive to read buffer size])
;;
*-*-dgux*)
- AC_DEFINE(IP_TOS_IS_BROKEN)
+ AC_DEFINE(IP_TOS_IS_BROKEN, 1,
+ [Define if your system choked on IP TOS setting])
AC_DEFINE(SETEUID_BREAKS_SETUID)
AC_DEFINE(BROKEN_SETREUID)
AC_DEFINE(BROKEN_SETREGID)
after setsid()])
AC_DEFINE(PASSWD_NEEDS_USERNAME, 1, [must supply username to passwd
in case the name is longer than 8 chars])
+ AC_DEFINE(BROKEN_TCGETATTR_ICANON, 1, [tcgetattr with ICANON may hang])
external_path_file=/etc/default/login
# hardwire lastlog location (can't detect it on some versions)
conf_lastlog_location="/var/adm/lastlog"
fi ]
)
+AC_CHECK_HEADER([zlib.h], ,AC_MSG_ERROR([*** zlib.h missing - please install first or check config.log ***]))
AC_CHECK_LIB(z, deflate, ,
[
saved_CPPFLAGS="$CPPFLAGS"
)
]
)
-AC_CHECK_HEADER([zlib.h], ,AC_MSG_ERROR([*** zlib.h missing - please install first or check config.log ***]))
AC_ARG_WITH(zlib-version-check,
[ --without-zlib-version-check Disable zlib version check],
LDFLAGS="-L/usr/local/ssl/lib ${saved_LDFLAGS}"
fi
CPPFLAGS="-I/usr/local/ssl/include ${saved_CPPFLAGS}"
+ AC_CHECK_HEADER([openssl/opensslv.h], ,
+ AC_MSG_ERROR([*** OpenSSL headers missing - please install first or check config.log ***]))
AC_TRY_LINK_FUNC(RAND_add, AC_DEFINE(HAVE_OPENSSL),
[
AC_MSG_ERROR([*** Can't find recent OpenSSL libcrypto (see config.log for details) ***])
]
)
+AC_MSG_CHECKING([if EVP_DigestUpdate returns an int])
+AC_LINK_IFELSE(
+ [AC_LANG_SOURCE([[
+#include <string.h>
+#include <openssl/evp.h>
+int main(void) { if(EVP_DigestUpdate(NULL, NULL,0)) exit(0); }
+ ]])],
+ [
+ AC_MSG_RESULT(yes)
+ ],
+ [
+ AC_MSG_RESULT(no)
+ AC_DEFINE(OPENSSL_EVP_DIGESTUPDATE_VOID, 1,
+ [Define if EVP_DigestUpdate returns void])
+ ]
+)
+
# Some systems want crypt() from libcrypt, *not* the version in OpenSSL,
# because the system crypt() is more featureful.
if test "x$check_for_libcrypt_before" = "x1"; then
#endif
])
-AC_CHECK_TYPES(in_addr_t,,,
+AC_CHECK_TYPES([in_addr_t, in_port_t],,,
[#include <sys/types.h>
#include <netinet/in.h>])
file descriptor passing])
fi
-AC_MSG_CHECKING(if f_fsid has val members)
+AC_MSG_CHECKING(if struct statvfs.f_fsid is integral type)
AC_TRY_COMPILE([
#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
+#ifdef HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
+], [struct statvfs s; s.f_fsid = 0;],
+[ AC_MSG_RESULT(yes) ],
+[ AC_MSG_RESULT(no)
+
+ AC_MSG_CHECKING(if fsid_t has member val)
+ AC_TRY_COMPILE([
+#include <sys/types.h>
#include <sys/statvfs.h>],
-[struct fsid_t t; t.val[0] = 0;],
+ [fsid_t t; t.val[0] = 0;],
[ AC_MSG_RESULT(yes)
- AC_DEFINE(FSID_HAS_VAL, 1, f_fsid has members) ],
- [ AC_MSG_RESULT(no) ]
-)
+ AC_DEFINE(FSID_HAS_VAL, 1, fsid_t has member val) ],
+ [ AC_MSG_RESULT(no) ])
+
+ AC_MSG_CHECKING(if f_fsid has member __val)
+ AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/statvfs.h>],
+ [fsid_t t; t.__val[0] = 0;],
+ [ AC_MSG_RESULT(yes)
+ AC_DEFINE(FSID_HAS___VAL, 1, fsid_t has member __val) ],
+ [ AC_MSG_RESULT(no) ])
+])
AC_CACHE_CHECK([for msg_control field in struct msghdr],
ac_cv_have_control_in_msghdr, [
AC_SEARCH_LIBS(res_query, resolv)
AC_SEARCH_LIBS(dn_expand, resolv)
AC_MSG_CHECKING(if res_query will link)
- AC_TRY_LINK_FUNC(res_query, AC_MSG_RESULT(yes),
+ AC_LINK_IFELSE([
+#include "confdefs.h"
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <resolv.h>
+int main()
+{
+ res_query (0, 0, 0, 0, 0);
+ return 0;
+}
+ ],
+ AC_MSG_RESULT(yes),
[AC_MSG_RESULT(no)
saved_LIBS="$LIBS"
LIBS="$LIBS -lresolv"
AC_MSG_CHECKING(for res_query in -lresolv)
AC_LINK_IFELSE([
+#include "confdefs.h"
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
#include <resolv.h>
int main()
{
return 0;
}
],
- [LIBS="$LIBS -lresolv"
- AC_MSG_RESULT(yes)],
+ [AC_MSG_RESULT(yes)],
[LIBS="$saved_LIBS"
AC_MSG_RESULT(no)])
])
AC_DEFINE(KRB5, 1, [Define if you want Kerberos 5 support])
KRB5_MSG="yes"
- AC_MSG_CHECKING(for krb5-config)
- if test -x $KRB5ROOT/bin/krb5-config ; then
- KRB5CONF=$KRB5ROOT/bin/krb5-config
- AC_MSG_RESULT($KRB5CONF)
+ AC_PATH_PROG([KRB5CONF],[krb5-config],
+ [$KRB5ROOT/bin/krb5-config],
+ [$KRB5ROOT/bin:$PATH])
+ if test -x $KRB5CONF ; then
AC_MSG_CHECKING(for gssapi support)
if $KRB5CONF | grep gssapi >/dev/null ; then
AC_MSG_RESULT(no)
)
else
- AC_MSG_RESULT(no)
CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include"
LDFLAGS="$LDFLAGS -L${KRB5ROOT}/lib"
AC_MSG_CHECKING(whether we are using Heimdal)
# Rename config files; postinstall script will copy them if necessary
-for cfgfile in ssh_config sshd_config ssh_prng_cmds
+for cfgfile in ssh_config sshd_config
do
mv $FAKE_ROOT/$sysconfdir/$cfgfile $FAKE_ROOT/$sysconfdir/$cfgfile.default
done
+# AIX 5.3 and newer have /dev/random and don't create ssh_prng_cmds
+if [ -f $FAKE_ROOT/$sysconfdir/ssh_prng_cmds ]
+then
+ mv FAKE_ROOT/$sysconfdir/ssh_prng_cmds \
+ $FAKE_ROOT/$sysconfdir/ssh_prng_cmds.default
+fi
+
#
# Generate lpp control files.
# working dir is $FAKE_ROOT but files are generated in dir above
#old cvs stuff. please update before use. may be deprecated.
%define use_stable 1
%if %{use_stable}
- %define version 5.2p1
+ %define version 5.3p1
%define cvs %{nil}
%define release 1
%else
- %define version 5.2p1
+ %define version 5.3p1
%define cvs cvs20050315
%define release 0r1
%endif
#!/bin/bash
#
-# ssh-host-config, Copyright 2000, 2001, 2002, 2003 Red Hat Inc.
+# ssh-host-config, Copyright 2000-2009 Red Hat Inc.
#
# This file is part of the Cygwin port of OpenSSH.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+# THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# ======================================================================
# Initialization
privsep_configured=no
privsep_used=yes
cygwin_value=""
+user_account=
password_value=
+opt_force=no
# ======================================================================
# Routine: create_host_keys
csih_inform "sshd requires. You need to have or to create a privileged"
csih_inform "account. This script will help you do so."
echo
+
+ [ "${opt_force}" = "yes" ] && opt_f=-f
+ [ -n "${user_account}" ] && opt_u="-u ""${user_account}"""
+ csih_select_privileged_username ${opt_f} ${opt_u} sshd
+
if ! csih_create_privileged_user "${password_value}"
then
csih_error_recoverable "There was a serious problem creating a privileged user."
if [ -n "${csih_cygenv}" ]
then
- cygwin_env="-e CYGWIN=\"${csih_cygenv}\""
+ cygwin_env=( -e "CYGWIN=${csih_cygenv}" )
fi
if [ -z "${password}" ]
then
- if eval cygrunsrv -I sshd -d \"CYGWIN sshd\" -p /usr/sbin/sshd \
- -a "-D" -y tcpip ${cygwin_env}
+ if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd \
+ -a "-D" -y tcpip "${cygwin_env[@]}"
then
echo
csih_inform "The sshd service has been installed under the LocalSystem"
csih_inform "will start automatically after the next reboot."
fi
else
- if eval cygrunsrv -I sshd -d \"CYGWIN sshd\" -p /usr/sbin/sshd \
- -a "-D" -y tcpip ${cygwin_env} \
+ if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd \
+ -a "-D" -y tcpip "${cygwin_env[@]}" \
-u "${run_service_as}" -w "${password}"
then
echo
then
csih_auto_answer="no"
csih_disable_color
+ opt_force=yes
fi
if [ -n "${SSH_HOST_CONFIG_AUTO_ANSWER_NO}" ]
then
csih_auto_answer="no"
csih_disable_color
+ opt_force=yes
fi
# ======================================================================
-y | --yes )
csih_auto_answer=yes
+ opt_force=yes
;;
-n | --no )
csih_auto_answer=no
+ opt_force=yes
;;
-c | --cygwin )
shift
;;
+ -u | --user )
+ user_account="$1"
+ shift
+ ;;
+
-w | --pwd )
password_value="$1"
shift
echo " --no -n Answer all questions with \"no\" automatically."
echo " --cygwin -c <options> Use \"options\" as value for CYGWIN environment var."
echo " --port -p <n> sshd listens on port n."
+ echo " --user -u <account> privileged user for service."
echo " --pwd -w <passwd> Use \"pwd\" as password for privileged user."
echo " --privileged On Windows NT/2k/XP, require privileged user"
echo " instead of LocalSystem for sshd service."
fi
# Create /var/empty file used as chroot jail for privilege separation
-csih_make_dir "${LOCALSTATEDIR}/empty" "Cannot create log directory."
+csih_make_dir "${LOCALSTATEDIR}/empty" "Cannot create ${LOCALSTATEDIR}/empty directory."
chmod 755 "${LOCALSTATEDIR}/empty"
setfacl -m u:system:rwx "${LOCALSTATEDIR}/empty"
#!/bin/bash
#
-# ssh-user-config, Copyright 2000, 2001, 2002, 2003, Red Hat Inc.
+# ssh-user-config, Copyright 2000-2008 Red Hat Inc.
#
# This file is part of the Cygwin port of OpenSSH.
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+# THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# ======================================================================
# Initialization
pwdhome=$(awk -F: '{ if ( $3 == '${uid}' ) print $6; }' < ${SYSCONFDIR}/passwd)
if [ "X${pwdhome}" = "X" ]
then
- csih_error_multiline \
+ csih_error_multi \
"There is no home directory set for you in ${SYSCONFDIR}/passwd." \
'Setting $HOME is not sufficient!'
fi
if [ ! -d "${pwdhome}" ]
then
- csih_error_multiline \
+ csih_error_multi \
"${pwdhome} is set in ${SYSCONFDIR}/passwd as your home directory" \
'but it is not a valid directory. Cannot create user identity files.'
fi
# Check passwd file
if [ ! -f ${SYSCONFDIR}/passwd ]
then
- csih_error_multiline \
+ csih_error_multi \
"${SYSCONFDIR}/passwd is nonexistant. Please generate an ${SYSCONFDIR}/passwd file" \
'first using mkpasswd. Check if it contains an entry for you and' \
'please care for the home directory in your entry as well.'
-%define ver 5.2p1
+%define ver 5.3p1
%define rel 1
# OpenSSH privilege separation requires a user & group ID
Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation
Name: openssh
-Version: 5.2p1
+Version: 5.3p1
URL: http://www.openssh.com/
Release: 1
Source0: openssh-%{version}.tar.gz
#ifndef HAVE_IN_ADDR_T
typedef u_int32_t in_addr_t;
#endif
+#ifndef HAVE_IN_PORT_T
+typedef u_int16_t in_port_t;
+#endif
#if defined(BROKEN_SYS_TERMIO_H) && !defined(_STRUCT_WINSIZE)
#define _STRUCT_WINSIZE
#define FSID_TO_ULONG(f) \
((((u_int64_t)(f).val[0] & 0xffffffffUL) << 32) | \
((f).val[1] & 0xffffffffUL))
+#elif defined(FSID_HAS___VAL)
+#define FSID_TO_ULONG(f) \
+ ((((u_int64_t)(f).__val[0] & 0xffffffffUL) << 32) | \
+ ((f).__val[1] & 0xffffffffUL))
#else
# define FSID_TO_ULONG(f) ((f))
#endif
#define INET6_ADDRSTRLEN 46
#endif
+#ifndef SSH_IOBUFSZ
+# define SSH_IOBUFSZ 8192
+#endif
+
#endif /* _DEFINES_H */
-/* $OpenBSD: gss-genr.c,v 1.19 2007/06/12 11:56:15 dtucker Exp $ */
+/* $OpenBSD: gss-genr.c,v 1.20 2009/06/22 05:39:28 dtucker Exp $ */
/*
* Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
#endif
#if defined(HAVE_GLOB_H) && defined(GLOB_HAS_ALTDIRFUNC) && \
defined(GLOB_HAS_GL_MATCHC) && \
- defined(HAVE_DECL_GLOB_NOMATCH) && HAVE_DECL_GLOB_NOMATCH != 0
+ defined(HAVE_DECL_GLOB_NOMATCH) && HAVE_DECL_GLOB_NOMATCH != 0 && \
+ !defined(BROKEN_GLOB)
# include <glob.h>
#endif
#ifdef HAVE_ENDIAN_H
-/* $OpenBSD: jpake.c,v 1.1 2008/11/04 08:22:12 djm Exp $ */
+/* $OpenBSD: jpake.c,v 1.2 2009/03/05 07:18:19 djm Exp $ */
/*
* Copyright (c) 2008 Damien Miller. All rights reserved.
*
#include "log.h"
#include "jpake.h"
+#include "schnorr.h"
#ifdef JPAKE
"98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB" \
"9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF"
-struct jpake_group *
+struct modp_group *
jpake_default_group(void)
{
- struct jpake_group *ret;
-
- ret = xmalloc(sizeof(*ret));
- ret->p = ret->q = ret->g = NULL;
- if (BN_hex2bn(&ret->p, JPAKE_GROUP_P) == 0 ||
- BN_hex2bn(&ret->g, JPAKE_GROUP_G) == 0)
- fatal("%s: BN_hex2bn", __func__);
- /* Subgroup order is p/2 (p is a safe prime) */
- if ((ret->q = BN_new()) == NULL)
- fatal("%s: BN_new", __func__);
- if (BN_rshift1(ret->q, ret->p) != 1)
- fatal("%s: BN_rshift1", __func__);
-
- return ret;
-}
-
-/*
- * Generate uniformly distributed random number in range (1, high).
- * Return number on success, NULL on failure.
- */
-BIGNUM *
-bn_rand_range_gt_one(const BIGNUM *high)
-{
- BIGNUM *r, *tmp;
- int success = -1;
-
- if ((tmp = BN_new()) == NULL) {
- error("%s: BN_new", __func__);
- return NULL;
- }
- if ((r = BN_new()) == NULL) {
- error("%s: BN_new failed", __func__);
- goto out;
- }
- if (BN_set_word(tmp, 2) != 1) {
- error("%s: BN_set_word(tmp, 2)", __func__);
- goto out;
- }
- if (BN_sub(tmp, high, tmp) == -1) {
- error("%s: BN_sub failed (tmp = high - 2)", __func__);
- goto out;
- }
- if (BN_rand_range(r, tmp) == -1) {
- error("%s: BN_rand_range failed", __func__);
- goto out;
- }
- if (BN_set_word(tmp, 2) != 1) {
- error("%s: BN_set_word(tmp, 2)", __func__);
- goto out;
- }
- if (BN_add(r, r, tmp) == -1) {
- error("%s: BN_add failed (r = r + 2)", __func__);
- goto out;
- }
- success = 0;
- out:
- BN_clear_free(tmp);
- if (success == 0)
- return r;
- BN_clear_free(r);
- return NULL;
-}
-
-/*
- * Hash contents of buffer 'b' with hash 'md'. Returns 0 on success,
- * with digest via 'digestp' (caller to free) and length via 'lenp'.
- * Returns -1 on failure.
- */
-int
-hash_buffer(const u_char *buf, u_int len, const EVP_MD *md,
- u_char **digestp, u_int *lenp)
-{
- u_char digest[EVP_MAX_MD_SIZE];
- u_int digest_len;
- EVP_MD_CTX evp_md_ctx;
- int success = -1;
-
- EVP_MD_CTX_init(&evp_md_ctx);
-
- if (EVP_DigestInit_ex(&evp_md_ctx, md, NULL) != 1) {
- error("%s: EVP_DigestInit_ex", __func__);
- goto out;
- }
- if (EVP_DigestUpdate(&evp_md_ctx, buf, len) != 1) {
- error("%s: EVP_DigestUpdate", __func__);
- goto out;
- }
- if (EVP_DigestFinal_ex(&evp_md_ctx, digest, &digest_len) != 1) {
- error("%s: EVP_DigestFinal_ex", __func__);
- goto out;
- }
- *digestp = xmalloc(digest_len);
- *lenp = digest_len;
- memcpy(*digestp, digest, *lenp);
- success = 0;
- out:
- EVP_MD_CTX_cleanup(&evp_md_ctx);
- bzero(digest, sizeof(digest));
- digest_len = 0;
- return success;
-}
-
-/* print formatted string followed by bignum */
-void
-jpake_debug3_bn(const BIGNUM *n, const char *fmt, ...)
-{
- char *out, *h;
- va_list args;
-
- out = NULL;
- va_start(args, fmt);
- vasprintf(&out, fmt, args);
- va_end(args);
- if (out == NULL)
- fatal("%s: vasprintf failed", __func__);
-
- if (n == NULL)
- debug3("%s(null)", out);
- else {
- h = BN_bn2hex(n);
- debug3("%s0x%s", out, h);
- free(h);
- }
- free(out);
-}
-
-/* print formatted string followed by buffer contents in hex */
-void
-jpake_debug3_buf(const u_char *buf, u_int len, const char *fmt, ...)
-{
- char *out, h[65];
- u_int i, j;
- va_list args;
-
- out = NULL;
- va_start(args, fmt);
- vasprintf(&out, fmt, args);
- va_end(args);
- if (out == NULL)
- fatal("%s: vasprintf failed", __func__);
-
- debug3("%s length %u%s", out, len, buf == NULL ? " (null)" : "");
- free(out);
- if (buf == NULL)
- return;
-
- *h = '\0';
- for (i = j = 0; i < len; i++) {
- snprintf(h + j, sizeof(h) - j, "%02x", buf[i]);
- j += 2;
- if (j >= sizeof(h) - 1 || i == len - 1) {
- debug3(" %s", h);
- *h = '\0';
- j = 0;
- }
- }
+ return modp_group_from_g_and_safe_p(JPAKE_GROUP_G, JPAKE_GROUP_P);
}
struct jpake_ctx *
return ret;
}
-
void
jpake_free(struct jpake_ctx *pctx)
{
/* Shared parts of step 1 exchange calculation */
void
-jpake_step1(struct jpake_group *grp,
+jpake_step1(struct modp_group *grp,
u_char **id, u_int *id_len,
BIGNUM **priv1, BIGNUM **priv2, BIGNUM **g_priv1, BIGNUM **g_priv2,
u_char **priv1_proof, u_int *priv1_proof_len,
fatal("%s: BN_mod_exp", __func__);
/* Generate proofs for holding x1/x3 and x2/x4 */
- if (schnorr_sign(grp->p, grp->q, grp->g,
+ if (schnorr_sign_buf(grp->p, grp->q, grp->g,
*priv1, *g_priv1, *id, *id_len,
priv1_proof, priv1_proof_len) != 0)
fatal("%s: schnorr_sign", __func__);
- if (schnorr_sign(grp->p, grp->q, grp->g,
+ if (schnorr_sign_buf(grp->p, grp->q, grp->g,
*priv2, *g_priv2, *id, *id_len,
priv2_proof, priv2_proof_len) != 0)
fatal("%s: schnorr_sign", __func__);
/* Shared parts of step 2 exchange calculation */
void
-jpake_step2(struct jpake_group *grp, BIGNUM *s,
+jpake_step2(struct modp_group *grp, BIGNUM *s,
BIGNUM *mypub1, BIGNUM *theirpub1, BIGNUM *theirpub2, BIGNUM *mypriv2,
const u_char *theirid, u_int theirid_len,
const u_char *myid, u_int myid_len,
if (BN_cmp(theirpub2, BN_value_one()) <= 0)
fatal("%s: theirpub2 <= 1", __func__);
- if (schnorr_verify(grp->p, grp->q, grp->g, theirpub1,
+ if (schnorr_verify_buf(grp->p, grp->q, grp->g, theirpub1,
theirid, theirid_len, theirpub1_proof, theirpub1_proof_len) != 1)
fatal("%s: schnorr_verify theirpub1 failed", __func__);
- if (schnorr_verify(grp->p, grp->q, grp->g, theirpub2,
+ if (schnorr_verify_buf(grp->p, grp->q, grp->g, theirpub2,
theirid, theirid_len, theirpub2_proof, theirpub2_proof_len) != 1)
fatal("%s: schnorr_verify theirpub2 failed", __func__);
JPAKE_DEBUG_BN((exponent, "%s: exponent = ", __func__));
/* Note the generator here is 'tmp', not g */
- if (schnorr_sign(grp->p, grp->q, tmp, exponent, *newpub,
+ if (schnorr_sign_buf(grp->p, grp->q, tmp, exponent, *newpub,
myid, myid_len,
newpub_exponent_proof, newpub_exponent_proof_len) != 0)
fatal("%s: schnorr_sign newpub", __func__);
/* Shared parts of key derivation and confirmation calculation */
void
-jpake_key_confirm(struct jpake_group *grp, BIGNUM *s, BIGNUM *step2_val,
+jpake_key_confirm(struct modp_group *grp, BIGNUM *s, BIGNUM *step2_val,
BIGNUM *mypriv2, BIGNUM *mypub1, BIGNUM *mypub2,
BIGNUM *theirpub1, BIGNUM *theirpub2,
const u_char *my_id, u_int my_id_len,
JPAKE_DEBUG_BN((tmp, "%s: tmp = ", __func__));
- if (schnorr_verify(grp->p, grp->q, tmp, step2_val,
+ if (schnorr_verify_buf(grp->p, grp->q, tmp, step2_val,
their_id, their_id_len,
theirpriv2_s_proof, theirpriv2_s_proof_len) != 1)
fatal("%s: schnorr_verify theirpriv2_s_proof failed", __func__);
-/* $OpenBSD: jpake.h,v 1.1 2008/11/04 08:22:13 djm Exp $ */
+/* $OpenBSD: jpake.h,v 1.2 2009/03/05 07:18:19 djm Exp $ */
/*
* Copyright (c) 2008 Damien Miller. All rights reserved.
*
# define JPAKE_DEBUG_BUF(a)
# define JPAKE_DEBUG_CTX(a)
#else
-# define JPAKE_DEBUG_BN(a) jpake_debug3_bn a
-# define JPAKE_DEBUG_BUF(a) jpake_debug3_buf a
+# define JPAKE_DEBUG_BN(a) debug3_bn a
+# define JPAKE_DEBUG_BUF(a) debug3_buf a
# define JPAKE_DEBUG_CTX(a) jpake_dump a
-#endif /* SCHNORR_DEBUG */
-
-struct jpake_group {
- BIGNUM *p, *q, *g;
-};
+#endif /* JPAKE_DEBUG */
#define KZP_ID_LEN 16 /* Length of client and server IDs */
struct jpake_ctx {
/* Parameters */
- struct jpake_group *grp;
+ struct modp_group *grp;
/* Private values shared by client and server */
BIGNUM *s; /* Secret (salted, crypted password) */
};
/* jpake.c */
-struct jpake_group *jpake_default_group(void);
-BIGNUM *bn_rand_range_gt_one(const BIGNUM *high);
-int hash_buffer(const u_char *, u_int, const EVP_MD *, u_char **, u_int *);
-void jpake_debug3_bn(const BIGNUM *, const char *, ...)
- __attribute__((__nonnull__ (2)))
- __attribute__((format(printf, 2, 3)));
-void jpake_debug3_buf(const u_char *, u_int, const char *, ...)
- __attribute__((__nonnull__ (3)))
- __attribute__((format(printf, 3, 4)));
+struct modp_group *jpake_default_group(void);
void jpake_dump(struct jpake_ctx *, const char *, ...)
__attribute__((__nonnull__ (2)))
__attribute__((format(printf, 2, 3)));
struct jpake_ctx *jpake_new(void);
void jpake_free(struct jpake_ctx *);
-void jpake_step1(struct jpake_group *, u_char **, u_int *,
+void jpake_step1(struct modp_group *, u_char **, u_int *,
BIGNUM **, BIGNUM **, BIGNUM **, BIGNUM **,
u_char **, u_int *, u_char **, u_int *);
-void jpake_step2(struct jpake_group *, BIGNUM *,
+void jpake_step2(struct modp_group *, BIGNUM *,
BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
const u_char *, u_int, const u_char *, u_int,
const u_char *, u_int, const u_char *, u_int,
const u_char *, u_int,
u_char **, u_int *);
-void jpake_key_confirm(struct jpake_group *, BIGNUM *, BIGNUM *,
+void jpake_key_confirm(struct modp_group *, BIGNUM *, BIGNUM *,
BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
const u_char *, u_int, const u_char *, u_int,
const u_char *, u_int, const u_char *, u_int,
int jpake_check_confirm(const BIGNUM *, const u_char *, u_int,
const u_char *, u_int, const u_char *, u_int);
-/* schnorr.c */
-int schnorr_sign(const BIGNUM *, const BIGNUM *, const BIGNUM *,
- const BIGNUM *, const BIGNUM *, const u_char *, u_int ,
- u_char **, u_int *);
-int schnorr_verify(const BIGNUM *, const BIGNUM *, const BIGNUM *,
- const BIGNUM *, const u_char *, u_int,
- const u_char *, u_int);
-
#endif /* JPAKE_H */
-/* $OpenBSD: kex.c,v 1.80 2008/09/06 12:24:13 djm Exp $ */
+/* $OpenBSD: kex.c,v 1.81 2009/05/27 06:34:36 andreas Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
#include "dispatch.h"
#include "monitor.h"
-#define KEX_COOKIE_LEN 16
-
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
# if defined(HAVE_EVP_SHA256)
# define evp_ssh_sha256 EVP_sha256
-/* $OpenBSD: kex.h,v 1.46 2007/06/07 19:37:34 pvalchev Exp $ */
+/* $OpenBSD: kex.h,v 1.47 2009/05/27 06:34:36 andreas Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
#include <openssl/evp.h>
#include <openssl/hmac.h>
+#define KEX_COOKIE_LEN 16
+
#define KEX_DH1 "diffie-hellman-group1-sha1"
#define KEX_DH14 "diffie-hellman-group14-sha1"
#define KEX_DHGEX_SHA1 "diffie-hellman-group-exchange-sha1"
-/* $OpenBSD: kexdhs.c,v 1.9 2006/11/06 21:25:28 markus Exp $ */
+/* $OpenBSD: kexdhs.c,v 1.10 2009/06/21 07:37:15 dtucker Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
}
/* sign H */
- PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, hashlen));
+ if (PRIVSEP(key_sign(server_host_key, &signature, &slen, hash,
+ hashlen)) < 0)
+ fatal("kexdh_server: key_sign failed");
/* destroy_sensitive_data(); */
-/* $OpenBSD: kexgexs.c,v 1.11 2009/01/01 21:17:36 djm Exp $ */
+/* $OpenBSD: kexgexs.c,v 1.12 2009/06/21 07:37:15 dtucker Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
* Copyright (c) 2001 Markus Friedl. All rights reserved.
}
/* sign H */
- PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, hashlen));
+ if (PRIVSEP(key_sign(server_host_key, &signature, &slen, hash,
+ hashlen)) < 0)
+ fatal("kexgex_server: key_sign failed");
/* destroy_sensitive_data(); */
-/* $OpenBSD: monitor.c,v 1.101 2009/02/12 03:26:22 djm Exp $ */
+/* $OpenBSD: monitor.c,v 1.104 2009/06/12 20:43:22 andreas Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
#include "compat.h"
#include "ssh2.h"
#include "jpake.h"
+#include "roaming.h"
#ifdef GSSAPI
static Gssctxt *gsscontext = NULL;
extern z_stream incoming_stream;
extern z_stream outgoing_stream;
extern u_char session_id[];
-extern Buffer input, output;
extern Buffer auth_debug;
extern int auth_debug_init;
extern Buffer loginmsg;
u_int ilen;
u_char *output;
u_int olen;
+ u_int64_t sent_bytes;
+ u_int64_t recv_bytes;
} child_state;
/* Functions on the monitor that answer unprivileged requests */
/* Network I/O buffers */
/* XXX inefficient for large buffers, need: buffer_init_from_string */
- buffer_clear(&input);
- buffer_append(&input, child_state.input, child_state.ilen);
+ buffer_clear(packet_get_input());
+ buffer_append(packet_get_input(), child_state.input, child_state.ilen);
memset(child_state.input, 0, child_state.ilen);
xfree(child_state.input);
- buffer_clear(&output);
- buffer_append(&output, child_state.output, child_state.olen);
+ buffer_clear(packet_get_output());
+ buffer_append(packet_get_output(), child_state.output,
+ child_state.olen);
memset(child_state.output, 0, child_state.olen);
xfree(child_state.output);
+
+ /* Roaming */
+ if (compat20)
+ roam_set_bytes(child_state.sent_bytes, child_state.recv_bytes);
}
static Kex *
child_state.input = buffer_get_string(&m, &child_state.ilen);
child_state.output = buffer_get_string(&m, &child_state.olen);
+ /* Roaming */
+ if (compat20) {
+ child_state.sent_bytes = buffer_get_int64(&m);
+ child_state.recv_bytes = buffer_get_int64(&m);
+ }
+
buffer_free(&m);
}
-/* $OpenBSD: monitor_mm.c,v 1.15 2006/08/03 03:34:42 deraadt Exp $ */
+/* $OpenBSD: monitor_mm.c,v 1.16 2009/06/22 05:39:28 dtucker Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
-/* $OpenBSD: monitor_wrap.c,v 1.64 2008/11/04 08:22:13 djm Exp $ */
+/* $OpenBSD: monitor_wrap.c,v 1.68 2009/06/22 05:39:28 dtucker Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
#include "atomicio.h"
#include "monitor_fdpass.h"
#include "misc.h"
+#include "schnorr.h"
#include "jpake.h"
#include "channels.h"
#include "session.h"
#include "servconf.h"
+#include "roaming.h"
/* Imports */
extern int compat20;
-extern Newkeys *newkeys[];
extern z_stream incoming_stream;
extern z_stream outgoing_stream;
extern struct monitor *pmonitor;
-extern Buffer input, output;
extern Buffer loginmsg;
extern ServerOptions options;
Enc *enc;
Mac *mac;
Comp *comp;
- Newkeys *newkey = newkeys[mode];
+ Newkeys *newkey = (Newkeys *)packet_get_newkeys(mode);
debug3("%s: converting %p", __func__, newkey);
void
mm_send_keystate(struct monitor *monitor)
{
- Buffer m;
+ Buffer m, *input, *output;
u_char *blob, *p;
u_int bloblen, plen;
u_int32_t seqnr, packets;
}
debug3("%s: Sending new keys: %p %p",
- __func__, newkeys[MODE_OUT], newkeys[MODE_IN]);
+ __func__, packet_get_newkeys(MODE_OUT),
+ packet_get_newkeys(MODE_IN));
/* Keys from Kex */
if (!mm_newkeys_to_blob(MODE_OUT, &blob, &bloblen))
buffer_put_string(&m, &incoming_stream, sizeof(incoming_stream));
/* Network I/O buffers */
- buffer_put_string(&m, buffer_ptr(&input), buffer_len(&input));
- buffer_put_string(&m, buffer_ptr(&output), buffer_len(&output));
+ input = (Buffer *)packet_get_input();
+ output = (Buffer *)packet_get_output();
+ buffer_put_string(&m, buffer_ptr(input), buffer_len(input));
+ buffer_put_string(&m, buffer_ptr(output), buffer_len(output));
+
+ /* Roaming */
+ if (compat20) {
+ buffer_put_int64(&m, get_sent_bytes());
+ buffer_put_int64(&m, get_recv_bytes());
+ }
mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m);
debug3("%s: Finished sending state", __func__);
}
void
-mm_jpake_step1(struct jpake_group *grp,
+mm_jpake_step1(struct modp_group *grp,
u_char **id, u_int *id_len,
BIGNUM **priv1, BIGNUM **priv2, BIGNUM **g_priv1, BIGNUM **g_priv2,
u_char **priv1_proof, u_int *priv1_proof_len,
}
void
-mm_jpake_step2(struct jpake_group *grp, BIGNUM *s,
+mm_jpake_step2(struct modp_group *grp, BIGNUM *s,
BIGNUM *mypub1, BIGNUM *theirpub1, BIGNUM *theirpub2, BIGNUM *mypriv2,
const u_char *theirid, u_int theirid_len,
const u_char *myid, u_int myid_len,
}
void
-mm_jpake_key_confirm(struct jpake_group *grp, BIGNUM *s, BIGNUM *step2_val,
+mm_jpake_key_confirm(struct modp_group *grp, BIGNUM *s, BIGNUM *step2_val,
BIGNUM *mypriv2, BIGNUM *mypub1, BIGNUM *mypub2,
BIGNUM *theirpub1, BIGNUM *theirpub2,
const u_char *my_id, u_int my_id_len,
-/* $OpenBSD: monitor_wrap.h,v 1.21 2008/11/04 08:22:13 djm Exp $ */
+/* $OpenBSD: monitor_wrap.h,v 1.22 2009/03/05 07:18:19 djm Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
int mm_skey_respond(void *, u_int, char **);
/* jpake */
-struct jpake_group;
+struct modp_group;
void mm_auth2_jpake_get_pwdata(struct Authctxt *, BIGNUM **, char **, char **);
-void mm_jpake_step1(struct jpake_group *, u_char **, u_int *,
+void mm_jpake_step1(struct modp_group *, u_char **, u_int *,
BIGNUM **, BIGNUM **, BIGNUM **, BIGNUM **,
u_char **, u_int *, u_char **, u_int *);
-void mm_jpake_step2(struct jpake_group *, BIGNUM *,
+void mm_jpake_step2(struct modp_group *, BIGNUM *,
BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
const u_char *, u_int, const u_char *, u_int,
const u_char *, u_int, const u_char *, u_int,
BIGNUM **, u_char **, u_int *);
-void mm_jpake_key_confirm(struct jpake_group *, BIGNUM *, BIGNUM *,
+void mm_jpake_key_confirm(struct modp_group *, BIGNUM *, BIGNUM *,
BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *,
const u_char *, u_int, const u_char *, u_int,
const u_char *, u_int, const u_char *, u_int,
#endif
#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/utsname.h>
-#include <sys/vfs.h>
#include <fcntl.h>
#include <stdlib.h>
#include <windows.h>
#include "xmalloc.h"
-#define is_winnt (GetVersion() < 0x80000000)
-
-#define ntsec_on(c) ((c) && strstr((c),"ntsec") && !strstr((c),"nontsec"))
-#define ntsec_off(c) ((c) && strstr((c),"nontsec"))
-#define ntea_on(c) ((c) && strstr((c),"ntea") && !strstr((c),"nontea"))
int
binary_open(const char *filename, int flags, ...)
return (ret);
}
-#define HAS_CREATE_TOKEN 1
-#define HAS_NTSEC_BY_DEFAULT 2
-#define HAS_CREATE_TOKEN_WO_NTSEC 3
-
-static int
-has_capability(int what)
-{
- static int inited;
- static int has_create_token;
- static int has_ntsec_by_default;
- static int has_create_token_wo_ntsec;
-
- /*
- * has_capability() basically calls uname() and checks if
- * specific capabilities of Cygwin can be evaluated from that.
- * This simplifies the calling functions which only have to ask
- * for a capability using has_capability() instead of having
- * to figure that out by themselves.
- */
- if (!inited) {
- struct utsname uts;
-
- if (!uname(&uts)) {
- int major_high = 0, major_low = 0, minor = 0;
- int api_major_version = 0, api_minor_version = 0;
- char *c;
-
- sscanf(uts.release, "%d.%d.%d", &major_high,
- &major_low, &minor);
- if ((c = strchr(uts.release, '(')) != NULL) {
- sscanf(c + 1, "%d.%d", &api_major_version,
- &api_minor_version);
- }
- if (major_high > 1 ||
- (major_high == 1 && (major_low > 3 ||
- (major_low == 3 && minor >= 2))))
- has_create_token = 1;
- if (api_major_version > 0 || api_minor_version >= 56)
- has_ntsec_by_default = 1;
- if (major_high > 1 ||
- (major_high == 1 && major_low >= 5))
- has_create_token_wo_ntsec = 1;
- inited = 1;
- }
- }
- switch (what) {
- case HAS_CREATE_TOKEN:
- return (has_create_token);
- case HAS_NTSEC_BY_DEFAULT:
- return (has_ntsec_by_default);
- case HAS_CREATE_TOKEN_WO_NTSEC:
- return (has_create_token_wo_ntsec);
- }
- return (0);
-}
-
-int
-check_nt_auth(int pwd_authenticated, struct passwd *pw)
-{
- /*
- * The only authentication which is able to change the user
- * context on NT systems is the password authentication. So
- * we deny all requsts for changing the user context if another
- * authentication method is used.
- *
- * This doesn't apply to Cygwin versions >= 1.3.2 anymore which
- * uses the undocumented NtCreateToken() call to create a user
- * token if the process has the appropriate privileges and if
- * CYGWIN ntsec setting is on.
- */
- static int has_create_token = -1;
-
- if (pw == NULL)
- return 0;
- if (is_winnt) {
- if (has_create_token < 0) {
- char *cygwin = getenv("CYGWIN");
-
- has_create_token = 0;
- if (has_capability(HAS_CREATE_TOKEN) &&
- (ntsec_on(cygwin) ||
- (has_capability(HAS_NTSEC_BY_DEFAULT) &&
- !ntsec_off(cygwin)) ||
- has_capability(HAS_CREATE_TOKEN_WO_NTSEC)))
- has_create_token = 1;
- }
- if (has_create_token < 1 &&
- !pwd_authenticated && geteuid() != pw->pw_uid)
- return (0);
- }
- return (1);
-}
-
int
check_ntsec(const char *filename)
{
return (pathconf(filename, _PC_POSIX_PERMISSIONS));
}
-void
-register_9x_service(void)
-{
- HINSTANCE kerneldll;
- DWORD (*RegisterServiceProcess)(DWORD, DWORD);
-
- /* The service register mechanism in 9x/Me is pretty different from
- * NT/2K/XP. In NT/2K/XP we're using a special service starter
- * application to register and control sshd as service. This method
- * doesn't play nicely with 9x/Me. For that reason we register here
- * as service when running under 9x/Me. This function is only called
- * by the child sshd when it's going to daemonize.
- */
- if (is_winnt)
- return;
- if (!(kerneldll = LoadLibrary("KERNEL32.DLL")))
- return;
- if (!(RegisterServiceProcess = (DWORD (*)(DWORD, DWORD))
- GetProcAddress(kerneldll, "RegisterServiceProcess")))
- return;
- RegisterServiceProcess(0, 1);
-}
-
#define NL(x) x, (sizeof (x) - 1)
#define WENV_SIZ (sizeof (wenv_arr) / sizeof (wenv_arr[0]))
#ifdef HAVE_CYGWIN
#undef ERROR
-#define is_winnt (GetVersion() < 0x80000000)
#include <windows.h>
#include <sys/cygwin.h>
int binary_open(const char *, int , ...);
int binary_pipe(int fd[2]);
-int check_nt_auth(int, struct passwd *);
int check_ntsec(const char *);
-void register_9x_service(void);
char **fetch_windows_environment(void);
void free_windows_environment(char **);
case -1:
return (-1);
case 0:
-#ifdef HAVE_CYGWIN
- register_9x_service();
-#endif
break;
default:
-#ifdef HAVE_CYGWIN
- /*
- * This sleep avoids a race condition which kills the
- * child process if parent is started by a NT/W2K service.
- */
- sleep(1);
-#endif
_exit(0);
}
/* ************** */
-#define ANSWER_BUFFER_SIZE 1024*64
+#define ANSWER_BUFFER_SIZE 0xffff
struct dns_query {
char *name;
}
#endif
+#ifdef OPENSSL_EVP_DIGESTUPDATE_VOID
+int
+ssh_EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, unsigned int cnt)
+{
+ EVP_DigestUpdate(ctx, d, cnt);
+ return 1;
+}
+#endif
+
#ifdef USE_OPENSSL_ENGINE
void
ssh_SSLeay_add_all_algorithms(void)
# define EVP_CIPHER_CTX_cleanup(a) ssh_EVP_CIPHER_CTX_cleanup((a))
# endif /* SSH_OLD_EVP */
+# ifdef OPENSSL_EVP_DIGESTUPDATE_VOID
+# define EVP_DigestUpdate(a,b,c) ssh_EVP_DigestUpdate((a),(b),(c))
+# endif
+
# ifdef USE_OPENSSL_ENGINE
# ifdef SSLeay_add_all_algorithms
# undef SSLeay_add_all_algorithms
#include "port-aix.h"
+static char *lastlogin_msg = NULL;
+
# ifdef HAVE_SETAUTHDB
static char old_registry[REGISTRY_SIZE] = "";
# endif
Buffer *loginmsg)
{
char *msg = NULL;
- static int msg_done = 0;
int success = 0;
aix_setauthdb(user);
if (loginsuccess((char *)user, (char *)host, (char *)ttynm, &msg) == 0) {
success = 1;
- if (msg != NULL && loginmsg != NULL && !msg_done) {
+ if (msg != NULL) {
debug("AIX/loginsuccess: msg %s", msg);
- buffer_append(loginmsg, msg, strlen(msg));
- xfree(msg);
- msg_done = 1;
+ if (lastlogin_msg == NULL)
+ lastlogin_msg = msg;
}
}
aix_restoreauthdb();
return (success);
}
+char *
+sys_auth_get_lastlogin_msg(const char *user, uid_t uid)
+{
+ char *msg = lastlogin_msg;
+
+ lastlogin_msg = NULL;
+ return msg;
+}
+
# ifdef CUSTOM_FAILED_LOGIN
/*
* record_failed_login: generic "login failed" interface function
# include <sys/timers.h>
#endif
+/* for setpcred and friends */
+#ifdef HAVE_USERSEC_H
+# include <usersec.h>
+#endif
+
/*
* According to the setauthdb man page, AIX password registries must be 15
* chars or less plus terminating NUL.
int sys_auth_allowed_user(struct passwd *, Buffer *);
# define CUSTOM_SYS_AUTH_RECORD_LOGIN 1
int sys_auth_record_login(const char *, const char *, const char *, Buffer *);
+# define CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG
+char *sys_auth_get_lastlogin_msg(const char *, uid_t);
# define CUSTOM_FAILED_LOGIN 1
#endif
-/* $OpenBSD: packet.c,v 1.160 2009/02/13 11:50:21 markus Exp $ */
+/* $OpenBSD: packet.c,v 1.166 2009/06/27 09:29:06 andreas Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
#include "canohost.h"
#include "misc.h"
#include "ssh.h"
+#include "roaming.h"
#ifdef PACKET_DEBUG
#define DBG(x) x
#define PACKET_MAX_SIZE (256 * 1024)
-/*
- * This variable contains the file descriptors used for communicating with
- * the other side. connection_in is used for reading; connection_out for
- * writing. These can be the same descriptor, in which case it is assumed to
- * be a socket.
- */
-static int connection_in = -1;
-static int connection_out = -1;
+struct packet_state {
+ u_int32_t seqnr;
+ u_int32_t packets;
+ u_int64_t blocks;
+ u_int64_t bytes;
+};
-/* Protocol flags for the remote side. */
-static u_int remote_protocol_flags = 0;
+struct packet {
+ TAILQ_ENTRY(packet) next;
+ u_char type;
+ Buffer payload;
+};
-/* Encryption context for receiving data. This is only used for decryption. */
-static CipherContext receive_context;
+struct session_state {
+ /*
+ * This variable contains the file descriptors used for
+ * communicating with the other side. connection_in is used for
+ * reading; connection_out for writing. These can be the same
+ * descriptor, in which case it is assumed to be a socket.
+ */
+ int connection_in;
+ int connection_out;
-/* Encryption context for sending data. This is only used for encryption. */
-static CipherContext send_context;
+ /* Protocol flags for the remote side. */
+ u_int remote_protocol_flags;
-/* Buffer for raw input data from the socket. */
-Buffer input;
+ /* Encryption context for receiving data. Only used for decryption. */
+ CipherContext receive_context;
-/* Buffer for raw output data going to the socket. */
-Buffer output;
+ /* Encryption context for sending data. Only used for encryption. */
+ CipherContext send_context;
-/* Buffer for the partial outgoing packet being constructed. */
-static Buffer outgoing_packet;
+ /* Buffer for raw input data from the socket. */
+ Buffer input;
-/* Buffer for the incoming packet currently being processed. */
-static Buffer incoming_packet;
+ /* Buffer for raw output data going to the socket. */
+ Buffer output;
-/* Scratch buffer for packet compression/decompression. */
-static Buffer compression_buffer;
-static int compression_buffer_ready = 0;
+ /* Buffer for the partial outgoing packet being constructed. */
+ Buffer outgoing_packet;
-/* Flag indicating whether packet compression/decompression is enabled. */
-static int packet_compression = 0;
+ /* Buffer for the incoming packet currently being processed. */
+ Buffer incoming_packet;
-/* default maximum packet size */
-u_int max_packet_size = 32768;
+ /* Scratch buffer for packet compression/decompression. */
+ Buffer compression_buffer;
+ int compression_buffer_ready;
-/* Flag indicating whether this module has been initialized. */
-static int initialized = 0;
+ /*
+ * Flag indicating whether packet compression/decompression is
+ * enabled.
+ */
+ int packet_compression;
-/* Set to true if the connection is interactive. */
-static int interactive_mode = 0;
+ /* default maximum packet size */
+ u_int max_packet_size;
-/* Set to true if we are the server side. */
-static int server_side = 0;
+ /* Flag indicating whether this module has been initialized. */
+ int initialized;
-/* Set to true if we are authenticated. */
-static int after_authentication = 0;
+ /* Set to true if the connection is interactive. */
+ int interactive_mode;
-int keep_alive_timeouts = 0;
+ /* Set to true if we are the server side. */
+ int server_side;
-/* Set to the maximum time that we will wait to send or receive a packet */
-static int packet_timeout_ms = -1;
+ /* Set to true if we are authenticated. */
+ int after_authentication;
-/* Session key information for Encryption and MAC */
-Newkeys *newkeys[MODE_MAX];
-static struct packet_state {
- u_int32_t seqnr;
- u_int32_t packets;
- u_int64_t blocks;
- u_int64_t bytes;
-} p_read, p_send;
+ int keep_alive_timeouts;
-static u_int64_t max_blocks_in, max_blocks_out;
-static u_int32_t rekey_limit;
+ /* The maximum time that we will wait to send or receive a packet */
+ int packet_timeout_ms;
-/* Session key for protocol v1 */
-static u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
-static u_int ssh1_keylen;
+ /* Session key information for Encryption and MAC */
+ Newkeys *newkeys[MODE_MAX];
+ struct packet_state p_read, p_send;
-/* roundup current message to extra_pad bytes */
-static u_char extra_pad = 0;
+ u_int64_t max_blocks_in, max_blocks_out;
+ u_int32_t rekey_limit;
-/* XXX discard incoming data after MAC error */
-static u_int packet_discard = 0;
-static Mac *packet_discard_mac = NULL;
+ /* Session key for protocol v1 */
+ u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
+ u_int ssh1_keylen;
-struct packet {
- TAILQ_ENTRY(packet) next;
- u_char type;
- Buffer payload;
+ /* roundup current message to extra_pad bytes */
+ u_char extra_pad;
+
+ /* XXX discard incoming data after MAC error */
+ u_int packet_discard;
+ Mac *packet_discard_mac;
+
+ /* Used in packet_read_poll2() */
+ u_int packlen;
+
+ /* Used in packet_send2 */
+ int rekeying;
+
+ /* Used in packet_set_interactive */
+ int set_interactive_called;
+
+ /* Used in packet_set_maxsize */
+ int set_maxsize_called;
+
+ TAILQ_HEAD(, packet) outgoing;
};
-TAILQ_HEAD(, packet) outgoing;
+
+static struct session_state *active_state, *backup_state;
+
+static struct session_state *
+alloc_session_state(void)
+{
+ struct session_state *s = xcalloc(1, sizeof(*s));
+
+ s->connection_in = -1;
+ s->connection_out = -1;
+ s->max_packet_size = 32768;
+ s->packet_timeout_ms = -1;
+ return s;
+}
/*
* Sets the descriptors used for communication. Disables encryption until
if (none == NULL)
fatal("packet_set_connection: cannot load cipher 'none'");
- connection_in = fd_in;
- connection_out = fd_out;
- cipher_init(&send_context, none, (const u_char *)"",
+ if (active_state == NULL)
+ active_state = alloc_session_state();
+ active_state->connection_in = fd_in;
+ active_state->connection_out = fd_out;
+ cipher_init(&active_state->send_context, none, (const u_char *)"",
0, NULL, 0, CIPHER_ENCRYPT);
- cipher_init(&receive_context, none, (const u_char *)"",
+ cipher_init(&active_state->receive_context, none, (const u_char *)"",
0, NULL, 0, CIPHER_DECRYPT);
- newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL;
- if (!initialized) {
- initialized = 1;
- buffer_init(&input);
- buffer_init(&output);
- buffer_init(&outgoing_packet);
- buffer_init(&incoming_packet);
- TAILQ_INIT(&outgoing);
- p_send.packets = p_read.packets = 0;
+ active_state->newkeys[MODE_IN] = active_state->newkeys[MODE_OUT] = NULL;
+ if (!active_state->initialized) {
+ active_state->initialized = 1;
+ buffer_init(&active_state->input);
+ buffer_init(&active_state->output);
+ buffer_init(&active_state->outgoing_packet);
+ buffer_init(&active_state->incoming_packet);
+ TAILQ_INIT(&active_state->outgoing);
+ active_state->p_send.packets = active_state->p_read.packets = 0;
}
}
packet_set_timeout(int timeout, int count)
{
if (timeout == 0 || count == 0) {
- packet_timeout_ms = -1;
+ active_state->packet_timeout_ms = -1;
return;
}
if ((INT_MAX / 1000) / count < timeout)
- packet_timeout_ms = INT_MAX;
+ active_state->packet_timeout_ms = INT_MAX;
else
- packet_timeout_ms = timeout * count * 1000;
+ active_state->packet_timeout_ms = timeout * count * 1000;
}
static void
packet_stop_discard(void)
{
- if (packet_discard_mac) {
+ if (active_state->packet_discard_mac) {
char buf[1024];
memset(buf, 'a', sizeof(buf));
- while (buffer_len(&incoming_packet) < PACKET_MAX_SIZE)
- buffer_append(&incoming_packet, buf, sizeof(buf));
- (void) mac_compute(packet_discard_mac,
- p_read.seqnr,
- buffer_ptr(&incoming_packet),
+ while (buffer_len(&active_state->incoming_packet) <
+ PACKET_MAX_SIZE)
+ buffer_append(&active_state->incoming_packet, buf,
+ sizeof(buf));
+ (void) mac_compute(active_state->packet_discard_mac,
+ active_state->p_read.seqnr,
+ buffer_ptr(&active_state->incoming_packet),
PACKET_MAX_SIZE);
}
logit("Finished discarding for %.200s", get_remote_ipaddr());
if (enc == NULL || !cipher_is_cbc(enc->cipher))
packet_disconnect("Packet corrupt");
if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled)
- packet_discard_mac = mac;
- if (buffer_len(&input) >= discard)
+ active_state->packet_discard_mac = mac;
+ if (buffer_len(&active_state->input) >= discard)
packet_stop_discard();
- packet_discard = discard - buffer_len(&input);
+ active_state->packet_discard = discard -
+ buffer_len(&active_state->input);
}
/* Returns 1 if remote host is connected via socket, 0 if not. */
socklen_t fromlen, tolen;
/* filedescriptors in and out are the same, so it's a socket */
- if (connection_in == connection_out)
+ if (active_state->connection_in == active_state->connection_out)
return 1;
fromlen = sizeof(from);
memset(&from, 0, sizeof(from));
- if (getpeername(connection_in, (struct sockaddr *)&from, &fromlen) < 0)
+ if (getpeername(active_state->connection_in, (struct sockaddr *)&from,
+ &fromlen) < 0)
return 0;
tolen = sizeof(to);
memset(&to, 0, sizeof(to));
- if (getpeername(connection_out, (struct sockaddr *)&to, &tolen) < 0)
+ if (getpeername(active_state->connection_out, (struct sockaddr *)&to,
+ &tolen) < 0)
return 0;
if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0)
return 0;
CipherContext *cc;
if (mode == MODE_OUT)
- cc = &send_context;
+ cc = &active_state->send_context;
else
- cc = &receive_context;
+ cc = &active_state->receive_context;
cipher_get_keyiv(cc, iv, len);
}
CipherContext *cc;
if (mode == MODE_OUT)
- cc = &send_context;
+ cc = &active_state->send_context;
else
- cc = &receive_context;
+ cc = &active_state->receive_context;
return (cipher_get_keycontext(cc, dat));
}
CipherContext *cc;
if (mode == MODE_OUT)
- cc = &send_context;
+ cc = &active_state->send_context;
else
- cc = &receive_context;
+ cc = &active_state->receive_context;
cipher_set_keycontext(cc, dat);
}
CipherContext *cc;
if (mode == MODE_OUT)
- cc = &send_context;
+ cc = &active_state->send_context;
else
- cc = &receive_context;
+ cc = &active_state->receive_context;
return (cipher_get_keyiv_len(cc));
}
CipherContext *cc;
if (mode == MODE_OUT)
- cc = &send_context;
+ cc = &active_state->send_context;
else
- cc = &receive_context;
+ cc = &active_state->receive_context;
cipher_set_keyiv(cc, dat);
}
int
packet_get_ssh1_cipher(void)
{
- return (cipher_get_number(receive_context.cipher));
+ return (cipher_get_number(active_state->receive_context.cipher));
}
void
{
struct packet_state *state;
- state = (mode == MODE_IN) ? &p_read : &p_send;
+ state = (mode == MODE_IN) ?
+ &active_state->p_read : &active_state->p_send;
if (seqnr)
*seqnr = state->seqnr;
if (blocks)
{
struct packet_state *state;
- state = (mode == MODE_IN) ? &p_read : &p_send;
+ state = (mode == MODE_IN) ?
+ &active_state->p_read : &active_state->p_send;
state->seqnr = seqnr;
state->blocks = blocks;
state->packets = packets;
socklen_t tolen = sizeof(to);
memset(&to, 0, sizeof(to));
- if (getsockname(connection_out, (struct sockaddr *)&to, &tolen) < 0)
+ if (getsockname(active_state->connection_out, (struct sockaddr *)&to,
+ &tolen) < 0)
return 0;
if (to.ss_family == AF_INET)
return 1;
packet_set_nonblocking(void)
{
/* Set the socket into non-blocking mode. */
- set_nonblock(connection_in);
+ set_nonblock(active_state->connection_in);
- if (connection_out != connection_in)
- set_nonblock(connection_out);
+ if (active_state->connection_out != active_state->connection_in)
+ set_nonblock(active_state->connection_out);
}
/* Returns the socket used for reading. */
int
packet_get_connection_in(void)
{
- return connection_in;
+ return active_state->connection_in;
}
/* Returns the descriptor used for writing. */
int
packet_get_connection_out(void)
{
- return connection_out;
+ return active_state->connection_out;
}
/* Closes the connection and clears and frees internal data structures. */
void
packet_close(void)
{
- if (!initialized)
+ if (!active_state->initialized)
return;
- initialized = 0;
- if (connection_in == connection_out) {
- shutdown(connection_out, SHUT_RDWR);
- close(connection_out);
+ active_state->initialized = 0;
+ if (active_state->connection_in == active_state->connection_out) {
+ shutdown(active_state->connection_out, SHUT_RDWR);
+ close(active_state->connection_out);
} else {
- close(connection_in);
- close(connection_out);
+ close(active_state->connection_in);
+ close(active_state->connection_out);
}
- buffer_free(&input);
- buffer_free(&output);
- buffer_free(&outgoing_packet);
- buffer_free(&incoming_packet);
- if (compression_buffer_ready) {
- buffer_free(&compression_buffer);
+ buffer_free(&active_state->input);
+ buffer_free(&active_state->output);
+ buffer_free(&active_state->outgoing_packet);
+ buffer_free(&active_state->incoming_packet);
+ if (active_state->compression_buffer_ready) {
+ buffer_free(&active_state->compression_buffer);
buffer_compress_uninit();
}
- cipher_cleanup(&send_context);
- cipher_cleanup(&receive_context);
+ cipher_cleanup(&active_state->send_context);
+ cipher_cleanup(&active_state->receive_context);
}
/* Sets remote side protocol flags. */
void
packet_set_protocol_flags(u_int protocol_flags)
{
- remote_protocol_flags = protocol_flags;
+ active_state->remote_protocol_flags = protocol_flags;
}
/* Returns the remote protocol flags set earlier by the above function. */
u_int
packet_get_protocol_flags(void)
{
- return remote_protocol_flags;
+ return active_state->remote_protocol_flags;
}
/*
static void
packet_init_compression(void)
{
- if (compression_buffer_ready == 1)
+ if (active_state->compression_buffer_ready == 1)
return;
- compression_buffer_ready = 1;
- buffer_init(&compression_buffer);
+ active_state->compression_buffer_ready = 1;
+ buffer_init(&active_state->compression_buffer);
}
void
packet_start_compression(int level)
{
- if (packet_compression && !compat20)
+ if (active_state->packet_compression && !compat20)
fatal("Compression already enabled.");
- packet_compression = 1;
+ active_state->packet_compression = 1;
packet_init_compression();
buffer_compress_init_send(level);
buffer_compress_init_recv();
fatal("packet_set_encryption_key: keylen too small: %d", keylen);
if (keylen > SSH_SESSION_KEY_LENGTH)
fatal("packet_set_encryption_key: keylen too big: %d", keylen);
- memcpy(ssh1_key, key, keylen);
- ssh1_keylen = keylen;
- cipher_init(&send_context, cipher, key, keylen, NULL, 0, CIPHER_ENCRYPT);
- cipher_init(&receive_context, cipher, key, keylen, NULL, 0, CIPHER_DECRYPT);
+ memcpy(active_state->ssh1_key, key, keylen);
+ active_state->ssh1_keylen = keylen;
+ cipher_init(&active_state->send_context, cipher, key, keylen, NULL,
+ 0, CIPHER_ENCRYPT);
+ cipher_init(&active_state->receive_context, cipher, key, keylen, NULL,
+ 0, CIPHER_DECRYPT);
}
u_int
packet_get_encryption_key(u_char *key)
{
if (key == NULL)
- return (ssh1_keylen);
- memcpy(key, ssh1_key, ssh1_keylen);
- return (ssh1_keylen);
+ return (active_state->ssh1_keylen);
+ memcpy(key, active_state->ssh1_key, active_state->ssh1_keylen);
+ return (active_state->ssh1_keylen);
}
/* Start constructing a packet to send. */
len = compat20 ? 6 : 9;
memset(buf, 0, len - 1);
buf[len - 1] = type;
- buffer_clear(&outgoing_packet);
- buffer_append(&outgoing_packet, buf, len);
+ buffer_clear(&active_state->outgoing_packet);
+ buffer_append(&active_state->outgoing_packet, buf, len);
}
/* Append payload. */
{
char ch = value;
- buffer_append(&outgoing_packet, &ch, 1);
+ buffer_append(&active_state->outgoing_packet, &ch, 1);
}
void
packet_put_int(u_int value)
{
- buffer_put_int(&outgoing_packet, value);
+ buffer_put_int(&active_state->outgoing_packet, value);
+}
+
+void
+packet_put_int64(u_int64_t value)
+{
+ buffer_put_int64(&active_state->outgoing_packet, value);
}
void
packet_put_string(const void *buf, u_int len)
{
- buffer_put_string(&outgoing_packet, buf, len);
+ buffer_put_string(&active_state->outgoing_packet, buf, len);
}
void
packet_put_cstring(const char *str)
{
- buffer_put_cstring(&outgoing_packet, str);
+ buffer_put_cstring(&active_state->outgoing_packet, str);
}
void
packet_put_raw(const void *buf, u_int len)
{
- buffer_append(&outgoing_packet, buf, len);
+ buffer_append(&active_state->outgoing_packet, buf, len);
}
void
packet_put_bignum(BIGNUM * value)
{
- buffer_put_bignum(&outgoing_packet, value);
+ buffer_put_bignum(&active_state->outgoing_packet, value);
}
void
packet_put_bignum2(BIGNUM * value)
{
- buffer_put_bignum2(&outgoing_packet, value);
+ buffer_put_bignum2(&active_state->outgoing_packet, value);
}
/*
* If using packet compression, compress the payload of the outgoing
* packet.
*/
- if (packet_compression) {
- buffer_clear(&compression_buffer);
+ if (active_state->packet_compression) {
+ buffer_clear(&active_state->compression_buffer);
/* Skip padding. */
- buffer_consume(&outgoing_packet, 8);
+ buffer_consume(&active_state->outgoing_packet, 8);
/* padding */
- buffer_append(&compression_buffer, "\0\0\0\0\0\0\0\0", 8);
- buffer_compress(&outgoing_packet, &compression_buffer);
- buffer_clear(&outgoing_packet);
- buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer),
- buffer_len(&compression_buffer));
+ buffer_append(&active_state->compression_buffer,
+ "\0\0\0\0\0\0\0\0", 8);
+ buffer_compress(&active_state->outgoing_packet,
+ &active_state->compression_buffer);
+ buffer_clear(&active_state->outgoing_packet);
+ buffer_append(&active_state->outgoing_packet,
+ buffer_ptr(&active_state->compression_buffer),
+ buffer_len(&active_state->compression_buffer));
}
/* Compute packet length without padding (add checksum, remove padding). */
- len = buffer_len(&outgoing_packet) + 4 - 8;
+ len = buffer_len(&active_state->outgoing_packet) + 4 - 8;
/* Insert padding. Initialized to zero in packet_start1() */
padding = 8 - len % 8;
- if (!send_context.plaintext) {
- cp = buffer_ptr(&outgoing_packet);
+ if (!active_state->send_context.plaintext) {
+ cp = buffer_ptr(&active_state->outgoing_packet);
for (i = 0; i < padding; i++) {
if (i % 4 == 0)
rnd = arc4random();
rnd >>= 8;
}
}
- buffer_consume(&outgoing_packet, 8 - padding);
+ buffer_consume(&active_state->outgoing_packet, 8 - padding);
/* Add check bytes. */
- checksum = ssh_crc32(buffer_ptr(&outgoing_packet),
- buffer_len(&outgoing_packet));
+ checksum = ssh_crc32(buffer_ptr(&active_state->outgoing_packet),
+ buffer_len(&active_state->outgoing_packet));
put_u32(buf, checksum);
- buffer_append(&outgoing_packet, buf, 4);
+ buffer_append(&active_state->outgoing_packet, buf, 4);
#ifdef PACKET_DEBUG
fprintf(stderr, "packet_send plain: ");
- buffer_dump(&outgoing_packet);
+ buffer_dump(&active_state->outgoing_packet);
#endif
/* Append to output. */
put_u32(buf, len);
- buffer_append(&output, buf, 4);
- cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
- cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet),
- buffer_len(&outgoing_packet));
+ buffer_append(&active_state->output, buf, 4);
+ cp = buffer_append_space(&active_state->output,
+ buffer_len(&active_state->outgoing_packet));
+ cipher_crypt(&active_state->send_context, cp,
+ buffer_ptr(&active_state->outgoing_packet),
+ buffer_len(&active_state->outgoing_packet));
#ifdef PACKET_DEBUG
fprintf(stderr, "encrypted: ");
- buffer_dump(&output);
+ buffer_dump(&active_state->output);
#endif
- p_send.packets++;
- p_send.bytes += len + buffer_len(&outgoing_packet);
- buffer_clear(&outgoing_packet);
+ active_state->p_send.packets++;
+ active_state->p_send.bytes += len +
+ buffer_len(&active_state->outgoing_packet);
+ buffer_clear(&active_state->outgoing_packet);
/*
* Note that the packet is now only buffered in output. It won't be
debug2("set_newkeys: mode %d", mode);
if (mode == MODE_OUT) {
- cc = &send_context;
+ cc = &active_state->send_context;
crypt_type = CIPHER_ENCRYPT;
- p_send.packets = p_send.blocks = 0;
- max_blocks = &max_blocks_out;
+ active_state->p_send.packets = active_state->p_send.blocks = 0;
+ max_blocks = &active_state->max_blocks_out;
} else {
- cc = &receive_context;
+ cc = &active_state->receive_context;
crypt_type = CIPHER_DECRYPT;
- p_read.packets = p_read.blocks = 0;
- max_blocks = &max_blocks_in;
+ active_state->p_read.packets = active_state->p_read.blocks = 0;
+ max_blocks = &active_state->max_blocks_in;
}
- if (newkeys[mode] != NULL) {
+ if (active_state->newkeys[mode] != NULL) {
debug("set_newkeys: rekeying");
cipher_cleanup(cc);
- enc = &newkeys[mode]->enc;
- mac = &newkeys[mode]->mac;
- comp = &newkeys[mode]->comp;
+ enc = &active_state->newkeys[mode]->enc;
+ mac = &active_state->newkeys[mode]->mac;
+ comp = &active_state->newkeys[mode]->comp;
mac_clear(mac);
xfree(enc->name);
xfree(enc->iv);
xfree(mac->name);
xfree(mac->key);
xfree(comp->name);
- xfree(newkeys[mode]);
+ xfree(active_state->newkeys[mode]);
}
- newkeys[mode] = kex_get_newkeys(mode);
- if (newkeys[mode] == NULL)
+ active_state->newkeys[mode] = kex_get_newkeys(mode);
+ if (active_state->newkeys[mode] == NULL)
fatal("newkeys: no keys for mode %d", mode);
- enc = &newkeys[mode]->enc;
- mac = &newkeys[mode]->mac;
- comp = &newkeys[mode]->comp;
+ enc = &active_state->newkeys[mode]->enc;
+ mac = &active_state->newkeys[mode]->mac;
+ comp = &active_state->newkeys[mode]->comp;
if (mac_init(mac) == 0)
mac->enabled = 1;
DBG(debug("cipher_init_context: %d", mode));
memset(enc->key, 0, enc->key_len);
memset(mac->key, 0, mac->key_len); */
if ((comp->type == COMP_ZLIB ||
- (comp->type == COMP_DELAYED && after_authentication)) &&
- comp->enabled == 0) {
+ (comp->type == COMP_DELAYED &&
+ active_state->after_authentication)) && comp->enabled == 0) {
packet_init_compression();
if (mode == MODE_OUT)
buffer_compress_init_send(6);
*max_blocks = (u_int64_t)1 << (enc->block_size*2);
else
*max_blocks = ((u_int64_t)1 << 30) / enc->block_size;
- if (rekey_limit)
- *max_blocks = MIN(*max_blocks, rekey_limit / enc->block_size);
+ if (active_state->rekey_limit)
+ *max_blocks = MIN(*max_blocks,
+ active_state->rekey_limit / enc->block_size);
}
/*
* Remember that we are past the authentication step, so rekeying
* with COMP_DELAYED will turn on compression immediately.
*/
- after_authentication = 1;
+ active_state->after_authentication = 1;
for (mode = 0; mode < MODE_MAX; mode++) {
/* protocol error: USERAUTH_SUCCESS received before NEWKEYS */
- if (newkeys[mode] == NULL)
+ if (active_state->newkeys[mode] == NULL)
continue;
- comp = &newkeys[mode]->comp;
+ comp = &active_state->newkeys[mode]->comp;
if (comp && !comp->enabled && comp->type == COMP_DELAYED) {
packet_init_compression();
if (mode == MODE_OUT)
Comp *comp = NULL;
int block_size;
- if (newkeys[MODE_OUT] != NULL) {
- enc = &newkeys[MODE_OUT]->enc;
- mac = &newkeys[MODE_OUT]->mac;
- comp = &newkeys[MODE_OUT]->comp;
+ if (active_state->newkeys[MODE_OUT] != NULL) {
+ enc = &active_state->newkeys[MODE_OUT]->enc;
+ mac = &active_state->newkeys[MODE_OUT]->mac;
+ comp = &active_state->newkeys[MODE_OUT]->comp;
}
block_size = enc ? enc->block_size : 8;
- cp = buffer_ptr(&outgoing_packet);
+ cp = buffer_ptr(&active_state->outgoing_packet);
type = cp[5];
#ifdef PACKET_DEBUG
fprintf(stderr, "plain: ");
- buffer_dump(&outgoing_packet);
+ buffer_dump(&active_state->outgoing_packet);
#endif
if (comp && comp->enabled) {
- len = buffer_len(&outgoing_packet);
+ len = buffer_len(&active_state->outgoing_packet);
/* skip header, compress only payload */
- buffer_consume(&outgoing_packet, 5);
- buffer_clear(&compression_buffer);
- buffer_compress(&outgoing_packet, &compression_buffer);
- buffer_clear(&outgoing_packet);
- buffer_append(&outgoing_packet, "\0\0\0\0\0", 5);
- buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer),
- buffer_len(&compression_buffer));
+ buffer_consume(&active_state->outgoing_packet, 5);
+ buffer_clear(&active_state->compression_buffer);
+ buffer_compress(&active_state->outgoing_packet,
+ &active_state->compression_buffer);
+ buffer_clear(&active_state->outgoing_packet);
+ buffer_append(&active_state->outgoing_packet, "\0\0\0\0\0", 5);
+ buffer_append(&active_state->outgoing_packet,
+ buffer_ptr(&active_state->compression_buffer),
+ buffer_len(&active_state->compression_buffer));
DBG(debug("compression: raw %d compressed %d", len,
- buffer_len(&outgoing_packet)));
+ buffer_len(&active_state->outgoing_packet)));
}
/* sizeof (packet_len + pad_len + payload) */
- len = buffer_len(&outgoing_packet);
+ len = buffer_len(&active_state->outgoing_packet);
/*
* calc size of padding, alloc space, get random data,
padlen = block_size - (len % block_size);
if (padlen < 4)
padlen += block_size;
- if (extra_pad) {
+ if (active_state->extra_pad) {
/* will wrap if extra_pad+padlen > 255 */
- extra_pad = roundup(extra_pad, block_size);
- pad = extra_pad - ((len + padlen) % extra_pad);
+ active_state->extra_pad =
+ roundup(active_state->extra_pad, block_size);
+ pad = active_state->extra_pad -
+ ((len + padlen) % active_state->extra_pad);
debug3("packet_send2: adding %d (len %d padlen %d extra_pad %d)",
- pad, len, padlen, extra_pad);
+ pad, len, padlen, active_state->extra_pad);
padlen += pad;
- extra_pad = 0;
+ active_state->extra_pad = 0;
}
- cp = buffer_append_space(&outgoing_packet, padlen);
- if (enc && !send_context.plaintext) {
+ cp = buffer_append_space(&active_state->outgoing_packet, padlen);
+ if (enc && !active_state->send_context.plaintext) {
/* random padding */
for (i = 0; i < padlen; i++) {
if (i % 4 == 0)
memset(cp, 0, padlen);
}
/* packet_length includes payload, padding and padding length field */
- packet_length = buffer_len(&outgoing_packet) - 4;
- cp = buffer_ptr(&outgoing_packet);
+ packet_length = buffer_len(&active_state->outgoing_packet) - 4;
+ cp = buffer_ptr(&active_state->outgoing_packet);
put_u32(cp, packet_length);
cp[4] = padlen;
DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen));
/* compute MAC over seqnr and packet(length fields, payload, padding) */
if (mac && mac->enabled) {
- macbuf = mac_compute(mac, p_send.seqnr,
- buffer_ptr(&outgoing_packet),
- buffer_len(&outgoing_packet));
- DBG(debug("done calc MAC out #%d", p_send.seqnr));
+ macbuf = mac_compute(mac, active_state->p_send.seqnr,
+ buffer_ptr(&active_state->outgoing_packet),
+ buffer_len(&active_state->outgoing_packet));
+ DBG(debug("done calc MAC out #%d", active_state->p_send.seqnr));
}
/* encrypt packet and append to output buffer. */
- cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
- cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet),
- buffer_len(&outgoing_packet));
+ cp = buffer_append_space(&active_state->output,
+ buffer_len(&active_state->outgoing_packet));
+ cipher_crypt(&active_state->send_context, cp,
+ buffer_ptr(&active_state->outgoing_packet),
+ buffer_len(&active_state->outgoing_packet));
/* append unencrypted MAC */
if (mac && mac->enabled)
- buffer_append(&output, macbuf, mac->mac_len);
+ buffer_append(&active_state->output, macbuf, mac->mac_len);
#ifdef PACKET_DEBUG
fprintf(stderr, "encrypted: ");
- buffer_dump(&output);
+ buffer_dump(&active_state->output);
#endif
/* increment sequence number for outgoing packets */
- if (++p_send.seqnr == 0)
+ if (++active_state->p_send.seqnr == 0)
logit("outgoing seqnr wraps around");
- if (++p_send.packets == 0)
+ if (++active_state->p_send.packets == 0)
if (!(datafellows & SSH_BUG_NOREKEY))
fatal("XXX too many packets with same key");
- p_send.blocks += (packet_length + 4) / block_size;
- p_send.bytes += packet_length + 4;
- buffer_clear(&outgoing_packet);
+ active_state->p_send.blocks += (packet_length + 4) / block_size;
+ active_state->p_send.bytes += packet_length + 4;
+ buffer_clear(&active_state->outgoing_packet);
if (type == SSH2_MSG_NEWKEYS)
set_newkeys(MODE_OUT);
- else if (type == SSH2_MSG_USERAUTH_SUCCESS && server_side)
+ else if (type == SSH2_MSG_USERAUTH_SUCCESS && active_state->server_side)
packet_enable_delayed_compress();
}
static void
packet_send2(void)
{
- static int rekeying = 0;
struct packet *p;
u_char type, *cp;
- cp = buffer_ptr(&outgoing_packet);
+ cp = buffer_ptr(&active_state->outgoing_packet);
type = cp[5];
/* during rekeying we can only send key exchange messages */
- if (rekeying) {
+ if (active_state->rekeying) {
if (!((type >= SSH2_MSG_TRANSPORT_MIN) &&
(type <= SSH2_MSG_TRANSPORT_MAX))) {
debug("enqueue packet: %u", type);
p = xmalloc(sizeof(*p));
p->type = type;
- memcpy(&p->payload, &outgoing_packet, sizeof(Buffer));
- buffer_init(&outgoing_packet);
- TAILQ_INSERT_TAIL(&outgoing, p, next);
+ memcpy(&p->payload, &active_state->outgoing_packet,
+ sizeof(Buffer));
+ buffer_init(&active_state->outgoing_packet);
+ TAILQ_INSERT_TAIL(&active_state->outgoing, p, next);
return;
}
}
/* rekeying starts with sending KEXINIT */
if (type == SSH2_MSG_KEXINIT)
- rekeying = 1;
+ active_state->rekeying = 1;
packet_send2_wrapped();
/* after a NEWKEYS message we can send the complete queue */
if (type == SSH2_MSG_NEWKEYS) {
- rekeying = 0;
- while ((p = TAILQ_FIRST(&outgoing))) {
+ active_state->rekeying = 0;
+ while ((p = TAILQ_FIRST(&active_state->outgoing))) {
type = p->type;
debug("dequeue packet: %u", type);
- buffer_free(&outgoing_packet);
- memcpy(&outgoing_packet, &p->payload,
+ buffer_free(&active_state->outgoing_packet);
+ memcpy(&active_state->outgoing_packet, &p->payload,
sizeof(Buffer));
- TAILQ_REMOVE(&outgoing, p, next);
+ TAILQ_REMOVE(&active_state->outgoing, p, next);
xfree(p);
packet_send2_wrapped();
}
int
packet_read_seqnr(u_int32_t *seqnr_p)
{
- int type, len, ret, ms_remain;
+ int type, len, ret, ms_remain, cont;
fd_set *setp;
char buf[8192];
struct timeval timeout, start, *timeoutp = NULL;
DBG(debug("packet_read()"));
- setp = (fd_set *)xcalloc(howmany(connection_in+1, NFDBITS),
- sizeof(fd_mask));
+ setp = (fd_set *)xcalloc(howmany(active_state->connection_in + 1,
+ NFDBITS), sizeof(fd_mask));
/* Since we are blocking, ensure that all written packets have been sent. */
packet_write_wait();
* Otherwise, wait for some data to arrive, add it to the
* buffer, and try again.
*/
- memset(setp, 0, howmany(connection_in + 1, NFDBITS) *
- sizeof(fd_mask));
- FD_SET(connection_in, setp);
+ memset(setp, 0, howmany(active_state->connection_in + 1,
+ NFDBITS) * sizeof(fd_mask));
+ FD_SET(active_state->connection_in, setp);
- if (packet_timeout_ms > 0) {
- ms_remain = packet_timeout_ms;
+ if (active_state->packet_timeout_ms > 0) {
+ ms_remain = active_state->packet_timeout_ms;
timeoutp = &timeout;
}
/* Wait for some data to arrive. */
for (;;) {
- if (packet_timeout_ms != -1) {
+ if (active_state->packet_timeout_ms != -1) {
ms_to_timeval(&timeout, ms_remain);
gettimeofday(&start, NULL);
}
- if ((ret = select(connection_in + 1, setp, NULL,
- NULL, timeoutp)) >= 0)
+ if ((ret = select(active_state->connection_in + 1, setp,
+ NULL, NULL, timeoutp)) >= 0)
break;
- if (errno != EAGAIN && errno != EINTR &&
+ if (errno != EAGAIN && errno != EINTR &&
errno != EWOULDBLOCK)
break;
- if (packet_timeout_ms == -1)
+ if (active_state->packet_timeout_ms == -1)
continue;
ms_subtract_diff(&start, &ms_remain);
if (ms_remain <= 0) {
cleanup_exit(255);
}
/* Read data from the socket. */
- len = read(connection_in, buf, sizeof(buf));
+ do {
+ cont = 0;
+ len = roaming_read(active_state->connection_in, buf,
+ sizeof(buf), &cont);
+ } while (len == 0 && cont);
if (len == 0) {
logit("Connection closed by %.200s", get_remote_ipaddr());
cleanup_exit(255);
u_int checksum, stored_checksum;
/* Check if input size is less than minimum packet size. */
- if (buffer_len(&input) < 4 + 8)
+ if (buffer_len(&active_state->input) < 4 + 8)
return SSH_MSG_NONE;
/* Get length of incoming packet. */
- cp = buffer_ptr(&input);
+ cp = buffer_ptr(&active_state->input);
len = get_u32(cp);
if (len < 1 + 2 + 2 || len > 256 * 1024)
packet_disconnect("Bad packet length %u.", len);
padded_len = (len + 8) & ~7;
/* Check if the packet has been entirely received. */
- if (buffer_len(&input) < 4 + padded_len)
+ if (buffer_len(&active_state->input) < 4 + padded_len)
return SSH_MSG_NONE;
/* The entire packet is in buffer. */
/* Consume packet length. */
- buffer_consume(&input, 4);
+ buffer_consume(&active_state->input, 4);
/*
* Cryptographic attack detector for ssh
* (C)1998 CORE-SDI, Buenos Aires Argentina
* Ariel Futoransky(futo@core-sdi.com)
*/
- if (!receive_context.plaintext) {
- switch (detect_attack(buffer_ptr(&input), padded_len)) {
+ if (!active_state->receive_context.plaintext) {
+ switch (detect_attack(buffer_ptr(&active_state->input),
+ padded_len)) {
case DEATTACK_DETECTED:
packet_disconnect("crc32 compensation attack: "
"network attack detected");
}
/* Decrypt data to incoming_packet. */
- buffer_clear(&incoming_packet);
- cp = buffer_append_space(&incoming_packet, padded_len);
- cipher_crypt(&receive_context, cp, buffer_ptr(&input), padded_len);
+ buffer_clear(&active_state->incoming_packet);
+ cp = buffer_append_space(&active_state->incoming_packet, padded_len);
+ cipher_crypt(&active_state->receive_context, cp,
+ buffer_ptr(&active_state->input), padded_len);
- buffer_consume(&input, padded_len);
+ buffer_consume(&active_state->input, padded_len);
#ifdef PACKET_DEBUG
fprintf(stderr, "read_poll plain: ");
- buffer_dump(&incoming_packet);
+ buffer_dump(&active_state->incoming_packet);
#endif
/* Compute packet checksum. */
- checksum = ssh_crc32(buffer_ptr(&incoming_packet),
- buffer_len(&incoming_packet) - 4);
+ checksum = ssh_crc32(buffer_ptr(&active_state->incoming_packet),
+ buffer_len(&active_state->incoming_packet) - 4);
/* Skip padding. */
- buffer_consume(&incoming_packet, 8 - len % 8);
+ buffer_consume(&active_state->incoming_packet, 8 - len % 8);
/* Test check bytes. */
- if (len != buffer_len(&incoming_packet))
+ if (len != buffer_len(&active_state->incoming_packet))
packet_disconnect("packet_read_poll1: len %d != buffer_len %d.",
- len, buffer_len(&incoming_packet));
+ len, buffer_len(&active_state->incoming_packet));
- cp = (u_char *)buffer_ptr(&incoming_packet) + len - 4;
+ cp = (u_char *)buffer_ptr(&active_state->incoming_packet) + len - 4;
stored_checksum = get_u32(cp);
if (checksum != stored_checksum)
packet_disconnect("Corrupted check bytes on input.");
- buffer_consume_end(&incoming_packet, 4);
-
- if (packet_compression) {
- buffer_clear(&compression_buffer);
- buffer_uncompress(&incoming_packet, &compression_buffer);
- buffer_clear(&incoming_packet);
- buffer_append(&incoming_packet, buffer_ptr(&compression_buffer),
- buffer_len(&compression_buffer));
+ buffer_consume_end(&active_state->incoming_packet, 4);
+
+ if (active_state->packet_compression) {
+ buffer_clear(&active_state->compression_buffer);
+ buffer_uncompress(&active_state->incoming_packet,
+ &active_state->compression_buffer);
+ buffer_clear(&active_state->incoming_packet);
+ buffer_append(&active_state->incoming_packet,
+ buffer_ptr(&active_state->compression_buffer),
+ buffer_len(&active_state->compression_buffer));
}
- p_read.packets++;
- p_read.bytes += padded_len + 4;
- type = buffer_get_char(&incoming_packet);
+ active_state->p_read.packets++;
+ active_state->p_read.bytes += padded_len + 4;
+ type = buffer_get_char(&active_state->incoming_packet);
if (type < SSH_MSG_MIN || type > SSH_MSG_MAX)
packet_disconnect("Invalid ssh1 packet type: %d", type);
return type;
static int
packet_read_poll2(u_int32_t *seqnr_p)
{
- static u_int packet_length = 0;
u_int padlen, need;
u_char *macbuf, *cp, type;
u_int maclen, block_size;
Mac *mac = NULL;
Comp *comp = NULL;
- if (packet_discard)
+ if (active_state->packet_discard)
return SSH_MSG_NONE;
- if (newkeys[MODE_IN] != NULL) {
- enc = &newkeys[MODE_IN]->enc;
- mac = &newkeys[MODE_IN]->mac;
- comp = &newkeys[MODE_IN]->comp;
+ if (active_state->newkeys[MODE_IN] != NULL) {
+ enc = &active_state->newkeys[MODE_IN]->enc;
+ mac = &active_state->newkeys[MODE_IN]->mac;
+ comp = &active_state->newkeys[MODE_IN]->comp;
}
maclen = mac && mac->enabled ? mac->mac_len : 0;
block_size = enc ? enc->block_size : 8;
- if (packet_length == 0) {
+ if (active_state->packlen == 0) {
/*
* check if input size is less than the cipher block size,
* decrypt first block and extract length of incoming packet
*/
- if (buffer_len(&input) < block_size)
+ if (buffer_len(&active_state->input) < block_size)
return SSH_MSG_NONE;
- buffer_clear(&incoming_packet);
- cp = buffer_append_space(&incoming_packet, block_size);
- cipher_crypt(&receive_context, cp, buffer_ptr(&input),
+ buffer_clear(&active_state->incoming_packet);
+ cp = buffer_append_space(&active_state->incoming_packet,
block_size);
- cp = buffer_ptr(&incoming_packet);
- packet_length = get_u32(cp);
- if (packet_length < 1 + 4 || packet_length > PACKET_MAX_SIZE) {
+ cipher_crypt(&active_state->receive_context, cp,
+ buffer_ptr(&active_state->input), block_size);
+ cp = buffer_ptr(&active_state->incoming_packet);
+ active_state->packlen = get_u32(cp);
+ if (active_state->packlen < 1 + 4 ||
+ active_state->packlen > PACKET_MAX_SIZE) {
#ifdef PACKET_DEBUG
- buffer_dump(&incoming_packet);
+ buffer_dump(&active_state->incoming_packet);
#endif
- logit("Bad packet length %u.", packet_length);
- packet_start_discard(enc, mac, packet_length,
+ logit("Bad packet length %u.", active_state->packlen);
+ packet_start_discard(enc, mac, active_state->packlen,
PACKET_MAX_SIZE);
return SSH_MSG_NONE;
}
- DBG(debug("input: packet len %u", packet_length+4));
- buffer_consume(&input, block_size);
+ DBG(debug("input: packet len %u", active_state->packlen+4));
+ buffer_consume(&active_state->input, block_size);
}
/* we have a partial packet of block_size bytes */
- need = 4 + packet_length - block_size;
+ need = 4 + active_state->packlen - block_size;
DBG(debug("partial packet %d, need %d, maclen %d", block_size,
need, maclen));
if (need % block_size != 0) {
logit("padding error: need %d block %d mod %d",
need, block_size, need % block_size);
- packet_start_discard(enc, mac, packet_length,
+ packet_start_discard(enc, mac, active_state->packlen,
PACKET_MAX_SIZE - block_size);
return SSH_MSG_NONE;
}
* check if the entire packet has been received and
* decrypt into incoming_packet
*/
- if (buffer_len(&input) < need + maclen)
+ if (buffer_len(&active_state->input) < need + maclen)
return SSH_MSG_NONE;
#ifdef PACKET_DEBUG
fprintf(stderr, "read_poll enc/full: ");
- buffer_dump(&input);
+ buffer_dump(&active_state->input);
#endif
- cp = buffer_append_space(&incoming_packet, need);
- cipher_crypt(&receive_context, cp, buffer_ptr(&input), need);
- buffer_consume(&input, need);
+ cp = buffer_append_space(&active_state->incoming_packet, need);
+ cipher_crypt(&active_state->receive_context, cp,
+ buffer_ptr(&active_state->input), need);
+ buffer_consume(&active_state->input, need);
/*
* compute MAC over seqnr and packet,
* increment sequence number for incoming packet
*/
if (mac && mac->enabled) {
- macbuf = mac_compute(mac, p_read.seqnr,
- buffer_ptr(&incoming_packet),
- buffer_len(&incoming_packet));
- if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0) {
+ macbuf = mac_compute(mac, active_state->p_read.seqnr,
+ buffer_ptr(&active_state->incoming_packet),
+ buffer_len(&active_state->incoming_packet));
+ if (memcmp(macbuf, buffer_ptr(&active_state->input),
+ mac->mac_len) != 0) {
logit("Corrupted MAC on input.");
if (need > PACKET_MAX_SIZE)
fatal("internal error need %d", need);
- packet_start_discard(enc, mac, packet_length,
+ packet_start_discard(enc, mac, active_state->packlen,
PACKET_MAX_SIZE - need);
return SSH_MSG_NONE;
}
- DBG(debug("MAC #%d ok", p_read.seqnr));
- buffer_consume(&input, mac->mac_len);
+ DBG(debug("MAC #%d ok", active_state->p_read.seqnr));
+ buffer_consume(&active_state->input, mac->mac_len);
}
/* XXX now it's safe to use fatal/packet_disconnect */
if (seqnr_p != NULL)
- *seqnr_p = p_read.seqnr;
- if (++p_read.seqnr == 0)
+ *seqnr_p = active_state->p_read.seqnr;
+ if (++active_state->p_read.seqnr == 0)
logit("incoming seqnr wraps around");
- if (++p_read.packets == 0)
+ if (++active_state->p_read.packets == 0)
if (!(datafellows & SSH_BUG_NOREKEY))
fatal("XXX too many packets with same key");
- p_read.blocks += (packet_length + 4) / block_size;
- p_read.bytes += packet_length + 4;
+ active_state->p_read.blocks += (active_state->packlen + 4) / block_size;
+ active_state->p_read.bytes += active_state->packlen + 4;
/* get padlen */
- cp = buffer_ptr(&incoming_packet);
+ cp = buffer_ptr(&active_state->incoming_packet);
padlen = cp[4];
DBG(debug("input: padlen %d", padlen));
if (padlen < 4)
packet_disconnect("Corrupted padlen %d on input.", padlen);
/* skip packet size + padlen, discard padding */
- buffer_consume(&incoming_packet, 4 + 1);
- buffer_consume_end(&incoming_packet, padlen);
+ buffer_consume(&active_state->incoming_packet, 4 + 1);
+ buffer_consume_end(&active_state->incoming_packet, padlen);
- DBG(debug("input: len before de-compress %d", buffer_len(&incoming_packet)));
+ DBG(debug("input: len before de-compress %d",
+ buffer_len(&active_state->incoming_packet)));
if (comp && comp->enabled) {
- buffer_clear(&compression_buffer);
- buffer_uncompress(&incoming_packet, &compression_buffer);
- buffer_clear(&incoming_packet);
- buffer_append(&incoming_packet, buffer_ptr(&compression_buffer),
- buffer_len(&compression_buffer));
+ buffer_clear(&active_state->compression_buffer);
+ buffer_uncompress(&active_state->incoming_packet,
+ &active_state->compression_buffer);
+ buffer_clear(&active_state->incoming_packet);
+ buffer_append(&active_state->incoming_packet,
+ buffer_ptr(&active_state->compression_buffer),
+ buffer_len(&active_state->compression_buffer));
DBG(debug("input: len after de-compress %d",
- buffer_len(&incoming_packet)));
+ buffer_len(&active_state->incoming_packet)));
}
/*
* get packet type, implies consume.
* return length of payload (without type field)
*/
- type = buffer_get_char(&incoming_packet);
+ type = buffer_get_char(&active_state->incoming_packet);
if (type < SSH2_MSG_MIN || type >= SSH2_MSG_LOCAL_MIN)
packet_disconnect("Invalid ssh2 packet type: %d", type);
if (type == SSH2_MSG_NEWKEYS)
set_newkeys(MODE_IN);
- else if (type == SSH2_MSG_USERAUTH_SUCCESS && !server_side)
+ else if (type == SSH2_MSG_USERAUTH_SUCCESS &&
+ !active_state->server_side)
packet_enable_delayed_compress();
#ifdef PACKET_DEBUG
fprintf(stderr, "read/plain[%d]:\r\n", type);
- buffer_dump(&incoming_packet);
+ buffer_dump(&active_state->incoming_packet);
#endif
/* reset for next packet */
- packet_length = 0;
+ active_state->packlen = 0;
return type;
}
if (compat20) {
type = packet_read_poll2(seqnr_p);
if (type) {
- keep_alive_timeouts = 0;
+ active_state->keep_alive_timeouts = 0;
DBG(debug("received packet type %d", type));
}
switch (type) {
void
packet_process_incoming(const char *buf, u_int len)
{
- if (packet_discard) {
- keep_alive_timeouts = 0; /* ?? */
- if (len >= packet_discard)
+ if (active_state->packet_discard) {
+ active_state->keep_alive_timeouts = 0; /* ?? */
+ if (len >= active_state->packet_discard)
packet_stop_discard();
- packet_discard -= len;
+ active_state->packet_discard -= len;
return;
}
- buffer_append(&input, buf, len);
+ buffer_append(&active_state->input, buf, len);
}
/* Returns a character from the packet. */
{
char ch;
- buffer_get(&incoming_packet, &ch, 1);
+ buffer_get(&active_state->incoming_packet, &ch, 1);
return (u_char) ch;
}
u_int
packet_get_int(void)
{
- return buffer_get_int(&incoming_packet);
+ return buffer_get_int(&active_state->incoming_packet);
+}
+
+/* Returns an 64 bit integer from the packet data. */
+
+u_int64_t
+packet_get_int64(void)
+{
+ return buffer_get_int64(&active_state->incoming_packet);
}
/*
void
packet_get_bignum(BIGNUM * value)
{
- buffer_get_bignum(&incoming_packet, value);
+ buffer_get_bignum(&active_state->incoming_packet, value);
}
void
packet_get_bignum2(BIGNUM * value)
{
- buffer_get_bignum2(&incoming_packet, value);
+ buffer_get_bignum2(&active_state->incoming_packet, value);
}
void *
packet_get_raw(u_int *length_ptr)
{
- u_int bytes = buffer_len(&incoming_packet);
+ u_int bytes = buffer_len(&active_state->incoming_packet);
if (length_ptr != NULL)
*length_ptr = bytes;
- return buffer_ptr(&incoming_packet);
+ return buffer_ptr(&active_state->incoming_packet);
}
int
packet_remaining(void)
{
- return buffer_len(&incoming_packet);
+ return buffer_len(&active_state->incoming_packet);
}
/*
void *
packet_get_string(u_int *length_ptr)
{
- return buffer_get_string(&incoming_packet, length_ptr);
+ return buffer_get_string(&active_state->incoming_packet, length_ptr);
}
void *
packet_get_string_ptr(u_int *length_ptr)
{
- return buffer_get_string_ptr(&incoming_packet, length_ptr);
+ return buffer_get_string_ptr(&active_state->incoming_packet, length_ptr);
}
/*
void
packet_write_poll(void)
{
- int len = buffer_len(&output);
+ int len = buffer_len(&active_state->output);
+ int cont;
if (len > 0) {
- len = write(connection_out, buffer_ptr(&output), len);
+ cont = 0;
+ len = roaming_write(active_state->connection_out,
+ buffer_ptr(&active_state->output), len, &cont);
if (len == -1) {
if (errno == EINTR || errno == EAGAIN ||
errno == EWOULDBLOCK)
return;
fatal("Write failed: %.100s", strerror(errno));
}
- if (len == 0)
+ if (len == 0 && !cont)
fatal("Write connection closed");
- buffer_consume(&output, len);
+ buffer_consume(&active_state->output, len);
}
}
-
/*
* Calls packet_write_poll repeatedly until all pending output data has been
* written.
int ret, ms_remain;
struct timeval start, timeout, *timeoutp = NULL;
- setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS),
- sizeof(fd_mask));
+ setp = (fd_set *)xcalloc(howmany(active_state->connection_out + 1,
+ NFDBITS), sizeof(fd_mask));
packet_write_poll();
while (packet_have_data_to_write()) {
- memset(setp, 0, howmany(connection_out + 1, NFDBITS) *
- sizeof(fd_mask));
- FD_SET(connection_out, setp);
+ memset(setp, 0, howmany(active_state->connection_out + 1,
+ NFDBITS) * sizeof(fd_mask));
+ FD_SET(active_state->connection_out, setp);
- if (packet_timeout_ms > 0) {
- ms_remain = packet_timeout_ms;
+ if (active_state->packet_timeout_ms > 0) {
+ ms_remain = active_state->packet_timeout_ms;
timeoutp = &timeout;
}
for (;;) {
- if (packet_timeout_ms != -1) {
+ if (active_state->packet_timeout_ms != -1) {
ms_to_timeval(&timeout, ms_remain);
gettimeofday(&start, NULL);
}
- if ((ret = select(connection_out + 1, NULL, setp,
- NULL, timeoutp)) >= 0)
+ if ((ret = select(active_state->connection_out + 1,
+ NULL, setp, NULL, timeoutp)) >= 0)
break;
- if (errno != EAGAIN && errno != EINTR &&
+ if (errno != EAGAIN && errno != EINTR &&
errno != EWOULDBLOCK)
break;
- if (packet_timeout_ms == -1)
+ if (active_state->packet_timeout_ms == -1)
continue;
ms_subtract_diff(&start, &ms_remain);
if (ms_remain <= 0) {
int
packet_have_data_to_write(void)
{
- return buffer_len(&output) != 0;
+ return buffer_len(&active_state->output) != 0;
}
/* Returns true if there is not too much data to write to the connection. */
int
packet_not_very_much_data_to_write(void)
{
- if (interactive_mode)
- return buffer_len(&output) < 16384;
+ if (active_state->interactive_mode)
+ return buffer_len(&active_state->output) < 16384;
else
- return buffer_len(&output) < 128 * 1024;
+ return buffer_len(&active_state->output) < 128 * 1024;
}
-
static void
packet_set_tos(int interactive)
{
if (!packet_connection_is_on_socket() ||
!packet_connection_is_ipv4())
return;
- if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, &tos,
+ if (setsockopt(active_state->connection_in, IPPROTO_IP, IP_TOS, &tos,
sizeof(tos)) < 0)
error("setsockopt IP_TOS %d: %.100s:",
tos, strerror(errno));
void
packet_set_interactive(int interactive)
{
- static int called = 0;
-
- if (called)
+ if (active_state->set_interactive_called)
return;
- called = 1;
+ active_state->set_interactive_called = 1;
/* Record that we are in interactive mode. */
- interactive_mode = interactive;
+ active_state->interactive_mode = interactive;
/* Only set socket options if using a socket. */
if (!packet_connection_is_on_socket())
return;
- set_nodelay(connection_in);
+ set_nodelay(active_state->connection_in);
packet_set_tos(interactive);
}
int
packet_is_interactive(void)
{
- return interactive_mode;
+ return active_state->interactive_mode;
}
int
packet_set_maxsize(u_int s)
{
- static int called = 0;
-
- if (called) {
+ if (active_state->set_maxsize_called) {
logit("packet_set_maxsize: called twice: old %d new %d",
- max_packet_size, s);
+ active_state->max_packet_size, s);
return -1;
}
if (s < 4 * 1024 || s > 1024 * 1024) {
logit("packet_set_maxsize: bad size %d", s);
return -1;
}
- called = 1;
+ active_state->set_maxsize_called = 1;
debug("packet_set_maxsize: setting to %d", s);
- max_packet_size = s;
+ active_state->max_packet_size = s;
return s;
}
+int
+packet_inc_alive_timeouts(void)
+{
+ return ++active_state->keep_alive_timeouts;
+}
+
+void
+packet_set_alive_timeouts(int ka)
+{
+ active_state->keep_alive_timeouts = ka;
+}
+
+u_int
+packet_get_maxsize(void)
+{
+ return active_state->max_packet_size;
+}
+
/* roundup current message to pad bytes */
void
packet_add_padding(u_char pad)
{
- extra_pad = pad;
+ active_state->extra_pad = pad;
}
/*
if (datafellows & SSH_BUG_NOREKEY)
return 0;
return
- (p_send.packets > MAX_PACKETS) ||
- (p_read.packets > MAX_PACKETS) ||
- (max_blocks_out && (p_send.blocks > max_blocks_out)) ||
- (max_blocks_in && (p_read.blocks > max_blocks_in));
+ (active_state->p_send.packets > MAX_PACKETS) ||
+ (active_state->p_read.packets > MAX_PACKETS) ||
+ (active_state->max_blocks_out &&
+ (active_state->p_send.blocks > active_state->max_blocks_out)) ||
+ (active_state->max_blocks_in &&
+ (active_state->p_read.blocks > active_state->max_blocks_in));
}
void
packet_set_rekey_limit(u_int32_t bytes)
{
- rekey_limit = bytes;
+ active_state->rekey_limit = bytes;
}
void
packet_set_server(void)
{
- server_side = 1;
+ active_state->server_side = 1;
}
void
packet_set_authenticated(void)
{
- after_authentication = 1;
+ active_state->after_authentication = 1;
+}
+
+void *
+packet_get_input(void)
+{
+ return (void *)&active_state->input;
+}
+
+void *
+packet_get_output(void)
+{
+ return (void *)&active_state->output;
+}
+
+void *
+packet_get_newkeys(int mode)
+{
+ return (void *)active_state->newkeys[mode];
+}
+
+/*
+ * Save the state for the real connection, and use a separate state when
+ * resuming a suspended connection.
+ */
+void
+packet_backup_state(void)
+{
+ struct session_state *tmp;
+
+ close(active_state->connection_in);
+ active_state->connection_in = -1;
+ close(active_state->connection_out);
+ active_state->connection_out = -1;
+ if (backup_state)
+ tmp = backup_state;
+ else
+ tmp = alloc_session_state();
+ backup_state = active_state;
+ active_state = tmp;
+}
+
+/*
+ * Swap in the old state when resuming a connecion.
+ */
+void
+packet_restore_state(void)
+{
+ struct session_state *tmp;
+ void *buf;
+ u_int len;
+
+ tmp = backup_state;
+ backup_state = active_state;
+ active_state = tmp;
+ active_state->connection_in = backup_state->connection_in;
+ backup_state->connection_in = -1;
+ active_state->connection_out = backup_state->connection_out;
+ backup_state->connection_out = -1;
+ len = buffer_len(&backup_state->input);
+ if (len > 0) {
+ buf = buffer_ptr(&backup_state->input);
+ buffer_append(&active_state->input, buf, len);
+ buffer_clear(&backup_state->input);
+ add_recv_bytes(len);
+ }
}
-/* $OpenBSD: packet.h,v 1.49 2008/07/10 18:08:11 markus Exp $ */
+/* $OpenBSD: packet.h,v 1.52 2009/06/27 09:29:06 andreas Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
void packet_start(u_char);
void packet_put_char(int ch);
void packet_put_int(u_int value);
+void packet_put_int64(u_int64_t value);
void packet_put_bignum(BIGNUM * value);
void packet_put_bignum2(BIGNUM * value);
void packet_put_string(const void *buf, u_int len);
u_int packet_get_char(void);
u_int packet_get_int(void);
+u_int64_t packet_get_int64(void);
void packet_get_bignum(BIGNUM * value);
void packet_get_bignum2(BIGNUM * value);
void *packet_get_raw(u_int *length_ptr);
void packet_set_state(int, u_int32_t, u_int64_t, u_int32_t, u_int64_t);
int packet_get_ssh1_cipher(void);
void packet_set_iv(int, u_char *);
+void *packet_get_newkeys(int);
void packet_write_poll(void);
void packet_write_wait(void);
void tty_make_modes(int, struct termios *);
void tty_parse_modes(int, int *);
-extern u_int max_packet_size;
-extern int keep_alive_timeouts;
+void packet_set_alive_timeouts(int);
+int packet_inc_alive_timeouts(void);
int packet_set_maxsize(u_int);
-#define packet_get_maxsize() max_packet_size
+u_int packet_get_maxsize(void);
/* don't allow remaining bytes after the end of the message */
#define packet_check_eom() \
int packet_need_rekeying(void);
void packet_set_rekey_limit(u_int32_t);
+void packet_backup_state(void);
+void packet_restore_state(void);
+
+void *packet_get_input(void);
+void *packet_get_output(void);
+
#endif /* PACKET_H */
-/* $OpenBSD: readconf.c,v 1.176 2009/02/12 03:00:56 djm Exp $ */
+/* $OpenBSD: readconf.c,v 1.177 2009/06/27 09:35:06 andreas Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
- oVisualHostKey, oZeroKnowledgePasswordAuthentication,
+ oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
oDeprecated, oUnsupported
} OpCodes;
{ "localcommand", oLocalCommand },
{ "permitlocalcommand", oPermitLocalCommand },
{ "visualhostkey", oVisualHostKey },
+ { "useroaming", oUseRoaming },
#ifdef JPAKE
{ "zeroknowledgepasswordauthentication",
oZeroKnowledgePasswordAuthentication },
intptr = &options->visual_host_key;
goto parse_flag;
+ case oUseRoaming:
+ intptr = &options->use_roaming;
+ goto parse_flag;
+
case oDeprecated:
debug("%s line %d: Deprecated option \"%s\"",
filename, linenum, keyword);
options->tun_remote = -1;
options->local_command = NULL;
options->permit_local_command = -1;
+ options->use_roaming = -1;
options->visual_host_key = -1;
options->zero_knowledge_password_authentication = -1;
}
options->tun_remote = SSH_TUNID_ANY;
if (options->permit_local_command == -1)
options->permit_local_command = 0;
+ if (options->use_roaming == -1)
+ options->use_roaming = 1;
if (options->visual_host_key == -1)
options->visual_host_key = 0;
if (options->zero_knowledge_password_authentication == -1)
-/* $OpenBSD: readconf.h,v 1.78 2009/02/12 03:00:56 djm Exp $ */
+/* $OpenBSD: readconf.h,v 1.79 2009/06/27 09:35:06 andreas Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
int permit_local_command;
int visual_host_key;
+ int use_roaming;
+
} Options;
#define SSHCTL_MASTER_NO 0
--- /dev/null
+/* $OpenBSD: roaming.h,v 1.4 2009/06/27 09:32:43 andreas Exp $ */
+/*
+ * Copyright (c) 2004-2009 AppGate Network Security AB
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef ROAMING_H
+#define ROAMING_H
+
+#define DEFAULT_ROAMBUF 65536
+
+extern int resume_in_progress;
+
+int get_snd_buf_size(void);
+int get_recv_buf_size(void);
+void add_recv_bytes(u_int64_t);
+void set_out_buffer_size(size_t);
+ssize_t roaming_write(int, const void *, size_t, int *);
+ssize_t roaming_read(int, void *, size_t, int *);
+size_t roaming_atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t);
+u_int64_t get_recv_bytes(void);
+u_int64_t get_sent_bytes(void);
+void roam_set_bytes(u_int64_t, u_int64_t);
+void resend_bytes(int, u_int64_t *);
+int resume_kex(void);
+
+#endif /* ROAMING */
--- /dev/null
+/* $OpenBSD: roaming_common.c,v 1.5 2009/06/27 09:32:43 andreas Exp $ */
+/*
+ * Copyright (c) 2004-2009 AppGate Network Security AB
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+
+#include <errno.h>
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "atomicio.h"
+#include "log.h"
+#include "packet.h"
+#include "xmalloc.h"
+#include "cipher.h"
+#include "buffer.h"
+#include "roaming.h"
+
+static size_t out_buf_size = 0;
+static char *out_buf = NULL;
+static size_t out_start;
+static size_t out_last;
+
+static u_int64_t write_bytes = 0;
+static u_int64_t read_bytes = 0;
+
+int roaming_enabled = 0;
+int resume_in_progress = 0;
+
+int
+get_snd_buf_size()
+{
+ int fd = packet_get_connection_out();
+ int optval, optvallen;
+
+ optvallen = sizeof(optval);
+ if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &optval, &optvallen) != 0)
+ optval = DEFAULT_ROAMBUF;
+ return optval;
+}
+
+int
+get_recv_buf_size()
+{
+ int fd = packet_get_connection_in();
+ int optval, optvallen;
+
+ optvallen = sizeof(optval);
+ if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &optval, &optvallen) != 0)
+ optval = DEFAULT_ROAMBUF;
+ return optval;
+}
+
+void
+set_out_buffer_size(size_t size)
+{
+ /*
+ * The buffer size can only be set once and the buffer will live
+ * as long as the session lives.
+ */
+ if (out_buf == NULL) {
+ out_buf_size = size;
+ out_buf = xmalloc(size);
+ out_start = 0;
+ out_last = 0;
+ }
+}
+
+u_int64_t
+get_recv_bytes(void)
+{
+ return read_bytes;
+}
+
+void
+add_recv_bytes(u_int64_t num)
+{
+ read_bytes += num;
+}
+
+u_int64_t
+get_sent_bytes(void)
+{
+ return write_bytes;
+}
+
+void
+roam_set_bytes(u_int64_t sent, u_int64_t recvd)
+{
+ read_bytes = recvd;
+ write_bytes = sent;
+}
+
+static void
+buf_append(const char *buf, size_t count)
+{
+ if (count > out_buf_size) {
+ buf += count - out_buf_size;
+ count = out_buf_size;
+ }
+ if (count < out_buf_size - out_last) {
+ memcpy(out_buf + out_last, buf, count);
+ if (out_start > out_last)
+ out_start += count;
+ out_last += count;
+ } else {
+ /* data will wrap */
+ size_t chunk = out_buf_size - out_last;
+ memcpy(out_buf + out_last, buf, chunk);
+ memcpy(out_buf, buf + chunk, count - chunk);
+ out_last = count - chunk;
+ out_start = out_last + 1;
+ }
+}
+
+ssize_t
+roaming_write(int fd, const void *buf, size_t count, int *cont)
+{
+ ssize_t ret;
+
+ ret = write(fd, buf, count);
+ if (ret > 0 && !resume_in_progress) {
+ write_bytes += ret;
+ if (out_buf_size > 0)
+ buf_append(buf, ret);
+ }
+ debug3("Wrote %ld bytes for a total of %llu", (long)ret,
+ (unsigned long long)write_bytes);
+ return ret;
+}
+
+ssize_t
+roaming_read(int fd, void *buf, size_t count, int *cont)
+{
+ ssize_t ret = read(fd, buf, count);
+ if (ret > 0) {
+ if (!resume_in_progress) {
+ read_bytes += ret;
+ }
+ }
+ return ret;
+}
+
+size_t
+roaming_atomicio(ssize_t(*f)(int, void*, size_t), int fd, void *buf,
+ size_t count)
+{
+ size_t ret = atomicio(f, fd, buf, count);
+
+ if (f == vwrite && ret > 0 && !resume_in_progress) {
+ write_bytes += ret;
+ } else if (f == read && ret > 0 && !resume_in_progress) {
+ read_bytes += ret;
+ }
+ return ret;
+}
+
+void
+resend_bytes(int fd, u_int64_t *offset)
+{
+ size_t available, needed;
+
+ if (out_start < out_last)
+ available = out_last - out_start;
+ else
+ available = out_buf_size;
+ needed = write_bytes - *offset;
+ debug3("resend_bytes: resend %lu bytes from %llu",
+ (unsigned long)needed, (unsigned long long)*offset);
+ if (needed > available)
+ fatal("Needed to resend more data than in the cache");
+ if (out_last < needed) {
+ int chunkend = needed - out_last;
+ atomicio(vwrite, fd, out_buf + out_buf_size - chunkend,
+ chunkend);
+ atomicio(vwrite, fd, out_buf, out_last);
+ } else {
+ atomicio(vwrite, fd, out_buf + (out_last - needed), needed);
+ }
+}
--- /dev/null
+/* $OpenBSD: roaming_dummy.c,v 1.3 2009/06/21 09:04:03 dtucker Exp $ */
+/*
+ * Copyright (c) 2004-2009 AppGate Network Security AB
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file is included in the client programs which should not
+ * support roaming.
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "roaming.h"
+
+int resume_in_progress = 0;
+
+u_int64_t
+get_recv_bytes(void)
+{
+ return 0;
+}
+
+ssize_t
+roaming_write(int fd, const void *buf, size_t count, int *cont)
+{
+ return write(fd, buf, count);
+}
+
+ssize_t
+roaming_read(int fd, void *buf, size_t count, int *cont)
+{
+ if (cont)
+ *cont = 0;
+ return read(fd, buf, count);
+}
+
+void
+add_recv_bytes(u_int64_t num)
+{
+}
+
+int
+resume_kex(void)
+{
+ return 1;
+}
-/* $OpenBSD: schnorr.c,v 1.2 2009/02/18 04:31:21 djm Exp $ */
+/* $OpenBSD: schnorr.c,v 1.3 2009/03/05 07:18:19 djm Exp $ */
/*
* Copyright (c) 2008 Damien Miller. All rights reserved.
*
#include "buffer.h"
#include "log.h"
-#include "jpake.h"
+#include "schnorr.h"
+
+#include "openbsd-compat/openssl-compat.h"
/* #define SCHNORR_DEBUG */ /* Privacy-violating debugging */
/* #define SCHNORR_MAIN */ /* Include main() selftest */
-/* XXX */
-/* Parametise signature hash? (sha256, sha1, etc.) */
-/* Signature format - include type name, hash type, group params? */
-
#ifndef SCHNORR_DEBUG
# define SCHNORR_DEBUG_BN(a)
# define SCHNORR_DEBUG_BUF(a)
#else
-# define SCHNORR_DEBUG_BN(a) jpake_debug3_bn a
-# define SCHNORR_DEBUG_BUF(a) jpake_debug3_buf a
+# define SCHNORR_DEBUG_BN(a) debug3_bn a
+# define SCHNORR_DEBUG_BUF(a) debug3_buf a
#endif /* SCHNORR_DEBUG */
/*
* Calculate hash component of Schnorr signature H(g || g^v || g^x || id)
- * using SHA1. Returns signature as bignum or NULL on error.
+ * using the hash function defined by "evp_md". Returns signature as
+ * bignum or NULL on error.
*/
static BIGNUM *
schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g,
- const BIGNUM *g_v, const BIGNUM *g_x,
+ const EVP_MD *evp_md, const BIGNUM *g_v, const BIGNUM *g_x,
const u_char *id, u_int idlen)
{
u_char *digest;
u_int digest_len;
BIGNUM *h;
- EVP_MD_CTX evp_md_ctx;
Buffer b;
int success = -1;
}
buffer_init(&b);
- EVP_MD_CTX_init(&evp_md_ctx);
/* h = H(g || p || q || g^v || g^x || id) */
buffer_put_bignum2(&b, g);
SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
"%s: hashblob", __func__));
- if (hash_buffer(buffer_ptr(&b), buffer_len(&b), EVP_sha256(),
+ if (hash_buffer(buffer_ptr(&b), buffer_len(&b), evp_md,
&digest, &digest_len) != 0) {
error("%s: hash_buffer", __func__);
goto out;
SCHNORR_DEBUG_BN((h, "%s: h = ", __func__));
out:
buffer_free(&b);
- EVP_MD_CTX_cleanup(&evp_md_ctx);
bzero(digest, digest_len);
xfree(digest);
digest_len = 0;
/*
* Generate Schnorr signature to prove knowledge of private value 'x' used
* in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g'
+ * using the hash function "evp_md".
* 'idlen' bytes from 'id' will be included in the signature hash as an anti-
* replay salt.
- * On success, 0 is returned and *siglen bytes of signature are returned in
- * *sig (caller to free). Returns -1 on failure.
+ *
+ * On success, 0 is returned. The signature values are returned as *e_p
+ * (g^v mod p) and *r_p (v - xh mod q). The caller must free these values.
+ * On failure, -1 is returned.
*/
int
schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
- const BIGNUM *x, const BIGNUM *g_x, const u_char *id, u_int idlen,
- u_char **sig, u_int *siglen)
+ const EVP_MD *evp_md, const BIGNUM *x, const BIGNUM *g_x,
+ const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p)
{
int success = -1;
- Buffer b;
BIGNUM *h, *tmp, *v, *g_v, *r;
BN_CTX *bn_ctx;
SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__));
/* h = H(g || g^v || g^x || id) */
- if ((h = schnorr_hash(grp_p, grp_q, grp_g, g_v, g_x,
+ if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, g_v, g_x,
id, idlen)) == NULL) {
error("%s: schnorr_hash failed", __func__);
goto out;
error("%s: BN_mod_mul (r = v - tmp)", __func__);
goto out;
}
+ SCHNORR_DEBUG_BN((g_v, "%s: e = ", __func__));
SCHNORR_DEBUG_BN((r, "%s: r = ", __func__));
- /* Signature is (g_v, r) */
+ *e_p = g_v;
+ *r_p = r;
+
+ success = 0;
+ out:
+ BN_CTX_free(bn_ctx);
+ if (h != NULL)
+ BN_clear_free(h);
+ if (v != NULL)
+ BN_clear_free(v);
+ BN_clear_free(tmp);
+
+ return success;
+}
+
+/*
+ * Generate Schnorr signature to prove knowledge of private value 'x' used
+ * in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g'
+ * using a SHA256 hash.
+ * 'idlen' bytes from 'id' will be included in the signature hash as an anti-
+ * replay salt.
+ * On success, 0 is returned and *siglen bytes of signature are returned in
+ * *sig (caller to free). Returns -1 on failure.
+ */
+int
+schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
+ const BIGNUM *x, const BIGNUM *g_x, const u_char *id, u_int idlen,
+ u_char **sig, u_int *siglen)
+{
+ Buffer b;
+ BIGNUM *r, *e;
+
+ if (schnorr_sign(grp_p, grp_q, grp_g, EVP_sha256(),
+ x, g_x, id, idlen, &r, &e) != 0)
+ return -1;
+
+ /* Signature is (e, r) */
buffer_init(&b);
/* XXX sigtype-hash as string? */
- buffer_put_bignum2(&b, g_v);
+ buffer_put_bignum2(&b, e);
buffer_put_bignum2(&b, r);
*siglen = buffer_len(&b);
*sig = xmalloc(*siglen);
SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
"%s: sigblob", __func__));
buffer_free(&b);
- success = 0;
- out:
- BN_CTX_free(bn_ctx);
- if (h != NULL)
- BN_clear_free(h);
- if (v != NULL)
- BN_clear_free(v);
+
BN_clear_free(r);
- BN_clear_free(g_v);
- BN_clear_free(tmp);
+ BN_clear_free(e);
- return success;
+ return 0;
}
/*
- * Verify Schnorr signature 'sig' of length 'siglen' against public exponent
- * g_x (g^x) under group defined by 'grp_p', 'grp_q' and 'grp_g'.
+ * Verify Schnorr signature { r (v - xh mod q), e (g^v mod p) } against
+ * public exponent g_x (g^x) under group defined by 'grp_p', 'grp_q' and
+ * 'grp_g' using hash "evp_md".
* Signature hash will be salted with 'idlen' bytes from 'id'.
* Returns -1 on failure, 0 on incorrect signature or 1 on matching signature.
*/
int
schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
- const BIGNUM *g_x, const u_char *id, u_int idlen,
- const u_char *sig, u_int siglen)
+ const EVP_MD *evp_md, const BIGNUM *g_x, const u_char *id, u_int idlen,
+ const BIGNUM *r, const BIGNUM *e)
{
int success = -1;
- Buffer b;
- BIGNUM *g_v, *h, *r, *g_xh, *g_r, *expected;
+ BIGNUM *h, *g_xh, *g_r, *expected;
BN_CTX *bn_ctx;
- u_int rlen;
SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__));
return -1;
}
- g_v = h = r = g_xh = g_r = expected = NULL;
+ h = g_xh = g_r = expected = NULL;
if ((bn_ctx = BN_CTX_new()) == NULL) {
error("%s: BN_CTX_new", __func__);
goto out;
}
- if ((g_v = BN_new()) == NULL ||
- (r = BN_new()) == NULL ||
- (g_xh = BN_new()) == NULL ||
+ if ((g_xh = BN_new()) == NULL ||
(g_r = BN_new()) == NULL ||
(expected = BN_new()) == NULL) {
error("%s: BN_new", __func__);
goto out;
}
- /* Extract g^v and r from signature blob */
- buffer_init(&b);
- buffer_append(&b, sig, siglen);
- SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
- "%s: sigblob", __func__));
- buffer_get_bignum2(&b, g_v);
- buffer_get_bignum2(&b, r);
- rlen = buffer_len(&b);
- buffer_free(&b);
- if (rlen != 0) {
- error("%s: remaining bytes in signature %d", __func__, rlen);
- goto out;
- }
- buffer_free(&b);
- SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__));
+ SCHNORR_DEBUG_BN((e, "%s: e = ", __func__));
SCHNORR_DEBUG_BN((r, "%s: r = ", __func__));
/* h = H(g || g^v || g^x || id) */
- if ((h = schnorr_hash(grp_p, grp_q, grp_g, g_v, g_x,
+ if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, e, g_x,
id, idlen)) == NULL) {
error("%s: schnorr_hash failed", __func__);
goto out;
}
SCHNORR_DEBUG_BN((expected, "%s: expected = ", __func__));
- /* Check g_v == expected */
- success = BN_cmp(expected, g_v) == 0;
+ /* Check e == expected */
+ success = BN_cmp(expected, e) == 0;
out:
BN_CTX_free(bn_ctx);
if (h != NULL)
BN_clear_free(h);
- BN_clear_free(g_v);
- BN_clear_free(r);
BN_clear_free(g_xh);
BN_clear_free(g_r);
BN_clear_free(expected);
return success;
}
+/*
+ * Verify Schnorr signature 'sig' of length 'siglen' against public exponent
+ * g_x (g^x) under group defined by 'grp_p', 'grp_q' and 'grp_g' using a
+ * SHA256 hash.
+ * Signature hash will be salted with 'idlen' bytes from 'id'.
+ * Returns -1 on failure, 0 on incorrect signature or 1 on matching signature.
+ */
+int
+schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q,
+ const BIGNUM *grp_g,
+ const BIGNUM *g_x, const u_char *id, u_int idlen,
+ const u_char *sig, u_int siglen)
+{
+ Buffer b;
+ int ret = -1;
+ u_int rlen;
+ BIGNUM *r, *e;
+
+ e = r = NULL;
+ if ((e = BN_new()) == NULL ||
+ (r = BN_new()) == NULL) {
+ error("%s: BN_new", __func__);
+ goto out;
+ }
+
+ /* Extract g^v and r from signature blob */
+ buffer_init(&b);
+ buffer_append(&b, sig, siglen);
+ SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b),
+ "%s: sigblob", __func__));
+ buffer_get_bignum2(&b, e);
+ buffer_get_bignum2(&b, r);
+ rlen = buffer_len(&b);
+ buffer_free(&b);
+ if (rlen != 0) {
+ error("%s: remaining bytes in signature %d", __func__, rlen);
+ goto out;
+ }
+
+ ret = schnorr_verify(grp_p, grp_q, grp_g, EVP_sha256(),
+ g_x, id, idlen, r, e);
+ out:
+ BN_clear_free(e);
+ BN_clear_free(r);
+
+ return ret;
+}
+
+/* Helper functions */
+
+/*
+ * Generate uniformly distributed random number in range (1, high).
+ * Return number on success, NULL on failure.
+ */
+BIGNUM *
+bn_rand_range_gt_one(const BIGNUM *high)
+{
+ BIGNUM *r, *tmp;
+ int success = -1;
+
+ if ((tmp = BN_new()) == NULL) {
+ error("%s: BN_new", __func__);
+ return NULL;
+ }
+ if ((r = BN_new()) == NULL) {
+ error("%s: BN_new failed", __func__);
+ goto out;
+ }
+ if (BN_set_word(tmp, 2) != 1) {
+ error("%s: BN_set_word(tmp, 2)", __func__);
+ goto out;
+ }
+ if (BN_sub(tmp, high, tmp) == -1) {
+ error("%s: BN_sub failed (tmp = high - 2)", __func__);
+ goto out;
+ }
+ if (BN_rand_range(r, tmp) == -1) {
+ error("%s: BN_rand_range failed", __func__);
+ goto out;
+ }
+ if (BN_set_word(tmp, 2) != 1) {
+ error("%s: BN_set_word(tmp, 2)", __func__);
+ goto out;
+ }
+ if (BN_add(r, r, tmp) == -1) {
+ error("%s: BN_add failed (r = r + 2)", __func__);
+ goto out;
+ }
+ success = 0;
+ out:
+ BN_clear_free(tmp);
+ if (success == 0)
+ return r;
+ BN_clear_free(r);
+ return NULL;
+}
+
+/*
+ * Hash contents of buffer 'b' with hash 'md'. Returns 0 on success,
+ * with digest via 'digestp' (caller to free) and length via 'lenp'.
+ * Returns -1 on failure.
+ */
+int
+hash_buffer(const u_char *buf, u_int len, const EVP_MD *md,
+ u_char **digestp, u_int *lenp)
+{
+ u_char digest[EVP_MAX_MD_SIZE];
+ u_int digest_len;
+ EVP_MD_CTX evp_md_ctx;
+ int success = -1;
+
+ EVP_MD_CTX_init(&evp_md_ctx);
+
+ if (EVP_DigestInit_ex(&evp_md_ctx, md, NULL) != 1) {
+ error("%s: EVP_DigestInit_ex", __func__);
+ goto out;
+ }
+ if (EVP_DigestUpdate(&evp_md_ctx, buf, len) != 1) {
+ error("%s: EVP_DigestUpdate", __func__);
+ goto out;
+ }
+ if (EVP_DigestFinal_ex(&evp_md_ctx, digest, &digest_len) != 1) {
+ error("%s: EVP_DigestFinal_ex", __func__);
+ goto out;
+ }
+ *digestp = xmalloc(digest_len);
+ *lenp = digest_len;
+ memcpy(*digestp, digest, *lenp);
+ success = 0;
+ out:
+ EVP_MD_CTX_cleanup(&evp_md_ctx);
+ bzero(digest, sizeof(digest));
+ digest_len = 0;
+ return success;
+}
+
+/* print formatted string followed by bignum */
+void
+debug3_bn(const BIGNUM *n, const char *fmt, ...)
+{
+ char *out, *h;
+ va_list args;
+
+ out = NULL;
+ va_start(args, fmt);
+ vasprintf(&out, fmt, args);
+ va_end(args);
+ if (out == NULL)
+ fatal("%s: vasprintf failed", __func__);
+
+ if (n == NULL)
+ debug3("%s(null)", out);
+ else {
+ h = BN_bn2hex(n);
+ debug3("%s0x%s", out, h);
+ free(h);
+ }
+ free(out);
+}
+
+/* print formatted string followed by buffer contents in hex */
+void
+debug3_buf(const u_char *buf, u_int len, const char *fmt, ...)
+{
+ char *out, h[65];
+ u_int i, j;
+ va_list args;
+
+ out = NULL;
+ va_start(args, fmt);
+ vasprintf(&out, fmt, args);
+ va_end(args);
+ if (out == NULL)
+ fatal("%s: vasprintf failed", __func__);
+
+ debug3("%s length %u%s", out, len, buf == NULL ? " (null)" : "");
+ free(out);
+ if (buf == NULL)
+ return;
+
+ *h = '\0';
+ for (i = j = 0; i < len; i++) {
+ snprintf(h + j, sizeof(h) - j, "%02x", buf[i]);
+ j += 2;
+ if (j >= sizeof(h) - 1 || i == len - 1) {
+ debug3(" %s", h);
+ *h = '\0';
+ j = 0;
+ }
+ }
+}
+
+/*
+ * Construct a MODP group from hex strings p (which must be a safe
+ * prime) and g, automatically calculating subgroup q as (p / 2)
+ */
+struct modp_group *
+modp_group_from_g_and_safe_p(const char *grp_g, const char *grp_p)
+{
+ struct modp_group *ret;
+
+ ret = xmalloc(sizeof(*ret));
+ ret->p = ret->q = ret->g = NULL;
+ if (BN_hex2bn(&ret->p, grp_p) == 0 ||
+ BN_hex2bn(&ret->g, grp_g) == 0)
+ fatal("%s: BN_hex2bn", __func__);
+ /* Subgroup order is p/2 (p is a safe prime) */
+ if ((ret->q = BN_new()) == NULL)
+ fatal("%s: BN_new", __func__);
+ if (BN_rshift1(ret->q, ret->p) != 1)
+ fatal("%s: BN_rshift1", __func__);
+
+ return ret;
+}
+
+void
+modp_group_free(struct modp_group *grp)
+{
+ if (grp->g != NULL)
+ BN_clear_free(grp->g);
+ if (grp->p != NULL)
+ BN_clear_free(grp->p);
+ if (grp->q != NULL)
+ BN_clear_free(grp->q);
+ bzero(grp, sizeof(*grp));
+ xfree(grp);
+}
+
+/* main() function for self-test */
+
#ifdef SCHNORR_MAIN
static void
schnorr_selftest_one(const BIGNUM *grp_p, const BIGNUM *grp_q,
if (BN_mod_exp(g_x, grp_g, x, grp_p, bn_ctx) == -1)
fatal("%s: g_x", __func__);
- if (schnorr_sign(grp_p, grp_q, grp_g, x, g_x, "junk", 4, &sig, &siglen))
+ if (schnorr_sign_buf(grp_p, grp_q, grp_g, x, g_x, "junk", 4,
+ &sig, &siglen))
fatal("%s: schnorr_sign", __func__);
- if (schnorr_verify(grp_p, grp_q, grp_g, g_x, "junk", 4,
+ if (schnorr_verify_buf(grp_p, grp_q, grp_g, g_x, "junk", 4,
sig, siglen) != 1)
fatal("%s: verify fail", __func__);
- if (schnorr_verify(grp_p, grp_q, grp_g, g_x, "JUNK", 4,
+ if (schnorr_verify_buf(grp_p, grp_q, grp_g, g_x, "JUNK", 4,
sig, siglen) != 0)
fatal("%s: verify should have failed (bad ID)", __func__);
sig[4] ^= 1;
- if (schnorr_verify(grp_p, grp_q, grp_g, g_x, "junk", 4,
+ if (schnorr_verify_buf(grp_p, grp_q, grp_g, g_x, "junk", 4,
sig, siglen) != 0)
fatal("%s: verify should have failed (bit error)", __func__);
xfree(sig);
schnorr_selftest(void)
{
BIGNUM *x;
- struct jpake_group *grp;
+ struct modp_group *grp;
u_int i;
char *hh;
--- /dev/null
+/* $OpenBSD: schnorr.h,v 1.1 2009/03/05 07:18:19 djm Exp $ */
+/*
+ * Copyright (c) 2009 Damien Miller. All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef SCHNORR_H
+#define SCHNORR_H
+
+#include <sys/types.h>
+
+#include <openssl/bn.h>
+
+struct modp_group {
+ BIGNUM *p, *q, *g;
+};
+
+BIGNUM *bn_rand_range_gt_one(const BIGNUM *high);
+int hash_buffer(const u_char *, u_int, const EVP_MD *, u_char **, u_int *);
+void debug3_bn(const BIGNUM *, const char *, ...)
+ __attribute__((__nonnull__ (2)))
+ __attribute__((format(printf, 2, 3)));
+void debug3_buf(const u_char *, u_int, const char *, ...)
+ __attribute__((__nonnull__ (3)))
+ __attribute__((format(printf, 3, 4)));
+struct modp_group *modp_group_from_g_and_safe_p(const char *, const char *);
+void modp_group_free(struct modp_group *);
+
+/* Signature and verification functions */
+int
+schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
+ const EVP_MD *evp_md, const BIGNUM *x, const BIGNUM *g_x,
+ const u_char *id, u_int idlen, BIGNUM **r_p, BIGNUM **e_p);
+int
+schnorr_sign_buf(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
+ const BIGNUM *x, const BIGNUM *g_x, const u_char *id, u_int idlen,
+ u_char **sig, u_int *siglen);
+int
+schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g,
+ const EVP_MD *evp_md, const BIGNUM *g_x, const u_char *id, u_int idlen,
+ const BIGNUM *r, const BIGNUM *e);
+int
+schnorr_verify_buf(const BIGNUM *grp_p, const BIGNUM *grp_q,
+ const BIGNUM *grp_g,
+ const BIGNUM *g_x, const u_char *id, u_int idlen,
+ const u_char *sig, u_int siglen);
+
+#endif /* JPAKE_H */
+
-/* $OpenBSD: servconf.c,v 1.194 2009/01/22 10:02:34 djm Exp $ */
+/* $OpenBSD: servconf.c,v 1.195 2009/04/14 21:10:54 jj Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
{ "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
- { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
+ { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
#ifdef KRB5
{ "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
{ "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
- { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
+ { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL},
{ "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
{ "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
- { "match", sMatch, SSHCFG_ALL },
+ { "match", sMatch, SSHCFG_ALL },
{ "permitopen", sPermitOpen, SSHCFG_ALL },
{ "forcecommand", sForceCommand, SSHCFG_ALL },
{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
/*
* Copy any supported values that are set.
*
- * If the preauth flag is set, we do not bother copying the the string or
+ * If the preauth flag is set, we do not bother copying the string or
* array values that are not used pre-authentication, because any that we
* do use must be explictly sent in mm_getpwnamallow().
*/
-/* $OpenBSD: serverloop.c,v 1.157 2009/02/12 03:16:01 djm Exp $ */
+/* $OpenBSD: serverloop.c,v 1.159 2009/05/28 16:50:16 andreas Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
#include "auth-options.h"
#include "serverloop.h"
#include "misc.h"
+#include "roaming.h"
extern ServerOptions options;
int channel_id;
/* timeout, check to see how many we have had */
- if (++keep_alive_timeouts > options.client_alive_count_max) {
+ if (packet_inc_alive_timeouts() > options.client_alive_count_max) {
logit("Timeout, client not responding.");
cleanup_exit(255);
}
/* Read and buffer any input data from the client. */
if (FD_ISSET(connection_in, readset)) {
- len = read(connection_in, buf, sizeof(buf));
+ int cont = 0;
+ len = roaming_read(connection_in, buf, sizeof(buf), &cont);
if (len == 0) {
+ if (cont)
+ return;
verbose("Connection closed by %.100s",
get_remote_ipaddr());
connection_closed = 1;
* even if this was generated by something other than
* the bogus CHANNEL_REQUEST we send for keepalives.
*/
- keep_alive_timeouts = 0;
+ packet_set_alive_timeouts(0);
}
static void
no_port_forwarding_flag ||
(!want_reply && listen_port == 0)
#ifndef NO_IPPORT_RESERVED_CONCEPT
- || (listen_port < IPPORT_RESERVED && pw->pw_uid != 0)
+ || (listen_port != 0 && listen_port < IPPORT_RESERVED &&
+ pw->pw_uid != 0)
#endif
) {
success = 0;
-/* $OpenBSD: session.c,v 1.245 2009/01/22 09:46:01 djm Exp $ */
+/* $OpenBSD: session.c,v 1.246 2009/04/17 19:23:06 stevesk Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
signal(WJSIGNAL, cray_job_termination_handler);
#endif /* _UNICOS */
#ifdef HAVE_CYGWIN
- if (is_winnt)
- cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
+ cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
#endif
s->pid = pid;
* Do common processing for the child, such as execing
* the command.
*/
- do_child(s, command);
- /* NOTREACHED */
+ do_child(s, command);
+ /* NOTREACHED */
default:
break;
}
signal(WJSIGNAL, cray_job_termination_handler);
#endif /* _UNICOS */
#ifdef HAVE_CYGWIN
- if (is_winnt)
- cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
+ cygwin_set_impersonation_token(INVALID_HANDLE_VALUE);
#endif
s->pid = pid;
fromlen = sizeof(from);
if (packet_connection_is_on_socket()) {
if (getpeername(packet_get_connection_in(),
- (struct sockaddr *) & from, &fromlen) < 0) {
+ (struct sockaddr *)&from, &fromlen) < 0) {
debug("getpeername: %.100s", strerror(errno));
cleanup_exit(255);
}
u_int i, envsize;
char **env, *laddr;
struct passwd *pw = s->pw;
-#ifndef HAVE_LOGIN_CAP
+#if !defined (HAVE_LOGIN_CAP) && !defined (HAVE_CYGWIN)
char *path = NULL;
#endif
if (getuid() == 0 || geteuid() == 0)
#endif /* HAVE_CYGWIN */
{
-
-#ifdef HAVE_SETPCRED
- if (setpcred(pw->pw_name, (char **)NULL) == -1)
- fatal("Failed to set process credentials");
-#endif /* HAVE_SETPCRED */
#ifdef HAVE_LOGIN_CAP
# ifdef __bsdi__
setpgid(0, 0);
free(chroot_path);
}
+#ifdef HAVE_SETPCRED
+ if (setpcred(pw->pw_name, (char **)NULL) == -1)
+ fatal("Failed to set process credentials");
+#endif /* HAVE_SETPCRED */
#ifdef HAVE_LOGIN_CAP
if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETUSER) < 0) {
perror("unable to set user context (setuser)");
#endif
}
-#ifdef HAVE_CYGWIN
- if (is_winnt)
-#endif
if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
int i;
char *p, *args;
- setproctitle("%s@internal-sftp-server", s->pw->pw_name);
+ setproctitle("%s@%s", s->pw->pw_name, INTERNAL_SFTP_NAME);
args = xstrdup(command ? command : "sftp-server");
for (i = 0, (p = strtok(args, " ")); p; (p = strtok(NULL, " ")))
if (i < ARGV_MAX - 1)
-/* $OpenBSD: sftp-client.c,v 1.86 2008/06/26 06:10:09 djm Exp $ */
+/* $OpenBSD: sftp-client.c,v 1.87 2009/06/22 05:39:28 dtucker Exp $ */
/*
* Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
*
-.\" $OpenBSD: sftp-server.8,v 1.14 2008/07/18 22:51:01 jmc Exp $
+.\" $OpenBSD: sftp-server.8,v 1.15 2009/03/26 08:38:39 sobrado Exp $
.\"
.\" Copyright (c) 2000 Markus Friedl. All rights reserved.
.\"
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: July 18 2008 $
+.Dd $Mdocdate: March 26 2009 $
.Dt SFTP-SERVER 8
.Os
.Sh NAME
.Pa /dev/log .
Use of
.Nm
-in a chroot configuation therefore requires that
+in a chroot configuration therefore requires that
.Xr syslogd 8
establish a logging socket inside the chroot directory.
.Sh SEE ALSO
-/* $OpenBSD: sftp-server.c,v 1.84 2008/06/26 06:10:09 djm Exp $ */
+/* $OpenBSD: sftp-server.c,v 1.85 2009/04/14 16:33:42 stevesk Exp $ */
/*
* Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
*
else if (S_ISREG(sb.st_mode)) {
/* Race-free rename of regular files */
if (link(oldpath, newpath) == -1) {
- if (errno == EOPNOTSUPP
+ if (errno == EOPNOTSUPP || errno == ENOSYS
#ifdef EXDEV
|| errno == EXDEV
#endif
__progname = ssh_get_progname(argv[0]);
log_init(__progname, log_level, log_facility, log_stderr);
- while (!skipargs && (ch = getopt(argc, argv, "C:f:l:che")) != -1) {
+ while (!skipargs && (ch = getopt(argc, argv, "f:l:che")) != -1) {
switch (ch) {
case 'c':
/*
-.\" $OpenBSD: ssh-agent.1,v 1.46 2007/09/09 11:38:01 sobrado Exp $
+.\" $OpenBSD: ssh-agent.1,v 1.47 2009/03/26 08:38:39 sobrado Exp $
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: June 5 2007 $
+.Dd $Mdocdate: March 26 2009 $
.Dt SSH-AGENT 1
.Os
.Sh NAME
.Xr sh 1
or
.Xr csh 1
-syntax can be generated) which can be evalled in the calling shell, eg
+syntax can be generated) which can be evaluated in the calling shell, eg
.Cm eval `ssh-agent -s`
for Bourne-type shells such as
.Xr sh 1
-/* $OpenBSD: ssh-agent.c,v 1.159 2008/06/28 14:05:15 djm Exp $ */
+/* $OpenBSD: ssh-agent.c,v 1.161 2009/03/23 19:38:04 tobias Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
pid_t pid;
char pidstrbuf[1 + 3 * sizeof pid];
struct timeval *tvp = NULL;
+ size_t len;
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
if (ac == 0 && !c_flag && !s_flag) {
shell = getenv("SHELL");
- if (shell != NULL &&
- strncmp(shell + strlen(shell) - 3, "csh", 3) == 0)
+ if (shell != NULL && (len = strlen(shell)) > 2 &&
+ strncmp(shell + len - 3, "csh", 3) == 0)
c_flag = 1;
}
if (k_flag) {
-/* $OpenBSD: ssh-keygen.c,v 1.173 2009/02/21 19:32:04 tobias Exp $ */
+/* $OpenBSD: ssh-keygen.c,v 1.174 2009/06/22 05:39:28 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
.\" (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.1,v 1.282 2009/02/12 03:44:25 djm Exp $
-.Dd $Mdocdate: February 12 2009 $
+.\" $OpenBSD: ssh.1,v 1.283 2009/03/19 15:15:09 jmc Exp $
+.Dd $Mdocdate: March 19 2009 $
.Dt SSH 1
.Os
.Sh NAME
.Ar cipher_spec
is a comma-separated list of ciphers
listed in order of preference.
-The supported ciphers are:
-3des-cbc,
-aes128-cbc,
-aes192-cbc,
-aes256-cbc,
-aes128-ctr,
-aes192-ctr,
-aes256-ctr,
-arcfour128,
-arcfour256,
-arcfour,
-blowfish-cbc,
-and
-cast128-cbc.
-The default is:
-.Bd -literal -offset indent
-aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128,
-arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr,
-aes192-ctr,aes256-ctr
-.Ed
+See the
+.Cm Ciphers
+keyword for more information.
.It Fl D Xo
.Sm off
.Oo Ar bind_address : Oc
-/* $OpenBSD: ssh.c,v 1.324 2009/02/12 03:00:56 djm Exp $ */
+/* $OpenBSD: ssh.c,v 1.326 2009/07/02 02:11:47 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
#endif
#include <sys/resource.h>
#include <sys/ioctl.h>
+#include <sys/param.h>
#include <sys/socket.h>
#include <ctype.h>
int
main(int ac, char **av)
{
- int i, opt, exit_status, use_syslog;
- char *p, *cp, *line, buf[256];
+ int i, r, opt, exit_status, use_syslog;
+ char *p, *cp, *line, *argv0, buf[MAXPATHLEN];
struct stat st;
struct passwd *pw;
int dummy, timeout_ms;
/* Parse command-line arguments. */
host = NULL;
use_syslog = 0;
+ argv0 = av[0];
again:
while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
* Initialize "log" output. Since we are the client all output
* actually goes to stderr.
*/
- log_init(av[0],
+ log_init(argv0,
options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level,
SYSLOG_FACILITY_USER, !use_syslog);
fatal("Can't open user config file %.100s: "
"%.100s", config, strerror(errno));
} else {
- snprintf(buf, sizeof buf, "%.100s/%.100s", pw->pw_dir,
+ r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
_PATH_SSH_USER_CONFFILE);
- (void)read_config_file(buf, host, &options, 1);
+ if (r > 0 && (size_t)r < sizeof(buf))
+ (void)read_config_file(buf, host, &options, 1);
/* Read systemwide configuration file after use config. */
(void)read_config_file(_PATH_HOST_CONFIG_FILE, host,
channel_set_af(options.address_family);
/* reinit */
- log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, !use_syslog);
+ log_init(argv0, options.log_level, SYSLOG_FACILITY_USER, !use_syslog);
seed_rng();
* Now that we are back to our own permissions, create ~/.ssh
* directory if it doesn't already exist.
*/
- snprintf(buf, sizeof buf, "%.100s%s%.100s", pw->pw_dir,
+ r = snprintf(buf, sizeof buf, "%s%s%s", pw->pw_dir,
strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
- if (stat(buf, &st) < 0)
+ if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0)
if (mkdir(buf, 0700) < 0)
error("Could not create directory '%.200s'.", buf);
-/* $OpenBSD: sshconnect.c,v 1.212 2008/10/14 18:11:33 stevesk Exp $ */
+/* $OpenBSD: sshconnect.c,v 1.214 2009/05/28 16:50:16 andreas Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
#include "atomicio.h"
#include "misc.h"
#include "dns.h"
+#include "roaming.h"
#include "version.h"
char *client_version_string = NULL;
* Waits for the server identification string, and sends our own
* identification string.
*/
-static void
+void
ssh_exchange_identification(int timeout_ms)
{
char buf[256], remote_version[256]; /* must be same size! */
}
}
- len = atomicio(read, connection_in, &buf[i], 1);
+ len = roaming_atomicio(read, connection_in, &buf[i], 1);
if (len != 1 && errno == EPIPE)
fatal("ssh_exchange_identification: "
compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
compat20 ? PROTOCOL_MINOR_2 : minor1,
SSH_VERSION, compat20 ? "\r\n" : "\n");
- if (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf))
+ if (roaming_atomicio(vwrite, connection_out, buf, strlen(buf))
+ != strlen(buf))
fatal("write: %.100s", strerror(errno));
client_version_string = xstrdup(buf);
chop(client_version_string);
-/* $OpenBSD: sshconnect.h,v 1.24 2007/09/04 11:15:56 djm Exp $ */
+/* $OpenBSD: sshconnect.h,v 1.25 2009/05/27 06:38:16 andreas Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
void
ssh_login(Sensitive *, const char *, struct sockaddr *, struct passwd *, int);
+void ssh_exchange_identification(int);
+
int verify_host_key(char *, struct sockaddr *, Key *);
void ssh_kex(char *, struct sockaddr *);
-/* $OpenBSD: sshconnect2.c,v 1.170 2008/11/04 08:22:13 djm Exp $ */
+/* $OpenBSD: sshconnect2.c,v 1.171 2009/03/05 07:18:19 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Damien Miller. All rights reserved.
#include "msg.h"
#include "pathnames.h"
#include "uidswap.h"
+#include "schnorr.h"
#include "jpake.h"
#ifdef GSSAPI
.\" (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: sshd.8,v 1.247 2008/10/03 13:08:12 jmc Exp $
-.Dd $Mdocdate: October 3 2008 $
+.\" $OpenBSD: sshd.8,v 1.248 2009/03/26 08:38:39 sobrado Exp $
+.Dd $Mdocdate: March 26 2009 $
.Dt SSHD 8
.Os
.Sh NAME
In addition to the wildcard matching that may be applied to hostnames or
addresses, a
.Cm from
-stanza may match IP addressess using CIDR address/masklen notation.
+stanza may match IP addresses using CIDR address/masklen notation.
.Pp
The purpose of this option is to optionally increase security: public key
authentication by itself does not trust the network or name servers or
-/* $OpenBSD: sshd.c,v 1.366 2009/01/22 10:02:34 djm Exp $ */
+/* $OpenBSD: sshd.c,v 1.367 2009/05/28 16:50:16 andreas Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
#include "ssh-gss.h"
#endif
#include "monitor_wrap.h"
+#include "roaming.h"
#include "version.h"
#ifdef LIBWRAP
server_version_string = xstrdup(buf);
/* Send our protocol version identification. */
- if (atomicio(vwrite, sock_out, server_version_string,
+ if (roaming_atomicio(vwrite, sock_out, server_version_string,
strlen(server_version_string))
!= strlen(server_version_string)) {
logit("Could not write ident string to %s", get_remote_ipaddr());
/* Read other sides version identification. */
memset(buf, 0, sizeof(buf));
for (i = 0; i < sizeof(buf) - 1; i++) {
- if (atomicio(read, sock_in, &buf[i], 1) != 1) {
+ if (roaming_atomicio(read, sock_in, &buf[i], 1) != 1) {
logit("Did not receive identification string from %s",
get_remote_ipaddr());
cleanup_exit(255);
static void
privsep_preauth_child(void)
{
- u_int32_t rnd[256];
+ u_int32_t rnd[256];
gid_t gidset[1];
/* Enable challenge-response authentication for privilege separation */
.\" (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: sshd_config.5,v 1.102 2009/02/22 23:59:25 djm Exp $
-.Dd $Mdocdate: February 22 2009 $
+.\" $OpenBSD: sshd_config.5,v 1.106 2009/04/21 15:13:17 stevesk Exp $
+.Dd $Mdocdate: April 21 2009 $
.Dt SSHD_CONFIG 5
.Os
.Sh NAME
This option is only available for protocol version 2.
By default, no banner is displayed.
.It Cm ChallengeResponseAuthentication
-Specifies whether challenge-response authentication is allowed.
-All authentication styles from
-.Xr login.conf 5
-are supported.
+Specifies whether challenge-response authentication is allowed (e.g. via
+PAM or though authentication styles supported in
+.Xr login.conf 5 )
The default is
.Dq yes .
.It Cm ChrootDirectory
to after authentication.
This path, and all its components, must be root-owned directories that are
not writable by any other user or group.
+After the chroot,
+.Xr sshd 8
+changes the working directory to the user's home directory.
.Pp
The path may contain the following tokens that are expanded at runtime once
the connecting user has been authenticated: %% is replaced by a literal '%',
The
.Cm ChrootDirectory
must contain the necessary files and directories to support the
-users' session.
+user's session.
For an interactive session this requires at least a shell, typically
.Xr sh 1 ,
and basic
For file transfer sessions using
.Dq sftp ,
no additional configuration of the environment is necessary if the
-in-process sftp server is used (see
-.Cm Subsystem
+in-process sftp server is used,
+though sessions which use logging do require
+.Pa /dev/log
+inside the chroot directory (see
+.Xr sftp-server 8
for details).
.Pp
The default is not to
static void
store_lastlog_message(const char *user, uid_t uid)
{
+#ifndef NO_SSH_LASTLOG
char *time_string, hostname[MAXHOSTNAMELEN] = "", buf[512];
time_t last_login_time;
-#ifndef NO_SSH_LASTLOG
if (!options.print_lastlog)
return;
+# ifdef CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG
+ time_string = sys_auth_get_lastlogin_msg(user, uid);
+ if (time_string != NULL) {
+ buffer_append(&loginmsg, time_string, strlen(time_string));
+ xfree(time_string);
+ }
+# else
last_login_time = get_last_login_time(uid, user, hostname,
sizeof(hostname));
time_string, hostname);
buffer_append(&loginmsg, buf, strlen(buf));
}
+# endif /* CUSTOM_SYS_AUTH_GET_LASTLOGIN_MSG */
#endif /* NO_SSH_LASTLOG */
}
-/* $OpenBSD: uuencode.c,v 1.24 2006/08/03 03:34:42 deraadt Exp $ */
+/* $OpenBSD: uuencode.c,v 1.25 2009/03/05 11:30:50 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
#include "xmalloc.h"
#include "uuencode.h"
+/*
+ * Encode binary 'src' of length 'srclength', writing base64-encoded text
+ * to 'target' of size 'targsize'. Will always nul-terminate 'target'.
+ * Returns the number of bytes stored in 'target' or -1 on error (inc.
+ * 'targsize' too small).
+ */
int
uuencode(const u_char *src, u_int srclength,
char *target, size_t targsize)
return __b64_ntop(src, srclength, target, targsize);
}
+/*
+ * Decode base64-encoded 'src' into buffer 'target' of 'targsize' bytes.
+ * Will skip leading and trailing whitespace. Returns the number of bytes
+ * stored in 'target' or -1 on error (inc. targsize too small).
+ */
int
uudecode(const char *src, u_char *target, size_t targsize)
{
-/* $OpenBSD: version.h,v 1.55 2009/02/23 00:06:15 djm Exp $ */
+/* $OpenBSD: version.h,v 1.56 2009/06/30 14:54:40 markus Exp $ */
-#define SSH_VERSION "OpenSSH_5.2"
+#define SSH_VERSION "OpenSSH_5.3"
#define SSH_PORTABLE "p1"
#define SSH_RELEASE SSH_VERSION SSH_PORTABLE