summaryrefslogtreecommitdiffstats
path: root/crypto/openssh
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2002-03-18 09:55:03 +0000
committerdes <des@FreeBSD.org>2002-03-18 09:55:03 +0000
commitec85a15f0e96d6f55b777e58d6cd8667d4068a01 (patch)
treed05ec686716cc1fd538eac3b98c796c8b5982dcb /crypto/openssh
parent2e2afe2675da81a967a0e183c832cf63ac46d9d5 (diff)
parent2fc4a488978a03338ecc65403597582c77dabeea (diff)
downloadFreeBSD-src-ec85a15f0e96d6f55b777e58d6cd8667d4068a01.zip
FreeBSD-src-ec85a15f0e96d6f55b777e58d6cd8667d4068a01.tar.gz
This commit was generated by cvs2svn to compensate for changes in r92555,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'crypto/openssh')
-rw-r--r--crypto/openssh/LICENCE84
-rw-r--r--crypto/openssh/Makefile8
-rw-r--r--crypto/openssh/Makefile.inc15
-rw-r--r--crypto/openssh/OVERVIEW6
-rw-r--r--crypto/openssh/README2
-rw-r--r--crypto/openssh/README.smartcard69
-rw-r--r--crypto/openssh/atomicio.c3
-rw-r--r--crypto/openssh/atomicio.h4
-rw-r--r--crypto/openssh/auth-bsdauth.c116
-rw-r--r--crypto/openssh/auth-options.c51
-rw-r--r--crypto/openssh/auth-options.h14
-rw-r--r--crypto/openssh/auth-rhosts.c27
-rw-r--r--crypto/openssh/auth2-chall.c288
-rw-r--r--crypto/openssh/authfd.h106
-rw-r--r--crypto/openssh/authfile.h26
-rw-r--r--crypto/openssh/bufaux.h51
-rw-r--r--crypto/openssh/buffer.c27
-rw-r--r--crypto/openssh/buffer.h57
-rw-r--r--crypto/openssh/canohost.h33
-rw-r--r--crypto/openssh/clientloop.c309
-rw-r--r--crypto/openssh/clientloop.h4
-rw-r--r--crypto/openssh/compress.c28
-rw-r--r--crypto/openssh/compress.h38
-rw-r--r--crypto/openssh/crc32.h10
-rw-r--r--crypto/openssh/deattack.c18
-rw-r--r--crypto/openssh/deattack.h4
-rw-r--r--crypto/openssh/dh.c53
-rw-r--r--crypto/openssh/dh.h10
-rw-r--r--crypto/openssh/dispatch.c40
-rw-r--r--crypto/openssh/dispatch.h14
-rw-r--r--crypto/openssh/fatal.c40
-rw-r--r--crypto/openssh/getput.h4
-rw-r--r--crypto/openssh/groupaccess.c14
-rw-r--r--crypto/openssh/groupaccess.h21
-rw-r--r--crypto/openssh/hostfile.h22
-rw-r--r--crypto/openssh/kex.c90
-rw-r--r--crypto/openssh/kex.h28
-rw-r--r--crypto/openssh/kexdh.c68
-rw-r--r--crypto/openssh/kexgex.c83
-rw-r--r--crypto/openssh/key.h56
-rw-r--r--crypto/openssh/lib/Makefile12
-rw-r--r--crypto/openssh/log.c23
-rw-r--r--crypto/openssh/log.h48
-rw-r--r--crypto/openssh/mac.c6
-rw-r--r--crypto/openssh/mac.h8
-rw-r--r--crypto/openssh/match.c85
-rw-r--r--crypto/openssh/match.h29
-rw-r--r--crypto/openssh/misc.c207
-rw-r--r--crypto/openssh/misc.h33
-rw-r--r--crypto/openssh/mpaux.h15
-rw-r--r--crypto/openssh/myproposal.h6
-rw-r--r--crypto/openssh/nchan.c369
-rw-r--r--crypto/openssh/nchan2.ms24
-rw-r--r--crypto/openssh/packet.c459
-rw-r--r--crypto/openssh/radix.c22
-rw-r--r--crypto/openssh/radix.h6
-rw-r--r--crypto/openssh/readpass.c109
-rw-r--r--crypto/openssh/readpass.h12
-rw-r--r--crypto/openssh/rijndael.c1594
-rw-r--r--crypto/openssh/rijndael.h92
-rw-r--r--crypto/openssh/scard.c372
-rw-r--r--crypto/openssh/scard.h40
-rw-r--r--crypto/openssh/scard/Makefile20
-rw-r--r--crypto/openssh/scard/Ssh.bin.uu16
-rw-r--r--crypto/openssh/scard/Ssh.java143
-rw-r--r--crypto/openssh/scp.130
-rw-r--r--crypto/openssh/scp.c152
-rw-r--r--crypto/openssh/scp/Makefile4
-rw-r--r--crypto/openssh/serverloop.h11
-rw-r--r--crypto/openssh/session.h15
-rw-r--r--crypto/openssh/sftp-client.c611
-rw-r--r--crypto/openssh/sftp-client.h55
-rw-r--r--crypto/openssh/sftp-common.c11
-rw-r--r--crypto/openssh/sftp-common.h21
-rw-r--r--crypto/openssh/sftp-glob.c71
-rw-r--r--crypto/openssh/sftp-glob.h14
-rw-r--r--crypto/openssh/sftp-int.c156
-rw-r--r--crypto/openssh/sftp-int.h6
-rw-r--r--crypto/openssh/sftp-server.82
-rw-r--r--crypto/openssh/sftp-server.c130
-rw-r--r--crypto/openssh/sftp.1117
-rw-r--r--crypto/openssh/sftp.c220
-rw-r--r--crypto/openssh/sftp.h3
-rw-r--r--crypto/openssh/sftp/Makefile4
-rw-r--r--crypto/openssh/ssh-add.141
-rw-r--r--crypto/openssh/ssh-agent.140
-rw-r--r--crypto/openssh/ssh-agent/Makefile2
-rw-r--r--crypto/openssh/ssh-dss.c104
-rw-r--r--crypto/openssh/ssh-dss.h15
-rw-r--r--crypto/openssh/ssh-keygen.163
-rw-r--r--crypto/openssh/ssh-keygen.c386
-rw-r--r--crypto/openssh/ssh-keygen/Makefile2
-rw-r--r--crypto/openssh/ssh-keyscan.1120
-rw-r--r--crypto/openssh/ssh-keyscan.c381
-rw-r--r--crypto/openssh/ssh-keyscan/Makefile6
-rw-r--r--crypto/openssh/ssh-rsa.c47
-rw-r--r--crypto/openssh/ssh-rsa.h15
-rw-r--r--crypto/openssh/ssh/Makefile10
-rw-r--r--crypto/openssh/ssh1.h7
-rw-r--r--crypto/openssh/ssh2.h18
-rw-r--r--crypto/openssh/sshd/Makefile26
-rw-r--r--crypto/openssh/sshlogin.h27
-rw-r--r--crypto/openssh/sshpty.h35
-rw-r--r--crypto/openssh/sshtty.c4
-rw-r--r--crypto/openssh/sshtty.h25
-rw-r--r--crypto/openssh/tildexpand.c4
-rw-r--r--crypto/openssh/tildexpand.h8
-rw-r--r--crypto/openssh/ttymodes.c23
-rw-r--r--crypto/openssh/ttymodes.h3
-rw-r--r--crypto/openssh/uidswap.c8
-rw-r--r--crypto/openssh/uidswap.h22
-rw-r--r--crypto/openssh/uuencode.c10
-rw-r--r--crypto/openssh/uuencode.h10
-rw-r--r--crypto/openssh/xmalloc.c7
-rw-r--r--crypto/openssh/xmalloc.h19
115 files changed, 5680 insertions, 3132 deletions
diff --git a/crypto/openssh/LICENCE b/crypto/openssh/LICENCE
index f60f502..1c98a1d 100644
--- a/crypto/openssh/LICENCE
+++ b/crypto/openssh/LICENCE
@@ -26,7 +26,7 @@ OpenSSH contains no GPL code.
[However, none of that term is relevant at this point in time. All of
these restrictively licenced software components which he talks about
- have been removed from OpenSSH, ie.
+ have been removed from OpenSSH, i.e.,
- RSA is no longer included, found in the OpenSSL library
- IDEA is no longer included, its use is deprecated
@@ -85,8 +85,7 @@ OpenSSH contains no GPL code.
3)
The 32-bit CRC compensation attack detector in deattack.c was
- contributed by CORE SDI S.A. under a BSD-style license. See
- http://www.core-sdi.com/english/ssh/ for details.
+ contributed by CORE SDI S.A. under a BSD-style license.
* Cryptographic attack detector for ssh - source code
*
@@ -104,8 +103,83 @@ OpenSSH contains no GPL code.
*
* Ariel Futoransky <futo@core-sdi.com>
* <http://www.core-sdi.com>
-
+
4)
+ ssh-keygen was contributed by David Mazieres under a BSD-style
+ license.
+
+ * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
+ *
+ * Modification and redistribution in source and binary forms is
+ * permitted provided that due credit is given to the author and the
+ * OpenBSD project by leaving this copyright notice intact.
+
+5)
+ The Rijndael implementation by Vincent Rijmen, Antoon Bosselaers
+ and Paulo Barreto is in the public domain and distributed
+ with the following license:
+
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+6)
+ One component of the ssh source code is under a 4-clause BSD license,
+ held by the University of California, since we pulled these parts from
+ original Berkeley code. The Regents of the University of California
+ have declared that term 3 is no longer enforceable on their source code,
+ but we retain that license as is.
+
+ * Copyright (c) 1983, 1990, 1992, 1993, 1995
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+
+7)
Remaining components of the software are provided under a standard
2-term BSD licence with the following names as copyright holders:
@@ -114,6 +188,8 @@ OpenSSH contains no GPL code.
Niels Provos
Dug Song
Aaron Campbell
+ Damien Miller
+ Kevin Steves
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/crypto/openssh/Makefile b/crypto/openssh/Makefile
index eea6f14..f1f871e 100644
--- a/crypto/openssh/Makefile
+++ b/crypto/openssh/Makefile
@@ -1,14 +1,14 @@
-# $OpenBSD: Makefile,v 1.8 2001/02/04 11:11:53 djm Exp $
+# $OpenBSD: Makefile,v 1.10 2002/02/09 17:37:34 deraadt Exp $
.include <bsd.own.mk>
SUBDIR= lib ssh sshd ssh-add ssh-keygen ssh-agent scp sftp-server \
- ssh-keyscan sftp
+ ssh-keyscan sftp scard
distribution:
install -C -o root -g wheel -m 0644 ${.CURDIR}/ssh_config \
- ${DESTDIR}/etc/ssh_config
+ ${DESTDIR}/etc/ssh/ssh_config
install -C -o root -g wheel -m 0644 ${.CURDIR}/sshd_config \
- ${DESTDIR}/etc/sshd_config
+ ${DESTDIR}/etc/ssh/sshd_config
.include <bsd.subdir.mk>
diff --git a/crypto/openssh/Makefile.inc b/crypto/openssh/Makefile.inc
index 89fdf43..c68f59a 100644
--- a/crypto/openssh/Makefile.inc
+++ b/crypto/openssh/Makefile.inc
@@ -1,8 +1,19 @@
-# $OpenBSD: Makefile.inc,v 1.13 2001/01/29 01:58:14 niklas Exp $
+# $OpenBSD: Makefile.inc,v 1.23 2002/03/06 00:23:27 markus Exp $
CFLAGS+= -I${.CURDIR}/..
-CFLAGS+= -Wall
+CDIAGFLAGS= -Wall
+#CDIAGFLAGS+= -Werror
+CDIAGFLAGS+= -Wpointer-arith
+CDIAGFLAGS+= -Wno-uninitialized
+#CDIAGFLAGS+= -Wstrict-prototypes
+CDIAGFLAGS+= -Wmissing-prototypes
+CDIAGFLAGS+= -Wunused
+
+#DEBUG=-g
+
+#CFLAGS+= -DSMARTCARD
+#LDADD+= -lsectok
.include <bsd.obj.mk>
diff --git a/crypto/openssh/OVERVIEW b/crypto/openssh/OVERVIEW
index 7f34ac4..ff03eca 100644
--- a/crypto/openssh/OVERVIEW
+++ b/crypto/openssh/OVERVIEW
@@ -1,9 +1,15 @@
+[Note: This file has not been updated for OpenSSH versions after
+OpenSSH-1.2 and should be considered OBSOLETE. It has been left in
+the distribution because some of its information may still be useful
+to developers.]
+
This document is intended for those who wish to read the ssh source
code. This tries to give an overview of the structure of the code.
Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>
Updated 17 Nov 1995.
Updated 19 Oct 1999 for OpenSSH-1.2
+Updated 20 May 2001 note obsolete for > OpenSSH-1.2
The software consists of ssh (client), sshd (server), scp, sdist, and
the auxiliary programs ssh-keygen, ssh-agent, ssh-add, and
diff --git a/crypto/openssh/README b/crypto/openssh/README
index 4e75d624..c13098b 100644
--- a/crypto/openssh/README
+++ b/crypto/openssh/README
@@ -14,7 +14,7 @@ To extract and install this release on your OpenBSD system use:
# make depend
# make
# make install
- # cp ssh_config sshd_config /etc
+ # cp ssh_config sshd_config /etc/ssh
OpenSSH is a derivative of the original and free ssh 1.2.12 release
by Tatu Ylonen. Aaron Campbell, Bob Beck, Markus Friedl, Niels
diff --git a/crypto/openssh/README.smartcard b/crypto/openssh/README.smartcard
new file mode 100644
index 0000000..499dc8e
--- /dev/null
+++ b/crypto/openssh/README.smartcard
@@ -0,0 +1,69 @@
+How to use smartcards with OpenSSH?
+
+OpenSSH contains experimental support for authentication using
+Cyberflex smartcards and TODOS card readers. To enable this you
+need to:
+
+(1) install sectok
+
+ $ cd /usr/src/lib/libsectok
+ $ make obj depend all install includes
+ $ cd /usr/src/usr.bin/sectok
+ $ make obj depend all install
+
+(2) enable SMARTCARD support in OpenSSH:
+
+ $ vi /usr/src/usr.bin/ssh/Makefile.inc
+ and uncomment
+ CFLAGS+= -DSMARTCARD
+ LDADD+= -lsectok
+
+(3) load the Java Cardlet to the Cyberflex card:
+
+ $ sectok
+ sectok> login -d
+ sectok> jload /usr/libdata/ssh/Ssh.bin
+ sectok> quit
+
+(4) load a RSA key to the card:
+
+ please don't use your production RSA keys, since
+ with the current version of sectok/ssh-keygen
+ the private key file is still readable
+
+ $ ssh-keygen -f /path/to/rsakey -U 1
+ (where 1 is the reader number, you can also try 0)
+
+ In spite of the name, this does not generate a key.
+ It just loads an already existing key on to the card.
+
+(5) optional:
+
+ Change the card password so that only you can
+ read the private key:
+
+ $ sectok
+ sectok> login -d
+ sectok> setpass
+ sectok> quit
+
+ This prevents reading the key but not use of the
+ key by the card applet.
+
+ Do not forget the passphrase. There is no way to
+ recover if you do.
+
+ IMPORTANT WARNING: If you attempt to login with the
+ wrong passphrase three times in a row, you will
+ destroy your card.
+
+(6) tell the ssh client to use the card reader:
+
+ $ ssh -I 1 otherhost
+
+(7) or tell the agent (don't forget to restart) to use the smartcard:
+
+ $ ssh-add -s 1
+
+-markus,
+Tue Jul 17 23:54:51 CEST 2001
diff --git a/crypto/openssh/atomicio.c b/crypto/openssh/atomicio.c
index 8e17b58..fd7d508 100644
--- a/crypto/openssh/atomicio.c
+++ b/crypto/openssh/atomicio.c
@@ -24,9 +24,8 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: atomicio.c,v 1.9 2001/03/02 18:54:30 deraadt Exp $");
+RCSID("$OpenBSD: atomicio.c,v 1.10 2001/05/08 22:48:07 markus Exp $");
-#include "xmalloc.h"
#include "atomicio.h"
/*
diff --git a/crypto/openssh/atomicio.h b/crypto/openssh/atomicio.h
index d878687..e569d38 100644
--- a/crypto/openssh/atomicio.h
+++ b/crypto/openssh/atomicio.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: atomicio.h,v 1.3 2001/03/02 18:54:30 deraadt Exp $ */
+/* $OpenBSD: atomicio.h,v 1.4 2001/06/26 06:32:46 itojun Exp $ */
/*
* Copyright (c) 1995,1999 Theo de Raadt. All rights reserved.
@@ -28,4 +28,4 @@
/*
* Ensure all of data on socket comes through. f==read || f==write
*/
-ssize_t atomicio(ssize_t (*f)(), int fd, void *s, size_t n);
+ssize_t atomicio(ssize_t (*)(), int, void *, size_t);
diff --git a/crypto/openssh/auth-bsdauth.c b/crypto/openssh/auth-bsdauth.c
new file mode 100644
index 0000000..b70d48f
--- /dev/null
+++ b/crypto/openssh/auth-bsdauth.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2001 Markus Friedl. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "includes.h"
+RCSID("$OpenBSD: auth-bsdauth.c,v 1.2 2001/12/19 07:18:56 deraadt Exp $");
+
+#ifdef BSD_AUTH
+#include "xmalloc.h"
+#include "auth.h"
+#include "log.h"
+
+static void *
+bsdauth_init_ctx(Authctxt *authctxt)
+{
+ return authctxt;
+}
+
+static int
+bsdauth_query(void *ctx, char **name, char **infotxt,
+ u_int *numprompts, char ***prompts, u_int **echo_on)
+{
+ Authctxt *authctxt = ctx;
+ char *challenge = NULL;
+
+ if (authctxt->as != NULL) {
+ debug2("bsdauth_query: try reuse session");
+ challenge = auth_getitem(authctxt->as, AUTHV_CHALLENGE);
+ if (challenge == NULL) {
+ auth_close(authctxt->as);
+ authctxt->as = NULL;
+ }
+ }
+
+ if (challenge == NULL) {
+ debug2("bsdauth_query: new bsd auth session");
+ debug3("bsdauth_query: style %s",
+ authctxt->style ? authctxt->style : "<default>");
+ authctxt->as = auth_userchallenge(authctxt->user,
+ authctxt->style, "auth-ssh", &challenge);
+ if (authctxt->as == NULL)
+ challenge = NULL;
+ debug2("bsdauth_query: <%s>", challenge ? challenge : "empty");
+ }
+
+ if (challenge == NULL)
+ return -1;
+
+ *name = xstrdup("");
+ *infotxt = xstrdup("");
+ *numprompts = 1;
+ *prompts = xmalloc(*numprompts * sizeof(char*));
+ *echo_on = xmalloc(*numprompts * sizeof(u_int));
+ (*echo_on)[0] = 0;
+ (*prompts)[0] = xstrdup(challenge);
+
+ return 0;
+}
+
+static int
+bsdauth_respond(void *ctx, u_int numresponses, char **responses)
+{
+ Authctxt *authctxt = ctx;
+ int authok;
+
+ if (authctxt->as == 0)
+ error("bsdauth_respond: no bsd auth session");
+
+ if (numresponses != 1)
+ return -1;
+
+ authok = auth_userresponse(authctxt->as, responses[0], 0);
+ authctxt->as = NULL;
+ debug3("bsdauth_respond: <%s> = <%d>", responses[0], authok);
+
+ return (authok == 0) ? -1 : 0;
+}
+
+static void
+bsdauth_free_ctx(void *ctx)
+{
+ Authctxt *authctxt = ctx;
+
+ if (authctxt && authctxt->as) {
+ auth_close(authctxt->as);
+ authctxt->as = NULL;
+ }
+}
+
+KbdintDevice bsdauth_device = {
+ "bsdauth",
+ bsdauth_init_ctx,
+ bsdauth_query,
+ bsdauth_respond,
+ bsdauth_free_ctx
+};
+#endif
diff --git a/crypto/openssh/auth-options.c b/crypto/openssh/auth-options.c
index 443f541..8df6a6d 100644
--- a/crypto/openssh/auth-options.c
+++ b/crypto/openssh/auth-options.c
@@ -10,7 +10,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: auth-options.c,v 1.16 2001/03/18 12:07:52 markus Exp $");
+RCSID("$OpenBSD: auth-options.c,v 1.21 2002/01/29 14:32:03 markus Exp $");
#include "packet.h"
#include "xmalloc.h"
@@ -20,6 +20,7 @@ RCSID("$OpenBSD: auth-options.c,v 1.16 2001/03/18 12:07:52 markus Exp $");
#include "channels.h"
#include "auth-options.h"
#include "servconf.h"
+#include "misc.h"
/* Flags set authorized_keys flags */
int no_port_forwarding_flag = 0;
@@ -167,10 +168,9 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
}
cp = "from=\"";
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
- int mname, mip;
const char *remote_ip = get_remote_ipaddr();
const char *remote_host = get_canonical_hostname(
- options.reverse_mapping_check);
+ options.verify_reverse_mapping);
char *patterns = xmalloc(strlen(opts) + 1);
opts += strlen(cp);
@@ -195,18 +195,9 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
}
patterns[i] = 0;
opts++;
- /*
- * Deny access if we get a negative
- * match for the hostname or the ip
- * or if we get not match at all
- */
- mname = match_hostname(remote_host, patterns,
- strlen(patterns));
- mip = match_hostname(remote_ip, patterns,
- strlen(patterns));
- xfree(patterns);
- if (mname == -1 || mip == -1 ||
- (mname != 1 && mip != 1)) {
+ if (match_host_and_ip(remote_host, remote_ip,
+ patterns) != 1) {
+ xfree(patterns);
log("Authentication tried for %.100s with "
"correct key but not from a permitted "
"host (host=%.200s, ip=%.200s).",
@@ -217,13 +208,14 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
/* deny access */
return 0;
}
+ xfree(patterns);
/* Host name matches. */
goto next_option;
}
cp = "permitopen=\"";
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
+ char host[256], sport[6];
u_short port;
- char *c, *ep;
char *patterns = xmalloc(strlen(opts) + 1);
opts += strlen(cp);
@@ -248,28 +240,25 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
}
patterns[i] = 0;
opts++;
- c = strchr(patterns, ':');
- if (c == NULL) {
- debug("%.100s, line %lu: permitopen: missing colon <%.100s>",
- file, linenum, patterns);
- packet_send_debug("%.100s, line %lu: missing colon",
- file, linenum);
+ if (sscanf(patterns, "%255[^:]:%5[0-9]", host, sport) != 2 &&
+ sscanf(patterns, "%255[^/]/%5[0-9]", host, sport) != 2) {
+ debug("%.100s, line %lu: Bad permitopen specification "
+ "<%.100s>", file, linenum, patterns);
+ packet_send_debug("%.100s, line %lu: "
+ "Bad permitopen specification", file, linenum);
xfree(patterns);
goto bad_option;
}
- *c = 0;
- c++;
- port = strtol(c, &ep, 0);
- if (c == ep) {
- debug("%.100s, line %lu: permitopen: missing port <%.100s>",
- file, linenum, patterns);
- packet_send_debug("%.100s, line %lu: missing port",
- file, linenum);
+ if ((port = a2port(sport)) == 0) {
+ debug("%.100s, line %lu: Bad permitopen port <%.100s>",
+ file, linenum, sport);
+ packet_send_debug("%.100s, line %lu: "
+ "Bad permitopen port", file, linenum);
xfree(patterns);
goto bad_option;
}
if (options.allow_tcp_forwarding)
- channel_add_permitted_opens(patterns, port);
+ channel_add_permitted_opens(host, port);
xfree(patterns);
goto next_option;
}
diff --git a/crypto/openssh/auth-options.h b/crypto/openssh/auth-options.h
index 8ee2694..aa6270fd 100644
--- a/crypto/openssh/auth-options.h
+++ b/crypto/openssh/auth-options.h
@@ -1,3 +1,5 @@
+/* $OpenBSD: auth-options.h,v 1.11 2002/03/04 17:27:39 stevesk Exp $ */
+
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -11,8 +13,6 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-/* $OpenBSD: auth-options.h,v 1.8 2001/01/21 19:05:42 markus Exp $ */
-
#ifndef AUTH_OPTIONS_H
#define AUTH_OPTIONS_H
@@ -30,15 +30,7 @@ extern int no_pty_flag;
extern char *forced_command;
extern struct envstring *custom_environment;
-/*
- * return 1 if access is granted, 0 if not.
- * side effect: sets key option flags
- */
-int
-auth_parse_options(struct passwd *pw, char *options, char *file,
- u_long linenum);
-
-/* reset options flags */
+int auth_parse_options(struct passwd *, char *, char *, u_long);
void auth_clear_options(void);
#endif
diff --git a/crypto/openssh/auth-rhosts.c b/crypto/openssh/auth-rhosts.c
index 324a0f9..bd15261 100644
--- a/crypto/openssh/auth-rhosts.c
+++ b/crypto/openssh/auth-rhosts.c
@@ -14,10 +14,9 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: auth-rhosts.c,v 1.23 2001/04/12 19:15:24 markus Exp $");
+RCSID("$OpenBSD: auth-rhosts.c,v 1.27 2002/03/04 12:43:06 markus Exp $");
#include "packet.h"
-#include "xmalloc.h"
#include "uidswap.h"
#include "pathnames.h"
#include "log.h"
@@ -34,7 +33,7 @@ extern ServerOptions options;
* based on the file, and returns zero otherwise.
*/
-int
+static int
check_rhosts_file(const char *filename, const char *hostname,
const char *ipaddr, const char *client_user,
const char *server_user)
@@ -156,7 +155,7 @@ auth_rhosts(struct passwd *pw, const char *client_user)
const char *hostname, *ipaddr;
int ret;
- hostname = get_canonical_hostname(options.reverse_mapping_check);
+ hostname = get_canonical_hostname(options.verify_reverse_mapping);
ipaddr = get_remote_ipaddr();
ret = auth_rhosts2(pw, client_user, hostname, ipaddr);
return ret;
@@ -186,7 +185,7 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
* servers.
*/
for (rhosts_file_index = 0; rhosts_files[rhosts_file_index];
- rhosts_file_index++) {
+ rhosts_file_index++) {
/* Check users .rhosts or .shosts. */
snprintf(buf, sizeof buf, "%.500s/%.100s",
pw->pw_dir, rhosts_files[rhosts_file_index]);
@@ -204,16 +203,16 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
/* If not logging in as superuser, try /etc/hosts.equiv and shosts.equiv. */
if (pw->pw_uid != 0) {
- if (check_rhosts_file(_PATH_RHOSTS_EQUIV, hostname, ipaddr, client_user,
- pw->pw_name)) {
+ if (check_rhosts_file(_PATH_RHOSTS_EQUIV, hostname, ipaddr,
+ client_user, pw->pw_name)) {
packet_send_debug("Accepted for %.100s [%.100s] by /etc/hosts.equiv.",
- hostname, ipaddr);
+ hostname, ipaddr);
return 1;
}
- if (check_rhosts_file(_PATH_SSH_HOSTS_EQUIV, hostname, ipaddr, client_user,
- pw->pw_name)) {
+ if (check_rhosts_file(_PATH_SSH_HOSTS_EQUIV, hostname, ipaddr,
+ client_user, pw->pw_name)) {
packet_send_debug("Accepted for %.100s [%.100s] by %.100s.",
- hostname, ipaddr, _PATH_SSH_HOSTS_EQUIV);
+ hostname, ipaddr, _PATH_SSH_HOSTS_EQUIV);
return 1;
}
}
@@ -230,7 +229,7 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
}
if (options.strict_modes &&
((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
- (st.st_mode & 022) != 0)) {
+ (st.st_mode & 022) != 0)) {
log("Rhosts authentication refused for %.100s: bad ownership or modes for home directory.",
pw->pw_name);
packet_send_debug("Rhosts authentication refused for %.100s: bad ownership or modes for home directory.",
@@ -242,7 +241,7 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
/* Check all .rhosts files (currently .shosts and .rhosts). */
for (rhosts_file_index = 0; rhosts_files[rhosts_file_index];
- rhosts_file_index++) {
+ rhosts_file_index++) {
/* Check users .rhosts or .shosts. */
snprintf(buf, sizeof buf, "%.500s/%.100s",
pw->pw_dir, rhosts_files[rhosts_file_index]);
@@ -257,7 +256,7 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
*/
if (options.strict_modes &&
((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
- (st.st_mode & 022) != 0)) {
+ (st.st_mode & 022) != 0)) {
log("Rhosts authentication refused for %.100s: bad modes for %.200s",
pw->pw_name, buf);
packet_send_debug("Bad file modes for %.200s", buf);
diff --git a/crypto/openssh/auth2-chall.c b/crypto/openssh/auth2-chall.c
index 5af60e4..9f1d932 100644
--- a/crypto/openssh/auth2-chall.c
+++ b/crypto/openssh/auth2-chall.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
+ * Copyright (c) 2001 Per Allansson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -22,91 +23,290 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
-RCSID("$OpenBSD: auth2-chall.c,v 1.4 2001/03/28 22:43:31 markus Exp $");
+RCSID("$OpenBSD: auth2-chall.c,v 1.16 2002/01/13 17:57:37 markus Exp $");
#include "ssh2.h"
#include "auth.h"
+#include "buffer.h"
#include "packet.h"
#include "xmalloc.h"
#include "dispatch.h"
+#include "auth.h"
#include "log.h"
-void send_userauth_into_request(Authctxt *authctxt, char *challenge, int echo);
-void input_userauth_info_response(int type, int plen, void *ctxt);
+static int auth2_challenge_start(Authctxt *);
+static int send_userauth_info_request(Authctxt *);
+static void input_userauth_info_response(int, u_int32_t, void *);
+
+#ifdef BSD_AUTH
+extern KbdintDevice bsdauth_device;
+#else
+#ifdef SKEY
+extern KbdintDevice skey_device;
+#endif
+#endif
+
+KbdintDevice *devices[] = {
+#ifdef BSD_AUTH
+ &bsdauth_device,
+#else
+#ifdef SKEY
+ &skey_device,
+#endif
+#endif
+ NULL
+};
+
+typedef struct KbdintAuthctxt KbdintAuthctxt;
+struct KbdintAuthctxt
+{
+ char *devices;
+ void *ctxt;
+ KbdintDevice *device;
+};
+
+static KbdintAuthctxt *
+kbdint_alloc(const char *devs)
+{
+ KbdintAuthctxt *kbdintctxt;
+ Buffer b;
+ int i;
+
+ kbdintctxt = xmalloc(sizeof(KbdintAuthctxt));
+ if (strcmp(devs, "") == 0) {
+ buffer_init(&b);
+ for (i = 0; devices[i]; i++) {
+ if (buffer_len(&b) > 0)
+ buffer_append(&b, ",", 1);
+ buffer_append(&b, devices[i]->name,
+ strlen(devices[i]->name));
+ }
+ buffer_append(&b, "\0", 1);
+ kbdintctxt->devices = xstrdup(buffer_ptr(&b));
+ buffer_free(&b);
+ } else {
+ kbdintctxt->devices = xstrdup(devs);
+ }
+ debug("kbdint_alloc: devices '%s'", kbdintctxt->devices);
+ kbdintctxt->ctxt = NULL;
+ kbdintctxt->device = NULL;
+
+ return kbdintctxt;
+}
+static void
+kbdint_reset_device(KbdintAuthctxt *kbdintctxt)
+{
+ if (kbdintctxt->ctxt) {
+ kbdintctxt->device->free_ctx(kbdintctxt->ctxt);
+ kbdintctxt->ctxt = NULL;
+ }
+ kbdintctxt->device = NULL;
+}
+static void
+kbdint_free(KbdintAuthctxt *kbdintctxt)
+{
+ if (kbdintctxt->device)
+ kbdint_reset_device(kbdintctxt);
+ if (kbdintctxt->devices) {
+ xfree(kbdintctxt->devices);
+ kbdintctxt->devices = NULL;
+ }
+ xfree(kbdintctxt);
+}
+/* get next device */
+static int
+kbdint_next_device(KbdintAuthctxt *kbdintctxt)
+{
+ size_t len;
+ char *t;
+ int i;
+
+ if (kbdintctxt->device)
+ kbdint_reset_device(kbdintctxt);
+ do {
+ len = kbdintctxt->devices ?
+ strcspn(kbdintctxt->devices, ",") : 0;
+
+ if (len == 0)
+ break;
+ for (i = 0; devices[i]; i++)
+ if (strncmp(kbdintctxt->devices, devices[i]->name, len) == 0)
+ kbdintctxt->device = devices[i];
+ t = kbdintctxt->devices;
+ kbdintctxt->devices = t[len] ? xstrdup(t+len+1) : NULL;
+ xfree(t);
+ debug2("kbdint_next_device: devices %s", kbdintctxt->devices ?
+ kbdintctxt->devices : "<empty>");
+ } while (kbdintctxt->devices && !kbdintctxt->device);
+
+ return kbdintctxt->device ? 1 : 0;
+}
/*
- * try challenge-reponse, return -1 (= postponed) if we have to
+ * try challenge-response, set authctxt->postponed if we have to
* wait for the response.
*/
int
auth2_challenge(Authctxt *authctxt, char *devs)
{
- char *challenge;
+ debug("auth2_challenge: user=%s devs=%s",
+ authctxt->user ? authctxt->user : "<nouser>",
+ devs ? devs : "<no devs>");
+
+ if (authctxt->user == NULL || !devs)
+ return 0;
+ if (authctxt->kbdintctxt == NULL)
+ authctxt->kbdintctxt = kbdint_alloc(devs);
+ return auth2_challenge_start(authctxt);
+}
+
+/* unregister kbd-int callbacks and context */
+void
+auth2_challenge_stop(Authctxt *authctxt)
+{
+ /* unregister callback */
+ dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
+ if (authctxt->kbdintctxt != NULL) {
+ kbdint_free(authctxt->kbdintctxt);
+ authctxt->kbdintctxt = NULL;
+ }
+}
+
+/* side effect: sets authctxt->postponed if a reply was sent*/
+static int
+auth2_challenge_start(Authctxt *authctxt)
+{
+ KbdintAuthctxt *kbdintctxt = authctxt->kbdintctxt;
+
+ debug2("auth2_challenge_start: devices %s",
+ kbdintctxt->devices ? kbdintctxt->devices : "<empty>");
- if (!authctxt->valid || authctxt->user == NULL)
+ if (kbdint_next_device(kbdintctxt) == 0) {
+ auth2_challenge_stop(authctxt);
return 0;
- if ((challenge = get_challenge(authctxt, devs)) == NULL)
+ }
+ debug("auth2_challenge_start: trying authentication method '%s'",
+ kbdintctxt->device->name);
+
+ if ((kbdintctxt->ctxt = kbdintctxt->device->init_ctx(authctxt)) == NULL) {
+ auth2_challenge_stop(authctxt);
return 0;
- send_userauth_into_request(authctxt, challenge, 0);
+ }
+ if (send_userauth_info_request(authctxt) == 0) {
+ auth2_challenge_stop(authctxt);
+ return 0;
+ }
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE,
&input_userauth_info_response);
+
authctxt->postponed = 1;
return 0;
}
-void
-send_userauth_into_request(Authctxt *authctxt, char *challenge, int echo)
+static int
+send_userauth_info_request(Authctxt *authctxt)
{
- int nprompts = 1;
+ KbdintAuthctxt *kbdintctxt;
+ char *name, *instr, **prompts;
+ int i;
+ u_int numprompts, *echo_on;
+
+ kbdintctxt = authctxt->kbdintctxt;
+ if (kbdintctxt->device->query(kbdintctxt->ctxt,
+ &name, &instr, &numprompts, &prompts, &echo_on))
+ return 0;
packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST);
- /* name, instruction and language are unused */
- packet_put_cstring("");
- packet_put_cstring("");
- packet_put_cstring("");
- packet_put_int(nprompts);
- packet_put_cstring(challenge);
- packet_put_char(echo);
+ packet_put_cstring(name);
+ packet_put_cstring(instr);
+ packet_put_cstring(""); /* language not used */
+ packet_put_int(numprompts);
+ for (i = 0; i < numprompts; i++) {
+ packet_put_cstring(prompts[i]);
+ packet_put_char(echo_on[i]);
+ }
packet_send();
packet_write_wait();
+
+ for (i = 0; i < numprompts; i++)
+ xfree(prompts[i]);
+ xfree(prompts);
+ xfree(echo_on);
+ xfree(name);
+ xfree(instr);
+ return 1;
}
-void
-input_userauth_info_response(int type, int plen, void *ctxt)
+static void
+input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
{
Authctxt *authctxt = ctxt;
- int authenticated = 0;
- u_int nresp, rlen;
- char *response, *method = "challenge-reponse";
+ KbdintAuthctxt *kbdintctxt;
+ int i, authenticated = 0, res, len;
+ u_int nresp;
+ char **response = NULL, *method;
if (authctxt == NULL)
fatal("input_userauth_info_response: no authctxt");
+ kbdintctxt = authctxt->kbdintctxt;
+ if (kbdintctxt == NULL || kbdintctxt->ctxt == NULL)
+ fatal("input_userauth_info_response: no kbdintctxt");
+ if (kbdintctxt->device == NULL)
+ fatal("input_userauth_info_response: no device");
authctxt->postponed = 0; /* reset */
nresp = packet_get_int();
- if (nresp == 1) {
- response = packet_get_string(&rlen);
- packet_done();
- if (strlen(response) == 0) {
- /*
- * if we received an empty response, resend challenge
- * with echo enabled
- */
- char *challenge = get_challenge(authctxt, NULL);
- if (challenge != NULL) {
- send_userauth_into_request(authctxt,
- challenge, 1);
- authctxt->postponed = 1;
- }
- } else if (authctxt->valid) {
- authenticated = verify_response(authctxt, response);
- memset(response, 'r', rlen);
- }
+ if (nresp > 0) {
+ response = xmalloc(nresp * sizeof(char*));
+ for (i = 0; i < nresp; i++)
+ response[i] = packet_get_string(NULL);
+ }
+ packet_check_eom();
+
+ if (authctxt->valid) {
+ res = kbdintctxt->device->respond(kbdintctxt->ctxt,
+ nresp, response);
+ } else {
+ res = -1;
+ }
+
+ for (i = 0; i < nresp; i++) {
+ memset(response[i], 'r', strlen(response[i]));
+ xfree(response[i]);
+ }
+ if (response)
xfree(response);
+
+ switch (res) {
+ case 0:
+ /* Success! */
+ authenticated = 1;
+ break;
+ case 1:
+ /* Authentication needs further interaction */
+ if (send_userauth_info_request(authctxt) == 1)
+ authctxt->postponed = 1;
+ break;
+ default:
+ /* Failure! */
+ break;
}
- /* unregister callback */
- if (!authctxt->postponed)
- dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
+ len = strlen("keyboard-interactive") + 2 +
+ strlen(kbdintctxt->device->name);
+ method = xmalloc(len);
+ snprintf(method, len, "keyboard-interactive/%s",
+ kbdintctxt->device->name);
+
+ if (!authctxt->postponed) {
+ if (authenticated) {
+ auth2_challenge_stop(authctxt);
+ } else {
+ /* start next device */
+ /* may set authctxt->postponed */
+ auth2_challenge_start(authctxt);
+ }
+ }
userauth_finish(authctxt, authenticated, method);
+ xfree(method);
}
diff --git a/crypto/openssh/authfd.h b/crypto/openssh/authfd.h
index 29d1847..0f2ca7a 100644
--- a/crypto/openssh/authfd.h
+++ b/crypto/openssh/authfd.h
@@ -1,3 +1,5 @@
+/* $OpenBSD: authfd.h,v 1.23 2002/03/04 17:27:39 stevesk Exp $ */
+
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -11,8 +13,6 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-/* RCSID("$OpenBSD: authfd.h,v 1.16 2000/12/20 19:37:21 markus Exp $"); */
-
#ifndef AUTHFD_H
#define AUTHFD_H
@@ -38,101 +38,43 @@
#define SSH2_AGENTC_REMOVE_IDENTITY 18
#define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19
+/* smartcard */
+#define SSH_AGENTC_ADD_SMARTCARD_KEY 20
+#define SSH_AGENTC_REMOVE_SMARTCARD_KEY 21
+
+/* extended failure messages */
+#define SSH2_AGENT_FAILURE 30
+
/* additional error code for ssh.com's ssh-agent2 */
-#define SSH_COM_AGENT2_FAILURE 102
+#define SSH_COM_AGENT2_FAILURE 102
#define SSH_AGENT_OLD_SIGNATURE 0x01
-
typedef struct {
int fd;
Buffer identities;
int howmany;
} AuthenticationConnection;
-/* Returns the number of the authentication fd, or -1 if there is none. */
-int ssh_get_authentication_socket(void);
+int ssh_get_authentication_socket(void);
+void ssh_close_authentication_socket(int);
-/*
- * This should be called for any descriptor returned by
- * ssh_get_authentication_socket(). Depending on the way the descriptor was
- * obtained, this may close the descriptor.
- */
-void ssh_close_authentication_socket(int authfd);
-
-/*
- * Opens and connects a private socket for communication with the
- * authentication agent. Returns NULL if an error occurred and the
- * connection could not be opened. The connection should be closed by the
- * caller by calling ssh_close_authentication_connection().
- */
AuthenticationConnection *ssh_get_authentication_connection(void);
+void ssh_close_authentication_connection(AuthenticationConnection *);
+int ssh_get_num_identities(AuthenticationConnection *, int);
+Key *ssh_get_first_identity(AuthenticationConnection *, char **, int);
+Key *ssh_get_next_identity(AuthenticationConnection *, char **, int);
+int ssh_add_identity(AuthenticationConnection *, Key *, const char *);
+int ssh_remove_identity(AuthenticationConnection *, Key *);
+int ssh_remove_all_identities(AuthenticationConnection *, int);
+int ssh_update_card(AuthenticationConnection *, int, const char *);
-/*
- * Closes the connection to the authentication agent and frees any associated
- * memory.
- */
-void ssh_close_authentication_connection(AuthenticationConnection *auth);
-
-/*
- * Returns the number authentication identity held by the agent.
- */
-int ssh_get_num_identities(AuthenticationConnection *auth, int version);
-
-/*
- * Returns the first authentication identity held by the agent or NULL if
- * no identies are available. Caller must free comment and key.
- * Note that you cannot mix calls with different versions.
- */
-Key *ssh_get_first_identity(AuthenticationConnection *auth, char **comment, int version);
-
-/*
- * Returns the next authentication identity for the agent. Other functions
- * can be called between this and ssh_get_first_identity or two calls of this
- * function. This returns NULL if there are no more identities. The caller
- * must free key and comment after a successful return.
- */
-Key *ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int version);
-
-/*
- * Requests the agent to decrypt the given challenge. Returns true if the
- * agent claims it was able to decrypt it.
- */
int
-ssh_decrypt_challenge(AuthenticationConnection *auth,
- Key *key, BIGNUM * challenge,
- u_char session_id[16],
- u_int response_type,
- u_char response[16]);
+ssh_decrypt_challenge(AuthenticationConnection *, Key *, BIGNUM *, u_char[16],
+ u_int, u_char[16]);
-/* Requests the agent to sign data using key */
int
-ssh_agent_sign(AuthenticationConnection *auth,
- Key *key,
- u_char **sigp, int *lenp,
- u_char *data, int datalen);
-
-/*
- * Adds an identity to the authentication server. This call is not meant to
- * be used by normal applications. This returns true if the identity was
- * successfully added.
- */
-int
-ssh_add_identity(AuthenticationConnection *auth, Key *key,
- const char *comment);
-
-/*
- * Removes the identity from the authentication server. This call is not
- * meant to be used by normal applications. This returns true if the
- * identity was successfully added.
- */
-int ssh_remove_identity(AuthenticationConnection *auth, Key *key);
-
-/*
- * Removes all identities from the authentication agent. This call is not
- * meant to be used by normal applications. This returns true if the
- * operation was successful.
- */
-int ssh_remove_all_identities(AuthenticationConnection *auth, int version);
+ssh_agent_sign(AuthenticationConnection *, Key *, u_char **, u_int *, u_char *,
+ u_int);
#endif /* AUTHFD_H */
diff --git a/crypto/openssh/authfile.h b/crypto/openssh/authfile.h
index da90cd9..c614ca1 100644
--- a/crypto/openssh/authfile.h
+++ b/crypto/openssh/authfile.h
@@ -1,3 +1,5 @@
+/* $OpenBSD: authfile.h,v 1.9 2002/03/04 17:27:39 stevesk Exp $ */
+
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -10,27 +12,13 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-/* $OpenBSD: authfile.h,v 1.6 2001/03/26 08:07:08 markus Exp $ */
-
#ifndef AUTHFILE_H
#define AUTHFILE_H
-int
-key_save_private(Key *key, const char *filename, const char *passphrase,
- const char *comment);
-
-Key *
-key_load_public(const char *filename, char **commentp);
-
-Key *
-key_load_public_type(int type, const char *filename, char **commentp);
-
-Key *
-key_load_private(const char *filename, const char *passphrase,
- char **commentp);
-
-Key *
-key_load_private_type(int type, const char *filename, const char *passphrase,
- char **commentp);
+int key_save_private(Key *, const char *, const char *, const char *);
+Key *key_load_public(const char *, char **);
+Key *key_load_public_type(int, const char *, char **);
+Key *key_load_private(const char *, const char *, char **);
+Key *key_load_private_type(int, const char *, const char *, char **);
#endif
diff --git a/crypto/openssh/bufaux.h b/crypto/openssh/bufaux.h
index 8902ec2..fda41ca 100644
--- a/crypto/openssh/bufaux.h
+++ b/crypto/openssh/bufaux.h
@@ -1,3 +1,5 @@
+/* $OpenBSD: bufaux.h,v 1.16 2002/03/04 17:27:39 stevesk Exp $ */
+
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -10,51 +12,28 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-/* RCSID("$OpenBSD: bufaux.h,v 1.11 2001/01/21 19:05:45 markus Exp $"); */
-
#ifndef BUFAUX_H
#define BUFAUX_H
#include "buffer.h"
#include <openssl/bn.h>
-/*
- * Stores an BIGNUM in the buffer with a 2-byte msb first bit count, followed
- * by (bits+7)/8 bytes of binary data, msb first.
- */
-void buffer_put_bignum(Buffer * buffer, BIGNUM * value);
-void buffer_put_bignum2(Buffer * buffer, BIGNUM * value);
-
-/* Retrieves an BIGNUM from the buffer. */
-int buffer_get_bignum(Buffer * buffer, BIGNUM * value);
-int buffer_get_bignum2(Buffer *buffer, BIGNUM * value);
+void buffer_put_bignum(Buffer *, BIGNUM *);
+void buffer_put_bignum2(Buffer *, BIGNUM *);
+void buffer_get_bignum(Buffer *, BIGNUM *);
+void buffer_get_bignum2(Buffer *, BIGNUM *);
-/* Returns an integer from the buffer (4 bytes, msb first). */
-u_int buffer_get_int(Buffer * buffer);
-u_int64_t buffer_get_int64(Buffer *buffer);
+u_int buffer_get_int(Buffer *);
+void buffer_put_int(Buffer *, u_int);
-/* Stores an integer in the buffer in 4 bytes, msb first. */
-void buffer_put_int(Buffer * buffer, u_int value);
-void buffer_put_int64(Buffer *buffer, u_int64_t value);
+u_int64_t buffer_get_int64(Buffer *);
+void buffer_put_int64(Buffer *, u_int64_t);
-/* Returns a character from the buffer (0 - 255). */
-int buffer_get_char(Buffer * buffer);
-
-/* Stores a character in the buffer. */
-void buffer_put_char(Buffer * buffer, int value);
-
-/*
- * Returns an arbitrary binary string from the buffer. The string cannot be
- * longer than 256k. The returned value points to memory allocated with
- * xmalloc; it is the responsibility of the calling function to free the
- * data. If length_ptr is non-NULL, the length of the returned data will be
- * stored there. A null character will be automatically appended to the
- * returned string, and is not counted in length.
- */
-char *buffer_get_string(Buffer * buffer, u_int *length_ptr);
+int buffer_get_char(Buffer *);
+void buffer_put_char(Buffer *, int);
-/* Stores and arbitrary binary string in the buffer. */
-void buffer_put_string(Buffer * buffer, const void *buf, u_int len);
-void buffer_put_cstring(Buffer *buffer, const char *s);
+void *buffer_get_string(Buffer *, u_int *);
+void buffer_put_string(Buffer *, const void *, u_int);
+void buffer_put_cstring(Buffer *, const char *);
#endif /* BUFAUX_H */
diff --git a/crypto/openssh/buffer.c b/crypto/openssh/buffer.c
index 044caaf..40572e5 100644
--- a/crypto/openssh/buffer.c
+++ b/crypto/openssh/buffer.c
@@ -12,7 +12,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: buffer.c,v 1.13 2001/04/12 19:15:24 markus Exp $");
+RCSID("$OpenBSD: buffer.c,v 1.15 2002/01/18 18:14:17 stevesk Exp $");
#include "xmalloc.h"
#include "buffer.h"
@@ -53,11 +53,11 @@ buffer_clear(Buffer *buffer)
/* Appends data to the buffer, expanding it if necessary. */
void
-buffer_append(Buffer *buffer, const char *data, u_int len)
+buffer_append(Buffer *buffer, const void *data, u_int len)
{
- char *cp;
- buffer_append_space(buffer, &cp, len);
- memcpy(cp, data, len);
+ void *p;
+ p = buffer_append_space(buffer, len);
+ memcpy(p, data, len);
}
/*
@@ -66,9 +66,11 @@ buffer_append(Buffer *buffer, const char *data, u_int len)
* to the allocated region.
*/
-void
-buffer_append_space(Buffer *buffer, char **datap, u_int len)
+void *
+buffer_append_space(Buffer *buffer, u_int len)
{
+ void *p;
+
/* If the buffer is empty, start using it from the beginning. */
if (buffer->offset == buffer->end) {
buffer->offset = 0;
@@ -77,9 +79,9 @@ buffer_append_space(Buffer *buffer, char **datap, u_int len)
restart:
/* If there is enough space to store all data, store it now. */
if (buffer->end + len < buffer->alloc) {
- *datap = buffer->buf + buffer->end;
+ p = buffer->buf + buffer->end;
buffer->end += len;
- return;
+ return p;
}
/*
* If the buffer is quite empty, but all data is at the end, move the
@@ -96,6 +98,7 @@ restart:
buffer->alloc += len + 32768;
buffer->buf = xrealloc(buffer->buf, buffer->alloc);
goto restart;
+ /* NOTREACHED */
}
/* Returns the number of bytes of data in the buffer. */
@@ -109,7 +112,7 @@ buffer_len(Buffer *buffer)
/* Gets data from the beginning of the buffer. */
void
-buffer_get(Buffer *buffer, char *buf, u_int len)
+buffer_get(Buffer *buffer, void *buf, u_int len)
{
if (len > buffer->end - buffer->offset)
fatal("buffer_get: trying to get more bytes %d than in buffer %d",
@@ -140,7 +143,7 @@ buffer_consume_end(Buffer *buffer, u_int bytes)
/* Returns a pointer to the first used byte in the buffer. */
-char *
+void *
buffer_ptr(Buffer *buffer)
{
return buffer->buf + buffer->offset;
@@ -152,7 +155,7 @@ void
buffer_dump(Buffer *buffer)
{
int i;
- u_char *ucp = (u_char *) buffer->buf;
+ u_char *ucp = buffer->buf;
for (i = buffer->offset; i < buffer->end; i++) {
fprintf(stderr, "%02x", ucp[i]);
diff --git a/crypto/openssh/buffer.h b/crypto/openssh/buffer.h
index f3c509d..5e4c412 100644
--- a/crypto/openssh/buffer.h
+++ b/crypto/openssh/buffer.h
@@ -1,3 +1,5 @@
+/* $OpenBSD: buffer.h,v 1.11 2002/03/04 17:27:39 stevesk Exp $ */
+
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -11,56 +13,31 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-/* RCSID("$OpenBSD: buffer.h,v 1.7 2000/12/19 23:17:55 markus Exp $"); */
-
#ifndef BUFFER_H
#define BUFFER_H
typedef struct {
- char *buf; /* Buffer for data. */
- u_int alloc; /* Number of bytes allocated for data. */
- u_int offset; /* Offset of first byte containing data. */
- u_int end; /* Offset of last byte containing data. */
+ u_char *buf; /* Buffer for data. */
+ u_int alloc; /* Number of bytes allocated for data. */
+ u_int offset; /* Offset of first byte containing data. */
+ u_int end; /* Offset of last byte containing data. */
} Buffer;
-/* Initializes the buffer structure. */
-void buffer_init(Buffer * buffer);
-
-/* Frees any memory used for the buffer. */
-void buffer_free(Buffer * buffer);
-
-/* Clears any data from the buffer, making it empty. This does not actually
- zero the memory. */
-void buffer_clear(Buffer * buffer);
-
-/* Appends data to the buffer, expanding it if necessary. */
-void buffer_append(Buffer * buffer, const char *data, u_int len);
-/*
- * Appends space to the buffer, expanding the buffer if necessary. This does
- * not actually copy the data into the buffer, but instead returns a pointer
- * to the allocated region.
- */
-void buffer_append_space(Buffer * buffer, char **datap, u_int len);
-
-/* Returns the number of bytes of data in the buffer. */
-u_int buffer_len(Buffer * buffer);
+void buffer_init(Buffer *);
+void buffer_clear(Buffer *);
+void buffer_free(Buffer *);
-/* Gets data from the beginning of the buffer. */
-void buffer_get(Buffer * buffer, char *buf, u_int len);
+u_int buffer_len(Buffer *);
+void *buffer_ptr(Buffer *);
-/* Consumes the given number of bytes from the beginning of the buffer. */
-void buffer_consume(Buffer * buffer, u_int bytes);
+void buffer_append(Buffer *, const void *, u_int);
+void *buffer_append_space(Buffer *, u_int);
-/* Consumes the given number of bytes from the end of the buffer. */
-void buffer_consume_end(Buffer * buffer, u_int bytes);
+void buffer_get(Buffer *, void *, u_int);
-/* Returns a pointer to the first used byte in the buffer. */
-char *buffer_ptr(Buffer * buffer);
+void buffer_consume(Buffer *, u_int);
+void buffer_consume_end(Buffer *, u_int);
-/*
- * Dumps the contents of the buffer to stderr in hex. This intended for
- * debugging purposes only.
- */
-void buffer_dump(Buffer * buffer);
+void buffer_dump(Buffer *);
#endif /* BUFFER_H */
diff --git a/crypto/openssh/canohost.h b/crypto/openssh/canohost.h
index 36fb345..4347b48 100644
--- a/crypto/openssh/canohost.h
+++ b/crypto/openssh/canohost.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: canohost.h,v 1.6 2001/04/12 19:15:24 markus Exp $ */
+/* $OpenBSD: canohost.h,v 1.8 2001/06/26 17:27:23 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -12,27 +12,14 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-/*
- * Return the canonical name of the host in the other side of the current
- * connection (as returned by packet_get_connection). The host name is
- * cached, so it is efficient to call this several times.
- */
-const char *get_canonical_hostname(int reverse_mapping_check);
-
-/*
- * Returns the IP-address of the remote host as a string. The returned
- * string is cached and must not be freed.
- */
-const char *get_remote_ipaddr(void);
-
-const char *get_remote_name_or_ip(u_int utmp_len, int reverse_mapping_check);
+const char *get_canonical_hostname(int);
+const char *get_remote_ipaddr(void);
+const char *get_remote_name_or_ip(u_int, int);
-/* Returns the ipaddr/port number of the peer of the socket. */
-char * get_peer_ipaddr(int socket);
-int get_peer_port(int sock);
-char * get_local_ipaddr(int socket);
-char * get_local_name(int socket);
+char *get_peer_ipaddr(int);
+int get_peer_port(int);
+char *get_local_ipaddr(int);
+char *get_local_name(int);
-/* Returns the port number of the remote/local host. */
-int get_remote_port(void);
-int get_local_port(void);
+int get_remote_port(void);
+int get_local_port(void);
diff --git a/crypto/openssh/clientloop.c b/crypto/openssh/clientloop.c
index 369ffe4..65a6682 100644
--- a/crypto/openssh/clientloop.c
+++ b/crypto/openssh/clientloop.c
@@ -35,7 +35,7 @@
*
*
* SSH2 support added by Markus Friedl.
- * Copyright (c) 1999,2000 Markus Friedl. All rights reserved.
+ * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -59,7 +59,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: clientloop.c,v 1.65 2001/04/20 07:17:51 djm Exp $");
+RCSID("$OpenBSD: clientloop.c,v 1.96 2002/02/06 14:55:15 markus Exp $");
#include "ssh.h"
#include "ssh1.h"
@@ -101,7 +101,8 @@ extern char *host;
* window size to be sent to the server a little later. This is volatile
* because this is updated in a signal handler.
*/
-static volatile int received_window_change_signal = 0;
+static volatile sig_atomic_t received_window_change_signal = 0;
+static volatile sig_atomic_t received_signal = 0;
/* Flag indicating whether the user\'s terminal is in non-blocking mode. */
static int in_non_blocking_mode = 0;
@@ -123,7 +124,7 @@ static int connection_out; /* Connection to server (output). */
static int need_rekeying; /* Set to non-zero if rekeying is requested. */
static int session_closed = 0; /* In SSH2: login session closed. */
-void client_init_dispatch(void);
+static void client_init_dispatch(void);
int session_ident = -1;
/*XXX*/
@@ -131,7 +132,7 @@ extern Kex *xxx_kex;
/* Restores stdin to blocking mode. */
-void
+static void
leave_non_blocking(void)
{
if (in_non_blocking_mode) {
@@ -143,7 +144,7 @@ leave_non_blocking(void)
/* Puts stdin terminal in non-blocking mode. */
-void
+static void
enter_non_blocking(void)
{
in_non_blocking_mode = 1;
@@ -156,7 +157,7 @@ enter_non_blocking(void)
* flag indicating that the window has changed.
*/
-void
+static void
window_change_handler(int sig)
{
received_window_change_signal = 1;
@@ -168,16 +169,11 @@ window_change_handler(int sig)
* signals must be trapped to restore terminal modes.
*/
-void
+static void
signal_handler(int sig)
{
- if (in_raw_mode())
- leave_raw_mode();
- if (in_non_blocking_mode)
- leave_non_blocking();
- channel_stop_listening();
- packet_close();
- fatal("Killed by signal %d.", sig);
+ received_signal = sig;
+ quit_pending = 1;
}
/*
@@ -185,7 +181,7 @@ signal_handler(int sig)
* available resolution.
*/
-double
+static double
get_current_time(void)
{
struct timeval tv;
@@ -199,7 +195,7 @@ get_current_time(void)
* not appear to wake up when redirecting from /dev/null.
*/
-void
+static void
client_check_initial_eof_on_stdin(void)
{
int len;
@@ -251,14 +247,14 @@ client_check_initial_eof_on_stdin(void)
* connection.
*/
-void
+static void
client_make_packets_from_stdin_data(void)
{
u_int len;
/* Send buffered stdin data to the server. */
while (buffer_len(&stdin_buffer) > 0 &&
- packet_not_very_much_data_to_write()) {
+ packet_not_very_much_data_to_write()) {
len = buffer_len(&stdin_buffer);
/* Keep the packets at reasonable size. */
if (len > packet_get_maxsize())
@@ -283,7 +279,7 @@ client_make_packets_from_stdin_data(void)
* appropriate.
*/
-void
+static void
client_check_window_change(void)
{
struct winsize ws;
@@ -320,12 +316,12 @@ client_check_window_change(void)
* one of the file descriptors).
*/
-void
+static void
client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
- int *maxfdp, int rekeying)
+ int *maxfdp, int *nallocp, int rekeying)
{
/* Add any selections by the channel mechanism. */
- channel_prepare_select(readsetp, writesetp, maxfdp, rekeying);
+ channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, rekeying);
if (!compat20) {
/* Read from the connection, unless our buffers are full. */
@@ -346,7 +342,16 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
if (buffer_len(&stderr_buffer) > 0)
FD_SET(fileno(stderr), *writesetp);
} else {
- FD_SET(connection_in, *readsetp);
+ /* channel_prepare_select could have closed the last channel */
+ if (session_closed && !channel_still_open() &&
+ !packet_have_data_to_write()) {
+ /* clear mask since we did not call select() */
+ memset(*readsetp, 0, *nallocp);
+ memset(*writesetp, 0, *nallocp);
+ return;
+ } else {
+ FD_SET(connection_in, *readsetp);
+ }
}
/* Select server connection if have data to write to the server. */
@@ -370,8 +375,8 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
* We have to return, because the mainloop checks for the flags
* set by the signal handlers.
*/
- memset(*readsetp, 0, *maxfdp);
- memset(*writesetp, 0, *maxfdp);
+ memset(*readsetp, 0, *nallocp);
+ memset(*writesetp, 0, *nallocp);
if (errno == EINTR)
return;
@@ -382,7 +387,7 @@ client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
}
}
-void
+static void
client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
{
struct winsize oldws, newws;
@@ -412,9 +417,9 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
/* Check if the window size has changed. */
if (ioctl(fileno(stdin), TIOCGWINSZ, &newws) >= 0 &&
(oldws.ws_row != newws.ws_row ||
- oldws.ws_col != newws.ws_col ||
- oldws.ws_xpixel != newws.ws_xpixel ||
- oldws.ws_ypixel != newws.ws_ypixel))
+ oldws.ws_col != newws.ws_col ||
+ oldws.ws_xpixel != newws.ws_xpixel ||
+ oldws.ws_ypixel != newws.ws_ypixel))
received_window_change_signal = 1;
/* OK, we have been continued by the user. Reinitialize buffers. */
@@ -425,7 +430,7 @@ client_suspend_self(Buffer *bin, Buffer *bout, Buffer *berr)
enter_raw_mode();
}
-void
+static void
client_process_net_input(fd_set * readset)
{
int len;
@@ -466,7 +471,7 @@ client_process_net_input(fd_set * readset)
}
/* process the characters one by one */
-int
+static int
process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len)
{
char string[1024];
@@ -517,36 +522,19 @@ process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len)
continue;
case '&':
- /* XXX does not work yet with proto 2 */
- if (compat20)
- continue;
/*
* Detach the program (continue to serve connections,
* but put in background and no more new connections).
*/
- if (!stdin_eof) {
- /*
- * Sending SSH_CMSG_EOF alone does not always appear
- * to be enough. So we try to send an EOF character
- * first.
- */
- packet_start(SSH_CMSG_STDIN_DATA);
- packet_put_string("\004", 1);
- packet_send();
- /* Close stdin. */
- stdin_eof = 1;
- if (buffer_len(bin) == 0) {
- packet_start(SSH_CMSG_EOF);
- packet_send();
- }
- }
/* Restore tty modes. */
leave_raw_mode();
/* Stop listening for new connections. */
channel_stop_listening();
- printf("%c& [backgrounded]\n", escape_char);
+ snprintf(string, sizeof string,
+ "%c& [backgrounded]\n", escape_char);
+ buffer_append(berr, string, strlen(string));
/* Fork into background. */
pid = fork();
@@ -559,14 +547,34 @@ process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len)
exit(0);
}
/* The child continues serving connections. */
- continue; /*XXX ? */
+ if (compat20) {
+ buffer_append(bin, "\004", 1);
+ /* fake EOF on stdin */
+ return -1;
+ } else if (!stdin_eof) {
+ /*
+ * Sending SSH_CMSG_EOF alone does not always appear
+ * to be enough. So we try to send an EOF character
+ * first.
+ */
+ packet_start(SSH_CMSG_STDIN_DATA);
+ packet_put_string("\004", 1);
+ packet_send();
+ /* Close stdin. */
+ stdin_eof = 1;
+ if (buffer_len(bin) == 0) {
+ packet_start(SSH_CMSG_EOF);
+ packet_send();
+ }
+ }
+ continue;
case '?':
snprintf(string, sizeof string,
"%c?\r\n\
Supported escape sequences:\r\n\
~. - terminate connection\r\n\
-~R - Request rekey (SSH protocol 2 only)\r\n\
+~R - Request rekey (SSH protocol 2 only)\r\n\
~^Z - suspend ssh\r\n\
~# - list forwarded connections\r\n\
~& - background ssh (when waiting for connections to terminate)\r\n\
@@ -616,7 +624,7 @@ Supported escape sequences:\r\n\
return bytes;
}
-void
+static void
client_process_input(fd_set * readset)
{
int len;
@@ -651,7 +659,7 @@ client_process_input(fd_set * readset)
packet_start(SSH_CMSG_EOF);
packet_send();
}
- } else if (escape_char == -1) {
+ } else if (escape_char == SSH_ESCAPECHAR_NONE) {
/*
* Normal successful read, and no escape character.
* Just append the data to buffer.
@@ -669,7 +677,7 @@ client_process_input(fd_set * readset)
}
}
-void
+static void
client_process_output(fd_set * writeset)
{
int len;
@@ -730,7 +738,7 @@ client_process_output(fd_set * writeset)
* preparatory phase.
*/
-void
+static void
client_process_buffered_input_packets(void)
{
dispatch_run(DISPATCH_NONBLOCK, &quit_pending, compat20 ? xxx_kex : NULL);
@@ -738,19 +746,20 @@ client_process_buffered_input_packets(void)
/* scan buf[] for '~' before sending data to the peer */
-int
+static int
simple_escape_filter(Channel *c, char *buf, int len)
{
/* XXX we assume c->extended is writeable */
return process_escapes(&c->input, &c->output, &c->extended, buf, len);
}
-void
+static void
client_channel_closed(int id, void *arg)
{
if (id != session_ident)
error("client_channel_closed: id %d != session_ident %d",
id, session_ident);
+ channel_cancel_cleanup(id);
session_closed = 1;
if (in_raw_mode())
leave_raw_mode();
@@ -759,8 +768,8 @@ client_channel_closed(int id, void *arg)
/*
* Implements the interactive session with the server. This is called after
* the user has been authenticated, and a command has been started on the
- * remote host. If escape_char != -1, it is the character used as an escape
- * character for terminating or suspending the session.
+ * remote host. If escape_char != SSH_ESCAPECHAR_NONE, it is the character
+ * used as an escape character for terminating or suspending the session.
*/
int
@@ -768,7 +777,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
{
fd_set *readset = NULL, *writeset = NULL;
double start_time, total_time;
- int max_fd = 0, len, rekeying = 0;
+ int max_fd = 0, max_fd2 = 0, len, rekeying = 0, nalloc = 0;
char buf[100];
debug("Entering interactive session.");
@@ -814,7 +823,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
signal(SIGINT, signal_handler);
signal(SIGQUIT, signal_handler);
signal(SIGTERM, signal_handler);
- signal(SIGPIPE, SIG_IGN);
if (have_pty)
signal(SIGWINCH, window_change_handler);
@@ -823,7 +831,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
if (compat20) {
session_ident = ssh2_chan_id;
- if (escape_char != -1)
+ if (escape_char != SSH_ESCAPECHAR_NONE)
channel_register_filter(session_ident,
simple_escape_filter);
if (session_ident != -1)
@@ -875,8 +883,9 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
* Wait until we have something to do (something becomes
* available on one of the descriptors).
*/
+ max_fd2 = max_fd;
client_wait_until_can_do_something(&readset, &writeset,
- &max_fd, rekeying);
+ &max_fd2, &nalloc, rekeying);
if (quit_pending)
break;
@@ -924,8 +933,24 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
if (have_pty)
signal(SIGWINCH, SIG_DFL);
- /* Stop listening for connections. */
- channel_stop_listening();
+ channel_free_all();
+
+ if (have_pty)
+ leave_raw_mode();
+
+ /* restore blocking io */
+ if (!isatty(fileno(stdin)))
+ unset_nonblock(fileno(stdin));
+ if (!isatty(fileno(stdout)))
+ unset_nonblock(fileno(stdout));
+ if (!isatty(fileno(stderr)))
+ unset_nonblock(fileno(stderr));
+
+ if (received_signal) {
+ if (in_non_blocking_mode) /* XXX */
+ leave_non_blocking();
+ fatal("Killed by signal %d.", (int) received_signal);
+ }
/*
* In interactive mode (with pseudo tty) display a message indicating
@@ -935,6 +960,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
snprintf(buf, sizeof buf, "Connection to %.64s closed.\r\n", host);
buffer_append(&stderr_buffer, buf, strlen(buf));
}
+
/* Output any buffered data for stdout. */
while (buffer_len(&stdout_buffer) > 0) {
len = write(fileno(stdout), buffer_ptr(&stdout_buffer),
@@ -959,9 +985,6 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
stderr_bytes += len;
}
- if (have_pty)
- leave_raw_mode();
-
/* Clear and free any buffers. */
memset(buf, 0, sizeof(buf));
buffer_free(&stdin_buffer);
@@ -971,11 +994,11 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
/* Report bytes transferred, and transfer rates. */
total_time = get_current_time() - start_time;
debug("Transferred: stdin %lu, stdout %lu, stderr %lu bytes in %.1f seconds",
- stdin_bytes, stdout_bytes, stderr_bytes, total_time);
+ stdin_bytes, stdout_bytes, stderr_bytes, total_time);
if (total_time > 0)
debug("Bytes per second: stdin %.1f, stdout %.1f, stderr %.1f",
- stdin_bytes / total_time, stdout_bytes / total_time,
- stderr_bytes / total_time);
+ stdin_bytes / total_time, stdout_bytes / total_time,
+ stderr_bytes / total_time);
/* Return the exit status of the program. */
debug("Exit status %d", exit_status);
@@ -984,31 +1007,31 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
/*********/
-void
-client_input_stdout_data(int type, int plen, void *ctxt)
+static void
+client_input_stdout_data(int type, u_int32_t seq, void *ctxt)
{
u_int data_len;
char *data = packet_get_string(&data_len);
- packet_integrity_check(plen, 4 + data_len, type);
+ packet_check_eom();
buffer_append(&stdout_buffer, data, data_len);
memset(data, 0, data_len);
xfree(data);
}
-void
-client_input_stderr_data(int type, int plen, void *ctxt)
+static void
+client_input_stderr_data(int type, u_int32_t seq, void *ctxt)
{
u_int data_len;
char *data = packet_get_string(&data_len);
- packet_integrity_check(plen, 4 + data_len, type);
+ packet_check_eom();
buffer_append(&stderr_buffer, data, data_len);
memset(data, 0, data_len);
xfree(data);
}
-void
-client_input_exit_status(int type, int plen, void *ctxt)
+static void
+client_input_exit_status(int type, u_int32_t seq, void *ctxt)
{
- packet_integrity_check(plen, 4, type);
exit_status = packet_get_int();
+ packet_check_eom();
/* Acknowledge the exit. */
packet_start(SSH_CMSG_EXIT_CONFIRMATION);
packet_send();
@@ -1021,44 +1044,46 @@ client_input_exit_status(int type, int plen, void *ctxt)
quit_pending = 1;
}
-Channel *
+static Channel *
client_request_forwarded_tcpip(const char *request_type, int rchan)
{
Channel* c = NULL;
char *listen_address, *originator_address;
int listen_port, originator_port;
- int sock, newch;
+ int sock;
/* Get rest of the packet */
listen_address = packet_get_string(NULL);
listen_port = packet_get_int();
originator_address = packet_get_string(NULL);
originator_port = packet_get_int();
- packet_done();
+ packet_check_eom();
debug("client_request_forwarded_tcpip: listen %s port %d, originator %s port %d",
listen_address, listen_port, originator_address, originator_port);
- sock = channel_connect_by_listen_adress(listen_port);
- if (sock >= 0) {
- newch = channel_new("forwarded-tcpip",
- SSH_CHANNEL_CONNECTING, sock, sock, -1,
- CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
- xstrdup(originator_address), 1);
- c = channel_lookup(newch);
+ sock = channel_connect_by_listen_address(listen_port);
+ if (sock < 0) {
+ xfree(originator_address);
+ xfree(listen_address);
+ return NULL;
}
+ c = channel_new("forwarded-tcpip",
+ SSH_CHANNEL_CONNECTING, sock, sock, -1,
+ CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
+ xstrdup(originator_address), 1);
xfree(originator_address);
xfree(listen_address);
return c;
}
-Channel*
+static Channel*
client_request_x11(const char *request_type, int rchan)
{
Channel *c = NULL;
char *originator;
int originator_port;
- int sock, newch;
+ int sock;
if (!options.forward_x11) {
error("Warning: ssh server tried X11 forwarding.");
@@ -1072,27 +1097,27 @@ client_request_x11(const char *request_type, int rchan)
} else {
originator_port = packet_get_int();
}
- packet_done();
+ packet_check_eom();
/* XXX check permission */
debug("client_request_x11: request from %s %d", originator,
originator_port);
- sock = x11_connect_display();
- if (sock >= 0) {
- newch = channel_new("x11",
- SSH_CHANNEL_X11_OPEN, sock, sock, -1,
- CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0,
- xstrdup("x11"), 1);
- c = channel_lookup(newch);
- }
xfree(originator);
+ sock = x11_connect_display();
+ if (sock < 0)
+ return NULL;
+ c = channel_new("x11",
+ SSH_CHANNEL_X11_OPEN, sock, sock, -1,
+ CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0,
+ xstrdup("x11"), 1);
+ c->force_drain = 1;
return c;
}
-Channel*
+static Channel*
client_request_agent(const char *request_type, int rchan)
{
Channel *c = NULL;
- int sock, newch;
+ int sock;
if (!options.forward_agent) {
error("Warning: ssh server tried agent forwarding.");
@@ -1100,19 +1125,19 @@ client_request_agent(const char *request_type, int rchan)
return NULL;
}
sock = ssh_get_authentication_socket();
- if (sock >= 0) {
- newch = channel_new("authentication agent connection",
- SSH_CHANNEL_OPEN, sock, sock, -1,
- CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
- xstrdup("authentication agent connection"), 1);
- c = channel_lookup(newch);
- }
+ if (sock < 0)
+ return NULL;
+ c = channel_new("authentication agent connection",
+ SSH_CHANNEL_OPEN, sock, sock, -1,
+ CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
+ xstrdup("authentication agent connection"), 1);
+ c->force_drain = 1;
return c;
}
/* XXXX move to generic input handler */
-void
-client_input_channel_open(int type, int plen, void *ctxt)
+static void
+client_input_channel_open(int type, u_int32_t seq, void *ctxt)
{
Channel *c = NULL;
char *ctype;
@@ -1142,26 +1167,29 @@ client_input_channel_open(int type, int plen, void *ctxt)
c->remote_id = rchan;
c->remote_window = rwindow;
c->remote_maxpacket = rmaxpack;
-
- packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
- packet_put_int(c->remote_id);
- packet_put_int(c->self);
- packet_put_int(c->local_window);
- packet_put_int(c->local_maxpacket);
- packet_send();
+ if (c->type != SSH_CHANNEL_CONNECTING) {
+ packet_start(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
+ packet_put_int(c->remote_id);
+ packet_put_int(c->self);
+ packet_put_int(c->local_window);
+ packet_put_int(c->local_maxpacket);
+ packet_send();
+ }
} else {
debug("failure %s", ctype);
packet_start(SSH2_MSG_CHANNEL_OPEN_FAILURE);
packet_put_int(rchan);
packet_put_int(SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED);
- packet_put_cstring("bla bla");
- packet_put_cstring("");
+ if (!(datafellows & SSH_BUG_OPENFAILURE)) {
+ packet_put_cstring("open failed");
+ packet_put_cstring("");
+ }
packet_send();
}
xfree(ctype);
}
-void
-client_input_channel_req(int type, int plen, void *ctxt)
+static void
+client_input_channel_req(int type, u_int32_t seq, void *ctxt)
{
Channel *c = NULL;
int id, reply, success = 0;
@@ -1186,7 +1214,7 @@ client_input_channel_req(int type, int plen, void *ctxt)
} else if (strcmp(rtype, "exit-status") == 0) {
success = 1;
exit_status = packet_get_int();
- packet_done();
+ packet_check_eom();
}
if (reply) {
packet_start(success ?
@@ -1196,8 +1224,26 @@ client_input_channel_req(int type, int plen, void *ctxt)
}
xfree(rtype);
}
+static void
+client_input_global_request(int type, u_int32_t seq, void *ctxt)
+{
+ char *rtype;
+ int want_reply;
+ int success = 0;
+
+ rtype = packet_get_string(NULL);
+ want_reply = packet_get_char();
+ debug("client_input_global_request: rtype %s want_reply %d", rtype, want_reply);
+ if (want_reply) {
+ packet_start(success ?
+ SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE);
+ packet_send();
+ packet_write_wait();
+ }
+ xfree(rtype);
+}
-void
+static void
client_init_dispatch_20(void)
{
dispatch_init(&dispatch_protocol_error);
@@ -1210,11 +1256,12 @@ client_init_dispatch_20(void)
dispatch_set(SSH2_MSG_CHANNEL_OPEN_FAILURE, &channel_input_open_failure);
dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &client_input_channel_req);
dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
+ dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &client_input_global_request);
/* rekeying */
dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
}
-void
+static void
client_init_dispatch_13(void)
{
dispatch_init(NULL);
@@ -1233,14 +1280,14 @@ client_init_dispatch_13(void)
dispatch_set(SSH_SMSG_X11_OPEN, options.forward_x11 ?
&x11_input_open : &deny_input_open);
}
-void
+static void
client_init_dispatch_15(void)
{
client_init_dispatch_13();
dispatch_set(SSH_MSG_CHANNEL_CLOSE, &channel_input_ieof);
dispatch_set(SSH_MSG_CHANNEL_CLOSE_CONFIRMATION, & channel_input_oclose);
}
-void
+static void
client_init_dispatch(void)
{
if (compat20)
diff --git a/crypto/openssh/clientloop.h b/crypto/openssh/clientloop.h
index ee40d87..1bc9a95 100644
--- a/crypto/openssh/clientloop.h
+++ b/crypto/openssh/clientloop.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.h,v 1.4 2001/02/06 22:43:02 markus Exp $ */
+/* $OpenBSD: clientloop.h,v 1.6 2001/06/26 17:27:23 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -36,4 +36,4 @@
*/
/* Client side main loop for the interactive session. */
-int client_loop(int have_pty, int escape_char, int id);
+int client_loop(int, int, int);
diff --git a/crypto/openssh/compress.c b/crypto/openssh/compress.c
index 3e41b3d..3badbf4 100644
--- a/crypto/openssh/compress.c
+++ b/crypto/openssh/compress.c
@@ -12,7 +12,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: compress.c,v 1.14 2001/04/05 10:39:01 markus Exp $");
+RCSID("$OpenBSD: compress.c,v 1.17 2001/12/29 21:56:01 stevesk Exp $");
#include "log.h"
#include "buffer.h"
@@ -33,7 +33,7 @@ void
buffer_compress_init_send(int level)
{
if (compress_init_send_called == 1)
- deflateEnd(&incoming_stream);
+ deflateEnd(&outgoing_stream);
compress_init_send_called = 1;
debug("Enabling compression at level %d.", level);
if (level < 1 || level > 9)
@@ -55,13 +55,13 @@ void
buffer_compress_uninit(void)
{
debug("compress outgoing: raw data %lu, compressed %lu, factor %.2f",
- outgoing_stream.total_in, outgoing_stream.total_out,
- outgoing_stream.total_in == 0 ? 0.0 :
- (double) outgoing_stream.total_out / outgoing_stream.total_in);
+ outgoing_stream.total_in, outgoing_stream.total_out,
+ outgoing_stream.total_in == 0 ? 0.0 :
+ (double) outgoing_stream.total_out / outgoing_stream.total_in);
debug("compress incoming: raw data %lu, compressed %lu, factor %.2f",
- incoming_stream.total_out, incoming_stream.total_in,
- incoming_stream.total_out == 0 ? 0.0 :
- (double) incoming_stream.total_in / incoming_stream.total_out);
+ incoming_stream.total_out, incoming_stream.total_in,
+ incoming_stream.total_out == 0 ? 0.0 :
+ (double) incoming_stream.total_in / incoming_stream.total_out);
if (compress_init_recv_called == 1)
inflateEnd(&incoming_stream);
if (compress_init_send_called == 1)
@@ -80,7 +80,7 @@ buffer_compress_uninit(void)
void
buffer_compress(Buffer * input_buffer, Buffer * output_buffer)
{
- char buf[4096];
+ u_char buf[4096];
int status;
/* This case is not handled below. */
@@ -88,13 +88,13 @@ buffer_compress(Buffer * input_buffer, Buffer * output_buffer)
return;
/* Input is the contents of the input buffer. */
- outgoing_stream.next_in = (u_char *) buffer_ptr(input_buffer);
+ outgoing_stream.next_in = buffer_ptr(input_buffer);
outgoing_stream.avail_in = buffer_len(input_buffer);
/* Loop compressing until deflate() returns with avail_out != 0. */
do {
/* Set up fixed-size output buffer. */
- outgoing_stream.next_out = (u_char *)buf;
+ outgoing_stream.next_out = buf;
outgoing_stream.avail_out = sizeof(buf);
/* Compress as much data into the buffer as possible. */
@@ -124,15 +124,15 @@ buffer_compress(Buffer * input_buffer, Buffer * output_buffer)
void
buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer)
{
- char buf[4096];
+ u_char buf[4096];
int status;
- incoming_stream.next_in = (u_char *) buffer_ptr(input_buffer);
+ incoming_stream.next_in = buffer_ptr(input_buffer);
incoming_stream.avail_in = buffer_len(input_buffer);
for (;;) {
/* Set up fixed-size output buffer. */
- incoming_stream.next_out = (u_char *) buf;
+ incoming_stream.next_out = buf;
incoming_stream.avail_out = sizeof(buf);
status = inflate(&incoming_stream, Z_PARTIAL_FLUSH);
diff --git a/crypto/openssh/compress.h b/crypto/openssh/compress.h
index f90932a..e364f4b 100644
--- a/crypto/openssh/compress.h
+++ b/crypto/openssh/compress.h
@@ -1,3 +1,5 @@
+/* $OpenBSD: compress.h,v 1.11 2002/03/04 17:27:39 stevesk Exp $ */
+
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -11,39 +13,13 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-/* RCSID("$OpenBSD: compress.h,v 1.8 2001/04/05 10:39:02 markus Exp $"); */
-
#ifndef COMPRESS_H
#define COMPRESS_H
-/*
- * Initializes compression; level is compression level from 1 to 9 (as in
- * gzip).
- */
-void buffer_compress_init_send(int level);
-void buffer_compress_init_recv(void);
-
-/* Frees any data structures allocated by buffer_compress_init. */
-void buffer_compress_uninit(void);
-
-/*
- * Compresses the contents of input_buffer into output_buffer. All packets
- * compressed using this function will form a single compressed data stream;
- * however, data will be flushed at the end of every call so that each
- * output_buffer can be decompressed independently (but in the appropriate
- * order since they together form a single compression stream) by the
- * receiver. This appends the compressed data to the output buffer.
- */
-void buffer_compress(Buffer * input_buffer, Buffer * output_buffer);
-
-/*
- * Uncompresses the contents of input_buffer into output_buffer. All packets
- * uncompressed using this function will form a single compressed data
- * stream; however, data will be flushed at the end of every call so that
- * each output_buffer. This must be called for the same size units that the
- * buffer_compress was called, and in the same order that buffers compressed
- * with that. This appends the uncompressed data to the output buffer.
- */
-void buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer);
+void buffer_compress_init_send(int);
+void buffer_compress_init_recv(void);
+void buffer_compress_uninit(void);
+void buffer_compress(Buffer *, Buffer *);
+void buffer_uncompress(Buffer *, Buffer *);
#endif /* COMPRESS_H */
diff --git a/crypto/openssh/crc32.h b/crypto/openssh/crc32.h
index c469a90..cd1832f 100644
--- a/crypto/openssh/crc32.h
+++ b/crypto/openssh/crc32.h
@@ -1,3 +1,5 @@
+/* $OpenBSD: crc32.h,v 1.13 2002/03/04 17:27:39 stevesk Exp $ */
+
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1992 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -11,15 +13,9 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-/* RCSID("$OpenBSD: crc32.h,v 1.10 2001/03/02 18:54:31 deraadt Exp $"); */
-
#ifndef CRC32_H
#define CRC32_H
-/*
- * This computes a 32 bit CRC of the data in the buffer, and returns the CRC.
- * The polynomial used is 0xedb88320.
- */
-u_int ssh_crc32(const u_char *buf, u_int len);
+u_int ssh_crc32(const u_char *, u_int);
#endif /* CRC32_H */
diff --git a/crypto/openssh/deattack.c b/crypto/openssh/deattack.c
index 36023e0..0442501 100644
--- a/crypto/openssh/deattack.c
+++ b/crypto/openssh/deattack.c
@@ -1,5 +1,3 @@
-/* $OpenBSD: deattack.c,v 1.13 2001/03/01 02:45:10 deraadt Exp $ */
-
/*
* Cryptographic attack detector for ssh - source code
*
@@ -20,11 +18,14 @@
*/
#include "includes.h"
+RCSID("$OpenBSD: deattack.c,v 1.18 2002/03/04 17:27:39 stevesk Exp $");
+
#include "deattack.h"
#include "log.h"
#include "crc32.h"
#include "getput.h"
#include "xmalloc.h"
+#include "deattack.h"
/* SSH Constants */
#define SSH_MAXBLOCKS (32 * 1024)
@@ -36,7 +37,7 @@
#define HASH_FACTOR(x) ((x)*3/2)
#define HASH_UNUSEDCHAR (0xff)
#define HASH_UNUSED (0xffff)
-#define HASH_IV (0xfffe)
+#define HASH_IV (0xfffe)
#define HASH_MINBLOCKS (7*SSH_BLOCKSIZE)
@@ -46,8 +47,7 @@
#define CMP(a, b) (memcmp(a, b, SSH_BLOCKSIZE))
-
-void
+static void
crc_update(u_int32_t *a, u_int32_t b)
{
b ^= *a;
@@ -55,7 +55,7 @@ crc_update(u_int32_t *a, u_int32_t b)
}
/* detect if a block is used in a particular pattern */
-int
+static int
check_crc(u_char *S, u_char *buf, u_int32_t len,
u_char *IV)
{
@@ -86,9 +86,9 @@ detect_attack(u_char *buf, u_int32_t len, u_char *IV)
{
static u_int16_t *h = (u_int16_t *) NULL;
static u_int32_t n = HASH_MINSIZE / HASH_ENTRYSIZE;
- register u_int32_t i, j;
+ u_int32_t i, j;
u_int32_t l;
- register u_char *c;
+ u_char *c;
u_char *d;
if (len > (SSH_MAXBLOCKS * SSH_BLOCKSIZE) ||
@@ -135,7 +135,7 @@ detect_attack(u_char *buf, u_int32_t len, u_char *IV)
for (c = buf, j = 0; c < (buf + len); c += SSH_BLOCKSIZE, j++) {
for (i = HASH(c) & (n - 1); h[i] != HASH_UNUSED;
- i = (i + 1) & (n - 1)) {
+ i = (i + 1) & (n - 1)) {
if (h[i] == HASH_IV) {
if (!CMP(c, IV)) {
if (check_crc(c, buf, len, IV))
diff --git a/crypto/openssh/deattack.h b/crypto/openssh/deattack.h
index 3907159..ddccdea 100644
--- a/crypto/openssh/deattack.h
+++ b/crypto/openssh/deattack.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: deattack.h,v 1.5 2001/01/29 01:58:15 niklas Exp $ */
+/* $OpenBSD: deattack.h,v 1.7 2001/06/26 17:27:23 markus Exp $ */
/*
* Cryptographic attack detector for ssh - Header file
@@ -26,5 +26,5 @@
#define DEATTACK_OK 0
#define DEATTACK_DETECTED 1
-int detect_attack(u_char *buf, u_int32_t len, u_char IV[8]);
+int detect_attack(u_char *, u_int32_t, u_char[8]);
#endif
diff --git a/crypto/openssh/dh.c b/crypto/openssh/dh.c
index 575522d..33187e0 100644
--- a/crypto/openssh/dh.c
+++ b/crypto/openssh/dh.c
@@ -23,7 +23,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: dh.c,v 1.14 2001/04/15 08:43:45 markus Exp $");
+RCSID("$OpenBSD: dh.c,v 1.21 2002/03/06 00:23:27 markus Exp $");
#include "xmalloc.h"
@@ -39,7 +39,7 @@ RCSID("$OpenBSD: dh.c,v 1.14 2001/04/15 08:43:45 markus Exp $");
#include "log.h"
#include "misc.h"
-int
+static int
parse_prime(int linenum, char *line, struct dhgroup *dhg)
{
char *cp, *arg;
@@ -78,8 +78,10 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg)
if (cp != NULL || *prime == '\0')
goto fail;
- dhg->g = BN_new();
- dhg->p = BN_new();
+ if ((dhg->g = BN_new()) == NULL)
+ fatal("parse_prime: BN_new failed");
+ if ((dhg->p = BN_new()) == NULL)
+ fatal("parse_prime: BN_new failed");
if (BN_hex2bn(&dhg->g, gen) == 0)
goto failclean;
@@ -92,8 +94,8 @@ parse_prime(int linenum, char *line, struct dhgroup *dhg)
return (1);
failclean:
- BN_free(dhg->g);
- BN_free(dhg->p);
+ BN_clear_free(dhg->g);
+ BN_clear_free(dhg->p);
fail:
error("Bad prime description in line %d", linenum);
return (0);
@@ -103,14 +105,14 @@ DH *
choose_dh(int min, int wantbits, int max)
{
FILE *f;
- char line[1024];
+ char line[2048];
int best, bestcount, which;
int linenum;
struct dhgroup dhg;
- f = fopen(_PATH_DH_PRIMES, "r");
- if (!f) {
- log("WARNING: %s does not exist, using old prime", _PATH_DH_PRIMES);
+ if ((f = fopen(_PATH_DH_MODULI, "r")) == NULL &&
+ (f = fopen(_PATH_DH_PRIMES, "r")) == NULL) {
+ log("WARNING: %s does not exist, using old modulus", _PATH_DH_MODULI);
return (dh_new_group1());
}
@@ -120,8 +122,8 @@ choose_dh(int min, int wantbits, int max)
linenum++;
if (!parse_prime(linenum, line, &dhg))
continue;
- BN_free(dhg.g);
- BN_free(dhg.p);
+ BN_clear_free(dhg.g);
+ BN_clear_free(dhg.p);
if (dhg.size > max || dhg.size < min)
continue;
@@ -134,18 +136,14 @@ choose_dh(int min, int wantbits, int max)
if (dhg.size == best)
bestcount++;
}
- fclose (f);
+ rewind(f);
if (bestcount == 0) {
+ fclose(f);
log("WARNING: no suitable primes in %s", _PATH_DH_PRIMES);
return (NULL);
}
- f = fopen(_PATH_DH_PRIMES, "r");
- if (!f) {
- fatal("WARNING: %s disappeared, giving up", _PATH_DH_PRIMES);
- }
-
linenum = 0;
which = arc4random() % bestcount;
while (fgets(line, sizeof(line), f)) {
@@ -154,8 +152,8 @@ choose_dh(int min, int wantbits, int max)
if ((dhg.size > max || dhg.size < min) ||
dhg.size != best ||
linenum++ != which) {
- BN_free(dhg.g);
- BN_free(dhg.p);
+ BN_clear_free(dhg.g);
+ BN_clear_free(dhg.p);
continue;
}
break;
@@ -205,9 +203,8 @@ dh_gen_key(DH *dh, int need)
BN_num_bits(dh->p), 2*need);
do {
if (dh->priv_key != NULL)
- BN_free(dh->priv_key);
- dh->priv_key = BN_new();
- if (dh->priv_key == NULL)
+ BN_clear_free(dh->priv_key);
+ if ((dh->priv_key = BN_new()) == NULL)
fatal("dh_gen_key: BN_new failed");
/* generate a 2*need bits random private exponent */
if (!BN_rand(dh->priv_key, 2*need, 0, 0))
@@ -229,9 +226,8 @@ dh_new_group_asc(const char *gen, const char *modulus)
{
DH *dh;
- dh = DH_new();
- if (dh == NULL)
- fatal("DH_new");
+ if ((dh = DH_new()) == NULL)
+ fatal("dh_new_group_asc: DH_new");
if (BN_hex2bn(&dh->p, modulus) == 0)
fatal("BN_hex2bn p");
@@ -251,9 +247,8 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulus)
{
DH *dh;
- dh = DH_new();
- if (dh == NULL)
- fatal("DH_new");
+ if ((dh = DH_new()) == NULL)
+ fatal("dh_new_group: DH_new");
dh->p = modulus;
dh->g = gen;
diff --git a/crypto/openssh/dh.h b/crypto/openssh/dh.h
index e8b2944..a0c97b2 100644
--- a/crypto/openssh/dh.h
+++ b/crypto/openssh/dh.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dh.h,v 1.5 2001/04/03 19:53:29 markus Exp $ */
+/* $OpenBSD: dh.h,v 1.7 2001/06/26 17:27:23 markus Exp $ */
/*
* Copyright (c) 2000 Niels Provos. All rights reserved.
@@ -32,15 +32,15 @@ struct dhgroup {
BIGNUM *p;
};
-DH *choose_dh(int min, int nbits, int max);
+DH *choose_dh(int, int, int);
DH *dh_new_group_asc(const char *, const char *);
DH *dh_new_group(BIGNUM *, BIGNUM *);
DH *dh_new_group1(void);
-void dh_gen_key(DH *, int);
-int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);
+void dh_gen_key(DH *, int);
+int dh_pub_is_valid(DH *, BIGNUM *);
-int dh_estimate(int bits);
+int dh_estimate(int);
#define DH_GRP_MIN 1024
#define DH_GRP_MAX 8192
diff --git a/crypto/openssh/dispatch.c b/crypto/openssh/dispatch.c
index 7168d1c..ce32bc2 100644
--- a/crypto/openssh/dispatch.c
+++ b/crypto/openssh/dispatch.c
@@ -22,7 +22,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
-RCSID("$OpenBSD: dispatch.c,v 1.10 2001/02/18 18:33:53 markus Exp $");
+RCSID("$OpenBSD: dispatch.c,v 1.15 2002/01/11 13:39:36 markus Exp $");
#include "ssh1.h"
#include "ssh2.h"
@@ -37,20 +37,40 @@ RCSID("$OpenBSD: dispatch.c,v 1.10 2001/02/18 18:33:53 markus Exp $");
dispatch_fn *dispatch[DISPATCH_MAX];
void
-dispatch_protocol_error(int type, int plen, void *ctxt)
+dispatch_protocol_error(int type, u_int32_t seq, void *ctxt)
{
- error("Hm, dispatch protocol error: type %d plen %d", type, plen);
- if (compat20 && type == SSH2_MSG_KEXINIT)
- fatal("dispatch_protocol_error: rekeying is not supported");
+ log("dispatch_protocol_error: type %d seq %u", type, seq);
+ if (!compat20)
+ fatal("protocol error");
+ packet_start(SSH2_MSG_UNIMPLEMENTED);
+ packet_put_int(seq);
+ packet_send();
+ packet_write_wait();
+}
+void
+dispatch_protocol_ignore(int type, u_int32_t seq, void *ctxt)
+{
+ log("dispatch_protocol_ignore: type %d seq %u", type, seq);
}
void
dispatch_init(dispatch_fn *dflt)
{
- int i;
+ u_int i;
for (i = 0; i < DISPATCH_MAX; i++)
dispatch[i] = dflt;
}
void
+dispatch_range(u_int from, u_int to, dispatch_fn *fn)
+{
+ u_int i;
+
+ for (i = from; i <= to; i++) {
+ if (i >= DISPATCH_MAX)
+ break;
+ dispatch[i] = fn;
+ }
+}
+void
dispatch_set(int type, dispatch_fn *fn)
{
dispatch[type] = fn;
@@ -59,18 +79,18 @@ void
dispatch_run(int mode, int *done, void *ctxt)
{
for (;;) {
- int plen;
int type;
+ u_int32_t seqnr;
if (mode == DISPATCH_BLOCK) {
- type = packet_read(&plen);
+ type = packet_read_seqnr(&seqnr);
} else {
- type = packet_read_poll(&plen);
+ type = packet_read_poll_seqnr(&seqnr);
if (type == SSH_MSG_NONE)
return;
}
if (type > 0 && type < DISPATCH_MAX && dispatch[type] != NULL)
- (*dispatch[type])(type, plen, ctxt);
+ (*dispatch[type])(type, seqnr, ctxt);
else
packet_disconnect("protocol error: rcvd type %d", type);
if (done != NULL && *done)
diff --git a/crypto/openssh/dispatch.h b/crypto/openssh/dispatch.h
index 0bee03b..a82e216 100644
--- a/crypto/openssh/dispatch.h
+++ b/crypto/openssh/dispatch.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dispatch.h,v 1.4 2001/01/29 01:58:15 niklas Exp $ */
+/* $OpenBSD: dispatch.h,v 1.9 2002/01/11 13:39:36 markus Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -28,9 +28,11 @@ enum {
DISPATCH_NONBLOCK
};
-typedef void dispatch_fn(int type, int plen, void *ctxt);
+typedef void dispatch_fn(int, u_int32_t, void *);
-void dispatch_init(dispatch_fn *dflt);
-void dispatch_set(int type, dispatch_fn *fn);
-void dispatch_run(int mode, int *done, void *ctxt);
-void dispatch_protocol_error(int type, int plen, void *ctxt);
+void dispatch_init(dispatch_fn *);
+void dispatch_set(int, dispatch_fn *);
+void dispatch_range(u_int, u_int, dispatch_fn *);
+void dispatch_run(int, int *, void *);
+void dispatch_protocol_error(int, u_int32_t, void *);
+void dispatch_protocol_ignore(int, u_int32_t, void *);
diff --git a/crypto/openssh/fatal.c b/crypto/openssh/fatal.c
new file mode 100644
index 0000000..9e7d160
--- /dev/null
+++ b/crypto/openssh/fatal.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2002 Markus Friedl. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: fatal.c,v 1.1 2002/02/22 12:20:34 markus Exp $");
+
+#include "log.h"
+
+/* Fatal messages. This function never returns. */
+
+void
+fatal(const char *fmt,...)
+{
+ va_list args;
+ va_start(args, fmt);
+ do_log(SYSLOG_LEVEL_FATAL, fmt, args);
+ va_end(args);
+ fatal_cleanup();
+}
diff --git a/crypto/openssh/getput.h b/crypto/openssh/getput.h
index 1a19d22..20cf8f2 100644
--- a/crypto/openssh/getput.h
+++ b/crypto/openssh/getput.h
@@ -1,3 +1,5 @@
+/* $OpenBSD: getput.h,v 1.8 2002/03/04 17:27:39 stevesk Exp $ */
+
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -11,8 +13,6 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-/* RCSID("$OpenBSD: getput.h,v 1.7 2001/01/10 22:56:22 markus Exp $"); */
-
#ifndef GETPUT_H
#define GETPUT_H
diff --git a/crypto/openssh/groupaccess.c b/crypto/openssh/groupaccess.c
index ac9e00ac..66dfa68 100644
--- a/crypto/openssh/groupaccess.c
+++ b/crypto/openssh/groupaccess.c
@@ -1,5 +1,3 @@
-/* $OpenBSD: groupaccess.c,v 1.3 2001/01/29 01:58:15 niklas Exp $ */
-
/*
* Copyright (c) 2001 Kevin Steves. All rights reserved.
*
@@ -25,6 +23,7 @@
*/
#include "includes.h"
+RCSID("$OpenBSD: groupaccess.c,v 1.5 2002/03/04 17:27:39 stevesk Exp $");
#include "groupaccess.h"
#include "xmalloc.h"
@@ -34,6 +33,10 @@
static int ngroups;
static char *groups_byname[NGROUPS_MAX + 1]; /* +1 for base/primary group */
+/*
+ * Initialize group access list for user with primary (base) and
+ * supplementary groups. Return the number of groups in the list.
+ */
int
ga_init(const char *user, gid_t base)
{
@@ -53,6 +56,10 @@ ga_init(const char *user, gid_t base)
return (ngroups = j);
}
+/*
+ * Return 1 if one of user's groups is contained in groups.
+ * Return 0 otherwise. Use match_pattern() for string comparison.
+ */
int
ga_match(char * const *groups, int n)
{
@@ -65,6 +72,9 @@ ga_match(char * const *groups, int n)
return 0;
}
+/*
+ * Free memory allocated for group access list.
+ */
void
ga_free(void)
{
diff --git a/crypto/openssh/groupaccess.h b/crypto/openssh/groupaccess.h
index b4e5e42..ede4805 100644
--- a/crypto/openssh/groupaccess.h
+++ b/crypto/openssh/groupaccess.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: groupaccess.h,v 1.2 2001/01/29 01:58:15 niklas Exp $ */
+/* $OpenBSD: groupaccess.h,v 1.4 2001/06/26 17:27:23 markus Exp $ */
/*
* Copyright (c) 2001 Kevin Steves. All rights reserved.
@@ -29,21 +29,8 @@
#include <grp.h>
-/*
- * Initialize group access list for user with primary (base) and
- * supplementary groups. Return the number of groups in the list.
- */
-int ga_init(const char *user, gid_t base);
-
-/*
- * Return 1 if one of user's groups is contained in groups.
- * Return 0 otherwise. Use match_pattern() for string comparison.
- */
-int ga_match(char * const *groups, int ngroups);
-
-/*
- * Free memory allocated for group access list.
- */
-void ga_free(void);
+int ga_init(const char *, gid_t);
+int ga_match(char * const *, int);
+void ga_free(void);
#endif
diff --git a/crypto/openssh/hostfile.h b/crypto/openssh/hostfile.h
index 346bcd9..0244fdb 100644
--- a/crypto/openssh/hostfile.h
+++ b/crypto/openssh/hostfile.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: hostfile.h,v 1.7 2001/02/08 19:30:51 itojun Exp $ */
+/* $OpenBSD: hostfile.h,v 1.10 2001/12/18 10:04:21 jakob Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -14,27 +14,13 @@
#ifndef HOSTFILE_H
#define HOSTFILE_H
-int
-auth_rsa_read_key(char **cpp, u_int *bitsp, BIGNUM * e, BIGNUM * n);
-
-/*
- * Checks whether the given host is already in the list of our known hosts.
- * Returns HOST_OK if the host is known and has the specified key, HOST_NEW
- * if the host is not known, and HOST_CHANGED if the host is known but used
- * to have a different host key. The host must be in all lowercase.
- */
typedef enum {
HOST_OK, HOST_NEW, HOST_CHANGED
} HostStatus;
+int hostfile_read_key(char **, u_int *, Key *);
HostStatus
-check_host_in_hostfile(const char *filename, const char *host, Key *key,
- Key *found, int *line);
-
-/*
- * Appends an entry to the host file. Returns false if the entry could not
- * be appended.
- */
-int add_host_to_hostfile(const char *filename, const char *host, Key *key);
+check_host_in_hostfile(const char *, const char *, Key *, Key *, int *);
+int add_host_to_hostfile(const char *, const char *, Key *);
#endif
diff --git a/crypto/openssh/kex.c b/crypto/openssh/kex.c
index 69ba102..bf8fd95 100644
--- a/crypto/openssh/kex.c
+++ b/crypto/openssh/kex.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000 Markus Friedl. All rights reserved.
+ * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,7 +23,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: kex.c,v 1.33 2001/04/05 10:42:50 markus Exp $");
+RCSID("$OpenBSD: kex.c,v 1.47 2002/02/28 15:46:33 markus Exp $");
#include <openssl/crypto.h>
@@ -43,11 +43,12 @@ RCSID("$OpenBSD: kex.c,v 1.33 2001/04/05 10:42:50 markus Exp $");
#define KEX_COOKIE_LEN 16
-void kex_kexinit_finish(Kex *kex);
-void kex_choose_conf(Kex *k);
+/* prototype */
+static void kex_kexinit_finish(Kex *);
+static void kex_choose_conf(Kex *);
/* put algorithm proposal into buffer */
-void
+static void
kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
{
u_int32_t rand = 0;
@@ -67,7 +68,7 @@ kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
}
/* parse buffer and return algorithm proposal */
-char **
+static char **
kex_buf2prop(Buffer *raw)
{
Buffer b;
@@ -95,7 +96,7 @@ kex_buf2prop(Buffer *raw)
return proposal;
}
-void
+static void
kex_prop_free(char **proposal)
{
int i;
@@ -105,28 +106,24 @@ kex_prop_free(char **proposal)
xfree(proposal);
}
-void
-kex_protocol_error(int type, int plen, void *ctxt)
+static void
+kex_protocol_error(int type, u_int32_t seq, void *ctxt)
{
- error("Hm, kex protocol error: type %d plen %d", type, plen);
+ error("Hm, kex protocol error: type %d seq %u", type, seq);
}
-void
-kex_clear_dispatch(void)
+static void
+kex_reset_dispatch(void)
{
- int i;
-
- /* Numbers 30-49 are used for kex packets */
- for (i = 30; i <= 49; i++)
- dispatch_set(i, &kex_protocol_error);
+ dispatch_range(SSH2_MSG_TRANSPORT_MIN,
+ SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error);
+ dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
}
void
kex_finish(Kex *kex)
{
- int plen;
-
- kex_clear_dispatch();
+ kex_reset_dispatch();
packet_start(SSH2_MSG_NEWKEYS);
packet_send();
@@ -134,7 +131,8 @@ kex_finish(Kex *kex)
debug("SSH2_MSG_NEWKEYS sent");
debug("waiting for SSH2_MSG_NEWKEYS");
- packet_read_expect(&plen, SSH2_MSG_NEWKEYS);
+ packet_read_expect(SSH2_MSG_NEWKEYS);
+ packet_check_eom();
debug("SSH2_MSG_NEWKEYS received");
kex->done = 1;
@@ -165,7 +163,7 @@ kex_send_kexinit(Kex *kex)
}
void
-kex_input_kexinit(int type, int plen, void *ctxt)
+kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
{
char *ptr;
int dlen;
@@ -186,7 +184,7 @@ kex_input_kexinit(int type, int plen, void *ctxt)
xfree(packet_get_string(NULL));
packet_get_char();
packet_get_int();
- packet_done();
+ packet_check_eom();
kex_kexinit_finish(kex);
}
@@ -204,13 +202,12 @@ kex_setup(char *proposal[PROPOSAL_MAX])
kex->done = 0;
kex_send_kexinit(kex); /* we start */
- kex_clear_dispatch();
- dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
+ kex_reset_dispatch();
return kex;
}
-void
+static void
kex_kexinit_finish(Kex *kex)
{
if (!(kex->flags & KEX_INIT_SENT))
@@ -218,7 +215,7 @@ kex_kexinit_finish(Kex *kex)
kex_choose_conf(kex);
- switch(kex->kex_type) {
+ switch (kex->kex_type) {
case DH_GRP1_SHA1:
kexdh(kex);
break;
@@ -230,21 +227,22 @@ kex_kexinit_finish(Kex *kex)
}
}
-void
+static void
choose_enc(Enc *enc, char *client, char *server)
{
char *name = match_list(client, server, NULL);
if (name == NULL)
fatal("no matching cipher found: client %s server %s", client, server);
- enc->cipher = cipher_by_name(name);
- if (enc->cipher == NULL)
+ if ((enc->cipher = cipher_by_name(name)) == NULL)
fatal("matching cipher is not supported: %s", name);
enc->name = name;
enc->enabled = 0;
enc->iv = NULL;
enc->key = NULL;
+ enc->key_len = cipher_keylen(enc->cipher);
+ enc->block_size = cipher_blocksize(enc->cipher);
}
-void
+static void
choose_mac(Mac *mac, char *client, char *server)
{
char *name = match_list(client, server, NULL);
@@ -259,7 +257,7 @@ choose_mac(Mac *mac, char *client, char *server)
mac->key = NULL;
mac->enabled = 0;
}
-void
+static void
choose_comp(Comp *comp, char *client, char *server)
{
char *name = match_list(client, server, NULL);
@@ -274,7 +272,7 @@ choose_comp(Comp *comp, char *client, char *server)
}
comp->name = name;
}
-void
+static void
choose_kex(Kex *k, char *client, char *server)
{
k->name = match_list(client, server, NULL);
@@ -287,7 +285,7 @@ choose_kex(Kex *k, char *client, char *server)
} else
fatal("bad kex alg %s", k->name);
}
-void
+static void
choose_hostkeyalg(Kex *k, char *client, char *server)
{
char *hostkeyalg = match_list(client, server, NULL);
@@ -299,7 +297,7 @@ choose_hostkeyalg(Kex *k, char *client, char *server)
xfree(hostkeyalg);
}
-void
+static void
kex_choose_conf(Kex *kex)
{
Newkeys *newkeys;
@@ -345,10 +343,10 @@ kex_choose_conf(Kex *kex)
need = 0;
for (mode = 0; mode < MODE_MAX; mode++) {
newkeys = kex->newkeys[mode];
- if (need < newkeys->enc.cipher->key_len)
- need = newkeys->enc.cipher->key_len;
- if (need < newkeys->enc.cipher->block_size)
- need = newkeys->enc.cipher->block_size;
+ if (need < newkeys->enc.key_len)
+ need = newkeys->enc.key_len;
+ if (need < newkeys->enc.block_size)
+ need = newkeys->enc.block_size;
if (need < newkeys->mac.key_len)
need = newkeys->mac.key_len;
}
@@ -359,15 +357,15 @@ kex_choose_conf(Kex *kex)
kex_prop_free(peer);
}
-u_char *
+static u_char *
derive_key(Kex *kex, int id, int need, u_char *hash, BIGNUM *shared_secret)
{
Buffer b;
- EVP_MD *evp_md = EVP_sha1();
+ const EVP_MD *evp_md = EVP_sha1();
EVP_MD_CTX md;
char c = id;
int have;
- int mdsz = evp_md->md_size;
+ int mdsz = EVP_MD_size(evp_md);
u_char *digest = xmalloc(roundup(need, mdsz));
buffer_init(&b);
@@ -375,7 +373,8 @@ derive_key(Kex *kex, int id, int need, u_char *hash, BIGNUM *shared_secret)
/* K1 = HASH(K || H || "A" || session_id) */
EVP_DigestInit(&md, evp_md);
- EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
+ if (!(datafellows & SSH_BUG_DERIVEKEY))
+ EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
EVP_DigestUpdate(&md, hash, mdsz);
EVP_DigestUpdate(&md, &c, 1);
EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len);
@@ -388,7 +387,8 @@ derive_key(Kex *kex, int id, int need, u_char *hash, BIGNUM *shared_secret)
*/
for (have = mdsz; need > have; have += mdsz) {
EVP_DigestInit(&md, evp_md);
- EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
+ if (!(datafellows & SSH_BUG_DERIVEKEY))
+ EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
EVP_DigestUpdate(&md, hash, mdsz);
EVP_DigestUpdate(&md, digest, have);
EVP_DigestFinal(&md, digest + have, NULL);
@@ -441,7 +441,7 @@ dump_digest(char *msg, u_char *digest, int len)
int i;
fprintf(stderr, "%s\n", msg);
- for (i = 0; i< len; i++){
+ for (i = 0; i< len; i++) {
fprintf(stderr, "%02x", digest[i]);
if (i%32 == 31)
fprintf(stderr, "\n");
diff --git a/crypto/openssh/kex.h b/crypto/openssh/kex.h
index 8758804..755bf33 100644
--- a/crypto/openssh/kex.h
+++ b/crypto/openssh/kex.h
@@ -1,7 +1,7 @@
-/* $OpenBSD: kex.h,v 1.22 2001/04/04 20:25:37 markus Exp $ */
+/* $OpenBSD: kex.h,v 1.29 2002/02/14 23:41:01 markus Exp $ */
/*
- * Copyright (c) 2000 Markus Friedl. All rights reserved.
+ * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -71,6 +71,8 @@ struct Enc {
char *name;
Cipher *cipher;
int enabled;
+ u_int key_len;
+ u_int block_size;
u_char *key;
u_char *iv;
};
@@ -107,24 +109,24 @@ struct Kex {
int flags;
char *client_version_string;
char *server_version_string;
- int (*check_host_key)(Key *hostkey);
- Key *(*load_host_key)(int type);
+ int (*verify_host_key)(Key *);
+ Key *(*load_host_key)(int);
};
-Kex *kex_setup(char *proposal[PROPOSAL_MAX]);
-void kex_finish(Kex *kex);
+Kex *kex_setup(char *[PROPOSAL_MAX]);
+void kex_finish(Kex *);
-void kex_send_kexinit(Kex *kex);
-void kex_input_kexinit(int type, int plen, void *ctxt);
-void kex_derive_keys(Kex *k, u_char *hash, BIGNUM *shared_secret);
+void kex_send_kexinit(Kex *);
+void kex_input_kexinit(int, u_int32_t, void *);
+void kex_derive_keys(Kex *, u_char *, BIGNUM *);
-void kexdh(Kex *);
-void kexgex(Kex *);
+void kexdh(Kex *);
+void kexgex(Kex *);
-Newkeys *kex_get_newkeys(int mode);
+Newkeys *kex_get_newkeys(int);
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH)
-void dump_digest(char *msg, u_char *digest, int len);
+void dump_digest(char *, u_char *, int);
#endif
#endif
diff --git a/crypto/openssh/kexdh.c b/crypto/openssh/kexdh.c
index 7b6a220..eaf497c 100644
--- a/crypto/openssh/kexdh.c
+++ b/crypto/openssh/kexdh.c
@@ -23,7 +23,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: kexdh.c,v 1.3 2001/04/04 09:48:34 markus Exp $");
+RCSID("$OpenBSD: kexdh.c,v 1.17 2002/02/28 15:46:33 markus Exp $");
#include <openssl/crypto.h>
#include <openssl/bn.h>
@@ -38,25 +38,25 @@ RCSID("$OpenBSD: kexdh.c,v 1.3 2001/04/04 09:48:34 markus Exp $");
#include "dh.h"
#include "ssh2.h"
-u_char *
+static u_char *
kex_dh_hash(
char *client_version_string,
char *server_version_string,
char *ckexinit, int ckexinitlen,
char *skexinit, int skexinitlen,
- char *serverhostkeyblob, int sbloblen,
+ u_char *serverhostkeyblob, int sbloblen,
BIGNUM *client_dh_pub,
BIGNUM *server_dh_pub,
BIGNUM *shared_secret)
{
Buffer b;
static u_char digest[EVP_MAX_MD_SIZE];
- EVP_MD *evp_md = EVP_sha1();
+ const EVP_MD *evp_md = EVP_sha1();
EVP_MD_CTX md;
buffer_init(&b);
- buffer_put_string(&b, client_version_string, strlen(client_version_string));
- buffer_put_string(&b, server_version_string, strlen(server_version_string));
+ buffer_put_cstring(&b, client_version_string);
+ buffer_put_cstring(&b, server_version_string);
/* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
buffer_put_int(&b, ckexinitlen+1);
@@ -81,23 +81,22 @@ kex_dh_hash(
buffer_free(&b);
#ifdef DEBUG_KEX
- dump_digest("hash", digest, evp_md->md_size);
+ dump_digest("hash", digest, EVP_MD_size(evp_md));
#endif
return digest;
}
/* client */
-void
+static void
kexdh_client(Kex *kex)
{
BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
DH *dh;
Key *server_host_key;
- char *server_host_key_blob = NULL, *signature = NULL;
+ u_char *server_host_key_blob = NULL, *signature = NULL;
u_char *kbuf, *hash;
u_int klen, kout, slen, sbloblen;
- int dlen, plen;
/* generate and send 'e', client DH public key */
dh = dh_new_group1();
@@ -115,23 +114,24 @@ kexdh_client(Kex *kex)
#endif
debug("expecting SSH2_MSG_KEXDH_REPLY");
- packet_read_expect(&plen, SSH2_MSG_KEXDH_REPLY);
+ packet_read_expect(SSH2_MSG_KEXDH_REPLY);
/* key, cert */
server_host_key_blob = packet_get_string(&sbloblen);
server_host_key = key_from_blob(server_host_key_blob, sbloblen);
if (server_host_key == NULL)
fatal("cannot decode server_host_key_blob");
-
- if (kex->check_host_key == NULL)
- fatal("cannot check server_host_key");
- kex->check_host_key(server_host_key);
+ if (server_host_key->type != kex->hostkey_type)
+ fatal("type mismatch for decoded server_host_key_blob");
+ if (kex->verify_host_key == NULL)
+ fatal("cannot verify server_host_key");
+ if (kex->verify_host_key(server_host_key) == -1)
+ fatal("server_host_key verification failed");
/* DH paramter f, server public DH key */
- dh_server_pub = BN_new();
- if (dh_server_pub == NULL)
+ if ((dh_server_pub = BN_new()) == NULL)
fatal("dh_server_pub == NULL");
- packet_get_bignum2(dh_server_pub, &dlen);
+ packet_get_bignum2(dh_server_pub);
#ifdef DEBUG_KEXDH
fprintf(stderr, "dh_server_pub= ");
@@ -142,7 +142,7 @@ kexdh_client(Kex *kex)
/* signed H */
signature = packet_get_string(&slen);
- packet_done();
+ packet_check_eom();
if (!dh_pub_is_valid(dh, dh_server_pub))
packet_disconnect("bad server public DH value");
@@ -153,7 +153,8 @@ kexdh_client(Kex *kex)
#ifdef DEBUG_KEXDH
dump_digest("shared secret", kbuf, kout);
#endif
- shared_secret = BN_new();
+ if ((shared_secret = BN_new()) == NULL)
+ fatal("kexdh_client: BN_new failed");
BN_bin2bn(kbuf, kout, shared_secret);
memset(kbuf, 0, klen);
xfree(kbuf);
@@ -170,10 +171,10 @@ kexdh_client(Kex *kex)
shared_secret
);
xfree(server_host_key_blob);
- BN_free(dh_server_pub);
+ BN_clear_free(dh_server_pub);
DH_free(dh);
- if (key_verify(server_host_key, (u_char *)signature, slen, hash, 20) != 1)
+ if (key_verify(server_host_key, signature, slen, hash, 20) != 1)
fatal("key_verify failed for server_host_key");
key_free(server_host_key);
xfree(signature);
@@ -192,7 +193,7 @@ kexdh_client(Kex *kex)
/* server */
-void
+static void
kexdh_server(Kex *kex)
{
BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
@@ -200,14 +201,14 @@ kexdh_server(Kex *kex)
Key *server_host_key;
u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
u_int sbloblen, klen, kout;
- int dlen, slen, plen;
+ u_int slen;
/* generate server DH public key */
dh = dh_new_group1();
dh_gen_key(dh, kex->we_need * 8);
debug("expecting SSH2_MSG_KEXDH_INIT");
- packet_read_expect(&plen, SSH2_MSG_KEXDH_INIT);
+ packet_read_expect(SSH2_MSG_KEXDH_INIT);
if (kex->load_host_key == NULL)
fatal("Cannot load hostkey");
@@ -216,10 +217,10 @@ kexdh_server(Kex *kex)
fatal("Unsupported hostkey type %d", kex->hostkey_type);
/* key, cert */
- dh_client_pub = BN_new();
- if (dh_client_pub == NULL)
+ if ((dh_client_pub = BN_new()) == NULL)
fatal("dh_client_pub == NULL");
- packet_get_bignum2(dh_client_pub, &dlen);
+ packet_get_bignum2(dh_client_pub);
+ packet_check_eom();
#ifdef DEBUG_KEXDH
fprintf(stderr, "dh_client_pub= ");
@@ -243,7 +244,8 @@ kexdh_server(Kex *kex)
#ifdef DEBUG_KEXDH
dump_digest("shared secret", kbuf, kout);
#endif
- shared_secret = BN_new();
+ if ((shared_secret = BN_new()) == NULL)
+ fatal("kexdh_server: BN_new failed");
BN_bin2bn(kbuf, kout, shared_secret);
memset(kbuf, 0, klen);
xfree(kbuf);
@@ -256,12 +258,12 @@ kexdh_server(Kex *kex)
kex->server_version_string,
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
buffer_ptr(&kex->my), buffer_len(&kex->my),
- (char *)server_host_key_blob, sbloblen,
+ server_host_key_blob, sbloblen,
dh_client_pub,
dh->pub_key,
shared_secret
);
- BN_free(dh_client_pub);
+ BN_clear_free(dh_client_pub);
/* save session id := H */
/* XXX hashlen depends on KEX */
@@ -279,9 +281,9 @@ kexdh_server(Kex *kex)
/* send server hostkey, DH pubkey 'f' and singed H */
packet_start(SSH2_MSG_KEXDH_REPLY);
- packet_put_string((char *)server_host_key_blob, sbloblen);
+ packet_put_string(server_host_key_blob, sbloblen);
packet_put_bignum2(dh->pub_key); /* f */
- packet_put_string((char *)signature, slen);
+ packet_put_string(signature, slen);
packet_send();
xfree(signature);
diff --git a/crypto/openssh/kexgex.c b/crypto/openssh/kexgex.c
index 44f2f5c..61896e6 100644
--- a/crypto/openssh/kexgex.c
+++ b/crypto/openssh/kexgex.c
@@ -24,7 +24,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: kexgex.c,v 1.5 2001/04/05 10:42:50 markus Exp $");
+RCSID("$OpenBSD: kexgex.c,v 1.20 2002/02/28 15:46:33 markus Exp $");
#include <openssl/bn.h>
@@ -39,13 +39,13 @@ RCSID("$OpenBSD: kexgex.c,v 1.5 2001/04/05 10:42:50 markus Exp $");
#include "ssh2.h"
#include "compat.h"
-u_char *
+static u_char *
kexgex_hash(
char *client_version_string,
char *server_version_string,
char *ckexinit, int ckexinitlen,
char *skexinit, int skexinitlen,
- char *serverhostkeyblob, int sbloblen,
+ u_char *serverhostkeyblob, int sbloblen,
int min, int wantbits, int max, BIGNUM *prime, BIGNUM *gen,
BIGNUM *client_dh_pub,
BIGNUM *server_dh_pub,
@@ -53,12 +53,12 @@ kexgex_hash(
{
Buffer b;
static u_char digest[EVP_MAX_MD_SIZE];
- EVP_MD *evp_md = EVP_sha1();
+ const EVP_MD *evp_md = EVP_sha1();
EVP_MD_CTX md;
buffer_init(&b);
- buffer_put_string(&b, client_version_string, strlen(client_version_string));
- buffer_put_string(&b, server_version_string, strlen(server_version_string));
+ buffer_put_cstring(&b, client_version_string);
+ buffer_put_cstring(&b, server_version_string);
/* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
buffer_put_int(&b, ckexinitlen+1);
@@ -92,14 +92,14 @@ kexgex_hash(
buffer_free(&b);
#ifdef DEBUG_KEXDH
- dump_digest("hash", digest, evp_md->md_size);
+ dump_digest("hash", digest, EVP_MD_size(evp_md));
#endif
return digest;
}
/* client */
-void
+static void
kexgex_client(Kex *kex)
{
BIGNUM *dh_server_pub = NULL, *shared_secret = NULL;
@@ -107,7 +107,7 @@ kexgex_client(Kex *kex)
Key *server_host_key;
u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
u_int klen, kout, slen, sbloblen;
- int dlen, plen, min, max, nbits;
+ int min, max, nbits;
DH *dh;
nbits = dh_estimate(kex->we_need * 8);
@@ -138,15 +138,15 @@ kexgex_client(Kex *kex)
packet_send();
debug("expecting SSH2_MSG_KEX_DH_GEX_GROUP");
- packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_GROUP);
+ packet_read_expect(SSH2_MSG_KEX_DH_GEX_GROUP);
if ((p = BN_new()) == NULL)
fatal("BN_new");
- packet_get_bignum2(p, &dlen);
+ packet_get_bignum2(p);
if ((g = BN_new()) == NULL)
fatal("BN_new");
- packet_get_bignum2(g, &dlen);
- packet_done();
+ packet_get_bignum2(g);
+ packet_check_eom();
if (BN_num_bits(p) < min || BN_num_bits(p) > max)
fatal("DH_GEX group out of range: %d !< %d !< %d",
@@ -169,23 +169,24 @@ kexgex_client(Kex *kex)
packet_send();
debug("expecting SSH2_MSG_KEX_DH_GEX_REPLY");
- packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_REPLY);
+ packet_read_expect(SSH2_MSG_KEX_DH_GEX_REPLY);
/* key, cert */
server_host_key_blob = packet_get_string(&sbloblen);
server_host_key = key_from_blob(server_host_key_blob, sbloblen);
if (server_host_key == NULL)
fatal("cannot decode server_host_key_blob");
-
- if (kex->check_host_key == NULL)
- fatal("cannot check server_host_key");
- kex->check_host_key(server_host_key);
+ if (server_host_key->type != kex->hostkey_type)
+ fatal("type mismatch for decoded server_host_key_blob");
+ if (kex->verify_host_key == NULL)
+ fatal("cannot verify server_host_key");
+ if (kex->verify_host_key(server_host_key) == -1)
+ fatal("server_host_key verification failed");
/* DH paramter f, server public DH key */
- dh_server_pub = BN_new();
- if (dh_server_pub == NULL)
+ if ((dh_server_pub = BN_new()) == NULL)
fatal("dh_server_pub == NULL");
- packet_get_bignum2(dh_server_pub, &dlen);
+ packet_get_bignum2(dh_server_pub);
#ifdef DEBUG_KEXDH
fprintf(stderr, "dh_server_pub= ");
@@ -196,7 +197,7 @@ kexgex_client(Kex *kex)
/* signed H */
signature = packet_get_string(&slen);
- packet_done();
+ packet_check_eom();
if (!dh_pub_is_valid(dh, dh_server_pub))
packet_disconnect("bad server public DH value");
@@ -207,7 +208,8 @@ kexgex_client(Kex *kex)
#ifdef DEBUG_KEXDH
dump_digest("shared secret", kbuf, kout);
#endif
- shared_secret = BN_new();
+ if ((shared_secret = BN_new()) == NULL)
+ fatal("kexgex_client: BN_new failed");
BN_bin2bn(kbuf, kout, shared_secret);
memset(kbuf, 0, klen);
xfree(kbuf);
@@ -231,9 +233,9 @@ kexgex_client(Kex *kex)
/* have keys, free DH */
DH_free(dh);
xfree(server_host_key_blob);
- BN_free(dh_server_pub);
+ BN_clear_free(dh_server_pub);
- if (key_verify(server_host_key, (u_char *)signature, slen, hash, 20) != 1)
+ if (key_verify(server_host_key, signature, slen, hash, 20) != 1)
fatal("key_verify failed for server_host_key");
key_free(server_host_key);
xfree(signature);
@@ -252,15 +254,15 @@ kexgex_client(Kex *kex)
/* server */
-void
+static void
kexgex_server(Kex *kex)
{
BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
Key *server_host_key;
DH *dh = dh;
u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
- u_int sbloblen, klen, kout;
- int min = -1, max = -1, nbits = -1, type, plen, dlen, slen;
+ u_int sbloblen, klen, kout, slen;
+ int min = -1, max = -1, nbits = -1, type;
if (kex->load_host_key == NULL)
fatal("Cannot load hostkey");
@@ -268,8 +270,8 @@ kexgex_server(Kex *kex)
if (server_host_key == NULL)
fatal("Unsupported hostkey type %d", kex->hostkey_type);
- type = packet_read(&plen);
- switch(type){
+ type = packet_read();
+ switch (type) {
case SSH2_MSG_KEX_DH_GEX_REQUEST:
debug("SSH2_MSG_KEX_DH_GEX_REQUEST received");
min = packet_get_int();
@@ -288,7 +290,7 @@ kexgex_server(Kex *kex)
default:
fatal("protocol error during kex, no DH_GEX_REQUEST: %d", type);
}
- packet_done();
+ packet_check_eom();
if (max < min || nbits < min || max < nbits)
fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d",
@@ -311,13 +313,13 @@ kexgex_server(Kex *kex)
dh_gen_key(dh, kex->we_need * 8);
debug("expecting SSH2_MSG_KEX_DH_GEX_INIT");
- packet_read_expect(&plen, SSH2_MSG_KEX_DH_GEX_INIT);
+ packet_read_expect(SSH2_MSG_KEX_DH_GEX_INIT);
/* key, cert */
- dh_client_pub = BN_new();
- if (dh_client_pub == NULL)
+ if ((dh_client_pub = BN_new()) == NULL)
fatal("dh_client_pub == NULL");
- packet_get_bignum2(dh_client_pub, &dlen);
+ packet_get_bignum2(dh_client_pub);
+ packet_check_eom();
#ifdef DEBUG_KEXDH
fprintf(stderr, "dh_client_pub= ");
@@ -341,7 +343,8 @@ kexgex_server(Kex *kex)
#ifdef DEBUG_KEXDH
dump_digest("shared secret", kbuf, kout);
#endif
- shared_secret = BN_new();
+ if ((shared_secret = BN_new()) == NULL)
+ fatal("kexgex_server: BN_new failed");
BN_bin2bn(kbuf, kout, shared_secret);
memset(kbuf, 0, klen);
xfree(kbuf);
@@ -357,14 +360,14 @@ kexgex_server(Kex *kex)
kex->server_version_string,
buffer_ptr(&kex->peer), buffer_len(&kex->peer),
buffer_ptr(&kex->my), buffer_len(&kex->my),
- (char *)server_host_key_blob, sbloblen,
+ server_host_key_blob, sbloblen,
min, nbits, max,
dh->p, dh->g,
dh_client_pub,
dh->pub_key,
shared_secret
);
- BN_free(dh_client_pub);
+ BN_clear_free(dh_client_pub);
/* save session id := H */
/* XXX hashlen depends on KEX */
@@ -383,9 +386,9 @@ kexgex_server(Kex *kex)
/* send server hostkey, DH pubkey 'f' and singed H */
debug("SSH2_MSG_KEX_DH_GEX_REPLY sent");
packet_start(SSH2_MSG_KEX_DH_GEX_REPLY);
- packet_put_string((char *)server_host_key_blob, sbloblen);
+ packet_put_string(server_host_key_blob, sbloblen);
packet_put_bignum2(dh->pub_key); /* f */
- packet_put_string((char *)signature, slen);
+ packet_put_string(signature, slen);
packet_send();
xfree(signature);
xfree(server_host_key_blob);
diff --git a/crypto/openssh/key.h b/crypto/openssh/key.h
index cee31c3..a225773 100644
--- a/crypto/openssh/key.h
+++ b/crypto/openssh/key.h
@@ -1,7 +1,7 @@
-/* $OpenBSD: key.h,v 1.12 2001/04/17 10:53:24 markus Exp $ */
+/* $OpenBSD: key.h,v 1.18 2002/02/24 19:14:59 markus Exp $ */
/*
- * Copyright (c) 2000 Markus Friedl. All rights reserved.
+ * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -44,41 +44,37 @@ enum fp_rep {
SSH_FP_HEX,
SSH_FP_BUBBLEBABBLE
};
+
+/* key is stored in external hardware */
+#define KEY_FLAG_EXT 0x0001
+
struct Key {
- int type;
+ int type;
+ int flags;
RSA *rsa;
DSA *dsa;
};
-Key *key_new(int type);
-Key *key_new_private(int type);
-void key_free(Key *k);
-int key_equal(Key *a, Key *b);
-char *key_fingerprint(Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep);
-char *key_type(Key *k);
-int key_write(Key *key, FILE *f);
-int key_read(Key *key, char **cpp);
-u_int key_size(Key *k);
-
-Key *key_generate(int type, u_int bits);
-Key *key_from_private(Key *k);
-int key_type_from_name(char *name);
+Key *key_new(int);
+Key *key_new_private(int);
+void key_free(Key *);
+int key_equal(Key *, Key *);
+char *key_fingerprint(Key *, enum fp_type, enum fp_rep);
+char *key_type(Key *);
+int key_write(Key *, FILE *);
+int key_read(Key *, char **);
+u_int key_size(Key *);
-Key *key_from_blob(char *blob, int blen);
-int key_to_blob(Key *key, u_char **blobp, u_int *lenp);
-char *key_ssh_name(Key *k);
-int key_names_valid2(const char *names);
+Key *key_generate(int, u_int);
+Key *key_from_private(Key *);
+int key_type_from_name(char *);
-int
-key_sign(
- Key *key,
- u_char **sigp, int *lenp,
- u_char *data, int datalen);
+Key *key_from_blob(u_char *, int);
+int key_to_blob(Key *, u_char **, u_int *);
+char *key_ssh_name(Key *);
+int key_names_valid2(const char *);
-int
-key_verify(
- Key *key,
- u_char *signature, int signaturelen,
- u_char *data, int datalen);
+int key_sign(Key *, u_char **, u_int *, u_char *, u_int);
+int key_verify(Key *, u_char *, u_int, u_char *, u_int);
#endif
diff --git a/crypto/openssh/lib/Makefile b/crypto/openssh/lib/Makefile
index fbcd66f..369cf90 100644
--- a/crypto/openssh/lib/Makefile
+++ b/crypto/openssh/lib/Makefile
@@ -1,15 +1,17 @@
-# $OpenBSD: Makefile,v 1.22 2001/04/03 19:53:30 markus Exp $
+# $OpenBSD: Makefile,v 1.31 2002/02/22 12:20:34 markus Exp $
.PATH: ${.CURDIR}/..
LIB= ssh
SRCS= authfd.c authfile.c bufaux.c buffer.c canohost.c channels.c \
- cipher.c compat.c compress.c crc32.c deattack.c \
+ cipher.c compat.c compress.c crc32.c deattack.c fatal.c \
hostfile.c log.c match.c mpaux.c nchan.c packet.c readpass.c \
rsa.c tildexpand.c ttymodes.c uidswap.c xmalloc.c atomicio.c \
key.c dispatch.c kex.c mac.c uuencode.c misc.c \
- cli.c rijndael.c ssh-dss.c ssh-rsa.c dh.c kexdh.c kexgex.c
+ rijndael.c ssh-dss.c ssh-rsa.c dh.c kexdh.c kexgex.c \
+ scard.c
+DEBUGLIBS= no
NOPROFILE= yes
NOPIC= yes
@@ -26,4 +28,8 @@ SRCS+= radix.c
.endif # AFS
.endif # KERBEROS
+.if (${KERBEROS5:L} == "yes")
+CFLAGS+= -DKRB5 -I${DESTDIR}/usr/include/kerberosV
+.endif # KERBEROS5
+
.include <bsd.lib.mk>
diff --git a/crypto/openssh/log.c b/crypto/openssh/log.c
index 34b4eb9..887045f 100644
--- a/crypto/openssh/log.c
+++ b/crypto/openssh/log.c
@@ -34,7 +34,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: log.c,v 1.17 2001/03/04 17:42:28 millert Exp $");
+RCSID("$OpenBSD: log.c,v 1.22 2002/02/22 12:20:34 markus Exp $");
#include "log.h"
#include "xmalloc.h"
@@ -65,7 +65,7 @@ static struct {
{ "LOCAL5", SYSLOG_FACILITY_LOCAL5 },
{ "LOCAL6", SYSLOG_FACILITY_LOCAL6 },
{ "LOCAL7", SYSLOG_FACILITY_LOCAL7 },
- { NULL, 0 }
+ { NULL, SYSLOG_FACILITY_NOT_SET }
};
static struct {
@@ -82,7 +82,7 @@ static struct {
{ "DEBUG1", SYSLOG_LEVEL_DEBUG1 },
{ "DEBUG2", SYSLOG_LEVEL_DEBUG2 },
{ "DEBUG3", SYSLOG_LEVEL_DEBUG3 },
- { NULL, 0 }
+ { NULL, SYSLOG_LEVEL_NOT_SET }
};
SyslogFacility
@@ -93,7 +93,7 @@ log_facility_number(char *name)
for (i = 0; log_facilities[i].name; i++)
if (strcasecmp(log_facilities[i].name, name) == 0)
return log_facilities[i].val;
- return (SyslogFacility) - 1;
+ return SYSLOG_FACILITY_NOT_SET;
}
LogLevel
@@ -104,18 +104,7 @@ log_level_number(char *name)
for (i = 0; log_levels[i].name; i++)
if (strcasecmp(log_levels[i].name, name) == 0)
return log_levels[i].val;
- return (LogLevel) - 1;
-}
-/* Fatal messages. This function never returns. */
-
-void
-fatal(const char *fmt,...)
-{
- va_list args;
- va_start(args, fmt);
- do_log(SYSLOG_LEVEL_FATAL, fmt, args);
- va_end(args);
- fatal_cleanup();
+ return SYSLOG_LEVEL_NOT_SET;
}
/* Error messages that should be logged. */
@@ -237,7 +226,7 @@ fatal_cleanup(void)
for (cu = fatal_cleanups; cu; cu = next_cu) {
next_cu = cu->next;
debug("Calling cleanup 0x%lx(0x%lx)",
- (u_long) cu->proc, (u_long) cu->context);
+ (u_long) cu->proc, (u_long) cu->context);
(*cu->proc) (cu->context);
}
exit(255);
diff --git a/crypto/openssh/log.h b/crypto/openssh/log.h
index ad9fa3f..276ba05 100644
--- a/crypto/openssh/log.h
+++ b/crypto/openssh/log.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: log.h,v 1.2 2001/01/29 01:58:16 niklas Exp $ */
+/* $OpenBSD: log.h,v 1.6 2002/02/22 12:20:34 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -27,7 +27,8 @@ typedef enum {
SYSLOG_FACILITY_LOCAL4,
SYSLOG_FACILITY_LOCAL5,
SYSLOG_FACILITY_LOCAL6,
- SYSLOG_FACILITY_LOCAL7
+ SYSLOG_FACILITY_LOCAL7,
+ SYSLOG_FACILITY_NOT_SET = -1,
} SyslogFacility;
typedef enum {
@@ -38,38 +39,27 @@ typedef enum {
SYSLOG_LEVEL_VERBOSE,
SYSLOG_LEVEL_DEBUG1,
SYSLOG_LEVEL_DEBUG2,
- SYSLOG_LEVEL_DEBUG3
+ SYSLOG_LEVEL_DEBUG3,
+ SYSLOG_LEVEL_NOT_SET = -1,
} LogLevel;
-/* Initializes logging. */
-void log_init(char *av0, LogLevel level, SyslogFacility facility, int on_stderr);
-/* Logging implementation, depending on server or client */
-void do_log(LogLevel level, const char *fmt, va_list args);
+void log_init(char *, LogLevel, SyslogFacility, int);
-/* name to facility/level */
-SyslogFacility log_facility_number(char *name);
-LogLevel log_level_number(char *name);
+SyslogFacility log_facility_number(char *);
+LogLevel log_level_number(char *);
-/* Output a message to syslog or stderr */
-void fatal(const char *fmt,...) __attribute__((format(printf, 1, 2)));
-void error(const char *fmt,...) __attribute__((format(printf, 1, 2)));
-void log(const char *fmt,...) __attribute__((format(printf, 1, 2)));
-void verbose(const char *fmt,...) __attribute__((format(printf, 1, 2)));
-void debug(const char *fmt,...) __attribute__((format(printf, 1, 2)));
-void debug2(const char *fmt,...) __attribute__((format(printf, 1, 2)));
-void debug3(const char *fmt,...) __attribute__((format(printf, 1, 2)));
+void fatal(const char *, ...) __attribute__((format(printf, 1, 2)));
+void error(const char *, ...) __attribute__((format(printf, 1, 2)));
+void log(const char *, ...) __attribute__((format(printf, 1, 2)));
+void verbose(const char *, ...) __attribute__((format(printf, 1, 2)));
+void debug(const char *, ...) __attribute__((format(printf, 1, 2)));
+void debug2(const char *, ...) __attribute__((format(printf, 1, 2)));
+void debug3(const char *, ...) __attribute__((format(printf, 1, 2)));
-/* same as fatal() but w/o logging */
-void fatal_cleanup(void);
+void fatal_cleanup(void);
+void fatal_add_cleanup(void (*) (void *), void *);
+void fatal_remove_cleanup(void (*) (void *), void *);
-/*
- * Registers a cleanup function to be called by fatal()/fatal_cleanup()
- * before exiting. It is permissible to call fatal_remove_cleanup for the
- * function itself from the function.
- */
-void fatal_add_cleanup(void (*proc) (void *context), void *context);
-
-/* Removes a cleanup function to be called at fatal(). */
-void fatal_remove_cleanup(void (*proc) (void *context), void *context);
+void do_log(LogLevel, const char *, va_list);
#endif
diff --git a/crypto/openssh/mac.c b/crypto/openssh/mac.c
index e8b4267..b250af2 100644
--- a/crypto/openssh/mac.c
+++ b/crypto/openssh/mac.c
@@ -23,7 +23,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: mac.c,v 1.2 2001/04/05 10:42:51 markus Exp $");
+RCSID("$OpenBSD: mac.c,v 1.4 2002/01/25 22:07:40 markus Exp $");
#include <openssl/hmac.h>
@@ -56,7 +56,7 @@ mac_init(Mac *mac, char *name)
if (strcmp(name, macs[i].name) == 0) {
if (mac != NULL) {
mac->md = (*macs[i].mdfunc)();
- mac->key_len = mac->mac_len = mac->md->md_size;
+ mac->key_len = mac->mac_len = EVP_MD_size(mac->md);
if (macs[i].truncatebits != 0)
mac->mac_len = macs[i].truncatebits/8;
}
@@ -99,7 +99,7 @@ mac_valid(const char *names)
return (0);
maclist = cp = xstrdup(names);
for ((p = strsep(&cp, MAC_SEP)); p && *p != '\0';
- (p = strsep(&cp, MAC_SEP))) {
+ (p = strsep(&cp, MAC_SEP))) {
if (mac_init(NULL, p) < 0) {
debug("bad mac %s [%s]", p, names);
xfree(maclist);
diff --git a/crypto/openssh/mac.h b/crypto/openssh/mac.h
index 6173eaa..43b485d 100644
--- a/crypto/openssh/mac.h
+++ b/crypto/openssh/mac.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mac.h,v 1.1 2001/02/11 12:59:24 markus Exp $ */
+/* $OpenBSD: mac.h,v 1.3 2001/06/26 17:27:24 markus Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@@ -23,6 +23,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-int mac_valid(const char *names);
-int mac_init(Mac *mac, char *name);
-u_char *mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen);
+int mac_valid(const char *);
+int mac_init(Mac *, char *);
+u_char *mac_compute(Mac *, u_int32_t, u_char *, int);
diff --git a/crypto/openssh/match.c b/crypto/openssh/match.c
index ebb562a..3ddb627 100644
--- a/crypto/openssh/match.c
+++ b/crypto/openssh/match.c
@@ -35,7 +35,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: match.c,v 1.12 2001/03/10 17:51:04 markus Exp $");
+RCSID("$OpenBSD: match.c,v 1.19 2002/03/01 13:12:10 markus Exp $");
#include "match.h"
#include "xmalloc.h"
@@ -104,14 +104,15 @@ match_pattern(const char *s, const char *pattern)
}
/*
- * Tries to match the host name (which must be in all lowercase) against the
+ * Tries to match the string against the
* comma-separated sequence of subpatterns (each possibly preceded by ! to
* indicate negation). Returns -1 if negation matches, 1 if there is
* a positive match, 0 if there is no match at all.
*/
int
-match_hostname(const char *host, const char *pattern, u_int len)
+match_pattern_list(const char *string, const char *pattern, u_int len,
+ int dolower)
{
char sub[1024];
int negated;
@@ -132,9 +133,10 @@ match_hostname(const char *host, const char *pattern, u_int len)
* subpattern to lowercase.
*/
for (subi = 0;
- i < len && subi < sizeof(sub) - 1 && pattern[i] != ',';
- subi++, i++)
- sub[subi] = isupper(pattern[i]) ? tolower(pattern[i]) : pattern[i];
+ i < len && subi < sizeof(sub) - 1 && pattern[i] != ',';
+ subi++, i++)
+ sub[subi] = dolower && isupper(pattern[i]) ?
+ tolower(pattern[i]) : pattern[i];
/* If subpattern too long, return failure (no match). */
if (subi >= sizeof(sub) - 1)
return 0;
@@ -146,8 +148,8 @@ match_hostname(const char *host, const char *pattern, u_int len)
/* Null-terminate the subpattern. */
sub[subi] = '\0';
- /* Try to match the subpattern against the host name. */
- if (match_pattern(host, sub)) {
+ /* Try to match the subpattern against the string. */
+ if (match_pattern(string, sub)) {
if (negated)
return -1; /* Negative */
else
@@ -162,8 +164,69 @@ match_hostname(const char *host, const char *pattern, u_int len)
return got_positive;
}
+/*
+ * Tries to match the host name (which must be in all lowercase) against the
+ * comma-separated sequence of subpatterns (each possibly preceded by ! to
+ * indicate negation). Returns -1 if negation matches, 1 if there is
+ * a positive match, 0 if there is no match at all.
+ */
+int
+match_hostname(const char *host, const char *pattern, u_int len)
+{
+ return match_pattern_list(host, pattern, len, 1);
+}
-#define MAX_PROP 20
+/*
+ * returns 0 if we get a negative match for the hostname or the ip
+ * or if we get no match at all. returns 1 otherwise.
+ */
+int
+match_host_and_ip(const char *host, const char *ipaddr,
+ const char *patterns)
+{
+ int mhost, mip;
+
+ /* negative ipaddr match */
+ if ((mip = match_hostname(ipaddr, patterns, strlen(patterns))) == -1)
+ return 0;
+ /* negative hostname match */
+ if ((mhost = match_hostname(host, patterns, strlen(patterns))) == -1)
+ return 0;
+ /* no match at all */
+ if (mhost == 0 && mip == 0)
+ return 0;
+ return 1;
+}
+
+/*
+ * match user, user@host_or_ip, user@host_or_ip_list against pattern
+ */
+int
+match_user(const char *user, const char *host, const char *ipaddr,
+ const char *pattern)
+{
+ char *p, *pat;
+ int ret;
+
+ if ((p = strchr(pattern,'@')) == NULL)
+ return match_pattern(user, pattern);
+
+ pat = xstrdup(pattern);
+ p = strchr(pat, '@');
+ *p++ = '\0';
+
+ if ((ret = match_pattern(user, pat)) == 1)
+ ret = match_host_and_ip(host, ipaddr, p);
+ xfree(pat);
+
+ return ret;
+}
+
+/*
+ * Returns first item from client-list that is also supported by server-list,
+ * caller must xfree() returned string.
+ */
+#define MAX_PROP 40
#define SEP ","
char *
match_list(const char *client, const char *server, u_int *next)
@@ -176,7 +239,7 @@ match_list(const char *client, const char *server, u_int *next)
s = sp = xstrdup(server);
for ((p = strsep(&sp, SEP)), i=0; p && *p != '\0';
- (p = strsep(&sp, SEP)), i++) {
+ (p = strsep(&sp, SEP)), i++) {
if (i < MAX_PROP)
sproposals[i] = p;
else
@@ -185,7 +248,7 @@ match_list(const char *client, const char *server, u_int *next)
nproposals = i;
for ((p = strsep(&cp, SEP)), i=0; p && *p != '\0';
- (p = strsep(&cp, SEP)), i++) {
+ (p = strsep(&cp, SEP)), i++) {
for (j = 0; j < nproposals; j++) {
if (strcmp(p, sproposals[j]) == 0) {
ret = xstrdup(p);
diff --git a/crypto/openssh/match.h b/crypto/openssh/match.h
index 09c9311..a0764e0 100644
--- a/crypto/openssh/match.h
+++ b/crypto/openssh/match.h
@@ -1,11 +1,9 @@
-/* $OpenBSD: match.h,v 1.7 2001/03/10 17:51:04 markus Exp $ */
+/* $OpenBSD: match.h,v 1.12 2002/03/01 13:12:10 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
- * This file contains various auxiliary functions related to multiple
- * precision integers.
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
@@ -16,24 +14,11 @@
#ifndef MATCH_H
#define MATCH_H
-/*
- * Returns true if the given string matches the pattern (which may contain ?
- * and * as wildcards), and zero if it does not match.
- */
-int match_pattern(const char *s, const char *pattern);
-
-/*
- * Tries to match the host name (which must be in all lowercase) against the
- * comma-separated sequence of subpatterns (each possibly preceded by ! to
- * indicate negation). Returns -1 if negation matches, 1 if there is
- * a positive match, 0 if there is no match at all.
- */
-int match_hostname(const char *host, const char *pattern, u_int len);
-
-/*
- * Returns first item from client-list that is also supported by server-list,
- * caller must xfree() returned string.
- */
-char *match_list(const char *client, const char *server, u_int *next);
+int match_pattern(const char *, const char *);
+int match_pattern_list(const char *, const char *, u_int, int);
+int match_hostname(const char *, const char *, u_int);
+int match_host_and_ip(const char *, const char *, const char *);
+int match_user(const char *, const char *, const char *, const char *);
+char *match_list(const char *, const char *, u_int *);
#endif
diff --git a/crypto/openssh/misc.c b/crypto/openssh/misc.c
index b5c0fd1..10f9173 100644
--- a/crypto/openssh/misc.c
+++ b/crypto/openssh/misc.c
@@ -1,5 +1,3 @@
-/* $OpenBSD: misc.c,v 1.5 2001/04/12 20:09:37 stevesk Exp $ */
-
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -25,18 +23,19 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: misc.c,v 1.5 2001/04/12 20:09:37 stevesk Exp $");
+RCSID("$OpenBSD: misc.c,v 1.19 2002/03/04 17:27:39 stevesk Exp $");
#include "misc.h"
#include "log.h"
#include "xmalloc.h"
+/* remove newline at end of string */
char *
chop(char *s)
{
char *t = s;
while (*t) {
- if(*t == '\n' || *t == '\r') {
+ if (*t == '\n' || *t == '\r') {
*t = '\0';
return s;
}
@@ -46,30 +45,75 @@ chop(char *s)
}
+/* set/unset filedescriptor to non-blocking */
void
set_nonblock(int fd)
{
int val;
+
val = fcntl(fd, F_GETFL, 0);
if (val < 0) {
error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno));
return;
}
if (val & O_NONBLOCK) {
- debug("fd %d IS O_NONBLOCK", fd);
+ debug2("fd %d is O_NONBLOCK", fd);
return;
}
debug("fd %d setting O_NONBLOCK", fd);
val |= O_NONBLOCK;
if (fcntl(fd, F_SETFL, val) == -1)
- if (errno != ENODEV)
- error("fcntl(%d, F_SETFL, O_NONBLOCK): %s",
- fd, strerror(errno));
+ debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s",
+ fd, strerror(errno));
+}
+
+void
+unset_nonblock(int fd)
+{
+ int val;
+
+ val = fcntl(fd, F_GETFL, 0);
+ if (val < 0) {
+ error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno));
+ return;
+ }
+ if (!(val & O_NONBLOCK)) {
+ debug2("fd %d is not O_NONBLOCK", fd);
+ return;
+ }
+ debug("fd %d clearing O_NONBLOCK", fd);
+ val &= ~O_NONBLOCK;
+ if (fcntl(fd, F_SETFL, val) == -1)
+ debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s",
+ fd, strerror(errno));
+}
+
+/* disable nagle on socket */
+void
+set_nodelay(int fd)
+{
+ int opt;
+ socklen_t optlen;
+
+ optlen = sizeof opt;
+ if (getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen) == -1) {
+ error("getsockopt TCP_NODELAY: %.100s", strerror(errno));
+ return;
+ }
+ if (opt == 1) {
+ debug2("fd %d is TCP_NODELAY", fd);
+ return;
+ }
+ opt = 1;
+ debug("fd %d setting TCP_NODELAY", fd);
+ if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof opt) == -1)
+ error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
}
/* Characters considered whitespace in strsep calls. */
#define WHITESPACE " \t\r\n"
+/* return next token in configuration line */
char *
strdelim(char **s)
{
@@ -108,13 +152,21 @@ pwcopy(struct passwd *pw)
copy->pw_gecos = xstrdup(pw->pw_gecos);
copy->pw_uid = pw->pw_uid;
copy->pw_gid = pw->pw_gid;
+ copy->pw_expire = pw->pw_expire;
+ copy->pw_change = pw->pw_change;
copy->pw_class = xstrdup(pw->pw_class);
copy->pw_dir = xstrdup(pw->pw_dir);
copy->pw_shell = xstrdup(pw->pw_shell);
return copy;
}
-int a2port(const char *s)
+/*
+ * Convert ASCII string to TCP/IP port number.
+ * Port must be >0 and <=65535.
+ * Return 0 if invalid.
+ */
+int
+a2port(const char *s)
{
long port;
char *endp;
@@ -128,3 +180,140 @@ int a2port(const char *s)
return port;
}
+
+#define SECONDS 1
+#define MINUTES (SECONDS * 60)
+#define HOURS (MINUTES * 60)
+#define DAYS (HOURS * 24)
+#define WEEKS (DAYS * 7)
+
+/*
+ * Convert a time string into seconds; format is
+ * a sequence of:
+ * time[qualifier]
+ *
+ * Valid time qualifiers are:
+ * <none> seconds
+ * s|S seconds
+ * m|M minutes
+ * h|H hours
+ * d|D days
+ * w|W weeks
+ *
+ * Examples:
+ * 90m 90 minutes
+ * 1h30m 90 minutes
+ * 2d 2 days
+ * 1w 1 week
+ *
+ * Return -1 if time string is invalid.
+ */
+long
+convtime(const char *s)
+{
+ long total, secs;
+ const char *p;
+ char *endp;
+
+ errno = 0;
+ total = 0;
+ p = s;
+
+ if (p == NULL || *p == '\0')
+ return -1;
+
+ while (*p) {
+ secs = strtol(p, &endp, 10);
+ if (p == endp ||
+ (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) ||
+ secs < 0)
+ return -1;
+
+ switch (*endp++) {
+ case '\0':
+ endp--;
+ case 's':
+ case 'S':
+ break;
+ case 'm':
+ case 'M':
+ secs *= MINUTES;
+ break;
+ case 'h':
+ case 'H':
+ secs *= HOURS;
+ break;
+ case 'd':
+ case 'D':
+ secs *= DAYS;
+ break;
+ case 'w':
+ case 'W':
+ secs *= WEEKS;
+ break;
+ default:
+ return -1;
+ }
+ total += secs;
+ if (total < 0)
+ return -1;
+ p = endp;
+ }
+
+ return total;
+}
+
+char *
+cleanhostname(char *host)
+{
+ if (*host == '[' && host[strlen(host) - 1] == ']') {
+ host[strlen(host) - 1] = '\0';
+ return (host + 1);
+ } else
+ return host;
+}
+
+char *
+colon(char *cp)
+{
+ int flag = 0;
+
+ if (*cp == ':') /* Leading colon is part of file name. */
+ return (0);
+ if (*cp == '[')
+ flag = 1;
+
+ for (; *cp; ++cp) {
+ if (*cp == '@' && *(cp+1) == '[')
+ flag = 1;
+ if (*cp == ']' && *(cp+1) == ':' && flag)
+ return (cp+1);
+ if (*cp == ':' && !flag)
+ return (cp);
+ if (*cp == '/')
+ return (0);
+ }
+ return (0);
+}
+
+/* function to assist building execv() arguments */
+void
+addargs(arglist *args, char *fmt, ...)
+{
+ va_list ap;
+ char buf[1024];
+
+ va_start(ap, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+
+ if (args->list == NULL) {
+ args->nalloc = 32;
+ args->num = 0;
+ } else if (args->num+2 >= args->nalloc)
+ args->nalloc *= 2;
+
+ args->list = xrealloc(args->list, args->nalloc * sizeof(char *));
+ args->list[args->num++] = xstrdup(buf);
+ args->list[args->num] = NULL;
+}
diff --git a/crypto/openssh/misc.h b/crypto/openssh/misc.h
index 9cd4ac1..d28b865 100644
--- a/crypto/openssh/misc.h
+++ b/crypto/openssh/misc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.h,v 1.4 2001/04/12 20:09:36 stevesk Exp $ */
+/* $OpenBSD: misc.h,v 1.11 2002/01/24 21:09:25 stevesk Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -11,20 +11,23 @@
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*/
-/* remove newline at end of string */
-char *chop(char *s);
-/* return next token in configuration line */
-char *strdelim(char **s);
+char *chop(char *);
+char *strdelim(char **);
+void set_nonblock(int);
+void unset_nonblock(int);
+void set_nodelay(int);
+int a2port(const char *);
+char *cleanhostname(char *);
+char *colon(char *);
+long convtime(const char *);
-/* set filedescriptor to non-blocking */
-void set_nonblock(int fd);
+struct passwd *pwcopy(struct passwd *);
-struct passwd * pwcopy(struct passwd *pw);
-
-/*
- * Convert ASCII string to TCP/IP port number.
- * Port must be >0 and <=65535.
- * Return 0 if invalid.
- */
-int a2port(const char *s);
+typedef struct arglist arglist;
+struct arglist {
+ char **list;
+ int num;
+ int nalloc;
+};
+void addargs(arglist *, char *, ...) __attribute__((format(printf, 2, 3)));
diff --git a/crypto/openssh/mpaux.h b/crypto/openssh/mpaux.h
index b3f15e4..2a312f5 100644
--- a/crypto/openssh/mpaux.h
+++ b/crypto/openssh/mpaux.h
@@ -1,3 +1,5 @@
+/* $OpenBSD: mpaux.h,v 1.12 2002/03/04 17:27:39 stevesk Exp $ */
+
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -12,20 +14,9 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-/* RCSID("$OpenBSD: mpaux.h,v 1.9 2000/12/19 23:17:57 markus Exp $"); */
-
#ifndef MPAUX_H
#define MPAUX_H
-/*
- * Computes a 16-byte session id in the global variable session_id. The
- * session id is computed by concatenating the linearized, msb first
- * representations of host_key_n, session_key_n, and the cookie.
- */
-void
-compute_session_id(u_char session_id[16],
- u_char cookie[8],
- BIGNUM * host_key_n,
- BIGNUM * session_key_n);
+void compute_session_id(u_char[16], u_char[8], BIGNUM *, BIGNUM *);
#endif /* MPAUX_H */
diff --git a/crypto/openssh/myproposal.h b/crypto/openssh/myproposal.h
index 4a9a363..1caf04a 100644
--- a/crypto/openssh/myproposal.h
+++ b/crypto/openssh/myproposal.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: myproposal.h,v 1.12 2001/03/05 15:56:16 deraadt Exp $ */
+/* $OpenBSD: myproposal.h,v 1.13 2002/01/21 22:30:12 markus Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -27,9 +27,7 @@
#define KEX_DEFAULT_PK_ALG "ssh-rsa,ssh-dss"
#define KEX_DEFAULT_ENCRYPT \
"aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour," \
- "aes192-cbc,aes256-cbc," \
- "rijndael128-cbc,rijndael192-cbc,rijndael256-cbc," \
- "rijndael-cbc@lysator.liu.se"
+ "aes192-cbc,aes256-cbc"
#define KEX_DEFAULT_MAC \
"hmac-md5,hmac-sha1,hmac-ripemd160," \
"hmac-ripemd160@openssh.com," \
diff --git a/crypto/openssh/nchan.c b/crypto/openssh/nchan.c
index eb96501..8153abb 100644
--- a/crypto/openssh/nchan.c
+++ b/crypto/openssh/nchan.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999 Markus Friedl. All rights reserved.
+ * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,40 +23,79 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: nchan.c,v 1.23 2001/02/28 08:54:55 markus Exp $");
+RCSID("$OpenBSD: nchan.c,v 1.44 2002/01/21 23:27:10 markus Exp $");
#include "ssh1.h"
#include "ssh2.h"
#include "buffer.h"
#include "packet.h"
#include "channels.h"
-#include "nchan.h"
#include "compat.h"
#include "log.h"
+/*
+ * SSH Protocol 1.5 aka New Channel Protocol
+ * Thanks to Martina, Axel and everyone who left Erlangen, leaving me bored.
+ * Written by Markus Friedl in October 1999
+ *
+ * Protocol versions 1.3 and 1.5 differ in the handshake protocol used for the
+ * tear down of channels:
+ *
+ * 1.3: strict request-ack-protocol:
+ * CLOSE ->
+ * <- CLOSE_CONFIRM
+ *
+ * 1.5: uses variations of:
+ * IEOF ->
+ * <- OCLOSE
+ * <- IEOF
+ * OCLOSE ->
+ * i.e. both sides have to close the channel
+ *
+ * 2.0: the EOF messages are optional
+ *
+ * See the debugging output from 'ssh -v' and 'sshd -d' of
+ * ssh-1.2.27 as an example.
+ *
+ */
+
/* functions manipulating channel states */
/*
* EVENTS update channel input/output states execute ACTIONS
*/
-/* events concerning the INPUT from socket for channel (istate) */
-chan_event_fn *chan_rcvd_oclose = NULL;
-chan_event_fn *chan_read_failed = NULL;
-chan_event_fn *chan_ibuf_empty = NULL;
-/* events concerning the OUTPUT from channel for socket (ostate) */
-chan_event_fn *chan_rcvd_ieof = NULL;
-chan_event_fn *chan_write_failed = NULL;
-chan_event_fn *chan_obuf_empty = NULL;
/*
* ACTIONS: should never update the channel states
*/
-static void chan_send_ieof1(Channel *c);
-static void chan_send_oclose1(Channel *c);
-static void chan_send_close2(Channel *c);
-static void chan_send_eof2(Channel *c);
+static void chan_send_ieof1(Channel *);
+static void chan_send_oclose1(Channel *);
+static void chan_send_close2(Channel *);
+static void chan_send_eof2(Channel *);
/* helper */
-static void chan_shutdown_write(Channel *c);
-static void chan_shutdown_read(Channel *c);
+static void chan_shutdown_write(Channel *);
+static void chan_shutdown_read(Channel *);
+
+static char *ostates[] = { "open", "drain", "wait_ieof", "closed" };
+static char *istates[] = { "open", "drain", "wait_oclose", "closed" };
+
+static void
+chan_set_istate(Channel *c, u_int next)
+{
+ if (c->istate > CHAN_INPUT_CLOSED || next > CHAN_INPUT_CLOSED)
+ fatal("chan_set_istate: bad state %d -> %d", c->istate, next);
+ debug("channel %d: input %s -> %s", c->self, istates[c->istate],
+ istates[next]);
+ c->istate = next;
+}
+static void
+chan_set_ostate(Channel *c, u_int next)
+{
+ if (c->ostate > CHAN_OUTPUT_CLOSED || next > CHAN_OUTPUT_CLOSED)
+ fatal("chan_set_ostate: bad state %d -> %d", c->ostate, next);
+ debug("channel %d: output %s -> %s", c->self, ostates[c->ostate],
+ ostates[next]);
+ c->ostate = next;
+}
/*
* SSH1 specific implementation of event functions
@@ -68,64 +107,61 @@ chan_rcvd_oclose1(Channel *c)
debug("channel %d: rcvd oclose", c->self);
switch (c->istate) {
case CHAN_INPUT_WAIT_OCLOSE:
- debug("channel %d: input wait_oclose -> closed", c->self);
- c->istate = CHAN_INPUT_CLOSED;
+ chan_set_istate(c, CHAN_INPUT_CLOSED);
break;
case CHAN_INPUT_OPEN:
- debug("channel %d: input open -> closed", c->self);
chan_shutdown_read(c);
chan_send_ieof1(c);
- c->istate = CHAN_INPUT_CLOSED;
+ chan_set_istate(c, CHAN_INPUT_CLOSED);
break;
case CHAN_INPUT_WAIT_DRAIN:
/* both local read_failed and remote write_failed */
- log("channel %d: input drain -> closed", c->self);
chan_send_ieof1(c);
- c->istate = CHAN_INPUT_CLOSED;
+ chan_set_istate(c, CHAN_INPUT_CLOSED);
break;
default:
- error("channel %d: protocol error: chan_rcvd_oclose for istate %d",
+ error("channel %d: protocol error: rcvd_oclose for istate %d",
c->self, c->istate);
return;
}
}
-static void
-chan_read_failed_12(Channel *c)
+void
+chan_read_failed(Channel *c)
{
debug("channel %d: read failed", c->self);
switch (c->istate) {
case CHAN_INPUT_OPEN:
- debug("channel %d: input open -> drain", c->self);
chan_shutdown_read(c);
- c->istate = CHAN_INPUT_WAIT_DRAIN;
- if (buffer_len(&c->input) == 0) {
- debug("channel %d: input: no drain shortcut", c->self);
- chan_ibuf_empty(c);
- }
+ chan_set_istate(c, CHAN_INPUT_WAIT_DRAIN);
break;
default:
- error("channel %d: internal error: we do not read, but chan_read_failed for istate %d",
+ error("channel %d: chan_read_failed for istate %d",
c->self, c->istate);
break;
}
}
-static void
-chan_ibuf_empty1(Channel *c)
+void
+chan_ibuf_empty(Channel *c)
{
debug("channel %d: ibuf empty", c->self);
if (buffer_len(&c->input)) {
- error("channel %d: internal error: chan_ibuf_empty for non empty buffer",
+ error("channel %d: chan_ibuf_empty for non empty buffer",
c->self);
return;
}
switch (c->istate) {
case CHAN_INPUT_WAIT_DRAIN:
- debug("channel %d: input drain -> wait_oclose", c->self);
- chan_send_ieof1(c);
- c->istate = CHAN_INPUT_WAIT_OCLOSE;
+ if (compat20) {
+ if (!(c->flags & CHAN_CLOSE_SENT))
+ chan_send_eof2(c);
+ chan_set_istate(c, CHAN_INPUT_CLOSED);
+ } else {
+ chan_send_ieof1(c);
+ chan_set_istate(c, CHAN_INPUT_WAIT_OCLOSE);
+ }
break;
default:
- error("channel %d: internal error: chan_ibuf_empty for istate %d",
+ error("channel %d: chan_ibuf_empty for istate %d",
c->self, c->istate);
break;
}
@@ -134,36 +170,15 @@ static void
chan_rcvd_ieof1(Channel *c)
{
debug("channel %d: rcvd ieof", c->self);
- if (c->type != SSH_CHANNEL_OPEN) {
- debug("channel %d: non-open", c->self);
- if (c->istate == CHAN_INPUT_OPEN) {
- debug("channel %d: non-open: input open -> wait_oclose", c->self);
- chan_shutdown_read(c);
- chan_send_ieof1(c);
- c->istate = CHAN_INPUT_WAIT_OCLOSE;
- } else {
- error("channel %d: istate %d != open", c->self, c->istate);
- }
- if (c->ostate == CHAN_OUTPUT_OPEN) {
- debug("channel %d: non-open: output open -> closed", c->self);
- chan_send_oclose1(c);
- c->ostate = CHAN_OUTPUT_CLOSED;
- } else {
- error("channel %d: ostate %d != open", c->self, c->ostate);
- }
- return;
- }
switch (c->ostate) {
case CHAN_OUTPUT_OPEN:
- debug("channel %d: output open -> drain", c->self);
- c->ostate = CHAN_OUTPUT_WAIT_DRAIN;
+ chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
break;
case CHAN_OUTPUT_WAIT_IEOF:
- debug("channel %d: output wait_ieof -> closed", c->self);
- c->ostate = CHAN_OUTPUT_CLOSED;
+ chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
break;
default:
- error("channel %d: protocol error: chan_rcvd_ieof for ostate %d",
+ error("channel %d: protocol error: rcvd_ieof for ostate %d",
c->self, c->ostate);
break;
}
@@ -174,38 +189,39 @@ chan_write_failed1(Channel *c)
debug("channel %d: write failed", c->self);
switch (c->ostate) {
case CHAN_OUTPUT_OPEN:
- debug("channel %d: output open -> wait_ieof", c->self);
+ chan_shutdown_write(c);
chan_send_oclose1(c);
- c->ostate = CHAN_OUTPUT_WAIT_IEOF;
+ chan_set_ostate(c, CHAN_OUTPUT_WAIT_IEOF);
break;
case CHAN_OUTPUT_WAIT_DRAIN:
- debug("channel %d: output wait_drain -> closed", c->self);
+ chan_shutdown_write(c);
chan_send_oclose1(c);
- c->ostate = CHAN_OUTPUT_CLOSED;
+ chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
break;
default:
- error("channel %d: internal error: chan_write_failed for ostate %d",
+ error("channel %d: chan_write_failed for ostate %d",
c->self, c->ostate);
break;
}
}
-static void
-chan_obuf_empty1(Channel *c)
+void
+chan_obuf_empty(Channel *c)
{
debug("channel %d: obuf empty", c->self);
if (buffer_len(&c->output)) {
- error("channel %d: internal error: chan_obuf_empty for non empty buffer",
+ error("channel %d: chan_obuf_empty for non empty buffer",
c->self);
return;
}
switch (c->ostate) {
case CHAN_OUTPUT_WAIT_DRAIN:
- debug("channel %d: output drain -> closed", c->self);
- chan_send_oclose1(c);
- c->ostate = CHAN_OUTPUT_CLOSED;
+ chan_shutdown_write(c);
+ if (!compat20)
+ chan_send_oclose1(c);
+ chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
break;
default:
- error("channel %d: internal error: chan_obuf_empty for ostate %d",
+ error("channel %d: internal error: obuf_empty for ostate %d",
c->self, c->ostate);
break;
}
@@ -222,7 +238,7 @@ chan_send_ieof1(Channel *c)
packet_send();
break;
default:
- error("channel %d: internal error: cannot send ieof for istate %d",
+ error("channel %d: cannot send ieof for istate %d",
c->self, c->istate);
break;
}
@@ -234,15 +250,14 @@ chan_send_oclose1(Channel *c)
switch (c->ostate) {
case CHAN_OUTPUT_OPEN:
case CHAN_OUTPUT_WAIT_DRAIN:
- chan_shutdown_write(c);
- buffer_consume(&c->output, buffer_len(&c->output));
+ buffer_clear(&c->output);
packet_start(SSH_MSG_CHANNEL_OUTPUT_CLOSE);
packet_put_int(c->remote_id);
packet_send();
break;
default:
- error("channel %d: internal error: cannot send oclose for ostate %d",
- c->self, c->ostate);
+ error("channel %d: cannot send oclose for ostate %d",
+ c->self, c->ostate);
break;
}
}
@@ -251,7 +266,7 @@ chan_send_oclose1(Channel *c)
* the same for SSH2
*/
static void
-chan_rcvd_oclose2(Channel *c)
+chan_rcvd_close2(Channel *c)
{
debug("channel %d: rcvd close", c->self);
if (c->flags & CHAN_CLOSE_RCVD)
@@ -259,59 +274,36 @@ chan_rcvd_oclose2(Channel *c)
c->flags |= CHAN_CLOSE_RCVD;
if (c->type == SSH_CHANNEL_LARVAL) {
/* tear down larval channels immediately */
- c->ostate = CHAN_OUTPUT_CLOSED;
- c->istate = CHAN_INPUT_CLOSED;
+ chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
+ chan_set_istate(c, CHAN_INPUT_CLOSED);
return;
}
switch (c->ostate) {
case CHAN_OUTPUT_OPEN:
- /* wait until a data from the channel is consumed if a CLOSE is received */
- debug("channel %d: output open -> drain", c->self);
- c->ostate = CHAN_OUTPUT_WAIT_DRAIN;
+ /*
+ * wait until a data from the channel is consumed if a CLOSE
+ * is received
+ */
+ chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
break;
}
switch (c->istate) {
case CHAN_INPUT_OPEN:
- debug("channel %d: input open -> closed", c->self);
chan_shutdown_read(c);
+ chan_set_istate(c, CHAN_INPUT_CLOSED);
break;
case CHAN_INPUT_WAIT_DRAIN:
- debug("channel %d: input drain -> closed", c->self);
chan_send_eof2(c);
- break;
- }
- c->istate = CHAN_INPUT_CLOSED;
-}
-static void
-chan_ibuf_empty2(Channel *c)
-{
- debug("channel %d: ibuf empty", c->self);
- if (buffer_len(&c->input)) {
- error("channel %d: internal error: chan_ibuf_empty for non empty buffer",
- c->self);
- return;
- }
- switch (c->istate) {
- case CHAN_INPUT_WAIT_DRAIN:
- debug("channel %d: input drain -> closed", c->self);
- if (!(c->flags & CHAN_CLOSE_SENT))
- chan_send_eof2(c);
- c->istate = CHAN_INPUT_CLOSED;
- break;
- default:
- error("channel %d: internal error: chan_ibuf_empty for istate %d",
- c->self, c->istate);
+ chan_set_istate(c, CHAN_INPUT_CLOSED);
break;
}
}
static void
-chan_rcvd_ieof2(Channel *c)
+chan_rcvd_eof2(Channel *c)
{
debug("channel %d: rcvd eof", c->self);
- if (c->ostate == CHAN_OUTPUT_OPEN) {
- debug("channel %d: output open -> drain", c->self);
- c->ostate = CHAN_OUTPUT_WAIT_DRAIN;
- }
+ if (c->ostate == CHAN_OUTPUT_OPEN)
+ chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
}
static void
chan_write_failed2(Channel *c)
@@ -319,38 +311,12 @@ chan_write_failed2(Channel *c)
debug("channel %d: write failed", c->self);
switch (c->ostate) {
case CHAN_OUTPUT_OPEN:
- debug("channel %d: output open -> closed", c->self);
- chan_shutdown_write(c); /* ?? */
- c->ostate = CHAN_OUTPUT_CLOSED;
- break;
- case CHAN_OUTPUT_WAIT_DRAIN:
- debug("channel %d: output drain -> closed", c->self);
- chan_shutdown_write(c);
- c->ostate = CHAN_OUTPUT_CLOSED;
- break;
- default:
- error("channel %d: internal error: chan_write_failed for ostate %d",
- c->self, c->ostate);
- break;
- }
-}
-static void
-chan_obuf_empty2(Channel *c)
-{
- debug("channel %d: obuf empty", c->self);
- if (buffer_len(&c->output)) {
- error("internal error: chan_obuf_empty %d for non empty buffer",
- c->self);
- return;
- }
- switch (c->ostate) {
case CHAN_OUTPUT_WAIT_DRAIN:
- debug("channel %d: output drain -> closed", c->self);
chan_shutdown_write(c);
- c->ostate = CHAN_OUTPUT_CLOSED;
+ chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
break;
default:
- error("channel %d: internal error: chan_obuf_empty for ostate %d",
+ error("channel %d: chan_write_failed for ostate %d",
c->self, c->ostate);
break;
}
@@ -366,7 +332,7 @@ chan_send_eof2(Channel *c)
packet_send();
break;
default:
- error("channel %d: internal error: cannot send eof for istate %d",
+ error("channel %d: cannot send eof for istate %d",
c->self, c->istate);
break;
}
@@ -377,10 +343,10 @@ chan_send_close2(Channel *c)
debug("channel %d: send close", c->self);
if (c->ostate != CHAN_OUTPUT_CLOSED ||
c->istate != CHAN_INPUT_CLOSED) {
- error("channel %d: internal error: cannot send close for istate/ostate %d/%d",
+ error("channel %d: cannot send close for istate/ostate %d/%d",
c->self, c->istate, c->ostate);
} else if (c->flags & CHAN_CLOSE_SENT) {
- error("channel %d: internal error: already sent close", c->self);
+ error("channel %d: already sent close", c->self);
} else {
packet_start(SSH2_MSG_CHANNEL_CLOSE);
packet_put_int(c->remote_id);
@@ -391,9 +357,47 @@ chan_send_close2(Channel *c)
/* shared */
+void
+chan_rcvd_ieof(Channel *c)
+{
+ if (compat20)
+ chan_rcvd_eof2(c);
+ else
+ chan_rcvd_ieof1(c);
+ if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
+ buffer_len(&c->output) == 0)
+ chan_obuf_empty(c);
+}
+void
+chan_rcvd_oclose(Channel *c)
+{
+ if (compat20)
+ chan_rcvd_close2(c);
+ else
+ chan_rcvd_oclose1(c);
+}
+void
+chan_write_failed(Channel *c)
+{
+ if (compat20)
+ chan_write_failed2(c);
+ else
+ chan_write_failed1(c);
+}
+
+void
+chan_mark_dead(Channel *c)
+{
+ c->type = SSH_CHANNEL_ZOMBIE;
+}
+
int
-chan_is_dead(Channel *c)
+chan_is_dead(Channel *c, int send)
{
+ if (c->type == SSH_CHANNEL_ZOMBIE) {
+ debug("channel %d: zombie", c->self);
+ return 1;
+ }
if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
return 0;
if (!compat20) {
@@ -414,10 +418,19 @@ chan_is_dead(Channel *c)
debug2("channel %d: active efd: %d len %d type %s",
c->self, c->efd, buffer_len(&c->extended),
c->extended_usage==CHAN_EXTENDED_READ ?
- "read": "write");
+ "read": "write");
} else {
if (!(c->flags & CHAN_CLOSE_SENT)) {
- chan_send_close2(c);
+ if (send) {
+ chan_send_close2(c);
+ } else {
+ /* channel would be dead if we sent a close */
+ if (c->flags & CHAN_CLOSE_RCVD) {
+ debug("channel %d: almost dead",
+ c->self);
+ return 1;
+ }
+ }
}
if ((c->flags & CHAN_CLOSE_SENT) &&
(c->flags & CHAN_CLOSE_RCVD)) {
@@ -428,55 +441,25 @@ chan_is_dead(Channel *c)
return 0;
}
-void
-chan_init_iostates(Channel *c)
-{
- c->ostate = CHAN_OUTPUT_OPEN;
- c->istate = CHAN_INPUT_OPEN;
- c->flags = 0;
-}
-
-/* init */
-void
-chan_init(void)
-{
- if (compat20) {
- chan_rcvd_oclose = chan_rcvd_oclose2;
- chan_read_failed = chan_read_failed_12;
- chan_ibuf_empty = chan_ibuf_empty2;
-
- chan_rcvd_ieof = chan_rcvd_ieof2;
- chan_write_failed = chan_write_failed2;
- chan_obuf_empty = chan_obuf_empty2;
- } else {
- chan_rcvd_oclose = chan_rcvd_oclose1;
- chan_read_failed = chan_read_failed_12;
- chan_ibuf_empty = chan_ibuf_empty1;
-
- chan_rcvd_ieof = chan_rcvd_ieof1;
- chan_write_failed = chan_write_failed1;
- chan_obuf_empty = chan_obuf_empty1;
- }
-}
-
/* helper */
static void
chan_shutdown_write(Channel *c)
{
- buffer_consume(&c->output, buffer_len(&c->output));
+ buffer_clear(&c->output);
if (compat20 && c->type == SSH_CHANNEL_LARVAL)
return;
/* shutdown failure is allowed if write failed already */
debug("channel %d: close_write", c->self);
if (c->sock != -1) {
if (shutdown(c->sock, SHUT_WR) < 0)
- debug("channel %d: chan_shutdown_write: shutdown() failed for fd%d: %.100s",
+ debug("channel %d: chan_shutdown_write: "
+ "shutdown() failed for fd%d: %.100s",
c->self, c->sock, strerror(errno));
} else {
- if (close(c->wfd) < 0)
- log("channel %d: chan_shutdown_write: close() failed for fd%d: %.100s",
+ if (channel_close_fd(&c->wfd) < 0)
+ log("channel %d: chan_shutdown_write: "
+ "close() failed for fd%d: %.100s",
c->self, c->wfd, strerror(errno));
- c->wfd = -1;
}
}
static void
@@ -487,12 +470,14 @@ chan_shutdown_read(Channel *c)
debug("channel %d: close_read", c->self);
if (c->sock != -1) {
if (shutdown(c->sock, SHUT_RD) < 0)
- error("channel %d: chan_shutdown_read: shutdown() failed for fd%d [i%d o%d]: %.100s",
- c->self, c->sock, c->istate, c->ostate, strerror(errno));
+ error("channel %d: chan_shutdown_read: "
+ "shutdown() failed for fd%d [i%d o%d]: %.100s",
+ c->self, c->sock, c->istate, c->ostate,
+ strerror(errno));
} else {
- if (close(c->rfd) < 0)
- log("channel %d: chan_shutdown_read: close() failed for fd%d: %.100s",
+ if (channel_close_fd(&c->rfd) < 0)
+ log("channel %d: chan_shutdown_read: "
+ "close() failed for fd%d: %.100s",
c->self, c->rfd, strerror(errno));
- c->rfd = -1;
}
}
diff --git a/crypto/openssh/nchan2.ms b/crypto/openssh/nchan2.ms
index 1b119d1..1cc51fa1 100644
--- a/crypto/openssh/nchan2.ms
+++ b/crypto/openssh/nchan2.ms
@@ -1,3 +1,27 @@
+.\" $OpenBSD: nchan2.ms,v 1.2 2001/10/03 10:05:57 markus Exp $
+.\"
+.\" Copyright (c) 2000 Markus Friedl. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
.TL
OpenSSH Channel Close Protocol 2.0 Implementation
.SH
diff --git a/crypto/openssh/packet.c b/crypto/openssh/packet.c
index 00109ea..b3e6d84 100644
--- a/crypto/openssh/packet.c
+++ b/crypto/openssh/packet.c
@@ -13,7 +13,7 @@
*
*
* SSH2 packet format added by Markus Friedl.
- * Copyright (c) 2000 Markus Friedl. All rights reserved.
+ * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,7 +37,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: packet.c,v 1.61 2001/04/05 10:42:51 markus Exp $");
+RCSID("$OpenBSD: packet.c,v 1.90 2002/02/27 21:23:13 stevesk Exp $");
#include "xmalloc.h"
#include "buffer.h"
@@ -59,6 +59,7 @@ RCSID("$OpenBSD: packet.c,v 1.61 2001/04/05 10:42:51 markus Exp $");
#include "mac.h"
#include "log.h"
#include "canohost.h"
+#include "misc.h"
#ifdef PACKET_DEBUG
#define DBG(x) x
@@ -75,12 +76,6 @@ RCSID("$OpenBSD: packet.c,v 1.61 2001/04/05 10:42:51 markus Exp $");
static int connection_in = -1;
static int connection_out = -1;
-/*
- * Cipher type. This value is only used to determine whether to pad the
- * packets with zeroes or random data.
- */
-static int cipher_type = SSH_CIPHER_NONE;
-
/* Protocol flags for the remote side. */
static u_int remote_protocol_flags = 0;
@@ -118,19 +113,11 @@ static int initialized = 0;
/* Set to true if the connection is interactive. */
static int interactive_mode = 0;
-/* True if SSH2 packet format is used */
-int use_ssh2_packet_format = 0;
-
/* Session key information for Encryption and MAC */
Newkeys *newkeys[MODE_MAX];
-void
-packet_set_ssh2_format(void)
-{
- DBG(debug("use_ssh2_packet_format"));
- use_ssh2_packet_format = 1;
- newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL;
-}
+/* roundup current message to extra_pad bytes */
+static u_char extra_pad = 0;
/*
* Sets the descriptors used for communication. Disables encryption until
@@ -144,9 +131,9 @@ packet_set_connection(int fd_in, int fd_out)
fatal("packet_set_connection: cannot load cipher 'none'");
connection_in = fd_in;
connection_out = fd_out;
- cipher_type = SSH_CIPHER_NONE;
- cipher_init(&send_context, none, (u_char *) "", 0, NULL, 0);
- cipher_init(&receive_context, none, (u_char *) "", 0, NULL, 0);
+ cipher_init(&send_context, none, "", 0, NULL, 0, CIPHER_ENCRYPT);
+ cipher_init(&receive_context, none, "", 0, NULL, 0, CIPHER_DECRYPT);
+ newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL;
if (!initialized) {
initialized = 1;
buffer_init(&input);
@@ -161,7 +148,7 @@ packet_set_connection(int fd_in, int fd_out)
/* Returns 1 if remote host is connected via socket, 0 if not. */
int
-packet_connection_is_on_socket()
+packet_connection_is_on_socket(void)
{
struct sockaddr_storage from, to;
socklen_t fromlen, tolen;
@@ -187,7 +174,7 @@ packet_connection_is_on_socket()
/* returns 1 if connection is via ipv4 */
int
-packet_connection_is_ipv4()
+packet_connection_is_ipv4(void)
{
struct sockaddr_storage to;
socklen_t tolen = sizeof(to);
@@ -203,7 +190,7 @@ packet_connection_is_ipv4()
/* Sets the connection into non-blocking mode. */
void
-packet_set_nonblocking()
+packet_set_nonblocking(void)
{
/* Set the socket into non-blocking mode. */
if (fcntl(connection_in, F_SETFL, O_NONBLOCK) < 0)
@@ -218,7 +205,7 @@ packet_set_nonblocking()
/* Returns the socket used for reading. */
int
-packet_get_connection_in()
+packet_get_connection_in(void)
{
return connection_in;
}
@@ -226,7 +213,7 @@ packet_get_connection_in()
/* Returns the descriptor used for writing. */
int
-packet_get_connection_out()
+packet_get_connection_out(void)
{
return connection_out;
}
@@ -234,7 +221,7 @@ packet_get_connection_out()
/* Closes the connection and clears and frees internal data structures. */
void
-packet_close()
+packet_close(void)
{
if (!initialized)
return;
@@ -254,6 +241,8 @@ packet_close()
buffer_free(&compression_buffer);
buffer_compress_uninit();
}
+ cipher_cleanup(&send_context);
+ cipher_cleanup(&receive_context);
}
/* Sets remote side protocol flags. */
@@ -262,13 +251,12 @@ void
packet_set_protocol_flags(u_int protocol_flags)
{
remote_protocol_flags = protocol_flags;
- channel_set_options((protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0);
}
/* Returns the remote protocol flags set earlier by the above function. */
u_int
-packet_get_protocol_flags()
+packet_get_protocol_flags(void)
{
return remote_protocol_flags;
}
@@ -278,8 +266,8 @@ packet_get_protocol_flags()
* Level is compression level 1 (fastest) - 9 (slow, best) as in gzip.
*/
-void
-packet_init_compression()
+static void
+packet_init_compression(void)
{
if (compression_buffer_ready == 1)
return;
@@ -290,7 +278,7 @@ packet_init_compression()
void
packet_start_compression(int level)
{
- if (packet_compression && !use_ssh2_packet_format)
+ if (packet_compression && !compat20)
fatal("Compression already enabled.");
packet_compression = 1;
packet_init_compression();
@@ -299,43 +287,10 @@ packet_start_compression(int level)
}
/*
- * Encrypts the given number of bytes, copying from src to dest. bytes is
- * known to be a multiple of 8.
- */
-
-void
-packet_encrypt(CipherContext * cc, void *dest, void *src,
- u_int bytes)
-{
- cipher_encrypt(cc, dest, src, bytes);
-}
-
-/*
- * Decrypts the given number of bytes, copying from src to dest. bytes is
- * known to be a multiple of 8.
- */
-
-void
-packet_decrypt(CipherContext *context, void *dest, void *src, u_int bytes)
-{
- /*
- * Cryptographic attack detector for ssh - Modifications for packet.c
- * (C)1998 CORE-SDI, Buenos Aires Argentina Ariel Futoransky(futo@core-sdi.com)
- */
- if (!compat20 &&
- context->cipher->number != SSH_CIPHER_NONE &&
- detect_attack(src, bytes, NULL) == DEATTACK_DETECTED)
- packet_disconnect("crc32 compensation attack: network attack detected");
-
- cipher_decrypt(context, dest, src, bytes);
-}
-
-/*
* Causes any further packets to be encrypted using the given key. The same
* key is used for both sending and reception. However, both directions are
* encrypted independently of each other.
*/
-
void
packet_set_encryption_key(const u_char *key, u_int keylen,
int number)
@@ -345,85 +300,52 @@ packet_set_encryption_key(const u_char *key, u_int keylen,
fatal("packet_set_encryption_key: unknown cipher number %d", number);
if (keylen < 20)
fatal("packet_set_encryption_key: keylen too small: %d", keylen);
- cipher_init(&receive_context, cipher, key, keylen, NULL, 0);
- cipher_init(&send_context, cipher, key, keylen, NULL, 0);
-}
-
-/* Starts constructing a packet to send. */
-
-void
-packet_start1(int type)
-{
- char buf[9];
-
- buffer_clear(&outgoing_packet);
- memset(buf, 0, 8);
- buf[8] = type;
- buffer_append(&outgoing_packet, buf, 9);
+ cipher_init(&send_context, cipher, key, keylen, NULL, 0, CIPHER_ENCRYPT);
+ cipher_init(&receive_context, cipher, key, keylen, NULL, 0, CIPHER_DECRYPT);
}
+/* Start constructing a packet to send. */
void
-packet_start2(int type)
+packet_start(u_char type)
{
- char buf[4+1+1];
-
- buffer_clear(&outgoing_packet);
- memset(buf, 0, sizeof buf);
- /* buf[0..3] = payload_len; */
- /* buf[4] = pad_len; */
- buf[5] = type & 0xff;
- buffer_append(&outgoing_packet, buf, sizeof buf);
-}
+ u_char buf[9];
+ int len;
-void
-packet_start(int type)
-{
DBG(debug("packet_start[%d]", type));
- if (use_ssh2_packet_format)
- packet_start2(type);
- else
- packet_start1(type);
+ len = compat20 ? 6 : 9;
+ memset(buf, 0, len - 1);
+ buf[len - 1] = type;
+ buffer_clear(&outgoing_packet);
+ buffer_append(&outgoing_packet, buf, len);
}
-/* Appends a character to the packet data. */
-
+/* Append payload. */
void
packet_put_char(int value)
{
char ch = value;
buffer_append(&outgoing_packet, &ch, 1);
}
-
-/* Appends an integer to the packet data. */
-
void
packet_put_int(u_int value)
{
buffer_put_int(&outgoing_packet, value);
}
-
-/* Appends a string to packet data. */
-
void
-packet_put_string(const char *buf, u_int len)
+packet_put_string(const void *buf, u_int len)
{
buffer_put_string(&outgoing_packet, buf, len);
}
void
packet_put_cstring(const char *str)
{
- buffer_put_string(&outgoing_packet, str, strlen(str));
+ buffer_put_cstring(&outgoing_packet, str);
}
-
void
-packet_put_raw(const char *buf, u_int len)
+packet_put_raw(const void *buf, u_int len)
{
buffer_append(&outgoing_packet, buf, len);
}
-
-
-/* Appends an arbitrary precision integer to packet data. */
-
void
packet_put_bignum(BIGNUM * value)
{
@@ -440,10 +362,10 @@ packet_put_bignum2(BIGNUM * value)
* encrypts the packet before sending.
*/
-void
+static void
packet_send1(void)
{
- char buf[8], *cp;
+ u_char buf[8], *cp;
int i, padding, len;
u_int checksum;
u_int32_t rand = 0;
@@ -461,14 +383,14 @@ packet_send1(void)
buffer_compress(&outgoing_packet, &compression_buffer);
buffer_clear(&outgoing_packet);
buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer),
- buffer_len(&compression_buffer));
+ buffer_len(&compression_buffer));
}
/* Compute packet length without padding (add checksum, remove padding). */
len = buffer_len(&outgoing_packet) + 4 - 8;
/* Insert padding. Initialized to zero in packet_start1() */
padding = 8 - len % 8;
- if (cipher_type != SSH_CIPHER_NONE) {
+ if (!send_context.plaintext) {
cp = buffer_ptr(&outgoing_packet);
for (i = 0; i < padding; i++) {
if (i % 4 == 0)
@@ -480,7 +402,7 @@ packet_send1(void)
buffer_consume(&outgoing_packet, 8 - padding);
/* Add check bytes. */
- checksum = ssh_crc32((u_char *) buffer_ptr(&outgoing_packet),
+ checksum = ssh_crc32(buffer_ptr(&outgoing_packet),
buffer_len(&outgoing_packet));
PUT_32BIT(buf, checksum);
buffer_append(&outgoing_packet, buf, 4);
@@ -493,9 +415,9 @@ packet_send1(void)
/* Append to output. */
PUT_32BIT(buf, len);
buffer_append(&output, buf, 4);
- buffer_append_space(&output, &cp, buffer_len(&outgoing_packet));
- packet_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet),
- buffer_len(&outgoing_packet));
+ cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
+ cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet),
+ buffer_len(&outgoing_packet));
#ifdef PACKET_DEBUG
fprintf(stderr, "encrypted: ");
@@ -511,21 +433,27 @@ packet_send1(void)
*/
}
-void
+static void
set_newkeys(int mode)
{
Enc *enc;
Mac *mac;
Comp *comp;
CipherContext *cc;
+ int encrypt;
debug("newkeys: mode %d", mode);
- cc = (mode == MODE_OUT) ? &send_context : &receive_context;
+ if (mode == MODE_OUT) {
+ cc = &send_context;
+ encrypt = CIPHER_ENCRYPT;
+ } else {
+ cc = &receive_context;
+ encrypt = CIPHER_DECRYPT;
+ }
if (newkeys[mode] != NULL) {
debug("newkeys: rekeying");
- /* todo: free old keys, reset compression/cipher-ctxt; */
- memset(cc, 0, sizeof(*cc));
+ cipher_cleanup(cc);
enc = &newkeys[mode]->enc;
mac = &newkeys[mode]->mac;
comp = &newkeys[mode]->comp;
@@ -547,10 +475,10 @@ set_newkeys(int mode)
if (mac->md != NULL)
mac->enabled = 1;
DBG(debug("cipher_init_context: %d", mode));
- cipher_init(cc, enc->cipher, enc->key, enc->cipher->key_len,
- enc->iv, enc->cipher->block_size);
- memset(enc->iv, 0, enc->cipher->block_size);
- memset(enc->key, 0, enc->cipher->key_len);
+ cipher_init(cc, enc->cipher, enc->key, enc->key_len,
+ enc->iv, enc->block_size, encrypt);
+ memset(enc->iv, 0, enc->block_size);
+ memset(enc->key, 0, enc->key_len);
if (comp->type != 0 && comp->enabled == 0) {
packet_init_compression();
if (mode == MODE_OUT)
@@ -564,16 +492,15 @@ set_newkeys(int mode)
/*
* Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
*/
-void
+static void
packet_send2(void)
{
static u_int32_t seqnr = 0;
- u_char *macbuf = NULL;
- char *cp;
+ u_char type, *cp, *macbuf = NULL;
+ u_char padlen, pad;
u_int packet_length = 0;
- u_int i, padlen, len;
+ u_int i, len;
u_int32_t rand = 0;
- int type;
Enc *enc = NULL;
Mac *mac = NULL;
Comp *comp = NULL;
@@ -584,10 +511,10 @@ packet_send2(void)
mac = &newkeys[MODE_OUT]->mac;
comp = &newkeys[MODE_OUT]->comp;
}
- block_size = enc ? enc->cipher->block_size : 8;
+ block_size = enc ? enc->block_size : 8;
cp = buffer_ptr(&outgoing_packet);
- type = cp[5] & 0xff;
+ type = cp[5];
#ifdef PACKET_DEBUG
fprintf(stderr, "plain: ");
@@ -618,8 +545,17 @@ packet_send2(void)
padlen = block_size - (len % block_size);
if (padlen < 4)
padlen += block_size;
- buffer_append_space(&outgoing_packet, &cp, padlen);
- if (enc && enc->cipher->number != SSH_CIPHER_NONE) {
+ if (extra_pad) {
+ /* will wrap if extra_pad+padlen > 255 */
+ extra_pad = roundup(extra_pad, block_size);
+ pad = extra_pad - ((len + padlen) % extra_pad);
+ debug("packet_send2: adding %d (len %d padlen %d extra_pad %d)",
+ pad, len, padlen, extra_pad);
+ padlen += pad;
+ extra_pad = 0;
+ }
+ cp = buffer_append_space(&outgoing_packet, padlen);
+ if (enc && !send_context.plaintext) {
/* random padding */
for (i = 0; i < padlen; i++) {
if (i % 4 == 0)
@@ -635,19 +571,19 @@ packet_send2(void)
packet_length = buffer_len(&outgoing_packet) - 4;
cp = buffer_ptr(&outgoing_packet);
PUT_32BIT(cp, packet_length);
- cp[4] = padlen & 0xff;
+ 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, seqnr,
- (u_char *) buffer_ptr(&outgoing_packet),
+ buffer_ptr(&outgoing_packet),
buffer_len(&outgoing_packet));
DBG(debug("done calc MAC out #%d", seqnr));
}
/* encrypt packet and append to output buffer. */
- buffer_append_space(&output, &cp, buffer_len(&outgoing_packet));
- packet_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet),
+ cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
+ cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet),
buffer_len(&outgoing_packet));
/* append unencrypted MAC */
if (mac && mac->enabled)
@@ -666,9 +602,9 @@ packet_send2(void)
}
void
-packet_send()
+packet_send(void)
{
- if (use_ssh2_packet_format)
+ if (compat20)
packet_send2();
else
packet_send1();
@@ -682,7 +618,7 @@ packet_send()
*/
int
-packet_read(int *payload_len_ptr)
+packet_read_seqnr(u_int32_t *seqnr_p)
{
int type, len;
fd_set *setp;
@@ -698,13 +634,13 @@ packet_read(int *payload_len_ptr)
/* Stay in the loop until we have received a complete packet. */
for (;;) {
/* Try to read a packet from the buffer. */
- type = packet_read_poll(payload_len_ptr);
- if (!use_ssh2_packet_format && (
+ type = packet_read_poll_seqnr(seqnr_p);
+ if (!compat20 && (
type == SSH_SMSG_SUCCESS
|| type == SSH_SMSG_FAILURE
|| type == SSH_CMSG_EOF
|| type == SSH_CMSG_EXIT_CONFIRMATION))
- packet_integrity_check(*payload_len_ptr, 0, type);
+ packet_check_eom();
/* If we got a packet, return it. */
if (type != SSH_MSG_NONE) {
xfree(setp);
@@ -737,17 +673,23 @@ packet_read(int *payload_len_ptr)
/* NOTREACHED */
}
+int
+packet_read(void)
+{
+ return packet_read_seqnr(NULL);
+}
+
/*
* Waits until a packet has been received, verifies that its type matches
* that given, and gives a fatal error and exits if there is a mismatch.
*/
void
-packet_read_expect(int *payload_len_ptr, int expected_type)
+packet_read_expect(int expected_type)
{
int type;
- type = packet_read(payload_len_ptr);
+ type = packet_read();
if (type != expected_type)
packet_disconnect("Protocol error: expected packet type %d, got %d",
expected_type, type);
@@ -760,28 +702,21 @@ packet_read_expect(int *payload_len_ptr, int expected_type)
* SSH_MSG_DISCONNECT is handled specially here. Also,
* SSH_MSG_IGNORE messages are skipped by this function and are never returned
* to higher levels.
- *
- * The returned payload_len does include space consumed by:
- * Packet length
- * Padding
- * Packet type
- * Check bytes
*/
-int
-packet_read_poll1(int *payload_len_ptr)
+static int
+packet_read_poll1(void)
{
u_int len, padded_len;
- u_char *ucp;
- char buf[8], *cp;
+ u_char *cp, type;
u_int checksum, stored_checksum;
/* Check if input size is less than minimum packet size. */
if (buffer_len(&input) < 4 + 8)
return SSH_MSG_NONE;
/* Get length of incoming packet. */
- ucp = (u_char *) buffer_ptr(&input);
- len = GET_32BIT(ucp);
+ cp = buffer_ptr(&input);
+ len = GET_32BIT(cp);
if (len < 1 + 2 + 2 || len > 256 * 1024)
packet_disconnect("Bad packet length %d.", len);
padded_len = (len + 8) & ~7;
@@ -795,10 +730,20 @@ packet_read_poll1(int *payload_len_ptr)
/* Consume packet length. */
buffer_consume(&input, 4);
- /* Copy data to incoming_packet. */
+ /*
+ * Cryptographic attack detector for ssh
+ * (C)1998 CORE-SDI, Buenos Aires Argentina
+ * Ariel Futoransky(futo@core-sdi.com)
+ */
+ if (!receive_context.plaintext &&
+ detect_attack(buffer_ptr(&input), padded_len, NULL) == DEATTACK_DETECTED)
+ packet_disconnect("crc32 compensation attack: network attack detected");
+
+ /* Decrypt data to incoming_packet. */
buffer_clear(&incoming_packet);
- buffer_append_space(&incoming_packet, &cp, padded_len);
- packet_decrypt(&receive_context, cp, buffer_ptr(&input), padded_len);
+ cp = buffer_append_space(&incoming_packet, padded_len);
+ cipher_crypt(&receive_context, cp, buffer_ptr(&input), padded_len);
+
buffer_consume(&input, padded_len);
#ifdef PACKET_DEBUG
@@ -807,25 +752,23 @@ packet_read_poll1(int *payload_len_ptr)
#endif
/* Compute packet checksum. */
- checksum = ssh_crc32((u_char *) buffer_ptr(&incoming_packet),
+ checksum = ssh_crc32(buffer_ptr(&incoming_packet),
buffer_len(&incoming_packet) - 4);
/* Skip padding. */
buffer_consume(&incoming_packet, 8 - len % 8);
/* Test check bytes. */
-
if (len != buffer_len(&incoming_packet))
- packet_disconnect("packet_read_poll: len %d != buffer_len %d.",
+ packet_disconnect("packet_read_poll1: len %d != buffer_len %d.",
len, buffer_len(&incoming_packet));
- ucp = (u_char *) buffer_ptr(&incoming_packet) + len - 4;
- stored_checksum = GET_32BIT(ucp);
+ cp = (u_char *)buffer_ptr(&incoming_packet) + len - 4;
+ stored_checksum = GET_32BIT(cp);
if (checksum != stored_checksum)
packet_disconnect("Corrupted check bytes on input.");
buffer_consume_end(&incoming_packet, 4);
- /* If using packet compression, decompress the packet. */
if (packet_compression) {
buffer_clear(&compression_buffer);
buffer_uncompress(&incoming_packet, &compression_buffer);
@@ -833,26 +776,17 @@ packet_read_poll1(int *payload_len_ptr)
buffer_append(&incoming_packet, buffer_ptr(&compression_buffer),
buffer_len(&compression_buffer));
}
- /* Get packet type. */
- buffer_get(&incoming_packet, &buf[0], 1);
-
- /* Return length of payload (without type field). */
- *payload_len_ptr = buffer_len(&incoming_packet);
-
- /* Return type. */
- return (u_char) buf[0];
+ type = buffer_get_char(&incoming_packet);
+ return type;
}
-int
-packet_read_poll2(int *payload_len_ptr)
+static int
+packet_read_poll2(u_int32_t *seqnr_p)
{
static u_int32_t seqnr = 0;
static u_int packet_length = 0;
u_int padlen, need;
- u_char buf[8], *macbuf;
- u_char *ucp;
- char *cp;
- int type;
+ u_char *macbuf, *cp, type;
int maclen, block_size;
Enc *enc = NULL;
Mac *mac = NULL;
@@ -864,7 +798,7 @@ packet_read_poll2(int *payload_len_ptr)
comp = &newkeys[MODE_IN]->comp;
}
maclen = mac && mac->enabled ? mac->mac_len : 0;
- block_size = enc ? enc->cipher->block_size : 8;
+ block_size = enc ? enc->block_size : 8;
if (packet_length == 0) {
/*
@@ -874,11 +808,11 @@ packet_read_poll2(int *payload_len_ptr)
if (buffer_len(&input) < block_size)
return SSH_MSG_NONE;
buffer_clear(&incoming_packet);
- buffer_append_space(&incoming_packet, &cp, block_size);
- packet_decrypt(&receive_context, cp, buffer_ptr(&input),
+ cp = buffer_append_space(&incoming_packet, block_size);
+ cipher_crypt(&receive_context, cp, buffer_ptr(&input),
block_size);
- ucp = (u_char *) buffer_ptr(&incoming_packet);
- packet_length = GET_32BIT(ucp);
+ cp = buffer_ptr(&incoming_packet);
+ packet_length = GET_32BIT(cp);
if (packet_length < 1 + 4 || packet_length > 256 * 1024) {
buffer_dump(&incoming_packet);
packet_disconnect("Bad packet length %d.", packet_length);
@@ -903,8 +837,8 @@ packet_read_poll2(int *payload_len_ptr)
fprintf(stderr, "read_poll enc/full: ");
buffer_dump(&input);
#endif
- buffer_append_space(&incoming_packet, &cp, need);
- packet_decrypt(&receive_context, cp, buffer_ptr(&input), need);
+ cp = buffer_append_space(&incoming_packet, need);
+ cipher_crypt(&receive_context, cp, buffer_ptr(&input), need);
buffer_consume(&input, need);
/*
* compute MAC over seqnr and packet,
@@ -912,19 +846,21 @@ packet_read_poll2(int *payload_len_ptr)
*/
if (mac && mac->enabled) {
macbuf = mac_compute(mac, seqnr,
- (u_char *) buffer_ptr(&incoming_packet),
+ buffer_ptr(&incoming_packet),
buffer_len(&incoming_packet));
if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0)
packet_disconnect("Corrupted MAC on input.");
DBG(debug("MAC #%d ok", seqnr));
buffer_consume(&input, mac->mac_len);
}
+ if (seqnr_p != NULL)
+ *seqnr_p = seqnr;
if (++seqnr == 0)
log("incoming seqnr wraps around");
/* get padlen */
- cp = buffer_ptr(&incoming_packet) + 4;
- padlen = *cp & 0xff;
+ cp = buffer_ptr(&incoming_packet);
+ padlen = cp[4];
DBG(debug("input: padlen %d", padlen));
if (padlen < 4)
packet_disconnect("Corrupted padlen %d on input.", padlen);
@@ -946,39 +882,31 @@ packet_read_poll2(int *payload_len_ptr)
* get packet type, implies consume.
* return length of payload (without type field)
*/
- buffer_get(&incoming_packet, (char *)&buf[0], 1);
- *payload_len_ptr = buffer_len(&incoming_packet);
-
- /* reset for next packet */
- packet_length = 0;
-
- /* extract packet type */
- type = (u_char)buf[0];
-
+ type = buffer_get_char(&incoming_packet);
if (type == SSH2_MSG_NEWKEYS)
set_newkeys(MODE_IN);
-
#ifdef PACKET_DEBUG
fprintf(stderr, "read/plain[%d]:\r\n", type);
buffer_dump(&incoming_packet);
#endif
- return (u_char)type;
+ /* reset for next packet */
+ packet_length = 0;
+ return type;
}
int
-packet_read_poll(int *payload_len_ptr)
+packet_read_poll_seqnr(u_int32_t *seqnr_p)
{
+ int reason, seqnr;
+ u_char type;
char *msg;
- for (;;) {
- int type = use_ssh2_packet_format ?
- packet_read_poll2(payload_len_ptr):
- packet_read_poll1(payload_len_ptr);
- if(compat20) {
- int reason;
- if (type != 0)
+ for (;;) {
+ if (compat20) {
+ type = packet_read_poll2(seqnr_p);
+ if (type)
DBG(debug("received packet type %d", type));
- switch(type) {
+ switch (type) {
case SSH2_MSG_IGNORE:
break;
case SSH2_MSG_DEBUG:
@@ -997,12 +925,17 @@ packet_read_poll(int *payload_len_ptr)
xfree(msg);
fatal_cleanup();
break;
+ case SSH2_MSG_UNIMPLEMENTED:
+ seqnr = packet_get_int();
+ debug("Received SSH2_MSG_UNIMPLEMENTED for %d", seqnr);
+ break;
default:
return type;
break;
}
} else {
- switch(type) {
+ type = packet_read_poll1();
+ switch (type) {
case SSH_MSG_IGNORE:
break;
case SSH_MSG_DEBUG:
@@ -1018,7 +951,7 @@ packet_read_poll(int *payload_len_ptr)
xfree(msg);
break;
default:
- if (type != 0)
+ if (type)
DBG(debug("received packet type %d", type));
return type;
break;
@@ -1027,6 +960,12 @@ packet_read_poll(int *payload_len_ptr)
}
}
+int
+packet_read_poll(void)
+{
+ return packet_read_poll_seqnr(NULL);
+}
+
/*
* Buffers the given amount of input characters. This is intended to be used
* together with packet_read_poll.
@@ -1041,7 +980,7 @@ packet_process_incoming(const char *buf, u_int len)
/* Returns a character from the packet. */
u_int
-packet_get_char()
+packet_get_char(void)
{
char ch;
buffer_get(&incoming_packet, &ch, 1);
@@ -1051,7 +990,7 @@ packet_get_char()
/* Returns an integer from the packet data. */
u_int
-packet_get_int()
+packet_get_int(void)
{
return buffer_get_int(&incoming_packet);
}
@@ -1062,18 +1001,18 @@ packet_get_int()
*/
void
-packet_get_bignum(BIGNUM * value, int *length_ptr)
+packet_get_bignum(BIGNUM * value)
{
- *length_ptr = buffer_get_bignum(&incoming_packet, value);
+ buffer_get_bignum(&incoming_packet, value);
}
void
-packet_get_bignum2(BIGNUM * value, int *length_ptr)
+packet_get_bignum2(BIGNUM * value)
{
- *length_ptr = buffer_get_bignum2(&incoming_packet, value);
+ buffer_get_bignum2(&incoming_packet, value);
}
-char *
+void *
packet_get_raw(int *length_ptr)
{
int bytes = buffer_len(&incoming_packet);
@@ -1095,7 +1034,7 @@ packet_remaining(void)
* integer into which the length of the string is stored.
*/
-char *
+void *
packet_get_string(u_int *length_ptr)
{
return buffer_get_string(&incoming_packet, length_ptr);
@@ -1169,13 +1108,13 @@ packet_disconnect(const char *fmt,...)
packet_put_cstring("");
} else {
packet_start(SSH_MSG_DISCONNECT);
- packet_put_string(buf, strlen(buf));
+ packet_put_cstring(buf);
}
packet_send();
packet_write_wait();
/* Stop listening for connections. */
- channel_stop_listening();
+ channel_close_all();
/* Close the connection. */
packet_close();
@@ -1188,7 +1127,7 @@ packet_disconnect(const char *fmt,...)
/* Checks if there is any buffered output, and tries to write some of the output. */
void
-packet_write_poll()
+packet_write_poll(void)
{
int len = buffer_len(&output);
if (len > 0) {
@@ -1209,7 +1148,7 @@ packet_write_poll()
*/
void
-packet_write_wait()
+packet_write_wait(void)
{
fd_set *setp;
@@ -1231,7 +1170,7 @@ packet_write_wait()
/* Returns true if there is buffered data to write to the connection. */
int
-packet_have_data_to_write()
+packet_have_data_to_write(void)
{
return buffer_len(&output) != 0;
}
@@ -1239,7 +1178,7 @@ packet_have_data_to_write()
/* Returns true if there is not too much data to write to the connection. */
int
-packet_not_very_much_data_to_write()
+packet_not_very_much_data_to_write(void)
{
if (interactive_mode)
return buffer_len(&output) < 16384;
@@ -1255,7 +1194,6 @@ packet_set_interactive(int interactive)
static int called = 0;
int lowdelay = IPTOS_LOWDELAY;
int throughput = IPTOS_THROUGHPUT;
- int on = 1;
if (called)
return;
@@ -1277,19 +1215,17 @@ packet_set_interactive(int interactive)
*/
if (packet_connection_is_ipv4()) {
if (setsockopt(connection_in, IPPROTO_IP, IP_TOS,
- (void *) &lowdelay, sizeof(lowdelay)) < 0)
+ &lowdelay, sizeof(lowdelay)) < 0)
error("setsockopt IPTOS_LOWDELAY: %.100s",
strerror(errno));
}
- if (setsockopt(connection_in, IPPROTO_TCP, TCP_NODELAY, (void *) &on,
- sizeof(on)) < 0)
- error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
+ set_nodelay(connection_in);
} else if (packet_connection_is_ipv4()) {
/*
* Set IP options for a non-interactive connection. Use
* IPTOS_THROUGHPUT.
*/
- if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &throughput,
+ if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, &throughput,
sizeof(throughput)) < 0)
error("setsockopt IPTOS_THROUGHPUT: %.100s", strerror(errno));
}
@@ -1298,7 +1234,7 @@ packet_set_interactive(int interactive)
/* Returns true if the current connection is interactive. */
int
-packet_is_interactive()
+packet_is_interactive(void)
{
return interactive_mode;
}
@@ -1316,11 +1252,19 @@ packet_set_maxsize(int s)
log("packet_set_maxsize: bad size %d", s);
return -1;
}
- log("packet_set_maxsize: setting to %d", s);
+ called = 1;
+ debug("packet_set_maxsize: setting to %d", s);
max_packet_size = s;
return s;
}
+/* roundup current message to pad bytes */
+void
+packet_add_padding(u_char pad)
+{
+ extra_pad = pad;
+}
+
/*
* 9.2. Ignored Data Message
*
@@ -1332,41 +1276,6 @@ packet_set_maxsize(int s)
* required to send them. This message can be used as an additional
* protection measure against advanced traffic analysis techniques.
*/
-/* size of current + ignore message should be n*sumlen bytes (w/o mac) */
-void
-packet_inject_ignore(int sumlen)
-{
- int blocksize, padlen, have, need, nb, mini, nbytes;
- Enc *enc = NULL;
-
- if (use_ssh2_packet_format == 0)
- return;
-
- have = buffer_len(&outgoing_packet);
- debug2("packet_inject_ignore: current %d", have);
- if (newkeys[MODE_OUT] != NULL)
- enc = &newkeys[MODE_OUT]->enc;
- blocksize = enc ? enc->cipher->block_size : 8;
- padlen = blocksize - (have % blocksize);
- if (padlen < 4)
- padlen += blocksize;
- have += padlen;
- have /= blocksize; /* # of blocks for current message */
-
- nb = roundup(sumlen, blocksize) / blocksize; /* blocks for both */
- mini = roundup(5+1+4+4, blocksize) / blocksize; /* minsize ignore msg */
- need = nb - (have % nb); /* blocks for ignore */
- if (need <= mini)
- need += nb;
- nbytes = (need - mini) * blocksize; /* size of ignore payload */
- debug2("packet_inject_ignore: block %d have %d nb %d mini %d need %d",
- blocksize, have, nb, mini, need);
-
- /* enqueue current message and append a ignore message */
- packet_send();
- packet_send_ignore(nbytes);
-}
-
void
packet_send_ignore(int nbytes)
{
@@ -1375,7 +1284,7 @@ packet_send_ignore(int nbytes)
packet_start(compat20 ? SSH2_MSG_IGNORE : SSH_MSG_IGNORE);
packet_put_int(nbytes);
- for(i = 0; i < nbytes; i++) {
+ for (i = 0; i < nbytes; i++) {
if (i % 4 == 0)
rand = arc4random();
packet_put_char(rand & 0xff);
diff --git a/crypto/openssh/radix.c b/crypto/openssh/radix.c
index 3b149a8..e604357 100644
--- a/crypto/openssh/radix.c
+++ b/crypto/openssh/radix.c
@@ -25,11 +25,13 @@
#include "includes.h"
#include "uuencode.h"
-RCSID("$OpenBSD: radix.c,v 1.15 2001/01/16 23:58:09 deraadt Exp $");
+RCSID("$OpenBSD: radix.c,v 1.17 2001/11/19 19:02:16 mpech Exp $");
#ifdef AFS
#include <krb.h>
+#include <radix.h>
+
typedef u_char my_u_char;
typedef u_int my_u_int32_t;
typedef u_short my_u_short;
@@ -37,7 +39,7 @@ typedef u_short my_u_short;
/* Nasty macros from BIND-4.9.2 */
#define GETSHORT(s, cp) { \
- register my_u_char *t_cp = (my_u_char *)(cp); \
+ my_u_char *t_cp = (my_u_char *)(cp); \
(s) = (((my_u_short)t_cp[0]) << 8) \
| (((my_u_short)t_cp[1])) \
; \
@@ -45,7 +47,7 @@ typedef u_short my_u_short;
}
#define GETLONG(l, cp) { \
- register my_u_char *t_cp = (my_u_char *)(cp); \
+ my_u_char *t_cp = (my_u_char *)(cp); \
(l) = (((my_u_int32_t)t_cp[0]) << 24) \
| (((my_u_int32_t)t_cp[1]) << 16) \
| (((my_u_int32_t)t_cp[2]) << 8) \
@@ -55,16 +57,16 @@ typedef u_short my_u_short;
}
#define PUTSHORT(s, cp) { \
- register my_u_short t_s = (my_u_short)(s); \
- register my_u_char *t_cp = (my_u_char *)(cp); \
+ my_u_short t_s = (my_u_short)(s); \
+ my_u_char *t_cp = (my_u_char *)(cp); \
*t_cp++ = t_s >> 8; \
*t_cp = t_s; \
(cp) += 2; \
}
#define PUTLONG(l, cp) { \
- register my_u_int32_t t_l = (my_u_int32_t)(l); \
- register my_u_char *t_cp = (my_u_char *)(cp); \
+ my_u_int32_t t_l = (my_u_int32_t)(l); \
+ my_u_char *t_cp = (my_u_char *)(cp); \
*t_cp++ = t_l >> 24; \
*t_cp++ = t_l >> 16; \
*t_cp++ = t_l >> 8; \
@@ -73,9 +75,9 @@ typedef u_short my_u_short;
}
#define GETSTRING(s, p, p_l) { \
- register char *p_targ = (p) + p_l; \
- register char *s_c = (s); \
- register char *p_c = (p); \
+ char *p_targ = (p) + p_l; \
+ char *s_c = (s); \
+ char *p_c = (p); \
while (*p_c && (p_c < p_targ)) { \
*s_c++ = *p_c++; \
} \
diff --git a/crypto/openssh/radix.h b/crypto/openssh/radix.h
index 57592d8..e94e4ac 100644
--- a/crypto/openssh/radix.h
+++ b/crypto/openssh/radix.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: radix.h,v 1.2 2001/01/29 01:58:17 niklas Exp $ */
+/* $OpenBSD: radix.h,v 1.4 2001/06/26 17:27:24 markus Exp $ */
/*
* Copyright (c) 1999 Dug Song. All rights reserved.
@@ -24,5 +24,5 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-int creds_to_radix(CREDENTIALS * creds, u_char *buf, size_t buflen);
-int radix_to_creds(const char *buf, CREDENTIALS * creds);
+int creds_to_radix(CREDENTIALS *, u_char *, size_t);
+int radix_to_creds(const char *, CREDENTIALS *);
diff --git a/crypto/openssh/readpass.c b/crypto/openssh/readpass.c
index b5f5971..c55dd21 100644
--- a/crypto/openssh/readpass.c
+++ b/crypto/openssh/readpass.c
@@ -1,6 +1,5 @@
/*
- * Copyright (c) 1988, 1993
- * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,55 +9,51 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
*
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
-RCSID("$OpenBSD: readpass.c,v 1.15 2001/04/18 21:57:41 markus Exp $");
+RCSID("$OpenBSD: readpass.c,v 1.26 2002/02/13 00:39:15 markus Exp $");
+
+#include <readpassphrase.h>
#include "xmalloc.h"
-#include "cli.h"
#include "readpass.h"
#include "pathnames.h"
#include "log.h"
-#include "atomicio.h"
#include "ssh.h"
-char *
-ssh_askpass(char *askpass, char *msg)
+static char *
+ssh_askpass(char *askpass, const char *msg)
{
pid_t pid;
size_t len;
- char *nl, *pass;
- int p[2], status;
+ char *pass;
+ int p[2], status, ret;
char buf[1024];
if (fflush(stdout) != 0)
error("ssh_askpass: fflush: %s", strerror(errno));
if (askpass == NULL)
fatal("internal error: askpass undefined");
- if (pipe(p) < 0)
- fatal("ssh_askpass: pipe: %s", strerror(errno));
- if ((pid = fork()) < 0)
- fatal("ssh_askpass: fork: %s", strerror(errno));
+ if (pipe(p) < 0) {
+ error("ssh_askpass: pipe: %s", strerror(errno));
+ return xstrdup("");
+ }
+ if ((pid = fork()) < 0) {
+ error("ssh_askpass: fork: %s", strerror(errno));
+ return xstrdup("");
+ }
if (pid == 0) {
seteuid(getuid());
setuid(getuid());
@@ -69,43 +64,48 @@ ssh_askpass(char *askpass, char *msg)
fatal("ssh_askpass: exec(%s): %s", askpass, strerror(errno));
}
close(p[1]);
- len = read(p[0], buf, sizeof buf);
+
+ len = ret = 0;
+ do {
+ ret = read(p[0], buf + len, sizeof(buf) - 1 - len);
+ if (ret == -1 && errno == EINTR)
+ continue;
+ if (ret <= 0)
+ break;
+ len += ret;
+ } while (sizeof(buf) - 1 - len > 0);
+ buf[len] = '\0';
+
close(p[0]);
while (waitpid(pid, &status, 0) < 0)
if (errno != EINTR)
break;
- if (len <= 1)
- return xstrdup("");
- nl = strchr(buf, '\n');
- if (nl)
- *nl = '\0';
+
+ buf[strcspn(buf, "\r\n")] = '\0';
pass = xstrdup(buf);
memset(buf, 0, sizeof(buf));
return pass;
}
-
/*
- * Reads a passphrase from /dev/tty with echo turned off. Returns the
- * passphrase (allocated with xmalloc), being very careful to ensure that
- * no other userland buffer is storing the password.
- */
-/*
- * Note: the funcationallity of this routing has been moved to
- * cli_read_passphrase(). This routing remains to maintain
- * compatibility with existing code.
+ * Reads a passphrase from /dev/tty with echo turned off/on. Returns the
+ * passphrase (allocated with xmalloc). Exits if EOF is encountered. If
+ * RP_ALLOW_STDIN is set, the passphrase will be read from stdin if no
+ * tty is available
*/
char *
-read_passphrase(char *prompt, int from_stdin)
+read_passphrase(const char *prompt, int flags)
{
- char *askpass = NULL;
- int use_askpass = 0, ttyfd;
+ char *askpass = NULL, *ret, buf[1024];
+ int rppflags, use_askpass = 0, ttyfd;
- if (from_stdin) {
+ rppflags = (flags & RP_ECHO) ? RPP_ECHO_ON : RPP_ECHO_OFF;
+ if (flags & RP_ALLOW_STDIN) {
if (!isatty(STDIN_FILENO))
use_askpass = 1;
} else {
- ttyfd = open("/dev/tty", O_RDWR);
+ rppflags |= RPP_REQUIRE_TTY;
+ ttyfd = open(_PATH_TTY, O_RDWR);
if (ttyfd >= 0)
close(ttyfd);
else
@@ -120,5 +120,10 @@ read_passphrase(char *prompt, int from_stdin)
return ssh_askpass(askpass, prompt);
}
- return cli_read_passphrase(prompt, from_stdin, 0);
+ if (readpassphrase(prompt, buf, sizeof buf, rppflags) == NULL)
+ return xstrdup("");
+
+ ret = xstrdup(buf);
+ memset(buf, 'x', sizeof buf);
+ return ret;
}
diff --git a/crypto/openssh/readpass.h b/crypto/openssh/readpass.h
index d8da448..229973c 100644
--- a/crypto/openssh/readpass.h
+++ b/crypto/openssh/readpass.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: readpass.h,v 1.2 2001/01/29 01:58:17 niklas Exp $ */
+/* $OpenBSD: readpass.h,v 1.6 2001/06/26 17:27:24 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -12,9 +12,7 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-/*
- * Reads a passphrase from /dev/tty with echo turned off. Returns the
- * passphrase (allocated with xmalloc). Exits if EOF is encountered. If
- * from_stdin is true, the passphrase will be read from stdin instead.
- */
-char *read_passphrase(char *prompt, int from_stdin);
+#define RP_ECHO 0x0001
+#define RP_ALLOW_STDIN 0x0002
+
+char *read_passphrase(const char *, int);
diff --git a/crypto/openssh/rijndael.c b/crypto/openssh/rijndael.c
index 98ecb55..a5d6804 100644
--- a/crypto/openssh/rijndael.c
+++ b/crypto/openssh/rijndael.c
@@ -1,412 +1,1242 @@
-/* $OpenBSD: rijndael.c,v 1.7 2001/02/04 15:32:24 stevesk Exp $ */
+/* $OpenBSD: rijndael.c,v 1.13 2001/12/19 07:18:56 deraadt Exp $ */
+
+/**
+ * rijndael-alg-fst.c
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdlib.h>
+#include <string.h>
-/* This is an independent implementation of the encryption algorithm: */
-/* */
-/* RIJNDAEL by Joan Daemen and Vincent Rijmen */
-/* */
-/* which is a candidate algorithm in the Advanced Encryption Standard */
-/* programme of the US National Institute of Standards and Technology. */
-/* */
-/* Copyright in this implementation is held by Dr B R Gladman but I */
-/* hereby give permission for its free direct or derivative use subject */
-/* to acknowledgment of its origin and compliance with any conditions */
-/* that the originators of the algorithm place on its exploitation. */
-/* */
-/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */
-
-/* Timing data for Rijndael (rijndael.c)
-
-Algorithm: rijndael (rijndael.c)
-
-128 bit key:
-Key Setup: 305/1389 cycles (encrypt/decrypt)
-Encrypt: 374 cycles = 68.4 mbits/sec
-Decrypt: 352 cycles = 72.7 mbits/sec
-Mean: 363 cycles = 70.5 mbits/sec
-
-192 bit key:
-Key Setup: 277/1595 cycles (encrypt/decrypt)
-Encrypt: 439 cycles = 58.3 mbits/sec
-Decrypt: 425 cycles = 60.2 mbits/sec
-Mean: 432 cycles = 59.3 mbits/sec
-
-256 bit key:
-Key Setup: 374/1960 cycles (encrypt/decrypt)
-Encrypt: 502 cycles = 51.0 mbits/sec
-Decrypt: 498 cycles = 51.4 mbits/sec
-Mean: 500 cycles = 51.2 mbits/sec
-
-*/
-
-#include <sys/types.h>
#include "rijndael.h"
-void gen_tabs __P((void));
-
-/* 3. Basic macros for speeding up generic operations */
-
-/* Circular rotate of 32 bit values */
-
-#define rotr(x,n) (((x) >> ((int)(n))) | ((x) << (32 - (int)(n))))
-#define rotl(x,n) (((x) << ((int)(n))) | ((x) >> (32 - (int)(n))))
-
-/* Invert byte order in a 32 bit variable */
-
-#define bswap(x) ((rotl(x, 8) & 0x00ff00ff) | (rotr(x, 8) & 0xff00ff00))
-
-/* Extract byte from a 32 bit quantity (little endian notation) */
-
-#define byte(x,n) ((u1byte)((x) >> (8 * n)))
-
-#if BYTE_ORDER != LITTLE_ENDIAN
-#define BYTE_SWAP
-#endif
-
-#ifdef BYTE_SWAP
-#define io_swap(x) bswap(x)
-#else
-#define io_swap(x) (x)
-#endif
-
-#define LARGE_TABLES
-
-u1byte pow_tab[256];
-u1byte log_tab[256];
-u1byte sbx_tab[256];
-u1byte isb_tab[256];
-u4byte rco_tab[ 10];
-u4byte ft_tab[4][256];
-u4byte it_tab[4][256];
-
-#ifdef LARGE_TABLES
- u4byte fl_tab[4][256];
- u4byte il_tab[4][256];
-#endif
-
-u4byte tab_gen = 0;
-
-#define ff_mult(a,b) (a && b ? pow_tab[(log_tab[a] + log_tab[b]) % 255] : 0)
-
-#define f_rn(bo, bi, n, k) \
- bo[n] = ft_tab[0][byte(bi[n],0)] ^ \
- ft_tab[1][byte(bi[(n + 1) & 3],1)] ^ \
- ft_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
- ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
-
-#define i_rn(bo, bi, n, k) \
- bo[n] = it_tab[0][byte(bi[n],0)] ^ \
- it_tab[1][byte(bi[(n + 3) & 3],1)] ^ \
- it_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
- it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
-
-#ifdef LARGE_TABLES
+#define FULL_UNROLL
-#define ls_box(x) \
- ( fl_tab[0][byte(x, 0)] ^ \
- fl_tab[1][byte(x, 1)] ^ \
- fl_tab[2][byte(x, 2)] ^ \
- fl_tab[3][byte(x, 3)] )
+/*
+Te0[x] = S [x].[02, 01, 01, 03];
+Te1[x] = S [x].[03, 02, 01, 01];
+Te2[x] = S [x].[01, 03, 02, 01];
+Te3[x] = S [x].[01, 01, 03, 02];
+Te4[x] = S [x].[01, 01, 01, 01];
-#define f_rl(bo, bi, n, k) \
- bo[n] = fl_tab[0][byte(bi[n],0)] ^ \
- fl_tab[1][byte(bi[(n + 1) & 3],1)] ^ \
- fl_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
- fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
-
-#define i_rl(bo, bi, n, k) \
- bo[n] = il_tab[0][byte(bi[n],0)] ^ \
- il_tab[1][byte(bi[(n + 3) & 3],1)] ^ \
- il_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
- il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
-
-#else
-
-#define ls_box(x) \
- ((u4byte)sbx_tab[byte(x, 0)] << 0) ^ \
- ((u4byte)sbx_tab[byte(x, 1)] << 8) ^ \
- ((u4byte)sbx_tab[byte(x, 2)] << 16) ^ \
- ((u4byte)sbx_tab[byte(x, 3)] << 24)
-
-#define f_rl(bo, bi, n, k) \
- bo[n] = (u4byte)sbx_tab[byte(bi[n],0)] ^ \
- rotl(((u4byte)sbx_tab[byte(bi[(n + 1) & 3],1)]), 8) ^ \
- rotl(((u4byte)sbx_tab[byte(bi[(n + 2) & 3],2)]), 16) ^ \
- rotl(((u4byte)sbx_tab[byte(bi[(n + 3) & 3],3)]), 24) ^ *(k + n)
-
-#define i_rl(bo, bi, n, k) \
- bo[n] = (u4byte)isb_tab[byte(bi[n],0)] ^ \
- rotl(((u4byte)isb_tab[byte(bi[(n + 3) & 3],1)]), 8) ^ \
- rotl(((u4byte)isb_tab[byte(bi[(n + 2) & 3],2)]), 16) ^ \
- rotl(((u4byte)isb_tab[byte(bi[(n + 1) & 3],3)]), 24) ^ *(k + n)
-
-#endif
-
-void
-gen_tabs(void)
-{
- u4byte i, t;
- u1byte p, q;
-
- /* log and power tables for GF(2**8) finite field with */
- /* 0x11b as modular polynomial - the simplest prmitive */
- /* root is 0x11, used here to generate the tables */
-
- for(i = 0,p = 1; i < 256; ++i) {
- pow_tab[i] = (u1byte)p; log_tab[p] = (u1byte)i;
-
- p = p ^ (p << 1) ^ (p & 0x80 ? 0x01b : 0);
- }
-
- log_tab[1] = 0; p = 1;
-
- for(i = 0; i < 10; ++i) {
- rco_tab[i] = p;
+Td0[x] = Si[x].[0e, 09, 0d, 0b];
+Td1[x] = Si[x].[0b, 0e, 09, 0d];
+Td2[x] = Si[x].[0d, 0b, 0e, 09];
+Td3[x] = Si[x].[09, 0d, 0b, 0e];
+Td4[x] = Si[x].[01, 01, 01, 01];
+*/
- p = (p << 1) ^ (p & 0x80 ? 0x1b : 0);
+static const u32 Te0[256] = {
+ 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
+ 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
+ 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
+ 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
+ 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
+ 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
+ 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
+ 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
+ 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
+ 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
+ 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
+ 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
+ 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
+ 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
+ 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
+ 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
+ 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
+ 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
+ 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
+ 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
+ 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
+ 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
+ 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
+ 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
+ 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
+ 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
+ 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
+ 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
+ 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
+ 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
+ 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
+ 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
+ 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
+ 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
+ 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
+ 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
+ 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
+ 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
+ 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
+ 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
+ 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
+ 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
+ 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
+ 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
+ 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
+ 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
+ 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
+ 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
+ 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
+ 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
+ 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
+ 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
+ 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
+ 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
+ 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
+ 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
+ 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
+ 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
+ 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
+ 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
+ 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
+ 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
+ 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
+ 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
+};
+static const u32 Te1[256] = {
+ 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
+ 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
+ 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
+ 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
+ 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
+ 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
+ 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
+ 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
+ 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
+ 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
+ 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
+ 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
+ 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
+ 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
+ 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
+ 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
+ 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
+ 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
+ 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
+ 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
+ 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
+ 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
+ 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
+ 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
+ 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
+ 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
+ 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
+ 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
+ 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
+ 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
+ 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
+ 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
+ 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
+ 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
+ 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
+ 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
+ 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
+ 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
+ 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
+ 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
+ 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
+ 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
+ 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
+ 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
+ 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
+ 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
+ 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
+ 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
+ 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
+ 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
+ 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
+ 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
+ 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
+ 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
+ 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
+ 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
+ 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
+ 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
+ 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
+ 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
+ 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
+ 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
+ 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
+ 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
+};
+static const u32 Te2[256] = {
+ 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
+ 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
+ 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
+ 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
+ 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
+ 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
+ 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
+ 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
+ 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
+ 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
+ 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
+ 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
+ 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
+ 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
+ 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
+ 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
+ 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
+ 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
+ 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
+ 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
+ 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
+ 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
+ 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
+ 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
+ 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
+ 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
+ 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
+ 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
+ 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
+ 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
+ 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
+ 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
+ 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
+ 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
+ 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
+ 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
+ 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
+ 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
+ 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
+ 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
+ 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
+ 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
+ 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
+ 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
+ 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
+ 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
+ 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
+ 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
+ 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
+ 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
+ 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
+ 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
+ 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
+ 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
+ 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
+ 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
+ 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
+ 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
+ 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
+ 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
+ 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
+ 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
+ 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
+ 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
+};
+static const u32 Te3[256] = {
+
+ 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
+ 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
+ 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
+ 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
+ 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
+ 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
+ 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
+ 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
+ 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
+ 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
+ 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
+ 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
+ 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
+ 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
+ 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
+ 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
+ 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
+ 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
+ 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
+ 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
+ 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
+ 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
+ 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
+ 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
+ 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
+ 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
+ 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
+ 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
+ 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
+ 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
+ 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
+ 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
+ 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
+ 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
+ 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
+ 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
+ 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
+ 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
+ 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
+ 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
+ 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
+ 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
+ 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
+ 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
+ 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
+ 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
+ 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
+ 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
+ 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
+ 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
+ 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
+ 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
+ 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
+ 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
+ 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
+ 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
+ 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
+ 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
+ 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
+ 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
+ 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
+ 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
+ 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
+ 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
+};
+static const u32 Te4[256] = {
+ 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
+ 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
+ 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
+ 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
+ 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
+ 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
+ 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
+ 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
+ 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
+ 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
+ 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
+ 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
+ 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
+ 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
+ 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
+ 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
+ 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
+ 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
+ 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
+ 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
+ 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
+ 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
+ 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
+ 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
+ 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
+ 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
+ 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
+ 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
+ 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
+ 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
+ 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
+ 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
+ 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
+ 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
+ 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
+ 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
+ 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
+ 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
+ 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
+ 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
+ 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
+ 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
+ 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
+ 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
+ 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
+ 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
+ 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
+ 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
+ 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
+ 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
+ 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
+ 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
+ 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
+ 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
+ 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
+ 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
+ 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
+ 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
+ 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
+ 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
+ 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
+ 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
+ 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
+ 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
+};
+static const u32 Td0[256] = {
+ 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
+ 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
+ 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
+ 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
+ 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
+ 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
+ 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
+ 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
+ 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
+ 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
+ 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
+ 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
+ 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
+ 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
+ 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
+ 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
+ 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
+ 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
+ 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
+ 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
+ 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
+ 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
+ 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
+ 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
+ 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
+ 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
+ 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
+ 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
+ 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
+ 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
+ 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
+ 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
+ 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
+ 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
+ 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
+ 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
+ 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
+ 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
+ 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
+ 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
+ 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
+ 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
+ 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
+ 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
+ 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
+ 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
+ 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
+ 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
+ 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
+ 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
+ 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
+ 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
+ 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
+ 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
+ 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
+ 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
+ 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
+ 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
+ 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
+ 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
+ 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
+ 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
+ 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
+ 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
+};
+static const u32 Td1[256] = {
+ 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
+ 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
+ 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
+ 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
+ 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
+ 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
+ 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
+ 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
+ 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
+ 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
+ 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
+ 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
+ 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
+ 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
+ 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
+ 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
+ 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
+ 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
+ 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
+ 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
+ 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
+ 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
+ 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
+ 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
+ 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
+ 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
+ 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
+ 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
+ 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
+ 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
+ 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
+ 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
+ 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
+ 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
+ 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
+ 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
+ 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
+ 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
+ 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
+ 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
+ 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
+ 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
+ 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
+ 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
+ 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
+ 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
+ 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
+ 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
+ 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
+ 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
+ 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
+ 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
+ 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
+ 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
+ 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
+ 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
+ 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
+ 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
+ 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
+ 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
+ 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
+ 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
+ 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
+ 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
+};
+static const u32 Td2[256] = {
+ 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
+ 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
+ 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
+ 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
+ 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
+ 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
+ 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
+ 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
+ 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
+ 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
+ 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
+ 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
+ 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
+ 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
+ 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
+ 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
+ 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
+ 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
+ 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
+ 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
+
+ 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
+ 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
+ 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
+ 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
+ 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
+ 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
+ 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
+ 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
+ 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
+ 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
+ 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
+ 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
+ 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
+ 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
+ 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
+ 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
+ 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
+ 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
+ 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
+ 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
+ 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
+ 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
+ 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
+ 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
+ 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
+ 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
+ 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
+ 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
+ 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
+ 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
+ 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
+ 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
+ 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
+ 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
+ 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
+ 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
+ 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
+ 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
+ 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
+ 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
+ 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
+ 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
+ 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
+ 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
+};
+static const u32 Td3[256] = {
+ 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
+ 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
+ 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
+ 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
+ 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
+ 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
+ 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
+ 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
+ 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
+ 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
+ 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
+ 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
+ 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
+ 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
+ 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
+ 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
+ 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
+ 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
+ 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
+ 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
+ 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
+ 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
+ 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
+ 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
+ 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
+ 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
+ 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
+ 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
+ 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
+ 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
+ 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
+ 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
+ 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
+ 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
+ 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
+ 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
+ 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
+ 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
+ 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
+ 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
+ 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
+ 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
+ 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
+ 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
+ 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
+ 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
+ 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
+ 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
+ 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
+ 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
+ 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
+ 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
+ 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
+ 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
+ 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
+ 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
+ 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
+ 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
+ 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
+ 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
+ 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
+ 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
+ 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
+ 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
+};
+static const u32 Td4[256] = {
+ 0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
+ 0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
+ 0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
+ 0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
+ 0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
+ 0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
+ 0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
+ 0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
+ 0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
+ 0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
+ 0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
+ 0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
+ 0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
+ 0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
+ 0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
+ 0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
+ 0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
+ 0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
+ 0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
+ 0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
+ 0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
+ 0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
+ 0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
+ 0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
+ 0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
+ 0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
+ 0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
+ 0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
+ 0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
+ 0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
+ 0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
+ 0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
+ 0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
+ 0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
+ 0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
+ 0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
+ 0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
+ 0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
+ 0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
+ 0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
+ 0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
+ 0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
+ 0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
+ 0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
+ 0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
+ 0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
+ 0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
+ 0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
+ 0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
+ 0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
+ 0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
+ 0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
+ 0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
+ 0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
+ 0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
+ 0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
+ 0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
+ 0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
+ 0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
+ 0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
+ 0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
+ 0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
+ 0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
+ 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
+};
+static const u32 rcon[] = {
+ 0x01000000, 0x02000000, 0x04000000, 0x08000000,
+ 0x10000000, 0x20000000, 0x40000000, 0x80000000,
+ 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
+};
+
+#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
+#define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
+
+/**
+ * Expand the cipher key into the encryption key schedule.
+ *
+ * @return the number of rounds for the given cipher key size.
+ */
+static int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) {
+ int i = 0;
+ u32 temp;
+
+ rk[0] = GETU32(cipherKey );
+ rk[1] = GETU32(cipherKey + 4);
+ rk[2] = GETU32(cipherKey + 8);
+ rk[3] = GETU32(cipherKey + 12);
+ if (keyBits == 128) {
+ for (;;) {
+ temp = rk[3];
+ rk[4] = rk[0] ^
+ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp ) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp >> 24) ] & 0x000000ff) ^
+ rcon[i];
+ rk[5] = rk[1] ^ rk[4];
+ rk[6] = rk[2] ^ rk[5];
+ rk[7] = rk[3] ^ rk[6];
+ if (++i == 10) {
+ return 10;
+ }
+ rk += 4;
+ }
}
-
- /* note that the affine byte transformation matrix in */
- /* rijndael specification is in big endian format with */
- /* bit 0 as the most significant bit. In the remainder */
- /* of the specification the bits are numbered from the */
- /* least significant end of a byte. */
-
- for(i = 0; i < 256; ++i) {
- p = (i ? pow_tab[255 - log_tab[i]] : 0); q = p;
- q = (q >> 7) | (q << 1); p ^= q;
- q = (q >> 7) | (q << 1); p ^= q;
- q = (q >> 7) | (q << 1); p ^= q;
- q = (q >> 7) | (q << 1); p ^= q ^ 0x63;
- sbx_tab[i] = (u1byte)p; isb_tab[p] = (u1byte)i;
+ rk[4] = GETU32(cipherKey + 16);
+ rk[5] = GETU32(cipherKey + 20);
+ if (keyBits == 192) {
+ for (;;) {
+ temp = rk[ 5];
+ rk[ 6] = rk[ 0] ^
+ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp ) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp >> 24) ] & 0x000000ff) ^
+ rcon[i];
+ rk[ 7] = rk[ 1] ^ rk[ 6];
+ rk[ 8] = rk[ 2] ^ rk[ 7];
+ rk[ 9] = rk[ 3] ^ rk[ 8];
+ if (++i == 8) {
+ return 12;
+ }
+ rk[10] = rk[ 4] ^ rk[ 9];
+ rk[11] = rk[ 5] ^ rk[10];
+ rk += 6;
+ }
}
-
- for(i = 0; i < 256; ++i) {
- p = sbx_tab[i];
-
-#ifdef LARGE_TABLES
-
- t = p; fl_tab[0][i] = t;
- fl_tab[1][i] = rotl(t, 8);
- fl_tab[2][i] = rotl(t, 16);
- fl_tab[3][i] = rotl(t, 24);
-#endif
- t = ((u4byte)ff_mult(2, p)) |
- ((u4byte)p << 8) |
- ((u4byte)p << 16) |
- ((u4byte)ff_mult(3, p) << 24);
-
- ft_tab[0][i] = t;
- ft_tab[1][i] = rotl(t, 8);
- ft_tab[2][i] = rotl(t, 16);
- ft_tab[3][i] = rotl(t, 24);
-
- p = isb_tab[i];
-
-#ifdef LARGE_TABLES
-
- t = p; il_tab[0][i] = t;
- il_tab[1][i] = rotl(t, 8);
- il_tab[2][i] = rotl(t, 16);
- il_tab[3][i] = rotl(t, 24);
-#endif
- t = ((u4byte)ff_mult(14, p)) |
- ((u4byte)ff_mult( 9, p) << 8) |
- ((u4byte)ff_mult(13, p) << 16) |
- ((u4byte)ff_mult(11, p) << 24);
-
- it_tab[0][i] = t;
- it_tab[1][i] = rotl(t, 8);
- it_tab[2][i] = rotl(t, 16);
- it_tab[3][i] = rotl(t, 24);
+ rk[6] = GETU32(cipherKey + 24);
+ rk[7] = GETU32(cipherKey + 28);
+ if (keyBits == 256) {
+ for (;;) {
+ temp = rk[ 7];
+ rk[ 8] = rk[ 0] ^
+ (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp ) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp >> 24) ] & 0x000000ff) ^
+ rcon[i];
+ rk[ 9] = rk[ 1] ^ rk[ 8];
+ rk[10] = rk[ 2] ^ rk[ 9];
+ rk[11] = rk[ 3] ^ rk[10];
+ if (++i == 7) {
+ return 14;
+ }
+ temp = rk[11];
+ rk[12] = rk[ 4] ^
+ (Te4[(temp >> 24) ] & 0xff000000) ^
+ (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(temp ) & 0xff] & 0x000000ff);
+ rk[13] = rk[ 5] ^ rk[12];
+ rk[14] = rk[ 6] ^ rk[13];
+ rk[15] = rk[ 7] ^ rk[14];
+ rk += 8;
+ }
}
-
- tab_gen = 1;
+ return 0;
}
-#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
-
-#define imix_col(y,x) \
- u = star_x(x); \
- v = star_x(u); \
- w = star_x(v); \
- t = w ^ (x); \
- (y) = u ^ v ^ w; \
- (y) ^= rotr(u ^ t, 8) ^ \
- rotr(v ^ t, 16) ^ \
- rotr(t,24)
-
-/* initialise the key schedule from the user supplied key */
-
-#define loop4(i) \
-{ t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \
- t ^= e_key[4 * i]; e_key[4 * i + 4] = t; \
- t ^= e_key[4 * i + 1]; e_key[4 * i + 5] = t; \
- t ^= e_key[4 * i + 2]; e_key[4 * i + 6] = t; \
- t ^= e_key[4 * i + 3]; e_key[4 * i + 7] = t; \
+/**
+ * Expand the cipher key into the decryption key schedule.
+ *
+ * @return the number of rounds for the given cipher key size.
+ */
+static int
+rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits,
+ int have_encrypt) {
+ int Nr, i, j;
+ u32 temp;
+
+ if (have_encrypt) {
+ Nr = have_encrypt;
+ } else {
+ /* expand the cipher key: */
+ Nr = rijndaelKeySetupEnc(rk, cipherKey, keyBits);
+ }
+ /* invert the order of the round keys: */
+ for (i = 0, j = 4*Nr; i < j; i += 4, j -= 4) {
+ temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
+ temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
+ temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
+ temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
+ }
+ /* apply the inverse MixColumn transform to all round keys but the first and the last: */
+ for (i = 1; i < Nr; i++) {
+ rk += 4;
+ rk[0] =
+ Td0[Te4[(rk[0] >> 24) ] & 0xff] ^
+ Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
+ Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^
+ Td3[Te4[(rk[0] ) & 0xff] & 0xff];
+ rk[1] =
+ Td0[Te4[(rk[1] >> 24) ] & 0xff] ^
+ Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
+ Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^
+ Td3[Te4[(rk[1] ) & 0xff] & 0xff];
+ rk[2] =
+ Td0[Te4[(rk[2] >> 24) ] & 0xff] ^
+ Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
+ Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^
+ Td3[Te4[(rk[2] ) & 0xff] & 0xff];
+ rk[3] =
+ Td0[Te4[(rk[3] >> 24) ] & 0xff] ^
+ Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
+ Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^
+ Td3[Te4[(rk[3] ) & 0xff] & 0xff];
+ }
+ return Nr;
}
-#define loop6(i) \
-{ t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \
- t ^= e_key[6 * i]; e_key[6 * i + 6] = t; \
- t ^= e_key[6 * i + 1]; e_key[6 * i + 7] = t; \
- t ^= e_key[6 * i + 2]; e_key[6 * i + 8] = t; \
- t ^= e_key[6 * i + 3]; e_key[6 * i + 9] = t; \
- t ^= e_key[6 * i + 4]; e_key[6 * i + 10] = t; \
- t ^= e_key[6 * i + 5]; e_key[6 * i + 11] = t; \
-}
+static void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16], u8 ct[16]) {
+ u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+ int r;
+#endif /* ?FULL_UNROLL */
+
+ /*
+ * map byte array block to cipher state
+ * and add initial round key:
+ */
+ s0 = GETU32(pt ) ^ rk[0];
+ s1 = GETU32(pt + 4) ^ rk[1];
+ s2 = GETU32(pt + 8) ^ rk[2];
+ s3 = GETU32(pt + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+ /* round 1: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
+ /* round 2: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
+ /* round 3: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
+ /* round 4: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
+ /* round 5: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
+ /* round 6: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
+ /* round 7: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
+ /* round 8: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
+ /* round 9: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
+ if (Nr > 10) {
+ /* round 10: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
+ /* round 11: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
+ if (Nr > 12) {
+ /* round 12: */
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
+ /* round 13: */
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
+ }
+ }
+ rk += Nr << 2;
+#else /* !FULL_UNROLL */
+ /*
+ * Nr - 1 full rounds:
+ */
+ r = Nr >> 1;
+ for (;;) {
+ t0 =
+ Te0[(s0 >> 24) ] ^
+ Te1[(s1 >> 16) & 0xff] ^
+ Te2[(s2 >> 8) & 0xff] ^
+ Te3[(s3 ) & 0xff] ^
+ rk[4];
+ t1 =
+ Te0[(s1 >> 24) ] ^
+ Te1[(s2 >> 16) & 0xff] ^
+ Te2[(s3 >> 8) & 0xff] ^
+ Te3[(s0 ) & 0xff] ^
+ rk[5];
+ t2 =
+ Te0[(s2 >> 24) ] ^
+ Te1[(s3 >> 16) & 0xff] ^
+ Te2[(s0 >> 8) & 0xff] ^
+ Te3[(s1 ) & 0xff] ^
+ rk[6];
+ t3 =
+ Te0[(s3 >> 24) ] ^
+ Te1[(s0 >> 16) & 0xff] ^
+ Te2[(s1 >> 8) & 0xff] ^
+ Te3[(s2 ) & 0xff] ^
+ rk[7];
+
+ rk += 8;
+ if (--r == 0) {
+ break;
+ }
-#define loop8(i) \
-{ t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \
- t ^= e_key[8 * i]; e_key[8 * i + 8] = t; \
- t ^= e_key[8 * i + 1]; e_key[8 * i + 9] = t; \
- t ^= e_key[8 * i + 2]; e_key[8 * i + 10] = t; \
- t ^= e_key[8 * i + 3]; e_key[8 * i + 11] = t; \
- t = e_key[8 * i + 4] ^ ls_box(t); \
- e_key[8 * i + 12] = t; \
- t ^= e_key[8 * i + 5]; e_key[8 * i + 13] = t; \
- t ^= e_key[8 * i + 6]; e_key[8 * i + 14] = t; \
- t ^= e_key[8 * i + 7]; e_key[8 * i + 15] = t; \
+ s0 =
+ Te0[(t0 >> 24) ] ^
+ Te1[(t1 >> 16) & 0xff] ^
+ Te2[(t2 >> 8) & 0xff] ^
+ Te3[(t3 ) & 0xff] ^
+ rk[0];
+ s1 =
+ Te0[(t1 >> 24) ] ^
+ Te1[(t2 >> 16) & 0xff] ^
+ Te2[(t3 >> 8) & 0xff] ^
+ Te3[(t0 ) & 0xff] ^
+ rk[1];
+ s2 =
+ Te0[(t2 >> 24) ] ^
+ Te1[(t3 >> 16) & 0xff] ^
+ Te2[(t0 >> 8) & 0xff] ^
+ Te3[(t1 ) & 0xff] ^
+ rk[2];
+ s3 =
+ Te0[(t3 >> 24) ] ^
+ Te1[(t0 >> 16) & 0xff] ^
+ Te2[(t1 >> 8) & 0xff] ^
+ Te3[(t2 ) & 0xff] ^
+ rk[3];
+ }
+#endif /* ?FULL_UNROLL */
+ /*
+ * apply last round and
+ * map cipher state to byte array block:
+ */
+ s0 =
+ (Te4[(t0 >> 24) ] & 0xff000000) ^
+ (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t3 ) & 0xff] & 0x000000ff) ^
+ rk[0];
+ PUTU32(ct , s0);
+ s1 =
+ (Te4[(t1 >> 24) ] & 0xff000000) ^
+ (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t0 ) & 0xff] & 0x000000ff) ^
+ rk[1];
+ PUTU32(ct + 4, s1);
+ s2 =
+ (Te4[(t2 >> 24) ] & 0xff000000) ^
+ (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t1 ) & 0xff] & 0x000000ff) ^
+ rk[2];
+ PUTU32(ct + 8, s2);
+ s3 =
+ (Te4[(t3 >> 24) ] & 0xff000000) ^
+ (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+ (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
+ (Te4[(t2 ) & 0xff] & 0x000000ff) ^
+ rk[3];
+ PUTU32(ct + 12, s3);
}
-rijndael_ctx *
-rijndael_set_key(rijndael_ctx *ctx, const u4byte *in_key, const u4byte key_len,
- int encrypt)
-{
- u4byte i, t, u, v, w;
- u4byte *e_key = ctx->e_key;
- u4byte *d_key = ctx->d_key;
-
- ctx->decrypt = !encrypt;
-
- if(!tab_gen)
- gen_tabs();
-
- ctx->k_len = (key_len + 31) / 32;
-
- e_key[0] = io_swap(in_key[0]); e_key[1] = io_swap(in_key[1]);
- e_key[2] = io_swap(in_key[2]); e_key[3] = io_swap(in_key[3]);
-
- switch(ctx->k_len) {
- case 4: t = e_key[3];
- for(i = 0; i < 10; ++i)
- loop4(i);
- break;
-
- case 6: e_key[4] = io_swap(in_key[4]); t = e_key[5] = io_swap(in_key[5]);
- for(i = 0; i < 8; ++i)
- loop6(i);
- break;
-
- case 8: e_key[4] = io_swap(in_key[4]); e_key[5] = io_swap(in_key[5]);
- e_key[6] = io_swap(in_key[6]); t = e_key[7] = io_swap(in_key[7]);
- for(i = 0; i < 7; ++i)
- loop8(i);
- break;
+static void rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16], u8 pt[16]) {
+ u32 s0, s1, s2, s3, t0, t1, t2, t3;
+#ifndef FULL_UNROLL
+ int r;
+#endif /* ?FULL_UNROLL */
+
+ /*
+ * map byte array block to cipher state
+ * and add initial round key:
+ */
+ s0 = GETU32(ct ) ^ rk[0];
+ s1 = GETU32(ct + 4) ^ rk[1];
+ s2 = GETU32(ct + 8) ^ rk[2];
+ s3 = GETU32(ct + 12) ^ rk[3];
+#ifdef FULL_UNROLL
+ /* round 1: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
+ /* round 2: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
+ /* round 3: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
+ /* round 4: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
+ /* round 5: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
+ /* round 6: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
+ /* round 7: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
+ /* round 8: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
+ /* round 9: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
+ if (Nr > 10) {
+ /* round 10: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
+ /* round 11: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
+ if (Nr > 12) {
+ /* round 12: */
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
+ /* round 13: */
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
}
-
- if (!encrypt) {
- d_key[0] = e_key[0]; d_key[1] = e_key[1];
- d_key[2] = e_key[2]; d_key[3] = e_key[3];
-
- for(i = 4; i < 4 * ctx->k_len + 24; ++i) {
- imix_col(d_key[i], e_key[i]);
- }
+ }
+ rk += Nr << 2;
+#else /* !FULL_UNROLL */
+ /*
+ * Nr - 1 full rounds:
+ */
+ r = Nr >> 1;
+ for (;;) {
+ t0 =
+ Td0[(s0 >> 24) ] ^
+ Td1[(s3 >> 16) & 0xff] ^
+ Td2[(s2 >> 8) & 0xff] ^
+ Td3[(s1 ) & 0xff] ^
+ rk[4];
+ t1 =
+ Td0[(s1 >> 24) ] ^
+ Td1[(s0 >> 16) & 0xff] ^
+ Td2[(s3 >> 8) & 0xff] ^
+ Td3[(s2 ) & 0xff] ^
+ rk[5];
+ t2 =
+ Td0[(s2 >> 24) ] ^
+ Td1[(s1 >> 16) & 0xff] ^
+ Td2[(s0 >> 8) & 0xff] ^
+ Td3[(s3 ) & 0xff] ^
+ rk[6];
+ t3 =
+ Td0[(s3 >> 24) ] ^
+ Td1[(s2 >> 16) & 0xff] ^
+ Td2[(s1 >> 8) & 0xff] ^
+ Td3[(s0 ) & 0xff] ^
+ rk[7];
+
+ rk += 8;
+ if (--r == 0) {
+ break;
}
- return ctx;
+ s0 =
+ Td0[(t0 >> 24) ] ^
+ Td1[(t3 >> 16) & 0xff] ^
+ Td2[(t2 >> 8) & 0xff] ^
+ Td3[(t1 ) & 0xff] ^
+ rk[0];
+ s1 =
+ Td0[(t1 >> 24) ] ^
+ Td1[(t0 >> 16) & 0xff] ^
+ Td2[(t3 >> 8) & 0xff] ^
+ Td3[(t2 ) & 0xff] ^
+ rk[1];
+ s2 =
+ Td0[(t2 >> 24) ] ^
+ Td1[(t1 >> 16) & 0xff] ^
+ Td2[(t0 >> 8) & 0xff] ^
+ Td3[(t3 ) & 0xff] ^
+ rk[2];
+ s3 =
+ Td0[(t3 >> 24) ] ^
+ Td1[(t2 >> 16) & 0xff] ^
+ Td2[(t1 >> 8) & 0xff] ^
+ Td3[(t0 ) & 0xff] ^
+ rk[3];
+ }
+#endif /* ?FULL_UNROLL */
+ /*
+ * apply last round and
+ * map cipher state to byte array block:
+ */
+ s0 =
+ (Td4[(t0 >> 24) ] & 0xff000000) ^
+ (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(t1 ) & 0xff] & 0x000000ff) ^
+ rk[0];
+ PUTU32(pt , s0);
+ s1 =
+ (Td4[(t1 >> 24) ] & 0xff000000) ^
+ (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(t2 ) & 0xff] & 0x000000ff) ^
+ rk[1];
+ PUTU32(pt + 4, s1);
+ s2 =
+ (Td4[(t2 >> 24) ] & 0xff000000) ^
+ (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(t3 ) & 0xff] & 0x000000ff) ^
+ rk[2];
+ PUTU32(pt + 8, s2);
+ s3 =
+ (Td4[(t3 >> 24) ] & 0xff000000) ^
+ (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
+ (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
+ (Td4[(t0 ) & 0xff] & 0x000000ff) ^
+ rk[3];
+ PUTU32(pt + 12, s3);
}
-/* encrypt a block of text */
-
-#define f_nround(bo, bi, k) \
- f_rn(bo, bi, 0, k); \
- f_rn(bo, bi, 1, k); \
- f_rn(bo, bi, 2, k); \
- f_rn(bo, bi, 3, k); \
- k += 4
-
-#define f_lround(bo, bi, k) \
- f_rl(bo, bi, 0, k); \
- f_rl(bo, bi, 1, k); \
- f_rl(bo, bi, 2, k); \
- f_rl(bo, bi, 3, k)
-
void
-rijndael_encrypt(rijndael_ctx *ctx, const u4byte *in_blk, u4byte *out_blk)
+rijndael_set_key(rijndael_ctx *ctx, u_char *key, int bits, int encrypt)
{
- u4byte k_len = ctx->k_len;
- u4byte *e_key = ctx->e_key;
- u4byte b0[4], b1[4], *kp;
-
- b0[0] = io_swap(in_blk[0]) ^ e_key[0];
- b0[1] = io_swap(in_blk[1]) ^ e_key[1];
- b0[2] = io_swap(in_blk[2]) ^ e_key[2];
- b0[3] = io_swap(in_blk[3]) ^ e_key[3];
-
- kp = e_key + 4;
-
- if(k_len > 6) {
- f_nround(b1, b0, kp); f_nround(b0, b1, kp);
- }
-
- if(k_len > 4) {
- f_nround(b1, b0, kp); f_nround(b0, b1, kp);
+ ctx->Nr = rijndaelKeySetupEnc(ctx->ek, key, bits);
+ if (encrypt) {
+ ctx->decrypt = 0;
+ memset(ctx->dk, 0, sizeof(ctx->dk));
+ } else {
+ ctx->decrypt = 1;
+ memcpy(ctx->dk, ctx->ek, sizeof(ctx->ek));
+ rijndaelKeySetupDec(ctx->dk, key, bits, ctx->Nr);
}
-
- f_nround(b1, b0, kp); f_nround(b0, b1, kp);
- f_nround(b1, b0, kp); f_nround(b0, b1, kp);
- f_nround(b1, b0, kp); f_nround(b0, b1, kp);
- f_nround(b1, b0, kp); f_nround(b0, b1, kp);
- f_nround(b1, b0, kp); f_lround(b0, b1, kp);
-
- out_blk[0] = io_swap(b0[0]); out_blk[1] = io_swap(b0[1]);
- out_blk[2] = io_swap(b0[2]); out_blk[3] = io_swap(b0[3]);
}
-/* decrypt a block of text */
-
-#define i_nround(bo, bi, k) \
- i_rn(bo, bi, 0, k); \
- i_rn(bo, bi, 1, k); \
- i_rn(bo, bi, 2, k); \
- i_rn(bo, bi, 3, k); \
- k -= 4
-
-#define i_lround(bo, bi, k) \
- i_rl(bo, bi, 0, k); \
- i_rl(bo, bi, 1, k); \
- i_rl(bo, bi, 2, k); \
- i_rl(bo, bi, 3, k)
-
void
-rijndael_decrypt(rijndael_ctx *ctx, const u4byte *in_blk, u4byte *out_blk)
+rijndael_decrypt(rijndael_ctx *ctx, u_char *src, u_char *dst)
{
- u4byte b0[4], b1[4], *kp;
- u4byte k_len = ctx->k_len;
- u4byte *e_key = ctx->e_key;
- u4byte *d_key = ctx->d_key;
-
- b0[0] = io_swap(in_blk[0]) ^ e_key[4 * k_len + 24];
- b0[1] = io_swap(in_blk[1]) ^ e_key[4 * k_len + 25];
- b0[2] = io_swap(in_blk[2]) ^ e_key[4 * k_len + 26];
- b0[3] = io_swap(in_blk[3]) ^ e_key[4 * k_len + 27];
-
- kp = d_key + 4 * (k_len + 5);
-
- if(k_len > 6) {
- i_nround(b1, b0, kp); i_nround(b0, b1, kp);
- }
-
- if(k_len > 4) {
- i_nround(b1, b0, kp); i_nround(b0, b1, kp);
- }
-
- i_nround(b1, b0, kp); i_nround(b0, b1, kp);
- i_nround(b1, b0, kp); i_nround(b0, b1, kp);
- i_nround(b1, b0, kp); i_nround(b0, b1, kp);
- i_nround(b1, b0, kp); i_nround(b0, b1, kp);
- i_nround(b1, b0, kp); i_lround(b0, b1, kp);
+ rijndaelDecrypt(ctx->dk, ctx->Nr, src, dst);
+}
- out_blk[0] = io_swap(b0[0]); out_blk[1] = io_swap(b0[1]);
- out_blk[2] = io_swap(b0[2]); out_blk[3] = io_swap(b0[3]);
+void
+rijndael_encrypt(rijndael_ctx *ctx, u_char *src, u_char *dst)
+{
+ rijndaelEncrypt(ctx->ek, ctx->Nr, src, dst);
}
diff --git a/crypto/openssh/rijndael.h b/crypto/openssh/rijndael.h
index 66e0bbe..c614bb1 100644
--- a/crypto/openssh/rijndael.h
+++ b/crypto/openssh/rijndael.h
@@ -1,47 +1,51 @@
-/* $OpenBSD: rijndael.h,v 1.7 2001/03/01 03:38:33 deraadt Exp $ */
-
-/* This is an independent implementation of the encryption algorithm: */
-/* */
-/* RIJNDAEL by Joan Daemen and Vincent Rijmen */
-/* */
-/* which is a candidate algorithm in the Advanced Encryption Standard */
-/* programme of the US National Institute of Standards and Technology. */
-/* */
-/* Copyright in this implementation is held by Dr B R Gladman but I */
-/* hereby give permission for its free direct or derivative use subject */
-/* to acknowledgment of its origin and compliance with any conditions */
-/* that the originators of the algorithm place on its exploitation. */
-/* */
-/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */
-
-#ifndef _RIJNDAEL_H_
-#define _RIJNDAEL_H_
-
-/* 1. Standard types for AES cryptography source code */
-
-typedef u_int8_t u1byte; /* an 8 bit unsigned character type */
-typedef u_int16_t u2byte; /* a 16 bit unsigned integer type */
-typedef u_int32_t u4byte; /* a 32 bit unsigned integer type */
-
-typedef int8_t s1byte; /* an 8 bit signed character type */
-typedef int16_t s2byte; /* a 16 bit signed integer type */
-typedef int32_t s4byte; /* a 32 bit signed integer type */
-
-typedef struct _rijndael_ctx {
- u4byte k_len;
- int decrypt;
- u4byte e_key[64];
- u4byte d_key[64];
+/* $OpenBSD: rijndael.h,v 1.12 2001/12/19 07:18:56 deraadt Exp $ */
+
+/**
+ * rijndael-alg-fst.h
+ *
+ * @version 3.0 (December 2000)
+ *
+ * Optimised ANSI C code for the Rijndael cipher (now AES)
+ *
+ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
+ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
+ * @author Paulo Barreto <paulo.barreto@terra.com.br>
+ *
+ * This code is hereby placed in the public domain.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __RIJNDAEL_H
+#define __RIJNDAEL_H
+
+#define MAXKC (256/32)
+#define MAXKB (256/8)
+#define MAXNR 14
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int u32;
+
+/* The structure for key information */
+typedef struct {
+ int decrypt;
+ int Nr; /* key-length-dependent number of rounds */
+ u32 ek[4*(MAXNR + 1)]; /* encrypt key schedule */
+ u32 dk[4*(MAXNR + 1)]; /* decrypt key schedule */
} rijndael_ctx;
+void rijndael_set_key(rijndael_ctx *, u_char *, int, int);
+void rijndael_decrypt(rijndael_ctx *, u_char *, u_char *);
+void rijndael_encrypt(rijndael_ctx *, u_char *, u_char *);
-/* 2. Standard interface for AES cryptographic routines */
-
-/* These are all based on 32 bit unsigned values and will therefore */
-/* require endian conversions for big-endian architectures */
-
-rijndael_ctx *rijndael_set_key __P((rijndael_ctx *, const u4byte *, u4byte, int));
-void rijndael_encrypt __P((rijndael_ctx *, const u4byte *, u4byte *));
-void rijndael_decrypt __P((rijndael_ctx *, const u4byte *, u4byte *));
-
-#endif /* _RIJNDAEL_H_ */
+#endif /* __RIJNDAEL_H */
diff --git a/crypto/openssh/scard.c b/crypto/openssh/scard.c
new file mode 100644
index 0000000..e1b1fb6
--- /dev/null
+++ b/crypto/openssh/scard.c
@@ -0,0 +1,372 @@
+/*
+ * Copyright (c) 2001 Markus Friedl. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef SMARTCARD
+#include "includes.h"
+RCSID("$OpenBSD: scard.c,v 1.17 2001/12/27 18:22:16 markus Exp $");
+
+#include <openssl/engine.h>
+#include <sectok.h>
+
+#include "key.h"
+#include "log.h"
+#include "xmalloc.h"
+#include "scard.h"
+
+#define CLA_SSH 0x05
+#define INS_DECRYPT 0x10
+#define INS_GET_KEYLENGTH 0x20
+#define INS_GET_PUBKEY 0x30
+#define INS_GET_RESPONSE 0xc0
+
+#define MAX_BUF_SIZE 256
+
+static int sc_fd = -1;
+static char *sc_reader_id = NULL;
+static int cla = 0x00; /* class */
+
+/* interface to libsectok */
+
+static int
+sc_open(void)
+{
+ int sw;
+
+ if (sc_fd >= 0)
+ return sc_fd;
+
+ sc_fd = sectok_friendly_open(sc_reader_id, STONOWAIT, &sw);
+ if (sc_fd < 0) {
+ error("sectok_open failed: %s", sectok_get_sw(sw));
+ return SCARD_ERROR_FAIL;
+ }
+ if (! sectok_cardpresent(sc_fd)) {
+ debug("smartcard in reader %s not present, skipping",
+ sc_reader_id);
+ sc_close();
+ return SCARD_ERROR_NOCARD;
+ }
+ if (sectok_reset(sc_fd, 0, NULL, &sw) <= 0) {
+ error("sectok_reset failed: %s", sectok_get_sw(sw));
+ sc_fd = -1;
+ return SCARD_ERROR_FAIL;
+ }
+ if ((cla = cyberflex_inq_class(sc_fd)) < 0)
+ cla = 0;
+
+ debug("sc_open ok %d", sc_fd);
+ return sc_fd;
+}
+
+static int
+sc_enable_applet(void)
+{
+ static u_char aid[] = {0xfc, 0x53, 0x73, 0x68, 0x2e, 0x62, 0x69, 0x6e};
+ int sw = 0;
+
+ /* select applet id */
+ sectok_apdu(sc_fd, cla, 0xa4, 0x04, 0, sizeof aid, aid, 0, NULL, &sw);
+ if (!sectok_swOK(sw)) {
+ error("sectok_apdu failed: %s", sectok_get_sw(sw));
+ sc_close();
+ return -1;
+ }
+ return 0;
+}
+
+static int
+sc_init(void)
+{
+ int status;
+
+ status = sc_open();
+ if (status == SCARD_ERROR_NOCARD) {
+ return SCARD_ERROR_NOCARD;
+ }
+ if (status < 0 ) {
+ error("sc_open failed");
+ return status;
+ }
+ if (sc_enable_applet() < 0) {
+ error("sc_enable_applet failed");
+ return SCARD_ERROR_APPLET;
+ }
+ return 0;
+}
+
+static int
+sc_read_pubkey(Key * k)
+{
+ u_char buf[2], *n;
+ char *p;
+ int len, sw, status = -1;
+
+ len = sw = 0;
+ n = NULL;
+
+ if (sc_fd < 0) {
+ status = sc_init();
+ if (status < 0 )
+ goto err;
+ }
+
+ /* get key size */
+ sectok_apdu(sc_fd, CLA_SSH, INS_GET_KEYLENGTH, 0, 0, 0, NULL,
+ sizeof(buf), buf, &sw);
+ if (!sectok_swOK(sw)) {
+ error("could not obtain key length: %s", sectok_get_sw(sw));
+ goto err;
+ }
+ len = (buf[0] << 8) | buf[1];
+ len /= 8;
+ debug("INS_GET_KEYLENGTH: len %d sw %s", len, sectok_get_sw(sw));
+
+ n = xmalloc(len);
+ /* get n */
+ sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw);
+ if (!sectok_swOK(sw)) {
+ error("could not obtain public key: %s", sectok_get_sw(sw));
+ goto err;
+ }
+
+ debug("INS_GET_KEYLENGTH: sw %s", sectok_get_sw(sw));
+
+ if (BN_bin2bn(n, len, k->rsa->n) == NULL) {
+ error("c_read_pubkey: BN_bin2bn failed");
+ goto err;
+ }
+
+ /* currently the java applet just stores 'n' */
+ if (!BN_set_word(k->rsa->e, 35)) {
+ error("c_read_pubkey: BN_set_word(e, 35) failed");
+ goto err;
+ }
+
+ status = 0;
+ p = key_fingerprint(k, SSH_FP_MD5, SSH_FP_HEX);
+ debug("fingerprint %d %s", key_size(k), p);
+ xfree(p);
+
+err:
+ if (n != NULL)
+ xfree(n);
+ sc_close();
+ return status;
+}
+
+/* private key operations */
+
+static int
+sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding)
+{
+ u_char *padded = NULL;
+ int sw, len, olen, status = -1;
+
+ debug("sc_private_decrypt called");
+
+ olen = len = sw = 0;
+ if (sc_fd < 0) {
+ status = sc_init();
+ if (status < 0 )
+ goto err;
+ }
+ if (padding != RSA_PKCS1_PADDING)
+ goto err;
+
+ len = BN_num_bytes(rsa->n);
+ padded = xmalloc(len);
+
+ sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, 0, NULL, &sw);
+ if (!sectok_swOK(sw)) {
+ error("sc_private_decrypt: INS_DECRYPT failed: %s",
+ sectok_get_sw(sw));
+ goto err;
+ }
+ sectok_apdu(sc_fd, CLA_SSH, INS_GET_RESPONSE, 0, 0, 0, NULL,
+ len, padded, &sw);
+ if (!sectok_swOK(sw)) {
+ error("sc_private_decrypt: INS_GET_RESPONSE failed: %s",
+ sectok_get_sw(sw));
+ goto err;
+ }
+ olen = RSA_padding_check_PKCS1_type_2(to, len, padded + 1, len - 1,
+ len);
+err:
+ if (padded)
+ xfree(padded);
+ sc_close();
+ return (olen >= 0 ? olen : status);
+}
+
+static int
+sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding)
+{
+ u_char *padded = NULL;
+ int sw, len, status = -1;
+
+ len = sw = 0;
+ if (sc_fd < 0) {
+ status = sc_init();
+ if (status < 0 )
+ goto err;
+ }
+ if (padding != RSA_PKCS1_PADDING)
+ goto err;
+
+ debug("sc_private_encrypt called");
+ len = BN_num_bytes(rsa->n);
+ padded = xmalloc(len);
+
+ if (RSA_padding_add_PKCS1_type_1(padded, len, from, flen) <= 0) {
+ error("RSA_padding_add_PKCS1_type_1 failed");
+ goto err;
+ }
+ sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, 0, NULL, &sw);
+ if (!sectok_swOK(sw)) {
+ error("sc_private_decrypt: INS_DECRYPT failed: %s",
+ sectok_get_sw(sw));
+ goto err;
+ }
+ sectok_apdu(sc_fd, CLA_SSH, INS_GET_RESPONSE, 0, 0, 0, NULL,
+ len, to, &sw);
+ if (!sectok_swOK(sw)) {
+ error("sc_private_decrypt: INS_GET_RESPONSE failed: %s",
+ sectok_get_sw(sw));
+ goto err;
+ }
+err:
+ if (padded)
+ xfree(padded);
+ sc_close();
+ return (len >= 0 ? len : status);
+}
+
+/* called on free */
+
+static int (*orig_finish)(RSA *rsa) = NULL;
+
+static int
+sc_finish(RSA *rsa)
+{
+ if (orig_finish)
+ orig_finish(rsa);
+ sc_close();
+ return 1;
+}
+
+
+/* engine for overloading private key operations */
+
+static ENGINE *smart_engine = NULL;
+static RSA_METHOD smart_rsa =
+{
+ "sectok",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ NULL,
+};
+
+ENGINE *
+sc_get_engine(void)
+{
+ RSA_METHOD *def;
+
+ def = RSA_get_default_openssl_method();
+
+ /* overload */
+ smart_rsa.rsa_priv_enc = sc_private_encrypt;
+ smart_rsa.rsa_priv_dec = sc_private_decrypt;
+
+ /* save original */
+ orig_finish = def->finish;
+ smart_rsa.finish = sc_finish;
+
+ /* just use the OpenSSL version */
+ smart_rsa.rsa_pub_enc = def->rsa_pub_enc;
+ smart_rsa.rsa_pub_dec = def->rsa_pub_dec;
+ smart_rsa.rsa_mod_exp = def->rsa_mod_exp;
+ smart_rsa.bn_mod_exp = def->bn_mod_exp;
+ smart_rsa.init = def->init;
+ smart_rsa.flags = def->flags;
+ smart_rsa.app_data = def->app_data;
+ smart_rsa.rsa_sign = def->rsa_sign;
+ smart_rsa.rsa_verify = def->rsa_verify;
+
+ if ((smart_engine = ENGINE_new()) == NULL)
+ fatal("ENGINE_new failed");
+
+ ENGINE_set_id(smart_engine, "sectok");
+ ENGINE_set_name(smart_engine, "libsectok");
+ ENGINE_set_RSA(smart_engine, &smart_rsa);
+ ENGINE_set_DSA(smart_engine, DSA_get_default_openssl_method());
+ ENGINE_set_DH(smart_engine, DH_get_default_openssl_method());
+ ENGINE_set_RAND(smart_engine, RAND_SSLeay());
+ ENGINE_set_BN_mod_exp(smart_engine, BN_mod_exp);
+
+ return smart_engine;
+}
+
+void
+sc_close(void)
+{
+ if (sc_fd >= 0) {
+ sectok_close(sc_fd);
+ sc_fd = -1;
+ }
+}
+
+Key *
+sc_get_key(const char *id)
+{
+ Key *k;
+ int status;
+
+ if (sc_reader_id != NULL)
+ xfree(sc_reader_id);
+ sc_reader_id = xstrdup(id);
+
+ k = key_new(KEY_RSA);
+ if (k == NULL) {
+ return NULL;
+ }
+ status = sc_read_pubkey(k);
+ if (status == SCARD_ERROR_NOCARD) {
+ key_free(k);
+ return NULL;
+ }
+ if (status < 0 ) {
+ error("sc_read_pubkey failed");
+ key_free(k);
+ return NULL;
+ }
+ return k;
+}
+#endif /* SMARTCARD */
diff --git a/crypto/openssh/scard.h b/crypto/openssh/scard.h
new file mode 100644
index 0000000..6ca9916
--- /dev/null
+++ b/crypto/openssh/scard.h
@@ -0,0 +1,40 @@
+/* $OpenBSD: scard.h,v 1.7 2002/03/04 17:27:39 stevesk Exp $ */
+
+/*
+ * Copyright (c) 2001 Markus Friedl. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <openssl/engine.h>
+
+#ifndef SCARD_H
+#define SCARD_H
+
+#define SCARD_ERROR_FAIL -1
+#define SCARD_ERROR_NOCARD -2
+#define SCARD_ERROR_APPLET -3
+
+Key *sc_get_key(const char*);
+ENGINE *sc_get_engine(void);
+void sc_close(void);
+
+#endif
diff --git a/crypto/openssh/scard/Makefile b/crypto/openssh/scard/Makefile
new file mode 100644
index 0000000..1cf7bbd
--- /dev/null
+++ b/crypto/openssh/scard/Makefile
@@ -0,0 +1,20 @@
+# $OpenBSD: Makefile,v 1.2 2001/06/29 07:02:09 markus Exp $
+
+.PATH: ${.CURDIR}/..
+
+CARDLET= Ssh.bin
+DATADIR= /usr/libdata/ssh
+
+all: ${CARDLET}
+
+clean:
+ rm -f ${CARDLET}
+
+install: ${CARDLET}
+ install -c -m ${LIBMODE} -o ${LIBOWN} -g ${LIBGRP} \
+ ${CARDLET} ${DESTDIR}${DATADIR}
+
+Ssh.bin: ${.CURDIR}/Ssh.bin.uu
+ uudecode ${.CURDIR}/$@.uu
+
+.include <bsd.prog.mk>
diff --git a/crypto/openssh/scard/Ssh.bin.uu b/crypto/openssh/scard/Ssh.bin.uu
new file mode 100644
index 0000000..1062e21
--- /dev/null
+++ b/crypto/openssh/scard/Ssh.bin.uu
@@ -0,0 +1,16 @@
+begin 644 Ssh.bin
+M`P)!%P`501P`;``!`C@"`/Y@\`4`_J'P!0!!%T$;`?Z@\`4`01=!&@'^>/,!
+M`4$701P!_G#S%P'^0],1`?Y@\!0`_G/S'0#^<]4``D$7L`4`_F'3``!!%T$9
+M`?YATP4`_G/5"P7^8=,'`OZAT`$!_J#0$@1!%T$8`0```$$7!`$&`/Y@`;@`
+M`$$8\`H(`$$9\`H``$$:\@\``$$;\B$``$$<\A```/`&__(```0(`!8```9C
+M""T#"<(H+00$*"T%""A;`&19``#P$/_R`P(&`0#(```38`!!70!&$UP`1@09
+M":1+``D*D`!@`"@37`!&!!E6`````*(````$____P````*$````0````*@``
+M`"````"-````,````&H37`!&`QD(2@`)"FX`8``H$UP`1@<9"@#_/2!@`$L1
+M2@`)"F<`8``H$UP`'A-<`$8($1-<`$8(7@!0"!%@`%59"C\`8`!:*PIS:&``
+M6BL37`!&`P,*`(!@`%\K`PH`@&``55D37`!&`P<H$UP`1@0#*`,%8`!565D*
+M;0!@`"A9`/`"__(!`0$)``@```J0`&``*%D`\!/_\@$!`@D`#```8D$7+5\`
+M/"M9````\!+_]@$!`P$`&```$UP`'EX`,D4`#Q-<`!X*`,@)$%X`-P17L`7_
+M\@$!!`(`/```$U\``!-B_J$M7P`%70`*$V+^H"U?``]=`!038OYX+0H$`%\`
+<&5T`'@H$`&``(T4`"0IG`&``*!->`"U9````````
+`
+end
diff --git a/crypto/openssh/scard/Ssh.java b/crypto/openssh/scard/Ssh.java
new file mode 100644
index 0000000..3692b9b
--- /dev/null
+++ b/crypto/openssh/scard/Ssh.java
@@ -0,0 +1,143 @@
+// $Id: Ssh.java,v 1.2 2001/07/30 20:08:14 rees Exp $
+//
+// Ssh.java
+// SSH / smartcard integration project, smartcard side
+//
+// Tomoko Fukuzawa, created, Feb., 2000
+//
+// Naomaru Itoi, modified, Apr., 2000
+//
+
+// copyright 2000
+// the regents of the university of michigan
+// all rights reserved
+//
+// permission is granted to use, copy, create derivative works
+// and redistribute this software and such derivative works
+// for any purpose, so long as the name of the university of
+// michigan is not used in any advertising or publicity
+// pertaining to the use or distribution of this software
+// without specific, written prior authorization. if the
+// above copyright notice or any other identification of the
+// university of michigan is included in any copy of any
+// portion of this software, then the disclaimer below must
+// also be included.
+//
+// this software is provided as is, without representation
+// from the university of michigan as to its fitness for any
+// purpose, and without warranty by the university of
+// michigan of any kind, either express or implied, including
+// without limitation the implied warranties of
+// merchantability and fitness for a particular purpose. the
+// regents of the university of michigan shall not be liable
+// for any damages, including special, indirect, incidental, or
+// consequential damages, with respect to any claim arising
+// out of or in connection with the use of the software, even
+// if it has been or is hereafter advised of the possibility of
+// such damages.
+
+import javacard.framework.*;
+import javacardx.framework.*;
+import javacardx.crypto.*;
+
+public class Ssh extends javacard.framework.Applet
+{
+ /* constants declaration */
+ // code of CLA byte in the command APDU header
+ static final byte Ssh_CLA =(byte)0x05;
+
+ // codes of INS byte in the command APDU header
+ static final byte DECRYPT = (byte) 0x10;
+ static final byte GET_KEYLENGTH = (byte) 0x20;
+ static final byte GET_PUBKEY = (byte) 0x30;
+ static final byte GET_RESPONSE = (byte) 0xc0;
+
+ /* instance variables declaration */
+ static final short keysize = 1024;
+
+ //RSA_CRT_PrivateKey rsakey;
+ AsymKey rsakey;
+ CyberflexFile file;
+ CyberflexOS os;
+
+ byte buffer[];
+
+ static byte[] keyHdr = {(byte)0xC2, (byte)0x01, (byte)0x05};
+
+ private Ssh()
+ {
+ file = new CyberflexFile();
+ os = new CyberflexOS();
+
+ rsakey = new RSA_CRT_PrivateKey (keysize);
+
+ if ( ! rsakey.isSupportedLength (keysize) )
+ ISOException.throwIt (ISO.SW_WRONG_LENGTH);
+
+ register();
+ } // end of the constructor
+
+ public boolean select() {
+ if (!rsakey.isInitialized())
+ rsakey.setKeyInstance ((short)0xc8, (short)0x10);
+
+ return true;
+ }
+
+ public static void install(APDU apdu)
+ {
+ new Ssh(); // create a Ssh applet instance (card)
+ } // end of install method
+
+ public static void main(String args[]) {
+ ISOException.throwIt((short) 0x9000);
+ }
+
+ public void process(APDU apdu)
+ {
+ // APDU object carries a byte array (buffer) to
+ // transfer incoming and outgoing APDU header
+ // and data bytes between card and CAD
+ buffer = apdu.getBuffer();
+
+ // verify that if the applet can accept this
+ // APDU message
+ // NI: change suggested by Wayne Dyksen, Purdue
+ if (buffer[ISO.OFFSET_INS] == ISO.INS_SELECT)
+ ISOException.throwIt(ISO.SW_NO_ERROR);
+
+ switch (buffer[ISO.OFFSET_INS]) {
+ case DECRYPT:
+ if (buffer[ISO.OFFSET_CLA] != Ssh_CLA)
+ ISOException.throwIt(ISO.SW_CLA_NOT_SUPPORTED);
+ //decrypt (apdu);
+ short size = (short) (buffer[ISO.OFFSET_LC] & 0x00FF);
+
+ if (apdu.setIncomingAndReceive() != size)
+ ISOException.throwIt (ISO.SW_WRONG_LENGTH);
+
+ rsakey.cryptoUpdate (buffer, (short) ISO.OFFSET_CDATA, size,
+ buffer, (short) ISO.OFFSET_CDATA);
+
+ apdu.setOutgoingAndSend ((short) ISO.OFFSET_CDATA, size);
+ return;
+ case GET_PUBKEY:
+ file.selectFile((short)(0x3f<<8)); // select root
+ file.selectFile((short)(('s'<<8)|'h')); // select public key file
+ os.readBinaryFile (buffer, (short)0, (short)0, (short)(keysize/8));
+ apdu.setOutgoingAndSend((short)0, (short)(keysize/8));
+ return;
+ case GET_KEYLENGTH:
+ buffer[0] = (byte)((keysize >> 8) & 0xff);
+ buffer[1] = (byte)(keysize & 0xff);
+ apdu.setOutgoingAndSend ((short)0, (short)2);
+ return;
+ case GET_RESPONSE:
+ return;
+ default:
+ ISOException.throwIt (ISO.SW_INS_NOT_SUPPORTED);
+ }
+
+ } // end of process method
+
+} // end of class Ssh
diff --git a/crypto/openssh/scp.1 b/crypto/openssh/scp.1
index 10e67aa3..69125c1 100644
--- a/crypto/openssh/scp.1
+++ b/crypto/openssh/scp.1
@@ -9,7 +9,7 @@
.\"
.\" Created: Sun May 7 00:14:37 1995 ylo
.\"
-.\" $OpenBSD: scp.1,v 1.14 2001/02/04 11:11:53 djm Exp $
+.\" $OpenBSD: scp.1,v 1.21 2002/01/29 23:50:37 markus Exp $
.\"
.Dd September 25, 1999
.Dt SCP 1
@@ -19,12 +19,13 @@
.Nd secure copy (remote file copy program)
.Sh SYNOPSIS
.Nm scp
-.Op Fl pqrvC46
+.Op Fl pqrvBC46
+.Op Fl F Ar ssh_config
.Op Fl S Ar program
.Op Fl P Ar port
.Op Fl c Ar cipher
.Op Fl i Ar identity_file
-.Op Fl o Ar option
+.Op Fl o Ar ssh_option
.Sm off
.Oo
.Op Ar user@
@@ -92,6 +93,12 @@ Passes the
flag to
.Xr ssh 1
to enable compression.
+.It Fl F Ar ssh_config
+Specifies an alternative
+per-user configuration file for
+.Nm ssh .
+This option is directly passed to
+.Xr ssh 1 .
.It Fl P Ar port
Specifies the port to connect to on the remote host.
Note that this option is written with a capital
@@ -107,9 +114,17 @@ to use for the encrypted connection.
The program must understand
.Xr ssh 1
options.
-.It Fl o Ar option
-The given option is directly passed to
-.Xr ssh 1 .
+.It Fl o Ar ssh_option
+Can be used to pass options to
+.Nm ssh
+in the format used in the
+.Xr ssh 1
+configuration file. This is useful for specifying options
+for which there is no separate
+.Nm scp
+command-line flag. For example, forcing the use of protocol
+version 1 is specified using
+.Ic scp -oProtocol=1 .
.It Fl 4
Forces
.Nm
@@ -119,6 +134,9 @@ Forces
.Nm
to use IPv6 addresses only.
.El
+.Sh DIAGNOSTICS
+.Nm
+exits with 0 on success or >0 if an error occurred.
.Sh AUTHORS
Timo Rinne <tri@iki.fi> and Tatu Ylonen <ylo@cs.hut.fi>
.Sh HISTORY
diff --git a/crypto/openssh/scp.c b/crypto/openssh/scp.c
index 81d3b55..159e4bb 100644
--- a/crypto/openssh/scp.c
+++ b/crypto/openssh/scp.c
@@ -75,16 +75,18 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: scp.c,v 1.68 2001/04/22 12:34:05 markus Exp $");
+RCSID("$OpenBSD: scp.c,v 1.86 2001/12/05 03:56:39 itojun Exp $");
#include "xmalloc.h"
#include "atomicio.h"
#include "pathnames.h"
#include "log.h"
-#include "scp-common.h"
+#include "misc.h"
/* For progressmeter() -- number of seconds before xfer considered "stalled" */
#define STALLTIME 5
+/* alarm() interval for updating progress meter */
+#define PROGRESSTIME 1
/* Visual statistics about files as they are transferred. */
void progressmeter(int);
@@ -93,8 +95,8 @@ void progressmeter(int);
int getttywidth(void);
int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc);
-/* setup arguments for the call to ssh */
-void addargs(char *fmt, ...) __attribute__((format(printf, 1, 2)));
+/* Struct for addargs */
+arglist args;
/* Time a transfer started. */
static struct timeval start;
@@ -117,13 +119,6 @@ int showprogress = 1;
/* This is the program to execute for the secured connection. ("ssh" or -S) */
char *ssh_program = _PATH_SSH_PROGRAM;
-/* This is the list of arguments that scp passes to ssh */
-struct {
- char **list;
- int num;
- int nalloc;
-} args;
-
/*
* This function executes the given command as the specified user on the
* given host. This returns < 0 if execution fails, and >= 0 otherwise. This
@@ -136,8 +131,10 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
int pin[2], pout[2], reserved[2];
if (verbose_mode)
- fprintf(stderr, "Executing: program %s host %s, user %s, command %s\n",
- ssh_program, host, remuser ? remuser : "(unspecified)", cmd);
+ fprintf(stderr,
+ "Executing: program %s host %s, user %s, command %s\n",
+ ssh_program, host,
+ remuser ? remuser : "(unspecified)", cmd);
/*
* Reserve two descriptors so that the real pipes won't get
@@ -167,9 +164,9 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
args.list[0] = ssh_program;
if (remuser != NULL)
- addargs("-l%s", remuser);
- addargs("%s", host);
- addargs("%s", cmd);
+ addargs(&args, "-l%s", remuser);
+ addargs(&args, "%s", host);
+ addargs(&args, "%s", cmd);
execvp(ssh_program, args.list);
perror(ssh_program);
@@ -222,29 +219,32 @@ main(argc, argv)
extern int optind;
args.list = NULL;
- addargs("ssh"); /* overwritten with ssh_program */
- addargs("-x");
- addargs("-oFallBackToRsh no");
+ addargs(&args, "ssh"); /* overwritten with ssh_program */
+ addargs(&args, "-x");
+ addargs(&args, "-oForwardAgent no");
+ addargs(&args, "-oFallBackToRsh no");
+ addargs(&args, "-oClearAllForwardings yes");
fflag = tflag = 0;
- while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:o:")) != -1)
+ while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:o:F:")) != -1)
switch (ch) {
/* User-visible flags. */
case '4':
case '6':
case 'C':
- addargs("-%c", ch);
+ addargs(&args, "-%c", ch);
break;
case 'o':
case 'c':
case 'i':
- addargs("-%c%s", ch, optarg);
+ case 'F':
+ addargs(&args, "-%c%s", ch, optarg);
break;
case 'P':
- addargs("-p%s", optarg);
+ addargs(&args, "-p%s", optarg);
break;
case 'B':
- addargs("-oBatchmode yes");
+ addargs(&args, "-oBatchmode yes");
break;
case 'p':
pflag = 1;
@@ -256,6 +256,7 @@ main(argc, argv)
ssh_program = xstrdup(optarg);
break;
case 'v':
+ addargs(&args, "-v");
verbose_mode = 1;
break;
case 'q':
@@ -352,13 +353,17 @@ toremote(targ, argc, argv)
for (i = 0; i < argc - 1; i++) {
src = colon(argv[i]);
if (src) { /* remote to remote */
+ static char *ssh_options =
+ "-x -o'FallBackToRsh no' "
+ "-o'ClearAllForwardings yes'";
*src++ = 0;
if (*src == 0)
src = ".";
host = strchr(argv[i], '@');
len = strlen(ssh_program) + strlen(argv[i]) +
strlen(src) + (tuser ? strlen(tuser) : 0) +
- strlen(thost) + strlen(targ) + CMDNEEDS + 32;
+ strlen(thost) + strlen(targ) +
+ strlen(ssh_options) + CMDNEEDS + 20;
bp = xmalloc(len);
if (host) {
*host++ = 0;
@@ -369,19 +374,19 @@ toremote(targ, argc, argv)
else if (!okname(suser))
continue;
snprintf(bp, len,
- "%s%s -x -o'FallBackToRsh no' -n "
+ "%s%s %s -n "
"-l %s %s %s %s '%s%s%s:%s'",
ssh_program, verbose_mode ? " -v" : "",
- suser, host, cmd, src,
+ ssh_options, suser, host, cmd, src,
tuser ? tuser : "", tuser ? "@" : "",
thost, targ);
} else {
host = cleanhostname(argv[i]);
snprintf(bp, len,
- "exec %s%s -x -o'FallBackToRsh no' -n %s "
+ "exec %s%s %s -n %s "
"%s %s '%s%s%s:%s'",
ssh_program, verbose_mode ? " -v" : "",
- host, cmd, src,
+ ssh_options, host, cmd, src,
tuser ? tuser : "", tuser ? "@" : "",
thost, targ);
}
@@ -479,6 +484,11 @@ source(argc, argv)
len = strlen(name);
while (len > 1 && name[len-1] == '/')
name[--len] = '\0';
+ if (strchr(name, '\n') != NULL) {
+ run_err("%s: skipping, filename contains a newline",
+ name);
+ goto next;
+ }
if ((fd = open(name, O_RDONLY, 0)) < 0)
goto syserr;
if (fstat(fd, &stb) < 0) {
@@ -641,7 +651,7 @@ sink(argc, argv)
#define atime tv[0]
#define mtime tv[1]
-#define SCREWUP(str) { why = str; goto screwup; }
+#define SCREWUP(str) do { why = str; goto screwup; } while (0)
setimes = targisdir = 0;
mask = umask(0);
@@ -784,7 +794,7 @@ sink(argc, argv)
}
omode = mode;
mode |= S_IWRITE;
- if ((ofd = open(np, O_WRONLY | O_CREAT | O_TRUNC, mode)) < 0) {
+ if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) {
bad: run_err("%s: %s", np, strerror(errno));
continue;
}
@@ -808,7 +818,8 @@ bad: run_err("%s: %s", np, strerror(errno));
count += amt;
do {
j = read(remin, cp, amt);
- if (j == -1 && (errno == EINTR || errno == EAGAIN)) {
+ if (j == -1 && (errno == EINTR ||
+ errno == EAGAIN)) {
continue;
} else if (j <= 0) {
run_err("%s", j ? strerror(errno) :
@@ -839,12 +850,10 @@ bad: run_err("%s: %s", np, strerror(errno));
wrerr = YES;
wrerrno = j >= 0 ? EIO : errno;
}
-#if 0
if (ftruncate(ofd, size)) {
run_err("%s: truncate: %s", np, strerror(errno));
wrerr = DISPLAYED;
}
-#endif
if (pflag) {
if (exists || omode != mode)
if (fchmod(ofd, omode))
@@ -886,7 +895,7 @@ screwup:
}
int
-response()
+response(void)
{
char ch, *cp, resp, rbuf[2048];
@@ -919,10 +928,11 @@ response()
}
void
-usage()
+usage(void)
{
- (void) fprintf(stderr, "usage: scp "
- "[-pqrvBC46] [-S ssh] [-P port] [-c cipher] [-i identity] f1 f2\n"
+ (void) fprintf(stderr,
+ "usage: scp [-pqrvBC46] [-F config] [-S ssh] [-P port] [-c cipher] [-i identity]\n"
+ " [-o option] f1 f2\n"
" or: scp [options] f1 ... fn directory\n");
exit(1);
}
@@ -932,22 +942,24 @@ run_err(const char *fmt,...)
{
static FILE *fp;
va_list ap;
- va_start(ap, fmt);
++errs;
if (fp == NULL && !(fp = fdopen(remout, "w")))
return;
(void) fprintf(fp, "%c", 0x01);
(void) fprintf(fp, "scp: ");
+ va_start(ap, fmt);
(void) vfprintf(fp, fmt, ap);
+ va_end(ap);
(void) fprintf(fp, "\n");
(void) fflush(fp);
if (!iamremote) {
+ va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
+ va_end(ap);
fprintf(stderr, "\n");
}
- va_end(ap);
}
void
@@ -974,7 +986,7 @@ okname(cp0)
cp = cp0;
do {
- c = *cp;
+ c = (int)*cp;
if (c & 0200)
goto bad;
if (!isalpha(c) && !isdigit(c) &&
@@ -1010,6 +1022,7 @@ allocbuf(bp, fd, blksize)
bp->buf = xmalloc(size);
else
bp->buf = xrealloc(bp->buf, size);
+ memset(bp->buf, 0, size);
bp->cnt = size;
return (bp);
}
@@ -1019,32 +1032,25 @@ lostconn(signo)
int signo;
{
if (!iamremote)
- fprintf(stderr, "lost connection\n");
- exit(1);
-}
-
-
-void
-alarmtimer(int wait)
-{
- struct itimerval itv;
-
- itv.it_value.tv_sec = wait;
- itv.it_value.tv_usec = 0;
- itv.it_interval = itv.it_value;
- setitimer(ITIMER_REAL, &itv, NULL);
+ write(STDERR_FILENO, "lost connection\n", 16);
+ if (signo)
+ _exit(1);
+ else
+ exit(1);
}
-void
+static void
updateprogressmeter(int ignore)
{
int save_errno = errno;
progressmeter(0);
+ signal(SIGALRM, updateprogressmeter);
+ alarm(PROGRESSTIME);
errno = save_errno;
}
-int
+static int
foregroundproc(void)
{
static pid_t pgrp = -1;
@@ -1093,8 +1099,10 @@ progressmeter(int flag)
i = barlength * ratio / 100;
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
"|%.*s%*s|", i,
- "*****************************************************************************"
- "*****************************************************************************",
+ "***************************************"
+ "***************************************"
+ "***************************************"
+ "***************************************",
barlength - i, "");
}
i = 0;
@@ -1150,9 +1158,9 @@ progressmeter(int flag)
if (flag == -1) {
signal(SIGALRM, updateprogressmeter);
- alarmtimer(1);
+ alarm(PROGRESSTIME);
} else if (flag == 1) {
- alarmtimer(0);
+ alarm(0);
atomicio(write, fileno(stdout), "\n", 1);
statbytes = 0;
}
@@ -1168,25 +1176,3 @@ getttywidth(void)
else
return (80);
}
-
-void
-addargs(char *fmt, ...)
-{
- va_list ap;
- char buf[1024];
-
- va_start(ap, fmt);
- vsnprintf(buf, sizeof(buf), fmt, ap);
- va_end(ap);
-
- if (args.list == NULL) {
- args.nalloc = 32;
- args.num = 0;
- args.list = xmalloc(args.nalloc * sizeof(char *));
- } else if (args.num+2 >= args.nalloc) {
- args.nalloc *= 2;
- args.list = xrealloc(args.list, args.nalloc * sizeof(char *));
- }
- args.list[args.num++] = xstrdup(buf);
- args.list[args.num] = NULL;
-}
diff --git a/crypto/openssh/scp/Makefile b/crypto/openssh/scp/Makefile
index 454682a..c8959bb 100644
--- a/crypto/openssh/scp/Makefile
+++ b/crypto/openssh/scp/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.12 2001/04/16 02:31:48 mouring Exp $
+# $OpenBSD: Makefile,v 1.13 2001/05/03 23:09:55 mouring Exp $
.PATH: ${.CURDIR}/..
@@ -10,6 +10,6 @@ BINMODE?=555
BINDIR= /usr/bin
MAN= scp.1
-SRCS= scp.c scp-common.c
+SRCS= scp.c misc.c
.include <bsd.prog.mk>
diff --git a/crypto/openssh/serverloop.h b/crypto/openssh/serverloop.h
index 652c1d9..f419198 100644
--- a/crypto/openssh/serverloop.h
+++ b/crypto/openssh/serverloop.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: serverloop.h,v 1.2 2001/01/29 01:58:17 niklas Exp $ */
+/* $OpenBSD: serverloop.h,v 1.5 2001/06/27 02:12:53 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -18,5 +18,10 @@
* (of the child program), and reads from stdout and stderr (of the child
* program).
*/
-void server_loop(pid_t pid, int fdin, int fdout, int fderr);
-void server_loop2(void);
+#ifndef SERVERLOOP_H
+#define SERVERLOOP_H
+
+void server_loop(pid_t, int, int, int);
+void server_loop2(Authctxt *);
+
+#endif
diff --git a/crypto/openssh/session.h b/crypto/openssh/session.h
index 842e941..ec8284a 100644
--- a/crypto/openssh/session.h
+++ b/crypto/openssh/session.h
@@ -1,7 +1,7 @@
-/* $OpenBSD: session.h,v 1.6 2001/03/21 11:43:45 markus Exp $ */
+/* $OpenBSD: session.h,v 1.14 2002/02/03 17:53:25 markus Exp $ */
/*
- * Copyright (c) 2000 Markus Friedl. All rights reserved.
+ * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,11 +26,12 @@
#ifndef SESSION_H
#define SESSION_H
-void do_authenticated(Authctxt *ac);
+void do_authenticated(Authctxt *);
-int session_open(int id);
-void session_input_channel_req(int id, void *arg);
-void session_close_by_pid(pid_t pid, int status);
-void session_close_by_channel(int id, void *arg);
+int session_open(Authctxt*, int);
+int session_input_channel_req(Channel *, const char *);
+void session_close_by_pid(pid_t, int);
+void session_close_by_channel(int, void *);
+void session_destroy_all(void);
#endif
diff --git a/crypto/openssh/sftp-client.c b/crypto/openssh/sftp-client.c
index b5d2fd3..10ac13d 100644
--- a/crypto/openssh/sftp-client.c
+++ b/crypto/openssh/sftp-client.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001 Damien Miller. All rights reserved.
+ * Copyright (c) 2001,2002 Damien Miller. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,34 +24,38 @@
/* XXX: memleaks */
/* XXX: signed vs unsigned */
-/* XXX: redesign to allow concurrent overlapped operations */
-/* XXX: we use fatal too much, error may be more appropriate in places */
+/* XXX: remove all logging, only return status codes */
/* XXX: copy between two remote sites */
#include "includes.h"
-RCSID("$OpenBSD: sftp-client.c,v 1.16 2001/04/05 10:42:52 markus Exp $");
+RCSID("$OpenBSD: sftp-client.c,v 1.24 2002/02/24 16:57:19 markus Exp $");
+
+#include <sys/queue.h>
-#include "ssh.h"
#include "buffer.h"
#include "bufaux.h"
#include "getput.h"
#include "xmalloc.h"
#include "log.h"
#include "atomicio.h"
-#include "pathnames.h"
#include "sftp.h"
#include "sftp-common.h"
#include "sftp-client.h"
-/* How much data to read/write at at time during copies */
-/* XXX: what should this be? */
-#define COPY_SIZE 8192
+/* Minimum amount of data to read at at time */
+#define MIN_READ_SIZE 512
-/* Message ID */
-static u_int msg_id = 1;
+struct sftp_conn {
+ int fd_in;
+ int fd_out;
+ u_int transfer_buflen;
+ u_int num_requests;
+ u_int version;
+ u_int msg_id;
+};
-void
+static void
send_msg(int fd, Buffer *m)
{
int mlen = buffer_len(m);
@@ -70,7 +74,7 @@ send_msg(int fd, Buffer *m)
buffer_free(&oqueue);
}
-void
+static void
get_msg(int fd, Buffer *m)
{
u_int len, msg_len;
@@ -98,7 +102,7 @@ get_msg(int fd, Buffer *m)
}
}
-void
+static void
send_string_request(int fd, u_int id, u_int code, char *s,
u_int len)
{
@@ -113,7 +117,7 @@ send_string_request(int fd, u_int id, u_int code, char *s,
buffer_free(&msg);
}
-void
+static void
send_string_attrs_request(int fd, u_int id, u_int code, char *s,
u_int len, Attrib *a)
{
@@ -129,7 +133,7 @@ send_string_attrs_request(int fd, u_int id, u_int code, char *s,
buffer_free(&msg);
}
-u_int
+static u_int
get_status(int fd, int expected_id)
{
Buffer msg;
@@ -154,7 +158,7 @@ get_status(int fd, int expected_id)
return(status);
}
-char *
+static char *
get_handle(int fd, u_int expected_id, u_int *len)
{
Buffer msg;
@@ -183,7 +187,7 @@ get_handle(int fd, u_int expected_id, u_int *len)
return(handle);
}
-Attrib *
+static Attrib *
get_decode_stat(int fd, u_int expected_id, int quiet)
{
Buffer msg;
@@ -217,11 +221,12 @@ get_decode_stat(int fd, u_int expected_id, int quiet)
return(a);
}
-int
-do_init(int fd_in, int fd_out)
+struct sftp_conn *
+do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
{
int type, version;
Buffer msg;
+ struct sftp_conn *ret;
buffer_init(&msg);
buffer_put_char(&msg, SSH2_FXP_INIT);
@@ -237,7 +242,7 @@ do_init(int fd_in, int fd_out)
error("Invalid packet back from SSH2_FXP_INIT (type %d)",
type);
buffer_free(&msg);
- return(-1);
+ return(NULL);
}
version = buffer_get_int(&msg);
@@ -255,25 +260,43 @@ do_init(int fd_in, int fd_out)
buffer_free(&msg);
- return(version);
+ ret = xmalloc(sizeof(*ret));
+ ret->fd_in = fd_in;
+ ret->fd_out = fd_out;
+ ret->transfer_buflen = transfer_buflen;
+ ret->num_requests = num_requests;
+ ret->version = version;
+ ret->msg_id = 1;
+
+ /* Some filexfer v.0 servers don't support large packets */
+ if (version == 0)
+ ret->transfer_buflen = MAX(ret->transfer_buflen, 20480);
+
+ return(ret);
+}
+
+u_int
+sftp_proto_version(struct sftp_conn *conn)
+{
+ return(conn->version);
}
int
-do_close(int fd_in, int fd_out, char *handle, u_int handle_len)
+do_close(struct sftp_conn *conn, char *handle, u_int handle_len)
{
u_int id, status;
Buffer msg;
buffer_init(&msg);
- id = msg_id++;
+ id = conn->msg_id++;
buffer_put_char(&msg, SSH2_FXP_CLOSE);
buffer_put_int(&msg, id);
buffer_put_string(&msg, handle, handle_len);
- send_msg(fd_out, &msg);
+ send_msg(conn->fd_out, &msg);
debug3("Sent message SSH2_FXP_CLOSE I:%d", id);
- status = get_status(fd_in, id);
+ status = get_status(conn->fd_in, id);
if (status != SSH2_FX_OK)
error("Couldn't close file: %s", fx2txt(status));
@@ -283,25 +306,25 @@ do_close(int fd_in, int fd_out, char *handle, u_int handle_len)
}
-int
-do_lsreaddir(int fd_in, int fd_out, char *path, int printflag,
+static int
+do_lsreaddir(struct sftp_conn *conn, char *path, int printflag,
SFTP_DIRENT ***dir)
{
Buffer msg;
u_int type, id, handle_len, i, expected_id, ents = 0;
char *handle;
- id = msg_id++;
+ id = conn->msg_id++;
buffer_init(&msg);
buffer_put_char(&msg, SSH2_FXP_OPENDIR);
buffer_put_int(&msg, id);
buffer_put_cstring(&msg, path);
- send_msg(fd_out, &msg);
+ send_msg(conn->fd_out, &msg);
buffer_clear(&msg);
- handle = get_handle(fd_in, id, &handle_len);
+ handle = get_handle(conn->fd_in, id, &handle_len);
if (handle == NULL)
return(-1);
@@ -310,12 +333,11 @@ do_lsreaddir(int fd_in, int fd_out, char *path, int printflag,
*dir = xmalloc(sizeof(**dir));
(*dir)[0] = NULL;
}
-
- for(;;) {
+ for (;;) {
int count;
- id = expected_id = msg_id++;
+ id = expected_id = conn->msg_id++;
debug3("Sending SSH2_FXP_READDIR I:%d", id);
@@ -323,11 +345,11 @@ do_lsreaddir(int fd_in, int fd_out, char *path, int printflag,
buffer_put_char(&msg, SSH2_FXP_READDIR);
buffer_put_int(&msg, id);
buffer_put_string(&msg, handle, handle_len);
- send_msg(fd_out, &msg);
+ send_msg(conn->fd_out, &msg);
buffer_clear(&msg);
- get_msg(fd_in, &msg);
+ get_msg(conn->fd_in, &msg);
type = buffer_get_char(&msg);
id = buffer_get_int(&msg);
@@ -347,7 +369,7 @@ do_lsreaddir(int fd_in, int fd_out, char *path, int printflag,
} else {
error("Couldn't read directory: %s",
fx2txt(status));
- do_close(fd_in, fd_out, handle, handle_len);
+ do_close(conn, handle, handle_len);
return(status);
}
} else if (type != SSH2_FXP_NAME)
@@ -358,7 +380,7 @@ do_lsreaddir(int fd_in, int fd_out, char *path, int printflag,
if (count == 0)
break;
debug3("Received %d SSH2_FXP_NAME responses", count);
- for(i = 0; i < count; i++) {
+ for (i = 0; i < count; i++) {
char *filename, *longname;
Attrib *a;
@@ -385,29 +407,29 @@ do_lsreaddir(int fd_in, int fd_out, char *path, int printflag,
}
buffer_free(&msg);
- do_close(fd_in, fd_out, handle, handle_len);
+ do_close(conn, handle, handle_len);
xfree(handle);
return(0);
}
int
-do_ls(int fd_in, int fd_out, char *path)
+do_ls(struct sftp_conn *conn, char *path)
{
- return(do_lsreaddir(fd_in, fd_out, path, 1, NULL));
+ return(do_lsreaddir(conn, path, 1, NULL));
}
int
-do_readdir(int fd_in, int fd_out, char *path, SFTP_DIRENT ***dir)
+do_readdir(struct sftp_conn *conn, char *path, SFTP_DIRENT ***dir)
{
- return(do_lsreaddir(fd_in, fd_out, path, 0, dir));
+ return(do_lsreaddir(conn, path, 0, dir));
}
void free_sftp_dirents(SFTP_DIRENT **s)
{
int i;
-
- for(i = 0; s[i]; i++) {
+
+ for (i = 0; s[i]; i++) {
xfree(s[i]->filename);
xfree(s[i]->longname);
xfree(s[i]);
@@ -416,30 +438,31 @@ void free_sftp_dirents(SFTP_DIRENT **s)
}
int
-do_rm(int fd_in, int fd_out, char *path)
+do_rm(struct sftp_conn *conn, char *path)
{
u_int status, id;
debug2("Sending SSH2_FXP_REMOVE \"%s\"", path);
- id = msg_id++;
- send_string_request(fd_out, id, SSH2_FXP_REMOVE, path, strlen(path));
- status = get_status(fd_in, id);
+ id = conn->msg_id++;
+ send_string_request(conn->fd_out, id, SSH2_FXP_REMOVE, path,
+ strlen(path));
+ status = get_status(conn->fd_in, id);
if (status != SSH2_FX_OK)
error("Couldn't delete file: %s", fx2txt(status));
return(status);
}
int
-do_mkdir(int fd_in, int fd_out, char *path, Attrib *a)
+do_mkdir(struct sftp_conn *conn, char *path, Attrib *a)
{
u_int status, id;
- id = msg_id++;
- send_string_attrs_request(fd_out, id, SSH2_FXP_MKDIR, path,
+ id = conn->msg_id++;
+ send_string_attrs_request(conn->fd_out, id, SSH2_FXP_MKDIR, path,
strlen(path), a);
- status = get_status(fd_in, id);
+ status = get_status(conn->fd_in, id);
if (status != SSH2_FX_OK)
error("Couldn't create directory: %s", fx2txt(status));
@@ -447,14 +470,15 @@ do_mkdir(int fd_in, int fd_out, char *path, Attrib *a)
}
int
-do_rmdir(int fd_in, int fd_out, char *path)
+do_rmdir(struct sftp_conn *conn, char *path)
{
u_int status, id;
- id = msg_id++;
- send_string_request(fd_out, id, SSH2_FXP_RMDIR, path, strlen(path));
+ id = conn->msg_id++;
+ send_string_request(conn->fd_out, id, SSH2_FXP_RMDIR, path,
+ strlen(path));
- status = get_status(fd_in, id);
+ status = get_status(conn->fd_in, id);
if (status != SSH2_FX_OK)
error("Couldn't remove directory: %s", fx2txt(status));
@@ -462,45 +486,61 @@ do_rmdir(int fd_in, int fd_out, char *path)
}
Attrib *
-do_stat(int fd_in, int fd_out, char *path, int quiet)
+do_stat(struct sftp_conn *conn, char *path, int quiet)
{
u_int id;
- id = msg_id++;
- send_string_request(fd_out, id, SSH2_FXP_STAT, path, strlen(path));
- return(get_decode_stat(fd_in, id, quiet));
+ id = conn->msg_id++;
+
+ send_string_request(conn->fd_out, id,
+ conn->version == 0 ? SSH2_FXP_STAT_VERSION_0 : SSH2_FXP_STAT,
+ path, strlen(path));
+
+ return(get_decode_stat(conn->fd_in, id, quiet));
}
Attrib *
-do_lstat(int fd_in, int fd_out, char *path, int quiet)
+do_lstat(struct sftp_conn *conn, char *path, int quiet)
{
u_int id;
- id = msg_id++;
- send_string_request(fd_out, id, SSH2_FXP_LSTAT, path, strlen(path));
- return(get_decode_stat(fd_in, id, quiet));
+ if (conn->version == 0) {
+ if (quiet)
+ debug("Server version does not support lstat operation");
+ else
+ error("Server version does not support lstat operation");
+ return(NULL);
+ }
+
+ id = conn->msg_id++;
+ send_string_request(conn->fd_out, id, SSH2_FXP_LSTAT, path,
+ strlen(path));
+
+ return(get_decode_stat(conn->fd_in, id, quiet));
}
Attrib *
-do_fstat(int fd_in, int fd_out, char *handle, u_int handle_len, int quiet)
+do_fstat(struct sftp_conn *conn, char *handle, u_int handle_len, int quiet)
{
u_int id;
- id = msg_id++;
- send_string_request(fd_out, id, SSH2_FXP_FSTAT, handle, handle_len);
- return(get_decode_stat(fd_in, id, quiet));
+ id = conn->msg_id++;
+ send_string_request(conn->fd_out, id, SSH2_FXP_FSTAT, handle,
+ handle_len);
+
+ return(get_decode_stat(conn->fd_in, id, quiet));
}
int
-do_setstat(int fd_in, int fd_out, char *path, Attrib *a)
+do_setstat(struct sftp_conn *conn, char *path, Attrib *a)
{
u_int status, id;
- id = msg_id++;
- send_string_attrs_request(fd_out, id, SSH2_FXP_SETSTAT, path,
+ id = conn->msg_id++;
+ send_string_attrs_request(conn->fd_out, id, SSH2_FXP_SETSTAT, path,
strlen(path), a);
- status = get_status(fd_in, id);
+ status = get_status(conn->fd_in, id);
if (status != SSH2_FX_OK)
error("Couldn't setstat on \"%s\": %s", path,
fx2txt(status));
@@ -509,16 +549,16 @@ do_setstat(int fd_in, int fd_out, char *path, Attrib *a)
}
int
-do_fsetstat(int fd_in, int fd_out, char *handle, u_int handle_len,
+do_fsetstat(struct sftp_conn *conn, char *handle, u_int handle_len,
Attrib *a)
{
u_int status, id;
- id = msg_id++;
- send_string_attrs_request(fd_out, id, SSH2_FXP_FSETSTAT, handle,
+ id = conn->msg_id++;
+ send_string_attrs_request(conn->fd_out, id, SSH2_FXP_FSETSTAT, handle,
handle_len, a);
- status = get_status(fd_in, id);
+ status = get_status(conn->fd_in, id);
if (status != SSH2_FX_OK)
error("Couldn't fsetstat: %s", fx2txt(status));
@@ -526,19 +566,20 @@ do_fsetstat(int fd_in, int fd_out, char *handle, u_int handle_len,
}
char *
-do_realpath(int fd_in, int fd_out, char *path)
+do_realpath(struct sftp_conn *conn, char *path)
{
Buffer msg;
u_int type, expected_id, count, id;
char *filename, *longname;
Attrib *a;
- expected_id = id = msg_id++;
- send_string_request(fd_out, id, SSH2_FXP_REALPATH, path, strlen(path));
+ expected_id = id = conn->msg_id++;
+ send_string_request(conn->fd_out, id, SSH2_FXP_REALPATH, path,
+ strlen(path));
buffer_init(&msg);
- get_msg(fd_in, &msg);
+ get_msg(conn->fd_in, &msg);
type = buffer_get_char(&msg);
id = buffer_get_int(&msg);
@@ -572,7 +613,7 @@ do_realpath(int fd_in, int fd_out, char *path)
}
int
-do_rename(int fd_in, int fd_out, char *oldpath, char *newpath)
+do_rename(struct sftp_conn *conn, char *oldpath, char *newpath)
{
Buffer msg;
u_int status, id;
@@ -580,65 +621,71 @@ do_rename(int fd_in, int fd_out, char *oldpath, char *newpath)
buffer_init(&msg);
/* Send rename request */
- id = msg_id++;
+ id = conn->msg_id++;
buffer_put_char(&msg, SSH2_FXP_RENAME);
buffer_put_int(&msg, id);
buffer_put_cstring(&msg, oldpath);
buffer_put_cstring(&msg, newpath);
- send_msg(fd_out, &msg);
+ send_msg(conn->fd_out, &msg);
debug3("Sent message SSH2_FXP_RENAME \"%s\" -> \"%s\"", oldpath,
newpath);
buffer_free(&msg);
- status = get_status(fd_in, id);
+ status = get_status(conn->fd_in, id);
if (status != SSH2_FX_OK)
- error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath, newpath,
- fx2txt(status));
+ error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath,
+ newpath, fx2txt(status));
return(status);
}
int
-do_symlink(int fd_in, int fd_out, char *oldpath, char *newpath)
+do_symlink(struct sftp_conn *conn, char *oldpath, char *newpath)
{
Buffer msg;
u_int status, id;
+ if (conn->version < 3) {
+ error("This server does not support the symlink operation");
+ return(SSH2_FX_OP_UNSUPPORTED);
+ }
+
buffer_init(&msg);
/* Send rename request */
- id = msg_id++;
+ id = conn->msg_id++;
buffer_put_char(&msg, SSH2_FXP_SYMLINK);
buffer_put_int(&msg, id);
buffer_put_cstring(&msg, oldpath);
buffer_put_cstring(&msg, newpath);
- send_msg(fd_out, &msg);
+ send_msg(conn->fd_out, &msg);
debug3("Sent message SSH2_FXP_SYMLINK \"%s\" -> \"%s\"", oldpath,
newpath);
buffer_free(&msg);
- status = get_status(fd_in, id);
+ status = get_status(conn->fd_in, id);
if (status != SSH2_FX_OK)
- error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath, newpath,
- fx2txt(status));
+ error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath,
+ newpath, fx2txt(status));
return(status);
}
char *
-do_readlink(int fd_in, int fd_out, char *path)
+do_readlink(struct sftp_conn *conn, char *path)
{
Buffer msg;
u_int type, expected_id, count, id;
char *filename, *longname;
Attrib *a;
- expected_id = id = msg_id++;
- send_string_request(fd_out, id, SSH2_FXP_READLINK, path, strlen(path));
+ expected_id = id = conn->msg_id++;
+ send_string_request(conn->fd_out, id, SSH2_FXP_READLINK, path,
+ strlen(path));
buffer_init(&msg);
- get_msg(fd_in, &msg);
+ get_msg(conn->fd_in, &msg);
type = buffer_get_char(&msg);
id = buffer_get_int(&msg);
@@ -671,19 +718,46 @@ do_readlink(int fd_in, int fd_out, char *path)
return(filename);
}
+static void
+send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len,
+ char *handle, u_int handle_len)
+{
+ Buffer msg;
+
+ buffer_init(&msg);
+ buffer_clear(&msg);
+ buffer_put_char(&msg, SSH2_FXP_READ);
+ buffer_put_int(&msg, id);
+ buffer_put_string(&msg, handle, handle_len);
+ buffer_put_int64(&msg, offset);
+ buffer_put_int(&msg, len);
+ send_msg(fd_out, &msg);
+ buffer_free(&msg);
+}
+
int
-do_download(int fd_in, int fd_out, char *remote_path, char *local_path,
+do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
int pflag)
{
- int local_fd;
- u_int expected_id, handle_len, mode, type, id;
- u_int64_t offset;
- char *handle;
- Buffer msg;
Attrib junk, *a;
- int status;
+ Buffer msg;
+ char *handle;
+ int local_fd, status, num_req, max_req, write_error;
+ int read_error, write_errno;
+ u_int64_t offset, size;
+ u_int handle_len, mode, type, id, buflen;
+ struct request {
+ u_int id;
+ u_int len;
+ u_int64_t offset;
+ TAILQ_ENTRY(request) tq;
+ };
+ TAILQ_HEAD(reqhead, request) requests;
+ struct request *req;
- a = do_stat(fd_in, fd_out, remote_path, 0);
+ TAILQ_INIT(&requests);
+
+ a = do_stat(conn, remote_path, 0);
if (a == NULL)
return(-1);
@@ -699,130 +773,199 @@ do_download(int fd_in, int fd_out, char *remote_path, char *local_path,
return(-1);
}
- local_fd = open(local_path, O_WRONLY | O_CREAT | O_TRUNC, mode);
- if (local_fd == -1) {
- error("Couldn't open local file \"%s\" for writing: %s",
- local_path, strerror(errno));
- return(-1);
- }
+ if (a->flags & SSH2_FILEXFER_ATTR_SIZE)
+ size = a->size;
+ else
+ size = 0;
+ buflen = conn->transfer_buflen;
buffer_init(&msg);
/* Send open request */
- id = msg_id++;
+ id = conn->msg_id++;
buffer_put_char(&msg, SSH2_FXP_OPEN);
buffer_put_int(&msg, id);
buffer_put_cstring(&msg, remote_path);
buffer_put_int(&msg, SSH2_FXF_READ);
attrib_clear(&junk); /* Send empty attributes */
encode_attrib(&msg, &junk);
- send_msg(fd_out, &msg);
+ send_msg(conn->fd_out, &msg);
debug3("Sent message SSH2_FXP_OPEN I:%d P:%s", id, remote_path);
- handle = get_handle(fd_in, id, &handle_len);
+ handle = get_handle(conn->fd_in, id, &handle_len);
if (handle == NULL) {
buffer_free(&msg);
- close(local_fd);
+ return(-1);
+ }
+
+ local_fd = open(local_path, O_WRONLY | O_CREAT | O_TRUNC, mode);
+ if (local_fd == -1) {
+ error("Couldn't open local file \"%s\" for writing: %s",
+ local_path, strerror(errno));
+ buffer_free(&msg);
+ xfree(handle);
return(-1);
}
/* Read from remote and write to local */
- offset = 0;
- for(;;) {
- u_int len;
+ write_error = read_error = write_errno = num_req = offset = 0;
+ max_req = 1;
+ while (num_req > 0 || max_req > 0) {
char *data;
+ u_int len;
- id = expected_id = msg_id++;
-
- buffer_clear(&msg);
- buffer_put_char(&msg, SSH2_FXP_READ);
- buffer_put_int(&msg, id);
- buffer_put_string(&msg, handle, handle_len);
- buffer_put_int64(&msg, offset);
- buffer_put_int(&msg, COPY_SIZE);
- send_msg(fd_out, &msg);
- debug3("Sent message SSH2_FXP_READ I:%d O:%llu S:%u",
- id, (unsigned long long)offset, COPY_SIZE);
+ /* Send some more requests */
+ while (num_req < max_req) {
+ debug3("Request range %llu -> %llu (%d/%d)",
+ offset, offset + buflen - 1, num_req, max_req);
+ req = xmalloc(sizeof(*req));
+ req->id = conn->msg_id++;
+ req->len = buflen;
+ req->offset = offset;
+ offset += buflen;
+ num_req++;
+ TAILQ_INSERT_TAIL(&requests, req, tq);
+ send_read_request(conn->fd_out, req->id, req->offset,
+ req->len, handle, handle_len);
+ }
buffer_clear(&msg);
-
- get_msg(fd_in, &msg);
+ get_msg(conn->fd_in, &msg);
type = buffer_get_char(&msg);
id = buffer_get_int(&msg);
- debug3("Received reply T:%d I:%d", type, id);
- if (id != expected_id)
- fatal("ID mismatch (%d != %d)", id, expected_id);
- if (type == SSH2_FXP_STATUS) {
+ debug3("Received reply T:%d I:%d R:%d", type, id, max_req);
+
+ /* Find the request in our queue */
+ for(req = TAILQ_FIRST(&requests);
+ req != NULL && req->id != id;
+ req = TAILQ_NEXT(req, tq))
+ ;
+ if (req == NULL)
+ fatal("Unexpected reply %u", id);
+
+ switch (type) {
+ case SSH2_FXP_STATUS:
status = buffer_get_int(&msg);
+ if (status != SSH2_FX_EOF)
+ read_error = 1;
+ max_req = 0;
+ TAILQ_REMOVE(&requests, req, tq);
+ xfree(req);
+ num_req--;
+ break;
+ case SSH2_FXP_DATA:
+ data = buffer_get_string(&msg, &len);
+ debug3("Received data %llu -> %llu", req->offset,
+ req->offset + len - 1);
+ if (len > req->len)
+ fatal("Received more data than asked for "
+ "%d > %d", len, req->len);
+ if ((lseek(local_fd, req->offset, SEEK_SET) == -1 ||
+ atomicio(write, local_fd, data, len) != len) &&
+ !write_error) {
+ write_errno = errno;
+ write_error = 1;
+ max_req = 0;
+ }
+ xfree(data);
- if (status == SSH2_FX_EOF)
- break;
- else {
- error("Couldn't read from remote "
- "file \"%s\" : %s", remote_path,
- fx2txt(status));
- do_close(fd_in, fd_out, handle, handle_len);
- goto done;
+ if (len == req->len) {
+ TAILQ_REMOVE(&requests, req, tq);
+ xfree(req);
+ num_req--;
+ } else {
+ /* Resend the request for the missing data */
+ debug3("Short data block, re-requesting "
+ "%llu -> %llu (%2d)", req->offset + len,
+ req->offset + req->len - 1, num_req);
+ req->id = conn->msg_id++;
+ req->len -= len;
+ req->offset += len;
+ send_read_request(conn->fd_out, req->id,
+ req->offset, req->len, handle, handle_len);
+ /* Reduce the request size */
+ if (len < buflen)
+ buflen = MAX(MIN_READ_SIZE, len);
}
- } else if (type != SSH2_FXP_DATA) {
+ if (max_req > 0) { /* max_req = 0 iff EOF received */
+ if (size > 0 && offset > size) {
+ /* Only one request at a time
+ * after the expected EOF */
+ debug3("Finish at %llu (%2d)",
+ offset, num_req);
+ max_req = 1;
+ }
+ else if (max_req < conn->num_requests + 1) {
+ ++max_req;
+ }
+ }
+ break;
+ default:
fatal("Expected SSH2_FXP_DATA(%d) packet, got %d",
SSH2_FXP_DATA, type);
}
-
- data = buffer_get_string(&msg, &len);
- if (len > COPY_SIZE)
- fatal("Received more data than asked for %d > %d",
- len, COPY_SIZE);
-
- debug3("In read loop, got %d offset %llu", len,
- (unsigned long long)offset);
- if (atomicio(write, local_fd, data, len) != len) {
- error("Couldn't write to \"%s\": %s", local_path,
- strerror(errno));
- do_close(fd_in, fd_out, handle, handle_len);
- status = -1;
- xfree(data);
- goto done;
- }
-
- offset += len;
- xfree(data);
}
- status = do_close(fd_in, fd_out, handle, handle_len);
- /* Override umask and utimes if asked */
- if (pflag && fchmod(local_fd, mode) == -1)
- error("Couldn't set mode on \"%s\": %s", local_path,
- strerror(errno));
- if (pflag && (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) {
- struct timeval tv[2];
- tv[0].tv_sec = a->atime;
- tv[1].tv_sec = a->mtime;
- tv[0].tv_usec = tv[1].tv_usec = 0;
- if (utimes(local_path, tv) == -1)
- error("Can't set times on \"%s\": %s", local_path,
- strerror(errno));
+ /* Sanity check */
+ if (TAILQ_FIRST(&requests) != NULL)
+ fatal("Transfer complete, but requests still in queue");
+
+ if (read_error) {
+ error("Couldn't read from remote file \"%s\" : %s",
+ remote_path, fx2txt(status));
+ do_close(conn, handle, handle_len);
+ } else if (write_error) {
+ error("Couldn't write to \"%s\": %s", local_path,
+ strerror(write_errno));
+ status = -1;
+ do_close(conn, handle, handle_len);
+ } else {
+ status = do_close(conn, handle, handle_len);
+
+ /* Override umask and utimes if asked */
+ if (pflag && fchmod(local_fd, mode) == -1)
+ error("Couldn't set mode on \"%s\": %s", local_path,
+ strerror(errno));
+ if (pflag && (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) {
+ struct timeval tv[2];
+ tv[0].tv_sec = a->atime;
+ tv[1].tv_sec = a->mtime;
+ tv[0].tv_usec = tv[1].tv_usec = 0;
+ if (utimes(local_path, tv) == -1)
+ error("Can't set times on \"%s\": %s",
+ local_path, strerror(errno));
+ }
}
-
-done:
close(local_fd);
buffer_free(&msg);
xfree(handle);
- return status;
+
+ return(status);
}
int
-do_upload(int fd_in, int fd_out, char *local_path, char *remote_path,
+do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
int pflag)
{
- int local_fd;
- u_int handle_len, id;
+ int local_fd, status;
+ u_int handle_len, id, type;
u_int64_t offset;
- char *handle;
+ char *handle, *data;
Buffer msg;
struct stat sb;
Attrib a;
- int status;
+ u_int32_t startid;
+ u_int32_t ackid;
+ struct outstanding_ack {
+ u_int id;
+ u_int len;
+ u_int64_t offset;
+ TAILQ_ENTRY(outstanding_ack) tq;
+ };
+ TAILQ_HEAD(ackhead, outstanding_ack) acks;
+ struct outstanding_ack *ack;
+
+ TAILQ_INIT(&acks);
if ((local_fd = open(local_path, O_RDONLY, 0)) == -1) {
error("Couldn't open local file \"%s\" for reading: %s",
@@ -846,85 +989,121 @@ do_upload(int fd_in, int fd_out, char *local_path, char *remote_path,
buffer_init(&msg);
/* Send open request */
- id = msg_id++;
+ id = conn->msg_id++;
buffer_put_char(&msg, SSH2_FXP_OPEN);
buffer_put_int(&msg, id);
buffer_put_cstring(&msg, remote_path);
buffer_put_int(&msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC);
encode_attrib(&msg, &a);
- send_msg(fd_out, &msg);
+ send_msg(conn->fd_out, &msg);
debug3("Sent message SSH2_FXP_OPEN I:%d P:%s", id, remote_path);
buffer_clear(&msg);
- handle = get_handle(fd_in, id, &handle_len);
+ handle = get_handle(conn->fd_in, id, &handle_len);
if (handle == NULL) {
close(local_fd);
buffer_free(&msg);
return(-1);
}
+ startid = ackid = id + 1;
+ data = xmalloc(conn->transfer_buflen);
+
/* Read from local and write to remote */
offset = 0;
- for(;;) {
+ for (;;) {
int len;
- char data[COPY_SIZE];
/*
* Can't use atomicio here because it returns 0 on EOF, thus losing
* the last block of the file
*/
do
- len = read(local_fd, data, COPY_SIZE);
+ len = read(local_fd, data, conn->transfer_buflen);
while ((len == -1) && (errno == EINTR || errno == EAGAIN));
if (len == -1)
fatal("Couldn't read from \"%s\": %s", local_path,
strerror(errno));
- if (len == 0)
+
+ if (len != 0) {
+ ack = xmalloc(sizeof(*ack));
+ ack->id = ++id;
+ ack->offset = offset;
+ ack->len = len;
+ TAILQ_INSERT_TAIL(&acks, ack, tq);
+
+ buffer_clear(&msg);
+ buffer_put_char(&msg, SSH2_FXP_WRITE);
+ buffer_put_int(&msg, ack->id);
+ buffer_put_string(&msg, handle, handle_len);
+ buffer_put_int64(&msg, offset);
+ buffer_put_string(&msg, data, len);
+ send_msg(conn->fd_out, &msg);
+ debug3("Sent message SSH2_FXP_WRITE I:%d O:%llu S:%u",
+ id, (u_int64_t)offset, len);
+ } else if (TAILQ_FIRST(&acks) == NULL)
break;
- buffer_clear(&msg);
- buffer_put_char(&msg, SSH2_FXP_WRITE);
- buffer_put_int(&msg, ++id);
- buffer_put_string(&msg, handle, handle_len);
- buffer_put_int64(&msg, offset);
- buffer_put_string(&msg, data, len);
- send_msg(fd_out, &msg);
- debug3("Sent message SSH2_FXP_WRITE I:%d O:%llu S:%u",
- id, (unsigned long long)offset, len);
-
- status = get_status(fd_in, id);
- if (status != SSH2_FX_OK) {
- error("Couldn't write to remote file \"%s\": %s",
- remote_path, fx2txt(status));
- do_close(fd_in, fd_out, handle, handle_len);
- close(local_fd);
- goto done;
- }
- debug3("In write loop, got %d offset %llu", len,
- (unsigned long long)offset);
+ if (ack == NULL)
+ fatal("Unexpected ACK %u", id);
+
+ if (id == startid || len == 0 ||
+ id - ackid >= conn->num_requests) {
+ buffer_clear(&msg);
+ get_msg(conn->fd_in, &msg);
+ type = buffer_get_char(&msg);
+ id = buffer_get_int(&msg);
+ if (type != SSH2_FXP_STATUS)
+ fatal("Expected SSH2_FXP_STATUS(%d) packet, "
+ "got %d", SSH2_FXP_STATUS, type);
+
+ status = buffer_get_int(&msg);
+ debug3("SSH2_FXP_STATUS %d", status);
+
+ /* Find the request in our queue */
+ for(ack = TAILQ_FIRST(&acks);
+ ack != NULL && ack->id != id;
+ ack = TAILQ_NEXT(ack, tq))
+ ;
+ if (ack == NULL)
+ fatal("Can't find request for ID %d", id);
+ TAILQ_REMOVE(&acks, ack, tq);
+
+ if (status != SSH2_FX_OK) {
+ error("Couldn't write to remote file \"%s\": %s",
+ remote_path, fx2txt(status));
+ do_close(conn, handle, handle_len);
+ close(local_fd);
+ goto done;
+ }
+ debug3("In write loop, ack for %u %d bytes at %llu",
+ ack->id, ack->len, ack->offset);
+ ++ackid;
+ free(ack);
+ }
offset += len;
}
+ xfree(data);
if (close(local_fd) == -1) {
error("Couldn't close local file \"%s\": %s", local_path,
strerror(errno));
- do_close(fd_in, fd_out, handle, handle_len);
+ do_close(conn, handle, handle_len);
status = -1;
goto done;
}
/* Override umask and utimes if asked */
if (pflag)
- do_fsetstat(fd_in, fd_out, handle, handle_len, &a);
+ do_fsetstat(conn, handle, handle_len, &a);
- status = do_close(fd_in, fd_out, handle, handle_len);
+ status = do_close(conn, handle, handle_len);
done:
xfree(handle);
buffer_free(&msg);
- return status;
+ return(status);
}
-
diff --git a/crypto/openssh/sftp-client.h b/crypto/openssh/sftp-client.h
index 09ffcc0..ceda879 100644
--- a/crypto/openssh/sftp-client.h
+++ b/crypto/openssh/sftp-client.h
@@ -1,7 +1,7 @@
-/* $OpenBSD: sftp-client.h,v 1.5 2001/04/05 10:42:52 markus Exp $ */
+/* $OpenBSD: sftp-client.h,v 1.9 2002/02/13 00:59:23 djm Exp $ */
/*
- * Copyright (c) 2001 Damien Miller. All rights reserved.
+ * Copyright (c) 2001,2002 Damien Miller. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,6 +26,9 @@
/* Client side of SSH2 filexfer protocol */
+#ifndef _SFTP_CLIENT_H
+#define _SFTP_CLIENT_H
+
typedef struct SFTP_DIRENT SFTP_DIRENT;
struct SFTP_DIRENT {
@@ -38,57 +41,59 @@ struct SFTP_DIRENT {
* Initialiase a SSH filexfer connection. Returns -1 on error or
* protocol version on success.
*/
-int do_init(int fd_in, int fd_out);
+struct sftp_conn *
+do_init(int, int, u_int, u_int);
+
+u_int
+sftp_proto_version(struct sftp_conn *);
/* Close file referred to by 'handle' */
-int do_close(int fd_in, int fd_out, char *handle, u_int handle_len);
+int do_close(struct sftp_conn *, char *, u_int);
/* List contents of directory 'path' to stdout */
-int do_ls(int fd_in, int fd_out, char *path);
+int do_ls(struct sftp_conn *, char *);
/* Read contents of 'path' to NULL-terminated array 'dir' */
-int do_readdir(int fd_in, int fd_out, char *path, SFTP_DIRENT ***dir);
+int do_readdir(struct sftp_conn *, char *, SFTP_DIRENT ***);
/* Frees a NULL-terminated array of SFTP_DIRENTs (eg. from do_readdir) */
-void free_sftp_dirents(SFTP_DIRENT **s);
+void free_sftp_dirents(SFTP_DIRENT **);
/* Delete file 'path' */
-int do_rm(int fd_in, int fd_out, char *path);
+int do_rm(struct sftp_conn *, char *);
/* Create directory 'path' */
-int do_mkdir(int fd_in, int fd_out, char *path, Attrib *a);
+int do_mkdir(struct sftp_conn *, char *, Attrib *);
/* Remove directory 'path' */
-int do_rmdir(int fd_in, int fd_out, char *path);
+int do_rmdir(struct sftp_conn *, char *);
/* Get file attributes of 'path' (follows symlinks) */
-Attrib *do_stat(int fd_in, int fd_out, char *path, int quiet);
+Attrib *do_stat(struct sftp_conn *, char *, int);
/* Get file attributes of 'path' (does not follow symlinks) */
-Attrib *do_lstat(int fd_in, int fd_out, char *path, int quiet);
+Attrib *do_lstat(struct sftp_conn *, char *, int);
/* Get file attributes of open file 'handle' */
-Attrib *do_fstat(int fd_in, int fd_out, char *handle, u_int handle_len,
- int quiet);
+Attrib *do_fstat(struct sftp_conn *, char *, u_int, int);
/* Set file attributes of 'path' */
-int do_setstat(int fd_in, int fd_out, char *path, Attrib *a);
+int do_setstat(struct sftp_conn *, char *, Attrib *);
/* Set file attributes of open file 'handle' */
-int do_fsetstat(int fd_in, int fd_out, char *handle,
- u_int handle_len, Attrib *a);
+int do_fsetstat(struct sftp_conn *, char *, u_int, Attrib *);
/* Canonicalise 'path' - caller must free result */
-char *do_realpath(int fd_in, int fd_out, char *path);
+char *do_realpath(struct sftp_conn *, char *);
/* Rename 'oldpath' to 'newpath' */
-int do_rename(int fd_in, int fd_out, char *oldpath, char *newpath);
+int do_rename(struct sftp_conn *, char *, char *);
/* Rename 'oldpath' to 'newpath' */
-int do_symlink(int fd_in, int fd_out, char *oldpath, char *newpath);
+int do_symlink(struct sftp_conn *, char *, char *);
/* Return target of symlink 'path' - caller must free result */
-char *do_readlink(int fd_in, int fd_out, char *path);
+char *do_readlink(struct sftp_conn *, char *);
/* XXX: add callbacks to do_download/do_upload so we can do progress meter */
@@ -96,12 +101,12 @@ char *do_readlink(int fd_in, int fd_out, char *path);
* Download 'remote_path' to 'local_path'. Preserve permissions and times
* if 'pflag' is set
*/
-int do_download(int fd_in, int fd_out, char *remote_path, char *local_path,
- int pflag);
+int do_download(struct sftp_conn *, char *, char *, int);
/*
* Upload 'local_path' to 'remote_path'. Preserve permissions and times
* if 'pflag' is set
*/
-int do_upload(int fd_in, int fd_out, char *local_path, char *remote_path,
- int pflag);
+int do_upload(struct sftp_conn *, char *, char *, int);
+
+#endif
diff --git a/crypto/openssh/sftp-common.c b/crypto/openssh/sftp-common.c
index 3310eab..4fb4496 100644
--- a/crypto/openssh/sftp-common.c
+++ b/crypto/openssh/sftp-common.c
@@ -24,17 +24,17 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: sftp-common.c,v 1.2 2001/02/06 23:50:10 markus Exp $");
+RCSID("$OpenBSD: sftp-common.c,v 1.5 2001/12/02 02:08:32 deraadt Exp $");
#include "buffer.h"
#include "bufaux.h"
-#include "getput.h"
#include "log.h"
#include "xmalloc.h"
#include "sftp.h"
#include "sftp-common.h"
+/* Clear contents of attributes structure */
void
attrib_clear(Attrib *a)
{
@@ -47,6 +47,7 @@ attrib_clear(Attrib *a)
a->mtime = 0;
}
+/* Convert from struct stat to filexfer attribs */
void
stat_to_attrib(struct stat *st, Attrib *a)
{
@@ -64,6 +65,7 @@ stat_to_attrib(struct stat *st, Attrib *a)
a->mtime = st->st_mtime;
}
+/* Decode attributes in buffer */
Attrib *
decode_attrib(Buffer *b)
{
@@ -98,6 +100,7 @@ decode_attrib(Buffer *b)
return &a;
}
+/* Encode attributes to buffer */
void
encode_attrib(Buffer *b, Attrib *a)
{
@@ -116,6 +119,7 @@ encode_attrib(Buffer *b, Attrib *a)
}
}
+/* Convert from SSH2_FX_ status to text error message */
const char *
fx2txt(int status)
{
@@ -140,7 +144,6 @@ fx2txt(int status)
return("Operation unsupported");
default:
return("Unknown status");
- };
+ }
/* NOTREACHED */
}
-
diff --git a/crypto/openssh/sftp-common.h b/crypto/openssh/sftp-common.h
index 6dc1a32..4c126bf 100644
--- a/crypto/openssh/sftp-common.h
+++ b/crypto/openssh/sftp-common.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-common.h,v 1.1 2001/02/04 11:11:54 djm Exp $ */
+/* $OpenBSD: sftp-common.h,v 1.3 2001/06/26 17:27:24 markus Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -38,18 +38,9 @@ struct Attrib {
u_int32_t mtime;
};
-/* Clear contents of attributes structure */
-void attrib_clear(Attrib *a);
-
-/* Convert from struct stat to filexfer attribs */
-void stat_to_attrib(struct stat *st, Attrib *a);
-
-/* Decode attributes in buffer */
-Attrib *decode_attrib(Buffer *b);
-
-/* Encode attributes to buffer */
-void encode_attrib(Buffer *b, Attrib *a);
-
-/* Convert from SSH2_FX_ status to text error message */
-const char *fx2txt(int status);
+void attrib_clear(Attrib *);
+void stat_to_attrib(struct stat *, Attrib *);
+Attrib *decode_attrib(Buffer *);
+void encode_attrib(Buffer *, Attrib *);
+const char *fx2txt(int);
diff --git a/crypto/openssh/sftp-glob.c b/crypto/openssh/sftp-glob.c
index 18d81c0..1d845d3 100644
--- a/crypto/openssh/sftp-glob.c
+++ b/crypto/openssh/sftp-glob.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001 Damien Miller. All rights reserved.
+ * Copyright (c) 2001,2002 Damien Miller. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -23,18 +23,14 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: sftp-glob.c,v 1.5 2001/04/15 08:43:46 markus Exp $");
+RCSID("$OpenBSD: sftp-glob.c,v 1.10 2002/02/13 00:59:23 djm Exp $");
#include <glob.h>
-#include "ssh.h"
#include "buffer.h"
#include "bufaux.h"
-#include "getput.h"
#include "xmalloc.h"
#include "log.h"
-#include "atomicio.h"
-#include "pathnames.h"
#include "sftp.h"
#include "sftp-common.h"
@@ -47,17 +43,17 @@ struct SFTP_OPENDIR {
};
static struct {
- int fd_in;
- int fd_out;
+ struct sftp_conn *conn;
} cur;
-void *fudge_opendir(const char *path)
+static void *
+fudge_opendir(const char *path)
{
struct SFTP_OPENDIR *r;
-
+
r = xmalloc(sizeof(*r));
-
- if (do_readdir(cur.fd_in, cur.fd_out, (char*)path, &r->dir))
+
+ if (do_readdir(cur.conn, (char*)path, &r->dir))
return(NULL);
r->offset = 0;
@@ -65,10 +61,11 @@ void *fudge_opendir(const char *path)
return((void*)r);
}
-struct dirent *fudge_readdir(struct SFTP_OPENDIR *od)
+static struct dirent *
+fudge_readdir(struct SFTP_OPENDIR *od)
{
static struct dirent ret;
-
+
if (od->dir[od->offset] == NULL)
return(NULL);
@@ -79,16 +76,18 @@ struct dirent *fudge_readdir(struct SFTP_OPENDIR *od)
return(&ret);
}
-void fudge_closedir(struct SFTP_OPENDIR *od)
+static void
+fudge_closedir(struct SFTP_OPENDIR *od)
{
free_sftp_dirents(od->dir);
xfree(od);
}
-void attrib_to_stat(Attrib *a, struct stat *st)
+static void
+attrib_to_stat(Attrib *a, struct stat *st)
{
memset(st, 0, sizeof(*st));
-
+
if (a->flags & SSH2_FILEXFER_ATTR_SIZE)
st->st_size = a->size;
if (a->flags & SSH2_FILEXFER_ATTR_UIDGID) {
@@ -103,44 +102,44 @@ void attrib_to_stat(Attrib *a, struct stat *st)
}
}
-int fudge_lstat(const char *path, struct stat *st)
+static int
+fudge_lstat(const char *path, struct stat *st)
{
Attrib *a;
-
- if (!(a = do_lstat(cur.fd_in, cur.fd_out, (char*)path, 0)))
+
+ if (!(a = do_lstat(cur.conn, (char*)path, 0)))
return(-1);
-
+
attrib_to_stat(a, st);
-
+
return(0);
}
-int fudge_stat(const char *path, struct stat *st)
+static int
+fudge_stat(const char *path, struct stat *st)
{
Attrib *a;
-
- if (!(a = do_stat(cur.fd_in, cur.fd_out, (char*)path, 0)))
+
+ if (!(a = do_stat(cur.conn, (char*)path, 0)))
return(-1);
-
+
attrib_to_stat(a, st);
-
+
return(0);
}
int
-remote_glob(int fd_in, int fd_out, const char *pattern, int flags,
+remote_glob(struct sftp_conn *conn, const char *pattern, int flags,
int (*errfunc)(const char *, int), glob_t *pglob)
{
- pglob->gl_opendir = (void*)fudge_opendir;
- pglob->gl_readdir = (void*)fudge_readdir;
- pglob->gl_closedir = (void*)fudge_closedir;
+ pglob->gl_opendir = fudge_opendir;
+ pglob->gl_readdir = (struct dirent *(*)(void *))fudge_readdir;
+ pglob->gl_closedir = (void (*)(void *))fudge_closedir;
pglob->gl_lstat = fudge_lstat;
pglob->gl_stat = fudge_stat;
-
+
memset(&cur, 0, sizeof(cur));
- cur.fd_in = fd_in;
- cur.fd_out = fd_out;
+ cur.conn = conn;
- return(glob(pattern, flags | GLOB_ALTDIRFUNC, (void*)errfunc,
- pglob));
+ return(glob(pattern, flags | GLOB_ALTDIRFUNC, errfunc, pglob));
}
diff --git a/crypto/openssh/sftp-glob.h b/crypto/openssh/sftp-glob.h
index 4206af4..488b0a8 100644
--- a/crypto/openssh/sftp-glob.h
+++ b/crypto/openssh/sftp-glob.h
@@ -1,7 +1,7 @@
-/* $OpenBSD: sftp-glob.h,v 1.3 2001/04/15 08:43:46 markus Exp $ */
+/* $OpenBSD: sftp-glob.h,v 1.6 2002/02/13 00:59:23 djm Exp $ */
/*
- * Copyright (c) 2001 Damien Miller. All rights reserved.
+ * Copyright (c) 2001,2002 Damien Miller. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,7 +26,13 @@
/* Remote sftp filename globbing */
+#ifndef _SFTP_GLOB_H
+#define _SFTP_GLOB_H
+
+#include "sftp-client.h"
+
int
-remote_glob(int fd_in, int fd_out, const char *pattern, int flags,
- int (*errfunc)(const char *, int), glob_t *pglob);
+remote_glob(struct sftp_conn *, const char *, int,
+ int (*)(const char *, int), glob_t *);
+#endif
diff --git a/crypto/openssh/sftp-int.c b/crypto/openssh/sftp-int.c
index 3a71daa..d986c76 100644
--- a/crypto/openssh/sftp-int.c
+++ b/crypto/openssh/sftp-int.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001 Damien Miller. All rights reserved.
+ * Copyright (c) 2001,2002 Damien Miller. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,7 +26,7 @@
/* XXX: recursive operations */
#include "includes.h"
-RCSID("$OpenBSD: sftp-int.c,v 1.36 2001/04/15 08:43:46 markus Exp $");
+RCSID("$OpenBSD: sftp-int.c,v 1.44 2002/02/13 00:59:23 djm Exp $");
#include <glob.h>
@@ -44,8 +44,11 @@ RCSID("$OpenBSD: sftp-int.c,v 1.36 2001/04/15 08:43:46 markus Exp $");
/* File to read commands from */
extern FILE *infile;
-/* Version of server we are speaking to */
-int version;
+/* Size of buffer used when copying files */
+extern size_t copy_buffer_len;
+
+/* Number of concurrent outstanding requests */
+extern int num_requests;
/* Seperators for interactive commands */
#define WHITESPACE " \t\r\n"
@@ -80,6 +83,7 @@ struct CMD {
};
const struct CMD cmds[] = {
+ { "bye", I_QUIT },
{ "cd", I_CHDIR },
{ "chdir", I_CHDIR },
{ "chgrp", I_CHGRP },
@@ -113,7 +117,7 @@ const struct CMD cmds[] = {
{ NULL, -1}
};
-void
+static void
help(void)
{
printf("Available commands:\n");
@@ -145,7 +149,7 @@ help(void)
printf("? Synonym for help\n");
}
-void
+static void
local_do_shell(const char *args)
{
int status;
@@ -165,10 +169,10 @@ local_do_shell(const char *args)
/* XXX: child has pipe fds to ssh subproc open - issue? */
if (args) {
debug3("Executing %s -c \"%s\"", shell, args);
- execl(shell, shell, "-c", args, NULL);
+ execl(shell, shell, "-c", args, (char *)NULL);
} else {
debug3("Executing %s", shell);
- execl(shell, shell, NULL);
+ execl(shell, shell, (char *)NULL);
}
fprintf(stderr, "Couldn't execute \"%s\": %s\n", shell,
strerror(errno));
@@ -182,7 +186,7 @@ local_do_shell(const char *args)
error("Shell exited with status %d", WEXITSTATUS(status));
}
-void
+static void
local_do_ls(const char *args)
{
if (!args || !*args)
@@ -198,7 +202,7 @@ local_do_ls(const char *args)
}
}
-char *
+static char *
path_append(char *p1, char *p2)
{
char *ret;
@@ -206,13 +210,14 @@ path_append(char *p1, char *p2)
ret = xmalloc(len);
strlcpy(ret, p1, len);
- strlcat(ret, "/", len);
+ if (strcmp(p1, "/") != 0)
+ strlcat(ret, "/", len);
strlcat(ret, p2, len);
return(ret);
}
-char *
+static char *
make_absolute(char *p, char *pwd)
{
char *abs;
@@ -226,7 +231,7 @@ make_absolute(char *p, char *pwd)
return(p);
}
-int
+static int
infer_path(const char *p, char **ifp)
{
char *cp;
@@ -246,7 +251,7 @@ infer_path(const char *p, char **ifp)
return(0);
}
-int
+static int
parse_getput_flags(const char **cpp, int *pflag)
{
const char *cp = *cpp;
@@ -269,7 +274,7 @@ parse_getput_flags(const char **cpp, int *pflag)
return(0);
}
-int
+static int
get_pathname(const char **cpp, char **path)
{
const char *cp = *cpp, *end;
@@ -317,7 +322,7 @@ get_pathname(const char **cpp, char **path)
return (-1);
}
-int
+static int
is_dir(char *path)
{
struct stat sb;
@@ -329,21 +334,21 @@ is_dir(char *path)
return(sb.st_mode & S_IFDIR);
}
-int
-remote_is_dir(int in, int out, char *path)
+static int
+remote_is_dir(struct sftp_conn *conn, char *path)
{
Attrib *a;
/* XXX: report errors? */
- if ((a = do_stat(in, out, path, 1)) == NULL)
+ if ((a = do_stat(conn, path, 1)) == NULL)
return(0);
if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS))
return(0);
return(a->perm & S_IFDIR);
}
-int
-process_get(int in, int out, char *src, char *dst, char *pwd, int pflag)
+static int
+process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
{
char *abs_src = NULL;
char *abs_dst = NULL;
@@ -357,7 +362,7 @@ process_get(int in, int out, char *src, char *dst, char *pwd, int pflag)
memset(&g, 0, sizeof(g));
debug3("Looking up %s", abs_src);
- if (remote_glob(in, out, abs_src, 0, NULL, &g)) {
+ if (remote_glob(conn, abs_src, 0, NULL, &g)) {
error("File \"%s\" not found.", abs_src);
err = -1;
goto out;
@@ -381,7 +386,7 @@ process_get(int in, int out, char *src, char *dst, char *pwd, int pflag)
goto out;
}
printf("Fetching %s to %s\n", g.gl_pathv[0], abs_dst);
- err = do_download(in, out, g.gl_pathv[0], abs_dst, pflag);
+ err = do_download(conn, g.gl_pathv[0], abs_dst, pflag);
goto out;
}
@@ -393,7 +398,7 @@ process_get(int in, int out, char *src, char *dst, char *pwd, int pflag)
goto out;
}
- for(i = 0; g.gl_pathv[i]; i++) {
+ for (i = 0; g.gl_pathv[i]; i++) {
if (infer_path(g.gl_pathv[i], &tmp)) {
err = -1;
goto out;
@@ -405,7 +410,7 @@ process_get(int in, int out, char *src, char *dst, char *pwd, int pflag)
abs_dst = tmp;
printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
- if (do_download(in, out, g.gl_pathv[i], abs_dst, pflag) == -1)
+ if (do_download(conn, g.gl_pathv[i], abs_dst, pflag) == -1)
err = -1;
xfree(abs_dst);
abs_dst = NULL;
@@ -419,8 +424,8 @@ out:
return(err);
}
-int
-process_put(int in, int out, char *src, char *dst, char *pwd, int pflag)
+static int
+process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
{
char *tmp_dst = NULL;
char *abs_dst = NULL;
@@ -446,7 +451,7 @@ process_put(int in, int out, char *src, char *dst, char *pwd, int pflag)
if (g.gl_pathv[0] && g.gl_matchc == 1) {
if (tmp_dst) {
/* If directory specified, append filename */
- if (remote_is_dir(in, out, tmp_dst)) {
+ if (remote_is_dir(conn, tmp_dst)) {
if (infer_path(g.gl_pathv[0], &tmp)) {
err = 1;
goto out;
@@ -463,19 +468,19 @@ process_put(int in, int out, char *src, char *dst, char *pwd, int pflag)
abs_dst = make_absolute(abs_dst, pwd);
}
printf("Uploading %s to %s\n", g.gl_pathv[0], abs_dst);
- err = do_upload(in, out, g.gl_pathv[0], abs_dst, pflag);
+ err = do_upload(conn, g.gl_pathv[0], abs_dst, pflag);
goto out;
}
/* Multiple matches, dst may be directory or unspecified */
- if (tmp_dst && !remote_is_dir(in, out, tmp_dst)) {
+ if (tmp_dst && !remote_is_dir(conn, tmp_dst)) {
error("Multiple files match, but \"%s\" is not a directory",
tmp_dst);
err = -1;
goto out;
}
- for(i = 0; g.gl_pathv[i]; i++) {
+ for (i = 0; g.gl_pathv[i]; i++) {
if (infer_path(g.gl_pathv[i], &tmp)) {
err = -1;
goto out;
@@ -487,7 +492,7 @@ process_put(int in, int out, char *src, char *dst, char *pwd, int pflag)
abs_dst = make_absolute(tmp, pwd);
printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
- if (do_upload(in, out, g.gl_pathv[i], abs_dst, pflag) == -1)
+ if (do_upload(conn, g.gl_pathv[i], abs_dst, pflag) == -1)
err = -1;
}
@@ -499,7 +504,7 @@ out:
return(err);
}
-int
+static int
parse_args(const char **cpp, int *pflag, unsigned long *n_arg,
char **path1, char **path2)
{
@@ -517,7 +522,7 @@ parse_args(const char **cpp, int *pflag, unsigned long *n_arg,
return(-1);
/* Figure out which command we have */
- for(i = 0; cmds[i].c; i++) {
+ for (i = 0; cmds[i].c; i++) {
int cmdlen = strlen(cmds[i].c);
/* Check for command followed by whitespace */
@@ -644,8 +649,8 @@ parse_args(const char **cpp, int *pflag, unsigned long *n_arg,
return(cmdnum);
}
-int
-parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
+static int
+parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd)
{
char *path1, *path2, *tmp;
int pflag, cmdnum, i;
@@ -665,32 +670,26 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
case -1:
break;
case I_GET:
- err = process_get(in, out, path1, path2, *pwd, pflag);
+ err = process_get(conn, path1, path2, *pwd, pflag);
break;
case I_PUT:
- err = process_put(in, out, path1, path2, *pwd, pflag);
+ err = process_put(conn, path1, path2, *pwd, pflag);
break;
case I_RENAME:
path1 = make_absolute(path1, *pwd);
path2 = make_absolute(path2, *pwd);
- err = do_rename(in, out, path1, path2);
+ err = do_rename(conn, path1, path2);
break;
case I_SYMLINK:
- if (version < 3) {
- error("The server (version %d) does not support "
- "this operation", version);
- err = -1;
- } else {
- path2 = make_absolute(path2, *pwd);
- err = do_symlink(in, out, path1, path2);
- }
+ path2 = make_absolute(path2, *pwd);
+ err = do_symlink(conn, path1, path2);
break;
case I_RM:
path1 = make_absolute(path1, *pwd);
- remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g);
- for(i = 0; g.gl_pathv[i]; i++) {
+ remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
+ for (i = 0; g.gl_pathv[i]; i++) {
printf("Removing %s\n", g.gl_pathv[i]);
- if (do_rm(in, out, g.gl_pathv[i]) == -1)
+ if (do_rm(conn, g.gl_pathv[i]) == -1)
err = -1;
}
break;
@@ -699,19 +698,19 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
attrib_clear(&a);
a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
a.perm = 0777;
- err = do_mkdir(in, out, path1, &a);
+ err = do_mkdir(conn, path1, &a);
break;
case I_RMDIR:
path1 = make_absolute(path1, *pwd);
- err = do_rmdir(in, out, path1);
+ err = do_rmdir(conn, path1);
break;
case I_CHDIR:
path1 = make_absolute(path1, *pwd);
- if ((tmp = do_realpath(in, out, path1)) == NULL) {
+ if ((tmp = do_realpath(conn, path1)) == NULL) {
err = 1;
break;
}
- if ((aa = do_stat(in, out, tmp, 0)) == NULL) {
+ if ((aa = do_stat(conn, tmp, 0)) == NULL) {
xfree(tmp);
err = 1;
break;
@@ -734,22 +733,22 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
break;
case I_LS:
if (!path1) {
- do_ls(in, out, *pwd);
+ do_ls(conn, *pwd);
break;
}
path1 = make_absolute(path1, *pwd);
- if ((tmp = do_realpath(in, out, path1)) == NULL)
+ if ((tmp = do_realpath(conn, path1)) == NULL)
break;
xfree(path1);
path1 = tmp;
- if ((aa = do_stat(in, out, path1, 0)) == NULL)
+ if ((aa = do_stat(conn, path1, 0)) == NULL)
break;
if ((aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
!S_ISDIR(aa->perm)) {
error("Can't ls: \"%s\" is not a directory", path1);
break;
}
- do_ls(in, out, path1);
+ do_ls(conn, path1);
break;
case I_LCHDIR:
if (chdir(path1) == -1) {
@@ -780,17 +779,17 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
attrib_clear(&a);
a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
a.perm = n_arg;
- remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g);
- for(i = 0; g.gl_pathv[i]; i++) {
+ remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
+ for (i = 0; g.gl_pathv[i]; i++) {
printf("Changing mode on %s\n", g.gl_pathv[i]);
- do_setstat(in, out, g.gl_pathv[i], &a);
+ do_setstat(conn, g.gl_pathv[i], &a);
}
break;
case I_CHOWN:
path1 = make_absolute(path1, *pwd);
- remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g);
- for(i = 0; g.gl_pathv[i]; i++) {
- if (!(aa = do_stat(in, out, g.gl_pathv[i], 0)))
+ remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
+ for (i = 0; g.gl_pathv[i]; i++) {
+ if (!(aa = do_stat(conn, g.gl_pathv[i], 0)))
continue;
if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
error("Can't get current ownership of "
@@ -800,14 +799,14 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
printf("Changing owner on %s\n", g.gl_pathv[i]);
aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
aa->uid = n_arg;
- do_setstat(in, out, g.gl_pathv[i], aa);
+ do_setstat(conn, g.gl_pathv[i], aa);
}
break;
case I_CHGRP:
path1 = make_absolute(path1, *pwd);
- remote_glob(in, out, path1, GLOB_NOCHECK, NULL, &g);
- for(i = 0; g.gl_pathv[i]; i++) {
- if (!(aa = do_stat(in, out, g.gl_pathv[i], 0)))
+ remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
+ for (i = 0; g.gl_pathv[i]; i++) {
+ if (!(aa = do_stat(conn, g.gl_pathv[i], 0)))
continue;
if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
error("Can't get current ownership of "
@@ -817,7 +816,7 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
printf("Changing group on %s\n", g.gl_pathv[i]);
aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
aa->gid = n_arg;
- do_setstat(in, out, g.gl_pathv[i], aa);
+ do_setstat(conn, g.gl_pathv[i], aa);
}
break;
case I_PWD:
@@ -837,7 +836,7 @@ parse_dispatch_command(int in, int out, const char *cmd, char **pwd)
help();
break;
case I_VERSION:
- printf("SFTP protocol version %d\n", version);
+ printf("SFTP protocol version %d\n", sftp_proto_version(conn));
break;
default:
fatal("%d is not implemented", cmdnum);
@@ -863,12 +862,13 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
char *pwd;
char *dir = NULL;
char cmd[2048];
+ struct sftp_conn *conn;
- version = do_init(fd_in, fd_out);
- if (version == -1)
+ conn = do_init(fd_in, fd_out, copy_buffer_len, num_requests);
+ if (conn == NULL)
fatal("Couldn't initialise connection to server");
- pwd = do_realpath(fd_in, fd_out, ".");
+ pwd = do_realpath(conn, ".");
if (pwd == NULL)
fatal("Need cwd");
@@ -876,10 +876,10 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
dir = xstrdup(file1);
dir = make_absolute(dir, pwd);
- if (remote_is_dir(fd_in, fd_out, dir) && file2 == NULL) {
+ if (remote_is_dir(conn, dir) && file2 == NULL) {
printf("Changing to: %s\n", dir);
snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
- parse_dispatch_command(fd_in, fd_out, cmd, &pwd);
+ parse_dispatch_command(conn, cmd, &pwd);
} else {
if (file2 == NULL)
snprintf(cmd, sizeof cmd, "get %s", dir);
@@ -887,14 +887,14 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
snprintf(cmd, sizeof cmd, "get %s %s", dir,
file2);
- parse_dispatch_command(fd_in, fd_out, cmd, &pwd);
+ parse_dispatch_command(conn, cmd, &pwd);
return;
}
}
setvbuf(stdout, NULL, _IOLBF, 0);
setvbuf(infile, NULL, _IOLBF, 0);
- for(;;) {
+ for (;;) {
char *cp;
printf("sftp> ");
@@ -910,7 +910,7 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
if (cp)
*cp = '\0';
- if (parse_dispatch_command(fd_in, fd_out, cmd, &pwd))
+ if (parse_dispatch_command(conn, cmd, &pwd))
break;
}
xfree(pwd);
diff --git a/crypto/openssh/sftp-int.h b/crypto/openssh/sftp-int.h
index b47f862..9768758 100644
--- a/crypto/openssh/sftp-int.h
+++ b/crypto/openssh/sftp-int.h
@@ -1,7 +1,7 @@
-/* $OpenBSD: sftp-int.h,v 1.2 2001/04/12 23:17:54 mouring Exp $ */
+/* $OpenBSD: sftp-int.h,v 1.5 2002/02/13 00:59:23 djm Exp $ */
/*
- * Copyright (c) 2001 Damien Miller. All rights reserved.
+ * Copyright (c) 2001,2002 Damien Miller. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,4 +24,4 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-void interactive_loop(int fd_in, int fd_out, char *file1, char *file2);
+void interactive_loop(int, int, char *, char *);
diff --git a/crypto/openssh/sftp-server.8 b/crypto/openssh/sftp-server.8
index afb233e..70c951f 100644
--- a/crypto/openssh/sftp-server.8
+++ b/crypto/openssh/sftp-server.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sftp-server.8,v 1.6 2001/04/22 13:32:26 markus Exp $
+.\" $OpenBSD: sftp-server.8,v 1.8 2001/06/23 05:57:08 deraadt Exp $
.\"
.\" Copyright (c) 2000 Markus Friedl. All rights reserved.
.\"
diff --git a/crypto/openssh/sftp-server.c b/crypto/openssh/sftp-server.c
index b49f861..b98c5ff 100644
--- a/crypto/openssh/sftp-server.c
+++ b/crypto/openssh/sftp-server.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000 Markus Friedl. All rights reserved.
+ * Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -22,7 +22,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
-RCSID("$OpenBSD: sftp-server.c,v 1.25 2001/04/05 10:42:53 markus Exp $");
+RCSID("$OpenBSD: sftp-server.c,v 1.33 2002/02/13 00:28:13 markus Exp $");
#include "buffer.h"
#include "bufaux.h"
@@ -56,7 +56,7 @@ struct Stat {
Attrib attrib;
};
-int
+static int
errno_to_portable(int unixerrno)
{
int ret = 0;
@@ -87,7 +87,7 @@ errno_to_portable(int unixerrno)
return ret;
}
-int
+static int
flags_from_portable(int pflags)
{
int flags = 0;
@@ -109,7 +109,7 @@ flags_from_portable(int pflags)
return flags;
}
-Attrib *
+static Attrib *
get_attrib(void)
{
return decode_attrib(&iqueue);
@@ -133,21 +133,21 @@ enum {
Handle handles[100];
-void
+static void
handle_init(void)
{
int i;
- for(i = 0; i < sizeof(handles)/sizeof(Handle); i++)
+ for (i = 0; i < sizeof(handles)/sizeof(Handle); i++)
handles[i].use = HANDLE_UNUSED;
}
-int
+static int
handle_new(int use, char *name, int fd, DIR *dirp)
{
int i;
- for(i = 0; i < sizeof(handles)/sizeof(Handle); i++) {
+ for (i = 0; i < sizeof(handles)/sizeof(Handle); i++) {
if (handles[i].use == HANDLE_UNUSED) {
handles[i].use = use;
handles[i].dirp = dirp;
@@ -159,14 +159,14 @@ handle_new(int use, char *name, int fd, DIR *dirp)
return -1;
}
-int
+static int
handle_is_ok(int i, int type)
{
return i >= 0 && i < sizeof(handles)/sizeof(Handle) &&
handles[i].use == type;
}
-int
+static int
handle_to_string(int handle, char **stringp, int *hlenp)
{
if (stringp == NULL || hlenp == NULL)
@@ -177,7 +177,7 @@ handle_to_string(int handle, char **stringp, int *hlenp)
return 0;
}
-int
+static int
handle_from_string(char *handle, u_int hlen)
{
int val;
@@ -191,7 +191,7 @@ handle_from_string(char *handle, u_int hlen)
return -1;
}
-char *
+static char *
handle_to_name(int handle)
{
if (handle_is_ok(handle, HANDLE_DIR)||
@@ -200,7 +200,7 @@ handle_to_name(int handle)
return NULL;
}
-DIR *
+static DIR *
handle_to_dir(int handle)
{
if (handle_is_ok(handle, HANDLE_DIR))
@@ -208,7 +208,7 @@ handle_to_dir(int handle)
return NULL;
}
-int
+static int
handle_to_fd(int handle)
{
if (handle_is_ok(handle, HANDLE_FILE))
@@ -216,7 +216,7 @@ handle_to_fd(int handle)
return -1;
}
-int
+static int
handle_close(int handle)
{
int ret = -1;
@@ -233,7 +233,7 @@ handle_close(int handle)
return ret;
}
-int
+static int
get_handle(void)
{
char *handle;
@@ -249,7 +249,7 @@ get_handle(void)
/* send replies */
-void
+static void
send_msg(Buffer *m)
{
int mlen = buffer_len(m);
@@ -259,7 +259,7 @@ send_msg(Buffer *m)
buffer_consume(m, mlen);
}
-void
+static void
send_status(u_int32_t id, u_int32_t error)
{
Buffer msg;
@@ -289,7 +289,7 @@ send_status(u_int32_t id, u_int32_t error)
send_msg(&msg);
buffer_free(&msg);
}
-void
+static void
send_data_or_handle(char type, u_int32_t id, char *data, int dlen)
{
Buffer msg;
@@ -302,14 +302,14 @@ send_data_or_handle(char type, u_int32_t id, char *data, int dlen)
buffer_free(&msg);
}
-void
+static void
send_data(u_int32_t id, char *data, int dlen)
{
TRACE("sent data id %d len %d", id, dlen);
send_data_or_handle(SSH2_FXP_DATA, id, data, dlen);
}
-void
+static void
send_handle(u_int32_t id, int handle)
{
char *string;
@@ -321,7 +321,7 @@ send_handle(u_int32_t id, int handle)
xfree(string);
}
-void
+static void
send_names(u_int32_t id, int count, Stat *stats)
{
Buffer msg;
@@ -341,7 +341,7 @@ send_names(u_int32_t id, int count, Stat *stats)
buffer_free(&msg);
}
-void
+static void
send_attrib(u_int32_t id, Attrib *a)
{
Buffer msg;
@@ -357,7 +357,7 @@ send_attrib(u_int32_t id, Attrib *a)
/* parse incoming */
-void
+static void
process_init(void)
{
Buffer msg;
@@ -371,7 +371,7 @@ process_init(void)
buffer_free(&msg);
}
-void
+static void
process_open(void)
{
u_int32_t id, pflags;
@@ -403,7 +403,7 @@ process_open(void)
xfree(name);
}
-void
+static void
process_close(void)
{
u_int32_t id;
@@ -417,7 +417,7 @@ process_close(void)
send_status(id, status);
}
-void
+static void
process_read(void)
{
char buf[64*1024];
@@ -457,7 +457,7 @@ process_read(void)
send_status(id, status);
}
-void
+static void
process_write(void)
{
u_int32_t id;
@@ -495,7 +495,7 @@ process_write(void)
xfree(data);
}
-void
+static void
process_do_stat(int do_lstat)
{
Attrib a;
@@ -520,19 +520,19 @@ process_do_stat(int do_lstat)
xfree(name);
}
-void
+static void
process_stat(void)
{
process_do_stat(0);
}
-void
+static void
process_lstat(void)
{
process_do_stat(1);
}
-void
+static void
process_fstat(void)
{
Attrib a;
@@ -558,7 +558,7 @@ process_fstat(void)
send_status(id, status);
}
-struct timeval *
+static struct timeval *
attrib_to_tv(Attrib *a)
{
static struct timeval tv[2];
@@ -570,7 +570,7 @@ attrib_to_tv(Attrib *a)
return tv;
}
-void
+static void
process_setstat(void)
{
Attrib *a;
@@ -583,6 +583,11 @@ process_setstat(void)
name = get_string(NULL);
a = get_attrib();
TRACE("setstat id %d name %s", id, name);
+ if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
+ ret = truncate(name, a->size);
+ if (ret == -1)
+ status = errno_to_portable(errno);
+ }
if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
ret = chmod(name, a->perm & 0777);
if (ret == -1)
@@ -602,7 +607,7 @@ process_setstat(void)
xfree(name);
}
-void
+static void
process_fsetstat(void)
{
Attrib *a;
@@ -618,6 +623,11 @@ process_fsetstat(void)
if (fd < 0) {
status = SSH2_FX_FAILURE;
} else {
+ if (a->flags & SSH2_FILEXFER_ATTR_SIZE) {
+ ret = ftruncate(fd, a->size);
+ if (ret == -1)
+ status = errno_to_portable(errno);
+ }
if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
ret = fchmod(fd, a->perm & 0777);
if (ret == -1)
@@ -637,7 +647,7 @@ process_fsetstat(void)
send_status(id, status);
}
-void
+static void
process_opendir(void)
{
DIR *dirp = NULL;
@@ -669,10 +679,10 @@ process_opendir(void)
/*
* drwxr-xr-x 5 markus markus 1024 Jan 13 18:39 .ssh
*/
-char *
+static char *
ls_file(char *name, struct stat *st)
{
- int sz = 0;
+ int ulen, glen, sz = 0;
struct passwd *pw;
struct group *gr;
struct tm *ltime = localtime(&st->st_mtime);
@@ -700,12 +710,15 @@ ls_file(char *name, struct stat *st)
}
if (sz == 0)
tbuf[0] = '\0';
- snprintf(buf, sizeof buf, "%s %3d %-8.8s %-8.8s %8llu %s %s", mode,
- st->st_nlink, user, group, (unsigned long long)st->st_size, tbuf, name);
+ ulen = MAX(strlen(user), 8);
+ glen = MAX(strlen(group), 8);
+ snprintf(buf, sizeof buf, "%s %3d %-*s %-*s %8llu %s %s", mode,
+ st->st_nlink, ulen, user, glen, group,
+ (unsigned long long)st->st_size, tbuf, name);
return xstrdup(buf);
}
-void
+static void
process_readdir(void)
{
DIR *dirp;
@@ -733,8 +746,8 @@ process_readdir(void)
stats = xrealloc(stats, nstats * sizeof(Stat));
}
/* XXX OVERFLOW ? */
- snprintf(pathname, sizeof pathname,
- "%s/%s", path, dp->d_name);
+ snprintf(pathname, sizeof pathname, "%s%s%s", path,
+ strcmp(path, "/") ? "/" : "", dp->d_name);
if (lstat(pathname, &st) < 0)
continue;
stat_to_attrib(&st, &(stats[count].attrib));
@@ -748,7 +761,7 @@ process_readdir(void)
}
if (count > 0) {
send_names(id, count, stats);
- for(i = 0; i < count; i++) {
+ for (i = 0; i < count; i++) {
xfree(stats[i].name);
xfree(stats[i].long_name);
}
@@ -759,7 +772,7 @@ process_readdir(void)
}
}
-void
+static void
process_remove(void)
{
char *name;
@@ -776,7 +789,7 @@ process_remove(void)
xfree(name);
}
-void
+static void
process_mkdir(void)
{
Attrib *a;
@@ -796,7 +809,7 @@ process_mkdir(void)
xfree(name);
}
-void
+static void
process_rmdir(void)
{
u_int32_t id;
@@ -812,7 +825,7 @@ process_rmdir(void)
xfree(name);
}
-void
+static void
process_realpath(void)
{
char resolvedname[MAXPATHLEN];
@@ -837,7 +850,7 @@ process_realpath(void)
xfree(path);
}
-void
+static void
process_rename(void)
{
u_int32_t id;
@@ -859,22 +872,23 @@ process_rename(void)
xfree(newpath);
}
-void
+static void
process_readlink(void)
{
u_int32_t id;
+ int len;
char link[MAXPATHLEN];
char *path;
id = get_int();
path = get_string(NULL);
TRACE("readlink id %d path %s", id, path);
- if (readlink(path, link, sizeof(link) - 1) == -1)
+ if ((len = readlink(path, link, sizeof(link) - 1)) == -1)
send_status(id, errno_to_portable(errno));
else {
Stat s;
-
- link[sizeof(link) - 1] = '\0';
+
+ link[len] = '\0';
attrib_clear(&s.attrib);
s.name = s.long_name = link;
send_names(id, 1, &s);
@@ -882,7 +896,7 @@ process_readlink(void)
xfree(path);
}
-void
+static void
process_symlink(void)
{
u_int32_t id;
@@ -904,7 +918,7 @@ process_symlink(void)
xfree(newpath);
}
-void
+static void
process_extended(void)
{
u_int32_t id;
@@ -918,7 +932,7 @@ process_extended(void)
/* stolen from ssh-agent */
-void
+static void
process(void)
{
u_int msg_len;
@@ -927,7 +941,7 @@ process(void)
if (buffer_len(&iqueue) < 5)
return; /* Incomplete message. */
- cp = (u_char *) buffer_ptr(&iqueue);
+ cp = buffer_ptr(&iqueue);
msg_len = GET_32BIT(cp);
if (msg_len > 256 * 1024) {
error("bad message ");
diff --git a/crypto/openssh/sftp.1 b/crypto/openssh/sftp.1
index b482996..2faaff1 100644
--- a/crypto/openssh/sftp.1
+++ b/crypto/openssh/sftp.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sftp.1,v 1.17 2001/04/22 13:32:27 markus Exp $
+.\" $OpenBSD: sftp.1,v 1.33 2002/02/26 19:06:43 deraadt Exp $
.\"
.\" Copyright (c) 2001 Damien Miller. All rights reserved.
.\"
@@ -30,14 +30,20 @@
.Nd Secure file transfer program
.Sh SYNOPSIS
.Nm sftp
-.Op Fl vC
+.Op Fl vC1
.Op Fl b Ar batchfile
.Op Fl o Ar ssh_option
-.Op Ar host
+.Op Fl s Ar subsystem | sftp_server
+.Op Fl B Ar buffer_size
+.Op Fl F Ar ssh_config
+.Op Fl P Ar sftp_server path
+.Op Fl R Ar num_requests
+.Op Fl S Ar program
+.Ar host
.Nm sftp
.Op [\fIuser\fR@]\fIhost\fR[:\fIfile\fR [\fIfile\fR]]
.Nm sftp
-.Op [\fIuser\fR@]\fIhost\fR[:\fIdir\fR[\fI/\fR]]
+.Op [\fIuser\fR@]\fIhost\fR[:\fIdir\fR[\fI/\fR]]
.Sh DESCRIPTION
.Nm
is an interactive file transfer program, similar to
@@ -49,12 +55,12 @@ It may also use many features of ssh, such as public key authentication and
compression.
.Nm
connects and logs into the specified
-.Ar hostname ,
+.Ar host ,
then enters an interactive command mode.
.Pp
-The second usage format will fetch files automaticly if a non-interactive
-authentication is used, else it do so after an interactive authentication
-is used.
+The second usage format will retrieve files automatically if a non-interactive
+authentication method is used; otherwise it will do so after
+successful interactive authentication.
.Pp
The last usage format allows the sftp client to start in a remote directory.
.Pp
@@ -68,49 +74,96 @@ instead of
Since it lacks user interaction it should be used in conjunction with
non-interactive authentication.
.Nm
-will abort if any of the following
-commands fail:
-.Ic get , put , rename , ln , rm , mkdir , chdir , lchdir
+will abort if any of the following
+commands fail:
+.Ic get , put , rename , ln ,
+.Ic rm , mkdir , chdir , lchdir
and
.Ic lmkdir .
-.It Fl C
-Enables compression (via ssh's
-.Fl C
-flag)
.It Fl o Ar ssh_option
-Specify an option to be directly passed to
-.Xr ssh 1 .
+Can be used to pass options to
+.Nm ssh
+in the format used in the
+.Xr ssh 1
+configuration file. This is useful for specifying options
+for which there is no separate
+.Nm sftp
+command-line flag. For example, to specify an alternate
+port use:
+.Ic sftp -oPort=24 .
+.It Fl s Ar subsystem | sftp_server
+Specifies the SSH2 subsystem or the path for an sftp server
+on the remote host. A path is useful for using sftp over
+protocol version 1, or when the remote
+.Nm sshd
+does not have an sftp subsystem configured.
.It Fl v
Raise logging level. This option is also passed to ssh.
+.It Fl B Ar buffer_size
+Specify the size of the buffer that
+.Nm
+uses when transferring files. Larger buffers require fewer round trips at
+the cost of higher memory consumption. The default is 32768 bytes.
+.It Fl C
+Enables compression (via ssh's
+.Fl C
+flag).
+.It Fl F Ar ssh_config
+Specifies an alternative
+per-user configuration file for
+.Nm ssh .
+This option is directly passed to
+.Xr ssh 1 .
+.It Fl P Ar sftp_server path
+Connect directly to a local
+.Nm sftp-server
+(rather than via
+.Nm ssh )
+This option may be useful in debugging the client and server.
+.It Fl R Ar num_requests
+Specify how many requests may be outstanding at any one time. Increasing
+this may slightly improve file transfer speed but will increase memory
+usage. The default is 16 outstanding requests.
+.It Fl S Ar program
+Name of the
+.Ar program
+to use for the encrypted connection.
+The program must understand
+.Xr ssh 1
+options.
+.It Fl 1
+Specify the use of protocol version 1.
.El
.Sh INTERACTIVE COMMANDS
Once in interactive mode,
.Nm
-understands a set of commands similar to those of
+understands a set of commands similar to those of
.Xr ftp 1 .
Commands are case insensitive and pathnames may be enclosed in quotes if they
contain spaces.
.Bl -tag -width Ds
+.It Ic bye
+Quit sftp.
.It Ic cd Ar path
-Change remote directory to
+Change remote directory to
.Ar path .
.It Ic lcd Ar path
-Change local directory to
+Change local directory to
.Ar path .
.It Ic chgrp Ar grp Ar path
-Change group of file
+Change group of file
.Ar path
to
.Ar grp .
.Ar grp
must be a numeric GID.
.It Ic chmod Ar mode Ar path
-Change permissions of file
+Change permissions of file
.Ar path
to
.Ar mode .
.It Ic chown Ar own Ar path
-Change owner of file
+Change owner of file
.Ar path
to
.Ar own .
@@ -127,15 +180,15 @@ Retrieve the
.Ar remote-path
and store it on the local machine.
If the local
-path name is not specified, it is given the same name it has on the
-remote machine. If the
+path name is not specified, it is given the same name it has on the
+remote machine. If the
.Fl P
flag is specified, then the file's full permission and access time are
copied too.
.It Ic help
Display help text.
.It Ic lls Op Ar ls-options Op Ar path
-Display local directory listing of either
+Display local directory listing of either
.Ar path
or current directory if
.Ar path
@@ -144,7 +197,7 @@ is not specified.
Create local directory specified by
.Ar path .
.It Ic ln Ar oldpath Ar newpath
-Create a symbolic link from
+Create a symbolic link from
.Ar oldpath
to
.Ar newpath .
@@ -157,7 +210,7 @@ or current directory if
.Ar path
is not specified.
.It Ic lumask Ar umask
-Set local umask to
+Set local umask to
.Ar umask .
.It Ic mkdir Ar path
Create remote directory specified by
@@ -169,8 +222,8 @@ Create remote directory specified by
.Xc
Upload
.Ar local-path
-and store it on the remote machine. If the remote path name is not
-specified, it is given the same name it has on the local machine. If the
+and store it on the remote machine. If the remote path name is not
+specified, it is given the same name it has on the local machine. If the
.Fl P
flag is specified, then the file's full permission and access time are
copied too.
@@ -190,12 +243,12 @@ Remove remote directory specified by
Delete remote file specified by
.Ar path .
.It Ic symlink Ar oldpath Ar newpath
-Create a symbolic link from
+Create a symbolic link from
.Ar oldpath
to
.Ar newpath .
.It Ic ! Ar command
-Execute
+Execute
.Ar command
in local shell.
.It Ic !
diff --git a/crypto/openssh/sftp.c b/crypto/openssh/sftp.c
index 2c57bef..0a7689c 100644
--- a/crypto/openssh/sftp.c
+++ b/crypto/openssh/sftp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001 Damien Miller. All rights reserved.
+ * Copyright (c) 2001,2002 Damien Miller. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,30 +24,27 @@
#include "includes.h"
-RCSID("$OpenBSD: sftp.c,v 1.15 2001/04/16 02:31:44 mouring Exp $");
+RCSID("$OpenBSD: sftp.c,v 1.26 2002/02/12 12:32:27 djm Exp $");
-/* XXX: commandline mode */
/* XXX: short-form remote directory listings (like 'ls -C') */
#include "buffer.h"
#include "xmalloc.h"
#include "log.h"
#include "pathnames.h"
+#include "misc.h"
#include "sftp.h"
#include "sftp-common.h"
#include "sftp-client.h"
#include "sftp-int.h"
-#include "scp-common.h"
-
-int use_ssh1 = 0;
-char *ssh_program = _PATH_SSH_PROGRAM;
-char *sftp_server = NULL;
FILE* infile;
+size_t copy_buffer_len = 32768;
+size_t num_requests = 16;
-void
-connect_to_server(char **args, int *in, int *out, pid_t *sshpid)
+static void
+connect_to_server(char *path, char **args, int *in, int *out, pid_t *sshpid)
{
int c_in, c_out;
#ifdef USE_PIPES
@@ -78,8 +75,8 @@ connect_to_server(char **args, int *in, int *out, pid_t *sshpid)
close(*out);
close(c_in);
close(c_out);
- execv(ssh_program, args);
- fprintf(stderr, "exec: %s: %s\n", ssh_program, strerror(errno));
+ execv(path, args);
+ fprintf(stderr, "exec: %s: %s\n", path, strerror(errno));
exit(1);
}
@@ -87,93 +84,59 @@ connect_to_server(char **args, int *in, int *out, pid_t *sshpid)
close(c_out);
}
-char **
-make_ssh_args(char *add_arg)
-{
- static char **args = NULL;
- static int nargs = 0;
- char debug_buf[4096];
- int i;
-
- /* Init args array */
- if (args == NULL) {
- nargs = 2;
- i = 0;
- args = xmalloc(sizeof(*args) * nargs);
- args[i++] = "ssh";
- args[i++] = NULL;
- }
-
- /* If asked to add args, then do so and return */
- if (add_arg) {
- i = nargs++ - 1;
- args = xrealloc(args, sizeof(*args) * nargs);
- args[i++] = add_arg;
- args[i++] = NULL;
- return(NULL);
- }
-
- /* no subsystem if the server-spec contains a '/' */
- if (sftp_server == NULL || strchr(sftp_server, '/') == NULL)
- make_ssh_args("-s");
- make_ssh_args("-oForwardX11=no");
- make_ssh_args("-oForwardAgent=no");
- make_ssh_args(use_ssh1 ? "-oProtocol=1" : "-oProtocol=2");
-
- /* Otherwise finish up and return the arg array */
- if (sftp_server != NULL)
- make_ssh_args(sftp_server);
- else
- make_ssh_args("sftp");
-
- /* XXX: overflow - doesn't grow debug_buf */
- debug_buf[0] = '\0';
- for(i = 0; args[i]; i++) {
- if (i)
- strlcat(debug_buf, " ", sizeof(debug_buf));
-
- strlcat(debug_buf, args[i], sizeof(debug_buf));
- }
- debug("SSH args \"%s\"", debug_buf);
-
- return(args);
-}
-
-void
+static void
usage(void)
{
- fprintf(stderr, "usage: sftp [-1vC] [-b batchfile] [-osshopt=value] [user@]host[:file [file]]\n");
+ extern char *__progname;
+
+ fprintf(stderr,
+ "usage: %s [-vC1] [-b batchfile] [-o option] [-s subsystem|path] [-B buffer_size]\n"
+ " [-F config] [-P direct server path] [-S program]\n"
+ " [user@]host[:file [file]]\n", __progname);
exit(1);
}
int
main(int argc, char **argv)
{
- int in, out, ch, debug_level, compress_flag;
+ int in, out, ch;
pid_t sshpid;
- char *file1 = NULL;
char *host, *userhost, *cp, *file2;
- LogLevel ll;
+ int debug_level = 0, sshver = 2;
+ char *file1 = NULL, *sftp_server = NULL;
+ char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL;
+ LogLevel ll = SYSLOG_LEVEL_INFO;
+ arglist args;
extern int optind;
extern char *optarg;
+ args.list = NULL;
+ addargs(&args, "ssh"); /* overwritten with ssh_program */
+ addargs(&args, "-oFallBackToRsh no");
+ addargs(&args, "-oForwardX11 no");
+ addargs(&args, "-oForwardAgent no");
+ addargs(&args, "-oClearAllForwardings yes");
+ ll = SYSLOG_LEVEL_INFO;
infile = stdin; /* Read from STDIN unless changed by -b */
- debug_level = compress_flag = 0;
- while ((ch = getopt(argc, argv, "1hvCo:s:S:b:")) != -1) {
+ while ((ch = getopt(argc, argv, "1hvCo:s:S:b:B:F:P:R:")) != -1) {
switch (ch) {
case 'C':
- compress_flag = 1;
+ addargs(&args, "-C");
break;
case 'v':
- debug_level = MIN(3, debug_level + 1);
+ if (debug_level < 3) {
+ addargs(&args, "-v");
+ ll = SYSLOG_LEVEL_DEBUG1 + debug_level;
+ }
+ debug_level++;
break;
+ case 'F':
case 'o':
- make_ssh_args("-o");
- make_ssh_args(optarg);
+ addargs(&args, "-%c%s", ch, optarg);
break;
case '1':
- use_ssh1 = 1;
+ sshver = 1;
if (sftp_server == NULL)
sftp_server = _PATH_SFTP_SERVER;
break;
@@ -191,71 +154,78 @@ main(int argc, char **argv)
} else
fatal("Filename already specified.");
break;
+ case 'P':
+ sftp_direct = optarg;
+ break;
+ case 'B':
+ copy_buffer_len = strtol(optarg, &cp, 10);
+ if (copy_buffer_len == 0 || *cp != '\0')
+ fatal("Invalid buffer size \"%s\"", optarg);
+ break;
+ case 'R':
+ num_requests = strtol(optarg, &cp, 10);
+ if (num_requests == 0 || *cp != '\0')
+ fatal("Invalid number of requests \"%s\"",
+ optarg);
+ break;
case 'h':
default:
usage();
}
}
- if (optind == argc || argc > (optind + 2))
- usage();
-
- userhost = xstrdup(argv[optind]);
- file2 = argv[optind+1];
+ if (sftp_direct == NULL) {
+ if (optind == argc || argc > (optind + 2))
+ usage();
- if ((cp = colon(userhost)) != NULL) {
- *cp++ = '\0';
- file1 = cp;
- }
+ userhost = xstrdup(argv[optind]);
+ file2 = argv[optind+1];
- if ((host = strchr(userhost, '@')) == NULL)
- host = userhost;
- else {
- *host++ = '\0';
- if (!userhost[0]) {
- fprintf(stderr, "Missing username\n");
- usage();
+ if ((cp = colon(userhost)) != NULL) {
+ *cp++ = '\0';
+ file1 = cp;
}
- make_ssh_args("-l");
- make_ssh_args(userhost);
- }
- host = cleanhostname(host);
- if (!*host) {
- fprintf(stderr, "Missing hostname\n");
- usage();
- }
+ if ((host = strchr(userhost, '@')) == NULL)
+ host = userhost;
+ else {
+ *host++ = '\0';
+ if (!userhost[0]) {
+ fprintf(stderr, "Missing username\n");
+ usage();
+ }
+ addargs(&args, "-l%s",userhost);
+ }
- /* Set up logging and debug '-d' arguments to ssh */
- ll = SYSLOG_LEVEL_INFO;
- switch (debug_level) {
- case 1:
- ll = SYSLOG_LEVEL_DEBUG1;
- make_ssh_args("-v");
- break;
- case 2:
- ll = SYSLOG_LEVEL_DEBUG2;
- make_ssh_args("-v");
- make_ssh_args("-v");
- break;
- case 3:
- ll = SYSLOG_LEVEL_DEBUG3;
- make_ssh_args("-v");
- make_ssh_args("-v");
- make_ssh_args("-v");
- break;
- }
+ host = cleanhostname(host);
+ if (!*host) {
+ fprintf(stderr, "Missing hostname\n");
+ usage();
+ }
- if (compress_flag)
- make_ssh_args("-C");
+ log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
+ addargs(&args, "-oProtocol %d", sshver);
- log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
+ /* no subsystem if the server-spec contains a '/' */
+ if (sftp_server == NULL || strchr(sftp_server, '/') == NULL)
+ addargs(&args, "-s");
- make_ssh_args(host);
+ addargs(&args, "%s", host);
+ addargs(&args, "%s", (sftp_server != NULL ?
+ sftp_server : "sftp"));
+ args.list[0] = ssh_program;
- fprintf(stderr, "Connecting to %s...\n", host);
+ fprintf(stderr, "Connecting to %s...\n", host);
+ connect_to_server(ssh_program, args.list, &in, &out,
+ &sshpid);
+ } else {
+ args.list = NULL;
+ addargs(&args, "sftp-server");
- connect_to_server(make_ssh_args(NULL), &in, &out, &sshpid);
+ fprintf(stderr, "Attaching to %s...\n", sftp_direct);
+ connect_to_server(sftp_direct, args.list, &in, &out,
+ &sshpid);
+ }
interactive_loop(in, out, file1, file2);
diff --git a/crypto/openssh/sftp.h b/crypto/openssh/sftp.h
index 2ad9586..675c608 100644
--- a/crypto/openssh/sftp.h
+++ b/crypto/openssh/sftp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp.h,v 1.3 2001/03/07 10:11:23 djm Exp $ */
+/* $OpenBSD: sftp.h,v 1.4 2002/02/13 00:59:23 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -38,6 +38,7 @@
#define SSH2_FXP_READ 5
#define SSH2_FXP_WRITE 6
#define SSH2_FXP_LSTAT 7
+#define SSH2_FXP_STAT_VERSION_0 7
#define SSH2_FXP_FSTAT 8
#define SSH2_FXP_SETSTAT 9
#define SSH2_FXP_FSETSTAT 10
diff --git a/crypto/openssh/sftp/Makefile b/crypto/openssh/sftp/Makefile
index 83fa8dc..3f5d866 100644
--- a/crypto/openssh/sftp/Makefile
+++ b/crypto/openssh/sftp/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.4 2001/04/16 02:31:52 mouring Exp $
+# $OpenBSD: Makefile,v 1.5 2001/05/03 23:09:57 mouring Exp $
.PATH: ${.CURDIR}/..
@@ -10,7 +10,7 @@ BINMODE?=555
BINDIR= /usr/bin
MAN= sftp.1
-SRCS= sftp.c sftp-client.c sftp-int.c sftp-common.c sftp-glob.c scp-common.c
+SRCS= sftp.c sftp-client.c sftp-int.c sftp-common.c sftp-glob.c misc.c
.include <bsd.prog.mk>
diff --git a/crypto/openssh/ssh-add.1 b/crypto/openssh/ssh-add.1
index d7725c6..41d5def 100644
--- a/crypto/openssh/ssh-add.1
+++ b/crypto/openssh/ssh-add.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-add.1,v 1.24 2001/04/10 09:13:21 itojun Exp $
+.\" $OpenBSD: ssh-add.1,v 1.30 2002/02/04 20:41:16 stevesk Exp $
.\"
.\" -*- nroff -*-
.\"
@@ -42,22 +42,29 @@
.Os
.Sh NAME
.Nm ssh-add
-.Nd adds RSA or DSA identities for the authentication agent
+.Nd adds RSA or DSA identities to the authentication agent
.Sh SYNOPSIS
.Nm ssh-add
.Op Fl lLdD
.Op Ar
+.Nm ssh-add
+.Fl s Ar reader
+.Nm ssh-add
+.Fl e Ar reader
.Sh DESCRIPTION
.Nm
adds RSA or DSA identities to the authentication agent,
.Xr ssh-agent 1 .
-When run without arguments, it adds the file
+When run without arguments, it adds the files
+.Pa $HOME/.ssh/id_rsa ,
+.Pa $HOME/.ssh/id_dsa
+and
.Pa $HOME/.ssh/identity .
Alternative file names can be given on the command line.
If any file requires a passphrase,
.Nm
asks for the passphrase from the user.
-The Passphrase it is read from the user's tty.
+The passphrase is read from the user's tty.
.Nm
retries the last passphrase if multiple identity files are given.
.Pp
@@ -76,26 +83,27 @@ Lists public key parameters of all identities currently represented by the agent
Instead of adding the identity, removes the identity from the agent.
.It Fl D
Deletes all identities from the agent.
+.It Fl s Ar reader
+Add key in smartcard
+.Ar reader .
+.It Fl e Ar reader
+Remove key in smartcard
+.Ar reader .
.El
.Sh FILES
.Bl -tag -width Ds
.It Pa $HOME/.ssh/identity
Contains the protocol version 1 RSA authentication identity of the user.
-This file should not be readable by anyone but the user.
-Note that
-.Nm
-ignores this file if it is accessible by others.
-It is possible to
-specify a passphrase when generating the key; that passphrase will be
-used to encrypt the private part of this file.
-This is the default file added by
-.Nm
-when no other files have been specified.
.It Pa $HOME/.ssh/id_dsa
Contains the protocol version 2 DSA authentication identity of the user.
.It Pa $HOME/.ssh/id_rsa
Contains the protocol version 2 RSA authentication identity of the user.
.El
+.Pp
+Identity files should not be readable by anyone but the user.
+Note that
+.Nm
+ignores identity files if they are accessible by others.
.Sh ENVIRONMENT
.Bl -tag -width Ds
.It Ev "DISPLAY" and "SSH_ASKPASS"
@@ -122,6 +130,11 @@ may be necessary to redirect the input from
.Pa /dev/null
to make this work.)
.El
+.Sh DIAGNOSTICS
+Exit status is 0 on success, 1 if the specified command fails,
+and 2 if
+.Nm
+is unable to contact the authentication agent.
.Sh AUTHORS
OpenSSH is a derivative of the original and free
ssh 1.2.12 release by Tatu Ylonen.
diff --git a/crypto/openssh/ssh-agent.1 b/crypto/openssh/ssh-agent.1
index 1d21469..9909ef5 100644
--- a/crypto/openssh/ssh-agent.1
+++ b/crypto/openssh/ssh-agent.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-agent.1,v 1.24 2001/04/10 09:13:21 itojun Exp $
+.\" $OpenBSD: ssh-agent.1,v 1.31 2002/02/04 20:41:16 stevesk Exp $
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -42,11 +42,11 @@
.Nd authentication agent
.Sh SYNOPSIS
.Nm ssh-agent
-.Ar command
-.Ar args ...
-.Nm ssh-agent
.Op Fl c Li | Fl s
+.Op Fl d
+.Op Ar command Op Ar args ...
.Nm ssh-agent
+.Op Fl c Li | Fl s
.Fl k
.Sh DESCRIPTION
.Nm
@@ -80,6 +80,10 @@ does not look like it's a csh style of shell.
Kill the current agent (given by the
.Ev SSH_AGENT_PID
environment variable).
+.It Fl d
+Debug mode. When this option is specified
+.Nm
+will not fork.
.El
.Pp
If a commandline is given, this is executed as a subprocess of the agent.
@@ -90,9 +94,11 @@ Keys are added using
.Xr ssh-add 1 .
When executed without arguments,
.Xr ssh-add 1
-adds the
-.Pa $HOME/.ssh/identity
-file.
+adds the files
+.Pa $HOME/.ssh/id_rsa ,
+.Pa $HOME/.ssh/id_dsa
+and
+.Pa $HOME/.ssh/identity .
If the identity has a passphrase,
.Xr ssh-add 1
asks for the passphrase (using a small X11 application if running
@@ -112,9 +118,9 @@ remote logins, and the user can thus use the privileges given by the
identities anywhere in the network in a secure way.
.Pp
There are two main ways to get an agent setup:
-Either you let the agent
-start a new subcommand into which some environment variables are exported, or
-you let the agent print the needed shell commands (either
+Either the agent starts a new subcommand into which some environment
+variables are exported, or the agent prints the needed shell commands
+(either
.Xr sh 1
or
.Xr csh 1
@@ -123,6 +129,11 @@ Later
.Xr ssh 1
looks at these variables and uses them to establish a connection to the agent.
.Pp
+The agent will never send a private key over its request channel.
+Instead, operations that require a private key will be performed
+by the agent, and the result will be returned to the requester.
+This way, private keys are not exposed to clients using the agent.
+.Pp
A unix-domain socket is created
.Pq Pa /tmp/ssh-XXXXXXXX/agent.<pid> ,
and the name of this socket is stored in the
@@ -143,15 +154,6 @@ line terminates.
.Bl -tag -width Ds
.It Pa $HOME/.ssh/identity
Contains the protocol version 1 RSA authentication identity of the user.
-This file should not be readable by anyone but the user.
-It is possible to
-specify a passphrase when generating the key; that passphrase will be
-used to encrypt the private part of this file.
-This file is not used by
-.Nm
-but is normally added to the agent using
-.Xr ssh-add 1
-at login time.
.It Pa $HOME/.ssh/id_dsa
Contains the protocol version 2 DSA authentication identity of the user.
.It Pa $HOME/.ssh/id_rsa
diff --git a/crypto/openssh/ssh-agent/Makefile b/crypto/openssh/ssh-agent/Makefile
index e1a2e2c..c252dbd 100644
--- a/crypto/openssh/ssh-agent/Makefile
+++ b/crypto/openssh/ssh-agent/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.17 2001/03/04 00:51:25 markus Exp $
+# $OpenBSD: Makefile,v 1.21 2001/06/27 19:29:16 markus Exp $
.PATH: ${.CURDIR}/..
diff --git a/crypto/openssh/ssh-dss.c b/crypto/openssh/ssh-dss.c
index adc8f98..02403f5 100644
--- a/crypto/openssh/ssh-dss.c
+++ b/crypto/openssh/ssh-dss.c
@@ -23,7 +23,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: ssh-dss.c,v 1.6 2001/02/08 19:30:52 itojun Exp $");
+RCSID("$OpenBSD: ssh-dss.c,v 1.14 2002/02/28 15:46:33 markus Exp $");
#include <openssl/bn.h>
#include <openssl/evp.h>
@@ -42,36 +42,31 @@ RCSID("$OpenBSD: ssh-dss.c,v 1.6 2001/02/08 19:30:52 itojun Exp $");
int
ssh_dss_sign(
Key *key,
- u_char **sigp, int *lenp,
- u_char *data, int datalen)
+ u_char **sigp, u_int *lenp,
+ u_char *data, u_int datalen)
{
- u_char *digest;
- u_char *ret;
DSA_SIG *sig;
- EVP_MD *evp_md = EVP_sha1();
+ const EVP_MD *evp_md = EVP_sha1();
EVP_MD_CTX md;
- u_int rlen;
- u_int slen;
- u_int len, dlen;
- u_char sigblob[SIGBLOB_LEN];
+ u_char *ret, digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
+ u_int rlen, slen, len, dlen;
Buffer b;
if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
error("ssh_dss_sign: no DSA key");
return -1;
}
- dlen = evp_md->md_size;
- digest = xmalloc(dlen);
EVP_DigestInit(&md, evp_md);
EVP_DigestUpdate(&md, data, datalen);
- EVP_DigestFinal(&md, digest, NULL);
+ EVP_DigestFinal(&md, digest, &dlen);
sig = DSA_do_sign(digest, dlen, key->dsa);
+ memset(digest, 'd', sizeof(digest));
+
if (sig == NULL) {
- fatal("ssh_dss_sign: cannot sign");
+ error("ssh_dss_sign: sign failed");
+ return -1;
}
- memset(digest, 0, dlen);
- xfree(digest);
rlen = BN_num_bytes(sig->r);
slen = BN_num_bytes(sig->s);
@@ -80,15 +75,12 @@ ssh_dss_sign(
DSA_SIG_free(sig);
return -1;
}
- debug("sig size %d %d", rlen, slen);
-
memset(sigblob, 0, SIGBLOB_LEN);
BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
DSA_SIG_free(sig);
if (datafellows & SSH_BUG_SIGBLOB) {
- debug("datafellows");
ret = xmalloc(SIGBLOB_LEN);
memcpy(ret, sigblob, SIGBLOB_LEN);
if (lenp != NULL)
@@ -114,37 +106,22 @@ ssh_dss_sign(
int
ssh_dss_verify(
Key *key,
- u_char *signature, int signaturelen,
- u_char *data, int datalen)
+ u_char *signature, u_int signaturelen,
+ u_char *data, u_int datalen)
{
- Buffer b;
- u_char *digest;
DSA_SIG *sig;
- EVP_MD *evp_md = EVP_sha1();
+ const EVP_MD *evp_md = EVP_sha1();
EVP_MD_CTX md;
- u_char *sigblob;
- char *txt;
+ u_char digest[EVP_MAX_MD_SIZE], *sigblob;
u_int len, dlen;
- int rlen;
- int ret;
+ int rlen, ret;
+ Buffer b;
if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
error("ssh_dss_verify: no DSA key");
return -1;
}
- if (!(datafellows & SSH_BUG_SIGBLOB) &&
- signaturelen == SIGBLOB_LEN) {
- datafellows |= ~SSH_BUG_SIGBLOB;
- log("autodetect SSH_BUG_SIGBLOB");
- } else if ((datafellows & SSH_BUG_SIGBLOB) &&
- signaturelen != SIGBLOB_LEN) {
- log("autoremove SSH_BUG_SIGBLOB");
- datafellows &= ~SSH_BUG_SIGBLOB;
- }
-
- debug("len %d datafellows %d", signaturelen, datafellows);
-
/* fetch signature */
if (datafellows & SSH_BUG_SIGBLOB) {
sigblob = signature;
@@ -153,22 +130,24 @@ ssh_dss_verify(
/* ietf-drafts */
char *ktype;
buffer_init(&b);
- buffer_append(&b, (char *) signature, signaturelen);
+ buffer_append(&b, signature, signaturelen);
ktype = buffer_get_string(&b, NULL);
if (strcmp("ssh-dss", ktype) != 0) {
error("ssh_dss_verify: cannot handle type %s", ktype);
buffer_free(&b);
+ xfree(ktype);
return -1;
}
- sigblob = (u_char *)buffer_get_string(&b, &len);
+ xfree(ktype);
+ sigblob = buffer_get_string(&b, &len);
rlen = buffer_len(&b);
- if(rlen != 0) {
- error("remaining bytes in signature %d", rlen);
- buffer_free(&b);
+ buffer_free(&b);
+ if (rlen != 0) {
+ error("ssh_dss_verify: "
+ "remaining bytes in signature %d", rlen);
+ xfree(sigblob);
return -1;
}
- buffer_free(&b);
- xfree(ktype);
}
if (len != SIGBLOB_LEN) {
@@ -176,9 +155,12 @@ ssh_dss_verify(
}
/* parse signature */
- sig = DSA_SIG_new();
- sig->r = BN_new();
- sig->s = BN_new();
+ if ((sig = DSA_SIG_new()) == NULL)
+ fatal("ssh_dss_verify: DSA_SIG_new failed");
+ if ((sig->r = BN_new()) == NULL)
+ fatal("ssh_dss_verify: BN_new failed");
+ if ((sig->s = BN_new()) == NULL)
+ fatal("ssh_dss_verify: BN_new failed");
BN_bin2bn(sigblob, INTBLOB_LEN, sig->r);
BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s);
@@ -188,30 +170,16 @@ ssh_dss_verify(
}
/* sha1 the data */
- dlen = evp_md->md_size;
- digest = xmalloc(dlen);
EVP_DigestInit(&md, evp_md);
EVP_DigestUpdate(&md, data, datalen);
- EVP_DigestFinal(&md, digest, NULL);
+ EVP_DigestFinal(&md, digest, &dlen);
ret = DSA_do_verify(digest, dlen, sig, key->dsa);
+ memset(digest, 'd', sizeof(digest));
- memset(digest, 0, dlen);
- xfree(digest);
DSA_SIG_free(sig);
- switch (ret) {
- case 1:
- txt = "correct";
- break;
- case 0:
- txt = "incorrect";
- break;
- case -1:
- default:
- txt = "error";
- break;
- }
- debug("ssh_dss_verify: signature %s", txt);
+ debug("ssh_dss_verify: signature %s",
+ ret == 1 ? "correct" : ret == 0 ? "incorrect" : "error");
return ret;
}
diff --git a/crypto/openssh/ssh-dss.h b/crypto/openssh/ssh-dss.h
index 0e6a20a..94961b1 100644
--- a/crypto/openssh/ssh-dss.h
+++ b/crypto/openssh/ssh-dss.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-dss.h,v 1.3 2001/01/29 01:58:18 niklas Exp $ */
+/* $OpenBSD: ssh-dss.h,v 1.6 2002/02/24 19:14:59 markus Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -26,16 +26,7 @@
#ifndef DSA_H
#define DSA_H
-int
-ssh_dss_sign(
- Key *key,
- u_char **sigp, int *lenp,
- u_char *data, int datalen);
-
-int
-ssh_dss_verify(
- Key *key,
- u_char *signature, int signaturelen,
- u_char *data, int datalen);
+int ssh_dss_sign(Key *, u_char **, u_int *, u_char *, u_int);
+int ssh_dss_verify(Key *, u_char *, u_int, u_char *, u_int);
#endif
diff --git a/crypto/openssh/ssh-keygen.1 b/crypto/openssh/ssh-keygen.1
index 371fc5f..6ad94e6 100644
--- a/crypto/openssh/ssh-keygen.1
+++ b/crypto/openssh/ssh-keygen.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-keygen.1,v 1.40 2001/04/23 21:57:07 markus Exp $
+.\" $OpenBSD: ssh-keygen.1,v 1.53 2002/02/16 14:53:37 stevesk Exp $
.\"
.\" -*- nroff -*-
.\"
@@ -47,7 +47,7 @@
.Nm ssh-keygen
.Op Fl q
.Op Fl b Ar bits
-.Op Fl t Ar type
+.Fl t Ar type
.Op Fl N Ar new_passphrase
.Op Fl C Ar comment
.Op Fl f Ar output_keyfile
@@ -76,15 +76,21 @@
.Nm ssh-keygen
.Fl B
.Op Fl f Ar input_keyfile
+.Nm ssh-keygen
+.Fl D Ar reader
+.Nm ssh-keygen
+.Fl U Ar reader
+.Op Fl f Ar input_keyfile
.Sh DESCRIPTION
.Nm
generates, manages and converts authentication keys for
.Xr ssh 1 .
.Nm
-defaults to generating a RSA1 key for use by SSH protocol version 1.
-specifying the
+can create RSA keys for use by SSH protocol version 1 and RSA or DSA
+keys for use by SSH protocol version 2. The type of key to be generated
+is specified with the
.Fl t
-option allows you to create a key for use by SSH protocol version 2.
+option.
.Pp
Normally each user wishing to use SSH
with RSA or DSA authentication runs this once to create the authentication
@@ -106,17 +112,21 @@ The program also asks for a passphrase.
The passphrase may be empty to indicate no passphrase
(host keys must have an empty passphrase), or it may be a string of
arbitrary length.
-Good passphrases are 10-30 characters long and are
+A passphrase is similar to a password, except it can be a phrase with a
+series of words, punctuation, numbers, whitespace, or any string of
+characters you want.
+Good passphrases are 10-30 characters long, are
not simple sentences or otherwise easily guessable (English
-prose has only 1-2 bits of entropy per word, and provides very bad
-passphrases).
+prose has only 1-2 bits of entropy per character, and provides very bad
+passphrases), and contain a mix of upper and lowercase letters,
+numbers, and non-alphanumeric characters.
The passphrase can be changed later by using the
.Fl p
option.
.Pp
There is no way to recover a lost passphrase.
If the passphrase is
-lost or forgotten, you will have to generate a new key and copy the
+lost or forgotten, a new key must be generated and copied to the
corresponding public key to other machines.
.Pp
For RSA1 keys,
@@ -142,8 +152,9 @@ above that no longer improve security but make things slower.
The default is 1024 bits.
.It Fl c
Requests changing the comment in the private and public key files.
+This operation is only supported for RSA1 keys.
The program will prompt for the file containing the private keys, for
-passphrase if the key has one, and for the new comment.
+the passphrase if the key has one, and for the new comment.
.It Fl e
This option will read a private or public OpenSSH key file and
print the key in a
@@ -151,7 +162,7 @@ print the key in a
to stdout.
This option allows exporting keys for use by several commercial
SSH implementations.
-.It Fl f
+.It Fl f Ar filename
Specifies the filename of the key file.
.It Fl i
This option will read an unencrypted private (or public) key file
@@ -163,7 +174,11 @@ also reads the
This option allows importing keys from several commercial
SSH implementations.
.It Fl l
-Show fingerprint of specified private or public key file.
+Show fingerprint of specified public key file.
+Private RSA1 keys are also supported.
+For RSA and DSA keys
+.Nm
+tries to find the matching public key file and prints its fingerprint.
.It Fl p
Requests changing the passphrase of a private key file instead of
creating a new private key.
@@ -188,16 +203,20 @@ for protocol version 1 and
or
.Dq dsa
for protocol version 2.
-The default is
-.Dq rsa1 .
.It Fl B
Show the bubblebabble digest of specified private or public key file.
.It Fl C Ar comment
Provides the new comment.
+.It Fl D Ar reader
+Download the RSA public key stored in the smartcard in
+.Ar reader .
.It Fl N Ar new_passphrase
Provides the new passphrase.
.It Fl P Ar passphrase
Provides the (old) passphrase.
+.It Fl U Ar reader
+Upload an existing RSA private key into the smartcard in
+.Ar reader .
.El
.Sh FILES
.Bl -tag -width Ds
@@ -210,14 +229,14 @@ used to encrypt the private part of this file using 3DES.
This file is not automatically accessed by
.Nm
but it is offered as the default file for the private key.
-.Xr sshd 8
+.Xr ssh 1
will read this file when a login attempt is made.
.It Pa $HOME/.ssh/identity.pub
Contains the protocol version 1 RSA public key for authentication.
The contents of this file should be added to
.Pa $HOME/.ssh/authorized_keys
on all machines
-where you wish to log in using RSA authentication.
+where the user wishes to log in using RSA authentication.
There is no need to keep the contents of this file secret.
.It Pa $HOME/.ssh/id_dsa
Contains the protocol version 2 DSA authentication identity of the user.
@@ -228,14 +247,14 @@ used to encrypt the private part of this file using 3DES.
This file is not automatically accessed by
.Nm
but it is offered as the default file for the private key.
-.Xr sshd 8
+.Xr ssh 1
will read this file when a login attempt is made.
.It Pa $HOME/.ssh/id_dsa.pub
Contains the protocol version 2 DSA public key for authentication.
The contents of this file should be added to
-.Pa $HOME/.ssh/authorized_keys2
+.Pa $HOME/.ssh/authorized_keys
on all machines
-where you wish to log in using public key authentication.
+where the user wishes to log in using public key authentication.
There is no need to keep the contents of this file secret.
.It Pa $HOME/.ssh/id_rsa
Contains the protocol version 2 RSA authentication identity of the user.
@@ -246,14 +265,14 @@ used to encrypt the private part of this file using 3DES.
This file is not automatically accessed by
.Nm
but it is offered as the default file for the private key.
-.Xr sshd 8
+.Xr ssh 1
will read this file when a login attempt is made.
.It Pa $HOME/.ssh/id_rsa.pub
Contains the protocol version 2 RSA public key for authentication.
The contents of this file should be added to
-.Pa $HOME/.ssh/authorized_keys2
+.Pa $HOME/.ssh/authorized_keys
on all machines
-where you wish to log in using public key authentication.
+where the user wishes to log in using public key authentication.
There is no need to keep the contents of this file secret.
.El
.Sh AUTHORS
diff --git a/crypto/openssh/ssh-keygen.c b/crypto/openssh/ssh-keygen.c
index 90d5ffa..961fad6 100644
--- a/crypto/openssh/ssh-keygen.c
+++ b/crypto/openssh/ssh-keygen.c
@@ -12,7 +12,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: ssh-keygen.c,v 1.60 2001/04/23 22:14:13 markus Exp $");
+RCSID("$OpenBSD: ssh-keygen.c,v 1.94 2002/02/25 16:33:27 markus Exp $");
#include <openssl/evp.h>
#include <openssl/pem.h>
@@ -28,6 +28,12 @@ RCSID("$OpenBSD: ssh-keygen.c,v 1.60 2001/04/23 22:14:13 markus Exp $");
#include "log.h"
#include "readpass.h"
+#ifdef SMARTCARD
+#include <sectok.h>
+#include <openssl/engine.h>
+#include "scard.h"
+#endif
+
/* Number of bits in the RSA/DSA key. This value can be changed on the command line. */
int bits = 1024;
@@ -67,35 +73,38 @@ int convert_to_ssh2 = 0;
int convert_from_ssh2 = 0;
int print_public = 0;
-/* default to RSA for SSH-1 */
-char *key_type_name = "rsa1";
+char *key_type_name = NULL;
/* argv0 */
extern char *__progname;
char hostname[MAXHOSTNAMELEN];
-void
+static void
ask_filename(struct passwd *pw, const char *prompt)
{
char buf[1024];
char *name = NULL;
- switch (key_type_from_name(key_type_name)) {
- case KEY_RSA1:
- name = _PATH_SSH_CLIENT_IDENTITY;
- break;
- case KEY_DSA:
- name = _PATH_SSH_CLIENT_ID_DSA;
- break;
- case KEY_RSA:
+ if (key_type_name == NULL)
name = _PATH_SSH_CLIENT_ID_RSA;
- break;
- default:
- fprintf(stderr, "bad key type");
- exit(1);
- break;
- }
+ else
+ switch (key_type_from_name(key_type_name)) {
+ case KEY_RSA1:
+ name = _PATH_SSH_CLIENT_IDENTITY;
+ break;
+ case KEY_DSA:
+ name = _PATH_SSH_CLIENT_ID_DSA;
+ break;
+ case KEY_RSA:
+ name = _PATH_SSH_CLIENT_ID_RSA;
+ break;
+ default:
+ fprintf(stderr, "bad key type");
+ exit(1);
+ break;
+ }
+
snprintf(identity_file, sizeof(identity_file), "%s/%s", pw->pw_dir, name);
fprintf(stderr, "%s (%s): ", prompt, identity_file);
fflush(stderr);
@@ -108,15 +117,19 @@ ask_filename(struct passwd *pw, const char *prompt)
have_identity = 1;
}
-Key *
-try_load_pem_key(char *filename)
+static Key *
+load_identity(char *filename)
{
char *pass;
Key *prv;
prv = key_load_private(filename, "", NULL);
if (prv == NULL) {
- pass = read_passphrase("Enter passphrase: ", 1);
+ if (identity_passphrase)
+ pass = xstrdup(identity_passphrase);
+ else
+ pass = read_passphrase("Enter passphrase: ",
+ RP_ALLOW_STDIN);
prv = key_load_private(filename, pass, NULL);
memset(pass, 0, strlen(pass));
xfree(pass);
@@ -129,11 +142,11 @@ try_load_pem_key(char *filename)
#define SSH_COM_PRIVATE_BEGIN "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"
#define SSH_COM_PRIVATE_KEY_MAGIC 0x3f6ff9eb
-void
+static void
do_convert_to_ssh2(struct passwd *pw)
{
Key *k;
- int len;
+ u_int len;
u_char *blob;
struct stat st;
@@ -144,12 +157,15 @@ do_convert_to_ssh2(struct passwd *pw)
exit(1);
}
if ((k = key_load_public(identity_file, NULL)) == NULL) {
- if ((k = try_load_pem_key(identity_file)) == NULL) {
+ if ((k = load_identity(identity_file)) == NULL) {
fprintf(stderr, "load failed\n");
exit(1);
}
}
- key_to_blob(k, &blob, &len);
+ if (key_to_blob(k, &blob, &len) <= 0) {
+ fprintf(stderr, "key_to_blob failed\n");
+ exit(1);
+ }
fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN);
fprintf(stdout,
"Comment: \"%d-bit %s, converted from OpenSSH by %s@%s\"\n",
@@ -162,7 +178,7 @@ do_convert_to_ssh2(struct passwd *pw)
exit(0);
}
-void
+static void
buffer_get_bignum_bits(Buffer *b, BIGNUM *value)
{
int bits = buffer_get_int(b);
@@ -171,17 +187,20 @@ buffer_get_bignum_bits(Buffer *b, BIGNUM *value)
if (buffer_len(b) < bytes)
fatal("buffer_get_bignum_bits: input buffer too small: "
"need %d have %d", bytes, buffer_len(b));
- BN_bin2bn((u_char *)buffer_ptr(b), bytes, value);
+ BN_bin2bn(buffer_ptr(b), bytes, value);
buffer_consume(b, bytes);
}
-Key *
-do_convert_private_ssh2_from_blob(char *blob, int blen)
+static Key *
+do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
{
Buffer b;
Key *key = NULL;
- int ignore, magic, rlen, ktype;
char *type, *cipher;
+ u_char *sig, data[] = "abcde12345";
+ int magic, rlen, ktype, i1, i2, i3, i4;
+ u_int slen;
+ u_long e;
buffer_init(&b);
buffer_append(&b, blob, blen);
@@ -192,13 +211,13 @@ do_convert_private_ssh2_from_blob(char *blob, int blen)
buffer_free(&b);
return NULL;
}
- ignore = buffer_get_int(&b);
+ i1 = buffer_get_int(&b);
type = buffer_get_string(&b, NULL);
cipher = buffer_get_string(&b, NULL);
- ignore = buffer_get_int(&b);
- ignore = buffer_get_int(&b);
- ignore = buffer_get_int(&b);
-
+ i2 = buffer_get_int(&b);
+ i3 = buffer_get_int(&b);
+ i4 = buffer_get_int(&b);
+ debug("ignore (%d %d %d %d)", i1,i2,i3,i4);
if (strcmp(cipher, "none") != 0) {
error("unsupported cipher %s", cipher);
xfree(cipher);
@@ -228,7 +247,17 @@ do_convert_private_ssh2_from_blob(char *blob, int blen)
buffer_get_bignum_bits(&b, key->dsa->priv_key);
break;
case KEY_RSA:
- if (!BN_set_word(key->rsa->e, (u_long) buffer_get_char(&b))) {
+ e = buffer_get_char(&b);
+ debug("e %lx", e);
+ if (e < 30) {
+ e <<= 8;
+ e += buffer_get_char(&b);
+ debug("e %lx", e);
+ e <<= 8;
+ e += buffer_get_char(&b);
+ debug("e %lx", e);
+ }
+ if (!BN_set_word(key->rsa->e, e)) {
buffer_free(&b);
key_free(key);
return NULL;
@@ -238,34 +267,29 @@ do_convert_private_ssh2_from_blob(char *blob, int blen)
buffer_get_bignum_bits(&b, key->rsa->iqmp);
buffer_get_bignum_bits(&b, key->rsa->q);
buffer_get_bignum_bits(&b, key->rsa->p);
- generate_additional_parameters(key->rsa);
+ rsa_generate_additional_parameters(key->rsa);
break;
}
rlen = buffer_len(&b);
- if(rlen != 0)
+ if (rlen != 0)
error("do_convert_private_ssh2_from_blob: "
"remaining bytes in key blob %d", rlen);
buffer_free(&b);
-#ifdef DEBUG_PK
- {
- u_int slen;
- u_char *sig, data[10] = "abcde12345";
- key_sign(key, &sig, &slen, data, sizeof data);
- key_verify(key, sig, slen, data, sizeof data);
- xfree(sig);
- }
-#endif
+ /* try the key */
+ key_sign(key, &sig, &slen, data, sizeof(data));
+ key_verify(key, sig, slen, data, sizeof(data));
+ xfree(sig);
return key;
}
-void
+static void
do_convert_from_ssh2(struct passwd *pw)
{
Key *k;
int blen;
char line[1024], *p;
- char blob[8096];
+ u_char blob[8096];
char encoded[8096];
struct stat st;
int escaped = 0, private = 0, ok;
@@ -294,6 +318,9 @@ do_convert_from_ssh2(struct passwd *pw)
strstr(line, ": ") != NULL) {
if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL)
private = 1;
+ if (strstr(line, " END ") != NULL) {
+ break;
+ }
/* fprintf(stderr, "ignore: %s", line); */
continue;
}
@@ -305,7 +332,7 @@ do_convert_from_ssh2(struct passwd *pw)
*p = '\0';
strlcat(encoded, line, sizeof(encoded));
}
- blen = uudecode(encoded, (u_char *)blob, sizeof(blob));
+ blen = uudecode(encoded, blob, sizeof(blob));
if (blen < 0) {
fprintf(stderr, "uudecode failed.\n");
exit(1);
@@ -327,12 +354,13 @@ do_convert_from_ssh2(struct passwd *pw)
exit(1);
}
key_free(k);
- fprintf(stdout, "\n");
+ if (!private)
+ fprintf(stdout, "\n");
fclose(fp);
exit(0);
}
-void
+static void
do_print_public(struct passwd *pw)
{
Key *prv;
@@ -344,7 +372,7 @@ do_print_public(struct passwd *pw)
perror(identity_file);
exit(1);
}
- prv = try_load_pem_key(identity_file);
+ prv = load_identity(identity_file);
if (prv == NULL) {
fprintf(stderr, "load failed\n");
exit(1);
@@ -356,13 +384,159 @@ do_print_public(struct passwd *pw)
exit(0);
}
-void
+#ifdef SMARTCARD
+#define NUM_RSA_KEY_ELEMENTS 5+1
+#define COPY_RSA_KEY(x, i) \
+ do { \
+ len = BN_num_bytes(prv->rsa->x); \
+ elements[i] = xmalloc(len); \
+ debug("#bytes %d", len); \
+ if (BN_bn2bin(prv->rsa->x, elements[i]) < 0) \
+ goto done; \
+ } while (0)
+
+static int
+get_AUT0(char *aut0)
+{
+ EVP_MD *evp_md = EVP_sha1();
+ EVP_MD_CTX md;
+ char *pass;
+
+ pass = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN);
+ if (pass == NULL)
+ return -1;
+ EVP_DigestInit(&md, evp_md);
+ EVP_DigestUpdate(&md, pass, strlen(pass));
+ EVP_DigestFinal(&md, aut0, NULL);
+ memset(pass, 0, strlen(pass));
+ xfree(pass);
+ return 0;
+}
+
+static void
+do_upload(struct passwd *pw, const char *sc_reader_id)
+{
+ Key *prv = NULL;
+ struct stat st;
+ u_char *elements[NUM_RSA_KEY_ELEMENTS];
+ u_char key_fid[2];
+ u_char DEFAUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63};
+ u_char AUT0[EVP_MAX_MD_SIZE];
+ int len, status = 1, i, fd = -1, ret;
+ int sw = 0, cla = 0x00;
+
+ for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
+ elements[i] = NULL;
+ if (!have_identity)
+ ask_filename(pw, "Enter file in which the key is");
+ if (stat(identity_file, &st) < 0) {
+ perror(identity_file);
+ goto done;
+ }
+ prv = load_identity(identity_file);
+ if (prv == NULL) {
+ error("load failed");
+ goto done;
+ }
+ COPY_RSA_KEY(q, 0);
+ COPY_RSA_KEY(p, 1);
+ COPY_RSA_KEY(iqmp, 2);
+ COPY_RSA_KEY(dmq1, 3);
+ COPY_RSA_KEY(dmp1, 4);
+ COPY_RSA_KEY(n, 5);
+ len = BN_num_bytes(prv->rsa->n);
+ fd = sectok_friendly_open(sc_reader_id, STONOWAIT, &sw);
+ if (fd < 0) {
+ error("sectok_open failed: %s", sectok_get_sw(sw));
+ goto done;
+ }
+ if (! sectok_cardpresent(fd)) {
+ error("smartcard in reader %s not present",
+ sc_reader_id);
+ goto done;
+ }
+ ret = sectok_reset(fd, 0, NULL, &sw);
+ if (ret <= 0) {
+ error("sectok_reset failed: %s", sectok_get_sw(sw));
+ goto done;
+ }
+ if ((cla = cyberflex_inq_class(fd)) < 0) {
+ error("cyberflex_inq_class failed");
+ goto done;
+ }
+ memcpy(AUT0, DEFAUT0, sizeof(DEFAUT0));
+ if (cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
+ if (get_AUT0(AUT0) < 0 ||
+ cyberflex_verify_AUT0(fd, cla, AUT0, sizeof(DEFAUT0)) < 0) {
+ error("cyberflex_verify_AUT0 failed");
+ goto done;
+ }
+ }
+ key_fid[0] = 0x00;
+ key_fid[1] = 0x12;
+ if (cyberflex_load_rsa_priv(fd, cla, key_fid, 5, 8*len, elements,
+ &sw) < 0) {
+ error("cyberflex_load_rsa_priv failed: %s", sectok_get_sw(sw));
+ goto done;
+ }
+ if (!sectok_swOK(sw))
+ goto done;
+ log("cyberflex_load_rsa_priv done");
+ key_fid[0] = 0x73;
+ key_fid[1] = 0x68;
+ if (cyberflex_load_rsa_pub(fd, cla, key_fid, len, elements[5],
+ &sw) < 0) {
+ error("cyberflex_load_rsa_pub failed: %s", sectok_get_sw(sw));
+ goto done;
+ }
+ if (!sectok_swOK(sw))
+ goto done;
+ log("cyberflex_load_rsa_pub done");
+ status = 0;
+ log("loading key done");
+done:
+
+ memset(elements[0], '\0', BN_num_bytes(prv->rsa->q));
+ memset(elements[1], '\0', BN_num_bytes(prv->rsa->p));
+ memset(elements[2], '\0', BN_num_bytes(prv->rsa->iqmp));
+ memset(elements[3], '\0', BN_num_bytes(prv->rsa->dmq1));
+ memset(elements[4], '\0', BN_num_bytes(prv->rsa->dmp1));
+ memset(elements[5], '\0', BN_num_bytes(prv->rsa->n));
+
+ if (prv)
+ key_free(prv);
+ for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
+ if (elements[i])
+ xfree(elements[i]);
+ if (fd != -1)
+ sectok_close(fd);
+ exit(status);
+}
+
+static void
+do_download(struct passwd *pw, const char *sc_reader_id)
+{
+ Key *pub = NULL;
+
+ pub = sc_get_key(sc_reader_id);
+ if (pub == NULL)
+ fatal("cannot read public key from smartcard");
+ key_write(pub, stdout);
+ key_free(pub);
+ fprintf(stdout, "\n");
+ exit(0);
+}
+#endif /* SMARTCARD */
+
+static void
do_fingerprint(struct passwd *pw)
{
FILE *f;
Key *public;
char *comment = NULL, *cp, *ep, line[16*1024], *fp;
- int i, skip = 0, num = 1, invalid = 1, rep, fptype;
+ int i, skip = 0, num = 1, invalid = 1;
+ enum fp_rep rep;
+ enum fp_type fptype;
struct stat st;
fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;
@@ -443,7 +617,7 @@ do_fingerprint(struct passwd *pw)
fclose(f);
}
if (invalid) {
- printf("%s is not a valid key file.\n", identity_file);
+ printf("%s is not a public key file.\n", identity_file);
exit(1);
}
exit(0);
@@ -453,7 +627,7 @@ do_fingerprint(struct passwd *pw)
* Perform changing a passphrase. The argument is the passwd structure
* for the current user.
*/
-void
+static void
do_change_passphrase(struct passwd *pw)
{
char *comment;
@@ -473,8 +647,11 @@ do_change_passphrase(struct passwd *pw)
if (identity_passphrase)
old_passphrase = xstrdup(identity_passphrase);
else
- old_passphrase = read_passphrase("Enter old passphrase: ", 1);
- private = key_load_private(identity_file, old_passphrase , &comment);
+ old_passphrase =
+ read_passphrase("Enter old passphrase: ",
+ RP_ALLOW_STDIN);
+ private = key_load_private(identity_file, old_passphrase,
+ &comment);
memset(old_passphrase, 0, strlen(old_passphrase));
xfree(old_passphrase);
if (private == NULL) {
@@ -490,8 +667,10 @@ do_change_passphrase(struct passwd *pw)
passphrase2 = NULL;
} else {
passphrase1 =
- read_passphrase("Enter new passphrase (empty for no passphrase): ", 1);
- passphrase2 = read_passphrase("Enter same passphrase again: ", 1);
+ read_passphrase("Enter new passphrase (empty for no "
+ "passphrase): ", RP_ALLOW_STDIN);
+ passphrase2 = read_passphrase("Enter same passphrase again: ",
+ RP_ALLOW_STDIN);
/* Verify that they are the same. */
if (strcmp(passphrase1, passphrase2) != 0) {
@@ -529,7 +708,7 @@ do_change_passphrase(struct passwd *pw)
/*
* Change the comment of a private key file.
*/
-void
+static void
do_change_comment(struct passwd *pw)
{
char new_comment[1024], *comment, *passphrase;
@@ -552,7 +731,8 @@ do_change_comment(struct passwd *pw)
else if (identity_new_passphrase)
passphrase = xstrdup(identity_new_passphrase);
else
- passphrase = read_passphrase("Enter passphrase: ", 1);
+ passphrase = read_passphrase("Enter passphrase: ",
+ RP_ALLOW_STDIN);
/* Try to load using the passphrase. */
private = key_load_private(identity_file, passphrase, &comment);
if (private == NULL) {
@@ -568,7 +748,7 @@ do_change_comment(struct passwd *pw)
fprintf(stderr, "Comments are only supported for RSA1 keys.\n");
key_free(private);
exit(1);
- }
+ }
printf("Key now has comment '%s'\n", comment);
if (identity_comment) {
@@ -622,11 +802,30 @@ do_change_comment(struct passwd *pw)
exit(0);
}
-void
+static void
usage(void)
{
- printf("Usage: %s [-ceilpqyB] [-t type] [-b bits] [-f file] [-C comment] "
- "[-N new-pass] [-P pass]\n", __progname);
+ fprintf(stderr, "Usage: %s [options]\n", __progname);
+ fprintf(stderr, "Options:\n");
+ fprintf(stderr, " -b bits Number of bits in the key to create.\n");
+ fprintf(stderr, " -c Change comment in private and public key files.\n");
+ fprintf(stderr, " -e Convert OpenSSH to IETF SECSH key file.\n");
+ fprintf(stderr, " -f filename Filename of the key file.\n");
+ fprintf(stderr, " -i Convert IETF SECSH to OpenSSH key file.\n");
+ fprintf(stderr, " -l Show fingerprint of key file.\n");
+ fprintf(stderr, " -p Change passphrase of private key file.\n");
+ fprintf(stderr, " -q Quiet.\n");
+ fprintf(stderr, " -y Read private key file and print public key.\n");
+ fprintf(stderr, " -t type Specify type of key to create.\n");
+ fprintf(stderr, " -B Show bubblebabble digest of key file.\n");
+ fprintf(stderr, " -C comment Provide new comment.\n");
+ fprintf(stderr, " -N phrase Provide new passphrase.\n");
+ fprintf(stderr, " -P phrase Provide old passphrase.\n");
+#ifdef SMARTCARD
+ fprintf(stderr, " -D reader Download public key from smartcard.\n");
+ fprintf(stderr, " -U reader Upload private key to smartcard.\n");
+#endif /* SMARTCARD */
+
exit(1);
}
@@ -636,11 +835,12 @@ usage(void)
int
main(int ac, char **av)
{
- char dotsshdir[16 * 1024], comment[1024], *passphrase1, *passphrase2;
+ char dotsshdir[MAXPATHLEN], comment[1024], *passphrase1, *passphrase2;
+ char *reader_id = NULL;
Key *private, *public;
struct passwd *pw;
- int opt, type, fd;
struct stat st;
+ int opt, type, fd, download = 0;
FILE *f;
extern int optind;
@@ -659,7 +859,7 @@ main(int ac, char **av)
exit(1);
}
- while ((opt = getopt(ac, av, "deiqpclBRxXyb:f:t:P:N:C:")) != -1) {
+ while ((opt = getopt(ac, av, "deiqpclBRxXyb:f:t:U:D:P:N:C:")) != -1) {
switch (opt) {
case 'b':
bits = atoi(optarg);
@@ -668,73 +868,62 @@ main(int ac, char **av)
exit(1);
}
break;
-
case 'l':
print_fingerprint = 1;
break;
-
case 'B':
print_bubblebabble = 1;
break;
-
case 'p':
change_passphrase = 1;
break;
-
case 'c':
change_comment = 1;
break;
-
case 'f':
strlcpy(identity_file, optarg, sizeof(identity_file));
have_identity = 1;
break;
-
case 'P':
identity_passphrase = optarg;
break;
-
case 'N':
identity_new_passphrase = optarg;
break;
-
case 'C':
identity_comment = optarg;
break;
-
case 'q':
quiet = 1;
break;
-
case 'R':
/* unused */
exit(0);
break;
-
case 'e':
case 'x':
/* export key */
convert_to_ssh2 = 1;
break;
-
case 'i':
case 'X':
/* import key */
convert_from_ssh2 = 1;
break;
-
case 'y':
print_public = 1;
break;
-
case 'd':
key_type_name = "dsa";
break;
-
case 't':
key_type_name = optarg;
break;
-
+ case 'D':
+ download = 1;
+ case 'U':
+ reader_id = optarg;
+ break;
case '?':
default:
usage();
@@ -760,9 +949,23 @@ main(int ac, char **av)
do_convert_from_ssh2(pw);
if (print_public)
do_print_public(pw);
+ if (reader_id != NULL) {
+#ifdef SMARTCARD
+ if (download)
+ do_download(pw, reader_id);
+ else
+ do_upload(pw, reader_id);
+#else /* SMARTCARD */
+ fatal("no support for smartcards.");
+#endif /* SMARTCARD */
+ }
arc4random_stir();
+ if (key_type_name == NULL) {
+ printf("You must specify a key type (-t).\n");
+ usage();
+ }
type = key_type_from_name(key_type_name);
if (type == KEY_UNSPEC) {
fprintf(stderr, "unknown key type %s\n", key_type_name);
@@ -808,10 +1011,15 @@ main(int ac, char **av)
else {
passphrase_again:
passphrase1 =
- read_passphrase("Enter passphrase (empty for no passphrase): ", 1);
- passphrase2 = read_passphrase("Enter same passphrase again: ", 1);
+ read_passphrase("Enter passphrase (empty for no "
+ "passphrase): ", RP_ALLOW_STDIN);
+ passphrase2 = read_passphrase("Enter same passphrase again: ",
+ RP_ALLOW_STDIN);
if (strcmp(passphrase1, passphrase2) != 0) {
- /* The passphrases do not match. Clear them and retry. */
+ /*
+ * The passphrases do not match. Clear them and
+ * retry.
+ */
memset(passphrase1, 0, strlen(passphrase1));
memset(passphrase2, 0, strlen(passphrase2));
xfree(passphrase1);
diff --git a/crypto/openssh/ssh-keygen/Makefile b/crypto/openssh/ssh-keygen/Makefile
index b7c1151..d175813 100644
--- a/crypto/openssh/ssh-keygen/Makefile
+++ b/crypto/openssh/ssh-keygen/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.17 2001/03/04 00:51:26 markus Exp $
+# $OpenBSD: Makefile,v 1.21 2001/06/27 19:29:16 markus Exp $
.PATH: ${.CURDIR}/..
diff --git a/crypto/openssh/ssh-keyscan.1 b/crypto/openssh/ssh-keyscan.1
index 4db8c5f..2f33ddf 100644
--- a/crypto/openssh/ssh-keyscan.1
+++ b/crypto/openssh/ssh-keyscan.1
@@ -1,11 +1,10 @@
-.\" $OpenBSD: ssh-keyscan.1,v 1.5 2001/04/18 16:21:05 ian Exp $
+.\" $OpenBSD: ssh-keyscan.1,v 1.14 2002/02/13 08:33:47 mpech Exp $
.\"
.\" Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
.\"
.\" Modification and redistribution in source and binary forms is
.\" permitted provided that due credit is given to the author and the
-.\" OpenBSD project (for instance by leaving this copyright notice
-.\" intact).
+.\" OpenBSD project by leaving this copyright notice intact.
.\"
.Dd January 1, 1996
.Dt SSH-KEYSCAN 1
@@ -15,9 +14,13 @@
.Nd gather ssh public keys
.Sh SYNOPSIS
.Nm ssh-keyscan
-.Op Fl t Ar timeout
-.Op Ar -- | host | addrlist namelist
-.Op Fl f Ar files ...
+.Op Fl v46
+.Op Fl p Ar port
+.Op Fl T Ar timeout
+.Op Fl t Ar type
+.Op Fl f Ar file
+.Op Ar host | addrlist namelist
+.Op Ar ...
.Sh DESCRIPTION
.Nm
is a utility for gathering the public ssh host keys of a number of
@@ -32,46 +35,76 @@ scripts.
uses non-blocking socket I/O to contact as many hosts as possible in
parallel, so it is very efficient. The keys from a domain of 1,000
hosts can be collected in tens of seconds, even when some of those
-hosts are down or do not run ssh. You do not need login access to the
-machines you are scanning, nor does the scanning process involve
-any encryption.
-.Sh SECURITY
-If you make an ssh_known_hosts file using
-.Nm
-without verifying the keys, you will be vulnerable to
-.I man in the middle
-attacks.
-On the other hand, if your security model allows such a risk,
-.Nm
-can help you detect tampered keyfiles or man in the middle attacks which
-have begun after you created your ssh_known_hosts file.
-.Sh OPTIONS
+hosts are down or do not run ssh. For scanning, one does not need
+login access to the machines that are being scanned, nor does the
+scanning process involve any encryption.
+.Pp
+The options are as follows:
.Bl -tag -width Ds
-.It Fl t
-Set the timeout for connection attempts. If
+.It Fl p Ar port
+Port to connect to on the remote host.
+.It Fl T Ar timeout
+Set the timeout for connection attempts. If
.Pa timeout
seconds have elapsed since a connection was initiated to a host or since the
last time anything was read from that host, then the connection is
closed and the host in question considered unavailable. Default is 5
seconds.
-.It Fl f
-Read hosts or
+.It Fl t Ar type
+Specifies the type of the key to fetch from the scanned hosts.
+The possible values are
+.Dq rsa1
+for protocol version 1 and
+.Dq rsa
+or
+.Dq dsa
+for protocol version 2.
+Multiple values may be specified by separating them with commas.
+The default is
+.Dq rsa1 .
+.It Fl f Ar filename
+Read hosts or
.Pa addrlist namelist
pairs from this file, one per line.
If
.Pa -
is supplied instead of a filename,
.Nm
-will read hosts or
+will read hosts or
.Pa addrlist namelist
pairs from the standard input.
+.It Fl v
+Verbose mode.
+Causes
+.Nm
+to print debugging messages about its progress.
+.It Fl 4
+Forces
+.Nm
+to use IPv4 addresses only.
+.It Fl 6
+Forces
+.Nm
+to use IPv6 addresses only.
.El
+.Sh SECURITY
+If a ssh_known_hosts file is constructed using
+.Nm
+without verifying the keys, users will be vulnerable to
+.I man in the middle
+attacks.
+On the other hand, if the security model allows such a risk,
+.Nm
+can help in the detection of tampered keyfiles or man in the middle
+attacks which have begun after the ssh_known_hosts file was created.
.Sh EXAMPLES
.Pp
-Print the host key for machine
+Print the
+.Pa rsa1
+host key for machine
.Pa hostname :
.Bd -literal
-ssh-keyscan hostname
+$ ssh-keyscan hostname
.Ed
.Pp
Find all hosts from the file
@@ -79,26 +112,43 @@ Find all hosts from the file
which have new or different keys from those in the sorted file
.Pa ssh_known_hosts :
.Bd -literal
-$ ssh-keyscan -f ssh_hosts | sort -u - ssh_known_hosts | \e\
- diff ssh_known_hosts -
+$ ssh-keyscan -t rsa,dsa -f ssh_hosts | \e\
+ sort -u - ssh_known_hosts | diff ssh_known_hosts -
.Ed
-.Pp
.Sh FILES
-.Pp
.Pa Input format:
+.Bd -literal
1.2.3.4,1.2.4.4 name.my.domain,name,n.my.domain,n,1.2.3.4,1.2.4.4
+.Ed
.Pp
-.Pa Output format:
+.Pa Output format for rsa1 keys:
+.Bd -literal
host-or-namelist bits exponent modulus
+.Ed
+.Pp
+.Pa Output format for rsa and dsa keys:
+.Bd -literal
+host-or-namelist keytype base64-encoded-key
+.Ed
+.Pp
+Where
+.Pa keytype
+is either
+.Dq ssh-rsa
+or
+.Dq ssh-dsa .
.Pp
-.Pa /etc/ssh_known_hosts
+.Pa /etc/ssh/ssh_known_hosts
.Sh BUGS
It generates "Connection closed by remote host" messages on the consoles
-of all the machines it scans.
+of all the machines it scans if the server is older than version 2.9.
This is because it opens a connection to the ssh port, reads the public
key, and drops the connection as soon as it gets the key.
.Sh SEE ALSO
.Xr ssh 1 ,
.Xr sshd 8
-.Sh AUTHOR
+.Sh AUTHORS
David Mazieres <dm@lcs.mit.edu>
+wrote the initial version, and
+Wayne Davison <wayned@users.sourceforge.net>
+added support for protocol version 2.
diff --git a/crypto/openssh/ssh-keyscan.c b/crypto/openssh/ssh-keyscan.c
index dba2d83..5fc5330 100644
--- a/crypto/openssh/ssh-keyscan.c
+++ b/crypto/openssh/ssh-keyscan.c
@@ -3,30 +3,44 @@
*
* Modification and redistribution in source and binary forms is
* permitted provided that due credit is given to the author and the
- * OpenBSD project (for instance by leaving this copyright notice
- * intact).
+ * OpenBSD project by leaving this copyright notice intact.
*/
#include "includes.h"
-RCSID("$OpenBSD: ssh-keyscan.c,v 1.22 2001/03/06 06:11:18 deraadt Exp $");
+RCSID("$OpenBSD: ssh-keyscan.c,v 1.35 2002/03/04 18:30:23 stevesk Exp $");
#include <sys/queue.h>
#include <errno.h>
#include <openssl/bn.h>
+#include <setjmp.h>
#include "xmalloc.h"
#include "ssh.h"
#include "ssh1.h"
#include "key.h"
+#include "kex.h"
+#include "compat.h"
+#include "myproposal.h"
+#include "packet.h"
+#include "dispatch.h"
#include "buffer.h"
#include "bufaux.h"
#include "log.h"
#include "atomicio.h"
+#include "misc.h"
-static int argno = 1; /* Number of argument currently being parsed */
+/* Flag indicating whether IPv4 or IPv6. This can be set on the command line.
+ Default value is AF_UNSPEC means both IPv4 and IPv6. */
+int IPv4or6 = AF_UNSPEC;
-int family = AF_UNSPEC; /* IPv4, IPv6 or both */
+int ssh_port = SSH_DEFAULT_PORT;
+
+#define KT_RSA1 1
+#define KT_DSA 2
+#define KT_RSA 4
+
+int get_keytypes = KT_RSA1; /* Get only RSA1 keys by default */
#define MAXMAXFD 256
@@ -40,6 +54,9 @@ extern char *__progname;
fd_set *read_wait;
size_t read_wait_size;
int ncon;
+int nonfatal_fatal = 0;
+jmp_buf kexjmp;
+Key *kexjmp_key;
/*
* Keep a connection structure for each file descriptor. The state
@@ -55,11 +72,13 @@ typedef struct Connection {
int c_plen; /* Packet length field for ssh packet */
int c_len; /* Total bytes which must be read. */
int c_off; /* Length of data read so far. */
+ int c_keytype; /* Only one of KT_RSA1, KT_DSA, or KT_RSA */
char *c_namebase; /* Address to free for c_name and c_namelist */
char *c_name; /* Hostname of connection for errors */
char *c_namelist; /* Pointer to other possible addresses */
char *c_output_name; /* Hostname of connection for output */
char *c_data; /* Data read from this fd */
+ Kex *c_kex; /* The key-exchange struct for ssh2 */
struct timeval c_tv; /* Time at which connection gets aborted */
TAILQ_ENTRY(Connection) c_link; /* List of connections in timeout order. */
} con;
@@ -83,7 +102,7 @@ typedef struct {
void (*errfun) (const char *,...);
} Linebuf;
-Linebuf *
+static Linebuf *
Linebuf_alloc(const char *filename, void (*errfun) (const char *,...))
{
Linebuf *lb;
@@ -117,7 +136,7 @@ Linebuf_alloc(const char *filename, void (*errfun) (const char *,...))
return (lb);
}
-void
+static void
Linebuf_free(Linebuf * lb)
{
fclose(lb->stream);
@@ -125,7 +144,8 @@ Linebuf_free(Linebuf * lb)
xfree(lb);
}
-void
+#if 0
+static void
Linebuf_restart(Linebuf * lb)
{
clearerr(lb->stream);
@@ -133,13 +153,14 @@ Linebuf_restart(Linebuf * lb)
lb->lineno = 0;
}
-int
+static int
Linebuf_lineno(Linebuf * lb)
{
return (lb->lineno);
}
+#endif
-char *
+static char *
Linebuf_getline(Linebuf * lb)
{
int n = 0;
@@ -176,7 +197,7 @@ Linebuf_getline(Linebuf * lb)
}
}
-int
+static int
fdlim_get(int hard)
{
struct rlimit rlfd;
@@ -189,7 +210,7 @@ fdlim_get(int hard)
return hard ? rlfd.rlim_max : rlfd.rlim_cur;
}
-int
+static int
fdlim_set(int lim)
{
struct rlimit rlfd;
@@ -208,7 +229,7 @@ fdlim_set(int lim)
* separators. This is the same as the 4.4BSD strsep, but different from the
* one in the GNU libc.
*/
-char *
+static char *
xstrsep(char **str, const char *delim)
{
char *s, *e;
@@ -230,7 +251,7 @@ xstrsep(char **str, const char *delim)
* Get the next non-null token (like GNU strsep). Strsep() will return a
* null token for two adjacent separators, so we may have to loop.
*/
-char *
+static char *
strnnsep(char **stringp, char *delim)
{
char *tok;
@@ -241,8 +262,8 @@ strnnsep(char **stringp, char *delim)
return (tok);
}
-void
-keyprint(char *host, char *output_name, char *kd, int len)
+static Key *
+keygrab_ssh1(con *c)
{
static Key *rsa;
static Buffer msg;
@@ -251,12 +272,12 @@ keyprint(char *host, char *output_name, char *kd, int len)
buffer_init(&msg);
rsa = key_new(KEY_RSA1);
}
- buffer_append(&msg, kd, len);
- buffer_consume(&msg, 8 - (len & 7)); /* padding */
+ buffer_append(&msg, c->c_data, c->c_plen);
+ buffer_consume(&msg, 8 - (c->c_plen & 7)); /* padding */
if (buffer_get_char(&msg) != (int) SSH_SMSG_PUBLIC_KEY) {
- error("%s: invalid packet type", host);
+ error("%s: invalid packet type", c->c_name);
buffer_clear(&msg);
- return;
+ return NULL;
}
buffer_consume(&msg, 8); /* cookie */
@@ -269,23 +290,82 @@ keyprint(char *host, char *output_name, char *kd, int len)
(void) buffer_get_int(&msg);
buffer_get_bignum(&msg, rsa->rsa->e);
buffer_get_bignum(&msg, rsa->rsa->n);
+
buffer_clear(&msg);
- fprintf(stdout, "%s ", output_name ? output_name : host);
- key_write(rsa, stdout);
+ return (rsa);
+}
+
+static int
+hostjump(Key *hostkey)
+{
+ kexjmp_key = hostkey;
+ longjmp(kexjmp, 1);
+}
+
+static int
+ssh2_capable(int remote_major, int remote_minor)
+{
+ switch (remote_major) {
+ case 1:
+ if (remote_minor == 99)
+ return 1;
+ break;
+ case 2:
+ return 1;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static Key *
+keygrab_ssh2(con *c)
+{
+ int j;
+
+ packet_set_connection(c->c_fd, c->c_fd);
+ enable_compat20();
+ myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = c->c_keytype == KT_DSA?
+ "ssh-dss": "ssh-rsa";
+ c->c_kex = kex_setup(myproposal);
+ c->c_kex->verify_host_key = hostjump;
+
+ if (!(j = setjmp(kexjmp))) {
+ nonfatal_fatal = 1;
+ dispatch_run(DISPATCH_BLOCK, &c->c_kex->done, c->c_kex);
+ fprintf(stderr, "Impossible! dispatch_run() returned!\n");
+ exit(1);
+ }
+ nonfatal_fatal = 0;
+ xfree(c->c_kex);
+ c->c_kex = NULL;
+ packet_close();
+
+ return j < 0? NULL : kexjmp_key;
+}
+
+static void
+keyprint(con *c, Key *key)
+{
+ if (!key)
+ return;
+
+ fprintf(stdout, "%s ", c->c_output_name ? c->c_output_name : c->c_name);
+ key_write(key, stdout);
fputs("\n", stdout);
}
-int
+static int
tcpconnect(char *host)
{
struct addrinfo hints, *ai, *aitop;
char strport[NI_MAXSERV];
int gaierr, s = -1;
- snprintf(strport, sizeof strport, "%d", SSH_DEFAULT_PORT);
+ snprintf(strport, sizeof strport, "%d", ssh_port);
memset(&hints, 0, sizeof(hints));
- hints.ai_family = family;
+ hints.ai_family = IPv4or6;
hints.ai_socktype = SOCK_STREAM;
if ((gaierr = getaddrinfo(host, strport, &hints, &aitop)) != 0)
fatal("getaddrinfo %s: %s", host, gai_strerror(gaierr));
@@ -309,8 +389,8 @@ tcpconnect(char *host)
return s;
}
-int
-conalloc(char *iname, char *oname)
+static int
+conalloc(char *iname, char *oname, int keytype)
{
int s;
char *namebase, *name, *namelist;
@@ -339,6 +419,7 @@ conalloc(char *iname, char *oname)
fdcon[s].c_data = (char *) &fdcon[s].c_plen;
fdcon[s].c_len = 4;
fdcon[s].c_off = 0;
+ fdcon[s].c_keytype = keytype;
gettimeofday(&fdcon[s].c_tv, NULL);
fdcon[s].c_tv.tv_sec += timeout;
TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link);
@@ -347,7 +428,7 @@ conalloc(char *iname, char *oname)
return (s);
}
-void
+static void
confree(int s)
{
if (s >= maxfd || fdcon[s].c_status == CS_UNUSED)
@@ -358,12 +439,13 @@ confree(int s)
if (fdcon[s].c_status == CS_KEYS)
xfree(fdcon[s].c_data);
fdcon[s].c_status = CS_UNUSED;
+ fdcon[s].c_keytype = 0;
TAILQ_REMOVE(&tq, &fdcon[s], c_link);
FD_CLR(s, read_wait);
ncon--;
}
-void
+static void
contouch(int s)
{
TAILQ_REMOVE(&tq, &fdcon[s], c_link);
@@ -372,58 +454,85 @@ contouch(int s)
TAILQ_INSERT_TAIL(&tq, &fdcon[s], c_link);
}
-int
+static int
conrecycle(int s)
{
int ret;
con *c = &fdcon[s];
- char *iname, *oname;
- iname = xstrdup(c->c_namelist);
- oname = xstrdup(c->c_output_name);
+ ret = conalloc(c->c_namelist, c->c_output_name, c->c_keytype);
confree(s);
- ret = conalloc(iname, oname);
- xfree(iname);
- xfree(oname);
return (ret);
}
-void
+static void
congreet(int s)
{
- char buf[80], *cp;
+ char buf[256], *cp;
+ char remote_version[sizeof buf];
size_t bufsiz;
- int n = 0;
+ int remote_major, remote_minor, n = 0;
con *c = &fdcon[s];
bufsiz = sizeof(buf);
cp = buf;
- while (bufsiz-- && (n = read(s, cp, 1)) == 1 && *cp != '\n' && *cp != '\r')
+ while (bufsiz-- && (n = read(s, cp, 1)) == 1 && *cp != '\n') {
+ if (*cp == '\r')
+ *cp = '\n';
cp++;
+ }
if (n < 0) {
if (errno != ECONNREFUSED)
error("read (%s): %s", c->c_name, strerror(errno));
conrecycle(s);
return;
}
+ if (n == 0) {
+ error("%s: Connection closed by remote host", c->c_name);
+ conrecycle(s);
+ return;
+ }
if (*cp != '\n' && *cp != '\r') {
error("%s: bad greeting", c->c_name);
confree(s);
return;
}
*cp = '\0';
- fprintf(stderr, "# %s %s\n", c->c_name, buf);
- n = snprintf(buf, sizeof buf, "SSH-1.5-OpenSSH-keyscan\r\n");
+ if (sscanf(buf, "SSH-%d.%d-%[^\n]\n",
+ &remote_major, &remote_minor, remote_version) == 3)
+ compat_datafellows(remote_version);
+ else
+ datafellows = 0;
+ if (c->c_keytype != KT_RSA1) {
+ if (!ssh2_capable(remote_major, remote_minor)) {
+ debug("%s doesn't support ssh2", c->c_name);
+ confree(s);
+ return;
+ }
+ } else if (remote_major != 1) {
+ debug("%s doesn't support ssh1", c->c_name);
+ confree(s);
+ return;
+ }
+ fprintf(stderr, "# %s %s\n", c->c_name, chop(buf));
+ n = snprintf(buf, sizeof buf, "SSH-%d.%d-OpenSSH-keyscan\r\n",
+ c->c_keytype == KT_RSA1? PROTOCOL_MAJOR_1 : PROTOCOL_MAJOR_2,
+ c->c_keytype == KT_RSA1? PROTOCOL_MINOR_1 : PROTOCOL_MINOR_2);
if (atomicio(write, s, buf, n) != n) {
error("write (%s): %s", c->c_name, strerror(errno));
confree(s);
return;
}
+ if (c->c_keytype != KT_RSA1) {
+ keyprint(c, keygrab_ssh2(c));
+ confree(s);
+ return;
+ }
c->c_status = CS_SIZE;
contouch(s);
}
-void
+static void
conread(int s)
{
int n;
@@ -451,7 +560,7 @@ conread(int s)
c->c_status = CS_KEYS;
break;
case CS_KEYS:
- keyprint(c->c_name, c->c_output_name, c->c_data, c->c_plen);
+ keyprint(c, keygrab_ssh1(c));
confree(s);
return;
break;
@@ -463,7 +572,7 @@ conread(int s)
contouch(s);
}
-void
+static void
conloop(void)
{
fd_set *r, *e;
@@ -515,81 +624,133 @@ conloop(void)
}
}
-char *
-nexthost(int argc, char **argv)
+static void
+do_host(char *host)
{
- static Linebuf *lb;
+ char *name = strnnsep(&host, " \t\n");
+ int j;
- for (;;) {
- if (!lb) {
- if (argno >= argc)
- return (NULL);
- if (argv[argno][0] != '-')
- return (argv[argno++]);
- if (!strcmp(argv[argno], "--")) {
- if (++argno >= argc)
- return (NULL);
- return (argv[argno++]);
- } else if (!strncmp(argv[argno], "-f", 2)) {
- char *fname;
-
- if (argv[argno][2])
- fname = &argv[argno++][2];
- else if (++argno >= argc) {
- error("missing filename for `-f'");
- return (NULL);
- } else
- fname = argv[argno++];
- if (!strcmp(fname, "-"))
- fname = NULL;
- lb = Linebuf_alloc(fname, error);
- } else
- error("ignoring invalid/misplaced option `%s'",
- argv[argno++]);
- } else {
- char *line;
-
- line = Linebuf_getline(lb);
- if (line)
- return (line);
- Linebuf_free(lb);
- lb = NULL;
+ if (name == NULL)
+ return;
+ for (j = KT_RSA1; j <= KT_RSA; j *= 2) {
+ if (get_keytypes & j) {
+ while (ncon >= MAXCON)
+ conloop();
+ conalloc(name, *host ? host : name, j);
}
}
}
void
+fatal(const char *fmt,...)
+{
+ va_list args;
+ va_start(args, fmt);
+ do_log(SYSLOG_LEVEL_FATAL, fmt, args);
+ va_end(args);
+ if (nonfatal_fatal)
+ longjmp(kexjmp, -1);
+ else
+ fatal_cleanup();
+}
+
+static void
usage(void)
{
- fatal("usage: %s [-t timeout] { [--] host | -f file } ...", __progname);
- return;
+ fprintf(stderr, "Usage: %s [options] host ...\n",
+ __progname);
+ fprintf(stderr, "Options:\n");
+ fprintf(stderr, " -f file Read hosts or addresses from file.\n");
+ fprintf(stderr, " -p port Connect to the specified port.\n");
+ fprintf(stderr, " -t keytype Specify the host key type.\n");
+ fprintf(stderr, " -T timeout Set connection timeout.\n");
+ fprintf(stderr, " -v Verbose; display verbose debugging messages.\n");
+ fprintf(stderr, " -4 Use IPv4 only.\n");
+ fprintf(stderr, " -6 Use IPv6 only.\n");
+ exit(1);
}
int
main(int argc, char **argv)
{
- char *host = NULL;
+ int debug_flag = 0, log_level = SYSLOG_LEVEL_INFO;
+ int opt, fopt_count = 0;
+ char *tname;
+
+ extern int optind;
+ extern char *optarg;
TAILQ_INIT(&tq);
- if (argc <= argno)
+ if (argc <= 1)
usage();
- if (argv[1][0] == '-' && argv[1][1] == 't') {
- argno++;
- if (argv[1][2])
- timeout = atoi(&argv[1][2]);
- else {
- if (argno >= argc)
+ while ((opt = getopt(argc, argv, "v46p:T:t:f:")) != -1) {
+ switch (opt) {
+ case 'p':
+ ssh_port = a2port(optarg);
+ if (ssh_port == 0) {
+ fprintf(stderr, "Bad port '%s'\n", optarg);
+ exit(1);
+ }
+ break;
+ case 'T':
+ timeout = atoi(optarg);
+ if (timeout <= 0)
usage();
- timeout = atoi(argv[argno++]);
- }
- if (timeout <= 0)
+ break;
+ case 'v':
+ if (!debug_flag) {
+ debug_flag = 1;
+ log_level = SYSLOG_LEVEL_DEBUG1;
+ }
+ else if (log_level < SYSLOG_LEVEL_DEBUG3)
+ log_level++;
+ else
+ fatal("Too high debugging level.");
+ break;
+ case 'f':
+ if (strcmp(optarg, "-") == 0)
+ optarg = NULL;
+ argv[fopt_count++] = optarg;
+ break;
+ case 't':
+ get_keytypes = 0;
+ tname = strtok(optarg, ",");
+ while (tname) {
+ int type = key_type_from_name(tname);
+ switch (type) {
+ case KEY_RSA1:
+ get_keytypes |= KT_RSA1;
+ break;
+ case KEY_DSA:
+ get_keytypes |= KT_DSA;
+ break;
+ case KEY_RSA:
+ get_keytypes |= KT_RSA;
+ break;
+ case KEY_UNSPEC:
+ fatal("unknown key type %s", tname);
+ }
+ tname = strtok(NULL, ",");
+ }
+ break;
+ case '4':
+ IPv4or6 = AF_INET;
+ break;
+ case '6':
+ IPv4or6 = AF_INET6;
+ break;
+ case '?':
+ default:
usage();
+ }
}
- if (argc <= argno)
+ if (optind == argc && !fopt_count)
usage();
+ log_init("ssh-keyscan", log_level, SYSLOG_FACILITY_USER, 1);
+
maxfd = fdlim_get(1);
if (maxfd < 0)
fatal("%s: fdlim_get: bad value", __progname);
@@ -606,18 +767,24 @@ main(int argc, char **argv)
read_wait = xmalloc(read_wait_size);
memset(read_wait, 0, read_wait_size);
- do {
- while (ncon < MAXCON) {
- char *name;
-
- host = nexthost(argc, argv);
- if (host == NULL)
- break;
- name = strnnsep(&host, " \t\n");
- conalloc(name, *host ? host : name);
+ if (fopt_count) {
+ Linebuf *lb;
+ char *line;
+ int j;
+
+ for (j = 0; j < fopt_count; j++) {
+ lb = Linebuf_alloc(argv[j], error);
+ if (!lb)
+ continue;
+ while ((line = Linebuf_getline(lb)) != NULL)
+ do_host(line);
+ Linebuf_free(lb);
}
- conloop();
- } while (host);
+ }
+
+ while (optind < argc)
+ do_host(argv[optind++]);
+
while (ncon > 0)
conloop();
diff --git a/crypto/openssh/ssh-keyscan/Makefile b/crypto/openssh/ssh-keyscan/Makefile
index 6748ed7..2ea5c23 100644
--- a/crypto/openssh/ssh-keyscan/Makefile
+++ b/crypto/openssh/ssh-keyscan/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.3 2001/03/03 23:59:39 markus Exp $
+# $OpenBSD: Makefile,v 1.4 2001/08/05 23:18:20 markus Exp $
.PATH: ${.CURDIR}/..
@@ -14,5 +14,5 @@ SRCS= ssh-keyscan.c
.include <bsd.prog.mk>
-LDADD+= -lcrypto
-DPADD+= ${LIBCRYPTO}
+LDADD+= -lcrypto -lz
+DPADD+= ${LIBCRYPTO} ${LIBZ}
diff --git a/crypto/openssh/ssh-rsa.c b/crypto/openssh/ssh-rsa.c
index b502ddb..8e79d4e 100644
--- a/crypto/openssh/ssh-rsa.c
+++ b/crypto/openssh/ssh-rsa.c
@@ -23,7 +23,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: ssh-rsa.c,v 1.8 2001/03/27 10:57:00 markus Exp $");
+RCSID("$OpenBSD: ssh-rsa.c,v 1.16 2002/02/24 19:14:59 markus Exp $");
#include <openssl/evp.h>
#include <openssl/err.h>
@@ -40,12 +40,12 @@ RCSID("$OpenBSD: ssh-rsa.c,v 1.8 2001/03/27 10:57:00 markus Exp $");
int
ssh_rsa_sign(
Key *key,
- u_char **sigp, int *lenp,
- u_char *data, int datalen)
+ u_char **sigp, u_int *lenp,
+ u_char *data, u_int datalen)
{
const EVP_MD *evp_md;
EVP_MD_CTX md;
- u_char *digest, *sig, *ret;
+ u_char digest[EVP_MAX_MD_SIZE], *sig, *ret;
u_int slen, dlen, len;
int ok, nid;
Buffer b;
@@ -54,23 +54,24 @@ ssh_rsa_sign(
error("ssh_rsa_sign: no RSA key");
return -1;
}
+ if (datafellows & SSH_BUG_SIGBLOB) {
+ error("ssh_rsa_sign: SSH_BUG_SIGBLOB not supported");
+ return -1;
+ }
nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
error("ssh_rsa_sign: EVP_get_digestbynid %d failed", nid);
return -1;
}
- dlen = evp_md->md_size;
- digest = xmalloc(dlen);
EVP_DigestInit(&md, evp_md);
EVP_DigestUpdate(&md, data, datalen);
- EVP_DigestFinal(&md, digest, NULL);
+ EVP_DigestFinal(&md, digest, &dlen);
slen = RSA_size(key->rsa);
sig = xmalloc(slen);
ok = RSA_sign(nid, digest, dlen, sig, &len, key->rsa);
- memset(digest, 'd', dlen);
- xfree(digest);
+ memset(digest, 'd', sizeof(digest));
if (ok != 1) {
int ecode = ERR_get_error();
@@ -103,21 +104,20 @@ ssh_rsa_sign(
*lenp = len;
if (sigp != NULL)
*sigp = ret;
- debug2("ssh_rsa_sign: done");
return 0;
}
int
ssh_rsa_verify(
Key *key,
- u_char *signature, int signaturelen,
- u_char *data, int datalen)
+ u_char *signature, u_int signaturelen,
+ u_char *data, u_int datalen)
{
Buffer b;
const EVP_MD *evp_md;
EVP_MD_CTX md;
char *ktype;
- u_char *sigblob, *digest;
+ u_char digest[EVP_MAX_MD_SIZE], *sigblob;
u_int len, dlen;
int rlen, ret, nid;
@@ -125,13 +125,17 @@ ssh_rsa_verify(
error("ssh_rsa_verify: no RSA key");
return -1;
}
+ if (datafellows & SSH_BUG_SIGBLOB) {
+ error("ssh_rsa_verify: SSH_BUG_SIGBLOB not supported");
+ return -1;
+ }
if (BN_num_bits(key->rsa->n) < 768) {
error("ssh_rsa_verify: n too small: %d bits",
BN_num_bits(key->rsa->n));
return -1;
}
buffer_init(&b);
- buffer_append(&b, (char *) signature, signaturelen);
+ buffer_append(&b, signature, signaturelen);
ktype = buffer_get_string(&b, NULL);
if (strcmp("ssh-rsa", ktype) != 0) {
error("ssh_rsa_verify: cannot handle type %s", ktype);
@@ -140,29 +144,26 @@ ssh_rsa_verify(
return -1;
}
xfree(ktype);
- sigblob = (u_char *)buffer_get_string(&b, &len);
+ sigblob = buffer_get_string(&b, &len);
rlen = buffer_len(&b);
buffer_free(&b);
- if(rlen != 0) {
- xfree(sigblob);
+ if (rlen != 0) {
error("ssh_rsa_verify: remaining bytes in signature %d", rlen);
+ xfree(sigblob);
return -1;
}
nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
- xfree(sigblob);
error("ssh_rsa_verify: EVP_get_digestbynid %d failed", nid);
+ xfree(sigblob);
return -1;
}
- dlen = evp_md->md_size;
- digest = xmalloc(dlen);
EVP_DigestInit(&md, evp_md);
EVP_DigestUpdate(&md, data, datalen);
- EVP_DigestFinal(&md, digest, NULL);
+ EVP_DigestFinal(&md, digest, &dlen);
ret = RSA_verify(nid, digest, dlen, sigblob, len, key->rsa);
- memset(digest, 'd', dlen);
- xfree(digest);
+ memset(digest, 'd', sizeof(digest));
memset(sigblob, 's', len);
xfree(sigblob);
if (ret == 0) {
diff --git a/crypto/openssh/ssh-rsa.h b/crypto/openssh/ssh-rsa.h
index af2b2fe..7177a3f 100644
--- a/crypto/openssh/ssh-rsa.h
+++ b/crypto/openssh/ssh-rsa.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-rsa.h,v 1.3 2001/01/29 01:58:18 niklas Exp $ */
+/* $OpenBSD: ssh-rsa.h,v 1.6 2002/02/24 19:14:59 markus Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -26,16 +26,7 @@
#ifndef SSH_RSA_H
#define SSH_RSA_H
-int
-ssh_rsa_sign(
- Key *key,
- u_char **sigp, int *lenp,
- u_char *data, int datalen);
-
-int
-ssh_rsa_verify(
- Key *key,
- u_char *signature, int signaturelen,
- u_char *data, int datalen);
+int ssh_rsa_sign(Key *, u_char **, u_int *, u_char *, u_int);
+int ssh_rsa_verify(Key *, u_char *, u_int, u_char *, u_int);
#endif
diff --git a/crypto/openssh/ssh/Makefile b/crypto/openssh/ssh/Makefile
index 2cf80e1..f493e1f 100644
--- a/crypto/openssh/ssh/Makefile
+++ b/crypto/openssh/ssh/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.30 2001/04/14 16:33:20 stevesk Exp $
+# $OpenBSD: Makefile,v 1.37 2002/03/05 00:49:51 deraadt Exp $
.PATH: ${.CURDIR}/..
@@ -17,6 +17,12 @@ SRCS= ssh.c readconf.c clientloop.c sshtty.c \
.include <bsd.own.mk> # for AFS
+.if (${KERBEROS5:L} == "yes")
+CFLAGS+= -DKRB5 -I${DESTDIR}/usr/include/kerberosV
+LDADD+= -lkrb5 -lasn1 -lcom_err
+DPADD+= ${LIBKRB5} ${LIBASN1}
+.endif # KERBEROS5
+
.if (${KERBEROS:L} == "yes")
CFLAGS+= -DKRB4 -I${DESTDIR}/usr/include/kerberosIV
LDADD+= -lkrb
@@ -30,5 +36,5 @@ DPADD+= ${LIBKRBAFS}
.include <bsd.prog.mk>
-LDADD+= -lcrypto -lz
+LDADD+= -lcrypto -lz -ldes
DPADD+= ${LIBCRYPTO} ${LIBZ}
diff --git a/crypto/openssh/ssh1.h b/crypto/openssh/ssh1.h
index 770c5e4..98d1dc9 100644
--- a/crypto/openssh/ssh1.h
+++ b/crypto/openssh/ssh1.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh1.h,v 1.2 2001/01/29 01:58:18 niklas Exp $ */
+/* $OpenBSD: ssh1.h,v 1.3 2001/05/30 12:55:13 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -66,6 +66,10 @@
#define SSH_CMSG_HAVE_KERBEROS_TGT 44 /* credentials (s) */
#define SSH_CMSG_HAVE_AFS_TOKEN 65 /* token (s) */
+/* protocol version 1.5 overloads some version 1.3 message types */
+#define SSH_MSG_CHANNEL_INPUT_EOF SSH_MSG_CHANNEL_CLOSE
+#define SSH_MSG_CHANNEL_OUTPUT_CLOSE SSH_MSG_CHANNEL_CLOSE_CONFIRMATION
+
/*
* Authentication methods. New types can be added, but old types should not
* be removed for compatibility. The maximum allowed value is 31.
@@ -83,4 +87,3 @@
/* Protocol flags. These are bit masks. */
#define SSH_PROTOFLAG_SCREEN_NUMBER 1 /* X11 forwarding includes screen */
#define SSH_PROTOFLAG_HOST_IN_FWD_OPEN 2 /* forwarding opens contain host */
-
diff --git a/crypto/openssh/ssh2.h b/crypto/openssh/ssh2.h
index e45aef2..091e52b 100644
--- a/crypto/openssh/ssh2.h
+++ b/crypto/openssh/ssh2.h
@@ -1,3 +1,5 @@
+/* $OpenBSD: ssh2.h,v 1.8 2002/03/04 17:27:39 stevesk Exp $ */
+
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -52,7 +54,21 @@
*
* 192-255 Local extensions
*/
-/* RCSID("$OpenBSD: ssh2.h,v 1.6 2001/03/27 17:46:49 provos Exp $"); */
+
+/* ranges */
+
+#define SSH2_MSG_TRANSPORT_MIN 1
+#define SSH2_MSG_TRANSPORT_MAX 49
+#define SSH2_MSG_USERAUTH_MIN 50
+#define SSH2_MSG_USERAUTH_MAX 79
+#define SSH2_MSG_CONNECTION_MIN 80
+#define SSH2_MSG_CONNECTION_MAX 127
+#define SSH2_MSG_RESERVED_MIN 128
+#define SSH2_MSG_RESERVED_MAX 191
+#define SSH2_MSG_LOCAL_MIN 192
+#define SSH2_MSG_LOCAL_MAX 255
+#define SSH2_MSG_MIN 1
+#define SSH2_MSG_MAX 255
/* transport layer: generic */
diff --git a/crypto/openssh/sshd/Makefile b/crypto/openssh/sshd/Makefile
index 5ccce8d..8fdd8e6 100644
--- a/crypto/openssh/sshd/Makefile
+++ b/crypto/openssh/sshd/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.38 2001/03/29 21:17:40 markus Exp $
+# $OpenBSD: Makefile,v 1.46 2002/03/05 00:49:51 deraadt Exp $
.PATH: ${.CURDIR}/..
@@ -7,15 +7,23 @@ BINOWN= root
BINMODE=555
BINDIR= /usr/sbin
MAN= sshd.8
-CFLAGS+=-DHAVE_LOGIN_CAP
+CFLAGS+=-DHAVE_LOGIN_CAP -DBSD_AUTH
SRCS= sshd.c auth-rhosts.c auth-passwd.c auth-rsa.c auth-rh-rsa.c \
sshpty.c sshlogin.c servconf.c serverloop.c \
auth.c auth1.c auth2.c auth-options.c session.c \
- auth-chall.c auth2-chall.c groupaccess.c
+ auth-chall.c auth2-chall.c groupaccess.c \
+ auth-skey.c auth-bsdauth.c
.include <bsd.own.mk> # for KERBEROS and AFS
+.if (${KERBEROS5:L} == "yes")
+CFLAGS+=-DKRB5 -I${DESTDIR}/usr/include/kerberosV
+SRCS+= auth-krb5.c
+LDADD+= -lkrb5 -lkafs -lasn1 -lcom_err
+DPADD+= ${LIBKRB5} ${LIBKAFS} ${LIBASN1}
+.endif # KERBEROS5
+
.if (${KERBEROS:L} == "yes")
.if (${AFS:L} == "yes")
CFLAGS+= -DAFS
@@ -30,7 +38,7 @@ DPADD+= ${LIBKRB}
.include <bsd.prog.mk>
-LDADD+= -lcrypto -lutil -lz
+LDADD+= -lcrypto -lutil -lz -ldes
DPADD+= ${LIBCRYPTO} ${LIBUTIL} ${LIBZ}
.if (${TCP_WRAPPERS:L} == "yes")
@@ -39,8 +47,8 @@ LDADD+= -lwrap
DPADD+= ${LIBWRAP}
.endif
-.if (${SKEY:L} == "yes")
-CFLAGS+= -DSKEY
-LDADD+= -lskey
-DPADD+= ${SKEY}
-.endif
+#.if (${SKEY:L} == "yes")
+#CFLAGS+= -DSKEY
+#LDADD+= -lskey
+#DPADD+= ${SKEY}
+#.endif
diff --git a/crypto/openssh/sshlogin.h b/crypto/openssh/sshlogin.h
index 7285bc2..27a8386 100644
--- a/crypto/openssh/sshlogin.h
+++ b/crypto/openssh/sshlogin.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshlogin.h,v 1.1 2001/03/04 01:46:30 djm Exp $ */
+/* $OpenBSD: sshlogin.h,v 1.3 2001/06/26 17:27:25 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -14,27 +14,10 @@
#ifndef SSHLOGIN_H
#define SSHLOGIN_H
-/*
- * Returns the time when the user last logged in. Returns 0 if the
- * information is not available. This must be called before record_login.
- * The host from which the user logged in is stored in buf.
- */
-u_long
-get_last_login_time(uid_t uid, const char *logname,
- char *buf, u_int bufsize);
-
-/*
- * Records that the user has logged in. This does many things normally done
- * by login(1).
- */
void
-record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid,
- const char *host, struct sockaddr *addr);
-
-/*
- * Records that the user has logged out. This does many thigs normally done
- * by login(1) or init.
- */
-void record_logout(pid_t pid, const char *ttyname);
+record_login(pid_t, const char *, const char *, uid_t,
+ const char *, struct sockaddr *);
+void record_logout(pid_t, const char *);
+u_long get_last_login_time(uid_t, const char *, char *, u_int);
#endif
diff --git a/crypto/openssh/sshpty.h b/crypto/openssh/sshpty.h
index d7aac0f..df65e28 100644
--- a/crypto/openssh/sshpty.h
+++ b/crypto/openssh/sshpty.h
@@ -1,3 +1,5 @@
+/* $OpenBSD: sshpty.h,v 1.4 2002/03/04 17:27:39 stevesk Exp $ */
+
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -12,36 +14,13 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-/* RCSID("$OpenBSD: sshpty.h,v 1.1 2001/03/04 01:46:30 djm Exp $"); */
-
#ifndef SSHPTY_H
#define SSHPTY_H
-/*
- * Allocates and opens a pty. Returns 0 if no pty could be allocated, or
- * nonzero if a pty was successfully allocated. On success, open file
- * descriptors for the pty and tty sides and the name of the tty side are
- * returned (the buffer must be able to hold at least 64 characters).
- */
-int pty_allocate(int *ptyfd, int *ttyfd, char *ttyname, int ttynamelen);
-
-/*
- * Releases the tty. Its ownership is returned to root, and permissions to
- * 0666.
- */
-void pty_release(const char *ttyname);
-
-/*
- * Makes the tty the processes controlling tty and sets it to sane modes.
- * This may need to reopen the tty to get rid of possible eavesdroppers.
- */
-void pty_make_controlling_tty(int *ttyfd, const char *ttyname);
-
-/* Changes the window size associated with the pty. */
-void
-pty_change_window_size(int ptyfd, int row, int col,
- int xpixel, int ypixel);
-
-void pty_setowner(struct passwd *pw, const char *ttyname);
+int pty_allocate(int *, int *, char *, int);
+void pty_release(const char *);
+void pty_make_controlling_tty(int *, const char *);
+void pty_change_window_size(int, int, int, int, int);
+void pty_setowner(struct passwd *, const char *);
#endif /* SSHPTY_H */
diff --git a/crypto/openssh/sshtty.c b/crypto/openssh/sshtty.c
index 7849890..5c016f8 100644
--- a/crypto/openssh/sshtty.c
+++ b/crypto/openssh/sshtty.c
@@ -1,4 +1,3 @@
-/* $OpenBSD: sshtty.c,v 1.1 2001/04/14 16:33:20 stevesk Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -36,6 +35,7 @@
*/
#include "includes.h"
+RCSID("$OpenBSD: sshtty.c,v 1.3 2002/03/04 17:27:39 stevesk Exp $");
#include "sshtty.h"
#include "log.h"
@@ -46,7 +46,7 @@ static int _in_raw_mode = 0;
int
in_raw_mode(void)
{
- return _in_raw_mode;
+ return _in_raw_mode;
}
struct termios
diff --git a/crypto/openssh/sshtty.h b/crypto/openssh/sshtty.h
index e29385e..7ba4a26 100644
--- a/crypto/openssh/sshtty.h
+++ b/crypto/openssh/sshtty.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshtty.h,v 1.1 2001/04/14 16:33:20 stevesk Exp $ */
+/* $OpenBSD: sshtty.h,v 1.2 2001/06/26 17:27:25 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -40,26 +40,9 @@
#include <termios.h>
-/*
- * Accessor function indicating whether we are in raw mode. Set by
- * enter_raw_mode() and leave_raw_mode().
- */
-int in_raw_mode(void);
-
-/*
- * Return terminal modes, as saved by enter_raw_mode().
- */
+int in_raw_mode(void);
struct termios get_saved_tio(void);
-
-/*
- * Returns the user's terminal to normal mode if it had been
- * put in raw mode.
- */
-void leave_raw_mode(void);
-
-/*
- * Puts the user's terminal in raw mode.
- */
-void enter_raw_mode(void);
+void leave_raw_mode(void);
+void enter_raw_mode(void);
#endif
diff --git a/crypto/openssh/tildexpand.c b/crypto/openssh/tildexpand.c
index 46bdaae..e89a7ad 100644
--- a/crypto/openssh/tildexpand.c
+++ b/crypto/openssh/tildexpand.c
@@ -11,7 +11,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: tildexpand.c,v 1.11 2001/02/08 19:30:53 itojun Exp $");
+RCSID("$OpenBSD: tildexpand.c,v 1.12 2001/08/11 22:51:27 jakob Exp $");
#include "xmalloc.h"
#include "log.h"
@@ -67,6 +67,6 @@ tilde_expand_filename(const char *filename, uid_t my_uid)
if (len > MAXPATHLEN)
fatal("Home directory too long (%d > %d", len-1, MAXPATHLEN-1);
expanded = xmalloc(len);
- snprintf(expanded, len, "%s/%s", pw->pw_dir, cp + 1);
+ snprintf(expanded, len, "%s%s%s", pw->pw_dir, strcmp(pw->pw_dir, "/") ? "/" : "", cp + 1);
return expanded;
}
diff --git a/crypto/openssh/tildexpand.h b/crypto/openssh/tildexpand.h
index 88734f4..f5e7e40 100644
--- a/crypto/openssh/tildexpand.h
+++ b/crypto/openssh/tildexpand.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tildexpand.h,v 1.2 2001/01/29 01:58:19 niklas Exp $ */
+/* $OpenBSD: tildexpand.h,v 1.4 2001/06/26 17:27:25 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -12,8 +12,4 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-/*
- * Expands tildes in the file name. Returns data allocated by xmalloc.
- * Warning: this calls getpw*.
- */
-char *tilde_expand_filename(const char *filename, uid_t my_uid);
+char *tilde_expand_filename(const char *, uid_t);
diff --git a/crypto/openssh/ttymodes.c b/crypto/openssh/ttymodes.c
index 6124cb4..ccc001f 100644
--- a/crypto/openssh/ttymodes.c
+++ b/crypto/openssh/ttymodes.c
@@ -43,7 +43,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: ttymodes.c,v 1.13 2001/04/15 01:35:22 stevesk Exp $");
+RCSID("$OpenBSD: ttymodes.c,v 1.16 2001/12/27 20:39:58 markus Exp $");
#include "packet.h"
#include "log.h"
@@ -275,22 +275,22 @@ tty_make_modes(int fd, struct termios *tiop)
/* Store input and output baud rates. */
baud = speed_to_baud(cfgetospeed(&tio));
- debug2("tty_make_modes: ospeed %d", baud);
+ debug3("tty_make_modes: ospeed %d", baud);
buffer_put_char(&buf, tty_op_ospeed);
buffer_put_int(&buf, baud);
baud = speed_to_baud(cfgetispeed(&tio));
- debug2("tty_make_modes: ispeed %d", baud);
+ debug3("tty_make_modes: ispeed %d", baud);
buffer_put_char(&buf, tty_op_ispeed);
buffer_put_int(&buf, baud);
/* Store values of mode flags. */
#define TTYCHAR(NAME, OP) \
- debug2("tty_make_modes: %d %d", OP, tio.c_cc[NAME]); \
+ debug3("tty_make_modes: %d %d", OP, tio.c_cc[NAME]); \
buffer_put_char(&buf, OP); \
put_arg(&buf, tio.c_cc[NAME]);
#define TTYMODE(NAME, FIELD, OP) \
- debug2("tty_make_modes: %d %d", OP, ((tio.FIELD & NAME) != 0)); \
+ debug3("tty_make_modes: %d %d", OP, ((tio.FIELD & NAME) != 0)); \
buffer_put_char(&buf, OP); \
put_arg(&buf, ((tio.FIELD & NAME) != 0));
@@ -326,7 +326,7 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
if (compat20) {
*n_bytes_ptr = packet_get_int();
- debug2("tty_parse_modes: SSH2 n_bytes %d", *n_bytes_ptr);
+ debug3("tty_parse_modes: SSH2 n_bytes %d", *n_bytes_ptr);
if (*n_bytes_ptr == 0)
return;
get_arg = packet_get_int;
@@ -358,7 +358,7 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
case TTY_OP_ISPEED_PROTO2:
n_bytes += 4;
baud = packet_get_int();
- debug2("tty_parse_modes: ispeed %d", baud);
+ debug3("tty_parse_modes: ispeed %d", baud);
if (failure != -1 && cfsetispeed(&tio, baud_to_speed(baud)) == -1)
error("cfsetispeed failed for %d", baud);
break;
@@ -368,7 +368,7 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
case TTY_OP_OSPEED_PROTO2:
n_bytes += 4;
baud = packet_get_int();
- debug2("tty_parse_modes: ospeed %d", baud);
+ debug3("tty_parse_modes: ospeed %d", baud);
if (failure != -1 && cfsetospeed(&tio, baud_to_speed(baud)) == -1)
error("cfsetospeed failed for %d", baud);
break;
@@ -377,7 +377,7 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
case OP: \
n_bytes += arg_size; \
tio.c_cc[NAME] = get_arg(); \
- debug2("tty_parse_modes: %d %d", OP, tio.c_cc[NAME]); \
+ debug3("tty_parse_modes: %d %d", OP, tio.c_cc[NAME]); \
break;
#define TTYMODE(NAME, FIELD, OP) \
case OP: \
@@ -386,7 +386,7 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
tio.FIELD |= NAME; \
else \
tio.FIELD &= ~NAME; \
- debug2("tty_parse_modes: %d %d", OP, arg); \
+ debug3("tty_parse_modes: %d %d", OP, arg); \
break;
#include "ttymodes.h"
@@ -396,7 +396,7 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
default:
debug("Ignoring unsupported tty mode opcode %d (0x%x)",
- opcode, opcode);
+ opcode, opcode);
if (!compat20) {
/*
* SSH1:
@@ -422,7 +422,6 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
* more coming after the mode data.
*/
log("parse_tty_modes: unknown opcode %d", opcode);
- packet_integrity_check(0, 1, SSH_CMSG_REQUEST_PTY);
goto set;
}
} else {
diff --git a/crypto/openssh/ttymodes.h b/crypto/openssh/ttymodes.h
index ad980e9..6870592 100644
--- a/crypto/openssh/ttymodes.h
+++ b/crypto/openssh/ttymodes.h
@@ -1,4 +1,5 @@
-/* RCSID("$OpenBSD: ttymodes.h,v 1.11 2001/04/14 16:33:20 stevesk Exp $"); */
+/* $OpenBSD: ttymodes.h,v 1.12 2002/03/04 17:27:39 stevesk Exp $ */
+
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
diff --git a/crypto/openssh/uidswap.c b/crypto/openssh/uidswap.c
index 39952e2..e794fac 100644
--- a/crypto/openssh/uidswap.c
+++ b/crypto/openssh/uidswap.c
@@ -12,7 +12,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: uidswap.c,v 1.16 2001/04/20 16:32:22 markus Exp $");
+RCSID("$OpenBSD: uidswap.c,v 1.19 2001/12/19 07:18:56 deraadt Exp $");
#include "log.h"
#include "uidswap.h"
@@ -54,8 +54,8 @@ temporarily_use_uid(struct passwd *pw)
}
privileged = 1;
temporarily_use_uid_effective = 1;
- saved_egid = getegid();
- saved_egroupslen = getgroups(NGROUPS_MAX, saved_egroups);
+ saved_egid = getegid();
+ saved_egroupslen = getgroups(NGROUPS_MAX, saved_egroups);
if (saved_egroupslen < 0)
fatal("getgroups: %.100s", strerror(errno));
@@ -64,7 +64,7 @@ temporarily_use_uid(struct passwd *pw)
if (initgroups(pw->pw_name, pw->pw_gid) < 0)
fatal("initgroups: %s: %.100s", pw->pw_name,
strerror(errno));
- user_groupslen = getgroups(NGROUPS_MAX, user_groups);
+ user_groupslen = getgroups(NGROUPS_MAX, user_groups);
if (user_groupslen < 0)
fatal("getgroups: %.100s", strerror(errno));
}
diff --git a/crypto/openssh/uidswap.h b/crypto/openssh/uidswap.h
index 228e5a5..0726980 100644
--- a/crypto/openssh/uidswap.h
+++ b/crypto/openssh/uidswap.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: uidswap.h,v 1.7 2001/04/06 21:00:17 markus Exp $ */
+/* $OpenBSD: uidswap.h,v 1.9 2001/06/26 17:27:25 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -15,22 +15,8 @@
#ifndef UIDSWAP_H
#define UIDSWAP_H
-/*
- * Temporarily changes to the given uid. If the effective user id is not
- * root, this does nothing. This call cannot be nested.
- */
-void temporarily_use_uid(struct passwd *pw);
-
-/*
- * Restores the original effective user id after temporarily_use_uid().
- * This should only be called while temporarily_use_uid is effective.
- */
-void restore_uid(void);
-
-/*
- * Permanently sets all uids to the given uid. This cannot be called while
- * temporarily_use_uid is effective. This must also clear any saved uids.
- */
-void permanently_set_uid(struct passwd *pw);
+void temporarily_use_uid(struct passwd *);
+void restore_uid(void);
+void permanently_set_uid(struct passwd *);
#endif /* UIDSWAP_H */
diff --git a/crypto/openssh/uuencode.c b/crypto/openssh/uuencode.c
index 1be975a..0074cd8 100644
--- a/crypto/openssh/uuencode.c
+++ b/crypto/openssh/uuencode.c
@@ -1,5 +1,3 @@
-/* $OpenBSD: uuencode.c,v 1.12 2001/03/01 02:27:18 deraadt Exp $ */
-
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -25,13 +23,13 @@
*/
#include "includes.h"
+RCSID("$OpenBSD: uuencode.c,v 1.15 2002/03/04 17:27:39 stevesk Exp $");
+
#include "xmalloc.h"
#include "uuencode.h"
#include <resolv.h>
-RCSID("$OpenBSD: uuencode.c,v 1.12 2001/03/01 02:27:18 deraadt Exp $");
-
int
uuencode(u_char *src, u_int srclength,
char *target, size_t targsize)
@@ -52,7 +50,7 @@ uudecode(const char *src, u_char *target, size_t targsize)
;
for (; *p != '\0' && *p != ' ' && *p != '\t'; p++)
;
- /* and remote trailing whitespace because __b64_pton needs this */
+ /* and remove trailing whitespace because __b64_pton needs this */
*p = '\0';
len = __b64_pton(encoded, target, targsize);
xfree(encoded);
@@ -60,7 +58,7 @@ uudecode(const char *src, u_char *target, size_t targsize)
}
void
-dump_base64(FILE *fp, u_char *data, int len)
+dump_base64(FILE *fp, u_char *data, u_int len)
{
u_char *buf = xmalloc(2*len);
int i, n;
diff --git a/crypto/openssh/uuencode.h b/crypto/openssh/uuencode.h
index 42f83c2..682b623 100644
--- a/crypto/openssh/uuencode.h
+++ b/crypto/openssh/uuencode.h
@@ -1,7 +1,7 @@
-/* $OpenBSD: uuencode.h,v 1.5 2001/01/29 01:58:19 niklas Exp $ */
+/* $OpenBSD: uuencode.h,v 1.9 2002/02/25 16:33:27 markus Exp $ */
/*
- * Copyright (c) 1999 Markus Friedl. All rights reserved.
+ * Copyright (c) 2000 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,7 +26,7 @@
#ifndef UUENCODE_H
#define UUENCODE_H
-int uuencode(u_char *src, u_int srclength, char *target, size_t targsize);
-int uudecode(const char *src, u_char *target, size_t targsize);
-void dump_base64(FILE *fp, u_char *data, int len);
+int uuencode(u_char *, u_int, char *, size_t);
+int uudecode(const char *, u_char *, size_t);
+void dump_base64(FILE *, u_char *, u_int);
#endif
diff --git a/crypto/openssh/xmalloc.c b/crypto/openssh/xmalloc.c
index 5046627..99c6ac3 100644
--- a/crypto/openssh/xmalloc.c
+++ b/crypto/openssh/xmalloc.c
@@ -13,7 +13,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: xmalloc.c,v 1.15 2001/04/16 08:05:34 deraadt Exp $");
+RCSID("$OpenBSD: xmalloc.c,v 1.16 2001/07/23 18:21:46 stevesk Exp $");
#include "xmalloc.h"
#include "log.h"
@@ -58,11 +58,10 @@ xfree(void *ptr)
char *
xstrdup(const char *str)
{
- size_t len = strlen(str) + 1;
+ size_t len;
char *cp;
- if (len == 0)
- fatal("xstrdup: zero size");
+ len = strlen(str) + 1;
cp = xmalloc(len);
strlcpy(cp, str, len);
return cp;
diff --git a/crypto/openssh/xmalloc.h b/crypto/openssh/xmalloc.h
index 59a598e..338a2d2 100644
--- a/crypto/openssh/xmalloc.h
+++ b/crypto/openssh/xmalloc.h
@@ -1,3 +1,5 @@
+/* $OpenBSD: xmalloc.h,v 1.8 2002/03/04 17:27:39 stevesk Exp $ */
+
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -14,21 +16,12 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-/* RCSID("$OpenBSD: xmalloc.h,v 1.5 2000/09/07 20:27:56 deraadt Exp $"); */
-
#ifndef XMALLOC_H
#define XMALLOC_H
-/* Like malloc, but calls fatal() if out of memory. */
-void *xmalloc(size_t size);
-
-/* Like realloc, but calls fatal() if out of memory. */
-void *xrealloc(void *ptr, size_t new_size);
-
-/* Frees memory allocated using xmalloc or xrealloc. */
-void xfree(void *ptr);
-
-/* Allocates memory using xmalloc, and copies the string into that memory. */
-char *xstrdup(const char *str);
+void *xmalloc(size_t);
+void *xrealloc(void *, size_t);
+void xfree(void *);
+char *xstrdup(const char *);
#endif /* XMALLOC_H */
OpenPOWER on IntegriCloud