summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/ssh/README.altprivsep4
-rw-r--r--usr/src/cmd/ssh/include/g11n.h4
-rw-r--r--usr/src/cmd/ssh/include/monitor.h108
-rw-r--r--usr/src/cmd/ssh/include/monitor_fdpass.h45
-rw-r--r--usr/src/cmd/ssh/include/monitor_mm.h79
-rw-r--r--usr/src/cmd/ssh/include/monitor_wrap.h125
-rw-r--r--usr/src/cmd/ssh/include/packet.h39
-rw-r--r--usr/src/cmd/ssh/include/readconf.h2
-rw-r--r--usr/src/cmd/ssh/libssh/Makefile.com2
-rw-r--r--usr/src/cmd/ssh/libssh/common/g11n.c64
-rw-r--r--usr/src/cmd/ssh/libssh/common/kex.c20
-rw-r--r--usr/src/cmd/ssh/libssh/common/kexdh.c1
-rw-r--r--usr/src/cmd/ssh/libssh/common/kexdhc.c1
-rw-r--r--usr/src/cmd/ssh/libssh/common/kexdhs.c3
-rw-r--r--usr/src/cmd/ssh/libssh/common/kexgex.c1
-rw-r--r--usr/src/cmd/ssh/libssh/common/kexgexc.c1
-rw-r--r--usr/src/cmd/ssh/libssh/common/kexgexs.c5
-rw-r--r--usr/src/cmd/ssh/libssh/common/kexgsss.c6
-rw-r--r--usr/src/cmd/ssh/libssh/common/llib-lssh4
-rw-r--r--usr/src/cmd/ssh/libssh/common/monitor_fdpass.c128
-rw-r--r--usr/src/cmd/ssh/libssh/common/monitor_wrap.c1174
-rw-r--r--usr/src/cmd/ssh/libssh/common/packet.c341
-rw-r--r--usr/src/cmd/ssh/libssh/common/readconf.c56
-rw-r--r--usr/src/cmd/ssh/libssh/common/ssh-gss.c19
-rw-r--r--usr/src/cmd/ssh/libssh/common/xlist.c113
-rw-r--r--usr/src/cmd/ssh/ssh/clientloop.c5
-rw-r--r--usr/src/cmd/ssh/ssh/gss-clnt.c26
-rw-r--r--usr/src/cmd/ssh/ssh/sshconnect2.c3
-rw-r--r--usr/src/cmd/ssh/sshd/Makefile2
-rw-r--r--usr/src/cmd/ssh/sshd/altprivsep.c10
-rw-r--r--usr/src/cmd/ssh/sshd/auth-bsdauth.c1
-rw-r--r--usr/src/cmd/ssh/sshd/auth-options.c7
-rw-r--r--usr/src/cmd/ssh/sshd/auth-pam.c8
-rw-r--r--usr/src/cmd/ssh/sshd/auth-rh-rsa.c4
-rw-r--r--usr/src/cmd/ssh/sshd/auth-rhosts.c4
-rw-r--r--usr/src/cmd/ssh/sshd/auth-rsa.c7
-rw-r--r--usr/src/cmd/ssh/sshd/auth-skey.c1
-rw-r--r--usr/src/cmd/ssh/sshd/auth1.c36
-rw-r--r--usr/src/cmd/ssh/sshd/auth2-gss.c16
-rw-r--r--usr/src/cmd/ssh/sshd/auth2-hostbased.c6
-rw-r--r--usr/src/cmd/ssh/sshd/auth2-none.c7
-rw-r--r--usr/src/cmd/ssh/sshd/auth2-pam.c8
-rw-r--r--usr/src/cmd/ssh/sshd/auth2-passwd.c6
-rw-r--r--usr/src/cmd/ssh/sshd/auth2-pubkey.c12
-rw-r--r--usr/src/cmd/ssh/sshd/auth2.c17
-rw-r--r--usr/src/cmd/ssh/sshd/gss-serv.c3
-rw-r--r--usr/src/cmd/ssh/sshd/monitor.c1852
-rw-r--r--usr/src/cmd/ssh/sshd/monitor_mm.c354
-rw-r--r--usr/src/cmd/ssh/sshd/servconf.c27
-rw-r--r--usr/src/cmd/ssh/sshd/serverloop.c9
-rw-r--r--usr/src/cmd/ssh/sshd/session.c15
-rw-r--r--usr/src/cmd/ssh/sshd/sshd.c284
52 files changed, 515 insertions, 4560 deletions
diff --git a/usr/src/cmd/ssh/README.altprivsep b/usr/src/cmd/ssh/README.altprivsep
index 610a610fa4..73cdeaf80f 100644
--- a/usr/src/cmd/ssh/README.altprivsep
+++ b/usr/src/cmd/ssh/README.altprivsep
@@ -1,4 +1,4 @@
- Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ Copyright 2007 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.
#ident "%Z%%M% %I% %E% SMI"
@@ -612,7 +612,7 @@ A. References
Note that for SSHv1 no on-the-wire messages are processed by the
monitor after authentication. In fact, the monitor thinks it's
- running SSHv2, even if the on-the-wire protocol is v2.
+ running SSHv2, even if the on-the-wire protocol is v1.
A. References
diff --git a/usr/src/cmd/ssh/include/g11n.h b/usr/src/cmd/ssh/include/g11n.h
index 0db14a6b27..9fff281c7b 100644
--- a/usr/src/cmd/ssh/include/g11n.h
+++ b/usr/src/cmd/ssh/include/g11n.h
@@ -18,7 +18,7 @@
*
* CDDL HEADER END
*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -72,6 +72,8 @@ char **g11n_langtag_set_locale_set_intersect(char *langtag_set,
char *g11n_srvr_locale_negotiate(char *clnt_langtags, char **srvr_locales);
+/* auxiliary functions */
+void g11n_freelist(char **list);
/*
* Functions for validating ASCII and UTF-8 strings
diff --git a/usr/src/cmd/ssh/include/monitor.h b/usr/src/cmd/ssh/include/monitor.h
deleted file mode 100644
index ea223d8a66..0000000000
--- a/usr/src/cmd/ssh/include/monitor.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-/* $OpenBSD: monitor.h,v 1.8 2002/09/26 11:38:43 markus Exp $ */
-
-#ifndef _MONITOR_H
-#define _MONITOR_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * 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.
- */
-
-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,
-#ifdef GSSAPI
- MONITOR_REQ_GSSSETUP,MONITOR_ANS_GSSSETUP,
- MONITOR_REQ_GSSSTEP,MONITOR_ANS_GSSSTEP,
- MONITOR_REQ_GSSSIGN,MONITOR_ANS_GSSSIGN,
- MONITOR_REQ_GSSUSEROK,MONITOR_ANS_GSSUSEROK,
- MONITOR_REQ_GSSMECHS,MONITOR_ANS_GSSMECHS,
- MONITOR_REQ_GSSLOCALNAME,MONITOR_ANS_GSSLOCALNAME,
- MONITOR_REQ_GSSERR,MONITOR_ANS_GSSERR,
-#endif
- 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_KRB4, MONITOR_ANS_KRB4,
- MONITOR_REQ_KRB5, MONITOR_ANS_KRB5,
- MONITOR_REQ_PAM_START,
- 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 *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _MONITOR_H */
diff --git a/usr/src/cmd/ssh/include/monitor_fdpass.h b/usr/src/cmd/ssh/include/monitor_fdpass.h
deleted file mode 100644
index d43c0e4fbb..0000000000
--- a/usr/src/cmd/ssh/include/monitor_fdpass.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* $OpenBSD: monitor_fdpass.h,v 1.2 2002/03/26 03:24:01 stevesk Exp $ */
-
-#ifndef _MONITOR_FDPASS_H
-#define _MONITOR_FDPASS_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * 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.
- */
-
-void mm_send_fd(int, int);
-int mm_receive_fd(int);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _MONITOR_FDPASS_H */
diff --git a/usr/src/cmd/ssh/include/monitor_mm.h b/usr/src/cmd/ssh/include/monitor_mm.h
deleted file mode 100644
index 37b53c7355..0000000000
--- a/usr/src/cmd/ssh/include/monitor_mm.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* $OpenBSD: monitor_mm.h,v 1.2 2002/03/26 03:24:01 stevesk Exp $ */
-
-#ifndef _MONITOR_MM_H
-#define _MONITOR_MM_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * 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 "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);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _MONITOR_MM_H */
diff --git a/usr/src/cmd/ssh/include/monitor_wrap.h b/usr/src/cmd/ssh/include/monitor_wrap.h
deleted file mode 100644
index 49a215af53..0000000000
--- a/usr/src/cmd/ssh/include/monitor_wrap.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-/* $OpenBSD: monitor_wrap.h,v 1.8 2002/09/26 11:38:43 markus Exp $ */
-
-#ifndef _MONITOR_WRAP_H
-#define _MONITOR_WRAP_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * 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 "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 *);
-
-#ifdef USE_PAM
-void mm_start_pam(char *);
-#endif
-
-#ifdef GSSAPI
-#include "ssh-gss.h"
-OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *ctxt, gss_buffer_t recv,
- gss_buffer_t send);
-int mm_ssh_gssapi_userok(Gssctxt *ctx, char *user);
-#endif
-
-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 **);
-
-/* auth_krb */
-#ifdef KRB4
-int mm_auth_krb4(struct Authctxt *, void *, char **, void *);
-#endif
-#ifdef KRB5
-/* auth and reply are really krb5_data objects, but we don't want to
- * include all of the krb5 headers here */
-int mm_auth_krb5(void *authctxt, void *auth, char **client, void *reply);
-#endif
-
-/* 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 *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _MONITOR_WRAP_H */
diff --git a/usr/src/cmd/ssh/include/packet.h b/usr/src/cmd/ssh/include/packet.h
index 2ad7a7f94d..8a71eb2864 100644
--- a/usr/src/cmd/ssh/include/packet.h
+++ b/usr/src/cmd/ssh/include/packet.h
@@ -1,15 +1,3 @@
-/* $OpenBSD: packet.h,v 1.35 2002/06/19 18:01:00 markus Exp $ */
-
-#ifndef _PACKET_H
-#define _PACKET_H
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -23,11 +11,24 @@ extern "C" {
* called by a name other than "ssh" or "Secure Shell".
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+#ifndef _PACKET_H
+#define _PACKET_H
+
+/* $OpenBSD: packet.h,v 1.35 2002/06/19 18:01:00 markus Exp $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
#include <openssl/bn.h>
+#include "kex.h"
#ifdef ALTPRIVSEP
/* Monitor-side functions */
@@ -89,14 +90,7 @@ void packet_disconnect(const char *fmt,...) __attribute__((format(printf, 1,
void packet_send_debug(const char *fmt,...) __attribute__((format(printf, 1, 2)));
void set_newkeys(int mode);
-int packet_get_keyiv_len(int);
-void packet_get_keyiv(int, u_char *, u_int);
-int packet_get_keycontext(int, u_char *);
-void packet_set_keycontext(int, u_char *);
-u_int32_t packet_get_seqnr(int);
-void packet_set_seqnr(int, u_int32_t);
-int packet_get_ssh1_cipher(void);
-void packet_set_iv(int, u_char *);
+void free_keys(Newkeys *keys);
void packet_write_poll(void);
void packet_write_wait(void);
@@ -127,6 +121,9 @@ do { \
} \
} while (0)
+int packet_need_rekeying(void);
+void packet_set_rekey_limit(u_int32_t);
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/cmd/ssh/include/readconf.h b/usr/src/cmd/ssh/include/readconf.h
index 3d1fe7b211..d4829960d8 100644
--- a/usr/src/cmd/ssh/include/readconf.h
+++ b/usr/src/cmd/ssh/include/readconf.h
@@ -150,6 +150,8 @@ typedef struct {
int num_remote_forwards;
Forward remote_forwards[SSH_MAX_FORWARDS_PER_DIRECTION];
int clear_forwardings;
+
+ int64_t rekey_limit;
int no_host_authentication_for_localhost;
int server_alive_interval;
int server_alive_count_max;
diff --git a/usr/src/cmd/ssh/libssh/Makefile.com b/usr/src/cmd/ssh/libssh/Makefile.com
index ed02ab1de2..c691c21225 100644
--- a/usr/src/cmd/ssh/libssh/Makefile.com
+++ b/usr/src/cmd/ssh/libssh/Makefile.com
@@ -80,8 +80,6 @@ OBJECTS = \
uuencode.o \
xlist.o \
xmalloc.o \
- monitor_wrap.o \
- monitor_fdpass.o \
readconf.o \
sftp-common.o \
proxy-io.o
diff --git a/usr/src/cmd/ssh/libssh/common/g11n.c b/usr/src/cmd/ssh/libssh/common/g11n.c
index 95b61bef62..6a985db7f3 100644
--- a/usr/src/cmd/ssh/libssh/common/g11n.c
+++ b/usr/src/cmd/ssh/libssh/common/g11n.c
@@ -18,7 +18,7 @@
*
* CDDL HEADER END
*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -57,6 +57,10 @@ static char *g11n_locale2langtag(char *locale);
uint_t g11n_validate_ascii(const char *str, uint_t len, uchar_t **error_str);
uint_t g11n_validate_utf8(const uchar_t *str, uint_t len, uchar_t **error_str);
+/*
+ * Convert locale string name into a language tag. The caller is responsible for
+ * freeing the memory allocated for the result.
+ */
static char *
g11n_locale2langtag(char *locale)
{
@@ -67,7 +71,7 @@ g11n_locale2langtag(char *locale)
return (NULL);
if (strcmp(locale, "POSIX") == 0 || strcmp(locale, "C") == 0)
- return ("i-default");
+ return (xstrdup("i-default"));
/* punt for language codes which are not exactly 2 letters */
if (strlen(locale) < 2 ||
@@ -270,8 +274,10 @@ g11n_getlocales()
list[n_elems++] = xstrdup(locale);
}
- if (n_elems == 0)
+ if (n_elems == 0) {
+ xfree(list);
return (NULL);
+ }
list[n_elems] = NULL;
(void) pclose(locale_out);
@@ -300,7 +306,7 @@ char *
g11n_locales2langs(char **locale_set)
{
char **p, **r, **q;
- char *langtag;
+ char *langtag, *langs;
int locales, skip;
for (locales = 0, p = locale_set; p && *p; p++)
@@ -321,10 +327,15 @@ g11n_locales2langs(char **locale_set)
}
if (!skip)
*(q++) = langtag;
+ else
+ xfree(langtag);
*q = NULL;
}
- return (xjoin(r, ','));
+ langs = xjoin(r, ',');
+ g11n_freelist(r);
+
+ return (langs);
}
static int
@@ -343,12 +354,12 @@ g11n_langtag_match(char *langtag1, char *langtag2)
char c1, c2;
len1 = (strchr(langtag1, '-')) ?
- (strchr(langtag1, '-') - langtag1)
- : strlen(langtag1);
+ (strchr(langtag1, '-') - langtag1)
+ : strlen(langtag1);
len2 = (strchr(langtag2, '-')) ?
- (strchr(langtag2, '-') - langtag2)
- : strlen(langtag2);
+ (strchr(langtag2, '-') - langtag2)
+ : strlen(langtag2);
/* no match */
if (len1 != len2 || strncmp(langtag1, langtag2, len1) != 0)
@@ -628,17 +639,25 @@ g11n_langtag_set_locale_set_intersect(char *langtag_set, char **locale_set)
char *
g11n_srvr_locale_negotiate(char *clnt_langtags, char **srvr_locales)
{
- char **results, *result = NULL;
+ char **results, **locales, *result = NULL;
+
+ if (srvr_locales == NULL)
+ locales = g11n_getlocales();
+ else
+ locales = srvr_locales;
if ((results = g11n_langtag_set_locale_set_intersect(clnt_langtags,
- srvr_locales ? srvr_locales : g11n_getlocales())) == NULL)
- return (NULL);
+ locales)) == NULL)
+ goto err;
if (*results != NULL)
result = xstrdup(*results);
xfree_split_list(results);
+err:
+ if (locales != srvr_locales)
+ g11n_freelist(locales);
return (result);
}
@@ -801,8 +820,8 @@ g11n_convert_from_ascii(const char *str, int *err_ptr, uchar_t **error_str)
* same, and there are aliases of codesets to boot...
*/
if (strcmp("646", nl_langinfo(CODESET)) == 0 ||
- strcmp("ASCII", nl_langinfo(CODESET)) == 0 ||
- strcmp("US-ASCII", nl_langinfo(CODESET)) == 0) {
+ strcmp("ASCII", nl_langinfo(CODESET)) == 0 ||
+ strcmp("US-ASCII", nl_langinfo(CODESET)) == 0) {
initialized = 1;
do_convert = 0;
} else {
@@ -1035,3 +1054,20 @@ do_iconv(iconv_t cd, uint_t *mul_ptr, const void *buf, uint_t len,
return (converted);
}
+
+/*
+ * Free all strings in the list and then free the list itself. We know that the
+ * list ends with a NULL pointer.
+ */
+void
+g11n_freelist(char **list)
+{
+ int i = 0;
+
+ while (list[i] != NULL) {
+ xfree(list[i]);
+ i++;
+ }
+
+ xfree(list);
+}
diff --git a/usr/src/cmd/ssh/libssh/common/kex.c b/usr/src/cmd/ssh/libssh/common/kex.c
index 0e3b8d9365..d535254210 100644
--- a/usr/src/cmd/ssh/libssh/common/kex.c
+++ b/usr/src/cmd/ssh/libssh/common/kex.c
@@ -21,7 +21,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -47,7 +47,6 @@ RCSID("$OpenBSD: kex.c,v 1.51 2002/06/24 14:55:38 markus Exp $");
#include "mac.h"
#include "match.h"
#include "dispatch.h"
-#include "monitor.h"
#include "g11n.h"
#ifdef GSSAPI
@@ -56,10 +55,6 @@ RCSID("$OpenBSD: kex.c,v 1.51 2002/06/24 14:55:38 markus Exp $");
#define KEX_COOKIE_LEN 16
-/* Use privilege separation for sshd */
-int use_privsep;
-struct monitor *pmonitor;
-
char *session_lang = NULL;
@@ -182,11 +177,8 @@ skip_newkeys:
buffer_clear(&kex->peer);
/* buffer_clear(&kex->my); */
kex->flags &= ~KEX_INIT_SENT;
-#if 0
- /* Must have this name for use in sshd (audit_save_kex())... */
xfree(kex->name);
kex->name = NULL;
-#endif
}
void
@@ -543,6 +535,7 @@ kex_choose_conf(Kex *kex)
g11n_setlocale(LC_ALL, locale);
debug("Negotiated main locale: %s", locale);
packet_send_debug("Negotiated main locale: %s", locale);
+ xfree(locale);
}
if (plangs != p_langs_s2c &&
p_langs_s2c && *p_langs_s2c) {
@@ -550,14 +543,11 @@ kex_choose_conf(Kex *kex)
if (locale) {
g11n_setlocale(LC_MESSAGES, locale);
debug("Negotiated messages locale: %s", locale);
- packet_send_debug("Negotiated messages locale: %s", locale);
+ packet_send_debug("Negotiated "
+ "messages locale: %s", locale);
+ xfree(locale);
}
}
- /*
- * Should we free locale? Or does setlocale
- * retain a reference?
- */
- /*xfree(locale);*/
}
}
else {
diff --git a/usr/src/cmd/ssh/libssh/common/kexdh.c b/usr/src/cmd/ssh/libssh/common/kexdh.c
index 7af19994fb..b15ecd2c5b 100644
--- a/usr/src/cmd/ssh/libssh/common/kexdh.c
+++ b/usr/src/cmd/ssh/libssh/common/kexdh.c
@@ -39,7 +39,6 @@ RCSID("$OpenBSD: kexdh.c,v 1.18 2002/03/18 17:50:31 provos Exp $");
#include "packet.h"
#include "dh.h"
#include "ssh2.h"
-#include "monitor_wrap.h"
u_char *
kex_dh_hash(
diff --git a/usr/src/cmd/ssh/libssh/common/kexdhc.c b/usr/src/cmd/ssh/libssh/common/kexdhc.c
index 6e7e7d7dc5..1c75f8449f 100644
--- a/usr/src/cmd/ssh/libssh/common/kexdhc.c
+++ b/usr/src/cmd/ssh/libssh/common/kexdhc.c
@@ -39,7 +39,6 @@ RCSID("$OpenBSD: kexdh.c,v 1.18 2002/03/18 17:50:31 provos Exp $");
#include "packet.h"
#include "dh.h"
#include "ssh2.h"
-#include "monitor_wrap.h"
void
kexdh_client(Kex *kex)
diff --git a/usr/src/cmd/ssh/libssh/common/kexdhs.c b/usr/src/cmd/ssh/libssh/common/kexdhs.c
index 1fc9f4c2ee..5e14b1333f 100644
--- a/usr/src/cmd/ssh/libssh/common/kexdhs.c
+++ b/usr/src/cmd/ssh/libssh/common/kexdhs.c
@@ -39,7 +39,6 @@ RCSID("$OpenBSD: kexdh.c,v 1.18 2002/03/18 17:50:31 provos Exp $");
#include "packet.h"
#include "dh.h"
#include "ssh2.h"
-#include "monitor_wrap.h"
void
kexdh_server(Kex *kex)
@@ -123,7 +122,7 @@ kexdh_server(Kex *kex)
/* sign H */
/* XXX hashlen depends on KEX */
- PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20));
+ key_sign(server_host_key, &signature, &slen, hash, 20);
/* destroy_sensitive_data(); */
diff --git a/usr/src/cmd/ssh/libssh/common/kexgex.c b/usr/src/cmd/ssh/libssh/common/kexgex.c
index 3553bb130f..3652e1c020 100644
--- a/usr/src/cmd/ssh/libssh/common/kexgex.c
+++ b/usr/src/cmd/ssh/libssh/common/kexgex.c
@@ -40,7 +40,6 @@ RCSID("$OpenBSD: kexgex.c,v 1.22 2002/03/24 17:27:03 stevesk Exp $");
#include "dh.h"
#include "ssh2.h"
#include "compat.h"
-#include "monitor_wrap.h"
u_char *
kexgex_hash(
diff --git a/usr/src/cmd/ssh/libssh/common/kexgexc.c b/usr/src/cmd/ssh/libssh/common/kexgexc.c
index 5f6ac3d283..5fddebaed9 100644
--- a/usr/src/cmd/ssh/libssh/common/kexgexc.c
+++ b/usr/src/cmd/ssh/libssh/common/kexgexc.c
@@ -40,7 +40,6 @@ RCSID("$OpenBSD: kexgex.c,v 1.22 2002/03/24 17:27:03 stevesk Exp $");
#include "dh.h"
#include "ssh2.h"
#include "compat.h"
-#include "monitor_wrap.h"
void
kexgex_client(Kex *kex)
diff --git a/usr/src/cmd/ssh/libssh/common/kexgexs.c b/usr/src/cmd/ssh/libssh/common/kexgexs.c
index 60608d2a65..b0bd4e3272 100644
--- a/usr/src/cmd/ssh/libssh/common/kexgexs.c
+++ b/usr/src/cmd/ssh/libssh/common/kexgexs.c
@@ -40,7 +40,6 @@ RCSID("$OpenBSD: kexgex.c,v 1.22 2002/03/24 17:27:03 stevesk Exp $");
#include "dh.h"
#include "ssh2.h"
#include "compat.h"
-#include "monitor_wrap.h"
void
kexgex_server(Kex *kex)
@@ -85,7 +84,7 @@ kexgex_server(Kex *kex)
min, nbits, max);
/* Contact privileged parent */
- dh = PRIVSEP(choose_dh(min, nbits, max));
+ dh = choose_dh(min, nbits, max);
if (dh == NULL)
packet_disconnect("Protocol error: no matching DH grp found");
@@ -168,7 +167,7 @@ kexgex_server(Kex *kex)
/* sign H */
/* XXX hashlen depends on KEX */
- PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20));
+ key_sign(server_host_key, &signature, &slen, hash, 20);
/* destroy_sensitive_data(); */
diff --git a/usr/src/cmd/ssh/libssh/common/kexgsss.c b/usr/src/cmd/ssh/libssh/common/kexgsss.c
index e6a6d67e61..61f3fb70f1 100644
--- a/usr/src/cmd/ssh/libssh/common/kexgsss.c
+++ b/usr/src/cmd/ssh/libssh/common/kexgsss.c
@@ -22,7 +22,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -45,7 +45,6 @@
#include "dh.h"
#include "ssh2.h"
#include "ssh-gss.h"
-#include "monitor_wrap.h"
#include "auth.h"
Gssctxt *xxx_gssctxt;
@@ -127,8 +126,7 @@ kexgss_server(Kex *kex)
type);
}
- maj_status=PRIVSEP(ssh_gssapi_accept_ctx(ctxt,&recv_tok,
- &send_tok));
+ maj_status = ssh_gssapi_accept_ctx(ctxt,&recv_tok, &send_tok);
xfree(recv_tok.value); /* We allocated this, not gss */
diff --git a/usr/src/cmd/ssh/libssh/common/llib-lssh b/usr/src/cmd/ssh/libssh/common/llib-lssh
index f827580891..ed817d9385 100644
--- a/usr/src/cmd/ssh/libssh/common/llib-lssh
+++ b/usr/src/cmd/ssh/libssh/common/llib-lssh
@@ -84,10 +84,6 @@
#include <match.h>
#include <misc.h>
#include <mktemp.h>
-#include <monitor_fdpass.h>
-#include <monitor.h>
-#include <monitor_mm.h>
-#include <monitor_wrap.h>
#include <mpaux.h>
#include <msg.h>
#include <myproposal.h>
diff --git a/usr/src/cmd/ssh/libssh/common/monitor_fdpass.c b/usr/src/cmd/ssh/libssh/common/monitor_fdpass.c
deleted file mode 100644
index 305e45e4cc..0000000000
--- a/usr/src/cmd/ssh/libssh/common/monitor_fdpass.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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.4 2002/06/26 14:50:04 deraadt Exp $");
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <sys/uio.h>
-
-#include "log.h"
-#include "monitor_fdpass.h"
-
-void
-mm_send_fd(int socket, int fd)
-{
-#if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR))
- struct msghdr msg;
- struct iovec vec;
- char ch = '\0';
- ssize_t n;
-#ifndef HAVE_ACCRIGHTS_IN_MSGHDR
- char tmp[CMSG_SPACE(sizeof(int))];
- struct cmsghdr *cmsg;
-#endif
-
- memset(&msg, 0, sizeof(msg));
-#ifdef HAVE_ACCRIGHTS_IN_MSGHDR
- msg.msg_accrights = (caddr_t)&fd;
- msg.msg_accrightslen = sizeof(fd);
-#else
- 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;
-#endif
-
- 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 %ld",
- __func__, (long)n);
-#else
- fatal("%s: UsePrivilegeSeparation=yes not supported",
- __func__);
-#endif
-}
-
-int
-mm_receive_fd(int socket)
-{
-#if defined(HAVE_RECVMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR))
- struct msghdr msg;
- struct iovec vec;
- ssize_t n;
- char ch;
- int fd;
-#ifndef HAVE_ACCRIGHTS_IN_MSGHDR
- char tmp[CMSG_SPACE(sizeof(int))];
- struct cmsghdr *cmsg;
-#endif
-
- memset(&msg, 0, sizeof(msg));
- vec.iov_base = &ch;
- vec.iov_len = 1;
- msg.msg_iov = &vec;
- msg.msg_iovlen = 1;
-#ifdef HAVE_ACCRIGHTS_IN_MSGHDR
- msg.msg_accrights = (caddr_t)&fd;
- msg.msg_accrightslen = sizeof(fd);
-#else
- msg.msg_control = tmp;
- msg.msg_controllen = sizeof(tmp);
-#endif
-
- if ((n = recvmsg(socket, &msg, 0)) == -1)
- fatal("%s: recvmsg: %s", __func__, strerror(errno));
- if (n != 1)
- fatal("%s: recvmsg: expected received 1 got %ld",
- __func__, (long)n);
-
-#ifdef HAVE_ACCRIGHTS_IN_MSGHDR
- if (msg.msg_accrightslen != sizeof(fd))
- fatal("%s: no fd", __func__);
-#else
- 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));
-#endif
- return fd;
-#else
- fatal("%s: UsePrivilegeSeparation=yes not supported",
- __func__);
-#endif
-}
diff --git a/usr/src/cmd/ssh/libssh/common/monitor_wrap.c b/usr/src/cmd/ssh/libssh/common/monitor_wrap.c
deleted file mode 100644
index 4882c3d967..0000000000
--- a/usr/src/cmd/ssh/libssh/common/monitor_wrap.c
+++ /dev/null
@@ -1,1174 +0,0 @@
-/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-/*
- * 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.19 2002/09/26 11:38:43 markus Exp $");
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#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"
-
-#ifdef GSSAPI
-#include "ssh-gss.h"
-#endif
-
-/* 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_int mlen = buffer_len(m);
- u_char buf[5];
-
- 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];
- u_int msg_len;
- ssize_t res;
-
- 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);
-#ifdef HAVE_PW_CLASS_IN_PASSWD
- pw->pw_class = buffer_get_string(&m, NULL);
-#endif
- 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 %u != %u", __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: %u > %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 %u", len);
- buffer_free(&b);
- return (newkey);
-}
-
-int
-mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp)
-{
- Buffer b;
- int len;
- 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);
- if (lenp != NULL)
- *lenp = len;
- if (blobp != NULL) {
- *blobp = xmalloc(len);
- memcpy(*blobp, buffer_ptr(&b), len);
- }
- memset(buffer_ptr(&b), 0, len);
- buffer_free(&b);
- 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;
- 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;
-}
-
-#ifdef USE_PAM
-void
-mm_start_pam(char *user)
-{
- Buffer m;
-
- debug3("%s entering", __func__);
-
- buffer_init(&m);
- buffer_put_cstring(&m, user);
-
- mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, &m);
-
- buffer_free(&m);
-}
-#endif /* USE_PAM */
-
-/* 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);
-}
-
-#ifdef KRB4
-int
-mm_auth_krb4(Authctxt *authctxt, void *_auth, char **client, void *_reply)
-{
- KTEXT auth, reply;
- Buffer m;
- u_int rlen;
- int success = 0;
- char *p;
-
- debug3("%s entering", __func__);
- auth = _auth;
- reply = _reply;
-
- buffer_init(&m);
- buffer_put_string(&m, auth->dat, auth->length);
-
- mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KRB4, &m);
- mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KRB4, &m);
-
- success = buffer_get_int(&m);
- if (success) {
- *client = buffer_get_string(&m, NULL);
- p = buffer_get_string(&m, &rlen);
- if (rlen >= MAX_KTXT_LEN)
- fatal("%s: reply from monitor too large", __func__);
- reply->length = rlen;
- memcpy(reply->dat, p, rlen);
- memset(p, 0, rlen);
- xfree(p);
- }
- buffer_free(&m);
- return (success);
-}
-#endif
-
-#ifdef KRB5
-int
-mm_auth_krb5(void *ctx, void *argp, char **userp, void *resp)
-{
- krb5_data *tkt, *reply;
- Buffer m;
- int success;
-
- debug3("%s entering", __func__);
- tkt = (krb5_data *) argp;
- reply = (krb5_data *) resp;
-
- buffer_init(&m);
- buffer_put_string(&m, tkt->data, tkt->length);
-
- mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KRB5, &m);
- mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KRB5, &m);
-
- success = buffer_get_int(&m);
- if (success) {
- u_int len;
-
- *userp = buffer_get_string(&m, NULL);
- reply->data = buffer_get_string(&m, &len);
- reply->length = len;
- } else {
- memset(reply, 0, sizeof(*reply));
- *userp = NULL;
- }
-
- buffer_free(&m);
- return (success);
-}
-#endif
-#ifdef GSSAPI
-OM_uint32
-mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) {
- Buffer m;
- OM_uint32 major;
-
- /* Client doesn't get to see the context */
- *ctx=NULL;
-
- buffer_init(&m);
- buffer_put_string(&m,oid->elements,oid->length);
-
- mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m);
- mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m);
-
- major=buffer_get_int(&m);
-
- buffer_free(&m);
- return(major);
-}
-
-OM_uint32
-mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_t in,
- gss_buffer_t out) {
-
- Buffer m;
- OM_uint32 major;
-
- buffer_init(&m);
- buffer_put_string(&m, in->value, in->length);
-
- mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m);
- mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m);
-
- major=buffer_get_int(&m);
- out->value=buffer_get_string(&m,&out->length);
- buffer_free(&m);
-
- return(major);
-}
-
-int
-mm_ssh_gssapi_userok(Gssctxt *ctx, char *user) {
- Buffer m;
- int authenticated = 0;
-
- buffer_init(&m);
-
- mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m);
- mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK,
- &m);
-
- authenticated = buffer_get_int(&m);
-
- buffer_free(&m);
- debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
- return(authenticated);
-}
-
-OM_uint32
-mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash) {
- Buffer m;
- OM_uint32 major;
-
- buffer_init(&m);
- buffer_put_string(&m, data->value, data->length);
-
- mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSIGN, &m);
- mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSIGN, &m);
-
- major=buffer_get_int(&m);
- hash->value = buffer_get_string(&m, &hash->length);
-
- buffer_free(&m);
-
- return(major);
-}
-
-char *
-mm_ssh_gssapi_last_error(Gssctxt *ctx, OM_uint32 *major, OM_uint32 *minor) {
- Buffer m;
- OM_uint32 maj,min;
- char *errstr;
-
- buffer_init(&m);
-
- mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSERR, &m);
- mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSERR, &m);
-
- maj = buffer_get_int(&m);
- min = buffer_get_int(&m);
-
- if (major) *major=maj;
- if (minor) *minor=min;
-
- errstr=buffer_get_string(&m,NULL);
-
- buffer_free(&m);
-
- return(errstr);
-}
-
-OM_uint32
-mm_gss_indicate_mechs(OM_uint32 *minor_status, gss_OID_set *mech_set)
-{
- Buffer m;
- OM_uint32 major,minor;
- int count;
- gss_OID_desc oid;
- u_int length;
-
- buffer_init(&m);
-
- mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSMECHS, &m);
- mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSMECHS,
- &m);
- major=buffer_get_int(&m);
- count=buffer_get_int(&m);
-
- gss_create_empty_oid_set(&minor,mech_set);
- while(count-->0) {
- oid.elements=buffer_get_string(&m,&length);
- oid.length=length;
- gss_add_oid_set_member(&minor,&oid,mech_set);
- }
-
- buffer_free(&m);
-
- return(major);
-}
-
-int
-mm_ssh_gssapi_localname(char **lname)
-{
- Buffer m;
-
- buffer_init(&m);
- mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSLOCALNAME, &m);
-
- debug3("%s: waiting for MONITOR_ANS_GSSLOCALNAME", __func__);
- mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSLOCALNAME,
- &m);
-
- *lname = buffer_get_string(&m, NULL);
-
- buffer_free(&m);
- if (lname[0] == '\0') {
- debug3("%s: gssapi identity mapping failed", __func__);
- } else {
- debug3("%s: gssapi identity mapped to %s", __func__, *lname);
- }
-
- return(0);
-}
-#endif /* GSSAPI */
diff --git a/usr/src/cmd/ssh/libssh/common/packet.c b/usr/src/cmd/ssh/libssh/common/packet.c
index 10fbdd0895..985666a576 100644
--- a/usr/src/cmd/ssh/libssh/common/packet.c
+++ b/usr/src/cmd/ssh/libssh/common/packet.c
@@ -36,30 +36,29 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#include "includes.h"
-RCSID("$OpenBSD: packet.c,v 1.97 2002/07/04 08:12:15 deraadt Exp $");
+/* $OpenBSD: packet.c,v 1.148 2007/06/07 19:37:34 pvalchev Exp $ */
#pragma ident "%Z%%M% %I% %E% SMI"
+#include "includes.h"
+
+#include "sys-queue.h"
#include "xmalloc.h"
#include "buffer.h"
#include "packet.h"
#include "bufaux.h"
#include "crc32.h"
#include "getput.h"
-
#include "compress.h"
#include "deattack.h"
#include "channels.h"
-
#include "compat.h"
#include "ssh1.h"
#include "ssh2.h"
-
#include "cipher.h"
#include "kex.h"
#include "mac.h"
@@ -127,8 +126,14 @@ 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;
+static struct packet_state {
+ u_int32_t seqnr;
+ u_int32_t packets;
+ u_int64_t blocks;
+} p_read, p_send;
+
+static u_int64_t max_blocks_in, max_blocks_out;
+static u_int32_t rekey_limit;
/* Session key for protocol v1 */
static u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
@@ -137,6 +142,13 @@ static u_int ssh1_keylen;
/* roundup current message to extra_pad bytes */
static u_char extra_pad = 0;
+struct packet {
+ TAILQ_ENTRY(packet) next;
+ u_char type;
+ Buffer payload;
+};
+TAILQ_HEAD(, packet) outgoing;
+
/*
* Sets the descriptors used for communication. Disables encryption until
* packet_set_encryption_key is called.
@@ -159,6 +171,7 @@ packet_set_connection(int fd_in, int fd_out)
buffer_init(&output);
buffer_init(&outgoing_packet);
buffer_init(&incoming_packet);
+ TAILQ_INIT(&outgoing);
} else {
buffer_clear(&input);
buffer_clear(&output);
@@ -202,99 +215,6 @@ 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
@@ -478,21 +398,25 @@ packet_put_char(int value)
buffer_append(&outgoing_packet, &ch, 1);
}
+
void
packet_put_int(u_int value)
{
buffer_put_int(&outgoing_packet, value);
}
+
void
packet_put_string(const void *buf, u_int len)
{
buffer_put_string(&outgoing_packet, buf, len);
}
+
void
packet_put_cstring(const char *str)
{
buffer_put_cstring(&outgoing_packet, str);
}
+
void
packet_put_ascii_cstring(const char *str)
{
@@ -520,11 +444,13 @@ packet_put_raw(const void *buf, u_int len)
{
buffer_append(&outgoing_packet, buf, len);
}
+
void
packet_put_bignum(BIGNUM * value)
{
buffer_put_bignum(&outgoing_packet, value);
}
+
void
packet_put_bignum2(BIGNUM * value)
{
@@ -542,7 +468,7 @@ packet_send1(void)
u_char buf[8], *cp;
int i, padding, len;
u_int checksum;
- u_int32_t rand = 0;
+ u_int32_t rnd = 0;
/*
* If using packet compression, compress the payload of the outgoing
@@ -568,9 +494,9 @@ packet_send1(void)
cp = buffer_ptr(&outgoing_packet);
for (i = 0; i < padding; i++) {
if (i % 4 == 0)
- rand = arc4random();
- cp[7 - i] = rand & 0xff;
- rand >>= 8;
+ rnd = arc4random();
+ cp[7 - i] = rnd & 0xff;
+ rnd >>= 8;
}
}
buffer_consume(&outgoing_packet, 8 - padding);
@@ -614,31 +540,26 @@ set_newkeys(int mode)
Mac *mac;
Comp *comp;
CipherContext *cc;
- int encrypt;
+ u_int64_t *max_blocks;
+ int crypt_type;
- debug("newkeys: mode %d", mode);
+ debug2("set_newkeys: mode %d", mode);
if (mode == MODE_OUT) {
cc = &send_context;
- encrypt = CIPHER_ENCRYPT;
+ crypt_type = CIPHER_ENCRYPT;
+ p_send.packets = p_send.blocks = 0;
+ max_blocks = &max_blocks_out;
} else {
cc = &receive_context;
- encrypt = CIPHER_DECRYPT;
+ crypt_type = CIPHER_DECRYPT;
+ p_read.packets = p_read.blocks = 0;
+ max_blocks = &max_blocks_in;
}
if (newkeys[mode] != NULL) {
- debug("newkeys: rekeying");
+ debug("set_newkeys: rekeying");
cipher_cleanup(cc);
- enc = &newkeys[mode]->enc;
- mac = &newkeys[mode]->mac;
- comp = &newkeys[mode]->comp;
- memset(mac->key, 0, mac->key_len);
- xfree(enc->name);
- xfree(enc->iv);
- xfree(enc->key);
- xfree(mac->name);
- xfree(mac->key);
- xfree(comp->name);
- xfree(newkeys[mode]);
+ free_keys(newkeys[mode]);
}
newkeys[mode] = kex_get_newkeys(mode);
if (newkeys[mode] == NULL)
@@ -650,7 +571,7 @@ set_newkeys(int mode)
mac->enabled = 1;
DBG(debug("cipher_init_context: %d", mode));
cipher_init(cc, enc->cipher, enc->key, enc->key_len,
- enc->iv, enc->block_size, encrypt);
+ enc->iv, enc->block_size, crypt_type);
/* Deleting the keys does not gain extra security */
/* memset(enc->iv, 0, enc->block_size);
memset(enc->key, 0, enc->key_len); */
@@ -662,19 +583,74 @@ set_newkeys(int mode)
buffer_compress_init_recv();
comp->enabled = 1;
}
+
+ /*
+ * In accordance to the RFCs listed below we enforce the key
+ * re-exchange for:
+ *
+ * - every 1GB of transmitted data if the selected cipher block size
+ * is less than 16 bytes (3DES, Blowfish)
+ * - every 2^(2*B) cipher blocks transmitted (B is block size in bytes)
+ * if the cipher block size is greater than or equal to 16 bytes (AES)
+ * - and we never send more than 2^32 SSH packets using the same keys.
+ * The recommendation of 2^31 packets is not enforced here but in
+ * packet_need_rekeying(). There is also a hard check in
+ * packet_send2_wrapped() that we don't send more than 2^32 packets.
+ *
+ * Note that if the SSH_BUG_NOREKEY compatibility flag is set then no
+ * automatic rekeying is performed nor do we enforce the 3rd rule.
+ * This means that we can be always forced by the opposite side to never
+ * initiate automatic key re-exchange. This might change in the future.
+ *
+ * The RekeyLimit option keyword may only enforce more frequent key
+ * renegotiation, never less. For more information on key renegotiation,
+ * see:
+ *
+ * - RFC 4253 (SSH Transport Layer Protocol), section "9. Key
+ * Re-Exchange"
+ * - RFC 4344 (SSH Transport Layer Encryption Modes), sections "3.
+ * Rekeying" and "6.1 Rekeying Considerations"
+ */
+ if (enc->block_size >= 16)
+ *max_blocks = (u_int64_t)1 << (enc->block_size * 2);
+ else
+ *max_blocks = ((u_int64_t)1 << 30) / enc->block_size;
+
+ if (rekey_limit)
+ *max_blocks = MIN(*max_blocks, rekey_limit / enc->block_size);
+}
+
+void
+free_keys(Newkeys *keys)
+{
+ Enc *enc;
+ Mac *mac;
+ Comp *comp;
+
+ enc = &keys->enc;
+ mac = &keys->mac;
+ comp = &keys->comp;
+ memset(mac->key, 0, mac->key_len);
+ xfree(enc->name);
+ xfree(enc->iv);
+ xfree(enc->key);
+ xfree(mac->name);
+ xfree(mac->key);
+ xfree(comp->name);
+ xfree(keys);
}
/*
* Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
*/
static void
-packet_send2(void)
+packet_send2_wrapped(void)
{
u_char type, *cp, *macbuf = NULL;
u_char padlen, pad;
u_int packet_length = 0;
u_int i, len;
- u_int32_t rand = 0;
+ u_int32_t rnd = 0;
Enc *enc = NULL;
Mac *mac = NULL;
Comp *comp = NULL;
@@ -733,9 +709,9 @@ packet_send2(void)
/* random padding */
for (i = 0; i < padlen; i++) {
if (i % 4 == 0)
- rand = arc4random();
- cp[i] = rand & 0xff;
- rand >>= 8;
+ rnd = arc4random();
+ cp[i] = rnd & 0xff;
+ rnd >>= 8;
}
} else {
/* clear padding */
@@ -750,10 +726,10 @@ packet_send2(void)
/* compute MAC over seqnr and packet(length fields, payload, padding) */
if (mac && mac->enabled) {
- macbuf = mac_compute(mac, send_seqnr,
+ macbuf = mac_compute(mac, p_send.seqnr,
buffer_ptr(&outgoing_packet),
buffer_len(&outgoing_packet));
- DBG(debug("done calc MAC out #%d", send_seqnr));
+ DBG(debug("done calc MAC out #%d", p_send.seqnr));
}
/* encrypt packet and append to output buffer. */
cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
@@ -767,8 +743,25 @@ packet_send2(void)
buffer_dump(&output);
#endif
/* increment sequence number for outgoing packets */
- if (++send_seqnr == 0)
+ if (++p_send.seqnr == 0)
log("outgoing seqnr wraps around");
+
+ /*
+ * RFC 4344: 3.1. First Rekeying Recommendation
+ *
+ * "Because of possible information leakage through the MAC tag after a
+ * key exchange, .... an SSH implementation SHOULD NOT send more than
+ * 2**32 packets before rekeying again."
+ *
+ * The code below is a hard check so that we are sure we don't go across
+ * the suggestion. However, since the largest cipher block size we have
+ * (AES) is 16 bytes we can't reach 2^32 SSH packets encrypted with the
+ * same key while performing periodic rekeying.
+ */
+ if (++p_send.packets == 0)
+ if (!(datafellows & SSH_BUG_NOREKEY))
+ fatal("too many packets encrypted with same key");
+ p_send.blocks += (packet_length + 4) / block_size;
buffer_clear(&outgoing_packet);
if (type == SSH2_MSG_NEWKEYS)
@@ -779,6 +772,51 @@ packet_send2(void)
set_newkeys(MODE_OUT);
}
+static void
+packet_send2(void)
+{
+ static int rekeying = 0;
+ struct packet *p;
+ u_char type, *cp;
+
+ cp = buffer_ptr(&outgoing_packet);
+ type = cp[5];
+
+ /* during rekeying we can only send key exchange messages */
+ if (rekeying) {
+ if (!((type >= SSH2_MSG_TRANSPORT_MIN) &&
+ (type <= SSH2_MSG_TRANSPORT_MAX))) {
+ debug("enqueue packet: %u", type);
+ p = xmalloc(sizeof(*p));
+ p->type = type;
+ memcpy(&p->payload, &outgoing_packet, sizeof(Buffer));
+ buffer_init(&outgoing_packet);
+ TAILQ_INSERT_TAIL(&outgoing, p, next);
+ return;
+ }
+ }
+
+ /* rekeying starts with sending KEXINIT */
+ if (type == SSH2_MSG_KEXINIT)
+ rekeying = 1;
+
+ packet_send2_wrapped();
+
+ /* after a NEWKEYS message we can send the complete queue */
+ if (type == SSH2_MSG_NEWKEYS) {
+ rekeying = 0;
+ while ((p = TAILQ_FIRST(&outgoing)) != NULL) {
+ type = p->type;
+ debug("dequeue packet: %u", type);
+ buffer_free(&outgoing_packet);
+ memcpy(&outgoing_packet, &p->payload, sizeof(Buffer));
+ TAILQ_REMOVE(&outgoing, p, next);
+ xfree(p);
+ packet_send2_wrapped();
+ }
+ }
+}
+
void
packet_send(void)
{
@@ -1003,7 +1041,7 @@ packet_read_poll2(u_int32_t *seqnr_p)
buffer_dump(&incoming_packet);
packet_disconnect("Bad packet length %d.", packet_length);
}
- DBG(debug("input: packet len %d", packet_length+4));
+ DBG(debug("input: packet len %u", packet_length + 4));
buffer_consume(&input, block_size);
}
/* we have a partial packet of block_size bytes */
@@ -1031,19 +1069,25 @@ packet_read_poll2(u_int32_t *seqnr_p)
* increment sequence number for incoming packet
*/
if (mac && mac->enabled) {
- macbuf = mac_compute(mac, read_seqnr,
+ macbuf = mac_compute(mac, p_read.seqnr,
buffer_ptr(&incoming_packet),
buffer_len(&incoming_packet));
if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0)
packet_disconnect("Corrupted MAC on input.");
- DBG(debug("MAC #%d ok", read_seqnr));
+ DBG(debug("MAC #%d ok", p_read.seqnr));
buffer_consume(&input, mac->mac_len);
}
if (seqnr_p != NULL)
- *seqnr_p = read_seqnr;
- if (++read_seqnr == 0)
+ *seqnr_p = p_read.seqnr;
+ if (++p_read.seqnr == 0)
log("incoming seqnr wraps around");
+ /* see above for the comment on "First Rekeying Recommendation" */
+ if (++p_read.packets == 0)
+ if (!(datafellows & SSH_BUG_NOREKEY))
+ fatal("too many packets with same key");
+ p_read.blocks += (packet_length + 4) / block_size;
+
/* get padlen */
cp = buffer_ptr(&incoming_packet);
padlen = cp[4];
@@ -1518,7 +1562,7 @@ packet_add_padding(u_char pad)
void
packet_send_ignore(int nbytes)
{
- u_int32_t rand = 0;
+ u_int32_t rnd = 0;
int i;
#ifdef ALTPRIVSEP
@@ -1531,12 +1575,31 @@ packet_send_ignore(int nbytes)
packet_put_int(nbytes);
for (i = 0; i < nbytes; i++) {
if (i % 4 == 0)
- rand = arc4random();
- packet_put_char(rand & 0xff);
- rand >>= 8;
+ rnd = arc4random();
+ packet_put_char((u_char)rnd & 0xff);
+ rnd >>= 8;
}
}
+#define MAX_PACKETS (1U<<31)
+int
+packet_need_rekeying(void)
+{
+ if (datafellows & SSH_BUG_NOREKEY)
+ return 0;
+ return
+ (p_send.packets > MAX_PACKETS) ||
+ (p_read.packets > MAX_PACKETS) ||
+ (max_blocks_out && (p_send.blocks > max_blocks_out)) ||
+ (max_blocks_in && (p_read.blocks > max_blocks_in));
+}
+
+void
+packet_set_rekey_limit(u_int32_t bytes)
+{
+ rekey_limit = bytes;
+}
+
#ifdef ALTPRIVSEP
void
packet_set_server(void)
diff --git a/usr/src/cmd/ssh/libssh/common/readconf.c b/usr/src/cmd/ssh/libssh/common/readconf.c
index 86caa54913..e08ff1e0b0 100644
--- a/usr/src/cmd/ssh/libssh/common/readconf.c
+++ b/usr/src/cmd/ssh/libssh/common/readconf.c
@@ -129,7 +129,8 @@ typedef enum {
oClearAllForwardings, oNoHostAuthenticationForLocalhost,
oFallBackToRsh, oUseRsh, oConnectTimeout, oHashKnownHosts,
oServerAliveInterval, oServerAliveCountMax, oDisableBanner,
- oIgnoreIfUnknown, oDeprecated
+ oIgnoreIfUnknown, oRekeyLimit,
+ oDeprecated
} OpCodes;
/* Textual representations of the tokens. */
@@ -215,6 +216,7 @@ static struct {
{ "smartcarddevice", oSmartcardDevice },
{ "clearallforwardings", oClearAllForwardings },
{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
+ { "rekeylimit", oRekeyLimit },
{ "connecttimeout", oConnectTimeout },
{ "serveraliveinterval", oServerAliveInterval },
{ "serveralivecountmax", oServerAliveCountMax },
@@ -318,7 +320,8 @@ process_config_line(Options *options, const char *host,
int *activep)
{
char *s, *string, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
- int opcode, *intptr, value, i;
+ int opcode, *intptr, value, scale, i;
+ long long orig, val64;
StoredOption *so;
Forward fwd;
@@ -530,6 +533,44 @@ parse_flag:
intptr = &options->compression_level;
goto parse_int;
+ case oRekeyLimit:
+ arg = strdelim(&s);
+ if (!arg || *arg == '\0')
+ fatal("%.200s line %d: Missing argument.", filename, linenum);
+ if (arg[0] < '0' || arg[0] > '9')
+ fatal("%.200s line %d: Bad number.", filename, linenum);
+ orig = val64 = strtoll(arg, &endofnumber, 10);
+ if (arg == endofnumber)
+ fatal("%.200s line %d: Bad number.", filename, linenum);
+ switch (toupper(*endofnumber)) {
+ case '\0':
+ scale = 1;
+ break;
+ case 'K':
+ scale = 1<<10;
+ break;
+ case 'M':
+ scale = 1<<20;
+ break;
+ case 'G':
+ scale = 1<<30;
+ break;
+ default:
+ fatal("%.200s line %d: Invalid RekeyLimit suffix",
+ filename, linenum);
+ }
+ val64 *= scale;
+ /* detect integer wrap and too-large limits */
+ if ((val64 / scale) != orig || val64 > UINT_MAX)
+ fatal("%.200s line %d: RekeyLimit too large",
+ filename, linenum);
+ if (val64 < 16)
+ fatal("%.200s line %d: RekeyLimit too small",
+ filename, linenum);
+ if (*activep && options->rekey_limit == -1)
+ options->rekey_limit = (u_int32_t)val64;
+ break;
+
case oIdentityFile:
arg = strdelim(&s);
if (!arg || *arg == '\0')
@@ -938,7 +979,8 @@ initialize_options(Options * options)
options->preferred_authentications = NULL;
options->bind_address = NULL;
options->smartcard_device = NULL;
- options->no_host_authentication_for_localhost = - 1;
+ options->no_host_authentication_for_localhost = -1;
+ options->rekey_limit = -1;
options->fallback_to_rsh = -1;
options->use_rsh = -1;
options->server_alive_interval = -1;
@@ -1077,11 +1119,13 @@ fill_default_options(Options * options)
options->log_level = SYSLOG_LEVEL_INFO;
if (options->clear_forwardings == 1)
clear_forwardings(options);
- if (options->no_host_authentication_for_localhost == - 1)
+ if (options->no_host_authentication_for_localhost == -1)
options->no_host_authentication_for_localhost = 0;
- if (options->fallback_to_rsh == - 1)
+ if (options->rekey_limit == -1)
+ options->rekey_limit = 0;
+ if (options->fallback_to_rsh == -1)
options->fallback_to_rsh = 0;
- if (options->use_rsh == - 1)
+ if (options->use_rsh == -1)
options->use_rsh = 0;
if (options->server_alive_interval == -1)
options->server_alive_interval = 0;
diff --git a/usr/src/cmd/ssh/libssh/common/ssh-gss.c b/usr/src/cmd/ssh/libssh/common/ssh-gss.c
index 17af3f0c41..fcf8e11b51 100644
--- a/usr/src/cmd/ssh/libssh/common/ssh-gss.c
+++ b/usr/src/cmd/ssh/libssh/common/ssh-gss.c
@@ -21,7 +21,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -44,7 +44,6 @@
#include "log.h"
#include "compat.h"
#include "xlist.h"
-#include "monitor_wrap.h"
#include <netdb.h>
@@ -523,13 +522,17 @@ void ssh_gssapi_set_oid(Gssctxt *ctx, gss_OID oid) {
/* All this effort to report an error ... */
void
-ssh_gssapi_error(Gssctxt *ctxt, const char *where) {
- if (where)
- debug("GSS-API error while %s: %s", where,
- ssh_gssapi_last_error(ctxt,NULL,NULL));
+ssh_gssapi_error(Gssctxt *ctxt, const char *where)
+{
+ char *errmsg = ssh_gssapi_last_error(ctxt, NULL, NULL);
+
+ if (where != NULL)
+ debug("GSS-API error while %s: %s", where, errmsg);
else
- debug("GSS-API error: %s",
- ssh_gssapi_last_error(ctxt,NULL,NULL));
+ debug("GSS-API error: %s", errmsg);
+
+ /* ssh_gssapi_last_error() can't return NULL */
+ xfree(errmsg);
}
char *
diff --git a/usr/src/cmd/ssh/libssh/common/xlist.c b/usr/src/cmd/ssh/libssh/common/xlist.c
index 45a5611510..c44e420eeb 100644
--- a/usr/src/cmd/ssh/libssh/common/xlist.c
+++ b/usr/src/cmd/ssh/libssh/common/xlist.c
@@ -1,7 +1,7 @@
- /*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
+/*
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -13,66 +13,73 @@
char **
xsplit(char *list, char sep)
{
- char **a;
- char *p, *q;
- u_int n = 0;
+ char **a;
+ char *p, *q;
+ uint_t n = 0;
- for (n = 0, p = list ; p && *p ; ) {
- while (p && *p && *p == sep) p++;
- if (!*p) break;
- n++;
- p = strchr(p, sep);
- }
- a = (char **) xmalloc(sizeof(char *) * (n + 2));
- for (n = 0, p = list ; p && *p ; ) {
- while (*p == sep) p++;
- if (!*p) break;
- q = strchr(p, sep);
- if (!q)
- q = p + strlen(p);
- a[n] = (char *) xmalloc((q - p + 2));
- (void) strncpy(a[n], p, q - p);
- a[n][q - p] = '\0';
- n++;
- if (!*q) break;
- p = q+1;
- }
- a[n] = NULL;
- return a;
+ for (n = 0, p = list; p && *p; ) {
+ while (p && *p && *p == sep)
+ p++;
+ if (!*p)
+ break;
+ n++;
+ p = strchr(p, sep);
+ }
+ a = (char **)xmalloc(sizeof (char *) * (n + 2));
+ for (n = 0, p = list; p && *p; ) {
+ while (*p == sep)
+ p++;
+ if (!*p)
+ break;
+ q = strchr(p, sep);
+ if (!q)
+ q = p + strlen(p);
+ a[n] = (char *)xmalloc((q - p + 2));
+ (void) strncpy(a[n], p, q - p);
+ a[n][q - p] = '\0';
+ n++;
+ if (!*q)
+ break;
+ p = q + 1;
+ }
+ a[n] = NULL;
+ return (a);
}
void
xfree_split_list(char **list)
{
- char **p;
- for (p = list ; p && *p ; p++) {
- xfree(*p);
- }
- xfree(list);
+ char **p;
+ for (p = list; p && *p; p++) {
+ xfree(*p);
+ }
+ xfree(list);
}
char *
xjoin(char **alist, char sep)
{
- char **p;
- char *list;
- char sep_str[2];
- u_int n;
+ char **p;
+ char *list;
+ char sep_str[2];
+ uint_t n;
- for (n = 1, p = alist ; p && *p ; p++) {
- if (!*p || !**p) continue;
- n += strlen(*p) + 1;
- }
- list = (char *) xmalloc(n);
- *list = '\0';
+ for (n = 1, p = alist; p && *p; p++) {
+ if (!*p || !**p)
+ continue;
+ n += strlen(*p) + 1;
+ }
+ list = (char *)xmalloc(n);
+ *list = '\0';
- sep_str[0] = sep;
- sep_str[1] = '\0';
- for (p = alist ; p && *p ; p++) {
- if (!*p || !**p) continue;
- if (*list != '\0')
- (void) strlcat(list, sep_str, n);
- (void) strlcat(list, *p, n);
- }
- return list;
+ sep_str[0] = sep;
+ sep_str[1] = '\0';
+ for (p = alist; p && *p; p++) {
+ if (!*p || !**p)
+ continue;
+ if (*list != '\0')
+ (void) strlcat(list, sep_str, n);
+ (void) strlcat(list, *p, n);
+ }
+ return (list);
}
diff --git a/usr/src/cmd/ssh/ssh/clientloop.c b/usr/src/cmd/ssh/ssh/clientloop.c
index 6485414a57..5929b7b6e0 100644
--- a/usr/src/cmd/ssh/ssh/clientloop.c
+++ b/usr/src/cmd/ssh/ssh/clientloop.c
@@ -1176,9 +1176,8 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
/* Do channel operations unless rekeying in progress. */
if (!rekeying) {
channel_after_select(readset, writeset);
-
- if (need_rekeying) {
- debug("user requests rekeying");
+ if (need_rekeying || packet_need_rekeying()) {
+ debug("need rekeying");
xxx_kex->done = 0;
kex_send_kexinit(xxx_kex);
need_rekeying = 0;
diff --git a/usr/src/cmd/ssh/ssh/gss-clnt.c b/usr/src/cmd/ssh/ssh/gss-clnt.c
index da65fe4666..3d536da7a6 100644
--- a/usr/src/cmd/ssh/ssh/gss-clnt.c
+++ b/usr/src/cmd/ssh/ssh/gss-clnt.c
@@ -21,7 +21,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -43,7 +43,6 @@
#include "kex.h"
#include "log.h"
#include "compat.h"
-#include "monitor_wrap.h"
#include <netdb.h>
@@ -72,6 +71,7 @@ ssh_gssapi_client_mechs(const char *server_host, gss_OID_set *mechs)
gss_buffer_desc tok;
OM_uint32 maj, min;
int i;
+ char *errmsg;
if (!mechs)
return;
@@ -85,8 +85,9 @@ ssh_gssapi_client_mechs(const char *server_host, gss_OID_set *mechs)
maj = gss_create_empty_oid_set(&min, &supported);
if (GSS_ERROR(maj)) {
- debug("Failed to allocate resources (%s) for GSS-API",
- ssh_gssapi_last_error(NULL, &maj, &min));
+ errmsg = ssh_gssapi_last_error(NULL, &maj, &min);
+ debug("Failed to allocate resources (%s) for GSS-API", errmsg);
+ xfree(errmsg);
(void) gss_release_oid_set(&min, &indicated);
return;
}
@@ -94,9 +95,10 @@ ssh_gssapi_client_mechs(const char *server_host, gss_OID_set *mechs)
GSS_C_INITIATE, &creds, &acquired, NULL);
if (GSS_ERROR(maj)) {
+ errmsg = ssh_gssapi_last_error(NULL, &maj, &min);
debug("Failed to acquire GSS-API credentials for any "
- "mechanisms (%s)",
- ssh_gssapi_last_error(NULL, &maj, &min));
+ "mechanisms (%s)", errmsg);
+ xfree(errmsg);
(void) gss_release_oid_set(&min, &indicated);
(void) gss_release_oid_set(&min, &supported);
return;
@@ -125,18 +127,22 @@ ssh_gssapi_client_mechs(const char *server_host, gss_OID_set *mechs)
maj = ssh_gssapi_init_ctx(ctxt, server_host, 0,
NULL, &tok);
if (GSS_ERROR(maj)) {
+ errmsg = ssh_gssapi_last_error(ctxt, NULL, NULL);
debug("Skipping GSS-API mechanism %s (%s)",
- ssh_gssapi_oid_to_name(mech),
- ssh_gssapi_last_error(ctxt, NULL, NULL));
+ ssh_gssapi_oid_to_name(mech), errmsg);
+ xfree(errmsg);
continue;
}
(void) gss_release_buffer(&min, &tok);
maj = gss_add_oid_set_member(&min, mech, &supported);
- if (GSS_ERROR(maj))
+ if (GSS_ERROR(maj)) {
+ errmsg = ssh_gssapi_last_error(NULL, &maj, &min);
debug("Failed to allocate resources (%s) for GSS-API",
- ssh_gssapi_last_error(NULL, &maj, &min));
+ errmsg);
+ xfree(errmsg);
+ }
}
*mechs = supported;
diff --git a/usr/src/cmd/ssh/ssh/sshconnect2.c b/usr/src/cmd/ssh/ssh/sshconnect2.c
index 5b2901ee32..9b95a15f2c 100644
--- a/usr/src/cmd/ssh/ssh/sshconnect2.c
+++ b/usr/src/cmd/ssh/ssh/sshconnect2.c
@@ -137,6 +137,9 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
options.hostkeyalgorithms;
+ if (options.rekey_limit)
+ packet_set_rekey_limit((u_int32_t)options.rekey_limit);
+
if (datafellows & SSH_BUG_LOCALES_NOT_LANGTAGS) {
char *locale = setlocale(LC_ALL, "");
diff --git a/usr/src/cmd/ssh/sshd/Makefile b/usr/src/cmd/ssh/sshd/Makefile
index 9999f6feff..51392676fb 100644
--- a/usr/src/cmd/ssh/sshd/Makefile
+++ b/usr/src/cmd/ssh/sshd/Makefile
@@ -60,8 +60,6 @@ OBJS = sshd.o \
gss-serv.o \
loginrec.o \
md5crypt.o \
- monitor.o \
- monitor_mm.o \
servconf.o \
serverloop.o \
session.o \
diff --git a/usr/src/cmd/ssh/sshd/altprivsep.c b/usr/src/cmd/ssh/sshd/altprivsep.c
index e3636efeb7..c2c0a17e8b 100644
--- a/usr/src/cmd/ssh/sshd/altprivsep.c
+++ b/usr/src/cmd/ssh/sshd/altprivsep.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -19,7 +18,7 @@
*
* CDDL HEADER END
*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -235,7 +234,7 @@ altprivsep_start_monitor(Authctxt *authctxt)
if (fcntl(pipe_fd, F_SETFL, O_NONBLOCK) < 0)
error("fcntl O_NONBLOCK: %.100s", strerror(errno));
- /* signal readyness of monitor */
+ /* signal readiness of monitor */
(void) write(pipe_fd, &pid, sizeof (pid));
aps_started = 1;
@@ -583,6 +582,7 @@ aps_send_newkeys(void)
packet_put_cstring(comp->name);
packet_send();
+ free_keys(newkeys);
}
struct _aps_login_rec {
diff --git a/usr/src/cmd/ssh/sshd/auth-bsdauth.c b/usr/src/cmd/ssh/sshd/auth-bsdauth.c
index e6ea549620..090fa0ef39 100644
--- a/usr/src/cmd/ssh/sshd/auth-bsdauth.c
+++ b/usr/src/cmd/ssh/sshd/auth-bsdauth.c
@@ -30,7 +30,6 @@ RCSID("$OpenBSD: auth-bsdauth.c,v 1.5 2002/06/30 21:59:45 deraadt Exp $");
#include "xmalloc.h"
#include "auth.h"
#include "log.h"
-#include "monitor_wrap.h"
static void *
bsdauth_init_ctx(Authctxt *authctxt)
diff --git a/usr/src/cmd/ssh/sshd/auth-options.c b/usr/src/cmd/ssh/sshd/auth-options.c
index 37930663f6..b186cbe045 100644
--- a/usr/src/cmd/ssh/sshd/auth-options.c
+++ b/usr/src/cmd/ssh/sshd/auth-options.c
@@ -22,7 +22,6 @@ RCSID("$OpenBSD: auth-options.c,v 1.26 2002/07/30 17:03:55 markus Exp $");
#include "auth-options.h"
#include "servconf.h"
#include "misc.h"
-#include "monitor_wrap.h"
#include "auth.h"
/* Flags set authorized_keys flags */
@@ -282,8 +281,7 @@ next_option:
/* Process the next option. */
}
- if (!use_privsep)
- auth_debug_send();
+ auth_debug_send();
/* grant access */
return 1;
@@ -294,8 +292,7 @@ bad_option:
auth_debug_add("Bad options in %.100s file, line %lu: %.50s",
file, linenum, opts);
- if (!use_privsep)
- auth_debug_send();
+ auth_debug_send();
/* deny access */
return 0;
diff --git a/usr/src/cmd/ssh/sshd/auth-pam.c b/usr/src/cmd/ssh/sshd/auth-pam.c
index a666edfa87..6763035a72 100644
--- a/usr/src/cmd/ssh/sshd/auth-pam.c
+++ b/usr/src/cmd/ssh/sshd/auth-pam.c
@@ -39,14 +39,12 @@
#include "compat.h"
#include "misc.h"
#include "sshlogin.h"
-#include "monitor_wrap.h"
+#include "ssh-gss.h"
#include <security/pam_appl.h>
extern char *__progname;
-extern int use_privsep;
-
extern u_int utmp_len;
extern ServerOptions options;
@@ -58,8 +56,6 @@ RCSID("$Id: auth-pam.c,v 1.54 2002/07/28 20:24:08 stevesk Exp $");
#define NEW_AUTHTOK_MSG \
"Warning: Your password has expired, please change it now."
-#define NEW_AUTHTOK_MSG_PRIVSEP \
- "Your password has expired, the session cannot proceed."
/* PAM conversation for non-interactive userauth methods */
static int do_pam_conversation(int num_msg, const struct pam_message **msg,
@@ -282,7 +278,7 @@ finish_userauth_do_pam(Authctxt *authctxt)
if (strcmp(user, authctxt->user) != 0) {
log("PAM changed the SSH username");
pwfree(&authctxt->pw);
- authctxt->pw = PRIVSEP(getpwnamallow(user));
+ authctxt->pw = getpwnamallow(user);
authctxt->valid = (authctxt->pw != NULL);
xfree(authctxt->user);
authctxt->user = xstrdup(user);
diff --git a/usr/src/cmd/ssh/sshd/auth-rh-rsa.c b/usr/src/cmd/ssh/sshd/auth-rh-rsa.c
index c6c9060c06..ab10e1738a 100644
--- a/usr/src/cmd/ssh/sshd/auth-rh-rsa.c
+++ b/usr/src/cmd/ssh/sshd/auth-rh-rsa.c
@@ -27,8 +27,6 @@ RCSID("$OpenBSD: auth-rh-rsa.c,v 1.34 2002/03/25 09:25:06 markus Exp $");
#include "auth.h"
#include "canohost.h"
-#include "monitor_wrap.h"
-
/* import */
extern ServerOptions options;
@@ -68,7 +66,7 @@ auth_rhosts_rsa(struct passwd *pw, char *cuser, Key *client_host_key)
chost = (char *)get_canonical_hostname(options.verify_reverse_mapping);
debug("Rhosts RSA authentication: canonical host %.900s", chost);
- if (!PRIVSEP(auth_rhosts_rsa_key_allowed(pw, cuser, chost, client_host_key))) {
+ if (!auth_rhosts_rsa_key_allowed(pw, cuser, chost, client_host_key)) {
debug("Rhosts with RSA host authentication denied: unknown or invalid host key");
packet_send_debug("Your host key cannot be verified: unknown or invalid host key.");
return 0;
diff --git a/usr/src/cmd/ssh/sshd/auth-rhosts.c b/usr/src/cmd/ssh/sshd/auth-rhosts.c
index 0b0d44a56f..2326eef8ae 100644
--- a/usr/src/cmd/ssh/sshd/auth-rhosts.c
+++ b/usr/src/cmd/ssh/sshd/auth-rhosts.c
@@ -28,7 +28,6 @@ RCSID("$OpenBSD: auth-rhosts.c,v 1.28 2002/05/13 21:26:49 markus Exp $");
/* import */
extern ServerOptions options;
-extern int use_privsep;
/*
* This function processes an rhosts-style file (.rhosts, .shosts, or
@@ -295,7 +294,6 @@ auth_rhosts2(struct passwd *pw, const char *client_user, const char *hostname,
auth_debug_reset();
ret = auth_rhosts2_raw(pw, client_user, hostname, ipaddr);
- if (!use_privsep)
- auth_debug_send();
+ auth_debug_send();
return ret;
}
diff --git a/usr/src/cmd/ssh/sshd/auth-rsa.c b/usr/src/cmd/ssh/sshd/auth-rsa.c
index a4896f20e1..3e0e6ea50d 100644
--- a/usr/src/cmd/ssh/sshd/auth-rsa.c
+++ b/usr/src/cmd/ssh/sshd/auth-rsa.c
@@ -34,7 +34,6 @@ RCSID("$OpenBSD: auth-rsa.c,v 1.56 2002/06/10 16:53:06 stevesk Exp $");
#include "servconf.h"
#include "auth.h"
#include "hostfile.h"
-#include "monitor_wrap.h"
#include "ssh.h"
/* import */
@@ -124,7 +123,7 @@ auth_rsa_challenge_dialog(Key *key)
if ((encrypted_challenge = BN_new()) == NULL)
fatal("auth_rsa_challenge_dialog: BN_new() failed");
- challenge = PRIVSEP(auth_rsa_generate_challenge(key));
+ challenge = auth_rsa_generate_challenge(key);
/* Encrypt the challenge with the public key. */
rsa_public_encrypt(encrypted_challenge, challenge, key->rsa);
@@ -142,7 +141,7 @@ auth_rsa_challenge_dialog(Key *key)
response[i] = packet_get_char();
packet_check_eom();
- success = PRIVSEP(auth_rsa_verify_response(key, challenge, response));
+ success = auth_rsa_verify_response(key, challenge, response);
BN_clear_free(challenge);
return (success);
}
@@ -295,7 +294,7 @@ auth_rsa(struct passwd *pw, BIGNUM *client_n)
if (pw == NULL)
return 0;
- if (!PRIVSEP(auth_rsa_key_allowed(pw, client_n, &key))) {
+ if (!auth_rsa_key_allowed(pw, client_n, &key)) {
auth_clear_options();
return (0);
}
diff --git a/usr/src/cmd/ssh/sshd/auth-skey.c b/usr/src/cmd/ssh/sshd/auth-skey.c
index 67ed5a6434..436f66aed8 100644
--- a/usr/src/cmd/ssh/sshd/auth-skey.c
+++ b/usr/src/cmd/ssh/sshd/auth-skey.c
@@ -32,7 +32,6 @@ RCSID("$OpenBSD: auth-skey.c,v 1.20 2002/06/30 21:59:45 deraadt Exp $");
#include "xmalloc.h"
#include "auth.h"
-#include "monitor_wrap.h"
static void *
skey_init_ctx(Authctxt *authctxt)
diff --git a/usr/src/cmd/ssh/sshd/auth1.c b/usr/src/cmd/ssh/sshd/auth1.c
index a797962fc8..0eed0c90c8 100644
--- a/usr/src/cmd/ssh/sshd/auth1.c
+++ b/usr/src/cmd/ssh/sshd/auth1.c
@@ -9,7 +9,7 @@
* called by a name other than "ssh" or "Secure Shell".
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -31,7 +31,6 @@ RCSID("$OpenBSD: auth1.c,v 1.44 2002/09/26 11:38:43 markus Exp $");
#include "channels.h"
#include "session.h"
#include "uidswap.h"
-#include "monitor_wrap.h"
#ifdef HAVE_BSM
#include "bsmaudit.h"
@@ -95,7 +94,7 @@ do_authloop(Authctxt *authctxt)
#if defined(KRB4) || defined(KRB5)
(!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
#endif
- PRIVSEP(auth_password(authctxt, ""))) {
+ auth_password(authctxt, "")) {
auth_log(authctxt, 1, "without authentication", "");
return;
}
@@ -137,8 +136,8 @@ do_authloop(Authctxt *authctxt)
if (tkt.length < MAX_KTXT_LEN)
memcpy(tkt.dat, kdata, tkt.length);
- if (PRIVSEP(auth_krb4(authctxt, &tkt,
- &client_user, &reply))) {
+ if (auth_krb4(authctxt, &tkt,
+ &client_user, &reply)) {
authenticated = 1;
snprintf(info, sizeof(info),
" tktuser %.100s",
@@ -158,8 +157,8 @@ do_authloop(Authctxt *authctxt)
tkt.length = dlen;
tkt.data = kdata;
- if (PRIVSEP(auth_krb5(authctxt, &tkt,
- &client_user, &reply))) {
+ if (auth_krb5(authctxt, &tkt,
+ &client_user, &reply)) {
authenticated = 1;
snprintf(info, sizeof(info),
" tktuser %.100s",
@@ -279,8 +278,7 @@ do_authloop(Authctxt *authctxt)
if (authctxt->init_failures <
options.max_init_auth_tries)
authenticated =
- PRIVSEP(auth_password(authctxt,
- password));
+ auth_password(authctxt, password);
memset(password, 0, strlen(password));
xfree(password);
@@ -351,16 +349,11 @@ do_authloop(Authctxt *authctxt)
}
#else
/* Special handling for root */
- if (!use_privsep &&
- authenticated && authctxt->pw->pw_uid == 0 &&
+ if (authenticated && authctxt->pw->pw_uid == 0 &&
!auth_root_allowed(get_authname(type)))
authenticated = 0;
#endif
#ifdef USE_PAM
- /* XXX PAM and PRIVSEP don't mix */
- if (use_privsep && authenticated)
- fatal("Privsep is not supported");
-
if (authenticated && type != SSH_CMSG_AUTH_PASSWORD)
authenticated = do_pam_non_initial_userauth(authctxt);
else if (authenticated && !AUTHPAM_DONE(authctxt))
@@ -440,28 +433,21 @@ do_authentication(void)
#endif /* HAVE_BSM */
/* Verify that the user is a valid user. */
- if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL) {
+ if ((authctxt->pw = getpwnamallow(user)) != NULL) {
authctxt->valid = 1;
} else {
authctxt->valid = 0;
debug("do_authentication: illegal user %s", user);
}
- setproctitle("%s%s", authctxt->pw ? user : "unknown",
- use_privsep ? " [net]" : "");
-
-#if 0
-#ifdef USE_PAM
- PRIVSEP(start_pam(authctxt->pw == NULL ? "NOUSER" : user));
-#endif
-#endif
+ setproctitle("%s", authctxt->pw ? user : "unknown");
/*
* If we are not running as root, the user must have the same uid as
* the server. (Unless you are running Windows)
*/
#ifndef HAVE_CYGWIN
- if (!use_privsep && getuid() != 0 && authctxt->pw &&
+ if (getuid() != 0 && authctxt->pw &&
authctxt->pw->pw_uid != getuid())
packet_disconnect("Cannot change user when server not running as root.");
#endif
diff --git a/usr/src/cmd/ssh/sshd/auth2-gss.c b/usr/src/cmd/ssh/sshd/auth2-gss.c
index 8892f6f718..70560dad3a 100644
--- a/usr/src/cmd/ssh/sshd/auth2-gss.c
+++ b/usr/src/cmd/ssh/sshd/auth2-gss.c
@@ -41,7 +41,6 @@
#include "buffer.h"
#include "bufaux.h"
#include "packet.h"
-#include "monitor_wrap.h"
#include <gssapi/gssapi.h>
#include "ssh-gss.h"
@@ -202,15 +201,14 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt)
u_int len;
if (authctxt == NULL || authctxt->method == NULL ||
- (authctxt->method->method_data == NULL && !use_privsep))
+ (authctxt->method->method_data == NULL))
fatal("No authentication or GSSAPI context during gssapi-with-mic userauth");
gssctxt=authctxt->method->method_data;
recv_tok.value=packet_get_string(&len);
recv_tok.length=len; /* u_int vs. size_t */
- maj_status=PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok,
- &send_tok));
+ maj_status = ssh_gssapi_accept_ctx(gssctxt, &recv_tok, &send_tok);
packet_check_eom();
if (GSS_ERROR(maj_status)) {
@@ -251,7 +249,7 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
gss_buffer_desc send_tok,recv_tok;
if (authctxt == NULL || authctxt->method == NULL ||
- (authctxt->method->method_data == NULL && !use_privsep))
+ (authctxt->method->method_data == NULL))
fatal("No authentication or GSSAPI context during gssapi-with-mic userauth");
gssctxt=authctxt->method->method_data;
@@ -259,7 +257,7 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
packet_check_eom();
/* Push the error token into GSSAPI to see what it says */
- (void) PRIVSEP(ssh_gssapi_accept_ctx(gssctxt, &recv_tok, &send_tok));
+ (void) ssh_gssapi_accept_ctx(gssctxt, &recv_tok, &send_tok);
debug("Client sent GSS-API error token during GSS userauth-- %s",
ssh_gssapi_last_error(gssctxt, NULL, NULL));
@@ -352,7 +350,7 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
packet_check_eom();
if (authctxt == NULL || authctxt->method == NULL ||
- (authctxt->method->method_data == NULL && !use_privsep))
+ (authctxt->method->method_data == NULL))
fatal("No authentication or GSSAPI context");
gssctxt=authctxt->method->method_data;
@@ -380,7 +378,7 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
* this will do for now.
*/
#if 0
- authctxt->method->authenticated = PRIVSEP(ssh_gssapi_userok(gssctxt, authctxt->user));
+ authctxt->method->authenticated = ssh_gssapi_userok(gssctxt, authctxt->user);
#endif
if (xxx_gssctxt != gssctxt)
@@ -425,7 +423,7 @@ userauth_gssapi_finish(Authctxt *authctxt, Gssctxt *gssctxt)
OM_uint32 major;
if (*authctxt->user != '\0' &&
- PRIVSEP(ssh_gssapi_userok(gssctxt, authctxt->user))) {
+ ssh_gssapi_userok(gssctxt, authctxt->user)) {
/*
* If the client princ did not map to the requested
diff --git a/usr/src/cmd/ssh/sshd/auth2-hostbased.c b/usr/src/cmd/ssh/sshd/auth2-hostbased.c
index f7bef1197b..c88e308100 100644
--- a/usr/src/cmd/ssh/sshd/auth2-hostbased.c
+++ b/usr/src/cmd/ssh/sshd/auth2-hostbased.c
@@ -47,7 +47,6 @@ RCSID("$OpenBSD: auth2-hostbased.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
#include "key.h"
#include "canohost.h"
-#include "monitor_wrap.h"
#include "pathnames.h"
/* import */
@@ -119,9 +118,8 @@ userauth_hostbased(Authctxt *authctxt)
#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)
+ if (hostbased_key_allowed(authctxt->pw, cuser, chost, key) &&
+ key_verify(key, sig, slen, buffer_ptr(&b), buffer_len(&b)) == 1)
authenticated = 1;
buffer_clear(&b);
diff --git a/usr/src/cmd/ssh/sshd/auth2-none.c b/usr/src/cmd/ssh/sshd/auth2-none.c
index 94dbf7d18a..8732cf168e 100644
--- a/usr/src/cmd/ssh/sshd/auth2-none.c
+++ b/usr/src/cmd/ssh/sshd/auth2-none.c
@@ -22,7 +22,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -39,7 +39,6 @@ RCSID("$OpenBSD: auth2-none.c,v 1.4 2002/06/27 10:35:47 deraadt Exp $");
#include "atomicio.h"
#include "compat.h"
#include "ssh2.h"
-#include "monitor_wrap.h"
/* import */
extern ServerOptions options;
@@ -83,7 +82,7 @@ userauth_banner(void)
if (options.banner == NULL || (datafellows & SSH_BUG_BANNER))
return;
- if ((banner = PRIVSEP(auth2_read_banner())) == NULL)
+ if ((banner = auth2_read_banner()) == NULL)
goto done;
packet_start(SSH2_MSG_USERAUTH_BANNER);
@@ -110,7 +109,7 @@ userauth_none(Authctxt *authctxt)
if (check_nt_auth(1, authctxt->pw) == 0)
return(0);
#endif
- authctxt->method->authenticated = PRIVSEP(auth_password(authctxt, ""));
+ authctxt->method->authenticated = auth_password(authctxt, "");
}
Authmethod method_none = {
diff --git a/usr/src/cmd/ssh/sshd/auth2-pam.c b/usr/src/cmd/ssh/sshd/auth2-pam.c
index 0c866c9625..802378fded 100644
--- a/usr/src/cmd/ssh/sshd/auth2-pam.c
+++ b/usr/src/cmd/ssh/sshd/auth2-pam.c
@@ -23,7 +23,6 @@ RCSID("$Id: auth2-pam.c,v 1.14 2002/06/28 16:48:12 mouring Exp $");
#include "canohost.h"
#include "log.h"
#include "servconf.h"
-#include "monitor_wrap.h"
#include "misc.h"
#ifdef HAVE_BSM
@@ -251,6 +250,8 @@ do_pam_conv_kbd_int(int num_msg, struct pam_message **msg,
}
if (conv_ctxt->num_expected == 0 && text == NULL) {
+ xfree(conv_ctxt->prompts);
+ xfree(conv_ctxt->responses);
xfree(conv_ctxt);
return PAM_SUCCESS;
}
@@ -301,6 +302,8 @@ do_pam_conv_kbd_int(int num_msg, struct pam_message **msg,
if (conv_ctxt->abandoned) {
authctxt->unwind_dispatch_loop = 1;
+ xfree(conv_ctxt->prompts);
+ xfree(conv_ctxt->responses);
xfree(conv_ctxt);
debug("PAM conv function returns PAM_CONV_ERR");
return PAM_CONV_ERR;
@@ -308,12 +311,15 @@ do_pam_conv_kbd_int(int num_msg, struct pam_message **msg,
if (conv_ctxt->num_received == conv_ctxt->num_expected) {
*resp = conv_ctxt->responses;
+ xfree(conv_ctxt->prompts);
xfree(conv_ctxt);
debug("PAM conv function returns PAM_SUCCESS");
return PAM_SUCCESS;
}
debug("PAM conv function returns PAM_CONV_ERR");
+ xfree(conv_ctxt->prompts);
+ xfree(conv_ctxt->responses);
xfree(conv_ctxt);
return PAM_CONV_ERR;
}
diff --git a/usr/src/cmd/ssh/sshd/auth2-passwd.c b/usr/src/cmd/ssh/sshd/auth2-passwd.c
index 4c8ca86ff0..9a1837fb05 100644
--- a/usr/src/cmd/ssh/sshd/auth2-passwd.c
+++ b/usr/src/cmd/ssh/sshd/auth2-passwd.c
@@ -22,7 +22,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -35,7 +35,6 @@ RCSID("$OpenBSD: auth2-passwd.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
#include "packet.h"
#include "log.h"
#include "auth.h"
-#include "monitor_wrap.h"
#include "servconf.h"
/* import */
@@ -60,8 +59,9 @@ userauth_passwd(Authctxt *authctxt)
#ifdef HAVE_CYGWIN
check_nt_auth(1, authctxt->pw) &&
#endif
- PRIVSEP(auth_password(authctxt, password)) == 1)
+ auth_password(authctxt, password) == 1) {
authctxt->method->authenticated = 1;
+ }
memset(password, 0, len);
xfree(password);
}
diff --git a/usr/src/cmd/ssh/sshd/auth2-pubkey.c b/usr/src/cmd/ssh/sshd/auth2-pubkey.c
index 9b02597d65..a6544f4f54 100644
--- a/usr/src/cmd/ssh/sshd/auth2-pubkey.c
+++ b/usr/src/cmd/ssh/sshd/auth2-pubkey.c
@@ -22,7 +22,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -45,7 +45,6 @@ RCSID("$OpenBSD: auth2-pubkey.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
#include "uidswap.h"
#include "auth-options.h"
#include "canohost.h"
-#include "monitor_wrap.h"
#ifdef USE_PAM
#include <security/pam_appl.h>
@@ -155,10 +154,11 @@ userauth_pubkey(Authctxt *authctxt)
buffer_dump(&b);
#endif
/* test for correct signature */
- if (PRIVSEP(user_key_allowed(authctxt->pw, key)) &&
- PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
- buffer_len(&b))) == 1)
+ if (user_key_allowed(authctxt->pw, key) &&
+ key_verify(key, sig, slen, buffer_ptr(&b),
+ buffer_len(&b)) == 1) {
authenticated = 1;
+ }
authctxt->method->postponed = 0;
buffer_clear(&b);
xfree(sig);
@@ -174,7 +174,7 @@ userauth_pubkey(Authctxt *authctxt)
* if a user is not allowed to login. is this an
* issue? -markus
*/
- if (PRIVSEP(user_key_allowed(authctxt->pw, key))) {
+ if (user_key_allowed(authctxt->pw, key)) {
packet_start(SSH2_MSG_USERAUTH_PK_OK);
packet_put_string(pkalg, alen);
packet_put_string(pkblob, blen);
diff --git a/usr/src/cmd/ssh/sshd/auth2.c b/usr/src/cmd/ssh/sshd/auth2.c
index d220276339..eba64ed56d 100644
--- a/usr/src/cmd/ssh/sshd/auth2.c
+++ b/usr/src/cmd/ssh/sshd/auth2.c
@@ -22,7 +22,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -42,7 +42,6 @@ RCSID("$OpenBSD: auth2.c,v 1.95 2002/08/22 21:33:58 markus Exp $");
#include "dispatch.h"
#include "sshlogin.h"
#include "pathnames.h"
-#include "monitor_wrap.h"
#ifdef HAVE_BSM
#include "bsmaudit.h"
@@ -120,8 +119,6 @@ do_authentication2(void)
options.kbd_interactive_authentication = 1;
if (options.pam_authentication_via_kbd_int)
options.kbd_interactive_authentication = 1;
- if (use_privsep)
- options.pam_authentication_via_kbd_int = 0;
dispatch_init(&dispatch_protocol_error);
dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
@@ -193,7 +190,7 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
if (authctxt->attempt == 1) {
/* setup auth context */
- authctxt->pw = PRIVSEP(getpwnamallow(user));
+ authctxt->pw = getpwnamallow(user);
/* May want to abstract SSHv2 services someday */
if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
/* enforced in userauth_finish() below */
@@ -202,14 +199,11 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
} else {
log("input_userauth_request: illegal user %s", user);
}
- setproctitle("%s%s", authctxt->pw ? user : "unknown",
- use_privsep ? " [net]" : "");
+ setproctitle("%s", authctxt->pw ? user : "unknown");
authctxt->user = xstrdup(user);
authctxt->service = xstrdup(service);
authctxt->style = style ? xstrdup(style) : NULL;
userauth_reset_methods();
- if (use_privsep)
- mm_inform_authserv(service, style);
} else {
char *abandoned;
@@ -293,8 +287,7 @@ userauth_finish(Authctxt *authctxt, char *method)
#ifndef USE_PAM
/* Special handling for root (done elsewhere for PAM) */
- if (!use_privsep &&
- authctxt->method->authenticated &&
+ if (authctxt->method->authenticated &&
authctxt->pw != NULL && authctxt->pw->pw_uid == 0 &&
!auth_root_allowed(method))
authctxt->method->authenticated = 0;
@@ -457,7 +450,7 @@ userauth_user_svc_change(Authctxt *authctxt, char *user, char *service)
xfree(authctxt->user);
authctxt->user = xstrdup(user);
pwfree(&authctxt->pw);
- authctxt->pw = PRIVSEP(getpwnamallow(user));
+ authctxt->pw = getpwnamallow(user);
authctxt->valid = (authctxt->pw != NULL);
/* Forget method state; abandon postponed userauths */
diff --git a/usr/src/cmd/ssh/sshd/gss-serv.c b/usr/src/cmd/ssh/sshd/gss-serv.c
index ad0d7c65f5..98b962b3d0 100644
--- a/usr/src/cmd/ssh/sshd/gss-serv.c
+++ b/usr/src/cmd/ssh/sshd/gss-serv.c
@@ -22,7 +22,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -51,7 +51,6 @@
#include "servconf.h"
#include "uidswap.h"
#include "compat.h"
-#include "monitor_wrap.h"
#include <pwd.h>
#include "ssh-gss.h"
diff --git a/usr/src/cmd/ssh/sshd/monitor.c b/usr/src/cmd/ssh/sshd/monitor.c
deleted file mode 100644
index c14973160b..0000000000
--- a/usr/src/cmd/ssh/sshd/monitor.c
+++ /dev/null
@@ -1,1852 +0,0 @@
-/*
- * 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.
- *
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include "includes.h"
-RCSID("$OpenBSD: monitor.c,v 1.29 2002/09/26 11:38:43 markus Exp $");
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#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"
-
-#ifndef lint
-
-#ifdef GSSAPI
-#include "ssh-gss.h"
-static Gssctxt *gsscontext = NULL;
-#endif
-
-/* 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 *);
-
-#ifdef USE_PAM
-int mm_answer_pam_start(int, Buffer *);
-#endif
-
-#ifdef KRB4
-int mm_answer_krb4(int, Buffer *);
-#endif
-#ifdef KRB5
-int mm_answer_krb5(int, Buffer *);
-#endif
-
-#ifdef GSSAPI
-int mm_answer_gss_setup_ctx(int, Buffer *);
-int mm_answer_gss_accept_ctx(int, Buffer *);
-int mm_answer_gss_userok(int, Buffer *);
-int mm_answer_gss_sign(int, Buffer *);
-int mm_answer_gss_error(int, Buffer *);
-int mm_answer_gss_indicate_mechs(int, Buffer *);
-int mm_answer_gss_localname(int, Buffer *);
-#endif
-
-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 char *hostbased_cuser = NULL;
-static 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 USE_PAM
- {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
-#endif
-#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
-#ifdef GSSAPI
- {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx},
- {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
- {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
- {MONITOR_REQ_GSSERR, MON_ISAUTH | MON_ONCE, mm_answer_gss_error},
- {MONITOR_REQ_GSSMECHS, MON_ISAUTH, mm_answer_gss_indicate_mechs},
- {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
-/* Turn this off until we use it */
-#if 0
- {MONITOR_REQ_GSSLOCALNAME, MON_ISAUTH, mm_answer_gss_localname},
-#endif
-#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[] = {
-#ifdef GSSAPI
- {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx},
- {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx},
- {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign},
- {MONITOR_REQ_GSSERR, 0, mm_answer_gss_error},
- {MONITOR_REQ_GSSMECHS, 0, mm_answer_gss_indicate_mechs},
-#endif
- {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
-#ifdef USE_PAM
- {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
-#endif
-#ifdef KRB4
- {MONITOR_REQ_KRB4, MON_ONCE|MON_AUTH, mm_answer_krb4},
-#endif
-#ifdef KRB5
- {MONITOR_REQ_KRB5, MON_ONCE|MON_AUTH, mm_answer_krb5},
-#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);
-#ifdef GSSAPI
- /* and for the GSSAPI key exchange */
- monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
- monitor_permit(mon_dispatch, MONITOR_REQ_GSSERR, 1);
- monitor_permit(mon_dispatch, MONITOR_REQ_GSSMECHS, 1);
-#endif
- } 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;
-#ifdef USE_PAM
- /*if (!do_pam_account(authctxt->pw->pw_name, * NULL))*/
- if (!do_pam_non_initial_userauth(authctxt))
- authenticated = 0;
-#endif
- }
-
- 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);
-
-#ifdef GSSAPI
- /* and for the GSSAPI key exchange */
- monitor_permit(mon_dispatch, MONITOR_REQ_GSSMECHS,1);
- monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP,1);
- monitor_permit(mon_dispatch, MONITOR_REQ_GSSERR,1);
-#endif
-
- } 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: %u", __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(%u)", __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);
-#ifdef HAVE_PW_CLASS_IN_PASSWD
- buffer_put_cstring(m, pwent->pw_class);
-#endif
- 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);
- }
-
-#ifdef USE_PAM
- monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1);
-#endif
-
- 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)
- xfree(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;
- u_int 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
-
-#ifdef USE_PAM
-int
-mm_answer_pam_start(int socket, Buffer *m)
-{
- char *user;
-
- user = buffer_get_string(m, NULL);
-
- new_start_pam(authctxt, /*XXX*/ NULL);
-
- xfree(user);
-
- return (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;
- char *cuser, *chost;
- u_char *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;
- 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, char *cuser,
- char *chost)
-{
- Buffer b;
- 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);
-
- auth_method = key_blobtype == MM_USERKEY ? "publickey" : "hostbased";
-
- monitor_reset_key_state();
-
- buffer_clear(m);
- buffer_put_int(m, verified);
- mm_request_send(socket, MONITOR_ANS_KEYVERIFY, m);
-
- return (verified);
-}
-
-static void
-mm_record_login(Session *s, struct passwd *pw)
-{
- /* Record that there was a login on that tty from the remote host. */
- record_login(s->pid, s->tty, NULL, pw->pw_name);
-}
-
-static void
-mm_session_close(Session *s)
-{
- debug3("%s: session %d pid %ld", __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);
-}
-
-#ifdef KRB4
-int
-mm_answer_krb4(int socket, Buffer *m)
-{
- KTEXT_ST auth, reply;
- char *client, *p;
- int success;
- u_int alen;
-
- reply.length = auth.length = 0;
-
- p = buffer_get_string(m, &alen);
- if (alen >= MAX_KTXT_LEN)
- fatal("%s: auth too large", __func__);
- memcpy(auth.dat, p, alen);
- auth.length = alen;
- memset(p, 0, alen);
- xfree(p);
-
- success = options.kerberos_authentication &&
- authctxt->valid &&
- auth_krb4(authctxt, &auth, &client, &reply);
-
- memset(auth.dat, 0, alen);
- buffer_clear(m);
- buffer_put_int(m, success);
-
- if (success) {
- buffer_put_cstring(m, client);
- buffer_put_string(m, reply.dat, reply.length);
- if (client)
- xfree(client);
- if (reply.length)
- memset(reply.dat, 0, reply.length);
- }
-
- debug3("%s: sending result %d", __func__, success);
- mm_request_send(socket, MONITOR_ANS_KRB4, m);
-
- auth_method = "kerberos";
-
- /* Causes monitor loop to terminate if authenticated */
- return (success);
-}
-#endif
-
-#ifdef KRB5
-int
-mm_answer_krb5(int socket, Buffer *m)
-{
- krb5_data tkt, reply;
- char *client_user;
- u_int len;
- int success;
-
- /* use temporary var to avoid size issues on 64bit arch */
- tkt.data = buffer_get_string(m, &len);
- tkt.length = len;
-
- success = options.kerberos_authentication &&
- authctxt->valid &&
- auth_krb5(authctxt, &tkt, &client_user, &reply);
-
- if (tkt.length)
- xfree(tkt.data);
-
- buffer_clear(m);
- buffer_put_int(m, success);
-
- if (success) {
- buffer_put_cstring(m, client_user);
- buffer_put_string(m, reply.data, reply.length);
- if (client_user)
- xfree(client_user);
- if (reply.length)
- xfree(reply.data);
- }
- mm_request_send(socket, MONITOR_ANS_KRB5, m);
-
- return success;
-}
-#endif
-
-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 */
- return (res);
- /* NOTREACHED */
-}
-
-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->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
- kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
-#ifdef GSSAPI
- kex->kex[KEX_GSS_GRP1_SHA1] =kexgss_server;
-#endif
- 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)
-{
- size_t len = size * ncount;
- void *address;
-
- if (len == 0 || ncount > SIZE_T_MAX / size)
- fatal("%s: mm_zalloc(%u, %u)", __func__, ncount, size);
-
- address = mm_malloc(mm, len);
-
- 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)
-{
-#ifdef HAVE_SOCKETPAIR
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
- fatal("%s: socketpair", __func__);
-#else
- fatal("%s: UsePrivilegeSeparation=yes not supported",
- __func__);
-#endif
- 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];
-}
-
-#ifdef GSSAPI
-int
-mm_answer_gss_setup_ctx(int socket, Buffer *m) {
- gss_OID_desc oid;
- OM_uint32 major;
- u_int len;
-
- oid.elements=buffer_get_string(m,&len);
- oid.length=len;
-
- /* XXX */
- ssh_gssapi_build_ctx(&gsscontext, 0, GSS_C_NULL_OID);
-
- xfree(oid.elements);
-
- buffer_clear(m);
- buffer_put_int(m,major);
-
- mm_request_send(socket,MONITOR_ANS_GSSSETUP,m);
-
- /* Now we have a context, enable the step and sign */
- monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP,1);
-
- return(0);
-}
-
-int
-mm_answer_gss_accept_ctx(int socket, Buffer *m) {
- gss_buffer_desc in,out;
- OM_uint32 major,minor;
- OM_uint32 flags = 0; /* GSI needs this */
-
- in.value = buffer_get_string(m,&in.length);
- major=ssh_gssapi_accept_ctx(gsscontext, &in, &out);
- xfree(in.value);
-
- buffer_clear(m);
- buffer_put_int(m, major);
- buffer_put_string(m, out.value, out.length);
- buffer_put_int(m, flags);
- mm_request_send(socket,MONITOR_ANS_GSSSTEP,m);
-
- gss_release_buffer(&minor, &out);
-
- /* Complete - now we can do signing */
- if (major==GSS_S_COMPLETE) {
- monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP,0);
- monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN,1);
- }
- return(0);
-}
-
-int
-mm_answer_gss_userok(int socket, Buffer *m) {
- int authenticated;
-
- authenticated = authctxt->valid &&
- ssh_gssapi_userok(gsscontext, authctxt->user);
-
- buffer_clear(m);
- buffer_put_int(m, authenticated);
-
- debug3("%s: sending result %d", __func__, authenticated);
- mm_request_send(socket, MONITOR_ANS_GSSUSEROK, m);
-
- /* XXX - auth method could also be 'external' */
- auth_method="gssapi";
-
- /* Monitor loop will terminate if authenticated */
- return(authenticated);
-}
-
-int
-mm_answer_gss_sign(int socket, Buffer *m) {
- gss_buffer_desc data,hash;
- OM_uint32 major,minor;
-
- data.value = buffer_get_string(m,&data.length);
- if (data.length != 20)
- fatal("%s: data length incorrect: %d", __func__, data.length);
-
- /* Save the session ID - only first time round */
- if (session_id2_len == 0) {
- session_id2_len=data.length;
- session_id2 = xmalloc(session_id2_len);
- memcpy(session_id2, data.value, session_id2_len);
- }
- major=ssh_gssapi_get_mic(gsscontext, &data, &hash);
-
- xfree(data.value);
-
- buffer_clear(m);
- buffer_put_int(m, major);
- buffer_put_string(m, hash.value, hash.length);
-
- mm_request_send(socket,MONITOR_ANS_GSSSIGN,m);
-
- gss_release_buffer(&minor,&hash);
-
- /* Turn on permissions for getpwnam */
- monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
-
- return(0);
-}
-
-int
-mm_answer_gss_error(int socket, Buffer *m) {
- OM_uint32 major,minor;
- char *msg;
-
- msg=ssh_gssapi_last_error(gsscontext,&major,&minor);
- buffer_clear(m);
- buffer_put_int(m,major);
- buffer_put_int(m,minor);
- buffer_put_cstring(m,msg);
-
- mm_request_send(socket,MONITOR_ANS_GSSERR,m);
-
- xfree(msg);
-
- return(0);
-}
-
-int
-mm_answer_gss_indicate_mechs(int socket, Buffer *m) {
- OM_uint32 major,minor;
- gss_OID_set mech_set;
- int i;
-
- major=gss_indicate_mechs(&minor, &mech_set);
-
- buffer_clear(m);
- buffer_put_int(m, major);
- buffer_put_int(m, mech_set->count);
- for (i=0; i < mech_set->count; i++) {
- buffer_put_string(m, mech_set->elements[i].elements,
- mech_set->elements[i].length);
- }
-
- gss_release_oid_set(&minor,&mech_set);
-
- mm_request_send(socket,MONITOR_ANS_GSSMECHS,m);
-
- return(0);
-}
-
-int
-mm_answer_gss_localname(int socket, Buffer *m) {
- char *name;
-
- name = ssh_gssapi_localname(gsscontext);
-
- buffer_clear(m);
- if (name) {
- buffer_put_cstring(m, name);
- debug3("%s: sending result %s", __func__, name);
- xfree(name);
- } else {
- buffer_put_cstring(m, "");
- debug3("%s: sending result \"\"", __func__);
- }
-
- mm_request_send(socket, MONITOR_ANS_GSSLOCALNAME, m);
-
- return(0);
-}
-#endif /* GSSAPI */
-#endif /* lint */
diff --git a/usr/src/cmd/ssh/sshd/monitor_mm.c b/usr/src/cmd/ssh/sshd/monitor_mm.c
deleted file mode 100644
index 04a82d28f8..0000000000
--- a/usr/src/cmd/ssh/sshd/monitor_mm.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * 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.
- *
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-#include "includes.h"
-RCSID("$OpenBSD: monitor_mm.c,v 1.8 2002/08/02 14:43:15 millert Exp $");
-
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-
-#include "xmmap.h"
-#include "ssh.h"
-#include "xmalloc.h"
-#include "log.h"
-#include "monitor_mm.h"
-
-#ifndef lint
-
-static int
-mm_compare(struct mm_share *a, struct mm_share *b)
-{
- long diff = (char *)a->address - (char *)b->address;
-
- if (diff == 0)
- return (0);
- else if (diff < 0)
- return (-1);
- else
- return (1);
-}
-
-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 = xmmap(size);
- 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);
-
-#ifdef HAVE_MMAP
- if (munmap(mm->address, mm->size) == -1)
- fatal("munmap(%p, %lu): %s", mm->address, (u_long)mm->size,
- strerror(errno));
-#else
- fatal("%s: UsePrivilegeSeparation=yes and Compression=yes not supported",
- __func__);
-#endif
- 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");
- if (size > SIZE_T_MAX - MM_MINSIZE + 1)
- fatal("mm_malloc: size too big");
-
- 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);
-}
-#endif /* lint */
diff --git a/usr/src/cmd/ssh/sshd/servconf.c b/usr/src/cmd/ssh/sshd/servconf.c
index 863a75af74..6f2cdbdc84 100644
--- a/usr/src/cmd/ssh/sshd/servconf.c
+++ b/usr/src/cmd/ssh/sshd/servconf.c
@@ -56,8 +56,6 @@ static void add_one_listen_addr(ServerOptions *, char *, u_short);
/* AF_UNSPEC or AF_INET or AF_INET6 */
extern int IPv4or6;
-/* Use of privilege separation or not */
-extern int use_privsep;
/* Initializes the server options to their default values. */
@@ -149,9 +147,6 @@ initialize_server_options(ServerOptions *options)
options->max_init_auth_tries_log = -1;
options->lookup_client_hostnames = -1;
-
- /* Needs to be accessable in many places */
- use_privsep = -1;
}
#ifdef HAVE_DEFOPEN
@@ -380,21 +375,6 @@ fill_default_server_options(ServerOptions *options)
if (options->lookup_client_hostnames == -1)
options->lookup_client_hostnames = 1;
-
- /* XXX SUNWssh resync */
- /* Turn privilege separation OFF by default */
- if (use_privsep == -1)
- use_privsep = 0;
-
-#ifndef HAVE_MMAP
- if (use_privsep && options->compression == 1) {
- error("This platform does not support both privilege "
- "separation and compression");
- error("Compression disabled");
- options->compression = 0;
- }
-#endif
-
}
/* Keyword tokens. */
@@ -939,8 +919,11 @@ parse_flag:
goto parse_flag;
case sUsePrivilegeSeparation:
- intptr = &use_privsep;
- goto parse_flag;
+ log("%s line %d: ignoring UsePrivilegeSeparation option value."
+ " This option is always on.", filename, linenum);
+ while (arg)
+ arg = strdelim(&cp);
+ break;
case sAllowUsers:
while (((arg = strdelim(&cp)) != NULL) && *arg != '\0') {
diff --git a/usr/src/cmd/ssh/sshd/serverloop.c b/usr/src/cmd/ssh/sshd/serverloop.c
index a720fae405..e7e7711f81 100644
--- a/usr/src/cmd/ssh/sshd/serverloop.c
+++ b/usr/src/cmd/ssh/sshd/serverloop.c
@@ -953,8 +953,14 @@ server_loop2(Authctxt *authctxt)
collect_children();
- if (!rekeying)
+ if (!rekeying) {
channel_after_select(readset, writeset);
+ if (packet_need_rekeying()) {
+ debug("need rekeying");
+ xxx_kex->done = 0;
+ kex_send_kexinit(xxx_kex);
+ }
+ }
#ifdef ALTPRIVSEP
else
altprivsep_process_input(xxx_kex, readset);
@@ -991,7 +997,6 @@ server_input_channel_failure(int type, u_int32_t seq, void *ctxt)
client_alive_timeouts = 0;
}
-
static void
server_input_stdin_data(int type, u_int32_t seq, void *ctxt)
{
diff --git a/usr/src/cmd/ssh/sshd/session.c b/usr/src/cmd/ssh/sshd/session.c
index d85558a44e..04b1c1f7e0 100644
--- a/usr/src/cmd/ssh/sshd/session.c
+++ b/usr/src/cmd/ssh/sshd/session.c
@@ -71,7 +71,6 @@ RCSID("$OpenBSD: session.c,v 1.150 2002/09/16 19:55:33 stevesk Exp $");
#include "serverloop.h"
#include "canohost.h"
#include "session.h"
-#include "monitor_wrap.h"
#ifdef USE_PAM
#include <security/pam_appl.h>
@@ -786,11 +785,6 @@ do_login(Session *s, const char *command)
#ifdef ALTPRIVSEP
debug3("Recording SSHv2 channel login in utmpx/wtmpx");
altprivsep_record_login(pid, s->tty);
-#else /* ALTPRIVSEP*/
- if (!use_privsep) {
- debug3("Recording SSHv2 channel login in utmpx/wtmpx");
- record_login(pid, s->tty, NULL, pw->pw_name);
- }
#endif /* ALTPRIVSEP*/
if (check_quietlogin(s, command))
@@ -1776,7 +1770,7 @@ session_pty_req(Session *s)
/* Allocate a pty and open it. */
debug("Allocating pty.");
- if (!PRIVSEP(pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)))) {
+ if (!pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty))) {
if (s->term)
xfree(s->term);
s->term = NULL;
@@ -1797,8 +1791,7 @@ session_pty_req(Session *s)
* time in case we call fatal() (e.g., the connection gets closed).
*/
fatal_add_cleanup(session_pty_cleanup, (void *)s);
- if (!use_privsep)
- pty_setowner(s->pw, s->tty);
+ pty_setowner(s->pw, s->tty);
/* Set window size from the packet. */
pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
@@ -2164,8 +2157,6 @@ session_pty_cleanup2(void *session)
debug3("Recording SSHv2 channel login in utmpx/wtmpx");
#ifdef ALTPRIVSEP
altprivsep_record_logout(s->pid);
-#else /* ALTPRIVSEP */
- record_logout(s->pid, s->tty, NULL, s->pw->pw_name);
#endif /* ALTPRIVSEP */
}
@@ -2188,7 +2179,7 @@ session_pty_cleanup2(void *session)
void
session_pty_cleanup(void *session)
{
- PRIVSEP(session_pty_cleanup2(session));
+ session_pty_cleanup2(session);
}
/*
diff --git a/usr/src/cmd/ssh/sshd/sshd.c b/usr/src/cmd/ssh/sshd/sshd.c
index 03e81f71e9..199f12ec31 100644
--- a/usr/src/cmd/ssh/sshd/sshd.c
+++ b/usr/src/cmd/ssh/sshd/sshd.c
@@ -87,10 +87,6 @@ RCSID("$OpenBSD: sshd.c,v 1.260 2002/09/27 10:42:09 mickey Exp $");
#include "dispatch.h"
#include "channels.h"
#include "session.h"
-#include "monitor_mm.h"
-#include "monitor.h"
-#include "monitor_wrap.h"
-#include "monitor_fdpass.h"
#include "g11n.h"
#include "sshlogin.h"
#include "xlist.h"
@@ -234,10 +230,6 @@ u_int utmp_len = MAXHOSTNAMELEN;
static int *startup_pipes = NULL;
static int startup_pipe = -1; /* in child */
-/* variables used for privilege separation */
-extern struct monitor *pmonitor;
-extern int use_privsep;
-
#ifdef GSSAPI
static gss_OID_set mechs = GSS_C_NULL_OID_SET;
#endif /* GSSAPI */
@@ -697,155 +689,6 @@ demote_sensitive_data(void)
/* We do not clear ssh1_host key and cookie. XXX - Okay Niels? */
}
-static void
-privsep_preauth_child(void)
-{
- u_int32_t rnd[256];
- gid_t gidset[1];
- struct passwd *pw;
- int i;
-
- /* Enable challenge-response authentication for privilege separation */
- privsep_challenge_enable();
-
- for (i = 0; i < 256; i++)
- rnd[i] = arc4random();
- RAND_seed(rnd, sizeof(rnd));
-
- /* Demote the private keys to public keys. */
- demote_sensitive_data();
-
- if ((pw = getpwnam(SSH_PRIVSEP_USER)) == NULL)
- fatal("Privilege separation user %s does not exist",
- SSH_PRIVSEP_USER);
- (void) memset(pw->pw_passwd, 0, strlen(pw->pw_passwd));
- endpwent();
-
- /* Change our root directory */
- if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1)
- fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR,
- strerror(errno));
- if (chdir("/") == -1)
- fatal("chdir(\"/\"): %s", strerror(errno));
-
- /* Drop our privileges */
- debug3("privsep user:group %u:%u", (u_int)pw->pw_uid,
- (u_int)pw->pw_gid);
-#if 0
- /* XXX not ready, to heavy after chroot */
- do_setusercontext(pw);
-#else
- gidset[0] = pw->pw_gid;
- if (setgid(pw->pw_gid) < 0)
- fatal("setgid failed for %u", pw->pw_gid);
- if (setgroups(1, gidset) < 0)
- fatal("setgroups: %.100s", strerror(errno));
- permanently_set_uid(pw);
-#endif
-}
-
-static Authctxt *
-privsep_preauth(void)
-{
- Authctxt *authctxt = NULL;
- int status;
- pid_t pid;
-
- /* Set up unprivileged child process to deal with network data */
- pmonitor = monitor_init();
- /* Store a pointer to the kex for later rekeying */
- pmonitor->m_pkex = &xxx_kex;
-
- pid = fork();
- if (pid == -1) {
- fatal("fork of unprivileged child failed");
- } else if (pid != 0) {
- fatal_remove_cleanup((void (*) (void *)) packet_close, NULL);
-
- debug2("Network child is on pid %ld", (long)pid);
-
- (void) close(pmonitor->m_recvfd);
- authctxt = monitor_child_preauth(pmonitor);
- (void) close(pmonitor->m_sendfd);
-
- /* Sync memory */
- monitor_sync(pmonitor);
-
- /* Wait for the child's exit status */
- while (waitpid(pid, &status, 0) < 0)
- if (errno != EINTR)
- break;
-
- /* Reinstall, since the child has finished */
- fatal_add_cleanup((void (*) (void *)) packet_close, NULL);
-
- return (authctxt);
- } else {
- /* child */
-
- (void) close(pmonitor->m_sendfd);
-
- /* Demote the child */
- if (getuid() == 0 || geteuid() == 0)
- privsep_preauth_child();
- setproctitle("%s", "[net]");
- }
- return (NULL);
-}
-
-static void
-privsep_postauth(Authctxt *authctxt)
-{
- extern Authctxt *x_authctxt;
-
- /* XXX - Remote port forwarding */
- x_authctxt = authctxt;
-
-#ifdef DISABLE_FD_PASSING
- if (1) {
-#else
- if (authctxt->pw->pw_uid == 0 || options.use_login) {
-#endif
- /* File descriptor passing is broken or root login */
- monitor_apply_keystate(pmonitor);
- use_privsep = 0;
- return;
- }
-
- if (startup_pipe != -1) {
- (void) close(startup_pipe);
- startup_pipe = -1;
- }
-
- /* New socket pair */
- monitor_reinit(pmonitor);
-
- pmonitor->m_pid = fork();
- if (pmonitor->m_pid == -1)
- fatal("fork of unprivileged child failed");
- else if (pmonitor->m_pid != 0) {
- fatal_remove_cleanup((void (*) (void *)) packet_close, NULL);
-
- debug2("User child is on pid %ld", (long)pmonitor->m_pid);
- (void) close(pmonitor->m_recvfd);
- monitor_child_postauth(pmonitor);
-
- /* NEVERREACHED */
- exit(0);
- }
-
- (void) close(pmonitor->m_sendfd);
-
- /* Demote the private keys to public keys. */
- demote_sensitive_data();
-
- /* Drop privileges */
- do_setusercontext(authctxt->pw);
-
- /* It is safe now to apply the key state */
- monitor_apply_keystate(pmonitor);
-}
-
static char *
list_hostkey_types(void)
{
@@ -1240,28 +1083,6 @@ main(int ac, char **av)
}
}
- if (use_privsep) {
- struct stat st;
-
- if (getpwnam(SSH_PRIVSEP_USER) == NULL)
- fatal("Privilege separation user %s does not exist",
- SSH_PRIVSEP_USER);
- if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) ||
- (S_ISDIR(st.st_mode) == 0))
- fatal("Missing privilege separation directory: %s",
- _PATH_PRIVSEP_CHROOT_DIR);
-
-#ifdef HAVE_CYGWIN
- if (check_ntsec(_PATH_PRIVSEP_CHROOT_DIR) &&
- (st.st_uid != getuid () ||
- (st.st_mode & (S_IWGRP|S_IWOTH)) != 0))
-#else
- if (st.st_uid != 0 || (st.st_mode & (S_IWGRP|S_IWOTH)) != 0)
-#endif
- fatal("Bad owner or mode for %s",
- _PATH_PRIVSEP_CHROOT_DIR);
- }
-
/* Configuration looks good, so exit if in test mode. */
if (test_flag)
exit(0);
@@ -1565,6 +1386,7 @@ main(int ac, char **av)
#ifdef HAVE_SOLARIS_CONTRACTS
contracts_post_fork_child();
#endif /* HAVE_SOLARIS_CONTRACTS */
+ xfree(fdset);
startup_pipe = startup_p[1];
close_startup_pipes();
close_listen_socks();
@@ -1714,10 +1536,6 @@ main(int ac, char **av)
packet_set_nonblocking();
- if (use_privsep)
- if ((authctxt = privsep_preauth()) != NULL)
- goto authenticated;
-
/* perform the key exchange */
/* authenticate user and start session */
if (compat20) {
@@ -1728,15 +1546,6 @@ main(int ac, char **av)
authctxt = do_authentication();
}
- /*
- * If we use privilege separation, the unprivileged child transfers
- * the current keystate and exits
- */
- if (use_privsep) {
- mm_send_keystate(pmonitor);
- exit(0);
- }
-
authenticated:
/* Authentication complete */
(void) alarm(0);
@@ -1746,17 +1555,6 @@ authenticated:
startup_pipe = -1;
}
- /*
- * In privilege separation, we fork another child and prepare
- * file descriptor passing.
- */
- if (use_privsep) {
- privsep_postauth(authctxt);
- /* the monitor process [priv] will not return */
- if (!compat20)
- destroy_sensitive_data();
- }
-
#ifdef ALTPRIVSEP
if ((aps_child = altprivsep_start_monitor(authctxt)) == -1)
fatal("Monitor could not be started.");
@@ -1781,7 +1579,7 @@ authenticated:
*
* NOTE: Order matters -- these fatal cleanups must come before
* the audit logout fatal cleanup as these functions are called
- * in in LIFO.
+ * in LIFO.
*
* NOTE: The monitor will packet_close(), which will close
* "newsock," so we dup() it.
@@ -1893,70 +1691,6 @@ authenticated:
/* NOTREACHED */
}
-
-#else /* ALTPRIVSEP */
-
- if (compat20) {
- debug3("Recording SSHv2 session login in wtmpx");
- record_login(getpid(), NULL, "sshd", authctxt->user);
- }
-
-#ifdef HAVE_BSM
- fatal_remove_cleanup(
- (void (*)(void *))audit_failed_login_cleanup,
- (void *)authctxt);
-
- /* Initialize the group list, audit sometimes needs it. */
- if (initgroups(authctxt->pw->pw_name, authctxt->pw->pw_gid) < 0) {
- perror("initgroups");
- exit (1);
- }
- audit_sshd_login(&ah, authctxt->pw->pw_uid,
- authctxt->pw->pw_gid);
-
- fatal_add_cleanup((void (*)(void *))audit_sshd_logout,
- (void *)&ah);
-#endif /* HAVE_BSM */
-
-#ifdef GSSAPI
- fatal_add_cleanup((void (*)(void *))ssh_gssapi_cleanup_creds,
- (void *)&xxx_gssctxt);
-#endif /* GSSAPI */
-
- /* Perform session preparation. */
- do_authenticated(authctxt);
-
- /* XXX - Add PRIVSEP() macro */
- if (compat20) {
- debug3("Recording SSHv2 session logout in wtmpx");
- record_logout(getpid(), NULL, "sshd", authctxt->user);
- }
-
-#ifdef GSSAPI
- fatal_remove_cleanup((void (*)(void *))ssh_gssapi_cleanup_creds,
- &xxx_gssctxt);
- ssh_gssapi_cleanup_creds(xxx_gssctxt);
- ssh_gssapi_server_mechs(NULL); /* release cached server mechs */
-#endif /* GSSAPI */
-
-#ifdef HAVE_BSM
- fatal_remove_cleanup((void (*)(void *))audit_sshd_logout, (void *)&ah);
- audit_sshd_logout(&ah);
-#endif /* HAVE_BSM */
-
-#ifdef USE_PAM
- finish_pam(authctxt);
-#endif /* USE_PAM */
-
- /* The connection has been terminated. */
- verbose("Closing connection to %.100s", remote_ip);
-
- packet_close();
-
- if (use_privsep)
- mm_terminate();
-
- return (0);
#endif /* ALTPRIVSEP */
}
@@ -2123,7 +1857,7 @@ do_ssh1_kex(void)
packet_check_eom();
/* Decrypt session_key_int using host/server keys */
- rsafail = PRIVSEP(ssh1_session_key(session_key_int));
+ rsafail = ssh1_session_key(session_key_int);
/*
* Extract session key from the decrypted integer. The key is in the
@@ -2178,9 +1912,6 @@ do_ssh1_kex(void)
/* Destroy the private and public keys. No longer. */
destroy_sensitive_data();
- if (use_privsep)
- mm_ssh1_session_id(session_id);
-
/* Destroy the decrypted integer. It is no longer needed. */
BN_clear_free(session_key_int);
@@ -2249,6 +1980,9 @@ do_ssh2_kex(void)
g11n_locales2langs(locales);
}
+ if (locales != NULL)
+ g11n_freelist(locales);
+
if ((myproposal[PROPOSAL_LANG_STOC] != NULL) ||
(strcmp(myproposal[PROPOSAL_LANG_STOC], "")) != 0)
myproposal[PROPOSAL_LANG_CTOS] =
@@ -2261,6 +1995,12 @@ do_ssh2_kex(void)
/* start key exchange */
kex = kex_setup(NULL, myproposal, kex_hook);
+
+ if (myproposal[PROPOSAL_LANG_STOC] != NULL)
+ xfree(myproposal[PROPOSAL_LANG_STOC]);
+ if (myproposal[PROPOSAL_LANG_CTOS] != NULL)
+ xfree(myproposal[PROPOSAL_LANG_CTOS]);
+
kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
#ifdef GSSAPI