From d03f42626b290c7c9839e1ecb27dfb069e76a396 Mon Sep 17 00:00:00 2001 From: jbasney Date: Fri, 18 Oct 2002 13:29:26 +0000 Subject: [PATCH] merged OpenSSH 3.5p1 to trunk --- openssh/Makefile.in | 34 +- openssh/acconfig.h | 13 +- openssh/auth-krb5.c | 20 +- openssh/auth-pam.c | 61 ++- openssh/auth-pam.h | 29 +- openssh/auth.c | 19 +- openssh/auth.h | 6 +- openssh/auth1.c | 49 +- openssh/auth2-none.c | 4 +- openssh/auth2.c | 28 +- openssh/canohost.c | 26 +- openssh/cipher.c | 19 +- openssh/compat.c | 8 +- openssh/compat.h | 7 +- openssh/configure.ac | 214 +++++---- openssh/contrib/aix/buildbff.sh | 29 +- openssh/contrib/gnome-ssh-askpass.c | 150 ------- openssh/defines.h | 18 +- openssh/includes.h | 11 + openssh/kex.h | 4 +- openssh/key.c | 30 +- openssh/log.c | 22 +- openssh/monitor.c | 130 +++++- openssh/monitor.h | 4 +- openssh/monitor_fdpass.c | 15 +- openssh/monitor_mm.c | 26 +- openssh/monitor_mm.h | 2 +- openssh/monitor_wrap.c | 102 ++++- openssh/monitor_wrap.h | 14 +- openssh/msg.c | 20 +- openssh/msg.h | 4 +- openssh/openbsd-compat/fake-queue.h | 490 -------------------- openssh/openbsd-compat/getopt.c | 2 +- openssh/openbsd-compat/port-aix.c | 45 +- openssh/openbsd-compat/port-aix.h | 30 +- openssh/openbsd-compat/tree.h | 667 ---------------------------- openssh/packet.c | 13 +- openssh/readconf.c | 2 +- openssh/servconf.c | 16 +- openssh/servconf.h | 3 +- openssh/session.c | 116 +++-- openssh/session.h | 4 +- openssh/ssh-agent.c | 60 ++- openssh/ssh-keysign.8 | 17 +- openssh/ssh-keysign.c | 37 +- openssh/ssh-rand-helper.c | 11 +- openssh/ssh.1 | 57 ++- openssh/ssh.c | 60 ++- openssh/ssh_config.5 | 67 +-- openssh/sshconnect1.c | 4 +- openssh/sshconnect2.c | 12 +- openssh/sshd.8 | 40 +- openssh/sshd.c | 93 ++-- openssh/sshd_config.5 | 62 ++- 54 files changed, 1207 insertions(+), 1819 deletions(-) delete mode 100644 openssh/contrib/gnome-ssh-askpass.c delete mode 100644 openssh/openbsd-compat/fake-queue.h delete mode 100644 openssh/openbsd-compat/tree.h diff --git a/openssh/Makefile.in b/openssh/Makefile.in index a2293aa..2ed79a0 100644 --- a/openssh/Makefile.in +++ b/openssh/Makefile.in @@ -130,7 +130,7 @@ ssh-keygen$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keygen.o $(LD) -o $@ ssh-keygen.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ssh-keysign$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keysign.o - $(LD) -o $@ ssh-keysign.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) + $(LD) -o $@ ssh-keysign.o readconf.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) @@ -199,12 +199,11 @@ distprep: catman-do $(AUTORECONF) (cd scard && $(MAKE) -f Makefile.in distprep) -install: $(CONFIGFILES) $(MANPAGES) $(TARGETS) install-files host-key check-user +install: $(CONFIGFILES) $(MANPAGES) $(TARGETS) install-files host-key check-config install-nokeys: $(CONFIGFILES) $(MANPAGES) $(TARGETS) install-files -check-user: - id $(SSH_PRIVSEP_USER) || \ - echo "WARNING: Privilege separation user \"$(SSH_PRIVSEP_USER)\" does not exist" +check-config: + -$(DESTDIR)$(sbindir)/sshd -t -f $(DESTDIR)$(sysconfdir)/sshd_config scard-install: (cd scard && $(MAKE) DESTDIR=$(DESTDIR) install) @@ -218,8 +217,7 @@ install-files: scard-install $(srcdir)/mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)5 $(srcdir)/mkinstalldirs $(DESTDIR)$(mandir)/$(mansubdir)8 $(srcdir)/mkinstalldirs $(DESTDIR)$(libexecdir) - $(srcdir)/mkinstalldirs $(DESTDIR)$(PRIVSEP_PATH) - chmod 0700 $(DESTDIR)$(PRIVSEP_PATH) + (umask 022 ; $(srcdir)/mkinstalldirs $(DESTDIR)$(PRIVSEP_PATH)) $(INSTALL) -m 0755 -s ssh $(DESTDIR)$(bindir)/ssh $(INSTALL) -m 0755 -s scp $(DESTDIR)$(bindir)/scp $(INSTALL) -m 0755 -s ssh-add $(DESTDIR)$(bindir)/ssh-add @@ -249,33 +247,33 @@ install-files: scard-install @NO_SFTP@$(INSTALL) -m 644 sftp-server.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/sftp-server.8 $(INSTALL) -m 644 ssh-keysign.8.out $(DESTDIR)$(mandir)/$(mansubdir)8/ssh-keysign.8 -rm -f $(DESTDIR)$(bindir)/slogin - ln -s ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin + ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin -rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 - ln -s ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 + ln -s ./ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1 if [ ! -z "$(INSTALL_GSISSH)" ]; then \ rm -f $(DESTDIR)$(bindir)/gsissh; \ - ln -s ssh$(EXEEXT) $(DESTDIR)$(bindir)/gsissh; \ + ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/gsissh; \ rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/gsissh.1; \ - ln -s ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/gsissh.1; \ + ln -s ./ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/gsissh.1; \ rm -f $(DESTDIR)$(bindir)/gsiscp; \ - ln -s scp$(EXEEXT) $(DESTDIR)$(bindir)/gsiscp; \ + ln -s ./scp$(EXEEXT) $(DESTDIR)$(bindir)/gsiscp; \ rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/gsiscp.1; \ - ln -s scp.1 $(DESTDIR)$(mandir)/$(mansubdir)1/gsiscp.1; \ + ln -s ./scp.1 $(DESTDIR)$(mandir)/$(mansubdir)1/gsiscp.1; \ fi if [ ! -d $(DESTDIR)$(sysconfdir) ]; then \ $(srcdir)/mkinstalldirs $(DESTDIR)$(sysconfdir); \ fi - if [ ! -f $(DESTDIR)$(sysconfdir)/ssh_config ]; then \ + @if [ ! -f $(DESTDIR)$(sysconfdir)/ssh_config ]; then \ $(INSTALL) -m 644 ssh_config.out $(DESTDIR)$(sysconfdir)/ssh_config; \ else \ echo "$(DESTDIR)$(sysconfdir)/ssh_config already exists, install will not overwrite"; \ fi - if [ ! -f $(DESTDIR)$(sysconfdir)/sshd_config ]; then \ + @if [ ! -f $(DESTDIR)$(sysconfdir)/sshd_config ]; then \ $(INSTALL) -m 644 sshd_config.out $(DESTDIR)$(sysconfdir)/sshd_config; \ else \ echo "$(DESTDIR)$(sysconfdir)/sshd_config already exists, install will not overwrite"; \ fi - if [ -f ssh_prng_cmds -a ! -z "$(INSTALL_SSH_PRNG_CMDS)" ]; then \ + @if [ -f ssh_prng_cmds -a ! -z "$(INSTALL_SSH_PRNG_CMDS)" ]; then \ $(PERL) $(srcdir)/fixprogs ssh_prng_cmds $(ENT); \ if [ ! -f $(DESTDIR)$(sysconfdir)/ssh_prng_cmds ] ; then \ $(INSTALL) -m 644 ssh_prng_cmds.out $(DESTDIR)$(sysconfdir)/ssh_prng_cmds; \ @@ -283,7 +281,7 @@ install-files: scard-install echo "$(DESTDIR)$(sysconfdir)/ssh_prng_cmds already exists, install will not overwrite"; \ fi ; \ fi - if [ ! -f $(DESTDIR)$(sysconfdir)/moduli ]; then \ + @if [ ! -f $(DESTDIR)$(sysconfdir)/moduli ]; then \ if [ -f $(DESTDIR)$(sysconfdir)/primes ]; then \ echo "moving $(DESTDIR)$(sysconfdir)/primes to $(DESTDIR)$(sysconfdir)/moduli"; \ mv "$(DESTDIR)$(sysconfdir)/primes" "$(DESTDIR)$(sysconfdir)/moduli"; \ @@ -295,7 +293,7 @@ install-files: scard-install fi host-key: ssh-keygen$(EXEEXT) - if [ -z "$(DESTDIR)" ] ; then \ + @if [ -z "$(DESTDIR)" ] ; then \ if [ -f "$(DESTDIR)$(sysconfdir)/ssh_host_key" ] ; then \ echo "$(DESTDIR)$(sysconfdir)/ssh_host_key already exists, skipping." ; \ else \ diff --git a/openssh/acconfig.h b/openssh/acconfig.h index 0353314..1676a42 100644 --- a/openssh/acconfig.h +++ b/openssh/acconfig.h @@ -150,6 +150,9 @@ /* Define if you don't want to use lastlog */ #undef DISABLE_LASTLOG +/* Define if you don't want to use lastlog in session.c */ +#undef NO_SSH_LASTLOG + /* Define if you don't want to use utmp */ #undef DISABLE_UTMP @@ -319,6 +322,9 @@ /* Define if X11 doesn't support AF_UNIX sockets on that system */ #undef NO_X11_UNIX_SOCKETS +/* Define if the concept of ports only accessible to superusers isn't known */ +#undef NO_IPPORT_RESERVED_CONCEPT + /* Needed for SCO and NeXT */ #undef BROKEN_SAVED_UIDS @@ -364,11 +370,8 @@ /* Path that unprivileged child will chroot() to in privep mode */ #undef PRIVSEP_PATH -/* Define if you have the `mmap' function that supports MAP_ANON|SHARED */ -#undef HAVE_MMAP_ANON_SHARED - -/* Define if sendmsg()/recvmsg() has problems passing file descriptors */ -#undef BROKEN_FD_PASSING +/* Define if your platform needs to skip post auth file descriptor passing */ +#undef DISABLE_FD_PASSING @BOTTOM@ diff --git a/openssh/auth-krb5.c b/openssh/auth-krb5.c index 308a6d5..512f70b 100644 --- a/openssh/auth-krb5.c +++ b/openssh/auth-krb5.c @@ -28,7 +28,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-krb5.c,v 1.8 2002/03/19 10:49:35 markus Exp $"); +RCSID("$OpenBSD: auth-krb5.c,v 1.9 2002/09/09 06:48:06 itojun Exp $"); #include "ssh.h" #include "ssh1.h" @@ -73,18 +73,17 @@ krb5_init(void *context) * from the ticket */ int -auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client) +auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *reply) { krb5_error_code problem; krb5_principal server; - krb5_data reply; krb5_ticket *ticket; int fd, ret; ret = 0; server = NULL; ticket = NULL; - reply.length = 0; + reply->length = 0; problem = krb5_init(authctxt); if (problem) @@ -131,7 +130,7 @@ auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client) /* if client wants mutual auth */ problem = krb5_mk_rep(authctxt->krb5_ctx, authctxt->krb5_auth_ctx, - &reply); + reply); if (problem) goto err; @@ -144,19 +143,16 @@ auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client) krb5_unparse_name(authctxt->krb5_ctx, authctxt->krb5_user, client); - packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE); - packet_put_string((char *) reply.data, reply.length); - packet_send(); - packet_write_wait(); - ret = 1; err: if (server) krb5_free_principal(authctxt->krb5_ctx, server); if (ticket) krb5_free_ticket(authctxt->krb5_ctx, ticket); - if (reply.length) - xfree(reply.data); + if (!ret && reply->length) { + xfree(reply->data); + memset(reply, 0, sizeof(*reply)); + } if (problem) { if (authctxt->krb5_ctx != NULL) diff --git a/openssh/auth-pam.c b/openssh/auth-pam.c index eb4c616..be521ff 100644 --- a/openssh/auth-pam.c +++ b/openssh/auth-pam.c @@ -25,10 +25,10 @@ #include "includes.h" #ifdef USE_PAM -#include "ssh.h" #include "xmalloc.h" #include "log.h" #include "auth.h" +#include "auth-options.h" #include "auth-pam.h" #include "servconf.h" #include "canohost.h" @@ -36,17 +36,21 @@ extern char *__progname; +extern int use_privsep; + RCSID("$Id$"); #define NEW_AUTHTOK_MSG \ - "Warning: Your password has expired, please change it now" + "Warning: Your password has expired, please change it now." +#define NEW_AUTHTOK_MSG_PRIVSEP \ + "Your password has expired, the session cannot proceed." static int do_pam_conversation(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr); /* module-local variables */ static struct pam_conv conv = { - do_pam_conversation, + (int (*)())do_pam_conversation, NULL }; static char *__pam_msg = NULL; @@ -55,7 +59,7 @@ static const char *__pampasswd = NULL; /* states for do_pam_conversation() */ enum { INITIAL_LOGIN, OTHER } pamstate = INITIAL_LOGIN; -/* remember whether pam_acct_mgmt() returned PAM_NEWAUTHTOK_REQD */ +/* remember whether pam_acct_mgmt() returned PAM_NEW_AUTHTOK_REQD */ static int password_change_required = 0; /* remember whether the last pam_authenticate() succeeded or not */ static int was_authenticated = 0; @@ -100,9 +104,7 @@ static int do_pam_conversation(int num_msg, const struct pam_message **msg, char buf[1024]; /* PAM will free this later */ - reply = malloc(num_msg * sizeof(*reply)); - if (reply == NULL) - return PAM_CONV_ERR; + reply = xmalloc(num_msg * sizeof(*reply)); for (count = 0; count < num_msg; count++) { if (pamstate == INITIAL_LOGIN) { @@ -112,11 +114,11 @@ static int do_pam_conversation(int num_msg, const struct pam_message **msg, */ switch(PAM_MSG_MEMBER(msg, count, msg_style)) { case PAM_PROMPT_ECHO_ON: - free(reply); + xfree(reply); return PAM_CONV_ERR; case PAM_PROMPT_ECHO_OFF: if (__pampasswd == NULL) { - free(reply); + xfree(reply); return PAM_CONV_ERR; } reply[count].resp = xstrdup(__pampasswd); @@ -124,7 +126,7 @@ static int do_pam_conversation(int num_msg, const struct pam_message **msg, break; case PAM_ERROR_MSG: case PAM_TEXT_INFO: - if ((*msg)[count].msg != NULL) { + if (PAM_MSG_MEMBER(msg, count, msg) != NULL) { message_cat(&__pam_msg, PAM_MSG_MEMBER(msg, count, msg)); } @@ -132,7 +134,7 @@ static int do_pam_conversation(int num_msg, const struct pam_message **msg, reply[count].resp_retcode = PAM_SUCCESS; break; default: - free(reply); + xfree(reply); return PAM_CONV_ERR; } } else { @@ -154,14 +156,14 @@ static int do_pam_conversation(int num_msg, const struct pam_message **msg, break; case PAM_ERROR_MSG: case PAM_TEXT_INFO: - if ((*msg)[count].msg != NULL) + if (PAM_MSG_MEMBER(msg, count, msg) != NULL) fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, count, msg)); reply[count].resp = xstrdup(""); reply[count].resp_retcode = PAM_SUCCESS; break; default: - free(reply); + xfree(reply); return PAM_CONV_ERR; } } @@ -256,9 +258,14 @@ int do_pam_account(char *username, char *remote_user) break; #if 0 case PAM_NEW_AUTHTOK_REQD: - message_cat(&__pam_msg, NEW_AUTHTOK_MSG); + message_cat(&__pam_msg, use_privsep ? + NEW_AUTHTOK_MSG_PRIVSEP : NEW_AUTHTOK_MSG); /* flag that password change is necessary */ password_change_required = 1; + /* disallow other functionality for now */ + no_port_forwarding_flag |= 2; + no_agent_forwarding_flag |= 2; + no_x11_forwarding_flag |= 2; break; #endif default: @@ -328,7 +335,7 @@ int is_pam_password_change_required(void) * Have user change authentication token if pam_acct_mgmt() indicated * it was expired. This needs to be called after an interactive * session is established and the user's pty is connected to - * stdin/stout/stderr. + * stdin/stdout/stderr. */ void do_pam_chauthtok(void) { @@ -337,11 +344,23 @@ void do_pam_chauthtok(void) do_pam_set_conv(&conv); if (password_change_required) { + if (use_privsep) + fatal("Password changing is currently unsupported" + " with privilege separation"); pamstate = OTHER; pam_retval = pam_chauthtok(__pamh, PAM_CHANGE_EXPIRED_AUTHTOK); if (pam_retval != PAM_SUCCESS) fatal("PAM pam_chauthtok failed[%d]: %.200s", pam_retval, PAM_STRERROR(__pamh, pam_retval)); +#if 0 + /* XXX: This would need to be done in the parent process, + * but there's currently no way to pass such request. */ + no_port_forwarding_flag &= ~2; + no_agent_forwarding_flag &= ~2; + no_x11_forwarding_flag &= ~2; + if (!no_port_forwarding_flag && options.allow_tcp_forwarding) + channel_permit_all_opens(); +#endif } } @@ -392,7 +411,7 @@ void start_pam(const char *user) fatal_add_cleanup(&do_pam_cleanup_proc, NULL); } -/* Return list of PAM enviornment strings */ +/* Return list of PAM environment strings */ char **fetch_pam_environment(void) { #ifdef HAVE_PAM_GETENVLIST @@ -422,6 +441,16 @@ int do_pam_putenv(char *name, char *value) { return(ret); } +void free_pam_environment(char **env) +{ + int i; + + if (env != NULL) { + for (i = 0; env[i] != NULL; i++) + xfree(env[i]); + } +} + /* Print any messages that have been generated during authentication */ /* or account checking to stderr */ void print_pam_messages(void) diff --git a/openssh/auth-pam.h b/openssh/auth-pam.h index 71996d9..50bf8f3 100644 --- a/openssh/auth-pam.h +++ b/openssh/auth-pam.h @@ -1,14 +1,41 @@ /* $Id$ */ +/* + * Copyright (c) 2000 Damien Miller. 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" #ifdef USE_PAM -#include /* For struct passwd */ +#if !defined(SSHD_PAM_SERVICE) +# define SSHD_PAM_SERVICE __progname +#endif void start_pam(const char *user); void finish_pam(void); int auth_pam_password(Authctxt *authctxt, const char *password); char **fetch_pam_environment(void); +void free_pam_environment(char **env); int do_pam_authenticate(int flags); int do_pam_account(char *username, char *remote_user); void do_pam_session(char *username, const char *ttyname); diff --git a/openssh/auth.c b/openssh/auth.c index 45855d4..ac5b3c2 100644 --- a/openssh/auth.c +++ b/openssh/auth.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth.c,v 1.43 2002/05/17 14:27:55 millert Exp $"); +RCSID("$OpenBSD: auth.c,v 1.45 2002/09/20 18:41:29 stevesk Exp $"); #ifdef HAVE_LOGIN_H #include @@ -256,6 +256,14 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) get_remote_ipaddr(), get_remote_port(), info); + +#ifdef WITH_AIXAUTHENTICATE + if (authenticated == 0 && strcmp(method, "password") == 0) + loginfailed(authctxt->user, + get_canonical_hostname(options.verify_reverse_mapping), + "ssh"); +#endif /* WITH_AIXAUTHENTICATE */ + } /* @@ -392,7 +400,7 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host, /* * Check a given file for security. This is defined as all components - * of the path to the file must either be owned by either the owner of + * of the path to the file must be owned by either the owner of * of the file or root and no directories must be group or world writable. * * XXX Should any specific check be done for sym links ? @@ -476,7 +484,12 @@ getpwnamallow(const char *user) struct passwd *pw; pw = getpwnam(user); - if (pw == NULL || !allowed_user(pw)) + if (pw == NULL) { + log("Illegal user %.100s from %.100s", + user, get_remote_ipaddr()); + return (NULL); + } + if (!allowed_user(pw)) return (NULL); #ifdef HAVE_LOGIN_CAP if ((lc = login_getclass(pw->pw_class)) == NULL) { diff --git a/openssh/auth.h b/openssh/auth.h index 6dd349c..8e63132 100644 --- a/openssh/auth.h +++ b/openssh/auth.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.h,v 1.39 2002/05/31 11:35:15 markus Exp $ */ +/* $OpenBSD: auth.h,v 1.41 2002/09/26 11:38:43 markus Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -114,7 +114,7 @@ int user_key_allowed(struct passwd *, Key *); #ifdef KRB4 #include -int auth_krb4(Authctxt *, KTEXT, char **); +int auth_krb4(Authctxt *, KTEXT, char **, KTEXT); int auth_krb4_password(Authctxt *, const char *); void krb4_cleanup_proc(void *); @@ -127,7 +127,7 @@ int auth_afs_token(Authctxt *, const char *); #endif /* KRB4 */ #ifdef KRB5 -int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client); +int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *); int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt); int auth_krb5_password(Authctxt *authctxt, const char *password); void krb5_cleanup_proc(void *authctxt); diff --git a/openssh/auth1.c b/openssh/auth1.c index 39145cb..ea570d1 100644 --- a/openssh/auth1.c +++ b/openssh/auth1.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth1.c,v 1.41 2002/06/19 00:27:55 deraadt Exp $"); +RCSID("$OpenBSD: auth1.c,v 1.44 2002/09/26 11:38:43 markus Exp $"); #include "xmalloc.h" #include "rsa.h" @@ -245,30 +245,49 @@ do_authloop(Authctxt *authctxt) if (kdata[0] == 4) { /* KRB_PROT_VERSION */ #ifdef KRB4 - KTEXT_ST tkt; - + KTEXT_ST tkt, reply; tkt.length = dlen; if (tkt.length < MAX_KTXT_LEN) memcpy(tkt.dat, kdata, tkt.length); - if (auth_krb4(authctxt, &tkt, &client_user)) { + if (PRIVSEP(auth_krb4(authctxt, &tkt, + &client_user, &reply))) { authenticated = 1; snprintf(info, sizeof(info), " tktuser %.100s", client_user); + + packet_start( + SSH_SMSG_AUTH_KERBEROS_RESPONSE); + packet_put_string((char *) + reply.dat, reply.length); + packet_send(); + packet_write_wait(); } #endif /* KRB4 */ } else { #ifdef KRB5 - krb5_data tkt; + krb5_data tkt, reply; tkt.length = dlen; tkt.data = kdata; - if (auth_krb5(authctxt, &tkt, &client_user)) { + if (PRIVSEP(auth_krb5(authctxt, &tkt, + &client_user, &reply))) { authenticated = 1; snprintf(info, sizeof(info), " tktuser %.100s", client_user); + + /* Send response to client */ + packet_start( + SSH_SMSG_AUTH_KERBEROS_RESPONSE); + packet_put_string((char *) + reply.data, reply.length); + packet_send(); + packet_write_wait(); + + if (reply.length) + xfree(reply.data); } #endif /* KRB5 */ } @@ -452,6 +471,15 @@ do_authloop(Authctxt *authctxt) fatal("INTERNAL ERROR: authenticated invalid user %s", authctxt->user); +#ifdef _UNICOS + if (type == SSH_CMSG_AUTH_PASSWORD && !authenticated) + cray_login_failure(authctxt->user, IA_UDBERR); + if (authenticated && cray_access_denied(authctxt->user)) { + authenticated = 0; + fatal("Access denied for user %s.",authctxt->user); + } +#endif /* _UNICOS */ + #ifdef HAVE_CYGWIN if (authenticated && !check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD, pw)) { @@ -461,7 +489,8 @@ do_authloop(Authctxt *authctxt) } #else /* Special handling for root */ - if (authenticated && authctxt->pw->pw_uid == 0 && + if (!use_privsep && + authenticated && authctxt->pw->pw_uid == 0 && !auth_root_allowed(get_authname(type))) authenticated = 0; #endif @@ -483,12 +512,6 @@ do_authloop(Authctxt *authctxt) return; if (authctxt->failures++ > AUTH_FAIL_MAX) { -#ifdef WITH_AIXAUTHENTICATE - /* XXX: privsep */ - loginfailed(authctxt->user, - get_canonical_hostname(options.verify_reverse_mapping), - "ssh"); -#endif /* WITH_AIXAUTHENTICATE */ packet_disconnect(AUTH_FAIL_MSG, authctxt->user); } diff --git a/openssh/auth2-none.c b/openssh/auth2-none.c index 720d3c1..c07b2dd 100644 --- a/openssh/auth2-none.c +++ b/openssh/auth2-none.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2-none.c,v 1.3 2002/06/19 00:27:55 deraadt Exp $"); +RCSID("$OpenBSD: auth2-none.c,v 1.4 2002/06/27 10:35:47 deraadt Exp $"); #include "auth.h" #include "xmalloc.h" @@ -61,7 +61,7 @@ auth2_read_banner(void) close(fd); if (n != len) { - free(banner); + xfree(banner); return (NULL); } banner[n] = '\0'; diff --git a/openssh/auth2.c b/openssh/auth2.c index b717298..fcab335 100644 --- a/openssh/auth2.c +++ b/openssh/auth2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth2.c,v 1.93 2002/05/31 11:35:15 markus Exp $"); +RCSID("$OpenBSD: auth2.c,v 1.95 2002/08/22 21:33:58 markus Exp $"); #include "ssh2.h" #include "ssh1.h" @@ -115,7 +115,7 @@ input_service_request(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; u_int len; - int accept = 0; + int acceptit = 0; char *service = packet_get_string(&len); packet_check_eom(); @@ -124,14 +124,14 @@ input_service_request(int type, u_int32_t seq, void *ctxt) if (strcmp(service, "ssh-userauth") == 0) { if (!authctxt->success) { - accept = 1; + acceptit = 1; /* now we can handle user-auth requests */ dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request); } } /* XXX all other service requests are denied */ - if (accept) { + if (acceptit) { packet_start(SSH2_MSG_SERVICE_ACCEPT); packet_put_cstring(service); packet_send(); @@ -267,7 +267,8 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) authctxt->user); /* Special handling for root */ - if (authenticated && authctxt->pw->pw_uid == 0 && + if (!use_privsep && + authenticated && authctxt->pw->pw_uid == 0 && !auth_root_allowed(method)) authenticated = 0; @@ -277,6 +278,13 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) authenticated = 0; #endif /* USE_PAM */ +#ifdef _UNICOS + if (authenticated && cray_access_denied(authctxt->user)) { + authenticated = 0; + fatal("Access denied for user %s.",authctxt->user); + } +#endif /* _UNICOS */ + /* Log before sending the reply */ if (!compat20) auth_log(authctxt, authenticated, method, " ssh1"); @@ -299,12 +307,6 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) authctxt->success = 1; } else { if (authctxt->failures++ > AUTH_FAIL_MAX) { -#ifdef WITH_AIXAUTHENTICATE - /* XXX: privsep */ - loginfailed(authctxt->user, - get_canonical_hostname(options.verify_reverse_mapping), - "ssh"); -#endif /* WITH_AIXAUTHENTICATE */ packet_disconnect(AUTH_FAIL_MSG, authctxt->user); } if (!compat20) { @@ -317,6 +319,10 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method) */ authctxt->success = authctxt->postponed = 1; } else { +#ifdef _UNICOS + if (strcmp(method, "password") == 0) + cray_login_failure(authctxt->user, IA_UDBERR); +#endif /* _UNICOS */ methods = authmethods_get(); packet_start(SSH2_MSG_USERAUTH_FAILURE); packet_put_cstring(methods); diff --git a/openssh/canohost.c b/openssh/canohost.c index 1f7e15a..b8d92b2 100644 --- a/openssh/canohost.c +++ b/openssh/canohost.c @@ -12,7 +12,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: canohost.c,v 1.32 2002/06/11 08:11:45 itojun Exp $"); +RCSID("$OpenBSD: canohost.c,v 1.34 2002/09/23 20:46:27 stevesk Exp $"); #include "packet.h" #include "xmalloc.h" @@ -77,7 +77,9 @@ get_remote_hostname(int socket, int verify_reverse_mapping) if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), NULL, 0, NI_NAMEREQD) != 0) { /* Host name not found. Use ip address. */ +#if 0 log("Could not reverse map address %.100s.", ntop); +#endif return xstrdup(ntop); } @@ -216,18 +218,12 @@ get_socket_address(int socket, int remote, int flags) if (remote) { if (getpeername(socket, (struct sockaddr *)&addr, &addrlen) - < 0) { - debug("get_socket_ipaddr: getpeername failed: %.100s", - strerror(errno)); + < 0) return NULL; - } } else { if (getsockname(socket, (struct sockaddr *)&addr, &addrlen) - < 0) { - debug("get_socket_ipaddr: getsockname failed: %.100s", - strerror(errno)); + < 0) return NULL; - } } /* Get the address in ascii. */ if (getnameinfo((struct sockaddr *)&addr, addrlen, ntop, sizeof(ntop), @@ -241,13 +237,21 @@ get_socket_address(int socket, int remote, int flags) char * get_peer_ipaddr(int socket) { - return get_socket_address(socket, 1, NI_NUMERICHOST); + char *p; + + if ((p = get_socket_address(socket, 1, NI_NUMERICHOST)) != NULL) + return p; + return xstrdup("UNKNOWN"); } char * get_local_ipaddr(int socket) { - return get_socket_address(socket, 0, NI_NUMERICHOST); + char *p; + + if ((p = get_socket_address(socket, 0, NI_NUMERICHOST)) != NULL) + return p; + return xstrdup("UNKNOWN"); } char * diff --git a/openssh/cipher.c b/openssh/cipher.c index 6db340d..1933d3e 100644 --- a/openssh/cipher.c +++ b/openssh/cipher.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: cipher.c,v 1.60 2002/06/23 03:26:52 deraadt Exp $"); +RCSID("$OpenBSD: cipher.c,v 1.61 2002/07/12 15:50:17 markus Exp $"); #include "xmalloc.h" #include "log.h" @@ -437,6 +437,18 @@ swap_bytes(const u_char *src, u_char *dst, int n) } } +#ifdef SSH_OLD_EVP +static void bf_ssh1_init (EVP_CIPHER_CTX * ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + if (iv != NULL) + memcpy (&(ctx->oiv[0]), iv, 8); + memcpy (&(ctx->iv[0]), &(ctx->oiv[0]), 8); + if (key != NULL) + BF_set_key (&(ctx->c.bf_ks), EVP_CIPHER_CTX_key_length (ctx), + key); +} +#endif static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *, const u_char *, u_int) = NULL; static int @@ -458,6 +470,9 @@ evp_ssh1_bf(void) memcpy(&ssh1_bf, EVP_bf_cbc(), sizeof(EVP_CIPHER)); orig_bf = ssh1_bf.do_cipher; ssh1_bf.nid = NID_undef; +#ifdef SSH_OLD_EVP + ssh1_bf.init = bf_ssh1_init; +#endif ssh1_bf.do_cipher = bf_ssh1_cipher; ssh1_bf.key_len = 32; return (&ssh1_bf); @@ -567,7 +582,7 @@ evp_rijndael(void) rijndal_cbc.do_cipher = ssh_rijndael_cbc; #ifndef SSH_OLD_EVP rijndal_cbc.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | - EVP_CIPH_ALWAYS_CALL_INIT; + EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV; #endif return (&rijndal_cbc); } diff --git a/openssh/compat.c b/openssh/compat.c index e8a89cd..734760a 100644 --- a/openssh/compat.c +++ b/openssh/compat.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: compat.c,v 1.63 2002/04/10 08:21:47 markus Exp $"); +RCSID("$OpenBSD: compat.c,v 1.65 2002/09/27 10:42:09 mickey Exp $"); #include "buffer.h" #include "packet.h" @@ -39,13 +39,13 @@ int datafellows = 0; void enable_compat20(void) { - verbose("Enabling compatibility mode for protocol 2.0"); + debug("Enabling compatibility mode for protocol 2.0"); compat20 = 1; } void enable_compat13(void) { - verbose("Enabling compatibility mode for protocol 1.3"); + debug("Enabling compatibility mode for protocol 1.3"); compat13 = 1; } /* datafellows bug compatibility */ @@ -148,6 +148,8 @@ compat_datafellows(const char *version) "OSU_1.5alpha3*", SSH_BUG_PASSWORDPAD }, { "*SSH_Version_Mapper*", SSH_BUG_SCANNER }, + { "Probe-*", + SSH_BUG_PROBE }, { NULL, 0 } }; diff --git a/openssh/compat.h b/openssh/compat.h index 98a8adf..aec2812 100644 --- a/openssh/compat.h +++ b/openssh/compat.h @@ -1,4 +1,4 @@ -/* $OpenBSD: compat.h,v 1.32 2002/04/10 08:21:47 markus Exp $ */ +/* $OpenBSD: compat.h,v 1.33 2002/09/27 10:42:09 mickey Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. @@ -54,8 +54,9 @@ #define SSH_BUG_DUMMYCHAN 0x00100000 #define SSH_BUG_EXTEOF 0x00200000 #define SSH_BUG_K5USER 0x00400000 -#define SSH_OLD_GSSAPI 0x00800000 -#define SSH_BUG_GSS_EMPTYUSER 0x01000000 +#define SSH_BUG_PROBE 0x00800000 +#define SSH_OLD_GSSAPI 0x10000000 +#define SSH_BUG_GSS_EMPTYUSER 0x20000000 void enable_compat13(void); void enable_compat20(void); diff --git a/openssh/configure.ac b/openssh/configure.ac index 67cff42..100c725 100644 --- a/openssh/configure.ac +++ b/openssh/configure.ac @@ -17,7 +17,6 @@ AC_PATH_PROGS(PERL, perl5 perl) AC_SUBST(PERL) AC_PATH_PROG(ENT, ent) AC_SUBST(ENT) -AC_PATH_PROGS(FILEPRIV, filepriv, true, /sbin:/usr/sbin) AC_PATH_PROG(TEST_MINUS_S_SH, bash) AC_PATH_PROG(TEST_MINUS_S_SH, ksh) AC_PATH_PROG(TEST_MINUS_S_SH, sh) @@ -71,7 +70,12 @@ case "$host" in ) LDFLAGS="$saved_LDFLAGS" fi - AC_CHECK_FUNC(authenticate, [AC_DEFINE(WITH_AIXAUTHENTICATE)]) + AC_CHECK_FUNC(authenticate, [AC_DEFINE(WITH_AIXAUTHENTICATE)], + [AC_CHECK_LIB(s,authenticate, + [ AC_DEFINE(WITH_AIXAUTHENTICATE) + LIBS="$LIBS -ls" + ]) + ]) AC_DEFINE(BROKEN_GETADDRINFO) AC_DEFINE(BROKEN_REALPATH) dnl AIX handles lastlog as part of its login message @@ -86,14 +90,24 @@ case "$host" in AC_DEFINE(IPV4_DEFAULT) AC_DEFINE(IP_TOS_IS_BROKEN) AC_DEFINE(NO_X11_UNIX_SOCKETS) - AC_DEFINE(BROKEN_FD_PASSING) + AC_DEFINE(NO_IPPORT_RESERVED_CONCEPT) + AC_DEFINE(DISABLE_FD_PASSING) AC_DEFINE(SETGROUPS_NOOP) ;; *-*-dgux*) AC_DEFINE(IP_TOS_IS_BROKEN) ;; *-*-darwin*) - AC_DEFINE(BROKEN_GETADDRINFO) + AC_MSG_CHECKING(if we have working getaddrinfo) + AC_TRY_RUN([#include +main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) + exit(0); + else + exit(1); +}], [AC_MSG_RESULT(working)], + [AC_MSG_RESULT(buggy) + AC_DEFINE(BROKEN_GETADDRINFO)], + [AC_MSG_RESULT(assume it is working)]) ;; *-*-hpux10.26) if test -z "$GCC"; then @@ -108,7 +122,8 @@ case "$host" in AC_DEFINE(DISABLE_SHADOW) AC_DEFINE(DISABLE_UTMP) AC_DEFINE(SPT_TYPE,SPT_PSTAT) - LIBS="$LIBS -lxnet -lsec -lsecpw" + LIBS="$LIBS -lsec -lsecpw" + AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***])) disable_ptmx_check=yes ;; *-*-hpux10*) @@ -123,7 +138,8 @@ case "$host" in AC_DEFINE(DISABLE_SHADOW) AC_DEFINE(DISABLE_UTMP) AC_DEFINE(SPT_TYPE,SPT_PSTAT) - LIBS="$LIBS -lxnet -lsec" + LIBS="$LIBS -lsec" + AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***])) ;; *-*-hpux11*) CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1" @@ -135,7 +151,8 @@ case "$host" in AC_DEFINE(DISABLE_SHADOW) AC_DEFINE(DISABLE_UTMP) AC_DEFINE(SPT_TYPE,SPT_PSTAT) - LIBS="$LIBS -lxnet -lsec" + LIBS="$LIBS -lsec" + AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***])) ;; *-*-irix5*) CPPFLAGS="$CPPFLAGS -I/usr/local/include" @@ -167,6 +184,7 @@ mips-sony-bsd|mips-sony-newsos4) SONY=1 ;; *-*-netbsd*) + check_for_libcrypt_before=1 need_dash_r=1 ;; *-*-freebsd*) @@ -267,17 +285,28 @@ mips-sony-bsd|mips-sony-newsos4) AC_DEFINE(USE_PIPES) AC_DEFINE(HAVE_SECUREWARE) AC_DEFINE(DISABLE_SHADOW) - AC_DEFINE(BROKEN_FD_PASSING) + AC_DEFINE(DISABLE_FD_PASSING) AC_CHECK_FUNCS(getluid setluid) MANTYPE=man ;; +*-*-unicosmk*) + no_libsocket=1 + no_libnsl=1 + AC_DEFINE(USE_PIPES) + AC_DEFINE(DISABLE_FD_PASSING) + LDFLAGS="$LDFLAGS" + LIBS="$LIBS -lgen -lrsc -lshare -luex -lacm" + MANTYPE=cat + ;; *-*-unicos*) no_libsocket=1 no_libnsl=1 AC_DEFINE(USE_PIPES) - AC_DEFINE(BROKEN_FD_PASSING) - LDFLAGS="$LDFLAGS -Wl,-Dmsglevel=334:fatal,-L/usr/local/lib" - LIBS="$LIBS -lgen -lrsc" + AC_DEFINE(DISABLE_FD_PASSING) + AC_DEFINE(NO_SSH_LASTLOG) + LDFLAGS="$LDFLAGS -Wl,-Dmsglevel=334:fatal" + LIBS="$LIBS -lgen -lrsc -lshare -luex -lacm" + MANTYPE=cat ;; *-dec-osf*) AC_MSG_CHECKING(for Digital Unix SIA) @@ -348,14 +377,14 @@ AC_ARG_WITH(libs, # Checks for header files. AC_CHECK_HEADERS(bstring.h crypt.h endian.h floatingpoint.h \ - getopt.h glob.h lastlog.h limits.h login.h \ + getopt.h glob.h ia.h lastlog.h limits.h login.h \ login_cap.h maillock.h netdb.h netgroup.h \ netinet/in_systm.h paths.h pty.h readpassphrase.h \ rpc/types.h security/pam_appl.h shadow.h stddef.h stdint.h \ strings.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h \ sys/mman.h sys/select.h sys/stat.h \ sys/stropts.h sys/sysmacros.h sys/time.h \ - sys/un.h time.h ttyent.h usersec.h \ + sys/un.h time.h tmpdir.h ttyent.h usersec.h \ util.h utime.h utmp.h utmpx.h) # Checks for libraries. @@ -419,7 +448,8 @@ AC_CHECK_FUNC(strcasecmp, [], [ AC_CHECK_LIB(resolv, strcasecmp, LIBS="$LIBS -lresolv") ] ) AC_CHECK_FUNC(utimes, - [], [ AC_CHECK_LIB(c89, utimes, LIBS="$LIBS -lc89") ] + [], [ AC_CHECK_LIB(c89, utimes, [AC_DEFINE(HAVE_UTIMES) + LIBS="$LIBS -lc89"]) ] ) dnl Checks for libutil functions @@ -468,7 +498,7 @@ AC_TRY_RUN( [ #include #include -int main(void){struct dirent d;return(sizeof(d.d_name)<=sizeof(char));} +int main(void){struct dirent d;exit(sizeof(d.d_name)<=sizeof(char));} ], [AC_MSG_RESULT(yes)], [ @@ -656,7 +686,7 @@ AC_ARG_WITH(skey, [ #include #include -int main() { char *ff = skey_keyinfo(""); ff=""; return 0; } +int main() { char *ff = skey_keyinfo(""); ff=""; exit(0); } ], [AC_MSG_RESULT(yes)], [ @@ -724,7 +754,7 @@ AC_ARG_WITH(tcp-wrappers, dnl Checks for library functions. AC_CHECK_FUNCS(arc4random b64_ntop bcopy bindresvport_sa \ clock fchmod fchown freeaddrinfo futimes gai_strerror \ - getaddrinfo getcwd getgrouplist getnameinfo getopt \ + getaddrinfo getcwd getgrouplist getnameinfo getopt getpeereid\ getrlimit getrusage getttyent glob inet_aton inet_ntoa \ inet_ntop innetgr login_getcapbool md5_crypt memmove \ mkdtemp mmap ngetaddrinfo openpty ogetaddrinfo readpassphrase \ @@ -734,30 +764,6 @@ AC_CHECK_FUNCS(arc4random b64_ntop bcopy bindresvport_sa \ socketpair strerror strlcat strlcpy strmode strsep sysconf tcgetpgrp \ truncate utimes vhangup vsnprintf waitpid __b64_ntop _getpty) -if test $ac_cv_func_mmap = yes ; then -AC_MSG_CHECKING([for mmap anon shared]) -AC_TRY_RUN( - [ -#include -#include -#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS) -#define MAP_ANON MAP_ANONYMOUS -#endif -main() { char *p; -p = (char *) mmap(NULL, 10, PROT_WRITE|PROT_READ, MAP_ANON|MAP_SHARED, -1, 0); -if (p == (char *)-1) - exit(1); -exit(0); -} - ], - [ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_MMAP_ANON_SHARED) - ], - [ AC_MSG_RESULT(no) ] -) -fi - dnl IRIX and Solaris 2.5.1 have dirname() in libgen AC_CHECK_FUNCS(dirname, [AC_CHECK_HEADERS(libgen.h)] ,[ AC_CHECK_LIB(gen, dirname,[ @@ -820,7 +826,7 @@ if test "x$ac_cv_func_snprintf" = "xyes" ; then AC_TRY_RUN( [ #include -int main(void){char b[5];snprintf(b,5,"123456789");return(b[4]!='\0');} +int main(void){char b[5];snprintf(b,5,"123456789");exit(b[4]!='\0');} ], [AC_MSG_RESULT(yes)], [ @@ -881,6 +887,12 @@ if test "x$PAM_MSG" = "xyes" ; then ) fi +# Some systems want crypt() from libcrypt, *not* the version in OpenSSL, +# because the system crypt() is more featureful. +if test "x$check_for_libcrypt_before" = "x1"; then + AC_CHECK_LIB(crypt, crypt) +fi + # Search for OpenSSL saved_CPPFLAGS="$CPPFLAGS" saved_LDFLAGS="$LDFLAGS" @@ -999,6 +1011,70 @@ AC_TRY_LINK_FUNC(RAND_add, AC_DEFINE(HAVE_OPENSSL), ] ) +# Determine OpenSSL header version +AC_MSG_CHECKING([OpenSSL header version]) +AC_TRY_RUN( + [ +#include +#include +#include +#define DATA "conftest.sslincver" +int main(void) { + FILE *fd; + int rc; + + fd = fopen(DATA,"w"); + if(fd == NULL) + exit(1); + + if ((rc = fprintf(fd ,"%x (%s)\n", OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT)) <0) + exit(1); + + exit(0); +} + ], + [ + ssl_header_ver=`cat conftest.sslincver` + AC_MSG_RESULT($ssl_header_ver) + ], + [ + AC_MSG_RESULT(not found) + AC_MSG_ERROR(OpenSSL version header not found.) + ] +) + +# Determine OpenSSL library version +AC_MSG_CHECKING([OpenSSL library version]) +AC_TRY_RUN( + [ +#include +#include +#include +#include +#define DATA "conftest.ssllibver" +int main(void) { + FILE *fd; + int rc; + + fd = fopen(DATA,"w"); + if(fd == NULL) + exit(1); + + if ((rc = fprintf(fd ,"%x (%s)\n", SSLeay(), SSLeay_version(SSLEAY_VERSION))) <0) + exit(1); + + exit(0); +} + ], + [ + ssl_library_ver=`cat conftest.ssllibver` + AC_MSG_RESULT($ssl_library_ver) + ], + [ + AC_MSG_RESULT(not found) + AC_MSG_ERROR(OpenSSL library not found.) + ] +) # Sanity check OpenSSL headers AC_MSG_CHECKING([whether OpenSSL's headers match the library]) @@ -1006,7 +1082,7 @@ AC_TRY_RUN( [ #include #include -int main(void) { return(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); } +int main(void) { exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); } ], [ AC_MSG_RESULT(yes) @@ -1032,7 +1108,7 @@ AC_TRY_RUN( [ #include #include -int main(void) { return(RAND_status() == 1 ? 0 : 1); } +int main(void) { exit(RAND_status() == 1 ? 0 : 1); } ], [ OPENSSL_SEEDS_ITSELF=yes @@ -1286,7 +1362,16 @@ fi AC_CACHE_CHECK([for int64_t type], ac_cv_have_int64_t, [ AC_TRY_COMPILE( - [ #include ], + [ +#include +#ifdef HAVE_STDINT_H +# include +#endif +#include +#ifdef HAVE_SYS_BITYPES_H +# include +#endif + ], [ int64_t a; a = 1;], [ ac_cv_have_int64_t="yes" ], [ ac_cv_have_int64_t="no" ] @@ -1294,33 +1379,6 @@ AC_CACHE_CHECK([for int64_t type], ac_cv_have_int64_t, [ ]) if test "x$ac_cv_have_int64_t" = "xyes" ; then AC_DEFINE(HAVE_INT64_T) - have_int64_t=1 -fi - -if test -z "$have_int64_t" ; then - AC_MSG_CHECKING([for int64_t type in sys/socket.h]) - AC_TRY_COMPILE( - [ #include ], - [ int64_t a; a = 1], - [ - AC_DEFINE(HAVE_INT64_T) - AC_MSG_RESULT(yes) - ], - [ AC_MSG_RESULT(no) ] - ) -fi - -if test -z "$have_int64_t" ; then - AC_MSG_CHECKING([for int64_t type in sys/bitypes.h]) - AC_TRY_COMPILE( - [ #include ], - [ int64_t a; a = 1], - [ - AC_DEFINE(HAVE_INT64_T) - AC_MSG_RESULT(yes) - ], - [ AC_MSG_RESULT(no) ] - ) fi AC_CACHE_CHECK([for u_intXX_t types], ac_cv_have_u_intxx_t, [ @@ -2090,7 +2148,7 @@ LIBS="$LIBS $KLIBS $K5LIBS" PRIVSEP_PATH=/var/empty AC_ARG_WITH(privsep-path, - [ --with-privsep-path=xxx Path for privilege separation chroot ], + [ --with-privsep-path=xxx Path for privilege separation chroot (default=/var/empty)], [ if test "x$withval" != "$no" ; then PRIVSEP_PATH=$withval @@ -2107,7 +2165,12 @@ AC_ARG_WITH(xauth, fi ], [ - AC_PATH_PROG(xauth_path, xauth,,$PATH:/usr/X/bin:/usr/bin/X11:/usr/X11R6/bin:/usr/openwin/bin) + TestPath="$PATH" + TestPath="${TestPath}${PATH_SEPARATOR}/usr/X/bin" + TestPath="${TestPath}${PATH_SEPARATOR}/usr/bin/X11" + TestPath="${TestPath}${PATH_SEPARATOR}/usr/X11R6/bin" + TestPath="${TestPath}${PATH_SEPARATOR}/usr/openwin/bin" + AC_PATH_PROG(xauth_path, xauth, , $TestPath) if (test ! -z "$xauth_path" && test -x "/usr/openwin/bin/xauth") ; then xauth_path="/usr/openwin/bin/xauth" fi @@ -2161,7 +2224,8 @@ AC_ARG_WITH(mantype, ] ) if test -z "$MANTYPE"; then - AC_PATH_PROGS(NROFF, nroff awf, /bin/false, /usr/bin:/usr/ucb) + TestPath="/usr/bin${PATH_SEPARATOR}/usr/ucb" + AC_PATH_PROGS(NROFF, nroff awf, /bin/false, $TestPath) if ${NROFF} -mdoc ${srcdir}/ssh.1 >/dev/null 2>&1; then MANTYPE=doc elif ${NROFF} -man ${srcdir}/ssh.1 >/dev/null 2>&1; then diff --git a/openssh/contrib/aix/buildbff.sh b/openssh/contrib/aix/buildbff.sh index d531e53..5c09c6b 100755 --- a/openssh/contrib/aix/buildbff.sh +++ b/openssh/contrib/aix/buildbff.sh @@ -18,6 +18,16 @@ X11_FORWARDING=no umask 022 +startdir=`pwd` + +# Path to inventory.sh: same place as buildbff.sh +if echo $0 | egrep '^/' +then + inventory=`dirname $0`/inventory.sh # absolute path +else + inventory=`pwd`/`dirname $0`/inventory.sh # relative path +fi + # # We still support running from contrib/aix, but this is depreciated # @@ -45,14 +55,6 @@ objdir=`pwd` PKGNAME=openssh PKGDIR=package -# Path to inventory.sh: same place as buildbff.sh -if echo $0 | egrep '^/' -then - inventory=`dirname $0`/inventory.sh # absolute path -else - inventory=`pwd`/`dirname $0`/inventory.sh # relative path -fi - # # Collect local configuration settings to override defaults # @@ -328,15 +330,10 @@ rm -f $PKGNAME-$VERSION.bff ) | backup -i -q -f ../$PKGNAME-$VERSION.bff $filelist # -# Move package into final location +# Move package into final location and clean up # -if [ "$contribaix" = "1" ] -then - mv ../$PKGNAME-$VERSION.bff $objdir/contrib/aix -else - mv ../$PKGNAME-$VERSION.bff $objdir -fi - +mv ../$PKGNAME-$VERSION.bff $startdir +cd $startdir rm -rf $objdir/$PKGDIR echo $0: done. diff --git a/openssh/contrib/gnome-ssh-askpass.c b/openssh/contrib/gnome-ssh-askpass.c deleted file mode 100644 index 27e5cca..0000000 --- a/openssh/contrib/gnome-ssh-askpass.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2000 Damien Miller. 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. - */ - -/* - * Compile with: - * - * cc `gnome-config --cflags gnome gnomeui` \ - * gnome-ssh-askpass.c -o gnome-ssh-askpass \ - * `gnome-config --libs gnome gnomeui` - * - */ - -#include -#include -#include -#include -#include -#include - -void -report_failed_grab (void) -{ - GtkWidget *err; - - err = gnome_message_box_new("Could not grab keyboard or mouse.\n" - "A malicious client may be eavesdropping on your session.", - GNOME_MESSAGE_BOX_ERROR, "EXIT", NULL); - gtk_window_set_position(GTK_WINDOW(err), GTK_WIN_POS_CENTER); - gtk_object_set(GTK_OBJECT(err), "type", GTK_WINDOW_POPUP, NULL); - - gnome_dialog_run_and_close(GNOME_DIALOG(err)); -} - -void -passphrase_dialog(char *message) -{ - char *passphrase; - char **messages; - int result, i; - - GtkWidget *dialog, *entry, *label; - - dialog = gnome_dialog_new("OpenSSH", GNOME_STOCK_BUTTON_OK, - GNOME_STOCK_BUTTON_CANCEL, NULL); - - messages = g_strsplit(message, "\\n", 0); - if (messages) - for(i = 0; messages[i]; i++) { - label = gtk_label_new(messages[i]); - gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), - label, FALSE, FALSE, 0); - } - - entry = gtk_entry_new(); - gtk_box_pack_start(GTK_BOX(GNOME_DIALOG(dialog)->vbox), entry, FALSE, - FALSE, 0); - gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE); - gtk_widget_grab_focus(entry); - - /* Center window and prepare for grab */ - gtk_object_set(GTK_OBJECT(dialog), "type", GTK_WINDOW_POPUP, NULL); - gnome_dialog_set_default(GNOME_DIALOG(dialog), 0); - gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_CENTER); - gtk_window_set_policy(GTK_WINDOW(dialog), FALSE, FALSE, TRUE); - gnome_dialog_close_hides(GNOME_DIALOG(dialog), TRUE); - gtk_container_set_border_width(GTK_CONTAINER(GNOME_DIALOG(dialog)->vbox), - GNOME_PAD); - gtk_widget_show_all(dialog); - - /* Grab focus */ - XGrabServer(GDK_DISPLAY()); - if (gdk_pointer_grab(dialog->window, TRUE, 0, NULL, NULL, - GDK_CURRENT_TIME)) - goto nograb; - if (gdk_keyboard_grab(dialog->window, FALSE, GDK_CURRENT_TIME)) - goto nograbkb; - - /* Make close dialog */ - gnome_dialog_editable_enters(GNOME_DIALOG(dialog), GTK_EDITABLE(entry)); - - /* Run dialog */ - result = gnome_dialog_run(GNOME_DIALOG(dialog)); - - /* Ungrab */ - XUngrabServer(GDK_DISPLAY()); - gdk_pointer_ungrab(GDK_CURRENT_TIME); - gdk_keyboard_ungrab(GDK_CURRENT_TIME); - gdk_flush(); - - /* Report passphrase if user selected OK */ - passphrase = gtk_entry_get_text(GTK_ENTRY(entry)); - if (result == 0) - puts(passphrase); - - /* Zero passphrase in memory */ - memset(passphrase, '\0', strlen(passphrase)); - gtk_entry_set_text(GTK_ENTRY(entry), passphrase); - - gnome_dialog_close(GNOME_DIALOG(dialog)); - return; - - /* At least one grab failed - ungrab what we got, and report - the failure to the user. Note that XGrabServer() cannot - fail. */ - nograbkb: - gdk_pointer_ungrab(GDK_CURRENT_TIME); - nograb: - XUngrabServer(GDK_DISPLAY()); - gnome_dialog_close(GNOME_DIALOG(dialog)); - - report_failed_grab(); -} - -int -main(int argc, char **argv) -{ - char *message; - - gnome_init("GNOME ssh-askpass", "0.1", argc, argv); - - if (argc == 2) - message = argv[1]; - else - message = "Enter your OpenSSH passphrase:"; - - setvbuf(stdout, 0, _IONBF, 0); - passphrase_dialog(message); - return 0; -} diff --git a/openssh/defines.h b/openssh/defines.h index 3f5b28a..69d8105 100644 --- a/openssh/defines.h +++ b/openssh/defines.h @@ -102,7 +102,7 @@ SCO Open Server 3 has INADDR_LOOPBACK defined in rpc/rpc.h but including rpc/rpc.h breaks Solaris 6 */ #ifndef INADDR_LOOPBACK -#define INADDR_LOOPBACK ((ulong)0x7f000001) +#define INADDR_LOOPBACK ((u_long)0x7f000001) #endif /* Types */ @@ -124,7 +124,7 @@ typedef char int8_t; # if (SIZEOF_SHORT_INT == 2) typedef short int int16_t; # else -# ifdef _CRAY +# ifdef _UNICOS # if (SIZEOF_SHORT_INT == 4) typedef short int16_t; # else @@ -132,16 +132,16 @@ typedef long int16_t; # endif # else # error "16 bit int type not found." -# endif /* _CRAY */ +# endif /* _UNICOS */ # endif # if (SIZEOF_INT == 4) typedef int int32_t; # else -# ifdef _CRAY +# ifdef _UNICOS typedef long int32_t; # else # error "32 bit int type not found." -# endif /* _CRAY */ +# endif /* _UNICOS */ # endif #endif @@ -161,7 +161,7 @@ typedef unsigned char u_int8_t; # if (SIZEOF_SHORT_INT == 2) typedef unsigned short int u_int16_t; # else -# ifdef _CRAY +# ifdef _UNICOS # if (SIZEOF_SHORT_INT == 4) typedef unsigned short u_int16_t; # else @@ -174,7 +174,7 @@ typedef unsigned long u_int16_t; # if (SIZEOF_INT == 4) typedef unsigned int u_int32_t; # else -# ifdef _CRAY +# ifdef _UNICOS typedef unsigned long u_int32_t; # else # error "32 bit int type not found." @@ -216,6 +216,10 @@ typedef unsigned char u_char; # define HAVE_U_CHAR #endif /* HAVE_U_CHAR */ +#ifndef SIZE_T_MAX +#define SIZE_T_MAX ULONG_MAX +#endif /* SIZE_T_MAX */ + #ifndef HAVE_SIZE_T typedef unsigned int size_t; # define HAVE_SIZE_T diff --git a/openssh/includes.h b/openssh/includes.h index e20d7a5..d7b875c 100644 --- a/openssh/includes.h +++ b/openssh/includes.h @@ -115,6 +115,9 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } #ifdef HAVE_SYS_UN_H # include /* For sockaddr_un */ #endif +#ifdef HAVE_STDINT_H +# include +#endif #ifdef HAVE_SYS_BITYPES_H # include /* For u_intXX_t */ #endif @@ -146,6 +149,14 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } # include #endif +#ifdef HAVE_IA_H +# include +#endif + +#ifdef HAVE_TMPDIR_H +# include +#endif + #include /* For OPENSSL_VERSION_NUMBER */ #include "defines.h" diff --git a/openssh/kex.h b/openssh/kex.h index 904dea8..98e13d9 100644 --- a/openssh/kex.h +++ b/openssh/kex.h @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.h,v 1.31 2002/05/16 22:02:50 markus Exp $ */ +/* $OpenBSD: kex.h,v 1.32 2002/09/09 14:54:14 markus Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -102,7 +102,7 @@ struct KexOptions { struct Kex { u_char *session_id; - int session_id_len; + u_int session_id_len; Newkeys *newkeys[MODE_MAX]; int we_need; int server; diff --git a/openssh/key.c b/openssh/key.c index 7f3fe4a..6701faa 100644 --- a/openssh/key.c +++ b/openssh/key.c @@ -32,7 +32,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: key.c,v 1.45 2002/06/23 03:26:19 deraadt Exp $"); +RCSID("$OpenBSD: key.c,v 1.49 2002/09/09 14:54:14 markus Exp $"); #include @@ -171,7 +171,7 @@ key_equal(Key *a, Key *b) return 0; } -static u_char* +static u_char * key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length) { const EVP_MD *md = NULL; @@ -227,8 +227,8 @@ key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length) return retval; } -static char* -key_fingerprint_hex(u_char* dgst_raw, u_int dgst_raw_len) +static char * +key_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len) { char *retval; int i; @@ -244,8 +244,8 @@ key_fingerprint_hex(u_char* dgst_raw, u_int dgst_raw_len) return retval; } -static char* -key_fingerprint_bubblebabble(u_char* dgst_raw, u_int dgst_raw_len) +static char * +key_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len) { char vowels[] = { 'a', 'e', 'i', 'o', 'u', 'y' }; char consonants[] = { 'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm', @@ -291,7 +291,7 @@ key_fingerprint_bubblebabble(u_char* dgst_raw, u_int dgst_raw_len) return retval; } -char* +char * key_fingerprint(Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) { char *retval = NULL; @@ -494,7 +494,8 @@ key_write(Key *key, FILE *f) { int n, success = 0; u_int len, bits = 0; - u_char *blob, *uu; + u_char *blob; + char *uu; if (key->type == KEY_RSA1 && key->rsa != NULL) { /* size of modulus 'n' */ @@ -731,7 +732,6 @@ key_to_blob(Key *key, u_char **blobp, u_int *lenp) { Buffer b; int len; - u_char *buf; if (key == NULL) { error("key_to_blob: key == NULL"); @@ -757,14 +757,14 @@ key_to_blob(Key *key, u_char **blobp, u_int *lenp) return 0; } len = buffer_len(&b); - buf = xmalloc(len); - memcpy(buf, buffer_ptr(&b), len); - memset(buffer_ptr(&b), 0, len); - buffer_free(&b); if (lenp != NULL) *lenp = len; - if (blobp != NULL) - *blobp = buf; + if (blobp != NULL) { + *blobp = xmalloc(len); + memcpy(*blobp, buffer_ptr(&b), len); + } + memset(buffer_ptr(&b), 0, len); + buffer_free(&b); return len; } diff --git a/openssh/log.c b/openssh/log.c index 860fa5e..d27dbaa 100644 --- a/openssh/log.c +++ b/openssh/log.c @@ -34,7 +34,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: log.c,v 1.22 2002/02/22 12:20:34 markus Exp $"); +RCSID("$OpenBSD: log.c,v 1.24 2002/07/19 15:43:33 markus Exp $"); #include "log.h" #include "xmalloc.h" @@ -92,6 +92,7 @@ SyslogFacility log_facility_number(char *name) { int i; + if (name != NULL) for (i = 0; log_facilities[i].name; i++) if (strcasecmp(log_facilities[i].name, name) == 0) @@ -103,6 +104,7 @@ LogLevel log_level_number(char *name) { int i; + if (name != NULL) for (i = 0; log_levels[i].name; i++) if (strcasecmp(log_levels[i].name, name) == 0) @@ -116,6 +118,7 @@ void error(const char *fmt,...) { va_list args; + va_start(args, fmt); do_log(SYSLOG_LEVEL_ERROR, fmt, args); va_end(args); @@ -127,6 +130,7 @@ void log(const char *fmt,...) { va_list args; + va_start(args, fmt); do_log(SYSLOG_LEVEL_INFO, fmt, args); va_end(args); @@ -138,6 +142,7 @@ void verbose(const char *fmt,...) { va_list args; + va_start(args, fmt); do_log(SYSLOG_LEVEL_VERBOSE, fmt, args); va_end(args); @@ -149,6 +154,7 @@ void debug(const char *fmt,...) { va_list args; + va_start(args, fmt); do_log(SYSLOG_LEVEL_DEBUG1, fmt, args); va_end(args); @@ -158,6 +164,7 @@ void debug2(const char *fmt,...) { va_list args; + va_start(args, fmt); do_log(SYSLOG_LEVEL_DEBUG2, fmt, args); va_end(args); @@ -167,6 +174,7 @@ void debug3(const char *fmt,...) { va_list args; + va_start(args, fmt); do_log(SYSLOG_LEVEL_DEBUG3, fmt, args); va_end(args); @@ -215,6 +223,18 @@ fatal_remove_cleanup(void (*proc) (void *context), void *context) (u_long) proc, (u_long) context); } +/* Remove all cleanups, to be called after fork() */ +void +fatal_remove_all_cleanups(void) +{ + struct fatal_cleanup *cu, *next_cu; + + for (cu = fatal_cleanups; cu; cu = next_cu) { + next_cu = cu->next; + xfree(cu); + } +} + /* Cleanup and exit */ void fatal_cleanup(void) diff --git a/openssh/monitor.c b/openssh/monitor.c index 38ee51b..bf5f0e6 100644 --- a/openssh/monitor.c +++ b/openssh/monitor.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor.c,v 1.18 2002/06/26 13:20:57 deraadt Exp $"); +RCSID("$OpenBSD: monitor.c,v 1.29 2002/09/26 11:38:43 markus Exp $"); #include @@ -139,6 +139,13 @@ int mm_answer_gss_display_status(int, Buffer *); int mm_answer_gsi_gridmap(int, Buffer *); #endif +#ifdef KRB4 +int mm_answer_krb4(int, Buffer *); +#endif +#ifdef KRB5 +int mm_answer_krb5(int, Buffer *); +#endif + static Authctxt *authctxt; static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ @@ -146,8 +153,8 @@ static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ static u_char *key_blob = NULL; static u_int key_bloblen = 0; static int key_blobtype = MM_NOKEY; -static u_char *hostbased_cuser = NULL; -static u_char *hostbased_chost = NULL; +static char *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; @@ -244,6 +251,12 @@ struct mon_table mon_dispatch_proto15[] = { #endif #ifdef USE_PAM {MONITOR_REQ_PAM_START, MON_ISAUTH, 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} }; @@ -527,7 +540,7 @@ mm_answer_sign(int socket, Buffer *m) p = buffer_get_string(m, &datlen); if (datlen != 20) - fatal("%s: data length incorrect: %d", __func__, datlen); + fatal("%s: data length incorrect: %u", __func__, datlen); /* save session id, it will be passed on the first call */ if (session_id2_len == 0) { @@ -541,7 +554,7 @@ mm_answer_sign(int socket, Buffer *m) if (key_sign(key, &signature, &siglen, p, datlen) < 0) fatal("%s: key_sign failed", __func__); - debug3("%s: signature %p(%d)", __func__, signature, siglen); + debug3("%s: signature %p(%u)", __func__, signature, siglen); buffer_clear(m); buffer_put_string(m, signature, siglen); @@ -629,7 +642,7 @@ int mm_answer_auth2_read_banner(int socket, Buffer *m) mm_request_send(socket, MONITOR_ANS_AUTH2_READ_BANNER, m); if (banner != NULL) - free(banner); + xfree(banner); return (0); } @@ -657,7 +670,8 @@ mm_answer_authpassword(int socket, Buffer *m) { static int call_count; char *passwd; - int authenticated, plen; + int authenticated; + u_int plen; passwd = buffer_get_string(m, &plen); /* Only authenticate if the context is valid */ @@ -820,7 +834,8 @@ int mm_answer_keyallowed(int socket, Buffer *m) { Key *key; - u_char *cuser, *chost, *blob; + char *cuser, *chost; + u_char *blob; u_int bloblen; enum mm_keytype type = 0; int allowed = 0; @@ -896,7 +911,7 @@ static int monitor_valid_userblob(u_char *data, u_int datalen) { Buffer b; - u_char *p; + char *p; u_int len; int fail = 0; @@ -949,11 +964,11 @@ monitor_valid_userblob(u_char *data, u_int datalen) } static int -monitor_valid_hostbasedblob(u_char *data, u_int datalen, u_char *cuser, - u_char *chost) +monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, + char *chost) { Buffer b; - u_char *p; + char *p; u_int len; int fail = 0; @@ -1071,8 +1086,8 @@ mm_record_login(Session *s, struct passwd *pw) * the address be 0.0.0.0. */ memset(&from, 0, sizeof(from)); + fromlen = sizeof(from); if (packet_connection_is_on_socket()) { - fromlen = sizeof(from); if (getpeername(packet_get_connection_in(), (struct sockaddr *) & from, &fromlen) < 0) { debug("getpeername: %.100s", strerror(errno)); @@ -1082,7 +1097,7 @@ 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, pw->pw_name, pw->pw_uid, get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping), - (struct sockaddr *)&from); + (struct sockaddr *)&from, fromlen); } static void @@ -1346,6 +1361,89 @@ mm_answer_rsa_response(int socket, Buffer *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) { @@ -1523,10 +1621,10 @@ mm_get_keystate(struct monitor *pmonitor) void * mm_zalloc(struct mm_master *mm, u_int ncount, u_int size) { - int len = size * ncount; + size_t len = size * ncount; void *address; - if (len <= 0) + if (len == 0 || ncount > SIZE_T_MAX / size) fatal("%s: mm_zalloc(%u, %u)", __func__, ncount, size); address = mm_malloc(mm, len); diff --git a/openssh/monitor.h b/openssh/monitor.h index 83e4986..80261a5 100644 --- a/openssh/monitor.h +++ b/openssh/monitor.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.h,v 1.6 2002/06/11 05:46:20 mpech Exp $ */ +/* $OpenBSD: monitor.h,v 1.8 2002/09/26 11:38:43 markus Exp $ */ /* * Copyright 2002 Niels Provos @@ -57,6 +57,8 @@ enum monitor_reqtype { 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 }; diff --git a/openssh/monitor_fdpass.c b/openssh/monitor_fdpass.c index 0d7628f..641ce72 100644 --- a/openssh/monitor_fdpass.c +++ b/openssh/monitor_fdpass.c @@ -24,7 +24,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor_fdpass.c,v 1.3 2002/06/04 23:05:49 markus Exp $"); +RCSID("$OpenBSD: monitor_fdpass.c,v 1.4 2002/06/26 14:50:04 deraadt Exp $"); #include @@ -38,7 +38,7 @@ mm_send_fd(int socket, int fd) struct msghdr msg; struct iovec vec; char ch = '\0'; - int n; + ssize_t n; #ifndef HAVE_ACCRIGHTS_IN_MSGHDR char tmp[CMSG_SPACE(sizeof(int))]; struct cmsghdr *cmsg; @@ -67,8 +67,8 @@ mm_send_fd(int socket, int fd) fatal("%s: sendmsg(%d): %s", __func__, fd, strerror(errno)); if (n != 1) - fatal("%s: sendmsg: expected sent 1 got %d", - __func__, n); + fatal("%s: sendmsg: expected sent 1 got %ld", + __func__, (long)n); #else fatal("%s: UsePrivilegeSeparation=yes not supported", __func__); @@ -81,8 +81,9 @@ 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, n; + int fd; #ifndef HAVE_ACCRIGHTS_IN_MSGHDR char tmp[CMSG_SPACE(sizeof(int))]; struct cmsghdr *cmsg; @@ -104,8 +105,8 @@ mm_receive_fd(int socket) if ((n = recvmsg(socket, &msg, 0)) == -1) fatal("%s: recvmsg: %s", __func__, strerror(errno)); if (n != 1) - fatal("%s: recvmsg: expected received 1 got %d", - __func__, n); + fatal("%s: recvmsg: expected received 1 got %ld", + __func__, (long)n); #ifdef HAVE_ACCRIGHTS_IN_MSGHDR if (msg.msg_accrightslen != sizeof(fd)) diff --git a/openssh/monitor_mm.c b/openssh/monitor_mm.c index c363036..b4a6e40 100644 --- a/openssh/monitor_mm.c +++ b/openssh/monitor_mm.c @@ -24,12 +24,13 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor_mm.c,v 1.6 2002/06/04 23:05:49 markus Exp $"); +RCSID("$OpenBSD: monitor_mm.c,v 1.8 2002/08/02 14:43:15 millert Exp $"); #ifdef HAVE_SYS_MMAN_H #include #endif +#include "openbsd-compat/xmmap.h" #include "ssh.h" #include "xmalloc.h" #include "log.h" @@ -38,7 +39,14 @@ RCSID("$OpenBSD: monitor_mm.c,v 1.6 2002/06/04 23:05:49 markus Exp $"); static int mm_compare(struct mm_share *a, struct mm_share *b) { - return ((char *)a->address - (char *)b->address); + 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) @@ -84,15 +92,9 @@ mm_create(struct mm_master *mmalloc, size_t size) */ mm->mmalloc = mmalloc; -#ifdef HAVE_MMAP_ANON_SHARED - address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_ANON|MAP_SHARED, - -1, 0); + address = xmmap(size); if (address == MAP_FAILED) fatal("mmap(%lu): %s", (u_long)size, strerror(errno)); -#else - fatal("%s: UsePrivilegeSeparation=yes and Compression=yes not supported", - __func__); -#endif mm->address = address; mm->size = size; @@ -130,7 +132,7 @@ mm_destroy(struct mm_master *mm) mm_freelist(mm->mmalloc, &mm->rb_free); mm_freelist(mm->mmalloc, &mm->rb_allocated); -#ifdef HAVE_MMAP_ANON_SHARED +#ifdef HAVE_MMAP if (munmap(mm->address, mm->size) == -1) fatal("munmap(%p, %lu): %s", mm->address, (u_long)mm->size, strerror(errno)); @@ -165,8 +167,10 @@ mm_malloc(struct mm_master *mm, size_t size) 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; + size = ((size + (MM_MINSIZE - 1)) / MM_MINSIZE) * MM_MINSIZE; RB_FOREACH(mms, mmtree, &mm->rb_free) { if (mms->size >= size) diff --git a/openssh/monitor_mm.h b/openssh/monitor_mm.h index c0a66d5..a1323b9 100644 --- a/openssh/monitor_mm.h +++ b/openssh/monitor_mm.h @@ -27,7 +27,7 @@ #ifndef _MM_H_ #define _MM_H_ -#include "openbsd-compat/tree.h" +#include "openbsd-compat/sys-tree.h" struct mm_share { RB_ENTRY(mm_share) next; diff --git a/openssh/monitor_wrap.c b/openssh/monitor_wrap.c index 099a627..0caaa93 100644 --- a/openssh/monitor_wrap.c +++ b/openssh/monitor_wrap.c @@ -25,7 +25,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: monitor_wrap.c,v 1.11 2002/06/19 18:01:00 markus Exp $"); +RCSID("$OpenBSD: monitor_wrap.c,v 1.19 2002/09/26 11:38:43 markus Exp $"); #include #include @@ -66,8 +66,8 @@ extern Buffer input, output; void mm_request_send(int socket, enum monitor_reqtype type, Buffer *m) { - u_char buf[5]; u_int mlen = buffer_len(m); + u_char buf[5]; debug3("%s entering: type %d", __func__, type); @@ -83,8 +83,8 @@ void mm_request_receive(int socket, Buffer *m) { u_char buf[4]; - ssize_t res; u_int msg_len; + ssize_t res; debug3("%s entering", __func__); @@ -211,7 +211,7 @@ mm_getpwnamallow(const char *login) return (pw); } -char* mm_auth2_read_banner(void) +char *mm_auth2_read_banner(void) { Buffer m; char *banner; @@ -415,7 +415,7 @@ mm_newkeys_from_blob(u_char *blob, int blen) enc->key = buffer_get_string(&b, &enc->key_len); enc->iv = buffer_get_string(&b, &len); if (len != enc->block_size) - fatal("%s: bad ivlen: expected %d != %d", __func__, + fatal("%s: bad ivlen: expected %u != %u", __func__, enc->block_size, len); if (enc->name == NULL || cipher_by_name(enc->name) != enc->cipher) @@ -429,7 +429,7 @@ mm_newkeys_from_blob(u_char *blob, int blen) mac->enabled = buffer_get_int(&b); mac->key = buffer_get_string(&b, &len); if (len > mac->key_len) - fatal("%s: bad mac key length: %d > %d", __func__, len, + fatal("%s: bad mac key length: %u > %d", __func__, len, mac->key_len); mac->key_len = len; @@ -440,7 +440,7 @@ mm_newkeys_from_blob(u_char *blob, int blen) len = buffer_len(&b); if (len != 0) - error("newkeys_from_blob: remaining bytes in blob %d", len); + error("newkeys_from_blob: remaining bytes in blob %u", len); buffer_free(&b); return (newkey); } @@ -450,7 +450,6 @@ mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp) { Buffer b; int len; - u_char *buf; Enc *enc; Mac *mac; Comp *comp; @@ -488,14 +487,14 @@ mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp) buffer_put_cstring(&b, comp->name); len = buffer_len(&b); - buf = xmalloc(len); - memcpy(buf, buffer_ptr(&b), len); - memset(buffer_ptr(&b), 0, len); - buffer_free(&b); if (lenp != NULL) *lenp = len; - if (blobp != NULL) - *blobp = buf; + if (blobp != NULL) { + *blobp = xmalloc(len); + memcpy(*blobp, buffer_ptr(&b), len); + } + memset(buffer_ptr(&b), 0, len); + buffer_free(&b); return len; } @@ -604,7 +603,7 @@ int mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) { Buffer m; - u_char *p; + char *p; int success = 0; buffer_init(&m); @@ -709,7 +708,7 @@ mm_chall_setup(char **name, char **infotxt, u_int *numprompts, *name = xstrdup(""); *infotxt = xstrdup(""); *numprompts = 1; - *prompts = xmalloc(*numprompts * sizeof(char*)); + *prompts = xmalloc(*numprompts * sizeof(char *)); *echo_on = xmalloc(*numprompts * sizeof(u_int)); (*echo_on)[0] = 0; } @@ -1141,3 +1140,74 @@ int mm_gsi_gridmap(char *subject_name, char **lname) } #endif /* GSI */ + +#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 diff --git a/openssh/monitor_wrap.h b/openssh/monitor_wrap.h index 04491b4..09766e7 100644 --- a/openssh/monitor_wrap.h +++ b/openssh/monitor_wrap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.h,v 1.5 2002/05/12 23:53:45 djm Exp $ */ +/* $OpenBSD: monitor_wrap.h,v 1.8 2002/09/26 11:38:43 markus Exp $ */ /* * Copyright 2002 Niels Provos @@ -44,7 +44,7 @@ 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); +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 *); @@ -105,6 +105,16 @@ int mm_bsdauth_respond(void *, u_int, char **); 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); diff --git a/openssh/msg.c b/openssh/msg.c index 7275c84..107a376 100644 --- a/openssh/msg.c +++ b/openssh/msg.c @@ -22,7 +22,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: msg.c,v 1.3 2002/06/24 15:49:22 itojun Exp $"); +RCSID("$OpenBSD: msg.c,v 1.4 2002/07/01 16:15:25 deraadt Exp $"); #include "buffer.h" #include "getput.h" @@ -31,43 +31,43 @@ RCSID("$OpenBSD: msg.c,v 1.3 2002/06/24 15:49:22 itojun Exp $"); #include "msg.h" void -msg_send(int fd, u_char type, Buffer *m) +ssh_msg_send(int fd, u_char type, Buffer *m) { u_char buf[5]; u_int mlen = buffer_len(m); - debug3("msg_send: type %u", (unsigned int)type & 0xff); + debug3("ssh_msg_send: type %u", (unsigned int)type & 0xff); PUT_32BIT(buf, mlen + 1); buf[4] = type; /* 1st byte of payload is mesg-type */ if (atomicio(write, fd, buf, sizeof(buf)) != sizeof(buf)) - fatal("msg_send: write"); + fatal("ssh_msg_send: write"); if (atomicio(write, fd, buffer_ptr(m), mlen) != mlen) - fatal("msg_send: write"); + fatal("ssh_msg_send: write"); } int -msg_recv(int fd, Buffer *m) +ssh_msg_recv(int fd, Buffer *m) { u_char buf[4]; ssize_t res; u_int msg_len; - debug3("msg_recv entering"); + debug3("ssh_msg_recv entering"); res = atomicio(read, fd, buf, sizeof(buf)); if (res != sizeof(buf)) { if (res == 0) return -1; - fatal("msg_recv: read: header %ld", (long)res); + fatal("ssh_msg_recv: read: header %ld", (long)res); } msg_len = GET_32BIT(buf); if (msg_len > 256 * 1024) - fatal("msg_recv: read: bad msg_len %d", msg_len); + fatal("ssh_msg_recv: read: bad msg_len %u", msg_len); buffer_clear(m); buffer_append_space(m, msg_len); res = atomicio(read, fd, buffer_ptr(m), msg_len); if (res != msg_len) - fatal("msg_recv: read: %ld != msg_len", (long)res); + fatal("ssh_msg_recv: read: %ld != msg_len", (long)res); return 0; } diff --git a/openssh/msg.h b/openssh/msg.h index 13fa95b..8980e25 100644 --- a/openssh/msg.h +++ b/openssh/msg.h @@ -25,7 +25,7 @@ #ifndef SSH_MSG_H #define SSH_MSG_H -void msg_send(int, u_char, Buffer *); -int msg_recv(int, Buffer *); +void ssh_msg_send(int, u_char, Buffer *); +int ssh_msg_recv(int, Buffer *); #endif diff --git a/openssh/openbsd-compat/fake-queue.h b/openssh/openbsd-compat/fake-queue.h deleted file mode 100644 index 269af41..0000000 --- a/openssh/openbsd-compat/fake-queue.h +++ /dev/null @@ -1,490 +0,0 @@ -/* $OpenBSD: queue.h,v 1.16 2000/09/07 19:47:59 art Exp $ */ -/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */ - -/* - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)queue.h 8.5 (Berkeley) 8/20/94 - */ - -#ifndef _SYS_QUEUE_H_ -#define _SYS_QUEUE_H_ - -/* - * This file defines five types of data structures: singly-linked lists, - * lists, simple queues, tail queues, and circular queues. - * - * - * A singly-linked list is headed by a single forward pointer. The elements - * are singly linked for minimum space and pointer manipulation overhead at - * the expense of O(n) removal for arbitrary elements. New elements can be - * added to the list after an existing element or at the head of the list. - * Elements being removed from the head of the list should use the explicit - * macro for this purpose for optimum efficiency. A singly-linked list may - * only be traversed in the forward direction. Singly-linked lists are ideal - * for applications with large datasets and few or no removals or for - * implementing a LIFO queue. - * - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before - * or after an existing element or at the head of the list. A list - * may only be traversed in the forward direction. - * - * A simple queue is headed by a pair of pointers, one the head of the - * list and the other to the tail of the list. The elements are singly - * linked to save space, so elements can only be removed from the - * head of the list. New elements can be added to the list before or after - * an existing element, at the head of the list, or at the end of the - * list. A simple queue may only be traversed in the forward direction. - * - * A tail queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or - * after an existing element, at the head of the list, or at the end of - * the list. A tail queue may be traversed in either direction. - * - * A circle queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or after - * an existing element, at the head of the list, or at the end of the list. - * A circle queue may be traversed in either direction, but has a more - * complex end of list detection. - * - * For details on the use of these macros, see the queue(3) manual page. - */ - -/* - * Singly-linked List definitions. - */ -#define SLIST_HEAD(name, type) \ -struct name { \ - struct type *slh_first; /* first element */ \ -} - -#define SLIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define SLIST_ENTRY(type) \ -struct { \ - struct type *sle_next; /* next element */ \ -} - -/* - * Singly-linked List access methods. - */ -#define SLIST_FIRST(head) ((head)->slh_first) -#define SLIST_END(head) NULL -#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) -#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) - -#define SLIST_FOREACH(var, head, field) \ - for((var) = SLIST_FIRST(head); \ - (var) != SLIST_END(head); \ - (var) = SLIST_NEXT(var, field)) - -/* - * Singly-linked List functions. - */ -#define SLIST_INIT(head) { \ - SLIST_FIRST(head) = SLIST_END(head); \ -} - -#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ - (elm)->field.sle_next = (slistelm)->field.sle_next; \ - (slistelm)->field.sle_next = (elm); \ -} while (0) - -#define SLIST_INSERT_HEAD(head, elm, field) do { \ - (elm)->field.sle_next = (head)->slh_first; \ - (head)->slh_first = (elm); \ -} while (0) - -#define SLIST_REMOVE_HEAD(head, field) do { \ - (head)->slh_first = (head)->slh_first->field.sle_next; \ -} while (0) - -/* - * List definitions. - */ -#define LIST_HEAD(name, type) \ -struct name { \ - struct type *lh_first; /* first element */ \ -} - -#define LIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define LIST_ENTRY(type) \ -struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ -} - -/* - * List access methods - */ -#define LIST_FIRST(head) ((head)->lh_first) -#define LIST_END(head) NULL -#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head)) -#define LIST_NEXT(elm, field) ((elm)->field.le_next) - -#define LIST_FOREACH(var, head, field) \ - for((var) = LIST_FIRST(head); \ - (var)!= LIST_END(head); \ - (var) = LIST_NEXT(var, field)) - -/* - * List functions. - */ -#define LIST_INIT(head) do { \ - LIST_FIRST(head) = LIST_END(head); \ -} while (0) - -#define LIST_INSERT_AFTER(listelm, elm, field) do { \ - if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ - (listelm)->field.le_next->field.le_prev = \ - &(elm)->field.le_next; \ - (listelm)->field.le_next = (elm); \ - (elm)->field.le_prev = &(listelm)->field.le_next; \ -} while (0) - -#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.le_prev = (listelm)->field.le_prev; \ - (elm)->field.le_next = (listelm); \ - *(listelm)->field.le_prev = (elm); \ - (listelm)->field.le_prev = &(elm)->field.le_next; \ -} while (0) - -#define LIST_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.le_next = (head)->lh_first) != NULL) \ - (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ - (head)->lh_first = (elm); \ - (elm)->field.le_prev = &(head)->lh_first; \ -} while (0) - -#define LIST_REMOVE(elm, field) do { \ - if ((elm)->field.le_next != NULL) \ - (elm)->field.le_next->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = (elm)->field.le_next; \ -} while (0) - -#define LIST_REPLACE(elm, elm2, field) do { \ - if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \ - (elm2)->field.le_next->field.le_prev = \ - &(elm2)->field.le_next; \ - (elm2)->field.le_prev = (elm)->field.le_prev; \ - *(elm2)->field.le_prev = (elm2); \ -} while (0) - -/* - * Simple queue definitions. - */ -#define SIMPLEQ_HEAD(name, type) \ -struct name { \ - struct type *sqh_first; /* first element */ \ - struct type **sqh_last; /* addr of last next element */ \ -} - -#define SIMPLEQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).sqh_first } - -#define SIMPLEQ_ENTRY(type) \ -struct { \ - struct type *sqe_next; /* next element */ \ -} - -/* - * Simple queue access methods. - */ -#define SIMPLEQ_FIRST(head) ((head)->sqh_first) -#define SIMPLEQ_END(head) NULL -#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head)) -#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) - -#define SIMPLEQ_FOREACH(var, head, field) \ - for((var) = SIMPLEQ_FIRST(head); \ - (var) != SIMPLEQ_END(head); \ - (var) = SIMPLEQ_NEXT(var, field)) - -/* - * Simple queue functions. - */ -#define SIMPLEQ_INIT(head) do { \ - (head)->sqh_first = NULL; \ - (head)->sqh_last = &(head)->sqh_first; \ -} while (0) - -#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ - (head)->sqh_last = &(elm)->field.sqe_next; \ - (head)->sqh_first = (elm); \ -} while (0) - -#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.sqe_next = NULL; \ - *(head)->sqh_last = (elm); \ - (head)->sqh_last = &(elm)->field.sqe_next; \ -} while (0) - -#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\ - (head)->sqh_last = &(elm)->field.sqe_next; \ - (listelm)->field.sqe_next = (elm); \ -} while (0) - -#define SIMPLEQ_REMOVE_HEAD(head, elm, field) do { \ - if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) \ - (head)->sqh_last = &(head)->sqh_first; \ -} while (0) - -/* - * Tail queue definitions. - */ -#define TAILQ_HEAD(name, type) \ -struct name { \ - struct type *tqh_first; /* first element */ \ - struct type **tqh_last; /* addr of last next element */ \ -} - -#define TAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first } - -#define TAILQ_ENTRY(type) \ -struct { \ - struct type *tqe_next; /* next element */ \ - struct type **tqe_prev; /* address of previous next element */ \ -} - -/* - * tail queue access methods - */ -#define TAILQ_FIRST(head) ((head)->tqh_first) -#define TAILQ_END(head) NULL -#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) -#define TAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) -/* XXX */ -#define TAILQ_PREV(elm, headname, field) \ - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) -#define TAILQ_EMPTY(head) \ - (TAILQ_FIRST(head) == TAILQ_END(head)) - -#define TAILQ_FOREACH(var, head, field) \ - for((var) = TAILQ_FIRST(head); \ - (var) != TAILQ_END(head); \ - (var) = TAILQ_NEXT(var, field)) - -#define TAILQ_FOREACH_REVERSE(var, head, field, headname) \ - for((var) = TAILQ_LAST(head, headname); \ - (var) != TAILQ_END(head); \ - (var) = TAILQ_PREV(var, headname, field)) - -/* - * Tail queue functions. - */ -#define TAILQ_INIT(head) do { \ - (head)->tqh_first = NULL; \ - (head)->tqh_last = &(head)->tqh_first; \ -} while (0) - -#define TAILQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ - (head)->tqh_first->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (head)->tqh_first = (elm); \ - (elm)->field.tqe_prev = &(head)->tqh_first; \ -} while (0) - -#define TAILQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.tqe_next = NULL; \ - (elm)->field.tqe_prev = (head)->tqh_last; \ - *(head)->tqh_last = (elm); \ - (head)->tqh_last = &(elm)->field.tqe_next; \ -} while (0) - -#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ - (elm)->field.tqe_next->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (listelm)->field.tqe_next = (elm); \ - (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ -} while (0) - -#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ - (elm)->field.tqe_next = (listelm); \ - *(listelm)->field.tqe_prev = (elm); \ - (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ -} while (0) - -#define TAILQ_REMOVE(head, elm, field) do { \ - if (((elm)->field.tqe_next) != NULL) \ - (elm)->field.tqe_next->field.tqe_prev = \ - (elm)->field.tqe_prev; \ - else \ - (head)->tqh_last = (elm)->field.tqe_prev; \ - *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ -} while (0) - -#define TAILQ_REPLACE(head, elm, elm2, field) do { \ - if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \ - (elm2)->field.tqe_next->field.tqe_prev = \ - &(elm2)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm2)->field.tqe_next; \ - (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \ - *(elm2)->field.tqe_prev = (elm2); \ -} while (0) - -/* - * Circular queue definitions. - */ -#define CIRCLEQ_HEAD(name, type) \ -struct name { \ - struct type *cqh_first; /* first element */ \ - struct type *cqh_last; /* last element */ \ -} - -#define CIRCLEQ_HEAD_INITIALIZER(head) \ - { CIRCLEQ_END(&head), CIRCLEQ_END(&head) } - -#define CIRCLEQ_ENTRY(type) \ -struct { \ - struct type *cqe_next; /* next element */ \ - struct type *cqe_prev; /* previous element */ \ -} - -/* - * Circular queue access methods - */ -#define CIRCLEQ_FIRST(head) ((head)->cqh_first) -#define CIRCLEQ_LAST(head) ((head)->cqh_last) -#define CIRCLEQ_END(head) ((void *)(head)) -#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) -#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) -#define CIRCLEQ_EMPTY(head) \ - (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head)) - -#define CIRCLEQ_FOREACH(var, head, field) \ - for((var) = CIRCLEQ_FIRST(head); \ - (var) != CIRCLEQ_END(head); \ - (var) = CIRCLEQ_NEXT(var, field)) - -#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ - for((var) = CIRCLEQ_LAST(head); \ - (var) != CIRCLEQ_END(head); \ - (var) = CIRCLEQ_PREV(var, field)) - -/* - * Circular queue functions. - */ -#define CIRCLEQ_INIT(head) do { \ - (head)->cqh_first = CIRCLEQ_END(head); \ - (head)->cqh_last = CIRCLEQ_END(head); \ -} while (0) - -#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - (elm)->field.cqe_next = (listelm)->field.cqe_next; \ - (elm)->field.cqe_prev = (listelm); \ - if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \ - (head)->cqh_last = (elm); \ - else \ - (listelm)->field.cqe_next->field.cqe_prev = (elm); \ - (listelm)->field.cqe_next = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ - (elm)->field.cqe_next = (listelm); \ - (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ - if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \ - (head)->cqh_first = (elm); \ - else \ - (listelm)->field.cqe_prev->field.cqe_next = (elm); \ - (listelm)->field.cqe_prev = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ - (elm)->field.cqe_next = (head)->cqh_first; \ - (elm)->field.cqe_prev = CIRCLEQ_END(head); \ - if ((head)->cqh_last == CIRCLEQ_END(head)) \ - (head)->cqh_last = (elm); \ - else \ - (head)->cqh_first->field.cqe_prev = (elm); \ - (head)->cqh_first = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.cqe_next = CIRCLEQ_END(head); \ - (elm)->field.cqe_prev = (head)->cqh_last; \ - if ((head)->cqh_first == CIRCLEQ_END(head)) \ - (head)->cqh_first = (elm); \ - else \ - (head)->cqh_last->field.cqe_next = (elm); \ - (head)->cqh_last = (elm); \ -} while (0) - -#define CIRCLEQ_REMOVE(head, elm, field) do { \ - if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \ - (head)->cqh_last = (elm)->field.cqe_prev; \ - else \ - (elm)->field.cqe_next->field.cqe_prev = \ - (elm)->field.cqe_prev; \ - if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \ - (head)->cqh_first = (elm)->field.cqe_next; \ - else \ - (elm)->field.cqe_prev->field.cqe_next = \ - (elm)->field.cqe_next; \ -} while (0) - -#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \ - if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \ - CIRCLEQ_END(head)) \ - (head).cqh_last = (elm2); \ - else \ - (elm2)->field.cqe_next->field.cqe_prev = (elm2); \ - if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \ - CIRCLEQ_END(head)) \ - (head).cqh_first = (elm2); \ - else \ - (elm2)->field.cqe_prev->field.cqe_next = (elm2); \ -} while (0) - -#endif /* !_SYS_QUEUE_H_ */ diff --git a/openssh/openbsd-compat/getopt.c b/openssh/openbsd-compat/getopt.c index f4fbc9b..4a5cfe5 100644 --- a/openssh/openbsd-compat/getopt.c +++ b/openssh/openbsd-compat/getopt.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -#include "config.h" +#include "includes.h" #if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET) #if defined(LIBC_SCCS) && !defined(lint) diff --git a/openssh/openbsd-compat/port-aix.c b/openssh/openbsd-compat/port-aix.c index ca0a88e..4c96a31 100644 --- a/openssh/openbsd-compat/port-aix.c +++ b/openssh/openbsd-compat/port-aix.c @@ -1,3 +1,28 @@ +/* + * + * Copyright (c) 2001 Gert Doering. 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" #ifdef _AIX @@ -6,21 +31,21 @@ #include <../xmalloc.h> /* - * AIX has a "usrinfo" area where logname and - * other stuff is stored - a few applications - * actually use this and die if it's not set + * AIX has a "usrinfo" area where logname and other stuff is stored - + * a few applications actually use this and die if it's not set + * + * NOTE: TTY= should be set, but since no one uses it and it's hard to + * acquire due to privsep code. We will just drop support. */ void -aix_usrinfo(struct passwd *pw, char *tty, int ttyfd) +aix_usrinfo(struct passwd *pw) { u_int i; - char *cp=NULL; + char *cp; - if (ttyfd == -1) - tty[0] = '\0'; - cp = xmalloc(22 + strlen(tty) + 2 * strlen(pw->pw_name)); - i = sprintf(cp, "LOGNAME=%s%cNAME=%s%cTTY=%s%c%c", pw->pw_name, 0, - pw->pw_name, 0, tty, 0, 0); + cp = xmalloc(16 + 2 * strlen(pw->pw_name)); + i = sprintf(cp, "LOGNAME=%s%cNAME=%s%c", pw->pw_name, 0, + pw->pw_name, 0); if (usrinfo(SETUINFO, cp, i) == -1) fatal("Couldn't set usrinfo: %s", strerror(errno)); debug3("AIX/UsrInfo: set len %d", i); diff --git a/openssh/openbsd-compat/port-aix.h b/openssh/openbsd-compat/port-aix.h index e4d14f4..79570a2 100644 --- a/openssh/openbsd-compat/port-aix.h +++ b/openssh/openbsd-compat/port-aix.h @@ -1,5 +1,29 @@ -#ifdef _AIX - -void aix_usrinfo(struct passwd *pw, char *tty, int ttyfd); +/* + * + * Copyright (c) 2001 Gert Doering. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifdef _AIX +void aix_usrinfo(struct passwd *pw); #endif /* _AIX */ diff --git a/openssh/openbsd-compat/tree.h b/openssh/openbsd-compat/tree.h deleted file mode 100644 index 30b4a85..0000000 --- a/openssh/openbsd-compat/tree.h +++ /dev/null @@ -1,667 +0,0 @@ -/* - * Copyright 2002 Niels Provos - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _SYS_TREE_H_ -#define _SYS_TREE_H_ - -/* - * This file defines data structures for different types of trees: - * splay trees and red-black trees. - * - * A splay tree is a self-organizing data structure. Every operation - * on the tree causes a splay to happen. The splay moves the requested - * node to the root of the tree and partly rebalances it. - * - * This has the benefit that request locality causes faster lookups as - * the requested nodes move to the top of the tree. On the other hand, - * every lookup causes memory writes. - * - * The Balance Theorem bounds the total access time for m operations - * and n inserts on an initially empty tree as O((m + n)lg n). The - * amortized cost for a sequence of m accesses to a splay tree is O(lg n); - * - * A red-black tree is a binary search tree with the node color as an - * extra attribute. It fulfills a set of conditions: - * - every search path from the root to a leaf consists of the - * same number of black nodes, - * - each red node (except for the root) has a black parent, - * - each leaf node is black. - * - * Every operation on a red-black tree is bounded as O(lg n). - * The maximum height of a red-black tree is 2lg (n+1). - */ - -#define SPLAY_HEAD(name, type) \ -struct name { \ - struct type *sph_root; /* root of the tree */ \ -} - -#define SPLAY_INITIALIZER(root) \ - { NULL } - -#define SPLAY_INIT(root) do { \ - (root)->sph_root = NULL; \ -} while (0) - -#define SPLAY_ENTRY(type) \ -struct { \ - struct type *spe_left; /* left element */ \ - struct type *spe_right; /* right element */ \ -} - -#define SPLAY_LEFT(elm, field) (elm)->field.spe_left -#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right -#define SPLAY_ROOT(head) (head)->sph_root -#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL) - -/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */ -#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \ - SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \ - SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ - (head)->sph_root = tmp; \ -} while (0) - -#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \ - SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \ - SPLAY_LEFT(tmp, field) = (head)->sph_root; \ - (head)->sph_root = tmp; \ -} while (0) - -#define SPLAY_LINKLEFT(head, tmp, field) do { \ - SPLAY_LEFT(tmp, field) = (head)->sph_root; \ - tmp = (head)->sph_root; \ - (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ -} while (0) - -#define SPLAY_LINKRIGHT(head, tmp, field) do { \ - SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ - tmp = (head)->sph_root; \ - (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ -} while (0) - -#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \ - SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \ - SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\ - SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \ - SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \ -} while (0) - -/* Generates prototypes and inline functions */ - -#define SPLAY_PROTOTYPE(name, type, field, cmp) \ -void name##_SPLAY(struct name *, struct type *); \ -void name##_SPLAY_MINMAX(struct name *, int); \ - \ -static __inline void \ -name##_SPLAY_INSERT(struct name *head, struct type *elm) \ -{ \ - if (SPLAY_EMPTY(head)) { \ - SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \ - } else { \ - int __comp; \ - name##_SPLAY(head, elm); \ - __comp = (cmp)(elm, (head)->sph_root); \ - if(__comp < 0) { \ - SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\ - SPLAY_RIGHT(elm, field) = (head)->sph_root; \ - SPLAY_LEFT((head)->sph_root, field) = NULL; \ - } else if (__comp > 0) { \ - SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\ - SPLAY_LEFT(elm, field) = (head)->sph_root; \ - SPLAY_RIGHT((head)->sph_root, field) = NULL; \ - } else \ - return; \ - } \ - (head)->sph_root = (elm); \ -} \ - \ -static __inline void \ -name##_SPLAY_REMOVE(struct name *head, struct type *elm) \ -{ \ - struct type *__tmp; \ - if (SPLAY_EMPTY(head)) \ - return; \ - name##_SPLAY(head, elm); \ - if ((cmp)(elm, (head)->sph_root) == 0) { \ - if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \ - (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\ - } else { \ - __tmp = SPLAY_RIGHT((head)->sph_root, field); \ - (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\ - name##_SPLAY(head, elm); \ - SPLAY_RIGHT((head)->sph_root, field) = __tmp; \ - } \ - } \ -} \ - \ -/* Finds the node with the same key as elm */ \ -static __inline struct type * \ -name##_SPLAY_FIND(struct name *head, struct type *elm) \ -{ \ - if (SPLAY_EMPTY(head)) \ - return(NULL); \ - name##_SPLAY(head, elm); \ - if ((cmp)(elm, (head)->sph_root) == 0) \ - return (head->sph_root); \ - return (NULL); \ -} \ - \ -static __inline struct type * \ -name##_SPLAY_NEXT(struct name *head, struct type *elm) \ -{ \ - name##_SPLAY(head, elm); \ - if (SPLAY_RIGHT(elm, field) != NULL) { \ - elm = SPLAY_RIGHT(elm, field); \ - while (SPLAY_LEFT(elm, field) != NULL) { \ - elm = SPLAY_LEFT(elm, field); \ - } \ - } else \ - elm = NULL; \ - return (elm); \ -} \ - \ -static __inline struct type * \ -name##_SPLAY_MIN_MAX(struct name *head, int val) \ -{ \ - name##_SPLAY_MINMAX(head, val); \ - return (SPLAY_ROOT(head)); \ -} - -/* Main splay operation. - * Moves node close to the key of elm to top - */ -#define SPLAY_GENERATE(name, type, field, cmp) \ -void name##_SPLAY(struct name *head, struct type *elm) \ -{ \ - struct type __node, *__left, *__right, *__tmp; \ - int __comp; \ -\ - SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ - __left = __right = &__node; \ -\ - while ((__comp = (cmp)(elm, (head)->sph_root))) { \ - if (__comp < 0) { \ - __tmp = SPLAY_LEFT((head)->sph_root, field); \ - if (__tmp == NULL) \ - break; \ - if ((cmp)(elm, __tmp) < 0){ \ - SPLAY_ROTATE_RIGHT(head, __tmp, field); \ - if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ - break; \ - } \ - SPLAY_LINKLEFT(head, __right, field); \ - } else if (__comp > 0) { \ - __tmp = SPLAY_RIGHT((head)->sph_root, field); \ - if (__tmp == NULL) \ - break; \ - if ((cmp)(elm, __tmp) > 0){ \ - SPLAY_ROTATE_LEFT(head, __tmp, field); \ - if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ - break; \ - } \ - SPLAY_LINKRIGHT(head, __left, field); \ - } \ - } \ - SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ -} \ - \ -/* Splay with either the minimum or the maximum element \ - * Used to find minimum or maximum element in tree. \ - */ \ -void name##_SPLAY_MINMAX(struct name *head, int __comp) \ -{ \ - struct type __node, *__left, *__right, *__tmp; \ -\ - SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ - __left = __right = &__node; \ -\ - while (1) { \ - if (__comp < 0) { \ - __tmp = SPLAY_LEFT((head)->sph_root, field); \ - if (__tmp == NULL) \ - break; \ - if (__comp < 0){ \ - SPLAY_ROTATE_RIGHT(head, __tmp, field); \ - if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ - break; \ - } \ - SPLAY_LINKLEFT(head, __right, field); \ - } else if (__comp > 0) { \ - __tmp = SPLAY_RIGHT((head)->sph_root, field); \ - if (__tmp == NULL) \ - break; \ - if (__comp > 0) { \ - SPLAY_ROTATE_LEFT(head, __tmp, field); \ - if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ - break; \ - } \ - SPLAY_LINKRIGHT(head, __left, field); \ - } \ - } \ - SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ -} - -#define SPLAY_NEGINF -1 -#define SPLAY_INF 1 - -#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y) -#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y) -#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y) -#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y) -#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \ - : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF)) -#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \ - : name##_SPLAY_MIN_MAX(x, SPLAY_INF)) - -#define SPLAY_FOREACH(x, name, head) \ - for ((x) = SPLAY_MIN(name, head); \ - (x) != NULL; \ - (x) = SPLAY_NEXT(name, head, x)) - -/* Macros that define a red-back tree */ -#define RB_HEAD(name, type) \ -struct name { \ - struct type *rbh_root; /* root of the tree */ \ -} - -#define RB_INITIALIZER(root) \ - { NULL } - -#define RB_INIT(root) do { \ - (root)->rbh_root = NULL; \ -} while (0) - -#define RB_BLACK 0 -#define RB_RED 1 -#define RB_ENTRY(type) \ -struct { \ - struct type *rbe_left; /* left element */ \ - struct type *rbe_right; /* right element */ \ - struct type *rbe_parent; /* parent element */ \ - int rbe_color; /* node color */ \ -} - -#define RB_LEFT(elm, field) (elm)->field.rbe_left -#define RB_RIGHT(elm, field) (elm)->field.rbe_right -#define RB_PARENT(elm, field) (elm)->field.rbe_parent -#define RB_COLOR(elm, field) (elm)->field.rbe_color -#define RB_ROOT(head) (head)->rbh_root -#define RB_EMPTY(head) (RB_ROOT(head) == NULL) - -#define RB_SET(elm, parent, field) do { \ - RB_PARENT(elm, field) = parent; \ - RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ - RB_COLOR(elm, field) = RB_RED; \ -} while (0) - -#define RB_SET_BLACKRED(black, red, field) do { \ - RB_COLOR(black, field) = RB_BLACK; \ - RB_COLOR(red, field) = RB_RED; \ -} while (0) - -#ifndef RB_AUGMENT -#define RB_AUGMENT(x) -#endif - -#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ - (tmp) = RB_RIGHT(elm, field); \ - if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) { \ - RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \ - } \ - RB_AUGMENT(elm); \ - if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \ - if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ - RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ - else \ - RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ - RB_AUGMENT(RB_PARENT(elm, field)); \ - } else \ - (head)->rbh_root = (tmp); \ - RB_LEFT(tmp, field) = (elm); \ - RB_PARENT(elm, field) = (tmp); \ - RB_AUGMENT(tmp); \ -} while (0) - -#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ - (tmp) = RB_LEFT(elm, field); \ - if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) { \ - RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \ - } \ - RB_AUGMENT(elm); \ - if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \ - if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ - RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ - else \ - RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ - RB_AUGMENT(RB_PARENT(elm, field)); \ - } else \ - (head)->rbh_root = (tmp); \ - RB_RIGHT(tmp, field) = (elm); \ - RB_PARENT(elm, field) = (tmp); \ - RB_AUGMENT(tmp); \ -} while (0) - -/* Generates prototypes and inline functions */ -#define RB_PROTOTYPE(name, type, field, cmp) \ -void name##_RB_INSERT_COLOR(struct name *, struct type *); \ -void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ -void name##_RB_REMOVE(struct name *, struct type *); \ -struct type *name##_RB_INSERT(struct name *, struct type *); \ -struct type *name##_RB_FIND(struct name *, struct type *); \ -struct type *name##_RB_NEXT(struct name *, struct type *); \ -struct type *name##_RB_MINMAX(struct name *, int); \ - \ - -/* Main rb operation. - * Moves node close to the key of elm to top - */ -#define RB_GENERATE(name, type, field, cmp) \ -void \ -name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ -{ \ - struct type *parent, *gparent, *tmp; \ - while ((parent = RB_PARENT(elm, field)) && \ - RB_COLOR(parent, field) == RB_RED) { \ - gparent = RB_PARENT(parent, field); \ - if (parent == RB_LEFT(gparent, field)) { \ - tmp = RB_RIGHT(gparent, field); \ - if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ - RB_COLOR(tmp, field) = RB_BLACK; \ - RB_SET_BLACKRED(parent, gparent, field);\ - elm = gparent; \ - continue; \ - } \ - if (RB_RIGHT(parent, field) == elm) { \ - RB_ROTATE_LEFT(head, parent, tmp, field);\ - tmp = parent; \ - parent = elm; \ - elm = tmp; \ - } \ - RB_SET_BLACKRED(parent, gparent, field); \ - RB_ROTATE_RIGHT(head, gparent, tmp, field); \ - } else { \ - tmp = RB_LEFT(gparent, field); \ - if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ - RB_COLOR(tmp, field) = RB_BLACK; \ - RB_SET_BLACKRED(parent, gparent, field);\ - elm = gparent; \ - continue; \ - } \ - if (RB_LEFT(parent, field) == elm) { \ - RB_ROTATE_RIGHT(head, parent, tmp, field);\ - tmp = parent; \ - parent = elm; \ - elm = tmp; \ - } \ - RB_SET_BLACKRED(parent, gparent, field); \ - RB_ROTATE_LEFT(head, gparent, tmp, field); \ - } \ - } \ - RB_COLOR(head->rbh_root, field) = RB_BLACK; \ -} \ - \ -void \ -name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \ -{ \ - struct type *tmp; \ - while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \ - elm != RB_ROOT(head)) { \ - if (RB_LEFT(parent, field) == elm) { \ - tmp = RB_RIGHT(parent, field); \ - if (RB_COLOR(tmp, field) == RB_RED) { \ - RB_SET_BLACKRED(tmp, parent, field); \ - RB_ROTATE_LEFT(head, parent, tmp, field);\ - tmp = RB_RIGHT(parent, field); \ - } \ - if ((RB_LEFT(tmp, field) == NULL || \ - RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ - (RB_RIGHT(tmp, field) == NULL || \ - RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ - RB_COLOR(tmp, field) = RB_RED; \ - elm = parent; \ - parent = RB_PARENT(elm, field); \ - } else { \ - if (RB_RIGHT(tmp, field) == NULL || \ - RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\ - struct type *oleft; \ - if ((oleft = RB_LEFT(tmp, field)))\ - RB_COLOR(oleft, field) = RB_BLACK;\ - RB_COLOR(tmp, field) = RB_RED; \ - RB_ROTATE_RIGHT(head, tmp, oleft, field);\ - tmp = RB_RIGHT(parent, field); \ - } \ - RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ - RB_COLOR(parent, field) = RB_BLACK; \ - if (RB_RIGHT(tmp, field)) \ - RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\ - RB_ROTATE_LEFT(head, parent, tmp, field);\ - elm = RB_ROOT(head); \ - break; \ - } \ - } else { \ - tmp = RB_LEFT(parent, field); \ - if (RB_COLOR(tmp, field) == RB_RED) { \ - RB_SET_BLACKRED(tmp, parent, field); \ - RB_ROTATE_RIGHT(head, parent, tmp, field);\ - tmp = RB_LEFT(parent, field); \ - } \ - if ((RB_LEFT(tmp, field) == NULL || \ - RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ - (RB_RIGHT(tmp, field) == NULL || \ - RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ - RB_COLOR(tmp, field) = RB_RED; \ - elm = parent; \ - parent = RB_PARENT(elm, field); \ - } else { \ - if (RB_LEFT(tmp, field) == NULL || \ - RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\ - struct type *oright; \ - if ((oright = RB_RIGHT(tmp, field)))\ - RB_COLOR(oright, field) = RB_BLACK;\ - RB_COLOR(tmp, field) = RB_RED; \ - RB_ROTATE_LEFT(head, tmp, oright, field);\ - tmp = RB_LEFT(parent, field); \ - } \ - RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ - RB_COLOR(parent, field) = RB_BLACK; \ - if (RB_LEFT(tmp, field)) \ - RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\ - RB_ROTATE_RIGHT(head, parent, tmp, field);\ - elm = RB_ROOT(head); \ - break; \ - } \ - } \ - } \ - if (elm) \ - RB_COLOR(elm, field) = RB_BLACK; \ -} \ - \ -void \ -name##_RB_REMOVE(struct name *head, struct type *elm) \ -{ \ - struct type *child, *parent; \ - int color; \ - if (RB_LEFT(elm, field) == NULL) \ - child = RB_RIGHT(elm, field); \ - else if (RB_RIGHT(elm, field) == NULL) \ - child = RB_LEFT(elm, field); \ - else { \ - struct type *old = elm, *left; \ - elm = RB_RIGHT(elm, field); \ - while ((left = RB_LEFT(elm, field))) \ - elm = left; \ - child = RB_RIGHT(elm, field); \ - parent = RB_PARENT(elm, field); \ - color = RB_COLOR(elm, field); \ - if (child) \ - RB_PARENT(child, field) = parent; \ - if (parent) { \ - if (RB_LEFT(parent, field) == elm) \ - RB_LEFT(parent, field) = child; \ - else \ - RB_RIGHT(parent, field) = child; \ - RB_AUGMENT(parent); \ - } else \ - RB_ROOT(head) = child; \ - if (RB_PARENT(elm, field) == old) \ - parent = elm; \ - (elm)->field = (old)->field; \ - if (RB_PARENT(old, field)) { \ - if (RB_LEFT(RB_PARENT(old, field), field) == old)\ - RB_LEFT(RB_PARENT(old, field), field) = elm;\ - else \ - RB_RIGHT(RB_PARENT(old, field), field) = elm;\ - RB_AUGMENT(RB_PARENT(old, field)); \ - } else \ - RB_ROOT(head) = elm; \ - RB_PARENT(RB_LEFT(old, field), field) = elm; \ - if (RB_RIGHT(old, field)) \ - RB_PARENT(RB_RIGHT(old, field), field) = elm; \ - if (parent) { \ - left = parent; \ - do { \ - RB_AUGMENT(left); \ - } while ((left = RB_PARENT(left, field))); \ - } \ - goto color; \ - } \ - parent = RB_PARENT(elm, field); \ - color = RB_COLOR(elm, field); \ - if (child) \ - RB_PARENT(child, field) = parent; \ - if (parent) { \ - if (RB_LEFT(parent, field) == elm) \ - RB_LEFT(parent, field) = child; \ - else \ - RB_RIGHT(parent, field) = child; \ - RB_AUGMENT(parent); \ - } else \ - RB_ROOT(head) = child; \ -color: \ - if (color == RB_BLACK) \ - name##_RB_REMOVE_COLOR(head, parent, child); \ -} \ - \ -/* Inserts a node into the RB tree */ \ -struct type * \ -name##_RB_INSERT(struct name *head, struct type *elm) \ -{ \ - struct type *tmp; \ - struct type *parent = NULL; \ - int comp = 0; \ - tmp = RB_ROOT(head); \ - while (tmp) { \ - parent = tmp; \ - comp = (cmp)(elm, parent); \ - if (comp < 0) \ - tmp = RB_LEFT(tmp, field); \ - else if (comp > 0) \ - tmp = RB_RIGHT(tmp, field); \ - else \ - return (tmp); \ - } \ - RB_SET(elm, parent, field); \ - if (parent != NULL) { \ - if (comp < 0) \ - RB_LEFT(parent, field) = elm; \ - else \ - RB_RIGHT(parent, field) = elm; \ - RB_AUGMENT(parent); \ - } else \ - RB_ROOT(head) = elm; \ - name##_RB_INSERT_COLOR(head, elm); \ - return (NULL); \ -} \ - \ -/* Finds the node with the same key as elm */ \ -struct type * \ -name##_RB_FIND(struct name *head, struct type *elm) \ -{ \ - struct type *tmp = RB_ROOT(head); \ - int comp; \ - while (tmp) { \ - comp = cmp(elm, tmp); \ - if (comp < 0) \ - tmp = RB_LEFT(tmp, field); \ - else if (comp > 0) \ - tmp = RB_RIGHT(tmp, field); \ - else \ - return (tmp); \ - } \ - return (NULL); \ -} \ - \ -struct type * \ -name##_RB_NEXT(struct name *head, struct type *elm) \ -{ \ - if (RB_RIGHT(elm, field)) { \ - elm = RB_RIGHT(elm, field); \ - while (RB_LEFT(elm, field)) \ - elm = RB_LEFT(elm, field); \ - } else { \ - if (RB_PARENT(elm, field) && \ - (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ - elm = RB_PARENT(elm, field); \ - else { \ - while (RB_PARENT(elm, field) && \ - (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\ - elm = RB_PARENT(elm, field); \ - elm = RB_PARENT(elm, field); \ - } \ - } \ - return (elm); \ -} \ - \ -struct type * \ -name##_RB_MINMAX(struct name *head, int val) \ -{ \ - struct type *tmp = RB_ROOT(head); \ - struct type *parent = NULL; \ - while (tmp) { \ - parent = tmp; \ - if (val < 0) \ - tmp = RB_LEFT(tmp, field); \ - else \ - tmp = RB_RIGHT(tmp, field); \ - } \ - return (parent); \ -} - -#define RB_NEGINF -1 -#define RB_INF 1 - -#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) -#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) -#define RB_FIND(name, x, y) name##_RB_FIND(x, y) -#define RB_NEXT(name, x, y) name##_RB_NEXT(x, y) -#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) -#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) - -#define RB_FOREACH(x, name, head) \ - for ((x) = RB_MIN(name, head); \ - (x) != NULL; \ - (x) = name##_RB_NEXT(head, x)) - -#endif /* _SYS_TREE_H_ */ diff --git a/openssh/packet.c b/openssh/packet.c index 4e6fc4a..ded0d41 100644 --- a/openssh/packet.c +++ b/openssh/packet.c @@ -37,7 +37,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: packet.c,v 1.96 2002/06/23 21:10:02 deraadt Exp $"); +RCSID("$OpenBSD: packet.c,v 1.97 2002/07/04 08:12:15 deraadt Exp $"); #include "xmalloc.h" #include "buffer.h" @@ -134,6 +134,7 @@ void packet_set_connection(int fd_in, int fd_out) { Cipher *none = cipher_by_name("none"); + if (none == NULL) fatal("packet_set_connection: cannot load cipher 'none'"); connection_in = fd_in; @@ -402,6 +403,7 @@ packet_set_encryption_key(const u_char *key, u_int keylen, int number) { Cipher *cipher = cipher_by_number(number); + if (cipher == NULL) fatal("packet_set_encryption_key: unknown cipher number %d", number); if (keylen < 20) @@ -443,6 +445,7 @@ void packet_put_char(int value) { char ch = value; + buffer_append(&outgoing_packet, &ch, 1); } void @@ -994,7 +997,8 @@ packet_read_poll2(u_int32_t *seqnr_p) buffer_clear(&incoming_packet); buffer_append(&incoming_packet, buffer_ptr(&compression_buffer), buffer_len(&compression_buffer)); - DBG(debug("input: len after de-compress %d", buffer_len(&incoming_packet))); + DBG(debug("input: len after de-compress %d", + buffer_len(&incoming_packet))); } /* * get packet type, implies consume. @@ -1102,6 +1106,7 @@ u_int packet_get_char(void) { char ch; + buffer_get(&incoming_packet, &ch, 1); return (u_char) ch; } @@ -1135,6 +1140,7 @@ void * packet_get_raw(int *length_ptr) { int bytes = buffer_len(&incoming_packet); + if (length_ptr != NULL) *length_ptr = bytes; return buffer_ptr(&incoming_packet); @@ -1214,6 +1220,7 @@ packet_disconnect(const char *fmt,...) char buf[1024]; va_list args; static int disconnecting = 0; + if (disconnecting) /* Guard against recursive invocations. */ fatal("packet_disconnect called recursively."); disconnecting = 1; @@ -1256,6 +1263,7 @@ void packet_write_poll(void) { int len = buffer_len(&output); + if (len > 0) { len = write(connection_out, buffer_ptr(&output), len); if (len <= 0) { @@ -1375,6 +1383,7 @@ int packet_set_maxsize(int s) { static int called = 0; + if (called) { log("packet_set_maxsize: called twice: old %d new %d", max_packet_size, s); diff --git a/openssh/readconf.c b/openssh/readconf.c index 211075d..52ecbcb 100644 --- a/openssh/readconf.c +++ b/openssh/readconf.c @@ -215,7 +215,7 @@ add_local_forward(Options *options, u_short port, const char *host, u_short host_port) { Forward *fwd; -#ifndef HAVE_CYGWIN +#ifndef NO_IPPORT_RESERVED_CONCEPT extern uid_t original_real_uid; if (port < IPPORT_RESERVED && original_real_uid != 0) fatal("Privileged ports can only be forwarded by root."); diff --git a/openssh/servconf.c b/openssh/servconf.c index 0528f7a..8b05132 100644 --- a/openssh/servconf.c +++ b/openssh/servconf.c @@ -10,7 +10,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: servconf.c,v 1.112 2002/06/23 09:46:51 deraadt Exp $"); +RCSID("$OpenBSD: servconf.c,v 1.115 2002/09/04 18:52:42 stevesk Exp $"); #if defined(KRB4) #include @@ -106,6 +106,7 @@ initialize_server_options(ServerOptions *options) options->kbd_interactive_authentication = -1; options->challenge_response_authentication = -1; options->permit_empty_passwd = -1; + options->permit_user_env = -1; options->use_login = -1; options->compression = -1; options->allow_tcp_forwarding = -1; @@ -163,7 +164,7 @@ fill_default_server_options(ServerOptions *options) if (options->server_key_bits == -1) options->server_key_bits = 768; if (options->login_grace_time == -1) - options->login_grace_time = 600; + options->login_grace_time = 120; if (options->key_regeneration_time == -1) options->key_regeneration_time = 3600; if (options->permit_root_login == PERMIT_NOT_SET) @@ -238,6 +239,8 @@ fill_default_server_options(ServerOptions *options) options->challenge_response_authentication = 1; if (options->permit_empty_passwd == -1) options->permit_empty_passwd = 0; + if (options->permit_user_env == -1) + options->permit_user_env = 0; if (options->use_login == -1) options->use_login = 0; if (options->compression == -1) @@ -272,7 +275,7 @@ fill_default_server_options(ServerOptions *options) if (use_privsep == -1) use_privsep = 1; -#if !defined(HAVE_MMAP_ANON_SHARED) +#ifndef HAVE_MMAP if (use_privsep && options->compression == 1) { error("This platform does not support both privilege " "separation and compression"); @@ -309,7 +312,7 @@ typedef enum { sPrintMotd, sPrintLastLog, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, sStrictModes, sEmptyPasswd, sKeepAlives, - sUseLogin, sAllowTcpForwarding, sCompression, + sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile, sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem, sMaxStartups, @@ -379,6 +382,7 @@ static struct { { "xauthlocation", sXAuthLocation }, { "strictmodes", sStrictModes }, { "permitemptypasswords", sEmptyPasswd }, + { "permituserenvironment", sPermitUserEnvironment }, { "uselogin", sUseLogin }, { "compression", sCompression }, { "keepalive", sKeepAlives }, @@ -752,6 +756,10 @@ parse_flag: intptr = &options->permit_empty_passwd; goto parse_flag; + case sPermitUserEnvironment: + intptr = &options->permit_user_env; + goto parse_flag; + case sUseLogin: intptr = &options->use_login; goto parse_flag; diff --git a/openssh/servconf.h b/openssh/servconf.h index fd326fc..1c947da 100644 --- a/openssh/servconf.h +++ b/openssh/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.58 2002/06/20 23:05:55 markus Exp $ */ +/* $OpenBSD: servconf.h,v 1.59 2002/07/30 17:03:55 markus Exp $ */ /* * Author: Tatu Ylonen @@ -104,6 +104,7 @@ typedef struct { int challenge_response_authentication; int permit_empty_passwd; /* If false, do not permit empty * passwords. */ + int permit_user_env; /* If true, read ~/.ssh/environment */ int use_login; /* If true, login(1) is used */ int compression; /* If true, compression is allowed */ int allow_tcp_forwarding; diff --git a/openssh/session.c b/openssh/session.c index 59de795..46d91fb 100644 --- a/openssh/session.c +++ b/openssh/session.c @@ -33,7 +33,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: session.c,v 1.142 2002/06/26 13:49:26 deraadt Exp $"); +RCSID("$OpenBSD: session.c,v 1.150 2002/09/16 19:55:33 stevesk Exp $"); #include "ssh.h" #include "ssh1.h" @@ -214,13 +214,6 @@ do_authenticated(Authctxt *authctxt) close(startup_pipe); startup_pipe = -1; } -#ifdef WITH_AIXAUTHENTICATE - /* We don't have a pty yet, so just label the line as "ssh" */ - if (loginsuccess(authctxt->user, - get_canonical_hostname(options.verify_reverse_mapping), - "ssh", &aixloginmsg) < 0) - aixloginmsg = NULL; -#endif /* WITH_AIXAUTHENTICATE */ /* setup the channel layer */ if (!no_port_forwarding_flag && options.allow_tcp_forwarding) @@ -480,6 +473,8 @@ do_exec_no_pty(Session *s, const char *command) /* Fork the child. */ if ((pid = fork()) == 0) { + fatal_remove_all_cleanups(); + /* Child. Reinitialize the log since the pid has changed. */ log_init(__progname, options.log_level, options.log_facility, log_stderr); @@ -527,10 +522,17 @@ do_exec_no_pty(Session *s, const char *command) perror("dup2 stderr"); #endif /* USE_PIPES */ +#ifdef _UNICOS + cray_init_job(s->pw); /* set up cray jid and tmpdir */ +#endif + /* Do processing for the child (exec command etc). */ do_child(s, command); /* NOTREACHED */ } +#ifdef _UNICOS + signal(WJSIGNAL, cray_job_termination_handler); +#endif /* _UNICOS */ #ifdef HAVE_CYGWIN if (is_winnt) cygwin_set_impersonation_token(INVALID_HANDLE_VALUE); @@ -601,6 +603,7 @@ do_exec_pty(Session *s, const char *command) /* Fork the child. */ if ((pid = fork()) == 0) { + fatal_remove_all_cleanups(); /* Child. Reinitialize the log because the pid has changed. */ log_init(__progname, options.log_level, options.log_facility, log_stderr); @@ -623,8 +626,12 @@ do_exec_pty(Session *s, const char *command) /* record login, etc. similar to login(1) */ #ifndef HAVE_OSF_SIA - if (!(options.use_login && command == NULL)) + if (!(options.use_login && command == NULL)) { +#ifdef _UNICOS + cray_init_job(s->pw); /* set up cray jid and tmpdir */ +#endif /* _UNICOS */ do_login(s, command); + } # ifdef LOGIN_NEEDS_UTMPX else do_pre_login(s); @@ -635,6 +642,9 @@ do_exec_pty(Session *s, const char *command) do_child(s, command); /* NOTREACHED */ } +#ifdef _UNICOS + signal(WJSIGNAL, cray_job_termination_handler); +#endif /* _UNICOS */ #ifdef HAVE_CYGWIN if (is_winnt) cygwin_set_impersonation_token(INVALID_HANDLE_VALUE); @@ -684,8 +694,8 @@ do_pre_login(Session *s) * the address be 0.0.0.0. */ memset(&from, 0, sizeof(from)); + fromlen = sizeof(from); if (packet_connection_is_on_socket()) { - fromlen = sizeof(from); if (getpeername(packet_get_connection_in(), (struct sockaddr *) & from, &fromlen) < 0) { debug("getpeername: %.100s", strerror(errno)); @@ -750,7 +760,7 @@ do_login(Session *s, const char *command) record_login(pid, s->tty, pw->pw_name, pw->pw_uid, get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping), - (struct sockaddr *)&from); + (struct sockaddr *)&from, fromlen); #ifdef USE_PAM /* @@ -775,6 +785,7 @@ do_login(Session *s, const char *command) printf("%s\n", aixloginmsg); #endif /* WITH_AIXAUTHENTICATE */ +#ifndef NO_SSH_LASTLOG if (options.print_lastlog && s->last_login_time != 0) { time_string = ctime(&s->last_login_time); if (strchr(time_string, '\n')) @@ -785,6 +796,7 @@ do_login(Session *s, const char *command) printf("Last login: %s from %s\r\n", time_string, s->hostname); } +#endif /* NO_SSH_LASTLOG */ do_motd(); } @@ -982,8 +994,10 @@ do_setup_env(Session *s, const char *shell) child_set_env(&env, &envsize, "LOGNAME", pw->pw_name); child_set_env(&env, &envsize, "HOME", pw->pw_dir); #ifdef HAVE_LOGIN_CAP - (void) setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH); - child_set_env(&env, &envsize, "PATH", getenv("PATH")); + if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETPATH) < 0) + child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); + else + child_set_env(&env, &envsize, "PATH", getenv("PATH")); #else /* HAVE_LOGIN_CAP */ # ifndef HAVE_CYGWIN /* @@ -1015,13 +1029,13 @@ do_setup_env(Session *s, const char *shell) if (!options.use_login) { while (custom_environment) { struct envstring *ce = custom_environment; - char *s = ce->s; + char *str = ce->s; - for (i = 0; s[i] != '=' && s[i]; i++) + for (i = 0; str[i] != '=' && str[i]; i++) ; - if (s[i] == '=') { - s[i] = 0; - child_set_env(&env, &envsize, s, s + i + 1); + if (str[i] == '=') { + str[i] = 0; + child_set_env(&env, &envsize, str, str + i + 1); } custom_environment = ce->next; xfree(ce->s); @@ -1029,10 +1043,16 @@ do_setup_env(Session *s, const char *shell) } } + /* SSH_CLIENT deprecated */ snprintf(buf, sizeof buf, "%.50s %d %d", get_remote_ipaddr(), get_remote_port(), get_local_port()); child_set_env(&env, &envsize, "SSH_CLIENT", buf); + snprintf(buf, sizeof buf, "%.50s %d %.50s %d", + get_remote_ipaddr(), get_remote_port(), + get_local_ipaddr(packet_get_connection_in()), get_local_port()); + child_set_env(&env, &envsize, "SSH_CONNECTION", buf); + if (s->ttyfd != -1) child_set_env(&env, &envsize, "SSH_TTY", s->tty); if (s->term) @@ -1043,6 +1063,11 @@ do_setup_env(Session *s, const char *shell) child_set_env(&env, &envsize, "SSH_ORIGINAL_COMMAND", original_command); +#ifdef _UNICOS + if (cray_tmpdir[0] != '\0') + child_set_env(&env, &envsize, "TMPDIR", cray_tmpdir); +#endif /* _UNICOS */ + #ifdef _AIX { char *cp; @@ -1065,8 +1090,17 @@ do_setup_env(Session *s, const char *shell) s->authctxt->krb5_ticket_file); #endif #ifdef USE_PAM - /* Pull in any environment variables that may have been set by PAM. */ - copy_environment(fetch_pam_environment(), &env, &envsize); + /* + * Pull in any environment variables that may have + * been set by PAM. + */ + { + char **p; + + p = fetch_pam_environment(); + copy_environment(p, &env, &envsize); + free_pam_environment(p); + } #endif /* USE_PAM */ if (auth_sock_name != NULL) @@ -1074,9 +1108,9 @@ do_setup_env(Session *s, const char *shell) auth_sock_name); /* read $HOME/.ssh/environment. */ - if (!options.use_login) { + if (options.permit_user_env && !options.use_login) { snprintf(buf, sizeof buf, "%.200s/.ssh/environment", - pw->pw_dir); + strcmp(pw->pw_dir, "/") ? pw->pw_dir : ""); read_environment_file(&env, &envsize, buf); } if (debug_flag) { @@ -1171,6 +1205,8 @@ do_nologin(struct passwd *pw) #endif if (f) { /* /etc/nologin exists. Print its contents and exit. */ + log("User %.100s not allowed because %s exists", + pw->pw_name, _PATH_NOLOGIN); while (fgets(buf, sizeof(buf), f)) fputs(buf, stderr); fclose(f); @@ -1182,8 +1218,6 @@ do_nologin(struct passwd *pw) void do_setusercontext(struct passwd *pw) { - char tty='\0'; - #ifdef HAVE_CYGWIN if (is_winnt) { #else /* HAVE_CYGWIN */ @@ -1193,9 +1227,9 @@ do_setusercontext(struct passwd *pw) setpcred(pw->pw_name); #endif /* HAVE_SETPCRED */ #ifdef HAVE_LOGIN_CAP -#ifdef __bsdi__ +# ifdef __bsdi__ setpgid(0, 0); -#endif +# endif if (setusercontext(lc, pw, pw->pw_uid, (LOGIN_SETALL & ~LOGIN_SETPATH)) < 0) { perror("unable to set user context"); @@ -1232,8 +1266,7 @@ do_setusercontext(struct passwd *pw) irix_setusercontext(pw); # endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ # ifdef _AIX - /* XXX: Disable tty setting. Enabled if required later */ - aix_usrinfo(pw, &tty, -1); + aix_usrinfo(pw); # endif /* _AIX */ /* Permanently switch to the desired uid. */ permanently_set_uid(pw); @@ -1286,6 +1319,10 @@ do_child(Session *s, const char *command) if (options.use_login && command != NULL) options.use_login = 0; +#ifdef _UNICOS + cray_setup(pw->pw_uid, pw->pw_name, command); +#endif /* _UNICOS */ + /* * Login(1) does this as well, and it needs uid 0 for the "-h" * switch, so we let login(1) to this for us. @@ -1821,6 +1858,27 @@ session_pty_cleanup(void *session) PRIVSEP(session_pty_cleanup2(session)); } +static char * +sig2name(int sig) +{ +#define SSH_SIG(x) if (sig == SIG ## x) return #x + SSH_SIG(ABRT); + SSH_SIG(ALRM); + SSH_SIG(FPE); + SSH_SIG(HUP); + SSH_SIG(ILL); + SSH_SIG(INT); + SSH_SIG(KILL); + SSH_SIG(PIPE); + SSH_SIG(QUIT); + SSH_SIG(SEGV); + SSH_SIG(TERM); + SSH_SIG(USR1); + SSH_SIG(USR2); +#undef SSH_SIG + return "SIG@openssh.com"; +} + static void session_exit_message(Session *s, int status) { @@ -1838,7 +1896,7 @@ session_exit_message(Session *s, int status) packet_send(); } else if (WIFSIGNALED(status)) { channel_request_start(s->chanid, "exit-signal", 0); - packet_put_int(WTERMSIG(status)); + packet_put_cstring(sig2name(WTERMSIG(status))); #ifdef WCOREDUMP packet_put_char(WCOREDUMP(status)); #else /* WCOREDUMP */ diff --git a/openssh/session.h b/openssh/session.h index ae4fb09..7fc3653 100644 --- a/openssh/session.h +++ b/openssh/session.h @@ -1,4 +1,4 @@ -/* $OpenBSD: session.h,v 1.18 2002/06/23 21:06:41 deraadt Exp $ */ +/* $OpenBSD: session.h,v 1.19 2002/06/30 21:59:45 deraadt Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -57,7 +57,7 @@ struct Session { void do_authenticated(Authctxt *); -int session_open(Authctxt*, int); +int session_open(Authctxt *, int); int session_input_channel_req(Channel *, const char *); void session_close_by_pid(pid_t, int); void session_close_by_channel(int, void *); diff --git a/openssh/ssh-agent.c b/openssh/ssh-agent.c index ac16bae..cca720e 100644 --- a/openssh/ssh-agent.c +++ b/openssh/ssh-agent.c @@ -34,8 +34,8 @@ */ #include "includes.h" -#include "openbsd-compat/fake-queue.h" -RCSID("$OpenBSD: ssh-agent.c,v 1.97 2002/06/24 14:55:38 markus Exp $"); +#include "openbsd-compat/sys-queue.h" +RCSID("$OpenBSD: ssh-agent.c,v 1.105 2002/10/01 20:34:12 markus Exp $"); #include #include @@ -106,6 +106,17 @@ extern char *__progname; char *__progname; #endif +static void +close_socket(SocketEntry *e) +{ + close(e->fd); + e->fd = -1; + e->type = AUTH_UNUSED; + buffer_free(&e->input); + buffer_free(&e->output); + buffer_free(&e->request); +} + static void idtab_init(void) { @@ -617,13 +628,7 @@ process_message(SocketEntry *e) cp = buffer_ptr(&e->input); msg_len = GET_32BIT(cp); if (msg_len > 256 * 1024) { - shutdown(e->fd, SHUT_RDWR); - close(e->fd); - e->fd = -1; - e->type = AUTH_UNUSED; - buffer_free(&e->input); - buffer_free(&e->output); - buffer_free(&e->request); + close_socket(e); return; } if (buffer_len(&e->input) < msg_len + 4) @@ -805,6 +810,8 @@ after_select(fd_set *readset, fd_set *writeset) char buf[1024]; int len, sock; u_int i; + uid_t euid; + gid_t egid; for (i = 0; i < sockets_alloc; i++) switch (sockets[i].type) { @@ -820,6 +827,19 @@ after_select(fd_set *readset, fd_set *writeset) strerror(errno)); break; } + if (getpeereid(sock, &euid, &egid) < 0) { + error("getpeereid %d failed: %s", + sock, strerror(errno)); + close(sock); + break; + } + if ((euid != 0) && (getuid() != euid)) { + error("uid mismatch: " + "peer euid %u != uid %u", + (u_int) euid, (u_int) getuid()); + close(sock); + break; + } new_socket(AUTH_CONNECTION, sock); } break; @@ -836,13 +856,7 @@ after_select(fd_set *readset, fd_set *writeset) break; } while (1); if (len <= 0) { - shutdown(sockets[i].fd, SHUT_RDWR); - close(sockets[i].fd); - sockets[i].fd = -1; - sockets[i].type = AUTH_UNUSED; - buffer_free(&sockets[i].input); - buffer_free(&sockets[i].output); - buffer_free(&sockets[i].request); + close_socket(&sockets[i]); break; } buffer_consume(&sockets[i].output, len); @@ -856,13 +870,7 @@ after_select(fd_set *readset, fd_set *writeset) break; } while (1); if (len <= 0) { - shutdown(sockets[i].fd, SHUT_RDWR); - close(sockets[i].fd); - sockets[i].fd = -1; - sockets[i].type = AUTH_UNUSED; - buffer_free(&sockets[i].input); - buffer_free(&sockets[i].output); - buffer_free(&sockets[i].request); + close_socket(&sockets[i]); break; } buffer_append(&sockets[i].input, buf, len); @@ -943,6 +951,10 @@ main(int ac, char **av) pid_t pid; char pidstrbuf[1 + 3 * sizeof pid]; + /* drop */ + setegid(getgid()); + setgid(getgid()); + SSLeay_add_all_algorithms(); __progname = get_progname(av[0]); @@ -1052,7 +1064,7 @@ main(int ac, char **av) #ifdef HAVE_CYGWIN umask(prev_mask); #endif - if (listen(sock, 5) < 0) { + if (listen(sock, 128) < 0) { perror("listen"); cleanup_exit(1); } diff --git a/openssh/ssh-keysign.8 b/openssh/ssh-keysign.8 index ab2cf21..cea4a82 100644 --- a/openssh/ssh-keysign.8 +++ b/openssh/ssh-keysign.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keysign.8,v 1.2 2002/06/10 16:56:30 stevesk Exp $ +.\" $OpenBSD: ssh-keysign.8,v 1.3 2002/07/03 14:21:05 markus Exp $ .\" .\" Copyright (c) 2002 Markus Friedl. All rights reserved. .\" @@ -36,6 +36,16 @@ is used by .Xr ssh 1 to access the local host keys and generate the digital signature required during hostbased authentication with SSH protocol version 2. +.Pp +.Nm +is disabled by default and can only be enabled in the +the global client configuration file +.Pa /etc/ssh/ssh_config +by setting +.Cm HostbasedAuthentication +to +.Dq yes . +.Pp .Nm is not intended to be invoked by the user, but from .Xr ssh 1 . @@ -46,6 +56,10 @@ and for more information about hostbased authentication. .Sh FILES .Bl -tag -width Ds +.It Pa /etc/ssh/ssh_config +Controls whether +.Nm +is enabled. .It Pa /etc/ssh/ssh_host_dsa_key, /etc/ssh/ssh_host_rsa_key These files contain the private parts of the host keys used to generate the digital signature. They @@ -58,6 +72,7 @@ must be set-uid root if hostbased authentication is used. .Sh SEE ALSO .Xr ssh 1 , .Xr ssh-keygen 1 , +.Xr ssh_config 5 , .Xr sshd 8 .Sh AUTHORS Markus Friedl diff --git a/openssh/ssh-keysign.c b/openssh/ssh-keysign.c index 7f1d25d..79aee17 100644 --- a/openssh/ssh-keysign.c +++ b/openssh/ssh-keysign.c @@ -22,12 +22,15 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "includes.h" -RCSID("$OpenBSD: ssh-keysign.c,v 1.4 2002/06/19 00:27:55 deraadt Exp $"); +RCSID("$OpenBSD: ssh-keysign.c,v 1.7 2002/07/03 14:21:05 markus Exp $"); #include +#include +#include #include "log.h" #include "key.h" +#include "ssh.h" #include "ssh2.h" #include "misc.h" #include "xmalloc.h" @@ -37,6 +40,9 @@ RCSID("$OpenBSD: ssh-keysign.c,v 1.4 2002/06/19 00:27:55 deraadt Exp $"); #include "msg.h" #include "canohost.h" #include "pathnames.h" +#include "readconf.h" + +uid_t original_real_uid; /* XXX readconf.c needs this */ #ifdef HAVE___PROGNAME extern char *__progname; @@ -134,12 +140,14 @@ int main(int argc, char **argv) { Buffer b; + Options options; Key *keys[2], *key; struct passwd *pw; int key_fd[2], i, found, version = 2, fd; u_char *signature, *data; char *host; u_int slen, dlen; + u_int32_t rnd[256]; key_fd[0] = open(_PATH_HOST_RSA_KEY_FILE, O_RDONLY); key_fd[1] = open(_PATH_HOST_DSA_KEY_FILE, O_RDONLY); @@ -155,6 +163,15 @@ main(int argc, char **argv) log_init("ssh-keysign", SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_AUTH, 0); #endif + /* verify that ssh-keysign is enabled by the admin */ + original_real_uid = getuid(); /* XXX readconf.c needs this */ + initialize_options(&options); + (void)read_config_file(_PATH_HOST_CONFIG_FILE, "", &options); + fill_default_options(&options); + if (options.hostbased_authentication != 1) + fatal("Hostbased authentication not enabled in %s", + _PATH_HOST_CONFIG_FILE); + if (key_fd[0] == -1 && key_fd[1] == -1) fatal("could not open any host key"); @@ -163,6 +180,9 @@ main(int argc, char **argv) pw = pwcopy(pw); SSLeay_add_all_algorithms(); + for (i = 0; i < 256; i++) + rnd[i] = arc4random(); + RAND_seed(rnd, sizeof(rnd)); found = 0; for (i = 0; i < 2; i++) { @@ -172,6 +192,13 @@ main(int argc, char **argv) keys[i] = key_load_private_pem(key_fd[i], KEY_UNSPEC, NULL, NULL); close(key_fd[i]); + if (keys[i] != NULL && keys[i]->type == KEY_RSA) { + if (RSA_blinding_on(keys[i]->rsa, NULL) != 1) { + error("RSA_blinding_on failed"); + key_free(keys[i]); + keys[i] = NULL; + } + } if (keys[i] != NULL) found = 1; } @@ -179,8 +206,8 @@ main(int argc, char **argv) fatal("no hostkey found"); buffer_init(&b); - if (msg_recv(STDIN_FILENO, &b) < 0) - fatal("msg_recv failed"); + if (ssh_msg_recv(STDIN_FILENO, &b) < 0) + fatal("ssh_msg_recv failed"); if (buffer_get_char(&b) != version) fatal("bad version"); fd = buffer_get_int(&b); @@ -192,7 +219,6 @@ main(int argc, char **argv) data = buffer_get_string(&b, &dlen); if (valid_request(pw, host, &key, data, dlen) < 0) fatal("not a valid request"); - xfree(data); xfree(host); found = 0; @@ -208,11 +234,12 @@ main(int argc, char **argv) if (key_sign(keys[i], &signature, &slen, data, dlen) != 0) fatal("key_sign failed"); + xfree(data); /* send reply */ buffer_clear(&b); buffer_put_string(&b, signature, slen); - msg_send(STDOUT_FILENO, version, &b); + ssh_msg_send(STDOUT_FILENO, version, &b); return (0); } diff --git a/openssh/ssh-rand-helper.c b/openssh/ssh-rand-helper.c index da78a09..f96447b 100644 --- a/openssh/ssh-rand-helper.c +++ b/openssh/ssh-rand-helper.c @@ -63,7 +63,6 @@ RCSID("$Id$"); # define SSH_PRNG_COMMAND_FILE SSHDIR "/ssh_prng_cmds" #endif - #ifdef HAVE___PROGNAME extern char *__progname; #else @@ -115,7 +114,7 @@ double stir_from_programs(void); double stir_gettimeofday(double entropy_estimate); double stir_clock(double entropy_estimate); double stir_rusage(int who, double entropy_estimate); -double hash_command_output(entropy_cmd_t *src, char *hash); +double hash_command_output(entropy_cmd_t *src, unsigned char *hash); int get_random_bytes_prngd(unsigned char *buf, int len, unsigned short tcp_port, char *socket_path); @@ -274,7 +273,7 @@ timeval_diff(struct timeval *t1, struct timeval *t2) } double -hash_command_output(entropy_cmd_t *src, char *hash) +hash_command_output(entropy_cmd_t *src, unsigned char *hash) { char buf[8192]; fd_set rdset; @@ -460,7 +459,7 @@ stir_from_programs(void) { int c; double entropy, total_entropy; - char hash[SHA_DIGEST_LENGTH]; + unsigned char hash[SHA_DIGEST_LENGTH]; total_entropy = 0; for(c = 0; entropy_cmds[c].path != NULL; c++) { @@ -543,7 +542,8 @@ void prng_write_seedfile(void) { int fd; - char seed[SEED_FILE_SIZE], filename[MAXPATHLEN]; + unsigned char seed[SEED_FILE_SIZE]; + char filename[MAXPATHLEN]; struct passwd *pw; pw = getpwuid(getuid()); @@ -862,4 +862,3 @@ main(int argc, char **argv) return ret == bytes ? 0 : 1; } - diff --git a/openssh/ssh.1 b/openssh/ssh.1 index 1f3efca..27808b1 100644 --- a/openssh/ssh.1 +++ b/openssh/ssh.1 @@ -34,7 +34,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. .\" -.\" $OpenBSD: ssh.1,v 1.160 2002/06/22 11:51:39 naddy Exp $ +.\" $OpenBSD: ssh.1,v 1.167 2002/09/27 15:46:21 stevesk Exp $ .Dd September 25, 1999 .Dt SSH 1 .Os @@ -48,7 +48,7 @@ .Op Ar command .Pp .Nm ssh -.Op Fl afgknqstvxACNPTX1246 +.Op Fl afgknqstvxACNTX1246 .Op Fl b Ar bind_address .Op Fl c Ar cipher_spec .Op Fl e Ar escape_char @@ -353,9 +353,17 @@ the connection is opened. The real authentication cookie is never sent to the server machine (and no cookies are sent in the plain). .Pp -If the user is using an authentication agent, the connection to the agent -is automatically forwarded to the remote side unless disabled on -the command line or in a configuration file. +If the +.Cm ForwardAgent +variable is set to +.Dq yes +(or, see the description of the +.Fl A +and +.Fl a +options described later) and +the user is using an authentication agent, the connection to the agent +is automatically forwarded to the remote side. .Pp Forwarding of arbitrary TCP/IP connections over the secure channel can be specified either on the command line or in a configuration file. @@ -394,6 +402,13 @@ Disables forwarding of the authentication agent connection. .It Fl A Enables forwarding of the authentication agent connection. This can also be specified on a per-host basis in a configuration file. +.Pp +Agent forwarding should be enabled with caution. Users with the +ability to bypass file permissions on the remote host (for the agent's +Unix-domain socket) can access the local agent through the forwarded +connection. An attacker cannot obtain key material from the agent, +however they can perform operations on the keys that enable them to +authenticate using the identities loaded into the agent. .It Fl b Ar bind_address Specify the interface to transmit from on machines with multiple interfaces or aliased addresses. @@ -515,15 +530,6 @@ command-line flag. Port to connect to on the remote host. This can be specified on a per-host basis in the configuration file. -.It Fl P -Use a non-privileged port for outgoing connections. -This can be used if a firewall does -not permit connections from privileged ports. -Note that this option turns off -.Cm RhostsAuthentication -and -.Cm RhostsRSAAuthentication -for older servers. .It Fl q Quiet mode. Causes all warning and diagnostic messages to be suppressed. @@ -559,6 +565,12 @@ Disables X11 forwarding. .It Fl X Enables X11 forwarding. This can also be specified on a per-host basis in a configuration file. +.Pp +X11 forwarding should be enabled with caution. Users with the ability +to bypass file permissions on the remote host (for the user's X +authorization database) can access the local X11 display through the +forwarded connection. An attacker may then be able to perform +activities such as keystroke monitoring. .It Fl C Requests compression of all data (including stdin, stdout, stderr, and data for forwarded X11 and TCP/IP connections). @@ -568,7 +580,7 @@ and the .Dq level can be controlled by the .Cm CompressionLevel -option. +option for protocol version 1. Compression is desirable on modem lines and other slow connections, but will only slow down things on fast networks. The default value can be set on a host-by-host basis in the @@ -714,11 +726,11 @@ to make this work.) .It Ev SSH_AUTH_SOCK Identifies the path of a unix-domain socket used to communicate with the agent. -.It Ev SSH_CLIENT -Identifies the client end of the connection. +.It Ev SSH_CONNECTION +Identifies the client and server ends of the connection. The variable contains -three space-separated values: client ip-address, client port number, -and server port number. +four space-separated values: client ip-address, client port number, +server ip-address and server port number. .It Ev SSH_ORIGINAL_COMMAND The variable contains the original command line if a forced command is executed. @@ -742,7 +754,12 @@ reads .Pa $HOME/.ssh/environment , and adds lines of the format .Dq VARNAME=value -to the environment. +to the environment if the file exists and if users are allowed to +change their environment. +See the +.Cm PermitUserEnvironment +option in +.Xr sshd_config 5 . .Sh FILES .Bl -tag -width Ds .It Pa $HOME/.ssh/known_hosts diff --git a/openssh/ssh.c b/openssh/ssh.c index f0dbd7e..82e8801 100644 --- a/openssh/ssh.c +++ b/openssh/ssh.c @@ -40,7 +40,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: ssh.c,v 1.179 2002/06/12 01:09:52 markus Exp $"); +RCSID("$OpenBSD: ssh.c,v 1.186 2002/09/19 01:58:18 djm Exp $"); #include #include @@ -146,6 +146,9 @@ int subsystem_flag = 0; /* # of replies received for global requests */ static int client_global_request_id = 0; +/* pid of proxycommand child process */ +pid_t proxy_command_pid = 0; + /* Prints a help message to the user. This function never returns. */ static void @@ -174,7 +177,6 @@ usage(void) fprintf(stderr, " -v Verbose; display verbose debugging messages.\n"); fprintf(stderr, " Multiple -v increases verbosity.\n"); fprintf(stderr, " -V Display version number only.\n"); - fprintf(stderr, " -P Don't allocate a privileged port.\n"); fprintf(stderr, " -q Quiet; don't display any warning messages.\n"); fprintf(stderr, " -f Fork into background after authentication.\n"); fprintf(stderr, " -e char Set escape character; ``none'' = disable (default: ~).\n"); @@ -229,6 +231,15 @@ main(int ac, char **av) */ original_real_uid = getuid(); original_effective_uid = geteuid(); + + /* + * Use uid-swapping to give up root privileges for the duration of + * option processing. We will re-instantiate the rights when we are + * ready to create the privileged port, and will permanently drop + * them when the port has been created (actually, when the connection + * has been made, as we may need to create the port several times). + */ + PRIV_END; #ifdef HAVE_SETRLIMIT /* If we are installed setuid root be careful to not drop core. */ @@ -248,15 +259,6 @@ main(int ac, char **av) /* Take a copy of the returned structure. */ pw = pwcopy(pw); - /* - * Use uid-swapping to give up root privileges for the duration of - * option processing. We will re-instantiate the rights when we are - * ready to create the privileged port, and will permanently drop - * them when the port has been created (actually, when the connection - * has been made, as we may need to create the port several times). - */ - PRIV_END; - /* * Set our umask to something reasonable, as some files are created * with the default umask. This will make them world-readable but @@ -303,7 +305,7 @@ again: case 'g': options.gateway_ports = 1; break; - case 'P': + case 'P': /* deprecated */ options.use_privileged_port = 0; break; case 'a': @@ -552,7 +554,7 @@ again: if (buffer_len(&command) == 0) tty_flag = 1; - /* Force no tty*/ + /* Force no tty */ if (no_tty_flag) tty_flag = 0; /* Do not allocate a tty if stdin is not a tty. */ @@ -668,7 +670,8 @@ again: if (options.rhosts_rsa_authentication || options.hostbased_authentication) { sensitive_data.nkeys = 3; - sensitive_data.keys = xmalloc(sensitive_data.nkeys*sizeof(Key)); + sensitive_data.keys = xmalloc(sensitive_data.nkeys * + sizeof(Key)); PRIV_START; sensitive_data.keys[0] = key_load_private_type(KEY_RSA1, @@ -679,7 +682,8 @@ again: _PATH_HOST_RSA_KEY_FILE, "", NULL); PRIV_END; - if (sensitive_data.keys[0] == NULL && + if (options.hostbased_authentication == 1 && + sensitive_data.keys[0] == NULL && sensitive_data.keys[1] == NULL && sensitive_data.keys[2] == NULL) { sensitive_data.keys[1] = key_load_public( @@ -752,6 +756,14 @@ again: exit_status = compat20 ? ssh_session2() : ssh_session(); packet_close(); + + /* + * Send SIGHUP to proxy command if used. We don't wait() in + * case it hangs and instead rely on init to reap the child + */ + if (proxy_command_pid > 1) + kill(proxy_command_pid, SIGHUP); + return exit_status; } @@ -763,11 +775,19 @@ x11_get_proto(char **_proto, char **_data) FILE *f; int got_data = 0, i; char *display; + struct stat st; *_proto = proto; *_data = data; proto[0] = data[0] = '\0'; - if (options.xauth_location && (display = getenv("DISPLAY"))) { + if (!options.xauth_location || + (stat(options.xauth_location, &st) == -1)) { + debug("No xauth program."); + } else { + if ((display = getenv("DISPLAY")) == NULL) { + debug("x11_get_proto: DISPLAY not set"); + return; + } /* Try to get Xauthority information for the display. */ if (strncmp(display, "localhost:", 10) == 0) /* @@ -782,7 +802,7 @@ x11_get_proto(char **_proto, char **_data) else snprintf(line, sizeof line, "%s list %.200s 2>" _PATH_DEVNULL, options.xauth_location, display); - debug2("x11_get_proto %s", line); + debug2("x11_get_proto: %s", line); f = popen(line, "r"); if (f && fgets(line, sizeof(line), f) && sscanf(line, "%*s %511s %511s", proto, data) == 2) @@ -801,6 +821,7 @@ x11_get_proto(char **_proto, char **_data) if (!got_data) { u_int32_t rand = 0; + log("Warning: No xauth data; using fake authentication data for X11 forwarding."); strlcpy(proto, "MIT-MAGIC-COOKIE-1", sizeof proto); for (i = 0; i < 16; i++) { if (i % 4 == 0) @@ -850,11 +871,8 @@ check_agent_present(void) { if (options.forward_agent) { /* Clear agent forwarding if we don\'t have an agent. */ - int authfd = ssh_get_authentication_socket(); - if (authfd < 0) + if (!ssh_agent_present()) options.forward_agent = 0; - else - ssh_close_authentication_socket(authfd); } } diff --git a/openssh/ssh_config.5 b/openssh/ssh_config.5 index aecc799..e62bf81 100644 --- a/openssh/ssh_config.5 +++ b/openssh/ssh_config.5 @@ -34,7 +34,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. .\" -.\" $OpenBSD: ssh_config.5,v 1.1 2002/06/20 19:56:07 stevesk Exp $ +.\" $OpenBSD: ssh_config.5,v 1.5 2002/08/29 22:54:10 stevesk Exp $ .Dd September 25, 1999 .Dt SSH_CONFIG 5 .Os @@ -50,29 +50,24 @@ .Nm ssh obtains configuration data from the following sources in the following order: -command line options, -feature-specific user configuration file(s) (see below), +.Bl -enum -offset indent -compact +.It +command-line options +.It user's configuration file -.Pq Pa $HOME/.ssh/config , -and system-wide configuration file -.Pq Pa /etc/ssh/ssh_config . -For compatibility with other -.Nm -versions, the following feature-specific user configuration files -will be processed after the command line options but before the user's -main configuration file, so options that other -.Nm -versions may not support don't need to go in the main configuration file: -.Bl -tag -width Ds -.It Pa $HOME/.ssh/config.gssapi -Read if GSSAPI authentication is supported. This is a good place for -the GssapiAuthentication and GssapiDelegateCredentials options. -.It Pa $HOME/.ssh/config.krb -Read if Kerberos authentication is supported. This is a good place -for the KerberosAuthentication and KerberosTgtPassing options. -.It Pa $HOME/.ssh/config.afs -Read if AFS token passing is supported. This is a good place for the -AfsTokenPassing option. +.Pq Pa $HOME/.ssh/config +.It +GSSAPI configuration file (GssapiAuthentication, GssapiDelegateCredentials) +.Pq Pa $HOME/.ssh/config.gssapi +.It +Kerberos configuration file (KerberosAuthentication, KerberosTgtPassing) +.Pq Pa $HOME/.ssh/config.krb +.It +AFS configuration file (AfsTokenPassing) +.Pq Pa $HOME/.ssh/config.afs +.It +system-wide configuration file +.Pq Pa /etc/ssh/ssh_config .El .Pp For each parameter, the first obtained value @@ -272,6 +267,13 @@ or .Dq no . The default is .Dq no . +.Pp +Agent forwarding should be enabled with caution. Users with the +ability to bypass file permissions on the remote host (for the agent's +Unix-domain socket) can access the local agent through the forwarded +connection. An attacker cannot obtain key material from the agent, +however they can perform operations on the keys that enable them to +authenticate using the identities loaded into the agent. .It Cm ForwardX11 Specifies whether X11 connections will be automatically redirected over the secure channel and @@ -283,6 +285,12 @@ or .Dq no . The default is .Dq no . +.Pp +X11 forwarding should be enabled with caution. Users with the ability +to bypass file permissions on the remote host (for the user's X +authorization database) can access the local X11 display through the +forwarded connection. An attacker may then be able to perform +activities such as keystroke monitoring. .It Cm GatewayPorts Specifies whether remote hosts are allowed to connect to local forwarded ports. @@ -528,7 +536,12 @@ or .Dq no . The default is .Dq no . -This option applies to protocol version 1 only. +This option applies to protocol version 1 only and requires +.Nm ssh +to be setuid root and +.Cm UsePrivilegedPort +to be set to +.Dq yes . .It Cm RhostsRSAAuthentication Specifies whether to try rhosts based authentication with RSA host authentication. @@ -603,6 +616,10 @@ or .Dq no . The default is .Dq no . +If set to +.Dq yes +.Nm ssh +must be setuid root. Note that this option must be set to .Dq yes if @@ -620,7 +637,7 @@ Specifies a file to use for the user host key database instead of .Pa $HOME/.ssh/known_hosts . .It Cm XAuthLocation -Specifies the location of the +Specifies the full pathname of the .Xr xauth 1 program. The default is diff --git a/openssh/sshconnect1.c b/openssh/sshconnect1.c index 86e0e3e..c7845a3 100644 --- a/openssh/sshconnect1.c +++ b/openssh/sshconnect1.c @@ -13,7 +13,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect1.c,v 1.51 2002/05/23 19:24:30 markus Exp $"); +RCSID("$OpenBSD: sshconnect1.c,v 1.52 2002/08/08 13:50:23 aaron Exp $"); #include #include @@ -265,7 +265,7 @@ try_rsa_authentication(int idx) * load the private key. Try first with empty passphrase; if it * fails, ask for a passphrase. */ - if (public->flags && KEY_FLAG_EXT) + if (public->flags & KEY_FLAG_EXT) private = public; else private = key_load_private_type(KEY_RSA1, authfile, "", NULL); diff --git a/openssh/sshconnect2.c b/openssh/sshconnect2.c index d525f64..614c70e 100644 --- a/openssh/sshconnect2.c +++ b/openssh/sshconnect2.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshconnect2.c,v 1.105 2002/06/23 03:30:17 deraadt Exp $"); +RCSID("$OpenBSD: sshconnect2.c,v 1.107 2002/07/01 19:48:46 markus Exp $"); #include "ssh.h" #include "ssh2.h" @@ -117,10 +117,10 @@ ssh_kex2(char *host, struct sockaddr *hostaddr) compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_STOC]); if (options.compression) { myproposal[PROPOSAL_COMP_ALGS_CTOS] = - myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib"; + myproposal[PROPOSAL_COMP_ALGS_STOC] = "zlib,none"; } else { myproposal[PROPOSAL_COMP_ALGS_CTOS] = - myproposal[PROPOSAL_COMP_ALGS_STOC] = "none"; + myproposal[PROPOSAL_COMP_ALGS_STOC] = "none,zlib"; } if (options.macs != NULL) { myproposal[PROPOSAL_MAC_ALGS_CTOS] = @@ -488,7 +488,7 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) clear_auth_state(authctxt); dispatch_set(SSH2_MSG_USERAUTH_PK_OK, NULL); - /* try another method if we did not send a packet*/ + /* try another method if we did not send a packet */ if (sent == 0) userauth(authctxt, NULL); @@ -1180,9 +1180,9 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp, buffer_init(&b); buffer_put_int(&b, packet_get_connection_in()); /* send # of socket */ buffer_put_string(&b, data, datalen); - msg_send(to[1], version, &b); + ssh_msg_send(to[1], version, &b); - if (msg_recv(from[0], &b) < 0) { + if (ssh_msg_recv(from[0], &b) < 0) { error("ssh_keysign: no reply"); buffer_clear(&b); return -1; diff --git a/openssh/sshd.8 b/openssh/sshd.8 index 37a7b58..22ab70e 100644 --- a/openssh/sshd.8 +++ b/openssh/sshd.8 @@ -34,7 +34,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. .\" -.\" $OpenBSD: sshd.8,v 1.186 2002/06/22 16:45:29 stevesk Exp $ +.\" $OpenBSD: sshd.8,v 1.193 2002/09/24 20:59:44 todd Exp $ .Dd September 25, 1999 .Dt SSHD 8 .Os @@ -203,7 +203,7 @@ The default is refuses to start if there is no configuration file. .It Fl g Ar login_grace_time Gives the grace time for clients to authenticate themselves (default -600 seconds). +120 seconds). If the client fails to authenticate the user within this many seconds, the server disconnects and exits. A value of zero indicates no limit. @@ -350,7 +350,11 @@ Sets up basic environment. .It Reads .Pa $HOME/.ssh/environment -if it exists. +if it exists and users are allowed to change their environment. +See the +.Cm PermitUserEnvironment +option in +.Xr sshd_config 5 . .It Changes to user's home directory. .It @@ -385,9 +389,9 @@ Each RSA public key consists of the following fields, separated by spaces: options, bits, exponent, modulus, comment. Each protocol version 2 public key consists of: options, keytype, base64 encoded key, comment. -The options fields -are optional; its presence is determined by whether the line starts -with a number or not (the option field never starts with a number). +The options field +is optional; its presence is determined by whether the line starts +with a number or not (the options field never starts with a number). The bits, exponent, modulus and comment fields give the RSA key for protocol version 1; the comment field is not used for anything (but may be convenient for the @@ -398,7 +402,7 @@ or .Dq ssh-rsa . .Pp Note that lines in this file are usually several hundred bytes long -(because of the size of the RSA key modulus). +(because of the size of the public key encoding). You don't want to type them in; instead, copy the .Pa identity.pub , .Pa id_dsa.pub @@ -417,7 +421,7 @@ The following option specifications are supported (note that option keywords are case-insensitive): .Bl -tag -width Ds .It Cm from="pattern-list" -Specifies that in addition to RSA authentication, the canonical name +Specifies that in addition to public key authentication, the canonical name of the remote host must be present in the comma-separated list of patterns .Pf ( Ql * @@ -429,7 +433,7 @@ patterns negated by prefixing them with .Ql ! ; if the canonical host name matches a negated pattern, the key is not accepted. The purpose -of this option is to optionally increase security: RSA authentication +of this option is to optionally increase security: public key authentication by itself does not trust the network or name servers or anything (but the key); however, if somebody somehow steals the key, the key permits an intruder to log in from anywhere in the world. @@ -447,7 +451,7 @@ one must not request a pty or should specify .Cm no-pty . A quote may be included in the command by quoting it with a backslash. This option might be useful -to restrict certain RSA keys to perform just a specific operation. +to restrict certain public keys to perform just a specific operation. An example might be a key that permits remote backups but nothing else. Note that the client may specify TCP/IP and/or X11 forwarding unless they are explicitly prohibited. @@ -458,6 +462,10 @@ logging in using this key. Environment variables set this way override other default environment values. Multiple options of this type are permitted. +Environment processing is disabled by default and is +controlled via the +.Cm PermitUserEnvironment +option. This option is automatically disabled if .Cm UseLogin is enabled. @@ -578,6 +586,8 @@ These files are created using .Xr ssh-keygen 1 . .It Pa /etc/moduli Contains Diffie-Hellman groups used for the "Diffie-Hellman Group Exchange". +The file format is described in +.Xr moduli 5 . .It Pa /var/empty .Xr chroot 2 directory used by @@ -698,6 +708,10 @@ It can only contain empty lines, comment lines (that start with and assignment lines of the form name=value. The file should be writable only by the user; it need not be readable by anyone else. +Environment processing is disabled by default and is +controlled via the +.Cm PermitUserEnvironment +option. .It Pa $HOME/.ssh/rc If this file exists, it is run with /bin/sh after reading the environment files but before starting the user's shell or command. @@ -723,12 +737,12 @@ something similar to: if read proto cookie && [ -n "$DISPLAY" ]; then if [ `echo $DISPLAY | cut -c1-10` = 'localhost:' ]; then # X11UseLocalhost=yes - xauth add unix:`echo $DISPLAY | + echo add unix:`echo $DISPLAY | cut -c11-` $proto $cookie else # X11UseLocalhost=no - xauth add $DISPLAY $proto $cookie - fi + echo add $DISPLAY $proto $cookie + fi | xauth -q - fi .Ed .Pp diff --git a/openssh/sshd.c b/openssh/sshd.c index 21b1059..07de2b5 100644 --- a/openssh/sshd.c +++ b/openssh/sshd.c @@ -42,7 +42,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: sshd.c,v 1.251 2002/06/25 18:51:04 markus Exp $"); +RCSID("$OpenBSD: sshd.c,v 1.260 2002/09/27 10:42:09 mickey Exp $"); #include #include @@ -312,11 +312,8 @@ grace_alarm_handler(int sig) { /* XXX no idea how fix this signal handler */ - /* Close the connection. */ - packet_close(); - /* Log error and exit. */ - fatal("Timeout before authentication for %s.", get_remote_ipaddr()); + fatal("Timeout before authentication for %s", get_remote_ipaddr()); } /* @@ -329,7 +326,7 @@ grace_alarm_handler(int sig) static void generate_ephemeral_server_key(void) { - u_int32_t rand = 0; + u_int32_t rnd = 0; int i; verbose("Generating %s%d bit RSA key.", @@ -342,9 +339,9 @@ generate_ephemeral_server_key(void) for (i = 0; i < SSH_SESSION_KEY_LENGTH; i++) { if (i % 4 == 0) - rand = arc4random(); - sensitive_data.ssh1_cookie[i] = rand & 0xff; - rand >>= 8; + rnd = arc4random(); + sensitive_data.ssh1_cookie[i] = rnd & 0xff; + rnd >>= 8; } arc4random_stir(); } @@ -436,6 +433,12 @@ sshd_exchange_identification(int sock_in, int sock_out) compat_datafellows(remote_version); + if (datafellows & SSH_BUG_PROBE) { + log("probed from %s with %s. Don't panic.", + get_remote_ipaddr(), client_version_string); + fatal_cleanup(); + } + if (datafellows & SSH_BUG_SCANNER) { log("scanned from %s with %s. Don't panic.", get_remote_ipaddr(), client_version_string); @@ -538,8 +541,8 @@ demote_sensitive_data(void) static void privsep_preauth_child(void) { - u_int32_t rand[256]; - gid_t gidset[2]; + u_int32_t rnd[256]; + gid_t gidset[1]; struct passwd *pw; int i; @@ -547,8 +550,8 @@ privsep_preauth_child(void) privsep_challenge_enable(); for (i = 0; i < 256; i++) - rand[i] = arc4random(); - RAND_seed(rand, sizeof(rand)); + rnd[i] = arc4random(); + RAND_seed(rnd, sizeof(rnd)); /* Demote the private keys to public keys. */ demote_sensitive_data(); @@ -559,7 +562,7 @@ privsep_preauth_child(void) memset(pw->pw_passwd, 0, strlen(pw->pw_passwd)); endpwent(); - /* Change our root directory*/ + /* Change our root directory */ if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1) fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR, strerror(errno)); @@ -582,7 +585,7 @@ privsep_preauth_child(void) #endif } -static Authctxt* +static Authctxt * privsep_preauth(void) { Authctxt *authctxt = NULL; @@ -598,6 +601,8 @@ privsep_preauth(void) 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); close(pmonitor->m_recvfd); @@ -611,6 +616,10 @@ privsep_preauth(void) 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 */ @@ -633,7 +642,7 @@ privsep_postauth(Authctxt *authctxt) /* XXX - Remote port forwarding */ x_authctxt = authctxt; -#ifdef BROKEN_FD_PASSING +#ifdef DISABLE_FD_PASSING if (1) { #else if (authctxt->pw->pw_uid == 0 || options.use_login) { @@ -658,6 +667,8 @@ privsep_postauth(Authctxt *authctxt) 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); close(pmonitor->m_recvfd); monitor_child_postauth(pmonitor); @@ -810,7 +821,6 @@ main(int ac, char **av) const char *remote_ip; int remote_port; FILE *f; - struct linger linger; struct addrinfo *ai; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; int listen_sock, maxfd; @@ -915,6 +925,10 @@ main(int ac, char **av) break; case 'u': utmp_len = atoi(optarg); + if (utmp_len > MAXHOSTNAMELEN) { + fprintf(stderr, "Invalid utmp length.\n"); + exit(1); + } break; case 'o': if (process_server_config_line(&options, optarg, @@ -941,7 +955,7 @@ main(int ac, char **av) SYSLOG_FACILITY_AUTH : options.log_facility, !inetd_flag); -#ifdef _CRAY +#ifdef _UNICOS /* Cray can define user privs drop all prives now! * Not needed on PRIV_SU systems! */ @@ -965,7 +979,8 @@ main(int ac, char **av) debug("sshd version %.100s", SSH_VERSION); /* load private host keys */ - sensitive_data.host_keys = xmalloc(options.num_host_key_files*sizeof(Key*)); + sensitive_data.host_keys = xmalloc(options.num_host_key_files * + sizeof(Key *)); for (i = 0; i < options.num_host_key_files; i++) sensitive_data.host_keys[i] = NULL; sensitive_data.server_key = NULL; @@ -1047,7 +1062,14 @@ main(int ac, char **av) (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); } @@ -1151,17 +1173,12 @@ main(int ac, char **av) continue; } /* - * Set socket options. We try to make the port - * reusable and have it close as fast as possible - * without waiting in unnecessary wait states on - * close. + * Set socket options. + * Allow local port reuse in TIME_WAIT. */ - setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, - &on, sizeof(on)); - linger.l_onoff = 1; - linger.l_linger = 5; - setsockopt(listen_sock, SOL_SOCKET, SO_LINGER, - &linger, sizeof(linger)); + if (setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, + &on, sizeof(on)) == -1) + error("setsockopt SO_REUSEADDR: %s", strerror(errno)); debug("Bind to port %s on %s.", strport, ntop); @@ -1410,16 +1427,6 @@ main(int ac, char **av) signal(SIGCHLD, SIG_DFL); signal(SIGINT, SIG_DFL); - /* - * Set socket options for the connection. We want the socket to - * close as fast as possible without waiting for anything. If the - * connection is not a socket, these will do nothing. - */ - /* setsockopt(sock_in, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(on)); */ - linger.l_onoff = 1; - linger.l_linger = 5; - setsockopt(sock_in, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)); - /* Set keepalives if requested. */ if (options.keepalives && setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, @@ -1607,7 +1614,7 @@ do_ssh1_kex(void) u_char session_key[SSH_SESSION_KEY_LENGTH]; u_char cookie[8]; u_int cipher_type, auth_mask, protocol_flags; - u_int32_t rand = 0; + u_int32_t rnd = 0; /* * Generate check bytes that the client must send back in the user @@ -1620,9 +1627,9 @@ do_ssh1_kex(void) */ for (i = 0; i < 8; i++) { if (i % 4 == 0) - rand = arc4random(); - cookie[i] = rand & 0xff; - rand >>= 8; + rnd = arc4random(); + cookie[i] = rnd & 0xff; + rnd >>= 8; } /* diff --git a/openssh/sshd_config.5 b/openssh/sshd_config.5 index 9c7c583..433bfab 100644 --- a/openssh/sshd_config.5 +++ b/openssh/sshd_config.5 @@ -34,7 +34,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. .\" -.\" $OpenBSD: sshd_config.5,v 1.4 2002/06/22 16:45:29 stevesk Exp $ +.\" $OpenBSD: sshd_config.5,v 1.13 2002/09/16 20:12:11 stevesk Exp $ .Dd September 25, 1999 .Dt SSHD_CONFIG 5 .Os @@ -400,7 +400,7 @@ options must precede this option for non port qualified addresses. The server disconnects after this time if the user has not successfully logged in. If the value is 0, there is no time limit. -The default is 600 (seconds). +The default is 120 seconds. .It Cm LogLevel Gives the verbosity level that is used when logging messages from .Nm sshd . @@ -486,6 +486,20 @@ for root. If this option is set to .Dq no root is not allowed to login. +.It Cm PermitUserEnvironment +Specifies whether +.Pa ~/.ssh/environment +and +.Cm environment= +options in +.Pa ~/.ssh/authorized_keys +are processed by +.Nm sshd . +The default is +.Dq no . +Enabling environment processing may enable users to bypass access +restrictions in some configurations using mechanisms such as +.Ev LD_PRELOAD . .It Cm PidFile Specifies the file that contains the process ID of the .Nm sshd @@ -520,7 +534,7 @@ The default is .It Cm Protocol Specifies the protocol versions .Nm sshd -should support. +supports. The possible values are .Dq 1 and @@ -528,6 +542,13 @@ and Multiple versions must be comma-separated. The default is .Dq 2,1 . +Note that the order of the protocol list does not indicate preference, +because the client selects among multiple protocol versions offered +by the server. +Specifying +.Dq 2,1 +is identical to +.Dq 1,2 . .It Cm PubkeyAuthentication Specifies whether public key authentication is allowed. The default is @@ -630,10 +651,35 @@ from interfering with real X11 servers. The default is 10. .It Cm X11Forwarding Specifies whether X11 forwarding is permitted. +The argument must be +.Dq yes +or +.Dq no . The default is .Dq no . -Note that disabling X11 forwarding does not improve security in any -way, as users can always install their own forwarders. +.Pp +When X11 forwarding is enabled, there may be additional exposure to +the server and to client displays if the +.Nm sshd +proxy display is configured to listen on the wildcard address (see +.Cm X11UseLocalhost +below), however this is not the default. +Additionally, the authentication spoofing and authentication data +verification and substitution occur on the client side. +The security risk of using X11 forwarding is that the client's X11 +display server may be exposed to attack when the ssh client requests +forwarding (see the warnings for +.Cm ForwardX11 +in +.Xr ssh_config 5 ). +A system administrator may have a stance in which they want to +protect clients that may expose themselves to attack by unwittingly +requesting X11 forwarding, which can warrant a +.Dq no +setting. +.Pp +Note that disabling X11 forwarding does not prevent users from +forwarding X11 traffic, as users can always install their own forwarders. X11 forwarding is automatically disabled if .Cm UseLogin is enabled. @@ -648,7 +694,7 @@ hostname part of the .Ev DISPLAY environment variable to .Dq localhost . -This prevents remote hosts from connecting to the fake display. +This prevents remote hosts from connecting to the proxy display. However, some older X11 clients may not function with this configuration. .Cm X11UseLocalhost @@ -663,7 +709,7 @@ or The default is .Dq yes . .It Cm XAuthLocation -Specifies the location of the +Specifies the full pathname of the .Xr xauth 1 program. The default is @@ -675,7 +721,7 @@ The default is command-line arguments and configuration file options that specify time may be expressed using a sequence of the form: .Sm off -.Ar time Oo Ar qualifier Oc , +.Ar time Op Ar qualifier , .Sm on where .Ar time -- 2.45.1