summaryrefslogtreecommitdiffstats
path: root/crypto/openssh
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2002-06-23 14:01:54 +0000
committerdes <des@FreeBSD.org>2002-06-23 14:01:54 +0000
commit0161794f0d7387d8dc3714adf0e35efdc6bd335f (patch)
treefb74f8e16feadc3adb3fb99bf777512697f87546 /crypto/openssh
parent89f8664ea6e6c86b47bc4f2736830ecea80edafe (diff)
parent610201f50fdb0594e9885594b69e4ee69c71dd08 (diff)
downloadFreeBSD-src-0161794f0d7387d8dc3714adf0e35efdc6bd335f.zip
FreeBSD-src-0161794f0d7387d8dc3714adf0e35efdc6bd335f.tar.gz
This commit was generated by cvs2svn to compensate for changes in r98675,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'crypto/openssh')
-rw-r--r--crypto/openssh/Makefile4
-rw-r--r--crypto/openssh/README.smartcard66
-rw-r--r--crypto/openssh/auth-bsdauth.c21
-rw-r--r--crypto/openssh/auth-options.c42
-rw-r--r--crypto/openssh/auth-rhosts.c68
-rw-r--r--crypto/openssh/auth2-hostbased.c182
-rw-r--r--crypto/openssh/auth2-kbdint.c61
-rw-r--r--crypto/openssh/auth2-none.c106
-rw-r--r--crypto/openssh/auth2-passwd.c62
-rw-r--r--crypto/openssh/auth2-pubkey.c279
-rw-r--r--crypto/openssh/authfd.h34
-rw-r--r--crypto/openssh/authfile.h3
-rw-r--r--crypto/openssh/bufaux.h8
-rw-r--r--crypto/openssh/clientloop.c74
-rw-r--r--crypto/openssh/clientloop.h3
-rw-r--r--crypto/openssh/compress.c14
-rw-r--r--crypto/openssh/kex.c36
-rw-r--r--crypto/openssh/kex.h5
-rw-r--r--crypto/openssh/kexdh.c5
-rw-r--r--crypto/openssh/kexgex.c11
-rw-r--r--crypto/openssh/key.h3
-rw-r--r--crypto/openssh/lib/Makefile16
-rw-r--r--crypto/openssh/log.h6
-rw-r--r--crypto/openssh/mac.c4
-rw-r--r--crypto/openssh/misc.h8
-rw-r--r--crypto/openssh/monitor.c1498
-rw-r--r--crypto/openssh/monitor.h81
-rw-r--r--crypto/openssh/monitor_fdpass.c96
-rw-r--r--crypto/openssh/monitor_fdpass.h34
-rw-r--r--crypto/openssh/monitor_mm.c330
-rw-r--r--crypto/openssh/monitor_mm.h66
-rw-r--r--crypto/openssh/monitor_wrap.c920
-rw-r--r--crypto/openssh/monitor_wrap.h88
-rw-r--r--crypto/openssh/msg.c73
-rw-r--r--crypto/openssh/msg.h31
-rw-r--r--crypto/openssh/nchan.c60
-rw-r--r--crypto/openssh/packet.c145
-rw-r--r--crypto/openssh/radix.c245
-rw-r--r--crypto/openssh/readpass.c7
-rw-r--r--crypto/openssh/readpass.h3
-rw-r--r--crypto/openssh/scard.c305
-rw-r--r--crypto/openssh/scard.h10
-rw-r--r--crypto/openssh/scard/Ssh.bin.uu27
-rw-r--r--crypto/openssh/scard/Ssh.java59
-rw-r--r--crypto/openssh/scp.19
-rw-r--r--crypto/openssh/scp.c29
-rw-r--r--crypto/openssh/session.h38
-rw-r--r--crypto/openssh/sftp-client.c64
-rw-r--r--crypto/openssh/sftp-glob.h4
-rw-r--r--crypto/openssh/sftp-int.c9
-rw-r--r--crypto/openssh/sftp-server.c20
-rw-r--r--crypto/openssh/sftp.117
-rw-r--r--crypto/openssh/sftp.c21
-rw-r--r--crypto/openssh/ssh-add.119
-rw-r--r--crypto/openssh/ssh-agent.111
-rw-r--r--crypto/openssh/ssh-keygen.14
-rw-r--r--crypto/openssh/ssh-keygen.c149
-rw-r--r--crypto/openssh/ssh-keyscan.c8
-rw-r--r--crypto/openssh/ssh-keysign.867
-rw-r--r--crypto/openssh/ssh-keysign.c208
-rw-r--r--crypto/openssh/ssh-keysign/Makefile18
-rw-r--r--crypto/openssh/ssh-rsa.c34
-rw-r--r--crypto/openssh/ssh/Makefile12
-rw-r--r--crypto/openssh/ssh_config.5621
-rw-r--r--crypto/openssh/sshd/Makefile16
-rw-r--r--crypto/openssh/sshd_config.5707
-rw-r--r--crypto/openssh/ttymodes.c20
-rw-r--r--crypto/openssh/uidswap.c21
-rw-r--r--crypto/openssh/xmalloc.h4
69 files changed, 6637 insertions, 692 deletions
diff --git a/crypto/openssh/Makefile b/crypto/openssh/Makefile
index f1f871e..0b9c668 100644
--- a/crypto/openssh/Makefile
+++ b/crypto/openssh/Makefile
@@ -1,9 +1,9 @@
-# $OpenBSD: Makefile,v 1.10 2002/02/09 17:37:34 deraadt Exp $
+# $OpenBSD: Makefile,v 1.11 2002/05/23 19:24:30 markus Exp $
.include <bsd.own.mk>
SUBDIR= lib ssh sshd ssh-add ssh-keygen ssh-agent scp sftp-server \
- ssh-keyscan sftp scard
+ ssh-keysign ssh-keyscan sftp scard
distribution:
install -C -o root -g wheel -m 0644 ${.CURDIR}/ssh_config \
diff --git a/crypto/openssh/README.smartcard b/crypto/openssh/README.smartcard
index 499dc8e..4112e12 100644
--- a/crypto/openssh/README.smartcard
+++ b/crypto/openssh/README.smartcard
@@ -4,52 +4,33 @@ 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:
+(1) 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:
+(2) If you have used a previous version of ssh with your card, you
+ must remove the old applet and keys.
$ sectok
sectok> login -d
- sectok> jload /usr/libdata/ssh/Ssh.bin
+ sectok> junload Ssh.bin
+ sectok> delete 0012
+ sectok> delete sh
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:
+(3) load the Java Cardlet to the Cyberflex card and set card passphrase:
$ sectok
sectok> login -d
+ sectok> jload /usr/libdata/ssh/Ssh.bin
sectok> setpass
+ Enter new AUT0 passphrase:
+ Re-enter passphrase:
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.
@@ -57,13 +38,36 @@ need to:
wrong passphrase three times in a row, you will
destroy your card.
-(6) tell the ssh client to use the card reader:
+(4) load a RSA key to the card:
+
+ $ 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) 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:
+(6) or tell the agent (don't forget to restart) to use the smartcard:
$ ssh-add -s 1
+(7) Optional: If you don't want to use a card passphrase, change the
+ acl on the private key file:
+
+ $ sectok
+ sectok> login -d
+ sectok> acl 0012 world: w
+ world: w
+ AUT0: w inval
+ sectok> quit
+
+ If you do this, anyone who has access to your card
+ can assume your identity. This is not recommended.
+
-markus,
Tue Jul 17 23:54:51 CEST 2001
+
+$OpenBSD: README.smartcard,v 1.8 2002/03/26 18:56:23 rees Exp $
diff --git a/crypto/openssh/auth-bsdauth.c b/crypto/openssh/auth-bsdauth.c
index b70d48f..4f1b452 100644
--- a/crypto/openssh/auth-bsdauth.c
+++ b/crypto/openssh/auth-bsdauth.c
@@ -22,12 +22,13 @@
* 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 $");
+RCSID("$OpenBSD: auth-bsdauth.c,v 1.4 2002/06/19 00:27:55 deraadt Exp $");
#ifdef BSD_AUTH
#include "xmalloc.h"
#include "auth.h"
#include "log.h"
+#include "monitor_wrap.h"
static void *
bsdauth_init_ctx(Authctxt *authctxt)
@@ -35,7 +36,7 @@ bsdauth_init_ctx(Authctxt *authctxt)
return authctxt;
}
-static int
+int
bsdauth_query(void *ctx, char **name, char **infotxt,
u_int *numprompts, char ***prompts, u_int **echo_on)
{
@@ -56,7 +57,7 @@ bsdauth_query(void *ctx, char **name, char **infotxt,
debug3("bsdauth_query: style %s",
authctxt->style ? authctxt->style : "<default>");
authctxt->as = auth_userchallenge(authctxt->user,
- authctxt->style, "auth-ssh", &challenge);
+ authctxt->style, "auth-ssh", &challenge);
if (authctxt->as == NULL)
challenge = NULL;
debug2("bsdauth_query: <%s>", challenge ? challenge : "empty");
@@ -65,8 +66,8 @@ bsdauth_query(void *ctx, char **name, char **infotxt,
if (challenge == NULL)
return -1;
- *name = xstrdup("");
- *infotxt = xstrdup("");
+ *name = xstrdup("");
+ *infotxt = xstrdup("");
*numprompts = 1;
*prompts = xmalloc(*numprompts * sizeof(char*));
*echo_on = xmalloc(*numprompts * sizeof(u_int));
@@ -76,7 +77,7 @@ bsdauth_query(void *ctx, char **name, char **infotxt,
return 0;
}
-static int
+int
bsdauth_respond(void *ctx, u_int numresponses, char **responses)
{
Authctxt *authctxt = ctx;
@@ -113,4 +114,12 @@ KbdintDevice bsdauth_device = {
bsdauth_respond,
bsdauth_free_ctx
};
+
+KbdintDevice mm_bsdauth_device = {
+ "bsdauth",
+ bsdauth_init_ctx,
+ mm_bsdauth_query,
+ mm_bsdauth_respond,
+ bsdauth_free_ctx
+};
#endif
diff --git a/crypto/openssh/auth-options.c b/crypto/openssh/auth-options.c
index 8df6a6d..2787d29 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.21 2002/01/29 14:32:03 markus Exp $");
+RCSID("$OpenBSD: auth-options.c,v 1.24 2002/05/13 20:44:58 markus Exp $");
#include "packet.h"
#include "xmalloc.h"
@@ -20,7 +20,10 @@ RCSID("$OpenBSD: auth-options.c,v 1.21 2002/01/29 14:32:03 markus Exp $");
#include "channels.h"
#include "auth-options.h"
#include "servconf.h"
+#include "bufaux.h"
#include "misc.h"
+#include "monitor_wrap.h"
+#include "auth.h"
/* Flags set authorized_keys flags */
int no_port_forwarding_flag = 0;
@@ -54,6 +57,7 @@ auth_clear_options(void)
forced_command = NULL;
}
channel_clear_permitted_opens();
+ auth_debug_reset();
}
/*
@@ -75,28 +79,28 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
while (*opts && *opts != ' ' && *opts != '\t') {
cp = "no-port-forwarding";
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
- packet_send_debug("Port forwarding disabled.");
+ auth_debug_add("Port forwarding disabled.");
no_port_forwarding_flag = 1;
opts += strlen(cp);
goto next_option;
}
cp = "no-agent-forwarding";
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
- packet_send_debug("Agent forwarding disabled.");
+ auth_debug_add("Agent forwarding disabled.");
no_agent_forwarding_flag = 1;
opts += strlen(cp);
goto next_option;
}
cp = "no-X11-forwarding";
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
- packet_send_debug("X11 forwarding disabled.");
+ auth_debug_add("X11 forwarding disabled.");
no_x11_forwarding_flag = 1;
opts += strlen(cp);
goto next_option;
}
cp = "no-pty";
if (strncasecmp(opts, cp, strlen(cp)) == 0) {
- packet_send_debug("Pty allocation disabled.");
+ auth_debug_add("Pty allocation disabled.");
no_pty_flag = 1;
opts += strlen(cp);
goto next_option;
@@ -119,14 +123,14 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
if (!*opts) {
debug("%.100s, line %lu: missing end quote",
file, linenum);
- packet_send_debug("%.100s, line %lu: missing end quote",
+ auth_debug_add("%.100s, line %lu: missing end quote",
file, linenum);
xfree(forced_command);
forced_command = NULL;
goto bad_option;
}
forced_command[i] = 0;
- packet_send_debug("Forced command: %.900s", forced_command);
+ auth_debug_add("Forced command: %.900s", forced_command);
opts++;
goto next_option;
}
@@ -151,13 +155,13 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
if (!*opts) {
debug("%.100s, line %lu: missing end quote",
file, linenum);
- packet_send_debug("%.100s, line %lu: missing end quote",
+ auth_debug_add("%.100s, line %lu: missing end quote",
file, linenum);
xfree(s);
goto bad_option;
}
s[i] = 0;
- packet_send_debug("Adding to environment: %.900s", s);
+ auth_debug_add("Adding to environment: %.900s", s);
debug("Adding to environment: %.900s", s);
opts++;
new_envstring = xmalloc(sizeof(struct envstring));
@@ -188,7 +192,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
if (!*opts) {
debug("%.100s, line %lu: missing end quote",
file, linenum);
- packet_send_debug("%.100s, line %lu: missing end quote",
+ auth_debug_add("%.100s, line %lu: missing end quote",
file, linenum);
xfree(patterns);
goto bad_option;
@@ -202,7 +206,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
"correct key but not from a permitted "
"host (host=%.200s, ip=%.200s).",
pw->pw_name, remote_host, remote_ip);
- packet_send_debug("Your host '%.200s' is not "
+ auth_debug_add("Your host '%.200s' is not "
"permitted to use this key for login.",
remote_host);
/* deny access */
@@ -233,7 +237,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
if (!*opts) {
debug("%.100s, line %lu: missing end quote",
file, linenum);
- packet_send_debug("%.100s, line %lu: missing end quote",
+ auth_debug_add("%.100s, line %lu: missing end quote",
file, linenum);
xfree(patterns);
goto bad_option;
@@ -244,7 +248,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
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: "
+ auth_debug_add("%.100s, line %lu: "
"Bad permitopen specification", file, linenum);
xfree(patterns);
goto bad_option;
@@ -252,7 +256,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
if ((port = a2port(sport)) == 0) {
debug("%.100s, line %lu: Bad permitopen port <%.100s>",
file, linenum, sport);
- packet_send_debug("%.100s, line %lu: "
+ auth_debug_add("%.100s, line %lu: "
"Bad permitopen port", file, linenum);
xfree(patterns);
goto bad_option;
@@ -276,14 +280,22 @@ next_option:
opts++;
/* Process the next option. */
}
+
+ if (!use_privsep)
+ auth_debug_send();
+
/* grant access */
return 1;
bad_option:
log("Bad options in %.100s file, line %lu: %.50s",
file, linenum, opts);
- packet_send_debug("Bad options in %.100s file, line %lu: %.50s",
+ auth_debug_add("Bad options in %.100s file, line %lu: %.50s",
file, linenum, opts);
+
+ if (!use_privsep)
+ auth_debug_send();
+
/* deny access */
return 0;
}
diff --git a/crypto/openssh/auth-rhosts.c b/crypto/openssh/auth-rhosts.c
index bd15261..afca1f7 100644
--- a/crypto/openssh/auth-rhosts.c
+++ b/crypto/openssh/auth-rhosts.c
@@ -14,7 +14,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: auth-rhosts.c,v 1.27 2002/03/04 12:43:06 markus Exp $");
+RCSID("$OpenBSD: auth-rhosts.c,v 1.28 2002/05/13 21:26:49 markus Exp $");
#include "packet.h"
#include "uidswap.h"
@@ -26,6 +26,7 @@ RCSID("$OpenBSD: auth-rhosts.c,v 1.27 2002/03/04 12:43:06 markus Exp $");
/* import */
extern ServerOptions options;
+extern int use_privsep;
/*
* This function processes an rhosts-style file (.rhosts, .shosts, or
@@ -69,7 +70,7 @@ check_rhosts_file(const char *filename, const char *hostname,
*/
switch (sscanf(buf, "%s %s %s", hostbuf, userbuf, dummy)) {
case 0:
- packet_send_debug("Found empty line in %.100s.", filename);
+ auth_debug_add("Found empty line in %.100s.", filename);
continue;
case 1:
/* Host name only. */
@@ -79,7 +80,7 @@ check_rhosts_file(const char *filename, const char *hostname,
/* Got both host and user name. */
break;
case 3:
- packet_send_debug("Found garbage in %.100s.", filename);
+ auth_debug_add("Found garbage in %.100s.", filename);
continue;
default:
/* Weird... */
@@ -106,8 +107,8 @@ check_rhosts_file(const char *filename, const char *hostname,
/* Check for empty host/user names (particularly '+'). */
if (!host[0] || !user[0]) {
/* We come here if either was '+' or '-'. */
- packet_send_debug("Ignoring wild host/user names in %.100s.",
- filename);
+ auth_debug_add("Ignoring wild host/user names in %.100s.",
+ filename);
continue;
}
/* Verify that host name matches. */
@@ -130,8 +131,8 @@ check_rhosts_file(const char *filename, const char *hostname,
/* If the entry was negated, deny access. */
if (negated) {
- packet_send_debug("Matched negative entry in %.100s.",
- filename);
+ auth_debug_add("Matched negative entry in %.100s.",
+ filename);
return 0;
}
/* Accept authentication. */
@@ -153,16 +154,14 @@ int
auth_rhosts(struct passwd *pw, const char *client_user)
{
const char *hostname, *ipaddr;
- int ret;
hostname = get_canonical_hostname(options.verify_reverse_mapping);
ipaddr = get_remote_ipaddr();
- ret = auth_rhosts2(pw, client_user, hostname, ipaddr);
- return ret;
+ return auth_rhosts2(pw, client_user, hostname, ipaddr);
}
-int
-auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
+static int
+auth_rhosts2_raw(struct passwd *pw, const char *client_user, const char *hostname,
const char *ipaddr)
{
char buf[1024];
@@ -205,13 +204,13 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
if (pw->pw_uid != 0) {
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.",
+ auth_debug_add("Accepted for %.100s [%.100s] by /etc/hosts.equiv.",
hostname, ipaddr);
return 1;
}
if (check_rhosts_file(_PATH_SSH_HOSTS_EQUIV, hostname, ipaddr,
client_user, pw->pw_name)) {
- packet_send_debug("Accepted for %.100s [%.100s] by %.100s.",
+ auth_debug_add("Accepted for %.100s [%.100s] by %.100s.",
hostname, ipaddr, _PATH_SSH_HOSTS_EQUIV);
return 1;
}
@@ -221,19 +220,19 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
* not group or world writable.
*/
if (stat(pw->pw_dir, &st) < 0) {
- log("Rhosts authentication refused for %.100s: no home directory %.200s",
- pw->pw_name, pw->pw_dir);
- packet_send_debug("Rhosts authentication refused for %.100s: no home directory %.200s",
- pw->pw_name, pw->pw_dir);
+ log("Rhosts authentication refused for %.100s: "
+ "no home directory %.200s", pw->pw_name, pw->pw_dir);
+ auth_debug_add("Rhosts authentication refused for %.100s: "
+ "no home directory %.200s", pw->pw_name, pw->pw_dir);
return 0;
}
if (options.strict_modes &&
((st.st_uid != 0 && st.st_uid != pw->pw_uid) ||
(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.",
- pw->pw_name);
+ log("Rhosts authentication refused for %.100s: "
+ "bad ownership or modes for home directory.", pw->pw_name);
+ auth_debug_add("Rhosts authentication refused for %.100s: "
+ "bad ownership or modes for home directory.", pw->pw_name);
return 0;
}
/* Temporarily use the user's uid. */
@@ -259,21 +258,23 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
(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);
+ auth_debug_add("Bad file modes for %.200s", buf);
continue;
}
/* Check if we have been configured to ignore .rhosts and .shosts files. */
if (options.ignore_rhosts) {
- packet_send_debug("Server has been configured to ignore %.100s.",
- rhosts_files[rhosts_file_index]);
+ auth_debug_add("Server has been configured to ignore %.100s.",
+ rhosts_files[rhosts_file_index]);
continue;
}
/* Check if authentication is permitted by the file. */
if (check_rhosts_file(buf, hostname, ipaddr, client_user, pw->pw_name)) {
- packet_send_debug("Accepted by %.100s.",
- rhosts_files[rhosts_file_index]);
+ auth_debug_add("Accepted by %.100s.",
+ rhosts_files[rhosts_file_index]);
/* Restore the privileged uid. */
restore_uid();
+ auth_debug_add("Accepted host %s ip %s client_user %s server_user %s",
+ hostname, ipaddr, client_user, pw->pw_name);
return 1;
}
}
@@ -282,3 +283,16 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
restore_uid();
return 0;
}
+
+int
+auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
+ const char *ipaddr)
+{
+ int ret;
+
+ auth_debug_reset();
+ ret = auth_rhosts2_raw(pw, client_user, hostname, ipaddr);
+ if (!use_privsep)
+ auth_debug_send();
+ return ret;
+}
diff --git a/crypto/openssh/auth2-hostbased.c b/crypto/openssh/auth2-hostbased.c
new file mode 100644
index 0000000..2bde7bb
--- /dev/null
+++ b/crypto/openssh/auth2-hostbased.c
@@ -0,0 +1,182 @@
+/*
+ * 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.
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: auth2-hostbased.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
+
+#include "ssh2.h"
+#include "xmalloc.h"
+#include "packet.h"
+#include "buffer.h"
+#include "log.h"
+#include "servconf.h"
+#include "compat.h"
+#include "bufaux.h"
+#include "auth.h"
+#include "key.h"
+#include "canohost.h"
+#include "monitor_wrap.h"
+#include "pathnames.h"
+
+/* import */
+extern ServerOptions options;
+extern u_char *session_id2;
+extern int session_id2_len;
+
+static int
+userauth_hostbased(Authctxt *authctxt)
+{
+ Buffer b;
+ Key *key = NULL;
+ char *pkalg, *cuser, *chost, *service;
+ u_char *pkblob, *sig;
+ u_int alen, blen, slen;
+ int pktype;
+ int authenticated = 0;
+
+ if (!authctxt->valid) {
+ debug2("userauth_hostbased: disabled because of invalid user");
+ return 0;
+ }
+ pkalg = packet_get_string(&alen);
+ pkblob = packet_get_string(&blen);
+ chost = packet_get_string(NULL);
+ cuser = packet_get_string(NULL);
+ sig = packet_get_string(&slen);
+
+ debug("userauth_hostbased: cuser %s chost %s pkalg %s slen %d",
+ cuser, chost, pkalg, slen);
+#ifdef DEBUG_PK
+ debug("signature:");
+ buffer_init(&b);
+ buffer_append(&b, sig, slen);
+ buffer_dump(&b);
+ buffer_free(&b);
+#endif
+ pktype = key_type_from_name(pkalg);
+ if (pktype == KEY_UNSPEC) {
+ /* this is perfectly legal */
+ log("userauth_hostbased: unsupported "
+ "public key algorithm: %s", pkalg);
+ goto done;
+ }
+ key = key_from_blob(pkblob, blen);
+ if (key == NULL) {
+ error("userauth_hostbased: cannot decode key: %s", pkalg);
+ goto done;
+ }
+ if (key->type != pktype) {
+ error("userauth_hostbased: type mismatch for decoded key "
+ "(received %d, expected %d)", key->type, pktype);
+ goto done;
+ }
+ service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
+ authctxt->service;
+ buffer_init(&b);
+ buffer_put_string(&b, session_id2, session_id2_len);
+ /* reconstruct packet */
+ buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
+ buffer_put_cstring(&b, authctxt->user);
+ buffer_put_cstring(&b, service);
+ buffer_put_cstring(&b, "hostbased");
+ buffer_put_string(&b, pkalg, alen);
+ buffer_put_string(&b, pkblob, blen);
+ buffer_put_cstring(&b, chost);
+ buffer_put_cstring(&b, cuser);
+#ifdef DEBUG_PK
+ buffer_dump(&b);
+#endif
+ /* test for allowed key and correct signature */
+ authenticated = 0;
+ if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
+ PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
+ buffer_len(&b))) == 1)
+ authenticated = 1;
+
+ buffer_clear(&b);
+done:
+ debug2("userauth_hostbased: authenticated %d", authenticated);
+ if (key != NULL)
+ key_free(key);
+ xfree(pkalg);
+ xfree(pkblob);
+ xfree(cuser);
+ xfree(chost);
+ xfree(sig);
+ return authenticated;
+}
+
+/* return 1 if given hostkey is allowed */
+int
+hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
+ Key *key)
+{
+ const char *resolvedname, *ipaddr, *lookup;
+ HostStatus host_status;
+ int len;
+
+ resolvedname = get_canonical_hostname(options.verify_reverse_mapping);
+ ipaddr = get_remote_ipaddr();
+
+ debug2("userauth_hostbased: chost %s resolvedname %s ipaddr %s",
+ chost, resolvedname, ipaddr);
+
+ if (options.hostbased_uses_name_from_packet_only) {
+ if (auth_rhosts2(pw, cuser, chost, chost) == 0)
+ return 0;
+ lookup = chost;
+ } else {
+ if (((len = strlen(chost)) > 0) && chost[len - 1] == '.') {
+ debug2("stripping trailing dot from chost %s", chost);
+ chost[len - 1] = '\0';
+ }
+ if (strcasecmp(resolvedname, chost) != 0)
+ log("userauth_hostbased mismatch: "
+ "client sends %s, but we resolve %s to %s",
+ chost, ipaddr, resolvedname);
+ if (auth_rhosts2(pw, cuser, resolvedname, ipaddr) == 0)
+ return 0;
+ lookup = resolvedname;
+ }
+ debug2("userauth_hostbased: access allowed by auth_rhosts2");
+
+ host_status = check_key_in_hostfiles(pw, key, lookup,
+ _PATH_SSH_SYSTEM_HOSTFILE,
+ options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE);
+
+ /* backward compat if no key has been found. */
+ if (host_status == HOST_NEW)
+ host_status = check_key_in_hostfiles(pw, key, lookup,
+ _PATH_SSH_SYSTEM_HOSTFILE2,
+ options.ignore_user_known_hosts ? NULL :
+ _PATH_SSH_USER_HOSTFILE2);
+
+ return (host_status == HOST_OK);
+}
+
+Authmethod method_hostbased = {
+ "hostbased",
+ userauth_hostbased,
+ &options.hostbased_authentication
+};
diff --git a/crypto/openssh/auth2-kbdint.c b/crypto/openssh/auth2-kbdint.c
new file mode 100644
index 0000000..cae051e
--- /dev/null
+++ b/crypto/openssh/auth2-kbdint.c
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: auth2-kbdint.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
+
+#include "packet.h"
+#include "auth.h"
+#include "log.h"
+#include "servconf.h"
+#include "xmalloc.h"
+
+/* import */
+extern ServerOptions options;
+
+static int
+userauth_kbdint(Authctxt *authctxt)
+{
+ int authenticated = 0;
+ char *lang, *devs;
+
+ lang = packet_get_string(NULL);
+ devs = packet_get_string(NULL);
+ packet_check_eom();
+
+ debug("keyboard-interactive devs %s", devs);
+
+ if (options.challenge_response_authentication)
+ authenticated = auth2_challenge(authctxt, devs);
+
+ xfree(devs);
+ xfree(lang);
+ return authenticated;
+}
+
+Authmethod method_kbdint = {
+ "keyboard-interactive",
+ userauth_kbdint,
+ &options.kbd_interactive_authentication
+};
diff --git a/crypto/openssh/auth2-none.c b/crypto/openssh/auth2-none.c
new file mode 100644
index 0000000..0afbc4f
--- /dev/null
+++ b/crypto/openssh/auth2-none.c
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: auth2-none.c,v 1.3 2002/06/19 00:27:55 deraadt Exp $");
+
+#include "auth.h"
+#include "xmalloc.h"
+#include "packet.h"
+#include "log.h"
+#include "servconf.h"
+#include "atomicio.h"
+#include "compat.h"
+#include "ssh2.h"
+#include "monitor_wrap.h"
+
+/* import */
+extern ServerOptions options;
+
+/* "none" is allowed only one time */
+static int none_enabled = 1;
+
+char *
+auth2_read_banner(void)
+{
+ struct stat st;
+ char *banner = NULL;
+ off_t len, n;
+ int fd;
+
+ if ((fd = open(options.banner, O_RDONLY)) == -1)
+ return (NULL);
+ if (fstat(fd, &st) == -1) {
+ close(fd);
+ return (NULL);
+ }
+ len = st.st_size;
+ banner = xmalloc(len + 1);
+ n = atomicio(read, fd, banner, len);
+ close(fd);
+
+ if (n != len) {
+ free(banner);
+ return (NULL);
+ }
+ banner[n] = '\0';
+
+ return (banner);
+}
+
+static void
+userauth_banner(void)
+{
+ char *banner = NULL;
+
+ if (options.banner == NULL || (datafellows & SSH_BUG_BANNER))
+ return;
+
+ if ((banner = PRIVSEP(auth2_read_banner())) == NULL)
+ goto done;
+
+ packet_start(SSH2_MSG_USERAUTH_BANNER);
+ packet_put_cstring(banner);
+ packet_put_cstring(""); /* language, unused */
+ packet_send();
+ debug("userauth_banner: sent");
+done:
+ if (banner)
+ xfree(banner);
+}
+
+static int
+userauth_none(Authctxt *authctxt)
+{
+ none_enabled = 0;
+ packet_check_eom();
+ userauth_banner();
+ return (authctxt->valid ? PRIVSEP(auth_password(authctxt, "")) : 0);
+}
+
+Authmethod method_none = {
+ "none",
+ userauth_none,
+ &none_enabled
+};
diff --git a/crypto/openssh/auth2-passwd.c b/crypto/openssh/auth2-passwd.c
new file mode 100644
index 0000000..bfd7aeb
--- /dev/null
+++ b/crypto/openssh/auth2-passwd.c
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: auth2-passwd.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
+
+#include "xmalloc.h"
+#include "packet.h"
+#include "log.h"
+#include "auth.h"
+#include "monitor_wrap.h"
+#include "servconf.h"
+
+/* import */
+extern ServerOptions options;
+
+static int
+userauth_passwd(Authctxt *authctxt)
+{
+ char *password;
+ int authenticated = 0;
+ int change;
+ u_int len;
+ change = packet_get_char();
+ if (change)
+ log("password change not supported");
+ password = packet_get_string(&len);
+ packet_check_eom();
+ if (authctxt->valid &&
+ PRIVSEP(auth_password(authctxt, password)) == 1)
+ authenticated = 1;
+ memset(password, 0, len);
+ xfree(password);
+ return authenticated;
+}
+
+Authmethod method_passwd = {
+ "password",
+ userauth_passwd,
+ &options.password_authentication
+};
diff --git a/crypto/openssh/auth2-pubkey.c b/crypto/openssh/auth2-pubkey.c
new file mode 100644
index 0000000..3d164ea
--- /dev/null
+++ b/crypto/openssh/auth2-pubkey.c
@@ -0,0 +1,279 @@
+/*
+ * 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.
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: auth2-pubkey.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
+
+#include "ssh2.h"
+#include "xmalloc.h"
+#include "packet.h"
+#include "buffer.h"
+#include "log.h"
+#include "servconf.h"
+#include "compat.h"
+#include "bufaux.h"
+#include "auth.h"
+#include "key.h"
+#include "pathnames.h"
+#include "uidswap.h"
+#include "auth-options.h"
+#include "canohost.h"
+#include "monitor_wrap.h"
+
+/* import */
+extern ServerOptions options;
+extern u_char *session_id2;
+extern int session_id2_len;
+
+static int
+userauth_pubkey(Authctxt *authctxt)
+{
+ Buffer b;
+ Key *key = NULL;
+ char *pkalg;
+ u_char *pkblob, *sig;
+ u_int alen, blen, slen;
+ int have_sig, pktype;
+ int authenticated = 0;
+
+ if (!authctxt->valid) {
+ debug2("userauth_pubkey: disabled because of invalid user");
+ return 0;
+ }
+ have_sig = packet_get_char();
+ if (datafellows & SSH_BUG_PKAUTH) {
+ debug2("userauth_pubkey: SSH_BUG_PKAUTH");
+ /* no explicit pkalg given */
+ pkblob = packet_get_string(&blen);
+ buffer_init(&b);
+ buffer_append(&b, pkblob, blen);
+ /* so we have to extract the pkalg from the pkblob */
+ pkalg = buffer_get_string(&b, &alen);
+ buffer_free(&b);
+ } else {
+ pkalg = packet_get_string(&alen);
+ pkblob = packet_get_string(&blen);
+ }
+ pktype = key_type_from_name(pkalg);
+ if (pktype == KEY_UNSPEC) {
+ /* this is perfectly legal */
+ log("userauth_pubkey: unsupported public key algorithm: %s",
+ pkalg);
+ goto done;
+ }
+ key = key_from_blob(pkblob, blen);
+ if (key == NULL) {
+ error("userauth_pubkey: cannot decode key: %s", pkalg);
+ goto done;
+ }
+ if (key->type != pktype) {
+ error("userauth_pubkey: type mismatch for decoded key "
+ "(received %d, expected %d)", key->type, pktype);
+ goto done;
+ }
+ if (have_sig) {
+ sig = packet_get_string(&slen);
+ packet_check_eom();
+ buffer_init(&b);
+ if (datafellows & SSH_OLD_SESSIONID) {
+ buffer_append(&b, session_id2, session_id2_len);
+ } else {
+ buffer_put_string(&b, session_id2, session_id2_len);
+ }
+ /* reconstruct packet */
+ buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
+ buffer_put_cstring(&b, authctxt->user);
+ buffer_put_cstring(&b,
+ datafellows & SSH_BUG_PKSERVICE ?
+ "ssh-userauth" :
+ authctxt->service);
+ if (datafellows & SSH_BUG_PKAUTH) {
+ buffer_put_char(&b, have_sig);
+ } else {
+ buffer_put_cstring(&b, "publickey");
+ buffer_put_char(&b, have_sig);
+ buffer_put_cstring(&b, pkalg);
+ }
+ buffer_put_string(&b, pkblob, blen);
+#ifdef DEBUG_PK
+ buffer_dump(&b);
+#endif
+ /* test for correct signature */
+ authenticated = 0;
+ if (PRIVSEP(user_key_allowed(authctxt->pw, key)) &&
+ PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
+ buffer_len(&b))) == 1)
+ authenticated = 1;
+ buffer_clear(&b);
+ xfree(sig);
+ } else {
+ debug("test whether pkalg/pkblob are acceptable");
+ packet_check_eom();
+
+ /* XXX fake reply and always send PK_OK ? */
+ /*
+ * XXX this allows testing whether a user is allowed
+ * to login: if you happen to have a valid pubkey this
+ * message is sent. the message is NEVER sent at all
+ * if a user is not allowed to login. is this an
+ * issue? -markus
+ */
+ if (PRIVSEP(user_key_allowed(authctxt->pw, key))) {
+ packet_start(SSH2_MSG_USERAUTH_PK_OK);
+ packet_put_string(pkalg, alen);
+ packet_put_string(pkblob, blen);
+ packet_send();
+ packet_write_wait();
+ authctxt->postponed = 1;
+ }
+ }
+ if (authenticated != 1)
+ auth_clear_options();
+done:
+ debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg);
+ if (key != NULL)
+ key_free(key);
+ xfree(pkalg);
+ xfree(pkblob);
+ return authenticated;
+}
+
+/* return 1 if user allows given key */
+static int
+user_key_allowed2(struct passwd *pw, Key *key, char *file)
+{
+ char line[8192];
+ int found_key = 0;
+ FILE *f;
+ u_long linenum = 0;
+ struct stat st;
+ Key *found;
+ char *fp;
+
+ if (pw == NULL)
+ return 0;
+
+ /* Temporarily use the user's uid. */
+ temporarily_use_uid(pw);
+
+ debug("trying public key file %s", file);
+
+ /* Fail quietly if file does not exist */
+ if (stat(file, &st) < 0) {
+ /* Restore the privileged uid. */
+ restore_uid();
+ return 0;
+ }
+ /* Open the file containing the authorized keys. */
+ f = fopen(file, "r");
+ if (!f) {
+ /* Restore the privileged uid. */
+ restore_uid();
+ return 0;
+ }
+ if (options.strict_modes &&
+ secure_filename(f, file, pw, line, sizeof(line)) != 0) {
+ fclose(f);
+ log("Authentication refused: %s", line);
+ restore_uid();
+ return 0;
+ }
+
+ found_key = 0;
+ found = key_new(key->type);
+
+ while (fgets(line, sizeof(line), f)) {
+ char *cp, *options = NULL;
+ linenum++;
+ /* Skip leading whitespace, empty and comment lines. */
+ for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
+ ;
+ if (!*cp || *cp == '\n' || *cp == '#')
+ continue;
+
+ if (key_read(found, &cp) != 1) {
+ /* no key? check if there are options for this key */
+ int quoted = 0;
+ debug2("user_key_allowed: check options: '%s'", cp);
+ options = cp;
+ for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
+ if (*cp == '\\' && cp[1] == '"')
+ cp++; /* Skip both */
+ else if (*cp == '"')
+ quoted = !quoted;
+ }
+ /* Skip remaining whitespace. */
+ for (; *cp == ' ' || *cp == '\t'; cp++)
+ ;
+ if (key_read(found, &cp) != 1) {
+ debug2("user_key_allowed: advance: '%s'", cp);
+ /* still no key? advance to next line*/
+ continue;
+ }
+ }
+ if (key_equal(found, key) &&
+ auth_parse_options(pw, options, file, linenum) == 1) {
+ found_key = 1;
+ debug("matching key found: file %s, line %lu",
+ file, linenum);
+ fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
+ verbose("Found matching %s key: %s",
+ key_type(found), fp);
+ xfree(fp);
+ break;
+ }
+ }
+ restore_uid();
+ fclose(f);
+ key_free(found);
+ if (!found_key)
+ debug2("key not found");
+ return found_key;
+}
+
+/* check whether given key is in .ssh/authorized_keys* */
+int
+user_key_allowed(struct passwd *pw, Key *key)
+{
+ int success;
+ char *file;
+
+ file = authorized_keys_file(pw);
+ success = user_key_allowed2(pw, key, file);
+ xfree(file);
+ if (success)
+ return success;
+
+ /* try suffix "2" for backward compat, too */
+ file = authorized_keys_file2(pw);
+ success = user_key_allowed2(pw, key, file);
+ xfree(file);
+ return success;
+}
+
+Authmethod method_pubkey = {
+ "publickey",
+ userauth_pubkey,
+ &options.pubkey_authentication
+};
diff --git a/crypto/openssh/authfd.h b/crypto/openssh/authfd.h
index 0f2ca7a..b2767e5 100644
--- a/crypto/openssh/authfd.h
+++ b/crypto/openssh/authfd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfd.h,v 1.23 2002/03/04 17:27:39 stevesk Exp $ */
+/* $OpenBSD: authfd.h,v 1.30 2002/06/19 00:27:55 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -40,34 +40,46 @@
/* smartcard */
#define SSH_AGENTC_ADD_SMARTCARD_KEY 20
-#define SSH_AGENTC_REMOVE_SMARTCARD_KEY 21
+#define SSH_AGENTC_REMOVE_SMARTCARD_KEY 21
+
+/* lock/unlock the agent */
+#define SSH_AGENTC_LOCK 22
+#define SSH_AGENTC_UNLOCK 23
+
+/* add key with constraints */
+#define SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24
+#define SSH2_AGENTC_ADD_ID_CONSTRAINED 25
+
+#define SSH_AGENT_CONSTRAIN_LIFETIME 1
/* 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;
+ int fd;
+ Buffer identities;
+ int howmany;
+} AuthenticationConnection;
-int ssh_get_authentication_socket(void);
-void ssh_close_authentication_socket(int);
+int ssh_get_authentication_socket(void);
+void ssh_close_authentication_socket(int);
AuthenticationConnection *ssh_get_authentication_connection(void);
-void ssh_close_authentication_connection(AuthenticationConnection *);
+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_add_identity_constrained(AuthenticationConnection *, Key *, const char *, u_int);
int ssh_remove_identity(AuthenticationConnection *, Key *);
int ssh_remove_all_identities(AuthenticationConnection *, int);
-int ssh_update_card(AuthenticationConnection *, int, const char *);
+int ssh_lock_agent(AuthenticationConnection *, int, const char *);
+int ssh_update_card(AuthenticationConnection *, int, const char *, const char *);
int
ssh_decrypt_challenge(AuthenticationConnection *, Key *, BIGNUM *, u_char[16],
diff --git a/crypto/openssh/authfile.h b/crypto/openssh/authfile.h
index c614ca1..7f92701 100644
--- a/crypto/openssh/authfile.h
+++ b/crypto/openssh/authfile.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: authfile.h,v 1.9 2002/03/04 17:27:39 stevesk Exp $ */
+/* $OpenBSD: authfile.h,v 1.10 2002/05/23 19:24:30 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -20,5 +20,6 @@ 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 **);
+Key *key_load_private_pem(int, int, const char *, char **);
#endif
diff --git a/crypto/openssh/bufaux.h b/crypto/openssh/bufaux.h
index fda41ca..9355535 100644
--- a/crypto/openssh/bufaux.h
+++ b/crypto/openssh/bufaux.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bufaux.h,v 1.16 2002/03/04 17:27:39 stevesk Exp $ */
+/* $OpenBSD: bufaux.h,v 1.18 2002/04/20 09:14:58 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -23,6 +23,9 @@ void buffer_put_bignum2(Buffer *, BIGNUM *);
void buffer_get_bignum(Buffer *, BIGNUM *);
void buffer_get_bignum2(Buffer *, BIGNUM *);
+u_short buffer_get_short(Buffer *);
+void buffer_put_short(Buffer *, u_short);
+
u_int buffer_get_int(Buffer *);
void buffer_put_int(Buffer *, u_int);
@@ -36,4 +39,7 @@ void *buffer_get_string(Buffer *, u_int *);
void buffer_put_string(Buffer *, const void *, u_int);
void buffer_put_cstring(Buffer *, const char *);
+#define buffer_skip_string(b) \
+ do { u_int l = buffer_get_int(b); buffer_consume(b, l); } while(0)
+
#endif /* BUFAUX_H */
diff --git a/crypto/openssh/clientloop.c b/crypto/openssh/clientloop.c
index 65a6682..75d24ac 100644
--- a/crypto/openssh/clientloop.c
+++ b/crypto/openssh/clientloop.c
@@ -59,7 +59,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: clientloop.c,v 1.96 2002/02/06 14:55:15 markus Exp $");
+RCSID("$OpenBSD: clientloop.c,v 1.101 2002/06/09 13:32:01 markus Exp $");
#include "ssh.h"
#include "ssh1.h"
@@ -81,6 +81,7 @@ RCSID("$OpenBSD: clientloop.c,v 1.96 2002/02/06 14:55:15 markus Exp $");
#include "atomicio.h"
#include "sshtty.h"
#include "misc.h"
+#include "readpass.h"
/* import options */
extern Options options;
@@ -470,6 +471,67 @@ client_process_net_input(fd_set * readset)
}
}
+static void
+process_cmdline(void)
+{
+ void (*handler)(int);
+ char *s, *cmd;
+ u_short fwd_port, fwd_host_port;
+ char buf[1024], sfwd_port[6], sfwd_host_port[6];
+ int local = 0;
+
+ leave_raw_mode();
+ handler = signal(SIGINT, SIG_IGN);
+ cmd = s = read_passphrase("\r\nssh> ", RP_ECHO);
+ if (s == NULL)
+ goto out;
+ while (*s && isspace(*s))
+ s++;
+ if (*s == 0)
+ goto out;
+ if (strlen(s) < 2 || s[0] != '-' || !(s[1] == 'L' || s[1] == 'R')) {
+ log("Invalid command.");
+ goto out;
+ }
+ if (s[1] == 'L')
+ local = 1;
+ if (!local && !compat20) {
+ log("Not supported for SSH protocol version 1.");
+ goto out;
+ }
+ s += 2;
+ while (*s && isspace(*s))
+ s++;
+
+ if (sscanf(s, "%5[0-9]:%255[^:]:%5[0-9]",
+ sfwd_port, buf, sfwd_host_port) != 3 &&
+ sscanf(s, "%5[0-9]/%255[^/]/%5[0-9]",
+ sfwd_port, buf, sfwd_host_port) != 3) {
+ log("Bad forwarding specification.");
+ goto out;
+ }
+ if ((fwd_port = a2port(sfwd_port)) == 0 ||
+ (fwd_host_port = a2port(sfwd_host_port)) == 0) {
+ log("Bad forwarding port(s).");
+ goto out;
+ }
+ if (local) {
+ if (channel_setup_local_fwd_listener(fwd_port, buf,
+ fwd_host_port, options.gateway_ports) < 0) {
+ log("Port forwarding failed.");
+ goto out;
+ }
+ } else
+ channel_request_remote_forwarding(fwd_port, buf,
+ fwd_host_port);
+ log("Forwarding port.");
+out:
+ signal(SIGINT, handler);
+ enter_raw_mode();
+ if (cmd)
+ xfree(cmd);
+}
+
/* process the characters one by one */
static int
process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len)
@@ -574,6 +636,7 @@ process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len)
"%c?\r\n\
Supported escape sequences:\r\n\
~. - terminate connection\r\n\
+~C - open a command line\r\n\
~R - Request rekey (SSH protocol 2 only)\r\n\
~^Z - suspend ssh\r\n\
~# - list forwarded connections\r\n\
@@ -593,6 +656,10 @@ Supported escape sequences:\r\n\
xfree(s);
continue;
+ case 'C':
+ process_cmdline();
+ continue;
+
default:
if (ch != escape_char) {
buffer_put_char(bin, escape_char);
@@ -1247,6 +1314,7 @@ static void
client_init_dispatch_20(void)
{
dispatch_init(&dispatch_protocol_error);
+
dispatch_set(SSH2_MSG_CHANNEL_CLOSE, &channel_input_oclose);
dispatch_set(SSH2_MSG_CHANNEL_DATA, &channel_input_data);
dispatch_set(SSH2_MSG_CHANNEL_EOF, &channel_input_ieof);
@@ -1260,6 +1328,10 @@ client_init_dispatch_20(void)
/* rekeying */
dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
+
+ /* global request reply messages */
+ dispatch_set(SSH2_MSG_REQUEST_FAILURE, &client_global_request_reply);
+ dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &client_global_request_reply);
}
static void
client_init_dispatch_13(void)
diff --git a/crypto/openssh/clientloop.h b/crypto/openssh/clientloop.h
index 1bc9a95..8056a40 100644
--- a/crypto/openssh/clientloop.h
+++ b/crypto/openssh/clientloop.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: clientloop.h,v 1.6 2001/06/26 17:27:23 markus Exp $ */
+/* $OpenBSD: clientloop.h,v 1.7 2002/04/22 21:04:52 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -37,3 +37,4 @@
/* Client side main loop for the interactive session. */
int client_loop(int, int, int);
+void client_global_request_reply(int type, u_int32_t seq, void *ctxt);
diff --git a/crypto/openssh/compress.c b/crypto/openssh/compress.c
index 3badbf4..85a361d 100644
--- a/crypto/openssh/compress.c
+++ b/crypto/openssh/compress.c
@@ -12,17 +12,19 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: compress.c,v 1.17 2001/12/29 21:56:01 stevesk Exp $");
+RCSID("$OpenBSD: compress.c,v 1.19 2002/03/18 17:31:54 provos Exp $");
#include "log.h"
#include "buffer.h"
#include "zlib.h"
#include "compress.h"
-static z_stream incoming_stream;
-static z_stream outgoing_stream;
+z_stream incoming_stream;
+z_stream outgoing_stream;
static int compress_init_send_called = 0;
static int compress_init_recv_called = 0;
+static int inflate_failed = 0;
+static int deflate_failed = 0;
/*
* Initializes compression; level is compression level from 1 to 9
@@ -62,9 +64,9 @@ buffer_compress_uninit(void)
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)
+ if (compress_init_recv_called == 1 && inflate_failed == 0)
inflateEnd(&incoming_stream);
- if (compress_init_send_called == 1)
+ if (compress_init_send_called == 1 && deflate_failed == 0)
deflateEnd(&outgoing_stream);
}
@@ -106,6 +108,7 @@ buffer_compress(Buffer * input_buffer, Buffer * output_buffer)
sizeof(buf) - outgoing_stream.avail_out);
break;
default:
+ deflate_failed = 1;
fatal("buffer_compress: deflate returned %d", status);
/* NOTREACHED */
}
@@ -149,6 +152,7 @@ buffer_uncompress(Buffer * input_buffer, Buffer * output_buffer)
*/
return;
default:
+ inflate_failed = 1;
fatal("buffer_uncompress: inflate returned %d", status);
/* NOTREACHED */
}
diff --git a/crypto/openssh/kex.c b/crypto/openssh/kex.c
index bf8fd95..d079ab0 100644
--- a/crypto/openssh/kex.c
+++ b/crypto/openssh/kex.c
@@ -23,7 +23,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: kex.c,v 1.47 2002/02/28 15:46:33 markus Exp $");
+RCSID("$OpenBSD: kex.c,v 1.50 2002/05/15 15:47:49 mouring Exp $");
#include <openssl/crypto.h>
@@ -40,9 +40,15 @@ RCSID("$OpenBSD: kex.c,v 1.47 2002/02/28 15:46:33 markus Exp $");
#include "mac.h"
#include "match.h"
#include "dispatch.h"
+#include "monitor.h"
#define KEX_COOKIE_LEN 16
+/* Use privilege separation for sshd */
+int use_privsep;
+struct monitor *pmonitor;
+
+
/* prototype */
static void kex_kexinit_finish(Kex *);
static void kex_choose_conf(Kex *);
@@ -51,16 +57,15 @@ static void kex_choose_conf(Kex *);
static void
kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
{
- u_int32_t rand = 0;
int i;
buffer_clear(b);
- for (i = 0; i < KEX_COOKIE_LEN; i++) {
- if (i % 4 == 0)
- rand = arc4random();
- buffer_put_char(b, rand & 0xff);
- rand >>= 8;
- }
+ /*
+ * add a dummy cookie, the cookie will be overwritten by
+ * kex_send_kexinit(), each time a kexinit is set
+ */
+ for (i = 0; i < KEX_COOKIE_LEN; i++)
+ buffer_put_char(b, 0);
for (i = 0; i < PROPOSAL_MAX; i++)
buffer_put_cstring(b, proposal[i]);
buffer_put_char(b, 0); /* first_kex_packet_follows */
@@ -146,6 +151,10 @@ kex_finish(Kex *kex)
void
kex_send_kexinit(Kex *kex)
{
+ u_int32_t rand = 0;
+ u_char *cookie;
+ int i;
+
if (kex == NULL) {
error("kex_send_kexinit: no kex, cannot rekey");
return;
@@ -155,6 +164,17 @@ kex_send_kexinit(Kex *kex)
return;
}
kex->done = 0;
+
+ /* generate a random cookie */
+ if (buffer_len(&kex->my) < KEX_COOKIE_LEN)
+ fatal("kex_send_kexinit: kex proposal too short");
+ cookie = buffer_ptr(&kex->my);
+ for (i = 0; i < KEX_COOKIE_LEN; i++) {
+ if (i % 4 == 0)
+ rand = arc4random();
+ cookie[i] = rand;
+ rand >>= 8;
+ }
packet_start(SSH2_MSG_KEXINIT);
packet_put_raw(buffer_ptr(&kex->my), buffer_len(&kex->my));
packet_send();
diff --git a/crypto/openssh/kex.h b/crypto/openssh/kex.h
index 755bf33..12edcdc 100644
--- a/crypto/openssh/kex.h
+++ b/crypto/openssh/kex.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.h,v 1.29 2002/02/14 23:41:01 markus Exp $ */
+/* $OpenBSD: kex.h,v 1.31 2002/05/16 22:02:50 markus Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -79,7 +79,7 @@ struct Enc {
struct Mac {
char *name;
int enabled;
- EVP_MD *md;
+ const EVP_MD *md;
int mac_len;
u_char *key;
int key_len;
@@ -111,6 +111,7 @@ struct Kex {
char *server_version_string;
int (*verify_host_key)(Key *);
Key *(*load_host_key)(int);
+ int (*host_key_index)(Key *);
};
Kex *kex_setup(char *[PROPOSAL_MAX]);
diff --git a/crypto/openssh/kexdh.c b/crypto/openssh/kexdh.c
index eaf497c..1e91e25 100644
--- a/crypto/openssh/kexdh.c
+++ b/crypto/openssh/kexdh.c
@@ -23,7 +23,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: kexdh.c,v 1.17 2002/02/28 15:46:33 markus Exp $");
+RCSID("$OpenBSD: kexdh.c,v 1.18 2002/03/18 17:50:31 provos Exp $");
#include <openssl/crypto.h>
#include <openssl/bn.h>
@@ -37,6 +37,7 @@ RCSID("$OpenBSD: kexdh.c,v 1.17 2002/02/28 15:46:33 markus Exp $");
#include "packet.h"
#include "dh.h"
#include "ssh2.h"
+#include "monitor_wrap.h"
static u_char *
kex_dh_hash(
@@ -275,7 +276,7 @@ kexdh_server(Kex *kex)
/* sign H */
/* XXX hashlen depends on KEX */
- key_sign(server_host_key, &signature, &slen, hash, 20);
+ PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20));
/* destroy_sensitive_data(); */
diff --git a/crypto/openssh/kexgex.c b/crypto/openssh/kexgex.c
index 61896e6..2d4a581 100644
--- a/crypto/openssh/kexgex.c
+++ b/crypto/openssh/kexgex.c
@@ -24,7 +24,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: kexgex.c,v 1.20 2002/02/28 15:46:33 markus Exp $");
+RCSID("$OpenBSD: kexgex.c,v 1.22 2002/03/24 17:27:03 stevesk Exp $");
#include <openssl/bn.h>
@@ -38,6 +38,7 @@ RCSID("$OpenBSD: kexgex.c,v 1.20 2002/02/28 15:46:33 markus Exp $");
#include "dh.h"
#include "ssh2.h"
#include "compat.h"
+#include "monitor_wrap.h"
static u_char *
kexgex_hash(
@@ -259,7 +260,7 @@ kexgex_server(Kex *kex)
{
BIGNUM *shared_secret = NULL, *dh_client_pub = NULL;
Key *server_host_key;
- DH *dh = dh;
+ DH *dh;
u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
u_int sbloblen, klen, kout, slen;
int min = -1, max = -1, nbits = -1, type;
@@ -296,7 +297,8 @@ kexgex_server(Kex *kex)
fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d",
min, nbits, max);
- dh = choose_dh(min, nbits, max);
+ /* Contact privileged parent */
+ dh = PRIVSEP(choose_dh(min, nbits, max));
if (dh == NULL)
packet_disconnect("Protocol error: no matching DH grp found");
@@ -379,7 +381,7 @@ kexgex_server(Kex *kex)
/* sign H */
/* XXX hashlen depends on KEX */
- key_sign(server_host_key, &signature, &slen, hash, 20);
+ PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20));
/* destroy_sensitive_data(); */
@@ -390,6 +392,7 @@ kexgex_server(Kex *kex)
packet_put_bignum2(dh->pub_key); /* f */
packet_put_string(signature, slen);
packet_send();
+
xfree(signature);
xfree(server_host_key_blob);
/* have keys, free DH */
diff --git a/crypto/openssh/key.h b/crypto/openssh/key.h
index a225773..8d1fa41 100644
--- a/crypto/openssh/key.h
+++ b/crypto/openssh/key.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: key.h,v 1.18 2002/02/24 19:14:59 markus Exp $ */
+/* $OpenBSD: key.h,v 1.19 2002/03/18 17:23:31 markus Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -58,6 +58,7 @@ struct Key {
Key *key_new(int);
Key *key_new_private(int);
void key_free(Key *);
+Key *key_demote(Key *);
int key_equal(Key *, Key *);
char *key_fingerprint(Key *, enum fp_type, enum fp_rep);
char *key_type(Key *);
diff --git a/crypto/openssh/lib/Makefile b/crypto/openssh/lib/Makefile
index 369cf90..ac950a9 100644
--- a/crypto/openssh/lib/Makefile
+++ b/crypto/openssh/lib/Makefile
@@ -1,15 +1,15 @@
-# $OpenBSD: Makefile,v 1.31 2002/02/22 12:20:34 markus Exp $
+# $OpenBSD: Makefile,v 1.36 2002/06/11 15:23:29 hin Exp $
.PATH: ${.CURDIR}/..
LIB= ssh
-SRCS= authfd.c authfile.c bufaux.c buffer.c canohost.c channels.c \
+SRCS= authfd.c authfile.c bufaux.c buffer.c canohost.c channels.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 \
+ rsa.c tildexpand.c ttymodes.c xmalloc.c atomicio.c \
key.c dispatch.c kex.c mac.c uuencode.c misc.c \
rijndael.c ssh-dss.c ssh-rsa.c dh.c kexdh.c kexgex.c \
- scard.c
+ scard.c monitor_wrap.c monitor_fdpass.c msg.c
DEBUGLIBS= no
NOPROFILE= yes
@@ -20,6 +20,10 @@ install:
.include <bsd.own.mk>
+.if (${KERBEROS5:L} == "yes")
+CFLAGS+= -DKRB5 -I${DESTDIR}/usr/include/kerberosV
+.endif # KERBEROS5
+
.if (${KERBEROS:L} == "yes")
CFLAGS+= -DKRB4 -I${DESTDIR}/usr/include/kerberosIV
.if (${AFS:L} == "yes")
@@ -28,8 +32,4 @@ 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.h b/crypto/openssh/log.h
index 276ba05..1c6a21c 100644
--- a/crypto/openssh/log.h
+++ b/crypto/openssh/log.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: log.h,v 1.6 2002/02/22 12:20:34 markus Exp $ */
+/* $OpenBSD: log.h,v 1.7 2002/05/19 20:54:52 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -28,7 +28,7 @@ typedef enum {
SYSLOG_FACILITY_LOCAL5,
SYSLOG_FACILITY_LOCAL6,
SYSLOG_FACILITY_LOCAL7,
- SYSLOG_FACILITY_NOT_SET = -1,
+ SYSLOG_FACILITY_NOT_SET = -1
} SyslogFacility;
typedef enum {
@@ -40,7 +40,7 @@ typedef enum {
SYSLOG_LEVEL_DEBUG1,
SYSLOG_LEVEL_DEBUG2,
SYSLOG_LEVEL_DEBUG3,
- SYSLOG_LEVEL_NOT_SET = -1,
+ SYSLOG_LEVEL_NOT_SET = -1
} LogLevel;
void log_init(char *, LogLevel, SyslogFacility, int);
diff --git a/crypto/openssh/mac.c b/crypto/openssh/mac.c
index b250af2..ab9a03d 100644
--- a/crypto/openssh/mac.c
+++ b/crypto/openssh/mac.c
@@ -23,7 +23,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: mac.c,v 1.4 2002/01/25 22:07:40 markus Exp $");
+RCSID("$OpenBSD: mac.c,v 1.5 2002/05/16 22:02:50 markus Exp $");
#include <openssl/hmac.h>
@@ -36,7 +36,7 @@ RCSID("$OpenBSD: mac.c,v 1.4 2002/01/25 22:07:40 markus Exp $");
struct {
char *name;
- EVP_MD * (*mdfunc)(void);
+ const EVP_MD * (*mdfunc)(void);
int truncatebits; /* truncate digest if != 0 */
} macs[] = {
{ "hmac-sha1", EVP_sha1, 0, },
diff --git a/crypto/openssh/misc.h b/crypto/openssh/misc.h
index d28b865..6d2869b 100644
--- a/crypto/openssh/misc.h
+++ b/crypto/openssh/misc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.h,v 1.11 2002/01/24 21:09:25 stevesk Exp $ */
+/* $OpenBSD: misc.h,v 1.12 2002/03/19 10:49:35 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -26,8 +26,8 @@ struct passwd *pwcopy(struct passwd *);
typedef struct arglist arglist;
struct arglist {
- char **list;
- int num;
- int nalloc;
+ char **list;
+ int num;
+ int nalloc;
};
void addargs(arglist *, char *, ...) __attribute__((format(printf, 2, 3)));
diff --git a/crypto/openssh/monitor.c b/crypto/openssh/monitor.c
new file mode 100644
index 0000000..4957be9
--- /dev/null
+++ b/crypto/openssh/monitor.c
@@ -0,0 +1,1498 @@
+/*
+ * Copyright 2002 Niels Provos <provos@citi.umich.edu>
+ * Copyright 2002 Markus Friedl <markus@openbsd.org>
+ * 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: monitor.c,v 1.16 2002/06/21 05:50:51 djm Exp $");
+
+#include <openssl/dh.h>
+
+#ifdef SKEY
+#include <skey.h>
+#endif
+
+#include "ssh.h"
+#include "auth.h"
+#include "kex.h"
+#include "dh.h"
+#include "zlib.h"
+#include "packet.h"
+#include "auth-options.h"
+#include "sshpty.h"
+#include "channels.h"
+#include "session.h"
+#include "sshlogin.h"
+#include "canohost.h"
+#include "log.h"
+#include "servconf.h"
+#include "monitor.h"
+#include "monitor_mm.h"
+#include "monitor_wrap.h"
+#include "monitor_fdpass.h"
+#include "xmalloc.h"
+#include "misc.h"
+#include "buffer.h"
+#include "bufaux.h"
+#include "compat.h"
+#include "ssh2.h"
+#include "mpaux.h"
+
+/* Imports */
+extern ServerOptions options;
+extern u_int utmp_len;
+extern Newkeys *current_keys[];
+extern z_stream incoming_stream;
+extern z_stream outgoing_stream;
+extern u_char session_id[];
+extern Buffer input, output;
+extern Buffer auth_debug;
+extern int auth_debug_init;
+
+/* State exported from the child */
+
+struct {
+ z_stream incoming;
+ z_stream outgoing;
+ u_char *keyin;
+ u_int keyinlen;
+ u_char *keyout;
+ u_int keyoutlen;
+ u_char *ivin;
+ u_int ivinlen;
+ u_char *ivout;
+ u_int ivoutlen;
+ u_char *ssh1key;
+ u_int ssh1keylen;
+ int ssh1cipher;
+ int ssh1protoflags;
+ u_char *input;
+ u_int ilen;
+ u_char *output;
+ u_int olen;
+} child_state;
+
+/* Functions on the montior that answer unprivileged requests */
+
+int mm_answer_moduli(int, Buffer *);
+int mm_answer_sign(int, Buffer *);
+int mm_answer_pwnamallow(int, Buffer *);
+int mm_answer_auth2_read_banner(int, Buffer *);
+int mm_answer_authserv(int, Buffer *);
+int mm_answer_authpassword(int, Buffer *);
+int mm_answer_bsdauthquery(int, Buffer *);
+int mm_answer_bsdauthrespond(int, Buffer *);
+int mm_answer_skeyquery(int, Buffer *);
+int mm_answer_skeyrespond(int, Buffer *);
+int mm_answer_keyallowed(int, Buffer *);
+int mm_answer_keyverify(int, Buffer *);
+int mm_answer_pty(int, Buffer *);
+int mm_answer_pty_cleanup(int, Buffer *);
+int mm_answer_term(int, Buffer *);
+int mm_answer_rsa_keyallowed(int, Buffer *);
+int mm_answer_rsa_challenge(int, Buffer *);
+int mm_answer_rsa_response(int, Buffer *);
+int mm_answer_sesskey(int, Buffer *);
+int mm_answer_sessid(int, Buffer *);
+
+static Authctxt *authctxt;
+static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */
+
+/* local state for key verify */
+static u_char *key_blob = NULL;
+static u_int key_bloblen = 0;
+static int key_blobtype = MM_NOKEY;
+static u_char *hostbased_cuser = NULL;
+static u_char *hostbased_chost = NULL;
+static char *auth_method = "unknown";
+static int session_id2_len = 0;
+static u_char *session_id2 = NULL;
+
+struct mon_table {
+ enum monitor_reqtype type;
+ int flags;
+ int (*f)(int, Buffer *);
+};
+
+#define MON_ISAUTH 0x0004 /* Required for Authentication */
+#define MON_AUTHDECIDE 0x0008 /* Decides Authentication */
+#define MON_ONCE 0x0010 /* Disable after calling */
+
+#define MON_AUTH (MON_ISAUTH|MON_AUTHDECIDE)
+
+#define MON_PERMIT 0x1000 /* Request is permitted */
+
+struct mon_table mon_dispatch_proto20[] = {
+ {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli},
+ {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
+ {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
+ {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
+ {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
+ {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
+#ifdef BSD_AUTH
+ {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
+ {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond},
+#endif
+#ifdef SKEY
+ {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
+ {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond},
+#endif
+ {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed},
+ {MONITOR_REQ_KEYVERIFY, MON_AUTH, mm_answer_keyverify},
+ {0, 0, NULL}
+};
+
+struct mon_table mon_dispatch_postauth20[] = {
+ {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
+ {MONITOR_REQ_SIGN, 0, mm_answer_sign},
+ {MONITOR_REQ_PTY, 0, mm_answer_pty},
+ {MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup},
+ {MONITOR_REQ_TERM, 0, mm_answer_term},
+ {0, 0, NULL}
+};
+
+struct mon_table mon_dispatch_proto15[] = {
+ {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
+ {MONITOR_REQ_SESSKEY, MON_ONCE, mm_answer_sesskey},
+ {MONITOR_REQ_SESSID, MON_ONCE, mm_answer_sessid},
+ {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
+ {MONITOR_REQ_RSAKEYALLOWED, MON_ISAUTH, mm_answer_rsa_keyallowed},
+ {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed},
+ {MONITOR_REQ_RSACHALLENGE, MON_ONCE, mm_answer_rsa_challenge},
+ {MONITOR_REQ_RSARESPONSE, MON_ONCE|MON_AUTHDECIDE, mm_answer_rsa_response},
+#ifdef BSD_AUTH
+ {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
+ {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond},
+#endif
+#ifdef SKEY
+ {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
+ {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond},
+#endif
+ {0, 0, NULL}
+};
+
+struct mon_table mon_dispatch_postauth15[] = {
+ {MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty},
+ {MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup},
+ {MONITOR_REQ_TERM, 0, mm_answer_term},
+ {0, 0, NULL}
+};
+
+struct mon_table *mon_dispatch;
+
+/* Specifies if a certain message is allowed at the moment */
+
+static void
+monitor_permit(struct mon_table *ent, enum monitor_reqtype type, int permit)
+{
+ while (ent->f != NULL) {
+ if (ent->type == type) {
+ ent->flags &= ~MON_PERMIT;
+ ent->flags |= permit ? MON_PERMIT : 0;
+ return;
+ }
+ ent++;
+ }
+}
+
+static void
+monitor_permit_authentications(int permit)
+{
+ struct mon_table *ent = mon_dispatch;
+
+ while (ent->f != NULL) {
+ if (ent->flags & MON_AUTH) {
+ ent->flags &= ~MON_PERMIT;
+ ent->flags |= permit ? MON_PERMIT : 0;
+ }
+ ent++;
+ }
+}
+
+Authctxt *
+monitor_child_preauth(struct monitor *pmonitor)
+{
+ struct mon_table *ent;
+ int authenticated = 0;
+
+ debug3("preauth child monitor started");
+
+ if (compat20) {
+ mon_dispatch = mon_dispatch_proto20;
+
+ /* Permit requests for moduli and signatures */
+ monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
+ monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
+ } else {
+ mon_dispatch = mon_dispatch_proto15;
+
+ monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);
+ }
+
+ authctxt = authctxt_new();
+
+ /* The first few requests do not require asynchronous access */
+ while (!authenticated) {
+ authenticated = monitor_read(pmonitor, mon_dispatch, &ent);
+ if (authenticated) {
+ if (!(ent->flags & MON_AUTHDECIDE))
+ fatal("%s: unexpected authentication from %d",
+ __func__, ent->type);
+ if (authctxt->pw->pw_uid == 0 &&
+ !auth_root_allowed(auth_method))
+ authenticated = 0;
+ }
+
+ if (ent->flags & MON_AUTHDECIDE) {
+ auth_log(authctxt, authenticated, auth_method,
+ compat20 ? " ssh2" : "");
+ if (!authenticated)
+ authctxt->failures++;
+ }
+ }
+
+ if (!authctxt->valid)
+ fatal("%s: authenticated invalid user", __func__);
+
+ debug("%s: %s has been authenticated by privileged process",
+ __func__, authctxt->user);
+
+ mm_get_keystate(pmonitor);
+
+ return (authctxt);
+}
+
+void
+monitor_child_postauth(struct monitor *pmonitor)
+{
+ if (compat20) {
+ mon_dispatch = mon_dispatch_postauth20;
+
+ /* Permit requests for moduli and signatures */
+ monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
+ monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
+ monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
+
+ } else {
+ mon_dispatch = mon_dispatch_postauth15;
+ monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
+ }
+ if (!no_pty_flag) {
+ monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1);
+ monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1);
+ }
+
+ for (;;)
+ monitor_read(pmonitor, mon_dispatch, NULL);
+}
+
+void
+monitor_sync(struct monitor *pmonitor)
+{
+ if (options.compression) {
+ /* The member allocation is not visible, so sync it */
+ mm_share_sync(&pmonitor->m_zlib, &pmonitor->m_zback);
+ }
+}
+
+int
+monitor_read(struct monitor *pmonitor, struct mon_table *ent,
+ struct mon_table **pent)
+{
+ Buffer m;
+ int ret;
+ u_char type;
+
+ buffer_init(&m);
+
+ mm_request_receive(pmonitor->m_sendfd, &m);
+ type = buffer_get_char(&m);
+
+ debug3("%s: checking request %d", __func__, type);
+
+ while (ent->f != NULL) {
+ if (ent->type == type)
+ break;
+ ent++;
+ }
+
+ if (ent->f != NULL) {
+ if (!(ent->flags & MON_PERMIT))
+ fatal("%s: unpermitted request %d", __func__,
+ type);
+ ret = (*ent->f)(pmonitor->m_sendfd, &m);
+ buffer_free(&m);
+
+ /* The child may use this request only once, disable it */
+ if (ent->flags & MON_ONCE) {
+ debug2("%s: %d used once, disabling now", __func__,
+ type);
+ ent->flags &= ~MON_PERMIT;
+ }
+
+ if (pent != NULL)
+ *pent = ent;
+
+ return ret;
+ }
+
+ fatal("%s: unsupported request: %d", __func__, type);
+
+ /* NOTREACHED */
+ return (-1);
+}
+
+/* allowed key state */
+static int
+monitor_allowed_key(u_char *blob, u_int bloblen)
+{
+ /* make sure key is allowed */
+ if (key_blob == NULL || key_bloblen != bloblen ||
+ memcmp(key_blob, blob, key_bloblen))
+ return (0);
+ return (1);
+}
+
+static void
+monitor_reset_key_state(void)
+{
+ /* reset state */
+ if (key_blob != NULL)
+ xfree(key_blob);
+ if (hostbased_cuser != NULL)
+ xfree(hostbased_cuser);
+ if (hostbased_chost != NULL)
+ xfree(hostbased_chost);
+ key_blob = NULL;
+ key_bloblen = 0;
+ key_blobtype = MM_NOKEY;
+ hostbased_cuser = NULL;
+ hostbased_chost = NULL;
+}
+
+int
+mm_answer_moduli(int socket, Buffer *m)
+{
+ DH *dh;
+ int min, want, max;
+
+ min = buffer_get_int(m);
+ want = buffer_get_int(m);
+ max = buffer_get_int(m);
+
+ debug3("%s: got parameters: %d %d %d",
+ __func__, min, want, max);
+ /* We need to check here, too, in case the child got corrupted */
+ if (max < min || want < min || max < want)
+ fatal("%s: bad parameters: %d %d %d",
+ __func__, min, want, max);
+
+ buffer_clear(m);
+
+ dh = choose_dh(min, want, max);
+ if (dh == NULL) {
+ buffer_put_char(m, 0);
+ return (0);
+ } else {
+ /* Send first bignum */
+ buffer_put_char(m, 1);
+ buffer_put_bignum2(m, dh->p);
+ buffer_put_bignum2(m, dh->g);
+
+ DH_free(dh);
+ }
+ mm_request_send(socket, MONITOR_ANS_MODULI, m);
+ return (0);
+}
+
+int
+mm_answer_sign(int socket, Buffer *m)
+{
+ Key *key;
+ u_char *p;
+ u_char *signature;
+ u_int siglen, datlen;
+ int keyid;
+
+ debug3("%s", __func__);
+
+ keyid = buffer_get_int(m);
+ p = buffer_get_string(m, &datlen);
+
+ if (datlen != 20)
+ fatal("%s: data length incorrect: %d", __func__, datlen);
+
+ /* save session id, it will be passed on the first call */
+ if (session_id2_len == 0) {
+ session_id2_len = datlen;
+ session_id2 = xmalloc(session_id2_len);
+ memcpy(session_id2, p, session_id2_len);
+ }
+
+ if ((key = get_hostkey_by_index(keyid)) == NULL)
+ fatal("%s: no hostkey from index %d", __func__, keyid);
+ if (key_sign(key, &signature, &siglen, p, datlen) < 0)
+ fatal("%s: key_sign failed", __func__);
+
+ debug3("%s: signature %p(%d)", __func__, signature, siglen);
+
+ buffer_clear(m);
+ buffer_put_string(m, signature, siglen);
+
+ xfree(p);
+ xfree(signature);
+
+ mm_request_send(socket, MONITOR_ANS_SIGN, m);
+
+ /* Turn on permissions for getpwnam */
+ monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
+
+ return (0);
+}
+
+/* Retrieves the password entry and also checks if the user is permitted */
+
+int
+mm_answer_pwnamallow(int socket, Buffer *m)
+{
+ char *login;
+ struct passwd *pwent;
+ int allowed = 0;
+
+ debug3("%s", __func__);
+
+ if (authctxt->attempt++ != 0)
+ fatal("%s: multiple attempts for getpwnam", __func__);
+
+ login = buffer_get_string(m, NULL);
+
+ pwent = getpwnamallow(login);
+
+ authctxt->user = xstrdup(login);
+ setproctitle("%s [priv]", pwent ? login : "unknown");
+ xfree(login);
+
+ buffer_clear(m);
+
+ if (pwent == NULL) {
+ buffer_put_char(m, 0);
+ goto out;
+ }
+
+ allowed = 1;
+ authctxt->pw = pwent;
+ authctxt->valid = 1;
+
+ buffer_put_char(m, 1);
+ buffer_put_string(m, pwent, sizeof(struct passwd));
+ buffer_put_cstring(m, pwent->pw_name);
+ buffer_put_cstring(m, "*");
+ buffer_put_cstring(m, pwent->pw_gecos);
+ buffer_put_cstring(m, pwent->pw_class);
+ buffer_put_cstring(m, pwent->pw_dir);
+ buffer_put_cstring(m, pwent->pw_shell);
+
+ out:
+ debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed);
+ mm_request_send(socket, MONITOR_ANS_PWNAM, m);
+
+ /* For SSHv1 allow authentication now */
+ if (!compat20)
+ monitor_permit_authentications(1);
+ else {
+ /* Allow service/style information on the auth context */
+ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
+ monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
+ }
+
+
+ return (0);
+}
+
+int mm_answer_auth2_read_banner(int socket, Buffer *m)
+{
+ char *banner;
+
+ buffer_clear(m);
+ banner = auth2_read_banner();
+ buffer_put_cstring(m, banner != NULL ? banner : "");
+ mm_request_send(socket, MONITOR_ANS_AUTH2_READ_BANNER, m);
+
+ if (banner != NULL)
+ free(banner);
+
+ return (0);
+}
+
+int
+mm_answer_authserv(int socket, Buffer *m)
+{
+ monitor_permit_authentications(1);
+
+ authctxt->service = buffer_get_string(m, NULL);
+ authctxt->style = buffer_get_string(m, NULL);
+ debug3("%s: service=%s, style=%s",
+ __func__, authctxt->service, authctxt->style);
+
+ if (strlen(authctxt->style) == 0) {
+ xfree(authctxt->style);
+ authctxt->style = NULL;
+ }
+
+ return (0);
+}
+
+int
+mm_answer_authpassword(int socket, Buffer *m)
+{
+ static int call_count;
+ char *passwd;
+ int authenticated, plen;
+
+ passwd = buffer_get_string(m, &plen);
+ /* Only authenticate if the context is valid */
+ authenticated = options.password_authentication &&
+ authctxt->valid && auth_password(authctxt, passwd);
+ memset(passwd, 0, strlen(passwd));
+ xfree(passwd);
+
+ buffer_clear(m);
+ buffer_put_int(m, authenticated);
+
+ debug3("%s: sending result %d", __func__, authenticated);
+ mm_request_send(socket, MONITOR_ANS_AUTHPASSWORD, m);
+
+ call_count++;
+ if (plen == 0 && call_count == 1)
+ auth_method = "none";
+ else
+ auth_method = "password";
+
+ /* Causes monitor loop to terminate if authenticated */
+ return (authenticated);
+}
+
+#ifdef BSD_AUTH
+int
+mm_answer_bsdauthquery(int socket, Buffer *m)
+{
+ char *name, *infotxt;
+ u_int numprompts;
+ u_int *echo_on;
+ char **prompts;
+ int res;
+
+ res = bsdauth_query(authctxt, &name, &infotxt, &numprompts,
+ &prompts, &echo_on);
+
+ buffer_clear(m);
+ buffer_put_int(m, res);
+ if (res != -1)
+ buffer_put_cstring(m, prompts[0]);
+
+ debug3("%s: sending challenge res: %d", __func__, res);
+ mm_request_send(socket, MONITOR_ANS_BSDAUTHQUERY, m);
+
+ if (res != -1) {
+ xfree(name);
+ xfree(infotxt);
+ xfree(prompts);
+ xfree(echo_on);
+ }
+
+ return (0);
+}
+
+int
+mm_answer_bsdauthrespond(int socket, Buffer *m)
+{
+ char *response;
+ int authok;
+
+ if (authctxt->as == 0)
+ fatal("%s: no bsd auth session", __func__);
+
+ response = buffer_get_string(m, NULL);
+ authok = options.challenge_response_authentication &&
+ auth_userresponse(authctxt->as, response, 0);
+ authctxt->as = NULL;
+ debug3("%s: <%s> = <%d>", __func__, response, authok);
+ xfree(response);
+
+ buffer_clear(m);
+ buffer_put_int(m, authok);
+
+ debug3("%s: sending authenticated: %d", __func__, authok);
+ mm_request_send(socket, MONITOR_ANS_BSDAUTHRESPOND, m);
+
+ auth_method = "bsdauth";
+
+ return (authok != 0);
+}
+#endif
+
+#ifdef SKEY
+int
+mm_answer_skeyquery(int socket, Buffer *m)
+{
+ struct skey skey;
+ char challenge[1024];
+ int res;
+
+ res = skeychallenge(&skey, authctxt->user, challenge);
+
+ buffer_clear(m);
+ buffer_put_int(m, res);
+ if (res != -1)
+ buffer_put_cstring(m, challenge);
+
+ debug3("%s: sending challenge res: %d", __func__, res);
+ mm_request_send(socket, MONITOR_ANS_SKEYQUERY, m);
+
+ return (0);
+}
+
+int
+mm_answer_skeyrespond(int socket, Buffer *m)
+{
+ char *response;
+ int authok;
+
+ response = buffer_get_string(m, NULL);
+
+ authok = (options.challenge_response_authentication &&
+ authctxt->valid &&
+ skey_haskey(authctxt->pw->pw_name) == 0 &&
+ skey_passcheck(authctxt->pw->pw_name, response) != -1);
+
+ xfree(response);
+
+ buffer_clear(m);
+ buffer_put_int(m, authok);
+
+ debug3("%s: sending authenticated: %d", __func__, authok);
+ mm_request_send(socket, MONITOR_ANS_SKEYRESPOND, m);
+
+ auth_method = "skey";
+
+ return (authok != 0);
+}
+#endif
+
+static void
+mm_append_debug(Buffer *m)
+{
+ if (auth_debug_init && buffer_len(&auth_debug)) {
+ debug3("%s: Appending debug messages for child", __func__);
+ buffer_append(m, buffer_ptr(&auth_debug),
+ buffer_len(&auth_debug));
+ buffer_clear(&auth_debug);
+ }
+}
+
+int
+mm_answer_keyallowed(int socket, Buffer *m)
+{
+ Key *key;
+ u_char *cuser, *chost, *blob;
+ u_int bloblen;
+ enum mm_keytype type = 0;
+ int allowed = 0;
+
+ debug3("%s entering", __func__);
+
+ type = buffer_get_int(m);
+ cuser = buffer_get_string(m, NULL);
+ chost = buffer_get_string(m, NULL);
+ blob = buffer_get_string(m, &bloblen);
+
+ key = key_from_blob(blob, bloblen);
+
+ if ((compat20 && type == MM_RSAHOSTKEY) ||
+ (!compat20 && type != MM_RSAHOSTKEY))
+ fatal("%s: key type and protocol mismatch", __func__);
+
+ debug3("%s: key_from_blob: %p", __func__, key);
+
+ if (key != NULL && authctxt->pw != NULL) {
+ switch(type) {
+ case MM_USERKEY:
+ allowed = options.pubkey_authentication &&
+ user_key_allowed(authctxt->pw, key);
+ break;
+ case MM_HOSTKEY:
+ allowed = options.hostbased_authentication &&
+ hostbased_key_allowed(authctxt->pw,
+ cuser, chost, key);
+ break;
+ case MM_RSAHOSTKEY:
+ key->type = KEY_RSA1; /* XXX */
+ allowed = options.rhosts_rsa_authentication &&
+ auth_rhosts_rsa_key_allowed(authctxt->pw,
+ cuser, chost, key);
+ break;
+ default:
+ fatal("%s: unknown key type %d", __func__, type);
+ break;
+ }
+ key_free(key);
+ }
+
+ /* clear temporarily storage (used by verify) */
+ monitor_reset_key_state();
+
+ if (allowed) {
+ /* Save temporarily for comparison in verify */
+ key_blob = blob;
+ key_bloblen = bloblen;
+ key_blobtype = type;
+ hostbased_cuser = cuser;
+ hostbased_chost = chost;
+ }
+
+ debug3("%s: key %p is %s",
+ __func__, key, allowed ? "allowed" : "disallowed");
+
+ buffer_clear(m);
+ buffer_put_int(m, allowed);
+
+ mm_append_debug(m);
+
+ mm_request_send(socket, MONITOR_ANS_KEYALLOWED, m);
+
+ if (type == MM_RSAHOSTKEY)
+ monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed);
+
+ return (0);
+}
+
+static int
+monitor_valid_userblob(u_char *data, u_int datalen)
+{
+ Buffer b;
+ u_char *p;
+ u_int len;
+ int fail = 0;
+
+ buffer_init(&b);
+ buffer_append(&b, data, datalen);
+
+ if (datafellows & SSH_OLD_SESSIONID) {
+ p = buffer_ptr(&b);
+ len = buffer_len(&b);
+ if ((session_id2 == NULL) ||
+ (len < session_id2_len) ||
+ (memcmp(p, session_id2, session_id2_len) != 0))
+ fail++;
+ buffer_consume(&b, session_id2_len);
+ } else {
+ p = buffer_get_string(&b, &len);
+ if ((session_id2 == NULL) ||
+ (len != session_id2_len) ||
+ (memcmp(p, session_id2, session_id2_len) != 0))
+ fail++;
+ xfree(p);
+ }
+ if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)
+ fail++;
+ p = buffer_get_string(&b, NULL);
+ if (strcmp(authctxt->user, p) != 0) {
+ log("wrong user name passed to monitor: expected %s != %.100s",
+ authctxt->user, p);
+ fail++;
+ }
+ xfree(p);
+ buffer_skip_string(&b);
+ if (datafellows & SSH_BUG_PKAUTH) {
+ if (!buffer_get_char(&b))
+ fail++;
+ } else {
+ p = buffer_get_string(&b, NULL);
+ if (strcmp("publickey", p) != 0)
+ fail++;
+ xfree(p);
+ if (!buffer_get_char(&b))
+ fail++;
+ buffer_skip_string(&b);
+ }
+ buffer_skip_string(&b);
+ if (buffer_len(&b) != 0)
+ fail++;
+ buffer_free(&b);
+ return (fail == 0);
+}
+
+static int
+monitor_valid_hostbasedblob(u_char *data, u_int datalen, u_char *cuser,
+ u_char *chost)
+{
+ Buffer b;
+ u_char *p;
+ u_int len;
+ int fail = 0;
+
+ buffer_init(&b);
+ buffer_append(&b, data, datalen);
+
+ p = buffer_get_string(&b, &len);
+ if ((session_id2 == NULL) ||
+ (len != session_id2_len) ||
+ (memcmp(p, session_id2, session_id2_len) != 0))
+ fail++;
+ xfree(p);
+
+ if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)
+ fail++;
+ p = buffer_get_string(&b, NULL);
+ if (strcmp(authctxt->user, p) != 0) {
+ log("wrong user name passed to monitor: expected %s != %.100s",
+ authctxt->user, p);
+ fail++;
+ }
+ xfree(p);
+ buffer_skip_string(&b); /* service */
+ p = buffer_get_string(&b, NULL);
+ if (strcmp(p, "hostbased") != 0)
+ fail++;
+ xfree(p);
+ buffer_skip_string(&b); /* pkalg */
+ buffer_skip_string(&b); /* pkblob */
+
+ /* verify client host, strip trailing dot if necessary */
+ p = buffer_get_string(&b, NULL);
+ if (((len = strlen(p)) > 0) && p[len - 1] == '.')
+ p[len - 1] = '\0';
+ if (strcmp(p, chost) != 0)
+ fail++;
+ xfree(p);
+
+ /* verify client user */
+ p = buffer_get_string(&b, NULL);
+ if (strcmp(p, cuser) != 0)
+ fail++;
+ xfree(p);
+
+ if (buffer_len(&b) != 0)
+ fail++;
+ buffer_free(&b);
+ return (fail == 0);
+}
+
+int
+mm_answer_keyverify(int socket, Buffer *m)
+{
+ Key *key;
+ u_char *signature, *data, *blob;
+ u_int signaturelen, datalen, bloblen;
+ int verified = 0;
+ int valid_data = 0;
+
+ blob = buffer_get_string(m, &bloblen);
+ signature = buffer_get_string(m, &signaturelen);
+ data = buffer_get_string(m, &datalen);
+
+ if (hostbased_cuser == NULL || hostbased_chost == NULL ||
+ !monitor_allowed_key(blob, bloblen))
+ fatal("%s: bad key, not previously allowed", __func__);
+
+ key = key_from_blob(blob, bloblen);
+ if (key == NULL)
+ fatal("%s: bad public key blob", __func__);
+
+ switch (key_blobtype) {
+ case MM_USERKEY:
+ valid_data = monitor_valid_userblob(data, datalen);
+ break;
+ case MM_HOSTKEY:
+ valid_data = monitor_valid_hostbasedblob(data, datalen,
+ hostbased_cuser, hostbased_chost);
+ break;
+ default:
+ valid_data = 0;
+ break;
+ }
+ if (!valid_data)
+ fatal("%s: bad signature data blob", __func__);
+
+ verified = key_verify(key, signature, signaturelen, data, datalen);
+ debug3("%s: key %p signature %s",
+ __func__, key, verified ? "verified" : "unverified");
+
+ key_free(key);
+ xfree(blob);
+ xfree(signature);
+ xfree(data);
+
+ monitor_reset_key_state();
+
+ buffer_clear(m);
+ buffer_put_int(m, verified);
+ mm_request_send(socket, MONITOR_ANS_KEYVERIFY, m);
+
+ auth_method = key_blobtype == MM_USERKEY ? "publickey" : "hostbased";
+
+ return (verified);
+}
+
+static void
+mm_record_login(Session *s, struct passwd *pw)
+{
+ socklen_t fromlen;
+ struct sockaddr_storage from;
+
+ /*
+ * Get IP address of client. If the connection is not a socket, let
+ * the address be 0.0.0.0.
+ */
+ memset(&from, 0, sizeof(from));
+ if (packet_connection_is_on_socket()) {
+ fromlen = sizeof(from);
+ if (getpeername(packet_get_connection_in(),
+ (struct sockaddr *) & from, &fromlen) < 0) {
+ debug("getpeername: %.100s", strerror(errno));
+ fatal_cleanup();
+ }
+ }
+ /* Record that there was a login on that tty from the remote host. */
+ record_login(s->pid, s->tty, pw->pw_name, pw->pw_uid,
+ get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping),
+ (struct sockaddr *)&from);
+}
+
+static void
+mm_session_close(Session *s)
+{
+ debug3("%s: session %d pid %d", __func__, s->self, s->pid);
+ if (s->ttyfd != -1) {
+ debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd);
+ fatal_remove_cleanup(session_pty_cleanup2, (void *)s);
+ session_pty_cleanup2(s);
+ }
+ s->used = 0;
+}
+
+int
+mm_answer_pty(int socket, Buffer *m)
+{
+ extern struct monitor *pmonitor;
+ Session *s;
+ int res, fd0;
+
+ debug3("%s entering", __func__);
+
+ buffer_clear(m);
+ s = session_new();
+ if (s == NULL)
+ goto error;
+ s->authctxt = authctxt;
+ s->pw = authctxt->pw;
+ s->pid = pmonitor->m_pid;
+ res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
+ if (res == 0)
+ goto error;
+ fatal_add_cleanup(session_pty_cleanup2, (void *)s);
+ pty_setowner(authctxt->pw, s->tty);
+
+ buffer_put_int(m, 1);
+ buffer_put_cstring(m, s->tty);
+ mm_request_send(socket, MONITOR_ANS_PTY, m);
+
+ mm_send_fd(socket, s->ptyfd);
+ mm_send_fd(socket, s->ttyfd);
+
+ /* We need to trick ttyslot */
+ if (dup2(s->ttyfd, 0) == -1)
+ fatal("%s: dup2", __func__);
+
+ mm_record_login(s, authctxt->pw);
+
+ /* Now we can close the file descriptor again */
+ close(0);
+
+ /* make sure nothing uses fd 0 */
+ if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0)
+ fatal("%s: open(/dev/null): %s", __func__, strerror(errno));
+ if (fd0 != 0)
+ error("%s: fd0 %d != 0", __func__, fd0);
+
+ /* slave is not needed */
+ close(s->ttyfd);
+ s->ttyfd = s->ptyfd;
+ /* no need to dup() because nobody closes ptyfd */
+ s->ptymaster = s->ptyfd;
+
+ debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ttyfd);
+
+ return (0);
+
+ error:
+ if (s != NULL)
+ mm_session_close(s);
+ buffer_put_int(m, 0);
+ mm_request_send(socket, MONITOR_ANS_PTY, m);
+ return (0);
+}
+
+int
+mm_answer_pty_cleanup(int socket, Buffer *m)
+{
+ Session *s;
+ char *tty;
+
+ debug3("%s entering", __func__);
+
+ tty = buffer_get_string(m, NULL);
+ if ((s = session_by_tty(tty)) != NULL)
+ mm_session_close(s);
+ buffer_clear(m);
+ xfree(tty);
+ return (0);
+}
+
+int
+mm_answer_sesskey(int socket, Buffer *m)
+{
+ BIGNUM *p;
+ int rsafail;
+
+ /* Turn off permissions */
+ monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);
+
+ if ((p = BN_new()) == NULL)
+ fatal("%s: BN_new", __func__);
+
+ buffer_get_bignum2(m, p);
+
+ rsafail = ssh1_session_key(p);
+
+ buffer_clear(m);
+ buffer_put_int(m, rsafail);
+ buffer_put_bignum2(m, p);
+
+ BN_clear_free(p);
+
+ mm_request_send(socket, MONITOR_ANS_SESSKEY, m);
+
+ /* Turn on permissions for sessid passing */
+ monitor_permit(mon_dispatch, MONITOR_REQ_SESSID, 1);
+
+ return (0);
+}
+
+int
+mm_answer_sessid(int socket, Buffer *m)
+{
+ int i;
+
+ debug3("%s entering", __func__);
+
+ if (buffer_len(m) != 16)
+ fatal("%s: bad ssh1 session id", __func__);
+ for (i = 0; i < 16; i++)
+ session_id[i] = buffer_get_char(m);
+
+ /* Turn on permissions for getpwnam */
+ monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
+
+ return (0);
+}
+
+int
+mm_answer_rsa_keyallowed(int socket, Buffer *m)
+{
+ BIGNUM *client_n;
+ Key *key = NULL;
+ u_char *blob = NULL;
+ u_int blen = 0;
+ int allowed = 0;
+
+ debug3("%s entering", __func__);
+
+ if (options.rsa_authentication && authctxt->valid) {
+ if ((client_n = BN_new()) == NULL)
+ fatal("%s: BN_new", __func__);
+ buffer_get_bignum2(m, client_n);
+ allowed = auth_rsa_key_allowed(authctxt->pw, client_n, &key);
+ BN_clear_free(client_n);
+ }
+ buffer_clear(m);
+ buffer_put_int(m, allowed);
+
+ /* clear temporarily storage (used by generate challenge) */
+ monitor_reset_key_state();
+
+ if (allowed && key != NULL) {
+ key->type = KEY_RSA; /* cheat for key_to_blob */
+ if (key_to_blob(key, &blob, &blen) == 0)
+ fatal("%s: key_to_blob failed", __func__);
+ buffer_put_string(m, blob, blen);
+
+ /* Save temporarily for comparison in verify */
+ key_blob = blob;
+ key_bloblen = blen;
+ key_blobtype = MM_RSAUSERKEY;
+ key_free(key);
+ }
+
+ mm_append_debug(m);
+
+ mm_request_send(socket, MONITOR_ANS_RSAKEYALLOWED, m);
+
+ monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed);
+ monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 0);
+ return (0);
+}
+
+int
+mm_answer_rsa_challenge(int socket, Buffer *m)
+{
+ Key *key = NULL;
+ u_char *blob;
+ u_int blen;
+
+ debug3("%s entering", __func__);
+
+ if (!authctxt->valid)
+ fatal("%s: authctxt not valid", __func__);
+ blob = buffer_get_string(m, &blen);
+ if (!monitor_allowed_key(blob, blen))
+ fatal("%s: bad key, not previously allowed", __func__);
+ if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY)
+ fatal("%s: key type mismatch", __func__);
+ if ((key = key_from_blob(blob, blen)) == NULL)
+ fatal("%s: received bad key", __func__);
+
+ if (ssh1_challenge)
+ BN_clear_free(ssh1_challenge);
+ ssh1_challenge = auth_rsa_generate_challenge(key);
+
+ buffer_clear(m);
+ buffer_put_bignum2(m, ssh1_challenge);
+
+ debug3("%s sending reply", __func__);
+ mm_request_send(socket, MONITOR_ANS_RSACHALLENGE, m);
+
+ monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 1);
+ return (0);
+}
+
+int
+mm_answer_rsa_response(int socket, Buffer *m)
+{
+ Key *key = NULL;
+ u_char *blob, *response;
+ u_int blen, len;
+ int success;
+
+ debug3("%s entering", __func__);
+
+ if (!authctxt->valid)
+ fatal("%s: authctxt not valid", __func__);
+ if (ssh1_challenge == NULL)
+ fatal("%s: no ssh1_challenge", __func__);
+
+ blob = buffer_get_string(m, &blen);
+ if (!monitor_allowed_key(blob, blen))
+ fatal("%s: bad key, not previously allowed", __func__);
+ if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY)
+ fatal("%s: key type mismatch: %d", __func__, key_blobtype);
+ if ((key = key_from_blob(blob, blen)) == NULL)
+ fatal("%s: received bad key", __func__);
+ response = buffer_get_string(m, &len);
+ if (len != 16)
+ fatal("%s: received bad response to challenge", __func__);
+ success = auth_rsa_verify_response(key, ssh1_challenge, response);
+
+ key_free(key);
+ xfree(response);
+
+ auth_method = key_blobtype == MM_RSAUSERKEY ? "rsa" : "rhosts-rsa";
+
+ /* reset state */
+ BN_clear_free(ssh1_challenge);
+ ssh1_challenge = NULL;
+ monitor_reset_key_state();
+
+ buffer_clear(m);
+ buffer_put_int(m, success);
+ mm_request_send(socket, MONITOR_ANS_RSARESPONSE, m);
+
+ return (success);
+}
+
+int
+mm_answer_term(int socket, Buffer *req)
+{
+ extern struct monitor *pmonitor;
+ int res, status;
+
+ debug3("%s: tearing down sessions", __func__);
+
+ /* The child is terminating */
+ session_destroy_all(&mm_session_close);
+
+ while (waitpid(pmonitor->m_pid, &status, 0) == -1)
+ if (errno != EINTR)
+ exit(1);
+
+ res = WIFEXITED(status) ? WEXITSTATUS(status) : 1;
+
+ /* Terminate process */
+ exit (res);
+}
+
+void
+monitor_apply_keystate(struct monitor *pmonitor)
+{
+ if (compat20) {
+ set_newkeys(MODE_IN);
+ set_newkeys(MODE_OUT);
+ } else {
+ packet_set_protocol_flags(child_state.ssh1protoflags);
+ packet_set_encryption_key(child_state.ssh1key,
+ child_state.ssh1keylen, child_state.ssh1cipher);
+ xfree(child_state.ssh1key);
+ }
+
+ /* for rc4 and other stateful ciphers */
+ packet_set_keycontext(MODE_OUT, child_state.keyout);
+ xfree(child_state.keyout);
+ packet_set_keycontext(MODE_IN, child_state.keyin);
+ xfree(child_state.keyin);
+
+ if (!compat20) {
+ packet_set_iv(MODE_OUT, child_state.ivout);
+ xfree(child_state.ivout);
+ packet_set_iv(MODE_IN, child_state.ivin);
+ xfree(child_state.ivin);
+ }
+
+ memcpy(&incoming_stream, &child_state.incoming,
+ sizeof(incoming_stream));
+ memcpy(&outgoing_stream, &child_state.outgoing,
+ sizeof(outgoing_stream));
+
+ /* Update with new address */
+ if (options.compression)
+ mm_init_compression(pmonitor->m_zlib);
+
+ /* Network I/O buffers */
+ /* XXX inefficient for large buffers, need: buffer_init_from_string */
+ buffer_clear(&input);
+ buffer_append(&input, child_state.input, child_state.ilen);
+ memset(child_state.input, 0, child_state.ilen);
+ xfree(child_state.input);
+
+ buffer_clear(&output);
+ buffer_append(&output, child_state.output, child_state.olen);
+ memset(child_state.output, 0, child_state.olen);
+ xfree(child_state.output);
+}
+
+static Kex *
+mm_get_kex(Buffer *m)
+{
+ Kex *kex;
+ void *blob;
+ u_int bloblen;
+
+ kex = xmalloc(sizeof(*kex));
+ memset(kex, 0, sizeof(*kex));
+ kex->session_id = buffer_get_string(m, &kex->session_id_len);
+ if ((session_id2 == NULL) ||
+ (kex->session_id_len != session_id2_len) ||
+ (memcmp(kex->session_id, session_id2, session_id2_len) != 0))
+ fatal("mm_get_get: internal error: bad session id");
+ kex->we_need = buffer_get_int(m);
+ kex->server = 1;
+ kex->hostkey_type = buffer_get_int(m);
+ kex->kex_type = buffer_get_int(m);
+ blob = buffer_get_string(m, &bloblen);
+ buffer_init(&kex->my);
+ buffer_append(&kex->my, blob, bloblen);
+ xfree(blob);
+ blob = buffer_get_string(m, &bloblen);
+ buffer_init(&kex->peer);
+ buffer_append(&kex->peer, blob, bloblen);
+ xfree(blob);
+ kex->done = 1;
+ kex->flags = buffer_get_int(m);
+ kex->client_version_string = buffer_get_string(m, NULL);
+ kex->server_version_string = buffer_get_string(m, NULL);
+ kex->load_host_key=&get_hostkey_by_type;
+ kex->host_key_index=&get_hostkey_index;
+
+ return (kex);
+}
+
+/* This function requries careful sanity checking */
+
+void
+mm_get_keystate(struct monitor *pmonitor)
+{
+ Buffer m;
+ u_char *blob, *p;
+ u_int bloblen, plen;
+
+ debug3("%s: Waiting for new keys", __func__);
+
+ buffer_init(&m);
+ mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, &m);
+ if (!compat20) {
+ child_state.ssh1protoflags = buffer_get_int(&m);
+ child_state.ssh1cipher = buffer_get_int(&m);
+ child_state.ssh1key = buffer_get_string(&m,
+ &child_state.ssh1keylen);
+ child_state.ivout = buffer_get_string(&m,
+ &child_state.ivoutlen);
+ child_state.ivin = buffer_get_string(&m, &child_state.ivinlen);
+ goto skip;
+ } else {
+ /* Get the Kex for rekeying */
+ *pmonitor->m_pkex = mm_get_kex(&m);
+ }
+
+ blob = buffer_get_string(&m, &bloblen);
+ current_keys[MODE_OUT] = mm_newkeys_from_blob(blob, bloblen);
+ xfree(blob);
+
+ debug3("%s: Waiting for second key", __func__);
+ blob = buffer_get_string(&m, &bloblen);
+ current_keys[MODE_IN] = mm_newkeys_from_blob(blob, bloblen);
+ xfree(blob);
+
+ /* Now get sequence numbers for the packets */
+ packet_set_seqnr(MODE_OUT, buffer_get_int(&m));
+ packet_set_seqnr(MODE_IN, buffer_get_int(&m));
+
+ skip:
+ /* Get the key context */
+ child_state.keyout = buffer_get_string(&m, &child_state.keyoutlen);
+ child_state.keyin = buffer_get_string(&m, &child_state.keyinlen);
+
+ debug3("%s: Getting compression state", __func__);
+ /* Get compression state */
+ p = buffer_get_string(&m, &plen);
+ if (plen != sizeof(child_state.outgoing))
+ fatal("%s: bad request size", __func__);
+ memcpy(&child_state.outgoing, p, sizeof(child_state.outgoing));
+ xfree(p);
+
+ p = buffer_get_string(&m, &plen);
+ if (plen != sizeof(child_state.incoming))
+ fatal("%s: bad request size", __func__);
+ memcpy(&child_state.incoming, p, sizeof(child_state.incoming));
+ xfree(p);
+
+ /* Network I/O buffers */
+ debug3("%s: Getting Network I/O buffers", __func__);
+ child_state.input = buffer_get_string(&m, &child_state.ilen);
+ child_state.output = buffer_get_string(&m, &child_state.olen);
+
+ buffer_free(&m);
+}
+
+
+/* Allocation functions for zlib */
+void *
+mm_zalloc(struct mm_master *mm, u_int ncount, u_int size)
+{
+ void *address;
+
+ address = mm_malloc(mm, size * ncount);
+
+ return (address);
+}
+
+void
+mm_zfree(struct mm_master *mm, void *address)
+{
+ mm_free(mm, address);
+}
+
+void
+mm_init_compression(struct mm_master *mm)
+{
+ outgoing_stream.zalloc = (alloc_func)mm_zalloc;
+ outgoing_stream.zfree = (free_func)mm_zfree;
+ outgoing_stream.opaque = mm;
+
+ incoming_stream.zalloc = (alloc_func)mm_zalloc;
+ incoming_stream.zfree = (free_func)mm_zfree;
+ incoming_stream.opaque = mm;
+}
+
+/* XXX */
+
+#define FD_CLOSEONEXEC(x) do { \
+ if (fcntl(x, F_SETFD, 1) == -1) \
+ fatal("fcntl(%d, F_SETFD)", x); \
+} while (0)
+
+static void
+monitor_socketpair(int *pair)
+{
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
+ fatal("%s: socketpair", __func__);
+ FD_CLOSEONEXEC(pair[0]);
+ FD_CLOSEONEXEC(pair[1]);
+}
+
+#define MM_MEMSIZE 65536
+
+struct monitor *
+monitor_init(void)
+{
+ struct monitor *mon;
+ int pair[2];
+
+ mon = xmalloc(sizeof(*mon));
+
+ monitor_socketpair(pair);
+
+ mon->m_recvfd = pair[0];
+ mon->m_sendfd = pair[1];
+
+ /* Used to share zlib space across processes */
+ if (options.compression) {
+ mon->m_zback = mm_create(NULL, MM_MEMSIZE);
+ mon->m_zlib = mm_create(mon->m_zback, 20 * MM_MEMSIZE);
+
+ /* Compression needs to share state across borders */
+ mm_init_compression(mon->m_zlib);
+ }
+
+ return mon;
+}
+
+void
+monitor_reinit(struct monitor *mon)
+{
+ int pair[2];
+
+ monitor_socketpair(pair);
+
+ mon->m_recvfd = pair[0];
+ mon->m_sendfd = pair[1];
+}
diff --git a/crypto/openssh/monitor.h b/crypto/openssh/monitor.h
new file mode 100644
index 0000000..42d5237
--- /dev/null
+++ b/crypto/openssh/monitor.h
@@ -0,0 +1,81 @@
+/* $OpenBSD: monitor.h,v 1.6 2002/06/11 05:46:20 mpech Exp $ */
+
+/*
+ * Copyright 2002 Niels Provos <provos@citi.umich.edu>
+ * 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.
+ */
+
+#ifndef _MONITOR_H_
+#define _MONITOR_H_
+
+enum monitor_reqtype {
+ MONITOR_REQ_MODULI, MONITOR_ANS_MODULI,
+ MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV,
+ MONITOR_REQ_SIGN, MONITOR_ANS_SIGN,
+ MONITOR_REQ_PWNAM, MONITOR_ANS_PWNAM,
+ MONITOR_REQ_AUTH2_READ_BANNER, MONITOR_ANS_AUTH2_READ_BANNER,
+ MONITOR_REQ_AUTHPASSWORD, MONITOR_ANS_AUTHPASSWORD,
+ MONITOR_REQ_BSDAUTHQUERY, MONITOR_ANS_BSDAUTHQUERY,
+ MONITOR_REQ_BSDAUTHRESPOND, MONITOR_ANS_BSDAUTHRESPOND,
+ MONITOR_REQ_SKEYQUERY, MONITOR_ANS_SKEYQUERY,
+ MONITOR_REQ_SKEYRESPOND, MONITOR_ANS_SKEYRESPOND,
+ MONITOR_REQ_KEYALLOWED, MONITOR_ANS_KEYALLOWED,
+ MONITOR_REQ_KEYVERIFY, MONITOR_ANS_KEYVERIFY,
+ MONITOR_REQ_KEYEXPORT,
+ MONITOR_REQ_PTY, MONITOR_ANS_PTY,
+ MONITOR_REQ_PTYCLEANUP,
+ MONITOR_REQ_SESSKEY, MONITOR_ANS_SESSKEY,
+ MONITOR_REQ_SESSID,
+ MONITOR_REQ_RSAKEYALLOWED, MONITOR_ANS_RSAKEYALLOWED,
+ MONITOR_REQ_RSACHALLENGE, MONITOR_ANS_RSACHALLENGE,
+ MONITOR_REQ_RSARESPONSE, MONITOR_ANS_RSARESPONSE,
+ MONITOR_REQ_TERM
+};
+
+struct mm_master;
+struct monitor {
+ int m_recvfd;
+ int m_sendfd;
+ struct mm_master *m_zback;
+ struct mm_master *m_zlib;
+ struct Kex **m_pkex;
+ pid_t m_pid;
+};
+
+struct monitor *monitor_init(void);
+void monitor_reinit(struct monitor *);
+void monitor_sync(struct monitor *);
+
+struct Authctxt;
+struct Authctxt *monitor_child_preauth(struct monitor *);
+void monitor_child_postauth(struct monitor *);
+
+struct mon_table;
+int monitor_read(struct monitor*, struct mon_table *, struct mon_table **);
+
+/* Prototypes for request sending and receiving */
+void mm_request_send(int, enum monitor_reqtype, Buffer *);
+void mm_request_receive(int, Buffer *);
+void mm_request_receive_expect(int, enum monitor_reqtype, Buffer *);
+
+#endif /* _MONITOR_H_ */
diff --git a/crypto/openssh/monitor_fdpass.c b/crypto/openssh/monitor_fdpass.c
new file mode 100644
index 0000000..9696c86
--- /dev/null
+++ b/crypto/openssh/monitor_fdpass.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2001 Niels Provos <provos@citi.umich.edu>
+ * 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: monitor_fdpass.c,v 1.3 2002/06/04 23:05:49 markus Exp $");
+
+#include <sys/uio.h>
+
+#include "log.h"
+#include "monitor_fdpass.h"
+
+void
+mm_send_fd(int socket, int fd)
+{
+ struct msghdr msg;
+ char tmp[CMSG_SPACE(sizeof(int))];
+ struct cmsghdr *cmsg;
+ struct iovec vec;
+ char ch = '\0';
+ int n;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_control = (caddr_t)tmp;
+ msg.msg_controllen = CMSG_LEN(sizeof(int));
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ *(int *)CMSG_DATA(cmsg) = fd;
+
+ vec.iov_base = &ch;
+ vec.iov_len = 1;
+ msg.msg_iov = &vec;
+ msg.msg_iovlen = 1;
+
+ if ((n = sendmsg(socket, &msg, 0)) == -1)
+ fatal("%s: sendmsg(%d): %s", __func__, fd,
+ strerror(errno));
+ if (n != 1)
+ fatal("%s: sendmsg: expected sent 1 got %d",
+ __func__, n);
+}
+
+int
+mm_receive_fd(int socket)
+{
+ struct msghdr msg;
+ char tmp[CMSG_SPACE(sizeof(int))];
+ struct cmsghdr *cmsg;
+ struct iovec vec;
+ char ch;
+ int fd, n;
+
+ memset(&msg, 0, sizeof(msg));
+ vec.iov_base = &ch;
+ vec.iov_len = 1;
+ msg.msg_iov = &vec;
+ msg.msg_iovlen = 1;
+ msg.msg_control = tmp;
+ msg.msg_controllen = sizeof(tmp);
+
+ if ((n = recvmsg(socket, &msg, 0)) == -1)
+ fatal("%s: recvmsg: %s", __func__, strerror(errno));
+ if (n != 1)
+ fatal("%s: recvmsg: expected received 1 got %d",
+ __func__, n);
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ if (cmsg->cmsg_type != SCM_RIGHTS)
+ fatal("%s: expected type %d got %d", __func__,
+ SCM_RIGHTS, cmsg->cmsg_type);
+ fd = (*(int *)CMSG_DATA(cmsg));
+ return fd;
+}
diff --git a/crypto/openssh/monitor_fdpass.h b/crypto/openssh/monitor_fdpass.h
new file mode 100644
index 0000000..31d080e
--- /dev/null
+++ b/crypto/openssh/monitor_fdpass.h
@@ -0,0 +1,34 @@
+/* $OpenBSD: monitor_fdpass.h,v 1.2 2002/03/26 03:24:01 stevesk Exp $ */
+
+/*
+ * Copyright 2002 Niels Provos <provos@citi.umich.edu>
+ * 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.
+ */
+
+#ifndef _MM_FDPASS_H_
+#define _MM_FDPASS_H_
+
+void mm_send_fd(int, int);
+int mm_receive_fd(int);
+
+#endif /* _MM_FDPASS_H_ */
diff --git a/crypto/openssh/monitor_mm.c b/crypto/openssh/monitor_mm.c
new file mode 100644
index 0000000..c6ea208
--- /dev/null
+++ b/crypto/openssh/monitor_mm.c
@@ -0,0 +1,330 @@
+/*
+ * Copyright 2002 Niels Provos <provos@citi.umich.edu>
+ * 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: monitor_mm.c,v 1.6 2002/06/04 23:05:49 markus Exp $");
+
+#include <sys/mman.h>
+
+#include "ssh.h"
+#include "xmalloc.h"
+#include "log.h"
+#include "monitor_mm.h"
+
+static int
+mm_compare(struct mm_share *a, struct mm_share *b)
+{
+ return ((char *)a->address - (char *)b->address);
+}
+
+RB_GENERATE(mmtree, mm_share, next, mm_compare)
+
+static struct mm_share *
+mm_make_entry(struct mm_master *mm, struct mmtree *head,
+ void *address, size_t size)
+{
+ struct mm_share *tmp, *tmp2;
+
+ if (mm->mmalloc == NULL)
+ tmp = xmalloc(sizeof(struct mm_share));
+ else
+ tmp = mm_xmalloc(mm->mmalloc, sizeof(struct mm_share));
+ tmp->address = address;
+ tmp->size = size;
+
+ tmp2 = RB_INSERT(mmtree, head, tmp);
+ if (tmp2 != NULL)
+ fatal("mm_make_entry(%p): double address %p->%p(%lu)",
+ mm, tmp2, address, (u_long)size);
+
+ return (tmp);
+}
+
+/* Creates a shared memory area of a certain size */
+
+struct mm_master *
+mm_create(struct mm_master *mmalloc, size_t size)
+{
+ void *address;
+ struct mm_master *mm;
+
+ if (mmalloc == NULL)
+ mm = xmalloc(sizeof(struct mm_master));
+ else
+ mm = mm_xmalloc(mmalloc, sizeof(struct mm_master));
+
+ /*
+ * If the memory map has a mm_master it can be completely
+ * shared including authentication between the child
+ * and the client.
+ */
+ mm->mmalloc = mmalloc;
+
+ address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANON|MAP_SHARED,
+ -1, 0);
+ if (address == MAP_FAILED)
+ fatal("mmap(%lu): %s", (u_long)size, strerror(errno));
+
+ mm->address = address;
+ mm->size = size;
+
+ RB_INIT(&mm->rb_free);
+ RB_INIT(&mm->rb_allocated);
+
+ mm_make_entry(mm, &mm->rb_free, address, size);
+
+ return (mm);
+}
+
+/* Frees either the allocated or the free list */
+
+static void
+mm_freelist(struct mm_master *mmalloc, struct mmtree *head)
+{
+ struct mm_share *mms, *next;
+
+ for (mms = RB_ROOT(head); mms; mms = next) {
+ next = RB_NEXT(mmtree, head, mms);
+ RB_REMOVE(mmtree, head, mms);
+ if (mmalloc == NULL)
+ xfree(mms);
+ else
+ mm_free(mmalloc, mms);
+ }
+}
+
+/* Destroys a memory mapped area */
+
+void
+mm_destroy(struct mm_master *mm)
+{
+ mm_freelist(mm->mmalloc, &mm->rb_free);
+ mm_freelist(mm->mmalloc, &mm->rb_allocated);
+
+ if (munmap(mm->address, mm->size) == -1)
+ fatal("munmap(%p, %lu): %s", mm->address, (u_long)mm->size,
+ strerror(errno));
+ if (mm->mmalloc == NULL)
+ xfree(mm);
+ else
+ mm_free(mm->mmalloc, mm);
+}
+
+void *
+mm_xmalloc(struct mm_master *mm, size_t size)
+{
+ void *address;
+
+ address = mm_malloc(mm, size);
+ if (address == NULL)
+ fatal("%s: mm_malloc(%lu)", __func__, (u_long)size);
+ return (address);
+}
+
+
+/* Allocates data from a memory mapped area */
+
+void *
+mm_malloc(struct mm_master *mm, size_t size)
+{
+ struct mm_share *mms, *tmp;
+
+ if (size == 0)
+ fatal("mm_malloc: try to allocate 0 space");
+
+ size = ((size + MM_MINSIZE - 1) / MM_MINSIZE) * MM_MINSIZE;
+
+ RB_FOREACH(mms, mmtree, &mm->rb_free) {
+ if (mms->size >= size)
+ break;
+ }
+
+ if (mms == NULL)
+ return (NULL);
+
+ /* Debug */
+ memset(mms->address, 0xd0, size);
+
+ tmp = mm_make_entry(mm, &mm->rb_allocated, mms->address, size);
+
+ /* Does not change order in RB tree */
+ mms->size -= size;
+ mms->address = (u_char *)mms->address + size;
+
+ if (mms->size == 0) {
+ RB_REMOVE(mmtree, &mm->rb_free, mms);
+ if (mm->mmalloc == NULL)
+ xfree(mms);
+ else
+ mm_free(mm->mmalloc, mms);
+ }
+
+ return (tmp->address);
+}
+
+/* Frees memory in a memory mapped area */
+
+void
+mm_free(struct mm_master *mm, void *address)
+{
+ struct mm_share *mms, *prev, tmp;
+
+ tmp.address = address;
+ mms = RB_FIND(mmtree, &mm->rb_allocated, &tmp);
+ if (mms == NULL)
+ fatal("mm_free(%p): can not find %p", mm, address);
+
+ /* Debug */
+ memset(mms->address, 0xd0, mms->size);
+
+ /* Remove from allocated list and insert in free list */
+ RB_REMOVE(mmtree, &mm->rb_allocated, mms);
+ if (RB_INSERT(mmtree, &mm->rb_free, mms) != NULL)
+ fatal("mm_free(%p): double address %p", mm, address);
+
+ /* Find previous entry */
+ prev = mms;
+ if (RB_LEFT(prev, next)) {
+ prev = RB_LEFT(prev, next);
+ while (RB_RIGHT(prev, next))
+ prev = RB_RIGHT(prev, next);
+ } else {
+ if (RB_PARENT(prev, next) &&
+ (prev == RB_RIGHT(RB_PARENT(prev, next), next)))
+ prev = RB_PARENT(prev, next);
+ else {
+ while (RB_PARENT(prev, next) &&
+ (prev == RB_LEFT(RB_PARENT(prev, next), next)))
+ prev = RB_PARENT(prev, next);
+ prev = RB_PARENT(prev, next);
+ }
+ }
+
+ /* Check if range does not overlap */
+ if (prev != NULL && MM_ADDRESS_END(prev) > address)
+ fatal("mm_free: memory corruption: %p(%lu) > %p",
+ prev->address, (u_long)prev->size, address);
+
+ /* See if we can merge backwards */
+ if (prev != NULL && MM_ADDRESS_END(prev) == address) {
+ prev->size += mms->size;
+ RB_REMOVE(mmtree, &mm->rb_free, mms);
+ if (mm->mmalloc == NULL)
+ xfree(mms);
+ else
+ mm_free(mm->mmalloc, mms);
+ } else
+ prev = mms;
+
+ if (prev == NULL)
+ return;
+
+ /* Check if we can merge forwards */
+ mms = RB_NEXT(mmtree, &mm->rb_free, prev);
+ if (mms == NULL)
+ return;
+
+ if (MM_ADDRESS_END(prev) > mms->address)
+ fatal("mm_free: memory corruption: %p < %p(%lu)",
+ mms->address, prev->address, (u_long)prev->size);
+ if (MM_ADDRESS_END(prev) != mms->address)
+ return;
+
+ prev->size += mms->size;
+ RB_REMOVE(mmtree, &mm->rb_free, mms);
+
+ if (mm->mmalloc == NULL)
+ xfree(mms);
+ else
+ mm_free(mm->mmalloc, mms);
+}
+
+static void
+mm_sync_list(struct mmtree *oldtree, struct mmtree *newtree,
+ struct mm_master *mm, struct mm_master *mmold)
+{
+ struct mm_master *mmalloc = mm->mmalloc;
+ struct mm_share *mms, *new;
+
+ /* Sync free list */
+ RB_FOREACH(mms, mmtree, oldtree) {
+ /* Check the values */
+ mm_memvalid(mmold, mms, sizeof(struct mm_share));
+ mm_memvalid(mm, mms->address, mms->size);
+
+ new = mm_xmalloc(mmalloc, sizeof(struct mm_share));
+ memcpy(new, mms, sizeof(struct mm_share));
+ RB_INSERT(mmtree, newtree, new);
+ }
+}
+
+void
+mm_share_sync(struct mm_master **pmm, struct mm_master **pmmalloc)
+{
+ struct mm_master *mm;
+ struct mm_master *mmalloc;
+ struct mm_master *mmold;
+ struct mmtree rb_free, rb_allocated;
+
+ debug3("%s: Share sync", __func__);
+
+ mm = *pmm;
+ mmold = mm->mmalloc;
+ mm_memvalid(mmold, mm, sizeof(*mm));
+
+ mmalloc = mm_create(NULL, mm->size);
+ mm = mm_xmalloc(mmalloc, sizeof(struct mm_master));
+ memcpy(mm, *pmm, sizeof(struct mm_master));
+ mm->mmalloc = mmalloc;
+
+ rb_free = mm->rb_free;
+ rb_allocated = mm->rb_allocated;
+
+ RB_INIT(&mm->rb_free);
+ RB_INIT(&mm->rb_allocated);
+
+ mm_sync_list(&rb_free, &mm->rb_free, mm, mmold);
+ mm_sync_list(&rb_allocated, &mm->rb_allocated, mm, mmold);
+
+ mm_destroy(mmold);
+
+ *pmm = mm;
+ *pmmalloc = mmalloc;
+
+ debug3("%s: Share sync end", __func__);
+}
+
+void
+mm_memvalid(struct mm_master *mm, void *address, size_t size)
+{
+ void *end = (u_char *)address + size;
+
+ if (address < mm->address)
+ fatal("mm_memvalid: address too small: %p", address);
+ if (end < address)
+ fatal("mm_memvalid: end < address: %p < %p", end, address);
+ if (end > (void *)((u_char *)mm->address + mm->size))
+ fatal("mm_memvalid: address too large: %p", address);
+}
diff --git a/crypto/openssh/monitor_mm.h b/crypto/openssh/monitor_mm.h
new file mode 100644
index 0000000..d8a5cdf
--- /dev/null
+++ b/crypto/openssh/monitor_mm.h
@@ -0,0 +1,66 @@
+/* $OpenBSD: monitor_mm.h,v 1.2 2002/03/26 03:24:01 stevesk Exp $ */
+
+/*
+ * Copyright 2002 Niels Provos <provos@citi.umich.edu>
+ * 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.
+ */
+
+#ifndef _MM_H_
+#define _MM_H_
+#include <sys/tree.h>
+
+struct mm_share {
+ RB_ENTRY(mm_share) next;
+ void *address;
+ size_t size;
+};
+
+struct mm_master {
+ RB_HEAD(mmtree, mm_share) rb_free;
+ struct mmtree rb_allocated;
+ void *address;
+ size_t size;
+
+ struct mm_master *mmalloc; /* Used to completely share */
+
+ int write; /* used to writing to other party */
+ int read; /* used for reading from other party */
+};
+
+RB_PROTOTYPE(mmtree, mm_share, next, mm_compare)
+
+#define MM_MINSIZE 128
+
+#define MM_ADDRESS_END(x) (void *)((u_char *)(x)->address + (x)->size)
+
+struct mm_master *mm_create(struct mm_master *, size_t);
+void mm_destroy(struct mm_master *);
+
+void mm_share_sync(struct mm_master **, struct mm_master **);
+
+void *mm_malloc(struct mm_master *, size_t);
+void *mm_xmalloc(struct mm_master *, size_t);
+void mm_free(struct mm_master *, void *);
+
+void mm_memvalid(struct mm_master *, void *, size_t);
+#endif /* _MM_H_ */
diff --git a/crypto/openssh/monitor_wrap.c b/crypto/openssh/monitor_wrap.c
new file mode 100644
index 0000000..faad6c2
--- /dev/null
+++ b/crypto/openssh/monitor_wrap.c
@@ -0,0 +1,920 @@
+/*
+ * Copyright 2002 Niels Provos <provos@citi.umich.edu>
+ * Copyright 2002 Markus Friedl <markus@openbsd.org>
+ * 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: monitor_wrap.c,v 1.11 2002/06/19 18:01:00 markus Exp $");
+
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+
+#include "ssh.h"
+#include "dh.h"
+#include "kex.h"
+#include "auth.h"
+#include "buffer.h"
+#include "bufaux.h"
+#include "packet.h"
+#include "mac.h"
+#include "log.h"
+#include "zlib.h"
+#include "monitor.h"
+#include "monitor_wrap.h"
+#include "xmalloc.h"
+#include "atomicio.h"
+#include "monitor_fdpass.h"
+#include "getput.h"
+
+#include "auth.h"
+#include "channels.h"
+#include "session.h"
+
+/* Imports */
+extern int compat20;
+extern Newkeys *newkeys[];
+extern z_stream incoming_stream;
+extern z_stream outgoing_stream;
+extern struct monitor *pmonitor;
+extern Buffer input, output;
+
+void
+mm_request_send(int socket, enum monitor_reqtype type, Buffer *m)
+{
+ u_char buf[5];
+ u_int mlen = buffer_len(m);
+
+ debug3("%s entering: type %d", __func__, type);
+
+ PUT_32BIT(buf, mlen + 1);
+ buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */
+ if (atomicio(write, socket, buf, sizeof(buf)) != sizeof(buf))
+ fatal("%s: write", __func__);
+ if (atomicio(write, socket, buffer_ptr(m), mlen) != mlen)
+ fatal("%s: write", __func__);
+}
+
+void
+mm_request_receive(int socket, Buffer *m)
+{
+ u_char buf[4];
+ ssize_t res;
+ u_int msg_len;
+
+ debug3("%s entering", __func__);
+
+ res = atomicio(read, socket, buf, sizeof(buf));
+ if (res != sizeof(buf)) {
+ if (res == 0)
+ fatal_cleanup();
+ fatal("%s: read: %ld", __func__, (long)res);
+ }
+ msg_len = GET_32BIT(buf);
+ if (msg_len > 256 * 1024)
+ fatal("%s: read: bad msg_len %d", __func__, msg_len);
+ buffer_clear(m);
+ buffer_append_space(m, msg_len);
+ res = atomicio(read, socket, buffer_ptr(m), msg_len);
+ if (res != msg_len)
+ fatal("%s: read: %ld != msg_len", __func__, (long)res);
+}
+
+void
+mm_request_receive_expect(int socket, enum monitor_reqtype type, Buffer *m)
+{
+ u_char rtype;
+
+ debug3("%s entering: type %d", __func__, type);
+
+ mm_request_receive(socket, m);
+ rtype = buffer_get_char(m);
+ if (rtype != type)
+ fatal("%s: read: rtype %d != type %d", __func__,
+ rtype, type);
+}
+
+DH *
+mm_choose_dh(int min, int nbits, int max)
+{
+ BIGNUM *p, *g;
+ int success = 0;
+ Buffer m;
+
+ buffer_init(&m);
+ buffer_put_int(&m, min);
+ buffer_put_int(&m, nbits);
+ buffer_put_int(&m, max);
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, &m);
+
+ debug3("%s: waiting for MONITOR_ANS_MODULI", __func__);
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, &m);
+
+ success = buffer_get_char(&m);
+ if (success == 0)
+ fatal("%s: MONITOR_ANS_MODULI failed", __func__);
+
+ if ((p = BN_new()) == NULL)
+ fatal("%s: BN_new failed", __func__);
+ if ((g = BN_new()) == NULL)
+ fatal("%s: BN_new failed", __func__);
+ buffer_get_bignum2(&m, p);
+ buffer_get_bignum2(&m, g);
+
+ debug3("%s: remaining %d", __func__, buffer_len(&m));
+ buffer_free(&m);
+
+ return (dh_new_group(g, p));
+}
+
+int
+mm_key_sign(Key *key, u_char **sigp, u_int *lenp, u_char *data, u_int datalen)
+{
+ Kex *kex = *pmonitor->m_pkex;
+ Buffer m;
+
+ debug3("%s entering", __func__);
+
+ buffer_init(&m);
+ buffer_put_int(&m, kex->host_key_index(key));
+ buffer_put_string(&m, data, datalen);
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m);
+
+ debug3("%s: waiting for MONITOR_ANS_SIGN", __func__);
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, &m);
+ *sigp = buffer_get_string(&m, lenp);
+ buffer_free(&m);
+
+ return (0);
+}
+
+struct passwd *
+mm_getpwnamallow(const char *login)
+{
+ Buffer m;
+ struct passwd *pw;
+ u_int pwlen;
+
+ debug3("%s entering", __func__);
+
+ buffer_init(&m);
+ buffer_put_cstring(&m, login);
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m);
+
+ debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__);
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m);
+
+ if (buffer_get_char(&m) == 0) {
+ buffer_free(&m);
+ return (NULL);
+ }
+ pw = buffer_get_string(&m, &pwlen);
+ if (pwlen != sizeof(struct passwd))
+ fatal("%s: struct passwd size mismatch", __func__);
+ pw->pw_name = buffer_get_string(&m, NULL);
+ pw->pw_passwd = buffer_get_string(&m, NULL);
+ pw->pw_gecos = buffer_get_string(&m, NULL);
+ pw->pw_class = buffer_get_string(&m, NULL);
+ pw->pw_dir = buffer_get_string(&m, NULL);
+ pw->pw_shell = buffer_get_string(&m, NULL);
+ buffer_free(&m);
+
+ return (pw);
+}
+
+char* mm_auth2_read_banner(void)
+{
+ Buffer m;
+ char *banner;
+
+ debug3("%s entering", __func__);
+
+ buffer_init(&m);
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m);
+ buffer_clear(&m);
+
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTH2_READ_BANNER, &m);
+ banner = buffer_get_string(&m, NULL);
+ buffer_free(&m);
+
+ return (banner);
+}
+
+/* Inform the privileged process about service and style */
+
+void
+mm_inform_authserv(char *service, char *style)
+{
+ Buffer m;
+
+ debug3("%s entering", __func__);
+
+ buffer_init(&m);
+ buffer_put_cstring(&m, service);
+ buffer_put_cstring(&m, style ? style : "");
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m);
+
+ buffer_free(&m);
+}
+
+/* Do the password authentication */
+int
+mm_auth_password(Authctxt *authctxt, char *password)
+{
+ Buffer m;
+ int authenticated = 0;
+
+ debug3("%s entering", __func__);
+
+ buffer_init(&m);
+ buffer_put_cstring(&m, password);
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, &m);
+
+ debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__);
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m);
+
+ authenticated = buffer_get_int(&m);
+
+ buffer_free(&m);
+
+ debug3("%s: user %sauthenticated",
+ __func__, authenticated ? "" : "not ");
+ return (authenticated);
+}
+
+int
+mm_user_key_allowed(struct passwd *pw, Key *key)
+{
+ return (mm_key_allowed(MM_USERKEY, NULL, NULL, key));
+}
+
+int
+mm_hostbased_key_allowed(struct passwd *pw, char *user, char *host,
+ Key *key)
+{
+ return (mm_key_allowed(MM_HOSTKEY, user, host, key));
+}
+
+int
+mm_auth_rhosts_rsa_key_allowed(struct passwd *pw, char *user,
+ char *host, Key *key)
+{
+ int ret;
+
+ key->type = KEY_RSA; /* XXX hack for key_to_blob */
+ ret = mm_key_allowed(MM_RSAHOSTKEY, user, host, key);
+ key->type = KEY_RSA1;
+ return (ret);
+}
+
+static void
+mm_send_debug(Buffer *m)
+{
+ char *msg;
+
+ while (buffer_len(m)) {
+ msg = buffer_get_string(m, NULL);
+ debug3("%s: Sending debug: %s", __func__, msg);
+ packet_send_debug("%s", msg);
+ xfree(msg);
+ }
+}
+
+int
+mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key)
+{
+ Buffer m;
+ u_char *blob;
+ u_int len;
+ int allowed = 0;
+
+ debug3("%s entering", __func__);
+
+ /* Convert the key to a blob and the pass it over */
+ if (!key_to_blob(key, &blob, &len))
+ return (0);
+
+ buffer_init(&m);
+ buffer_put_int(&m, type);
+ buffer_put_cstring(&m, user ? user : "");
+ buffer_put_cstring(&m, host ? host : "");
+ buffer_put_string(&m, blob, len);
+ xfree(blob);
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m);
+
+ debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__);
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYALLOWED, &m);
+
+ allowed = buffer_get_int(&m);
+
+ /* Send potential debug messages */
+ mm_send_debug(&m);
+
+ buffer_free(&m);
+
+ return (allowed);
+}
+
+/*
+ * This key verify needs to send the key type along, because the
+ * privileged parent makes the decision if the key is allowed
+ * for authentication.
+ */
+
+int
+mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
+{
+ Buffer m;
+ u_char *blob;
+ u_int len;
+ int verified = 0;
+
+ debug3("%s entering", __func__);
+
+ /* Convert the key to a blob and the pass it over */
+ if (!key_to_blob(key, &blob, &len))
+ return (0);
+
+ buffer_init(&m);
+ buffer_put_string(&m, blob, len);
+ buffer_put_string(&m, sig, siglen);
+ buffer_put_string(&m, data, datalen);
+ xfree(blob);
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m);
+
+ debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__);
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m);
+
+ verified = buffer_get_int(&m);
+
+ buffer_free(&m);
+
+ return (verified);
+}
+
+/* Export key state after authentication */
+Newkeys *
+mm_newkeys_from_blob(u_char *blob, int blen)
+{
+ Buffer b;
+ u_int len;
+ Newkeys *newkey = NULL;
+ Enc *enc;
+ Mac *mac;
+ Comp *comp;
+
+ debug3("%s: %p(%d)", __func__, blob, blen);
+#ifdef DEBUG_PK
+ dump_base64(stderr, blob, blen);
+#endif
+ buffer_init(&b);
+ buffer_append(&b, blob, blen);
+
+ newkey = xmalloc(sizeof(*newkey));
+ enc = &newkey->enc;
+ mac = &newkey->mac;
+ comp = &newkey->comp;
+
+ /* Enc structure */
+ enc->name = buffer_get_string(&b, NULL);
+ buffer_get(&b, &enc->cipher, sizeof(enc->cipher));
+ enc->enabled = buffer_get_int(&b);
+ enc->block_size = buffer_get_int(&b);
+ enc->key = buffer_get_string(&b, &enc->key_len);
+ enc->iv = buffer_get_string(&b, &len);
+ if (len != enc->block_size)
+ fatal("%s: bad ivlen: expected %d != %d", __func__,
+ enc->block_size, len);
+
+ if (enc->name == NULL || cipher_by_name(enc->name) != enc->cipher)
+ fatal("%s: bad cipher name %s or pointer %p", __func__,
+ enc->name, enc->cipher);
+
+ /* Mac structure */
+ mac->name = buffer_get_string(&b, NULL);
+ if (mac->name == NULL || mac_init(mac, mac->name) == -1)
+ fatal("%s: can not init mac %s", __func__, mac->name);
+ mac->enabled = buffer_get_int(&b);
+ mac->key = buffer_get_string(&b, &len);
+ if (len > mac->key_len)
+ fatal("%s: bad mac key length: %d > %d", __func__, len,
+ mac->key_len);
+ mac->key_len = len;
+
+ /* Comp structure */
+ comp->type = buffer_get_int(&b);
+ comp->enabled = buffer_get_int(&b);
+ comp->name = buffer_get_string(&b, NULL);
+
+ len = buffer_len(&b);
+ if (len != 0)
+ error("newkeys_from_blob: remaining bytes in blob %d", len);
+ buffer_free(&b);
+ return (newkey);
+}
+
+int
+mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp)
+{
+ Buffer b;
+ int len;
+ u_char *buf;
+ Enc *enc;
+ Mac *mac;
+ Comp *comp;
+ Newkeys *newkey = newkeys[mode];
+
+ debug3("%s: converting %p", __func__, newkey);
+
+ if (newkey == NULL) {
+ error("%s: newkey == NULL", __func__);
+ return 0;
+ }
+ enc = &newkey->enc;
+ mac = &newkey->mac;
+ comp = &newkey->comp;
+
+ buffer_init(&b);
+ /* Enc structure */
+ buffer_put_cstring(&b, enc->name);
+ /* The cipher struct is constant and shared, you export pointer */
+ buffer_append(&b, &enc->cipher, sizeof(enc->cipher));
+ buffer_put_int(&b, enc->enabled);
+ buffer_put_int(&b, enc->block_size);
+ buffer_put_string(&b, enc->key, enc->key_len);
+ packet_get_keyiv(mode, enc->iv, enc->block_size);
+ buffer_put_string(&b, enc->iv, enc->block_size);
+
+ /* Mac structure */
+ buffer_put_cstring(&b, mac->name);
+ buffer_put_int(&b, mac->enabled);
+ buffer_put_string(&b, mac->key, mac->key_len);
+
+ /* Comp structure */
+ buffer_put_int(&b, comp->type);
+ buffer_put_int(&b, comp->enabled);
+ buffer_put_cstring(&b, comp->name);
+
+ len = buffer_len(&b);
+ buf = xmalloc(len);
+ memcpy(buf, buffer_ptr(&b), len);
+ memset(buffer_ptr(&b), 0, len);
+ buffer_free(&b);
+ if (lenp != NULL)
+ *lenp = len;
+ if (blobp != NULL)
+ *blobp = buf;
+ return len;
+}
+
+static void
+mm_send_kex(Buffer *m, Kex *kex)
+{
+ buffer_put_string(m, kex->session_id, kex->session_id_len);
+ buffer_put_int(m, kex->we_need);
+ buffer_put_int(m, kex->hostkey_type);
+ buffer_put_int(m, kex->kex_type);
+ buffer_put_string(m, buffer_ptr(&kex->my), buffer_len(&kex->my));
+ buffer_put_string(m, buffer_ptr(&kex->peer), buffer_len(&kex->peer));
+ buffer_put_int(m, kex->flags);
+ buffer_put_cstring(m, kex->client_version_string);
+ buffer_put_cstring(m, kex->server_version_string);
+}
+
+void
+mm_send_keystate(struct monitor *pmonitor)
+{
+ Buffer m;
+ u_char *blob, *p;
+ u_int bloblen, plen;
+
+ buffer_init(&m);
+
+ if (!compat20) {
+ u_char iv[24];
+ u_char *key;
+ u_int ivlen, keylen;
+
+ buffer_put_int(&m, packet_get_protocol_flags());
+
+ buffer_put_int(&m, packet_get_ssh1_cipher());
+
+ debug3("%s: Sending ssh1 KEY+IV", __func__);
+ keylen = packet_get_encryption_key(NULL);
+ key = xmalloc(keylen+1); /* add 1 if keylen == 0 */
+ keylen = packet_get_encryption_key(key);
+ buffer_put_string(&m, key, keylen);
+ memset(key, 0, keylen);
+ xfree(key);
+
+ ivlen = packet_get_keyiv_len(MODE_OUT);
+ packet_get_keyiv(MODE_OUT, iv, ivlen);
+ buffer_put_string(&m, iv, ivlen);
+ ivlen = packet_get_keyiv_len(MODE_OUT);
+ packet_get_keyiv(MODE_IN, iv, ivlen);
+ buffer_put_string(&m, iv, ivlen);
+ goto skip;
+ } else {
+ /* Kex for rekeying */
+ mm_send_kex(&m, *pmonitor->m_pkex);
+ }
+
+ debug3("%s: Sending new keys: %p %p",
+ __func__, newkeys[MODE_OUT], newkeys[MODE_IN]);
+
+ /* Keys from Kex */
+ if (!mm_newkeys_to_blob(MODE_OUT, &blob, &bloblen))
+ fatal("%s: conversion of newkeys failed", __func__);
+
+ buffer_put_string(&m, blob, bloblen);
+ xfree(blob);
+
+ if (!mm_newkeys_to_blob(MODE_IN, &blob, &bloblen))
+ fatal("%s: conversion of newkeys failed", __func__);
+
+ buffer_put_string(&m, blob, bloblen);
+ xfree(blob);
+
+ buffer_put_int(&m, packet_get_seqnr(MODE_OUT));
+ buffer_put_int(&m, packet_get_seqnr(MODE_IN));
+
+ debug3("%s: New keys have been sent", __func__);
+ skip:
+ /* More key context */
+ plen = packet_get_keycontext(MODE_OUT, NULL);
+ p = xmalloc(plen+1);
+ packet_get_keycontext(MODE_OUT, p);
+ buffer_put_string(&m, p, plen);
+ xfree(p);
+
+ plen = packet_get_keycontext(MODE_IN, NULL);
+ p = xmalloc(plen+1);
+ packet_get_keycontext(MODE_IN, p);
+ buffer_put_string(&m, p, plen);
+ xfree(p);
+
+ /* Compression state */
+ debug3("%s: Sending compression state", __func__);
+ buffer_put_string(&m, &outgoing_stream, sizeof(outgoing_stream));
+ buffer_put_string(&m, &incoming_stream, sizeof(incoming_stream));
+
+ /* Network I/O buffers */
+ buffer_put_string(&m, buffer_ptr(&input), buffer_len(&input));
+ buffer_put_string(&m, buffer_ptr(&output), buffer_len(&output));
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m);
+ debug3("%s: Finished sending state", __func__);
+
+ buffer_free(&m);
+}
+
+int
+mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
+{
+ Buffer m;
+ u_char *p;
+ int success = 0;
+
+ buffer_init(&m);
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m);
+
+ debug3("%s: waiting for MONITOR_ANS_PTY", __func__);
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, &m);
+
+ success = buffer_get_int(&m);
+ if (success == 0) {
+ debug3("%s: pty alloc failed", __func__);
+ buffer_free(&m);
+ return (0);
+ }
+ p = buffer_get_string(&m, NULL);
+ buffer_free(&m);
+
+ strlcpy(namebuf, p, namebuflen); /* Possible truncation */
+ xfree(p);
+
+ *ptyfd = mm_receive_fd(pmonitor->m_recvfd);
+ *ttyfd = mm_receive_fd(pmonitor->m_recvfd);
+
+ /* Success */
+ return (1);
+}
+
+void
+mm_session_pty_cleanup2(void *session)
+{
+ Session *s = session;
+ Buffer m;
+
+ if (s->ttyfd == -1)
+ return;
+ buffer_init(&m);
+ buffer_put_cstring(&m, s->tty);
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, &m);
+ buffer_free(&m);
+
+ /* closed dup'ed master */
+ if (close(s->ptymaster) < 0)
+ error("close(s->ptymaster): %s", strerror(errno));
+
+ /* unlink pty from session */
+ s->ttyfd = -1;
+}
+
+/* Request process termination */
+
+void
+mm_terminate(void)
+{
+ Buffer m;
+
+ buffer_init(&m);
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, &m);
+ buffer_free(&m);
+}
+
+int
+mm_ssh1_session_key(BIGNUM *num)
+{
+ int rsafail;
+ Buffer m;
+
+ buffer_init(&m);
+ buffer_put_bignum2(&m, num);
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSKEY, &m);
+
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SESSKEY, &m);
+
+ rsafail = buffer_get_int(&m);
+ buffer_get_bignum2(&m, num);
+
+ buffer_free(&m);
+
+ return (rsafail);
+}
+
+static void
+mm_chall_setup(char **name, char **infotxt, u_int *numprompts,
+ char ***prompts, u_int **echo_on)
+{
+ *name = xstrdup("");
+ *infotxt = xstrdup("");
+ *numprompts = 1;
+ *prompts = xmalloc(*numprompts * sizeof(char*));
+ *echo_on = xmalloc(*numprompts * sizeof(u_int));
+ (*echo_on)[0] = 0;
+}
+
+int
+mm_bsdauth_query(void *ctx, char **name, char **infotxt,
+ u_int *numprompts, char ***prompts, u_int **echo_on)
+{
+ Buffer m;
+ int res;
+ char *challenge;
+
+ debug3("%s: entering", __func__);
+
+ buffer_init(&m);
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, &m);
+
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY,
+ &m);
+ res = buffer_get_int(&m);
+ if (res == -1) {
+ debug3("%s: no challenge", __func__);
+ buffer_free(&m);
+ return (-1);
+ }
+
+ /* Get the challenge, and format the response */
+ challenge = buffer_get_string(&m, NULL);
+ buffer_free(&m);
+
+ mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
+ (*prompts)[0] = challenge;
+
+ debug3("%s: received challenge: %s", __func__, challenge);
+
+ return (0);
+}
+
+int
+mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses)
+{
+ Buffer m;
+ int authok;
+
+ debug3("%s: entering", __func__);
+ if (numresponses != 1)
+ return (-1);
+
+ buffer_init(&m);
+ buffer_put_cstring(&m, responses[0]);
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, &m);
+
+ mm_request_receive_expect(pmonitor->m_recvfd,
+ MONITOR_ANS_BSDAUTHRESPOND, &m);
+
+ authok = buffer_get_int(&m);
+ buffer_free(&m);
+
+ return ((authok == 0) ? -1 : 0);
+}
+
+int
+mm_skey_query(void *ctx, char **name, char **infotxt,
+ u_int *numprompts, char ***prompts, u_int **echo_on)
+{
+ Buffer m;
+ int len, res;
+ char *p, *challenge;
+
+ debug3("%s: entering", __func__);
+
+ buffer_init(&m);
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYQUERY, &m);
+
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SKEYQUERY,
+ &m);
+ res = buffer_get_int(&m);
+ if (res == -1) {
+ debug3("%s: no challenge", __func__);
+ buffer_free(&m);
+ return (-1);
+ }
+
+ /* Get the challenge, and format the response */
+ challenge = buffer_get_string(&m, NULL);
+ buffer_free(&m);
+
+ debug3("%s: received challenge: %s", __func__, challenge);
+
+ mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
+
+ len = strlen(challenge) + strlen(SKEY_PROMPT) + 1;
+ p = xmalloc(len);
+ strlcpy(p, challenge, len);
+ strlcat(p, SKEY_PROMPT, len);
+ (*prompts)[0] = p;
+ xfree(challenge);
+
+ return (0);
+}
+
+int
+mm_skey_respond(void *ctx, u_int numresponses, char **responses)
+{
+ Buffer m;
+ int authok;
+
+ debug3("%s: entering", __func__);
+ if (numresponses != 1)
+ return (-1);
+
+ buffer_init(&m);
+ buffer_put_cstring(&m, responses[0]);
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYRESPOND, &m);
+
+ mm_request_receive_expect(pmonitor->m_recvfd,
+ MONITOR_ANS_SKEYRESPOND, &m);
+
+ authok = buffer_get_int(&m);
+ buffer_free(&m);
+
+ return ((authok == 0) ? -1 : 0);
+}
+
+void
+mm_ssh1_session_id(u_char session_id[16])
+{
+ Buffer m;
+ int i;
+
+ debug3("%s entering", __func__);
+
+ buffer_init(&m);
+ for (i = 0; i < 16; i++)
+ buffer_put_char(&m, session_id[i]);
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSID, &m);
+ buffer_free(&m);
+}
+
+int
+mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
+{
+ Buffer m;
+ Key *key;
+ u_char *blob;
+ u_int blen;
+ int allowed = 0;
+
+ debug3("%s entering", __func__);
+
+ buffer_init(&m);
+ buffer_put_bignum2(&m, client_n);
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSAKEYALLOWED, &m);
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &m);
+
+ allowed = buffer_get_int(&m);
+
+ if (allowed && rkey != NULL) {
+ blob = buffer_get_string(&m, &blen);
+ if ((key = key_from_blob(blob, blen)) == NULL)
+ fatal("%s: key_from_blob failed", __func__);
+ *rkey = key;
+ xfree(blob);
+ }
+ mm_send_debug(&m);
+ buffer_free(&m);
+
+ return (allowed);
+}
+
+BIGNUM *
+mm_auth_rsa_generate_challenge(Key *key)
+{
+ Buffer m;
+ BIGNUM *challenge;
+ u_char *blob;
+ u_int blen;
+
+ debug3("%s entering", __func__);
+
+ if ((challenge = BN_new()) == NULL)
+ fatal("%s: BN_new failed", __func__);
+
+ key->type = KEY_RSA; /* XXX cheat for key_to_blob */
+ if (key_to_blob(key, &blob, &blen) == 0)
+ fatal("%s: key_to_blob failed", __func__);
+ key->type = KEY_RSA1;
+
+ buffer_init(&m);
+ buffer_put_string(&m, blob, blen);
+ xfree(blob);
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSACHALLENGE, &m);
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSACHALLENGE, &m);
+
+ buffer_get_bignum2(&m, challenge);
+ buffer_free(&m);
+
+ return (challenge);
+}
+
+int
+mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16])
+{
+ Buffer m;
+ u_char *blob;
+ u_int blen;
+ int success = 0;
+
+ debug3("%s entering", __func__);
+
+ key->type = KEY_RSA; /* XXX cheat for key_to_blob */
+ if (key_to_blob(key, &blob, &blen) == 0)
+ fatal("%s: key_to_blob failed", __func__);
+ key->type = KEY_RSA1;
+
+ buffer_init(&m);
+ buffer_put_string(&m, blob, blen);
+ buffer_put_string(&m, response, 16);
+ xfree(blob);
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSARESPONSE, &m);
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSARESPONSE, &m);
+
+ success = buffer_get_int(&m);
+ buffer_free(&m);
+
+ return (success);
+}
diff --git a/crypto/openssh/monitor_wrap.h b/crypto/openssh/monitor_wrap.h
new file mode 100644
index 0000000..739b054
--- /dev/null
+++ b/crypto/openssh/monitor_wrap.h
@@ -0,0 +1,88 @@
+/* $OpenBSD: monitor_wrap.h,v 1.5 2002/05/12 23:53:45 djm Exp $ */
+
+/*
+ * Copyright 2002 Niels Provos <provos@citi.umich.edu>
+ * 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.
+ */
+
+#ifndef _MM_WRAP_H_
+#define _MM_WRAP_H_
+#include "key.h"
+#include "buffer.h"
+
+extern int use_privsep;
+#define PRIVSEP(x) (use_privsep ? mm_##x : x)
+
+enum mm_keytype {MM_NOKEY, MM_HOSTKEY, MM_USERKEY, MM_RSAHOSTKEY, MM_RSAUSERKEY};
+
+struct monitor;
+struct mm_master;
+struct passwd;
+struct Authctxt;
+
+DH *mm_choose_dh(int, int, int);
+int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int);
+void mm_inform_authserv(char *, char *);
+struct passwd *mm_getpwnamallow(const char *);
+char* mm_auth2_read_banner(void);
+int mm_auth_password(struct Authctxt *, char *);
+int mm_key_allowed(enum mm_keytype, char *, char *, Key *);
+int mm_user_key_allowed(struct passwd *, Key *);
+int mm_hostbased_key_allowed(struct passwd *, char *, char *, Key *);
+int mm_auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *);
+int mm_key_verify(Key *, u_char *, u_int, u_char *, u_int);
+int mm_auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **);
+int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *);
+BIGNUM *mm_auth_rsa_generate_challenge(Key *);
+
+void mm_terminate(void);
+int mm_pty_allocate(int *, int *, char *, int);
+void mm_session_pty_cleanup2(void *);
+
+/* SSHv1 interfaces */
+void mm_ssh1_session_id(u_char *);
+int mm_ssh1_session_key(BIGNUM *);
+
+/* Key export functions */
+struct Newkeys *mm_newkeys_from_blob(u_char *, int);
+int mm_newkeys_to_blob(int, u_char **, u_int *);
+
+void monitor_apply_keystate(struct monitor *);
+void mm_get_keystate(struct monitor *);
+void mm_send_keystate(struct monitor*);
+
+/* bsdauth */
+int mm_bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **);
+int mm_bsdauth_respond(void *, u_int, char **);
+
+/* skey */
+int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **);
+int mm_skey_respond(void *, u_int, char **);
+
+/* zlib allocation hooks */
+
+void *mm_zalloc(struct mm_master *, u_int, u_int);
+void mm_zfree(struct mm_master *, void *);
+void mm_init_compression(struct mm_master *);
+
+#endif /* _MM_H_ */
diff --git a/crypto/openssh/msg.c b/crypto/openssh/msg.c
new file mode 100644
index 0000000..103aed2
--- /dev/null
+++ b/crypto/openssh/msg.c
@@ -0,0 +1,73 @@
+/*
+ * 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: msg.c,v 1.2 2002/06/19 00:27:55 deraadt Exp $");
+
+#include "buffer.h"
+#include "getput.h"
+#include "log.h"
+#include "atomicio.h"
+#include "msg.h"
+
+void
+msg_send(int fd, u_char type, Buffer *m)
+{
+ u_char buf[5];
+ u_int mlen = buffer_len(m);
+
+ debug3("msg_send: type %d", type);
+
+ PUT_32BIT(buf, mlen + 1);
+ buf[4] = type; /* 1st byte of payload is mesg-type */
+ if (atomicio(write, fd, buf, sizeof(buf)) != sizeof(buf))
+ fatal("msg_send: write");
+ if (atomicio(write, fd, buffer_ptr(m), mlen) != mlen)
+ fatal("msg_send: write");
+}
+
+int
+msg_recv(int fd, Buffer *m)
+{
+ u_char buf[4];
+ ssize_t res;
+ u_int msg_len;
+
+ debug3("msg_recv entering");
+
+ res = atomicio(read, fd, buf, sizeof(buf));
+ if (res != sizeof(buf)) {
+ if (res == 0)
+ return -1;
+ fatal("msg_recv: read: header %d", res);
+ }
+ msg_len = GET_32BIT(buf);
+ if (msg_len > 256 * 1024)
+ fatal("msg_recv: read: bad msg_len %d", msg_len);
+ buffer_clear(m);
+ buffer_append_space(m, msg_len);
+ res = atomicio(read, fd, buffer_ptr(m), msg_len);
+ if (res != msg_len)
+ fatal("msg_recv: read: %ld != msg_len", (long)res);
+ return 0;
+}
diff --git a/crypto/openssh/msg.h b/crypto/openssh/msg.h
new file mode 100644
index 0000000..13fa95b
--- /dev/null
+++ b/crypto/openssh/msg.h
@@ -0,0 +1,31 @@
+/* $OpenBSD: msg.h,v 1.1 2002/05/23 19:24:30 markus Exp $ */
+/*
+ * 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.
+ */
+#ifndef SSH_MSG_H
+#define SSH_MSG_H
+
+void msg_send(int, u_char, Buffer *);
+int msg_recv(int, Buffer *);
+
+#endif
diff --git a/crypto/openssh/nchan.c b/crypto/openssh/nchan.c
index 8153abb..b9b304d 100644
--- a/crypto/openssh/nchan.c
+++ b/crypto/openssh/nchan.c
@@ -23,7 +23,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: nchan.c,v 1.44 2002/01/21 23:27:10 markus Exp $");
+RCSID("$OpenBSD: nchan.c,v 1.47 2002/06/19 00:27:55 deraadt Exp $");
#include "ssh1.h"
#include "ssh2.h"
@@ -302,6 +302,7 @@ static void
chan_rcvd_eof2(Channel *c)
{
debug("channel %d: rcvd eof", c->self);
+ c->flags |= CHAN_EOF_RCVD;
if (c->ostate == CHAN_OUTPUT_OPEN)
chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
}
@@ -330,6 +331,7 @@ chan_send_eof2(Channel *c)
packet_start(SSH2_MSG_CHANNEL_EOF);
packet_put_int(c->remote_id);
packet_send();
+ c->flags |= CHAN_EOF_SENT;
break;
default:
error("channel %d: cannot send eof for istate %d",
@@ -365,7 +367,8 @@ chan_rcvd_ieof(Channel *c)
else
chan_rcvd_ieof1(c);
if (c->ostate == CHAN_OUTPUT_WAIT_DRAIN &&
- buffer_len(&c->output) == 0)
+ buffer_len(&c->output) == 0 &&
+ !CHANNEL_EFD_OUTPUT_ACTIVE(c))
chan_obuf_empty(c);
}
void
@@ -404,39 +407,30 @@ chan_is_dead(Channel *c, int send)
debug("channel %d: is dead", c->self);
return 1;
}
- /*
- * we have to delay the close message if the efd (for stderr) is
- * still active
- */
- if (((c->extended_usage != CHAN_EXTENDED_IGNORE) &&
- buffer_len(&c->extended) > 0)
-#if 0
- || ((c->extended_usage == CHAN_EXTENDED_READ) &&
- c->efd != -1)
-#endif
- ) {
- 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");
- } else {
- if (!(c->flags & CHAN_CLOSE_SENT)) {
- 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 ((datafellows & SSH_BUG_EXTEOF) &&
+ c->extended_usage == CHAN_EXTENDED_WRITE &&
+ c->efd != -1 &&
+ buffer_len(&c->extended) > 0) {
+ debug2("channel %d: active efd: %d len %d",
+ c->self, c->efd, buffer_len(&c->extended));
+ return 0;
+ }
+ if (!(c->flags & CHAN_CLOSE_SENT)) {
+ 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)) {
- debug("channel %d: is dead", c->self);
- return 1;
- }
+ }
+ if ((c->flags & CHAN_CLOSE_SENT) &&
+ (c->flags & CHAN_CLOSE_RCVD)) {
+ debug("channel %d: is dead", c->self);
+ return 1;
}
return 0;
}
diff --git a/crypto/openssh/packet.c b/crypto/openssh/packet.c
index b3e6d84..759361b 100644
--- a/crypto/openssh/packet.c
+++ b/crypto/openssh/packet.c
@@ -37,7 +37,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: packet.c,v 1.90 2002/02/27 21:23:13 stevesk Exp $");
+RCSID("$OpenBSD: packet.c,v 1.95 2002/06/19 18:01:00 markus Exp $");
#include "xmalloc.h"
#include "buffer.h"
@@ -60,6 +60,7 @@ RCSID("$OpenBSD: packet.c,v 1.90 2002/02/27 21:23:13 stevesk Exp $");
#include "log.h"
#include "canohost.h"
#include "misc.h"
+#include "ssh.h"
#ifdef PACKET_DEBUG
#define DBG(x) x
@@ -86,10 +87,10 @@ static CipherContext receive_context;
static CipherContext send_context;
/* Buffer for raw input data from the socket. */
-static Buffer input;
+Buffer input;
/* Buffer for raw output data going to the socket. */
-static Buffer output;
+Buffer output;
/* Buffer for the partial outgoing packet being constructed. */
static Buffer outgoing_packet;
@@ -115,6 +116,12 @@ static int interactive_mode = 0;
/* Session key information for Encryption and MAC */
Newkeys *newkeys[MODE_MAX];
+static u_int32_t read_seqnr = 0;
+static u_int32_t send_seqnr = 0;
+
+/* Session key for protocol v1 */
+static u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
+static u_int ssh1_keylen;
/* roundup current message to extra_pad bytes */
static u_char extra_pad = 0;
@@ -171,6 +178,99 @@ packet_connection_is_on_socket(void)
return 1;
}
+/*
+ * Exports an IV from the CipherContext required to export the key
+ * state back from the unprivileged child to the privileged parent
+ * process.
+ */
+
+void
+packet_get_keyiv(int mode, u_char *iv, u_int len)
+{
+ CipherContext *cc;
+
+ if (mode == MODE_OUT)
+ cc = &send_context;
+ else
+ cc = &receive_context;
+
+ cipher_get_keyiv(cc, iv, len);
+}
+
+int
+packet_get_keycontext(int mode, u_char *dat)
+{
+ CipherContext *cc;
+
+ if (mode == MODE_OUT)
+ cc = &send_context;
+ else
+ cc = &receive_context;
+
+ return (cipher_get_keycontext(cc, dat));
+}
+
+void
+packet_set_keycontext(int mode, u_char *dat)
+{
+ CipherContext *cc;
+
+ if (mode == MODE_OUT)
+ cc = &send_context;
+ else
+ cc = &receive_context;
+
+ cipher_set_keycontext(cc, dat);
+}
+
+int
+packet_get_keyiv_len(int mode)
+{
+ CipherContext *cc;
+
+ if (mode == MODE_OUT)
+ cc = &send_context;
+ else
+ cc = &receive_context;
+
+ return (cipher_get_keyiv_len(cc));
+}
+void
+packet_set_iv(int mode, u_char *dat)
+{
+ CipherContext *cc;
+
+ if (mode == MODE_OUT)
+ cc = &send_context;
+ else
+ cc = &receive_context;
+
+ cipher_set_keyiv(cc, dat);
+}
+int
+packet_get_ssh1_cipher()
+{
+ return (cipher_get_number(receive_context.cipher));
+}
+
+
+u_int32_t
+packet_get_seqnr(int mode)
+{
+ return (mode == MODE_IN ? read_seqnr : send_seqnr);
+}
+
+void
+packet_set_seqnr(int mode, u_int32_t seqnr)
+{
+ if (mode == MODE_IN)
+ read_seqnr = seqnr;
+ else if (mode == MODE_OUT)
+ send_seqnr = seqnr;
+ else
+ fatal("packet_set_seqnr: bad mode %d", mode);
+}
+
/* returns 1 if connection is via ipv4 */
int
@@ -291,6 +391,7 @@ packet_start_compression(int level)
* 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)
@@ -300,10 +401,23 @@ 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);
+ if (keylen > SSH_SESSION_KEY_LENGTH)
+ fatal("packet_set_encryption_key: keylen too big: %d", keylen);
+ memcpy(ssh1_key, key, keylen);
+ ssh1_keylen = keylen;
cipher_init(&send_context, cipher, key, keylen, NULL, 0, CIPHER_ENCRYPT);
cipher_init(&receive_context, cipher, key, keylen, NULL, 0, CIPHER_DECRYPT);
}
+u_int
+packet_get_encryption_key(u_char *key)
+{
+ if (key == NULL)
+ return (ssh1_keylen);
+ memcpy(key, ssh1_key, ssh1_keylen);
+ return (ssh1_keylen);
+}
+
/* Start constructing a packet to send. */
void
packet_start(u_char type)
@@ -433,7 +547,7 @@ packet_send1(void)
*/
}
-static void
+void
set_newkeys(int mode)
{
Enc *enc;
@@ -477,8 +591,9 @@ set_newkeys(int mode)
DBG(debug("cipher_init_context: %d", mode));
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);
+ /* Deleting the keys does not gain extra security */
+ /* 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)
@@ -495,7 +610,6 @@ set_newkeys(int mode)
static void
packet_send2(void)
{
- static u_int32_t seqnr = 0;
u_char type, *cp, *macbuf = NULL;
u_char padlen, pad;
u_int packet_length = 0;
@@ -549,7 +663,7 @@ packet_send2(void)
/* 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)",
+ debug3("packet_send2: adding %d (len %d padlen %d extra_pad %d)",
pad, len, padlen, extra_pad);
padlen += pad;
extra_pad = 0;
@@ -576,10 +690,10 @@ packet_send2(void)
/* compute MAC over seqnr and packet(length fields, payload, padding) */
if (mac && mac->enabled) {
- macbuf = mac_compute(mac, seqnr,
+ macbuf = mac_compute(mac, send_seqnr,
buffer_ptr(&outgoing_packet),
buffer_len(&outgoing_packet));
- DBG(debug("done calc MAC out #%d", seqnr));
+ DBG(debug("done calc MAC out #%d", send_seqnr));
}
/* encrypt packet and append to output buffer. */
cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
@@ -593,7 +707,7 @@ packet_send2(void)
buffer_dump(&output);
#endif
/* increment sequence number for outgoing packets */
- if (++seqnr == 0)
+ if (++send_seqnr == 0)
log("outgoing seqnr wraps around");
buffer_clear(&outgoing_packet);
@@ -783,7 +897,6 @@ packet_read_poll1(void)
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 *macbuf, *cp, type;
@@ -845,17 +958,17 @@ packet_read_poll2(u_int32_t *seqnr_p)
* increment sequence number for incoming packet
*/
if (mac && mac->enabled) {
- macbuf = mac_compute(mac, seqnr,
+ macbuf = mac_compute(mac, read_seqnr,
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));
+ DBG(debug("MAC #%d ok", read_seqnr));
buffer_consume(&input, mac->mac_len);
}
if (seqnr_p != NULL)
- *seqnr_p = seqnr;
- if (++seqnr == 0)
+ *seqnr_p = read_seqnr;
+ if (++read_seqnr == 0)
log("incoming seqnr wraps around");
/* get padlen */
diff --git a/crypto/openssh/radix.c b/crypto/openssh/radix.c
index e604357..580e7e0 100644
--- a/crypto/openssh/radix.c
+++ b/crypto/openssh/radix.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 1999 Dug Song. All rights reserved.
+ * 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
@@ -25,190 +26,132 @@
#include "includes.h"
#include "uuencode.h"
-RCSID("$OpenBSD: radix.c,v 1.17 2001/11/19 19:02:16 mpech Exp $");
+RCSID("$OpenBSD: radix.c,v 1.21 2002/06/19 00:27:55 deraadt Exp $");
#ifdef AFS
#include <krb.h>
#include <radix.h>
+#include "bufaux.h"
-typedef u_char my_u_char;
-typedef u_int my_u_int32_t;
-typedef u_short my_u_short;
-
-/* Nasty macros from BIND-4.9.2 */
-
-#define GETSHORT(s, cp) { \
- my_u_char *t_cp = (my_u_char *)(cp); \
- (s) = (((my_u_short)t_cp[0]) << 8) \
- | (((my_u_short)t_cp[1])) \
- ; \
- (cp) += 2; \
-}
-
-#define GETLONG(l, 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) \
- | (((my_u_int32_t)t_cp[3])) \
- ; \
- (cp) += 4; \
-}
-
-#define PUTSHORT(s, 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; \
-}
+int
+creds_to_radix(CREDENTIALS *creds, u_char *buf, size_t buflen)
+{
+ Buffer b;
+ int ret;
-#define PUTLONG(l, 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; \
- *t_cp = t_l; \
- (cp) += 4; \
-}
+ buffer_init(&b);
-#define GETSTRING(s, p, p_l) { \
- 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++; \
- } \
- if (p_c == p_targ) { \
- return 1; \
- } \
- *s_c = *p_c++; \
- (p_l) = (p_l) - (p_c - (p)); \
- (p) = p_c; \
-}
+ buffer_put_char(&b, 1); /* version */
+ buffer_append(&b, creds->service, strlen(creds->service));
+ buffer_put_char(&b, '\0');
+ buffer_append(&b, creds->instance, strlen(creds->instance));
+ buffer_put_char(&b, '\0');
+ buffer_append(&b, creds->realm, strlen(creds->realm));
+ buffer_put_char(&b, '\0');
+ buffer_append(&b, creds->pname, strlen(creds->pname));
+ buffer_put_char(&b, '\0');
+ buffer_append(&b, creds->pinst, strlen(creds->pinst));
+ buffer_put_char(&b, '\0');
-int
-creds_to_radix(CREDENTIALS *creds, u_char *buf, size_t buflen)
-{
- char *p, *s;
- int len;
- char temp[2048];
-
- p = temp;
- *p++ = 1; /* version */
- s = creds->service;
- while (*s)
- *p++ = *s++;
- *p++ = *s;
- s = creds->instance;
- while (*s)
- *p++ = *s++;
- *p++ = *s;
- s = creds->realm;
- while (*s)
- *p++ = *s++;
- *p++ = *s;
-
- s = creds->pname;
- while (*s)
- *p++ = *s++;
- *p++ = *s;
- s = creds->pinst;
- while (*s)
- *p++ = *s++;
- *p++ = *s;
/* Null string to repeat the realm. */
- *p++ = '\0';
+ buffer_put_char(&b, '\0');
- PUTLONG(creds->issue_date, p);
- {
- u_int endTime;
- endTime = (u_int) krb_life_to_time(creds->issue_date,
- creds->lifetime);
- PUTLONG(endTime, p);
- }
+ buffer_put_int(&b, creds->issue_date);
+ buffer_put_int(&b, krb_life_to_time(creds->issue_date,
+ creds->lifetime));
+ buffer_append(&b, creds->session, sizeof(creds->session));
+ buffer_put_short(&b, creds->kvno);
- memcpy(p, &creds->session, sizeof(creds->session));
- p += sizeof(creds->session);
+ /* 32 bit size + data */
+ buffer_put_string(&b, creds->ticket_st.dat, creds->ticket_st.length);
- PUTSHORT(creds->kvno, p);
- PUTLONG(creds->ticket_st.length, p);
+ ret = uuencode(buffer_ptr(&b), buffer_len(&b), (char *)buf, buflen);
- memcpy(p, creds->ticket_st.dat, creds->ticket_st.length);
- p += creds->ticket_st.length;
- len = p - temp;
-
- return (uuencode((u_char *)temp, len, (char *)buf, buflen));
+ buffer_free(&b);
+ return ret;
}
+#define GETSTRING(b, t, tlen) \
+ do { \
+ int i, found = 0; \
+ for (i = 0; i < tlen; i++) { \
+ if (buffer_len(b) == 0) \
+ goto done; \
+ t[i] = buffer_get_char(b); \
+ if (t[i] == '\0') { \
+ found = 1; \
+ break; \
+ } \
+ } \
+ if (!found) \
+ goto done; \
+ } while(0)
+
int
radix_to_creds(const char *buf, CREDENTIALS *creds)
{
+ Buffer b;
+ char c, version, *space, *p;
+ u_int endTime;
+ int len, blen, ret;
- char *p;
- int len, tl;
- char version;
- char temp[2048];
+ ret = 0;
+ blen = strlen(buf);
- len = uudecode(buf, (u_char *)temp, sizeof(temp));
- if (len < 0)
+ /* sanity check for size */
+ if (blen > 8192)
return 0;
- p = temp;
+ buffer_init(&b);
+ space = buffer_append_space(&b, blen);
/* check version and length! */
+ len = uudecode(buf, space, blen);
if (len < 1)
- return 0;
- version = *p;
- p++;
- len--;
+ goto done;
+
+ version = buffer_get_char(&b);
+
+ GETSTRING(&b, creds->service, sizeof creds->service);
+ GETSTRING(&b, creds->instance, sizeof creds->instance);
+ GETSTRING(&b, creds->realm, sizeof creds->realm);
+ GETSTRING(&b, creds->pname, sizeof creds->pname);
+ GETSTRING(&b, creds->pinst, sizeof creds->pinst);
- GETSTRING(creds->service, p, len);
- GETSTRING(creds->instance, p, len);
- GETSTRING(creds->realm, p, len);
+ if (buffer_len(&b) == 0)
+ goto done;
- GETSTRING(creds->pname, p, len);
- GETSTRING(creds->pinst, p, len);
/* Ignore possibly different realm. */
- while (*p && len)
- p++, len--;
- if (len == 0)
- return 0;
- p++, len--;
+ while (buffer_len(&b) > 0 && (c = buffer_get_char(&b)) != '\0')
+ ;
- /* Enough space for remaining fixed-length parts? */
- if (len < (4 + 4 + sizeof(creds->session) + 2 + 4))
- return 0;
+ if (buffer_len(&b) == 0)
+ goto done;
- GETLONG(creds->issue_date, p);
- len -= 4;
- {
- u_int endTime;
- GETLONG(endTime, p);
- len -= 4;
- creds->lifetime = krb_time_to_life(creds->issue_date, endTime);
- }
-
- memcpy(&creds->session, p, sizeof(creds->session));
- p += sizeof(creds->session);
- len -= sizeof(creds->session);
-
- GETSHORT(creds->kvno, p);
- len -= 2;
- GETLONG(creds->ticket_st.length, p);
- len -= 4;
-
- tl = creds->ticket_st.length;
- if (tl < 0 || tl > len || tl > sizeof(creds->ticket_st.dat))
- return 0;
+ creds->issue_date = buffer_get_int(&b);
+
+ endTime = buffer_get_int(&b);
+ creds->lifetime = krb_time_to_life(creds->issue_date, endTime);
+
+ len = buffer_len(&b);
+ if (len < sizeof(creds->session))
+ goto done;
+ memcpy(&creds->session, buffer_ptr(&b), sizeof(creds->session));
+ buffer_consume(&b, sizeof(creds->session));
+
+ creds->kvno = buffer_get_short(&b);
- memcpy(creds->ticket_st.dat, p, tl);
- p += tl;
- len -= tl;
+ p = buffer_get_string(&b, &len);
+ if (len < 0 || len > sizeof(creds->ticket_st.dat))
+ goto done;
+ memcpy(&creds->ticket_st.dat, p, len);
+ creds->ticket_st.length = len;
- return 1;
+ ret = 1;
+done:
+ buffer_free(&b);
+ return ret;
}
#endif /* AFS */
diff --git a/crypto/openssh/readpass.c b/crypto/openssh/readpass.c
index c55dd21..dc1b11f 100644
--- a/crypto/openssh/readpass.c
+++ b/crypto/openssh/readpass.c
@@ -23,7 +23,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: readpass.c,v 1.26 2002/02/13 00:39:15 markus Exp $");
+RCSID("$OpenBSD: readpass.c,v 1.27 2002/03/26 15:58:46 markus Exp $");
#include <readpassphrase.h>
@@ -120,8 +120,11 @@ read_passphrase(const char *prompt, int flags)
return ssh_askpass(askpass, prompt);
}
- if (readpassphrase(prompt, buf, sizeof buf, rppflags) == NULL)
+ if (readpassphrase(prompt, buf, sizeof buf, rppflags) == NULL) {
+ if (flags & RP_ALLOW_EOF)
+ return NULL;
return xstrdup("");
+ }
ret = xstrdup(buf);
memset(buf, 'x', sizeof buf);
diff --git a/crypto/openssh/readpass.h b/crypto/openssh/readpass.h
index 229973c..a45d32f 100644
--- a/crypto/openssh/readpass.h
+++ b/crypto/openssh/readpass.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: readpass.h,v 1.6 2001/06/26 17:27:24 markus Exp $ */
+/* $OpenBSD: readpass.h,v 1.7 2002/03/26 15:58:46 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -14,5 +14,6 @@
#define RP_ECHO 0x0001
#define RP_ALLOW_STDIN 0x0002
+#define RP_ALLOW_EOF 0x0004
char *read_passphrase(const char *, int);
diff --git a/crypto/openssh/scard.c b/crypto/openssh/scard.c
index e1b1fb6..e71815e 100644
--- a/crypto/openssh/scard.c
+++ b/crypto/openssh/scard.c
@@ -24,16 +24,30 @@
#ifdef SMARTCARD
#include "includes.h"
-RCSID("$OpenBSD: scard.c,v 1.17 2001/12/27 18:22:16 markus Exp $");
+RCSID("$OpenBSD: scard.c,v 1.25 2002/03/26 18:46:59 rees Exp $");
-#include <openssl/engine.h>
+#include <openssl/evp.h>
#include <sectok.h>
#include "key.h"
#include "log.h"
#include "xmalloc.h"
+#include "readpass.h"
#include "scard.h"
+#if OPENSSL_VERSION_NUMBER < 0x00907000L
+#define USE_ENGINE
+#define RSA_get_default_method RSA_get_default_openssl_method
+#else
+#endif
+
+#ifdef USE_ENGINE
+#include <openssl/engine.h>
+#define sc_get_rsa sc_get_engine
+#else
+#define sc_get_rsa sc_get_rsa_method
+#endif
+
#define CLA_SSH 0x05
#define INS_DECRYPT 0x10
#define INS_GET_KEYLENGTH 0x20
@@ -42,10 +56,17 @@ RCSID("$OpenBSD: scard.c,v 1.17 2001/12/27 18:22:16 markus Exp $");
#define MAX_BUF_SIZE 256
+u_char DEFAUT0[] = {0xad, 0x9f, 0x61, 0xfe, 0xfa, 0x20, 0xce, 0x63};
+
static int sc_fd = -1;
static char *sc_reader_id = NULL;
+static char *sc_pin = NULL;
static int cla = 0x00; /* class */
+static void sc_mk_digest(const char *pin, u_char *digest);
+static int get_AUT0(u_char *aut0);
+static int try_AUT0(void);
+
/* interface to libsectok */
static int
@@ -126,8 +147,7 @@ sc_read_pubkey(Key * k)
n = NULL;
if (sc_fd < 0) {
- status = sc_init();
- if (status < 0 )
+ if (sc_init() < 0)
goto err;
}
@@ -145,6 +165,12 @@ sc_read_pubkey(Key * k)
n = xmalloc(len);
/* get n */
sectok_apdu(sc_fd, CLA_SSH, INS_GET_PUBKEY, 0, 0, 0, NULL, len, n, &sw);
+
+ if (sw == 0x6982) {
+ if (try_AUT0() < 0)
+ goto err;
+ 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;
@@ -178,7 +204,8 @@ err:
/* private key operations */
static int
-sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding)
+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;
@@ -197,16 +224,15 @@ sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding)
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_DECRYPT, 0, 0, len, from, len, padded, &sw);
+
+ if (sw == 0x6982) {
+ if (try_AUT0() < 0)
+ goto err;
+ sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, from, len, padded, &sw);
}
- 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",
+ error("sc_private_decrypt: INS_DECRYPT failed: %s",
sectok_get_sw(sw));
goto err;
}
@@ -220,7 +246,8 @@ err:
}
static int
-sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding)
+sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa,
+ int padding)
{
u_char *padded = NULL;
int sw, len, status = -1;
@@ -238,20 +265,18 @@ sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding)
len = BN_num_bytes(rsa->n);
padded = xmalloc(len);
- if (RSA_padding_add_PKCS1_type_1(padded, len, from, flen) <= 0) {
+ if (RSA_padding_add_PKCS1_type_1(padded, len, (u_char *)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_DECRYPT, 0, 0, len, padded, len, to, &sw);
+ if (sw == 0x6982) {
+ if (try_AUT0() < 0)
+ goto err;
+ sectok_apdu(sc_fd, CLA_SSH, INS_DECRYPT, 0, 0, len, padded, len, to, &sw);
}
- 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",
+ error("sc_private_encrypt: INS_DECRYPT failed: %s",
sectok_get_sw(sw));
goto err;
}
@@ -275,31 +300,18 @@ sc_finish(RSA *rsa)
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)
+static RSA_METHOD *
+sc_get_rsa_method(void)
{
- RSA_METHOD *def;
+ static RSA_METHOD smart_rsa;
+ const RSA_METHOD *def = RSA_get_default_method();
+
+ /* use the OpenSSL version */
+ memcpy(&smart_rsa, def, sizeof(smart_rsa));
- def = RSA_get_default_openssl_method();
+ smart_rsa.name = "sectok";
/* overload */
smart_rsa.rsa_priv_enc = sc_private_encrypt;
@@ -309,23 +321,22 @@ sc_get_engine(void)
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;
+ return &smart_rsa;
+}
+
+#ifdef USE_ENGINE
+static ENGINE *
+sc_get_engine(void)
+{
+ static ENGINE *smart_engine = NULL;
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_RSA(smart_engine, sc_get_rsa_method());
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());
@@ -333,6 +344,7 @@ sc_get_engine(void)
return smart_engine;
}
+#endif
void
sc_close(void)
@@ -343,16 +355,20 @@ sc_close(void)
}
}
-Key *
-sc_get_key(const char *id)
+Key **
+sc_get_keys(const char *id, const char *pin)
{
- Key *k;
- int status;
+ Key *k, *n, **keys;
+ int status, nkeys = 2;
if (sc_reader_id != NULL)
xfree(sc_reader_id);
sc_reader_id = xstrdup(id);
+ if (sc_pin != NULL)
+ xfree(sc_pin);
+ sc_pin = (pin == NULL) ? NULL : xstrdup(pin);
+
k = key_new(KEY_RSA);
if (k == NULL) {
return NULL;
@@ -367,6 +383,175 @@ sc_get_key(const char *id)
key_free(k);
return NULL;
}
- return k;
+ keys = xmalloc((nkeys+1) * sizeof(Key *));
+
+ n = key_new(KEY_RSA1);
+ BN_copy(n->rsa->n, k->rsa->n);
+ BN_copy(n->rsa->e, k->rsa->e);
+ RSA_set_method(n->rsa, sc_get_rsa());
+ n->flags |= KEY_FLAG_EXT;
+ keys[0] = n;
+
+ n = key_new(KEY_RSA);
+ BN_copy(n->rsa->n, k->rsa->n);
+ BN_copy(n->rsa->e, k->rsa->e);
+ RSA_set_method(n->rsa, sc_get_rsa());
+ n->flags |= KEY_FLAG_EXT;
+ keys[1] = n;
+
+ keys[2] = NULL;
+
+ key_free(k);
+ return keys;
+}
+
+#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 void
+sc_mk_digest(const char *pin, u_char *digest)
+{
+ const EVP_MD *evp_md = EVP_sha1();
+ EVP_MD_CTX md;
+
+ EVP_DigestInit(&md, evp_md);
+ EVP_DigestUpdate(&md, pin, strlen(pin));
+ EVP_DigestFinal(&md, digest, NULL);
+}
+
+static int
+get_AUT0(u_char *aut0)
+{
+ char *pass;
+
+ pass = read_passphrase("Enter passphrase for smartcard: ", RP_ALLOW_STDIN);
+ if (pass == NULL)
+ return -1;
+ if (!strcmp(pass, "-")) {
+ memcpy(aut0, DEFAUT0, sizeof DEFAUT0);
+ return 0;
+ }
+ sc_mk_digest(pass, aut0);
+ memset(pass, 0, strlen(pass));
+ xfree(pass);
+ return 0;
+}
+
+static int
+try_AUT0(void)
+{
+ u_char aut0[EVP_MAX_MD_SIZE];
+
+ /* permission denied; try PIN if provided */
+ if (sc_pin && strlen(sc_pin) > 0) {
+ sc_mk_digest(sc_pin, aut0);
+ if (cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) {
+ error("smartcard passphrase incorrect");
+ return (-1);
+ }
+ } else {
+ /* try default AUT0 key */
+ if (cyberflex_verify_AUT0(sc_fd, cla, DEFAUT0, 8) < 0) {
+ /* default AUT0 key failed; prompt for passphrase */
+ if (get_AUT0(aut0) < 0 ||
+ cyberflex_verify_AUT0(sc_fd, cla, aut0, 8) < 0) {
+ error("smartcard passphrase incorrect");
+ return (-1);
+ }
+ }
+ }
+ return (0);
+}
+
+int
+sc_put_key(Key *prv, const char *id)
+{
+ u_char *elements[NUM_RSA_KEY_ELEMENTS];
+ u_char key_fid[2];
+ 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;
+
+ 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(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", 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) {
+ memset(AUT0, 0, sizeof(DEFAUT0));
+ error("smartcard passphrase incorrect");
+ goto done;
+ }
+ }
+ memset(AUT0, 0, sizeof(DEFAUT0));
+ 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;
+
+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));
+
+ for (i = 0; i < NUM_RSA_KEY_ELEMENTS; i++)
+ if (elements[i])
+ xfree(elements[i]);
+ if (fd != -1)
+ sectok_close(fd);
+ return (status);
}
#endif /* SMARTCARD */
diff --git a/crypto/openssh/scard.h b/crypto/openssh/scard.h
index 6ca9916..c0aa9ed 100644
--- a/crypto/openssh/scard.h
+++ b/crypto/openssh/scard.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: scard.h,v 1.7 2002/03/04 17:27:39 stevesk Exp $ */
+/* $OpenBSD: scard.h,v 1.10 2002/03/25 17:34:27 markus Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -24,17 +24,17 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <openssl/engine.h>
-
#ifndef SCARD_H
#define SCARD_H
+#include "key.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);
+Key **sc_get_keys(const char*, const char*);
void sc_close(void);
+int sc_put_key(Key *, const char*);
#endif
diff --git a/crypto/openssh/scard/Ssh.bin.uu b/crypto/openssh/scard/Ssh.bin.uu
index 1062e21..ea3986a 100644
--- a/crypto/openssh/scard/Ssh.bin.uu
+++ b/crypto/openssh/scard/Ssh.bin.uu
@@ -1,16 +1,17 @@
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````````
+M`P)!&P`801X`>``!`E@"`/Y@\`4`_J'P!0!!&T$=`?Z@\`4`01M!'`'^>/,!
+M`4$;01X!_G#S%P'^0],1`?Y@\!0`_G/S'0#^<]4``D$;L`4`_F'3``#^8=,%
+M`/ZAT`$!_J#0)P'^H],*`?ZCTPD`_G/5"P7^8=,'`OZAT`H`_J#0$@3^:-,@
+M`T$;`P`%`/Y@`<P``$$<\@\``$$=\B$``$$>\A```/`0__(%`@8!`0H``&``
+M0205!!D)I$L`"0J0`&``*!4$&58``````.P````%____P````.D````0````
+M,P```"````#'````,````(T````R````V!4#&0A*``D*;@!@`"@5!QD*`/\]
+M(6``1A)*``D*9P!@`"@*/P!@`$LK"1)@`$LK!6``4!P$#00#2@`.#01@`%5@
+M`%I@`"@37``>%0@2%0A>`%\($F``9%(`:`H_`&``2RL*<VA@`$LK8`!I"1`U
+M(14#`Q)@`&X<!`T$`TL`"P,28`!D4@`.#01@`%5@`%I@`"A2`"X5`PH$`&``
+M<RL#!6``9%(`'14#"@$"8`!S*P,%8`!D4@`,4@`)"FT`8``H60``\`+_\@$!
+M`0D`"```"I``8``H60#P$__R`0$""0`,``!B01LM7P`\*UD```#P$O_V`0$#
+M`0`8```37``>7@`R10`/$UP`'@H`R`D07@`W!%>P!?_R`0$$`@`\```37P``
+M$V+^H2U?``5=``H38OZ@+5\`#UT`%!-B_G@M"@0`7P`970`>"@0`8``C10`)
+/"F<`8``H$UX`+5D`````
`
end
diff --git a/crypto/openssh/scard/Ssh.java b/crypto/openssh/scard/Ssh.java
index 3692b9b..1f2ae58 100644
--- a/crypto/openssh/scard/Ssh.java
+++ b/crypto/openssh/scard/Ssh.java
@@ -1,4 +1,4 @@
-// $Id: Ssh.java,v 1.2 2001/07/30 20:08:14 rees Exp $
+// $Id: Ssh.java,v 1.3 2002/03/21 22:44:05 rees Exp $
//
// Ssh.java
// SSH / smartcard integration project, smartcard side
@@ -42,6 +42,9 @@ import javacardx.crypto.*;
public class Ssh extends javacard.framework.Applet
{
+ // Change this when the applet changes; hi byte is major, low byte is minor
+ static final short applet_version = (short)0x0102;
+
/* constants declaration */
// code of CLA byte in the command APDU header
static final byte Ssh_CLA =(byte)0x05;
@@ -50,20 +53,19 @@ public class Ssh extends javacard.framework.Applet
static final byte DECRYPT = (byte) 0x10;
static final byte GET_KEYLENGTH = (byte) 0x20;
static final byte GET_PUBKEY = (byte) 0x30;
+ static final byte GET_VERSION = (byte) 0x32;
static final byte GET_RESPONSE = (byte) 0xc0;
- /* instance variables declaration */
static final short keysize = 1024;
+ static final short root_fid = (short)0x3f00;
+ static final short privkey_fid = (short)0x0012;
+ static final short pubkey_fid = (short)(('s'<<8)|'h');
- //RSA_CRT_PrivateKey rsakey;
+ /* instance variables declaration */
AsymKey rsakey;
CyberflexFile file;
CyberflexOS os;
- byte buffer[];
-
- static byte[] keyHdr = {(byte)0xC2, (byte)0x01, (byte)0x05};
-
private Ssh()
{
file = new CyberflexFile();
@@ -98,7 +100,8 @@ public class Ssh extends javacard.framework.Applet
// APDU object carries a byte array (buffer) to
// transfer incoming and outgoing APDU header
// and data bytes between card and CAD
- buffer = apdu.getBuffer();
+ byte buffer[] = apdu.getBuffer();
+ short size, st;
// verify that if the applet can accept this
// APDU message
@@ -111,29 +114,47 @@ public class Ssh extends javacard.framework.Applet
if (buffer[ISO.OFFSET_CLA] != Ssh_CLA)
ISOException.throwIt(ISO.SW_CLA_NOT_SUPPORTED);
//decrypt (apdu);
- short size = (short) (buffer[ISO.OFFSET_LC] & 0x00FF);
+ size = (short) (buffer[ISO.OFFSET_LC] & 0x00FF);
if (apdu.setIncomingAndReceive() != size)
ISOException.throwIt (ISO.SW_WRONG_LENGTH);
+ // check access; depends on bit 2 (x/a)
+ file.selectFile(root_fid);
+ file.selectFile(privkey_fid);
+ st = os.checkAccess(ACL.EXECUTE);
+ if (st != ST.ACCESS_CLEARED) {
+ CyberflexAPDU.prepareSW1SW2(st);
+ ISOException.throwIt(CyberflexAPDU.getSW1SW2());
+ }
+
rsakey.cryptoUpdate (buffer, (short) ISO.OFFSET_CDATA, size,
buffer, (short) ISO.OFFSET_CDATA);
apdu.setOutgoingAndSend ((short) ISO.OFFSET_CDATA, size);
- return;
+ break;
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;
+ file.selectFile(root_fid); // select root
+ file.selectFile(pubkey_fid); // select public key file
+ size = (short)(file.getFileSize() - 16);
+ st = os.readBinaryFile(buffer, (short)0, (short)0, size);
+ if (st == ST.SUCCESS)
+ apdu.setOutgoingAndSend((short)0, size);
+ else {
+ CyberflexAPDU.prepareSW1SW2(st);
+ ISOException.throwIt(CyberflexAPDU.getSW1SW2());
+ }
+ break;
case GET_KEYLENGTH:
- buffer[0] = (byte)((keysize >> 8) & 0xff);
- buffer[1] = (byte)(keysize & 0xff);
+ Util.setShort(buffer, (short)0, keysize);
+ apdu.setOutgoingAndSend ((short)0, (short)2);
+ break;
+ case GET_VERSION:
+ Util.setShort(buffer, (short)0, applet_version);
apdu.setOutgoingAndSend ((short)0, (short)2);
- return;
+ break;
case GET_RESPONSE:
- return;
+ break;
default:
ISOException.throwIt (ISO.SW_INS_NOT_SUPPORTED);
}
diff --git a/crypto/openssh/scp.1 b/crypto/openssh/scp.1
index 69125c1..c0caff4 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.21 2002/01/29 23:50:37 markus Exp $
+.\" $OpenBSD: scp.1,v 1.22 2002/06/20 20:00:05 stevesk Exp $
.\"
.Dd September 25, 1999
.Dt SCP 1
@@ -117,9 +117,9 @@ options.
.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
+in the format used in
+.Xr ssh_config 5 .
+This is useful for specifying options
for which there is no separate
.Nm scp
command-line flag. For example, forcing the use of protocol
@@ -152,4 +152,5 @@ California.
.Xr ssh-add 1 ,
.Xr ssh-agent 1 ,
.Xr ssh-keygen 1 ,
+.Xr ssh_config 5
.Xr sshd 8
diff --git a/crypto/openssh/scp.c b/crypto/openssh/scp.c
index 159e4bb..e2a085c 100644
--- a/crypto/openssh/scp.c
+++ b/crypto/openssh/scp.c
@@ -75,7 +75,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: scp.c,v 1.86 2001/12/05 03:56:39 itojun Exp $");
+RCSID("$OpenBSD: scp.c,v 1.91 2002/06/19 00:27:55 deraadt Exp $");
#include "xmalloc.h"
#include "atomicio.h"
@@ -219,10 +219,9 @@ main(argc, argv)
extern int optind;
args.list = NULL;
- addargs(&args, "ssh"); /* overwritten with ssh_program */
+ 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;
@@ -354,8 +353,7 @@ toremote(targ, argc, argv)
src = colon(argv[i]);
if (src) { /* remote to remote */
static char *ssh_options =
- "-x -o'FallBackToRsh no' "
- "-o'ClearAllForwardings yes'";
+ "-x -o'ClearAllForwardings yes'";
*src++ = 0;
if (*src == 0)
src = ".";
@@ -756,7 +754,7 @@ sink(argc, argv)
cursize = need;
}
(void) snprintf(namebuf, need, "%s%s%s", targ,
- *targ ? "/" : "", cp);
+ strcmp(targ, "/") ? "/" : "", cp);
np = namebuf;
} else
np = targ;
@@ -931,9 +929,9 @@ void
usage(void)
{
(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");
+ "usage: scp [-pqrvBC46] [-F config] [-S program] [-P port]\n"
+ " [-c cipher] [-i identity] [-o option]\n"
+ " [[user@]host1:]file1 [...] [[user@]host2:]file2\n");
exit(1);
}
@@ -1073,7 +1071,7 @@ progressmeter(int flag)
off_t cursize, abbrevsize;
double elapsed;
int ratio, barlength, i, remaining;
- char buf[256];
+ char buf[512];
if (flag == -1) {
(void) gettimeofday(&start, (struct timezone *) 0);
@@ -1099,10 +1097,13 @@ progressmeter(int flag)
i = barlength * ratio / 100;
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),
"|%.*s%*s|", i,
- "***************************************"
- "***************************************"
- "***************************************"
- "***************************************",
+ "*******************************************************"
+ "*******************************************************"
+ "*******************************************************"
+ "*******************************************************"
+ "*******************************************************"
+ "*******************************************************"
+ "*******************************************************",
barlength - i, "");
}
i = 0;
diff --git a/crypto/openssh/session.h b/crypto/openssh/session.h
index ec8284a..2a7e4b2 100644
--- a/crypto/openssh/session.h
+++ b/crypto/openssh/session.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: session.h,v 1.14 2002/02/03 17:53:25 markus Exp $ */
+/* $OpenBSD: session.h,v 1.17 2002/03/29 18:59:32 markus Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@@ -26,12 +26,46 @@
#ifndef SESSION_H
#define SESSION_H
+#define TTYSZ 64
+typedef struct Session Session;
+struct Session {
+ int used;
+ int self;
+ struct passwd *pw;
+ Authctxt *authctxt;
+ pid_t pid;
+ /* tty */
+ char *term;
+ int ptyfd, ttyfd, ptymaster;
+ int row, col, xpixel, ypixel;
+ char tty[TTYSZ];
+ /* last login */
+ char hostname[MAXHOSTNAMELEN];
+ time_t last_login_time;
+ /* X11 */
+ int display_number;
+ char *display;
+ int screen;
+ char *auth_display;
+ char *auth_proto;
+ char *auth_data;
+ int single_connection;
+ /* proto 2 */
+ int chanid;
+ int is_subsystem;
+};
+
void do_authenticated(Authctxt *);
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);
+void session_destroy_all(void (*)(Session *));
+void session_pty_cleanup2(void *);
+Session *session_new(void);
+Session *session_by_tty(char *);
+void session_close(Session *);
+void do_setusercontext(struct passwd *);
#endif
diff --git a/crypto/openssh/sftp-client.c b/crypto/openssh/sftp-client.c
index 10ac13d..fb3d166 100644
--- a/crypto/openssh/sftp-client.c
+++ b/crypto/openssh/sftp-client.c
@@ -28,7 +28,7 @@
/* XXX: copy between two remote sites */
#include "includes.h"
-RCSID("$OpenBSD: sftp-client.c,v 1.24 2002/02/24 16:57:19 markus Exp $");
+RCSID("$OpenBSD: sftp-client.c,v 1.32 2002/06/09 13:32:01 markus Exp $");
#include <sys/queue.h>
@@ -270,7 +270,7 @@ do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests)
/* Some filexfer v.0 servers don't support large packets */
if (version == 0)
- ret->transfer_buflen = MAX(ret->transfer_buflen, 20480);
+ ret->transfer_buflen = MIN(ret->transfer_buflen, 20480);
return(ret);
}
@@ -445,7 +445,7 @@ do_rm(struct sftp_conn *conn, char *path)
debug2("Sending SSH2_FXP_REMOVE \"%s\"", path);
id = conn->msg_id++;
- send_string_request(conn->fd_out, id, SSH2_FXP_REMOVE, path,
+ 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)
@@ -492,8 +492,8 @@ do_stat(struct sftp_conn *conn, char *path, int quiet)
id = conn->msg_id++;
- send_string_request(conn->fd_out, id,
- conn->version == 0 ? SSH2_FXP_STAT_VERSION_0 : SSH2_FXP_STAT,
+ 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));
@@ -508,8 +508,8 @@ do_lstat(struct sftp_conn *conn, char *path, int quiet)
if (quiet)
debug("Server version does not support lstat operation");
else
- error("Server version does not support lstat operation");
- return(NULL);
+ log("Server version does not support lstat operation");
+ return(do_stat(conn, path, quiet));
}
id = conn->msg_id++;
@@ -723,7 +723,7 @@ 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);
@@ -733,7 +733,7 @@ send_read_request(int fd_out, u_int id, u_int64_t offset, u_int len,
buffer_put_int(&msg, len);
send_msg(fd_out, &msg);
buffer_free(&msg);
-}
+}
int
do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
@@ -750,7 +750,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
u_int id;
u_int len;
u_int64_t offset;
- TAILQ_ENTRY(request) tq;
+ TAILQ_ENTRY(request) tq;
};
TAILQ_HEAD(reqhead, request) requests;
struct request *req;
@@ -816,8 +816,10 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
/* Send some more requests */
while (num_req < max_req) {
- debug3("Request range %llu -> %llu (%d/%d)",
- offset, offset + buflen - 1, num_req, max_req);
+ debug3("Request range %llu -> %llu (%d/%d)",
+ (unsigned long long)offset,
+ (unsigned long long)offset + buflen - 1,
+ num_req, max_req);
req = xmalloc(sizeof(*req));
req->id = conn->msg_id++;
req->len = buflen;
@@ -825,7 +827,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
offset += buflen;
num_req++;
TAILQ_INSERT_TAIL(&requests, req, tq);
- send_read_request(conn->fd_out, req->id, req->offset,
+ send_read_request(conn->fd_out, req->id, req->offset,
req->len, handle, handle_len);
}
@@ -855,8 +857,9 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
break;
case SSH2_FXP_DATA:
data = buffer_get_string(&msg, &len);
- debug3("Received data %llu -> %llu", req->offset,
- req->offset + len - 1);
+ debug3("Received data %llu -> %llu",
+ (unsigned long long)req->offset,
+ (unsigned long long)req->offset + len - 1);
if (len > req->len)
fatal("Received more data than asked for "
"%d > %d", len, req->len);
@@ -876,12 +879,14 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
} 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);
+ "%llu -> %llu (%2d)",
+ (unsigned long long)req->offset + len,
+ (unsigned long long)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,
+ send_read_request(conn->fd_out, req->id,
req->offset, req->len, handle, handle_len);
/* Reduce the request size */
if (len < buflen)
@@ -892,7 +897,8 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
/* Only one request at a time
* after the expected EOF */
debug3("Finish at %llu (%2d)",
- offset, num_req);
+ (unsigned long long)offset,
+ num_req);
max_req = 1;
}
else if (max_req < conn->num_requests + 1) {
@@ -911,7 +917,7 @@ do_download(struct sftp_conn *conn, char *remote_path, char *local_path,
fatal("Transfer complete, but requests still in queue");
if (read_error) {
- error("Couldn't read from remote file \"%s\" : %s",
+ error("Couldn't read from remote file \"%s\" : %s",
remote_path, fx2txt(status));
do_close(conn, handle, handle_len);
} else if (write_error) {
@@ -960,7 +966,7 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
u_int id;
u_int len;
u_int64_t offset;
- TAILQ_ENTRY(outstanding_ack) tq;
+ TAILQ_ENTRY(outstanding_ack) tq;
};
TAILQ_HEAD(ackhead, outstanding_ack) acks;
struct outstanding_ack *ack;
@@ -1042,19 +1048,21 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
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);
+ id, (unsigned long long)offset, len);
} else if (TAILQ_FIRST(&acks) == NULL)
break;
if (ack == NULL)
fatal("Unexpected ACK %u", id);
- if (id == startid || len == 0 ||
+ if (id == startid || len == 0 ||
id - ackid >= conn->num_requests) {
+ u_int r_id;
+
buffer_clear(&msg);
get_msg(conn->fd_in, &msg);
type = buffer_get_char(&msg);
- id = buffer_get_int(&msg);
+ r_id = buffer_get_int(&msg);
if (type != SSH2_FXP_STATUS)
fatal("Expected SSH2_FXP_STATUS(%d) packet, "
@@ -1065,11 +1073,11 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
/* Find the request in our queue */
for(ack = TAILQ_FIRST(&acks);
- ack != NULL && ack->id != id;
+ ack != NULL && ack->id != r_id;
ack = TAILQ_NEXT(ack, tq))
;
if (ack == NULL)
- fatal("Can't find request for ID %d", id);
+ fatal("Can't find request for ID %d", r_id);
TAILQ_REMOVE(&acks, ack, tq);
if (status != SSH2_FX_OK) {
@@ -1079,8 +1087,8 @@ do_upload(struct sftp_conn *conn, char *local_path, char *remote_path,
close(local_fd);
goto done;
}
- debug3("In write loop, ack for %u %d bytes at %llu",
- ack->id, ack->len, ack->offset);
+ debug3("In write loop, ack for %u %d bytes at %llu",
+ ack->id, ack->len, (unsigned long long)ack->offset);
++ackid;
free(ack);
}
diff --git a/crypto/openssh/sftp-glob.h b/crypto/openssh/sftp-glob.h
index 488b0a8..9c75491 100644
--- a/crypto/openssh/sftp-glob.h
+++ b/crypto/openssh/sftp-glob.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sftp-glob.h,v 1.6 2002/02/13 00:59:23 djm Exp $ */
+/* $OpenBSD: sftp-glob.h,v 1.7 2002/03/19 10:49:35 markus Exp $ */
/*
* Copyright (c) 2001,2002 Damien Miller. All rights reserved.
@@ -32,7 +32,7 @@
#include "sftp-client.h"
int
-remote_glob(struct sftp_conn *, const char *, int,
+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 d986c76..d433141 100644
--- a/crypto/openssh/sftp-int.c
+++ b/crypto/openssh/sftp-int.c
@@ -26,7 +26,7 @@
/* XXX: recursive operations */
#include "includes.h"
-RCSID("$OpenBSD: sftp-int.c,v 1.44 2002/02/13 00:59:23 djm Exp $");
+RCSID("$OpenBSD: sftp-int.c,v 1.46 2002/03/30 18:51:15 markus Exp $");
#include <glob.h>
@@ -178,8 +178,9 @@ local_do_shell(const char *args)
strerror(errno));
_exit(1);
}
- if (waitpid(pid, &status, 0) == -1)
- fatal("Couldn't wait for child: %s", strerror(errno));
+ while (waitpid(pid, &status, 0) == -1)
+ if (errno != EINTR)
+ fatal("Couldn't wait for child: %s", strerror(errno));
if (!WIFEXITED(status))
error("Shell exited abormally");
else if (WEXITSTATUS(status))
@@ -888,8 +889,10 @@ interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
file2);
parse_dispatch_command(conn, cmd, &pwd);
+ xfree(dir);
return;
}
+ xfree(dir);
}
setvbuf(stdout, NULL, _IOLBF, 0);
setvbuf(infile, NULL, _IOLBF, 0);
diff --git a/crypto/openssh/sftp-server.c b/crypto/openssh/sftp-server.c
index b98c5ff..27f33bd 100644
--- a/crypto/openssh/sftp-server.c
+++ b/crypto/openssh/sftp-server.c
@@ -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.33 2002/02/13 00:28:13 markus Exp $");
+RCSID("$OpenBSD: sftp-server.c,v 1.35 2002/06/06 17:30:11 markus Exp $");
#include "buffer.h"
#include "bufaux.h"
@@ -362,7 +362,7 @@ process_init(void)
{
Buffer msg;
- version = buffer_get_int(&iqueue);
+ version = get_int();
TRACE("client version %d", version);
buffer_init(&msg);
buffer_put_char(&msg, SSH2_FXP_VERSION);
@@ -936,10 +936,13 @@ static void
process(void)
{
u_int msg_len;
+ u_int buf_len;
+ u_int consumed;
u_int type;
u_char *cp;
- if (buffer_len(&iqueue) < 5)
+ buf_len = buffer_len(&iqueue);
+ if (buf_len < 5)
return; /* Incomplete message. */
cp = buffer_ptr(&iqueue);
msg_len = GET_32BIT(cp);
@@ -947,9 +950,10 @@ process(void)
error("bad message ");
exit(11);
}
- if (buffer_len(&iqueue) < msg_len + 4)
+ if (buf_len < msg_len + 4)
return;
buffer_consume(&iqueue, 4);
+ buf_len -= 4;
type = buffer_get_char(&iqueue);
switch (type) {
case SSH2_FXP_INIT:
@@ -1016,6 +1020,14 @@ process(void)
error("Unknown message %d", type);
break;
}
+ /* discard the remaining bytes from the current packet */
+ if (buf_len < buffer_len(&iqueue))
+ fatal("iqueue grows");
+ consumed = buf_len - buffer_len(&iqueue);
+ if (msg_len < consumed)
+ fatal("msg_len %d < consumed %d", msg_len, consumed);
+ if (msg_len > consumed)
+ buffer_consume(&iqueue, msg_len - consumed);
}
int
diff --git a/crypto/openssh/sftp.1 b/crypto/openssh/sftp.1
index 2faaff1..0e6d741 100644
--- a/crypto/openssh/sftp.1
+++ b/crypto/openssh/sftp.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sftp.1,v 1.33 2002/02/26 19:06:43 deraadt Exp $
+.\" $OpenBSD: sftp.1,v 1.35 2002/06/20 20:00:05 stevesk Exp $
.\"
.\" Copyright (c) 2001 Damien Miller. All rights reserved.
.\"
@@ -83,9 +83,9 @@ and
.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
+in the format used in
+.Xr ssh_config 5 .
+This is useful for specifying options
for which there is no separate
.Nm sftp
command-line flag. For example, to specify an alternate
@@ -100,7 +100,7 @@ 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
+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.
@@ -115,13 +115,13 @@ per-user configuration file for
This option is directly passed to
.Xr ssh 1 .
.It Fl P Ar sftp_server path
-Connect directly to a local
-.Nm sftp-server
+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
+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
@@ -263,6 +263,7 @@ Damien Miller <djm@mindrot.org>
.Xr ssh 1 ,
.Xr ssh-add 1 ,
.Xr ssh-keygen 1 ,
+.Xr ssh_config 5 ,
.Xr sftp-server 8 ,
.Xr sshd 8
.Rs
diff --git a/crypto/openssh/sftp.c b/crypto/openssh/sftp.c
index 0a7689c..ddc7530 100644
--- a/crypto/openssh/sftp.c
+++ b/crypto/openssh/sftp.c
@@ -24,7 +24,7 @@
#include "includes.h"
-RCSID("$OpenBSD: sftp.c,v 1.26 2002/02/12 12:32:27 djm Exp $");
+RCSID("$OpenBSD: sftp.c,v 1.29 2002/04/02 17:37:48 markus Exp $");
/* XXX: short-form remote directory listings (like 'ls -C') */
@@ -88,7 +88,7 @@ static void
usage(void)
{
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"
@@ -165,7 +165,7 @@ main(int argc, char **argv)
case 'R':
num_requests = strtol(optarg, &cp, 10);
if (num_requests == 0 || *cp != '\0')
- fatal("Invalid number of requests \"%s\"",
+ fatal("Invalid number of requests \"%s\"",
optarg);
break;
case 'h':
@@ -174,6 +174,8 @@ main(int argc, char **argv)
}
}
+ log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
+
if (sftp_direct == NULL) {
if (optind == argc || argc > (optind + 2))
usage();
@@ -203,7 +205,6 @@ main(int argc, char **argv)
usage();
}
- log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
addargs(&args, "-oProtocol %d", sshver);
/* no subsystem if the server-spec contains a '/' */
@@ -211,19 +212,19 @@ main(int argc, char **argv)
addargs(&args, "-s");
addargs(&args, "%s", host);
- addargs(&args, "%s", (sftp_server != NULL ?
+ addargs(&args, "%s", (sftp_server != NULL ?
sftp_server : "sftp"));
args.list[0] = ssh_program;
fprintf(stderr, "Connecting to %s...\n", host);
- connect_to_server(ssh_program, args.list, &in, &out,
+ connect_to_server(ssh_program, args.list, &in, &out,
&sshpid);
} else {
args.list = NULL;
addargs(&args, "sftp-server");
fprintf(stderr, "Attaching to %s...\n", sftp_direct);
- connect_to_server(sftp_direct, args.list, &in, &out,
+ connect_to_server(sftp_direct, args.list, &in, &out,
&sshpid);
}
@@ -234,8 +235,10 @@ main(int argc, char **argv)
if (infile != stdin)
fclose(infile);
- if (waitpid(sshpid, NULL, 0) == -1)
- fatal("Couldn't wait for ssh process: %s", strerror(errno));
+ while (waitpid(sshpid, NULL, 0) == -1)
+ if (errno != EINTR)
+ fatal("Couldn't wait for ssh process: %s",
+ strerror(errno));
exit(0);
}
diff --git a/crypto/openssh/ssh-add.1 b/crypto/openssh/ssh-add.1
index 41d5def..2a34a51 100644
--- a/crypto/openssh/ssh-add.1
+++ b/crypto/openssh/ssh-add.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-add.1,v 1.30 2002/02/04 20:41:16 stevesk Exp $
+.\" $OpenBSD: ssh-add.1,v 1.35 2002/06/19 00:27:55 deraadt Exp $
.\"
.\" -*- nroff -*-
.\"
@@ -45,7 +45,8 @@
.Nd adds RSA or DSA identities to the authentication agent
.Sh SYNOPSIS
.Nm ssh-add
-.Op Fl lLdD
+.Op Fl lLdDxX
+.Op Fl t Ar life
.Op Ar
.Nm ssh-add
.Fl s Ar reader
@@ -57,7 +58,7 @@ adds RSA or DSA identities to the authentication agent,
.Xr ssh-agent 1 .
When run without arguments, it adds the files
.Pa $HOME/.ssh/id_rsa ,
-.Pa $HOME/.ssh/id_dsa
+.Pa $HOME/.ssh/id_dsa
and
.Pa $HOME/.ssh/identity .
Alternative file names can be given on the command line.
@@ -83,6 +84,15 @@ 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 x
+Lock the agent with a password.
+.It Fl X
+Unlock the agent.
+.It Fl t Ar life
+Set a maximum lifetime when adding identities to an agent.
+The lifetime may be specified in seconds or in a time format
+specified in
+.Xr sshd 8 .
.It Fl s Ar reader
Add key in smartcard
.Ar reader .
@@ -129,6 +139,9 @@ or related script.
may be necessary to redirect the input from
.Pa /dev/null
to make this work.)
+.It Ev SSH_AUTH_SOCK
+Identifies the path of a unix-domain socket used to communicate with the
+agent.
.El
.Sh DIAGNOSTICS
Exit status is 0 on success, 1 if the specified command fails,
diff --git a/crypto/openssh/ssh-agent.1 b/crypto/openssh/ssh-agent.1
index 9909ef5..e5ea1e3 100644
--- a/crypto/openssh/ssh-agent.1
+++ b/crypto/openssh/ssh-agent.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-agent.1,v 1.31 2002/02/04 20:41:16 stevesk Exp $
+.\" $OpenBSD: ssh-agent.1,v 1.33 2002/06/19 00:27:55 deraadt Exp $
.\"
.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -42,6 +42,7 @@
.Nd authentication agent
.Sh SYNOPSIS
.Nm ssh-agent
+.Op Fl a Ar bind_address
.Op Fl c Li | Fl s
.Op Fl d
.Op Ar command Op Ar args ...
@@ -64,6 +65,11 @@ machines using
.Pp
The options are as follows:
.Bl -tag -width Ds
+.It Fl a Ar bind_address
+Bind the agent to the unix-domain socket
+.Ar bind_address .
+The default is
+.Pa /tmp/ssh-XXXXXXXX/agent.<pid> .
.It Fl c
Generate C-shell commands on
.Dv stdout .
@@ -96,7 +102,7 @@ When executed without arguments,
.Xr ssh-add 1
adds the files
.Pa $HOME/.ssh/id_rsa ,
-.Pa $HOME/.ssh/id_dsa
+.Pa $HOME/.ssh/id_dsa
and
.Pa $HOME/.ssh/identity .
If the identity has a passphrase,
@@ -135,7 +141,6 @@ 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
.Ev SSH_AUTH_SOCK
environment
diff --git a/crypto/openssh/ssh-keygen.1 b/crypto/openssh/ssh-keygen.1
index 6ad94e6..35b0bb9 100644
--- a/crypto/openssh/ssh-keygen.1
+++ b/crypto/openssh/ssh-keygen.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: ssh-keygen.1,v 1.53 2002/02/16 14:53:37 stevesk Exp $
+.\" $OpenBSD: ssh-keygen.1,v 1.54 2002/06/19 00:27:55 deraadt Exp $
.\"
.\" -*- nroff -*-
.\"
@@ -86,7 +86,7 @@
generates, manages and converts authentication keys for
.Xr ssh 1 .
.Nm
-can create RSA keys for use by SSH protocol version 1 and RSA or DSA
+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
diff --git a/crypto/openssh/ssh-keygen.c b/crypto/openssh/ssh-keygen.c
index 961fad6..66f00cc 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.94 2002/02/25 16:33:27 markus Exp $");
+RCSID("$OpenBSD: ssh-keygen.c,v 1.100 2002/06/19 00:27:55 deraadt Exp $");
#include <openssl/evp.h>
#include <openssl/pem.h>
@@ -29,8 +29,6 @@ RCSID("$OpenBSD: ssh-keygen.c,v 1.94 2002/02/25 16:33:27 markus Exp $");
#include "readpass.h"
#ifdef SMARTCARD
-#include <sectok.h>
-#include <openssl/engine.h>
#include "scard.h"
#endif
@@ -138,7 +136,7 @@ load_identity(char *filename)
}
#define SSH_COM_PUBLIC_BEGIN "---- BEGIN SSH2 PUBLIC KEY ----"
-#define SSH_COM_PUBLIC_END "---- END SSH2 PUBLIC KEY ----"
+#define SSH_COM_PUBLIC_END "---- END SSH2 PUBLIC KEY ----"
#define SSH_COM_PRIVATE_BEGIN "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"
#define SSH_COM_PRIVATE_KEY_MAGIC 0x3f6ff9eb
@@ -288,6 +286,7 @@ do_convert_from_ssh2(struct passwd *pw)
{
Key *k;
int blen;
+ u_int len;
char line[1024], *p;
u_char blob[8096];
char encoded[8096];
@@ -332,6 +331,12 @@ do_convert_from_ssh2(struct passwd *pw)
*p = '\0';
strlcat(encoded, line, sizeof(encoded));
}
+ len = strlen(encoded);
+ if (((len % 4) == 3) &&
+ (encoded[len-1] == '=') &&
+ (encoded[len-2] == '=') &&
+ (encoded[len-3] == '='))
+ encoded[len-3] = '\0';
blen = uudecode(encoded, blob, sizeof(blob));
if (blen < 0) {
fprintf(stderr, "uudecode failed.\n");
@@ -385,145 +390,47 @@ do_print_public(struct passwd *pw)
}
#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;
+ int ret;
+
if (!have_identity)
ask_filename(pw, "Enter file in which the key is");
if (stat(identity_file, &st) < 0) {
perror(identity_file);
- goto done;
+ exit(1);
}
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;
+ exit(1);
}
- if (!sectok_swOK(sw))
- goto done;
- log("cyberflex_load_rsa_pub done");
- status = 0;
+ ret = sc_put_key(prv, sc_reader_id);
+ key_free(prv);
+ if (ret < 0)
+ exit(1);
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);
+ exit(0);
}
static void
do_download(struct passwd *pw, const char *sc_reader_id)
{
- Key *pub = NULL;
+ Key **keys = NULL;
+ int i;
- pub = sc_get_key(sc_reader_id);
- if (pub == NULL)
+ keys = sc_get_keys(sc_reader_id, NULL);
+ if (keys == NULL)
fatal("cannot read public key from smartcard");
- key_write(pub, stdout);
- key_free(pub);
- fprintf(stdout, "\n");
+ for (i = 0; keys[i]; i++) {
+ key_write(keys[i], stdout);
+ key_free(keys[i]);
+ fprintf(stdout, "\n");
+ }
+ xfree(keys);
exit(0);
}
#endif /* SMARTCARD */
diff --git a/crypto/openssh/ssh-keyscan.c b/crypto/openssh/ssh-keyscan.c
index 5fc5330..947f704 100644
--- a/crypto/openssh/ssh-keyscan.c
+++ b/crypto/openssh/ssh-keyscan.c
@@ -7,7 +7,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: ssh-keyscan.c,v 1.35 2002/03/04 18:30:23 stevesk Exp $");
+RCSID("$OpenBSD: ssh-keyscan.c,v 1.36 2002/06/16 21:30:58 itojun Exp $");
#include <sys/queue.h>
#include <errno.h>
@@ -581,7 +581,7 @@ conloop(void)
con *c;
gettimeofday(&now, NULL);
- c = tq.tqh_first;
+ c = TAILQ_FIRST(&tq);
if (c && (c->c_tv.tv_sec > now.tv_sec ||
(c->c_tv.tv_sec == now.tv_sec && c->c_tv.tv_usec > now.tv_usec))) {
@@ -614,12 +614,12 @@ conloop(void)
xfree(r);
xfree(e);
- c = tq.tqh_first;
+ c = TAILQ_FIRST(&tq);
while (c && (c->c_tv.tv_sec < now.tv_sec ||
(c->c_tv.tv_sec == now.tv_sec && c->c_tv.tv_usec < now.tv_usec))) {
int s = c->c_fd;
- c = c->c_link.tqe_next;
+ c = TAILQ_NEXT(c, c_link);
conrecycle(s);
}
}
diff --git a/crypto/openssh/ssh-keysign.8 b/crypto/openssh/ssh-keysign.8
new file mode 100644
index 0000000..ab2cf21
--- /dev/null
+++ b/crypto/openssh/ssh-keysign.8
@@ -0,0 +1,67 @@
+.\" $OpenBSD: ssh-keysign.8,v 1.2 2002/06/10 16:56:30 stevesk Exp $
+.\"
+.\" 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.
+.\"
+.Dd May 24, 2002
+.Dt SSH-KEYSIGN 8
+.Os
+.Sh NAME
+.Nm ssh-keysign
+.Nd ssh helper program for hostbased authentication
+.Sh SYNOPSIS
+.Nm
+.Sh DESCRIPTION
+.Nm
+is used by
+.Xr ssh 1
+to access the local host keys and generate the digital signature
+required during hostbased authentication with SSH protocol version 2.
+.Nm
+is not intended to be invoked by the user, but from
+.Xr ssh 1 .
+See
+.Xr ssh 1
+and
+.Xr sshd 8
+for more information about hostbased authentication.
+.Sh FILES
+.Bl -tag -width Ds
+.It Pa /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_rsa_key
+These files contain the private parts of the host keys used to
+generate the digital signature. They
+should be owned by root, readable only by root, and not
+accessible to others.
+Since they are readable only by root,
+.Nm
+must be set-uid root if hostbased authentication is used.
+.El
+.Sh SEE ALSO
+.Xr ssh 1 ,
+.Xr ssh-keygen 1 ,
+.Xr sshd 8
+.Sh AUTHORS
+Markus Friedl <markus@openbsd.org>
+.Sh HISTORY
+.Nm
+first appeared in
+.Ox 3.2 .
diff --git a/crypto/openssh/ssh-keysign.c b/crypto/openssh/ssh-keysign.c
new file mode 100644
index 0000000..0f69b9b
--- /dev/null
+++ b/crypto/openssh/ssh-keysign.c
@@ -0,0 +1,208 @@
+/*
+ * 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: ssh-keysign.c,v 1.4 2002/06/19 00:27:55 deraadt Exp $");
+
+#include <openssl/evp.h>
+
+#include "log.h"
+#include "key.h"
+#include "ssh2.h"
+#include "misc.h"
+#include "xmalloc.h"
+#include "buffer.h"
+#include "bufaux.h"
+#include "authfile.h"
+#include "msg.h"
+#include "canohost.h"
+#include "pathnames.h"
+
+static int
+valid_request(struct passwd *pw, char *host, Key **ret, u_char *data,
+ u_int datalen)
+{
+ Buffer b;
+ Key *key;
+ u_char *pkblob;
+ u_int blen, len;
+ char *pkalg, *p;
+ int pktype, fail;
+
+ fail = 0;
+
+ buffer_init(&b);
+ buffer_append(&b, data, datalen);
+
+ /* session id, currently limited to SHA1 (20 bytes) */
+ p = buffer_get_string(&b, &len);
+ if (len != 20)
+ fail++;
+ xfree(p);
+
+ if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)
+ fail++;
+
+ /* server user */
+ buffer_skip_string(&b);
+
+ /* service */
+ p = buffer_get_string(&b, NULL);
+ if (strcmp("ssh-connection", p) != 0)
+ fail++;
+ xfree(p);
+
+ /* method */
+ p = buffer_get_string(&b, NULL);
+ if (strcmp("hostbased", p) != 0)
+ fail++;
+ xfree(p);
+
+ /* pubkey */
+ pkalg = buffer_get_string(&b, NULL);
+ pkblob = buffer_get_string(&b, &blen);
+
+ pktype = key_type_from_name(pkalg);
+ if (pktype == KEY_UNSPEC)
+ fail++;
+ else if ((key = key_from_blob(pkblob, blen)) == NULL)
+ fail++;
+ else if (key->type != pktype)
+ fail++;
+ xfree(pkalg);
+ xfree(pkblob);
+
+ /* client host name, handle trailing dot */
+ p = buffer_get_string(&b, &len);
+ debug2("valid_request: check expect chost %s got %s", host, p);
+ if (strlen(host) != len - 1)
+ fail++;
+ else if (p[len - 1] != '.')
+ fail++;
+ else if (strncasecmp(host, p, len - 1) != 0)
+ fail++;
+ xfree(p);
+
+ /* local user */
+ p = buffer_get_string(&b, NULL);
+
+ if (strcmp(pw->pw_name, p) != 0)
+ fail++;
+ xfree(p);
+
+ /* end of message */
+ if (buffer_len(&b) != 0)
+ fail++;
+
+ debug3("valid_request: fail %d", fail);
+
+ if (fail && key != NULL)
+ key_free(key);
+ else
+ *ret = key;
+
+ return (fail ? -1 : 0);
+}
+
+int
+main(int argc, char **argv)
+{
+ Buffer b;
+ Key *keys[2], *key;
+ struct passwd *pw;
+ int key_fd[2], i, found, version = 2, fd;
+ u_char *signature, *data;
+ char *host;
+ u_int slen, dlen;
+
+ key_fd[0] = open(_PATH_HOST_RSA_KEY_FILE, O_RDONLY);
+ key_fd[1] = open(_PATH_HOST_DSA_KEY_FILE, O_RDONLY);
+
+ seteuid(getuid());
+ setuid(getuid());
+
+#ifdef DEBUG_SSH_KEYSIGN
+ log_init("ssh-keysign", SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0);
+#endif
+
+ if (key_fd[0] == -1 && key_fd[1] == -1)
+ fatal("could not open any host key");
+
+ if ((pw = getpwuid(getuid())) == NULL)
+ fatal("getpwuid failed");
+ pw = pwcopy(pw);
+
+ SSLeay_add_all_algorithms();
+
+ found = 0;
+ for (i = 0; i < 2; i++) {
+ keys[i] = NULL;
+ if (key_fd[i] == -1)
+ continue;
+ keys[i] = key_load_private_pem(key_fd[i], KEY_UNSPEC,
+ NULL, NULL);
+ close(key_fd[i]);
+ if (keys[i] != NULL)
+ found = 1;
+ }
+ if (!found)
+ fatal("no hostkey found");
+
+ buffer_init(&b);
+ if (msg_recv(STDIN_FILENO, &b) < 0)
+ fatal("msg_recv failed");
+ if (buffer_get_char(&b) != version)
+ fatal("bad version");
+ fd = buffer_get_int(&b);
+ if ((fd == STDIN_FILENO) || (fd == STDOUT_FILENO))
+ fatal("bad fd");
+ if ((host = get_local_name(fd)) == NULL)
+ fatal("cannot get sockname for fd");
+
+ data = buffer_get_string(&b, &dlen);
+ if (valid_request(pw, host, &key, data, dlen) < 0)
+ fatal("not a valid request");
+ xfree(data);
+ xfree(host);
+
+ found = 0;
+ for (i = 0; i < 2; i++) {
+ if (keys[i] != NULL &&
+ key_equal(key, keys[i])) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ fatal("no matching hostkey found");
+
+ if (key_sign(keys[i], &signature, &slen, data, dlen) != 0)
+ fatal("key_sign failed");
+
+ /* send reply */
+ buffer_clear(&b);
+ buffer_put_string(&b, signature, slen);
+ msg_send(STDOUT_FILENO, version, &b);
+
+ return (0);
+}
diff --git a/crypto/openssh/ssh-keysign/Makefile b/crypto/openssh/ssh-keysign/Makefile
new file mode 100644
index 0000000..1a13d9e
--- /dev/null
+++ b/crypto/openssh/ssh-keysign/Makefile
@@ -0,0 +1,18 @@
+# $OpenBSD: Makefile,v 1.3 2002/05/31 10:30:33 markus Exp $
+
+.PATH: ${.CURDIR}/..
+
+PROG= ssh-keysign
+BINOWN= root
+
+BINMODE?=4555
+
+BINDIR= /usr/libexec
+MAN= ssh-keysign.8
+
+SRCS= ssh-keysign.c
+
+.include <bsd.prog.mk>
+
+LDADD+= -lcrypto -lz
+DPADD+= ${LIBCRYPTO} ${LIBZ}
diff --git a/crypto/openssh/ssh-rsa.c b/crypto/openssh/ssh-rsa.c
index 8e79d4e..3e66294 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.16 2002/02/24 19:14:59 markus Exp $");
+RCSID("$OpenBSD: ssh-rsa.c,v 1.20 2002/06/10 16:53:06 stevesk Exp $");
#include <openssl/evp.h>
#include <openssl/err.h>
@@ -35,6 +35,7 @@ RCSID("$OpenBSD: ssh-rsa.c,v 1.16 2002/02/24 19:14:59 markus Exp $");
#include "key.h"
#include "ssh-rsa.h"
#include "compat.h"
+#include "ssh.h"
/* RSASSA-PKCS1-v1_5 (PKCS #1 v2.0 signature) with SHA1 */
int
@@ -54,10 +55,6 @@ 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);
@@ -118,20 +115,16 @@ ssh_rsa_verify(
EVP_MD_CTX md;
char *ktype;
u_char digest[EVP_MAX_MD_SIZE], *sigblob;
- u_int len, dlen;
+ u_int len, dlen, modlen;
int rlen, ret, nid;
if (key == NULL || key->type != KEY_RSA || key->rsa == NULL) {
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));
+ if (BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE) {
+ error("ssh_rsa_verify: RSA modulus too small: %d < minimum %d bits",
+ BN_num_bits(key->rsa->n), SSH_RSA_MINIMUM_MODULUS_SIZE);
return -1;
}
buffer_init(&b);
@@ -152,6 +145,21 @@ ssh_rsa_verify(
xfree(sigblob);
return -1;
}
+ /* RSA_verify expects a signature of RSA_size */
+ modlen = RSA_size(key->rsa);
+ if (len > modlen) {
+ error("ssh_rsa_verify: len %d > modlen %d", len, modlen);
+ xfree(sigblob);
+ return -1;
+ } else if (len < modlen) {
+ int diff = modlen - len;
+ debug("ssh_rsa_verify: add padding: modlen %d > len %d",
+ modlen, len);
+ sigblob = xrealloc(sigblob, modlen);
+ memmove(sigblob + diff, sigblob, len);
+ memset(sigblob, 0, diff);
+ len = modlen;
+ }
nid = (datafellows & SSH_BUG_RSASIGMD5) ? NID_md5 : NID_sha1;
if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
error("ssh_rsa_verify: EVP_get_digestbynid %d failed", nid);
diff --git a/crypto/openssh/ssh/Makefile b/crypto/openssh/ssh/Makefile
index f493e1f..80511de 100644
--- a/crypto/openssh/ssh/Makefile
+++ b/crypto/openssh/ssh/Makefile
@@ -1,14 +1,14 @@
-# $OpenBSD: Makefile,v 1.37 2002/03/05 00:49:51 deraadt Exp $
+# $OpenBSD: Makefile,v 1.42 2002/06/20 19:56:07 stevesk Exp $
.PATH: ${.CURDIR}/..
PROG= ssh
BINOWN= root
-BINMODE?=4555
+#BINMODE?=4555
BINDIR= /usr/bin
-MAN= ssh.1
+MAN= ssh.1 ssh_config.5
LINKS= ${BINDIR}/ssh ${BINDIR}/slogin
MLINKS= ssh.1 slogin.1
@@ -20,7 +20,7 @@ SRCS= ssh.c readconf.c clientloop.c sshtty.c \
.if (${KERBEROS5:L} == "yes")
CFLAGS+= -DKRB5 -I${DESTDIR}/usr/include/kerberosV
LDADD+= -lkrb5 -lasn1 -lcom_err
-DPADD+= ${LIBKRB5} ${LIBASN1}
+DPADD+= ${LIBKRB5} ${LIBASN1} ${LIBCOM_ERR}
.endif # KERBEROS5
.if (${KERBEROS:L} == "yes")
@@ -30,11 +30,11 @@ DPADD+= ${LIBKRB}
.if (${AFS:L} == "yes")
CFLAGS+= -DAFS
LDADD+= -lkafs
-DPADD+= ${LIBKRBAFS}
+DPADD+= ${LIBKAFS}
.endif # AFS
.endif # KERBEROS
.include <bsd.prog.mk>
LDADD+= -lcrypto -lz -ldes
-DPADD+= ${LIBCRYPTO} ${LIBZ}
+DPADD+= ${LIBCRYPTO} ${LIBZ} ${LIBDES}
diff --git a/crypto/openssh/ssh_config.5 b/crypto/openssh/ssh_config.5
new file mode 100644
index 0000000..53cb0fe
--- /dev/null
+++ b/crypto/openssh/ssh_config.5
@@ -0,0 +1,621 @@
+.\" -*- nroff -*-
+.\"
+.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
+.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+.\" All rights reserved
+.\"
+.\" 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
+.\" software must be clearly marked as such, and if the derived work is
+.\" incompatible with the protocol description in the RFC file, it must be
+.\" called by a name other than "ssh" or "Secure Shell".
+.\"
+.\" Copyright (c) 1999,2000 Markus Friedl. All rights reserved.
+.\" Copyright (c) 1999 Aaron Campbell. All rights reserved.
+.\" Copyright (c) 1999 Theo de Raadt. 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.
+.\"
+.\" $OpenBSD: ssh_config.5,v 1.1 2002/06/20 19:56:07 stevesk Exp $
+.Dd September 25, 1999
+.Dt SSH_CONFIG 5
+.Os
+.Sh NAME
+.Nm ssh_config
+.Nd OpenSSH SSH client configuration files
+.Sh SYNOPSIS
+.Bl -tag -width Ds -compact
+.It Pa $HOME/.ssh/config
+.It Pa /etc/ssh/ssh_config
+.El
+.Sh DESCRIPTION
+.Nm ssh
+obtains configuration data from the following sources in
+the following order:
+command line options, user's configuration file
+.Pq Pa $HOME/.ssh/config ,
+and system-wide configuration file
+.Pq Pa /etc/ssh/ssh_config .
+.Pp
+For each parameter, the first obtained value
+will be used.
+The configuration files contain sections bracketed by
+.Dq Host
+specifications, and that section is only applied for hosts that
+match one of the patterns given in the specification.
+The matched host name is the one given on the command line.
+.Pp
+Since the first obtained value for each parameter is used, more
+host-specific declarations should be given near the beginning of the
+file, and general defaults at the end.
+.Pp
+The configuration file has the following format:
+.Pp
+Empty lines and lines starting with
+.Ql #
+are comments.
+.Pp
+Otherwise a line is of the format
+.Dq keyword arguments .
+Configuration options may be separated by whitespace or
+optional whitespace and exactly one
+.Ql = ;
+the latter format is useful to avoid the need to quote whitespace
+when specifying configuration options using the
+.Nm ssh ,
+.Nm scp
+and
+.Nm sftp
+.Fl o
+option.
+.Pp
+The possible
+keywords and their meanings are as follows (note that
+keywords are case-insensitive and arguments are case-sensitive):
+.Bl -tag -width Ds
+.It Cm Host
+Restricts the following declarations (up to the next
+.Cm Host
+keyword) to be only for those hosts that match one of the patterns
+given after the keyword.
+.Ql \&*
+and
+.Ql ?
+can be used as wildcards in the
+patterns.
+A single
+.Ql \&*
+as a pattern can be used to provide global
+defaults for all hosts.
+The host is the
+.Ar hostname
+argument given on the command line (i.e., the name is not converted to
+a canonicalized host name before matching).
+.It Cm AFSTokenPassing
+Specifies whether to pass AFS tokens to remote host.
+The argument to this keyword must be
+.Dq yes
+or
+.Dq no .
+This option applies to protocol version 1 only.
+.It Cm BatchMode
+If set to
+.Dq yes ,
+passphrase/password querying will be disabled.
+This option is useful in scripts and other batch jobs where no user
+is present to supply the password.
+The argument must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq no .
+.It Cm BindAddress
+Specify the interface to transmit from on machines with multiple
+interfaces or aliased addresses.
+Note that this option does not work if
+.Cm UsePrivilegedPort
+is set to
+.Dq yes .
+.It Cm ChallengeResponseAuthentication
+Specifies whether to use challenge response authentication.
+The argument to this keyword must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq yes .
+.It Cm CheckHostIP
+If this flag is set to
+.Dq yes ,
+ssh will additionally check the host IP address in the
+.Pa known_hosts
+file.
+This allows ssh to detect if a host key changed due to DNS spoofing.
+If the option is set to
+.Dq no ,
+the check will not be executed.
+The default is
+.Dq yes .
+.It Cm Cipher
+Specifies the cipher to use for encrypting the session
+in protocol version 1.
+Currently,
+.Dq blowfish ,
+.Dq 3des ,
+and
+.Dq des
+are supported.
+.Ar des
+is only supported in the
+.Nm ssh
+client for interoperability with legacy protocol 1 implementations
+that do not support the
+.Ar 3des
+cipher. Its use is strongly discouraged due to cryptographic
+weaknesses.
+The default is
+.Dq 3des .
+.It Cm Ciphers
+Specifies the ciphers allowed for protocol version 2
+in order of preference.
+Multiple ciphers must be comma-separated.
+The default is
+.Pp
+.Bd -literal
+ ``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,
+ aes192-cbc,aes256-cbc''
+.Ed
+.It Cm ClearAllForwardings
+Specifies that all local, remote and dynamic port forwardings
+specified in the configuration files or on the command line be
+cleared. This option is primarily useful when used from the
+.Nm ssh
+command line to clear port forwardings set in
+configuration files, and is automatically set by
+.Xr scp 1
+and
+.Xr sftp 1 .
+The argument must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq no .
+.It Cm Compression
+Specifies whether to use compression.
+The argument must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq no .
+.It Cm CompressionLevel
+Specifies the compression level to use if compression is enabled.
+The argument must be an integer from 1 (fast) to 9 (slow, best).
+The default level is 6, which is good for most applications.
+The meaning of the values is the same as in
+.Xr gzip 1 .
+Note that this option applies to protocol version 1 only.
+.It Cm ConnectionAttempts
+Specifies the number of tries (one per second) to make before exiting.
+The argument must be an integer.
+This may be useful in scripts if the connection sometimes fails.
+The default is 1.
+.It Cm DynamicForward
+Specifies that a TCP/IP port on the local machine be forwarded
+over the secure channel, and the application
+protocol is then used to determine where to connect to from the
+remote machine. The argument must be a port number.
+Currently the SOCKS4 protocol is supported, and
+.Nm ssh
+will act as a SOCKS4 server.
+Multiple forwardings may be specified, and
+additional forwardings can be given on the command line. Only
+the superuser can forward privileged ports.
+.It Cm EscapeChar
+Sets the escape character (default:
+.Ql ~ ) .
+The escape character can also
+be set on the command line.
+The argument should be a single character,
+.Ql ^
+followed by a letter, or
+.Dq none
+to disable the escape
+character entirely (making the connection transparent for binary
+data).
+.It Cm ForwardAgent
+Specifies whether the connection to the authentication agent (if any)
+will be forwarded to the remote machine.
+The argument must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq no .
+.It Cm ForwardX11
+Specifies whether X11 connections will be automatically redirected
+over the secure channel and
+.Ev DISPLAY
+set.
+The argument must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq no .
+.It Cm GatewayPorts
+Specifies whether remote hosts are allowed to connect to local
+forwarded ports.
+By default,
+.Nm ssh
+binds local port forwardings to the loopback address. This
+prevents other remote hosts from connecting to forwarded ports.
+.Cm GatewayPorts
+can be used to specify that
+.Nm ssh
+should bind local port forwardings to the wildcard address,
+thus allowing remote hosts to connect to forwarded ports.
+The argument must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq no .
+.It Cm GlobalKnownHostsFile
+Specifies a file to use for the global
+host key database instead of
+.Pa /etc/ssh/ssh_known_hosts .
+.It Cm HostbasedAuthentication
+Specifies whether to try rhosts based authentication with public key
+authentication.
+The argument must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq no .
+This option applies to protocol version 2 only and
+is similar to
+.Cm RhostsRSAAuthentication .
+.It Cm HostKeyAlgorithms
+Specifies the protocol version 2 host key algorithms
+that the client wants to use in order of preference.
+The default for this option is:
+.Dq ssh-rsa,ssh-dss .
+.It Cm HostKeyAlias
+Specifies an alias that should be used instead of the
+real host name when looking up or saving the host key
+in the host key database files.
+This option is useful for tunneling ssh connections
+or for multiple servers running on a single host.
+.It Cm HostName
+Specifies the real host name to log into.
+This can be used to specify nicknames or abbreviations for hosts.
+Default is the name given on the command line.
+Numeric IP addresses are also permitted (both on the command line and in
+.Cm HostName
+specifications).
+.It Cm IdentityFile
+Specifies a file from which the user's RSA or DSA authentication identity
+is read. The default is
+.Pa $HOME/.ssh/identity
+for protocol version 1, and
+.Pa $HOME/.ssh/id_rsa
+and
+.Pa $HOME/.ssh/id_dsa
+for protocol version 2.
+Additionally, any identities represented by the authentication agent
+will be used for authentication.
+The file name may use the tilde
+syntax to refer to a user's home directory.
+It is possible to have
+multiple identity files specified in configuration files; all these
+identities will be tried in sequence.
+.It Cm KeepAlive
+Specifies whether the system should send TCP keepalive messages to the
+other side.
+If they are sent, death of the connection or crash of one
+of the machines will be properly noticed.
+However, this means that
+connections will die if the route is down temporarily, and some people
+find it annoying.
+.Pp
+The default is
+.Dq yes
+(to send keepalives), and the client will notice
+if the network goes down or the remote host dies.
+This is important in scripts, and many users want it too.
+.Pp
+To disable keepalives, the value should be set to
+.Dq no .
+.It Cm KerberosAuthentication
+Specifies whether Kerberos authentication will be used.
+The argument to this keyword must be
+.Dq yes
+or
+.Dq no .
+.It Cm KerberosTgtPassing
+Specifies whether a Kerberos TGT will be forwarded to the server.
+This will only work if the Kerberos server is actually an AFS kaserver.
+The argument to this keyword must be
+.Dq yes
+or
+.Dq no .
+.It Cm LocalForward
+Specifies that a TCP/IP port on the local machine be forwarded over
+the secure channel to the specified host and port from the remote machine.
+The first argument must be a port number, and the second must be
+.Ar host:port .
+IPv6 addresses can be specified with an alternative syntax:
+.Ar host/port .
+Multiple forwardings may be specified, and additional
+forwardings can be given on the command line.
+Only the superuser can forward privileged ports.
+.It Cm LogLevel
+Gives the verbosity level that is used when logging messages from
+.Nm ssh .
+The possible values are:
+QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2 and DEBUG3.
+The default is INFO. DEBUG and DEBUG1 are equivalent. DEBUG2
+and DEBUG3 each specify higher levels of verbose output.
+.It Cm MACs
+Specifies the MAC (message authentication code) algorithms
+in order of preference.
+The MAC algorithm is used in protocol version 2
+for data integrity protection.
+Multiple algorithms must be comma-separated.
+The default is
+.Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 .
+.It Cm NoHostAuthenticationForLocalhost
+This option can be used if the home directory is shared across machines.
+In this case localhost will refer to a different machine on each of
+the machines and the user will get many warnings about changed host keys.
+However, this option disables host authentication for localhost.
+The argument to this keyword must be
+.Dq yes
+or
+.Dq no .
+The default is to check the host key for localhost.
+.It Cm NumberOfPasswordPrompts
+Specifies the number of password prompts before giving up.
+The argument to this keyword must be an integer.
+Default is 3.
+.It Cm PasswordAuthentication
+Specifies whether to use password authentication.
+The argument to this keyword must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq yes .
+.It Cm Port
+Specifies the port number to connect on the remote host.
+Default is 22.
+.It Cm PreferredAuthentications
+Specifies the order in which the client should try protocol 2
+authentication methods. This allows a client to prefer one method (e.g.
+.Cm keyboard-interactive )
+over another method (e.g.
+.Cm password )
+The default for this option is:
+.Dq hostbased,publickey,keyboard-interactive,password .
+.It Cm Protocol
+Specifies the protocol versions
+.Nm ssh
+should support in order of preference.
+The possible values are
+.Dq 1
+and
+.Dq 2 .
+Multiple versions must be comma-separated.
+The default is
+.Dq 2,1 .
+This means that
+.Nm ssh
+tries version 2 and falls back to version 1
+if version 2 is not available.
+.It Cm ProxyCommand
+Specifies the command to use to connect to the server.
+The command
+string extends to the end of the line, and is executed with
+.Pa /bin/sh .
+In the command string,
+.Ql %h
+will be substituted by the host name to
+connect and
+.Ql %p
+by the port.
+The command can be basically anything,
+and should read from its standard input and write to its standard output.
+It should eventually connect an
+.Xr sshd 8
+server running on some machine, or execute
+.Ic sshd -i
+somewhere.
+Host key management will be done using the
+HostName of the host being connected (defaulting to the name typed by
+the user).
+Note that
+.Cm CheckHostIP
+is not available for connects with a proxy command.
+.Pp
+.It Cm PubkeyAuthentication
+Specifies whether to try public key authentication.
+The argument to this keyword must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq yes .
+This option applies to protocol version 2 only.
+.It Cm RemoteForward
+Specifies that a TCP/IP port on the remote machine be forwarded over
+the secure channel to the specified host and port from the local machine.
+The first argument must be a port number, and the second must be
+.Ar host:port .
+IPv6 addresses can be specified with an alternative syntax:
+.Ar host/port .
+Multiple forwardings may be specified, and additional
+forwardings can be given on the command line.
+Only the superuser can forward privileged ports.
+.It Cm RhostsAuthentication
+Specifies whether to try rhosts based authentication.
+Note that this
+declaration only affects the client side and has no effect whatsoever
+on security.
+Most servers do not permit RhostsAuthentication because it
+is not secure (see
+.Cm RhostsRSAAuthentication ) .
+The argument to this keyword must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq no .
+This option applies to protocol version 1 only.
+.It Cm RhostsRSAAuthentication
+Specifies whether to try rhosts based authentication with RSA host
+authentication.
+The argument must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq no .
+This option applies to protocol version 1 only and requires
+.Nm ssh
+to be setuid root.
+.It Cm RSAAuthentication
+Specifies whether to try RSA authentication.
+The argument to this keyword must be
+.Dq yes
+or
+.Dq no .
+RSA authentication will only be
+attempted if the identity file exists, or an authentication agent is
+running.
+The default is
+.Dq yes .
+Note that this option applies to protocol version 1 only.
+.It Cm SmartcardDevice
+Specifies which smartcard device to use. The argument to this keyword is
+the device
+.Nm ssh
+should use to communicate with a smartcard used for storing the user's
+private RSA key. By default, no device is specified and smartcard support
+is not activated.
+.It Cm StrictHostKeyChecking
+If this flag is set to
+.Dq yes ,
+.Nm ssh
+will never automatically add host keys to the
+.Pa $HOME/.ssh/known_hosts
+file, and refuses to connect to hosts whose host key has changed.
+This provides maximum protection against trojan horse attacks,
+however, can be annoying when the
+.Pa /etc/ssh/ssh_known_hosts
+file is poorly maintained, or connections to new hosts are
+frequently made.
+This option forces the user to manually
+add all new hosts.
+If this flag is set to
+.Dq no ,
+.Nm ssh
+will automatically add new host keys to the
+user known hosts files.
+If this flag is set to
+.Dq ask ,
+new host keys
+will be added to the user known host files only after the user
+has confirmed that is what they really want to do, and
+.Nm ssh
+will refuse to connect to hosts whose host key has changed.
+The host keys of
+known hosts will be verified automatically in all cases.
+The argument must be
+.Dq yes ,
+.Dq no
+or
+.Dq ask .
+The default is
+.Dq ask .
+.It Cm UsePrivilegedPort
+Specifies whether to use a privileged port for outgoing connections.
+The argument must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq no .
+Note that this option must be set to
+.Dq yes
+if
+.Cm RhostsAuthentication
+and
+.Cm RhostsRSAAuthentication
+authentications are needed with older servers.
+.It Cm User
+Specifies the user to log in as.
+This can be useful when a different user name is used on different machines.
+This saves the trouble of
+having to remember to give the user name on the command line.
+.It Cm UserKnownHostsFile
+Specifies a file to use for the user
+host key database instead of
+.Pa $HOME/.ssh/known_hosts .
+.It Cm XAuthLocation
+Specifies the location of the
+.Xr xauth 1
+program.
+The default is
+.Pa /usr/X11R6/bin/xauth .
+.El
+.Sh FILES
+.Bl -tag -width Ds
+.It Pa $HOME/.ssh/config
+This is the per-user configuration file.
+The format of this file is described above.
+This file is used by the
+.Nm ssh
+client.
+This file does not usually contain any sensitive information,
+but the recommended permissions are read/write for the user, and not
+accessible by others.
+.It Pa /etc/ssh/ssh_config
+Systemwide configuration file.
+This file provides defaults for those
+values that are not specified in the user's configuration file, and
+for those users who do not have a configuration file.
+This file must be world-readable.
+.El
+.Sh AUTHORS
+OpenSSH is a derivative of the original and free
+ssh 1.2.12 release by Tatu Ylonen.
+Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
+Theo de Raadt and Dug Song
+removed many bugs, re-added newer features and
+created OpenSSH.
+Markus Friedl contributed the support for SSH
+protocol versions 1.5 and 2.0.
+.Sh SEE ALSO
+.Xr ssh 1
diff --git a/crypto/openssh/sshd/Makefile b/crypto/openssh/sshd/Makefile
index 8fdd8e6..14ef3e0 100644
--- a/crypto/openssh/sshd/Makefile
+++ b/crypto/openssh/sshd/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.46 2002/03/05 00:49:51 deraadt Exp $
+# $OpenBSD: Makefile,v 1.51 2002/06/20 19:56:07 stevesk Exp $
.PATH: ${.CURDIR}/..
@@ -6,14 +6,16 @@ PROG= sshd
BINOWN= root
BINMODE=555
BINDIR= /usr/sbin
-MAN= sshd.8
+MAN= sshd.8 sshd_config.5
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 \
+ sshpty.c sshlogin.c servconf.c serverloop.c uidswap.c \
auth.c auth1.c auth2.c auth-options.c session.c \
auth-chall.c auth2-chall.c groupaccess.c \
- auth-skey.c auth-bsdauth.c
+ auth-skey.c auth-bsdauth.c monitor_mm.c monitor.c \
+ auth2-none.c auth2-passwd.c auth2-pubkey.c \
+ auth2-hostbased.c auth2-kbdint.c
.include <bsd.own.mk> # for KERBEROS and AFS
@@ -21,14 +23,14 @@ SRCS= sshd.c auth-rhosts.c auth-passwd.c auth-rsa.c auth-rh-rsa.c \
CFLAGS+=-DKRB5 -I${DESTDIR}/usr/include/kerberosV
SRCS+= auth-krb5.c
LDADD+= -lkrb5 -lkafs -lasn1 -lcom_err
-DPADD+= ${LIBKRB5} ${LIBKAFS} ${LIBASN1}
+DPADD+= ${LIBKRB5} ${LIBKAFS} ${LIBASN1} ${LIBCOM_ERR}
.endif # KERBEROS5
.if (${KERBEROS:L} == "yes")
.if (${AFS:L} == "yes")
CFLAGS+= -DAFS
LDADD+= -lkafs
-DPADD+= ${LIBKRBAFS}
+DPADD+= ${LIBKAFS}
.endif # AFS
CFLAGS+= -DKRB4 -I${DESTDIR}/usr/include/kerberosIV
SRCS+= auth-krb4.c
@@ -39,7 +41,7 @@ DPADD+= ${LIBKRB}
.include <bsd.prog.mk>
LDADD+= -lcrypto -lutil -lz -ldes
-DPADD+= ${LIBCRYPTO} ${LIBUTIL} ${LIBZ}
+DPADD+= ${LIBCRYPTO} ${LIBUTIL} ${LIBZ} ${LIBDES}
.if (${TCP_WRAPPERS:L} == "yes")
CFLAGS+= -DLIBWRAP
diff --git a/crypto/openssh/sshd_config.5 b/crypto/openssh/sshd_config.5
new file mode 100644
index 0000000..efa1305
--- /dev/null
+++ b/crypto/openssh/sshd_config.5
@@ -0,0 +1,707 @@
+.\" -*- nroff -*-
+.\"
+.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
+.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+.\" All rights reserved
+.\"
+.\" 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
+.\" software must be clearly marked as such, and if the derived work is
+.\" incompatible with the protocol description in the RFC file, it must be
+.\" called by a name other than "ssh" or "Secure Shell".
+.\"
+.\" Copyright (c) 1999,2000 Markus Friedl. All rights reserved.
+.\" Copyright (c) 1999 Aaron Campbell. All rights reserved.
+.\" Copyright (c) 1999 Theo de Raadt. 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.
+.\"
+.\" $OpenBSD: sshd_config.5,v 1.3 2002/06/20 23:37:12 markus Exp $
+.Dd September 25, 1999
+.Dt SSHD_CONFIG 5
+.Os
+.Sh NAME
+.Nm sshd_config
+.Nd OpenSSH SSH daemon configuration file
+.Sh SYNOPSIS
+.Bl -tag -width Ds -compact
+.It Pa /etc/ssh/sshd_config
+.El
+.Sh DESCRIPTION
+.Nm sshd
+reads configuration data from
+.Pa /etc/ssh/sshd_config
+(or the file specified with
+.Fl f
+on the command line).
+The file contains keyword-argument pairs, one per line.
+Lines starting with
+.Ql #
+and empty lines are interpreted as comments.
+.Pp
+The possible
+keywords and their meanings are as follows (note that
+keywords are case-insensitive and arguments are case-sensitive):
+.Bl -tag -width Ds
+.It Cm AFSTokenPassing
+Specifies whether an AFS token may be forwarded to the server.
+Default is
+.Dq no .
+.It Cm AllowGroups
+This keyword can be followed by a list of group name patterns, separated
+by spaces.
+If specified, login is allowed only for users whose primary
+group or supplementary group list matches one of the patterns.
+.Ql \&*
+and
+.Ql ?
+can be used as
+wildcards in the patterns.
+Only group names are valid; a numerical group ID is not recognized.
+By default, login is allowed for all groups.
+.Pp
+.It Cm AllowTcpForwarding
+Specifies whether TCP forwarding is permitted.
+The default is
+.Dq yes .
+Note that disabling TCP forwarding does not improve security unless
+users are also denied shell access, as they can always install their
+own forwarders.
+.Pp
+.It Cm AllowUsers
+This keyword can be followed by a list of user name patterns, separated
+by spaces.
+If specified, login is allowed only for users names that
+match one of the patterns.
+.Ql \&*
+and
+.Ql ?
+can be used as
+wildcards in the patterns.
+Only user names are valid; a numerical user ID is not recognized.
+By default, login is allowed for all users.
+If the pattern takes the form USER@HOST then USER and HOST
+are separately checked, restricting logins to particular
+users from particular hosts.
+.Pp
+.It Cm AuthorizedKeysFile
+Specifies the file that contains the public keys that can be used
+for user authentication.
+.Cm AuthorizedKeysFile
+may contain tokens of the form %T which are substituted during connection
+set-up. The following tokens are defined: %% is replaced by a literal '%',
+%h is replaced by the home directory of the user being authenticated and
+%u is replaced by the username of that user.
+After expansion,
+.Cm AuthorizedKeysFile
+is taken to be an absolute path or one relative to the user's home
+directory.
+The default is
+.Dq .ssh/authorized_keys .
+.It Cm Banner
+In some jurisdictions, sending a warning message before authentication
+may be relevant for getting legal protection.
+The contents of the specified file are sent to the remote user before
+authentication is allowed.
+This option is only available for protocol version 2.
+By default, no banner is displayed.
+.Pp
+.It Cm ChallengeResponseAuthentication
+Specifies whether challenge response authentication is allowed.
+All authentication styles from
+.Xr login.conf 5
+are supported.
+The default is
+.Dq yes .
+.It Cm Ciphers
+Specifies the ciphers allowed for protocol version 2.
+Multiple ciphers must be comma-separated.
+The default is
+.Pp
+.Bd -literal
+ ``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,
+ aes192-cbc,aes256-cbc''
+.Ed
+.It Cm ClientAliveInterval
+Sets a timeout interval in seconds after which if no data has been received
+from the client,
+.Nm sshd
+will send a message through the encrypted
+channel to request a response from the client.
+The default
+is 0, indicating that these messages will not be sent to the client.
+This option applies to protocol version 2 only.
+.It Cm ClientAliveCountMax
+Sets the number of client alive messages (see above) which may be
+sent without
+.Nm sshd
+receiving any messages back from the client. If this threshold is
+reached while client alive messages are being sent,
+.Nm sshd
+will disconnect the client, terminating the session. It is important
+to note that the use of client alive messages is very different from
+.Cm KeepAlive
+(below). The client alive messages are sent through the
+encrypted channel and therefore will not be spoofable. The TCP keepalive
+option enabled by
+.Cm KeepAlive
+is spoofable. The client alive mechanism is valuable when the client or
+server depend on knowing when a connection has become inactive.
+.Pp
+The default value is 3. If
+.Cm ClientAliveInterval
+(above) is set to 15, and
+.Cm ClientAliveCountMax
+is left at the default, unresponsive ssh clients
+will be disconnected after approximately 45 seconds.
+.It Cm Compression
+Specifies whether compression is allowed.
+The argument must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq yes .
+.It Cm DenyGroups
+This keyword can be followed by a list of group name patterns, separated
+by spaces.
+Login is disallowed for users whose primary group or supplementary
+group list matches one of the patterns.
+.Ql \&*
+and
+.Ql ?
+can be used as
+wildcards in the patterns.
+Only group names are valid; a numerical group ID is not recognized.
+By default, login is allowed for all groups.
+.Pp
+.It Cm DenyUsers
+This keyword can be followed by a list of user name patterns, separated
+by spaces.
+Login is disallowed for user names that match one of the patterns.
+.Ql \&*
+and
+.Ql ?
+can be used as wildcards in the patterns.
+Only user names are valid; a numerical user ID is not recognized.
+By default, login is allowed for all users.
+If the pattern takes the form USER@HOST then USER and HOST
+are separately checked, restricting logins to particular
+users from particular hosts.
+.It Cm GatewayPorts
+Specifies whether remote hosts are allowed to connect to ports
+forwarded for the client.
+By default,
+.Nm sshd
+binds remote port forwardings to the loopback address. This
+prevents other remote hosts from connecting to forwarded ports.
+.Cm GatewayPorts
+can be used to specify that
+.Nm sshd
+should bind remote port forwardings to the wildcard address,
+thus allowing remote hosts to connect to forwarded ports.
+The argument must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq no .
+.It Cm HostbasedAuthentication
+Specifies whether rhosts or /etc/hosts.equiv authentication together
+with successful public key client host authentication is allowed
+(hostbased authentication).
+This option is similar to
+.Cm RhostsRSAAuthentication
+and applies to protocol version 2 only.
+The default is
+.Dq no .
+.It Cm HostKey
+Specifies a file containing a private host key
+used by SSH.
+The default is
+.Pa /etc/ssh/ssh_host_key
+for protocol version 1, and
+.Pa /etc/ssh/ssh_host_rsa_key
+and
+.Pa /etc/ssh/ssh_host_dsa_key
+for protocol version 2.
+Note that
+.Nm sshd
+will refuse to use a file if it is group/world-accessible.
+It is possible to have multiple host key files.
+.Dq rsa1
+keys are used for version 1 and
+.Dq dsa
+or
+.Dq rsa
+are used for version 2 of the SSH protocol.
+.It Cm IgnoreRhosts
+Specifies that
+.Pa .rhosts
+and
+.Pa .shosts
+files will not be used in
+.Cm RhostsAuthentication ,
+.Cm RhostsRSAAuthentication
+or
+.Cm HostbasedAuthentication .
+.Pp
+.Pa /etc/hosts.equiv
+and
+.Pa /etc/shosts.equiv
+are still used.
+The default is
+.Dq yes .
+.It Cm IgnoreUserKnownHosts
+Specifies whether
+.Nm sshd
+should ignore the user's
+.Pa $HOME/.ssh/known_hosts
+during
+.Cm RhostsRSAAuthentication
+or
+.Cm HostbasedAuthentication .
+The default is
+.Dq no .
+.It Cm KeepAlive
+Specifies whether the system should send TCP keepalive messages to the
+other side.
+If they are sent, death of the connection or crash of one
+of the machines will be properly noticed.
+However, this means that
+connections will die if the route is down temporarily, and some people
+find it annoying.
+On the other hand, if keepalives are not sent,
+sessions may hang indefinitely on the server, leaving
+.Dq ghost
+users and consuming server resources.
+.Pp
+The default is
+.Dq yes
+(to send keepalives), and the server will notice
+if the network goes down or the client host crashes.
+This avoids infinitely hanging sessions.
+.Pp
+To disable keepalives, the value should be set to
+.Dq no .
+.It Cm KerberosAuthentication
+Specifies whether Kerberos authentication is allowed.
+This can be in the form of a Kerberos ticket, or if
+.Cm PasswordAuthentication
+is yes, the password provided by the user will be validated through
+the Kerberos KDC.
+To use this option, the server needs a
+Kerberos servtab which allows the verification of the KDC's identity.
+Default is
+.Dq no .
+.It Cm KerberosOrLocalPasswd
+If set then if password authentication through Kerberos fails then
+the password will be validated via any additional local mechanism
+such as
+.Pa /etc/passwd .
+Default is
+.Dq yes .
+.It Cm KerberosTgtPassing
+Specifies whether a Kerberos TGT may be forwarded to the server.
+Default is
+.Dq no ,
+as this only works when the Kerberos KDC is actually an AFS kaserver.
+.It Cm KerberosTicketCleanup
+Specifies whether to automatically destroy the user's ticket cache
+file on logout.
+Default is
+.Dq yes .
+.It Cm KeyRegenerationInterval
+In protocol version 1, the ephemeral server key is automatically regenerated
+after this many seconds (if it has been used).
+The purpose of regeneration is to prevent
+decrypting captured sessions by later breaking into the machine and
+stealing the keys.
+The key is never stored anywhere.
+If the value is 0, the key is never regenerated.
+The default is 3600 (seconds).
+.It Cm ListenAddress
+Specifies the local addresses
+.Nm sshd
+should listen on.
+The following forms may be used:
+.Pp
+.Bl -item -offset indent -compact
+.It
+.Cm ListenAddress
+.Sm off
+.Ar host No | Ar IPv4_addr No | Ar IPv6_addr
+.Sm on
+.It
+.Cm ListenAddress
+.Sm off
+.Ar host No | Ar IPv4_addr No : Ar port
+.Sm on
+.It
+.Cm ListenAddress
+.Sm off
+.Oo
+.Ar host No | Ar IPv6_addr Oc : Ar port
+.Sm on
+.El
+.Pp
+If
+.Ar port
+is not specified,
+.Nm sshd
+will listen on the address and all prior
+.Cm Port
+options specified. The default is to listen on all local
+addresses. Multiple
+.Cm ListenAddress
+options are permitted. Additionally, any
+.Cm Port
+options must precede this option for non port qualified addresses.
+.It Cm LoginGraceTime
+The server disconnects after this time if the user has not
+successfully logged in.
+If the value is 0, there is no time limit.
+The default is 600 (seconds).
+.It Cm LogLevel
+Gives the verbosity level that is used when logging messages from
+.Nm sshd .
+The possible values are:
+QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2 and DEBUG3.
+The default is INFO. DEBUG and DEBUG1 are equivalent. DEBUG2
+and DEBUG3 each specify higher levels of debugging output.
+Logging with a DEBUG level violates the privacy of users
+and is not recommended.
+.It Cm MACs
+Specifies the available MAC (message authentication code) algorithms.
+The MAC algorithm is used in protocol version 2
+for data integrity protection.
+Multiple algorithms must be comma-separated.
+The default is
+.Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 .
+.It Cm MaxStartups
+Specifies the maximum number of concurrent unauthenticated connections to the
+.Nm sshd
+daemon.
+Additional connections will be dropped until authentication succeeds or the
+.Cm LoginGraceTime
+expires for a connection.
+The default is 10.
+.Pp
+Alternatively, random early drop can be enabled by specifying
+the three colon separated values
+.Dq start:rate:full
+(e.g., "10:30:60").
+.Nm sshd
+will refuse connection attempts with a probability of
+.Dq rate/100
+(30%)
+if there are currently
+.Dq start
+(10)
+unauthenticated connections.
+The probability increases linearly and all connection attempts
+are refused if the number of unauthenticated connections reaches
+.Dq full
+(60).
+.It Cm PasswordAuthentication
+Specifies whether password authentication is allowed.
+The default is
+.Dq yes .
+.It Cm PermitEmptyPasswords
+When password authentication is allowed, it specifies whether the
+server allows login to accounts with empty password strings.
+The default is
+.Dq no .
+.It Cm PermitRootLogin
+Specifies whether root can login using
+.Xr ssh 1 .
+The argument must be
+.Dq yes ,
+.Dq without-password ,
+.Dq forced-commands-only
+or
+.Dq no .
+The default is
+.Dq yes .
+.Pp
+If this option is set to
+.Dq without-password
+password authentication is disabled for root.
+.Pp
+If this option is set to
+.Dq forced-commands-only
+root login with public key authentication will be allowed,
+but only if the
+.Ar command
+option has been specified
+(which may be useful for taking remote backups even if root login is
+normally not allowed). All other authentication methods are disabled
+for root.
+.Pp
+If this option is set to
+.Dq no
+root is not allowed to login.
+.It Cm PidFile
+Specifies the file that contains the process identifier of the
+.Nm sshd
+daemon.
+The default is
+.Pa /var/run/sshd.pid .
+.It Cm Port
+Specifies the port number that
+.Nm sshd
+listens on.
+The default is 22.
+Multiple options of this type are permitted.
+See also
+.Cm ListenAddress .
+.It Cm PrintLastLog
+Specifies whether
+.Nm sshd
+should print the date and time when the user last logged in.
+The default is
+.Dq yes .
+.It Cm PrintMotd
+Specifies whether
+.Nm sshd
+should print
+.Pa /etc/motd
+when a user logs in interactively.
+(On some systems it is also printed by the shell,
+.Pa /etc/profile ,
+or equivalent.)
+The default is
+.Dq yes .
+.It Cm Protocol
+Specifies the protocol versions
+.Nm sshd
+should support.
+The possible values are
+.Dq 1
+and
+.Dq 2 .
+Multiple versions must be comma-separated.
+The default is
+.Dq 2,1 .
+.It Cm PubkeyAuthentication
+Specifies whether public key authentication is allowed.
+The default is
+.Dq yes .
+Note that this option applies to protocol version 2 only.
+.It Cm RhostsAuthentication
+Specifies whether authentication using rhosts or /etc/hosts.equiv
+files is sufficient.
+Normally, this method should not be permitted because it is insecure.
+.Cm RhostsRSAAuthentication
+should be used
+instead, because it performs RSA-based host authentication in addition
+to normal rhosts or /etc/hosts.equiv authentication.
+The default is
+.Dq no .
+This option applies to protocol version 1 only.
+.It Cm RhostsRSAAuthentication
+Specifies whether rhosts or /etc/hosts.equiv authentication together
+with successful RSA host authentication is allowed.
+The default is
+.Dq no .
+This option applies to protocol version 1 only.
+.It Cm RSAAuthentication
+Specifies whether pure RSA authentication is allowed.
+The default is
+.Dq yes .
+This option applies to protocol version 1 only.
+.It Cm ServerKeyBits
+Defines the number of bits in the ephemeral protocol version 1 server key.
+The minimum value is 512, and the default is 768.
+.It Cm StrictModes
+Specifies whether
+.Nm sshd
+should check file modes and ownership of the
+user's files and home directory before accepting login.
+This is normally desirable because novices sometimes accidentally leave their
+directory or files world-writable.
+The default is
+.Dq yes .
+.It Cm Subsystem
+Configures an external subsystem (e.g., file transfer daemon).
+Arguments should be a subsystem name and a command to execute upon subsystem
+request.
+The command
+.Xr sftp-server 8
+implements the
+.Dq sftp
+file transfer subsystem.
+By default no subsystems are defined.
+Note that this option applies to protocol version 2 only.
+.It Cm SyslogFacility
+Gives the facility code that is used when logging messages from
+.Nm sshd .
+The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
+LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
+The default is AUTH.
+.It Cm UseLogin
+Specifies whether
+.Xr login 1
+is used for interactive login sessions.
+The default is
+.Dq no .
+Note that
+.Xr login 1
+is never used for remote command execution.
+Note also, that if this is enabled,
+.Cm X11Forwarding
+will be disabled because
+.Xr login 1
+does not know how to handle
+.Xr xauth 1
+cookies. If
+.Cm UsePrivilegeSeparation
+is specified, it will be disabled after authentication.
+.It Cm UsePrivilegeSeparation
+Specifies whether
+.Nm sshd
+separates privileges by creating an unprivileged child process
+to deal with incoming network traffic. After successful authentication,
+another process will be created that has the privilege of the authenticated
+user. The goal of privilege separation is to prevent privilege
+escalation by containing any corruption within the unprivileged processes.
+The default is
+.Dq yes .
+.It Cm VerifyReverseMapping
+Specifies whether
+.Nm sshd
+should try to verify the remote host name and check that
+the resolved host name for the remote IP address maps back to the
+very same IP address.
+The default is
+.Dq no .
+.It Cm X11DisplayOffset
+Specifies the first display number available for
+.Nm sshd Ns 's
+X11 forwarding.
+This prevents
+.Nm sshd
+from interfering with real X11 servers.
+The default is 10.
+.It Cm X11Forwarding
+Specifies whether X11 forwarding is permitted.
+The default is
+.Dq no .
+Note that disabling X11 forwarding does not improve security in any
+way, as users can always install their own forwarders.
+X11 forwarding is automatically disabled if
+.Cm UseLogin
+is enabled.
+.It Cm X11UseLocalhost
+Specifies whether
+.Nm sshd
+should bind the X11 forwarding server to the loopback address or to
+the wildcard address. By default,
+.Nm sshd
+binds the forwarding server to the loopback address and sets the
+hostname part of the
+.Ev DISPLAY
+environment variable to
+.Dq localhost .
+This prevents remote hosts from connecting to the fake display.
+However, some older X11 clients may not function with this
+configuration.
+.Cm X11UseLocalhost
+may be set to
+.Dq no
+to specify that the forwarding server should be bound to the wildcard
+address.
+The argument must be
+.Dq yes
+or
+.Dq no .
+The default is
+.Dq yes .
+.It Cm XAuthLocation
+Specifies the location of the
+.Xr xauth 1
+program.
+The default is
+.Pa /usr/X11R6/bin/xauth .
+.El
+.Ss Time Formats
+.Pp
+.Nm sshd
+command-line arguments and configuration file options that specify time
+may be expressed using a sequence of the form:
+.Sm off
+.Ar time Oo Ar qualifier Oc ,
+.Sm on
+where
+.Ar time
+is a positive integer value and
+.Ar qualifier
+is one of the following:
+.Pp
+.Bl -tag -width Ds -compact -offset indent
+.It Cm <none>
+seconds
+.It Cm s | Cm S
+seconds
+.It Cm m | Cm M
+minutes
+.It Cm h | Cm H
+hours
+.It Cm d | Cm D
+days
+.It Cm w | Cm W
+weeks
+.El
+.Pp
+Each member of the sequence is added together to calculate
+the total time value.
+.Pp
+Time format examples:
+.Pp
+.Bl -tag -width Ds -compact -offset indent
+.It 600
+600 seconds (10 minutes)
+.It 10m
+10 minutes
+.It 1h30m
+1 hour 30 minutes (90 minutes)
+.El
+.Sh FILES
+.Bl -tag -width Ds
+.It Pa /etc/ssh/sshd_config
+Contains configuration data for
+.Nm sshd .
+This file should be writable by root only, but it is recommended
+(though not necessary) that it be world-readable.
+.El
+.Sh AUTHORS
+OpenSSH is a derivative of the original and free
+ssh 1.2.12 release by Tatu Ylonen.
+Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
+Theo de Raadt and Dug Song
+removed many bugs, re-added newer features and
+created OpenSSH.
+Markus Friedl contributed the support for SSH
+protocol versions 1.5 and 2.0.
+Niels Provos and Markus Friedl contributed support
+for privilege separation.
+.Sh SEE ALSO
+.Xr sshd 8
diff --git a/crypto/openssh/ttymodes.c b/crypto/openssh/ttymodes.c
index ccc001f..5cc13dc 100644
--- a/crypto/openssh/ttymodes.c
+++ b/crypto/openssh/ttymodes.c
@@ -43,7 +43,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: ttymodes.c,v 1.16 2001/12/27 20:39:58 markus Exp $");
+RCSID("$OpenBSD: ttymodes.c,v 1.18 2002/06/19 00:27:55 deraadt Exp $");
#include "packet.h"
#include "log.h"
@@ -307,7 +307,6 @@ end:
else
packet_put_raw(buffer_ptr(&buf), buffer_len(&buf));
buffer_free(&buf);
- return;
}
/*
@@ -402,17 +401,17 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
* SSH1:
* Opcodes 1 to 127 are defined to have
* a one-byte argument.
- * Opcodes 128 to 159 are defined to have
- * an integer argument.
- */
+ * Opcodes 128 to 159 are defined to have
+ * an integer argument.
+ */
if (opcode > 0 && opcode < 128) {
n_bytes += 1;
(void) packet_get_char();
break;
} else if (opcode >= 128 && opcode < 160) {
- n_bytes += 4;
- (void) packet_get_int();
- break;
+ n_bytes += 4;
+ (void) packet_get_int();
+ break;
} else {
/*
* It is a truly undefined opcode (160 to 255).
@@ -423,7 +422,7 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
*/
log("parse_tty_modes: unknown opcode %d", opcode);
goto set;
- }
+ }
} else {
/*
* SSH2:
@@ -440,7 +439,7 @@ tty_parse_modes(int fd, int *n_bytes_ptr)
log("parse_tty_modes: unknown opcode %d", opcode);
goto set;
}
- }
+ }
}
}
@@ -457,5 +456,4 @@ set:
/* Set the new modes for the terminal. */
if (tcsetattr(fd, TCSANOW, &tio) == -1)
log("Setting tty modes failed: %.100s", strerror(errno));
- return;
}
diff --git a/crypto/openssh/uidswap.c b/crypto/openssh/uidswap.c
index e794fac..ab43cba 100644
--- a/crypto/openssh/uidswap.c
+++ b/crypto/openssh/uidswap.c
@@ -12,7 +12,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: uidswap.c,v 1.19 2001/12/19 07:18:56 deraadt Exp $");
+RCSID("$OpenBSD: uidswap.c,v 1.22 2002/05/28 21:24:00 stevesk Exp $");
#include "log.h"
#include "uidswap.h"
@@ -46,8 +46,8 @@ temporarily_use_uid(struct passwd *pw)
{
/* Save the current euid, and egroups. */
saved_euid = geteuid();
- debug("temporarily_use_uid: %d/%d (e=%d)",
- pw->pw_uid, pw->pw_gid, saved_euid);
+ debug("temporarily_use_uid: %u/%u (e=%u)",
+ (u_int)pw->pw_uid, (u_int)pw->pw_gid, (u_int)saved_euid);
if (saved_euid != 0) {
privileged = 0;
return;
@@ -71,12 +71,11 @@ temporarily_use_uid(struct passwd *pw)
/* Set the effective uid to the given (unprivileged) uid. */
if (setgroups(user_groupslen, user_groups) < 0)
fatal("setgroups: %.100s", strerror(errno));
- pw->pw_gid = pw->pw_gid;
if (setegid(pw->pw_gid) < 0)
- fatal("setegid %u: %.100s", (u_int) pw->pw_gid,
+ fatal("setegid %u: %.100s", (u_int)pw->pw_gid,
strerror(errno));
if (seteuid(pw->pw_uid) == -1)
- fatal("seteuid %u: %.100s", (u_int) pw->pw_uid,
+ fatal("seteuid %u: %.100s", (u_int)pw->pw_uid,
strerror(errno));
}
@@ -94,11 +93,11 @@ restore_uid(void)
fatal("restore_uid: temporarily_use_uid not effective");
/* Set the effective uid back to the saved privileged uid. */
if (seteuid(saved_euid) < 0)
- fatal("seteuid %u: %.100s", (u_int) saved_euid, strerror(errno));
+ fatal("seteuid %u: %.100s", (u_int)saved_euid, strerror(errno));
if (setgroups(saved_egroupslen, saved_egroups) < 0)
fatal("setgroups: %.100s", strerror(errno));
if (setegid(saved_egid) < 0)
- fatal("setegid %u: %.100s", (u_int) saved_egid, strerror(errno));
+ fatal("setegid %u: %.100s", (u_int)saved_egid, strerror(errno));
temporarily_use_uid_effective = 0;
}
@@ -110,9 +109,9 @@ void
permanently_set_uid(struct passwd *pw)
{
if (temporarily_use_uid_effective)
- fatal("restore_uid: temporarily_use_uid effective");
+ fatal("permanently_set_uid: temporarily_use_uid effective");
if (setgid(pw->pw_gid) < 0)
- fatal("setgid %u: %.100s", (u_int) pw->pw_gid, strerror(errno));
+ fatal("setgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno));
if (setuid(pw->pw_uid) < 0)
- fatal("setuid %u: %.100s", (u_int) pw->pw_uid, strerror(errno));
+ fatal("setuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno));
}
diff --git a/crypto/openssh/xmalloc.h b/crypto/openssh/xmalloc.h
index 338a2d2..7ac4b13 100644
--- a/crypto/openssh/xmalloc.h
+++ b/crypto/openssh/xmalloc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: xmalloc.h,v 1.8 2002/03/04 17:27:39 stevesk Exp $ */
+/* $OpenBSD: xmalloc.h,v 1.9 2002/06/19 00:27:55 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -22,6 +22,6 @@
void *xmalloc(size_t);
void *xrealloc(void *, size_t);
void xfree(void *);
-char *xstrdup(const char *);
+char *xstrdup(const char *);
#endif /* XMALLOC_H */
OpenPOWER on IntegriCloud