Resolve conflicts.

This commit is contained in:
Dag-Erling Smørgrav 2004-02-26 10:52:33 +00:00
parent 6b475b41d8
commit 1ec0d75429
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=126277
61 changed files with 2271 additions and 2987 deletions

View File

@ -45,16 +45,16 @@ OpenSSH contains no GPL code.
software are publicly available on the Internet and at any major
bookstore, scientific library, and patent office worldwide. More
information can be found e.g. at "http://www.cs.hut.fi/crypto".
The legal status of this program is some combination of all these
permissions and restrictions. Use only at your own responsibility.
You will be responsible for any legal consequences yourself; I am not
making any claims whether possessing or using this is legal or not in
your country, and I am not taking any responsibility on your behalf.
NO WARRANTY
NO WARRANTY
BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
@ -64,7 +64,7 @@ OpenSSH contains no GPL code.
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
@ -112,15 +112,15 @@ OpenSSH contains no GPL code.
with the following license:
* @version 3.0 (December 2000)
*
*
* Optimised ANSI C code for the Rijndael cipher (now AES)
*
*
* @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
* @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
* @author Paulo Barreto <paulo.barreto@terra.com.br>
*
*
* This code is hereby placed in the public domain.
*
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -177,13 +177,12 @@ OpenSSH contains no GPL code.
Damien Miller
Kevin Steves
Daniel Kouril
Per Allansson
Wesley Griffin
Per Allansson
Nils Nordman
Simon Wilkinson
Portable OpenSSH additionally includes code from the following copyright
Portable OpenSSH additionally includes code from the following copyright
holders, also under the 2-term BSD license:
Ben Lindstrom
@ -203,6 +202,7 @@ OpenSSH contains no GPL code.
Todd C. Miller
Wayne Schroeder
William Jones
Darren Tucker
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -229,24 +229,24 @@ OpenSSH contains no GPL code.
a) md5crypt.c, md5crypt.h
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@login.dknet.dk> wrote this file. As long as you retain this
* notice you can do whatever you want with this stuff. If we meet
* some day, and you think this stuff is worth it, you can buy me a
* <phk@login.dknet.dk> wrote this file. As long as you retain this
* notice you can do whatever you want with this stuff. If we meet
* some day, and you think this stuff is worth it, you can buy me a
* beer in return. Poul-Henning Kamp
b) snprintf replacement
* Copyright Patrick Powell 1995
* This code is based on code written by Patrick Powell
* (papowell@astart.com) It may be used for any purpose as long as this
* This code is based on code written by Patrick Powell
* (papowell@astart.com) It may be used for any purpose as long as this
* notice remains intact on all source code distributions
c) Compatibility code (openbsd-compat)
Apart from the previously mentioned licenses, various pieces of code
Apart from the previously mentioned licenses, various pieces of code
in the openbsd-compat/ subdirectory are licensed as follows:
Some code is licensed under a 3-term BSD license, to the following
Some code is licensed under a 3-term BSD license, to the following
copyright holders:
Todd C. Miller
@ -279,7 +279,7 @@ OpenSSH contains no GPL code.
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
Some code is licensed under an ISC-style license, to the following
Some code is licensed under an ISC-style license, to the following
copyright holders:
Internet Software Consortium.
@ -297,7 +297,7 @@ OpenSSH contains no GPL code.
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Some code is licensed under a MIT-style license to the following
Some code is licensed under a MIT-style license to the following
copyright holders:
Free Software Foundation, Inc.
@ -329,4 +329,4 @@ OpenSSH contains no GPL code.
------
$OpenBSD: LICENCE,v 1.17 2003/08/22 20:55:06 markus Exp $
$OpenBSD: LICENCE,v 1.18 2003/11/21 11:57:02 djm Exp $

View File

@ -1,4 +1,4 @@
/* $Id: acconfig.h,v 1.166 2003/09/16 01:52:19 dtucker Exp $ */
/* $Id: acconfig.h,v 1.173 2004/02/06 05:24:31 dtucker Exp $ */
/* $FreeBSD$ */
/*
@ -42,6 +42,12 @@
/* Define if your setregid() is broken */
#undef BROKEN_SETREGID
/* Define if your setresuid() is broken */
#undef BROKEN_SETRESUID
/* Define if your setresgid() is broken */
#undef BROKEN_SETRESGID
/* Define to a Set Process Title type if your system is */
/* supported by bsd-setproctitle.c */
#undef SPT_TYPE
@ -60,6 +66,9 @@
/* from environment and PATH */
#undef LOGIN_PROGRAM_FALLBACK
/* Full path of your "passwd" program */
#undef _PATH_PASSWD_PROG
/* Define if your password has a pw_class field */
#undef HAVE_PW_CLASS_IN_PASSWD
@ -90,6 +99,9 @@
/* Define if you have the getuserattr function. */
#undef HAVE_GETUSERATTR
/* Define if you have the basename function. */
#undef HAVE_BASENAME
/* Work around problematic Linux PAM modules handling of PAM_TTY */
#undef PAM_TTY_KLUDGE
@ -248,6 +260,9 @@
/* Define this if you are using the Heimdal version of Kerberos V5 */
#undef HEIMDAL
/* Define this if you want to use libkafs' AFS support */
#undef USE_AFS
/* Define if you want S/Key support */
#undef SKEY
@ -419,15 +434,15 @@
#undef LOCKED_PASSWD_PREFIX
#undef LOCKED_PASSWD_SUBSTR
/* Define if DNS support is to be activated */
#undef DNS
/* Define if getrrsetbyname() exists */
#undef HAVE_GETRRSETBYNAME
/* Define if HEADER.ad exists in arpa/nameser.h */
#undef HAVE_HEADER_AD
/* Define if your resolver libs need this for getrrsetbyname */
#undef BIND_8_COMPAT
@BOTTOM@
/* ******************* Shouldn't need to edit below this line ************** */

View File

@ -23,7 +23,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth-chall.c,v 1.8 2001/05/18 14:13:28 markus Exp $");
RCSID("$OpenBSD: auth-chall.c,v 1.9 2003/11/03 09:03:37 djm Exp $");
RCSID("$FreeBSD$");
#include "auth.h"
@ -68,36 +68,38 @@ get_challenge(Authctxt *authctxt)
int
verify_response(Authctxt *authctxt, const char *response)
{
char *resp[1];
int res;
char *resp[1], *name, *info, **prompts;
u_int i, numprompts, *echo_on;
int authenticated = 0;
if (device == NULL)
return 0;
if (authctxt->kbdintctxt == NULL)
return 0;
resp[0] = (char *)response;
res = device->respond(authctxt->kbdintctxt, 1, resp);
if (res == 1) {
/* postponed - send a null query just in case */
char *name, *info, **prompts;
u_int i, numprompts, *echo_on;
switch (device->respond(authctxt->kbdintctxt, 1, resp)) {
case 0: /* Success */
authenticated = 1;
break;
case 1: /* Postponed - retry with empty query for PAM */
if ((device->query(authctxt->kbdintctxt, &name, &info,
&numprompts, &prompts, &echo_on)) != 0)
break;
if (numprompts == 0 &&
device->respond(authctxt->kbdintctxt, 0, resp) == 0)
authenticated = 1;
res = device->query(authctxt->kbdintctxt, &name, &info,
&numprompts, &prompts, &echo_on);
if (res == 0) {
for (i = 0; i < numprompts; i++)
xfree(prompts[i]);
xfree(prompts);
xfree(name);
xfree(echo_on);
xfree(info);
}
/* if we received more prompts, we're screwed */
res = (res == 0 && numprompts == 0) ? 0 : -1;
for (i = 0; i < numprompts; i++)
xfree(prompts[i]);
xfree(prompts);
xfree(name);
xfree(echo_on);
xfree(info);
break;
}
device->free_ctx(authctxt->kbdintctxt);
authctxt->kbdintctxt = NULL;
return res ? 0 : 1;
return authenticated;
}
void
abandon_challenge_response(Authctxt *authctxt)

View File

@ -28,7 +28,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth-krb5.c,v 1.12 2003/08/28 12:54:34 markus Exp $");
RCSID("$OpenBSD: auth-krb5.c,v 1.15 2003/11/21 11:57:02 djm Exp $");
RCSID("$FreeBSD$");
#include "ssh.h"
@ -41,7 +41,6 @@ RCSID("$FreeBSD$");
#include "auth.h"
#ifdef KRB5
#include <krb5.h>
extern ServerOptions options;
@ -51,7 +50,6 @@ krb5_init(void *context)
{
Authctxt *authctxt = (Authctxt *)context;
krb5_error_code problem;
static int cleanup_registered = 0;
if (authctxt->krb5_ctx == NULL) {
problem = krb5_init_context(&authctxt->krb5_ctx);
@ -59,10 +57,6 @@ krb5_init(void *context)
return (problem);
krb5_init_ets(authctxt->krb5_ctx);
}
if (!cleanup_registered) {
fatal_add_cleanup(krb5_cleanup_proc, authctxt);
cleanup_registered = 1;
}
return (0);
}
@ -74,11 +68,11 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
krb5_principal server;
char ccname[40];
int tmpfd;
#endif
#endif
krb5_error_code problem;
krb5_ccache ccache = NULL;
if (authctxt->pw == NULL)
if (!authctxt->valid)
return (0);
temporarily_use_uid(authctxt->pw);
@ -103,14 +97,15 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
goto out;
restore_uid();
problem = krb5_verify_user(authctxt->krb5_ctx, authctxt->krb5_user,
ccache, password, 1, NULL);
temporarily_use_uid(authctxt->pw);
if (problem)
goto out;
problem = krb5_cc_gen_new(authctxt->krb5_ctx, &krb5_fcc_ops,
&authctxt->krb5_fwd_ccache);
if (problem)
@ -141,21 +136,21 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
temporarily_use_uid(authctxt->pw);
if (problem)
goto out;
if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
if (!krb5_kuserok(authctxt->krb5_ctx, authctxt->krb5_user,
authctxt->pw->pw_name)) {
problem = -1;
goto out;
}
}
snprintf(ccname,sizeof(ccname),"FILE:/tmp/krb5cc_%d_XXXXXX",geteuid());
if ((tmpfd = mkstemp(ccname+strlen("FILE:")))==-1) {
logit("mkstemp(): %.100s", strerror(errno));
problem = errno;
goto out;
}
if (fchmod(tmpfd,S_IRUSR | S_IWUSR) == -1) {
logit("fchmod(): %.100s", strerror(errno));
close(tmpfd);
@ -172,12 +167,12 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
authctxt->krb5_user);
if (problem)
goto out;
problem= krb5_cc_store_cred(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache,
&creds);
if (problem)
goto out;
#endif
#endif
authctxt->krb5_ticket_file = (char *)krb5_cc_get_name(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);
@ -206,10 +201,8 @@ auth_krb5_password(Authctxt *authctxt, const char *password)
}
void
krb5_cleanup_proc(void *context)
krb5_cleanup_proc(Authctxt *authctxt)
{
Authctxt *authctxt = (Authctxt *)context;
debug("krb5_cleanup_proc called");
if (authctxt->krb5_fwd_ccache) {
krb5_cc_destroy(authctxt->krb5_ctx, authctxt->krb5_fwd_ccache);

View File

@ -31,11 +31,15 @@
/* 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.72.2.2 2003/09/23 09:24:21 djm Exp $");
RCSID("$Id: auth-pam.c,v 1.95 2004/02/17 12:20:08 dtucker Exp $");
RCSID("$FreeBSD$");
#ifdef USE_PAM
#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
#include "auth.h"
#include "auth-pam.h"
@ -53,24 +57,54 @@ RCSID("$FreeBSD$");
#include "auth-options.h"
extern ServerOptions options;
#ifndef __unused
#define __unused
#endif
extern Buffer loginmsg;
extern int compat20;
#ifdef USE_POSIX_THREADS
#include <pthread.h>
/*
* Avoid namespace clash when *not* using pthreads for systems *with*
* pthreads, which unconditionally define pthread_t via sys/types.h
* Avoid namespace clash when *not* using pthreads for systems *with*
* pthreads, which unconditionally define pthread_t via sys/types.h
* (e.g. Linux)
*/
typedef pthread_t sp_pthread_t;
typedef pthread_t sp_pthread_t;
#else
typedef pid_t sp_pthread_t;
#endif
struct pam_ctxt {
sp_pthread_t pam_thread;
int pam_psock;
int pam_csock;
int pam_done;
};
static void sshpam_free_ctx(void *);
static struct pam_ctxt *cleanup_ctxt;
#ifndef USE_POSIX_THREADS
/*
* Simulate threads with processes.
*/
typedef pid_t sp_pthread_t;
static int sshpam_thread_status = -1;
static mysig_t sshpam_oldsig;
static void
sshpam_sigchld_handler(int sig)
{
if (cleanup_ctxt == NULL)
return; /* handler called after PAM cleanup, shouldn't happen */
if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, 0) == -1)
return; /* couldn't wait for process */
if (WIFSIGNALED(sshpam_thread_status) &&
WTERMSIG(sshpam_thread_status) == SIGTERM)
return; /* terminated by pthread_cancel */
if (!WIFEXITED(sshpam_thread_status))
fatal("PAM: authentication thread exited unexpectedly");
if (WEXITSTATUS(sshpam_thread_status) != 0)
fatal("PAM: authentication thread exited uncleanly");
}
static void
pthread_exit(void *value __unused)
@ -93,6 +127,7 @@ pthread_create(sp_pthread_t *thread, const void *attr __unused,
_exit(1);
default:
*thread = pid;
sshpam_oldsig = signal(SIGCHLD, sshpam_sigchld_handler);
return (0);
}
}
@ -100,6 +135,7 @@ pthread_create(sp_pthread_t *thread, const void *attr __unused,
static int
pthread_cancel(sp_pthread_t thread)
{
signal(SIGCHLD, sshpam_oldsig);
return (kill(thread, SIGTERM));
}
@ -108,6 +144,9 @@ pthread_join(sp_pthread_t thread, void **value __unused)
{
int status;
if (sshpam_thread_status != -1)
return (sshpam_thread_status);
signal(SIGCHLD, sshpam_oldsig);
waitpid(thread, &status, 0);
return (status);
}
@ -117,18 +156,80 @@ pthread_join(sp_pthread_t thread, void **value __unused)
static pam_handle_t *sshpam_handle = NULL;
static int sshpam_err = 0;
static int sshpam_authenticated = 0;
static int sshpam_new_authtok_reqd = 0;
static int sshpam_session_open = 0;
static int sshpam_cred_established = 0;
static int sshpam_account_status = -1;
static char **sshpam_env = NULL;
static int *force_pwchange;
struct pam_ctxt {
sp_pthread_t pam_thread;
int pam_psock;
int pam_csock;
int pam_done;
};
/* Some PAM implementations don't implement this */
#ifndef HAVE_PAM_GETENVLIST
static char **
pam_getenvlist(pam_handle_t *pamh)
{
/*
* XXX - If necessary, we can still support envrionment passing
* for platforms without pam_getenvlist by searching for known
* env vars (e.g. KRB5CCNAME) from the PAM environment.
*/
return NULL;
}
#endif
static void sshpam_free_ctx(void *);
void
pam_password_change_required(int reqd)
{
debug3("%s %d", __func__, reqd);
*force_pwchange = reqd;
if (reqd) {
no_port_forwarding_flag |= 2;
no_agent_forwarding_flag |= 2;
no_x11_forwarding_flag |= 2;
} else {
no_port_forwarding_flag &= ~2;
no_agent_forwarding_flag &= ~2;
no_x11_forwarding_flag &= ~2;
}
}
/* Import regular and PAM environment from subprocess */
static void
import_environments(Buffer *b)
{
char *env;
u_int i, num_env;
int err;
debug3("PAM: %s entering", __func__);
/* Import variables set by do_pam_account */
sshpam_account_status = buffer_get_int(b);
pam_password_change_required(buffer_get_int(b));
/* Import environment from subprocess */
num_env = buffer_get_int(b);
sshpam_env = xmalloc((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);
sshpam_env[num_env] = NULL;
/* Import PAM environment from subprocess */
num_env = buffer_get_int(b);
debug("PAM: num PAM env strings %d", num_env);
for(i = 0; i < num_env; i++) {
env = buffer_get_string(b, NULL);
#ifdef HAVE_PAM_PUTENV
/* Errors are not fatal here */
if ((err = pam_putenv(sshpam_handle, env)) != PAM_SUCCESS) {
error("PAM: pam_putenv: %s",
pam_strerror(sshpam_handle, sshpam_err));
}
#endif
}
}
/*
* Conversation function for authentication thread.
@ -142,6 +243,7 @@ sshpam_thread_conv(int n, const struct pam_message **msg,
struct pam_response *reply;
int i;
debug3("PAM: %s entering, %d messages", __func__, n);
*resp = NULL;
ctxt = data;
@ -156,36 +258,42 @@ sshpam_thread_conv(int n, const struct pam_message **msg,
for (i = 0; i < n; ++i) {
switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
case PAM_PROMPT_ECHO_OFF:
buffer_put_cstring(&buffer,
buffer_put_cstring(&buffer,
PAM_MSG_MEMBER(msg, i, msg));
ssh_msg_send(ctxt->pam_csock,
PAM_MSG_MEMBER(msg, i, msg_style), &buffer);
ssh_msg_recv(ctxt->pam_csock, &buffer);
if (ssh_msg_send(ctxt->pam_csock,
PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1)
goto fail;
if (ssh_msg_recv(ctxt->pam_csock, &buffer) == -1)
goto fail;
if (buffer_get_char(&buffer) != PAM_AUTHTOK)
goto fail;
reply[i].resp = buffer_get_string(&buffer, NULL);
break;
case PAM_PROMPT_ECHO_ON:
buffer_put_cstring(&buffer,
buffer_put_cstring(&buffer,
PAM_MSG_MEMBER(msg, i, msg));
ssh_msg_send(ctxt->pam_csock,
PAM_MSG_MEMBER(msg, i, msg_style), &buffer);
ssh_msg_recv(ctxt->pam_csock, &buffer);
if (ssh_msg_send(ctxt->pam_csock,
PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1)
goto fail;
if (ssh_msg_recv(ctxt->pam_csock, &buffer) == -1)
goto fail;
if (buffer_get_char(&buffer) != PAM_AUTHTOK)
goto fail;
reply[i].resp = buffer_get_string(&buffer, NULL);
break;
case PAM_ERROR_MSG:
buffer_put_cstring(&buffer,
buffer_put_cstring(&buffer,
PAM_MSG_MEMBER(msg, i, msg));
ssh_msg_send(ctxt->pam_csock,
PAM_MSG_MEMBER(msg, i, msg_style), &buffer);
if (ssh_msg_send(ctxt->pam_csock,
PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1)
goto fail;
break;
case PAM_TEXT_INFO:
buffer_put_cstring(&buffer,
buffer_put_cstring(&buffer,
PAM_MSG_MEMBER(msg, i, msg));
ssh_msg_send(ctxt->pam_csock,
PAM_MSG_MEMBER(msg, i, msg_style), &buffer);
if (ssh_msg_send(ctxt->pam_csock,
PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1)
goto fail;
break;
default:
goto fail;
@ -216,10 +324,14 @@ sshpam_thread(void *ctxtp)
Buffer buffer;
struct pam_conv sshpam_conv;
#ifndef USE_POSIX_THREADS
extern char **environ;
char **env_from_pam;
u_int i;
const char *pam_user;
pam_get_item(sshpam_handle, PAM_USER, (const void **)&pam_user);
setproctitle("%s [pam]", pam_user);
environ[0] = NULL;
#endif
sshpam_conv.conv = sshpam_thread_conv;
@ -233,7 +345,43 @@ sshpam_thread(void *ctxtp)
sshpam_err = pam_authenticate(sshpam_handle, 0);
if (sshpam_err != PAM_SUCCESS)
goto auth_fail;
if (compat20) {
if (!do_pam_account())
goto auth_fail;
if (*force_pwchange) {
sshpam_err = pam_chauthtok(sshpam_handle,
PAM_CHANGE_EXPIRED_AUTHTOK);
if (sshpam_err != PAM_SUCCESS)
goto auth_fail;
pam_password_change_required(0);
}
}
buffer_put_cstring(&buffer, "OK");
#ifndef USE_POSIX_THREADS
/* Export variables set by do_pam_account */
buffer_put_int(&buffer, sshpam_account_status);
buffer_put_int(&buffer, *force_pwchange);
/* Export any environment strings set in child */
for(i = 0; environ[i] != NULL; i++)
; /* Count */
buffer_put_int(&buffer, i);
for(i = 0; environ[i] != NULL; i++)
buffer_put_cstring(&buffer, environ[i]);
/* Export any environment strings set by PAM in child */
env_from_pam = pam_getenvlist(sshpam_handle);
for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++)
; /* Count */
buffer_put_int(&buffer, i);
for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++)
buffer_put_cstring(&buffer, env_from_pam[i]);
#endif /* USE_POSIX_THREADS */
/* XXX - can't do much about an error here */
ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer);
buffer_free(&buffer);
pthread_exit(NULL);
@ -241,37 +389,43 @@ sshpam_thread(void *ctxtp)
auth_fail:
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);
buffer_free(&buffer);
pthread_exit(NULL);
return (NULL); /* Avoid warning for non-pthread case */
}
static void
sshpam_thread_cleanup(void *ctxtp)
void
sshpam_thread_cleanup(void)
{
struct pam_ctxt *ctxt = ctxtp;
struct pam_ctxt *ctxt = cleanup_ctxt;
pthread_cancel(ctxt->pam_thread);
pthread_join(ctxt->pam_thread, NULL);
close(ctxt->pam_psock);
close(ctxt->pam_csock);
debug3("PAM: %s entering", __func__);
if (ctxt != NULL && ctxt->pam_thread != 0) {
pthread_cancel(ctxt->pam_thread);
pthread_join(ctxt->pam_thread, NULL);
close(ctxt->pam_psock);
close(ctxt->pam_csock);
memset(ctxt, 0, sizeof(*ctxt));
cleanup_ctxt = NULL;
}
}
static int
sshpam_null_conv(int n, const struct pam_message **msg,
struct pam_response **resp, void *data)
{
debug3("PAM: %s entering, %d messages", __func__, n);
return (PAM_CONV_ERR);
}
static struct pam_conv null_conv = { sshpam_null_conv, NULL };
static void
sshpam_cleanup(void *arg)
void
sshpam_cleanup(void)
{
(void)arg;
debug("PAM: cleanup");
if (sshpam_handle == NULL)
return;
@ -284,7 +438,7 @@ sshpam_cleanup(void *arg)
pam_close_session(sshpam_handle, PAM_SILENT);
sshpam_session_open = 0;
}
sshpam_authenticated = sshpam_new_authtok_reqd = 0;
sshpam_authenticated = 0;
pam_end(sshpam_handle, sshpam_err);
sshpam_handle = NULL;
}
@ -302,7 +456,6 @@ sshpam_init(const char *user)
PAM_USER, (const void **)&pam_user);
if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0)
return (0);
fatal_remove_cleanup(sshpam_cleanup, NULL);
pam_end(sshpam_handle, sshpam_err);
sshpam_handle = NULL;
}
@ -323,11 +476,11 @@ sshpam_init(const char *user)
return (-1);
}
#ifdef PAM_TTY_KLUDGE
/*
* Some silly PAM modules (e.g. pam_time) require a TTY to operate.
* sshd doesn't set the tty until too late in the auth process and
/*
* Some silly PAM modules (e.g. pam_time) require a TTY to operate.
* sshd doesn't set the tty until too late in the auth process and
* may not even set one (for tty-less connections)
*/
*/
debug("PAM: setting PAM_TTY to \"ssh\"");
sshpam_err = pam_set_item(sshpam_handle, PAM_TTY, "ssh");
if (sshpam_err != PAM_SUCCESS) {
@ -336,7 +489,6 @@ sshpam_init(const char *user)
return (-1);
}
#endif
fatal_add_cleanup(sshpam_cleanup, NULL);
return (0);
}
@ -346,6 +498,7 @@ sshpam_init_ctx(Authctxt *authctxt)
struct pam_ctxt *ctxt;
int socks[2];
debug3("PAM: %s entering", __func__);
/* Refuse to start if we don't have PAM enabled */
if (!options.use_pam)
return NULL;
@ -357,7 +510,9 @@ sshpam_init_ctx(Authctxt *authctxt)
}
ctxt = xmalloc(sizeof *ctxt);
ctxt->pam_done = 0;
memset(ctxt, 0, sizeof(*ctxt));
force_pwchange = &(authctxt->force_pwchange);
/* Start the authentication thread */
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, socks) == -1) {
@ -375,7 +530,7 @@ sshpam_init_ctx(Authctxt *authctxt)
xfree(ctxt);
return (NULL);
}
fatal_add_cleanup(sshpam_thread_cleanup, ctxt);
cleanup_ctxt = ctxt;
return (ctxt);
}
@ -390,6 +545,7 @@ sshpam_query(void *ctx, char **name, char **info,
char *msg;
size_t len;
debug3("PAM: %s entering", __func__);
buffer_init(&buffer);
*name = xstrdup("");
*info = xstrdup("");
@ -413,26 +569,23 @@ sshpam_query(void *ctx, char **name, char **info,
case PAM_ERROR_MSG:
case PAM_TEXT_INFO:
/* accumulate messages */
len = plen + strlen(msg) + 1;
len = plen + strlen(msg) + 2;
**prompts = xrealloc(**prompts, len);
plen += snprintf(**prompts + plen, len, "%s", msg);
plen += snprintf(**prompts + plen, len, "%s\n", msg);
xfree(msg);
break;
case PAM_SUCCESS:
case PAM_AUTH_ERR:
if (**prompts != NULL) {
/* drain any accumulated messages */
#if 0 /* XXX - not compatible with privsep */
packet_start(SSH2_MSG_USERAUTH_BANNER);
packet_put_cstring(**prompts);
packet_put_cstring("");
packet_send();
packet_write_wait();
#endif
debug("PAM: %s", **prompts);
buffer_append(&loginmsg, **prompts,
strlen(**prompts));
xfree(**prompts);
**prompts = NULL;
}
if (type == PAM_SUCCESS) {
import_environments(&buffer);
*num = 0;
**echo_on = 0;
ctxt->pam_done = 1;
@ -440,6 +593,7 @@ sshpam_query(void *ctx, char **name, char **info,
return (0);
}
error("PAM: %s", msg);
/* FALLTHROUGH */
default:
*num = 0;
**echo_on = 0;
@ -458,7 +612,7 @@ sshpam_respond(void *ctx, u_int num, char **resp)
Buffer buffer;
struct pam_ctxt *ctxt = ctx;
debug2("PAM: %s", __func__);
debug2("PAM: %s entering, %d responses", __func__, num);
switch (ctxt->pam_done) {
case 1:
sshpam_authenticated = 1;
@ -474,7 +628,10 @@ sshpam_respond(void *ctx, u_int num, char **resp)
}
buffer_init(&buffer);
buffer_put_cstring(&buffer, *resp);
ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer);
if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer) == -1) {
buffer_free(&buffer);
return (-1);
}
buffer_free(&buffer);
return (1);
}
@ -484,8 +641,8 @@ sshpam_free_ctx(void *ctxtp)
{
struct pam_ctxt *ctxt = ctxtp;
fatal_remove_cleanup(sshpam_thread_cleanup, ctxt);
sshpam_thread_cleanup(ctxtp);
debug3("PAM: %s entering", __func__);
sshpam_thread_cleanup();
xfree(ctxt);
/*
* We don't call sshpam_cleanup() here because we may need the PAM
@ -527,44 +684,28 @@ start_pam(const char *user)
void
finish_pam(void)
{
fatal_remove_cleanup(sshpam_cleanup, NULL);
sshpam_cleanup(NULL);
sshpam_cleanup();
}
u_int
do_pam_account(void)
{
if (sshpam_account_status != -1)
return (sshpam_account_status);
sshpam_err = pam_acct_mgmt(sshpam_handle, 0);
debug3("%s: pam_acct_mgmt = %d", __func__, sshpam_err);
debug3("PAM: %s pam_acct_mgmt = %d", __func__, sshpam_err);
if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD)
return (0);
if (sshpam_err == PAM_NEW_AUTHTOK_REQD) {
sshpam_new_authtok_reqd = 1;
/* Prevent forwardings until password changed */
no_port_forwarding_flag |= 2;
no_agent_forwarding_flag |= 2;
no_x11_forwarding_flag |= 2;
if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) {
sshpam_account_status = 0;
return (sshpam_account_status);
}
return (1);
}
if (sshpam_err == PAM_NEW_AUTHTOK_REQD)
pam_password_change_required(1);
void
do_pam_session(void)
{
sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
(const void *)&null_conv);
if (sshpam_err != PAM_SUCCESS)
fatal("PAM: failed to set PAM_CONV: %s",
pam_strerror(sshpam_handle, sshpam_err));
sshpam_err = pam_open_session(sshpam_handle, 0);
if (sshpam_err != PAM_SUCCESS)
fatal("PAM: pam_open_session(): %s",
pam_strerror(sshpam_handle, sshpam_err));
sshpam_session_open = 1;
sshpam_account_status = 1;
return (sshpam_account_status);
}
void
@ -606,23 +747,19 @@ do_pam_setcred(int init)
pam_strerror(sshpam_handle, sshpam_err));
}
int
is_pam_password_change_required(void)
{
return (sshpam_new_authtok_reqd);
}
static int
pam_chauthtok_conv(int n, const struct pam_message **msg,
pam_tty_conv(int n, const struct pam_message **msg,
struct pam_response **resp, void *data)
{
char input[PAM_MAX_MSG_SIZE];
struct pam_response *reply;
int i;
debug3("PAM: %s called with %d messages", __func__, n);
*resp = NULL;
if (n <= 0 || n > PAM_MAX_NUM_MSG)
if (n <= 0 || n > PAM_MAX_NUM_MSG || !isatty(STDIN_FILENO))
return (PAM_CONV_ERR);
if ((reply = malloc(n * sizeof(*reply))) == NULL)
@ -633,19 +770,19 @@ pam_chauthtok_conv(int n, const struct pam_message **msg,
switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
case PAM_PROMPT_ECHO_OFF:
reply[i].resp =
read_passphrase(PAM_MSG_MEMBER(msg, i, msg),
read_passphrase(PAM_MSG_MEMBER(msg, i, msg),
RP_ALLOW_STDIN);
reply[i].resp_retcode = PAM_SUCCESS;
break;
case PAM_PROMPT_ECHO_ON:
fputs(PAM_MSG_MEMBER(msg, i, msg), stderr);
fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg));
fgets(input, sizeof input, stdin);
reply[i].resp = xstrdup(input);
reply[i].resp_retcode = PAM_SUCCESS;
break;
case PAM_ERROR_MSG:
case PAM_TEXT_INFO:
fputs(PAM_MSG_MEMBER(msg, i, msg), stderr);
fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg));
reply[i].resp_retcode = PAM_SUCCESS;
break;
default:
@ -664,6 +801,8 @@ pam_chauthtok_conv(int n, const struct pam_message **msg,
return (PAM_CONV_ERR);
}
static struct pam_conv tty_conv = { pam_tty_conv, NULL };
/*
* XXX this should be done in the authentication phase, but ssh1 doesn't
* support that
@ -671,15 +810,10 @@ pam_chauthtok_conv(int n, const struct pam_message **msg,
void
do_pam_chauthtok(void)
{
struct pam_conv pam_conv;
pam_conv.conv = pam_chauthtok_conv;
pam_conv.appdata_ptr = NULL;
if (use_privsep)
fatal("Password expired (unable to change with privsep)");
sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
(const void *)&pam_conv);
(const void *)&tty_conv);
if (sshpam_err != PAM_SUCCESS)
fatal("PAM: failed to set PAM_CONV: %s",
pam_strerror(sshpam_handle, sshpam_err));
@ -690,17 +824,77 @@ do_pam_chauthtok(void)
pam_strerror(sshpam_handle, sshpam_err));
}
/*
static int
pam_store_conv(int n, const struct pam_message **msg,
struct pam_response **resp, void *data)
{
struct pam_response *reply;
int i;
size_t len;
debug3("PAM: %s called with %d messages", __func__, n);
*resp = NULL;
if (n <= 0 || n > PAM_MAX_NUM_MSG)
return (PAM_CONV_ERR);
if ((reply = malloc(n * sizeof(*reply))) == NULL)
return (PAM_CONV_ERR);
memset(reply, 0, n * sizeof(*reply));
for (i = 0; i < n; ++i) {
switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
case PAM_ERROR_MSG:
case PAM_TEXT_INFO:
len = strlen(PAM_MSG_MEMBER(msg, i, msg));
buffer_append(&loginmsg, PAM_MSG_MEMBER(msg, i, msg), len);
buffer_append(&loginmsg, "\n", 1 );
reply[i].resp_retcode = PAM_SUCCESS;
break;
default:
goto fail;
}
}
*resp = reply;
return (PAM_SUCCESS);
fail:
for(i = 0; i < n; i++) {
if (reply[i].resp != NULL)
xfree(reply[i].resp);
}
xfree(reply);
return (PAM_CONV_ERR);
}
static struct pam_conv store_conv = { pam_store_conv, NULL };
void
do_pam_session(void)
{
debug3("PAM: opening session");
sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
(const void *)&store_conv);
if (sshpam_err != PAM_SUCCESS)
fatal("PAM: failed to set PAM_CONV: %s",
pam_strerror(sshpam_handle, sshpam_err));
sshpam_err = pam_open_session(sshpam_handle, 0);
if (sshpam_err != PAM_SUCCESS)
fatal("PAM: pam_open_session(): %s",
pam_strerror(sshpam_handle, sshpam_err));
sshpam_session_open = 1;
}
/*
* Set a PAM environment string. We need to do this so that the session
* modules can handle things like Kerberos/GSI credentials that appear
* during the ssh authentication process.
*/
int
do_pam_putenv(char *name, char *value)
do_pam_putenv(char *name, char *value)
{
int ret = 1;
#ifdef HAVE_PAM_PUTENV
#ifdef HAVE_PAM_PUTENV
char *compound;
size_t len;
@ -715,21 +909,16 @@ do_pam_putenv(char *name, char *value)
return (ret);
}
void
print_pam_messages(void)
char **
fetch_pam_child_environment(void)
{
/* XXX */
return sshpam_env;
}
char **
fetch_pam_environment(void)
{
#ifdef HAVE_PAM_GETENVLIST
debug("PAM: retrieving environment");
return (pam_getenvlist(sshpam_handle));
#else
return (NULL);
#endif
}
void

View File

@ -1,4 +1,4 @@
/* $Id: auth-pam.h,v 1.21 2003/09/02 13:18:53 djm Exp $ */
/* $Id: auth-pam.h,v 1.24 2004/02/10 02:23:29 dtucker Exp $ */
/* $FreeBSD$ */
/*
@ -38,11 +38,12 @@ u_int do_pam_account(void);
void do_pam_session(void);
void do_pam_set_tty(const char *);
void do_pam_setcred(int );
int is_pam_password_change_required(void);
void do_pam_chauthtok(void);
int do_pam_putenv(char *, char *);
void print_pam_messages(void);
char ** fetch_pam_environment(void);
char ** fetch_pam_child_environment(void);
void free_pam_environment(char **);
void sshpam_thread_cleanup(void);
void sshpam_cleanup(void);
#endif /* USE_PAM */

View File

@ -36,20 +36,25 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth-passwd.c,v 1.29 2003/08/26 09:58:43 markus Exp $");
RCSID("$OpenBSD: auth-passwd.c,v 1.31 2004/01/30 09:48:57 markus Exp $");
RCSID("$FreeBSD$");
#include "packet.h"
#include "log.h"
#include "servconf.h"
#include "auth.h"
#ifdef WITH_AIXAUTHENTICATE
# include "buffer.h"
# include "canohost.h"
extern Buffer loginmsg;
#endif
#include "auth-options.h"
extern ServerOptions options;
int sys_auth_passwd(Authctxt *, const char *);
void
disable_forwarding(void)
{
no_port_forwarding_flag = 1;
no_agent_forwarding_flag = 1;
no_x11_forwarding_flag = 1;
}
/*
* Tries to authenticate the user using password. Returns true if
@ -60,29 +65,31 @@ auth_password(Authctxt *authctxt, const char *password)
{
struct passwd * pw = authctxt->pw;
int ok = authctxt->valid;
static int expire_checked = 0;
/* deny if no user. */
if (pw == NULL)
return 0;
#ifndef HAVE_CYGWIN
if (pw && pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)
if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)
ok = 0;
#endif
if (*password == '\0' && options.permit_empty_passwd == 0)
return 0;
#if defined(HAVE_OSF_SIA)
/*
* XXX: any reason this is before krb? could be moved to
* sys_auth_passwd()? -dt
*/
return auth_sia_password(authctxt, password) && ok;
#else
# ifdef KRB5
#endif
#ifdef KRB5
if (options.kerberos_authentication == 1) {
int ret = auth_krb5_password(authctxt, password);
if (ret == 1 || ret == 0)
return ret && ok;
/* Fall back to ordinary passwd authentication. */
}
# endif
# ifdef HAVE_CYGWIN
#endif
#ifdef HAVE_CYGWIN
if (is_winnt) {
HANDLE hToken = cygwin_logon_user(pw, password);
@ -91,74 +98,60 @@ auth_password(Authctxt *authctxt, const char *password)
cygwin_set_impersonation_token(hToken);
return ok;
}
# endif
# ifdef WITH_AIXAUTHENTICATE
{
char *authmsg = NULL;
int reenter = 1;
int authsuccess = 0;
if (authenticate(pw->pw_name, password, &reenter,
&authmsg) == 0 && ok) {
char *msg;
char *host =
(char *)get_canonical_hostname(options.use_dns);
authsuccess = 1;
aix_remove_embedded_newlines(authmsg);
debug3("AIX/authenticate succeeded for user %s: %.100s",
pw->pw_name, authmsg);
/* No pty yet, so just label the line as "ssh" */
aix_setauthdb(authctxt->user);
if (loginsuccess(authctxt->user, host, "ssh",
&msg) == 0) {
if (msg != NULL) {
debug("%s: msg %s", __func__, msg);
buffer_append(&loginmsg, msg,
strlen(msg));
xfree(msg);
}
}
} else {
debug3("AIX/authenticate failed for user %s: %.100s",
pw->pw_name, authmsg);
#endif
#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
if (!expire_checked) {
expire_checked = 1;
if (auth_shadow_pwexpired(authctxt)) {
disable_forwarding();
authctxt->force_pwchange = 1;
}
if (authmsg != NULL)
xfree(authmsg);
return authsuccess;
}
# endif
# ifdef BSD_AUTH
if (auth_userokay(pw->pw_name, authctxt->style, "auth-ssh",
(char *)password) == 0)
return 0;
else
return ok;
# else
{
#endif
return (sys_auth_passwd(authctxt, password) && ok);
}
#ifdef BSD_AUTH
int
sys_auth_passwd(Authctxt *authctxt, const char *password)
{
struct passwd *pw = authctxt->pw;
auth_session_t *as;
as = auth_usercheck(pw->pw_name, authctxt->style, "auth-ssh",
(char *)password);
if (auth_getstate(as) & AUTH_PWEXPIRED) {
auth_close(as);
disable_forwarding();
authctxt->force_pwchange = 1;
return (1);
} else {
return (auth_close(as));
}
}
#elif !defined(CUSTOM_SYS_AUTH_PASSWD)
int
sys_auth_passwd(Authctxt *authctxt, const char *password)
{
struct passwd *pw = authctxt->pw;
char *encrypted_password;
/* Just use the supplied fake password if authctxt is invalid */
char *pw_password = authctxt->valid ? shadow_pw(pw) : pw->pw_passwd;
/* Check for users with no password. */
if (strcmp(pw_password, "") == 0 && strcmp(password, "") == 0)
return ok;
else {
/* Encrypt the candidate password using the proper salt. */
char *encrypted_password = xcrypt(password,
(pw_password[0] && pw_password[1]) ? pw_password : "xx");
return (1);
/*
* Authentication is accepted if the encrypted passwords
* are identical.
*/
return (strcmp(encrypted_password, pw_password) == 0) && ok;
}
/* Encrypt the candidate password using the proper salt. */
encrypted_password = xcrypt(password,
(pw_password[0] && pw_password[1]) ? pw_password : "xx");
}
# endif
#endif /* !HAVE_OSF_SIA */
/*
* Authentication is accepted if the encrypted passwords
* are identical.
*/
return (strcmp(encrypted_password, pw_password) == 0);
}
#endif

View File

@ -13,7 +13,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth-rh-rsa.c,v 1.36 2003/06/02 09:17:34 markus Exp $");
RCSID("$OpenBSD: auth-rh-rsa.c,v 1.37 2003/11/04 08:54:09 djm Exp $");
#include "packet.h"
#include "uidswap.h"
@ -52,14 +52,15 @@ auth_rhosts_rsa_key_allowed(struct passwd *pw, char *cuser, char *chost,
* its host key. Returns true if authentication succeeds.
*/
int
auth_rhosts_rsa(struct passwd *pw, char *cuser, Key *client_host_key)
auth_rhosts_rsa(Authctxt *authctxt, char *cuser, Key *client_host_key)
{
char *chost;
struct passwd *pw = authctxt->pw;
debug("Trying rhosts with RSA host authentication for client user %.100s",
cuser);
if (pw == NULL || client_host_key == NULL ||
if (!authctxt->valid || client_host_key == NULL ||
client_host_key->rsa == NULL)
return 0;

View File

@ -14,7 +14,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth-rsa.c,v 1.57 2003/04/08 20:21:28 itojun Exp $");
RCSID("$OpenBSD: auth-rsa.c,v 1.58 2003/11/04 08:54:09 djm Exp $");
#include <openssl/rsa.h>
#include <openssl/md5.h>
@ -284,13 +284,14 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
* successful. This may exit if there is a serious protocol violation.
*/
int
auth_rsa(struct passwd *pw, BIGNUM *client_n)
auth_rsa(Authctxt *authctxt, BIGNUM *client_n)
{
Key *key;
char *fp;
struct passwd *pw = authctxt->pw;
/* no user given */
if (pw == NULL)
if (!authctxt->valid)
return 0;
if (!PRIVSEP(auth_rsa_key_allowed(pw, client_n, &key))) {

View File

@ -23,15 +23,15 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth.c,v 1.49 2003/08/26 09:58:43 markus Exp $");
RCSID("$OpenBSD: auth.c,v 1.51 2003/11/21 11:57:02 djm Exp $");
RCSID("$FreeBSD$");
#ifdef HAVE_LOGIN_H
#include <login.h>
#endif
#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
#ifdef USE_SHADOW
#include <shadow.h>
#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */
#endif
#ifdef HAVE_LIBGEN_H
#include <libgen.h>
@ -77,7 +77,7 @@ allowed_user(struct passwd * pw)
const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL;
char *shell;
int i;
#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
#ifdef USE_SHADOW
struct spwd *spw = NULL;
#endif
@ -85,53 +85,24 @@ allowed_user(struct passwd * pw)
if (!pw || !pw->pw_name)
return 0;
#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
#ifdef USE_SHADOW
if (!options.use_pam)
spw = getspnam(pw->pw_name);
#ifdef HAS_SHADOW_EXPIRE
#define DAY (24L * 60 * 60) /* 1 day in seconds */
if (!options.use_pam && spw != NULL) {
time_t today;
today = time(NULL) / DAY;
debug3("allowed_user: today %d sp_expire %d sp_lstchg %d"
" sp_max %d", (int)today, (int)spw->sp_expire,
(int)spw->sp_lstchg, (int)spw->sp_max);
/*
* We assume account and password expiration occurs the
* day after the day specified.
*/
if (spw->sp_expire != -1 && today > spw->sp_expire) {
logit("Account %.100s has expired", pw->pw_name);
return 0;
}
if (spw->sp_lstchg == 0) {
logit("User %.100s password has expired (root forced)",
pw->pw_name);
return 0;
}
if (spw->sp_max != -1 &&
today > spw->sp_lstchg + spw->sp_max) {
logit("User %.100s password has expired (password aged)",
pw->pw_name);
return 0;
}
}
if (!options.use_pam && spw != NULL && auth_shadow_acctexpired(spw))
return 0;
#endif /* HAS_SHADOW_EXPIRE */
#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */
#endif /* USE_SHADOW */
/* grab passwd field for locked account check */
#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
/* grab passwd field for locked account check */
#ifdef USE_SHADOW
if (spw != NULL)
passwd = spw->sp_pwdp;
#else
passwd = pw->pw_passwd;
#endif
/* check for locked account */
/* check for locked account */
if (!options.use_pam && passwd && *passwd) {
int locked = 0;
@ -243,7 +214,7 @@ allowed_user(struct passwd * pw)
if ((pw->pw_uid != 0) && (geteuid() == 0)) {
char *msg;
if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &msg) != 0) {
if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &msg) != 0) {
int loginrestrict_errno = errno;
if (msg && *msg) {
@ -253,7 +224,7 @@ allowed_user(struct passwd * pw)
pw->pw_name, msg);
}
/* Don't fail if /etc/nologin set */
if (!(loginrestrict_errno == EPERM &&
if (!(loginrestrict_errno == EPERM &&
stat(_PATH_NOLOGIN, &st) == 0))
return 0;
}
@ -264,14 +235,6 @@ allowed_user(struct passwd * pw)
return 1;
}
Authctxt *
authctxt_new(void)
{
Authctxt *authctxt = xmalloc(sizeof(*authctxt));
memset(authctxt, 0, sizeof(*authctxt));
return authctxt;
}
void
auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
{
@ -599,7 +562,7 @@ fakepw(void)
memset(&fake, 0, sizeof(fake));
fake.pw_name = "NOUSER";
fake.pw_passwd =
"$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK";
"$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK";
fake.pw_gecos = "NOUSER";
fake.pw_uid = -1;
fake.pw_gid = -1;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: auth.h,v 1.46 2003/08/28 12:54:34 markus Exp $ */
/* $OpenBSD: auth.h,v 1.49 2004/01/30 09:48:57 markus Exp $ */
/* $FreeBSD$ */
/*
@ -53,6 +53,7 @@ struct Authctxt {
int valid; /* user exists and is allowed to login */
int attempt;
int failures;
int force_pwchange;
char *user; /* username sent by the client */
char *service;
struct passwd *pw; /* set if 'valid' */
@ -103,9 +104,9 @@ int auth_rhosts(struct passwd *, const char *);
int
auth_rhosts2(struct passwd *, const char *, const char *, const char *);
int auth_rhosts_rsa(struct passwd *, char *, Key *);
int auth_rhosts_rsa(Authctxt *, char *, Key *);
int auth_password(Authctxt *, const char *);
int auth_rsa(struct passwd *, BIGNUM *);
int auth_rsa(Authctxt *, BIGNUM *);
int auth_rsa_challenge_dialog(Key *);
BIGNUM *auth_rsa_generate_challenge(Key *);
int auth_rsa_verify_response(Key *, BIGNUM *, u_char[]);
@ -119,15 +120,21 @@ int user_key_allowed(struct passwd *, Key *);
int auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *);
int auth_krb5_tgt(Authctxt *authctxt, krb5_data *tgt);
int auth_krb5_password(Authctxt *authctxt, const char *password);
void krb5_cleanup_proc(void *authctxt);
void krb5_cleanup_proc(Authctxt *authctxt);
#endif /* KRB5 */
#if defined(USE_SHADOW) && defined(HAS_SHADOW_EXPIRE)
#include <shadow.h>
int auth_shadow_acctexpired(struct spwd *);
int auth_shadow_pwexpired(Authctxt *);
#endif
#include "auth-pam.h"
void disable_forwarding(void);
Authctxt *do_authentication(void);
Authctxt *do_authentication2(void);
void do_authentication(Authctxt *);
void do_authentication2(Authctxt *);
Authctxt *authctxt_new(void);
void auth_log(Authctxt *, int, char *, char *);
void userauth_finish(Authctxt *, int, char *);
int auth_root_allowed(char *);
@ -150,8 +157,6 @@ char *get_challenge(Authctxt *);
int verify_response(Authctxt *, const char *);
void abandon_challenge_response(Authctxt *);
struct passwd * auth_get_user(void);
char *expand_filename(const char *, struct passwd *);
char *authorized_keys_file(struct passwd *);
char *authorized_keys_file2(struct passwd *);

View File

@ -10,7 +10,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth1.c,v 1.52 2003/08/28 12:54:34 markus Exp $");
RCSID("$OpenBSD: auth1.c,v 1.55 2003/11/08 16:02:40 jakob Exp $");
RCSID("$FreeBSD$");
#include "xmalloc.h"
@ -140,7 +140,7 @@ do_authloop(Authctxt *authctxt)
BN_num_bits(client_host_key->rsa->n), bits);
packet_check_eom();
authenticated = auth_rhosts_rsa(pw, client_user,
authenticated = auth_rhosts_rsa(authctxt, client_user,
client_host_key);
key_free(client_host_key);
@ -157,7 +157,7 @@ do_authloop(Authctxt *authctxt)
fatal("do_authloop: BN_new failed");
packet_get_bignum(n);
packet_check_eom();
authenticated = auth_rsa(pw, n);
authenticated = auth_rsa(authctxt, n);
BN_clear_free(n);
break;
@ -236,7 +236,7 @@ do_authloop(Authctxt *authctxt)
if (authenticated &&
!check_nt_auth(type == SSH_CMSG_AUTH_PASSWORD, pw)) {
packet_disconnect("Authentication rejected for uid %d.",
pw == NULL ? -1 : pw->pw_uid);
pw == NULL ? -1 : pw->pw_uid);
authenticated = 0;
}
#else
@ -247,7 +247,7 @@ do_authloop(Authctxt *authctxt)
#endif
#ifdef USE_PAM
if (options.use_pam && authenticated &&
if (options.use_pam && authenticated &&
!PRIVSEP(do_pam_account()))
authenticated = 0;
#endif
@ -276,10 +276,9 @@ do_authloop(Authctxt *authctxt)
* Performs authentication of an incoming connection. Session key has already
* been exchanged and encryption is enabled.
*/
Authctxt *
do_authentication(void)
void
do_authentication(Authctxt *authctxt)
{
Authctxt *authctxt;
u_int ulen;
char *user, *style = NULL;
@ -293,7 +292,6 @@ do_authentication(void)
if ((style = strchr(user, ':')) != NULL)
*style++ = '\0';
authctxt = authctxt_new();
authctxt->user = user;
authctxt->style = style;
@ -333,6 +331,4 @@ do_authentication(void)
packet_start(SSH_SMSG_SUCCESS);
packet_send();
packet_write_wait();
return (authctxt);
}

View File

@ -23,7 +23,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: auth2.c,v 1.102 2003/08/26 09:58:43 markus Exp $");
RCSID("$OpenBSD: auth2.c,v 1.104 2003/11/04 08:54:09 djm Exp $");
RCSID("$FreeBSD$");
#include "canohost.h"
@ -47,8 +47,6 @@ extern ServerOptions options;
extern u_char *session_id2;
extern u_int session_id2_len;
Authctxt *x_authctxt = NULL;
/* methods */
extern Authmethod method_none;
@ -81,19 +79,14 @@ static void input_userauth_request(int, u_int32_t, void *);
static Authmethod *authmethod_lookup(const char *);
static char *authmethods_get(void);
int user_key_allowed(struct passwd *, Key *);
int hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
/*
* loop until authctxt->success == TRUE
*/
Authctxt *
do_authentication2(void)
void
do_authentication2(Authctxt *authctxt)
{
Authctxt *authctxt = authctxt_new();
x_authctxt = authctxt; /*XXX*/
/* challenge-response is implemented via keyboard interactive */
if (options.challenge_response_authentication)
options.kbd_interactive_authentication = 1;
@ -101,8 +94,6 @@ do_authentication2(void)
dispatch_init(&dispatch_protocol_error);
dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt);
return (authctxt);
}
static void
@ -294,14 +285,6 @@ userauth_finish(Authctxt *authctxt, int authenticated, char *method)
}
}
/* get current user */
struct passwd*
auth_get_user(void)
{
return (x_authctxt != NULL && x_authctxt->valid) ? x_authctxt->pw : NULL;
}
#define DELIM ","
static char *

View File

@ -35,7 +35,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: authfd.c,v 1.61 2003/06/28 16:23:06 deraadt Exp $");
RCSID("$OpenBSD: authfd.c,v 1.63 2003/11/21 11:57:03 djm Exp $");
#include <openssl/evp.h>
@ -114,7 +114,8 @@ ssh_get_authentication_socket(void)
static int
ssh_request_reply(AuthenticationConnection *auth, Buffer *request, Buffer *reply)
{
int l, len;
int l;
u_int len;
char buf[1024];
/* Get the length of the message, and format it in the buffer. */
@ -147,7 +148,7 @@ ssh_request_reply(AuthenticationConnection *auth, Buffer *request, Buffer *reply
/* Extract the length, and check it for sanity. */
len = GET_32BIT(buf);
if (len > 256 * 1024)
fatal("Authentication response too long: %d", len);
fatal("Authentication response too long: %u", len);
/* Read the rest of the response in to the buffer. */
buffer_clear(reply);
@ -292,7 +293,7 @@ ssh_get_num_identities(AuthenticationConnection *auth, int version)
/* Get the number of entries in the response and check it for sanity. */
auth->howmany = buffer_get_int(&auth->identities);
if (auth->howmany > 1024)
if ((u_int)auth->howmany > 1024)
fatal("Too many identities in authentication reply: %d",
auth->howmany);
@ -589,7 +590,7 @@ ssh_remove_identity(AuthenticationConnection *auth, Key *key)
}
int
ssh_update_card(AuthenticationConnection *auth, int add,
ssh_update_card(AuthenticationConnection *auth, int add,
const char *reader_id, const char *pin, u_int life, u_int confirm)
{
Buffer msg;
@ -606,7 +607,7 @@ ssh_update_card(AuthenticationConnection *auth, int add,
buffer_put_char(&msg, type);
buffer_put_cstring(&msg, reader_id);
buffer_put_cstring(&msg, pin);
if (constrained) {
if (life != 0) {
buffer_put_char(&msg, SSH_AGENT_CONSTRAIN_LIFETIME);

View File

@ -36,7 +36,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: authfile.c,v 1.54 2003/05/24 09:30:39 djm Exp $");
RCSID("$OpenBSD: authfile.c,v 1.55 2003/09/18 07:56:05 markus Exp $");
#include <openssl/err.h>
#include <openssl/evp.h>
@ -143,6 +143,7 @@ key_save_private_rsa1(Key *key, const char *filename, const char *passphrase,
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
if (fd < 0) {
error("open %s failed: %s.", filename, strerror(errno));
buffer_free(&encrypted);
return 0;
}
if (write(fd, buffer_ptr(&encrypted), buffer_len(&encrypted)) !=

View File

@ -37,7 +37,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: bufaux.c,v 1.29 2003/04/08 20:21:28 itojun Exp $");
RCSID("$OpenBSD: bufaux.c,v 1.32 2004/02/23 15:12:46 markus Exp $");
RCSID("$FreeBSD$");
#include <openssl/bn.h>
@ -51,7 +51,7 @@ RCSID("$FreeBSD$");
* by (bits+7)/8 bytes of binary data, msb first.
*/
void
buffer_put_bignum(Buffer *buffer, BIGNUM *value)
buffer_put_bignum(Buffer *buffer, const BIGNUM *value)
{
int bits = BN_num_bits(value);
int bin_size = (bits + 7) / 8;
@ -81,7 +81,7 @@ buffer_put_bignum(Buffer *buffer, BIGNUM *value)
void
buffer_get_bignum(Buffer *buffer, BIGNUM *value)
{
int bits, bytes;
u_int bits, bytes;
u_char buf[2], *bin;
/* Get the number for bits. */
@ -102,48 +102,49 @@ buffer_get_bignum(Buffer *buffer, BIGNUM *value)
* Stores an BIGNUM in the buffer in SSH2 format.
*/
void
buffer_put_bignum2(Buffer *buffer, BIGNUM *value)
buffer_put_bignum2(Buffer *buffer, const BIGNUM *value)
{
int bytes = BN_num_bytes(value) + 1;
u_char *buf = xmalloc(bytes);
u_int bytes;
u_char *buf;
int oi;
int hasnohigh = 0;
u_int hasnohigh = 0;
if (BN_is_zero(value)) {
buffer_put_int(buffer, 0);
return;
}
if (value->neg)
fatal("buffer_put_bignum2: negative numbers not supported");
bytes = BN_num_bytes(value) + 1; /* extra padding byte */
if (bytes < 2)
fatal("buffer_put_bignum2: BN too small");
buf = xmalloc(bytes);
buf[0] = '\0';
/* Get the value of in binary */
oi = BN_bn2bin(value, buf+1);
if (oi != bytes-1)
fatal("buffer_put_bignum: BN_bn2bin() failed: oi %d != bin_size %d",
oi, bytes);
fatal("buffer_put_bignum2: BN_bn2bin() failed: "
"oi %d != bin_size %d", oi, bytes);
hasnohigh = (buf[1] & 0x80) ? 0 : 1;
if (value->neg) {
/**XXX should be two's-complement */
int i, carry;
u_char *uc = buf;
logit("negativ!");
for (i = bytes-1, carry = 1; i>=0; i--) {
uc[i] ^= 0xff;
if (carry)
carry = !++uc[i];
}
}
buffer_put_string(buffer, buf+hasnohigh, bytes-hasnohigh);
memset(buf, 0, bytes);
xfree(buf);
}
/* XXX does not handle negative BNs */
void
buffer_get_bignum2(Buffer *buffer, BIGNUM *value)
{
u_int len;
u_char *bin = buffer_get_string(buffer, &len);
if (len > 0 && (bin[0] & 0x80))
fatal("buffer_get_bignum2: negative numbers not supported");
if (len > 8 * 1024)
fatal("buffer_get_bignum2: cannot handle BN of size %d", len);
BN_bin2bn(bin, len, value);
xfree(bin);
}
/*
* Returns integers from the buffer (msb first).
*/

View File

@ -12,7 +12,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: canohost.c,v 1.37 2003/06/02 09:17:34 markus Exp $");
RCSID("$OpenBSD: canohost.c,v 1.38 2003/09/23 20:17:11 markus Exp $");
#include "packet.h"
#include "xmalloc.h"
@ -20,6 +20,7 @@ RCSID("$OpenBSD: canohost.c,v 1.37 2003/06/02 09:17:34 markus Exp $");
#include "canohost.h"
static void check_ip_options(int, char *);
static void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *);
/*
* Return the canonical name of the host at the other end of the socket. The
@ -40,31 +41,11 @@ get_remote_hostname(int socket, int use_dns)
memset(&from, 0, sizeof(from));
if (getpeername(socket, (struct sockaddr *)&from, &fromlen) < 0) {
debug("getpeername failed: %.100s", strerror(errno));
fatal_cleanup();
cleanup_exit(255);
}
#ifdef IPV4_IN_IPV6
if (from.ss_family == AF_INET6) {
struct sockaddr_in6 *from6 = (struct sockaddr_in6 *)&from;
/* Detect IPv4 in IPv6 mapped address and convert it to */
/* plain (AF_INET) IPv4 address */
if (IN6_IS_ADDR_V4MAPPED(&from6->sin6_addr)) {
struct sockaddr_in *from4 = (struct sockaddr_in *)&from;
struct in_addr addr;
u_int16_t port;
ipv64_normalise_mapped(&from, &fromlen);
memcpy(&addr, ((char *)&from6->sin6_addr) + 12, sizeof(addr));
port = from6->sin6_port;
memset(&from, 0, sizeof(from));
from4->sin_family = AF_INET;
fromlen = sizeof(*from4);
memcpy(&from4->sin_addr, &addr, sizeof(addr));
from4->sin_port = port;
}
}
#endif
if (from.ss_family == AF_INET6)
fromlen = sizeof(struct sockaddr_in6);
@ -185,6 +166,31 @@ check_ip_options(int socket, char *ipaddr)
#endif /* IP_OPTIONS */
}
static void
ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len)
{
struct sockaddr_in6 *a6 = (struct sockaddr_in6 *)addr;
struct sockaddr_in *a4 = (struct sockaddr_in *)addr;
struct in_addr inaddr;
u_int16_t port;
if (addr->ss_family != AF_INET6 ||
!IN6_IS_ADDR_V4MAPPED(&a6->sin6_addr))
return;
debug3("Normalising mapped IPv4 in IPv6 address");
memcpy(&inaddr, ((char *)&a6->sin6_addr) + 12, sizeof(inaddr));
port = a6->sin6_port;
memset(addr, 0, sizeof(*a4));
a4->sin_family = AF_INET;
*len = sizeof(*a4);
memcpy(&a4->sin_addr, &inaddr, sizeof(inaddr));
a4->sin_port = port;
}
/*
* Return the canonical name of the host in the other side of the current
* connection. The host name is cached, so it is efficient to call this
@ -296,7 +302,7 @@ get_remote_ipaddr(void)
canonical_host_ip =
get_peer_ipaddr(packet_get_connection_in());
if (canonical_host_ip == NULL)
fatal_cleanup();
cleanup_exit(255);
} else {
/* If not on socket, return UNKNOWN. */
canonical_host_ip = xstrdup("UNKNOWN");
@ -336,7 +342,7 @@ get_sock_port(int sock, int local)
} else {
if (getpeername(sock, (struct sockaddr *)&from, &fromlen) < 0) {
debug("getpeername failed: %.100s", strerror(errno));
fatal_cleanup();
cleanup_exit(255);
}
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: channels.h,v 1.70 2002/06/24 14:33:27 markus Exp $ */
/* $OpenBSD: channels.h,v 1.71 2003/09/23 20:41:11 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -214,7 +214,6 @@ void deny_input_open(int, u_int32_t, void *);
/* agent forwarding */
void auth_request_forwarding(void);
void auth_input_open_request(int, u_int32_t, void *);
/* channel close */

View File

@ -35,7 +35,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: cipher.c,v 1.65 2003/05/17 04:27:52 markus Exp $");
RCSID("$OpenBSD: cipher.c,v 1.68 2004/01/23 19:26:33 hshoexer Exp $");
#include "xmalloc.h"
#include "log.h"
@ -52,6 +52,17 @@ RCSID("$OpenBSD: cipher.c,v 1.65 2003/05/17 04:27:52 markus Exp $");
extern const EVP_CIPHER *evp_rijndael(void);
extern void ssh_rijndael_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
#endif
#if !defined(EVP_CTRL_SET_ACSS_MODE)
# if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
extern const EVP_CIPHER *evp_acss(void);
# define EVP_acss evp_acss
# define EVP_CTRL_SET_ACSS_MODE xxx /* used below */
# else
# define EVP_acss NULL /* Don't try to support ACSS on older OpenSSL */
# endif /* (OPENSSL_VERSION_NUMBER >= 0x00906000L) */
#endif /* !defined(EVP_CTRL_SET_ACSS_MODE) */
extern const EVP_CIPHER *evp_ssh1_bf(void);
extern const EVP_CIPHER *evp_ssh1_3des(void);
extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
@ -87,31 +98,33 @@ struct Cipher {
{ "rijndael-cbc@lysator.liu.se",
SSH_CIPHER_SSH2, 16, 32, EVP_aes_256_cbc },
#endif
#if OPENSSL_VERSION_NUMBER >= 0x00906000L
#if OPENSSL_VERSION_NUMBER >= 0x00905000L
{ "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, evp_aes_128_ctr },
{ "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, evp_aes_128_ctr },
{ "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, evp_aes_128_ctr },
#endif
#if defined(EVP_CTRL_SET_ACSS_MODE)
{ "acss@openssh.org", SSH_CIPHER_SSH2, 16, 5, EVP_acss },
#endif
{ NULL, SSH_CIPHER_ILLEGAL, 0, 0, NULL }
};
/*--*/
u_int
cipher_blocksize(Cipher *c)
cipher_blocksize(const Cipher *c)
{
return (c->block_size);
}
u_int
cipher_keylen(Cipher *c)
cipher_keylen(const Cipher *c)
{
return (c->key_len);
}
u_int
cipher_get_number(Cipher *c)
cipher_get_number(const Cipher *c)
{
return (c->number);
}
@ -311,7 +324,7 @@ cipher_set_key_string(CipherContext *cc, Cipher *cipher,
*/
int
cipher_get_keyiv_len(CipherContext *cc)
cipher_get_keyiv_len(const CipherContext *cc)
{
Cipher *c = cc->cipher;
int ivlen;
@ -397,12 +410,12 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv)
#endif
int
cipher_get_keycontext(CipherContext *cc, u_char *dat)
cipher_get_keycontext(const CipherContext *cc, u_char *dat)
{
Cipher *c = cc->cipher;
int plen = 0;
if (c->evptype == EVP_rc4) {
if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) {
plen = EVP_X_STATE_LEN(cc->evp);
if (dat == NULL)
return (plen);
@ -417,7 +430,7 @@ cipher_set_keycontext(CipherContext *cc, u_char *dat)
Cipher *c = cc->cipher;
int plen;
if (c->evptype == EVP_rc4) {
if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) {
plen = EVP_X_STATE_LEN(cc->evp);
memcpy(EVP_X_STATE(cc->evp), dat, plen);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: cipher.h,v 1.33 2002/03/18 17:13:15 markus Exp $ */
/* $OpenBSD: cipher.h,v 1.34 2003/11/10 16:23:41 jakob Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -79,13 +79,13 @@ void cipher_init(CipherContext *, Cipher *, const u_char *, u_int,
void cipher_crypt(CipherContext *, u_char *, const u_char *, u_int);
void cipher_cleanup(CipherContext *);
void cipher_set_key_string(CipherContext *, Cipher *, const char *, int);
u_int cipher_blocksize(Cipher *);
u_int cipher_keylen(Cipher *);
u_int cipher_blocksize(const Cipher *);
u_int cipher_keylen(const Cipher *);
u_int cipher_get_number(Cipher *);
u_int cipher_get_number(const Cipher *);
void cipher_get_keyiv(CipherContext *, u_char *, u_int);
void cipher_set_keyiv(CipherContext *, u_char *);
int cipher_get_keyiv_len(CipherContext *);
int cipher_get_keycontext(CipherContext *, u_char *);
int cipher_get_keyiv_len(const CipherContext *);
int cipher_get_keycontext(const CipherContext *, u_char *);
void cipher_set_keycontext(CipherContext *, u_char *);
#endif /* CIPHER_H */

View File

@ -23,7 +23,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: compat.c,v 1.69 2003/08/29 10:03:15 markus Exp $");
RCSID("$OpenBSD: compat.c,v 1.70 2003/11/02 11:01:03 markus Exp $");
RCSID("$FreeBSD$");
#include "buffer.h"
@ -80,11 +80,7 @@ compat_datafellows(const char *version)
{ "OpenSSH_2.5.3*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
{ "OpenSSH_2.*,"
"OpenSSH_3.0*,"
"OpenSSH_3.1*", SSH_BUG_EXTEOF|SSH_BUG_GSSAPI_BER},
{ "OpenSSH_3.2*,"
"OpenSSH_3.3*,"
"OpenSSH_3.4*,"
"OpenSSH_3.5*", SSH_BUG_GSSAPI_BER},
"OpenSSH_3.1*", SSH_BUG_EXTEOF},
{ "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF},
{ "OpenSSH*", 0 },
{ "*MindTerm*", 0 },

View File

@ -1,4 +1,4 @@
/* $OpenBSD: compat.h,v 1.36 2003/08/29 10:03:15 markus Exp $ */
/* $OpenBSD: compat.h,v 1.37 2003/11/02 11:01:03 markus Exp $ */
/*
* Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved.
@ -55,7 +55,6 @@
#define SSH_BUG_EXTEOF 0x00200000
#define SSH_BUG_PROBE 0x00400000
#define SSH_BUG_FIRSTKEX 0x00800000
#define SSH_BUG_GSSAPI_BER 0x01000000
void enable_compat13(void);
void enable_compat20(void);

File diff suppressed because it is too large Load Diff

View File

@ -36,7 +36,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: hostfile.c,v 1.31 2003/04/08 20:21:28 itojun Exp $");
RCSID("$OpenBSD: hostfile.c,v 1.32 2003/11/10 16:23:41 jakob Exp $");
#include "packet.h"
#include "match.h"
@ -72,7 +72,7 @@ hostfile_read_key(char **cpp, u_int *bitsp, Key *ret)
}
static int
hostfile_check_key(int bits, Key *key, const char *host, const char *filename, int linenum)
hostfile_check_key(int bits, const Key *key, const char *host, const char *filename, int linenum)
{
if (key == NULL || key->type != KEY_RSA1 || key->rsa == NULL)
return 1;
@ -98,7 +98,7 @@ hostfile_check_key(int bits, Key *key, const char *host, const char *filename, i
static HostStatus
check_host_in_hostfile_by_key_or_type(const char *filename,
const char *host, Key *key, int keytype, Key *found, int *numret)
const char *host, const Key *key, int keytype, Key *found, int *numret)
{
FILE *f;
char line[8192];
@ -188,7 +188,7 @@ check_host_in_hostfile_by_key_or_type(const char *filename,
}
HostStatus
check_host_in_hostfile(const char *filename, const char *host, Key *key,
check_host_in_hostfile(const char *filename, const char *host, const Key *key,
Key *found, int *numret)
{
if (key == NULL)
@ -211,7 +211,7 @@ lookup_key_in_hostfile_by_type(const char *filename, const char *host,
*/
int
add_host_to_hostfile(const char *filename, const char *host, Key *key)
add_host_to_hostfile(const char *filename, const char *host, const Key *key)
{
FILE *f;
int success = 0;

View File

@ -135,6 +135,12 @@ __RCSID(msg)
#ifdef HAVE_SYS_STRTIO_H
#include <sys/strtio.h> /* for TIOCCBRK on HP-UX */
#endif
#if defined(HAVE_SYS_PTMS_H) && defined(HAVE_DEV_PTMX)
# if defined(HAVE_SYS_STREAM_H)
# include <sys/stream.h> /* reqd for queue_t on Solaris 2.5.1 */
# endif
#include <sys/ptms.h> /* for grantpt() and friends */
#endif
#include <netinet/in_systm.h> /* For typedefs */
#include <netinet/in.h> /* For IPv6 macros */
@ -148,7 +154,11 @@ __RCSID(msg)
# include <rpc/types.h> /* For INADDR_LOOPBACK */
#endif
#ifdef USE_PAM
#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
#endif
#ifdef HAVE_READPASSPHRASE_H
# include <readpassphrase.h>
@ -166,6 +176,11 @@ __RCSID(msg)
# include <libutil.h> /* Openpty on FreeBSD at least */
#endif
#if defined(KRB5) && defined(USE_AFS)
# include <krb5.h>
# include <kafs.h>
#endif
#include <openssl/opensslv.h> /* For OPENSSL_VERSION_NUMBER */
#include "defines.h"

View File

@ -32,7 +32,7 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
RCSID("$OpenBSD: key.c,v 1.54 2003/07/09 13:58:19 avsm Exp $");
RCSID("$OpenBSD: key.c,v 1.55 2003/11/10 16:23:41 jakob Exp $");
#include <openssl/evp.h>
@ -143,8 +143,9 @@ key_free(Key *k)
}
xfree(k);
}
int
key_equal(Key *a, Key *b)
key_equal(const Key *a, const Key *b)
{
if (a == NULL || b == NULL || a->type != b->type)
return 0;
@ -170,7 +171,8 @@ key_equal(Key *a, Key *b)
}
u_char*
key_fingerprint_raw(Key *k, enum fp_type dgst_type, u_int *dgst_raw_length)
key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
u_int *dgst_raw_length)
{
const EVP_MD *md = NULL;
EVP_MD_CTX ctx;
@ -292,7 +294,7 @@ key_fingerprint_bubblebabble(u_char *dgst_raw, u_int dgst_raw_len)
}
char *
key_fingerprint(Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep)
{
char *retval = NULL;
u_char *dgst_raw;
@ -490,7 +492,7 @@ key_read(Key *ret, char **cpp)
}
int
key_write(Key *key, FILE *f)
key_write(const Key *key, FILE *f)
{
int n, success = 0;
u_int len, bits = 0;
@ -522,8 +524,8 @@ key_write(Key *key, FILE *f)
return success;
}
char *
key_type(Key *k)
const char *
key_type(const Key *k)
{
switch (k->type) {
case KEY_RSA1:
@ -539,8 +541,8 @@ key_type(Key *k)
return "unknown";
}
char *
key_ssh_name(Key *k)
const char *
key_ssh_name(const Key *k)
{
switch (k->type) {
case KEY_RSA:
@ -554,7 +556,7 @@ key_ssh_name(Key *k)
}
u_int
key_size(Key *k)
key_size(const Key *k)
{
switch (k->type) {
case KEY_RSA1:
@ -611,7 +613,7 @@ key_generate(int type, u_int bits)
}
Key *
key_from_private(Key *k)
key_from_private(const Key *k)
{
Key *n = NULL;
switch (k->type) {
@ -676,7 +678,7 @@ key_names_valid2(const char *names)
}
Key *
key_from_blob(u_char *blob, u_int blen)
key_from_blob(const u_char *blob, u_int blen)
{
Buffer b;
char *ktype;
@ -726,7 +728,7 @@ key_from_blob(u_char *blob, u_int blen)
}
int
key_to_blob(Key *key, u_char **blobp, u_int *lenp)
key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
{
Buffer b;
int len;
@ -768,9 +770,9 @@ key_to_blob(Key *key, u_char **blobp, u_int *lenp)
int
key_sign(
Key *key,
const Key *key,
u_char **sigp, u_int *lenp,
u_char *data, u_int datalen)
const u_char *data, u_int datalen)
{
switch (key->type) {
case KEY_DSA:
@ -792,9 +794,9 @@ key_sign(
*/
int
key_verify(
Key *key,
u_char *signature, u_int signaturelen,
u_char *data, u_int datalen)
const Key *key,
const u_char *signature, u_int signaturelen,
const u_char *data, u_int datalen)
{
if (signaturelen == 0)
return -1;
@ -815,7 +817,7 @@ key_verify(
/* Converts a private to a public key */
Key *
key_demote(Key *k)
key_demote(const Key *k)
{
Key *pk;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: log.h,v 1.9 2003/04/08 20:21:28 itojun Exp $ */
/* $OpenBSD: log.h,v 1.10 2003/09/23 20:17:11 markus Exp $ */
/* $FreeBSD$ */
/*
@ -70,11 +70,6 @@ void debug(const char *, ...) __attribute__((format(printf, 1, 2)));
void debug2(const char *, ...) __attribute__((format(printf, 1, 2)));
void debug3(const char *, ...) __attribute__((format(printf, 1, 2)));
void fatal_cleanup(void);
void fatal_add_cleanup(void (*) (void *), void *);
void fatal_remove_cleanup(void (*) (void *), void *);
void fatal_remove_all_cleanups(void);
void do_log(LogLevel, const char *, va_list);
void cleanup_exit(int);
#endif

View File

@ -158,7 +158,7 @@
#include "log.h"
#include "atomicio.h"
RCSID("$Id: loginrec.c,v 1.52 2003/07/06 05:20:46 dtucker Exp $");
RCSID("$Id: loginrec.c,v 1.54 2004/02/10 05:49:35 dtucker Exp $");
RCSID("$FreeBSD$");
#ifdef HAVE_UTIL_H
@ -443,7 +443,7 @@ login_write (struct logininfo *li)
int
login_utmp_only(struct logininfo *li)
{
li->type = LTYPE_LOGIN;
li->type = LTYPE_LOGIN;
login_set_current_time(li);
# ifdef USE_UTMP
utmp_write_entry(li);
@ -1185,6 +1185,7 @@ wtmp_get_entry(struct logininfo *li)
static int
wtmpx_write(struct logininfo *li, struct utmpx *utx)
{
#ifndef HAVE_UPDWTMPX
struct stat buf;
int fd, ret = 1;
@ -1204,6 +1205,10 @@ wtmpx_write(struct logininfo *li, struct utmpx *utx)
(void)close(fd);
return ret;
#else
updwtmpx(WTMPX_FILE, utx);
return 1;
#endif
}
@ -1536,7 +1541,7 @@ lastlog_get_entry(struct logininfo *li)
lastlog_populate_entry(li, &last);
return (1);
case -1:
error("%s: Error reading from %s: %s", __func__,
error("%s: Error reading from %s: %s", __func__,
LASTLOG_FILE, strerror(errno));
return (0);
default:

View File

@ -25,7 +25,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: monitor.c,v 1.49 2003/08/28 12:54:34 markus Exp $");
RCSID("$OpenBSD: monitor.c,v 1.55 2004/02/05 05:37:17 dtucker Exp $");
RCSID("$FreeBSD$");
#include <openssl/dh.h>
@ -143,6 +143,7 @@ int mm_answer_pam_free_ctx(int, Buffer *);
int mm_answer_gss_setup_ctx(int, Buffer *);
int mm_answer_gss_accept_ctx(int, Buffer *);
int mm_answer_gss_userok(int, Buffer *);
int mm_answer_gss_checkmic(int, Buffer *);
#endif
static Authctxt *authctxt;
@ -202,6 +203,7 @@ struct mon_table mon_dispatch_proto20[] = {
{MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx},
{MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
{MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
{MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
#endif
{0, 0, NULL}
};
@ -281,14 +283,17 @@ monitor_permit_authentications(int permit)
}
}
Authctxt *
monitor_child_preauth(struct monitor *pmonitor)
void
monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor)
{
struct mon_table *ent;
int authenticated = 0;
debug3("preauth child monitor started");
authctxt = _authctxt;
memset(authctxt, 0, sizeof(*authctxt));
if (compat20) {
mon_dispatch = mon_dispatch_proto20;
@ -301,8 +306,6 @@ monitor_child_preauth(struct monitor *pmonitor)
monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);
}
authctxt = authctxt_new();
/* The first few requests do not require asynchronous access */
while (!authenticated) {
authenticated = monitor_read(pmonitor, mon_dispatch, &ent);
@ -315,11 +318,11 @@ monitor_child_preauth(struct monitor *pmonitor)
authenticated = 0;
#ifdef USE_PAM
/* PAM needs to perform account checks after auth */
if (options.use_pam) {
if (options.use_pam && authenticated) {
Buffer m;
buffer_init(&m);
mm_request_receive_expect(pmonitor->m_sendfd,
mm_request_receive_expect(pmonitor->m_sendfd,
MONITOR_REQ_PAM_ACCOUNT, &m);
authenticated = mm_answer_pam_account(pmonitor->m_sendfd, &m);
buffer_free(&m);
@ -342,8 +345,6 @@ monitor_child_preauth(struct monitor *pmonitor)
__func__, authctxt->user);
mm_get_keystate(pmonitor);
return (authctxt);
}
static void
@ -575,6 +576,7 @@ mm_answer_pwnamallow(int socket, Buffer *m)
if (pwent == NULL) {
buffer_put_char(m, 0);
authctxt->pw = fakepw();
goto out;
}
@ -790,7 +792,7 @@ int
mm_answer_pam_start(int socket, Buffer *m)
{
char *user;
if (!options.use_pam)
fatal("UsePAM not set, but ended up in %s anyway", __func__);
@ -809,7 +811,7 @@ int
mm_answer_pam_account(int socket, Buffer *m)
{
u_int ret;
if (!options.use_pam)
fatal("UsePAM not set, but ended up in %s anyway", __func__);
@ -956,7 +958,7 @@ mm_answer_keyallowed(int socket, Buffer *m)
debug3("%s: key_from_blob: %p", __func__, key);
if (key != NULL && authctxt->pw != NULL) {
if (key != NULL && authctxt->valid) {
switch(type) {
case MM_USERKEY:
allowed = options.pubkey_authentication &&
@ -1194,7 +1196,7 @@ mm_record_login(Session *s, struct passwd *pw)
if (getpeername(packet_get_connection_in(),
(struct sockaddr *) & from, &fromlen) < 0) {
debug("getpeername: %.100s", strerror(errno));
fatal_cleanup();
cleanup_exit(255);
}
}
/* Record that there was a login on that tty from the remote host. */
@ -1209,7 +1211,6 @@ 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);
fatal_remove_cleanup(session_pty_cleanup2, (void *)s);
session_pty_cleanup2(s);
}
s->used = 0;
@ -1234,7 +1235,6 @@ mm_answer_pty(int socket, Buffer *m)
res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
if (res == 0)
goto error;
fatal_add_cleanup(session_pty_cleanup2, (void *)s);
pty_setowner(authctxt->pw, s->tty);
buffer_put_int(m, 1);
@ -1717,6 +1717,7 @@ monitor_init(void)
mon = xmalloc(sizeof(*mon));
mon->m_pid = 0;
monitor_socketpair(pair);
mon->m_recvfd = pair[0];
@ -1793,14 +1794,42 @@ mm_answer_gss_accept_ctx(int socket, Buffer *m)
gss_release_buffer(&minor, &out);
/* Complete - now we can do signing */
if (major==GSS_S_COMPLETE) {
monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
}
return (0);
}
int
mm_answer_gss_checkmic(int socket, Buffer *m)
{
gss_buffer_desc gssbuf, mic;
OM_uint32 ret;
u_int len;
gssbuf.value = buffer_get_string(m, &len);
gssbuf.length = len;
mic.value = buffer_get_string(m, &len);
mic.length = len;
ret = ssh_gssapi_checkmic(gsscontext, &gssbuf, &mic);
xfree(gssbuf.value);
xfree(mic.value);
buffer_clear(m);
buffer_put_int(m, ret);
mm_request_send(socket, MONITOR_ANS_GSSCHECKMIC, m);
if (!GSS_ERROR(ret))
monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
return (0);
}
int
mm_answer_gss_userok(int socket, Buffer *m)
{
@ -1814,7 +1843,7 @@ mm_answer_gss_userok(int socket, Buffer *m)
debug3("%s: sending result %d", __func__, authenticated);
mm_request_send(socket, MONITOR_ANS_GSSUSEROK, m);
auth_method="gssapi";
auth_method="gssapi-with-mic";
/* Monitor loop will terminate if authenticated */
return (authenticated);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: monitor.h,v 1.11 2003/08/28 12:54:34 markus Exp $ */
/* $OpenBSD: monitor.h,v 1.13 2003/11/17 11:06:07 markus Exp $ */
/* $FreeBSD$ */
/*
@ -53,6 +53,7 @@ enum monitor_reqtype {
MONITOR_REQ_GSSSETUP, MONITOR_ANS_GSSSETUP,
MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP,
MONITOR_REQ_GSSUSEROK, MONITOR_ANS_GSSUSEROK,
MONITOR_REQ_GSSCHECKMIC, MONITOR_ANS_GSSCHECKMIC,
MONITOR_REQ_PAM_START,
MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT,
MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX,
@ -77,7 +78,7 @@ void monitor_reinit(struct monitor *);
void monitor_sync(struct monitor *);
struct Authctxt;
struct Authctxt *monitor_child_preauth(struct monitor *);
void monitor_child_preauth(struct Authctxt *, struct monitor *);
void monitor_child_postauth(struct monitor *);
struct mon_table;

View File

@ -25,7 +25,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: monitor_wrap.c,v 1.31 2003/08/28 12:54:34 markus Exp $");
RCSID("$OpenBSD: monitor_wrap.c,v 1.35 2003/11/17 11:06:07 markus Exp $");
RCSID("$FreeBSD$");
#include <openssl/bn.h>
@ -67,6 +67,16 @@ extern struct monitor *pmonitor;
extern Buffer input, output;
extern ServerOptions options;
int
mm_is_monitor(void)
{
/*
* m_pid is only set in the privileged part, and
* points to the unprivileged child.
*/
return (pmonitor && pmonitor->m_pid > 0);
}
void
mm_request_send(int socket, enum monitor_reqtype type, Buffer *m)
{
@ -95,7 +105,7 @@ mm_request_receive(int socket, Buffer *m)
res = atomicio(read, socket, buf, sizeof(buf));
if (res != sizeof(buf)) {
if (res == 0)
fatal_cleanup();
cleanup_exit(255);
fatal("%s: read: %ld", __func__, (long)res);
}
msg_len = GET_32BIT(buf);
@ -215,7 +225,8 @@ mm_getpwnamallow(const char *login)
return (pw);
}
char *mm_auth2_read_banner(void)
char *
mm_auth2_read_banner(void)
{
Buffer m;
char *banner;
@ -226,10 +237,16 @@ char *mm_auth2_read_banner(void)
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m);
buffer_clear(&m);
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTH2_READ_BANNER, &m);
mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_AUTH2_READ_BANNER, &m);
banner = buffer_get_string(&m, NULL);
buffer_free(&m);
/* treat empty banner as missing banner */
if (strlen(banner) == 0) {
xfree(banner);
banner = NULL;
}
return (banner);
}
@ -649,9 +666,8 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
}
void
mm_session_pty_cleanup2(void *session)
mm_session_pty_cleanup2(Session *s)
{
Session *s = session;
Buffer m;
if (s->ttyfd == -1)
@ -700,12 +716,12 @@ mm_do_pam_account(void)
buffer_init(&m);
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m);
mm_request_receive_expect(pmonitor->m_recvfd,
mm_request_receive_expect(pmonitor->m_recvfd,
MONITOR_ANS_PAM_ACCOUNT, &m);
ret = buffer_get_int(&m);
buffer_free(&m);
debug3("%s returning %d", __func__, ret);
return (ret);
@ -1121,6 +1137,25 @@ mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in,
return (major);
}
OM_uint32
mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
{
Buffer m;
OM_uint32 major;
buffer_init(&m);
buffer_put_string(&m, gssbuf->value, gssbuf->length);
buffer_put_string(&m, gssmic->value, gssmic->length);
mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m);
mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC,
&m);
major = buffer_get_int(&m);
buffer_free(&m);
return(major);
}
int
mm_ssh_gssapi_userok(char *user)
{

View File

@ -1,4 +1,4 @@
/* $OpenBSD: monitor_wrap.h,v 1.11 2003/08/28 12:54:34 markus Exp $ */
/* $OpenBSD: monitor_wrap.h,v 1.13 2003/11/17 11:06:07 markus Exp $ */
/* $FreeBSD$ */
/*
@ -41,6 +41,7 @@ struct mm_master;
struct passwd;
struct Authctxt;
int mm_is_monitor(void);
DH *mm_choose_dh(int, int, int);
int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int);
void mm_inform_authserv(char *, char *);
@ -62,6 +63,7 @@ OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **ctxt, gss_OID oid);
OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *ctxt,
gss_buffer_desc *recv, gss_buffer_desc *send, OM_uint32 *flags);
int mm_ssh_gssapi_userok(char *user);
OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
#endif
#ifdef USE_PAM
@ -73,9 +75,10 @@ int mm_sshpam_respond(void *, u_int, char **);
void mm_sshpam_free_ctx(void *);
#endif
struct Session;
void mm_terminate(void);
int mm_pty_allocate(int *, int *, char *, int);
void mm_session_pty_cleanup2(void *);
void mm_session_pty_cleanup2(struct Session *);
/* SSHv1 interfaces */
void mm_ssh1_session_id(u_char *);

View File

@ -1,4 +1,4 @@
/* $Id: fake-rfc2553.h,v 1.6.2.1 2003/09/22 02:09:18 dtucker Exp $ */
/* $Id: fake-rfc2553.h,v 1.8 2004/02/10 02:05:41 dtucker Exp $ */
/* $FreeBSD$ */
/*
@ -134,19 +134,23 @@ struct addrinfo {
#endif /* !HAVE_STRUCT_ADDRINFO */
#ifndef HAVE_GETADDRINFO
#define getaddrinfo(a,b,c,d) (ssh_getaddrinfo(a,b,c,d))
int getaddrinfo(const char *, const char *,
const struct addrinfo *, struct addrinfo **);
#endif /* !HAVE_GETADDRINFO */
#if !defined(HAVE_GAI_STRERROR) && !defined(HAVE_CONST_GAI_STRERROR_PROTO)
#define gai_strerror(a) (ssh_gai_strerror(a))
char *gai_strerror(int);
#endif /* !HAVE_GAI_STRERROR */
#ifndef HAVE_FREEADDRINFO
#define freeaddrinfo(a) (ssh_freeaddrinfo(a))
void freeaddrinfo(struct addrinfo *);
#endif /* !HAVE_FREEADDRINFO */
#ifndef HAVE_GETNAMEINFO
#define getnameinfo(a,b,c,d,e,f,g) (ssh_getnameinfo(a,b,c,d,e,f,g))
int getnameinfo(const struct sockaddr *, size_t, char *, size_t,
char *, size_t, int);
#endif /* !HAVE_GETNAMEINFO */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: pathnames.h,v 1.13 2002/05/23 19:24:30 markus Exp $ */
/* $OpenBSD: pathnames.h,v 1.14 2004/01/30 09:48:57 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -150,6 +150,11 @@
#define _PATH_PRIVSEP_CHROOT_DIR "/var/empty"
#endif
/* for passwd change */
#ifndef _PATH_PASSWD_PROG
#define _PATH_PASSWD_PROG "/usr/bin/passwd"
#endif
#ifndef _PATH_LS
#define _PATH_LS "ls"
#endif

View File

@ -12,7 +12,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: readconf.c,v 1.121 2003/09/01 18:15:50 markus Exp $");
RCSID("$OpenBSD: readconf.c,v 1.127 2003/12/16 15:49:51 markus Exp $");
RCSID("$FreeBSD$");
#include "ssh.h"
@ -79,7 +79,7 @@ RCSID("$FreeBSD$");
RSAAuthentication yes
RhostsRSAAuthentication yes
StrictHostKeyChecking yes
KeepAlives no
TcpKeepAlive no
IdentityFile ~/.ssh/identity
Port 22
EscapeChar ~
@ -90,14 +90,14 @@ RCSID("$FreeBSD$");
typedef enum {
oBadOption,
oForwardAgent, oForwardX11, oGatewayPorts,
oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
oPasswordAuthentication, oRSAAuthentication,
oChallengeResponseAuthentication, oXAuthLocation,
oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts,
oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
@ -106,6 +106,7 @@ typedef enum {
oClearAllForwardings, oNoHostAuthenticationForLocalhost,
oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
oAddressFamily, oGssAuthentication, oGssDelegateCreds,
oServerAliveInterval, oServerAliveCountMax,
oVersionAddendum,
oDeprecated, oUnsupported
} OpCodes;
@ -118,6 +119,7 @@ static struct {
} keywords[] = {
{ "forwardagent", oForwardAgent },
{ "forwardx11", oForwardX11 },
{ "forwardx11trusted", oForwardX11Trusted },
{ "xauthlocation", oXAuthLocation },
{ "gatewayports", oGatewayPorts },
{ "useprivilegedport", oUsePrivilegedPort },
@ -170,7 +172,8 @@ static struct {
{ "stricthostkeychecking", oStrictHostKeyChecking },
{ "compression", oCompression },
{ "compressionlevel", oCompressionLevel },
{ "keepalive", oKeepAlives },
{ "tcpkeepalive", oTCPKeepAlive },
{ "keepalive", oTCPKeepAlive }, /* obsolete */
{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
{ "loglevel", oLogLevel },
{ "dynamicforward", oDynamicForward },
@ -184,15 +187,13 @@ static struct {
#endif
{ "clearallforwardings", oClearAllForwardings },
{ "enablesshkeysign", oEnableSSHKeysign },
#ifdef DNS
{ "verifyhostkeydns", oVerifyHostKeyDNS },
#else
{ "verifyhostkeydns", oUnsupported },
#endif
{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
{ "rekeylimit", oRekeyLimit },
{ "connecttimeout", oConnectTimeout },
{ "addressfamily", oAddressFamily },
{ "serveraliveinterval", oServerAliveInterval },
{ "serveralivecountmax", oServerAliveCountMax },
{ "versionaddendum", oVersionAddendum },
{ NULL, oBadOption }
};
@ -312,7 +313,7 @@ process_config_line(Options *options, const char *host,
/* NOTREACHED */
case oConnectTimeout:
intptr = &options->connection_timeout;
/* parse_time: */
parse_time:
arg = strdelim(&s);
if (!arg || *arg == '\0')
fatal("%s line %d: missing time value.",
@ -345,6 +346,10 @@ process_config_line(Options *options, const char *host,
intptr = &options->forward_x11;
goto parse_flag;
case oForwardX11Trusted:
intptr = &options->forward_x11_trusted;
goto parse_flag;
case oGatewayPorts:
intptr = &options->gateway_ports;
goto parse_flag;
@ -403,10 +408,11 @@ process_config_line(Options *options, const char *host,
case oVerifyHostKeyDNS:
intptr = &options->verify_host_key_dns;
goto parse_flag;
goto parse_yesnoask;
case oStrictHostKeyChecking:
intptr = &options->strict_host_key_checking;
parse_yesnoask:
arg = strdelim(&s);
if (!arg || *arg == '\0')
fatal("%.200s line %d: Missing yes/no/ask argument.",
@ -428,8 +434,8 @@ process_config_line(Options *options, const char *host,
intptr = &options->compression;
goto parse_flag;
case oKeepAlives:
intptr = &options->keepalives;
case oTCPKeepAlive:
intptr = &options->tcp_keep_alive;
goto parse_flag;
case oNoHostAuthenticationForLocalhost:
@ -733,6 +739,14 @@ process_config_line(Options *options, const char *host,
intptr = &options->enable_ssh_keysign;
goto parse_flag;
case oServerAliveInterval:
intptr = &options->server_alive_interval;
goto parse_time;
case oServerAliveCountMax:
intptr = &options->server_alive_count_max;
goto parse_int;
case oVersionAddendum:
ssh_version_set_addendum(strtok(s, "\n"));
do {
@ -816,6 +830,7 @@ initialize_options(Options * options)
memset(options, 'X', sizeof(*options));
options->forward_agent = -1;
options->forward_x11 = -1;
options->forward_x11_trusted = -1;
options->xauth_location = NULL;
options->gateway_ports = -1;
options->use_privileged_port = -1;
@ -833,7 +848,7 @@ initialize_options(Options * options)
options->check_host_ip = -1;
options->strict_host_key_checking = -1;
options->compression = -1;
options->keepalives = -1;
options->tcp_keep_alive = -1;
options->compression_level = -1;
options->port = -1;
options->address_family = -1;
@ -866,6 +881,8 @@ initialize_options(Options * options)
options->no_host_authentication_for_localhost = - 1;
options->rekey_limit = - 1;
options->verify_host_key_dns = -1;
options->server_alive_interval = -1;
options->server_alive_count_max = -1;
}
/*
@ -882,6 +899,8 @@ fill_default_options(Options * options)
options->forward_agent = 0;
if (options->forward_x11 == -1)
options->forward_x11 = 0;
if (options->forward_x11_trusted == -1)
options->forward_x11_trusted = 0;
if (options->xauth_location == NULL)
options->xauth_location = _PATH_XAUTH;
if (options->gateway_ports == -1)
@ -895,7 +914,7 @@ fill_default_options(Options * options)
if (options->challenge_response_authentication == -1)
options->challenge_response_authentication = 1;
if (options->gss_authentication == -1)
options->gss_authentication = 1;
options->gss_authentication = 0;
if (options->gss_deleg_creds == -1)
options->gss_deleg_creds = 0;
if (options->password_authentication == -1)
@ -914,8 +933,8 @@ fill_default_options(Options * options)
options->strict_host_key_checking = 2; /* 2 is default */
if (options->compression == -1)
options->compression = 0;
if (options->keepalives == -1)
options->keepalives = 1;
if (options->tcp_keep_alive == -1)
options->tcp_keep_alive = 1;
if (options->compression_level == -1)
options->compression_level = 6;
if (options->port == -1)
@ -978,6 +997,10 @@ fill_default_options(Options * options)
options->rekey_limit = 0;
if (options->verify_host_key_dns == -1)
options->verify_host_key_dns = 0;
if (options->server_alive_interval == -1)
options->server_alive_interval = 0;
if (options->server_alive_count_max == -1)
options->server_alive_count_max = 3;
/* options->proxy_command should not be set by default */
/* options->user will be set in the main program if appropriate */
/* options->hostname will be set in the main program if appropriate */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: readconf.h,v 1.55 2003/09/01 18:15:50 markus Exp $ */
/* $OpenBSD: readconf.h,v 1.59 2003/12/16 15:49:51 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -30,6 +30,7 @@ typedef struct {
typedef struct {
int forward_agent; /* Forward authentication agent. */
int forward_x11; /* Forward X11 display. */
int forward_x11_trusted; /* Trust Forward X11 display. */
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. */
@ -52,7 +53,7 @@ typedef struct {
int compression; /* Compress packets in both directions. */
int compression_level; /* Compression level 1 (fast) to 9
* (best). */
int keepalives; /* Set SO_KEEPALIVE. */
int tcp_keep_alive; /* Set SO_KEEPALIVE. */
LogLevel log_level; /* Level for logging. */
int port; /* Port to connect. */
@ -60,7 +61,7 @@ typedef struct {
int connection_attempts; /* Max attempts (seconds) before
* giving up */
int connection_timeout; /* Max time (seconds) before
* aborting connection attempt */
* aborting connection attempt */
int number_of_password_prompts; /* Max number of password
* prompts. */
int cipher; /* Cipher to use. */
@ -99,6 +100,8 @@ typedef struct {
int enable_ssh_keysign;
int rekey_limit;
int no_host_authentication_for_localhost;
int server_alive_interval;
int server_alive_count_max;
} Options;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: rijndael.c,v 1.14 2002/07/10 17:53:54 deraadt Exp $ */
/* $OpenBSD: rijndael.c,v 1.15 2003/11/21 11:57:03 djm Exp $ */
/**
* rijndael-alg-fst.c
@ -725,7 +725,7 @@ static const u32 rcon[] = {
* @return the number of rounds for the given cipher key size.
*/
static int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits) {
int i = 0;
int i = 0;
u32 temp;
rk[0] = GETU32(cipherKey );
@ -797,7 +797,7 @@ static int rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int
(Te4[(temp ) & 0xff] & 0x000000ff);
rk[13] = rk[ 5] ^ rk[12];
rk[14] = rk[ 6] ^ rk[13];
rk[15] = rk[ 7] ^ rk[14];
rk[15] = rk[ 7] ^ rk[14];
rk += 8;
}
}
@ -871,50 +871,50 @@ static void rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16
s3 = GETU32(pt + 12) ^ rk[3];
#ifdef FULL_UNROLL
/* round 1: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
/* round 2: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
/* round 2: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
/* round 3: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
/* round 4: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
/* round 4: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
/* round 5: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
/* round 6: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
/* round 6: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
/* round 7: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
/* round 8: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
/* round 8: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
/* round 9: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
if (Nr > 10) {
/* round 10: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
@ -1187,33 +1187,33 @@ static void rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16
* apply last round and
* map cipher state to byte array block:
*/
s0 =
(Td4[(t0 >> 24) ] & 0xff000000) ^
(Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t1 ) & 0xff] & 0x000000ff) ^
rk[0];
s0 =
(Td4[(t0 >> 24) ] & 0xff000000) ^
(Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t1 ) & 0xff] & 0x000000ff) ^
rk[0];
PUTU32(pt , s0);
s1 =
(Td4[(t1 >> 24) ] & 0xff000000) ^
(Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t2 ) & 0xff] & 0x000000ff) ^
rk[1];
s1 =
(Td4[(t1 >> 24) ] & 0xff000000) ^
(Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t2 ) & 0xff] & 0x000000ff) ^
rk[1];
PUTU32(pt + 4, s1);
s2 =
(Td4[(t2 >> 24) ] & 0xff000000) ^
(Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t3 ) & 0xff] & 0x000000ff) ^
rk[2];
s2 =
(Td4[(t2 >> 24) ] & 0xff000000) ^
(Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t3 ) & 0xff] & 0x000000ff) ^
rk[2];
PUTU32(pt + 8, s2);
s3 =
(Td4[(t3 >> 24) ] & 0xff000000) ^
(Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t0 ) & 0xff] & 0x000000ff) ^
rk[3];
s3 =
(Td4[(t3 >> 24) ] & 0xff000000) ^
(Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t0 ) & 0xff] & 0x000000ff) ^
rk[3];
PUTU32(pt + 12, s3);
}

View File

@ -71,7 +71,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: scp.c,v 1.108 2003/07/18 01:54:25 deraadt Exp $");
RCSID("$OpenBSD: scp.c,v 1.113 2003/11/23 23:21:21 djm Exp $");
#include "xmalloc.h"
#include "atomicio.h"
@ -92,7 +92,7 @@ void bwlimit(int);
arglist args;
/* Bandwidth limit */
off_t limitbw = 0;
off_t limit_rate = 0;
/* Name of current file being transferred. */
char *curfile;
@ -257,7 +257,7 @@ main(int argc, char **argv)
speed = strtod(optarg, &endp);
if (speed <= 0 || *endp != '\0')
usage();
limitbw = speed * 1024;
limit_rate = speed * 1024;
break;
case 'p':
pflag = 1;
@ -273,6 +273,7 @@ main(int argc, char **argv)
verbose_mode = 1;
break;
case 'q':
addargs(&args, "-q");
showprogress = 0;
break;
@ -426,7 +427,8 @@ toremote(char *targ, int argc, char **argv)
}
if (verbose_mode)
fprintf(stderr, "Executing: %s\n", bp);
(void) system(bp);
if (system(bp) != 0)
errs = 1;
(void) xfree(bp);
} else { /* local to remote */
if (remin == -1) {
@ -587,7 +589,7 @@ next: (void) close(fd);
haderr = result >= 0 ? EIO : errno;
statbytes += result;
}
if (limitbw)
if (limit_rate)
bwlimit(amt);
}
if (showprogress)
@ -679,7 +681,7 @@ bwlimit(int amount)
return;
lamt *= 8;
wait = (double)1000000L * lamt / limitbw;
wait = (double)1000000L * lamt / limit_rate;
bwstart.tv_sec = wait / 1000000L;
bwstart.tv_usec = wait % 1000000L;
@ -905,8 +907,8 @@ bad: run_err("%s: %s", np, strerror(errno));
cp += j;
statbytes += j;
} while (amt > 0);
if (limitbw)
if (limit_rate)
bwlimit(4096);
if (count == bp->cnt) {
@ -1018,8 +1020,8 @@ void
usage(void)
{
(void) fprintf(stderr,
"usage: scp [-pqrvBC1246] [-F config] [-S program] [-P port]\n"
" [-c cipher] [-i identity] [-l limit] [-o option]\n"
"usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
" [-l limit] [-o ssh_option] [-P port] [-S program]\n"
" [[user@]host1:]file1 [...] [[user@]host2:]file2\n");
exit(1);
}

View File

@ -10,7 +10,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: servconf.c,v 1.127 2003/09/01 18:15:50 markus Exp $");
RCSID("$OpenBSD: servconf.c,v 1.130 2003/12/23 16:12:10 jakob Exp $");
RCSID("$FreeBSD$");
#include "ssh.h"
@ -62,7 +62,7 @@ initialize_server_options(ServerOptions *options)
options->x11_use_localhost = -1;
options->xauth_location = NULL;
options->strict_modes = -1;
options->keepalives = -1;
options->tcp_keep_alive = -1;
options->log_facility = SYSLOG_FACILITY_NOT_SET;
options->log_level = SYSLOG_LEVEL_NOT_SET;
options->rhosts_rsa_authentication = -1;
@ -73,6 +73,7 @@ initialize_server_options(ServerOptions *options)
options->kerberos_authentication = -1;
options->kerberos_or_local_passwd = -1;
options->kerberos_ticket_cleanup = -1;
options->kerberos_get_afs_token = -1;
options->gss_authentication=-1;
options->gss_cleanup_creds = -1;
options->password_authentication = -1;
@ -158,8 +159,8 @@ fill_default_server_options(ServerOptions *options)
options->xauth_location = _PATH_XAUTH;
if (options->strict_modes == -1)
options->strict_modes = 1;
if (options->keepalives == -1)
options->keepalives = 1;
if (options->tcp_keep_alive == -1)
options->tcp_keep_alive = 1;
if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
options->log_facility = SYSLOG_FACILITY_AUTH;
if (options->log_level == SYSLOG_LEVEL_NOT_SET)
@ -180,6 +181,8 @@ fill_default_server_options(ServerOptions *options)
options->kerberos_or_local_passwd = 1;
if (options->kerberos_ticket_cleanup == -1)
options->kerberos_ticket_cleanup = 1;
if (options->kerberos_get_afs_token == -1)
options->kerberos_get_afs_token = 0;
if (options->gss_authentication == -1)
options->gss_authentication = 0;
if (options->gss_cleanup_creds == -1)
@ -253,11 +256,12 @@ typedef enum {
sPermitRootLogin, sLogFacility, sLogLevel,
sRhostsRSAAuthentication, sRSAAuthentication,
sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
sKerberosGetAFSToken,
sKerberosTgtPassing, sChallengeResponseAuthentication,
sPasswordAuthentication, sKbdInteractiveAuthentication, sListenAddress,
sPrintMotd, sPrintLastLog, sIgnoreRhosts,
sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
sStrictModes, sEmptyPasswd, sKeepAlives,
sStrictModes, sEmptyPasswd, sTCPKeepAlive,
sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
@ -305,19 +309,25 @@ static struct {
{ "kerberosauthentication", sKerberosAuthentication },
{ "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
{ "kerberosticketcleanup", sKerberosTicketCleanup },
#ifdef USE_AFS
{ "kerberosgetafstoken", sKerberosGetAFSToken },
#else
{ "kerberosgetafstoken", sUnsupported },
#endif
#else
{ "kerberosauthentication", sUnsupported },
{ "kerberosorlocalpasswd", sUnsupported },
{ "kerberosticketcleanup", sUnsupported },
{ "kerberosgetafstoken", sUnsupported },
#endif
{ "kerberostgtpassing", sUnsupported },
{ "afstokenpassing", sUnsupported },
#ifdef GSSAPI
{ "gssapiauthentication", sGssAuthentication },
{ "gssapicleanupcreds", sGssCleanupCreds },
{ "gssapicleanupcredentials", sGssCleanupCreds },
#else
{ "gssapiauthentication", sUnsupported },
{ "gssapicleanupcreds", sUnsupported },
{ "gssapicleanupcredentials", sUnsupported },
#endif
{ "passwordauthentication", sPasswordAuthentication },
{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication },
@ -338,7 +348,8 @@ static struct {
{ "permituserenvironment", sPermitUserEnvironment },
{ "uselogin", sUseLogin },
{ "compression", sCompression },
{ "keepalive", sKeepAlives },
{ "tcpkeepalive", sTCPKeepAlive },
{ "keepalive", sTCPKeepAlive }, /* obsolete alias */
{ "allowtcpforwarding", sAllowTcpForwarding },
{ "allowusers", sAllowUsers },
{ "denyusers", sDenyUsers },
@ -634,6 +645,10 @@ process_server_config_line(ServerOptions *options, char *line,
intptr = &options->kerberos_ticket_cleanup;
goto parse_flag;
case sKerberosGetAFSToken:
intptr = &options->kerberos_get_afs_token;
goto parse_flag;
case sGssAuthentication:
intptr = &options->gss_authentication;
goto parse_flag;
@ -682,8 +697,8 @@ process_server_config_line(ServerOptions *options, char *line,
intptr = &options->strict_modes;
goto parse_flag;
case sKeepAlives:
intptr = &options->keepalives;
case sTCPKeepAlive:
intptr = &options->tcp_keep_alive;
goto parse_flag;
case sEmptyPasswd:

View File

@ -1,4 +1,4 @@
/* $OpenBSD: servconf.h,v 1.65 2003/09/01 18:15:50 markus Exp $ */
/* $OpenBSD: servconf.h,v 1.67 2003/12/23 16:12:10 jakob Exp $ */
/* $FreeBSD$ */
/*
@ -59,7 +59,7 @@ typedef struct {
int x11_use_localhost; /* If true, use localhost for fake X11 server. */
char *xauth_location; /* Location of xauth program */
int strict_modes; /* If true, require string home dir modes. */
int keepalives; /* If true, set SO_KEEPALIVE. */
int tcp_keep_alive; /* If true, set SO_KEEPALIVE. */
char *ciphers; /* Supported SSH2 ciphers. */
char *macs; /* Supported SSH2 macs. */
int protocol; /* Supported protocol versions. */
@ -81,6 +81,8 @@ typedef struct {
* /etc/passwd */
int kerberos_ticket_cleanup; /* If true, destroy ticket
* file on logout. */
int kerberos_get_afs_token; /* If true, try to get AFS token if
* authenticated with Kerberos. */
int gss_authentication; /* If true, permit GSSAPI authentication */
int gss_cleanup_creds; /* If true, destroy cred cache on logout */
int password_authentication; /* If true, permit password

View File

@ -35,7 +35,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: serverloop.c,v 1.110 2003/06/24 08:23:46 markus Exp $");
RCSID("$OpenBSD: serverloop.c,v 1.115 2004/01/19 21:25:15 markus Exp $");
#include "xmalloc.h"
#include "packet.h"
@ -60,7 +60,7 @@ extern ServerOptions options;
/* XXX */
extern Kex *xxx_kex;
static Authctxt *xxx_authctxt;
extern Authctxt *the_authctxt;
static Buffer stdin_buffer; /* Buffer for stdin data. */
static Buffer stdout_buffer; /* Buffer for stdout data. */
@ -212,26 +212,23 @@ make_packets_from_stdout_data(void)
static void
client_alive_check(void)
{
static int had_channel = 0;
int id;
id = channel_find_open();
if (id == -1) {
if (!had_channel)
return;
packet_disconnect("No open channels after timeout!");
}
had_channel = 1;
int channel_id;
/* timeout, check to see how many we have had */
if (++client_alive_timeouts > options.client_alive_count_max)
packet_disconnect("Timeout, your session not responding.");
/*
* send a bogus channel request with "wantreply",
* send a bogus global/channel request with "wantreply",
* we should get back a failure
*/
channel_request_start(id, "keepalive@openssh.com", 1);
if ((channel_id = channel_find_open()) == -1) {
packet_start(SSH2_MSG_GLOBAL_REQUEST);
packet_put_cstring("keepalive@openssh.com");
packet_put_char(1); /* boolean: want reply */
} else {
channel_request_start(channel_id, "keepalive@openssh.com", 1);
}
packet_send();
}
@ -355,13 +352,13 @@ process_input(fd_set * readset)
connection_closed = 1;
if (compat20)
return;
fatal_cleanup();
cleanup_exit(255);
} else if (len < 0) {
if (errno != EINTR && errno != EAGAIN) {
verbose("Read error from remote host "
"%.100s: %.100s",
get_remote_ipaddr(), strerror(errno));
fatal_cleanup();
cleanup_exit(255);
}
} else {
/* Buffer any received data. */
@ -756,8 +753,6 @@ server_loop2(Authctxt *authctxt)
max_fd = MAX(connection_in, connection_out);
max_fd = MAX(max_fd, notify_pipe[0]);
xxx_authctxt = authctxt;
server_init_dispatch();
for (;;) {
@ -799,9 +794,9 @@ server_loop2(Authctxt *authctxt)
}
static void
server_input_channel_failure(int type, u_int32_t seq, void *ctxt)
server_input_keep_alive(int type, u_int32_t seq, void *ctxt)
{
debug("Got CHANNEL_FAILURE for keepalive");
debug("Got %d/%u for keepalive", type, seq);
/*
* reset timeout, since we got a sane answer from the client.
* even if this was generated by something other than
@ -810,7 +805,6 @@ server_input_channel_failure(int type, u_int32_t seq, void *ctxt)
client_alive_timeouts = 0;
}
static void
server_input_stdin_data(int type, u_int32_t seq, void *ctxt)
{
@ -856,7 +850,7 @@ server_input_window_size(int type, u_int32_t seq, void *ctxt)
}
static Channel *
server_request_direct_tcpip(char *ctype)
server_request_direct_tcpip(void)
{
Channel *c;
int sock;
@ -878,14 +872,14 @@ server_request_direct_tcpip(char *ctype)
xfree(originator);
if (sock < 0)
return NULL;
c = channel_new(ctype, SSH_CHANNEL_CONNECTING,
c = channel_new("direct-tcpip", SSH_CHANNEL_CONNECTING,
sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT,
CHAN_TCP_PACKET_DEFAULT, 0, "direct-tcpip", 1);
return c;
}
static Channel *
server_request_session(char *ctype)
server_request_session(void)
{
Channel *c;
@ -897,10 +891,10 @@ server_request_session(char *ctype)
* SSH_CHANNEL_LARVAL. Additionally, a callback for handling all
* CHANNEL_REQUEST messages is registered.
*/
c = channel_new(ctype, SSH_CHANNEL_LARVAL,
c = channel_new("session", SSH_CHANNEL_LARVAL,
-1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
0, "server-session", 1);
if (session_open(xxx_authctxt, c->self) != 1) {
if (session_open(the_authctxt, c->self) != 1) {
debug("session open failed, free channel %d", c->self);
channel_free(c);
return NULL;
@ -926,9 +920,9 @@ server_input_channel_open(int type, u_int32_t seq, void *ctxt)
ctype, rchan, rwindow, rmaxpack);
if (strcmp(ctype, "session") == 0) {
c = server_request_session(ctype);
c = server_request_session();
} else if (strcmp(ctype, "direct-tcpip") == 0) {
c = server_request_direct_tcpip(ctype);
c = server_request_direct_tcpip();
}
if (c != NULL) {
debug("server_input_channel_open: confirm %s", ctype);
@ -974,9 +968,9 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt)
char *listen_address;
u_short listen_port;
pw = auth_get_user();
if (pw == NULL)
fatal("server_input_global_request: no user");
pw = the_authctxt->pw;
if (pw == NULL || !the_authctxt->valid)
fatal("server_input_global_request: no/invalid user");
listen_address = packet_get_string(NULL);
listen_port = (u_short)packet_get_int();
debug("server_input_global_request: tcpip-forward listen %s port %d",
@ -1050,7 +1044,9 @@ server_init_dispatch_20(void)
dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust);
dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request);
/* client_alive */
dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &server_input_channel_failure);
dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &server_input_keep_alive);
dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &server_input_keep_alive);
dispatch_set(SSH2_MSG_REQUEST_FAILURE, &server_input_keep_alive);
/* rekeying */
dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
}

View File

@ -33,7 +33,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: session.c,v 1.164 2003/09/18 08:49:45 markus Exp $");
RCSID("$OpenBSD: session.c,v 1.172 2004/01/30 09:48:57 markus Exp $");
RCSID("$FreeBSD$");
#include "ssh.h"
@ -59,6 +59,10 @@ RCSID("$FreeBSD$");
#include "session.h"
#include "monitor_wrap.h"
#if defined(KRB5) && defined(USE_AFS)
#include <kafs.h>
#endif
#ifdef GSSAPI
#include "ssh-gss.h"
#endif
@ -67,7 +71,7 @@ RCSID("$FreeBSD$");
Session *session_new(void);
void session_set_fds(Session *, int, int, int);
void session_pty_cleanup(void *);
void session_pty_cleanup(Session *);
void session_proctitle(Session *);
int session_setup_x11fwd(Session *);
void do_exec_pty(Session *, const char *);
@ -107,6 +111,8 @@ Session sessions[MAX_SESSIONS];
login_cap_t *lc;
#endif
static int is_child = 0;
/* Name and directory of socket for authentication agent forwarding. */
static char *auth_sock_name = NULL;
static char *auth_sock_dir = NULL;
@ -114,10 +120,8 @@ static char *auth_sock_dir = NULL;
/* removes the agent forwarding socket */
static void
auth_sock_cleanup_proc(void *_pw)
auth_sock_cleanup_proc(struct passwd *pw)
{
struct passwd *pw = _pw;
if (auth_sock_name != NULL) {
temporarily_use_uid(pw);
unlink(auth_sock_name);
@ -145,7 +149,7 @@ auth_input_request_forwarding(struct passwd * pw)
/* Allocate a buffer for the socket name, and format the name. */
auth_sock_name = xmalloc(MAXPATHLEN);
auth_sock_dir = xmalloc(MAXPATHLEN);
strlcpy(auth_sock_dir, "/tmp/ssh-XXXXXXXX", MAXPATHLEN);
strlcpy(auth_sock_dir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN);
/* Create private directory for socket */
if (mkdtemp(auth_sock_dir) == NULL) {
@ -161,9 +165,6 @@ auth_input_request_forwarding(struct passwd * pw)
snprintf(auth_sock_name, MAXPATHLEN, "%s/agent.%ld",
auth_sock_dir, (long) getpid());
/* delete agent socket on fatal() */
fatal_add_cleanup(auth_sock_cleanup_proc, pw);
/* Create the socket. */
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0)
@ -181,7 +182,7 @@ auth_input_request_forwarding(struct passwd * pw)
restore_uid();
/* Start listening on the socket. */
if (listen(sock, 5) < 0)
if (listen(sock, SSH_LISTEN_BACKLOG) < 0)
packet_disconnect("listen: %.100s", strerror(errno));
/* Allocate a channel for the authentication agent socket. */
@ -193,6 +194,15 @@ auth_input_request_forwarding(struct passwd * pw)
return 1;
}
static void
display_loginmsg(void)
{
if (buffer_len(&loginmsg) > 0) {
buffer_append(&loginmsg, "\0", 1);
printf("%s\n", (char *)buffer_ptr(&loginmsg));
buffer_clear(&loginmsg);
}
}
void
do_authenticated(Authctxt *authctxt)
@ -208,7 +218,6 @@ do_authenticated(Authctxt *authctxt)
close(startup_pipe);
startup_pipe = -1;
}
/* setup the channel layer */
if (!no_port_forwarding_flag && options.allow_tcp_forwarding)
channel_permit_all_opens();
@ -218,13 +227,7 @@ do_authenticated(Authctxt *authctxt)
else
do_authenticated1(authctxt);
/* remove agent socket */
if (auth_sock_name != NULL)
auth_sock_cleanup_proc(authctxt->pw);
#ifdef KRB5
if (options.kerberos_ticket_cleanup)
krb5_cleanup_proc(authctxt);
#endif
do_cleanup(authctxt);
}
/*
@ -396,17 +399,13 @@ do_exec_no_pty(Session *s, const char *command)
session_proctitle(s);
#if defined(USE_PAM)
if (options.use_pam) {
if (options.use_pam && !use_privsep)
do_pam_setcred(1);
if (is_pam_password_change_required())
packet_disconnect("Password change required but no "
"TTY available");
}
#endif /* USE_PAM */
/* Fork the child. */
if ((pid = fork()) == 0) {
fatal_remove_all_cleanups();
is_child = 1;
/* Child. Reinitialize the log since the pid has changed. */
log_init(__progname, options.log_level, options.log_facility, log_stderr);
@ -526,13 +525,14 @@ do_exec_pty(Session *s, const char *command)
#if defined(USE_PAM)
if (options.use_pam) {
do_pam_set_tty(s->tty);
do_pam_setcred(1);
if (!use_privsep)
do_pam_setcred(1);
}
#endif
/* Fork the child. */
if ((pid = fork()) == 0) {
fatal_remove_all_cleanups();
is_child = 1;
/* Child. Reinitialize the log because the pid has changed. */
log_init(__progname, options.log_level, options.log_facility, log_stderr);
@ -628,7 +628,7 @@ do_pre_login(Session *s)
if (getpeername(packet_get_connection_in(),
(struct sockaddr *) & from, &fromlen) < 0) {
debug("getpeername: %.100s", strerror(errno));
fatal_cleanup();
cleanup_exit(255);
}
}
@ -688,7 +688,7 @@ do_login(Session *s, const char *command)
if (getpeername(packet_get_connection_in(),
(struct sockaddr *) & from, &fromlen) < 0) {
debug("getpeername: %.100s", strerror(errno));
fatal_cleanup();
cleanup_exit(255);
}
}
@ -704,9 +704,10 @@ do_login(Session *s, const char *command)
* If password change is needed, do it now.
* This needs to occur before the ~/.hushlogin check.
*/
if (options.use_pam && is_pam_password_change_required()) {
print_pam_messages();
if (options.use_pam && !use_privsep && s->authctxt->force_pwchange) {
display_loginmsg();
do_pam_chauthtok();
s->authctxt->force_pwchange = 0;
/* XXX - signal [net] parent to enable forwardings */
}
#endif
@ -714,17 +715,7 @@ do_login(Session *s, const char *command)
if (check_quietlogin(s, command))
return;
#ifdef USE_PAM
if (options.use_pam && !is_pam_password_change_required())
print_pam_messages();
#endif /* USE_PAM */
/* display post-login message */
if (buffer_len(&loginmsg) > 0) {
buffer_append(&loginmsg, "\0", 1);
printf("%s\n", (char *)buffer_ptr(&loginmsg));
}
buffer_free(&loginmsg);
display_loginmsg();
#ifndef NO_SSH_LASTLOG
if (options.print_lastlog && s->last_login_time != 0) {
@ -934,7 +925,7 @@ read_etc_default_login(char ***env, u_int *envsize, uid_t uid)
{
char **tmpenv = NULL, *var;
u_int i, tmpenvsize = 0;
mode_t mask;
u_long mask;
/*
* We don't want to copy the whole file to the child's environment,
@ -952,11 +943,11 @@ read_etc_default_login(char ***env, u_int *envsize, uid_t uid)
var = child_get_env(tmpenv, "PATH");
if (var != NULL)
child_set_env(env, envsize, "PATH", var);
if ((var = child_get_env(tmpenv, "UMASK")) != NULL)
if (sscanf(var, "%5lo", &mask) == 1)
umask(mask);
umask((mode_t)mask);
for (i = 0; tmpenv[i] != NULL; i++)
xfree(tmpenv[i]);
xfree(tmpenv);
@ -981,7 +972,7 @@ void copy_environment(char **source, char ***env, u_int *envsize)
debug3("Copy environment: %s=%s", var_name, var_val);
child_set_env(env, envsize, var_name, var_val);
xfree(var_name);
}
}
@ -1015,7 +1006,7 @@ do_setup_env(Session *s, const char *shell)
child_set_env(&env, &envsize, "TZ", getenv("TZ"));
#ifdef GSSAPI
/* Allow any GSSAPI methods that we've used to alter
/* Allow any GSSAPI methods that we've used to alter
* the childs environment as they see fit
*/
ssh_gssapi_do_child(&env, &envsize);
@ -1058,7 +1049,7 @@ do_setup_env(Session *s, const char *shell)
path = child_get_env(env, "PATH");
# endif /* HAVE_ETC_DEFAULT_LOGIN */
if (path == NULL || *path == '\0') {
child_set_env(&env, &envsize, "PATH",
child_set_env(&env, &envsize, "PATH",
s->pw->pw_uid == 0 ?
SUPERUSER_PATH : _PATH_STDPATH);
}
@ -1135,8 +1126,13 @@ do_setup_env(Session *s, const char *shell)
* been set by PAM.
*/
if (options.use_pam) {
char **p = fetch_pam_environment();
char **p;
p = fetch_pam_child_environment();
copy_environment(p, &env, &envsize);
free_pam_environment(p);
p = fetch_pam_environment();
copy_environment(p, &env, &envsize);
free_pam_environment(p);
}
@ -1209,7 +1205,7 @@ do_rc_files(Session *s, const char *shell)
if (debug_flag) {
fprintf(stderr,
"Running %.500s remove %.100s\n",
options.xauth_location, s->auth_display);
options.xauth_location, s->auth_display);
fprintf(stderr,
"%.500s add %.100s %.100s %.100s\n",
options.xauth_location, s->auth_display,
@ -1275,6 +1271,12 @@ do_setusercontext(struct passwd *pw)
# ifdef __bsdi__
setpgid(0, 0);
# endif
# ifdef USE_PAM
if (options.use_pam) {
do_pam_session();
do_pam_setcred(0);
}
# endif /* USE_PAM */
if (setusercontext(lc, pw, pw->pw_uid,
(LOGIN_SETALL & ~(LOGIN_SETENV|LOGIN_SETPATH))) < 0) {
perror("unable to set user context");
@ -1301,7 +1303,7 @@ do_setusercontext(struct passwd *pw)
endgrent();
# ifdef USE_PAM
/*
* PAM credentials may take the form of supplementary groups.
* PAM credentials may take the form of supplementary groups.
* These will have been wiped by the above initgroups() call.
* Reestablish them here.
*/
@ -1328,6 +1330,22 @@ do_setusercontext(struct passwd *pw)
fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
}
static void
do_pwchange(Session *s)
{
fprintf(stderr, "WARNING: Your password has expired.\n");
if (s->ttyfd != -1) {
fprintf(stderr,
"You must change your password now and login again!\n");
execl(_PATH_PASSWD_PROG, "passwd", (char *)NULL);
perror("passwd");
} else {
fprintf(stderr,
"Password change required but no TTY available.\n");
}
exit(1);
}
static void
launch_login(struct passwd *pw, const char *hostname)
{
@ -1349,6 +1367,40 @@ launch_login(struct passwd *pw, const char *hostname)
exit(1);
}
static void
child_close_fds(void)
{
int i;
if (packet_get_connection_in() == packet_get_connection_out())
close(packet_get_connection_in());
else {
close(packet_get_connection_in());
close(packet_get_connection_out());
}
/*
* Close all descriptors related to channels. They will still remain
* open in the parent.
*/
/* XXX better use close-on-exec? -markus */
channel_close_all();
/*
* Close any extra file descriptors. Note that there may still be
* descriptors left by system functions. They will be closed later.
*/
endpwent();
/*
* Close any extra open file descriptors so that we don\'t have them
* hanging around in clients. Note that we want to do this after
* initgroups, because at least on Solaris 2.3 it leaves file
* descriptors open.
*/
for (i = 3; i < 64; i++)
close(i);
}
/*
* Performs common processing for the child, such as setting up the
* environment, closing extra file descriptors, setting the user and group
@ -1362,7 +1414,6 @@ do_child(Session *s, const char *command)
char *argv[10];
const char *shell, *shell0, *hostname = NULL;
struct passwd *pw = s->pw;
u_int i;
#ifdef HAVE_LOGIN_CAP
int lc_requirehome;
#endif
@ -1370,6 +1421,14 @@ do_child(Session *s, const char *command)
/* remove hostkey from the child's memory */
destroy_sensitive_data();
/* Force a password change */
if (s->authctxt->force_pwchange) {
do_setusercontext(pw);
child_close_fds();
do_pwchange(s);
exit(1);
}
/* login(1) is only called if we execute the login shell */
if (options.use_login && command != NULL)
options.use_login = 0;
@ -1420,37 +1479,7 @@ do_child(Session *s, const char *command)
* closed before building the environment, as we call
* get_remote_ipaddr there.
*/
if (packet_get_connection_in() == packet_get_connection_out())
close(packet_get_connection_in());
else {
close(packet_get_connection_in());
close(packet_get_connection_out());
}
/*
* Close all descriptors related to channels. They will still remain
* open in the parent.
*/
/* XXX better use close-on-exec? -markus */
channel_close_all();
#ifdef HAVE_LOGIN_CAP
lc_requirehome = login_getcapbool(lc, "requirehome", 0);
login_close(lc);
#endif
/*
* Close any extra file descriptors. Note that there may still be
* descriptors left by system functions. They will be closed later.
*/
endpwent();
/*
* Close any extra open file descriptors so that we don\'t have them
* hanging around in clients. Note that we want to do this after
* initgroups, because at least on Solaris 2.3 it leaves file
* descriptors open.
*/
for (i = 3; i < 64; i++)
close(i);
child_close_fds();
/*
* Must take new environment into use so that .ssh/rc,
@ -1458,6 +1487,36 @@ do_child(Session *s, const char *command)
*/
environ = env;
#ifdef HAVE_LOGIN_CAP
lc_requirehome = login_getcapbool(lc, "requirehome", 0);
login_close(lc);
#endif
#if defined(KRB5) && defined(USE_AFS)
/*
* At this point, we check to see if AFS is active and if we have
* a valid Kerberos 5 TGT. If so, it seems like a good idea to see
* if we can (and need to) extend the ticket into an AFS token. If
* we don't do this, we run into potential problems if the user's
* home directory is in AFS and it's not world-readable.
*/
if (options.kerberos_get_afs_token && k_hasafs() &&
(s->authctxt->krb5_ctx != NULL)) {
char cell[64];
debug("Getting AFS token");
k_setpag();
if (k_afs_cell_of_file(pw->pw_dir, cell, sizeof(cell)) == 0)
krb5_afslog(s->authctxt->krb5_ctx,
s->authctxt->krb5_fwd_ccache, cell, NULL);
krb5_afslog_home(s->authctxt->krb5_ctx,
s->authctxt->krb5_fwd_ccache, NULL, NULL, pw->pw_dir);
}
#endif
/* Change current directory to the user\'s home directory. */
if (chdir(pw->pw_dir) < 0) {
fprintf(stderr, "Could not chdir to home directory %s: %s\n",
@ -1579,7 +1638,7 @@ session_open(Authctxt *authctxt, int chanid)
}
s->authctxt = authctxt;
s->pw = authctxt->pw;
if (s->pw == NULL)
if (s->pw == NULL || !authctxt->valid)
fatal("no user for session %d", s->self);
debug("session_open: session %d: link with channel %d", s->self, chanid);
s->chanid = chanid;
@ -1701,11 +1760,6 @@ session_pty_req(Session *s)
n_bytes = packet_remaining();
tty_parse_modes(s->ttyfd, &n_bytes);
/*
* Add a cleanup function to clear the utmp entry and record logout
* time in case we call fatal() (e.g., the connection gets closed).
*/
fatal_add_cleanup(session_pty_cleanup, (void *)s);
if (!use_privsep)
pty_setowner(s->pw, s->tty);
@ -1887,10 +1941,8 @@ session_set_fds(Session *s, int fdin, int fdout, int fderr)
* (e.g., due to a dropped connection).
*/
void
session_pty_cleanup2(void *session)
session_pty_cleanup2(Session *s)
{
Session *s = session;
if (s == NULL) {
error("session_pty_cleanup: no session");
return;
@ -1921,9 +1973,9 @@ session_pty_cleanup2(void *session)
}
void
session_pty_cleanup(void *session)
session_pty_cleanup(Session *s)
{
PRIVSEP(session_pty_cleanup2(session));
PRIVSEP(session_pty_cleanup2(s));
}
static char *
@ -1996,10 +2048,8 @@ void
session_close(Session *s)
{
debug("session_close: session %d pid %ld", s->self, (long)s->pid);
if (s->ttyfd != -1) {
fatal_remove_cleanup(session_pty_cleanup, (void *)s);
if (s->ttyfd != -1)
session_pty_cleanup(s);
}
if (s->term)
xfree(s->term);
if (s->display)
@ -2048,10 +2098,8 @@ session_close_by_channel(int id, void *arg)
* delay detach of session, but release pty, since
* the fd's to the child are already closed
*/
if (s->ttyfd != -1) {
fatal_remove_cleanup(session_pty_cleanup, (void *)s);
if (s->ttyfd != -1)
session_pty_cleanup(s);
}
return;
}
/* detach by removing callback */
@ -2086,13 +2134,13 @@ session_tty_list(void)
for (i = 0; i < MAX_SESSIONS; i++) {
Session *s = &sessions[i];
if (s->used && s->ttyfd != -1) {
if (strncmp(s->tty, "/dev/", 5) != 0) {
cp = strrchr(s->tty, '/');
cp = (cp == NULL) ? s->tty : cp + 1;
} else
cp = s->tty + 5;
if (buf[0] != '\0')
strlcat(buf, ",", sizeof buf);
strlcat(buf, cp, sizeof buf);
@ -2192,8 +2240,51 @@ static void
do_authenticated2(Authctxt *authctxt)
{
server_loop2(authctxt);
#if defined(GSSAPI)
if (options.gss_cleanup_creds)
ssh_gssapi_cleanup_creds(NULL);
#endif
}
void
do_cleanup(Authctxt *authctxt)
{
static int called = 0;
debug("do_cleanup");
/* no cleanup if we're in the child for login shell */
if (is_child)
return;
/* avoid double cleanup */
if (called)
return;
called = 1;
if (authctxt == NULL)
return;
#ifdef KRB5
if (options.kerberos_ticket_cleanup &&
authctxt->krb5_ctx)
krb5_cleanup_proc(authctxt);
#endif
#ifdef GSSAPI
if (compat20 && options.gss_cleanup_creds)
ssh_gssapi_cleanup_creds();
#endif
#ifdef USE_PAM
if (options.use_pam) {
sshpam_cleanup();
sshpam_thread_cleanup();
}
#endif
/* remove agent socket */
auth_sock_cleanup_proc(authctxt->pw);
/*
* Cleanup ptys/utmp only if privsep is disabled,
* or if running in monitor.
*/
if (!use_privsep || mm_is_monitor())
session_destroy_all(session_pty_cleanup2);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: session.h,v 1.20 2003/08/22 10:56:09 markus Exp $ */
/* $OpenBSD: session.h,v 1.21 2003/09/23 20:17:11 markus Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@ -56,13 +56,14 @@ struct Session {
};
void do_authenticated(Authctxt *);
void do_cleanup(Authctxt *);
int session_open(Authctxt *, int);
int session_input_channel_req(Channel *, const char *);
void session_close_by_pid(pid_t, int);
void session_close_by_channel(int, void *);
void session_destroy_all(void (*)(Session *));
void session_pty_cleanup2(void *);
void session_pty_cleanup2(Session *);
Session *session_new(void);
Session *session_by_tty(char *);

View File

@ -1,37 +0,0 @@
/* $OpenBSD: sftp-glob.h,v 1.8 2002/09/11 22:41:50 djm Exp $ */
/*
* Copyright (c) 2001,2002 Damien Miller. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* Remote sftp filename globbing */
#ifndef _SFTP_GLOB_H
#define _SFTP_GLOB_H
#include "sftp-client.h"
int remote_glob(struct sftp_conn *, const char *, int,
int (*)(const char *, int), glob_t *);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +0,0 @@
/* $OpenBSD: sftp-int.h,v 1.6 2003/01/08 23:53:26 djm Exp $ */
/*
* Copyright (c) 2001,2002 Damien Miller. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
int interactive_loop(int, int, char *, char *);

View File

@ -35,7 +35,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: ssh-add.c,v 1.68 2003/06/16 10:22:45 markus Exp $");
RCSID("$OpenBSD: ssh-add.c,v 1.69 2003/11/21 11:57:03 djm Exp $");
#include <openssl/evp.h>
@ -169,14 +169,14 @@ add_file(AuthenticationConnection *ac, const char *filename)
}
}
if (ssh_add_identity_constrained(ac, private, comment, lifetime,
confirm)) {
if (ssh_add_identity_constrained(ac, private, comment, lifetime,
confirm)) {
fprintf(stderr, "Identity added: %s (%s)\n", filename, comment);
ret = 0;
if (lifetime != 0)
fprintf(stderr,
"Lifetime set to %d seconds\n", lifetime);
if (confirm != 0)
if (confirm != 0)
fprintf(stderr,
"The user has to confirm each use of the key\n");
} else if (ssh_add_identity(ac, private, comment)) {

View File

@ -35,7 +35,7 @@
#include "includes.h"
#include "openbsd-compat/sys-queue.h"
RCSID("$OpenBSD: ssh-agent.c,v 1.112 2003/09/18 08:49:45 markus Exp $");
RCSID("$OpenBSD: ssh-agent.c,v 1.117 2003/12/02 17:01:15 markus Exp $");
RCSID("$FreeBSD$");
#include <openssl/evp.h>
@ -180,7 +180,7 @@ confirm_key(Identity *id)
p = read_passphrase(prompt, RP_ALLOW_EOF);
if (p != NULL) {
/*
* Accept empty responses and responses consisting
* Accept empty responses and responses consisting
* of the word "yes" as affirmative.
*/
if (*p == '\0' || *p == '\n' || strcasecmp(p, "yes") == 0)
@ -950,7 +950,7 @@ after_select(fd_set *readset, fd_set *writeset)
}
static void
cleanup_socket(void *p)
cleanup_socket(void)
{
if (socket_name[0])
unlink(socket_name);
@ -958,17 +958,17 @@ cleanup_socket(void *p)
rmdir(socket_dir);
}
static void
void
cleanup_exit(int i)
{
cleanup_socket(NULL);
exit(i);
cleanup_socket();
_exit(i);
}
static void
cleanup_handler(int sig)
{
cleanup_socket(NULL);
cleanup_socket();
_exit(2);
}
@ -1102,7 +1102,7 @@ main(int ac, char **av)
if (agentsocket == NULL) {
/* Create private directory for agent socket */
strlcpy(socket_dir, "/tmp/ssh-XXXXXXXX", sizeof socket_dir);
strlcpy(socket_dir, "/tmp/ssh-XXXXXXXXXX", sizeof socket_dir);
if (mkdtemp(socket_dir) == NULL) {
perror("mkdtemp: private socket dir");
exit(1);
@ -1140,7 +1140,7 @@ main(int ac, char **av)
#ifdef HAVE_CYGWIN
umask(prev_mask);
#endif
if (listen(sock, 128) < 0) {
if (listen(sock, SSH_LISTEN_BACKLOG) < 0) {
perror("listen");
cleanup_exit(1);
}
@ -1211,7 +1211,6 @@ main(int ac, char **av)
#endif
skip:
fatal_add_cleanup(cleanup_socket, NULL);
new_socket(AUTH_SOCKET, sock);
if (ac > 0) {
mysignal(SIGALRM, check_parent_exists);

View File

@ -7,7 +7,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: ssh-keyscan.c,v 1.44 2003/06/28 16:23:06 deraadt Exp $");
RCSID("$OpenBSD: ssh-keyscan.c,v 1.46 2003/11/23 23:17:34 djm Exp $");
#include "openbsd-compat/sys-queue.h"
@ -214,13 +214,11 @@ fdlim_get(int hard)
if (getrlimit(RLIMIT_NOFILE, &rlfd) < 0)
return (-1);
if ((hard ? rlfd.rlim_max : rlfd.rlim_cur) == RLIM_INFINITY)
return 10000;
return SSH_SYSFDMAX;
else
return hard ? rlfd.rlim_max : rlfd.rlim_cur;
#elif defined (HAVE_SYSCONF)
return sysconf (_SC_OPEN_MAX);
#else
return 10000;
return SSH_SYSFDMAX;
#endif
}
@ -675,7 +673,7 @@ fatal(const char *fmt,...)
if (nonfatal_fatal)
longjmp(kexjmp, -1);
else
fatal_cleanup();
exit(255);
}
static void

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.175 2003/07/22 13:35:22 markus Exp $
.\" $OpenBSD: ssh.1,v 1.181 2003/12/16 15:49:51 markus Exp $
.\" $FreeBSD$
.Dd September 25, 1999
.Dt SSH 1
@ -44,22 +44,14 @@
.Nd OpenSSH SSH client (remote login program)
.Sh SYNOPSIS
.Nm ssh
.Op Fl l Ar login_name
.Ar hostname | user@hostname
.Op Ar command
.Pp
.Nm ssh
.Bk -words
.Op Fl afgknqstvxACNTVX1246
.Op Fl 1246AaCfgkNnqsTtVvXxY
.Op Fl b Ar bind_address
.Op Fl c Ar cipher_spec
.Op Fl D Ar port
.Op Fl e Ar escape_char
.Op Fl i Ar identity_file
.Op Fl l Ar login_name
.Op Fl m Ar mac_spec
.Op Fl o Ar option
.Op Fl p Ar port
.Op Fl F Ar configfile
.Op Fl i Ar identity_file
.Bk -words
.Oo Fl L Xo
.Sm off
.Ar port :
@ -69,7 +61,12 @@
.Xc
.Oc
.Ek
.Op Fl l Ar login_name
.Op Fl m Ar mac_spec
.Op Fl o Ar option
.Bk -words
.Op Fl p Ar port
.Ek
.Oo Fl R Xo
.Sm off
.Ar port :
@ -78,29 +75,34 @@
.Sm on
.Xc
.Oc
.Op Fl D Ar port
.Ar hostname | user@hostname
.Oo Ar user Ns @ Oc Ns Ar hostname
.Op Ar command
.Ek
.Sh DESCRIPTION
.Nm
(SSH client) is a program for logging into a remote machine and for
executing commands on a remote machine.
It is intended to replace
rlogin and rsh, and provide secure encrypted communications between
It is intended to replace rlogin and rsh,
and provide secure encrypted communications between
two untrusted hosts over an insecure network.
X11 connections and
arbitrary TCP/IP ports can also be forwarded over the secure channel.
X11 connections and arbitrary TCP/IP ports
can also be forwarded over the secure channel.
.Pp
.Nm
connects and logs into the specified
.Ar hostname .
.Ar hostname
(with optional
.Ar user
name).
The user must prove
his/her identity to the remote machine using one of several methods
depending on the protocol version used:
depending on the protocol version used.
.Pp
If
.Ar command
is specified,
.Ar command
is executed on the remote host instead of a login shell.
.Ss SSH protocol version 1
.Pp
First, if the machine the user logs in from is listed in
.Pa /etc/hosts.equiv
or
@ -108,9 +110,9 @@ or
on the remote machine, and the user names are
the same on both sides, the user is immediately permitted to log in.
Second, if
.Pa \&.rhosts
.Pa .rhosts
or
.Pa \&.shosts
.Pa .shosts
exists in the user's home directory on the
remote machine and contains a line containing the name of the client
machine and the name of the user on that machine, the user is
@ -119,9 +121,9 @@ This form of authentication alone is normally not
allowed by the server because it is not secure.
.Pp
The second authentication method is the
.Pa rhosts
.Em rhosts
or
.Pa hosts.equiv
.Em hosts.equiv
method combined with RSA-based host authentication.
It means that if the login would be permitted by
.Pa $HOME/.rhosts ,
@ -136,7 +138,7 @@ and
.Pa $HOME/.ssh/known_hosts
in the
.Sx FILES
section), only then login is permitted.
section), only then is login permitted.
This authentication method closes security holes due to IP
spoofing, DNS spoofing and routing spoofing.
[Note to the administrator:
@ -155,24 +157,23 @@ RSA is one such system.
The idea is that each user creates a public/private
key pair for authentication purposes.
The server knows the public key, and only the user knows the private key.
.Pp
The file
.Pa $HOME/.ssh/authorized_keys
lists the public keys that are permitted for logging
in.
lists the public keys that are permitted for logging in.
When the user logs in, the
.Nm
program tells the server which key pair it would like to use for
authentication.
The server checks if this key is permitted, and if
so, sends the user (actually the
The server checks if this key is permitted, and if so,
sends the user (actually the
.Nm
program running on behalf of the user) a challenge, a random number,
encrypted by the user's public key.
The challenge can only be
decrypted using the proper private key.
The user's client then decrypts the
challenge using the private key, proving that he/she knows the private
key but without disclosing it to the server.
The challenge can only be decrypted using the proper private key.
The user's client then decrypts the challenge using the private key,
proving that he/she knows the private key
but without disclosing it to the server.
.Pp
.Nm
implements the RSA authentication protocol automatically.
@ -180,7 +181,7 @@ The user creates his/her RSA key pair by running
.Xr ssh-keygen 1 .
This stores the private key in
.Pa $HOME/.ssh/identity
and the public key in
and stores the public key in
.Pa $HOME/.ssh/identity.pub
in the user's home directory.
The user should then copy the
@ -194,8 +195,9 @@ file corresponds to the conventional
file, and has one key
per line, though the lines can be very long).
After this, the user can log in without giving the password.
RSA authentication is much
more secure than rhosts authentication.
RSA authentication is much more secure than
.Em rhosts
authentication.
.Pp
The most convenient way to use RSA authentication may be with an
authentication agent.
@ -209,16 +211,14 @@ prompts the user for a password.
The password is sent to the remote
host for checking; however, since all communications are encrypted,
the password cannot be seen by someone listening on the network.
.Pp
.Ss SSH protocol version 2
.Pp
When a user connects using protocol version 2
When a user connects using protocol version 2,
similar authentication methods are available.
Using the default values for
.Cm PreferredAuthentications ,
the client will try to authenticate first using the hostbased method;
if this method fails public key authentication is attempted,
and finally if this method fails keyboard-interactive and
if this method fails, public key authentication is attempted,
and finally if this method fails, keyboard-interactive and
password authentication are tried.
.Pp
The public key method is similar to RSA authentication described
@ -234,8 +234,8 @@ and grants access if both the key is found and the signature is correct.
The session identifier is derived from a shared Diffie-Hellman value
and is only known to the client and the server.
.Pp
If public key authentication fails or is not available a password
can be sent encrypted to the remote host for proving the user's identity.
If public key authentication fails or is not available, a password
can be sent encrypted to the remote host to prove the user's identity.
.Pp
Additionally,
.Nm
@ -246,9 +246,7 @@ Protocol 2 provides additional mechanisms for confidentiality
and integrity (hmac-md5, hmac-sha1).
Note that protocol 1 lacks a strong mechanism for ensuring the
integrity of the connection.
.Pp
.Ss Login session and remote execution
.Pp
When the user's identity has been accepted by the server, the server
either executes the given command, or logs into the machine and gives
the user a normal shell on the remote machine.
@ -258,23 +256,20 @@ the remote command or shell will be automatically encrypted.
If a pseudo-terminal has been allocated (normal login session), the
user may use the escape characters noted below.
.Pp
If no pseudo tty has been allocated, the
session is transparent and can be used to reliably transfer binary
data.
If no pseudo-tty has been allocated,
the session is transparent and can be used to reliably transfer binary data.
On most systems, setting the escape character to
.Dq none
will also make the session transparent even if a tty is used.
.Pp
The session terminates when the command or shell on the remote
machine exits and all X11 and TCP/IP connections have been closed.
The exit status of the remote program is returned as the exit status
of
The exit status of the remote program is returned as the exit status of
.Nm ssh .
.Pp
.Ss Escape Characters
.Pp
When a pseudo terminal has been requested, ssh supports a number of functions
through the use of an escape character.
When a pseudo-terminal has been requested,
.Nm
supports a number of functions through the use of an escape character.
.Pp
A single tilde character can be sent as
.Ic ~~
@ -292,37 +287,37 @@ The supported escapes (assuming the default
are:
.Bl -tag -width Ds
.It Cm ~.
Disconnect
Disconnect.
.It Cm ~^Z
Background ssh
Background
.Nm ssh .
.It Cm ~#
List forwarded connections
List forwarded connections.
.It Cm ~&
Background ssh at logout when waiting for forwarded connection / X11 sessions
to terminate
Background
.Nm
at logout when waiting for forwarded connection / X11 sessions to terminate.
.It Cm ~?
Display a list of escape characters
Display a list of escape characters.
.It Cm ~B
Send a BREAK to the remote system (only useful for SSH protocol version 2
and if the peer supports it)
Send a BREAK to the remote system
(only useful for SSH protocol version 2 and if the peer supports it).
.It Cm ~C
Open command line (only useful for adding port forwardings using the
.Fl L
and
.Fl R
options)
options).
.It Cm ~R
Request rekeying of the connection (only useful for SSH protocol version 2
and if the peer supports it)
Request rekeying of the connection
(only useful for SSH protocol version 2 and if the peer supports it).
.El
.Pp
.Ss X11 and TCP forwarding
.Pp
If the
.Cm ForwardX11
variable is set to
.Dq yes
(or, see the description of the
(or see the description of the
.Fl X
and
.Fl x
@ -344,8 +339,7 @@ The
.Ev DISPLAY
value set by
.Nm
will point to the server machine, but with a display number greater
than zero.
will point to the server machine, but with a display number greater than zero.
This is normal, and happens because
.Nm
creates a
@ -366,7 +360,7 @@ If the
.Cm ForwardAgent
variable is set to
.Dq yes
(or, see the description of the
(or see the description of the
.Fl A
and
.Fl a
@ -378,9 +372,7 @@ Forwarding of arbitrary TCP/IP connections over the secure channel can
be specified either on the command line or in a configuration file.
One possible application of TCP/IP forwarding is a secure connection to an
electronic purse; another is going through firewalls.
.Pp
.Ss Server authentication
.Pp
.Nm
automatically maintains and checks a database containing
identifications for all hosts it has ever been used with.
@ -391,14 +383,12 @@ Additionally, the file
.Pa /etc/ssh/ssh_known_hosts
is automatically checked for known hosts.
Any new hosts are automatically added to the user's file.
If a host's identification
ever changes,
If a host's identification ever changes,
.Nm
warns about this and disables password authentication to prevent a
trojan horse from getting the user's password.
Another purpose of
this mechanism is to prevent man-in-the-middle attacks which could
otherwise be used to circumvent the encryption.
Another purpose of this mechanism is to prevent man-in-the-middle attacks
which could otherwise be used to circumvent the encryption.
The
.Cm StrictHostKeyChecking
option can be used to prevent logins to machines whose
@ -406,8 +396,22 @@ host key is not known or has changed.
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl a
Disables forwarding of the authentication agent connection.
.It Fl 1
Forces
.Nm
to try protocol version 1 only.
.It Fl 2
Forces
.Nm
to try protocol version 2 only.
.It Fl 4
Forces
.Nm
to use IPv4 addresses only.
.It Fl 6
Forces
.Nm
to use IPv6 addresses only.
.It Fl A
Enables forwarding of the authentication agent connection.
This can also be specified on a per-host basis in a configuration file.
@ -419,10 +423,28 @@ can access the local agent through the forwarded connection.
An attacker cannot obtain key material from the agent,
however they can perform operations on the keys that enable them to
authenticate using the identities loaded into the agent.
.It Fl a
Disables forwarding of the authentication agent connection.
.It Fl b Ar bind_address
Specify the interface to transmit from on machines with multiple
interfaces or aliased addresses.
.It Fl c Ar blowfish|3des|des
.It Fl C
Requests compression of all data (including stdin, stdout, stderr, and
data for forwarded X11 and TCP/IP connections).
The compression algorithm is the same used by
.Xr gzip 1 ,
and the
.Dq level
can be controlled by the
.Cm CompressionLevel
option for protocol version 1.
Compression is desirable on modem lines and other
slow connections, but will only slow down things on fast networks.
The default value can be set on a host-by-host basis in the
configuration files; see the
.Cm Compression
option.
.It Fl c Ar blowfish | 3des | des
Selects the cipher to use for encrypting the session.
.Ar 3des
is used by default.
@ -430,7 +452,7 @@ It is believed to be secure.
.Ar 3des
(triple-des) is an encrypt-decrypt-encrypt triple with three different keys.
.Ar blowfish
is a fast block cipher, it appears very secure and is much faster than
is a fast block cipher; it appears very secure and is much faster than
.Ar 3des .
.Ar des
is only supported in the
@ -446,18 +468,41 @@ be specified in order of preference.
See
.Cm Ciphers
for more information.
.It Fl e Ar ch|^ch|none
.It Fl D Ar port
Specifies a local
.Dq dynamic
application-level port forwarding.
This works by allocating a socket to listen to
.Ar port
on the local side, and whenever a connection is made to this port, the
connection is forwarded over the secure channel, and the application
protocol is then used to determine where to connect to from the
remote machine.
Currently the SOCKS4 and SOCKS5 protocols are supported, and
.Nm
will act as a SOCKS server.
Only root can forward privileged ports.
Dynamic port forwardings can also be specified in the configuration file.
.It Fl e Ar ch | ^ch | none
Sets the escape character for sessions with a pty (default:
.Ql ~ ) .
The escape character is only recognized at the beginning of a line.
The escape character followed by a dot
.Pq Ql \&.
closes the connection, followed
by control-Z suspends the connection, and followed by itself sends the
escape character once.
closes the connection;
followed by control-Z suspends the connection;
and followed by itself sends the escape character once.
Setting the character to
.Dq none
disables any escapes and makes the session fully transparent.
.It Fl F Ar configfile
Specifies an alternative per-user configuration file.
If a configuration file is given on the command line,
the system-wide configuration file
.Pq Pa /etc/ssh/ssh_config
will be ignored.
The default for the per-user configuration file is
.Pa $HOME/.ssh/config .
.It Fl f
Requests
.Nm
@ -473,6 +518,12 @@ something like
.Ic ssh -f host xterm .
.It Fl g
Allows remote hosts to connect to local forwarded ports.
.It Fl I Ar smartcard_device
Specifies which smartcard device to use.
The argument is the device
.Nm
should use to communicate with a smartcard used for storing the user's
private RSA key.
.It Fl i Ar identity_file
Selects a file from which the identity (private key) for
RSA or DSA authentication is read.
@ -489,15 +540,33 @@ It is possible to have multiple
.Fl i
options (and multiple identities specified in
configuration files).
.It Fl I Ar smartcard_device
Specifies which smartcard device to use.
The argument is the device
.Nm
should use to communicate with a smartcard used for storing the user's
private RSA key.
.It Fl k
Disables forwarding of Kerberos tickets.
This may also be specified on a per-host basis in the configuration file.
Disables forwarding (delegation) of GSSAPI credentials to the server.
.It Fl L Xo
.Sm off
.Ar port : host : hostport
.Sm on
.Xc
Specifies that the given port on the local (client) host is to be
forwarded to the given host and port on the remote side.
This works by allocating a socket to listen to
.Ar port
on the local side, and whenever a connection is made to this port, the
connection is forwarded over the secure channel, and a connection is
made to
.Ar host
port
.Ar hostport
from the remote machine.
Port forwardings can also be specified in the configuration file.
Only root can forward privileged ports.
IPv6 addresses can be specified with an alternative syntax:
.Sm off
.Xo
.Ar port No / Ar host No /
.Ar hostport .
.Xc
.Sm on
.It Fl l Ar login_name
Specifies the user to log in as on the remote machine.
This also may be specified on a per-host basis in the configuration file.
@ -508,6 +577,10 @@ be specified in order of preference.
See the
.Cm MACs
keyword for more information.
.It Fl N
Do not execute a remote command.
This is useful for just forwarding ports
(protocol version 2 only).
.It Fl n
Redirects stdin from
.Pa /dev/null
@ -528,14 +601,66 @@ program will be put in the background.
needs to ask for a password or passphrase; see also the
.Fl f
option.)
.It Fl N
Do not execute a remote command.
This is useful for just forwarding ports
(protocol version 2 only).
.It Fl o Ar option
Can be used to give options in the format used in the configuration file.
This is useful for specifying options for which there is no separate
command-line flag.
For full details of the options listed below, and their possible values, see
.Xr ssh_config 5 .
.Pp
.Bl -tag -width Ds -offset indent -compact
.It AddressFamily
.It BatchMode
.It BindAddress
.It ChallengeResponseAuthentication
.It CheckHostIP
.It Cipher
.It Ciphers
.It ClearAllForwardings
.It Compression
.It CompressionLevel
.It ConnectionAttempts
.It ConnectionTimeout
.It DynamicForward
.It EscapeChar
.It ForwardAgent
.It ForwardX11
.It ForwardX11Trusted
.It GatewayPorts
.It GlobalKnownHostsFile
.It GSSAPIAuthentication
.It GSSAPIDelegateCredentials
.It Host
.It HostbasedAuthentication
.It HostKeyAlgorithms
.It HostKeyAlias
.It HostName
.It IdentityFile
.It LocalForward
.It LogLevel
.It MACs
.It NoHostAuthenticationForLocalhost
.It NumberOfPasswordPrompts
.It PasswordAuthentication
.It Port
.It PreferredAuthentications
.It Protocol
.It ProxyCommand
.It PubkeyAuthentication
.It RemoteForward
.It RhostsRSAAuthentication
.It RSAAuthentication
.It ServerAliveInterval
.It ServerAliveCountMax
.It SmartcardDevice
.It StrictHostKeyChecking
.It TCPKeepAlive
.It UsePrivilegedPort
.It User
.It UserKnownHostsFile
.It VerifyHostKeyDNS
.It XAuthLocation
.El
.It Fl p Ar port
Port to connect to on the remote host.
This can be specified on a
@ -543,88 +668,11 @@ per-host basis in the configuration file.
.It Fl q
Quiet mode.
Causes all warning and diagnostic messages to be suppressed.
.It Fl s
May be used to request invocation of a subsystem on the remote system.
Subsystems are a feature of the SSH2 protocol which facilitate the use
of SSH as a secure transport for other applications (eg. sftp).
The subsystem is specified as the remote command.
.It Fl t
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.
Multiple
.Fl t
options force tty allocation, even if
.Nm
has no local tty.
.It Fl T
Disable pseudo-tty allocation.
.It Fl v
Verbose mode.
Causes
.Nm
to print debugging messages about its progress.
This is helpful in
debugging connection, authentication, and configuration problems.
Multiple
.Fl v
options increase the verbosity.
The maximum is 3.
.It Fl V
Display the version number and exit.
.It Fl x
Disables X11 forwarding.
.It Fl X
Enables X11 forwarding.
This can also be specified on a per-host basis in a configuration file.
.Pp
X11 forwarding should be enabled with caution.
Users with the ability to bypass file permissions on the remote host
(for the user's X authorization database)
can access the local X11 display through the forwarded connection.
An attacker may then be able to perform activities such as keystroke monitoring.
.It Fl C
Requests compression of all data (including stdin, stdout, stderr, and
data for forwarded X11 and TCP/IP connections).
The compression algorithm is the same used by
.Xr gzip 1 ,
and the
.Dq level
can be controlled by the
.Cm CompressionLevel
option for protocol version 1.
Compression is desirable on modem lines and other
slow connections, but will only slow down things on fast networks.
The default value can be set on a host-by-host basis in the
configuration files; see the
.Cm Compression
option.
.It Fl F Ar configfile
Specifies an alternative per-user configuration file.
If a configuration file is given on the command line,
the system-wide configuration file
.Pq Pa /etc/ssh/ssh_config
will be ignored.
The default for the per-user configuration file is
.Pa $HOME/.ssh/config .
.It Fl L Ar port:host:hostport
Specifies that the given port on the local (client) host is to be
forwarded to the given host and port on the remote side.
This works by allocating a socket to listen to
.Ar port
on the local side, and whenever a connection is made to this port, the
connection is forwarded over the secure channel, and a connection is
made to
.Ar host
port
.Ar hostport
from the remote machine.
Port forwardings can also be specified in the configuration file.
Only root can forward privileged ports.
IPv6 addresses can be specified with an alternative syntax:
.Ar port/host/hostport
.It Fl R Ar port:host:hostport
.It Fl R Xo
.Sm off
.Ar port : host : hostport
.Sm on
.Xc
Specifies that the given port on the remote (server) host is to be
forwarded to the given host and port on the local side.
This works by allocating a socket to listen to
@ -640,38 +688,56 @@ Port forwardings can also be specified in the configuration file.
Privileged ports can be forwarded only when
logging in as root on the remote machine.
IPv6 addresses can be specified with an alternative syntax:
.Ar port/host/hostport
.It Fl D Ar port
Specifies a local
.Dq dynamic
application-level port forwarding.
This works by allocating a socket to listen to
.Ar port
on the local side, and whenever a connection is made to this port, the
connection is forwarded over the secure channel, and the application
protocol is then used to determine where to connect to from the
remote machine.
Currently the SOCKS4 and SOCKS5 protocols are supported, and
.Sm off
.Xo
.Ar port No / Ar host No /
.Ar hostport .
.Xc
.Sm on
.It Fl s
May be used to request invocation of a subsystem on the remote system.
Subsystems are a feature of the SSH2 protocol which facilitate the use
of SSH as a secure transport for other applications (eg.\&
.Xr sftp 1 ) .
The subsystem is specified as the remote command.
.It Fl T
Disable pseudo-tty allocation.
.It Fl t
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.
Multiple
.Fl t
options force tty allocation, even if
.Nm
will act as a SOCKS server.
Only root can forward privileged ports.
Dynamic port forwardings can also be specified in the configuration file.
.It Fl 1
Forces
has no local tty.
.It Fl V
Display the version number and exit.
.It Fl v
Verbose mode.
Causes
.Nm
to try protocol version 1 only.
.It Fl 2
Forces
.Nm
to try protocol version 2 only.
.It Fl 4
Forces
.Nm
to use IPv4 addresses only.
.It Fl 6
Forces
.Nm
to use IPv6 addresses only.
to print debugging messages about its progress.
This is helpful in
debugging connection, authentication, and configuration problems.
Multiple
.Fl v
options increase the verbosity.
The maximum is 3.
.It Fl X
Enables X11 forwarding.
This can also be specified on a per-host basis in a configuration file.
.Pp
X11 forwarding should be enabled with caution.
Users with the ability to bypass file permissions on the remote host
(for the user's X authorization database)
can access the local X11 display through the forwarded connection.
An attacker may then be able to perform activities such as keystroke monitoring.
.It Fl x
Disables X11 forwarding.
.It Fl Y
Enables trusted X11 forwarding.
.El
.Sh CONFIGURATION FILES
.Nm
@ -682,7 +748,7 @@ The file format and configuration options are described in
.Sh ENVIRONMENT
.Nm
will normally set the following environment variables:
.Bl -tag -width Ds
.Bl -tag -width LOGNAME
.It Ev DISPLAY
The
.Ev DISPLAY
@ -692,7 +758,7 @@ It is automatically set by
to point to a value of the form
.Dq hostname:n
where hostname indicates
the host where the shell runs, and n is an integer \*(>= 1.
the host where the shell runs, and n is an integer \*(Ge 1.
.Nm
uses this special value to forward X11 connections over the secure
channel.
@ -770,7 +836,7 @@ and adds lines of the format
.Dq VARNAME=value
to the environment if the file exists and if users are allowed to
change their environment.
See the
For more information, see the
.Cm PermitUserEnvironment
option in
.Xr sshd_config 5 .
@ -799,7 +865,7 @@ Contains the public key for authentication (public part of the
identity file in human-readable form).
The contents of the
.Pa $HOME/.ssh/identity.pub
file should be added to
file should be added to the file
.Pa $HOME/.ssh/authorized_keys
on all machines
where the user wishes to log in using protocol version 1 RSA authentication.
@ -825,7 +891,8 @@ Lists the public keys (RSA/DSA) that can be used for logging in as this user.
The format of this file is described in the
.Xr sshd 8
manual page.
In the simplest form the format is the same as the .pub
In the simplest form the format is the same as the
.Pa .pub
identity files.
This file is not highly sensitive, but the recommended
permissions are read/write for the user, and not accessible by others.
@ -841,7 +908,7 @@ by spaces): system name, public key and optional comment field.
When different names are used
for the same machine, all such names should be listed, separated by
commas.
The format is described on the
The format is described in the
.Xr sshd 8
manual page.
.Pp
@ -881,7 +948,7 @@ By default
is not setuid root.
.It Pa $HOME/.rhosts
This file is used in
.Pa \&.rhosts
.Em rhosts
authentication to list the
host/user pairs that are permitted to log in.
(Note that this file is
@ -903,7 +970,9 @@ accessible by others.
Note that by default
.Xr sshd 8
will be installed so that it requires successful RSA host
authentication before permitting \s+2.\s0rhosts authentication.
authentication before permitting
.Em rhosts
authentication.
If the server machine does not have the client's host key in
.Pa /etc/ssh/ssh_known_hosts ,
it can be stored in
@ -914,21 +983,20 @@ will automatically add the host key to
.Pa $HOME/.ssh/known_hosts .
.It Pa $HOME/.shosts
This file is used exactly the same way as
.Pa \&.rhosts .
.Pa .rhosts .
The purpose for
having this file is to be able to use rhosts authentication with
.Nm
without permitting login with
.Nm rlogin
.Xr rlogin
or
.Xr rsh 1 .
.It Pa /etc/hosts.equiv
This file is used during
.Pa \&.rhosts
.Em rhosts
authentication.
It contains
canonical hosts names, one per line (the full format is described on
the
canonical hosts names, one per line (the full format is described in the
.Xr sshd 8
manual page).
If the client host is found in this file, login is
@ -968,6 +1036,7 @@ above.
exits with the exit status of the remote command or with 255
if an error occurred.
.Sh SEE ALSO
.Xr gzip 1 ,
.Xr rsh 1 ,
.Xr scp 1 ,
.Xr sftp 1 ,
@ -975,6 +1044,7 @@ if an error occurred.
.Xr ssh-agent 1 ,
.Xr ssh-keygen 1 ,
.Xr telnet 1 ,
.Xr hosts.equiv 5 ,
.Xr ssh_config 5 ,
.Xr ssh-keysign 8 ,
.Xr sshd 8

View File

@ -13,7 +13,7 @@
* called by a name other than "ssh" or "Secure Shell".
*
* Copyright (c) 1999 Niels Provos. All rights reserved.
* Copyright (c) 2000, 2001, 2002 Markus Friedl. All rights reserved.
* Copyright (c) 2000, 2001, 2002, 2003 Markus Friedl. All rights reserved.
*
* Modified to work with SSL by Niels Provos <provos@citi.umich.edu>
* in Canada (German citizen).
@ -40,7 +40,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: ssh.c,v 1.201 2003/09/01 18:15:50 markus Exp $");
RCSID("$OpenBSD: ssh.c,v 1.206 2003/12/16 15:49:51 markus Exp $");
RCSID("$FreeBSD$");
#include <openssl/evp.h>
@ -156,6 +156,7 @@ usage(void)
fprintf(stderr, " -A Enable authentication agent forwarding.\n");
fprintf(stderr, " -a Disable authentication agent forwarding (default).\n");
fprintf(stderr, " -X Enable X11 connection forwarding.\n");
fprintf(stderr, " -Y Enable trusted X11 connection forwarding.\n");
fprintf(stderr, " -x Disable X11 connection forwarding (default).\n");
fprintf(stderr, " -i file Identity for public key authentication "
"(default: ~/.ssh/identity)\n");
@ -205,7 +206,7 @@ main(int ac, char **av)
int i, opt, exit_status;
u_short fwd_port, fwd_host_port;
char sfwd_port[6], sfwd_host_port[6];
char *p, *cp, buf[256];
char *p, *cp, *line, buf[256];
struct stat st;
struct passwd *pw;
int dummy;
@ -221,7 +222,7 @@ main(int ac, char **av)
*/
original_real_uid = getuid();
original_effective_uid = geteuid();
/*
* Use uid-swapping to give up root privileges for the duration of
* option processing. We will re-instantiate the rights when we are
@ -265,7 +266,7 @@ main(int ac, char **av)
again:
while ((opt = getopt(ac, av,
"1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:NPR:TVX")) != -1) {
"1246ab:c:e:fgi:kl:m:no:p:qstvxACD:F:I:L:NPR:TVXY")) != -1) {
switch (opt) {
case '1':
options.protocol = SSH_PROTO_1;
@ -292,6 +293,10 @@ main(int ac, char **av)
case 'X':
options.forward_x11 = 1;
break;
case 'Y':
options.forward_x11 = 1;
options.forward_x11_trusted = 1;
break;
case 'g':
options.gateway_ports = 1;
break;
@ -305,7 +310,7 @@ main(int ac, char **av)
options.forward_agent = 1;
break;
case 'k':
/* ignored for backward compatibility */
options.gss_deleg_creds = 0;
break;
case 'i':
if (stat(optarg, &st) < 0) {
@ -460,9 +465,11 @@ main(int ac, char **av)
break;
case 'o':
dummy = 1;
line = xstrdup(optarg);
if (process_config_line(&options, host ? host : "",
optarg, "command-line", 0, &dummy) != 0)
line, "command-line", 0, &dummy) != 0)
exit(1);
xfree(line);
break;
case 's':
subsystem_flag = 1;
@ -730,7 +737,7 @@ main(int ac, char **av)
packet_close();
/*
* Send SIGHUP to proxy command if used. We don't wait() in
* Send SIGHUP to proxy command if used. We don't wait() in
* case it hangs and instead rely on init to reap the child
*/
if (proxy_command_pid > 1)
@ -739,19 +746,25 @@ main(int ac, char **av)
return exit_status;
}
#define SSH_X11_PROTO "MIT-MAGIC-COOKIE-1"
static void
x11_get_proto(char **_proto, char **_data)
{
char cmd[1024];
char line[512];
char xdisplay[512];
static char proto[512], data[512];
FILE *f;
int got_data = 0, i;
char *display;
int got_data = 0, generated = 0, do_unlink = 0, i;
char *display, *xauthdir, *xauthfile;
struct stat st;
xauthdir = xauthfile = NULL;
*_proto = proto;
*_data = data;
proto[0] = data[0] = '\0';
if (!options.xauth_location ||
(stat(options.xauth_location, &st) == -1)) {
debug("No xauth program.");
@ -760,28 +773,59 @@ x11_get_proto(char **_proto, char **_data)
debug("x11_get_proto: DISPLAY not set");
return;
}
/* Try to get Xauthority information for the display. */
if (strncmp(display, "localhost:", 10) == 0)
/*
* Handle FamilyLocal case where $DISPLAY does
* not match an authorization entry. For this we
* just try "xauth list unix:displaynum.screennum".
* XXX: "localhost" match to determine FamilyLocal
* is not perfect.
*/
snprintf(line, sizeof line, "%s list unix:%s 2>"
_PATH_DEVNULL, options.xauth_location, display+10);
else
snprintf(line, sizeof line, "%s list %.200s 2>"
_PATH_DEVNULL, options.xauth_location, display);
debug2("x11_get_proto: %s", line);
f = popen(line, "r");
/*
* Handle FamilyLocal case where $DISPLAY does
* not match an authorization entry. For this we
* just try "xauth list unix:displaynum.screennum".
* XXX: "localhost" match to determine FamilyLocal
* is not perfect.
*/
if (strncmp(display, "localhost:", 10) == 0) {
snprintf(xdisplay, sizeof(xdisplay), "unix:%s",
display + 10);
display = xdisplay;
}
if (options.forward_x11_trusted == 0) {
xauthdir = xmalloc(MAXPATHLEN);
xauthfile = xmalloc(MAXPATHLEN);
strlcpy(xauthdir, "/tmp/ssh-XXXXXXXXXX", MAXPATHLEN);
if (mkdtemp(xauthdir) != NULL) {
do_unlink = 1;
snprintf(xauthfile, MAXPATHLEN, "%s/xauthfile",
xauthdir);
snprintf(cmd, sizeof(cmd),
"%s -f %s generate %s " SSH_X11_PROTO
" untrusted timeout 120 2>" _PATH_DEVNULL,
options.xauth_location, xauthfile, display);
debug2("x11_get_proto: %s", cmd);
if (system(cmd) == 0)
generated = 1;
}
}
snprintf(cmd, sizeof(cmd),
"%s %s%s list %s . 2>" _PATH_DEVNULL,
options.xauth_location,
generated ? "-f " : "" ,
generated ? xauthfile : "",
display);
debug2("x11_get_proto: %s", cmd);
f = popen(cmd, "r");
if (f && fgets(line, sizeof(line), f) &&
sscanf(line, "%*s %511s %511s", proto, data) == 2)
got_data = 1;
if (f)
pclose(f);
}
if (do_unlink) {
unlink(xauthfile);
rmdir(xauthdir);
}
if (xauthdir)
xfree(xauthdir);
if (xauthfile)
xfree(xauthfile);
/*
* If we didn't get authentication data, just make up some
* data. The forwarding code will check the validity of the
@ -793,12 +837,14 @@ x11_get_proto(char **_proto, char **_data)
if (!got_data) {
u_int32_t rand = 0;
logit("Warning: No xauth data; using fake authentication data for X11 forwarding.");
strlcpy(proto, "MIT-MAGIC-COOKIE-1", sizeof proto);
logit("Warning: No xauth data; "
"using fake authentication data for X11 forwarding.");
strlcpy(proto, SSH_X11_PROTO, sizeof proto);
for (i = 0; i < 16; i++) {
if (i % 4 == 0)
rand = arc4random();
snprintf(data + 2 * i, sizeof data - 2 * i, "%02x", rand & 0xff);
snprintf(data + 2 * i, sizeof data - 2 * i, "%02x",
rand & 0xff);
rand >>= 8;
}
}
@ -1001,16 +1047,13 @@ client_subsystem_reply(int type, u_int32_t seq, void *ctxt)
}
void
client_global_request_reply(int type, u_int32_t seq, void *ctxt)
client_global_request_reply_fwd(int type, u_int32_t seq, void *ctxt)
{
int i;
i = client_global_request_id++;
if (i >= options.num_remote_forwards) {
debug("client_global_request_reply: too many replies %d > %d",
i, options.num_remote_forwards);
if (i >= options.num_remote_forwards)
return;
}
debug("remote forward %s for: listen %d, connect %s:%d",
type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure",
options.remote_forwards[i].port,

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh.h,v 1.74 2003/09/01 13:52:18 markus Exp $ */
/* $OpenBSD: ssh.h,v 1.75 2003/12/02 17:01:15 markus Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
@ -103,4 +103,7 @@
/* Minimum modulus size (n) for RSA keys. */
#define SSH_RSA_MINIMUM_MODULUS_SIZE 768
/* Listen backlog for sshd, ssh-agent and forwarding sockets */
#define SSH_LISTEN_BACKLOG 128
#endif /* SSH_H */

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.20 2003/09/02 18:50:06 jmc Exp $
.\" $OpenBSD: ssh_config.5,v 1.28 2003/12/16 15:49:51 markus Exp $
.\" $FreeBSD$
.Dd September 25, 1999
.Dt SSH_CONFIG 5
@ -187,7 +187,6 @@ Specifies the ciphers allowed for protocol version 2
in order of preference.
Multiple ciphers must be comma-separated.
The default is
.Pp
.Bd -literal
``aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,
aes192-cbc,aes256-cbc''
@ -261,6 +260,7 @@ or
.Dq no .
The default is
.Dq no .
This option should be placed in the non-hostspecific section.
See
.Xr ssh-keysign 8
for more information.
@ -307,9 +307,27 @@ The default is
.Pp
X11 forwarding should be enabled with caution.
Users with the ability to bypass file permissions on the remote host
(for the user's X authorization database)
(for the user's X11 authorization database)
can access the local X11 display through the forwarded connection.
An attacker may then be able to perform activities such as keystroke monitoring.
An attacker may then be able to perform activities such as keystroke monitoring
if the
.Cm ForwardX11Trusted
option is also enabled.
.It Cm ForwardX11Trusted
If the this option is set to
.Dq yes
then remote X11 clients will have full access to the original X11 display.
If this option is set to
.Dq no
then remote X11 clients will be considered untrusted and prevented
from stealing or tampering with data belonging to trusted X11
clients.
.Pp
The default is
.Dq no .
.Pp
See the X11 SECURITY extension specification for full details on
the restrictions imposed on untrusted clients.
.It Cm GatewayPorts
Specifies whether remote hosts are allowed to connect to local
forwarded ports.
@ -333,11 +351,9 @@ Specifies a file to use for the global
host key database instead of
.Pa /etc/ssh/ssh_known_hosts .
.It Cm GSSAPIAuthentication
Specifies whether authentication based on GSSAPI may be used, either using
the result of a successful key exchange, or using GSSAPI user
authentication.
Specifies whether user authentication based on GSSAPI is allowed.
The default is
.Dq yes .
.Dq no .
Note that this option applies to protocol version 2 only.
.It Cm GSSAPIDelegateCredentials
Forward (delegate) credentials to the server.
@ -391,23 +407,6 @@ syntax to refer to a user's home directory.
It is possible to have
multiple identity files specified in configuration files; all these
identities will be tried in sequence.
.It Cm KeepAlive
Specifies whether the system should send TCP keepalive messages to the
other side.
If they are sent, death of the connection or crash of one
of the machines will be properly noticed.
However, this means that
connections will die if the route is down temporarily, and some people
find it annoying.
.Pp
The default is
.Dq yes
(to send keepalives), and the client will notice
if the network goes down or the remote host dies.
This is important in scripts, and many users want it too.
.Pp
To disable keepalives, the value should be set to
.Dq no .
.It Cm LocalForward
Specifies that a TCP/IP port on the local machine be forwarded over
the secure channel to the specified host and port from the remote machine.
@ -554,6 +553,42 @@ running.
The default is
.Dq yes .
Note that this option applies to protocol version 1 only.
.It Cm ServerAliveInterval
Sets a timeout interval in seconds after which if no data has been received
from the server,
.Nm ssh
will send a message through the encrypted
channel to request a response from the server.
The default
is 0, indicating that these messages will not be sent to the server.
This option applies to protocol version 2 only.
.It Cm ServerAliveCountMax
Sets the number of server alive messages (see above) which may be
sent without
.Nm ssh
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.
It is important to note that the use of server alive messages is very
different from
.Cm TCPKeepAlive
(below).
The server alive messages are sent through the encrypted channel
and therefore will not be spoofable.
The TCP keepalive option enabled by
.Cm TCPKeepAlive
is spoofable.
The server alive mechanism is valuable when the client or
server depend on knowing when a connection has become inactive.
.Pp
The default value is 3.
If, for example,
.Cm ServerAliveInterval
(above) is set to 15, and
.Cm ServerAliveCountMax
is left at the default, if the server becomes unresponsive ssh
will disconnect after approximately 45 seconds.
.It Cm SmartcardDevice
Specifies which smartcard device to use.
The argument to this keyword is the device
@ -596,6 +631,23 @@ or
.Dq ask .
The default is
.Dq ask .
.It Cm TCPKeepAlive
Specifies whether the system should send TCP keepalive messages to the
other side.
If they are sent, death of the connection or crash of one
of the machines will be properly noticed.
However, this means that
connections will die if the route is down temporarily, and some people
find it annoying.
.Pp
The default is
.Dq yes
(to send TCP keepalive messages), and the client will notice
if the network goes down or the remote host dies.
This is important in scripts, and many users want it too.
.Pp
To disable TCP keepalive messages, the value should be set to
.Dq no .
.It Cm UsePrivilegedPort
Specifies whether to use a privileged port for outgoing connections.
The argument must be
@ -625,6 +677,23 @@ host key database instead of
.It Cm VerifyHostKeyDNS
Specifies whether to verify the remote key using DNS and SSHFP resource
records.
If this option is set to
.Dq yes ,
the client will implicitly trust keys that match a secure fingerprint
from DNS.
Insecure fingerprints will be handled as if this option was set to
.Dq ask .
If this option is set to
.Dq ask ,
information on fingerprint match will be displayed, but the user will still
need to confirm new host keys according to the
.Cm StrictHostKeyChecking
option.
The argument must be
.Dq yes ,
.Dq no
or
.Dq ask .
The default is
.Dq no .
Note that this option applies to protocol version 2 only.

View File

@ -13,7 +13,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sshconnect.c,v 1.148 2003/09/18 07:52:54 markus Exp $");
RCSID("$OpenBSD: sshconnect.c,v 1.156 2004/01/25 03:49:09 djm Exp $");
#include <openssl/bn.h>
@ -33,16 +33,12 @@ RCSID("$OpenBSD: sshconnect.c,v 1.148 2003/09/18 07:52:54 markus Exp $");
#include "misc.h"
#include "readpass.h"
#ifdef DNS
#include "dns.h"
#endif
char *client_version_string = NULL;
char *server_version_string = NULL;
#ifdef DNS
int verified_host_key_dns = 0;
#endif
int matching_host_key_dns = 0;
/* import */
extern Options options;
@ -56,6 +52,7 @@ extern pid_t proxy_command_pid;
#endif
static int show_other_keys(const char *, Key *);
static void warn_changed_key(Key *);
/*
* Connect to the given ssh server using a proxy command.
@ -77,7 +74,7 @@ ssh_proxy_connect(const char *host, u_short port, const char *proxy_command)
* Build the final command string in the buffer by making the
* appropriate substitutions to the given proxy command.
*
* Use "exec" to avoid "sh -c" processes on some platforms
* Use "exec" to avoid "sh -c" processes on some platforms
* (e.g. Solaris)
*/
buffer_init(&command);
@ -234,12 +231,12 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
if (timeout <= 0)
return (connect(sockfd, serv_addr, addrlen));
if (fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0)
return (-1);
set_nonblock(sockfd);
rc = connect(sockfd, serv_addr, addrlen);
if (rc == 0)
if (rc == 0) {
unset_nonblock(sockfd);
return (0);
}
if (errno != EINPROGRESS)
return (-1);
@ -264,15 +261,15 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
break;
case -1:
/* Select error */
debug("select: %s", strerror(errno));
debug("select: %s", strerror(errno));
break;
case 1:
/* Completed or failed */
optval = 0;
optlen = sizeof(optval);
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval,
if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval,
&optlen) == -1) {
debug("getsockopt: %s", strerror(errno));
debug("getsockopt: %s", strerror(errno));
break;
}
if (optval != 0) {
@ -280,6 +277,7 @@ timeout_connect(int sockfd, const struct sockaddr *serv_addr,
break;
}
result = 0;
unset_nonblock(sockfd);
break;
default:
/* Should not occur */
@ -418,8 +416,8 @@ ssh_connect(const char *host, struct sockaddr_storage * hostaddr,
debug("Connection established.");
/* Set keepalives if requested. */
if (options.keepalives &&
/* Set SO_KEEPALIVE if requested. */
if (options.tcp_keep_alive &&
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,
sizeof(on)) < 0)
error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
@ -566,7 +564,7 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
int readonly, const char *user_hostfile, const char *system_hostfile)
{
Key *file_key;
char *type = key_type(host_key);
const char *type = key_type(host_key);
char *ip = NULL;
char hostline[1000], *hostp, *fp;
HostStatus host_status;
@ -730,9 +728,8 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
/* The default */
fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
msg2[0] = '\0';
#ifdef DNS
if (options.verify_host_key_dns) {
if (verified_host_key_dns)
if (matching_host_key_dns)
snprintf(msg2, sizeof(msg2),
"Matching host key fingerprint"
" found in DNS.\n");
@ -741,7 +738,6 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
"No matching host key fingerprint"
" found in DNS.\n");
}
#endif
snprintf(msg, sizeof(msg),
"The authenticity of host '%.200s (%s)' can't be "
"established%s\n"
@ -791,20 +787,10 @@ check_host_key(char *host, struct sockaddr *hostaddr, Key *host_key,
error("Offending key for IP in %s:%d", ip_file, ip_line);
}
/* The host key has changed. */
fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @");
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
error("It is also possible that the %s host key has just been changed.", type);
error("The fingerprint for the %s key sent by the remote host is\n%s.",
type, fp);
error("Please contact your system administrator.");
warn_changed_key(host_key);
error("Add correct host key in %.100s to get rid of this message.",
user_hostfile);
error("Offending key in %s:%d", host_file, host_line);
xfree(fp);
/*
* If strict host key checking is in use, the user will have
@ -907,27 +893,27 @@ int
verify_host_key(char *host, struct sockaddr *hostaddr, Key *host_key)
{
struct stat st;
int flags = 0;
#ifdef DNS
if (options.verify_host_key_dns) {
switch(verify_host_key_dns(host, hostaddr, host_key)) {
case DNS_VERIFY_OK:
#ifdef DNSSEC
return 0;
#else
verified_host_key_dns = 1;
break;
#endif
case DNS_VERIFY_FAILED:
return -1;
case DNS_VERIFY_ERROR:
break;
default:
debug3("bad return value from verify_host_key_dns");
break;
if (options.verify_host_key_dns &&
verify_host_key_dns(host, hostaddr, host_key, &flags) == 0) {
if (flags & DNS_VERIFY_FOUND) {
if (options.verify_host_key_dns == 1 &&
flags & DNS_VERIFY_MATCH &&
flags & DNS_VERIFY_SECURE)
return 0;
if (flags & DNS_VERIFY_MATCH) {
matching_host_key_dns = 1;
} else {
warn_changed_key(host_key);
error("Update the SSHFP RR in DNS with the new "
"host key to get rid of this message.");
}
}
}
#endif /* DNS */
/* return ok if the key can be found in an old keyfile */
if (stat(options.system_hostfile2, &st) == 0 ||
@ -1053,3 +1039,24 @@ show_other_keys(const char *host, Key *key)
}
return (found);
}
static void
warn_changed_key(Key *host_key)
{
char *fp;
const char *type = key_type(host_key);
fp = key_fingerprint(host_key, SSH_FP_MD5, SSH_FP_HEX);
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
error("@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @");
error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
error("IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!");
error("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
error("It is also possible that the %s host key has just been changed.", type);
error("The fingerprint for the %s key sent by the remote host is\n%s.",
type, fp);
error("Please contact your system administrator.");
xfree(fp);
}

View File

@ -23,7 +23,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sshconnect2.c,v 1.124 2003/08/25 10:33:33 djm Exp $");
RCSID("$OpenBSD: sshconnect2.c,v 1.134 2004/01/19 21:25:15 markus Exp $");
#include "openbsd-compat/sys-queue.h"
@ -222,7 +222,7 @@ static char *authmethods_get(void);
Authmethod authmethods[] = {
#ifdef GSSAPI
{"gssapi",
{"gssapi-with-mic",
userauth_gssapi,
&options.gss_authentication,
NULL},
@ -358,10 +358,12 @@ void
input_userauth_banner(int type, u_int32_t seq, void *ctxt)
{
char *msg, *lang;
debug3("input_userauth_banner");
msg = packet_get_string(NULL);
lang = packet_get_string(NULL);
logit("%s", msg);
if (options.log_level > SYSLOG_LEVEL_QUIET)
fprintf(stderr, "%s", msg);
xfree(msg);
xfree(lang);
}
@ -372,10 +374,14 @@ input_userauth_success(int type, u_int32_t seq, void *ctxt)
Authctxt *authctxt = ctxt;
if (authctxt == NULL)
fatal("input_userauth_success: no authentication context");
if (authctxt->authlist)
if (authctxt->authlist) {
xfree(authctxt->authlist);
if (authctxt->methoddata)
authctxt->authlist = NULL;
}
if (authctxt->methoddata) {
xfree(authctxt->methoddata);
authctxt->methoddata = NULL;
}
authctxt->success = 1; /* break out */
}
@ -447,7 +453,12 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
debug2("input_userauth_pk_ok: fp %s", fp);
xfree(fp);
TAILQ_FOREACH(id, &authctxt->keys, next) {
/*
* search keys in the reverse order, because last candidate has been
* moved to the end of the queue. this also avoids confusion by
* duplicate keys
*/
TAILQ_FOREACH_REVERSE(id, &authctxt->keys, next, idlist) {
if (key_equal(key, id->key)) {
sent = sign_and_send_pubkey(authctxt, id);
break;
@ -465,11 +476,11 @@ input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
}
#ifdef GSSAPI
int
int
userauth_gssapi(Authctxt *authctxt)
{
Gssctxt *gssctxt = NULL;
static gss_OID_set supported = NULL;
static gss_OID_set gss_supported = NULL;
static int mech = 0;
OM_uint32 min;
int ok = 0;
@ -477,18 +488,18 @@ userauth_gssapi(Authctxt *authctxt)
/* Try one GSSAPI method at a time, rather than sending them all at
* once. */
if (supported == NULL)
gss_indicate_mechs(&min, &supported);
if (gss_supported == NULL)
gss_indicate_mechs(&min, &gss_supported);
/* Check to see if the mechanism is usable before we offer it */
while (mech<supported->count && !ok) {
while (mech < gss_supported->count && !ok) {
if (gssctxt)
ssh_gssapi_delete_ctx(&gssctxt);
ssh_gssapi_build_ctx(&gssctxt);
ssh_gssapi_set_oid(gssctxt, &supported->elements[mech]);
ssh_gssapi_set_oid(gssctxt, &gss_supported->elements[mech]);
/* My DER encoding requires length<128 */
if (supported->elements[mech].length < 128 &&
if (gss_supported->elements[mech].length < 128 &&
!GSS_ERROR(ssh_gssapi_import_name(gssctxt,
authctxt->host))) {
ok = 1; /* Mechanism works */
@ -508,17 +519,11 @@ userauth_gssapi(Authctxt *authctxt)
packet_put_int(1);
/* Some servers encode the OID incorrectly (as we used to) */
if (datafellows & SSH_BUG_GSSAPI_BER) {
packet_put_string(supported->elements[mech].elements,
supported->elements[mech].length);
} else {
packet_put_int((supported->elements[mech].length)+2);
packet_put_char(SSH_GSS_OIDTYPE);
packet_put_char(supported->elements[mech].length);
packet_put_raw(supported->elements[mech].elements,
supported->elements[mech].length);
}
packet_put_int((gss_supported->elements[mech].length) + 2);
packet_put_char(SSH_GSS_OIDTYPE);
packet_put_char(gss_supported->elements[mech].length);
packet_put_raw(gss_supported->elements[mech].elements,
gss_supported->elements[mech].length);
packet_send();
@ -532,15 +537,66 @@ userauth_gssapi(Authctxt *authctxt)
return 1;
}
static OM_uint32
process_gssapi_token(void *ctxt, gss_buffer_t recv_tok)
{
Authctxt *authctxt = ctxt;
Gssctxt *gssctxt = authctxt->methoddata;
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
gss_buffer_desc gssbuf, mic;
OM_uint32 status, ms, flags;
Buffer b;
status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
recv_tok, &send_tok, &flags);
if (send_tok.length > 0) {
if (GSS_ERROR(status))
packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
else
packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
packet_put_string(send_tok.value, send_tok.length);
packet_send();
gss_release_buffer(&ms, &send_tok);
}
if (status == GSS_S_COMPLETE) {
/* send either complete or MIC, depending on mechanism */
if (!(flags & GSS_C_INTEG_FLAG)) {
packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
packet_send();
} else {
ssh_gssapi_buildmic(&b, authctxt->server_user,
authctxt->service, "gssapi-with-mic");
gssbuf.value = buffer_ptr(&b);
gssbuf.length = buffer_len(&b);
status = ssh_gssapi_sign(gssctxt, &gssbuf, &mic);
if (!GSS_ERROR(status)) {
packet_start(SSH2_MSG_USERAUTH_GSSAPI_MIC);
packet_put_string(mic.value, mic.length);
packet_send();
}
buffer_free(&b);
gss_release_buffer(&ms, &mic);
}
}
return status;
}
void
input_gssapi_response(int type, u_int32_t plen, void *ctxt)
{
Authctxt *authctxt = ctxt;
Gssctxt *gssctxt;
OM_uint32 status, ms;
int oidlen;
char *oidv;
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
if (authctxt == NULL)
fatal("input_gssapi_response: no authentication context");
@ -549,94 +605,55 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt)
/* Setup our OID */
oidv = packet_get_string(&oidlen);
if (datafellows & SSH_BUG_GSSAPI_BER) {
if (!ssh_gssapi_check_oid(gssctxt, oidv, oidlen))
fatal("Server returned different OID than expected");
} else {
if(oidv[0] != SSH_GSS_OIDTYPE || oidv[1] != oidlen-2) {
debug("Badly encoded mechanism OID received");
userauth(authctxt, NULL);
xfree(oidv);
return;
}
if (!ssh_gssapi_check_oid(gssctxt, oidv+2, oidlen-2))
fatal("Server returned different OID than expected");
if (oidlen <= 2 ||
oidv[0] != SSH_GSS_OIDTYPE ||
oidv[1] != oidlen - 2) {
xfree(oidv);
debug("Badly encoded mechanism OID received");
userauth(authctxt, NULL);
return;
}
if (!ssh_gssapi_check_oid(gssctxt, oidv + 2, oidlen - 2))
fatal("Server returned different OID than expected");
packet_check_eom();
xfree(oidv);
status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
GSS_C_NO_BUFFER, &send_tok, NULL);
if (GSS_ERROR(status)) {
if (send_tok.length > 0) {
packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
packet_put_string(send_tok.value, send_tok.length);
packet_send();
gss_release_buffer(&ms, &send_tok);
}
if (GSS_ERROR(process_gssapi_token(ctxt, GSS_C_NO_BUFFER))) {
/* Start again with next method on list */
debug("Trying to start again");
userauth(authctxt, NULL);
return;
}
/* We must have data to send */
packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
packet_put_string(send_tok.value, send_tok.length);
packet_send();
gss_release_buffer(&ms, &send_tok);
}
void
input_gssapi_token(int type, u_int32_t plen, void *ctxt)
{
Authctxt *authctxt = ctxt;
Gssctxt *gssctxt;
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
gss_buffer_desc recv_tok;
OM_uint32 status, ms;
OM_uint32 status;
u_int slen;
if (authctxt == NULL)
fatal("input_gssapi_response: no authentication context");
gssctxt = authctxt->methoddata;
recv_tok.value = packet_get_string(&slen);
recv_tok.length = slen; /* safe typecast */
packet_check_eom();
status=ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
&recv_tok, &send_tok, NULL);
status = process_gssapi_token(ctxt, &recv_tok);
xfree(recv_tok.value);
if (GSS_ERROR(status)) {
if (send_tok.length > 0) {
packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
packet_put_string(send_tok.value, send_tok.length);
packet_send();
gss_release_buffer(&ms, &send_tok);
}
/* Start again with the next method in the list */
userauth(authctxt, NULL);
return;
}
if (send_tok.length > 0) {
packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
packet_put_string(send_tok.value, send_tok.length);
packet_send();
gss_release_buffer(&ms, &send_tok);
}
if (status == GSS_S_COMPLETE) {
/* If that succeeded, send a exchange complete message */
packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
packet_send();
}
}
void
@ -1016,7 +1033,7 @@ pubkey_prepare(Authctxt *authctxt)
key = ssh_get_next_identity(ac, &comment, 2)) {
found = 0;
TAILQ_FOREACH(id, &files, next) {
/* agent keys from the config file are preferred */
/* agent keys from the config file are preferred */
if (key_equal(key, id->key)) {
key_free(key);
xfree(comment);
@ -1080,6 +1097,7 @@ userauth_pubkey(Authctxt *authctxt)
while ((id = TAILQ_FIRST(&authctxt->keys))) {
if (id->tried++)
return (0);
/* move key to the end of the queue */
TAILQ_REMOVE(&authctxt->keys, id, next);
TAILQ_INSERT_TAIL(&authctxt->keys, id, next);
/*
@ -1244,11 +1262,12 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp,
buffer_init(&b);
buffer_put_int(&b, packet_get_connection_in()); /* send # of socket */
buffer_put_string(&b, data, datalen);
ssh_msg_send(to[1], version, &b);
if (ssh_msg_send(to[1], version, &b) == -1)
fatal("ssh_keysign: couldn't send request");
if (ssh_msg_recv(from[0], &b) < 0) {
error("ssh_keysign: no reply");
buffer_clear(&b);
buffer_free(&b);
return -1;
}
close(from[0]);
@ -1260,11 +1279,11 @@ ssh_keysign(Key *key, u_char **sigp, u_int *lenp,
if (buffer_get_char(&b) != version) {
error("ssh_keysign: bad version");
buffer_clear(&b);
buffer_free(&b);
return -1;
}
*sigp = buffer_get_string(&b, lenp);
buffer_clear(&b);
buffer_free(&b);
return 0;
}

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.199 2003/08/13 08:46:31 markus Exp $
.\" $OpenBSD: sshd.8,v 1.200 2003/10/08 08:27:36 jmc Exp $
.\" $FreeBSD$
.Dd September 25, 1999
.Dt SSHD 8
@ -45,7 +45,7 @@
.Sh SYNOPSIS
.Nm sshd
.Bk -words
.Op Fl deiqtD46
.Op Fl 46Ddeiqt
.Op Fl b Ar bits
.Op Fl f Ar config_file
.Op Fl g Ar login_grace_time
@ -79,9 +79,7 @@ This implementation of
supports both SSH protocol version 1 and 2 simultaneously.
.Nm
works as follows:
.Pp
.Ss SSH protocol version 1
.Pp
Each host has a host-specific RSA key
(normally 1024 bits) used to identify the host.
Additionally, when
@ -93,7 +91,7 @@ Whenever a client connects, the daemon responds with its public
host and server keys.
The client compares the
RSA host key against its own database to verify that it has not changed.
The client then generates a 256 bit random number.
The client then generates a 256-bit random number.
It encrypts this
random number using both the host key and the server key, and sends
the encrypted number to the server.
@ -108,9 +106,9 @@ to use from those offered by the server.
.Pp
Next, the server and the client enter an authentication dialog.
The client tries to authenticate itself using
.Pa .rhosts
.Em .rhosts
authentication,
.Pa .rhosts
.Em .rhosts
authentication combined with RSA host
authentication, RSA challenge-response authentication, or password
based authentication.
@ -138,7 +136,8 @@ or
.Ql \&*NP\&*
).
.Pp
Rhosts authentication is normally disabled
.Em rhosts
authentication is normally disabled
because it is fundamentally insecure, but can be enabled in the server
configuration file if desired.
System security is not improved unless
@ -151,9 +150,7 @@ are disabled (thus completely disabling
and
.Xr rsh
into the machine).
.Pp
.Ss SSH protocol version 2
.Pp
Version 2 works similarly:
Each host has a host-specific key (RSA or DSA) used to identify the host.
However, when the daemon starts, it does not generate a server key.
@ -161,7 +158,7 @@ Forward security is provided through a Diffie-Hellman key agreement.
This key agreement results in a shared session key.
.Pp
The rest of the session is encrypted using a symmetric cipher, currently
128 bit AES, Blowfish, 3DES, CAST128, Arcfour, 192 bit AES, or 256 bit AES.
128-bit AES, Blowfish, 3DES, CAST128, Arcfour, 192-bit AES, or 256-bit AES.
The client selects the encryption algorithm
to use from those offered by the server.
Additionally, session integrity is provided
@ -172,9 +169,7 @@ Protocol version 2 provides a public key based
user (PubkeyAuthentication) or
client host (HostbasedAuthentication) authentication method,
conventional password authentication and challenge response based methods.
.Pp
.Ss Command execution and data forwarding
.Pp
If the client successfully authenticates itself, a dialog for
preparing the session is entered.
At this time the client may request
@ -193,8 +188,9 @@ connections have been closed, the server sends command exit status to
the client, and both sides exit.
.Pp
.Nm
can be configured using command-line options or a configuration
file.
can be configured using command-line options or a configuration file
(by default
.Xr sshd_config 5 ) .
Command-line options override values specified in the
configuration file.
.Pp
@ -206,9 +202,23 @@ by executing itself with the name it was started as, i.e.,
.Pp
The options are as follows:
.Bl -tag -width Ds
.It Fl 4
Forces
.Nm
to use IPv4 addresses only.
.It Fl 6
Forces
.Nm
to use IPv6 addresses only.
.It Fl b Ar bits
Specifies the number of bits in the ephemeral protocol version 1
server key (default 768).
.It Fl D
When this option is specified,
.Nm
will not detach and does not become a daemon.
This allows easy monitoring of
.Nm sshd .
.It Fl d
Debug mode.
The server sends verbose debug output to the system
@ -266,7 +276,7 @@ be feasible.
Specifies how often the ephemeral protocol version 1 server key is
regenerated (default 3600 seconds, or one hour).
The motivation for regenerating the key fairly
often is that the key is not stored anywhere, and after about an hour,
often is that the key is not stored anywhere, and after about an hour
it becomes impossible to recover the key for decrypting intercepted
communications even if the machine is cracked into or physically
seized.
@ -275,6 +285,8 @@ A value of zero indicates that the key will never be regenerated.
Can be used to give options in the format used in the configuration file.
This is useful for specifying options for which there is no separate
command-line flag.
For full details of the options, and their values, see
.Xr sshd_config 5 .
.It Fl p Ar port
Specifies the port on which the server listens for connections
(default 22).
@ -324,20 +336,6 @@ USER@HOST pattern in
.Cm AllowUsers
or
.Cm DenyUsers .
.It Fl D
When this option is specified
.Nm
will not detach and does not become a daemon.
This allows easy monitoring of
.Nm sshd .
.It Fl 4
Forces
.Nm
to use IPv4 addresses only.
.It Fl 6
Forces
.Nm
to use IPv6 addresses only.
.El
.Sh CONFIGURATION FILE
.Nm
@ -375,9 +373,9 @@ Changes to run with normal user privileges.
.It
Sets up basic environment.
.It
Reads
.Pa $HOME/.ssh/environment
if it exists and users are allowed to change their environment.
Reads the file
.Pa $HOME/.ssh/environment ,
if it exists, and users are allowed to change their environment.
See the
.Cm PermitUserEnvironment
option in
@ -517,7 +515,7 @@ Limit local
port forwarding such that it may only connect to the specified host and
port.
IPv6 addresses can be specified with an alternative syntax:
.Ar host/port .
.Ar host Ns / Ns Ar port .
Multiple
.Cm permitopen
options may be applied separated by commas.
@ -525,13 +523,13 @@ No pattern matching is performed on the specified hostnames,
they must be literal domains or addresses.
.El
.Ss Examples
1024 33 12121.\|.\|.\|312314325 ylo@foo.bar
1024 33 12121...312314325 ylo@foo.bar
.Pp
from="*.niksula.hut.fi,!pc.niksula.hut.fi" 1024 35 23.\|.\|.\|2334 ylo@niksula
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
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
permitopen="10.2.1.55:80",permitopen="10.2.1.56:25" 1024 33 23...2323
.Sh SSH_KNOWN_HOSTS FILE FORMAT
The
.Pa /etc/ssh/ssh_known_hosts
@ -589,7 +587,7 @@ or by taking
and adding the host names at the front.
.Ss Examples
.Bd -literal
closenet,.\|.\|.\|,130.233.208.41 1024 37 159.\|.\|.93 closenet.hut.fi
closenet,...,130.233.208.41 1024 37 159...93 closenet.hut.fi
cvs.openbsd.org,199.185.137.3 ssh-rsa AAAA1234.....=
.Ed
.Sh FILES
@ -648,7 +646,7 @@ and/or
.Pa id_rsa.pub
files into this file, as described in
.Xr ssh-keygen 1 .
.It Pa "/etc/ssh/ssh_known_hosts" and "$HOME/.ssh/known_hosts"
.It Pa "/etc/ssh/ssh_known_hosts", "$HOME/.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.
@ -682,7 +680,7 @@ The file must
be writable only by the user; it is recommended that it not be
accessible by others.
.Pp
If is also possible to use netgroups in the file.
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.
@ -694,7 +692,7 @@ 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
.Pa .rhosts
.Em rhosts
authentication.
In the simplest form, this file contains host names, one per line.
Users on
@ -801,9 +799,12 @@ This file should be writable only by root, and should be world-readable.
.Xr ssh-add 1 ,
.Xr ssh-agent 1 ,
.Xr ssh-keygen 1 ,
.Xr chroot 2 ,
.Xr hosts_access 5 ,
.Xr login.conf 5 ,
.Xr moduli 5 ,
.Xr sshd_config 5 ,
.Xr inetd 8 ,
.Xr sftp-server 8
.Rs
.%A T. Ylonen

View File

@ -42,7 +42,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sshd.c,v 1.276 2003/08/28 12:54:34 markus Exp $");
RCSID("$OpenBSD: sshd.c,v 1.286 2004/02/23 12:02:33 markus Exp $");
RCSID("$FreeBSD$");
#include <openssl/dh.h>
@ -106,6 +106,7 @@ extern char *__progname;
#else
char *__progname;
#endif
extern char **environ;
/* Server configuration options. */
ServerOptions options;
@ -204,11 +205,14 @@ int startup_pipe; /* in child */
/* variables used for privilege separation */
int use_privsep;
struct monitor *pmonitor;
struct monitor *pmonitor = NULL;
/* message to be displayed after login */
Buffer loginmsg;
/* global authentication context */
Authctxt *the_authctxt = NULL;
/* Prototypes for various functions defined later in this file. */
void destroy_sensitive_data(void);
void demote_sensitive_data(void);
@ -307,6 +311,9 @@ grace_alarm_handler(int sig)
{
/* XXX no idea how fix this signal handler */
if (use_privsep && pmonitor != NULL && pmonitor->m_pid > 0)
kill(pmonitor->m_pid, SIGALRM);
/* Log error and exit. */
fatal("Timeout before authentication for %s", get_remote_ipaddr());
}
@ -380,7 +387,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
strlen(server_version_string))
!= strlen(server_version_string)) {
logit("Could not write ident string to %s", get_remote_ipaddr());
fatal_cleanup();
cleanup_exit(255);
}
/* Read other sides version identification. */
@ -389,7 +396,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
if (atomicio(read, sock_in, &buf[i], 1) != 1) {
logit("Did not receive identification string from %s",
get_remote_ipaddr());
fatal_cleanup();
cleanup_exit(255);
}
if (buf[i] == '\r') {
buf[i] = 0;
@ -419,7 +426,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
close(sock_out);
logit("Bad protocol version identification '%.100s' from %s",
client_version_string, get_remote_ipaddr());
fatal_cleanup();
cleanup_exit(255);
}
debug("Client protocol version %d.%d; client software version %.100s",
remote_major, remote_minor, remote_version);
@ -429,13 +436,13 @@ sshd_exchange_identification(int sock_in, int sock_out)
if (datafellows & SSH_BUG_PROBE) {
logit("probed from %s with %s. Don't panic.",
get_remote_ipaddr(), client_version_string);
fatal_cleanup();
cleanup_exit(255);
}
if (datafellows & SSH_BUG_SCANNER) {
logit("scanned from %s with %s. Don't panic.",
get_remote_ipaddr(), client_version_string);
fatal_cleanup();
cleanup_exit(255);
}
mismatch = 0;
@ -481,7 +488,7 @@ sshd_exchange_identification(int sock_in, int sock_out)
logit("Protocol major versions differ for %s: %.200s vs. %.200s",
get_remote_ipaddr(),
server_version_string, client_version_string);
fatal_cleanup();
cleanup_exit(255);
}
}
@ -576,10 +583,9 @@ privsep_preauth_child(void)
#endif
}
static Authctxt *
privsep_preauth(void)
static int
privsep_preauth(Authctxt *authctxt)
{
Authctxt *authctxt = NULL;
int status;
pid_t pid;
@ -592,12 +598,11 @@ privsep_preauth(void)
if (pid == -1) {
fatal("fork of unprivileged child failed");
} else if (pid != 0) {
fatal_remove_cleanup((void (*) (void *)) packet_close, NULL);
debug2("Network child is on pid %ld", (long)pid);
close(pmonitor->m_recvfd);
authctxt = monitor_child_preauth(pmonitor);
pmonitor->m_pid = pid;
monitor_child_preauth(authctxt, pmonitor);
close(pmonitor->m_sendfd);
/* Sync memory */
@ -607,11 +612,7 @@ privsep_preauth(void)
while (waitpid(pid, &status, 0) < 0)
if (errno != EINTR)
break;
/* Reinstall, since the child has finished */
fatal_add_cleanup((void (*) (void *)) packet_close, NULL);
return (authctxt);
return (1);
} else {
/* child */
@ -622,17 +623,12 @@ privsep_preauth(void)
privsep_preauth_child();
setproctitle("%s", "[net]");
}
return (NULL);
return (0);
}
static void
privsep_postauth(Authctxt *authctxt)
{
extern Authctxt *x_authctxt;
/* XXX - Remote port forwarding */
x_authctxt = authctxt;
#ifdef DISABLE_FD_PASSING
if (1) {
#else
@ -658,8 +654,6 @@ privsep_postauth(Authctxt *authctxt)
if (pmonitor->m_pid == -1)
fatal("fork of unprivileged child failed");
else if (pmonitor->m_pid != 0) {
fatal_remove_cleanup((void (*) (void *)) packet_close, NULL);
debug2("User child is on pid %ld", (long)pmonitor->m_pid);
close(pmonitor->m_recvfd);
monitor_child_postauth(pmonitor);
@ -684,7 +678,8 @@ static char *
list_hostkey_types(void)
{
Buffer b;
char *p;
const char *p;
char *ret;
int i;
buffer_init(&b);
@ -703,10 +698,10 @@ list_hostkey_types(void)
}
}
buffer_append(&b, "\0", 1);
p = xstrdup(buffer_ptr(&b));
ret = xstrdup(buffer_ptr(&b));
buffer_free(&b);
debug("list_hostkey_types: %s", p);
return p;
debug("list_hostkey_types: %s", ret);
return ret;
}
Key *
@ -774,7 +769,8 @@ drop_connection(int startups)
static void
usage(void)
{
fprintf(stderr, "sshd version %s\n", SSH_VERSION);
fprintf(stderr, "sshd version %s, %s\n",
SSH_VERSION, SSLeay_version(SSLEAY_VERSION));
fprintf(stderr, "Usage: %s [options]\n", __progname);
fprintf(stderr, "Options:\n");
fprintf(stderr, " -f file Configuration file (default %s)\n", _PATH_SERVER_CONFIG_FILE);
@ -814,11 +810,12 @@ main(int ac, char **av)
FILE *f;
struct addrinfo *ai;
char ntop[NI_MAXHOST], strport[NI_MAXSERV];
char *line;
int listen_sock, maxfd;
int startup_p[2];
int startups = 0;
Authctxt *authctxt;
Key *key;
Authctxt *authctxt;
int ret, key_used = 0;
#ifdef HAVE_SECUREWARE
@ -922,9 +919,11 @@ main(int ac, char **av)
}
break;
case 'o':
if (process_server_config_line(&options, optarg,
line = xstrdup(optarg);
if (process_server_config_line(&options, line,
"command-line", 0) != 0)
exit(1);
xfree(line);
break;
case '?':
default:
@ -1069,8 +1068,8 @@ main(int ac, char **av)
/*
* Clear out any supplemental groups we may have inherited. This
* prevents inadvertent creation of files with bad modes (in the
* portable version at least, it's certainly possible for PAM
* to create a file, and we can't control the code in every
* portable version at least, it's certainly possible for PAM
* to create a file, and we can't control the code in every
* module which might be used).
*/
if (setgroups(0, NULL) < 0)
@ -1112,6 +1111,11 @@ main(int ac, char **av)
unmounted if desired. */
chdir("/");
#ifndef HAVE_CYGWIN
/* Clear environment */
environ[0] = NULL;
#endif
/* ignore SIGPIPE */
signal(SIGPIPE, SIG_IGN);
@ -1180,7 +1184,7 @@ main(int ac, char **av)
/* Start listening on the port. */
logit("Server listening on %s port %s.", ntop, strport);
if (listen(listen_sock, 5) < 0)
if (listen(listen_sock, SSH_LISTEN_BACKLOG) < 0)
fatal("listen: %.100s", strerror(errno));
}
@ -1419,8 +1423,8 @@ main(int ac, char **av)
signal(SIGCHLD, SIG_DFL);
signal(SIGINT, SIG_DFL);
/* Set keepalives if requested. */
if (options.keepalives &&
/* Set SO_KEEPALIVE if requested. */
if (options.tcp_keep_alive &&
setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on,
sizeof(on)) < 0)
error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
@ -1481,21 +1485,28 @@ main(int ac, char **av)
packet_set_nonblocking();
/* prepare buffers to collect authentication messages */
/* prepare buffers to collect authentication messages */
buffer_init(&loginmsg);
/* allocate authentication context */
authctxt = xmalloc(sizeof(*authctxt));
memset(authctxt, 0, sizeof(*authctxt));
/* XXX global for cleanup, access from other modules */
the_authctxt = authctxt;
if (use_privsep)
if ((authctxt = privsep_preauth()) != NULL)
if (privsep_preauth(authctxt) == 1)
goto authenticated;
/* perform the key exchange */
/* authenticate user and start session */
if (compat20) {
do_ssh2_kex();
authctxt = do_authentication2();
do_authentication2(authctxt);
} else {
do_ssh1_kex();
authctxt = do_authentication();
do_authentication(authctxt);
}
/*
* If we use privilege separation, the unprivileged child transfers
@ -1518,7 +1529,7 @@ main(int ac, char **av)
destroy_sensitive_data();
}
/* Perform session preparation. */
/* Start session. */
do_authenticated(authctxt);
/* The connection has been terminated. */
@ -1811,3 +1822,12 @@ do_ssh2_kex(void)
#endif
debug("KEX done");
}
/* server specific fatal cleanup */
void
cleanup_exit(int i)
{
if (the_authctxt)
do_cleanup(the_authctxt);
_exit(i);
}

View File

@ -1,4 +1,4 @@
# $OpenBSD: sshd_config,v 1.65 2003/08/28 12:54:34 markus Exp $
# $OpenBSD: sshd_config,v 1.68 2003/12/29 16:39:50 millert Exp $
# $FreeBSD$
# This is the sshd server system-wide configuration file. See
@ -66,15 +66,16 @@
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCreds yes
#GSSAPICleanupCredentials yes
# Set this to 'yes' to enable PAM authentication (via challenge-response)
# and session processing. Depending on your PAM configuration, this may
# bypass the setting of 'PasswordAuthentication'
#UsePAM yes
# bypass the setting of 'PasswordAuthentication' and 'PermitEmptyPasswords'
#UsePAM no
#AllowTcpForwarding yes
#GatewayPorts no
@ -83,7 +84,7 @@
#X11UseLocalhost yes
#PrintMotd yes
#PrintLastLog yes
#KeepAlive yes
#TCPKeepAlive yes
#UseLogin no
#UsePrivilegeSeparation yes
#PermitUserEnvironment no

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.25 2003/09/01 09:50:04 markus Exp $
.\" $OpenBSD: sshd_config.5,v 1.28 2004/02/17 19:35:21 jmc Exp $
.\" $FreeBSD$
.Dd September 25, 1999
.Dt SSHD_CONFIG 5
@ -164,12 +164,12 @@ If this threshold is reached while client alive messages are being sent,
will disconnect the client, terminating the session.
It is important to note that the use of client alive messages is very
different from
.Cm KeepAlive
.Cm TCPKeepAlive
(below).
The client alive messages are sent through the encrypted channel
and therefore will not be spoofable.
The TCP keepalive option enabled by
.Cm KeepAlive
.Cm TCPKeepAlive
is spoofable.
The client alive mechanism is valuable when the client or
server depend on knowing when a connection has become inactive.
@ -235,7 +235,7 @@ The default is
.Dq no .
.It Cm GSSAPIAuthentication
Specifies whether user authentication based on GSSAPI is allowed.
The default is
The default is
.Dq no .
Note that this option applies to protocol version 2 only.
.It Cm GSSAPICleanupCredentials
@ -298,27 +298,6 @@ or
.Cm HostbasedAuthentication .
The default is
.Dq no .
.It Cm KeepAlive
Specifies whether the system should send TCP keepalive messages to the
other side.
If they are sent, death of the connection or crash of one
of the machines will be properly noticed.
However, this means that
connections will die if the route is down temporarily, and some people
find it annoying.
On the other hand, if keepalives are not sent,
sessions may hang indefinitely on the server, leaving
.Dq ghost
users and consuming server resources.
.Pp
The default is
.Dq yes
(to send keepalives), and the server will notice
if the network goes down or the client host crashes.
This avoids infinitely hanging sessions.
.Pp
To disable keepalives, the value should be set to
.Dq no .
.It Cm KerberosAuthentication
Specifies whether the password provided by the user for
.Cm PasswordAuthentication
@ -603,6 +582,27 @@ Gives the facility code that is used when logging messages from
The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2,
LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7.
The default is AUTH.
.It Cm TCPKeepAlive
Specifies whether the system should send TCP keepalive messages to the
other side.
If they are sent, death of the connection or crash of one
of the machines will be properly noticed.
However, this means that
connections will die if the route is down temporarily, and some people
find it annoying.
On the other hand, if TCP keepalives are not sent,
sessions may hang indefinitely on the server, leaving
.Dq ghost
users and consuming server resources.
.Pp
The default is
.Dq yes
(to send TCP keepalive messages), and the server will notice
if the network goes down or the client host crashes.
This avoids infinitely hanging sessions.
.Pp
To disable TCP keepalive messages, the value should be set to
.Dq no .
.It Cm UseDNS
Specifies whether
.Nm sshd
@ -631,12 +631,13 @@ If
.Cm UsePrivilegeSeparation
is specified, it will be disabled after authentication.
.It Cm UsePAM
Enables PAM authentication (via challenge-response) and session set up.
If you enable this, you should probably disable
Enables PAM authentication (via challenge-response) and session set up.
If you enable this, you should probably disable
.Cm PasswordAuthentication .
If you enable
If you enable
.CM UsePAM
then you will not be able to run sshd as a non-root user.
then you will not be able to run sshd as a non-root user. The default is
.Dq no .
.It Cm UsePrivilegeSeparation
Specifies whether
.Nm sshd

View File

@ -12,7 +12,7 @@
*/
#include "includes.h"
RCSID("$OpenBSD: sshpty.c,v 1.10 2003/06/12 07:57:38 markus Exp $");
RCSID("$OpenBSD: sshpty.c,v 1.11 2004/01/11 21:55:06 deraadt Exp $");
#ifdef HAVE_UTIL_H
# include <util.h>
@ -22,17 +22,9 @@ RCSID("$OpenBSD: sshpty.c,v 1.10 2003/06/12 07:57:38 markus Exp $");
#include "log.h"
#include "misc.h"
/* Pty allocated with _getpty gets broken if we do I_PUSH:es to it. */
#if defined(HAVE__GETPTY) || defined(HAVE_OPENPTY)
#undef HAVE_DEV_PTMX
#endif
#ifdef HAVE_PTY_H
# include <pty.h>
#endif
#if defined(HAVE_DEV_PTMX) && defined(HAVE_SYS_STROPTS_H)
# include <sys/stropts.h>
#endif
#ifndef O_NOCTTY
#define O_NOCTTY 0
@ -48,7 +40,6 @@ RCSID("$OpenBSD: sshpty.c,v 1.10 2003/06/12 07:57:38 markus Exp $");
int
pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
{
#if defined(HAVE_OPENPTY) || defined(BSD4_4)
/* openpty(3) exists in OSF/1 and some other os'es */
char *name;
int i;
@ -64,187 +55,6 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
strlcpy(namebuf, name, namebuflen); /* possible truncation */
return 1;
#else /* HAVE_OPENPTY */
#ifdef HAVE__GETPTY
/*
* _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more
* pty's automagically when needed
*/
char *slave;
slave = _getpty(ptyfd, O_RDWR, 0622, 0);
if (slave == NULL) {
error("_getpty: %.100s", strerror(errno));
return 0;
}
strlcpy(namebuf, slave, namebuflen);
/* Open the slave side. */
*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
if (*ttyfd < 0) {
error("%.200s: %.100s", namebuf, strerror(errno));
close(*ptyfd);
return 0;
}
return 1;
#else /* HAVE__GETPTY */
#if defined(HAVE_DEV_PTMX)
/*
* This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3
* also has bsd-style ptys, but they simply do not work.)
*/
int ptm;
char *pts;
mysig_t old_signal;
ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY);
if (ptm < 0) {
error("/dev/ptmx: %.100s", strerror(errno));
return 0;
}
old_signal = signal(SIGCHLD, SIG_DFL);
if (grantpt(ptm) < 0) {
error("grantpt: %.100s", strerror(errno));
return 0;
}
signal(SIGCHLD, old_signal);
if (unlockpt(ptm) < 0) {
error("unlockpt: %.100s", strerror(errno));
return 0;
}
pts = ptsname(ptm);
if (pts == NULL)
error("Slave pty side name could not be obtained.");
strlcpy(namebuf, pts, namebuflen);
*ptyfd = ptm;
/* Open the slave side. */
*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
if (*ttyfd < 0) {
error("%.100s: %.100s", namebuf, strerror(errno));
close(*ptyfd);
return 0;
}
#ifndef HAVE_CYGWIN
/*
* Push the appropriate streams modules, as described in Solaris pts(7).
* HP-UX pts(7) doesn't have ttcompat module.
*/
if (ioctl(*ttyfd, I_PUSH, "ptem") < 0)
error("ioctl I_PUSH ptem: %.100s", strerror(errno));
if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0)
error("ioctl I_PUSH ldterm: %.100s", strerror(errno));
#ifndef __hpux
if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0)
error("ioctl I_PUSH ttcompat: %.100s", strerror(errno));
#endif
#endif
return 1;
#else /* HAVE_DEV_PTMX */
#ifdef HAVE_DEV_PTS_AND_PTC
/* AIX-style pty code. */
const char *name;
*ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY);
if (*ptyfd < 0) {
error("Could not open /dev/ptc: %.100s", strerror(errno));
return 0;
}
name = ttyname(*ptyfd);
if (!name)
fatal("Open of /dev/ptc returns device for which ttyname fails.");
strlcpy(namebuf, name, namebuflen);
*ttyfd = open(name, O_RDWR | O_NOCTTY);
if (*ttyfd < 0) {
error("Could not open pty slave side %.100s: %.100s",
name, strerror(errno));
close(*ptyfd);
return 0;
}
return 1;
#else /* HAVE_DEV_PTS_AND_PTC */
#ifdef _UNICOS
char buf[64];
int i;
int highpty;
#ifdef _SC_CRAY_NPTY
highpty = sysconf(_SC_CRAY_NPTY);
if (highpty == -1)
highpty = 128;
#else
highpty = 128;
#endif
for (i = 0; i < highpty; i++) {
snprintf(buf, sizeof(buf), "/dev/pty/%03d", i);
*ptyfd = open(buf, O_RDWR|O_NOCTTY);
if (*ptyfd < 0)
continue;
snprintf(namebuf, namebuflen, "/dev/ttyp%03d", i);
/* Open the slave side. */
*ttyfd = open(namebuf, O_RDWR|O_NOCTTY);
if (*ttyfd < 0) {
error("%.100s: %.100s", namebuf, strerror(errno));
close(*ptyfd);
return 0;
}
return 1;
}
return 0;
#else
/* BSD-style pty code. */
char buf[64];
int i;
const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char *ptyminors = "0123456789abcdef";
int num_minors = strlen(ptyminors);
int num_ptys = strlen(ptymajors) * num_minors;
struct termios tio;
for (i = 0; i < num_ptys; i++) {
snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors],
ptyminors[i % num_minors]);
snprintf(namebuf, namebuflen, "/dev/tty%c%c",
ptymajors[i / num_minors], ptyminors[i % num_minors]);
*ptyfd = open(buf, O_RDWR | O_NOCTTY);
if (*ptyfd < 0) {
/* Try SCO style naming */
snprintf(buf, sizeof buf, "/dev/ptyp%d", i);
snprintf(namebuf, namebuflen, "/dev/ttyp%d", i);
*ptyfd = open(buf, O_RDWR | O_NOCTTY);
if (*ptyfd < 0)
continue;
}
/* Open the slave side. */
*ttyfd = open(namebuf, O_RDWR | O_NOCTTY);
if (*ttyfd < 0) {
error("%.100s: %.100s", namebuf, strerror(errno));
close(*ptyfd);
return 0;
}
/* set tty modes to a sane state for broken clients */
if (tcgetattr(*ptyfd, &tio) < 0)
logit("Getting tty modes for pty failed: %.100s", strerror(errno));
else {
tio.c_lflag |= (ECHO | ISIG | ICANON);
tio.c_oflag |= (OPOST | ONLCR);
tio.c_iflag |= ICRNL;
/* Set the new modes for the terminal. */
if (tcsetattr(*ptyfd, TCSANOW, &tio) < 0)
logit("Setting tty modes for pty failed: %.100s", strerror(errno));
}
return 1;
}
return 0;
#endif /* CRAY */
#endif /* HAVE_DEV_PTS_AND_PTC */
#endif /* HAVE_DEV_PTMX */
#endif /* HAVE__GETPTY */
#endif /* HAVE_OPENPTY */
}
/* Releases the tty. Its ownership is returned to root, and permissions to 0666. */
@ -343,7 +153,7 @@ pty_make_controlling_tty(int *ttyfd, const char *ttyname)
if (fd < 0)
error("open /dev/tty failed - could not set controlling tty: %.100s",
strerror(errno));
else
else
close(fd);
#endif /* _UNICOS */
}

View File

@ -1,11 +1,11 @@
/* $OpenBSD: version.h,v 1.39 2003/09/16 21:02:40 markus Exp $ */
/* $OpenBSD: version.h,v 1.40 2004/02/23 15:16:46 markus Exp $ */
/* $FreeBSD$ */
#ifndef SSH_VERSION
#define SSH_VERSION (ssh_version_get())
#define SSH_VERSION_BASE "OpenSSH_3.7.1p2"
#define SSH_VERSION_ADDENDUM "FreeBSD-20040106"
#define SSH_VERSION_BASE "OpenSSH_3.8p1"
#define SSH_VERSION_ADDENDUM "FreeBSD-20040226"
const char *ssh_version_get(void);
void ssh_version_set_addendum(const char *add);