aboutsummaryrefslogtreecommitdiff
path: root/crypto
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2005-06-05 15:46:09 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>2005-06-05 15:46:09 +0000
commitaa49c9264c97095f0d273288be7cb0b4b06658ab (patch)
tree7d41ca8690f59b7463bd4d5fefde78dac8a00e60 /crypto
parent6dbd30e786949c7c1f38b2513970ef79d11bf413 (diff)
downloadsrc-aa49c9264c97095f0d273288be7cb0b4b06658ab.tar.gz
src-aa49c9264c97095f0d273288be7cb0b4b06658ab.zip
Resolve conflicts.
Notes
Notes: svn path=/head/; revision=147005
Diffstat (limited to 'crypto')
-rw-r--r--crypto/openssh/LICENCE5
-rw-r--r--crypto/openssh/acconfig.h5
-rw-r--r--crypto/openssh/auth-chall.c7
-rw-r--r--crypto/openssh/auth-krb5.c5
-rw-r--r--crypto/openssh/auth-pam.c167
-rw-r--r--crypto/openssh/auth-pam.h3
-rw-r--r--crypto/openssh/auth-passwd.c64
-rw-r--r--crypto/openssh/auth-rsa.c11
-rw-r--r--crypto/openssh/auth.c84
-rw-r--r--crypto/openssh/auth.h8
-rw-r--r--crypto/openssh/auth1.c33
-rw-r--r--crypto/openssh/auth2-chall.c35
-rw-r--r--crypto/openssh/auth2-kbdint.c2
-rw-r--r--crypto/openssh/auth2.c31
-rw-r--r--crypto/openssh/authfile.c17
-rw-r--r--crypto/openssh/bufaux.c215
-rw-r--r--crypto/openssh/canohost.c23
-rw-r--r--crypto/openssh/channels.c99
-rw-r--r--crypto/openssh/channels.h11
-rw-r--r--crypto/openssh/cipher.c10
-rw-r--r--crypto/openssh/compat.c20
-rw-r--r--crypto/openssh/compat.h3
-rw-r--r--crypto/openssh/configure.ac547
-rw-r--r--crypto/openssh/hostfile.c123
-rw-r--r--crypto/openssh/includes.h2
-rw-r--r--crypto/openssh/key.c38
-rw-r--r--crypto/openssh/loginrec.c824
-rw-r--r--crypto/openssh/monitor.c75
-rw-r--r--crypto/openssh/monitor.h1
-rw-r--r--crypto/openssh/monitor_wrap.c35
-rw-r--r--crypto/openssh/monitor_wrap.h6
-rw-r--r--crypto/openssh/openbsd-compat/fake-rfc2553.h3
-rw-r--r--crypto/openssh/readconf.c173
-rw-r--r--crypto/openssh/readconf.h16
-rw-r--r--crypto/openssh/scp.c17
-rw-r--r--crypto/openssh/servconf.c95
-rw-r--r--crypto/openssh/servconf.h3
-rw-r--r--crypto/openssh/session.c71
-rw-r--r--crypto/openssh/ssh-add.c6
-rw-r--r--crypto/openssh/ssh-agent.c30
-rw-r--r--crypto/openssh/ssh-keyscan.c18
-rw-r--r--crypto/openssh/ssh.11
-rw-r--r--crypto/openssh/ssh.c200
-rw-r--r--crypto/openssh/ssh.h9
-rw-r--r--crypto/openssh/ssh_config8
-rw-r--r--crypto/openssh/ssh_config.5103
-rw-r--r--crypto/openssh/sshconnect.c58
-rw-r--r--crypto/openssh/sshd.852
-rw-r--r--crypto/openssh/sshd.c77
-rw-r--r--crypto/openssh/sshd_config5
-rw-r--r--crypto/openssh/sshd_config.541
-rw-r--r--crypto/openssh/version.h5
52 files changed, 2431 insertions, 1069 deletions
diff --git a/crypto/openssh/LICENCE b/crypto/openssh/LICENCE
index d8c157304dc5..ae03eb3a7d49 100644
--- a/crypto/openssh/LICENCE
+++ b/crypto/openssh/LICENCE
@@ -97,7 +97,7 @@ OpenSSH contains no GPL code.
* <http://www.core-sdi.com>
3)
- ssh-keygen was contributed by David Mazieres under a BSD-style
+ ssh-keyscan was contributed by David Mazieres under a BSD-style
license.
* Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
@@ -203,6 +203,7 @@ OpenSSH contains no GPL code.
Wayne Schroeder
William Jones
Darren Tucker
+ Sun Microsystems
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -329,4 +330,4 @@ OpenSSH contains no GPL code.
------
-$OpenBSD: LICENCE,v 1.18 2003/11/21 11:57:02 djm Exp $
+$OpenBSD: LICENCE,v 1.19 2004/08/30 09:18:08 markus Exp $
diff --git a/crypto/openssh/acconfig.h b/crypto/openssh/acconfig.h
index a42facf3c768..2daf603a0576 100644
--- a/crypto/openssh/acconfig.h
+++ b/crypto/openssh/acconfig.h
@@ -1,4 +1,4 @@
-/* $Id: acconfig.h,v 1.180 2004/08/16 13:12:06 dtucker Exp $ */
+/* $Id: acconfig.h,v 1.181 2005/02/25 23:07:38 dtucker Exp $ */
/* $FreeBSD$ */
/*
@@ -53,9 +53,6 @@
#undef SPT_TYPE
#undef SPT_PADCHAR
-/* setgroups() NOOP allowed */
-#undef SETGROUPS_NOOP
-
/* SCO workaround */
#undef BROKEN_SYS_TERMIO_H
diff --git a/crypto/openssh/auth-chall.c b/crypto/openssh/auth-chall.c
index dbe04cdf2d40..248aca99fa96 100644
--- a/crypto/openssh/auth-chall.c
+++ b/crypto/openssh/auth-chall.c
@@ -29,11 +29,13 @@ RCSID("$FreeBSD$");
#include "auth.h"
#include "log.h"
#include "xmalloc.h"
+#include "servconf.h"
/* limited protocol v1 interface to kbd-interactive authentication */
extern KbdintDevice *devices[];
static KbdintDevice *device;
+extern ServerOptions options;
char *
get_challenge(Authctxt *authctxt)
@@ -42,6 +44,11 @@ get_challenge(Authctxt *authctxt)
u_int i, numprompts;
u_int *echo_on;
+#ifdef USE_PAM
+ if (!options.use_pam)
+ remove_kbdint_device("pam");
+#endif
+
device = devices[0]; /* we always use the 1st device for protocol 1 */
if (device == NULL)
return NULL;
diff --git a/crypto/openssh/auth-krb5.c b/crypto/openssh/auth-krb5.c
index acd2ddac460e..a8c69fae45e5 100644
--- a/crypto/openssh/auth-krb5.c
+++ b/crypto/openssh/auth-krb5.c
@@ -188,6 +188,11 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
snprintf(authctxt->krb5_ccname, len, "FILE:%s",
authctxt->krb5_ticket_file);
+#ifdef USE_PAM
+ if (options.use_pam)
+ do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname);
+#endif
+
out:
restore_uid();
diff --git a/crypto/openssh/auth-pam.c b/crypto/openssh/auth-pam.c
index 7690c38b0f89..cc11445a7019 100644
--- a/crypto/openssh/auth-pam.c
+++ b/crypto/openssh/auth-pam.c
@@ -47,7 +47,7 @@
/* Based on $xFreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */
#include "includes.h"
-RCSID("$Id: auth-pam.c,v 1.114 2004/08/16 13:12:06 dtucker Exp $");
+RCSID("$Id: auth-pam.c,v 1.122 2005/05/25 06:18:10 dtucker Exp $");
RCSID("$FreeBSD$");
#ifdef USE_PAM
@@ -77,7 +77,17 @@ extern Buffer loginmsg;
extern int compat20;
extern u_int utmp_len;
+/* so we don't silently change behaviour */
#ifdef USE_POSIX_THREADS
+# error "USE_POSIX_THREADS replaced by UNSUPPORTED_POSIX_THREADS_HACK"
+#endif
+
+/*
+ * Formerly known as USE_POSIX_THREADS, using this is completely unsupported
+ * and generally a bad idea. Use at own risk and do not expect support if
+ * this breaks.
+ */
+#ifdef UNSUPPORTED_POSIX_THREADS_HACK
#include <pthread.h>
/*
* Avoid namespace clash when *not* using pthreads for systems *with*
@@ -99,7 +109,7 @@ struct pam_ctxt {
static void sshpam_free_ctx(void *);
static struct pam_ctxt *cleanup_ctxt;
-#ifndef USE_POSIX_THREADS
+#ifndef UNSUPPORTED_POSIX_THREADS_HACK
/*
* Simulate threads with processes.
*/
@@ -187,6 +197,7 @@ static int sshpam_account_status = -1;
static char **sshpam_env = NULL;
static Authctxt *sshpam_authctxt = NULL;
static const char *sshpam_password = NULL;
+static char badpw[] = "\b\n\r\177INCORRECT";
/* Some PAM implementations don't implement this */
#ifndef HAVE_PAM_GETENVLIST
@@ -255,7 +266,7 @@ import_environments(Buffer *b)
debug3("PAM: %s entering", __func__);
-#ifndef USE_POSIX_THREADS
+#ifndef UNSUPPORTED_POSIX_THREADS_HACK
/* Import variables set by do_pam_account */
sshpam_account_status = buffer_get_int(b);
sshpam_password_change_required(buffer_get_int(b));
@@ -384,7 +395,7 @@ sshpam_thread(void *ctxtp)
struct pam_conv sshpam_conv;
int flags = (options.permit_empty_passwd == 0 ?
PAM_DISALLOW_NULL_AUTHTOK : 0);
-#ifndef USE_POSIX_THREADS
+#ifndef UNSUPPORTED_POSIX_THREADS_HACK
extern char **environ;
char **env_from_pam;
u_int i;
@@ -428,7 +439,7 @@ sshpam_thread(void *ctxtp)
buffer_put_cstring(&buffer, "OK");
-#ifndef USE_POSIX_THREADS
+#ifndef UNSUPPORTED_POSIX_THREADS_HACK
/* Export variables set by do_pam_account */
buffer_put_int(&buffer, sshpam_account_status);
buffer_put_int(&buffer, sshpam_authctxt->force_pwchange);
@@ -447,7 +458,7 @@ sshpam_thread(void *ctxtp)
buffer_put_int(&buffer, i);
for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++)
buffer_put_cstring(&buffer, env_from_pam[i]);
-#endif /* USE_POSIX_THREADS */
+#endif /* UNSUPPORTED_POSIX_THREADS_HACK */
/* XXX - can't do much about an error here */
ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer);
@@ -491,6 +502,51 @@ sshpam_null_conv(int n, struct pam_message **msg,
static struct pam_conv null_conv = { sshpam_null_conv, NULL };
+static int
+sshpam_store_conv(int n, struct pam_message **msg,
+ struct pam_response **resp, void *data)
+{
+ struct pam_response *reply;
+ int i;
+ size_t len;
+
+ debug3("PAM: %s called with %d messages", __func__, n);
+ *resp = NULL;
+
+ if (n <= 0 || n > PAM_MAX_NUM_MSG)
+ return (PAM_CONV_ERR);
+
+ if ((reply = malloc(n * sizeof(*reply))) == NULL)
+ return (PAM_CONV_ERR);
+ memset(reply, 0, n * sizeof(*reply));
+
+ for (i = 0; i < n; ++i) {
+ switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
+ case PAM_ERROR_MSG:
+ case PAM_TEXT_INFO:
+ len = strlen(PAM_MSG_MEMBER(msg, i, msg));
+ buffer_append(&loginmsg, PAM_MSG_MEMBER(msg, i, msg), len);
+ buffer_append(&loginmsg, "\n", 1 );
+ reply[i].resp_retcode = PAM_SUCCESS;
+ break;
+ default:
+ goto fail;
+ }
+ }
+ *resp = reply;
+ return (PAM_SUCCESS);
+
+ fail:
+ for(i = 0; i < n; i++) {
+ if (reply[i].resp != NULL)
+ xfree(reply[i].resp);
+ }
+ xfree(reply);
+ return (PAM_CONV_ERR);
+}
+
+static struct pam_conv store_conv = { sshpam_store_conv, NULL };
+
void
sshpam_cleanup(void)
{
@@ -528,7 +584,7 @@ sshpam_init(Authctxt *authctxt)
}
debug("PAM: initializing for \"%s\"", user);
sshpam_err =
- pam_start(SSHD_PAM_SERVICE, user, &null_conv, &sshpam_handle);
+ pam_start(SSHD_PAM_SERVICE, user, &store_conv, &sshpam_handle);
sshpam_authctxt = authctxt;
if (sshpam_err != PAM_SUCCESS) {
@@ -610,7 +666,7 @@ sshpam_query(void *ctx, char **name, char **info,
size_t plen;
u_char type;
char *msg;
- size_t len;
+ size_t len, mlen;
debug3("PAM: %s entering", __func__);
buffer_init(&buffer);
@@ -623,22 +679,27 @@ sshpam_query(void *ctx, char **name, char **info,
while (ssh_msg_recv(ctxt->pam_psock, &buffer) == 0) {
type = buffer_get_char(&buffer);
msg = buffer_get_string(&buffer, NULL);
+ mlen = strlen(msg);
switch (type) {
case PAM_PROMPT_ECHO_ON:
case PAM_PROMPT_ECHO_OFF:
*num = 1;
- len = plen + strlen(msg) + 1;
+ len = plen + mlen + 1;
**prompts = xrealloc(**prompts, len);
- plen += snprintf(**prompts + plen, len, "%s", msg);
+ strlcpy(**prompts + plen, msg, len - plen);
+ plen += mlen;
**echo_on = (type == PAM_PROMPT_ECHO_ON);
xfree(msg);
return (0);
case PAM_ERROR_MSG:
case PAM_TEXT_INFO:
/* accumulate messages */
- len = plen + strlen(msg) + 2;
+ len = plen + mlen + 2;
**prompts = xrealloc(**prompts, len);
- plen += snprintf(**prompts + plen, len, "%s\n", msg);
+ strlcpy(**prompts + plen, msg, len - plen);
+ plen += mlen;
+ strlcat(**prompts + plen, "\n", len - plen);
+ plen++;
xfree(msg);
break;
case PAM_SUCCESS:
@@ -652,6 +713,12 @@ sshpam_query(void *ctx, char **name, char **info,
**prompts = NULL;
}
if (type == PAM_SUCCESS) {
+ if (!sshpam_authctxt->valid ||
+ (sshpam_authctxt->pw->pw_uid == 0 &&
+ options.permit_root_login != PERMIT_YES))
+ fatal("Internal error: PAM auth "
+ "succeeded when it should have "
+ "failed");
import_environments(&buffer);
*num = 0;
**echo_on = 0;
@@ -697,7 +764,12 @@ sshpam_respond(void *ctx, u_int num, char **resp)
return (-1);
}
buffer_init(&buffer);
- buffer_put_cstring(&buffer, *resp);
+ if (sshpam_authctxt->valid &&
+ (sshpam_authctxt->pw->pw_uid != 0 ||
+ options.permit_root_login == PERMIT_YES))
+ buffer_put_cstring(&buffer, *resp);
+ else
+ buffer_put_cstring(&buffer, badpw);
if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer) == -1) {
buffer_free(&buffer);
return (-1);
@@ -760,11 +832,13 @@ finish_pam(void)
u_int
do_pam_account(void)
{
+ debug("%s: called", __func__);
if (sshpam_account_status != -1)
return (sshpam_account_status);
sshpam_err = pam_acct_mgmt(sshpam_handle, 0);
- debug3("PAM: %s pam_acct_mgmt = %d", __func__, sshpam_err);
+ debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err,
+ pam_strerror(sshpam_handle, sshpam_err));
if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) {
sshpam_account_status = 0;
@@ -794,7 +868,7 @@ void
do_pam_setcred(int init)
{
sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
- (const void *)&null_conv);
+ (const void *)&store_conv);
if (sshpam_err != PAM_SUCCESS)
fatal("PAM: failed to set PAM_CONV: %s",
pam_strerror(sshpam_handle, sshpam_err));
@@ -895,51 +969,6 @@ do_pam_chauthtok(void)
pam_strerror(sshpam_handle, sshpam_err));
}
-static int
-sshpam_store_conv(int n, struct pam_message **msg,
- struct pam_response **resp, void *data)
-{
- struct pam_response *reply;
- int i;
- size_t len;
-
- debug3("PAM: %s called with %d messages", __func__, n);
- *resp = NULL;
-
- if (n <= 0 || n > PAM_MAX_NUM_MSG)
- return (PAM_CONV_ERR);
-
- if ((reply = malloc(n * sizeof(*reply))) == NULL)
- return (PAM_CONV_ERR);
- memset(reply, 0, n * sizeof(*reply));
-
- for (i = 0; i < n; ++i) {
- switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
- case PAM_ERROR_MSG:
- case PAM_TEXT_INFO:
- len = strlen(PAM_MSG_MEMBER(msg, i, msg));
- buffer_append(&loginmsg, PAM_MSG_MEMBER(msg, i, msg), len);
- buffer_append(&loginmsg, "\n", 1 );
- reply[i].resp_retcode = PAM_SUCCESS;
- break;
- default:
- goto fail;
- }
- }
- *resp = reply;
- return (PAM_SUCCESS);
-
- fail:
- for(i = 0; i < n; i++) {
- if (reply[i].resp != NULL)
- xfree(reply[i].resp);
- }
- xfree(reply);
- return (PAM_CONV_ERR);
-}
-
-static struct pam_conv store_conv = { sshpam_store_conv, NULL };
-
void
do_pam_session(void)
{
@@ -950,10 +979,21 @@ do_pam_session(void)
fatal("PAM: failed to set PAM_CONV: %s",
pam_strerror(sshpam_handle, sshpam_err));
sshpam_err = pam_open_session(sshpam_handle, 0);
- if (sshpam_err != PAM_SUCCESS)
- fatal("PAM: pam_open_session(): %s",
+ if (sshpam_err == PAM_SUCCESS)
+ sshpam_session_open = 1;
+ else {
+ sshpam_session_open = 0;
+ disable_forwarding();
+ error("PAM: pam_open_session(): %s",
pam_strerror(sshpam_handle, sshpam_err));
- sshpam_session_open = 1;
+ }
+
+}
+
+int
+is_pam_session_open(void)
+{
+ return sshpam_session_open;
}
/*
@@ -1076,7 +1116,6 @@ sshpam_auth_passwd(Authctxt *authctxt, const char *password)
{
int flags = (options.permit_empty_passwd == 0 ?
PAM_DISALLOW_NULL_AUTHTOK : 0);
- static char badpw[] = "\b\n\r\177INCORRECT";
if (!options.use_pam || sshpam_handle == NULL)
fatal("PAM: %s called when PAM disabled or failed to "
diff --git a/crypto/openssh/auth-pam.h b/crypto/openssh/auth-pam.h
index b4c3311b1318..afdc66e819c5 100644
--- a/crypto/openssh/auth-pam.h
+++ b/crypto/openssh/auth-pam.h
@@ -1,4 +1,4 @@
-/* $Id: auth-pam.h,v 1.26 2004/05/30 10:43:59 dtucker Exp $ */
+/* $Id: auth-pam.h,v 1.27 2004/09/11 12:17:26 dtucker Exp $ */
/* $FreeBSD$ */
/*
@@ -46,5 +46,6 @@ void free_pam_environment(char **);
void sshpam_thread_cleanup(void);
void sshpam_cleanup(void);
int sshpam_auth_passwd(Authctxt *, const char *);
+int is_pam_session_open(void);
#endif /* USE_PAM */
diff --git a/crypto/openssh/auth-passwd.c b/crypto/openssh/auth-passwd.c
index 1b3977590b1b..3ce5ba445007 100644
--- a/crypto/openssh/auth-passwd.c
+++ b/crypto/openssh/auth-passwd.c
@@ -36,17 +36,26 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: auth-passwd.c,v 1.31 2004/01/30 09:48:57 markus Exp $");
+RCSID("$OpenBSD: auth-passwd.c,v 1.33 2005/01/24 11:47:13 dtucker Exp $");
RCSID("$FreeBSD$");
#include "packet.h"
+#include "buffer.h"
#include "log.h"
#include "servconf.h"
#include "auth.h"
#include "auth-options.h"
+extern Buffer loginmsg;
extern ServerOptions options;
-int sys_auth_passwd(Authctxt *, const char *);
+
+#ifdef HAVE_LOGIN_CAP
+extern login_cap_t *lc;
+#endif
+
+
+#define DAY (24L * 60 * 60) /* 1 day in seconds */
+#define TWO_WEEKS (2L * 7 * DAY) /* 2 weeks in seconds */
void
disable_forwarding(void)
@@ -64,7 +73,7 @@ int
auth_password(Authctxt *authctxt, const char *password)
{
struct passwd * pw = authctxt->pw;
- int ok = authctxt->valid;
+ int result, ok = authctxt->valid;
#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
static int expire_checked = 0;
#endif
@@ -101,22 +110,57 @@ auth_password(Authctxt *authctxt, const char *password)
#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
if (!expire_checked) {
expire_checked = 1;
- if (auth_shadow_pwexpired(authctxt)) {
- disable_forwarding();
+ if (auth_shadow_pwexpired(authctxt))
authctxt->force_pwchange = 1;
- }
}
#endif
-
- return (sys_auth_passwd(authctxt, password) && ok);
+ result = sys_auth_passwd(authctxt, password);
+ if (authctxt->force_pwchange)
+ disable_forwarding();
+ return (result && ok);
}
#ifdef BSD_AUTH
+static void
+warn_expiry(Authctxt *authctxt, auth_session_t *as)
+{
+ char buf[256];
+ quad_t pwtimeleft, actimeleft, daysleft, pwwarntime, acwarntime;
+
+ pwwarntime = acwarntime = TWO_WEEKS;
+
+ pwtimeleft = auth_check_change(as);
+ actimeleft = auth_check_expire(as);
+#ifdef HAVE_LOGIN_CAP
+ if (authctxt->valid) {
+ pwwarntime = login_getcaptime(lc, "password-warn", TWO_WEEKS,
+ TWO_WEEKS);
+ acwarntime = login_getcaptime(lc, "expire-warn", TWO_WEEKS,
+ TWO_WEEKS);
+ }
+#endif
+ if (pwtimeleft != 0 && pwtimeleft < pwwarntime) {
+ daysleft = pwtimeleft / DAY + 1;
+ snprintf(buf, sizeof(buf),
+ "Your password will expire in %lld day%s.\n",
+ daysleft, daysleft == 1 ? "" : "s");
+ buffer_append(&loginmsg, buf, strlen(buf));
+ }
+ if (actimeleft != 0 && actimeleft < acwarntime) {
+ daysleft = actimeleft / DAY + 1;
+ snprintf(buf, sizeof(buf),
+ "Your account will expire in %lld day%s.\n",
+ daysleft, daysleft == 1 ? "" : "s");
+ buffer_append(&loginmsg, buf, strlen(buf));
+ }
+}
+
int
sys_auth_passwd(Authctxt *authctxt, const char *password)
{
struct passwd *pw = authctxt->pw;
auth_session_t *as;
+ static int expire_checked = 0;
as = auth_usercheck(pw->pw_name, authctxt->style, "auth-ssh",
(char *)password);
@@ -126,6 +170,10 @@ sys_auth_passwd(Authctxt *authctxt, const char *password)
authctxt->force_pwchange = 1;
return (1);
} else {
+ if (!expire_checked) {
+ expire_checked = 1;
+ warn_expiry(authctxt, as);
+ }
return (auth_close(as));
}
}
diff --git a/crypto/openssh/auth-rsa.c b/crypto/openssh/auth-rsa.c
index 16369d47c80d..4378008d3616 100644
--- a/crypto/openssh/auth-rsa.c
+++ b/crypto/openssh/auth-rsa.c
@@ -14,7 +14,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: auth-rsa.c,v 1.60 2004/06/21 17:36:31 avsm Exp $");
+RCSID("$OpenBSD: auth-rsa.c,v 1.62 2004/12/11 01:48:56 dtucker Exp $");
#include <openssl/rsa.h>
#include <openssl/md5.h>
@@ -33,6 +33,7 @@ RCSID("$OpenBSD: auth-rsa.c,v 1.60 2004/06/21 17:36:31 avsm Exp $");
#include "hostfile.h"
#include "monitor_wrap.h"
#include "ssh.h"
+#include "misc.h"
/* import */
extern ServerOptions options;
@@ -49,7 +50,7 @@ extern u_char session_id[16];
* options bits e n comment
* where bits, e and n are decimal numbers,
* and comment is any string of characters up to newline. The maximum
- * length of a line is 8000 characters. See the documentation for a
+ * length of a line is SSH_MAX_PUBKEY_BYTES characters. See sshd(8) for a
* description of the options.
*/
@@ -152,7 +153,7 @@ auth_rsa_challenge_dialog(Key *key)
int
auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
{
- char line[8192], *file;
+ char line[SSH_MAX_PUBKEY_BYTES], *file;
int allowed = 0;
u_int bits;
FILE *f;
@@ -201,12 +202,10 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
* found, perform a challenge-response dialog to verify that the
* user really has the corresponding private key.
*/
- while (fgets(line, sizeof(line), f)) {
+ while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
char *cp;
char *key_options;
- linenum++;
-
/* Skip leading whitespace, empty and comment lines. */
for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
;
diff --git a/crypto/openssh/auth.c b/crypto/openssh/auth.c
index 624a34a9a75b..9419b660d244 100644
--- a/crypto/openssh/auth.c
+++ b/crypto/openssh/auth.c
@@ -23,7 +23,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: auth.c,v 1.56 2004/07/28 09:40:29 markus Exp $");
+RCSID("$OpenBSD: auth.c,v 1.58 2005/03/14 11:44:42 dtucker Exp $");
RCSID("$FreeBSD$");
#ifdef HAVE_LOGIN_H
@@ -51,6 +51,8 @@ RCSID("$FreeBSD$");
#include "misc.h"
#include "bufaux.h"
#include "packet.h"
+#include "loginrec.h"
+#include "monitor_wrap.h"
/* import */
extern ServerOptions options;
@@ -144,7 +146,8 @@ allowed_user(struct passwd * pw)
return 0;
}
- if (options.num_deny_users > 0 || options.num_allow_users > 0) {
+ if (options.num_deny_users > 0 || options.num_allow_users > 0 ||
+ options.num_deny_groups > 0 || options.num_allow_groups > 0) {
hostname = get_canonical_hostname(options.use_dns);
ipaddr = get_remote_ipaddr();
}
@@ -154,8 +157,9 @@ allowed_user(struct passwd * pw)
for (i = 0; i < options.num_deny_users; i++)
if (match_user(pw->pw_name, hostname, ipaddr,
options.deny_users[i])) {
- logit("User %.100s not allowed because listed in DenyUsers",
- pw->pw_name);
+ logit("User %.100s from %.100s not allowed "
+ "because listed in DenyUsers",
+ pw->pw_name, hostname);
return 0;
}
}
@@ -167,16 +171,16 @@ allowed_user(struct passwd * pw)
break;
/* i < options.num_allow_users iff we break for loop */
if (i >= options.num_allow_users) {
- logit("User %.100s not allowed because not listed in AllowUsers",
- pw->pw_name);
+ logit("User %.100s from %.100s not allowed because "
+ "not listed in AllowUsers", pw->pw_name, hostname);
return 0;
}
}
if (options.num_deny_groups > 0 || options.num_allow_groups > 0) {
/* Get the user's group access list (primary and supplementary) */
if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
- logit("User %.100s not allowed because not in any group",
- pw->pw_name);
+ logit("User %.100s from %.100s not allowed because "
+ "not in any group", pw->pw_name, hostname);
return 0;
}
@@ -185,8 +189,9 @@ allowed_user(struct passwd * pw)
if (ga_match(options.deny_groups,
options.num_deny_groups)) {
ga_free();
- logit("User %.100s not allowed because a group is listed in DenyGroups",
- pw->pw_name);
+ logit("User %.100s from %.100s not allowed "
+ "because a group is listed in DenyGroups",
+ pw->pw_name, hostname);
return 0;
}
/*
@@ -197,15 +202,16 @@ allowed_user(struct passwd * pw)
if (!ga_match(options.allow_groups,
options.num_allow_groups)) {
ga_free();
- logit("User %.100s not allowed because none of user's groups are listed in AllowGroups",
- pw->pw_name);
+ logit("User %.100s from %.100s not allowed "
+ "because none of user's groups are listed "
+ "in AllowGroups", pw->pw_name, hostname);
return 0;
}
ga_free();
}
#ifdef CUSTOM_SYS_AUTH_ALLOWED_USER
- if (!sys_auth_allowed_user(pw))
+ if (!sys_auth_allowed_user(pw, &loginmsg))
return 0;
#endif
@@ -241,8 +247,50 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
info);
#ifdef CUSTOM_FAILED_LOGIN
- if (authenticated == 0 && strcmp(method, "password") == 0)
- record_failed_login(authctxt->user, "ssh");
+ if (authenticated == 0 && !authctxt->postponed &&
+ (strcmp(method, "password") == 0 ||
+ strncmp(method, "keyboard-interactive", 20) == 0 ||
+ strcmp(method, "challenge-response") == 0))
+ record_failed_login(authctxt->user,
+ get_canonical_hostname(options.use_dns), "ssh");
+#endif
+#ifdef SSH_AUDIT_EVENTS
+ if (authenticated == 0 && !authctxt->postponed) {
+ ssh_audit_event_t event;
+
+ debug3("audit failed auth attempt, method %s euid %d",
+ method, (int)geteuid());
+ /*
+ * Because the auth loop is used in both monitor and slave,
+ * we must be careful to send each event only once and with
+ * enough privs to write the event.
+ */
+ event = audit_classify_auth(method);
+ switch(event) {
+ case SSH_AUTH_FAIL_NONE:
+ case SSH_AUTH_FAIL_PASSWD:
+ case SSH_AUTH_FAIL_KBDINT:
+ if (geteuid() == 0)
+ audit_event(event);
+ break;
+ case SSH_AUTH_FAIL_PUBKEY:
+ case SSH_AUTH_FAIL_HOSTBASED:
+ case SSH_AUTH_FAIL_GSSAPI:
+ /*
+ * This is required to handle the case where privsep
+ * is enabled but it's root logging in, since
+ * use_privsep won't be cleared until after a
+ * successful login.
+ */
+ if (geteuid() == 0)
+ audit_event(event);
+ else
+ PRIVSEP(audit_event(event));
+ break;
+ default:
+ error("unknown authentication audit event %d", event);
+ }
+ }
#endif
}
@@ -466,8 +514,12 @@ getpwnamallow(const char *user)
logit("Invalid user %.100s from %.100s",
user, get_remote_ipaddr());
#ifdef CUSTOM_FAILED_LOGIN
- record_failed_login(user, "ssh");
+ record_failed_login(user,
+ get_canonical_hostname(options.use_dns), "ssh");
#endif
+#ifdef SSH_AUDIT_EVENTS
+ audit_event(SSH_INVALID_USER);
+#endif /* SSH_AUDIT_EVENTS */
return (NULL);
}
if (!allowed_user(pw))
diff --git a/crypto/openssh/auth.h b/crypto/openssh/auth.h
index b7639d955e43..d06c028744b0 100644
--- a/crypto/openssh/auth.h
+++ b/crypto/openssh/auth.h
@@ -31,6 +31,7 @@
#include "key.h"
#include "hostfile.h"
+#include "buffer.h"
#include <openssl/rsa.h>
#ifdef HAVE_LOGIN_CAP
@@ -69,6 +70,7 @@ struct Authctxt {
char *krb5_ticket_file;
char *krb5_ccname;
#endif
+ Buffer *loginmsg;
void *methoddata;
};
/*
@@ -131,6 +133,9 @@ int auth_shadow_pwexpired(Authctxt *);
#endif
#include "auth-pam.h"
+#include "audit.h"
+void remove_kbdint_device(const char *);
+
void disable_forwarding(void);
void do_authentication(Authctxt *);
@@ -138,6 +143,7 @@ void do_authentication2(Authctxt *);
void auth_log(Authctxt *, int, char *, char *);
void userauth_finish(Authctxt *, int, char *);
+void userauth_send_banner(const char *);
int auth_root_allowed(char *);
char *auth2_read_banner(void);
@@ -182,6 +188,8 @@ void auth_debug_reset(void);
struct passwd *fakepw(void);
+int sys_auth_passwd(Authctxt *, const char *);
+
#define AUTH_FAIL_MSG "Too many authentication failures for %.100s"
#ifdef SKEY
diff --git a/crypto/openssh/auth1.c b/crypto/openssh/auth1.c
index 806c173487f0..0c26e114da25 100644
--- a/crypto/openssh/auth1.c
+++ b/crypto/openssh/auth1.c
@@ -26,9 +26,11 @@ RCSID("$FreeBSD$");
#include "session.h"
#include "uidswap.h"
#include "monitor_wrap.h"
+#include "buffer.h"
/* import */
extern ServerOptions options;
+extern Buffer loginmsg;
/*
* convert ssh auth msg type into description
@@ -246,14 +248,33 @@ do_authloop(Authctxt *authctxt)
#else
/* Special handling for root */
if (authenticated && authctxt->pw->pw_uid == 0 &&
- !auth_root_allowed(get_authname(type)))
+ !auth_root_allowed(get_authname(type))) {
authenticated = 0;
+# ifdef SSH_AUDIT_EVENTS
+ PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED));
+# endif
+ }
#endif
#ifdef USE_PAM
if (options.use_pam && authenticated &&
- !PRIVSEP(do_pam_account()))
- authenticated = 0;
+ !PRIVSEP(do_pam_account())) {
+ char *msg;
+ size_t len;
+
+ error("Access denied for user %s by PAM account "
+ "configuration", authctxt->user);
+ len = buffer_len(&loginmsg);
+ buffer_append(&loginmsg, "\0", 1);
+ msg = buffer_ptr(&loginmsg);
+ /* strip trailing newlines */
+ if (len > 0)
+ while (len > 0 && msg[--len] == '\n')
+ msg[len] = '\0';
+ else
+ msg = "Access denied.";
+ packet_disconnect(msg);
+ }
#endif
/* Log before sending the reply */
@@ -267,8 +288,12 @@ do_authloop(Authctxt *authctxt)
if (authenticated)
return;
- if (authctxt->failures++ > options.max_authtries)
+ if (authctxt->failures++ > options.max_authtries) {
+#ifdef SSH_AUDIT_EVENTS
+ PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES));
+#endif
packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
+ }
packet_start(SSH_SMSG_FAILURE);
packet_send();
diff --git a/crypto/openssh/auth2-chall.c b/crypto/openssh/auth2-chall.c
index 788c6c60b6b9..7b5762fb0ac9 100644
--- a/crypto/openssh/auth2-chall.c
+++ b/crypto/openssh/auth2-chall.c
@@ -23,7 +23,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
-RCSID("$OpenBSD: auth2-chall.c,v 1.21 2004/06/01 14:20:45 dtucker Exp $");
+RCSID("$OpenBSD: auth2-chall.c,v 1.22 2005/01/19 13:11:47 dtucker Exp $");
RCSID("$FreeBSD$");
#include "ssh2.h"
@@ -33,6 +33,10 @@ RCSID("$FreeBSD$");
#include "xmalloc.h"
#include "dispatch.h"
#include "log.h"
+#include "servconf.h"
+
+/* import */
+extern ServerOptions options;
static int auth2_challenge_start(Authctxt *);
static int send_userauth_info_request(Authctxt *);
@@ -72,6 +76,21 @@ struct KbdintAuthctxt
u_int nreq;
};
+#ifdef USE_PAM
+void
+remove_kbdint_device(const char *devname)
+{
+ int i, j;
+
+ for (i = 0; devices[i] != NULL; i++)
+ if (strcmp(devices[i]->name, devname) == 0) {
+ for (j = i; devices[j] != NULL; j++)
+ devices[j] = devices[j+1];
+ i--;
+ }
+}
+#endif
+
static KbdintAuthctxt *
kbdint_alloc(const char *devs)
{
@@ -79,6 +98,11 @@ kbdint_alloc(const char *devs)
Buffer b;
int i;
+#ifdef USE_PAM
+ if (!options.use_pam)
+ remove_kbdint_device("pam");
+#endif
+
kbdintctxt = xmalloc(sizeof(KbdintAuthctxt));
if (strcmp(devs, "") == 0) {
buffer_init(&b);
@@ -275,12 +299,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
}
packet_check_eom();
- if (authctxt->valid) {
- res = kbdintctxt->device->respond(kbdintctxt->ctxt,
- nresp, response);
- } else {
- res = -1;
- }
+ res = kbdintctxt->device->respond(kbdintctxt->ctxt, nresp, response);
for (i = 0; i < nresp; i++) {
memset(response[i], 'r', strlen(response[i]));
@@ -292,7 +311,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
switch (res) {
case 0:
/* Success! */
- authenticated = 1;
+ authenticated = authctxt->valid ? 1 : 0;
break;
case 1:
/* Authentication needs further interaction */
diff --git a/crypto/openssh/auth2-kbdint.c b/crypto/openssh/auth2-kbdint.c
index 15c20b33921e..878a21dfcadf 100644
--- a/crypto/openssh/auth2-kbdint.c
+++ b/crypto/openssh/auth2-kbdint.c
@@ -54,7 +54,7 @@ userauth_kbdint(Authctxt *authctxt)
xfree(lang);
#ifdef HAVE_CYGWIN
if (check_nt_auth(0, authctxt->pw) == 0)
- return(0);
+ authenticated = 0;
#endif
return authenticated;
}
diff --git a/crypto/openssh/auth2.c b/crypto/openssh/auth2.c
index 089ea34a4e14..ce7263bcafd0 100644
--- a/crypto/openssh/auth2.c
+++ b/crypto/openssh/auth2.c
@@ -37,6 +37,7 @@ RCSID("$FreeBSD$");
#include "dispatch.h"
#include "pathnames.h"
#include "monitor_wrap.h"
+#include "buffer.h"
#ifdef GSSAPI
#include "ssh-gss.h"
@@ -46,6 +47,7 @@ RCSID("$FreeBSD$");
extern ServerOptions options;
extern u_char *session_id2;
extern u_int session_id2_len;
+extern Buffer loginmsg;
/* methods */
@@ -174,6 +176,9 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
if (options.use_pam)
PRIVSEP(start_pam(authctxt));
#endif
+#ifdef SSH_AUDIT_EVENTS
+ PRIVSEP(audit_event(SSH_INVALID_USER));
+#endif
}
setproctitle("%s%s", authctxt->valid ? user : "unknown",
use_privsep ? " [net]" : "");
@@ -242,12 +247,26 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
/* Special handling for root */
if (authenticated && authctxt->pw->pw_uid == 0 &&
- !auth_root_allowed(method))
+ !auth_root_allowed(method)) {
authenticated = 0;
+#ifdef SSH_AUDIT_EVENTS
+ PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED));
+#endif
+ }
#ifdef USE_PAM
- if (options.use_pam && authenticated && !PRIVSEP(do_pam_account()))
- authenticated = 0;
+ if (options.use_pam && authenticated) {
+ if (!PRIVSEP(do_pam_account())) {
+ /* if PAM returned a message, send it to the user */
+ if (buffer_len(&loginmsg) > 0) {
+ buffer_append(&loginmsg, "\0", 1);
+ userauth_send_banner(buffer_ptr(&loginmsg));
+ packet_write_wait();
+ }
+ fatal("Access denied for user %s by PAM account "
+ "configuration", authctxt->user);
+ }
+ }
#endif
#ifdef _UNICOS
@@ -273,8 +292,12 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
/* now we can break out */
authctxt->success = 1;
} else {
- if (authctxt->failures++ > options.max_authtries)
+ if (authctxt->failures++ > options.max_authtries) {
+#ifdef SSH_AUDIT_EVENTS
+ PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES));
+#endif
packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
+ }
methods = authmethods_get();
packet_start(SSH2_MSG_USERAUTH_FAILURE);
packet_put_cstring(methods);
diff --git a/crypto/openssh/authfile.c b/crypto/openssh/authfile.c
index 76a60d020f7a..6a04cd7a95a2 100644
--- a/crypto/openssh/authfile.c
+++ b/crypto/openssh/authfile.c
@@ -36,7 +36,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: authfile.c,v 1.57 2004/06/21 17:36:31 avsm Exp $");
+RCSID("$OpenBSD: authfile.c,v 1.60 2004/12/11 01:48:56 dtucker Exp $");
#include <openssl/err.h>
#include <openssl/evp.h>
@@ -51,6 +51,7 @@ RCSID("$OpenBSD: authfile.c,v 1.57 2004/06/21 17:36:31 avsm Exp $");
#include "log.h"
#include "authfile.h"
#include "rsa.h"
+#include "misc.h"
/* Version identification string for SSH v1 identity files. */
static const char authfile_id_string[] =
@@ -243,8 +244,10 @@ key_load_public_rsa1(int fd, const char *filename, char **commentp)
filename, strerror(errno));
return NULL;
}
- if (st.st_size > 1*1024*1024)
- close(fd);
+ if (st.st_size > 1*1024*1024) {
+ error("key file %.200s too large", filename);
+ return NULL;
+ }
len = (size_t)st.st_size; /* truncated */
buffer_init(&buffer);
@@ -335,6 +338,7 @@ key_load_private_rsa1(int fd, const char *filename, const char *passphrase,
return NULL;
}
if (st.st_size > 1*1024*1024) {
+ error("key file %.200s too large", filename);
close(fd);
return (NULL);
}
@@ -598,13 +602,14 @@ static int
key_try_load_public(Key *k, const char *filename, char **commentp)
{
FILE *f;
- char line[4096];
+ char line[SSH_MAX_PUBKEY_BYTES];
char *cp;
+ u_long linenum = 0;
f = fopen(filename, "r");
if (f != NULL) {
- while (fgets(line, sizeof(line), f)) {
- line[sizeof(line)-1] = '\0';
+ while (read_keyfile_line(f, filename, line, sizeof(line),
+ &linenum) != -1) {
cp = line;
switch (*cp) {
case '#':
diff --git a/crypto/openssh/bufaux.c b/crypto/openssh/bufaux.c
index adbb4bdd5887..27c42b04cafb 100644
--- a/crypto/openssh/bufaux.c
+++ b/crypto/openssh/bufaux.c
@@ -37,7 +37,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: bufaux.c,v 1.32 2004/02/23 15:12:46 markus Exp $");
+RCSID("$OpenBSD: bufaux.c,v 1.35 2005/03/10 22:01:05 deraadt Exp $");
RCSID("$FreeBSD$");
#include <openssl/bn.h>
@@ -50,8 +50,8 @@ RCSID("$FreeBSD$");
* Stores an BIGNUM in the buffer with a 2-byte msb first bit count, followed
* by (bits+7)/8 bytes of binary data, msb first.
*/
-void
-buffer_put_bignum(Buffer *buffer, const BIGNUM *value)
+int
+buffer_put_bignum_ret(Buffer *buffer, const BIGNUM *value)
{
int bits = BN_num_bits(value);
int bin_size = (bits + 7) / 8;
@@ -61,9 +61,11 @@ buffer_put_bignum(Buffer *buffer, const BIGNUM *value)
/* Get the value of in binary */
oi = BN_bn2bin(value, buf);
- if (oi != bin_size)
- fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d",
+ if (oi != bin_size) {
+ error("buffer_put_bignum_ret: BN_bn2bin() failed: oi %d != bin_size %d",
oi, bin_size);
+ return (-1);
+ }
/* Store the number of bits in the buffer in two bytes, msb first. */
PUT_16BIT(msg, bits);
@@ -73,36 +75,63 @@ buffer_put_bignum(Buffer *buffer, const BIGNUM *value)
memset(buf, 0, bin_size);
xfree(buf);
+
+ return (0);
+}
+
+void
+buffer_put_bignum(Buffer *buffer, const BIGNUM *value)
+{
+ if (buffer_put_bignum_ret(buffer, value) == -1)
+ fatal("buffer_put_bignum: buffer error");
}
/*
* Retrieves an BIGNUM from the buffer.
*/
-void
-buffer_get_bignum(Buffer *buffer, BIGNUM *value)
+int
+buffer_get_bignum_ret(Buffer *buffer, BIGNUM *value)
{
u_int bits, bytes;
u_char buf[2], *bin;
/* Get the number for bits. */
- buffer_get(buffer, (char *) buf, 2);
+ if (buffer_get_ret(buffer, (char *) buf, 2) == -1) {
+ error("buffer_get_bignum_ret: invalid length");
+ return (-1);
+ }
bits = GET_16BIT(buf);
/* Compute the number of binary bytes that follow. */
bytes = (bits + 7) / 8;
- if (bytes > 8 * 1024)
- fatal("buffer_get_bignum: cannot handle BN of size %d", bytes);
- if (buffer_len(buffer) < bytes)
- fatal("buffer_get_bignum: input buffer too small");
+ if (bytes > 8 * 1024) {
+ error("buffer_get_bignum_ret: cannot handle BN of size %d", bytes);
+ return (-1);
+ }
+ if (buffer_len(buffer) < bytes) {
+ error("buffer_get_bignum_ret: input buffer too small");
+ return (-1);
+ }
bin = buffer_ptr(buffer);
BN_bin2bn(bin, bytes, value);
- buffer_consume(buffer, bytes);
+ if (buffer_consume_ret(buffer, bytes) == -1) {
+ error("buffer_get_bignum_ret: buffer_consume failed");
+ return (-1);
+ }
+ return (0);
+}
+
+void
+buffer_get_bignum(Buffer *buffer, BIGNUM *value)
+{
+ if (buffer_get_bignum_ret(buffer, value) == -1)
+ fatal("buffer_get_bignum: buffer error");
}
/*
* Stores an BIGNUM in the buffer in SSH2 format.
*/
-void
-buffer_put_bignum2(Buffer *buffer, const BIGNUM *value)
+int
+buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value)
{
u_int bytes;
u_char *buf;
@@ -111,69 +140,140 @@ buffer_put_bignum2(Buffer *buffer, const BIGNUM *value)
if (BN_is_zero(value)) {
buffer_put_int(buffer, 0);
- return;
+ return 0;
+ }
+ if (value->neg) {
+ error("buffer_put_bignum2_ret: negative numbers not supported");
+ return (-1);
}
- if (value->neg)
- fatal("buffer_put_bignum2: negative numbers not supported");
bytes = BN_num_bytes(value) + 1; /* extra padding byte */
- if (bytes < 2)
- fatal("buffer_put_bignum2: BN too small");
+ if (bytes < 2) {
+ error("buffer_put_bignum2_ret: BN too small");
+ return (-1);
+ }
buf = xmalloc(bytes);
- buf[0] = '\0';
+ buf[0] = 0x00;
/* Get the value of in binary */
oi = BN_bn2bin(value, buf+1);
- if (oi != bytes-1)
- fatal("buffer_put_bignum2: BN_bn2bin() failed: "
+ if (oi != bytes-1) {
+ error("buffer_put_bignum2_ret: BN_bn2bin() failed: "
"oi %d != bin_size %d", oi, bytes);
+ xfree(buf);
+ return (-1);
+ }
hasnohigh = (buf[1] & 0x80) ? 0 : 1;
buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh);
memset(buf, 0, bytes);
xfree(buf);
+ return (0);
}
void
-buffer_get_bignum2(Buffer *buffer, BIGNUM *value)
+buffer_put_bignum2(Buffer *buffer, const BIGNUM *value)
+{
+ if (buffer_put_bignum2_ret(buffer, value) == -1)
+ fatal("buffer_put_bignum2: buffer error");
+}
+
+int
+buffer_get_bignum2_ret(Buffer *buffer, BIGNUM *value)
{
u_int len;
- u_char *bin = buffer_get_string(buffer, &len);
+ u_char *bin;
+
+ if ((bin = buffer_get_string_ret(buffer, &len)) == NULL) {
+ error("buffer_get_bignum2_ret: invalid bignum");
+ return (-1);
+ }
- if (len > 0 && (bin[0] & 0x80))
- fatal("buffer_get_bignum2: negative numbers not supported");
- if (len > 8 * 1024)
- fatal("buffer_get_bignum2: cannot handle BN of size %d", len);
+ if (len > 0 && (bin[0] & 0x80)) {
+ error("buffer_get_bignum2_ret: negative numbers not supported");
+ return (-1);
+ }
+ if (len > 8 * 1024) {
+ error("buffer_get_bignum2_ret: cannot handle BN of size %d", len);
+ return (-1);
+ }
BN_bin2bn(bin, len, value);
xfree(bin);
+ return (0);
+}
+
+void
+buffer_get_bignum2(Buffer *buffer, BIGNUM *value)
+{
+ if (buffer_get_bignum2_ret(buffer, value) == -1)
+ fatal("buffer_get_bignum2: buffer error");
}
/*
* Returns integers from the buffer (msb first).
*/
+int
+buffer_get_short_ret(u_short *ret, Buffer *buffer)
+{
+ u_char buf[2];
+
+ if (buffer_get_ret(buffer, (char *) buf, 2) == -1)
+ return (-1);
+ *ret = GET_16BIT(buf);
+ return (0);
+}
+
u_short
buffer_get_short(Buffer *buffer)
{
- u_char buf[2];
+ u_short ret;
+
+ if (buffer_get_short_ret(&ret, buffer) == -1)
+ fatal("buffer_get_short: buffer error");
- buffer_get(buffer, (char *) buf, 2);
- return GET_16BIT(buf);
+ return (ret);
+}
+
+int
+buffer_get_int_ret(u_int *ret, Buffer *buffer)
+{
+ u_char buf[4];
+
+ if (buffer_get_ret(buffer, (char *) buf, 4) == -1)
+ return (-1);
+ *ret = GET_32BIT(buf);
+ return (0);
}
u_int
buffer_get_int(Buffer *buffer)
{
- u_char buf[4];
+ u_int ret;
+
+ if (buffer_get_int_ret(&ret, buffer) == -1)
+ fatal("buffer_get_int: buffer error");
+
+ return (ret);
+}
- buffer_get(buffer, (char *) buf, 4);
- return GET_32BIT(buf);
+int
+buffer_get_int64_ret(u_int64_t *ret, Buffer *buffer)
+{
+ u_char buf[8];
+
+ if (buffer_get_ret(buffer, (char *) buf, 8) == -1)
+ return (-1);
+ *ret = GET_64BIT(buf);
+ return (0);
}
u_int64_t
buffer_get_int64(Buffer *buffer)
{
- u_char buf[8];
+ u_int64_t ret;
- buffer_get(buffer, (char *) buf, 8);
- return GET_64BIT(buf);
+ if (buffer_get_int64_ret(&ret, buffer) == -1)
+ fatal("buffer_get_int: buffer error");
+
+ return (ret);
}
/*
@@ -215,25 +315,41 @@ buffer_put_int64(Buffer *buffer, u_int64_t value)
* to the returned string, and is not counted in length.
*/
void *
-buffer_get_string(Buffer *buffer, u_int *length_ptr)
+buffer_get_string_ret(Buffer *buffer, u_int *length_ptr)
{
u_char *value;
u_int len;
/* Get the length. */
len = buffer_get_int(buffer);
- if (len > 256 * 1024)
- fatal("buffer_get_string: bad string length %u", len);
+ if (len > 256 * 1024) {
+ error("buffer_get_string_ret: bad string length %u", len);
+ return (NULL);
+ }
/* Allocate space for the string. Add one byte for a null character. */
value = xmalloc(len + 1);
/* Get the string. */
- buffer_get(buffer, value, len);
+ if (buffer_get_ret(buffer, value, len) == -1) {
+ error("buffer_get_string_ret: buffer_get failed");
+ xfree(value);
+ return (NULL);
+ }
/* Append a null character to make processing easier. */
value[len] = 0;
/* Optionally return the length of the string. */
if (length_ptr)
*length_ptr = len;
- return value;
+ return (value);
+}
+
+void *
+buffer_get_string(Buffer *buffer, u_int *length_ptr)
+{
+ void *ret;
+
+ if ((ret = buffer_get_string_ret(buffer, length_ptr)) == NULL)
+ fatal("buffer_get_string: buffer error");
+ return (ret);
}
/*
@@ -257,11 +373,22 @@ buffer_put_cstring(Buffer *buffer, const char *s)
* Returns a character from the buffer (0 - 255).
*/
int
+buffer_get_char_ret(char *ret, Buffer *buffer)
+{
+ if (buffer_get_ret(buffer, ret, 1) == -1) {
+ error("buffer_get_char_ret: buffer_get_ret failed");
+ return (-1);
+ }
+ return (0);
+}
+
+int
buffer_get_char(Buffer *buffer)
{
char ch;
- buffer_get(buffer, &ch, 1);
+ if (buffer_get_char_ret(&ch, buffer) == -1)
+ fatal("buffer_get_char: buffer error");
return (u_char) ch;
}
diff --git a/crypto/openssh/canohost.c b/crypto/openssh/canohost.c
index 8ad684d6c383..94d666432f0e 100644
--- a/crypto/openssh/canohost.c
+++ b/crypto/openssh/canohost.c
@@ -12,7 +12,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: canohost.c,v 1.41 2004/07/21 11:51:29 djm Exp $");
+RCSID("$OpenBSD: canohost.c,v 1.42 2005/02/18 03:05:53 djm Exp $");
#include "packet.h"
#include "xmalloc.h"
@@ -20,7 +20,6 @@ RCSID("$OpenBSD: canohost.c,v 1.41 2004/07/21 11:51:29 djm Exp $");
#include "canohost.h"
static void check_ip_options(int, char *);
-static void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *);
/*
* Return the canonical name of the host at the other end of the socket. The
@@ -166,7 +165,7 @@ check_ip_options(int sock, char *ipaddr)
#endif /* IP_OPTIONS */
}
-static void
+void
ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len)
{
struct sockaddr_in6 *a6 = (struct sockaddr_in6 *)addr;
@@ -232,6 +231,7 @@ get_socket_address(int sock, int remote, int flags)
struct sockaddr_storage addr;
socklen_t addrlen;
char ntop[NI_MAXHOST];
+ int r;
/* Get IP address of client. */
addrlen = sizeof(addr);
@@ -251,10 +251,13 @@ get_socket_address(int sock, int remote, int flags)
if (addr.ss_family == AF_INET6)
addrlen = sizeof(struct sockaddr_in6);
+ ipv64_normalise_mapped(&addr, &addrlen);
+
/* Get the address in ascii. */
- if (getnameinfo((struct sockaddr *)&addr, addrlen, ntop, sizeof(ntop),
- NULL, 0, flags) != 0) {
- error("get_socket_address: getnameinfo %d failed", flags);
+ if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop,
+ sizeof(ntop), NULL, 0, flags)) != 0) {
+ error("get_socket_address: getnameinfo %d failed: %s", flags,
+ r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r));
return NULL;
}
return xstrdup(ntop);
@@ -330,6 +333,7 @@ get_sock_port(int sock, int local)
struct sockaddr_storage from;
socklen_t fromlen;
char strport[NI_MAXSERV];
+ int r;
/* Get IP address of client. */
fromlen = sizeof(from);
@@ -351,9 +355,10 @@ get_sock_port(int sock, int local)
fromlen = sizeof(struct sockaddr_in6);
/* Return port number. */
- if (getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0,
- strport, sizeof(strport), NI_NUMERICSERV) != 0)
- fatal("get_sock_port: getnameinfo NI_NUMERICSERV failed");
+ if ((r = getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0,
+ strport, sizeof(strport), NI_NUMERICSERV)) != 0)
+ fatal("get_sock_port: getnameinfo NI_NUMERICSERV failed: %s",
+ r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r));
return atoi(strport);
}
diff --git a/crypto/openssh/channels.c b/crypto/openssh/channels.c
index 1f6984aa7662..3f6db60c6fc6 100644
--- a/crypto/openssh/channels.c
+++ b/crypto/openssh/channels.c
@@ -39,7 +39,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.209 2004/08/11 21:43:04 avsm Exp $");
+RCSID("$OpenBSD: channels.c,v 1.214 2005/03/14 11:46:56 markus Exp $");
#include "ssh.h"
#include "ssh1.h"
@@ -58,6 +58,8 @@ RCSID("$OpenBSD: channels.c,v 1.209 2004/08/11 21:43:04 avsm Exp $");
/* -- channel core */
+#define CHAN_RBUF 16*1024
+
/*
* Pointer to an array containing all allocated channels. The array is
* dynamically extended as needed.
@@ -712,6 +714,9 @@ channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset)
{
u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
+ /* check buffer limits */
+ limit = MIN(limit, (BUFFER_MAX_LEN - BUFFER_MAX_CHUNK - CHAN_RBUF));
+
if (c->istate == CHAN_INPUT_OPEN &&
limit > 0 &&
buffer_len(&c->input) < limit)
@@ -1018,7 +1023,7 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
debug2("channel %d: only socks5 connect supported", c->self);
return -1;
}
- switch(s5_req.atyp){
+ switch (s5_req.atyp){
case SSH_SOCKS5_IPV4:
addrlen = 4;
af = AF_INET;
@@ -1360,7 +1365,7 @@ channel_post_connecting(Channel *c, fd_set * readset, fd_set * writeset)
static int
channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
{
- char buf[16*1024];
+ char buf[CHAN_RBUF];
int len;
if (c->rfd != -1 &&
@@ -1454,7 +1459,7 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
static int
channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
{
- char buf[16*1024];
+ char buf[CHAN_RBUF];
int len;
/** XXX handle drain efd, too */
@@ -2179,14 +2184,14 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
const char *host_to_connect, u_short port_to_connect, int gateway_ports)
{
Channel *c;
- int success, sock, on = 1;
+ int sock, r, success = 0, on = 1, wildcard = 0, is_client;
struct addrinfo hints, *ai, *aitop;
- const char *host;
+ const char *host, *addr;
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
- success = 0;
host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
listen_addr : host_to_connect;
+ is_client = (type == SSH_CHANNEL_PORT_LISTENER);
if (host == NULL) {
error("No forward host name.");
@@ -2198,16 +2203,60 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
}
/*
+ * Determine whether or not a port forward listens to loopback,
+ * specified address or wildcard. On the client, a specified bind
+ * address will always override gateway_ports. On the server, a
+ * gateway_ports of 1 (``yes'') will override the client's
+ * specification and force a wildcard bind, whereas a value of 2
+ * (``clientspecified'') will bind to whatever address the client
+ * asked for.
+ *
+ * Special-case listen_addrs are:
+ *
+ * "0.0.0.0" -> wildcard v4/v6 if SSH_OLD_FORWARD_ADDR
+ * "" (empty string), "*" -> wildcard v4/v6
+ * "localhost" -> loopback v4/v6
+ */
+ addr = NULL;
+ if (listen_addr == NULL) {
+ /* No address specified: default to gateway_ports setting */
+ if (gateway_ports)
+ wildcard = 1;
+ } else if (gateway_ports || is_client) {
+ if (((datafellows & SSH_OLD_FORWARD_ADDR) &&
+ strcmp(listen_addr, "0.0.0.0") == 0) ||
+ *listen_addr == '\0' || strcmp(listen_addr, "*") == 0 ||
+ (!is_client && gateway_ports == 1))
+ wildcard = 1;
+ else if (strcmp(listen_addr, "localhost") != 0)
+ addr = listen_addr;
+ }
+
+ debug3("channel_setup_fwd_listener: type %d wildcard %d addr %s",
+ type, wildcard, (addr == NULL) ? "NULL" : addr);
+
+ /*
* getaddrinfo returns a loopback address if the hostname is
* set to NULL and hints.ai_flags is not AI_PASSIVE
*/
memset(&hints, 0, sizeof(hints));
hints.ai_family = IPv4or6;
- hints.ai_flags = gateway_ports ? AI_PASSIVE : 0;
+ hints.ai_flags = wildcard ? AI_PASSIVE : 0;
hints.ai_socktype = SOCK_STREAM;
snprintf(strport, sizeof strport, "%d", listen_port);
- if (getaddrinfo(NULL, strport, &hints, &aitop) != 0)
- packet_disconnect("getaddrinfo: fatal error");
+ if ((r = getaddrinfo(addr, strport, &hints, &aitop)) != 0) {
+ if (addr == NULL) {
+ /* This really shouldn't happen */
+ packet_disconnect("getaddrinfo: fatal error: %s",
+ gai_strerror(r));
+ } else {
+ verbose("channel_setup_fwd_listener: "
+ "getaddrinfo(%.64s): %s", addr, gai_strerror(r));
+ packet_send_debug("channel_setup_fwd_listener: "
+ "getaddrinfo(%.64s): %s", addr, gai_strerror(r));
+ }
+ aitop = NULL;
+ }
for (ai = aitop; ai; ai = ai->ai_next) {
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
@@ -2273,13 +2322,13 @@ channel_cancel_rport_listener(const char *host, u_short port)
u_int i;
int found = 0;
- for(i = 0; i < channels_alloc; i++) {
+ for (i = 0; i < channels_alloc; i++) {
Channel *c = channels[i];
if (c != NULL && c->type == SSH_CHANNEL_RPORT_LISTENER &&
strncmp(c->path, host, sizeof(c->path)) == 0 &&
c->listening_port == port) {
- debug2("%s: close clannel %d", __func__, i);
+ debug2("%s: close channel %d", __func__, i);
channel_free(c);
found = 1;
}
@@ -2290,11 +2339,12 @@ channel_cancel_rport_listener(const char *host, u_short port)
/* protocol local port fwd, used by ssh (and sshd in v1) */
int
-channel_setup_local_fwd_listener(u_short listen_port,
+channel_setup_local_fwd_listener(const char *listen_host, u_short listen_port,
const char *host_to_connect, u_short port_to_connect, int gateway_ports)
{
return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER,
- NULL, listen_port, host_to_connect, port_to_connect, gateway_ports);
+ listen_host, listen_port, host_to_connect, port_to_connect,
+ gateway_ports);
}
/* protocol v2 remote port fwd, used by sshd */
@@ -2312,7 +2362,7 @@ channel_setup_remote_fwd_listener(const char *listen_address,
*/
void
-channel_request_remote_forwarding(u_short listen_port,
+channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
const char *host_to_connect, u_short port_to_connect)
{
int type, success = 0;
@@ -2323,7 +2373,14 @@ channel_request_remote_forwarding(u_short listen_port,
/* Send the forward request to the remote side. */
if (compat20) {
- const char *address_to_bind = "0.0.0.0";
+ const char *address_to_bind;
+ if (listen_host == NULL)
+ address_to_bind = "localhost";
+ else if (*listen_host == '\0' || strcmp(listen_host, "*") == 0)
+ address_to_bind = "";
+ else
+ address_to_bind = listen_host;
+
packet_start(SSH2_MSG_GLOBAL_REQUEST);
packet_put_cstring("tcpip-forward");
packet_put_char(1); /* boolean: want reply */
@@ -2369,10 +2426,9 @@ channel_request_remote_forwarding(u_short listen_port,
* local side.
*/
void
-channel_request_rforward_cancel(u_short port)
+channel_request_rforward_cancel(const char *host, u_short port)
{
int i;
- const char *address_to_bind = "0.0.0.0";
if (!compat20)
return;
@@ -2389,7 +2445,7 @@ channel_request_rforward_cancel(u_short port)
packet_start(SSH2_MSG_GLOBAL_REQUEST);
packet_put_cstring("cancel-tcpip-forward");
packet_put_char(0);
- packet_put_cstring(address_to_bind);
+ packet_put_cstring(host == NULL ? "" : host);
packet_put_int(port);
packet_send();
@@ -2430,7 +2486,8 @@ channel_input_port_forward_request(int is_root, int gateway_ports)
#endif
/* Initiate forwarding */
- channel_setup_local_fwd_listener(port, hostname, host_port, gateway_ports);
+ channel_setup_local_fwd_listener(NULL, port, hostname,
+ host_port, gateway_ports);
/* Free the argument string. */
xfree(hostname);
@@ -2577,7 +2634,7 @@ channel_send_window_changes(void)
struct winsize ws;
for (i = 0; i < channels_alloc; i++) {
- if (channels[i] == NULL ||
+ if (channels[i] == NULL || !channels[i]->client_tty ||
channels[i]->type != SSH_CHANNEL_OPEN)
continue;
if (ioctl(channels[i]->rfd, TIOCGWINSZ, &ws) < 0)
diff --git a/crypto/openssh/channels.h b/crypto/openssh/channels.h
index f8dc8249c2a2..fc20fb2c331e 100644
--- a/crypto/openssh/channels.h
+++ b/crypto/openssh/channels.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: channels.h,v 1.74 2004/08/11 21:43:04 avsm Exp $ */
+/* $OpenBSD: channels.h,v 1.76 2005/03/01 10:09:52 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -79,6 +79,7 @@ struct Channel {
int ctl_fd; /* control fd (client sharing) */
int isatty; /* rfd is a tty */
int wfd_isatty; /* wfd is a tty */
+ int client_tty; /* (client) TTY has been requested */
int force_drain; /* force close on iEOF */
int delayed; /* fdset hack */
Buffer input; /* data read from socket, to be sent over
@@ -202,9 +203,11 @@ void channel_clear_permitted_opens(void);
void channel_input_port_forward_request(int, int);
int channel_connect_to(const char *, u_short);
int channel_connect_by_listen_address(u_short);
-void channel_request_remote_forwarding(u_short, const char *, u_short);
-void channel_request_rforward_cancel(u_short port);
-int channel_setup_local_fwd_listener(u_short, const char *, u_short, int);
+void channel_request_remote_forwarding(const char *, u_short,
+ const char *, u_short);
+int channel_setup_local_fwd_listener(const char *, u_short,
+ const char *, u_short, int);
+void channel_request_rforward_cancel(const char *host, u_short port);
int channel_setup_remote_fwd_listener(const char *, u_short, int);
int channel_cancel_rport_listener(const char *, u_short);
diff --git a/crypto/openssh/cipher.c b/crypto/openssh/cipher.c
index 075a4c5fceb0..beba4618dc82 100644
--- a/crypto/openssh/cipher.c
+++ b/crypto/openssh/cipher.c
@@ -35,7 +35,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: cipher.c,v 1.71 2004/07/28 09:40:29 markus Exp $");
+RCSID("$OpenBSD: cipher.c,v 1.73 2005/01/23 10:18:12 djm Exp $");
#include "xmalloc.h"
#include "log.h"
@@ -146,7 +146,7 @@ cipher_by_name(const char *name)
{
Cipher *c;
for (c = ciphers; c->name != NULL; c++)
- if (strcasecmp(c->name, name) == 0)
+ if (strcmp(c->name, name) == 0)
return c;
return NULL;
}
@@ -199,8 +199,10 @@ cipher_number(const char *name)
Cipher *c;
if (name == NULL)
return -1;
- c = cipher_by_name(name);
- return (c==NULL) ? -1 : c->number;
+ for (c = ciphers; c->name != NULL; c++)
+ if (strcasecmp(c->name, name) == 0)
+ return c->number;
+ return -1;
}
char *
diff --git a/crypto/openssh/compat.c b/crypto/openssh/compat.c
index 482caba8f758..37a892bc34d4 100644
--- a/crypto/openssh/compat.c
+++ b/crypto/openssh/compat.c
@@ -23,7 +23,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: compat.c,v 1.70 2003/11/02 11:01:03 markus Exp $");
+RCSID("$OpenBSD: compat.c,v 1.71 2005/03/01 10:09:52 djm Exp $");
RCSID("$FreeBSD$");
#include "buffer.h"
@@ -63,24 +63,28 @@ compat_datafellows(const char *version)
"OpenSSH_2.1*,"
"OpenSSH_2.2*", SSH_OLD_SESSIONID|SSH_BUG_BANNER|
SSH_OLD_DHGEX|SSH_BUG_NOREKEY|
- SSH_BUG_EXTEOF},
+ SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR},
{ "OpenSSH_2.3.0*", SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES|
SSH_OLD_DHGEX|SSH_BUG_NOREKEY|
- SSH_BUG_EXTEOF},
+ SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR},
{ "OpenSSH_2.3.*", SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX|
- SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
+ SSH_BUG_NOREKEY|SSH_BUG_EXTEOF|
+ SSH_OLD_FORWARD_ADDR},
{ "OpenSSH_2.5.0p1*,"
"OpenSSH_2.5.1p1*",
SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX|
- SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
+ SSH_BUG_NOREKEY|SSH_BUG_EXTEOF|
+ SSH_OLD_FORWARD_ADDR},
{ "OpenSSH_2.5.0*,"
"OpenSSH_2.5.1*,"
"OpenSSH_2.5.2*", SSH_OLD_DHGEX|SSH_BUG_NOREKEY|
- SSH_BUG_EXTEOF},
- { "OpenSSH_2.5.3*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
+ SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR},
+ { "OpenSSH_2.5.3*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF|
+ SSH_OLD_FORWARD_ADDR},
{ "OpenSSH_2.*,"
"OpenSSH_3.0*,"
- "OpenSSH_3.1*", SSH_BUG_EXTEOF},
+ "OpenSSH_3.1*", SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR},
+ { "OpenSSH_3.*", SSH_OLD_FORWARD_ADDR },
{ "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
{ "OpenSSH*", 0 },
{ "*MindTerm*", 0 },
diff --git a/crypto/openssh/compat.h b/crypto/openssh/compat.h
index 5efb5c29e395..cf92dbdeefcc 100644
--- a/crypto/openssh/compat.h
+++ b/crypto/openssh/compat.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: compat.h,v 1.38 2004/07/11 17:48:47 deraadt Exp $ */
+/* $OpenBSD: compat.h,v 1.39 2005/03/01 10:09:52 djm Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
@@ -55,6 +55,7 @@
#define SSH_BUG_EXTEOF 0x00200000
#define SSH_BUG_PROBE 0x00400000
#define SSH_BUG_FIRSTKEX 0x00800000
+#define SSH_OLD_FORWARD_ADDR 0x01000000
void enable_compat13(void);
void enable_compat20(void);
diff --git a/crypto/openssh/configure.ac b/crypto/openssh/configure.ac
index a1e549728ac5..e0d8aa852149 100644
--- a/crypto/openssh/configure.ac
+++ b/crypto/openssh/configure.ac
@@ -1,4 +1,4 @@
-# $Id: configure.ac,v 1.226 2004/08/16 13:12:06 dtucker Exp $
+# $Id: configure.ac,v 1.260 2005/04/24 07:52:23 dtucker Exp $
# $FreeBSD$
#
# Copyright (c) 1999-2004 Damien Miller
@@ -15,7 +15,7 @@
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-AC_INIT
+AC_INIT(OpenSSH, Portable)
AC_CONFIG_SRCDIR([ssh.c])
AC_CONFIG_HEADER(config.h)
@@ -76,7 +76,7 @@ if test -z "$LD" ; then
LD=$CC
fi
AC_SUBST(LD)
-
+
AC_C_INLINE
if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
CFLAGS="$CFLAGS -Wall -Wpointer-arith -Wno-uninitialized"
@@ -85,7 +85,7 @@ fi
AC_ARG_WITH(rpath,
[ --without-rpath Disable auto-added -R linker paths],
[
- if test "x$withval" = "xno" ; then
+ if test "x$withval" = "xno" ; then
need_dash_r=""
fi
if test "x$withval" = "xyes" ; then
@@ -122,8 +122,11 @@ case "$host" in
LIBS="$LIBS -ls"
])
])
+ dnl Check for various auth function declarations in headers.
+ AC_CHECK_DECLS([authenticate, loginrestrictions, loginsuccess,
+ passwdexpired, setauthdb], , , [#include <usersec.h>])
dnl Check if loginfailed is declared and takes 4 arguments (AIX >= 5.2)
- AC_CHECK_DECL(loginfailed,
+ AC_CHECK_DECLS(loginfailed,
[AC_MSG_CHECKING(if loginfailed takes 4 arguments)
AC_TRY_COMPILE(
[#include <usersec.h>],
@@ -136,7 +139,7 @@ case "$host" in
[#include <usersec.h>]
)
AC_CHECK_FUNCS(setauthdb)
- AC_DEFINE(BROKEN_GETADDRINFO)
+ check_for_aix_broken_getaddrinfo=1
AC_DEFINE(BROKEN_REALPATH)
AC_DEFINE(SETEUID_BREAKS_SETUID)
AC_DEFINE(BROKEN_SETREUID)
@@ -156,7 +159,6 @@ case "$host" in
AC_DEFINE(NO_X11_UNIX_SOCKETS)
AC_DEFINE(NO_IPPORT_RESERVED_CONCEPT)
AC_DEFINE(DISABLE_FD_PASSING)
- AC_DEFINE(SETGROUPS_NOOP)
;;
*-*-dgux*)
AC_DEFINE(IP_TOS_IS_BROKEN)
@@ -220,7 +222,9 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
AC_DEFINE(DISABLE_UTMP)
AC_DEFINE(LOCKED_PASSWD_STRING, "*")
AC_DEFINE(SPT_TYPE,SPT_PSTAT)
+ AC_DEFINE(USE_BTMP, 1, [Use btmp to log bad logins])
check_for_hpux_broken_getaddrinfo=1
+ check_for_conflicting_getspnam=1
LIBS="$LIBS -lsec"
AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***]))
;;
@@ -256,6 +260,8 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
AC_DEFINE(LOCKED_PASSWD_PREFIX, "!")
AC_DEFINE(SPT_TYPE,SPT_REUSEARGV)
AC_DEFINE(LINK_OPNOTSUPP_ERRNO, EPERM)
+ AC_DEFINE(_PATH_BTMP, "/var/log/btmp", [log for bad login attempts])
+ AC_DEFINE(USE_BTMP, 1, [Use btmp to log bad logins])
inet6_default_4in6=yes
case `uname -r` in
1.*|2.0.*)
@@ -269,7 +275,7 @@ mips-sony-bsd|mips-sony-newsos4)
;;
*-*-netbsd*)
check_for_libcrypt_before=1
- if test "x$withval" != "xno" ; then
+ if test "x$withval" != "xno" ; then
need_dash_r=1
fi
;;
@@ -292,7 +298,7 @@ mips-sony-bsd|mips-sony-newsos4)
AC_DEFINE(BROKEN_SAVED_UIDS)
;;
*-*-solaris*)
- if test "x$withval" != "xno" ; then
+ if test "x$withval" != "xno" ; then
need_dash_r=1
fi
AC_DEFINE(PAM_SUN_CODEBASE)
@@ -336,6 +342,8 @@ mips-sony-bsd|mips-sony-newsos4)
*-sni-sysv*)
# /usr/ucblib MUST NOT be searched on ReliantUNIX
AC_CHECK_LIB(dl, dlsym, ,)
+ # -lresolv needs to be at then end of LIBS or DNS lookups break
+ AC_CHECK_LIB(res_query, resolv, [ LIBS="$LIBS -lresolv" ])
IPADDR_IN_DISPLAY=yes
AC_DEFINE(USE_PIPES)
AC_DEFINE(IP_TOS_IS_BROKEN)
@@ -348,39 +356,29 @@ mips-sony-bsd|mips-sony-newsos4)
# Attention: always take care to bind libsocket and libnsl before libc,
# otherwise you will find lots of "SIOCGPGRP errno 22" on syslog
;;
+# UnixWare 1.x, UnixWare 2.x, and others based on code from Univel.
*-*-sysv4.2*)
AC_DEFINE(USE_PIPES)
AC_DEFINE(SETEUID_BREAKS_SETUID)
AC_DEFINE(BROKEN_SETREUID)
AC_DEFINE(BROKEN_SETREGID)
+ AC_DEFINE(PASSWD_NEEDS_USERNAME, 1, [must supply username to passwd])
;;
+# UnixWare 7.x, OpenUNIX 8
*-*-sysv5*)
AC_DEFINE(USE_PIPES)
AC_DEFINE(SETEUID_BREAKS_SETUID)
AC_DEFINE(BROKEN_SETREUID)
AC_DEFINE(BROKEN_SETREGID)
+ AC_DEFINE(PASSWD_NEEDS_USERNAME, 1, [must supply username to passwd])
;;
*-*-sysv*)
;;
+# SCO UNIX and OEM versions of SCO UNIX
*-*-sco3.2v4*)
- CPPFLAGS="$CPPFLAGS -Dftruncate=chsize"
- LIBS="$LIBS -los -lprot -lcrypt_i -lx -ltinfo -lm"
- RANLIB=true
- no_dev_ptmx=1
- AC_DEFINE(BROKEN_SYS_TERMIO_H)
- AC_DEFINE(USE_PIPES)
- AC_DEFINE(HAVE_SECUREWARE)
- AC_DEFINE(DISABLE_SHADOW)
- AC_DEFINE(BROKEN_SAVED_UIDS)
- AC_DEFINE(SETEUID_BREAKS_SETUID)
- AC_DEFINE(BROKEN_SETREUID)
- AC_DEFINE(BROKEN_SETREGID)
- AC_DEFINE(WITH_ABBREV_NO_TTY)
- AC_CHECK_FUNCS(getluid setluid)
- MANTYPE=man
- do_sco3_extra_lib_check=yes
- TEST_SHELL=ksh
+ AC_MSG_ERROR("This Platform is no longer supported.")
;;
+# SCO OpenServer 5.x
*-*-sco3.2v5*)
if test -z "$GCC"; then
CFLAGS="$CFLAGS -belf"
@@ -396,6 +394,7 @@ mips-sony-bsd|mips-sony-newsos4)
AC_DEFINE(BROKEN_SETREGID)
AC_DEFINE(WITH_ABBREV_NO_TTY)
AC_DEFINE(BROKEN_UPDWTMPX)
+ AC_DEFINE(PASSWD_NEEDS_USERNAME, 1, [must supply username to passwd])
AC_CHECK_FUNCS(getluid setluid)
MANTYPE=man
TEST_SHELL=ksh
@@ -476,15 +475,17 @@ esac
AC_ARG_WITH(cflags,
[ --with-cflags Specify additional flags to pass to compiler],
[
- if test "x$withval" != "xno" ; then
+ if test -n "$withval" && test "x$withval" != "xno" && \
+ test "x${withval}" != "xyes"; then
CFLAGS="$CFLAGS $withval"
fi
- ]
+ ]
)
AC_ARG_WITH(cppflags,
[ --with-cppflags Specify additional flags to pass to preprocessor] ,
[
- if test "x$withval" != "xno"; then
+ if test -n "$withval" && test "x$withval" != "xno" && \
+ test "x${withval}" != "xyes"; then
CPPFLAGS="$CPPFLAGS $withval"
fi
]
@@ -492,30 +493,34 @@ AC_ARG_WITH(cppflags,
AC_ARG_WITH(ldflags,
[ --with-ldflags Specify additional flags to pass to linker],
[
- if test "x$withval" != "xno" ; then
+ if test -n "$withval" && test "x$withval" != "xno" && \
+ test "x${withval}" != "xyes"; then
LDFLAGS="$LDFLAGS $withval"
fi
- ]
+ ]
)
AC_ARG_WITH(libs,
[ --with-libs Specify additional libraries to link with],
[
- if test "x$withval" != "xno" ; then
+ if test -n "$withval" && test "x$withval" != "xno" && \
+ test "x${withval}" != "xyes"; then
LIBS="$LIBS $withval"
fi
- ]
+ ]
)
AC_MSG_CHECKING(compiler and flags for sanity)
-AC_TRY_RUN([
+AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([
#include <stdio.h>
int main(){exit(0);}
- ],
+ ])],
[ AC_MSG_RESULT(yes) ],
[
AC_MSG_RESULT(no)
AC_MSG_ERROR([*** compiler cannot create working executables, check config.log ***])
- ]
+ ],
+ [ AC_MSG_WARN([cross compiling: not checking compiler sanity]) ]
)
# Checks for header files.
@@ -526,21 +531,21 @@ AC_CHECK_HEADERS(bstring.h crypt.h dirent.h endian.h features.h \
rpc/types.h security/pam_appl.h shadow.h stddef.h stdint.h \
strings.h sys/dir.h sys/strtio.h sys/audit.h sys/bitypes.h \
sys/bsdtty.h sys/cdefs.h sys/mman.h sys/ndir.h sys/prctl.h \
- sys/pstat.h sys/ptms.h sys/select.h sys/stat.h sys/stream.h \
+ sys/pstat.h sys/select.h sys/stat.h sys/stream.h \
sys/stropts.h sys/sysmacros.h sys/time.h sys/timers.h sys/un.h \
time.h tmpdir.h ttyent.h usersec.h util.h utime.h utmp.h utmpx.h vis.h)
+# sys/ptms.h requires sys/stream.h to be included first on Solaris
+AC_CHECK_HEADERS(sys/ptms.h, [], [], [
+#ifdef HAVE_SYS_STREAM_H
+# include <sys/stream.h>
+#endif
+])
+
# Checks for libraries.
AC_CHECK_FUNC(yp_match, , AC_CHECK_LIB(nsl, yp_match))
AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt))
-dnl SCO OS3 needs this for libwrap
-if test "x$with_tcp_wrappers" != "xno" ; then
- if test "x$do_sco3_extra_lib_check" = "xyes" ; then
- AC_CHECK_LIB(rpc, innetgr, LIBS="-lrpc -lyp -lrpc $LIBS" , , -lyp -lrpc)
- fi
-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,[
@@ -585,10 +590,9 @@ AC_SEARCH_LIBS(basename, gen, AC_DEFINE(HAVE_BASENAME))
dnl zlib is required
AC_ARG_WITH(zlib,
[ --with-zlib=PATH Use zlib in PATH],
- [
- if test "x$withval" = "xno" ; then
- AC_MSG_ERROR([*** zlib is required ***])
- fi
+ [ if test "x$withval" = "xno" ; then
+ AC_MSG_ERROR([*** zlib is required ***])
+ elif test "x$withval" != "xyes"; then
if test -d "$withval/lib"; then
if test -n "${need_dash_r}"; then
LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}"
@@ -607,7 +611,7 @@ AC_ARG_WITH(zlib,
else
CPPFLAGS="-I${withval} ${CPPFLAGS}"
fi
- ]
+ fi ]
)
AC_CHECK_LIB(z, deflate, ,
@@ -640,33 +644,45 @@ AC_ARG_WITH(zlib-version-check,
]
)
-AC_MSG_CHECKING(for zlib 1.1.4 or greater)
-AC_TRY_RUN([
+AC_MSG_CHECKING(for possibly buggy zlib)
+AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#include <stdio.h>
#include <zlib.h>
int main()
{
- int a, b, c, v;
- if (sscanf(ZLIB_VERSION, "%d.%d.%d", &a, &b, &c) != 3)
+ int a=0, b=0, c=0, d=0, n, v;
+ n = sscanf(ZLIB_VERSION, "%d.%d.%d.%d", &a, &b, &c, &d);
+ if (n != 3 && n != 4)
exit(1);
- v = a*1000000 + b*1000 + c;
- if (v >= 1001004)
+ v = a*1000000 + b*10000 + c*100 + d;
+ fprintf(stderr, "found zlib version %s (%d)\n", ZLIB_VERSION, v);
+
+ /* 1.1.4 is OK */
+ if (a == 1 && b == 1 && c >= 4)
+ exit(0);
+
+ /* 1.2.1.2 and up are OK */
+ if (v >= 1020102)
exit(0);
+
exit(2);
}
- ],
- AC_MSG_RESULT(yes),
- [ AC_MSG_RESULT(no)
+ ]])],
+ AC_MSG_RESULT(no),
+ [ AC_MSG_RESULT(yes)
if test -z "$zlib_check_nonfatal" ; then
AC_MSG_ERROR([*** zlib too old - check config.log ***
Your reported zlib version has known security problems. It's possible your
vendor has fixed these problems without changing the version number. If you
are sure this is the case, you can disable the check by running
"./configure --without-zlib-version-check".
-If you are in doubt, upgrade zlib to version 1.1.4 or greater.])
+If you are in doubt, upgrade zlib to version 1.2.1.2 or greater.
+See http://www.gzip.org/zlib/ for details.])
else
AC_MSG_WARN([zlib version may have security problems])
fi
- ]
+ ],
+ [ AC_MSG_WARN([cross compiling: not checking zlib version]) ]
)
dnl UnixWare 2.x
@@ -720,16 +736,20 @@ AC_EGREP_CPP(FOUNDIT,
)
AC_MSG_CHECKING([whether struct dirent allocates space for d_name])
-AC_TRY_RUN(
- [
+AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
#include <sys/types.h>
#include <dirent.h>
int main(void){struct dirent d;exit(sizeof(d.d_name)<=sizeof(char));}
- ],
+ ]])],
[AC_MSG_RESULT(yes)],
[
AC_MSG_RESULT(no)
AC_DEFINE(BROKEN_ONE_BYTE_DIRENT_D_NAME)
+ ],
+ [
+ AC_MSG_WARN([cross compiling: assuming BROKEN_ONE_BYTE_DIRENT_D_NAME])
+ AC_DEFINE(BROKEN_ONE_BYTE_DIRENT_D_NAME)
]
)
@@ -744,8 +764,7 @@ fi
# Check whether user wants S/Key support
SKEY_MSG="no"
AC_ARG_WITH(skey,
- [ --with-skey[[=PATH]] Enable S/Key support
- (optionally in PATH)],
+ [ --with-skey[[=PATH]] Enable S/Key support (optionally in PATH)],
[
if test "x$withval" != "xno" ; then
@@ -757,7 +776,7 @@ AC_ARG_WITH(skey,
AC_DEFINE(SKEY)
LIBS="-lskey $LIBS"
SKEY_MSG="yes"
-
+
AC_MSG_CHECKING([for s/key support])
AC_TRY_RUN(
[
@@ -821,14 +840,14 @@ int main() { char *ff = opie_keyinfo(""); ff=""; return 0; }
# Check whether user wants TCP wrappers support
TCPW_MSG="no"
AC_ARG_WITH(tcp-wrappers,
- [ --with-tcp-wrappers[[=PATH]] Enable tcpwrappers support
- (optionally in PATH)],
+ [ --with-tcp-wrappers[[=PATH]] Enable tcpwrappers support (optionally in PATH)],
[
if test "x$withval" != "xno" ; then
saved_LIBS="$LIBS"
saved_LDFLAGS="$LDFLAGS"
saved_CPPFLAGS="$CPPFLAGS"
- if test -n "${withval}" -a "${withval}" != "yes"; then
+ if test -n "${withval}" && \
+ test "x${withval}" != "xyes"; then
if test -d "${withval}/lib"; then
if test -n "${need_dash_r}"; then
LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}"
@@ -875,12 +894,64 @@ AC_ARG_WITH(tcp-wrappers,
]
)
+# Check whether user wants libedit support
+LIBEDIT_MSG="no"
+AC_ARG_WITH(libedit,
+ [ --with-libedit[[=PATH]] Enable libedit support for sftp],
+ [ if test "x$withval" != "xno" ; then
+ if test "x$withval" != "xyes"; then
+ CPPFLAGS="$CPPFLAGS -I$withval/include"
+ LDFLAGS="$LDFLAGS -L$withval/lib"
+ fi
+ AC_CHECK_LIB(edit, el_init,
+ [ AC_DEFINE(USE_LIBEDIT, [], [Use libedit for sftp])
+ LIBEDIT="-ledit -lcurses"
+ LIBEDIT_MSG="yes"
+ AC_SUBST(LIBEDIT)
+ ],
+ [ AC_MSG_ERROR(libedit not found) ],
+ [ -lcurses ]
+ )
+ fi ]
+)
+
+AUDIT_MODULE=none
+AC_ARG_WITH(audit,
+ [ --with-audit=module Enable EXPERIMENTAL audit support (modules=debug,bsm)],
+ [
+ AC_MSG_CHECKING(for supported audit module)
+ case "$withval" in
+ bsm)
+ AC_MSG_RESULT(bsm)
+ AUDIT_MODULE=bsm
+ dnl Checks for headers, libs and functions
+ AC_CHECK_HEADERS(bsm/audit.h, [],
+ [AC_MSG_ERROR(BSM enabled and bsm/audit.h not found)])
+ AC_CHECK_LIB(bsm, getaudit, [],
+ [AC_MSG_ERROR(BSM enabled and required library not found)])
+ AC_CHECK_FUNCS(getaudit, [],
+ [AC_MSG_ERROR(BSM enabled and required function not found)])
+ # These are optional
+ AC_CHECK_FUNCS(getaudit_addr)
+ AC_DEFINE(USE_BSM_AUDIT, [], [Use BSM audit module])
+ ;;
+ debug)
+ AUDIT_MODULE=debug
+ AC_MSG_RESULT(debug)
+ AC_DEFINE(SSH_AUDIT_EVENTS, [], Use audit debugging module)
+ ;;
+ *)
+ AC_MSG_ERROR([Unknown audit module $withval])
+ ;;
+ esac ]
+)
+
dnl Checks for library functions. Please keep in alphabetical order
AC_CHECK_FUNCS(\
arc4random __b64_ntop b64_ntop __b64_pton b64_pton bcopy \
- bindresvport_sa clock closefrom dirfd fchmod fchown freeaddrinfo \
- futimes getaddrinfo getcwd getgrouplist getnameinfo getopt \
- getpeereid _getpty getrlimit getttyent glob inet_aton \
+ bindresvport_sa clock closefrom dirfd fchdir fchmod fchown \
+ freeaddrinfo futimes getaddrinfo getcwd getgrouplist getnameinfo \
+ getopt getpeereid _getpty getrlimit getttyent glob inet_aton \
inet_ntoa inet_ntop innetgr login_getcapbool md5_crypt memmove \
mkdtemp mmap ngetaddrinfo nsleep ogetaddrinfo openlog_r openpty \
pstat prctl readpassphrase realpath recvmsg rresvport_af sendmsg \
@@ -924,28 +995,32 @@ AC_CHECK_DECLS(h_errno, , ,[#include <netdb.h>])
AC_CHECK_FUNCS(setresuid, [
dnl Some platorms have setresuid that isn't implemented, test for this
AC_MSG_CHECKING(if setresuid seems to work)
- AC_TRY_RUN([
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
#include <stdlib.h>
#include <errno.h>
int main(){errno=0; setresuid(0,0,0); if (errno==ENOSYS) exit(1); else exit(0);}
- ],
+ ]])],
[AC_MSG_RESULT(yes)],
[AC_DEFINE(BROKEN_SETRESUID)
- AC_MSG_RESULT(not implemented)]
+ AC_MSG_RESULT(not implemented)],
+ [AC_MSG_WARN([cross compiling: not checking setresuid])]
)
])
AC_CHECK_FUNCS(setresgid, [
dnl Some platorms have setresgid that isn't implemented, test for this
AC_MSG_CHECKING(if setresgid seems to work)
- AC_TRY_RUN([
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
#include <stdlib.h>
#include <errno.h>
int main(){errno=0; setresgid(0,0,0); if (errno==ENOSYS) exit(1); else exit(0);}
- ],
+ ]])],
[AC_MSG_RESULT(yes)],
[AC_DEFINE(BROKEN_SETRESGID)
- AC_MSG_RESULT(not implemented)]
+ AC_MSG_RESULT(not implemented)],
+ [AC_MSG_WARN([cross compiling: not checking setresuid])]
)
])
@@ -971,17 +1046,18 @@ AC_CHECK_FUNC(getpagesize,
# Check for broken snprintf
if test "x$ac_cv_func_snprintf" = "xyes" ; then
AC_MSG_CHECKING([whether snprintf correctly terminates long strings])
- AC_TRY_RUN(
- [
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
#include <stdio.h>
int main(void){char b[5];snprintf(b,5,"123456789");exit(b[4]!='\0');}
- ],
+ ]])],
[AC_MSG_RESULT(yes)],
[
AC_MSG_RESULT(no)
AC_DEFINE(BROKEN_SNPRINTF)
AC_MSG_WARN([****** Your snprintf() function is broken, complain to your vendor])
- ]
+ ],
+ [ AC_MSG_WARN([cross compiling: Assuming working snprintf()]) ]
)
fi
@@ -993,7 +1069,9 @@ if test "x$ac_cv_func_getpeereid" != "xyes" ; then
[#include <sys/types.h>
#include <sys/socket.h>],
[int i = SO_PEERCRED;],
- [AC_MSG_RESULT(yes)],
+ [ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_SO_PEERCRED, [], [Have PEERCRED socket option])
+ ],
[AC_MSG_RESULT(no)
NO_PEERCHECK=1]
)
@@ -1072,7 +1150,8 @@ main()
)
fi
-if test "x$ac_cv_func_getaddrinfo" = "xyes" -a "x$check_for_hpux_broken_getaddrinfo" = "x1"; then
+if test "x$ac_cv_func_getaddrinfo" = "xyes" && \
+ test "x$check_for_hpux_broken_getaddrinfo" = "x1"; then
AC_MSG_CHECKING(if getaddrinfo seems to work)
AC_TRY_RUN(
[
@@ -1140,6 +1219,83 @@ main(void)
)
fi
+if test "x$ac_cv_func_getaddrinfo" = "xyes" && \
+ test "x$check_for_aix_broken_getaddrinfo" = "x1"; then
+ AC_MSG_CHECKING(if getaddrinfo seems to work)
+ AC_TRY_RUN(
+ [
+#include <stdio.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <errno.h>
+#include <netinet/in.h>
+
+#define TEST_PORT "2222"
+
+int
+main(void)
+{
+ int err, sock;
+ struct addrinfo *gai_ai, *ai, hints;
+ char ntop[NI_MAXHOST], strport[NI_MAXSERV], *name = NULL;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_PASSIVE;
+
+ err = getaddrinfo(name, TEST_PORT, &hints, &gai_ai);
+ if (err != 0) {
+ fprintf(stderr, "getaddrinfo failed (%s)", gai_strerror(err));
+ exit(1);
+ }
+
+ for (ai = gai_ai; ai != NULL; ai = ai->ai_next) {
+ if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
+ continue;
+
+ err = getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop,
+ sizeof(ntop), strport, sizeof(strport),
+ NI_NUMERICHOST|NI_NUMERICSERV);
+
+ if (ai->ai_family == AF_INET && err != 0) {
+ perror("getnameinfo");
+ exit(2);
+ }
+ }
+ exit(0);
+}
+ ],
+ [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(AIX_GETNAMEINFO_HACK, [],
+[Define if you have a getaddrinfo that fails for the all-zeros IPv6 address])
+ ],
+ [
+ AC_MSG_RESULT(no)
+ AC_DEFINE(BROKEN_GETADDRINFO)
+ ]
+ )
+fi
+
+if test "x$check_for_conflicting_getspnam" = "x1"; then
+ AC_MSG_CHECKING(for conflicting getspnam in shadow.h)
+ AC_COMPILE_IFELSE(
+ [
+#include <shadow.h>
+int main(void) {exit(0);}
+ ],
+ [
+ AC_MSG_RESULT(no)
+ ],
+ [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(GETSPNAM_CONFLICTING_DEFS, 1,
+ [Conflicting defs for getspnam])
+ ]
+ )
+fi
+
AC_FUNC_GETPGRP
# Check for PAM libs
@@ -1201,6 +1357,10 @@ AC_ARG_WITH(ssl-dir,
[ --with-ssl-dir=PATH Specify path to OpenSSL installation ],
[
if test "x$withval" != "xno" ; then
+ case "$withval" in
+ # Relative paths
+ ./*|../*) withval="`pwd`/$withval"
+ esac
if test -d "$withval/lib"; then
if test -n "${need_dash_r}"; then
LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}"
@@ -1242,8 +1402,8 @@ AC_TRY_LINK_FUNC(RAND_add, AC_DEFINE(HAVE_OPENSSL),
# Determine OpenSSL header version
AC_MSG_CHECKING([OpenSSL header version])
-AC_TRY_RUN(
- [
+AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
#include <stdio.h>
#include <string.h>
#include <openssl/opensslv.h>
@@ -1261,7 +1421,7 @@ int main(void) {
exit(0);
}
- ],
+ ]])],
[
ssl_header_ver=`cat conftest.sslincver`
AC_MSG_RESULT($ssl_header_ver)
@@ -1269,13 +1429,16 @@ int main(void) {
[
AC_MSG_RESULT(not found)
AC_MSG_ERROR(OpenSSL version header not found.)
+ ],
+ [
+ AC_MSG_WARN([cross compiling: not checking])
]
)
# Determine OpenSSL library version
AC_MSG_CHECKING([OpenSSL library version])
-AC_TRY_RUN(
- [
+AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
#include <stdio.h>
#include <string.h>
#include <openssl/opensslv.h>
@@ -1294,7 +1457,7 @@ int main(void) {
exit(0);
}
- ],
+ ]])],
[
ssl_library_ver=`cat conftest.ssllibver`
AC_MSG_RESULT($ssl_library_ver)
@@ -1302,17 +1465,20 @@ int main(void) {
[
AC_MSG_RESULT(not found)
AC_MSG_ERROR(OpenSSL library not found.)
+ ],
+ [
+ AC_MSG_WARN([cross compiling: not checking])
]
)
# Sanity check OpenSSL headers
AC_MSG_CHECKING([whether OpenSSL's headers match the library])
-AC_TRY_RUN(
- [
+AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
#include <string.h>
#include <openssl/opensslv.h>
int main(void) { exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); }
- ],
+ ]])],
[
AC_MSG_RESULT(yes)
],
@@ -1321,6 +1487,9 @@ int main(void) { exit(SSLeay() == OPENSSL_VERSION_NUMBER ? 0 : 1); }
AC_MSG_ERROR([Your OpenSSL headers do not match your library.
Check config.log for details.
Also see contrib/findssl.sh for help identifying header/library mismatches.])
+ ],
+ [
+ AC_MSG_WARN([cross compiling: not checking])
]
)
@@ -1341,12 +1510,12 @@ fi
# Check wheter OpenSSL seeds itself
AC_MSG_CHECKING([whether OpenSSL's PRNG is internally seeded])
-AC_TRY_RUN(
- [
+AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
#include <string.h>
#include <openssl/rand.h>
int main(void) { exit(RAND_status() == 1 ? 0 : 1); }
- ],
+ ]])],
[
OPENSSL_SEEDS_ITSELF=yes
AC_MSG_RESULT(yes)
@@ -1356,6 +1525,12 @@ int main(void) { exit(RAND_status() == 1 ? 0 : 1); }
# Default to use of the rand helper if OpenSSL doesn't
# seed itself
USE_RAND_HELPER=yes
+ ],
+ [
+ AC_MSG_WARN([cross compiling: assuming yes])
+ # This is safe, since all recent OpenSSL versions will
+ # complain at runtime if not seeded correctly.
+ OPENSSL_SEEDS_ITSELF=yes
]
)
@@ -1376,10 +1551,10 @@ AC_ARG_WITH(rand-helper,
USE_RAND_HELPER=yes
fi
],
-)
+)
# Which randomness source do we use?
-if test ! -z "$OPENSSL_SEEDS_ITSELF" -a -z "$USE_RAND_HELPER" ; then
+if test ! -z "$OPENSSL_SEEDS_ITSELF" && test -z "$USE_RAND_HELPER" ; then
# OpenSSL only
AC_DEFINE(OPENSSL_PRNG_ONLY)
RAND_MSG="OpenSSL internal ONLY"
@@ -1469,10 +1644,11 @@ entropy_timeout=200
AC_ARG_WITH(entropy-timeout,
[ --with-entropy-timeout Specify entropy gathering command timeout (msec)],
[
- if test "x$withval" != "xno" ; then
+ if test -n "$withval" && test "x$withval" != "xno" && \
+ test "x${withval}" != "xyes"; then
entropy_timeout=$withval
fi
- ]
+ ]
)
AC_DEFINE_UNQUOTED(ENTROPY_TIMEOUT_MSEC, $entropy_timeout)
@@ -1480,10 +1656,11 @@ SSH_PRIVSEP_USER=sshd
AC_ARG_WITH(privsep-user,
[ --with-privsep-user=user Specify non-privileged user for privilege separation],
[
- if test -n "$withval"; then
+ if test -n "$withval" && test "x$withval" != "xno" && \
+ test "x${withval}" != "xyes"; then
SSH_PRIVSEP_USER=$withval
fi
- ]
+ ]
)
AC_DEFINE_UNQUOTED(SSH_PRIVSEP_USER, "$SSH_PRIVSEP_USER")
AC_SUBST(SSH_PRIVSEP_USER)
@@ -1740,6 +1917,10 @@ TYPE_SOCKLEN_T
AC_CHECK_TYPES(sig_atomic_t,,,[#include <signal.h>])
+AC_CHECK_TYPES(in_addr_t,,,
+[#include <sys/types.h>
+#include <netinet/in.h>])
+
AC_CACHE_CHECK([for size_t], ac_cv_have_size_t, [
AC_TRY_COMPILE(
[
@@ -1913,17 +2094,17 @@ fi
AC_CHECK_TYPES(struct timespec)
# We need int64_t or else certian parts of the compile will fail.
-if test "x$ac_cv_have_int64_t" = "xno" -a \
- "x$ac_cv_sizeof_long_int" != "x8" -a \
- "x$ac_cv_sizeof_long_long_int" = "x0" ; then
+if test "x$ac_cv_have_int64_t" = "xno" && \
+ test "x$ac_cv_sizeof_long_int" != "x8" && \
+ test "x$ac_cv_sizeof_long_long_int" = "x0" ; then
echo "OpenSSH requires int64_t support. Contact your vendor or install"
echo "an alternative compiler (I.E., GCC) before continuing."
echo ""
exit 1;
else
dnl test snprintf (broken on SCO w/gcc)
- AC_TRY_RUN(
- [
+ AC_RUN_IFELSE(
+ [AC_LANG_SOURCE([[
#include <stdio.h>
#include <string.h>
#ifdef HAVE_SNPRINTF
@@ -1946,7 +2127,8 @@ main()
#else
main() { exit(0); }
#endif
- ], [ true ], [ AC_DEFINE(BROKEN_SNPRINTF) ]
+ ]])], [ true ], [ AC_DEFINE(BROKEN_SNPRINTF) ],
+ AC_MSG_WARN([cross compiling: Assuming working snprintf()])
)
fi
@@ -2051,13 +2233,14 @@ fi
dnl make sure we're using the real structure members and not defines
AC_CACHE_CHECK([for msg_accrights field in struct msghdr],
ac_cv_have_accrights_in_msghdr, [
- AC_TRY_RUN(
+ AC_COMPILE_IFELSE(
[
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
int main() {
#ifdef msg_accrights
+#error "msg_accrights is a macro"
exit(1);
#endif
struct msghdr m;
@@ -2075,13 +2258,14 @@ fi
AC_CACHE_CHECK([for msg_control field in struct msghdr],
ac_cv_have_control_in_msghdr, [
- AC_TRY_RUN(
+ AC_COMPILE_IFELSE(
[
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
int main() {
#ifdef msg_control
+#error "msg_control is a macro"
exit(1);
#endif
struct msghdr m;
@@ -2208,23 +2392,28 @@ AC_ARG_WITH(sectok,
)
# Check whether user wants OpenSC support
+OPENSC_CONFIG="no"
AC_ARG_WITH(opensc,
- AC_HELP_STRING([--with-opensc=PFX],
- [Enable smartcard support using OpenSC]),
- opensc_config_prefix="$withval", opensc_config_prefix="")
-if test x$opensc_config_prefix != x ; then
- OPENSC_CONFIG=$opensc_config_prefix/bin/opensc-config
- AC_PATH_PROG(OPENSC_CONFIG, opensc-config, no)
- if test "$OPENSC_CONFIG" != "no"; then
- LIBOPENSC_CFLAGS=`$OPENSC_CONFIG --cflags`
- LIBOPENSC_LIBS=`$OPENSC_CONFIG --libs`
- CPPFLAGS="$CPPFLAGS $LIBOPENSC_CFLAGS"
- LDFLAGS="$LDFLAGS $LIBOPENSC_LIBS"
- AC_DEFINE(SMARTCARD)
- AC_DEFINE(USE_OPENSC)
- SCARD_MSG="yes, using OpenSC"
- fi
-fi
+ [--with-opensc[[=PFX]] Enable smartcard support using OpenSC (optionally in PATH)],
+ [
+ if test "x$withval" != "xno" ; then
+ if test "x$withval" != "xyes" ; then
+ OPENSC_CONFIG=$withval/bin/opensc-config
+ else
+ AC_PATH_PROG(OPENSC_CONFIG, opensc-config, no)
+ fi
+ if test "$OPENSC_CONFIG" != "no"; then
+ LIBOPENSC_CFLAGS=`$OPENSC_CONFIG --cflags`
+ LIBOPENSC_LIBS=`$OPENSC_CONFIG --libs`
+ CPPFLAGS="$CPPFLAGS $LIBOPENSC_CFLAGS"
+ LDFLAGS="$LDFLAGS $LIBOPENSC_LIBS"
+ AC_DEFINE(SMARTCARD)
+ AC_DEFINE(USE_OPENSC)
+ SCARD_MSG="yes, using OpenSC"
+ fi
+ fi
+ ]
+)
# Check libraries needed by DNS fingerprint support
AC_SEARCH_LIBS(getrrsetbyname, resolv,
@@ -2307,7 +2496,7 @@ AC_ARG_WITH(kerberos5,
AC_DEFINE(HEIMDAL)
K5LIBS="-lkrb5 -ldes"
K5LIBS="$K5LIBS -lcom_err -lasn1"
- AC_CHECK_LIB(roken, net_write,
+ AC_CHECK_LIB(roken, net_write,
[K5LIBS="$K5LIBS -lroken"])
],
[ AC_MSG_RESULT(no)
@@ -2326,7 +2515,7 @@ AC_ARG_WITH(kerberos5,
$K5LIBS)
],
$K5LIBS)
-
+
AC_CHECK_HEADER(gssapi.h, ,
[ unset ac_cv_header_gssapi_h
CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi"
@@ -2366,7 +2555,8 @@ PRIVSEP_PATH=/var/empty
AC_ARG_WITH(privsep-path,
[ --with-privsep-path=xxx Path for privilege separation chroot (default=/var/empty)],
[
- if test "x$withval" != "$no" ; then
+ if test -n "$withval" && test "x$withval" != "xno" && \
+ test "x${withval}" != "xyes"; then
PRIVSEP_PATH=$withval
fi
]
@@ -2376,7 +2566,8 @@ AC_SUBST(PRIVSEP_PATH)
AC_ARG_WITH(xauth,
[ --with-xauth=PATH Specify path to xauth program ],
[
- if test "x$withval" != "xno" ; then
+ if test -n "$withval" && test "x$withval" != "xno" && \
+ test "x${withval}" != "xyes"; then
xauth_path=$withval
fi
],
@@ -2419,6 +2610,10 @@ if test ! -z "$MAIL" ; then
AC_DEFINE_UNQUOTED(MAIL_DIRECTORY, "$maildir")
fi
+if test ! -z "$cross_compiling" && test "x$cross_compiling" = "xyes"; then
+ AC_MSG_WARN([cross compiling: Disabling /dev/ptmx test])
+ disable_ptmx_check=yes
+fi
if test -z "$no_dev_ptmx" ; then
if test "x$disable_ptmx_check" != "xyes" ; then
AC_CHECK_FILE("/dev/ptmx",
@@ -2429,12 +2624,17 @@ if test -z "$no_dev_ptmx" ; then
)
fi
fi
-AC_CHECK_FILE("/dev/ptc",
- [
- AC_DEFINE_UNQUOTED(HAVE_DEV_PTS_AND_PTC)
- have_dev_ptc=1
- ]
-)
+
+if test ! -z "$cross_compiling" && test "x$cross_compiling" != "xyes"; then
+ AC_CHECK_FILE("/dev/ptc",
+ [
+ AC_DEFINE_UNQUOTED(HAVE_DEV_PTS_AND_PTC)
+ have_dev_ptc=1
+ ]
+ )
+else
+ AC_MSG_WARN([cross compiling: Disabling /dev/ptc test])
+fi
# Options from here on. Some of these are preset by platform above
AC_ARG_WITH(mantype,
@@ -2485,7 +2685,7 @@ AC_ARG_WITH(md5-passwords,
AC_ARG_WITH(shadow,
[ --without-shadow Disable shadow password support],
[
- if test "x$withval" = "xno" ; then
+ if test "x$withval" = "xno" ; then
AC_DEFINE(DISABLE_SHADOW)
disable_shadow=yes
fi
@@ -2520,7 +2720,7 @@ else
AC_ARG_WITH(ipaddr-display,
[ --with-ipaddr-display Use ip address instead of hostname in \$DISPLAY],
[
- if test "x$withval" != "xno" ; then
+ if test "x$withval" != "xno" ; then
AC_DEFINE(IPADDR_IN_DISPLAY)
DISPLAY_HACK_MSG="yes"
fi
@@ -2530,18 +2730,30 @@ fi
# check for /etc/default/login and use it if present.
AC_ARG_ENABLE(etc-default-login,
- [ --disable-etc-default-login Disable using PATH from /etc/default/login [no]],,
-[
-AC_CHECK_FILE("/etc/default/login", [ external_path_file=/etc/default/login ])
+ [ --disable-etc-default-login Disable using PATH from /etc/default/login [no]],
+ [ if test "x$enableval" = "xno"; then
+ AC_MSG_NOTICE([/etc/default/login handling disabled])
+ etc_default_login=no
+ else
+ etc_default_login=yes
+ fi ],
+ [ etc_default_login=yes ]
+)
-if test "x$external_path_file" = "x/etc/default/login"; then
- AC_DEFINE(HAVE_ETC_DEFAULT_LOGIN)
+if test "x$etc_default_login" != "xno"; then
+ AC_CHECK_FILE("/etc/default/login",
+ [ external_path_file=/etc/default/login ])
+ if test ! -z "$cross_compiling" && test "x$cross_compiling" = "xyes";
+ then
+ AC_MSG_WARN([cross compiling: Disabling /etc/default/login test])
+ elif test "x$external_path_file" = "x/etc/default/login"; then
+ AC_DEFINE(HAVE_ETC_DEFAULT_LOGIN)
+ fi
fi
-])
dnl BSD systems use /etc/login.conf so --with-default-path= has no effect
-if test $ac_cv_func_login_getcapbool = "yes" -a \
- $ac_cv_header_login_cap_h = "yes" ; then
+if test $ac_cv_func_login_getcapbool = "yes" && \
+ test $ac_cv_header_login_cap_h = "yes" ; then
external_path_file=/etc/login.conf
fi
@@ -2554,7 +2766,7 @@ AC_ARG_WITH(default-path,
AC_MSG_WARN([
--with-default-path=PATH has no effect on this system.
Edit /etc/login.conf instead.])
- elif test "x$withval" != "xno" ; then
+ elif test "x$withval" != "xno" ; then
if test ! -z "$external_path_file" ; then
AC_MSG_WARN([
--with-default-path=PATH will only be used if PATH is not defined in
@@ -2595,11 +2807,11 @@ main()
{
FILE *fd;
int rc;
-
+
fd = fopen(DATA,"w");
if(fd == NULL)
exit(1);
-
+
if ((rc = fprintf(fd,"%s", _PATH_STDPATH)) < 0)
exit(1);
@@ -2636,7 +2848,8 @@ fi
AC_ARG_WITH(superuser-path,
[ --with-superuser-path= Specify different path for super-user],
[
- if test "x$withval" != "xno" ; then
+ if test -n "$withval" && test "x$withval" != "xno" && \
+ test "x${withval}" != "xyes"; then
AC_DEFINE_UNQUOTED(SUPERUSER_PATH, "$withval")
superuser_path=$withval
fi
@@ -2672,7 +2885,7 @@ BSD_AUTH_MSG=no
AC_ARG_WITH(bsd-auth,
[ --with-bsd-auth Enable BSD auth support],
[
- if test "x$withval" != "xno" ; then
+ if test "x$withval" != "xno" ; then
AC_DEFINE(BSD_AUTH)
BSD_AUTH_MSG=yes
fi
@@ -2682,7 +2895,7 @@ AC_ARG_WITH(bsd-auth,
# Where to place sshd.pid
piddir=/var/run
# make sure the directory exists
-if test ! -d $piddir ; then
+if test ! -d $piddir ; then
piddir=`eval echo ${sysconfdir}`
case $piddir in
NONE/*) piddir=`echo $piddir | sed "s~NONE~$ac_default_prefix~"` ;;
@@ -2692,9 +2905,10 @@ fi
AC_ARG_WITH(pid-dir,
[ --with-pid-dir=PATH Specify location of ssh.pid file],
[
- if test "x$withval" != "xno" ; then
+ if test -n "$withval" && test "x$withval" != "xno" && \
+ test "x${withval}" != "xyes"; then
piddir=$withval
- if test ! -d $piddir ; then
+ if test ! -d $piddir ; then
AC_MSG_WARN([** no $piddir directory on this system **])
fi
fi
@@ -2772,9 +2986,9 @@ AC_ARG_ENABLE(pututxline,
AC_ARG_WITH(lastlog,
[ --with-lastlog=FILE|DIR specify lastlog location [common locations]],
[
- if test "x$withval" = "xno" ; then
+ if test "x$withval" = "xno" ; then
AC_DEFINE(DISABLE_LASTLOG)
- else
+ elif test -n "$withval" && test "x${withval}" != "xyes"; then
conf_lastlog_location=$withval
fi
]
@@ -2841,7 +3055,7 @@ fi
if test -n "$conf_lastlog_location"; then
AC_DEFINE_UNQUOTED(CONF_LASTLOG_FILE, "$conf_lastlog_location")
-fi
+fi
dnl utmp detection
AC_MSG_CHECKING([if your system defines UTMP_FILE])
@@ -2871,7 +3085,7 @@ if test -z "$conf_utmp_location"; then
fi
if test -n "$conf_utmp_location"; then
AC_DEFINE_UNQUOTED(CONF_UTMP_FILE, "$conf_utmp_location")
-fi
+fi
dnl wtmp detection
AC_MSG_CHECKING([if your system defines WTMP_FILE])
@@ -2901,7 +3115,7 @@ if test -z "$conf_wtmp_location"; then
fi
if test -n "$conf_wtmp_location"; then
AC_DEFINE_UNQUOTED(CONF_WTMP_FILE, "$conf_wtmp_location")
-fi
+fi
dnl utmpx detection - I don't know any system so perverse as to require
@@ -2929,7 +3143,7 @@ if test -z "$conf_utmpx_location"; then
fi
else
AC_DEFINE_UNQUOTED(CONF_UTMPX_FILE, "$conf_utmpx_location")
-fi
+fi
dnl wtmpx detection
AC_MSG_CHECKING([if your system defines WTMPX_FILE])
@@ -2954,7 +3168,7 @@ if test -z "$conf_wtmpx_location"; then
fi
else
AC_DEFINE_UNQUOTED(CONF_WTMPX_FILE, "$conf_wtmpx_location")
-fi
+fi
if test ! -z "$blibpath" ; then
@@ -2971,7 +3185,8 @@ if test "$ac_cv_lib_pam_pam_set_item" = yes ; then
fi
AC_EXEEXT
-AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openbsd-compat/Makefile scard/Makefile ssh_prng_cmds])
+AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openbsd-compat/Makefile \
+ scard/Makefile ssh_prng_cmds survey.sh])
AC_OUTPUT
# Print summary of options
@@ -3018,6 +3233,7 @@ echo " S/KEY support: $SKEY_MSG"
echo " OPIE support: $OPIE_MSG"
echo " TCP Wrappers support: $TCPW_MSG"
echo " MD5 password support: $MD5_MSG"
+echo " libedit support: $LIBEDIT_MSG"
echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
echo " BSD Auth support: $BSD_AUTH_MSG"
@@ -3038,7 +3254,8 @@ echo " Libraries: ${LIBWRAP} ${LIBPAM} ${LIBS}"
echo ""
if test "x$MAKE_PACKAGE_SUPPORTED" = "xyes" ; then
- echo "SVR4 style packages are supported with \"make package\"\n"
+ echo "SVR4 style packages are supported with \"make package\""
+ echo ""
fi
if test "x$PAM_MSG" = "xyes" ; then
@@ -3067,3 +3284,7 @@ if test ! -z "$NO_PEERCHECK" ; then
echo ""
fi
+if test "$AUDIT_MODULE" = "bsm" ; then
+ echo "WARNING: BSM audit support is currently considered EXPERIMENTAL."
+ echo "See the Solaris section in README.platform for details."
+fi
diff --git a/crypto/openssh/hostfile.c b/crypto/openssh/hostfile.c
index 88c054912782..bf2a31c9bab3 100644
--- a/crypto/openssh/hostfile.c
+++ b/crypto/openssh/hostfile.c
@@ -36,13 +36,102 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: hostfile.c,v 1.32 2003/11/10 16:23:41 jakob Exp $");
+RCSID("$OpenBSD: hostfile.c,v 1.34 2005/03/10 22:01:05 deraadt Exp $");
+
+#include <resolv.h>
+#include <openssl/hmac.h>
+#include <openssl/sha.h>
#include "packet.h"
#include "match.h"
#include "key.h"
#include "hostfile.h"
#include "log.h"
+#include "xmalloc.h"
+
+static int
+extract_salt(const char *s, u_int l, char *salt, size_t salt_len)
+{
+ char *p, *b64salt;
+ u_int b64len;
+ int ret;
+
+ if (l < sizeof(HASH_MAGIC) - 1) {
+ debug2("extract_salt: string too short");
+ return (-1);
+ }
+ if (strncmp(s, HASH_MAGIC, sizeof(HASH_MAGIC) - 1) != 0) {
+ debug2("extract_salt: invalid magic identifier");
+ return (-1);
+ }
+ s += sizeof(HASH_MAGIC) - 1;
+ l -= sizeof(HASH_MAGIC) - 1;
+ if ((p = memchr(s, HASH_DELIM, l)) == NULL) {
+ debug2("extract_salt: missing salt termination character");
+ return (-1);
+ }
+
+ b64len = p - s;
+ /* Sanity check */
+ if (b64len == 0 || b64len > 1024) {
+ debug2("extract_salt: bad encoded salt length %u", b64len);
+ return (-1);
+ }
+ b64salt = xmalloc(1 + b64len);
+ memcpy(b64salt, s, b64len);
+ b64salt[b64len] = '\0';
+
+ ret = __b64_pton(b64salt, salt, salt_len);
+ xfree(b64salt);
+ if (ret == -1) {
+ debug2("extract_salt: salt decode error");
+ return (-1);
+ }
+ if (ret != SHA_DIGEST_LENGTH) {
+ debug2("extract_salt: expected salt len %u, got %u",
+ salt_len, ret);
+ return (-1);
+ }
+
+ return (0);
+}
+
+char *
+host_hash(const char *host, const char *name_from_hostfile, u_int src_len)
+{
+ const EVP_MD *md = EVP_sha1();
+ HMAC_CTX mac_ctx;
+ char salt[256], result[256], uu_salt[512], uu_result[512];
+ static char encoded[1024];
+ u_int i, len;
+
+ len = EVP_MD_size(md);
+
+ if (name_from_hostfile == NULL) {
+ /* Create new salt */
+ for (i = 0; i < len; i++)
+ salt[i] = arc4random();
+ } else {
+ /* Extract salt from known host entry */
+ if (extract_salt(name_from_hostfile, src_len, salt,
+ sizeof(salt)) == -1)
+ return (NULL);
+ }
+
+ HMAC_Init(&mac_ctx, salt, len, md);
+ HMAC_Update(&mac_ctx, host, strlen(host));
+ HMAC_Final(&mac_ctx, result, NULL);
+ HMAC_cleanup(&mac_ctx);
+
+ if (__b64_ntop(salt, len, uu_salt, sizeof(uu_salt)) == -1 ||
+ __b64_ntop(result, len, uu_result, sizeof(uu_result)) == -1)
+ fatal("host_hash: __b64_ntop failed");
+
+ snprintf(encoded, sizeof(encoded), "%s%s%c%s", HASH_MAGIC, uu_salt,
+ HASH_DELIM, uu_result);
+
+ return (encoded);
+}
/*
* Parses an RSA (number of bits, e, n) or DSA key from a string. Moves the
@@ -104,7 +193,7 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
char line[8192];
int linenum = 0;
u_int kbits;
- char *cp, *cp2;
+ char *cp, *cp2, *hashed_host;
HostStatus end_return;
debug3("check_host_in_hostfile: filename %s", filename);
@@ -137,8 +226,18 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
;
/* Check if the host name matches. */
- if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1)
- continue;
+ if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1) {
+ if (*cp != HASH_DELIM)
+ continue;
+ hashed_host = host_hash(host, cp, (u_int) (cp2 - cp));
+ if (hashed_host == NULL) {
+ debug("Invalid hashed host line %d of %s",
+ linenum, filename);
+ continue;
+ }
+ if (strncmp(hashed_host, cp, (u_int) (cp2 - cp)) != 0)
+ continue;
+ }
/* Got a match. Skip host name. */
cp = cp2;
@@ -211,16 +310,28 @@ lookup_key_in_hostfile_by_type(const char *filename, const char *host,
*/
int
-add_host_to_hostfile(const char *filename, const char *host, const Key *key)
+add_host_to_hostfile(const char *filename, const char *host, const Key *key,
+ int store_hash)
{
FILE *f;
int success = 0;
+ char *hashed_host;
+
if (key == NULL)
return 1; /* XXX ? */
f = fopen(filename, "a");
if (!f)
return 0;
- fprintf(f, "%s ", host);
+
+ if (store_hash) {
+ if ((hashed_host = host_hash(host, NULL, 0)) == NULL) {
+ error("add_host_to_hostfile: host_hash failed");
+ fclose(f);
+ return 0;
+ }
+ }
+ fprintf(f, "%s ", store_hash ? hashed_host : host);
+
if (key_write(key, f)) {
success = 1;
} else {
diff --git a/crypto/openssh/includes.h b/crypto/openssh/includes.h
index 0dc2fb7baf02..3cbc2c2e71c2 100644
--- a/crypto/openssh/includes.h
+++ b/crypto/openssh/includes.h
@@ -186,7 +186,7 @@ __RCSID(msg)
* On HP-UX 11.11, shadow.h and prot.h provide conflicting declarations
* of getspnam when _INCLUDE__STDC__ is defined, so we unset it here.
*/
-#ifdef __hpux
+#ifdef GETSPNAM_CONFLICTING_DEFS
# ifdef _INCLUDE__STDC__
# undef _INCLUDE__STDC__
# endif
diff --git a/crypto/openssh/key.c b/crypto/openssh/key.c
index 21b0869df09a..e419304641b1 100644
--- a/crypto/openssh/key.c
+++ b/crypto/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.56 2004/07/28 09:40:29 markus Exp $");
+RCSID("$OpenBSD: key.c,v 1.57 2004/10/29 23:57:05 djm Exp $");
#include <openssl/evp.h>
@@ -681,8 +681,8 @@ Key *
key_from_blob(const u_char *blob, u_int blen)
{
Buffer b;
- char *ktype;
int rlen, type;
+ char *ktype = NULL;
Key *key = NULL;
#ifdef DEBUG_PK
@@ -690,24 +690,38 @@ key_from_blob(const u_char *blob, u_int blen)
#endif
buffer_init(&b);
buffer_append(&b, blob, blen);
- ktype = buffer_get_string(&b, NULL);
+ if ((ktype = buffer_get_string_ret(&b, NULL)) == NULL) {
+ error("key_from_blob: can't read key type");
+ goto out;
+ }
+
type = key_type_from_name(ktype);
switch (type) {
case KEY_RSA:
key = key_new(type);
- buffer_get_bignum2(&b, key->rsa->e);
- buffer_get_bignum2(&b, key->rsa->n);
+ if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 ||
+ buffer_get_bignum2_ret(&b, key->rsa->n) == -1) {
+ error("key_from_blob: can't read rsa key");
+ key_free(key);
+ key = NULL;
+ goto out;
+ }
#ifdef DEBUG_PK
RSA_print_fp(stderr, key->rsa, 8);
#endif
break;
case KEY_DSA:
key = key_new(type);
- buffer_get_bignum2(&b, key->dsa->p);
- buffer_get_bignum2(&b, key->dsa->q);
- buffer_get_bignum2(&b, key->dsa->g);
- buffer_get_bignum2(&b, key->dsa->pub_key);
+ if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 ||
+ buffer_get_bignum2_ret(&b, key->dsa->q) == -1 ||
+ buffer_get_bignum2_ret(&b, key->dsa->g) == -1 ||
+ buffer_get_bignum2_ret(&b, key->dsa->pub_key) == -1) {
+ error("key_from_blob: can't read dsa key");
+ key_free(key);
+ key = NULL;
+ goto out;
+ }
#ifdef DEBUG_PK
DSA_print_fp(stderr, key->dsa, 8);
#endif
@@ -717,12 +731,14 @@ key_from_blob(const u_char *blob, u_int blen)
break;
default:
error("key_from_blob: cannot handle type %s", ktype);
- break;
+ goto out;
}
rlen = buffer_len(&b);
if (key != NULL && rlen != 0)
error("key_from_blob: remaining bytes in key blob %d", rlen);
- xfree(ktype);
+ out:
+ if (ktype != NULL)
+ xfree(ktype);
buffer_free(&b);
return key;
}
diff --git a/crypto/openssh/loginrec.c b/crypto/openssh/loginrec.c
index 18eca382a89d..44dd823f449d 100644
--- a/crypto/openssh/loginrec.c
+++ b/crypto/openssh/loginrec.c
@@ -25,130 +25,125 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/*
+ * The btmp logging code is derived from login.c from util-linux and is under
+ * the the following license:
+ *
+ * Copyright (c) 1980, 1987, 1988 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
/**
** loginrec.c: platform-independent login recording and lastlog retrieval
**/
/*
- The new login code explained
- ============================
-
- This code attempts to provide a common interface to login recording
- (utmp and friends) and last login time retrieval.
-
- Its primary means of achieving this is to use 'struct logininfo', a
- union of all the useful fields in the various different types of
- system login record structures one finds on UNIX variants.
-
- We depend on autoconf to define which recording methods are to be
- used, and which fields are contained in the relevant data structures
- on the local system. Many C preprocessor symbols affect which code
- gets compiled here.
-
- The code is designed to make it easy to modify a particular
- recording method, without affecting other methods nor requiring so
- many nested conditional compilation blocks as were commonplace in
- the old code.
-
- For login recording, we try to use the local system's libraries as
- these are clearly most likely to work correctly. For utmp systems
- this usually means login() and logout() or setutent() etc., probably
- in libutil, along with logwtmp() etc. On these systems, we fall back
- to writing the files directly if we have to, though this method
- requires very thorough testing so we do not corrupt local auditing
- information. These files and their access methods are very system
- specific indeed.
-
- For utmpx systems, the corresponding library functions are
- setutxent() etc. To the author's knowledge, all utmpx systems have
- these library functions and so no direct write is attempted. If such
- a system exists and needs support, direct analogues of the [uw]tmp
- code should suffice.
-
- Retrieving the time of last login ('lastlog') is in some ways even
- more problemmatic than login recording. Some systems provide a
- simple table of all users which we seek based on uid and retrieve a
- relatively standard structure. Others record the same information in
- a directory with a separate file, and others don't record the
- information separately at all. For systems in the latter category,
- we look backwards in the wtmp or wtmpx file for the last login entry
- for our user. Naturally this is slower and on busy systems could
- incur a significant performance penalty.
-
- Calling the new code
- --------------------
-
- In OpenSSH all login recording and retrieval is performed in
- login.c. Here you'll find working examples. Also, in the logintest.c
- program there are more examples.
-
- Internal handler calling method
- -------------------------------
-
- When a call is made to login_login() or login_logout(), both
- routines set a struct logininfo flag defining which action (log in,
- or log out) is to be taken. They both then call login_write(), which
- calls whichever of the many structure-specific handlers autoconf
- selects for the local system.
-
- The handlers themselves handle system data structure specifics. Both
- struct utmp and struct utmpx have utility functions (see
- construct_utmp*()) to try to make it simpler to add extra systems
- that introduce new features to either structure.
-
- While it may seem terribly wasteful to replicate so much similar
- code for each method, experience has shown that maintaining code to
- write both struct utmp and utmpx in one function, whilst maintaining
- support for all systems whether they have library support or not, is
- a difficult and time-consuming task.
-
- Lastlog support proceeds similarly. Functions login_get_lastlog()
- (and its OpenSSH-tuned friend login_get_lastlog_time()) call
- getlast_entry(), which tries one of three methods to find the last
- login time. It uses local system lastlog support if it can,
- otherwise it tries wtmp or wtmpx before giving up and returning 0,
- meaning "tilt".
-
- Maintenance
- -----------
-
- In many cases it's possible to tweak autoconf to select the correct
- methods for a particular platform, either by improving the detection
- code (best), or by presetting DISABLE_<method> or CONF_<method>_FILE
- symbols for the platform.
-
- Use logintest to check which symbols are defined before modifying
- configure.ac and loginrec.c. (You have to build logintest yourself
- with 'make logintest' as it's not built by default.)
-
- Otherwise, patches to the specific method(s) are very helpful!
-
-*/
-
-/**
- ** TODO:
- ** homegrown ttyslot()
- ** test, test, test
- **
- ** Platform status:
- ** ----------------
- **
- ** Known good:
- ** Linux (Redhat 6.2, Debian)
- ** Solaris
- ** HP-UX 10.20 (gcc only)
- ** IRIX
- ** NeXT - M68k/HPPA/Sparc (4.2/3.3)
- **
- ** Testing required: Please send reports!
- ** NetBSD
- ** HP-UX 11
- ** AIX
- **
- ** Platforms with known problems:
- ** Some variants of Slackware Linux
- **
- **/
+ * The new login code explained
+ * ============================
+ *
+ * This code attempts to provide a common interface to login recording
+ * (utmp and friends) and last login time retrieval.
+ *
+ * Its primary means of achieving this is to use 'struct logininfo', a
+ * union of all the useful fields in the various different types of
+ * system login record structures one finds on UNIX variants.
+ *
+ * We depend on autoconf to define which recording methods are to be
+ * used, and which fields are contained in the relevant data structures
+ * on the local system. Many C preprocessor symbols affect which code
+ * gets compiled here.
+ *
+ * The code is designed to make it easy to modify a particular
+ * recording method, without affecting other methods nor requiring so
+ * many nested conditional compilation blocks as were commonplace in
+ * the old code.
+ *
+ * For login recording, we try to use the local system's libraries as
+ * these are clearly most likely to work correctly. For utmp systems
+ * this usually means login() and logout() or setutent() etc., probably
+ * in libutil, along with logwtmp() etc. On these systems, we fall back
+ * to writing the files directly if we have to, though this method
+ * requires very thorough testing so we do not corrupt local auditing
+ * information. These files and their access methods are very system
+ * specific indeed.
+ *
+ * For utmpx systems, the corresponding library functions are
+ * setutxent() etc. To the author's knowledge, all utmpx systems have
+ * these library functions and so no direct write is attempted. If such
+ * a system exists and needs support, direct analogues of the [uw]tmp
+ * code should suffice.
+ *
+ * Retrieving the time of last login ('lastlog') is in some ways even
+ * more problemmatic than login recording. Some systems provide a
+ * simple table of all users which we seek based on uid and retrieve a
+ * relatively standard structure. Others record the same information in
+ * a directory with a separate file, and others don't record the
+ * information separately at all. For systems in the latter category,
+ * we look backwards in the wtmp or wtmpx file for the last login entry
+ * for our user. Naturally this is slower and on busy systems could
+ * incur a significant performance penalty.
+ *
+ * Calling the new code
+ * --------------------
+ *
+ * In OpenSSH all login recording and retrieval is performed in
+ * login.c. Here you'll find working examples. Also, in the logintest.c
+ * program there are more examples.
+ *
+ * Internal handler calling method
+ * -------------------------------
+ *
+ * When a call is made to login_login() or login_logout(), both
+ * routines set a struct logininfo flag defining which action (log in,
+ * or log out) is to be taken. They both then call login_write(), which
+ * calls whichever of the many structure-specific handlers autoconf
+ * selects for the local system.
+ *
+ * The handlers themselves handle system data structure specifics. Both
+ * struct utmp and struct utmpx have utility functions (see
+ * construct_utmp*()) to try to make it simpler to add extra systems
+ * that introduce new features to either structure.
+ *
+ * While it may seem terribly wasteful to replicate so much similar
+ * code for each method, experience has shown that maintaining code to
+ * write both struct utmp and utmpx in one function, whilst maintaining
+ * support for all systems whether they have library support or not, is
+ * a difficult and time-consuming task.
+ *
+ * Lastlog support proceeds similarly. Functions login_get_lastlog()
+ * (and its OpenSSH-tuned friend login_get_lastlog_time()) call
+ * getlast_entry(), which tries one of three methods to find the last
+ * login time. It uses local system lastlog support if it can,
+ * otherwise it tries wtmp or wtmpx before giving up and returning 0,
+ * meaning "tilt".
+ *
+ * Maintenance
+ * -----------
+ *
+ * In many cases it's possible to tweak autoconf to select the correct
+ * methods for a particular platform, either by improving the detection
+ * code (best), or by presetting DISABLE_<method> or CONF_<method>_FILE
+ * symbols for the platform.
+ *
+ * Use logintest to check which symbols are defined before modifying
+ * configure.ac and loginrec.c. (You have to build logintest yourself
+ * with 'make logintest' as it's not built by default.)
+ *
+ * Otherwise, patches to the specific method(s) are very helpful!
+ */
#include "includes.h"
@@ -157,18 +152,22 @@
#include "loginrec.h"
#include "log.h"
#include "atomicio.h"
-
-RCSID("$Id: loginrec.c,v 1.58 2004/08/15 09:12:52 djm Exp $");
-RCSID("$FreeBSD$");
+#include "packet.h"
+#include "canohost.h"
+#include "auth.h"
+#include "buffer.h"
#ifdef HAVE_UTIL_H
-# include <util.h>
+# include <util.h>
#endif
#ifdef HAVE_LIBUTIL_H
-# include <libutil.h>
+# include <libutil.h>
#endif
+RCSID("$Id: loginrec.c,v 1.67 2005/02/15 11:19:28 dtucker Exp $");
+RCSID("$FreeBSD$");
+
/**
** prototypes for helper functions in this file
**/
@@ -195,14 +194,17 @@ int lastlog_get_entry(struct logininfo *li);
int wtmp_get_entry(struct logininfo *li);
int wtmpx_get_entry(struct logininfo *li);
+extern Buffer loginmsg;
+
/* pick the shortest string */
-#define MIN_SIZEOF(s1,s2) ( sizeof(s1) < sizeof(s2) ? sizeof(s1) : sizeof(s2) )
+#define MIN_SIZEOF(s1,s2) (sizeof(s1) < sizeof(s2) ? sizeof(s1) : sizeof(s2))
/**
** platform-independent login functions
**/
-/* login_login(struct logininfo *) -Record a login
+/*
+ * login_login(struct logininfo *) - Record a login
*
* Call with a pointer to a struct logininfo initialised with
* login_init_entry() or login_alloc_entry()
@@ -212,14 +214,15 @@ int wtmpx_get_entry(struct logininfo *li);
* 0 on failure (will use OpenSSH's logging facilities for diagnostics)
*/
int
-login_login (struct logininfo *li)
+login_login(struct logininfo *li)
{
li->type = LTYPE_LOGIN;
- return login_write(li);
+ return (login_write(li));
}
-/* login_logout(struct logininfo *) - Record a logout
+/*
+ * login_logout(struct logininfo *) - Record a logout
*
* Call as with login_login()
*
@@ -231,10 +234,11 @@ int
login_logout(struct logininfo *li)
{
li->type = LTYPE_LOGOUT;
- return login_write(li);
+ return (login_write(li));
}
-/* login_get_lastlog_time(int) - Retrieve the last login time
+/*
+ * login_get_lastlog_time(int) - Retrieve the last login time
*
* Retrieve the last login time for the given uid. Will try to use the
* system lastlog facilities if they are available, but will fall back
@@ -257,12 +261,13 @@ login_get_lastlog_time(const int uid)
struct logininfo li;
if (login_get_lastlog(&li, uid))
- return li.tv_sec;
+ return (li.tv_sec);
else
- return 0;
+ return (0);
}
-/* login_get_lastlog(struct logininfo *, int) - Retrieve a lastlog entry
+/*
+ * login_get_lastlog(struct logininfo *, int) - Retrieve a lastlog entry
*
* Retrieve a logininfo structure populated (only partially) with
* information from the system lastlog data, or from wtmp/wtmpx if no
@@ -273,7 +278,6 @@ login_get_lastlog_time(const int uid)
* Returns:
* >0: A pointer to your struct logininfo if successful
* 0 on failure (will use OpenSSH's logging facilities for diagnostics)
- *
*/
struct logininfo *
login_get_lastlog(struct logininfo *li, const int uid)
@@ -290,20 +294,21 @@ login_get_lastlog(struct logininfo *li, const int uid)
*/
pw = getpwuid(uid);
if (pw == NULL)
- fatal("login_get_lastlog: Cannot find account for uid %i", uid);
+ fatal("%s: Cannot find account for uid %i", __func__, uid);
/* No MIN_SIZEOF here - we absolutely *must not* truncate the
- * username */
+ * username (XXX - so check for trunc!) */
strlcpy(li->username, pw->pw_name, sizeof(li->username));
if (getlast_entry(li))
- return li;
+ return (li);
else
- return NULL;
+ return (NULL);
}
-/* login_alloc_entry(int, char*, char*, char*) - Allocate and initialise
+/*
+ * login_alloc_entry(int, char*, char*, char*) - Allocate and initialise
* a logininfo structure
*
* This function creates a new struct logininfo, a data structure
@@ -314,13 +319,13 @@ login_get_lastlog(struct logininfo *li, const int uid)
*/
struct
logininfo *login_alloc_entry(int pid, const char *username,
- const char *hostname, const char *line)
+ const char *hostname, const char *line)
{
struct logininfo *newli;
- newli = (struct logininfo *) xmalloc (sizeof(*newli));
- (void)login_init_entry(newli, pid, username, hostname, line);
- return newli;
+ newli = xmalloc(sizeof(*newli));
+ login_init_entry(newli, pid, username, hostname, line);
+ return (newli);
}
@@ -342,7 +347,7 @@ login_free_entry(struct logininfo *li)
*/
int
login_init_entry(struct logininfo *li, int pid, const char *username,
- const char *hostname, const char *line)
+ const char *hostname, const char *line)
{
struct passwd *pw;
@@ -357,18 +362,21 @@ login_init_entry(struct logininfo *li, int pid, const char *username,
if (username) {
strlcpy(li->username, username, sizeof(li->username));
pw = getpwnam(li->username);
- if (pw == NULL)
- fatal("login_init_entry: Cannot find user \"%s\"", li->username);
+ if (pw == NULL) {
+ fatal("%s: Cannot find user \"%s\"", __func__,
+ li->username);
+ }
li->uid = pw->pw_uid;
}
if (hostname)
strlcpy(li->hostname, hostname, sizeof(li->hostname));
- return 1;
+ return (1);
}
-/* login_set_current_time(struct logininfo *) - set the current time
+/*
+ * login_set_current_time(struct logininfo *) - set the current time
*
* Set the current time in a logininfo structure. This function is
* meant to eliminate the need to deal with system dependencies for
@@ -388,7 +396,7 @@ login_set_current_time(struct logininfo *li)
/* copy a sockaddr_* into our logininfo */
void
login_set_addr(struct logininfo *li, const struct sockaddr *sa,
- const unsigned int sa_size)
+ const unsigned int sa_size)
{
unsigned int bufsize = sa_size;
@@ -396,7 +404,7 @@ login_set_addr(struct logininfo *li, const struct sockaddr *sa,
if (sizeof(li->hostaddr) < sa_size)
bufsize = sizeof(li->hostaddr);
- memcpy((void *)&(li->hostaddr.sa), (const void *)sa, bufsize);
+ memcpy(&li->hostaddr.sa, sa, bufsize);
}
@@ -405,12 +413,12 @@ login_set_addr(struct logininfo *li, const struct sockaddr *sa,
** results
**/
int
-login_write (struct logininfo *li)
+login_write(struct logininfo *li)
{
#ifndef HAVE_CYGWIN
- if ((int)geteuid() != 0) {
- logit("Attempt to write login records by non-root user (aborting)");
- return 1;
+ if (geteuid() != 0) {
+ logit("Attempt to write login records by non-root user (aborting)");
+ return (1);
}
#endif
@@ -420,9 +428,8 @@ login_write (struct logininfo *li)
syslogin_write_entry(li);
#endif
#ifdef USE_LASTLOG
- if (li->type == LTYPE_LOGIN) {
+ if (li->type == LTYPE_LOGIN)
lastlog_write_entry(li);
- }
#endif
#ifdef USE_UTMP
utmp_write_entry(li);
@@ -438,10 +445,16 @@ login_write (struct logininfo *li)
#endif
#ifdef CUSTOM_SYS_AUTH_RECORD_LOGIN
if (li->type == LTYPE_LOGIN &&
- !sys_auth_record_login(li->username,li->hostname,li->line))
+ !sys_auth_record_login(li->username,li->hostname,li->line, &loginmsg))
logit("Writing login record failed for %s", li->username);
#endif
- return 0;
+#ifdef SSH_AUDIT_EVENTS
+ if (li->type == LTYPE_LOGIN)
+ audit_session_open(li->line);
+ else if (li->type == LTYPE_LOGOUT)
+ audit_session_close(li->line);
+#endif
+ return (0);
}
#ifdef LOGIN_NEEDS_UTMPX
@@ -462,7 +475,7 @@ login_utmp_only(struct logininfo *li)
# ifdef USE_WTMPX
wtmpx_write_entry(li);
# endif
- return 0;
+ return (0);
}
#endif
@@ -479,25 +492,21 @@ getlast_entry(struct logininfo *li)
return(lastlog_get_entry(li));
#else /* !USE_LASTLOG */
-#ifdef DISABLE_LASTLOG
+#if defined(DISABLE_LASTLOG)
/* On some systems we shouldn't even try to obtain last login
* time, e.g. AIX */
- return 0;
-# else /* DISABLE_LASTLOG */
- /* Try to retrieve the last login time from wtmp */
-# if defined(USE_WTMP) && (defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP))
+ return (0);
+# elif defined(USE_WTMP) && \
+ (defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP))
/* retrieve last login time from utmp */
return (wtmp_get_entry(li));
-# else /* defined(USE_WTMP) && (defined(HAVE_TIME_IN_UTMP) || defined(HAVE_TV_IN_UTMP)) */
+# elif defined(USE_WTMPX) && \
+ (defined(HAVE_TIME_IN_UTMPX) || defined(HAVE_TV_IN_UTMPX))
/* If wtmp isn't available, try wtmpx */
-# if defined(USE_WTMPX) && (defined(HAVE_TIME_IN_UTMPX) || defined(HAVE_TV_IN_UTMPX))
- /* retrieve last login time from utmpx */
return (wtmpx_get_entry(li));
-# else
+# else
/* Give up: No means of retrieving last login time */
- return 0;
-# endif /* USE_WTMPX && (HAVE_TIME_IN_UTMPX || HAVE_TV_IN_UTMPX) */
-# endif /* USE_WTMP && (HAVE_TIME_IN_UTMP || HAVE_TV_IN_UTMP) */
+ return (0);
# endif /* DISABLE_LASTLOG */
#endif /* USE_LASTLOG */
}
@@ -521,19 +530,21 @@ getlast_entry(struct logininfo *li)
*/
-/* line_fullname(): add the leading '/dev/' if it doesn't exist make
- * sure dst has enough space, if not just copy src (ugh) */
+/*
+ * line_fullname(): add the leading '/dev/' if it doesn't exist make
+ * sure dst has enough space, if not just copy src (ugh)
+ */
char *
line_fullname(char *dst, const char *src, int dstsize)
{
memset(dst, '\0', dstsize);
- if ((strncmp(src, "/dev/", 5) == 0) || (dstsize < (strlen(src) + 5))) {
+ if ((strncmp(src, "/dev/", 5) == 0) || (dstsize < (strlen(src) + 5)))
strlcpy(dst, src, dstsize);
- } else {
+ else {
strlcpy(dst, "/dev/", dstsize);
strlcat(dst, src, dstsize);
}
- return dst;
+ return (dst);
}
/* line_stripname(): strip the leading '/dev' if it exists, return dst */
@@ -545,15 +556,17 @@ line_stripname(char *dst, const char *src, int dstsize)
strlcpy(dst, src + 5, dstsize);
else
strlcpy(dst, src, dstsize);
- return dst;
+ return (dst);
}
-/* line_abbrevname(): Return the abbreviated (usually four-character)
+/*
+ * line_abbrevname(): Return the abbreviated (usually four-character)
* form of the line (Just use the last <dstsize> characters of the
* full name.)
*
* NOTE: use strncpy because we do NOT necessarily want zero
- * termination */
+ * termination
+ */
char *
line_abbrevname(char *dst, const char *src, int dstsize)
{
@@ -580,7 +593,7 @@ line_abbrevname(char *dst, const char *src, int dstsize)
strncpy(dst, src, (size_t)dstsize);
}
- return dst;
+ return (dst);
}
/**
@@ -596,13 +609,11 @@ line_abbrevname(char *dst, const char *src, int dstsize)
void
set_utmp_time(struct logininfo *li, struct utmp *ut)
{
-# ifdef HAVE_TV_IN_UTMP
+# if defined(HAVE_TV_IN_UTMP)
ut->ut_tv.tv_sec = li->tv_sec;
ut->ut_tv.tv_usec = li->tv_usec;
-# else
-# ifdef HAVE_TIME_IN_UTMP
+# elif defined(HAVE_TIME_IN_UTMP)
ut->ut_time = li->tv_sec;
-# endif
# endif
}
@@ -612,7 +623,8 @@ construct_utmp(struct logininfo *li,
{
# ifdef HAVE_ADDR_V6_IN_UTMP
struct sockaddr_in6 *sa6;
-# endif
+# endif
+
memset(ut, '\0', sizeof(*ut));
/* First fill out fields used for both logins and logouts */
@@ -648,7 +660,7 @@ construct_utmp(struct logininfo *li,
/* If we're logging out, leave all other fields blank */
if (li->type == LTYPE_LOGOUT)
- return;
+ return;
/*
* These fields are only used when logging in, and are blank
@@ -656,7 +668,8 @@ construct_utmp(struct logininfo *li,
*/
/* Use strncpy because we don't necessarily want null termination */
- strncpy(ut->ut_name, li->username, MIN_SIZEOF(ut->ut_name, li->username));
+ strncpy(ut->ut_name, li->username,
+ MIN_SIZEOF(ut->ut_name, li->username));
# ifdef HAVE_HOST_IN_UTMP
realhostname_sa(ut->ut_host, sizeof ut->ut_host,
&li->hostaddr.sa, li->hostaddr.sa.sa_len);
@@ -694,14 +707,12 @@ construct_utmp(struct logininfo *li,
void
set_utmpx_time(struct logininfo *li, struct utmpx *utx)
{
-# ifdef HAVE_TV_IN_UTMPX
+# if defined(HAVE_TV_IN_UTMPX)
utx->ut_tv.tv_sec = li->tv_sec;
utx->ut_tv.tv_usec = li->tv_usec;
-# else /* HAVE_TV_IN_UTMPX */
-# ifdef HAVE_TIME_IN_UTMPX
+# elif defined(HAVE_TIME_IN_UTMPX)
utx->ut_time = li->tv_sec;
-# endif /* HAVE_TIME_IN_UTMPX */
-# endif /* HAVE_TV_IN_UTMPX */
+# endif
}
void
@@ -711,6 +722,7 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx)
struct sockaddr_in6 *sa6;
# endif
memset(utx, '\0', sizeof(*utx));
+
# ifdef HAVE_ID_IN_UTMPX
line_abbrevname(utx->ut_id, li->line, sizeof(utx->ut_id));
# endif
@@ -727,8 +739,10 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx)
line_stripname(utx->ut_line, li->line, sizeof(utx->ut_line));
set_utmpx_time(li, utx);
utx->ut_pid = li->pid;
+
/* strncpy(): Don't necessarily want null termination */
- strncpy(utx->ut_name, li->username, MIN_SIZEOF(utx->ut_name, li->username));
+ strncpy(utx->ut_name, li->username,
+ MIN_SIZEOF(utx->ut_name, li->username));
if (li->type == LTYPE_LOGOUT)
return;
@@ -739,7 +753,8 @@ construct_utmpx(struct logininfo *li, struct utmpx *utx)
*/
# ifdef HAVE_HOST_IN_UTMPX
- strncpy(utx->ut_host, li->hostname, MIN_SIZEOF(utx->ut_host, li->hostname));
+ strncpy(utx->ut_host, li->hostname,
+ MIN_SIZEOF(utx->ut_host, li->hostname));
# endif
# ifdef HAVE_ADDR_IN_UTMPX
/* this is just a 32-bit IP address */
@@ -787,16 +802,17 @@ utmp_write_library(struct logininfo *li, struct utmp *ut)
{
setutent();
pututline(ut);
-
# ifdef HAVE_ENDUTENT
endutent();
# endif
- return 1;
+ return (1);
}
# else /* UTMP_USE_LIBRARY */
-/* write a utmp entry direct to the file */
-/* This is a slightly modification of code in OpenBSD's login.c */
+/*
+ * Write a utmp entry direct to the file
+ * This is a slightly modification of code in OpenBSD's login.c
+ */
static int
utmp_write_direct(struct logininfo *li, struct utmp *ut)
{
@@ -807,19 +823,18 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut)
/* FIXME: (ATL) ttyslot() needs local implementation */
#if defined(HAVE_GETTTYENT)
- register struct ttyent *ty;
+ struct ttyent *ty;
tty=0;
-
setttyent();
- while ((struct ttyent *)0 != (ty = getttyent())) {
+ while (NULL != (ty = getttyent())) {
tty++;
if (!strncmp(ty->ty_name, ut->ut_line, sizeof(ut->ut_line)))
break;
}
endttyent();
- if((struct ttyent *)0 == ty) {
+ if (NULL == ty) {
logit("%s: tty not found", __func__);
return (0);
}
@@ -834,12 +849,12 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut)
pos = (off_t)tty * sizeof(struct utmp);
if ((ret = lseek(fd, pos, SEEK_SET)) == -1) {
- logit("%s: llseek: %s", strerror(errno));
+ logit("%s: lseek: %s", __func__, strerror(errno));
return (0);
}
if (ret != pos) {
- logit("%s: Couldn't seek to tty %s slot in %s", tty,
- UTMP_FILE);
+ logit("%s: Couldn't seek to tty %d slot in %s",
+ __func__, tty, UTMP_FILE);
return (0);
}
/*
@@ -848,29 +863,29 @@ utmp_write_direct(struct logininfo *li, struct utmp *ut)
* and ut_line and ut_name match, preserve the old ut_line.
*/
if (atomicio(read, fd, &old_ut, sizeof(old_ut)) == sizeof(old_ut) &&
- (ut->ut_host[0] == '\0') && (old_ut.ut_host[0] != '\0') &&
- (strncmp(old_ut.ut_line, ut->ut_line, sizeof(ut->ut_line)) == 0) &&
- (strncmp(old_ut.ut_name, ut->ut_name, sizeof(ut->ut_name)) == 0)) {
- (void)memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host));
- }
+ (ut->ut_host[0] == '\0') && (old_ut.ut_host[0] != '\0') &&
+ (strncmp(old_ut.ut_line, ut->ut_line, sizeof(ut->ut_line)) == 0) &&
+ (strncmp(old_ut.ut_name, ut->ut_name, sizeof(ut->ut_name)) == 0))
+ memcpy(ut->ut_host, old_ut.ut_host, sizeof(ut->ut_host));
if ((ret = lseek(fd, pos, SEEK_SET)) == -1) {
- logit("%s: llseek: %s", __func__, strerror(errno));
+ logit("%s: lseek: %s", __func__, strerror(errno));
return (0);
}
if (ret != pos) {
- logit("%s: Couldn't seek to tty %s slot in %s",
+ logit("%s: Couldn't seek to tty %d slot in %s",
__func__, tty, UTMP_FILE);
return (0);
}
- if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut))
+ if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) {
logit("%s: error writing %s: %s", __func__,
UTMP_FILE, strerror(errno));
+ }
- (void)close(fd);
- return 1;
+ close(fd);
+ return (1);
} else {
- return 0;
+ return (0);
}
}
# endif /* UTMP_USE_LIBRARY */
@@ -883,16 +898,16 @@ utmp_perform_login(struct logininfo *li)
construct_utmp(li, &ut);
# ifdef UTMP_USE_LIBRARY
if (!utmp_write_library(li, &ut)) {
- logit("utmp_perform_login: utmp_write_library() failed");
- return 0;
+ logit("%s: utmp_write_library() failed", __func__);
+ return (0);
}
# else
if (!utmp_write_direct(li, &ut)) {
- logit("utmp_perform_login: utmp_write_direct() failed");
- return 0;
+ logit("%s: utmp_write_direct() failed", __func__);
+ return (0);
}
# endif
- return 1;
+ return (1);
}
@@ -904,16 +919,16 @@ utmp_perform_logout(struct logininfo *li)
construct_utmp(li, &ut);
# ifdef UTMP_USE_LIBRARY
if (!utmp_write_library(li, &ut)) {
- logit("utmp_perform_logout: utmp_write_library() failed");
- return 0;
+ logit("%s: utmp_write_library() failed", __func__);
+ return (0);
}
# else
if (!utmp_write_direct(li, &ut)) {
- logit("utmp_perform_logout: utmp_write_direct() failed");
- return 0;
+ logit("%s: utmp_write_direct() failed", __func__);
+ return (0);
}
# endif
- return 1;
+ return (1);
}
@@ -922,14 +937,14 @@ utmp_write_entry(struct logininfo *li)
{
switch(li->type) {
case LTYPE_LOGIN:
- return utmp_perform_login(li);
+ return (utmp_perform_login(li));
case LTYPE_LOGOUT:
- return utmp_perform_logout(li);
+ return (utmp_perform_logout(li));
default:
- logit("utmp_write_entry: invalid type field");
- return 0;
+ logit("%s: invalid type field", __func__);
+ return (0);
}
}
#endif /* USE_UTMP */
@@ -960,7 +975,7 @@ utmpx_write_library(struct logininfo *li, struct utmpx *utx)
# ifdef HAVE_ENDUTXENT
endutxent();
# endif
- return 1;
+ return (1);
}
# else /* UTMPX_USE_LIBRARY */
@@ -969,8 +984,8 @@ utmpx_write_library(struct logininfo *li, struct utmpx *utx)
static int
utmpx_write_direct(struct logininfo *li, struct utmpx *utx)
{
- logit("utmpx_write_direct: not implemented!");
- return 0;
+ logit("%s: not implemented!", __func__);
+ return (0);
}
# endif /* UTMPX_USE_LIBRARY */
@@ -982,16 +997,16 @@ utmpx_perform_login(struct logininfo *li)
construct_utmpx(li, &utx);
# ifdef UTMPX_USE_LIBRARY
if (!utmpx_write_library(li, &utx)) {
- logit("utmpx_perform_login: utmp_write_library() failed");
- return 0;
+ logit("%s: utmp_write_library() failed", __func__);
+ return (0);
}
# else
if (!utmpx_write_direct(li, &ut)) {
- logit("utmpx_perform_login: utmp_write_direct() failed");
- return 0;
+ logit("%s: utmp_write_direct() failed", __func__);
+ return (0);
}
# endif
- return 1;
+ return (1);
}
@@ -1013,7 +1028,7 @@ utmpx_perform_logout(struct logininfo *li)
# else
utmpx_write_direct(li, &utx);
# endif
- return 1;
+ return (1);
}
int
@@ -1021,12 +1036,12 @@ utmpx_write_entry(struct logininfo *li)
{
switch(li->type) {
case LTYPE_LOGIN:
- return utmpx_perform_login(li);
+ return (utmpx_perform_login(li));
case LTYPE_LOGOUT:
- return utmpx_perform_logout(li);
+ return (utmpx_perform_logout(li));
default:
- logit("utmpx_write_entry: invalid type field");
- return 0;
+ logit("%s: invalid type field", __func__);
+ return (0);
}
}
#endif /* USE_UTMPX */
@@ -1038,8 +1053,10 @@ utmpx_write_entry(struct logininfo *li)
#ifdef USE_WTMP
-/* write a wtmp entry direct to the end of the file */
-/* This is a slight modification of code in OpenBSD's logwtmp.c */
+/*
+ * Write a wtmp entry direct to the end of the file
+ * This is a slight modification of code in OpenBSD's logwtmp.c
+ */
static int
wtmp_write(struct logininfo *li, struct utmp *ut)
{
@@ -1047,19 +1064,19 @@ wtmp_write(struct logininfo *li, struct utmp *ut)
int fd, ret = 1;
if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) < 0) {
- logit("wtmp_write: problem writing %s: %s",
+ logit("%s: problem writing %s: %s", __func__,
WTMP_FILE, strerror(errno));
- return 0;
+ return (0);
}
if (fstat(fd, &buf) == 0)
if (atomicio(vwrite, fd, ut, sizeof(*ut)) != sizeof(*ut)) {
ftruncate(fd, buf.st_size);
- logit("wtmp_write: problem writing %s: %s",
+ logit("%s: problem writing %s: %s", __func__,
WTMP_FILE, strerror(errno));
ret = 0;
}
- (void)close(fd);
- return ret;
+ close(fd);
+ return (ret);
}
static int
@@ -1068,7 +1085,7 @@ wtmp_perform_login(struct logininfo *li)
struct utmp ut;
construct_utmp(li, &ut);
- return wtmp_write(li, &ut);
+ return (wtmp_write(li, &ut));
}
@@ -1078,7 +1095,7 @@ wtmp_perform_logout(struct logininfo *li)
struct utmp ut;
construct_utmp(li, &ut);
- return wtmp_write(li, &ut);
+ return (wtmp_write(li, &ut));
}
@@ -1087,17 +1104,18 @@ wtmp_write_entry(struct logininfo *li)
{
switch(li->type) {
case LTYPE_LOGIN:
- return wtmp_perform_login(li);
+ return (wtmp_perform_login(li));
case LTYPE_LOGOUT:
- return wtmp_perform_logout(li);
+ return (wtmp_perform_logout(li));
default:
- logit("wtmp_write_entry: invalid type field");
- return 0;
+ logit("%s: invalid type field", __func__);
+ return (0);
}
}
-/* Notes on fetching login data from wtmp/wtmpx
+/*
+ * Notes on fetching login data from wtmp/wtmpx
*
* Logouts are usually recorded with (amongst other things) a blank
* username on a given tty line. However, some systems (HP-UX is one)
@@ -1118,15 +1136,15 @@ static int
wtmp_islogin(struct logininfo *li, struct utmp *ut)
{
if (strncmp(li->username, ut->ut_name,
- MIN_SIZEOF(li->username, ut->ut_name)) == 0) {
+ MIN_SIZEOF(li->username, ut->ut_name)) == 0) {
# ifdef HAVE_TYPE_IN_UTMP
if (ut->ut_type & USER_PROCESS)
- return 1;
+ return (1);
# else
- return 1;
+ return (1);
# endif
}
- return 0;
+ return (0);
}
int
@@ -1134,41 +1152,43 @@ wtmp_get_entry(struct logininfo *li)
{
struct stat st;
struct utmp ut;
- int fd, found=0;
+ int fd, found = 0;
/* Clear the time entries in our logininfo */
li->tv_sec = li->tv_usec = 0;
if ((fd = open(WTMP_FILE, O_RDONLY)) < 0) {
- logit("wtmp_get_entry: problem opening %s: %s",
+ logit("%s: problem opening %s: %s", __func__,
WTMP_FILE, strerror(errno));
- return 0;
+ return (0);
}
if (fstat(fd, &st) != 0) {
- logit("wtmp_get_entry: couldn't stat %s: %s",
+ logit("%s: couldn't stat %s: %s", __func__,
WTMP_FILE, strerror(errno));
close(fd);
- return 0;
+ return (0);
}
/* Seek to the start of the last struct utmp */
if (lseek(fd, -(off_t)sizeof(struct utmp), SEEK_END) == -1) {
/* Looks like we've got a fresh wtmp file */
close(fd);
- return 0;
+ return (0);
}
while (!found) {
if (atomicio(read, fd, &ut, sizeof(ut)) != sizeof(ut)) {
- logit("wtmp_get_entry: read of %s failed: %s",
+ logit("%s: read of %s failed: %s", __func__,
WTMP_FILE, strerror(errno));
close (fd);
- return 0;
+ return (0);
}
if ( wtmp_islogin(li, &ut) ) {
found = 1;
- /* We've already checked for a time in struct
- * utmp, in login_getlast(). */
+ /*
+ * We've already checked for a time in struct
+ * utmp, in login_getlast()
+ */
# ifdef HAVE_TIME_IN_UTMP
li->tv_sec = ut.ut_time;
# else
@@ -1177,24 +1197,24 @@ wtmp_get_entry(struct logininfo *li)
# endif
# endif
line_fullname(li->line, ut.ut_line,
- MIN_SIZEOF(li->line, ut.ut_line));
+ MIN_SIZEOF(li->line, ut.ut_line));
# ifdef HAVE_HOST_IN_UTMP
strlcpy(li->hostname, ut.ut_host,
- MIN_SIZEOF(li->hostname, ut.ut_host));
+ MIN_SIZEOF(li->hostname, ut.ut_host));
# endif
continue;
}
/* Seek back 2 x struct utmp */
if (lseek(fd, -(off_t)(2 * sizeof(struct utmp)), SEEK_CUR) == -1) {
/* We've found the start of the file, so quit */
- close (fd);
- return 0;
+ close(fd);
+ return (0);
}
}
/* We found an entry. Tidy up and return */
close(fd);
- return 1;
+ return (1);
}
# endif /* USE_WTMP */
@@ -1204,8 +1224,10 @@ wtmp_get_entry(struct logininfo *li)
**/
#ifdef USE_WTMPX
-/* write a wtmpx entry direct to the end of the file */
-/* This is a slight modification of code in OpenBSD's logwtmp.c */
+/*
+ * Write a wtmpx entry direct to the end of the file
+ * This is a slight modification of code in OpenBSD's logwtmp.c
+ */
static int
wtmpx_write(struct logininfo *li, struct utmpx *utx)
{
@@ -1214,24 +1236,24 @@ wtmpx_write(struct logininfo *li, struct utmpx *utx)
int fd, ret = 1;
if ((fd = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0)) < 0) {
- logit("wtmpx_write: problem opening %s: %s",
+ logit("%s: problem opening %s: %s", __func__,
WTMPX_FILE, strerror(errno));
- return 0;
+ return (0);
}
if (fstat(fd, &buf) == 0)
if (atomicio(vwrite, fd, utx, sizeof(*utx)) != sizeof(*utx)) {
ftruncate(fd, buf.st_size);
- logit("wtmpx_write: problem writing %s: %s",
+ logit("%s: problem writing %s: %s", __func__,
WTMPX_FILE, strerror(errno));
ret = 0;
}
- (void)close(fd);
+ close(fd);
- return ret;
+ return (ret);
#else
updwtmpx(WTMPX_FILE, utx);
- return 1;
+ return (1);
#endif
}
@@ -1242,7 +1264,7 @@ wtmpx_perform_login(struct logininfo *li)
struct utmpx utx;
construct_utmpx(li, &utx);
- return wtmpx_write(li, &utx);
+ return (wtmpx_write(li, &utx));
}
@@ -1252,7 +1274,7 @@ wtmpx_perform_logout(struct logininfo *li)
struct utmpx utx;
construct_utmpx(li, &utx);
- return wtmpx_write(li, &utx);
+ return (wtmpx_write(li, &utx));
}
@@ -1261,12 +1283,12 @@ wtmpx_write_entry(struct logininfo *li)
{
switch(li->type) {
case LTYPE_LOGIN:
- return wtmpx_perform_login(li);
+ return (wtmpx_perform_login(li));
case LTYPE_LOGOUT:
- return wtmpx_perform_logout(li);
+ return (wtmpx_perform_logout(li));
default:
- logit("wtmpx_write_entry: invalid type field");
- return 0;
+ logit("%s: invalid type field", __func__);
+ return (0);
}
}
@@ -1277,16 +1299,16 @@ wtmpx_write_entry(struct logininfo *li)
static int
wtmpx_islogin(struct logininfo *li, struct utmpx *utx)
{
- if ( strncmp(li->username, utx->ut_name,
- MIN_SIZEOF(li->username, utx->ut_name)) == 0 ) {
+ if (strncmp(li->username, utx->ut_name,
+ MIN_SIZEOF(li->username, utx->ut_name)) == 0 ) {
# ifdef HAVE_TYPE_IN_UTMPX
if (utx->ut_type == USER_PROCESS)
- return 1;
+ return (1);
# else
- return 1;
+ return (1);
# endif
}
- return 0;
+ return (0);
}
@@ -1301,57 +1323,57 @@ wtmpx_get_entry(struct logininfo *li)
li->tv_sec = li->tv_usec = 0;
if ((fd = open(WTMPX_FILE, O_RDONLY)) < 0) {
- logit("wtmpx_get_entry: problem opening %s: %s",
+ logit("%s: problem opening %s: %s", __func__,
WTMPX_FILE, strerror(errno));
- return 0;
+ return (0);
}
if (fstat(fd, &st) != 0) {
- logit("wtmpx_get_entry: couldn't stat %s: %s",
+ logit("%s: couldn't stat %s: %s", __func__,
WTMPX_FILE, strerror(errno));
close(fd);
- return 0;
+ return (0);
}
/* Seek to the start of the last struct utmpx */
if (lseek(fd, -(off_t)sizeof(struct utmpx), SEEK_END) == -1 ) {
/* probably a newly rotated wtmpx file */
close(fd);
- return 0;
+ return (0);
}
while (!found) {
if (atomicio(read, fd, &utx, sizeof(utx)) != sizeof(utx)) {
- logit("wtmpx_get_entry: read of %s failed: %s",
+ logit("%s: read of %s failed: %s", __func__,
WTMPX_FILE, strerror(errno));
close (fd);
- return 0;
+ return (0);
}
- /* Logouts are recorded as a blank username on a particular line.
- * So, we just need to find the username in struct utmpx */
- if ( wtmpx_islogin(li, &utx) ) {
+ /*
+ * Logouts are recorded as a blank username on a particular
+ * line. So, we just need to find the username in struct utmpx
+ */
+ if (wtmpx_islogin(li, &utx)) {
found = 1;
-# ifdef HAVE_TV_IN_UTMPX
+# if defined(HAVE_TV_IN_UTMPX)
li->tv_sec = utx.ut_tv.tv_sec;
-# else
-# ifdef HAVE_TIME_IN_UTMPX
+# elif defined(HAVE_TIME_IN_UTMPX)
li->tv_sec = utx.ut_time;
-# endif
# endif
line_fullname(li->line, utx.ut_line, sizeof(li->line));
-# ifdef HAVE_HOST_IN_UTMPX
+# if defined(HAVE_HOST_IN_UTMPX)
strlcpy(li->hostname, utx.ut_host,
- MIN_SIZEOF(li->hostname, utx.ut_host));
+ MIN_SIZEOF(li->hostname, utx.ut_host));
# endif
continue;
}
if (lseek(fd, -(off_t)(2 * sizeof(struct utmpx)), SEEK_CUR) == -1) {
- close (fd);
- return 0;
+ close(fd);
+ return (0);
}
}
close(fd);
- return 1;
+ return (1);
}
#endif /* USE_WTMPX */
@@ -1365,15 +1387,12 @@ syslogin_perform_login(struct logininfo *li)
{
struct utmp *ut;
- if (! (ut = (struct utmp *)malloc(sizeof(*ut)))) {
- logit("syslogin_perform_login: couldn't malloc()");
- return 0;
- }
+ ut = xmalloc(sizeof(*ut));
construct_utmp(li, ut);
login(ut);
free(ut);
- return 1;
+ return (1);
}
static int
@@ -1384,19 +1403,18 @@ syslogin_perform_logout(struct logininfo *li)
(void)line_stripname(line, li->line, sizeof(line));
- if (!logout(line)) {
- logit("syslogin_perform_logout: logout() returned an error");
+ if (!logout(line))
+ logit("%s: logout() returned an error", __func__);
# ifdef HAVE_LOGWTMP
- } else {
+ else
logwtmp(line, "", "");
# endif
- }
/* FIXME: (ATL - if the need arises) What to do if we have
* login, but no logout? what if logout but no logwtmp? All
* routines are in libutil so they should all be there,
* but... */
# endif
- return 1;
+ return (1);
}
int
@@ -1404,12 +1422,12 @@ syslogin_write_entry(struct logininfo *li)
{
switch (li->type) {
case LTYPE_LOGIN:
- return syslogin_perform_login(li);
+ return (syslogin_perform_login(li));
case LTYPE_LOGOUT:
- return syslogin_perform_logout(li);
+ return (syslogin_perform_logout(li));
default:
- logit("syslogin_write_entry: Invalid type field");
- return 0;
+ logit("%s: Invalid type field", __func__);
+ return (0);
}
}
#endif /* USE_LOGIN */
@@ -1431,7 +1449,7 @@ lastlog_construct(struct logininfo *li, struct lastlog *last)
/* clear the structure */
memset(last, '\0', sizeof(*last));
- (void)line_stripname(last->ll_line, li->line, sizeof(last->ll_line));
+ line_stripname(last->ll_line, li->line, sizeof(last->ll_line));
strlcpy(last->ll_host, li->hostname,
MIN_SIZEOF(last->ll_host, li->hostname));
last->ll_time = li->tv_sec;
@@ -1443,16 +1461,16 @@ lastlog_filetype(char *filename)
struct stat st;
if (stat(LASTLOG_FILE, &st) != 0) {
- logit("lastlog_perform_login: Couldn't stat %s: %s", LASTLOG_FILE,
- strerror(errno));
- return 0;
+ logit("%s: Couldn't stat %s: %s", __func__,
+ LASTLOG_FILE, strerror(errno));
+ return (0);
}
if (S_ISDIR(st.st_mode))
- return LL_DIR;
+ return (LL_DIR);
else if (S_ISREG(st.st_mode))
- return LL_FILE;
+ return (LL_FILE);
else
- return LL_OTHER;
+ return (LL_OTHER);
}
@@ -1466,38 +1484,39 @@ lastlog_openseek(struct logininfo *li, int *fd, int filemode)
type = lastlog_filetype(LASTLOG_FILE);
switch (type) {
- case LL_FILE:
- strlcpy(lastlog_file, LASTLOG_FILE, sizeof(lastlog_file));
- break;
- case LL_DIR:
- snprintf(lastlog_file, sizeof(lastlog_file), "%s/%s",
- LASTLOG_FILE, li->username);
- break;
- default:
- logit("lastlog_openseek: %.100s is not a file or directory!",
- LASTLOG_FILE);
- return 0;
+ case LL_FILE:
+ strlcpy(lastlog_file, LASTLOG_FILE,
+ sizeof(lastlog_file));
+ break;
+ case LL_DIR:
+ snprintf(lastlog_file, sizeof(lastlog_file), "%s/%s",
+ LASTLOG_FILE, li->username);
+ break;
+ default:
+ logit("%s: %.100s is not a file or directory!", __func__,
+ LASTLOG_FILE);
+ return (0);
}
*fd = open(lastlog_file, filemode, 0600);
- if ( *fd < 0) {
- debug("lastlog_openseek: Couldn't open %s: %s",
+ if (*fd < 0) {
+ debug("%s: Couldn't open %s: %s", __func__,
lastlog_file, strerror(errno));
- return 0;
+ return (0);
}
if (type == LL_FILE) {
/* find this uid's offset in the lastlog file */
offset = (off_t) ((long)li->uid * sizeof(struct lastlog));
- if ( lseek(*fd, offset, SEEK_SET) != offset ) {
- logit("lastlog_openseek: %s->lseek(): %s",
- lastlog_file, strerror(errno));
- return 0;
+ if (lseek(*fd, offset, SEEK_SET) != offset) {
+ logit("%s: %s->lseek(): %s", __func__,
+ lastlog_file, strerror(errno));
+ return (0);
}
}
- return 1;
+ return (1);
}
static int
@@ -1510,18 +1529,18 @@ lastlog_perform_login(struct logininfo *li)
lastlog_construct(li, &last);
if (!lastlog_openseek(li, &fd, O_RDWR|O_CREAT))
- return(0);
+ return (0);
/* write the entry */
if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) {
close(fd);
- logit("lastlog_write_filemode: Error writing to %s: %s",
+ logit("%s: Error writing to %s: %s", __func__,
LASTLOG_FILE, strerror(errno));
- return 0;
+ return (0);
}
close(fd);
- return 1;
+ return (1);
}
int
@@ -1529,10 +1548,10 @@ lastlog_write_entry(struct logininfo *li)
{
switch(li->type) {
case LTYPE_LOGIN:
- return lastlog_perform_login(li);
+ return (lastlog_perform_login(li));
default:
- logit("lastlog_write_entry: Invalid type field");
- return 0;
+ logit("%s: Invalid type field", __func__);
+ return (0);
}
}
@@ -1541,7 +1560,7 @@ lastlog_populate_entry(struct logininfo *li, struct lastlog *last)
{
line_fullname(li->line, last->ll_line, sizeof(li->line));
strlcpy(li->hostname, last->ll_host,
- MIN_SIZEOF(li->hostname, last->ll_host));
+ MIN_SIZEOF(li->hostname, last->ll_host));
li->tv_sec = last->ll_time;
}
@@ -1578,3 +1597,82 @@ lastlog_get_entry(struct logininfo *li)
return (0);
}
#endif /* USE_LASTLOG */
+
+#ifdef USE_BTMP
+ /*
+ * Logs failed login attempts in _PATH_BTMP if that exists.
+ * The most common login failure is to give password instead of username.
+ * So the _PATH_BTMP file checked for the correct permission, so that
+ * only root can read it.
+ */
+
+void
+record_failed_login(const char *username, const char *hostname,
+ const char *ttyn)
+{
+ int fd;
+ struct utmp ut;
+ struct sockaddr_storage from;
+ size_t fromlen = sizeof(from);
+ struct sockaddr_in *a4;
+ struct sockaddr_in6 *a6;
+ time_t t;
+ struct stat fst;
+
+ if (geteuid() != 0)
+ return;
+ if ((fd = open(_PATH_BTMP, O_WRONLY | O_APPEND)) < 0) {
+ debug("Unable to open the btmp file %s: %s", _PATH_BTMP,
+ strerror(errno));
+ return;
+ }
+ if (fstat(fd, &fst) < 0) {
+ logit("%s: fstat of %s failed: %s", __func__, _PATH_BTMP,
+ strerror(errno));
+ goto out;
+ }
+ if((fst.st_mode & (S_IRWXG | S_IRWXO)) || (fst.st_uid != 0)){
+ logit("Excess permission or bad ownership on file %s",
+ _PATH_BTMP);
+ goto out;
+ }
+
+ memset(&ut, 0, sizeof(ut));
+ /* strncpy because we don't necessarily want nul termination */
+ strncpy(ut.ut_user, username, sizeof(ut.ut_user));
+ strlcpy(ut.ut_line, "ssh:notty", sizeof(ut.ut_line));
+
+ time(&t);
+ ut.ut_time = t; /* ut_time is not always a time_t */
+ ut.ut_type = LOGIN_PROCESS;
+ ut.ut_pid = getpid();
+
+ /* strncpy because we don't necessarily want nul termination */
+ strncpy(ut.ut_host, hostname, sizeof(ut.ut_host));
+
+ if (packet_connection_is_on_socket() &&
+ getpeername(packet_get_connection_in(),
+ (struct sockaddr *)&from, &fromlen) == 0) {
+ ipv64_normalise_mapped(&from, &fromlen);
+ if (from.ss_family == AF_INET) {
+ a4 = (struct sockaddr_in *)&from;
+ memcpy(&ut.ut_addr, &(a4->sin_addr),
+ MIN_SIZEOF(ut.ut_addr, a4->sin_addr));
+ }
+#ifdef HAVE_ADDR_V6_IN_UTMP
+ if (from.ss_family == AF_INET6) {
+ a6 = (struct sockaddr_in6 *)&from;
+ memcpy(&ut.ut_addr_v6, &(a6->sin6_addr),
+ MIN_SIZEOF(ut.ut_addr_v6, a6->sin6_addr));
+ }
+#endif
+ }
+
+ if (atomicio(vwrite, fd, &ut, sizeof(ut)) != sizeof(ut))
+ error("Failed to write to %s: %s", _PATH_BTMP,
+ strerror(errno));
+
+out:
+ close(fd);
+}
+#endif /* USE_BTMP */
diff --git a/crypto/openssh/monitor.c b/crypto/openssh/monitor.c
index 1fa6db0c07c2..ef8fbc4f169e 100644
--- a/crypto/openssh/monitor.c
+++ b/crypto/openssh/monitor.c
@@ -25,7 +25,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: monitor.c,v 1.61 2004/07/17 05:31:41 dtucker Exp $");
+RCSID("$OpenBSD: monitor.c,v 1.63 2005/03/10 22:01:05 deraadt Exp $");
RCSID("$FreeBSD$");
#include <openssl/dh.h>
@@ -152,6 +152,11 @@ int mm_answer_gss_userok(int, Buffer *);
int mm_answer_gss_checkmic(int, Buffer *);
#endif
+#ifdef SSH_AUDIT_EVENTS
+int mm_answer_audit_event(int, Buffer *);
+int mm_answer_audit_command(int, Buffer *);
+#endif
+
static Authctxt *authctxt;
static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */
@@ -195,6 +200,9 @@ struct mon_table mon_dispatch_proto20[] = {
{MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
{MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx},
#endif
+#ifdef SSH_AUDIT_EVENTS
+ {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
+#endif
#ifdef BSD_AUTH
{MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
{MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond},
@@ -220,6 +228,10 @@ struct mon_table mon_dispatch_postauth20[] = {
{MONITOR_REQ_PTY, 0, mm_answer_pty},
{MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup},
{MONITOR_REQ_TERM, 0, mm_answer_term},
+#ifdef SSH_AUDIT_EVENTS
+ {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
+ {MONITOR_REQ_AUDIT_COMMAND, MON_PERMIT, mm_answer_audit_command},
+#endif
{0, 0, NULL}
};
@@ -248,6 +260,9 @@ struct mon_table mon_dispatch_proto15[] = {
{MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
{MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx},
#endif
+#ifdef SSH_AUDIT_EVENTS
+ {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
+#endif
{0, 0, NULL}
};
@@ -255,6 +270,10 @@ struct mon_table mon_dispatch_postauth15[] = {
{MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty},
{MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup},
{MONITOR_REQ_TERM, 0, mm_answer_term},
+#ifdef SSH_AUDIT_EVENTS
+ {MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
+ {MONITOR_REQ_AUDIT_COMMAND, MON_ONCE, mm_answer_audit_command},
+#endif
{0, 0, NULL}
};
@@ -300,6 +319,8 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
authctxt = _authctxt;
memset(authctxt, 0, sizeof(*authctxt));
+ authctxt->loginmsg = &loginmsg;
+
if (compat20) {
mon_dispatch = mon_dispatch_proto20;
@@ -618,6 +639,9 @@ mm_answer_pwnamallow(int sock, Buffer *m)
if (options.use_pam)
monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1);
#endif
+#ifdef SSH_AUDIT_EVENTS
+ monitor_permit(mon_dispatch, MONITOR_REQ_AUDIT_COMMAND, 1);
+#endif
return (0);
}
@@ -819,6 +843,9 @@ mm_answer_pam_account(int sock, Buffer *m)
ret = do_pam_account();
buffer_put_int(m, ret);
+ buffer_append(&loginmsg, "\0", 1);
+ buffer_put_cstring(m, buffer_ptr(&loginmsg));
+ buffer_clear(&loginmsg);
mm_request_send(sock, MONITOR_ANS_PAM_ACCOUNT, m);
@@ -960,7 +987,7 @@ mm_answer_keyallowed(int sock, Buffer *m)
debug3("%s: key_from_blob: %p", __func__, key);
if (key != NULL && authctxt->valid) {
- switch(type) {
+ switch (type) {
case MM_USERKEY:
allowed = options.pubkey_authentication &&
user_key_allowed(authctxt->pw, key);
@@ -1306,7 +1333,7 @@ mm_answer_sesskey(int sock, Buffer *m)
int rsafail;
/* Turn off permissions */
- monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);
+ monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 0);
if ((p = BN_new()) == NULL)
fatal("%s: BN_new", __func__);
@@ -1497,6 +1524,48 @@ mm_answer_term(int sock, Buffer *req)
exit(res);
}
+#ifdef SSH_AUDIT_EVENTS
+/* Report that an audit event occurred */
+int
+mm_answer_audit_event(int socket, Buffer *m)
+{
+ ssh_audit_event_t event;
+
+ debug3("%s entering", __func__);
+
+ event = buffer_get_int(m);
+ switch(event) {
+ case SSH_AUTH_FAIL_PUBKEY:
+ case SSH_AUTH_FAIL_HOSTBASED:
+ case SSH_AUTH_FAIL_GSSAPI:
+ case SSH_LOGIN_EXCEED_MAXTRIES:
+ case SSH_LOGIN_ROOT_DENIED:
+ case SSH_CONNECTION_CLOSE:
+ case SSH_INVALID_USER:
+ audit_event(event);
+ break;
+ default:
+ fatal("Audit event type %d not permitted", event);
+ }
+
+ return (0);
+}
+
+int
+mm_answer_audit_command(int socket, Buffer *m)
+{
+ u_int len;
+ char *cmd;
+
+ debug3("%s entering", __func__);
+ cmd = buffer_get_string(m, &len);
+ /* sanity check command, if so how? */
+ audit_run_command(cmd);
+ xfree(cmd);
+ return (0);
+}
+#endif /* SSH_AUDIT_EVENTS */
+
void
monitor_apply_keystate(struct monitor *pmonitor)
{
diff --git a/crypto/openssh/monitor.h b/crypto/openssh/monitor.h
index feab93fbd1f3..46adeb094614 100644
--- a/crypto/openssh/monitor.h
+++ b/crypto/openssh/monitor.h
@@ -60,6 +60,7 @@ enum monitor_reqtype {
MONITOR_REQ_PAM_QUERY, MONITOR_ANS_PAM_QUERY,
MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND,
MONITOR_REQ_PAM_FREE_CTX, MONITOR_ANS_PAM_FREE_CTX,
+ MONITOR_REQ_AUDIT_EVENT, MONITOR_REQ_AUDIT_COMMAND,
MONITOR_REQ_TERM
};
diff --git a/crypto/openssh/monitor_wrap.c b/crypto/openssh/monitor_wrap.c
index dab175a55d76..216c454badce 100644
--- a/crypto/openssh/monitor_wrap.c
+++ b/crypto/openssh/monitor_wrap.c
@@ -73,6 +73,7 @@ extern struct monitor *pmonitor;
extern Buffer input, output;
extern Buffer loginmsg;
extern ServerOptions options;
+extern Buffer loginmsg;
int
mm_is_monitor(void)
@@ -717,6 +718,7 @@ mm_do_pam_account(void)
{
Buffer m;
u_int ret;
+ char *msg;
debug3("%s entering", __func__);
if (!options.use_pam)
@@ -728,6 +730,9 @@ mm_do_pam_account(void)
mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_PAM_ACCOUNT, &m);
ret = buffer_get_int(&m);
+ msg = buffer_get_string(&m, NULL);
+ buffer_append(&loginmsg, msg, strlen(msg));
+ xfree(msg);
buffer_free(&m);
@@ -1099,6 +1104,36 @@ mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16])
return (success);
}
+#ifdef SSH_AUDIT_EVENTS
+void
+mm_audit_event(ssh_audit_event_t event)
+{
+ Buffer m;
+
+ debug3("%s entering", __func__);
+
+ buffer_init(&m);
+ buffer_put_int(&m, event);
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, &m);
+ buffer_free(&m);
+}
+
+void
+mm_audit_run_command(const char *command)
+{
+ Buffer m;
+
+ debug3("%s entering command %s", __func__, command);
+
+ buffer_init(&m);
+ buffer_put_cstring(&m, command);
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m);
+ buffer_free(&m);
+}
+#endif /* SSH_AUDIT_EVENTS */
+
#ifdef GSSAPI
OM_uint32
mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid)
diff --git a/crypto/openssh/monitor_wrap.h b/crypto/openssh/monitor_wrap.h
index 1f24d568edf8..c2f1f3736c66 100644
--- a/crypto/openssh/monitor_wrap.h
+++ b/crypto/openssh/monitor_wrap.h
@@ -75,6 +75,12 @@ int mm_sshpam_respond(void *, u_int, char **);
void mm_sshpam_free_ctx(void *);
#endif
+#ifdef SSH_AUDIT_EVENTS
+#include "audit.h"
+void mm_audit_event(ssh_audit_event_t);
+void mm_audit_run_command(const char *);
+#endif
+
struct Session;
void mm_terminate(void);
int mm_pty_allocate(int *, int *, char *, int);
diff --git a/crypto/openssh/openbsd-compat/fake-rfc2553.h b/crypto/openssh/openbsd-compat/fake-rfc2553.h
index 44e146d014e1..1cfcd26e38e6 100644
--- a/crypto/openssh/openbsd-compat/fake-rfc2553.h
+++ b/crypto/openssh/openbsd-compat/fake-rfc2553.h
@@ -1,4 +1,4 @@
-/* $Id: fake-rfc2553.h,v 1.8 2004/02/10 02:05:41 dtucker Exp $ */
+/* $Id: fake-rfc2553.h,v 1.10 2005/02/11 07:32:13 dtucker Exp $ */
/* $FreeBSD$ */
/*
@@ -118,6 +118,7 @@ struct sockaddr_in6 {
# define EAI_NODATA 1
# define EAI_MEMORY 2
# define EAI_NONAME 3
+# define EAI_SYSTEM 4
#endif
#ifndef HAVE_STRUCT_ADDRINFO
diff --git a/crypto/openssh/readconf.c b/crypto/openssh/readconf.c
index 5a5813ab2dbd..2a1f36f0080c 100644
--- a/crypto/openssh/readconf.c
+++ b/crypto/openssh/readconf.c
@@ -12,7 +12,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: readconf.c,v 1.134 2004/07/11 17:48:47 deraadt Exp $");
+RCSID("$OpenBSD: readconf.c,v 1.139 2005/03/10 22:01:05 deraadt Exp $");
RCSID("$FreeBSD$");
#include "ssh.h"
@@ -107,7 +107,7 @@ typedef enum {
oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
oAddressFamily, oGssAuthentication, oGssDelegateCreds,
oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
- oSendEnv, oControlPath, oControlMaster,
+ oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
oVersionAddendum,
oDeprecated, oUnsupported
} OpCodes;
@@ -199,6 +199,7 @@ static struct {
{ "sendenv", oSendEnv },
{ "controlpath", oControlPath },
{ "controlmaster", oControlMaster },
+ { "hashknownhosts", oHashKnownHosts },
{ "versionaddendum", oVersionAddendum },
{ NULL, oBadOption }
};
@@ -209,21 +210,23 @@ static struct {
*/
void
-add_local_forward(Options *options, u_short port, const char *host,
- u_short host_port)
+add_local_forward(Options *options, const Forward *newfwd)
{
Forward *fwd;
#ifndef NO_IPPORT_RESERVED_CONCEPT
extern uid_t original_real_uid;
- if (port < IPPORT_RESERVED && original_real_uid != 0)
+ if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0)
fatal("Privileged ports can only be forwarded by root.");
#endif
if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
fwd = &options->local_forwards[options->num_local_forwards++];
- fwd->port = port;
- fwd->host = xstrdup(host);
- fwd->host_port = host_port;
+
+ fwd->listen_host = (newfwd->listen_host == NULL) ?
+ NULL : xstrdup(newfwd->listen_host);
+ fwd->listen_port = newfwd->listen_port;
+ fwd->connect_host = xstrdup(newfwd->connect_host);
+ fwd->connect_port = newfwd->connect_port;
}
/*
@@ -232,17 +235,19 @@ add_local_forward(Options *options, u_short port, const char *host,
*/
void
-add_remote_forward(Options *options, u_short port, const char *host,
- u_short host_port)
+add_remote_forward(Options *options, const Forward *newfwd)
{
Forward *fwd;
if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
fatal("Too many remote forwards (max %d).",
SSH_MAX_FORWARDS_PER_DIRECTION);
fwd = &options->remote_forwards[options->num_remote_forwards++];
- fwd->port = port;
- fwd->host = xstrdup(host);
- fwd->host_port = host_port;
+
+ fwd->listen_host = (newfwd->listen_host == NULL) ?
+ NULL : xstrdup(newfwd->listen_host);
+ fwd->listen_port = newfwd->listen_port;
+ fwd->connect_host = xstrdup(newfwd->connect_host);
+ fwd->connect_port = newfwd->connect_port;
}
static void
@@ -250,11 +255,17 @@ clear_forwardings(Options *options)
{
int i;
- for (i = 0; i < options->num_local_forwards; i++)
- xfree(options->local_forwards[i].host);
+ for (i = 0; i < options->num_local_forwards; i++) {
+ if (options->local_forwards[i].listen_host != NULL)
+ xfree(options->local_forwards[i].listen_host);
+ xfree(options->local_forwards[i].connect_host);
+ }
options->num_local_forwards = 0;
- for (i = 0; i < options->num_remote_forwards; i++)
- xfree(options->remote_forwards[i].host);
+ for (i = 0; i < options->num_remote_forwards; i++) {
+ if (options->remote_forwards[i].listen_host != NULL)
+ xfree(options->remote_forwards[i].listen_host);
+ xfree(options->remote_forwards[i].connect_host);
+ }
options->num_remote_forwards = 0;
}
@@ -287,14 +298,13 @@ process_config_line(Options *options, const char *host,
char *line, const char *filename, int linenum,
int *activep)
{
- char buf[256], *s, **charptr, *endofnumber, *keyword, *arg;
+ char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
int opcode, *intptr, value;
size_t len;
- u_short fwd_port, fwd_host_port;
- char sfwd_host_port[6];
+ Forward fwd;
/* Strip trailing whitespace */
- for(len = strlen(line) - 1; len > 0; len--) {
+ for (len = strlen(line) - 1; len > 0; len--) {
if (strchr(WHITESPACE, line[len]) == NULL)
break;
line[len] = '\0';
@@ -648,30 +658,26 @@ parse_int:
case oLocalForward:
case oRemoteForward:
arg = strdelim(&s);
- if (!arg || *arg == '\0')
+ if (arg == NULL || *arg == '\0')
fatal("%.200s line %d: Missing port argument.",
filename, linenum);
- if ((fwd_port = a2port(arg)) == 0)
- fatal("%.200s line %d: Bad listen port.",
+ arg2 = strdelim(&s);
+ if (arg2 == NULL || *arg2 == '\0')
+ fatal("%.200s line %d: Missing target argument.",
filename, linenum);
- arg = strdelim(&s);
- if (!arg || *arg == '\0')
- fatal("%.200s line %d: Missing second argument.",
- filename, linenum);
- if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 &&
- sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
+
+ /* construct a string for parse_forward */
+ snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
+
+ if (parse_forward(&fwd, fwdarg) == 0)
fatal("%.200s line %d: Bad forwarding specification.",
filename, linenum);
- if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
- fatal("%.200s line %d: Bad forwarding port.",
- filename, linenum);
+
if (*activep) {
if (opcode == oLocalForward)
- add_local_forward(options, fwd_port, buf,
- fwd_host_port);
+ add_local_forward(options, &fwd);
else if (opcode == oRemoteForward)
- add_remote_forward(options, fwd_port, buf,
- fwd_host_port);
+ add_remote_forward(options, &fwd);
}
break;
@@ -680,12 +686,25 @@ parse_int:
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing port argument.",
filename, linenum);
- fwd_port = a2port(arg);
- if (fwd_port == 0)
+ memset(&fwd, '\0', sizeof(fwd));
+ fwd.connect_host = "socks";
+ fwd.listen_host = hpdelim(&arg);
+ if (fwd.listen_host == NULL ||
+ strlen(fwd.listen_host) >= NI_MAXHOST)
+ fatal("%.200s line %d: Bad forwarding specification.",
+ filename, linenum);
+ if (arg) {
+ fwd.listen_port = a2port(arg);
+ fwd.listen_host = cleanhostname(fwd.listen_host);
+ } else {
+ fwd.listen_port = a2port(fwd.listen_host);
+ fwd.listen_host = "";
+ }
+ if (fwd.listen_port == 0)
fatal("%.200s line %d: Badly formatted port number.",
filename, linenum);
if (*activep)
- add_local_forward(options, fwd_port, "socks", 0);
+ add_local_forward(options, &fwd);
break;
case oClearAllForwardings:
@@ -761,6 +780,8 @@ parse_int:
if (strchr(arg, '=') != NULL)
fatal("%s line %d: Invalid environment name.",
filename, linenum);
+ if (!*activep)
+ continue;
if (options->num_send_env >= MAX_SEND_ENV)
fatal("%s line %d: too many send env.",
filename, linenum);
@@ -777,6 +798,10 @@ parse_int:
intptr = &options->control_master;
goto parse_yesnoask;
+ case oHashKnownHosts:
+ intptr = &options->hash_known_hosts;
+ goto parse_flag;
+
case oVersionAddendum:
ssh_version_set_addendum(strtok(s, "\n"));
do {
@@ -927,6 +952,7 @@ initialize_options(Options * options)
options->num_send_env = 0;
options->control_path = NULL;
options->control_master = -1;
+ options->hash_known_hosts = -1;
}
/*
@@ -1049,9 +1075,76 @@ fill_default_options(Options * options)
options->server_alive_count_max = 3;
if (options->control_master == -1)
options->control_master = 0;
+ if (options->hash_known_hosts == -1)
+ options->hash_known_hosts = 0;
/* options->proxy_command should not be set by default */
/* options->user will be set in the main program if appropriate */
/* options->hostname will be set in the main program if appropriate */
/* options->host_key_alias should not be set by default */
/* options->preferred_authentications will be set in ssh */
}
+
+/*
+ * parse_forward
+ * parses a string containing a port forwarding specification of the form:
+ * [listenhost:]listenport:connecthost:connectport
+ * returns number of arguments parsed or zero on error
+ */
+int
+parse_forward(Forward *fwd, const char *fwdspec)
+{
+ int i;
+ char *p, *cp, *fwdarg[4];
+
+ memset(fwd, '\0', sizeof(*fwd));
+
+ cp = p = xstrdup(fwdspec);
+
+ /* skip leading spaces */
+ while (*cp && isspace(*cp))
+ cp++;
+
+ for (i = 0; i < 4; ++i)
+ if ((fwdarg[i] = hpdelim(&cp)) == NULL)
+ break;
+
+ /* Check for trailing garbage in 4-arg case*/
+ if (cp != NULL)
+ i = 0; /* failure */
+
+ switch (i) {
+ case 3:
+ fwd->listen_host = NULL;
+ fwd->listen_port = a2port(fwdarg[0]);
+ fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
+ fwd->connect_port = a2port(fwdarg[2]);
+ break;
+
+ case 4:
+ fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
+ fwd->listen_port = a2port(fwdarg[1]);
+ fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
+ fwd->connect_port = a2port(fwdarg[3]);
+ break;
+ default:
+ i = 0; /* failure */
+ }
+
+ xfree(p);
+
+ if (fwd->listen_port == 0 && fwd->connect_port == 0)
+ goto fail_free;
+
+ if (fwd->connect_host != NULL &&
+ strlen(fwd->connect_host) >= NI_MAXHOST)
+ goto fail_free;
+
+ return (i);
+
+ fail_free:
+ if (fwd->connect_host != NULL)
+ xfree(fwd->connect_host);
+ if (fwd->listen_host != NULL)
+ xfree(fwd->listen_host);
+ return (0);
+}
diff --git a/crypto/openssh/readconf.h b/crypto/openssh/readconf.h
index ded4225857bf..de4b4cb2787c 100644
--- a/crypto/openssh/readconf.h
+++ b/crypto/openssh/readconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: readconf.h,v 1.64 2004/07/11 17:48:47 deraadt Exp $ */
+/* $OpenBSD: readconf.h,v 1.66 2005/03/01 10:40:27 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -21,9 +21,10 @@
/* Data structure for representing a forwarding request. */
typedef struct {
- u_short port; /* Port to forward. */
- char *host; /* Host to connect. */
- u_short host_port; /* Port to connect on host. */
+ char *listen_host; /* Host (address) to listen on. */
+ u_short listen_port; /* Port to forward. */
+ char *connect_host; /* Host to connect. */
+ u_short connect_port; /* Port to connect on connect_host. */
} Forward;
/* Data structure for representing option data. */
@@ -111,17 +112,20 @@ typedef struct {
char *control_path;
int control_master;
+
+ int hash_known_hosts;
} Options;
void initialize_options(Options *);
void fill_default_options(Options *);
int read_config_file(const char *, const char *, Options *, int);
+int parse_forward(Forward *, const char *);
int
process_config_line(Options *, const char *, char *, const char *, int, int *);
-void add_local_forward(Options *, u_short, const char *, u_short);
-void add_remote_forward(Options *, u_short, const char *, u_short);
+void add_local_forward(Options *, const Forward *);
+void add_remote_forward(Options *, const Forward *);
#endif /* READCONF_H */
diff --git a/crypto/openssh/scp.c b/crypto/openssh/scp.c
index ef9eaa1a4114..1d34cc63938a 100644
--- a/crypto/openssh/scp.c
+++ b/crypto/openssh/scp.c
@@ -71,7 +71,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: scp.c,v 1.117 2004/08/11 21:44:32 avsm Exp $");
+RCSID("$OpenBSD: scp.c,v 1.121 2005/04/02 12:41:16 djm Exp $");
#include "xmalloc.h"
#include "atomicio.h"
@@ -108,8 +108,10 @@ pid_t do_cmd_pid = -1;
static void
killchild(int signo)
{
- if (do_cmd_pid > 1)
+ if (do_cmd_pid > 1) {
kill(do_cmd_pid, signo);
+ waitpid(do_cmd_pid, NULL, 0);
+ }
_exit(1);
}
@@ -359,20 +361,21 @@ void
toremote(char *targ, int argc, char **argv)
{
int i, len;
- char *bp, *host, *src, *suser, *thost, *tuser;
+ char *bp, *host, *src, *suser, *thost, *tuser, *arg;
*targ++ = 0;
if (*targ == 0)
targ = ".";
- if ((thost = strrchr(argv[argc - 1], '@'))) {
+ arg = xstrdup(argv[argc - 1]);
+ if ((thost = strrchr(arg, '@'))) {
/* user@host */
*thost++ = 0;
- tuser = argv[argc - 1];
+ tuser = arg;
if (*tuser == '\0')
tuser = NULL;
} else {
- thost = argv[argc - 1];
+ thost = arg;
tuser = NULL;
}
@@ -726,7 +729,7 @@ sink(int argc, char **argv)
#define atime tv[0]
#define mtime tv[1]
-#define SCREWUP(str) do { why = str; goto screwup; } while (0)
+#define SCREWUP(str) { why = str; goto screwup; }
setimes = targisdir = 0;
mask = umask(0);
diff --git a/crypto/openssh/servconf.c b/crypto/openssh/servconf.c
index 83479c185785..deba9923c8b1 100644
--- a/crypto/openssh/servconf.c
+++ b/crypto/openssh/servconf.c
@@ -10,7 +10,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: servconf.c,v 1.137 2004/08/13 11:09:24 dtucker Exp $");
+RCSID("$OpenBSD: servconf.c,v 1.140 2005/03/10 22:01:05 deraadt Exp $");
RCSID("$FreeBSD$");
#include "ssh.h"
@@ -27,8 +27,6 @@ RCSID("$FreeBSD$");
static void add_listen_addr(ServerOptions *, char *, u_short);
static void add_one_listen_addr(ServerOptions *, char *, u_short);
-/* AF_UNSPEC or AF_INET or AF_INET6 */
-extern int IPv4or6;
/* Use of privilege separation or not */
extern int use_privsep;
@@ -46,6 +44,7 @@ initialize_server_options(ServerOptions *options)
options->num_ports = 0;
options->ports_from_cmdline = 0;
options->listen_addrs = NULL;
+ options->address_family = -1;
options->num_host_key_files = 0;
options->pid_file = NULL;
options->server_key_bits = -1;
@@ -261,7 +260,8 @@ typedef enum {
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
sKerberosGetAFSToken,
sKerberosTgtPassing, sChallengeResponseAuthentication,
- sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
+ sPasswordAuthentication, sKbdInteractiveAuthentication,
+ sListenAddress, sAddressFamily,
sPrintMotd, sPrintLastLog, sIgnoreRhosts,
sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
sStrictModes, sEmptyPasswd, sTCPKeepAlive,
@@ -339,6 +339,7 @@ static struct {
{ "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
{ "checkmail", sDeprecated },
{ "listenaddress", sListenAddress },
+ { "addressfamily", sAddressFamily },
{ "printmotd", sPrintMotd },
{ "printlastlog", sPrintLastLog },
{ "ignorerhosts", sIgnoreRhosts },
@@ -406,6 +407,8 @@ add_listen_addr(ServerOptions *options, char *addr, u_short port)
if (options->num_ports == 0)
options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
+ if (options->address_family == -1)
+ options->address_family = AF_UNSPEC;
if (port == 0)
for (i = 0; i < options->num_ports; i++)
add_one_listen_addr(options, addr, options->ports[i]);
@@ -421,7 +424,7 @@ add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
int gaierr;
memset(&hints, 0, sizeof(hints));
- hints.ai_family = IPv4or6;
+ hints.ai_family = options->address_family;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
snprintf(strport, sizeof strport, "%u", port);
@@ -442,6 +445,7 @@ process_server_config_line(ServerOptions *options, char *line,
char *cp, **charptr, *arg, *p;
int *intptr, value, i, n;
ServerOpCodes opcode;
+ u_short port;
cp = line;
arg = strdelim(&cp);
@@ -514,39 +518,40 @@ parse_time:
case sListenAddress:
arg = strdelim(&cp);
- if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0)
- fatal("%s line %d: missing inet addr.",
+ if (arg == NULL || *arg == '\0')
+ fatal("%s line %d: missing address",
filename, linenum);
- if (*arg == '[') {
- if ((p = strchr(arg, ']')) == NULL)
- fatal("%s line %d: bad ipv6 inet addr usage.",
- filename, linenum);
- arg++;
- memmove(p, p+1, strlen(p+1)+1);
- } else if (((p = strchr(arg, ':')) == NULL) ||
- (strchr(p+1, ':') != NULL)) {
- add_listen_addr(options, arg, 0);
- break;
- }
- if (*p == ':') {
- u_short port;
+ p = hpdelim(&arg);
+ if (p == NULL)
+ fatal("%s line %d: bad address:port usage",
+ filename, linenum);
+ p = cleanhostname(p);
+ if (arg == NULL)
+ port = 0;
+ else if ((port = a2port(arg)) == 0)
+ fatal("%s line %d: bad port number", filename, linenum);
- p++;
- if (*p == '\0')
- fatal("%s line %d: bad inet addr:port usage.",
- filename, linenum);
- else {
- *(p-1) = '\0';
- if ((port = a2port(p)) == 0)
- fatal("%s line %d: bad port number.",
- filename, linenum);
- add_listen_addr(options, arg, port);
- }
- } else if (*p == '\0')
- add_listen_addr(options, arg, 0);
+ add_listen_addr(options, p, port);
+
+ break;
+
+ case sAddressFamily:
+ arg = strdelim(&cp);
+ intptr = &options->address_family;
+ if (options->listen_addrs != NULL)
+ fatal("%s line %d: address family must be specified before "
+ "ListenAddress.", filename, linenum);
+ if (strcasecmp(arg, "inet") == 0)
+ value = AF_INET;
+ else if (strcasecmp(arg, "inet6") == 0)
+ value = AF_INET6;
+ else if (strcasecmp(arg, "any") == 0)
+ value = AF_UNSPEC;
else
- fatal("%s line %d: bad inet addr usage.",
- filename, linenum);
+ fatal("%s line %d: unsupported address family \"%s\".",
+ filename, linenum, arg);
+ if (*intptr == -1)
+ *intptr = value;
break;
case sHostKeyFile:
@@ -725,7 +730,23 @@ parse_flag:
case sGatewayPorts:
intptr = &options->gateway_ports;
- goto parse_flag;
+ arg = strdelim(&cp);
+ if (!arg || *arg == '\0')
+ fatal("%s line %d: missing yes/no/clientspecified "
+ "argument.", filename, linenum);
+ value = 0; /* silence compiler */
+ if (strcmp(arg, "clientspecified") == 0)
+ value = 2;
+ else if (strcmp(arg, "yes") == 0)
+ value = 1;
+ else if (strcmp(arg, "no") == 0)
+ value = 0;
+ else
+ fatal("%s line %d: Bad yes/no/clientspecified "
+ "argument: %s", filename, linenum, arg);
+ if (*intptr == -1)
+ *intptr = value;
+ break;
case sUseDNS:
intptr = &options->use_dns;
@@ -992,7 +1013,7 @@ parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
obuf = cbuf = xstrdup(buffer_ptr(conf));
linenum = 1;
- while((cp = strsep(&cbuf, "\n")) != NULL) {
+ while ((cp = strsep(&cbuf, "\n")) != NULL) {
if (process_server_config_line(options, cp, filename,
linenum++) != 0)
bad_options++;
diff --git a/crypto/openssh/servconf.h b/crypto/openssh/servconf.h
index 828634215963..20d468f4a346 100644
--- a/crypto/openssh/servconf.h
+++ b/crypto/openssh/servconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.h,v 1.70 2004/06/24 19:30:54 djm Exp $ */
+/* $OpenBSD: servconf.h,v 1.71 2004/12/23 23:11:00 djm Exp $ */
/* $FreeBSD$ */
/*
@@ -44,6 +44,7 @@ typedef struct {
u_short ports[MAX_PORTS]; /* Port number to listen on. */
char *listen_addr; /* Address on which the server listens. */
struct addrinfo *listen_addrs; /* Addresses on which the server listens. */
+ int address_family; /* Address family used by the server. */
char *host_key_files[MAX_HOSTKEYS]; /* Files containing host keys. */
int num_host_key_files; /* Number of files for host keys. */
char *pid_file; /* Where to put our pid */
diff --git a/crypto/openssh/session.c b/crypto/openssh/session.c
index cbc8db1b918c..2a8a900f5bdb 100644
--- a/crypto/openssh/session.c
+++ b/crypto/openssh/session.c
@@ -33,7 +33,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.180 2004/07/28 09:40:29 markus Exp $");
+RCSID("$OpenBSD: session.c,v 1.181 2004/12/23 17:35:48 markus Exp $");
RCSID("$FreeBSD$");
#include "ssh.h"
@@ -246,6 +246,10 @@ do_authenticated1(Authctxt *authctxt)
u_int proto_len, data_len, dlen, compression_level = 0;
s = session_new();
+ if (s == NULL) {
+ error("no more sessions");
+ return;
+ }
s->authctxt = authctxt;
s->pw = authctxt->pw;
@@ -662,11 +666,15 @@ do_exec(Session *s, const char *command)
debug("Forced command '%.900s'", command);
}
-#ifdef GSSAPI
- if (options.gss_authentication) {
- temporarily_use_uid(s->pw);
- ssh_gssapi_storecreds();
- restore_uid();
+#ifdef SSH_AUDIT_EVENTS
+ if (command != NULL)
+ PRIVSEP(audit_run_command(command));
+ else if (s->ttyfd == -1) {
+ char *shell = s->pw->pw_shell;
+
+ if (shell[0] == '\0') /* empty shell means /bin/sh */
+ shell =_PATH_BSHELL;
+ PRIVSEP(audit_run_command(shell));
}
#endif
@@ -1002,7 +1010,13 @@ do_setup_env(Session *s, const char *shell)
* The Windows environment contains some setting which are
* important for a running system. They must not be dropped.
*/
- copy_environment(environ, &env, &envsize);
+ {
+ char **p;
+
+ p = fetch_windows_environment();
+ copy_environment(p, &env, &envsize);
+ free_windows_environment(p);
+ }
#endif
if (getenv("TZ"))
@@ -1111,14 +1125,24 @@ do_setup_env(Session *s, const char *shell)
child_set_env(&env, &envsize, "TMPDIR", cray_tmpdir);
#endif /* _UNICOS */
+ /*
+ * Since we clear KRB5CCNAME at startup, if it's set now then it
+ * must have been set by a native authentication method (eg AIX or
+ * SIA), so copy it to the child.
+ */
+ {
+ char *cp;
+
+ if ((cp = getenv("KRB5CCNAME")) != NULL)
+ child_set_env(&env, &envsize, "KRB5CCNAME", cp);
+ }
+
#ifdef _AIX
{
char *cp;
if ((cp = getenv("AUTHSTATE")) != NULL)
child_set_env(&env, &envsize, "AUTHSTATE", cp);
- if ((cp = getenv("KRB5CCNAME")) != NULL)
- child_set_env(&env, &envsize, "KRB5CCNAME", cp);
read_environment_file(&env, &envsize, "/etc/environment");
}
#endif
@@ -1278,6 +1302,13 @@ do_setusercontext(struct passwd *pw)
# ifdef __bsdi__
setpgid(0, 0);
# endif
+#ifdef GSSAPI
+ if (options.gss_authentication) {
+ temporarily_use_uid(pw);
+ ssh_gssapi_storecreds();
+ restore_uid();
+ }
+#endif
# ifdef USE_PAM
if (options.use_pam) {
do_pam_session();
@@ -1308,6 +1339,13 @@ do_setusercontext(struct passwd *pw)
exit(1);
}
endgrent();
+#ifdef GSSAPI
+ if (options.gss_authentication) {
+ temporarily_use_uid(pw);
+ ssh_gssapi_storecreds();
+ restore_uid();
+ }
+#endif
# ifdef USE_PAM
/*
* PAM credentials may take the form of supplementary groups.
@@ -1345,7 +1383,12 @@ do_pwchange(Session *s)
if (s->ttyfd != -1) {
fprintf(stderr,
"You must change your password now and login again!\n");
+#ifdef PASSWD_NEEDS_USERNAME
+ execl(_PATH_PASSWD_PROG, "passwd", s->pw->pw_name,
+ (char *)NULL);
+#else
execl(_PATH_PASSWD_PROG, "passwd", (char *)NULL);
+#endif
perror("passwd");
} else {
fprintf(stderr,
@@ -1462,11 +1505,19 @@ do_child(Session *s, const char *command)
* generated messages, so if this in an interactive
* login then display them too.
*/
- if (command == NULL)
+ if (!check_quietlogin(s, command))
display_loginmsg();
#endif /* HAVE_OSF_SIA */
}
+#ifdef USE_PAM
+ if (options.use_pam && !options.use_login && !is_pam_session_open()) {
+ debug3("PAM session not opened, exiting");
+ display_loginmsg();
+ exit(254);
+ }
+#endif
+
/*
* Get the shell from the password data. An empty shell field is
* legal, and means /bin/sh.
diff --git a/crypto/openssh/ssh-add.c b/crypto/openssh/ssh-add.c
index 06a52464e034..a796647a7643 100644
--- a/crypto/openssh/ssh-add.c
+++ b/crypto/openssh/ssh-add.c
@@ -35,7 +35,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: ssh-add.c,v 1.70 2004/05/08 00:21:31 djm Exp $");
+RCSID("$OpenBSD: ssh-add.c,v 1.71 2005/03/10 22:01:06 deraadt Exp $");
#include <openssl/evp.h>
@@ -389,7 +389,7 @@ main(int argc, char **argv)
goto done;
}
- for(i = 0; default_files[i]; i++) {
+ for (i = 0; default_files[i]; i++) {
snprintf(buf, sizeof(buf), "%s/%s", pw->pw_dir,
default_files[i]);
if (stat(buf, &st) < 0)
@@ -402,7 +402,7 @@ main(int argc, char **argv)
if (count == 0)
ret = 1;
} else {
- for(i = 0; i < argc; i++) {
+ for (i = 0; i < argc; i++) {
if (do_file(ac, deleting, argv[i]) == -1)
ret = 1;
}
diff --git a/crypto/openssh/ssh-agent.c b/crypto/openssh/ssh-agent.c
index 22cf7e5ed6db..99ec904b6992 100644
--- a/crypto/openssh/ssh-agent.c
+++ b/crypto/openssh/ssh-agent.c
@@ -35,7 +35,7 @@
#include "includes.h"
#include "openbsd-compat/sys-queue.h"
-RCSID("$OpenBSD: ssh-agent.c,v 1.120 2004/08/11 21:43:05 avsm Exp $");
+RCSID("$OpenBSD: ssh-agent.c,v 1.122 2004/10/29 22:53:56 djm Exp $");
RCSID("$FreeBSD$");
#include <openssl/evp.h>
@@ -169,23 +169,15 @@ lookup_identity(Key *key, int version)
static int
confirm_key(Identity *id)
{
- char *p, prompt[1024];
+ char *p;
int ret = -1;
p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX);
- snprintf(prompt, sizeof(prompt), "Allow use of key %s?\n"
- "Key fingerprint %s.", id->comment, p);
+ if (ask_permission("Allow use of key %s?\nKey fingerprint %s.",
+ id->comment, p))
+ ret = 0;
xfree(p);
- p = read_passphrase(prompt, RP_ALLOW_EOF);
- if (p != NULL) {
- /*
- * Accept empty responses and responses consisting
- * of the word "yes" as affirmative.
- */
- if (*p == '\0' || *p == '\n' || strcasecmp(p, "yes") == 0)
- ret = 0;
- xfree(p);
- }
+
return (ret);
}
@@ -1011,9 +1003,7 @@ main(int ac, char **av)
#ifdef HAVE_SETRLIMIT
struct rlimit rlim;
#endif
-#ifdef HAVE_CYGWIN
int prev_mask;
-#endif
extern int optind;
extern char *optarg;
pid_t pid;
@@ -1126,24 +1116,20 @@ main(int ac, char **av)
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
perror("socket");
+ *socket_name = '\0'; /* Don't unlink any existing file */
cleanup_exit(1);
}
memset(&sunaddr, 0, sizeof(sunaddr));
sunaddr.sun_family = AF_UNIX;
strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path));
-#ifdef HAVE_CYGWIN
prev_mask = umask(0177);
-#endif
if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) {
perror("bind");
-#ifdef HAVE_CYGWIN
+ *socket_name = '\0'; /* Don't unlink any existing file */
umask(prev_mask);
-#endif
cleanup_exit(1);
}
-#ifdef HAVE_CYGWIN
umask(prev_mask);
-#endif
if (listen(sock, SSH_LISTEN_BACKLOG) < 0) {
perror("listen");
cleanup_exit(1);
diff --git a/crypto/openssh/ssh-keyscan.c b/crypto/openssh/ssh-keyscan.c
index 3cb52ac2e9f3..bc2c3b728886 100644
--- a/crypto/openssh/ssh-keyscan.c
+++ b/crypto/openssh/ssh-keyscan.c
@@ -7,7 +7,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: ssh-keyscan.c,v 1.50 2004/08/11 21:44:32 avsm Exp $");
+RCSID("$OpenBSD: ssh-keyscan.c,v 1.52 2005/03/01 15:47:14 jmc Exp $");
#include "openbsd-compat/sys-queue.h"
@@ -28,6 +28,7 @@ RCSID("$OpenBSD: ssh-keyscan.c,v 1.50 2004/08/11 21:44:32 avsm Exp $");
#include "log.h"
#include "atomicio.h"
#include "misc.h"
+#include "hostfile.h"
/* Flag indicating whether IPv4 or IPv6. This can be set on the command line.
Default value is AF_UNSPEC means both IPv4 and IPv6. */
@@ -41,6 +42,8 @@ int ssh_port = SSH_DEFAULT_PORT;
int get_keytypes = KT_RSA1; /* Get only RSA1 keys by default */
+int hash_hosts = 0; /* Hash hostname on output */
+
#define MAXMAXFD 256
/* The number of seconds after which to give up on a TCP connection */
@@ -366,10 +369,14 @@ keygrab_ssh2(con *c)
static void
keyprint(con *c, Key *key)
{
+ char *host = c->c_output_name ? c->c_output_name : c->c_name;
+
if (!key)
return;
+ if (hash_hosts && (host = host_hash(host, NULL, 0)) == NULL)
+ fatal("host_hash failed");
- fprintf(stdout, "%s ", c->c_output_name ? c->c_output_name : c->c_name);
+ fprintf(stdout, "%s ", host);
key_write(key, stdout);
fputs("\n", stdout);
}
@@ -676,7 +683,7 @@ fatal(const char *fmt,...)
static void
usage(void)
{
- fprintf(stderr, "usage: %s [-v46] [-p port] [-T timeout] [-t type] [-f file]\n"
+ fprintf(stderr, "usage: %s [-46Hv] [-f file] [-p port] [-T timeout] [-t type]\n"
"\t\t [host | addrlist namelist] [...]\n",
__progname);
exit(1);
@@ -700,8 +707,11 @@ main(int argc, char **argv)
if (argc <= 1)
usage();
- while ((opt = getopt(argc, argv, "v46p:T:t:f:")) != -1) {
+ while ((opt = getopt(argc, argv, "Hv46p:T:t:f:")) != -1) {
switch (opt) {
+ case 'H':
+ hash_hosts = 1;
+ break;
case 'p':
ssh_port = a2port(optarg);
if (ssh_port == 0) {
diff --git a/crypto/openssh/ssh.1 b/crypto/openssh/ssh.1
index 4e5dbf1f1bf7..296a32650b98 100644
--- a/crypto/openssh/ssh.1
+++ b/crypto/openssh/ssh.1
@@ -341,7 +341,6 @@ The user should not manually set
.Ev DISPLAY .
Forwarding of X11 connections can be
configured on the command line or in configuration files.
-Take note that X11 forwarding can represent a security hazard.
.Pp
The
.Ev DISPLAY
diff --git a/crypto/openssh/ssh.c b/crypto/openssh/ssh.c
index 0952f51ac51c..3f9c7f10ee18 100644
--- a/crypto/openssh/ssh.c
+++ b/crypto/openssh/ssh.c
@@ -40,7 +40,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: ssh.c,v 1.224 2004/07/28 09:40:29 markus Exp $");
+RCSID("$OpenBSD: ssh.c,v 1.234 2005/03/10 22:01:06 deraadt Exp $");
RCSID("$FreeBSD$");
#include <openssl/evp.h>
@@ -145,6 +145,9 @@ pid_t proxy_command_pid = 0;
/* fd to control socket */
int control_fd = -1;
+/* Multiplexing control command */
+static u_int mux_command = SSHMUX_COMMAND_OPEN;
+
/* Only used in control client mode */
volatile sig_atomic_t control_client_terminate = 0;
u_int control_server_pid = 0;
@@ -155,10 +158,12 @@ static void
usage(void)
{
fprintf(stderr,
-"usage: ssh [-1246AaCfghkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n"
-" [-D port] [-e escape_char] [-F configfile] [-i identity_file]\n"
-" [-L port:host:hostport] [-l login_name] [-m mac_spec] [-o option]\n"
-" [-p port] [-R port:host:hostport] [-S ctl] [user@]hostname [command]\n"
+"usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n"
+" [-D port] [-e escape_char] [-F configfile]\n"
+" [-i identity_file] [-L [bind_address:]port:host:hostport]\n"
+" [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n"
+" [-R [bind_address:]port:host:hostport] [-S ctl_path]\n"
+" [user@]hostname [command]\n"
);
exit(1);
}
@@ -175,14 +180,13 @@ int
main(int ac, char **av)
{
int i, opt, exit_status;
- u_short fwd_port, fwd_host_port;
- char sfwd_port[6], sfwd_host_port[6];
char *p, *cp, *line, buf[256];
struct stat st;
struct passwd *pw;
int dummy;
extern int optind, optreset;
extern char *optarg;
+ Forward fwd;
__progname = ssh_get_progname(av[0]);
init_rng();
@@ -237,7 +241,7 @@ main(int ac, char **av)
again:
while ((opt = getopt(ac, av,
- "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNPR:S:TVXY")) != -1) {
+ "1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVXY")) != -1) {
switch (opt) {
case '1':
options.protocol = SSH_PROTO_1;
@@ -271,6 +275,14 @@ again:
case 'g':
options.gateway_ports = 1;
break;
+ case 'O':
+ if (strcmp(optarg, "check") == 0)
+ mux_command = SSHMUX_COMMAND_ALIVE_CHECK;
+ else if (strcmp(optarg, "exit") == 0)
+ mux_command = SSHMUX_COMMAND_TERMINATE;
+ else
+ fatal("Invalid multiplex command.");
+ break;
case 'P': /* deprecated */
options.use_privileged_port = 0;
break;
@@ -286,7 +298,8 @@ again:
case 'i':
if (stat(optarg, &st) < 0) {
fprintf(stderr, "Warning: Identity file %s "
- "does not exist.\n", optarg);
+ "not accessible: %s.\n", optarg,
+ strerror(errno));
break;
}
if (options.num_identity_files >=
@@ -317,10 +330,10 @@ again:
options.log_level++;
break;
}
- /* fallthrough */
+ /* FALLTHROUGH */
case 'V':
fprintf(stderr, "%s, %s\n",
- SSH_VERSION, SSLeay_version(SSLEAY_VERSION));
+ SSH_RELEASE, SSLeay_version(SSLEAY_VERSION));
if (opt == 'V')
exit(0);
break;
@@ -389,39 +402,51 @@ again:
break;
case 'L':
- case 'R':
- if (sscanf(optarg, "%5[0123456789]:%255[^:]:%5[0123456789]",
- sfwd_port, buf, sfwd_host_port) != 3 &&
- sscanf(optarg, "%5[0123456789]/%255[^/]/%5[0123456789]",
- sfwd_port, buf, sfwd_host_port) != 3) {
+ if (parse_forward(&fwd, optarg))
+ add_local_forward(&options, &fwd);
+ else {
fprintf(stderr,
- "Bad forwarding specification '%s'\n",
+ "Bad local forwarding specification '%s'\n",
optarg);
- usage();
- /* NOTREACHED */
+ exit(1);
}
- if ((fwd_port = a2port(sfwd_port)) == 0 ||
- (fwd_host_port = a2port(sfwd_host_port)) == 0) {
+ break;
+
+ case 'R':
+ if (parse_forward(&fwd, optarg)) {
+ add_remote_forward(&options, &fwd);
+ } else {
fprintf(stderr,
- "Bad forwarding port(s) '%s'\n", optarg);
+ "Bad remote forwarding specification "
+ "'%s'\n", optarg);
exit(1);
}
- if (opt == 'L')
- add_local_forward(&options, fwd_port, buf,
- fwd_host_port);
- else if (opt == 'R')
- add_remote_forward(&options, fwd_port, buf,
- fwd_host_port);
break;
case 'D':
- fwd_port = a2port(optarg);
- if (fwd_port == 0) {
+ cp = p = xstrdup(optarg);
+ memset(&fwd, '\0', sizeof(fwd));
+ fwd.connect_host = "socks";
+ if ((fwd.listen_host = hpdelim(&cp)) == NULL) {
+ fprintf(stderr, "Bad dynamic forwarding "
+ "specification '%.100s'\n", optarg);
+ exit(1);
+ }
+ if (cp != NULL) {
+ fwd.listen_port = a2port(cp);
+ fwd.listen_host = cleanhostname(fwd.listen_host);
+ } else {
+ fwd.listen_port = a2port(fwd.listen_host);
+ fwd.listen_host = "";
+ }
+
+ if (fwd.listen_port == 0) {
fprintf(stderr, "Bad dynamic port '%s'\n",
optarg);
exit(1);
}
- add_local_forward(&options, fwd_port, "socks", 0);
+ add_local_forward(&options, &fwd);
+ xfree(p);
break;
case 'C':
@@ -847,14 +872,19 @@ ssh_init_forwarding(void)
/* Initiate local TCP/IP port forwardings. */
for (i = 0; i < options.num_local_forwards; i++) {
- debug("Connections to local port %d forwarded to remote address %.200s:%d",
- options.local_forwards[i].port,
- options.local_forwards[i].host,
- options.local_forwards[i].host_port);
+ debug("Local connections to %.200s:%d forwarded to remote "
+ "address %.200s:%d",
+ (options.local_forwards[i].listen_host == NULL) ?
+ (options.gateway_ports ? "*" : "LOCALHOST") :
+ options.local_forwards[i].listen_host,
+ options.local_forwards[i].listen_port,
+ options.local_forwards[i].connect_host,
+ options.local_forwards[i].connect_port);
success += channel_setup_local_fwd_listener(
- options.local_forwards[i].port,
- options.local_forwards[i].host,
- options.local_forwards[i].host_port,
+ options.local_forwards[i].listen_host,
+ options.local_forwards[i].listen_port,
+ options.local_forwards[i].connect_host,
+ options.local_forwards[i].connect_port,
options.gateway_ports);
}
if (i > 0 && success == 0)
@@ -862,14 +892,19 @@ ssh_init_forwarding(void)
/* Initiate remote TCP/IP port forwardings. */
for (i = 0; i < options.num_remote_forwards; i++) {
- debug("Connections to remote port %d forwarded to local address %.200s:%d",
- options.remote_forwards[i].port,
- options.remote_forwards[i].host,
- options.remote_forwards[i].host_port);
+ debug("Remote connections from %.200s:%d forwarded to "
+ "local address %.200s:%d",
+ (options.remote_forwards[i].listen_host == NULL) ?
+ (options.gateway_ports ? "*" : "LOCALHOST") :
+ options.remote_forwards[i].listen_host,
+ options.remote_forwards[i].listen_port,
+ options.remote_forwards[i].connect_host,
+ options.remote_forwards[i].connect_port);
channel_request_remote_forwarding(
- options.remote_forwards[i].port,
- options.remote_forwards[i].host,
- options.remote_forwards[i].host_port);
+ options.remote_forwards[i].listen_host,
+ options.remote_forwards[i].listen_port,
+ options.remote_forwards[i].connect_host,
+ options.remote_forwards[i].connect_port);
}
}
@@ -1045,12 +1080,12 @@ client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt)
return;
debug("remote forward %s for: listen %d, connect %s:%d",
type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
- options.remote_forwards[i].port,
- options.remote_forwards[i].host,
- options.remote_forwards[i].host_port);
+ options.remote_forwards[i].listen_port,
+ options.remote_forwards[i].connect_host,
+ options.remote_forwards[i].connect_port);
if (type == SSH2_MSG_REQUEST_FAILURE)
- logit("Warning: remote port forwarding failed for listen port %d",
- options.remote_forwards[i].port);
+ logit("Warning: remote port forwarding failed for listen "
+ "port %d", options.remote_forwards[i].listen_port);
}
static void
@@ -1078,7 +1113,7 @@ ssh_control_listener(void)
old_umask = umask(0177);
if (bind(control_fd, (struct sockaddr*)&addr, addr_len) == -1) {
control_fd = -1;
- if (errno == EINVAL)
+ if (errno == EINVAL || errno == EADDRINUSE)
fatal("ControlSocket %s already exists",
options.control_path);
else
@@ -1267,10 +1302,20 @@ static void
control_client(const char *path)
{
struct sockaddr_un addr;
- int i, r, sock, exitval, num_env, addr_len;
+ int i, r, fd, sock, exitval, num_env, addr_len;
Buffer m;
- char *cp;
+ char *term;
extern char **environ;
+ u_int flags;
+
+ if (stdin_null_flag) {
+ if ((fd = open(_PATH_DEVNULL, O_RDONLY)) == -1)
+ fatal("open(/dev/null): %s", strerror(errno));
+ if (dup2(fd, STDIN_FILENO) == -1)
+ fatal("dup2: %s", strerror(errno));
+ if (fd > STDERR_FILENO)
+ close(fd);
+ }
memset(&addr, '\0', sizeof(addr));
addr.sun_family = AF_UNIX;
@@ -1287,26 +1332,52 @@ control_client(const char *path)
if (connect(sock, (struct sockaddr*)&addr, addr_len) == -1)
fatal("Couldn't connect to %s: %s", path, strerror(errno));
- if ((cp = getenv("TERM")) == NULL)
- cp = "";
+ if ((term = getenv("TERM")) == NULL)
+ term = "";
+
+ flags = 0;
+ if (tty_flag)
+ flags |= SSHMUX_FLAG_TTY;
+ if (subsystem_flag)
+ flags |= SSHMUX_FLAG_SUBSYS;
buffer_init(&m);
- /* Get PID of controlee */
+ /* Send our command to server */
+ buffer_put_int(&m, mux_command);
+ buffer_put_int(&m, flags);
+ if (ssh_msg_send(sock, /* version */1, &m) == -1)
+ fatal("%s: msg_send", __func__);
+ buffer_clear(&m);
+
+ /* Get authorisation status and PID of controlee */
if (ssh_msg_recv(sock, &m) == -1)
fatal("%s: msg_recv", __func__);
- if (buffer_get_char(&m) != 0)
+ if (buffer_get_char(&m) != 1)
fatal("%s: wrong version", __func__);
- /* Connection allowed? */
if (buffer_get_int(&m) != 1)
fatal("Connection to master denied");
control_server_pid = buffer_get_int(&m);
buffer_clear(&m);
- buffer_put_int(&m, tty_flag);
- buffer_put_int(&m, subsystem_flag);
- buffer_put_cstring(&m, cp);
+ switch (mux_command) {
+ case SSHMUX_COMMAND_ALIVE_CHECK:
+ fprintf(stderr, "Master running (pid=%d)\r\n",
+ control_server_pid);
+ exit(0);
+ case SSHMUX_COMMAND_TERMINATE:
+ fprintf(stderr, "Exit request sent.\r\n");
+ exit(0);
+ case SSHMUX_COMMAND_OPEN:
+ /* continue below */
+ break;
+ default:
+ fatal("silly mux_command %d", mux_command);
+ }
+
+ /* SSHMUX_COMMAND_OPEN */
+ buffer_put_cstring(&m, term);
buffer_append(&command, "\0", 1);
buffer_put_cstring(&m, buffer_ptr(&command));
@@ -1328,7 +1399,7 @@ control_client(const char *path)
}
}
- if (ssh_msg_send(sock, /* version */0, &m) == -1)
+ if (ssh_msg_send(sock, /* version */1, &m) == -1)
fatal("%s: msg_send", __func__);
mm_send_fd(sock, STDIN_FILENO);
@@ -1339,10 +1410,11 @@ control_client(const char *path)
buffer_clear(&m);
if (ssh_msg_recv(sock, &m) == -1)
fatal("%s: msg_recv", __func__);
- if (buffer_get_char(&m) != 0)
- fatal("%s: master returned error", __func__);
+ if (buffer_get_char(&m) != 1)
+ fatal("%s: wrong version", __func__);
buffer_free(&m);
+ signal(SIGHUP, control_client_sighandler);
signal(SIGINT, control_client_sighandler);
signal(SIGTERM, control_client_sighandler);
signal(SIGWINCH, control_client_sigrelay);
diff --git a/crypto/openssh/ssh.h b/crypto/openssh/ssh.h
index a3b2ebbb5620..07592415b157 100644
--- a/crypto/openssh/ssh.h
+++ b/crypto/openssh/ssh.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh.h,v 1.75 2003/12/02 17:01:15 markus Exp $ */
+/* $OpenBSD: ssh.h,v 1.76 2004/12/06 11:41:03 dtucker Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -40,6 +40,13 @@
#define SSH_MAX_IDENTITY_FILES 100
/*
+ * Maximum length of lines in authorized_keys file.
+ * Current value permits 16kbit RSA and RSA1 keys and 8kbit DSA keys, with
+ * some room for options and comments.
+ */
+#define SSH_MAX_PUBKEY_BYTES 8192
+
+/*
* Major protocol version. Different version indicates major incompatibility
* that prevents communication.
*
diff --git a/crypto/openssh/ssh_config b/crypto/openssh/ssh_config
index 0b11c8a4925e..c1234d186553 100644
--- a/crypto/openssh/ssh_config
+++ b/crypto/openssh/ssh_config
@@ -1,4 +1,4 @@
-# $OpenBSD: ssh_config,v 1.19 2003/08/13 08:46:31 markus Exp $
+# $OpenBSD: ssh_config,v 1.20 2005/01/28 09:45:53 dtucker Exp $
# $FreeBSD$
# This is the ssh client system-wide configuration file. See
@@ -14,7 +14,9 @@
# Thus, host-specific definitions should be at the beginning of the
# configuration file, and defaults at the end.
-# Site-wide defaults for various options
+# Site-wide defaults for some commonly used options. For a comprehensive
+# list of available options, their meanings and defaults, please see the
+# ssh_config(5) man page.
# Host *
# ForwardAgent no
@@ -36,4 +38,4 @@
# Cipher 3des
# Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
# EscapeChar ~
-# VersionAddendum FreeBSD-20041028
+# VersionAddendum FreeBSD-20050605
diff --git a/crypto/openssh/ssh_config.5 b/crypto/openssh/ssh_config.5
index e1cc15133adc..805dd9eea33f 100644
--- a/crypto/openssh/ssh_config.5
+++ b/crypto/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.38 2004/06/26 09:11:14 jmc Exp $
+.\" $OpenBSD: ssh_config.5,v 1.49 2005/03/16 11:10:38 jmc Exp $
.\" $FreeBSD$
.Dd September 25, 1999
.Dt SSH_CONFIG 5
@@ -64,7 +64,7 @@ system-wide configuration file
.Pp
For each parameter, the first obtained value
will be used.
-The configuration files contain sections bracketed by
+The configuration files contain sections separated by
.Dq Host
specifications, and that section is only applied for hosts that
match one of the patterns given in the specification.
@@ -121,9 +121,9 @@ Specifies which address family to use when connecting.
Valid arguments are
.Dq any ,
.Dq inet
-(Use IPv4 only) or
+(use IPv4 only) or
.Dq inet6
-(Use IPv6 only.)
+(use IPv6 only).
.It Cm BatchMode
If set to
.Dq yes ,
@@ -360,11 +360,16 @@ option is also enabled.
If this option is set to
.Dq yes
then remote X11 clients will have full access to the original X11 display.
+.Pp
If this option is set to
.Dq no
then remote X11 clients will be considered untrusted and prevented
from stealing or tampering with data belonging to trusted X11
clients.
+Furthermore, the
+.Xr xauth 1
+token used for the session will be set to expire after 20 minutes.
+Remote clients will be refused access after this time.
.Pp
The default is
.Dq no .
@@ -403,6 +408,22 @@ Forward (delegate) credentials to the server.
The default is
.Dq no .
Note that this option applies to protocol version 2 only.
+.It Cm HashKnownHosts
+Indicates that
+.Nm ssh
+should hash host names and addresses when they are added to
+.Pa $HOME/.ssh/known_hosts .
+These hashed names may be used normally by
+.Nm ssh
+and
+.Nm sshd ,
+but they do not reveal identifying information should the file's contents
+be disclosed.
+The default is
+.Dq no .
+Note that hashing of names and addresses will not be retrospectively applied
+to existing known hosts files, but these may be manually hashed using
+.Xr ssh-keygen 1 .
.It Cm HostbasedAuthentication
Specifies whether to try rhosts based authentication with public key
authentication.
@@ -468,16 +489,41 @@ This option is intented for situations where
offers many different identities.
The default is
.Dq no .
+.It Cm KbdInteractiveDevices
+Specifies the list of methods to use in keyboard-interactive authentication.
+Multiple method names must be comma-separated.
+The default is to use the server specified list.
.It Cm LocalForward
Specifies that a TCP/IP port on the local machine be forwarded over
the secure channel to the specified host and port from the remote machine.
-The first argument must be a port number, and the second must be
-.Ar host:port .
-IPv6 addresses can be specified with an alternative syntax:
-.Ar host/port .
-Multiple forwardings may be specified, and additional
-forwardings can be given on the command line.
+The first argument must be
+.Sm off
+.Oo Ar bind_address : Oc Ar port
+.Sm on
+and the second argument must be
+.Ar host : Ns Ar hostport .
+IPv6 addresses can be specified by enclosing addresses in square brackets or
+by using an alternative syntax:
+.Oo Ar bind_address Ns / Oc Ns Ar port
+and
+.Ar host Ns / Ns Ar hostport .
+Multiple forwardings may be specified, and additional forwardings can be
+given on the command line.
Only the superuser can forward privileged ports.
+By default, the local port is bound in accordance with the
+.Cm GatewayPorts
+setting.
+However, an explicit
+.Ar bind_address
+may be used to bind the connection to a specific address.
+The
+.Ar bind_address
+of
+.Dq localhost
+indicates that the listening port be bound for local use only, while an
+empty address or
+.Sq *
+indicates that the port should be available from all interfaces.
.It Cm LogLevel
Gives the verbosity level that is used when logging messages from
.Nm ssh .
@@ -522,9 +568,9 @@ Default is 22.
.It Cm PreferredAuthentications
Specifies the order in which the client should try protocol 2
authentication methods.
-This allows a client to prefer one method (e.g.
+This allows a client to prefer one method (e.g.\&
.Cm keyboard-interactive )
-over another method (e.g.
+over another method (e.g.\&
.Cm password )
The default for this option is:
.Dq hostbased,publickey,keyboard-interactive,password .
@@ -583,13 +629,36 @@ This option applies to protocol version 2 only.
.It Cm RemoteForward
Specifies that a TCP/IP port on the remote machine be forwarded over
the secure channel to the specified host and port from the local machine.
-The first argument must be a port number, and the second must be
-.Ar host:port .
-IPv6 addresses can be specified with an alternative syntax:
-.Ar host/port .
+The first argument must be
+.Sm off
+.Oo Ar bind_address : Oc Ar port
+.Sm on
+and the second argument must be
+.Ar host : Ns Ar hostport .
+IPv6 addresses can be specified by enclosing addresses in square brackets
+or by using an alternative syntax:
+.Oo Ar bind_address Ns / Oc Ns Ar port
+and
+.Ar host Ns / Ns Ar hostport .
Multiple forwardings may be specified, and additional
forwardings can be given on the command line.
Only the superuser can forward privileged ports.
+.Pp
+If the
+.Ar bind_address
+is not specified, the default is to only bind to loopback addresses.
+If the
+.Ar bind_address
+is
+.Ql *
+or an empty string, then the forwarding is requested to listen on all
+interfaces.
+Specifying a remote
+.Ar bind_address
+will only succeed if the server's
+.Cm GatewayPorts
+option is enabled (see
+.Xr sshd_config 5 ) .
.It Cm RhostsRSAAuthentication
Specifies whether to try rhosts based authentication with RSA host
authentication.
@@ -783,7 +852,7 @@ Note that this option applies to protocol version 2 only.
Specifies a string to append to the regular version string to identify
OS- or site-specific modifications.
The default is
-.Dq FreeBSD-20041028 .
+.Dq FreeBSD-20050605 .
.It Cm XAuthLocation
Specifies the full pathname of the
.Xr xauth 1
diff --git a/crypto/openssh/sshconnect.c b/crypto/openssh/sshconnect.c
index 11008e544ff6..07703cf77091 100644
--- a/crypto/openssh/sshconnect.c
+++ b/crypto/openssh/sshconnect.c
@@ -13,7 +13,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: sshconnect.c,v 1.158 2004/06/21 17:36:31 avsm Exp $");
+RCSID("$OpenBSD: sshconnect.c,v 1.162 2005/03/10 22:01:06 deraadt Exp $");
#include <openssl/bn.h>
@@ -247,13 +247,13 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
tv.tv_sec = timeout;
tv.tv_usec = 0;
- for(;;) {
+ for (;;) {
rc = select(sockfd + 1, NULL, fdset, NULL, &tv);
if (rc != -1 || errno != EINTR)
break;
}
- switch(rc) {
+ switch (rc) {
case 0:
/* Timed out */
errno = ETIMEDOUT;
@@ -297,12 +297,6 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
* second). If proxy_command is non-NULL, it specifies the command (with %h
* and %p substituted for host and port, respectively) to use to contact
* the daemon.
- * Return values:
- * 0 for OK
- * ECONNREFUSED if we got a "Connection Refused" by the peer on any address
- * ECONNABORTED if we failed without a "Connection refused"
- * Suitable error messages for the connection failure will already have been
- * printed.
*/
int
ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
@@ -315,12 +309,6 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
struct addrinfo hints, *ai, *aitop;
struct servent *sp;
- /*
- * Did we get only other errors than "Connection refused" (which
- * should block fallback to rsh and similar), or did we get at least
- * one "Connection refused"?
- */
- int full_failure = 1;
debug2("ssh_connect: needpriv %d", needpriv);
@@ -381,8 +369,6 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
break;
} else {
- if (errno == ECONNREFUSED)
- full_failure = 0;
debug("connect to address %s port %s: %s",
ntop, strport, strerror(errno));
/*
@@ -408,9 +394,9 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
/* Return failure if we didn't get a successful connection. */
if (attempt >= connection_attempts) {
- logit("ssh: connect to host %s port %s: %s",
+ error("ssh: connect to host %s port %s: %s",
host, strport, strerror(errno));
- return full_failure ? ECONNABORTED : ECONNREFUSED;
+ return (-1);
}
debug("Connection established.");
@@ -568,7 +554,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
char hostline[1000], *hostp, *fp;
HostStatus host_status;
HostStatus ip_status;
- int local = 0, host_ip_differ = 0;
+ int r, local = 0, host_ip_differ = 0;
int salen;
char ntop[NI_MAXHOST];
char msg[1024];
@@ -692,7 +678,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
"'%.128s' not in list of known hosts.",
type, ip);
else if (!add_host_to_hostfile(user_hostfile, ip,
- host_key))
+ host_key, options.hash_known_hosts))
logit("Failed to add the %s host key for IP "
"address '%.128s' to the list of known "
"hosts (%.30s).", type, ip, user_hostfile);
@@ -748,17 +734,33 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
if (!confirm(msg))
goto fail;
}
- if (options.check_host_ip && ip_status == HOST_NEW) {
- snprintf(hostline, sizeof(hostline), "%s,%s", host, ip);
- hostp = hostline;
- } else
- hostp = host;
-
/*
* If not in strict mode, add the key automatically to the
* local known_hosts file.
*/
- if (!add_host_to_hostfile(user_hostfile, hostp, host_key))
+ if (options.check_host_ip && ip_status == HOST_NEW) {
+ snprintf(hostline, sizeof(hostline), "%s,%s",
+ host, ip);
+ hostp = hostline;
+ if (options.hash_known_hosts) {
+ /* Add hash of host and IP separately */
+ r = add_host_to_hostfile(user_hostfile, host,
+ host_key, options.hash_known_hosts) &&
+ add_host_to_hostfile(user_hostfile, ip,
+ host_key, options.hash_known_hosts);
+ } else {
+ /* Add unhashed "host,ip" */
+ r = add_host_to_hostfile(user_hostfile,
+ hostline, host_key,
+ options.hash_known_hosts);
+ }
+ } else {
+ r = add_host_to_hostfile(user_hostfile, host, host_key,
+ options.hash_known_hosts);
+ hostp = host;
+ }
+
+ if (!r)
logit("Failed to add the host to the list of known "
"hosts (%.500s).", user_hostfile);
else
diff --git a/crypto/openssh/sshd.8 b/crypto/openssh/sshd.8
index 0402a6466c12..5d6ee3ba69be 100644
--- a/crypto/openssh/sshd.8
+++ b/crypto/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.201 2004/05/02 11:54:31 dtucker Exp $
+.\" $OpenBSD: sshd.8,v 1.206 2005/03/01 14:59:49 jmc Exp $
.\" $FreeBSD$
.Dd September 25, 1999
.Dt SSHD 8
@@ -107,8 +107,6 @@ to use from those offered by the server.
Next, the server and the client enter an authentication dialog.
The client tries to authenticate itself using
.Em .rhosts
-authentication,
-.Em .rhosts
authentication combined with RSA host
authentication, RSA challenge-response authentication, or password
based authentication.
@@ -136,11 +134,6 @@ or
.Ql \&*NP\&*
).
.Pp
-.Em rhosts
-authentication is normally disabled
-because it is fundamentally insecure, but can be enabled in the server
-configuration file if desired.
-System security is not improved unless
.Nm rshd ,
.Nm rlogind ,
and
@@ -428,7 +421,9 @@ or
.Dq ssh-rsa .
.Pp
Note that lines in this file are usually several hundred bytes long
-(because of the size of the public key encoding).
+(because of the size of the public key encoding) up to a limit of
+8 kilobytes, which permits DSA keys up to 8 kilobits and RSA
+keys up to 16 kilobits.
You don't want to type them in; instead, copy the
.Pa identity.pub ,
.Pa id_dsa.pub
@@ -559,6 +554,14 @@ to indicate negation: if the host name matches a negated
pattern, it is not accepted (by that line) even if it matched another
pattern on the line.
.Pp
+Alternately, hostnames may be stored in a hashed form which hides host names
+and addresses should the file's contents be disclosed.
+Hashed hostnames start with a
+.Ql |
+character.
+Only one hashed hostname may appear on a single line and none of the above
+negation or wildcard operators may be applied.
+.Pp
Bits, exponent, and modulus are taken directly from the RSA host key; they
can be obtained, e.g., from
.Pa /etc/ssh/ssh_host_key.pub .
@@ -590,6 +593,11 @@ and adding the host names at the front.
closenet,...,130.233.208.41 1024 37 159...93 closenet.hut.fi
cvs.openbsd.org,199.185.137.3 ssh-rsa AAAA1234.....=
.Ed
+.Bd -literal
+# A hashed hostname
+|1|JfKTdBh7rNbXkVAQCRp4OQoPfmI=|USECr3SWf1JUPsms5AqfD5QfxkM= ssh-rsa
+AAAA1234.....=
+.Ed
.Sh FILES
.Bl -tag -width Ds
.It Pa /etc/ssh/sshd_config
@@ -658,6 +666,20 @@ These files should be writable only by root/the owner.
should be world-readable, and
.Pa $HOME/.ssh/known_hosts
can, but need not be, world-readable.
+.It Pa /etc/motd
+See
+.Xr motd 5 .
+.It Pa $HOME/.hushlogin
+This file is used to suppress printing the last login time and
+.Pa /etc/motd ,
+if
+.Cm PrintLastLog
+and
+.Cm PrintMotd ,
+respectively,
+are enabled.
+It does not suppress printing of the banner specified by
+.Cm Banner .
.It Pa /etc/nologin
If this file exists,
.Nm
@@ -671,7 +693,11 @@ Access controls that should be enforced by tcp-wrappers are defined here.
Further details are described in
.Xr hosts_access 5 .
.It Pa $HOME/.rhosts
-This file contains host-username pairs, separated by a space, one per
+This file is used during
+.Cm RhostsRSAAuthentication
+and
+.Cm HostbasedAuthentication
+and contains host-username pairs, separated by a space, one per
line.
The given user on the corresponding host is permitted to log in
without a password.
@@ -692,7 +718,9 @@ However, this file is
not used by rlogin and rshd, so using this permits access using SSH only.
.It Pa /etc/hosts.equiv
This file is used during
-.Em rhosts
+.Cm RhostsRSAAuthentication
+and
+.Cm HostbasedAuthentication
authentication.
In the simplest form, this file contains host names, one per line.
Users on
@@ -711,7 +739,7 @@ Negated entries start with
If the client host/user is successfully matched in this file, login is
automatically permitted provided the client and server user names are the
same.
-Additionally, successful RSA host authentication is normally required.
+Additionally, successful client host key authentication is required.
This file must be writable only by root; it is recommended
that it be world-readable.
.Pp
diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c
index 0e5dbf2b98ba..d1a968a3bd54 100644
--- a/crypto/openssh/sshd.c
+++ b/crypto/openssh/sshd.c
@@ -42,7 +42,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.301 2004/08/11 11:50:09 dtucker Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.308 2005/02/08 22:24:57 dtucker Exp $");
RCSID("$FreeBSD$");
#include <openssl/dh.h>
@@ -117,12 +117,6 @@ ServerOptions options;
char *config_file_name = _PATH_SERVER_CONFIG_FILE;
/*
- * Flag indicating whether IPv4 or IPv6. This can be set on the command line.
- * Default value is AF_UNSPEC means both IPv4 and IPv6.
- */
-int IPv4or6 = AF_UNSPEC;
-
-/*
* Debug mode flag. This can be set on the command line. If debug
* mode is enabled, extra debugging output will be sent to the system
* log, the daemon will not go to background, and will exit after processing
@@ -755,7 +749,7 @@ get_hostkey_index(Key *key)
static int
drop_connection(int startups)
{
- double p, r;
+ int p, r;
if (startups < options.max_startups_begin)
return 0;
@@ -766,12 +760,11 @@ drop_connection(int startups)
p = 100 - options.max_startups_rate;
p *= startups - options.max_startups_begin;
- p /= (double) (options.max_startups - options.max_startups_begin);
+ p /= options.max_startups - options.max_startups_begin;
p += options.max_startups_rate;
- p /= 100.0;
- r = arc4random() / (double) UINT_MAX;
+ r = arc4random() % 100;
- debug("drop_connection: p %g, r %g", p, r);
+ debug("drop_connection: p %d, r %d", p, r);
return (r < p) ? 1 : 0;
}
@@ -779,7 +772,7 @@ static void
usage(void)
{
fprintf(stderr, "%s, %s\n",
- SSH_VERSION, SSLeay_version(SSLEAY_VERSION));
+ SSH_RELEASE, SSLeay_version(SSLEAY_VERSION));
fprintf(stderr,
"usage: sshd [-46Ddeiqt] [-b bits] [-f config_file] [-g login_grace_time]\n"
" [-h host_key_file] [-k key_gen_time] [-o option] [-p port] [-u len]\n"
@@ -889,7 +882,7 @@ main(int ac, char **av)
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
char *line;
int listen_sock, maxfd;
- int startup_p[2], config_s[2];
+ int startup_p[2] = { -1 , -1 }, config_s[2] = { -1 , -1 };
int startups = 0;
Key *key;
Authctxt *authctxt;
@@ -926,10 +919,10 @@ main(int ac, char **av)
while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:dDeiqrtQR46")) != -1) {
switch (opt) {
case '4':
- IPv4or6 = AF_INET;
+ options.address_family = AF_INET;
break;
case '6':
- IPv4or6 = AF_INET6;
+ options.address_family = AF_INET6;
break;
case 'f':
config_file_name = optarg;
@@ -1030,7 +1023,6 @@ main(int ac, char **av)
closefrom(REEXEC_DEVCRYPTO_RESERVED_FD);
SSLeay_add_all_algorithms();
- channel_set_af(IPv4or6);
/*
* Force logging to stderr until we have loaded the private host
@@ -1043,13 +1035,13 @@ main(int ac, char **av)
SYSLOG_FACILITY_AUTH : options.log_facility,
log_stderr || !inetd_flag);
-#ifdef _AIX
/*
* Unset KRB5CCNAME, otherwise the user's session may inherit it from
* root's environment
*/
- unsetenv("KRB5CCNAME");
-#endif /* _AIX */
+ if (getenv("KRB5CCNAME") != NULL)
+ unsetenv("KRB5CCNAME");
+
#ifdef _UNICOS
/* Cray can define user privs drop all privs now!
* Not needed on PRIV_SU systems!
@@ -1080,13 +1072,16 @@ main(int ac, char **av)
/* Fill in default values for those options not explicitly set. */
fill_default_server_options(&options);
+ /* set default channel AF */
+ channel_set_af(options.address_family);
+
/* Check that there are no remaining arguments. */
if (optind < ac) {
fprintf(stderr, "Extra argument %s.\n", av[optind]);
exit(1);
}
- debug("sshd version %.100s", SSH_VERSION);
+ debug("sshd version %.100s", SSH_RELEASE);
/* load private host keys */
sensitive_data.host_keys = xmalloc(options.num_host_key_files *
@@ -1202,7 +1197,7 @@ main(int ac, char **av)
}
/* Initialize the log (it is reinitialized below in case we forked). */
- if (debug_flag && !inetd_flag)
+ if (debug_flag && (!inetd_flag || rexeced_flag))
log_stderr = 1;
log_init(__progname, options.log_level, options.log_facility, log_stderr);
@@ -1278,10 +1273,12 @@ main(int ac, char **av)
if (num_listen_socks >= MAX_LISTEN_SOCKS)
fatal("Too many listen sockets. "
"Enlarge MAX_LISTEN_SOCKS");
- if (getnameinfo(ai->ai_addr, ai->ai_addrlen,
+ if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen,
ntop, sizeof(ntop), strport, sizeof(strport),
- NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
- error("getnameinfo failed");
+ NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
+ error("getnameinfo failed: %.100s",
+ (ret != EAI_SYSTEM) ? gai_strerror(ret) :
+ strerror(errno));
continue;
}
/* Create socket for listening. */
@@ -1512,7 +1509,8 @@ main(int ac, char **av)
sock_in = newsock;
sock_out = newsock;
log_init(__progname, options.log_level, options.log_facility, log_stderr);
- close(config_s[0]);
+ if (rexec_flag)
+ close(config_s[0]);
break;
}
}
@@ -1648,6 +1646,9 @@ main(int ac, char **av)
remote_port = get_remote_port();
remote_ip = get_remote_ipaddr();
+#ifdef SSH_AUDIT_EVENTS
+ audit_connection_from(remote_ip, remote_port);
+#endif
#ifdef LIBWRAP
/* Check whether logins are denied from this host. */
if (packet_connection_is_on_socket()) {
@@ -1684,23 +1685,22 @@ main(int ac, char **av)
packet_set_nonblocking();
- /* prepare buffers to collect authentication messages */
- buffer_init(&loginmsg);
-
/* allocate authentication context */
authctxt = xmalloc(sizeof(*authctxt));
memset(authctxt, 0, sizeof(*authctxt));
+ authctxt->loginmsg = &loginmsg;
+
/* XXX global for cleanup, access from other modules */
the_authctxt = authctxt;
+ /* prepare buffer to collect messages to display to user after login */
+ buffer_init(&loginmsg);
+
if (use_privsep)
if (privsep_preauth(authctxt) == 1)
goto authenticated;
- /* prepare buffer to collect messages to display to user after login */
- buffer_init(&loginmsg);
-
/* perform the key exchange */
/* authenticate user and start session */
if (compat20) {
@@ -1720,6 +1720,10 @@ main(int ac, char **av)
}
authenticated:
+#ifdef SSH_AUDIT_EVENTS
+ audit_event(SSH_AUTH_SUCCESS);
+#endif
+
/*
* In privilege separation, we fork another child and prepare
* file descriptor passing.
@@ -1742,6 +1746,10 @@ main(int ac, char **av)
finish_pam();
#endif /* USE_PAM */
+#ifdef SSH_AUDIT_EVENTS
+ PRIVSEP(audit_event(SSH_CONNECTION_CLOSE));
+#endif
+
packet_close();
if (use_privsep)
@@ -2033,5 +2041,10 @@ cleanup_exit(int i)
{
if (the_authctxt)
do_cleanup(the_authctxt);
+#ifdef SSH_AUDIT_EVENTS
+ /* done after do_cleanup so it can cancel the PAM auth 'thread' */
+ if (!use_privsep || mm_is_monitor())
+ audit_event(SSH_CONNECTION_ABANDON);
+#endif
_exit(i);
}
diff --git a/crypto/openssh/sshd_config b/crypto/openssh/sshd_config
index 980da4b406ce..140576b5f824 100644
--- a/crypto/openssh/sshd_config
+++ b/crypto/openssh/sshd_config
@@ -1,4 +1,4 @@
-# $OpenBSD: sshd_config,v 1.69 2004/05/23 23:59:53 dtucker Exp $
+# $OpenBSD: sshd_config,v 1.70 2004/12/23 23:11:00 djm Exp $
# $FreeBSD$
# This is the sshd server system-wide configuration file. See
@@ -14,10 +14,11 @@
# Note that some of FreeBSD's defaults differ from OpenBSD's, and
# FreeBSD has a few additional options.
-#VersionAddendum FreeBSD-20041028
+#VersionAddendum FreeBSD-20050605
#Port 22
#Protocol 2
+#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
diff --git a/crypto/openssh/sshd_config.5 b/crypto/openssh/sshd_config.5
index b8bb78e7bf3e..59bca462dcd1 100644
--- a/crypto/openssh/sshd_config.5
+++ b/crypto/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.35 2004/06/26 09:14:40 jmc Exp $
+.\" $OpenBSD: sshd_config.5,v 1.40 2005/03/18 17:05:00 jmc Exp $
.\" $FreeBSD$
.Dd September 25, 1999
.Dt SSHD_CONFIG 5
@@ -84,6 +84,17 @@ Be warned that some environment variables could be used to bypass restricted
user environments.
For this reason, care should be taken in the use of this directive.
The default is not to accept any environment variables.
+.It Cm AddressFamily
+Specifies which address family should be used by
+.Nm sshd .
+Valid arguments are
+.Dq any ,
+.Dq inet
+(use IPv4 only) or
+.Dq inet6
+(use IPv6 only).
+The default is
+.Dq any .
.It Cm AllowGroups
This keyword can be followed by a list of group name patterns, separated
by spaces.
@@ -253,12 +264,15 @@ This prevents other remote hosts from connecting to forwarded ports.
.Cm GatewayPorts
can be used to specify that
.Nm sshd
-should bind remote port forwardings to the wildcard address,
-thus allowing remote hosts to connect to forwarded ports.
-The argument must be
+should allow remote port forwardings to bind to non-loopback addresses, thus
+allowing other hosts to connect.
+The argument may be
+.Dq no
+to force remote port forwardings to be available to the local host only,
.Dq yes
-or
-.Dq no .
+to force remote port forwardings to bind to the wildcard address, or
+.Dq clientspecified
+to allow the client to select the address to which the forwarding is bound.
The default is
.Dq no .
.It Cm GSSAPIAuthentication
@@ -476,7 +490,7 @@ server allows login to accounts with empty password strings.
The default is
.Dq no .
.It Cm PermitRootLogin
-Specifies whether root can login using
+Specifies whether root can log in using
.Xr ssh 1 .
The argument must be
.Dq yes ,
@@ -496,9 +510,7 @@ the root user may be allowed in with its password even if
.Pp
If this option is set to
.Dq without-password
-password authentication is disabled for root. Note that other authentication
-methods (e.g., keyboard-interactive/PAM) may still allow root to login using
-a password.
+password authentication is disabled for root.
.Pp
If this option is set to
.Dq forced-commands-only
@@ -512,7 +524,7 @@ All other authentication methods are disabled for root.
.Pp
If this option is set to
.Dq no
-root is not allowed to login.
+root is not allowed to log in.
.It Cm PermitUserEnvironment
Specifies whether
.Pa ~/.ssh/environment
@@ -544,7 +556,8 @@ See also
.It Cm PrintLastLog
Specifies whether
.Nm sshd
-should print the date and time when the user last logged in.
+should print the date and time of the last user login when a user logs
+in interactively.
The default is
.Dq yes .
.It Cm PrintMotd
@@ -647,7 +660,7 @@ To disable TCP keepalive messages, the value should be set to
.It Cm UseDNS
Specifies whether
.Nm sshd
-should lookup the remote host name and check that
+should look up the remote host name and check that
the resolved host name for the remote IP address maps back to the
very same IP address.
The default is
@@ -707,7 +720,7 @@ The default is
Specifies a string to append to the regular version string to identify
OS- or site-specific modifications.
The default is
-.Dq FreeBSD-20041028 .
+.Dq FreeBSD-20050605 .
.It Cm X11DisplayOffset
Specifies the first display number available for
.Nm sshd Ns 's
diff --git a/crypto/openssh/version.h b/crypto/openssh/version.h
index 45f66be44473..5abce508b072 100644
--- a/crypto/openssh/version.h
+++ b/crypto/openssh/version.h
@@ -1,10 +1,11 @@
-/* $OpenBSD: version.h,v 1.42 2004/08/16 08:17:01 markus Exp $ */
+/* $OpenBSD: version.h,v 1.44 2005/03/16 21:17:39 markus Exp $ */
/* $FreeBSD$ */
#ifndef SSH_VERSION
#define SSH_VERSION (ssh_version_get())
-#define SSH_VERSION_BASE "OpenSSH_3.9p1"
+#define SSH_RELEASE (ssh_version_get())
+#define SSH_VERSION_BASE "OpenSSH_4.1p1"
#define SSH_VERSION_ADDENDUM "FreeBSD-20041028"
const char *ssh_version_get(void);