Resolve conflicts.
This commit is contained in:
parent
1754c77e5e
commit
124c4a1415
@ -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 $
|
||||
|
@ -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 ************** */
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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))) {
|
||||
|
@ -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;
|
||||
|
@ -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 *);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 *
|
||||
|
@ -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);
|
||||
|
@ -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)) !=
|
||||
|
@ -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).
|
||||
*/
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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 },
|
||||
|
@ -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
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 *);
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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 @@ parse_flag:
|
||||
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 @@ parse_flag:
|
||||
|
||||
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 @@ parse_flag:
|
||||
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 @@ parse_int:
|
||||
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 */
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 @@ parse_flag:
|
||||
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 @@ parse_flag:
|
||||
intptr = &options->strict_modes;
|
||||
goto parse_flag;
|
||||
|
||||
case sKeepAlives:
|
||||
intptr = &options->keepalives;
|
||||
case sTCPKeepAlive:
|
||||
intptr = &options->tcp_keep_alive;
|
||||
goto parse_flag;
|
||||
|
||||
case sEmptyPasswd:
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 *);
|
||||
|
@ -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
@ -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 *);
|
@ -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)) {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 @@ again:
|
||||
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 @@ again:
|
||||
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 @@ again:
|
||||
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 @@ again:
|
||||
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 @@ again:
|
||||
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,
|
||||
|
@ -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 */
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 @@ done:
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user