Merge conflicts.

MFC after:	1 week
This commit is contained in:
Dag-Erling Smørgrav 2006-09-30 13:38:06 +00:00
parent a4f3c15342
commit 333ee03933
69 changed files with 3354 additions and 1978 deletions

View File

@ -287,6 +287,8 @@ OpenSSH contains no GPL code.
Internet Software Consortium.
Todd C. Miller
Reyk Floeter
Chad Mynhier
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above

View File

@ -1,3 +1,4 @@
/* $OpenBSD: auth-chall.c,v 1.12 2006/08/03 03:34:41 deraadt Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@ -23,12 +24,17 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth-chall.c,v 1.9 2003/11/03 09:03:37 djm Exp $");
RCSID("$FreeBSD$");
__RCSID("$FreeBSD$");
#include <sys/types.h>
#include <stdarg.h>
#include "xmalloc.h"
#include "key.h"
#include "hostfile.h"
#include "auth.h"
#include "log.h"
#include "xmalloc.h"
#include "servconf.h"
/* limited protocol v1 interface to kbd-interactive authentication */

View File

@ -1,3 +1,4 @@
/* $OpenBSD: auth-krb5.c,v 1.19 2006/08/03 03:34:41 deraadt Exp $ */
/*
* Kerberos v5 authentication and ticket-passing routines.
*
@ -28,19 +29,28 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth-krb5.c,v 1.16 2005/11/21 09:42:10 dtucker Exp $");
RCSID("$FreeBSD$");
__RCSID("$FreeBSD$");
#include <sys/types.h>
#include <pwd.h>
#include <stdarg.h>
#include "xmalloc.h"
#include "ssh.h"
#include "ssh1.h"
#include "packet.h"
#include "xmalloc.h"
#include "log.h"
#include "buffer.h"
#include "servconf.h"
#include "uidswap.h"
#include "key.h"
#include "hostfile.h"
#include "auth.h"
#ifdef KRB5
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <krb5.h>
extern ServerOptions options;

View File

@ -47,8 +47,17 @@
/* Based on $xFreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */
#include "includes.h"
RCSID("$Id: auth-pam.c,v 1.128 2006/01/29 05:46:13 dtucker Exp $");
RCSID("$FreeBSD$");
__RCSID("$FreeBSD$");
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <errno.h>
#include <signal.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#ifdef USE_PAM
#if defined(HAVE_SECURITY_PAM_APPL_H)
@ -64,20 +73,31 @@ RCSID("$FreeBSD$");
# define sshpam_const const /* LinuxPAM, OpenPAM */
#endif
/* Ambiguity in spec: is it an array of pointers or a pointer to an array? */
#ifdef PAM_SUN_CODEBASE
# define PAM_MSG_MEMBER(msg, n, member) ((*(msg))[(n)].member)
#else
# define PAM_MSG_MEMBER(msg, n, member) ((msg)[(n)]->member)
#endif
#include "xmalloc.h"
#include "buffer.h"
#include "key.h"
#include "hostfile.h"
#include "auth.h"
#include "auth-pam.h"
#include "buffer.h"
#include "bufaux.h"
#include "canohost.h"
#include "log.h"
#include "monitor_wrap.h"
#include "msg.h"
#include "packet.h"
#include "misc.h"
#include "servconf.h"
#include "ssh2.h"
#include "xmalloc.h"
#include "auth-options.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
#include "monitor_wrap.h"
extern ServerOptions options;
extern Buffer loginmsg;
@ -147,14 +167,16 @@ sshpam_sigchld_handler(int sig)
fatal("PAM: authentication thread exited uncleanly");
}
/* ARGSUSED */
static void
pthread_exit(void *value __unused)
pthread_exit(void *value)
{
_exit(0);
}
/* ARGSUSED */
static int
pthread_create(sp_pthread_t *thread, const void *attr __unused,
pthread_create(sp_pthread_t *thread, const void *attr,
void *(*thread_start)(void *), void *arg)
{
pid_t pid;
@ -186,8 +208,9 @@ pthread_cancel(sp_pthread_t thread)
return (kill(thread, SIGTERM));
}
/* ARGSUSED */
static int
pthread_join(sp_pthread_t thread, void **value __unused)
pthread_join(sp_pthread_t thread, void **value)
{
int status;
@ -285,7 +308,10 @@ import_environments(Buffer *b)
/* Import environment from subprocess */
num_env = buffer_get_int(b);
sshpam_env = xmalloc((num_env + 1) * sizeof(*sshpam_env));
if (num_env > 1024)
fatal("%s: received %u environment variables, expected <= 1024",
__func__, num_env);
sshpam_env = xcalloc(num_env + 1, sizeof(*sshpam_env));
debug3("PAM: num env strings %d", num_env);
for(i = 0; i < num_env; i++)
sshpam_env[i] = buffer_get_string(b, NULL);
@ -332,9 +358,8 @@ sshpam_thread_conv(int n, sshpam_const struct pam_message **msg,
if (n <= 0 || n > PAM_MAX_NUM_MSG)
return (PAM_CONV_ERR);
if ((reply = malloc(n * sizeof(*reply))) == NULL)
if ((reply = calloc(n, sizeof(*reply))) == NULL)
return (PAM_CONV_ERR);
memset(reply, 0, n * sizeof(*reply));
buffer_init(&buffer);
for (i = 0; i < n; ++i) {
@ -413,10 +438,16 @@ sshpam_thread(void *ctxtp)
u_int i;
const char *pam_user;
const char **ptr_pam_user = &pam_user;
char *tz = getenv("TZ");
pam_get_item(sshpam_handle, PAM_USER,
(sshpam_const void **)ptr_pam_user);
environ[0] = NULL;
if (tz != NULL)
if (setenv("TZ", tz, 1) == -1)
error("PAM: could not set TZ environment: %s",
strerror(errno));
if (sshpam_authctxt != NULL) {
setproctitle("%s [pam]",
@ -440,8 +471,10 @@ sshpam_thread(void *ctxtp)
goto auth_fail;
if (compat20) {
if (!do_pam_account())
if (!do_pam_account()) {
sshpam_err = PAM_ACCT_EXPIRED;
goto auth_fail;
}
if (sshpam_authctxt->force_pwchange) {
sshpam_err = pam_chauthtok(sshpam_handle,
PAM_CHANGE_EXPIRED_AUTHTOK);
@ -483,7 +516,10 @@ sshpam_thread(void *ctxtp)
buffer_put_cstring(&buffer,
pam_strerror(sshpam_handle, sshpam_err));
/* XXX - can't do much about an error here */
ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer);
if (sshpam_err == PAM_ACCT_EXPIRED)
ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, &buffer);
else
ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer);
buffer_free(&buffer);
pthread_exit(NULL);
@ -530,9 +566,8 @@ sshpam_store_conv(int n, sshpam_const struct pam_message **msg,
if (n <= 0 || n > PAM_MAX_NUM_MSG)
return (PAM_CONV_ERR);
if ((reply = malloc(n * sizeof(*reply))) == NULL)
if ((reply = calloc(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)) {
@ -639,8 +674,11 @@ sshpam_init_ctx(Authctxt *authctxt)
int socks[2];
debug3("PAM: %s entering", __func__);
/* Refuse to start if we don't have PAM enabled */
if (!options.use_pam)
/*
* Refuse to start if we don't have PAM enabled or do_pam_account
* has previously failed.
*/
if (!options.use_pam || sshpam_account_status == 0)
return NULL;
/* Initialize PAM */
@ -700,7 +738,7 @@ sshpam_query(void *ctx, char **name, char **info,
case PAM_PROMPT_ECHO_OFF:
*num = 1;
len = plen + mlen + 1;
**prompts = xrealloc(**prompts, len);
**prompts = xrealloc(**prompts, 1, len);
strlcpy(**prompts + plen, msg, len - plen);
plen += mlen;
**echo_on = (type == PAM_PROMPT_ECHO_ON);
@ -710,21 +748,25 @@ sshpam_query(void *ctx, char **name, char **info,
case PAM_TEXT_INFO:
/* accumulate messages */
len = plen + mlen + 2;
**prompts = xrealloc(**prompts, len);
**prompts = xrealloc(**prompts, 1, len);
strlcpy(**prompts + plen, msg, len - plen);
plen += mlen;
strlcat(**prompts + plen, "\n", len - plen);
plen++;
xfree(msg);
break;
case PAM_ACCT_EXPIRED:
sshpam_account_status = 0;
/* FALLTHROUGH */
case PAM_AUTH_ERR:
debug3("PAM: PAM_AUTH_ERR");
debug3("PAM: %s", pam_strerror(sshpam_handle, type));
if (**prompts != NULL && strlen(**prompts) != 0) {
*info = **prompts;
**prompts = NULL;
*num = 0;
**echo_on = 0;
ctxt->pam_done = -1;
xfree(msg);
return 0;
}
/* FALLTHROUGH */
@ -931,9 +973,8 @@ sshpam_tty_conv(int n, sshpam_const struct pam_message **msg,
if (n <= 0 || n > PAM_MAX_NUM_MSG || !isatty(STDIN_FILENO))
return (PAM_CONV_ERR);
if ((reply = malloc(n * sizeof(*reply))) == NULL)
if ((reply = calloc(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)) {

View File

@ -1,3 +1,4 @@
/* $OpenBSD: auth-passwd.c,v 1.40 2006/08/03 03:34:41 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -36,13 +37,21 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth-passwd.c,v 1.34 2005/07/19 15:32:26 otto Exp $");
RCSID("$FreeBSD$");
__RCSID("$FreeBSD$");
#include <sys/types.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "packet.h"
#include "buffer.h"
#include "log.h"
#include "servconf.h"
#include "key.h"
#include "hostfile.h"
#include "auth.h"
#include "auth-options.h"

View File

@ -1,3 +1,4 @@
/* $OpenBSD: auth-rh-rsa.c,v 1.42 2006/08/03 03:34:41 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -13,18 +14,25 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth-rh-rsa.c,v 1.38 2005/07/17 07:17:54 djm Exp $");
#include <sys/types.h>
#include <pwd.h>
#include <stdarg.h>
#include "packet.h"
#include "uidswap.h"
#include "log.h"
#include "buffer.h"
#include "servconf.h"
#include "key.h"
#include "hostfile.h"
#include "pathnames.h"
#include "auth.h"
#include "canohost.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
#include "monitor_wrap.h"
/* import */

View File

@ -1,3 +1,4 @@
/* $OpenBSD: auth-rsa.c,v 1.71 2006/08/03 03:34:41 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -14,23 +15,35 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth-rsa.c,v 1.63 2005/06/17 02:44:32 djm Exp $");
#include <sys/types.h>
#include <sys/stat.h>
#include <openssl/rsa.h>
#include <openssl/md5.h>
#include <pwd.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "xmalloc.h"
#include "rsa.h"
#include "packet.h"
#include "xmalloc.h"
#include "ssh1.h"
#include "uidswap.h"
#include "match.h"
#include "buffer.h"
#include "auth-options.h"
#include "pathnames.h"
#include "log.h"
#include "servconf.h"
#include "auth.h"
#include "key.h"
#include "hostfile.h"
#include "auth.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
#include "monitor_wrap.h"
#include "ssh.h"
#include "misc.h"
@ -137,7 +150,7 @@ auth_rsa_challenge_dialog(Key *key)
/* Wait for a response. */
packet_read_expect(SSH_CMSG_AUTH_RSA_RESPONSE);
for (i = 0; i < 16; i++)
response[i] = packet_get_char();
response[i] = (u_char)packet_get_char();
packet_check_eom();
success = PRIVSEP(auth_rsa_verify_response(key, challenge, response));

View File

@ -1,3 +1,4 @@
/* $OpenBSD: auth-skey.c,v 1.26 2006/08/05 08:28:24 dtucker Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@ -21,12 +22,17 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
RCSID("$OpenBSD: auth-skey.c,v 1.20 2002/06/30 21:59:45 deraadt Exp $");
RCSID("$FreeBSD$");
__RCSID("$FreeBSD$");
#ifdef SKEY
#include <sys/types.h>
#include <pwd.h>
#include <stdio.h>
#ifdef OPIE
#include <opie.h>
#define skey opie
@ -38,7 +44,10 @@ RCSID("$FreeBSD$");
#endif
#include "xmalloc.h"
#include "key.h"
#include "hostfile.h"
#include "auth.h"
#include "ssh-gss.h"
#include "monitor_wrap.h"
static void *
@ -52,8 +61,7 @@ skey_query(void *ctx, char **name, char **infotxt,
u_int* numprompts, char ***prompts, u_int **echo_on)
{
Authctxt *authctxt = ctx;
char challenge[1024], *p;
int len;
char challenge[1024];
struct skey skey;
if (_compat_skeychallenge(&skey, authctxt->user, challenge,
@ -63,15 +71,10 @@ skey_query(void *ctx, char **name, char **infotxt,
*name = xstrdup("");
*infotxt = xstrdup("");
*numprompts = 1;
*prompts = xmalloc(*numprompts * sizeof(char *));
*echo_on = xmalloc(*numprompts * sizeof(u_int));
(*echo_on)[0] = 0;
*prompts = xcalloc(*numprompts, sizeof(char *));
*echo_on = xcalloc(*numprompts, sizeof(u_int));
len = strlen(challenge) + strlen(SKEY_PROMPT) + 1;
p = xmalloc(len);
strlcpy(p, challenge, len);
strlcat(p, SKEY_PROMPT, len);
(*prompts)[0] = p;
xasprintf(*prompts, "%s%s", challenge, SKEY_PROMPT);
return 0;
}

View File

@ -1,3 +1,4 @@
/* $OpenBSD: auth.c,v 1.75 2006/08/03 03:34:41 deraadt Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -23,40 +24,57 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth.c,v 1.60 2005/06/17 02:44:32 djm Exp $");
RCSID("$FreeBSD$");
__RCSID("$FreeBSD$");
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <errno.h>
#ifdef HAVE_PATHS_H
# include <paths.h>
#endif
#include <pwd.h>
#ifdef HAVE_LOGIN_H
#include <login.h>
#endif
#ifdef USE_SHADOW
#include <shadow.h>
#endif
#ifdef HAVE_LIBGEN_H
#include <libgen.h>
#endif
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "xmalloc.h"
#include "match.h"
#include "groupaccess.h"
#include "log.h"
#include "buffer.h"
#include "servconf.h"
#include "key.h"
#include "hostfile.h"
#include "auth.h"
#include "auth-options.h"
#include "canohost.h"
#include "buffer.h"
#include "bufaux.h"
#include "uidswap.h"
#include "misc.h"
#include "bufaux.h"
#include "packet.h"
#include "loginrec.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
#include "monitor_wrap.h"
/* import */
extern ServerOptions options;
extern int use_privsep;
extern Buffer loginmsg;
extern struct passwd *privsep_pw;
/* Debugging messages */
Buffer auth_debug;
@ -232,6 +250,9 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
void (*authlog) (const char *fmt,...) = verbose;
char *authmsg;
if (use_privsep && !mm_is_monitor() && !authctxt->postponed)
return;
/* Raise logging level */
if (authenticated == 1 ||
!authctxt->valid ||
@ -260,44 +281,15 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
strcmp(method, "challenge-response") == 0))
record_failed_login(authctxt->user,
get_canonical_hostname(options.use_dns), "ssh");
# ifdef WITH_AIXAUTHENTICATE
if (authenticated)
sys_auth_record_login(authctxt->user,
get_canonical_hostname(options.use_dns), "ssh", &loginmsg);
# endif
#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);
}
}
if (authenticated == 0 && !authctxt->postponed)
audit_event(audit_classify_auth(method));
#endif
}
@ -310,7 +302,6 @@ auth_root_allowed(char *method)
switch (options.permit_root_login) {
case PERMIT_YES:
return 1;
break;
case PERMIT_NO_PASSWD:
if (strcmp(method, "password") != 0)
return 1;
@ -337,7 +328,8 @@ auth_root_allowed(char *method)
static char *
expand_authorized_keys(const char *filename, struct passwd *pw)
{
char *file, *ret;
char *file, ret[MAXPATHLEN];
int i;
file = percent_expand(filename, "h", pw->pw_dir,
"u", pw->pw_name, (char *)NULL);
@ -349,14 +341,11 @@ expand_authorized_keys(const char *filename, struct passwd *pw)
if (*file == '/')
return (file);
ret = xmalloc(MAXPATHLEN);
if (strlcpy(ret, pw->pw_dir, MAXPATHLEN) >= MAXPATHLEN ||
strlcat(ret, "/", MAXPATHLEN) >= MAXPATHLEN ||
strlcat(ret, file, MAXPATHLEN) >= MAXPATHLEN)
i = snprintf(ret, sizeof(ret), "%s/%s", pw->pw_dir, file);
if (i < 0 || (size_t)i >= sizeof(ret))
fatal("expand_authorized_keys: path too long");
xfree(file);
return (ret);
return (xstrdup(ret));
}
char *
@ -493,6 +482,9 @@ getpwnamallow(const char *user)
#endif
struct passwd *pw;
parse_server_match_config(&options, user,
get_canonical_hostname(options.use_dns), get_remote_ipaddr());
pw = getpwnam(user);
if (pw == NULL) {
logit("Invalid user %.100s from %.100s",
@ -580,6 +572,8 @@ fakepw(void)
fake.pw_gecos = "NOUSER";
fake.pw_uid = (uid_t)-1;
fake.pw_gid = (gid_t)-1;
fake.pw_uid = privsep_pw->pw_uid;
fake.pw_gid = privsep_pw->pw_gid;
#ifdef HAVE_PW_CLASS_IN_PASSWD
fake.pw_class = "";
#endif

View File

@ -1,5 +1,5 @@
/* $OpenBSD: auth.h,v 1.51 2005/06/06 11:20:36 djm Exp $ */
/* $FreeBSD$ */
/* $OpenBSD: auth.h,v 1.58 2006/08/18 09:15:20 markus Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -29,9 +29,8 @@
#ifndef AUTH_H
#define AUTH_H
#include "key.h"
#include "hostfile.h"
#include "buffer.h"
#include <signal.h>
#include <openssl/rsa.h>
#ifdef HAVE_LOGIN_CAP
@ -49,7 +48,8 @@ typedef struct Authmethod Authmethod;
typedef struct KbdintDevice KbdintDevice;
struct Authctxt {
int success;
sig_atomic_t success;
int authenticated; /* authenticated and alarms cancelled */
int postponed; /* authentication needs another step */
int valid; /* user exists and is allowed to login */
int attempt;

View File

@ -1,3 +1,4 @@
/* $OpenBSD: auth1.c,v 1.70 2006/08/03 03:34:41 deraadt Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@ -10,8 +11,15 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth1.c,v 1.62 2005/07/16 01:35:24 djm Exp $");
RCSID("$FreeBSD$");
__RCSID("$FreeBSD$");
#include <sys/types.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pwd.h>
#include "xmalloc.h"
#include "rsa.h"
@ -21,10 +29,15 @@ RCSID("$FreeBSD$");
#include "log.h"
#include "servconf.h"
#include "compat.h"
#include "key.h"
#include "hostfile.h"
#include "auth.h"
#include "channels.h"
#include "session.h"
#include "uidswap.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
#include "monitor_wrap.h"
#include "buffer.h"
@ -78,7 +91,7 @@ static const struct AuthMethod1
{
int i;
for(i = 0; auth1_methods[i].name != NULL; i++)
for (i = 0; auth1_methods[i].name != NULL; i++)
if (auth1_methods[i].type == type)
return (&(auth1_methods[i]));
@ -97,6 +110,7 @@ get_authname(int type)
return (buf);
}
/*ARGSUSED*/
static int
auth1_process_password(Authctxt *authctxt, char *info, size_t infolen)
{
@ -121,6 +135,7 @@ auth1_process_password(Authctxt *authctxt, char *info, size_t infolen)
return (authenticated);
}
/*ARGSUSED*/
static int
auth1_process_rsa(Authctxt *authctxt, char *info, size_t infolen)
{
@ -138,6 +153,7 @@ auth1_process_rsa(Authctxt *authctxt, char *info, size_t infolen)
return (authenticated);
}
/*ARGSUSED*/
static int
auth1_process_rhosts_rsa(Authctxt *authctxt, char *info, size_t infolen)
{
@ -176,6 +192,7 @@ auth1_process_rhosts_rsa(Authctxt *authctxt, char *info, size_t infolen)
return (authenticated);
}
/*ARGSUSED*/
static int
auth1_process_tis_challenge(Authctxt *authctxt, char *info, size_t infolen)
{
@ -194,6 +211,7 @@ auth1_process_tis_challenge(Authctxt *authctxt, char *info, size_t infolen)
return (-1);
}
/*ARGSUSED*/
static int
auth1_process_tis_response(Authctxt *authctxt, char *info, size_t infolen)
{

View File

@ -1,3 +1,4 @@
/* $OpenBSD: auth2-chall.c,v 1.31 2006/08/05 08:28:24 dtucker Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2001 Per Allansson. All rights reserved.
@ -22,15 +23,23 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
RCSID("$OpenBSD: auth2-chall.c,v 1.24 2005/07/17 07:17:54 djm Exp $");
RCSID("$FreeBSD$");
#include "includes.h"
__RCSID("$FreeBSD$");
#include <sys/types.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "xmalloc.h"
#include "ssh2.h"
#include "key.h"
#include "hostfile.h"
#include "auth.h"
#include "buffer.h"
#include "packet.h"
#include "xmalloc.h"
#include "dispatch.h"
#include "log.h"
#include "servconf.h"
@ -292,7 +301,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
if (nresp > 100)
fatal("input_userauth_info_response: too many replies");
if (nresp > 0) {
response = xmalloc(nresp * sizeof(char *));
response = xcalloc(nresp, sizeof(char *));
for (i = 0; i < nresp; i++)
response[i] = packet_get_string(NULL);
}

View File

@ -1,3 +1,4 @@
/* $OpenBSD: auth2-kbdint.c,v 1.5 2006/08/03 03:34:41 deraadt Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -23,14 +24,20 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth2-kbdint.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
RCSID("$FreeBSD$");
__RCSID("$FreeBSD$");
#include <sys/types.h>
#include <stdarg.h>
#include "xmalloc.h"
#include "packet.h"
#include "key.h"
#include "hostfile.h"
#include "auth.h"
#include "log.h"
#include "buffer.h"
#include "servconf.h"
#include "xmalloc.h"
/* import */
extern ServerOptions options;

View File

@ -1,3 +1,4 @@
/* $OpenBSD: auth2.c,v 1.113 2006/08/03 03:34:41 deraadt Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -23,25 +24,33 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth2.c,v 1.107 2004/07/28 09:40:29 markus Exp $");
RCSID("$FreeBSD$");
__RCSID("$FreeBSD$");
#include <sys/types.h>
#include <pwd.h>
#include <stdarg.h>
#include <string.h>
#include "canohost.h"
#include "ssh2.h"
#include "xmalloc.h"
#include "ssh2.h"
#include "packet.h"
#include "log.h"
#include "buffer.h"
#include "servconf.h"
#include "compat.h"
#include "key.h"
#include "hostfile.h"
#include "auth.h"
#include "dispatch.h"
#include "pathnames.h"
#include "monitor_wrap.h"
#include "buffer.h"
#include "canohost.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
#include "monitor_wrap.h"
/* import */
extern ServerOptions options;
@ -98,6 +107,7 @@ do_authentication2(Authctxt *authctxt)
dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt);
}
/*ARGSUSED*/
static void
input_service_request(int type, u_int32_t seq, void *ctxt)
{
@ -131,6 +141,7 @@ input_service_request(int type, u_int32_t seq, void *ctxt)
xfree(service);
}
/*ARGSUSED*/
static void
input_userauth_request(int type, u_int32_t seq, void *ctxt)
{

View File

@ -1,3 +1,4 @@
/* $OpenBSD: authfd.c,v 1.80 2006/08/03 03:34:41 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -35,16 +36,25 @@
*/
#include "includes.h"
RCSID("$OpenBSD: authfd.c,v 1.66 2005/06/17 02:44:32 djm Exp $");
#include <sys/types.h>
#include <sys/un.h>
#include <sys/socket.h>
#include <openssl/evp.h>
#include <openssl/crypto.h>
#include <fcntl.h>
#include <stdlib.h>
#include <signal.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include "xmalloc.h"
#include "ssh.h"
#include "rsa.h"
#include "buffer.h"
#include "bufaux.h"
#include "xmalloc.h"
#include "getput.h"
#include "key.h"
#include "authfd.h"
#include "cipher.h"
@ -52,6 +62,7 @@ RCSID("$OpenBSD: authfd.c,v 1.66 2005/06/17 02:44:32 djm Exp $");
#include "compat.h"
#include "log.h"
#include "atomicio.h"
#include "misc.h"
static int agent_present = 0;
@ -103,7 +114,7 @@ ssh_get_authentication_socket(void)
close(sock);
return -1;
}
if (connect(sock, (struct sockaddr *) &sunaddr, sizeof sunaddr) < 0) {
if (connect(sock, (struct sockaddr *)&sunaddr, sizeof sunaddr) < 0) {
close(sock);
return -1;
}
@ -119,7 +130,7 @@ ssh_request_reply(AuthenticationConnection *auth, Buffer *request, Buffer *reply
/* Get the length of the message, and format it in the buffer. */
len = buffer_len(request);
PUT_32BIT(buf, len);
put_u32(buf, len);
/* Send the length and then the packet to the agent. */
if (atomicio(vwrite, auth->fd, buf, 4) != 4 ||
@ -138,7 +149,7 @@ ssh_request_reply(AuthenticationConnection *auth, Buffer *request, Buffer *reply
}
/* Extract the length, and check it for sanity. */
len = GET_32BIT(buf);
len = get_u32(buf);
if (len > 256 * 1024)
fatal("Authentication response too long: %u", len);
@ -335,7 +346,6 @@ ssh_get_next_identity(AuthenticationConnection *auth, char **comment, int versio
break;
default:
return NULL;
break;
}
/* Decrement the number of remaining entries. */
auth->howmany--;
@ -394,7 +404,7 @@ ssh_decrypt_challenge(AuthenticationConnection *auth,
* fatal error if the packet is corrupt.
*/
for (i = 0; i < 16; i++)
response[i] = buffer_get_char(&buffer);
response[i] = (u_char)buffer_get_char(&buffer);
}
buffer_free(&buffer);
return success;
@ -517,7 +527,6 @@ ssh_add_identity_constrained(AuthenticationConnection *auth, Key *key,
default:
buffer_free(&msg);
return 0;
break;
}
if (constrained) {
if (life != 0) {

View File

@ -1,3 +1,4 @@
/* $OpenBSD: authfile.c,v 1.76 2006/08/03 03:34:41 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -36,16 +37,27 @@
*/
#include "includes.h"
RCSID("$OpenBSD: authfile.c,v 1.61 2005/06/17 02:44:32 djm Exp $");
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/uio.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include "cipher.h"
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "xmalloc.h"
#include "cipher.h"
#include "buffer.h"
#include "bufaux.h"
#include "key.h"
#include "ssh.h"
#include "log.h"
@ -184,7 +196,7 @@ key_save_private_pem(Key *key, const char *filename, const char *_passphrase,
return 0;
}
fp = fdopen(fd, "w");
if (fp == NULL ) {
if (fp == NULL) {
error("fdopen %s failed: %s.", filename, strerror(errno));
close(fd);
return 0;
@ -211,12 +223,10 @@ key_save_private(Key *key, const char *filename, const char *passphrase,
case KEY_RSA1:
return key_save_private_rsa1(key, filename, passphrase,
comment);
break;
case KEY_DSA:
case KEY_RSA:
return key_save_private_pem(key, filename, passphrase,
comment);
break;
default:
break;
}
@ -507,7 +517,7 @@ key_load_private_pem(int fd, int type, const char *passphrase,
return prv;
}
static int
int
key_perm_ok(int fd, const char *filename)
{
struct stat st;
@ -537,7 +547,7 @@ key_perm_ok(int fd, const char *filename)
Key *
key_load_private_type(int type, const char *filename, const char *passphrase,
char **commentp)
char **commentp, int *perm_ok)
{
int fd;
@ -545,22 +555,24 @@ key_load_private_type(int type, const char *filename, const char *passphrase,
if (fd < 0)
return NULL;
if (!key_perm_ok(fd, filename)) {
if (perm_ok != NULL)
*perm_ok = 0;
error("bad permissions: ignore key: %s", filename);
close(fd);
return NULL;
}
if (perm_ok != NULL)
*perm_ok = 1;
switch (type) {
case KEY_RSA1:
return key_load_private_rsa1(fd, filename, passphrase,
commentp);
/* closes fd */
break;
case KEY_DSA:
case KEY_RSA:
case KEY_UNSPEC:
return key_load_private_pem(fd, type, passphrase, commentp);
/* closes fd */
break;
default:
close(fd);
break;

View File

@ -1,3 +1,4 @@
/* $OpenBSD: bufaux.c,v 1.44 2006/08/03 03:34:41 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -37,177 +38,19 @@
*/
#include "includes.h"
RCSID("$OpenBSD: bufaux.c,v 1.37 2005/11/05 05:01:15 djm Exp $");
RCSID("$FreeBSD$");
__RCSID("$FreeBSD$");
#include <sys/types.h>
#include <openssl/bn.h>
#include "bufaux.h"
#include <string.h>
#include <stdarg.h>
#include "xmalloc.h"
#include "getput.h"
#include "buffer.h"
#include "log.h"
/*
* 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.
*/
int
buffer_put_bignum_ret(Buffer *buffer, const BIGNUM *value)
{
int bits = BN_num_bits(value);
int bin_size = (bits + 7) / 8;
u_char *buf = xmalloc(bin_size);
int oi;
char msg[2];
/* Get the value of in binary */
oi = BN_bn2bin(value, buf);
if (oi != bin_size) {
error("buffer_put_bignum_ret: BN_bn2bin() failed: oi %d != bin_size %d",
oi, bin_size);
xfree(buf);
return (-1);
}
/* Store the number of bits in the buffer in two bytes, msb first. */
PUT_16BIT(msg, bits);
buffer_append(buffer, msg, 2);
/* Store the binary data. */
buffer_append(buffer, (char *)buf, oi);
memset(buf, 0, bin_size);
xfree(buf);
return (0);
}
void
buffer_put_bignum(Buffer *buffer, const BIGNUM *value)
{
if (buffer_put_bignum_ret(buffer, value) == -1)
fatal("buffer_put_bignum: buffer error");
}
/*
* Retrieves an BIGNUM from the buffer.
*/
int
buffer_get_bignum_ret(Buffer *buffer, BIGNUM *value)
{
u_int bits, bytes;
u_char buf[2], *bin;
/* Get the number for bits. */
if (buffer_get_ret(buffer, (char *) buf, 2) == -1) {
error("buffer_get_bignum_ret: invalid length");
return (-1);
}
bits = GET_16BIT(buf);
/* Compute the number of binary bytes that follow. */
bytes = (bits + 7) / 8;
if (bytes > 8 * 1024) {
error("buffer_get_bignum_ret: cannot handle BN of size %d", bytes);
return (-1);
}
if (buffer_len(buffer) < bytes) {
error("buffer_get_bignum_ret: input buffer too small");
return (-1);
}
bin = buffer_ptr(buffer);
BN_bin2bn(bin, bytes, value);
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.
*/
int
buffer_put_bignum2_ret(Buffer *buffer, const BIGNUM *value)
{
u_int bytes;
u_char *buf;
int oi;
u_int hasnohigh = 0;
if (BN_is_zero(value)) {
buffer_put_int(buffer, 0);
return 0;
}
if (value->neg) {
error("buffer_put_bignum2_ret: negative numbers not supported");
return (-1);
}
bytes = BN_num_bytes(value) + 1; /* extra padding byte */
if (bytes < 2) {
error("buffer_put_bignum2_ret: BN too small");
return (-1);
}
buf = xmalloc(bytes);
buf[0] = 0x00;
/* Get the value of in binary */
oi = BN_bn2bin(value, buf+1);
if (oi < 0 || (u_int)oi != bytes - 1) {
error("buffer_put_bignum2_ret: BN_bn2bin() failed: "
"oi %d != bin_size %d", oi, bytes);
xfree(buf);
return (-1);
}
hasnohigh = (buf[1] & 0x80) ? 0 : 1;
buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh);
memset(buf, 0, bytes);
xfree(buf);
return (0);
}
void
buffer_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");
xfree(bin);
return (-1);
}
if (len > 8 * 1024) {
error("buffer_get_bignum2_ret: cannot handle BN of size %d", len);
xfree(bin);
return (-1);
}
BN_bin2bn(bin, len, value);
xfree(bin);
return (0);
}
void
buffer_get_bignum2(Buffer *buffer, BIGNUM *value)
{
if (buffer_get_bignum2_ret(buffer, value) == -1)
fatal("buffer_get_bignum2: buffer error");
}
#include "misc.h"
/*
* Returns integers from the buffer (msb first).
@ -220,7 +63,7 @@ buffer_get_short_ret(u_short *ret, Buffer *buffer)
if (buffer_get_ret(buffer, (char *) buf, 2) == -1)
return (-1);
*ret = GET_16BIT(buf);
*ret = get_u16(buf);
return (0);
}
@ -242,7 +85,7 @@ buffer_get_int_ret(u_int *ret, Buffer *buffer)
if (buffer_get_ret(buffer, (char *) buf, 4) == -1)
return (-1);
*ret = GET_32BIT(buf);
*ret = get_u32(buf);
return (0);
}
@ -264,7 +107,7 @@ buffer_get_int64_ret(u_int64_t *ret, Buffer *buffer)
if (buffer_get_ret(buffer, (char *) buf, 8) == -1)
return (-1);
*ret = GET_64BIT(buf);
*ret = get_u64(buf);
return (0);
}
@ -287,7 +130,7 @@ buffer_put_short(Buffer *buffer, u_short value)
{
char buf[2];
PUT_16BIT(buf, value);
put_u16(buf, value);
buffer_append(buffer, buf, 2);
}
@ -296,7 +139,7 @@ buffer_put_int(Buffer *buffer, u_int value)
{
char buf[4];
PUT_32BIT(buf, value);
put_u32(buf, value);
buffer_append(buffer, buf, 4);
}
@ -305,7 +148,7 @@ buffer_put_int64(Buffer *buffer, u_int64_t value)
{
char buf[8];
PUT_64BIT(buf, value);
put_u64(buf, value);
buffer_append(buffer, buf, 8);
}

View File

@ -1,3 +1,4 @@
/* $OpenBSD: canohost.c,v 1.61 2006/08/03 03:34:41 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -12,10 +13,23 @@
*/
#include "includes.h"
RCSID("$OpenBSD: canohost.c,v 1.48 2005/12/28 22:46:06 stevesk Exp $");
#include "packet.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "xmalloc.h"
#include "packet.h"
#include "log.h"
#include "canohost.h"
@ -43,6 +57,9 @@ get_remote_hostname(int sock, int use_dns)
cleanup_exit(255);
}
if (from.ss_family == AF_INET)
check_ip_options(sock, ntop);
ipv64_normalise_mapped(&from, &fromlen);
if (from.ss_family == AF_INET6)
@ -52,9 +69,6 @@ get_remote_hostname(int sock, int use_dns)
NULL, 0, NI_NUMERICHOST) != 0)
fatal("get_remote_hostname: getnameinfo NI_NUMERICHOST failed");
if (from.ss_family == AF_INET)
check_ip_options(sock, ntop);
if (!use_dns)
return xstrdup(ntop);
@ -87,7 +101,7 @@ get_remote_hostname(int sock, int use_dns)
*/
for (i = 0; name[i]; i++)
if (isupper(name[i]))
name[i] = tolower(name[i]);
name[i] = (char)tolower(name[i]);
/*
* Map it back to an IP address and check that the given
* address actually is an address of this host. This is
@ -102,7 +116,7 @@ get_remote_hostname(int sock, int use_dns)
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(name, NULL, &hints, &aitop) != 0) {
logit("reverse mapping checking getaddrinfo for %.700s "
"failed - POSSIBLE BREAK-IN ATTEMPT!", name);
"[%s] failed - POSSIBLE BREAK-IN ATTEMPT!", name, ntop);
return xstrdup(ntop);
}
/* Look for the address from the list of addresses. */

View File

@ -1,3 +1,4 @@
/* $OpenBSD: channels.c,v 1.266 2006/08/29 10:40:18 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -39,22 +40,41 @@
*/
#include "includes.h"
RCSID("$OpenBSD: channels.c,v 1.232 2006/01/30 12:22:22 reyk Exp $");
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/un.h>
#include <sys/socket.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <stdarg.h>
#include "xmalloc.h"
#include "ssh.h"
#include "ssh1.h"
#include "ssh2.h"
#include "packet.h"
#include "xmalloc.h"
#include "log.h"
#include "misc.h"
#include "buffer.h"
#include "channels.h"
#include "compat.h"
#include "canohost.h"
#include "key.h"
#include "authfd.h"
#include "pathnames.h"
#include "bufaux.h"
/* -- channel core */
@ -91,11 +111,18 @@ typedef struct {
u_short listen_port; /* Remote side should listen port number. */
} ForwardPermission;
/* List of all permitted host/port pairs to connect. */
/* List of all permitted host/port pairs to connect by the user. */
static ForwardPermission permitted_opens[SSH_MAX_FORWARDS_PER_DIRECTION];
/* Number of permitted host/port pairs in the array. */
/* List of all permitted host/port pairs to connect by the admin. */
static ForwardPermission permitted_adm_opens[SSH_MAX_FORWARDS_PER_DIRECTION];
/* Number of permitted host/port pairs in the array permitted by the user. */
static int num_permitted_opens = 0;
/* Number of permitted host/port pair in the array permitted by the admin. */
static int num_adm_permitted_opens = 0;
/*
* If this is true, all opens are permitted. This is the case on the server
* on which we have to trust the client anyway, and the user could do
@ -123,7 +150,7 @@ static u_int x11_saved_data_len = 0;
* Fake X11 authentication data. This is what the server will be sending us;
* we should replace any occurrences of this by the real data.
*/
static char *x11_fake_data = NULL;
static u_char *x11_fake_data = NULL;
static u_int x11_fake_data_len;
@ -168,7 +195,7 @@ channel_lookup(int id)
if ((c = channel_by_id(id)) == NULL)
return (NULL);
switch(c->type) {
switch (c->type) {
case SSH_CHANNEL_X11_OPEN:
case SSH_CHANNEL_LARVAL:
case SSH_CHANNEL_CONNECTING:
@ -178,7 +205,6 @@ channel_lookup(int id)
case SSH_CHANNEL_INPUT_DRAINING:
case SSH_CHANNEL_OUTPUT_DRAINING:
return (c);
break;
}
logit("Non-public channel %d, type %d.", id, c->type);
return (NULL);
@ -188,7 +214,6 @@ channel_lookup(int id)
* Register filedescriptors for a channel, used when allocating a channel or
* when the channel consumer/producer is ready, e.g. shell exec'd
*/
static void
channel_register_fds(Channel *c, int rfd, int wfd, int efd,
int extusage, int nonblock)
@ -235,7 +260,6 @@ channel_register_fds(Channel *c, int rfd, int wfd, int efd,
* Allocate a new channel object and set its type and socket. This will cause
* remote_name to be freed.
*/
Channel *
channel_new(char *ctype, int type, int rfd, int wfd, int efd,
u_int window, u_int maxpack, int extusage, char *remote_name, int nonblock)
@ -247,7 +271,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
/* Do initial allocation if this is the first call. */
if (channels_alloc == 0) {
channels_alloc = 10;
channels = xmalloc(channels_alloc * sizeof(Channel *));
channels = xcalloc(channels_alloc, sizeof(Channel *));
for (i = 0; i < channels_alloc; i++)
channels[i] = NULL;
}
@ -264,16 +288,15 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
if (channels_alloc > 10000)
fatal("channel_new: internal error: channels_alloc %d "
"too big.", channels_alloc);
channels = xrealloc(channels,
(channels_alloc + 10) * sizeof(Channel *));
channels = xrealloc(channels, channels_alloc + 10,
sizeof(Channel *));
channels_alloc += 10;
debug2("channel: expanding %d", channels_alloc);
for (i = found; i < channels_alloc; i++)
channels[i] = NULL;
}
/* Initialize and return new channel. */
c = channels[found] = xmalloc(sizeof(Channel));
memset(c, 0, sizeof(Channel));
c = channels[found] = xcalloc(1, sizeof(Channel));
buffer_init(&c->input);
buffer_init(&c->output);
buffer_init(&c->extended);
@ -337,7 +360,6 @@ channel_close_fd(int *fdp)
}
/* Close all channel fd/socket. */
static void
channel_close_fds(Channel *c)
{
@ -352,7 +374,6 @@ channel_close_fds(Channel *c)
}
/* Free the channel and close its fd/socket. */
void
channel_free(Channel *c)
{
@ -399,7 +420,6 @@ channel_free_all(void)
* Closes the sockets/fds of all channels. This is used to close extra file
* descriptors after a fork.
*/
void
channel_close_all(void)
{
@ -413,7 +433,6 @@ channel_close_all(void)
/*
* Stop listening to channels.
*/
void
channel_stop_listening(void)
{
@ -440,7 +459,6 @@ channel_stop_listening(void)
* Returns true if no channel has too much buffered data, and false if one or
* more channel is overfull.
*/
int
channel_not_very_much_buffered_data(void)
{
@ -470,7 +488,6 @@ channel_not_very_much_buffered_data(void)
}
/* Returns true if any channel is still open. */
int
channel_still_open(void)
{
@ -513,7 +530,6 @@ channel_still_open(void)
}
/* Returns the id of an open channel suitable for keepaliving */
int
channel_find_open(void)
{
@ -558,7 +574,6 @@ channel_find_open(void)
* suitable for sending to the client. The message contains crlf pairs for
* newlines.
*/
char *
channel_open_message(void)
{
@ -643,6 +658,7 @@ channel_request_start(int id, char *service, int wantconfirm)
packet_put_cstring(service);
packet_put_char(wantconfirm);
}
void
channel_register_confirm(int id, channel_callback_fn *fn, void *ctx)
{
@ -655,6 +671,7 @@ channel_register_confirm(int id, channel_callback_fn *fn, void *ctx)
c->confirm = fn;
c->confirm_ctx = ctx;
}
void
channel_register_cleanup(int id, channel_callback_fn *fn, int do_close)
{
@ -667,6 +684,7 @@ channel_register_cleanup(int id, channel_callback_fn *fn, int do_close)
c->detach_user = fn;
c->detach_close = do_close;
}
void
channel_cancel_cleanup(int id)
{
@ -679,6 +697,7 @@ channel_cancel_cleanup(int id)
c->detach_user = NULL;
c->detach_close = 0;
}
void
channel_register_filter(int id, channel_infilter_fn *ifn,
channel_outfilter_fn *ofn)
@ -718,25 +737,27 @@ channel_set_fds(int id, int rfd, int wfd, int efd,
* 'channel_post*': perform any appropriate operations for channels which
* have events pending.
*/
typedef void chan_fn(Channel *c, fd_set * readset, fd_set * writeset);
typedef void chan_fn(Channel *c, fd_set *readset, fd_set *writeset);
chan_fn *channel_pre[SSH_CHANNEL_MAX_TYPE];
chan_fn *channel_post[SSH_CHANNEL_MAX_TYPE];
/* ARGSUSED */
static void
channel_pre_listener(Channel *c, fd_set * readset, fd_set * writeset)
channel_pre_listener(Channel *c, fd_set *readset, fd_set *writeset)
{
FD_SET(c->sock, readset);
}
/* ARGSUSED */
static void
channel_pre_connecting(Channel *c, fd_set * readset, fd_set * writeset)
channel_pre_connecting(Channel *c, fd_set *readset, fd_set *writeset)
{
debug3("channel %d: waiting for connection", c->self);
FD_SET(c->sock, writeset);
}
static void
channel_pre_open_13(Channel *c, fd_set * readset, fd_set * writeset)
channel_pre_open_13(Channel *c, fd_set *readset, fd_set *writeset)
{
if (buffer_len(&c->input) < packet_get_maxsize())
FD_SET(c->sock, readset);
@ -745,16 +766,14 @@ channel_pre_open_13(Channel *c, fd_set * readset, fd_set * writeset)
}
static void
channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset)
channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)
{
u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
/* check buffer limits */
limit = MIN(limit, (BUFFER_MAX_LEN - BUFFER_MAX_CHUNK - CHAN_RBUF));
if (c->istate == CHAN_INPUT_OPEN &&
limit > 0 &&
buffer_len(&c->input) < limit)
buffer_len(&c->input) < limit &&
buffer_check_alloc(&c->input, CHAN_RBUF))
FD_SET(c->rfd, readset);
if (c->ostate == CHAN_OUTPUT_OPEN ||
c->ostate == CHAN_OUTPUT_WAIT_DRAIN) {
@ -784,8 +803,9 @@ channel_pre_open(Channel *c, fd_set * readset, fd_set * writeset)
FD_SET(c->ctl_fd, readset);
}
/* ARGSUSED */
static void
channel_pre_input_draining(Channel *c, fd_set * readset, fd_set * writeset)
channel_pre_input_draining(Channel *c, fd_set *readset, fd_set *writeset)
{
if (buffer_len(&c->input) == 0) {
packet_start(SSH_MSG_CHANNEL_CLOSE);
@ -796,8 +816,9 @@ channel_pre_input_draining(Channel *c, fd_set * readset, fd_set * writeset)
}
}
/* ARGSUSED */
static void
channel_pre_output_draining(Channel *c, fd_set * readset, fd_set * writeset)
channel_pre_output_draining(Channel *c, fd_set *readset, fd_set *writeset)
{
if (buffer_len(&c->output) == 0)
chan_mark_dead(c);
@ -873,7 +894,7 @@ x11_open_helper(Buffer *b)
}
static void
channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset)
channel_pre_x11_open_13(Channel *c, fd_set *readset, fd_set *writeset)
{
int ret = x11_open_helper(&c->output);
@ -899,7 +920,7 @@ channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset)
}
static void
channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset)
channel_pre_x11_open(Channel *c, fd_set *readset, fd_set *writeset)
{
int ret = x11_open_helper(&c->output);
@ -925,8 +946,9 @@ channel_pre_x11_open(Channel *c, fd_set * readset, fd_set * writeset)
}
/* try to decode a socks4 header */
/* ARGSUSED */
static int
channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset)
channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset)
{
char *p, *host;
u_int len, have, i, found;
@ -990,7 +1012,7 @@ channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset)
s4_rsp.command = 90; /* cd: req granted */
s4_rsp.dest_port = 0; /* ignored */
s4_rsp.dest_addr.s_addr = INADDR_ANY; /* ignored */
buffer_append(&c->output, (char *)&s4_rsp, sizeof(s4_rsp));
buffer_append(&c->output, &s4_rsp, sizeof(s4_rsp));
return 1;
}
@ -1003,8 +1025,9 @@ channel_decode_socks4(Channel *c, fd_set * readset, fd_set * writeset)
#define SSH_SOCKS5_CONNECT 0x01
#define SSH_SOCKS5_SUCCESS 0x00
/* ARGSUSED */
static int
channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset)
{
struct {
u_int8_t version;
@ -1014,7 +1037,7 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
} s5_req, s5_rsp;
u_int16_t dest_port;
u_char *p, dest_addr[255+1];
u_int have, i, found, nmethods, addrlen, af;
u_int have, need, i, found, nmethods, addrlen, af;
debug2("channel %d: decode socks5", c->self);
p = buffer_ptr(&c->input);
@ -1030,7 +1053,7 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
return 0;
/* look for method: "NO AUTHENTICATION REQUIRED" */
for (found = 0, i = 2 ; i < nmethods + 2; i++) {
if (p[i] == SSH_SOCKS5_NOAUTH ) {
if (p[i] == SSH_SOCKS5_NOAUTH) {
found = 1;
break;
}
@ -1051,7 +1074,7 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
debug2("channel %d: socks5 post auth", c->self);
if (have < sizeof(s5_req)+1)
return 0; /* need more */
memcpy((char *)&s5_req, p, sizeof(s5_req));
memcpy(&s5_req, p, sizeof(s5_req));
if (s5_req.version != 0x05 ||
s5_req.command != SSH_SOCKS5_CONNECT ||
s5_req.reserved != 0x00) {
@ -1075,7 +1098,10 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
debug2("channel %d: bad socks5 atyp %d", c->self, s5_req.atyp);
return -1;
}
if (have < 4 + addrlen + 2)
need = sizeof(s5_req) + addrlen + 2;
if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
need++;
if (have < need)
return 0;
buffer_consume(&c->input, sizeof(s5_req));
if (s5_req.atyp == SSH_SOCKS5_DOMAIN)
@ -1099,15 +1125,15 @@ channel_decode_socks5(Channel *c, fd_set * readset, fd_set * writeset)
((struct in_addr *)&dest_addr)->s_addr = INADDR_ANY;
dest_port = 0; /* ignored */
buffer_append(&c->output, (char *)&s5_rsp, sizeof(s5_rsp));
buffer_append(&c->output, (char *)&dest_addr, sizeof(struct in_addr));
buffer_append(&c->output, (char *)&dest_port, sizeof(dest_port));
buffer_append(&c->output, &s5_rsp, sizeof(s5_rsp));
buffer_append(&c->output, &dest_addr, sizeof(struct in_addr));
buffer_append(&c->output, &dest_port, sizeof(dest_port));
return 1;
}
/* dynamic port forwarding */
static void
channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)
channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset)
{
u_char *p;
u_int have;
@ -1150,8 +1176,9 @@ channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset)
}
/* This is our fake X11 server socket. */
/* ARGSUSED */
static void
channel_post_x11_listener(Channel *c, fd_set * readset, fd_set * writeset)
channel_post_x11_listener(Channel *c, fd_set *readset, fd_set *writeset)
{
Channel *nc;
struct sockaddr addr;
@ -1275,8 +1302,9 @@ channel_set_reuseaddr(int fd)
/*
* This socket is listening for connections to a forwarded TCP/IP port.
*/
/* ARGSUSED */
static void
channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)
channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset)
{
Channel *nc;
struct sockaddr addr;
@ -1332,8 +1360,9 @@ channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)
* This is the authentication agent socket listening for connections from
* clients.
*/
/* ARGSUSED */
static void
channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset)
channel_post_auth_listener(Channel *c, fd_set *readset, fd_set *writeset)
{
Channel *nc;
int newsock;
@ -1365,8 +1394,9 @@ channel_post_auth_listener(Channel *c, fd_set * readset, fd_set * writeset)
}
}
/* ARGSUSED */
static void
channel_post_connecting(Channel *c, fd_set * readset, fd_set * writeset)
channel_post_connecting(Channel *c, fd_set *readset, fd_set *writeset)
{
int err = 0;
socklen_t sz = sizeof(err);
@ -1411,18 +1441,25 @@ channel_post_connecting(Channel *c, fd_set * readset, fd_set * writeset)
}
}
/* ARGSUSED */
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[CHAN_RBUF];
int len;
if (c->rfd != -1 &&
FD_ISSET(c->rfd, readset)) {
errno = 0;
len = read(c->rfd, buf, sizeof(buf));
if (len < 0 && (errno == EINTR || errno == EAGAIN))
return 1;
#ifndef PTY_ZEROREAD
if (len <= 0) {
#else
if ((!c->isatty && len <= 0) ||
(c->isatty && (len < 0 || (len == 0 && errno != 0)))) {
#endif
debug2("channel %d: read<=0 rfd %d len %d",
c->self, c->rfd, len);
if (c->type != SSH_CHANNEL_OPEN) {
@ -1451,8 +1488,10 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
}
return 1;
}
/* ARGSUSED */
static int
channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
channel_handle_wfd(Channel *c, fd_set *readset, fd_set *writeset)
{
struct termios tio;
u_char *data = NULL, *buf;
@ -1538,8 +1577,9 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
}
return 1;
}
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[CHAN_RBUF];
int len;
@ -1581,8 +1621,10 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
}
return 1;
}
/* ARGSUSED */
static int
channel_handle_ctl(Channel *c, fd_set * readset, fd_set * writeset)
channel_handle_ctl(Channel *c, fd_set *readset, fd_set *writeset)
{
char buf[16];
int len;
@ -1608,6 +1650,7 @@ channel_handle_ctl(Channel *c, fd_set * readset, fd_set * writeset)
}
return 1;
}
static int
channel_check_window(Channel *c)
{
@ -1629,7 +1672,7 @@ channel_check_window(Channel *c)
}
static void
channel_post_open(Channel *c, fd_set * readset, fd_set * writeset)
channel_post_open(Channel *c, fd_set *readset, fd_set *writeset)
{
if (c->delayed)
return;
@ -1642,8 +1685,9 @@ channel_post_open(Channel *c, fd_set * readset, fd_set * writeset)
channel_check_window(c);
}
/* ARGSUSED */
static void
channel_post_output_drain_13(Channel *c, fd_set * readset, fd_set * writeset)
channel_post_output_drain_13(Channel *c, fd_set *readset, fd_set *writeset)
{
int len;
@ -1760,7 +1804,7 @@ channel_garbage_collect(Channel *c)
}
static void
channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)
channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset)
{
static int did_init = 0;
u_int i;
@ -1788,15 +1832,20 @@ void
channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
u_int *nallocp, int rekeying)
{
u_int n, sz;
u_int n, sz, nfdset;
n = MAX(*maxfdp, channel_max_fd);
sz = howmany(n+1, NFDBITS) * sizeof(fd_mask);
nfdset = howmany(n+1, NFDBITS);
/* Explicitly test here, because xrealloc isn't always called */
if (nfdset && SIZE_T_MAX / nfdset < sizeof(fd_mask))
fatal("channel_prepare_select: max_fd (%d) is too large", n);
sz = nfdset * sizeof(fd_mask);
/* perhaps check sz < nalloc/2 and shrink? */
if (*readsetp == NULL || sz > *nallocp) {
*readsetp = xrealloc(*readsetp, sz);
*writesetp = xrealloc(*writesetp, sz);
*readsetp = xrealloc(*readsetp, nfdset, sizeof(fd_mask));
*writesetp = xrealloc(*writesetp, nfdset, sizeof(fd_mask));
*nallocp = sz;
}
*maxfdp = n;
@ -1812,14 +1861,13 @@ channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
* events pending.
*/
void
channel_after_select(fd_set * readset, fd_set * writeset)
channel_after_select(fd_set *readset, fd_set *writeset)
{
channel_handler(channel_post, readset, writeset);
}
/* If there is data to send to the connection, enqueue some of it now. */
void
channel_output_poll(void)
{
@ -1940,6 +1988,7 @@ channel_output_poll(void)
/* -- protocol input */
/* ARGSUSED */
void
channel_input_data(int type, u_int32_t seq, void *ctxt)
{
@ -1999,6 +2048,7 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
xfree(data);
}
/* ARGSUSED */
void
channel_input_extended_data(int type, u_int32_t seq, void *ctxt)
{
@ -2045,6 +2095,7 @@ channel_input_extended_data(int type, u_int32_t seq, void *ctxt)
xfree(data);
}
/* ARGSUSED */
void
channel_input_ieof(int type, u_int32_t seq, void *ctxt)
{
@ -2068,6 +2119,7 @@ channel_input_ieof(int type, u_int32_t seq, void *ctxt)
}
/* ARGSUSED */
void
channel_input_close(int type, u_int32_t seq, void *ctxt)
{
@ -2106,6 +2158,7 @@ channel_input_close(int type, u_int32_t seq, void *ctxt)
}
/* proto version 1.5 overloads CLOSE_CONFIRMATION with OCLOSE */
/* ARGSUSED */
void
channel_input_oclose(int type, u_int32_t seq, void *ctxt)
{
@ -2118,6 +2171,7 @@ channel_input_oclose(int type, u_int32_t seq, void *ctxt)
chan_rcvd_oclose(c);
}
/* ARGSUSED */
void
channel_input_close_confirmation(int type, u_int32_t seq, void *ctxt)
{
@ -2134,6 +2188,7 @@ channel_input_close_confirmation(int type, u_int32_t seq, void *ctxt)
channel_free(c);
}
/* ARGSUSED */
void
channel_input_open_confirmation(int type, u_int32_t seq, void *ctxt)
{
@ -2181,6 +2236,7 @@ reason2txt(int reason)
return "unknown reason";
}
/* ARGSUSED */
void
channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
{
@ -2212,6 +2268,7 @@ channel_input_open_failure(int type, u_int32_t seq, void *ctxt)
channel_free(c);
}
/* ARGSUSED */
void
channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
{
@ -2236,6 +2293,7 @@ channel_input_window_adjust(int type, u_int32_t seq, void *ctxt)
c->remote_window += adjust;
}
/* ARGSUSED */
void
channel_input_port_open(int type, u_int32_t seq, void *ctxt)
{
@ -2454,7 +2512,7 @@ channel_setup_remote_fwd_listener(const char *listen_address,
* the secure channel to host:port from local side.
*/
void
int
channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
const char *host_to_connect, u_short port_to_connect)
{
@ -2498,7 +2556,6 @@ channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
success = 1;
break;
case SSH_SMSG_FAILURE:
logit("Warning: Server denied remote port forwarding.");
break;
default:
/* Unknown packet */
@ -2512,6 +2569,7 @@ channel_request_remote_forwarding(const char *listen_host, u_short listen_port,
permitted_opens[num_permitted_opens].listen_port = listen_port;
num_permitted_opens++;
}
return (success ? 0 : -1);
}
/*
@ -2551,13 +2609,13 @@ channel_request_rforward_cancel(const char *host, u_short port)
/*
* This is called after receiving CHANNEL_FORWARDING_REQUEST. This initates
* listening for the port, and sends back a success reply (or disconnect
* message if there was an error). This never returns if there was an error.
* message if there was an error).
*/
void
int
channel_input_port_forward_request(int is_root, int gateway_ports)
{
u_short port, host_port;
int success = 0;
char *hostname;
/* Get arguments from the packet. */
@ -2579,11 +2637,13 @@ channel_input_port_forward_request(int is_root, int gateway_ports)
#endif
/* Initiate forwarding */
channel_setup_local_fwd_listener(NULL, port, hostname,
success = channel_setup_local_fwd_listener(NULL, port, hostname,
host_port, gateway_ports);
/* Free the argument string. */
xfree(hostname);
return (success ? 0 : -1);
}
/*
@ -2602,7 +2662,7 @@ void
channel_add_permitted_opens(char *host, int port)
{
if (num_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
fatal("channel_request_remote_forwarding: too many forwards");
fatal("channel_add_permitted_opens: too many forwards");
debug("allow port forwarding to host %s port %d", host, port);
permitted_opens[num_permitted_opens].host_to_connect = xstrdup(host);
@ -2612,6 +2672,19 @@ channel_add_permitted_opens(char *host, int port)
all_opens_permitted = 0;
}
int
channel_add_adm_permitted_opens(char *host, int port)
{
if (num_adm_permitted_opens >= SSH_MAX_FORWARDS_PER_DIRECTION)
fatal("channel_add_adm_permitted_opens: too many forwards");
debug("config allows port forwarding to host %s port %d", host, port);
permitted_adm_opens[num_adm_permitted_opens].host_to_connect
= xstrdup(host);
permitted_adm_opens[num_adm_permitted_opens].port_to_connect = port;
return ++num_adm_permitted_opens;
}
void
channel_clear_permitted_opens(void)
{
@ -2621,9 +2694,18 @@ channel_clear_permitted_opens(void)
if (permitted_opens[i].host_to_connect != NULL)
xfree(permitted_opens[i].host_to_connect);
num_permitted_opens = 0;
}
void
channel_clear_adm_permitted_opens(void)
{
int i;
for (i = 0; i < num_adm_permitted_opens; i++)
if (permitted_adm_opens[i].host_to_connect != NULL)
xfree(permitted_adm_opens[i].host_to_connect);
num_adm_permitted_opens = 0;
}
/* return socket to remote host, port */
static int
@ -2701,7 +2783,7 @@ channel_connect_by_listen_address(u_short listen_port)
int
channel_connect_to(const char *host, u_short port)
{
int i, permit;
int i, permit, permit_adm = 1;
permit = all_opens_permitted;
if (!permit) {
@ -2710,9 +2792,19 @@ channel_connect_to(const char *host, u_short port)
permitted_opens[i].port_to_connect == port &&
strcmp(permitted_opens[i].host_to_connect, host) == 0)
permit = 1;
}
if (!permit) {
if (num_adm_permitted_opens > 0) {
permit_adm = 0;
for (i = 0; i < num_adm_permitted_opens; i++)
if (permitted_adm_opens[i].host_to_connect != NULL &&
permitted_adm_opens[i].port_to_connect == port &&
strcmp(permitted_adm_opens[i].host_to_connect, host)
== 0)
permit_adm = 1;
}
if (!permit || !permit_adm) {
logit("Received request to connect to host %.100s port %d, "
"but the request was denied.", host, port);
return -1;
@ -2733,10 +2825,10 @@ channel_send_window_changes(void)
if (ioctl(channels[i]->rfd, TIOCGWINSZ, &ws) < 0)
continue;
channel_request_start(i, "window-change", 0);
packet_put_int(ws.ws_col);
packet_put_int(ws.ws_row);
packet_put_int(ws.ws_xpixel);
packet_put_int(ws.ws_ypixel);
packet_put_int((u_int)ws.ws_col);
packet_put_int((u_int)ws.ws_row);
packet_put_int((u_int)ws.ws_xpixel);
packet_put_int((u_int)ws.ws_ypixel);
packet_send();
}
}
@ -2844,7 +2936,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost,
}
/* Allocate a channel for each socket. */
*chanids = xmalloc(sizeof(**chanids) * (num_socks + 1));
*chanids = xcalloc(num_socks + 1, sizeof(**chanids));
for (n = 0; n < num_socks; n++) {
sock = socks[n];
nc = channel_new("x11 listener",
@ -2873,7 +2965,7 @@ connect_local_xsocket(u_int dnr)
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
snprintf(addr.sun_path, sizeof addr.sun_path, _PATH_UNIX_X, dnr);
if (connect(sock, (struct sockaddr *) & addr, sizeof(addr)) == 0)
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0)
return sock;
close(sock);
error("connect %.100s: %.100s", addr.sun_path, strerror(errno));
@ -2883,12 +2975,12 @@ connect_local_xsocket(u_int dnr)
int
x11_connect_display(void)
{
int display_number, sock = 0;
u_int display_number;
const char *display;
char buf[1024], *cp;
struct addrinfo hints, *ai, *aitop;
char strport[NI_MAXSERV];
int gaierr;
int gaierr, sock = 0;
/* Try to open a socket for the local X server. */
display = getenv("DISPLAY");
@ -2908,7 +3000,7 @@ x11_connect_display(void)
if (strncmp(display, "unix:", 5) == 0 ||
display[0] == ':') {
/* Connect to the unix domain socket. */
if (sscanf(strrchr(display, ':') + 1, "%d", &display_number) != 1) {
if (sscanf(strrchr(display, ':') + 1, "%u", &display_number) != 1) {
error("Could not parse display number from DISPLAY: %.100s",
display);
return -1;
@ -2933,7 +3025,7 @@ x11_connect_display(void)
}
*cp = 0;
/* buf now contains the host name. But first we parse the display number. */
if (sscanf(cp + 1, "%d", &display_number) != 1) {
if (sscanf(cp + 1, "%u", &display_number) != 1) {
error("Could not parse display number from DISPLAY: %.100s",
display);
return -1;
@ -2943,7 +3035,7 @@ x11_connect_display(void)
memset(&hints, 0, sizeof(hints));
hints.ai_family = IPv4or6;
hints.ai_socktype = SOCK_STREAM;
snprintf(strport, sizeof strport, "%d", 6000 + display_number);
snprintf(strport, sizeof strport, "%u", 6000 + display_number);
if ((gaierr = getaddrinfo(buf, strport, &hints, &aitop)) != 0) {
error("%.100s: unknown host. (%s)", buf, gai_strerror(gaierr));
return -1;
@ -2957,7 +3049,7 @@ x11_connect_display(void)
}
/* Connect it to the display. */
if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
debug2("connect %.100s port %d: %.100s", buf,
debug2("connect %.100s port %u: %.100s", buf,
6000 + display_number, strerror(errno));
close(sock);
continue;
@ -2967,7 +3059,7 @@ x11_connect_display(void)
}
freeaddrinfo(aitop);
if (!ai) {
error("connect %.100s port %d: %.100s", buf, 6000 + display_number,
error("connect %.100s port %u: %.100s", buf, 6000 + display_number,
strerror(errno));
return -1;
}
@ -2981,6 +3073,7 @@ x11_connect_display(void)
* with either SSH_MSG_OPEN_CONFIRMATION or SSH_MSG_OPEN_FAILURE.
*/
/* ARGSUSED */
void
x11_input_open(int type, u_int32_t seq, void *ctxt)
{
@ -3024,6 +3117,7 @@ x11_input_open(int type, u_int32_t seq, void *ctxt)
}
/* dummy protocol handler that denies SSH-1 requests (agent/x11) */
/* ARGSUSED */
void
deny_input_open(int type, u_int32_t seq, void *ctxt)
{
@ -3070,13 +3164,11 @@ x11_request_forwarding_with_spoofing(int client_session_id, const char *disp,
return;
}
cp = disp;
if (disp)
cp = strchr(disp, ':');
cp = strchr(disp, ':');
if (cp)
cp = strchr(cp, '.');
if (cp)
screen_number = atoi(cp + 1);
screen_number = (u_int)strtonum(cp + 1, 0, 400, NULL);
else
screen_number = 0;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: channels.h,v 1.83 2005/12/30 15:56:37 reyk Exp $ */
/* $OpenBSD: channels.h,v 1.88 2006/08/03 03:34:42 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -38,8 +38,6 @@
#ifndef CHANNEL_H
#define CHANNEL_H
#include "buffer.h"
/* Definitions for channel types. */
#define SSH_CHANNEL_X11_LISTENER 1 /* Listening for inet X11 conn. */
#define SSH_CHANNEL_PORT_LISTENER 2 /* Listening on a port. */
@ -207,11 +205,13 @@ int channel_find_open(void);
void channel_set_af(int af);
void channel_permit_all_opens(void);
void channel_add_permitted_opens(char *, int);
int channel_add_adm_permitted_opens(char *, int);
void channel_clear_permitted_opens(void);
void channel_input_port_forward_request(int, int);
void channel_clear_adm_permitted_opens(void);
int channel_input_port_forward_request(int, int);
int channel_connect_to(const char *, u_short);
int channel_connect_by_listen_address(u_short);
void channel_request_remote_forwarding(const char *, u_short,
int channel_request_remote_forwarding(const char *, u_short,
const char *, u_short);
int channel_setup_local_fwd_listener(const char *, u_short,
const char *, u_short, int);

View File

@ -1,3 +1,4 @@
/* $OpenBSD: cipher.c,v 1.81 2006/08/03 03:34:42 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -35,14 +36,18 @@
*/
#include "includes.h"
RCSID("$OpenBSD: cipher.c,v 1.77 2005/07/16 01:35:24 djm Exp $");
#include <sys/types.h>
#include <openssl/md5.h>
#include <string.h>
#include <stdarg.h>
#include "xmalloc.h"
#include "log.h"
#include "cipher.h"
#include <openssl/md5.h>
/* compatibility with old or broken OpenSSL versions */
#include "openbsd-compat/openssl-compat.h"

View File

@ -1,4 +1,4 @@
/* $OpenBSD: cipher.h,v 1.35 2004/07/28 09:40:29 markus Exp $ */
/* $OpenBSD: cipher.h,v 1.36 2006/03/25 22:22:42 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>

View File

@ -1,3 +1,4 @@
/* $OpenBSD: compat.c,v 1.76 2006/08/03 03:34:42 deraadt Exp $ */
/*
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
*
@ -23,12 +24,17 @@
*/
#include "includes.h"
RCSID("$OpenBSD: compat.c,v 1.71 2005/03/01 10:09:52 djm Exp $");
RCSID("$FreeBSD$");
__RCSID("$FreeBSD$");
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "xmalloc.h"
#include "buffer.h"
#include "packet.h"
#include "xmalloc.h"
#include "compat.h"
#include "log.h"
#include "match.h"

View File

@ -1,4 +1,4 @@
/* $OpenBSD: compat.h,v 1.39 2005/03/01 10:09:52 djm Exp $ */
/* $OpenBSD: compat.h,v 1.40 2006/03/25 22:22:43 djm Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.

View File

@ -1,4 +1,4 @@
# $Id: configure.ac,v 1.322 2006/01/29 13:22:39 dtucker Exp $
# $Id: configure.ac,v 1.367 2006/09/24 19:08:59 tim Exp $
# $FreeBSD$
#
# Copyright (c) 1999-2004 Damien Miller
@ -16,6 +16,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org)
AC_REVISION($Revision: 1.367 $)
AC_CONFIG_SRCDIR([ssh.c])
AC_CONFIG_HEADER(config.h)
@ -28,6 +29,7 @@ AC_PROG_AWK
AC_PROG_CPP
AC_PROG_RANLIB
AC_PROG_INSTALL
AC_PROG_EGREP
AC_PATH_PROG(AR, ar)
AC_PATH_PROG(CAT, cat)
AC_PATH_PROG(KILL, kill)
@ -126,15 +128,45 @@ AC_ARG_WITH(rpath,
]
)
# Messages for features tested for in target-specific section
SIA_MSG="no"
SPC_MSG="no"
# Check for some target-specific stuff
case "$host" in
*-*-aix*)
# Some versions of VAC won't allow macro redefinitions at
# -qlanglevel=ansi, and autoconf 2.60 sometimes insists on using that
# particularly with older versions of vac or xlc.
# It also throws errors about null macro argments, but these are
# not fatal.
AC_MSG_CHECKING(if compiler allows macro redefinitions)
AC_COMPILE_IFELSE(
[AC_LANG_SOURCE([[
#define testmacro foo
#define testmacro bar
int main(void) { exit(0); }
]])],
[ AC_MSG_RESULT(yes) ],
[ AC_MSG_RESULT(no)
CC="`echo $CC | sed 's/-qlanglvl\=ansi//g'`"
LD="`echo $LD | sed 's/-qlanglvl\=ansi//g'`"
CFLAGS="`echo $CFLAGS | sed 's/-qlanglvl\=ansi//g'`"
CPPFLAGS="`echo $CPPFLAGS | sed 's/-qlanglvl\=ansi//g'`"
]
)
AC_MSG_CHECKING([how to specify blibpath for linker ($LD)])
if (test -z "$blibpath"); then
blibpath="/usr/lib:/lib"
fi
saved_LDFLAGS="$LDFLAGS"
for tryflags in -blibpath: -Wl,-blibpath: -Wl,-rpath, ;do
if test "$GCC" = "yes"; then
flags="-Wl,-blibpath: -Wl,-rpath, -blibpath:"
else
flags="-blibpath: -Wl,-blibpath: -Wl,-rpath,"
fi
for tryflags in $flags ;do
if (test -z "$blibflags"); then
LDFLAGS="$saved_LDFLAGS $tryflags$blibpath"
AC_TRY_LINK([], [], [blibflags=$tryflags])
@ -174,6 +206,12 @@ case "$host" in
[#include <usersec.h>]
)
AC_CHECK_FUNCS(setauthdb)
AC_CHECK_DECL(F_CLOSEM,
AC_DEFINE(HAVE_FCNTL_CLOSEM, 1, [Use F_CLOSEM fcntl for closefrom]),
[],
[ #include <limits.h>
#include <fcntl.h> ]
)
check_for_aix_broken_getaddrinfo=1
AC_DEFINE(BROKEN_REALPATH, 1, [Define if you have a broken realpath.])
AC_DEFINE(SETEUID_BREAKS_SETUID, 1,
@ -189,6 +227,7 @@ case "$host" in
supported by bsd-setproctitle.c])
AC_DEFINE(SSHPAM_CHAUTHTOK_NEEDS_RUID, 1,
[AIX 5.2 and 5.3 (and presumably newer) require this])
AC_DEFINE(PTY_ZEROREAD, 1, [read(1) can return 0 for a non-closed fd])
;;
*-*-cygwin*)
check_for_libcrypt_later=1
@ -230,6 +269,14 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
AC_DEFINE(BROKEN_SETREGID)
AC_DEFINE_UNQUOTED(BIND_8_COMPAT, 1,
[Define if your resolver libs need this for getrrsetbyname])
AC_DEFINE(SSH_TUN_FREEBSD, 1, [Open tunnel devices the FreeBSD way])
AC_DEFINE(SSH_TUN_COMPAT_AF, 1,
[Use tunnel device compatibility to OpenBSD])
AC_DEFINE(SSH_TUN_PREPEND_AF, 1,
[Prepend the address family to IP tunnel traffic])
;;
*-*-dragonfly*)
SSHDLIBS="$SSHDLIBS -lcrypt"
;;
*-*-hpux*)
# first we define all of the options common to all HP-UX releases
@ -344,7 +391,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
fi
;;
mips-sony-bsd|mips-sony-newsos4)
AC_DEFINE(NEED_SETPRGP, 1, [Need setpgrp to acquire controlling tty])
AC_DEFINE(NEED_SETPGRP, 1, [Need setpgrp to acquire controlling tty])
SONY=1
;;
*-*-netbsd*)
@ -384,6 +431,8 @@ mips-sony-bsd|mips-sony-newsos4)
AC_DEFINE(HAVE_ATTRIBUTE__SENTINEL__, 1, [OpenBSD's gcc has sentinel])
AC_DEFINE(HAVE_ATTRIBUTE__BOUNDED__, 1, [OpenBSD's gcc has bounded])
AC_DEFINE(SSH_TUN_OPENBSD, 1, [Open tunnel devices the OpenBSD way])
AC_DEFINE(SYSLOG_R_SAFE_IN_SIGHAND, 1,
[syslog_r function is safe to use in in a signal handler])
;;
*-*-solaris*)
if test "x$withval" != "xno" ; then
@ -403,6 +452,8 @@ mips-sony-bsd|mips-sony-newsos4)
AC_DEFINE(SSHD_ACQUIRES_CTTY, 1,
[Define if sshd somehow reacquires a controlling TTY
after setsid()])
AC_DEFINE(PASSWD_NEEDS_USERNAME, 1, [must supply username to passwd
in case the name is longer than 8 chars])
external_path_file=/etc/default/login
# hardwire lastlog location (can't detect it on some versions)
conf_lastlog_location="/var/adm/lastlog"
@ -416,6 +467,17 @@ mips-sony-bsd|mips-sony-newsos4)
else
AC_MSG_RESULT(no)
fi
AC_ARG_WITH(solaris-contracts,
[ --with-solaris-contracts Enable Solaris process contracts (experimental)],
[
AC_CHECK_LIB(contract, ct_tmpl_activate,
[ AC_DEFINE(USE_SOLARIS_PROCESS_CONTRACTS, 1,
[Define if you have Solaris process contracts])
SSHDLIBS="$SSHDLIBS -lcontract"
AC_SUBST(SSHDLIBS)
SPC_MSG="yes" ], )
],
)
;;
*-*-sunos4*)
CPPFLAGS="$CPPFLAGS -DSUNOS4"
@ -453,7 +515,6 @@ mips-sony-bsd|mips-sony-newsos4)
;;
# UnixWare 1.x, UnixWare 2.x, and others based on code from Univel.
*-*-sysv4.2*)
CFLAGS="$CFLAGS -Dva_list=_VA_LIST"
AC_DEFINE(USE_PIPES)
AC_DEFINE(SETEUID_BREAKS_SETUID)
AC_DEFINE(BROKEN_SETREUID)
@ -475,6 +536,7 @@ mips-sony-bsd|mips-sony-newsos4)
TEST_SHELL=/u95/bin/sh
AC_DEFINE(BROKEN_LIBIAF, 1,
[ia_uinfo routines not supported by OS yet])
AC_DEFINE(BROKEN_UPDWTMPX)
;;
*) AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*")
;;
@ -564,6 +626,7 @@ mips-sony-bsd|mips-sony-newsos4)
system's login() call])
AC_DEFINE(DISABLE_FD_PASSING)
LIBS="$LIBS -lsecurity -ldb -lm -laud"
SIA_MSG="yes"
else
AC_MSG_RESULT(no)
AC_DEFINE(LOCKED_PASSWD_SUBSTR, "Nologin",
@ -576,18 +639,21 @@ mips-sony-bsd|mips-sony-newsos4)
AC_DEFINE(BROKEN_SETREGID)
;;
*-*-nto-qnx)
*-*-nto-qnx*)
AC_DEFINE(USE_PIPES)
AC_DEFINE(NO_X11_UNIX_SOCKETS)
AC_DEFINE(MISSING_NFDBITS, 1, [Define on *nto-qnx systems])
AC_DEFINE(MISSING_HOWMANY, 1, [Define on *nto-qnx systems])
AC_DEFINE(MISSING_FD_MASK, 1, [Define on *nto-qnx systems])
AC_DEFINE(DISABLE_LASTLOG)
AC_DEFINE(SSHD_ACQUIRES_CTTY)
enable_etc_default_login=no # has incompatible /etc/default/login
;;
*-*-ultrix*)
AC_DEFINE(BROKEN_GETGROUPS, 1, [getgroups(0,NULL) will return -1])
AC_DEFINE(BROKEN_MMAP, 1, [Ultrix mmap can't map files])
AC_DEFINE(NEED_SETPRGP)
AC_DEFINE(NEED_SETPGRP)
AC_DEFINE(HAVE_SYS_SYSLOG_H, 1, [Force use of sys/syslog.h on Ultrix])
;;
@ -665,30 +731,30 @@ dnl Checks for header files.
AC_CHECK_HEADERS( \
bstring.h \
crypt.h \
crypto/sha2.h \
dirent.h \
endian.h \
features.h \
fcntl.h \
floatingpoint.h \
getopt.h \
glob.h \
ia.h \
iaf.h \
lastlog.h \
limits.h \
login.h \
login_cap.h \
maillock.h \
ndir.h \
net/if.h \
net/if_tun.h \
netdb.h \
netgroup.h \
netinet/in_systm.h \
pam/pam_appl.h \
paths.h \
pty.h \
readpassphrase.h \
rpc/types.h \
security/pam_appl.h \
sha2.h \
shadow.h \
stddef.h \
stdint.h \
@ -724,6 +790,13 @@ AC_CHECK_HEADERS( \
vis.h \
)
# lastlog.h requires sys/time.h to be included first on Solaris
AC_CHECK_HEADERS(lastlog.h, [], [], [
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
])
# sys/ptms.h requires sys/stream.h to be included first on Solaris
AC_CHECK_HEADERS(sys/ptms.h, [], [], [
#ifdef HAVE_SYS_STREAM_H
@ -731,6 +804,11 @@ AC_CHECK_HEADERS(sys/ptms.h, [], [], [
#endif
])
# login_cap.h requires sys/types.h on NetBSD
AC_CHECK_HEADERS(login_cap.h, [], [], [
#include <sys/types.h>
])
# Checks for libraries.
AC_CHECK_FUNC(yp_match, , AC_CHECK_LIB(nsl, yp_match))
AC_CHECK_FUNC(setsockopt, , AC_CHECK_LIB(socket, setsockopt))
@ -915,11 +993,9 @@ AC_EGREP_CPP(FOUNDIT,
# Check for g.gl_matchc glob() extension
AC_MSG_CHECKING(for gl_matchc field in glob_t)
AC_EGREP_CPP(FOUNDIT,
[
#include <glob.h>
int main(void){glob_t g; g.gl_matchc = 1;}
],
AC_TRY_COMPILE(
[ #include <glob.h> ],
[glob_t g; g.gl_matchc = 1;],
[
AC_DEFINE(GLOB_HAS_GL_MATCHC, 1,
[Define if your system glob() function has
@ -931,6 +1007,8 @@ AC_EGREP_CPP(FOUNDIT,
]
)
AC_CHECK_DECLS(GLOB_NOMATCH, , , [#include <glob.h>])
AC_MSG_CHECKING([whether struct dirent allocates space for d_name])
AC_RUN_IFELSE(
[AC_LANG_SOURCE([[
@ -1147,7 +1225,13 @@ AC_ARG_WITH(audit,
AUDIT_MODULE=bsm
dnl Checks for headers, libs and functions
AC_CHECK_HEADERS(bsm/audit.h, [],
[AC_MSG_ERROR(BSM enabled and bsm/audit.h not found)])
[AC_MSG_ERROR(BSM enabled and bsm/audit.h not found)],
[
#ifdef HAVE_TIME_H
# include <time.h>
#endif
]
)
AC_CHECK_LIB(bsm, getaudit, [],
[AC_MSG_ERROR(BSM enabled and required library not found)])
AC_CHECK_FUNCS(getaudit, [],
@ -1293,6 +1377,29 @@ AC_CHECK_DECL(tcsendbreak,
AC_CHECK_DECLS(h_errno, , ,[#include <netdb.h>])
AC_CHECK_DECLS(SHUT_RD, , ,
[
#include <sys/types.h>
#include <sys/socket.h>
])
AC_CHECK_DECLS(O_NONBLOCK, , ,
[
#include <sys/types.h>
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
])
AC_CHECK_DECLS(writev, , , [
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
])
AC_CHECK_FUNCS(setresuid, [
dnl Some platorms have setresuid that isn't implemented, test for this
AC_MSG_CHECKING(if setresuid seems to work)
@ -1637,6 +1744,7 @@ main(void)
AC_MSG_RESULT(no)
AC_DEFINE(BROKEN_GETADDRINFO)
],
[
AC_MSG_RESULT(cross-compiling, assuming no)
]
)
@ -1662,61 +1770,6 @@ fi
AC_FUNC_GETPGRP
# Check for PAM libs
PAM_MSG="no"
AC_ARG_WITH(pam,
[ --with-pam Enable PAM support ],
[
if test "x$withval" != "xno" ; then
if test "x$ac_cv_header_security_pam_appl_h" != "xyes" && \
test "x$ac_cv_header_pam_pam_appl_h" != "xyes" ; then
AC_MSG_ERROR([PAM headers not found])
fi
AC_CHECK_LIB(dl, dlopen, , )
AC_CHECK_LIB(pam, pam_set_item, , AC_MSG_ERROR([*** libpam missing]))
AC_CHECK_FUNCS(pam_getenvlist)
AC_CHECK_FUNCS(pam_putenv)
PAM_MSG="yes"
AC_DEFINE(USE_PAM, 1,
[Define if you want to enable PAM support])
if test $ac_cv_lib_dl_dlopen = yes; then
LIBPAM="-lpam -ldl"
else
LIBPAM="-lpam"
fi
AC_SUBST(LIBPAM)
fi
]
)
# Check for older PAM
if test "x$PAM_MSG" = "xyes" ; then
# Check PAM strerror arguments (old PAM)
AC_MSG_CHECKING([whether pam_strerror takes only one argument])
AC_TRY_COMPILE(
[
#include <stdlib.h>
#if defined(HAVE_SECURITY_PAM_APPL_H)
#include <security/pam_appl.h>
#elif defined (HAVE_PAM_PAM_APPL_H)
#include <pam/pam_appl.h>
#endif
],
[(void)pam_strerror((pam_handle_t *)NULL, -1);],
[AC_MSG_RESULT(no)],
[
AC_DEFINE(HAVE_OLD_PAM, 1,
[Define if you have an old version of PAM
which takes only one argument to pam_strerror])
AC_MSG_RESULT(yes)
PAM_MSG="yes (old library)"
]
)
fi
# Search for OpenSSL
saved_CPPFLAGS="$CPPFLAGS"
saved_LDFLAGS="$LDFLAGS"
@ -1862,13 +1915,61 @@ Also see contrib/findssl.sh for help identifying header/library mismatches.])
]
)
AC_MSG_CHECKING([if programs using OpenSSL functions will link])
AC_LINK_IFELSE(
[AC_LANG_SOURCE([[
#include <openssl/evp.h>
int main(void) { SSLeay_add_all_algorithms(); }
]])],
[
AC_MSG_RESULT(yes)
],
[
AC_MSG_RESULT(no)
saved_LIBS="$LIBS"
LIBS="$LIBS -ldl"
AC_MSG_CHECKING([if programs using OpenSSL need -ldl])
AC_LINK_IFELSE(
[AC_LANG_SOURCE([[
#include <openssl/evp.h>
int main(void) { SSLeay_add_all_algorithms(); }
]])],
[
AC_MSG_RESULT(yes)
],
[
AC_MSG_RESULT(no)
LIBS="$saved_LIBS"
]
)
]
)
AC_ARG_WITH(ssl-engine,
[ --with-ssl-engine Enable OpenSSL (hardware) ENGINE support ],
[ if test "x$withval" != "xno" ; then
AC_MSG_CHECKING(for OpenSSL ENGINE support)
AC_TRY_COMPILE(
[ #include <openssl/engine.h>],
[
int main(void){ENGINE_load_builtin_engines();ENGINE_register_all_complete();}
],
[ AC_MSG_RESULT(yes)
AC_DEFINE(USE_OPENSSL_ENGINE, 1,
[Enable OpenSSL engine support])
],
[ AC_MSG_ERROR(OpenSSL ENGINE support not found)]
)
fi ]
)
# Check for OpenSSL without EVP_aes_{192,256}_cbc
AC_MSG_CHECKING([whether OpenSSL has crippled AES support])
AC_COMPILE_IFELSE(
AC_LINK_IFELSE(
[AC_LANG_SOURCE([[
#include <string.h>
#include <openssl/evp.h>
int main(void) { exit(EVP_aes_192_cbc() == NULL || EVP_aes_256_cbc() == NULL)}
int main(void) { exit(EVP_aes_192_cbc() == NULL || EVP_aes_256_cbc() == NULL);}
]])],
[
AC_MSG_RESULT(no)
@ -1892,6 +1993,9 @@ if test "x$check_for_libcrypt_later" = "x1"; then
AC_CHECK_LIB(crypt, crypt, LIBS="$LIBS -lcrypt")
fi
# Search for SHA256 support in libc and/or OpenSSL
AC_CHECK_FUNCS(SHA256_Update EVP_sha256)
AC_CHECK_LIB(iaf, ia_openinfo)
### Configure cryptographic random number support
@ -1922,6 +2026,69 @@ int main(void) { exit(RAND_status() == 1 ? 0 : 1); }
]
)
# Check for PAM libs
PAM_MSG="no"
AC_ARG_WITH(pam,
[ --with-pam Enable PAM support ],
[
if test "x$withval" != "xno" ; then
if test "x$ac_cv_header_security_pam_appl_h" != "xyes" && \
test "x$ac_cv_header_pam_pam_appl_h" != "xyes" ; then
AC_MSG_ERROR([PAM headers not found])
fi
saved_LIBS="$LIBS"
AC_CHECK_LIB(dl, dlopen, , )
AC_CHECK_LIB(pam, pam_set_item, , AC_MSG_ERROR([*** libpam missing]))
AC_CHECK_FUNCS(pam_getenvlist)
AC_CHECK_FUNCS(pam_putenv)
LIBS="$saved_LIBS"
PAM_MSG="yes"
LIBPAM="-lpam"
AC_DEFINE(USE_PAM, 1,
[Define if you want to enable PAM support])
if test $ac_cv_lib_dl_dlopen = yes; then
case "$LIBS" in
*-ldl*)
# libdl already in LIBS
;;
*)
LIBPAM="$LIBPAM -ldl"
;;
esac
fi
AC_SUBST(LIBPAM)
fi
]
)
# Check for older PAM
if test "x$PAM_MSG" = "xyes" ; then
# Check PAM strerror arguments (old PAM)
AC_MSG_CHECKING([whether pam_strerror takes only one argument])
AC_TRY_COMPILE(
[
#include <stdlib.h>
#if defined(HAVE_SECURITY_PAM_APPL_H)
#include <security/pam_appl.h>
#elif defined (HAVE_PAM_PAM_APPL_H)
#include <pam/pam_appl.h>
#endif
],
[(void)pam_strerror((pam_handle_t *)NULL, -1);],
[AC_MSG_RESULT(no)],
[
AC_DEFINE(HAVE_OLD_PAM, 1,
[Define if you have an old version of PAM
which takes only one argument to pam_strerror])
AC_MSG_RESULT(yes)
PAM_MSG="yes (old library)"
]
)
fi
# Do we want to force the use of the rand helper?
AC_ARG_WITH(rand-helper,
@ -2141,6 +2308,34 @@ if test -z "$have_llong_max"; then
#define __USE_ISOC99
#include <limits.h>
#define DATA "conftest.llminmax"
#define my_abs(a) ((a) < 0 ? ((a) * -1) : (a))
/*
* printf in libc on some platforms (eg old Tru64) does not understand %lld so
* we do this the hard way.
*/
static int
fprint_ll(FILE *f, long long n)
{
unsigned int i;
int l[sizeof(long long) * 8];
if (n < 0)
if (fprintf(f, "-") < 0)
return -1;
for (i = 0; n != 0; i++) {
l[i] = my_abs(n % 10);
n /= 10;
}
do {
if (fprintf(f, "%d", l[--i]) < 0)
return -1;
} while (i != 0);
if (fprintf(f, " ") < 0)
return -1;
return 0;
}
int main(void) {
FILE *f;
long long i, llmin, llmax = 0;
@ -2162,14 +2357,18 @@ int main(void) {
/* Sanity check */
if (llmin + 1 < llmin || llmin - 1 < llmin || llmax + 1 > llmax
|| llmax - 1 > llmax) {
|| llmax - 1 > llmax || llmin == llmax || llmin == 0
|| llmax == 0 || llmax < LONG_MAX || llmin > LONG_MIN) {
fprintf(f, "unknown unknown\n");
exit(2);
}
if (fprintf(f ,"%lld %lld", llmin, llmax) < 0)
if (fprint_ll(f, llmin) < 0)
exit(3);
if (fprint_ll(f, llmax) < 0)
exit(4);
if (fclose(f) < 0)
exit(5);
exit(0);
}
]])],
@ -2177,17 +2376,6 @@ int main(void) {
llong_min=`$AWK '{print $1}' conftest.llminmax`
llong_max=`$AWK '{print $2}' conftest.llminmax`
# snprintf on some Tru64s doesn't understand "%lld"
case "$host" in
alpha-dec-osf*)
if test "x$ac_cv_sizeof_long_long_int" = "x8" &&
test "x$llong_max" = "xld"; then
llong_min="-9223372036854775808"
llong_max="9223372036854775807"
fi
;;
esac
AC_MSG_RESULT($llong_max)
AC_DEFINE_UNQUOTED(LLONG_MAX, [${llong_max}LL],
[max value of long long calculated by configure])
@ -2937,7 +3125,7 @@ AC_ARG_WITH(opensc,
LIBOPENSC_CFLAGS=`$OPENSC_CONFIG --cflags`
LIBOPENSC_LIBS=`$OPENSC_CONFIG --libs`
CPPFLAGS="$CPPFLAGS $LIBOPENSC_CFLAGS"
LDFLAGS="$LDFLAGS $LIBOPENSC_LIBS"
LIBS="$LIBS $LIBOPENSC_LIBS"
AC_DEFINE(SMARTCARD)
AC_DEFINE(USE_OPENSC, 1,
[Define if you want smartcard support
@ -2985,6 +3173,23 @@ int main()
[#include <arpa/nameser.h>])
])
# Check whether user wants SELinux support
SELINUX_MSG="no"
LIBSELINUX=""
AC_ARG_WITH(selinux,
[ --with-selinux Enable SELinux support],
[ if test "x$withval" != "xno" ; then
AC_DEFINE(WITH_SELINUX,1,[Define if you want SELinux support.])
SELINUX_MSG="yes"
AC_CHECK_HEADER([selinux/selinux.h], ,
AC_MSG_ERROR(SELinux support requires selinux.h header))
AC_CHECK_LIB(selinux, setexeccon, [ LIBSELINUX="-lselinux" ],
AC_MSG_ERROR(SELinux support requires libselinux library))
AC_CHECK_FUNCS(getseuserbyname get_default_context_with_level)
fi ]
)
AC_SUBST(LIBSELINUX)
# Check whether user wants Kerberos 5 support
KRB5_MSG="no"
AC_ARG_WITH(kerberos5,
@ -3747,20 +3952,13 @@ if test ! -z "$blibpath" ; then
AC_MSG_WARN([Please check and edit blibpath in LDFLAGS in Makefile])
fi
dnl remove pam and dl because they are in $LIBPAM
if test "$PAM_MSG" = yes ; then
LIBS=`echo $LIBS | sed 's/-lpam //'`
fi
if test "$ac_cv_lib_pam_pam_set_item" = yes ; then
LIBS=`echo $LIBS | sed 's/-ldl //'`
fi
dnl Adding -Werror to CFLAGS early prevents configure tests from running.
dnl Add now.
CFLAGS="$CFLAGS $werror_flags"
AC_EXEEXT
AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openbsd-compat/Makefile \
AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openssh.xml \
openbsd-compat/Makefile openbsd-compat/regress/Makefile \
scard/Makefile ssh_prng_cmds survey.sh])
AC_OUTPUT
@ -3802,13 +4000,16 @@ echo " sshd superuser user PATH: $J"
fi
echo " Manpage format: $MANTYPE"
echo " PAM support: $PAM_MSG"
echo " OSF SIA support: $SIA_MSG"
echo " KerberosV support: $KRB5_MSG"
echo " SELinux support: $SELINUX_MSG"
echo " Smartcard support: $SCARD_MSG"
echo " S/KEY support: $SKEY_MSG"
echo " OPIE support: $OPIE_MSG"
echo " TCP Wrappers support: $TCPW_MSG"
echo " MD5 password support: $MD5_MSG"
echo " libedit support: $LIBEDIT_MSG"
echo " Solaris process contract support: $SPC_MSG"
echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
echo " Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
echo " BSD Auth support: $BSD_AUTH_MSG"

View File

@ -1,3 +1,4 @@
/* $OpenBSD: hostfile.c,v 1.45 2006/08/03 03:34:42 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -36,18 +37,25 @@
*/
#include "includes.h"
RCSID("$OpenBSD: hostfile.c,v 1.36 2005/11/22 03:36:03 dtucker Exp $");
#include <resolv.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <openssl/hmac.h>
#include <openssl/sha.h>
#include "packet.h"
#include <resolv.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xmalloc.h"
#include "match.h"
#include "key.h"
#include "hostfile.h"
#include "log.h"
#include "xmalloc.h"
static int
extract_salt(const char *s, u_int l, char *salt, size_t salt_len)
@ -254,8 +262,10 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
if (key == NULL) {
/* we found a key of the requested type */
if (found->type == keytype)
if (found->type == keytype) {
fclose(f);
return HOST_FOUND;
}
continue;
}

View File

@ -1,5 +1,5 @@
/* $OpenBSD: includes.h,v 1.22 2006/01/01 08:59:27 stevesk Exp $ */
/* $FreeBSD$ */
/* $OpenBSD: includes.h,v 1.54 2006/07/22 20:48:23 stevesk Exp $ */
/* $FreeBSD$ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -17,44 +17,24 @@
#ifndef INCLUDES_H
#define INCLUDES_H
#define RCSID(msg) \
__RCSID(msg)
#include "config.h"
#define _GNU_SOURCE /* activate extra prototypes for glibc */
#include <stdarg.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h> /* For O_NONBLOCK */
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <dirent.h>
#include <stddef.h>
#include <sys/types.h>
#include <sys/socket.h> /* For CMSG_* */
#ifdef HAVE_LIMITS_H
# include <limits.h> /* For PATH_MAX */
#endif
#ifdef HAVE_GETOPT_H
# include <getopt.h>
#endif
#ifdef HAVE_BSTRING_H
# include <bstring.h>
#endif
#if defined(HAVE_GLOB_H) && defined(GLOB_HAS_ALTDIRFUNC) && \
defined(GLOB_HAS_GL_MATCHC)
defined(GLOB_HAS_GL_MATCHC) && \
defined(HAVE_DECL_GLOB_NOMATCH) && HAVE_DECL_GLOB_NOMATCH != 0
# include <glob.h>
#endif
#ifdef HAVE_NETGROUP_H
# include <netgroup.h>
#endif
#ifdef HAVE_ENDIAN_H
# include <endian.h>
#endif
@ -68,10 +48,11 @@ __RCSID(msg)
# include <maillock.h> /* For _PATH_MAILDIR */
#endif
#ifdef HAVE_NEXT
# include <libc.h>
# include <libc.h>
#endif
#ifdef HAVE_PATHS
# include <paths.h>
#endif
#include <unistd.h> /* For STDIN_FILENO, etc */
#include <termios.h> /* Struct winsize */
/*
*-*-nto-qnx needs these headers for strcasecmp and LASTLOG_FILE respectively
@ -87,39 +68,22 @@ __RCSID(msg)
# include <utmp.h>
#endif
#ifdef HAVE_UTMPX_H
# ifdef HAVE_TV_IN_UTMPX
# include <sys/time.h>
# endif
# include <utmpx.h>
#endif
#ifdef HAVE_LASTLOG_H
# include <lastlog.h>
#endif
#ifdef HAVE_PATHS_H
# include <paths.h> /* For _PATH_XXX */
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h> /* For timersub */
#endif
#include <sys/resource.h>
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
#ifdef HAVE_SYS_BSDTTY_H
# include <sys/bsdtty.h>
#endif
#include <sys/param.h> /* For MAXPATHLEN and roundup() */
#ifdef HAVE_SYS_UN_H
# include <sys/un.h> /* For sockaddr_un */
#endif
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#include <termios.h>
#ifdef HAVE_SYS_BITYPES_H
# include <sys/bitypes.h> /* For u_intXX_t */
#endif
@ -145,14 +109,8 @@ __RCSID(msg)
#include <sys/ptms.h> /* for grantpt() and friends */
#endif
#include <netinet/in.h>
#include <netinet/in_systm.h> /* For typedefs */
#include <netinet/in.h> /* For IPv6 macros */
#include <netinet/ip.h> /* For IPTOS macros */
#include <netinet/tcp.h>
#include <arpa/inet.h>
#if defined(HAVE_NETDB_H)
# include <netdb.h>
#endif
#ifdef HAVE_RPC_TYPES_H
# include <rpc/types.h> /* For INADDR_LOOPBACK */
#endif
@ -206,7 +164,7 @@ __RCSID(msg)
#include "defines.h"
#include "version.h"
#include "platform.h"
#include "openbsd-compat/openbsd-compat.h"
#include "openbsd-compat/bsd-nextstep.h"

View File

@ -1,3 +1,4 @@
/* $OpenBSD: key.c,v 1.67 2006/08/03 03:34:42 deraadt Exp $ */
/*
* read_bignum():
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -31,17 +32,22 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
RCSID("$OpenBSD: key.c,v 1.58 2005/06/17 02:44:32 djm Exp $");
#include <sys/types.h>
#include <openssl/evp.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "xmalloc.h"
#include "key.h"
#include "rsa.h"
#include "uuencode.h"
#include "buffer.h"
#include "bufaux.h"
#include "log.h"
Key *
@ -50,9 +56,8 @@ key_new(int type)
Key *k;
RSA *rsa;
DSA *dsa;
k = xmalloc(sizeof(*k));
k = xcalloc(1, sizeof(*k));
k->type = type;
k->flags = 0;
k->dsa = NULL;
k->rsa = NULL;
switch (k->type) {
@ -123,6 +128,8 @@ key_new_private(int type)
void
key_free(Key *k)
{
if (k == NULL)
fatal("key_free: key is NULL");
switch (k->type) {
case KEY_RSA1:
case KEY_RSA:
@ -155,14 +162,12 @@ key_equal(const Key *a, const Key *b)
return a->rsa != NULL && b->rsa != NULL &&
BN_cmp(a->rsa->e, b->rsa->e) == 0 &&
BN_cmp(a->rsa->n, b->rsa->n) == 0;
break;
case KEY_DSA:
return a->dsa != NULL && b->dsa != NULL &&
BN_cmp(a->dsa->p, b->dsa->p) == 0 &&
BN_cmp(a->dsa->q, b->dsa->q) == 0 &&
BN_cmp(a->dsa->g, b->dsa->g) == 0 &&
BN_cmp(a->dsa->pub_key, b->dsa->pub_key) == 0;
break;
default:
fatal("key_equal: bad key type %d", a->type);
break;
@ -209,7 +214,6 @@ key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
break;
case KEY_UNSPEC:
return retval;
break;
default:
fatal("key_fingerprint_raw: bad key type %d", k->type);
break;
@ -233,8 +237,7 @@ key_fingerprint_hex(u_char *dgst_raw, u_int dgst_raw_len)
char *retval;
u_int i;
retval = xmalloc(dgst_raw_len * 3 + 1);
retval[0] = '\0';
retval = xcalloc(1, dgst_raw_len * 3 + 1);
for (i = 0; i < dgst_raw_len; i++) {
char hex[4];
snprintf(hex, sizeof(hex), "%02x:", dgst_raw[i]);
@ -256,7 +259,7 @@ key_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len)
char *retval;
rounds = (dgst_raw_len / 2) + 1;
retval = xmalloc(sizeof(char) * (rounds*6));
retval = xcalloc((rounds * 6), sizeof(char));
retval[j++] = 'x';
for (i = 0; i < rounds; i++) {
u_int idx0, idx1, idx2, idx3, idx4;
@ -530,13 +533,10 @@ key_type(const Key *k)
switch (k->type) {
case KEY_RSA1:
return "RSA1";
break;
case KEY_RSA:
return "RSA";
break;
case KEY_DSA:
return "DSA";
break;
}
return "unknown";
}
@ -547,10 +547,8 @@ key_ssh_name(const Key *k)
switch (k->type) {
case KEY_RSA:
return "ssh-rsa";
break;
case KEY_DSA:
return "ssh-dss";
break;
}
return "ssh-unknown";
}
@ -562,10 +560,8 @@ key_size(const Key *k)
case KEY_RSA1:
case KEY_RSA:
return BN_num_bits(k->rsa->n);
break;
case KEY_DSA:
return BN_num_bits(k->dsa->p);
break;
}
return 0;
}
@ -574,6 +570,7 @@ static RSA *
rsa_generate_private_key(u_int bits)
{
RSA *private;
private = RSA_generate_key(bits, 35, NULL, NULL);
if (private == NULL)
fatal("rsa_generate_private_key: key generation failed.");
@ -584,6 +581,7 @@ static DSA*
dsa_generate_private_key(u_int bits)
{
DSA *private = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
if (private == NULL)
fatal("dsa_generate_private_key: DSA_generate_parameters failed");
if (!DSA_generate_key(private))
@ -793,14 +791,11 @@ key_sign(
switch (key->type) {
case KEY_DSA:
return ssh_dss_sign(key, sigp, lenp, data, datalen);
break;
case KEY_RSA:
return ssh_rsa_sign(key, sigp, lenp, data, datalen);
break;
default:
error("key_sign: invalid key type %d", key->type);
return -1;
break;
}
}
@ -820,14 +815,11 @@ key_verify(
switch (key->type) {
case KEY_DSA:
return ssh_dss_verify(key, signature, signaturelen, data, datalen);
break;
case KEY_RSA:
return ssh_rsa_verify(key, signature, signaturelen, data, datalen);
break;
default:
error("key_verify: invalid key type %d", key->type);
return -1;
break;
}
}
@ -837,7 +829,7 @@ key_demote(const Key *k)
{
Key *pk;
pk = xmalloc(sizeof(*pk));
pk = xcalloc(1, sizeof(*pk));
pk->type = k->type;
pk->flags = k->flags;
pk->dsa = NULL;

View File

@ -1,5 +1,5 @@
/* $OpenBSD: log.h,v 1.11 2004/06/21 22:02:58 djm Exp $ */
/* $FreeBSD$ */
/* $OpenBSD: log.h,v 1.15 2006/08/18 09:13:25 deraadt Exp $ */
/* $FreeBSD$ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -16,8 +16,6 @@
#ifndef SSH_LOG_H
#define SSH_LOG_H
#include <syslog.h> /* Needed for LOG_AUTHPRIV (if present) */
/* Supported syslog facilities and levels. */
typedef enum {
SYSLOG_FACILITY_DAEMON,
@ -64,6 +62,7 @@ LogLevel log_level_number(char *);
void fatal(const char *, ...) __dead __attribute__((format(printf, 1, 2)));
void error(const char *, ...) __attribute__((format(printf, 1, 2)));
void sigdie(const char *, ...) __attribute__((format(printf, 1, 2)));
void logit(const char *, ...) __attribute__((format(printf, 1, 2)));
void verbose(const char *, ...) __attribute__((format(printf, 1, 2)));
void debug(const char *, ...) __attribute__((format(printf, 1, 2)));

View File

@ -146,9 +146,28 @@
*/
#include "includes.h"
__RCSID("$FreeBSD$");
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_PATHS_H
# include <paths.h>
#endif
#include <pwd.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include "ssh.h"
#include "xmalloc.h"
#include "key.h"
#include "hostfile.h"
#include "ssh.h"
#include "loginrec.h"
#include "log.h"
#include "atomicio.h"
@ -165,9 +184,6 @@
# include <libutil.h>
#endif
RCSID("$Id: loginrec.c,v 1.71 2005/11/22 08:55:13 dtucker Exp $");
RCSID("$FreeBSD$");
/**
** prototypes for helper functions in this file
**/

View File

@ -1,3 +1,4 @@
/* $OpenBSD: monitor.c,v 1.88 2006/08/12 20:46:46 miod Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -25,10 +26,25 @@
*/
#include "includes.h"
RCSID("$OpenBSD: monitor.c,v 1.64 2005/10/13 22:24:31 stevesk Exp $");
RCSID("$FreeBSD$");
__RCSID("$FreeBSD$");
#include <openssl/dh.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include "openbsd-compat/sys-tree.h"
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#include <pwd.h>
#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef SKEY
#ifdef OPIE
@ -42,8 +58,15 @@ RCSID("$FreeBSD$");
#endif
#endif
#include <openssl/dh.h>
#include "xmalloc.h"
#include "ssh.h"
#include "key.h"
#include "buffer.h"
#include "hostfile.h"
#include "auth.h"
#include "cipher.h"
#include "kex.h"
#include "dh.h"
#ifdef TARGET_OS_MAC /* XXX Broken krb5 headers on Mac */
@ -64,17 +87,16 @@ RCSID("$FreeBSD$");
#include "servconf.h"
#include "monitor.h"
#include "monitor_mm.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
#include "monitor_wrap.h"
#include "monitor_fdpass.h"
#include "xmalloc.h"
#include "misc.h"
#include "buffer.h"
#include "bufaux.h"
#include "compat.h"
#include "ssh2.h"
#ifdef GSSAPI
#include "ssh-gss.h"
static Gssctxt *gsscontext = NULL;
#endif
@ -180,6 +202,7 @@ struct mon_table {
#define MON_ISAUTH 0x0004 /* Required for Authentication */
#define MON_AUTHDECIDE 0x0008 /* Decides Authentication */
#define MON_ONCE 0x0010 /* Disable after calling */
#define MON_ALOG 0x0020 /* Log auth attempt without authenticating */
#define MON_AUTH (MON_ISAUTH|MON_AUTHDECIDE)
@ -205,7 +228,7 @@ struct mon_table mon_dispatch_proto20[] = {
#endif
#ifdef BSD_AUTH
{MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
{MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond},
{MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH, mm_answer_bsdauthrespond},
#endif
#ifdef SKEY
{MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
@ -240,13 +263,13 @@ struct mon_table mon_dispatch_proto15[] = {
{MONITOR_REQ_SESSKEY, MON_ONCE, mm_answer_sesskey},
{MONITOR_REQ_SESSID, MON_ONCE, mm_answer_sessid},
{MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
{MONITOR_REQ_RSAKEYALLOWED, MON_ISAUTH, mm_answer_rsa_keyallowed},
{MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed},
{MONITOR_REQ_RSAKEYALLOWED, MON_ISAUTH|MON_ALOG, mm_answer_rsa_keyallowed},
{MONITOR_REQ_KEYALLOWED, MON_ISAUTH|MON_ALOG, mm_answer_keyallowed},
{MONITOR_REQ_RSACHALLENGE, MON_ONCE, mm_answer_rsa_challenge},
{MONITOR_REQ_RSARESPONSE, MON_ONCE|MON_AUTHDECIDE, mm_answer_rsa_response},
#ifdef BSD_AUTH
{MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
{MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond},
{MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH, mm_answer_bsdauthrespond},
#endif
#ifdef SKEY
{MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
@ -335,6 +358,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
/* The first few requests do not require asynchronous access */
while (!authenticated) {
auth_method = "unknown";
authenticated = monitor_read(pmonitor, mon_dispatch, &ent);
if (authenticated) {
if (!(ent->flags & MON_AUTHDECIDE))
@ -357,7 +381,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
#endif
}
if (ent->flags & MON_AUTHDECIDE) {
if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) {
auth_log(authctxt, authenticated, auth_method,
compat20 ? " ssh2" : "");
if (!authenticated)
@ -367,6 +391,8 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
if (!authctxt->valid)
fatal("%s: authenticated invalid user", __func__);
if (strcmp(auth_method, "unknown") == 0)
fatal("%s: authentication method name unknown", __func__);
debug("%s: %s has been authenticated by privileged process",
__func__, authctxt->user);
@ -546,7 +572,11 @@ mm_answer_sign(int sock, Buffer *m)
keyid = buffer_get_int(m);
p = buffer_get_string(m, &datlen);
if (datlen != 20)
/*
* Supported KEX types will only return SHA1 (20 byte) or
* SHA256 (32 byte) hashes
*/
if (datlen != 20 && datlen != 32)
fatal("%s: data length incorrect: %u", __func__, datlen);
/* save session id, it will be passed on the first call */
@ -899,6 +929,7 @@ mm_answer_pam_query(int sock, Buffer *m)
xfree(prompts);
if (echo_on != NULL)
xfree(echo_on);
auth_method = "keyboard-interactive/pam";
mm_request_send(sock, MONITOR_ANS_PAM_QUERY, m);
return (0);
}
@ -914,7 +945,7 @@ mm_answer_pam_respond(int sock, Buffer *m)
sshpam_authok = NULL;
num = buffer_get_int(m);
if (num > 0) {
resp = xmalloc(num * sizeof(char *));
resp = xcalloc(num, sizeof(char *));
for (i = 0; i < num; ++i)
resp[i] = buffer_get_string(m, NULL);
ret = (sshpam_device.respond)(sshpam_ctxt, num, resp);
@ -941,6 +972,7 @@ mm_answer_pam_free_ctx(int sock, Buffer *m)
(sshpam_device.free_ctx)(sshpam_ctxt);
buffer_clear(m);
mm_request_send(sock, MONITOR_ANS_PAM_FREE_CTX, m);
auth_method = "keyboard-interactive/pam";
return (sshpam_authok == sshpam_ctxt);
}
#endif
@ -986,17 +1018,20 @@ mm_answer_keyallowed(int sock, Buffer *m)
case MM_USERKEY:
allowed = options.pubkey_authentication &&
user_key_allowed(authctxt->pw, key);
auth_method = "publickey";
break;
case MM_HOSTKEY:
allowed = options.hostbased_authentication &&
hostbased_key_allowed(authctxt->pw,
cuser, chost, key);
auth_method = "hostbased";
break;
case MM_RSAHOSTKEY:
key->type = KEY_RSA1; /* XXX */
allowed = options.rhosts_rsa_authentication &&
auth_rhosts_rsa_key_allowed(authctxt->pw,
cuser, chost, key);
auth_method = "rsa";
break;
default:
fatal("%s: unknown key type %d", __func__, type);
@ -1016,6 +1051,12 @@ mm_answer_keyallowed(int sock, Buffer *m)
key_blobtype = type;
hostbased_cuser = cuser;
hostbased_chost = chost;
} else {
/* Log failed attempt */
auth_log(authctxt, 0, auth_method, compat20 ? " ssh2" : "");
xfree(blob);
xfree(cuser);
xfree(chost);
}
debug3("%s: key %p is %s",
@ -1217,7 +1258,7 @@ mm_record_login(Session *s, struct passwd *pw)
fromlen = sizeof(from);
if (packet_connection_is_on_socket()) {
if (getpeername(packet_get_connection_in(),
(struct sockaddr *) & from, &fromlen) < 0) {
(struct sockaddr *)&from, &fromlen) < 0) {
debug("getpeername: %.100s", strerror(errno));
cleanup_exit(255);
}
@ -1233,7 +1274,7 @@ mm_session_close(Session *s)
{
debug3("%s: session %d pid %ld", __func__, s->self, (long)s->pid);
if (s->ttyfd != -1) {
debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd);
debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd);
session_pty_cleanup2(s);
}
s->used = 0;
@ -1293,7 +1334,7 @@ mm_answer_pty(int sock, Buffer *m)
/* no need to dup() because nobody closes ptyfd */
s->ptymaster = s->ptyfd;
debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ttyfd);
debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ttyfd);
return (0);
@ -1380,6 +1421,7 @@ mm_answer_rsa_keyallowed(int sock, Buffer *m)
debug3("%s entering", __func__);
auth_method = "rsa";
if (options.rsa_authentication && authctxt->valid) {
if ((client_n = BN_new()) == NULL)
fatal("%s: BN_new", __func__);
@ -1616,8 +1658,7 @@ mm_get_kex(Buffer *m)
void *blob;
u_int bloblen;
kex = xmalloc(sizeof(*kex));
memset(kex, 0, sizeof(*kex));
kex = xcalloc(1, sizeof(*kex));
kex->session_id = buffer_get_string(m, &kex->session_id_len);
if ((session_id2 == NULL) ||
(kex->session_id_len != session_id2_len) ||
@ -1627,6 +1668,7 @@ mm_get_kex(Buffer *m)
kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
kex->server = 1;
kex->hostkey_type = buffer_get_int(m);
kex->kex_type = buffer_get_int(m);
@ -1786,9 +1828,8 @@ monitor_init(void)
struct monitor *mon;
int pair[2];
mon = xmalloc(sizeof(*mon));
mon = xcalloc(1, sizeof(*mon));
mon->m_pid = 0;
monitor_socketpair(pair);
mon->m_recvfd = pair[0];

View File

@ -1,5 +1,5 @@
/* $OpenBSD: monitor.h,v 1.13 2003/11/17 11:06:07 markus Exp $ */
/* $FreeBSD$ */
/* $OpenBSD: monitor.h,v 1.14 2006/03/25 22:22:43 djm Exp $ */
/* $FreeBSD$ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>

View File

@ -1,3 +1,4 @@
/* $OpenBSD: monitor_wrap.c,v 1.54 2006/08/12 20:46:46 miod Exp $ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* Copyright 2002 Markus Friedl <markus@openbsd.org>
@ -25,19 +26,32 @@
*/
#include "includes.h"
RCSID("$OpenBSD: monitor_wrap.c,v 1.40 2005/05/24 17:32:43 avsm Exp $");
RCSID("$FreeBSD$");
__RCSID("$FreeBSD$");
#include <sys/types.h>
#include <sys/uio.h>
#include <errno.h>
#include <pwd.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <openssl/bn.h>
#include <openssl/dh.h>
#include "xmalloc.h"
#include "ssh.h"
#include "dh.h"
#include "buffer.h"
#include "key.h"
#include "cipher.h"
#include "kex.h"
#include "hostfile.h"
#include "auth.h"
#include "auth-options.h"
#include "buffer.h"
#include "bufaux.h"
#include "packet.h"
#include "mac.h"
#include "log.h"
@ -49,20 +63,17 @@ RCSID("$FreeBSD$");
#include "zlib.h"
#endif
#include "monitor.h"
#include "monitor_wrap.h"
#include "xmalloc.h"
#include "atomicio.h"
#include "monitor_fdpass.h"
#include "getput.h"
#include "servconf.h"
#include "auth.h"
#include "channels.h"
#include "session.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
#include "monitor_wrap.h"
#include "atomicio.h"
#include "monitor_fdpass.h"
#include "misc.h"
#include "servconf.h"
#include "channels.h"
#include "session.h"
/* Imports */
extern int compat20;
@ -92,7 +103,7 @@ mm_request_send(int sock, enum monitor_reqtype type, Buffer *m)
debug3("%s entering: type %d", __func__, type);
PUT_32BIT(buf, mlen + 1);
put_u32(buf, mlen + 1);
buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */
if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf))
fatal("%s: write: %s", __func__, strerror(errno));
@ -113,7 +124,7 @@ mm_request_receive(int sock, Buffer *m)
cleanup_exit(255);
fatal("%s: read: %s", __func__, strerror(errno));
}
msg_len = GET_32BIT(buf);
msg_len = get_u32(buf);
if (msg_len > 256 * 1024)
fatal("%s: read: bad msg_len %d", __func__, msg_len);
buffer_clear(m);
@ -638,7 +649,7 @@ mm_send_keystate(struct monitor *monitor)
}
int
mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
{
Buffer m;
char *p, *msg;
@ -777,8 +788,11 @@ mm_sshpam_query(void *ctx, char **name, char **info,
*name = buffer_get_string(&m, NULL);
*info = buffer_get_string(&m, NULL);
*num = buffer_get_int(&m);
*prompts = xmalloc((*num + 1) * sizeof(char *));
*echo_on = xmalloc((*num + 1) * sizeof(u_int));
if (*num > PAM_MAX_NUM_MSG)
fatal("%s: recieved %u PAM messages, expected <= %u",
__func__, *num, PAM_MAX_NUM_MSG);
*prompts = xcalloc((*num + 1), sizeof(char *));
*echo_on = xcalloc((*num + 1), sizeof(u_int));
for (i = 0; i < *num; ++i) {
(*prompts)[i] = buffer_get_string(&m, NULL);
(*echo_on)[i] = buffer_get_int(&m);
@ -861,8 +875,8 @@ mm_chall_setup(char **name, char **infotxt, u_int *numprompts,
*name = xstrdup("");
*infotxt = xstrdup("");
*numprompts = 1;
*prompts = xmalloc(*numprompts * sizeof(char *));
*echo_on = xmalloc(*numprompts * sizeof(u_int));
*prompts = xcalloc(*numprompts, sizeof(char *));
*echo_on = xcalloc(*numprompts, sizeof(u_int));
(*echo_on)[0] = 0;
}
@ -929,9 +943,8 @@ mm_skey_query(void *ctx, char **name, char **infotxt,
u_int *numprompts, char ***prompts, u_int **echo_on)
{
Buffer m;
int len;
u_int success;
char *p, *challenge;
char *challenge;
debug3("%s: entering", __func__);
@ -955,11 +968,7 @@ mm_skey_query(void *ctx, char **name, char **infotxt,
mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
len = strlen(challenge) + strlen(SKEY_PROMPT) + 1;
p = xmalloc(len);
strlcpy(p, challenge, len);
strlcat(p, SKEY_PROMPT, len);
(*prompts)[0] = p;
xasprintf(*prompts, "%s%s", challenge, SKEY_PROMPT);
xfree(challenge);
return (0);

View File

@ -1,5 +1,5 @@
/* $OpenBSD: monitor_wrap.h,v 1.14 2004/06/21 17:36:31 avsm Exp $ */
/* $FreeBSD$ */
/* $OpenBSD: monitor_wrap.h,v 1.20 2006/08/03 03:34:42 deraadt Exp $ */
/* $FreeBSD$ */
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
@ -28,8 +28,6 @@
#ifndef _MM_WRAP_H_
#define _MM_WRAP_H_
#include "key.h"
#include "buffer.h"
extern int use_privsep;
#define PRIVSEP(x) (use_privsep ? mm_##x : x)
@ -38,7 +36,6 @@ enum mm_keytype {MM_NOKEY, MM_HOSTKEY, MM_USERKEY, MM_RSAHOSTKEY, MM_RSAUSERKEY}
struct monitor;
struct mm_master;
struct passwd;
struct Authctxt;
int mm_is_monitor(void);
@ -58,7 +55,6 @@ int mm_auth_rsa_verify_response(Key *, BIGNUM *, u_char *);
BIGNUM *mm_auth_rsa_generate_challenge(Key *);
#ifdef GSSAPI
#include "ssh-gss.h"
OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *,
gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *);
@ -83,7 +79,7 @@ void mm_audit_run_command(const char *);
struct Session;
void mm_terminate(void);
int mm_pty_allocate(int *, int *, char *, int);
int mm_pty_allocate(int *, int *, char *, size_t);
void mm_session_pty_cleanup2(struct Session *);
/* SSHv1 interfaces */
@ -112,4 +108,4 @@ void *mm_zalloc(struct mm_master *, u_int, u_int);
void mm_zfree(struct mm_master *, void *);
void mm_init_compression(struct mm_master *);
#endif /* _MM_H_ */
#endif /* _MM_WRAP_H_ */

View File

@ -1,5 +1,5 @@
/* $OpenBSD: myproposal.h,v 1.18 2005/07/25 11:59:39 markus Exp $ */
/* $FreeBSD$ */
/* $OpenBSD: myproposal.h,v 1.21 2006/03/25 22:22:43 djm Exp $ */
/* $FreeBSD$ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -24,9 +24,23 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define KEX_DEFAULT_KEX "diffie-hellman-group-exchange-sha1," \
#include <openssl/opensslv.h>
/* Old OpenSSL doesn't support what we need for DHGEX-sha256 */
#if OPENSSL_VERSION_NUMBER < 0x00907000L
# define KEX_DEFAULT_KEX \
"diffie-hellman-group-exchange-sha1," \
"diffie-hellman-group14-sha1," \
"diffie-hellman-group1-sha1"
#else
# define KEX_DEFAULT_KEX \
"diffie-hellman-group-exchange-sha256," \
"diffie-hellman-group-exchange-sha1," \
"diffie-hellman-group14-sha1," \
"diffie-hellman-group1-sha1"
#endif
#define KEX_DEFAULT_PK_ALG "ssh-dss,ssh-rsa"
#define KEX_DEFAULT_ENCRYPT \
"aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \

View File

@ -1,4 +1,4 @@
/* $Id: fake-rfc2553.h,v 1.12 2005/08/03 05:36:21 dtucker Exp $ */
/* $Id: fake-rfc2553.h,v 1.13 2006/07/24 03:51:52 djm Exp $ */
/* $FreeBSD$ */
/*
@ -42,7 +42,10 @@
#define _FAKE_RFC2553_H
#include "includes.h"
#include "sys/types.h"
#include <sys/types.h>
#if defined(HAVE_NETDB_H)
# include <netdb.h>
#endif
/*
* First, socket and INET6 related definitions

View File

@ -1,4 +1,4 @@
/* $OpenBSD: packet.h,v 1.43 2005/07/25 11:59:40 markus Exp $ */
/* $OpenBSD: packet.h,v 1.45 2006/03/25 22:22:43 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -16,6 +16,8 @@
#ifndef PACKET_H
#define PACKET_H
#include <termios.h>
#include <openssl/bn.h>
void packet_set_connection(int, int);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: pathnames.h,v 1.15 2004/07/11 17:48:47 deraadt Exp $ */
/* $OpenBSD: pathnames.h,v 1.16 2006/03/25 22:22:43 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>

View File

@ -1,3 +1,4 @@
/* $OpenBSD: readconf.c,v 1.159 2006/08/03 03:34:42 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -12,18 +13,34 @@
*/
#include "includes.h"
RCSID("$OpenBSD: readconf.c,v 1.145 2005/12/08 18:34:11 reyk Exp $");
RCSID("$FreeBSD$");
__RCSID("$FreeBSD$");
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "ssh.h"
#include "xmalloc.h"
#include "ssh.h"
#include "compat.h"
#include "cipher.h"
#include "pathnames.h"
#include "log.h"
#include "key.h"
#include "readconf.h"
#include "match.h"
#include "misc.h"
#include "buffer.h"
#include "kex.h"
#include "mac.h"
@ -95,6 +112,7 @@ RCSID("$FreeBSD$");
typedef enum {
oBadOption,
oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
oExitOnForwardFailure,
oPasswordAuthentication, oRSAAuthentication,
oChallengeResponseAuthentication, oXAuthLocation,
oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
@ -126,6 +144,7 @@ static struct {
{ "forwardagent", oForwardAgent },
{ "forwardx11", oForwardX11 },
{ "forwardx11trusted", oForwardX11Trusted },
{ "exitonforwardfailure", oExitOnForwardFailure },
{ "xauthlocation", oXAuthLocation },
{ "gatewayports", oGatewayPorts },
{ "useprivilegedport", oUsePrivilegedPort },
@ -309,7 +328,8 @@ process_config_line(Options *options, const char *host,
int *activep)
{
char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
int opcode, *intptr, value, value2;
int opcode, *intptr, value, value2, scale;
long long orig, val64;
size_t len;
Forward fwd;
@ -322,7 +342,8 @@ process_config_line(Options *options, const char *host,
s = line;
/* Get the keyword. (Each line is supposed to begin with a keyword). */
keyword = strdelim(&s);
if ((keyword = strdelim(&s)) == NULL)
return 0;
/* Ignore leading whitespace. */
if (*keyword == '\0')
keyword = strdelim(&s);
@ -379,6 +400,10 @@ process_config_line(Options *options, const char *host,
intptr = &options->gateway_ports;
goto parse_flag;
case oExitOnForwardFailure:
intptr = &options->exit_on_forward_failure;
goto parse_flag;
case oUsePrivilegedPort:
intptr = &options->use_privileged_port;
goto parse_flag;
@ -482,22 +507,36 @@ process_config_line(Options *options, const char *host,
fatal("%.200s line %d: Missing argument.", filename, linenum);
if (arg[0] < '0' || arg[0] > '9')
fatal("%.200s line %d: Bad number.", filename, linenum);
value = strtol(arg, &endofnumber, 10);
orig = val64 = strtoll(arg, &endofnumber, 10);
if (arg == endofnumber)
fatal("%.200s line %d: Bad number.", filename, linenum);
switch (toupper(*endofnumber)) {
case '\0':
scale = 1;
break;
case 'K':
value *= 1<<10;
scale = 1<<10;
break;
case 'M':
value *= 1<<20;
scale = 1<<20;
break;
case 'G':
value *= 1<<30;
scale = 1<<30;
break;
default:
fatal("%.200s line %d: Invalid RekeyLimit suffix",
filename, linenum);
}
val64 *= scale;
/* detect integer wrap and too-large limits */
if ((val64 / scale) != orig || val64 > INT_MAX)
fatal("%.200s line %d: RekeyLimit too large",
filename, linenum);
if (val64 < 16)
fatal("%.200s line %d: RekeyLimit too small",
filename, linenum);
if (*activep && *intptr == -1)
*intptr = value;
*intptr = (int)val64;
break;
case oIdentityFile:
@ -973,6 +1012,7 @@ initialize_options(Options * options)
options->forward_agent = -1;
options->forward_x11 = -1;
options->forward_x11_trusted = -1;
options->exit_on_forward_failure = -1;
options->xauth_location = NULL;
options->gateway_ports = -1;
options->use_privileged_port = -1;
@ -1053,6 +1093,8 @@ fill_default_options(Options * options)
options->forward_x11 = 0;
if (options->forward_x11_trusted == -1)
options->forward_x11_trusted = 0;
if (options->exit_on_forward_failure == -1)
options->exit_on_forward_failure = 0;
if (options->xauth_location == NULL)
options->xauth_location = _PATH_XAUTH;
if (options->gateway_ports == -1)

View File

@ -1,4 +1,4 @@
/* $OpenBSD: readconf.h,v 1.68 2005/12/06 22:38:27 reyk Exp $ */
/* $OpenBSD: readconf.h,v 1.71 2006/08/03 03:34:42 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -16,8 +16,6 @@
#ifndef READCONF_H
#define READCONF_H
#include "key.h"
/* Data structure for representing a forwarding request. */
typedef struct {
@ -34,6 +32,7 @@ typedef struct {
int forward_agent; /* Forward authentication agent. */
int forward_x11; /* Forward X11 display. */
int forward_x11_trusted; /* Trust Forward X11 display. */
int exit_on_forward_failure; /* Exit if bind(2) fails for -L/-R */
char *xauth_location; /* Location for xauth program */
int gateway_ports; /* Allow remote connects to forwarded ports. */
int use_privileged_port; /* Don't use privileged port if false. */

View File

@ -1,3 +1,4 @@
/* $OpenBSD: rsa.c,v 1.28 2006/08/03 03:34:42 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -60,11 +61,15 @@
*/
#include "includes.h"
RCSID("$OpenBSD: rsa.c,v 1.24 2001/12/27 18:22:16 markus Exp $");
#include <sys/types.h>
#include <stdarg.h>
#include <string.h>
#include "xmalloc.h"
#include "rsa.h"
#include "log.h"
#include "xmalloc.h"
void
rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key)

View File

@ -1,4 +1,4 @@
/* $OpenBSD: rsa.h,v 1.15 2002/03/04 17:27:39 stevesk Exp $ */
/* $OpenBSD: rsa.h,v 1.16 2006/03/25 22:22:43 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>

View File

@ -1,3 +1,4 @@
/* $OpenBSD: scp.c,v 1.155 2006/08/03 03:34:42 deraadt Exp $ */
/*
* scp - secure remote copy. This is basically patched BSD rcp which
* uses ssh to do the data transfer (instead of using rcmd).
@ -71,7 +72,30 @@
*/
#include "includes.h"
RCSID("$OpenBSD: scp.c,v 1.130 2006/01/31 10:35:43 djm Exp $");
#include <sys/types.h>
#include <sys/param.h>
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <sys/wait.h>
#include <sys/uio.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "xmalloc.h"
#include "atomicio.h"
@ -82,6 +106,8 @@ RCSID("$OpenBSD: scp.c,v 1.130 2006/01/31 10:35:43 djm Exp $");
extern char *__progname;
int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout);
void bwlimit(int);
/* Struct for addargs */
@ -167,7 +193,7 @@ do_local_cmd(arglist *a)
*/
int
do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout)
{
int pin[2], pout[2], reserved[2];
@ -181,7 +207,8 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)
* Reserve two descriptors so that the real pipes won't get
* descriptors 0 and 1 because that will screw up dup2 below.
*/
pipe(reserved);
if (pipe(reserved) < 0)
fatal("pipe: %s", strerror(errno));
/* Create a socket pair for communicating with ssh. */
if (pipe(pin) < 0)
@ -234,7 +261,6 @@ typedef struct {
BUF *allocbuf(BUF *, int, int);
void lostconn(int);
void nospace(void);
int okname(char *);
void run_err(const char *,...);
void verifydir(char *);
@ -258,15 +284,21 @@ void usage(void);
int
main(int argc, char **argv)
{
int ch, fflag, tflag, status;
int ch, fflag, tflag, status, n;
double speed;
char *targ, *endp;
char *targ, *endp, **newargv;
extern char *optarg;
extern int optind;
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
/* Copy argv, because we modify it */
newargv = xcalloc(MAX(argc + 1, 1), sizeof(*newargv));
for (n = 0; n < argc; n++)
newargv[n] = xstrdup(argv[n]);
argv = newargv;
__progname = ssh_get_progname(argv[0]);
memset(&args, '\0', sizeof(args));
@ -409,9 +441,9 @@ main(int argc, char **argv)
void
toremote(char *targ, int argc, char **argv)
{
int i, len;
char *bp, *host, *src, *suser, *thost, *tuser, *arg;
arglist alist;
int i;
memset(&alist, '\0', sizeof(alist));
alist.list = NULL;
@ -476,12 +508,10 @@ toremote(char *targ, int argc, char **argv)
errs = 1;
} else { /* local to remote */
if (remin == -1) {
len = strlen(targ) + CMDNEEDS + 20;
bp = xmalloc(len);
(void) snprintf(bp, len, "%s -t %s", cmd, targ);
xasprintf(&bp, "%s -t %s", cmd, targ);
host = cleanhostname(thost);
if (do_cmd(host, tuser, bp, &remin,
&remout, argc) < 0)
&remout) < 0)
exit(1);
if (response() < 0)
exit(1);
@ -490,14 +520,15 @@ toremote(char *targ, int argc, char **argv)
source(1, argv + i);
}
}
xfree(arg);
}
void
tolocal(int argc, char **argv)
{
int i, len;
char *bp, *host, *src, *suser;
arglist alist;
int i;
memset(&alist, '\0', sizeof(alist));
alist.list = NULL;
@ -529,10 +560,8 @@ tolocal(int argc, char **argv)
suser = pwd->pw_name;
}
host = cleanhostname(host);
len = strlen(src) + CMDNEEDS + 20;
bp = xmalloc(len);
(void) snprintf(bp, len, "%s -f %s", cmd, src);
if (do_cmd(host, suser, bp, &remin, &remout, argc) < 0) {
xasprintf(&bp, "%s -f %s", cmd, src);
if (do_cmd(host, suser, bp, &remin, &remout) < 0) {
(void) xfree(bp);
++errs;
continue;
@ -777,7 +806,8 @@ sink(int argc, char **argv)
BUF *bp;
off_t i;
size_t j, count;
int amt, exists, first, mask, mode, ofd, omode;
int amt, exists, first, ofd;
mode_t mode, omode, mask;
off_t size, statbytes;
int setimes, targisdir, wrerrno = 0;
char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];
@ -1097,15 +1127,15 @@ run_err(const char *fmt,...)
va_list ap;
++errs;
if (fp == NULL && !(fp = fdopen(remout, "w")))
return;
(void) fprintf(fp, "%c", 0x01);
(void) fprintf(fp, "scp: ");
va_start(ap, fmt);
(void) vfprintf(fp, fmt, ap);
va_end(ap);
(void) fprintf(fp, "\n");
(void) fflush(fp);
if (fp != NULL || (remout != -1 && (fp = fdopen(remout, "w")))) {
(void) fprintf(fp, "%c", 0x01);
(void) fprintf(fp, "scp: ");
va_start(ap, fmt);
(void) vfprintf(fp, fmt, ap);
va_end(ap);
(void) fprintf(fp, "\n");
(void) fflush(fp);
}
if (!iamremote) {
va_start(ap, fmt);
@ -1181,7 +1211,7 @@ allocbuf(BUF *bp, int fd, int blksize)
if (bp->buf == NULL)
bp->buf = xmalloc(size);
else
bp->buf = xrealloc(bp->buf, size);
bp->buf = xrealloc(bp->buf, 1, size);
memset(bp->buf, 0, size);
bp->cnt = size;
return (bp);

View File

@ -1,3 +1,4 @@
/* $OpenBSD: servconf.c,v 1.165 2006/08/14 12:40:25 dtucker Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@ -10,25 +11,42 @@
*/
#include "includes.h"
RCSID("$OpenBSD: servconf.c,v 1.146 2005/12/08 18:34:11 reyk Exp $");
RCSID("$FreeBSD$");
__RCSID("$FreeBSD$");
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <stdarg.h>
#include "xmalloc.h"
#include "ssh.h"
#include "log.h"
#include "buffer.h"
#include "servconf.h"
#include "xmalloc.h"
#include "compat.h"
#include "pathnames.h"
#include "misc.h"
#include "cipher.h"
#include "key.h"
#include "kex.h"
#include "mac.h"
#include "match.h"
#include "channels.h"
#include "groupaccess.h"
static void add_listen_addr(ServerOptions *, char *, u_short);
static void add_one_listen_addr(ServerOptions *, char *, u_short);
/* Use of privilege separation or not */
extern int use_privsep;
extern Buffer cfg;
/* Initializes the server options to their default values. */
@ -103,9 +121,8 @@ initialize_server_options(ServerOptions *options)
options->authorized_keys_file2 = NULL;
options->num_accept_env = 0;
options->permit_tun = -1;
/* Needs to be accessable in many places */
use_privsep = -1;
options->num_permitted_opens = -1;
options->adm_forced_command = NULL;
}
void
@ -277,112 +294,121 @@ typedef enum {
sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
sMatch, sPermitOpen, sForceCommand,
sUsePrivilegeSeparation,
sVersionAddendum,
sDeprecated, sUnsupported
} ServerOpCodes;
#define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */
#define SSHCFG_MATCH 0x02 /* allowed inside a Match section */
#define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH)
/* Textual representation of the tokens. */
static struct {
const char *name;
ServerOpCodes opcode;
u_int flags;
} keywords[] = {
/* Portable-specific options */
#ifdef USE_PAM
{ "usepam", sUsePAM },
{ "usepam", sUsePAM, SSHCFG_GLOBAL },
#else
{ "usepam", sUnsupported },
{ "usepam", sUnsupported, SSHCFG_GLOBAL },
#endif
{ "pamauthenticationviakbdint", sDeprecated },
{ "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
/* Standard Options */
{ "port", sPort },
{ "hostkey", sHostKeyFile },
{ "hostdsakey", sHostKeyFile }, /* alias */
{ "pidfile", sPidFile },
{ "serverkeybits", sServerKeyBits },
{ "logingracetime", sLoginGraceTime },
{ "keyregenerationinterval", sKeyRegenerationTime },
{ "permitrootlogin", sPermitRootLogin },
{ "syslogfacility", sLogFacility },
{ "loglevel", sLogLevel },
{ "rhostsauthentication", sDeprecated },
{ "rhostsrsaauthentication", sRhostsRSAAuthentication },
{ "hostbasedauthentication", sHostbasedAuthentication },
{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly },
{ "rsaauthentication", sRSAAuthentication },
{ "pubkeyauthentication", sPubkeyAuthentication },
{ "dsaauthentication", sPubkeyAuthentication }, /* alias */
{ "port", sPort, SSHCFG_GLOBAL },
{ "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
{ "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL }, /* alias */
{ "pidfile", sPidFile, SSHCFG_GLOBAL },
{ "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
{ "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
{ "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
{ "permitrootlogin", sPermitRootLogin, SSHCFG_GLOBAL },
{ "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
{ "loglevel", sLogLevel, SSHCFG_GLOBAL },
{ "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
{ "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_GLOBAL },
{ "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_GLOBAL },
{ "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_GLOBAL },
{ "rsaauthentication", sRSAAuthentication, SSHCFG_GLOBAL },
{ "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL },
{ "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
#ifdef KRB5
{ "kerberosauthentication", sKerberosAuthentication },
{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
{ "kerberosticketcleanup", sKerberosTicketCleanup },
{ "kerberosauthentication", sKerberosAuthentication, SSHCFG_GLOBAL },
{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
{ "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
#ifdef USE_AFS
{ "kerberosgetafstoken", sKerberosGetAFSToken },
{ "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
#else
{ "kerberosgetafstoken", sUnsupported },
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
#endif
#else
{ "kerberosauthentication", sUnsupported },
{ "kerberosorlocalpasswd", sUnsupported },
{ "kerberosticketcleanup", sUnsupported },
{ "kerberosgetafstoken", sUnsupported },
{ "kerberosauthentication", sUnsupported, SSHCFG_GLOBAL },
{ "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
{ "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
{ "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
#endif
{ "kerberostgtpassing", sUnsupported },
{ "afstokenpassing", sUnsupported },
{ "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
#ifdef GSSAPI
{ "gssapiauthentication", sGssAuthentication },
{ "gssapicleanupcredentials", sGssCleanupCreds },
{ "gssapiauthentication", sGssAuthentication, SSHCFG_GLOBAL },
{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
#else
{ "gssapiauthentication", sUnsupported },
{ "gssapicleanupcredentials", sUnsupported },
{ "gssapiauthentication", sUnsupported, SSHCFG_GLOBAL },
{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
#endif
{ "passwordauthentication", sPasswordAuthentication },
{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
{ "challengeresponseauthentication", sChallengeResponseAuthentication },
{ "skeyauthentication", sChallengeResponseAuthentication }, /* alias */
{ "checkmail", sDeprecated },
{ "listenaddress", sListenAddress },
{ "addressfamily", sAddressFamily },
{ "printmotd", sPrintMotd },
{ "printlastlog", sPrintLastLog },
{ "ignorerhosts", sIgnoreRhosts },
{ "ignoreuserknownhosts", sIgnoreUserKnownHosts },
{ "x11forwarding", sX11Forwarding },
{ "x11displayoffset", sX11DisplayOffset },
{ "x11uselocalhost", sX11UseLocalhost },
{ "xauthlocation", sXAuthLocation },
{ "strictmodes", sStrictModes },
{ "permitemptypasswords", sEmptyPasswd },
{ "permituserenvironment", sPermitUserEnvironment },
{ "uselogin", sUseLogin },
{ "compression", sCompression },
{ "tcpkeepalive", sTCPKeepAlive },
{ "keepalive", sTCPKeepAlive }, /* obsolete alias */
{ "allowtcpforwarding", sAllowTcpForwarding },
{ "allowusers", sAllowUsers },
{ "denyusers", sDenyUsers },
{ "allowgroups", sAllowGroups },
{ "denygroups", sDenyGroups },
{ "ciphers", sCiphers },
{ "macs", sMacs },
{ "protocol", sProtocol },
{ "gatewayports", sGatewayPorts },
{ "subsystem", sSubsystem },
{ "maxstartups", sMaxStartups },
{ "maxauthtries", sMaxAuthTries },
{ "banner", sBanner },
{ "usedns", sUseDNS },
{ "verifyreversemapping", sDeprecated },
{ "reversemappingcheck", sDeprecated },
{ "clientaliveinterval", sClientAliveInterval },
{ "clientalivecountmax", sClientAliveCountMax },
{ "authorizedkeysfile", sAuthorizedKeysFile },
{ "authorizedkeysfile2", sAuthorizedKeysFile2 },
{ "useprivilegeseparation", sUsePrivilegeSeparation},
{ "acceptenv", sAcceptEnv },
{ "permittunnel", sPermitTunnel },
{ "versionaddendum", sVersionAddendum },
{ NULL, sBadOption }
{ "passwordauthentication", sPasswordAuthentication, SSHCFG_GLOBAL },
{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_GLOBAL },
{ "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
{ "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
{ "checkmail", sDeprecated, SSHCFG_GLOBAL },
{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
{ "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
{ "printmotd", sPrintMotd, SSHCFG_GLOBAL },
{ "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
{ "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
{ "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
{ "x11forwarding", sX11Forwarding, SSHCFG_ALL },
{ "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
{ "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
{ "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
{ "strictmodes", sStrictModes, SSHCFG_GLOBAL },
{ "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL },
{ "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
{ "uselogin", sUseLogin, SSHCFG_GLOBAL },
{ "compression", sCompression, SSHCFG_GLOBAL },
{ "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
{ "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL }, /* obsolete alias */
{ "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
{ "allowusers", sAllowUsers, SSHCFG_GLOBAL },
{ "denyusers", sDenyUsers, SSHCFG_GLOBAL },
{ "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
{ "denygroups", sDenyGroups, SSHCFG_GLOBAL },
{ "ciphers", sCiphers, SSHCFG_GLOBAL },
{ "macs", sMacs, SSHCFG_GLOBAL },
{ "protocol", sProtocol, SSHCFG_GLOBAL },
{ "gatewayports", sGatewayPorts, SSHCFG_ALL },
{ "subsystem", sSubsystem, SSHCFG_GLOBAL },
{ "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
{ "maxauthtries", sMaxAuthTries, SSHCFG_GLOBAL },
{ "banner", sBanner, SSHCFG_GLOBAL },
{ "usedns", sUseDNS, SSHCFG_GLOBAL },
{ "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
{ "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
{ "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
{ "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
{ "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
{ "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
{ "match", sMatch, SSHCFG_ALL },
{ "permitopen", sPermitOpen, SSHCFG_ALL },
{ "forcecommand", sForceCommand, SSHCFG_ALL },
{ "versionaddendum", sVersionAddendum, SSHCFG_GLOBAL },
{ NULL, sBadOption, 0 }
};
/*
@ -391,13 +417,15 @@ static struct {
static ServerOpCodes
parse_token(const char *cp, const char *filename,
int linenum)
int linenum, u_int *flags)
{
u_int i;
for (i = 0; keywords[i].name; i++)
if (strcasecmp(cp, keywords[i].name) == 0)
if (strcasecmp(cp, keywords[i].name) == 0) {
*flags = keywords[i].flags;
return keywords[i].opcode;
}
error("%s: line %d: Bad configuration option: %s",
filename, linenum, cp);
@ -442,18 +470,171 @@ add_one_listen_addr(ServerOptions *options, char *addr, u_short port)
options->listen_addrs = aitop;
}
/*
* The strategy for the Match blocks is that the config file is parsed twice.
*
* The first time is at startup. activep is initialized to 1 and the
* directives in the global context are processed and acted on. Hitting a
* Match directive unsets activep and the directives inside the block are
* checked for syntax only.
*
* The second time is after a connection has been established but before
* authentication. activep is initialized to 2 and global config directives
* are ignored since they have already been processed. If the criteria in a
* Match block is met, activep is set and the subsequent directives
* processed and actioned until EOF or another Match block unsets it. Any
* options set are copied into the main server config.
*
* Potential additions/improvements:
* - Add Match support for pre-kex directives, eg Protocol, Ciphers.
*
* - Add a Tag directive (idea from David Leonard) ala pf, eg:
* Match Address 192.168.0.*
* Tag trusted
* Match Group wheel
* Tag trusted
* Match Tag trusted
* AllowTcpForwarding yes
* GatewayPorts clientspecified
* [...]
*
* - Add a PermittedChannelRequests directive
* Match Group shell
* PermittedChannelRequests session,forwarded-tcpip
*/
static int
match_cfg_line_group(const char *grps, int line, const char *user)
{
int result = 0;
u_int ngrps = 0;
char *arg, *p, *cp, *grplist[MAX_MATCH_GROUPS];
struct passwd *pw;
/*
* Even if we do not have a user yet, we still need to check for
* valid syntax.
*/
arg = cp = xstrdup(grps);
while ((p = strsep(&cp, ",")) != NULL && *p != '\0') {
if (ngrps >= MAX_MATCH_GROUPS) {
error("line %d: too many groups in Match Group", line);
result = -1;
goto out;
}
grplist[ngrps++] = p;
}
if (user == NULL)
goto out;
if ((pw = getpwnam(user)) == NULL) {
debug("Can't match group at line %d because user %.100s does "
"not exist", line, user);
} else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
debug("Can't Match group because user %.100s not in any group "
"at line %d", user, line);
} else if (ga_match(grplist, ngrps) != 1) {
debug("user %.100s does not match group %.100s at line %d",
user, arg, line);
} else {
debug("user %.100s matched group %.100s at line %d", user,
arg, line);
result = 1;
}
out:
ga_free();
xfree(arg);
return result;
}
static int
match_cfg_line(char **condition, int line, const char *user, const char *host,
const char *address)
{
int result = 1;
char *arg, *attrib, *cp = *condition;
size_t len;
if (user == NULL)
debug3("checking syntax for 'Match %s'", cp);
else
debug3("checking match for '%s' user %s host %s addr %s", cp,
user ? user : "(null)", host ? host : "(null)",
address ? address : "(null)");
while ((attrib = strdelim(&cp)) && *attrib != '\0') {
if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
error("Missing Match criteria for %s", attrib);
return -1;
}
len = strlen(arg);
if (strcasecmp(attrib, "user") == 0) {
if (!user) {
result = 0;
continue;
}
if (match_pattern_list(user, arg, len, 0) != 1)
result = 0;
else
debug("user %.100s matched 'User %.100s' at "
"line %d", user, arg, line);
} else if (strcasecmp(attrib, "group") == 0) {
switch (match_cfg_line_group(arg, line, user)) {
case -1:
return -1;
case 0:
result = 0;
}
} else if (strcasecmp(attrib, "host") == 0) {
if (!host) {
result = 0;
continue;
}
if (match_hostname(host, arg, len) != 1)
result = 0;
else
debug("connection from %.100s matched 'Host "
"%.100s' at line %d", host, arg, line);
} else if (strcasecmp(attrib, "address") == 0) {
debug("address '%s' arg '%s'", address, arg);
if (!address) {
result = 0;
continue;
}
if (match_hostname(address, arg, len) != 1)
result = 0;
else
debug("connection from %.100s matched 'Address "
"%.100s' at line %d", address, arg, line);
} else {
error("Unsupported Match attribute %s", attrib);
return -1;
}
}
if (user != NULL)
debug3("match %sfound", result ? "" : "not ");
*condition = cp;
return result;
}
#define WHITESPACE " \t\r\n"
int
process_server_config_line(ServerOptions *options, char *line,
const char *filename, int linenum)
const char *filename, int linenum, int *activep, const char *user,
const char *host, const char *address)
{
char *cp, **charptr, *arg, *p;
int *intptr, value, n;
int cmdline = 0, *intptr, value, n;
ServerOpCodes opcode;
u_short port;
u_int i;
u_int i, flags = 0;
size_t len;
cp = line;
arg = strdelim(&cp);
if ((arg = strdelim(&cp)) == NULL)
return 0;
/* Ignore leading whitespace */
if (*arg == '\0')
arg = strdelim(&cp);
@ -461,7 +642,25 @@ process_server_config_line(ServerOptions *options, char *line,
return 0;
intptr = NULL;
charptr = NULL;
opcode = parse_token(arg, filename, linenum);
opcode = parse_token(arg, filename, linenum, &flags);
if (activep == NULL) { /* We are processing a command line directive */
cmdline = 1;
activep = &cmdline;
}
if (*activep && opcode != sMatch)
debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
if (user == NULL) {
fatal("%s line %d: Directive '%s' is not allowed "
"within a Match block", filename, linenum, arg);
} else { /* this is a directive we have already processed */
while (arg)
arg = strdelim(&cp);
return 0;
}
}
switch (opcode) {
/* Portable-specific options */
case sUsePAM:
@ -499,7 +698,7 @@ process_server_config_line(ServerOptions *options, char *line,
fatal("%s line %d: missing integer value.",
filename, linenum);
value = atoi(arg);
if (*intptr == -1)
if (*activep && *intptr == -1)
*intptr = value;
break;
@ -579,7 +778,7 @@ process_server_config_line(ServerOptions *options, char *line,
if (!arg || *arg == '\0')
fatal("%s line %d: missing file name.",
filename, linenum);
if (*charptr == NULL) {
if (*activep && *charptr == NULL) {
*charptr = tilde_expand_filename(arg, getuid());
/* increase optional counter */
if (intptr != NULL)
@ -630,7 +829,7 @@ process_server_config_line(ServerOptions *options, char *line,
else
fatal("%s line %d: Bad yes/no argument: %s",
filename, linenum, arg);
if (*intptr == -1)
if (*activep && *intptr == -1)
*intptr = value;
break;
@ -825,7 +1024,7 @@ process_server_config_line(ServerOptions *options, char *line,
case sDenyUsers:
while ((arg = strdelim(&cp)) && *arg != '\0') {
if (options->num_deny_users >= MAX_DENY_USERS)
fatal( "%s line %d: too many deny users.",
fatal("%s line %d: too many deny users.",
filename, linenum);
options->deny_users[options->num_deny_users++] =
xstrdup(arg);
@ -895,6 +1094,10 @@ process_server_config_line(ServerOptions *options, char *line,
if (!arg || *arg == '\0')
fatal("%s line %d: Missing subsystem name.",
filename, linenum);
if (!*activep) {
arg = strdelim(&cp);
break;
}
for (i = 0; i < options->num_subsystems; i++)
if (strcmp(arg, options->subsystem_name[i]) == 0)
fatal("%s line %d: Subsystem '%s' already defined.",
@ -905,6 +1108,17 @@ process_server_config_line(ServerOptions *options, char *line,
fatal("%s line %d: Missing subsystem command.",
filename, linenum);
options->subsystem_command[options->num_subsystems] = xstrdup(arg);
/* Collect arguments (separate to executable) */
p = xstrdup(arg);
len = strlen(p) + 1;
while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
len += 1 + strlen(arg);
p = xrealloc(p, 1, len);
strlcat(p, " ", len);
strlcat(p, arg, len);
}
options->subsystem_args[options->num_subsystems] = p;
options->num_subsystems++;
break;
@ -945,7 +1159,7 @@ process_server_config_line(ServerOptions *options, char *line,
*/
case sAuthorizedKeysFile:
case sAuthorizedKeysFile2:
charptr = (opcode == sAuthorizedKeysFile ) ?
charptr = (opcode == sAuthorizedKeysFile) ?
&options->authorized_keys_file :
&options->authorized_keys_file2;
goto parse_filename;
@ -966,6 +1180,8 @@ process_server_config_line(ServerOptions *options, char *line,
if (options->num_accept_env >= MAX_ACCEPT_ENV)
fatal("%s line %d: too many allow env.",
filename, linenum);
if (!*activep)
break;
options->accept_env[options->num_accept_env++] =
xstrdup(arg);
}
@ -993,6 +1209,55 @@ process_server_config_line(ServerOptions *options, char *line,
*intptr = value;
break;
case sMatch:
if (cmdline)
fatal("Match directive not supported as a command-line "
"option");
value = match_cfg_line(&cp, linenum, user, host, address);
if (value < 0)
fatal("%s line %d: Bad Match condition", filename,
linenum);
*activep = value;
break;
case sPermitOpen:
arg = strdelim(&cp);
if (!arg || *arg == '\0')
fatal("%s line %d: missing PermitOpen specification",
filename, linenum);
if (strcmp(arg, "any") == 0) {
if (*activep) {
channel_clear_adm_permitted_opens();
options->num_permitted_opens = 0;
}
break;
}
for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
p = hpdelim(&arg);
if (p == NULL)
fatal("%s line %d: missing host in PermitOpen",
filename, linenum);
p = cleanhostname(p);
if (arg == NULL || (port = a2port(arg)) == 0)
fatal("%s line %d: bad port number in "
"PermitOpen", filename, linenum);
if (*activep && options->num_permitted_opens == -1) {
channel_clear_adm_permitted_opens();
options->num_permitted_opens =
channel_add_adm_permitted_opens(p, port);
}
}
break;
case sForceCommand:
if (cp == NULL)
fatal("%.200s line %d: Missing argument.", filename,
linenum);
len = strspn(cp, WHITESPACE);
if (*activep && options->adm_forced_command == NULL)
options->adm_forced_command = xstrdup(cp + len);
return 0;
case sVersionAddendum:
ssh_version_set_addendum(strtok(cp, "\n"));
do {
@ -1056,18 +1321,52 @@ load_server_config(const char *filename, Buffer *conf)
}
void
parse_server_config(ServerOptions *options, const char *filename, Buffer *conf)
parse_server_match_config(ServerOptions *options, const char *user,
const char *host, const char *address)
{
int linenum, bad_options = 0;
ServerOptions mo;
initialize_server_options(&mo);
parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
copy_set_server_options(options, &mo);
}
/* Copy any (supported) values that are set */
void
copy_set_server_options(ServerOptions *dst, ServerOptions *src)
{
if (src->allow_tcp_forwarding != -1)
dst->allow_tcp_forwarding = src->allow_tcp_forwarding;
if (src->gateway_ports != -1)
dst->gateway_ports = src->gateway_ports;
if (src->adm_forced_command != NULL) {
if (dst->adm_forced_command != NULL)
xfree(dst->adm_forced_command);
dst->adm_forced_command = src->adm_forced_command;
}
if (src->x11_display_offset != -1)
dst->x11_display_offset = src->x11_display_offset;
if (src->x11_forwarding != -1)
dst->x11_forwarding = src->x11_forwarding;
if (src->x11_use_localhost != -1)
dst->x11_use_localhost = src->x11_use_localhost;
}
void
parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
const char *user, const char *host, const char *address)
{
int active, linenum, bad_options = 0;
char *cp, *obuf, *cbuf;
debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
obuf = cbuf = xstrdup(buffer_ptr(conf));
active = user ? 0 : 1;
linenum = 1;
while ((cp = strsep(&cbuf, "\n")) != NULL) {
if (process_server_config_line(options, cp, filename,
linenum++) != 0)
linenum++, &active, user, host, address) != 0)
bad_options++;
}
xfree(obuf);

View File

@ -1,5 +1,5 @@
/* $OpenBSD: servconf.h,v 1.72 2005/12/06 22:38:27 reyk Exp $ */
/* $FreeBSD$ */
/* $OpenBSD: servconf.h,v 1.79 2006/08/14 12:40:25 dtucker Exp $ */
/* $FreeBSD$ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -17,8 +17,6 @@
#ifndef SERVCONF_H
#define SERVCONF_H
#include "buffer.h"
#define MAX_PORTS 256 /* Max # ports. */
#define MAX_ALLOW_USERS 256 /* Max # users on allow list. */
@ -28,6 +26,7 @@
#define MAX_SUBSYSTEMS 256 /* Max # subsystems. */
#define MAX_HOSTKEYS 256 /* Max # hostkeys. */
#define MAX_ACCEPT_ENV 256 /* Max # of env vars. */
#define MAX_MATCH_GROUPS 256 /* Max # of groups for Match. */
/* permit_root_login */
#define PERMIT_NOT_SET -1
@ -112,6 +111,7 @@ typedef struct {
u_int num_subsystems;
char *subsystem_name[MAX_SUBSYSTEMS];
char *subsystem_command[MAX_SUBSYSTEMS];
char *subsystem_args[MAX_SUBSYSTEMS];
u_int num_accept_env;
char *accept_env[MAX_ACCEPT_ENV];
@ -135,15 +135,24 @@ typedef struct {
char *authorized_keys_file; /* File containing public keys */
char *authorized_keys_file2;
char *adm_forced_command;
int use_pam; /* Enable auth via PAM */
int permit_tun;
int num_permitted_opens;
} ServerOptions;
void initialize_server_options(ServerOptions *);
void fill_default_server_options(ServerOptions *);
int process_server_config_line(ServerOptions *, char *, const char *, int);
int process_server_config_line(ServerOptions *, char *, const char *, int,
int *, const char *, const char *, const char *);
void load_server_config(const char *, Buffer *);
void parse_server_config(ServerOptions *, const char *, Buffer *);
void parse_server_config(ServerOptions *, const char *, Buffer *,
const char *, const char *, const char *);
void parse_server_match_config(ServerOptions *, const char *, const char *,
const char *);
void copy_set_server_options(ServerOptions *, ServerOptions *);
#endif /* SERVCONF_H */

View File

@ -1,3 +1,4 @@
/* $OpenBSD: serverloop.c,v 1.144 2006/08/03 03:34:42 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -35,7 +36,25 @@
*/
#include "includes.h"
RCSID("$OpenBSD: serverloop.c,v 1.124 2005/12/13 15:03:02 reyk Exp $");
#include <sys/types.h>
#include <sys/param.h>
#include <sys/wait.h>
#include <sys/socket.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <netinet/in.h>
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <signal.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <stdarg.h>
#include "xmalloc.h"
#include "packet.h"
@ -48,13 +67,16 @@ RCSID("$OpenBSD: serverloop.c,v 1.124 2005/12/13 15:03:02 reyk Exp $");
#include "compat.h"
#include "ssh1.h"
#include "ssh2.h"
#include "key.h"
#include "cipher.h"
#include "kex.h"
#include "hostfile.h"
#include "auth.h"
#include "session.h"
#include "dispatch.h"
#include "auth-options.h"
#include "serverloop.h"
#include "misc.h"
#include "kex.h"
extern ServerOptions options;
@ -142,11 +164,11 @@ notify_done(fd_set *readset)
debug2("notify_done: reading");
}
/*ARGSUSED*/
static void
sigchld_handler(int sig)
{
int save_errno = errno;
debug("Received SIGCHLD.");
child_terminated = 1;
#ifndef _UNICOS
mysignal(SIGCHLD, sigchld_handler);
@ -155,6 +177,7 @@ sigchld_handler(int sig)
errno = save_errno;
}
/*ARGSUSED*/
static void
sigterm_handler(int sig)
{
@ -348,7 +371,7 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
* in buffers and processed later.
*/
static void
process_input(fd_set * readset)
process_input(fd_set *readset)
{
int len;
char buf[16384];
@ -380,10 +403,16 @@ process_input(fd_set * readset)
/* Read and buffer any available stdout data from the program. */
if (!fdout_eof && FD_ISSET(fdout, readset)) {
errno = 0;
len = read(fdout, buf, sizeof(buf));
if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
/* do nothing */
#ifndef PTY_ZEROREAD
} else if (len <= 0) {
#else
} else if ((!isatty(fdout) && len <= 0) ||
(isatty(fdout) && (len < 0 || (len == 0 && errno != 0)))) {
#endif
fdout_eof = 1;
} else {
buffer_append(&stdout_buffer, buf, len);
@ -392,10 +421,16 @@ process_input(fd_set * readset)
}
/* Read and buffer any available stderr data from the program. */
if (!fderr_eof && FD_ISSET(fderr, readset)) {
errno = 0;
len = read(fderr, buf, sizeof(buf));
if (len < 0 && (errno == EINTR || errno == EAGAIN)) {
/* do nothing */
#ifndef PTY_ZEROREAD
} else if (len <= 0) {
#else
} else if ((!isatty(fderr) && len <= 0) ||
(isatty(fderr) && (len < 0 || (len == 0 && errno != 0)))) {
#endif
fderr_eof = 1;
} else {
buffer_append(&stderr_buffer, buf, len);
@ -407,7 +442,7 @@ process_input(fd_set * readset)
* Sends data from internal buffers to client program stdin.
*/
static void
process_output(fd_set * writeset)
process_output(fd_set *writeset)
{
struct termios tio;
u_char *data;
@ -749,6 +784,7 @@ collect_children(void)
sigaddset(&nset, SIGCHLD);
sigprocmask(SIG_BLOCK, &nset, &oset);
if (child_terminated) {
debug("Received SIGCHLD.");
while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
(pid < 0 && errno == EINTR))
if (pid > 0)
@ -873,10 +909,10 @@ server_input_eof(int type, u_int32_t seq, void *ctxt)
static void
server_input_window_size(int type, u_int32_t seq, void *ctxt)
{
int row = packet_get_int();
int col = packet_get_int();
int xpixel = packet_get_int();
int ypixel = packet_get_int();
u_int row = packet_get_int();
u_int col = packet_get_int();
u_int xpixel = packet_get_int();
u_int ypixel = packet_get_int();
debug("Window change received.");
packet_check_eom();
@ -937,7 +973,7 @@ server_request_tun(void)
tun = packet_get_int();
if (forced_tun_device != -1) {
if (tun != SSH_TUNID_ANY && forced_tun_device != tun)
if (tun != SSH_TUNID_ANY && forced_tun_device != tun)
goto done;
tun = forced_tun_device;
}
@ -1085,6 +1121,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
success = channel_cancel_rport_listener(cancel_address,
cancel_port);
xfree(cancel_address);
}
if (want_reply) {
packet_start(success ?
@ -1094,6 +1131,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
}
xfree(rtype);
}
static void
server_input_channel_req(int type, u_int32_t seq, void *ctxt)
{

View File

@ -1,3 +1,4 @@
/* $OpenBSD: session.c,v 1.219 2006/08/29 10:40:19 djm Exp $ */
/*
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
@ -33,13 +34,36 @@
*/
#include "includes.h"
RCSID("$OpenBSD: session.c,v 1.191 2005/12/24 02:27:41 djm Exp $");
RCSID("$FreeBSD$");
__RCSID("$FreeBSD$");
#include <sys/types.h>
#include <sys/param.h>
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <errno.h>
#include <grp.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#include <pwd.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "xmalloc.h"
#include "ssh.h"
#include "ssh1.h"
#include "ssh2.h"
#include "xmalloc.h"
#include "sshpty.h"
#include "packet.h"
#include "buffer.h"
@ -47,7 +71,12 @@ RCSID("$FreeBSD$");
#include "uidswap.h"
#include "compat.h"
#include "channels.h"
#include "bufaux.h"
#include "key.h"
#include "cipher.h"
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
#include "hostfile.h"
#include "auth.h"
#include "auth-options.h"
#include "pathnames.h"
@ -64,10 +93,6 @@ RCSID("$FreeBSD$");
#include <kafs.h>
#endif
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
/* func */
Session *session_new(void);
@ -176,7 +201,7 @@ auth_input_request_forwarding(struct passwd * pw)
sunaddr.sun_family = AF_UNIX;
strlcpy(sunaddr.sun_path, auth_sock_name, sizeof(sunaddr.sun_path));
if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0)
if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0)
packet_disconnect("bind: %.100s", strerror(errno));
/* Restore the privileged uid. */
@ -323,7 +348,11 @@ do_authenticated1(Authctxt *authctxt)
break;
}
debug("Received TCP/IP port forwarding request.");
channel_input_port_forward_request(s->pw->pw_uid == 0, options.gateway_ports);
if (channel_input_port_forward_request(s->pw->pw_uid == 0,
options.gateway_ports) < 0) {
debug("Port forwarding failed.");
break;
}
success = 1;
break;
@ -633,7 +662,7 @@ do_pre_login(Session *s)
fromlen = sizeof(from);
if (packet_connection_is_on_socket()) {
if (getpeername(packet_get_connection_in(),
(struct sockaddr *) & from, &fromlen) < 0) {
(struct sockaddr *)&from, &fromlen) < 0) {
debug("getpeername: %.100s", strerror(errno));
cleanup_exit(255);
}
@ -652,10 +681,14 @@ do_pre_login(Session *s)
void
do_exec(Session *s, const char *command)
{
if (forced_command) {
if (options.adm_forced_command) {
original_command = command;
command = options.adm_forced_command;
debug("Forced command (config) '%.900s'", command);
} else if (forced_command) {
original_command = command;
command = forced_command;
debug("Forced command '%.900s'", command);
debug("Forced command (key option) '%.900s'", command);
}
#ifdef SSH_AUDIT_EVENTS
@ -845,7 +878,7 @@ child_set_env(char ***envp, u_int *envsizep, const char *name,
if (envsize >= 1000)
fatal("child_set_env: too many env vars");
envsize += 50;
env = (*envp) = xrealloc(env, envsize * sizeof(char *));
env = (*envp) = xrealloc(env, envsize, sizeof(char *));
*envsizep = envsize;
}
/* Need to set the NULL pointer at end of array beyond the new slot. */
@ -986,16 +1019,18 @@ do_setup_env(Session *s, const char *shell)
{
char buf[256];
u_int i, envsize;
char **env, *laddr, *path = NULL;
#ifdef HAVE_LOGIN_CAP
char **env, *laddr;
struct passwd *pw = s->pw;
#ifndef HAVE_LOGIN_CAP
char *path = NULL;
#else
extern char **environ;
char **senv, **var;
#endif
struct passwd *pw = s->pw;
/* Initialize the environment. */
envsize = 100;
env = xmalloc(envsize * sizeof(char *));
env = xcalloc(envsize, sizeof(char *));
env[0] = NULL;
#ifdef HAVE_CYGWIN
@ -1371,6 +1406,10 @@ do_setusercontext(struct passwd *pw)
#endif
if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
#ifdef WITH_SELINUX
ssh_selinux_setup_exec_context(pw->pw_name);
#endif
}
static void
@ -1597,7 +1636,7 @@ do_child(Session *s, const char *command)
do_rc_files(s, shell);
/* restore SIGPIPE for child */
signal(SIGPIPE, SIG_DFL);
signal(SIGPIPE, SIG_DFL);
if (options.use_login) {
launch_login(pw, hostname);
@ -1861,7 +1900,7 @@ session_subsystem_req(Session *s)
struct stat st;
u_int len;
int success = 0;
char *cmd, *subsys = packet_get_string(&len);
char *prog, *cmd, *subsys = packet_get_string(&len);
u_int i;
packet_check_eom();
@ -1869,9 +1908,10 @@ session_subsystem_req(Session *s)
for (i = 0; i < options.num_subsystems; i++) {
if (strcmp(subsys, options.subsystem_name[i]) == 0) {
cmd = options.subsystem_command[i];
if (stat(cmd, &st) < 0) {
error("subsystem: cannot stat %s: %s", cmd,
prog = options.subsystem_command[i];
cmd = options.subsystem_args[i];
if (stat(prog, &st) < 0) {
error("subsystem: cannot stat %s: %s", prog,
strerror(errno));
break;
}
@ -1968,8 +2008,8 @@ session_env_req(Session *s)
for (i = 0; i < options.num_accept_env; i++) {
if (match_pattern(name, options.accept_env[i])) {
debug2("Setting env %d: %s=%s", s->num_env, name, val);
s->env = xrealloc(s->env, sizeof(*s->env) *
(s->num_env + 1));
s->env = xrealloc(s->env, s->num_env + 1,
sizeof(*s->env));
s->env[s->num_env].name = name;
s->env[s->num_env].val = val;
s->num_env++;
@ -2214,11 +2254,10 @@ session_exit_message(Session *s, int status)
/* disconnect channel */
debug("session_exit_message: release channel %d", s->chanid);
s->pid = 0;
/*
* Adjust cleanup callback attachment to send close messages when
* the channel gets EOF. The session will be then be closed
* the channel gets EOF. The session will be then be closed
* by session_close_by_channel when the childs close their fds.
*/
channel_register_cleanup(c->self, session_close_by_channel, 1);
@ -2254,12 +2293,13 @@ session_close(Session *s)
if (s->auth_proto)
xfree(s->auth_proto);
s->used = 0;
for (i = 0; i < s->num_env; i++) {
xfree(s->env[i].name);
xfree(s->env[i].val);
}
if (s->env != NULL)
if (s->env != NULL) {
for (i = 0; i < s->num_env; i++) {
xfree(s->env[i].name);
xfree(s->env[i].val);
}
xfree(s->env);
}
session_proctitle(s);
}
@ -2276,6 +2316,7 @@ session_close_by_pid(pid_t pid, int status)
session_exit_message(s, status);
if (s->ttyfd != -1)
session_pty_cleanup(s);
s->pid = 0;
}
/*
@ -2474,7 +2515,7 @@ do_cleanup(Authctxt *authctxt)
return;
called = 1;
if (authctxt == NULL)
if (authctxt == NULL || !authctxt->authenticated)
return;
#ifdef KRB5
if (options.kerberos_ticket_cleanup &&

View File

@ -1,4 +1,4 @@
/* $OpenBSD: session.h,v 1.25 2005/07/17 06:49:04 djm Exp $ */
/* $OpenBSD: session.h,v 1.29 2006/08/03 03:34:42 deraadt Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@ -34,11 +34,13 @@ struct Session {
struct passwd *pw;
Authctxt *authctxt;
pid_t pid;
/* tty */
char *term;
int ptyfd, ttyfd, ptymaster;
u_int row, col, xpixel, ypixel;
char tty[TTYSZ];
/* X11 */
u_int display_number;
char *display;
@ -47,6 +49,7 @@ struct Session {
char *auth_proto;
char *auth_data;
int single_connection;
/* proto 2 */
int chanid;
int *x11_chanids;
@ -55,7 +58,7 @@ struct Session {
struct {
char *name;
char *val;
} *env;
} *env;
};
void do_authenticated(Authctxt *);

View File

@ -1,3 +1,4 @@
/* $OpenBSD: ssh-add.c,v 1.89 2006/08/03 03:34:42 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -35,15 +36,27 @@
*/
#include "includes.h"
RCSID("$OpenBSD: ssh-add.c,v 1.74 2005/11/12 18:37:59 deraadt Exp $");
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <openssl/evp.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "xmalloc.h"
#include "ssh.h"
#include "rsa.h"
#include "log.h"
#include "xmalloc.h"
#include "key.h"
#include "buffer.h"
#include "authfd.h"
#include "authfile.h"
#include "pathnames.h"
@ -124,16 +137,25 @@ delete_all(AuthenticationConnection *ac)
static int
add_file(AuthenticationConnection *ac, const char *filename)
{
struct stat st;
Key *private;
char *comment = NULL;
char msg[1024];
int ret = -1;
int fd, perms_ok, ret = -1;
if (stat(filename, &st) < 0) {
if ((fd = open(filename, O_RDONLY)) < 0) {
perror(filename);
return -1;
}
/*
* Since we'll try to load a keyfile multiple times, permission errors
* will occur multiple times, so check perms first and bail if wrong.
*/
perms_ok = key_perm_ok(fd, filename);
close(fd);
if (!perms_ok)
return -1;
/* At first, try empty passphrase */
private = key_load_private(filename, "", &comment);
if (comment == NULL)
@ -287,7 +309,7 @@ do_file(AuthenticationConnection *ac, int deleting, char *file)
static void
usage(void)
{
fprintf(stderr, "Usage: %s [options]\n", __progname);
fprintf(stderr, "Usage: %s [options] [file ...]\n", __progname);
fprintf(stderr, "Options:\n");
fprintf(stderr, " -l List fingerprints of all identities.\n");
fprintf(stderr, " -L List public key parameters of all identities.\n");
@ -335,13 +357,11 @@ main(int argc, char **argv)
if (list_identities(ac, ch == 'l' ? 1 : 0) == -1)
ret = 1;
goto done;
break;
case 'x':
case 'X':
if (lock_agent(ac, ch == 'x' ? 1 : 0) == -1)
ret = 1;
goto done;
break;
case 'c':
confirm = 1;
break;
@ -352,7 +372,6 @@ main(int argc, char **argv)
if (delete_all(ac) == -1)
ret = 1;
goto done;
break;
case 's':
sc_reader_id = optarg;
break;

View File

@ -1,3 +1,4 @@
/* $OpenBSD: ssh-agent.c,v 1.152 2006/08/04 20:46:05 stevesk Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -34,19 +35,41 @@
*/
#include "includes.h"
__RCSID("$FreeBSD$");
#include <sys/types.h>
#include <sys/param.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/socket.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#ifdef HAVE_SYS_UN_H
# include <sys/un.h>
#endif
#include "openbsd-compat/sys-queue.h"
RCSID("$OpenBSD: ssh-agent.c,v 1.124 2005/10/30 08:52:18 djm Exp $");
RCSID("$FreeBSD$");
#include <openssl/evp.h>
#include <openssl/md5.h>
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_PATHS_H
# include <paths.h>
#endif
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include "xmalloc.h"
#include "ssh.h"
#include "rsa.h"
#include "buffer.h"
#include "bufaux.h"
#include "xmalloc.h"
#include "getput.h"
#include "key.h"
#include "authfd.h"
#include "compat.h"
@ -100,8 +123,8 @@ int max_fd = 0;
pid_t parent_pid = -1;
/* pathname and directory for AUTH_SOCKET */
char socket_name[1024];
char socket_dir[1024];
char socket_name[MAXPATHLEN];
char socket_dir[MAXPATHLEN];
/* locking */
int locked = 0;
@ -306,8 +329,8 @@ process_sign_request2(SocketEntry *e)
Identity *id = lookup_identity(key, 2);
if (id != NULL && (!id->confirm || confirm_key(id) == 0))
ok = key_sign(id->key, &signature, &slen, data, dlen);
key_free(key);
}
key_free(key);
buffer_init(&msg);
if (ok == 0) {
buffer_put_char(&msg, SSH2_AGENT_SIGN_RESPONSE);
@ -682,7 +705,7 @@ process_message(SocketEntry *e)
if (buffer_len(&e->input) < 5)
return; /* Incomplete message. */
cp = buffer_ptr(&e->input);
msg_len = GET_32BIT(cp);
msg_len = get_u32(cp);
if (msg_len > 256 * 1024) {
close_socket(e);
return;
@ -794,10 +817,7 @@ new_socket(sock_type type, int fd)
}
old_alloc = sockets_alloc;
new_alloc = sockets_alloc + 10;
if (sockets)
sockets = xrealloc(sockets, new_alloc * sizeof(sockets[0]));
else
sockets = xmalloc(new_alloc * sizeof(sockets[0]));
sockets = xrealloc(sockets, new_alloc, sizeof(sockets[0]));
for (i = old_alloc; i < new_alloc; i++)
sockets[i].type = AUTH_UNUSED;
sockets_alloc = new_alloc;
@ -878,7 +898,7 @@ after_select(fd_set *readset, fd_set *writeset)
if (FD_ISSET(sockets[i].fd, readset)) {
slen = sizeof(sunaddr);
sock = accept(sockets[i].fd,
(struct sockaddr *) &sunaddr, &slen);
(struct sockaddr *)&sunaddr, &slen);
if (sock < 0) {
error("accept from AUTH_SOCKET: %s",
strerror(errno));
@ -955,6 +975,7 @@ cleanup_exit(int i)
_exit(i);
}
/*ARGSUSED*/
static void
cleanup_handler(int sig)
{
@ -962,6 +983,7 @@ cleanup_handler(int sig)
_exit(2);
}
/*ARGSUSED*/
static void
check_parent_exists(int sig)
{
@ -995,7 +1017,7 @@ int
main(int ac, char **av)
{
int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0;
int sock, fd, ch;
int sock, fd, ch;
u_int nalloc;
char *shell, *format, *pidstr, *agentsocket = NULL;
fd_set *readsetp = NULL, *writesetp = NULL;
@ -1069,20 +1091,24 @@ main(int ac, char **av)
if (ac == 0 && !c_flag && !s_flag) {
shell = getenv("SHELL");
if (shell != NULL && strncmp(shell + strlen(shell) - 3, "csh", 3) == 0)
if (shell != NULL &&
strncmp(shell + strlen(shell) - 3, "csh", 3) == 0)
c_flag = 1;
}
if (k_flag) {
const char *errstr = NULL;
pidstr = getenv(SSH_AGENTPID_ENV_NAME);
if (pidstr == NULL) {
fprintf(stderr, "%s not set, cannot kill agent\n",
SSH_AGENTPID_ENV_NAME);
exit(1);
}
pid = atoi(pidstr);
if (pid < 1) {
fprintf(stderr, "%s=\"%s\", which is not a good PID\n",
SSH_AGENTPID_ENV_NAME, pidstr);
pid = (int)strtonum(pidstr, 2, INT_MAX, &errstr);
if (errstr) {
fprintf(stderr,
"%s=\"%s\", which is not a good PID: %s\n",
SSH_AGENTPID_ENV_NAME, pidstr, errstr);
exit(1);
}
if (kill(pid, SIGTERM) == -1) {
@ -1126,7 +1152,7 @@ main(int ac, char **av)
sunaddr.sun_family = AF_UNIX;
strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path));
prev_mask = umask(0177);
if (bind(sock, (struct sockaddr *) & sunaddr, sizeof(sunaddr)) < 0) {
if (bind(sock, (struct sockaddr *) &sunaddr, sizeof(sunaddr)) < 0) {
perror("bind");
*socket_name = '\0'; /* Don't unlink any existing file */
umask(prev_mask);

View File

@ -1,3 +1,4 @@
/* $OpenBSD: ssh-keyscan.c,v 1.73 2006/08/03 03:34:42 deraadt Exp $ */
/*
* Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
*
@ -7,24 +8,39 @@
*/
#include "includes.h"
RCSID("$OpenBSD: ssh-keyscan.c,v 1.57 2005/10/30 04:01:03 djm Exp $");
#include "openbsd-compat/sys-queue.h"
#include <sys/resource.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <netinet/in.h>
#include <arpa/inet.h>
#include <openssl/bn.h>
#include <netdb.h>
#include <errno.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include "xmalloc.h"
#include "ssh.h"
#include "ssh1.h"
#include "buffer.h"
#include "key.h"
#include "cipher.h"
#include "kex.h"
#include "compat.h"
#include "myproposal.h"
#include "packet.h"
#include "dispatch.h"
#include "buffer.h"
#include "bufaux.h"
#include "log.h"
#include "atomicio.h"
#include "misc.h"
@ -54,7 +70,7 @@ int maxfd;
extern char *__progname;
fd_set *read_wait;
size_t read_wait_size;
size_t read_wait_nfdset;
int ncon;
int nonfatal_fatal = 0;
jmp_buf kexjmp;
@ -128,7 +144,7 @@ Linebuf_alloc(const char *filename, void (*errfun) (const char *,...))
lb->stream = stdin;
}
if (!(lb->buf = malloc(lb->size = LINEBUF_SIZE))) {
if (!(lb->buf = malloc((lb->size = LINEBUF_SIZE)))) {
if (errfun)
(*errfun) ("linebuf (%s): malloc failed\n", lb->filename);
xfree(lb);
@ -350,6 +366,7 @@ keygrab_ssh2(con *c)
c->c_kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
c->c_kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
c->c_kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
c->c_kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
c->c_kex->verify_host_key = hostjump;
if (!(j = setjmp(kexjmp))) {
@ -602,7 +619,6 @@ conread(int s)
keyprint(c, keygrab_ssh1(c));
confree(s);
return;
break;
default:
fatal("conread: invalid status %d", c->c_status);
break;
@ -634,10 +650,10 @@ conloop(void)
} else
seltime.tv_sec = seltime.tv_usec = 0;
r = xmalloc(read_wait_size);
memcpy(r, read_wait, read_wait_size);
e = xmalloc(read_wait_size);
memcpy(e, read_wait, read_wait_size);
r = xcalloc(read_wait_nfdset, sizeof(fd_mask));
e = xcalloc(read_wait_nfdset, sizeof(fd_mask));
memcpy(r, read_wait, read_wait_nfdset * sizeof(fd_mask));
memcpy(e, read_wait, read_wait_nfdset * sizeof(fd_mask));
while (select(maxfd, r, NULL, e, &seltime) == -1 &&
(errno == EAGAIN || errno == EINTR))
@ -804,12 +820,10 @@ main(int argc, char **argv)
fatal("%s: not enough file descriptors", __progname);
if (maxfd > fdlim_get(0))
fdlim_set(maxfd);
fdcon = xmalloc(maxfd * sizeof(con));
memset(fdcon, 0, maxfd * sizeof(con));
fdcon = xcalloc(maxfd, sizeof(con));
read_wait_size = howmany(maxfd, NFDBITS) * sizeof(fd_mask);
read_wait = xmalloc(read_wait_size);
memset(read_wait, 0, read_wait_size);
read_wait_nfdset = howmany(maxfd, NFDBITS);
read_wait = xcalloc(read_wait_nfdset, sizeof(fd_mask));
if (fopt_count) {
Linebuf *lb;

View File

@ -34,7 +34,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: ssh.1,v 1.253 2006/01/30 13:37:49 jmc Exp $
.\" $OpenBSD: ssh.1,v 1.263 2006/07/11 18:50:48 markus Exp $
.\" $FreeBSD$
.Dd September 25, 1999
.Dt SSH 1
@ -79,7 +79,8 @@
.Oc
.Op Fl S Ar ctl_path
.Bk -words
.Op Fl w Ar tunnel : Ns Ar tunnel
.Oo Fl w Ar local_tun Ns
.Op : Ns Ar remote_tun Oc
.Oo Ar user Ns @ Oc Ns Ar hostname
.Op Ar command
.Ek
@ -449,6 +450,7 @@ For full details of the options listed below, and their possible values, see
.It ControlPath
.It DynamicForward
.It EscapeChar
.It ExitOnForwardFailure
.It ForwardAgent
.It ForwardX11
.It ForwardX11Trusted
@ -571,7 +573,7 @@ Disable pseudo-tty allocation.
Force pseudo-tty allocation.
This can be used to execute arbitrary
screen-based programs on a remote machine, which can be very useful,
e.g., when implementing menu services.
e.g. when implementing menu services.
Multiple
.Fl t
options force tty allocation, even if
@ -590,24 +592,35 @@ Multiple
.Fl v
options increase the verbosity.
The maximum is 3.
.It Fl w Ar tunnel : Ns Ar tunnel
Requests a
.It Fl w Xo
.Ar local_tun Ns Op : Ns Ar remote_tun
.Xc
Requests
tunnel
device forwarding with the specified
.Xr tun 4
device on the client
(first
.Ar tunnel
arg)
and server
(second
.Ar tunnel
arg).
devices between the client
.Pq Ar local_tun
and the server
.Pq Ar remote_tun .
.Pp
The devices may be specified by numerical ID or the keyword
.Dq any ,
which uses the next available tunnel device.
If
.Ar remote_tun
is not specified, it defaults to
.Dq any .
See also the
.Cm Tunnel
directive in
and
.Cm TunnelDevice
directives in
.Xr ssh_config 5 .
If the
.Cm Tunnel
directive is unset, it is set to the default tunnel mode, which is
.Dq point-to-point .
.It Fl X
Enables X11 forwarding.
This can also be specified on a per-host basis in a configuration file.
@ -668,6 +681,7 @@ Protocol 1 lacks a strong mechanism for ensuring the
integrity of the connection.
.Pp
The methods available for authentication are:
GSSAPI-based authentication,
host-based authentication,
public key authentication,
challenge-response authentication,
@ -874,7 +888,9 @@ and
options (see above).
It also allows the cancellation of existing remote port-forwardings
using
.Fl KR Ar hostport .
.Sm off
.Fl KR Oo Ar bind_address : Oc Ar port .
.Sm on
.Ic !\& Ns Ar command
allows the user to execute a local command if the
.Ic PermitLocalCommand
@ -1027,8 +1043,7 @@ In this example, we are connecting a client to a server,
The SSHFP resource records should first be added to the zonefile for
host.example.com:
.Bd -literal -offset indent
$ ssh-keygen -f /etc/ssh/ssh_host_rsa_key.pub -r host.example.com.
$ ssh-keygen -f /etc/ssh/ssh_host_dsa_key.pub -r host.example.com.
$ ssh-keygen -r host.example.com.
.Ed
.Pp
The output lines will have to be added to the zonefile.
@ -1077,11 +1092,11 @@ Client access may be more finely tuned via the
file (see below) and the
.Cm PermitRootLogin
server option.
The following entry would permit connections on the first
The following entry would permit connections on
.Xr tun 4
device from user
device 1 from user
.Dq jane
and on the second device from user
and on tun device 2 from user
.Dq john ,
if
.Cm PermitRootLogin
@ -1089,7 +1104,7 @@ is set to
.Dq forced-commands-only :
.Bd -literal -offset 2n
tunnel="1",command="sh /etc/netstart tun1" ssh-rsa ... jane
tunnel="2",command="sh /etc/netstart tun1" ssh-rsa ... john
tunnel="2",command="sh /etc/netstart tun2" ssh-rsa ... john
.Ed
.Pp
Since a SSH-based setup entails a fair amount of overhead,
@ -1180,7 +1195,7 @@ If the current session has no tty,
this variable is not set.
.It Ev TZ
This variable is set to indicate the present time zone if it
was set when the daemon was started (i.e., the daemon passes the value
was set when the daemon was started (i.e. the daemon passes the value
on to new connections).
.It Ev USER
Set to the name of the user logging in.
@ -1341,15 +1356,59 @@ manual page for more information.
.Xr ssh-keysign 8 ,
.Xr sshd 8
.Rs
.%A T. Ylonen
.%A T. Kivinen
.%A M. Saarinen
.%A T. Rinne
.%A S. Lehtinen
.%T "SSH Protocol Architecture"
.%N draft-ietf-secsh-architecture-12.txt
.%D January 2002
.%O work in progress material
.%R RFC 4250
.%T "The Secure Shell (SSH) Protocol Assigned Numbers"
.%D 2006
.Re
.Rs
.%R RFC 4251
.%T "The Secure Shell (SSH) Protocol Architecture"
.%D 2006
.Re
.Rs
.%R RFC 4252
.%T "The Secure Shell (SSH) Authentication Protocol"
.%D 2006
.Re
.Rs
.%R RFC 4253
.%T "The Secure Shell (SSH) Transport Layer Protocol"
.%D 2006
.Re
.Rs
.%R RFC 4254
.%T "The Secure Shell (SSH) Connection Protocol"
.%D 2006
.Re
.Rs
.%R RFC 4255
.%T "Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints"
.%D 2006
.Re
.Rs
.%R RFC 4256
.%T "Generic Message Exchange Authentication for the Secure Shell Protocol (SSH)"
.%D 2006
.Re
.Rs
.%R RFC 4335
.%T "The Secure Shell (SSH) Session Channel Break Extension"
.%D 2006
.Re
.Rs
.%R RFC 4344
.%T "The Secure Shell (SSH) Transport Layer Encryption Modes"
.%D 2006
.Re
.Rs
.%R RFC 4345
.%T "Improved Arcfour Modes for the Secure Shell (SSH) Transport Layer Protocol"
.%D 2006
.Re
.Rs
.%R RFC 4419
.%T "Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol"
.%D 2006
.Re
.Sh AUTHORS
OpenSSH is a derivative of the original and free

View File

@ -1,3 +1,4 @@
/* $OpenBSD: ssh.c,v 1.293 2006/08/03 03:34:42 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -40,21 +41,47 @@
*/
#include "includes.h"
RCSID("$OpenBSD: ssh.c,v 1.257 2005/12/20 04:41:07 dtucker Exp $");
RCSID("$FreeBSD$");
__RCSID("$FreeBSD$");
#include <sys/types.h>
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#include <sys/resource.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#include <pwd.h>
#include <signal.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include "xmalloc.h"
#include "ssh.h"
#include "ssh1.h"
#include "ssh2.h"
#include "compat.h"
#include "cipher.h"
#include "xmalloc.h"
#include "packet.h"
#include "buffer.h"
#include "bufaux.h"
#include "channels.h"
#include "key.h"
#include "authfd.h"
@ -73,6 +100,7 @@ RCSID("$FreeBSD$");
#include "msg.h"
#include "monitor_fdpass.h"
#include "uidswap.h"
#include "version.h"
#ifdef SMARTCARD
#include "scard.h"
@ -163,7 +191,7 @@ usage(void)
" [-i identity_file] [-L [bind_address:]port:host:hostport]\n"
" [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n"
" [-R [bind_address:]port:host:hostport] [-S ctl_path]\n"
" [-w tunnel:tunnel] [user@]hostname [command]\n"
" [-w local_tun[:remote_tun]] [user@]hostname [command]\n"
);
exit(255);
}
@ -243,7 +271,7 @@ main(int ac, char **av)
/* Parse command-line arguments. */
host = NULL;
again:
again:
while ((opt = getopt(ac, av,
"1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:MNO:PR:S:TVw:XY")) != -1) {
switch (opt) {
@ -634,7 +662,7 @@ main(int ac, char **av)
if (options.host_key_alias != NULL) {
for (p = options.host_key_alias; *p; p++)
if (isupper(*p))
*p = tolower(*p);
*p = (char)tolower(*p);
}
/* Get default port if port has not been set. */
@ -651,11 +679,15 @@ main(int ac, char **av)
options.control_path = NULL;
if (options.control_path != NULL) {
char thishost[NI_MAXHOST];
if (gethostname(thishost, sizeof(thishost)) == -1)
fatal("gethostname: %s", strerror(errno));
snprintf(buf, sizeof(buf), "%d", options.port);
cp = tilde_expand_filename(options.control_path,
original_real_uid);
options.control_path = percent_expand(cp, "p", buf, "h", host,
"r", options.user, (char *)NULL);
"r", options.user, "l", thishost, (char *)NULL);
xfree(cp);
}
if (mux_command != 0 && options.control_path == NULL)
@ -688,16 +720,16 @@ main(int ac, char **av)
if (options.rhosts_rsa_authentication ||
options.hostbased_authentication) {
sensitive_data.nkeys = 3;
sensitive_data.keys = xmalloc(sensitive_data.nkeys *
sensitive_data.keys = xcalloc(sensitive_data.nkeys,
sizeof(Key));
PRIV_START;
sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
_PATH_HOST_KEY_FILE, "", NULL);
_PATH_HOST_KEY_FILE, "", NULL, NULL);
sensitive_data.keys[1] = key_load_private_type(KEY_DSA,
_PATH_HOST_DSA_KEY_FILE, "", NULL);
_PATH_HOST_DSA_KEY_FILE, "", NULL, NULL);
sensitive_data.keys[2] = key_load_private_type(KEY_RSA,
_PATH_HOST_RSA_KEY_FILE, "", NULL);
_PATH_HOST_RSA_KEY_FILE, "", NULL, NULL);
PRIV_END;
if (options.hostbased_authentication == 1 &&
@ -813,6 +845,8 @@ ssh_init_forwarding(void)
options.local_forwards[i].connect_port,
options.gateway_ports);
}
if (i > 0 && success != i && options.exit_on_forward_failure)
fatal("Could not request local forwarding.");
if (i > 0 && success == 0)
error("Could not request local forwarding.");
@ -825,11 +859,17 @@ ssh_init_forwarding(void)
options.remote_forwards[i].listen_port,
options.remote_forwards[i].connect_host,
options.remote_forwards[i].connect_port);
channel_request_remote_forwarding(
if (channel_request_remote_forwarding(
options.remote_forwards[i].listen_host,
options.remote_forwards[i].listen_port,
options.remote_forwards[i].connect_host,
options.remote_forwards[i].connect_port);
options.remote_forwards[i].connect_port) < 0) {
if (options.exit_on_forward_failure)
fatal("Could not request remote forwarding.");
else
logit("Warning: Could not request remote "
"forwarding.");
}
}
}
@ -890,10 +930,10 @@ ssh_session(void)
/* Store window size in the packet. */
if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) < 0)
memset(&ws, 0, sizeof(ws));
packet_put_int(ws.ws_row);
packet_put_int(ws.ws_col);
packet_put_int(ws.ws_xpixel);
packet_put_int(ws.ws_ypixel);
packet_put_int((u_int)ws.ws_row);
packet_put_int((u_int)ws.ws_col);
packet_put_int((u_int)ws.ws_xpixel);
packet_put_int((u_int)ws.ws_ypixel);
/* Store tty modes in the packet. */
tty_make_modes(fileno(stdin), NULL);
@ -1011,9 +1051,16 @@ client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt)
options.remote_forwards[i].listen_port,
options.remote_forwards[i].connect_host,
options.remote_forwards[i].connect_port);
if (type == SSH2_MSG_REQUEST_FAILURE)
logit("Warning: remote port forwarding failed for listen "
"port %d", options.remote_forwards[i].listen_port);
if (type == SSH2_MSG_REQUEST_FAILURE) {
if (options.exit_on_forward_failure)
fatal("Error: remote port forwarding failed for "
"listen port %d",
options.remote_forwards[i].listen_port);
else
logit("Warning: remote port forwarding failed for "
"listen port %d",
options.remote_forwards[i].listen_port);
}
}
static void
@ -1042,7 +1089,7 @@ ssh_control_listener(void)
fatal("%s socket(): %s", __func__, strerror(errno));
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;
if (errno == EINVAL || errno == EADDRINUSE)
fatal("ControlSocket %s already exists",
@ -1194,15 +1241,16 @@ ssh_session2(void)
static void
load_public_identity_files(void)
{
char *filename;
char *filename, *cp, thishost[NI_MAXHOST];
int i = 0;
Key *public;
struct passwd *pw;
#ifdef SMARTCARD
Key **keys;
if (options.smartcard_device != NULL &&
options.num_identity_files < SSH_MAX_IDENTITY_FILES &&
(keys = sc_get_keys(options.smartcard_device, NULL)) != NULL ) {
(keys = sc_get_keys(options.smartcard_device, NULL)) != NULL) {
int count = 0;
for (i = 0; keys[i] != NULL; i++) {
count++;
@ -1220,9 +1268,18 @@ load_public_identity_files(void)
xfree(keys);
}
#endif /* SMARTCARD */
if ((pw = getpwuid(original_real_uid)) == NULL)
fatal("load_public_identity_files: getpwuid failed");
if (gethostname(thishost, sizeof(thishost)) == -1)
fatal("load_public_identity_files: gethostname: %s",
strerror(errno));
for (; i < options.num_identity_files; i++) {
filename = tilde_expand_filename(options.identity_files[i],
cp = tilde_expand_filename(options.identity_files[i],
original_real_uid);
filename = percent_expand(cp, "d", pw->pw_dir,
"u", pw->pw_name, "l", thishost, "h", host,
"r", options.user, (char *)NULL);
xfree(cp);
public = key_load_public(filename, NULL);
debug("identity file %s type %d", filename,
public ? public->type : -1);
@ -1248,14 +1305,14 @@ control_client_sigrelay(int signo)
static int
env_permitted(char *env)
{
int i;
int i, ret;
char name[1024], *cp;
strlcpy(name, env, sizeof(name));
if ((cp = strchr(name, '=')) == NULL)
if ((cp = strchr(env, '=')) == NULL || cp == env)
return (0);
*cp = '\0';
ret = snprintf(name, sizeof(name), "%.*s", (int)(cp - env), env);
if (ret <= 0 || (size_t)ret >= sizeof(name))
fatal("env_permitted: name '%.100s...' too long", env);
for (i = 0; i < options.num_send_env; i++)
if (match_pattern(name, options.send_env[i]))
@ -1300,29 +1357,29 @@ control_client(const char *path)
if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
fatal("%s socket(): %s", __func__, strerror(errno));
if (connect(sock, (struct sockaddr*)&addr, addr_len) == -1) {
if (connect(sock, (struct sockaddr *)&addr, addr_len) == -1) {
if (mux_command != SSHMUX_COMMAND_OPEN) {
fatal("Control socket connect(%.100s): %s", path,
strerror(errno));
}
if (errno == ENOENT)
debug("Control socket \"%.100s\" does not exist", path);
debug("Control socket \"%.100s\" does not exist", path);
else {
error("Control socket connect(%.100s): %s", path,
error("Control socket connect(%.100s): %s", path,
strerror(errno));
}
close(sock);
return;
}
close(sock);
return;
}
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);
}
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);
}
term = getenv("TERM");

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh.h,v 1.76 2004/12/06 11:41:03 dtucker Exp $ */
/* $OpenBSD: ssh.h,v 1.78 2006/08/03 03:34:42 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -12,18 +12,6 @@
* called by a name other than "ssh" or "Secure Shell".
*/
#ifndef SSH_H
#define SSH_H
#include <netinet/in.h> /* For struct sockaddr_in */
#include <pwd.h> /* For struct pw */
#include <stdarg.h> /* For va_list */
#include <syslog.h> /* For LOG_AUTH and friends */
#include <sys/socket.h> /* For struct sockaddr_storage */
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
/* Cipher used for encrypting authentication files. */
#define SSH_AUTHFILE_CIPHER SSH_CIPHER_3DES
@ -112,5 +100,3 @@
/* Listen backlog for sshd, ssh-agent and forwarding sockets */
#define SSH_LISTEN_BACKLOG 128
#endif /* SSH_H */

View File

@ -1,4 +1,4 @@
# $OpenBSD: ssh_config,v 1.21 2005/12/06 22:38:27 reyk Exp $
# $OpenBSD: ssh_config,v 1.22 2006/05/29 12:56:33 dtucker Exp $
# $FreeBSD$
# This is the ssh client system-wide configuration file. See
@ -25,6 +25,8 @@
# RSAAuthentication yes
# PasswordAuthentication yes
# HostbasedAuthentication no
# GSSAPIAuthentication no
# GSSAPIDelegateCredentials no
# BatchMode no
# CheckHostIP no
# AddressFamily any

View File

@ -34,7 +34,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: ssh_config.5,v 1.76 2006/01/20 11:21:45 jmc Exp $
.\" $OpenBSD: ssh_config.5,v 1.97 2006/07/27 08:00:50 jmc Exp $
.\" $FreeBSD$
.Dd September 25, 1999
.Dt SSH_CONFIG 5
@ -48,9 +48,10 @@
.It Pa /etc/ssh/ssh_config
.El
.Sh DESCRIPTION
.Nm ssh
.Xr ssh 1
obtains configuration data from the following sources in
the following order:
.Pp
.Bl -enum -offset indent -compact
.It
command-line options
@ -79,7 +80,6 @@ The configuration file has the following format:
Empty lines and lines starting with
.Ql #
are comments.
.Pp
Otherwise a line is of the format
.Dq keyword arguments .
Configuration options may be separated by whitespace or
@ -88,11 +88,14 @@ optional whitespace and exactly one
the latter format is useful to avoid the need to quote whitespace
when specifying configuration options using the
.Nm ssh ,
.Nm scp
.Nm scp ,
and
.Nm sftp
.Fl o
option.
Arguments may optionally be enclosed in double quotes
.Pq \&"
in order to represent arguments containing spaces.
.Pp
The possible
keywords and their meanings are as follows (note that
@ -103,25 +106,24 @@ Restricts the following declarations (up to the next
.Cm Host
keyword) to be only for those hosts that match one of the patterns
given after the keyword.
.Ql \&*
and
.Ql \&?
can be used as wildcards in the
patterns.
A single
.Ql \&*
.Ql *
as a pattern can be used to provide global
defaults for all hosts.
The host is the
.Ar hostname
argument given on the command line (i.e., the name is not converted to
argument given on the command line (i.e. the name is not converted to
a canonicalized host name before matching).
.Pp
See
.Sx PATTERNS
for more information on patterns.
.It Cm AddressFamily
Specifies which address family to use when connecting.
Valid arguments are
.Dq any ,
.Dq inet
(use IPv4 only) or
(use IPv4 only), or
.Dq inet6
(use IPv6 only).
.It Cm BatchMode
@ -145,7 +147,7 @@ Note that this option does not work if
is set to
.Dq yes .
.It Cm ChallengeResponseAuthentication
Specifies whether to use challenge response authentication.
Specifies whether to use challenge-response authentication.
The argument to this keyword must be
.Dq yes
or
@ -155,7 +157,8 @@ The default is
.It Cm CheckHostIP
If this flag is set to
.Dq yes ,
ssh will additionally check the host IP address in the
.Xr ssh 1
will additionally check the host IP address in the
.Pa known_hosts
file.
This allows ssh to detect if a host key changed due to DNS spoofing.
@ -175,7 +178,7 @@ and
are supported.
.Ar des
is only supported in the
.Nm ssh
.Xr ssh 1
client for interoperability with legacy protocol 1 implementations
that do not support the
.Ar 3des
@ -201,18 +204,18 @@ The supported ciphers are
.Dq blowfish-cbc ,
and
.Dq cast128-cbc .
The default is
.Bd -literal
``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128,
arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr,
aes192-ctr,aes256-ctr''
The default is:
.Bd -literal -offset 3n
aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128,
arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr,
aes192-ctr,aes256-ctr
.Ed
.It Cm ClearAllForwardings
Specifies that all local, remote and dynamic port forwardings
Specifies that all local, remote, and dynamic port forwardings
specified in the configuration files or on the command line be
cleared.
This option is primarily useful when used from the
.Nm ssh
.Xr ssh 1
command line to clear port forwardings set in
configuration files, and is automatically set by
.Xr scp 1
@ -245,15 +248,15 @@ The argument must be an integer.
This may be useful in scripts if the connection sometimes fails.
The default is 1.
.It Cm ConnectTimeout
Specifies the timeout (in seconds) used when connecting to the ssh
server, instead of using the default system TCP timeout.
Specifies the timeout (in seconds) used when connecting to the
SSH server, instead of using the default system TCP timeout.
This value is used only when the target is down or really unreachable,
not when it refuses the connection.
.It Cm ControlMaster
Enables the sharing of multiple sessions over a single network connection.
When set to
.Dq yes
.Nm ssh
.Dq yes ,
.Xr ssh 1
will listen for connections on a control socket specified using the
.Cm ControlPath
argument.
@ -270,8 +273,7 @@ if the control socket does not exist, or is not listening.
.Pp
Setting this to
.Dq ask
will cause
.Nm ssh
will cause ssh
to listen for control connections, but require confirmation using the
.Ev SSH_ASKPASS
program before they are accepted (see
@ -279,9 +281,8 @@ program before they are accepted (see
for details).
If the
.Cm ControlPath
can not be opened,
.Nm ssh
will continue without connecting to a master instance.
cannot be opened,
ssh will continue without connecting to a master instance.
.Pp
X11 and
.Xr ssh-agent 1
@ -307,16 +308,18 @@ section above or the string
.Dq none
to disable connection sharing.
In the path,
.Ql %l
will be substituted by the local host name,
.Ql %h
will be substituted by the target host name,
.Ql %p
the port and
the port, and
.Ql %r
by the remote login username.
It is recommended that any
.Cm ControlPath
used for opportunistic connection sharing include
all three of these escape sequences.
at least %h, %p, and %r.
This ensures that shared connections are uniquely identified.
.It Cm DynamicForward
Specifies that a TCP port on the local machine be forwarded
@ -347,7 +350,7 @@ empty address or
indicates that the port should be available from all interfaces.
.Pp
Currently the SOCKS4 and SOCKS5 protocols are supported, and
.Nm ssh
.Xr ssh 1
will act as a SOCKS server.
Multiple forwardings may be specified, and
additional forwardings can be given on the command line.
@ -383,6 +386,17 @@ followed by a letter, or
to disable the escape
character entirely (making the connection transparent for binary
data).
.It Cm ExitOnForwardFailure
Specifies whether
.Xr ssh 1
should terminate the connection if it cannot set up all requested
dynamic, local, and remote port forwardings.
The argument must be
.Dq yes
or
.Dq no .
The default is
.Dq no .
.It Cm ForwardAgent
Specifies whether the connection to the authentication agent (if any)
will be forwarded to the remote machine.
@ -422,12 +436,12 @@ if the
option is also enabled.
.It Cm ForwardX11Trusted
If this option is set to
.Dq yes
then remote X11 clients will have full access to the original X11 display.
.Dq yes ,
remote X11 clients will have full access to the original X11 display.
.Pp
If this option is set to
.Dq no
then remote X11 clients will be considered untrusted and prevented
.Dq no ,
remote X11 clients will be considered untrusted and prevented
from stealing or tampering with data belonging to trusted X11
clients.
Furthermore, the
@ -444,12 +458,11 @@ the restrictions imposed on untrusted clients.
Specifies whether remote hosts are allowed to connect to local
forwarded ports.
By default,
.Nm ssh
.Xr ssh 1
binds local port forwardings to the loopback address.
This prevents other remote hosts from connecting to forwarded ports.
.Cm GatewayPorts
can be used to specify that
.Nm ssh
can be used to specify that ssh
should bind local port forwardings to the wildcard address,
thus allowing remote hosts to connect to forwarded ports.
The argument must be
@ -474,19 +487,20 @@ The default is
Note that this option applies to protocol version 2 only.
.It Cm HashKnownHosts
Indicates that
.Nm ssh
.Xr ssh 1
should hash host names and addresses when they are added to
.Pa ~/.ssh/known_hosts .
These hashed names may be used normally by
.Nm ssh
.Xr ssh 1
and
.Nm sshd ,
.Xr sshd 8 ,
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
Note that existing names and addresses in known hosts files
will not be converted automatically,
but may be manually hashed using
.Xr ssh-keygen 1 .
.It Cm HostbasedAuthentication
Specifies whether to try rhosts based authentication with public key
@ -509,30 +523,29 @@ The default for this option is:
Specifies an alias that should be used instead of the
real host name when looking up or saving the host key
in the host key database files.
This option is useful for tunneling ssh connections
This option is useful for tunneling SSH connections
or for multiple servers running on a single host.
.It Cm HostName
Specifies the real host name to log into.
This can be used to specify nicknames or abbreviations for hosts.
Default is the name given on the command line.
The default is the name given on the command line.
Numeric IP addresses are also permitted (both on the command line and in
.Cm HostName
specifications).
.It Cm IdentitiesOnly
Specifies that
.Nm ssh
.Xr ssh 1
should only use the authentication identity files configured in the
.Nm
files,
even if the
.Nm ssh-agent
even if
.Xr ssh-agent 1
offers more identities.
The argument to this keyword must be
.Dq yes
or
.Dq no .
This option is intended for situations where
.Nm ssh-agent
This option is intended for situations where ssh-agent
offers many different identities.
The default is
.Dq no .
@ -548,8 +561,21 @@ and
for protocol version 2.
Additionally, any identities represented by the authentication agent
will be used for authentication.
.Pp
The file name may use the tilde
syntax to refer to a user's home directory.
syntax to refer to a user's home directory or one of the following
escape characters:
.Ql %d
(local user's home directory),
.Ql %u
(local user name),
.Ql %l
(local host name),
.Ql %h
(remote host name) or
.Ql %r
(remote user name).
.Pp
It is possible to have
multiple identity files specified in configuration files; all these
identities will be tried in sequence.
@ -557,6 +583,13 @@ identities will be tried in sequence.
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.
The methods available vary depending on what the server supports.
For an OpenSSH server,
it may be zero or more of:
.Dq bsdauth ,
.Dq pam ,
and
.Dq skey .
.It Cm LocalCommand
Specifies a command to execute on the local machine after successfully
connecting to the server.
@ -598,9 +631,9 @@ empty address or
indicates that the port should be available from all interfaces.
.It Cm LogLevel
Gives the verbosity level that is used when logging messages from
.Nm ssh .
.Xr ssh 1 .
The possible values are:
QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2 and DEBUG3.
QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2, and DEBUG3.
The default is INFO.
DEBUG and DEBUG1 are equivalent.
DEBUG2 and DEBUG3 each specify higher levels of verbose output.
@ -610,7 +643,7 @@ in order of preference.
The MAC algorithm is used in protocol version 2
for data integrity protection.
Multiple algorithms must be comma-separated.
The default is
The default is:
.Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 .
.It Cm NoHostAuthenticationForLocalhost
This option can be used if the home directory is shared across machines.
@ -625,7 +658,7 @@ The default is to check the host key for localhost.
.It Cm NumberOfPasswordPrompts
Specifies the number of password prompts before giving up.
The argument to this keyword must be an integer.
Default is 3.
The default is 3.
.It Cm PasswordAuthentication
Specifies whether to use password authentication.
The argument to this keyword must be
@ -649,7 +682,7 @@ The default is
.Dq no .
.It Cm Port
Specifies the port number to connect on the remote host.
Default is 22.
The default is 22.
.It Cm PreferredAuthentications
Specifies the order in which the client should try protocol 2
authentication methods.
@ -658,20 +691,24 @@ This allows a client to prefer one method (e.g.\&
over another method (e.g.\&
.Cm password )
The default for this option is:
.Dq hostbased,publickey,keyboard-interactive,password .
.Do gssapi-with-mic ,
hostbased,
publickey,
keyboard-interactive,
password
.Dc .
.It Cm Protocol
Specifies the protocol versions
.Nm ssh
.Xr ssh 1
should support in order of preference.
The possible values are
.Dq 1
.Sq 1
and
.Dq 2 .
.Sq 2 .
Multiple versions must be comma-separated.
The default is
.Dq 2,1 .
This means that
.Nm ssh
This means that ssh
tries version 2 and falls back to version 1
if version 2 is not available.
.It Cm ProxyCommand
@ -729,9 +766,9 @@ or
.Sq G
to indicate Kilobytes, Megabytes, or Gigabytes, respectively.
The default is between
.Dq 1G
.Sq 1G
and
.Dq 4G ,
.Sq 4G ,
depending on the cipher.
This option applies to protocol version 2 only.
.It Cm RemoteForward
@ -777,7 +814,7 @@ or
The default is
.Dq no .
This option applies to protocol version 1 only and requires
.Nm ssh
.Xr ssh 1
to be setuid root.
.It Cm RSAAuthentication
Specifies whether to try RSA authentication.
@ -795,31 +832,31 @@ Note that this option applies to protocol version 1 only.
Specifies what variables from the local
.Xr environ 7
should be sent to the server.
Note that environment passing is only supported for protocol 2, the
server must also support it, and the server must be configured to
Note that environment passing is only supported for protocol 2.
The server must also support it, and the server must be configured to
accept these environment variables.
Refer to
.Cm AcceptEnv
in
.Xr sshd_config 5
for how to configure the server.
Variables are specified by name, which may contain the wildcard characters
.Ql \&*
and
.Ql \&? .
Variables are specified by name, which may contain wildcard characters.
Multiple environment variables may be separated by whitespace or spread
across multiple
.Cm SendEnv
directives.
The default is not to send any environment variables.
.Pp
See
.Sx PATTERNS
for more information on patterns.
.It Cm ServerAliveCountMax
Sets the number of server alive messages (see below) which may be
sent without
.Nm ssh
.Xr ssh 1
receiving any messages back from the server.
If this threshold is reached while server alive messages are being sent,
.Nm ssh
will disconnect from the server, terminating the session.
ssh will disconnect from the server, terminating the session.
It is important to note that the use of server alive messages is very
different from
.Cm TCPKeepAlive
@ -835,14 +872,15 @@ server depend on knowing when a connection has become inactive.
The default value is 3.
If, for example,
.Cm ServerAliveInterval
(see below) is set to 15, and
(see below) is set to 15 and
.Cm ServerAliveCountMax
is left at the default, if the server becomes unresponsive ssh
will disconnect after approximately 45 seconds.
is left at the default, if the server becomes unresponsive,
ssh will disconnect after approximately 45 seconds.
This option applies to protocol version 2 only.
.It Cm ServerAliveInterval
Sets a timeout interval in seconds after which if no data has been received
from the server,
.Nm ssh
.Xr ssh 1
will send a message through the encrypted
channel to request a response from the server.
The default
@ -851,41 +889,39 @@ This option applies to protocol version 2 only.
.It Cm SmartcardDevice
Specifies which smartcard device to use.
The argument to this keyword is the device
.Nm ssh
.Xr ssh 1
should use to communicate with a smartcard used for storing the user's
private RSA key.
By default, no device is specified and smartcard support is not activated.
.It Cm StrictHostKeyChecking
If this flag is set to
.Dq yes ,
.Nm ssh
.Xr ssh 1
will never automatically add host keys to the
.Pa ~/.ssh/known_hosts
file, and refuses to connect to hosts whose host key has changed.
This provides maximum protection against trojan horse attacks,
however, can be annoying when the
though it can be annoying when the
.Pa /etc/ssh/ssh_known_hosts
file is poorly maintained, or connections to new hosts are
file is poorly maintained or when connections to new hosts are
frequently made.
This option forces the user to manually
add all new hosts.
If this flag is set to
.Dq no ,
.Nm ssh
will automatically add new host keys to the
ssh will automatically add new host keys to the
user known hosts files.
If this flag is set to
.Dq ask ,
new host keys
will be added to the user known host files only after the user
has confirmed that is what they really want to do, and
.Nm ssh
will refuse to connect to hosts whose host key has changed.
ssh will refuse to connect to hosts whose host key has changed.
The host keys of
known hosts will be verified automatically in all cases.
The argument must be
.Dq yes ,
.Dq no
.Dq no ,
or
.Dq ask .
The default is
@ -908,24 +944,44 @@ This is important in scripts, and many users want it too.
To disable TCP keepalive messages, the value should be set to
.Dq no .
.It Cm Tunnel
Request starting
Request
.Xr tun 4
device forwarding between the client and the server.
This option also allows requesting layer 2 (ethernet)
instead of layer 3 (point-to-point) tunneling from the server.
The argument must be
.Dq yes ,
.Dq point-to-point ,
.Dq point-to-point
(layer 3),
.Dq ethernet
(layer 2),
or
.Dq no .
Specifying
.Dq yes
requests the default tunnel mode, which is
.Dq point-to-point .
The default is
.Dq no .
.It Cm TunnelDevice
Force a specified
Specifies the
.Xr tun 4
device on the client.
Without this option, the next available device will be used.
devices to open on the client
.Pq Ar local_tun
and the server
.Pq Ar remote_tun .
.Pp
The argument must be
.Sm off
.Ar local_tun Op : Ar remote_tun .
.Sm on
The devices may be specified by numerical ID or the keyword
.Dq any ,
which uses the next available tunnel device.
If
.Ar remote_tun
is not specified, it defaults to
.Dq any .
The default is
.Dq any:any .
.It Cm UsePrivilegedPort
Specifies whether to use a privileged port for outgoing connections.
The argument must be
@ -935,8 +991,8 @@ or
The default is
.Dq no .
If set to
.Dq yes
.Nm ssh
.Dq yes ,
.Xr ssh 1
must be setuid root.
Note that this option must be set to
.Dq yes
@ -969,12 +1025,17 @@ need to confirm new host keys according to the
option.
The argument must be
.Dq yes ,
.Dq no
.Dq no ,
or
.Dq ask .
The default is
.Dq no .
Note that this option applies to protocol version 2 only.
.Pp
See also
.Sx VERIFYING HOST KEYS
in
.Xr ssh 1 .
.It Cm VersionAddendum
Specifies a string to append to the regular version string to identify
OS- or site-specific modifications.
@ -987,14 +1048,47 @@ program.
The default is
.Pa /usr/X11R6/bin/xauth .
.El
.Sh PATTERNS
A
.Em pattern
consists of zero or more non-whitespace characters,
.Sq *
(a wildcard that matches zero or more characters),
or
.Sq ?\&
(a wildcard that matches exactly one character).
For example, to specify a set of declarations for any host in the
.Dq .co.uk
set of domains,
the following pattern could be used:
.Pp
.Dl Host *.co.uk
.Pp
The following pattern
would match any host in the 192.168.0.[0-9] network range:
.Pp
.Dl Host 192.168.0.?
.Pp
A
.Em pattern-list
is a comma-separated list of patterns.
Patterns within pattern-lists may be negated
by preceding them with an exclamation mark
.Pq Sq !\& .
For example,
to allow a key to be used from anywhere within an organisation
except from the
.Dq dialup
pool,
the following entry (in authorized_keys) could be used:
.Pp
.Dl from=\&"!*.dialup.example.com,*.example.com\&"
.Sh FILES
.Bl -tag -width Ds
.It Pa ~/.ssh/config
This is the per-user configuration file.
The format of this file is described above.
This file is used by the
.Nm ssh
client.
This file is used by the SSH client.
Because of the potential for abuse, this file must have strict permissions:
read/write for the user, and not accessible by others.
.It Pa /etc/ssh/ssh_config

View File

@ -7,7 +7,7 @@
*
* A list of symbols which need munging is obtained as follows:
*
* nm libssh.a | awk '$2 == "T" && $3 !~ /^ssh_/ { print $3 }'
* nm libssh.a | awk '$2 == "T" && $3 !~ /^ssh_/ { print "#define", $3, "ssh_" $3 }'
*
* $FreeBSD$
*/
@ -21,9 +21,11 @@
#define addargs ssh_addargs
#define ask_permission ssh_ask_permission
#define atomicio ssh_atomicio
#define atomiciov ssh_atomiciov
#define auth_request_forwarding ssh_auth_request_forwarding
#define buffer_append ssh_buffer_append
#define buffer_append_space ssh_buffer_append_space
#define buffer_check_alloc ssh_buffer_check_alloc
#define buffer_clear ssh_buffer_clear
#define buffer_compress ssh_buffer_compress
#define buffer_compress_init_recv ssh_buffer_compress_init_recv
@ -73,11 +75,13 @@
#define chan_rcvd_oclose ssh_chan_rcvd_oclose
#define chan_read_failed ssh_chan_read_failed
#define chan_write_failed ssh_chan_write_failed
#define channel_add_adm_permitted_opens ssh_channel_add_adm_permitted_opens
#define channel_add_permitted_opens ssh_channel_add_permitted_opens
#define channel_after_select ssh_channel_after_select
#define channel_by_id ssh_channel_by_id
#define channel_cancel_cleanup ssh_channel_cancel_cleanup
#define channel_cancel_rport_listener ssh_channel_cancel_rport_listener
#define channel_clear_adm_permitted_opens ssh_channel_clear_adm_permitted_opens
#define channel_clear_permitted_opens ssh_channel_clear_permitted_opens
#define channel_close_all ssh_channel_close_all
#define channel_close_fd ssh_channel_close_fd
@ -185,6 +189,9 @@
#define get_remote_ipaddr ssh_get_remote_ipaddr
#define get_remote_name_or_ip ssh_get_remote_name_or_ip
#define get_remote_port ssh_get_remote_port
#define get_u16 ssh_get_u16
#define get_u32 ssh_get_u32
#define get_u64 ssh_get_u64
#define getrrsetbyname ssh_getrrsetbyname
#define host_hash ssh_host_hash
#define hostfile_read_key ssh_hostfile_read_key
@ -217,6 +224,7 @@
#define key_names_valid2 ssh_key_names_valid2
#define key_new ssh_key_new
#define key_new_private ssh_key_new_private
#define key_perm_ok ssh_key_perm_ok
#define key_read ssh_key_read
#define key_save_private ssh_key_save_private
#define key_sign ssh_key_sign
@ -301,9 +309,14 @@
#define packet_write_poll ssh_packet_write_poll
#define packet_write_wait ssh_packet_write_wait
#define percent_expand ssh_percent_expand
#define permanently_drop_suid ssh_permanently_drop_suid
#define permanently_set_uid ssh_permanently_set_uid
#define prime_test ssh_prime_test
#define proto_spec ssh_proto_spec
#define put_host_port ssh_put_host_port
#define put_u16 ssh_put_u16
#define put_u32 ssh_put_u32
#define put_u64 ssh_put_u64
#define pwcopy ssh_pwcopy
#define read_keyfile_line ssh_read_keyfile_line
#define read_passphrase ssh_read_passphrase
@ -322,6 +335,7 @@
#define set_nodelay ssh_set_nodelay
#define set_nonblock ssh_set_nonblock
#define shadow_pw ssh_shadow_pw
#define sigdie ssh_sigdie
#define ssh1_3des_iv ssh_ssh1_3des_iv
#define start_progress_meter ssh_start_progress_meter
#define stop_progress_meter ssh_stop_progress_meter
@ -345,6 +359,8 @@
#define x11_create_display_inet ssh_x11_create_display_inet
#define x11_input_open ssh_x11_input_open
#define x11_request_forwarding_with_spoofing ssh_x11_request_forwarding_with_spoofing
#define xasprintf ssh_xasprintf
#define xcalloc ssh_xcalloc
#define xcrypt ssh_xcrypt
#define xfree ssh_xfree
#define xmalloc ssh_xmalloc

View File

@ -1,3 +1,4 @@
/* $OpenBSD: sshconnect.c,v 1.199 2006/08/03 03:34:42 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -13,12 +14,35 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sshconnect.c,v 1.171 2005/12/06 22:38:27 reyk Exp $");
#include <openssl/bn.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/socket.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#include <pwd.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "ssh.h"
#include "xmalloc.h"
#include "key.h"
#include "hostfile.h"
#include "ssh.h"
#include "rsa.h"
#include "buffer.h"
#include "packet.h"
@ -32,6 +56,7 @@ RCSID("$OpenBSD: sshconnect.c,v 1.171 2005/12/06 22:38:27 reyk Exp $");
#include "atomicio.h"
#include "misc.h"
#include "dns.h"
#include "version.h"
char *client_version_string = NULL;
char *server_version_string = NULL;
@ -62,7 +87,6 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
int pin[2], pout[2];
pid_t pid;
char strport[NI_MAXSERV];
size_t len;
/* Convert the port number into a string. */
snprintf(strport, sizeof strport, "%hu", port);
@ -74,10 +98,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
* Use "exec" to avoid "sh -c" processes on some platforms
* (e.g. Solaris)
*/
len = strlen(proxy_command) + 6;
tmp = xmalloc(len);
strlcpy(tmp, "exec ", len);
strlcat(tmp, proxy_command, len);
xasprintf(&tmp, "exec %s", proxy_command);
command_string = percent_expand(tmp, "h", host,
"p", strport, (char *)NULL);
xfree(tmp);
@ -94,8 +115,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
char *argv[10];
/* Child. Permanently give up superuser privileges. */
seteuid(original_real_uid);
setuid(original_real_uid);
permanently_drop_suid(original_real_uid);
/* Redirect stdin and stdout. */
close(pin[1]);
@ -205,7 +225,7 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
fd_set *fdset;
struct timeval tv;
socklen_t optlen;
int fdsetsz, optval, rc, result = -1;
int optval, rc, result = -1;
if (timeout <= 0)
return (connect(sockfd, serv_addr, addrlen));
@ -219,10 +239,8 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
if (errno != EINPROGRESS)
return (-1);
fdsetsz = howmany(sockfd + 1, NFDBITS) * sizeof(fd_mask);
fdset = (fd_set *)xmalloc(fdsetsz);
memset(fdset, 0, fdsetsz);
fdset = (fd_set *)xcalloc(howmany(sockfd + 1, NFDBITS),
sizeof(fd_mask));
FD_SET(sockfd, fdset);
tv.tv_sec = timeout;
tv.tv_usec = 0;
@ -305,17 +323,14 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
fatal("%s: %.100s: %s", __progname, host,
gai_strerror(gaierr));
/*
* Try to connect several times. On some machines, the first time
* will sometimes fail. In general socket code appears to behave
* quite magically on many machines.
*/
for (attempt = 0; ;) {
for (attempt = 0; attempt < connection_attempts; attempt++) {
if (attempt > 0)
debug("Trying again...");
/* Loop through addresses for this host, and try each one in
sequence until the connection succeeds. */
/*
* Loop through addresses for this host, and try each one in
* sequence until the connection succeeds.
*/
for (ai = aitop; ai; ai = ai->ai_next) {
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
continue;
@ -342,21 +357,13 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
} else {
debug("connect to address %s port %s: %s",
ntop, strport, strerror(errno));
/*
* Close the failed socket; there appear to
* be some problems when reusing a socket for
* which connect() has already returned an
* error.
*/
close(sock);
sock = -1;
}
}
if (ai)
if (sock != -1)
break; /* Successful connection. */
attempt++;
if (attempt >= connection_attempts)
break;
/* Sleep a moment before retrying. */
sleep(1);
}
@ -364,7 +371,7 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
freeaddrinfo(aitop);
/* Return failure if we didn't get a successful connection. */
if (attempt >= connection_attempts) {
if (sock == -1) {
error("ssh: connect to host %s port %s: %s",
host, strport, strerror(errno));
return (-1);
@ -396,10 +403,10 @@ ssh_exchange_identification(void)
int connection_in = packet_get_connection_in();
int connection_out = packet_get_connection_out();
int minor1 = PROTOCOL_MINOR_1;
u_int i;
u_int i, n;
/* Read other side's version identification. */
for (;;) {
for (n = 0;;) {
for (i = 0; i < sizeof(buf) - 1; i++) {
size_t len = atomicio(read, connection_in, &buf[i], 1);
@ -416,6 +423,8 @@ ssh_exchange_identification(void)
buf[i + 1] = 0;
break;
}
if (++n > 65536)
fatal("ssh_exchange_identification: No banner received");
}
buf[sizeof(buf) - 1] = 0;
if (strncmp(buf, "SSH-", 4) == 0)
@ -517,13 +526,17 @@ confirm(const char *prompt)
* check whether the supplied host key is valid, return -1 if the key
* is not valid. the user_hostfile will not be updated if 'readonly' is true.
*/
#define RDRW 0
#define RDONLY 1
#define ROQUIET 2
static int
check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
int readonly, const char *user_hostfile, const char *system_hostfile)
check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port,
Key *host_key, int readonly, const char *user_hostfile,
const char *system_hostfile)
{
Key *file_key;
const char *type = key_type(host_key);
char *ip = NULL;
char *ip = NULL, *host = NULL;
char hostline[1000], *hostp, *fp;
HostStatus host_status;
HostStatus ip_status;
@ -574,7 +587,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
if (getnameinfo(hostaddr, salen, ntop, sizeof(ntop),
NULL, 0, NI_NUMERICHOST) != 0)
fatal("check_host_key: getnameinfo failed");
ip = xstrdup(ntop);
ip = put_host_port(ntop, port);
} else {
ip = xstrdup("<no hostip for proxy command>");
}
@ -582,18 +595,21 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
* Turn off check_host_ip if the connection is to localhost, via proxy
* command or if we don't have a hostname to compare with
*/
if (options.check_host_ip &&
(local || strcmp(host, ip) == 0 || options.proxy_command != NULL))
if (options.check_host_ip && (local ||
strcmp(hostname, ip) == 0 || options.proxy_command != NULL))
options.check_host_ip = 0;
/*
* Allow the user to record the key under a different name. This is
* useful for ssh tunneling over forwarded connections or if you run
* multiple sshd's on different ports on the same machine.
* Allow the user to record the key under a different name or
* differentiate a non-standard port. This is useful for ssh
* tunneling over forwarded connections or if you run multiple
* sshd's on different ports on the same machine.
*/
if (options.host_key_alias != NULL) {
host = options.host_key_alias;
host = xstrdup(options.host_key_alias);
debug("using hostkeyalias: %s", host);
} else {
host = put_host_port(hostname, port);
}
/*
@ -662,6 +678,15 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
}
break;
case HOST_NEW:
if (options.host_key_alias == NULL && port != 0 &&
port != SSH_DEFAULT_PORT) {
debug("checking without port identifier");
if (check_host_key(hostname, hostaddr, 0, host_key, 2,
user_hostfile, system_hostfile) == 0) {
debug("found matching key w/out port");
break;
}
}
if (readonly)
goto fail;
/* The host is new. */
@ -741,6 +766,8 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
"list of known hosts.", hostp, type);
break;
case HOST_CHANGED:
if (readonly == ROQUIET)
goto fail;
if (options.check_host_ip && host_ip_differ) {
char *key_msg;
if (ip_status == HOST_NEW)
@ -779,7 +806,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
/*
* If strict host key checking has not been requested, allow
* the connection but without MITM-able authentication or
* agent forwarding.
* forwarding.
*/
if (options.password_authentication) {
error("Password authentication is disabled to avoid "
@ -814,6 +841,11 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
options.num_local_forwards =
options.num_remote_forwards = 0;
}
if (options.tun_open != SSH_TUNMODE_NO) {
error("Tunnel forwarding is disabled to avoid "
"man-in-the-middle attacks.");
options.tun_open = SSH_TUNMODE_NO;
}
/*
* XXX Should permit the user to change to use the new id.
* This could be done by converting the host key to an
@ -855,10 +887,12 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
}
xfree(ip);
xfree(host);
return 0;
fail:
xfree(ip);
xfree(host);
return -1;
}
@ -892,12 +926,13 @@ verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
/* return ok if the key can be found in an old keyfile */
if (stat(options.system_hostfile2, &st) == 0 ||
stat(options.user_hostfile2, &st) == 0) {
if (check_host_key(host, hostaddr, host_key, /*readonly*/ 1,
options.user_hostfile2, options.system_hostfile2) == 0)
if (check_host_key(host, hostaddr, options.port, host_key,
RDONLY, options.user_hostfile2,
options.system_hostfile2) == 0)
return 0;
}
return check_host_key(host, hostaddr, host_key, /*readonly*/ 0,
options.user_hostfile, options.system_hostfile);
return check_host_key(host, hostaddr, options.port, host_key,
RDRW, options.user_hostfile, options.system_hostfile);
}
/*
@ -921,7 +956,7 @@ ssh_login(Sensitive *sensitive, const char *orighost,
host = xstrdup(orighost);
for (cp = host; *cp; cp++)
if (isupper(*cp))
*cp = tolower(*cp);
*cp = (char)tolower(*cp);
/* Exchange protocol version identification strings with the server. */
ssh_exchange_identification();
@ -938,6 +973,7 @@ ssh_login(Sensitive *sensitive, const char *orighost,
ssh_kex(host, hostaddr);
ssh_userauth1(local_user, server_user, host, sensitive);
}
xfree(local_user);
}
void
@ -951,8 +987,7 @@ ssh_put_password(char *password)
return;
}
size = roundup(strlen(password) + 1, 32);
padded = xmalloc(size);
memset(padded, 0, size);
padded = xcalloc(1, size);
strlcpy(padded, password, size);
packet_put_string(padded, size);
memset(padded, 0, size);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect.h,v 1.18 2005/12/06 22:38:28 reyk Exp $ */
/* $OpenBSD: sshconnect.h,v 1.23 2006/08/03 03:34:42 deraadt Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@ -23,8 +23,6 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SSHCONNECT_H
#define SSHCONNECT_H
typedef struct Sensitive Sensitive;
struct Sensitive {
@ -54,16 +52,18 @@ int ssh_local_cmd(const char *);
/*
* Macros to raise/lower permissions.
*/
#define PRIV_START do { \
int save_errno = errno; \
(void)seteuid(original_effective_uid); \
errno = save_errno; \
#define PRIV_START do { \
int save_errno = errno; \
if (seteuid(original_effective_uid) != 0) \
fatal("PRIV_START: seteuid: %s", \
strerror(errno)); \
errno = save_errno; \
} while (0)
#define PRIV_END do { \
int save_errno = errno; \
(void)seteuid(original_real_uid); \
errno = save_errno; \
#define PRIV_END do { \
int save_errno = errno; \
if (seteuid(original_real_uid) != 0) \
fatal("PRIV_END: seteuid: %s", \
strerror(errno)); \
errno = save_errno; \
} while (0)
#endif

View File

@ -1,3 +1,4 @@
/* $OpenBSD: sshconnect1.c,v 1.69 2006/08/03 03:34:42 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -13,28 +14,38 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sshconnect1.c,v 1.62 2005/10/30 08:52:18 djm Exp $");
#include <sys/types.h>
#include <sys/socket.h>
#include <openssl/bn.h>
#include <openssl/md5.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <pwd.h>
#include "xmalloc.h"
#include "ssh.h"
#include "ssh1.h"
#include "xmalloc.h"
#include "rsa.h"
#include "buffer.h"
#include "packet.h"
#include "key.h"
#include "cipher.h"
#include "kex.h"
#include "uidswap.h"
#include "log.h"
#include "readconf.h"
#include "key.h"
#include "authfd.h"
#include "sshconnect.h"
#include "authfile.h"
#include "misc.h"
#include "cipher.h"
#include "canohost.h"
#include "hostfile.h"
#include "auth.h"
/* Session id for the current session. */
@ -197,7 +208,7 @@ try_rsa_authentication(int idx)
BIGNUM *challenge;
Key *public, *private;
char buf[300], *passphrase, *comment, *authfile;
int i, type, quit;
int i, perm_ok = 1, type, quit;
public = options.identity_keys[idx];
authfile = options.identity_files[idx];
@ -243,15 +254,16 @@ try_rsa_authentication(int idx)
if (public->flags & KEY_FLAG_EXT)
private = public;
else
private = key_load_private_type(KEY_RSA1, authfile, "", NULL);
if (private == NULL && !options.batch_mode) {
private = key_load_private_type(KEY_RSA1, authfile, "", NULL,
&perm_ok);
if (private == NULL && !options.batch_mode && perm_ok) {
snprintf(buf, sizeof(buf),
"Enter passphrase for RSA key '%.100s': ", comment);
for (i = 0; i < options.number_of_password_prompts; i++) {
passphrase = read_passphrase(buf, 0);
if (strcmp(passphrase, "") != 0) {
private = key_load_private_type(KEY_RSA1,
authfile, passphrase, NULL);
authfile, passphrase, NULL, NULL);
quit = 0;
} else {
debug2("no passphrase given, try next key");
@ -268,7 +280,7 @@ try_rsa_authentication(int idx)
xfree(comment);
if (private == NULL) {
if (!options.batch_mode)
if (!options.batch_mode && perm_ok)
error("Bad passphrase.");
/* Send a dummy response packet to avoid protocol error. */

View File

@ -1,3 +1,4 @@
/* $OpenBSD: sshconnect2.c,v 1.162 2006/08/30 00:06:51 dtucker Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@ -23,18 +24,30 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sshconnect2.c,v 1.143 2005/10/14 02:17:59 stevesk Exp $");
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>
#include <pwd.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "openbsd-compat/sys-queue.h"
#include "xmalloc.h"
#include "ssh.h"
#include "ssh2.h"
#include "xmalloc.h"
#include "buffer.h"
#include "packet.h"
#include "compat.h"
#include "bufaux.h"
#include "cipher.h"
#include "key.h"
#include "kex.h"
#include "myproposal.h"
#include "sshconnect.h"
@ -49,6 +62,7 @@ RCSID("$OpenBSD: sshconnect2.c,v 1.143 2005/10/14 02:17:59 stevesk Exp $");
#include "canohost.h"
#include "msg.h"
#include "pathnames.h"
#include "uidswap.h"
#ifdef GSSAPI
#include "ssh-gss.h"
@ -122,6 +136,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
kex->client_version_string=client_version_string;
kex->server_version_string=server_version_string;
kex->verify_host_key=&verify_host_key_callback;
@ -363,7 +378,7 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt)
debug3("input_userauth_banner");
msg = packet_get_string(NULL);
lang = packet_get_string(NULL);
if (options.log_level > SYSLOG_LEVEL_QUIET)
if (options.log_level >= SYSLOG_LEVEL_INFO)
fprintf(stderr, "%s", msg);
xfree(msg);
xfree(lang);
@ -494,15 +509,10 @@ userauth_gssapi(Authctxt *authctxt)
/* Check to see if the mechanism is usable before we offer it */
while (mech < gss_supported->count && !ok) {
if (gssctxt)
ssh_gssapi_delete_ctx(&gssctxt);
ssh_gssapi_build_ctx(&gssctxt);
ssh_gssapi_set_oid(gssctxt, &gss_supported->elements[mech]);
/* My DER encoding requires length<128 */
if (gss_supported->elements[mech].length < 128 &&
!GSS_ERROR(ssh_gssapi_import_name(gssctxt,
authctxt->host))) {
ssh_gssapi_check_mechanism(&gssctxt,
&gss_supported->elements[mech], authctxt->host)) {
ok = 1; /* Mechanism works */
} else {
mech++;
@ -963,14 +973,16 @@ load_identity_file(char *filename)
{
Key *private;
char prompt[300], *passphrase;
int quit, i;
int perm_ok, quit, i;
struct stat st;
if (stat(filename, &st) < 0) {
debug3("no such identity: %s", filename);
return NULL;
}
private = key_load_private_type(KEY_UNSPEC, filename, "", NULL);
private = key_load_private_type(KEY_UNSPEC, filename, "", NULL, &perm_ok);
if (!perm_ok)
return NULL;
if (private == NULL) {
if (options.batch_mode)
return NULL;
@ -979,8 +991,8 @@ load_identity_file(char *filename)
for (i = 0; i < options.number_of_password_prompts; i++) {
passphrase = read_passphrase(prompt, 0);
if (strcmp(passphrase, "") != 0) {
private = key_load_private_type(KEY_UNSPEC, filename,
passphrase, NULL);
private = key_load_private_type(KEY_UNSPEC,
filename, passphrase, NULL, NULL);
quit = 0;
} else {
debug2("no passphrase given, try next key");
@ -1023,8 +1035,7 @@ pubkey_prepare(Authctxt *authctxt)
if (key && key->type == KEY_RSA1)
continue;
options.identity_keys[i] = NULL;
id = xmalloc(sizeof(*id));
memset(id, 0, sizeof(*id));
id = xcalloc(1, sizeof(*id));
id->key = key;
id->filename = xstrdup(options.identity_files[i]);
TAILQ_INSERT_TAIL(&files, id, next);
@ -1048,8 +1059,7 @@ pubkey_prepare(Authctxt *authctxt)
}
}
if (!found && !options.identities_only) {
id = xmalloc(sizeof(*id));
memset(id, 0, sizeof(*id));
id = xcalloc(1, sizeof(*id));
id->key = key;
id->filename = comment;
id->ac = ac;
@ -1245,8 +1255,7 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp,
return -1;
}
if (pid == 0) {
seteuid(getuid());
setuid(getuid());
permanently_drop_suid(getuid());
close(from[0]);
if (dup2(from[1], STDOUT_FILENO) < 0)
fatal("ssh_keysign: dup2: %s", strerror(errno));
@ -1326,12 +1335,11 @@ userauth_hostbased(Authctxt *authctxt)
if (p == NULL) {
error("userauth_hostbased: cannot get local ipaddr/name");
key_free(private);
xfree(blob);
return 0;
}
len = strlen(p) + 2;
chost = xmalloc(len);
strlcpy(chost, p, len);
strlcat(chost, ".", len);
xasprintf(&chost, "%s.", p);
debug2("userauth_hostbased: chost %s", chost);
xfree(p);
@ -1364,6 +1372,7 @@ userauth_hostbased(Authctxt *authctxt)
error("key_sign failed");
xfree(chost);
xfree(pkalg);
xfree(blob);
return 0;
}
packet_start(SSH2_MSG_USERAUTH_REQUEST);
@ -1379,6 +1388,7 @@ userauth_hostbased(Authctxt *authctxt)
xfree(signature);
xfree(chost);
xfree(pkalg);
xfree(blob);
packet_send();
return 1;

View File

@ -34,7 +34,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: sshd.8,v 1.215 2006/02/01 09:11:41 jmc Exp $
.\" $OpenBSD: sshd.8,v 1.234 2006/08/21 08:15:57 dtucker Exp $
.\" $FreeBSD$
.Dd September 25, 1999
.Dt SSHD 8
@ -82,7 +82,7 @@ configuration file.
.Nm
rereads its configuration file when it receives a hangup signal,
.Dv SIGHUP ,
by executing itself with the name and options it was started with, e.g.,
by executing itself with the name and options it was started with, e.g.\&
.Pa /usr/sbin/sshd .
.Pp
The options are as follows:
@ -153,7 +153,7 @@ is normally not run
from inetd because it needs to generate the server key before it can
respond to the client, and this may take tens of seconds.
Clients would have to wait too long if the key was regenerated every time.
However, with small key sizes (e.g., 512) using
However, with small key sizes (e.g. 512) using
.Nm
from inetd may
be feasible.
@ -307,17 +307,6 @@ or
.Ql \&*NP\&*
).
.Pp
System security is not improved unless
.Nm rshd ,
.Nm rlogind ,
and
.Nm rexecd
are disabled (thus completely disabling
.Xr rlogin
and
.Xr rsh
into the machine).
.Sh COMMAND EXECUTION AND DATA FORWARDING
If the client successfully authenticates itself, a dialog for
preparing the session is entered.
At this time the client may request
@ -325,7 +314,7 @@ things like allocating a pseudo-tty, forwarding X11 connections,
forwarding TCP connections, or forwarding the authentication agent
connection over the secure channel.
.Pp
Finally, the client either requests a shell or execution of a command.
After this, the client either requests a shell or execution of a command.
The sides then enter session mode.
In this mode, either side may send
data at any time, and such data is forwarded to/from the shell or
@ -381,32 +370,74 @@ it; otherwise runs
The
.Dq rc
files are given the X11
authentication protocol and cookie (if applicable) in standard input.
authentication protocol and cookie in standard input.
See
.Sx SSHRC ,
below.
.It
Runs user's shell or command.
.El
.Sh AUTHORIZED_KEYS FILE FORMAT
.Pa ~/.ssh/authorized_keys
is the default file that lists the public keys that are
permitted for RSA authentication in protocol version 1
and for public key authentication (PubkeyAuthentication)
in protocol version 2.
.Cm AuthorizedKeysFile
may be used to specify an alternative file.
.Sh SSHRC
If the file
.Pa ~/.ssh/rc
exists,
.Xr sh 1
runs it after reading the
environment files but before starting the user's shell or command.
It must not produce any output on stdout; stderr must be used
instead.
If X11 forwarding is in use, it will receive the "proto cookie" pair in
its standard input (and
.Ev DISPLAY
in its environment).
The script must call
.Xr xauth 1
because
.Nm
will not run xauth automatically to add X11 cookies.
.Pp
The primary purpose of this file is to run any initialization routines
which may be needed before the user's home directory becomes
accessible; AFS is a particular example of such an environment.
.Pp
This file will probably contain some initialization code followed by
something similar to:
.Bd -literal -offset 3n
if read proto cookie && [ -n "$DISPLAY" ]; then
if [ `echo $DISPLAY | cut -c1-10` = 'localhost:' ]; then
# X11UseLocalhost=yes
echo add unix:`echo $DISPLAY |
cut -c11-` $proto $cookie
else
# X11UseLocalhost=no
echo add $DISPLAY $proto $cookie
fi | xauth -q -
fi
.Ed
.Pp
If this file does not exist,
.Pa /etc/ssh/sshrc
is run, and if that
does not exist either, xauth is used to add the cookie.
.Sh AUTHORIZED_KEYS FILE FORMAT
.Cm AuthorizedKeysFile
specifies the file containing public keys for
public key authentication;
if none is specified, the default is
.Pa ~/.ssh/authorized_keys .
Each line of the file contains one
key (empty lines and lines starting with a
.Ql #
are ignored as
comments).
Each RSA public key consists of the following fields, separated by
spaces: options, bits, exponent, modulus, comment.
Each protocol version 2 public key consists of:
options, keytype, base64 encoded key, comment.
The options field
is optional; its presence is determined by whether the line starts
Protocol 1 public keys consist of the following space-separated fields:
options, bits, exponent, modulus, comment.
Protocol 2 public key consist of:
options, keytype, base64-encoded key, comment.
The options field is optional;
its presence is determined by whether the line starts
with a number or not (the options field never starts with a number).
The bits, exponent, modulus and comment fields give the RSA key for
The bits, exponent, modulus, and comment fields give the RSA key for
protocol version 1; the
comment field is not used for anything (but may be convenient for the
user to identify the key).
@ -421,7 +452,7 @@ Note that lines in this file are usually several hundred bytes long
keys up to 16 kilobits.
You don't want to type them in; instead, copy the
.Pa identity.pub ,
.Pa id_dsa.pub
.Pa id_dsa.pub ,
or the
.Pa id_rsa.pub
file and edit it.
@ -436,26 +467,6 @@ No spaces are permitted, except within double quotes.
The following option specifications are supported (note
that option keywords are case-insensitive):
.Bl -tag -width Ds
.It Cm from="pattern-list"
Specifies that in addition to public key authentication, the canonical name
of the remote host must be present in the comma-separated list of
patterns
.Pf ( Ql \&*
and
.Ql \&?
serve as wildcards).
The list may also contain
patterns negated by prefixing them with
.Ql \&! ;
if the canonical host name matches a negated pattern, the key is not accepted.
The purpose
of this option is to optionally increase security: public key authentication
by itself does not trust the network or name servers or anything (but
the key); however, if somebody somehow steals the key, the key
permits an intruder to log in from anywhere in the world.
This additional option makes using a stolen key more difficult (name
servers and/or routers would have to be compromised in addition to
just the key).
.It Cm command="command"
Specifies that the command is executed whenever this key is used for
authentication.
@ -471,6 +482,9 @@ to restrict certain public keys to perform just a specific operation.
An example might be a key that permits remote backups but nothing else.
Note that the client may specify TCP and/or X11
forwarding unless they are explicitly prohibited.
The command originally supplied by the client is available in the
.Ev SSH_ORIGINAL_COMMAND
environment variable.
Note that this option applies to shell, command or subsystem execution.
.It Cm environment="NAME=value"
Specifies that the string is to be added to the environment when
@ -485,20 +499,38 @@ option.
This option is automatically disabled if
.Cm UseLogin
is enabled.
.It Cm no-port-forwarding
Forbids TCP forwarding when this key is used for authentication.
Any port forward requests by the client will return an error.
This might be used, e.g., in connection with the
.Cm command
option.
.It Cm no-X11-forwarding
Forbids X11 forwarding when this key is used for authentication.
Any X11 forward requests by the client will return an error.
.It Cm from="pattern-list"
Specifies that in addition to public key authentication, the canonical name
of the remote host must be present in the comma-separated list of
patterns.
The purpose
of this option is to optionally increase security: public key authentication
by itself does not trust the network or name servers or anything (but
the key); however, if somebody somehow steals the key, the key
permits an intruder to log in from anywhere in the world.
This additional option makes using a stolen key more difficult (name
servers and/or routers would have to be compromised in addition to
just the key).
.Pp
See
.Sx PATTERNS
in
.Xr ssh_config 5
for more information on patterns.
.It Cm no-agent-forwarding
Forbids authentication agent forwarding when this key is used for
authentication.
.It Cm no-port-forwarding
Forbids TCP forwarding when this key is used for authentication.
Any port forward requests by the client will return an error.
This might be used, e.g. in connection with the
.Cm command
option.
.It Cm no-pty
Prevents tty allocation (a request to allocate a pty will fail).
.It Cm no-X11-forwarding
Forbids X11 forwarding when this key is used for authentication.
Any X11 forward requests by the client will return an error.
.It Cm permitopen="host:port"
Limit local
.Li ``ssh -L''
@ -518,16 +550,20 @@ device on the server.
Without this option, the next available device will be used if
the client requests a tunnel.
.El
.Ss Examples
1024 33 12121...312314325 ylo@foo.bar
.Pp
from="*.niksula.hut.fi,!pc.niksula.hut.fi" 1024 35 23...2334 ylo@niksula
.Pp
command="dump /home",no-pty,no-port-forwarding 1024 33 23...2323 backup.hut.fi
.Pp
permitopen="10.2.1.55:80",permitopen="10.2.1.56:25" 1024 33 23...2323
.Pp
tunnel="0",command="sh /etc/netstart tun0" ssh-rsa AAAA...== reyk@openbsd.org
An example authorized_keys file:
.Bd -literal -offset 3n
# Comments allowed at start of line
ssh-rsa AAAAB3Nza...LiPk== user@example.net
from="*.sales.example.net,!pc.sales.example.net" ssh-rsa
AAAAB2...19Q== john@example.net
command="dump /home",no-pty,no-port-forwarding ssh-dss
AAAAC3...51R== example.net
permitopen="192.0.2.1:80",permitopen="192.0.2.2:25" ssh-dss
AAAAB5...21S==
tunnel="0",command="sh /etc/netstart tun0" ssh-rsa AAAA...==
jane@example.net
.Ed
.Sh SSH_KNOWN_HOSTS FILE FORMAT
The
.Pa /etc/ssh/ssh_known_hosts
@ -536,7 +572,7 @@ and
files contain host public keys for all known hosts.
The global file should
be prepared by the administrator (optional), and the per-user file is
maintained automatically: whenever the user connects from an unknown host
maintained automatically: whenever the user connects from an unknown host,
its key is added to the per-user file.
.Pp
Each line in these files contains the following fields: hostnames,
@ -544,7 +580,7 @@ bits, exponent, modulus, comment.
The fields are separated by spaces.
.Pp
Hostnames is a comma-separated list of patterns
.Pf ( Ql \&*
.Pf ( Ql *
and
.Ql \&?
act as
@ -556,6 +592,13 @@ A pattern may also be preceded by
to indicate negation: if the host name matches a negated
pattern, it is not accepted (by that line) even if it matched another
pattern on the line.
A hostname or address may optionally be enclosed within
.Ql \&[
and
.Ql \&]
brackets then followed by
.Ql \&:
and a non-standard port number.
.Pp
Alternately, hostnames may be stored in a hashed form which hides host names
and addresses should the file's contents be disclosed.
@ -566,7 +609,7 @@ Only one hashed hostname may appear on a single line and none of the above
negation or wildcard operators may be applied.
.Pp
Bits, exponent, and modulus are taken directly from the RSA host key; they
can be obtained, e.g., from
can be obtained, for example, from
.Pa /etc/ssh/ssh_host_key.pub .
The optional comment field continues to the end of the line, and is not used.
.Pp
@ -591,88 +634,19 @@ Rather, generate them by a script
or by taking
.Pa /etc/ssh/ssh_host_key.pub
and adding the host names at the front.
.Ss Examples
.Bd -literal
closenet,...,130.233.208.41 1024 37 159...93 closenet.hut.fi
cvs.openbsd.org,199.185.137.3 ssh-rsa AAAA1234.....=
.Ed
.Bd -literal
.Pp
An example ssh_known_hosts file:
.Bd -literal -offset 3n
# Comments allowed at start of line
closenet,...,192.0.2.53 1024 37 159...93 closenet.example.net
cvs.example.net,192.0.2.10 ssh-rsa AAAA1234.....=
# A hashed hostname
|1|JfKTdBh7rNbXkVAQCRp4OQoPfmI=|USECr3SWf1JUPsms5AqfD5QfxkM= ssh-rsa
AAAA1234.....=
.Ed
.Sh FILES
.Bl -tag -width Ds
.It Pa /etc/ssh/sshd_config
Contains configuration data for
.Nm sshd .
The file format and configuration options are described in
.Xr sshd_config 5 .
.It Pa /etc/ssh/ssh_host_key, /etc/ssh/ssh_host_dsa_key
These two files contain the private parts of the host keys.
These files should only be owned by root, readable only by root, and not
accessible to others.
Note that
.Nm
does not start if this file is group/world-accessible.
.It Pa /etc/ssh/ssh_host_key.pub, /etc/ssh/ssh_host_dsa_key.pub
These two files contain the public parts of the host keys.
These files should be world-readable but writable only by
root.
Their contents should match the respective private parts.
These files are not
really used for anything; they are provided for the convenience of
the user so their contents can be copied to known hosts files.
These files are created using
.Xr ssh-keygen 1 .
.It Pa /etc/ssh/moduli
Contains Diffie-Hellman groups used for the "Diffie-Hellman Group Exchange".
The file format is described in
.Xr moduli 5 .
.It Pa /var/empty
.Xr chroot 2
directory used by
.Nm
during privilege separation in the pre-authentication phase.
The directory should not contain any files and must be owned by root
and not group or world-writable.
.It Pa /var/run/sshd.pid
Contains the process ID of the
.Nm
listening for connections (if there are several daemons running
concurrently for different ports, this contains the process ID of the one
started last).
The content of this file is not sensitive; it can be world-readable.
.It Pa ~/.ssh/authorized_keys
Lists the public keys (RSA or DSA) that can be used to log into the user's account.
This file must be readable by root (which may on some machines imply
it being world-readable if the user's home directory resides on an NFS
volume).
It is recommended that it not be accessible by others.
The format of this file is described above.
Users will place the contents of their
.Pa identity.pub ,
.Pa id_dsa.pub
and/or
.Pa id_rsa.pub
files into this file, as described in
.Xr ssh-keygen 1 .
.It Pa "/etc/ssh/ssh_known_hosts", "~/.ssh/known_hosts"
These files are consulted when using rhosts with RSA host
authentication or protocol version 2 hostbased authentication
to check the public key of the host.
The key must be listed in one of these files to be accepted.
The client uses the same files
to verify that it is connecting to the correct remote host.
These files should be writable only by root/the owner.
.Pa /etc/ssh/ssh_known_hosts
should be world-readable, and
.Pa ~/.ssh/known_hosts
can, but need not be, world-readable.
.It Pa /etc/motd
See
.Xr motd 5 .
.It Pa ~/.hushlogin
.Bl -tag -width Ds -compact
.It ~/.hushlogin
This file is used to suppress printing the last login time and
.Pa /etc/motd ,
if
@ -683,86 +657,49 @@ respectively,
are enabled.
It does not suppress printing of the banner specified by
.Cm Banner .
.It Pa /etc/nologin
If this file exists,
.Pp
.It ~/.rhosts
This file is used for host-based authentication (see
.Xr ssh 1
for more information).
On some machines this file may need to be
world-readable if the user's home directory is on an NFS partition,
because
.Nm
refuses to let anyone except root log in.
The contents of the file
are displayed to anyone trying to log in, and non-root connections are
refused.
The file should be world-readable.
.It Pa /etc/hosts.allow, /etc/hosts.deny
Access controls that should be enforced by tcp-wrappers are defined here.
Further details are described in
.Xr hosts_access 5 .
.It Pa ~/.rhosts
This file is used during
.Cm RhostsRSAAuthentication
and
.Cm HostbasedAuthentication
and contains host-username pairs, separated by a space, one per
line.
The given user on the corresponding host is permitted to log in
without a password.
The same file is used by rlogind and rshd.
The file must
be writable only by the user; it is recommended that it not be
reads it as root.
Additionally, this file must be owned by the user,
and must not have write permissions for anyone else.
The recommended
permission for most machines is read/write for the user, and not
accessible by others.
.Pp
It is also possible to use netgroups in the file.
Either host or user
name may be of the form +@groupname to specify all hosts or all users
in the group.
.It Pa ~/.shosts
For ssh,
this file is exactly the same as for
.Pa .rhosts .
However, this file is
not used by rlogin and rshd, so using this permits access using SSH only.
.It Pa /etc/hosts.equiv
This file is used during
.Cm RhostsRSAAuthentication
and
.Cm HostbasedAuthentication
authentication.
In the simplest form, this file contains host names, one per line.
Users on
those hosts are permitted to log in without a password, provided they
have the same user name on both machines.
The host name may also be
followed by a user name; such users are permitted to log in as
.Em any
user on this machine (except root).
Additionally, the syntax
.Dq +@group
can be used to specify netgroups.
Negated entries start with
.Ql \&- .
.It ~/.shosts
This file is used in exactly the same way as
.Pa .rhosts ,
but allows host-based authentication without permitting login with
rlogin/rsh.
.Pp
If the client host/user is successfully matched in this file, login is
automatically permitted provided the client and server user names are the
same.
Additionally, successful client host key authentication is required.
This file must be writable only by root; it is recommended
that it be world-readable.
.It ~/.ssh/authorized_keys
Lists the public keys (RSA/DSA) that can be used for logging in as this user.
The format of this file is described above.
The content of the file is not highly sensitive, but the recommended
permissions are read/write for the user, and not accessible by others.
.Pp
.Sy "Warning: It is almost never a good idea to use user names in"
.Pa hosts.equiv .
Beware that it really means that the named user(s) can log in as
.Em anybody ,
which includes bin, daemon, adm, and other accounts that own critical
binaries and directories.
Using a user name practically grants the user root access.
The only valid use for user names that I can think
of is in negative entries.
If this file, the
.Pa ~/.ssh
directory, or the user's home directory are writable
by other users, then the file could be modified or replaced by unauthorized
users.
In this case,
.Nm
will not allow it to be used unless the
.Cm StrictModes
option has been set to
.Dq no .
The recommended permissions can be set by executing
.Dq chmod go-w ~/ ~/.ssh ~/.ssh/authorized_keys .
.Pp
Note that this warning also applies to rsh/rlogin.
.It Pa /etc/ssh/shosts.equiv
This is processed exactly as
.Pa /etc/hosts.equiv .
However, this file may be useful in environments that want to run both
rsh/rlogin and ssh.
.It Pa ~/.ssh/environment
.It ~/.ssh/environment
This file is read into the environment at login (if it exists).
It can only contain empty lines, comment lines (that start with
.Ql # ) ,
@ -773,55 +710,115 @@ Environment processing is disabled by default and is
controlled via the
.Cm PermitUserEnvironment
option.
.It Pa ~/.ssh/rc
If this file exists, it is run with
.Pa /bin/sh
after reading the
environment files but before starting the user's shell or command.
It must not produce any output on stdout; stderr must be used
instead.
If X11 forwarding is in use, it will receive the "proto cookie" pair in
its standard input (and
.Ev DISPLAY
in its environment).
The script must call
.Xr xauth 1
because
.Nm
will not run xauth automatically to add X11 cookies.
.Pp
The primary purpose of this file is to run any initialization routines
which may be needed before the user's home directory becomes
accessible; AFS is a particular example of such an environment.
.Pp
This file will probably contain some initialization code followed by
something similar to:
.Bd -literal
if read proto cookie && [ -n "$DISPLAY" ]; then
if [ `echo $DISPLAY | cut -c1-10` = 'localhost:' ]; then
# X11UseLocalhost=yes
echo add unix:`echo $DISPLAY |
cut -c11-` $proto $cookie
else
# X11UseLocalhost=no
echo add $DISPLAY $proto $cookie
fi | xauth -q -
fi
.Ed
.Pp
If this file does not exist,
.Pa /etc/ssh/sshrc
is run, and if that
does not exist either, xauth is used to add the cookie.
.It ~/.ssh/known_hosts
Contains a list of host keys for all hosts the user has logged into
that are not already in the systemwide list of known host keys.
The format of this file is described above.
This file should be writable only by root/the owner and
can, but need not be, world-readable.
.Pp
.It ~/.ssh/rc
Contains initialization routines to be run before
the user's home directory becomes accessible.
This file should be writable only by the user, and need not be
readable by anyone else.
.It Pa /etc/ssh/sshrc
Like
.Pa ~/.ssh/rc .
This can be used to specify
.Pp
.It /etc/hosts.allow
.It /etc/hosts.deny
Access controls that should be enforced by tcp-wrappers are defined here.
Further details are described in
.Xr hosts_access 5 .
.Pp
.It /etc/hosts.equiv
This file is for host-based authentication (see
.Xr ssh 1 ) .
It should only be writable by root.
.Pp
.It /etc/moduli
Contains Diffie-Hellman groups used for the "Diffie-Hellman Group Exchange".
The file format is described in
.Xr moduli 5 .
.Pp
.It /etc/motd
See
.Xr motd 5 .
.Pp
.It /etc/nologin
If this file exists,
.Nm
refuses to let anyone except root log in.
The contents of the file
are displayed to anyone trying to log in, and non-root connections are
refused.
The file should be world-readable.
.Pp
.It /etc/shosts.equiv
This file is used in exactly the same way as
.Pa hosts.equiv ,
but allows host-based authentication without permitting login with
rlogin/rsh.
.Pp
.It /etc/ssh/ssh_known_hosts
Systemwide list of known host keys.
This file should be prepared by the
system administrator to contain the public host keys of all machines in the
organization.
The format of this file is described above.
This file should be writable only by root/the owner and
should be world-readable.
.Pp
.It /etc/ssh/ssh_host_key
.It /etc/ssh/ssh_host_dsa_key
.It /etc/ssh/ssh_host_rsa_key
These three files contain the private parts of the host keys.
These files should only be owned by root, readable only by root, and not
accessible to others.
Note that
.Nm
does not start if these files are group/world-accessible.
.Pp
.It /etc/ssh/ssh_host_key.pub
.It /etc/ssh/ssh_host_dsa_key.pub
.It /etc/ssh/ssh_host_rsa_key.pub
These three files contain the public parts of the host keys.
These files should be world-readable but writable only by
root.
Their contents should match the respective private parts.
These files are not
really used for anything; they are provided for the convenience of
the user so their contents can be copied to known hosts files.
These files are created using
.Xr ssh-keygen 1 .
.Pp
.It /etc/ssh/sshd_config
Contains configuration data for
.Nm sshd .
The file format and configuration options are described in
.Xr sshd_config 5 .
.Pp
.It /etc/ssh/sshrc
Similar to
.Pa ~/.ssh/rc ,
it can be used to specify
machine-specific login-time initializations globally.
This file should be writable only by root, and should be world-readable.
.Pp
.It /var/empty
.Xr chroot 2
directory used by
.Nm
during privilege separation in the pre-authentication phase.
The directory should not contain any files and must be owned by root
and not group or world-writable.
.Pp
.It /var/run/sshd.pid
Contains the process ID of the
.Nm
listening for connections (if there are several daemons running
concurrently for different ports, this contains the process ID of the one
started last).
The content of this file is not sensitive; it can be world-readable.
.El
.Sh SEE ALSO
.Xr scp 1 ,
@ -837,26 +834,6 @@ This file should be writable only by root, and should be world-readable.
.Xr sshd_config 5 ,
.Xr inetd 8 ,
.Xr sftp-server 8
.Rs
.%A T. Ylonen
.%A T. Kivinen
.%A M. Saarinen
.%A T. Rinne
.%A S. Lehtinen
.%T "SSH Protocol Architecture"
.%N draft-ietf-secsh-architecture-12.txt
.%D January 2002
.%O work in progress material
.Re
.Rs
.%A M. Friedl
.%A N. Provos
.%A W. A. Simpson
.%T "Diffie-Hellman Group Exchange for the SSH Transport Layer Protocol"
.%N draft-ietf-secsh-dh-group-exchange-02.txt
.%D January 2002
.%O work in progress material
.Re
.Sh AUTHORS
OpenSSH is a derivative of the original and free
ssh 1.2.12 release by Tatu Ylonen.
@ -868,3 +845,14 @@ Markus Friedl contributed the support for SSH
protocol versions 1.5 and 2.0.
Niels Provos and Markus Friedl contributed support
for privilege separation.
.Sh CAVEATS
System security is not improved unless
.Nm rshd ,
.Nm rlogind ,
and
.Nm rexecd
are disabled (thus completely disabling
.Xr rlogin
and
.Xr rsh
into the machine).

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
# $OpenBSD: sshd_config,v 1.73 2005/12/06 22:38:28 reyk Exp $
# $OpenBSD: sshd_config,v 1.74 2006/07/19 13:07:10 dtucker Exp $
# $FreeBSD$
# This is the sshd server system-wide configuration file. See
@ -74,14 +74,15 @@
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
# Set this to 'no' to disable PAM authentication, account processing,
# Set this to 'no' to disable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication mechanism.
# Depending on your PAM configuration, this may bypass the setting of
# PasswordAuthentication, PermitEmptyPasswords, and
# "PermitRootLogin without-password". If you just want the PAM account and
# session checks to run without PAM authentication, then enable this but set
# ChallengeResponseAuthentication=no
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
#UsePAM yes
#AllowTcpForwarding yes
@ -108,3 +109,9 @@
# override default of no subsystems
Subsystem sftp /usr/libexec/sftp-server
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# ForceCommand cvs server

View File

@ -34,7 +34,7 @@
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $OpenBSD: sshd_config.5,v 1.48 2006/01/02 17:09:49 jmc Exp $
.\" $OpenBSD: sshd_config.5,v 1.70 2006/08/21 08:14:01 dtucker Exp $
.\" $FreeBSD$
.Dd September 25, 1999
.Dt SSHD_CONFIG 5
@ -47,7 +47,7 @@
.It Pa /etc/ssh/sshd_config
.El
.Sh DESCRIPTION
.Nm sshd
.Xr sshd 8
reads configuration data from
.Pa /etc/ssh/sshd_config
(or the file specified with
@ -57,6 +57,9 @@ The file contains keyword-argument pairs, one per line.
Lines starting with
.Ql #
and empty lines are interpreted as comments.
Arguments may optionally be enclosed in double quotes
.Pq \&"
in order to represent arguments containing spaces.
.Pp
The possible
keywords and their meanings are as follows (note that
@ -73,7 +76,7 @@ in
for how to configure the client.
Note that environment passing is only supported for protocol 2.
Variables are specified by name, which may contain the wildcard characters
.Ql \&*
.Ql *
and
.Ql \&? .
Multiple environment variables may be separated by whitespace or spread
@ -86,11 +89,11 @@ For this reason, care should be taken in the use of this directive.
The default is not to accept any environment variables.
.It Cm AddressFamily
Specifies which address family should be used by
.Nm sshd .
.Xr sshd 8 .
Valid arguments are
.Dq any ,
.Dq inet
(use IPv4 only) or
(use IPv4 only), or
.Dq inet6
(use IPv6 only).
The default is
@ -100,13 +103,20 @@ This keyword can be followed by a list of group name patterns, separated
by spaces.
If specified, login is allowed only for users whose primary
group or supplementary group list matches one of the patterns.
.Ql \&*
and
.Ql \&?
can be used as
wildcards in the patterns.
Only group names are valid; a numerical group ID is not recognized.
By default, login is allowed for all groups.
The allow/deny directives are processed in the following order:
.Cm DenyUsers ,
.Cm AllowUsers ,
.Cm DenyGroups ,
and finally
.Cm AllowGroups .
.Pp
See
.Sx PATTERNS
in
.Xr ssh_config 5
for more information on patterns.
.It Cm AllowTcpForwarding
Specifies whether TCP forwarding is permitted.
The default is
@ -119,24 +129,31 @@ This keyword can be followed by a list of user name patterns, separated
by spaces.
If specified, login is allowed only for user names that
match one of the patterns.
.Ql \&*
and
.Ql \&?
can be used as
wildcards in the patterns.
Only user names are valid; a numerical user ID is not recognized.
By default, login is allowed for all users.
If the pattern takes the form USER@HOST then USER and HOST
are separately checked, restricting logins to particular
users from particular hosts.
The allow/deny directives are processed in the following order:
.Cm DenyUsers ,
.Cm AllowUsers ,
.Cm DenyGroups ,
and finally
.Cm AllowGroups .
.Pp
See
.Sx PATTERNS
in
.Xr ssh_config 5
for more information on patterns.
.It Cm AuthorizedKeysFile
Specifies the file that contains the public keys that can be used
for user authentication.
.Cm AuthorizedKeysFile
may contain tokens of the form %T which are substituted during connection
set-up.
setup.
The following tokens are defined: %% is replaced by a literal '%',
%h is replaced by the home directory of the user being authenticated and
%h is replaced by the home directory of the user being authenticated, and
%u is replaced by the username of that user.
After expansion,
.Cm AuthorizedKeysFile
@ -182,20 +199,19 @@ The supported ciphers are
.Dq blowfish-cbc ,
and
.Dq cast128-cbc .
The default is
.Bd -literal
``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128,
arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr,
aes192-ctr,aes256-ctr''
The default is:
.Bd -literal -offset 3n
aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128,
arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr,
aes192-ctr,aes256-ctr
.Ed
.It Cm ClientAliveCountMax
Sets the number of client alive messages (see below) which may be
sent without
.Nm sshd
.Xr sshd 8
receiving any messages back from the client.
If this threshold is reached while client alive messages are being sent,
.Nm sshd
will disconnect the client, terminating the session.
sshd will disconnect the client, terminating the session.
It is important to note that the use of client alive messages is very
different from
.Cm TCPKeepAlive
@ -213,12 +229,13 @@ If
.Cm ClientAliveInterval
(see below) is set to 15, and
.Cm ClientAliveCountMax
is left at the default, unresponsive ssh clients
is left at the default, unresponsive SSH clients
will be disconnected after approximately 45 seconds.
This option applies to protocol version 2 only.
.It Cm ClientAliveInterval
Sets a timeout interval in seconds after which if no data has been received
from the client,
.Nm sshd
.Xr sshd 8
will send a message through the encrypted
channel to request a response from the client.
The default
@ -239,36 +256,62 @@ This keyword can be followed by a list of group name patterns, separated
by spaces.
Login is disallowed for users whose primary group or supplementary
group list matches one of the patterns.
.Ql \&*
and
.Ql \&?
can be used as
wildcards in the patterns.
Only group names are valid; a numerical group ID is not recognized.
By default, login is allowed for all groups.
The allow/deny directives are processed in the following order:
.Cm DenyUsers ,
.Cm AllowUsers ,
.Cm DenyGroups ,
and finally
.Cm AllowGroups .
.Pp
See
.Sx PATTERNS
in
.Xr ssh_config 5
for more information on patterns.
.It Cm DenyUsers
This keyword can be followed by a list of user name patterns, separated
by spaces.
Login is disallowed for user names that match one of the patterns.
.Ql \&*
and
.Ql \&?
can be used as wildcards in the patterns.
Only user names are valid; a numerical user ID is not recognized.
By default, login is allowed for all users.
If the pattern takes the form USER@HOST then USER and HOST
are separately checked, restricting logins to particular
users from particular hosts.
The allow/deny directives are processed in the following order:
.Cm DenyUsers ,
.Cm AllowUsers ,
.Cm DenyGroups ,
and finally
.Cm AllowGroups .
.Pp
See
.Sx PATTERNS
in
.Xr ssh_config 5
for more information on patterns.
.It Cm ForceCommand
Forces the execution of the command specified by
.Cm ForceCommand ,
ignoring any command supplied by the client.
The command is invoked by using the user's login shell with the -c option.
This applies to shell, command, or subsystem execution.
It is most useful inside a
.Cm Match
block.
The command originally supplied by the client is available in the
.Ev SSH_ORIGINAL_COMMAND
environment variable.
.It Cm GatewayPorts
Specifies whether remote hosts are allowed to connect to ports
forwarded for the client.
By default,
.Nm sshd
.Xr sshd 8
binds remote port forwardings to the loopback address.
This prevents other remote hosts from connecting to forwarded ports.
.Cm GatewayPorts
can be used to specify that
.Nm sshd
can be used to specify that sshd
should allow remote port forwardings to bind to non-loopback addresses, thus
allowing other hosts to connect.
The argument may be
@ -294,12 +337,29 @@ Note that this option applies to protocol version 2 only.
.It Cm HostbasedAuthentication
Specifies whether rhosts or /etc/hosts.equiv authentication together
with successful public key client host authentication is allowed
(hostbased authentication).
(host-based authentication).
This option is similar to
.Cm RhostsRSAAuthentication
and applies to protocol version 2 only.
The default is
.Dq no .
.It Cm HostbasedUsesNameFromPacketOnly
Specifies whether or not the server will attempt to perform a reverse
name lookup when matching the name in the
.Pa ~/.shosts ,
.Pa ~/.rhosts ,
and
.Pa /etc/hosts.equiv
files during
.Cm HostbasedAuthentication .
A setting of
.Dq yes
means that
.Xr sshd 8
uses the name supplied by the client rather than
attempting to resolve the name from the TCP connection itself.
The default is
.Dq no .
.It Cm HostKey
Specifies a file containing a private host key
used by SSH.
@ -309,7 +369,7 @@ for protocol version 1, and
.Pa /etc/ssh/ssh_host_dsa_key
for protocol version 2.
Note that
.Nm sshd
.Xr sshd 8
will refuse to use a file if it is group/world-accessible.
It is possible to have multiple host key files.
.Dq rsa1
@ -336,7 +396,7 @@ The default is
.Dq yes .
.It Cm IgnoreUserKnownHosts
Specifies whether
.Nm sshd
.Xr sshd 8
should ignore the user's
.Pa ~/.ssh/known_hosts
during
@ -351,24 +411,24 @@ Specifies whether the password provided by the user for
will be validated through the Kerberos KDC.
To use this option, the server needs a
Kerberos servtab which allows the verification of the KDC's identity.
Default is
The default is
.Dq no .
.It Cm KerberosGetAFSToken
If AFS is active and the user has a Kerberos 5 TGT, attempt to acquire
an AFS token before accessing the user's home directory.
Default is
The default is
.Dq no .
.It Cm KerberosOrLocalPasswd
If set then if password authentication through Kerberos fails then
If password authentication through Kerberos fails then
the password will be validated via any additional local mechanism
such as
.Pa /etc/passwd .
Default is
The default is
.Dq yes .
.It Cm KerberosTicketCleanup
Specifies whether to automatically destroy the user's ticket cache
file on logout.
Default is
The default is
.Dq yes .
.It Cm KeyRegenerationInterval
In protocol version 1, the ephemeral server key is automatically regenerated
@ -381,7 +441,7 @@ If the value is 0, the key is never regenerated.
The default is 3600 (seconds).
.It Cm ListenAddress
Specifies the local addresses
.Nm sshd
.Xr sshd 8
should listen on.
The following forms may be used:
.Pp
@ -407,8 +467,7 @@ The following forms may be used:
If
.Ar port
is not specified,
.Nm sshd
will listen on the address and all prior
sshd will listen on the address and all prior
.Cm Port
options specified.
The default is to listen on all local addresses.
@ -417,7 +476,7 @@ Multiple
options are permitted.
Additionally, any
.Cm Port
options must precede this option for non port qualified addresses.
options must precede this option for non-port qualified addresses.
.It Cm LoginGraceTime
The server disconnects after this time if the user has not
successfully logged in.
@ -425,9 +484,9 @@ If the value is 0, there is no time limit.
The default is 120 seconds.
.It Cm LogLevel
Gives the verbosity level that is used when logging messages from
.Nm sshd .
.Xr sshd 8 .
The possible values are:
QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2 and DEBUG3.
QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2, and DEBUG3.
The default is INFO.
DEBUG and DEBUG1 are equivalent.
DEBUG2 and DEBUG3 each specify higher levels of debugging output.
@ -437,8 +496,37 @@ Specifies the available MAC (message authentication code) algorithms.
The MAC algorithm is used in protocol version 2
for data integrity protection.
Multiple algorithms must be comma-separated.
The default is
The default is:
.Dq hmac-md5,hmac-sha1,hmac-ripemd160,hmac-sha1-96,hmac-md5-96 .
.It Cm Match
Introduces a conditional block.
If all of the criteria on the
.Cm Match
line are satisfied, the keywords on the following lines override those
set in the global section of the config file, until either another
.Cm Match
line or the end of the file.
The arguments to
.Cm Match
are one or more criteria-pattern pairs.
The available criteria are
.Cm User ,
.Cm Group ,
.Cm Host ,
and
.Cm Address .
Only a subset of keywords may be used on the lines following a
.Cm Match
keyword.
Available keywords are
.Cm AllowTcpForwarding ,
.Cm ForceCommand ,
.Cm GatewayPorts ,
.Cm PermitOpen ,
.Cm X11DisplayOffset ,
.Cm X11Forwarding ,
and
.Cm X11UseLocalHost .
.It Cm MaxAuthTries
Specifies the maximum number of authentication attempts permitted per
connection.
@ -447,8 +535,7 @@ additional failures are logged.
The default is 6.
.It Cm MaxStartups
Specifies the maximum number of concurrent unauthenticated connections to the
.Nm sshd
daemon.
SSH daemon.
Additional connections will be dropped until authentication succeeds or the
.Cm LoginGraceTime
expires for a connection.
@ -457,8 +544,8 @@ The default is 10.
Alternatively, random early drop can be enabled by specifying
the three colon separated values
.Dq start:rate:full
(e.g., "10:30:60").
.Nm sshd
(e.g. "10:30:60").
.Xr sshd 8
will refuse connection attempts with a probability of
.Dq rate/100
(30%)
@ -494,13 +581,40 @@ When password authentication is allowed, it specifies whether the
server allows login to accounts with empty password strings.
The default is
.Dq no .
.It Cm PermitOpen
Specifies the destinations to which TCP port forwarding is permitted.
The forwarding specification must be one of the following forms:
.Pp
.Bl -item -offset indent -compact
.It
.Cm PermitOpen
.Sm off
.Ar host : port
.Sm on
.It
.Cm PermitOpen
.Sm off
.Ar IPv4_addr : port
.Sm on
.It
.Cm PermitOpen
.Sm off
.Ar \&[ IPv6_addr \&] : port
.Sm on
.El
.Pp
Multiple forwards may be specified by separating them with whitespace.
An argument of
.Dq any
can be used to remove all restrictions and permit any forwarding requests.
By default all port forwarding requests are permitted.
.It Cm PermitRootLogin
Specifies whether root can log in using
.Xr ssh 1 .
The argument must be
.Dq yes ,
.Dq without-password ,
.Dq forced-commands-only
.Dq forced-commands-only ,
or
.Dq no .
The default is
@ -514,11 +628,11 @@ the root user may be allowed in with its password even if
.Dq without-password .
.Pp
If this option is set to
.Dq without-password
.Dq without-password ,
password authentication is disabled for root.
.Pp
If this option is set to
.Dq forced-commands-only
.Dq forced-commands-only ,
root login with public key authentication will be allowed,
but only if the
.Ar command
@ -528,7 +642,7 @@ normally not allowed).
All other authentication methods are disabled for root.
.Pp
If this option is set to
.Dq no
.Dq no ,
root is not allowed to log in.
.It Cm PermitTunnel
Specifies whether
@ -536,10 +650,17 @@ Specifies whether
device forwarding is allowed.
The argument must be
.Dq yes ,
.Dq point-to-point ,
.Dq point-to-point
(layer 3),
.Dq ethernet
or
(layer 2), or
.Dq no .
Specifying
.Dq yes
permits both
.Dq point-to-point
and
.Dq ethernet .
The default is
.Dq no .
.It Cm PermitUserEnvironment
@ -550,7 +671,7 @@ and
options in
.Pa ~/.ssh/authorized_keys
are processed by
.Nm sshd .
.Xr sshd 8 .
The default is
.Dq no .
Enabling environment processing may enable users to bypass access
@ -558,13 +679,12 @@ restrictions in some configurations using mechanisms such as
.Ev LD_PRELOAD .
.It Cm PidFile
Specifies the file that contains the process ID of the
.Nm sshd
daemon.
SSH daemon.
The default is
.Pa /var/run/sshd.pid .
.It Cm Port
Specifies the port number that
.Nm sshd
.Xr sshd 8
listens on.
The default is 22.
Multiple options of this type are permitted.
@ -572,14 +692,14 @@ See also
.Cm ListenAddress .
.It Cm PrintLastLog
Specifies whether
.Nm sshd
.Xr sshd 8
should print the date and time of the last user login when a user logs
in interactively.
The default is
.Dq yes .
.It Cm PrintMotd
Specifies whether
.Nm sshd
.Xr sshd 8
should print
.Pa /etc/motd
when a user logs in interactively.
@ -590,12 +710,12 @@ The default is
.Dq yes .
.It Cm Protocol
Specifies the protocol versions
.Nm sshd
.Xr sshd 8
supports.
The possible values are
.Dq 1
.Sq 1
and
.Dq 2 .
.Sq 2 .
Multiple versions must be comma-separated.
The default is
.Dq 2 .
@ -629,7 +749,7 @@ Defines the number of bits in the ephemeral protocol version 1 server key.
The minimum value is 512, and the default is 768.
.It Cm StrictModes
Specifies whether
.Nm sshd
.Xr sshd 8
should check file modes and ownership of the
user's files and home directory before accepting login.
This is normally desirable because novices sometimes accidentally leave their
@ -637,9 +757,9 @@ directory or files world-writable.
The default is
.Dq yes .
.It Cm Subsystem
Configures an external subsystem (e.g., file transfer daemon).
Arguments should be a subsystem name and a command to execute upon subsystem
request.
Configures an external subsystem (e.g. file transfer daemon).
Arguments should be a subsystem name and a command (with optional arguments)
to execute upon subsystem request.
The command
.Xr sftp-server 8
implements the
@ -649,7 +769,7 @@ By default no subsystems are defined.
Note that this option applies to protocol version 2 only.
.It Cm SyslogFacility
Gives the facility code that is used when logging messages from
.Nm sshd .
.Xr sshd 8 .
The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
The default is AUTH.
@ -676,7 +796,7 @@ To disable TCP keepalive messages, the value should be set to
.Dq no .
.It Cm UseDNS
Specifies whether
.Nm sshd
.Xr sshd 8
should look up the remote host name and check that
the resolved host name for the remote IP address maps back to the
very same IP address.
@ -707,7 +827,10 @@ If set to
.Dq yes
this will enable PAM authentication using
.Cm ChallengeResponseAuthentication
and PAM account and session module processing for all authentication types.
and
.Cm PasswordAuthentication
in addition to PAM account and session module processing for all
authentication types.
.Pp
Because PAM challenge-response authentication usually serves an equivalent
role to password authentication, you should disable either
@ -724,7 +847,7 @@ The default is
.Dq yes .
.It Cm UsePrivilegeSeparation
Specifies whether
.Nm sshd
.Xr sshd 8
separates privileges by creating an unprivileged child process
to deal with incoming network traffic.
After successful authentication, another process will be created that has
@ -740,11 +863,9 @@ The default is
.Dq FreeBSD-20060322 .
.It Cm X11DisplayOffset
Specifies the first display number available for
.Nm sshd Ns 's
.Xr sshd 8 Ns 's
X11 forwarding.
This prevents
.Nm sshd
from interfering with real X11 servers.
This prevents sshd from interfering with real X11 servers.
The default is 10.
.It Cm X11Forwarding
Specifies whether X11 forwarding is permitted.
@ -757,14 +878,14 @@ The default is
.Pp
When X11 forwarding is enabled, there may be additional exposure to
the server and to client displays if the
.Nm sshd
.Xr sshd 8
proxy display is configured to listen on the wildcard address (see
.Cm X11UseLocalhost
below), however this is not the default.
below), though this is not the default.
Additionally, the authentication spoofing and authentication data
verification and substitution occur on the client side.
The security risk of using X11 forwarding is that the client's X11
display server may be exposed to attack when the ssh client requests
display server may be exposed to attack when the SSH client requests
forwarding (see the warnings for
.Cm ForwardX11
in
@ -782,12 +903,11 @@ X11 forwarding is automatically disabled if
is enabled.
.It Cm X11UseLocalhost
Specifies whether
.Nm sshd
.Xr sshd 8
should bind the X11 forwarding server to the loopback address or to
the wildcard address.
By default,
.Nm sshd
binds the forwarding server to the loopback address and sets the
sshd binds the forwarding server to the loopback address and sets the
hostname part of the
.Ev DISPLAY
environment variable to
@ -813,8 +933,8 @@ program.
The default is
.Pa /usr/X11R6/bin/xauth .
.El
.Ss Time Formats
.Nm sshd
.Sh TIME FORMATS
.Xr sshd 8
command-line arguments and configuration file options that specify time
may be expressed using a sequence of the form:
.Sm off
@ -827,7 +947,7 @@ is a positive integer value and
is one of the following:
.Pp
.Bl -tag -width Ds -compact -offset indent
.It Cm <none>
.It Aq Cm none
seconds
.It Cm s | Cm S
seconds
@ -858,7 +978,7 @@ Time format examples:
.Bl -tag -width Ds
.It Pa /etc/ssh/sshd_config
Contains configuration data for
.Nm sshd .
.Xr sshd 8 .
This file should be writable by root only, but it is recommended
(though not necessary) that it be world-readable.
.El

View File

@ -1,3 +1,4 @@
/* $OpenBSD: sshlogin.c,v 1.25 2006/08/03 03:34:42 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -39,7 +40,20 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sshlogin.c,v 1.13 2004/08/12 09:18:24 djm Exp $");
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include "loginrec.h"
#include "log.h"
@ -54,15 +68,15 @@ extern ServerOptions options;
* information is not available. This must be called before record_login.
* The host the user logged in from will be returned in buf.
*/
u_long
time_t
get_last_login_time(uid_t uid, const char *logname,
char *buf, u_int bufsize)
char *buf, size_t bufsize)
{
struct logininfo li;
login_get_lastlog(&li, uid);
strlcpy(buf, li.hostname, bufsize);
return li.tv_sec;
return (time_t)li.tv_sec;
}
/*
@ -103,7 +117,7 @@ store_lastlog_message(const char *user, uid_t uid)
*/
void
record_login(pid_t pid, const char *tty, const char *user, uid_t uid,
const char *host, struct sockaddr * addr, socklen_t addrlen)
const char *host, struct sockaddr *addr, socklen_t addrlen)
{
struct logininfo *li;
@ -119,7 +133,7 @@ record_login(pid_t pid, const char *tty, const char *user, uid_t uid,
#ifdef LOGIN_NEEDS_UTMPX
void
record_utmp_only(pid_t pid, const char *ttyname, const char *user,
const char *host, struct sockaddr * addr, socklen_t addrlen)
const char *host, struct sockaddr *addr, socklen_t addrlen)
{
struct logininfo *li;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshlogin.h,v 1.4 2002/08/29 15:57:25 stevesk Exp $ */
/* $OpenBSD: sshlogin.h,v 1.8 2006/08/03 03:34:42 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -11,18 +11,13 @@
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*/
#ifndef SSHLOGIN_H
#define SSHLOGIN_H
void
record_login(pid_t, const char *, const char *, uid_t,
void record_login(pid_t, const char *, const char *, uid_t,
const char *, struct sockaddr *, socklen_t);
void record_logout(pid_t, const char *, const char *);
u_long get_last_login_time(uid_t, const char *, char *, u_int);
time_t get_last_login_time(uid_t, const char *, char *, u_int);
#ifdef LOGIN_NEEDS_UTMPX
void record_utmp_only(pid_t, const char *, const char *, const char *,
struct sockaddr *, socklen_t);
#endif
#endif

View File

@ -1,3 +1,4 @@
/* $OpenBSD: sshpty.c,v 1.26 2006/08/03 03:34:42 deraadt Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -12,11 +13,26 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sshpty.c,v 1.12 2004/06/21 17:36:31 avsm Exp $");
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#ifdef HAVE_PATHS_H
# include <paths.h>
#endif
#include <pwd.h>
#include <stdarg.h>
#include <string.h>
#include <termios.h>
#ifdef HAVE_UTIL_H
# include <util.h>
#endif /* HAVE_UTIL_H */
#endif
#include <unistd.h>
#include "sshpty.h"
#include "log.h"
@ -38,7 +54,7 @@ RCSID("$OpenBSD: sshpty.c,v 1.12 2004/06/21 17:36:31 avsm Exp $");
*/
int
pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
{
/* openpty(3) exists in OSF/1 and some other os'es */
char *name;
@ -161,11 +177,12 @@ pty_make_controlling_tty(int *ttyfd, const char *tty)
/* Changes the window size associated with the pty. */
void
pty_change_window_size(int ptyfd, int row, int col,
int xpixel, int ypixel)
pty_change_window_size(int ptyfd, u_int row, u_int col,
u_int xpixel, u_int ypixel)
{
struct winsize w;
/* may truncate u_int -> u_short */
w.ws_row = row;
w.ws_col = col;
w.ws_xpixel = xpixel;
@ -200,6 +217,10 @@ pty_setowner(struct passwd *pw, const char *tty)
fatal("stat(%.100s) failed: %.100s", tty,
strerror(errno));
#ifdef WITH_SELINUX
ssh_selinux_setup_pty(pw->pw_name, tty);
#endif
if (st.st_uid != pw->pw_uid || st.st_gid != gid) {
if (chown(tty, pw->pw_uid, gid) < 0) {
if (errno == EROFS &&

View File

@ -1,11 +1,11 @@
/* $OpenBSD: version.h,v 1.46 2006/02/01 11:27:22 markus Exp $ */
/* $OpenBSD: version.h,v 1.47 2006/08/30 00:14:37 djm Exp $ */
/* $FreeBSD$ */
#ifndef SSH_VERSION
#define SSH_VERSION (ssh_version_get())
#define SSH_RELEASE (ssh_version_get())
#define SSH_VERSION_BASE "OpenSSH_4.3p1"
#define SSH_VERSION_BASE "OpenSSH_4.4p1"
#define SSH_VERSION_ADDENDUM "FreeBSD-20060322"
const char *ssh_version_get(void);