Resolve conflicts.

This commit is contained in:
des 2005-06-05 15:46:09 +00:00
parent 3c5bc6b274
commit 983ad11a1c
52 changed files with 2437 additions and 1075 deletions

View File

@ -97,7 +97,7 @@ OpenSSH contains no GPL code.
* <http://www.core-sdi.com> * <http://www.core-sdi.com>
3) 3)
ssh-keygen was contributed by David Mazieres under a BSD-style ssh-keyscan was contributed by David Mazieres under a BSD-style
license. license.
* Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
@ -203,6 +203,7 @@ OpenSSH contains no GPL code.
Wayne Schroeder Wayne Schroeder
William Jones William Jones
Darren Tucker Darren Tucker
Sun Microsystems
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * 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 $

View File

@ -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$ */ /* $FreeBSD$ */
/* /*
@ -53,9 +53,6 @@
#undef SPT_TYPE #undef SPT_TYPE
#undef SPT_PADCHAR #undef SPT_PADCHAR
/* setgroups() NOOP allowed */
#undef SETGROUPS_NOOP
/* SCO workaround */ /* SCO workaround */
#undef BROKEN_SYS_TERMIO_H #undef BROKEN_SYS_TERMIO_H

View File

@ -29,11 +29,13 @@ RCSID("$FreeBSD$");
#include "auth.h" #include "auth.h"
#include "log.h" #include "log.h"
#include "xmalloc.h" #include "xmalloc.h"
#include "servconf.h"
/* limited protocol v1 interface to kbd-interactive authentication */ /* limited protocol v1 interface to kbd-interactive authentication */
extern KbdintDevice *devices[]; extern KbdintDevice *devices[];
static KbdintDevice *device; static KbdintDevice *device;
extern ServerOptions options;
char * char *
get_challenge(Authctxt *authctxt) get_challenge(Authctxt *authctxt)
@ -42,6 +44,11 @@ get_challenge(Authctxt *authctxt)
u_int i, numprompts; u_int i, numprompts;
u_int *echo_on; 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 */ device = devices[0]; /* we always use the 1st device for protocol 1 */
if (device == NULL) if (device == NULL)
return NULL; return NULL;

View File

@ -188,6 +188,11 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
snprintf(authctxt->krb5_ccname, len, "FILE:%s", snprintf(authctxt->krb5_ccname, len, "FILE:%s",
authctxt->krb5_ticket_file); authctxt->krb5_ticket_file);
#ifdef USE_PAM
if (options.use_pam)
do_pam_putenv("KRB5CCNAME", authctxt->krb5_ccname);
#endif
out: out:
restore_uid(); restore_uid();

View File

@ -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 $ */ /* Based on $xFreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */
#include "includes.h" #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$"); RCSID("$FreeBSD$");
#ifdef USE_PAM #ifdef USE_PAM
@ -77,7 +77,17 @@ extern Buffer loginmsg;
extern int compat20; extern int compat20;
extern u_int utmp_len; extern u_int utmp_len;
/* so we don't silently change behaviour */
#ifdef USE_POSIX_THREADS #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> #include <pthread.h>
/* /*
* Avoid namespace clash when *not* using pthreads for systems *with* * Avoid namespace clash when *not* using pthreads for systems *with*
@ -99,7 +109,7 @@ struct pam_ctxt {
static void sshpam_free_ctx(void *); static void sshpam_free_ctx(void *);
static struct pam_ctxt *cleanup_ctxt; static struct pam_ctxt *cleanup_ctxt;
#ifndef USE_POSIX_THREADS #ifndef UNSUPPORTED_POSIX_THREADS_HACK
/* /*
* Simulate threads with processes. * Simulate threads with processes.
*/ */
@ -187,6 +197,7 @@ static int sshpam_account_status = -1;
static char **sshpam_env = NULL; static char **sshpam_env = NULL;
static Authctxt *sshpam_authctxt = NULL; static Authctxt *sshpam_authctxt = NULL;
static const char *sshpam_password = NULL; static const char *sshpam_password = NULL;
static char badpw[] = "\b\n\r\177INCORRECT";
/* Some PAM implementations don't implement this */ /* Some PAM implementations don't implement this */
#ifndef HAVE_PAM_GETENVLIST #ifndef HAVE_PAM_GETENVLIST
@ -255,7 +266,7 @@ import_environments(Buffer *b)
debug3("PAM: %s entering", __func__); debug3("PAM: %s entering", __func__);
#ifndef USE_POSIX_THREADS #ifndef UNSUPPORTED_POSIX_THREADS_HACK
/* Import variables set by do_pam_account */ /* Import variables set by do_pam_account */
sshpam_account_status = buffer_get_int(b); sshpam_account_status = buffer_get_int(b);
sshpam_password_change_required(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; struct pam_conv sshpam_conv;
int flags = (options.permit_empty_passwd == 0 ? int flags = (options.permit_empty_passwd == 0 ?
PAM_DISALLOW_NULL_AUTHTOK : 0); PAM_DISALLOW_NULL_AUTHTOK : 0);
#ifndef USE_POSIX_THREADS #ifndef UNSUPPORTED_POSIX_THREADS_HACK
extern char **environ; extern char **environ;
char **env_from_pam; char **env_from_pam;
u_int i; u_int i;
@ -428,7 +439,7 @@ sshpam_thread(void *ctxtp)
buffer_put_cstring(&buffer, "OK"); buffer_put_cstring(&buffer, "OK");
#ifndef USE_POSIX_THREADS #ifndef UNSUPPORTED_POSIX_THREADS_HACK
/* Export variables set by do_pam_account */ /* Export variables set by do_pam_account */
buffer_put_int(&buffer, sshpam_account_status); buffer_put_int(&buffer, sshpam_account_status);
buffer_put_int(&buffer, sshpam_authctxt->force_pwchange); buffer_put_int(&buffer, sshpam_authctxt->force_pwchange);
@ -447,7 +458,7 @@ sshpam_thread(void *ctxtp)
buffer_put_int(&buffer, i); buffer_put_int(&buffer, i);
for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++) for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++)
buffer_put_cstring(&buffer, env_from_pam[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 */ /* XXX - can't do much about an error here */
ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer); 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 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 void
sshpam_cleanup(void) sshpam_cleanup(void)
{ {
@ -528,7 +584,7 @@ sshpam_init(Authctxt *authctxt)
} }
debug("PAM: initializing for \"%s\"", user); debug("PAM: initializing for \"%s\"", user);
sshpam_err = 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; sshpam_authctxt = authctxt;
if (sshpam_err != PAM_SUCCESS) { if (sshpam_err != PAM_SUCCESS) {
@ -610,7 +666,7 @@ sshpam_query(void *ctx, char **name, char **info,
size_t plen; size_t plen;
u_char type; u_char type;
char *msg; char *msg;
size_t len; size_t len, mlen;
debug3("PAM: %s entering", __func__); debug3("PAM: %s entering", __func__);
buffer_init(&buffer); buffer_init(&buffer);
@ -623,22 +679,27 @@ sshpam_query(void *ctx, char **name, char **info,
while (ssh_msg_recv(ctxt->pam_psock, &buffer) == 0) { while (ssh_msg_recv(ctxt->pam_psock, &buffer) == 0) {
type = buffer_get_char(&buffer); type = buffer_get_char(&buffer);
msg = buffer_get_string(&buffer, NULL); msg = buffer_get_string(&buffer, NULL);
mlen = strlen(msg);
switch (type) { switch (type) {
case PAM_PROMPT_ECHO_ON: case PAM_PROMPT_ECHO_ON:
case PAM_PROMPT_ECHO_OFF: case PAM_PROMPT_ECHO_OFF:
*num = 1; *num = 1;
len = plen + strlen(msg) + 1; len = plen + mlen + 1;
**prompts = xrealloc(**prompts, len); **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); **echo_on = (type == PAM_PROMPT_ECHO_ON);
xfree(msg); xfree(msg);
return (0); return (0);
case PAM_ERROR_MSG: case PAM_ERROR_MSG:
case PAM_TEXT_INFO: case PAM_TEXT_INFO:
/* accumulate messages */ /* accumulate messages */
len = plen + strlen(msg) + 2; len = plen + mlen + 2;
**prompts = xrealloc(**prompts, len); **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); xfree(msg);
break; break;
case PAM_SUCCESS: case PAM_SUCCESS:
@ -652,6 +713,12 @@ sshpam_query(void *ctx, char **name, char **info,
**prompts = NULL; **prompts = NULL;
} }
if (type == PAM_SUCCESS) { 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); import_environments(&buffer);
*num = 0; *num = 0;
**echo_on = 0; **echo_on = 0;
@ -697,7 +764,12 @@ sshpam_respond(void *ctx, u_int num, char **resp)
return (-1); return (-1);
} }
buffer_init(&buffer); 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) { if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer) == -1) {
buffer_free(&buffer); buffer_free(&buffer);
return (-1); return (-1);
@ -760,11 +832,13 @@ finish_pam(void)
u_int u_int
do_pam_account(void) do_pam_account(void)
{ {
debug("%s: called", __func__);
if (sshpam_account_status != -1) if (sshpam_account_status != -1)
return (sshpam_account_status); return (sshpam_account_status);
sshpam_err = pam_acct_mgmt(sshpam_handle, 0); 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) { if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) {
sshpam_account_status = 0; sshpam_account_status = 0;
@ -794,7 +868,7 @@ void
do_pam_setcred(int init) do_pam_setcred(int init)
{ {
sshpam_err = pam_set_item(sshpam_handle, PAM_CONV, sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
(const void *)&null_conv); (const void *)&store_conv);
if (sshpam_err != PAM_SUCCESS) if (sshpam_err != PAM_SUCCESS)
fatal("PAM: failed to set PAM_CONV: %s", fatal("PAM: failed to set PAM_CONV: %s",
pam_strerror(sshpam_handle, sshpam_err)); pam_strerror(sshpam_handle, sshpam_err));
@ -895,51 +969,6 @@ do_pam_chauthtok(void)
pam_strerror(sshpam_handle, sshpam_err)); 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 void
do_pam_session(void) do_pam_session(void)
{ {
@ -950,10 +979,21 @@ do_pam_session(void)
fatal("PAM: failed to set PAM_CONV: %s", fatal("PAM: failed to set PAM_CONV: %s",
pam_strerror(sshpam_handle, sshpam_err)); pam_strerror(sshpam_handle, sshpam_err));
sshpam_err = pam_open_session(sshpam_handle, 0); sshpam_err = pam_open_session(sshpam_handle, 0);
if (sshpam_err != PAM_SUCCESS) if (sshpam_err == PAM_SUCCESS)
fatal("PAM: pam_open_session(): %s", sshpam_session_open = 1;
else {
sshpam_session_open = 0;
disable_forwarding();
error("PAM: pam_open_session(): %s",
pam_strerror(sshpam_handle, sshpam_err)); 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 ? int flags = (options.permit_empty_passwd == 0 ?
PAM_DISALLOW_NULL_AUTHTOK : 0); PAM_DISALLOW_NULL_AUTHTOK : 0);
static char badpw[] = "\b\n\r\177INCORRECT";
if (!options.use_pam || sshpam_handle == NULL) if (!options.use_pam || sshpam_handle == NULL)
fatal("PAM: %s called when PAM disabled or failed to " fatal("PAM: %s called when PAM disabled or failed to "

View File

@ -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$ */ /* $FreeBSD$ */
/* /*
@ -46,5 +46,6 @@ void free_pam_environment(char **);
void sshpam_thread_cleanup(void); void sshpam_thread_cleanup(void);
void sshpam_cleanup(void); void sshpam_cleanup(void);
int sshpam_auth_passwd(Authctxt *, const char *); int sshpam_auth_passwd(Authctxt *, const char *);
int is_pam_session_open(void);
#endif /* USE_PAM */ #endif /* USE_PAM */

View File

@ -36,17 +36,26 @@
*/ */
#include "includes.h" #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$"); RCSID("$FreeBSD$");
#include "packet.h" #include "packet.h"
#include "buffer.h"
#include "log.h" #include "log.h"
#include "servconf.h" #include "servconf.h"
#include "auth.h" #include "auth.h"
#include "auth-options.h" #include "auth-options.h"
extern Buffer loginmsg;
extern ServerOptions options; 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 void
disable_forwarding(void) disable_forwarding(void)
@ -64,7 +73,7 @@ int
auth_password(Authctxt *authctxt, const char *password) auth_password(Authctxt *authctxt, const char *password)
{ {
struct passwd * pw = authctxt->pw; struct passwd * pw = authctxt->pw;
int ok = authctxt->valid; int result, ok = authctxt->valid;
#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE) #if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
static int expire_checked = 0; static int expire_checked = 0;
#endif #endif
@ -101,22 +110,57 @@ auth_password(Authctxt *authctxt, const char *password)
#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE) #if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
if (!expire_checked) { if (!expire_checked) {
expire_checked = 1; expire_checked = 1;
if (auth_shadow_pwexpired(authctxt)) { if (auth_shadow_pwexpired(authctxt))
disable_forwarding();
authctxt->force_pwchange = 1; authctxt->force_pwchange = 1;
}
} }
#endif #endif
result = sys_auth_passwd(authctxt, password);
return (sys_auth_passwd(authctxt, password) && ok); if (authctxt->force_pwchange)
disable_forwarding();
return (result && ok);
} }
#ifdef BSD_AUTH #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 int
sys_auth_passwd(Authctxt *authctxt, const char *password) sys_auth_passwd(Authctxt *authctxt, const char *password)
{ {
struct passwd *pw = authctxt->pw; struct passwd *pw = authctxt->pw;
auth_session_t *as; auth_session_t *as;
static int expire_checked = 0;
as = auth_usercheck(pw->pw_name, authctxt->style, "auth-ssh", as = auth_usercheck(pw->pw_name, authctxt->style, "auth-ssh",
(char *)password); (char *)password);
@ -126,6 +170,10 @@ sys_auth_passwd(Authctxt *authctxt, const char *password)
authctxt->force_pwchange = 1; authctxt->force_pwchange = 1;
return (1); return (1);
} else { } else {
if (!expire_checked) {
expire_checked = 1;
warn_expiry(authctxt, as);
}
return (auth_close(as)); return (auth_close(as));
} }
} }

View File

@ -14,7 +14,7 @@
*/ */
#include "includes.h" #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/rsa.h>
#include <openssl/md5.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 "hostfile.h"
#include "monitor_wrap.h" #include "monitor_wrap.h"
#include "ssh.h" #include "ssh.h"
#include "misc.h"
/* import */ /* import */
extern ServerOptions options; extern ServerOptions options;
@ -49,7 +50,7 @@ extern u_char session_id[16];
* options bits e n comment * options bits e n comment
* where bits, e and n are decimal numbers, * where bits, e and n are decimal numbers,
* and comment is any string of characters up to newline. The maximum * 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. * description of the options.
*/ */
@ -152,7 +153,7 @@ auth_rsa_challenge_dialog(Key *key)
int int
auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) 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; int allowed = 0;
u_int bits; u_int bits;
FILE *f; 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 * found, perform a challenge-response dialog to verify that the
* user really has the corresponding private key. * 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 *cp;
char *key_options; char *key_options;
linenum++;
/* Skip leading whitespace, empty and comment lines. */ /* Skip leading whitespace, empty and comment lines. */
for (cp = line; *cp == ' ' || *cp == '\t'; cp++) for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
; ;

View File

@ -23,7 +23,7 @@
*/ */
#include "includes.h" #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$"); RCSID("$FreeBSD$");
#ifdef HAVE_LOGIN_H #ifdef HAVE_LOGIN_H
@ -51,6 +51,8 @@ RCSID("$FreeBSD$");
#include "misc.h" #include "misc.h"
#include "bufaux.h" #include "bufaux.h"
#include "packet.h" #include "packet.h"
#include "loginrec.h"
#include "monitor_wrap.h"
/* import */ /* import */
extern ServerOptions options; extern ServerOptions options;
@ -144,7 +146,8 @@ allowed_user(struct passwd * pw)
return 0; 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); hostname = get_canonical_hostname(options.use_dns);
ipaddr = get_remote_ipaddr(); ipaddr = get_remote_ipaddr();
} }
@ -154,8 +157,9 @@ allowed_user(struct passwd * pw)
for (i = 0; i < options.num_deny_users; i++) for (i = 0; i < options.num_deny_users; i++)
if (match_user(pw->pw_name, hostname, ipaddr, if (match_user(pw->pw_name, hostname, ipaddr,
options.deny_users[i])) { options.deny_users[i])) {
logit("User %.100s not allowed because listed in DenyUsers", logit("User %.100s from %.100s not allowed "
pw->pw_name); "because listed in DenyUsers",
pw->pw_name, hostname);
return 0; return 0;
} }
} }
@ -167,16 +171,16 @@ allowed_user(struct passwd * pw)
break; break;
/* i < options.num_allow_users iff we break for loop */ /* i < options.num_allow_users iff we break for loop */
if (i >= options.num_allow_users) { if (i >= options.num_allow_users) {
logit("User %.100s not allowed because not listed in AllowUsers", logit("User %.100s from %.100s not allowed because "
pw->pw_name); "not listed in AllowUsers", pw->pw_name, hostname);
return 0; return 0;
} }
} }
if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { if (options.num_deny_groups > 0 || options.num_allow_groups > 0) {
/* Get the user's group access list (primary and supplementary) */ /* Get the user's group access list (primary and supplementary) */
if (ga_init(pw->pw_name, pw->pw_gid) == 0) { if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
logit("User %.100s not allowed because not in any group", logit("User %.100s from %.100s not allowed because "
pw->pw_name); "not in any group", pw->pw_name, hostname);
return 0; return 0;
} }
@ -185,8 +189,9 @@ allowed_user(struct passwd * pw)
if (ga_match(options.deny_groups, if (ga_match(options.deny_groups,
options.num_deny_groups)) { options.num_deny_groups)) {
ga_free(); ga_free();
logit("User %.100s not allowed because a group is listed in DenyGroups", logit("User %.100s from %.100s not allowed "
pw->pw_name); "because a group is listed in DenyGroups",
pw->pw_name, hostname);
return 0; return 0;
} }
/* /*
@ -197,15 +202,16 @@ allowed_user(struct passwd * pw)
if (!ga_match(options.allow_groups, if (!ga_match(options.allow_groups,
options.num_allow_groups)) { options.num_allow_groups)) {
ga_free(); ga_free();
logit("User %.100s not allowed because none of user's groups are listed in AllowGroups", logit("User %.100s from %.100s not allowed "
pw->pw_name); "because none of user's groups are listed "
"in AllowGroups", pw->pw_name, hostname);
return 0; return 0;
} }
ga_free(); ga_free();
} }
#ifdef CUSTOM_SYS_AUTH_ALLOWED_USER #ifdef CUSTOM_SYS_AUTH_ALLOWED_USER
if (!sys_auth_allowed_user(pw)) if (!sys_auth_allowed_user(pw, &loginmsg))
return 0; return 0;
#endif #endif
@ -241,8 +247,50 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
info); info);
#ifdef CUSTOM_FAILED_LOGIN #ifdef CUSTOM_FAILED_LOGIN
if (authenticated == 0 && strcmp(method, "password") == 0) if (authenticated == 0 && !authctxt->postponed &&
record_failed_login(authctxt->user, "ssh"); (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 #endif
} }
@ -466,8 +514,12 @@ getpwnamallow(const char *user)
logit("Invalid user %.100s from %.100s", logit("Invalid user %.100s from %.100s",
user, get_remote_ipaddr()); user, get_remote_ipaddr());
#ifdef CUSTOM_FAILED_LOGIN #ifdef CUSTOM_FAILED_LOGIN
record_failed_login(user, "ssh"); record_failed_login(user,
get_canonical_hostname(options.use_dns), "ssh");
#endif #endif
#ifdef SSH_AUDIT_EVENTS
audit_event(SSH_INVALID_USER);
#endif /* SSH_AUDIT_EVENTS */
return (NULL); return (NULL);
} }
if (!allowed_user(pw)) if (!allowed_user(pw))

View File

@ -31,6 +31,7 @@
#include "key.h" #include "key.h"
#include "hostfile.h" #include "hostfile.h"
#include "buffer.h"
#include <openssl/rsa.h> #include <openssl/rsa.h>
#ifdef HAVE_LOGIN_CAP #ifdef HAVE_LOGIN_CAP
@ -69,6 +70,7 @@ struct Authctxt {
char *krb5_ticket_file; char *krb5_ticket_file;
char *krb5_ccname; char *krb5_ccname;
#endif #endif
Buffer *loginmsg;
void *methoddata; void *methoddata;
}; };
/* /*
@ -131,6 +133,9 @@ int auth_shadow_pwexpired(Authctxt *);
#endif #endif
#include "auth-pam.h" #include "auth-pam.h"
#include "audit.h"
void remove_kbdint_device(const char *);
void disable_forwarding(void); void disable_forwarding(void);
void do_authentication(Authctxt *); void do_authentication(Authctxt *);
@ -138,6 +143,7 @@ void do_authentication2(Authctxt *);
void auth_log(Authctxt *, int, char *, char *); void auth_log(Authctxt *, int, char *, char *);
void userauth_finish(Authctxt *, int, char *); void userauth_finish(Authctxt *, int, char *);
void userauth_send_banner(const char *);
int auth_root_allowed(char *); int auth_root_allowed(char *);
char *auth2_read_banner(void); char *auth2_read_banner(void);
@ -182,6 +188,8 @@ void auth_debug_reset(void);
struct passwd *fakepw(void); struct passwd *fakepw(void);
int sys_auth_passwd(Authctxt *, const char *);
#define AUTH_FAIL_MSG "Too many authentication failures for %.100s" #define AUTH_FAIL_MSG "Too many authentication failures for %.100s"
#ifdef SKEY #ifdef SKEY

View File

@ -26,9 +26,11 @@ RCSID("$FreeBSD$");
#include "session.h" #include "session.h"
#include "uidswap.h" #include "uidswap.h"
#include "monitor_wrap.h" #include "monitor_wrap.h"
#include "buffer.h"
/* import */ /* import */
extern ServerOptions options; extern ServerOptions options;
extern Buffer loginmsg;
/* /*
* convert ssh auth msg type into description * convert ssh auth msg type into description
@ -246,14 +248,33 @@ do_authloop(Authctxt *authctxt)
#else #else
/* Special handling for root */ /* Special handling for root */
if (authenticated && authctxt->pw->pw_uid == 0 && if (authenticated && authctxt->pw->pw_uid == 0 &&
!auth_root_allowed(get_authname(type))) !auth_root_allowed(get_authname(type))) {
authenticated = 0; authenticated = 0;
# ifdef SSH_AUDIT_EVENTS
PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED));
# endif
}
#endif #endif
#ifdef USE_PAM #ifdef USE_PAM
if (options.use_pam && authenticated && if (options.use_pam && authenticated &&
!PRIVSEP(do_pam_account())) !PRIVSEP(do_pam_account())) {
authenticated = 0; 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 #endif
/* Log before sending the reply */ /* Log before sending the reply */
@ -267,8 +288,12 @@ do_authloop(Authctxt *authctxt)
if (authenticated) if (authenticated)
return; 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_disconnect(AUTH_FAIL_MSG, authctxt->user);
}
packet_start(SSH_SMSG_FAILURE); packet_start(SSH_SMSG_FAILURE);
packet_send(); packet_send();

View File

@ -23,7 +23,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "includes.h" #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$"); RCSID("$FreeBSD$");
#include "ssh2.h" #include "ssh2.h"
@ -33,6 +33,10 @@ RCSID("$FreeBSD$");
#include "xmalloc.h" #include "xmalloc.h"
#include "dispatch.h" #include "dispatch.h"
#include "log.h" #include "log.h"
#include "servconf.h"
/* import */
extern ServerOptions options;
static int auth2_challenge_start(Authctxt *); static int auth2_challenge_start(Authctxt *);
static int send_userauth_info_request(Authctxt *); static int send_userauth_info_request(Authctxt *);
@ -72,6 +76,21 @@ struct KbdintAuthctxt
u_int nreq; 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 * static KbdintAuthctxt *
kbdint_alloc(const char *devs) kbdint_alloc(const char *devs)
{ {
@ -79,6 +98,11 @@ kbdint_alloc(const char *devs)
Buffer b; Buffer b;
int i; int i;
#ifdef USE_PAM
if (!options.use_pam)
remove_kbdint_device("pam");
#endif
kbdintctxt = xmalloc(sizeof(KbdintAuthctxt)); kbdintctxt = xmalloc(sizeof(KbdintAuthctxt));
if (strcmp(devs, "") == 0) { if (strcmp(devs, "") == 0) {
buffer_init(&b); buffer_init(&b);
@ -275,12 +299,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
} }
packet_check_eom(); packet_check_eom();
if (authctxt->valid) { res = kbdintctxt->device->respond(kbdintctxt->ctxt, nresp, response);
res = kbdintctxt->device->respond(kbdintctxt->ctxt,
nresp, response);
} else {
res = -1;
}
for (i = 0; i < nresp; i++) { for (i = 0; i < nresp; i++) {
memset(response[i], 'r', strlen(response[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) { switch (res) {
case 0: case 0:
/* Success! */ /* Success! */
authenticated = 1; authenticated = authctxt->valid ? 1 : 0;
break; break;
case 1: case 1:
/* Authentication needs further interaction */ /* Authentication needs further interaction */

View File

@ -54,7 +54,7 @@ userauth_kbdint(Authctxt *authctxt)
xfree(lang); xfree(lang);
#ifdef HAVE_CYGWIN #ifdef HAVE_CYGWIN
if (check_nt_auth(0, authctxt->pw) == 0) if (check_nt_auth(0, authctxt->pw) == 0)
return(0); authenticated = 0;
#endif #endif
return authenticated; return authenticated;
} }

View File

@ -37,6 +37,7 @@ RCSID("$FreeBSD$");
#include "dispatch.h" #include "dispatch.h"
#include "pathnames.h" #include "pathnames.h"
#include "monitor_wrap.h" #include "monitor_wrap.h"
#include "buffer.h"
#ifdef GSSAPI #ifdef GSSAPI
#include "ssh-gss.h" #include "ssh-gss.h"
@ -46,6 +47,7 @@ RCSID("$FreeBSD$");
extern ServerOptions options; extern ServerOptions options;
extern u_char *session_id2; extern u_char *session_id2;
extern u_int session_id2_len; extern u_int session_id2_len;
extern Buffer loginmsg;
/* methods */ /* methods */
@ -173,6 +175,9 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt)
#ifdef USE_PAM #ifdef USE_PAM
if (options.use_pam) if (options.use_pam)
PRIVSEP(start_pam(authctxt)); PRIVSEP(start_pam(authctxt));
#endif
#ifdef SSH_AUDIT_EVENTS
PRIVSEP(audit_event(SSH_INVALID_USER));
#endif #endif
} }
setproctitle("%s%s", authctxt->valid ? user : "unknown", setproctitle("%s%s", authctxt->valid ? user : "unknown",
@ -242,12 +247,26 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
/* Special handling for root */ /* Special handling for root */
if (authenticated && authctxt->pw->pw_uid == 0 && if (authenticated && authctxt->pw->pw_uid == 0 &&
!auth_root_allowed(method)) !auth_root_allowed(method)) {
authenticated = 0; authenticated = 0;
#ifdef SSH_AUDIT_EVENTS
PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED));
#endif
}
#ifdef USE_PAM #ifdef USE_PAM
if (options.use_pam && authenticated && !PRIVSEP(do_pam_account())) if (options.use_pam && authenticated) {
authenticated = 0; 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 #endif
#ifdef _UNICOS #ifdef _UNICOS
@ -273,8 +292,12 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
/* now we can break out */ /* now we can break out */
authctxt->success = 1; authctxt->success = 1;
} else { } 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); packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
}
methods = authmethods_get(); methods = authmethods_get();
packet_start(SSH2_MSG_USERAUTH_FAILURE); packet_start(SSH2_MSG_USERAUTH_FAILURE);
packet_put_cstring(methods); packet_put_cstring(methods);

View File

@ -36,7 +36,7 @@
*/ */
#include "includes.h" #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/err.h>
#include <openssl/evp.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 "log.h"
#include "authfile.h" #include "authfile.h"
#include "rsa.h" #include "rsa.h"
#include "misc.h"
/* Version identification string for SSH v1 identity files. */ /* Version identification string for SSH v1 identity files. */
static const char authfile_id_string[] = static const char authfile_id_string[] =
@ -243,8 +244,10 @@ key_load_public_rsa1(int fd, const char *filename, char **commentp)
filename, strerror(errno)); filename, strerror(errno));
return NULL; return NULL;
} }
if (st.st_size > 1*1024*1024) if (st.st_size > 1*1024*1024) {
close(fd); error("key file %.200s too large", filename);
return NULL;
}
len = (size_t)st.st_size; /* truncated */ len = (size_t)st.st_size; /* truncated */
buffer_init(&buffer); buffer_init(&buffer);
@ -335,6 +338,7 @@ key_load_private_rsa1(int fd, const char *filename, const char *passphrase,
return NULL; return NULL;
} }
if (st.st_size > 1*1024*1024) { if (st.st_size > 1*1024*1024) {
error("key file %.200s too large", filename);
close(fd); close(fd);
return (NULL); return (NULL);
} }
@ -598,13 +602,14 @@ static int
key_try_load_public(Key *k, const char *filename, char **commentp) key_try_load_public(Key *k, const char *filename, char **commentp)
{ {
FILE *f; FILE *f;
char line[4096]; char line[SSH_MAX_PUBKEY_BYTES];
char *cp; char *cp;
u_long linenum = 0;
f = fopen(filename, "r"); f = fopen(filename, "r");
if (f != NULL) { if (f != NULL) {
while (fgets(line, sizeof(line), f)) { while (read_keyfile_line(f, filename, line, sizeof(line),
line[sizeof(line)-1] = '\0'; &linenum) != -1) {
cp = line; cp = line;
switch (*cp) { switch (*cp) {
case '#': case '#':

View File

@ -37,7 +37,7 @@
*/ */
#include "includes.h" #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$"); RCSID("$FreeBSD$");
#include <openssl/bn.h> #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 * 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. * by (bits+7)/8 bytes of binary data, msb first.
*/ */
void int
buffer_put_bignum(Buffer *buffer, const BIGNUM *value) buffer_put_bignum_ret(Buffer *buffer, const BIGNUM *value)
{ {
int bits = BN_num_bits(value); int bits = BN_num_bits(value);
int bin_size = (bits + 7) / 8; int bin_size = (bits + 7) / 8;
@ -61,9 +61,11 @@ buffer_put_bignum(Buffer *buffer, const BIGNUM *value)
/* Get the value of in binary */ /* Get the value of in binary */
oi = BN_bn2bin(value, buf); oi = BN_bn2bin(value, buf);
if (oi != bin_size) if (oi != bin_size) {
fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d", error("buffer_put_bignum_ret: BN_bn2bin() failed: oi %d != bin_size %d",
oi, bin_size); oi, bin_size);
return (-1);
}
/* Store the number of bits in the buffer in two bytes, msb first. */ /* Store the number of bits in the buffer in two bytes, msb first. */
PUT_16BIT(msg, bits); PUT_16BIT(msg, bits);
@ -73,36 +75,63 @@ buffer_put_bignum(Buffer *buffer, const BIGNUM *value)
memset(buf, 0, bin_size); memset(buf, 0, bin_size);
xfree(buf); 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. * Retrieves an BIGNUM from the buffer.
*/ */
void int
buffer_get_bignum(Buffer *buffer, BIGNUM *value) buffer_get_bignum_ret(Buffer *buffer, BIGNUM *value)
{ {
u_int bits, bytes; u_int bits, bytes;
u_char buf[2], *bin; u_char buf[2], *bin;
/* Get the number for bits. */ /* 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); bits = GET_16BIT(buf);
/* Compute the number of binary bytes that follow. */ /* Compute the number of binary bytes that follow. */
bytes = (bits + 7) / 8; bytes = (bits + 7) / 8;
if (bytes > 8 * 1024) if (bytes > 8 * 1024) {
fatal("buffer_get_bignum: cannot handle BN of size %d", bytes); error("buffer_get_bignum_ret: cannot handle BN of size %d", bytes);
if (buffer_len(buffer) < bytes) return (-1);
fatal("buffer_get_bignum: input buffer too small"); }
if (buffer_len(buffer) < bytes) {
error("buffer_get_bignum_ret: input buffer too small");
return (-1);
}
bin = buffer_ptr(buffer); bin = buffer_ptr(buffer);
BN_bin2bn(bin, bytes, value); 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. * Stores an BIGNUM in the buffer in SSH2 format.
*/ */
void int
buffer_put_bignum2(Buffer *buffer, const BIGNUM *value) buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value)
{ {
u_int bytes; u_int bytes;
u_char *buf; u_char *buf;
@ -111,69 +140,140 @@ buffer_put_bignum2(Buffer *buffer, const BIGNUM *value)
if (BN_is_zero(value)) { if (BN_is_zero(value)) {
buffer_put_int(buffer, 0); 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 */ bytes = BN_num_bytes(value) + 1; /* extra padding byte */
if (bytes < 2) if (bytes < 2) {
fatal("buffer_put_bignum2: BN too small"); error("buffer_put_bignum2_ret: BN too small");
return (-1);
}
buf = xmalloc(bytes); buf = xmalloc(bytes);
buf[0] = '\0'; buf[0] = 0x00;
/* Get the value of in binary */ /* Get the value of in binary */
oi = BN_bn2bin(value, buf+1); oi = BN_bn2bin(value, buf+1);
if (oi != bytes-1) if (oi != bytes-1) {
fatal("buffer_put_bignum2: BN_bn2bin() failed: " error("buffer_put_bignum2_ret: BN_bn2bin() failed: "
"oi %d != bin_size %d", oi, bytes); "oi %d != bin_size %d", oi, bytes);
xfree(buf);
return (-1);
}
hasnohigh = (buf[1] & 0x80) ? 0 : 1; hasnohigh = (buf[1] & 0x80) ? 0 : 1;
buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh); buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh);
memset(buf, 0, bytes); memset(buf, 0, bytes);
xfree(buf); xfree(buf);
return (0);
}
void
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;
if ((bin = buffer_get_string_ret(buffer, &len)) == NULL) {
error("buffer_get_bignum2_ret: invalid bignum");
return (-1);
}
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 void
buffer_get_bignum2(Buffer *buffer, BIGNUM *value) buffer_get_bignum2(Buffer *buffer, BIGNUM *value)
{ {
u_int len; if (buffer_get_bignum2_ret(buffer, value) == -1)
u_char *bin = buffer_get_string(buffer, &len); fatal("buffer_get_bignum2: buffer error");
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);
BN_bin2bn(bin, len, value);
xfree(bin);
} }
/* /*
* Returns integers from the buffer (msb first). * Returns integers from the buffer (msb first).
*/ */
u_short int
buffer_get_short(Buffer *buffer) buffer_get_short_ret(u_short *ret, Buffer *buffer)
{ {
u_char buf[2]; u_char buf[2];
buffer_get(buffer, (char *) buf, 2); if (buffer_get_ret(buffer, (char *) buf, 2) == -1)
return GET_16BIT(buf); return (-1);
*ret = GET_16BIT(buf);
return (0);
}
u_short
buffer_get_short(Buffer *buffer)
{
u_short ret;
if (buffer_get_short_ret(&ret, buffer) == -1)
fatal("buffer_get_short: buffer error");
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 u_int
buffer_get_int(Buffer *buffer) buffer_get_int(Buffer *buffer)
{ {
u_char buf[4]; u_int ret;
buffer_get(buffer, (char *) buf, 4); if (buffer_get_int_ret(&ret, buffer) == -1)
return GET_32BIT(buf); fatal("buffer_get_int: buffer error");
return (ret);
}
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 u_int64_t
buffer_get_int64(Buffer *buffer) buffer_get_int64(Buffer *buffer)
{ {
u_char buf[8]; u_int64_t ret;
buffer_get(buffer, (char *) buf, 8); if (buffer_get_int64_ret(&ret, buffer) == -1)
return GET_64BIT(buf); 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. * to the returned string, and is not counted in length.
*/ */
void * void *
buffer_get_string(Buffer *buffer, u_int *length_ptr) buffer_get_string_ret(Buffer *buffer, u_int *length_ptr)
{ {
u_char *value; u_char *value;
u_int len; u_int len;
/* Get the length. */ /* Get the length. */
len = buffer_get_int(buffer); len = buffer_get_int(buffer);
if (len > 256 * 1024) if (len > 256 * 1024) {
fatal("buffer_get_string: bad string length %u", len); error("buffer_get_string_ret: bad string length %u", len);
return (NULL);
}
/* Allocate space for the string. Add one byte for a null character. */ /* Allocate space for the string. Add one byte for a null character. */
value = xmalloc(len + 1); value = xmalloc(len + 1);
/* Get the string. */ /* 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. */ /* Append a null character to make processing easier. */
value[len] = 0; value[len] = 0;
/* Optionally return the length of the string. */ /* Optionally return the length of the string. */
if (length_ptr) if (length_ptr)
*length_ptr = len; *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);
} }
/* /*
@ -256,12 +372,23 @@ buffer_put_cstring(Buffer *buffer, const char *s)
/* /*
* Returns a character from the buffer (0 - 255). * 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 int
buffer_get_char(Buffer *buffer) buffer_get_char(Buffer *buffer)
{ {
char ch; 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; return (u_char) ch;
} }

View File

@ -12,7 +12,7 @@
*/ */
#include "includes.h" #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 "packet.h"
#include "xmalloc.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" #include "canohost.h"
static void check_ip_options(int, char *); 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 * 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 */ #endif /* IP_OPTIONS */
} }
static void void
ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len) ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len)
{ {
struct sockaddr_in6 *a6 = (struct sockaddr_in6 *)addr; 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; struct sockaddr_storage addr;
socklen_t addrlen; socklen_t addrlen;
char ntop[NI_MAXHOST]; char ntop[NI_MAXHOST];
int r;
/* Get IP address of client. */ /* Get IP address of client. */
addrlen = sizeof(addr); addrlen = sizeof(addr);
@ -251,10 +251,13 @@ get_socket_address(int sock, int remote, int flags)
if (addr.ss_family == AF_INET6) if (addr.ss_family == AF_INET6)
addrlen = sizeof(struct sockaddr_in6); addrlen = sizeof(struct sockaddr_in6);
ipv64_normalise_mapped(&addr, &addrlen);
/* Get the address in ascii. */ /* Get the address in ascii. */
if (getnameinfo((struct sockaddr *)&addr, addrlen, ntop, sizeof(ntop), if ((r = getnameinfo((struct sockaddr *)&addr, addrlen, ntop,
NULL, 0, flags) != 0) { sizeof(ntop), NULL, 0, flags)) != 0) {
error("get_socket_address: getnameinfo %d failed", flags); error("get_socket_address: getnameinfo %d failed: %s", flags,
r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r));
return NULL; return NULL;
} }
return xstrdup(ntop); return xstrdup(ntop);
@ -330,6 +333,7 @@ get_sock_port(int sock, int local)
struct sockaddr_storage from; struct sockaddr_storage from;
socklen_t fromlen; socklen_t fromlen;
char strport[NI_MAXSERV]; char strport[NI_MAXSERV];
int r;
/* Get IP address of client. */ /* Get IP address of client. */
fromlen = sizeof(from); fromlen = sizeof(from);
@ -351,9 +355,10 @@ get_sock_port(int sock, int local)
fromlen = sizeof(struct sockaddr_in6); fromlen = sizeof(struct sockaddr_in6);
/* Return port number. */ /* Return port number. */
if (getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0, if ((r = getnameinfo((struct sockaddr *)&from, fromlen, NULL, 0,
strport, sizeof(strport), NI_NUMERICSERV) != 0) strport, sizeof(strport), NI_NUMERICSERV)) != 0)
fatal("get_sock_port: getnameinfo NI_NUMERICSERV failed"); fatal("get_sock_port: getnameinfo NI_NUMERICSERV failed: %s",
r == EAI_SYSTEM ? strerror(errno) : gai_strerror(r));
return atoi(strport); return atoi(strport);
} }

View File

@ -39,7 +39,7 @@
*/ */
#include "includes.h" #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 "ssh.h"
#include "ssh1.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 */ /* -- channel core */
#define CHAN_RBUF 16*1024
/* /*
* Pointer to an array containing all allocated channels. The array is * Pointer to an array containing all allocated channels. The array is
* dynamically extended as needed. * 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(); 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 && if (c->istate == CHAN_INPUT_OPEN &&
limit > 0 && limit > 0 &&
buffer_len(&c->input) < limit) 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); debug2("channel %d: only socks5 connect supported", c->self);
return -1; return -1;
} }
switch(s5_req.atyp){ switch (s5_req.atyp){
case SSH_SOCKS5_IPV4: case SSH_SOCKS5_IPV4:
addrlen = 4; addrlen = 4;
af = AF_INET; af = AF_INET;
@ -1360,7 +1365,7 @@ channel_post_connecting(Channel *c, fd_set * readset, fd_set * writeset)
static int static int
channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset) channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
{ {
char buf[16*1024]; char buf[CHAN_RBUF];
int len; int len;
if (c->rfd != -1 && if (c->rfd != -1 &&
@ -1454,7 +1459,7 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
static int static int
channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset) channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
{ {
char buf[16*1024]; char buf[CHAN_RBUF];
int len; int len;
/** XXX handle drain efd, too */ /** 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) const char *host_to_connect, u_short port_to_connect, int gateway_ports)
{ {
Channel *c; Channel *c;
int success, sock, on = 1; int sock, r, success = 0, on = 1, wildcard = 0, is_client;
struct addrinfo hints, *ai, *aitop; struct addrinfo hints, *ai, *aitop;
const char *host; const char *host, *addr;
char ntop[NI_MAXHOST], strport[NI_MAXSERV]; char ntop[NI_MAXHOST], strport[NI_MAXSERV];
success = 0;
host = (type == SSH_CHANNEL_RPORT_LISTENER) ? host = (type == SSH_CHANNEL_RPORT_LISTENER) ?
listen_addr : host_to_connect; listen_addr : host_to_connect;
is_client = (type == SSH_CHANNEL_PORT_LISTENER);
if (host == NULL) { if (host == NULL) {
error("No forward host name."); error("No forward host name.");
@ -2197,17 +2202,61 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por
return success; return success;
} }
/*
* 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 * getaddrinfo returns a loopback address if the hostname is
* set to NULL and hints.ai_flags is not AI_PASSIVE * set to NULL and hints.ai_flags is not AI_PASSIVE
*/ */
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_family = IPv4or6; hints.ai_family = IPv4or6;
hints.ai_flags = gateway_ports ? AI_PASSIVE : 0; hints.ai_flags = wildcard ? AI_PASSIVE : 0;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
snprintf(strport, sizeof strport, "%d", listen_port); snprintf(strport, sizeof strport, "%d", listen_port);
if (getaddrinfo(NULL, strport, &hints, &aitop) != 0) if ((r = getaddrinfo(addr, strport, &hints, &aitop)) != 0) {
packet_disconnect("getaddrinfo: fatal error"); 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) { for (ai = aitop; ai; ai = ai->ai_next) {
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) 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; u_int i;
int found = 0; int found = 0;
for(i = 0; i < channels_alloc; i++) { for (i = 0; i < channels_alloc; i++) {
Channel *c = channels[i]; Channel *c = channels[i];
if (c != NULL && c->type == SSH_CHANNEL_RPORT_LISTENER && if (c != NULL && c->type == SSH_CHANNEL_RPORT_LISTENER &&
strncmp(c->path, host, sizeof(c->path)) == 0 && strncmp(c->path, host, sizeof(c->path)) == 0 &&
c->listening_port == port) { c->listening_port == port) {
debug2("%s: close clannel %d", __func__, i); debug2("%s: close channel %d", __func__, i);
channel_free(c); channel_free(c);
found = 1; 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) */ /* protocol local port fwd, used by ssh (and sshd in v1) */
int 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) const char *host_to_connect, u_short port_to_connect, int gateway_ports)
{ {
return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER, 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 */ /* protocol v2 remote port fwd, used by sshd */
@ -2312,7 +2362,7 @@ channel_setup_remote_fwd_listener(const char *listen_address,
*/ */
void 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) const char *host_to_connect, u_short port_to_connect)
{ {
int type, success = 0; int type, success = 0;
@ -2323,7 +2373,14 @@ channel_request_remote_forwarding(u_short listen_port,
/* Send the forward request to the remote side. */ /* Send the forward request to the remote side. */
if (compat20) { 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_start(SSH2_MSG_GLOBAL_REQUEST);
packet_put_cstring("tcpip-forward"); packet_put_cstring("tcpip-forward");
packet_put_char(1); /* boolean: want reply */ packet_put_char(1); /* boolean: want reply */
@ -2369,10 +2426,9 @@ channel_request_remote_forwarding(u_short listen_port,
* local side. * local side.
*/ */
void void
channel_request_rforward_cancel(u_short port) channel_request_rforward_cancel(const char *host, u_short port)
{ {
int i; int i;
const char *address_to_bind = "0.0.0.0";
if (!compat20) if (!compat20)
return; return;
@ -2389,7 +2445,7 @@ channel_request_rforward_cancel(u_short port)
packet_start(SSH2_MSG_GLOBAL_REQUEST); packet_start(SSH2_MSG_GLOBAL_REQUEST);
packet_put_cstring("cancel-tcpip-forward"); packet_put_cstring("cancel-tcpip-forward");
packet_put_char(0); packet_put_char(0);
packet_put_cstring(address_to_bind); packet_put_cstring(host == NULL ? "" : host);
packet_put_int(port); packet_put_int(port);
packet_send(); packet_send();
@ -2430,7 +2486,8 @@ channel_input_port_forward_request(int is_root, int gateway_ports)
#endif #endif
/* Initiate forwarding */ /* 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. */ /* Free the argument string. */
xfree(hostname); xfree(hostname);
@ -2577,7 +2634,7 @@ channel_send_window_changes(void)
struct winsize ws; struct winsize ws;
for (i = 0; i < channels_alloc; i++) { 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) channels[i]->type != SSH_CHANNEL_OPEN)
continue; continue;
if (ioctl(channels[i]->rfd, TIOCGWINSZ, &ws) < 0) if (ioctl(channels[i]->rfd, TIOCGWINSZ, &ws) < 0)

View File

@ -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> * Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -79,6 +79,7 @@ struct Channel {
int ctl_fd; /* control fd (client sharing) */ int ctl_fd; /* control fd (client sharing) */
int isatty; /* rfd is a tty */ int isatty; /* rfd is a tty */
int wfd_isatty; /* wfd 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 force_drain; /* force close on iEOF */
int delayed; /* fdset hack */ int delayed; /* fdset hack */
Buffer input; /* data read from socket, to be sent over 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); void channel_input_port_forward_request(int, int);
int channel_connect_to(const char *, u_short); int channel_connect_to(const char *, u_short);
int channel_connect_by_listen_address(u_short); int channel_connect_by_listen_address(u_short);
void channel_request_remote_forwarding(u_short, const char *, u_short); void channel_request_remote_forwarding(const char *, u_short,
void channel_request_rforward_cancel(u_short port); const char *, u_short);
int channel_setup_local_fwd_listener(u_short, const char *, u_short, int); 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_setup_remote_fwd_listener(const char *, u_short, int);
int channel_cancel_rport_listener(const char *, u_short); int channel_cancel_rport_listener(const char *, u_short);

View File

@ -35,7 +35,7 @@
*/ */
#include "includes.h" #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 "xmalloc.h"
#include "log.h" #include "log.h"
@ -146,7 +146,7 @@ cipher_by_name(const char *name)
{ {
Cipher *c; Cipher *c;
for (c = ciphers; c->name != NULL; c++) for (c = ciphers; c->name != NULL; c++)
if (strcasecmp(c->name, name) == 0) if (strcmp(c->name, name) == 0)
return c; return c;
return NULL; return NULL;
} }
@ -199,8 +199,10 @@ cipher_number(const char *name)
Cipher *c; Cipher *c;
if (name == NULL) if (name == NULL)
return -1; return -1;
c = cipher_by_name(name); for (c = ciphers; c->name != NULL; c++)
return (c==NULL) ? -1 : c->number; if (strcasecmp(c->name, name) == 0)
return c->number;
return -1;
} }
char * char *

View File

@ -23,7 +23,7 @@
*/ */
#include "includes.h" #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$"); RCSID("$FreeBSD$");
#include "buffer.h" #include "buffer.h"
@ -63,24 +63,28 @@ compat_datafellows(const char *version)
"OpenSSH_2.1*," "OpenSSH_2.1*,"
"OpenSSH_2.2*", SSH_OLD_SESSIONID|SSH_BUG_BANNER| "OpenSSH_2.2*", SSH_OLD_SESSIONID|SSH_BUG_BANNER|
SSH_OLD_DHGEX|SSH_BUG_NOREKEY| 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| { "OpenSSH_2.3.0*", SSH_BUG_BANNER|SSH_BUG_BIGENDIANAES|
SSH_OLD_DHGEX|SSH_BUG_NOREKEY| 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| { "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.0p1*,"
"OpenSSH_2.5.1p1*", "OpenSSH_2.5.1p1*",
SSH_BUG_BIGENDIANAES|SSH_OLD_DHGEX| 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.0*,"
"OpenSSH_2.5.1*," "OpenSSH_2.5.1*,"
"OpenSSH_2.5.2*", SSH_OLD_DHGEX|SSH_BUG_NOREKEY| "OpenSSH_2.5.2*", SSH_OLD_DHGEX|SSH_BUG_NOREKEY|
SSH_BUG_EXTEOF}, SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR},
{ "OpenSSH_2.5.3*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, { "OpenSSH_2.5.3*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF|
SSH_OLD_FORWARD_ADDR},
{ "OpenSSH_2.*," { "OpenSSH_2.*,"
"OpenSSH_3.0*," "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}, { "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
{ "OpenSSH*", 0 }, { "OpenSSH*", 0 },
{ "*MindTerm*", 0 }, { "*MindTerm*", 0 },

View File

@ -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. * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
@ -55,6 +55,7 @@
#define SSH_BUG_EXTEOF 0x00200000 #define SSH_BUG_EXTEOF 0x00200000
#define SSH_BUG_PROBE 0x00400000 #define SSH_BUG_PROBE 0x00400000
#define SSH_BUG_FIRSTKEX 0x00800000 #define SSH_BUG_FIRSTKEX 0x00800000
#define SSH_OLD_FORWARD_ADDR 0x01000000
void enable_compat13(void); void enable_compat13(void);
void enable_compat20(void); void enable_compat20(void);

File diff suppressed because it is too large Load Diff

View File

@ -36,13 +36,102 @@
*/ */
#include "includes.h" #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 "packet.h"
#include "match.h" #include "match.h"
#include "key.h" #include "key.h"
#include "hostfile.h" #include "hostfile.h"
#include "log.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 * 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]; char line[8192];
int linenum = 0; int linenum = 0;
u_int kbits; u_int kbits;
char *cp, *cp2; char *cp, *cp2, *hashed_host;
HostStatus end_return; HostStatus end_return;
debug3("check_host_in_hostfile: filename %s", filename); 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. */ /* Check if the host name matches. */
if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1) if (match_hostname(host, cp, (u_int) (cp2 - cp)) != 1) {
continue; 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. */ /* Got a match. Skip host name. */
cp = cp2; cp = cp2;
@ -211,16 +310,28 @@ lookup_key_in_hostfile_by_type(const char *filename, const char *host,
*/ */
int 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; FILE *f;
int success = 0; int success = 0;
char *hashed_host;
if (key == NULL) if (key == NULL)
return 1; /* XXX ? */ return 1; /* XXX ? */
f = fopen(filename, "a"); f = fopen(filename, "a");
if (!f) if (!f)
return 0; 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)) { if (key_write(key, f)) {
success = 1; success = 1;
} else { } else {

View File

@ -186,7 +186,7 @@ __RCSID(msg)
* On HP-UX 11.11, shadow.h and prot.h provide conflicting declarations * 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. * of getspnam when _INCLUDE__STDC__ is defined, so we unset it here.
*/ */
#ifdef __hpux #ifdef GETSPNAM_CONFLICTING_DEFS
# ifdef _INCLUDE__STDC__ # ifdef _INCLUDE__STDC__
# undef _INCLUDE__STDC__ # undef _INCLUDE__STDC__
# endif # endif

View File

@ -32,7 +32,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "includes.h" #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> #include <openssl/evp.h>
@ -681,8 +681,8 @@ Key *
key_from_blob(const u_char *blob, u_int blen) key_from_blob(const u_char *blob, u_int blen)
{ {
Buffer b; Buffer b;
char *ktype;
int rlen, type; int rlen, type;
char *ktype = NULL;
Key *key = NULL; Key *key = NULL;
#ifdef DEBUG_PK #ifdef DEBUG_PK
@ -690,24 +690,38 @@ key_from_blob(const u_char *blob, u_int blen)
#endif #endif
buffer_init(&b); buffer_init(&b);
buffer_append(&b, blob, blen); 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); type = key_type_from_name(ktype);
switch (type) { switch (type) {
case KEY_RSA: case KEY_RSA:
key = key_new(type); key = key_new(type);
buffer_get_bignum2(&b, key->rsa->e); if (buffer_get_bignum2_ret(&b, key->rsa->e) == -1 ||
buffer_get_bignum2(&b, key->rsa->n); 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 #ifdef DEBUG_PK
RSA_print_fp(stderr, key->rsa, 8); RSA_print_fp(stderr, key->rsa, 8);
#endif #endif
break; break;
case KEY_DSA: case KEY_DSA:
key = key_new(type); key = key_new(type);
buffer_get_bignum2(&b, key->dsa->p); if (buffer_get_bignum2_ret(&b, key->dsa->p) == -1 ||
buffer_get_bignum2(&b, key->dsa->q); buffer_get_bignum2_ret(&b, key->dsa->q) == -1 ||
buffer_get_bignum2(&b, key->dsa->g); buffer_get_bignum2_ret(&b, key->dsa->g) == -1 ||
buffer_get_bignum2(&b, key->dsa->pub_key); 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 #ifdef DEBUG_PK
DSA_print_fp(stderr, key->dsa, 8); DSA_print_fp(stderr, key->dsa, 8);
#endif #endif
@ -717,12 +731,14 @@ key_from_blob(const u_char *blob, u_int blen)
break; break;
default: default:
error("key_from_blob: cannot handle type %s", ktype); error("key_from_blob: cannot handle type %s", ktype);
break; goto out;
} }
rlen = buffer_len(&b); rlen = buffer_len(&b);
if (key != NULL && rlen != 0) if (key != NULL && rlen != 0)
error("key_from_blob: remaining bytes in key blob %d", rlen); error("key_from_blob: remaining bytes in key blob %d", rlen);
xfree(ktype); out:
if (ktype != NULL)
xfree(ktype);
buffer_free(&b); buffer_free(&b);
return key; return key;
} }

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,7 @@
*/ */
#include "includes.h" #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$"); RCSID("$FreeBSD$");
#include <openssl/dh.h> #include <openssl/dh.h>
@ -152,6 +152,11 @@ int mm_answer_gss_userok(int, Buffer *);
int mm_answer_gss_checkmic(int, Buffer *); int mm_answer_gss_checkmic(int, Buffer *);
#endif #endif
#ifdef SSH_AUDIT_EVENTS
int mm_answer_audit_event(int, Buffer *);
int mm_answer_audit_command(int, Buffer *);
#endif
static Authctxt *authctxt; static Authctxt *authctxt;
static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ 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_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
{MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx}, {MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx},
#endif #endif
#ifdef SSH_AUDIT_EVENTS
{MONITOR_REQ_AUDIT_EVENT, MON_PERMIT, mm_answer_audit_event},
#endif
#ifdef BSD_AUTH #ifdef BSD_AUTH
{MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
{MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond}, {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_PTY, 0, mm_answer_pty},
{MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup}, {MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup},
{MONITOR_REQ_TERM, 0, mm_answer_term}, {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} {0, 0, NULL}
}; };
@ -247,6 +259,9 @@ struct mon_table mon_dispatch_proto15[] = {
{MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
{MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond}, {MONITOR_REQ_PAM_RESPOND, MON_ISAUTH, mm_answer_pam_respond},
{MONITOR_REQ_PAM_FREE_CTX, MON_ONCE|MON_AUTHDECIDE, mm_answer_pam_free_ctx}, {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 #endif
{0, 0, NULL} {0, 0, NULL}
}; };
@ -255,6 +270,10 @@ struct mon_table mon_dispatch_postauth15[] = {
{MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty}, {MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty},
{MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup}, {MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup},
{MONITOR_REQ_TERM, 0, mm_answer_term}, {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} {0, 0, NULL}
}; };
@ -300,6 +319,8 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
authctxt = _authctxt; authctxt = _authctxt;
memset(authctxt, 0, sizeof(*authctxt)); memset(authctxt, 0, sizeof(*authctxt));
authctxt->loginmsg = &loginmsg;
if (compat20) { if (compat20) {
mon_dispatch = mon_dispatch_proto20; mon_dispatch = mon_dispatch_proto20;
@ -618,6 +639,9 @@ mm_answer_pwnamallow(int sock, Buffer *m)
if (options.use_pam) if (options.use_pam)
monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1);
#endif #endif
#ifdef SSH_AUDIT_EVENTS
monitor_permit(mon_dispatch, MONITOR_REQ_AUDIT_COMMAND, 1);
#endif
return (0); return (0);
} }
@ -819,6 +843,9 @@ mm_answer_pam_account(int sock, Buffer *m)
ret = do_pam_account(); ret = do_pam_account();
buffer_put_int(m, ret); 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); 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); debug3("%s: key_from_blob: %p", __func__, key);
if (key != NULL && authctxt->valid) { if (key != NULL && authctxt->valid) {
switch(type) { switch (type) {
case MM_USERKEY: case MM_USERKEY:
allowed = options.pubkey_authentication && allowed = options.pubkey_authentication &&
user_key_allowed(authctxt->pw, key); user_key_allowed(authctxt->pw, key);
@ -1306,7 +1333,7 @@ mm_answer_sesskey(int sock, Buffer *m)
int rsafail; int rsafail;
/* Turn off permissions */ /* Turn off permissions */
monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 0);
if ((p = BN_new()) == NULL) if ((p = BN_new()) == NULL)
fatal("%s: BN_new", __func__); fatal("%s: BN_new", __func__);
@ -1497,6 +1524,48 @@ mm_answer_term(int sock, Buffer *req)
exit(res); 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 void
monitor_apply_keystate(struct monitor *pmonitor) monitor_apply_keystate(struct monitor *pmonitor)
{ {

View File

@ -60,6 +60,7 @@ enum monitor_reqtype {
MONITOR_REQ_PAM_QUERY, MONITOR_ANS_PAM_QUERY, MONITOR_REQ_PAM_QUERY, MONITOR_ANS_PAM_QUERY,
MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND, MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND,
MONITOR_REQ_PAM_FREE_CTX, MONITOR_ANS_PAM_FREE_CTX, MONITOR_REQ_PAM_FREE_CTX, MONITOR_ANS_PAM_FREE_CTX,
MONITOR_REQ_AUDIT_EVENT, MONITOR_REQ_AUDIT_COMMAND,
MONITOR_REQ_TERM MONITOR_REQ_TERM
}; };

View File

@ -73,6 +73,7 @@ extern struct monitor *pmonitor;
extern Buffer input, output; extern Buffer input, output;
extern Buffer loginmsg; extern Buffer loginmsg;
extern ServerOptions options; extern ServerOptions options;
extern Buffer loginmsg;
int int
mm_is_monitor(void) mm_is_monitor(void)
@ -717,6 +718,7 @@ mm_do_pam_account(void)
{ {
Buffer m; Buffer m;
u_int ret; u_int ret;
char *msg;
debug3("%s entering", __func__); debug3("%s entering", __func__);
if (!options.use_pam) if (!options.use_pam)
@ -728,6 +730,9 @@ mm_do_pam_account(void)
mm_request_receive_expect(pmonitor->m_recvfd, mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_PAM_ACCOUNT, &m); MONITOR_ANS_PAM_ACCOUNT, &m);
ret = buffer_get_int(&m); ret = buffer_get_int(&m);
msg = buffer_get_string(&m, NULL);
buffer_append(&loginmsg, msg, strlen(msg));
xfree(msg);
buffer_free(&m); buffer_free(&m);
@ -1099,6 +1104,36 @@ mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16])
return (success); 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 #ifdef GSSAPI
OM_uint32 OM_uint32
mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid) mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid)

View File

@ -75,6 +75,12 @@ int mm_sshpam_respond(void *, u_int, char **);
void mm_sshpam_free_ctx(void *); void mm_sshpam_free_ctx(void *);
#endif #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; struct Session;
void mm_terminate(void); void mm_terminate(void);
int mm_pty_allocate(int *, int *, char *, int); int mm_pty_allocate(int *, int *, char *, int);

View File

@ -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$ */ /* $FreeBSD$ */
/* /*
@ -118,6 +118,7 @@ struct sockaddr_in6 {
# define EAI_NODATA 1 # define EAI_NODATA 1
# define EAI_MEMORY 2 # define EAI_MEMORY 2
# define EAI_NONAME 3 # define EAI_NONAME 3
# define EAI_SYSTEM 4
#endif #endif
#ifndef HAVE_STRUCT_ADDRINFO #ifndef HAVE_STRUCT_ADDRINFO

View File

@ -12,7 +12,7 @@
*/ */
#include "includes.h" #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$"); RCSID("$FreeBSD$");
#include "ssh.h" #include "ssh.h"
@ -107,7 +107,7 @@ typedef enum {
oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
oAddressFamily, oGssAuthentication, oGssDelegateCreds, oAddressFamily, oGssAuthentication, oGssDelegateCreds,
oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
oSendEnv, oControlPath, oControlMaster, oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
oVersionAddendum, oVersionAddendum,
oDeprecated, oUnsupported oDeprecated, oUnsupported
} OpCodes; } OpCodes;
@ -199,6 +199,7 @@ static struct {
{ "sendenv", oSendEnv }, { "sendenv", oSendEnv },
{ "controlpath", oControlPath }, { "controlpath", oControlPath },
{ "controlmaster", oControlMaster }, { "controlmaster", oControlMaster },
{ "hashknownhosts", oHashKnownHosts },
{ "versionaddendum", oVersionAddendum }, { "versionaddendum", oVersionAddendum },
{ NULL, oBadOption } { NULL, oBadOption }
}; };
@ -209,21 +210,23 @@ static struct {
*/ */
void void
add_local_forward(Options *options, u_short port, const char *host, add_local_forward(Options *options, const Forward *newfwd)
u_short host_port)
{ {
Forward *fwd; Forward *fwd;
#ifndef NO_IPPORT_RESERVED_CONCEPT #ifndef NO_IPPORT_RESERVED_CONCEPT
extern uid_t original_real_uid; 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."); fatal("Privileged ports can only be forwarded by root.");
#endif #endif
if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
fatal("Too many local forwards (max %d).", 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 = &options->local_forwards[options->num_local_forwards++];
fwd->port = port;
fwd->host = xstrdup(host); fwd->listen_host = (newfwd->listen_host == NULL) ?
fwd->host_port = host_port; 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 void
add_remote_forward(Options *options, u_short port, const char *host, add_remote_forward(Options *options, const Forward *newfwd)
u_short host_port)
{ {
Forward *fwd; Forward *fwd;
if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
fatal("Too many remote forwards (max %d).", fatal("Too many remote forwards (max %d).",
SSH_MAX_FORWARDS_PER_DIRECTION); SSH_MAX_FORWARDS_PER_DIRECTION);
fwd = &options->remote_forwards[options->num_remote_forwards++]; fwd = &options->remote_forwards[options->num_remote_forwards++];
fwd->port = port;
fwd->host = xstrdup(host); fwd->listen_host = (newfwd->listen_host == NULL) ?
fwd->host_port = host_port; 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 static void
@ -250,11 +255,17 @@ clear_forwardings(Options *options)
{ {
int i; int i;
for (i = 0; i < options->num_local_forwards; i++) for (i = 0; i < options->num_local_forwards; i++) {
xfree(options->local_forwards[i].host); 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; options->num_local_forwards = 0;
for (i = 0; i < options->num_remote_forwards; i++) for (i = 0; i < options->num_remote_forwards; i++) {
xfree(options->remote_forwards[i].host); 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; options->num_remote_forwards = 0;
} }
@ -287,14 +298,13 @@ process_config_line(Options *options, const char *host,
char *line, const char *filename, int linenum, char *line, const char *filename, int linenum,
int *activep) int *activep)
{ {
char buf[256], *s, **charptr, *endofnumber, *keyword, *arg; char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
int opcode, *intptr, value; int opcode, *intptr, value;
size_t len; size_t len;
u_short fwd_port, fwd_host_port; Forward fwd;
char sfwd_host_port[6];
/* Strip trailing whitespace */ /* 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) if (strchr(WHITESPACE, line[len]) == NULL)
break; break;
line[len] = '\0'; line[len] = '\0';
@ -648,30 +658,26 @@ process_config_line(Options *options, const char *host,
case oLocalForward: case oLocalForward:
case oRemoteForward: case oRemoteForward:
arg = strdelim(&s); arg = strdelim(&s);
if (!arg || *arg == '\0') if (arg == NULL || *arg == '\0')
fatal("%.200s line %d: Missing port argument.", fatal("%.200s line %d: Missing port argument.",
filename, linenum); filename, linenum);
if ((fwd_port = a2port(arg)) == 0) arg2 = strdelim(&s);
fatal("%.200s line %d: Bad listen port.", if (arg2 == NULL || *arg2 == '\0')
fatal("%.200s line %d: Missing target argument.",
filename, linenum); filename, linenum);
arg = strdelim(&s);
if (!arg || *arg == '\0') /* construct a string for parse_forward */
fatal("%.200s line %d: Missing second argument.", snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
filename, linenum);
if (sscanf(arg, "%255[^:]:%5[0-9]", buf, sfwd_host_port) != 2 && if (parse_forward(&fwd, fwdarg) == 0)
sscanf(arg, "%255[^/]/%5[0-9]", buf, sfwd_host_port) != 2)
fatal("%.200s line %d: Bad forwarding specification.", fatal("%.200s line %d: Bad forwarding specification.",
filename, linenum); filename, linenum);
if ((fwd_host_port = a2port(sfwd_host_port)) == 0)
fatal("%.200s line %d: Bad forwarding port.",
filename, linenum);
if (*activep) { if (*activep) {
if (opcode == oLocalForward) if (opcode == oLocalForward)
add_local_forward(options, fwd_port, buf, add_local_forward(options, &fwd);
fwd_host_port);
else if (opcode == oRemoteForward) else if (opcode == oRemoteForward)
add_remote_forward(options, fwd_port, buf, add_remote_forward(options, &fwd);
fwd_host_port);
} }
break; break;
@ -680,12 +686,25 @@ process_config_line(Options *options, const char *host,
if (!arg || *arg == '\0') if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing port argument.", fatal("%.200s line %d: Missing port argument.",
filename, linenum); filename, linenum);
fwd_port = a2port(arg); memset(&fwd, '\0', sizeof(fwd));
if (fwd_port == 0) 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.", fatal("%.200s line %d: Badly formatted port number.",
filename, linenum); filename, linenum);
if (*activep) if (*activep)
add_local_forward(options, fwd_port, "socks", 0); add_local_forward(options, &fwd);
break; break;
case oClearAllForwardings: case oClearAllForwardings:
@ -761,6 +780,8 @@ process_config_line(Options *options, const char *host,
if (strchr(arg, '=') != NULL) if (strchr(arg, '=') != NULL)
fatal("%s line %d: Invalid environment name.", fatal("%s line %d: Invalid environment name.",
filename, linenum); filename, linenum);
if (!*activep)
continue;
if (options->num_send_env >= MAX_SEND_ENV) if (options->num_send_env >= MAX_SEND_ENV)
fatal("%s line %d: too many send env.", fatal("%s line %d: too many send env.",
filename, linenum); filename, linenum);
@ -777,6 +798,10 @@ process_config_line(Options *options, const char *host,
intptr = &options->control_master; intptr = &options->control_master;
goto parse_yesnoask; goto parse_yesnoask;
case oHashKnownHosts:
intptr = &options->hash_known_hosts;
goto parse_flag;
case oVersionAddendum: case oVersionAddendum:
ssh_version_set_addendum(strtok(s, "\n")); ssh_version_set_addendum(strtok(s, "\n"));
do { do {
@ -927,6 +952,7 @@ initialize_options(Options * options)
options->num_send_env = 0; options->num_send_env = 0;
options->control_path = NULL; options->control_path = NULL;
options->control_master = -1; options->control_master = -1;
options->hash_known_hosts = -1;
} }
/* /*
@ -1049,9 +1075,76 @@ fill_default_options(Options * options)
options->server_alive_count_max = 3; options->server_alive_count_max = 3;
if (options->control_master == -1) if (options->control_master == -1)
options->control_master = 0; 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->proxy_command should not be set by default */
/* options->user will be set in the main program if appropriate */ /* options->user will be set in the main program if appropriate */
/* options->hostname 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->host_key_alias should not be set by default */
/* options->preferred_authentications will be set in ssh */ /* 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);
}

View File

@ -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> * Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -21,9 +21,10 @@
/* Data structure for representing a forwarding request. */ /* Data structure for representing a forwarding request. */
typedef struct { typedef struct {
u_short port; /* Port to forward. */ char *listen_host; /* Host (address) to listen on. */
char *host; /* Host to connect. */ u_short listen_port; /* Port to forward. */
u_short host_port; /* Port to connect on host. */ char *connect_host; /* Host to connect. */
u_short connect_port; /* Port to connect on connect_host. */
} Forward; } Forward;
/* Data structure for representing option data. */ /* Data structure for representing option data. */
@ -111,17 +112,20 @@ typedef struct {
char *control_path; char *control_path;
int control_master; int control_master;
int hash_known_hosts;
} Options; } Options;
void initialize_options(Options *); void initialize_options(Options *);
void fill_default_options(Options *); void fill_default_options(Options *);
int read_config_file(const char *, const char *, Options *, int); int read_config_file(const char *, const char *, Options *, int);
int parse_forward(Forward *, const char *);
int int
process_config_line(Options *, const char *, char *, const char *, int, 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_local_forward(Options *, const Forward *);
void add_remote_forward(Options *, u_short, const char *, u_short); void add_remote_forward(Options *, const Forward *);
#endif /* READCONF_H */ #endif /* READCONF_H */

View File

@ -71,7 +71,7 @@
*/ */
#include "includes.h" #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 "xmalloc.h"
#include "atomicio.h" #include "atomicio.h"
@ -108,8 +108,10 @@ pid_t do_cmd_pid = -1;
static void static void
killchild(int signo) killchild(int signo)
{ {
if (do_cmd_pid > 1) if (do_cmd_pid > 1) {
kill(do_cmd_pid, signo); kill(do_cmd_pid, signo);
waitpid(do_cmd_pid, NULL, 0);
}
_exit(1); _exit(1);
} }
@ -359,20 +361,21 @@ void
toremote(char *targ, int argc, char **argv) toremote(char *targ, int argc, char **argv)
{ {
int i, len; int i, len;
char *bp, *host, *src, *suser, *thost, *tuser; char *bp, *host, *src, *suser, *thost, *tuser, *arg;
*targ++ = 0; *targ++ = 0;
if (*targ == 0) if (*targ == 0)
targ = "."; targ = ".";
if ((thost = strrchr(argv[argc - 1], '@'))) { arg = xstrdup(argv[argc - 1]);
if ((thost = strrchr(arg, '@'))) {
/* user@host */ /* user@host */
*thost++ = 0; *thost++ = 0;
tuser = argv[argc - 1]; tuser = arg;
if (*tuser == '\0') if (*tuser == '\0')
tuser = NULL; tuser = NULL;
} else { } else {
thost = argv[argc - 1]; thost = arg;
tuser = NULL; tuser = NULL;
} }
@ -726,7 +729,7 @@ sink(int argc, char **argv)
#define atime tv[0] #define atime tv[0]
#define mtime tv[1] #define mtime tv[1]
#define SCREWUP(str) do { why = str; goto screwup; } while (0) #define SCREWUP(str) { why = str; goto screwup; }
setimes = targisdir = 0; setimes = targisdir = 0;
mask = umask(0); mask = umask(0);

View File

@ -10,7 +10,7 @@
*/ */
#include "includes.h" #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$"); RCSID("$FreeBSD$");
#include "ssh.h" #include "ssh.h"
@ -27,8 +27,6 @@ RCSID("$FreeBSD$");
static void add_listen_addr(ServerOptions *, char *, u_short); static void add_listen_addr(ServerOptions *, char *, u_short);
static void add_one_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 */ /* Use of privilege separation or not */
extern int use_privsep; extern int use_privsep;
@ -46,6 +44,7 @@ initialize_server_options(ServerOptions *options)
options->num_ports = 0; options->num_ports = 0;
options->ports_from_cmdline = 0; options->ports_from_cmdline = 0;
options->listen_addrs = NULL; options->listen_addrs = NULL;
options->address_family = -1;
options->num_host_key_files = 0; options->num_host_key_files = 0;
options->pid_file = NULL; options->pid_file = NULL;
options->server_key_bits = -1; options->server_key_bits = -1;
@ -261,7 +260,8 @@ typedef enum {
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup, sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
sKerberosGetAFSToken, sKerberosGetAFSToken,
sKerberosTgtPassing, sChallengeResponseAuthentication, sKerberosTgtPassing, sChallengeResponseAuthentication,
sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress, sPasswordAuthentication, sKbdInteractiveAuthentication,
sListenAddress, sAddressFamily,
sPrintMotd, sPrintLastLog, sIgnoreRhosts, sPrintMotd, sPrintLastLog, sIgnoreRhosts,
sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost, sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
sStrictModes, sEmptyPasswd, sTCPKeepAlive, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
@ -339,6 +339,7 @@ static struct {
{ "skeyauthentication", sChallengeResponseAuthentication }, /* alias */ { "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
{ "checkmail", sDeprecated }, { "checkmail", sDeprecated },
{ "listenaddress", sListenAddress }, { "listenaddress", sListenAddress },
{ "addressfamily", sAddressFamily },
{ "printmotd", sPrintMotd }, { "printmotd", sPrintMotd },
{ "printlastlog", sPrintLastLog }, { "printlastlog", sPrintLastLog },
{ "ignorerhosts", sIgnoreRhosts }, { "ignorerhosts", sIgnoreRhosts },
@ -406,6 +407,8 @@ add_listen_addr(ServerOptions *options, char *addr, u_short port)
if (options->num_ports == 0) if (options->num_ports == 0)
options->ports[options->num_ports++] = SSH_DEFAULT_PORT; options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
if (options->address_family == -1)
options->address_family = AF_UNSPEC;
if (port == 0) if (port == 0)
for (i = 0; i < options->num_ports; i++) for (i = 0; i < options->num_ports; i++)
add_one_listen_addr(options, addr, options->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; int gaierr;
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_family = IPv4or6; hints.ai_family = options->address_family;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0; hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
snprintf(strport, sizeof strport, "%u", port); snprintf(strport, sizeof strport, "%u", port);
@ -442,6 +445,7 @@ process_server_config_line(ServerOptions *options, char *line,
char *cp, **charptr, *arg, *p; char *cp, **charptr, *arg, *p;
int *intptr, value, i, n; int *intptr, value, i, n;
ServerOpCodes opcode; ServerOpCodes opcode;
u_short port;
cp = line; cp = line;
arg = strdelim(&cp); arg = strdelim(&cp);
@ -514,39 +518,40 @@ process_server_config_line(ServerOptions *options, char *line,
case sListenAddress: case sListenAddress:
arg = strdelim(&cp); arg = strdelim(&cp);
if (!arg || *arg == '\0' || strncmp(arg, "[]", 2) == 0) if (arg == NULL || *arg == '\0')
fatal("%s line %d: missing inet addr.", fatal("%s line %d: missing address",
filename, linenum); filename, linenum);
if (*arg == '[') { p = hpdelim(&arg);
if ((p = strchr(arg, ']')) == NULL) if (p == NULL)
fatal("%s line %d: bad ipv6 inet addr usage.", fatal("%s line %d: bad address:port usage",
filename, linenum); filename, linenum);
arg++; p = cleanhostname(p);
memmove(p, p+1, strlen(p+1)+1); if (arg == NULL)
} else if (((p = strchr(arg, ':')) == NULL) || port = 0;
(strchr(p+1, ':') != NULL)) { else if ((port = a2port(arg)) == 0)
add_listen_addr(options, arg, 0); fatal("%s line %d: bad port number", filename, linenum);
break;
}
if (*p == ':') {
u_short port;
p++; add_listen_addr(options, p, port);
if (*p == '\0')
fatal("%s line %d: bad inet addr:port usage.", break;
filename, linenum);
else { case sAddressFamily:
*(p-1) = '\0'; arg = strdelim(&cp);
if ((port = a2port(p)) == 0) intptr = &options->address_family;
fatal("%s line %d: bad port number.", if (options->listen_addrs != NULL)
filename, linenum); fatal("%s line %d: address family must be specified before "
add_listen_addr(options, arg, port); "ListenAddress.", filename, linenum);
} if (strcasecmp(arg, "inet") == 0)
} else if (*p == '\0') value = AF_INET;
add_listen_addr(options, arg, 0); else if (strcasecmp(arg, "inet6") == 0)
value = AF_INET6;
else if (strcasecmp(arg, "any") == 0)
value = AF_UNSPEC;
else else
fatal("%s line %d: bad inet addr usage.", fatal("%s line %d: unsupported address family \"%s\".",
filename, linenum); filename, linenum, arg);
if (*intptr == -1)
*intptr = value;
break; break;
case sHostKeyFile: case sHostKeyFile:
@ -725,7 +730,23 @@ process_server_config_line(ServerOptions *options, char *line,
case sGatewayPorts: case sGatewayPorts:
intptr = &options->gateway_ports; 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: case sUseDNS:
intptr = &options->use_dns; intptr = &options->use_dns;
@ -992,7 +1013,7 @@ parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
obuf = cbuf = xstrdup(buffer_ptr(conf)); obuf = cbuf = xstrdup(buffer_ptr(conf));
linenum = 1; linenum = 1;
while((cp = strsep(&cbuf, "\n")) != NULL) { while ((cp = strsep(&cbuf, "\n")) != NULL) {
if (process_server_config_line(options, cp, filename, if (process_server_config_line(options, cp, filename,
linenum++) != 0) linenum++) != 0)
bad_options++; bad_options++;

View File

@ -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$ */ /* $FreeBSD$ */
/* /*
@ -44,6 +44,7 @@ typedef struct {
u_short ports[MAX_PORTS]; /* Port number to listen on. */ u_short ports[MAX_PORTS]; /* Port number to listen on. */
char *listen_addr; /* Address on which the server listens. */ char *listen_addr; /* Address on which the server listens. */
struct addrinfo *listen_addrs; /* Addresses 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. */ char *host_key_files[MAX_HOSTKEYS]; /* Files containing host keys. */
int num_host_key_files; /* Number of files for host keys. */ int num_host_key_files; /* Number of files for host keys. */
char *pid_file; /* Where to put our pid */ char *pid_file; /* Where to put our pid */

View File

@ -33,7 +33,7 @@
*/ */
#include "includes.h" #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$"); RCSID("$FreeBSD$");
#include "ssh.h" #include "ssh.h"
@ -246,6 +246,10 @@ do_authenticated1(Authctxt *authctxt)
u_int proto_len, data_len, dlen, compression_level = 0; u_int proto_len, data_len, dlen, compression_level = 0;
s = session_new(); s = session_new();
if (s == NULL) {
error("no more sessions");
return;
}
s->authctxt = authctxt; s->authctxt = authctxt;
s->pw = authctxt->pw; s->pw = authctxt->pw;
@ -662,11 +666,15 @@ do_exec(Session *s, const char *command)
debug("Forced command '%.900s'", command); debug("Forced command '%.900s'", command);
} }
#ifdef GSSAPI #ifdef SSH_AUDIT_EVENTS
if (options.gss_authentication) { if (command != NULL)
temporarily_use_uid(s->pw); PRIVSEP(audit_run_command(command));
ssh_gssapi_storecreds(); else if (s->ttyfd == -1) {
restore_uid(); char *shell = s->pw->pw_shell;
if (shell[0] == '\0') /* empty shell means /bin/sh */
shell =_PATH_BSHELL;
PRIVSEP(audit_run_command(shell));
} }
#endif #endif
@ -1002,7 +1010,13 @@ do_setup_env(Session *s, const char *shell)
* The Windows environment contains some setting which are * The Windows environment contains some setting which are
* important for a running system. They must not be dropped. * 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 #endif
if (getenv("TZ")) if (getenv("TZ"))
@ -1111,14 +1125,24 @@ do_setup_env(Session *s, const char *shell)
child_set_env(&env, &envsize, "TMPDIR", cray_tmpdir); child_set_env(&env, &envsize, "TMPDIR", cray_tmpdir);
#endif /* _UNICOS */ #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 #ifdef _AIX
{ {
char *cp; char *cp;
if ((cp = getenv("AUTHSTATE")) != NULL) if ((cp = getenv("AUTHSTATE")) != NULL)
child_set_env(&env, &envsize, "AUTHSTATE", cp); 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"); read_environment_file(&env, &envsize, "/etc/environment");
} }
#endif #endif
@ -1278,6 +1302,13 @@ do_setusercontext(struct passwd *pw)
# ifdef __bsdi__ # ifdef __bsdi__
setpgid(0, 0); setpgid(0, 0);
# endif # endif
#ifdef GSSAPI
if (options.gss_authentication) {
temporarily_use_uid(pw);
ssh_gssapi_storecreds();
restore_uid();
}
#endif
# ifdef USE_PAM # ifdef USE_PAM
if (options.use_pam) { if (options.use_pam) {
do_pam_session(); do_pam_session();
@ -1308,6 +1339,13 @@ do_setusercontext(struct passwd *pw)
exit(1); exit(1);
} }
endgrent(); endgrent();
#ifdef GSSAPI
if (options.gss_authentication) {
temporarily_use_uid(pw);
ssh_gssapi_storecreds();
restore_uid();
}
#endif
# ifdef USE_PAM # ifdef USE_PAM
/* /*
* PAM credentials may take the form of supplementary groups. * PAM credentials may take the form of supplementary groups.
@ -1345,7 +1383,12 @@ do_pwchange(Session *s)
if (s->ttyfd != -1) { if (s->ttyfd != -1) {
fprintf(stderr, fprintf(stderr,
"You must change your password now and login again!\n"); "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); execl(_PATH_PASSWD_PROG, "passwd", (char *)NULL);
#endif
perror("passwd"); perror("passwd");
} else { } else {
fprintf(stderr, fprintf(stderr,
@ -1462,11 +1505,19 @@ do_child(Session *s, const char *command)
* generated messages, so if this in an interactive * generated messages, so if this in an interactive
* login then display them too. * login then display them too.
*/ */
if (command == NULL) if (!check_quietlogin(s, command))
display_loginmsg(); display_loginmsg();
#endif /* HAVE_OSF_SIA */ #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 * Get the shell from the password data. An empty shell field is
* legal, and means /bin/sh. * legal, and means /bin/sh.

View File

@ -35,7 +35,7 @@
*/ */
#include "includes.h" #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> #include <openssl/evp.h>
@ -389,7 +389,7 @@ main(int argc, char **argv)
goto done; 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, snprintf(buf, sizeof(buf), "%s/%s", pw->pw_dir,
default_files[i]); default_files[i]);
if (stat(buf, &st) < 0) if (stat(buf, &st) < 0)
@ -402,7 +402,7 @@ main(int argc, char **argv)
if (count == 0) if (count == 0)
ret = 1; ret = 1;
} else { } else {
for(i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
if (do_file(ac, deleting, argv[i]) == -1) if (do_file(ac, deleting, argv[i]) == -1)
ret = 1; ret = 1;
} }

View File

@ -35,7 +35,7 @@
#include "includes.h" #include "includes.h"
#include "openbsd-compat/sys-queue.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$"); RCSID("$FreeBSD$");
#include <openssl/evp.h> #include <openssl/evp.h>
@ -169,23 +169,15 @@ lookup_identity(Key *key, int version)
static int static int
confirm_key(Identity *id) confirm_key(Identity *id)
{ {
char *p, prompt[1024]; char *p;
int ret = -1; int ret = -1;
p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX);
snprintf(prompt, sizeof(prompt), "Allow use of key %s?\n" if (ask_permission("Allow use of key %s?\nKey fingerprint %s.",
"Key fingerprint %s.", id->comment, p); id->comment, p))
ret = 0;
xfree(p); 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); return (ret);
} }
@ -1011,9 +1003,7 @@ main(int ac, char **av)
#ifdef HAVE_SETRLIMIT #ifdef HAVE_SETRLIMIT
struct rlimit rlim; struct rlimit rlim;
#endif #endif
#ifdef HAVE_CYGWIN
int prev_mask; int prev_mask;
#endif
extern int optind; extern int optind;
extern char *optarg; extern char *optarg;
pid_t pid; pid_t pid;
@ -1126,24 +1116,20 @@ main(int ac, char **av)
sock = socket(AF_UNIX, SOCK_STREAM, 0); sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) { if (sock < 0) {
perror("socket"); perror("socket");
*socket_name = '\0'; /* Don't unlink any existing file */
cleanup_exit(1); cleanup_exit(1);
} }
memset(&sunaddr, 0, sizeof(sunaddr)); memset(&sunaddr, 0, sizeof(sunaddr));
sunaddr.sun_family = AF_UNIX; sunaddr.sun_family = AF_UNIX;
strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path)); strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path));
#ifdef HAVE_CYGWIN
prev_mask = umask(0177); prev_mask = umask(0177);
#endif
if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) { if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) {
perror("bind"); perror("bind");
#ifdef HAVE_CYGWIN *socket_name = '\0'; /* Don't unlink any existing file */
umask(prev_mask); umask(prev_mask);
#endif
cleanup_exit(1); cleanup_exit(1);
} }
#ifdef HAVE_CYGWIN
umask(prev_mask); umask(prev_mask);
#endif
if (listen(sock, SSH_LISTEN_BACKLOG) < 0) { if (listen(sock, SSH_LISTEN_BACKLOG) < 0) {
perror("listen"); perror("listen");
cleanup_exit(1); cleanup_exit(1);

View File

@ -7,7 +7,7 @@
*/ */
#include "includes.h" #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" #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 "log.h"
#include "atomicio.h" #include "atomicio.h"
#include "misc.h" #include "misc.h"
#include "hostfile.h"
/* Flag indicating whether IPv4 or IPv6. This can be set on the command line. /* Flag indicating whether IPv4 or IPv6. This can be set on the command line.
Default value is AF_UNSPEC means both IPv4 and IPv6. */ 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 get_keytypes = KT_RSA1; /* Get only RSA1 keys by default */
int hash_hosts = 0; /* Hash hostname on output */
#define MAXMAXFD 256 #define MAXMAXFD 256
/* The number of seconds after which to give up on a TCP connection */ /* The number of seconds after which to give up on a TCP connection */
@ -366,10 +369,14 @@ keygrab_ssh2(con *c)
static void static void
keyprint(con *c, Key *key) keyprint(con *c, Key *key)
{ {
char *host = c->c_output_name ? c->c_output_name : c->c_name;
if (!key) if (!key)
return; 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); key_write(key, stdout);
fputs("\n", stdout); fputs("\n", stdout);
} }
@ -676,7 +683,7 @@ fatal(const char *fmt,...)
static void static void
usage(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", "\t\t [host | addrlist namelist] [...]\n",
__progname); __progname);
exit(1); exit(1);
@ -700,8 +707,11 @@ main(int argc, char **argv)
if (argc <= 1) if (argc <= 1)
usage(); usage();
while ((opt = getopt(argc, argv, "v46p:T:t:f:")) != -1) { while ((opt = getopt(argc, argv, "Hv46p:T:t:f:")) != -1) {
switch (opt) { switch (opt) {
case 'H':
hash_hosts = 1;
break;
case 'p': case 'p':
ssh_port = a2port(optarg); ssh_port = a2port(optarg);
if (ssh_port == 0) { if (ssh_port == 0) {

View File

@ -341,7 +341,6 @@ The user should not manually set
.Ev DISPLAY . .Ev DISPLAY .
Forwarding of X11 connections can be Forwarding of X11 connections can be
configured on the command line or in configuration files. configured on the command line or in configuration files.
Take note that X11 forwarding can represent a security hazard.
.Pp .Pp
The The
.Ev DISPLAY .Ev DISPLAY

View File

@ -40,7 +40,7 @@
*/ */
#include "includes.h" #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$"); RCSID("$FreeBSD$");
#include <openssl/evp.h> #include <openssl/evp.h>
@ -145,6 +145,9 @@ pid_t proxy_command_pid = 0;
/* fd to control socket */ /* fd to control socket */
int control_fd = -1; int control_fd = -1;
/* Multiplexing control command */
static u_int mux_command = SSHMUX_COMMAND_OPEN;
/* Only used in control client mode */ /* Only used in control client mode */
volatile sig_atomic_t control_client_terminate = 0; volatile sig_atomic_t control_client_terminate = 0;
u_int control_server_pid = 0; u_int control_server_pid = 0;
@ -155,10 +158,12 @@ static void
usage(void) usage(void)
{ {
fprintf(stderr, fprintf(stderr,
"usage: ssh [-1246AaCfghkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n" "usage: ssh [-1246AaCfgkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n"
" [-D port] [-e escape_char] [-F configfile] [-i identity_file]\n" " [-D port] [-e escape_char] [-F configfile]\n"
" [-L port:host:hostport] [-l login_name] [-m mac_spec] [-o option]\n" " [-i identity_file] [-L [bind_address:]port:host:hostport]\n"
" [-p port] [-R port:host:hostport] [-S ctl] [user@]hostname [command]\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); exit(1);
} }
@ -175,14 +180,13 @@ int
main(int ac, char **av) main(int ac, char **av)
{ {
int i, opt, exit_status; 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]; char *p, *cp, *line, buf[256];
struct stat st; struct stat st;
struct passwd *pw; struct passwd *pw;
int dummy; int dummy;
extern int optind, optreset; extern int optind, optreset;
extern char *optarg; extern char *optarg;
Forward fwd;
__progname = ssh_get_progname(av[0]); __progname = ssh_get_progname(av[0]);
init_rng(); init_rng();
@ -237,7 +241,7 @@ main(int ac, char **av)
again: again:
while ((opt = getopt(ac, av, 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) { switch (opt) {
case '1': case '1':
options.protocol = SSH_PROTO_1; options.protocol = SSH_PROTO_1;
@ -271,6 +275,14 @@ main(int ac, char **av)
case 'g': case 'g':
options.gateway_ports = 1; options.gateway_ports = 1;
break; 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 */ case 'P': /* deprecated */
options.use_privileged_port = 0; options.use_privileged_port = 0;
break; break;
@ -286,7 +298,8 @@ main(int ac, char **av)
case 'i': case 'i':
if (stat(optarg, &st) < 0) { if (stat(optarg, &st) < 0) {
fprintf(stderr, "Warning: Identity file %s " fprintf(stderr, "Warning: Identity file %s "
"does not exist.\n", optarg); "not accessible: %s.\n", optarg,
strerror(errno));
break; break;
} }
if (options.num_identity_files >= if (options.num_identity_files >=
@ -317,10 +330,10 @@ main(int ac, char **av)
options.log_level++; options.log_level++;
break; break;
} }
/* fallthrough */ /* FALLTHROUGH */
case 'V': case 'V':
fprintf(stderr, "%s, %s\n", fprintf(stderr, "%s, %s\n",
SSH_VERSION, SSLeay_version(SSLEAY_VERSION)); SSH_RELEASE, SSLeay_version(SSLEAY_VERSION));
if (opt == 'V') if (opt == 'V')
exit(0); exit(0);
break; break;
@ -389,39 +402,51 @@ main(int ac, char **av)
break; break;
case 'L': case 'L':
case 'R': if (parse_forward(&fwd, optarg))
if (sscanf(optarg, "%5[0123456789]:%255[^:]:%5[0123456789]", add_local_forward(&options, &fwd);
sfwd_port, buf, sfwd_host_port) != 3 && else {
sscanf(optarg, "%5[0123456789]/%255[^/]/%5[0123456789]",
sfwd_port, buf, sfwd_host_port) != 3) {
fprintf(stderr, fprintf(stderr,
"Bad forwarding specification '%s'\n", "Bad local forwarding specification '%s'\n",
optarg); optarg);
usage();
/* NOTREACHED */
}
if ((fwd_port = a2port(sfwd_port)) == 0 ||
(fwd_host_port = a2port(sfwd_host_port)) == 0) {
fprintf(stderr,
"Bad forwarding port(s) '%s'\n", optarg);
exit(1); exit(1);
} }
if (opt == 'L') break;
add_local_forward(&options, fwd_port, buf,
fwd_host_port); case 'R':
else if (opt == 'R') if (parse_forward(&fwd, optarg)) {
add_remote_forward(&options, fwd_port, buf, add_remote_forward(&options, &fwd);
fwd_host_port); } else {
fprintf(stderr,
"Bad remote forwarding specification "
"'%s'\n", optarg);
exit(1);
}
break; break;
case 'D': case 'D':
fwd_port = a2port(optarg); cp = p = xstrdup(optarg);
if (fwd_port == 0) { 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", fprintf(stderr, "Bad dynamic port '%s'\n",
optarg); optarg);
exit(1); exit(1);
} }
add_local_forward(&options, fwd_port, "socks", 0); add_local_forward(&options, &fwd);
xfree(p);
break; break;
case 'C': case 'C':
@ -847,14 +872,19 @@ ssh_init_forwarding(void)
/* Initiate local TCP/IP port forwardings. */ /* Initiate local TCP/IP port forwardings. */
for (i = 0; i < options.num_local_forwards; i++) { for (i = 0; i < options.num_local_forwards; i++) {
debug("Connections to local port %d forwarded to remote address %.200s:%d", debug("Local connections to %.200s:%d forwarded to remote "
options.local_forwards[i].port, "address %.200s:%d",
options.local_forwards[i].host, (options.local_forwards[i].listen_host == NULL) ?
options.local_forwards[i].host_port); (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( success += channel_setup_local_fwd_listener(
options.local_forwards[i].port, options.local_forwards[i].listen_host,
options.local_forwards[i].host, options.local_forwards[i].listen_port,
options.local_forwards[i].host_port, options.local_forwards[i].connect_host,
options.local_forwards[i].connect_port,
options.gateway_ports); options.gateway_ports);
} }
if (i > 0 && success == 0) if (i > 0 && success == 0)
@ -862,14 +892,19 @@ ssh_init_forwarding(void)
/* Initiate remote TCP/IP port forwardings. */ /* Initiate remote TCP/IP port forwardings. */
for (i = 0; i < options.num_remote_forwards; i++) { for (i = 0; i < options.num_remote_forwards; i++) {
debug("Connections to remote port %d forwarded to local address %.200s:%d", debug("Remote connections from %.200s:%d forwarded to "
options.remote_forwards[i].port, "local address %.200s:%d",
options.remote_forwards[i].host, (options.remote_forwards[i].listen_host == NULL) ?
options.remote_forwards[i].host_port); (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( channel_request_remote_forwarding(
options.remote_forwards[i].port, options.remote_forwards[i].listen_host,
options.remote_forwards[i].host, options.remote_forwards[i].listen_port,
options.remote_forwards[i].host_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; return;
debug("remote forward %s for: listen %d, connect %s:%d", debug("remote forward %s for: listen %d, connect %s:%d",
type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
options.remote_forwards[i].port, options.remote_forwards[i].listen_port,
options.remote_forwards[i].host, options.remote_forwards[i].connect_host,
options.remote_forwards[i].host_port); options.remote_forwards[i].connect_port);
if (type == SSH2_MSG_REQUEST_FAILURE) if (type == SSH2_MSG_REQUEST_FAILURE)
logit("Warning: remote port forwarding failed for listen port %d", logit("Warning: remote port forwarding failed for listen "
options.remote_forwards[i].port); "port %d", options.remote_forwards[i].listen_port);
} }
static void static void
@ -1078,7 +1113,7 @@ ssh_control_listener(void)
old_umask = umask(0177); old_umask = umask(0177);
if (bind(control_fd, (struct sockaddr*)&addr, addr_len) == -1) { if (bind(control_fd, (struct sockaddr*)&addr, addr_len) == -1) {
control_fd = -1; control_fd = -1;
if (errno == EINVAL) if (errno == EINVAL || errno == EADDRINUSE)
fatal("ControlSocket %s already exists", fatal("ControlSocket %s already exists",
options.control_path); options.control_path);
else else
@ -1267,10 +1302,20 @@ static void
control_client(const char *path) control_client(const char *path)
{ {
struct sockaddr_un addr; 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; Buffer m;
char *cp; char *term;
extern char **environ; 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)); memset(&addr, '\0', sizeof(addr));
addr.sun_family = AF_UNIX; addr.sun_family = AF_UNIX;
@ -1287,26 +1332,52 @@ control_client(const char *path)
if (connect(sock, (struct sockaddr*)&addr, addr_len) == -1) if (connect(sock, (struct sockaddr*)&addr, addr_len) == -1)
fatal("Couldn't connect to %s: %s", path, strerror(errno)); fatal("Couldn't connect to %s: %s", path, strerror(errno));
if ((cp = getenv("TERM")) == NULL) if ((term = getenv("TERM")) == NULL)
cp = ""; term = "";
flags = 0;
if (tty_flag)
flags |= SSHMUX_FLAG_TTY;
if (subsystem_flag)
flags |= SSHMUX_FLAG_SUBSYS;
buffer_init(&m); 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) if (ssh_msg_recv(sock, &m) == -1)
fatal("%s: msg_recv", __func__); fatal("%s: msg_recv", __func__);
if (buffer_get_char(&m) != 0) if (buffer_get_char(&m) != 1)
fatal("%s: wrong version", __func__); fatal("%s: wrong version", __func__);
/* Connection allowed? */
if (buffer_get_int(&m) != 1) if (buffer_get_int(&m) != 1)
fatal("Connection to master denied"); fatal("Connection to master denied");
control_server_pid = buffer_get_int(&m); control_server_pid = buffer_get_int(&m);
buffer_clear(&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_append(&command, "\0", 1);
buffer_put_cstring(&m, buffer_ptr(&command)); 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__); fatal("%s: msg_send", __func__);
mm_send_fd(sock, STDIN_FILENO); mm_send_fd(sock, STDIN_FILENO);
@ -1339,10 +1410,11 @@ control_client(const char *path)
buffer_clear(&m); buffer_clear(&m);
if (ssh_msg_recv(sock, &m) == -1) if (ssh_msg_recv(sock, &m) == -1)
fatal("%s: msg_recv", __func__); fatal("%s: msg_recv", __func__);
if (buffer_get_char(&m) != 0) if (buffer_get_char(&m) != 1)
fatal("%s: master returned error", __func__); fatal("%s: wrong version", __func__);
buffer_free(&m); buffer_free(&m);
signal(SIGHUP, control_client_sighandler);
signal(SIGINT, control_client_sighandler); signal(SIGINT, control_client_sighandler);
signal(SIGTERM, control_client_sighandler); signal(SIGTERM, control_client_sighandler);
signal(SIGWINCH, control_client_sigrelay); signal(SIGWINCH, control_client_sigrelay);

View File

@ -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> * Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -39,6 +39,13 @@
*/ */
#define SSH_MAX_IDENTITY_FILES 100 #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 * Major protocol version. Different version indicates major incompatibility
* that prevents communication. * that prevents communication.

View File

@ -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$ # $FreeBSD$
# This is the ssh client system-wide configuration file. See # 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 # Thus, host-specific definitions should be at the beginning of the
# configuration file, and defaults at the end. # 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 * # Host *
# ForwardAgent no # ForwardAgent no
@ -36,4 +38,4 @@
# Cipher 3des # Cipher 3des
# Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc # Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
# EscapeChar ~ # EscapeChar ~
# VersionAddendum FreeBSD-20041028 # VersionAddendum FreeBSD-20050605

View File

@ -34,7 +34,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, 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$ .\" $FreeBSD$
.Dd September 25, 1999 .Dd September 25, 1999
.Dt SSH_CONFIG 5 .Dt SSH_CONFIG 5
@ -64,7 +64,7 @@ system-wide configuration file
.Pp .Pp
For each parameter, the first obtained value For each parameter, the first obtained value
will be used. will be used.
The configuration files contain sections bracketed by The configuration files contain sections separated by
.Dq Host .Dq Host
specifications, and that section is only applied for hosts that specifications, and that section is only applied for hosts that
match one of the patterns given in the specification. match one of the patterns given in the specification.
@ -121,9 +121,9 @@ Specifies which address family to use when connecting.
Valid arguments are Valid arguments are
.Dq any , .Dq any ,
.Dq inet .Dq inet
(Use IPv4 only) or (use IPv4 only) or
.Dq inet6 .Dq inet6
(Use IPv6 only.) (use IPv6 only).
.It Cm BatchMode .It Cm BatchMode
If set to If set to
.Dq yes , .Dq yes ,
@ -360,11 +360,16 @@ option is also enabled.
If this option is set to If this option is set to
.Dq yes .Dq yes
then remote X11 clients will have full access to the original X11 display. then remote X11 clients will have full access to the original X11 display.
.Pp
If this option is set to If this option is set to
.Dq no .Dq no
then remote X11 clients will be considered untrusted and prevented then remote X11 clients will be considered untrusted and prevented
from stealing or tampering with data belonging to trusted X11 from stealing or tampering with data belonging to trusted X11
clients. 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 .Pp
The default is The default is
.Dq no . .Dq no .
@ -403,6 +408,22 @@ Forward (delegate) credentials to the server.
The default is The default is
.Dq no . .Dq no .
Note that this option applies to protocol version 2 only. 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 .It Cm HostbasedAuthentication
Specifies whether to try rhosts based authentication with public key Specifies whether to try rhosts based authentication with public key
authentication. authentication.
@ -468,16 +489,41 @@ This option is intented for situations where
offers many different identities. offers many different identities.
The default is The default is
.Dq no . .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 .It Cm LocalForward
Specifies that a TCP/IP port on the local machine be forwarded over 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 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 The first argument must be
.Ar host:port . .Sm off
IPv6 addresses can be specified with an alternative syntax: .Oo Ar bind_address : Oc Ar port
.Ar host/port . .Sm on
Multiple forwardings may be specified, and additional and the second argument must be
forwardings can be given on the command line. .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. 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 .It Cm LogLevel
Gives the verbosity level that is used when logging messages from Gives the verbosity level that is used when logging messages from
.Nm ssh . .Nm ssh .
@ -522,9 +568,9 @@ Default is 22.
.It Cm PreferredAuthentications .It Cm PreferredAuthentications
Specifies the order in which the client should try protocol 2 Specifies the order in which the client should try protocol 2
authentication methods. 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 ) .Cm keyboard-interactive )
over another method (e.g. over another method (e.g.\&
.Cm password ) .Cm password )
The default for this option is: The default for this option is:
.Dq hostbased,publickey,keyboard-interactive,password . .Dq hostbased,publickey,keyboard-interactive,password .
@ -583,13 +629,36 @@ This option applies to protocol version 2 only.
.It Cm RemoteForward .It Cm RemoteForward
Specifies that a TCP/IP port on the remote machine be forwarded over 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 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 The first argument must be
.Ar host:port . .Sm off
IPv6 addresses can be specified with an alternative syntax: .Oo Ar bind_address : Oc Ar port
.Ar host/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 Multiple forwardings may be specified, and additional
forwardings can be given on the command line. forwardings can be given on the command line.
Only the superuser can forward privileged ports. 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 .It Cm RhostsRSAAuthentication
Specifies whether to try rhosts based authentication with RSA host Specifies whether to try rhosts based authentication with RSA host
authentication. 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 Specifies a string to append to the regular version string to identify
OS- or site-specific modifications. OS- or site-specific modifications.
The default is The default is
.Dq FreeBSD-20041028 . .Dq FreeBSD-20050605 .
.It Cm XAuthLocation .It Cm XAuthLocation
Specifies the full pathname of the Specifies the full pathname of the
.Xr xauth 1 .Xr xauth 1

View File

@ -13,7 +13,7 @@
*/ */
#include "includes.h" #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> #include <openssl/bn.h>
@ -247,13 +247,13 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
tv.tv_sec = timeout; tv.tv_sec = timeout;
tv.tv_usec = 0; tv.tv_usec = 0;
for(;;) { for (;;) {
rc = select(sockfd + 1, NULL, fdset, NULL, &tv); rc = select(sockfd + 1, NULL, fdset, NULL, &tv);
if (rc != -1 || errno != EINTR) if (rc != -1 || errno != EINTR)
break; break;
} }
switch(rc) { switch (rc) {
case 0: case 0:
/* Timed out */ /* Timed out */
errno = ETIMEDOUT; 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 * 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 * and %p substituted for host and port, respectively) to use to contact
* the daemon. * 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 int
ssh_connect(const char *host, struct sockaddr_storage * hostaddr, 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]; char ntop[NI_MAXHOST], strport[NI_MAXSERV];
struct addrinfo hints, *ai, *aitop; struct addrinfo hints, *ai, *aitop;
struct servent *sp; 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); 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); memcpy(hostaddr, ai->ai_addr, ai->ai_addrlen);
break; break;
} else { } else {
if (errno == ECONNREFUSED)
full_failure = 0;
debug("connect to address %s port %s: %s", debug("connect to address %s port %s: %s",
ntop, strport, strerror(errno)); 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. */ /* Return failure if we didn't get a successful connection. */
if (attempt >= connection_attempts) { 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)); host, strport, strerror(errno));
return full_failure ? ECONNABORTED : ECONNREFUSED; return (-1);
} }
debug("Connection established."); debug("Connection established.");
@ -568,7 +554,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
char hostline[1000], *hostp, *fp; char hostline[1000], *hostp, *fp;
HostStatus host_status; HostStatus host_status;
HostStatus ip_status; HostStatus ip_status;
int local = 0, host_ip_differ = 0; int r, local = 0, host_ip_differ = 0;
int salen; int salen;
char ntop[NI_MAXHOST]; char ntop[NI_MAXHOST];
char msg[1024]; 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.", "'%.128s' not in list of known hosts.",
type, ip); type, ip);
else if (!add_host_to_hostfile(user_hostfile, 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 " logit("Failed to add the %s host key for IP "
"address '%.128s' to the list of known " "address '%.128s' to the list of known "
"hosts (%.30s).", type, ip, user_hostfile); "hosts (%.30s).", type, ip, user_hostfile);
@ -748,17 +734,33 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
if (!confirm(msg)) if (!confirm(msg))
goto fail; 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 * If not in strict mode, add the key automatically to the
* local known_hosts file. * 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 " logit("Failed to add the host to the list of known "
"hosts (%.500s).", user_hostfile); "hosts (%.500s).", user_hostfile);
else else

View File

@ -34,7 +34,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, 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$ .\" $FreeBSD$
.Dd September 25, 1999 .Dd September 25, 1999
.Dt SSHD 8 .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. Next, the server and the client enter an authentication dialog.
The client tries to authenticate itself using The client tries to authenticate itself using
.Em .rhosts .Em .rhosts
authentication,
.Em .rhosts
authentication combined with RSA host authentication combined with RSA host
authentication, RSA challenge-response authentication, or password authentication, RSA challenge-response authentication, or password
based authentication. based authentication.
@ -136,11 +134,6 @@ or
.Ql \&*NP\&* .Ql \&*NP\&*
). ).
.Pp .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 rshd ,
.Nm rlogind , .Nm rlogind ,
and and
@ -428,7 +421,9 @@ or
.Dq ssh-rsa . .Dq ssh-rsa .
.Pp .Pp
Note that lines in this file are usually several hundred bytes long 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 You don't want to type them in; instead, copy the
.Pa identity.pub , .Pa identity.pub ,
.Pa id_dsa.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, it is not accepted (by that line) even if it matched another
pattern on the line. pattern on the line.
.Pp .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 Bits, exponent, and modulus are taken directly from the RSA host key; they
can be obtained, e.g., from can be obtained, e.g., from
.Pa /etc/ssh/ssh_host_key.pub . .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 closenet,...,130.233.208.41 1024 37 159...93 closenet.hut.fi
cvs.openbsd.org,199.185.137.3 ssh-rsa AAAA1234.....= cvs.openbsd.org,199.185.137.3 ssh-rsa AAAA1234.....=
.Ed .Ed
.Bd -literal
# A hashed hostname
|1|JfKTdBh7rNbXkVAQCRp4OQoPfmI=|USECr3SWf1JUPsms5AqfD5QfxkM= ssh-rsa
AAAA1234.....=
.Ed
.Sh FILES .Sh FILES
.Bl -tag -width Ds .Bl -tag -width Ds
.It Pa /etc/ssh/sshd_config .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 should be world-readable, and
.Pa $HOME/.ssh/known_hosts .Pa $HOME/.ssh/known_hosts
can, but need not be, world-readable. 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 .It Pa /etc/nologin
If this file exists, If this file exists,
.Nm .Nm
@ -671,7 +693,11 @@ Access controls that should be enforced by tcp-wrappers are defined here.
Further details are described in Further details are described in
.Xr hosts_access 5 . .Xr hosts_access 5 .
.It Pa $HOME/.rhosts .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. line.
The given user on the corresponding host is permitted to log in The given user on the corresponding host is permitted to log in
without a password. 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. not used by rlogin and rshd, so using this permits access using SSH only.
.It Pa /etc/hosts.equiv .It Pa /etc/hosts.equiv
This file is used during This file is used during
.Em rhosts .Cm RhostsRSAAuthentication
and
.Cm HostbasedAuthentication
authentication. authentication.
In the simplest form, this file contains host names, one per line. In the simplest form, this file contains host names, one per line.
Users on Users on
@ -711,7 +739,7 @@ Negated entries start with
If the client host/user is successfully matched in this file, login is If the client host/user is successfully matched in this file, login is
automatically permitted provided the client and server user names are the automatically permitted provided the client and server user names are the
same. 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 This file must be writable only by root; it is recommended
that it be world-readable. that it be world-readable.
.Pp .Pp

View File

@ -42,7 +42,7 @@
*/ */
#include "includes.h" #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$"); RCSID("$FreeBSD$");
#include <openssl/dh.h> #include <openssl/dh.h>
@ -116,12 +116,6 @@ ServerOptions options;
/* Name of the server configuration file. */ /* Name of the server configuration file. */
char *config_file_name = _PATH_SERVER_CONFIG_FILE; 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 * 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 * mode is enabled, extra debugging output will be sent to the system
@ -755,7 +749,7 @@ get_hostkey_index(Key *key)
static int static int
drop_connection(int startups) drop_connection(int startups)
{ {
double p, r; int p, r;
if (startups < options.max_startups_begin) if (startups < options.max_startups_begin)
return 0; return 0;
@ -766,12 +760,11 @@ drop_connection(int startups)
p = 100 - options.max_startups_rate; p = 100 - options.max_startups_rate;
p *= startups - options.max_startups_begin; 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 += options.max_startups_rate;
p /= 100.0; r = arc4random() % 100;
r = arc4random() / (double) UINT_MAX;
debug("drop_connection: p %g, r %g", p, r); debug("drop_connection: p %d, r %d", p, r);
return (r < p) ? 1 : 0; return (r < p) ? 1 : 0;
} }
@ -779,7 +772,7 @@ static void
usage(void) usage(void)
{ {
fprintf(stderr, "%s, %s\n", fprintf(stderr, "%s, %s\n",
SSH_VERSION, SSLeay_version(SSLEAY_VERSION)); SSH_RELEASE, SSLeay_version(SSLEAY_VERSION));
fprintf(stderr, fprintf(stderr,
"usage: sshd [-46Ddeiqt] [-b bits] [-f config_file] [-g login_grace_time]\n" "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" " [-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 ntop[NI_MAXHOST], strport[NI_MAXSERV];
char *line; char *line;
int listen_sock, maxfd; 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; int startups = 0;
Key *key; Key *key;
Authctxt *authctxt; 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) { while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:dDeiqrtQR46")) != -1) {
switch (opt) { switch (opt) {
case '4': case '4':
IPv4or6 = AF_INET; options.address_family = AF_INET;
break; break;
case '6': case '6':
IPv4or6 = AF_INET6; options.address_family = AF_INET6;
break; break;
case 'f': case 'f':
config_file_name = optarg; config_file_name = optarg;
@ -1030,7 +1023,6 @@ main(int ac, char **av)
closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); closefrom(REEXEC_DEVCRYPTO_RESERVED_FD);
SSLeay_add_all_algorithms(); SSLeay_add_all_algorithms();
channel_set_af(IPv4or6);
/* /*
* Force logging to stderr until we have loaded the private host * 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, SYSLOG_FACILITY_AUTH : options.log_facility,
log_stderr || !inetd_flag); log_stderr || !inetd_flag);
#ifdef _AIX
/* /*
* Unset KRB5CCNAME, otherwise the user's session may inherit it from * Unset KRB5CCNAME, otherwise the user's session may inherit it from
* root's environment * root's environment
*/ */
unsetenv("KRB5CCNAME"); if (getenv("KRB5CCNAME") != NULL)
#endif /* _AIX */ unsetenv("KRB5CCNAME");
#ifdef _UNICOS #ifdef _UNICOS
/* Cray can define user privs drop all privs now! /* Cray can define user privs drop all privs now!
* Not needed on PRIV_SU systems! * 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 in default values for those options not explicitly set. */
fill_default_server_options(&options); fill_default_server_options(&options);
/* set default channel AF */
channel_set_af(options.address_family);
/* Check that there are no remaining arguments. */ /* Check that there are no remaining arguments. */
if (optind < ac) { if (optind < ac) {
fprintf(stderr, "Extra argument %s.\n", av[optind]); fprintf(stderr, "Extra argument %s.\n", av[optind]);
exit(1); exit(1);
} }
debug("sshd version %.100s", SSH_VERSION); debug("sshd version %.100s", SSH_RELEASE);
/* load private host keys */ /* load private host keys */
sensitive_data.host_keys = xmalloc(options.num_host_key_files * 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). */ /* 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_stderr = 1;
log_init(__progname, options.log_level, options.log_facility, log_stderr); 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) if (num_listen_socks >= MAX_LISTEN_SOCKS)
fatal("Too many listen sockets. " fatal("Too many listen sockets. "
"Enlarge MAX_LISTEN_SOCKS"); "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), ntop, sizeof(ntop), strport, sizeof(strport),
NI_NUMERICHOST|NI_NUMERICSERV) != 0) { NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
error("getnameinfo failed"); error("getnameinfo failed: %.100s",
(ret != EAI_SYSTEM) ? gai_strerror(ret) :
strerror(errno));
continue; continue;
} }
/* Create socket for listening. */ /* Create socket for listening. */
@ -1512,7 +1509,8 @@ main(int ac, char **av)
sock_in = newsock; sock_in = newsock;
sock_out = newsock; sock_out = newsock;
log_init(__progname, options.log_level, options.log_facility, log_stderr); log_init(__progname, options.log_level, options.log_facility, log_stderr);
close(config_s[0]); if (rexec_flag)
close(config_s[0]);
break; break;
} }
} }
@ -1648,6 +1646,9 @@ main(int ac, char **av)
remote_port = get_remote_port(); remote_port = get_remote_port();
remote_ip = get_remote_ipaddr(); remote_ip = get_remote_ipaddr();
#ifdef SSH_AUDIT_EVENTS
audit_connection_from(remote_ip, remote_port);
#endif
#ifdef LIBWRAP #ifdef LIBWRAP
/* Check whether logins are denied from this host. */ /* Check whether logins are denied from this host. */
if (packet_connection_is_on_socket()) { if (packet_connection_is_on_socket()) {
@ -1684,23 +1685,22 @@ main(int ac, char **av)
packet_set_nonblocking(); packet_set_nonblocking();
/* prepare buffers to collect authentication messages */
buffer_init(&loginmsg);
/* allocate authentication context */ /* allocate authentication context */
authctxt = xmalloc(sizeof(*authctxt)); authctxt = xmalloc(sizeof(*authctxt));
memset(authctxt, 0, sizeof(*authctxt)); memset(authctxt, 0, sizeof(*authctxt));
authctxt->loginmsg = &loginmsg;
/* XXX global for cleanup, access from other modules */ /* XXX global for cleanup, access from other modules */
the_authctxt = authctxt; the_authctxt = authctxt;
/* prepare buffer to collect messages to display to user after login */
buffer_init(&loginmsg);
if (use_privsep) if (use_privsep)
if (privsep_preauth(authctxt) == 1) if (privsep_preauth(authctxt) == 1)
goto authenticated; goto authenticated;
/* prepare buffer to collect messages to display to user after login */
buffer_init(&loginmsg);
/* perform the key exchange */ /* perform the key exchange */
/* authenticate user and start session */ /* authenticate user and start session */
if (compat20) { if (compat20) {
@ -1720,6 +1720,10 @@ main(int ac, char **av)
} }
authenticated: authenticated:
#ifdef SSH_AUDIT_EVENTS
audit_event(SSH_AUTH_SUCCESS);
#endif
/* /*
* In privilege separation, we fork another child and prepare * In privilege separation, we fork another child and prepare
* file descriptor passing. * file descriptor passing.
@ -1742,6 +1746,10 @@ main(int ac, char **av)
finish_pam(); finish_pam();
#endif /* USE_PAM */ #endif /* USE_PAM */
#ifdef SSH_AUDIT_EVENTS
PRIVSEP(audit_event(SSH_CONNECTION_CLOSE));
#endif
packet_close(); packet_close();
if (use_privsep) if (use_privsep)
@ -2033,5 +2041,10 @@ cleanup_exit(int i)
{ {
if (the_authctxt) if (the_authctxt)
do_cleanup(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); _exit(i);
} }

View File

@ -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$ # $FreeBSD$
# This is the sshd server system-wide configuration file. See # 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 # Note that some of FreeBSD's defaults differ from OpenBSD's, and
# FreeBSD has a few additional options. # FreeBSD has a few additional options.
#VersionAddendum FreeBSD-20041028 #VersionAddendum FreeBSD-20050605
#Port 22 #Port 22
#Protocol 2 #Protocol 2
#AddressFamily any
#ListenAddress 0.0.0.0 #ListenAddress 0.0.0.0
#ListenAddress :: #ListenAddress ::

View File

@ -34,7 +34,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" THIS SOFTWARE, 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$ .\" $FreeBSD$
.Dd September 25, 1999 .Dd September 25, 1999
.Dt SSHD_CONFIG 5 .Dt SSHD_CONFIG 5
@ -84,6 +84,17 @@ Be warned that some environment variables could be used to bypass restricted
user environments. user environments.
For this reason, care should be taken in the use of this directive. For this reason, care should be taken in the use of this directive.
The default is not to accept any environment variables. 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 .It Cm AllowGroups
This keyword can be followed by a list of group name patterns, separated This keyword can be followed by a list of group name patterns, separated
by spaces. by spaces.
@ -253,12 +264,15 @@ This prevents other remote hosts from connecting to forwarded ports.
.Cm GatewayPorts .Cm GatewayPorts
can be used to specify that can be used to specify that
.Nm sshd .Nm sshd
should bind remote port forwardings to the wildcard address, should allow remote port forwardings to bind to non-loopback addresses, thus
thus allowing remote hosts to connect to forwarded ports. allowing other hosts to connect.
The argument must be The argument may be
.Dq no
to force remote port forwardings to be available to the local host only,
.Dq yes .Dq yes
or to force remote port forwardings to bind to the wildcard address, or
.Dq no . .Dq clientspecified
to allow the client to select the address to which the forwarding is bound.
The default is The default is
.Dq no . .Dq no .
.It Cm GSSAPIAuthentication .It Cm GSSAPIAuthentication
@ -476,7 +490,7 @@ server allows login to accounts with empty password strings.
The default is The default is
.Dq no . .Dq no .
.It Cm PermitRootLogin .It Cm PermitRootLogin
Specifies whether root can login using Specifies whether root can log in using
.Xr ssh 1 . .Xr ssh 1 .
The argument must be The argument must be
.Dq yes , .Dq yes ,
@ -496,9 +510,7 @@ the root user may be allowed in with its password even if
.Pp .Pp
If this option is set to If this option is set to
.Dq without-password .Dq without-password
password authentication is disabled for root. Note that other authentication password authentication is disabled for root.
methods (e.g., keyboard-interactive/PAM) may still allow root to login using
a password.
.Pp .Pp
If this option is set to If this option is set to
.Dq forced-commands-only .Dq forced-commands-only
@ -512,7 +524,7 @@ All other authentication methods are disabled for root.
.Pp .Pp
If this option is set to If this option is set to
.Dq no .Dq no
root is not allowed to login. root is not allowed to log in.
.It Cm PermitUserEnvironment .It Cm PermitUserEnvironment
Specifies whether Specifies whether
.Pa ~/.ssh/environment .Pa ~/.ssh/environment
@ -544,7 +556,8 @@ See also
.It Cm PrintLastLog .It Cm PrintLastLog
Specifies whether Specifies whether
.Nm sshd .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 The default is
.Dq yes . .Dq yes .
.It Cm PrintMotd .It Cm PrintMotd
@ -647,7 +660,7 @@ To disable TCP keepalive messages, the value should be set to
.It Cm UseDNS .It Cm UseDNS
Specifies whether Specifies whether
.Nm sshd .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 the resolved host name for the remote IP address maps back to the
very same IP address. very same IP address.
The default is The default is
@ -707,7 +720,7 @@ The default is
Specifies a string to append to the regular version string to identify Specifies a string to append to the regular version string to identify
OS- or site-specific modifications. OS- or site-specific modifications.
The default is The default is
.Dq FreeBSD-20041028 . .Dq FreeBSD-20050605 .
.It Cm X11DisplayOffset .It Cm X11DisplayOffset
Specifies the first display number available for Specifies the first display number available for
.Nm sshd Ns 's .Nm sshd Ns 's

View File

@ -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$ */ /* $FreeBSD$ */
#ifndef SSH_VERSION #ifndef SSH_VERSION
#define SSH_VERSION (ssh_version_get()) #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" #define SSH_VERSION_ADDENDUM "FreeBSD-20041028"
const char *ssh_version_get(void); const char *ssh_version_get(void);